Skip to content

Commit ce0f749

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/presend-email-verify
# Conflicts: # apps/sim/tools/generated/tool-ids.ts # apps/sim/tools/generated/tool-metadata.ts # apps/sim/tools/generated/tool-outputs.ts
2 parents b428ff6 + dd5add6 commit ce0f749

7,853 files changed

Lines changed: 2029821 additions & 184720 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-block/SKILL.md‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ When adding or changing an OAuth integration block:
177177
`packages/sim-setup/src/capability-config.ts`. The CLI catalog is exhaustively typed and checked
178178
against the runtime field list; do not infer secrecy from the field name.
179179
4. If the canonical OAuth service declares `serviceAccountProviderId`, run
180-
`bun run deployment-config:generate`; this regenerates the provider-ID facts in
180+
`bun run generate:deployment-config`; this regenerates the provider-ID facts in
181181
`packages/deployment-config/src/service-account-providers.generated.ts`. Never hand-edit that
182182
generated map. Add `deploymentRequirement` policy in
183183
`packages/deployment-config/src/service-account-metadata.ts` only when the service-account path
@@ -350,7 +350,7 @@ sourceIds.forEach((id) => delete params[id]) // subblock ids are deleted
350350
if (chosen !== undefined) params[group.canonicalId] = chosen
351351
```
352352

353-
So by the time `tools.config.params(inputs)` runs (`executor/handlers/generic/generic-handler.ts`),
353+
So by the time `tools.config.params(inputs)` runs (`executor/handlers/generic/handler.ts`),
354354
`params.uploadFile` and `params.fileRef` are **gone** and the value is under `params.file`. Reading a
355355
subblock id there yields `undefined` and silently sends no file.
356356

@@ -359,7 +359,7 @@ and the first non-empty advanced value in advanced mode, so a stale value in the
359359
never leak. `normalizeFileInput` then handles the JSON string that advanced-mode template resolution
360360
produces.
361361

362-
Note that `generic-handler` merges rather than replaces (`{ ...inputs, ...transformedParams }`), so
362+
Note that `generic/handler` merges rather than replaces (`{ ...inputs, ...transformedParams }`), so
363363
omitting a key from the returned object does not strip it from what the tool receives. Tools simply
364364
ignore params they do not declare.
365365

@@ -615,7 +615,7 @@ tools: {
615615

616616
## Outputs Definition
617617

618-
**IMPORTANT:** Block outputs have a simpler schema than tool outputs. Block outputs do NOT support:
618+
Block outputs have a simpler schema than tool outputs. They do not support:
619619
- `optional: true` - This is only for tool outputs
620620
- `items` property - This is only for tool outputs with array types
621621

@@ -729,7 +729,7 @@ export const ServiceBlock: BlockConfig = {
729729
longDescription: 'Full description for documentation...',
730730
docsLink: 'https://docs.sim.ai/integrations/service',
731731
category: 'tools',
732-
integrationType: IntegrationType.DeveloperTools,
732+
integrationType: IntegrationType.DevOps,
733733
bgColor: '#FF6B6B',
734734
icon: ServiceIcon,
735735
authMode: AuthMode.OAuth,
@@ -959,11 +959,11 @@ Verify it with `bun run check:block-successors`.
959959
Adding a block on its own needs no **tool metadata** regeneration — a block references existing
960960
tool IDs through `tools.access` and does not change any tool's shape.
961961

962-
But if the same change also adds, edits **or removes** a tool, run `bun run tool-metadata:generate` and commit the result, or CI fails on stale artifacts. That matters here because a block's `outputs` are authored to match its tools' outputs, and the UI reads those from the generated metadata, not the executable registry — an unregenerated tool change makes the block's outputs disagree with what the panel renders. See `.agents/skills/tool-registry-boundary/SKILL.md`.
962+
But if the same change also adds, edits **or removes** a tool, run `bun run generate:tool-metadata` and commit the result, or CI fails on stale artifacts. That matters here because a block's `outputs` are authored to match its tools' outputs, and the UI reads those from the generated metadata, not the executable registry — an unregenerated tool change makes the block's outputs disagree with what the panel renders. See `.agents/skills/tool-registry-boundary/SKILL.md`.
963963

964964
A visible integration block does require the generated integration catalog and docs to be refreshed:
965-
`bun run tool-metadata:generate` (only when a tool changed), `bun run scripts/generate-docs.ts`,
966-
`bun run deployment-config:generate`, then `bun run check:audits`. Also run
965+
`bun run generate:tool-metadata` (only when a tool changed), `bun run scripts/generate-docs.ts`,
966+
`bun run generate:deployment-config`, then `bun run check:audits`. Also run
967967
`bun run apps/sim/scripts/check-block-registry.ts origin/staging` (CI runs it outside `check:audits`). Commit the
968968
full generator output. For what each check verifies, see the `validate-integration` skill →
969969
Regenerate Derived Artifacts.
@@ -986,10 +986,10 @@ Regenerate Derived Artifacts.
986986
- [ ] Outputs match tool outputs
987987
- [ ] Block + meta registered in registry-maps.ts (`BLOCK_REGISTRY` / `BLOCK_META_REGISTRY`)
988988
- [ ] If `sunset.replacedBy` changed: regenerated and committed the block successor map; `bun run check:block-successors` passes
989-
- [ ] If any tool was added, changed or removed alongside the block: ran `bun run tool-metadata:generate` and committed the artifacts
989+
- [ ] If any tool was added, changed or removed alongside the block: ran `bun run generate:tool-metadata` and committed the artifacts
990990
- [ ] Ran `bun run scripts/generate-docs.ts`, reviewed the generated diff, and committed the integration catalog changes
991-
- [ ] `bun run integration-catalog:check` passes
992-
- [ ] `bun run docs:check` passes (CI gate — fails on any stale generated docs page)
991+
- [ ] `bun run check:integration-catalog` passes
992+
- [ ] `bun run check:docs` passes (CI gate — fails on any stale generated docs page)
993993
- [ ] If icon missing: asked user to provide SVG
994994
- [ ] If triggers exist: `triggers` config set, trigger subBlocks spread
995995
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`

