@zhixuan92/multi-model-agent-core 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +0 -6
  2. package/dist/config/schema.d.ts +73 -45
  3. package/dist/config/schema.d.ts.map +1 -1
  4. package/dist/config/schema.js +14 -0
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/context/context-block-store.d.ts +75 -0
  7. package/dist/context/context-block-store.d.ts.map +1 -0
  8. package/dist/context/context-block-store.js +82 -0
  9. package/dist/context/context-block-store.js.map +1 -0
  10. package/dist/context/expand-context-blocks.d.ts +20 -0
  11. package/dist/context/expand-context-blocks.d.ts.map +1 -0
  12. package/dist/context/expand-context-blocks.js +46 -0
  13. package/dist/context/expand-context-blocks.js.map +1 -0
  14. package/dist/delegate-with-escalation.d.ts +34 -0
  15. package/dist/delegate-with-escalation.d.ts.map +1 -0
  16. package/dist/delegate-with-escalation.js +172 -0
  17. package/dist/delegate-with-escalation.js.map +1 -0
  18. package/dist/index.d.ts +4 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/model-profiles.json +42 -4
  23. package/dist/provider.d.ts.map +1 -1
  24. package/dist/provider.js +7 -1
  25. package/dist/provider.js.map +1 -1
  26. package/dist/routing/model-profiles.d.ts +9 -4
  27. package/dist/routing/model-profiles.d.ts.map +1 -1
  28. package/dist/routing/model-profiles.js +8 -0
  29. package/dist/routing/model-profiles.js.map +1 -1
  30. package/dist/run-tasks.d.ts +26 -2
  31. package/dist/run-tasks.d.ts.map +1 -1
  32. package/dist/run-tasks.js +61 -19
  33. package/dist/run-tasks.js.map +1 -1
  34. package/dist/runners/claude-runner.d.ts.map +1 -1
  35. package/dist/runners/claude-runner.js +721 -32
  36. package/dist/runners/claude-runner.js.map +1 -1
  37. package/dist/runners/codex-runner.d.ts.map +1 -1
  38. package/dist/runners/codex-runner.js +541 -48
  39. package/dist/runners/codex-runner.js.map +1 -1
  40. package/dist/runners/error-classification.d.ts +30 -0
  41. package/dist/runners/error-classification.d.ts.map +1 -0
  42. package/dist/runners/error-classification.js +72 -0
  43. package/dist/runners/error-classification.js.map +1 -0
  44. package/dist/runners/injection-type.d.ts +22 -0
  45. package/dist/runners/injection-type.d.ts.map +1 -0
  46. package/dist/runners/injection-type.js +34 -0
  47. package/dist/runners/injection-type.js.map +1 -0
  48. package/dist/runners/openai-runner.d.ts +5 -0
  49. package/dist/runners/openai-runner.d.ts.map +1 -1
  50. package/dist/runners/openai-runner.js +608 -36
  51. package/dist/runners/openai-runner.js.map +1 -1
  52. package/dist/runners/prevention.d.ts +41 -0
  53. package/dist/runners/prevention.d.ts.map +1 -0
  54. package/dist/runners/prevention.js +68 -0
  55. package/dist/runners/prevention.js.map +1 -0
  56. package/dist/runners/supervision.d.ts +137 -0
  57. package/dist/runners/supervision.d.ts.map +1 -0
  58. package/dist/runners/supervision.js +345 -0
  59. package/dist/runners/supervision.js.map +1 -0
  60. package/dist/tools/claude-adapter.d.ts.map +1 -1
  61. package/dist/tools/claude-adapter.js +6 -3
  62. package/dist/tools/claude-adapter.js.map +1 -1
  63. package/dist/tools/definitions.d.ts +3 -1
  64. package/dist/tools/definitions.d.ts.map +1 -1
  65. package/dist/tools/definitions.js +57 -5
  66. package/dist/tools/definitions.js.map +1 -1
  67. package/dist/tools/openai-adapter.d.ts.map +1 -1
  68. package/dist/tools/openai-adapter.js +6 -3
  69. package/dist/tools/openai-adapter.js.map +1 -1
  70. package/dist/tools/scratchpad.d.ts +28 -0
  71. package/dist/tools/scratchpad.d.ts.map +1 -0
  72. package/dist/tools/scratchpad.js +49 -0
  73. package/dist/tools/scratchpad.js.map +1 -0
  74. package/dist/tools/tracker.d.ts +42 -2
  75. package/dist/tools/tracker.d.ts.map +1 -1
  76. package/dist/tools/tracker.js +63 -5
  77. package/dist/tools/tracker.js.map +1 -1
  78. package/dist/types.d.ts +261 -2
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/types.js +43 -1
  81. package/dist/types.js.map +1 -1
  82. package/package.json +7 -3
