Skip to content

Commit 4593a8a

Browse files
committed
Table tools
1 parent 301fdb9 commit 4593a8a

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

apps/sim/lib/copilot/tools/server/router.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ const WRITE_ACTIONS: Record<string, string[]> = {
4646
'delete_row',
4747
'update_rows_by_filter',
4848
'delete_rows_by_filter',
49+
'add_column',
50+
'rename_column',
51+
'delete_column',
52+
'update_column',
4953
],
5054
manage_custom_tool: ['add', 'edit', 'delete'],
5155
manage_mcp_tool: ['add', 'edit', 'delete'],

apps/sim/lib/copilot/tools/server/table/user-table.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ import { createLogger } from '@sim/logger'
22
import type { BaseServerTool, ServerToolContext } from '@/lib/copilot/tools/server/base-tool'
33
import type { UserTableArgs, UserTableResult } from '@/lib/copilot/tools/shared/schemas'
44
import {
5+
addTableColumn,
56
batchInsertRows,
67
createTable,
8+
deleteColumn,
79
deleteRow,
810
deleteRowsByFilter,
911
deleteTable,
1012
getRowById,
1113
getTableById,
1214
insertRow,
1315
queryRows,
16+
renameColumn,
17+
updateColumnConstraints,
18+
updateColumnType,
1419
updateRow,
1520
updateRowsByFilter,
1621
} from '@/lib/table/service'
@@ -637,6 +642,113 @@ export const userTableServerTool: BaseServerTool<UserTableArgs, UserTableResult>
637642
}
638643
}
639644

645+
case 'add_column': {
646+
if (!args.tableId) {
647+
return { success: false, message: 'Table ID is required' }
648+
}
649+
const col = (args as Record<string, unknown>).column as
650+
| {
651+
name: string
652+
type: string
653+
required?: boolean
654+
unique?: boolean
655+
position?: number
656+
}
657+
| undefined
658+
if (!col?.name || !col?.type) {
659+
return {
660+
success: false,
661+
message: 'column with name and type is required for add_column',
662+
}
663+
}
664+
const requestId = crypto.randomUUID().slice(0, 8)
665+
const updated = await addTableColumn(args.tableId, col, requestId)
666+
return {
667+
success: true,
668+
message: `Added column "${col.name}" (${col.type}) to table`,
669+
data: { schema: updated.schema },
670+
}
671+
}
672+
673+
case 'rename_column': {
674+
if (!args.tableId) {
675+
return { success: false, message: 'Table ID is required' }
676+
}
677+
const colName = (args as Record<string, unknown>).columnName as string | undefined
678+
const newColName = (args as Record<string, unknown>).newName as string | undefined
679+
if (!colName || !newColName) {
680+
return { success: false, message: 'columnName and newName are required' }
681+
}
682+
const requestId = crypto.randomUUID().slice(0, 8)
683+
const updated = await renameColumn(
684+
{ tableId: args.tableId, columnName: colName, newName: newColName },
685+
requestId
686+
)
687+
return {
688+
success: true,
689+
message: `Renamed column "${colName}" to "${newColName}"`,
690+
data: { schema: updated.schema },
691+
}
692+
}
693+
694+
case 'delete_column': {
695+
if (!args.tableId) {
696+
return { success: false, message: 'Table ID is required' }
697+
}
698+
const colName = (args as Record<string, unknown>).columnName as string | undefined
699+
if (!colName) {
700+
return { success: false, message: 'columnName is required' }
701+
}
702+
const requestId = crypto.randomUUID().slice(0, 8)
703+
const updated = await deleteColumn(
704+
{ tableId: args.tableId, columnName: colName },
705+
requestId
706+
)
707+
return {
708+
success: true,
709+
message: `Deleted column "${colName}"`,
710+
data: { schema: updated.schema },
711+
}
712+
}
713+
714+
case 'update_column': {
715+
if (!args.tableId) {
716+
return { success: false, message: 'Table ID is required' }
717+
}
718+
const colName = (args as Record<string, unknown>).columnName as string | undefined
719+
if (!colName) {
720+
return { success: false, message: 'columnName is required' }
721+
}
722+
const newType = (args as Record<string, unknown>).newType as string | undefined
723+
const reqFlag = (args as Record<string, unknown>).required as boolean | undefined
724+
const uniqFlag = (args as Record<string, unknown>).unique as boolean | undefined
725+
if (newType === undefined && reqFlag === undefined && uniqFlag === undefined) {
726+
return {
727+
success: false,
728+
message: 'At least one of newType, required, or unique must be provided',
729+
}
730+
}
731+
const requestId = crypto.randomUUID().slice(0, 8)
732+
let result: TableDefinition | undefined
733+
if (newType !== undefined) {
734+
result = await updateColumnType(
735+
{ tableId: args.tableId, columnName: colName, newType },
736+
requestId
737+
)
738+
}
739+
if (reqFlag !== undefined || uniqFlag !== undefined) {
740+
result = await updateColumnConstraints(
741+
{ tableId: args.tableId, columnName: colName, required: reqFlag, unique: uniqFlag },
742+
requestId
743+
)
744+
}
745+
return {
746+
success: true,
747+
message: `Updated column "${colName}"`,
748+
data: { schema: result?.schema },
749+
}
750+
}
751+
640752
default:
641753
return { success: false, message: `Unknown operation: ${operation}` }
642754
}

apps/sim/lib/copilot/tools/shared/schemas.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ export const UserTableArgsSchema = z.object({
113113
'delete_row',
114114
'update_rows_by_filter',
115115
'delete_rows_by_filter',
116+
'add_column',
117+
'rename_column',
118+
'delete_column',
119+
'update_column',
116120
]),
117121
args: z
118122
.object({
@@ -128,6 +132,20 @@ export const UserTableArgsSchema = z.object({
128132
limit: z.number().optional(),
129133
offset: z.number().optional(),
130134
filePath: z.string().optional(),
135+
column: z
136+
.object({
137+
name: z.string(),
138+
type: z.string(),
139+
required: z.boolean().optional(),
140+
unique: z.boolean().optional(),
141+
position: z.number().optional(),
142+
})
143+
.optional(),
144+
columnName: z.string().optional(),
145+
newName: z.string().optional(),
146+
newType: z.string().optional(),
147+
required: z.boolean().optional(),
148+
unique: z.boolean().optional(),
131149
})
132150
.optional(),
133151
})

0 commit comments

Comments
 (0)