@crewhaus/ir 0.1.4 → 0.1.6

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/src/index.ts DELETED
@@ -1,1004 +0,0 @@
1
- /**
2
- * v0 IR — runtime-agnostic representation, target-tagged.
3
- * In the slice, IR shape mirrors the spec; later passes (ir-passes module)
4
- * will perform optimization and target-specific lowering.
5
- */
6
- export type IrPermissionRule = {
7
- readonly type: "alwaysAllow" | "alwaysDeny" | "alwaysAsk";
8
- readonly pattern: string;
9
- };
10
-
11
- /**
12
- * Permissions config carried through to codegen. The mode here cannot be
13
- * "bypass" — that's enforced by the spec parser. Bypass enters via CLI flag.
14
- */
15
- export type IrPermissions = {
16
- readonly mode?: "default" | "plan" | "auto";
17
- readonly rules: readonly IrPermissionRule[];
18
- };
19
-
20
- /**
21
- * MCP server configs carried through to codegen (Section 9). Lower-time
22
- * normalisation: optional spec fields become required IR fields with
23
- * empty defaults, so target codegen doesn't need `?? []` guards.
24
- */
25
- export type IrMcpStdioConfig = {
26
- readonly transport: "stdio";
27
- readonly command: string;
28
- readonly args: readonly string[];
29
- readonly env?: Readonly<Record<string, string>>;
30
- };
31
-
32
- export type IrMcpSseConfig = {
33
- readonly transport: "sse";
34
- readonly url: string;
35
- readonly headers?: Readonly<Record<string, string>>;
36
- };
37
-
38
- export type IrMcpServerConfig = IrMcpStdioConfig | IrMcpSseConfig;
39
- export type IrMcpServers = Readonly<Record<string, IrMcpServerConfig>>;
40
-
41
- /**
42
- * Section 13 — a sub-agent definition lowered from spec form. The map's key
43
- * is hoisted to a `name` field for ergonomics. `tools: readonly string[]`
44
- * mirrors `IrV0.tools`; codegen filters the parent catalog to this
45
- * allowlist when building the child catalog. `permissions` defaults to
46
- * `"inherit"` at lower-time when undefined; `inheritBypass` to false.
47
- */
48
- export type IrSubAgentDefinition = {
49
- readonly name: string;
50
- readonly description: string;
51
- readonly instructions: string;
52
- readonly tools: readonly string[];
53
- readonly model?: string;
54
- readonly permissions:
55
- | "inherit"
56
- | "scoped"
57
- | { readonly allow: readonly string[]; readonly deny: readonly string[] };
58
- readonly inheritBypass: boolean;
59
- };
60
-
61
- /**
62
- * Section 14 — per-tool runtime config carried verbatim from the spec to
63
- * codegen. Keys are tool names (lowercase variable name as used in
64
- * `BUILTIN_TOOL_MAP`); values are tool-specific config blobs whose schemas
65
- * live inside each tool package. Empty-default at lower-time so codegen
66
- * never has to `?? {}`.
67
- */
68
- export type IrToolConfigs = Readonly<Record<string, unknown>>;
69
-
70
- /**
71
- * Section 17 — optional per-target compaction config. `model` overrides
72
- * the model used by `compaction-autocompact` for summarisation; when
73
- * undefined (or the whole block is undefined) the runtime defaults to
74
- * the agent's primary model. Lower-time the spec block is normalised to
75
- * an object so codegen never has to `?? {}`.
76
- */
77
- export type IrCompaction = {
78
- readonly model?: string;
79
- /** Pillar 2 — when true, target emitters wire `compaction-curator`
80
- * as a pre-pass before the autocompact threshold check. The spec
81
- * layer accepts this verbatim (validated in `packages/spec`); the
82
- * IR holds it as an opt-in flag with no default so emitters can
83
- * distinguish "user said false" from "user didn't say". */
84
- readonly curate?: boolean;
85
- /** Cosine threshold for the curator's dedupe pass. Curator's own
86
- * default (0.92, `DEFAULT_DEDUPE_THRESHOLD` in
87
- * `@crewhaus/compaction-curator`) applies when undefined. */
88
- readonly dedupeThreshold?: number;
89
- /** Top-K cap for the curator's relevance reorder. Undefined means
90
- * reorder without trimming. */
91
- readonly relevanceTopK?: number;
92
- };
93
-
94
- /**
95
- * Section 55 (Track A) — named failure taxonomy. Cross-cutting; carried
96
- * through to runtime-core so `recovery-engine` can consult the user's
97
- * named classes before falling back to its built-in taxonomy.
98
- *
99
- * `pattern` is a substring (case-insensitive) of the error.message OR a
100
- * `/regex/` literal — the recovery engine compiles each form once at
101
- * spec-load time. `recovery` names which `RecoveryAction` to take.
102
- * `hint`, when present, is what `runtime-core` appends as a synthetic
103
- * system message on `retry`/`continue` recoveries so the model gets
104
- * named-class self-correction guidance.
105
- *
106
- * Source: Natural-Language Agent Harnesses (arxiv 2603.25723).
107
- */
108
- export type IrFailureTaxonomyEntry = {
109
- readonly class: string;
110
- readonly pattern: string;
111
- readonly recovery: "retry" | "compact" | "continue" | "tombstone" | "fail";
112
- readonly hint?: string;
113
- };
114
-
115
- export type IrFailureTaxonomy = readonly IrFailureTaxonomyEntry[];
116
-
117
- /**
118
- * Pillar 3 (FR-004) — per-target security fabric configuration the
119
- * compiler lowers from the spec's `security` block. Today it carries the
120
- * intent-gate's judge selection; `egressPolicy` is reserved for the
121
- * sink-side fabric (FR-002/006) and intentionally not modelled here.
122
- *
123
- * `justification.judge` selects which `JustificationJudge` the runtime
124
- * wires for `requireJustification: true` tools — `"rule-based"` (the
125
- * deterministic default, `ruleBasedJustificationJudge`) or `"claude"`
126
- * (the model-backed `@crewhaus/justification-judge-claude`). `model` is
127
- * the judge model id when `judge: "claude"`; the consumer defaults it to
128
- * a haiku-class model when omitted. Optional + spread-in at lower-time so
129
- * the field is absent when the spec omits the block (same convention as
130
- * `failureTaxonomy`).
131
- */
132
- export type IrSecurity = {
133
- readonly justification?: {
134
- readonly judge: "rule-based" | "claude";
135
- readonly model?: string;
136
- };
137
- /**
138
- * Pillar 3 sink-side fabric (FR-006) — the egress-matching strategy.
139
- * `"substring"` is the behavior-preserving `SubstringEgressMatcher`
140
- * (`MIN_MATCH_LENGTH`); `"semantic"` selects the optional embedding-backed
141
- * `@crewhaus/egress-matcher-semantic`. Lowered from
142
- * `spec.security.egressMatcher`. Absent when the spec omits it, in which
143
- * case the runtime stays on the substring default. Honoured on BOTH paths:
144
- * the `crewhaus run` interpreter resolves it into
145
- * `runChatLoop({ egressMatcher })`, and `@crewhaus/target-cli` emits the
146
- * same matcher construction into the standalone compiled bundle. Only
147
- * changes *how* lineage matches are detected — the per-origin/per-sink
148
- * policy and the three audit outcomes (`egress-passed | egress-warned |
149
- * egress-blocked`) are matcher-independent and live in `classifyEgress`,
150
- * not here.
151
- */
152
- readonly egressMatcher?: "substring" | "semantic";
153
- };
154
-
155
- /**
156
- * Track F (Section 57) — typed message schemas (Σ) for multi-agent
157
- * communication. Source: AgentFlow (arxiv 2604.20801). A typed graph
158
- * DSL with well-formedness checking makes searching the full multi-
159
- * agent design space tractable: structurally broken candidates are
160
- * eliminated cheaply, so the search budget goes to well-formed
161
- * harnesses only.
162
- *
163
- * An IrMessageSchema is a named JSON-Schema shape describing what a
164
- * given edge in the crew/graph carries. The well-formedness pass in
165
- * `@crewhaus/ir-passes` checks that every edge in the graph references
166
- * either a declared schema or `untyped` (the legacy default).
167
- */
168
- export type IrMessageSchema = {
169
- readonly name: string;
170
- /** JSON Schema describing the message payload. v0 keeps it as `unknown`
171
- * rather than typed-importing zod-to-json-schema — the wellformedness
172
- * pass only checks that the schema is an object; full validation
173
- * happens at runtime in `@crewhaus/runtime-core`. */
174
- readonly schema: Readonly<Record<string, unknown>>;
175
- };
176
-
177
- /**
178
- * Per-edge schema reference. `untyped` means "any payload" (the v0
179
- * default that preserves backwards compatibility). Named references
180
- * must match one of the variant's `messageSchemas` entries.
181
- */
182
- export type IrSchemaRef =
183
- | { readonly kind: "untyped" }
184
- | { readonly kind: "named"; readonly name: string };
185
-
186
- /**
187
- * Phase 3 §3.3 — CLI banner config carried into IR for codegen.
188
- */
189
- export type IrCliBanner = {
190
- readonly taglineMode: "static" | "random";
191
- readonly taglines: readonly string[];
192
- };
193
-
194
- export type IrCliOptions = {
195
- readonly banner?: IrCliBanner;
196
- /** Phase 2 M2.2 — TUI mode gate. */
197
- readonly tui?: "basic" | "rich";
198
- };
199
-
200
- export type IrV0 = {
201
- readonly version: 0;
202
- readonly name: string;
203
- readonly target: "cli";
204
- readonly agent: {
205
- readonly model: string;
206
- readonly instructions: string;
207
- };
208
- readonly tools: readonly string[];
209
- readonly toolConfigs: IrToolConfigs;
210
- readonly mcp_servers: IrMcpServers;
211
- readonly permissions: IrPermissions;
212
- readonly subAgents: readonly IrSubAgentDefinition[];
213
- readonly compaction: IrCompaction;
214
- readonly cli?: IrCliOptions;
215
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
216
- readonly failureTaxonomy?: IrFailureTaxonomy;
217
- /** Pillar 3 (FR-004) — security fabric config (intent-gate judge
218
- * selection). Optional; absent when the spec omits the `security`
219
- * block. */
220
- readonly security?: IrSecurity;
221
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
222
- readonly chains?: readonly IrChainBinding[];
223
- readonly wallets?: readonly IrWalletBinding[];
224
- readonly contracts?: readonly IrContractBinding[];
225
- readonly transactionPolicy?: IrTransactionPolicy;
226
- };
227
-
228
- /**
229
- * One step in a workflow IR. `model` is resolved at lower-time
230
- * (`step.model ?? workflow.model`) so codegen can read it directly.
231
- */
232
- export type IrWorkflowStep = {
233
- readonly name: string;
234
- readonly instructions: string;
235
- readonly model: string;
236
- readonly tools: readonly string[];
237
- readonly toolConfigs: IrToolConfigs;
238
- };
239
-
240
- /**
241
- * Workflow IR — a sequence of steps. Each step runs as one user→assistant
242
- * turn; the prior step's terminal assistant text is threaded into the next
243
- * step's user message by the generated runtime (target-workflow).
244
- */
245
- export type IrWorkflowV0 = {
246
- readonly version: 0;
247
- readonly name: string;
248
- readonly target: "workflow";
249
- readonly steps: readonly IrWorkflowStep[];
250
- readonly mcp_servers: IrMcpServers;
251
- readonly permissions: IrPermissions;
252
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
253
- readonly chains?: readonly IrChainBinding[];
254
- readonly wallets?: readonly IrWalletBinding[];
255
- readonly contracts?: readonly IrContractBinding[];
256
- readonly transactionPolicy?: IrTransactionPolicy;
257
- readonly compaction: IrCompaction;
258
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
259
- readonly failureTaxonomy?: IrFailureTaxonomy;
260
- };
261
-
262
- /**
263
- * A secret value referenced by a channel config (Section 12). Lower-time
264
- * normalisation: spec strings starting with `$VAR_NAME` (where VAR_NAME
265
- * matches `[A-Z_][A-Z0-9_]*`) become `{ kind: "env", name }`, anything else
266
- * becomes `{ kind: "literal", value }`. Codegen emits literals as quoted
267
- * strings and env-refs as `process.env.VAR_NAME`, plus a startup check
268
- * that exits non-zero when a referenced env var is unset.
269
- */
270
- export type IrSecretRef =
271
- | { readonly kind: "literal"; readonly value: string }
272
- | { readonly kind: "env"; readonly name: string };
273
-
274
- /**
275
- * Section 47 — Blockchain primitives (cross-cutting subsystem).
276
- *
277
- * These types are shared across shapes that interact with chain state.
278
- * Any shape may declare optional `chains` / `wallets` / `contracts` /
279
- * `transactionPolicy` blocks; the §47 `onchain` and `onchain-game`
280
- * target variants additionally require `triggers` and a `game` block
281
- * respectively (those types land with slice 2).
282
- *
283
- * Finality policy is encoded explicitly because reorg tolerance and
284
- * confirmation counts are quality knobs (Pillar 2: optimizable) and
285
- * security boundaries (Pillar 3: a wrong finality choice lets an
286
- * attacker present a reorged log as real). See [recipes/47-onchain-daemon-and-game.md](https://github.com/crewhaus/demos/blob/main/walkthroughs/47-onchain-daemon-and-game.md).
287
- */
288
- export type IrChainFinality =
289
- | { readonly kind: "confirmations"; readonly count: number }
290
- | { readonly kind: "finalized" }
291
- | { readonly kind: "safe" };
292
-
293
- /**
294
- * Resolved chain config. `kind: "evm"` is the only supported family in
295
- * slice 0/1/2 — Solana, Cosmos, and Bitcoin are deferred. `rpcUrls` is
296
- * an array of `IrSecretRef` so URLs that carry API keys (Alchemy,
297
- * Infura) can be loaded from env at runtime. `rpcPolicy` controls how
298
- * multiple URLs are used: `single` picks the first, `fallback` retries
299
- * the next on error, `quorum` requires N/M agreement on critical reads.
300
- */
301
- export type IrChainBinding = {
302
- readonly id: string;
303
- readonly kind: "evm";
304
- readonly rpcUrls: readonly IrSecretRef[];
305
- readonly rpcPolicy: "single" | "quorum" | "fallback";
306
- readonly finality: IrChainFinality;
307
- readonly reorgTolerant: boolean;
308
- };
309
-
310
- /**
311
- * Wallet binding — how the runtime signs transactions for `chainId`.
312
- * `custody` declares where the key lives; `signingPolicy` declares how
313
- * each sign request is gated. The default for any `destructive: true`
314
- * tool that uses this wallet is `explicit-user-approval`; `policy-gated`
315
- * defers to the §47 `transaction_policy` block; `automated` is only
316
- * permitted when the wallet is also marked `kms` or `hsm` custody.
317
- * `keyRef` is required for `kms` / `hsm` / `local` custody; for
318
- * `user-controlled` (WalletConnect, MetaMask, etc.) the signing happens
319
- * externally and `keyRef` is omitted.
320
- */
321
- export type IrWalletBinding = {
322
- readonly id: string;
323
- readonly chainId: string;
324
- readonly custody: "user-controlled" | "kms" | "hsm" | "local";
325
- readonly signingPolicy: "explicit-user-approval" | "policy-gated" | "automated";
326
- readonly keyRef?: IrSecretRef;
327
- };
328
-
329
- /**
330
- * Smart-contract binding. `abiRef` is a string the
331
- * `tool-contract-gateway` (slice 1) resolves into a typed-tool set;
332
- * supported schemes are `abi://erc20`, `abi://erc721`, `abi://erc1155`,
333
- * and `file://path/to/abi.json`. Reads against this contract become
334
- * `readOnly: true` tools; writes become `destructive: true` and gate
335
- * approval automatically via `permission-engine`.
336
- */
337
- export type IrContractBinding = {
338
- readonly id: string;
339
- readonly chainId: string;
340
- readonly address: string;
341
- readonly abiRef: string;
342
- };
343
-
344
- /**
345
- * Transaction policy — the safety floor for any tool that signs and
346
- * broadcasts a transaction. `defaultWriteApproval: "required"` is the
347
- * default; setting it to `"none"` is only valid when every wallet is
348
- * `automated` custody, which the §47 IR pass enforces. `maxValueUsd`
349
- * is an upper bound on native-token transfers (in USD, evaluated at
350
- * sign-time via the configured price oracle); transactions exceeding
351
- * the cap are rejected pre-broadcast. `allowedContracts` is a list of
352
- * `IrContractBinding.id` values — destructive calls to any other
353
- * contract are rejected. `simulationRequired: true` forces every
354
- * destructive call through a fork-simulator before approval.
355
- */
356
- export type IrTransactionPolicy = {
357
- readonly defaultWriteApproval: "required" | "policy" | "none";
358
- readonly maxValueUsd?: number;
359
- /** Oracle-free native-token spend ceiling (wei, decimal or 0x-hex string). */
360
- readonly maxValueWei?: string;
361
- readonly allowedContracts: readonly string[];
362
- readonly simulationRequired: boolean;
363
- };
364
-
365
- export type IrSlackConfig = {
366
- readonly botToken: IrSecretRef;
367
- readonly signingSecret: IrSecretRef;
368
- readonly appToken?: IrSecretRef;
369
- };
370
-
371
- /**
372
- * Section 33 — Telegram channel config. `secretToken` is the value passed
373
- * to `setWebhook(secret_token=...)` and verified on every inbound POST
374
- * via the `X-Telegram-Bot-Api-Secret-Token` header.
375
- */
376
- export type IrTelegramConfig = {
377
- readonly botToken: IrSecretRef;
378
- readonly secretToken: IrSecretRef;
379
- };
380
-
381
- /**
382
- * Section 33 — Discord channel config. `publicKeyHex` is the bot
383
- * application's public key (hex, 64 chars) used for Ed25519 verification
384
- * of inbound interaction webhooks.
385
- */
386
- export type IrDiscordConfig = {
387
- readonly applicationId: IrSecretRef;
388
- readonly botToken: IrSecretRef;
389
- readonly publicKeyHex: IrSecretRef;
390
- };
391
-
392
- /**
393
- * Section 33 — WhatsApp Business Cloud API channel config.
394
- * `phoneNumberId` is the Meta-issued phone-number id (numeric,
395
- * stringified) the bot sends messages from. `accessToken` is the
396
- * system-user token authorising sends. `appSecret` is the Meta app
397
- * secret used to verify the `X-Hub-Signature-256` HMAC.
398
- */
399
- export type IrWhatsAppConfig = {
400
- readonly phoneNumberId: IrSecretRef;
401
- readonly accessToken: IrSecretRef;
402
- readonly appSecret: IrSecretRef;
403
- };
404
-
405
- /**
406
- * Section 33 — iMessage channel config (macOS host-bound). `chatDbPath`
407
- * defaults to `~/Library/Messages/chat.db`; `cursorPath` defaults to
408
- * `.crewhaus/imessage-cursor.json`. Both can be overridden in spec for
409
- * tests. The adapter requires `CREWHAUS_IMESSAGE_HOST_ENABLED=1` at
410
- * boot, so no IR-level secret is needed.
411
- */
412
- export type IrIMessageConfig = {
413
- readonly chatDbPath?: IrSecretRef;
414
- readonly cursorPath?: IrSecretRef;
415
- };
416
-
417
- export type IrChannels = {
418
- readonly slack?: IrSlackConfig;
419
- readonly telegram?: IrTelegramConfig;
420
- readonly discord?: IrDiscordConfig;
421
- readonly whatsapp?: IrWhatsAppConfig;
422
- readonly imessage?: IrIMessageConfig;
423
- };
424
-
425
- export type IrRouting = {
426
- readonly sessionKey: "thread" | "user" | "channel";
427
- };
428
-
429
- /**
430
- * Channel IR — a long-running daemon that listens for inbound webhook events
431
- * and runs one agent turn per inbound message. The daemon resumes per-thread
432
- * sessions (keyed by `routing.sessionKey`) via session-store + event-log,
433
- * appends the new message, and runs one `runChatLoop` turn.
434
- */
435
- /**
436
- * Phase 3 §3.1 — heartbeat config carried into IR. `everyMs` is
437
- * normalized from the duration-string in the spec to milliseconds at
438
- * lower time so codegen can emit a literal numeric setInterval arg.
439
- */
440
- export type IrHeartbeat = {
441
- readonly everyMs: number;
442
- readonly instructions: string;
443
- };
444
-
445
- /**
446
- * Phase 3 §3.4 — channel daemon control-UI gateway config.
447
- */
448
- export type IrChannelGateway = {
449
- readonly port: number;
450
- readonly ui: boolean;
451
- };
452
-
453
- export type IrChannelV0 = {
454
- readonly version: 0;
455
- readonly name: string;
456
- readonly target: "channel";
457
- readonly agent: {
458
- readonly model: string;
459
- readonly instructions: string;
460
- };
461
- readonly tools: readonly string[];
462
- readonly toolConfigs: IrToolConfigs;
463
- readonly channels: IrChannels;
464
- readonly routing: IrRouting;
465
- readonly mcp_servers: IrMcpServers;
466
- readonly permissions: IrPermissions;
467
- readonly subAgents: readonly IrSubAgentDefinition[];
468
- readonly compaction: IrCompaction;
469
- readonly heartbeat?: IrHeartbeat;
470
- readonly gateway?: IrChannelGateway;
471
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
472
- readonly failureTaxonomy?: IrFailureTaxonomy;
473
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
474
- readonly chains?: readonly IrChainBinding[];
475
- readonly wallets?: readonly IrWalletBinding[];
476
- readonly contracts?: readonly IrContractBinding[];
477
- readonly transactionPolicy?: IrTransactionPolicy;
478
- };
479
-
480
- /**
481
- * Section 20 — Managed daemon IR. Carries the agent block, the
482
- * tenant table, and any per-tenant policy / budget overrides. The
483
- * `target-managed` codegen consumes this to emit `daemon.ts` +
484
- * `agent.ts` files.
485
- */
486
- export type IrManagedTenant = {
487
- readonly id: string;
488
- readonly budget: {
489
- readonly maxInputTokens: number;
490
- readonly maxOutputTokens: number;
491
- };
492
- };
493
-
494
- export type IrManagedV0 = {
495
- readonly version: 0;
496
- readonly name: string;
497
- readonly target: "managed";
498
- readonly agent: {
499
- readonly model: string;
500
- readonly instructions: string;
501
- };
502
- readonly tenants: readonly IrManagedTenant[];
503
- readonly permissions: IrPermissions;
504
- readonly compaction: IrCompaction;
505
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
506
- readonly failureTaxonomy?: IrFailureTaxonomy;
507
- };
508
-
509
- /**
510
- * Section 19 — Graph IR. A `target: "graph"` spec lowers into a fixed
511
- * set of LLM-backed nodes plus the edges that connect them.
512
- */
513
- export type IrGraphNode = {
514
- readonly name: string;
515
- readonly instructions: string;
516
- /** Resolved at lower-time (node.model ?? graph.model). */
517
- readonly model: string;
518
- readonly tools: readonly string[];
519
- readonly toolConfigs: IrToolConfigs;
520
- /**
521
- * When set, the node calls `ctx.requestApproval(prompt)` after the
522
- * LLM turn and pauses the graph until `resume(checkpointId, decision)`.
523
- */
524
- readonly hitlPrompt?: string;
525
- };
526
-
527
- export type IrGraphEdge = {
528
- readonly from: string;
529
- readonly to: string;
530
- /** Track F (Section 57) — typed message schema carried by this edge.
531
- * Defaults to `{ kind: "untyped" }` (any payload) when absent. The
532
- * ir-passes wellformedness check verifies named refs resolve. */
533
- readonly schema?: IrSchemaRef;
534
- };
535
-
536
- export type IrGraphV0 = {
537
- readonly version: 0;
538
- readonly name: string;
539
- readonly target: "graph";
540
- readonly entry: string;
541
- readonly nodes: readonly IrGraphNode[];
542
- readonly edges: readonly IrGraphEdge[];
543
- /** Track F (Section 57) — named message schemas referenced by edges.
544
- * Absent means no typed edges (all `untyped` by default). */
545
- readonly messageSchemas?: readonly IrMessageSchema[];
546
- readonly permissions: IrPermissions;
547
- readonly compaction: IrCompaction;
548
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
549
- readonly failureTaxonomy?: IrFailureTaxonomy;
550
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
551
- readonly chains?: readonly IrChainBinding[];
552
- readonly wallets?: readonly IrWalletBinding[];
553
- readonly contracts?: readonly IrContractBinding[];
554
- readonly transactionPolicy?: IrTransactionPolicy;
555
- };
556
-
557
- /**
558
- * Section 21 — Pipeline / RAG IR. Carries the embedder + vector-store
559
- * config + an indexing pipeline (chunker → embed → store) + the agent
560
- * block that uses the Retrieve tool.
561
- */
562
- export type IrPipelineDocument = {
563
- readonly id: string;
564
- readonly text: string;
565
- readonly metadata?: Readonly<Record<string, unknown>>;
566
- };
567
-
568
- /**
569
- * Vector-store backend selector. Mirrors `VectorBackendId` from
570
- * `@crewhaus/vector-store` — the canonical source of truth for which
571
- * backends exist — but kept inline here (exactly as `IrBatchQueueAdapter`
572
- * mirrors the `queue-protocol` adapter ids) so the runtime-agnostic IR
573
- * keeps its zero runtime-package dependencies. Keep the two in sync when a
574
- * backend is added or removed.
575
- */
576
- export type IrVectorBackend = "in-memory" | "lance" | "qdrant" | "pinecone" | "weaviate";
577
-
578
- export type IrPipelineV0 = {
579
- readonly version: 0;
580
- readonly name: string;
581
- readonly target: "pipeline";
582
- readonly agent: {
583
- readonly model: string;
584
- readonly instructions: string;
585
- };
586
- readonly retrieve: {
587
- readonly embedderModel: string;
588
- readonly vectorBackend: IrVectorBackend;
589
- readonly defaultK: number;
590
- /**
591
- * Remote (qdrant/pinecone/weaviate) and file (lance) backends — the
592
- * service base URL or, for lance, the on-disk index path. Omitted for
593
- * `in-memory`. Required for the HTTP backends (enforced at spec parse).
594
- */
595
- readonly url?: string;
596
- /** Remote/file backends — collection / table name. */
597
- readonly collection?: string;
598
- /**
599
- * Remote backends — API key, lowered to an env-ref (`$VAR` →
600
- * `process.env`) or a literal so real secrets stay out of the bundle.
601
- */
602
- readonly apiKey?: IrSecretRef;
603
- };
604
- readonly indexing: {
605
- readonly chunkStrategy: "fixed" | "semantic" | "markdown";
606
- readonly chunkSize: number;
607
- readonly chunkOverlap: number;
608
- readonly documents: readonly IrPipelineDocument[];
609
- };
610
- readonly permissions: IrPermissions;
611
- readonly compaction: IrCompaction;
612
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
613
- readonly failureTaxonomy?: IrFailureTaxonomy;
614
- };
615
-
616
- /**
617
- * Section 22 — CRW (multi-agent crew) IR. One role definition per entry;
618
- * `entry` names the role that runs first; optional `routing` block carries
619
- * either a `match` map (predicate-driven) or `llm` directive (use a model
620
- * to pick the next role) — both lower-time placeholders today, with the
621
- * built-in default-router behaviour preserved when both are absent.
622
- */
623
- export type IrCrewRole = {
624
- readonly name: string;
625
- /** Resolved at lower-time (`role.model ?? crew.model`). */
626
- readonly model: string;
627
- readonly instructions: string;
628
- readonly tools: readonly string[];
629
- readonly toolConfigs: IrToolConfigs;
630
- readonly subAgents: readonly IrSubAgentDefinition[];
631
- };
632
-
633
- export type IrCrewRoutingKind = "match" | "llm";
634
-
635
- export type IrCrewRouting = {
636
- readonly kind: IrCrewRoutingKind;
637
- /**
638
- * Per-role match table. Only set when `kind === "match"`. Keys are
639
- * source role names; values are simple substring matchers tested
640
- * against the source role's terminal output to pick the next role.
641
- */
642
- readonly match?: Readonly<
643
- Record<string, ReadonlyArray<{ readonly contains: string; readonly to: string }>>
644
- >;
645
- };
646
-
647
- export type IrCrewV0 = {
648
- readonly version: 0;
649
- readonly name: string;
650
- readonly target: "crew";
651
- readonly entry: string;
652
- readonly roles: readonly IrCrewRole[];
653
- readonly routing?: IrCrewRouting;
654
- /** Track F (Section 57) — named message schemas referenced by handoffs.
655
- * Absent means no typed handoffs (all `untyped` by default). */
656
- readonly messageSchemas?: readonly IrMessageSchema[];
657
- readonly mcp_servers: IrMcpServers;
658
- readonly permissions: IrPermissions;
659
- readonly compaction: IrCompaction;
660
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
661
- readonly failureTaxonomy?: IrFailureTaxonomy;
662
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
663
- readonly chains?: readonly IrChainBinding[];
664
- readonly wallets?: readonly IrWalletBinding[];
665
- readonly contracts?: readonly IrContractBinding[];
666
- readonly transactionPolicy?: IrTransactionPolicy;
667
- };
668
-
669
- /**
670
- * Section 23 — RES (autonomous research) IR. The compiled daemon
671
- * decomposes `goal` into `branchingFactor` sub-questions, runs each
672
- * branch as a single-turn agent loop, and writes a numbered-citation
673
- * report. The agent in each branch has the standard tool catalog plus
674
- * the auto-injected `Source(uri)` and `CiteFact(uri, snippet, ...)`
675
- * tools from `@crewhaus/crawler` + `@crewhaus/citation-tracker`.
676
- */
677
- export type IrResearchV0 = {
678
- readonly version: 0;
679
- readonly name: string;
680
- readonly target: "research";
681
- readonly agent: {
682
- readonly model: string;
683
- readonly instructions: string;
684
- };
685
- /** Default research goal. The daemon's `--goal "..."` flag overrides. */
686
- readonly goal: string;
687
- /** How many sub-questions the planner decomposes into per run. */
688
- readonly branchingFactor: number;
689
- /** Soft per-run wall-clock cap. The daemon emits `[budget exceeded]` and writes a partial report. */
690
- readonly maxDurationMs: number;
691
- readonly retrieve: {
692
- /** http(s) origins the crawler may fetch. Empty array denies all https. */
693
- readonly allowedOrigins: readonly string[];
694
- /** Absolute file:// roots the crawler may read from. Empty denies all file://. */
695
- readonly allowedFileRoots: readonly string[];
696
- /** Optional vector backend hint for future RAG-augmented research. */
697
- readonly vectorBackend?: IrVectorBackend;
698
- };
699
- readonly tools: readonly string[];
700
- readonly toolConfigs: IrToolConfigs;
701
- readonly mcp_servers: IrMcpServers;
702
- readonly permissions: IrPermissions;
703
- readonly compaction: IrCompaction;
704
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
705
- readonly failureTaxonomy?: IrFailureTaxonomy;
706
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
707
- readonly chains?: readonly IrChainBinding[];
708
- readonly wallets?: readonly IrWalletBinding[];
709
- readonly contracts?: readonly IrContractBinding[];
710
- readonly transactionPolicy?: IrTransactionPolicy;
711
- };
712
-
713
- /**
714
- * Section 23 BATCH — queue-worker IR. The compiled daemon pulls jobs
715
- * from the configured queue, runs the user's handler with `concurrency`
716
- * bounded parallelism, wraps each invocation in an idempotency-key
717
- * cache, and acks/nacks based on outcome. The handler runs the agent
718
- * (single-turn `runChatLoop`) with the job's input as the user message.
719
- */
720
- export type IrBatchQueueAdapter = "in-memory" | "sqs" | "redis-streams" | "postgres";
721
-
722
- export type IrBatchV0 = {
723
- readonly version: 0;
724
- readonly name: string;
725
- readonly target: "batch";
726
- readonly agent: {
727
- readonly model: string;
728
- readonly instructions: string;
729
- };
730
- readonly queue: {
731
- readonly adapter: IrBatchQueueAdapter;
732
- /** Per-domain rate-limit ms; >= 0. */
733
- readonly visibilityTimeoutMs: number;
734
- /** Stop renew sidecar past this; ack/nack by then. */
735
- readonly visibilityRenewIntervalMs?: number;
736
- /** Cap on attempts before DLQ. Default 3. */
737
- readonly maxRetries: number;
738
- /** When `adapter === "in-memory"`, optional seed jobs (mostly tests + smoke). */
739
- readonly seedJobs?: readonly string[];
740
- };
741
- readonly concurrency: number;
742
- readonly idempotencyWindowMs: number;
743
- readonly tools: readonly string[];
744
- readonly toolConfigs: IrToolConfigs;
745
- readonly mcp_servers: IrMcpServers;
746
- readonly permissions: IrPermissions;
747
- readonly compaction: IrCompaction;
748
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
749
- readonly failureTaxonomy?: IrFailureTaxonomy;
750
- /** §47 cross-cutting blockchain subsystem (slice 0). All optional. */
751
- readonly chains?: readonly IrChainBinding[];
752
- readonly wallets?: readonly IrWalletBinding[];
753
- readonly contracts?: readonly IrContractBinding[];
754
- readonly transactionPolicy?: IrTransactionPolicy;
755
- };
756
-
757
- /**
758
- * Section 24 — VOICE (realtime audio agent) IR. The compiled daemon
759
- * opens a realtime adapter (OpenAI Realtime by default), hosts a
760
- * call-session state machine, and runs a barge-in controller over
761
- * inbound audio frames.
762
- */
763
- export type IrVoiceProvider = "openai" | "vapi";
764
- export type IrVoiceTelephony = "twilio" | "livekit-sip" | "in-memory";
765
-
766
- export type IrVoiceV0 = {
767
- readonly version: 0;
768
- readonly name: string;
769
- readonly target: "voice";
770
- readonly agent: {
771
- readonly model: string;
772
- readonly instructions: string;
773
- };
774
- readonly voice: {
775
- readonly provider: IrVoiceProvider;
776
- /** Provider-specific voice id (OpenAI: alloy, echo, …). */
777
- readonly voiceId: string;
778
- /** Server VAD vs caller-driven. v0 defaults to "server". */
779
- readonly vad: "server" | "none";
780
- /** Barge-in trigger frame count (consecutive speech frames). */
781
- readonly bargeInTriggerFrames: number;
782
- /** Barge-in window ms — sliding window for the trigger count. */
783
- readonly bargeInWindowMs: number;
784
- };
785
- /** Optional telephony adapter wiring (Twilio, LiveKit, in-memory for the smoke). */
786
- readonly telephony?: {
787
- readonly provider: IrVoiceTelephony;
788
- };
789
- readonly tools: readonly string[];
790
- readonly toolConfigs: IrToolConfigs;
791
- readonly mcp_servers: IrMcpServers;
792
- readonly permissions: IrPermissions;
793
- readonly compaction: IrCompaction;
794
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
795
- readonly failureTaxonomy?: IrFailureTaxonomy;
796
- };
797
-
798
- /**
799
- * Section 25 — BROW (computer-use / browser driver) IR. The compiled
800
- * daemon launches a chromium driver, registers Screenshot + Click /
801
- * Type / Key / Scroll + FindElement tools, optionally navigates to
802
- * `startUrl`, and runs `runChatLoop` against the user's prompt.
803
- */
804
- export type IrBrowserBackend = "host" | "chromium" | "remote";
805
-
806
- export type IrBrowserV0 = {
807
- readonly version: 0;
808
- readonly name: string;
809
- readonly target: "browser";
810
- readonly agent: {
811
- readonly model: string;
812
- readonly instructions: string;
813
- };
814
- readonly driver: {
815
- readonly backend: IrBrowserBackend;
816
- readonly viewport: {
817
- readonly width: number;
818
- readonly height: number;
819
- };
820
- /** Optional initial URL; daemon calls driver.goto() before runChatLoop. */
821
- readonly startUrl?: string;
822
- };
823
- /** Vision-grounding model. Defaults at lower-time to agent.model. */
824
- readonly groundingModel: string;
825
- readonly tools: readonly string[];
826
- readonly toolConfigs: IrToolConfigs;
827
- readonly mcp_servers: IrMcpServers;
828
- readonly permissions: IrPermissions;
829
- readonly compaction: IrCompaction;
830
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
831
- readonly failureTaxonomy?: IrFailureTaxonomy;
832
- };
833
-
834
- /** Discriminated union over every supported target IR. */
835
- /**
836
- * Section 29 — IR for the EVAL target shape. Lowered from the spec's
837
- * dataset/graders/concurrency/seed; codegen writes a single-file
838
- * `agent.ts` that boots dataset-registry + grader-registry + eval-runner.
839
- */
840
- export type IrEvalV0 = {
841
- readonly version: 0;
842
- readonly name: string;
843
- readonly target: "eval";
844
- readonly agent: {
845
- readonly model: string;
846
- readonly instructions: string;
847
- readonly tools: readonly string[];
848
- };
849
- readonly dataset: {
850
- readonly name: string;
851
- readonly version: string;
852
- readonly split: "train" | "dev" | "test";
853
- };
854
- readonly graders: readonly {
855
- readonly name: string;
856
- readonly opts?: Readonly<Record<string, unknown>>;
857
- }[];
858
- readonly concurrency: number;
859
- readonly seed?: number;
860
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
861
- readonly failureTaxonomy?: IrFailureTaxonomy;
862
- };
863
-
864
- /**
865
- * Section 47 — `onchain` daemon trigger. The compiled daemon listens
866
- * for one of three trigger kinds and runs one agent turn per inbound
867
- * event:
868
- * - `event`: subscribe to a contract event (topic[0] = keccak of the
869
- * event signature). The daemon decodes the event using the
870
- * declared contract ABI and threads the decoded payload into the
871
- * agent's user message.
872
- * - `block`: scan new blocks at `scanIntervalMs` cadence, running
873
- * the agent against block-level summaries. Used by treasury
874
- * monitors and reorg detectors.
875
- * - `address`: watch transfers/calls to or from a watched address.
876
- * `direction` ("in" | "out" | "both") filters which side of the
877
- * transfer fires the trigger.
878
- */
879
- export type IrChainTrigger =
880
- | {
881
- readonly kind: "event";
882
- readonly chainId: string;
883
- readonly contract: string;
884
- readonly event: string;
885
- readonly filter?: Readonly<Record<string, unknown>>;
886
- }
887
- | {
888
- readonly kind: "block";
889
- readonly chainId: string;
890
- readonly scanIntervalMs: number;
891
- }
892
- | {
893
- readonly kind: "address";
894
- readonly chainId: string;
895
- readonly address: string;
896
- readonly direction: "in" | "out" | "both";
897
- };
898
-
899
- /**
900
- * Section 47 — IR for the `onchain` target shape. The compiled daemon
901
- * subscribes to the configured triggers, dedupes events by `(txHash,
902
- * logIndex)` within `idempotencyWindowMs`, and runs one
903
- * `runChatLoop({singleTurn: true})` per inbound trigger with the
904
- * decoded payload as the user message. The agent has access to the
905
- * standard tool catalog (including §47 `tool-evm` + `tool-evm-tx`) so
906
- * it can respond with transactions, alerts, or notifications.
907
- */
908
- export type IrChainV0 = {
909
- readonly version: 0;
910
- readonly name: string;
911
- readonly target: "onchain";
912
- readonly agent: {
913
- readonly model: string;
914
- readonly instructions: string;
915
- };
916
- readonly chains: readonly IrChainBinding[];
917
- readonly wallets: readonly IrWalletBinding[];
918
- readonly contracts: readonly IrContractBinding[];
919
- readonly transactionPolicy: IrTransactionPolicy;
920
- readonly triggers: readonly IrChainTrigger[];
921
- /** Dedup window for `(txHash, logIndex)` (or block height for block triggers). */
922
- readonly idempotencyWindowMs: number;
923
- readonly tools: readonly string[];
924
- readonly toolConfigs: IrToolConfigs;
925
- readonly mcp_servers: IrMcpServers;
926
- readonly permissions: IrPermissions;
927
- readonly compaction: IrCompaction;
928
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
929
- readonly failureTaxonomy?: IrFailureTaxonomy;
930
- };
931
-
932
- /**
933
- * Section 47 — IR for the `onchain-game` target. Models a perceive-act
934
- * loop against a game contract: the daemon reads game state via the
935
- * configured `stateReader` view function, runs the agent to propose a
936
- * move, broadcasts the move as a transaction, waits for confirmation,
937
- * and re-reads the new state. Closest analogues are `voice` (realtime
938
- * perceive-act loop with barge-in) and `browser` (perceive-act loop
939
- * with vision grounding). The chain-specific concerns are turn
940
- * semantics (sync/realtime/async) and move-confirmation finality.
941
- */
942
- export type IrChainGameTurnSemantics = "turn-based" | "real-time" | "async";
943
-
944
- export type IrChainGameV0 = {
945
- readonly version: 0;
946
- readonly name: string;
947
- readonly target: "onchain-game";
948
- readonly agent: {
949
- readonly model: string;
950
- readonly instructions: string;
951
- };
952
- /** Games are bound to one chain at a time; multi-chain games are rare. */
953
- readonly chain: IrChainBinding;
954
- /** Single player wallet. */
955
- readonly wallet: IrWalletBinding;
956
- readonly game: {
957
- /** Game contract binding. */
958
- readonly contract: IrContractBinding;
959
- /** ABI method name for reading the full game state (a view fn). */
960
- readonly stateReader: string;
961
- /** Optional separate actions contract; defaults to game.contract. */
962
- readonly actionsContract?: string;
963
- readonly turnSemantics: IrChainGameTurnSemantics;
964
- /** Hard cap on a move's wall-clock spend for real-time games. */
965
- readonly moveTimeoutMs?: number;
966
- /** Natural-language win condition the model uses to evaluate state. */
967
- readonly objective?: string;
968
- };
969
- readonly transactionPolicy: IrTransactionPolicy;
970
- readonly tools: readonly string[];
971
- readonly toolConfigs: IrToolConfigs;
972
- readonly mcp_servers: IrMcpServers;
973
- readonly permissions: IrPermissions;
974
- readonly compaction: IrCompaction;
975
- /** Section 55 (Track A) — named failure taxonomy. Optional. */
976
- readonly failureTaxonomy?: IrFailureTaxonomy;
977
- };
978
-
979
- export type IrNode =
980
- | IrV0
981
- | IrWorkflowV0
982
- | IrChannelV0
983
- | IrGraphV0
984
- | IrManagedV0
985
- | IrPipelineV0
986
- | IrCrewV0
987
- | IrResearchV0
988
- | IrBatchV0
989
- | IrVoiceV0
990
- | IrBrowserV0
991
- | IrEvalV0
992
- | IrChainV0
993
- | IrChainGameV0;
994
-
995
- /**
996
- * The output of compilation: a set of files to be written to disk by the
997
- * bundle-packager (slice: written directly by the CLI app).
998
- */
999
- export type Bundle = {
1000
- readonly files: ReadonlyArray<{
1001
- readonly path: string;
1002
- readonly content: string;
1003
- }>;
1004
- };