@hilbras/omninode 1.0.0 → 2.0.0-alpha.10

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
@@ -1,29 +1,75 @@
1
1
  import { z } from 'zod';
2
+ import { ChildProcess } from 'node:child_process';
2
3
 
3
4
  /** Structured report format so reports can be processed programmatically (§16). */
4
5
  type Confidence = "low" | "medium" | "high";
5
6
  type FindingSeverity = "info" | "low" | "medium" | "high" | "critical";
7
+ /** Typed evidence (roadmap §13, Evidence). Plain strings remain accepted
8
+ * and normalize to `observation` evidence. */
9
+ type EvidenceKind = "file" | "line" | "url" | "command" | "observation" | "artifact";
10
+ interface Evidence {
11
+ kind: EvidenceKind;
12
+ /** Path, URL, command or logical reference. */
13
+ ref?: string;
14
+ /** Line number for file/line evidence. */
15
+ line?: number;
16
+ /** Verbatim excerpt backing the finding. */
17
+ excerpt?: string;
18
+ /** Agent that produced the evidence. */
19
+ agent?: string;
20
+ }
21
+ type EvidenceInput = string | Evidence;
22
+ /** Artifact produced alongside a report (§13). */
23
+ interface ReportArtifact {
24
+ kind: "file" | "patch" | "log" | "screenshot" | "document" | "data";
25
+ ref: string;
26
+ description?: string;
27
+ mediaType?: string;
28
+ bytes?: number;
29
+ }
30
+ /** Where a finding came from, when known. */
31
+ interface FindingOrigin {
32
+ agent?: string;
33
+ reportId?: string;
34
+ pipelineRunId?: string;
35
+ }
6
36
  interface Finding {
7
37
  id: string;
8
38
  title: string;
39
+ /** v1 field, kept for compatibility; `description` is the v2 field. */
9
40
  detail: string;
41
+ /** Full description of the finding (§13, Findings). */
42
+ description?: string;
10
43
  severity?: FindingSeverity;
11
- evidence?: string[];
44
+ confidence?: Confidence;
45
+ evidence?: EvidenceInput[];
12
46
  /** File path or conceptual location the finding refers to. */
13
47
  location?: string;
14
48
  tags?: string[];
49
+ /** Provenance of the finding, when known (§13). */
50
+ source?: FindingOrigin;
51
+ /** The concrete fix this finding implies. */
52
+ recommendation?: string;
15
53
  }
16
54
  interface Report {
17
55
  id: string;
18
56
  taskId: string;
19
57
  /** Agent name from the agent registry. */
20
58
  agent: string;
59
+ /** v2 spelling of `agent` for machine consumers (§13). */
60
+ agentId?: string;
61
+ /** Pipeline run that produced this report, when applicable. */
62
+ pipelineRunId?: string;
21
63
  /** Model id used, if known. */
22
64
  model?: string;
23
65
  summary: string;
24
66
  findings: Finding[];
25
67
  recommendations: string[];
26
68
  confidence?: Confidence;
69
+ /** Report-level evidence backing the summary. */
70
+ evidence?: EvidenceInput[];
71
+ /** Artifacts produced with the report (§13, Artifacts). */
72
+ artifacts?: ReportArtifact[];
27
73
  createdAt: string;
28
74
  metadata?: Record<string, unknown>;
29
75
  }
@@ -41,7 +87,31 @@ interface AggregatedFinding {
41
87
  occurrences: number;
42
88
  /** Highest severity seen across merged duplicates. */
43
89
  severity?: FindingSeverity;
44
- evidence: string[];
90
+ /** Highest confidence seen across merged duplicates (§14 — confidence preservation). */
91
+ confidence?: Confidence;
92
+ /** Per-agent severity, so a disagreement is visible rather than flattened. */
93
+ severityBySource?: Record<string, FindingSeverity>;
94
+ /** Per-agent confidence. */
95
+ confidenceBySource?: Record<string, Confidence>;
96
+ /** Distinct recommendations attached to this finding across reports. */
97
+ recommendations?: string[];
98
+ /** Typed evidence, normalized from strings when reports were ingested. */
99
+ evidence: Evidence[];
100
+ }
101
+ /** One agent's position on a disputed finding (§14, Conflicts). */
102
+ interface ConflictPosition {
103
+ agent: string;
104
+ reportId: string;
105
+ severity?: FindingSeverity;
106
+ confidence?: Confidence;
107
+ recommendation?: string;
108
+ }
109
+ interface ReportConflict {
110
+ type: "severity" | "recommendation";
111
+ findingTitle: string;
112
+ /** Both positions are preserved — OmniNode never silently chooses one. */
113
+ positions: ConflictPosition[];
114
+ note: string;
45
115
  }
