From 0aa2de55d8df275996f92272710039b0b7bf47f9 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 2 May 2026 18:05:16 -0700 Subject: [PATCH 1/4] hide new workflow column feature --- .../column-sidebar/column-sidebar.tsx | 9 +- .../lib/copilot/generated/tool-catalog-v1.ts | 114 +- .../lib/copilot/generated/tool-schemas-v1.ts | 5129 +++++++++-------- 3 files changed, 2640 insertions(+), 2612 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-sidebar/column-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-sidebar/column-sidebar.tsx index cd72fe26d57..69fc07bcf02 100644 --- a/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-sidebar/column-sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/column-sidebar/column-sidebar.tsx @@ -765,8 +765,13 @@ export function ColumnSidebar({ } const typeOptions = useMemo( - () => COLUMN_TYPE_OPTIONS.map((o) => ({ label: o.label, value: o.type, icon: o.icon })), - [] + () => + COLUMN_TYPE_OPTIONS.filter((o) => o.type !== 'workflow' || !!existingGroup).map((o) => ({ + label: o.label, + value: o.type, + icon: o.icon, + })), + [existingGroup] ) /** diff --git a/apps/sim/lib/copilot/generated/tool-catalog-v1.ts b/apps/sim/lib/copilot/generated/tool-catalog-v1.ts index 87966286490..5083432bd87 100644 --- a/apps/sim/lib/copilot/generated/tool-catalog-v1.ts +++ b/apps/sim/lib/copilot/generated/tool-catalog-v1.ts @@ -2792,15 +2792,6 @@ export const UserTable: ToolCatalogEntry = { type: 'object', description: 'Arguments for the operation', properties: { - autoRun: { - type: 'boolean', - description: - 'Optional flag for add_workflow_group. When true, existing rows whose dependencies are already filled run immediately. Default false: groups are staged silently — call run_workflow_group when ready to fire rows. Set true if the user explicitly asked you to start runs.', - }, - blockId: { - type: 'string', - description: 'Source block ID inside the workflow. Used by add_workflow_group_output.', - }, column: { type: 'object', description: 'Column definition for add_column: { name, type, unique?, position? }', @@ -2808,7 +2799,7 @@ export const UserTable: ToolCatalogEntry = { columnName: { type: 'string', description: - 'Column name. Required for rename_column, update_column, and delete_workflow_group_output (the bound column to drop). Optional for add_workflow_group_output (auto-derived from path when omitted). Use columnNames array for batch delete_column.', + 'Column name (required for rename_column, update_column; use columnNames array for batch delete_column)', }, columnNames: { type: 'array', @@ -2819,23 +2810,6 @@ export const UserTable: ToolCatalogEntry = { type: 'object', description: 'Row data as key-value pairs (required for insert_row, update_row)', }, - dependencies: { - type: 'object', - description: - 'Dependencies the workflow group requires before running a row. { columns?: string[] } lists input column names that must be filled; { workflowGroups?: string[] } lists other workflow group IDs whose outputs must complete first. Used by add_workflow_group and update_workflow_group.', - properties: { - columns: { - type: 'array', - description: 'Input column names that must be filled before the group runs.', - items: { type: 'string' }, - }, - workflowGroups: { - type: 'array', - description: 'Other workflow group IDs whose outputs must complete first.', - items: { type: 'string' }, - }, - }, - }, description: { type: 'string', description: "Table description (optional for 'create')" }, fileId: { type: 'string', @@ -2852,11 +2826,6 @@ export const UserTable: ToolCatalogEntry = { description: 'MongoDB-style filter for query_rows, update_rows_by_filter, delete_rows_by_filter', }, - groupId: { - type: 'string', - description: - 'Workflow group ID (required for update_workflow_group, delete_workflow_group, add_workflow_group_output, delete_workflow_group_output, run_workflow_group).', - }, limit: { type: 'number', description: 'Maximum rows to return or affect (optional, default 100)', @@ -2864,11 +2833,11 @@ export const UserTable: ToolCatalogEntry = { mapping: { type: 'object', description: - 'Optional explicit CSV-header → table-column mapping for import_file, as { "csvHeader": "columnName" | null }. A string maps the CSV header to that table column; null skips that CSV header (it won\'t be imported); omit a header entirely to fall back to auto-mapping by sanitized name (case-insensitive).', + 'Optional explicit CSV-header → table-column mapping for import_file, as { "csvHeader": "columnName" | null }. When omitted, headers are auto-matched by sanitized name (case-insensitive fallback). Use null to skip a CSV column.', additionalProperties: { - type: ['string', 'null'], + type: 'string', description: - "Target column name on the table. null skips that CSV header (it won't be imported); omit it entirely to fall back to auto-mapping.", + 'Target column name on the table. Use null to skip this CSV header instead of a column name.', }, }, mode: { @@ -2899,33 +2868,6 @@ export const UserTable: ToolCatalogEntry = { description: 'Pipe query_rows results directly to a NEW workspace file. The format is auto-inferred from the file extension: .csv → CSV, .json → JSON, .md → Markdown, etc. Use .csv for tabular exports. Use a flat path like "files/export.csv" — nested paths are not supported.', }, - outputs: { - type: 'array', - description: - "Outputs to surface as columns. Each entry maps a workflow block output to a table column: { blockId, path, columnName?, columnType? }. blockId is the source block; path is the dotted output path; columnName auto-derives from the path when omitted; columnType defaults from the leaf type when omitted. Used by add_workflow_group. (Also accepted by update_workflow_group for the UI's bulk replace, but the AI flow should use add_workflow_group_output / delete_workflow_group_output instead.) If unsure about valid (blockId, path) pairs, call list_workflow_outputs first — paths are validated against the live workflow and invalid picks return an error with the valid options. For Agent blocks with structured outputs, the structured fields appear as top-level paths (e.g. summary, industry); there is NO response.content path on a structured agent.", - items: { - type: 'object', - properties: { - blockId: { type: 'string', description: 'Source block ID inside the workflow.' }, - columnName: { - type: 'string', - description: - 'Optional target column name. Auto-derived from the path when omitted.', - }, - columnType: { - type: 'string', - description: 'Optional column type. Defaults from the leaf type when omitted.', - enum: ['string', 'number', 'boolean', 'date', 'json'], - }, - path: { type: 'string', description: 'Dotted output path on the block.' }, - }, - required: ['blockId', 'path'], - }, - }, - path: { - type: 'string', - description: 'Dotted output path on the block. Used by add_workflow_group_output.', - }, position: { type: 'integer', description: @@ -2939,36 +2881,21 @@ export const UserTable: ToolCatalogEntry = { }, rowId: { type: 'string', - description: - "Row ID. Required for get_row, update_row, delete_row, and for cancel_table_runs when scope:'row'.", + description: 'Row ID (required for get_row, update_row, delete_row)', }, rowIds: { type: 'array', - description: - 'Array of row IDs. Used by batch_delete_rows (rows to delete) and run_workflow_group (optional row scope: when omitted, runs across the whole table; when provided, only these rows are candidates and the eligibility predicate still applies — mid-run rows or rows with unmet deps are silently skipped).', - items: { type: 'string' }, + description: 'Array of row IDs to delete (for batch_delete_rows)', }, rows: { type: 'array', description: 'Array of row data objects (required for batch_insert_rows)', }, - runMode: { - type: 'string', - description: - "Run mode for run_workflow_group. 'incomplete' (default) re-runs only rows that never produced output or last failed; 'all' re-runs every dep-satisfied row.", - enum: ['incomplete', 'all'], - }, schema: { type: 'object', description: "Table schema with columns array (required for 'create'). Each column: { name, type, unique? }", }, - scope: { - type: 'string', - description: - "Cancellation scope for cancel_table_runs. 'all' cancels in-flight runs across the whole table; 'row' cancels only the row identified by rowId.", - enum: ['all', 'row'], - }, sort: { type: 'object', description: @@ -2998,11 +2925,6 @@ export const UserTable: ToolCatalogEntry = { description: 'Map of rowId to value for single-column batch update: { "rowId1": val1, "rowId2": val2 } (for batch_update_rows with columnName)', }, - workflowId: { - type: 'string', - description: - 'ID of the workflow (required for add_workflow_group and list_workflow_outputs).', - }, }, }, operation: { @@ -3029,14 +2951,6 @@ export const UserTable: ToolCatalogEntry = { 'rename_column', 'delete_column', 'update_column', - 'add_workflow_group', - 'update_workflow_group', - 'delete_workflow_group', - 'add_workflow_group_output', - 'delete_workflow_group_output', - 'run_workflow_group', - 'cancel_table_runs', - 'list_workflow_outputs', ], }, }, @@ -3375,14 +3289,6 @@ export const UserTableOperation = { renameColumn: 'rename_column', deleteColumn: 'delete_column', updateColumn: 'update_column', - addWorkflowGroup: 'add_workflow_group', - updateWorkflowGroup: 'update_workflow_group', - deleteWorkflowGroup: 'delete_workflow_group', - addWorkflowGroupOutput: 'add_workflow_group_output', - deleteWorkflowGroupOutput: 'delete_workflow_group_output', - runWorkflowGroup: 'run_workflow_group', - cancelTableRuns: 'cancel_table_runs', - listWorkflowOutputs: 'list_workflow_outputs', } as const export type UserTableOperation = (typeof UserTableOperation)[keyof typeof UserTableOperation] @@ -3408,14 +3314,6 @@ export const UserTableOperationValues = [ UserTableOperation.renameColumn, UserTableOperation.deleteColumn, UserTableOperation.updateColumn, - UserTableOperation.addWorkflowGroup, - UserTableOperation.updateWorkflowGroup, - UserTableOperation.deleteWorkflowGroup, - UserTableOperation.addWorkflowGroupOutput, - UserTableOperation.deleteWorkflowGroupOutput, - UserTableOperation.runWorkflowGroup, - UserTableOperation.cancelTableRuns, - UserTableOperation.listWorkflowOutputs, ] as const export const WorkspaceFileOperation = { diff --git a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts index bf53f649415..f450dccbcec 100644 --- a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts +++ b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts @@ -5,3027 +5,3152 @@ export type JsonSchema = unknown export interface ToolRuntimeSchemaEntry { - parameters?: JsonSchema - resultSchema?: JsonSchema + parameters?: JsonSchema; + resultSchema?: JsonSchema; } export const TOOL_RUNTIME_SCHEMAS: Record = { - agent: { + ["agent"]: { parameters: { - properties: { - request: { - description: 'What tool/skill/MCP action is needed.', - type: 'string', - }, + "properties": { + "request": { + "description": "What tool/skill/MCP action is needed.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - auth: { + ["auth"]: { parameters: { - properties: { - request: { - description: 'What authentication/credential action is needed.', - type: 'string', - }, + "properties": { + "request": { + "description": "What authentication/credential action is needed.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - check_deployment_status: { + ["check_deployment_status"]: { parameters: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID to check (defaults to current workflow)', - }, - }, + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "description": "Workflow ID to check (defaults to current workflow)" + } + } }, resultSchema: undefined, }, - complete_job: { + ["complete_job"]: { parameters: { - type: 'object', - properties: { - jobId: { - type: 'string', - description: 'The ID of the job to mark as completed.', - }, + "type": "object", + "properties": { + "jobId": { + "type": "string", + "description": "The ID of the job to mark as completed." + } }, - required: ['jobId'], + "required": [ + "jobId" + ] }, resultSchema: undefined, }, - context_write: { + ["context_write"]: { parameters: { - type: 'object', - properties: { - content: { - type: 'string', - description: 'Full content to write to the file (replaces existing content)', - }, - file_path: { - type: 'string', - description: "Path of the file to write (e.g. 'SESSION.md')", + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "Full content to write to the file (replaces existing content)" }, + "file_path": { + "type": "string", + "description": "Path of the file to write (e.g. 'SESSION.md')" + } }, - required: ['file_path', 'content'], + "required": [ + "file_path", + "content" + ] }, resultSchema: undefined, }, - crawl_website: { + ["crawl_website"]: { parameters: { - type: 'object', - properties: { - exclude_paths: { - type: 'array', - description: 'Skip URLs matching these patterns', - items: { - type: 'string', - }, - }, - include_paths: { - type: 'array', - description: 'Only crawl URLs matching these patterns', - items: { - type: 'string', - }, + "type": "object", + "properties": { + "exclude_paths": { + "type": "array", + "description": "Skip URLs matching these patterns", + "items": { + "type": "string" + } }, - limit: { - type: 'number', - description: 'Maximum pages to crawl (default 10, max 50)', + "include_paths": { + "type": "array", + "description": "Only crawl URLs matching these patterns", + "items": { + "type": "string" + } }, - max_depth: { - type: 'number', - description: 'How deep to follow links (default 2)', + "limit": { + "type": "number", + "description": "Maximum pages to crawl (default 10, max 50)" }, - url: { - type: 'string', - description: 'Starting URL to crawl from', + "max_depth": { + "type": "number", + "description": "How deep to follow links (default 2)" }, + "url": { + "type": "string", + "description": "Starting URL to crawl from" + } }, - required: ['url'], + "required": [ + "url" + ] }, resultSchema: undefined, }, - create_file: { + ["create_file"]: { parameters: { - type: 'object', - properties: { - contentType: { - type: 'string', - description: - 'Optional MIME type override. Usually omit and let the system infer from the file extension.', - }, - fileName: { - type: 'string', - description: - 'Plain workspace filename including extension, e.g. "main.py" or "report.md". Must not contain slashes.', + "type": "object", + "properties": { + "contentType": { + "type": "string", + "description": "Optional MIME type override. Usually omit and let the system infer from the file extension." }, + "fileName": { + "type": "string", + "description": "Plain workspace filename including extension, e.g. \"main.py\" or \"report.md\". Must not contain slashes." + } }, - required: ['fileName'], + "required": [ + "fileName" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: 'Contains id (the fileId) and name.', - }, - message: { - type: 'string', - description: 'Human-readable outcome.', + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Contains id (the fileId) and name." }, - success: { - type: 'boolean', - description: 'Whether the file was created.', + "message": { + "type": "string", + "description": "Human-readable outcome." }, + "success": { + "type": "boolean", + "description": "Whether the file was created." + } }, - required: ['success', 'message'], + "required": [ + "success", + "message" + ] }, }, - create_folder: { + ["create_folder"]: { parameters: { - type: 'object', - properties: { - name: { - type: 'string', - description: 'Folder name.', - }, - parentId: { - type: 'string', - description: 'Optional parent folder ID.', + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Folder name." }, - workspaceId: { - type: 'string', - description: 'Optional workspace ID.', + "parentId": { + "type": "string", + "description": "Optional parent folder ID." }, + "workspaceId": { + "type": "string", + "description": "Optional workspace ID." + } }, - required: ['name'], + "required": [ + "name" + ] }, resultSchema: undefined, }, - create_job: { + ["create_job"]: { parameters: { - type: 'object', - properties: { - cron: { - type: 'string', - description: - "Cron expression for recurring jobs (e.g., '*/5 * * * *' for every 5 minutes, '0 9 * * *' for daily at 9 AM). Omit for one-time jobs.", + "type": "object", + "properties": { + "cron": { + "type": "string", + "description": "Cron expression for recurring jobs (e.g., '*/5 * * * *' for every 5 minutes, '0 9 * * *' for daily at 9 AM). Omit for one-time jobs." }, - lifecycle: { - type: 'string', - description: - "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called after the success condition is met.", - enum: ['persistent', 'until_complete'], + "lifecycle": { + "type": "string", + "description": "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called after the success condition is met.", + "enum": [ + "persistent", + "until_complete" + ] }, - maxRuns: { - type: 'integer', - description: - 'Maximum number of executions before the job auto-completes. Safety limit to prevent runaway polling.', + "maxRuns": { + "type": "integer", + "description": "Maximum number of executions before the job auto-completes. Safety limit to prevent runaway polling." }, - prompt: { - type: 'string', - description: - 'The prompt to execute when the job fires. This is sent to the Mothership as a user message.', + "prompt": { + "type": "string", + "description": "The prompt to execute when the job fires. This is sent to the Mothership as a user message." }, - successCondition: { - type: 'string', - description: - "What must happen for the job to be considered complete. Used with until_complete lifecycle (e.g., 'John has replied to the partnership email').", + "successCondition": { + "type": "string", + "description": "What must happen for the job to be considered complete. Used with until_complete lifecycle (e.g., 'John has replied to the partnership email')." }, - time: { - type: 'string', - description: - "ISO 8601 datetime for one-time execution or as the start time for a cron schedule (e.g., '2026-03-06T09:00:00'). Include timezone offset or use the timezone parameter.", + "time": { + "type": "string", + "description": "ISO 8601 datetime for one-time execution or as the start time for a cron schedule (e.g., '2026-03-06T09:00:00'). Include timezone offset or use the timezone parameter." }, - timezone: { - type: 'string', - description: - "IANA timezone for the schedule (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC.", - }, - title: { - type: 'string', - description: - "A short, descriptive title for the job (e.g., 'Email Poller', 'Daily Report'). Used as the display name.", + "timezone": { + "type": "string", + "description": "IANA timezone for the schedule (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC." }, + "title": { + "type": "string", + "description": "A short, descriptive title for the job (e.g., 'Email Poller', 'Daily Report'). Used as the display name." + } }, - required: ['title', 'prompt'], + "required": [ + "title", + "prompt" + ] }, resultSchema: undefined, }, - create_workflow: { + ["create_workflow"]: { parameters: { - type: 'object', - properties: { - description: { - type: 'string', - description: 'Optional workflow description.', - }, - folderId: { - type: 'string', - description: 'Optional folder ID.', + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Optional workflow description." }, - name: { - type: 'string', - description: 'Workflow name.', + "folderId": { + "type": "string", + "description": "Optional folder ID." }, - workspaceId: { - type: 'string', - description: 'Optional workspace ID.', + "name": { + "type": "string", + "description": "Workflow name." }, + "workspaceId": { + "type": "string", + "description": "Optional workspace ID." + } }, - required: ['name'], + "required": [ + "name" + ] }, resultSchema: undefined, }, - create_workspace_mcp_server: { + ["create_workspace_mcp_server"]: { parameters: { - type: 'object', - properties: { - description: { - type: 'string', - description: 'Optional description for the server', - }, - name: { - type: 'string', - description: 'Required: server name', + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Optional description for the server" }, - workspaceId: { - type: 'string', - description: 'Workspace ID (defaults to current workspace)', + "name": { + "type": "string", + "description": "Required: server name" }, + "workspaceId": { + "type": "string", + "description": "Workspace ID (defaults to current workspace)" + } }, - required: ['name'], + "required": [ + "name" + ] }, resultSchema: undefined, }, - debug: { + ["debug"]: { parameters: { - properties: { - context: { - description: - 'Pre-gathered context: workflow state JSON, block schemas, error logs. The debug agent will skip re-reading anything included here.', - type: 'string', - }, - request: { - description: - 'What to debug. Include error messages, block IDs, and any context about the failure.', - type: 'string', + "properties": { + "context": { + "description": "Pre-gathered context: workflow state JSON, block schemas, error logs. The debug agent will skip re-reading anything included here.", + "type": "string" }, + "request": { + "description": "What to debug. Include error messages, block IDs, and any context about the failure.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - delete_file: { + ["delete_file"]: { parameters: { - type: 'object', - properties: { - fileIds: { - type: 'array', - description: 'Canonical workspace file IDs of the files to delete.', - items: { - type: 'string', - }, - }, + "type": "object", + "properties": { + "fileIds": { + "type": "array", + "description": "Canonical workspace file IDs of the files to delete.", + "items": { + "type": "string" + } + } }, - required: ['fileIds'], + "required": [ + "fileIds" + ] }, resultSchema: { - type: 'object', - properties: { - message: { - type: 'string', - description: 'Human-readable outcome.', - }, - success: { - type: 'boolean', - description: 'Whether the delete succeeded.', + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Human-readable outcome." }, + "success": { + "type": "boolean", + "description": "Whether the delete succeeded." + } }, - required: ['success', 'message'], + "required": [ + "success", + "message" + ] }, }, - delete_folder: { + ["delete_folder"]: { parameters: { - type: 'object', - properties: { - folderIds: { - type: 'array', - description: 'The folder IDs to delete.', - items: { - type: 'string', - }, - }, + "type": "object", + "properties": { + "folderIds": { + "type": "array", + "description": "The folder IDs to delete.", + "items": { + "type": "string" + } + } }, - required: ['folderIds'], + "required": [ + "folderIds" + ] }, resultSchema: undefined, }, - delete_workflow: { + ["delete_workflow"]: { parameters: { - type: 'object', - properties: { - workflowIds: { - type: 'array', - description: 'The workflow IDs to delete.', - items: { - type: 'string', - }, - }, + "type": "object", + "properties": { + "workflowIds": { + "type": "array", + "description": "The workflow IDs to delete.", + "items": { + "type": "string" + } + } }, - required: ['workflowIds'], + "required": [ + "workflowIds" + ] }, resultSchema: undefined, }, - delete_workspace_mcp_server: { + ["delete_workspace_mcp_server"]: { parameters: { - type: 'object', - properties: { - serverId: { - type: 'string', - description: 'Required: the MCP server ID to delete', - }, + "type": "object", + "properties": { + "serverId": { + "type": "string", + "description": "Required: the MCP server ID to delete" + } }, - required: ['serverId'], + "required": [ + "serverId" + ] }, resultSchema: undefined, }, - deploy: { + ["deploy"]: { parameters: { - properties: { - request: { - description: - 'Detailed deployment instructions. Include deployment type (api/chat) and ALL user-specified options: identifier, title, description, authType, password, allowedEmails, welcomeMessage, outputConfigs (block outputs to display).', - type: 'string', - }, + "properties": { + "request": { + "description": "Detailed deployment instructions. Include deployment type (api/chat) and ALL user-specified options: identifier, title, description, authType, password, allowedEmails, welcomeMessage, outputConfigs (block outputs to display).", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - deploy_api: { + ["deploy_api"]: { parameters: { - type: 'object', - properties: { - action: { - type: 'string', - description: 'Whether to deploy or undeploy the API endpoint', - enum: ['deploy', 'undeploy'], - default: 'deploy', - }, - workflowId: { - type: 'string', - description: 'Workflow ID to deploy (required in workspace context)', + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Whether to deploy or undeploy the API endpoint", + "enum": [ + "deploy", + "undeploy" + ], + "default": "deploy" }, - }, + "workflowId": { + "type": "string", + "description": "Workflow ID to deploy (required in workspace context)" + } + } }, resultSchema: { - type: 'object', - properties: { - apiEndpoint: { - type: 'string', - description: 'Canonical workflow execution endpoint.', - }, - baseUrl: { - type: 'string', - description: 'Base URL used to construct deployment URLs.', - }, - deployedAt: { - type: 'string', - description: 'Deployment timestamp when the workflow is deployed.', - }, - deploymentConfig: { - type: 'object', - description: - 'Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details.', - }, - deploymentStatus: { - type: 'object', - description: - 'Structured per-surface deployment status keyed by surface name, such as api.', - }, - deploymentType: { - type: 'string', - description: - 'Deployment surface this result describes. For deploy_api and redeploy this is always "api".', - }, - examples: { - type: 'object', - description: - 'Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling.', - }, - isDeployed: { - type: 'boolean', - description: 'Whether the workflow API is currently deployed after this tool call.', - }, - version: { - type: 'number', - description: 'Deployment version for the current API deployment.', - }, - workflowId: { - type: 'string', - description: 'Workflow ID that was deployed or undeployed.', - }, - }, - required: [ - 'workflowId', - 'isDeployed', - 'deploymentType', - 'deploymentStatus', - 'deploymentConfig', - 'examples', - ], - }, - }, - deploy_chat: { - parameters: { - type: 'object', - properties: { - action: { - type: 'string', - description: 'Whether to deploy or undeploy the chat interface', - enum: ['deploy', 'undeploy'], - default: 'deploy', - }, - allowedEmails: { - type: 'array', - description: 'List of allowed emails/domains for email or SSO auth', - items: { - type: 'string', - }, - }, - authType: { - type: 'string', - description: 'Authentication type: public, password, email, or sso', - enum: ['public', 'password', 'email', 'sso'], - default: 'public', - }, - description: { - type: 'string', - description: 'Optional description for the chat', - }, - identifier: { - type: 'string', - description: 'URL slug for the chat (lowercase letters, numbers, hyphens only)', - }, - outputConfigs: { - type: 'array', - description: 'Output configurations specifying which block outputs to display in chat', - items: { - type: 'object', - properties: { - blockId: { - type: 'string', - description: 'The block UUID', - }, - path: { - type: 'string', - description: "The output path (e.g. 'response', 'response.content')", + "type": "object", + "properties": { + "apiEndpoint": { + "type": "string", + "description": "Canonical workflow execution endpoint." + }, + "baseUrl": { + "type": "string", + "description": "Base URL used to construct deployment URLs." + }, + "deployedAt": { + "type": "string", + "description": "Deployment timestamp when the workflow is deployed." + }, + "deploymentConfig": { + "type": "object", + "description": "Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details." + }, + "deploymentStatus": { + "type": "object", + "description": "Structured per-surface deployment status keyed by surface name, such as api." + }, + "deploymentType": { + "type": "string", + "description": "Deployment surface this result describes. For deploy_api and redeploy this is always \"api\"." + }, + "examples": { + "type": "object", + "description": "Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling." + }, + "isDeployed": { + "type": "boolean", + "description": "Whether the workflow API is currently deployed after this tool call." + }, + "version": { + "type": "number", + "description": "Deployment version for the current API deployment." + }, + "workflowId": { + "type": "string", + "description": "Workflow ID that was deployed or undeployed." + } + }, + "required": [ + "workflowId", + "isDeployed", + "deploymentType", + "deploymentStatus", + "deploymentConfig", + "examples" + ] + }, + }, + ["deploy_chat"]: { + parameters: { + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Whether to deploy or undeploy the chat interface", + "enum": [ + "deploy", + "undeploy" + ], + "default": "deploy" + }, + "allowedEmails": { + "type": "array", + "description": "List of allowed emails/domains for email or SSO auth", + "items": { + "type": "string" + } + }, + "authType": { + "type": "string", + "description": "Authentication type: public, password, email, or sso", + "enum": [ + "public", + "password", + "email", + "sso" + ], + "default": "public" + }, + "description": { + "type": "string", + "description": "Optional description for the chat" + }, + "identifier": { + "type": "string", + "description": "URL slug for the chat (lowercase letters, numbers, hyphens only)" + }, + "outputConfigs": { + "type": "array", + "description": "Output configurations specifying which block outputs to display in chat", + "items": { + "type": "object", + "properties": { + "blockId": { + "type": "string", + "description": "The block UUID" }, - }, - required: ['blockId', 'path'], - }, - }, - password: { - type: 'string', - description: 'Password for password-protected chats', - }, - title: { - type: 'string', - description: 'Display title for the chat interface', - }, - welcomeMessage: { - type: 'string', - description: 'Welcome message shown to users', - }, - workflowId: { - type: 'string', - description: 'Workflow ID to deploy (required in workspace context)', - }, - }, + "path": { + "type": "string", + "description": "The output path (e.g. 'response', 'response.content')" + } + }, + "required": [ + "blockId", + "path" + ] + } + }, + "password": { + "type": "string", + "description": "Password for password-protected chats" + }, + "title": { + "type": "string", + "description": "Display title for the chat interface" + }, + "welcomeMessage": { + "type": "string", + "description": "Welcome message shown to users" + }, + "workflowId": { + "type": "string", + "description": "Workflow ID to deploy (required in workspace context)" + } + } }, resultSchema: { - type: 'object', - properties: { - action: { - type: 'string', - description: 'Action performed by the tool, such as "deploy" or "undeploy".', - }, - apiEndpoint: { - type: 'string', - description: 'Paired workflow execution endpoint used by the chat deployment.', - }, - baseUrl: { - type: 'string', - description: 'Base URL used to construct deployment URLs.', - }, - chatUrl: { - type: 'string', - description: 'Shareable chat URL when the chat surface is deployed.', - }, - deployedAt: { - type: 'string', - description: 'Deployment timestamp for the underlying workflow deployment.', - }, - deploymentConfig: { - type: 'object', - description: - 'Structured deployment configuration keyed by surface name. Includes chat settings and the paired API invocation configuration.', - }, - deploymentStatus: { - type: 'object', - description: - 'Structured per-surface deployment status keyed by surface name, including api and chat.', - }, - deploymentType: { - type: 'string', - description: - 'Deployment surface this result describes. For deploy_chat this is always "chat".', - }, - examples: { - type: 'object', - description: - 'Invocation examples keyed by surface name. Includes chat access details and API curl examples.', - }, - identifier: { - type: 'string', - description: 'Chat identifier or slug.', - }, - isChatDeployed: { - type: 'boolean', - description: 'Whether the chat surface is deployed after this tool call.', - }, - isDeployed: { - type: 'boolean', - description: 'Whether the paired API surface remains deployed after this tool call.', - }, - success: { - type: 'boolean', - description: 'Whether the deploy_chat action completed successfully.', - }, - version: { - type: 'number', - description: 'Deployment version for the underlying workflow deployment.', - }, - workflowId: { - type: 'string', - description: 'Workflow ID associated with the chat deployment.', - }, - }, - required: [ - 'workflowId', - 'success', - 'action', - 'isDeployed', - 'isChatDeployed', - 'deploymentType', - 'deploymentStatus', - 'deploymentConfig', - 'examples', - ], - }, - }, - deploy_mcp: { - parameters: { - type: 'object', - properties: { - parameterDescriptions: { - type: 'array', - description: 'Array of parameter descriptions for the tool', - items: { - type: 'object', - properties: { - description: { - type: 'string', - description: 'Parameter description', - }, - name: { - type: 'string', - description: 'Parameter name', + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Action performed by the tool, such as \"deploy\" or \"undeploy\"." + }, + "apiEndpoint": { + "type": "string", + "description": "Paired workflow execution endpoint used by the chat deployment." + }, + "baseUrl": { + "type": "string", + "description": "Base URL used to construct deployment URLs." + }, + "chatUrl": { + "type": "string", + "description": "Shareable chat URL when the chat surface is deployed." + }, + "deployedAt": { + "type": "string", + "description": "Deployment timestamp for the underlying workflow deployment." + }, + "deploymentConfig": { + "type": "object", + "description": "Structured deployment configuration keyed by surface name. Includes chat settings and the paired API invocation configuration." + }, + "deploymentStatus": { + "type": "object", + "description": "Structured per-surface deployment status keyed by surface name, including api and chat." + }, + "deploymentType": { + "type": "string", + "description": "Deployment surface this result describes. For deploy_chat this is always \"chat\"." + }, + "examples": { + "type": "object", + "description": "Invocation examples keyed by surface name. Includes chat access details and API curl examples." + }, + "identifier": { + "type": "string", + "description": "Chat identifier or slug." + }, + "isChatDeployed": { + "type": "boolean", + "description": "Whether the chat surface is deployed after this tool call." + }, + "isDeployed": { + "type": "boolean", + "description": "Whether the paired API surface remains deployed after this tool call." + }, + "success": { + "type": "boolean", + "description": "Whether the deploy_chat action completed successfully." + }, + "version": { + "type": "number", + "description": "Deployment version for the underlying workflow deployment." + }, + "workflowId": { + "type": "string", + "description": "Workflow ID associated with the chat deployment." + } + }, + "required": [ + "workflowId", + "success", + "action", + "isDeployed", + "isChatDeployed", + "deploymentType", + "deploymentStatus", + "deploymentConfig", + "examples" + ] + }, + }, + ["deploy_mcp"]: { + parameters: { + "type": "object", + "properties": { + "parameterDescriptions": { + "type": "array", + "description": "Array of parameter descriptions for the tool", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "Parameter description" }, - }, - required: ['name', 'description'], - }, - }, - serverId: { - type: 'string', - description: 'Required: server ID from list_workspace_mcp_servers', - }, - toolDescription: { - type: 'string', - description: 'Description for the MCP tool', - }, - toolName: { - type: 'string', - description: 'Name for the MCP tool (defaults to workflow name)', - }, - workflowId: { - type: 'string', - description: 'Workflow ID (defaults to active workflow)', - }, - }, - required: ['serverId'], + "name": { + "type": "string", + "description": "Parameter name" + } + }, + "required": [ + "name", + "description" + ] + } + }, + "serverId": { + "type": "string", + "description": "Required: server ID from list_workspace_mcp_servers" + }, + "toolDescription": { + "type": "string", + "description": "Description for the MCP tool" + }, + "toolName": { + "type": "string", + "description": "Name for the MCP tool (defaults to workflow name)" + }, + "workflowId": { + "type": "string", + "description": "Workflow ID (defaults to active workflow)" + } + }, + "required": [ + "serverId" + ] }, resultSchema: { - type: 'object', - properties: { - action: { - type: 'string', - description: 'Action performed by the tool, such as "deploy" or "undeploy".', - }, - apiEndpoint: { - type: 'string', - description: 'Underlying workflow API endpoint associated with the MCP tool.', + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Action performed by the tool, such as \"deploy\" or \"undeploy\"." }, - baseUrl: { - type: 'string', - description: 'Base URL used to construct deployment URLs.', + "apiEndpoint": { + "type": "string", + "description": "Underlying workflow API endpoint associated with the MCP tool." }, - deploymentConfig: { - type: 'object', - description: - 'Structured deployment configuration keyed by surface name. Includes MCP server, tool, auth, and parameter schema details.', + "baseUrl": { + "type": "string", + "description": "Base URL used to construct deployment URLs." }, - deploymentStatus: { - type: 'object', - description: - 'Structured per-surface deployment status keyed by surface name, including mcp and the underlying api surface when applicable.', + "deploymentConfig": { + "type": "object", + "description": "Structured deployment configuration keyed by surface name. Includes MCP server, tool, auth, and parameter schema details." }, - deploymentType: { - type: 'string', - description: - 'Deployment surface this result describes. For deploy_mcp this is always "mcp".', + "deploymentStatus": { + "type": "object", + "description": "Structured per-surface deployment status keyed by surface name, including mcp and the underlying api surface when applicable." }, - examples: { - type: 'object', - description: - 'Setup examples keyed by surface name. Includes ready-to-paste config snippets for supported MCP clients.', + "deploymentType": { + "type": "string", + "description": "Deployment surface this result describes. For deploy_mcp this is always \"mcp\"." }, - mcpServerUrl: { - type: 'string', - description: 'HTTP MCP server URL to configure in clients.', + "examples": { + "type": "object", + "description": "Setup examples keyed by surface name. Includes ready-to-paste config snippets for supported MCP clients." }, - removed: { - type: 'boolean', - description: 'Whether the MCP deployment was removed during an undeploy action.', + "mcpServerUrl": { + "type": "string", + "description": "HTTP MCP server URL to configure in clients." }, - serverId: { - type: 'string', - description: 'Workspace MCP server ID.', + "removed": { + "type": "boolean", + "description": "Whether the MCP deployment was removed during an undeploy action." }, - serverName: { - type: 'string', - description: 'Workspace MCP server name.', + "serverId": { + "type": "string", + "description": "Workspace MCP server ID." }, - toolDescription: { - type: 'string', - description: 'MCP tool description exposed on the server.', + "serverName": { + "type": "string", + "description": "Workspace MCP server name." }, - toolId: { - type: 'string', - description: 'MCP tool ID when deployed.', + "toolDescription": { + "type": "string", + "description": "MCP tool description exposed on the server." }, - toolName: { - type: 'string', - description: 'MCP tool name exposed on the server.', + "toolId": { + "type": "string", + "description": "MCP tool ID when deployed." }, - updated: { - type: 'boolean', - description: 'Whether an existing MCP tool deployment was updated instead of created.', + "toolName": { + "type": "string", + "description": "MCP tool name exposed on the server." }, - workflowId: { - type: 'string', - description: 'Workflow ID associated with the MCP deployment.', + "updated": { + "type": "boolean", + "description": "Whether an existing MCP tool deployment was updated instead of created." }, + "workflowId": { + "type": "string", + "description": "Workflow ID associated with the MCP deployment." + } }, - required: ['deploymentType', 'deploymentStatus'], + "required": [ + "deploymentType", + "deploymentStatus" + ] }, }, - download_to_workspace_file: { + ["download_to_workspace_file"]: { parameters: { - type: 'object', - properties: { - fileName: { - type: 'string', - description: - 'Optional workspace file name to save as. If omitted, the name is inferred from the response or URL.', - }, - url: { - type: 'string', - description: - 'Direct URL of the file to download, such as an image CDN URL ending in .png or .jpg', + "type": "object", + "properties": { + "fileName": { + "type": "string", + "description": "Optional workspace file name to save as. If omitted, the name is inferred from the response or URL." }, + "url": { + "type": "string", + "description": "Direct URL of the file to download, such as an image CDN URL ending in .png or .jpg" + } }, - required: ['url'], + "required": [ + "url" + ] }, resultSchema: undefined, }, - edit_content: { + ["edit_content"]: { parameters: { - type: 'object', - properties: { - content: { - type: 'string', - description: - 'The text content to write. For append: text to append. For update: full replacement text. For patch with search_replace: the replacement text. For patch with anchored: the insert/replacement text.', - }, + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "The text content to write. For append: text to append. For update: full replacement text. For patch with search_replace: the replacement text. For patch with anchored: the insert/replacement text." + } }, - required: ['content'], + "required": [ + "content" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: - 'Optional operation metadata such as file id, file name, size, and content type.', - }, - message: { - type: 'string', - description: 'Human-readable summary of the outcome.', - }, - success: { - type: 'boolean', - description: 'Whether the content was applied successfully.', - }, - }, - required: ['success', 'message'], - }, - }, - edit_workflow: { - parameters: { - type: 'object', - properties: { - operations: { - type: 'array', - description: 'Array of edit operations', - items: { - type: 'object', - properties: { - block_id: { - type: 'string', - description: - 'Block ID for the operation. For add operations, this will be the desired ID for the new block.', + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Optional operation metadata such as file id, file name, size, and content type." + }, + "message": { + "type": "string", + "description": "Human-readable summary of the outcome." + }, + "success": { + "type": "boolean", + "description": "Whether the content was applied successfully." + } + }, + "required": [ + "success", + "message" + ] + }, + }, + ["edit_workflow"]: { + parameters: { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "Array of edit operations", + "items": { + "type": "object", + "properties": { + "block_id": { + "type": "string", + "description": "Block ID for the operation. For add operations, this will be the desired ID for the new block." }, - operation_type: { - type: 'string', - description: 'Type of operation to perform', - enum: ['add', 'edit', 'delete', 'insert_into_subflow', 'extract_from_subflow'], + "operation_type": { + "type": "string", + "description": "Type of operation to perform", + "enum": [ + "add", + "edit", + "delete", + "insert_into_subflow", + "extract_from_subflow" + ] }, - params: { - type: 'object', - description: - 'Parameters for the operation. \nFor edit: {"inputs": {"temperature": 0.5}} NOT {"subBlocks": {"temperature": {"value": 0.5}}}\nFor add: {"type": "agent", "name": "My Agent", "inputs": {"model": "claude-sonnet-4-6"}}\nFor delete: {} (empty object)', - }, - }, - required: ['operation_type', 'block_id', 'params'], - }, - }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to edit. If not provided, uses the current workflow in context.', + "params": { + "type": "object", + "description": "Parameters for the operation. \nFor edit: {\"inputs\": {\"temperature\": 0.5}} NOT {\"subBlocks\": {\"temperature\": {\"value\": 0.5}}}\nFor add: {\"type\": \"agent\", \"name\": \"My Agent\", \"inputs\": {\"model\": \"claude-sonnet-4-6\"}}\nFor delete: {} (empty object)" + } + }, + "required": [ + "operation_type", + "block_id", + "params" + ] + } }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID to edit. If not provided, uses the current workflow in context." + } }, - required: ['operations'], + "required": [ + "operations" + ] }, resultSchema: undefined, }, - file: { - parameters: { - type: 'object', - }, + ["file"]: { + parameters: { + "type": "object" + }, + resultSchema: undefined, + }, + ["function_execute"]: { + parameters: { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "Code to execute. For JS: raw statements auto-wrapped in async context. For Python: full script. For shell: bash script with access to pre-installed CLI tools and workspace env vars as $VAR_NAME." + }, + "inputFiles": { + "type": "array", + "description": "Canonical workspace file IDs to mount in the sandbox. Discover IDs via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\"). Mounted path: /home/user/files/{fileId}/{originalName}. Example: [\"wf_123\"]", + "items": { + "type": "string" + } + }, + "inputTables": { + "type": "array", + "description": "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Example: [\"tbl_abc123\"]", + "items": { + "type": "string" + } + }, + "language": { + "type": "string", + "description": "Execution language.", + "enum": [ + "javascript", + "python", + "shell" + ] + }, + "outputFormat": { + "type": "string", + "description": "Format for outputPath. Determines how the code result is serialized. If omitted, inferred from outputPath file extension.", + "enum": [ + "json", + "csv", + "txt", + "md", + "html" + ] + }, + "outputMimeType": { + "type": "string", + "description": "MIME type for outputSandboxPath export. Required for binary files: image/png, image/jpeg, application/pdf, etc. Omit for text files." + }, + "outputPath": { + "type": "string", + "description": "Pipe output directly to a NEW workspace file instead of returning in context. ALWAYS use this instead of a separate workspace_file write call. Use a flat path like \"files/result.json\" — nested paths are not supported." + }, + "outputSandboxPath": { + "type": "string", + "description": "Path to a file created inside the sandbox that should be exported to the workspace. Use together with outputPath." + }, + "outputTable": { + "type": "string", + "description": "Table ID to overwrite with the code's return value. Code MUST return an array of objects where keys match column names. All existing rows are replaced. Example: \"tbl_abc123\"" + } + }, + "required": [ + "code" + ] + }, resultSchema: undefined, }, - function_execute: { - parameters: { - type: 'object', - properties: { - code: { - type: 'string', - description: - 'Code to execute. For JS: raw statements auto-wrapped in async context. For Python: full script. For shell: bash script with access to pre-installed CLI tools and workspace env vars as $VAR_NAME.', - }, - inputFiles: { - type: 'array', - description: - 'Canonical workspace file IDs to mount in the sandbox. Discover IDs via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json"). Mounted path: /home/user/files/{fileId}/{originalName}. Example: ["wf_123"]', - items: { - type: 'string', - }, - }, - inputTables: { - type: 'array', - description: - 'Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Example: ["tbl_abc123"]', - items: { - type: 'string', - }, - }, - language: { - type: 'string', - description: 'Execution language.', - enum: ['javascript', 'python', 'shell'], - }, - outputFormat: { - type: 'string', - description: - 'Format for outputPath. Determines how the code result is serialized. If omitted, inferred from outputPath file extension.', - enum: ['json', 'csv', 'txt', 'md', 'html'], - }, - outputMimeType: { - type: 'string', - description: - 'MIME type for outputSandboxPath export. Required for binary files: image/png, image/jpeg, application/pdf, etc. Omit for text files.', - }, - outputPath: { - type: 'string', - description: - 'Pipe output directly to a NEW workspace file instead of returning in context. ALWAYS use this instead of a separate workspace_file write call. Use a flat path like "files/result.json" — nested paths are not supported.', - }, - outputSandboxPath: { - type: 'string', - description: - 'Path to a file created inside the sandbox that should be exported to the workspace. Use together with outputPath.', - }, - outputTable: { - type: 'string', - description: - 'Table ID to overwrite with the code\'s return value. Code MUST return an array of objects where keys match column names. All existing rows are replaced. Example: "tbl_abc123"', - }, - }, - required: ['code'], + ["generate_api_key"]: { + parameters: { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "A descriptive name for the API key (e.g., 'production-key', 'dev-testing')." + }, + "workspaceId": { + "type": "string", + "description": "Optional workspace ID. Defaults to user's default workspace." + } + }, + "required": [ + "name" + ] }, resultSchema: undefined, }, - generate_api_key: { + ["generate_image"]: { parameters: { - type: 'object', - properties: { - name: { - type: 'string', - description: - "A descriptive name for the API key (e.g., 'production-key', 'dev-testing').", - }, - workspaceId: { - type: 'string', - description: "Optional workspace ID. Defaults to user's default workspace.", - }, + "type": "object", + "properties": { + "aspectRatio": { + "type": "string", + "description": "Aspect ratio for the generated image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "4:3", + "3:4" + ] + }, + "fileName": { + "type": "string", + "description": "Output file name. Defaults to \"generated-image.png\". Workspace files are flat, so pass a plain file name, not a nested path." + }, + "overwriteFileId": { + "type": "string", + "description": "If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated image so the existing chat resource stays current instead of creating a duplicate like \"image (1).png\". The file ID is returned by previous generate_image or generate_visualization calls (fileId field), or can be found via read(\"files/by-id/{fileId}/meta.json\")." + }, + "prompt": { + "type": "string", + "description": "Detailed text description of the image to generate, or editing instructions when used with editFileId." + }, + "referenceFileIds": { + "type": "array", + "description": "File IDs of workspace images to include as context for the generation. All images are sent alongside the prompt. Use for: editing a single image (1 file), compositing multiple images together (2+ files), style transfer, face swapping, etc. Order matters — list the primary/base image first. When revising an existing image in place, pair the primary file ID here with overwriteFileId set to that same ID.", + "items": { + "type": "string" + } + } }, - required: ['name'], + "required": [ + "prompt" + ] }, resultSchema: undefined, }, - generate_image: { + ["generate_visualization"]: { parameters: { - type: 'object', - properties: { - aspectRatio: { - type: 'string', - description: 'Aspect ratio for the generated image.', - enum: ['1:1', '16:9', '9:16', '4:3', '3:4'], + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "Python code that generates a visualization using matplotlib. MUST call plt.savefig('/home/user/output.png', dpi=150, bbox_inches='tight') to produce output." }, - fileName: { - type: 'string', - description: - 'Output file name. Defaults to "generated-image.png". Workspace files are flat, so pass a plain file name, not a nested path.', + "fileName": { + "type": "string", + "description": "Output file name. Defaults to \"chart.png\". Workspace files are flat, so pass a plain file name, not a nested path." }, - overwriteFileId: { - type: 'string', - description: - 'If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated image so the existing chat resource stays current instead of creating a duplicate like "image (1).png". The file ID is returned by previous generate_image or generate_visualization calls (fileId field), or can be found via read("files/by-id/{fileId}/meta.json").', + "inputFiles": { + "type": "array", + "description": "Canonical workspace file IDs to mount in the sandbox. Discover IDs via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\"). Mounted path: /home/user/files/{fileId}/{originalName}.", + "items": { + "type": "string" + } }, - prompt: { - type: 'string', - description: - 'Detailed text description of the image to generate, or editing instructions when used with editFileId.', - }, - referenceFileIds: { - type: 'array', - description: - 'File IDs of workspace images to include as context for the generation. All images are sent alongside the prompt. Use for: editing a single image (1 file), compositing multiple images together (2+ files), style transfer, face swapping, etc. Order matters — list the primary/base image first. When revising an existing image in place, pair the primary file ID here with overwriteFileId set to that same ID.', - items: { - type: 'string', - }, - }, - }, - required: ['prompt'], - }, - resultSchema: undefined, - }, - generate_visualization: { - parameters: { - type: 'object', - properties: { - code: { - type: 'string', - description: - "Python code that generates a visualization using matplotlib. MUST call plt.savefig('/home/user/output.png', dpi=150, bbox_inches='tight') to produce output.", - }, - fileName: { - type: 'string', - description: - 'Output file name. Defaults to "chart.png". Workspace files are flat, so pass a plain file name, not a nested path.', - }, - inputFiles: { - type: 'array', - description: - 'Canonical workspace file IDs to mount in the sandbox. Discover IDs via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json"). Mounted path: /home/user/files/{fileId}/{originalName}.', - items: { - type: 'string', - }, - }, - inputTables: { - type: 'array', - description: - "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Read with pandas: pd.read_csv('/home/user/tables/tbl_xxx.csv')", - items: { - type: 'string', - }, - }, - overwriteFileId: { - type: 'string', - description: - 'If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated chart so the existing chat resource stays current instead of creating a duplicate like "chart (1).png". The file ID is returned by previous generate_visualization or generate_image calls (fileId field), or can be found via read("files/by-id/{fileId}/meta.json").', + "inputTables": { + "type": "array", + "description": "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Read with pandas: pd.read_csv('/home/user/tables/tbl_xxx.csv')", + "items": { + "type": "string" + } }, + "overwriteFileId": { + "type": "string", + "description": "If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated chart so the existing chat resource stays current instead of creating a duplicate like \"chart (1).png\". The file ID is returned by previous generate_visualization or generate_image calls (fileId field), or can be found via read(\"files/by-id/{fileId}/meta.json\")." + } }, - required: ['code'], + "required": [ + "code" + ] }, resultSchema: undefined, }, - get_block_outputs: { + ["get_block_outputs"]: { parameters: { - type: 'object', - properties: { - blockIds: { - type: 'array', - description: - 'Optional array of block UUIDs. If provided, returns outputs only for those blocks. If not provided, returns outputs for all blocks in the workflow.', - items: { - type: 'string', - }, + "type": "object", + "properties": { + "blockIds": { + "type": "array", + "description": "Optional array of block UUIDs. If provided, returns outputs only for those blocks. If not provided, returns outputs for all blocks in the workflow.", + "items": { + "type": "string" + } }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', - }, - }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } + } }, resultSchema: undefined, }, - get_block_upstream_references: { + ["get_block_upstream_references"]: { parameters: { - type: 'object', - properties: { - blockIds: { - type: 'array', - description: - 'Required array of block UUIDs (minimum 1). Returns what each block can reference based on its position in the workflow graph.', - items: { - type: 'string', - }, - }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', + "type": "object", + "properties": { + "blockIds": { + "type": "array", + "description": "Required array of block UUIDs (minimum 1). Returns what each block can reference based on its position in the workflow graph.", + "items": { + "type": "string" + } }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } }, - required: ['blockIds'], + "required": [ + "blockIds" + ] }, resultSchema: undefined, }, - get_deployed_workflow_state: { + ["get_deployed_workflow_state"]: { parameters: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', - }, - }, + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } + } }, resultSchema: undefined, }, - get_deployment_version: { + ["get_deployment_version"]: { parameters: { - type: 'object', - properties: { - version: { - type: 'number', - description: 'The deployment version number', - }, - workflowId: { - type: 'string', - description: 'The workflow ID', + "type": "object", + "properties": { + "version": { + "type": "number", + "description": "The deployment version number" }, + "workflowId": { + "type": "string", + "description": "The workflow ID" + } }, - required: ['workflowId', 'version'], + "required": [ + "workflowId", + "version" + ] }, resultSchema: undefined, }, - get_execution_summary: { + ["get_execution_summary"]: { parameters: { - type: 'object', - properties: { - limit: { - type: 'number', - description: 'Max number of executions to return (default: 10, max: 20).', - }, - status: { - type: 'string', - description: "Filter by status: 'success', 'error', or 'all' (default: 'all').", - enum: ['success', 'error', 'all'], + "type": "object", + "properties": { + "limit": { + "type": "number", + "description": "Max number of executions to return (default: 10, max: 20)." }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If omitted, returns executions across all workflows in the workspace.', + "status": { + "type": "string", + "description": "Filter by status: 'success', 'error', or 'all' (default: 'all').", + "enum": [ + "success", + "error", + "all" + ] }, - workspaceId: { - type: 'string', - description: 'Workspace ID to scope executions to.', + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If omitted, returns executions across all workflows in the workspace." }, + "workspaceId": { + "type": "string", + "description": "Workspace ID to scope executions to." + } }, - required: ['workspaceId'], + "required": [ + "workspaceId" + ] }, resultSchema: undefined, }, - get_job_logs: { + ["get_job_logs"]: { parameters: { - type: 'object', - properties: { - executionId: { - type: 'string', - description: 'Optional execution ID for a specific run.', + "type": "object", + "properties": { + "executionId": { + "type": "string", + "description": "Optional execution ID for a specific run." }, - includeDetails: { - type: 'boolean', - description: 'Include tool calls, outputs, and cost details.', + "includeDetails": { + "type": "boolean", + "description": "Include tool calls, outputs, and cost details." }, - jobId: { - type: 'string', - description: 'The job (schedule) ID to get logs for.', - }, - limit: { - type: 'number', - description: 'Max number of entries (default: 3, max: 5)', + "jobId": { + "type": "string", + "description": "The job (schedule) ID to get logs for." }, + "limit": { + "type": "number", + "description": "Max number of entries (default: 3, max: 5)" + } }, - required: ['jobId'], + "required": [ + "jobId" + ] }, resultSchema: undefined, }, - get_page_contents: { + ["get_page_contents"]: { parameters: { - type: 'object', - properties: { - include_highlights: { - type: 'boolean', - description: 'Include key highlights (default false)', - }, - include_summary: { - type: 'boolean', - description: 'Include AI-generated summary (default false)', + "type": "object", + "properties": { + "include_highlights": { + "type": "boolean", + "description": "Include key highlights (default false)" }, - include_text: { - type: 'boolean', - description: 'Include full page text (default true)', + "include_summary": { + "type": "boolean", + "description": "Include AI-generated summary (default false)" }, - urls: { - type: 'array', - description: 'URLs to get content from (max 10)', - items: { - type: 'string', - }, + "include_text": { + "type": "boolean", + "description": "Include full page text (default true)" }, + "urls": { + "type": "array", + "description": "URLs to get content from (max 10)", + "items": { + "type": "string" + } + } }, - required: ['urls'], + "required": [ + "urls" + ] }, resultSchema: undefined, }, - get_platform_actions: { + ["get_platform_actions"]: { parameters: { - type: 'object', - properties: {}, + "type": "object", + "properties": {} }, resultSchema: undefined, }, - get_workflow_data: { + ["get_workflow_data"]: { parameters: { - type: 'object', - properties: { - data_type: { - type: 'string', - description: 'The type of workflow data to retrieve', - enum: ['global_variables', 'custom_tools', 'mcp_tools', 'files'], - }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', + "type": "object", + "properties": { + "data_type": { + "type": "string", + "description": "The type of workflow data to retrieve", + "enum": [ + "global_variables", + "custom_tools", + "mcp_tools", + "files" + ] }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } }, - required: ['data_type'], + "required": [ + "data_type" + ] }, resultSchema: undefined, }, - get_workflow_logs: { + ["get_workflow_logs"]: { parameters: { - type: 'object', - properties: { - executionId: { - type: 'string', - description: - 'Optional execution ID to get logs for a specific execution. Use with get_execution_summary to find execution IDs first.', - }, - includeDetails: { - type: 'boolean', - description: 'Include detailed info', + "type": "object", + "properties": { + "executionId": { + "type": "string", + "description": "Optional execution ID to get logs for a specific execution. Use with get_execution_summary to find execution IDs first." }, - limit: { - type: 'number', - description: 'Max number of entries (hard limit: 3)', + "includeDetails": { + "type": "boolean", + "description": "Include detailed info" }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', + "limit": { + "type": "number", + "description": "Max number of entries (hard limit: 3)" }, - }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } + } }, resultSchema: undefined, }, - glob: { + ["glob"]: { parameters: { - type: 'object', - properties: { - pattern: { - type: 'string', - description: - 'Glob pattern to match file paths. Supports * (any segment) and ** (any depth).', - }, - toolTitle: { - type: 'string', - description: - 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "workflow configs" or "knowledge bases", not a full sentence like "Finding workflow configs".', + "type": "object", + "properties": { + "pattern": { + "type": "string", + "description": "Glob pattern to match file paths. Supports * (any segment) and ** (any depth)." }, + "toolTitle": { + "type": "string", + "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"workflow configs\" or \"knowledge bases\", not a full sentence like \"Finding workflow configs\"." + } }, - required: ['pattern', 'toolTitle'], + "required": [ + "pattern", + "toolTitle" + ] }, resultSchema: undefined, }, - grep: { + ["grep"]: { parameters: { - type: 'object', - properties: { - context: { - type: 'number', - description: - "Number of lines to show before and after each match. Only applies to output_mode 'content'.", - }, - ignoreCase: { - type: 'boolean', - description: 'Case insensitive search (default false).', + "type": "object", + "properties": { + "context": { + "type": "number", + "description": "Number of lines to show before and after each match. Only applies to output_mode 'content'." }, - lineNumbers: { - type: 'boolean', - description: - "Include line numbers in output (default true). Only applies to output_mode 'content'.", + "ignoreCase": { + "type": "boolean", + "description": "Case insensitive search (default false)." }, - maxResults: { - type: 'number', - description: 'Maximum number of matches to return (default 50).', + "lineNumbers": { + "type": "boolean", + "description": "Include line numbers in output (default true). Only applies to output_mode 'content'." }, - output_mode: { - type: 'string', - description: - "Output mode: 'content' shows matching lines (default), 'files_with_matches' shows only file paths, 'count' shows match counts per file.", - enum: ['content', 'files_with_matches', 'count'], + "maxResults": { + "type": "number", + "description": "Maximum number of matches to return (default 50)." }, - path: { - type: 'string', - description: - "Optional path prefix to scope the search (e.g. 'workflows/', 'environment/', 'internal/', 'components/blocks/').", + "output_mode": { + "type": "string", + "description": "Output mode: 'content' shows matching lines (default), 'files_with_matches' shows only file paths, 'count' shows match counts per file.", + "enum": [ + "content", + "files_with_matches", + "count" + ] }, - pattern: { - type: 'string', - description: 'Regex pattern to search for in file contents.', + "path": { + "type": "string", + "description": "Optional path prefix to scope the search (e.g. 'workflows/', 'environment/', 'internal/', 'components/blocks/')." }, - toolTitle: { - type: 'string', - description: - 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "Slack integrations" or "deployed workflows", not a full sentence like "Searching for Slack integrations".', + "pattern": { + "type": "string", + "description": "Regex pattern to search for in file contents." }, + "toolTitle": { + "type": "string", + "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"Slack integrations\" or \"deployed workflows\", not a full sentence like \"Searching for Slack integrations\"." + } }, - required: ['pattern', 'toolTitle'], + "required": [ + "pattern", + "toolTitle" + ] }, resultSchema: undefined, }, - job: { + ["job"]: { parameters: { - properties: { - request: { - description: 'What job action is needed.', - type: 'string', - }, + "properties": { + "request": { + "description": "What job action is needed.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - knowledge: { + ["knowledge"]: { parameters: { - properties: { - request: { - description: 'What knowledge base action is needed.', - type: 'string', - }, + "properties": { + "request": { + "description": "What knowledge base action is needed.", + "type": "string" + } }, - required: ['request'], - type: 'object', - }, - resultSchema: undefined, - }, - knowledge_base: { - parameters: { - type: 'object', - properties: { - args: { - type: 'object', - description: 'Arguments for the operation', - properties: { - apiKey: { - type: 'string', - description: - 'API key for API-key-based connectors (required when connector auth mode is apiKey)', - }, - chunkingConfig: { - type: 'object', - description: "Chunking configuration (optional for 'create')", - properties: { - maxSize: { - type: 'number', - description: 'Maximum chunk size (100-4000, default: 1024)', - default: 1024, - }, - minSize: { - type: 'number', - description: 'Minimum chunk size (1-2000, default: 1)', - default: 1, + "required": [ + "request" + ], + "type": "object" + }, + resultSchema: undefined, + }, + ["knowledge_base"]: { + parameters: { + "type": "object", + "properties": { + "args": { + "type": "object", + "description": "Arguments for the operation", + "properties": { + "apiKey": { + "type": "string", + "description": "API key for API-key-based connectors (required when connector auth mode is apiKey)" + }, + "chunkingConfig": { + "type": "object", + "description": "Chunking configuration (optional for 'create')", + "properties": { + "maxSize": { + "type": "number", + "description": "Maximum chunk size (100-4000, default: 1024)", + "default": 1024 }, - overlap: { - type: 'number', - description: 'Overlap between chunks (0-500, default: 200)', - default: 200, + "minSize": { + "type": "number", + "description": "Minimum chunk size (1-2000, default: 1)", + "default": 1 }, - }, - }, - connectorId: { - type: 'string', - description: - 'Connector ID (required for update_connector, delete_connector, sync_connector)', - }, - connectorStatus: { - type: 'string', - description: 'Connector status (optional for update_connector)', - enum: ['active', 'paused'], - }, - connectorType: { - type: 'string', - description: - "Connector type from registry, e.g. 'confluence', 'google_drive', 'notion' (required for add_connector). Read knowledgebases/connectors/{type}.json for the config schema.", - }, - credentialId: { - type: 'string', - description: - 'OAuth credential ID from environment/credentials.json (required for OAuth connectors)', - }, - description: { - type: 'string', - description: "Description of the knowledge base (optional for 'create')", - }, - disabledTagIds: { - type: 'array', - description: - 'Tag definition IDs to opt out of (optional for add_connector). See tagDefinitions in the connector schema.', - }, - documentId: { - type: 'string', - description: 'Document ID (required for update_document)', - }, - documentIds: { - type: 'array', - description: 'Document IDs (for batch delete_document)', - items: { - type: 'string', - }, - }, - enabled: { - type: 'boolean', - description: 'Enable/disable a document (optional for update_document)', - }, - fileIds: { - type: 'array', - description: - 'Canonical workspace file IDs to add as documents (for add_file). Discover via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json").', - items: { - type: 'string', - }, - }, - filename: { - type: 'string', - description: 'New filename for a document (optional for update_document)', - }, - knowledgeBaseId: { - type: 'string', - description: - 'Knowledge base ID (required for get, query, add_file, list_tags, create_tag, get_tag_usage)', - }, - knowledgeBaseIds: { - type: 'array', - description: 'Knowledge base IDs (for batch delete)', - items: { - type: 'string', - }, - }, - name: { - type: 'string', - description: "Name of the knowledge base (required for 'create')", - }, - query: { - type: 'string', - description: "Search query text (required for 'query')", - }, - sourceConfig: { - type: 'object', - description: - 'Connector-specific configuration matching the configFields in knowledgebases/connectors/{type}.json', - }, - syncIntervalMinutes: { - type: 'number', - description: - 'Sync interval in minutes: 60 (hourly), 360 (6h), 1440 (daily), 10080 (weekly), 0 (manual only). Default: 1440', - default: 1440, - }, - tagDefinitionId: { - type: 'string', - description: 'Tag definition ID (required for update_tag, delete_tag)', - }, - tagDisplayName: { - type: 'string', - description: - 'Display name for the tag (required for create_tag, optional for update_tag)', - }, - tagFieldType: { - type: 'string', - description: - 'Field type: text, number, date, boolean (optional for create_tag, defaults to text)', - enum: ['text', 'number', 'date', 'boolean'], - }, - topK: { - type: 'number', - description: 'Number of results to return (1-50, default: 5)', - default: 5, - }, - workspaceId: { - type: 'string', - description: "Workspace ID (required for 'create', optional filter for 'list')", - }, - }, - }, - operation: { - type: 'string', - description: 'The operation to perform', - enum: [ - 'create', - 'get', - 'query', - 'add_file', - 'update', - 'delete', - 'delete_document', - 'update_document', - 'list_tags', - 'create_tag', - 'update_tag', - 'delete_tag', - 'get_tag_usage', - 'add_connector', - 'update_connector', - 'delete_connector', - 'sync_connector', - ], - }, - }, - required: ['operation', 'args'], + "overlap": { + "type": "number", + "description": "Overlap between chunks (0-500, default: 200)", + "default": 200 + } + } + }, + "connectorId": { + "type": "string", + "description": "Connector ID (required for update_connector, delete_connector, sync_connector)" + }, + "connectorStatus": { + "type": "string", + "description": "Connector status (optional for update_connector)", + "enum": [ + "active", + "paused" + ] + }, + "connectorType": { + "type": "string", + "description": "Connector type from registry, e.g. 'confluence', 'google_drive', 'notion' (required for add_connector). Read knowledgebases/connectors/{type}.json for the config schema." + }, + "credentialId": { + "type": "string", + "description": "OAuth credential ID from environment/credentials.json (required for OAuth connectors)" + }, + "description": { + "type": "string", + "description": "Description of the knowledge base (optional for 'create')" + }, + "disabledTagIds": { + "type": "array", + "description": "Tag definition IDs to opt out of (optional for add_connector). See tagDefinitions in the connector schema." + }, + "documentId": { + "type": "string", + "description": "Document ID (required for update_document)" + }, + "documentIds": { + "type": "array", + "description": "Document IDs (for batch delete_document)", + "items": { + "type": "string" + } + }, + "enabled": { + "type": "boolean", + "description": "Enable/disable a document (optional for update_document)" + }, + "fileIds": { + "type": "array", + "description": "Canonical workspace file IDs to add as documents (for add_file). Discover via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\").", + "items": { + "type": "string" + } + }, + "filename": { + "type": "string", + "description": "New filename for a document (optional for update_document)" + }, + "knowledgeBaseId": { + "type": "string", + "description": "Knowledge base ID (required for get, query, add_file, list_tags, create_tag, get_tag_usage)" + }, + "knowledgeBaseIds": { + "type": "array", + "description": "Knowledge base IDs (for batch delete)", + "items": { + "type": "string" + } + }, + "name": { + "type": "string", + "description": "Name of the knowledge base (required for 'create')" + }, + "query": { + "type": "string", + "description": "Search query text (required for 'query')" + }, + "sourceConfig": { + "type": "object", + "description": "Connector-specific configuration matching the configFields in knowledgebases/connectors/{type}.json" + }, + "syncIntervalMinutes": { + "type": "number", + "description": "Sync interval in minutes: 60 (hourly), 360 (6h), 1440 (daily), 10080 (weekly), 0 (manual only). Default: 1440", + "default": 1440 + }, + "tagDefinitionId": { + "type": "string", + "description": "Tag definition ID (required for update_tag, delete_tag)" + }, + "tagDisplayName": { + "type": "string", + "description": "Display name for the tag (required for create_tag, optional for update_tag)" + }, + "tagFieldType": { + "type": "string", + "description": "Field type: text, number, date, boolean (optional for create_tag, defaults to text)", + "enum": [ + "text", + "number", + "date", + "boolean" + ] + }, + "topK": { + "type": "number", + "description": "Number of results to return (1-50, default: 5)", + "default": 5 + }, + "workspaceId": { + "type": "string", + "description": "Workspace ID (required for 'create', optional filter for 'list')" + } + } + }, + "operation": { + "type": "string", + "description": "The operation to perform", + "enum": [ + "create", + "get", + "query", + "add_file", + "update", + "delete", + "delete_document", + "update_document", + "list_tags", + "create_tag", + "update_tag", + "delete_tag", + "get_tag_usage", + "add_connector", + "update_connector", + "delete_connector", + "sync_connector" + ] + } + }, + "required": [ + "operation", + "args" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: 'Operation-specific result payload.', - }, - message: { - type: 'string', - description: 'Human-readable outcome summary.', + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Operation-specific result payload." }, - success: { - type: 'boolean', - description: 'Whether the operation succeeded.', + "message": { + "type": "string", + "description": "Human-readable outcome summary." }, + "success": { + "type": "boolean", + "description": "Whether the operation succeeded." + } }, - required: ['success', 'message'], + "required": [ + "success", + "message" + ] }, }, - list_folders: { + ["list_folders"]: { parameters: { - type: 'object', - properties: { - workspaceId: { - type: 'string', - description: 'Optional workspace ID to list folders for.', - }, - }, + "type": "object", + "properties": { + "workspaceId": { + "type": "string", + "description": "Optional workspace ID to list folders for." + } + } }, resultSchema: undefined, }, - list_user_workspaces: { + ["list_user_workspaces"]: { parameters: { - type: 'object', - properties: {}, + "type": "object", + "properties": {} }, resultSchema: undefined, }, - list_workspace_mcp_servers: { + ["list_workspace_mcp_servers"]: { parameters: { - type: 'object', - properties: { - workspaceId: { - type: 'string', - description: 'Workspace ID (defaults to current workspace)', - }, - }, + "type": "object", + "properties": { + "workspaceId": { + "type": "string", + "description": "Workspace ID (defaults to current workspace)" + } + } }, resultSchema: undefined, }, - manage_credential: { + ["manage_credential"]: { parameters: { - type: 'object', - properties: { - credentialId: { - type: 'string', - description: 'The credential ID (required for rename)', - }, - credentialIds: { - type: 'array', - description: 'Array of credential IDs (for batch delete)', - items: { - type: 'string', - }, + "type": "object", + "properties": { + "credentialId": { + "type": "string", + "description": "The credential ID (required for rename)" }, - displayName: { - type: 'string', - description: 'New display name (required for rename)', + "credentialIds": { + "type": "array", + "description": "Array of credential IDs (for batch delete)", + "items": { + "type": "string" + } }, - operation: { - type: 'string', - description: 'The operation to perform', - enum: ['rename', 'delete'], + "displayName": { + "type": "string", + "description": "New display name (required for rename)" }, + "operation": { + "type": "string", + "description": "The operation to perform", + "enum": [ + "rename", + "delete" + ] + } }, - required: ['operation'], + "required": [ + "operation" + ] }, resultSchema: undefined, }, - manage_custom_tool: { + ["manage_custom_tool"]: { parameters: { - type: 'object', - properties: { - code: { - type: 'string', - description: - 'The JavaScript code that executes when the tool is called (required for add). Parameters from schema are available as variables. Function body only - no signature or wrapping braces.', + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "The JavaScript code that executes when the tool is called (required for add). Parameters from schema are available as variables. Function body only - no signature or wrapping braces." }, - operation: { - type: 'string', - description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", - enum: ['add', 'edit', 'delete', 'list'], + "operation": { + "type": "string", + "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", + "enum": [ + "add", + "edit", + "delete", + "list" + ] }, - schema: { - type: 'object', - description: 'The tool schema in OpenAI function calling format (required for add).', - properties: { - function: { - type: 'object', - description: 'The function definition', - properties: { - description: { - type: 'string', - description: 'What the function does', + "schema": { + "type": "object", + "description": "The tool schema in OpenAI function calling format (required for add).", + "properties": { + "function": { + "type": "object", + "description": "The function definition", + "properties": { + "description": { + "type": "string", + "description": "What the function does" }, - name: { - type: 'string', - description: 'The function name (camelCase)', + "name": { + "type": "string", + "description": "The function name (camelCase)" }, - parameters: { - type: 'object', - description: 'The function parameters schema', - properties: { - properties: { - type: 'object', - description: 'Parameter definitions as key-value pairs', + "parameters": { + "type": "object", + "description": "The function parameters schema", + "properties": { + "properties": { + "type": "object", + "description": "Parameter definitions as key-value pairs" }, - required: { - type: 'array', - description: 'Array of required parameter names', - items: { - type: 'string', - }, - }, - type: { - type: 'string', - description: "Must be 'object'", + "required": { + "type": "array", + "description": "Array of required parameter names", + "items": { + "type": "string" + } }, + "type": { + "type": "string", + "description": "Must be 'object'" + } }, - required: ['type', 'properties'], - }, + "required": [ + "type", + "properties" + ] + } }, - required: ['name', 'parameters'], - }, - type: { - type: 'string', - description: "Must be 'function'", - }, - }, - required: ['type', 'function'], - }, - toolId: { - type: 'string', - description: - "The ID of the custom tool (required for edit). Must be the exact toolId from the get_workflow_data custom tool response - do not guess or construct it. DO NOT PROVIDE THE TOOL ID IF THE OPERATION IS 'ADD'.", - }, - toolIds: { - type: 'array', - description: 'Array of custom tool IDs (for batch delete)', - items: { - type: 'string', - }, - }, - }, - required: ['operation'], - }, - resultSchema: undefined, - }, - manage_job: { - parameters: { - type: 'object', - properties: { - args: { - type: 'object', - description: - 'Operation-specific arguments. For create: {title, prompt, cron?, time?, timezone?, lifecycle?, successCondition?, maxRuns?}. For get/delete: {jobId}. For update: {jobId, title?, prompt?, cron?, timezone?, status?, lifecycle?, successCondition?, maxRuns?}. For list: no args needed.', - properties: { - cron: { - type: 'string', - description: 'Cron expression for recurring jobs', - }, - jobId: { - type: 'string', - description: 'Job ID (required for get, update)', - }, - jobIds: { - type: 'array', - description: 'Array of job IDs (for batch delete)', - items: { - type: 'string', - }, - }, - lifecycle: { - type: 'string', - description: - "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called.", - }, - maxRuns: { - type: 'integer', - description: 'Max executions before auto-completing. Safety limit.', - }, - prompt: { - type: 'string', - description: 'The prompt to execute when the job fires', - }, - status: { - type: 'string', - description: 'Job status: active, paused', - }, - successCondition: { - type: 'string', - description: - 'What must happen for the job to be considered complete (until_complete lifecycle).', - }, - time: { - type: 'string', - description: 'ISO 8601 datetime for one-time jobs or cron start time', - }, - timezone: { - type: 'string', - description: 'IANA timezone (e.g. America/New_York). Defaults to UTC.', - }, - title: { - type: 'string', - description: "Short descriptive title for the job (e.g. 'Email Poller')", - }, - }, - }, - operation: { - type: 'string', - description: 'The operation to perform: create, list, get, update, delete', - enum: ['create', 'list', 'get', 'update', 'delete'], - }, - }, - required: ['operation'], - }, - resultSchema: undefined, - }, - manage_mcp_tool: { - parameters: { - type: 'object', - properties: { - config: { - type: 'object', - description: 'Required for add and edit. The MCP server configuration.', - properties: { - enabled: { - type: 'boolean', - description: 'Whether the server is enabled (default: true)', - }, - headers: { - type: 'object', - description: 'Optional HTTP headers to send with requests (key-value pairs)', - }, - name: { - type: 'string', - description: 'Display name for the MCP server', - }, - timeout: { - type: 'number', - description: 'Request timeout in milliseconds (default: 30000)', - }, - transport: { - type: 'string', - description: "Transport protocol: 'streamable-http' or 'sse'", - enum: ['streamable-http', 'sse'], - default: 'streamable-http', - }, - url: { - type: 'string', - description: 'The MCP server endpoint URL (required for add)', - }, - }, - }, - operation: { - type: 'string', - description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", - enum: ['add', 'edit', 'delete', 'list'], - }, - serverId: { - type: 'string', - description: - "Required for edit and delete. The database ID of the MCP server. DO NOT PROVIDE if operation is 'add' or 'list'.", - }, - }, - required: ['operation'], - }, - resultSchema: undefined, - }, - manage_skill: { - parameters: { - type: 'object', - properties: { - content: { - type: 'string', - description: 'Markdown instructions for the skill. Required for add, optional for edit.', - }, - description: { - type: 'string', - description: 'Short description of the skill. Required for add, optional for edit.', - }, - name: { - type: 'string', - description: - "Skill name in kebab-case (e.g. 'my-skill'). Required for add, optional for edit.", - }, - operation: { - type: 'string', - description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", - enum: ['add', 'edit', 'delete', 'list'], - }, - skillId: { - type: 'string', - description: - "The ID of the skill (required for edit/delete). Must be the exact ID from the VFS or list. DO NOT PROVIDE if operation is 'add' or 'list'.", - }, - }, - required: ['operation'], - }, - resultSchema: undefined, - }, - materialize_file: { - parameters: { - type: 'object', - properties: { - fileNames: { - type: 'array', - description: - 'The names of the uploaded files to materialize (e.g. ["report.pdf", "data.csv"])', - items: { - type: 'string', + "required": [ + "name", + "parameters" + ] + }, + "type": { + "type": "string", + "description": "Must be 'function'" + } }, + "required": [ + "type", + "function" + ] + }, + "toolId": { + "type": "string", + "description": "The ID of the custom tool (required for edit). Must be the exact toolId from the get_workflow_data custom tool response - do not guess or construct it. DO NOT PROVIDE THE TOOL ID IF THE OPERATION IS 'ADD'." + }, + "toolIds": { + "type": "array", + "description": "Array of custom tool IDs (for batch delete)", + "items": { + "type": "string" + } + } + }, + "required": [ + "operation" + ] + }, + resultSchema: undefined, + }, + ["manage_job"]: { + parameters: { + "type": "object", + "properties": { + "args": { + "type": "object", + "description": "Operation-specific arguments. For create: {title, prompt, cron?, time?, timezone?, lifecycle?, successCondition?, maxRuns?}. For get/delete: {jobId}. For update: {jobId, title?, prompt?, cron?, timezone?, status?, lifecycle?, successCondition?, maxRuns?}. For list: no args needed.", + "properties": { + "cron": { + "type": "string", + "description": "Cron expression for recurring jobs" + }, + "jobId": { + "type": "string", + "description": "Job ID (required for get, update)" + }, + "jobIds": { + "type": "array", + "description": "Array of job IDs (for batch delete)", + "items": { + "type": "string" + } + }, + "lifecycle": { + "type": "string", + "description": "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called." + }, + "maxRuns": { + "type": "integer", + "description": "Max executions before auto-completing. Safety limit." + }, + "prompt": { + "type": "string", + "description": "The prompt to execute when the job fires" + }, + "status": { + "type": "string", + "description": "Job status: active, paused" + }, + "successCondition": { + "type": "string", + "description": "What must happen for the job to be considered complete (until_complete lifecycle)." + }, + "time": { + "type": "string", + "description": "ISO 8601 datetime for one-time jobs or cron start time" + }, + "timezone": { + "type": "string", + "description": "IANA timezone (e.g. America/New_York). Defaults to UTC." + }, + "title": { + "type": "string", + "description": "Short descriptive title for the job (e.g. 'Email Poller')" + } + } + }, + "operation": { + "type": "string", + "description": "The operation to perform: create, list, get, update, delete", + "enum": [ + "create", + "list", + "get", + "update", + "delete" + ] + } + }, + "required": [ + "operation" + ] + }, + resultSchema: undefined, + }, + ["manage_mcp_tool"]: { + parameters: { + "type": "object", + "properties": { + "config": { + "type": "object", + "description": "Required for add and edit. The MCP server configuration.", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the server is enabled (default: true)" + }, + "headers": { + "type": "object", + "description": "Optional HTTP headers to send with requests (key-value pairs)" + }, + "name": { + "type": "string", + "description": "Display name for the MCP server" + }, + "timeout": { + "type": "number", + "description": "Request timeout in milliseconds (default: 30000)" + }, + "transport": { + "type": "string", + "description": "Transport protocol: 'streamable-http' or 'sse'", + "enum": [ + "streamable-http", + "sse" + ], + "default": "streamable-http" + }, + "url": { + "type": "string", + "description": "The MCP server endpoint URL (required for add)" + } + } + }, + "operation": { + "type": "string", + "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", + "enum": [ + "add", + "edit", + "delete", + "list" + ] + }, + "serverId": { + "type": "string", + "description": "Required for edit and delete. The database ID of the MCP server. DO NOT PROVIDE if operation is 'add' or 'list'." + } + }, + "required": [ + "operation" + ] + }, + resultSchema: undefined, + }, + ["manage_skill"]: { + parameters: { + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "Markdown instructions for the skill. Required for add, optional for edit." + }, + "description": { + "type": "string", + "description": "Short description of the skill. Required for add, optional for edit." + }, + "name": { + "type": "string", + "description": "Skill name in kebab-case (e.g. 'my-skill'). Required for add, optional for edit." + }, + "operation": { + "type": "string", + "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", + "enum": [ + "add", + "edit", + "delete", + "list" + ] + }, + "skillId": { + "type": "string", + "description": "The ID of the skill (required for edit/delete). Must be the exact ID from the VFS or list. DO NOT PROVIDE if operation is 'add' or 'list'." + } + }, + "required": [ + "operation" + ] + }, + resultSchema: undefined, + }, + ["materialize_file"]: { + parameters: { + "type": "object", + "properties": { + "fileNames": { + "type": "array", + "description": "The names of the uploaded files to materialize (e.g. [\"report.pdf\", \"data.csv\"])", + "items": { + "type": "string" + } + }, + "knowledgeBaseId": { + "type": "string", + "description": "ID of an existing knowledge base to add the file to (only used with operation \"knowledge_base\"). If omitted, a new KB is created." + }, + "operation": { + "type": "string", + "description": "What to do with the file. \"save\" promotes it to files/. \"import\" imports a workflow JSON. \"table\" converts CSV/TSV/JSON to a table. \"knowledge_base\" saves and adds to a KB. Defaults to \"save\".", + "enum": [ + "save", + "import", + "table", + "knowledge_base" + ], + "default": "save" }, - knowledgeBaseId: { - type: 'string', - description: - 'ID of an existing knowledge base to add the file to (only used with operation "knowledge_base"). If omitted, a new KB is created.', - }, - operation: { - type: 'string', - description: - 'What to do with the file. "save" promotes it to files/. "import" imports a workflow JSON. "table" converts CSV/TSV/JSON to a table. "knowledge_base" saves and adds to a KB. Defaults to "save".', - enum: ['save', 'import', 'table', 'knowledge_base'], - default: 'save', - }, - tableName: { - type: 'string', - description: - 'Custom name for the table (only used with operation "table"). Defaults to the file name without extension.', - }, + "tableName": { + "type": "string", + "description": "Custom name for the table (only used with operation \"table\"). Defaults to the file name without extension." + } }, - required: ['fileNames'], + "required": [ + "fileNames" + ] }, resultSchema: undefined, }, - move_folder: { + ["move_folder"]: { parameters: { - type: 'object', - properties: { - folderId: { - type: 'string', - description: 'The folder ID to move.', - }, - parentId: { - type: 'string', - description: - 'Target parent folder ID. Omit or pass empty string to move to workspace root.', + "type": "object", + "properties": { + "folderId": { + "type": "string", + "description": "The folder ID to move." }, + "parentId": { + "type": "string", + "description": "Target parent folder ID. Omit or pass empty string to move to workspace root." + } }, - required: ['folderId'], + "required": [ + "folderId" + ] }, resultSchema: undefined, }, - move_workflow: { + ["move_workflow"]: { parameters: { - type: 'object', - properties: { - folderId: { - type: 'string', - description: 'Target folder ID. Omit or pass empty string to move to workspace root.', - }, - workflowIds: { - type: 'array', - description: 'The workflow IDs to move.', - items: { - type: 'string', - }, + "type": "object", + "properties": { + "folderId": { + "type": "string", + "description": "Target folder ID. Omit or pass empty string to move to workspace root." }, + "workflowIds": { + "type": "array", + "description": "The workflow IDs to move.", + "items": { + "type": "string" + } + } }, - required: ['workflowIds'], + "required": [ + "workflowIds" + ] }, resultSchema: undefined, }, - oauth_get_auth_link: { + ["oauth_get_auth_link"]: { parameters: { - type: 'object', - properties: { - providerName: { - type: 'string', - description: - "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar', 'GitHub')", - }, + "type": "object", + "properties": { + "providerName": { + "type": "string", + "description": "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar', 'GitHub')" + } }, - required: ['providerName'], + "required": [ + "providerName" + ] }, resultSchema: undefined, }, - oauth_request_access: { + ["oauth_request_access"]: { parameters: { - type: 'object', - properties: { - providerName: { - type: 'string', - description: - "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar')", - }, + "type": "object", + "properties": { + "providerName": { + "type": "string", + "description": "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar')" + } }, - required: ['providerName'], + "required": [ + "providerName" + ] }, resultSchema: undefined, }, - open_resource: { + ["open_resource"]: { parameters: { - type: 'object', - properties: { - resources: { - type: 'array', - description: 'Array of resources to open. Each item must have type and id.', - items: { - type: 'object', - properties: { - id: { - type: 'string', - description: 'The resource ID.', - }, - type: { - type: 'string', - description: 'The resource type.', - enum: ['workflow', 'table', 'knowledgebase', 'file', 'log'], + "type": "object", + "properties": { + "resources": { + "type": "array", + "description": "Array of resources to open. Each item must have type and id.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The resource ID." }, + "type": { + "type": "string", + "description": "The resource type.", + "enum": [ + "workflow", + "table", + "knowledgebase", + "file", + "log" + ] + } }, - required: ['type', 'id'], - }, - }, + "required": [ + "type", + "id" + ] + } + } }, - required: ['resources'], + "required": [ + "resources" + ] }, resultSchema: undefined, }, - read: { + ["read"]: { parameters: { - type: 'object', - properties: { - limit: { - type: 'number', - description: 'Maximum number of lines to read.', - }, - offset: { - type: 'number', - description: 'Line offset to start reading from (0-indexed).', + "type": "object", + "properties": { + "limit": { + "type": "number", + "description": "Maximum number of lines to read." }, - outputTable: { - type: 'string', - description: - 'Table ID to import the file contents into (CSV/JSON). All existing rows are replaced. Example: "tbl_abc123"', + "offset": { + "type": "number", + "description": "Line offset to start reading from (0-indexed)." }, - path: { - type: 'string', - description: - "Path to the file to read (e.g. 'workflows/My Workflow/state.json' or 'workflows/Projects/Q1/My Workflow/state.json').", + "outputTable": { + "type": "string", + "description": "Table ID to import the file contents into (CSV/JSON). All existing rows are replaced. Example: \"tbl_abc123\"" }, + "path": { + "type": "string", + "description": "Path to the file to read (e.g. 'workflows/My Workflow/state.json' or 'workflows/Projects/Q1/My Workflow/state.json')." + } }, - required: ['path'], + "required": [ + "path" + ] }, resultSchema: undefined, }, - redeploy: { + ["redeploy"]: { parameters: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID to redeploy (required in workspace context)', - }, - }, + "type": "object", + "properties": { + "workflowId": { + "type": "string", + "description": "Workflow ID to redeploy (required in workspace context)" + } + } }, resultSchema: { - type: 'object', - properties: { - apiEndpoint: { - type: 'string', - description: 'Canonical workflow execution endpoint.', - }, - baseUrl: { - type: 'string', - description: 'Base URL used to construct deployment URLs.', - }, - deployedAt: { - type: 'string', - description: 'Deployment timestamp when the workflow is deployed.', - }, - deploymentConfig: { - type: 'object', - description: - 'Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details.', - }, - deploymentStatus: { - type: 'object', - description: - 'Structured per-surface deployment status keyed by surface name, such as api.', - }, - deploymentType: { - type: 'string', - description: - 'Deployment surface this result describes. For deploy_api and redeploy this is always "api".', - }, - examples: { - type: 'object', - description: - 'Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling.', - }, - isDeployed: { - type: 'boolean', - description: 'Whether the workflow API is currently deployed after this tool call.', - }, - version: { - type: 'number', - description: 'Deployment version for the current API deployment.', - }, - workflowId: { - type: 'string', - description: 'Workflow ID that was deployed or undeployed.', - }, - }, - required: [ - 'workflowId', - 'isDeployed', - 'deploymentType', - 'deploymentStatus', - 'deploymentConfig', - 'examples', - ], - }, - }, - rename_file: { - parameters: { - type: 'object', - properties: { - fileId: { - type: 'string', - description: 'Canonical workspace file ID of the file to rename.', - }, - newName: { - type: 'string', - description: - 'New filename including extension, e.g. "draft_v2.md". Must not contain slashes.', - }, - }, - required: ['fileId', 'newName'], + "type": "object", + "properties": { + "apiEndpoint": { + "type": "string", + "description": "Canonical workflow execution endpoint." + }, + "baseUrl": { + "type": "string", + "description": "Base URL used to construct deployment URLs." + }, + "deployedAt": { + "type": "string", + "description": "Deployment timestamp when the workflow is deployed." + }, + "deploymentConfig": { + "type": "object", + "description": "Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details." + }, + "deploymentStatus": { + "type": "object", + "description": "Structured per-surface deployment status keyed by surface name, such as api." + }, + "deploymentType": { + "type": "string", + "description": "Deployment surface this result describes. For deploy_api and redeploy this is always \"api\"." + }, + "examples": { + "type": "object", + "description": "Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling." + }, + "isDeployed": { + "type": "boolean", + "description": "Whether the workflow API is currently deployed after this tool call." + }, + "version": { + "type": "number", + "description": "Deployment version for the current API deployment." + }, + "workflowId": { + "type": "string", + "description": "Workflow ID that was deployed or undeployed." + } + }, + "required": [ + "workflowId", + "isDeployed", + "deploymentType", + "deploymentStatus", + "deploymentConfig", + "examples" + ] + }, + }, + ["rename_file"]: { + parameters: { + "type": "object", + "properties": { + "fileId": { + "type": "string", + "description": "Canonical workspace file ID of the file to rename." + }, + "newName": { + "type": "string", + "description": "New filename including extension, e.g. \"draft_v2.md\". Must not contain slashes." + } + }, + "required": [ + "fileId", + "newName" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: 'Contains id and the new name.', - }, - message: { - type: 'string', - description: 'Human-readable outcome.', + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Contains id and the new name." }, - success: { - type: 'boolean', - description: 'Whether the rename succeeded.', + "message": { + "type": "string", + "description": "Human-readable outcome." }, + "success": { + "type": "boolean", + "description": "Whether the rename succeeded." + } }, - required: ['success', 'message'], + "required": [ + "success", + "message" + ] }, }, - rename_workflow: { + ["rename_workflow"]: { parameters: { - type: 'object', - properties: { - name: { - type: 'string', - description: 'The new name for the workflow.', - }, - workflowId: { - type: 'string', - description: 'The workflow ID to rename.', + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The new name for the workflow." }, + "workflowId": { + "type": "string", + "description": "The workflow ID to rename." + } }, - required: ['workflowId', 'name'], + "required": [ + "workflowId", + "name" + ] }, resultSchema: undefined, }, - research: { + ["research"]: { parameters: { - properties: { - topic: { - description: 'The topic to research.', - type: 'string', - }, + "properties": { + "topic": { + "description": "The topic to research.", + "type": "string" + } }, - required: ['topic'], - type: 'object', + "required": [ + "topic" + ], + "type": "object" }, resultSchema: undefined, }, - respond: { + ["respond"]: { parameters: { - additionalProperties: true, - properties: { - output: { - description: - 'The result — facts, status, VFS paths to persisted data, whatever the caller needs to act on.', - type: 'string', - }, - success: { - description: 'Whether the task completed successfully', - type: 'boolean', + "additionalProperties": true, + "properties": { + "output": { + "description": "The result — facts, status, VFS paths to persisted data, whatever the caller needs to act on.", + "type": "string" }, - type: { - description: 'Optional logical result type override', - type: 'string', + "success": { + "description": "Whether the task completed successfully", + "type": "boolean" }, + "type": { + "description": "Optional logical result type override", + "type": "string" + } }, - required: ['output', 'success'], - type: 'object', + "required": [ + "output", + "success" + ], + "type": "object" }, resultSchema: undefined, }, - restore_resource: { + ["restore_resource"]: { parameters: { - type: 'object', - properties: { - id: { - type: 'string', - description: 'The canonical resource ID to restore.', - }, - type: { - type: 'string', - description: 'The resource type to restore.', - enum: ['workflow', 'table', 'file', 'knowledgebase', 'folder'], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The canonical resource ID to restore." }, + "type": { + "type": "string", + "description": "The resource type to restore.", + "enum": [ + "workflow", + "table", + "file", + "knowledgebase", + "folder" + ] + } }, - required: ['type', 'id'], + "required": [ + "type", + "id" + ] }, resultSchema: undefined, }, - revert_to_version: { + ["revert_to_version"]: { parameters: { - type: 'object', - properties: { - version: { - type: 'number', - description: 'The deployment version number to revert to', - }, - workflowId: { - type: 'string', - description: 'The workflow ID', + "type": "object", + "properties": { + "version": { + "type": "number", + "description": "The deployment version number to revert to" }, + "workflowId": { + "type": "string", + "description": "The workflow ID" + } }, - required: ['workflowId', 'version'], + "required": [ + "workflowId", + "version" + ] }, resultSchema: undefined, }, - run: { + ["run"]: { parameters: { - properties: { - context: { - description: 'Pre-gathered context: workflow state, block IDs, input requirements.', - type: 'string', - }, - request: { - description: 'What to run or what logs to check.', - type: 'string', + "properties": { + "context": { + "description": "Pre-gathered context: workflow state, block IDs, input requirements.", + "type": "string" }, + "request": { + "description": "What to run or what logs to check.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - run_block: { + ["run_block"]: { parameters: { - type: 'object', - properties: { - blockId: { - type: 'string', - description: 'The block ID to run in isolation.', + "type": "object", + "properties": { + "blockId": { + "type": "string", + "description": "The block ID to run in isolation." }, - executionId: { - type: 'string', - description: - 'Optional execution ID to load the snapshot from. Uses latest execution if omitted.', + "executionId": { + "type": "string", + "description": "Optional execution ID to load the snapshot from. Uses latest execution if omitted." }, - useDeployedState: { - type: 'boolean', - description: - 'When true, runs the deployed version instead of the live draft. Default: false (draft).', + "useDeployedState": { + "type": "boolean", + "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to run. If not provided, uses the current workflow in context.', - }, - workflow_input: { - type: 'object', - description: 'JSON object with key-value mappings where each key is an input field name', + "workflowId": { + "type": "string", + "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." }, + "workflow_input": { + "type": "object", + "description": "JSON object with key-value mappings where each key is an input field name" + } }, - required: ['blockId'], + "required": [ + "blockId" + ] }, resultSchema: undefined, }, - run_from_block: { + ["run_from_block"]: { parameters: { - type: 'object', - properties: { - executionId: { - type: 'string', - description: - 'Optional execution ID to load the snapshot from. Uses latest execution if omitted.', - }, - startBlockId: { - type: 'string', - description: 'The block ID to start execution from.', + "type": "object", + "properties": { + "executionId": { + "type": "string", + "description": "Optional execution ID to load the snapshot from. Uses latest execution if omitted." }, - useDeployedState: { - type: 'boolean', - description: - 'When true, runs the deployed version instead of the live draft. Default: false (draft).', + "startBlockId": { + "type": "string", + "description": "The block ID to start execution from." }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to run. If not provided, uses the current workflow in context.', + "useDeployedState": { + "type": "boolean", + "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." }, - workflow_input: { - type: 'object', - description: 'JSON object with key-value mappings where each key is an input field name', + "workflowId": { + "type": "string", + "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." }, + "workflow_input": { + "type": "object", + "description": "JSON object with key-value mappings where each key is an input field name" + } }, - required: ['startBlockId'], + "required": [ + "startBlockId" + ] }, resultSchema: undefined, }, - run_workflow: { + ["run_workflow"]: { parameters: { - type: 'object', - properties: { - triggerBlockId: { - type: 'string', - description: - 'Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one.', - }, - useDeployedState: { - type: 'boolean', - description: - 'When true, runs the deployed version instead of the live draft. Default: false (draft).', + "type": "object", + "properties": { + "triggerBlockId": { + "type": "string", + "description": "Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one." }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to run. If not provided, uses the current workflow in context.', + "useDeployedState": { + "type": "boolean", + "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." }, - workflow_input: { - type: 'object', - description: 'JSON object with key-value mappings where each key is an input field name', + "workflowId": { + "type": "string", + "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." }, + "workflow_input": { + "type": "object", + "description": "JSON object with key-value mappings where each key is an input field name" + } }, - required: ['workflow_input'], + "required": [ + "workflow_input" + ] }, resultSchema: undefined, }, - run_workflow_until_block: { + ["run_workflow_until_block"]: { parameters: { - type: 'object', - properties: { - stopAfterBlockId: { - type: 'string', - description: 'The block ID to stop after. Execution halts once this block completes.', + "type": "object", + "properties": { + "stopAfterBlockId": { + "type": "string", + "description": "The block ID to stop after. Execution halts once this block completes." }, - triggerBlockId: { - type: 'string', - description: - 'Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one.', + "triggerBlockId": { + "type": "string", + "description": "Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one." }, - useDeployedState: { - type: 'boolean', - description: - 'When true, runs the deployed version instead of the live draft. Default: false (draft).', + "useDeployedState": { + "type": "boolean", + "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to run. If not provided, uses the current workflow in context.', - }, - workflow_input: { - type: 'object', - description: 'JSON object with key-value mappings where each key is an input field name', + "workflowId": { + "type": "string", + "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." }, + "workflow_input": { + "type": "object", + "description": "JSON object with key-value mappings where each key is an input field name" + } }, - required: ['stopAfterBlockId'], + "required": [ + "stopAfterBlockId" + ] }, resultSchema: undefined, }, - scrape_page: { + ["scrape_page"]: { parameters: { - type: 'object', - properties: { - include_links: { - type: 'boolean', - description: 'Extract all links from the page (default false)', - }, - url: { - type: 'string', - description: 'The URL to scrape (must include https://)', + "type": "object", + "properties": { + "include_links": { + "type": "boolean", + "description": "Extract all links from the page (default false)" }, - wait_for: { - type: 'string', - description: 'CSS selector to wait for before scraping (for JS-heavy pages)', + "url": { + "type": "string", + "description": "The URL to scrape (must include https://)" }, + "wait_for": { + "type": "string", + "description": "CSS selector to wait for before scraping (for JS-heavy pages)" + } }, - required: ['url'], + "required": [ + "url" + ] }, resultSchema: undefined, }, - search_documentation: { + ["search_documentation"]: { parameters: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'The search query', - }, - topK: { - type: 'number', - description: 'Number of results (max 10)', + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The search query" }, + "topK": { + "type": "number", + "description": "Number of results (max 10)" + } }, - required: ['query'], + "required": [ + "query" + ] }, resultSchema: undefined, }, - search_library_docs: { + ["search_library_docs"]: { parameters: { - type: 'object', - properties: { - library_name: { - type: 'string', - description: "Name of the library to search for (e.g., 'nextjs', 'stripe', 'langchain')", + "type": "object", + "properties": { + "library_name": { + "type": "string", + "description": "Name of the library to search for (e.g., 'nextjs', 'stripe', 'langchain')" }, - query: { - type: 'string', - description: 'The question or topic to find documentation for - be specific', - }, - version: { - type: 'string', - description: "Specific version (optional, e.g., '14', 'v2')", + "query": { + "type": "string", + "description": "The question or topic to find documentation for - be specific" }, + "version": { + "type": "string", + "description": "Specific version (optional, e.g., '14', 'v2')" + } }, - required: ['library_name', 'query'], + "required": [ + "library_name", + "query" + ] }, resultSchema: undefined, }, - search_online: { + ["search_online"]: { parameters: { - type: 'object', - properties: { - category: { - type: 'string', - description: 'Filter by category', - enum: [ - 'news', - 'tweet', - 'github', - 'paper', - 'company', - 'research paper', - 'linkedin profile', - 'pdf', - 'personal site', - ], - }, - include_text: { - type: 'boolean', - description: 'Include page text content (default true)', + "type": "object", + "properties": { + "category": { + "type": "string", + "description": "Filter by category", + "enum": [ + "news", + "tweet", + "github", + "paper", + "company", + "research paper", + "linkedin profile", + "pdf", + "personal site" + ] }, - num_results: { - type: 'number', - description: 'Number of results (default 10, max 25)', + "include_text": { + "type": "boolean", + "description": "Include page text content (default true)" }, - query: { - type: 'string', - description: 'Natural language search query', + "num_results": { + "type": "number", + "description": "Number of results (default 10, max 25)" }, - toolTitle: { - type: 'string', - description: - 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "pricing changes" or "Slack webhook docs", not a full sentence like "Searching online for pricing changes".', + "query": { + "type": "string", + "description": "Natural language search query" }, + "toolTitle": { + "type": "string", + "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"pricing changes\" or \"Slack webhook docs\", not a full sentence like \"Searching online for pricing changes\"." + } }, - required: ['query', 'toolTitle'], + "required": [ + "query", + "toolTitle" + ] }, resultSchema: undefined, }, - search_patterns: { + ["search_patterns"]: { parameters: { - type: 'object', - properties: { - limit: { - type: 'integer', - description: 'Maximum number of unique pattern examples to return (defaults to 3).', - }, - queries: { - type: 'array', - description: - 'Up to 3 descriptive strings explaining the workflow pattern(s) you need. Focus on intent and desired outcomes.', - items: { - type: 'string', - description: 'Example: "how to automate wealthbox meeting notes into follow-up tasks"', - }, + "type": "object", + "properties": { + "limit": { + "type": "integer", + "description": "Maximum number of unique pattern examples to return (defaults to 3)." }, + "queries": { + "type": "array", + "description": "Up to 3 descriptive strings explaining the workflow pattern(s) you need. Focus on intent and desired outcomes.", + "items": { + "type": "string", + "description": "Example: \"how to automate wealthbox meeting notes into follow-up tasks\"" + } + } }, - required: ['queries'], + "required": [ + "queries" + ] }, resultSchema: undefined, }, - set_block_enabled: { + ["set_block_enabled"]: { parameters: { - type: 'object', - properties: { - blockId: { - type: 'string', - description: 'The block ID whose enabled state should be changed.', + "type": "object", + "properties": { + "blockId": { + "type": "string", + "description": "The block ID whose enabled state should be changed." }, - enabled: { - type: 'boolean', - description: 'Set to true to enable the block, or false to disable it.', - }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID to edit. If not provided, uses the current workflow in context.', + "enabled": { + "type": "boolean", + "description": "Set to true to enable the block, or false to disable it." }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID to edit. If not provided, uses the current workflow in context." + } }, - required: ['blockId', 'enabled'], + "required": [ + "blockId", + "enabled" + ] }, - resultSchema: undefined, + resultSchema: undefined, }, - set_environment_variables: { + ["set_environment_variables"]: { parameters: { - type: 'object', - properties: { - scope: { - type: 'string', - description: - 'Whether to set workspace or personal environment variables. Defaults to workspace.', - enum: ['personal', 'workspace'], - default: 'workspace', - }, - variables: { - type: 'array', - description: 'List of env vars to set', - items: { - type: 'object', - properties: { - name: { - type: 'string', - description: 'Variable name', - }, - value: { - type: 'string', - description: 'Variable value', - }, - }, - required: ['name', 'value'], - }, - }, - }, - required: ['variables'], - }, - resultSchema: undefined, - }, - set_global_workflow_variables: { - parameters: { - type: 'object', - properties: { - operations: { - type: 'array', - description: 'List of operations to apply', - items: { - type: 'object', - properties: { - name: { - type: 'string', + "type": "object", + "properties": { + "scope": { + "type": "string", + "description": "Whether to set workspace or personal environment variables. Defaults to workspace.", + "enum": [ + "personal", + "workspace" + ], + "default": "workspace" + }, + "variables": { + "type": "array", + "description": "List of env vars to set", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Variable name" }, - operation: { - type: 'string', - enum: ['add', 'delete', 'edit'], + "value": { + "type": "string", + "description": "Variable value" + } + }, + "required": [ + "name", + "value" + ] + } + } + }, + "required": [ + "variables" + ] + }, + resultSchema: undefined, + }, + ["set_global_workflow_variables"]: { + parameters: { + "type": "object", + "properties": { + "operations": { + "type": "array", + "description": "List of operations to apply", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" }, - type: { - type: 'string', - enum: ['plain', 'number', 'boolean', 'array', 'object'], + "operation": { + "type": "string", + "enum": [ + "add", + "delete", + "edit" + ] }, - value: { - type: 'string', + "type": { + "type": "string", + "enum": [ + "plain", + "number", + "boolean", + "array", + "object" + ] }, + "value": { + "type": "string" + } }, - required: ['operation', 'name', 'type', 'value'], - }, - }, - workflowId: { - type: 'string', - description: - 'Optional workflow ID. If not provided, uses the current workflow in context.', + "required": [ + "operation", + "name", + "type", + "value" + ] + } }, + "workflowId": { + "type": "string", + "description": "Optional workflow ID. If not provided, uses the current workflow in context." + } }, - required: ['operations'], + "required": [ + "operations" + ] }, resultSchema: undefined, }, - superagent: { + ["superagent"]: { parameters: { - properties: { - task: { - description: - "A single sentence — the agent has full conversation context. Do NOT pre-read credentials or look up configs. Example: 'send the email we discussed' or 'check my calendar for tomorrow'.", - type: 'string', - }, + "properties": { + "task": { + "description": "A single sentence — the agent has full conversation context. Do NOT pre-read credentials or look up configs. Example: 'send the email we discussed' or 'check my calendar for tomorrow'.", + "type": "string" + } }, - required: ['task'], - type: 'object', + "required": [ + "task" + ], + "type": "object" }, resultSchema: undefined, }, - table: { + ["table"]: { parameters: { - properties: { - request: { - description: 'What table action is needed.', - type: 'string', - }, + "properties": { + "request": { + "description": "What table action is needed.", + "type": "string" + } }, - required: ['request'], - type: 'object', + "required": [ + "request" + ], + "type": "object" }, resultSchema: undefined, }, - tool_search_tool_regex: { + ["tool_search_tool_regex"]: { parameters: { - properties: { - case_insensitive: { - description: 'Whether the regex should be case-insensitive (default true).', - type: 'boolean', + "properties": { + "case_insensitive": { + "description": "Whether the regex should be case-insensitive (default true).", + "type": "boolean" }, - max_results: { - description: 'Maximum number of tools to return (optional).', - type: 'integer', - }, - pattern: { - description: 'Regular expression to match tool names or descriptions.', - type: 'string', + "max_results": { + "description": "Maximum number of tools to return (optional).", + "type": "integer" }, + "pattern": { + "description": "Regular expression to match tool names or descriptions.", + "type": "string" + } }, - required: ['pattern'], - type: 'object', + "required": [ + "pattern" + ], + "type": "object" }, resultSchema: undefined, }, - update_job_history: { + ["update_job_history"]: { parameters: { - type: 'object', - properties: { - jobId: { - type: 'string', - description: 'The job ID.', - }, - summary: { - type: 'string', - description: - "A concise summary of what was done this run (e.g., 'Sent follow-up emails to 3 leads: Alice, Bob, Carol').", - }, + "type": "object", + "properties": { + "jobId": { + "type": "string", + "description": "The job ID." + }, + "summary": { + "type": "string", + "description": "A concise summary of what was done this run (e.g., 'Sent follow-up emails to 3 leads: Alice, Bob, Carol')." + } }, - required: ['jobId', 'summary'], + "required": [ + "jobId", + "summary" + ] }, resultSchema: undefined, }, - update_workspace_mcp_server: { + ["update_workspace_mcp_server"]: { parameters: { - type: 'object', - properties: { - description: { - type: 'string', - description: 'New description for the server', - }, - isPublic: { - type: 'boolean', - description: 'Whether the server is publicly accessible', + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "New description for the server" }, - name: { - type: 'string', - description: 'New name for the server', + "isPublic": { + "type": "boolean", + "description": "Whether the server is publicly accessible" }, - serverId: { - type: 'string', - description: 'Required: the MCP server ID to update', + "name": { + "type": "string", + "description": "New name for the server" }, + "serverId": { + "type": "string", + "description": "Required: the MCP server ID to update" + } }, - required: ['serverId'], + "required": [ + "serverId" + ] }, resultSchema: undefined, }, - user_memory: { + ["user_memory"]: { parameters: { - type: 'object', - properties: { - confidence: { - type: 'number', - description: 'Confidence level 0-1 (default 1.0 for explicit, 0.8 for inferred)', - }, - correct_value: { - type: 'string', - description: "The correct value to replace the wrong one (for 'correct' operation)", - }, - key: { - type: 'string', - description: "Unique key for the memory (e.g., 'preferred_model', 'slack_credential')", - }, - limit: { - type: 'number', - description: 'Number of results for search (default 10)', + "type": "object", + "properties": { + "confidence": { + "type": "number", + "description": "Confidence level 0-1 (default 1.0 for explicit, 0.8 for inferred)" }, - memory_type: { - type: 'string', - description: "Type of memory: 'preference', 'entity', 'history', or 'correction'", - enum: ['preference', 'entity', 'history', 'correction'], + "correct_value": { + "type": "string", + "description": "The correct value to replace the wrong one (for 'correct' operation)" }, - operation: { - type: 'string', - description: "Operation: 'add', 'search', 'delete', 'correct', or 'list'", - enum: ['add', 'search', 'delete', 'correct', 'list'], + "key": { + "type": "string", + "description": "Unique key for the memory (e.g., 'preferred_model', 'slack_credential')" }, - query: { - type: 'string', - description: 'Search query to find relevant memories', - }, - source: { - type: 'string', - description: "Source: 'explicit' (user told you) or 'inferred' (you observed)", - enum: ['explicit', 'inferred'], - }, - value: { - type: 'string', - description: 'Value to remember', - }, - }, - required: ['operation'], - }, - resultSchema: undefined, - }, - user_table: { - parameters: { - type: 'object', - properties: { - args: { - type: 'object', - description: 'Arguments for the operation', - properties: { - autoRun: { - type: 'boolean', - description: - 'Optional flag for add_workflow_group. When true, existing rows whose dependencies are already filled run immediately. Default false: groups are staged silently — call run_workflow_group when ready to fire rows. Set true if the user explicitly asked you to start runs.', - }, - blockId: { - type: 'string', - description: - 'Source block ID inside the workflow. Used by add_workflow_group_output.', - }, - column: { - type: 'object', - description: 'Column definition for add_column: { name, type, unique?, position? }', - }, - columnName: { - type: 'string', - description: - 'Column name. Required for rename_column, update_column, and delete_workflow_group_output (the bound column to drop). Optional for add_workflow_group_output (auto-derived from path when omitted). Use columnNames array for batch delete_column.', - }, - columnNames: { - type: 'array', - description: - 'Array of column names to delete at once (for delete_column). Preferred over columnName when deleting multiple columns.', - }, - data: { - type: 'object', - description: 'Row data as key-value pairs (required for insert_row, update_row)', - }, - dependencies: { - type: 'object', - description: - 'Dependencies the workflow group requires before running a row. { columns?: string[] } lists input column names that must be filled; { workflowGroups?: string[] } lists other workflow group IDs whose outputs must complete first. Used by add_workflow_group and update_workflow_group.', - properties: { - columns: { - type: 'array', - description: 'Input column names that must be filled before the group runs.', - items: { - type: 'string', - }, - }, - workflowGroups: { - type: 'array', - description: 'Other workflow group IDs whose outputs must complete first.', - items: { - type: 'string', - }, - }, - }, - }, - description: { - type: 'string', - description: "Table description (optional for 'create')", - }, - fileId: { - type: 'string', - description: - 'Canonical workspace file ID for create_from_file/import_file. Discover via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json").', - }, - filePath: { - type: 'string', - description: - 'Legacy workspace file reference for create_from_file/import_file. Prefer fileId.', - }, - filter: { - type: 'object', - description: - 'MongoDB-style filter for query_rows, update_rows_by_filter, delete_rows_by_filter', - }, - groupId: { - type: 'string', - description: - 'Workflow group ID (required for update_workflow_group, delete_workflow_group, add_workflow_group_output, delete_workflow_group_output, run_workflow_group).', - }, - limit: { - type: 'number', - description: 'Maximum rows to return or affect (optional, default 100)', - }, - mapping: { - type: 'object', - description: - 'Optional explicit CSV-header → table-column mapping for import_file, as { "csvHeader": "columnName" | null }. A string maps the CSV header to that table column; null skips that CSV header (it won\'t be imported); omit a header entirely to fall back to auto-mapping by sanitized name (case-insensitive).', - additionalProperties: { - type: ['string', 'null'], - description: - "Target column name on the table. null skips that CSV header (it won't be imported); omit it entirely to fall back to auto-mapping.", - }, - }, - mode: { - type: 'string', - description: - "Import mode for import_file. 'append' (default) adds rows; 'replace' truncates existing rows in a transaction before inserting the new rows.", - enum: ['append', 'replace'], - }, - name: { - type: 'string', - description: "Table name (required for 'create')", - }, - newName: { - type: 'string', - description: 'New column name (required for rename_column)', - }, - newType: { - type: 'string', - description: - 'New column type (optional for update_column). Types: string, number, boolean, date, json', - }, - offset: { - type: 'number', - description: 'Number of rows to skip (optional for query_rows, default 0)', - }, - outputFormat: { - type: 'string', - description: - 'Explicit format override for outputPath. Usually unnecessary — the file extension determines the format automatically. Only use this to force a different format than what the extension implies.', - enum: ['json', 'csv', 'txt', 'md', 'html'], - }, - outputPath: { - type: 'string', - description: - 'Pipe query_rows results directly to a NEW workspace file. The format is auto-inferred from the file extension: .csv → CSV, .json → JSON, .md → Markdown, etc. Use .csv for tabular exports. Use a flat path like "files/export.csv" — nested paths are not supported.', - }, - outputs: { - type: 'array', - description: - "Outputs to surface as columns. Each entry maps a workflow block output to a table column: { blockId, path, columnName?, columnType? }. blockId is the source block; path is the dotted output path; columnName auto-derives from the path when omitted; columnType defaults from the leaf type when omitted. Used by add_workflow_group. (Also accepted by update_workflow_group for the UI's bulk replace, but the AI flow should use add_workflow_group_output / delete_workflow_group_output instead.) If unsure about valid (blockId, path) pairs, call list_workflow_outputs first — paths are validated against the live workflow and invalid picks return an error with the valid options. For Agent blocks with structured outputs, the structured fields appear as top-level paths (e.g. summary, industry); there is NO response.content path on a structured agent.", - items: { - type: 'object', - properties: { - blockId: { - type: 'string', - description: 'Source block ID inside the workflow.', - }, - columnName: { - type: 'string', - description: - 'Optional target column name. Auto-derived from the path when omitted.', - }, - columnType: { - type: 'string', - description: 'Optional column type. Defaults from the leaf type when omitted.', - enum: ['string', 'number', 'boolean', 'date', 'json'], - }, - path: { - type: 'string', - description: 'Dotted output path on the block.', - }, - }, - required: ['blockId', 'path'], - }, - }, - path: { - type: 'string', - description: 'Dotted output path on the block. Used by add_workflow_group_output.', - }, - position: { - type: 'integer', - description: - 'Zero-based index at which to insert the row (optional, insert_row only). Rows at and below that index shift down. Omit to append at the end.', - }, - positions: { - type: 'array', - description: - 'Per-row insertion indices for batch_insert_rows (optional). Must be the same length as rows and contain no duplicates. Values are final positions in the resulting table — lower-index shifts are applied automatically. Omit to append all rows at the end.', - items: { - type: 'integer', - }, - }, - rowId: { - type: 'string', - description: - "Row ID. Required for get_row, update_row, delete_row, and for cancel_table_runs when scope:'row'.", - }, - rowIds: { - type: 'array', - description: - 'Array of row IDs. Used by batch_delete_rows (rows to delete) and run_workflow_group (optional row scope: when omitted, runs across the whole table; when provided, only these rows are candidates and the eligibility predicate still applies — mid-run rows or rows with unmet deps are silently skipped).', - items: { - type: 'string', - }, - }, - rows: { - type: 'array', - description: 'Array of row data objects (required for batch_insert_rows)', - }, - runMode: { - type: 'string', - description: - "Run mode for run_workflow_group. 'incomplete' (default) re-runs only rows that never produced output or last failed; 'all' re-runs every dep-satisfied row.", - enum: ['incomplete', 'all'], - }, - schema: { - type: 'object', - description: - "Table schema with columns array (required for 'create'). Each column: { name, type, unique? }", - }, - scope: { - type: 'string', - description: - "Cancellation scope for cancel_table_runs. 'all' cancels in-flight runs across the whole table; 'row' cancels only the row identified by rowId.", - enum: ['all', 'row'], - }, - sort: { - type: 'object', - description: - "Sort specification as { field: 'asc' | 'desc' } (optional for query_rows)", - }, - tableId: { - type: 'string', - description: - "Table ID (required for most operations except 'create' and batch 'delete')", - }, - tableIds: { - type: 'array', - description: 'Array of table IDs (for batch delete)', - items: { - type: 'string', - }, - }, - unique: { - type: 'boolean', - description: 'Set column unique constraint (optional for update_column)', - }, - updates: { - type: 'array', - description: - 'Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows)', - }, - values: { - type: 'object', - description: - 'Map of rowId to value for single-column batch update: { "rowId1": val1, "rowId2": val2 } (for batch_update_rows with columnName)', - }, - workflowId: { - type: 'string', - description: - 'ID of the workflow (required for add_workflow_group and list_workflow_outputs).', - }, - }, - }, - operation: { - type: 'string', - description: 'The operation to perform', - enum: [ - 'create', - 'create_from_file', - 'import_file', - 'get', - 'get_schema', - 'delete', - 'insert_row', - 'batch_insert_rows', - 'get_row', - 'query_rows', - 'update_row', - 'delete_row', - 'update_rows_by_filter', - 'delete_rows_by_filter', - 'batch_update_rows', - 'batch_delete_rows', - 'add_column', - 'rename_column', - 'delete_column', - 'update_column', - 'add_workflow_group', - 'update_workflow_group', - 'delete_workflow_group', - 'add_workflow_group_output', - 'delete_workflow_group_output', - 'run_workflow_group', - 'cancel_table_runs', - 'list_workflow_outputs', - ], - }, - }, - required: ['operation', 'args'], + "limit": { + "type": "number", + "description": "Number of results for search (default 10)" + }, + "memory_type": { + "type": "string", + "description": "Type of memory: 'preference', 'entity', 'history', or 'correction'", + "enum": [ + "preference", + "entity", + "history", + "correction" + ] + }, + "operation": { + "type": "string", + "description": "Operation: 'add', 'search', 'delete', 'correct', or 'list'", + "enum": [ + "add", + "search", + "delete", + "correct", + "list" + ] + }, + "query": { + "type": "string", + "description": "Search query to find relevant memories" + }, + "source": { + "type": "string", + "description": "Source: 'explicit' (user told you) or 'inferred' (you observed)", + "enum": [ + "explicit", + "inferred" + ] + }, + "value": { + "type": "string", + "description": "Value to remember" + } + }, + "required": [ + "operation" + ] + }, + resultSchema: undefined, + }, + ["user_table"]: { + parameters: { + "type": "object", + "properties": { + "args": { + "type": "object", + "description": "Arguments for the operation", + "properties": { + "column": { + "type": "object", + "description": "Column definition for add_column: { name, type, unique?, position? }" + }, + "columnName": { + "type": "string", + "description": "Column name (required for rename_column, update_column; use columnNames array for batch delete_column)" + }, + "columnNames": { + "type": "array", + "description": "Array of column names to delete at once (for delete_column). Preferred over columnName when deleting multiple columns." + }, + "data": { + "type": "object", + "description": "Row data as key-value pairs (required for insert_row, update_row)" + }, + "description": { + "type": "string", + "description": "Table description (optional for 'create')" + }, + "fileId": { + "type": "string", + "description": "Canonical workspace file ID for create_from_file/import_file. Discover via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\")." + }, + "filePath": { + "type": "string", + "description": "Legacy workspace file reference for create_from_file/import_file. Prefer fileId." + }, + "filter": { + "type": "object", + "description": "MongoDB-style filter for query_rows, update_rows_by_filter, delete_rows_by_filter" + }, + "limit": { + "type": "number", + "description": "Maximum rows to return or affect (optional, default 100)" + }, + "mapping": { + "type": "object", + "description": "Optional explicit CSV-header → table-column mapping for import_file, as { \"csvHeader\": \"columnName\" | null }. When omitted, headers are auto-matched by sanitized name (case-insensitive fallback). Use null to skip a CSV column.", + "additionalProperties": { + "type": "string", + "description": "Target column name on the table. Use null to skip this CSV header instead of a column name." + } + }, + "mode": { + "type": "string", + "description": "Import mode for import_file. 'append' (default) adds rows; 'replace' truncates existing rows in a transaction before inserting the new rows.", + "enum": [ + "append", + "replace" + ] + }, + "name": { + "type": "string", + "description": "Table name (required for 'create')" + }, + "newName": { + "type": "string", + "description": "New column name (required for rename_column)" + }, + "newType": { + "type": "string", + "description": "New column type (optional for update_column). Types: string, number, boolean, date, json" + }, + "offset": { + "type": "number", + "description": "Number of rows to skip (optional for query_rows, default 0)" + }, + "outputFormat": { + "type": "string", + "description": "Explicit format override for outputPath. Usually unnecessary — the file extension determines the format automatically. Only use this to force a different format than what the extension implies.", + "enum": [ + "json", + "csv", + "txt", + "md", + "html" + ] + }, + "outputPath": { + "type": "string", + "description": "Pipe query_rows results directly to a NEW workspace file. The format is auto-inferred from the file extension: .csv → CSV, .json → JSON, .md → Markdown, etc. Use .csv for tabular exports. Use a flat path like \"files/export.csv\" — nested paths are not supported." + }, + "position": { + "type": "integer", + "description": "Zero-based index at which to insert the row (optional, insert_row only). Rows at and below that index shift down. Omit to append at the end." + }, + "positions": { + "type": "array", + "description": "Per-row insertion indices for batch_insert_rows (optional). Must be the same length as rows and contain no duplicates. Values are final positions in the resulting table — lower-index shifts are applied automatically. Omit to append all rows at the end.", + "items": { + "type": "integer" + } + }, + "rowId": { + "type": "string", + "description": "Row ID (required for get_row, update_row, delete_row)" + }, + "rowIds": { + "type": "array", + "description": "Array of row IDs to delete (for batch_delete_rows)" + }, + "rows": { + "type": "array", + "description": "Array of row data objects (required for batch_insert_rows)" + }, + "schema": { + "type": "object", + "description": "Table schema with columns array (required for 'create'). Each column: { name, type, unique? }" + }, + "sort": { + "type": "object", + "description": "Sort specification as { field: 'asc' | 'desc' } (optional for query_rows)" + }, + "tableId": { + "type": "string", + "description": "Table ID (required for most operations except 'create' and batch 'delete')" + }, + "tableIds": { + "type": "array", + "description": "Array of table IDs (for batch delete)", + "items": { + "type": "string" + } + }, + "unique": { + "type": "boolean", + "description": "Set column unique constraint (optional for update_column)" + }, + "updates": { + "type": "array", + "description": "Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows)" + }, + "values": { + "type": "object", + "description": "Map of rowId to value for single-column batch update: { \"rowId1\": val1, \"rowId2\": val2 } (for batch_update_rows with columnName)" + } + } + }, + "operation": { + "type": "string", + "description": "The operation to perform", + "enum": [ + "create", + "create_from_file", + "import_file", + "get", + "get_schema", + "delete", + "insert_row", + "batch_insert_rows", + "get_row", + "query_rows", + "update_row", + "delete_row", + "update_rows_by_filter", + "delete_rows_by_filter", + "batch_update_rows", + "batch_delete_rows", + "add_column", + "rename_column", + "delete_column", + "update_column" + ] + } + }, + "required": [ + "operation", + "args" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: 'Operation-specific result payload.', - }, - message: { - type: 'string', - description: 'Human-readable outcome summary.', - }, - success: { - type: 'boolean', - description: 'Whether the operation succeeded.', - }, - }, - required: ['success', 'message'], - }, - }, - workflow: { - parameters: { - type: 'object', - }, - resultSchema: undefined, - }, - workspace_file: { - parameters: { - type: 'object', - properties: { - operation: { - type: 'string', - description: 'The file operation to perform.', - enum: ['append', 'update', 'patch'], - }, - target: { - type: 'object', - description: 'Explicit file target. Use kind=file_id + fileId for existing files.', - properties: { - fileId: { - type: 'string', - description: - 'Canonical existing workspace file ID. Required when target.kind=file_id.', - }, - fileName: { - type: 'string', - description: - 'Plain workspace filename including extension, e.g. "main.py" or "report.docx". Required when target.kind=new_file.', - }, - kind: { - type: 'string', - description: 'How the file target is identified.', - enum: ['new_file', 'file_id'], - }, + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Operation-specific result payload." + }, + "message": { + "type": "string", + "description": "Human-readable outcome summary." + }, + "success": { + "type": "boolean", + "description": "Whether the operation succeeded." + } + }, + "required": [ + "success", + "message" + ] + }, + }, + ["workflow"]: { + parameters: { + "type": "object" + }, + resultSchema: undefined, + }, + ["workspace_file"]: { + parameters: { + "type": "object", + "properties": { + "operation": { + "type": "string", + "description": "The file operation to perform.", + "enum": [ + "append", + "update", + "patch" + ] + }, + "target": { + "type": "object", + "description": "Explicit file target. Use kind=file_id + fileId for existing files.", + "properties": { + "fileId": { + "type": "string", + "description": "Canonical existing workspace file ID. Required when target.kind=file_id." + }, + "fileName": { + "type": "string", + "description": "Plain workspace filename including extension, e.g. \"main.py\" or \"report.docx\". Required when target.kind=new_file." + }, + "kind": { + "type": "string", + "description": "How the file target is identified.", + "enum": [ + "new_file", + "file_id" + ] + } }, - required: ['kind'], - }, - title: { - type: 'string', - description: - 'Required short UI label for this content unit, e.g. "Chapter 1", "Slide 3", or "Fix footer spacing".', - }, - contentType: { - type: 'string', - description: - 'Optional MIME type override. Usually omit and let the system infer from the target file extension.', - enum: [ - 'text/markdown', - 'text/html', - 'text/plain', - 'application/json', - 'text/csv', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'application/pdf', - ], - }, - edit: { - type: 'object', - description: - 'Patch metadata. Use strategy=search_replace for exact text replacement, or strategy=anchored for line-based inserts/replacements/deletions. The actual replacement/insert content is provided via the paired edit_content tool call.', - properties: { - after_anchor: { - type: 'string', - description: - 'Boundary line kept after inserted replacement content. Required for mode=replace_between.', - }, - anchor: { - type: 'string', - description: - 'Anchor line after which new content is inserted. Required for mode=insert_after.', - }, - before_anchor: { - type: 'string', - description: - 'Boundary line kept before inserted replacement content. Required for mode=replace_between.', - }, - end_anchor: { - type: 'string', - description: 'First line to keep after deletion. Required for mode=delete_between.', - }, - mode: { - type: 'string', - description: 'Anchored edit mode when strategy=anchored.', - enum: ['replace_between', 'insert_after', 'delete_between'], - }, - occurrence: { - type: 'number', - description: '1-based occurrence for repeated anchor lines. Optional; defaults to 1.', - }, - replaceAll: { - type: 'boolean', - description: - 'When true and strategy=search_replace, replace every match instead of requiring a unique single match.', - }, - search: { - type: 'string', - description: - 'Exact text to find when strategy=search_replace. Must match exactly once unless replaceAll=true.', - }, - start_anchor: { - type: 'string', - description: 'First line to delete. Required for mode=delete_between.', - }, - strategy: { - type: 'string', - description: 'Patch strategy.', - enum: ['search_replace', 'anchored'], - }, - }, - }, - newName: { - type: 'string', - description: - 'New file name for rename. Must be a plain workspace filename like "main.py".', - }, - }, - required: ['operation', 'target', 'title'], + "required": [ + "kind" + ] + }, + "title": { + "type": "string", + "description": "Required short UI label for this content unit, e.g. \"Chapter 1\", \"Slide 3\", or \"Fix footer spacing\"." + }, + "contentType": { + "type": "string", + "description": "Optional MIME type override. Usually omit and let the system infer from the target file extension.", + "enum": [ + "text/markdown", + "text/html", + "text/plain", + "application/json", + "text/csv", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/pdf" + ] + }, + "edit": { + "type": "object", + "description": "Patch metadata. Use strategy=search_replace for exact text replacement, or strategy=anchored for line-based inserts/replacements/deletions. The actual replacement/insert content is provided via the paired edit_content tool call.", + "properties": { + "after_anchor": { + "type": "string", + "description": "Boundary line kept after inserted replacement content. Required for mode=replace_between." + }, + "anchor": { + "type": "string", + "description": "Anchor line after which new content is inserted. Required for mode=insert_after." + }, + "before_anchor": { + "type": "string", + "description": "Boundary line kept before inserted replacement content. Required for mode=replace_between." + }, + "end_anchor": { + "type": "string", + "description": "First line to keep after deletion. Required for mode=delete_between." + }, + "mode": { + "type": "string", + "description": "Anchored edit mode when strategy=anchored.", + "enum": [ + "replace_between", + "insert_after", + "delete_between" + ] + }, + "occurrence": { + "type": "number", + "description": "1-based occurrence for repeated anchor lines. Optional; defaults to 1." + }, + "replaceAll": { + "type": "boolean", + "description": "When true and strategy=search_replace, replace every match instead of requiring a unique single match." + }, + "search": { + "type": "string", + "description": "Exact text to find when strategy=search_replace. Must match exactly once unless replaceAll=true." + }, + "start_anchor": { + "type": "string", + "description": "First line to delete. Required for mode=delete_between." + }, + "strategy": { + "type": "string", + "description": "Patch strategy.", + "enum": [ + "search_replace", + "anchored" + ] + } + } + }, + "newName": { + "type": "string", + "description": "New file name for rename. Must be a plain workspace filename like \"main.py\"." + } + }, + "required": [ + "operation", + "target", + "title" + ] }, resultSchema: { - type: 'object', - properties: { - data: { - type: 'object', - description: - 'Optional operation metadata such as file id, file name, size, and content type.', - }, - message: { - type: 'string', - description: 'Human-readable summary of the outcome.', - }, - success: { - type: 'boolean', - description: 'Whether the file operation succeeded.', - }, - }, - required: ['success', 'message'], + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "Optional operation metadata such as file id, file name, size, and content type." + }, + "message": { + "type": "string", + "description": "Human-readable summary of the outcome." + }, + "success": { + "type": "boolean", + "description": "Whether the file operation succeeded." + } + }, + "required": [ + "success", + "message" + ] }, }, } From 1fbac96159300873505cdd352e1526ed7630a437 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 2 May 2026 18:09:41 -0700 Subject: [PATCH 2/4] fix lint --- .../lib/copilot/generated/tool-schemas-v1.ts | 5030 ++++++++--------- 1 file changed, 2403 insertions(+), 2627 deletions(-) diff --git a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts index f450dccbcec..5a2e2a196d8 100644 --- a/apps/sim/lib/copilot/generated/tool-schemas-v1.ts +++ b/apps/sim/lib/copilot/generated/tool-schemas-v1.ts @@ -5,3152 +5,2928 @@ export type JsonSchema = unknown export interface ToolRuntimeSchemaEntry { - parameters?: JsonSchema; - resultSchema?: JsonSchema; + parameters?: JsonSchema + resultSchema?: JsonSchema } export const TOOL_RUNTIME_SCHEMAS: Record = { - ["agent"]: { + agent: { parameters: { - "properties": { - "request": { - "description": "What tool/skill/MCP action is needed.", - "type": "string" - } + properties: { + request: { + description: 'What tool/skill/MCP action is needed.', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["auth"]: { + auth: { parameters: { - "properties": { - "request": { - "description": "What authentication/credential action is needed.", - "type": "string" - } + properties: { + request: { + description: 'What authentication/credential action is needed.', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["check_deployment_status"]: { + check_deployment_status: { parameters: { - "type": "object", - "properties": { - "workflowId": { - "type": "string", - "description": "Workflow ID to check (defaults to current workflow)" - } - } + type: 'object', + properties: { + workflowId: { + type: 'string', + description: 'Workflow ID to check (defaults to current workflow)', + }, + }, }, resultSchema: undefined, }, - ["complete_job"]: { + complete_job: { parameters: { - "type": "object", - "properties": { - "jobId": { - "type": "string", - "description": "The ID of the job to mark as completed." - } + type: 'object', + properties: { + jobId: { + type: 'string', + description: 'The ID of the job to mark as completed.', + }, }, - "required": [ - "jobId" - ] + required: ['jobId'], }, resultSchema: undefined, }, - ["context_write"]: { + context_write: { parameters: { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Full content to write to the file (replaces existing content)" + type: 'object', + properties: { + content: { + type: 'string', + description: 'Full content to write to the file (replaces existing content)', + }, + file_path: { + type: 'string', + description: "Path of the file to write (e.g. 'SESSION.md')", }, - "file_path": { - "type": "string", - "description": "Path of the file to write (e.g. 'SESSION.md')" - } }, - "required": [ - "file_path", - "content" - ] + required: ['file_path', 'content'], }, resultSchema: undefined, }, - ["crawl_website"]: { + crawl_website: { parameters: { - "type": "object", - "properties": { - "exclude_paths": { - "type": "array", - "description": "Skip URLs matching these patterns", - "items": { - "type": "string" - } + type: 'object', + properties: { + exclude_paths: { + type: 'array', + description: 'Skip URLs matching these patterns', + items: { + type: 'string', + }, + }, + include_paths: { + type: 'array', + description: 'Only crawl URLs matching these patterns', + items: { + type: 'string', + }, }, - "include_paths": { - "type": "array", - "description": "Only crawl URLs matching these patterns", - "items": { - "type": "string" - } + limit: { + type: 'number', + description: 'Maximum pages to crawl (default 10, max 50)', }, - "limit": { - "type": "number", - "description": "Maximum pages to crawl (default 10, max 50)" + max_depth: { + type: 'number', + description: 'How deep to follow links (default 2)', }, - "max_depth": { - "type": "number", - "description": "How deep to follow links (default 2)" + url: { + type: 'string', + description: 'Starting URL to crawl from', }, - "url": { - "type": "string", - "description": "Starting URL to crawl from" - } }, - "required": [ - "url" - ] + required: ['url'], }, resultSchema: undefined, }, - ["create_file"]: { + create_file: { parameters: { - "type": "object", - "properties": { - "contentType": { - "type": "string", - "description": "Optional MIME type override. Usually omit and let the system infer from the file extension." + type: 'object', + properties: { + contentType: { + type: 'string', + description: + 'Optional MIME type override. Usually omit and let the system infer from the file extension.', + }, + fileName: { + type: 'string', + description: + 'Plain workspace filename including extension, e.g. "main.py" or "report.md". Must not contain slashes.', }, - "fileName": { - "type": "string", - "description": "Plain workspace filename including extension, e.g. \"main.py\" or \"report.md\". Must not contain slashes." - } }, - "required": [ - "fileName" - ] + required: ['fileName'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Contains id (the fileId) and name." + type: 'object', + properties: { + data: { + type: 'object', + description: 'Contains id (the fileId) and name.', + }, + message: { + type: 'string', + description: 'Human-readable outcome.', }, - "message": { - "type": "string", - "description": "Human-readable outcome." + success: { + type: 'boolean', + description: 'Whether the file was created.', }, - "success": { - "type": "boolean", - "description": "Whether the file was created." - } }, - "required": [ - "success", - "message" - ] + required: ['success', 'message'], }, }, - ["create_folder"]: { + create_folder: { parameters: { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Folder name." + type: 'object', + properties: { + name: { + type: 'string', + description: 'Folder name.', + }, + parentId: { + type: 'string', + description: 'Optional parent folder ID.', }, - "parentId": { - "type": "string", - "description": "Optional parent folder ID." + workspaceId: { + type: 'string', + description: 'Optional workspace ID.', }, - "workspaceId": { - "type": "string", - "description": "Optional workspace ID." - } }, - "required": [ - "name" - ] + required: ['name'], }, resultSchema: undefined, }, - ["create_job"]: { + create_job: { parameters: { - "type": "object", - "properties": { - "cron": { - "type": "string", - "description": "Cron expression for recurring jobs (e.g., '*/5 * * * *' for every 5 minutes, '0 9 * * *' for daily at 9 AM). Omit for one-time jobs." + type: 'object', + properties: { + cron: { + type: 'string', + description: + "Cron expression for recurring jobs (e.g., '*/5 * * * *' for every 5 minutes, '0 9 * * *' for daily at 9 AM). Omit for one-time jobs.", }, - "lifecycle": { - "type": "string", - "description": "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called after the success condition is met.", - "enum": [ - "persistent", - "until_complete" - ] + lifecycle: { + type: 'string', + description: + "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called after the success condition is met.", + enum: ['persistent', 'until_complete'], }, - "maxRuns": { - "type": "integer", - "description": "Maximum number of executions before the job auto-completes. Safety limit to prevent runaway polling." + maxRuns: { + type: 'integer', + description: + 'Maximum number of executions before the job auto-completes. Safety limit to prevent runaway polling.', }, - "prompt": { - "type": "string", - "description": "The prompt to execute when the job fires. This is sent to the Mothership as a user message." + prompt: { + type: 'string', + description: + 'The prompt to execute when the job fires. This is sent to the Mothership as a user message.', }, - "successCondition": { - "type": "string", - "description": "What must happen for the job to be considered complete. Used with until_complete lifecycle (e.g., 'John has replied to the partnership email')." + successCondition: { + type: 'string', + description: + "What must happen for the job to be considered complete. Used with until_complete lifecycle (e.g., 'John has replied to the partnership email').", }, - "time": { - "type": "string", - "description": "ISO 8601 datetime for one-time execution or as the start time for a cron schedule (e.g., '2026-03-06T09:00:00'). Include timezone offset or use the timezone parameter." + time: { + type: 'string', + description: + "ISO 8601 datetime for one-time execution or as the start time for a cron schedule (e.g., '2026-03-06T09:00:00'). Include timezone offset or use the timezone parameter.", }, - "timezone": { - "type": "string", - "description": "IANA timezone for the schedule (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC." + timezone: { + type: 'string', + description: + "IANA timezone for the schedule (e.g., 'America/New_York', 'Europe/London'). Defaults to UTC.", + }, + title: { + type: 'string', + description: + "A short, descriptive title for the job (e.g., 'Email Poller', 'Daily Report'). Used as the display name.", }, - "title": { - "type": "string", - "description": "A short, descriptive title for the job (e.g., 'Email Poller', 'Daily Report'). Used as the display name." - } }, - "required": [ - "title", - "prompt" - ] + required: ['title', 'prompt'], }, resultSchema: undefined, }, - ["create_workflow"]: { + create_workflow: { parameters: { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Optional workflow description." + type: 'object', + properties: { + description: { + type: 'string', + description: 'Optional workflow description.', + }, + folderId: { + type: 'string', + description: 'Optional folder ID.', }, - "folderId": { - "type": "string", - "description": "Optional folder ID." + name: { + type: 'string', + description: 'Workflow name.', }, - "name": { - "type": "string", - "description": "Workflow name." + workspaceId: { + type: 'string', + description: 'Optional workspace ID.', }, - "workspaceId": { - "type": "string", - "description": "Optional workspace ID." - } }, - "required": [ - "name" - ] + required: ['name'], }, resultSchema: undefined, }, - ["create_workspace_mcp_server"]: { + create_workspace_mcp_server: { parameters: { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Optional description for the server" + type: 'object', + properties: { + description: { + type: 'string', + description: 'Optional description for the server', + }, + name: { + type: 'string', + description: 'Required: server name', }, - "name": { - "type": "string", - "description": "Required: server name" + workspaceId: { + type: 'string', + description: 'Workspace ID (defaults to current workspace)', }, - "workspaceId": { - "type": "string", - "description": "Workspace ID (defaults to current workspace)" - } }, - "required": [ - "name" - ] + required: ['name'], }, resultSchema: undefined, }, - ["debug"]: { + debug: { parameters: { - "properties": { - "context": { - "description": "Pre-gathered context: workflow state JSON, block schemas, error logs. The debug agent will skip re-reading anything included here.", - "type": "string" + properties: { + context: { + description: + 'Pre-gathered context: workflow state JSON, block schemas, error logs. The debug agent will skip re-reading anything included here.', + type: 'string', + }, + request: { + description: + 'What to debug. Include error messages, block IDs, and any context about the failure.', + type: 'string', }, - "request": { - "description": "What to debug. Include error messages, block IDs, and any context about the failure.", - "type": "string" - } }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["delete_file"]: { + delete_file: { parameters: { - "type": "object", - "properties": { - "fileIds": { - "type": "array", - "description": "Canonical workspace file IDs of the files to delete.", - "items": { - "type": "string" - } - } + type: 'object', + properties: { + fileIds: { + type: 'array', + description: 'Canonical workspace file IDs of the files to delete.', + items: { + type: 'string', + }, + }, }, - "required": [ - "fileIds" - ] + required: ['fileIds'], }, resultSchema: { - "type": "object", - "properties": { - "message": { - "type": "string", - "description": "Human-readable outcome." + type: 'object', + properties: { + message: { + type: 'string', + description: 'Human-readable outcome.', + }, + success: { + type: 'boolean', + description: 'Whether the delete succeeded.', }, - "success": { - "type": "boolean", - "description": "Whether the delete succeeded." - } }, - "required": [ - "success", - "message" - ] + required: ['success', 'message'], }, }, - ["delete_folder"]: { + delete_folder: { parameters: { - "type": "object", - "properties": { - "folderIds": { - "type": "array", - "description": "The folder IDs to delete.", - "items": { - "type": "string" - } - } + type: 'object', + properties: { + folderIds: { + type: 'array', + description: 'The folder IDs to delete.', + items: { + type: 'string', + }, + }, }, - "required": [ - "folderIds" - ] + required: ['folderIds'], }, resultSchema: undefined, }, - ["delete_workflow"]: { + delete_workflow: { parameters: { - "type": "object", - "properties": { - "workflowIds": { - "type": "array", - "description": "The workflow IDs to delete.", - "items": { - "type": "string" - } - } + type: 'object', + properties: { + workflowIds: { + type: 'array', + description: 'The workflow IDs to delete.', + items: { + type: 'string', + }, + }, }, - "required": [ - "workflowIds" - ] + required: ['workflowIds'], }, resultSchema: undefined, }, - ["delete_workspace_mcp_server"]: { + delete_workspace_mcp_server: { parameters: { - "type": "object", - "properties": { - "serverId": { - "type": "string", - "description": "Required: the MCP server ID to delete" - } + type: 'object', + properties: { + serverId: { + type: 'string', + description: 'Required: the MCP server ID to delete', + }, }, - "required": [ - "serverId" - ] + required: ['serverId'], }, resultSchema: undefined, }, - ["deploy"]: { + deploy: { parameters: { - "properties": { - "request": { - "description": "Detailed deployment instructions. Include deployment type (api/chat) and ALL user-specified options: identifier, title, description, authType, password, allowedEmails, welcomeMessage, outputConfigs (block outputs to display).", - "type": "string" - } + properties: { + request: { + description: + 'Detailed deployment instructions. Include deployment type (api/chat) and ALL user-specified options: identifier, title, description, authType, password, allowedEmails, welcomeMessage, outputConfigs (block outputs to display).', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["deploy_api"]: { + deploy_api: { parameters: { - "type": "object", - "properties": { - "action": { - "type": "string", - "description": "Whether to deploy or undeploy the API endpoint", - "enum": [ - "deploy", - "undeploy" - ], - "default": "deploy" + type: 'object', + properties: { + action: { + type: 'string', + description: 'Whether to deploy or undeploy the API endpoint', + enum: ['deploy', 'undeploy'], + default: 'deploy', + }, + workflowId: { + type: 'string', + description: 'Workflow ID to deploy (required in workspace context)', }, - "workflowId": { - "type": "string", - "description": "Workflow ID to deploy (required in workspace context)" - } - } + }, }, resultSchema: { - "type": "object", - "properties": { - "apiEndpoint": { - "type": "string", - "description": "Canonical workflow execution endpoint." - }, - "baseUrl": { - "type": "string", - "description": "Base URL used to construct deployment URLs." - }, - "deployedAt": { - "type": "string", - "description": "Deployment timestamp when the workflow is deployed." - }, - "deploymentConfig": { - "type": "object", - "description": "Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details." - }, - "deploymentStatus": { - "type": "object", - "description": "Structured per-surface deployment status keyed by surface name, such as api." - }, - "deploymentType": { - "type": "string", - "description": "Deployment surface this result describes. For deploy_api and redeploy this is always \"api\"." - }, - "examples": { - "type": "object", - "description": "Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling." - }, - "isDeployed": { - "type": "boolean", - "description": "Whether the workflow API is currently deployed after this tool call." - }, - "version": { - "type": "number", - "description": "Deployment version for the current API deployment." - }, - "workflowId": { - "type": "string", - "description": "Workflow ID that was deployed or undeployed." - } - }, - "required": [ - "workflowId", - "isDeployed", - "deploymentType", - "deploymentStatus", - "deploymentConfig", - "examples" - ] - }, - }, - ["deploy_chat"]: { - parameters: { - "type": "object", - "properties": { - "action": { - "type": "string", - "description": "Whether to deploy or undeploy the chat interface", - "enum": [ - "deploy", - "undeploy" - ], - "default": "deploy" - }, - "allowedEmails": { - "type": "array", - "description": "List of allowed emails/domains for email or SSO auth", - "items": { - "type": "string" - } - }, - "authType": { - "type": "string", - "description": "Authentication type: public, password, email, or sso", - "enum": [ - "public", - "password", - "email", - "sso" - ], - "default": "public" - }, - "description": { - "type": "string", - "description": "Optional description for the chat" - }, - "identifier": { - "type": "string", - "description": "URL slug for the chat (lowercase letters, numbers, hyphens only)" - }, - "outputConfigs": { - "type": "array", - "description": "Output configurations specifying which block outputs to display in chat", - "items": { - "type": "object", - "properties": { - "blockId": { - "type": "string", - "description": "The block UUID" + type: 'object', + properties: { + apiEndpoint: { + type: 'string', + description: 'Canonical workflow execution endpoint.', + }, + baseUrl: { + type: 'string', + description: 'Base URL used to construct deployment URLs.', + }, + deployedAt: { + type: 'string', + description: 'Deployment timestamp when the workflow is deployed.', + }, + deploymentConfig: { + type: 'object', + description: + 'Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details.', + }, + deploymentStatus: { + type: 'object', + description: + 'Structured per-surface deployment status keyed by surface name, such as api.', + }, + deploymentType: { + type: 'string', + description: + 'Deployment surface this result describes. For deploy_api and redeploy this is always "api".', + }, + examples: { + type: 'object', + description: + 'Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling.', + }, + isDeployed: { + type: 'boolean', + description: 'Whether the workflow API is currently deployed after this tool call.', + }, + version: { + type: 'number', + description: 'Deployment version for the current API deployment.', + }, + workflowId: { + type: 'string', + description: 'Workflow ID that was deployed or undeployed.', + }, + }, + required: [ + 'workflowId', + 'isDeployed', + 'deploymentType', + 'deploymentStatus', + 'deploymentConfig', + 'examples', + ], + }, + }, + deploy_chat: { + parameters: { + type: 'object', + properties: { + action: { + type: 'string', + description: 'Whether to deploy or undeploy the chat interface', + enum: ['deploy', 'undeploy'], + default: 'deploy', + }, + allowedEmails: { + type: 'array', + description: 'List of allowed emails/domains for email or SSO auth', + items: { + type: 'string', + }, + }, + authType: { + type: 'string', + description: 'Authentication type: public, password, email, or sso', + enum: ['public', 'password', 'email', 'sso'], + default: 'public', + }, + description: { + type: 'string', + description: 'Optional description for the chat', + }, + identifier: { + type: 'string', + description: 'URL slug for the chat (lowercase letters, numbers, hyphens only)', + }, + outputConfigs: { + type: 'array', + description: 'Output configurations specifying which block outputs to display in chat', + items: { + type: 'object', + properties: { + blockId: { + type: 'string', + description: 'The block UUID', }, - "path": { - "type": "string", - "description": "The output path (e.g. 'response', 'response.content')" - } - }, - "required": [ - "blockId", - "path" - ] - } - }, - "password": { - "type": "string", - "description": "Password for password-protected chats" - }, - "title": { - "type": "string", - "description": "Display title for the chat interface" - }, - "welcomeMessage": { - "type": "string", - "description": "Welcome message shown to users" - }, - "workflowId": { - "type": "string", - "description": "Workflow ID to deploy (required in workspace context)" - } - } + path: { + type: 'string', + description: "The output path (e.g. 'response', 'response.content')", + }, + }, + required: ['blockId', 'path'], + }, + }, + password: { + type: 'string', + description: 'Password for password-protected chats', + }, + title: { + type: 'string', + description: 'Display title for the chat interface', + }, + welcomeMessage: { + type: 'string', + description: 'Welcome message shown to users', + }, + workflowId: { + type: 'string', + description: 'Workflow ID to deploy (required in workspace context)', + }, + }, }, resultSchema: { - "type": "object", - "properties": { - "action": { - "type": "string", - "description": "Action performed by the tool, such as \"deploy\" or \"undeploy\"." - }, - "apiEndpoint": { - "type": "string", - "description": "Paired workflow execution endpoint used by the chat deployment." - }, - "baseUrl": { - "type": "string", - "description": "Base URL used to construct deployment URLs." - }, - "chatUrl": { - "type": "string", - "description": "Shareable chat URL when the chat surface is deployed." - }, - "deployedAt": { - "type": "string", - "description": "Deployment timestamp for the underlying workflow deployment." - }, - "deploymentConfig": { - "type": "object", - "description": "Structured deployment configuration keyed by surface name. Includes chat settings and the paired API invocation configuration." - }, - "deploymentStatus": { - "type": "object", - "description": "Structured per-surface deployment status keyed by surface name, including api and chat." - }, - "deploymentType": { - "type": "string", - "description": "Deployment surface this result describes. For deploy_chat this is always \"chat\"." - }, - "examples": { - "type": "object", - "description": "Invocation examples keyed by surface name. Includes chat access details and API curl examples." - }, - "identifier": { - "type": "string", - "description": "Chat identifier or slug." - }, - "isChatDeployed": { - "type": "boolean", - "description": "Whether the chat surface is deployed after this tool call." - }, - "isDeployed": { - "type": "boolean", - "description": "Whether the paired API surface remains deployed after this tool call." - }, - "success": { - "type": "boolean", - "description": "Whether the deploy_chat action completed successfully." - }, - "version": { - "type": "number", - "description": "Deployment version for the underlying workflow deployment." - }, - "workflowId": { - "type": "string", - "description": "Workflow ID associated with the chat deployment." - } - }, - "required": [ - "workflowId", - "success", - "action", - "isDeployed", - "isChatDeployed", - "deploymentType", - "deploymentStatus", - "deploymentConfig", - "examples" - ] - }, - }, - ["deploy_mcp"]: { - parameters: { - "type": "object", - "properties": { - "parameterDescriptions": { - "type": "array", - "description": "Array of parameter descriptions for the tool", - "items": { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "Parameter description" + type: 'object', + properties: { + action: { + type: 'string', + description: 'Action performed by the tool, such as "deploy" or "undeploy".', + }, + apiEndpoint: { + type: 'string', + description: 'Paired workflow execution endpoint used by the chat deployment.', + }, + baseUrl: { + type: 'string', + description: 'Base URL used to construct deployment URLs.', + }, + chatUrl: { + type: 'string', + description: 'Shareable chat URL when the chat surface is deployed.', + }, + deployedAt: { + type: 'string', + description: 'Deployment timestamp for the underlying workflow deployment.', + }, + deploymentConfig: { + type: 'object', + description: + 'Structured deployment configuration keyed by surface name. Includes chat settings and the paired API invocation configuration.', + }, + deploymentStatus: { + type: 'object', + description: + 'Structured per-surface deployment status keyed by surface name, including api and chat.', + }, + deploymentType: { + type: 'string', + description: + 'Deployment surface this result describes. For deploy_chat this is always "chat".', + }, + examples: { + type: 'object', + description: + 'Invocation examples keyed by surface name. Includes chat access details and API curl examples.', + }, + identifier: { + type: 'string', + description: 'Chat identifier or slug.', + }, + isChatDeployed: { + type: 'boolean', + description: 'Whether the chat surface is deployed after this tool call.', + }, + isDeployed: { + type: 'boolean', + description: 'Whether the paired API surface remains deployed after this tool call.', + }, + success: { + type: 'boolean', + description: 'Whether the deploy_chat action completed successfully.', + }, + version: { + type: 'number', + description: 'Deployment version for the underlying workflow deployment.', + }, + workflowId: { + type: 'string', + description: 'Workflow ID associated with the chat deployment.', + }, + }, + required: [ + 'workflowId', + 'success', + 'action', + 'isDeployed', + 'isChatDeployed', + 'deploymentType', + 'deploymentStatus', + 'deploymentConfig', + 'examples', + ], + }, + }, + deploy_mcp: { + parameters: { + type: 'object', + properties: { + parameterDescriptions: { + type: 'array', + description: 'Array of parameter descriptions for the tool', + items: { + type: 'object', + properties: { + description: { + type: 'string', + description: 'Parameter description', }, - "name": { - "type": "string", - "description": "Parameter name" - } - }, - "required": [ - "name", - "description" - ] - } - }, - "serverId": { - "type": "string", - "description": "Required: server ID from list_workspace_mcp_servers" - }, - "toolDescription": { - "type": "string", - "description": "Description for the MCP tool" - }, - "toolName": { - "type": "string", - "description": "Name for the MCP tool (defaults to workflow name)" - }, - "workflowId": { - "type": "string", - "description": "Workflow ID (defaults to active workflow)" - } - }, - "required": [ - "serverId" - ] + name: { + type: 'string', + description: 'Parameter name', + }, + }, + required: ['name', 'description'], + }, + }, + serverId: { + type: 'string', + description: 'Required: server ID from list_workspace_mcp_servers', + }, + toolDescription: { + type: 'string', + description: 'Description for the MCP tool', + }, + toolName: { + type: 'string', + description: 'Name for the MCP tool (defaults to workflow name)', + }, + workflowId: { + type: 'string', + description: 'Workflow ID (defaults to active workflow)', + }, + }, + required: ['serverId'], }, resultSchema: { - "type": "object", - "properties": { - "action": { - "type": "string", - "description": "Action performed by the tool, such as \"deploy\" or \"undeploy\"." + type: 'object', + properties: { + action: { + type: 'string', + description: 'Action performed by the tool, such as "deploy" or "undeploy".', + }, + apiEndpoint: { + type: 'string', + description: 'Underlying workflow API endpoint associated with the MCP tool.', }, - "apiEndpoint": { - "type": "string", - "description": "Underlying workflow API endpoint associated with the MCP tool." + baseUrl: { + type: 'string', + description: 'Base URL used to construct deployment URLs.', }, - "baseUrl": { - "type": "string", - "description": "Base URL used to construct deployment URLs." + deploymentConfig: { + type: 'object', + description: + 'Structured deployment configuration keyed by surface name. Includes MCP server, tool, auth, and parameter schema details.', }, - "deploymentConfig": { - "type": "object", - "description": "Structured deployment configuration keyed by surface name. Includes MCP server, tool, auth, and parameter schema details." + deploymentStatus: { + type: 'object', + description: + 'Structured per-surface deployment status keyed by surface name, including mcp and the underlying api surface when applicable.', }, - "deploymentStatus": { - "type": "object", - "description": "Structured per-surface deployment status keyed by surface name, including mcp and the underlying api surface when applicable." + deploymentType: { + type: 'string', + description: + 'Deployment surface this result describes. For deploy_mcp this is always "mcp".', }, - "deploymentType": { - "type": "string", - "description": "Deployment surface this result describes. For deploy_mcp this is always \"mcp\"." + examples: { + type: 'object', + description: + 'Setup examples keyed by surface name. Includes ready-to-paste config snippets for supported MCP clients.', }, - "examples": { - "type": "object", - "description": "Setup examples keyed by surface name. Includes ready-to-paste config snippets for supported MCP clients." + mcpServerUrl: { + type: 'string', + description: 'HTTP MCP server URL to configure in clients.', }, - "mcpServerUrl": { - "type": "string", - "description": "HTTP MCP server URL to configure in clients." + removed: { + type: 'boolean', + description: 'Whether the MCP deployment was removed during an undeploy action.', }, - "removed": { - "type": "boolean", - "description": "Whether the MCP deployment was removed during an undeploy action." + serverId: { + type: 'string', + description: 'Workspace MCP server ID.', }, - "serverId": { - "type": "string", - "description": "Workspace MCP server ID." + serverName: { + type: 'string', + description: 'Workspace MCP server name.', }, - "serverName": { - "type": "string", - "description": "Workspace MCP server name." + toolDescription: { + type: 'string', + description: 'MCP tool description exposed on the server.', }, - "toolDescription": { - "type": "string", - "description": "MCP tool description exposed on the server." + toolId: { + type: 'string', + description: 'MCP tool ID when deployed.', }, - "toolId": { - "type": "string", - "description": "MCP tool ID when deployed." + toolName: { + type: 'string', + description: 'MCP tool name exposed on the server.', }, - "toolName": { - "type": "string", - "description": "MCP tool name exposed on the server." + updated: { + type: 'boolean', + description: 'Whether an existing MCP tool deployment was updated instead of created.', }, - "updated": { - "type": "boolean", - "description": "Whether an existing MCP tool deployment was updated instead of created." + workflowId: { + type: 'string', + description: 'Workflow ID associated with the MCP deployment.', }, - "workflowId": { - "type": "string", - "description": "Workflow ID associated with the MCP deployment." - } }, - "required": [ - "deploymentType", - "deploymentStatus" - ] + required: ['deploymentType', 'deploymentStatus'], }, }, - ["download_to_workspace_file"]: { + download_to_workspace_file: { parameters: { - "type": "object", - "properties": { - "fileName": { - "type": "string", - "description": "Optional workspace file name to save as. If omitted, the name is inferred from the response or URL." + type: 'object', + properties: { + fileName: { + type: 'string', + description: + 'Optional workspace file name to save as. If omitted, the name is inferred from the response or URL.', + }, + url: { + type: 'string', + description: + 'Direct URL of the file to download, such as an image CDN URL ending in .png or .jpg', }, - "url": { - "type": "string", - "description": "Direct URL of the file to download, such as an image CDN URL ending in .png or .jpg" - } }, - "required": [ - "url" - ] + required: ['url'], }, resultSchema: undefined, }, - ["edit_content"]: { + edit_content: { parameters: { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "The text content to write. For append: text to append. For update: full replacement text. For patch with search_replace: the replacement text. For patch with anchored: the insert/replacement text." - } + type: 'object', + properties: { + content: { + type: 'string', + description: + 'The text content to write. For append: text to append. For update: full replacement text. For patch with search_replace: the replacement text. For patch with anchored: the insert/replacement text.', + }, }, - "required": [ - "content" - ] + required: ['content'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Optional operation metadata such as file id, file name, size, and content type." - }, - "message": { - "type": "string", - "description": "Human-readable summary of the outcome." - }, - "success": { - "type": "boolean", - "description": "Whether the content was applied successfully." - } - }, - "required": [ - "success", - "message" - ] - }, - }, - ["edit_workflow"]: { - parameters: { - "type": "object", - "properties": { - "operations": { - "type": "array", - "description": "Array of edit operations", - "items": { - "type": "object", - "properties": { - "block_id": { - "type": "string", - "description": "Block ID for the operation. For add operations, this will be the desired ID for the new block." + type: 'object', + properties: { + data: { + type: 'object', + description: + 'Optional operation metadata such as file id, file name, size, and content type.', + }, + message: { + type: 'string', + description: 'Human-readable summary of the outcome.', + }, + success: { + type: 'boolean', + description: 'Whether the content was applied successfully.', + }, + }, + required: ['success', 'message'], + }, + }, + edit_workflow: { + parameters: { + type: 'object', + properties: { + operations: { + type: 'array', + description: 'Array of edit operations', + items: { + type: 'object', + properties: { + block_id: { + type: 'string', + description: + 'Block ID for the operation. For add operations, this will be the desired ID for the new block.', + }, + operation_type: { + type: 'string', + description: 'Type of operation to perform', + enum: ['add', 'edit', 'delete', 'insert_into_subflow', 'extract_from_subflow'], }, - "operation_type": { - "type": "string", - "description": "Type of operation to perform", - "enum": [ - "add", - "edit", - "delete", - "insert_into_subflow", - "extract_from_subflow" - ] + params: { + type: 'object', + description: + 'Parameters for the operation. \nFor edit: {"inputs": {"temperature": 0.5}} NOT {"subBlocks": {"temperature": {"value": 0.5}}}\nFor add: {"type": "agent", "name": "My Agent", "inputs": {"model": "claude-sonnet-4-6"}}\nFor delete: {} (empty object)', }, - "params": { - "type": "object", - "description": "Parameters for the operation. \nFor edit: {\"inputs\": {\"temperature\": 0.5}} NOT {\"subBlocks\": {\"temperature\": {\"value\": 0.5}}}\nFor add: {\"type\": \"agent\", \"name\": \"My Agent\", \"inputs\": {\"model\": \"claude-sonnet-4-6\"}}\nFor delete: {} (empty object)" - } - }, - "required": [ - "operation_type", - "block_id", - "params" - ] - } + }, + required: ['operation_type', 'block_id', 'params'], + }, + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID to edit. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to edit. If not provided, uses the current workflow in context." - } }, - "required": [ - "operations" - ] + required: ['operations'], }, resultSchema: undefined, }, - ["file"]: { - parameters: { - "type": "object" - }, - resultSchema: undefined, - }, - ["function_execute"]: { - parameters: { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "Code to execute. For JS: raw statements auto-wrapped in async context. For Python: full script. For shell: bash script with access to pre-installed CLI tools and workspace env vars as $VAR_NAME." - }, - "inputFiles": { - "type": "array", - "description": "Canonical workspace file IDs to mount in the sandbox. Discover IDs via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\"). Mounted path: /home/user/files/{fileId}/{originalName}. Example: [\"wf_123\"]", - "items": { - "type": "string" - } - }, - "inputTables": { - "type": "array", - "description": "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Example: [\"tbl_abc123\"]", - "items": { - "type": "string" - } - }, - "language": { - "type": "string", - "description": "Execution language.", - "enum": [ - "javascript", - "python", - "shell" - ] - }, - "outputFormat": { - "type": "string", - "description": "Format for outputPath. Determines how the code result is serialized. If omitted, inferred from outputPath file extension.", - "enum": [ - "json", - "csv", - "txt", - "md", - "html" - ] - }, - "outputMimeType": { - "type": "string", - "description": "MIME type for outputSandboxPath export. Required for binary files: image/png, image/jpeg, application/pdf, etc. Omit for text files." - }, - "outputPath": { - "type": "string", - "description": "Pipe output directly to a NEW workspace file instead of returning in context. ALWAYS use this instead of a separate workspace_file write call. Use a flat path like \"files/result.json\" — nested paths are not supported." - }, - "outputSandboxPath": { - "type": "string", - "description": "Path to a file created inside the sandbox that should be exported to the workspace. Use together with outputPath." - }, - "outputTable": { - "type": "string", - "description": "Table ID to overwrite with the code's return value. Code MUST return an array of objects where keys match column names. All existing rows are replaced. Example: \"tbl_abc123\"" - } - }, - "required": [ - "code" - ] - }, + file: { + parameters: { + type: 'object', + }, resultSchema: undefined, }, - ["generate_api_key"]: { - parameters: { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "A descriptive name for the API key (e.g., 'production-key', 'dev-testing')." - }, - "workspaceId": { - "type": "string", - "description": "Optional workspace ID. Defaults to user's default workspace." - } - }, - "required": [ - "name" - ] + function_execute: { + parameters: { + type: 'object', + properties: { + code: { + type: 'string', + description: + 'Code to execute. For JS: raw statements auto-wrapped in async context. For Python: full script. For shell: bash script with access to pre-installed CLI tools and workspace env vars as $VAR_NAME.', + }, + inputFiles: { + type: 'array', + description: + 'Canonical workspace file IDs to mount in the sandbox. Discover IDs via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json"). Mounted path: /home/user/files/{fileId}/{originalName}. Example: ["wf_123"]', + items: { + type: 'string', + }, + }, + inputTables: { + type: 'array', + description: + 'Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Example: ["tbl_abc123"]', + items: { + type: 'string', + }, + }, + language: { + type: 'string', + description: 'Execution language.', + enum: ['javascript', 'python', 'shell'], + }, + outputFormat: { + type: 'string', + description: + 'Format for outputPath. Determines how the code result is serialized. If omitted, inferred from outputPath file extension.', + enum: ['json', 'csv', 'txt', 'md', 'html'], + }, + outputMimeType: { + type: 'string', + description: + 'MIME type for outputSandboxPath export. Required for binary files: image/png, image/jpeg, application/pdf, etc. Omit for text files.', + }, + outputPath: { + type: 'string', + description: + 'Pipe output directly to a NEW workspace file instead of returning in context. ALWAYS use this instead of a separate workspace_file write call. Use a flat path like "files/result.json" — nested paths are not supported.', + }, + outputSandboxPath: { + type: 'string', + description: + 'Path to a file created inside the sandbox that should be exported to the workspace. Use together with outputPath.', + }, + outputTable: { + type: 'string', + description: + 'Table ID to overwrite with the code\'s return value. Code MUST return an array of objects where keys match column names. All existing rows are replaced. Example: "tbl_abc123"', + }, + }, + required: ['code'], }, resultSchema: undefined, }, - ["generate_image"]: { + generate_api_key: { parameters: { - "type": "object", - "properties": { - "aspectRatio": { - "type": "string", - "description": "Aspect ratio for the generated image.", - "enum": [ - "1:1", - "16:9", - "9:16", - "4:3", - "3:4" - ] - }, - "fileName": { - "type": "string", - "description": "Output file name. Defaults to \"generated-image.png\". Workspace files are flat, so pass a plain file name, not a nested path." - }, - "overwriteFileId": { - "type": "string", - "description": "If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated image so the existing chat resource stays current instead of creating a duplicate like \"image (1).png\". The file ID is returned by previous generate_image or generate_visualization calls (fileId field), or can be found via read(\"files/by-id/{fileId}/meta.json\")." - }, - "prompt": { - "type": "string", - "description": "Detailed text description of the image to generate, or editing instructions when used with editFileId." - }, - "referenceFileIds": { - "type": "array", - "description": "File IDs of workspace images to include as context for the generation. All images are sent alongside the prompt. Use for: editing a single image (1 file), compositing multiple images together (2+ files), style transfer, face swapping, etc. Order matters — list the primary/base image first. When revising an existing image in place, pair the primary file ID here with overwriteFileId set to that same ID.", - "items": { - "type": "string" - } - } + type: 'object', + properties: { + name: { + type: 'string', + description: + "A descriptive name for the API key (e.g., 'production-key', 'dev-testing').", + }, + workspaceId: { + type: 'string', + description: "Optional workspace ID. Defaults to user's default workspace.", + }, }, - "required": [ - "prompt" - ] + required: ['name'], }, resultSchema: undefined, }, - ["generate_visualization"]: { + generate_image: { parameters: { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "Python code that generates a visualization using matplotlib. MUST call plt.savefig('/home/user/output.png', dpi=150, bbox_inches='tight') to produce output." + type: 'object', + properties: { + aspectRatio: { + type: 'string', + description: 'Aspect ratio for the generated image.', + enum: ['1:1', '16:9', '9:16', '4:3', '3:4'], + }, + fileName: { + type: 'string', + description: + 'Output file name. Defaults to "generated-image.png". Workspace files are flat, so pass a plain file name, not a nested path.', }, - "fileName": { - "type": "string", - "description": "Output file name. Defaults to \"chart.png\". Workspace files are flat, so pass a plain file name, not a nested path." + overwriteFileId: { + type: 'string', + description: + 'If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated image so the existing chat resource stays current instead of creating a duplicate like "image (1).png". The file ID is returned by previous generate_image or generate_visualization calls (fileId field), or can be found via read("files/by-id/{fileId}/meta.json").', }, - "inputFiles": { - "type": "array", - "description": "Canonical workspace file IDs to mount in the sandbox. Discover IDs via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\"). Mounted path: /home/user/files/{fileId}/{originalName}.", - "items": { - "type": "string" - } + prompt: { + type: 'string', + description: + 'Detailed text description of the image to generate, or editing instructions when used with editFileId.', }, - "inputTables": { - "type": "array", - "description": "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Read with pandas: pd.read_csv('/home/user/tables/tbl_xxx.csv')", - "items": { - "type": "string" - } + referenceFileIds: { + type: 'array', + description: + 'File IDs of workspace images to include as context for the generation. All images are sent alongside the prompt. Use for: editing a single image (1 file), compositing multiple images together (2+ files), style transfer, face swapping, etc. Order matters — list the primary/base image first. When revising an existing image in place, pair the primary file ID here with overwriteFileId set to that same ID.', + items: { + type: 'string', + }, }, - "overwriteFileId": { - "type": "string", - "description": "If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated chart so the existing chat resource stays current instead of creating a duplicate like \"chart (1).png\". The file ID is returned by previous generate_visualization or generate_image calls (fileId field), or can be found via read(\"files/by-id/{fileId}/meta.json\")." - } }, - "required": [ - "code" - ] + required: ['prompt'], }, resultSchema: undefined, }, - ["get_block_outputs"]: { + generate_visualization: { parameters: { - "type": "object", - "properties": { - "blockIds": { - "type": "array", - "description": "Optional array of block UUIDs. If provided, returns outputs only for those blocks. If not provided, returns outputs for all blocks in the workflow.", - "items": { - "type": "string" - } + type: 'object', + properties: { + code: { + type: 'string', + description: + "Python code that generates a visualization using matplotlib. MUST call plt.savefig('/home/user/output.png', dpi=150, bbox_inches='tight') to produce output.", + }, + fileName: { + type: 'string', + description: + 'Output file name. Defaults to "chart.png". Workspace files are flat, so pass a plain file name, not a nested path.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } - } + inputFiles: { + type: 'array', + description: + 'Canonical workspace file IDs to mount in the sandbox. Discover IDs via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json"). Mounted path: /home/user/files/{fileId}/{originalName}.', + items: { + type: 'string', + }, + }, + inputTables: { + type: 'array', + description: + "Table IDs to mount as CSV files in the sandbox. Each table appears at /home/user/tables/{tableId}.csv with a header row. Read with pandas: pd.read_csv('/home/user/tables/tbl_xxx.csv')", + items: { + type: 'string', + }, + }, + overwriteFileId: { + type: 'string', + description: + 'If provided, overwrites the existing workspace file with this ID instead of creating a new file. Use this when the user asks to update, refine, or redo a previously generated chart so the existing chat resource stays current instead of creating a duplicate like "chart (1).png". The file ID is returned by previous generate_visualization or generate_image calls (fileId field), or can be found via read("files/by-id/{fileId}/meta.json").', + }, + }, + required: ['code'], }, resultSchema: undefined, }, - ["get_block_upstream_references"]: { + get_block_outputs: { parameters: { - "type": "object", - "properties": { - "blockIds": { - "type": "array", - "description": "Required array of block UUIDs (minimum 1). Returns what each block can reference based on its position in the workflow graph.", - "items": { - "type": "string" - } + type: 'object', + properties: { + blockIds: { + type: 'array', + description: + 'Optional array of block UUIDs. If provided, returns outputs only for those blocks. If not provided, returns outputs for all blocks in the workflow.', + items: { + type: 'string', + }, + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', + }, + }, + }, + resultSchema: undefined, + }, + get_block_upstream_references: { + parameters: { + type: 'object', + properties: { + blockIds: { + type: 'array', + description: + 'Required array of block UUIDs (minimum 1). Returns what each block can reference based on its position in the workflow graph.', + items: { + type: 'string', + }, + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } }, - "required": [ - "blockIds" - ] + required: ['blockIds'], }, resultSchema: undefined, }, - ["get_deployed_workflow_state"]: { + get_deployed_workflow_state: { parameters: { - "type": "object", - "properties": { - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } - } + type: 'object', + properties: { + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', + }, + }, }, resultSchema: undefined, }, - ["get_deployment_version"]: { + get_deployment_version: { parameters: { - "type": "object", - "properties": { - "version": { - "type": "number", - "description": "The deployment version number" + type: 'object', + properties: { + version: { + type: 'number', + description: 'The deployment version number', + }, + workflowId: { + type: 'string', + description: 'The workflow ID', }, - "workflowId": { - "type": "string", - "description": "The workflow ID" - } }, - "required": [ - "workflowId", - "version" - ] + required: ['workflowId', 'version'], }, resultSchema: undefined, }, - ["get_execution_summary"]: { + get_execution_summary: { parameters: { - "type": "object", - "properties": { - "limit": { - "type": "number", - "description": "Max number of executions to return (default: 10, max: 20)." + type: 'object', + properties: { + limit: { + type: 'number', + description: 'Max number of executions to return (default: 10, max: 20).', }, - "status": { - "type": "string", - "description": "Filter by status: 'success', 'error', or 'all' (default: 'all').", - "enum": [ - "success", - "error", - "all" - ] + status: { + type: 'string', + description: "Filter by status: 'success', 'error', or 'all' (default: 'all').", + enum: ['success', 'error', 'all'], }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If omitted, returns executions across all workflows in the workspace." + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If omitted, returns executions across all workflows in the workspace.', + }, + workspaceId: { + type: 'string', + description: 'Workspace ID to scope executions to.', }, - "workspaceId": { - "type": "string", - "description": "Workspace ID to scope executions to." - } }, - "required": [ - "workspaceId" - ] + required: ['workspaceId'], }, resultSchema: undefined, }, - ["get_job_logs"]: { + get_job_logs: { parameters: { - "type": "object", - "properties": { - "executionId": { - "type": "string", - "description": "Optional execution ID for a specific run." + type: 'object', + properties: { + executionId: { + type: 'string', + description: 'Optional execution ID for a specific run.', + }, + includeDetails: { + type: 'boolean', + description: 'Include tool calls, outputs, and cost details.', }, - "includeDetails": { - "type": "boolean", - "description": "Include tool calls, outputs, and cost details." + jobId: { + type: 'string', + description: 'The job (schedule) ID to get logs for.', }, - "jobId": { - "type": "string", - "description": "The job (schedule) ID to get logs for." + limit: { + type: 'number', + description: 'Max number of entries (default: 3, max: 5)', }, - "limit": { - "type": "number", - "description": "Max number of entries (default: 3, max: 5)" - } }, - "required": [ - "jobId" - ] + required: ['jobId'], }, resultSchema: undefined, }, - ["get_page_contents"]: { + get_page_contents: { parameters: { - "type": "object", - "properties": { - "include_highlights": { - "type": "boolean", - "description": "Include key highlights (default false)" + type: 'object', + properties: { + include_highlights: { + type: 'boolean', + description: 'Include key highlights (default false)', }, - "include_summary": { - "type": "boolean", - "description": "Include AI-generated summary (default false)" + include_summary: { + type: 'boolean', + description: 'Include AI-generated summary (default false)', }, - "include_text": { - "type": "boolean", - "description": "Include full page text (default true)" + include_text: { + type: 'boolean', + description: 'Include full page text (default true)', + }, + urls: { + type: 'array', + description: 'URLs to get content from (max 10)', + items: { + type: 'string', + }, }, - "urls": { - "type": "array", - "description": "URLs to get content from (max 10)", - "items": { - "type": "string" - } - } }, - "required": [ - "urls" - ] + required: ['urls'], }, resultSchema: undefined, }, - ["get_platform_actions"]: { + get_platform_actions: { parameters: { - "type": "object", - "properties": {} + type: 'object', + properties: {}, }, resultSchema: undefined, }, - ["get_workflow_data"]: { + get_workflow_data: { parameters: { - "type": "object", - "properties": { - "data_type": { - "type": "string", - "description": "The type of workflow data to retrieve", - "enum": [ - "global_variables", - "custom_tools", - "mcp_tools", - "files" - ] + type: 'object', + properties: { + data_type: { + type: 'string', + description: 'The type of workflow data to retrieve', + enum: ['global_variables', 'custom_tools', 'mcp_tools', 'files'], + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } }, - "required": [ - "data_type" - ] + required: ['data_type'], }, resultSchema: undefined, }, - ["get_workflow_logs"]: { + get_workflow_logs: { parameters: { - "type": "object", - "properties": { - "executionId": { - "type": "string", - "description": "Optional execution ID to get logs for a specific execution. Use with get_execution_summary to find execution IDs first." + type: 'object', + properties: { + executionId: { + type: 'string', + description: + 'Optional execution ID to get logs for a specific execution. Use with get_execution_summary to find execution IDs first.', + }, + includeDetails: { + type: 'boolean', + description: 'Include detailed info', }, - "includeDetails": { - "type": "boolean", - "description": "Include detailed info" + limit: { + type: 'number', + description: 'Max number of entries (hard limit: 3)', }, - "limit": { - "type": "number", - "description": "Max number of entries (hard limit: 3)" + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } - } + }, }, resultSchema: undefined, }, - ["glob"]: { + glob: { parameters: { - "type": "object", - "properties": { - "pattern": { - "type": "string", - "description": "Glob pattern to match file paths. Supports * (any segment) and ** (any depth)." + type: 'object', + properties: { + pattern: { + type: 'string', + description: + 'Glob pattern to match file paths. Supports * (any segment) and ** (any depth).', + }, + toolTitle: { + type: 'string', + description: + 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "workflow configs" or "knowledge bases", not a full sentence like "Finding workflow configs".', }, - "toolTitle": { - "type": "string", - "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"workflow configs\" or \"knowledge bases\", not a full sentence like \"Finding workflow configs\"." - } }, - "required": [ - "pattern", - "toolTitle" - ] + required: ['pattern', 'toolTitle'], }, resultSchema: undefined, }, - ["grep"]: { + grep: { parameters: { - "type": "object", - "properties": { - "context": { - "type": "number", - "description": "Number of lines to show before and after each match. Only applies to output_mode 'content'." + type: 'object', + properties: { + context: { + type: 'number', + description: + "Number of lines to show before and after each match. Only applies to output_mode 'content'.", }, - "ignoreCase": { - "type": "boolean", - "description": "Case insensitive search (default false)." + ignoreCase: { + type: 'boolean', + description: 'Case insensitive search (default false).', }, - "lineNumbers": { - "type": "boolean", - "description": "Include line numbers in output (default true). Only applies to output_mode 'content'." + lineNumbers: { + type: 'boolean', + description: + "Include line numbers in output (default true). Only applies to output_mode 'content'.", }, - "maxResults": { - "type": "number", - "description": "Maximum number of matches to return (default 50)." + maxResults: { + type: 'number', + description: 'Maximum number of matches to return (default 50).', }, - "output_mode": { - "type": "string", - "description": "Output mode: 'content' shows matching lines (default), 'files_with_matches' shows only file paths, 'count' shows match counts per file.", - "enum": [ - "content", - "files_with_matches", - "count" - ] + output_mode: { + type: 'string', + description: + "Output mode: 'content' shows matching lines (default), 'files_with_matches' shows only file paths, 'count' shows match counts per file.", + enum: ['content', 'files_with_matches', 'count'], }, - "path": { - "type": "string", - "description": "Optional path prefix to scope the search (e.g. 'workflows/', 'environment/', 'internal/', 'components/blocks/')." + path: { + type: 'string', + description: + "Optional path prefix to scope the search (e.g. 'workflows/', 'environment/', 'internal/', 'components/blocks/').", }, - "pattern": { - "type": "string", - "description": "Regex pattern to search for in file contents." + pattern: { + type: 'string', + description: 'Regex pattern to search for in file contents.', + }, + toolTitle: { + type: 'string', + description: + 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "Slack integrations" or "deployed workflows", not a full sentence like "Searching for Slack integrations".', }, - "toolTitle": { - "type": "string", - "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"Slack integrations\" or \"deployed workflows\", not a full sentence like \"Searching for Slack integrations\"." - } }, - "required": [ - "pattern", - "toolTitle" - ] + required: ['pattern', 'toolTitle'], }, resultSchema: undefined, }, - ["job"]: { + job: { parameters: { - "properties": { - "request": { - "description": "What job action is needed.", - "type": "string" - } + properties: { + request: { + description: 'What job action is needed.', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["knowledge"]: { + knowledge: { parameters: { - "properties": { - "request": { - "description": "What knowledge base action is needed.", - "type": "string" - } + properties: { + request: { + description: 'What knowledge base action is needed.', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" - }, - resultSchema: undefined, - }, - ["knowledge_base"]: { - parameters: { - "type": "object", - "properties": { - "args": { - "type": "object", - "description": "Arguments for the operation", - "properties": { - "apiKey": { - "type": "string", - "description": "API key for API-key-based connectors (required when connector auth mode is apiKey)" - }, - "chunkingConfig": { - "type": "object", - "description": "Chunking configuration (optional for 'create')", - "properties": { - "maxSize": { - "type": "number", - "description": "Maximum chunk size (100-4000, default: 1024)", - "default": 1024 + required: ['request'], + type: 'object', + }, + resultSchema: undefined, + }, + knowledge_base: { + parameters: { + type: 'object', + properties: { + args: { + type: 'object', + description: 'Arguments for the operation', + properties: { + apiKey: { + type: 'string', + description: + 'API key for API-key-based connectors (required when connector auth mode is apiKey)', + }, + chunkingConfig: { + type: 'object', + description: "Chunking configuration (optional for 'create')", + properties: { + maxSize: { + type: 'number', + description: 'Maximum chunk size (100-4000, default: 1024)', + default: 1024, }, - "minSize": { - "type": "number", - "description": "Minimum chunk size (1-2000, default: 1)", - "default": 1 + minSize: { + type: 'number', + description: 'Minimum chunk size (1-2000, default: 1)', + default: 1, }, - "overlap": { - "type": "number", - "description": "Overlap between chunks (0-500, default: 200)", - "default": 200 - } - } - }, - "connectorId": { - "type": "string", - "description": "Connector ID (required for update_connector, delete_connector, sync_connector)" - }, - "connectorStatus": { - "type": "string", - "description": "Connector status (optional for update_connector)", - "enum": [ - "active", - "paused" - ] - }, - "connectorType": { - "type": "string", - "description": "Connector type from registry, e.g. 'confluence', 'google_drive', 'notion' (required for add_connector). Read knowledgebases/connectors/{type}.json for the config schema." - }, - "credentialId": { - "type": "string", - "description": "OAuth credential ID from environment/credentials.json (required for OAuth connectors)" - }, - "description": { - "type": "string", - "description": "Description of the knowledge base (optional for 'create')" - }, - "disabledTagIds": { - "type": "array", - "description": "Tag definition IDs to opt out of (optional for add_connector). See tagDefinitions in the connector schema." - }, - "documentId": { - "type": "string", - "description": "Document ID (required for update_document)" - }, - "documentIds": { - "type": "array", - "description": "Document IDs (for batch delete_document)", - "items": { - "type": "string" - } - }, - "enabled": { - "type": "boolean", - "description": "Enable/disable a document (optional for update_document)" - }, - "fileIds": { - "type": "array", - "description": "Canonical workspace file IDs to add as documents (for add_file). Discover via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\").", - "items": { - "type": "string" - } - }, - "filename": { - "type": "string", - "description": "New filename for a document (optional for update_document)" - }, - "knowledgeBaseId": { - "type": "string", - "description": "Knowledge base ID (required for get, query, add_file, list_tags, create_tag, get_tag_usage)" - }, - "knowledgeBaseIds": { - "type": "array", - "description": "Knowledge base IDs (for batch delete)", - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "description": "Name of the knowledge base (required for 'create')" - }, - "query": { - "type": "string", - "description": "Search query text (required for 'query')" - }, - "sourceConfig": { - "type": "object", - "description": "Connector-specific configuration matching the configFields in knowledgebases/connectors/{type}.json" - }, - "syncIntervalMinutes": { - "type": "number", - "description": "Sync interval in minutes: 60 (hourly), 360 (6h), 1440 (daily), 10080 (weekly), 0 (manual only). Default: 1440", - "default": 1440 - }, - "tagDefinitionId": { - "type": "string", - "description": "Tag definition ID (required for update_tag, delete_tag)" - }, - "tagDisplayName": { - "type": "string", - "description": "Display name for the tag (required for create_tag, optional for update_tag)" - }, - "tagFieldType": { - "type": "string", - "description": "Field type: text, number, date, boolean (optional for create_tag, defaults to text)", - "enum": [ - "text", - "number", - "date", - "boolean" - ] - }, - "topK": { - "type": "number", - "description": "Number of results to return (1-50, default: 5)", - "default": 5 - }, - "workspaceId": { - "type": "string", - "description": "Workspace ID (required for 'create', optional filter for 'list')" - } - } - }, - "operation": { - "type": "string", - "description": "The operation to perform", - "enum": [ - "create", - "get", - "query", - "add_file", - "update", - "delete", - "delete_document", - "update_document", - "list_tags", - "create_tag", - "update_tag", - "delete_tag", - "get_tag_usage", - "add_connector", - "update_connector", - "delete_connector", - "sync_connector" - ] - } - }, - "required": [ - "operation", - "args" - ] + overlap: { + type: 'number', + description: 'Overlap between chunks (0-500, default: 200)', + default: 200, + }, + }, + }, + connectorId: { + type: 'string', + description: + 'Connector ID (required for update_connector, delete_connector, sync_connector)', + }, + connectorStatus: { + type: 'string', + description: 'Connector status (optional for update_connector)', + enum: ['active', 'paused'], + }, + connectorType: { + type: 'string', + description: + "Connector type from registry, e.g. 'confluence', 'google_drive', 'notion' (required for add_connector). Read knowledgebases/connectors/{type}.json for the config schema.", + }, + credentialId: { + type: 'string', + description: + 'OAuth credential ID from environment/credentials.json (required for OAuth connectors)', + }, + description: { + type: 'string', + description: "Description of the knowledge base (optional for 'create')", + }, + disabledTagIds: { + type: 'array', + description: + 'Tag definition IDs to opt out of (optional for add_connector). See tagDefinitions in the connector schema.', + }, + documentId: { + type: 'string', + description: 'Document ID (required for update_document)', + }, + documentIds: { + type: 'array', + description: 'Document IDs (for batch delete_document)', + items: { + type: 'string', + }, + }, + enabled: { + type: 'boolean', + description: 'Enable/disable a document (optional for update_document)', + }, + fileIds: { + type: 'array', + description: + 'Canonical workspace file IDs to add as documents (for add_file). Discover via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json").', + items: { + type: 'string', + }, + }, + filename: { + type: 'string', + description: 'New filename for a document (optional for update_document)', + }, + knowledgeBaseId: { + type: 'string', + description: + 'Knowledge base ID (required for get, query, add_file, list_tags, create_tag, get_tag_usage)', + }, + knowledgeBaseIds: { + type: 'array', + description: 'Knowledge base IDs (for batch delete)', + items: { + type: 'string', + }, + }, + name: { + type: 'string', + description: "Name of the knowledge base (required for 'create')", + }, + query: { + type: 'string', + description: "Search query text (required for 'query')", + }, + sourceConfig: { + type: 'object', + description: + 'Connector-specific configuration matching the configFields in knowledgebases/connectors/{type}.json', + }, + syncIntervalMinutes: { + type: 'number', + description: + 'Sync interval in minutes: 60 (hourly), 360 (6h), 1440 (daily), 10080 (weekly), 0 (manual only). Default: 1440', + default: 1440, + }, + tagDefinitionId: { + type: 'string', + description: 'Tag definition ID (required for update_tag, delete_tag)', + }, + tagDisplayName: { + type: 'string', + description: + 'Display name for the tag (required for create_tag, optional for update_tag)', + }, + tagFieldType: { + type: 'string', + description: + 'Field type: text, number, date, boolean (optional for create_tag, defaults to text)', + enum: ['text', 'number', 'date', 'boolean'], + }, + topK: { + type: 'number', + description: 'Number of results to return (1-50, default: 5)', + default: 5, + }, + workspaceId: { + type: 'string', + description: "Workspace ID (required for 'create', optional filter for 'list')", + }, + }, + }, + operation: { + type: 'string', + description: 'The operation to perform', + enum: [ + 'create', + 'get', + 'query', + 'add_file', + 'update', + 'delete', + 'delete_document', + 'update_document', + 'list_tags', + 'create_tag', + 'update_tag', + 'delete_tag', + 'get_tag_usage', + 'add_connector', + 'update_connector', + 'delete_connector', + 'sync_connector', + ], + }, + }, + required: ['operation', 'args'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Operation-specific result payload." + type: 'object', + properties: { + data: { + type: 'object', + description: 'Operation-specific result payload.', + }, + message: { + type: 'string', + description: 'Human-readable outcome summary.', }, - "message": { - "type": "string", - "description": "Human-readable outcome summary." + success: { + type: 'boolean', + description: 'Whether the operation succeeded.', }, - "success": { - "type": "boolean", - "description": "Whether the operation succeeded." - } }, - "required": [ - "success", - "message" - ] + required: ['success', 'message'], }, }, - ["list_folders"]: { + list_folders: { parameters: { - "type": "object", - "properties": { - "workspaceId": { - "type": "string", - "description": "Optional workspace ID to list folders for." - } - } + type: 'object', + properties: { + workspaceId: { + type: 'string', + description: 'Optional workspace ID to list folders for.', + }, + }, }, resultSchema: undefined, }, - ["list_user_workspaces"]: { + list_user_workspaces: { parameters: { - "type": "object", - "properties": {} + type: 'object', + properties: {}, }, resultSchema: undefined, }, - ["list_workspace_mcp_servers"]: { + list_workspace_mcp_servers: { parameters: { - "type": "object", - "properties": { - "workspaceId": { - "type": "string", - "description": "Workspace ID (defaults to current workspace)" - } - } + type: 'object', + properties: { + workspaceId: { + type: 'string', + description: 'Workspace ID (defaults to current workspace)', + }, + }, }, resultSchema: undefined, }, - ["manage_credential"]: { + manage_credential: { parameters: { - "type": "object", - "properties": { - "credentialId": { - "type": "string", - "description": "The credential ID (required for rename)" + type: 'object', + properties: { + credentialId: { + type: 'string', + description: 'The credential ID (required for rename)', + }, + credentialIds: { + type: 'array', + description: 'Array of credential IDs (for batch delete)', + items: { + type: 'string', + }, }, - "credentialIds": { - "type": "array", - "description": "Array of credential IDs (for batch delete)", - "items": { - "type": "string" - } + displayName: { + type: 'string', + description: 'New display name (required for rename)', }, - "displayName": { - "type": "string", - "description": "New display name (required for rename)" + operation: { + type: 'string', + description: 'The operation to perform', + enum: ['rename', 'delete'], }, - "operation": { - "type": "string", - "description": "The operation to perform", - "enum": [ - "rename", - "delete" - ] - } }, - "required": [ - "operation" - ] + required: ['operation'], }, resultSchema: undefined, }, - ["manage_custom_tool"]: { + manage_custom_tool: { parameters: { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "The JavaScript code that executes when the tool is called (required for add). Parameters from schema are available as variables. Function body only - no signature or wrapping braces." + type: 'object', + properties: { + code: { + type: 'string', + description: + 'The JavaScript code that executes when the tool is called (required for add). Parameters from schema are available as variables. Function body only - no signature or wrapping braces.', }, - "operation": { - "type": "string", - "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", - "enum": [ - "add", - "edit", - "delete", - "list" - ] + operation: { + type: 'string', + description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", + enum: ['add', 'edit', 'delete', 'list'], }, - "schema": { - "type": "object", - "description": "The tool schema in OpenAI function calling format (required for add).", - "properties": { - "function": { - "type": "object", - "description": "The function definition", - "properties": { - "description": { - "type": "string", - "description": "What the function does" + schema: { + type: 'object', + description: 'The tool schema in OpenAI function calling format (required for add).', + properties: { + function: { + type: 'object', + description: 'The function definition', + properties: { + description: { + type: 'string', + description: 'What the function does', }, - "name": { - "type": "string", - "description": "The function name (camelCase)" + name: { + type: 'string', + description: 'The function name (camelCase)', }, - "parameters": { - "type": "object", - "description": "The function parameters schema", - "properties": { - "properties": { - "type": "object", - "description": "Parameter definitions as key-value pairs" + parameters: { + type: 'object', + description: 'The function parameters schema', + properties: { + properties: { + type: 'object', + description: 'Parameter definitions as key-value pairs', + }, + required: { + type: 'array', + description: 'Array of required parameter names', + items: { + type: 'string', + }, }, - "required": { - "type": "array", - "description": "Array of required parameter names", - "items": { - "type": "string" - } + type: { + type: 'string', + description: "Must be 'object'", }, - "type": { - "type": "string", - "description": "Must be 'object'" - } }, - "required": [ - "type", - "properties" - ] - } + required: ['type', 'properties'], + }, }, - "required": [ - "name", - "parameters" - ] - }, - "type": { - "type": "string", - "description": "Must be 'function'" - } + required: ['name', 'parameters'], + }, + type: { + type: 'string', + description: "Must be 'function'", + }, + }, + required: ['type', 'function'], + }, + toolId: { + type: 'string', + description: + "The ID of the custom tool (required for edit). Must be the exact toolId from the get_workflow_data custom tool response - do not guess or construct it. DO NOT PROVIDE THE TOOL ID IF THE OPERATION IS 'ADD'.", + }, + toolIds: { + type: 'array', + description: 'Array of custom tool IDs (for batch delete)', + items: { + type: 'string', }, - "required": [ - "type", - "function" - ] - }, - "toolId": { - "type": "string", - "description": "The ID of the custom tool (required for edit). Must be the exact toolId from the get_workflow_data custom tool response - do not guess or construct it. DO NOT PROVIDE THE TOOL ID IF THE OPERATION IS 'ADD'." - }, - "toolIds": { - "type": "array", - "description": "Array of custom tool IDs (for batch delete)", - "items": { - "type": "string" - } - } - }, - "required": [ - "operation" - ] - }, - resultSchema: undefined, - }, - ["manage_job"]: { - parameters: { - "type": "object", - "properties": { - "args": { - "type": "object", - "description": "Operation-specific arguments. For create: {title, prompt, cron?, time?, timezone?, lifecycle?, successCondition?, maxRuns?}. For get/delete: {jobId}. For update: {jobId, title?, prompt?, cron?, timezone?, status?, lifecycle?, successCondition?, maxRuns?}. For list: no args needed.", - "properties": { - "cron": { - "type": "string", - "description": "Cron expression for recurring jobs" - }, - "jobId": { - "type": "string", - "description": "Job ID (required for get, update)" - }, - "jobIds": { - "type": "array", - "description": "Array of job IDs (for batch delete)", - "items": { - "type": "string" - } - }, - "lifecycle": { - "type": "string", - "description": "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called." - }, - "maxRuns": { - "type": "integer", - "description": "Max executions before auto-completing. Safety limit." - }, - "prompt": { - "type": "string", - "description": "The prompt to execute when the job fires" - }, - "status": { - "type": "string", - "description": "Job status: active, paused" - }, - "successCondition": { - "type": "string", - "description": "What must happen for the job to be considered complete (until_complete lifecycle)." - }, - "time": { - "type": "string", - "description": "ISO 8601 datetime for one-time jobs or cron start time" - }, - "timezone": { - "type": "string", - "description": "IANA timezone (e.g. America/New_York). Defaults to UTC." - }, - "title": { - "type": "string", - "description": "Short descriptive title for the job (e.g. 'Email Poller')" - } - } - }, - "operation": { - "type": "string", - "description": "The operation to perform: create, list, get, update, delete", - "enum": [ - "create", - "list", - "get", - "update", - "delete" - ] - } - }, - "required": [ - "operation" - ] - }, - resultSchema: undefined, - }, - ["manage_mcp_tool"]: { - parameters: { - "type": "object", - "properties": { - "config": { - "type": "object", - "description": "Required for add and edit. The MCP server configuration.", - "properties": { - "enabled": { - "type": "boolean", - "description": "Whether the server is enabled (default: true)" - }, - "headers": { - "type": "object", - "description": "Optional HTTP headers to send with requests (key-value pairs)" - }, - "name": { - "type": "string", - "description": "Display name for the MCP server" - }, - "timeout": { - "type": "number", - "description": "Request timeout in milliseconds (default: 30000)" - }, - "transport": { - "type": "string", - "description": "Transport protocol: 'streamable-http' or 'sse'", - "enum": [ - "streamable-http", - "sse" - ], - "default": "streamable-http" - }, - "url": { - "type": "string", - "description": "The MCP server endpoint URL (required for add)" - } - } - }, - "operation": { - "type": "string", - "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", - "enum": [ - "add", - "edit", - "delete", - "list" - ] - }, - "serverId": { - "type": "string", - "description": "Required for edit and delete. The database ID of the MCP server. DO NOT PROVIDE if operation is 'add' or 'list'." - } - }, - "required": [ - "operation" - ] - }, - resultSchema: undefined, - }, - ["manage_skill"]: { - parameters: { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Markdown instructions for the skill. Required for add, optional for edit." - }, - "description": { - "type": "string", - "description": "Short description of the skill. Required for add, optional for edit." - }, - "name": { - "type": "string", - "description": "Skill name in kebab-case (e.g. 'my-skill'). Required for add, optional for edit." - }, - "operation": { - "type": "string", - "description": "The operation to perform: 'add', 'edit', 'list', or 'delete'", - "enum": [ - "add", - "edit", - "delete", - "list" - ] - }, - "skillId": { - "type": "string", - "description": "The ID of the skill (required for edit/delete). Must be the exact ID from the VFS or list. DO NOT PROVIDE if operation is 'add' or 'list'." - } - }, - "required": [ - "operation" - ] - }, - resultSchema: undefined, - }, - ["materialize_file"]: { - parameters: { - "type": "object", - "properties": { - "fileNames": { - "type": "array", - "description": "The names of the uploaded files to materialize (e.g. [\"report.pdf\", \"data.csv\"])", - "items": { - "type": "string" - } - }, - "knowledgeBaseId": { - "type": "string", - "description": "ID of an existing knowledge base to add the file to (only used with operation \"knowledge_base\"). If omitted, a new KB is created." - }, - "operation": { - "type": "string", - "description": "What to do with the file. \"save\" promotes it to files/. \"import\" imports a workflow JSON. \"table\" converts CSV/TSV/JSON to a table. \"knowledge_base\" saves and adds to a KB. Defaults to \"save\".", - "enum": [ - "save", - "import", - "table", - "knowledge_base" - ], - "default": "save" }, - "tableName": { - "type": "string", - "description": "Custom name for the table (only used with operation \"table\"). Defaults to the file name without extension." - } }, - "required": [ - "fileNames" - ] + required: ['operation'], }, resultSchema: undefined, }, - ["move_folder"]: { + manage_job: { parameters: { - "type": "object", - "properties": { - "folderId": { - "type": "string", - "description": "The folder ID to move." + type: 'object', + properties: { + args: { + type: 'object', + description: + 'Operation-specific arguments. For create: {title, prompt, cron?, time?, timezone?, lifecycle?, successCondition?, maxRuns?}. For get/delete: {jobId}. For update: {jobId, title?, prompt?, cron?, timezone?, status?, lifecycle?, successCondition?, maxRuns?}. For list: no args needed.', + properties: { + cron: { + type: 'string', + description: 'Cron expression for recurring jobs', + }, + jobId: { + type: 'string', + description: 'Job ID (required for get, update)', + }, + jobIds: { + type: 'array', + description: 'Array of job IDs (for batch delete)', + items: { + type: 'string', + }, + }, + lifecycle: { + type: 'string', + description: + "'persistent' (default) or 'until_complete'. Until_complete jobs stop when complete_job is called.", + }, + maxRuns: { + type: 'integer', + description: 'Max executions before auto-completing. Safety limit.', + }, + prompt: { + type: 'string', + description: 'The prompt to execute when the job fires', + }, + status: { + type: 'string', + description: 'Job status: active, paused', + }, + successCondition: { + type: 'string', + description: + 'What must happen for the job to be considered complete (until_complete lifecycle).', + }, + time: { + type: 'string', + description: 'ISO 8601 datetime for one-time jobs or cron start time', + }, + timezone: { + type: 'string', + description: 'IANA timezone (e.g. America/New_York). Defaults to UTC.', + }, + title: { + type: 'string', + description: "Short descriptive title for the job (e.g. 'Email Poller')", + }, + }, + }, + operation: { + type: 'string', + description: 'The operation to perform: create, list, get, update, delete', + enum: ['create', 'list', 'get', 'update', 'delete'], + }, + }, + required: ['operation'], + }, + resultSchema: undefined, + }, + manage_mcp_tool: { + parameters: { + type: 'object', + properties: { + config: { + type: 'object', + description: 'Required for add and edit. The MCP server configuration.', + properties: { + enabled: { + type: 'boolean', + description: 'Whether the server is enabled (default: true)', + }, + headers: { + type: 'object', + description: 'Optional HTTP headers to send with requests (key-value pairs)', + }, + name: { + type: 'string', + description: 'Display name for the MCP server', + }, + timeout: { + type: 'number', + description: 'Request timeout in milliseconds (default: 30000)', + }, + transport: { + type: 'string', + description: "Transport protocol: 'streamable-http' or 'sse'", + enum: ['streamable-http', 'sse'], + default: 'streamable-http', + }, + url: { + type: 'string', + description: 'The MCP server endpoint URL (required for add)', + }, + }, + }, + operation: { + type: 'string', + description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", + enum: ['add', 'edit', 'delete', 'list'], + }, + serverId: { + type: 'string', + description: + "Required for edit and delete. The database ID of the MCP server. DO NOT PROVIDE if operation is 'add' or 'list'.", + }, + }, + required: ['operation'], + }, + resultSchema: undefined, + }, + manage_skill: { + parameters: { + type: 'object', + properties: { + content: { + type: 'string', + description: 'Markdown instructions for the skill. Required for add, optional for edit.', + }, + description: { + type: 'string', + description: 'Short description of the skill. Required for add, optional for edit.', + }, + name: { + type: 'string', + description: + "Skill name in kebab-case (e.g. 'my-skill'). Required for add, optional for edit.", + }, + operation: { + type: 'string', + description: "The operation to perform: 'add', 'edit', 'list', or 'delete'", + enum: ['add', 'edit', 'delete', 'list'], + }, + skillId: { + type: 'string', + description: + "The ID of the skill (required for edit/delete). Must be the exact ID from the VFS or list. DO NOT PROVIDE if operation is 'add' or 'list'.", + }, + }, + required: ['operation'], + }, + resultSchema: undefined, + }, + materialize_file: { + parameters: { + type: 'object', + properties: { + fileNames: { + type: 'array', + description: + 'The names of the uploaded files to materialize (e.g. ["report.pdf", "data.csv"])', + items: { + type: 'string', + }, + }, + knowledgeBaseId: { + type: 'string', + description: + 'ID of an existing knowledge base to add the file to (only used with operation "knowledge_base"). If omitted, a new KB is created.', + }, + operation: { + type: 'string', + description: + 'What to do with the file. "save" promotes it to files/. "import" imports a workflow JSON. "table" converts CSV/TSV/JSON to a table. "knowledge_base" saves and adds to a KB. Defaults to "save".', + enum: ['save', 'import', 'table', 'knowledge_base'], + default: 'save', + }, + tableName: { + type: 'string', + description: + 'Custom name for the table (only used with operation "table"). Defaults to the file name without extension.', + }, + }, + required: ['fileNames'], + }, + resultSchema: undefined, + }, + move_folder: { + parameters: { + type: 'object', + properties: { + folderId: { + type: 'string', + description: 'The folder ID to move.', + }, + parentId: { + type: 'string', + description: + 'Target parent folder ID. Omit or pass empty string to move to workspace root.', }, - "parentId": { - "type": "string", - "description": "Target parent folder ID. Omit or pass empty string to move to workspace root." - } }, - "required": [ - "folderId" - ] + required: ['folderId'], }, resultSchema: undefined, }, - ["move_workflow"]: { + move_workflow: { parameters: { - "type": "object", - "properties": { - "folderId": { - "type": "string", - "description": "Target folder ID. Omit or pass empty string to move to workspace root." + type: 'object', + properties: { + folderId: { + type: 'string', + description: 'Target folder ID. Omit or pass empty string to move to workspace root.', + }, + workflowIds: { + type: 'array', + description: 'The workflow IDs to move.', + items: { + type: 'string', + }, }, - "workflowIds": { - "type": "array", - "description": "The workflow IDs to move.", - "items": { - "type": "string" - } - } }, - "required": [ - "workflowIds" - ] + required: ['workflowIds'], }, resultSchema: undefined, }, - ["oauth_get_auth_link"]: { + oauth_get_auth_link: { parameters: { - "type": "object", - "properties": { - "providerName": { - "type": "string", - "description": "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar', 'GitHub')" - } + type: 'object', + properties: { + providerName: { + type: 'string', + description: + "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar', 'GitHub')", + }, }, - "required": [ - "providerName" - ] + required: ['providerName'], }, resultSchema: undefined, }, - ["oauth_request_access"]: { + oauth_request_access: { parameters: { - "type": "object", - "properties": { - "providerName": { - "type": "string", - "description": "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar')" - } + type: 'object', + properties: { + providerName: { + type: 'string', + description: + "The name of the OAuth provider to connect (e.g., 'Slack', 'Gmail', 'Google Calendar')", + }, }, - "required": [ - "providerName" - ] + required: ['providerName'], }, resultSchema: undefined, }, - ["open_resource"]: { + open_resource: { parameters: { - "type": "object", - "properties": { - "resources": { - "type": "array", - "description": "Array of resources to open. Each item must have type and id.", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The resource ID." + type: 'object', + properties: { + resources: { + type: 'array', + description: 'Array of resources to open. Each item must have type and id.', + items: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'The resource ID.', + }, + type: { + type: 'string', + description: 'The resource type.', + enum: ['workflow', 'table', 'knowledgebase', 'file', 'log'], }, - "type": { - "type": "string", - "description": "The resource type.", - "enum": [ - "workflow", - "table", - "knowledgebase", - "file", - "log" - ] - } }, - "required": [ - "type", - "id" - ] - } - } + required: ['type', 'id'], + }, + }, }, - "required": [ - "resources" - ] + required: ['resources'], }, resultSchema: undefined, }, - ["read"]: { + read: { parameters: { - "type": "object", - "properties": { - "limit": { - "type": "number", - "description": "Maximum number of lines to read." + type: 'object', + properties: { + limit: { + type: 'number', + description: 'Maximum number of lines to read.', + }, + offset: { + type: 'number', + description: 'Line offset to start reading from (0-indexed).', }, - "offset": { - "type": "number", - "description": "Line offset to start reading from (0-indexed)." + outputTable: { + type: 'string', + description: + 'Table ID to import the file contents into (CSV/JSON). All existing rows are replaced. Example: "tbl_abc123"', }, - "outputTable": { - "type": "string", - "description": "Table ID to import the file contents into (CSV/JSON). All existing rows are replaced. Example: \"tbl_abc123\"" + path: { + type: 'string', + description: + "Path to the file to read (e.g. 'workflows/My Workflow/state.json' or 'workflows/Projects/Q1/My Workflow/state.json').", }, - "path": { - "type": "string", - "description": "Path to the file to read (e.g. 'workflows/My Workflow/state.json' or 'workflows/Projects/Q1/My Workflow/state.json')." - } }, - "required": [ - "path" - ] + required: ['path'], }, resultSchema: undefined, }, - ["redeploy"]: { + redeploy: { parameters: { - "type": "object", - "properties": { - "workflowId": { - "type": "string", - "description": "Workflow ID to redeploy (required in workspace context)" - } - } + type: 'object', + properties: { + workflowId: { + type: 'string', + description: 'Workflow ID to redeploy (required in workspace context)', + }, + }, }, resultSchema: { - "type": "object", - "properties": { - "apiEndpoint": { - "type": "string", - "description": "Canonical workflow execution endpoint." - }, - "baseUrl": { - "type": "string", - "description": "Base URL used to construct deployment URLs." - }, - "deployedAt": { - "type": "string", - "description": "Deployment timestamp when the workflow is deployed." - }, - "deploymentConfig": { - "type": "object", - "description": "Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details." - }, - "deploymentStatus": { - "type": "object", - "description": "Structured per-surface deployment status keyed by surface name, such as api." - }, - "deploymentType": { - "type": "string", - "description": "Deployment surface this result describes. For deploy_api and redeploy this is always \"api\"." - }, - "examples": { - "type": "object", - "description": "Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling." - }, - "isDeployed": { - "type": "boolean", - "description": "Whether the workflow API is currently deployed after this tool call." - }, - "version": { - "type": "number", - "description": "Deployment version for the current API deployment." - }, - "workflowId": { - "type": "string", - "description": "Workflow ID that was deployed or undeployed." - } - }, - "required": [ - "workflowId", - "isDeployed", - "deploymentType", - "deploymentStatus", - "deploymentConfig", - "examples" - ] - }, - }, - ["rename_file"]: { - parameters: { - "type": "object", - "properties": { - "fileId": { - "type": "string", - "description": "Canonical workspace file ID of the file to rename." - }, - "newName": { - "type": "string", - "description": "New filename including extension, e.g. \"draft_v2.md\". Must not contain slashes." - } - }, - "required": [ - "fileId", - "newName" - ] + type: 'object', + properties: { + apiEndpoint: { + type: 'string', + description: 'Canonical workflow execution endpoint.', + }, + baseUrl: { + type: 'string', + description: 'Base URL used to construct deployment URLs.', + }, + deployedAt: { + type: 'string', + description: 'Deployment timestamp when the workflow is deployed.', + }, + deploymentConfig: { + type: 'object', + description: + 'Structured deployment configuration keyed by surface name. For API deploys this includes endpoint, auth, and sync/stream/async mode details.', + }, + deploymentStatus: { + type: 'object', + description: + 'Structured per-surface deployment status keyed by surface name, such as api.', + }, + deploymentType: { + type: 'string', + description: + 'Deployment surface this result describes. For deploy_api and redeploy this is always "api".', + }, + examples: { + type: 'object', + description: + 'Invocation examples keyed by surface name. For API deploys this includes curl examples for sync, stream, async, and polling.', + }, + isDeployed: { + type: 'boolean', + description: 'Whether the workflow API is currently deployed after this tool call.', + }, + version: { + type: 'number', + description: 'Deployment version for the current API deployment.', + }, + workflowId: { + type: 'string', + description: 'Workflow ID that was deployed or undeployed.', + }, + }, + required: [ + 'workflowId', + 'isDeployed', + 'deploymentType', + 'deploymentStatus', + 'deploymentConfig', + 'examples', + ], + }, + }, + rename_file: { + parameters: { + type: 'object', + properties: { + fileId: { + type: 'string', + description: 'Canonical workspace file ID of the file to rename.', + }, + newName: { + type: 'string', + description: + 'New filename including extension, e.g. "draft_v2.md". Must not contain slashes.', + }, + }, + required: ['fileId', 'newName'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Contains id and the new name." + type: 'object', + properties: { + data: { + type: 'object', + description: 'Contains id and the new name.', + }, + message: { + type: 'string', + description: 'Human-readable outcome.', }, - "message": { - "type": "string", - "description": "Human-readable outcome." + success: { + type: 'boolean', + description: 'Whether the rename succeeded.', }, - "success": { - "type": "boolean", - "description": "Whether the rename succeeded." - } }, - "required": [ - "success", - "message" - ] + required: ['success', 'message'], }, }, - ["rename_workflow"]: { + rename_workflow: { parameters: { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The new name for the workflow." + type: 'object', + properties: { + name: { + type: 'string', + description: 'The new name for the workflow.', + }, + workflowId: { + type: 'string', + description: 'The workflow ID to rename.', }, - "workflowId": { - "type": "string", - "description": "The workflow ID to rename." - } }, - "required": [ - "workflowId", - "name" - ] + required: ['workflowId', 'name'], }, resultSchema: undefined, }, - ["research"]: { + research: { parameters: { - "properties": { - "topic": { - "description": "The topic to research.", - "type": "string" - } + properties: { + topic: { + description: 'The topic to research.', + type: 'string', + }, }, - "required": [ - "topic" - ], - "type": "object" + required: ['topic'], + type: 'object', }, resultSchema: undefined, }, - ["respond"]: { + respond: { parameters: { - "additionalProperties": true, - "properties": { - "output": { - "description": "The result — facts, status, VFS paths to persisted data, whatever the caller needs to act on.", - "type": "string" + additionalProperties: true, + properties: { + output: { + description: + 'The result — facts, status, VFS paths to persisted data, whatever the caller needs to act on.', + type: 'string', }, - "success": { - "description": "Whether the task completed successfully", - "type": "boolean" + success: { + description: 'Whether the task completed successfully', + type: 'boolean', + }, + type: { + description: 'Optional logical result type override', + type: 'string', }, - "type": { - "description": "Optional logical result type override", - "type": "string" - } }, - "required": [ - "output", - "success" - ], - "type": "object" + required: ['output', 'success'], + type: 'object', }, resultSchema: undefined, }, - ["restore_resource"]: { + restore_resource: { parameters: { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The canonical resource ID to restore." + type: 'object', + properties: { + id: { + type: 'string', + description: 'The canonical resource ID to restore.', + }, + type: { + type: 'string', + description: 'The resource type to restore.', + enum: ['workflow', 'table', 'file', 'knowledgebase', 'folder'], }, - "type": { - "type": "string", - "description": "The resource type to restore.", - "enum": [ - "workflow", - "table", - "file", - "knowledgebase", - "folder" - ] - } }, - "required": [ - "type", - "id" - ] + required: ['type', 'id'], }, resultSchema: undefined, }, - ["revert_to_version"]: { + revert_to_version: { parameters: { - "type": "object", - "properties": { - "version": { - "type": "number", - "description": "The deployment version number to revert to" + type: 'object', + properties: { + version: { + type: 'number', + description: 'The deployment version number to revert to', + }, + workflowId: { + type: 'string', + description: 'The workflow ID', }, - "workflowId": { - "type": "string", - "description": "The workflow ID" - } }, - "required": [ - "workflowId", - "version" - ] + required: ['workflowId', 'version'], }, resultSchema: undefined, }, - ["run"]: { + run: { parameters: { - "properties": { - "context": { - "description": "Pre-gathered context: workflow state, block IDs, input requirements.", - "type": "string" + properties: { + context: { + description: 'Pre-gathered context: workflow state, block IDs, input requirements.', + type: 'string', + }, + request: { + description: 'What to run or what logs to check.', + type: 'string', }, - "request": { - "description": "What to run or what logs to check.", - "type": "string" - } }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["run_block"]: { + run_block: { parameters: { - "type": "object", - "properties": { - "blockId": { - "type": "string", - "description": "The block ID to run in isolation." + type: 'object', + properties: { + blockId: { + type: 'string', + description: 'The block ID to run in isolation.', }, - "executionId": { - "type": "string", - "description": "Optional execution ID to load the snapshot from. Uses latest execution if omitted." + executionId: { + type: 'string', + description: + 'Optional execution ID to load the snapshot from. Uses latest execution if omitted.', }, - "useDeployedState": { - "type": "boolean", - "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." + useDeployedState: { + type: 'boolean', + description: + 'When true, runs the deployed version instead of the live draft. Default: false (draft).', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." + workflowId: { + type: 'string', + description: + 'Optional workflow ID to run. If not provided, uses the current workflow in context.', + }, + workflow_input: { + type: 'object', + description: 'JSON object with key-value mappings where each key is an input field name', }, - "workflow_input": { - "type": "object", - "description": "JSON object with key-value mappings where each key is an input field name" - } }, - "required": [ - "blockId" - ] + required: ['blockId'], }, resultSchema: undefined, }, - ["run_from_block"]: { + run_from_block: { parameters: { - "type": "object", - "properties": { - "executionId": { - "type": "string", - "description": "Optional execution ID to load the snapshot from. Uses latest execution if omitted." + type: 'object', + properties: { + executionId: { + type: 'string', + description: + 'Optional execution ID to load the snapshot from. Uses latest execution if omitted.', + }, + startBlockId: { + type: 'string', + description: 'The block ID to start execution from.', }, - "startBlockId": { - "type": "string", - "description": "The block ID to start execution from." + useDeployedState: { + type: 'boolean', + description: + 'When true, runs the deployed version instead of the live draft. Default: false (draft).', }, - "useDeployedState": { - "type": "boolean", - "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." + workflowId: { + type: 'string', + description: + 'Optional workflow ID to run. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." + workflow_input: { + type: 'object', + description: 'JSON object with key-value mappings where each key is an input field name', }, - "workflow_input": { - "type": "object", - "description": "JSON object with key-value mappings where each key is an input field name" - } }, - "required": [ - "startBlockId" - ] + required: ['startBlockId'], }, resultSchema: undefined, }, - ["run_workflow"]: { + run_workflow: { parameters: { - "type": "object", - "properties": { - "triggerBlockId": { - "type": "string", - "description": "Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one." + type: 'object', + properties: { + triggerBlockId: { + type: 'string', + description: + 'Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one.', }, - "useDeployedState": { - "type": "boolean", - "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." + useDeployedState: { + type: 'boolean', + description: + 'When true, runs the deployed version instead of the live draft. Default: false (draft).', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." + workflowId: { + type: 'string', + description: + 'Optional workflow ID to run. If not provided, uses the current workflow in context.', + }, + workflow_input: { + type: 'object', + description: 'JSON object with key-value mappings where each key is an input field name', }, - "workflow_input": { - "type": "object", - "description": "JSON object with key-value mappings where each key is an input field name" - } }, - "required": [ - "workflow_input" - ] + required: ['workflow_input'], }, resultSchema: undefined, }, - ["run_workflow_until_block"]: { + run_workflow_until_block: { parameters: { - "type": "object", - "properties": { - "stopAfterBlockId": { - "type": "string", - "description": "The block ID to stop after. Execution halts once this block completes." + type: 'object', + properties: { + stopAfterBlockId: { + type: 'string', + description: 'The block ID to stop after. Execution halts once this block completes.', + }, + triggerBlockId: { + type: 'string', + description: + 'Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one.', }, - "triggerBlockId": { - "type": "string", - "description": "Optional trigger block ID when the workflow has multiple entrypoints and you need to target a specific one." + useDeployedState: { + type: 'boolean', + description: + 'When true, runs the deployed version instead of the live draft. Default: false (draft).', }, - "useDeployedState": { - "type": "boolean", - "description": "When true, runs the deployed version instead of the live draft. Default: false (draft)." + workflowId: { + type: 'string', + description: + 'Optional workflow ID to run. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to run. If not provided, uses the current workflow in context." + workflow_input: { + type: 'object', + description: 'JSON object with key-value mappings where each key is an input field name', }, - "workflow_input": { - "type": "object", - "description": "JSON object with key-value mappings where each key is an input field name" - } }, - "required": [ - "stopAfterBlockId" - ] + required: ['stopAfterBlockId'], }, resultSchema: undefined, }, - ["scrape_page"]: { + scrape_page: { parameters: { - "type": "object", - "properties": { - "include_links": { - "type": "boolean", - "description": "Extract all links from the page (default false)" + type: 'object', + properties: { + include_links: { + type: 'boolean', + description: 'Extract all links from the page (default false)', + }, + url: { + type: 'string', + description: 'The URL to scrape (must include https://)', }, - "url": { - "type": "string", - "description": "The URL to scrape (must include https://)" + wait_for: { + type: 'string', + description: 'CSS selector to wait for before scraping (for JS-heavy pages)', }, - "wait_for": { - "type": "string", - "description": "CSS selector to wait for before scraping (for JS-heavy pages)" - } }, - "required": [ - "url" - ] + required: ['url'], }, resultSchema: undefined, }, - ["search_documentation"]: { + search_documentation: { parameters: { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "The search query" + type: 'object', + properties: { + query: { + type: 'string', + description: 'The search query', + }, + topK: { + type: 'number', + description: 'Number of results (max 10)', }, - "topK": { - "type": "number", - "description": "Number of results (max 10)" - } }, - "required": [ - "query" - ] + required: ['query'], }, resultSchema: undefined, }, - ["search_library_docs"]: { + search_library_docs: { parameters: { - "type": "object", - "properties": { - "library_name": { - "type": "string", - "description": "Name of the library to search for (e.g., 'nextjs', 'stripe', 'langchain')" + type: 'object', + properties: { + library_name: { + type: 'string', + description: "Name of the library to search for (e.g., 'nextjs', 'stripe', 'langchain')", + }, + query: { + type: 'string', + description: 'The question or topic to find documentation for - be specific', }, - "query": { - "type": "string", - "description": "The question or topic to find documentation for - be specific" + version: { + type: 'string', + description: "Specific version (optional, e.g., '14', 'v2')", }, - "version": { - "type": "string", - "description": "Specific version (optional, e.g., '14', 'v2')" - } }, - "required": [ - "library_name", - "query" - ] + required: ['library_name', 'query'], }, resultSchema: undefined, }, - ["search_online"]: { + search_online: { parameters: { - "type": "object", - "properties": { - "category": { - "type": "string", - "description": "Filter by category", - "enum": [ - "news", - "tweet", - "github", - "paper", - "company", - "research paper", - "linkedin profile", - "pdf", - "personal site" - ] + type: 'object', + properties: { + category: { + type: 'string', + description: 'Filter by category', + enum: [ + 'news', + 'tweet', + 'github', + 'paper', + 'company', + 'research paper', + 'linkedin profile', + 'pdf', + 'personal site', + ], + }, + include_text: { + type: 'boolean', + description: 'Include page text content (default true)', + }, + num_results: { + type: 'number', + description: 'Number of results (default 10, max 25)', }, - "include_text": { - "type": "boolean", - "description": "Include page text content (default true)" + query: { + type: 'string', + description: 'Natural language search query', }, - "num_results": { - "type": "number", - "description": "Number of results (default 10, max 25)" + toolTitle: { + type: 'string', + description: + 'Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like "pricing changes" or "Slack webhook docs", not a full sentence like "Searching online for pricing changes".', + }, + }, + required: ['query', 'toolTitle'], + }, + resultSchema: undefined, + }, + search_patterns: { + parameters: { + type: 'object', + properties: { + limit: { + type: 'integer', + description: 'Maximum number of unique pattern examples to return (defaults to 3).', }, - "query": { - "type": "string", - "description": "Natural language search query" + queries: { + type: 'array', + description: + 'Up to 3 descriptive strings explaining the workflow pattern(s) you need. Focus on intent and desired outcomes.', + items: { + type: 'string', + description: 'Example: "how to automate wealthbox meeting notes into follow-up tasks"', + }, }, - "toolTitle": { - "type": "string", - "description": "Optional target-only UI phrase for the search row. The UI verb is supplied for you, so pass text like \"pricing changes\" or \"Slack webhook docs\", not a full sentence like \"Searching online for pricing changes\"." - } }, - "required": [ - "query", - "toolTitle" - ] + required: ['queries'], }, resultSchema: undefined, }, - ["search_patterns"]: { + set_block_enabled: { parameters: { - "type": "object", - "properties": { - "limit": { - "type": "integer", - "description": "Maximum number of unique pattern examples to return (defaults to 3)." + type: 'object', + properties: { + blockId: { + type: 'string', + description: 'The block ID whose enabled state should be changed.', + }, + enabled: { + type: 'boolean', + description: 'Set to true to enable the block, or false to disable it.', + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID to edit. If not provided, uses the current workflow in context.', }, - "queries": { - "type": "array", - "description": "Up to 3 descriptive strings explaining the workflow pattern(s) you need. Focus on intent and desired outcomes.", - "items": { - "type": "string", - "description": "Example: \"how to automate wealthbox meeting notes into follow-up tasks\"" - } - } }, - "required": [ - "queries" - ] + required: ['blockId', 'enabled'], }, resultSchema: undefined, }, - ["set_block_enabled"]: { + set_environment_variables: { parameters: { - "type": "object", - "properties": { - "blockId": { - "type": "string", - "description": "The block ID whose enabled state should be changed." + type: 'object', + properties: { + scope: { + type: 'string', + description: + 'Whether to set workspace or personal environment variables. Defaults to workspace.', + enum: ['personal', 'workspace'], + default: 'workspace', }, - "enabled": { - "type": "boolean", - "description": "Set to true to enable the block, or false to disable it." + variables: { + type: 'array', + description: 'List of env vars to set', + items: { + type: 'object', + properties: { + name: { + type: 'string', + description: 'Variable name', + }, + value: { + type: 'string', + description: 'Variable value', + }, + }, + required: ['name', 'value'], + }, }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID to edit. If not provided, uses the current workflow in context." - } }, - "required": [ - "blockId", - "enabled" - ] + required: ['variables'], }, - resultSchema: undefined, + resultSchema: undefined, }, - ["set_environment_variables"]: { + set_global_workflow_variables: { parameters: { - "type": "object", - "properties": { - "scope": { - "type": "string", - "description": "Whether to set workspace or personal environment variables. Defaults to workspace.", - "enum": [ - "personal", - "workspace" - ], - "default": "workspace" - }, - "variables": { - "type": "array", - "description": "List of env vars to set", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Variable name" + type: 'object', + properties: { + operations: { + type: 'array', + description: 'List of operations to apply', + items: { + type: 'object', + properties: { + name: { + type: 'string', }, - "value": { - "type": "string", - "description": "Variable value" - } - }, - "required": [ - "name", - "value" - ] - } - } - }, - "required": [ - "variables" - ] - }, - resultSchema: undefined, - }, - ["set_global_workflow_variables"]: { - parameters: { - "type": "object", - "properties": { - "operations": { - "type": "array", - "description": "List of operations to apply", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" + operation: { + type: 'string', + enum: ['add', 'delete', 'edit'], }, - "operation": { - "type": "string", - "enum": [ - "add", - "delete", - "edit" - ] + type: { + type: 'string', + enum: ['plain', 'number', 'boolean', 'array', 'object'], }, - "type": { - "type": "string", - "enum": [ - "plain", - "number", - "boolean", - "array", - "object" - ] + value: { + type: 'string', }, - "value": { - "type": "string" - } }, - "required": [ - "operation", - "name", - "type", - "value" - ] - } + required: ['operation', 'name', 'type', 'value'], + }, + }, + workflowId: { + type: 'string', + description: + 'Optional workflow ID. If not provided, uses the current workflow in context.', }, - "workflowId": { - "type": "string", - "description": "Optional workflow ID. If not provided, uses the current workflow in context." - } }, - "required": [ - "operations" - ] + required: ['operations'], }, resultSchema: undefined, }, - ["superagent"]: { + superagent: { parameters: { - "properties": { - "task": { - "description": "A single sentence — the agent has full conversation context. Do NOT pre-read credentials or look up configs. Example: 'send the email we discussed' or 'check my calendar for tomorrow'.", - "type": "string" - } + properties: { + task: { + description: + "A single sentence — the agent has full conversation context. Do NOT pre-read credentials or look up configs. Example: 'send the email we discussed' or 'check my calendar for tomorrow'.", + type: 'string', + }, }, - "required": [ - "task" - ], - "type": "object" + required: ['task'], + type: 'object', }, resultSchema: undefined, }, - ["table"]: { + table: { parameters: { - "properties": { - "request": { - "description": "What table action is needed.", - "type": "string" - } + properties: { + request: { + description: 'What table action is needed.', + type: 'string', + }, }, - "required": [ - "request" - ], - "type": "object" + required: ['request'], + type: 'object', }, resultSchema: undefined, }, - ["tool_search_tool_regex"]: { + tool_search_tool_regex: { parameters: { - "properties": { - "case_insensitive": { - "description": "Whether the regex should be case-insensitive (default true).", - "type": "boolean" + properties: { + case_insensitive: { + description: 'Whether the regex should be case-insensitive (default true).', + type: 'boolean', }, - "max_results": { - "description": "Maximum number of tools to return (optional).", - "type": "integer" + max_results: { + description: 'Maximum number of tools to return (optional).', + type: 'integer', + }, + pattern: { + description: 'Regular expression to match tool names or descriptions.', + type: 'string', }, - "pattern": { - "description": "Regular expression to match tool names or descriptions.", - "type": "string" - } }, - "required": [ - "pattern" - ], - "type": "object" + required: ['pattern'], + type: 'object', }, resultSchema: undefined, }, - ["update_job_history"]: { + update_job_history: { parameters: { - "type": "object", - "properties": { - "jobId": { - "type": "string", - "description": "The job ID." - }, - "summary": { - "type": "string", - "description": "A concise summary of what was done this run (e.g., 'Sent follow-up emails to 3 leads: Alice, Bob, Carol')." - } + type: 'object', + properties: { + jobId: { + type: 'string', + description: 'The job ID.', + }, + summary: { + type: 'string', + description: + "A concise summary of what was done this run (e.g., 'Sent follow-up emails to 3 leads: Alice, Bob, Carol').", + }, }, - "required": [ - "jobId", - "summary" - ] + required: ['jobId', 'summary'], }, resultSchema: undefined, }, - ["update_workspace_mcp_server"]: { + update_workspace_mcp_server: { parameters: { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "New description for the server" + type: 'object', + properties: { + description: { + type: 'string', + description: 'New description for the server', + }, + isPublic: { + type: 'boolean', + description: 'Whether the server is publicly accessible', }, - "isPublic": { - "type": "boolean", - "description": "Whether the server is publicly accessible" + name: { + type: 'string', + description: 'New name for the server', }, - "name": { - "type": "string", - "description": "New name for the server" + serverId: { + type: 'string', + description: 'Required: the MCP server ID to update', }, - "serverId": { - "type": "string", - "description": "Required: the MCP server ID to update" - } }, - "required": [ - "serverId" - ] + required: ['serverId'], }, resultSchema: undefined, }, - ["user_memory"]: { + user_memory: { parameters: { - "type": "object", - "properties": { - "confidence": { - "type": "number", - "description": "Confidence level 0-1 (default 1.0 for explicit, 0.8 for inferred)" + type: 'object', + properties: { + confidence: { + type: 'number', + description: 'Confidence level 0-1 (default 1.0 for explicit, 0.8 for inferred)', + }, + correct_value: { + type: 'string', + description: "The correct value to replace the wrong one (for 'correct' operation)", + }, + key: { + type: 'string', + description: "Unique key for the memory (e.g., 'preferred_model', 'slack_credential')", + }, + limit: { + type: 'number', + description: 'Number of results for search (default 10)', + }, + memory_type: { + type: 'string', + description: "Type of memory: 'preference', 'entity', 'history', or 'correction'", + enum: ['preference', 'entity', 'history', 'correction'], + }, + operation: { + type: 'string', + description: "Operation: 'add', 'search', 'delete', 'correct', or 'list'", + enum: ['add', 'search', 'delete', 'correct', 'list'], + }, + query: { + type: 'string', + description: 'Search query to find relevant memories', + }, + source: { + type: 'string', + description: "Source: 'explicit' (user told you) or 'inferred' (you observed)", + enum: ['explicit', 'inferred'], + }, + value: { + type: 'string', + description: 'Value to remember', }, - "correct_value": { - "type": "string", - "description": "The correct value to replace the wrong one (for 'correct' operation)" + }, + required: ['operation'], + }, + resultSchema: undefined, + }, + user_table: { + parameters: { + type: 'object', + properties: { + args: { + type: 'object', + description: 'Arguments for the operation', + properties: { + column: { + type: 'object', + description: 'Column definition for add_column: { name, type, unique?, position? }', + }, + columnName: { + type: 'string', + description: + 'Column name (required for rename_column, update_column; use columnNames array for batch delete_column)', + }, + columnNames: { + type: 'array', + description: + 'Array of column names to delete at once (for delete_column). Preferred over columnName when deleting multiple columns.', + }, + data: { + type: 'object', + description: 'Row data as key-value pairs (required for insert_row, update_row)', + }, + description: { + type: 'string', + description: "Table description (optional for 'create')", + }, + fileId: { + type: 'string', + description: + 'Canonical workspace file ID for create_from_file/import_file. Discover via read("files/{name}/meta.json") or glob("files/by-id/*/meta.json").', + }, + filePath: { + type: 'string', + description: + 'Legacy workspace file reference for create_from_file/import_file. Prefer fileId.', + }, + filter: { + type: 'object', + description: + 'MongoDB-style filter for query_rows, update_rows_by_filter, delete_rows_by_filter', + }, + limit: { + type: 'number', + description: 'Maximum rows to return or affect (optional, default 100)', + }, + mapping: { + type: 'object', + description: + 'Optional explicit CSV-header → table-column mapping for import_file, as { "csvHeader": "columnName" | null }. When omitted, headers are auto-matched by sanitized name (case-insensitive fallback). Use null to skip a CSV column.', + additionalProperties: { + type: 'string', + description: + 'Target column name on the table. Use null to skip this CSV header instead of a column name.', + }, + }, + mode: { + type: 'string', + description: + "Import mode for import_file. 'append' (default) adds rows; 'replace' truncates existing rows in a transaction before inserting the new rows.", + enum: ['append', 'replace'], + }, + name: { + type: 'string', + description: "Table name (required for 'create')", + }, + newName: { + type: 'string', + description: 'New column name (required for rename_column)', + }, + newType: { + type: 'string', + description: + 'New column type (optional for update_column). Types: string, number, boolean, date, json', + }, + offset: { + type: 'number', + description: 'Number of rows to skip (optional for query_rows, default 0)', + }, + outputFormat: { + type: 'string', + description: + 'Explicit format override for outputPath. Usually unnecessary — the file extension determines the format automatically. Only use this to force a different format than what the extension implies.', + enum: ['json', 'csv', 'txt', 'md', 'html'], + }, + outputPath: { + type: 'string', + description: + 'Pipe query_rows results directly to a NEW workspace file. The format is auto-inferred from the file extension: .csv → CSV, .json → JSON, .md → Markdown, etc. Use .csv for tabular exports. Use a flat path like "files/export.csv" — nested paths are not supported.', + }, + position: { + type: 'integer', + description: + 'Zero-based index at which to insert the row (optional, insert_row only). Rows at and below that index shift down. Omit to append at the end.', + }, + positions: { + type: 'array', + description: + 'Per-row insertion indices for batch_insert_rows (optional). Must be the same length as rows and contain no duplicates. Values are final positions in the resulting table — lower-index shifts are applied automatically. Omit to append all rows at the end.', + items: { + type: 'integer', + }, + }, + rowId: { + type: 'string', + description: 'Row ID (required for get_row, update_row, delete_row)', + }, + rowIds: { + type: 'array', + description: 'Array of row IDs to delete (for batch_delete_rows)', + }, + rows: { + type: 'array', + description: 'Array of row data objects (required for batch_insert_rows)', + }, + schema: { + type: 'object', + description: + "Table schema with columns array (required for 'create'). Each column: { name, type, unique? }", + }, + sort: { + type: 'object', + description: + "Sort specification as { field: 'asc' | 'desc' } (optional for query_rows)", + }, + tableId: { + type: 'string', + description: + "Table ID (required for most operations except 'create' and batch 'delete')", + }, + tableIds: { + type: 'array', + description: 'Array of table IDs (for batch delete)', + items: { + type: 'string', + }, + }, + unique: { + type: 'boolean', + description: 'Set column unique constraint (optional for update_column)', + }, + updates: { + type: 'array', + description: + 'Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows)', + }, + values: { + type: 'object', + description: + 'Map of rowId to value for single-column batch update: { "rowId1": val1, "rowId2": val2 } (for batch_update_rows with columnName)', + }, + }, }, - "key": { - "type": "string", - "description": "Unique key for the memory (e.g., 'preferred_model', 'slack_credential')" + operation: { + type: 'string', + description: 'The operation to perform', + enum: [ + 'create', + 'create_from_file', + 'import_file', + 'get', + 'get_schema', + 'delete', + 'insert_row', + 'batch_insert_rows', + 'get_row', + 'query_rows', + 'update_row', + 'delete_row', + 'update_rows_by_filter', + 'delete_rows_by_filter', + 'batch_update_rows', + 'batch_delete_rows', + 'add_column', + 'rename_column', + 'delete_column', + 'update_column', + ], }, - "limit": { - "type": "number", - "description": "Number of results for search (default 10)" - }, - "memory_type": { - "type": "string", - "description": "Type of memory: 'preference', 'entity', 'history', or 'correction'", - "enum": [ - "preference", - "entity", - "history", - "correction" - ] - }, - "operation": { - "type": "string", - "description": "Operation: 'add', 'search', 'delete', 'correct', or 'list'", - "enum": [ - "add", - "search", - "delete", - "correct", - "list" - ] - }, - "query": { - "type": "string", - "description": "Search query to find relevant memories" - }, - "source": { - "type": "string", - "description": "Source: 'explicit' (user told you) or 'inferred' (you observed)", - "enum": [ - "explicit", - "inferred" - ] - }, - "value": { - "type": "string", - "description": "Value to remember" - } - }, - "required": [ - "operation" - ] - }, - resultSchema: undefined, - }, - ["user_table"]: { - parameters: { - "type": "object", - "properties": { - "args": { - "type": "object", - "description": "Arguments for the operation", - "properties": { - "column": { - "type": "object", - "description": "Column definition for add_column: { name, type, unique?, position? }" - }, - "columnName": { - "type": "string", - "description": "Column name (required for rename_column, update_column; use columnNames array for batch delete_column)" - }, - "columnNames": { - "type": "array", - "description": "Array of column names to delete at once (for delete_column). Preferred over columnName when deleting multiple columns." - }, - "data": { - "type": "object", - "description": "Row data as key-value pairs (required for insert_row, update_row)" - }, - "description": { - "type": "string", - "description": "Table description (optional for 'create')" - }, - "fileId": { - "type": "string", - "description": "Canonical workspace file ID for create_from_file/import_file. Discover via read(\"files/{name}/meta.json\") or glob(\"files/by-id/*/meta.json\")." - }, - "filePath": { - "type": "string", - "description": "Legacy workspace file reference for create_from_file/import_file. Prefer fileId." - }, - "filter": { - "type": "object", - "description": "MongoDB-style filter for query_rows, update_rows_by_filter, delete_rows_by_filter" - }, - "limit": { - "type": "number", - "description": "Maximum rows to return or affect (optional, default 100)" - }, - "mapping": { - "type": "object", - "description": "Optional explicit CSV-header → table-column mapping for import_file, as { \"csvHeader\": \"columnName\" | null }. When omitted, headers are auto-matched by sanitized name (case-insensitive fallback). Use null to skip a CSV column.", - "additionalProperties": { - "type": "string", - "description": "Target column name on the table. Use null to skip this CSV header instead of a column name." - } - }, - "mode": { - "type": "string", - "description": "Import mode for import_file. 'append' (default) adds rows; 'replace' truncates existing rows in a transaction before inserting the new rows.", - "enum": [ - "append", - "replace" - ] - }, - "name": { - "type": "string", - "description": "Table name (required for 'create')" - }, - "newName": { - "type": "string", - "description": "New column name (required for rename_column)" - }, - "newType": { - "type": "string", - "description": "New column type (optional for update_column). Types: string, number, boolean, date, json" - }, - "offset": { - "type": "number", - "description": "Number of rows to skip (optional for query_rows, default 0)" - }, - "outputFormat": { - "type": "string", - "description": "Explicit format override for outputPath. Usually unnecessary — the file extension determines the format automatically. Only use this to force a different format than what the extension implies.", - "enum": [ - "json", - "csv", - "txt", - "md", - "html" - ] - }, - "outputPath": { - "type": "string", - "description": "Pipe query_rows results directly to a NEW workspace file. The format is auto-inferred from the file extension: .csv → CSV, .json → JSON, .md → Markdown, etc. Use .csv for tabular exports. Use a flat path like \"files/export.csv\" — nested paths are not supported." - }, - "position": { - "type": "integer", - "description": "Zero-based index at which to insert the row (optional, insert_row only). Rows at and below that index shift down. Omit to append at the end." - }, - "positions": { - "type": "array", - "description": "Per-row insertion indices for batch_insert_rows (optional). Must be the same length as rows and contain no duplicates. Values are final positions in the resulting table — lower-index shifts are applied automatically. Omit to append all rows at the end.", - "items": { - "type": "integer" - } - }, - "rowId": { - "type": "string", - "description": "Row ID (required for get_row, update_row, delete_row)" - }, - "rowIds": { - "type": "array", - "description": "Array of row IDs to delete (for batch_delete_rows)" - }, - "rows": { - "type": "array", - "description": "Array of row data objects (required for batch_insert_rows)" - }, - "schema": { - "type": "object", - "description": "Table schema with columns array (required for 'create'). Each column: { name, type, unique? }" - }, - "sort": { - "type": "object", - "description": "Sort specification as { field: 'asc' | 'desc' } (optional for query_rows)" - }, - "tableId": { - "type": "string", - "description": "Table ID (required for most operations except 'create' and batch 'delete')" - }, - "tableIds": { - "type": "array", - "description": "Array of table IDs (for batch delete)", - "items": { - "type": "string" - } - }, - "unique": { - "type": "boolean", - "description": "Set column unique constraint (optional for update_column)" - }, - "updates": { - "type": "array", - "description": "Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows)" - }, - "values": { - "type": "object", - "description": "Map of rowId to value for single-column batch update: { \"rowId1\": val1, \"rowId2\": val2 } (for batch_update_rows with columnName)" - } - } - }, - "operation": { - "type": "string", - "description": "The operation to perform", - "enum": [ - "create", - "create_from_file", - "import_file", - "get", - "get_schema", - "delete", - "insert_row", - "batch_insert_rows", - "get_row", - "query_rows", - "update_row", - "delete_row", - "update_rows_by_filter", - "delete_rows_by_filter", - "batch_update_rows", - "batch_delete_rows", - "add_column", - "rename_column", - "delete_column", - "update_column" - ] - } - }, - "required": [ - "operation", - "args" - ] + }, + required: ['operation', 'args'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Operation-specific result payload." - }, - "message": { - "type": "string", - "description": "Human-readable outcome summary." - }, - "success": { - "type": "boolean", - "description": "Whether the operation succeeded." - } - }, - "required": [ - "success", - "message" - ] - }, - }, - ["workflow"]: { - parameters: { - "type": "object" - }, - resultSchema: undefined, - }, - ["workspace_file"]: { - parameters: { - "type": "object", - "properties": { - "operation": { - "type": "string", - "description": "The file operation to perform.", - "enum": [ - "append", - "update", - "patch" - ] - }, - "target": { - "type": "object", - "description": "Explicit file target. Use kind=file_id + fileId for existing files.", - "properties": { - "fileId": { - "type": "string", - "description": "Canonical existing workspace file ID. Required when target.kind=file_id." - }, - "fileName": { - "type": "string", - "description": "Plain workspace filename including extension, e.g. \"main.py\" or \"report.docx\". Required when target.kind=new_file." - }, - "kind": { - "type": "string", - "description": "How the file target is identified.", - "enum": [ - "new_file", - "file_id" - ] - } + type: 'object', + properties: { + data: { + type: 'object', + description: 'Operation-specific result payload.', + }, + message: { + type: 'string', + description: 'Human-readable outcome summary.', + }, + success: { + type: 'boolean', + description: 'Whether the operation succeeded.', + }, + }, + required: ['success', 'message'], + }, + }, + workflow: { + parameters: { + type: 'object', + }, + resultSchema: undefined, + }, + workspace_file: { + parameters: { + type: 'object', + properties: { + operation: { + type: 'string', + description: 'The file operation to perform.', + enum: ['append', 'update', 'patch'], + }, + target: { + type: 'object', + description: 'Explicit file target. Use kind=file_id + fileId for existing files.', + properties: { + fileId: { + type: 'string', + description: + 'Canonical existing workspace file ID. Required when target.kind=file_id.', + }, + fileName: { + type: 'string', + description: + 'Plain workspace filename including extension, e.g. "main.py" or "report.docx". Required when target.kind=new_file.', + }, + kind: { + type: 'string', + description: 'How the file target is identified.', + enum: ['new_file', 'file_id'], + }, }, - "required": [ - "kind" - ] - }, - "title": { - "type": "string", - "description": "Required short UI label for this content unit, e.g. \"Chapter 1\", \"Slide 3\", or \"Fix footer spacing\"." - }, - "contentType": { - "type": "string", - "description": "Optional MIME type override. Usually omit and let the system infer from the target file extension.", - "enum": [ - "text/markdown", - "text/html", - "text/plain", - "application/json", - "text/csv", - "application/vnd.openxmlformats-officedocument.presentationml.presentation", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - "application/pdf" - ] - }, - "edit": { - "type": "object", - "description": "Patch metadata. Use strategy=search_replace for exact text replacement, or strategy=anchored for line-based inserts/replacements/deletions. The actual replacement/insert content is provided via the paired edit_content tool call.", - "properties": { - "after_anchor": { - "type": "string", - "description": "Boundary line kept after inserted replacement content. Required for mode=replace_between." - }, - "anchor": { - "type": "string", - "description": "Anchor line after which new content is inserted. Required for mode=insert_after." - }, - "before_anchor": { - "type": "string", - "description": "Boundary line kept before inserted replacement content. Required for mode=replace_between." - }, - "end_anchor": { - "type": "string", - "description": "First line to keep after deletion. Required for mode=delete_between." - }, - "mode": { - "type": "string", - "description": "Anchored edit mode when strategy=anchored.", - "enum": [ - "replace_between", - "insert_after", - "delete_between" - ] - }, - "occurrence": { - "type": "number", - "description": "1-based occurrence for repeated anchor lines. Optional; defaults to 1." - }, - "replaceAll": { - "type": "boolean", - "description": "When true and strategy=search_replace, replace every match instead of requiring a unique single match." - }, - "search": { - "type": "string", - "description": "Exact text to find when strategy=search_replace. Must match exactly once unless replaceAll=true." - }, - "start_anchor": { - "type": "string", - "description": "First line to delete. Required for mode=delete_between." - }, - "strategy": { - "type": "string", - "description": "Patch strategy.", - "enum": [ - "search_replace", - "anchored" - ] - } - } - }, - "newName": { - "type": "string", - "description": "New file name for rename. Must be a plain workspace filename like \"main.py\"." - } - }, - "required": [ - "operation", - "target", - "title" - ] + required: ['kind'], + }, + title: { + type: 'string', + description: + 'Required short UI label for this content unit, e.g. "Chapter 1", "Slide 3", or "Fix footer spacing".', + }, + contentType: { + type: 'string', + description: + 'Optional MIME type override. Usually omit and let the system infer from the target file extension.', + enum: [ + 'text/markdown', + 'text/html', + 'text/plain', + 'application/json', + 'text/csv', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/pdf', + ], + }, + edit: { + type: 'object', + description: + 'Patch metadata. Use strategy=search_replace for exact text replacement, or strategy=anchored for line-based inserts/replacements/deletions. The actual replacement/insert content is provided via the paired edit_content tool call.', + properties: { + after_anchor: { + type: 'string', + description: + 'Boundary line kept after inserted replacement content. Required for mode=replace_between.', + }, + anchor: { + type: 'string', + description: + 'Anchor line after which new content is inserted. Required for mode=insert_after.', + }, + before_anchor: { + type: 'string', + description: + 'Boundary line kept before inserted replacement content. Required for mode=replace_between.', + }, + end_anchor: { + type: 'string', + description: 'First line to keep after deletion. Required for mode=delete_between.', + }, + mode: { + type: 'string', + description: 'Anchored edit mode when strategy=anchored.', + enum: ['replace_between', 'insert_after', 'delete_between'], + }, + occurrence: { + type: 'number', + description: '1-based occurrence for repeated anchor lines. Optional; defaults to 1.', + }, + replaceAll: { + type: 'boolean', + description: + 'When true and strategy=search_replace, replace every match instead of requiring a unique single match.', + }, + search: { + type: 'string', + description: + 'Exact text to find when strategy=search_replace. Must match exactly once unless replaceAll=true.', + }, + start_anchor: { + type: 'string', + description: 'First line to delete. Required for mode=delete_between.', + }, + strategy: { + type: 'string', + description: 'Patch strategy.', + enum: ['search_replace', 'anchored'], + }, + }, + }, + newName: { + type: 'string', + description: + 'New file name for rename. Must be a plain workspace filename like "main.py".', + }, + }, + required: ['operation', 'target', 'title'], }, resultSchema: { - "type": "object", - "properties": { - "data": { - "type": "object", - "description": "Optional operation metadata such as file id, file name, size, and content type." - }, - "message": { - "type": "string", - "description": "Human-readable summary of the outcome." - }, - "success": { - "type": "boolean", - "description": "Whether the file operation succeeded." - } - }, - "required": [ - "success", - "message" - ] + type: 'object', + properties: { + data: { + type: 'object', + description: + 'Optional operation metadata such as file id, file name, size, and content type.', + }, + message: { + type: 'string', + description: 'Human-readable summary of the outcome.', + }, + success: { + type: 'boolean', + description: 'Whether the file operation succeeded.', + }, + }, + required: ['success', 'message'], }, }, } From 5b933615005790c11d8b2dce208f7e88bd9c6a96 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 2 May 2026 18:16:28 -0700 Subject: [PATCH 3/4] fix unit test timout --- apps/sim/lib/copilot/vfs/file-reader.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/sim/lib/copilot/vfs/file-reader.test.ts b/apps/sim/lib/copilot/vfs/file-reader.test.ts index 1e202d77d5f..fa5ba5855eb 100644 --- a/apps/sim/lib/copilot/vfs/file-reader.test.ts +++ b/apps/sim/lib/copilot/vfs/file-reader.test.ts @@ -28,6 +28,10 @@ async function makeNoisePng(width: number, height: number): Promise { .toBuffer() } +// Both tests do real sharp work (encode + metadata read) that can exceed the +// default 10s timeout when CI runs them alongside thousands of other tests. +const SHARP_TEST_TIMEOUT_MS = 30_000 + describe('readFileRecord', () => { it('returns small images as attachments without resize note', async () => { const sharp = (await import('sharp')).default @@ -62,7 +66,7 @@ describe('readFileRecord', () => { expect(result?.attachment?.source.media_type).toBe('image/png') expect(result?.content).not.toContain('resized for vision') expect(Buffer.from(result?.attachment?.source.data ?? '', 'base64')).toEqual(smallPng) - }) + }, SHARP_TEST_TIMEOUT_MS) it('downscales oversized images into attachments that fit the read limit', async () => { const largePng = await makeNoisePng(1800, 1800) @@ -90,5 +94,5 @@ describe('readFileRecord', () => { const decoded = Buffer.from(result?.attachment?.source.data ?? '', 'base64') expect(decoded.length).toBeLessThanOrEqual(MAX_IMAGE_READ_BYTES) expect(result?.attachment?.source.media_type).toMatch(/^image\/(jpeg|webp|png)$/) - }) + }, SHARP_TEST_TIMEOUT_MS) }) From 75235705ded4f4f878184017af6e75d019033926 Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Sat, 2 May 2026 18:18:06 -0700 Subject: [PATCH 4/4] fix lint --- apps/sim/lib/copilot/vfs/file-reader.test.ts | 132 ++++++++++--------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/apps/sim/lib/copilot/vfs/file-reader.test.ts b/apps/sim/lib/copilot/vfs/file-reader.test.ts index fa5ba5855eb..367861d038f 100644 --- a/apps/sim/lib/copilot/vfs/file-reader.test.ts +++ b/apps/sim/lib/copilot/vfs/file-reader.test.ts @@ -33,66 +33,74 @@ async function makeNoisePng(width: number, height: number): Promise { const SHARP_TEST_TIMEOUT_MS = 30_000 describe('readFileRecord', () => { - it('returns small images as attachments without resize note', async () => { - const sharp = (await import('sharp')).default - const smallPng = await sharp({ - create: { - width: 200, - height: 200, - channels: 3, - background: { r: 255, g: 0, b: 0 }, - }, - }) - .png() - .toBuffer() - - downloadWorkspaceFile.mockResolvedValue(smallPng) - - const result = await readFileRecord({ - id: 'wf_small', - workspaceId: 'ws_1', - name: 'small.png', - key: 'uploads/small.png', - path: '/api/files/serve/uploads%2Fsmall.png?context=mothership', - size: smallPng.length, - type: 'image/png', - uploadedBy: 'user_1', - uploadedAt: new Date(), - deletedAt: null, - storageContext: 'mothership', - }) - - expect(result?.attachment?.type).toBe('image') - expect(result?.attachment?.source.media_type).toBe('image/png') - expect(result?.content).not.toContain('resized for vision') - expect(Buffer.from(result?.attachment?.source.data ?? '', 'base64')).toEqual(smallPng) - }, SHARP_TEST_TIMEOUT_MS) - - it('downscales oversized images into attachments that fit the read limit', async () => { - const largePng = await makeNoisePng(1800, 1800) - expect(largePng.length).toBeGreaterThan(MAX_IMAGE_READ_BYTES) - - downloadWorkspaceFile.mockResolvedValue(largePng) - - const result = await readFileRecord({ - id: 'wf_large', - workspaceId: 'ws_1', - name: 'chesspng.png', - key: 'uploads/chesspng.png', - path: '/api/files/serve/uploads%2Fchesspng.png?context=mothership', - size: largePng.length, - type: 'image/png', - uploadedBy: 'user_1', - uploadedAt: new Date(), - deletedAt: null, - storageContext: 'mothership', - }) - - expect(result?.attachment?.type).toBe('image') - expect(result?.content).toContain('resized for vision') - - const decoded = Buffer.from(result?.attachment?.source.data ?? '', 'base64') - expect(decoded.length).toBeLessThanOrEqual(MAX_IMAGE_READ_BYTES) - expect(result?.attachment?.source.media_type).toMatch(/^image\/(jpeg|webp|png)$/) - }, SHARP_TEST_TIMEOUT_MS) + it( + 'returns small images as attachments without resize note', + async () => { + const sharp = (await import('sharp')).default + const smallPng = await sharp({ + create: { + width: 200, + height: 200, + channels: 3, + background: { r: 255, g: 0, b: 0 }, + }, + }) + .png() + .toBuffer() + + downloadWorkspaceFile.mockResolvedValue(smallPng) + + const result = await readFileRecord({ + id: 'wf_small', + workspaceId: 'ws_1', + name: 'small.png', + key: 'uploads/small.png', + path: '/api/files/serve/uploads%2Fsmall.png?context=mothership', + size: smallPng.length, + type: 'image/png', + uploadedBy: 'user_1', + uploadedAt: new Date(), + deletedAt: null, + storageContext: 'mothership', + }) + + expect(result?.attachment?.type).toBe('image') + expect(result?.attachment?.source.media_type).toBe('image/png') + expect(result?.content).not.toContain('resized for vision') + expect(Buffer.from(result?.attachment?.source.data ?? '', 'base64')).toEqual(smallPng) + }, + SHARP_TEST_TIMEOUT_MS + ) + + it( + 'downscales oversized images into attachments that fit the read limit', + async () => { + const largePng = await makeNoisePng(1800, 1800) + expect(largePng.length).toBeGreaterThan(MAX_IMAGE_READ_BYTES) + + downloadWorkspaceFile.mockResolvedValue(largePng) + + const result = await readFileRecord({ + id: 'wf_large', + workspaceId: 'ws_1', + name: 'chesspng.png', + key: 'uploads/chesspng.png', + path: '/api/files/serve/uploads%2Fchesspng.png?context=mothership', + size: largePng.length, + type: 'image/png', + uploadedBy: 'user_1', + uploadedAt: new Date(), + deletedAt: null, + storageContext: 'mothership', + }) + + expect(result?.attachment?.type).toBe('image') + expect(result?.content).toContain('resized for vision') + + const decoded = Buffer.from(result?.attachment?.source.data ?? '', 'base64') + expect(decoded.length).toBeLessThanOrEqual(MAX_IMAGE_READ_BYTES) + expect(result?.attachment?.source.media_type).toMatch(/^image\/(jpeg|webp|png)$/) + }, + SHARP_TEST_TIMEOUT_MS + ) })