Skip to content

Commit bd22424

Browse files
feat(tool-exec): add a run-tool skill for direct integration tool calls
2 parents a00ba8d + 442fb58 commit bd22424

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

‎scripts/validate-skills.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const expectedSkillNames = [
1414
"build-workflow",
1515
"deploy-workflow",
1616
"knowledge-base",
17+
"run-tool",
1718
"run-workflow",
1819
"table",
1920
] as const;

‎skills/build-workflow/SKILL.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ description: Create or modify Sim workflows through the sim CLI. Use when transl
88
Build the smallest valid graph that satisfies the request, using the Sim CLI as the source of truth
99
for available resources and accepted shapes.
1010

11+
A request that is one action against one connected service needs no graph at all — call the tool
12+
directly with `sim tools execute` (see the `run-tool` skill). Build a workflow when the task needs
13+
more than one call, branching, or a schedule.
14+
1115
## Establish context
1216

1317
- Use the profile the user named. If none was named, inspect configured profiles and current context;

‎skills/run-tool/SKILL.md‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
name: run-tool
3+
description: Call one Sim integration tool directly through the sim CLI, using credentials Sim already holds. Use for a single action against a connected service — send a message, create an issue, scrape a page; not for multi-step logic or anything scheduled, which belongs in a workflow.
4+
---
5+
6+
# Run a Sim Integration Tool
7+
8+
Sim holds the credentials. Read what the tool declares, bind auth from that declaration, and run it.
9+
Never put a live credential in the command.
10+
11+
## Preflight
12+
13+
- `tools execute` requires a personal API-key profile; a workspace API key is refused.
14+
- Find the tool with `sim --output json tools list --search <term>`, then read it with
15+
`sim --output json tools get <toolId>`. Never guess a tool id or a parameter name.
16+
- An unversioned name resolves to the newest version visible in the workspace, and the response
17+
echoes the id that answered. Use that id in the call.
18+
19+
## Bind auth from the declaration, not from habit
20+
21+
`tools get` labels every parameter with a `visibility`, and the label says where its value comes
22+
from:
23+
24+
- `user-or-llm` — you supply it in `--input`.
25+
- `user-only` — you supply it, but pass a reference instead of the secret: `{{VAR_NAME}}` as the
26+
whole value, resolved server-side. List the available names with
27+
`sim --output json secrets list`; values are never returned. Any other value is sent verbatim.
28+
One exception: a parameter named `credential` or `oauthCredential` is the credential selector,
29+
not a secret — see below. It is refused in `--input`.
30+
- `hidden` — Sim fills it. Never put it in `--input`; it is refused.
31+
32+
Then bind the credential by the tool's own shape:
33+
34+
- The tool declares `oauth.required`, **or** declares a required `credential` or `oauthCredential`
35+
parameter (Snowflake and others do the latter, with no `oauth` block) — find the credential with
36+
`sim --output json credentials list --provider-id <provider>` and pass `--credential-id`. It is
37+
the one place a credential is named; Sim places it where the tool expects it. Omitting it fails
38+
naming `credentialId`; putting it in `--input` under any spelling is refused.
39+
- `hostedApiKey` is `always`, or `conditional` and this call matches — omit the key entirely; Sim
40+
supplies its own and bills the workspace.
41+
- Otherwise the tool takes its own `user-only` key parameter; pass a `{{VAR_NAME}}` reference.
42+
43+
`--input` accepts exactly what `tools get` publishes as yours to send. An undeclared key, a
44+
`hidden` one, or a credential under any name is a `400` that names the offending field — read
45+
it rather than guessing at a spelling.
46+
47+
## Run and read the outcome
48+
49+
```bash
50+
sim --output json tools execute <toolId> --credential-id <id> --input '{"...": "..."}'
51+
```
52+
53+
`--input` also accepts `@path` or `@-`, which is how a payload too large or too awkward to quote
54+
reaches the command.
55+
56+
A tool that ran and refused exits non-zero with `status: "failed"` and the reason in `error.message`:
57+
the call reached the service and the service declined. Report that reason. A `403` carrying
58+
`error.details.code` `INTEGRATION_NOT_ALLOWED` is a workspace policy decision, not a fixable
59+
argument — say so and stop.
60+
61+
## Invariants
62+
63+
- Never print a resolved secret, an OAuth token, or a profile credential. You hold a credential id
64+
and a variable name; that is all the call needs.
65+
- Do not retry a failed write blind. A tool call is not idempotent, and a retry can duplicate the
66+
message, issue, or record the first attempt created.
67+
- Build a workflow instead when the task needs more than one call, branching, or a schedule.

0 commit comments

Comments
 (0)