Skip to content

Commit f066fef

Browse files
committed
Merge remote-tracking branch 'origin/staging' into fix/provider-transport-defaults
# Conflicts: # apps/sim/app/api/guardrails/validate/route.ts # apps/sim/lib/guardrails/validate_hallucination.ts
2 parents 3e3e2b3 + c530d27 commit f066fef

835 files changed

Lines changed: 95935 additions & 7952 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/add-integration/SKILL.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: add-integration
3-
description: Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, and integration conventions. Use when introducing a new service under `apps/sim/tools`, `apps/sim/blocks`, and `apps/sim/triggers`.
3+
description: Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions. Use when introducing a new service under `apps/sim/tools`, `apps/sim/blocks`, and `apps/sim/triggers`.
44
argument-hint: <service-name> [api-docs-url]
55
---
66

@@ -122,6 +122,64 @@ export const {service}{Action}Tool: ToolConfig<Params, Response> = {
122122
- When using `type: 'json'` and you know the object shape, define `properties` with the inner fields so downstream consumers know the structure. Only use bare `type: 'json'` when the shape is truly dynamic
123123
- If you do not know the response JSON shape from docs or verified examples, you MUST tell the user and stop. Never guess outputs or response mappings.
124124

125+
### Resolved Secrets at Model and Persistence Boundaries
126+
127+
Classify every request field before implementing the tool:
128+
129+
This is opt-in, not a blanket integration migration. Add a model-input declaration only when the
130+
service's official documentation or an unambiguous local execution path proves that the exact
131+
field is consumed by an AI model. If that cannot be established, preserve existing tool behavior
132+
and leave the field unannotated.
133+
134+
- **Ordinary provider/API input:** leave it unchanged. Do not add blanket result sanitization.
135+
- **Text or structured content consumed by an AI model:** declare `request.modelInput` with
136+
`mode: 'project'` and select only the exact model-visible fields. The shared executor replaces
137+
activated Sim secrets with canonical `{{NAME}}` labels before request formatting. For nested or
138+
JSON-string fields, use a small shared selector plus `applyProjected`; verify that selecting the
139+
rebuilt params reproduces the projected selection.
140+
- **Opaque model input sent directly to an external provider** such as a model-read URL or image
141+
payload: declare `request.opaqueModelInput` with `mode: 'reject-resolved-secrets'` and select only
142+
the exact effective value. The shared `executeTool` preflight rejects incomplete or secret-bearing
143+
committed provenance before URL/body formatting or network I/O, preserves safe request bytes,
144+
and sends no provenance metadata to the provider.
145+
- **Opaque model input owned by an authenticated internal route** such as uploaded audio, image,
146+
video, file bytes, or signed URLs: add `privateProvenance` to a projected request, or use
147+
`mode: 'private-provenance'` when there is no textual projection. The route must call
148+
`validateOpaqueModelInputProvenance` before downloading or sending content to the model and must
149+
apply the workspace-file provenance guard before reading a persisted workspace file.
150+
- **Sim-owned durable storage or internal execution handoff** that can later enter a workflow/model
151+
(table cells, Agent memory, knowledge documents/chunks, workspace-file contents, or child-workflow
152+
input): transport encrypted field-scoped provenance with `request.secretProvenance`. The
153+
authenticated receiver validates the exact selection and scope, strips the private envelope, and
154+
persists, imports, or propagates it at the owning boundary. Preserve shared legacy behavior for
155+
headerless internal calls and rows/files whose provenance marker is `NULL`; never invent a
156+
tool-local migration rule.
157+
158+
Hard rules:
159+
160+
- Never substitute secret plaintext into source or serialize plaintext provenance.
161+
- Never hand-roll private provenance headers/envelopes; the shared `executeTool` boundary owns
162+
transport and strips private metadata from functional results.
163+
- Never attach private provenance to an external URL or to `directExecution`. Use the centralized
164+
`opaqueModelInput` rejection mode for external/direct opaque model inputs, or an authenticated
165+
internal route when encrypted provenance must cross the boundary.
166+
- Never sanitize arbitrary third-party tool results. Projection applies only to secrets activated
167+
by Sim's resolved-secret provenance for that execution/tool call.
168+
- Do not add provenance merely because a value is persisted, returned by a tool, or appears in a
169+
filename. Require a concrete Sim `{{...}}` resolution path and a later model/log boundary. If an
170+
unsupported field can resolve a secret but does not justify durable tracking (for example a
171+
`file_write` path), reject it at that exact ingress.
172+
- At diagnostic boundaries, project only values carrying execution-scoped provenance. Ordinary
173+
provider responses, filenames, URLs, and errors remain unchanged when Sim did not resolve a
174+
secret into them.
175+
176+
Add focused tests covering named projection, ordinary identical text without provenance, nested
177+
shape preservation, malformed/incomplete private metadata failing closed, centralized external
178+
opaque rejection before formatting/I/O without byte changes or metadata transport, headerless
179+
legacy requests, and absence of private metadata in the public tool result. For durable sinks, also
180+
cover legacy `NULL` markers, exact-empty new writes, tracked secret writes, stale/missing sidecars,
181+
and scope isolation.
182+
125183
## Step 3: Create Block
126184

127185
### File Location
@@ -535,6 +593,11 @@ If creating V2 versions (API-aligned outputs):
535593
- [ ] Created `index.ts` barrel export
536594
- [ ] Registered all tools in `tools/registry.ts`
537595
- [ ] Ran `bun run tool-metadata:generate` and committed the regenerated artifacts
596+
- [ ] Classified every model-visible, opaque, Sim-durable, and internal-execution request field
597+
- [ ] Added shared model-input projection, centralized opaque rejection, or private provenance only
598+
where required
599+
- [ ] Confirmed ordinary third-party tool results are not generically sanitized
600+
- [ ] Added provenance compatibility and fail-closed boundary tests where applicable
538601

539602
### Block
540603
- [ ] Created `blocks/blocks/{service}.ts`
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
name: add-managed-cli
3+
description: Add or upgrade a curated, immutable managed CLI for Sim Function sandboxes, including client-safe catalog metadata, a pinned server-only installation recipe, checksum and executable verification, provider compatibility, PATH propagation, content-addressed image identity, and tests. Use when adding a CLI to the Sandbox managed-CLI selector or changing an existing managed CLI version or recipe.
4+
---
5+
6+
# Add a Managed CLI
7+
8+
Add CLIs through the curated registry. Never turn this surface into arbitrary commands or package names: system packages already cover validated Debian/APT coordinates, while managed CLIs require immutable artifacts and reproducible recipes.
9+
10+
## Read First
11+
12+
Read these live sources before editing; do not copy their current entries into this skill:
13+
14+
1. `apps/sim/lib/execution/remote-sandbox/cli-tools.ts` — persisted IDs and client-safe metadata.
15+
2. `apps/sim/lib/execution/remote-sandbox/cli-tools.server.ts` — server-only recipes and recipe helpers.
16+
3. `apps/sim/lib/execution/remote-sandbox/cli-tools.test.ts` — catalog and supply-chain invariants.
17+
4. `apps/sim/lib/execution/remote-sandbox/cli-tools-boundary.test.ts` — client/server import boundary.
18+
5. `apps/sim/lib/execution/remote-sandbox/sandbox-spec.ts` — content-addressed hash inputs.
19+
20+
Read `resolve.ts` and `e2b.ts` only when changing provisioning mechanics. A normal catalog addition should not require UI, API, database, resolver, or provider edits; those paths derive from the registries.
21+
22+
Do not modify the dedicated Function base image or the separate Mothership Shell template for a normal managed CLI addition. Managed recipes layer on the Function base image. Do not change `MAX_SANDBOX_CLI_TOOLS` from ten unless the user separately requests a product-limit change.
23+
24+
## 1. Verify the Upstream Release
25+
26+
Use primary upstream release documentation and official artifacts. Establish all of the following before writing code:
27+
28+
- Exact version and stable Linux x86-64 artifact URL. Never use `latest`, mutable redirects, or an unversioned installer.
29+
- SHA-256 for the exact artifact. Prefer a publisher-signed checksum; otherwise download the official artifact and compute it independently.
30+
- Archive layout and the exact executable paths to install.
31+
- Noninteractive, credential-free verification commands for every advertised executable, normally version commands.
32+
- Required PATH entries under `/opt/sim-cli`.
33+
- E2B and Daytona compatibility. Default to both only when the same Linux recipe works on both.
34+
35+
When the user does not name a version, select the current stable upstream release from primary sources and state the exact version chosen. Do not silently choose a prerelease or infer a version from an unverified secondary source.
36+
37+
Reject curl-to-shell installers, `npm install`, `pip install`, distro package repositories, arbitrary user commands, and artifacts from unofficial mirrors. Never place credentials, tokens, login commands, or account configuration in an image recipe or build log; authentication is runtime-only.
38+
39+
## 2. Choose an Immutable ID
40+
41+
Use `<tool>@<upstream-version>-r<recipe-revision>`.
42+
43+
- New upstream version: append a new ID ending in `-r1`.
44+
- Recipe-only change for the same upstream version: append `-r2`, `-r3`, and so on.
45+
- Never mutate or delete an existing ID or recipe. Persisted sandboxes must continue resolving to the bytes and behavior they selected.
46+
- On upgrade, retain the old ID and recipe and set its metadata to `selectable: false`. Only the newest version keeps the public label selectable.
47+
48+
Before shipping the first upgrade for a tool family, verify that editing a sandbox cannot leave both the retired and replacement IDs selected. If the generic selector and API validation do not already replace or reject colliding versions, address that once at the generic registry boundary with focused UI and contract tests; never special-case the individual CLI or silently install two versions that expose the same executable.
49+
50+
Recipe identity includes the ID, revision, and SHA-256 in the sandbox image hash. Keeping old entries is what makes that identity reproducible rather than merely cache-busting.
51+
52+
## 3. Add Client-Safe Metadata
53+
54+
In `cli-tools.ts`:
55+
56+
1. Append the ID to `SANDBOX_CLI_TOOL_IDS` in the same order used by the metadata and recipe registries.
57+
2. Add a `SANDBOX_CLI_TOOLS` entry whose key and `id` exactly match.
58+
3. Provide a unique selectable `label`, concise `description`, existing `category`, and useful executable/vendor aliases in `searchTerms`.
59+
4. Add a category only when no existing category is accurate, then ensure it has at least one selectable entry.
60+
61+
Keep this file safe for client bundles. It must not contain artifact URLs, checksums, install commands, verification commands, PATH recipes, provider SDKs, or imports from `cli-tools.server.ts`.
62+
63+
The API enum and searchable grouped selector derive from this registry. Do not add parallel option arrays or route-local wire types.
64+
65+
## 4. Add the Server-Only Recipe
66+
67+
In `cli-tools.server.ts`, use the narrowest existing helper:
68+
69+
- `defineBinaryRecipe` for one downloaded binary.
70+
- `defineTarGzipRecipe` or `defineZipRecipe` for archives containing binaries.
71+
- `defineVerifiedRecipe` for a vendor archive or installer layout that needs explicit commands.
72+
- A direct typed entry only when the helpers cannot faithfully model the release.
73+
74+
Provide every field the recipe contract requires:
75+
76+
- Exact `version`, `artifactUrl`, `artifactName`, and lowercase 64-character `sha256`.
77+
- Every installed `executable` and a corresponding `verificationCommands` entry.
78+
- Deterministic extraction/install commands into `/opt/sim-cli`; quote fixed paths and clean temporary artifacts.
79+
- `pathEntries` when the executable is not installed into the helper's default `bin` directory.
80+
- `supportedProviders` only when it differs from the E2B-and-Daytona default.
81+
- `revision` when it differs from `1`; it must agree with the ID suffix.
82+
83+
Verification must prove the command is discoverable through `sandboxCliEnvironment`, not authenticate or contact a user account. Recipe commands run as root during both prebuilt image creation and runtime provisioning.
84+
85+
If the artifact host is new, add only the exact official hostname to the `officialHosts` allowlist in `cli-tools.test.ts`. Treat that as a supply-chain review, not a way to silence the test.
86+
87+
## 5. Preserve Generic Behavior
88+
89+
Confirm the existing generic paths remain sufficient:
90+
91+
- `sandboxCliToolRecipes` canonicalizes and resolves the recipe.
92+
- `sandboxCliEnvironment` propagates PATH to Python subprocesses, JavaScript subprocesses, and Shell.
93+
- E2B bakes the recipe into the custom image; runtime-strategy providers install it within the Function timeout.
94+
- CLI-only sandboxes remain buildable even with no language packages.
95+
- `hashSandboxSpec` includes recipe ID, revision, and checksum while preserving the legacy hash for an empty CLI list.
96+
- The settings selector derives groups and search aliases from client-safe metadata.
97+
98+
Do not special-case a CLI in those layers unless the registry contract cannot express a genuine provider requirement. Extend the registry contract generically when multiple CLIs need the same new behavior.
99+
100+
## 6. Test the Addition
101+
102+
Extend tests when the new entry introduces behavior not already covered:
103+
104+
- For every upgrade, add a regression proving the old ID and recipe remain resolvable but non-selectable, while the replacement ID is selectable.
105+
- Add important executable aliases to the table-driven search assertion.
106+
- Add a focused assertion for a multi-executable recipe, custom PATH, or restricted provider.
107+
- Add an opt-in credentialed smoke test only when installation plus a real minimal command cannot be validated without authentication. Read credentials from test-only environment variables, skip by default, create them only at runtime, and always tear down the sandbox.
108+
109+
Never commit downloaded artifacts or credentials.
110+
111+
## Required Validation
112+
113+
From `apps/sim`:
114+
115+
```bash
116+
bunx vitest run \
117+
lib/execution/remote-sandbox/cli-tools.test.ts \
118+
lib/execution/remote-sandbox/cli-tools-boundary.test.ts \
119+
lib/execution/remote-sandbox/sandbox-spec.test.ts \
120+
lib/execution/remote-sandbox/resolve.test.ts \
121+
lib/api/contracts/sandboxes.test.ts \
122+
'app/workspace/[workspaceId]/settings/components/sandboxes/utils.test.ts' \
123+
'app/workspace/[workspaceId]/settings/components/sandboxes/components/sandbox-editor.test.tsx'
124+
```
125+
126+
From the repository root:
127+
128+
```bash
129+
bun run type-check
130+
bun run check:api-validation
131+
bunx biome check \
132+
apps/sim/lib/execution/remote-sandbox/cli-tools.ts \
133+
apps/sim/lib/execution/remote-sandbox/cli-tools.server.ts \
134+
apps/sim/lib/execution/remote-sandbox/cli-tools.test.ts
135+
git diff --check
136+
```
137+
138+
For a new recipe, also exercise its install and every verification command in an actual E2B or Daytona sandbox when credentials and network access are available. Report clearly when only registry/unit validation ran.
139+
140+
## Completion Checklist
141+
142+
- [ ] Official immutable Linux x86-64 artifact and SHA-256 verified.
143+
- [ ] Versioned ID appended; old IDs and recipes retained.
144+
- [ ] Client metadata is searchable, categorized, unique, and recipe-free.
145+
- [ ] Server recipe is pinned, integrity-checked, noninteractive, and credential-free.
146+
- [ ] Every advertised executable has an offline verification command and PATH entry.
147+
- [ ] Provider compatibility is explicit and accurate.
148+
- [ ] Catalog, boundary, hash, resolver, type, API-validation, format, and diff checks pass.
149+
- [ ] Real provider installation was tested, or the missing live verification is disclosed.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
interface:
2+
display_name: "Add Managed CLI"
3+
short_description: "Add a verified CLI to sandbox images"
4+
default_prompt: "Use $add-managed-cli to add a pinned, verified CLI to Sim sandbox images."

.agents/skills/add-tools/SKILL.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ export const {serviceName}{Action}Tool: ToolConfig<
145145
- Always explicitly set `required: true` or `required: false`
146146
- Optional params should have `required: false`
147147

148+
## Resolved Secrets and Provenance Boundaries
149+
150+
- Leave ordinary external API inputs and third-party results unchanged. Add provenance handling only
151+
when an exact field is proven to cross a Sim model, durable-storage, or internal-execution boundary.
152+
- Project AI-consumed text/structured fields with the smallest exact `request.modelInput` selector.
153+
- Reject resolved secrets in opaque model input sent directly to an external provider with
154+
`request.opaqueModelInput`; never attach private metadata to an external URL or `directExecution`.
155+
- For authenticated internal routes, use `privateProvenance` for opaque model input or
156+
`request.secretProvenance` for durable writes and execution handoffs. Authenticate first, validate
157+
the exact selection and scope, strip the private envelope, then import or propagate provenance at
158+
the receiving boundary. Preserve documented headerless legacy behavior.
159+
- Never substitute secret plaintext into source, serialize plaintext provenance, hand-roll private
160+
headers, or blanket-sanitize tool results.
161+
- Add focused tests for named projection, identical unproven public text, malformed/incomplete
162+
metadata, metadata stripping, scope isolation, and legacy compatibility where applicable.
163+
148164
## Critical Rules for Outputs
149165

150166
### Output Types
@@ -456,6 +472,9 @@ All tool IDs MUST use `snake_case`: `{service}_{action}` (e.g., `x_create_tweet`
456472
- [ ] Tools registered in `tools/registry.ts`
457473
- [ ] `bun run tool-metadata:generate` run and the regenerated artifacts committed
458474
- [ ] Block wired: `tools.access`, dropdown options, subBlocks, `tools.config`, outputs, inputs
475+
- [ ] Model, durable-storage, and internal-execution boundaries use the shared provenance mechanisms
476+
only where a concrete Sim `{{...}}` resolution path requires them
477+
- [ ] Ordinary third-party inputs/results remain unchanged and private metadata never leaves Sim
459478

460479
## Final Validation (Required)
461480

0 commit comments

Comments
 (0)