mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
127 lines
4.5 KiB
TypeScript
127 lines
4.5 KiB
TypeScript
import { createLogger } from '@sim/logger'
|
|
import { Loader2, Settings2, X, XCircle } from 'lucide-react'
|
|
import {
|
|
BaseClientTool,
|
|
type BaseClientToolMetadata,
|
|
ClientToolCallState,
|
|
} from '@/lib/copilot/tools/client/base-tool'
|
|
import { registerToolUIConfig } from '@/lib/copilot/tools/client/ui-config'
|
|
import { ExecuteResponseSuccessSchema } from '@/lib/copilot/tools/shared/schemas'
|
|
import { useEnvironmentStore } from '@/stores/settings/environment'
|
|
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
|
|
|
|
interface SetEnvArgs {
|
|
variables: Record<string, string>
|
|
workflowId?: string
|
|
}
|
|
|
|
export class SetEnvironmentVariablesClientTool extends BaseClientTool {
|
|
static readonly id = 'set_environment_variables'
|
|
|
|
constructor(toolCallId: string) {
|
|
super(
|
|
toolCallId,
|
|
SetEnvironmentVariablesClientTool.id,
|
|
SetEnvironmentVariablesClientTool.metadata
|
|
)
|
|
}
|
|
|
|
static readonly metadata: BaseClientToolMetadata = {
|
|
displayNames: {
|
|
[ClientToolCallState.generating]: {
|
|
text: 'Preparing to set environment variables',
|
|
icon: Loader2,
|
|
},
|
|
[ClientToolCallState.pending]: { text: 'Set environment variables?', icon: Settings2 },
|
|
[ClientToolCallState.executing]: { text: 'Setting environment variables', icon: Loader2 },
|
|
[ClientToolCallState.success]: { text: 'Set environment variables', icon: Settings2 },
|
|
[ClientToolCallState.error]: { text: 'Failed to set environment variables', icon: X },
|
|
[ClientToolCallState.aborted]: {
|
|
text: 'Aborted setting environment variables',
|
|
icon: XCircle,
|
|
},
|
|
[ClientToolCallState.rejected]: {
|
|
text: 'Skipped setting environment variables',
|
|
icon: XCircle,
|
|
},
|
|
},
|
|
interrupt: {
|
|
accept: { text: 'Apply', icon: Settings2 },
|
|
reject: { text: 'Skip', icon: XCircle },
|
|
},
|
|
uiConfig: {
|
|
alwaysExpanded: true,
|
|
interrupt: {
|
|
accept: { text: 'Apply', icon: Settings2 },
|
|
reject: { text: 'Skip', icon: XCircle },
|
|
showAllowOnce: true,
|
|
showAllowAlways: true,
|
|
},
|
|
paramsTable: {
|
|
columns: [
|
|
{ key: 'name', label: 'Variable', width: '36%', editable: true },
|
|
{ key: 'value', label: 'Value', width: '64%', editable: true, mono: true },
|
|
],
|
|
extractRows: (params) => {
|
|
const variables = params.variables || {}
|
|
const entries = Array.isArray(variables)
|
|
? variables.map((v: any, i: number) => [String(i), v.name || `var_${i}`, v.value || ''])
|
|
: Object.entries(variables).map(([key, val]) => {
|
|
if (typeof val === 'object' && val !== null && 'value' in (val as any)) {
|
|
return [key, key, (val as any).value]
|
|
}
|
|
return [key, key, val]
|
|
})
|
|
return entries as Array<[string, ...any[]]>
|
|
},
|
|
},
|
|
},
|
|
getDynamicText: (params, state) => {
|
|
if (params?.variables && typeof params.variables === 'object') {
|
|
const count = Object.keys(params.variables).length
|
|
const varText = count === 1 ? 'variable' : 'variables'
|
|
|
|
switch (state) {
|
|
case ClientToolCallState.success:
|
|
return `Set ${count} ${varText}`
|
|
case ClientToolCallState.executing:
|
|
return `Setting ${count} ${varText}`
|
|
case ClientToolCallState.generating:
|
|
return `Preparing to set ${count} ${varText}`
|
|
case ClientToolCallState.pending:
|
|
return `Set ${count} ${varText}?`
|
|
case ClientToolCallState.error:
|
|
return `Failed to set ${count} ${varText}`
|
|
case ClientToolCallState.aborted:
|
|
return `Aborted setting ${count} ${varText}`
|
|
case ClientToolCallState.rejected:
|
|
return `Skipped setting ${count} ${varText}`
|
|
}
|
|
}
|
|
return undefined
|
|
},
|
|
}
|
|
|
|
async handleReject(): Promise<void> {
|
|
await super.handleReject()
|
|
this.setState(ClientToolCallState.rejected)
|
|
}
|
|
|
|
async handleAccept(_args?: SetEnvArgs): Promise<void> {
|
|
// Tool execution is handled server-side by the orchestrator.
|
|
this.setState(ClientToolCallState.executing)
|
|
}
|
|
|
|
async execute(): Promise<void> {
|
|
// Tool execution is handled server-side by the orchestrator.
|
|
// Client tool classes are retained for UI display configuration only.
|
|
this.setState(ClientToolCallState.success)
|
|
}
|
|
}
|
|
|
|
// Register UI config at module load
|
|
registerToolUIConfig(
|
|
SetEnvironmentVariablesClientTool.id,
|
|
SetEnvironmentVariablesClientTool.metadata.uiConfig!
|
|
)
|