broods 0.54.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,233 +2,52 @@ import { SystemModelMessage, LanguageModelCallOptions, RequestOptions, streamTex
2
2
  import * as convex_values from 'convex/values';
3
3
  import { Infer } from 'convex/values';
4
4
 
5
- /**
6
- * Account-owned code hook upload validation for Convex config-plane sync.
7
- * Mirrors core's account hook upload contract without requiring the Node runtime.
8
- */
9
5
  declare const AGENT_HOOK_EVENT_NAMES: readonly ["agent.started", "agent.step.finished", "agent.finished", "agent.failed", "agent.approval.required", "tool.call.started", "tool.call.finished", "tool.result", "subagent.task.started", "subagent.task.finished", "channel.message.received", "channel.message.sending"];
10
6
  type AgentHookEventName = (typeof AGENT_HOOK_EVENT_NAMES)[number];
11
7
 
12
- /**
13
- * Every Vercel AI SDK provider that ships language models, the community
14
- * providers on the same spec that take an API key (`cloudflare`, `llmgateway`,
15
- * `ollama`, `openrouter`), `custom` (any OpenAI-compatible endpoint), and
16
- * `chatgpt` (OpenAI on a Sign in with ChatGPT login instead of an API key).
17
- * Image-, speech- and transcription-only providers are deliberately absent:
18
- * they cannot back `config.model`.
19
- */
20
- declare const MODEL_PROVIDERS: {
21
- readonly alibaba: {
22
- readonly label: "Alibaba Qwen";
23
- readonly modelPlaceholder: "qwen3-max";
24
- };
25
- readonly anthropic: {
26
- readonly label: "Anthropic";
27
- readonly modelPlaceholder: "claude-sonnet-4-5-20250929";
28
- };
29
- readonly azure: {
30
- readonly label: "Azure OpenAI";
31
- readonly modelPlaceholder: "gpt-4.1-mini";
32
- };
33
- readonly baseten: {
34
- readonly label: "Baseten";
35
- readonly modelPlaceholder: "deepseek-ai/DeepSeek-V3";
36
- };
37
- readonly bedrock: {
38
- readonly label: "Amazon Bedrock";
39
- readonly modelPlaceholder: "anthropic.claude-sonnet-4-5-20250929-v1:0";
40
- };
41
- readonly cerebras: {
42
- readonly label: "Cerebras";
43
- readonly modelPlaceholder: "llama3.1-8b";
44
- };
45
- readonly chatgpt: {
46
- readonly label: "ChatGPT plan";
47
- readonly modelPlaceholder: "gpt-5.5";
48
- };
49
- readonly cloudflare: {
50
- readonly label: "Cloudflare";
51
- readonly modelPlaceholder: "@cf/meta/llama-3.3-70b-instruct-fp8-fast";
52
- };
53
- readonly cohere: {
54
- readonly label: "Cohere";
55
- readonly modelPlaceholder: "command-a-03-2025";
56
- };
57
- readonly custom: {
58
- readonly label: "Custom OpenAI-compatible";
59
- readonly modelPlaceholder: "gpt-oss-120b";
60
- };
61
- readonly deepinfra: {
62
- readonly label: "DeepInfra";
63
- readonly modelPlaceholder: "deepseek-ai/DeepSeek-V3";
64
- };
65
- readonly deepseek: {
66
- readonly label: "DeepSeek";
67
- readonly modelPlaceholder: "deepseek-chat";
68
- };
69
- readonly fireworks: {
70
- readonly label: "Fireworks";
71
- readonly modelPlaceholder: "accounts/fireworks/models/deepseek-v3";
72
- };
73
- readonly google: {
74
- readonly label: "Google";
75
- readonly modelPlaceholder: "gemini-2.5-flash";
76
- };
77
- readonly groq: {
78
- readonly label: "Groq";
79
- readonly modelPlaceholder: "llama-3.3-70b-versatile";
80
- };
81
- readonly huggingface: {
82
- readonly label: "Hugging Face";
83
- readonly modelPlaceholder: "meta-llama/Llama-3.3-70B-Instruct";
84
- };
85
- readonly llmgateway: {
86
- readonly label: "LLM Gateway";
87
- readonly modelPlaceholder: "openai/gpt-4.1-mini";
88
- };
89
- readonly minimax: {
90
- readonly label: "MiniMax";
91
- readonly modelPlaceholder: "MiniMax-M2.7";
92
- };
93
- readonly mistral: {
94
- readonly label: "Mistral";
95
- readonly modelPlaceholder: "mistral-large-latest";
96
- };
97
- readonly moonshotai: {
98
- readonly label: "Moonshot AI Kimi";
99
- readonly modelPlaceholder: "kimi-k2.6";
100
- };
101
- readonly ollama: {
102
- readonly label: "Ollama";
103
- readonly modelPlaceholder: "gpt-oss:120b";
104
- };
105
- readonly openai: {
106
- readonly label: "OpenAI";
107
- readonly modelPlaceholder: "gpt-4.1-mini";
108
- };
109
- readonly openrouter: {
110
- readonly label: "OpenRouter";
111
- readonly modelPlaceholder: "anthropic/claude-sonnet-4.5";
112
- };
113
- readonly perplexity: {
114
- readonly label: "Perplexity";
115
- readonly modelPlaceholder: "low";
116
- };
117
- readonly togetherai: {
118
- readonly label: "Together.ai";
119
- readonly modelPlaceholder: "deepseek-ai/DeepSeek-V3";
120
- };
121
- readonly v0: {
122
- readonly label: "Vercel v0";
123
- readonly modelPlaceholder: "v0-1.0-md";
124
- };
125
- readonly vercel: {
126
- readonly label: "Vercel AI Gateway";
127
- readonly modelPlaceholder: "openai/gpt-4.1-mini";
128
- };
129
- readonly vertex: {
130
- readonly label: "Google Vertex AI";
131
- readonly modelPlaceholder: "gemini-2.5-flash";
132
- };
133
- readonly xai: {
134
- readonly label: "xAI Grok";
135
- readonly modelPlaceholder: "grok-4";
136
- };
137
- readonly zai: {
138
- readonly label: "Z.ai GLM";
139
- readonly modelPlaceholder: "glm-4.7";
140
- };
141
- };
142
- type AccountModelProviderName = keyof typeof MODEL_PROVIDERS;
143
-
144
- /**
145
- * Agent config validation, the only copy of it: Convex config HTTP checks a
146
- * config on write and core re-checks the stored config on every run. Pure
147
- * module: safe for the default Convex runtime. The public projection lives in
148
- * ./responses.ts.
149
- */
8
+ declare const ACCOUNT_MODEL_PROVIDER_NAMES: readonly ["alibaba", "anthropic", "azure", "baseten", "bedrock", "cerebras", "chatgpt", "cloudflare", "cohere", "custom", "deepinfra", "deepseek", "fireworks", "google", "groq", "huggingface", "llmgateway", "minimax", "mistral", "moonshotai", "ollama", "openai", "openrouter", "perplexity", "togetherai", "v0", "vercel", "vertex", "xai", "zai"];
9
+ type AccountModelProviderName = (typeof ACCOUNT_MODEL_PROVIDER_NAMES)[number];
150
10
 
151
11
  declare const AGENT_HARNESS_TYPES: readonly ["claude-code", "codex", "deepagents", "opencode", "pi"];
152
12
  declare const AGENT_HARNESS_DEBUG_LEVELS: readonly ["error", "warn", "info", "debug", "trace"];
153
13
  declare const AGENT_HARNESS_PERMISSION_MODES: readonly ["allow-reads", "allow-edits", "allow-all"];
154
14
  declare const AGENT_LIFECYCLE_EVENT_NAMES: readonly ["agent.started", "agent.step.finished", "agent.finished", "agent.failed", "agent.approval.required", "tool.call.started", "tool.call.finished", "tool.result", "subagent.task.started", "subagent.task.finished"];
155
15
 
156
- /**
157
- * Shared validation for MCP server registrations (#331). One normalizer
158
- * serves every write path (CLI sync, direct API, dashboard). A `url` makes an "http" row
159
- * core connects to over the stateless 2026-07-28 transport; a `bundle` makes
160
- * a "hosted" row, hashed here so sha256 always travels with the bundle; the
161
- * S3 bundle writer (aws/bundles.ts) marks whether Cloudflare Dynamic Workers
162
- * can run it. Auth header values may carry ${NAME}
163
- * account env refs; they resolve into the encrypted agent config at sync
164
- * time, never on this row, and credential-bearing headers must use one
165
- * instead of an inline secret. `oauth` follows the same rule: clientSecret
166
- * and refreshToken must be ${NAME} refs, so the row never holds a secret.
167
- */
168
-
169
- /**
170
- * OAuth 2.0 refresh-token grant for an external row. Core mints access tokens
171
- * at connect time and sends `Authorization: Bearer <token>`, so a server
172
- * whose tokens expire (Google's Workspace MCP endpoints) still works where a
173
- * static header cannot. Secret fields hold ${NAME} refs on the row.
174
- */
175
16
  interface McpOauth {
176
17
  clientId: string;
177
18
  clientSecret: string;
178
19
  refreshToken: string;
179
- /** Token endpoint, https only; core defaults to https://oauth2.googleapis.com/token. */
180
20
  tokenUrl?: string;
181
21
  }
182
22
 
183
- /**
184
- * Agent configuration: types for the per-agent settings object and the
185
- * runtime projection of a stored config. The validation rules are the config
186
- * plane's (`@broods/convex/model/agentRules`), so a config is judged the same
187
- * on write and on every run. Decrypting the stored blob is
188
- * `../convex/account-keys.ts`.
189
- * Account types and auth live in `./accounts.ts` and `../auth.ts`.
190
- */
191
-
192
23
  interface AgentConfig {
193
24
  agent?: AgentBehaviorConfig;
194
25
  harness?: AgentHarnessConfig;
195
26
  model?: AgentModelConfig;
196
27
  provider?: AgentProviderConfig;
28
+ /** Sandbox record ids. The first is the default for bash, workspaces and a harness. */
197
29
  sandboxes?: string[];
198
30
  workspaces?: AgentWorkspaceRef[];
199
31
  session?: AgentSessionConfig;
200
32
  hooks?: AgentHooksConfig;
201
33
  channels?: AgentChannelsConfig;
202
34
  tools?: AgentToolsConfig;
203
- /** Connected MCP servers, keyed by their config-plane row id (#331). */
204
35
  mcp?: AgentMcpConfig;
205
- /**
206
- * Tool names withheld for this run, applied after the tool set is built.
207
- * Set by a channel record; a channel can take a tool away, never add one.
208
- * Names that are not present are ignored.
209
- */
36
+ /** Withheld after the tool set is built; a channel can take a tool away, never add one. */
210
37
  denyTools?: string[];
211
38
  skills?: AgentSkillsConfig;
212
39
  subagent?: AgentSubagentConfig;
213
40
  scheduler?: AgentSchedulerConfig;
214
- /**
215
- * Registers the `browse` tool, which runs Obscura on the first sandbox. That
216
- * sandbox must be lambda with image "obscura" and network allow-all, or a
217
- * machine; manifest sync refuses anything else it can see.
218
- */
41
+ /** `browse` runs on the first sandbox: a machine, or lambda "obscura" with allow-all. */
219
42
  browser?: {
220
43
  enabled?: boolean;
221
44
  };
222
- /** Policies that gate this agent. Each one carries its own enforcement mode. */
223
45
  policies?: string[];
46
+ /** Opens the runtime-key path; account keys, cron and channel webhooks never need it. */
224
47
  publicAccess?: boolean;
225
48
  allowRunOverrides?: boolean;
226
49
  [key: string]: unknown;
227
50
  }
228
- /**
229
- * What a code hook reads as ctx.config: the model and the names of what the
230
- * agent can use. An allow-list, so no credential field can reach hook code.
231
- */
232
51
  interface HookAgentConfig {
233
52
  readonly model: {
234
53
  readonly provider?: AccountModelProviderName;
@@ -244,6 +63,7 @@ interface HookAgentConfig {
244
63
  readonly denyTools: readonly string[];
245
64
  }
246
65
  interface AgentBehaviorConfig {
66
+ /** Steps per turn. 0 lifts the cap; unset is the harness default. */
247
67
  maxTurn?: number;
248
68
  system?: string | SystemModelMessage | SystemModelMessage[];
249
69
  [key: string]: unknown;
@@ -269,10 +89,6 @@ interface AgentSkillsConfig {
269
89
  allowed?: string[];
270
90
  [key: string]: unknown;
271
91
  }
272
- /**
273
- * Opt-in for the `schedule` tool. Off by default: a scheduled task starts
274
- * billable agent runs long after the turn that asked for it.
275
- */
276
92
  interface AgentSchedulerConfig {
277
93
  enabled?: boolean;
278
94
  [key: string]: unknown;
@@ -282,33 +98,16 @@ interface AgentSubagentConfig {
282
98
  allowed?: string[];
283
99
  context?: "new" | "inherited";
284
100
  mode?: "ephemeral" | "persistent";
285
- /**
286
- * Publishes child reasoning, text, and tool stream parts to the existing
287
- * WebSocket/JetStream response path. Off by default.
288
- */
289
101
  stream?: boolean;
290
- /**
291
- * Controls what the parent agent sees from a finished subagent (AI SDK
292
- * "controlling what the model sees"): `full` = the child's whole transcript,
293
- * `result` = only its final result (default), `none` = nothing. A
294
- * `subagent.task.finished` code hook overrides this for custom shaping.
295
- */
102
+ /** What the parent sees of a finished child; default `result`. A code hook can override it. */
296
103
  visibility?: "full" | "result" | "none";
297
- /**
298
- * Model for virtual subagents (no `agentId`), laid over the parent's
299
- * `model` key by key. The child keeps the parent's tools, MCP, sandboxes,
300
- * hooks and policies. A registered agent always runs on its own model.
301
- */
104
+ /** Virtual subagents only, merged over the parent's `model`; registered agents use their own. */
302
105
  model?: Partial<AgentModelConfig>;
303
106
  [key: string]: unknown;
304
107
  }
305
108
  interface AgentModelConfig extends LanguageModelCallOptions, Partial<Pick<RequestOptions, "maxRetries" | "timeout">> {
306
109
  provider?: AccountModelProviderName;
307
110
  modelId?: string;
308
- /**
309
- * Speech-to-text model for inbound audio, on the same provider and key as
310
- * `modelId`. Defaults to the widest-container model the provider ships.
311
- */
312
111
  transcriptionModelId?: string;
313
112
  providerOptions?: AgentModelProviderOptions;
314
113
  output?: AgentModelOutputConfig;
@@ -335,16 +134,10 @@ type AgentModelOutputMetadata = {
335
134
  type AgentProviderConfig = Partial<Record<AccountModelProviderName, AgentProviderSettings>>;
336
135
  interface AgentProviderSettings {
337
136
  apiKey?: string;
338
- /** OpenAI-compatible endpoint (`custom`). Snake form, as documented. */
339
137
  base_url?: string;
340
- /** OpenAI-compatible endpoint (`custom`). AI-SDK form; the dashboard writes both. */
341
138
  baseURL?: string;
342
- /** Cloudflare AI Gateway id (`cloudflare`). Set, requests go through the gateway. */
343
139
  gatewayId?: string;
344
- /** A streamed model request with no response within this many ms is sent again. Unset: no limit. */
345
- firstByteTimeoutMs?: number;
346
140
  headers?: Record<string, string>;
347
- /** Endpoint label; becomes the provider id and the pi harness env prefix. */
348
141
  name?: string;
349
142
  organization?: string;
350
143
  project?: string;
@@ -353,6 +146,7 @@ interface AgentProviderSettings {
353
146
  interface AgentWorkspaceRef {
354
147
  name: string;
355
148
  workspaceId: string;
149
+ /** Unset inherits the default; `null` is read-only, read from S3 without a mount. */
356
150
  sandbox?: string | null;
357
151
  }
358
152
  interface AgentSessionConfig {
@@ -364,35 +158,19 @@ interface AgentSessionPruningConfig {
364
158
  enabled?: boolean;
365
159
  [key: string]: unknown;
366
160
  }
367
- /**
368
- * Compaction after a finished turn, on unless `enabled: false`. It runs once
369
- * the turn's last model call read `maxContextLength` input tokens or more
370
- * (default 500000), or after the provider refused a turn for context length.
371
- * `/compact` works whatever this says.
372
- */
161
+ /** On by default: runs once a turn's last call read `maxContextLength` (500000) tokens. */
373
162
  interface AgentSessionAutoCompactionConfig {
374
163
  enabled?: boolean;
375
164
  maxContextLength?: number;
376
165
  [key: string]: unknown;
377
166
  }
378
167
  interface AgentHooksConfig {
379
- /** Outbound event webhooks. An agent may register several independent endpoints. */
380
168
  webhooks?: AgentWebhookHookConfig[];
381
- /**
382
- * Uploaded code hooks. Each entry references an accountHooks bundle by id; the
383
- * bundle runs in the V8 isolate at the matching fire-points and its validated
384
- * return is folded into mutable harness state.
385
- */
386
169
  code?: AgentCodeHookConfig[];
387
170
  [key: string]: unknown;
388
171
  }
389
172
  interface AgentCodeHookConfig {
390
173
  hookId: string;
391
- /**
392
- * Optional narrowing of the events this reference reacts to. Omitted => the
393
- * bundle's own declared `events` set. Any listed event outside the bundle's
394
- * declared set is ignored at runtime.
395
- */
396
174
  events?: AgentHookEventName[];
397
175
  enabled?: boolean;
398
176
  [key: string]: unknown;
@@ -410,22 +188,14 @@ type AgentToolsConfig = Record<string, AgentToolConfig>;
410
188
  interface AgentToolConfig {
411
189
  enabled?: boolean;
412
190
  needsApproval?: boolean;
413
- async?: boolean;
414
191
  config?: Record<string, unknown>;
415
192
  [key: string]: unknown;
416
193
  }
417
194
  type AgentMcpConfig = Record<string, AgentMcpEntry>;
418
195
  interface AgentMcpEntry {
419
196
  enabled?: boolean;
420
- /** Applies to every tool the server exposes. */
421
197
  needsApproval?: boolean;
422
- /** Extra request headers; values resolved from account env vars at sync. */
423
198
  headers?: Record<string, string>;
424
- /**
425
- * Overrides for the row's oauth credentials; values resolved from account
426
- * env vars at sync, so the row's ${NAME} refs never reach the token
427
- * endpoint. tokenUrl stays on the row, where registration checked it.
428
- */
429
199
  oauth?: Partial<Omit<McpOauth, "tokenUrl">>;
430
200
  [key: string]: unknown;
431
201
  }
@@ -440,17 +210,11 @@ interface AgentChannelsConfig {
440
210
  teams?: AgentTeamsChannelConfig;
441
211
  twilio?: AgentTwilioChannelConfig;
442
212
  zalo?: AgentZaloChannelConfig;
443
- matrix?: AgentMatrixChannelConfig;
444
213
  instagram?: AgentInstagramChannelConfig;
445
214
  messenger?: AgentMessengerChannelConfig;
446
215
  whatsapp?: AgentWhatsAppChannelConfig;
447
216
  [key: string]: unknown;
448
217
  }
449
- /**
450
- * How an attached partitioned workspace splits its folders for runs arriving
451
- * through this door. `shared` mounts the workspace root; `conversation` mounts
452
- * a private child folder per thread, issue or chat under `alias`.
453
- */
454
218
  type ChannelPartition = {
455
219
  by: "shared";
456
220
  alias?: never;
@@ -465,7 +229,6 @@ interface AgentTelegramChannelConfig {
465
229
  webhookSecret?: string;
466
230
  allowedChannelIds?: string[];
467
231
  allowedUserIds?: string[];
468
- /** Bot's @username, e.g. `tracy_bot`. Set it to answer only when the agent is mentioned. */
469
232
  botUsername?: string;
470
233
  reactionEmoji?: string;
471
234
  trace?: "enabled" | "disabled";
@@ -480,31 +243,20 @@ interface AgentGitHubChannelConfig {
480
243
  privateKey?: string;
481
244
  allowedChannelIds?: string[];
482
245
  allowedUserIds?: string[];
483
- /** Bot username for @-mention detection (e.g. "my-bot" or "my-bot[bot]"). */
484
246
  botUserName?: string;
485
- /** Bot's numeric GitHub user ID for self-message detection. */
486
247
  botUserId?: number;
487
- /** When false, the bot does not auto-trigger on new issues (opened/edited/reopened). Defaults to true. The bot still triggers when assigned to an issue. */
488
248
  triggerOnIssueOpen?: boolean;
489
- /** When false, the bot does not auto-trigger on new PRs (opened/edited/reopened). Defaults to true. The bot still triggers when assigned to a PR. */
490
249
  triggerOnPROpen?: boolean;
491
250
  trace?: "enabled" | "disabled";
492
251
  partition?: ChannelPartition;
493
252
  [key: string]: unknown;
494
253
  }
495
- /**
496
- * A Linear member the agent comments as, through that member's personal API
497
- * key. The agent answers comments that mention `@userName` on issues, and
498
- * `webhookSecret` checks every delivery.
499
- */
500
254
  interface AgentLinearChannelConfig {
501
255
  allowedChannelIds?: string[];
502
256
  allowedUserIds?: string[];
503
257
  id?: string;
504
258
  apiKey?: string;
505
- /** Linear GraphQL endpoint. Defaults to `https://api.linear.app/graphql`. */
506
259
  apiUrl?: string;
507
- /** The member's display name, e.g. `acme-agent`. `@acme-agent` addresses the agent. */
508
260
  userName?: string;
509
261
  webhookSecret?: string;
510
262
  trace?: "enabled" | "disabled";
@@ -530,41 +282,12 @@ interface AgentDiscordChannelConfig {
530
282
  publicKey?: string;
531
283
  allowedChannelIds?: string[];
532
284
  allowedUserIds?: string[];
533
- /** Bot's Discord user id. Set it to answer only when the agent is mentioned. */
534
285
  botUserId?: string;
535
- /** Role ids that count as mentioning the agent, e.g. an on-call role. */
536
286
  mentionRoleIds?: string[];
537
287
  trace?: "enabled" | "disabled";
538
288
  partition?: ChannelPartition;
539
289
  [key: string]: unknown;
540
290
  }
541
- /**
542
- * A Matrix account the agent speaks as. Matrix has no bot concept, so this is
543
- * usually a person's own account: replies carry a per-message profile named
544
- * `botName`, and `mentionText` decides what addresses the agent, because a
545
- * mention of the account would also be a mention of its owner.
546
- */
547
- interface AgentMatrixChannelConfig {
548
- id?: string;
549
- /** Homeserver base URL, e.g. `https://matrix.org`. */
550
- apiUrl?: string;
551
- /** Access token of the account; `apps/matrix-forwarder` syncs with it. */
552
- botToken?: string;
553
- /** Room ids. */
554
- allowedChannelIds?: string[];
555
- /** Matrix user ids, e.g. `@alice:matrix.org`. */
556
- allowedUserIds?: string[];
557
- /** Name replies are shown under. Unset, replies look like the account's own messages. */
558
- botName?: string;
559
- /**
560
- * Text that addresses the agent, e.g. `@georgi-ai`. Unset, a mention of the
561
- * account does. Other messages are stored as context either way.
562
- */
563
- mentionText?: string;
564
- trace?: "enabled" | "disabled";
565
- partition?: ChannelPartition;
566
- [key: string]: unknown;
567
- }
568
291
  interface AgentPancakeChannelConfig {
569
292
  allowedChannelIds?: string[];
570
293
  allowedUserIds?: string[];
@@ -587,73 +310,46 @@ interface AgentZaloChannelConfig {
587
310
  partition?: ChannelPartition;
588
311
  [key: string]: unknown;
589
312
  }
590
- /**
591
- * An Instagram professional account, reached through a Meta app with
592
- * Instagram Login. `accountId` is the account the webhook entries name.
593
- */
594
313
  interface AgentInstagramChannelConfig {
595
314
  allowedChannelIds?: string[];
596
315
  allowedUserIds?: string[];
597
316
  id?: string;
598
- /** Instagram user access token with `instagram_business_manage_messages`. */
599
317
  accessToken?: string;
600
- /** Instagram professional account id. */
601
318
  accountId?: string;
602
- /** Graph API version, e.g. `v26.0`. Defaults to the SDK's. */
603
319
  apiVersion?: string;
604
- /** Meta app secret; signs every webhook POST. */
605
320
  appSecret?: string;
606
321
  userName?: string;
607
- /** The verify token typed into the Meta webhook settings. */
608
322
  verifyToken?: string;
609
323
  trace?: "enabled" | "disabled";
610
324
  partition?: ChannelPartition;
611
325
  [key: string]: unknown;
612
326
  }
613
- /** A Facebook Page the agent answers Messenger DMs for. */
614
327
  interface AgentMessengerChannelConfig {
615
328
  allowedChannelIds?: string[];
616
329
  allowedUserIds?: string[];
617
330
  id?: string;
618
- /** Graph API version, e.g. `v21.0`. Defaults to the SDK's. */
619
331
  apiVersion?: string;
620
- /** Meta app secret; signs every webhook POST. */
621
332
  appSecret?: string;
622
- /** Page access token for the Page the app is subscribed to. */
623
333
  pageAccessToken?: string;
624
334
  userName?: string;
625
- /** The verify token typed into the Meta webhook settings. */
626
335
  verifyToken?: string;
627
336
  trace?: "enabled" | "disabled";
628
337
  partition?: ChannelPartition;
629
338
  [key: string]: unknown;
630
339
  }
631
- /**
632
- * A Google Chat app on the HTTP endpoint connection. It posts as the service
633
- * account in `credentials`, and a webhook is accepted when its Google-signed
634
- * token names `endpointUrl` or `googleChatProjectNumber` as the audience.
635
- */
636
340
  interface AgentGoogleChatChannelConfig {
637
341
  allowedChannelIds?: string[];
638
342
  allowedUserIds?: string[];
639
343
  id?: string;
640
- /** The service-account key JSON, as downloaded from Google Cloud. */
641
344
  credentials?: string;
642
- /** Audience when the app authenticates with "HTTP endpoint URL". */
643
345
  endpointUrl?: string;
644
- /** Audience when the app authenticates with "Project number". */
645
346
  googleChatProjectNumber?: string;
646
- /** `service-{projectNumber}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com`, for an app built as a Workspace add-on. */
647
347
  workspaceAddOnServiceAccountEmail?: string;
648
348
  userName?: string;
649
349
  trace?: "enabled" | "disabled";
650
350
  partition?: ChannelPartition;
651
351
  [key: string]: unknown;
652
352
  }
653
- /**
654
- * A Microsoft Teams bot registered in Azure Bot Service, authenticated with a
655
- * client secret. `appTenantId` is required unless `appType` is `MultiTenant`.
656
- */
657
353
  interface AgentTeamsChannelConfig {
658
354
  allowedChannelIds?: string[];
659
355
  allowedUserIds?: string[];
@@ -668,11 +364,6 @@ interface AgentTeamsChannelConfig {
668
364
  partition?: ChannelPartition;
669
365
  [key: string]: unknown;
670
366
  }
671
- /**
672
- * A Twilio number or Messaging Service for SMS and MMS. `authToken` checks
673
- * Twilio's signature, which covers the exact public URL Twilio called, so
674
- * `webhookUrl` is only set when that URL is not the broods webhook URL.
675
- */
676
367
  interface AgentTwilioChannelConfig {
677
368
  allowedChannelIds?: string[];
678
369
  allowedUserIds?: string[];
@@ -680,22 +371,16 @@ interface AgentTwilioChannelConfig {
680
371
  accountSid?: string;
681
372
  apiUrl?: string;
682
373
  authToken?: string;
683
- /** `MG...`. Replies go through the service instead of the number texted. */
684
374
  messagingServiceSid?: string;
685
- /** E.164 number, e.g. `+15551234567`. Messages to another number go to the agent holding it. */
686
375
  phoneNumber?: string;
687
376
  statusCallbackUrl?: string;
688
377
  userName?: string;
689
- /** The URL entered in the Twilio console, when it is not `{PUBLIC_BASE_URL}/v1/webhooks/...`. */
378
+ /** The URL Twilio calls, when not the broods webhook: its signature covers the exact URL. */
690
379
  webhookUrl?: string;
691
380
  trace?: "enabled" | "disabled";
692
381
  partition?: ChannelPartition;
693
382
  [key: string]: unknown;
694
383
  }
695
- /**
696
- * A WhatsApp Business Cloud API number. `appSecret` signs every delivery and
697
- * `verifyToken` answers Meta's subscription handshake.
698
- */
699
384
  interface AgentWhatsAppChannelConfig {
700
385
  allowedChannelIds?: string[];
701
386
  allowedUserIds?: string[];
@@ -712,18 +397,8 @@ interface AgentWhatsAppChannelConfig {
712
397
  [key: string]: unknown;
713
398
  }
714
399
 
715
- /**
716
- * Cron-job records and patch-merge helpers for the runtime. Input
717
- * normalization lives in the config plane (packages/convex/model/cronRules.ts,
718
- * the single home of those rules).
719
- */
720
-
721
400
  type CronStatus = "active" | "paused";
722
401
  type CronLastStatus = "started" | "completed" | "failed";
723
- /**
724
- * One-of run payload mirroring the agent direct API's AgentRunInput: provide a
725
- * single `input` string (wrapped into one user message) or a full `events` list.
726
- */
727
402
  type CronRunInput = {
728
403
  input: string;
729
404
  events?: never;
@@ -756,20 +431,9 @@ type UpdateCronInput = {
756
431
  input?: never;
757
432
  });
758
433
 
759
- /**
760
- * The sandbox provider list: the one list the schema validator, the config
761
- * rules, core's executor registry and the SDK derive from. A leaf on purpose,
762
- * so `schema.ts` can read it without pulling the rules' import graph.
763
- */
764
434
  declare const SANDBOX_PROVIDERS: readonly ["sandbox", "lambda", "e2b", "daytona", "vercel", "cloudflare", "worker", "machine", "custom"];
765
435
  type SandboxProvider = (typeof SANDBOX_PROVIDERS)[number];
766
436
 
767
- /**
768
- * Sandbox-config validation for the Convex config plane. Ports core's former
769
- * storage/sandbox-config.ts normalizer so the public /v1/sandboxes contract
770
- * is unchanged. The public projection lives in ./responses.ts.
771
- */
772
-
773
437
  declare const SANDBOX_IMAGES: readonly ["browser", "obscura"];
774
438
  declare const SANDBOX_RUNTIMES: readonly ["bash", "python", "node"];
775
439
  declare const SANDBOX_PERMISSION_MODES: readonly ["edit", "ask", "bypass"];
@@ -780,9 +444,6 @@ type PermissionMode = (typeof SANDBOX_PERMISSION_MODES)[number];
780
444
  type NetworkMode = (typeof SANDBOX_NETWORK_MODES)[number];
781
445
  type SandboxSize = (typeof SANDBOX_SIZE_NAMES)[number];
782
446
  type SandboxImage = (typeof SANDBOX_IMAGES)[number];
783
- /**
784
- * Idle and maximum lifetime controls for a persistent sandbox.
785
- */
786
447
  interface SandboxLifecycleConfig {
787
448
  idleTimeoutSeconds?: number;
788
449
  maxLifetimeSeconds?: number;
@@ -792,9 +453,6 @@ interface SandboxNetworkConfig {
792
453
  allowDomains?: string[];
793
454
  allowCidrs?: string[];
794
455
  }
795
- /**
796
- * Account-scoped reusable sandbox configuration referenced by agents.
797
- */
798
456
  interface SandboxConfig {
799
457
  provider: SandboxProvider;
800
458
  fallbackProvider?: SandboxProvider;
@@ -814,99 +472,49 @@ interface SandboxConfig {
814
472
  options?: Record<string, unknown>;
815
473
  }
816
474
 
817
- /**
818
- * Sandbox config: account-scoped, reusable sandbox definitions referenced by
819
- * agents via `config.sandboxes`. A sandbox is a collection of Claude-Code-style
820
- * tools (bash/read/write/edit/glob/grep) backed by a provider. Stored encrypted
821
- * at rest because `envVars`/`options` may hold secrets. Validation and the
822
- * public projection live in packages/convex/model/sandboxRules.ts. The exec
823
- * wire contract a sandbox server speaks is here too, since the SDK publishes it.
824
- */
825
-
826
- /**
827
- * One exec, POSTed as JSON to `<endpoint>/exec`. The `lambda` MicroVM image
828
- * speaks it and the `custom` provider lets an account point core at its own
829
- * server that does. snake_case on purpose: the image shipped it first.
830
- */
831
475
  interface SandboxExecRequest {
832
- /** Which interpreter runs `code`. Core sends `bash`. */
833
476
  runtime: RuntimeName;
834
477
  code: string;
835
- /** Workspace namespace; selects the working directory. Absent for a stateless run. */
478
+ /** Selects the working directory; absent for a stateless run. */
836
479
  namespace?: string;
837
- /** Root the namespace sits under; the server picks its default when absent. */
838
480
  workspace_root?: string;
839
- /** The server kills the process and answers `timed_out: true` once this passes. */
840
481
  timeout_ms: number;
841
- /** Positional arguments for `code`. */
842
482
  args?: string[];
843
- /** The process environment, set over an empty one or the server's start-up defaults (HOME, TMPDIR, PATH). */
844
483
  env: Record<string, string>;
845
484
  }
846
- /** The JSON answer to one exec; HTTP 200 even when the code failed. */
485
+ /** HTTP 200 even when the code failed. */
847
486
  interface SandboxExecResponse {
848
- /** False when the process failed, timed out, or the request was invalid. */
849
487
  ok: boolean;
850
488
  runtime?: string;
851
489
  /** Null when the process was killed by the timeout. */
852
490
  exit_code?: number | null;
853
491
  timed_out: boolean;
854
- /** Wall-clock time of the exec. */
855
492
  duration_ms: number;
856
493
  stdout: string;
857
494
  stderr: string;
858
- /** True when the server already cut stdout or stderr. */
859
495
  truncated?: boolean;
860
- /** CPU time of the exec in microseconds, for usage metering. */
861
496
  cpu_usec?: number;
862
- /** The machine's vCPU-s and GB-s above its baseline since boot. MicroVM only. */
497
+ /** MicroVM only: vCPU-s and GB-s above the machine's baseline since boot. */
863
498
  burst?: {
864
499
  vcpu_seconds: number;
865
500
  gb_seconds: number;
866
501
  };
867
502
  }
868
503
 
869
- /**
870
- * Workspace isolation levels, the one list the config plane, core, the
871
- * dashboard and the CLI read. No imports on purpose: the CLI bundles this file
872
- * without the Convex runtime behind workspaceRules (like modelProviders.ts).
873
- */
874
504
  declare const WORKSPACE_ISOLATION_LEVELS: readonly ["conversation", "agent"];
875
- /**
876
- * How a workspace splits its files. "conversation" mounts a folder per channel
877
- * partition, "agent" gives every attached agent its own folder. Unset shares
878
- * one root between every agent and conversation.
879
- */
505
+ /** A folder per channel partition or per agent; unset shares one root. */
880
506
  type WorkspaceIsolation = (typeof WORKSPACE_ISOLATION_LEVELS)[number];
881
507
 
882
- /**
883
- * Workspace-config validation for the Convex config plane. Ports core's
884
- * former storage/workspace-config.ts normalizer so the public /v1/workspaces
885
- * contract is unchanged. Workspace config holds no secrets (a roleArn is not
886
- * a secret, and R2 keys are `${NAME}` env refs), so it is stored and returned
887
- * in plaintext. Pure module, safe
888
- * for the default Convex runtime. The public projection lives in
889
- * ./responses.ts. Core runs the storage access rule too, so it reads the env
890
- * names of both sides.
891
- */
892
-
893
508
  declare const WORKSPACE_STORAGE_PROVIDERS: readonly ["s3"];
894
509
  type WorkspaceStorageProvider = (typeof WORKSPACE_STORAGE_PROVIDERS)[number];
895
510
  type WorkspaceStorageAuth = {
896
511
  type: "managed";
897
- }
898
- /**
899
- * The role's trust policy requires the account's Broods-assigned
900
- * sts:ExternalId (`storageTrust.ts`); a customer never sets one here.
901
- */
902
- | {
512
+ } | {
903
513
  type: "assumeRole";
904
514
  roleArn: string;
905
515
  } | {
906
516
  type: "r2";
907
- /** `${NAME}` ref to the parent R2 token's access key id. */
908
517
  accessKeyId: string;
909
- /** `${NAME}` ref to the parent R2 token's secret access key. */
910
518
  secretAccessKey: string;
911
519
  };
912
520
  interface WorkspaceStorageConfig {
@@ -930,11 +538,6 @@ interface WorkspaceConfig {
930
538
  };
931
539
  }
932
540
 
933
- /**
934
- * Versioned policy document accepted by account-management CRUD, as the
935
- * `agentPolicies` and `accountRoles` tables store it. `mode` says how hard
936
- * the policy bites where it is attached; omitted reads as `audit`.
937
- */
938
541
  declare const policyDocumentValidator: convex_values.VObject<{
939
542
  mode?: "enforce" | "audit" | undefined;
940
543
  version: 1;
@@ -1014,7 +617,6 @@ declare const policyDocumentValidator: convex_values.VObject<{
1014
617
  resourceIds?: string[] | undefined;
1015
618
  } | undefined, {
1016
619
  toolNames: convex_values.VArray<string[] | undefined, convex_values.VString<string, "required">, "optional">;
1017
- /** MCP registration ids, for scoping tool.call rules per server (#331). */
1018
620
  mcpIds: convex_values.VArray<string[] | undefined, convex_values.VString<string, "required">, "optional">;
1019
621
  workspaceIds: convex_values.VArray<string[] | undefined, convex_values.VString<string, "required">, "optional">;
1020
622
  workspaceNames: convex_values.VArray<string[] | undefined, convex_values.VString<string, "required">, "optional">;
@@ -1040,18 +642,9 @@ declare const policyDocumentValidator: convex_values.VObject<{
1040
642
  }, "required", "version" | "mode" | "rules">;
1041
643
  type PolicyDocument = Infer<typeof policyDocumentValidator>;
1042
644
 
1043
- /**
1044
- * Channel record validation for the config plane, the single home of the
1045
- * normalizers core's `shared/domain/channel-record.ts` re-exports. Kept free
1046
- * of Convex imports so the rules stay unit-testable; the public projection
1047
- * lives in ./responses.ts.
1048
- */
1049
- /** Where a reply lands: its own thread, or wherever the message came from. */
1050
645
  declare const CHANNEL_REPLY_TARGETS: readonly ["thread", "source"];
1051
646
  type ChannelReplyIn = (typeof CHANNEL_REPLY_TARGETS)[number];
1052
647
 
1053
- /** Telegram channel adapter. */
1054
-
1055
648
  interface TelegramSource {
1056
649
  chatId: number;
1057
650
  commandToken?: string;
@@ -1062,13 +655,6 @@ interface TelegramSource {
1062
655
  fromUsername?: string;
1063
656
  }
1064
657
 
1065
- /**
1066
- * Google Chat channel adapter, for a Chat app on an HTTP endpoint. The Chat
1067
- * SDK adapter is the transport: it verifies Google's signed token, reads the
1068
- * message and posts the reply as the app's service account. Pub/Sub delivery
1069
- * is not wired, so the app hears direct messages and @-mentions only.
1070
- */
1071
-
1072
658
  interface GoogleChatSource {
1073
659
  messageName: string;
1074
660
  spaceName: string;
@@ -1078,11 +664,6 @@ interface GoogleChatSource {
1078
664
  userName?: string;
1079
665
  }
1080
666
 
1081
- /**
1082
- * GitHub channel adapter. Event filtering and source mapping live here; auth and
1083
- * API calls go through the Chat SDK.
1084
- */
1085
-
1086
667
  interface GitHubSource {
1087
668
  owner: string;
1088
669
  repo: string;
@@ -1095,30 +676,18 @@ interface GitHubSource {
1095
676
  target: "issue" | "issue_comment" | "pull_request" | "pull_request_review_comment";
1096
677
  }
1097
678
 
1098
- /**
1099
- * Linear channel adapter, for @-mentions in issue comments. The Chat SDK
1100
- * adapter is the transport: it posts the reply under the comment thread and
1101
- * reacts to the comment. The signature check is the Linear SDK's webhook
1102
- * client, the same one the adapter runs. There is no streaming: every edit of
1103
- * a Linear comment comes back as another webhook delivery.
1104
- */
1105
-
1106
679
  interface LinearSource {
1107
- /** The comment that mentioned the agent, where the reaction goes. */
1108
680
  commentId: string;
1109
681
  issueId: string;
1110
- /** `linear:{issueId}:c:{rootCommentId}`: the reply nests under the root comment. */
1111
682
  threadId: string;
1112
683
  }
1113
684
 
1114
- /** Slack channel adapter. */
1115
-
1116
685
  interface SlackSource {
1117
686
  teamId: string;
1118
687
  channelId: string;
1119
- /** Where the reply goes. Unset posts to the channel. */
688
+ /** Where the reply goes; unset posts to the channel. */
1120
689
  threadTs?: string;
1121
- /** The thread the message arrived in, unset when it arrived in the channel. */
690
+ /** The thread the message arrived in. */
1122
691
  inThreadTs?: string;
1123
692
  messageTs?: string;
1124
693
  responseUrl?: string;
@@ -1126,8 +695,6 @@ interface SlackSource {
1126
695
  userId?: string;
1127
696
  }
1128
697
 
1129
- /** Discord channel adapter. */
1130
-
1131
698
  interface DiscordSource {
1132
699
  applicationId: string;
1133
700
  interactionToken?: string;
@@ -1140,37 +707,6 @@ interface DiscordSource {
1140
707
  userId?: string;
1141
708
  }
1142
709
 
1143
- /**
1144
- * Matrix channel adapter.
1145
- *
1146
- * Matrix delivers nothing over a webhook, so `apps/matrix-forwarder` holds a
1147
- * `/sync` long-poll per account, decrypts what arrives and POSTs each room
1148
- * message here. The forwarder also holds the account's end-to-end encryption
1149
- * keys, which is why every event sent into a room goes back through it.
1150
- * Media never does: an attachment's key rides the decrypted event, so this
1151
- * module downloads, decrypts, encrypts and uploads files against the
1152
- * homeserver itself.
1153
- *
1154
- * The wire shapes shared with the forwarder live in `matrix-wire.ts`.
1155
- */
1156
-
1157
- /** Where a reply goes: the room, and the thread when the message was in one. */
1158
- interface MatrixSource {
1159
- encrypted: boolean;
1160
- messageId: string;
1161
- roomId: string;
1162
- threadRootId?: string;
1163
- userId: string;
1164
- }
1165
-
1166
- /**
1167
- * Pancake channel adapter.
1168
- *
1169
- * Per-conversation policy (e.g. skipping human-owned conversations by tag) is
1170
- * not baked in: the parsed source carries `tagIds` so a user `onMessageReceived`
1171
- * hook can decide to drop the message.
1172
- */
1173
-
1174
710
  interface PancakeSource {
1175
711
  pageId: string;
1176
712
  conversationId: string;
@@ -1183,14 +719,6 @@ interface PancakeSource {
1183
719
  tagIds?: string[];
1184
720
  }
1185
721
 
1186
- /**
1187
- * Microsoft Teams channel adapter, on the Bot Framework. The Chat SDK adapter
1188
- * is the transport that reads the activity and posts the reply; the inbound
1189
- * token is checked with the Teams SDK's JWT validator, set up for Bot Framework
1190
- * connector tokens only, since the Chat SDK only reaches it through a full
1191
- * `Chat` instance.
1192
- */
1193
-
1194
722
  interface TeamsSource {
1195
723
  conversationId: string;
1196
724
  messageId: string;
@@ -1199,40 +727,18 @@ interface TeamsSource {
1199
727
  userName?: string;
1200
728
  }
1201
729
 
1202
- /**
1203
- * The core HTTP contract every handler speaks, plus generic request/response
1204
- * helpers. Handlers take a CoreRequest + RequestContext and return a Web
1205
- * Response; the transport edge (`src/server.ts`) builds the CoreRequest from
1206
- * a real request. Keep route-specific logic out of here.
1207
- */
1208
730
  declare global {
1209
731
  interface BunFetchRequestInit {
1210
732
  timeout?: number | boolean;
1211
733
  }
1212
734
  }
1213
735
 
1214
- /**
1215
- * Twilio channel adapter, for SMS and MMS on a Twilio number or Messaging
1216
- * Service. The Chat SDK adapter is the transport: it checks Twilio's
1217
- * signature, reads the form Twilio posts and sends the reply. SMS has no typing
1218
- * indicator and no reactions, so those actions do nothing.
1219
- */
1220
-
1221
736
  interface TwilioSource {
1222
- /** The person's number, where the reply goes. */
1223
737
  from: string;
1224
738
  messageSid: string;
1225
- /** The Twilio number they texted. */
1226
739
  to: string;
1227
740
  }
1228
741
 
1229
- /**
1230
- * WhatsApp channel adapter, on the WhatsApp Business Cloud API. The Chat SDK
1231
- * adapter is the transport: it checks Meta's signature, reads the message and
1232
- * posts the reply. Meta's GET subscription handshake is answered here too,
1233
- * because it arrives on the same webhook URL.
1234
- */
1235
-
1236
742
  interface WhatsAppSource {
1237
743
  messageId: string;
1238
744
  phoneNumberId: string;
@@ -1241,8 +747,6 @@ interface WhatsAppSource {
1241
747
  userWaId: string;
1242
748
  }
1243
749
 
1244
- /** Zalo channel adapter, on the official Zalo Bot API. */
1245
-
1246
750
  declare const ZALO_CHAT_TYPES: readonly ["PRIVATE", "GROUP"];
1247
751
  type ZaloChatType = (typeof ZALO_CHAT_TYPES)[number];
1248
752
  interface ZaloSource {
@@ -1255,20 +759,6 @@ interface ZaloSource {
1255
759
  date?: number;
1256
760
  }
1257
761
 
1258
- /**
1259
- * What Messenger and Instagram share. Both deliver Meta Graph webhooks: a GET
1260
- * subscription handshake answered with the verify token, an
1261
- * `X-Hub-Signature-256` HMAC over every POST, and one envelope of batched
1262
- * messaging events whose entries each name the Page or account they are for.
1263
- * Both reply through a Chat SDK adapter used as transport only. Each channel
1264
- * file builds its transport and names how the two differ.
1265
- */
1266
-
1267
- /**
1268
- * Where a Messenger or Instagram message came from. `recipientId` is the Page
1269
- * or Instagram professional account that received it; `threadId` is the Chat
1270
- * SDK thread the reply goes to.
1271
- */
1272
762
  interface MetaSource {
1273
763
  messageId: string;
1274
764
  recipientId: string;
@@ -1276,32 +766,10 @@ interface MetaSource {
1276
766
  threadId: string;
1277
767
  }
1278
768
 
1279
- /**
1280
- * Instagram DM channel adapter, on the Instagram API with Instagram Login. The
1281
- * Chat SDK adapter reads the message and posts the reply, media included; the
1282
- * Meta webhook handshake, signature check and event walk are shared with
1283
- * Messenger in `meta-channel.ts`.
1284
- */
1285
-
1286
769
  type InstagramSource = MetaSource;
1287
770
 
1288
- /**
1289
- * Facebook Messenger channel adapter, on the Messenger Platform Send API. The
1290
- * Chat SDK adapter reads the message, posts the reply and names the Page its
1291
- * token belongs to; the Meta webhook handshake, signature check and event walk
1292
- * are shared with Instagram in `meta-channel.ts`.
1293
- */
1294
-
1295
771
  type MessengerSource = MetaSource;
1296
772
 
1297
- /**
1298
- * Canonical CLI manifest wire types, the single source of truth shared by the
1299
- * backend (cliSync.ts, cliHttp.ts) and the SDK/CLI (packages/broods).
1300
- *
1301
- * This file intentionally has no runtime imports (its values are plain
1302
- * lists) so the SDK can import it without pulling the Convex server module
1303
- * graph into its typecheck.
1304
- */
1305
773
  type CliManifestResource = {
1306
774
  kind: "agent" | "workspace" | "sandbox" | "cron" | "skill" | "hook" | "mcp" | "policy" | "channelRecord";
1307
775
  name: string;
@@ -1319,26 +787,17 @@ type GeneratedIds = {
1319
787
  policies: Record<string, string>;
1320
788
  channelRecords: Record<string, string>;
1321
789
  };
1322
- /** Where a Production stage runs. */
1323
790
  declare const DEPLOYMENT_REGIONS: readonly ["ap-southeast-1", "eu-west-1", "us-east-1"];
1324
791
  type DeploymentRegion = (typeof DEPLOYMENT_REGIONS)[number];
1325
792
  type CliManifest = {
1326
793
  version: 1;
1327
794
  project: string;
1328
795
  stage: string;
1329
- /**
1330
- * Production only: the region its first deploy pins (eu-west-1 when unset).
1331
- * A later deploy naming another region is refused.
1332
- */
796
+ /** Production only: pinned by the first deploy; a later deploy naming another is refused. */
1333
797
  region?: DeploymentRegion;
1334
798
  resources: CliManifestResource[];
1335
799
  };
1336
800
 
1337
- /**
1338
- * Type contracts inherited from Convex and core domain/runtime modules.
1339
- * Keep this file type-only so the public SDK does not bundle backend code.
1340
- */
1341
-
1342
801
  type Id<TableName extends string = string> = string & {
1343
802
  readonly __tableName?: TableName;
1344
803
  };
@@ -1361,37 +820,22 @@ type AgentRunOverrides = {
1361
820
  model?: AgentRunModelOverrides;
1362
821
  };
1363
822
  type AgentRunEventInput = {
1364
- /** Shorthand for a single user text message. */
1365
823
  input: string;
1366
824
  events?: never;
1367
825
  answers?: never;
1368
826
  } | {
1369
- /** Full-fidelity event list for multimodal content or tool responses. */
1370
827
  events: [ModelMessage, ...ModelMessage[]];
1371
828
  input?: never;
1372
829
  answers?: never;
1373
830
  };
1374
- /**
1375
- * Resolves a run's events from either the explicit `events` list or the `input`
1376
- * string shorthand, matching the core direct API's event contract.
1377
- */
1378
831
  declare function resolveRunEvents(input: AgentRunEventInput): ModelMessage[];
1379
832
 
1380
- /**
1381
- * Shared direct-run stream contracts and SSE parsing helpers.
1382
- */
1383
-
1384
833
  type AgentStreamPart = TextStreamPart<ToolSet> | {
1385
834
  type: "structured-output";
1386
835
  output: unknown;
1387
836
  };
1388
- /** Yield the payload of each `data:` line from an SSE response body. */
1389
837
  declare function readSseStream(body: ReadableStream<Uint8Array>): AsyncGenerator<string>;
1390
838
 
1391
- /**
1392
- * Shared WebSocket wire message contracts used by the SDK client and gateway.
1393
- */
1394
-
1395
839
  type IngressMode = "reject" | "followup" | "collect" | "steer";
1396
840
  type IngressStatus = "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired";
1397
841
  /** One open `ask_questions` prompt while a run is `awaiting_input`. */
@@ -1422,9 +866,8 @@ type AgentRunAnswerInput = {
1422
866
  events?: never;
1423
867
  };
1424
868
  /**
1425
- * A frame too large for NATS arrives as its own `type` with `truncated: true`
1426
- * and `originalBytes`, its payload dropped. Read the full result from the run
1427
- * status.
869
+ * A frame too large for NATS keeps its `type`, gains `truncated: true` and `originalBytes`,
870
+ * and drops its payload: read the full result from the run status.
1428
871
  */
1429
872
  type WebSocketStreamMessage = AgentStreamPart | {
1430
873
  type: "question-request";
@@ -1469,9 +912,8 @@ type WebSocketServerMessage = {
1469
912
  statusUrl?: string;
1470
913
  } | WebSocketOutputMessage | WebSocketStreamMessage;
1471
914
  /**
1472
- * Durable-stream envelope around one stream part. The SDK unwraps `data` for
1473
- * handlers and surfaces the envelope itself through `onOutput` so clients can
1474
- * persist `cursor` for attach-based resume.
915
+ * The SDK unwraps `data` for handlers and passes this envelope to `onOutput`, so a client
916
+ * can persist `cursor` to resume with `attach`.
1475
917
  */
1476
918
  type WebSocketOutputMessage = {
1477
919
  type: "output";
@@ -1512,13 +954,6 @@ type WebSocketClientCancelMessage = {
1512
954
  };
1513
955
  type WebSocketClientMessage = WebSocketClientExecuteMessage | WebSocketClientControlMessage | WebSocketClientAttachMessage | WebSocketClientCancelMessage;
1514
956
 
1515
- /**
1516
- * Wire types for the public account-manage and harness APIs. These mirror
1517
- * the deployed API contract (docs/api-reference/openapi.yaml is the source
1518
- * of truth); they are intentionally independent of the runtime internals so
1519
- * the SDK keeps working when the runtime is ported.
1520
- */
1521
-
1522
957
  interface Account {
1523
958
  account: {
1524
959
  accountId: string;
@@ -1533,9 +968,7 @@ interface Agent {
1533
968
  }
1534
969
  interface AsyncRequestAccepted {
1535
970
  statusUrl: string;
1536
- /** Account-unique id for this run; what the status URL names. */
1537
971
  runId: string;
1538
- /** The eventId sent with the request, echoed back. */
1539
972
  eventId: string;
1540
973
  agentId: string;
1541
974
  status?: "accepted" | "queued" | "applied" | "processing";
@@ -1543,10 +976,9 @@ interface AsyncRequestAccepted {
1543
976
  }
1544
977
  interface AsyncStatus {
1545
978
  status: "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired" | "not_found";
1546
- /** Set on every core answer. Absent only on the `not_found` the SDK returns for a 404. */
979
+ /** Absent only on the `not_found` the SDK returns for a 404. */
1547
980
  runId?: string;
1548
981
  eventId?: string;
1549
- /** The agent that owns the run. A subagent run names the child agent. */
1550
982
  agentId?: string;
1551
983
  conversationKey?: string;
1552
984
  requestedMode?: "reject" | "followup" | "collect" | "steer";
@@ -1555,7 +987,6 @@ interface AsyncStatus {
1555
987
  result?: unknown;
1556
988
  response?: unknown;
1557
989
  error?: string;
1558
- /** True when `failed` was a deliberate /stop, not a fault. */
1559
990
  stoppedByUser?: boolean;
1560
991
  approvals?: ToolApprovalSummary[];
1561
992
  questions?: PendingQuestion[];
@@ -1602,7 +1033,6 @@ interface Skill {
1602
1033
  size?: number;
1603
1034
  }>;
1604
1035
  }
1605
- /** A tool call held for user approval by an `ask`-mode sandbox. */
1606
1036
  interface ToolApprovalSummary {
1607
1037
  approvalId: string;
1608
1038
  toolCallId: string;
@@ -1614,11 +1044,6 @@ interface Workspace {
1614
1044
  name: string;
1615
1045
  }
1616
1046
 
1617
- /**
1618
- * Shared WebSocket wire-protocol types for the observability gateway, used by
1619
- * the gateway, the SDK/CLI, and the dashboard. Pure types + tiny pure helpers,
1620
- * zero runtime deps. Kept separate from the agent-test websocket-contracts.
1621
- */
1622
1047
  declare const MAX_OBSERVABILITY_BACKFILL = 500;
1623
1048
  type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
1624
1049
  type ObservabilityLogEntry = {
@@ -1691,38 +1116,20 @@ type ObservabilityErrorMessage = {
1691
1116
  error: string;
1692
1117
  };
1693
1118
  type ObservabilityServerMessage = ObservabilityReadyMessage | ObservabilityBackfillMessage | ObservabilityLogMessage | ObservabilitySpanMessage | ObservabilityErrorMessage;
1694
- /** Narrow an unknown wire value to a LogLevel. */
1695
1119
  declare function isLogLevel(value: unknown): value is LogLevel;
1696
1120
  declare function isObservabilityClientMessage(v: unknown): v is ObservabilityClientMessage;
1697
- /** Whether a span is a top-level run, each of which owns its own trace. */
1698
1121
  declare function isRootSpanKind(kind: ObservabilitySpanRow["kind"]): boolean;
1699
- /**
1700
- * Narrow a wire value to a sandbox log id. Strict on purpose: the gateway
1701
- * interpolates it into LogQL, so only the UUID shape core mints may pass.
1702
- */
1122
+ /** Strict on purpose: the gateway interpolates it into LogQL. */
1703
1123
  declare function isSandboxLogId(value: unknown): value is string;
1704
- /** Whether a value is a real trace id a log line can be followed to. */
1705
1124
  declare function isTraceId(value: unknown): value is string;
1706
1125
 
1707
- /**
1708
- * Configurable client for running deployed agents over direct core SSE.
1709
- * Stream chunks are the Vercel AI SDK's `TextStreamPart` parts that core emits.
1710
- */
1711
-
1712
1126
  declare const DEFAULT_CORE_BASE_URL = "https://gateway.broods.app";
1713
- /**
1714
- * Input for a single agent run. The core direct API is event-based (a list of
1715
- * Vercel AI SDK model messages), so `events` is the full-fidelity form. Use it
1716
- * for multimodal content (images/files), ephemeral system messages, or
1717
- * tool-approval responses. `input` is a shorthand for a single user text message
1718
- * and is wrapped into one user event. Provide exactly one of the two.
1719
- */
1720
1127
  type AgentRunInputBase = {
1721
1128
  conversationKey?: string;
1722
1129
  eventId?: string;
1723
- /** Busy-conversation behavior. Defaults to `steer`: join the live run at its next step boundary (falls back to a FIFO follow-up). */
1130
+ /** When the conversation is busy. Default `steer` joins the live run at its next step. */
1724
1131
  mode?: "reject" | "followup" | "collect" | "steer";
1725
- /** Stable retry identity within the conversation; defaults to eventId. */
1132
+ /** Defaults to `eventId`. */
1726
1133
  idempotencyKey?: string;
1727
1134
  } & AgentRunOverrides;
1728
1135
  type AgentRunInput = AgentRunInputBase & AgentRunEventInput;
@@ -1730,7 +1137,6 @@ interface AgentRunResult {
1730
1137
  text: string;
1731
1138
  events: TextStreamPart<ToolSet>[];
1732
1139
  }
1733
- /** Input for `continue`: the conversation to re-enter. */
1734
1140
  interface AgentContinueInput {
1735
1141
  /** The key given to `run`, or the scoped key a dashboard trace row shows. */
1736
1142
  conversationKey: string;
@@ -1756,19 +1162,13 @@ interface AgentReference<Name extends string = string> {
1756
1162
  readonly id: string;
1757
1163
  readonly project: string;
1758
1164
  readonly stage: string;
1759
- /**
1760
- * Authoritative scope of the stage's runtime key, embedded by codegen
1761
- * from the deploy response. When present the client posts to the scoped URL
1762
- * `/v1/projects/{projectSlug}/stages/{stageSlug}/agents/{endpointId}` (matching the
1763
- * dashboard); when absent it falls back to the base URL.
1764
- */
1765
1165
  readonly endpointId?: string;
1766
1166
  readonly projectSlug?: string;
1767
1167
  readonly stageSlug?: string;
1768
1168
  }
1769
1169
  interface ChannelReference {
1770
1170
  readonly kind: "channel";
1771
- readonly type: "telegram" | "gchat" | "github" | "linear" | "slack" | "discord" | "matrix" | "pancake" | "teams" | "twilio" | "zalo" | "whatsapp" | "instagram" | "messenger";
1171
+ readonly type: "telegram" | "gchat" | "github" | "linear" | "slack" | "discord" | "pancake" | "teams" | "twilio" | "zalo" | "whatsapp" | "instagram" | "messenger";
1772
1172
  readonly agentName: string;
1773
1173
  readonly agentId: string;
1774
1174
  readonly accountId: string;
@@ -1784,20 +1184,12 @@ interface ResourceApi {
1784
1184
  readonly policies?: Record<string, unknown>;
1785
1185
  }
1786
1186
  interface BroodsClientOptions {
1787
- /**
1788
- * Base URL of the core service to call directly. Use `https://gateway.broods.app`
1789
- * for the hosted service. If you only have a domain, use `host` instead.
1790
- */
1791
1187
  baseUrl?: string;
1792
- /** Hostname or URL of the core service. `gateway.broods.app` becomes `https://gateway.broods.app`. */
1793
1188
  host?: string;
1794
- /** Runtime key used as the Bearer token for direct runtime calls. */
1795
1189
  apiKey?: string;
1796
1190
  /**
1797
- * The signed-in user's token, sent beside the runtime key on every call.
1798
- * Pass a function to get a fresh one per call (a browser fetches it from
1799
- * your backend, which signs it with `signUserToken`). An agent that
1800
- * requires one refuses the runtime key without it.
1191
+ * Sent beside the runtime key; an agent that requires one refuses the key alone.
1192
+ * A function fetches a fresh token per call, e.g. one your backend signs with `signUserToken`.
1801
1193
  */
1802
1194
  userToken?: string | (() => string | Promise<string>);
1803
1195
  fetch?: typeof fetch;
@@ -1815,62 +1207,37 @@ declare class BroodsClient {
1815
1207
  private readonly userToken?;
1816
1208
  private readonly fetchImpl;
1817
1209
  constructor(options?: BroodsClientOptions);
1818
- /** Return the public provider webhook URL for a generated channel reference. */
1819
1210
  channelWebhookUrl(ref: ChannelReference): string;
1820
- /**
1821
- * Return the provider webhook URL for an account's channel. The URL names no
1822
- * agent, since every channel of one type in an account shares it, so this is
1823
- * what to paste into the provider when several agents sit behind the same app.
1824
- */
1211
+ /** Names no agent: paste it into the provider when several agents share one app. */
1825
1212
  accountWebhookUrl(accountId: string, channelType: ChannelReference["type"]): string;
1826
- /**
1827
- * Return the provider webhook URL pinned to one stage. Production keeps the
1828
- * bare account URL from `accountWebhookUrl`.
1829
- */
1213
+ /** Pinned to one non-production stage; production uses `accountWebhookUrl`. */
1830
1214
  stageWebhookUrl(accountId: string, endpointId: string, channelType: ChannelReference["type"]): string;
1831
1215
  agent<const Name extends string>(ref: AgentReference<Name>): AgentHandle;
1832
1216
  agent(name: string, agentId: string): AgentHandle;
1833
- /** Run an agent and accumulate the streamed text and raw parts. */
1834
1217
  run(ref: AgentReference, input: AgentRunInput): Promise<AgentRunResult>;
1835
1218
  run(input: AgentRunInput & {
1836
1219
  agentId: string;
1837
1220
  agentName?: string;
1838
1221
  }): Promise<AgentRunResult>;
1839
- /** Stream an agent run, yielding each AI SDK `TextStreamPart` as it arrives. */
1840
1222
  stream(ref: AgentReference, input: AgentRunInput): AsyncGenerator<TextStreamPart<ToolSet>>;
1841
1223
  stream(input: AgentRunInput & {
1842
1224
  agentId: string;
1843
1225
  agentName?: string;
1844
1226
  }): AsyncGenerator<TextStreamPart<ToolSet>>;
1845
- /** Start an async agent run and return the status id/URL used for polling. */
1846
1227
  runAsync(ref: AgentReference, input: AgentRunInput): Promise<AsyncAgentRun>;
1847
1228
  runAsync(input: AgentRunInput & {
1848
1229
  agentId: string;
1849
1230
  agentName?: string;
1850
1231
  }): Promise<AsyncAgentRun>;
1851
- /**
1852
- * Re-enter a conversation whose last turn stopped short (step cap, provider
1853
- * fault). Core adds one "continue" user turn on the persisted history and
1854
- * runs it like a background run; a live channel session answers in its channel.
1855
- */
1232
+ /** Re-enter a conversation whose last turn stopped short (step cap, provider fault). */
1856
1233
  continue(ref: AgentReference, input: AgentContinueInput): Promise<AsyncAgentRun>;
1857
1234
  continue(input: AgentContinueInput & {
1858
1235
  agentId: string;
1859
1236
  }): Promise<AsyncAgentRun>;
1860
- /** Fetch one async status snapshot by status URL or run id. */
1861
1237
  getAsyncStatus(status: AsyncRequestAccepted | string): Promise<AsyncStatus>;
1862
- /** Poll async status until it reaches completed, failed, awaiting_approval, awaiting_input, or timeout. */
1863
1238
  waitForAsyncStatus(status: AsyncRequestAccepted | string, options?: AsyncPollOptions): Promise<AsyncStatus>;
1864
- /**
1865
- * Scoped invoke URL for a deployed agent. When codegen embedded the runtime
1866
- * key's scope, this is
1867
- * `/v1/projects/{projectSlug}/stages/{stageSlug}/agents/{endpointId}` (the
1868
- * same URL the dashboard shows, so core can validate the key against the
1869
- * path); otherwise it falls back to the single run endpoint.
1870
- */
1871
1239
  private scopedUrl;
1872
1240
  private asyncAgentRun;
1873
- /** POST a run body that must answer 202 and wrap the accepted run for polling. */
1874
1241
  private postAcceptedRun;
1875
1242
  private openStream;
1876
1243
  private fetchCore;
@@ -1881,33 +1248,14 @@ declare class BroodsClient {
1881
1248
  }
1882
1249
  declare function normalizeHttpServiceUrl(value: string): string;
1883
1250
 
1884
- /** The HTTP header a token rides on. */
1885
1251
  declare const USER_TOKEN_HEADER = "x-broods-user-token";
1886
- /** A token naming a later expiry is refused: it is a bearer for its whole life. */
1887
1252
  declare const USER_TOKEN_MAX_TTL_MS: number;
1888
1253
 
1889
- /**
1890
- * Server-side signing of end-user tokens. The runtime key (`bsk_`) sits in a
1891
- * frontend, so it cannot say who is using it; your backend, which knows the
1892
- * signed-in user, signs a short-lived token with the stage's signing secret
1893
- * (`bsig_`, from the dashboard's Runtime key tab) and hands it to the
1894
- * frontend. Core then keeps every conversation that request touches under
1895
- * that user, so one visitor can never read or steer another's. Never ship the
1896
- * signing secret to a browser.
1897
- */
1898
-
1899
- /**
1900
- * The env var `signUserToken` reads the signing secret from, and the one
1901
- * `broods dev` / `broods deploy` write it to in `.env.local`.
1902
- */
1903
1254
  declare const USER_TOKEN_SECRET_ENV = "BROODS_USER_TOKEN_SECRET";
1904
1255
  interface SignUserTokenInput {
1905
1256
  /** Your own id for the signed-in user. Letters, digits and `._@+=-`, at most 128. */
1906
1257
  userId: string;
1907
- /**
1908
- * The conversation keys this user may use. Omit to allow any key, which
1909
- * still lands under this user only.
1910
- */
1258
+ /** Conversation keys this user may use. Omit to allow any key, still under this user only. */
1911
1259
  conversations?: string[];
1912
1260
  /** Lifetime in ms. Defaults to 10 minutes, at most 60. */
1913
1261
  ttlMs?: number;
@@ -1915,38 +1263,26 @@ interface SignUserTokenInput {
1915
1263
  secret?: string;
1916
1264
  }
1917
1265
  /**
1918
- * A user token for the runtime key: pass it as `userToken` to `BroodsClient`
1919
- * or `BroodsWebSocketClient`, or send it in the `X-Broods-User-Token` header.
1266
+ * Signs a short-lived token for your signed-in user, so core keeps that user's conversations
1267
+ * apart. Call it on your backend only: never ship the `bsig_` secret to a browser. Pass the
1268
+ * token as `userToken` to `BroodsClient` or `BroodsWebSocketClient`.
1920
1269
  * @throws when no signing secret is set or an input is out of range
1921
1270
  */
1922
1271
  declare function signUserToken(input: SignUserTokenInput): Promise<string>;
1923
1272
 
1924
- /**
1925
- * Connections: external accounts an agent acts through, one of each type per
1926
- * Broods account. `broods connect <type>` opens the provider's sign-in; the
1927
- * deployment trades the code, checks the ID token and keeps the tokens, and
1928
- * core refreshes them from then on. `chatgpt` backs the `chatgpt` model
1929
- * provider. Plain data, so the CLI, the config plane, core and the dashboard
1930
- * read one copy.
1931
- */
1932
1273
  declare const CONNECTION_TYPE_NAMES: readonly ["chatgpt"];
1933
1274
  type ConnectionType = (typeof CONNECTION_TYPE_NAMES)[number];
1934
- /** Starts a sign-in: `POST /v1/account/connections/{type}/start`. */
1935
1275
  interface ConnectionStart {
1936
- /** The loopback address the provider redirects back to. */
1937
1276
  redirectUri: string;
1938
1277
  codeChallenge: string;
1939
1278
  state: string;
1940
1279
  nonce: string;
1941
1280
  }
1942
- /** The provider's consent screen, plus the client and host id the PUT echoes back. */
1943
1281
  interface ConnectionStartResult {
1944
1282
  authorizeUrl: string;
1945
- /** The client the consent runs on; a redirect that signs in again may omit it. */
1946
1283
  clientId: string;
1947
1284
  hostId: string;
1948
1285
  }
1949
- /** Finishes a sign-in: `PUT /v1/account/connections/{type}` with the redirect's code. */
1950
1286
  interface ConnectionCode {
1951
1287
  code: string;
1952
1288
  codeVerifier: string;
@@ -1956,71 +1292,37 @@ interface ConnectionCode {
1956
1292
  clientId: string;
1957
1293
  hostId: string;
1958
1294
  }
1959
- /** A connection as the API answers it: never its tokens. */
1960
1295
  interface Connection {
1961
1296
  type: ConnectionType;
1962
1297
  clientId: string;
1963
- /** The deployment's `ext_agent_host_id`, kept across sign-ins. */
1964
1298
  hostId: string;
1965
1299
  email?: string;
1966
1300
  scopes: string[];
1967
- /** ISO 8601 access-token expiry; Broods refreshes it before then. */
1968
1301
  expiresAt: string;
1969
1302
  updatedAt: string;
1970
- /** Answered by a sign-in only: the models the plan may call. */
1971
1303
  models?: string[];
1972
1304
  }
1973
1305
 
1974
- /**
1975
- * Account config-plane client for the broods public account REST API.
1976
- *
1977
- * This is the DYNAMIC counterpart to the config-first `broods dev` / `broods
1978
- * deploy` flow: `broods dev` syncs the predefined resources declared in your
1979
- * `broods/` folder, while `BroodsAccountClient` creates and mutates the full
1980
- * account config plane at runtime: agents, sandboxes (config + lifecycle),
1981
- * workspaces (config + files), tools, policies, skills, crons, and the account
1982
- * itself. One caller is a multi-tenant app provisioning one agent per customer
1983
- * from its own backend.
1984
- *
1985
- * Kept intentionally standalone (import from `broods/account`): pure fetch,
1986
- * no Node built-ins, no `.env` file loading, so it runs in edge/worker
1987
- * runtimes such as Convex actions, Cloudflare Workers, and the browser-less
1988
- * server runtimes, as well as Node and Bun.
1989
- *
1990
- * Auth: every call sends `Authorization: Bearer {accountSecret}` to
1991
- * `{baseUrl}/v1/...`, or a short-lived `bsts_` role session token from
1992
- * `assumeRole()`, limited to what the role's policy allows. Secrets inside
1993
- * agent configs are encrypted at rest by the platform and come back redacted
1994
- * (`********`) on reads.
1995
- */
1996
-
1997
- /** A config PATCH body: objects merge key by key, `null` deletes a key, arrays and scalars replace. */
1306
+ /** Objects merge key by key, `null` deletes a key, arrays and scalars replace. */
1998
1307
  type ConfigPatch<T> = T extends readonly unknown[] ? T : T extends object ? {
1999
1308
  [K in keyof T]?: ConfigPatch<T[K]> | null;
2000
1309
  } : T;
2001
1310
  interface BroodsAccountClientOptions {
2002
- /** Base URL of the broods gateway. Falls back to `BROODS_BASE_URL`, then `https://gateway.broods.app`. */
2003
1311
  baseUrl?: string;
2004
- /** Account key used as the Bearer token. Falls back to `BROODS_ACCOUNT_SECRET`. */
2005
1312
  accountSecret?: string;
2006
- /**
2007
- * Short-lived `bsts_` role session token (from {@link BroodsAccountClient.assumeRole})
2008
- * used as the Bearer instead of the account key. The session can only do
2009
- * what its role's policy allows. Falls back to `BROODS_SESSION_TOKEN`.
2010
- */
1313
+ /** From {@link BroodsAccountClient.assumeRole}; wins over `accountSecret`. */
2011
1314
  sessionToken?: string;
2012
1315
  fetch?: typeof fetch;
2013
1316
  }
2014
- /** Public account record returned by `GET /v1/account`. */
2015
1317
  interface BroodsAccount {
2016
1318
  accountId: string;
2017
1319
  username: string;
2018
1320
  status: string;
2019
- /** Days an audit row is kept; absent means the 90 day default. */
1321
+ /** Absent means the 90 day default. */
2020
1322
  auditRetentionDays?: number;
2021
1323
  [key: string]: unknown;
2022
1324
  }
2023
- /** Public agent record; `config` comes back with secret values redacted. */
1325
+ /** `config` secrets come back redacted as `********`. */
2024
1326
  interface AccountAgent {
2025
1327
  accountId: string;
2026
1328
  agentId: string;
@@ -2037,20 +1339,16 @@ interface CreateAgentResult {
2037
1339
  name: string;
2038
1340
  description?: string;
2039
1341
  }
2040
- /** Write-only account environment variable metadata. */
2041
1342
  interface AccountEnvVar {
2042
1343
  name: string;
2043
- /** ISO 8601, like every other timestamp in the API. */
2044
1344
  updatedAt: string;
2045
1345
  }
2046
1346
 
2047
- /** Fields accepted by `PATCH /v1/agents/{id}`. `config` is deep-merged; `null` values delete keys. */
2048
1347
  interface UpdateAgentInput {
2049
1348
  name?: string;
2050
1349
  description?: string | null;
2051
1350
  config?: ConfigPatch<AgentConfig>;
2052
1351
  }
2053
- /** Public workspace record returned by the workspaces routes. */
2054
1352
  interface AccountWorkspace {
2055
1353
  accountId: string;
2056
1354
  workspaceId: string;
@@ -2060,7 +1358,6 @@ interface AccountWorkspace {
2060
1358
  createdAt: string;
2061
1359
  updatedAt: string;
2062
1360
  }
2063
- /** One entry of a workspace file listing (`GET /v1/workspaces/{id}/files`). */
2064
1361
  interface WorkspaceFileEntry {
2065
1362
  path: string;
2066
1363
  name: string;
@@ -2068,7 +1365,7 @@ interface WorkspaceFileEntry {
2068
1365
  sizeBytes?: number;
2069
1366
  updatedAt?: string;
2070
1367
  }
2071
- /** Public sandbox config record; `config` comes back with secret values (e.g. `envVars`) redacted. */
1368
+ /** `config` secrets such as `envVars` come back redacted. */
2072
1369
  interface AccountSandbox {
2073
1370
  accountId: string;
2074
1371
  sandboxId: string;
@@ -2079,7 +1376,6 @@ interface AccountSandbox {
2079
1376
  updatedAt: string;
2080
1377
  [key: string]: unknown;
2081
1378
  }
2082
- /** Public agent-policy record returned by the policies routes. */
2083
1379
  interface AccountPolicy {
2084
1380
  accountId: string;
2085
1381
  policyId: string;
@@ -2090,11 +1386,7 @@ interface AccountPolicy {
2090
1386
  createdAt: string;
2091
1387
  updatedAt: string;
2092
1388
  }
2093
- /**
2094
- * Public account-role record returned by the roles routes. The policy uses the
2095
- * API action namespace (`"agents:read"`, `"crons:write"`, ...); `projectId` and
2096
- * `stageId` bound which runtime keys may assume the role.
2097
- */
1389
+ /** `policy` uses API actions (`agents:read`); `projectId` + `stageId` bound who may assume it. */
2098
1390
  interface AccountRole {
2099
1391
  accountId: string;
2100
1392
  roleId: string;
@@ -2106,7 +1398,6 @@ interface AccountRole {
2106
1398
  createdAt: string;
2107
1399
  updatedAt: string;
2108
1400
  }
2109
- /** One link of an agent actor's delegation chain: who asked, or an agent that delegated. */
2110
1401
  type AuditPrincipalLink = {
2111
1402
  kind: "user";
2112
1403
  id: string;
@@ -2120,10 +1411,8 @@ type AuditPrincipalLink = {
2120
1411
  agentId: string;
2121
1412
  };
2122
1413
  /**
2123
- * One row of the account's hash-chained audit ledger, as `GET /v1/audit`
2124
- * serves it. `hash` is sha256 over the canonical JSON of every field but
2125
- * `hash` itself (an absent optional field is left out, not null), with
2126
- * `prevHash` linking it to the row before.
1414
+ * `hash` is sha256 of the canonical JSON of every other field (an absent optional is left
1415
+ * out, not null); `prevHash` is the previous row's `hash`.
2127
1416
  */
2128
1417
  interface AuditEvent {
2129
1418
  accountId: string;
@@ -2153,44 +1442,31 @@ interface AuditEvent {
2153
1442
  stageId?: string;
2154
1443
  traceId?: string;
2155
1444
  }
2156
- /** A page of ledger rows plus the chain head to compare the last row against. */
2157
1445
  interface AuditPage {
2158
1446
  events: AuditEvent[];
2159
- /** Pass as `since` to read the rows after this page. */
2160
1447
  nextSince: number;
2161
1448
  head: {
2162
1449
  seq: number;
2163
1450
  hash: string;
2164
1451
  } | null;
2165
1452
  }
2166
- /** Result of `GET /v1/audit/verify`: the chain recomputed over the checked range. */
2167
1453
  interface AuditVerification {
2168
1454
  ok: boolean;
2169
1455
  brokenAtSeq?: number;
2170
1456
  checkedFrom?: number;
2171
1457
  checkedTo?: number;
2172
1458
  }
2173
- /** The account's audit export target. The signing secret never comes back. */
2174
1459
  interface AuditSink {
2175
1460
  kind: "webhook";
2176
1461
  url: string;
2177
- /** Highest seq the receiver acknowledged. */
2178
1462
  exportedSeq: number;
2179
1463
  lastError?: string;
2180
1464
  updatedAt: string;
2181
1465
  }
2182
- /** Short-lived role session minted by `POST /v1/account/assume-role`. */
2183
1466
  interface AssumeRoleResult {
2184
- /** `bsts_` bearer token; pass it as `sessionToken` to a new client. */
2185
1467
  token: string;
2186
- /** ISO timestamp when the session stops working. */
2187
1468
  expiresAt: string;
2188
1469
  }
2189
- /**
2190
- * One real place a team talks, bound to an agent: a Slack channel, a Discord
2191
- * channel, a repo. The runtime reads it on the inbound webhook to decide who
2192
- * answers there and with what instructions, workspaces and policies.
2193
- */
2194
1470
  interface AccountChannel {
2195
1471
  accountId: string;
2196
1472
  channelId: string;
@@ -2216,39 +1492,26 @@ interface ChannelRecordConfig {
2216
1492
  name: string;
2217
1493
  workspaceId: string;
2218
1494
  }>;
2219
- /** Added to whatever the agent already carries. Each policy holds its own mode. */
2220
1495
  policies?: string[];
2221
- /**
2222
- * Tool names withheld in this channel, applied after the tool set is built,
2223
- * so it also covers sandbox tools (`bash`, `read`, …) that `config.tools`
2224
- * cannot name. Narrowing only; unknown names are ignored.
2225
- */
1496
+ /** Also covers sandbox tools (`bash`, `read`, …); unknown names are ignored. */
2226
1497
  denyTools?: string[];
2227
- /**
2228
- * Where the reply lands. `source` answers wherever the message came from, and
2229
- * threads only when the message already did. Slack only. No other provider
2230
- * gives the runtime a second place to reply.
2231
- */
1498
+ /** Slack only. `source` replies where the message came from, threading only if it was. */
2232
1499
  replyIn?: ChannelReplyIn;
2233
1500
  partition?: ChannelPartition;
2234
- /** Images the agent may stand a sandbox up from for a thread here. */
2235
1501
  sandboxImages?: string[];
2236
- /** Named groups of people, readable from policy conditions as `userRoles`. */
1502
+ /** Readable from policy conditions as `userRoles`. */
2237
1503
  tagRoles?: Array<{
2238
1504
  roleId: string;
2239
1505
  userIds: string[];
2240
1506
  }>;
2241
1507
  }
2242
- /** The stage a resource belongs to. Same name in two stages = two resources. */
2243
1508
  interface StageScope {
2244
1509
  project: string;
2245
1510
  stage: string;
2246
1511
  }
2247
1512
  /**
2248
- * OAuth 2.0 refresh-token grant on an external MCP row. The runtime mints and
2249
- * refreshes access tokens and sends `Authorization: Bearer <token>` itself.
2250
- * `clientSecret` and `refreshToken` must be `${NAME}` account env refs;
2251
- * `tokenUrl` defaults to https://oauth2.googleapis.com/token.
1513
+ * Refresh-token grant; the runtime mints the Bearer itself. `clientSecret` and `refreshToken`
1514
+ * must be `${NAME}` env refs; `tokenUrl` defaults to https://oauth2.googleapis.com/token.
2252
1515
  */
2253
1516
  interface McpOauthInput {
2254
1517
  clientId: string;
@@ -2256,9 +1519,8 @@ interface McpOauthInput {
2256
1519
  refreshToken: string;
2257
1520
  tokenUrl?: string;
2258
1521
  }
2259
- /** Where a hosted MCP server may run. */
1522
+ /** `auto` (the default) runs a hosted bundle on Cloudflare Workers when it can, else Lambda. */
2260
1523
  type McpRuntime = "auto" | "lambda";
2261
- /** Public MCP server registration returned by the `/v1/mcp` routes (#331). */
2262
1524
  interface AccountMcp {
2263
1525
  accountId: string;
2264
1526
  serverId: string;
@@ -2266,16 +1528,12 @@ interface AccountMcp {
2266
1528
  stageId: string;
2267
1529
  name: string;
2268
1530
  description?: string;
1531
+ /** `http` sets `url`, `hosted` sets `sha256`/`runtime`, `machine` sets `sandbox`/`command`. */
2269
1532
  transport: "http" | "hosted" | "machine";
2270
- /** External servers only; a hosted row has no endpoint of its own. */
2271
1533
  url?: string;
2272
- /** Machine servers only: the sandbox (by name) that serves it. */
2273
1534
  sandbox?: string;
2274
- /** Machine servers only: argv of the stdio server a lambda sandbox runs. */
2275
1535
  command?: string[];
2276
- /** Hosted servers only: content hash of the uploaded bundle. */
2277
1536
  sha256?: string;
2278
- /** Hosted servers only: "auto" or "lambda". */
2279
1537
  runtime?: McpRuntime;
2280
1538
  headers?: Record<string, string>;
2281
1539
  oauth?: McpOauthInput;
@@ -2286,11 +1544,7 @@ interface AccountMcp {
2286
1544
  updatedAt: string;
2287
1545
  deletedAt?: string;
2288
1546
  }
2289
- /**
2290
- * Fields accepted by `POST /v1/mcp`: `url` connects, `bundle` uploads inline
2291
- * (≤10 MB); a larger bundle goes through `uploadMcpBundle` first; `sandbox`
2292
- * runs it on that sandbox: a machine's daemon, or `command` on a lambda VM.
2293
- */
1547
+ /** `bundle` inline is ≤10 MB, a larger one goes through `uploadMcpBundle` first. */
2294
1548
  interface CreateMcpInput {
2295
1549
  name: string;
2296
1550
  description?: string;
@@ -2303,14 +1557,8 @@ interface CreateMcpInput {
2303
1557
  headers?: Record<string, string>;
2304
1558
  oauth?: McpOauthInput;
2305
1559
  allowedTools?: string[];
2306
- /**
2307
- * Hosted servers only. "auto" (the default) runs it on Cloudflare Workers
2308
- * when its bundle can run there, on Lambda otherwise; "lambda" always runs
2309
- * it on Lambda.
2310
- */
2311
1560
  runtime?: McpRuntime;
2312
1561
  }
2313
- /** Fields accepted by `PATCH /v1/mcp/{serverId}`; every field is optional. */
2314
1562
  interface UpdateMcpInput {
2315
1563
  name?: string;
2316
1564
  description?: string;
@@ -2323,19 +1571,10 @@ interface UpdateMcpInput {
2323
1571
  headers?: Record<string, string>;
2324
1572
  oauth?: McpOauthInput;
2325
1573
  allowedTools?: string[];
2326
- /**
2327
- * Hosted servers only. "auto" (the default) runs it on Cloudflare Workers
2328
- * when its bundle can run there, on Lambda otherwise; "lambda" always runs
2329
- * it on Lambda.
2330
- */
2331
1574
  runtime?: McpRuntime;
2332
1575
  disabled?: boolean;
2333
1576
  }
2334
- /**
2335
- * Body of a skill upload (`POST /v1/skills`, `PUT /v1/skills/{skillName}`).
2336
- * `json` needs `name`/`description`/`content`; `files` needs base64 `files`
2337
- * including a root `SKILL.md`; `github` needs a tree `url`.
2338
- */
1577
+ /** `json` needs name, description, content; `files` a root `SKILL.md`; `github` a tree `url`. */
2339
1578
  interface SkillUploadInput {
2340
1579
  source: "json" | "files" | "github";
2341
1580
  name?: string;
@@ -2348,101 +1587,72 @@ interface SkillUploadInput {
2348
1587
  }>;
2349
1588
  url?: string;
2350
1589
  }
2351
- /** Result of `POST /v1/account/rotate-secret`. The returned `secret` is the new account key, shown once; the old key stops working immediately. */
2352
1590
  interface RotateSecretResult {
2353
1591
  account: BroodsAccount;
2354
1592
  secret: string;
2355
1593
  }
2356
1594
  /**
2357
- * Result of `GET /v1/account/storage-trust`: what a workspace's own AWS role
2358
- * must trust. Broods assigns `externalId` per account and sends it on every
2359
- * AssumeRole of an `assumeRole` workspace's role; it is never set in config.
1595
+ * `externalId` is per account and sent on every AssumeRole; it is never set in config.
1596
+ * `principalArn` and `trustPolicy` are absent on a deployment with no AWS.
2360
1597
  */
2361
1598
  interface StorageTrust {
2362
1599
  externalId: string;
2363
- /** The Broods AWS principal to trust; absent on a deployment with no AWS. */
2364
1600
  principalArn?: string;
2365
- /** A ready-to-paste trust policy JSON; absent on a deployment with no AWS. */
2366
1601
  trustPolicy?: string;
2367
1602
  }
2368
- /** Result of `DELETE /v1/account`: the account and all account-scoped data are removed; `cleanup` reports per-resource deletion counts. */
2369
1603
  interface DeleteAccountResult {
2370
1604
  deleted: boolean;
2371
1605
  cleanup?: Record<string, number>;
2372
1606
  }
2373
- /** Result of a suspend/resume/terminate sandbox lifecycle action. */
2374
1607
  interface SandboxLifecycleResult {
2375
1608
  status: string;
2376
1609
  }
2377
- /** Result of `POST /v1/sandboxes/{id}/snapshot`. */
2378
1610
  interface SandboxSnapshotResult {
2379
1611
  status: string;
2380
1612
  snapshotId?: string;
2381
1613
  externalImageId?: string;
2382
1614
  }
2383
- /** Sealed ticket from `POST /v1/sandboxes/{id}/terminal`; hand `token` to the gateway terminal WebSocket at `websocketPath`. */
2384
1615
  interface SandboxTerminalTicket {
2385
1616
  token: string;
2386
1617
  expiresAt: number;
2387
1618
  websocketPath: string;
2388
1619
  }
2389
- /** Non-2xx response from the account API (404s on id routes return null instead). */
2390
1620
  declare class BroodsAccountApiError extends Error {
2391
1621
  readonly status: number;
2392
1622
  readonly body: string;
2393
1623
  constructor(method: string, path: string, status: number, body: string);
2394
1624
  }
2395
- /** Build a validated account env-var reference for use in an agent config. */
2396
1625
  declare function envPlaceholder(name: string): string;
2397
- /**
2398
- * The credential the environment supplies, with a role session winning over
2399
- * the account key. The constructor throws through this same resolution, so
2400
- * callers that can run without an account credential (`broods mcp` with only a
2401
- * stored login) probe here instead of catching the constructor.
2402
- */
1626
+ /** The constructor's env fallback, for callers that must not throw without one. */
2403
1627
  declare function resolveEnvCredential(): string | undefined;
2404
1628
  /**
2405
- * Typed client for the broods account config API. All `get`/`update`/`delete`
2406
- * methods return `null`/`false` when the resource does not exist (HTTP 404) so
2407
- * callers can implement upsert flows without try/catch; every other non-2xx
2408
- * status throws {@link BroodsAccountApiError}.
1629
+ * Lookups, updates and deletes return `null`/`false` on a 404, so upserts need no try/catch.
1630
+ * Any other failure throws {@link BroodsAccountApiError}.
2409
1631
  */
2410
1632
  declare class BroodsAccountClient {
2411
1633
  private readonly baseUrl;
2412
1634
  private readonly bearerToken;
2413
1635
  private readonly fetchImpl;
2414
1636
  constructor(options?: BroodsAccountClientOptions);
2415
- /** The account this secret belongs to. Its `accountId` is the first segment of channel webhook URLs. */
2416
1637
  getAccount(): Promise<BroodsAccount>;
2417
- /** The external id and Broods principal this account's own storage roles must trust. */
2418
1638
  getStorageTrust(): Promise<StorageTrust>;
2419
- /** Update account metadata (username/description). Returns null when the account is gone. Runtime config is managed through the agent endpoints. */
2420
1639
  updateAccount(patch: {
2421
1640
  username?: string;
2422
1641
  description?: string | null;
2423
- /** 1 to 3650 days, or null to return to the 90 day default. */
1642
+ /** 1 to 3650 days, or null for the 90 day default. */
2424
1643
  auditRetentionDays?: number | null;
2425
1644
  }): Promise<BroodsAccount | null>;
2426
1645
  /**
2427
- * Exchange a role for a short-lived `bsts_` session token. Callable with
2428
- * the account key, a CLI login token, or a runtime key (the latter
2429
- * only into roles scoped to the key's own project/stage). Construct a new
2430
- * client with `{ sessionToken: result.token }` to act as the role.
1646
+ * A runtime key may assume only roles scoped to its own project and stage.
1647
+ * Act as the role with `new BroodsAccountClient({ sessionToken: result.token })`.
2431
1648
  */
2432
1649
  assumeRole(roleId: string, options?: {
2433
1650
  ttlSeconds?: number;
2434
1651
  }): Promise<AssumeRoleResult>;
2435
- /** Rotate the account key. The returned `secret` is the new key, shown once, and the current key stops working immediately, so persist it before the process exits. */
1652
+ /** The old key dies at once and `secret` is shown only once: persist it before exiting. */
2436
1653
  rotateSecret(): Promise<RotateSecretResult>;
2437
- /** Delete this account and cascade-clean every account-scoped resource. `cleanup` reports per-resource deletion counts. */
2438
1654
  deleteAccount(): Promise<DeleteAccountResult>;
2439
- /**
2440
- * Provider webhook URL for one of the account's channels. Paste this into the
2441
- * provider's webhook settings (Slack Event Subscriptions, Zalo OA webhook,
2442
- * Pancake page webhook). Routing is per account + channel: the credentials
2443
- * that verify the request pick the receiving agent, and a channel record
2444
- * binds each place to the agent that should answer there.
2445
- */
1655
+ /** One URL per account and channel type; the credentials that verify a request pick the agent. */
2446
1656
  webhookUrl(accountId: string, channelType: string): string;
2447
1657
  listAgents(): Promise<AccountAgent[]>;
2448
1658
  createAgent(input: {
@@ -2451,31 +1661,22 @@ declare class BroodsAccountClient {
2451
1661
  config: AgentConfig;
2452
1662
  }): Promise<CreateAgentResult>;
2453
1663
  getAgent(agentId: string): Promise<AccountAgent | null>;
2454
- /** PATCH an agent. `config` deep-merges into the stored config; `null` leaves delete keys. Returns null when the agent is gone. */
2455
1664
  updateAgent(agentId: string, patch: UpdateAgentInput): Promise<AccountAgent | null>;
2456
1665
  deleteAgent(agentId: string): Promise<boolean>;
2457
- /** List account environment variable names and update timestamps; values are never returned. */
2458
1666
  listEnvVars(): Promise<AccountEnvVar[]>;
2459
- /** Create or replace one write-only account environment variable. */
2460
1667
  setEnvVar(name: string, value: string): Promise<void>;
2461
- /** Delete one account environment variable. Returns false when it is already absent. */
2462
1668
  deleteEnvVar(name: string): Promise<boolean>;
2463
- /** The account's connections (`broods connect`), never their tokens. */
2464
1669
  listConnections(): Promise<Connection[]>;
2465
- /** The account's connection of one type, or null when there is none. */
2466
1670
  getConnection(type: ConnectionType): Promise<Connection | null>;
2467
- /** Starts a sign-in: the provider's consent screen for `broods connect` to open. */
2468
1671
  startConnection(type: ConnectionType, start: ConnectionStart): Promise<ConnectionStartResult>;
2469
- /** Finishes a sign-in with the code the browser brought back; the deployment keeps the tokens. */
2470
1672
  connect(type: ConnectionType, code: ConnectionCode): Promise<Connection>;
2471
- /** Forget a connection and revoke it at the provider. False when there was none. */
2472
1673
  disconnect(type: ConnectionType): Promise<boolean>;
2473
1674
  listCrons(): Promise<Cron[]>;
2474
1675
  createCron(input: CreateCronInput): Promise<Cron>;
2475
1676
  getCron(cronId: string): Promise<Cron | null>;
2476
1677
  updateCron(cronId: string, patch: UpdateCronInput): Promise<Cron | null>;
2477
1678
  deleteCron(cronId: string): Promise<boolean>;
2478
- /** Run history for a cron, newest first. Returns [] when the cron is gone. */
1679
+ /** Newest first. */
2479
1680
  listCronRuns(cronId: string, options?: {
2480
1681
  limit?: number;
2481
1682
  }): Promise<CronRun[]>;
@@ -2492,19 +1693,14 @@ declare class BroodsAccountClient {
2492
1693
  config?: ConfigPatch<WorkspaceConfig>;
2493
1694
  }): Promise<AccountWorkspace | null>;
2494
1695
  deleteWorkspace(workspaceId: string): Promise<boolean>;
2495
- /** Flat listing of every file in the workspace's S3-backed filesystem. Returns [] when the workspace is gone. */
2496
1696
  listWorkspaceFiles(workspaceId: string): Promise<WorkspaceFileEntry[]>;
2497
- /** Short-lived download URL for one workspace file. Returns null when the workspace or file is gone. */
2498
1697
  getWorkspaceFileUrl(workspaceId: string, path: string): Promise<string | null>;
2499
- /** Upload or replace one workspace file from base64 content. Throws when the workspace is gone (404). */
2500
1698
  uploadWorkspaceFile(workspaceId: string, input: {
2501
1699
  path: string;
2502
1700
  contentBase64: string;
2503
1701
  contentType?: string;
2504
1702
  }): Promise<WorkspaceFileEntry>;
2505
- /** Rename a workspace file or folder. Returns how many objects moved; throws when the workspace or source path is gone. */
2506
1703
  renameWorkspaceFile(workspaceId: string, path: string, newPath: string): Promise<number>;
2507
- /** Delete a workspace file or folder. Returns how many objects were deleted, 0 when the workspace or path is gone. */
2508
1704
  deleteWorkspaceFile(workspaceId: string, path: string): Promise<number>;
2509
1705
  listSandboxes(): Promise<AccountSandbox[]>;
2510
1706
  createSandbox(input: {
@@ -2513,30 +1709,24 @@ declare class BroodsAccountClient {
2513
1709
  config?: SandboxConfig;
2514
1710
  }): Promise<AccountSandbox>;
2515
1711
  getSandbox(sandboxId: string): Promise<AccountSandbox | null>;
2516
- /** PATCH a sandbox config. `config` deep-merges into the stored config; `null` leaves delete keys. Returns null when the sandbox is gone. */
2517
1712
  updateSandbox(sandboxId: string, patch: {
2518
1713
  name?: string;
2519
1714
  description?: string | null;
2520
1715
  config?: ConfigPatch<SandboxConfig>;
2521
1716
  }): Promise<AccountSandbox | null>;
2522
1717
  deleteSandbox(sandboxId: string): Promise<boolean>;
2523
- /** Suspend a persistent sandbox reservation. Throws on 404/403/409 (missing sandbox, foreign reservation, or unsupported provider). */
2524
1718
  suspendSandbox(sandboxId: string, reservationKey: string): Promise<SandboxLifecycleResult>;
2525
- /** Resume a persistent sandbox reservation. Throws on 404/403/409. */
2526
1719
  resumeSandbox(sandboxId: string, reservationKey: string): Promise<SandboxLifecycleResult>;
2527
- /** Terminate a persistent sandbox reservation and drop its live-instance row. Throws on 404/403/409. */
2528
1720
  terminateSandbox(sandboxId: string, reservationKey: string): Promise<SandboxLifecycleResult>;
2529
- /** Snapshot a persistent sandbox reservation into an image any sandbox of that provider on the same stage can pin with `snapshot` (`sandbox`, `daytona`, `e2b`, `vercel`, or `lambda`, which answers `building` until its image build lands). The snapshot is locked to the stage of the sandbox it was taken from: pinning it on another stage throws a 400. Throws on 404/403/409. */
1721
+ /**
1722
+ * Providers `sandbox`, `daytona`, `e2b`, `vercel` and `lambda` (`building` until its image
1723
+ * lands). Only the source stage may pin the snapshot; any other stage gets a 400.
1724
+ */
2530
1725
  snapshotSandbox(sandboxId: string, reservationKey: string, name: string): Promise<SandboxSnapshotResult>;
2531
- /** Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox (`sandbox`/`lambda`/`cloudflare` providers). Throws on 404/403/409. */
1726
+ /** Providers `sandbox`, `lambda` and `cloudflare` only. */
2532
1727
  openSandboxTerminal(sandboxId: string, reservationKey: string): Promise<SandboxTerminalTicket>;
2533
- /** MCP servers live in one stage, so the collection routes need a scope. */
2534
1728
  listMcp(scope: StageScope): Promise<AccountMcp[]>;
2535
1729
  createMcp(scope: StageScope, input: CreateMcpInput): Promise<AccountMcp>;
2536
- /**
2537
- * Upload a hosted MCP bundle too large for the JSON body; returns the
2538
- * `bundleStorageId` + `sha256` pair `createMcp`/`updateMcp` accept.
2539
- */
2540
1730
  uploadMcpBundle(bundle: string): Promise<{
2541
1731
  bundleStorageId: string;
2542
1732
  sha256: string;
@@ -2551,7 +1741,6 @@ declare class BroodsAccountClient {
2551
1741
  document: PolicyDocument;
2552
1742
  }): Promise<AccountPolicy>;
2553
1743
  getPolicy(policyId: string): Promise<AccountPolicy | null>;
2554
- /** PATCH a policy. `description: null` clears it. Returns null when the policy is gone. */
2555
1744
  updatePolicy(policyId: string, patch: {
2556
1745
  name?: string;
2557
1746
  description?: string | null;
@@ -2559,9 +1748,8 @@ declare class BroodsAccountClient {
2559
1748
  status?: string;
2560
1749
  }): Promise<AccountPolicy | null>;
2561
1750
  deletePolicy(policyId: string): Promise<boolean>;
2562
- /** Roles are account-secret only: a session cannot list, mint, or edit roles. */
1751
+ /** Roles need the account key: a session cannot list, mint, or edit them. */
2563
1752
  listRoles(): Promise<AccountRole[]>;
2564
- /** Create a role whose policy uses the API action namespace. `projectId`/`stageId` must be provided together. */
2565
1753
  createRole(input: {
2566
1754
  name: string;
2567
1755
  policy: PolicyDocument;
@@ -2569,41 +1757,36 @@ declare class BroodsAccountClient {
2569
1757
  stageId?: string;
2570
1758
  }): Promise<AccountRole>;
2571
1759
  getRole(roleId: string): Promise<AccountRole | null>;
2572
- /** PATCH a role. `status: "disabled"` kills every live session of the role. Returns null when the role is gone. */
1760
+ /** `status: "disabled"` kills every live session of the role. */
2573
1761
  updateRole(roleId: string, patch: {
2574
1762
  name?: string;
2575
1763
  policy?: PolicyDocument;
2576
1764
  status?: "active" | "disabled";
2577
1765
  }): Promise<AccountRole | null>;
2578
1766
  deleteRole(roleId: string): Promise<boolean>;
2579
- /** The audit ledger: rows since a seq, chain verification, and the webhook sink. */
2580
1767
  readonly audit: {
2581
- /** Rows with `seq > since`, oldest first, at most `limit` (default 100, max 500). */
1768
+ /** Rows with `seq > since`, oldest first; `limit` defaults to 100, max 500. */
2582
1769
  list: (options?: {
2583
1770
  since?: number;
2584
1771
  limit?: number;
2585
1772
  }) => Promise<AuditPage>;
2586
1773
  /**
2587
- * Recompute the chain over `[fromSeq, toSeq]`, from the oldest kept row by
2588
- * default, at most 1000 rows per call. `ok` covers only `checkedFrom` to
2589
- * `checkedTo`; on a longer ledger call again with `fromSeq: checkedTo + 1`.
1774
+ * At most 1000 rows per call: `ok` covers only `checkedFrom` to `checkedTo`, so on a longer
1775
+ * ledger call again with `fromSeq: checkedTo + 1`.
2590
1776
  */
2591
1777
  verify: (options?: {
2592
1778
  fromSeq?: number;
2593
1779
  toSeq?: number;
2594
1780
  }) => Promise<AuditVerification>;
2595
- /** The account's sink, or null when none is set. */
2596
1781
  getSink: () => Promise<AuditSink | null>;
2597
- /** Set the one webhook sink. `url` must be public https; `secret` signs each batch. */
1782
+ /** `url` must be public https; `secret` signs each batch. */
2598
1783
  setSink: (input: {
2599
1784
  url: string;
2600
1785
  secret: string;
2601
1786
  }) => Promise<AuditSink>;
2602
- /** Remove the sink; exports stop and rows age out on retention alone. Returns whether one existed. */
2603
1787
  deleteSink: () => Promise<boolean>;
2604
1788
  };
2605
1789
  listChannels(): Promise<AccountChannel[]>;
2606
- /** Bind one real chat channel to an agent. One active record per place. */
2607
1790
  createChannel(input: {
2608
1791
  platform: string;
2609
1792
  externalId: string;
@@ -2613,7 +1796,6 @@ declare class BroodsAccountClient {
2613
1796
  config: ChannelRecordConfig;
2614
1797
  }): Promise<AccountChannel>;
2615
1798
  getChannel(channelId: string): Promise<AccountChannel | null>;
2616
- /** PATCH a channel. `description: null` clears it. Returns null when it is gone. */
2617
1799
  updateChannel(channelId: string, patch: {
2618
1800
  name?: string;
2619
1801
  description?: string | null;
@@ -2622,24 +1804,15 @@ declare class BroodsAccountClient {
2622
1804
  status?: "active" | "deleted";
2623
1805
  }): Promise<AccountChannel | null>;
2624
1806
  deleteChannel(channelId: string): Promise<boolean>;
2625
- /** All skills for the account, each with its `<accountId>/<name>` path. */
2626
1807
  listSkills(): Promise<Skill[]>;
2627
- /** Upload a new skill from JSON content, a base64 file bundle, or a GitHub tree URL. Every bundle must include a root `SKILL.md`. */
2628
1808
  createSkill(input: SkillUploadInput): Promise<Skill>;
2629
1809
  getSkill(skillName: string): Promise<Skill | null>;
2630
- /** Replace a skill's bundle in place (`PUT`). Throws when the skill is gone (404). */
2631
1810
  uploadSkill(skillName: string, input: SkillUploadInput): Promise<Skill>;
2632
1811
  deleteSkill(skillName: string): Promise<boolean>;
2633
- /** POST a sandbox lifecycle action, throwing on any non-2xx (including 404, since these are not upsert flows). */
2634
1812
  private sandboxAction;
2635
1813
  private request;
2636
1814
  }
2637
1815
 
2638
- /**
2639
- * WebSocket client for deployed-agent endpoints.
2640
- * Uses the gateway URL when configured, or derives one from the core service URL.
2641
- */
2642
-
2643
1816
  type WebSocketRunInput = {
2644
1817
  agent?: AgentReference;
2645
1818
  agentId?: string;
@@ -2666,12 +1839,10 @@ type WebSocketAttachInput = Omit<WebSocketClientAttachMessage, "type"> & {
2666
1839
  };
2667
1840
  interface WebSocketHandlers {
2668
1841
  /**
2669
- * Receives every server message with durable output envelopes unwrapped:
2670
- * stream parts arrive as themselves (`message.type === "text-delta"`), never
2671
- * nested under `data`. Use `onOutput` when the envelope cursor is needed.
1842
+ * Every server message with output envelopes unwrapped: a stream part arrives as itself
1843
+ * (`message.type === "text-delta"`), never under `data`. `onOutput` gets the cursor.
2672
1844
  */
2673
1845
  onMessage?(message: WebSocketServerMessage): void;
2674
- /** Receives the raw durable output envelope (cursor, replay flag, part). */
2675
1846
  onOutput?(output: WebSocketOutputMessage): void;
2676
1847
  onMeta?(meta: Extract<WebSocketServerMessage, {
2677
1848
  type: "meta";
@@ -2687,15 +1858,14 @@ interface WebSocketSubscription {
2687
1858
  interface BroodsWebSocketClientOptions {
2688
1859
  /** Base URL of the core service. Use `https://...`; the client converts it to `wss://...`. */
2689
1860
  baseUrl?: string;
2690
- /** Hostname or URL of the core service. `gateway.broods.app` becomes `https://gateway.broods.app`. */
1861
+ /** Hostname or URL of the core service, e.g. `gateway.broods.app`; `https://` is added. */
2691
1862
  host?: string;
2692
- /** Runtime key used as the WebSocket token. Defaults to BROODS_API_KEY from the environment or local .env files. */
1863
+ /** Runtime key sent as the WebSocket token. Defaults to BROODS_API_KEY (env or .env files). */
2693
1864
  apiKey?: string;
2694
1865
  /**
2695
- * The signed-in user's token (from `signUserToken` on your backend). Each
2696
- * socket carries it from its upgrade on; an agent that requires one refuses
2697
- * the runtime key without it. Tokens are short-lived, so a long-lived client
2698
- * passes a fresh one per run as `userToken` on the input instead.
1866
+ * The signed-in user's token from `signUserToken`; an agent that requires one refuses the
1867
+ * runtime key without it. Tokens are short-lived: a long-lived client passes a fresh one
1868
+ * per run as the input's `userToken` instead.
2699
1869
  */
2700
1870
  userToken?: string;
2701
1871
  WebSocket?: WebSocketConstructorLike;
@@ -2733,20 +1903,8 @@ declare class BroodsWebSocketClient {
2733
1903
  private resolveWebSocket;
2734
1904
  }
2735
1905
  declare function toWebSocketBaseUrl(url: string): string;
2736
- /**
2737
- * The credential travels as a `Sec-WebSocket-Protocol` entry rather than in
2738
- * the URL, so it never lands in proxy or access logs, and so does the user
2739
- * token. The gateway answers with `broods.v1`, which is what completes a
2740
- * handshake that offered subprotocols.
2741
- */
2742
1906
  declare function webSocketSubprotocols(apiKey: string, userToken?: string): string[];
2743
1907
 
2744
- /**
2745
- * Resource definition helpers for the code-first `broods/` project folder.
2746
- *
2747
- * Every runtime function here is synchronous.
2748
- */
2749
-
2750
1908
  declare const RESOURCE_MARKER: unique symbol;
2751
1909
  declare const CONFIG_MARKER: unique symbol;
2752
1910
  declare const CONNECTION_MARKER: unique symbol;
@@ -2754,7 +1912,6 @@ interface EnvRef<Name extends string = string> {
2754
1912
  readonly __beeblastEnv: true;
2755
1913
  readonly name: Name;
2756
1914
  }
2757
- /** Callable accessor for {@link env}. */
2758
1915
  interface EnvAccessor {
2759
1916
  <const Name extends string>(name: Name): EnvRef<Name>;
2760
1917
  }
@@ -2769,7 +1926,6 @@ interface BroodsProjectConfig {
2769
1926
  [name: string]: string | undefined;
2770
1927
  };
2771
1928
  dashboardUrl?: string;
2772
- /** Convex control-plane base URL for sync/env calls; defaults to the URL discovered at login. */
2773
1929
  baseUrl?: string;
2774
1930
  }
2775
1931
  interface BroodsConfigDefinition {
@@ -2784,143 +1940,67 @@ interface ResourceDefinition<Kind extends ResourceKind, Name extends string, Con
2784
1940
  readonly description?: string;
2785
1941
  readonly config: Config;
2786
1942
  }
2787
- /**
2788
- * Authoring shape for every resource helper: the resource's own `name` (plus an
2789
- * optional human `description`) sits inline with that resource's config keys.
2790
- */
2791
1943
  type ResourceInput<Name extends string, Config> = {
2792
1944
  name: Name;
2793
1945
  description?: string;
2794
1946
  } & Config;
2795
- /**
2796
- * Provider-specific sandbox knobs. `reservationKey` names the reserved machine a
2797
- * `persistent` sandbox reconnects to when no workspace is mounted; unset, each
2798
- * agent gets its own, and pinning one string on two sandboxes shares a machine.
2799
- * Keys are scoped to the account, so they cannot reach another account's machine.
2800
- * A `custom` sandbox names its server with `endpoint` (https, required), an
2801
- * optional bearer `token` and extra static `headers`; a credential header's
2802
- * value is an `env("NAME")` ref.
2803
- */
2804
1947
  type SandboxDefinitionOptions = Record<string, unknown> & {
1948
+ /** The machine a `persistent` sandbox reconnects to; one key on two sandboxes shares it. */
2805
1949
  reservationKey?: string;
2806
- /** daytona: mount workspaces (its snapshot must ship mount-s3). sandbox: mount even with no workspace. */
1950
+ /** daytona: mount workspaces (snapshot needs mount-s3); sandbox: mount even without one. */
2807
1951
  mountAwsS3Buckets?: boolean;
1952
+ /** `custom` sandbox: its https server, with a bearer `token` and `env()` credential headers. */
2808
1953
  endpoint?: string;
2809
1954
  token?: string | EnvRef;
2810
1955
  headers?: Record<string, string | EnvRef>;
2811
1956
  };
2812
- /**
2813
- * Code-first sandbox config input. Mirrors core's `SandboxConfig` but lets
2814
- * `envVars` values be `env("NAME")` references (compiled to `${NAME}` placeholders
2815
- * at sync time, exactly like provider `apiKey`). Add overrides here if more
2816
- * sandbox fields should accept env refs.
2817
- */
2818
1957
  type SandboxDefinitionConfig = Omit<SandboxConfig, "envVars" | "options"> & {
2819
1958
  envVars?: Record<string, string | EnvRef | undefined>;
2820
1959
  options?: SandboxDefinitionOptions;
2821
1960
  };
2822
1961
  type HarnessType = NonNullable<AgentConfig["harness"]>["type"];
2823
- /** Harness settings. The harness runs on the agent's first sandbox. */
2824
1962
  type HarnessDefinition = NonNullable<AgentConfig["harness"]>;
2825
1963
  interface SkillDefinitionConfig {
2826
- /**
2827
- * Folder containing SKILL.md plus optional scripts/assets. Relative paths are
2828
- * resolved from the `broods/` project directory.
2829
- */
1964
+ /** Folder holding SKILL.md, relative to the `broods/` project directory. */
2830
1965
  path: string;
2831
1966
  }
2832
1967
  type PolicyDefinitionConfig = Omit<PolicyDocument, "version"> & {
2833
1968
  version?: PolicyDocument["version"];
2834
1969
  };
2835
- /**
2836
- * Fetch-style MCP handler for a hosted server: what
2837
- * `createMcpHandler(...)` from @modelcontextprotocol/server returns: either
2838
- * the request function itself or an object exposing it as `fetch`.
2839
- */
2840
1970
  type McpHandler = ((request: Request) => Response | Promise<Response>) | {
2841
1971
  fetch(request: Request): Response | Promise<Response>;
2842
1972
  };
2843
- /**
2844
- * MCP server registration (#331): external (`url`), hosted (`handler`), or on
2845
- * a sandbox (`sandbox`). Either way the server's tools are offered as
2846
- * `<name>__<tool>`; an external row is dialed over the stateless HTTP
2847
- * transport (spec 2026-07-28) at agent registration time. The name namespaces
2848
- * those tools, so it must be 1-32 lowercase letters, digits, or hyphens,
2849
- * starting with a letter.
2850
- */
1973
+ /** Tools are offered as `<name>__<tool>`: the name is 1-32 of a-z, 0-9, "-", letter first. */
2851
1974
  interface McpDefinitionConfig {
2852
- /** External server's MCP endpoint; http(s), no embedded credentials. */
2853
1975
  url?: string;
2854
- /**
2855
- * Instead of `url` or `handler`: the sandbox that runs this server. On a
2856
- * machine sandbox its daemon runs the entry with the same name in its
2857
- * `--mcp` file; on a lambda sandbox the VM runs `command`.
2858
- */
1976
+ /** A machine sandbox runs its `--mcp` file's entry of this name; a lambda one runs `command`. */
2859
1977
  sandbox?: SandboxResource | string;
2860
- /**
2861
- * Argv of the stdio server, required when `sandbox` is a lambda sandbox,
2862
- * e.g. `["obscura", "mcp"]`. A machine sandbox's daemon ignores it.
2863
- */
2864
1978
  command?: string[];
2865
- /**
2866
- * Hosted alternative to `url`: declare the server inline as
2867
- * `handler: createMcpHandler(factory, { legacy: "reject" })` from
2868
- * @modelcontextprotocol/server, right next to the `defineMcp` call; Broods
2869
- * speaks MCP 2026-07-28 only. The CLI bundles the defining module
2870
- * and the platform hosts it, one invocation per batch of requests: with
2871
- * `runtime` "auto" on Cloudflare Workers when the bundle builds for them,
2872
- * on Lambda otherwise.
2873
- */
1979
+ /** Hosted: `createMcpHandler(factory, { legacy: "reject" })`; MCP 2026-07-28 only. */
2874
1980
  handler?: McpHandler;
2875
- /**
2876
- * Hosted servers only. "auto" (the default) runs the handler on Cloudflare
2877
- * Workers when it builds for them; "lambda" always ships the Node build to
2878
- * Lambda, for a server that needs Node APIs Workers lack.
2879
- */
1981
+ /** "auto" runs on Workers when the bundle builds for them; "lambda" ships the Node build. */
2880
1982
  runtime?: McpRuntime;
2881
- /**
2882
- * Extra request headers. Credential-bearing headers (Authorization,
2883
- * X-Api-Key, ...) must reference an account env var by name inside a plain
2884
- * string, e.g. `"Bearer ${TOKEN}"`. `env()` returns an object, so a template
2885
- * literal around it sends `[object Object]`. Never carry an inline secret.
2886
- */
1983
+ /** A credential header names an env var in a plain string, `"Bearer ${TOKEN}"`, never `env()`. */
2887
1984
  headers?: Record<string, string>;
2888
- /**
2889
- * OAuth 2.0 refresh-token grant for an external server whose access tokens
2890
- * expire (Google's Workspace MCP endpoints). The runtime mints, caches and
2891
- * refreshes access tokens and sends `Authorization: Bearer <token>` itself,
2892
- * so do not also set an Authorization header. `clientSecret` and
2893
- * `refreshToken` must be `env("NAME")` refs; `tokenUrl` defaults to
2894
- * https://oauth2.googleapis.com/token.
2895
- */
1985
+ /** The runtime sends the bearer itself: set no Authorization header. Secrets are `env()`. */
2896
1986
  oauth?: {
2897
1987
  clientId: string | EnvRef;
2898
1988
  clientSecret: string | EnvRef;
2899
1989
  refreshToken: string | EnvRef;
2900
1990
  tokenUrl?: string;
2901
1991
  };
2902
- /** Tool names agents may use from this server; omit to allow all. */
2903
1992
  allowedTools?: string[];
2904
1993
  }
2905
- type ChannelType = "telegram" | "gchat" | "github" | "linear" | "slack" | "discord" | "matrix" | "pancake" | "teams" | "twilio" | "zalo" | "whatsapp" | "instagram" | "messenger";
2906
- /**
2907
- * A connection is one app install: the credentials an agent needs before a
2908
- * provider can reach it at all. Channels point at a connection; a connection
2909
- * never points back, which is what keeps the reference graph acyclic.
2910
- */
1994
+ type ChannelType = "telegram" | "gchat" | "github" | "linear" | "slack" | "discord" | "pancake" | "teams" | "twilio" | "zalo" | "whatsapp" | "instagram" | "messenger";
1995
+ /** One app install. Channels point at it and it never points back, so references stay acyclic. */
2911
1996
  interface ConnectionDefinition<Type extends ChannelType, Config> {
2912
1997
  readonly [CONNECTION_MARKER]: true;
2913
1998
  readonly kind: "connection";
2914
1999
  readonly type: Type;
2915
2000
  readonly partition?: ChannelPartition;
2916
- /** `partition` is lifted out of the authored input, so it is not in here. */
2917
2001
  readonly config: Omit<Config, "partition">;
2918
2002
  }
2919
- /**
2920
- * An agent bound to a channel. Every bound agent runs when a message arrives;
2921
- * `reply: false` runs it with a silenced channel, so it can work without
2922
- * speaking in the room.
2923
- */
2003
+ /** Every bound agent runs; `reply: false` runs it without speaking in the room. */
2924
2004
  type ChannelAgentInput = AgentResource | {
2925
2005
  agent: AgentResource;
2926
2006
  reply?: boolean;
@@ -2928,16 +2008,10 @@ type ChannelAgentInput = AgentResource | {
2928
2008
  type RequiredChannelKeys<Config, Keys extends keyof Config> = Required<Pick<Config, Keys>> & Omit<Config, Keys>;
2929
2009
  type ChannelSecret = string | EnvRef | undefined;
2930
2010
  type ConnectionIdentityInput = {
2931
- /** Include the dashboard trace link in channel replies. Off by default. */
2932
2011
  trace?: "enabled" | "disabled";
2933
2012
  partition?: ChannelPartition;
2934
- /**
2935
- * Rooms this connection answers in, on top of every channel declared against
2936
- * it. Use `["*"]` to answer everywhere instead, which is the only reason to
2937
- * name rooms here at all: a room with rules belongs in a channel resource.
2938
- */
2013
+ /** Rooms beyond its channels'; `["*"]` answers everywhere. A room with rules is a channel. */
2939
2014
  allowedChannelIds?: readonly string[];
2940
- /** Provider user ids allowed to trigger the agent. `["*"]` or omitted is everyone. */
2941
2015
  allowedUserIds?: readonly string[];
2942
2016
  };
2943
2017
  type TelegramConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentTelegramChannelConfig, "apiUrl" | "botToken" | "webhookSecret" | "botUsername" | "reactionEmoji">, "botToken" | "webhookSecret">> & ConnectionIdentityInput;
@@ -2946,7 +2020,6 @@ type GitHubConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentGitHubCh
2946
2020
  type LinearConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentLinearChannelConfig, "apiKey" | "apiUrl" | "userName" | "webhookSecret">, "apiKey" | "userName" | "webhookSecret">> & ConnectionIdentityInput;
2947
2021
  type SlackConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentSlackChannelConfig, "apiUrl" | "botToken" | "signingSecret" | "reactionEmoji">, "botToken" | "signingSecret">> & ConnectionIdentityInput;
2948
2022
  type DiscordConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentDiscordChannelConfig, "apiUrl" | "botToken" | "publicKey" | "botUserId" | "mentionRoleIds">, "botToken" | "publicKey">> & ConnectionIdentityInput;
2949
- type MatrixConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentMatrixChannelConfig, "apiUrl" | "botToken" | "botName" | "mentionText">, "apiUrl" | "botToken">> & ConnectionIdentityInput;
2950
2023
  type TeamsConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentTeamsChannelConfig, "apiUrl" | "appId" | "appPassword" | "appTenantId" | "appType" | "userName">, "appId" | "appPassword">> & ConnectionIdentityInput;
2951
2024
  type WhatsAppConnectionInput = EnvRefString<RequiredChannelKeys<Pick<AgentWhatsAppChannelConfig, "accessToken" | "apiUrl" | "apiVersion" | "appSecret" | "phoneNumberId" | "userName" | "verifyToken">, "accessToken" | "appSecret" | "phoneNumberId" | "verifyToken">> & ConnectionIdentityInput;
2952
2025
  interface PancakeConnectionInput extends ConnectionIdentityInput {
@@ -2968,7 +2041,6 @@ type GitHubConnectionDefinition = ConnectionDefinition<"github", GitHubConnectio
2968
2041
  type LinearConnectionDefinition = ConnectionDefinition<"linear", LinearConnectionInput>;
2969
2042
  type SlackConnectionDefinition = ConnectionDefinition<"slack", SlackConnectionInput>;
2970
2043
  type DiscordConnectionDefinition = ConnectionDefinition<"discord", DiscordConnectionInput>;
2971
- type MatrixConnectionDefinition = ConnectionDefinition<"matrix", MatrixConnectionInput>;
2972
2044
  type PancakeConnectionDefinition = ConnectionDefinition<"pancake", PancakeConnectionInput>;
2973
2045
  type TeamsConnectionDefinition = ConnectionDefinition<"teams", TeamsConnectionInput>;
2974
2046
  type TwilioConnectionDefinition = ConnectionDefinition<"twilio", TwilioConnectionInput>;
@@ -2976,32 +2048,18 @@ type ZaloConnectionDefinition = ConnectionDefinition<"zalo", ZaloConnectionInput
2976
2048
  type InstagramConnectionDefinition = ConnectionDefinition<"instagram", InstagramConnectionInput>;
2977
2049
  type MessengerConnectionDefinition = ConnectionDefinition<"messenger", MessengerConnectionInput>;
2978
2050
  type WhatsAppConnectionDefinition = ConnectionDefinition<"whatsapp", WhatsAppConnectionInput>;
2979
- type AnyConnectionDefinition = TelegramConnectionDefinition | GoogleChatConnectionDefinition | GitHubConnectionDefinition | LinearConnectionDefinition | SlackConnectionDefinition | DiscordConnectionDefinition | MatrixConnectionDefinition | PancakeConnectionDefinition | TeamsConnectionDefinition | TwilioConnectionDefinition | ZaloConnectionDefinition | WhatsAppConnectionDefinition | InstagramConnectionDefinition | MessengerConnectionDefinition;
2980
- /**
2981
- * One real place a team talks: a Slack channel, a Discord channel, a repo. It
2982
- * narrows and adds, and never grants what a bound agent lacks: instructions
2983
- * append, policies union, tools and workspaces only narrow. It names the
2984
- * connection it belongs to, so `platform` is never written by hand.
2985
- */
2051
+ type AnyConnectionDefinition = TelegramConnectionDefinition | GoogleChatConnectionDefinition | GitHubConnectionDefinition | LinearConnectionDefinition | SlackConnectionDefinition | DiscordConnectionDefinition | PancakeConnectionDefinition | TeamsConnectionDefinition | TwilioConnectionDefinition | ZaloConnectionDefinition | WhatsAppConnectionDefinition | InstagramConnectionDefinition | MessengerConnectionDefinition;
2052
+ /** Never grants what a bound agent lacks: instructions append, policies union, the rest narrows. */
2986
2053
  type ChannelDefinitionConfig = {
2987
2054
  connection: AnyConnectionDefinition;
2988
- /**
2989
- * Provider id of the place, from the per-platform field on the input. A list
2990
- * fans out to one record per id at deploy time.
2991
- */
2992
2055
  externalId: string | readonly string[];
2993
- /** Team, guild or repo owner the place sits in, when the provider has one. */
2994
2056
  workspaceRef?: string;
2995
- /** Every one of these runs. Omit and the connection's own agent answers. */
2057
+ /** Omit and the connection's own agent answers. */
2996
2058
  agents?: readonly ChannelAgentInput[];
2997
- /** Appended after each agent's own system prompt, never replacing it. */
2998
2059
  instructions?: string;
2999
- /** Selects from what the agent already attaches; anything else is dropped. */
3000
2060
  workspaces?: readonly AgentWorkspaceInput[];
3001
- /** Added to whatever the agent already carries. Each policy holds its own mode. */
3002
2061
  policies?: readonly (PolicyResource | string)[];
3003
2062
  denyTools?: readonly string[];
3004
- /** Where the reply lands. Slack only. */
3005
2063
  replyIn?: ChannelReplyIn;
3006
2064
  partition?: ChannelPartition;
3007
2065
  sandboxImages?: readonly string[];
@@ -3010,102 +2068,76 @@ type ChannelDefinitionConfig = {
3010
2068
  userIds: readonly string[];
3011
2069
  }[];
3012
2070
  };
3013
- /** Rules shared by every channel, whatever the provider calls its rooms. */
3014
2071
  type ChannelRulesInput = Omit<ChannelDefinitionConfig, "connection" | "externalId" | "workspaceRef" | "replyIn">;
3015
2072
  type SlackChannelInput = ChannelRulesInput & {
3016
2073
  connection: SlackConnectionDefinition;
3017
- /** Slack channel id, e.g. "C0123ABCD". */
2074
+ /** e.g. "C0123ABCD". */
3018
2075
  channelId: string;
3019
- /** Slack team id the channel sits in. */
3020
2076
  teamId?: string;
3021
- /** Where the reply lands. Slack is the only provider with a choice. */
3022
2077
  replyIn?: ChannelReplyIn;
3023
2078
  };
3024
2079
  type DiscordChannelInput = ChannelRulesInput & {
3025
2080
  connection: DiscordConnectionDefinition;
3026
- /** Discord channel id (a snowflake). */
3027
2081
  channelId: string;
3028
- /** Guild the channel sits in. */
3029
2082
  guildId?: string;
3030
2083
  };
3031
- type MatrixChannelInput = ChannelRulesInput & {
3032
- connection: MatrixConnectionDefinition;
3033
- /** Matrix room id, e.g. "!abc123:matrix.org". */
3034
- channelId: string;
3035
- };
3036
2084
  type GoogleChatChannelInput = ChannelRulesInput & {
3037
2085
  connection: GoogleChatConnectionDefinition;
3038
- /** Google Chat space name, e.g. "spaces/AAAAxxxx". */
2086
+ /** e.g. "spaces/AAAAxxxx". */
3039
2087
  spaceName: string;
3040
2088
  };
3041
2089
  type GitHubChannelInput = ChannelRulesInput & {
3042
2090
  connection: GitHubConnectionDefinition;
3043
- /** Repository full name, e.g. "beeblast/api". */
2091
+ /** "owner/name". */
3044
2092
  repo: string;
3045
2093
  };
3046
2094
  type LinearChannelInput = ChannelRulesInput & {
3047
2095
  connection: LinearConnectionDefinition;
3048
- /** Team key, e.g. "ENG", or several that share one set of rules. */
2096
+ /** Team key, e.g. "ENG". */
3049
2097
  team: string | readonly string[];
3050
2098
  };
3051
2099
  type TeamsChannelInput = ChannelRulesInput & {
3052
2100
  connection: TeamsConnectionDefinition;
3053
- /** Teams channel id, or a chat's conversation id, e.g. "19:abc@thread.tacv2". */
2101
+ /** Channel or chat conversation id, e.g. "19:abc@thread.tacv2". */
3054
2102
  channelId: string;
3055
- /** Team the channel sits in. */
3056
2103
  teamId?: string;
3057
2104
  };
3058
2105
  type TelegramChannelInput = ChannelRulesInput & {
3059
2106
  connection: TelegramConnectionDefinition;
3060
- /** Telegram chat id, e.g. "-1001234567". */
3061
2107
  chatId: string;
3062
2108
  };
3063
2109
  type TwilioChannelInput = ChannelRulesInput & {
3064
2110
  connection: TwilioConnectionDefinition;
3065
- /** Sender's number in E.164, e.g. "+15551234567", or several. */
2111
+ /** Sender's number in E.164, e.g. "+15551234567". */
3066
2112
  from: string | readonly string[];
3067
2113
  };
3068
2114
  type ZaloChannelInput = ChannelRulesInput & {
3069
2115
  connection: ZaloConnectionDefinition;
3070
- /** Zalo user or group chat id, or several that share one set of rules. */
3071
2116
  chatId: string | readonly string[];
3072
2117
  };
3073
2118
  type InstagramChannelInput = ChannelRulesInput & {
3074
2119
  connection: InstagramConnectionDefinition;
3075
- /** Instagram-scoped id (IGSID) of the person, or several. */
3076
2120
  igsid: string | readonly string[];
3077
2121
  };
3078
2122
  type MessengerChannelInput = ChannelRulesInput & {
3079
2123
  connection: MessengerConnectionDefinition;
3080
- /** Page-scoped id (PSID) of the person, or several. */
3081
2124
  psid: string | readonly string[];
3082
2125
  };
3083
2126
  type WhatsAppChannelInput = ChannelRulesInput & {
3084
2127
  connection: WhatsAppConnectionDefinition;
3085
- /** Customer's WhatsApp id, their number with country code and no "+", or several. */
2128
+ /** The number with country code and no "+". */
3086
2129
  waId: string | readonly string[];
3087
2130
  };
3088
2131
  type PancakeChannelInput = ChannelRulesInput & {
3089
2132
  connection: PancakeConnectionDefinition;
3090
- /** Pancake conversation id. */
3091
2133
  conversationId: string;
3092
2134
  };
3093
- /**
3094
- * Per-agent workspace mount with an optional sandbox override. A bare
3095
- * `defineWorkspace(...)` inherits the agent's first sandbox; the object form lets
3096
- * a single workspace pin its own sandbox, or set `sandbox: null` to force the
3097
- * workspace read-only (no compute attached).
3098
- */
3099
2135
  interface AgentWorkspaceRefInput {
3100
2136
  workspace: WorkspaceResource | string;
2137
+ /** Omit for the agent's first sandbox; `null` mounts it read-only, with no compute. */
3101
2138
  sandbox?: SandboxResource | string | null;
3102
2139
  }
3103
2140
  type AgentWorkspaceInput = WorkspaceResource | AgentWorkspaceRefInput;
3104
- /**
3105
- * `subagent` block where `allowed` may reference other `defineAgent(...)`
3106
- * resources directly; the compiler rewrites them to agent names and the backend
3107
- * resolves those to deploy-time agent ids.
3108
- */
3109
2141
  type AgentSubagentDefinitionConfig = Omit<NonNullable<AgentConfig["subagent"]>, "allowed"> & {
3110
2142
  allowed?: readonly (AgentResource | string)[];
3111
2143
  };
@@ -3114,31 +2146,21 @@ type AgentSkillsDefinitionConfig = Omit<NonNullable<AgentConfig["skills"]>, "all
3114
2146
  };
3115
2147
  interface HookContext {
3116
2148
  fetch: typeof fetch;
3117
- /** The model and the names of the agent's tools, MCP servers, channels, skills and subagents. Never credentials. */
2149
+ /** The model and the agent's tool, server, channel, skill and subagent names; no credentials. */
3118
2150
  config: HookAgentConfig;
3119
2151
  /**
3120
- * Mutable per-request scratchpad shared across this agent request's hooks.
3121
- * Seed it in an early hook (e.g. `onStart`) and read or modify it later.
3122
- * Every loop hook, `onSubagentFinish`, and the reply's `onMessageSending`
3123
- * see the same state. Keep it JSON-serializable. `onMessageReceived`,
3124
- * delayed background replies, and each subagent's own run get fresh state.
2152
+ * Shared by one request's hooks; keep it JSON-serializable. `onMessageReceived`, delayed
2153
+ * replies and each subagent's own run start fresh.
3125
2154
  */
3126
2155
  state: Record<string, unknown>;
3127
2156
  }
3128
2157
  type Handler<Event, Result> = (ctx: HookContext, event: Event) => Result | void | Promise<Result | void>;
3129
- /**
3130
- * Channel-specific routing data attached to an inbound message. Inherited from
3131
- * the core channel adapters (via contracts.ts) so an `onMessageReceived` hook
3132
- * that narrows on `event.channel` always sees exactly what core emits (e.g.
3133
- * Pancake `tagIds`).
3134
- */
3135
2158
  type TelegramMessageSource = TelegramSource;
3136
2159
  type GoogleChatMessageSource = GoogleChatSource;
3137
2160
  type GitHubMessageSource = GitHubSource;
3138
2161
  type LinearMessageSource = LinearSource;
3139
2162
  type SlackMessageSource = SlackSource;
3140
2163
  type DiscordMessageSource = DiscordSource;
3141
- type MatrixMessageSource = MatrixSource;
3142
2164
  type PancakeMessageSource = PancakeSource;
3143
2165
  type TeamsMessageSource = TeamsSource;
3144
2166
  type TwilioMessageSource = TwilioSource;
@@ -3146,10 +2168,6 @@ type ZaloMessageSource = ZaloSource;
3146
2168
  type InstagramMessageSource = InstagramSource;
3147
2169
  type MessengerMessageSource = MessengerSource;
3148
2170
  type WhatsAppMessageSource = WhatsAppSource;
3149
- /**
3150
- * Inbound channel message passed to `onMessageReceived`, discriminated on
3151
- * `channel` so each variant exposes its channel's strongly-typed `source`.
3152
- */
3153
2171
  type ChannelMessageReceived = {
3154
2172
  channel: "telegram";
3155
2173
  text: string;
@@ -3174,10 +2192,6 @@ type ChannelMessageReceived = {
3174
2192
  channel: "discord";
3175
2193
  text: string;
3176
2194
  source: DiscordMessageSource;
3177
- } | {
3178
- channel: "matrix";
3179
- text: string;
3180
- source: MatrixMessageSource;
3181
2195
  } | {
3182
2196
  channel: "pancake";
3183
2197
  text: string;
@@ -3208,15 +2222,9 @@ type ChannelMessageReceived = {
3208
2222
  source: MessengerMessageSource;
3209
2223
  };
3210
2224
  /**
3211
- * Inline agent hook callbacks. Handlers are serialized with `.toString()`,
3212
- * bundled into one account hook, and run in a fresh V8 isolate. Keep them
3213
- * self-contained: use only `ctx`, `event`, and JavaScript globals. Do not rely
3214
- * on imports or closure variables. Arrow functions and function expressions are
3215
- * preferred so the serialized source is valid as an object-literal value.
3216
- *
3217
- * Subagent runs fire hooks too: a registered subagent runs its own hooks, a
3218
- * prompt-only (virtual) subagent inherits this bundle, always with fresh
3219
- * `ctx.state`. `onSubagentFinish` fires on the parent with the parent's state.
2225
+ * Serialized with `.toString()` into a fresh V8 isolate: use only `ctx`, `event` and JS globals,
2226
+ * no imports or closures, and prefer arrow functions. A registered subagent runs its own hooks,
2227
+ * a prompt-only one inherits these; `onSubagentFinish` fires on the parent with its state.
3220
2228
  */
3221
2229
  interface AgentHooks {
3222
2230
  onStart?: Handler<{
@@ -3265,6 +2273,7 @@ interface AgentHooks {
3265
2273
  }, {
3266
2274
  visibleResult?: unknown;
3267
2275
  }>;
2276
+ /** Returned `metadata` (opaque JSON) is stored and resurfaces on `onStart`'s messages. */
3268
2277
  onMessageReceived?: Handler<ChannelMessageReceived, {
3269
2278
  drop?: boolean;
3270
2279
  text?: string;
@@ -3278,33 +2287,15 @@ interface AgentHooks {
3278
2287
  text?: string;
3279
2288
  }>;
3280
2289
  }
3281
- /**
3282
- * Code-first agent config input. Built from an explicit `Pick` of `AgentConfig`
3283
- * (not `Omit`) so the SDK input type does NOT inherit `AgentConfig`'s
3284
- * `[key: string]: unknown` index signature, which would otherwise disable
3285
- * TypeScript's excess-property checks and silently accept typos like
3286
- * `workspace:` instead of `workspaces:`. Add a key here when core's `AgentConfig`
3287
- * gains a new top-level field that should be code-definable.
3288
- */
3289
- /**
3290
- * SDK-facing model-provider constructor settings. Open by design: everything a
3291
- * provider's Vercel AI SDK factory accepts is forwarded verbatim, so there is no
3292
- * key list to keep in sync. Only the keys broods reads itself are named (and so
3293
- * typo-checked at run time by `validateProviderConfig`); every string field also
3294
- * accepts an `env("NAME")` reference.
3295
- */
2290
+ /** Forwarded verbatim to the provider's AI SDK factory; only the named keys are checked. */
3296
2291
  interface ProviderSettingsInput {
3297
2292
  apiKey?: string | EnvRef;
3298
2293
  base_url?: string | EnvRef;
3299
2294
  baseURL?: string | EnvRef;
3300
- /** A streamed model request with no response within this many ms is sent again. */
3301
- firstByteTimeoutMs?: number;
3302
- /** `cloudflare` only: the AI Gateway every request goes through. */
3303
2295
  gatewayId?: string;
3304
2296
  headers?: Record<string, string | EnvRef>;
3305
2297
  [key: string]: unknown;
3306
2298
  }
3307
- /** Per-provider settings; provider names stay synced with core's `AgentConfig`. */
3308
2299
  type ProviderConfigInput = Partial<Record<keyof NonNullable<AgentConfig["provider"]>, ProviderSettingsInput>>;
3309
2300
  type AgentDefinitionConfig = EnvRefString<Pick<AgentConfig, "agent" | "model" | "scheduler" | "browser" | "session" | "tools" | "mcp">> & {
3310
2301
  provider?: ProviderConfigInput;
@@ -3314,50 +2305,30 @@ type AgentDefinitionConfig = EnvRefString<Pick<AgentConfig, "agent" | "model" |
3314
2305
  webhooks?: readonly EnvRefString<AgentWebhookHookConfig>[];
3315
2306
  };
3316
2307
  connections?: readonly AnyConnectionDefinition[];
3317
- /**
3318
- * Sandboxes this agent runs on. The first is the default: bash with no
3319
- * workspace runs there, workspaces without their own sandbox mount it, and a
3320
- * harness runs on it. The model reaches the others by name.
3321
- */
2308
+ /** The first runs the harness, bash and any workspace without its own sandbox. */
3322
2309
  sandboxes?: readonly (SandboxResource | string)[];
3323
2310
  workspaces?: readonly AgentWorkspaceInput[];
3324
2311
  subagent?: AgentSubagentDefinitionConfig;
3325
2312
  skills?: AgentSkillsDefinitionConfig;
3326
- /** Policies that gate this agent. Each one carries its own enforcement mode. */
3327
2313
  policies?: readonly (PolicyResource | string)[];
3328
- /**
3329
- * Opt the agent into the public runtime endpoint (SSE/WebSocket via the
3330
- * runtime key). Off by default: when unset the public endpoint
3331
- * refuses requests for this agent. Reach a private agent through an
3332
- * internal endpoint or a channel webhook. See issue #65.
3333
- */
2314
+ /** Serve this agent on the public runtime endpoint. Off by default. */
3334
2315
  publicAccess?: boolean;
3335
- /**
3336
- * Let a runtime-key caller send `system` and `model` overrides on a run. Off
3337
- * by default: such a run is refused with `403 run_overrides_disabled`.
3338
- */
2316
+ /** Accept `system` and `model` run overrides; off answers `403 run_overrides_disabled`. */
3339
2317
  allowRunOverrides?: boolean;
3340
2318
  };
3341
2319
  type CronDefinitionConfig = Omit<CreateCronInput, "agentId" | "name"> & {
3342
2320
  agent: AgentResource | string;
3343
2321
  };
3344
2322
  type AgentResource<Name extends string = string> = ResourceDefinition<"agent", Name, AgentDefinitionConfig>;
3345
- /**
3346
- * Code-first workspace config. Says `partitioned` where storage says
3347
- * `isolation`. "conversation" permits a per-conversation split that a
3348
- * channel's `partition` performs; "agent" splits the workspace per attached
3349
- * agent on its own, with no partition needed. R2 keys take `env("NAME")`.
3350
- */
3351
2323
  type WorkspaceDefinitionConfig = Omit<WorkspaceConfig, "isolation" | "storage"> & {
3352
2324
  storage?: WorkspaceStorageDefinition;
3353
- /** How to split this workspace: per conversation or per agent. */
2325
+ /** "conversation" lets a channel's `partition` split it; "agent" splits it per agent. */
3354
2326
  partitioned?: WorkspaceIsolation;
3355
2327
  };
3356
2328
  type WorkspaceStorageAuthConfig = NonNullable<WorkspaceConfig["storage"]["auth"]>;
3357
2329
  type WorkspaceR2Auth = Extract<WorkspaceStorageAuthConfig, {
3358
2330
  type: "r2";
3359
2331
  }>;
3360
- /** Workspace storage as authored: only the R2 keys take `env()`. */
3361
2332
  type WorkspaceStorageDefinition = Omit<WorkspaceConfig["storage"], "auth"> & {
3362
2333
  auth?: Exclude<WorkspaceStorageAuthConfig, {
3363
2334
  type: "r2";
@@ -3375,29 +2346,11 @@ type CronResource<Name extends string = string> = ResourceDefinition<"cron", Nam
3375
2346
  type ChannelResource<Name extends string = string> = ResourceDefinition<"channelRecord", Name, ChannelDefinitionConfig>;
3376
2347
  type AnyResource = AgentResource | WorkspaceResource | SandboxResource | CronResource | SkillResource | McpResource | PolicyResource | ChannelResource;
3377
2348
  /**
3378
- * References an account/environment variable resolved on the SERVER at runtime.
3379
- * Set it with `broods env set <NAME>` or in the dashboard (the Convex-style
3380
- * `convex env set` model). It is a deferred reference, never read from your local
3381
- * environment and never baked into the deployed config:
3382
- *
3383
- * apiKey: env("OPENAI_API_KEY")
3384
- *
3385
- * It compiles to a `${NAME}` placeholder the harness fills in at run time. This is
3386
- * NOT `process.env`: agent configs are compiled locally, so `process.env.NAME` would
3387
- * bake the literal local value into the deployed config instead of deferring it.
3388
- *
3389
- * The reference must resolve: syncing a manifest whose `env("NAME")` has no value
3390
- * stored for the stage is rejected outright, so an unset or misspelled name fails
3391
- * the sync instead of reaching the runtime as a literal `${NAME}`. `broods dev`
3392
- * pushes matching `.env.local` values first, so a local value is enough there.
2349
+ * A stage env var (`broods env set NAME`) the server fills in at run time, e.g.
2350
+ * `apiKey: env("OPENAI_API_KEY")`. Not `process.env`, which bakes the local value into the config.
2351
+ * A sync is refused while a referenced name has no stored value; `broods dev` pushes `.env.local`.
3393
2352
  */
3394
2353
  declare const env: EnvAccessor;
3395
- /**
3396
- * Shared builder behind every `define*` helper below. The public helpers are
3397
- * thin, per-kind typed front doors: each pins its `kind` (the discriminant the
3398
- * sync/codegen pipeline switches on) and splits the flat authoring input back
3399
- * into the `{ name, description?, config }` shape the manifest wire format uses.
3400
- */
3401
2354
  declare function defineAgent<const Name extends string>(input: ResourceInput<Name, AgentDefinitionConfig>): AgentResource<Name>;
3402
2355
  declare function defineBroods(config: BroodsProjectConfig): BroodsConfigDefinition;
3403
2356
  declare function defineCron<const Name extends string>(input: ResourceInput<Name, CronDefinitionConfig>): CronResource<Name>;
@@ -3412,7 +2365,6 @@ declare function defineGitHubConnection(config: GitHubConnectionInput): GitHubCo
3412
2365
  declare function defineGoogleChatConnection(config: GoogleChatConnectionInput): GoogleChatConnectionDefinition;
3413
2366
  declare function defineInstagramConnection(config: InstagramConnectionInput): InstagramConnectionDefinition;
3414
2367
  declare function defineLinearConnection(config: LinearConnectionInput): LinearConnectionDefinition;
3415
- declare function defineMatrixConnection(config: MatrixConnectionInput): MatrixConnectionDefinition;
3416
2368
  declare function defineMessengerConnection(config: MessengerConnectionInput): MessengerConnectionDefinition;
3417
2369
  declare function definePancakeConnection(config: PancakeConnectionInput): PancakeConnectionDefinition;
3418
2370
  declare function defineSlackConnection(config: SlackConnectionInput): SlackConnectionDefinition;
@@ -3426,7 +2378,6 @@ declare function defineGitHubChannel<const Name extends string>(input: ResourceI
3426
2378
  declare function defineGoogleChatChannel<const Name extends string>(input: ResourceInput<Name, GoogleChatChannelInput>): ChannelResource<Name>;
3427
2379
  declare function defineInstagramChannel<const Name extends string>(input: ResourceInput<Name, InstagramChannelInput>): ChannelResource<Name>;
3428
2380
  declare function defineLinearChannel<const Name extends string>(input: ResourceInput<Name, LinearChannelInput>): ChannelResource<Name>;
3429
- declare function defineMatrixChannel<const Name extends string>(input: ResourceInput<Name, MatrixChannelInput>): ChannelResource<Name>;
3430
2381
  declare function defineMessengerChannel<const Name extends string>(input: ResourceInput<Name, MessengerChannelInput>): ChannelResource<Name>;
3431
2382
  declare function definePancakeChannel<const Name extends string>(input: ResourceInput<Name, PancakeChannelInput>): ChannelResource<Name>;
3432
2383
  declare function defineSlackChannel<const Name extends string>(input: ResourceInput<Name, SlackChannelInput>): ChannelResource<Name>;
@@ -3439,5 +2390,5 @@ declare function isBroodsConfig(value: unknown): value is BroodsConfigDefinition
3439
2390
  declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
3440
2391
  declare function isResource(value: unknown): value is AnyResource;
3441
2392
 
3442
- export { BroodsAccountApiError, BroodsAccountClient, BroodsClient, BroodsWebSocketClient, DEFAULT_CORE_BASE_URL, IngressAcceptedError, MAX_OBSERVABILITY_BACKFILL, USER_TOKEN_HEADER, USER_TOKEN_MAX_TTL_MS, USER_TOKEN_SECRET_ENV, BroodsWebSocketClient as WebSocketClient, BroodsWebSocketClient as WebsocketClient, defineAgent, defineBroods, defineCron, defineDiscordChannel, defineDiscordConnection, defineGitHubChannel, defineGitHubConnection, defineGoogleChatChannel, defineGoogleChatConnection, defineHarness, defineInstagramChannel, defineInstagramConnection, defineLinearChannel, defineLinearConnection, defineMatrixChannel, defineMatrixConnection, defineMcp, defineMessengerChannel, defineMessengerConnection, definePancakeChannel, definePancakeConnection, definePolicy, defineSandbox, defineSkill, defineSlackChannel, defineSlackConnection, defineTeamsChannel, defineTeamsConnection, defineTelegramChannel, defineTelegramConnection, defineTwilioChannel, defineTwilioConnection, defineWhatsAppChannel, defineWhatsAppConnection, defineWorkspace, defineZaloChannel, defineZaloConnection, env, envPlaceholder, isBroodsConfig, isConnectionDefinition, isLogLevel, isObservabilityClientMessage, isResource, isRootSpanKind, isSandboxLogId, isTraceId, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, signUserToken, toWebSocketBaseUrl, webSocketSubprotocols };
3443
- export type { Account, AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, Agent, AgentChannelsConfig, AgentCodeHookConfig, AgentConfig, AgentConfigDoc, AgentContinueInput, AgentDefinitionConfig, AgentDiscordChannelConfig, AgentGitHubChannelConfig, AgentGoogleChatChannelConfig, AgentHandle, AgentHookEventName, AgentHooks, AgentHooksConfig, AgentInstagramChannelConfig, AgentLinearChannelConfig, AgentMatrixChannelConfig, AgentMessengerChannelConfig, AgentPancakeChannelConfig, AgentProviderSettings, AgentReference, AgentResource, AgentRunAnswerInput, AgentRunEventInput, AgentRunInput, AgentRunModelOverrides, AgentRunOverrides, AgentRunResult, AgentSkillsDefinitionConfig, AgentSlackChannelConfig, AgentStreamPart, AgentSubagentDefinitionConfig, AgentTeamsChannelConfig, AgentTelegramChannelConfig, AgentTwilioChannelConfig, AgentWebhookHookConfig, AgentWhatsAppChannelConfig, AgentWorkspaceInput, AgentWorkspaceRef, AgentWorkspaceRefInput, AgentZaloChannelConfig, AnyConnectionDefinition, AnyResource, AssumeRoleResult, AsyncAgentRun, AsyncPollOptions, AsyncRequestAccepted, AsyncStatus, AuditEvent, AuditPage, AuditPrincipalLink, AuditSink, AuditVerification, BroodsAccount, BroodsAccountClientOptions, BroodsClientOptions, BroodsConfigDefinition, BroodsProjectConfig, BroodsWebSocketClientOptions, ChannelAgentInput, ChannelDefinitionConfig, ChannelMessageReceived, ChannelPartition, ChannelRecordConfig, ChannelReference, ChannelReplyIn, ChannelResource, ChannelType, CliManifest, CliManifestResource, ConfigPatch, Connection, ConnectionCode, ConnectionDefinition, ConnectionStart, ConnectionStartResult, ConnectionType, CreateAgentResult, CreateCronInput, CreateMcpInput, Cron, CronDefinitionConfig, CronDoc, CronLastStatus, CronResource, CronRun, CronStatus, DeleteAccountResult, DeploymentRegion, DiscordChannelInput, DiscordConnectionDefinition, DiscordConnectionInput, DiscordMessageSource, DiscordSource, Doc, EnvAccessor, EnvRef, EnvRefString, GeneratedIds, GitHubChannelInput, GitHubConnectionDefinition, GitHubConnectionInput, GitHubMessageSource, GitHubSource, GoogleChatChannelInput, GoogleChatConnectionDefinition, GoogleChatConnectionInput, GoogleChatMessageSource, GoogleChatSource, HarnessDefinition, HarnessType, HookAgentConfig, HookContext, Id, IngressMode, IngressStatus, InstagramChannelInput, InstagramConnectionDefinition, InstagramConnectionInput, InstagramMessageSource, InstagramSource, LinearChannelInput, LinearConnectionDefinition, LinearConnectionInput, LinearMessageSource, LinearSource, LogLevel, MatrixChannelInput, MatrixConnectionDefinition, MatrixConnectionInput, MatrixMessageSource, MatrixSource, McpDefinitionConfig, McpHandler, McpOauthInput, McpResource, McpRuntime, MessengerChannelInput, MessengerConnectionDefinition, MessengerConnectionInput, MessengerMessageSource, MessengerSource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityFetchTraceMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, PendingQuestion, PolicyDefinitionConfig, PolicyDocument, PolicyResource, ProjectDoc, ProviderConfigInput, ProviderSettingsInput, QuestionAnswer, ResourceApi, ResourceDefinition, ResourceInput, ResourceKind, RotateSecretResult, Sandbox, SandboxConfig, SandboxConfigDoc, SandboxDefinitionConfig, SandboxDefinitionOptions, SandboxExecRequest, SandboxExecResponse, SandboxLifecycleResult, SandboxProvider, SandboxResource, SandboxSnapshotResult, SandboxTerminalTicket, SignUserTokenInput, Skill, SkillDefinitionConfig, SkillResource, SkillUploadInput, SlackChannelInput, SlackConnectionDefinition, SlackConnectionInput, SlackMessageSource, SlackSource, StageDoc, StageScope, StorageTrust, TaskWaitingOn, TeamsChannelInput, TeamsConnectionDefinition, TeamsConnectionInput, TeamsMessageSource, TeamsSource, TelegramChannelInput, TelegramConnectionDefinition, TelegramConnectionInput, TelegramMessageSource, TelegramSource, ToolApprovalSummary, TwilioChannelInput, TwilioConnectionDefinition, TwilioConnectionInput, TwilioMessageSource, TwilioSource, UpdateAgentInput, UpdateCronInput, UpdateMcpInput, WebSocketAttachInput, WebSocketClientAttachMessage, WebSocketClientCancelMessage, WebSocketClientControlMessage, WebSocketClientExecuteMessage, WebSocketClientMessage, WebSocketConstructorLike, WebSocketHandlers, WebSocketLike, WebSocketOutputMessage, WebSocketRunInput, WebSocketServerMessage, WebSocketStreamMessage, WebSocketSubscription, WhatsAppChannelInput, WhatsAppConnectionDefinition, WhatsAppConnectionInput, WhatsAppMessageSource, WhatsAppSource, Workspace, WorkspaceConfig, WorkspaceConfigDoc, WorkspaceDefinitionConfig, WorkspaceFileEntry, WorkspaceIsolation, WorkspaceResource, WorkspaceStorageDefinition, ZaloChannelInput, ZaloConnectionDefinition, ZaloConnectionInput, ZaloMessageSource, ZaloSource };
2393
+ export { BroodsAccountApiError, BroodsAccountClient, BroodsClient, BroodsWebSocketClient, DEFAULT_CORE_BASE_URL, IngressAcceptedError, MAX_OBSERVABILITY_BACKFILL, USER_TOKEN_HEADER, USER_TOKEN_MAX_TTL_MS, USER_TOKEN_SECRET_ENV, BroodsWebSocketClient as WebSocketClient, BroodsWebSocketClient as WebsocketClient, defineAgent, defineBroods, defineCron, defineDiscordChannel, defineDiscordConnection, defineGitHubChannel, defineGitHubConnection, defineGoogleChatChannel, defineGoogleChatConnection, defineHarness, defineInstagramChannel, defineInstagramConnection, defineLinearChannel, defineLinearConnection, defineMcp, defineMessengerChannel, defineMessengerConnection, definePancakeChannel, definePancakeConnection, definePolicy, defineSandbox, defineSkill, defineSlackChannel, defineSlackConnection, defineTeamsChannel, defineTeamsConnection, defineTelegramChannel, defineTelegramConnection, defineTwilioChannel, defineTwilioConnection, defineWhatsAppChannel, defineWhatsAppConnection, defineWorkspace, defineZaloChannel, defineZaloConnection, env, envPlaceholder, isBroodsConfig, isConnectionDefinition, isLogLevel, isObservabilityClientMessage, isResource, isRootSpanKind, isSandboxLogId, isTraceId, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, signUserToken, toWebSocketBaseUrl, webSocketSubprotocols };
2394
+ export type { Account, AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, Agent, AgentChannelsConfig, AgentCodeHookConfig, AgentConfig, AgentConfigDoc, AgentContinueInput, AgentDefinitionConfig, AgentDiscordChannelConfig, AgentGitHubChannelConfig, AgentGoogleChatChannelConfig, AgentHandle, AgentHookEventName, AgentHooks, AgentHooksConfig, AgentInstagramChannelConfig, AgentLinearChannelConfig, AgentMessengerChannelConfig, AgentPancakeChannelConfig, AgentProviderSettings, AgentReference, AgentResource, AgentRunAnswerInput, AgentRunEventInput, AgentRunInput, AgentRunModelOverrides, AgentRunOverrides, AgentRunResult, AgentSkillsDefinitionConfig, AgentSlackChannelConfig, AgentStreamPart, AgentSubagentDefinitionConfig, AgentTeamsChannelConfig, AgentTelegramChannelConfig, AgentTwilioChannelConfig, AgentWebhookHookConfig, AgentWhatsAppChannelConfig, AgentWorkspaceInput, AgentWorkspaceRef, AgentWorkspaceRefInput, AgentZaloChannelConfig, AnyConnectionDefinition, AnyResource, AssumeRoleResult, AsyncAgentRun, AsyncPollOptions, AsyncRequestAccepted, AsyncStatus, AuditEvent, AuditPage, AuditPrincipalLink, AuditSink, AuditVerification, BroodsAccount, BroodsAccountClientOptions, BroodsClientOptions, BroodsConfigDefinition, BroodsProjectConfig, BroodsWebSocketClientOptions, ChannelAgentInput, ChannelDefinitionConfig, ChannelMessageReceived, ChannelPartition, ChannelRecordConfig, ChannelReference, ChannelReplyIn, ChannelResource, ChannelType, CliManifest, CliManifestResource, ConfigPatch, Connection, ConnectionCode, ConnectionDefinition, ConnectionStart, ConnectionStartResult, ConnectionType, CreateAgentResult, CreateCronInput, CreateMcpInput, Cron, CronDefinitionConfig, CronDoc, CronLastStatus, CronResource, CronRun, CronStatus, DeleteAccountResult, DeploymentRegion, DiscordChannelInput, DiscordConnectionDefinition, DiscordConnectionInput, DiscordMessageSource, DiscordSource, Doc, EnvAccessor, EnvRef, EnvRefString, GeneratedIds, GitHubChannelInput, GitHubConnectionDefinition, GitHubConnectionInput, GitHubMessageSource, GitHubSource, GoogleChatChannelInput, GoogleChatConnectionDefinition, GoogleChatConnectionInput, GoogleChatMessageSource, GoogleChatSource, HarnessDefinition, HarnessType, HookAgentConfig, HookContext, Id, IngressMode, IngressStatus, InstagramChannelInput, InstagramConnectionDefinition, InstagramConnectionInput, InstagramMessageSource, InstagramSource, LinearChannelInput, LinearConnectionDefinition, LinearConnectionInput, LinearMessageSource, LinearSource, LogLevel, McpDefinitionConfig, McpHandler, McpOauthInput, McpResource, McpRuntime, MessengerChannelInput, MessengerConnectionDefinition, MessengerConnectionInput, MessengerMessageSource, MessengerSource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityFetchTraceMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, PendingQuestion, PolicyDefinitionConfig, PolicyDocument, PolicyResource, ProjectDoc, ProviderConfigInput, ProviderSettingsInput, QuestionAnswer, ResourceApi, ResourceDefinition, ResourceInput, ResourceKind, RotateSecretResult, Sandbox, SandboxConfig, SandboxConfigDoc, SandboxDefinitionConfig, SandboxDefinitionOptions, SandboxExecRequest, SandboxExecResponse, SandboxLifecycleResult, SandboxProvider, SandboxResource, SandboxSnapshotResult, SandboxTerminalTicket, SignUserTokenInput, Skill, SkillDefinitionConfig, SkillResource, SkillUploadInput, SlackChannelInput, SlackConnectionDefinition, SlackConnectionInput, SlackMessageSource, SlackSource, StageDoc, StageScope, StorageTrust, TaskWaitingOn, TeamsChannelInput, TeamsConnectionDefinition, TeamsConnectionInput, TeamsMessageSource, TeamsSource, TelegramChannelInput, TelegramConnectionDefinition, TelegramConnectionInput, TelegramMessageSource, TelegramSource, ToolApprovalSummary, TwilioChannelInput, TwilioConnectionDefinition, TwilioConnectionInput, TwilioMessageSource, TwilioSource, UpdateAgentInput, UpdateCronInput, UpdateMcpInput, WebSocketAttachInput, WebSocketClientAttachMessage, WebSocketClientCancelMessage, WebSocketClientControlMessage, WebSocketClientExecuteMessage, WebSocketClientMessage, WebSocketConstructorLike, WebSocketHandlers, WebSocketLike, WebSocketOutputMessage, WebSocketRunInput, WebSocketServerMessage, WebSocketStreamMessage, WebSocketSubscription, WhatsAppChannelInput, WhatsAppConnectionDefinition, WhatsAppConnectionInput, WhatsAppMessageSource, WhatsAppSource, Workspace, WorkspaceConfig, WorkspaceConfigDoc, WorkspaceDefinitionConfig, WorkspaceFileEntry, WorkspaceIsolation, WorkspaceResource, WorkspaceStorageDefinition, ZaloChannelInput, ZaloConnectionDefinition, ZaloConnectionInput, ZaloMessageSource, ZaloSource };