@hilbras/omninode 2.0.0-alpha.1 → 2.0.0-alpha.11

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+). */
@@ -177,32 +369,73 @@ interface ChatResponse {
177
369
  * layer so adapters (e.g. planner) never depend on engine modules.
178
370
  */
179
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
+ }
180
380
 
181
381
  /**
182
- * Memory abstraction. Remembera is the preferred Hilbras integration, but the
183
- * 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.
184
387
  */
185
- 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";
186
391
  interface MemoryEntry {
187
392
  key: string;
188
393
  scope: MemoryScope;
189
394
  content: string;
395
+ /** Structured category, when the backend supports it. */
396
+ category?: MemoryCategory;
190
397
  tags?: string[];
191
398
  createdAt?: string;
192
399
  updatedAt?: string;
193
400
  metadata?: Record<string, unknown>;
194
401
  }
195
402
  interface MemoryQuery {
403
+ /** Free-text relevance query. */
404
+ text?: string;
196
405
  scope?: MemoryScope;
406
+ category?: MemoryCategory;
197
407
  tags?: string[];
198
- /** Free-text relevance query; implementations decide ranking. */
199
- text?: string;
200
408
  limit?: number;
201
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
+ */
202
423
  interface IMemoryProvider {
203
424
  readonly name: string;
204
- /** 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}. */
205
437
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
438
+ /** @deprecated v1 alias of {@link store}. */
206
439
  write(entry: MemoryEntry): Promise<void>;
207
440
  }
208
441
 
@@ -215,21 +448,52 @@ interface ModelCapabilities {
215
448
  embeddings?: boolean;
216
449
  }
217
450
  type ModelStatus = "available" | "unavailable" | "deprecated";
451
+ type Modality = "text" | "image" | "audio" | "video" | "embedding";
452
+ /** Model metadata (roadmap §10, Model Metadata). */
218
453
  interface ModelInfo {
219
454
  /** Name of the provider this model belongs to. */
220
455
  provider: string;
221
456
  /** Provider-specific model identifier, e.g. "qwen3-coder". */
222
457
  id: string;
223
458
  displayName?: string;
459
+ /** Human-readable model name reported by the provider, when available. */
460
+ name?: string;
224
461
  capabilities?: ModelCapabilities;
225
462
  contextWindow?: number;
463
+ inputTypes?: Modality[];
464
+ outputTypes?: Modality[];
465
+ supportsTools?: boolean;
466
+ supportsVision?: boolean;
467
+ supportsReasoning?: boolean;
468
+ supportsStructuredOutput?: boolean;
469
+ supportsStreaming?: boolean;
226
470
  status?: ModelStatus;
227
471
  metadata?: Record<string, unknown>;
228
472
  }
229
473
 
230
474
  /** Task system: every operation becomes a Task (§13). */
231
475
 
232
- 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
+ }
233
497
  interface TaskContext {
234
498
  project?: string;
235
499
  /** Paths or globs relevant to the task. */
@@ -262,6 +526,12 @@ interface Task {
262
526
  status: TaskStatus;
263
527
  createdAt: string;
264
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[];
265
535
  result?: TaskResult;
266
536
  }
267
537
 
@@ -282,6 +552,8 @@ interface PipelineStep {
282
552
  dependsOn?: string[];
283
553
  condition?: PipelineStepCondition;
284
554
  retries?: number;
555
+ /** Constraints handed to the planner for plan steps (§15). */
556
+ constraints?: string[];
285
557
  }
286
558
  interface PipelineDefinition {
287
559
  id: string;
@@ -292,19 +564,43 @@ interface PipelineDefinition {
292
564
  role?: string;
293
565
  steps: PipelineStep[];
294
566
  }
295
- type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
567
+ /**
568
+ * Run status. "partial" means the run finished but some step outcome was
569
+ * incomplete or unprovable (partial fan-out, unknown task state) — the
570
+ * authoritative detail always lives in `stepRuns`/`taskRuns`.
571
+ */
572
+ type PipelineRunStatus = "pending" | "running" | "completed" | "failed" | "partial" | "cancelled";
573
+ /**
574
+ * One step execution inside a run (§9.1 — Step Run is NOT the Step).
575
+ */
296
576
  interface PipelineStepRun {
297
577
  stepId: string;
298
578
  status: TaskStatus;
299
579
  /** Tasks created for this step (research fans out to several). */
300
580
  taskIds?: string[];
581
+ /** Execution ids of the tasks this step created, for correlation (§6.5). */
582
+ executionIds?: string[];
583
+ /** Which attempt of this step produced this record (1 = first try). */
584
+ attempt?: number;
301
585
  /** Set on plan steps that produced a stored plan (§18). */
302
586
  planId?: string;
303
587
  error?: string;
304
588
  }
589
+ /** One execution attempt of a run (§9.1 — Attempt is not the Run). */
590
+ interface PipelineRunAttempt {
591
+ attempt: number;
592
+ startedAt: string;
593
+ finishedAt?: string;
594
+ status: PipelineRunStatus;
595
+ }
305
596
  interface PipelineRun {
306
597
  id: string;
307
598
  pipelineId: string;
599
+ /** Execution attempt counter: retries of the same run increment it. */
600
+ attempt: number;
601
+ /** Set when cancellation was requested; the run stops at the next check point. */
602
+ cancellationRequested?: boolean;
603
+ cancellationRequestedAt?: string;
308
604
  /** The objective this run is executing (persisted for retries). */
309
605
  objective?: string;
310
606
  status: PipelineRunStatus;
@@ -319,6 +615,28 @@ interface PipelineRun {
319
615
  planId?: string;
320
616
  /** Outcome summary of the final executed step (§28 — Result). */
321
617
  resultSummary?: string;
618
+ /** Per-attempt history (§9.1). */
619
+ attempts?: PipelineRunAttempt[];
620
+ }
621
+ /**
622
+ * Executor contract (roadmap §9.1 / §9.2): a Pipeline definition, a Run of
623
+ * it, Steps, Step Runs and Attempts are distinct concepts; this interface is
624
+ * what orchestration code depends on.
625
+ */
626
+ interface IPipelineExecutor {
627
+ validate(definition: PipelineDefinition): void;
628
+ run(definition: PipelineDefinition, options?: PipelineRunOptions): Promise<PipelineRun>;
629
+ cancel(runId: string): Promise<void>;
630
+ get(runId: string): Promise<PipelineRun | undefined>;
631
+ listRuns(filter?: {
632
+ pipelineId?: string;
633
+ }): Promise<PipelineRun[]>;
634
+ }
635
+ interface PipelineRunOptions {
636
+ objective?: string;
637
+ onStep?: (stepRun: PipelineStepRun) => void;
638
+ /** Total run attempts (1 = no automatic rerun of the whole run). */
639
+ maxAttempts?: number;
322
640
  }
323
641
 
324
642
  /** Plan types: the final implementation plan produced by the planner layer (§18). */
@@ -338,6 +656,8 @@ interface PlanStep {
338
656
  interface Plan {
339
657
  id: string;
340
658
  objective: string;
659
+ /** Explicit goal statement (§15, Planner Output). */
660
+ goal?: string;
341
661
  summary: string;
342
662
  steps: PlanStep[];
343
663
  risks?: string[];
@@ -459,7 +779,20 @@ interface Project {
459
779
 
460
780
  type ProviderType = "openai-compatible" | "omnihilbras" | "openrouter" | "local" | "custom";
461
781
  type ProviderHealth = "unknown" | "healthy" | "degraded" | "unreachable";
782
+ /** Declared provider capabilities (roadmap §10, Provider Interface). */
783
+ type ProviderCapability = "chat" | "models" | "streaming" | "tools" | "embeddings" | "vision";
784
+ /** Normalized authentication description — never contains a secret value. */
785
+ interface ProviderAuthentication {
786
+ /** How the provider authenticates. */
787
+ method: "bearer" | "none" | "custom";
788
+ /** Environment variable that holds the credential, if any. */
789
+ envVar?: string;
790
+ /** True when the referenced variable is currently set. */
791
+ configured: boolean;
792
+ }
462
793
  interface ProviderConfig {
794
+ /** Stable identifier used in records and references (defaults to `name`). */
795
+ providerId?: string;
463
796
  /** Unique name used in project configuration and the model registry. */
464
797
  name: string;
465
798
  type: ProviderType;
@@ -470,6 +803,10 @@ interface ProviderConfig {
470
803
  */
471
804
  apiKeyEnvVar?: string;
472
805
  headers?: Record<string, string>;
806
+ /** Provider-level request timeout in ms (distinct from agent/pipeline budgets). */
807
+ timeoutMs?: number;
808
+ /** Capabilities declared for this provider (discovered ones are merged in). */
809
+ capabilities?: ProviderCapability[];
473
810
  enabled?: boolean;
474
811
  metadata?: Record<string, unknown>;
475
812
  }
@@ -483,17 +820,33 @@ interface ProviderStatus {
483
820
  lastCheckedAt?: string;
484
821
  message?: string;
485
822
  }
486
- /** Contract every provider adapter implements (Phase 1+). */
823
+ /** Contract every provider adapter implements (roadmap §10). */
487
824
  interface IProvider {
488
825
  readonly config: ProviderConfig;
826
+ /** Stable identifier of this provider. */
827
+ readonly providerId: string;
828
+ /** Normalized authentication description (no secret values). */
829
+ readonly authentication: ProviderAuthentication;
830
+ /**
831
+ * Connect: authenticate and discover models (roadmap §10, Model Discovery).
832
+ * Returns the discovered models.
833
+ */
834
+ connect(): Promise<ModelInfo[]>;
489
835
  /** Discover models exposed by this provider. */
490
836
  listModels(): Promise<ModelInfo[]>;
837
+ /** Fetch a single model's metadata (from discovery; re-discovers if unknown). */
838
+ getModel(modelId: string): Promise<ModelInfo | undefined>;
491
839
  /** Check connectivity and authentication. */
492
840
  healthCheck(): Promise<ProviderStatus>;
493
841
  }
494
842
  /** Contract for providers that can run chat completions (foundation for planning). */
495
843
  interface IChatProvider extends IProvider {
496
844
  chat(request: ChatRequest): Promise<ChatResponse>;
845
+ /**
846
+ * Stream a completion where the provider supports it (§11). Chunks are
847
+ * delivered in order; the resolved ChatResponse carries the assembled text.
848
+ */
849
+ stream?(request: ChatRequest, onChunk: (chunk: ChatStreamChunk) => void): Promise<ChatResponse>;
497
850
  }
498
851
 
499
852
  /** Typed error hierarchy shared across the whole codebase (§4.1 — error model). */
@@ -578,6 +931,7 @@ declare const providerConfigSchema: z.ZodObject<{
578
931
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
579
932
  base_url: z.ZodString;
580
933
  api_key_env_var: z.ZodOptional<z.ZodString>;
934
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
581
935
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
582
936
  enabled: z.ZodOptional<z.ZodBoolean>;
583
937
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -585,18 +939,20 @@ declare const providerConfigSchema: z.ZodObject<{
585
939
  name: string;
586
940
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
587
941
  base_url: string;
942
+ metadata?: Record<string, unknown> | undefined;
588
943
  api_key_env_var?: string | undefined;
944
+ timeout_ms?: number | undefined;
589
945
  headers?: Record<string, string> | undefined;
590
946
  enabled?: boolean | undefined;
591
- metadata?: Record<string, unknown> | undefined;
592
947
  }, {
593
948
  name: string;
594
949
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
595
950
  base_url: string;
951
+ metadata?: Record<string, unknown> | undefined;
596
952
  api_key_env_var?: string | undefined;
953
+ timeout_ms?: number | undefined;
597
954
  headers?: Record<string, string> | undefined;
598
955
  enabled?: boolean | undefined;
599
- metadata?: Record<string, unknown> | undefined;
600
956
  }>;
601
957
  declare const agentConfigSchema: z.ZodObject<{
602
958
  name: z.ZodString;
@@ -609,29 +965,44 @@ declare const agentConfigSchema: z.ZodObject<{
609
965
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
610
966
  timeout_ms: z.ZodOptional<z.ZodNumber>;
611
967
  inherit_env: z.ZodOptional<z.ZodBoolean>;
968
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
969
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
970
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
971
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
972
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
612
973
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
613
974
  }, "strict", z.ZodTypeAny, {
614
975
  name: string;
615
976
  type: "native" | "process" | "cli";
616
- input_mode: "stdin" | "arg" | "protocol";
617
- metadata?: Record<string, unknown> | undefined;
977
+ input_mode: "protocol" | "stdin" | "arg";
618
978
  command?: string | undefined;
979
+ metadata?: Record<string, unknown> | undefined;
980
+ timeout_ms?: number | undefined;
619
981
  args?: string[] | undefined;
620
982
  cwd?: string | undefined;
621
983
  env?: Record<string, string> | undefined;
622
- timeout_ms?: number | undefined;
623
984
  inherit_env?: boolean | undefined;
985
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
986
+ env_allowlist?: string[] | undefined;
987
+ env_denylist?: string[] | undefined;
988
+ max_output_bytes?: number | undefined;
989
+ allow_external_cwd?: boolean | undefined;
624
990
  }, {
625
991
  name: string;
626
- type?: "native" | "process" | "cli" | undefined;
627
- metadata?: Record<string, unknown> | undefined;
628
992
  command?: string | undefined;
993
+ metadata?: Record<string, unknown> | undefined;
994
+ type?: "native" | "process" | "cli" | undefined;
995
+ timeout_ms?: number | undefined;
629
996
  args?: string[] | undefined;
630
997
  cwd?: string | undefined;
631
998
  env?: Record<string, string> | undefined;
632
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
633
- timeout_ms?: number | undefined;
999
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
634
1000
  inherit_env?: boolean | undefined;
1001
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1002
+ env_allowlist?: string[] | undefined;
1003
+ env_denylist?: string[] | undefined;
1004
+ max_output_bytes?: number | undefined;
1005
+ allow_external_cwd?: boolean | undefined;
635
1006
  }>;
636
1007
  declare const roleConfigSchema: z.ZodObject<{
637
1008
  id: z.ZodString;
@@ -670,6 +1041,8 @@ declare const pipelineStepConfigSchema: z.ZodObject<{
670
1041
  depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
671
1042
  retries: z.ZodOptional<z.ZodNumber>;
672
1043
  condition: z.ZodOptional<z.ZodEnum<["always", "on-success", "on-failure"]>>;
1044
+ /** Constraints passed to the planner for plan steps (§15). */
1045
+ constraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
673
1046
  }, "strict", z.ZodTypeAny, {
674
1047
  id: string;
675
1048
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -679,6 +1052,7 @@ declare const pipelineStepConfigSchema: z.ZodObject<{
679
1052
  depends_on?: string[] | undefined;
680
1053
  retries?: number | undefined;
681
1054
  condition?: "always" | "on-success" | "on-failure" | undefined;
1055
+ constraints?: string[] | undefined;
682
1056
  }, {
683
1057
  id: string;
684
1058
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -688,6 +1062,7 @@ declare const pipelineStepConfigSchema: z.ZodObject<{
688
1062
  depends_on?: string[] | undefined;
689
1063
  retries?: number | undefined;
690
1064
  condition?: "always" | "on-success" | "on-failure" | undefined;
1065
+ constraints?: string[] | undefined;
691
1066
  }>;
692
1067
  declare const pipelineConfigSchema: z.ZodObject<{
693
1068
  id: z.ZodString;
@@ -703,6 +1078,8 @@ declare const pipelineConfigSchema: z.ZodObject<{
703
1078
  depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
704
1079
  retries: z.ZodOptional<z.ZodNumber>;
705
1080
  condition: z.ZodOptional<z.ZodEnum<["always", "on-success", "on-failure"]>>;
1081
+ /** Constraints passed to the planner for plan steps (§15). */
1082
+ constraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
706
1083
  }, "strict", z.ZodTypeAny, {
707
1084
  id: string;
708
1085
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -712,6 +1089,7 @@ declare const pipelineConfigSchema: z.ZodObject<{
712
1089
  depends_on?: string[] | undefined;
713
1090
  retries?: number | undefined;
714
1091
  condition?: "always" | "on-success" | "on-failure" | undefined;
1092
+ constraints?: string[] | undefined;
715
1093
  }, {
716
1094
  id: string;
717
1095
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -721,6 +1099,7 @@ declare const pipelineConfigSchema: z.ZodObject<{
721
1099
  depends_on?: string[] | undefined;
722
1100
  retries?: number | undefined;
723
1101
  condition?: "always" | "on-success" | "on-failure" | undefined;
1102
+ constraints?: string[] | undefined;
724
1103
  }>, "many">;
725
1104
  }, "strict", z.ZodTypeAny, {
726
1105
  id: string;
@@ -733,9 +1112,10 @@ declare const pipelineConfigSchema: z.ZodObject<{
733
1112
  depends_on?: string[] | undefined;
734
1113
  retries?: number | undefined;
735
1114
  condition?: "always" | "on-success" | "on-failure" | undefined;
1115
+ constraints?: string[] | undefined;
736
1116
  }[];
737
- role?: string | undefined;
738
1117
  name?: string | undefined;
1118
+ role?: string | undefined;
739
1119
  objective?: string | undefined;
740
1120
  }, {
741
1121
  id: string;
@@ -748,9 +1128,10 @@ declare const pipelineConfigSchema: z.ZodObject<{
748
1128
  depends_on?: string[] | undefined;
749
1129
  retries?: number | undefined;
750
1130
  condition?: "always" | "on-success" | "on-failure" | undefined;
1131
+ constraints?: string[] | undefined;
751
1132
  }[];
752
- role?: string | undefined;
753
1133
  name?: string | undefined;
1134
+ role?: string | undefined;
754
1135
  objective?: string | undefined;
755
1136
  }>;
756
1137
  declare const plannerConfigSchema: z.ZodObject<{
@@ -773,6 +1154,7 @@ declare const projectConfigSchema: z.ZodObject<{
773
1154
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
774
1155
  base_url: z.ZodString;
775
1156
  api_key_env_var: z.ZodOptional<z.ZodString>;
1157
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
776
1158
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
777
1159
  enabled: z.ZodOptional<z.ZodBoolean>;
778
1160
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -780,18 +1162,20 @@ declare const projectConfigSchema: z.ZodObject<{
780
1162
  name: string;
781
1163
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
782
1164
  base_url: string;
1165
+ metadata?: Record<string, unknown> | undefined;
783
1166
  api_key_env_var?: string | undefined;
1167
+ timeout_ms?: number | undefined;
784
1168
  headers?: Record<string, string> | undefined;
785
1169
  enabled?: boolean | undefined;
786
- metadata?: Record<string, unknown> | undefined;
787
1170
  }, {
788
1171
  name: string;
789
1172
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
790
1173
  base_url: string;
1174
+ metadata?: Record<string, unknown> | undefined;
791
1175
  api_key_env_var?: string | undefined;
1176
+ timeout_ms?: number | undefined;
792
1177
  headers?: Record<string, string> | undefined;
793
1178
  enabled?: boolean | undefined;
794
- metadata?: Record<string, unknown> | undefined;
795
1179
  }>, "many">>;
796
1180
  agents: z.ZodDefault<z.ZodArray<z.ZodObject<{
797
1181
  name: z.ZodString;
@@ -804,29 +1188,44 @@ declare const projectConfigSchema: z.ZodObject<{
804
1188
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
805
1189
  timeout_ms: z.ZodOptional<z.ZodNumber>;
806
1190
  inherit_env: z.ZodOptional<z.ZodBoolean>;
1191
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
1192
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1193
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1194
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
1195
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
807
1196
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
808
1197
  }, "strict", z.ZodTypeAny, {
809
1198
  name: string;
810
1199
  type: "native" | "process" | "cli";
811
- input_mode: "stdin" | "arg" | "protocol";
812
- metadata?: Record<string, unknown> | undefined;
1200
+ input_mode: "protocol" | "stdin" | "arg";
813
1201
  command?: string | undefined;
1202
+ metadata?: Record<string, unknown> | undefined;
1203
+ timeout_ms?: number | undefined;
814
1204
  args?: string[] | undefined;
815
1205
  cwd?: string | undefined;
816
1206
  env?: Record<string, string> | undefined;
817
- timeout_ms?: number | undefined;
818
1207
  inherit_env?: boolean | undefined;
1208
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1209
+ env_allowlist?: string[] | undefined;
1210
+ env_denylist?: string[] | undefined;
1211
+ max_output_bytes?: number | undefined;
1212
+ allow_external_cwd?: boolean | undefined;
819
1213
  }, {
820
1214
  name: string;
821
- type?: "native" | "process" | "cli" | undefined;
822
- metadata?: Record<string, unknown> | undefined;
823
1215
  command?: string | undefined;
1216
+ metadata?: Record<string, unknown> | undefined;
1217
+ type?: "native" | "process" | "cli" | undefined;
1218
+ timeout_ms?: number | undefined;
824
1219
  args?: string[] | undefined;
825
1220
  cwd?: string | undefined;
826
1221
  env?: Record<string, string> | undefined;
827
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
828
- timeout_ms?: number | undefined;
1222
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
829
1223
  inherit_env?: boolean | undefined;
1224
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1225
+ env_allowlist?: string[] | undefined;
1226
+ env_denylist?: string[] | undefined;
1227
+ max_output_bytes?: number | undefined;
1228
+ allow_external_cwd?: boolean | undefined;
830
1229
  }>, "many">>;
831
1230
  roles: z.ZodDefault<z.ZodArray<z.ZodObject<{
832
1231
  id: z.ZodString;
@@ -870,6 +1269,8 @@ declare const projectConfigSchema: z.ZodObject<{
870
1269
  depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
871
1270
  retries: z.ZodOptional<z.ZodNumber>;
872
1271
  condition: z.ZodOptional<z.ZodEnum<["always", "on-success", "on-failure"]>>;
1272
+ /** Constraints passed to the planner for plan steps (§15). */
1273
+ constraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
873
1274
  }, "strict", z.ZodTypeAny, {
874
1275
  id: string;
875
1276
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -879,6 +1280,7 @@ declare const projectConfigSchema: z.ZodObject<{
879
1280
  depends_on?: string[] | undefined;
880
1281
  retries?: number | undefined;
881
1282
  condition?: "always" | "on-success" | "on-failure" | undefined;
1283
+ constraints?: string[] | undefined;
882
1284
  }, {
883
1285
  id: string;
884
1286
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -888,6 +1290,7 @@ declare const projectConfigSchema: z.ZodObject<{
888
1290
  depends_on?: string[] | undefined;
889
1291
  retries?: number | undefined;
890
1292
  condition?: "always" | "on-success" | "on-failure" | undefined;
1293
+ constraints?: string[] | undefined;
891
1294
  }>, "many">;
892
1295
  }, "strict", z.ZodTypeAny, {
893
1296
  id: string;
@@ -900,9 +1303,10 @@ declare const projectConfigSchema: z.ZodObject<{
900
1303
  depends_on?: string[] | undefined;
901
1304
  retries?: number | undefined;
902
1305
  condition?: "always" | "on-success" | "on-failure" | undefined;
1306
+ constraints?: string[] | undefined;
903
1307
  }[];
904
- role?: string | undefined;
905
1308
  name?: string | undefined;
1309
+ role?: string | undefined;
906
1310
  objective?: string | undefined;
907
1311
  }, {
908
1312
  id: string;
@@ -915,9 +1319,10 @@ declare const projectConfigSchema: z.ZodObject<{
915
1319
  depends_on?: string[] | undefined;
916
1320
  retries?: number | undefined;
917
1321
  condition?: "always" | "on-success" | "on-failure" | undefined;
1322
+ constraints?: string[] | undefined;
918
1323
  }[];
919
- role?: string | undefined;
920
1324
  name?: string | undefined;
1325
+ role?: string | undefined;
921
1326
  objective?: string | undefined;
922
1327
  }>, "many">>;
923
1328
  planner: z.ZodOptional<z.ZodObject<{
@@ -937,37 +1342,47 @@ declare const projectConfigSchema: z.ZodObject<{
937
1342
  provider: z.ZodDefault<z.ZodString>;
938
1343
  base_url: z.ZodOptional<z.ZodString>;
939
1344
  api_key_env_var: z.ZodOptional<z.ZodString>;
1345
+ /** When true, memory failures fail tasks instead of being tolerated (§12). */
1346
+ required: z.ZodOptional<z.ZodBoolean>;
940
1347
  }, "strict", z.ZodTypeAny, {
941
1348
  provider: string;
942
1349
  base_url?: string | undefined;
943
1350
  api_key_env_var?: string | undefined;
1351
+ required?: boolean | undefined;
944
1352
  }, {
945
1353
  base_url?: string | undefined;
946
1354
  api_key_env_var?: string | undefined;
947
1355
  provider?: string | undefined;
1356
+ required?: boolean | undefined;
948
1357
  }>>;
949
1358
  }, "strict", z.ZodTypeAny, {
950
1359
  name: string;
951
1360
  agents: {
952
1361
  name: string;
953
1362
  type: "native" | "process" | "cli";
954
- input_mode: "stdin" | "arg" | "protocol";
955
- metadata?: Record<string, unknown> | undefined;
1363
+ input_mode: "protocol" | "stdin" | "arg";
956
1364
  command?: string | undefined;
1365
+ metadata?: Record<string, unknown> | undefined;
1366
+ timeout_ms?: number | undefined;
957
1367
  args?: string[] | undefined;
958
1368
  cwd?: string | undefined;
959
1369
  env?: Record<string, string> | undefined;
960
- timeout_ms?: number | undefined;
961
1370
  inherit_env?: boolean | undefined;
1371
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1372
+ env_allowlist?: string[] | undefined;
1373
+ env_denylist?: string[] | undefined;
1374
+ max_output_bytes?: number | undefined;
1375
+ allow_external_cwd?: boolean | undefined;
962
1376
  }[];
963
1377
  providers: {
964
1378
  name: string;
965
1379
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
966
1380
  base_url: string;
1381
+ metadata?: Record<string, unknown> | undefined;
967
1382
  api_key_env_var?: string | undefined;
1383
+ timeout_ms?: number | undefined;
968
1384
  headers?: Record<string, string> | undefined;
969
1385
  enabled?: boolean | undefined;
970
- metadata?: Record<string, unknown> | undefined;
971
1386
  }[];
972
1387
  roles: {
973
1388
  name: string;
@@ -990,9 +1405,10 @@ declare const projectConfigSchema: z.ZodObject<{
990
1405
  depends_on?: string[] | undefined;
991
1406
  retries?: number | undefined;
992
1407
  condition?: "always" | "on-success" | "on-failure" | undefined;
1408
+ constraints?: string[] | undefined;
993
1409
  }[];
994
- role?: string | undefined;
995
1410
  name?: string | undefined;
1411
+ role?: string | undefined;
996
1412
  objective?: string | undefined;
997
1413
  }[];
998
1414
  planner?: {
@@ -1004,29 +1420,36 @@ declare const projectConfigSchema: z.ZodObject<{
1004
1420
  provider: string;
1005
1421
  base_url?: string | undefined;
1006
1422
  api_key_env_var?: string | undefined;
1423
+ required?: boolean | undefined;
1007
1424
  } | undefined;
1008
1425
  }, {
1009
1426
  name: string;
1010
1427
  agents?: {
1011
1428
  name: string;
1012
- type?: "native" | "process" | "cli" | undefined;
1013
- metadata?: Record<string, unknown> | undefined;
1014
1429
  command?: string | undefined;
1430
+ metadata?: Record<string, unknown> | undefined;
1431
+ type?: "native" | "process" | "cli" | undefined;
1432
+ timeout_ms?: number | undefined;
1015
1433
  args?: string[] | undefined;
1016
1434
  cwd?: string | undefined;
1017
1435
  env?: Record<string, string> | undefined;
1018
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1019
- timeout_ms?: number | undefined;
1436
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1020
1437
  inherit_env?: boolean | undefined;
1438
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1439
+ env_allowlist?: string[] | undefined;
1440
+ env_denylist?: string[] | undefined;
1441
+ max_output_bytes?: number | undefined;
1442
+ allow_external_cwd?: boolean | undefined;
1021
1443
  }[] | undefined;
1022
1444
  providers?: {
1023
1445
  name: string;
1024
1446
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1025
1447
  base_url: string;
1448
+ metadata?: Record<string, unknown> | undefined;
1026
1449
  api_key_env_var?: string | undefined;
1450
+ timeout_ms?: number | undefined;
1027
1451
  headers?: Record<string, string> | undefined;
1028
1452
  enabled?: boolean | undefined;
1029
- metadata?: Record<string, unknown> | undefined;
1030
1453
  }[] | undefined;
1031
1454
  roles?: {
1032
1455
  name: string;
@@ -1049,9 +1472,10 @@ declare const projectConfigSchema: z.ZodObject<{
1049
1472
  depends_on?: string[] | undefined;
1050
1473
  retries?: number | undefined;
1051
1474
  condition?: "always" | "on-success" | "on-failure" | undefined;
1475
+ constraints?: string[] | undefined;
1052
1476
  }[];
1053
- role?: string | undefined;
1054
1477
  name?: string | undefined;
1478
+ role?: string | undefined;
1055
1479
  objective?: string | undefined;
1056
1480
  }[] | undefined;
1057
1481
  planner?: {
@@ -1063,6 +1487,7 @@ declare const projectConfigSchema: z.ZodObject<{
1063
1487
  base_url?: string | undefined;
1064
1488
  api_key_env_var?: string | undefined;
1065
1489
  provider?: string | undefined;
1490
+ required?: boolean | undefined;
1066
1491
  } | undefined;
1067
1492
  }>;
1068
1493
  declare const appConfigSchema: z.ZodObject<{
@@ -1073,6 +1498,7 @@ declare const appConfigSchema: z.ZodObject<{
1073
1498
  type: z.ZodEnum<["openai-compatible", "omnihilbras", "openrouter", "local", "custom"]>;
1074
1499
  base_url: z.ZodString;
1075
1500
  api_key_env_var: z.ZodOptional<z.ZodString>;
1501
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
1076
1502
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1077
1503
  enabled: z.ZodOptional<z.ZodBoolean>;
1078
1504
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
@@ -1080,18 +1506,20 @@ declare const appConfigSchema: z.ZodObject<{
1080
1506
  name: string;
1081
1507
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1082
1508
  base_url: string;
1509
+ metadata?: Record<string, unknown> | undefined;
1083
1510
  api_key_env_var?: string | undefined;
1511
+ timeout_ms?: number | undefined;
1084
1512
  headers?: Record<string, string> | undefined;
1085
1513
  enabled?: boolean | undefined;
1086
- metadata?: Record<string, unknown> | undefined;
1087
1514
  }, {
1088
1515
  name: string;
1089
1516
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1090
1517
  base_url: string;
1518
+ metadata?: Record<string, unknown> | undefined;
1091
1519
  api_key_env_var?: string | undefined;
1520
+ timeout_ms?: number | undefined;
1092
1521
  headers?: Record<string, string> | undefined;
1093
1522
  enabled?: boolean | undefined;
1094
- metadata?: Record<string, unknown> | undefined;
1095
1523
  }>, "many">>;
1096
1524
  agents: z.ZodDefault<z.ZodArray<z.ZodObject<{
1097
1525
  name: z.ZodString;
@@ -1104,29 +1532,44 @@ declare const appConfigSchema: z.ZodObject<{
1104
1532
  input_mode: z.ZodDefault<z.ZodEnum<["stdin", "arg", "protocol"]>>;
1105
1533
  timeout_ms: z.ZodOptional<z.ZodNumber>;
1106
1534
  inherit_env: z.ZodOptional<z.ZodBoolean>;
1535
+ env_policy: z.ZodOptional<z.ZodEnum<["inherit", "allowlist", "denylist", "explicit"]>>;
1536
+ env_allowlist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1537
+ env_denylist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1538
+ max_output_bytes: z.ZodOptional<z.ZodNumber>;
1539
+ allow_external_cwd: z.ZodOptional<z.ZodBoolean>;
1107
1540
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1108
1541
  }, "strict", z.ZodTypeAny, {
1109
1542
  name: string;
1110
1543
  type: "native" | "process" | "cli";
1111
- input_mode: "stdin" | "arg" | "protocol";
1112
- metadata?: Record<string, unknown> | undefined;
1544
+ input_mode: "protocol" | "stdin" | "arg";
1113
1545
  command?: string | undefined;
1546
+ metadata?: Record<string, unknown> | undefined;
1547
+ timeout_ms?: number | undefined;
1114
1548
  args?: string[] | undefined;
1115
1549
  cwd?: string | undefined;
1116
1550
  env?: Record<string, string> | undefined;
1117
- timeout_ms?: number | undefined;
1118
1551
  inherit_env?: boolean | undefined;
1552
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1553
+ env_allowlist?: string[] | undefined;
1554
+ env_denylist?: string[] | undefined;
1555
+ max_output_bytes?: number | undefined;
1556
+ allow_external_cwd?: boolean | undefined;
1119
1557
  }, {
1120
1558
  name: string;
1121
- type?: "native" | "process" | "cli" | undefined;
1122
- metadata?: Record<string, unknown> | undefined;
1123
1559
  command?: string | undefined;
1560
+ metadata?: Record<string, unknown> | undefined;
1561
+ type?: "native" | "process" | "cli" | undefined;
1562
+ timeout_ms?: number | undefined;
1124
1563
  args?: string[] | undefined;
1125
1564
  cwd?: string | undefined;
1126
1565
  env?: Record<string, string> | undefined;
1127
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1128
- timeout_ms?: number | undefined;
1566
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1129
1567
  inherit_env?: boolean | undefined;
1568
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1569
+ env_allowlist?: string[] | undefined;
1570
+ env_denylist?: string[] | undefined;
1571
+ max_output_bytes?: number | undefined;
1572
+ allow_external_cwd?: boolean | undefined;
1130
1573
  }>, "many">>;
1131
1574
  roles: z.ZodDefault<z.ZodArray<z.ZodObject<{
1132
1575
  id: z.ZodString;
@@ -1170,6 +1613,8 @@ declare const appConfigSchema: z.ZodObject<{
1170
1613
  depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1171
1614
  retries: z.ZodOptional<z.ZodNumber>;
1172
1615
  condition: z.ZodOptional<z.ZodEnum<["always", "on-success", "on-failure"]>>;
1616
+ /** Constraints passed to the planner for plan steps (§15). */
1617
+ constraints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1173
1618
  }, "strict", z.ZodTypeAny, {
1174
1619
  id: string;
1175
1620
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -1179,6 +1624,7 @@ declare const appConfigSchema: z.ZodObject<{
1179
1624
  depends_on?: string[] | undefined;
1180
1625
  retries?: number | undefined;
1181
1626
  condition?: "always" | "on-success" | "on-failure" | undefined;
1627
+ constraints?: string[] | undefined;
1182
1628
  }, {
1183
1629
  id: string;
1184
1630
  kind: "custom" | "research" | "collect" | "analyze" | "plan" | "execute";
@@ -1188,6 +1634,7 @@ declare const appConfigSchema: z.ZodObject<{
1188
1634
  depends_on?: string[] | undefined;
1189
1635
  retries?: number | undefined;
1190
1636
  condition?: "always" | "on-success" | "on-failure" | undefined;
1637
+ constraints?: string[] | undefined;
1191
1638
  }>, "many">;
1192
1639
  }, "strict", z.ZodTypeAny, {
1193
1640
  id: string;
@@ -1200,9 +1647,10 @@ declare const appConfigSchema: z.ZodObject<{
1200
1647
  depends_on?: string[] | undefined;
1201
1648
  retries?: number | undefined;
1202
1649
  condition?: "always" | "on-success" | "on-failure" | undefined;
1650
+ constraints?: string[] | undefined;
1203
1651
  }[];
1204
- role?: string | undefined;
1205
1652
  name?: string | undefined;
1653
+ role?: string | undefined;
1206
1654
  objective?: string | undefined;
1207
1655
  }, {
1208
1656
  id: string;
@@ -1215,9 +1663,10 @@ declare const appConfigSchema: z.ZodObject<{
1215
1663
  depends_on?: string[] | undefined;
1216
1664
  retries?: number | undefined;
1217
1665
  condition?: "always" | "on-success" | "on-failure" | undefined;
1666
+ constraints?: string[] | undefined;
1218
1667
  }[];
1219
- role?: string | undefined;
1220
1668
  name?: string | undefined;
1669
+ role?: string | undefined;
1221
1670
  objective?: string | undefined;
1222
1671
  }>, "many">>;
1223
1672
  planner: z.ZodOptional<z.ZodObject<{
@@ -1237,37 +1686,47 @@ declare const appConfigSchema: z.ZodObject<{
1237
1686
  provider: z.ZodDefault<z.ZodString>;
1238
1687
  base_url: z.ZodOptional<z.ZodString>;
1239
1688
  api_key_env_var: z.ZodOptional<z.ZodString>;
1689
+ /** When true, memory failures fail tasks instead of being tolerated (§12). */
1690
+ required: z.ZodOptional<z.ZodBoolean>;
1240
1691
  }, "strict", z.ZodTypeAny, {
1241
1692
  provider: string;
1242
1693
  base_url?: string | undefined;
1243
1694
  api_key_env_var?: string | undefined;
1695
+ required?: boolean | undefined;
1244
1696
  }, {
1245
1697
  base_url?: string | undefined;
1246
1698
  api_key_env_var?: string | undefined;
1247
1699
  provider?: string | undefined;
1700
+ required?: boolean | undefined;
1248
1701
  }>>;
1249
1702
  }, "strict", z.ZodTypeAny, {
1250
1703
  name: string;
1251
1704
  agents: {
1252
1705
  name: string;
1253
1706
  type: "native" | "process" | "cli";
1254
- input_mode: "stdin" | "arg" | "protocol";
1255
- metadata?: Record<string, unknown> | undefined;
1707
+ input_mode: "protocol" | "stdin" | "arg";
1256
1708
  command?: string | undefined;
1709
+ metadata?: Record<string, unknown> | undefined;
1710
+ timeout_ms?: number | undefined;
1257
1711
  args?: string[] | undefined;
1258
1712
  cwd?: string | undefined;
1259
1713
  env?: Record<string, string> | undefined;
1260
- timeout_ms?: number | undefined;
1261
1714
  inherit_env?: boolean | undefined;
1715
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1716
+ env_allowlist?: string[] | undefined;
1717
+ env_denylist?: string[] | undefined;
1718
+ max_output_bytes?: number | undefined;
1719
+ allow_external_cwd?: boolean | undefined;
1262
1720
  }[];
1263
1721
  providers: {
1264
1722
  name: string;
1265
1723
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1266
1724
  base_url: string;
1725
+ metadata?: Record<string, unknown> | undefined;
1267
1726
  api_key_env_var?: string | undefined;
1727
+ timeout_ms?: number | undefined;
1268
1728
  headers?: Record<string, string> | undefined;
1269
1729
  enabled?: boolean | undefined;
1270
- metadata?: Record<string, unknown> | undefined;
1271
1730
  }[];
1272
1731
  roles: {
1273
1732
  name: string;
@@ -1290,9 +1749,10 @@ declare const appConfigSchema: z.ZodObject<{
1290
1749
  depends_on?: string[] | undefined;
1291
1750
  retries?: number | undefined;
1292
1751
  condition?: "always" | "on-success" | "on-failure" | undefined;
1752
+ constraints?: string[] | undefined;
1293
1753
  }[];
1294
- role?: string | undefined;
1295
1754
  name?: string | undefined;
1755
+ role?: string | undefined;
1296
1756
  objective?: string | undefined;
1297
1757
  }[];
1298
1758
  planner?: {
@@ -1304,29 +1764,36 @@ declare const appConfigSchema: z.ZodObject<{
1304
1764
  provider: string;
1305
1765
  base_url?: string | undefined;
1306
1766
  api_key_env_var?: string | undefined;
1767
+ required?: boolean | undefined;
1307
1768
  } | undefined;
1308
1769
  }, {
1309
1770
  name: string;
1310
1771
  agents?: {
1311
1772
  name: string;
1312
- type?: "native" | "process" | "cli" | undefined;
1313
- metadata?: Record<string, unknown> | undefined;
1314
1773
  command?: string | undefined;
1774
+ metadata?: Record<string, unknown> | undefined;
1775
+ type?: "native" | "process" | "cli" | undefined;
1776
+ timeout_ms?: number | undefined;
1315
1777
  args?: string[] | undefined;
1316
1778
  cwd?: string | undefined;
1317
1779
  env?: Record<string, string> | undefined;
1318
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1319
- timeout_ms?: number | undefined;
1780
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1320
1781
  inherit_env?: boolean | undefined;
1782
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1783
+ env_allowlist?: string[] | undefined;
1784
+ env_denylist?: string[] | undefined;
1785
+ max_output_bytes?: number | undefined;
1786
+ allow_external_cwd?: boolean | undefined;
1321
1787
  }[] | undefined;
1322
1788
  providers?: {
1323
1789
  name: string;
1324
1790
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1325
1791
  base_url: string;
1792
+ metadata?: Record<string, unknown> | undefined;
1326
1793
  api_key_env_var?: string | undefined;
1794
+ timeout_ms?: number | undefined;
1327
1795
  headers?: Record<string, string> | undefined;
1328
1796
  enabled?: boolean | undefined;
1329
- metadata?: Record<string, unknown> | undefined;
1330
1797
  }[] | undefined;
1331
1798
  roles?: {
1332
1799
  name: string;
@@ -1349,9 +1816,10 @@ declare const appConfigSchema: z.ZodObject<{
1349
1816
  depends_on?: string[] | undefined;
1350
1817
  retries?: number | undefined;
1351
1818
  condition?: "always" | "on-success" | "on-failure" | undefined;
1819
+ constraints?: string[] | undefined;
1352
1820
  }[];
1353
- role?: string | undefined;
1354
1821
  name?: string | undefined;
1822
+ role?: string | undefined;
1355
1823
  objective?: string | undefined;
1356
1824
  }[] | undefined;
1357
1825
  planner?: {
@@ -1363,6 +1831,7 @@ declare const appConfigSchema: z.ZodObject<{
1363
1831
  base_url?: string | undefined;
1364
1832
  api_key_env_var?: string | undefined;
1365
1833
  provider?: string | undefined;
1834
+ required?: boolean | undefined;
1366
1835
  } | undefined;
1367
1836
  }>;
1368
1837
  logging: z.ZodOptional<z.ZodObject<{
@@ -1378,23 +1847,29 @@ declare const appConfigSchema: z.ZodObject<{
1378
1847
  agents: {
1379
1848
  name: string;
1380
1849
  type: "native" | "process" | "cli";
1381
- input_mode: "stdin" | "arg" | "protocol";
1382
- metadata?: Record<string, unknown> | undefined;
1850
+ input_mode: "protocol" | "stdin" | "arg";
1383
1851
  command?: string | undefined;
1852
+ metadata?: Record<string, unknown> | undefined;
1853
+ timeout_ms?: number | undefined;
1384
1854
  args?: string[] | undefined;
1385
1855
  cwd?: string | undefined;
1386
1856
  env?: Record<string, string> | undefined;
1387
- timeout_ms?: number | undefined;
1388
1857
  inherit_env?: boolean | undefined;
1858
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1859
+ env_allowlist?: string[] | undefined;
1860
+ env_denylist?: string[] | undefined;
1861
+ max_output_bytes?: number | undefined;
1862
+ allow_external_cwd?: boolean | undefined;
1389
1863
  }[];
1390
1864
  providers: {
1391
1865
  name: string;
1392
1866
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1393
1867
  base_url: string;
1868
+ metadata?: Record<string, unknown> | undefined;
1394
1869
  api_key_env_var?: string | undefined;
1870
+ timeout_ms?: number | undefined;
1395
1871
  headers?: Record<string, string> | undefined;
1396
1872
  enabled?: boolean | undefined;
1397
- metadata?: Record<string, unknown> | undefined;
1398
1873
  }[];
1399
1874
  roles: {
1400
1875
  name: string;
@@ -1417,9 +1892,10 @@ declare const appConfigSchema: z.ZodObject<{
1417
1892
  depends_on?: string[] | undefined;
1418
1893
  retries?: number | undefined;
1419
1894
  condition?: "always" | "on-success" | "on-failure" | undefined;
1895
+ constraints?: string[] | undefined;
1420
1896
  }[];
1421
- role?: string | undefined;
1422
1897
  name?: string | undefined;
1898
+ role?: string | undefined;
1423
1899
  objective?: string | undefined;
1424
1900
  }[];
1425
1901
  planner?: {
@@ -1431,6 +1907,7 @@ declare const appConfigSchema: z.ZodObject<{
1431
1907
  provider: string;
1432
1908
  base_url?: string | undefined;
1433
1909
  api_key_env_var?: string | undefined;
1910
+ required?: boolean | undefined;
1434
1911
  } | undefined;
1435
1912
  };
1436
1913
  logging?: {
@@ -1441,24 +1918,30 @@ declare const appConfigSchema: z.ZodObject<{
1441
1918
  name: string;
1442
1919
  agents?: {
1443
1920
  name: string;
1444
- type?: "native" | "process" | "cli" | undefined;
1445
- metadata?: Record<string, unknown> | undefined;
1446
1921
  command?: string | undefined;
1922
+ metadata?: Record<string, unknown> | undefined;
1923
+ type?: "native" | "process" | "cli" | undefined;
1924
+ timeout_ms?: number | undefined;
1447
1925
  args?: string[] | undefined;
1448
1926
  cwd?: string | undefined;
1449
1927
  env?: Record<string, string> | undefined;
1450
- input_mode?: "stdin" | "arg" | "protocol" | undefined;
1451
- timeout_ms?: number | undefined;
1928
+ input_mode?: "protocol" | "stdin" | "arg" | undefined;
1452
1929
  inherit_env?: boolean | undefined;
1930
+ env_policy?: "inherit" | "allowlist" | "denylist" | "explicit" | undefined;
1931
+ env_allowlist?: string[] | undefined;
1932
+ env_denylist?: string[] | undefined;
1933
+ max_output_bytes?: number | undefined;
1934
+ allow_external_cwd?: boolean | undefined;
1453
1935
  }[] | undefined;
1454
1936
  providers?: {
1455
1937
  name: string;
1456
1938
  type: "custom" | "openai-compatible" | "omnihilbras" | "openrouter" | "local";
1457
1939
  base_url: string;
1940
+ metadata?: Record<string, unknown> | undefined;
1458
1941
  api_key_env_var?: string | undefined;
1942
+ timeout_ms?: number | undefined;
1459
1943
  headers?: Record<string, string> | undefined;
1460
1944
  enabled?: boolean | undefined;
1461
- metadata?: Record<string, unknown> | undefined;
1462
1945
  }[] | undefined;
1463
1946
  roles?: {
1464
1947
  name: string;
@@ -1481,9 +1964,10 @@ declare const appConfigSchema: z.ZodObject<{
1481
1964
  depends_on?: string[] | undefined;
1482
1965
  retries?: number | undefined;
1483
1966
  condition?: "always" | "on-success" | "on-failure" | undefined;
1967
+ constraints?: string[] | undefined;
1484
1968
  }[];
1485
- role?: string | undefined;
1486
1969
  name?: string | undefined;
1970
+ role?: string | undefined;
1487
1971
  objective?: string | undefined;
1488
1972
  }[] | undefined;
1489
1973
  planner?: {
@@ -1495,6 +1979,7 @@ declare const appConfigSchema: z.ZodObject<{
1495
1979
  base_url?: string | undefined;
1496
1980
  api_key_env_var?: string | undefined;
1497
1981
  provider?: string | undefined;
1982
+ required?: boolean | undefined;
1498
1983
  } | undefined;
1499
1984
  };
1500
1985
  logging?: {
@@ -1526,6 +2011,7 @@ interface AppConfig {
1526
2011
  provider: string;
1527
2012
  baseUrl?: string;
1528
2013
  apiKeyEnvVar?: string;
2014
+ required?: boolean;
1529
2015
  };
1530
2016
  };
1531
2017
  logging?: {
@@ -1576,11 +2062,63 @@ declare function requestJson(url: string, options?: HttpRequestOptions): Promise
1576
2062
  declare const OPENAI_COMPATIBLE_TYPES: readonly ProviderType[];
1577
2063
  declare function createProvider(config: ProviderConfig): IChatProvider;
1578
2064
 
2065
+ /**
2066
+ * Provider error normalization (roadmap §10).
2067
+ *
2068
+ * Every provider failure is mapped to one stable kind, so callers can react
2069
+ * (retry a rate limit, surface an auth problem, treat a missing model
2070
+ * differently) without string-matching provider-specific payloads.
2071
+ */
2072
+
2073
+ type ProviderErrorKind = "AUTHENTICATION_ERROR" | "RATE_LIMIT_ERROR" | "INVALID_REQUEST" | "MODEL_NOT_FOUND" | "TIMEOUT" | "NETWORK_ERROR" | "SERVER_ERROR" | "UNKNOWN_ERROR";
2074
+ interface ProviderErrorContext {
2075
+ provider: string;
2076
+ operation: string;
2077
+ status?: number;
2078
+ body?: unknown;
2079
+ retryAfterMs?: number;
2080
+ cause?: unknown;
2081
+ /** Maps the normalized kind onto the legacy stable error code. */
2082
+ code?: "PROVIDER_UNAVAILABLE" | "PROVIDER_AUTH_FAILED" | "MODEL_NOT_FOUND";
2083
+ }
2084
+ /** Kinds worth retrying automatically (rate limits and transient server errors). */
2085
+ declare function isRetryable(kind: ProviderErrorKind): boolean;
2086
+ /** Maps an HTTP status (and optional body) to a normalized kind. */
2087
+ declare function kindFromStatus(status: number): ProviderErrorKind;
2088
+ /** Extracts a human message from common provider error body shapes. */
2089
+ declare function extractMessage(body: unknown): string | undefined;
2090
+ /** Parses `Retry-After` (seconds or HTTP-date) into milliseconds. */
2091
+ declare function parseRetryAfter(value: string | null | undefined, now?: number): number | undefined;
2092
+ /** True for the abort/timeout errors raised by fetch's AbortSignal.timeout. */
2093
+ declare function isTimeoutError(error: unknown): boolean;
2094
+ /** True for transport failures (DNS, refused, TLS, offline). */
2095
+ declare function isNetworkError(error: unknown): boolean;
2096
+ declare function providerHttpError(context: ProviderErrorContext): ProviderError;
2097
+ /** Wraps a thrown transport/abort error into a normalized ProviderError. */
2098
+ declare function providerTransportError(context: Omit<ProviderErrorContext, "status" | "body">): ProviderError;
2099
+
1579
2100
  declare class OpenAICompatibleProvider implements IChatProvider {
1580
2101
  readonly config: ProviderConfig;
2102
+ readonly providerId: string;
2103
+ readonly authentication: ProviderAuthentication;
1581
2104
  private readonly log;
1582
- constructor(config: ProviderConfig, log?: Logger);
2105
+ /** Discovered models, so getModel() answers without another round-trip. */
2106
+ private discovered?;
2107
+ private readonly env;
2108
+ constructor(config: ProviderConfig, log?: Logger, env?: Record<string, string | undefined>);
2109
+ /** Provider-level request timeout (roadmap §6.6/§11) with the shared default. */
2110
+ private get requestTimeoutMs();
2111
+ /** Authenticate + discover (roadmap §10, Model Discovery). */
2112
+ connect(): Promise<ModelInfo[]>;
2113
+ getModel(modelId: string): Promise<ModelInfo | undefined>;
2114
+ /** Raw /models body (protected so adapters can capture gateway-level metadata). */
2115
+ protected rawModelsResponse(): Promise<unknown>;
2116
+ private modelsRequest;
1583
2117
  listModels(): Promise<ModelInfo[]>;
2118
+ /** Maps a raw model entry onto the normalized metadata shape (§10). */
2119
+ private toModelInfo;
2120
+ /** Streaming where the gateway supports it (§11). */
2121
+ stream(request: ChatRequest, onChunk: (chunk: ChatStreamChunk) => void): Promise<ChatResponse>;
1584
2122
  healthCheck(): Promise<ProviderStatus>;
1585
2123
  chat(request: ChatRequest): Promise<ChatResponse>;
1586
2124
  }
@@ -1623,20 +2161,37 @@ interface OmniHilbrasConnectionResult {
1623
2161
  registered: number;
1624
2162
  }
1625
2163
  declare class OmniHilbrasProvider extends OpenAICompatibleProvider {
2164
+ private gateway?;
2165
+ listModels(): Promise<ModelInfo[]>;
1626
2166
  /**
1627
2167
  * Run the full connect flow. Throws on authentication or transport failure
1628
2168
  * (use healthCheck() for a non-throwing probe).
1629
2169
  */
1630
- connect(registry?: ModelRegistry): Promise<OmniHilbrasConnectionResult>;
2170
+ /**
2171
+ * Gateway metadata reported alongside the model list (gateway version, tier,
2172
+ * region…), kept separate from per-model metadata (§11 — provider metadata).
2173
+ */
2174
+ gatewayMetadata(): Record<string, unknown> | undefined;
2175
+ protected extractGatewayMetadata(body: unknown): Promise<void>;
2176
+ connectAndRegister(registry?: ModelRegistry): Promise<OmniHilbrasConnectionResult>;
1631
2177
  }
1632
2178
 
1633
2179
  /**
1634
- * Builds the child environment. By default the agent inherits the full
1635
- * environment; with `inheritEnv: false` it receives only PATH plus the
1636
- * explicitly configured variables — useful to avoid leaking OmniNode's
1637
- * own secrets (e.g. provider API keys) into third-party agents.
2180
+ * Process adapter (§9): runs CLI agents as child processes and communicates
2181
+ * over stdin/stdout, managing the process lifecycle, working directory,
2182
+ * environment, exit codes, logs and timeouts.
2183
+ *
2184
+ * Three input modes (§9, §21):
2185
+ * - "stdin": the composed task text is written to the agent's stdin.
2186
+ * - "arg": the composed task text is appended as the last command argument.
2187
+ * - "protocol": NodeToAgentMessage envelopes as JSON lines on stdin; the
2188
+ * agent answers with AgentToNodeMessage JSON lines (REPORT,
2189
+ * COMPLETION, ERROR, ...) whose structured payloads are parsed
2190
+ * into reports.
1638
2191
  */
1639
- declare function buildChildEnv(config: AgentConfig): NodeJS.ProcessEnv;
2192
+
2193
+ /** Per-stream byte budget before output is truncated and the agent killed. */
2194
+ declare const DEFAULT_MAX_OUTPUT_BYTES: number;
1640
2195
  declare function composeTaskText(input: AgentTaskInput): string;
1641
2196
  declare class ProcessAgent implements IAgent {
1642
2197
  readonly config: AgentConfig;
@@ -1649,6 +2204,63 @@ declare class ProcessAgent implements IAgent {
1649
2204
  cancel(taskId: string): Promise<void>;
1650
2205
  runningTaskIds(): string[];
1651
2206
  }
2207
+ /** Kills a child and, on POSIX, its whole process group (roadmap §8 tree cleanup). */
2208
+ declare function killTree(child: ChildProcess, signal: NodeJS.Signals): void;
2209
+ /** Human-readable exit reason, including signal terminations. */
2210
+ declare function describeExit(code: number | null, signal: NodeJS.Signals | null): string;
2211
+ /**
2212
+ * Decodes a stdout/stderr chunk safely: invalid UTF-8 becomes replacement
2213
+ * characters and NUL bytes are stripped, so binary noise cannot poison the
2214
+ * protocol decoder or the terminal (roadmap §8, encoding hardening).
2215
+ */
2216
+ declare function sanitizeChunk(chunk: Buffer): string;
2217
+
2218
+ /**
2219
+ * Agent environment policies (roadmap §8, Environment Isolation).
2220
+ *
2221
+ * Four explicit policies, so operators decide exactly what an agent can see:
2222
+ * - `inherit` (default, backwards compatible): the full parent environment
2223
+ * - `allowlist`: only the allow-listed variables (+ PATH/HOME)
2224
+ * - `denylist`: the parent environment minus the deny-listed variables
2225
+ * - `explicit`: nothing from the parent; only PATH/HOME and `env`
2226
+ *
2227
+ * The v1 boolean `inherit_env: false` is still honored and maps to `explicit`.
2228
+ */
2229
+
2230
+ type EnvPolicy = "inherit" | "allowlist" | "denylist" | "explicit";
2231
+ declare function resolveEnvPolicy(config: Partial<AgentConfig>): EnvPolicy;
2232
+ declare function buildChildEnv(config: AgentConfig): NodeJS.ProcessEnv;
2233
+
2234
+ interface CwdValidation {
2235
+ /** Normalized absolute path. */
2236
+ cwd: string;
2237
+ /** True when the directory sits outside the project root (project boundary). */
2238
+ outsideProject: boolean;
2239
+ }
2240
+ declare function validateWorkingDirectory(cwd: string | undefined, options?: {
2241
+ projectRoot?: string;
2242
+ allowExternal?: boolean;
2243
+ }): CwdValidation | undefined;
2244
+
2245
+ interface IAgentAdapter {
2246
+ /** Integration type this adapter serves, e.g. "native" or "process". */
2247
+ readonly integration: string;
2248
+ create(config: AgentConfig): IAgent;
2249
+ }
2250
+ declare class AgentAdapterRegistry {
2251
+ private readonly adapters;
2252
+ register(adapter: IAgentAdapter): void;
2253
+ get(integration: string): IAgentAdapter | undefined;
2254
+ list(): IAgentAdapter[];
2255
+ create(config: AgentConfig): IAgent;
2256
+ }
2257
+ /** Process-level adapter — the built-in CLI integration. */
2258
+ declare class ProcessAgentAdapter implements IAgentAdapter {
2259
+ private readonly factory;
2260
+ readonly integration = "process";
2261
+ constructor(factory: (config: AgentConfig) => IAgent);
2262
+ create(config: AgentConfig): IAgent;
2263
+ }
1652
2264
 
1653
2265
  /** Agent registry (§10): the set of agents connected to OmniNode. */
1654
2266
 
@@ -1664,10 +2276,109 @@ declare class AgentRegistry {
1664
2276
  * "cli" agent configs are mapped to the process integration by the loader.
1665
2277
  */
1666
2278
 
1667
- declare function createAgent(config: AgentConfig): IAgent;
2279
+ declare function createAgent(config: AgentConfig, adapters?: AgentAdapterRegistry): IAgent;
2280
+
1668
2281
  /** Builds an agent registry from the project configuration, skipping agents that fail to construct. */
1669
2282
  declare function buildAgentRegistry(config: AppConfig, log?: Logger): AgentRegistry;
1670
2283
 
2284
+ /**
2285
+ * OmniNode Agent Protocol v2 — versioning (roadmap §7.1).
2286
+ *
2287
+ * Protocol identifiers are namespaced strings so an agent can negotiate the
2288
+ * dialect it speaks: `omninode-agent-protocol/2`.
2289
+ */
2290
+ declare const PROTOCOL_V2 = "omninode-agent-protocol/2";
2291
+ /** Versions this build accepts. v1 is the unversioned dialect shipped with OmniNode 1.x. */
2292
+ declare const SUPPORTED_PROTOCOL_VERSIONS: readonly string[];
2293
+ declare const MAX_MESSAGE_BYTES = 1048576;
2294
+ declare function isSupportedProtocol(protocol: string): boolean;
2295
+
2296
+ type ProtocolViolationCode = "INVALID_JSON" | "NOT_AN_OBJECT" | "UNKNOWN_TYPE" | "MISSING_FIELD" | "UNSUPPORTED_VERSION" | "OVERSIZED" | "INVALID_PAYLOAD";
2297
+ interface ProtocolViolation {
2298
+ code: ProtocolViolationCode;
2299
+ message: string;
2300
+ /** Raw line (truncated) for diagnostics. */
2301
+ sample?: string;
2302
+ }
2303
+ type DecodeResult = {
2304
+ ok: true;
2305
+ envelope: ProtocolEnvelope;
2306
+ legacy: boolean;
2307
+ } | {
2308
+ ok: false;
2309
+ error: ProtocolViolation;
2310
+ };
2311
+ /** Validates one decoded JSON value as a protocol envelope. */
2312
+ declare function validateEnvelope(value: unknown, line?: string): DecodeResult;
2313
+ /** Decodes one protocol line (no trailing newline). */
2314
+ declare function decodeMessage(line: string, maxBytes?: number): DecodeResult;
2315
+ /** Serializes an envelope to a single JSON line. */
2316
+ declare function encodeMessage(envelope: ProtocolEnvelope, maxBytes?: number): string;
2317
+ /**
2318
+ * Streaming line decoder for agent stdout. Feed chunks; receive decoded
2319
+ * envelopes and violations in order. Survives garbage: a bad line yields a
2320
+ * violation and the stream continues.
2321
+ */
2322
+ declare class ProtocolDecoder {
2323
+ private buffer;
2324
+ private readonly maxBytes;
2325
+ constructor(maxBytes?: number);
2326
+ push(chunk: string): DecodeResult[];
2327
+ /** Flush any trailing line when the process exits. */
2328
+ flush(): DecodeResult[];
2329
+ }
2330
+
2331
+ /**
2332
+ * OmniNode Agent Protocol v2 — session (roadmap §7.6).
2333
+ *
2334
+ * A session drives a protocol-mode agent: it emits v2 envelopes with
2335
+ * correlation ids, tolerates legacy (unversioned) replies, answers agent
2336
+ * questions through a responder callback, and collects reports, artifacts
2337
+ * and the completion — never throwing on malformed input.
2338
+ */
2339
+
2340
+ interface SessionIds {
2341
+ requestId: string;
2342
+ taskId: string;
2343
+ agentId: string;
2344
+ pipelineId?: string;
2345
+ executionId?: string;
2346
+ }
2347
+ interface QuestionResponder {
2348
+ (question: {
2349
+ questionId: string;
2350
+ question: string;
2351
+ expected?: string;
2352
+ }): Promise<string> | string;
2353
+ }
2354
+ declare class ProtocolSession {
2355
+ readonly decoder: ProtocolDecoder;
2356
+ private readonly ids;
2357
+ private readonly responder;
2358
+ readonly violations: ProtocolViolation[];
2359
+ readonly questions: AskedQuestion[];
2360
+ readonly artifacts: ProtocolEnvelope["payload"][];
2361
+ reports: ProtocolEnvelope["payload"][];
2362
+ descriptor?: AgentDescriptor;
2363
+ completionSummary?: string;
2364
+ errorMessage?: string;
2365
+ constructor(ids: SessionIds, options?: {
2366
+ responder?: QuestionResponder;
2367
+ maxBytes?: number;
2368
+ });
2369
+ /** The v2 messages OmniNode sends to open a task (written to the agent's stdin). */
2370
+ taskMessages(objective: string, role?: unknown, context?: string, instruction?: string): string[];
2371
+ helloAck(descriptor: AgentDescriptor): string;
2372
+ /** Consumes decoded stdout, answering questions as they arrive. */
2373
+ handle(decoded: DecodeResult): Promise<void>;
2374
+ private answerQuestion;
2375
+ readonly pendingAnswers: string[];
2376
+ /** True once any inbound message carried the v2 protocol field. */
2377
+ sawV2: boolean;
2378
+ }
2379
+ declare function decodeStream(session: ProtocolSession, chunk: string): Promise<string[]>;
2380
+ declare function requireCompletion(session: ProtocolSession): void;
2381
+
1671
2382
  /** Role registry (§11): the set of roles available for task assignment. */
1672
2383
 
1673
2384
  declare class RoleRegistry {
@@ -1764,8 +2475,17 @@ declare function keywords(text: string): Set<string>;
1764
2475
  declare class LocalMemoryProvider extends JsonFileStore<MemoryEntry> implements IMemoryProvider {
1765
2476
  readonly name = "local";
1766
2477
  constructor(directory?: string);
2478
+ metadata(): MemoryProviderMetadata;
2479
+ search(text: string, options?: {
2480
+ limit?: number;
2481
+ scope?: MemoryQuery["scope"];
2482
+ }): Promise<MemoryEntry[]>;
2483
+ /** @deprecated v1 alias of {@link retrieve}. */
1767
2484
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
2485
+ /** @deprecated v1 alias of {@link store}. */
1768
2486
  write(entry: MemoryEntry): Promise<void>;
2487
+ retrieve(query: MemoryQuery): Promise<MemoryEntry[]>;
2488
+ store(entry: MemoryEntry): Promise<void>;
1769
2489
  count(): Promise<number>;
1770
2490
  }
1771
2491
 
@@ -1781,9 +2501,20 @@ declare class RememberaMemoryProvider implements IMemoryProvider {
1781
2501
  private readonly env;
1782
2502
  private readonly log;
1783
2503
  constructor(config: RememberaConfig, log?: Logger);
2504
+ private get authenticationConfigured();
1784
2505
  private headers;
2506
+ /** Search delegates to the gateway's relevance query. */
2507
+ search(text: string, options?: {
2508
+ limit?: number;
2509
+ scope?: MemoryQuery["scope"];
2510
+ }): Promise<MemoryEntry[]>;
2511
+ metadata(): MemoryProviderMetadata;
2512
+ /** @deprecated v1 alias of {@link retrieve}. */
1785
2513
  query(query: MemoryQuery): Promise<MemoryEntry[]>;
2514
+ /** @deprecated v1 alias of {@link store}. */
1786
2515
  write(entry: MemoryEntry): Promise<void>;
2516
+ retrieve(query: MemoryQuery): Promise<MemoryEntry[]>;
2517
+ store(entry: MemoryEntry): Promise<void>;
1787
2518
  private request;
1788
2519
  private toEntry;
1789
2520
  }
@@ -1791,31 +2522,66 @@ declare class RememberaMemoryProvider implements IMemoryProvider {
1791
2522
  type MemoryProviderConfig = NonNullable<AppConfig["project"]["memory"]>;
1792
2523
  declare function createMemoryProvider(config?: MemoryProviderConfig): IMemoryProvider;
1793
2524
 
1794
- /**
1795
- * Memory service (§19–§20): gathers relevant memory before a task runs and
1796
- * records outcomes afterwards — the Task → memory → relevant context →
1797
- * agents → reports → memory loop. Memory failures are best-effort: they log
1798
- * a warning and never fail a task, because memory is an enhancement, not a
1799
- * dependency (§2).
1800
- */
1801
-
1802
2525
  interface MemoryContextQuery {
1803
2526
  objective: string;
1804
2527
  role?: string;
1805
2528
  project?: string;
2529
+ /** Maximum entries to consider (relevance-ranked by the provider). */
2530
+ limit?: number;
2531
+ }
2532
+ interface MemoryTaskContext {
2533
+ /** Prompt-ready context text ("" when nothing relevant was found). */
2534
+ text: string;
2535
+ entries: MemoryEntry[];
2536
+ /** True when the character budget cut the context short. */
2537
+ truncated: boolean;
2538
+ }
2539
+ declare const MAX_CONTEXT_CHARS = 4000;
2540
+ interface MemoryServiceOptions {
2541
+ /** When true, backend failures propagate instead of being logged. */
2542
+ required?: boolean;
2543
+ maxContextChars?: number;
1806
2544
  }
1807
2545
  declare class MemoryService {
1808
2546
  private readonly provider;
1809
2547
  private readonly log;
1810
- constructor(provider: IMemoryProvider, log?: Logger);
2548
+ private readonly required;
2549
+ private readonly maxContextChars;
2550
+ constructor(provider: IMemoryProvider, log?: Logger, options?: MemoryServiceOptions);
1811
2551
  get providerRef(): IMemoryProvider;
1812
2552
  get providerName(): string;
1813
- /** Relevant context for a task objective; empty string when nothing matches. */
2553
+ get isRequired(): boolean;
2554
+ /** Structured, budgeted context for a task (§12 — avoid loading all memory). */
2555
+ contextFor(query: MemoryContextQuery): Promise<MemoryTaskContext>;
2556
+ /** Prompt-ready context text (v1 convenience wrapper). */
1814
2557
  gatherContext(query: MemoryContextQuery): Promise<string>;
1815
- /** Records a finished task's outcome — best-effort. */
2558
+ /** Records a finished task's outcome — task history plus "known problems" (§12). */
1816
2559
  recordTaskOutcome(task: Task): Promise<void>;
2560
+ private format;
2561
+ /**
2562
+ * Failure policy (§12): continue unless memory is explicitly required.
2563
+ */
2564
+ private handleFailure;
1817
2565
  }
1818
2566
 
2567
+ /**
2568
+ * Shared memory-contract helpers (roadmap §12). Adapters implement
2569
+ * `retrieve` / `store`; these helpers supply the defaults for `search`,
2570
+ * `metadata` and the v1 `query` / `write` aliases, so the contract is
2571
+ * defined once.
2572
+ */
2573
+
2574
+ /** Free-text search defaults to a relevance retrieve. */
2575
+ declare function defaultSearch(provider: Pick<IMemoryProvider, "retrieve">, text: string, options?: {
2576
+ limit?: number;
2577
+ scope?: MemoryQuery["scope"];
2578
+ }): Promise<MemoryEntry[]>;
2579
+ declare function defaultMetadata(name: string, options?: {
2580
+ capabilities?: MemoryProviderMetadata["capabilities"];
2581
+ relevanceRanking?: boolean;
2582
+ backend?: Record<string, unknown>;
2583
+ }): MemoryProviderMetadata;
2584
+
1819
2585
  interface CreateTaskInput {
1820
2586
  objective: string;
1821
2587
  project?: string;
@@ -1823,6 +2589,12 @@ interface CreateTaskInput {
1823
2589
  agent?: string;
1824
2590
  context?: TaskContext;
1825
2591
  }
2592
+ interface RunTaskOptions {
2593
+ /** Total attempts (1 = no automatic retry). Retries apply to retryable errors only. */
2594
+ maxAttempts?: number;
2595
+ /** Linear backoff base in ms: waits backoffMs × attempt between attempts. */
2596
+ retryBackoffMs?: number;
2597
+ }
1826
2598
  interface TaskEngineOptions {
1827
2599
  agents: AgentRegistry;
1828
2600
  roles: RoleRegistry;
@@ -1840,10 +2612,12 @@ declare class TaskEngine {
1840
2612
  get store(): TaskStore;
1841
2613
  create(input: CreateTaskInput): Promise<Task>;
1842
2614
  queue(id: string): Promise<Task>;
1843
- /** Runs the task through its assigned agent and records the result. */
1844
- run(id: string): Promise<Task>;
2615
+ /** Runs the task through its assigned agent and records the result.
2616
+ * `maxAttempts` enables bounded automatic retries of *retryable* errors
2617
+ * with linear backoff; unknown/timed_out outcomes are never auto-retried. */
2618
+ run(id: string, options?: RunTaskOptions): Promise<Task>;
1845
2619
  cancel(id: string): Promise<Task>;
1846
- /** Error recovery (§27 Phase 9): reset a failed/cancelled task so it can run again. */
2620
+ /** Error recovery: reset a failed/cancelled/unknown/timed_out task so it can run again. */
1847
2621
  retry(id: string): Promise<Task>;
1848
2622
  get(id: string): Promise<Task | undefined>;
1849
2623
  list(filter?: TaskStoreFilter): Promise<Task[]>;
@@ -1902,12 +2676,24 @@ interface CombinedMeta {
1902
2676
  pipelineRunId?: string;
1903
2677
  taskIds?: string[];
1904
2678
  }
2679
+ interface CollectionDiagnostics {
2680
+ collected: number;
2681
+ accepted: number;
2682
+ rejected: Array<{
2683
+ key: string;
2684
+ reason: string;
2685
+ issues: string[];
2686
+ }>;
2687
+ }
1905
2688
  declare class ReportService {
1906
2689
  private readonly store;
1907
2690
  private readonly log;
2691
+ /** Rejected reports from the last collection (§13 — malformed never enters aggregation). */
2692
+ lastDiagnostics: CollectionDiagnostics;
1908
2693
  constructor(store: ReportStore, log?: Logger);
1909
2694
  get storeRef(): ReportStore;
1910
- /** Normalizes finished tasks into reports (§17 — normalizer). */
2695
+ /** Normalizes finished tasks into reports (§17 — normalizer), validating each
2696
+ * one so malformed reports never reach aggregation (§13). */
1911
2697
  collectFromTasks(tasks: Task[]): Promise<Report[]>;
1912
2698
  saveReports(reports: Report[]): Promise<void>;
1913
2699
  generateCombined(reports: Report[], meta?: CombinedMeta): Promise<CombinedReport | undefined>;
@@ -1935,18 +2721,49 @@ interface AggregateOptions {
1935
2721
  similarityThreshold?: number;
1936
2722
  }
1937
2723
  declare function aggregateReports(reports: Report[], options?: AggregateOptions): CombinedReport;
2724
+ /**
2725
+ * Conflict detection (§14): agents disagreeing about the same finding is a
2726
+ * first-class result. Both positions are preserved — OmniNode never silently
2727
+ * chooses one.
2728
+ */
2729
+ declare function detectConflicts(groups: AggregatedFinding[]): ReportConflict[];
1938
2730
  declare function similar(a: string, b: string, threshold: number): boolean;
1939
2731
 
2732
+ interface ReportValidationIssue {
2733
+ path: string;
2734
+ message: string;
2735
+ }
2736
+ type ReportValidationResult = {
2737
+ valid: true;
2738
+ report: Report;
2739
+ } | {
2740
+ valid: false;
2741
+ issues: ReportValidationIssue[];
2742
+ reason: string;
2743
+ };
2744
+ /** Validates (and normalizes) a report; malformed reports are rejected. */
2745
+ declare function validateReport(value: unknown): ReportValidationResult;
2746
+ /** Normalizes evidence entries (strings or objects) to typed evidence. */
2747
+ declare function normalizeEvidence(input: EvidenceInput[] | undefined): Evidence[] | undefined;
2748
+ declare function normalizeFinding(finding: Finding): Finding;
2749
+
1940
2750
  /** Planner interface and request contract (§18). The planner is replaceable. */
1941
2751
 
1942
2752
  interface PlanRequest {
2753
+ /** The original task (§15, Planner Input). */
1943
2754
  objective: string;
1944
- /** Raw reports (already normalized) the plan is based on. */
2755
+ /** Project context (repository/workspace background, role-derived context…). */
2756
+ projectContext?: string;
2757
+ /** Agent reports the plan is based on. */
1945
2758
  reports: Report[];
2759
+ /** Aggregated findings (combined report) — consensus and conflicts made explicit. */
2760
+ aggregated?: CombinedReport;
1946
2761
  /** Combined research context from upstream pipeline steps, if available. */
1947
2762
  context?: string;
1948
2763
  role?: RoleDefinition;
1949
2764
  memory?: MemoryEntry[];
2765
+ /** Constraints the plan must respect. */
2766
+ constraints?: string[];
1950
2767
  project?: string;
1951
2768
  taskId?: string;
1952
2769
  pipelineRunId?: string;
@@ -1957,10 +2774,9 @@ interface IPlanner {
1957
2774
  }
1958
2775
 
1959
2776
  /**
1960
- * Planner context builder (§18): assembles everything the planner needs —
1961
- * the objective, the combined findings from the AI reports (with source
1962
- * attribution), relevant memory and the role definition — into one
1963
- * structured text.
2777
+ * Planner context builder (§15, Planner Input): assembles the original task,
2778
+ * project context, agent reports, aggregated findings, relevant memory and
2779
+ * constraints into one structured input, in that order.
1964
2780
  */
1965
2781
 
1966
2782
  declare function buildPlannerContext(request: PlanRequest): string;
@@ -1987,13 +2803,108 @@ declare class ModelPlanner implements IPlanner {
1987
2803
  plan(request: PlanRequest): Promise<Plan>;
1988
2804
  private degrade;
1989
2805
  }
1990
- /** Extracts and validates the plan JSON from arbitrary model output. */
1991
- declare function parsePlanJson(text: string): {
2806
+ type PlanJsonResult = {
2807
+ ok: true;
2808
+ goal: string;
1992
2809
  summary: string;
1993
2810
  steps: PlanStep[];
1994
2811
  risks?: string[];
1995
2812
  notes?: string[];
1996
- } | undefined;
2813
+ } | {
2814
+ ok: false;
2815
+ reason: string;
2816
+ issues: Array<{
2817
+ path: string;
2818
+ message: string;
2819
+ }>;
2820
+ };
2821
+ /** Extracts and validates plan JSON from arbitrary model output (§15). */
2822
+ declare function parsePlanJson(text: string): PlanJsonResult;
2823
+
2824
+ /**
2825
+ * Plan validation (roadmap §15, Validation): every generated plan passes
2826
+ * schema validation. Invalid plans are rejected with structured issues and
2827
+ * — where a fallback is configured — fall back to heuristic planning.
2828
+ */
2829
+
2830
+ declare const planJsonSchema: z.ZodObject<{
2831
+ goal: z.ZodString;
2832
+ summary: z.ZodString;
2833
+ steps: z.ZodArray<z.ZodObject<{
2834
+ id: z.ZodOptional<z.ZodString>;
2835
+ title: z.ZodString;
2836
+ description: z.ZodOptional<z.ZodString>;
2837
+ order: z.ZodOptional<z.ZodNumber>;
2838
+ targets: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2839
+ acceptance_criteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2840
+ depends_on: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2841
+ source_findings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2842
+ }, "strip", z.ZodTypeAny, {
2843
+ title: string;
2844
+ id?: string | undefined;
2845
+ description?: string | undefined;
2846
+ depends_on?: string[] | undefined;
2847
+ order?: number | undefined;
2848
+ targets?: string[] | undefined;
2849
+ acceptance_criteria?: string[] | undefined;
2850
+ source_findings?: string[] | undefined;
2851
+ }, {
2852
+ title: string;
2853
+ id?: string | undefined;
2854
+ description?: string | undefined;
2855
+ depends_on?: string[] | undefined;
2856
+ order?: number | undefined;
2857
+ targets?: string[] | undefined;
2858
+ acceptance_criteria?: string[] | undefined;
2859
+ source_findings?: string[] | undefined;
2860
+ }>, "many">;
2861
+ risks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2862
+ notes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2863
+ }, "strip", z.ZodTypeAny, {
2864
+ steps: {
2865
+ title: string;
2866
+ id?: string | undefined;
2867
+ description?: string | undefined;
2868
+ depends_on?: string[] | undefined;
2869
+ order?: number | undefined;
2870
+ targets?: string[] | undefined;
2871
+ acceptance_criteria?: string[] | undefined;
2872
+ source_findings?: string[] | undefined;
2873
+ }[];
2874
+ summary: string;
2875
+ goal: string;
2876
+ risks?: string[] | undefined;
2877
+ notes?: string[] | undefined;
2878
+ }, {
2879
+ steps: {
2880
+ title: string;
2881
+ id?: string | undefined;
2882
+ description?: string | undefined;
2883
+ depends_on?: string[] | undefined;
2884
+ order?: number | undefined;
2885
+ targets?: string[] | undefined;
2886
+ acceptance_criteria?: string[] | undefined;
2887
+ source_findings?: string[] | undefined;
2888
+ }[];
2889
+ summary: string;
2890
+ goal: string;
2891
+ risks?: string[] | undefined;
2892
+ notes?: string[] | undefined;
2893
+ }>;
2894
+ interface PlanValidationIssue {
2895
+ path: string;
2896
+ message: string;
2897
+ }
2898
+ type PlanValidationResult = {
2899
+ valid: true;
2900
+ plan: Plan;
2901
+ } | {
2902
+ valid: false;
2903
+ issues: PlanValidationIssue[];
2904
+ reason: string;
2905
+ };
2906
+ /** Validates a plan object (ids/order filled by the caller). */
2907
+ declare function validatePlan(plan: Plan): PlanValidationResult;
1997
2908
 
1998
2909
  /**
1999
2910
  * Plan persistence (§27 Phase 8 — planner result storage). Same
@@ -2060,11 +2971,19 @@ interface RunPipelineOptions {
2060
2971
  objective?: string;
2061
2972
  onStep?: (stepRun: PipelineStepRun) => void;
2062
2973
  }
2063
- declare class PipelineEngine {
2974
+ declare class PipelineEngine implements IPipelineExecutor {
2064
2975
  private readonly options;
2065
2976
  private readonly log;
2977
+ /** Runs executing in THIS process — cancellation can terminate them directly. */
2978
+ private readonly activeRuns;
2066
2979
  constructor(options: PipelineEngineOptions);
2067
2980
  get store(): PipelineRunStore;
2981
+ /**
2982
+ * Saves the run while preserving fields that may be set by another process
2983
+ * (e.g. a cancellation request) — an in-memory snapshot must never clobber
2984
+ * externally requested cancellation (§9.2).
2985
+ */
2986
+ private persist;
2068
2987
  /** Structural + semantic validation (§27 Phase 5 — pipeline parser). */
2069
2988
  validate(def: PipelineDefinition): void;
2070
2989
  private assertAcyclic;
@@ -2073,13 +2992,18 @@ declare class PipelineEngine {
2073
2992
  * dependencies, which enable parallel branches.
2074
2993
  */
2075
2994
  private effectiveDependencies;
2076
- run(def: PipelineDefinition, options?: RunPipelineOptions): Promise<PipelineRun>;
2995
+ run(def: PipelineDefinition, options?: PipelineRunOptions): Promise<PipelineRun>;
2996
+ /** First-class cancellation (§9.2): requests cancellation and terminates
2997
+ * tasks that are running in this process immediately. */
2998
+ cancel(runId: string): Promise<void>;
2077
2999
  get(runId: string): Promise<PipelineRun | undefined>;
2078
3000
  listRuns(filter?: {
2079
3001
  pipelineId?: string;
2080
3002
  }): Promise<PipelineRun[]>;
2081
3003
  private shouldRun;
2082
3004
  private executeStep;
3005
+ /** Registers tasks created for a step as live, so cancellation can terminate them (§9.2). */
3006
+ private trackLiveTasks;
2083
3007
  private executeStepOnce;
2084
3008
  /** Research fan-out: one task per agent, in parallel (§15). */
2085
3009
  private runFanOut;
@@ -2111,6 +3035,6 @@ declare class ProjectStores {
2111
3035
  constructor(directory?: string);
2112
3036
  }
2113
3037
 
2114
- declare const OMNINODE_VERSION = "2.0.0-alpha.1";
3038
+ declare const OMNINODE_VERSION = "2.0.0-alpha.11";
2115
3039
 
2116
- 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, FilePlanStore, FileReportStore, FileTaskStore, type Finding, type FindingSeverity, type FindingSource, HeuristicPlanner, type HttpRequestOptions, type HttpResponse, type IAgent, type IChatProvider, type IMemoryProvider, type IPlanner, type IProvider, type JsonDocument, JsonFileStore, type JsonFileStoreOptions, 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, ModelPlanner, 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 PlanFilter, type PlanRequest, type PlanStep, type PlanStore, type PlannerConfigYaml, PlannerError, ProcessAgent, type Project, type ProjectConfigYaml, ProjectStores, 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, buildChildEnv, buildPipelineEngine, buildPlanner, buildPlannerContext, buildRoleRegistry, composeTaskText, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, defaultProjectConfigYaml, expandEnvRefs, extractReportFromText, findConfigFile, isOmniNodeError, keywords, loadConfig, logger, parsePlanJson, pipelineConfigSchema, pipelineStepConfigSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, registryKey, requestJson, resolveApiKey, roleConfigSchema, similar };
3040
+ 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 PlanJsonResult, type PlanRequest, type PlanStep, type PlanStore, type PlanValidationIssue, type PlanValidationResult, 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, planJsonSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, providerHttpError, providerTransportError, registryKey, requestJson, requireCompletion, resolveApiKey, resolveEnvPolicy, roleConfigSchema, sanitizeChunk, similar, validateEnvelope, validatePlan, validateReport, validateWorkingDirectory };