Skip to content

Commit 5617a3b

Browse files
committed
mothership: prepare_file_edit create + new_file pass input validation
The workspace-file handler has always supported operation=create with a new_file target, but the generated tool schema (from the copilot catalog) forbade both, so the watched write could never create a file: a "save this report as a workspace file" turn died on `/operation must be equal to one of the allowed values` (dev 2026-09-03). Regenerated from the catalog that now declares create, new_file, and fileName; regression test on the validator.
1 parent 2d45595 commit 5617a3b

3 files changed

Lines changed: 83 additions & 46 deletions

File tree

‎apps/sim/lib/mothership/generated/tool-catalog-v1.ts‎

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,16 +3809,22 @@ export const PrepareFileEdit: ToolCatalogEntry = {
38093809
operation: {
38103810
type: 'string',
38113811
description: 'The file operation to perform.',
3812-
enum: ['append', 'update', 'patch'],
3812+
enum: ['create', 'append', 'update', 'patch'],
38133813
},
38143814
target: {
38153815
type: 'object',
3816-
description: 'Explicit file target. Use kind=path + path for existing files.',
3816+
description:
3817+
'Explicit file target: kind=new_file + fileName creates a file; kind=path + path names an existing one.',
38173818
properties: {
3819+
fileName: {
3820+
type: 'string',
3821+
description:
3822+
'Name of the file to create, e.g. "q3-summary.md". Required when target.kind=new_file.',
3823+
},
38183824
kind: {
38193825
type: 'string',
38203826
description: 'How the file target is identified.',
3821-
enum: ['path'],
3827+
enum: ['path', 'new_file'],
38223828
},
38233829
path: {
38243830
type: 'string',
@@ -4213,7 +4219,7 @@ export const QueryUserTable: ToolCatalogEntry = {
42134219
filter: {
42144220
type: 'object',
42154221
description:
4216-
'Predicate filter object for query_rows. A predicate is a tree: {"all":[...]} (AND) or {"any":[...]} (OR); members are leaves {field, op, value} or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (use * as the wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array value. TTL filter values are absolute whole Unix epoch seconds, never milliseconds. Examples: {"all":[{"field":"status","op":"eq","value":"active"}]}; {"any":[{"field":"status","op":"eq","value":"active"},{"field":"status","op":"eq","value":"pending"}]}; {"all":[{"field":"name","op":"ilike","value":"*jo*"}]}.',
4222+
'Predicate filter object for query_rows. A predicate is a tree: {"all":[...]} (AND) or {"any":[...]} (OR); members are leaves {field, op, value} or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (use * as the wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array value. Examples: {"all":[{"field":"status","op":"eq","value":"active"}]}; {"any":[{"field":"status","op":"eq","value":"active"},{"field":"status","op":"eq","value":"pending"}]}; {"all":[{"field":"name","op":"ilike","value":"*jo*"}]}.',
42174223
},
42184224
limit: {
42194225
type: 'number',
@@ -5473,7 +5479,7 @@ export const TableColumns: ToolCatalogEntry = {
54735479
column: {
54745480
type: 'object',
54755481
description:
5476-
'Column definition for add_column: { name, type, unique?, position? }; type may be string, number, boolean, date, json, select, or ttl. Select (enum) columns also take { options: [names], multiple?: true } — options is required for select. A table may have at most one ttl column; adding it enables row expiration, with cell values stored as absolute whole Unix epoch seconds rather than milliseconds.',
5482+
'Column definition for add_column: { name, type, unique?, position? }; select (enum) columns also take { options: [names], multiple?: true } — options is required for select.',
54775483
},
54785484
columnName: {
54795485
type: 'string',
@@ -5494,7 +5500,7 @@ export const TableColumns: ToolCatalogEntry = {
54945500
newType: {
54955501
type: 'string',
54965502
description:
5497-
'New column type for update_column: string, number, boolean, date, json, select, ttl. Converting to select also requires options; conversion fails if an existing cell value matches no option. A multiple select round-trips through text as a comma-separated cell. Converting to ttl enables row expiration and fails if the table already has another ttl column; TTL values are absolute whole Unix epoch seconds, not milliseconds.',
5503+
'New column type for update_column: string, number, boolean, date, json, select. Converting to select also requires options; conversion fails if an existing cell value matches no option. A multiple select round-trips through text as a comma-separated cell.',
54985504
},
54995505
options: {
55005506
type: 'array',
@@ -5673,7 +5679,7 @@ export const TableManage: ToolCatalogEntry = {
56735679
schema: {
56745680
type: 'object',
56755681
description:
5676-
'Table schema with a columns array (required for create). Each column: { name, type, unique? }; types are string, number, boolean, date, json, select, and ttl. A select (enum) column also requires options (display names) and takes multiple?. A table may have at most one ttl column; adding it enables row expiration, with cell values stored as absolute whole Unix epoch seconds rather than milliseconds.',
5682+
'Table schema with a columns array (required for create). Each column: { name, type, unique? }; a select (enum) column also requires options (display names) and takes multiple?.',
56775683
},
56785684
tableId: {
56795685
type: 'string',
@@ -5719,12 +5725,12 @@ export const TableRows: ToolCatalogEntry = {
57195725
data: {
57205726
type: 'object',
57215727
description:
5722-
'Row data as column → value pairs (required for insert_row, update_row; the patch object for update_rows_by_filter). Select (enum) cells take the option NAME. TTL cells take absolute whole Unix epoch seconds, never JavaScript milliseconds. On insert_row, a missing or null TTL means no expiration. On update_row and update_rows_by_filter, omit the TTL to preserve its current value or set it to null to clear the expiration.',
5728+
'Row data as column → value pairs (required for insert_row, update_row; the patch object for update_rows_by_filter). Select (enum) cells take the option NAME.',
57235729
},
57245730
filter: {
57255731
type: 'object',
57265732
description:
5727-
'Predicate filter for update_rows_by_filter / delete_rows_by_filter: {"all":[...]} (AND) or {"any":[...]} (OR) of {field, op, value} leaves or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (* wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array. Single-select columns match by eq/ne/in/nin; multiple-select by contains/ncontains — values are option NAMES. TTL filter values are absolute whole Unix epoch seconds.',
5733+
'Predicate filter for update_rows_by_filter / delete_rows_by_filter: {"all":[...]} (AND) or {"any":[...]} (OR) of {field, op, value} leaves or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (* wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array. Single-select columns match by eq/ne/in/nin; multiple-select by contains/ncontains — values are option NAMES.',
57285734
},
57295735
limit: {
57305736
type: 'number',
@@ -5749,19 +5755,18 @@ export const TableRows: ToolCatalogEntry = {
57495755
},
57505756
rows: {
57515757
type: 'array',
5752-
description:
5753-
'Array of row data objects (required for batch_insert_rows). TTL cells take absolute whole Unix epoch seconds, never JavaScript milliseconds; a missing or null TTL means no expiration.',
5758+
description: 'Array of row data objects (required for batch_insert_rows)',
57545759
},
57555760
tableId: { type: 'string', description: 'Table ID (required for every operation)' },
57565761
updates: {
57575762
type: 'array',
57585763
description:
5759-
"Array of per-row updates: [{ rowId, data: { col: val } }] (batch_update_rows format a). TTL values are absolute whole Unix epoch seconds, never JavaScript milliseconds; omit a row's TTL key to preserve it or set it to null to clear the expiration.",
5764+
'Array of per-row updates: [{ rowId, data: { col: val } }] (batch_update_rows format a)',
57605765
},
57615766
values: {
57625767
type: 'object',
57635768
description:
5764-
"Map of rowId → value for single-column batch update (batch_update_rows format b, with columnName). For a TTL column, values are absolute whole Unix epoch seconds, never JavaScript milliseconds; set a row's value to null to clear its expiration, and omit the row from the map to leave it unchanged.",
5769+
'Map of rowId → value for single-column batch update (batch_update_rows format b, with columnName)',
57655770
},
57665771
},
57675772
required: ['tableId'],
@@ -6079,7 +6084,7 @@ export const UserTable: ToolCatalogEntry = {
60796084
column: {
60806085
type: 'object',
60816086
description:
6082-
'Column definition for add_column: { name, type, unique?, position? }. Type may be string, number, boolean, date, json, select, or ttl. For a select (enum) column also pass { options: ["Open", "Closed"], multiple?: true } — options is a list of display names and is required for select. A table may have at most one ttl column; adding it enables row expiration, with cell values stored as absolute whole Unix epoch seconds rather than milliseconds.',
6087+
'Column definition for add_column: { name, type, unique?, position? }. For a select (enum) column also pass { options: ["Open", "Closed"], multiple?: true } — options is a list of display names and is required for select.',
60836088
},
60846089
columnName: {
60856090
type: 'string',
@@ -6098,8 +6103,7 @@ export const UserTable: ToolCatalogEntry = {
60986103
},
60996104
data: {
61006105
type: 'object',
6101-
description:
6102-
'Row data as key-value pairs (required for insert_row, update_row). TTL cells take absolute whole Unix epoch seconds, never JavaScript milliseconds. On insert_row, a missing or null TTL means no expiration. On update_row, omit the TTL to preserve its current value or set it to null to clear the expiration.',
6106+
description: 'Row data as key-value pairs (required for insert_row, update_row)',
61036107
},
61046108
dependencies: {
61056109
type: 'object',
@@ -6128,7 +6132,7 @@ export const UserTable: ToolCatalogEntry = {
61286132
filter: {
61296133
type: 'object',
61306134
description:
6131-
'Predicate filter object for query_rows, update_rows_by_filter, delete_rows_by_filter. A predicate is a tree: {"all":[...]} (AND) or {"any":[...]} (OR); members are leaves {field, op, value} or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (use * as the wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array value. TTL filter values are absolute whole Unix epoch seconds, never milliseconds. Examples: {"all":[{"field":"status","op":"eq","value":"active"}]}; {"all":[{"field":"wins","op":"gte","value":18},{"field":"status","op":"eq","value":"pending"}]}; {"any":[{"field":"status","op":"eq","value":"active"},{"field":"status","op":"eq","value":"pending"}]}; {"all":[{"field":"name","op":"ilike","value":"*jo*"}]}; {"all":[{"field":"slack_user_id","op":"in","value":["U1","U2"]}]}.',
6135+
'Predicate filter object for query_rows, update_rows_by_filter, delete_rows_by_filter. A predicate is a tree: {"all":[...]} (AND) or {"any":[...]} (OR); members are leaves {field, op, value} or nested groups. Ops: eq, ne, gt, gte, lt, lte, in, nin, like, ilike (use * as the wildcard), nlike, nilike, contains, ncontains, startsWith, endsWith, isNull, isNotNull, isEmpty, isNotEmpty. in/nin take a non-empty array value. Examples: {"all":[{"field":"status","op":"eq","value":"active"}]}; {"all":[{"field":"wins","op":"gte","value":18},{"field":"status","op":"eq","value":"pending"}]}; {"any":[{"field":"status","op":"eq","value":"active"},{"field":"status","op":"eq","value":"pending"}]}; {"all":[{"field":"name","op":"ilike","value":"*jo*"}]}; {"all":[{"field":"slack_user_id","op":"in","value":["U1","U2"]}]}.',
61326136
},
61336137
groupId: {
61346138
type: 'string',
@@ -6217,7 +6221,7 @@ export const UserTable: ToolCatalogEntry = {
62176221
newType: {
62186222
type: 'string',
62196223
description:
6220-
'New column type (optional for update_column). Types: string, number, boolean, date, json, select, ttl. Converting a column to select also requires options; the conversion fails if any existing cell value doesn\'t match one of them. Converting to a multiple: true select also accepts a comma-separated cell ("Open, Urgent"), which is the form a multi column converts to text as — so multiselect → text → multiselect round-trips. Converting to ttl enables row expiration and fails if the table already has another ttl column; TTL values are absolute whole Unix epoch seconds, not milliseconds.',
6224+
'New column type (optional for update_column). Types: string, number, boolean, date, json, select. Converting a column to select also requires options; the conversion fails if any existing cell value doesn\'t match one of them. Converting to a multiple: true select also accepts a comma-separated cell ("Open, Urgent"), which is the form a multi column converts to text as — so multiselect → text → multiselect round-trips.',
62216225
},
62226226
options: {
62236227
type: 'array',
@@ -6295,8 +6299,7 @@ export const UserTable: ToolCatalogEntry = {
62956299
},
62966300
rows: {
62976301
type: 'array',
6298-
description:
6299-
'Array of row data objects (required for batch_insert_rows). TTL cells take absolute whole Unix epoch seconds, never JavaScript milliseconds; a missing or null TTL means no expiration.',
6302+
description: 'Array of row data objects (required for batch_insert_rows)',
63006303
},
63016304
runMode: {
63026305
type: 'string',
@@ -6307,7 +6310,7 @@ export const UserTable: ToolCatalogEntry = {
63076310
schema: {
63086311
type: 'object',
63096312
description:
6310-
'Table schema with columns array (required for \'create\'). Each column: { name, type, unique? }. Types are string, number, boolean, date, json, select, and ttl. A select (enum) column also takes { options: ["Open", "Closed"], multiple?: true } — options is a list of display names and is required for select. A table may have at most one ttl column; adding it enables row expiration, with cell values stored as absolute whole Unix epoch seconds rather than milliseconds.',
6313+
'Table schema with columns array (required for \'create\'). Each column: { name, type, unique? }. A select (enum) column also takes { options: ["Open", "Closed"], multiple?: true } — options is a list of display names and is required for select.',
63116314
},
63126315
scope: {
63136316
type: 'string',
@@ -6332,12 +6335,12 @@ export const UserTable: ToolCatalogEntry = {
63326335
updates: {
63336336
type: 'array',
63346337
description:
6335-
"Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows). TTL values are absolute whole Unix epoch seconds, never JavaScript milliseconds; omit a row's TTL key to preserve it or set it to null to clear the expiration.",
6338+
'Array of per-row updates: [{ rowId, data: { col: val } }] (for batch_update_rows)',
63366339
},
63376340
values: {
63386341
type: 'object',
63396342
description:
6340-
'Map of rowId to value for single-column batch update: { "rowId1": val1, "rowId2": val2 } (for batch_update_rows with columnName). For a TTL column, values are absolute whole Unix epoch seconds, never JavaScript milliseconds; set a row\'s value to null to clear its expiration, and omit the row from the map to leave it unchanged.',
6343+
'Map of rowId to value for single-column batch update: { "rowId1": val1, "rowId2": val2 } (for batch_update_rows with columnName)',
63416344
},
63426345
workflowId: {
63436346
type: 'string',
@@ -6740,6 +6743,7 @@ export const ManageSkillOperationValues = [
67406743
] as const
67416744

67426745
export const PrepareFileEditOperation = {
6746+
create: 'create',
67436747
append: 'append',
67446748
update: 'update',
67456749
patch: 'patch',
@@ -6749,6 +6753,7 @@ export type PrepareFileEditOperation =
67496753
(typeof PrepareFileEditOperation)[keyof typeof PrepareFileEditOperation]
67506754

67516755
export const PrepareFileEditOperationValues = [
6756+
PrepareFileEditOperation.create,
67526757
PrepareFileEditOperation.append,
67536758
PrepareFileEditOperation.update,
67546759
PrepareFileEditOperation.patch,

0 commit comments

Comments
 (0)