Skip to content

Commit 6423ab1

Browse files
Merge branch 'staging' into feat/table-v2-block
2 parents 2626482 + fcfa41c commit 6423ab1

1,603 files changed

Lines changed: 184578 additions & 24893 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ import type { BlockConfig, BlockMeta } from '@/blocks/types'
640640

641641
export const {Service}BlockMeta = {
642642
tags: ['messaging', 'automation'], // Same tags as the block's tags field
643+
url: 'https://{service}.com', // Canonical homepage of the external service
643644
templates: [ // Optional but strongly encouraged
644645
{
645646
icon: {Service}Icon,
@@ -666,6 +667,7 @@ export const {Service}BlockMeta = {
666667

667668
- **Import `BlockMeta`** from `@/blocks/types` alongside `BlockConfig`
668669
- **`tags`** must match the `tags` array on the block config exactly
670+
- **`url`** is the canonical homepage of the external service the block integrates with (e.g. `'https://exa.ai'`, `'https://salesforce.com'`) — the catalog "link back to the tool". It is distinct from `BlockConfig.docsLink`, which points at Sim's own integration docs on `docs.sim.ai`. Use the service's real root domain over `https` (verify it actually resolves), no tracking params, no trailing slash. Omit `url` only for first-party/built-in blocks that have no external service (e.g. `agent`, `function`, `condition`, `api`, `response`)
669671
- **Templates are optional** but should be added for any integration that has a recognizable use case — aim for 2–4 templates per block
670672
- **Template `prompt`** should start with "Build a workflow that..." or "Create a workflow that..." and be concrete enough to generate a real workflow in Mothership
671673
- **Template `modules`** lists the Sim modules the template relies on: `'knowledge-base' | 'tables' | 'files' | 'workflows' | 'scheduled' | 'agent'`
@@ -906,6 +908,7 @@ All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MU
906908
- [ ] Outputs match tool outputs
907909
- [ ] Block registered in `registry.ts` blocks object (alphabetically)
908910
- [ ] `{Service}BlockMeta` exported at bottom of block file with `tags` and `templates`
911+
- [ ] `url` set on `{Service}BlockMeta` to the external service's verified homepage (omit only for first-party blocks with no external service)
909912
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in the block's `tools.access` and derived from a real online-sourced use case (not invented)
910913
- [ ] `BlockMeta` imported from `@/blocks/types` alongside `BlockConfig`
911914
- [ ] Block meta registered in `registry.ts` blocksMeta object (alphabetically)

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

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ You are an expert at adding knowledge base connectors to Sim. A connector syncs
1212
When the user asks you to create a connector:
1313
1. Use Context7 or WebFetch to read the service's API documentation
1414
2. Determine the auth mode: **OAuth** (if Sim already has an OAuth provider for the service) or **API key** (if the service uses API key / Bearer token auth)
15-
3. Create the connector directory and config
16-
4. Register it in the connector registry
15+
3. Create the connector directory: a client-safe `meta.ts` (declarative metadata) plus the runtime module that spreads it
16+
4. Register it in BOTH the server registry and the client-safe meta registry
1717

1818
## Hard Rule: No Guessed Response Or Document Schemas
1919

@@ -32,13 +32,19 @@ If the source schema is unknown, do one of these instead:
3232

3333
## Directory Structure
3434

35+
Each connector is split into a client-safe metadata file and a server-only runtime file. This mirrors the `XBlockMeta` / `BLOCK_META_REGISTRY` split in `apps/sim/blocks` — client components (the knowledge UI) only need the metadata (icon, name, auth, config fields), so the runtime functions (which pull server-only helpers like `input-validation.server``undici``node:net`) must stay out of the client bundle.
36+
3537
Create files in `apps/sim/connectors/{service}/`:
3638
```
3739
connectors/{service}/
38-
├── index.ts # Barrel export
39-
└── {service}.ts # ConnectorConfig definition
40+
├── index.ts # Barrel export (re-exports the runtime connector)
41+
├── meta.ts # ConnectorMeta — client-safe declarative metadata
42+
└── {service}.ts # ConnectorConfig — spreads the meta + adds runtime functions
4043
```
4144

45+
- `meta.ts` exports `{service}ConnectorMeta: ConnectorMeta`. It imports ONLY the icon from `@/components/icons`, `import type { ConnectorMeta } from '@/connectors/types'`, and any pure-data constants. It must NEVER import server/runtime code.
46+
- `{service}.ts` exports `{service}Connector: ConnectorConfig`. It imports the meta via `import { {service}ConnectorMeta } from '@/connectors/{service}/meta'`, spreads it as the first property, and holds the runtime functions (which may import server-only helpers like `@/lib/knowledge/documents/utils`).
47+
4248
## Authentication
4349

4450
Connectors use a discriminated union for auth config (`ConnectorAuthConfig` in `connectors/types.ts`):
@@ -55,19 +61,17 @@ For services with existing OAuth providers in `apps/sim/lib/oauth/types.ts`. The
5561
### API key mode
5662
For services that use API key / Bearer token auth. The modal shows a password input with the configured `label` and `placeholder`. The API key is encrypted at rest using AES-256-GCM and stored in a dedicated `encryptedApiKey` column on the connector record. The sync engine decrypts it automatically — connectors receive the raw access token in `listDocuments`, `getDocument`, and `validateConfig`.
5763
58-
## ConnectorConfig Structure
64+
## Connector Structure (meta.ts + runtime)
65+
66+
The declarative metadata lives in `meta.ts` (`ConnectorMeta`). The runtime functions live in `{service}.ts` (`ConnectorConfig`), which spreads the meta as its first property.
5967
60-
### OAuth connector example
68+
### `meta.ts` — client-safe metadata
6169
6270
```typescript
63-
import { createLogger } from '@sim/logger'
6471
import { {Service}Icon } from '@/components/icons'
65-
import { fetchWithRetry } from '@/lib/knowledge/documents/utils'
66-
import type { ConnectorConfig, ExternalDocument, ExternalDocumentList } from '@/connectors/types'
67-
68-
const logger = createLogger('{Service}Connector')
72+
import type { ConnectorMeta } from '@/connectors/types'
6973

70-
export const {service}Connector: ConnectorConfig = {
74+
export const {service}ConnectorMeta: ConnectorMeta = {
7175
id: '{service}',
7276
name: '{Service}',
7377
description: 'Sync documents from {Service} into your knowledge base',
@@ -85,6 +89,26 @@ export const {service}Connector: ConnectorConfig = {
8589
// Supports 'short-input' and 'dropdown' types
8690
],
8791

92+
// Optional: tag definitions are metadata too — declare them here
93+
// tagDefinitions: [ ... ],
94+
}
95+
```
96+
97+
Keep `meta.ts` free of any server/runtime import. Only the icon, the `ConnectorMeta` type, and pure-data constants belong here.
98+
99+
### `{service}.ts` — runtime (OAuth example)
100+
101+
```typescript
102+
import { createLogger } from '@sim/logger'
103+
import { fetchWithRetry } from '@/lib/knowledge/documents/utils'
104+
import { {service}ConnectorMeta } from '@/connectors/{service}/meta'
105+
import type { ConnectorConfig, ExternalDocument, ExternalDocumentList } from '@/connectors/types'
106+
107+
const logger = createLogger('{Service}Connector')
108+
109+
export const {service}Connector: ConnectorConfig = {
110+
...{service}ConnectorMeta,
111+
88112
listDocuments: async (accessToken, sourceConfig, cursor) => {
89113
// Return metadata stubs with contentDeferred: true (if per-doc content fetch needed)
90114
// Or full documents with content (if list API returns content inline)
@@ -111,8 +135,11 @@ Only map fields in `listDocuments`, `getDocument`, `validateConfig`, and `mapTag
111135

112136
### API key connector example
113137

138+
The split is identical — `auth` lives in `meta.ts`, runtime functions in `{service}.ts`.
139+
114140
```typescript
115-
export const {service}Connector: ConnectorConfig = {
141+
// meta.ts
142+
export const {service}ConnectorMeta: ConnectorMeta = {
116143
id: '{service}',
117144
name: '{Service}',
118145
description: 'Sync documents from {Service} into your knowledge base',
@@ -126,6 +153,11 @@ export const {service}Connector: ConnectorConfig = {
126153
},
127154

128155
configFields: [ /* ... */ ],
156+
}
157+
158+
// {service}.ts
159+
export const {service}Connector: ConnectorConfig = {
160+
...{service}ConnectorMeta,
129161
listDocuments: async (accessToken, sourceConfig, cursor) => { /* ... */ },
130162
getDocument: async (accessToken, sourceConfig, externalId) => { /* ... */ },
131163
validateConfig: async (accessToken, sourceConfig) => { /* ... */ },
@@ -499,7 +531,9 @@ If the service already has an icon in `apps/sim/components/icons.tsx` (from a to
499531

500532
## Registering
501533

502-
Add one line to `apps/sim/connectors/registry.ts`:
534+
Register in BOTH registries, keeping the same alphabetical-by-id ordering in each.
535+
536+
1. **Server registry**`apps/sim/connectors/registry.server.ts` (server-only full registry; holds full connectors with runtime functions, imported by the sync engine and knowledge API routes):
503537

504538
```typescript
505539
import { {service}Connector } from '@/connectors/{service}'
@@ -510,6 +544,19 @@ export const CONNECTOR_REGISTRY: ConnectorRegistry = {
510544
}
511545
```
512546

547+
2. **Client-safe meta registry**`apps/sim/connectors/registry.ts` (imports each connector's `meta.ts` only, so client components can use it without pulling server-only code; the metadata counterpart to `BLOCK_META_REGISTRY`):
548+
549+
```typescript
550+
import { {service}ConnectorMeta } from '@/connectors/{service}/meta'
551+
552+
export const CONNECTOR_META_REGISTRY: ConnectorMetaRegistry = {
553+
// ... existing connector metas ...
554+
{service}: {service}ConnectorMeta,
555+
}
556+
```
557+
558+
`registry.ts` exports `CONNECTOR_META_REGISTRY: ConnectorMetaRegistry` plus the helpers `getConnectorMeta(id)` and `getAllConnectorMeta()`, importing each `@/connectors/{service}/meta` directly — never the runtime module. `registry.server.ts` exports `CONNECTOR_REGISTRY: ConnectorRegistry`.
559+
513560
## Reference Implementations
514561

515562
- **OAuth + contentDeferred**: `apps/sim/connectors/google-drive/google-drive.ts` — file download with metadata-based hash, `orderBy` for deterministic pagination
@@ -520,7 +567,8 @@ export const CONNECTOR_REGISTRY: ConnectorRegistry = {
520567

521568
## Checklist
522569

523-
- [ ] Created `connectors/{service}/{service}.ts` with full ConnectorConfig
570+
- [ ] Created `connectors/{service}/meta.ts` with `{service}ConnectorMeta: ConnectorMeta` (icon, name, auth, configFields, tagDefinitions) — no server/runtime imports
571+
- [ ] Created `connectors/{service}/{service}.ts` with `{service}Connector: ConnectorConfig` spreading the meta + runtime functions
524572
- [ ] Created `connectors/{service}/index.ts` barrel export
525573
- [ ] **Auth configured correctly:**
526574
- OAuth: `auth.provider` matches an existing `OAuthService` in `lib/oauth/types.ts`
@@ -542,4 +590,5 @@ export const CONNECTOR_REGISTRY: ConnectorRegistry = {
542590
- [ ] All external API calls use `fetchWithRetry` (not raw `fetch`)
543591
- [ ] All optional config fields validated in `validateConfig`
544592
- [ ] Icon exists in `components/icons.tsx` (or asked user to provide SVG)
545-
- [ ] Registered in `connectors/registry.ts`
593+
- [ ] Registered the full connector in `connectors/registry.server.ts`
594+
- [ ] Registered the meta in `connectors/registry.ts` (same alphabetical-by-id ordering as registry.server.ts)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,12 @@ If anything matches, run the affected provider tests and update assertions as ne
143143

144144
### New API behavior is NOT data-driven
145145

146-
The Consumption Matrix (Step 2) tells you which capability *flags* are honored by existing provider code. But if the new model needs **net-new** request handling that the provider doesn't implement yet — a new beta header (e.g. Anthropic's `anthropic-beta` structured-outputs header in `anthropic/index.ts`), a new thinking/reasoning encoding, a Responses-API quirk — you must edit `apps/sim/providers/<provider>/core.ts` / `index.ts`. Setting a flag whose behavior isn't implemented is a silent no-op.
146+
The Consumption Matrix (Step 2) tells you which capability *flags* are honored by existing provider code. But if the new model needs **net-new** request handling that the provider doesn't implement yet — a new beta header (e.g. Anthropic's `anthropic-beta` structured-outputs header in `anthropic/index.ts`), a new thinking/reasoning encoding, a Responses-API quirk — you must edit `apps/sim/providers/<provider>/core.ts` / `index.ts`. Setting a flag whose behavior isn't implemented is a silent no-op. When you do edit provider code, reuse the shared helpers rather than hand-rolling: streaming responses are assembled via `createStreamingExecution` (`@/providers/streaming-execution`) and tool schemas via `adaptOpenAIChatToolSchema` / `adaptAnthropicToolSchema` (`@/providers/tool-schema-adapter`).
147147

148148
### Wrong family entirely?
149149

150150
- **Embedding or rerank model** → it does NOT go in the `models[]` array. Use `EMBEDDING_MODEL_PRICING` / `RERANK_MODEL_PRICING` in `models.ts` instead.
151-
- **Brand-new provider** (not just a new model under an existing one) → much larger surface: add the id to `ProviderId` in `providers/types.ts`, a registry entry in `providers/registry.ts`, a provider implementation under `providers/<id>/`, an icon in `components/icons.tsx`, and the `PROVIDER_DEFINITIONS` block. That is beyond this skill — tell the user.
151+
- **Brand-new provider** (not just a new model under an existing one) → much larger surface: add the id to `ProviderId` in `providers/types.ts`, a registry entry in `providers/registry.ts`, a provider implementation under `providers/<id>/` (assemble streaming responses with `createStreamingExecution` and wrap tool schemas with the `@/providers/tool-schema-adapter` helpers), an icon in `components/icons.tsx`, and the `PROVIDER_DEFINITIONS` block. That is beyond this skill — tell the user.
152152

153153
## Step 5: Write, lint
154154

0 commit comments

Comments
 (0)