‎.agents/skills/add-column-type/SKILL.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ The three that are easy to get wrong:
9898

9999
Add the entry to `COLUMN_TYPE_REGISTRY` in `registry.ts` **and** `COLUMN_TYPE_SERVER_REGISTRY` in `registry.server.ts`.
100100

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.
102102

103103
## Step 5: Migrations (only if the stored bytes change)
104104

@@ -131,6 +131,7 @@ Registering the *type* is compiler-enforced. Registering its *metadata* is not,
131131
| `lib/table/types.ts` `ColumnDefinition` | (this one DOES fail — the ownership loop indexes it) |
132132
| `column-types/types.ts` `TYPE_SPECIFIC_COLUMN_KEYS` | it is never stripped on conversion, and poisons the target type |
133133
| `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 |
134135
| `columns/service.ts` `addTableColumn` param type | callers cannot pass it |
135136
| 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 |
136137
| `column-config-sidebar.tsx` | no UI to set it |

‎.agents/skills/add-connector/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export const {service}ConnectorMeta: ConnectorMeta = {
8989

9090
configFields: [
9191
// Rendered dynamically by the add-connector modal UI
92-
// Supports 'short-input', 'dropdown', and 'selector' types — see ConfigField Types below
92+
// Supports 'short-input', 'dropdown', and 'selector' types — see ConnectorConfigField Types below
9393
],
9494

9595
// Optional: tag definitions are metadata too — declare them here
@@ -167,7 +167,7 @@ export const {service}Connector: ConnectorConfig = {
167167
}
168168
```
169169

170-
## ConfigField Types
170+
## ConnectorConfigField Types
171171

172172
The add-connector modal renders these automatically — no custom UI needed.
173173

‎.agents/skills/add-enrichment/SKILL.md‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Because enrichments run on Sim's hosted keys by default, **every provider tool y
2222

2323
## Architecture (what you're plugging into)
2424

