You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
improvement(tools): route internal API calls through one declarative primitive
Calls to Sim's own API were identified by inspecting the resolved URL string for
an /api/ prefix, in two separate transports. Both now take an internalRoute
template: the route comes from a source literal, interpolated ids are encoded,
and query params go through withQuery. Static config strings stay as they are.
Copy file name to clipboardExpand all lines: .claude/rules/sim-integrations.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,7 @@ The full authoring instructions — tool/block/icon/trigger scaffolding, SubBloc
14
14
## Hard rules (don't get these wrong)
15
15
16
16
- Tool IDs are `snake_case` (`service_action`). Register tools in `tools/registry.ts`, blocks in `blocks/registry-maps.ts` (the `BLOCK_REGISTRY` config map + `BLOCK_META_REGISTRY` catalog-meta map, alphabetically — `blocks/registry.ts` holds only the accessor functions), triggers in `triggers/registry.ts`.
17
+
- A tool that calls Sim's own API declares it: a static `request.url` string (`'/api/tools/{service}/{action}'`), or `` internalRoute`/api/table/${params.tableId}/rows` `` from `@/tools/internal-route` when the path is dynamic (query params via `.withQuery({...})`). The transport signs internal requests with the executing user's token, so that decision follows the tool's source, never the resolved string — a builder returning a bare `/api/...` string is treated as EXTERNAL, because a `user-or-llm` param can produce one. `internalRoute` encodes every `${...}`; never add `encodeURIComponent` inside the template.
17
18
- Type coercions (`Number()`, etc.) belong in `tools.config.params` (runs at execution, after variable resolution) — never in `tools.config.tool` (runs at serialization; coercing there destroys dynamic `<Block.output>` references).
18
19
-`canonicalParamId` must NOT match any subblock's `id`, must be unique **block-wide** (groups are keyed by canonical id across every subblock and hold exactly one `basicId`, so two operations that each need a pair need two different canonical ids), and all subblocks in a canonical group must share the same `required` status. The `inputs` section and the params function reference canonical IDs, not raw subblock IDs — the serializer deletes the subblock IDs and republishes the active member's value under the canonical ID.
19
20
- A canonical pair carries ONE concept. For files that is upload (basic) + file reference (advanced), as in Gmail attachments (`blocks/blocks/gmail.ts`). Never overload the advanced side with alternate identifiers (URL, provider asset ID) — give those their own subblocks, mark mutually exclusive sources `required: false`, and enforce "exactly one" at execution.
0 commit comments