diff --git a/apps/sim/lib/copilot/generated/tool-catalog-v1.ts b/apps/sim/lib/copilot/generated/tool-catalog-v1.ts index 4abbd46b8db..a6b42aba811 100644 --- a/apps/sim/lib/copilot/generated/tool-catalog-v1.ts +++ b/apps/sim/lib/copilot/generated/tool-catalog-v1.ts @@ -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,54 @@ 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: 'Label of the provider that produced the result, or null on no match.', + }, + result: { + type: 'object', + description: 'Mapped output values from the winning provider (empty object on no match).', + }, + }, + required: ['matched', 'result'], + }, +} + export const Ffmpeg: ToolCatalogEntry = { id: 'ffmpeg', name: 'ffmpeg', @@ -1106,7 +1154,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 +1174,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 +1255,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 +1334,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 +1354,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 +1419,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 +1495,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 +1515,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 +1585,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 +1644,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 +1664,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 +1719,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 +1781,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 +1801,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 +1877,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 +3737,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 +4622,7 @@ export const TOOL_CATALOG: Record = { [DownloadToWorkspaceFile.id]: DownloadToWorkspaceFile, [EditContent.id]: EditContent, [EditWorkflow.id]: EditWorkflow, + [EnrichmentRun.id]: EnrichmentRun, [Ffmpeg.id]: Ffmpeg, [File.id]: File, [FunctionExecute.id]: FunctionExecute, @@ -4694,7 +4690,6 @@ export const TOOL_CATALOG: Record = { [SetGlobalWorkflowVariables.id]: SetGlobalWorkflowVariables, [Superagent.id]: Superagent, [Table.id]: Table, - [TouchPlan.id]: TouchPlan, [UpdateDeploymentVersion.id]: UpdateDeploymentVersion, [UpdateJobHistory.id]: UpdateJobHistory, [UpdateWorkspaceMcpServer.id]: UpdateWorkspaceMcpServer, diff --git a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts index 0c4c0d06517..77888ddef2c 100644 --- a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts +++ b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts @@ -10,7 +10,7 @@ export interface ToolRuntimeSchemaEntry { } export const TOOL_RUNTIME_SCHEMAS: Record = { - agent: { + ['agent']: { parameters: { properties: { request: { @@ -23,7 +23,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - auth: { + ['auth']: { parameters: { properties: { request: { @@ -36,7 +36,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - check_deployment_status: { + ['check_deployment_status']: { parameters: { type: 'object', properties: { @@ -48,7 +48,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - complete_job: { + ['complete_job']: { parameters: { type: 'object', properties: { @@ -61,7 +61,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - crawl_website: { + ['crawl_website']: { parameters: { type: 'object', properties: { @@ -96,7 +96,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - create_file: { + ['create_file']: { parameters: { type: 'object', properties: { @@ -162,7 +162,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - create_file_folder: { + ['create_file_folder']: { parameters: { type: 'object', properties: { @@ -180,7 +180,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - create_folder: { + ['create_folder']: { parameters: { type: 'object', properties: { @@ -201,7 +201,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - create_workflow: { + ['create_workflow']: { parameters: { type: 'object', properties: { @@ -226,7 +226,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - create_workspace_mcp_server: { + ['create_workspace_mcp_server']: { parameters: { type: 'object', properties: { @@ -259,7 +259,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - delete_file: { + ['delete_file']: { parameters: { type: 'object', properties: { @@ -289,7 +289,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - delete_file_folder: { + ['delete_file_folder']: { parameters: { type: 'object', properties: { @@ -305,7 +305,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - delete_folder: { + ['delete_folder']: { parameters: { type: 'object', properties: { @@ -321,7 +321,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - delete_workflow: { + ['delete_workflow']: { parameters: { type: 'object', properties: { @@ -337,7 +337,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - delete_workspace_mcp_server: { + ['delete_workspace_mcp_server']: { parameters: { type: 'object', properties: { @@ -350,7 +350,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - deploy: { + ['deploy']: { parameters: { properties: { request: { @@ -364,7 +364,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - deploy_api: { + ['deploy_api']: { parameters: { type: 'object', properties: { @@ -448,7 +448,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { ], }, }, - deploy_chat: { + ['deploy_chat']: { parameters: { type: 'object', properties: { @@ -607,7 +607,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { ], }, }, - deploy_mcp: { + ['deploy_mcp']: { parameters: { type: 'object', properties: { @@ -723,7 +723,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['deploymentType', 'deploymentStatus'], }, }, - diff_workflows: { + ['diff_workflows']: { parameters: { type: 'object', properties: { @@ -747,7 +747,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - download_to_workspace_file: { + ['download_to_workspace_file']: { parameters: { type: 'object', properties: { @@ -796,7 +796,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - edit_content: { + ['edit_content']: { parameters: { type: 'object', properties: { @@ -828,7 +828,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - edit_workflow: { + ['edit_workflow']: { parameters: { type: 'object', properties: { @@ -867,7 +867,50 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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: 'Label of the provider that produced the result, 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 +945,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +965,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1052,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1091,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - file: { + ['file']: { parameters: { properties: { prompt: { @@ -1062,7 +1104,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - function_execute: { + ['function_execute']: { parameters: { type: 'object', properties: { @@ -1086,7 +1128,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1148,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1219,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1242,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - generate_api_key: { + ['generate_api_key']: { parameters: { type: 'object', properties: { @@ -1219,7 +1260,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - generate_audio: { + ['generate_audio']: { parameters: { type: 'object', properties: { @@ -1243,7 +1284,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1304,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1380,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1412,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - generate_image: { + ['generate_image']: { parameters: { type: 'object', properties: { @@ -1396,7 +1436,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1456,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1517,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1540,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - generate_video: { + ['generate_video']: { parameters: { type: 'object', properties: { @@ -1534,7 +1573,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1593,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { 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 +1675,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1707,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_block_outputs: { + ['get_block_outputs']: { parameters: { type: 'object', properties: { @@ -1690,7 +1728,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_block_upstream_references: { + ['get_block_upstream_references']: { parameters: { type: 'object', properties: { @@ -1712,7 +1750,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_deployed_workflow_state: { + ['get_deployed_workflow_state']: { parameters: { type: 'object', properties: { @@ -1725,7 +1763,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_deployment_log: { + ['get_deployment_log']: { parameters: { type: 'object', properties: { @@ -1738,7 +1776,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_job_logs: { + ['get_job_logs']: { parameters: { type: 'object', properties: { @@ -1763,7 +1801,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_page_contents: { + ['get_page_contents']: { parameters: { type: 'object', properties: { @@ -1791,14 +1829,14 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +1855,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - get_workflow_run_options: { + ['get_workflow_run_options']: { parameters: { type: 'object', properties: { @@ -1830,7 +1868,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - glob: { + ['glob']: { parameters: { type: 'object', properties: { @@ -1849,7 +1887,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - grep: { + ['grep']: { parameters: { type: 'object', properties: { @@ -1897,7 +1935,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - job: { + ['job']: { parameters: { properties: { request: { @@ -1910,7 +1948,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - knowledge: { + ['knowledge']: { parameters: { properties: { request: { @@ -1923,7 +1961,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - knowledge_base: { + ['knowledge_base']: { parameters: { type: 'object', properties: { @@ -2116,7 +2154,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - list_file_folders: { + ['list_file_folders']: { parameters: { type: 'object', properties: { @@ -2128,7 +2166,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - list_folders: { + ['list_folders']: { parameters: { type: 'object', properties: { @@ -2140,7 +2178,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - list_integration_tools: { + ['list_integration_tools']: { parameters: { properties: { integration: { @@ -2154,14 +2192,14 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +2212,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - load_deployment: { + ['load_deployment']: { parameters: { type: 'object', properties: { @@ -2193,7 +2231,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - load_integration_tool: { + ['load_integration_tool']: { parameters: { properties: { tool_ids: { @@ -2210,7 +2248,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - manage_credential: { + ['manage_credential']: { parameters: { type: 'object', properties: { @@ -2239,7 +2277,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - manage_custom_tool: { + ['manage_custom_tool']: { parameters: { type: 'object', properties: { @@ -2319,7 +2357,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - manage_job: { + ['manage_job']: { parameters: { type: 'object', properties: { @@ -2394,7 +2432,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - manage_mcp_tool: { + ['manage_mcp_tool']: { parameters: { type: 'object', properties: { @@ -2446,7 +2484,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - manage_skill: { + ['manage_skill']: { parameters: { type: 'object', properties: { @@ -2479,7 +2517,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - materialize_file: { + ['materialize_file']: { parameters: { type: 'object', properties: { @@ -2503,7 +2541,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - media: { + ['media']: { parameters: { properties: { prompt: { @@ -2516,7 +2554,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - move_file: { + ['move_file']: { parameters: { type: 'object', properties: { @@ -2537,7 +2575,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - move_file_folder: { + ['move_file_folder']: { parameters: { type: 'object', properties: { @@ -2555,7 +2593,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - move_folder: { + ['move_folder']: { parameters: { type: 'object', properties: { @@ -2573,7 +2611,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - move_workflow: { + ['move_workflow']: { parameters: { type: 'object', properties: { @@ -2593,7 +2631,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - oauth_get_auth_link: { + ['oauth_get_auth_link']: { parameters: { type: 'object', properties: { @@ -2607,7 +2645,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - oauth_request_access: { + ['oauth_request_access']: { parameters: { type: 'object', properties: { @@ -2621,7 +2659,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - open_resource: { + ['open_resource']: { parameters: { type: 'object', properties: { @@ -2655,7 +2693,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - promote_to_live: { + ['promote_to_live']: { parameters: { type: 'object', properties: { @@ -2674,7 +2712,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - query_logs: { + ['query_logs']: { parameters: { type: 'object', properties: { @@ -2785,7 +2823,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - read: { + ['read']: { parameters: { type: 'object', properties: { @@ -2812,7 +2850,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - redeploy: { + ['redeploy']: { parameters: { type: 'object', properties: { @@ -2891,7 +2929,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { ], }, }, - rename_file: { + ['rename_file']: { parameters: { type: 'object', properties: { @@ -2927,7 +2965,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - rename_file_folder: { + ['rename_file_folder']: { parameters: { type: 'object', properties: { @@ -2944,7 +2982,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - rename_workflow: { + ['rename_workflow']: { parameters: { type: 'object', properties: { @@ -2961,7 +2999,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - research: { + ['research']: { parameters: { properties: { topic: { @@ -2974,7 +3012,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - respond: { + ['respond']: { parameters: { additionalProperties: true, properties: { @@ -2997,7 +3035,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - restore_resource: { + ['restore_resource']: { parameters: { type: 'object', properties: { @@ -3015,7 +3053,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - run: { + ['run']: { parameters: { properties: { context: { @@ -3032,7 +3070,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - run_block: { + ['run_block']: { parameters: { type: 'object', properties: { @@ -3064,7 +3102,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - run_from_block: { + ['run_from_block']: { parameters: { type: 'object', properties: { @@ -3096,7 +3134,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - run_workflow: { + ['run_workflow']: { parameters: { type: 'object', properties: { @@ -3134,7 +3172,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - run_workflow_until_block: { + ['run_workflow_until_block']: { parameters: { type: 'object', properties: { @@ -3177,7 +3215,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - scrape_page: { + ['scrape_page']: { parameters: { type: 'object', properties: { @@ -3198,7 +3236,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - search_documentation: { + ['search_documentation']: { parameters: { type: 'object', properties: { @@ -3215,7 +3253,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - search_library_docs: { + ['search_library_docs']: { parameters: { type: 'object', properties: { @@ -3236,7 +3274,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - search_online: { + ['search_online']: { parameters: { type: 'object', properties: { @@ -3276,7 +3314,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - search_patterns: { + ['search_patterns']: { parameters: { type: 'object', properties: { @@ -3298,7 +3336,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - set_block_enabled: { + ['set_block_enabled']: { parameters: { type: 'object', properties: { @@ -3320,7 +3358,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - set_environment_variables: { + ['set_environment_variables']: { parameters: { type: 'object', properties: { @@ -3354,7 +3392,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - set_global_workflow_variables: { + ['set_global_workflow_variables']: { parameters: { type: 'object', properties: { @@ -3395,7 +3433,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - superagent: { + ['superagent']: { parameters: { properties: { task: { @@ -3409,7 +3447,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - table: { + ['table']: { parameters: { properties: { request: { @@ -3422,54 +3460,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, 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 +3489,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - update_job_history: { + ['update_job_history']: { parameters: { type: 'object', properties: { @@ -3516,7 +3507,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - update_workspace_mcp_server: { + ['update_workspace_mcp_server']: { parameters: { type: 'object', properties: { @@ -3541,7 +3532,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - user_memory: { + ['user_memory']: { parameters: { type: 'object', properties: { @@ -3590,7 +3581,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - user_table: { + ['user_table']: { parameters: { type: 'object', properties: { @@ -3952,7 +3943,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { required: ['success', 'message'], }, }, - workflow: { + ['workflow']: { parameters: { properties: { prompt: { @@ -3965,7 +3956,7 @@ export const TOOL_RUNTIME_SCHEMAS: Record = { }, resultSchema: undefined, }, - workspace_file: { + ['workspace_file']: { parameters: { type: 'object', properties: { diff --git a/apps/sim/lib/copilot/tools/server/enrichment/enrichment-run.ts b/apps/sim/lib/copilot/tools/server/enrichment/enrichment-run.ts new file mode 100644 index 00000000000..5acc5b04551 --- /dev/null +++ b/apps/sim/lib/copilot/tools/server/enrichment/enrichment-run.ts @@ -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 +} + +interface EnrichmentRunResult { + matched: boolean + result: Record + 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 = { + name: EnrichmentRun.id, + async execute(params: EnrichmentRunParams, context): Promise { + 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 } } : {}), + } + }, +} diff --git a/apps/sim/lib/copilot/tools/server/files/create-file.ts b/apps/sim/lib/copilot/tools/server/files/create-file.ts index d7b9489d6fd..146d0237773 100644 --- a/apps/sim/lib/copilot/tools/server/files/create-file.ts +++ b/apps/sim/lib/copilot/tools/server/files/create-file.ts @@ -56,7 +56,7 @@ export const createFileServerTool: BaseServerTool ({ - 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() - }) -}) diff --git a/apps/sim/lib/copilot/tools/server/files/touch-plan.ts b/apps/sim/lib/copilot/tools/server/files/touch-plan.ts deleted file mode 100644 index 168903236ba..00000000000 --- a/apps/sim/lib/copilot/tools/server/files/touch-plan.ts +++ /dev/null @@ -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 -} - -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 = { - name: TOUCH_PLAN_TOOL_ID, - async execute(params: TouchPlanArgs, context?: ServerToolContext): Promise { - 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, - }, - } - }, -} diff --git a/apps/sim/lib/copilot/tools/server/router.ts b/apps/sim/lib/copilot/tools/server/router.ts index a151b25a511..c62116d7f47 100644 --- a/apps/sim/lib/copilot/tools/server/router.ts +++ b/apps/sim/lib/copilot/tools/server/router.ts @@ -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 @@ -112,7 +110,6 @@ const WRITE_ACTIONS: Record = { [WorkspaceFile.id]: ['create', 'append', 'update', 'delete', 'rename', 'patch'], [editContentServerTool.name]: ['*'], [CreateFile.id]: ['*'], - [TouchPlan.id]: ['*'], [RenameFile.id]: ['*'], [DeleteFile.id]: ['*'], [MoveFile.id]: ['*'], @@ -151,11 +148,11 @@ const baseServerToolRegistry: Record = { [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 +169,7 @@ const baseServerToolRegistry: Record = { } function getServerToolRegistry(): Record { - if (isMothershipBetaFeaturesEnabled) { - return baseServerToolRegistry - } - const registry = { ...baseServerToolRegistry } - delete registry[touchPlanServerTool.name] - return registry + return baseServerToolRegistry } export function getRegisteredServerToolNames(): string[] { diff --git a/apps/sim/lib/copilot/vfs/resource-writer.ts b/apps/sim/lib/copilot/vfs/resource-writer.ts index 476c9186c83..460f6ba36dd 100644 --- a/apps/sim/lib/copilot/vfs/resource-writer.ts +++ b/apps/sim/lib/copilot/vfs/resource-writer.ts @@ -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 {