@bluecopa/harness 2.0.0 → 2.0.1-snapshot.1

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.
@@ -1,7 +1,89 @@
1
- import { A as AnyTool, T as ToolProvider, a as ToolResult, M as ModelFactory, b as ToolResultArtifact } from '../shared-types-DRxnerLT.js';
2
- export { c as ActionType, B as BashOptions, d as BatchOp, e as BatchResult, G as GlobOptions, f as GrepOptions, R as ReadOptions, g as TextEditorRequest, h as ThreadStatus, i as ToolProviderCapabilities, W as WebFetchOptions } from '../shared-types-DRxnerLT.js';
1
+ import { A as AnyTool, T as ToolProvider, a as ToolResult, M as ModelFactory, b as ToolResultArtifact } from '../shared-types-vZuVoy_H.js';
2
+ export { c as ActionType, B as BashOptions, d as BatchOp, e as BatchResult, G as GlobOptions, f as GrepOptions, R as ReadOptions, g as TextEditorRequest, h as ThreadStatus, i as ToolProviderCapabilities, W as WebFetchOptions } from '../shared-types-vZuVoy_H.js';
3
+ import { HarnessTelemetry } from '../observability/otel.js';
3
4
  import 'ai';
4
5
 
6
+ /** Long-running job orchestration primitives. Generic; no coding-agent assumptions. */
7
+ type JobKind = "local" | "remote";
8
+ /** Discriminated on `kind` so remote-only fields only exist on remote transports. */
9
+ type JobTransport = {
10
+ kind: "local";
11
+ } | {
12
+ kind: "remote";
13
+ host: string;
14
+ user?: string | undefined;
15
+ keyPath?: string | undefined;
16
+ };
17
+ interface JobSpec {
18
+ id: string;
19
+ label: string;
20
+ command: string;
21
+ cwd?: string | undefined;
22
+ env?: Record<string, string> | undefined;
23
+ transport: JobTransport;
24
+ startedAt: number;
25
+ startedBy?: {
26
+ tupleId?: string | undefined;
27
+ turn?: number | undefined;
28
+ } | undefined;
29
+ }
30
+ type JobState = "running" | "exited" | "failed" | "killed" | "unknown";
31
+ interface JobStatus {
32
+ spec: JobSpec;
33
+ state: JobState;
34
+ /** Local supervisor PID. */
35
+ pid?: number | undefined;
36
+ /** Remote parent PID (only set when transport.kind === "remote"). */
37
+ remotePid?: number | undefined;
38
+ exitCode?: number | undefined;
39
+ /** Mirrors spec.startedAt; kept on the status for convenience when reading status without spec unpacking. */
40
+ startedAt: number;
41
+ endedAt?: number | undefined;
42
+ lastSeenAliveAt: number;
43
+ tailLines: string[];
44
+ bytesWritten: number;
45
+ }
46
+ type JobEvent = {
47
+ type: "job_started";
48
+ status: JobStatus;
49
+ } | {
50
+ type: "job_output";
51
+ id: string;
52
+ chunk: string;
53
+ at: number;
54
+ } | {
55
+ type: "job_exited";
56
+ status: JobStatus;
57
+ } | {
58
+ type: "job_failed";
59
+ status: JobStatus;
60
+ error: string;
61
+ } | {
62
+ type: "job_killed";
63
+ status: JobStatus;
64
+ reason: string;
65
+ };
66
+ interface JobStartOptions {
67
+ label: string;
68
+ command: string;
69
+ transport?: JobTransport | undefined;
70
+ cwd?: string | undefined;
71
+ env?: Record<string, string> | undefined;
72
+ }
73
+ interface JobRegistry {
74
+ start(opts: JobStartOptions, startedBy?: JobSpec["startedBy"]): Promise<JobStatus>;
75
+ check(id: string): Promise<JobStatus | null>;
76
+ cancel(id: string, signal?: "TERM" | "KILL"): Promise<JobStatus | null>;
77
+ list(): Promise<JobStatus[]>;
78
+ tail(id: string, lines?: number): Promise<string[]>;
79
+ waitFor(id: string, signal?: AbortSignal): Promise<JobStatus>;
80
+ subscribe(handler: (e: JobEvent) => void): () => void;
81
+ /** Cheap synchronous snapshot — suitable for orchestrator context each turn. */
82
+ snapshot(): JobStatus[];
83
+ /** Remove completed/killed/failed jobs older than `olderThanMs` (default 24h). Returns count removed. */
84
+ prune(olderThanMs?: number): Promise<number>;
85
+ }
86
+
5
87
  interface ToolCallInfo {
6
88
  toolCallId: string;
7
89
  toolName: string;
@@ -40,15 +122,37 @@ interface AgentMessage {
40
122
  * (truecode). The harness only provides the Tool contract and helpers.
41
123
  */
42
124
 
125
+ type ToolExecutionMode = "serial" | "parallel";
43
126
  /** A registered tool: schema for the model, execute for the worker */
44
127
  interface Tool {
45
128
  name: string;
46
129
  /** AI SDK tool schema. Optional for ARC-internal tools (ReadEpisode, LCM_*, ScratchPad_*). */
47
130
  schema?: AnyTool | undefined;
131
+ /** Worker execution mode for batched tool calls. Defaults to serial. */
132
+ executionMode?: ToolExecutionMode | ((args: Record<string, unknown>) => ToolExecutionMode);
48
133
  /** Execute using the ToolProvider. If not set, tool is handled externally (e.g. ARC tools). */
49
134
  execute?: (provider: ToolProvider, args: Record<string, unknown>, workDir: string) => Promise<ToolResult>;
135
+ /**
136
+ * When true, this tool may yield the worker loop if the operation is incomplete.
137
+ * After execution, the worker checks if the target thread is still running.
138
+ * If it is and `waitForThread` is available on the ToolProvider, the worker
139
+ * suspends (does not count a step) until the thread completes.
140
+ * The tool args must include a `threadId` field for the worker to track.
141
+ */
142
+ yieldsOnIncomplete?: boolean | undefined;
50
143
  }
51
144
 
145
+ /**
146
+ * Serialized attachment form suitable for JSON persistence. Unlike the in-flight
147
+ * `ContentPart` (which carries a `Buffer`), the stored form keeps image bytes
148
+ * base64-encoded so messages round-trip cleanly through session snapshots.
149
+ * Converted to a real `ContentPart` only when building AgentMessage[] for the model.
150
+ */
151
+ interface StoredAttachment {
152
+ type: "image";
153
+ imageBase64: string;
154
+ mimeType: string;
155
+ }
52
156
  interface StoredMessage {
53
157
  id: string;
54
158
  conversationId: string;
@@ -57,6 +161,8 @@ interface StoredMessage {
57
161
  content: string;
58
162
  toolCalls?: ToolCallInfo[];
59
163
  toolResults?: ToolResultInfo[];
164
+ /** Multimodal image attachments. Persisted as base64; converted to ContentPart[] at model-call time. */
165
+ attachments?: StoredAttachment[];
60
166
  timestamp: number;
61
167
  }
62
168
  interface GrepResult {
@@ -232,7 +338,7 @@ interface ExpectedOutputContract {
232
338
  description?: string | undefined;
233
339
  }
234
340
  /** Worker model tier for dispatch routing. */
235
- type DispatchTier = "fast" | "strong";
341
+ type DispatchTier = "fast" | "medium" | "strong";
236
342
  /** Worker instruction tuple */
237
343
  interface Tuple {
238
344
  id: string;
@@ -243,12 +349,22 @@ interface Tuple {
243
349
  expectedOutput: ExpectedOutputContract;
244
350
  /** Tool names available to worker */
245
351
  tools: string[];
246
- /** Step budget (1-10) */
352
+ /** Step budget */
247
353
  steps: number;
248
- /** Worker model tier 'fast' for simple tasks, 'strong' (default) for complex reasoning. */
354
+ /** Worker model tier. Omitted dispatches use the default step budget and strong worker model. */
249
355
  tier?: DispatchTier | undefined;
356
+ /** Semantic role label for this worker (e.g. "Debugger", "Researcher", "Sysadmin").
357
+ * Shown in the TUI instead of the generic tier name to give the user a clear
358
+ * mental model of what the worker is doing. */
359
+ role?: string | undefined;
250
360
  /** Public orchestrator rationale that preceded this dispatch */
251
361
  orchestratorContext?: string | undefined;
362
+ /** Prior tuple this dispatch is continuing from, when ARC resumes internally. */
363
+ continuationOf?: string | undefined;
364
+ /** Why ARC created this continuation dispatch. */
365
+ continuationReason?: "step_budget" | "user_steering" | undefined;
366
+ /** Compact user-facing checkpoint summary for continuation UI. */
367
+ continuationSummary?: string | undefined;
252
368
  }
253
369
  interface DispatchRecord {
254
370
  tuple: Tuple;
@@ -286,6 +402,16 @@ interface TraceToolCall {
286
402
  args: Record<string, unknown>;
287
403
  }
288
404
  type ArcTraceEvent = {
405
+ scope: "orchestrator";
406
+ phase: "context_assembled";
407
+ turn: number;
408
+ totalChars: number;
409
+ estimatedTokens: number;
410
+ sections: Record<string, {
411
+ chars: number;
412
+ estimatedTokens: number;
413
+ }>;
414
+ } | {
289
415
  scope: "orchestrator";
290
416
  phase: "model_input";
291
417
  turn: number;
@@ -341,6 +467,12 @@ type ArcTraceEvent = {
341
467
  tupleId: string;
342
468
  step: number;
343
469
  toolNames: string[];
470
+ } | {
471
+ scope: "worker";
472
+ phase: "textual_tool_call_rescued";
473
+ tupleId: string;
474
+ step: number;
475
+ toolNames: string[];
344
476
  } | {
345
477
  scope: "worker";
346
478
  phase: "tool_call";
@@ -374,6 +506,8 @@ interface VectorIndex {
374
506
  search(query: string, k: number): Promise<string[]>;
375
507
  load(): Promise<void>;
376
508
  save(): Promise<void>;
509
+ /** Number of documents currently indexed. Used to detect empty index on session resume. */
510
+ size(): Promise<number>;
377
511
  }
378
512
  interface ArtifactStore {
379
513
  set(id: string, artifact: Artifact): Promise<void>;
@@ -443,6 +577,11 @@ interface OrchestratorContext {
443
577
 
444
578
  interface ArcConfig {
445
579
  task: string;
580
+ /**
581
+ * Image attachments to inject alongside the initial task when the orchestrator
582
+ * model is multimodal. Subsequent task attachments flow through pushTask instead.
583
+ */
584
+ initialAttachments?: StoredAttachment[] | undefined;
446
585
  workDir: string;
447
586
  /** Model ID for the orchestrator */
448
587
  model: string;
@@ -450,13 +589,17 @@ interface ArcConfig {
450
589
  workerModel: string;
451
590
  /** Optional per-tier worker model overrides. Falls back to workerModel when a tier is missing. */
452
591
  workerModelMap?: Partial<Record<DispatchTier, string>> | undefined;
592
+ /** Optional per-tier worker step budgets. Falls back to ARC defaults when unset. */
593
+ workerStepBudgets?: Partial<Record<DispatchTier, number>> | undefined;
594
+ /** Optional cheap model for post-dispatch completion gating. Falls back to workerModelMap.fast, then workerModel. */
595
+ doneGateModel?: string | undefined;
453
596
  createModel?: ModelFactory;
454
597
  toolProvider: ToolProvider;
455
598
  /** Agent-provided tool definitions (Bash, Read, Write, etc.) with schemas, execute, and artifact metadata. Harness adds ARC framework tools internally. */
456
599
  tools?: Map<string, Tool> | undefined;
457
600
  /** Max orchestrator turns before stopping (default: 12) */
458
601
  maxTurns?: number;
459
- /** Max steps per worker (default: 5, max: 10) */
602
+ /** Max steps per untiered worker (default: 30). Explicit tiers use workerStepBudgets/default tier budgets. */
460
603
  maxStepsPerWorker?: number;
461
604
  /** Rolling window size for orchestrator context (default: 10) */
462
605
  orchestratorWindowSize?: number;
@@ -470,6 +613,8 @@ interface ArcConfig {
470
613
  transcriptStore?: TranscriptStore;
471
614
  /** Injected artifact store (default: in-memory) */
472
615
  artifactStore?: ArtifactStore;
616
+ /** Custom orchestrator system prompt (appended to default) */
617
+ orchestratorSystemPromptSuffix?: string | undefined;
473
618
  /** Custom worker system prompt (appended to default) */
474
619
  workerSystemPromptSuffix?: string | undefined;
475
620
  /** Custom messages after the core task/budget block */
@@ -478,12 +623,18 @@ interface ArcConfig {
478
623
  providerOptions?: Record<string, unknown> | undefined;
479
624
  /** Optional hook runner for PreToolUse/PostToolUse/BeforeWorker/AfterWorker events */
480
625
  hookRunner?: HookRunner | undefined;
626
+ /** Optional telemetry collector for profiling spans and metrics. */
627
+ telemetry?: HarnessTelemetry | undefined;
481
628
  /** Callback for AskUser orchestrator tool. If provided, AskUser is available to the orchestrator. */
482
629
  askUser?: ((question: string, options?: string[]) => Promise<string>) | undefined;
483
630
  /** Session store for persistence across restarts. */
484
631
  sessionStore?: SessionStore | undefined;
485
632
  /** Session ID to resume. If provided with sessionStore, loop hydrates from saved state. */
486
633
  sessionId?: string | undefined;
634
+ /** Job registry for long-running process orchestration. Default: MemoryJobRegistry. */
635
+ jobRegistry?: JobRegistry | undefined;
636
+ /** Per model-call timeout in milliseconds. Applied to both orchestrator and worker generateText. Default: 180000 (3 min). */
637
+ modelCallTimeoutMs?: number | undefined;
487
638
  }
488
639
  type ArcEvent = {
489
640
  type: "orchestrator_turn";
@@ -499,6 +650,12 @@ type ArcEvent = {
499
650
  } | {
500
651
  type: "dispatch_full";
501
652
  tuple: Tuple;
653
+ } | {
654
+ type: "worker_continuation";
655
+ tupleId: string;
656
+ fromTupleId: string;
657
+ reason: "step_budget" | "user_steering";
658
+ summary: string;
502
659
  } | {
503
660
  type: "worker_progress";
504
661
  tupleId: string;
@@ -523,6 +680,9 @@ type ArcEvent = {
523
680
  type: "ask_user";
524
681
  question: string;
525
682
  options?: string[] | undefined;
683
+ } | {
684
+ type: "interrupt_status";
685
+ summary: string;
526
686
  } | {
527
687
  type: "orchestrator_usage";
528
688
  turn: number;
@@ -537,6 +697,20 @@ type ArcEvent = {
537
697
  } | {
538
698
  type: "text_delta";
539
699
  text: string;
700
+ } | {
701
+ type: "reasoning_delta";
702
+ text: string;
703
+ } | {
704
+ type: "job_event";
705
+ event: JobEvent;
706
+ } | {
707
+ type: "interjection_queued";
708
+ position: number;
709
+ text: string;
710
+ } | {
711
+ type: "interjection_delivered";
712
+ position: number;
713
+ turn: number;
540
714
  };
541
715
  type WorkerProgressEvent = {
542
716
  kind: "model_start";
@@ -573,7 +747,9 @@ type WorkerProgressEvent = {
573
747
  durationMs: number;
574
748
  outputSummary: string;
575
749
  output?: string | undefined;
750
+ artifact?: ToolResultArtifact | undefined;
576
751
  exitCode?: unknown;
752
+ metadata?: Record<string, unknown> | undefined;
577
753
  } | {
578
754
  kind: "tool_error";
579
755
  step: number;
@@ -586,6 +762,18 @@ type WorkerProgressEvent = {
586
762
  status: "complete" | "incomplete" | "failed" | "interrupted";
587
763
  stepsUsed: number;
588
764
  summary: string;
765
+ } | {
766
+ kind: "yield_start";
767
+ step: number;
768
+ toolCallId: string;
769
+ toolName: string;
770
+ threadId: string;
771
+ } | {
772
+ kind: "yield_resume";
773
+ step: number;
774
+ toolCallId: string;
775
+ toolName: string;
776
+ threadId: string;
589
777
  };
590
778
  interface RunWorkerConfig {
591
779
  /** Original top-level task */
@@ -608,6 +796,8 @@ interface RunWorkerConfig {
608
796
  signal?: AbortSignal | undefined;
609
797
  /** Extra text prefixed to worker system prompt */
610
798
  systemPromptPrefix?: string | undefined;
799
+ /** Semantic role label for TUI display (e.g. "Debugger", "Researcher"). */
800
+ role?: string | undefined;
611
801
  /** Extra text appended to worker system prompt */
612
802
  systemPromptSuffix?: string | undefined;
613
803
  /** Provider options passed to generateText (e.g. reasoning config). */
@@ -622,6 +812,18 @@ interface RunWorkerConfig {
622
812
  onTrace?: ((event: ArcTraceEvent) => void) | undefined;
623
813
  /** Optional hook runner for PreToolUse/PostToolUse events */
624
814
  hookRunner?: HookRunner | undefined;
815
+ /** Optional telemetry collector for profiling spans and metrics. */
816
+ telemetry?: HarnessTelemetry | undefined;
817
+ /** Current sub-dispatch depth (0 = top-level worker). Used to enforce max depth. */
818
+ dispatchDepth?: number | undefined;
819
+ /** Existing messages to resume from (for continuations). When set, the worker
820
+ * appends `instruction` as a user message to these messages instead of building
821
+ * a fresh initial prompt. */
822
+ resumeMessages?: AgentMessage[] | undefined;
823
+ /** Steps already consumed before this resume (for accurate step counting). */
824
+ stepsAlreadyUsed?: number | undefined;
825
+ /** Per model-call timeout in milliseconds. Default: 180000 (3 min). */
826
+ modelCallTimeoutMs?: number | undefined;
625
827
  }
626
828
  interface WorkerResult {
627
829
  transcript: AgentMessage[];
@@ -640,47 +842,108 @@ interface ArcRunResult {
640
842
  output: string;
641
843
  events: ArcEvent[];
642
844
  }
845
+ type PushResult = {
846
+ delivered: "as_task";
847
+ } | {
848
+ delivered: "as_interjection";
849
+ position: number;
850
+ } | {
851
+ delivered: "dropped";
852
+ reason: "in_ask_user";
853
+ };
854
+ interface PushTaskOptions {
855
+ /** Multimodal attachments to attach to the resulting user message. */
856
+ attachments?: StoredAttachment[];
857
+ }
643
858
  declare class ArcLoop {
644
859
  private config;
645
860
  private readonly transcriptStore;
646
861
  private readonly vectorIndex;
647
862
  private readonly scratchPad;
648
863
  private readonly artifactStore;
864
+ private readonly jobRegistry;
865
+ /** Non-output job events queued for orchestrator turn-boundary injection. */
866
+ private pendingJobEvents;
867
+ /** Events that need to flow out of the async generator stream (job events, interjection lifecycle). */
868
+ private pendingArcEvents;
869
+ private jobUnsubscribe;
870
+ private readonly telemetry;
649
871
  private messageStore;
650
872
  private summaryDAG;
651
873
  private readonly createModel;
652
874
  private readonly windowSize;
653
875
  private readonly model;
876
+ private readonly doneGateModel;
877
+ /** Full orchestrator system prompt (base + optional suffix). */
878
+ private readonly orchestratorSystem;
654
879
  /** Orchestrator tool schemas (for the model) */
655
880
  private readonly orchestratorToolSchemas;
656
881
  /** Orchestrator tool registry (for execute) — excludes dispatch/done (control flow) */
657
882
  private readonly orchestratorToolRegistry;
883
+ /** ARC framework tools that are always available to workers. */
884
+ private readonly workerArcTools;
658
885
  /** Dispatcher deps + mutable state — shared with dispatcher.ts functions */
659
886
  private readonly dispatchDeps;
660
887
  private readonly dispatchState;
661
888
  private orchestratorMessageIndex;
662
889
  private turn;
663
890
  private maxTurns;
891
+ private readonly inFlightDispatches;
892
+ private readonly historySearchesThisTask;
893
+ private readonly historyReadsThisTask;
894
+ private readonly historyExpansionsThisTask;
895
+ private readonly historyExpansionSummaryCache;
896
+ private lastSessionCheckpointAt;
664
897
  /** Per-turn abort controller — cancelled by interrupt(), refreshed each turn. */
665
898
  private turnController;
666
899
  /** Resolver for the next task — set when the loop is waiting between tasks. */
667
900
  private taskResolve;
901
+ private pendingInterjections;
902
+ /** Image attachments for the currently active task. Injected into orchestrator prompts. */
903
+ private currentTaskAttachments;
904
+ /** Consecutive dispatch rounds where every dispatch ended in failed/incomplete. Forces done at threshold. */
905
+ private consecutiveFailedDispatchRounds;
906
+ private askUserPending;
907
+ private readonly modelCallTimeoutMs;
668
908
  constructor(config: ArcConfig);
909
+ /**
910
+ * Replace agent-provided worker tools for future dispatches.
911
+ * Already-running workers keep the tool set they started with.
912
+ */
913
+ refreshWorkerTools(tools: Map<string, Tool>): void;
914
+ /** Drain events from asynchronous sources (job registry, interjections) into the generator stream. */
915
+ private drainPendingArcEvents;
916
+ private drainPendingJobEvents;
917
+ private drainPendingInterjections;
918
+ /** Release subscriptions and free resources held by this loop. */
919
+ dispose(): void;
669
920
  /**
670
921
  * Interrupt the current turn — cancels in-flight model calls and workers.
671
922
  * The orchestrator loop stays alive and will prompt for user steering.
672
923
  */
673
924
  interrupt(): void;
925
+ private refreshTurnSignal;
674
926
  /** True when the loop is waiting for the next task (between done boundaries). */
675
927
  get idle(): boolean;
928
+ /** Serialize current loop state for UI-level checkpoints. */
929
+ getSessionSnapshot(): SessionSnapshot;
930
+ /** Restore loop state from a prior UI-level checkpoint. */
931
+ restoreSessionSnapshot(snapshot: SessionSnapshot | null): void;
676
932
  /**
677
- * Push a follow-up task into the loop. The orchestrator sees it as
678
- * a new user message with full conversational context from prior tasks.
933
+ * Deliver a message to the orchestrator regardless of loop state.
934
+ * - Idle (waiting for next task): resolves waitForNextTask becomes next task.
935
+ * - Running: queued as [user interjection], drained at next turn boundary.
936
+ * - Inside askUser: dropped; caller should resolve the askUser promise directly.
679
937
  */
680
- pushTask(task: string): boolean;
938
+ pushTask(msg: string, options?: PushTaskOptions): PushResult;
939
+ private wrappedAskUser;
681
940
  private waitForNextTask;
682
941
  /** Save session snapshot + update meta if a session store is configured. */
683
942
  private saveSession;
943
+ private buildSessionSnapshot;
944
+ private checkpointSession;
945
+ private checkpointAfterDispatchEvent;
946
+ private clearCompletedInFlightDispatches;
684
947
  /** Reset per-task state while keeping full conversation history. */
685
948
  private resetForNewTask;
686
949
  /**
@@ -692,17 +955,30 @@ declare class ArcLoop {
692
955
  * Breaks after the first `done` event — does not wait for follow-up tasks.
693
956
  */
694
957
  run(signal?: AbortSignal): Promise<ArcRunResult>;
958
+ private runDispatchCalls;
959
+ private continueStepBudgetDispatches;
960
+ private buildContinuationDispatchArgs;
961
+ private runDoneGate;
962
+ private completeCurrentTask;
695
963
  /** Append a message to the LCM message store (single source of truth) */
696
964
  private appendOrchestratorMessage;
697
965
  private findEpisodeRecordBySummaryId;
966
+ private searchHistoryWithGuardrails;
967
+ private readHistoryWithGuardrails;
968
+ private expandHistoryWithGuardrails;
969
+ private summarizeHistoryExpansion;
698
970
  private buildContext;
699
971
  private buildOrchestratorMessages;
700
972
  private buildTaskContextText;
973
+ private buildAttachmentMessage;
701
974
  private readEpisode;
702
975
  /**
703
- * Handle a turn interrupt: prompt user for steering, inject into context.
976
+ * Handle a turn interrupt without routing every follow-up through the
977
+ * orchestrator. Status questions are answered from the saved worker record;
978
+ * steering/continue become an internal worker continuation.
704
979
  */
705
980
  private handleInterrupt;
981
+ private formatInterruptStatus;
706
982
  }
707
983
 
708
984
  /**
@@ -720,6 +996,15 @@ declare function formatDispatchForPrompt(record: DispatchRecord, options?: {
720
996
 
721
997
  declare function cloneForTrace<T>(value: T): T;
722
998
 
999
+ /** Default budget for dispatches that do not request a tier. */
1000
+ declare const DEFAULT_MAX_STEPS_PER_WORKER = 30;
1001
+ /** Per-tier initial budgets. Strong is intentionally larger for implementation loops. */
1002
+ declare const DEFAULT_WORKER_STEP_BUDGETS: Record<DispatchTier, number>;
1003
+ /** Hard ceiling on worker steps after RequestMoreSteps extensions. */
1004
+ declare const ABSOLUTE_MAX_WORKER_STEPS = 60;
1005
+ /** Recommended extension size when workers need to keep their current context. */
1006
+ declare const REQUEST_MORE_STEPS_INCREMENT = 15;
1007
+
723
1008
  /** In-memory transcript store for testing */
724
1009
  declare class MemoryTranscriptStore implements TranscriptStore {
725
1010
  private transcripts;
@@ -735,6 +1020,7 @@ declare class MemoryVectorIndex implements VectorIndex {
735
1020
  search(query: string, k: number): Promise<string[]>;
736
1021
  load(): Promise<void>;
737
1022
  save(): Promise<void>;
1023
+ size(): Promise<number>;
738
1024
  }
739
1025
  /** In-memory scratch pad for testing */
740
1026
  declare class MemoryScratchPad implements ScratchPad {
@@ -793,4 +1079,29 @@ declare class FsArtifactStore implements ArtifactStore {
793
1079
  private save;
794
1080
  }
795
1081
 
796
- export { AnyTool, type ArcConfig, type ArcEvent, ArcLoop, type ArcRunResult, type ArcTraceEvent, type Artifact, type ArtifactStore, type DispatchRecord, type DispatchTier, type ExpectedArtifact, type ExpectedOutputContract, FsArtifactStore, FsTranscriptStore, MemoryArtifactStore, MemoryMessageStore, MemoryScratchPad, MemorySessionStore, MemorySummaryDAG, MemoryTranscriptStore, MemoryVectorIndex, type MessageStore, ModelFactory, type OodaSnapshot, type OrchestratorContext, type ReadEpisodeArgs, type ReadEpisodeDetail, type RunWorkerConfig, type ScratchPad, type SessionMeta, type SessionSnapshot, type SessionStore, type StoredMessage, type SummaryDAG, type SummaryNode, type Tool, ToolProvider, ToolResult, ToolResultArtifact, type TraceToolCall, type Transcript, type TranscriptStore, type Tuple, type VectorIndex, type WorkerProgressEvent, type WorkerResult, cloneForTrace, formatDispatchForPrompt };
1082
+ /**
1083
+ * In-memory reference implementation of JobRegistry.
1084
+ *
1085
+ * Jobs here never actually spawn processes — callers use `simulateExit` /
1086
+ * `simulateOutput` / `simulateFailure` to drive state. Intended for tests
1087
+ * and agents that don't need filesystem-backed persistence.
1088
+ */
1089
+ declare class MemoryJobRegistry implements JobRegistry {
1090
+ private jobs;
1091
+ private handlers;
1092
+ private seq;
1093
+ start(opts: JobStartOptions, startedBy?: JobSpec["startedBy"]): Promise<JobStatus>;
1094
+ check(id: string): Promise<JobStatus | null>;
1095
+ cancel(id: string, _signal?: "TERM" | "KILL"): Promise<JobStatus | null>;
1096
+ list(): Promise<JobStatus[]>;
1097
+ tail(id: string, lines?: number): Promise<string[]>;
1098
+ waitFor(id: string, signal?: AbortSignal): Promise<JobStatus>;
1099
+ subscribe(handler: (e: JobEvent) => void): () => void;
1100
+ snapshot(): JobStatus[];
1101
+ prune(_olderThanMs?: number): Promise<number>;
1102
+ simulateOutput(id: string, chunk: string): void;
1103
+ simulateExit(id: string, exitCode: number): void;
1104
+ private emit;
1105
+ }
1106
+
1107
+ export { ABSOLUTE_MAX_WORKER_STEPS, AnyTool, type ArcConfig, type ArcEvent, ArcLoop, type ArcRunResult, type ArcTraceEvent, type Artifact, type ArtifactStore, DEFAULT_MAX_STEPS_PER_WORKER, DEFAULT_WORKER_STEP_BUDGETS, type DispatchRecord, type DispatchTier, type ExpectedArtifact, type ExpectedOutputContract, FsArtifactStore, FsTranscriptStore, type JobEvent, type JobKind, type JobRegistry, type JobSpec, type JobStartOptions, type JobState, type JobStatus, type JobTransport, MemoryArtifactStore, MemoryJobRegistry, MemoryMessageStore, MemoryScratchPad, MemorySessionStore, MemorySummaryDAG, MemoryTranscriptStore, MemoryVectorIndex, type MessageStore, ModelFactory, type OodaSnapshot, type OrchestratorContext, type PushResult, REQUEST_MORE_STEPS_INCREMENT, type ReadEpisodeArgs, type ReadEpisodeDetail, type RunWorkerConfig, type ScratchPad, type SessionMeta, type SessionSnapshot, type SessionStore, type StoredAttachment, type StoredMessage, type SummaryDAG, type SummaryNode, type Tool, type ToolExecutionMode, ToolProvider, ToolResult, ToolResultArtifact, type TraceToolCall, type Transcript, type TranscriptStore, type Tuple, type VectorIndex, type WorkerProgressEvent, type WorkerResult, cloneForTrace, formatDispatchForPrompt };