From 053ac911ad3011c89585e1bcf683b7accd5f1639 Mon Sep 17 00:00:00 2001 From: "vellum-apollo-bot[bot]" <242025090+vellum-apollo-bot[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 22:57:23 +0000 Subject: [PATCH] tools: move executionMode from Tool to ToolDefinition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brings the dispatch-intent field into the author-facing tool surface so all dispatcher-relevant knobs (executionTarget + executionMode) live on ToolDefinition. Tool now only adds 'category' on top of LoadedTool — one step closer to Tool === LoadedTool. LoadedTool keeps executionMode genuinely optional via Required> because undefined is the canonical 'local' state — load-time stamping would force a meaningless default. No runtime change. Pure type-level move. ### AGENTS.md compliance Grepped assistant/AGENTS.md for executionMode|ToolDefinition|LoadedTool| plugin-api|skill manifest|breaking change|public surface — no conventions apply to this move. --- assistant/src/tools/types.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/assistant/src/tools/types.ts b/assistant/src/tools/types.ts index 7b1bdefb75c..1a9a3cbc215 100644 --- a/assistant/src/tools/types.ts +++ b/assistant/src/tools/types.ts @@ -330,6 +330,8 @@ export interface ToolDefinition { input_schema?: object; /** Where the tool runs — sandbox (assistant container) or host (guardian device via proxy). Resolved by `resolveExecutionTarget` if omitted. */ executionTarget?: ExecutionTarget; + /** When set to 'proxy', the tool is forwarded to a connected client rather than executed locally. Genuinely optional — omit (or set to 'local') for in-process tools. */ + executionMode?: "local" | "proxy"; /** Implementation invoked when the model calls the tool. */ execute?: ( input: Record, @@ -337,8 +339,18 @@ export interface ToolDefinition { ) => Promise; } -/** Tool after the loader has derived its name and filled defaults. */ -export type LoadedTool = Required & { name: string }; +/** + * Tool after the loader has derived its name and filled defaults. + * + * `executionMode` is deliberately kept optional on the loaded shape — it + * carries dispatch intent ("forward to client" vs "execute locally") and + * staying `undefined` is the canonical "local" state. All other declared + * fields are required post-finalize. + */ +export type LoadedTool = Required> & { + name: string; + executionMode?: "local" | "proxy"; +}; /** The kind of extension that owns a tool. Core tools have no owner. */ export type OwnerKind = "skill" | "mcp" | "plugin"; @@ -356,6 +368,4 @@ export interface OwnerInfo { export interface Tool extends LoadedTool { category: string; - /** When set to 'proxy', the tool is forwarded to a connected client rather than executed locally. */ - executionMode?: "local" | "proxy"; }