improvement(mship): add enrichment tool, clean up dead tools (#5058)

* feat(mothership): add enrichment_run server tool for one-off lookups

Implement the Sim-side handler for the copilot enrichment_run tool: runs the
enrichment provider cascade for a single entity and returns the result inline,
surfacing the hosted-key cost as _serviceCost for per-round billing (matching
the media tools). Registered in the server-tool router.

Regenerate the copilot tool catalog/schemas to include enrichment_run.

* fix(mothership): remove leftover touch_plan tool references

touch_plan was removed from the copilot tool catalog earlier, but the Sim side
still referenced it. Regenerating the generated tool catalog (for enrichment_run)
synced it to the current contract and dropped the stale TouchPlan export, which
broke the build where router.ts still imported it.

Remove the dead touch_plan server tool and its test, drop its router
registration and WRITE_ACTIONS entry, simplify getServerToolRegistry (no more
beta-gated server tools), and clean up stale "use touch_plan" guidance strings.

* chore(mothership): trigger dev redeploy

* improvement(mothership): log billed cost on enrichment_run lookups

* fix(contracts): regenerate mship contracts

* fix(contracts): fix mship contracts
This commit is contained in:
Siddharth Ganesan
2026-06-15 10:57:29 -07:00
committed by GitHub
parent 17500432ef
commit cefb2dc239
11 changed files with 297 additions and 625 deletions
@@ -30,6 +30,7 @@ export interface ToolCatalogEntry {
| 'download_to_workspace_file'
| 'edit_content'
| 'edit_workflow'
| 'enrichment_run'
| 'ffmpeg'
| 'file'
| 'function_execute'
@@ -97,7 +98,6 @@ export interface ToolCatalogEntry {
| 'set_global_workflow_variables'
| 'superagent'
| 'table'
| 'touch_plan'
| 'update_deployment_version'
| 'update_job_history'
| 'update_workspace_mcp_server'
@@ -131,6 +131,7 @@ export interface ToolCatalogEntry {
| 'download_to_workspace_file'
| 'edit_content'
| 'edit_workflow'
| 'enrichment_run'
| 'ffmpeg'
| 'file'
| 'function_execute'
@@ -198,7 +199,6 @@ export interface ToolCatalogEntry {
| 'set_global_workflow_variables'
| 'superagent'
| 'table'
| 'touch_plan'
| 'update_deployment_version'
| 'update_job_history'
| 'update_workspace_mcp_server'
@@ -1073,6 +1073,56 @@ export const EditWorkflow: ToolCatalogEntry = {
requiredPermission: 'write',
}
export const EnrichmentRun: ToolCatalogEntry = {
id: 'enrichment_run',
name: 'enrichment_run',
route: 'sim',
mode: 'async',
parameters: {
type: 'object',
properties: {
enrichmentId: {
type: 'string',
description:
"Which enrichment to run. Discover the full set and each one's inputs/outputs via user_table.list_enrichments.",
enum: [
'work-email',
'phone-number',
'company-domain',
'company-info',
'email-verification',
],
},
inputs: {
type: 'object',
description:
'Map of the enrichment\'s input id → value, e.g. { "fullName": "Jane Doe", "companyDomain": "acme.com" }. Provide a value for every required input.',
},
},
required: ['enrichmentId', 'inputs'],
},
resultSchema: {
type: 'object',
properties: {
matched: {
type: 'boolean',
description: 'True when a provider returned a non-empty result.',
},
provider: {
type: 'string',
description:
'Internal label of the provider that produced the result (billing/diagnostics only — do NOT surface it to the user), or null on no match.',
},
result: {
type: 'object',
description: 'Mapped output values from the winning provider (empty object on no match).',
},
},
required: ['matched', 'result'],
},
requiredPermission: 'write',
}
export const Ffmpeg: ToolCatalogEntry = {
id: 'ffmpeg',
name: 'ffmpeg',
@@ -1106,7 +1156,7 @@ export const Ffmpeg: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1126,7 +1176,7 @@ export const Ffmpeg: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1207,8 +1257,7 @@ export const Ffmpeg: ToolCatalogEntry = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1287,7 +1336,7 @@ export const FunctionExecute: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1307,7 +1356,7 @@ export const FunctionExecute: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1372,8 +1421,7 @@ export const FunctionExecute: ToolCatalogEntry = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1449,7 +1497,7 @@ export const GenerateAudio: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1469,7 +1517,7 @@ export const GenerateAudio: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1539,8 +1587,7 @@ export const GenerateAudio: ToolCatalogEntry = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1599,7 +1646,7 @@ export const GenerateImage: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1619,7 +1666,7 @@ export const GenerateImage: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1674,8 +1721,7 @@ export const GenerateImage: ToolCatalogEntry = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1737,7 +1783,7 @@ export const GenerateVideo: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1757,7 +1803,7 @@ export const GenerateVideo: ToolCatalogEntry = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1833,8 +1879,7 @@ export const GenerateVideo: ToolCatalogEntry = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -3694,54 +3739,6 @@ export const Table: ToolCatalogEntry = {
internal: true,
}
export const TouchPlan: ToolCatalogEntry = {
id: 'touch_plan',
name: 'touch_plan',
route: 'sim',
mode: 'async',
parameters: {
type: 'object',
properties: {
name: {
type: 'string',
description:
'Plan file name or relative path under .plans, e.g. "implementation.md" or "phase-1/implementation.md". If no extension is supplied, ".md" is appended.',
},
scope: {
type: 'string',
description:
'Plan scope. Use "workspace" for root .plans/** main-agent plans. Use "workflow" for workflows/{workflow}/.plans/** subplans. If omitted with workflowPath, workflow scope is assumed; otherwise workspace scope is assumed.',
enum: ['workspace', 'workflow'],
},
title: {
type: 'string',
description: 'Optional short user-visible label for the plan creation.',
},
workflowPath: {
type: 'string',
description:
'Required for scope "workflow". Canonical workflow VFS path, e.g. "workflows/My%20Workflow" or "workflows/Folder/My%20Workflow". Copy paths verbatim from glob/read/grep output — they are percent-encoded per segment (spaces are %20, an in-name slash is %2F; parentheses and dots stay literal). Both the encoded path and the plain name resolve, so copy the returned path exactly rather than retyping or decoding it. Do not use workflow IDs.',
},
},
required: ['name'],
},
resultSchema: {
type: 'object',
properties: {
data: {
type: 'object',
description:
'Contains id, name, scope, vfsPath, backingVfsPath, and workflowId for workflow plans. Use vfsPath for follow-up workspace_file calls.',
},
message: { type: 'string', description: 'Human-readable outcome.' },
success: { type: 'boolean', description: 'Whether the plan file was created.' },
},
required: ['success', 'message'],
},
requiredPermission: 'write',
capabilities: ['file_output'],
}
export const UpdateDeploymentVersion: ToolCatalogEntry = {
id: 'update_deployment_version',
name: 'update_deployment_version',
@@ -4627,6 +4624,7 @@ export const TOOL_CATALOG: Record<string, ToolCatalogEntry> = {
[DownloadToWorkspaceFile.id]: DownloadToWorkspaceFile,
[EditContent.id]: EditContent,
[EditWorkflow.id]: EditWorkflow,
[EnrichmentRun.id]: EnrichmentRun,
[Ffmpeg.id]: Ffmpeg,
[File.id]: File,
[FunctionExecute.id]: FunctionExecute,
@@ -4694,7 +4692,6 @@ export const TOOL_CATALOG: Record<string, ToolCatalogEntry> = {
[SetGlobalWorkflowVariables.id]: SetGlobalWorkflowVariables,
[Superagent.id]: Superagent,
[Table.id]: Table,
[TouchPlan.id]: TouchPlan,
[UpdateDeploymentVersion.id]: UpdateDeploymentVersion,
[UpdateJobHistory.id]: UpdateJobHistory,
[UpdateWorkspaceMcpServer.id]: UpdateWorkspaceMcpServer,
+156 -164
View File
@@ -10,7 +10,7 @@ export interface ToolRuntimeSchemaEntry {
}
export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
agent: {
['agent']: {
parameters: {
properties: {
request: {
@@ -23,7 +23,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
auth: {
['auth']: {
parameters: {
properties: {
request: {
@@ -36,7 +36,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
check_deployment_status: {
['check_deployment_status']: {
parameters: {
type: 'object',
properties: {
@@ -48,7 +48,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
complete_job: {
['complete_job']: {
parameters: {
type: 'object',
properties: {
@@ -61,7 +61,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
crawl_website: {
['crawl_website']: {
parameters: {
type: 'object',
properties: {
@@ -96,7 +96,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
create_file: {
['create_file']: {
parameters: {
type: 'object',
properties: {
@@ -162,7 +162,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
create_file_folder: {
['create_file_folder']: {
parameters: {
type: 'object',
properties: {
@@ -180,7 +180,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
create_folder: {
['create_folder']: {
parameters: {
type: 'object',
properties: {
@@ -201,7 +201,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
create_workflow: {
['create_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -226,7 +226,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
create_workspace_mcp_server: {
['create_workspace_mcp_server']: {
parameters: {
type: 'object',
properties: {
@@ -259,7 +259,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
delete_file: {
['delete_file']: {
parameters: {
type: 'object',
properties: {
@@ -289,7 +289,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
delete_file_folder: {
['delete_file_folder']: {
parameters: {
type: 'object',
properties: {
@@ -305,7 +305,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
delete_folder: {
['delete_folder']: {
parameters: {
type: 'object',
properties: {
@@ -321,7 +321,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
delete_workflow: {
['delete_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -337,7 +337,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
delete_workspace_mcp_server: {
['delete_workspace_mcp_server']: {
parameters: {
type: 'object',
properties: {
@@ -350,7 +350,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
deploy: {
['deploy']: {
parameters: {
properties: {
request: {
@@ -364,7 +364,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
deploy_api: {
['deploy_api']: {
parameters: {
type: 'object',
properties: {
@@ -448,7 +448,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
],
},
},
deploy_chat: {
['deploy_chat']: {
parameters: {
type: 'object',
properties: {
@@ -607,7 +607,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
],
},
},
deploy_mcp: {
['deploy_mcp']: {
parameters: {
type: 'object',
properties: {
@@ -723,7 +723,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['deploymentType', 'deploymentStatus'],
},
},
diff_workflows: {
['diff_workflows']: {
parameters: {
type: 'object',
properties: {
@@ -747,7 +747,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
download_to_workspace_file: {
['download_to_workspace_file']: {
parameters: {
type: 'object',
properties: {
@@ -796,7 +796,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
edit_content: {
['edit_content']: {
parameters: {
type: 'object',
properties: {
@@ -828,7 +828,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
edit_workflow: {
['edit_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -867,7 +867,51 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
ffmpeg: {
['enrichment_run']: {
parameters: {
type: 'object',
properties: {
enrichmentId: {
type: 'string',
description:
"Which enrichment to run. Discover the full set and each one's inputs/outputs via user_table.list_enrichments.",
enum: [
'work-email',
'phone-number',
'company-domain',
'company-info',
'email-verification',
],
},
inputs: {
type: 'object',
description:
'Map of the enrichment\'s input id → value, e.g. { "fullName": "Jane Doe", "companyDomain": "acme.com" }. Provide a value for every required input.',
},
},
required: ['enrichmentId', 'inputs'],
},
resultSchema: {
type: 'object',
properties: {
matched: {
type: 'boolean',
description: 'True when a provider returned a non-empty result.',
},
provider: {
type: 'string',
description:
'Internal label of the provider that produced the result (billing/diagnostics only — do NOT surface it to the user), or null on no match.',
},
result: {
type: 'object',
description: 'Mapped output values from the winning provider (empty object on no match).',
},
},
required: ['matched', 'result'],
},
},
['ffmpeg']: {
parameters: {
type: 'object',
properties: {
@@ -902,7 +946,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -922,7 +966,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1009,8 +1053,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1049,7 +1092,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
file: {
['file']: {
parameters: {
properties: {
prompt: {
@@ -1062,7 +1105,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
function_execute: {
['function_execute']: {
parameters: {
type: 'object',
properties: {
@@ -1086,7 +1129,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1106,7 +1149,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1177,8 +1220,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1201,7 +1243,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
generate_api_key: {
['generate_api_key']: {
parameters: {
type: 'object',
properties: {
@@ -1219,7 +1261,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
generate_audio: {
['generate_audio']: {
parameters: {
type: 'object',
properties: {
@@ -1243,7 +1285,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1263,7 +1305,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1339,8 +1381,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1372,7 +1413,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
generate_image: {
['generate_image']: {
parameters: {
type: 'object',
properties: {
@@ -1396,7 +1437,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1416,7 +1457,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1477,8 +1518,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1501,7 +1541,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
generate_video: {
['generate_video']: {
parameters: {
type: 'object',
properties: {
@@ -1534,7 +1574,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS folder path, e.g. "files/Reports" or "workflows/My%20Workflow/.plans". By default this mounts at "/home/user/{path}". Workflow alias directories mount under "/home/user/workflows/...".',
'Canonical VFS folder path, e.g. "files/Reports". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1554,7 +1594,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
path: {
type: 'string',
description:
'Canonical VFS file path, e.g. "files/Reports/sales.csv" or "workflows/My%20Workflow/changelog.md". By default this mounts at "/home/user/{path}". Workflow alias paths mount under "/home/user/workflows/...".',
'Canonical VFS file path, e.g. "files/Reports/sales.csv". By default this mounts at "/home/user/{path}".',
},
sandboxPath: {
type: 'string',
@@ -1636,8 +1676,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
path: {
type: 'string',
description:
'Canonical destination VFS path, e.g. "files/Reports/chart.png", "workflows/My%20Workflow/changelog.md", or "workflows/My%20Workflow/.plans/plan.md".',
description: 'Canonical destination VFS path, e.g. "files/Reports/chart.png".',
},
sandboxPath: {
type: 'string',
@@ -1669,7 +1708,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_block_outputs: {
['get_block_outputs']: {
parameters: {
type: 'object',
properties: {
@@ -1690,7 +1729,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_block_upstream_references: {
['get_block_upstream_references']: {
parameters: {
type: 'object',
properties: {
@@ -1712,7 +1751,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_deployed_workflow_state: {
['get_deployed_workflow_state']: {
parameters: {
type: 'object',
properties: {
@@ -1725,7 +1764,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_deployment_log: {
['get_deployment_log']: {
parameters: {
type: 'object',
properties: {
@@ -1738,7 +1777,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_job_logs: {
['get_job_logs']: {
parameters: {
type: 'object',
properties: {
@@ -1763,7 +1802,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_page_contents: {
['get_page_contents']: {
parameters: {
type: 'object',
properties: {
@@ -1791,14 +1830,14 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_platform_actions: {
['get_platform_actions']: {
parameters: {
type: 'object',
properties: {},
},
resultSchema: undefined,
},
get_workflow_data: {
['get_workflow_data']: {
parameters: {
type: 'object',
properties: {
@@ -1817,7 +1856,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
get_workflow_run_options: {
['get_workflow_run_options']: {
parameters: {
type: 'object',
properties: {
@@ -1830,7 +1869,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
glob: {
['glob']: {
parameters: {
type: 'object',
properties: {
@@ -1849,7 +1888,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
grep: {
['grep']: {
parameters: {
type: 'object',
properties: {
@@ -1897,7 +1936,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
job: {
['job']: {
parameters: {
properties: {
request: {
@@ -1910,7 +1949,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
knowledge: {
['knowledge']: {
parameters: {
properties: {
request: {
@@ -1923,7 +1962,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
knowledge_base: {
['knowledge_base']: {
parameters: {
type: 'object',
properties: {
@@ -2116,7 +2155,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
list_file_folders: {
['list_file_folders']: {
parameters: {
type: 'object',
properties: {
@@ -2128,7 +2167,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
list_folders: {
['list_folders']: {
parameters: {
type: 'object',
properties: {
@@ -2140,7 +2179,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
list_integration_tools: {
['list_integration_tools']: {
parameters: {
properties: {
integration: {
@@ -2154,14 +2193,14 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
list_user_workspaces: {
['list_user_workspaces']: {
parameters: {
type: 'object',
properties: {},
},
resultSchema: undefined,
},
list_workspace_mcp_servers: {
['list_workspace_mcp_servers']: {
parameters: {
type: 'object',
properties: {
@@ -2174,7 +2213,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
load_deployment: {
['load_deployment']: {
parameters: {
type: 'object',
properties: {
@@ -2193,7 +2232,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
load_integration_tool: {
['load_integration_tool']: {
parameters: {
properties: {
tool_ids: {
@@ -2210,7 +2249,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
manage_credential: {
['manage_credential']: {
parameters: {
type: 'object',
properties: {
@@ -2239,7 +2278,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
manage_custom_tool: {
['manage_custom_tool']: {
parameters: {
type: 'object',
properties: {
@@ -2319,7 +2358,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
manage_job: {
['manage_job']: {
parameters: {
type: 'object',
properties: {
@@ -2394,7 +2433,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
manage_mcp_tool: {
['manage_mcp_tool']: {
parameters: {
type: 'object',
properties: {
@@ -2446,7 +2485,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
manage_skill: {
['manage_skill']: {
parameters: {
type: 'object',
properties: {
@@ -2479,7 +2518,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
materialize_file: {
['materialize_file']: {
parameters: {
type: 'object',
properties: {
@@ -2503,7 +2542,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
media: {
['media']: {
parameters: {
properties: {
prompt: {
@@ -2516,7 +2555,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
move_file: {
['move_file']: {
parameters: {
type: 'object',
properties: {
@@ -2537,7 +2576,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
move_file_folder: {
['move_file_folder']: {
parameters: {
type: 'object',
properties: {
@@ -2555,7 +2594,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
move_folder: {
['move_folder']: {
parameters: {
type: 'object',
properties: {
@@ -2573,7 +2612,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
move_workflow: {
['move_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -2593,7 +2632,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
oauth_get_auth_link: {
['oauth_get_auth_link']: {
parameters: {
type: 'object',
properties: {
@@ -2607,7 +2646,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
oauth_request_access: {
['oauth_request_access']: {
parameters: {
type: 'object',
properties: {
@@ -2621,7 +2660,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
open_resource: {
['open_resource']: {
parameters: {
type: 'object',
properties: {
@@ -2655,7 +2694,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
promote_to_live: {
['promote_to_live']: {
parameters: {
type: 'object',
properties: {
@@ -2674,7 +2713,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
query_logs: {
['query_logs']: {
parameters: {
type: 'object',
properties: {
@@ -2785,7 +2824,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
read: {
['read']: {
parameters: {
type: 'object',
properties: {
@@ -2812,7 +2851,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
redeploy: {
['redeploy']: {
parameters: {
type: 'object',
properties: {
@@ -2891,7 +2930,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
],
},
},
rename_file: {
['rename_file']: {
parameters: {
type: 'object',
properties: {
@@ -2927,7 +2966,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
rename_file_folder: {
['rename_file_folder']: {
parameters: {
type: 'object',
properties: {
@@ -2944,7 +2983,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
rename_workflow: {
['rename_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -2961,7 +3000,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
research: {
['research']: {
parameters: {
properties: {
topic: {
@@ -2974,7 +3013,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
respond: {
['respond']: {
parameters: {
additionalProperties: true,
properties: {
@@ -2997,7 +3036,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
restore_resource: {
['restore_resource']: {
parameters: {
type: 'object',
properties: {
@@ -3015,7 +3054,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
run: {
['run']: {
parameters: {
properties: {
context: {
@@ -3032,7 +3071,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
run_block: {
['run_block']: {
parameters: {
type: 'object',
properties: {
@@ -3064,7 +3103,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
run_from_block: {
['run_from_block']: {
parameters: {
type: 'object',
properties: {
@@ -3096,7 +3135,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
run_workflow: {
['run_workflow']: {
parameters: {
type: 'object',
properties: {
@@ -3134,7 +3173,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
run_workflow_until_block: {
['run_workflow_until_block']: {
parameters: {
type: 'object',
properties: {
@@ -3177,7 +3216,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
scrape_page: {
['scrape_page']: {
parameters: {
type: 'object',
properties: {
@@ -3198,7 +3237,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
search_documentation: {
['search_documentation']: {
parameters: {
type: 'object',
properties: {
@@ -3215,7 +3254,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
search_library_docs: {
['search_library_docs']: {
parameters: {
type: 'object',
properties: {
@@ -3236,7 +3275,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
search_online: {
['search_online']: {
parameters: {
type: 'object',
properties: {
@@ -3276,7 +3315,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
search_patterns: {
['search_patterns']: {
parameters: {
type: 'object',
properties: {
@@ -3298,7 +3337,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
set_block_enabled: {
['set_block_enabled']: {
parameters: {
type: 'object',
properties: {
@@ -3320,7 +3359,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
set_environment_variables: {
['set_environment_variables']: {
parameters: {
type: 'object',
properties: {
@@ -3354,7 +3393,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
set_global_workflow_variables: {
['set_global_workflow_variables']: {
parameters: {
type: 'object',
properties: {
@@ -3395,7 +3434,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
superagent: {
['superagent']: {
parameters: {
properties: {
task: {
@@ -3409,7 +3448,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
table: {
['table']: {
parameters: {
properties: {
request: {
@@ -3422,54 +3461,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
touch_plan: {
parameters: {
type: 'object',
properties: {
name: {
type: 'string',
description:
'Plan file name or relative path under .plans, e.g. "implementation.md" or "phase-1/implementation.md". If no extension is supplied, ".md" is appended.',
},
scope: {
type: 'string',
description:
'Plan scope. Use "workspace" for root .plans/** main-agent plans. Use "workflow" for workflows/{workflow}/.plans/** subplans. If omitted with workflowPath, workflow scope is assumed; otherwise workspace scope is assumed.',
enum: ['workspace', 'workflow'],
},
title: {
type: 'string',
description: 'Optional short user-visible label for the plan creation.',
},
workflowPath: {
type: 'string',
description:
'Required for scope "workflow". Canonical workflow VFS path, e.g. "workflows/My%20Workflow" or "workflows/Folder/My%20Workflow". Copy paths verbatim from glob/read/grep output — they are percent-encoded per segment (spaces are %20, an in-name slash is %2F; parentheses and dots stay literal). Both the encoded path and the plain name resolve, so copy the returned path exactly rather than retyping or decoding it. Do not use workflow IDs.',
},
},
required: ['name'],
},
resultSchema: {
type: 'object',
properties: {
data: {
type: 'object',
description:
'Contains id, name, scope, vfsPath, backingVfsPath, and workflowId for workflow plans. Use vfsPath for follow-up workspace_file calls.',
},
message: {
type: 'string',
description: 'Human-readable outcome.',
},
success: {
type: 'boolean',
description: 'Whether the plan file was created.',
},
},
required: ['success', 'message'],
},
},
update_deployment_version: {
['update_deployment_version']: {
parameters: {
type: 'object',
properties: {
@@ -3498,7 +3490,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
update_job_history: {
['update_job_history']: {
parameters: {
type: 'object',
properties: {
@@ -3516,7 +3508,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
update_workspace_mcp_server: {
['update_workspace_mcp_server']: {
parameters: {
type: 'object',
properties: {
@@ -3541,7 +3533,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
user_memory: {
['user_memory']: {
parameters: {
type: 'object',
properties: {
@@ -3590,7 +3582,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
user_table: {
['user_table']: {
parameters: {
type: 'object',
properties: {
@@ -3952,7 +3944,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
required: ['success', 'message'],
},
},
workflow: {
['workflow']: {
parameters: {
properties: {
prompt: {
@@ -3965,7 +3957,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record<string, ToolRuntimeSchemaEntry> = {
},
resultSchema: undefined,
},
workspace_file: {
['workspace_file']: {
parameters: {
type: 'object',
properties: {
@@ -0,0 +1,66 @@
import { createLogger } from '@sim/logger'
import { EnrichmentRun } from '@/lib/copilot/generated/tool-catalog-v1'
import type { BaseServerTool } from '@/lib/copilot/tools/server/base-tool'
import { getEnrichment } from '@/enrichments/registry'
import { runEnrichment } from '@/enrichments/run'
interface EnrichmentRunParams {
enrichmentId: string
inputs: Record<string, unknown>
}
interface EnrichmentRunResult {
matched: boolean
result: Record<string, unknown>
provider: string | null
/** Hosted-key cost surfaced for per-round billing (omitted for BYOK / free). */
_serviceCost?: { service: string; cost: number }
}
/**
* Direct one-off enrichment lookup. Runs the same provider cascade as table
* enrichments (`runEnrichment`) for a single entity and returns the result
* inline — no table required. The hosted-key cost is surfaced as `_serviceCost`
* so copilot's per-round billing charges for it, matching how the media tools
* bill (see image/generate-image.ts).
*/
export const enrichmentRunServerTool: BaseServerTool<EnrichmentRunParams, EnrichmentRunResult> = {
name: EnrichmentRun.id,
async execute(params: EnrichmentRunParams, context): Promise<EnrichmentRunResult> {
const logger = createLogger('EnrichmentRunServerTool')
const { enrichmentId, inputs } = params
if (!enrichmentId || typeof enrichmentId !== 'string') {
throw new Error('enrichmentId is required')
}
const workspaceId = context?.workspaceId
if (!workspaceId) {
throw new Error('workspaceId is required to run an enrichment')
}
const enrichment = getEnrichment(enrichmentId)
if (!enrichment) {
throw new Error(`Unknown enrichment "${enrichmentId}"`)
}
const { result, cost, error, provider } = await runEnrichment(enrichment, inputs ?? {}, {
workspaceId,
signal: context?.abortSignal,
})
const matched = Object.keys(result).length > 0
logger.info('Enrichment run', { enrichmentId, matched, provider, cost })
// A genuine "no match" returns normally (matched: false). Only surface an
// error when every provider that ran failed (infra/auth/rate-limit).
if (error && !matched) {
throw new Error(error)
}
return {
matched,
result,
provider,
...(cost > 0 ? { _serviceCost: { service: provider ?? enrichmentId, cost } } : {}),
}
},
}
@@ -56,7 +56,7 @@ export const createFileServerTool: BaseServerTool<CreateFileArgs, CreateFileResu
return {
success: false,
message:
'create_file does not initialize plan aliases. Use touch_plan for new workspace or workflow plans; changelog.md is created automatically per workflow.',
'create_file does not initialize plan aliases; changelog.md is created automatically per workflow.',
}
}
const contentType = outputFile?.mimeType ?? inferContentType(outputPath, explicitType)
@@ -1,143 +0,0 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const mocks = vi.hoisted(() => ({
ensureWorkspaceAccess: vi.fn(),
resolveWorkflowAliasForWorkspace: vi.fn(),
writeWorkspaceFileByPath: vi.fn(),
}))
vi.mock('@/lib/copilot/tools/handlers/access', () => ({
ensureWorkspaceAccess: mocks.ensureWorkspaceAccess,
}))
vi.mock('@/lib/copilot/vfs/workflow-alias-resolver', () => ({
resolveWorkflowAliasForWorkspace: mocks.resolveWorkflowAliasForWorkspace,
}))
vi.mock('@/lib/copilot/vfs/resource-writer', () => ({
writeWorkspaceFileByPath: mocks.writeWorkspaceFileByPath,
}))
vi.mock('@/lib/core/config/feature-flags', () => ({
isMothershipBetaFeaturesEnabled: true,
}))
import { touchPlanServerTool } from './touch-plan'
describe('touch_plan server tool', () => {
beforeEach(() => {
vi.clearAllMocks()
mocks.ensureWorkspaceAccess.mockResolvedValue(undefined)
})
it('creates a workflow-local plan alias and returns backing metadata', async () => {
mocks.resolveWorkflowAliasForWorkspace.mockResolvedValue({
kind: 'plan_file',
scope: 'workflow',
workflowId: 'wf_1',
workflowName: 'My Workflow',
workflowPath: 'workflows/My%20Workflow',
aliasPath: 'workflows/My%20Workflow/.plans/implementation.md',
backingPath: 'files/.plans/wf_1/implementation.md',
backingFolderPath: 'files/.plans/wf_1',
planRelativePath: 'implementation.md',
})
mocks.writeWorkspaceFileByPath.mockResolvedValue({
id: 'file-plan',
name: 'implementation.md',
vfsPath: 'workflows/My%20Workflow/.plans/implementation.md',
backingVfsPath: 'files/.plans/wf_1/implementation.md',
})
const result = await touchPlanServerTool.execute(
{ workflowPath: 'workflows/My Workflow', name: 'implementation' },
{ userId: 'user-1', workspaceId: 'workspace-1' }
)
expect(mocks.resolveWorkflowAliasForWorkspace).toHaveBeenCalledWith({
workspaceId: 'workspace-1',
path: 'workflows/My%20Workflow/.plans/implementation.md',
})
expect(mocks.writeWorkspaceFileByPath).toHaveBeenCalledWith({
workspaceId: 'workspace-1',
userId: 'user-1',
target: {
path: 'workflows/My%20Workflow/.plans/implementation.md',
mode: 'create',
mimeType: 'text/markdown',
},
buffer: Buffer.from('', 'utf-8'),
inferredMimeType: 'text/markdown',
})
expect(result).toMatchObject({
success: true,
data: {
id: 'file-plan',
scope: 'workflow',
vfsPath: 'workflows/My%20Workflow/.plans/implementation.md',
backingVfsPath: 'files/.plans/wf_1/implementation.md',
workflowId: 'wf_1',
},
})
})
it('creates a workspace root plan alias and returns backing metadata', async () => {
mocks.resolveWorkflowAliasForWorkspace.mockResolvedValue({
kind: 'plan_file',
scope: 'workspace',
aliasPath: '.plans/migration.md',
backingPath: 'files/.plans/workspace/migration.md',
backingFolderPath: 'files/.plans/workspace',
planRelativePath: 'migration.md',
})
mocks.writeWorkspaceFileByPath.mockResolvedValue({
id: 'file-root-plan',
name: 'migration.md',
vfsPath: '.plans/migration.md',
backingVfsPath: 'files/.plans/workspace/migration.md',
})
const result = await touchPlanServerTool.execute(
{ scope: 'workspace', name: 'migration' },
{ userId: 'user-1', workspaceId: 'workspace-1' }
)
expect(mocks.resolveWorkflowAliasForWorkspace).toHaveBeenCalledWith({
workspaceId: 'workspace-1',
path: '.plans/migration.md',
})
expect(mocks.writeWorkspaceFileByPath).toHaveBeenCalledWith({
workspaceId: 'workspace-1',
userId: 'user-1',
target: {
path: '.plans/migration.md',
mode: 'create',
mimeType: 'text/markdown',
},
buffer: Buffer.from('', 'utf-8'),
inferredMimeType: 'text/markdown',
})
expect(result).toMatchObject({
success: true,
data: {
id: 'file-root-plan',
scope: 'workspace',
vfsPath: '.plans/migration.md',
backingVfsPath: 'files/.plans/workspace/migration.md',
},
})
})
it('rejects missing workflows before writing', async () => {
mocks.resolveWorkflowAliasForWorkspace.mockResolvedValue(null)
const result = await touchPlanServerTool.execute(
{ workflowPath: 'workflows/Missing', name: 'implementation.md' },
{ userId: 'user-1', workspaceId: 'workspace-1' }
)
expect(result.success).toBe(false)
expect(result.message).toContain('Workflow not found')
expect(mocks.writeWorkspaceFileByPath).not.toHaveBeenCalled()
})
})
@@ -1,152 +0,0 @@
import { createLogger } from '@sim/logger'
import { ensureWorkspaceAccess } from '@/lib/copilot/tools/handlers/access'
import {
assertServerToolNotAborted,
type BaseServerTool,
type ServerToolContext,
} from '@/lib/copilot/tools/server/base-tool'
import {
canonicalizeVfsPath,
decodeVfsPathSegments,
encodeVfsPathSegments,
} from '@/lib/copilot/vfs/path-utils'
import { writeWorkspaceFileByPath } from '@/lib/copilot/vfs/resource-writer'
import { resolveWorkflowAliasForWorkspace } from '@/lib/copilot/vfs/workflow-alias-resolver'
import { isMothershipBetaFeaturesEnabled } from '@/lib/core/config/feature-flags'
const logger = createLogger('TouchPlanServerTool')
const TOUCH_PLAN_TOOL_ID = 'touch_plan'
interface TouchPlanArgs {
scope?: 'workspace' | 'workflow'
workflowPath?: string
name: string
title?: string
args?: Record<string, unknown>
}
interface TouchPlanResult {
success: boolean
message: string
data?: {
id: string
name: string
vfsPath: string
backingVfsPath?: string
scope: 'workspace' | 'workflow'
workflowId?: string
}
}
function normalizeWorkflowPath(path: string): string {
const trimmed = path.trim().replace(/^\/+|\/+$/g, '')
const withoutKnownLeaf = trimmed
.replace(/\/(meta|state|executions|deployment|versions|links)\.json$/, '')
.replace(/\/changelog\.md$/, '')
.replace(/\/\.plans$/, '')
const canonical = canonicalizeVfsPath(withoutKnownLeaf)
if (!canonical.startsWith('workflows/')) {
throw new Error('workflowPath must be a canonical workflows/... VFS path')
}
return canonical
}
function normalizePlanRelativePath(name: string): string {
const segments = decodeVfsPathSegments(name)
if (segments.length === 0) {
throw new Error('Plan name is required')
}
const leaf = segments.at(-1) ?? ''
const leafWithExtension = leaf.includes('.') ? leaf : `${leaf}.md`
return encodeVfsPathSegments([...segments.slice(0, -1), leafWithExtension])
}
export const touchPlanServerTool: BaseServerTool<TouchPlanArgs, TouchPlanResult> = {
name: TOUCH_PLAN_TOOL_ID,
async execute(params: TouchPlanArgs, context?: ServerToolContext): Promise<TouchPlanResult> {
if (!isMothershipBetaFeaturesEnabled) {
return { success: false, message: 'touch_plan is not available' }
}
if (!context?.userId) {
throw new Error('Authentication required')
}
const workspaceId = context.workspaceId
if (!workspaceId) {
return { success: false, message: 'Workspace ID is required' }
}
await ensureWorkspaceAccess(workspaceId, context.userId, 'write')
const nested = params.args
const nestedScope = nested?.scope as TouchPlanArgs['scope'] | undefined
const scope =
params.scope ||
nestedScope ||
(params.workflowPath || nested?.workflowPath ? 'workflow' : 'workspace')
const workflowPath = params.workflowPath || (nested?.workflowPath as string) || ''
const name = params.name || (nested?.name as string) || ''
if (!name) {
return { success: false, message: 'touch_plan requires name' }
}
if (scope !== 'workspace' && scope !== 'workflow') {
return { success: false, message: 'touch_plan scope must be "workspace" or "workflow"' }
}
if (scope === 'workflow' && !workflowPath) {
return {
success: false,
message: 'touch_plan with workflow scope requires workflowPath and name',
}
}
const planRelativePath = normalizePlanRelativePath(name)
const aliasPath =
scope === 'workspace'
? `.plans/${planRelativePath}`
: `${normalizeWorkflowPath(workflowPath)}/.plans/${planRelativePath}`
const alias = await resolveWorkflowAliasForWorkspace({ workspaceId, path: aliasPath })
if (!alias || alias.kind !== 'plan_file') {
return {
success: false,
message:
scope === 'workflow'
? `Workflow not found for plan path: ${aliasPath}`
: `Unsupported workspace plan path: ${aliasPath}`,
}
}
assertServerToolNotAborted(context)
const result = await writeWorkspaceFileByPath({
workspaceId,
userId: context.userId,
target: {
path: aliasPath,
mode: 'create',
mimeType: 'text/markdown',
},
buffer: Buffer.from('', 'utf-8'),
inferredMimeType: 'text/markdown',
})
logger.info('Workflow plan touched via copilot', {
workspaceId,
workflowId: alias.scope === 'workflow' ? alias.workflowId : undefined,
scope: alias.scope,
vfsPath: result.vfsPath,
backingVfsPath: result.backingVfsPath,
userId: context.userId,
})
return {
success: true,
message: `${alias.scope === 'workspace' ? 'Workspace' : 'Workflow'} plan "${result.vfsPath}" created successfully`,
data: {
id: result.id,
name: result.name,
vfsPath: result.vfsPath,
backingVfsPath: result.backingVfsPath,
scope: alias.scope,
workflowId: alias.scope === 'workflow' ? alias.workflowId : undefined,
},
}
},
}
+5 -11
View File
@@ -19,7 +19,6 @@ import {
MoveFileFolder,
RenameFile,
RenameFileFolder,
TouchPlan,
UserTable,
WorkspaceFile,
} from '@/lib/copilot/generated/tool-catalog-v1'
@@ -31,6 +30,7 @@ import {
import { getBlocksMetadataServerTool } from '@/lib/copilot/tools/server/blocks/get-blocks-metadata-tool'
import { getTriggerBlocksServerTool } from '@/lib/copilot/tools/server/blocks/get-trigger-blocks'
import { searchDocumentationServerTool } from '@/lib/copilot/tools/server/docs/search-documentation'
import { enrichmentRunServerTool } from '@/lib/copilot/tools/server/enrichment/enrichment-run'
import { createFileServerTool } from '@/lib/copilot/tools/server/files/create-file'
import { deleteFileServerTool } from '@/lib/copilot/tools/server/files/delete-file'
import { downloadToWorkspaceFileServerTool } from '@/lib/copilot/tools/server/files/download-to-workspace-file'
@@ -44,7 +44,6 @@ import {
renameFileFolderServerTool,
} from '@/lib/copilot/tools/server/files/file-folders'
import { renameFileServerTool } from '@/lib/copilot/tools/server/files/rename-file'
import { touchPlanServerTool } from '@/lib/copilot/tools/server/files/touch-plan'
import { workspaceFileServerTool } from '@/lib/copilot/tools/server/files/workspace-file'
import { validateGeneratedToolPayload } from '@/lib/copilot/tools/server/generated-schema'
import { generateImageServerTool } from '@/lib/copilot/tools/server/image/generate-image'
@@ -59,7 +58,6 @@ import { getCredentialsServerTool } from '@/lib/copilot/tools/server/user/get-cr
import { setEnvironmentVariablesServerTool } from '@/lib/copilot/tools/server/user/set-environment-variables'
import { editWorkflowServerTool } from '@/lib/copilot/tools/server/workflow/edit-workflow'
import { queryLogsServerTool } from '@/lib/copilot/tools/server/workflow/query-logs'
import { isMothershipBetaFeaturesEnabled } from '@/lib/core/config/feature-flags'
export type ExecuteResponseSuccess = z.output<typeof ExecuteResponseSuccessSchema>
@@ -112,7 +110,6 @@ const WRITE_ACTIONS: Record<string, string[]> = {
[WorkspaceFile.id]: ['create', 'append', 'update', 'delete', 'rename', 'patch'],
[editContentServerTool.name]: ['*'],
[CreateFile.id]: ['*'],
[TouchPlan.id]: ['*'],
[RenameFile.id]: ['*'],
[DeleteFile.id]: ['*'],
[MoveFile.id]: ['*'],
@@ -125,6 +122,8 @@ const WRITE_ACTIONS: Record<string, string[]> = {
[GenerateVideo.id]: ['generate'],
[GenerateAudio.id]: ['generate'],
[Ffmpeg.id]: ['*'],
// Paid external-provider lookups (hosted-key cost), like the media tools.
[enrichmentRunServerTool.name]: ['*'],
}
function isWritePermission(userPermission: string): boolean {
@@ -151,11 +150,11 @@ const baseServerToolRegistry: Record<string, BaseServerTool> = {
[setEnvironmentVariablesServerTool.name]: setEnvironmentVariablesServerTool,
[getCredentialsServerTool.name]: getCredentialsServerTool,
[knowledgeBaseServerTool.name]: knowledgeBaseServerTool,
[enrichmentRunServerTool.name]: enrichmentRunServerTool,
[userTableServerTool.name]: userTableServerTool,
[workspaceFileServerTool.name]: workspaceFileServerTool,
[editContentServerTool.name]: editContentServerTool,
[createFileServerTool.name]: createFileServerTool,
[touchPlanServerTool.name]: touchPlanServerTool,
[renameFileServerTool.name]: renameFileServerTool,
[deleteFileServerTool.name]: deleteFileServerTool,
[moveFileServerTool.name]: moveFileServerTool,
@@ -172,12 +171,7 @@ const baseServerToolRegistry: Record<string, BaseServerTool> = {
}
function getServerToolRegistry(): Record<string, BaseServerTool> {
if (isMothershipBetaFeaturesEnabled) {
return baseServerToolRegistry
}
const registry = { ...baseServerToolRegistry }
delete registry[touchPlanServerTool.name]
return registry
return baseServerToolRegistry
}
export function getRegisteredServerToolNames(): string[] {
+1 -3
View File
@@ -207,9 +207,7 @@ async function resolveWorkflowAliasFileTarget(args: {
includeReservedSystemFolders: true,
})
if (!folderId) {
throw new Error(
`Plan backing directory is not provisioned for ${args.alias.aliasPath}. Create the plan with touch_plan first.`
)
throw new Error(`Plan backing directory is not provisioned for ${args.alias.aliasPath}.`)
}
return {
-2
View File
@@ -33,8 +33,6 @@
"mship-contracts:check": "bun run scripts/sync-mothership-stream-contract.ts --check",
"mship-tools:generate": "bun run scripts/sync-tool-catalog.ts",
"mship-tools:check": "bun run scripts/sync-tool-catalog.ts --check",
"trace-contracts:generate": "bun run scripts/sync-request-trace-contract.ts",
"trace-contracts:check": "bun run scripts/sync-request-trace-contract.ts --check",
"trace-spans-contract:generate": "bun run scripts/sync-trace-spans-contract.ts",
"trace-spans-contract:check": "bun run scripts/sync-trace-spans-contract.ts --check",
"trace-attributes-contract:generate": "bun run scripts/sync-trace-attributes-contract.ts",
-1
View File
@@ -19,7 +19,6 @@ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const GENERATORS = [
'scripts/sync-mothership-stream-contract.ts',
'scripts/sync-tool-catalog.ts',
'scripts/sync-request-trace-contract.ts',
'scripts/sync-trace-spans-contract.ts',
'scripts/sync-trace-attributes-contract.ts',
'scripts/sync-trace-attribute-values-contract.ts',
-77
View File
@@ -1,77 +0,0 @@
import { mkdir, readFile, writeFile } from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { compile } from 'json-schema-to-typescript'
import { formatGeneratedSource } from './format-generated-source'
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url))
const ROOT = resolve(SCRIPT_DIR, '..')
const DEFAULT_CONTRACT_PATH = resolve(
ROOT,
'../copilot/copilot/contracts/request-trace-v1.schema.json'
)
const OUTPUT_PATH = resolve(ROOT, 'apps/sim/lib/copilot/generated/request-trace-v1.ts')
function generateRuntimeConstants(schema: Record<string, unknown>): string {
const defs = (schema.$defs ?? schema.definitions ?? {}) as Record<string, unknown>
const lines: string[] = []
for (const [name, def] of Object.entries(defs)) {
if (!def || typeof def !== 'object') continue
const defObj = def as Record<string, unknown>
const enumValues = defObj.enum
if (!Array.isArray(enumValues) || enumValues.length === 0) continue
if (!enumValues.every((v) => typeof v === 'string')) continue
const entries = (enumValues as string[])
.map((v) => ` ${JSON.stringify(v)}: ${JSON.stringify(v)}`)
.join(',\n')
lines.push(`export const ${name} = {\n${entries},\n} as const;\n`)
}
return lines.join('\n')
}
async function main() {
const checkOnly = process.argv.includes('--check')
const inputPathArg = process.argv.find((arg) => arg.startsWith('--input='))
const inputPath = inputPathArg
? resolve(ROOT, inputPathArg.slice('--input='.length))
: DEFAULT_CONTRACT_PATH
const raw = await readFile(inputPath, 'utf8')
const schema = JSON.parse(raw)
const types = await compile(schema, 'RequestTraceV1SimReport', {
bannerComment: '// AUTO-GENERATED FILE. DO NOT EDIT.\n//',
unreachableDefinitions: true,
additionalProperties: false,
})
const constants = generateRuntimeConstants(schema)
const rendered = formatGeneratedSource(
constants ? `${types}\n${constants}\n` : types,
OUTPUT_PATH,
ROOT
)
if (checkOnly) {
const existing = await readFile(OUTPUT_PATH, 'utf8').catch(() => null)
if (existing !== rendered) {
throw new Error(
`Generated request trace contract is stale. Run: bun run trace-contracts:generate`
)
}
console.log('Request trace contract is up to date.')
return
}
await mkdir(dirname(OUTPUT_PATH), { recursive: true })
await writeFile(OUTPUT_PATH, rendered, 'utf8')
console.log(`Generated request trace types -> ${OUTPUT_PATH}`)
}
main().catch((err) => {
console.error(err)
process.exit(1)
})