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