Skip to content

Commit b6f3cce

Browse files
committed
feat(copilot): expose sandbox capability catalog in VFS
1 parent 8b4e5f0 commit b6f3cce

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

apps/sim/lib/copilot/vfs/serializers.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
* @vitest-environment node
33
*/
44
import { describe, expect, it } from 'vitest'
5+
import {
6+
MAX_SANDBOX_CLI_TOOLS,
7+
SANDBOX_CLI_TOOLS,
8+
SANDBOX_SELECTABLE_CLI_TOOL_IDS,
9+
} from '@/lib/execution/remote-sandbox/cli-tools'
510
import type { BlockConfig } from '@/blocks/types'
611
import { hostedKeyEnabledWhen } from '@/tools/hosting'
712
import type { ToolConfig } from '@/tools/types'
@@ -14,6 +19,7 @@ import {
1419
serializeIntegrationSchema,
1520
serializeKBMeta,
1621
serializeSandbox,
22+
serializeSandboxCatalog,
1723
serializeTableMeta,
1824
serializeWorkflowMeta,
1925
} from './serializers'
@@ -155,6 +161,19 @@ describe('VFS metadata serializers', () => {
155161
cliTools: ['kubectl@1.36.3-r1'],
156162
})
157163
})
164+
165+
it('generates the sandbox capability reference from the authoritative CLI registry', () => {
166+
const reference = serializeSandboxCatalog('prebuilt')
167+
168+
expect(reference).toContain('Active dependency strategy: `prebuilt`')
169+
expect(reference).toContain(`accepts at most ${MAX_SANDBOX_CLI_TOOLS} exact pinned ids`)
170+
for (const id of SANDBOX_SELECTABLE_CLI_TOOL_IDS) {
171+
const tool = SANDBOX_CLI_TOOLS[id]
172+
expect(reference).toContain(`\`${id}\``)
173+
expect(reference).toContain(tool.label)
174+
expect(reference).toContain(tool.description)
175+
}
176+
})
158177
})
159178

160179
describe('entitlement-projected block schemas', () => {

apps/sim/lib/copilot/vfs/serializers.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import {
66
getServiceAccountConnectNoun,
77
getServiceAccountGatingBlockType,
88
} from '@/lib/credentials/service-account-provider-ids'
9+
import {
10+
MAX_SANDBOX_CLI_TOOLS,
11+
SANDBOX_CLI_TOOLS,
12+
SANDBOX_SELECTABLE_CLI_TOOL_IDS,
13+
} from '@/lib/execution/remote-sandbox/cli-tools'
914
import { type FilterFieldType, getOperatorsForFieldType } from '@/lib/knowledge/filters/types'
1015
import { getServiceAccountProviderForProviderId } from '@/lib/oauth/utils'
1116
import { isSubBlockHidden } from '@/lib/workflows/subblocks/visibility'
@@ -1001,6 +1006,39 @@ export function serializeSandbox(sandbox: Sandbox, strategy: 'prebuilt' | 'runti
10011006
)
10021007
}
10031008

1009+
/**
1010+
* Generate the authoritative Sim-sandbox capability reference exposed in VFS.
1011+
* The managed-CLI rows come directly from the same client-safe registry used by
1012+
* validation and the settings UI, so adding or upgrading a CLI updates agent
1013+
* discovery without a second hand-maintained list.
1014+
*/
1015+
export function serializeSandboxCatalog(strategy: 'prebuilt' | 'runtime'): string {
1016+
const rows = SANDBOX_SELECTABLE_CLI_TOOL_IDS.map((id) => {
1017+
const tool = SANDBOX_CLI_TOOLS[id]
1018+
const aliases = tool.searchTerms?.join(', ') || '(none)'
1019+
return `| \`${tool.id}\` | ${tool.label} | ${tool.category} | ${tool.description} | ${aliases} |`
1020+
})
1021+
1022+
return [
1023+
'# Sim Sandbox Capabilities',
1024+
'',
1025+
'This file is generated from the active Sim sandbox registry. Treat it as the authoritative catalog; do not guess or reuse managed CLI ids from memory.',
1026+
'',
1027+
`- Active dependency strategy: \`${strategy}\``,
1028+
'- Dependency languages: `javascript` installs npm packages; `python` installs PyPI packages. Shell execution may select either language.',
1029+
'- `systemPackages` accepts Debian package coordinates in `package[:architecture][=version]` form.',
1030+
`- \`cliTools\` accepts at most ${MAX_SANDBOX_CLI_TOOLS} exact pinned ids from the catalog below.`,
1031+
'- A Sim sandbox may combine language dependencies, Debian system packages, and managed CLIs.',
1032+
'',
1033+
'## Managed CLI catalog',
1034+
'',
1035+
'| Exact id | Name | Category | What it provides | Search terms / executables |',
1036+
'|----------|------|----------|------------------|----------------------------|',
1037+
...rows,
1038+
'',
1039+
].join('\n')
1040+
}
1041+
10041042
/**
10051043
* Serialize an integration/tool schema for VFS components/integrations/{service}/{operation}.json
10061044
*/

apps/sim/lib/copilot/vfs/workspace-vfs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import {
8484
serializeMcpServer,
8585
serializeRecentExecutions,
8686
serializeSandbox,
87+
serializeSandboxCatalog,
8788
serializeSkill,
8889
serializeTableMeta,
8990
serializeTaskChat,
@@ -538,6 +539,7 @@ function getStaticComponentFiles(): Map<string, string> {
538539
* tasks/{title}/session.md
539540
* tasks/{title}/chat.json
540541
* custom-tools/{name}.json
542+
* agent/sandboxes/README.md
541543
* agent/sandboxes/{name}.json
542544
* environment/credentials.json
543545
* environment/api-keys.json
@@ -2179,6 +2181,7 @@ export class WorkspaceVFS {
21792181
try {
21802182
const sandboxes = await listWorkspaceSandboxes(workspaceId)
21812183
const strategy = currentSandboxStrategy()
2184+
this.files.set('agent/sandboxes/README.md', serializeSandboxCatalog(strategy))
21822185
for (const sandbox of sandboxes) {
21832186
this.files.set(
21842187
`agent/sandboxes/${sanitizeName(sandbox.name)}.json`,

0 commit comments

Comments
 (0)