25-
- **`enrichments/types.ts`** — `EnrichmentConfig { id, name, description, icon, inputs, outputs, providers }` and `EnrichmentProvider { id, label, toolId, buildParams, projectFailure, mapOutput }` — `toolProvider` fills `projectFailure` with the standard HTTP projection; override it only for a provider whose failure shape is nonstandard (see `enrichments/provider-failures/`). Providers are **plain data** (no `@/tools` import) so the catalog stays client-safe.
25+
- **`enrichments/types.ts`** — `EnrichmentConfig { id, name, description, icon, inputs, outputs, providers }` and `EnrichmentProvider { id, label, toolId, buildParams, projectFailure, mapOutput, isVerified? }` — `toolProvider` fills `projectFailure` with the standard HTTP projection; override it only for a provider whose failure shape is nonstandard (see `enrichments/provider-failures/`). Providers are **plain data** (no `@/tools` import) so the catalog stays client-safe.
2626
- **`enrichments/providers.ts`** — `toolProvider(...)` (typed passthrough) plus shared input helpers: `str(v)`, `normalizeDomain(v)`, `firstNonEmpty(arr)`, `splitName(fullName)`, and `projectEnrichmentProviderFailure`.
2727
- **`enrichments/run.ts`** — the server-only cascade runner. Calls `executeTool(provider.toolId, { ...params, _context: { workspaceId, userId } })`, accumulates hosted-key cost, returns the first non-empty mapped result. **You do not edit this** — it works for any registry entry.
2828
- **`enrichments/registry.ts`** — `ENRICHMENT_REGISTRY` / `ALL_ENRICHMENTS` / `getEnrichment`. Register new entries here.
@@ -37,7 +37,9 @@ For each output the enrichment produces, decide which existing tool provides it.
3737
- Its `params` accept what you can derive from table columns (read the tool's `params`).
3838
- Its `outputs` / `transformResponse` actually expose the field you need (read the real output shape — don't assume).
3939

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 by **accuracy first, then price per hit**. Order decides which answer wins when two providers would disagree, so a cheaper but less accurate provider ahead of a better one trades quality for cost; reorder for price only with benchmark evidence. Among similarly accurate providers, put the ones that bill on a miss or charge a high price per hit after the cheaper, free-on-miss ones (check each vendor's billing docs and the tool's `hosting.pricing`); never move a more accurate provider behind a less accurate one to save cost. The cascade stops at the first non-empty, verified result. Apollo and LinkedIn APIs are not hosted-safe (ToS) — never call them as providers.
41+
42+
Prefer a vendor's own verified-only option (e.g. Prospeo `only_verified_email`) when it turns an unverified result into a free miss. Otherwise, when a provider can return an unconfirmed hit (a catch-all guess, a `risky` status), declare `isVerified(output)`: an unconfirmed hit is held while later providers look for a confirmed one, and fills the cell only if none does. `isVerified: false` marks a provider that never confirms its hits (a database record); it runs only while nothing is held.
4143

4244
## Step 2: Verify hosted-key support — chain to `/add-hosted-key` if missing
4345

@@ -109,7 +111,7 @@ export { myEnrichment } from './my-enrichment'
109111
```
110112

111113
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.
114+
- 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.
113115
- `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).
114116
- Output `id`s are the keys `mapOutput` returns; output `name`s are the default column names (the user can rename them in the config).
115117

@@ -136,7 +138,8 @@ export const ENRICHMENT_REGISTRY: EnrichmentRegistry = {
136138

137139
- [ ] Each output mapped to a real tool field (verified against the tool's `params`/`outputs`)
138140
- [ ] **Every provider tool has a `hosting` block — ran `/add-hosted-key` for any that didn't**
139-
- [ ] Providers ordered cheapest / most-likely-first; Apollo/LinkedIn not used
141+
- [ ] Providers ordered accuracy-first, then price per hit (billing on a miss checked against vendor docs); Apollo/LinkedIn not used
142+
- [ ] Providers that can return an unconfirmed hit declare `isVerified`
140143
- [ ] Enrichment file is client-safe (no `@/tools` import); uses `toolProvider` + shared helpers
141144
- [ ] `buildParams` returns `null` on insufficient inputs; `mapOutput` returns `null` on a miss
142145
- [ ] Registered in `enrichments/registry.ts`

‎.agents/skills/add-hosted-key/SKILL.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,20 @@ pricing: {
154154

155155
**`getCost` must always throw** if it cannot determine cost. Never silently fall back to a default — this would hide billing inaccuracies.
156156

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+
157171
### Capturing Cost Data from the API
158172

159173
If the API returns cost info, capture it in `transformResponse` so `getCost` can read it from the output:

0 commit comments

Comments
 (0)