46
116
  interface AggregatedRecommendation {
47
117
  text: string;
@@ -57,6 +127,10 @@ interface CombinedReport {
57
127
  taskIds: string[];
58
128
  summary: string;
59
129
  findings: AggregatedFinding[];
130
+ /** Findings multiple agents reported with the same severity (consensus). */
131
+ agreements: AggregatedFinding[];
132
+ /** Disagreements between agents (§14) — both positions preserved. */
133
+ conflicts: ReportConflict[];
60
134
  recommendations: AggregatedRecommendation[];
61
135
  /** Distinct agent names that contributed. */
62
136
  sources: string[];
@@ -65,6 +139,99 @@ interface CombinedReport {
65
139
  metadata?: Record<string, unknown>;
66
140
  }
67
141
 
142
+ /**
143
+ * OmniNode Agent Protocol v2 — message model (roadmap §7.2–§7.4, §7.7).
144
+ *
145
+ * Every message is a JSON line carrying a `ProtocolEnvelope`. All ids are
146
+ * optional for inbound tolerance but OmniNode always emits them, so every
147
+ * message is traceable to agent / task / pipeline / execution / request.
148
+ */
149
+
150
+ /** Messages OmniNode sends to an agent. */
151
+ type ProtocolNodeToAgentType = "TASK" | "HELLO_ACK" | "CONTEXT" | "INSTRUCTION" | "RESPONSE" | "CANCEL";
152
+ /** Messages an agent sends to OmniNode. */
153
+ type ProtocolAgentToNodeType = "HELLO" | "TASK_REQUEST" | "TASK_ACCEPTED" | "TASK_STARTED" | "STATUS" | "QUESTION" | "REPORT" | "ARTIFACT" | "COMPLETION" | "ERROR" | "CANCELLED";
154
+ type ProtocolMessageType = ProtocolNodeToAgentType | ProtocolAgentToNodeType;
155
+ interface ProtocolEnvelope<T extends ProtocolMessageType = ProtocolMessageType> {
156
+ /** `omninode-agent-protocol/2`. Inbound messages without it are treated as v1. */
157
+ protocol: string;
158
+ /** Unique id of this message. */
159
+ messageId: string;
160
+ /** Id of the request/thread this message belongs to. */
161
+ requestId?: string;
162
+ taskId?: string;
163
+ agentId?: string;
164
+ pipelineId?: string;
165
+ /** Execution identity (roadmap §6.5) — ties the message to one attempt. */
166
+ executionId?: string;
167
+ timestamp: string;
168
+ type: T;
169
+ payload: unknown;
170
+ metadata?: Record<string, unknown>;
171
+ }
172
+ /** Standard artifact kinds (roadmap §7.7). */
173
+ type ArtifactKind = "file" | "patch" | "report" | "log" | "screenshot" | "document" | "data";
174
+ interface ArtifactPayload {
175
+ kind: ArtifactKind;
176
+ /** Path, URL or logical name. */
177
+ ref: string;
178
+ description?: string;
179
+ mediaType?: string;
180
+ bytes?: number;
181
+ metadata?: Record<string, unknown>;
182
+ }
183
+ interface QuestionPayload {
184
+ /** Question id to answer. */
185
+ questionId: string;
186
+ question: string;
187
+ /** What kind of answer is expected (free text, file path, options…). */
188
+ expected?: "text" | "path" | "choice";
189
+ options?: string[];
190
+ }
191
+ interface TaskPayload {
192
+ taskId: string;
193
+ objective: string;
194
+ }
195
+ interface ReportPayload {
196
+ report: Report | Report[];
197
+ }
198
+ /** A question an agent asked during a run, with the answer OmniNode gave (if any). */
199
+ interface AskedQuestion {
200
+ questionId: string;
201
+ question: string;
202
+ answer?: string;
203
+ }
204
+ declare function newMessageId(prefix?: string): string;
205
+ /** Builds a v2 envelope with ids and timestamp filled in. */
206
+ declare function envelope<T extends ProtocolMessageType>(type: T, payload: unknown, ids?: {
207
+ requestId?: string;
208
+ taskId?: string;
209
+ agentId?: string;
210
+ pipelineId?: string;
211
+ executionId?: string;
212
+ metadata?: Record<string, unknown>;
213
+ }): ProtocolEnvelope<T>;
214
+
215
+ interface AgentDescriptor {
216
+ /** Protocol the agent speaks. */
217
+ protocol: string;
218
+ name: string;
219
+ version?: string;
220
+ capabilities: string[];
221
+ /** Message types the agent can emit. */
222
+ supports: string[];
223
+ }
224
+ type HelloResult = {
225
+ ok: true;
226
+ descriptor: AgentDescriptor;
227
+ } | {
228
+ ok: false;
229
+ reason: string;
230
+ };
231
+ declare function parseHello(envelopeValue: ProtocolEnvelope): HelloResult;
232
+ declare function buildHello(descriptor: Omit<AgentDescriptor, "protocol">): ProtocolEnvelope<"HELLO">;
233
+ declare function buildHelloAck(descriptor: AgentDescriptor): ProtocolEnvelope<"HELLO_ACK">;
234
+
68
235
  /** Role system: what an AI is supposed to do, independent of any provider (§11). */
69
236
  interface RoleDefinition {
70
237
  /** Slug identifier, e.g. "architecture-reviewer". */
@@ -98,8 +265,21 @@ interface AgentConfig {
98
265
  inputMode?: AgentInputMode;
99
266
  /** Per-task timeout in milliseconds; the process is killed when exceeded. */
100
267
  timeoutMs?: number;
101
- /** When false, the agent process starts with a minimal environment (PATH + env). */
268
+ /**
269
+ * When false, the agent process starts with a minimal environment (PATH +
270
+ * env). Deprecated in v2 — prefer `envPolicy`.
271
+ */
102
272
  inheritEnv?: boolean;
273
+ /** Explicit environment policy (roadmap §8). */
274
+ envPolicy?: "inherit" | "allowlist" | "denylist" | "explicit";
275
+ /** Variables forwarded from the parent under the `allowlist` policy. */
276
+ envAllowlist?: string[];
277
+ /** Variables removed from the parent under the `denylist` policy. */
278
+ envDenylist?: string[];
279
+ /** Per-stream byte budget for agent stdout/stderr (default 5 MiB). */
280
+ maxOutputBytes?: number;
281
+ /** Allow a working directory outside the project root. */
282
+ allowExternalCwd?: boolean;
103
283
  /** Models (as "provider:model-id") this agent may use, if restricted. */
104
284
  allowedModels?: string[];
105
285
  metadata?: Record<string, unknown>;
@@ -117,6 +297,10 @@ interface AgentInfo {
117
297
  interface AgentTaskInput {
118
298
  taskId: string;
119
299
  objective: string;
300
+ /** Pipeline run that owns this task (protocol correlation, §7.4). */
301
+ pipelineId?: string;
302
+ /** Execution identity for this attempt (protocol correlation, §7.4). */
303
+ executionId?: string;
120
304
  role?: RoleDefinition;
121
305
  /** Assembled task context (project, memory, files) already selected for this agent. */
122
306
  context?: string;
@@ -132,6 +316,14 @@ interface AgentTaskOutput {
132
316
  logs?: string[];
133
317
  /** Structured reports extracted from protocol-mode runs (§16, §21). */
134
318
  reports?: Report[];
319
+ /** Protocol diagnostics for protocol-mode runs (roadmap §7): questions asked, violations seen. */
320
+ protocol?: {
321
+ protocol: string;
322
+ legacy: boolean;
323
+ descriptor?: AgentDescriptor;
324
+ questions: AskedQuestion[];
325
+ violations: string[];
326
+ };
135
327
  error?: string;
136
328
  }
137
329
  /** Contract every agent adapter implements (Phase 3+). */
@@ -172,32 +364,78 @@ interface ChatResponse {
172
364
  /** Verbatim provider response body for advanced consumers. */
173
365
  raw?: unknown;
174
366
  }
367
+ /**
368
+ * Model-backed chat used by the planner layer. Lives in the neutral types
369
+ * layer so adapters (e.g. planner) never depend on engine modules.
370
+ */
371
+ type ChatFn = (model: string, messages: ChatMessage[]) => Promise<string>;
372
+ /** One streamed chunk (SSE deltas from OpenAI-compatible gateways). */
373
+ interface ChatStreamChunk {
374
+ /** Text delta (empty for role-only or final chunks). */
375
+ delta: string;
376
+ /** Provider-reported finish reason, on the final chunk. */
377
+ finishReason?: string;
378
+ raw?: unknown;
379
+ }
175
380
 
176
381
  /**
177
- * Memory abstraction. Remembera is the preferred Hilbras integration, but the
178
- * core depends only on this interface (memory-agnostic principle, §2, §19).
382
+ * Memory abstraction (§19). Remembera is the preferred implementation, but
383
+ * the core depends only on this interface (memory-agnostic principle, §2).
384
+ *
385
+ * v2 contract (roadmap §12): retrieve / store / search / metadata, across
386
+ * project / task / role scopes with structured categories.
179
387
  */
180
- type MemoryScope = "project" | "role" | "task" | "knowledge";
388
+ type MemoryScope = "project" | "task" | "role" | "knowledge";
389
+ /** Structured memory categories (roadmap §12, Memory Categories). */
390
+ type MemoryCategory = "project" | "architecture" | "decisions" | "tasks" | "problems" | "solutions" | "conventions" | "agent_reports";
181
391
  interface MemoryEntry {
182
392
  key: string;
183
393
  scope: MemoryScope;
184
394
  content: string;
395
+ /** Structured category, when the backend supports it. */
396
+ category?: MemoryCategory;
185
397
  tags?: string[];
186
398
  createdAt?: string;
187
399
  updatedAt?: string;
188
400
  metadata?: Record<string, unknown>;
189
401
  }
190
402
  interface MemoryQuery {
403
+ /** Free-text relevance query. */
404
+ text?: string;
191
405
  scope?: MemoryScope;
406
+ category?: MemoryCategory;
192
407
  tags?: string[];
193
- /** Free-text relevance query; implementations decide ranking. */
194
- text?: string;
195
408
  limit?: number;
196
409
  }
410
+ interface MemoryProviderMetadata {
411
+ name: string;
412
+ /** What the backend can do, so callers can adapt (e.g. no category support). */
413
+ capabilities: Array<"retrieve" | "store" | "search" | "categories" | "tags">;
414
+ /** True when the backend enforces relevance ranking itself. */
415
+ relevanceRanking: boolean;
416
+ /** Backend-specific info (gateway version, endpoint type…). */
417
+ backend?: Record<string, unknown>;
418
+ }
419
+ /**
420
+ * The memory contract. `query`/`write` are the v1 names, kept as aliases so
421
+ * existing integrations keep working — new code should use retrieve/store.
422
+ */
197
423
  interface IMemoryProvider {
198
424
  readonly name: string;
199
- /** Retrieve relevant memory; only relevant context should reach a task (§20). */
425
+ /** Retrieve entries relevant to a query (task-oriented). */
426
+ retrieve(query: MemoryQuery): Promise<MemoryEntry[]>;
427
+ /** Store an entry (upsert by key). */
428
+ store(entry: MemoryEntry): Promise<void>;
429
+ /** Free-text search across scopes. */
430
+ search(text: string, options?: {
431
+ limit?: number;
432
+ scope?: MemoryScope;
433
+ }): Promise<MemoryEntry[]>;
434
+ /** Provider capabilities (contract introspection). */
435
+ metadata(): MemoryProviderMetadata;
436
+ /** @deprecated v1 alias of {@link retrieve}. */
200
437
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
438
+ /** @deprecated v1 alias of {@link store}. */
201
439
  write(entry: MemoryEntry): Promise<void>;
202
440
  }
203
441
 
@@ -210,21 +448,52 @@ interface ModelCapabilities {
210
448
  embeddings?: boolean;
211
449
  }
212
450
  type ModelStatus = "available" | "unavailable" | "deprecated";
451
+ type Modality = "text" | "image" | "audio" | "video" | "embedding";
452
+ /** Model metadata (roadmap §10, Model Metadata). */
213
453
  interface ModelInfo {
214
454
  /** Name of the provider this model belongs to. */
215
455
  provider: string;
216
456
  /** Provider-specific model identifier, e.g. "qwen3-coder". */
217
457
  id: string;
218
458
  displayName?: string;
459
+ /** Human-readable model name reported by the provider, when available. */
460
+ name?: string;
219
461
  capabilities?: ModelCapabilities;
220
462
  contextWindow?: number;
463
+ inputTypes?: Modality[];
464
+ outputTypes?: Modality[];
465
+ supportsTools?: boolean;
466
+ supportsVision?: boolean;
467
+ supportsReasoning?: boolean;
468
+ supportsStructuredOutput?: boolean;
469
+ supportsStreaming?: boolean;
221
470
  status?: ModelStatus;
222
471
  metadata?: Record<string, unknown>;
223
472
  }
224
473
 
225
474
  /** Task system: every operation becomes a Task (§13). */
226
475
 
227
- type TaskStatus = "created" | "queued" | "running" | "waiting" | "completed" | "failed" | "cancelled";
476
+ /**
477
+ * Execution states (v2 Phase 2, roadmap §6.1).
478
+ *
479
+ * The crucial distinction: `unknown` means "we cannot prove the outcome" —
480
+ * e.g. a process timeout after the agent may already have performed side
481
+ * effects. It is deliberately NOT `failed`: retrying blindly could duplicate
482
+ * work, and reporting failure would be a lie. Resolve it explicitly with
483
+ * `task retry` (which starts a fresh execution) or by inspecting artifacts.
484
+ */
485
+ type TaskStatus = "created" | "queued" | "running" | "waiting" | "completed" | "failed" | "timed_out" | "cancelled" | "unknown" | "partially_completed";
486
+ /** States from which no further automatic transition happens. */
487
+ declare const TERMINAL_TASK_STATUSES: readonly TaskStatus[];
488
+ /** One execution attempt (roadmap §6.5 identity: task + attempt + execution id). */
489
+ interface ExecutionRecord {
490
+ executionId: string;
491
+ attempt: number;
492
+ startedAt: string;
493
+ finishedAt: string;
494
+ outcome: "completed" | "failed" | "timed_out" | "unknown" | "cancelled";
495
+ error?: string;
496
+ }
228
497
  interface TaskContext {
229
498
  project?: string;
230
499
  /** Paths or globs relevant to the task. */
@@ -257,6 +526,12 @@ interface Task {
257
526
  status: TaskStatus;
258
527
  createdAt: string;
259
528
  updatedAt: string;
529
+ /** Number of engine.run attempts so far (0 = never executed). */
530
+ attempt: number;
531
+ /** Error from the most recent failed/unknown attempt. */
532
+ lastError?: string;
533
+ /** Recent execution attempts, newest last, bounded in length. */
534
+ executions?: ExecutionRecord[];
260
535
  result?: TaskResult;
261
536
  }
262
537
 
@@ -287,19 +562,43 @@ interface PipelineDefinition {
287
562
  role?: string;
288
563
  steps: PipelineStep[];
289
564
  }
290
- type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
565
+ /**
566
+ * Run status. "partial" means the run finished but some step outcome was
567
+ * incomplete or unprovable (partial fan-out, unknown task state) — the
568
+ * authoritative detail always lives in `stepRuns`/`taskRuns`.
569
+ */
570
+ type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "partial" | "cancelled";
571
+ /**
572
+ * One step execution inside a run (§9.1 — Step Run is NOT the Step).
573
+ */
291
574
  interface PipelineStepRun {
292
575
  stepId: string;
293
576
  status: TaskStatus;
294
577
  /** Tasks created for this step (research fans out to several). */
295
578
  taskIds?: string[];
579
+ /** Execution ids of the tasks this step created, for correlation (§6.5). */
580
+ executionIds?: string[];
581
+ /** Which attempt of this step produced this record (1 = first try). */
582
+ attempt?: number;
296
583
  /** Set on plan steps that produced a stored plan (§18). */
297
584
  planId?: string;
298
585
  error?: string;
299
586
  }
587
+ /** One execution attempt of a run (§9.1 — Attempt is not the Run). */
588
+ interface PipelineRunAttempt {
589
+ attempt: number;
590
+ startedAt: string;
591
+ finishedAt?: string;
592
+ status: PipelineRunStatus;
593
+ }
300
594
  interface PipelineRun {
301
595
  id: string;
302
596
  pipelineId: string;
597
+ /** Execution attempt counter: retries of the same run increment it. */
598
+ attempt: number;
599
+ /** Set when cancellation was requested; the run stops at the next check point. */
600
+ cancellationRequested?: boolean;
601
+ cancellationRequestedAt?: string;
303
602
  /** The objective this run is executing (persisted for retries). */
304
603
  objective?: string;
305
604
  status: PipelineRunStatus;
@@ -314,6 +613,28 @@ interface PipelineRun {
314
613
  planId?: string;
315
614
  /** Outcome summary of the final executed step (§28 — Result). */
316
615
  resultSummary?: string;
616
+ /** Per-attempt history (§9.1). */
617
+ attempts?: PipelineRunAttempt[];
618
+ }
619
+ /**
620
+ * Executor contract (roadmap §9.1 / §9.2): a Pipeline definition, a Run of
621
+ * it, Steps, Step Runs and Attempts are distinct concepts; this interface is
622
+ * what orchestration code depends on.
623
+ */
624
+ interface IPipelineExecutor {
625
+ validate(definition: PipelineDefinition): void;
626
+ run(definition: PipelineDefinition, options?: PipelineRunOptions): Promise<PipelineRun>;
627
+ cancel(runId: string): Promise<void>;
628
+ get(runId: string): Promise<PipelineRun | undefined>;
629
+ listRuns(filter?: {
630
+ pipelineId?: string;
631
+ }): Promise<PipelineRun[]>;
632
+ }
633
+ interface PipelineRunOptions {
634
+ objective?: string;
635
+ onStep?: (stepRun: PipelineStepRun) => void;
636
+ /** Total run attempts (1 = no automatic rerun of the whole run). */
637
+ maxAttempts?: number;
317
638
  }
318
639
 
319
640
  /** Plan types: the final implementation plan produced by the planner layer (§18). */
@@ -454,7 +775,20 @@ interface Project {
454
775
 
455
776
  type ProviderType = "openai-compatible" | "omnihilbras" | "openrouter" | "local" | "custom";
456
777
  type ProviderHealth = "unknown" | "healthy" | "degraded" | "unreachable";
778
+ /** Declared provider capabilities (roadmap §10, Provider Interface). */
779
+ type ProviderCapability = "chat" | "models" | "streaming" | "tools" | "embeddings" | "vision";
780
+ /** Normalized authentication description — never contains a secret value. */
781
+ interface ProviderAuthentication {
782
+ /** How the provider authenticates. */
783
+ method: "bearer" | "none" | "custom";
784
+ /** Environment variable that holds the credential, if any. */
785
+ envVar?: string;
786
+ /** True when the referenced variable is currently set. */
787
+ configured: boolean;
788
+ }
457
789
  interface ProviderConfig {
790
+ /** Stable identifier used in records and references (defaults to `name`). */
791
+ providerId?: string;
458
792
  /** Unique name used in project configuration and the model registry. */
459
793
  name: string;
460
794
  type: ProviderType;
@@ -465,6 +799,10 @@ interface ProviderConfig {
465
799
  */
466
800
  apiKeyEnvVar?: string;
467
801
  headers?: Record<string, string>;
802
+ /** Provider-level request timeout in ms (distinct from agent/pipeline budgets). */
803
+ timeoutMs?: number;
804
+ /** Capabilities declared for this provider (discovered ones are merged in). */
805
+ capabilities?: ProviderCapability[];
468
806
  enabled?: boolean;
469
807
  metadata?: Record<string, unknown>;
470
808
  }
@@ -478,17 +816,33 @@ interface ProviderStatus {
478
816
  lastCheckedAt?: string;
479
817
  message?: string;
480
818
  }
481
- /** Contract every provider adapter implements (Phase 1+). */
819
+ /** Contract every provider adapter implements (roadmap §10). */
482
820
  interface IProvider {
483
821
  readonly config: ProviderConfig;
822
+ /** Stable identifier of this provider. */
823
+ readonly providerId: string;
824
+ /** Normalized authentication description (no secret values). */
825
+ readonly authentication: ProviderAuthentication;
826
+ /**
827
+ * Connect: authenticate and discover models (roadmap §10, Model Discovery).
828
+ * Returns the discovered models.
829
+ */
830
+ connect(): Promise<ModelInfo[]>;
484
831
  /** Discover models exposed by this provider. */
485
832
  listModels(): Promise<ModelInfo[]>;
833
+ /** Fetch a single model's metadata (from discovery; re-discovers if unknown). */
834
+ getModel(modelId: string): Promise<ModelInfo | undefined>;
486
835
  /** Check connectivity and authentication. */
487
836
  healthCheck(): Promise<ProviderStatus>;
488
837
  }
489
838
  /** Contract for providers that can run chat completions (foundation for planning). */
490
839
  interface IChatProvider extends IProvider {
491
840
  chat(request: ChatRequest): Promise<ChatResponse>;
841
+ /**
842
+ * Stream a completion where the provider supports it (§11). Chunks are
843
+ * delivered in order; the resolved ChatResponse carries the assembled text.
844
+ */
845
+ stream?(request: ChatRequest, onChunk: (chunk: ChatStreamChunk) => void): Promise<ChatResponse>;
492
846
  }
493
847
 
494
848
  /** Typed error hierarchy shared across the whole codebase (§4.1 — error model). */
@@ -573,6 +927,7 @@ declare const providerConfigSchema: z.ZodObject<{
573
927
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
574
928
  base_url: z.ZodString;
575
929
  api_key_env_var: z.ZodOptional<z.ZodString>;
930
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
576
931
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
577
932
  enabled: z.ZodOptional<z.ZodBoolean>;
578
933
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -580,18 +935,20 @@ declare const providerConfigSchema: z.ZodObject<{
580
935
  name: string;
581
936
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
582
937
  base_url: string;
938
+ metadata?: Record<string, unknown> | undefined;
583
939
  api_key_env_var?: string | undefined;
940
+ timeout_ms?: number | undefined;
584
941
  headers?: Record<string, string> | undefined;
585
942
  enabled?: boolean | undefined;
586
- metadata?: Record<string, unknown> | undefined;
587
943
  }, {
588
944
  name: string;
589
945
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
590
946
  base_url: string;
947
+ metadata?: Record<string, unknown> | undefined;
591
948
  api_key_env_var?: string | undefined;
949
+ timeout_ms?: number | undefined;
592
950
  headers?: Record<string, string> | undefined;
593
951
  enabled?: boolean | undefined;
594
- metadata?: Record<string, unknown> | undefined;
595
952
  }>;
596
953
  declare const agentConfigSchema: z.ZodObject<{
597
954
  name: z.ZodString;
@@ -604,29 +961,44 @@ declare const agentConfigSchema: z.ZodObject<{
604
961
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
605
962
  timeout_ms: z.ZodOptional<z.ZodNumber>;
606
963
  inherit_env: z.ZodOptional<z.ZodBoolean>;
964
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
965
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
966
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
967
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
968
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
607
969
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
608
970
  }, "strict", z.ZodTypeAny, {
609
971
  name: string;
610
972
  type: "native" | "process" | "cli";
611
- input_mode: "stdin" | "arg" | "protocol";
612
- metadata?: Record<string, unknown> | undefined;
973
+ input_mode: "protocol" | "stdin" | "arg";
613
974
  command?: string | undefined;
975
+ metadata?: Record<string, unknown> | undefined;
976
+ timeout_ms?: number | undefined;
614
977
  args?: string[] | undefined;
615
978
  cwd?: string | undefined;
616
979
  env?: Record<string, string> | undefined;
617
- timeout_ms?: number | undefined;
618
980
  inherit_env?: boolean | undefined;
981
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
982
+ env_allowlist?: string[] | undefined;
983
+ env_denylist?: string[] | undefined;
984
+ max_output_bytes?: number | undefined;
985
+ allow_external_cwd?: boolean | undefined;
619
986
  }, {
620
987
  name: string;
621
- type?: "native" | "process" | "cli" | undefined;
622
- metadata?: Record<string, unknown> | undefined;
623
988
  command?: string | undefined;
989
+ metadata?: Record<string, unknown> | undefined;
990
+ type?: "native" | "process" | "cli" | undefined;
991
+ timeout_ms?: number | undefined;
624
992
  args?: string[] | undefined;
625
993
  cwd?: string | undefined;
626
994
  env?: Record<string, string> | undefined;
627
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
628
- timeout_ms?: number | undefined;
995
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
629
996
  inherit_env?: boolean | undefined;
997
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
998
+ env_allowlist?: string[] | undefined;
999
+ env_denylist?: string[] | undefined;
1000
+ max_output_bytes?: number | undefined;
1001
+ allow_external_cwd?: boolean | undefined;
630
1002
  }>;
631
1003
  declare const roleConfigSchema: z.ZodObject<{
632
1004
  id: z.ZodString;
@@ -729,8 +1101,8 @@ declare const pipelineConfigSchema: z.ZodObject<{
729
1101
  retries?: number | undefined;
730
1102
  condition?: "always" | "on-success" | "on-failure" | undefined;
731
1103
  }[];
732
- role?: string | undefined;
733
1104
  name?: string | undefined;
1105
+ role?: string | undefined;
734
1106
  objective?: string | undefined;
735
1107
  }, {
736
1108
  id: string;
@@ -744,8 +1116,8 @@ declare const pipelineConfigSchema: z.ZodObject<{
744
1116
  retries?: number | undefined;
745
1117
  condition?: "always" | "on-success" | "on-failure" | undefined;
746
1118
  }[];
747
- role?: string | undefined;
748
1119
  name?: string | undefined;
1120
+ role?: string | undefined;
749
1121
  objective?: string | undefined;
750
1122
  }>;
751
1123
  declare const plannerConfigSchema: z.ZodObject<{
@@ -768,6 +1140,7 @@ declare const projectConfigSchema: z.ZodObject<{
768
1140
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
769
1141
  base_url: z.ZodString;
770
1142
  api_key_env_var: z.ZodOptional<z.ZodString>;
1143
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
771
1144
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
772
1145
  enabled: z.ZodOptional<z.ZodBoolean>;
773
1146
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -775,18 +1148,20 @@ declare const projectConfigSchema: z.ZodObject<{
775
1148
  name: string;
776
1149
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
777
1150
  base_url: string;
1151
+ metadata?: Record<string, unknown> | undefined;
778
1152
  api_key_env_var?: string | undefined;
1153
+ timeout_ms?: number | undefined;
779
1154
  headers?: Record<string, string> | undefined;
780
1155
  enabled?: boolean | undefined;
781
- metadata?: Record<string, unknown> | undefined;
782
1156
  }, {
783
1157
  name: string;
784
1158
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
785
1159
  base_url: string;
1160
+ metadata?: Record<string, unknown> | undefined;
786
1161
  api_key_env_var?: string | undefined;
1162
+ timeout_ms?: number | undefined;
787
1163
  headers?: Record<string, string> | undefined;
788
1164
  enabled?: boolean | undefined;
789
- metadata?: Record<string, unknown> | undefined;
790
1165
  }>, "many">>;
791
1166
  agents: z.ZodDefault<z.ZodArray<z.ZodObject<{
792
1167
  name: z.ZodString;
@@ -799,29 +1174,44 @@ declare const projectConfigSchema: z.ZodObject<{
799
1174
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
800
1175
  timeout_ms: z.ZodOptional<z.ZodNumber>;
801
1176
  inherit_env: z.ZodOptional<z.ZodBoolean>;
1177
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
1178
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1179
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1180
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
1181
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
802
1182
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
803
1183
  }, "strict", z.ZodTypeAny, {
804
1184
  name: string;
805
1185
  type: "native" | "process" | "cli";
806
- input_mode: "stdin" | "arg" | "protocol";
807
- metadata?: Record<string, unknown> | undefined;
1186
+ input_mode: "protocol" | "stdin" | "arg";
808
1187
  command?: string | undefined;
1188
+ metadata?: Record<string, unknown> | undefined;
1189
+ timeout_ms?: number | undefined;
809
1190
  args?: string[] | undefined;
810
1191
  cwd?: string | undefined;
811
1192
  env?: Record<string, string> | undefined;
812
- timeout_ms?: number | undefined;
813
1193
  inherit_env?: boolean | undefined;
1194
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1195
+ env_allowlist?: string[] | undefined;
1196
+ env_denylist?: string[] | undefined;
1197
+ max_output_bytes?: number | undefined;
1198
+ allow_external_cwd?: boolean | undefined;
814
1199
  }, {
815
1200
  name: string;
816
- type?: "native" | "process" | "cli" | undefined;
817
- metadata?: Record<string, unknown> | undefined;
818
1201
  command?: string | undefined;
1202
+ metadata?: Record<string, unknown> | undefined;
1203
+ type?: "native" | "process" | "cli" | undefined;
1204
+ timeout_ms?: number | undefined;
819
1205
  args?: string[] | undefined;
820
1206
  cwd?: string | undefined;
821
1207
  env?: Record<string, string> | undefined;
822
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
823
- timeout_ms?: number | undefined;
1208
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
824
1209
  inherit_env?: boolean | undefined;
1210
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1211
+ env_allowlist?: string[] | undefined;
1212
+ env_denylist?: string[] | undefined;
1213
+ max_output_bytes?: number | undefined;
1214
+ allow_external_cwd?: boolean | undefined;
825
1215
  }>, "many">>;
826
1216
  roles: z.ZodDefault<z.ZodArray<z.ZodObject<{
827
1217
  id: z.ZodString;
@@ -896,8 +1286,8 @@ declare const projectConfigSchema: z.ZodObject<{
896
1286
  retries?: number | undefined;
897
1287
  condition?: "always" | "on-success" | "on-failure" | undefined;
898
1288
  }[];
899
- role?: string | undefined;
900
1289
  name?: string | undefined;
1290
+ role?: string | undefined;
901
1291
  objective?: string | undefined;
902
1292
  }, {
903
1293
  id: string;
@@ -911,8 +1301,8 @@ declare const projectConfigSchema: z.ZodObject<{
911
1301
  retries?: number | undefined;
912
1302
  condition?: "always" | "on-success" | "on-failure" | undefined;
913
1303
  }[];
914
- role?: string | undefined;
915
1304
  name?: string | undefined;
1305
+ role?: string | undefined;
916
1306
  objective?: string | undefined;
917
1307
  }>, "many">>;
918
1308
  planner: z.ZodOptional<z.ZodObject<{
@@ -932,37 +1322,47 @@ declare const projectConfigSchema: z.ZodObject<{
932
1322
  provider: z.ZodDefault<z.ZodString>;
933
1323
  base_url: z.ZodOptional<z.ZodString>;
934
1324
  api_key_env_var: z.ZodOptional<z.ZodString>;
1325
+ /** When true, memory failures fail tasks instead of being tolerated (§12). */
1326
+ required: z.ZodOptional<z.ZodBoolean>;
935
1327
  }, "strict", z.ZodTypeAny, {
936
1328
  provider: string;
937
1329
  base_url?: string | undefined;
938
1330
  api_key_env_var?: string | undefined;
1331
+ required?: boolean | undefined;
939
1332
  }, {
940
1333
  base_url?: string | undefined;
941
1334
  api_key_env_var?: string | undefined;
942
1335
  provider?: string | undefined;
1336
+ required?: boolean | undefined;
943
1337
  }>>;
944
1338
  }, "strict", z.ZodTypeAny, {
945
1339
  name: string;
946
1340
  agents: {
947
1341
  name: string;
948
1342
  type: "native" | "process" | "cli";
949
- input_mode: "stdin" | "arg" | "protocol";
950
- metadata?: Record<string, unknown> | undefined;
1343
+ input_mode: "protocol" | "stdin" | "arg";
951
1344
  command?: string | undefined;
1345
+ metadata?: Record<string, unknown> | undefined;
1346
+ timeout_ms?: number | undefined;
952
1347
  args?: string[] | undefined;
953
1348
  cwd?: string | undefined;
954
1349
  env?: Record<string, string> | undefined;
955
- timeout_ms?: number | undefined;
956
1350
  inherit_env?: boolean | undefined;
1351
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1352
+ env_allowlist?: string[] | undefined;
1353
+ env_denylist?: string[] | undefined;
1354
+ max_output_bytes?: number | undefined;
1355
+ allow_external_cwd?: boolean | undefined;
957
1356
  }[];
958
1357
  providers: {
959
1358
  name: string;
960
1359
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
961
1360
  base_url: string;
1361
+ metadata?: Record<string, unknown> | undefined;
962
1362
  api_key_env_var?: string | undefined;
1363
+ timeout_ms?: number | undefined;
963
1364
  headers?: Record<string, string> | undefined;
964
1365
  enabled?: boolean | undefined;
965
- metadata?: Record<string, unknown> | undefined;
966
1366
  }[];
967
1367
  roles: {
968
1368
  name: string;
@@ -986,8 +1386,8 @@ declare const projectConfigSchema: z.ZodObject<{
986
1386
  retries?: number | undefined;
987
1387
  condition?: "always" | "on-success" | "on-failure" | undefined;
988
1388
  }[];
989
- role?: string | undefined;
990
1389
  name?: string | undefined;
1390
+ role?: string | undefined;
991
1391
  objective?: string | undefined;
992
1392
  }[];
993
1393
  planner?: {
@@ -999,29 +1399,36 @@ declare const projectConfigSchema: z.ZodObject<{
999
1399
  provider: string;
1000
1400
  base_url?: string | undefined;
1001
1401
  api_key_env_var?: string | undefined;
1402
+ required?: boolean | undefined;
1002
1403
  } | undefined;
1003
1404
  }, {
1004
1405
  name: string;
1005
1406
  agents?: {
1006
1407
  name: string;
1007
- type?: "native" | "process" | "cli" | undefined;
1008
- metadata?: Record<string, unknown> | undefined;
1009
1408
  command?: string | undefined;
1409
+ metadata?: Record<string, unknown> | undefined;
1410
+ type?: "native" | "process" | "cli" | undefined;
1411
+ timeout_ms?: number | undefined;
1010
1412
  args?: string[] | undefined;
1011
1413
  cwd?: string | undefined;
1012
1414
  env?: Record<string, string> | undefined;
1013
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1014
- timeout_ms?: number | undefined;
1415
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1015
1416
  inherit_env?: boolean | undefined;
1417
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1418
+ env_allowlist?: string[] | undefined;
1419
+ env_denylist?: string[] | undefined;
1420
+ max_output_bytes?: number | undefined;
1421
+ allow_external_cwd?: boolean | undefined;
1016
1422
  }[] | undefined;
1017
1423
  providers?: {
1018
1424
  name: string;
1019
1425
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1020
1426
  base_url: string;
1427
+ metadata?: Record<string, unknown> | undefined;
1021
1428
  api_key_env_var?: string | undefined;
1429
+ timeout_ms?: number | undefined;
1022
1430
  headers?: Record<string, string> | undefined;
1023
1431
  enabled?: boolean | undefined;
1024
- metadata?: Record<string, unknown> | undefined;
1025
1432
  }[] | undefined;
1026
1433
  roles?: {
1027
1434
  name: string;
@@ -1045,8 +1452,8 @@ declare const projectConfigSchema: z.ZodObject<{
1045
1452
  retries?: number | undefined;
1046
1453
  condition?: "always" | "on-success" | "on-failure" | undefined;
1047
1454
  }[];
1048
- role?: string | undefined;
1049
1455
  name?: string | undefined;
1456
+ role?: string | undefined;
1050
1457
  objective?: string | undefined;
1051
1458
  }[] | undefined;
1052
1459
  planner?: {
@@ -1058,6 +1465,7 @@ declare const projectConfigSchema: z.ZodObject<{
1058
1465
  base_url?: string | undefined;
1059
1466
  api_key_env_var?: string | undefined;
1060
1467
  provider?: string | undefined;
1468
+ required?: boolean | undefined;
1061
1469
  } | undefined;
1062
1470
  }>;
1063
1471
  declare const appConfigSchema: z.ZodObject<{
@@ -1068,6 +1476,7 @@ declare const appConfigSchema: z.ZodObject<{
1068
1476
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
1069
1477
  base_url: z.ZodString;
1070
1478
  api_key_env_var: z.ZodOptional<z.ZodString>;
1479
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
1071
1480
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1072
1481
  enabled: z.ZodOptional<z.ZodBoolean>;
1073
1482
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -1075,18 +1484,20 @@ declare const appConfigSchema: z.ZodObject<{
1075
1484
  name: string;
1076
1485
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1077
1486
  base_url: string;
1487
+ metadata?: Record<string, unknown> | undefined;
1078
1488
  api_key_env_var?: string | undefined;
1489
+ timeout_ms?: number | undefined;
1079
1490
  headers?: Record<string, string> | undefined;
1080
1491
  enabled?: boolean | undefined;
1081
- metadata?: Record<string, unknown> | undefined;
1082
1492
  }, {
1083
1493
  name: string;
1084
1494
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1085
1495
  base_url: string;
1496
+ metadata?: Record<string, unknown> | undefined;
1086
1497
  api_key_env_var?: string | undefined;
1498
+ timeout_ms?: number | undefined;
1087
1499
  headers?: Record<string, string> | undefined;
1088
1500
  enabled?: boolean | undefined;
1089
- metadata?: Record<string, unknown> | undefined;
1090
1501
  }>, "many">>;
1091
1502
  agents: z.ZodDefault<z.ZodArray<z.ZodObject<{
1092
1503
  name: z.ZodString;
@@ -1099,29 +1510,44 @@ declare const appConfigSchema: z.ZodObject<{
1099
1510
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
1100
1511
  timeout_ms: z.ZodOptional<z.ZodNumber>;
1101
1512
  inherit_env: z.ZodOptional<z.ZodBoolean>;
1513
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
1514
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1515
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1516
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
1517
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
1102
1518
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1103
1519
  }, "strict", z.ZodTypeAny, {
1104
1520
  name: string;
1105
1521
  type: "native" | "process" | "cli";
1106
- input_mode: "stdin" | "arg" | "protocol";
1107
- metadata?: Record<string, unknown> | undefined;
1522
+ input_mode: "protocol" | "stdin" | "arg";
1108
1523
  command?: string | undefined;
1524
+ metadata?: Record<string, unknown> | undefined;
1525
+ timeout_ms?: number | undefined;
1109
1526
  args?: string[] | undefined;
1110
1527
  cwd?: string | undefined;
1111
1528
  env?: Record<string, string> | undefined;
1112
- timeout_ms?: number | undefined;
1113
1529
  inherit_env?: boolean | undefined;
1530
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1531
+ env_allowlist?: string[] | undefined;
1532
+ env_denylist?: string[] | undefined;
1533
+ max_output_bytes?: number | undefined;
1534
+ allow_external_cwd?: boolean | undefined;
1114
1535
  }, {
1115
1536
  name: string;
1116
- type?: "native" | "process" | "cli" | undefined;
1117
- metadata?: Record<string, unknown> | undefined;
1118
1537
  command?: string | undefined;
1538
+ metadata?: Record<string, unknown> | undefined;
1539
+ type?: "native" | "process" | "cli" | undefined;
1540
+ timeout_ms?: number | undefined;
1119
1541
  args?: string[] | undefined;
1120
1542
  cwd?: string | undefined;
1121
1543
  env?: Record<string, string> | undefined;
1122
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1123
- timeout_ms?: number | undefined;
1544
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1124
1545
  inherit_env?: boolean | undefined;
1546
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1547
+ env_allowlist?: string[] | undefined;
1548
+ env_denylist?: string[] | undefined;
1549
+ max_output_bytes?: number | undefined;
1550
+ allow_external_cwd?: boolean | undefined;
1125
1551
  }>, "many">>;
1126
1552
  roles: z.ZodDefault<z.ZodArray<z.ZodObject<{
1127
1553
  id: z.ZodString;
@@ -1196,8 +1622,8 @@ declare const appConfigSchema: z.ZodObject<{
1196
1622
  retries?: number | undefined;
1197
1623
  condition?: "always" | "on-success" | "on-failure" | undefined;
1198
1624
  }[];
1199
- role?: string | undefined;
1200
1625
  name?: string | undefined;
1626
+ role?: string | undefined;
1201
1627
  objective?: string | undefined;
1202
1628
  }, {
1203
1629
  id: string;
@@ -1211,8 +1637,8 @@ declare const appConfigSchema: z.ZodObject<{
1211
1637
  retries?: number | undefined;
1212
1638
  condition?: "always" | "on-success" | "on-failure" | undefined;
1213
1639
  }[];
1214
- role?: string | undefined;
1215
1640
  name?: string | undefined;
1641
+ role?: string | undefined;
1216
1642
  objective?: string | undefined;
1217
1643
  }>, "many">>;
1218
1644
  planner: z.ZodOptional<z.ZodObject<{
@@ -1232,37 +1658,47 @@ declare const appConfigSchema: z.ZodObject<{
1232
1658
  provider: z.ZodDefault<z.ZodString>;
1233
1659
  base_url: z.ZodOptional<z.ZodString>;
1234
1660
  api_key_env_var: z.ZodOptional<z.ZodString>;
1661
+ /** When true, memory failures fail tasks instead of being tolerated (§12). */
1662
+ required: z.ZodOptional<z.ZodBoolean>;
1235
1663
  }, "strict", z.ZodTypeAny, {
1236
1664
  provider: string;
1237
1665
  base_url?: string | undefined;
1238
1666
  api_key_env_var?: string | undefined;
1667
+ required?: boolean | undefined;
1239
1668
  }, {
1240
1669
  base_url?: string | undefined;
1241
1670
  api_key_env_var?: string | undefined;
1242
1671
  provider?: string | undefined;
1672
+ required?: boolean | undefined;
1243
1673
  }>>;
1244
1674
  }, "strict", z.ZodTypeAny, {
1245
1675
  name: string;
1246
1676
  agents: {
1247
1677
  name: string;
1248
1678
  type: "native" | "process" | "cli";
1249
- input_mode: "stdin" | "arg" | "protocol";
1250
- metadata?: Record<string, unknown> | undefined;
1679
+ input_mode: "protocol" | "stdin" | "arg";
1251
1680
  command?: string | undefined;
1681
+ metadata?: Record<string, unknown> | undefined;
1682
+ timeout_ms?: number | undefined;
1252
1683
  args?: string[] | undefined;
1253
1684
  cwd?: string | undefined;
1254
1685
  env?: Record<string, string> | undefined;
1255
- timeout_ms?: number | undefined;
1256
1686
  inherit_env?: boolean | undefined;
1687
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1688
+ env_allowlist?: string[] | undefined;
1689
+ env_denylist?: string[] | undefined;
1690
+ max_output_bytes?: number | undefined;
1691
+ allow_external_cwd?: boolean | undefined;
1257
1692
  }[];
1258
1693
  providers: {
1259
1694
  name: string;
1260
1695
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1261
1696
  base_url: string;
1697
+ metadata?: Record<string, unknown> | undefined;
1262
1698
  api_key_env_var?: string | undefined;
1699
+ timeout_ms?: number | undefined;
1263
1700
  headers?: Record<string, string> | undefined;
1264
1701
  enabled?: boolean | undefined;
1265
- metadata?: Record<string, unknown> | undefined;
1266
1702
  }[];
1267
1703
  roles: {
1268
1704
  name: string;
@@ -1286,8 +1722,8 @@ declare const appConfigSchema: z.ZodObject<{
1286
1722
  retries?: number | undefined;
1287
1723
  condition?: "always" | "on-success" | "on-failure" | undefined;
1288
1724
  }[];
1289
- role?: string | undefined;
1290
1725
  name?: string | undefined;
1726
+ role?: string | undefined;
1291
1727
  objective?: string | undefined;
1292
1728
  }[];
1293
1729
  planner?: {
@@ -1299,29 +1735,36 @@ declare const appConfigSchema: z.ZodObject<{
1299
1735
  provider: string;
1300
1736
  base_url?: string | undefined;
1301
1737
  api_key_env_var?: string | undefined;
1738
+ required?: boolean | undefined;
1302
1739
  } | undefined;
1303
1740
  }, {
1304
1741
  name: string;
1305
1742
  agents?: {
1306
1743
  name: string;
1307
- type?: "native" | "process" | "cli" | undefined;
1308
- metadata?: Record<string, unknown> | undefined;
1309
1744
  command?: string | undefined;
1745
+ metadata?: Record<string, unknown> | undefined;
1746
+ type?: "native" | "process" | "cli" | undefined;
1747
+ timeout_ms?: number | undefined;
1310
1748
  args?: string[] | undefined;
1311
1749
  cwd?: string | undefined;
1312
1750
  env?: Record<string, string> | undefined;
1313
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1314
- timeout_ms?: number | undefined;
1751
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1315
1752
  inherit_env?: boolean | undefined;
1753
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1754
+ env_allowlist?: string[] | undefined;
1755
+ env_denylist?: string[] | undefined;
1756
+ max_output_bytes?: number | undefined;
1757
+ allow_external_cwd?: boolean | undefined;
1316
1758
  }[] | undefined;
1317
1759
  providers?: {
1318
1760
  name: string;
1319
1761
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1320
1762
  base_url: string;
1763
+ metadata?: Record<string, unknown> | undefined;
1321
1764
  api_key_env_var?: string | undefined;
1765
+ timeout_ms?: number | undefined;
1322
1766
  headers?: Record<string, string> | undefined;
1323
1767
  enabled?: boolean | undefined;
1324
- metadata?: Record<string, unknown> | undefined;
1325
1768
  }[] | undefined;
1326
1769
  roles?: {
1327
1770
  name: string;
@@ -1345,8 +1788,8 @@ declare const appConfigSchema: z.ZodObject<{
1345
1788
  retries?: number | undefined;
1346
1789
  condition?: "always" | "on-success" | "on-failure" | undefined;
1347
1790
  }[];
1348
- role?: string | undefined;
1349
1791
  name?: string | undefined;
1792
+ role?: string | undefined;
1350
1793
  objective?: string | undefined;
1351
1794
  }[] | undefined;
1352
1795
  planner?: {
@@ -1358,6 +1801,7 @@ declare const appConfigSchema: z.ZodObject<{
1358
1801
  base_url?: string | undefined;
1359
1802
  api_key_env_var?: string | undefined;
1360
1803
  provider?: string | undefined;
1804
+ required?: boolean | undefined;
1361
1805
  } | undefined;
1362
1806
  }>;
1363
1807
  logging: z.ZodOptional<z.ZodObject<{
@@ -1373,23 +1817,29 @@ declare const appConfigSchema: z.ZodObject<{
1373
1817
  agents: {
1374
1818
  name: string;
1375
1819
  type: "native" | "process" | "cli";
1376
- input_mode: "stdin" | "arg" | "protocol";
1377
- metadata?: Record<string, unknown> | undefined;
1820
+ input_mode: "protocol" | "stdin" | "arg";
1378
1821
  command?: string | undefined;
1822
+ metadata?: Record<string, unknown> | undefined;
1823
+ timeout_ms?: number | undefined;
1379
1824
  args?: string[] | undefined;
1380
1825
  cwd?: string | undefined;
1381
1826
  env?: Record<string, string> | undefined;
1382
- timeout_ms?: number | undefined;
1383
1827
  inherit_env?: boolean | undefined;
1828
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1829
+ env_allowlist?: string[] | undefined;
1830
+ env_denylist?: string[] | undefined;
1831
+ max_output_bytes?: number | undefined;
1832
+ allow_external_cwd?: boolean | undefined;
1384
1833
  }[];
1385
1834
  providers: {
1386
1835
  name: string;
1387
1836
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1388
1837
  base_url: string;
1838
+ metadata?: Record<string, unknown> | undefined;
1389
1839
  api_key_env_var?: string | undefined;
1840
+ timeout_ms?: number | undefined;
1390
1841
  headers?: Record<string, string> | undefined;
1391
1842
  enabled?: boolean | undefined;
1392
- metadata?: Record<string, unknown> | undefined;
1393
1843
  }[];
1394
1844
  roles: {
1395
1845
  name: string;
@@ -1413,8 +1863,8 @@ declare const appConfigSchema: z.ZodObject<{
1413
1863
  retries?: number | undefined;
1414
1864
  condition?: "always" | "on-success" | "on-failure" | undefined;
1415
1865
  }[];
1416
- role?: string | undefined;
1417
1866
  name?: string | undefined;
1867
+ role?: string | undefined;
1418
1868
  objective?: string | undefined;
1419
1869
  }[];
1420
1870
  planner?: {
@@ -1426,6 +1876,7 @@ declare const appConfigSchema: z.ZodObject<{
1426
1876
  provider: string;
1427
1877
  base_url?: string | undefined;
1428
1878
  api_key_env_var?: string | undefined;
1879
+ required?: boolean | undefined;
1429
1880
  } | undefined;
1430
1881
  };
1431
1882
  logging?: {
@@ -1436,24 +1887,30 @@ declare const appConfigSchema: z.ZodObject<{
1436
1887
  name: string;
1437
1888
  agents?: {
1438
1889
  name: string;
1439
- type?: "native" | "process" | "cli" | undefined;
1440
- metadata?: Record<string, unknown> | undefined;
1441
1890
  command?: string | undefined;
1891
+ metadata?: Record<string, unknown> | undefined;
1892
+ type?: "native" | "process" | "cli" | undefined;
1893
+ timeout_ms?: number | undefined;
1442
1894
  args?: string[] | undefined;
1443
1895
  cwd?: string | undefined;
1444
1896
  env?: Record<string, string> | undefined;
1445
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1446
- timeout_ms?: number | undefined;
1897
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1447
1898
  inherit_env?: boolean | undefined;
1899
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1900
+ env_allowlist?: string[] | undefined;
1901
+ env_denylist?: string[] | undefined;
1902
+ max_output_bytes?: number | undefined;
1903
+ allow_external_cwd?: boolean | undefined;
1448
1904
  }[] | undefined;
1449
1905
  providers?: {
1450
1906
  name: string;
1451
1907
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1452
1908
  base_url: string;
1909
+ metadata?: Record<string, unknown> | undefined;
1453
1910
  api_key_env_var?: string | undefined;
1911
+ timeout_ms?: number | undefined;
1454
1912
  headers?: Record<string, string> | undefined;
1455
1913
  enabled?: boolean | undefined;
1456
- metadata?: Record<string, unknown> | undefined;
1457
1914
  }[] | undefined;
1458
1915
  roles?: {
1459
1916
  name: string;
@@ -1477,8 +1934,8 @@ declare const appConfigSchema: z.ZodObject<{
1477
1934
  retries?: number | undefined;
1478
1935
  condition?: "always" | "on-success" | "on-failure" | undefined;
1479
1936
  }[];
1480
- role?: string | undefined;
1481
1937
  name?: string | undefined;
1938
+ role?: string | undefined;
1482
1939
  objective?: string | undefined;
1483
1940
  }[] | undefined;
1484
1941
  planner?: {
@@ -1490,6 +1947,7 @@ declare const appConfigSchema: z.ZodObject<{
1490
1947
  base_url?: string | undefined;
1491
1948
  api_key_env_var?: string | undefined;
1492
1949
  provider?: string | undefined;
1950
+ required?: boolean | undefined;
1493
1951
  } | undefined;
1494
1952
  };
1495
1953
  logging?: {
@@ -1521,6 +1979,7 @@ interface AppConfig {
1521
1979
  provider: string;
1522
1980
  baseUrl?: string;
1523
1981
  apiKeyEnvVar?: string;
1982
+ required?: boolean;
1524
1983
  };
1525
1984
  };
1526
1985
  logging?: {
@@ -1571,11 +2030,63 @@ declare function requestJson(url: string, options?: HttpRequestOptions): Promise
1571
2030
  declare const OPENAI_COMPATIBLE_TYPES: readonly ProviderType[];
1572
2031
  declare function createProvider(config: ProviderConfig): IChatProvider;
1573
2032
 
2033
+ /**
2034
+ * Provider error normalization (roadmap §10).
2035
+ *
2036
+ * Every provider failure is mapped to one stable kind, so callers can react
2037
+ * (retry a rate limit, surface an auth problem, treat a missing model
2038
+ * differently) without string-matching provider-specific payloads.
2039
+ */
2040
+
2041
+ type ProviderErrorKind = "AUTHENTICATION_ERROR" | "RATE_LIMIT_ERROR" | "INVALID_REQUEST" | "MODEL_NOT_FOUND" | "TIMEOUT" | "NETWORK_ERROR" | "SERVER_ERROR" | "UNKNOWN_ERROR";
2042
+ interface ProviderErrorContext {
2043
+ provider: string;
2044
+ operation: string;
2045
+ status?: number;
2046
+ body?: unknown;
2047
+ retryAfterMs?: number;
2048
+ cause?: unknown;
2049
+ /** Maps the normalized kind onto the legacy stable error code. */
2050
+ code?: "PROVIDER_UNAVAILABLE" | "PROVIDER_AUTH_FAILED" | "MODEL_NOT_FOUND";
2051
+ }
2052
+ /** Kinds worth retrying automatically (rate limits and transient server errors). */
2053
+ declare function isRetryable(kind: ProviderErrorKind): boolean;
2054
+ /** Maps an HTTP status (and optional body) to a normalized kind. */
2055
+ declare function kindFromStatus(status: number): ProviderErrorKind;
2056
+ /** Extracts a human message from common provider error body shapes. */
2057
+ declare function extractMessage(body: unknown): string | undefined;
2058
+ /** Parses `Retry-After` (seconds or HTTP-date) into milliseconds. */
2059
+ declare function parseRetryAfter(value: string | null | undefined, now?: number): number | undefined;
2060
+ /** True for the abort/timeout errors raised by fetch's AbortSignal.timeout. */
2061
+ declare function isTimeoutError(error: unknown): boolean;
2062
+ /** True for transport failures (DNS, refused, TLS, offline). */
2063
+ declare function isNetworkError(error: unknown): boolean;
2064
+ declare function providerHttpError(context: ProviderErrorContext): ProviderError;
2065
+ /** Wraps a thrown transport/abort error into a normalized ProviderError. */
2066
+ declare function providerTransportError(context: Omit<ProviderErrorContext, "status" | "body">): ProviderError;
2067
+
1574
2068
  declare class OpenAICompatibleProvider implements IChatProvider {
1575
2069
  readonly config: ProviderConfig;
2070
+ readonly providerId: string;
2071
+ readonly authentication: ProviderAuthentication;
1576
2072
  private readonly log;
1577
- constructor(config: ProviderConfig, log?: Logger);
2073
+ /** Discovered models, so getModel() answers without another round-trip. */
2074
+ private discovered?;
2075
+ private readonly env;
2076
+ constructor(config: ProviderConfig, log?: Logger, env?: Record<string, string | undefined>);
2077
+ /** Provider-level request timeout (roadmap §6.6/§11) with the shared default. */
2078
+ private get requestTimeoutMs();
2079
+ /** Authenticate + discover (roadmap §10, Model Discovery). */
2080
+ connect(): Promise<ModelInfo[]>;
2081
+ getModel(modelId: string): Promise<ModelInfo | undefined>;
2082
+ /** Raw /models body (protected so adapters can capture gateway-level metadata). */
2083
+ protected rawModelsResponse(): Promise<unknown>;
2084
+ private modelsRequest;
1578
2085
  listModels(): Promise<ModelInfo[]>;
2086
+ /** Maps a raw model entry onto the normalized metadata shape (§10). */
2087
+ private toModelInfo;
2088
+ /** Streaming where the gateway supports it (§11). */
2089
+ stream(request: ChatRequest, onChunk: (chunk: ChatStreamChunk) => void): Promise<ChatResponse>;
1579
2090
  healthCheck(): Promise<ProviderStatus>;
1580
2091
  chat(request: ChatRequest): Promise<ChatResponse>;
1581
2092
  }
@@ -1618,13 +2129,37 @@ interface OmniHilbrasConnectionResult {
1618
2129
  registered: number;
1619
2130
  }
1620
2131
  declare class OmniHilbrasProvider extends OpenAICompatibleProvider {
2132
+ private gateway?;
2133
+ listModels(): Promise<ModelInfo[]>;
1621
2134
  /**
1622
2135
  * Run the full connect flow. Throws on authentication or transport failure
1623
2136
  * (use healthCheck() for a non-throwing probe).
1624
2137
  */
1625
- connect(registry?: ModelRegistry): Promise<OmniHilbrasConnectionResult>;
2138
+ /**
2139
+ * Gateway metadata reported alongside the model list (gateway version, tier,
2140
+ * region…), kept separate from per-model metadata (§11 — provider metadata).
2141
+ */
2142
+ gatewayMetadata(): Record<string, unknown> | undefined;
2143
+ protected extractGatewayMetadata(body: unknown): Promise<void>;
2144
+ connectAndRegister(registry?: ModelRegistry): Promise<OmniHilbrasConnectionResult>;
1626
2145
  }
1627
2146
 
2147
+ /**
2148
+ * Process adapter (§9): runs CLI agents as child processes and communicates
2149
+ * over stdin/stdout, managing the process lifecycle, working directory,
2150
+ * environment, exit codes, logs and timeouts.
2151
+ *
2152
+ * Three input modes (§9, §21):
2153
+ * - "stdin": the composed task text is written to the agent's stdin.
2154
+ * - "arg": the composed task text is appended as the last command argument.
2155
+ * - "protocol": NodeToAgentMessage envelopes as JSON lines on stdin; the
2156
+ * agent answers with AgentToNodeMessage JSON lines (REPORT,
2157
+ * COMPLETION, ERROR, ...) whose structured payloads are parsed
2158
+ * into reports.
2159
+ */
2160
+
2161
+ /** Per-stream byte budget before output is truncated and the agent killed. */
2162
+ declare const DEFAULT_MAX_OUTPUT_BYTES: number;
1628
2163
  declare function composeTaskText(input: AgentTaskInput): string;
1629
2164
  declare class ProcessAgent implements IAgent {
1630
2165
  readonly config: AgentConfig;
@@ -1637,6 +2172,63 @@ declare class ProcessAgent implements IAgent {
1637
2172
  cancel(taskId: string): Promise<void>;
1638
2173
  runningTaskIds(): string[];
1639
2174
  }
2175
+ /** Kills a child and, on POSIX, its whole process group (roadmap §8 tree cleanup). */
2176
+ declare function killTree(child: ChildProcess, signal: NodeJS.Signals): void;
2177
+ /** Human-readable exit reason, including signal terminations. */
2178
+ declare function describeExit(code: number | null, signal: NodeJS.Signals | null): string;
2179
+ /**
2180
+ * Decodes a stdout/stderr chunk safely: invalid UTF-8 becomes replacement
2181
+ * characters and NUL bytes are stripped, so binary noise cannot poison the
2182
+ * protocol decoder or the terminal (roadmap §8, encoding hardening).
2183
+ */
2184
+ declare function sanitizeChunk(chunk: Buffer): string;
2185
+
2186
+ /**
2187
+ * Agent environment policies (roadmap §8, Environment Isolation).
2188
+ *
2189
+ * Four explicit policies, so operators decide exactly what an agent can see:
2190
+ * - `inherit` (default, backwards compatible): the full parent environment
2191
+ * - `allowlist`: only the allow-listed variables (+ PATH/HOME)
2192
+ * - `denylist`: the parent environment minus the deny-listed variables
2193
+ * - `explicit`: nothing from the parent; only PATH/HOME and `env`
2194
+ *
2195
+ * The v1 boolean `inherit_env: false` is still honored and maps to `explicit`.
2196
+ */
2197
+
2198
+ type EnvPolicy = "inherit" | "allowlist" | "denylist" | "explicit";
2199
+ declare function resolveEnvPolicy(config: Partial<AgentConfig>): EnvPolicy;
2200
+ declare function buildChildEnv(config: AgentConfig): NodeJS.ProcessEnv;
2201
+
2202
+ interface CwdValidation {
2203
+ /** Normalized absolute path. */
2204
+ cwd: string;
2205
+ /** True when the directory sits outside the project root (project boundary). */
2206
+ outsideProject: boolean;
2207
+ }
2208
+ declare function validateWorkingDirectory(cwd: string | undefined, options?: {
2209
+ projectRoot?: string;
2210
+ allowExternal?: boolean;
2211
+ }): CwdValidation | undefined;
2212
+
2213
+ interface IAgentAdapter {
2214
+ /** Integration type this adapter serves, e.g. "native" or "process". */
2215
+ readonly integration: string;
2216
+ create(config: AgentConfig): IAgent;
2217
+ }
2218
+ declare class AgentAdapterRegistry {
2219
+ private readonly adapters;
2220
+ register(adapter: IAgentAdapter): void;
2221
+ get(integration: string): IAgentAdapter | undefined;
2222
+ list(): IAgentAdapter[];
2223
+ create(config: AgentConfig): IAgent;
2224
+ }
2225
+ /** Process-level adapter — the built-in CLI integration. */
2226
+ declare class ProcessAgentAdapter implements IAgentAdapter {
2227
+ private readonly factory;
2228
+ readonly integration = "process";
2229
+ constructor(factory: (config: AgentConfig) => IAgent);
2230
+ create(config: AgentConfig): IAgent;
2231
+ }
1640
2232
 
1641
2233
  /** Agent registry (§10): the set of agents connected to OmniNode. */
1642
2234
 
@@ -1652,10 +2244,109 @@ declare class AgentRegistry {
1652
2244
  * "cli" agent configs are mapped to the process integration by the loader.
1653
2245
  */
1654
2246
 
1655
- declare function createAgent(config: AgentConfig): IAgent;
2247
+ declare function createAgent(config: AgentConfig, adapters?: AgentAdapterRegistry): IAgent;
2248
+
1656
2249
  /** Builds an agent registry from the project configuration, skipping agents that fail to construct. */
1657
2250
  declare function buildAgentRegistry(config: AppConfig, log?: Logger): AgentRegistry;
1658
2251
 
2252
+ /**
2253
+ * OmniNode Agent Protocol v2 — versioning (roadmap §7.1).
2254
+ *
2255
+ * Protocol identifiers are namespaced strings so an agent can negotiate the
2256
+ * dialect it speaks: `omninode-agent-protocol/2`.
2257
+ */
2258
+ declare const PROTOCOL_V2 = "omninode-agent-protocol/2";
2259
+ /** Versions this build accepts. v1 is the unversioned dialect shipped with OmniNode 1.x. */
2260
+ declare const SUPPORTED_PROTOCOL_VERSIONS: readonly string[];
2261
+ declare const MAX_MESSAGE_BYTES = 1048576;
2262
+ declare function isSupportedProtocol(protocol: string): boolean;
2263
+
2264
+ type ProtocolViolationCode = "INVALID_JSON" | "NOT_AN_OBJECT" | "UNKNOWN_TYPE" | "MISSING_FIELD" | "UNSUPPORTED_VERSION" | "OVERSIZED" | "INVALID_PAYLOAD";
2265
+ interface ProtocolViolation {
2266
+ code: ProtocolViolationCode;
2267
+ message: string;
2268
+ /** Raw line (truncated) for diagnostics. */
2269
+ sample?: string;
2270
+ }
2271
+ type DecodeResult = {
2272
+ ok: true;
2273
+ envelope: ProtocolEnvelope;
2274
+ legacy: boolean;
2275
+ } | {
2276
+ ok: false;
2277
+ error: ProtocolViolation;
2278
+ };
2279
+ /** Validates one decoded JSON value as a protocol envelope. */
2280
+ declare function validateEnvelope(value: unknown, line?: string): DecodeResult;
2281
+ /** Decodes one protocol line (no trailing newline). */
2282
+ declare function decodeMessage(line: string, maxBytes?: number): DecodeResult;
2283
+ /** Serializes an envelope to a single JSON line. */
2284
+ declare function encodeMessage(envelope: ProtocolEnvelope, maxBytes?: number): string;
2285
+ /**
2286
+ * Streaming line decoder for agent stdout. Feed chunks; receive decoded
2287
+ * envelopes and violations in order. Survives garbage: a bad line yields a
2288
+ * violation and the stream continues.
2289
+ */
2290
+ declare class ProtocolDecoder {
2291
+ private buffer;
2292
+ private readonly maxBytes;
2293
+ constructor(maxBytes?: number);
2294
+ push(chunk: string): DecodeResult[];
2295
+ /** Flush any trailing line when the process exits. */
2296
+ flush(): DecodeResult[];
2297
+ }
2298
+
2299
+ /**
2300
+ * OmniNode Agent Protocol v2 — session (roadmap §7.6).
2301
+ *
2302
+ * A session drives a protocol-mode agent: it emits v2 envelopes with
2303
+ * correlation ids, tolerates legacy (unversioned) replies, answers agent
2304
+ * questions through a responder callback, and collects reports, artifacts
2305
+ * and the completion — never throwing on malformed input.
2306
+ */
2307
+
2308
+ interface SessionIds {
2309
+ requestId: string;
2310
+ taskId: string;
2311
+ agentId: string;
2312
+ pipelineId?: string;
2313
+ executionId?: string;
2314
+ }
2315
+ interface QuestionResponder {
2316
+ (question: {
2317
+ questionId: string;
2318
+ question: string;
2319
+ expected?: string;
2320
+ }): Promise<string> | string;
2321
+ }
2322
+ declare class ProtocolSession {
2323
+ readonly decoder: ProtocolDecoder;
2324
+ private readonly ids;
2325
+ private readonly responder;
2326
+ readonly violations: ProtocolViolation[];
2327
+ readonly questions: AskedQuestion[];
2328
+ readonly artifacts: ProtocolEnvelope["payload"][];
2329
+ reports: ProtocolEnvelope["payload"][];
2330
+ descriptor?: AgentDescriptor;
2331
+ completionSummary?: string;
2332
+ errorMessage?: string;
2333
+ constructor(ids: SessionIds, options?: {
2334
+ responder?: QuestionResponder;
2335
+ maxBytes?: number;
2336
+ });
2337
+ /** The v2 messages OmniNode sends to open a task (written to the agent's stdin). */
2338
+ taskMessages(objective: string, role?: unknown, context?: string, instruction?: string): string[];
2339
+ helloAck(descriptor: AgentDescriptor): string;
2340
+ /** Consumes decoded stdout, answering questions as they arrive. */
2341
+ handle(decoded: DecodeResult): Promise<void>;
2342
+ private answerQuestion;
2343
+ readonly pendingAnswers: string[];
2344
+ /** True once any inbound message carried the v2 protocol field. */
2345
+ sawV2: boolean;
2346
+ }
2347
+ declare function decodeStream(session: ProtocolSession, chunk: string): Promise<string[]>;
2348
+ declare function requireCompletion(session: ProtocolSession): void;
2349
+
1659
2350
  /** Role registry (§11): the set of roles available for task assignment. */
1660
2351
 
1661
2352
  declare class RoleRegistry {
@@ -1668,6 +2359,41 @@ declare class RoleRegistry {
1668
2359
  /** Builds a role registry from the project configuration. */
1669
2360
  declare function buildRoleRegistry(config: AppConfig): RoleRegistry;
1670
2361
 
2362
+ interface JsonDocument<T> {
2363
+ /** Bumped when the persisted shape changes in a breaking way (v2 Phase 12). */
2364
+ schemaVersion?: number;
2365
+ items: T[];
2366
+ }
2367
+ interface JsonFileStoreOptions {
2368
+ directory?: string;
2369
+ fileName: string;
2370
+ schemaVersion?: number;
2371
+ /** Called when a persisted file cannot be parsed. */
2372
+ onCorrupt?: (path: string, error: unknown) => void;
2373
+ }
2374
+ declare class JsonFileStore<T> {
2375
+ private readonly filePath;
2376
+ private readonly schemaVersion;
2377
+ private readonly onCorrupt?;
2378
+ private readonly log;
2379
+ private queue;
2380
+ constructor(options: JsonFileStoreOptions);
2381
+ get path(): string;
2382
+ /** All items, or [] when missing/corrupt. */
2383
+ protected readAll(): Promise<T[]>;
2384
+ protected writeAll(items: T[]): Promise<void>;
2385
+ /** Serializes an async operation against this file. */
2386
+ protected synchronized<R>(operation: () => Promise<R>): Promise<R>;
2387
+ /** Read-modify-write helper: applies `mutate` to the current items. */
2388
+ protected mutate<R>(mutate: (items: T[]) => Promise<[T[], R]> | [T[], R]): Promise<R>;
2389
+ }
2390
+
2391
+ /**
2392
+ * Task persistence (§4.1 — execution state). The store is replaceable
2393
+ * (§2 — Modular); the default implementation is a local JSON file so
2394
+ * OmniNode stays local-first (§25).
2395
+ */
2396
+
1671
2397
  interface TaskStoreFilter {
1672
2398
  status?: TaskStatus;
1673
2399
  project?: string;
@@ -1677,20 +2403,11 @@ interface TaskStore {
1677
2403
  get(id: string): Promise<Task | undefined>;
1678
2404
  list(filter?: TaskStoreFilter): Promise<Task[]>;
1679
2405
  }
1680
- declare class FileTaskStore implements TaskStore {
1681
- private readonly filePath;
1682
- /**
1683
- * Read-modify-write operations are serialized: parallel pipeline tasks
1684
- * would otherwise race on the JSON file (last writer wins).
1685
- */
1686
- private queue;
2406
+ declare class FileTaskStore extends JsonFileStore<Task> implements TaskStore {
1687
2407
  constructor(directory?: string);
1688
2408
  save(task: Task): Promise<void>;
1689
2409
  get(id: string): Promise<Task | undefined>;
1690
2410
  list(filter?: TaskStoreFilter): Promise<Task[]>;
1691
- private synchronized;
1692
- private load;
1693
- private write;
1694
2411
  }
1695
2412
 
1696
2413
  type AuditAction = "task.created" | "task.queued" | "task.running" | "task.completed" | "task.failed" | "task.cancelled" | "task.retry" | "pipeline.run.started" | "pipeline.run.finished" | "plan.generated" | "memory.context.gathered" | "memory.outcome.recorded";
@@ -1715,18 +2432,29 @@ declare class FileAuditLog implements AuditSink {
1715
2432
  recent(limit?: number): Promise<AuditEvent[]>;
1716
2433
  }
1717
2434
 
2435
+ /**
2436
+ * Local file-based memory provider: the default implementation so persistent
2437
+ * memory works out of the box, locally (§25), with no external service.
2438
+ * Relevance is scored by keyword overlap and tag matches — deterministic and
2439
+ * dependency-free.
2440
+ */
2441
+
1718
2442
  declare function keywords(text: string): Set<string>;
1719
- declare class LocalMemoryProvider implements IMemoryProvider {
2443
+ declare class LocalMemoryProvider extends JsonFileStore<MemoryEntry> implements IMemoryProvider {
1720
2444
  readonly name = "local";
1721
- private readonly filePath;
1722
- private queue;
1723
2445
  constructor(directory?: string);
2446
+ metadata(): MemoryProviderMetadata;
2447
+ search(text: string, options?: {
2448
+ limit?: number;
2449
+ scope?: MemoryQuery["scope"];
2450
+ }): Promise<MemoryEntry[]>;
2451
+ /** @deprecated v1 alias of {@link retrieve}. */
1724
2452
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
2453
+ /** @deprecated v1 alias of {@link store}. */
1725
2454
  write(entry: MemoryEntry): Promise<void>;
2455
+ retrieve(query: MemoryQuery): Promise<MemoryEntry[]>;
2456
+ store(entry: MemoryEntry): Promise<void>;
1726
2457
  count(): Promise<number>;
1727
- private synchronized;
1728
- private load;
1729
- private saveAll;
1730
2458
  }
1731
2459
 
1732
2460
  interface RememberaConfig {
@@ -1741,9 +2469,20 @@ declare class RememberaMemoryProvider implements IMemoryProvider {
1741
2469
  private readonly env;
1742
2470
  private readonly log;
1743
2471
  constructor(config: RememberaConfig, log?: Logger);
2472
+ private get authenticationConfigured();
1744
2473
  private headers;
2474
+ /** Search delegates to the gateway's relevance query. */
2475
+ search(text: string, options?: {
2476
+ limit?: number;
2477
+ scope?: MemoryQuery["scope"];
2478
+ }): Promise<MemoryEntry[]>;
2479
+ metadata(): MemoryProviderMetadata;
2480
+ /** @deprecated v1 alias of {@link retrieve}. */
1745
2481
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
2482
+ /** @deprecated v1 alias of {@link store}. */
1746
2483
  write(entry: MemoryEntry): Promise<void>;
2484
+ retrieve(query: MemoryQuery): Promise<MemoryEntry[]>;
2485
+ store(entry: MemoryEntry): Promise<void>;
1747
2486
  private request;
1748
2487
  private toEntry;
1749
2488
  }
@@ -1751,31 +2490,66 @@ declare class RememberaMemoryProvider implements IMemoryProvider {
1751
2490
  type MemoryProviderConfig = NonNullable<AppConfig["project"]["memory"]>;
1752
2491
  declare function createMemoryProvider(config?: MemoryProviderConfig): IMemoryProvider;
1753
2492
 
1754
- /**
1755
- * Memory service (§19–§20): gathers relevant memory before a task runs and
1756
- * records outcomes afterwards — the Task → memory → relevant context →
1757
- * agents → reports → memory loop. Memory failures are best-effort: they log
1758
- * a warning and never fail a task, because memory is an enhancement, not a
1759
- * dependency (§2).
1760
- */
1761
-
1762
2493
  interface MemoryContextQuery {
1763
2494
  objective: string;
1764
2495
  role?: string;
1765
2496
  project?: string;
2497
+ /** Maximum entries to consider (relevance-ranked by the provider). */
2498
+ limit?: number;
2499
+ }
2500
+ interface MemoryTaskContext {
2501
+ /** Prompt-ready context text ("" when nothing relevant was found). */
2502
+ text: string;
2503
+ entries: MemoryEntry[];
2504
+ /** True when the character budget cut the context short. */
2505
+ truncated: boolean;
2506
+ }
2507
+ declare const MAX_CONTEXT_CHARS = 4000;
2508
+ interface MemoryServiceOptions {
2509
+ /** When true, backend failures propagate instead of being logged. */
2510
+ required?: boolean;
2511
+ maxContextChars?: number;
1766
2512
  }
1767
2513
  declare class MemoryService {
1768
2514
  private readonly provider;
1769
2515
  private readonly log;
1770
- constructor(provider: IMemoryProvider, log?: Logger);
2516
+ private readonly required;
2517
+ private readonly maxContextChars;
2518
+ constructor(provider: IMemoryProvider, log?: Logger, options?: MemoryServiceOptions);
1771
2519
  get providerRef(): IMemoryProvider;
1772
2520
  get providerName(): string;
1773
- /** Relevant context for a task objective; empty string when nothing matches. */
2521
+ get isRequired(): boolean;
2522
+ /** Structured, budgeted context for a task (§12 — avoid loading all memory). */
2523
+ contextFor(query: MemoryContextQuery): Promise<MemoryTaskContext>;
2524
+ /** Prompt-ready context text (v1 convenience wrapper). */
1774
2525
  gatherContext(query: MemoryContextQuery): Promise<string>;
1775
- /** Records a finished task's outcome — best-effort. */
2526
+ /** Records a finished task's outcome — task history plus "known problems" (§12). */
1776
2527
  recordTaskOutcome(task: Task): Promise<void>;
2528
+ private format;
2529
+ /**
2530
+ * Failure policy (§12): continue unless memory is explicitly required.
2531
+ */
2532
+ private handleFailure;
1777
2533
  }
1778
2534
 
2535
+ /**
2536
+ * Shared memory-contract helpers (roadmap §12). Adapters implement
2537
+ * `retrieve` / `store`; these helpers supply the defaults for `search`,
2538
+ * `metadata` and the v1 `query` / `write` aliases, so the contract is
2539
+ * defined once.
2540
+ */
2541
+
2542
+ /** Free-text search defaults to a relevance retrieve. */
2543
+ declare function defaultSearch(provider: Pick<IMemoryProvider, "retrieve">, text: string, options?: {
2544
+ limit?: number;
2545
+ scope?: MemoryQuery["scope"];
2546
+ }): Promise<MemoryEntry[]>;
2547
+ declare function defaultMetadata(name: string, options?: {
2548
+ capabilities?: MemoryProviderMetadata["capabilities"];
2549
+ relevanceRanking?: boolean;
2550
+ backend?: Record<string, unknown>;
2551
+ }): MemoryProviderMetadata;
2552
+
1779
2553
  interface CreateTaskInput {
1780
2554
  objective: string;
1781
2555
  project?: string;
@@ -1783,6 +2557,12 @@ interface CreateTaskInput {
1783
2557
  agent?: string;
1784
2558
  context?: TaskContext;
1785
2559
  }
2560
+ interface RunTaskOptions {
2561
+ /** Total attempts (1 = no automatic retry). Retries apply to retryable errors only. */
2562
+ maxAttempts?: number;
2563
+ /** Linear backoff base in ms: waits backoffMs × attempt between attempts. */
2564
+ retryBackoffMs?: number;
2565
+ }
1786
2566
  interface TaskEngineOptions {
1787
2567
  agents: AgentRegistry;
1788
2568
  roles: RoleRegistry;
@@ -1800,10 +2580,12 @@ declare class TaskEngine {
1800
2580
  get store(): TaskStore;
1801
2581
  create(input: CreateTaskInput): Promise<Task>;
1802
2582
  queue(id: string): Promise<Task>;
1803
- /** Runs the task through its assigned agent and records the result. */
1804
- run(id: string): Promise<Task>;
2583
+ /** Runs the task through its assigned agent and records the result.
2584
+ * `maxAttempts` enables bounded automatic retries of *retryable* errors
2585
+ * with linear backoff; unknown/timed_out outcomes are never auto-retried. */
2586
+ run(id: string, options?: RunTaskOptions): Promise<Task>;
1805
2587
  cancel(id: string): Promise<Task>;
1806
- /** Error recovery (§27 Phase 9): reset a failed/cancelled task so it can run again. */
2588
+ /** Error recovery: reset a failed/cancelled/unknown/timed_out task so it can run again. */
1807
2589
  retry(id: string): Promise<Task>;
1808
2590
  get(id: string): Promise<Task | undefined>;
1809
2591
  list(filter?: TaskStoreFilter): Promise<Task[]>;
@@ -1816,6 +2598,11 @@ declare class TaskEngine {
1816
2598
 
1817
2599
  declare function createTaskEngine(config: AppConfig, log?: Logger, directory?: string): TaskEngine;
1818
2600
 
2601
+ /**
2602
+ * Report persistence (§16 — report storage). Same replaceable-store and
2603
+ * serialized-write patterns as the other local stores.
2604
+ */
2605
+
1819
2606
  interface ReportFilter {
1820
2607
  taskId?: string;
1821
2608
  agent?: string;
@@ -1830,18 +2617,20 @@ interface ReportStore {
1830
2617
  getCombined(id: string): Promise<CombinedReport | undefined>;
1831
2618
  listCombined(filter?: CombinedReportFilter): Promise<CombinedReport[]>;
1832
2619
  }
1833
- declare class FileReportStore implements ReportStore {
1834
- private readonly filePath;
1835
- private queue;
2620
+ type StoreEntry = {
2621
+ kind: "report";
2622
+ report: Report;
2623
+ } | {
2624
+ kind: "combined";
2625
+ combined: CombinedReport;
2626
+ };
2627
+ declare class FileReportStore extends JsonFileStore<StoreEntry> implements ReportStore {
1836
2628
  constructor(directory?: string);
1837
2629
  saveReports(reports: Report[]): Promise<void>;
1838
2630
  listReports(filter?: ReportFilter): Promise<Report[]>;
1839
2631
  saveCombined(combined: CombinedReport): Promise<void>;
1840
2632
  getCombined(id: string): Promise<CombinedReport | undefined>;
1841
2633
  listCombined(filter?: CombinedReportFilter): Promise<CombinedReport[]>;
1842
- private synchronized;
1843
- private load;
1844
- private write;
1845
2634
  }
1846
2635
 
1847
2636
  /**
@@ -1855,12 +2644,24 @@ interface CombinedMeta {
1855
2644
  pipelineRunId?: string;
1856
2645
  taskIds?: string[];
1857
2646
  }
2647
+ interface CollectionDiagnostics {
2648
+ collected: number;
2649
+ accepted: number;
2650
+ rejected: Array<{
2651
+ key: string;
2652
+ reason: string;
2653
+ issues: string[];
2654
+ }>;
2655
+ }
1858
2656
  declare class ReportService {
1859
2657
  private readonly store;
1860
2658
  private readonly log;
2659
+ /** Rejected reports from the last collection (§13 — malformed never enters aggregation). */
2660
+ lastDiagnostics: CollectionDiagnostics;
1861
2661
  constructor(store: ReportStore, log?: Logger);
1862
2662
  get storeRef(): ReportStore;
1863
- /** Normalizes finished tasks into reports (§17 — normalizer). */
2663
+ /** Normalizes finished tasks into reports (§17 — normalizer), validating each
2664
+ * one so malformed reports never reach aggregation (§13). */
1864
2665
  collectFromTasks(tasks: Task[]): Promise<Report[]>;
1865
2666
  saveReports(reports: Report[]): Promise<void>;
1866
2667
  generateCombined(reports: Report[], meta?: CombinedMeta): Promise<CombinedReport | undefined>;
@@ -1888,8 +2689,32 @@ interface AggregateOptions {
1888
2689
  similarityThreshold?: number;
1889
2690
  }
1890
2691
  declare function aggregateReports(reports: Report[], options?: AggregateOptions): CombinedReport;
2692
+ /**
2693
+ * Conflict detection (§14): agents disagreeing about the same finding is a
2694
+ * first-class result. Both positions are preserved — OmniNode never silently
2695
+ * chooses one.
2696
+ */
2697
+ declare function detectConflicts(groups: AggregatedFinding[]): ReportConflict[];
1891
2698
  declare function similar(a: string, b: string, threshold: number): boolean;
1892
2699
 
2700
+ interface ReportValidationIssue {
2701
+ path: string;
2702
+ message: string;
2703
+ }
2704
+ type ReportValidationResult = {
2705
+ valid: true;
2706
+ report: Report;
2707
+ } | {
2708
+ valid: false;
2709
+ issues: ReportValidationIssue[];
2710
+ reason: string;
2711
+ };
2712
+ /** Validates (and normalizes) a report; malformed reports are rejected. */
2713
+ declare function validateReport(value: unknown): ReportValidationResult;
2714
+ /** Normalizes evidence entries (strings or objects) to typed evidence. */
2715
+ declare function normalizeEvidence(input: EvidenceInput[] | undefined): Evidence[] | undefined;
2716
+ declare function normalizeFinding(finding: Finding): Finding;
2717
+
1893
2718
  /** Planner interface and request contract (§18). The planner is replaceable. */
1894
2719
 
1895
2720
  interface PlanRequest {
@@ -1909,6 +2734,50 @@ interface IPlanner {
1909
2734
  plan(request: PlanRequest): Promise<Plan>;
1910
2735
  }
1911
2736
 
2737
+ /**
2738
+ * Planner context builder (§18): assembles everything the planner needs —
2739
+ * the objective, the combined findings from the AI reports (with source
2740
+ * attribution), relevant memory and the role definition — into one
2741
+ * structured text.
2742
+ */
2743
+
2744
+ declare function buildPlannerContext(request: PlanRequest): string;
2745
+
2746
+ declare class HeuristicPlanner implements IPlanner {
2747
+ readonly name = "heuristic";
2748
+ plan(request: PlanRequest): Promise<Plan>;
2749
+ }
2750
+
2751
+ interface ModelPlannerOptions {
2752
+ model: string;
2753
+ chat: ChatFn;
2754
+ /** Extra instruction appended to the system prompt. */
2755
+ instruction?: string;
2756
+ /** Used when the model output is unparseable (or the call fails, if tolerateErrors). */
2757
+ fallback?: IPlanner;
2758
+ log?: Logger;
2759
+ }
2760
+ declare class ModelPlanner implements IPlanner {
2761
+ private readonly options;
2762
+ readonly name = "model";
2763
+ private readonly log;
2764
+ constructor(options: ModelPlannerOptions);
2765
+ plan(request: PlanRequest): Promise<Plan>;
2766
+ private degrade;
2767
+ }
2768
+ /** Extracts and validates the plan JSON from arbitrary model output. */
2769
+ declare function parsePlanJson(text: string): {
2770
+ summary: string;
2771
+ steps: PlanStep[];
2772
+ risks?: string[];
2773
+ notes?: string[];
2774
+ } | undefined;
2775
+
2776
+ /**
2777
+ * Plan persistence (§27 Phase 8 — planner result storage). Same
2778
+ * replaceable-store pattern as the other local stores.
2779
+ */
2780
+
1912
2781
  interface PlanFilter {
1913
2782
  pipelineRunId?: string;
1914
2783
  taskId?: string;
@@ -1918,6 +2787,19 @@ interface PlanStore {
1918
2787
  get(id: string): Promise<Plan | undefined>;
1919
2788
  list(filter?: PlanFilter): Promise<Plan[]>;
1920
2789
  }
2790
+ declare class FilePlanStore extends JsonFileStore<Plan> implements PlanStore {
2791
+ constructor(directory?: string);
2792
+ save(plan: Plan): Promise<void>;
2793
+ get(id: string): Promise<Plan | undefined>;
2794
+ list(filter?: PlanFilter): Promise<Plan[]>;
2795
+ }
2796
+
2797
+ declare function buildPlanner(plannerConfig: AppConfig["project"]["planner"], chat: ChatFn, log?: Logger): IPlanner | undefined;
2798
+
2799
+ /**
2800
+ * Pipeline run persistence (§27 Phase 5 — pipeline state). Same
2801
+ * replaceable-store pattern as the task store, local-first JSON file.
2802
+ */
1921
2803
 
1922
2804
  interface PipelineRunFilter {
1923
2805
  pipelineId?: string;
@@ -1928,19 +2810,13 @@ interface PipelineRunStore {
1928
2810
  get(id: string): Promise<PipelineRun | undefined>;
1929
2811
  list(filter?: PipelineRunFilter): Promise<PipelineRun[]>;
1930
2812
  }
1931
- declare class FilePipelineRunStore implements PipelineRunStore {
1932
- private readonly filePath;
1933
- private queue;
2813
+ declare class FilePipelineRunStore extends JsonFileStore<PipelineRun> implements PipelineRunStore {
1934
2814
  constructor(directory?: string);
1935
2815
  save(run: PipelineRun): Promise<void>;
1936
2816
  get(id: string): Promise<PipelineRun | undefined>;
1937
2817
  list(filter?: PipelineRunFilter): Promise<PipelineRun[]>;
1938
- private synchronized;
1939
- private load;
1940
- private write;
1941
2818
  }
1942
2819
 
1943
- type ChatFn = (modelRef: string, messages: ChatMessage[]) => Promise<string>;
1944
2820
  interface PipelineEngineOptions {
1945
2821
  tasks: TaskEngine;
1946
2822
  agents: AgentRegistry;
@@ -1962,11 +2838,19 @@ interface RunPipelineOptions {
1962
2838
  objective?: string;
1963
2839
  onStep?: (stepRun: PipelineStepRun) => void;
1964
2840
  }
1965
- declare class PipelineEngine {
2841
+ declare class PipelineEngine implements IPipelineExecutor {
1966
2842
  private readonly options;
1967
2843
  private readonly log;
2844
+ /** Runs executing in THIS process — cancellation can terminate them directly. */
2845
+ private readonly activeRuns;
1968
2846
  constructor(options: PipelineEngineOptions);
1969
2847
  get store(): PipelineRunStore;
2848
+ /**
2849
+ * Saves the run while preserving fields that may be set by another process
2850
+ * (e.g. a cancellation request) — an in-memory snapshot must never clobber
2851
+ * externally requested cancellation (§9.2).
2852
+ */
2853
+ private persist;
1970
2854
  /** Structural + semantic validation (§27 Phase 5 — pipeline parser). */
1971
2855
  validate(def: PipelineDefinition): void;
1972
2856
  private assertAcyclic;
@@ -1975,13 +2859,18 @@ declare class PipelineEngine {
1975
2859
  * dependencies, which enable parallel branches.
1976
2860
  */
1977
2861
  private effectiveDependencies;
1978
- run(def: PipelineDefinition, options?: RunPipelineOptions): Promise<PipelineRun>;
2862
+ run(def: PipelineDefinition, options?: PipelineRunOptions): Promise<PipelineRun>;
2863
+ /** First-class cancellation (§9.2): requests cancellation and terminates
2864
+ * tasks that are running in this process immediately. */
2865
+ cancel(runId: string): Promise<void>;
1979
2866
  get(runId: string): Promise<PipelineRun | undefined>;
1980
2867
  listRuns(filter?: {
1981
2868
  pipelineId?: string;
1982
2869
  }): Promise<PipelineRun[]>;
1983
2870
  private shouldRun;
1984
2871
  private executeStep;
2872
+ /** Registers tasks created for a step as live, so cancellation can terminate them (§9.2). */
2873
+ private trackLiveTasks;
1985
2874
  private executeStepOnce;
1986
2875
  /** Research fan-out: one task per agent, in parallel (§15). */
1987
2876
  private runFanOut;
@@ -1994,6 +2883,25 @@ declare function createDefaultChatFn(providers: AppConfig["project"]["providers"
1994
2883
 
1995
2884
  declare function buildPipelineEngine(config: AppConfig, log?: Logger): PipelineEngine;
1996
2885
 
1997
- declare const OMNINODE_VERSION = "1.0.0";
2886
+ /**
2887
+ * Persistence layer (v2 Phase 1): one entry point to every local store.
2888
+ *
2889
+ * All stores are interfaces with a local JSON default
2890
+ * (TaskStore, PipelineRunStore, ReportStore, PlanStore, IMemoryProvider,
2891
+ * AuditSink) — see docs/API.md for the inventory and stability status.
2892
+ */
2893
+
2894
+ /** Bundles every store for a single project directory. */
2895
+ declare class ProjectStores {
2896
+ readonly tasks: FileTaskStore;
2897
+ readonly pipelineRuns: FilePipelineRunStore;
2898
+ readonly reports: FileReportStore;
2899
+ readonly plans: FilePlanStore;
2900
+ readonly memory: LocalMemoryProvider;
2901
+ readonly audit: FileAuditLog;
2902
+ constructor(directory?: string);
2903
+ }
2904
+
2905
+ declare const OMNINODE_VERSION = "2.0.0-alpha.10";
1998
2906
 
1999
- export { type AgentConfig, type AgentConfigYaml, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigYaml, type AuditAction, type AuditEvent, type AuditSink, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatUsage, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, ConsoleLogSink, type CreateTaskInput, type DiscoveryResult, type EnvelopeMeta, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FileReportStore, FileTaskStore, type Finding, type FindingSeverity, type FindingSource, type HttpRequestOptions, type HttpResponse, type IAgent, type IChatProvider, type IMemoryProvider, type IProvider, type LoadConfigOptions, LocalMemoryProvider, type LogLevel, type LogSink, Logger, type LoggerOptions, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryQuery, type MemoryScope, MemoryService, type MessageEnvelope, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunFilter, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type Plan, type PlanStep, type PlannerConfigYaml, PlannerError, ProcessAgent, type Project, type ProjectConfigYaml, ProtocolError, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderHealth, type ProviderStatus, type ProviderType, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportFilter, ReportService, type ReportStore, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, authHeaders, buildAgentRegistry, buildPipelineEngine, buildRoleRegistry, composeTaskText, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, defaultProjectConfigYaml, expandEnvRefs, extractReportFromText, findConfigFile, isOmniNodeError, keywords, loadConfig, logger, pipelineConfigSchema, pipelineStepConfigSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, registryKey, requestJson, resolveApiKey, roleConfigSchema, similar };
2907
+ export { AgentAdapterRegistry, type AgentConfig, type AgentConfigYaml, type AgentDescriptor, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigYaml, type ArtifactKind, type ArtifactPayload, type AskedQuestion, type AuditAction, type AuditEvent, type AuditSink, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatStreamChunk, type ChatUsage, type CollectionDiagnostics, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, type ConflictPosition, ConsoleLogSink, type CreateTaskInput, type CwdValidation, DEFAULT_MAX_OUTPUT_BYTES, type DecodeResult, type DiscoveryResult, type EnvPolicy, type EnvelopeMeta, type Evidence, type EvidenceInput, type EvidenceKind, type ExecutionRecord, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FilePlanStore, FileReportStore, FileTaskStore, type Finding, type FindingOrigin, type FindingSeverity, type FindingSource, type HelloResult, HeuristicPlanner, type HttpRequestOptions, type HttpResponse, type IAgent, type IAgentAdapter, type IChatProvider, type IMemoryProvider, type IPipelineExecutor, type IPlanner, type IProvider, type JsonDocument, JsonFileStore, type JsonFileStoreOptions, type LoadConfigOptions, LocalMemoryProvider, type LogLevel, type LogSink, Logger, type LoggerOptions, MAX_CONTEXT_CHARS, MAX_MESSAGE_BYTES, type MemoryCategory, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryProviderMetadata, type MemoryQuery, type MemoryScope, MemoryService, type MemoryServiceOptions, type MemoryTaskContext, type MessageEnvelope, type Modality, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelPlanner, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, PROTOCOL_V2, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunAttempt, type PipelineRunFilter, type PipelineRunOptions, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type Plan, type PlanFilter, type PlanRequest, type PlanStep, type PlanStore, type PlannerConfigYaml, PlannerError, ProcessAgent, ProcessAgentAdapter, type Project, type ProjectConfigYaml, ProjectStores, type ProtocolAgentToNodeType, ProtocolDecoder, type ProtocolEnvelope, ProtocolError, type ProtocolMessageType, type ProtocolNodeToAgentType, ProtocolSession, type ProtocolViolation, type ProtocolViolationCode, type ProviderAuthentication, type ProviderCapability, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderErrorKind, type ProviderHealth, type ProviderStatus, type ProviderType, type QuestionPayload, type QuestionResponder, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportArtifact, type ReportConflict, type ReportFilter, type ReportPayload, ReportService, type ReportStore, type ReportValidationIssue, type ReportValidationResult, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, SUPPORTED_PROTOCOL_VERSIONS, type SessionIds, TERMINAL_TASK_STATUSES, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskPayload, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, authHeaders, buildAgentRegistry, buildChildEnv, buildHello, buildHelloAck, buildPipelineEngine, buildPlanner, buildPlannerContext, buildRoleRegistry, composeTaskText, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, decodeMessage, decodeStream, defaultMetadata, defaultProjectConfigYaml, defaultSearch, describeExit, detectConflicts, encodeMessage, envelope, expandEnvRefs, extractMessage, extractReportFromText, findConfigFile, isNetworkError, isOmniNodeError, isRetryable, isSupportedProtocol, isTimeoutError, keywords, killTree, kindFromStatus, loadConfig, logger, newMessageId, normalizeEvidence, normalizeFinding, parseHello, parsePlanJson, parseRetryAfter, pipelineConfigSchema, pipelineStepConfigSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, providerHttpError, providerTransportError, registryKey, requestJson, requireCompletion, resolveApiKey, resolveEnvPolicy, roleConfigSchema, sanitizeChunk, similar, validateEnvelope, validateReport, validateWorkingDirectory };