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
{{ message }}
Repository navigation
Commit 9aa3bcb
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: .agents/skills/add-column-type/SKILL.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -98,7 +98,7 @@ The three that are easy to get wrong:
98
98
99
99
Add the entry to `COLUMN_TYPE_REGISTRY` in `registry.ts`**and**`COLUMN_TYPE_SERVER_REGISTRY` in `registry.server.ts`.
100
100
101
-
`COLUMN_TYPES` is declared in `types.ts` (not derived from the registry — the registry is annotated `Record<ColumnType, …>` against it, which is the gate). `constants.ts` re-exports it, so `columnTypeSchema = z.enum(COLUMN_TYPES)` picks your type up with no edit. **Type-specific metadata does not** — see the next step.
101
+
`COLUMN_TYPES` is declared in `types.ts` (not derived from the registry — the registry is annotated `Record<ColumnType, …>` against it, which is the gate). `columnTypeSchema` in `lib/api/contracts/tables.ts` is `z.enum(COLUMN_TYPES)`, so it picks your type up with no edit. **Type-specific metadata does not** — see the next step.
102
102
103
103
## Step 5: Migrations (only if the stored bytes change)
104
104
@@ -131,6 +131,7 @@ Registering the *type* is compiler-enforced. Registering its *metadata* is not,
131
131
|`lib/table/types.ts``ColumnDefinition`| (this one DOES fail — the ownership loop indexes it) |
132
132
|`column-types/types.ts``TYPE_SPECIFIC_COLUMN_KEYS`| it is never stripped on conversion, and poisons the target type |
133
133
|`lib/api/contracts/tables.ts` — the schema slot in all three column schemas, plus `refineColumnOptions`| zod strips it at the boundary; silently never saved |
134
+
|`lib/api/contracts/v2/tables.ts` and `lib/table/application/columns.ts` — the same slots for the v2 API and its use cases | the v2 API silently drops it |
134
135
|`columns/service.ts``addTableColumn` param type | callers cannot pass it |
135
136
| A metadata-only update in `lib/table/columns/service.ts` (`updateColumnCurrency` is the model) + a branch in `performUpdateTableColumn` in `lib/table/orchestration/columns.ts`| changing it on an existing column is a silent 200 no-op |
Copy file name to clipboardExpand all lines: .agents/skills/add-enrichment/SKILL.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,7 +37,7 @@ For each output the enrichment produces, decide which existing tool provides it.
37
37
- Its `params` accept what you can derive from table columns (read the tool's `params`).
38
38
- Its `outputs` / `transformResponse` actually expose the field you need (read the real output shape — don't assume).
39
39
40
-
Order providers **cheapest / most-likely-to-hit first**; the cascade stops at the first non-empty result. Apollo / LinkedIn are not hosted-safe (ToS) — don't use them.
40
+
Order providers **cheapest / most-likely-to-hit first**; the cascade stops at the first non-empty result. Apollo and LinkedIn APIs are not hosted-safe (ToS) — never call them as providers.
41
41
42
42
## Step 2: Verify hosted-key support — chain to `/add-hosted-key` if missing
43
43
@@ -109,7 +109,7 @@ export { myEnrichment } from './my-enrichment'
109
109
```
110
110
111
111
Rules:
112
-
- Keep the file **client-safe**: import only `@sim/emcn/icons`, `@sim/utils/*`, `@/enrichments/providers`, and the types. **Never import `@/tools`** here — the runner does the tool call.
112
+
- Keep the file **client-safe**: import only `@sim/emcn/icons`, `@sim/utils/*`, `@/enrichments/providers`, `@/enrichments/provider-failures/*`, and the types. **Never import `@/tools`** here — the runner does the tool call.
113
113
-`buildParams` returns `null` when inputs are insufficient (provider skipped). `mapOutput` returns `null`/empty for a miss (falls through). Use `filterUndefined` when assembling optional tool params; coerce numbers explicitly (don't pass `''` to number outputs).
114
114
- Output `id`s are the keys `mapOutput` returns; output `name`s are the default column names (the user can rename them in the config).
Copy file name to clipboardExpand all lines: .agents/skills/add-hosted-key/SKILL.md
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -154,6 +154,20 @@ pricing: {
154
154
155
155
**`getCost` must always throw** if it cannot determine cost. Never silently fall back to a default — this would hide billing inaccuracies.
156
156
157
+
**When the provider charges a flat price per call** — use `per_request` instead of `getCost` (as `tools/brandfetch/get_brand.ts` does):
158
+
159
+
```typescript
160
+
pricing: {
161
+
type: 'per_request',
162
+
// $0.04 per call — from https://example.com/pricing
163
+
cost: 0.04,
164
+
},
165
+
```
166
+
167
+
### Hosted Keys for Some Parameter Combinations
168
+
169
+
When only some calls can use the hosted key (for example, one provider of several), gate the config with `enabled: hostedKeyEnabledWhen<Params>({ field: 'provider', operator: 'equals', value: 'falai' })` from `@/tools/hosting` (`operator: 'one_of'` takes `values`); `tools/image/generate.ts` is the reference.
170
+
157
171
### Capturing Cost Data from the API
158
172
159
173
If the API returns cost info, capture it in `transformResponse` so `getCost` can read it from the output:
Copy file name to clipboardExpand all lines: .agents/skills/add-model/SKILL.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,13 +49,13 @@ Use a precise WebFetch prompt: *"Extract for {model_id}: exact model id string,
49
49
|---|---|---|
50
50
|`temperature`| All providers (passed through if set) | Safe but inert on always-reasoning models that reject it |
51
51
|`toolUsageControl`| All providers (provider-level default) | Override per model only when that model differs |
52
-
|`forcedToolUse`|`anthropic/core.ts` (anthropic, azure-anthropic, kie); defaults to `toolUsageControl`| Ignored by every other provider; set `false` only on a model behind that core that cannot force tools |
52
+
|`forcedToolUse`|`anthropic/core.ts` (anthropic, azure-anthropic, kie) defaults it to `toolUsageControl`and reads `thinking.forcedToolUse` for forcing while thinking; `openai/core.ts` and `bedrock/index.ts` treat only an explicit `false` as "cannot force" | Ignored by every other provider; set `false` only on a model that cannot force tools |
53
53
|`promptCaching`| Caller-placed cache breakpoints | Set only where the vendor charges for opt-in caching (absent for OpenAI/Gemini implicit caching) |
54
54
|`reasoningEffort`|`openai/core.ts`, `azure-openai`, `xai`, `deepseek`, `groq`, `zai`, `kimi`, `cerebras`, `meta`, `litellm` (each `index.ts`) | Not read by anthropic/gemini (they use `thinking`) or by mistral, openrouter, fireworks, vertex — re-grep before assuming |
55
55
|`verbosity`|`openai/core.ts`, `azure-openai/index.ts` only | Dead elsewhere |
56
56
|`thinking`|`anthropic/core.ts`, `gemini/core.ts`; `deepseek`, `groq`, `zai`, `kimi` (each `index.ts`) read the resolved `thinkingLevel`| Dead elsewhere |
57
57
|`thinking.streamed`| Docs generator + `getThinkingStreamVisibility` (`models.ts`); `anthropic/core.ts` uses `'summary'` to request `display: 'summarized'` on agent-events runs |**Mandatory on Anthropic-family thinking models** (`check:agent-stream-docs` fails without it); other families fall back to provider defaults |
58
-
|`nativeStructuredOutputs`|`anthropic/core.ts`, `bedrock/index.ts` (via `models.ts``supportsNativeStructuredOutputs`, which reads the flag) | Dead elsewhere — fireworks/baseten/together/openrouter call their own provider-level `supportsNativeStructuredOutputs` that ignores the model flag (always on, always off, or OpenRouter API metadata) |
58
+
|`nativeStructuredOutputs`|`anthropic/core.ts`, `bedrock/index.ts` (via `models.ts``supportsNativeStructuredOutputs`, which reads the flag), `nebius/index.ts`, `nvidia/index.ts` (via `getModelCapabilities`)| Dead elsewhere — fireworks/baseten/together/openrouter call their own provider-level `supportsNativeStructuredOutputs` that ignores the model flag (always on, always off, or OpenRouter API metadata) |
59
59
|`maxOutputTokens`| Read by UI + executor for token estimation | Always meaningful — set if provider documents a cap |
60
60
|`computerUse`|`providers/utils.ts` (`getComputerUseModels` → `computerUseModels` routing) | Set only on actual computer-use SKUs |
61
61
|`deepResearch`| UI flag for routing to deep-research SKUs | Set only on actual deep-research model IDs |
Copy file name to clipboardExpand all lines: .agents/skills/add-permission-group-item/SKILL.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,7 +45,7 @@ Allowlist when the safe posture is "only what the admin named" and the member se
45
45
46
46
**Is the decision knowable from the config alone?** A rule needing a request value (an auth mode, a connector id) is *parameterized* and cannot be declared on an operation — see Step 3.
47
47
48
-
**Is it a gate or a projection?** A key that withholds *fields from a response* rather than the response is a projection. `hideTraceSpans` and `hideCostInfo` work this way: the logs routes declare `capability: 'none'` and strip fields, because refusing the read would withhold the status and error message too. Projections have one owner — `lib/logs/log-projection.ts` (`resolveLogFieldProjection`, `projectExecutionData`, `projectCostTotal`), carrying the `permission-group-enforced:` annotations. Add yours there; two copies of a redaction rule is how one of them stops redacting. Corollary: refuse the query that *selects on* a withheld field — otherwise the projection is a filter oracle; `logQuerySelectsCost` / `assertLogCostQueryAllowed` in that same module are the shape.
48
+
**Is it a gate or a projection?** A key that withholds *fields from a response* rather than the response is a projection. `hideTraceSpans` and `hideCostInfo` work this way: the logs routes declare `capability: 'none'` and strip fields, because refusing the read would withhold the status and error message too. Projections have one owner — `lib/logs/projection.ts` (`resolveLogFieldProjection`, `projectExecutionData`, `projectCostTotal`), carrying the `permission-group-enforced:` annotations. Add yours there; two copies of a redaction rule is how one of them stops redacting. Corollary: refuse the query that *selects on* a withheld field — otherwise the projection is a filter oracle; `logQuerySelectsCost` / `assertLogCostQueryAllowed` in that same module are the shape.
49
49
50
50
## Step 1: Append the field entry — never insert
51
51
@@ -255,7 +255,7 @@ What a run *does* is still governed by `assertPermissionsAllowed`. An item that
255
255
## Checklist Before Finishing
256
256
257
257
-[ ] Kind and `enforcement` chosen deliberately; `ui-only` justified in writing if used
258
-
-[ ] It is a gate, not a projection — a projection belongs in `lib/logs/log-projection.ts` with `capability: 'none'` on the routes, and still refuses queries that select on the withheld field
258
+
-[ ] It is a gate, not a projection — a projection belongs in `lib/logs/projection.ts` with `capability: 'none'` on the routes, and still refuses queries that select on the withheld field
259
259
-[ ] Entry **appended** to `PERMISSION_GROUP_FIELDS`, permissive default, restriction-phrased name
260
260
-[ ] Category present in `PLATFORM_CATEGORY_ORDER`, named after what is withheld
261
261
-[ ]`hint` says what access is revoked, never "hide" — it is also the active-restriction prose
@@ -190,7 +188,7 @@ fallback, or caller-controlled `_context` authority.
190
188
191
189
A required `'hidden'` param needs an `oauth` declaration or `hosting.apiKeyParam` to supply it (`bun run check:tool-param-reachability`).
192
190
193
-
A declared `timeout` param is an ordinary tool input — put it in the request body or URL yourself if the provider expects it; it becomes Sim's millisecond request deadline only when the tool sets `timeoutParamIsDeadline: true` (`http_request`). A `method` param on a tool with a fixed `request.method` would be sent as the HTTP verb, so the same audit rejects it.
191
+
A declared `timeout` param is an ordinary tool input — put it in the request body or URL yourself if the provider expects it; it becomes Sim's millisecond request deadline only when the tool sets `timeoutParamIsDeadline: true` (e.g. `http_request`). A `method` param on a tool with a fixed `request.method` would be sent as the HTTP verb, so the same audit rejects it.
194
192
195
193
### Parameter Types
196
194
-`'string'` - Text values
@@ -362,7 +360,7 @@ Only use bare `type: 'json'` without `properties` when the shape is truly dynami
362
360
## Critical Rules for transformResponse
363
361
364
362
### Handle Nullable Fields
365
-
ALWAYS use`?? null` for fields that may be undefined:
363
+
Use`?? null` for fields that may be undefined:
366
364
```typescript
367
365
transformResponse: async (response:Response) => {
368
366
const data =awaitresponse.json()
@@ -465,7 +463,7 @@ these are regenerated — and CI fails on stale artifacts. Commit the result. Se
465
463
466
464
## Wiring Tools into the Block (Required)
467
465
468
-
After registering in `tools/registry.ts`, you MUST also update the block definition at `apps/sim/blocks/blocks/{service}.ts`. This is not optional — tools are only usable from the UI if they are wired into the block.
466
+
After registering in `tools/registry.ts`, also update the block definition at `apps/sim/blocks/blocks/{service}.ts`: a tool is usable from the UI only once the block wires it.
@@ -299,6 +298,7 @@ If they differ: the tag dropdown shows fields that don't exist, or actual data h
299
298
If the service API supports programmatic webhook creation, implement `createSubscription` and `deleteSubscription` on the handler. The orchestration layer calls these automatically — **no code touches `route.ts`, `provider-subscriptions.ts`, or `deploy.ts`**.
Copy file name to clipboardExpand all lines: .agents/skills/council/SKILL.md
+1-8Lines changed: 1 addition & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,13 +2,6 @@
2
2
name: council
3
3
description: Spawn parallel task agents to explore a given area of the codebase from multiple angles, then use their findings to answer the question or build a plan. Use when a task needs broad fan-out exploration across many files before acting.
4
4
argument-hint: <area-of-interest>
5
-
# No agents/openai.yaml by design: council is a meta/exploration utility (like cleanup, ship, you-might-not-need-*), not a service-integration builder, so it intentionally ships no standalone agent card.
6
5
---
7
6
8
-
Based on the given area of interest, please:
9
-
10
-
1. Dig around the codebase in terms of that given area of interest, gather general information such as keywords and architecture overview.
11
-
2. Spawn off n=10 (unless specified otherwise) task agents to dig deeper into the codebase in terms of that given area of interest, some of them should be out of the box for variance.
12
-
3. Once the task agents are done, use the information to do what the user wants.
13
-
14
-
If user is in plan mode, use the information to create the plan.
7
+
Map the area of interest first (keywords, architecture), then fan out parallel agents, each exploring a distinct angle, including a few unconventional ones. Size the fan-out to the area (the user may name a number). Use their findings to answer the question, or to write the plan in plan mode.
0 commit comments