omk-agent-core 0.98.0 → 0.98.2

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 (77) hide show
  1. package/dist/harness/agent-harness.d.ts +29 -14
  2. package/dist/harness/agent-harness.d.ts.map +1 -1
  3. package/dist/harness/agent-harness.js +409 -453
  4. package/dist/harness/agent-harness.js.map +1 -1
  5. package/dist/harness/compaction/branch-summarization.d.ts +5 -1
  6. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
  7. package/dist/harness/compaction/branch-summarization.js +3 -3
  8. package/dist/harness/compaction/branch-summarization.js.map +1 -1
  9. package/dist/harness/compaction/compaction.d.ts +8 -4
  10. package/dist/harness/compaction/compaction.d.ts.map +1 -1
  11. package/dist/harness/compaction/compaction.js +12 -97
  12. package/dist/harness/compaction/compaction.js.map +1 -1
  13. package/dist/harness/compaction/operation.d.ts +13 -0
  14. package/dist/harness/compaction/operation.d.ts.map +1 -0
  15. package/dist/harness/compaction/operation.js +2 -0
  16. package/dist/harness/compaction/operation.js.map +1 -0
  17. package/dist/harness/compaction/summarization-prompts.d.ts +5 -0
  18. package/dist/harness/compaction/summarization-prompts.d.ts.map +1 -0
  19. package/dist/harness/compaction/summarization-prompts.js +88 -0
  20. package/dist/harness/compaction/summarization-prompts.js.map +1 -0
  21. package/dist/harness/errors.d.ts +15 -0
  22. package/dist/harness/errors.d.ts.map +1 -0
  23. package/dist/harness/errors.js +32 -0
  24. package/dist/harness/errors.js.map +1 -0
  25. package/dist/harness/harness-session.d.ts +52 -0
  26. package/dist/harness/harness-session.d.ts.map +1 -0
  27. package/dist/harness/harness-session.js +113 -0
  28. package/dist/harness/harness-session.js.map +1 -0
  29. package/dist/harness/messages.d.ts +3 -1
  30. package/dist/harness/messages.d.ts.map +1 -1
  31. package/dist/harness/messages.js +26 -0
  32. package/dist/harness/messages.js.map +1 -1
  33. package/dist/harness/name-validation.d.ts +2 -0
  34. package/dist/harness/name-validation.d.ts.map +1 -0
  35. package/dist/harness/name-validation.js +11 -0
  36. package/dist/harness/name-validation.js.map +1 -0
  37. package/dist/harness/operation-lifecycle-controller.d.ts +68 -0
  38. package/dist/harness/operation-lifecycle-controller.d.ts.map +1 -0
  39. package/dist/harness/operation-lifecycle-controller.js +199 -0
  40. package/dist/harness/operation-lifecycle-controller.js.map +1 -0
  41. package/dist/harness/operation-lifecycle-reducer.d.ts +19 -0
  42. package/dist/harness/operation-lifecycle-reducer.d.ts.map +1 -0
  43. package/dist/harness/operation-lifecycle-reducer.js +201 -0
  44. package/dist/harness/operation-lifecycle-reducer.js.map +1 -0
  45. package/dist/harness/operation-lifecycle-types.d.ts +130 -0
  46. package/dist/harness/operation-lifecycle-types.d.ts.map +1 -0
  47. package/dist/harness/operation-lifecycle-types.js +34 -0
  48. package/dist/harness/operation-lifecycle-types.js.map +1 -0
  49. package/dist/harness/operation-outcome.d.ts +71 -0
  50. package/dist/harness/operation-outcome.d.ts.map +1 -0
  51. package/dist/harness/operation-outcome.js +131 -0
  52. package/dist/harness/operation-outcome.js.map +1 -0
  53. package/dist/harness/session-write-coordinator.d.ts +76 -0
  54. package/dist/harness/session-write-coordinator.d.ts.map +1 -0
  55. package/dist/harness/session-write-coordinator.js +126 -0
  56. package/dist/harness/session-write-coordinator.js.map +1 -0
  57. package/dist/harness/stream-options.d.ts +31 -0
  58. package/dist/harness/stream-options.d.ts.map +1 -0
  59. package/dist/harness/stream-options.js +66 -0
  60. package/dist/harness/stream-options.js.map +1 -0
  61. package/dist/harness/subscriber-fanout.d.ts +37 -0
  62. package/dist/harness/subscriber-fanout.d.ts.map +1 -0
  63. package/dist/harness/subscriber-fanout.js +73 -0
  64. package/dist/harness/subscriber-fanout.js.map +1 -0
  65. package/dist/harness/summarization-retry.d.ts +29 -0
  66. package/dist/harness/summarization-retry.d.ts.map +1 -0
  67. package/dist/harness/summarization-retry.js +20 -0
  68. package/dist/harness/summarization-retry.js.map +1 -0
  69. package/dist/harness/tree-navigation.d.ts +45 -0
  70. package/dist/harness/tree-navigation.d.ts.map +1 -0
  71. package/dist/harness/tree-navigation.js +59 -0
  72. package/dist/harness/tree-navigation.js.map +1 -0
  73. package/dist/harness/types.d.ts +69 -43
  74. package/dist/harness/types.d.ts.map +1 -1
  75. package/dist/harness/types.js +1 -32
  76. package/dist/harness/types.js.map +1 -1
  77. package/package.json +2 -2
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Subscriber fan-out with a self-wait barrier, extracted from `AgentHarness`.
3
+ *
4
+ * A listener that awaits the end of the very operation whose emission it is
5
+ * blocking forms a cycle. The call that closes that cycle (`waitForIdle()`,
6
+ * `abort()`) is always made during the listener's *synchronous* prologue — an
7
+ * async function body runs synchronously up to its first `await` — so marking
8
+ * just that window identifies callback-originated waits exactly, without
9
+ * falsely rejecting an unrelated concurrent caller that runs later while the
10
+ * listener's promise is merely pending.
11
+ *
12
+ * This module imports no harness or session types so it stays a leaf for the
13
+ * import-cycle ratchet; the harness passes the current operation id in.
14
+ */
15
+ import { AgentHarnessError } from "./errors.js";
16
+ import { normalizeHarnessError } from "./operation-outcome.js";
17
+ export class SubscriberFanout {
18
+ listeners = new Set();
19
+ /** Non-zero only while a subscriber's synchronous prologue is on the stack. */
20
+ syncFrameDepth = 0;
21
+ operationId;
22
+ eventType;
23
+ subscribe(listener) {
24
+ this.listeners.add(listener);
25
+ return () => this.listeners.delete(listener);
26
+ }
27
+ /** Deliver `event` to every subscriber in order; a throwing subscriber fails the emission as `hook`. */
28
+ async emit(event, currentOperationId, signal) {
29
+ for (const listener of this.listeners) {
30
+ const previousOperationId = this.operationId;
31
+ const previousEventType = this.eventType;
32
+ this.operationId = currentOperationId;
33
+ this.eventType = event.type;
34
+ let pending;
35
+ this.syncFrameDepth += 1;
36
+ try {
37
+ pending = listener(event, signal);
38
+ }
39
+ catch (error) {
40
+ this.operationId = previousOperationId;
41
+ this.eventType = previousEventType;
42
+ throw normalizeHarnessError(error, "hook");
43
+ }
44
+ finally {
45
+ this.syncFrameDepth -= 1;
46
+ }
47
+ try {
48
+ await pending;
49
+ }
50
+ catch (error) {
51
+ throw normalizeHarnessError(error, "hook");
52
+ }
53
+ finally {
54
+ this.operationId = previousOperationId;
55
+ this.eventType = previousEventType;
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Fail closed when an awaited listener tries to wait on its own operation.
61
+ * Rejecting immediately turns a permanent deadlock into a classified error.
62
+ *
63
+ * Scope: this catches a wait issued from the listener's synchronous prologue,
64
+ * which covers `await harness.waitForIdle()` / `await harness.abort()`. A wait
65
+ * deferred behind an unrelated `await` inside the listener is not detected.
66
+ */
67
+ assertNotSelfWait(api, currentOperationId) {
68
+ if (this.syncFrameDepth > 0 && currentOperationId !== undefined && currentOperationId === this.operationId) {
69
+ throw new AgentHarnessError("invalid_state", `${api} cannot await the current operation from an awaited ${this.eventType ?? "unknown"} callback`);
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=subscriber-fanout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriber-fanout.js","sourceRoot":"","sources":["../../src/harness/subscriber-fanout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAI/D,MAAM,OAAO,gBAAgB;IACX,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IACnE,+EAA+E;IACvE,cAAc,GAAG,CAAC,CAAC;IACnB,WAAW,CAAqB;IAChC,SAAS,CAAqB;IAEtC,SAAS,CAAC,QAAoC,EAAc;QAC3D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAAA,CAC7C;IAED,wGAAwG;IACxG,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,kBAAsC,EAAE,MAAoB,EAAiB;QACtG,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC;YAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC;YACzC,IAAI,CAAC,WAAW,GAAG,kBAAkB,CAAC;YACtC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YAC5B,IAAI,OAAmC,CAAC;YACxC,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;YACzB,IAAI,CAAC;gBACJ,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC,WAAW,GAAG,mBAAmB,CAAC;gBACvC,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;gBACnC,MAAM,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC5C,CAAC;oBAAS,CAAC;gBACV,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,CAAC;gBACJ,MAAM,OAAO,CAAC;YACf,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC5C,CAAC;oBAAS,CAAC;gBACV,IAAI,CAAC,WAAW,GAAG,mBAAmB,CAAC;gBACvC,IAAI,CAAC,SAAS,GAAG,iBAAiB,CAAC;YACpC,CAAC;QACF,CAAC;IAAA,CACD;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,GAAW,EAAE,kBAAsC,EAAQ;QAC5E,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5G,MAAM,IAAI,iBAAiB,CAC1B,eAAe,EACf,GAAG,GAAG,uDAAuD,IAAI,CAAC,SAAS,IAAI,SAAS,WAAW,CACnG,CAAC;QACH,CAAC;IAAA,CACD;CACD","sourcesContent":["/**\n * Subscriber fan-out with a self-wait barrier, extracted from `AgentHarness`.\n *\n * A listener that awaits the end of the very operation whose emission it is\n * blocking forms a cycle. The call that closes that cycle (`waitForIdle()`,\n * `abort()`) is always made during the listener's *synchronous* prologue — an\n * async function body runs synchronously up to its first `await` — so marking\n * just that window identifies callback-originated waits exactly, without\n * falsely rejecting an unrelated concurrent caller that runs later while the\n * listener's promise is merely pending.\n *\n * This module imports no harness or session types so it stays a leaf for the\n * import-cycle ratchet; the harness passes the current operation id in.\n */\n\nimport { AgentHarnessError } from \"./errors.ts\";\nimport { normalizeHarnessError } from \"./operation-outcome.ts\";\n\nexport type SubscriberListener<TEvent> = (event: TEvent, signal?: AbortSignal) => Promise<void> | void;\n\nexport class SubscriberFanout<TEvent extends { readonly type: string }> {\n\tprivate readonly listeners = new Set<SubscriberListener<TEvent>>();\n\t/** Non-zero only while a subscriber's synchronous prologue is on the stack. */\n\tprivate syncFrameDepth = 0;\n\tprivate operationId: string | undefined;\n\tprivate eventType: string | undefined;\n\n\tsubscribe(listener: SubscriberListener<TEvent>): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\t/** Deliver `event` to every subscriber in order; a throwing subscriber fails the emission as `hook`. */\n\tasync emit(event: TEvent, currentOperationId: string | undefined, signal?: AbortSignal): Promise<void> {\n\t\tfor (const listener of this.listeners) {\n\t\t\tconst previousOperationId = this.operationId;\n\t\t\tconst previousEventType = this.eventType;\n\t\t\tthis.operationId = currentOperationId;\n\t\t\tthis.eventType = event.type;\n\t\t\tlet pending: Promise<unknown> | unknown;\n\t\t\tthis.syncFrameDepth += 1;\n\t\t\ttry {\n\t\t\t\tpending = listener(event, signal);\n\t\t\t} catch (error) {\n\t\t\t\tthis.operationId = previousOperationId;\n\t\t\t\tthis.eventType = previousEventType;\n\t\t\t\tthrow normalizeHarnessError(error, \"hook\");\n\t\t\t} finally {\n\t\t\t\tthis.syncFrameDepth -= 1;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait pending;\n\t\t\t} catch (error) {\n\t\t\t\tthrow normalizeHarnessError(error, \"hook\");\n\t\t\t} finally {\n\t\t\t\tthis.operationId = previousOperationId;\n\t\t\t\tthis.eventType = previousEventType;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fail closed when an awaited listener tries to wait on its own operation.\n\t * Rejecting immediately turns a permanent deadlock into a classified error.\n\t *\n\t * Scope: this catches a wait issued from the listener's synchronous prologue,\n\t * which covers `await harness.waitForIdle()` / `await harness.abort()`. A wait\n\t * deferred behind an unrelated `await` inside the listener is not detected.\n\t */\n\tassertNotSelfWait(api: string, currentOperationId: string | undefined): void {\n\t\tif (this.syncFrameDepth > 0 && currentOperationId !== undefined && currentOperationId === this.operationId) {\n\t\t\tthrow new AgentHarnessError(\n\t\t\t\t\"invalid_state\",\n\t\t\t\t`${api} cannot await the current operation from an awaited ${this.eventType ?? \"unknown\"} callback`,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import type { RetryCallbacks, RetryPolicy } from "omk-ai";
2
+ export type SummarizationOperation = "compaction" | "branch_summary";
3
+ export interface RetryScheduledEvent {
4
+ readonly type: "retry_scheduled";
5
+ readonly operation: SummarizationOperation;
6
+ readonly attempt: number;
7
+ readonly maxAttempts: number;
8
+ readonly delayMs: number;
9
+ readonly errorMessage: string;
10
+ }
11
+ export interface RetryAttemptStartEvent {
12
+ readonly type: "retry_attempt_start";
13
+ readonly operation: SummarizationOperation;
14
+ readonly attempt: number;
15
+ }
16
+ export interface RetryFinishedEvent {
17
+ readonly type: "retry_finished";
18
+ readonly operation: SummarizationOperation;
19
+ readonly success: boolean;
20
+ readonly attempt: number;
21
+ readonly finalError?: string;
22
+ }
23
+ export type SummarizationRetryEvent = RetryScheduledEvent | RetryAttemptStartEvent | RetryFinishedEvent;
24
+ /** Build retry policy/callbacks without coupling the leaf module to harness event types. */
25
+ export declare function createSummarizationRetry(operation: SummarizationOperation, policy: RetryPolicy | undefined, emit: (event: SummarizationRetryEvent) => Promise<void> | void): {
26
+ readonly retry: RetryPolicy | undefined;
27
+ readonly callbacks: RetryCallbacks;
28
+ };
29
+ //# sourceMappingURL=summarization-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarization-retry.d.ts","sourceRoot":"","sources":["../../src/harness/summarization-retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1D,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAErE,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;AAExG,4FAA4F;AAC5F,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,sBAAsB,EACjC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,IAAI,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAC5D;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;CAAE,CAiBjF","sourcesContent":["import type { RetryCallbacks, RetryPolicy } from \"omk-ai\";\n\nexport type SummarizationOperation = \"compaction\" | \"branch_summary\";\n\nexport interface RetryScheduledEvent {\n\treadonly type: \"retry_scheduled\";\n\treadonly operation: SummarizationOperation;\n\treadonly attempt: number;\n\treadonly maxAttempts: number;\n\treadonly delayMs: number;\n\treadonly errorMessage: string;\n}\n\nexport interface RetryAttemptStartEvent {\n\treadonly type: \"retry_attempt_start\";\n\treadonly operation: SummarizationOperation;\n\treadonly attempt: number;\n}\n\nexport interface RetryFinishedEvent {\n\treadonly type: \"retry_finished\";\n\treadonly operation: SummarizationOperation;\n\treadonly success: boolean;\n\treadonly attempt: number;\n\treadonly finalError?: string;\n}\n\nexport type SummarizationRetryEvent = RetryScheduledEvent | RetryAttemptStartEvent | RetryFinishedEvent;\n\n/** Build retry policy/callbacks without coupling the leaf module to harness event types. */\nexport function createSummarizationRetry(\n\toperation: SummarizationOperation,\n\tpolicy: RetryPolicy | undefined,\n\temit: (event: SummarizationRetryEvent) => Promise<void> | void,\n): { readonly retry: RetryPolicy | undefined; readonly callbacks: RetryCallbacks } {\n\tlet scheduledAttempt = 0;\n\treturn {\n\t\tretry: policy,\n\t\tcallbacks: {\n\t\t\tonRetryScheduled: async (attempt, maxAttempts, delayMs, errorMessage) => {\n\t\t\t\tscheduledAttempt = attempt;\n\t\t\t\tawait emit({ type: \"retry_scheduled\", operation, attempt, maxAttempts, delayMs, errorMessage });\n\t\t\t},\n\t\t\tonRetryAttemptStart: async () => {\n\t\t\t\tawait emit({ type: \"retry_attempt_start\", operation, attempt: scheduledAttempt });\n\t\t\t},\n\t\t\tonRetryFinished: async (success, attempt, finalError) => {\n\t\t\t\tawait emit({ type: \"retry_finished\", operation, success, attempt, finalError });\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /** Build retry policy/callbacks without coupling the leaf module to harness event types. */
2
+ export function createSummarizationRetry(operation, policy, emit) {
3
+ let scheduledAttempt = 0;
4
+ return {
5
+ retry: policy,
6
+ callbacks: {
7
+ onRetryScheduled: async (attempt, maxAttempts, delayMs, errorMessage) => {
8
+ scheduledAttempt = attempt;
9
+ await emit({ type: "retry_scheduled", operation, attempt, maxAttempts, delayMs, errorMessage });
10
+ },
11
+ onRetryAttemptStart: async () => {
12
+ await emit({ type: "retry_attempt_start", operation, attempt: scheduledAttempt });
13
+ },
14
+ onRetryFinished: async (success, attempt, finalError) => {
15
+ await emit({ type: "retry_finished", operation, success, attempt, finalError });
16
+ },
17
+ },
18
+ };
19
+ }
20
+ //# sourceMappingURL=summarization-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarization-retry.js","sourceRoot":"","sources":["../../src/harness/summarization-retry.ts"],"names":[],"mappings":"AA6BA,4FAA4F;AAC5F,MAAM,UAAU,wBAAwB,CACvC,SAAiC,EACjC,MAA+B,EAC/B,IAA8D,EACoB;IAClF,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,OAAO;QACN,KAAK,EAAE,MAAM;QACb,SAAS,EAAE;YACV,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC;gBACxE,gBAAgB,GAAG,OAAO,CAAC;gBAC3B,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;YAAA,CAChG;YACD,mBAAmB,EAAE,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAAA,CAClF;YACD,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;gBACxD,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YAAA,CAChF;SACD;KACD,CAAC;AAAA,CACF","sourcesContent":["import type { RetryCallbacks, RetryPolicy } from \"omk-ai\";\n\nexport type SummarizationOperation = \"compaction\" | \"branch_summary\";\n\nexport interface RetryScheduledEvent {\n\treadonly type: \"retry_scheduled\";\n\treadonly operation: SummarizationOperation;\n\treadonly attempt: number;\n\treadonly maxAttempts: number;\n\treadonly delayMs: number;\n\treadonly errorMessage: string;\n}\n\nexport interface RetryAttemptStartEvent {\n\treadonly type: \"retry_attempt_start\";\n\treadonly operation: SummarizationOperation;\n\treadonly attempt: number;\n}\n\nexport interface RetryFinishedEvent {\n\treadonly type: \"retry_finished\";\n\treadonly operation: SummarizationOperation;\n\treadonly success: boolean;\n\treadonly attempt: number;\n\treadonly finalError?: string;\n}\n\nexport type SummarizationRetryEvent = RetryScheduledEvent | RetryAttemptStartEvent | RetryFinishedEvent;\n\n/** Build retry policy/callbacks without coupling the leaf module to harness event types. */\nexport function createSummarizationRetry(\n\toperation: SummarizationOperation,\n\tpolicy: RetryPolicy | undefined,\n\temit: (event: SummarizationRetryEvent) => Promise<void> | void,\n): { readonly retry: RetryPolicy | undefined; readonly callbacks: RetryCallbacks } {\n\tlet scheduledAttempt = 0;\n\treturn {\n\t\tretry: policy,\n\t\tcallbacks: {\n\t\t\tonRetryScheduled: async (attempt, maxAttempts, delayMs, errorMessage) => {\n\t\t\t\tscheduledAttempt = attempt;\n\t\t\t\tawait emit({ type: \"retry_scheduled\", operation, attempt, maxAttempts, delayMs, errorMessage });\n\t\t\t},\n\t\t\tonRetryAttemptStart: async () => {\n\t\t\t\tawait emit({ type: \"retry_attempt_start\", operation, attempt: scheduledAttempt });\n\t\t\t},\n\t\t\tonRetryFinished: async (success, attempt, finalError) => {\n\t\t\t\tawait emit({ type: \"retry_finished\", operation, success, attempt, finalError });\n\t\t\t},\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tree-navigation helpers extracted from `AgentHarness.navigateTree`.
3
+ *
4
+ * These cover the two self-contained steps of a navigation — deciding where to
5
+ * land, and producing a branch summary — so the harness method is left with
6
+ * lifecycle staging, hook dispatch, and the session commit.
7
+ */
8
+ import type { Model, RetryPolicy } from "omk-ai";
9
+ import { type SummarizationRetryEvent } from "./summarization-retry.ts";
10
+ import type { SessionTreeEntry } from "./types.ts";
11
+ export interface NavigationTarget {
12
+ /** Leaf the session should move to. */
13
+ readonly newLeafId: string | null;
14
+ /** Original text of a user-authored target, handed back for re-editing. */
15
+ readonly editorText?: string;
16
+ }
17
+ /**
18
+ * Where a navigation lands. Targeting a user-authored entry rewinds to its
19
+ * parent and returns that entry's text, so the caller can edit and resend it;
20
+ * any other entry is entered directly.
21
+ */
22
+ export declare function resolveNavigationTarget(targetEntry: SessionTreeEntry, targetId: string): NavigationTarget;
23
+ export type BranchSummaryOutcome = {
24
+ readonly cancelled: true;
25
+ } | {
26
+ readonly cancelled: false;
27
+ readonly summary: string;
28
+ readonly details: unknown;
29
+ };
30
+ /**
31
+ * Summarize the entries being navigated away from. An aborted summary is a
32
+ * cancellation, not a failure; every other summarization error is classified
33
+ * as `branch_summary`.
34
+ */
35
+ export declare function runBranchSummary(input: {
36
+ readonly entries: SessionTreeEntry[];
37
+ readonly model: Model<any>;
38
+ readonly apiKey: string;
39
+ readonly headers?: Record<string, string>;
40
+ readonly customInstructions?: string;
41
+ readonly replaceInstructions?: boolean;
42
+ readonly summarizationRetry: RetryPolicy | undefined;
43
+ readonly emit: (event: SummarizationRetryEvent) => Promise<void> | void;
44
+ }): Promise<BranchSummaryOutcome>;
45
+ //# sourceMappingURL=tree-navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.d.ts","sourceRoot":"","sources":["../../src/harness/tree-navigation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAgB,KAAK,EAAE,WAAW,EAAe,MAAM,QAAQ,CAAC;AAE5E,OAAO,EAA4B,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAWnD,MAAM,WAAW,gBAAgB;IAChC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAQzG;AAED,MAAM,MAAM,oBAAoB,GAC7B;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtF;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC7C,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,kBAAkB,EAAE,WAAW,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAmBhC","sourcesContent":["/**\n * Tree-navigation helpers extracted from `AgentHarness.navigateTree`.\n *\n * These cover the two self-contained steps of a navigation — deciding where to\n * land, and producing a branch summary — so the harness method is left with\n * lifecycle staging, hook dispatch, and the session commit.\n */\n\nimport type { ImageContent, Model, RetryPolicy, TextContent } from \"omk-ai\";\nimport { generateBranchSummary } from \"./compaction/branch-summarization.ts\";\nimport { createSummarizationRetry, type SummarizationRetryEvent } from \"./summarization-retry.ts\";\nimport type { SessionTreeEntry } from \"./types.ts\";\nimport { AgentHarnessError } from \"./types.ts\";\n\nfunction flattenText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") return content;\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\nexport interface NavigationTarget {\n\t/** Leaf the session should move to. */\n\treadonly newLeafId: string | null;\n\t/** Original text of a user-authored target, handed back for re-editing. */\n\treadonly editorText?: string;\n}\n\n/**\n * Where a navigation lands. Targeting a user-authored entry rewinds to its\n * parent and returns that entry's text, so the caller can edit and resend it;\n * any other entry is entered directly.\n */\nexport function resolveNavigationTarget(targetEntry: SessionTreeEntry, targetId: string): NavigationTarget {\n\tif (targetEntry.type === \"message\" && targetEntry.message.role === \"user\") {\n\t\treturn { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.message.content) };\n\t}\n\tif (targetEntry.type === \"custom_message\") {\n\t\treturn { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.content) };\n\t}\n\treturn { newLeafId: targetId };\n}\n\nexport type BranchSummaryOutcome =\n\t| { readonly cancelled: true }\n\t| { readonly cancelled: false; readonly summary: string; readonly details: unknown };\n\n/**\n * Summarize the entries being navigated away from. An aborted summary is a\n * cancellation, not a failure; every other summarization error is classified\n * as `branch_summary`.\n */\nexport async function runBranchSummary(input: {\n\treadonly entries: SessionTreeEntry[];\n\treadonly model: Model<any>;\n\treadonly apiKey: string;\n\treadonly headers?: Record<string, string>;\n\treadonly customInstructions?: string;\n\treadonly replaceInstructions?: boolean;\n\treadonly summarizationRetry: RetryPolicy | undefined;\n\treadonly emit: (event: SummarizationRetryEvent) => Promise<void> | void;\n}): Promise<BranchSummaryOutcome> {\n\tconst result = await generateBranchSummary(input.entries, {\n\t\tmodel: input.model,\n\t\tapiKey: input.apiKey,\n\t\theaders: input.headers,\n\t\tsignal: new AbortController().signal,\n\t\tcustomInstructions: input.customInstructions,\n\t\treplaceInstructions: input.replaceInstructions,\n\t\t...createSummarizationRetry(\"branch_summary\", input.summarizationRetry, input.emit),\n\t});\n\tif (!result.ok) {\n\t\tif (result.error.code === \"aborted\") return { cancelled: true };\n\t\tthrow new AgentHarnessError(\"branch_summary\", result.error.message, result.error);\n\t}\n\treturn {\n\t\tcancelled: false,\n\t\tsummary: result.value.summary,\n\t\tdetails: { readFiles: result.value.readFiles, modifiedFiles: result.value.modifiedFiles },\n\t};\n}\n"]}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Tree-navigation helpers extracted from `AgentHarness.navigateTree`.
3
+ *
4
+ * These cover the two self-contained steps of a navigation — deciding where to
5
+ * land, and producing a branch summary — so the harness method is left with
6
+ * lifecycle staging, hook dispatch, and the session commit.
7
+ */
8
+ import { generateBranchSummary } from "./compaction/branch-summarization.js";
9
+ import { createSummarizationRetry } from "./summarization-retry.js";
10
+ import { AgentHarnessError } from "./types.js";
11
+ function flattenText(content) {
12
+ if (typeof content === "string")
13
+ return content;
14
+ return content
15
+ .filter((part) => part.type === "text")
16
+ .map((part) => part.text)
17
+ .join("");
18
+ }
19
+ /**
20
+ * Where a navigation lands. Targeting a user-authored entry rewinds to its
21
+ * parent and returns that entry's text, so the caller can edit and resend it;
22
+ * any other entry is entered directly.
23
+ */
24
+ export function resolveNavigationTarget(targetEntry, targetId) {
25
+ if (targetEntry.type === "message" && targetEntry.message.role === "user") {
26
+ return { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.message.content) };
27
+ }
28
+ if (targetEntry.type === "custom_message") {
29
+ return { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.content) };
30
+ }
31
+ return { newLeafId: targetId };
32
+ }
33
+ /**
34
+ * Summarize the entries being navigated away from. An aborted summary is a
35
+ * cancellation, not a failure; every other summarization error is classified
36
+ * as `branch_summary`.
37
+ */
38
+ export async function runBranchSummary(input) {
39
+ const result = await generateBranchSummary(input.entries, {
40
+ model: input.model,
41
+ apiKey: input.apiKey,
42
+ headers: input.headers,
43
+ signal: new AbortController().signal,
44
+ customInstructions: input.customInstructions,
45
+ replaceInstructions: input.replaceInstructions,
46
+ ...createSummarizationRetry("branch_summary", input.summarizationRetry, input.emit),
47
+ });
48
+ if (!result.ok) {
49
+ if (result.error.code === "aborted")
50
+ return { cancelled: true };
51
+ throw new AgentHarnessError("branch_summary", result.error.message, result.error);
52
+ }
53
+ return {
54
+ cancelled: false,
55
+ summary: result.value.summary,
56
+ details: { readFiles: result.value.readFiles, modifiedFiles: result.value.modifiedFiles },
57
+ };
58
+ }
59
+ //# sourceMappingURL=tree-navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-navigation.js","sourceRoot":"","sources":["../../src/harness/tree-navigation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAgC,MAAM,0BAA0B,CAAC;AAElG,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,SAAS,WAAW,CAAC,OAAgD,EAAU;IAC9E,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,OAAO;SACZ,MAAM,CAAC,CAAC,IAAI,EAAuB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;SAC3D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,EAAE,CAAC,CAAC;AAAA,CACX;AASD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAA6B,EAAE,QAAgB,EAAoB;IAC1G,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3E,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAClG,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC3C,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1F,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA,CAC/B;AAMD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAStC,EAAiC;IACjC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,OAAO,EAAE;QACzD,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;QACpC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,GAAG,wBAAwB,CAAC,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,IAAI,CAAC;KACnF,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QAChB,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAChE,MAAM,IAAI,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACnF,CAAC;IACD,OAAO;QACN,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;QAC7B,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;KACzF,CAAC;AAAA,CACF","sourcesContent":["/**\n * Tree-navigation helpers extracted from `AgentHarness.navigateTree`.\n *\n * These cover the two self-contained steps of a navigation — deciding where to\n * land, and producing a branch summary — so the harness method is left with\n * lifecycle staging, hook dispatch, and the session commit.\n */\n\nimport type { ImageContent, Model, RetryPolicy, TextContent } from \"omk-ai\";\nimport { generateBranchSummary } from \"./compaction/branch-summarization.ts\";\nimport { createSummarizationRetry, type SummarizationRetryEvent } from \"./summarization-retry.ts\";\nimport type { SessionTreeEntry } from \"./types.ts\";\nimport { AgentHarnessError } from \"./types.ts\";\n\nfunction flattenText(content: string | (TextContent | ImageContent)[]): string {\n\tif (typeof content === \"string\") return content;\n\treturn content\n\t\t.filter((part): part is TextContent => part.type === \"text\")\n\t\t.map((part) => part.text)\n\t\t.join(\"\");\n}\n\nexport interface NavigationTarget {\n\t/** Leaf the session should move to. */\n\treadonly newLeafId: string | null;\n\t/** Original text of a user-authored target, handed back for re-editing. */\n\treadonly editorText?: string;\n}\n\n/**\n * Where a navigation lands. Targeting a user-authored entry rewinds to its\n * parent and returns that entry's text, so the caller can edit and resend it;\n * any other entry is entered directly.\n */\nexport function resolveNavigationTarget(targetEntry: SessionTreeEntry, targetId: string): NavigationTarget {\n\tif (targetEntry.type === \"message\" && targetEntry.message.role === \"user\") {\n\t\treturn { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.message.content) };\n\t}\n\tif (targetEntry.type === \"custom_message\") {\n\t\treturn { newLeafId: targetEntry.parentId, editorText: flattenText(targetEntry.content) };\n\t}\n\treturn { newLeafId: targetId };\n}\n\nexport type BranchSummaryOutcome =\n\t| { readonly cancelled: true }\n\t| { readonly cancelled: false; readonly summary: string; readonly details: unknown };\n\n/**\n * Summarize the entries being navigated away from. An aborted summary is a\n * cancellation, not a failure; every other summarization error is classified\n * as `branch_summary`.\n */\nexport async function runBranchSummary(input: {\n\treadonly entries: SessionTreeEntry[];\n\treadonly model: Model<any>;\n\treadonly apiKey: string;\n\treadonly headers?: Record<string, string>;\n\treadonly customInstructions?: string;\n\treadonly replaceInstructions?: boolean;\n\treadonly summarizationRetry: RetryPolicy | undefined;\n\treadonly emit: (event: SummarizationRetryEvent) => Promise<void> | void;\n}): Promise<BranchSummaryOutcome> {\n\tconst result = await generateBranchSummary(input.entries, {\n\t\tmodel: input.model,\n\t\tapiKey: input.apiKey,\n\t\theaders: input.headers,\n\t\tsignal: new AbortController().signal,\n\t\tcustomInstructions: input.customInstructions,\n\t\treplaceInstructions: input.replaceInstructions,\n\t\t...createSummarizationRetry(\"branch_summary\", input.summarizationRetry, input.emit),\n\t});\n\tif (!result.ok) {\n\t\tif (result.error.code === \"aborted\") return { cancelled: true };\n\t\tthrow new AgentHarnessError(\"branch_summary\", result.error.message, result.error);\n\t}\n\treturn {\n\t\tcancelled: false,\n\t\tsummary: result.value.summary,\n\t\tdetails: { readFiles: result.value.readFiles, modifiedFiles: result.value.modifiedFiles },\n\t};\n}\n"]}
@@ -1,6 +1,12 @@
1
- import type { ImageContent, Model, SimpleStreamOptions, TextContent, Transport } from "omk-ai";
2
- import type { AgentEvent, AgentMessage, AgentTool, QueueMode, ThinkingLevel } from "../index.ts";
1
+ import type { ImageContent, Model, TextContent } from "omk-ai";
2
+ import type { AgentEvent, AgentMessage, AgentTool, QueueMode, ThinkingLevel } from "../types.ts";
3
+ export { AgentHarnessError, type AgentHarnessErrorCode, SessionError, type SessionErrorCode, toError, } from "./errors.ts";
4
+ import type { HarnessAttemptRef, HarnessAttemptSummary, HarnessOperationOutcome, HarnessOperationRef } from "./operation-lifecycle-types.ts";
3
5
  import type { Session } from "./session/session.ts";
6
+ import type { AgentHarnessStreamOptions, AgentHarnessStreamOptionsPatch } from "./stream-options.ts";
7
+ import type { SummarizationRetryEvent } from "./summarization-retry.ts";
8
+ export type { AgentHarnessStreamOptions, AgentHarnessStreamOptionsPatch } from "./stream-options.ts";
9
+ export type { RetryAttemptStartEvent, RetryFinishedEvent, RetryScheduledEvent, SummarizationOperation, SummarizationRetryEvent, } from "./summarization-retry.ts";
4
10
  /** Result of a fallible operation. Expected failures are returned as `ok: false` instead of thrown. */
5
11
  export type Result<TValue, TError> = {
6
12
  ok: true;
@@ -17,8 +23,6 @@ export declare function err<TValue, TError>(error: TError): Result<TValue, TErro
17
23
  export declare function getOrThrow<TValue, TError>(result: Result<TValue, TError>): TValue;
18
24
  /** Return the success value or `undefined`. Only object values are allowed to avoid truthiness bugs with primitives. */
19
25
  export declare function getOrUndefined<TValue extends object, TError>(result: Result<TValue, TError>): TValue | undefined;
20
- /** Normalize unknown thrown values into Error instances before using them as typed error causes. */
21
- export declare function toError(error: unknown): Error;
22
26
  /**
23
27
  * Skill loaded from a `SKILL.md` file or provided by an application.
24
28
  *
@@ -53,30 +57,6 @@ export interface AgentHarnessResources<TSkill extends Skill = Skill, TPromptTemp
53
57
  /** Skills available to the model and explicit skill invocation. */
54
58
  skills?: TSkill[];
55
59
  }
56
- /** Curated provider request options owned by the harness and snapshotted per turn. */
57
- export interface AgentHarnessStreamOptions {
58
- /** Preferred transport forwarded to the stream function. */
59
- transport?: Transport;
60
- /** Provider request timeout in milliseconds. */
61
- timeoutMs?: number;
62
- /** Maximum provider retry attempts. */
63
- maxRetries?: number;
64
- /** Optional cap for provider-requested retry delays. */
65
- maxRetryDelayMs?: number;
66
- /** Additional request headers merged with auth and lifecycle headers. */
67
- headers?: Record<string, string>;
68
- /** Provider metadata forwarded with requests. */
69
- metadata?: SimpleStreamOptions["metadata"];
70
- /** Provider cache retention hint. */
71
- cacheRetention?: SimpleStreamOptions["cacheRetention"];
72
- }
73
- /** Per-request stream option patch returned by provider hooks. */
74
- export interface AgentHarnessStreamOptionsPatch extends Omit<Partial<AgentHarnessStreamOptions>, "headers" | "metadata"> {
75
- /** Header patch. `undefined` values delete keys; explicit `headers: undefined` clears all headers. */
76
- headers?: Record<string, string | undefined>;
77
- /** Metadata patch. `undefined` values delete keys; explicit `metadata: undefined` clears all metadata. */
78
- metadata?: Record<string, unknown | undefined>;
79
- }
80
60
  /** Kind of filesystem object as addressed by a {@link FileSystem}. Symlinks are not followed automatically. */
81
61
  export type FileKind = "file" | "directory" | "symlink";
82
62
  /** Stable, backend-independent file error codes returned by {@link FileSystem} file operations. */
@@ -113,19 +93,6 @@ export declare class BranchSummaryError extends Error {
113
93
  code: BranchSummaryErrorCode;
114
94
  constructor(code: BranchSummaryErrorCode, message: string, cause?: Error);
115
95
  }
116
- export type SessionErrorCode = "not_found" | "invalid_session" | "invalid_entry" | "invalid_fork_target" | "storage" | "unknown";
117
- /** Error thrown by session storage, repositories, and session tree operations. */
118
- export declare class SessionError extends Error {
119
- /** Session subsystem error code. */
120
- code: SessionErrorCode;
121
- constructor(code: SessionErrorCode, message: string, cause?: Error);
122
- }
123
- export type AgentHarnessErrorCode = "busy" | "invalid_state" | "invalid_argument" | "session" | "hook" | "auth" | "compaction" | "branch_summary" | "unknown";
124
- /** Public AgentHarness failure with a stable top-level classification. */
125
- export declare class AgentHarnessError extends Error {
126
- code: AgentHarnessErrorCode;
127
- constructor(code: AgentHarnessErrorCode, message: string, cause?: Error);
128
- }
129
96
  /** Metadata for one filesystem object in a {@link FileSystem}. */
130
97
  export interface FileInfo {
131
98
  /** Basename of {@link path}. */
@@ -309,6 +276,12 @@ export interface JsonlSessionMetadata extends SessionMetadata {
309
276
  path: string;
310
277
  parentSessionPath?: string;
311
278
  }
279
+ /**
280
+ * Durable session storage adapter.
281
+ *
282
+ * Mutation methods are non-reentrant: while a storage mutation is unsettled, its implementation must not call or await
283
+ * mutators on the owning `Session`, `HarnessSession`, or `AgentHarness`.
284
+ */
312
285
  export interface SessionStorage<TMetadata extends SessionMetadata = SessionMetadata> {
313
286
  getMetadata(): Promise<TMetadata>;
314
287
  getLeafId(): Promise<string | null>;
@@ -349,8 +322,37 @@ export interface JsonlSessionListOptions {
349
322
  }
350
323
  export interface JsonlSessionRepoApi extends SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions> {
351
324
  }
325
+ /**
326
+ * @deprecated Internal facade-gate vocabulary. Operation lifecycle state is
327
+ * owned by `OperationLifecycleController`; this union remains only as the
328
+ * session facade's write-gate mapping and will be removed at 1.0.
329
+ */
352
330
  export type AgentHarnessPhase = "idle" | "turn" | "compaction" | "branch_summary" | "retry";
353
331
  export type PendingSessionWrite = SessionTreeEntry extends infer TEntry ? TEntry extends SessionTreeEntry ? Omit<TEntry, "id" | "parentId" | "timestamp"> : never : never;
332
+ export interface HarnessCustomMessageInput<T = unknown> {
333
+ readonly customType: string;
334
+ readonly content: string | readonly (TextContent | ImageContent)[];
335
+ readonly display: boolean;
336
+ readonly details?: T;
337
+ }
338
+ /** Public storage-free view over persisted session state and ordered extension writes. */
339
+ export interface HarnessSession {
340
+ getMetadata(): Promise<Readonly<SessionMetadata>>;
341
+ getLeafId(): Promise<string | null>;
342
+ getEntry(id: string): Promise<Readonly<SessionTreeEntry> | undefined>;
343
+ getEntries(): Promise<readonly Readonly<SessionTreeEntry>[]>;
344
+ getBranch(fromId?: string): Promise<readonly Readonly<SessionTreeEntry>[]>;
345
+ buildContext(): Promise<Readonly<SessionContext>>;
346
+ getLabel(id: string): Promise<string | undefined>;
347
+ getSessionName(): Promise<string | undefined>;
348
+ getPendingWrites(): readonly PendingSessionWrite[];
349
+ appendMessage(message: AgentMessage): Promise<void>;
350
+ appendCustomEntry(customType: string, data?: unknown): Promise<void>;
351
+ appendCustomMessage<T = unknown>(input: HarnessCustomMessageInput<T>): Promise<void>;
352
+ appendLabel(targetId: string, label: string | undefined): Promise<void>;
353
+ appendSessionName(name: string): Promise<void>;
354
+ setLeafId(targetId: string | null): Promise<void>;
355
+ }
354
356
  export interface QueueUpdateEvent {
355
357
  type: "queue_update";
356
358
  steer: AgentMessage[];
@@ -369,6 +371,23 @@ export interface AbortEvent {
369
371
  export interface SettledEvent {
370
372
  type: "settled";
371
373
  nextTurnCount: number;
374
+ /** Identity of the public operation that just settled exactly once. */
375
+ operationId: string;
376
+ outcome: HarnessOperationOutcome;
377
+ attemptCount: number;
378
+ }
379
+ export interface OperationStartedEvent {
380
+ type: "operation_started";
381
+ operation: HarnessOperationRef;
382
+ }
383
+ export interface AttemptStartedEvent {
384
+ type: "attempt_started";
385
+ attempt: HarnessAttemptRef;
386
+ }
387
+ /** Emitted once per low-level agent attempt; carries a bounded summary, never a transcript. */
388
+ export interface AttemptFinishedEvent {
389
+ type: "attempt_finished";
390
+ summary: HarnessAttemptSummary;
372
391
  }
373
392
  export interface BeforeAgentStartEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> {
374
393
  type: "before_agent_start";
@@ -460,7 +479,7 @@ export interface ResourcesUpdateEvent<TSkill extends Skill = Skill, TPromptTempl
460
479
  resources: AgentHarnessResources<TSkill, TPromptTemplate>;
461
480
  previousResources: AgentHarnessResources<TSkill, TPromptTemplate>;
462
481
  }
463
- export type AgentHarnessOwnEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = QueueUpdateEvent | SavePointEvent | AbortEvent | SettledEvent | BeforeAgentStartEvent<TSkill, TPromptTemplate> | ContextEvent | BeforeProviderRequestEvent | BeforeProviderPayloadEvent | AfterProviderResponseEvent | ToolCallEvent | ToolResultEvent | SessionBeforeCompactEvent | SessionCompactEvent | SessionBeforeTreeEvent | SessionTreeEvent | ModelUpdateEvent | ThinkingLevelUpdateEvent | ResourcesUpdateEvent<TSkill, TPromptTemplate> | ToolsUpdateEvent;
482
+ export type AgentHarnessOwnEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = QueueUpdateEvent | SavePointEvent | AbortEvent | SettledEvent | OperationStartedEvent | AttemptStartedEvent | AttemptFinishedEvent | BeforeAgentStartEvent<TSkill, TPromptTemplate> | ContextEvent | BeforeProviderRequestEvent | BeforeProviderPayloadEvent | AfterProviderResponseEvent | ToolCallEvent | ToolResultEvent | SessionBeforeCompactEvent | SessionCompactEvent | SessionBeforeTreeEvent | SessionTreeEvent | SummarizationRetryEvent | ModelUpdateEvent | ThinkingLevelUpdateEvent | ResourcesUpdateEvent<TSkill, TPromptTemplate> | ToolsUpdateEvent;
464
483
  export type AgentHarnessEvent<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate> = AgentEvent | AgentHarnessOwnEvent<TSkill, TPromptTemplate>;
465
484
  export interface BeforeAgentStartResult {
466
485
  messages?: AgentMessage[];
@@ -511,6 +530,9 @@ export type AgentHarnessEventResultMap = {
511
530
  session_compact: undefined;
512
531
  session_before_tree: SessionBeforeTreeResult | undefined;
513
532
  session_tree: undefined;
533
+ retry_scheduled: undefined;
534
+ retry_attempt_start: undefined;
535
+ retry_finished: undefined;
514
536
  model_update: undefined;
515
537
  thinking_level_update: undefined;
516
538
  resources_update: undefined;
@@ -519,6 +541,9 @@ export type AgentHarnessEventResultMap = {
519
541
  save_point: undefined;
520
542
  abort: undefined;
521
543
  settled: undefined;
544
+ operation_started: undefined;
545
+ attempt_started: undefined;
546
+ attempt_finished: undefined;
522
547
  };
523
548
  export interface AgentHarnessPromptOptions {
524
549
  images?: ImageContent[];
@@ -606,11 +631,12 @@ export interface AgentHarnessOptions<TSkill extends Skill = Skill, TPromptTempla
606
631
  } | undefined>;
607
632
  /** Curated stream/provider request options. Snapshotted at turn start. */
608
633
  streamOptions?: AgentHarnessStreamOptions;
634
+ /** Automatic compaction thresholds. Defaults to {@link DEFAULT_COMPACTION_SETTINGS}. */
635
+ compaction?: CompactionSettings;
609
636
  model: Model<any>;
610
637
  thinkingLevel?: ThinkingLevel;
611
638
  activeToolNames?: string[];
612
639
  steeringMode?: QueueMode;
613
640
  followUpMode?: QueueMode;
614
641
  }
615
- export type { AgentHarness } from "./agent-harness.ts";
616
642
  //# sourceMappingURL=types.d.ts.map