@@ -0,0 +1,28 @@
1
+ /**
2
+ * TextScratchpad — accumulates assistant text emissions across turns of a
3
+ * sub-agent run. The runner appends text from each turn so that, on any
4
+ * termination (clean exit, abort, timeout, error), the salvage layer can
5
+ * return the best buffered text instead of an empty string.
6
+ *
7
+ * See docs/superpowers/specs/2026-04-10-subagent-completion-supervision-design.md
8
+ * Part A.2.1 for the design rationale.
9
+ */
10
+ export declare class TextScratchpad {
11
+ private turns;
12
+ /** Record a non-empty text emission for the given turn. Empty/whitespace
13
+ * emissions are ignored — they have no salvage value. */
14
+ append(turn: number, text: string): void;
15
+ isEmpty(): boolean;
16
+ /** All buffered text concatenated, in turn order, separated by a fixed
17
+ * delimiter. Used as the salvage payload when no clean final answer
18
+ * was produced. */
19
+ toString(): string;
20
+ /** The most recent buffered emission. Empty string if isEmpty(). */
21
+ latest(): string;
22
+ /** The longest buffered emission across all turns. Empty string if
23
+ * isEmpty(). Used by the escalation layer to pick the best salvageable
24
+ * result across multiple provider attempts. */
25
+ longest(): string;
26
+ reset(): void;
27
+ }
28
+ //# sourceMappingURL=scratchpad.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratchpad.d.ts","sourceRoot":"","sources":["../../src/tools/scratchpad.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAwC;IAErD;8DAC0D;IAC1D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxC,OAAO,IAAI,OAAO;IAIlB;;wBAEoB;IACpB,QAAQ,IAAI,MAAM;IAIlB,oEAAoE;IACpE,MAAM,IAAI,MAAM;IAIhB;;oDAEgD;IAChD,OAAO,IAAI,MAAM;IASjB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * TextScratchpad — accumulates assistant text emissions across turns of a
3
+ * sub-agent run. The runner appends text from each turn so that, on any
4
+ * termination (clean exit, abort, timeout, error), the salvage layer can
5
+ * return the best buffered text instead of an empty string.
6
+ *
7
+ * See docs/superpowers/specs/2026-04-10-subagent-completion-supervision-design.md
8
+ * Part A.2.1 for the design rationale.
9
+ */
10
+ export class TextScratchpad {
11
+ turns = [];
12
+ /** Record a non-empty text emission for the given turn. Empty/whitespace
13
+ * emissions are ignored — they have no salvage value. */
14
+ append(turn, text) {
15
+ if (!text || text.trim().length === 0)
16
+ return;
17
+ this.turns.push({ turn, text });
18
+ }
19
+ isEmpty() {
20
+ return this.turns.length === 0;
21
+ }
22
+ /** All buffered text concatenated, in turn order, separated by a fixed
23
+ * delimiter. Used as the salvage payload when no clean final answer
24
+ * was produced. */
25
+ toString() {
26
+ return this.turns.map((t) => t.text).join('\n\n---\n\n');
27
+ }
28
+ /** The most recent buffered emission. Empty string if isEmpty(). */
29
+ latest() {
30
+ return this.turns.length === 0 ? '' : this.turns[this.turns.length - 1].text;
31
+ }
32
+ /** The longest buffered emission across all turns. Empty string if
33
+ * isEmpty(). Used by the escalation layer to pick the best salvageable
34
+ * result across multiple provider attempts. */
35
+ longest() {
36
+ if (this.turns.length === 0)
37
+ return '';
38
+ let best = this.turns[0].text;
39
+ for (const t of this.turns) {
40
+ if (t.text.length > best.length)
41
+ best = t.text;
42
+ }
43
+ return best;
44
+ }
45
+ reset() {
46
+ this.turns = [];
47
+ }
48
+ }
49
+ //# sourceMappingURL=scratchpad.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scratchpad.js","sourceRoot":"","sources":["../../src/tools/scratchpad.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAc;IACjB,KAAK,GAAqC,EAAE,CAAC;IAErD;8DAC0D;IAC1D,MAAM,CAAC,IAAY,EAAE,IAAY;QAC/B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC9C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;wBAEoB;IACpB,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;IAED,oEAAoE;IACpE,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/E,CAAC;IAED;;oDAEgD;IAChD,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACvC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM;gBAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF"}
@@ -1,7 +1,47 @@
1
+ /**
2
+ * Tracks file accesses and tool invocations inside a sub-agent run so the
3
+ * runner can report what the worker actually did. Reads, writes, and tool
4
+ * calls are stored separately because they answer different questions for
5
+ * the caller:
6
+ *
7
+ * - filesRead → "what did the worker look at?" (debugging, audit trail)
8
+ * - directoriesListed → "which directories were enumerated?" (exploration)
9
+ * - filesWritten → "what changed on disk?" (review, rollback)
10
+ * - toolCalls → "what did the worker actually do, in order?"
11
+ * (debugging, post-mortem)
12
+ *
13
+ * Read-only tasks (audits, surveys, exploration) used to return an empty
14
+ * `files` array because the original tracker only recorded writes. That made
15
+ * it impossible to tell whether the worker had done substantial work or had
16
+ * bailed out immediately.
17
+ */
1
18
  export declare class FileTracker {
2
- private files;
19
+ private reads;
20
+ private dirs;
21
+ private writes;
22
+ private toolCalls;
23
+ private readonly onToolCall?;
24
+ /**
25
+ * @param onToolCall Optional callback invoked synchronously after every
26
+ * `trackToolCall(...)`. Used by runners (Task 9+) to stream tool
27
+ * invocations out as `ProgressEvent`s in real time. The callback must
28
+ * not throw; the runner wraps it in `safeSink` before passing it in.
29
+ */
30
+ constructor(onToolCall?: (summary: string) => void);
31
+ trackRead(filePath: string): void;
32
+ trackDirectoryList(dirPath: string): void;
3
33
  trackWrite(filePath: string): void;
4
- getFiles(): string[];
34
+ /**
35
+ * Record a one-line summary of a tool invocation. Order is preserved so
36
+ * the caller can reconstruct what the worker actually did. If an
37
+ * `onToolCall` callback was supplied at construction, it is fired
38
+ * synchronously after the summary is recorded.
39
+ */
40
+ trackToolCall(summary: string): void;
41
+ getReads(): string[];
42
+ getDirectoriesListed(): string[];
43
+ getWrites(): string[];
44
+ getToolCalls(): string[];
5
45
  reset(): void;
6
46
  }
