Tool Calling
Scritorio uses tool calling to let an AI persona consult bounded manuscript context and local project canon before answering questions that depend on book facts. The model does not receive open-ended filesystem access. It receives a small set of local manuscript and canon tools, and Scritorio executes those tools against the currently selected book project.Where Tool Calling Runs
Tool calling is currently active for OpenAI chat mode in the desktop app and for the CLI smoke-test command:OPENAI_API_KEY from the shell environment.
Ollama chat uses the same persona and context-message construction, but it does not currently receive local manuscript or canon tools.
Request Flow
When the author sends a chat message, Scritorio builds a request in this order:- The selected chat persona becomes the system message.
- If a document or selection is active, Scritorio adds a context message with metadata for the current manuscript context.
- Recent chat history is included unless the OpenAI conversation is continuing from a previous Responses API response id.
- The author’s current message is added.
- The native Tauri layer sends the request to the OpenAI Responses API.
- If the request mode is
chat, Scritorio appends local manuscript and canon tool instructions and registers tool schemas. - If the model emits function calls, Scritorio executes them locally, returns
function_call_outputitems, and asks the model to continue. - Scritorio repeats tool execution for up to four rounds, then returns the final assistant text.
parallel_tool_calls is disabled so canon lookups are easier to reason about, debug, and apply in a stable order.
The chat UI can show live reading details while the request is in progress. Appearance settings control whether the author sees detailed tool-call rows, Flex/Fast routing status, and the Peek Prompt button. These settings affect the UI only; they do not disable actual tool calling, routing, evidence storage, or provenance.
Board Member System Prompt Formation
The selected board member id is normalized against the built-in board member list. Internally these ids still use the persona naming from the prompt code. If the requested id is missing or invalid, Scritorio falls back to the Developmental Editor. The prompt builder receives the current book’s genre, audience age group, and audience sex/gender lens. Those values are rendered into locked role sections and into the shared audience context section. Missing genre renders[genre not set]. Missing audience age renders [audience age not set].
The system prompt is formed as:
| Board member id | Purpose |
|---|---|
developmental-editor | Story architecture, stakes, pacing, scene purpose, and payoff. |
character-psychologist | Motivation, emotional continuity, relationships, agency, and subtext. |
continuity-editor | Canon facts, timeline drift, contradictions, terminology, and confirmations. |
worldbuilding-auditor | Systems logic, consequences, technology, institutions, and daily life. |
first-time-reader | Blind reader experience, curiosity, confusion, engagement, and drift. |
writing-coach | Craft patterns, teachable revision habits, exercises, and author growth. |
Context Message Formation
For OpenAI advisor chat, Scritorio builds at most one manuscript context attachment per turn. The initial prompt includes metadata only, not manuscript prose. Actual chapter, document, or selected text is available to the model only when it callsget_manuscript_context.
If the author has selected text, the context message includes:
- that a focused selection exists
- document path and title when available
- source and selection word counts when available
- a source selection hash when available
- document path and title when available
- word count
get_manuscript_context({ ref: "selection" }).
For non-tool providers such as Ollama, Scritorio may still use inline context fallback behavior. Long document context defaults to a 24,000 character limit.
OpenAI Request Shape
The Tauri layer converts system messages into the Responses APIinstructions field. Non-system messages are joined into the input field with explicit User: and Assistant: labels.
For chat mode only, Scritorio appends local manuscript and canon instructions to instructions:
- use
get_manuscript_contextbefore answering questions that require chapter, document, or selected text - use
get_manuscript_contextwithref: "selection"for highlighted or selected text - use
get_manuscript_contextwithref: "current"for the current chapter, open document, or current passage - use
get_manuscript_contextwith chapter numbers, titles, relative paths, orrefsfor multi-chapter comparisons - use local canon tools before answering questions that depend on project facts
- fetch relevant canon after manuscript context when the author asks about characters, relationships, motivation, locations, organizations, items, events, world rules, or style
- do not ask for or invent a project path
- use the specific
get_*_contexttools when the type is known - use
search_codexwhen the exact entry or type is unknown - use
list_codex_entriesfor inventories or counts - use
propose_codex_updatefor reviewable changes to existing characters, locations, organizations, items, concepts, events, and style entries - use
propose_codex_createfor reviewable creation of missing Codex entries - keep
propose_character_updateavailable for legacy character-update behavior - answer from returned tool output when using manuscript prose or local canon
Desktop Advisor Tools
| Tool | Purpose | Arguments | Writes files |
|---|---|---|---|
get_manuscript_context | Reads manuscript prose from the selected book/project. Use for the current document, focused selection, specific chapters, or multi-chapter comparisons. | ref, or refs | No |
get_character_context | Looks up compact local canon for a character. | name | No |
get_location_context | Looks up compact local canon for a place or setting. | name | No |
get_organization_context | Looks up compact local canon for an institution, faction, guild, government, or similar group. | name | No |
get_item_context | Looks up compact local canon for an object, technology, artifact, or resource. | name | No |
get_concept_context | Looks up compact local canon for world rules, technology, social systems, terminology, history, or recurring ideas. | name | No |
get_event_context | Looks up compact local canon for an event or timeline entry. | name | No |
get_style_context | Looks up compact local style guide or style rule canon. | name | No |
list_codex_entries | Lists compact entries of one canon type for counts, cast lists, setting lists, and overviews. | entryType | No |
search_codex | Searches local canon when the exact entry name or type is unknown. | query, optional entryType | No |
propose_codex_update | Returns a reviewable proposal for changing an existing Codex entry. | entryType, name, changeSummary, targetSection, proposedMarkdown | No |
propose_codex_create | Returns a reviewable proposal for creating a new Codex entry. | entryType, name, changeSummary, fields, customFields, markdownBody, soulMarkdown | No |
propose_character_update | Legacy character-only update proposal. | name, changeSummary, targetSection, proposedMarkdown | No |
get_*_context lookup tools are exposed for manuscript context, characters, locations, organizations, items, concepts, events, and style entries.
The CLI smoke test currently uses the canon-only subset: get_character_context, get_location_context, get_organization_context, get_item_context, get_concept_context, get_event_context, get_style_context, list_codex_entries, search_codex, propose_character_update, propose_codex_update, and propose_codex_create.
Manuscript Context Lookup Behavior
Tool execution happens inside Scritorio, not inside the model.get_manuscript_context resolves manuscript references against the selected project:
ref: "current"returns the active chapter or document bodyref: "selection"returns the selected text captured privately for the current turn- chapter numbers, titles, and relative paths resolve specific manuscript units
refscan return multiple manuscript units for comparisons
Canon Lookup Behavior
Forget_*_context, Scritorio scans Markdown files in the selected project, filters to the requested Codex type, and scores candidates by exact name, title, filename stem, alias, and partial-name matches. The returned context includes the project path, relative path, semantic type, name, title, aliases, summary, and a source excerpt.
For search_codex, Scritorio searches candidate name, title, type, path, summary, and source excerpt, then returns up to eight scored matches.
For list_codex_entries, Scritorio returns compact summaries for entries of the requested type.
Canon Mutation Proposals
Codex mutation tools are intentionally review-only. They return structured proposals and never modify the project directly.propose_codex_update resolves an existing entry, extracts the relevant section when possible, and returns proposed Markdown plus warnings.
propose_codex_create suggests a safe project-relative path and proposed Markdown for a new entry. For characters, it can also propose a soul.md file. If a soul is proposed, Scritorio prefers the folder shape:
Role field before review. This prevents a broad rewrite of the character’s narrative function when the author only asked to change the role.
Safety And Debugging
Tool calling follows the same privacy model as other AI features:- the selected book/project path is fixed by Scritorio
- the model does not choose arbitrary local paths
- manuscript prose is exposed through
get_manuscript_context, not injected into the initial OpenAI advisor prompt - canon tools return compact excerpts rather than unrestricted file reads
- evidence trails record compact lookup metadata and tool summaries, not full manuscript bodies
- proposed updates are review-only until the author applies them
- OpenAI debug logs redact request
input,messages, andpromptfields - API keys are never included in debug output
- provider calls and generated outputs are recorded through local provenance where the app supports it