7
47
  //# sourceMappingURL=tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/tools/tracker.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAqB;IAElC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC,QAAQ,IAAI,MAAM,EAAE;IAIpB,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/tools/tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAA4B;IAExD;;;;;OAKG;gBACS,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAIlD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIzC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIlC;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKpC,QAAQ,IAAI,MAAM,EAAE;IAIpB,oBAAoB,IAAI,MAAM,EAAE;IAIhC,SAAS,IAAI,MAAM,EAAE;IAIrB,YAAY,IAAI,MAAM,EAAE;IAIxB,KAAK,IAAI,IAAI;CAMd"}
@@ -1,13 +1,71 @@
1
+ /**
2
+ * Tracks file accesses and tool invocations inside a sub-agent run so the
3
+ * runner can report what the worker actually did. Reads, writes, and tool
4
+ * calls are stored separately because they answer different questions for
5
+ * the caller:
6
+ *
7
+ * - filesRead → "what did the worker look at?" (debugging, audit trail)
8
+ * - directoriesListed → "which directories were enumerated?" (exploration)
9
+ * - filesWritten → "what changed on disk?" (review, rollback)
10
+ * - toolCalls → "what did the worker actually do, in order?"
11
+ * (debugging, post-mortem)
12
+ *
13
+ * Read-only tasks (audits, surveys, exploration) used to return an empty
14
+ * `files` array because the original tracker only recorded writes. That made
15
+ * it impossible to tell whether the worker had done substantial work or had
16
+ * bailed out immediately.
17
+ */
1
18
  export class FileTracker {
2
- files = new Set();
19
+ reads = new Set();
20
+ dirs = [];
21
+ writes = new Set();
22
+ toolCalls = [];
23
+ onToolCall;
24
+ /**
25
+ * @param onToolCall Optional callback invoked synchronously after every
26
+ * `trackToolCall(...)`. Used by runners (Task 9+) to stream tool
27
+ * invocations out as `ProgressEvent`s in real time. The callback must
28
+ * not throw; the runner wraps it in `safeSink` before passing it in.
29
+ */
30
+ constructor(onToolCall) {
31
+ this.onToolCall = onToolCall;
32
+ }
33
+ trackRead(filePath) {
34
+ this.reads.add(filePath);
35
+ }
36
+ trackDirectoryList(dirPath) {
37
+ this.dirs.push(dirPath);
38
+ }
3
39
  trackWrite(filePath) {
4
- this.files.add(filePath);
40
+ this.writes.add(filePath);
41
+ }
42
+ /**
43
+ * Record a one-line summary of a tool invocation. Order is preserved so
44
+ * the caller can reconstruct what the worker actually did. If an
45
+ * `onToolCall` callback was supplied at construction, it is fired
46
+ * synchronously after the summary is recorded.
47
+ */
48
+ trackToolCall(summary) {
49
+ this.toolCalls.push(summary);
50
+ this.onToolCall?.(summary);
51
+ }
52
+ getReads() {
53
+ return [...this.reads].sort();
54
+ }
55
+ getDirectoriesListed() {
56
+ return [...this.dirs];
57
+ }
58
+ getWrites() {
59
+ return [...this.writes].sort();
5
60
  }
6
- getFiles() {
7
- return [...this.files].sort();
61
+ getToolCalls() {
62
+ return [...this.toolCalls];
8
63
  }
9
64
  reset() {
10
- this.files.clear();
65
+ this.reads.clear();
66
+ this.dirs = [];
67
+ this.writes.clear();
68
+ this.toolCalls = [];
11
69
  }
12
70
  }
13
71
  //# sourceMappingURL=tracker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/tools/tracker.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAW;IACd,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,UAAU,CAAC,QAAgB;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,QAAQ;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/tools/tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,WAAW;IACd,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1B,IAAI,GAAa,EAAE,CAAC;IACpB,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3B,SAAS,GAAa,EAAE,CAAC;IAChB,UAAU,CAA6B;IAExD;;;;;OAKG;IACH,YAAY,UAAsC;QAChD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,SAAS,CAAC,QAAgB;QACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,kBAAkB,CAAC,OAAe;QAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,UAAU,CAAC,QAAgB;QACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,OAAe;QAC3B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,oBAAoB;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAED,YAAY;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;CACF"}
package/dist/types.d.ts CHANGED
@@ -1,10 +1,11 @@
1
+ import type { ContextBlockStore } from './context/context-block-store.js';
1
2
  export type Tier = 'trivial' | 'standard' | 'reasoning';
2
3
  export type Capability = 'file_read' | 'file_write' | 'grep' | 'glob' | 'shell' | 'web_search' | 'web_fetch';
3
4
  export type ToolMode = 'none' | 'full';
4
5
  export type SandboxPolicy = 'none' | 'cwd-only';
5
6
  export type Effort = 'none' | 'low' | 'medium' | 'high';
6
7
  export type CostTier = 'free' | 'low' | 'medium' | 'high';
7
- export type RunStatus = 'ok' | 'error' | 'timeout' | 'max_turns';
8
+ export type RunStatus = 'ok' | 'incomplete' | 'max_turns' | 'timeout' | 'api_aborted' | 'api_error' | 'network_error' | 'error';
8
9
  export interface TaskSpec {
9
10
  prompt: string;
10
11
  /** Provider name. If omitted, core auto-selects. */
@@ -17,6 +18,27 @@ export interface TaskSpec {
17
18
  cwd?: string;
18
19
  effort?: Effort;
19
20
  sandboxPolicy?: SandboxPolicy;
21
+ /** Optional context block ids to expand into the prompt before dispatch.
22
+ * Each id is resolved against `RunTasksRuntime.contextBlockStore` in
23
+ * order and its content is prepended to `prompt` separated by
24
+ * '\n\n---\n\n'. The field is stripped from the task that reaches the
25
+ * provider so runners never see it. See `expandContextBlocks`. */
26
+ contextBlockIds?: string[];
27
+ /** Optional caller-declared output expectations. When supplied, the
28
+ * supervision layer can validate the output for enumerable deliverables
29
+ * after syntactic completion checks pass. */
30
+ expectedCoverage?: {
31
+ /** Minimum section count. A section is a line matching `sectionPattern`. */
32
+ minSections?: number;
33
+ /** Regex for section headings. Applied with the multiline flag. */
34
+ sectionPattern?: string;
35
+ /** Substrings that must all appear somewhere in the output. */
36
+ requiredMarkers?: string[];
37
+ };
38
+ /** Opt-in progress capture for post-hoc execution observability. */
39
+ includeProgressTrace?: boolean;
40
+ /** Optional hint about the parent session's model for saved-cost estimates. */
41
+ parentModel?: string;
20
42
  }
21
43
  export interface CodexProviderConfig {
22
44
  type: 'codex';
@@ -27,6 +49,14 @@ export interface CodexProviderConfig {
27
49
  sandboxPolicy?: SandboxPolicy;
28
50
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
29
51
  costTier?: CostTier;
52
+ /** Optional pricing in USD per million input tokens. Used to compute RunResult.usage.costUSD. */
53
+ inputCostPerMTok?: number;
54
+ /** Optional pricing in USD per million output tokens. Used to compute RunResult.usage.costUSD. */
55
+ outputCostPerMTok?: number;
56
+ /** Optional override for the per-provider input token soft limit
57
+ * used by the watchdog. When unset, falls back to the model profile
58
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
59
+ inputTokenSoftLimit?: number;
30
60
  }
31
61
  export interface ClaudeProviderConfig {
32
62
  type: 'claude';
@@ -37,6 +67,13 @@ export interface ClaudeProviderConfig {
37
67
  sandboxPolicy?: SandboxPolicy;
38
68
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
39
69
  costTier?: CostTier;
70
+ /** Optional pricing override; if set, recomputes costUSD from token usage instead of trusting the SDK. */
71
+ inputCostPerMTok?: number;
72
+ outputCostPerMTok?: number;
73
+ /** Optional override for the per-provider input token soft limit
74
+ * used by the watchdog. When unset, falls back to the model profile
75
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
76
+ inputTokenSoftLimit?: number;
40
77
  }
41
78
  export interface OpenAICompatibleProviderConfig {
42
79
  type: 'openai-compatible';
@@ -51,6 +88,14 @@ export interface OpenAICompatibleProviderConfig {
51
88
  sandboxPolicy?: SandboxPolicy;
52
89
  hostedTools?: ('web_search' | 'image_generation' | 'code_interpreter')[];
53
90
  costTier?: CostTier;
91
+ /** Optional pricing in USD per million input tokens. Used to compute RunResult.usage.costUSD. */
92
+ inputCostPerMTok?: number;
93
+ /** Optional pricing in USD per million output tokens. Used to compute RunResult.usage.costUSD. */
94
+ outputCostPerMTok?: number;
95
+ /** Optional override for the per-provider input token soft limit
96
+ * used by the watchdog. When unset, falls back to the model profile
97
+ * default, then to a hardcoded 100_000 fallback. See spec A.1.4. */
98
+ inputTokenSoftLimit?: number;
54
99
  }
55
100
  /** Discriminated union — each provider type has distinct required fields. */
56
101
  export type ProviderConfig = CodexProviderConfig | ClaudeProviderConfig | OpenAICompatibleProviderConfig;
@@ -60,6 +105,11 @@ export interface MultiModelConfig {
60
105
  maxTurns: number;
61
106
  timeoutMs: number;
62
107
  tools: ToolMode;
108
+ /** Character threshold that triggers auto-switch from 'full' to
109
+ * 'summary' response mode when the caller uses `responseMode: 'auto'`
110
+ * (the default). Optional — defaults to 65_536 when absent.
111
+ * Env var and buildMcpServer option can override at higher precedence. */
112
+ largeResponseThresholdChars?: number;
63
113
  };
64
114
  }
65
115
  export interface TokenUsage {
@@ -67,15 +117,115 @@ export interface TokenUsage {
67
117
  outputTokens: number;
68
118
  totalTokens: number;
69
119
  costUSD: number | null;
120
+ /** Estimated cost savings versus the declared parent model, if known. */
121
+ savedCostUSD?: number | null;
70
122
  }
71
123
  export interface RunResult {
72
124
  output: string;
73
125
  status: RunStatus;
74
126
  usage: TokenUsage;
75
127
  turns: number;
76
- files: string[];
128
+ /** Files whose contents the worker read (via readFile/grep/listFiles). */
129
+ filesRead: string[];
130
+ /** Files the worker wrote (via writeFile). */
131
+ filesWritten: string[];
132
+ /** Compact one-line summaries of every tool the worker invoked, in order. */
133
+ toolCalls: string[];
134
+ /** `true` when `output` is a runner-synthesized diagnostic template
135
+ * (`"Sub-agent error: …"`, `"Agent timed out after …"`, the incomplete
136
+ * template from `buildXxxIncompleteDiagnostic`, etc.) because the
137
+ * scratchpad was empty at termination. `false` when `output` contains
138
+ * real model-produced content — either a clean final answer on the
139
+ * `ok` path, or `scratchpad.latest()` on any salvage path where the
140
+ * scratchpad had buffered text.
141
+ *
142
+ * Used by the escalation orchestrator's all-fail fallback to prefer
143
+ * real content over diagnostic templates regardless of status or
144
+ * length (otherwise a long `"Sub-agent error: <stack trace>"` string
145
+ * could beat a shorter genuine partial answer from an earlier
146
+ * attempt). */
147
+ outputIsDiagnostic: boolean;
148
+ /** One entry per provider attempt within this dispatch. Length === 1
149
+ * for tasks that succeeded on the first try; longer when escalation
150
+ * occurred. Runners initialize this to `[]`; the escalation
151
+ * orchestrator populates it on each return path. */
152
+ escalationLog: AttemptRecord[];
153
+ /** Wall-clock duration of this task in milliseconds. */
154
+ durationMs?: number;
155
+ /** Directories whose entries the worker listed. */
156
+ directoriesListed?: string[];
157
+ /** Bounded trace of progress events emitted during this task's run. */
158
+ progressTrace?: ProgressTraceEntry[];
77
159
  error?: string;
78
160
  }
161
+ /** A captured progress entry, or a synthetic marker when trace trimming occurred. */
162
+ export type ProgressTraceEntry = ProgressEvent | {
163
+ kind: '_trimmed';
164
+ droppedCount: number;
165
+ droppedKinds: Partial<Record<ProgressEvent['kind'], number>>;
166
+ capExceededByBoundaryEvents?: boolean;
167
+ };
168
+ /** Aggregate timing metrics for a `delegate_tasks` batch. */
169
+ export interface BatchTimings {
170
+ wallClockMs: number;
171
+ sumOfTaskMs: number;
172
+ estimatedParallelSavingsMs: number;
173
+ }
174
+ /** Aggregate completion counts for a `delegate_tasks` batch. */
175
+ export interface BatchProgress {
176
+ totalTasks: number;
177
+ completedTasks: number;
178
+ incompleteTasks: number;
179
+ failedTasks: number;
180
+ successPercent: number;
181
+ }
182
+ /** Aggregate cost metrics for a `delegate_tasks` batch. */
183
+ export interface BatchAggregateCost {
184
+ totalActualCostUSD: number;
185
+ totalSavedCostUSD: number;
186
+ actualCostUnavailableTasks: number;
187
+ savedCostUnavailableTasks: number;
188
+ }
189
+ /**
190
+ * Single provider-attempt record inside an escalation chain. The orchestrator
191
+ * (`delegateWithEscalation`) pushes one entry per `provider.run(...)` call.
192
+ */
193
+ export interface AttemptRecord {
194
+ provider: string;
195
+ status: RunStatus;
196
+ turns: number;
197
+ inputTokens: number;
198
+ outputTokens: number;
199
+ costUSD: number | null;
200
+ /** Character count of the canonical orchestrator-side initial brief for
201
+ * this attempt — the exact string
202
+ * `${buildSystemPrompt()}\n\n${buildBudgetHint(...)}\n\n${prompt}`
203
+ * (as assembled before any runner-specific wrapping). Populated by the
204
+ * escalation orchestrator via the `RunOptions.onInitialRequest` callback
205
+ * the runner invokes exactly once per attempt.
206
+ *
207
+ * NOTE: This is a canonical identifier, NOT a wire-level checksum. The
208
+ * provider's SDK may wrap or transform this string before sending (e.g.
209
+ * the Anthropic SDK prepends its `claude_code` preset to the system
210
+ * prompt via `{ type: 'preset', preset: 'claude_code', append: ... }`;
211
+ * the OpenAI SDKs wrap it in a `messages` array). All three runners use
212
+ * the same canonical form so the hash is cross-runner stable: identical
213
+ * briefs produce identical hashes regardless of which runner executed
214
+ * them. Use this to verify "did the orchestrator send the same brief
215
+ * across retries?", not "were the literal bytes on the wire identical?".
216
+ *
217
+ * Defaults to 0 if the runner never invoked the callback. */
218
+ initialPromptLengthChars: number;
219
+ /** sha256 hex of the canonical orchestrator-side initial brief. See the
220
+ * comment on `initialPromptLengthChars` above for the exact hashed
221
+ * string and the wire-level caveat. Defaults to the empty string if the
222
+ * runner never invoked the callback. */
223
+ initialPromptHash: string;
224
+ /** Why this attempt was abandoned, if it was. Empty if status === 'ok'. */
225
+ reason?: string;
226
+ /** Bounded progress trace captured for this attempt, when enabled. */
227
+ progressTrace?: ProgressTraceEntry[];
228
+ }
79
229
  export interface Provider {
80
230
  name: string;
81
231
  config: ProviderConfig;
@@ -88,7 +238,107 @@ export interface RunOptions {
88
238
  cwd?: string;
89
239
  effort?: Effort;
90
240
  sandboxPolicy?: SandboxPolicy;
241
+ /** Optional caller-declared output expectations. When supplied, the
242
+ * supervision layer runs `validateCoverage` after `validateCompletion`'s
243
+ * syntactic check passes, and re-prompts with specific missing-item
244
+ * guidance if coverage is insufficient. Same 3-retry budget as other
245
+ * degeneracy classes. Opt-in: callers who omit this field see zero
246
+ * change in runner behavior. Generic across all workload shapes that
247
+ * produce enumerable deliverables. */
248
+ expectedCoverage?: TaskSpec['expectedCoverage'];
249
+ /** Optional callback invoked by runners and the escalation orchestrator to
250
+ * stream in-flight progress events. See `ProgressEvent` for the full set
251
+ * of variants. Runners receive this via `provider.run(..., { onProgress })`
252
+ * and call it synchronously from their loop; the callback MUST NOT throw
253
+ * and should return quickly. Wired in Task 8 (interface + plumbing);
254
+ * runners emit events in Tasks 9-11. */
255
+ onProgress?: (event: ProgressEvent) => void;
256
+ /** Called exactly once per attempt, when the runner has assembled the
257
+ * canonical orchestrator-side initial brief — the string
258
+ * `${buildSystemPrompt()}\n\n${buildBudgetHint(...)}\n\n${prompt}`,
259
+ * after prevention scaffolding has been produced but before any tool
260
+ * cycles, re-grounding, supervision, or watchdog injections happen.
261
+ * The escalation orchestrator passes a closure here to capture the
262
+ * metadata into the `AttemptRecord` it builds.
263
+ *
264
+ * This is a canonical identifier, NOT a wire-level checksum: each
265
+ * runner computes it from the same canonical string so the hash is
266
+ * cross-runner stable, even though the SDK underneath may wrap the
267
+ * inputs before sending (Claude prepends its `claude_code` preset to
268
+ * the system prompt; OpenAI/Codex wrap inputs in structured message
269
+ * arrays). See `AttemptRecord.initialPromptHash` for the full caveat.
270
+ *
271
+ * If a runner is re-invoked by escalation, the callback fires again
272
+ * for the new attempt because the orchestrator resets its per-attempt
273
+ * closure. Passing nothing keeps existing behaviour (no-op). */
274
+ onInitialRequest?: (meta: {
275
+ lengthChars: number;
276
+ sha256: string;
277
+ }) => void;
278
+ /** Optional hint about the parent session's model for saved-cost estimates.
279
+ * When supplied, `RunResult.usage.savedCostUSD` is computed against this
280
+ * model's profile rates. */
281
+ parentModel?: string;
282
+ /** Opt-in: when true, the runner captures every progress event fired
283
+ * during this task's execution into a bounded, priority-trimmed
284
+ * `progressTrace` on the final RunResult. Useful for post-hoc
285
+ * execution observability on long-running delegated tasks. Zero
286
+ * cost when false (the default). */
287
+ includeProgressTrace?: boolean;
288
+ }
289
+ /**
290
+ * Runtime dependencies for `runTasks`. Kept separate from static `MultiModelConfig`
291
+ * because these are per-session objects (today: the context-block store) the
292
+ * caller owns and passes in explicitly, not config loaded from disk.
293
+ */
294
+ export interface RunTasksRuntime {
295
+ /** Optional store of registered context blocks. When provided, each task's
296
+ * `contextBlockIds` are resolved against this store before dispatch; when
297
+ * omitted, tasks with `contextBlockIds` are passed through unchanged. */
298
+ contextBlockStore?: ContextBlockStore;
91
299
  }
300
+ /**
301
+ * In-flight progress signal emitted by runners and the escalation
302
+ * orchestrator. Consumers (today: the MCP cli bridge) translate these into
303
+ * transport-level notifications so callers can observe a sub-agent's work
304
+ * without polling. One `ProgressEvent` per meaningful state transition.
305
+ *
306
+ * Variants mirror spec Part B.1. Runner emission lives in Tasks 9-11; the
307
+ * escalation `escalation_start` hop is emitted by `delegateWithEscalation`
308
+ * itself in Task 8.
309
+ */
310
+ export type ProgressEvent = {
311
+ kind: 'turn_start';
312
+ turn: number;
313
+ provider: string;
314
+ } | {
315
+ kind: 'tool_call';
316
+ turn: number;
317
+ toolSummary: string;
318
+ } | {
319
+ kind: 'text_emission';
320
+ turn: number;
321
+ chars: number;
322
+ preview: string;
323
+ } | {
324
+ kind: 'turn_complete';
325
+ turn: number;
326
+ cumulativeInputTokens: number;
327
+ cumulativeOutputTokens: number;
328
+ } | {
329
+ kind: 'injection';
330
+ injectionType: 'reground' | 'supervise_empty' | 'supervise_thinking' | 'supervise_fragment' | 'supervise_insufficient_coverage' | 'watchdog_warning' | 'watchdog_force_salvage';
331
+ turn: number;
332
+ contentLengthChars: number;
333
+ } | {
334
+ kind: 'escalation_start';
335
+ previousProvider: string;
336
+ previousReason: string;
337
+ nextProvider: string;
338
+ } | {
339
+ kind: 'done';
340
+ status: RunStatus;
341
+ };
92
342
  export type EligibilityFailureCheck = 'capability' | 'tier' | 'tool_mode' | 'provider_not_found' | 'unsupported_provider_type' | 'missing_required_field' | string;
93
343
  export interface EligibilityFailure {
94
344
  check: EligibilityFailureCheck;
@@ -102,5 +352,14 @@ export interface ProviderEligibility {
102
352
  /** Reasons only present when eligible === false. */
103
353
  reasons: EligibilityFailure[];
104
354
  }
355
+ /**
356
+ * Compute USD cost from token usage and the provider config's optional
357
+ * per-million-token rates. Returns null when either rate is missing — that
358
+ * way the caller can distinguish "we know the cost is zero" (free provider
359
+ * with both rates set to 0) from "we don't know the cost" (rates not
360
+ * configured). Negative or non-finite rates are treated as missing.
361
+ */
362
+ export declare function computeCostUSD(inputTokens: number, outputTokens: number, config: ProviderConfig): number | null;
363
+ export declare function computeSavedCostUSD(actualCostUSD: number | null, inputTokens: number, outputTokens: number, parentModel: string | undefined): number | null;
105
364
  export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, onTimeout: () => T, abort?: AbortController): Promise<T>;
106
365
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,5 +1,47 @@
1
- // === Tier & Capability ===
1
+ import { findModelProfile } from './routing/model-profiles.js';
2
2
  // === Utilities ===
3
+ /**
4
+ * Compute USD cost from token usage and the provider config's optional
5
+ * per-million-token rates. Returns null when either rate is missing — that
6
+ * way the caller can distinguish "we know the cost is zero" (free provider
7
+ * with both rates set to 0) from "we don't know the cost" (rates not
8
+ * configured). Negative or non-finite rates are treated as missing.
9
+ */
10
+ export function computeCostUSD(inputTokens, outputTokens, config) {
11
+ const explicitRates = resolveRatePair(config.inputCostPerMTok, config.outputCostPerMTok);
12
+ if (explicitRates !== null) {
13
+ return (inputTokens * explicitRates.input + outputTokens * explicitRates.output) / 1_000_000;
14
+ }
15
+ const profile = findModelProfile(config.model);
16
+ const profileRates = resolveRatePair(profile.inputCostPerMTok, profile.outputCostPerMTok);
17
+ if (profileRates === null) {
18
+ return null;
19
+ }
20
+ return (inputTokens * profileRates.input + outputTokens * profileRates.output) / 1_000_000;
21
+ }
22
+ export function computeSavedCostUSD(actualCostUSD, inputTokens, outputTokens, parentModel) {
23
+ if (actualCostUSD === null || parentModel === undefined) {
24
+ return null;
25
+ }
26
+ const profile = findModelProfile(parentModel);
27
+ const profileRates = resolveRatePair(profile.inputCostPerMTok, profile.outputCostPerMTok);
28
+ if (profileRates === null) {
29
+ return null;
30
+ }
31
+ const hypotheticalParentCostUSD = (inputTokens * profileRates.input + outputTokens * profileRates.output) / 1_000_000;
32
+ return hypotheticalParentCostUSD - actualCostUSD;
33
+ }
34
+ function resolveRatePair(inputCostPerMTok, outputCostPerMTok) {
35
+ if (inputCostPerMTok !== undefined &&
36
+ outputCostPerMTok !== undefined &&
37
+ Number.isFinite(inputCostPerMTok) &&
38
+ Number.isFinite(outputCostPerMTok) &&
39
+ inputCostPerMTok >= 0 &&
40
+ outputCostPerMTok >= 0) {
41
+ return { input: inputCostPerMTok, output: outputCostPerMTok };
42
+ }
43
+ return null;
44
+ }
3
45
  export function withTimeout(promise, timeoutMs, onTimeout, abort) {
4
46
  let timeoutId;
5
47
  const timeoutPromise = new Promise((resolve) => {
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4BAA4B;AA8I5B,oBAAoB;AAEpB,MAAM,UAAU,WAAW,CACzB,OAAmB,EACnB,SAAiB,EACjB,SAAkB,EAClB,KAAuB;IAEvB,IAAI,SAAoD,CAAC;IAEzD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;QAChD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,KAAK,EAAE,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACvB,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO;SACX,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,SAAS,KAAK,SAAS;YAAE,YAAY,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}