omk-agent-core 0.98.1 → 0.98.3

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 (91) hide show
  1. package/CHANGELOG.md +644 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +3 -5
  4. package/dist/agent.js.map +1 -1
  5. package/dist/effects/effect-journal.d.ts +43 -0
  6. package/dist/effects/effect-journal.d.ts.map +1 -0
  7. package/dist/effects/effect-journal.js +186 -0
  8. package/dist/effects/effect-journal.js.map +1 -0
  9. package/dist/effects/effect-recovery.d.ts +70 -0
  10. package/dist/effects/effect-recovery.d.ts.map +1 -0
  11. package/dist/effects/effect-recovery.js +120 -0
  12. package/dist/effects/effect-recovery.js.map +1 -0
  13. package/dist/effects/effect-transitions.d.ts +34 -0
  14. package/dist/effects/effect-transitions.d.ts.map +1 -0
  15. package/dist/effects/effect-transitions.js +148 -0
  16. package/dist/effects/effect-transitions.js.map +1 -0
  17. package/dist/effects/effect-types.d.ts +135 -0
  18. package/dist/effects/effect-types.d.ts.map +1 -0
  19. package/dist/effects/effect-types.js +32 -0
  20. package/dist/effects/effect-types.js.map +1 -0
  21. package/dist/harness/abort-delivery.d.ts +26 -0
  22. package/dist/harness/abort-delivery.d.ts.map +1 -0
  23. package/dist/harness/abort-delivery.js +36 -0
  24. package/dist/harness/abort-delivery.js.map +1 -0
  25. package/dist/harness/agent-harness.d.ts +38 -6
  26. package/dist/harness/agent-harness.d.ts.map +1 -1
  27. package/dist/harness/agent-harness.js +327 -325
  28. package/dist/harness/agent-harness.js.map +1 -1
  29. package/dist/harness/canonical-digest.d.ts +32 -0
  30. package/dist/harness/canonical-digest.d.ts.map +1 -0
  31. package/dist/harness/canonical-digest.js +164 -0
  32. package/dist/harness/canonical-digest.js.map +1 -0
  33. package/dist/harness/compaction/operation.d.ts +7 -0
  34. package/dist/harness/compaction/operation.d.ts.map +1 -1
  35. package/dist/harness/compaction/operation.js.map +1 -1
  36. package/dist/harness/deferred-commands.d.ts +53 -0
  37. package/dist/harness/deferred-commands.d.ts.map +1 -0
  38. package/dist/harness/deferred-commands.js +96 -0
  39. package/dist/harness/deferred-commands.js.map +1 -0
  40. package/dist/harness/harness-session.d.ts +5 -58
  41. package/dist/harness/harness-session.d.ts.map +1 -1
  42. package/dist/harness/harness-session.js +15 -18
  43. package/dist/harness/harness-session.js.map +1 -1
  44. package/dist/harness/operation-lifecycle-controller.d.ts +68 -0
  45. package/dist/harness/operation-lifecycle-controller.d.ts.map +1 -0
  46. package/dist/harness/operation-lifecycle-controller.js +199 -0
  47. package/dist/harness/operation-lifecycle-controller.js.map +1 -0
  48. package/dist/harness/operation-lifecycle-reducer.d.ts +19 -0
  49. package/dist/harness/operation-lifecycle-reducer.d.ts.map +1 -0
  50. package/dist/harness/operation-lifecycle-reducer.js +201 -0
  51. package/dist/harness/operation-lifecycle-reducer.js.map +1 -0
  52. package/dist/harness/operation-lifecycle-types.d.ts +130 -0
  53. package/dist/harness/operation-lifecycle-types.d.ts.map +1 -0
  54. package/dist/harness/operation-lifecycle-types.js +34 -0
  55. package/dist/harness/operation-lifecycle-types.js.map +1 -0
  56. package/dist/harness/operation-outcome.d.ts +79 -0
  57. package/dist/harness/operation-outcome.d.ts.map +1 -0
  58. package/dist/harness/operation-outcome.js +167 -0
  59. package/dist/harness/operation-outcome.js.map +1 -0
  60. package/dist/harness/operation-trace-divergence.d.ts +60 -0
  61. package/dist/harness/operation-trace-divergence.d.ts.map +1 -0
  62. package/dist/harness/operation-trace-divergence.js +199 -0
  63. package/dist/harness/operation-trace-divergence.js.map +1 -0
  64. package/dist/harness/operation-trace.d.ts +134 -0
  65. package/dist/harness/operation-trace.d.ts.map +1 -0
  66. package/dist/harness/operation-trace.js +161 -0
  67. package/dist/harness/operation-trace.js.map +1 -0
  68. package/dist/harness/session-write-coordinator.d.ts +76 -0
  69. package/dist/harness/session-write-coordinator.d.ts.map +1 -0
  70. package/dist/harness/session-write-coordinator.js +126 -0
  71. package/dist/harness/session-write-coordinator.js.map +1 -0
  72. package/dist/harness/subscriber-fanout.d.ts +50 -0
  73. package/dist/harness/subscriber-fanout.d.ts.map +1 -0
  74. package/dist/harness/subscriber-fanout.js +92 -0
  75. package/dist/harness/subscriber-fanout.js.map +1 -0
  76. package/dist/harness/tree-navigation.d.ts +45 -0
  77. package/dist/harness/tree-navigation.d.ts.map +1 -0
  78. package/dist/harness/tree-navigation.js +59 -0
  79. package/dist/harness/tree-navigation.js.map +1 -0
  80. package/dist/harness/types.d.ts +34 -3
  81. package/dist/harness/types.d.ts.map +1 -1
  82. package/dist/harness/types.js.map +1 -1
  83. package/dist/index.d.ts +2 -0
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -0
  86. package/dist/index.js.map +1 -1
  87. package/dist/listener-delivery.d.ts +22 -0
  88. package/dist/listener-delivery.d.ts.map +1 -0
  89. package/dist/listener-delivery.js +36 -0
  90. package/dist/listener-delivery.js.map +1 -0
  91. package/package.json +4 -3
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Effect Journal V2 vocabulary: the durable identity and phase model for every
3
+ * side effect a harness operation performs.
4
+ *
5
+ * A side effect is not a tool result. The tool result says what the tool
6
+ * reported; the effect record says what the runtime committed to before,
7
+ * during, and after the action, so that after a crash the question "did it
8
+ * happen?" has one of three honest answers — committed, not committed, or
9
+ * unknown — instead of being overwritten by a retry.
10
+ *
11
+ * This module imports nothing and declares no behaviour. Legal phase moves
12
+ * live in `effect-transitions.ts`, the hash-chained journal in
13
+ * `effect-journal.ts`, recovery in `effect-recovery.ts`.
14
+ */
15
+ export declare const EFFECT_RECORD_SCHEMA_VERSION: 2;
16
+ /** The hash a journal's first record chains to. */
17
+ export declare const EFFECT_JOURNAL_GENESIS_HASH: string;
18
+ /**
19
+ * What the runtime may assume about re-executing the effect.
20
+ *
21
+ * | semantics | automatic recovery |
22
+ * | --------------- | ------------------------------------------------- |
23
+ * | `pure` | re-execute freely |
24
+ * | `idempotent` | re-execute with the same idempotency key |
25
+ * | `inspectable` | inspect the target, then decide |
26
+ * | `compensatable` | run the declared compensation |
27
+ * | `opaque` | never re-execute automatically; operator decides |
28
+ */
29
+ export type EffectSemantics = "pure" | "idempotent" | "inspectable" | "compensatable" | "opaque";
30
+ export type EffectPhase = "prepared" | "dispatched" | "observed_committed" | "observed_not_committed" | "commit_unknown" | "acknowledged" | "compensating" | "compensated" | "abandoned";
31
+ /** Phases after which the journal accepts no further transition for the effect. */
32
+ export declare const TERMINAL_EFFECT_PHASES: readonly EffectPhase[];
33
+ /** Phases whose external outcome is not yet known; a verified verdict needs this set empty. */
34
+ export declare const UNCERTAIN_EFFECT_PHASES: readonly EffectPhase[];
35
+ export interface EffectInspectionDescriptor {
36
+ readonly kind: string;
37
+ readonly targetDigest?: string;
38
+ readonly parameters?: Readonly<Record<string, string>>;
39
+ }
40
+ export interface EffectCompensationDescriptor {
41
+ readonly kind: string;
42
+ readonly parameters?: Readonly<Record<string, string>>;
43
+ }
44
+ /** Who performs the effect, under which operation, attempt, lane epoch, and process incarnation. */
45
+ export interface EffectIdentity {
46
+ readonly effectId: string;
47
+ readonly operationId: string;
48
+ readonly attemptId: string;
49
+ readonly laneId?: string;
50
+ readonly laneEpoch?: number;
51
+ readonly processIncarnation: string;
52
+ }
53
+ /** What the effect intends to do, committed before dispatch and constant for the effect's lifetime. */
54
+ export interface EffectIntent {
55
+ readonly semantics: EffectSemantics;
56
+ readonly capabilityDigest: string;
57
+ readonly intentDigest: string;
58
+ readonly idempotencyKey?: string;
59
+ readonly inspectDescriptor?: EffectInspectionDescriptor;
60
+ readonly compensationDescriptor?: EffectCompensationDescriptor;
61
+ }
62
+ /** One hash-chained journal entry: the effect's identity, intent, and phase at `sequence`. */
63
+ export interface EffectRecord extends EffectIdentity, EffectIntent {
64
+ readonly schemaVersion: typeof EFFECT_RECORD_SCHEMA_VERSION;
65
+ readonly phase: EffectPhase;
66
+ readonly sequence: number;
67
+ readonly timestamp: string;
68
+ readonly reasonCode?: string;
69
+ readonly previousRecordHash: string;
70
+ readonly recordHash: string;
71
+ }
72
+ export type EffectObservation = "committed" | "not_committed" | "unknown";
73
+ export type EffectCommand = {
74
+ readonly type: "prepare";
75
+ readonly identity: EffectIdentity;
76
+ readonly intent: EffectIntent;
77
+ readonly timestamp: string;
78
+ } | {
79
+ readonly type: "dispatch";
80
+ readonly effectId: string;
81
+ readonly timestamp: string;
82
+ } | {
83
+ readonly type: "observe";
84
+ readonly effectId: string;
85
+ readonly observation: EffectObservation;
86
+ readonly timestamp: string;
87
+ readonly reasonCode?: string;
88
+ } | {
89
+ readonly type: "acknowledge";
90
+ readonly effectId: string;
91
+ readonly timestamp: string;
92
+ } | {
93
+ readonly type: "resolve_unknown";
94
+ readonly effectId: string;
95
+ readonly inspection: "committed" | "not_committed";
96
+ readonly timestamp: string;
97
+ } | {
98
+ readonly type: "redispatch";
99
+ readonly effectId: string;
100
+ readonly timestamp: string;
101
+ } | {
102
+ readonly type: "compensate_begin";
103
+ readonly effectId: string;
104
+ readonly timestamp: string;
105
+ } | {
106
+ readonly type: "compensate_end";
107
+ readonly effectId: string;
108
+ readonly result: "compensated" | "unknown";
109
+ readonly timestamp: string;
110
+ } | {
111
+ readonly type: "abandon";
112
+ readonly effectId: string;
113
+ readonly reasonCode: string;
114
+ readonly timestamp: string;
115
+ };
116
+ export type EffectViolationCode = "unknown_effect" | "duplicate_effect" | "invalid_transition" | "unsafe_replay" | "missing_descriptor" | "identity_mismatch" | "sequence_violation" | "chain_break" | "hash_mismatch" | "invalid_record";
117
+ export declare class EffectJournalViolation extends Error {
118
+ readonly code: EffectViolationCode;
119
+ readonly effectId?: string;
120
+ constructor(code: EffectViolationCode, message: string, effectId?: string);
121
+ }
122
+ export type EffectJournalResult<T> = {
123
+ readonly ok: true;
124
+ readonly value: T;
125
+ } | {
126
+ readonly ok: false;
127
+ readonly error: EffectJournalViolation;
128
+ };
129
+ /** Latest record per effect plus the chain head; the whole thing is plain data. */
130
+ export interface EffectJournalState {
131
+ readonly headHash: string;
132
+ readonly lastSequence: number;
133
+ readonly effects: Readonly<Record<string, EffectRecord>>;
134
+ }
135
+ //# sourceMappingURL=effect-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-types.d.ts","sourceRoot":"","sources":["../../src/effects/effect-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Effect Journal V2 vocabulary: the durable identity and phase model for every\n * side effect a harness operation performs.\n *\n * A side effect is not a tool result. The tool result says what the tool\n * reported; the effect record says what the runtime committed to before,\n * during, and after the action, so that after a crash the question \"did it\n * happen?\" has one of three honest answers — committed, not committed, or\n * unknown — instead of being overwritten by a retry.\n *\n * This module imports nothing and declares no behaviour. Legal phase moves\n * live in `effect-transitions.ts`, the hash-chained journal in\n * `effect-journal.ts`, recovery in `effect-recovery.ts`.\n */\n\nexport const EFFECT_RECORD_SCHEMA_VERSION = 2 as const;\n\n/** The hash a journal's first record chains to. */\nexport const EFFECT_JOURNAL_GENESIS_HASH = \"0\".repeat(64);\n\n/**\n * What the runtime may assume about re-executing the effect.\n *\n * | semantics | automatic recovery |\n * | --------------- | ------------------------------------------------- |\n * | `pure` | re-execute freely |\n * | `idempotent` | re-execute with the same idempotency key |\n * | `inspectable` | inspect the target, then decide |\n * | `compensatable` | run the declared compensation |\n * | `opaque` | never re-execute automatically; operator decides |\n */\nexport type EffectSemantics = \"pure\" | \"idempotent\" | \"inspectable\" | \"compensatable\" | \"opaque\";\n\nexport type EffectPhase =\n\t| \"prepared\"\n\t| \"dispatched\"\n\t| \"observed_committed\"\n\t| \"observed_not_committed\"\n\t| \"commit_unknown\"\n\t| \"acknowledged\"\n\t| \"compensating\"\n\t| \"compensated\"\n\t| \"abandoned\";\n\n/** Phases after which the journal accepts no further transition for the effect. */\nexport const TERMINAL_EFFECT_PHASES: readonly EffectPhase[] = [\"acknowledged\", \"compensated\", \"abandoned\"];\n\n/** Phases whose external outcome is not yet known; a verified verdict needs this set empty. */\nexport const UNCERTAIN_EFFECT_PHASES: readonly EffectPhase[] = [\"dispatched\", \"commit_unknown\", \"compensating\"];\n\nexport interface EffectInspectionDescriptor {\n\treadonly kind: string;\n\treadonly targetDigest?: string;\n\treadonly parameters?: Readonly<Record<string, string>>;\n}\n\nexport interface EffectCompensationDescriptor {\n\treadonly kind: string;\n\treadonly parameters?: Readonly<Record<string, string>>;\n}\n\n/** Who performs the effect, under which operation, attempt, lane epoch, and process incarnation. */\nexport interface EffectIdentity {\n\treadonly effectId: string;\n\treadonly operationId: string;\n\treadonly attemptId: string;\n\treadonly laneId?: string;\n\treadonly laneEpoch?: number;\n\treadonly processIncarnation: string;\n}\n\n/** What the effect intends to do, committed before dispatch and constant for the effect's lifetime. */\nexport interface EffectIntent {\n\treadonly semantics: EffectSemantics;\n\treadonly capabilityDigest: string;\n\treadonly intentDigest: string;\n\treadonly idempotencyKey?: string;\n\treadonly inspectDescriptor?: EffectInspectionDescriptor;\n\treadonly compensationDescriptor?: EffectCompensationDescriptor;\n}\n\n/** One hash-chained journal entry: the effect's identity, intent, and phase at `sequence`. */\nexport interface EffectRecord extends EffectIdentity, EffectIntent {\n\treadonly schemaVersion: typeof EFFECT_RECORD_SCHEMA_VERSION;\n\treadonly phase: EffectPhase;\n\treadonly sequence: number;\n\treadonly timestamp: string;\n\treadonly reasonCode?: string;\n\treadonly previousRecordHash: string;\n\treadonly recordHash: string;\n}\n\nexport type EffectObservation = \"committed\" | \"not_committed\" | \"unknown\";\n\nexport type EffectCommand =\n\t| {\n\t\t\treadonly type: \"prepare\";\n\t\t\treadonly identity: EffectIdentity;\n\t\t\treadonly intent: EffectIntent;\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"dispatch\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"observe\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly observation: EffectObservation;\n\t\t\treadonly timestamp: string;\n\t\t\treadonly reasonCode?: string;\n\t }\n\t| { readonly type: \"acknowledge\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"resolve_unknown\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly inspection: \"committed\" | \"not_committed\";\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"redispatch\"; readonly effectId: string; readonly timestamp: string }\n\t| { readonly type: \"compensate_begin\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"compensate_end\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly result: \"compensated\" | \"unknown\";\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"abandon\"; readonly effectId: string; readonly reasonCode: string; readonly timestamp: string };\n\nexport type EffectViolationCode =\n\t| \"unknown_effect\"\n\t| \"duplicate_effect\"\n\t| \"invalid_transition\"\n\t| \"unsafe_replay\"\n\t| \"missing_descriptor\"\n\t| \"identity_mismatch\"\n\t| \"sequence_violation\"\n\t| \"chain_break\"\n\t| \"hash_mismatch\"\n\t| \"invalid_record\";\n\nexport class EffectJournalViolation extends Error {\n\tpublic readonly code: EffectViolationCode;\n\tpublic readonly effectId?: string;\n\n\tconstructor(code: EffectViolationCode, message: string, effectId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"EffectJournalViolation\";\n\t\tthis.code = code;\n\t\tthis.effectId = effectId;\n\t}\n}\n\nexport type EffectJournalResult<T> =\n\t| { readonly ok: true; readonly value: T }\n\t| { readonly ok: false; readonly error: EffectJournalViolation };\n\n/** Latest record per effect plus the chain head; the whole thing is plain data. */\nexport interface EffectJournalState {\n\treadonly headHash: string;\n\treadonly lastSequence: number;\n\treadonly effects: Readonly<Record<string, EffectRecord>>;\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Effect Journal V2 vocabulary: the durable identity and phase model for every
3
+ * side effect a harness operation performs.
4
+ *
5
+ * A side effect is not a tool result. The tool result says what the tool
6
+ * reported; the effect record says what the runtime committed to before,
7
+ * during, and after the action, so that after a crash the question "did it
8
+ * happen?" has one of three honest answers — committed, not committed, or
9
+ * unknown — instead of being overwritten by a retry.
10
+ *
11
+ * This module imports nothing and declares no behaviour. Legal phase moves
12
+ * live in `effect-transitions.ts`, the hash-chained journal in
13
+ * `effect-journal.ts`, recovery in `effect-recovery.ts`.
14
+ */
15
+ export const EFFECT_RECORD_SCHEMA_VERSION = 2;
16
+ /** The hash a journal's first record chains to. */
17
+ export const EFFECT_JOURNAL_GENESIS_HASH = "0".repeat(64);
18
+ /** Phases after which the journal accepts no further transition for the effect. */
19
+ export const TERMINAL_EFFECT_PHASES = ["acknowledged", "compensated", "abandoned"];
20
+ /** Phases whose external outcome is not yet known; a verified verdict needs this set empty. */
21
+ export const UNCERTAIN_EFFECT_PHASES = ["dispatched", "commit_unknown", "compensating"];
22
+ export class EffectJournalViolation extends Error {
23
+ code;
24
+ effectId;
25
+ constructor(code, message, effectId) {
26
+ super(message);
27
+ this.name = "EffectJournalViolation";
28
+ this.code = code;
29
+ this.effectId = effectId;
30
+ }
31
+ }
32
+ //# sourceMappingURL=effect-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect-types.js","sourceRoot":"","sources":["../../src/effects/effect-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAU,CAAC;AAEvD,mDAAmD;AACnD,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AA0B1D,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAA2B,CAAC,cAAc,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAE3G,+FAA+F;AAC/F,MAAM,CAAC,MAAM,uBAAuB,GAA2B,CAAC,YAAY,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAC;AA0FhH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAChC,IAAI,CAAsB;IAC1B,QAAQ,CAAU;IAElC,YAAY,IAAyB,EAAE,OAAe,EAAE,QAAiB,EAAE;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAAA,CACzB;CACD","sourcesContent":["/**\n * Effect Journal V2 vocabulary: the durable identity and phase model for every\n * side effect a harness operation performs.\n *\n * A side effect is not a tool result. The tool result says what the tool\n * reported; the effect record says what the runtime committed to before,\n * during, and after the action, so that after a crash the question \"did it\n * happen?\" has one of three honest answers — committed, not committed, or\n * unknown — instead of being overwritten by a retry.\n *\n * This module imports nothing and declares no behaviour. Legal phase moves\n * live in `effect-transitions.ts`, the hash-chained journal in\n * `effect-journal.ts`, recovery in `effect-recovery.ts`.\n */\n\nexport const EFFECT_RECORD_SCHEMA_VERSION = 2 as const;\n\n/** The hash a journal's first record chains to. */\nexport const EFFECT_JOURNAL_GENESIS_HASH = \"0\".repeat(64);\n\n/**\n * What the runtime may assume about re-executing the effect.\n *\n * | semantics | automatic recovery |\n * | --------------- | ------------------------------------------------- |\n * | `pure` | re-execute freely |\n * | `idempotent` | re-execute with the same idempotency key |\n * | `inspectable` | inspect the target, then decide |\n * | `compensatable` | run the declared compensation |\n * | `opaque` | never re-execute automatically; operator decides |\n */\nexport type EffectSemantics = \"pure\" | \"idempotent\" | \"inspectable\" | \"compensatable\" | \"opaque\";\n\nexport type EffectPhase =\n\t| \"prepared\"\n\t| \"dispatched\"\n\t| \"observed_committed\"\n\t| \"observed_not_committed\"\n\t| \"commit_unknown\"\n\t| \"acknowledged\"\n\t| \"compensating\"\n\t| \"compensated\"\n\t| \"abandoned\";\n\n/** Phases after which the journal accepts no further transition for the effect. */\nexport const TERMINAL_EFFECT_PHASES: readonly EffectPhase[] = [\"acknowledged\", \"compensated\", \"abandoned\"];\n\n/** Phases whose external outcome is not yet known; a verified verdict needs this set empty. */\nexport const UNCERTAIN_EFFECT_PHASES: readonly EffectPhase[] = [\"dispatched\", \"commit_unknown\", \"compensating\"];\n\nexport interface EffectInspectionDescriptor {\n\treadonly kind: string;\n\treadonly targetDigest?: string;\n\treadonly parameters?: Readonly<Record<string, string>>;\n}\n\nexport interface EffectCompensationDescriptor {\n\treadonly kind: string;\n\treadonly parameters?: Readonly<Record<string, string>>;\n}\n\n/** Who performs the effect, under which operation, attempt, lane epoch, and process incarnation. */\nexport interface EffectIdentity {\n\treadonly effectId: string;\n\treadonly operationId: string;\n\treadonly attemptId: string;\n\treadonly laneId?: string;\n\treadonly laneEpoch?: number;\n\treadonly processIncarnation: string;\n}\n\n/** What the effect intends to do, committed before dispatch and constant for the effect's lifetime. */\nexport interface EffectIntent {\n\treadonly semantics: EffectSemantics;\n\treadonly capabilityDigest: string;\n\treadonly intentDigest: string;\n\treadonly idempotencyKey?: string;\n\treadonly inspectDescriptor?: EffectInspectionDescriptor;\n\treadonly compensationDescriptor?: EffectCompensationDescriptor;\n}\n\n/** One hash-chained journal entry: the effect's identity, intent, and phase at `sequence`. */\nexport interface EffectRecord extends EffectIdentity, EffectIntent {\n\treadonly schemaVersion: typeof EFFECT_RECORD_SCHEMA_VERSION;\n\treadonly phase: EffectPhase;\n\treadonly sequence: number;\n\treadonly timestamp: string;\n\treadonly reasonCode?: string;\n\treadonly previousRecordHash: string;\n\treadonly recordHash: string;\n}\n\nexport type EffectObservation = \"committed\" | \"not_committed\" | \"unknown\";\n\nexport type EffectCommand =\n\t| {\n\t\t\treadonly type: \"prepare\";\n\t\t\treadonly identity: EffectIdentity;\n\t\t\treadonly intent: EffectIntent;\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"dispatch\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"observe\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly observation: EffectObservation;\n\t\t\treadonly timestamp: string;\n\t\t\treadonly reasonCode?: string;\n\t }\n\t| { readonly type: \"acknowledge\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"resolve_unknown\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly inspection: \"committed\" | \"not_committed\";\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"redispatch\"; readonly effectId: string; readonly timestamp: string }\n\t| { readonly type: \"compensate_begin\"; readonly effectId: string; readonly timestamp: string }\n\t| {\n\t\t\treadonly type: \"compensate_end\";\n\t\t\treadonly effectId: string;\n\t\t\treadonly result: \"compensated\" | \"unknown\";\n\t\t\treadonly timestamp: string;\n\t }\n\t| { readonly type: \"abandon\"; readonly effectId: string; readonly reasonCode: string; readonly timestamp: string };\n\nexport type EffectViolationCode =\n\t| \"unknown_effect\"\n\t| \"duplicate_effect\"\n\t| \"invalid_transition\"\n\t| \"unsafe_replay\"\n\t| \"missing_descriptor\"\n\t| \"identity_mismatch\"\n\t| \"sequence_violation\"\n\t| \"chain_break\"\n\t| \"hash_mismatch\"\n\t| \"invalid_record\";\n\nexport class EffectJournalViolation extends Error {\n\tpublic readonly code: EffectViolationCode;\n\tpublic readonly effectId?: string;\n\n\tconstructor(code: EffectViolationCode, message: string, effectId?: string) {\n\t\tsuper(message);\n\t\tthis.name = \"EffectJournalViolation\";\n\t\tthis.code = code;\n\t\tthis.effectId = effectId;\n\t}\n}\n\nexport type EffectJournalResult<T> =\n\t| { readonly ok: true; readonly value: T }\n\t| { readonly ok: false; readonly error: EffectJournalViolation };\n\n/** Latest record per effect plus the chain head; the whole thing is plain data. */\nexport interface EffectJournalState {\n\treadonly headHash: string;\n\treadonly lastSequence: number;\n\treadonly effects: Readonly<Record<string, EffectRecord>>;\n}\n"]}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pure abort-delivery vocabulary, extracted from `AgentHarness`.
3
+ *
4
+ * Aborting has two halves that callers need separately: delivering the signal
5
+ * (safe from anywhere, including an operation's own callbacks, because it never
6
+ * waits) and waiting for the target's settlement (which a callback of that same
7
+ * operation must never do — settlement awaits the callback). Keeping the refusal
8
+ * table and the delivery description here means the oversized harness module only
9
+ * gains thin delegation, and the rules stay testable without a harness instance.
10
+ */
11
+ import type { HarnessAbortCapture } from "./operation-lifecycle-controller.ts";
12
+ import type { HarnessLifecycleState } from "./operation-lifecycle-types.ts";
13
+ /** What one abort-signal delivery did, without waiting for anything. */
14
+ export interface AbortSignalDeliveryResult {
15
+ /** The operation the signal targeted, when one was active or settling. */
16
+ readonly operationId?: string;
17
+ /** True only when the abort signal was newly delivered to that operation. */
18
+ readonly signalDelivered: boolean;
19
+ /** True when the target was already settling, so no signal could be delivered. */
20
+ readonly alreadySettling: boolean;
21
+ }
22
+ /** Throw when the active operation is one that refuses an abort. */
23
+ export declare function assertAbortAllowed(snapshot: Readonly<HarnessLifecycleState>): void;
24
+ /** Describe one captured abort delivery for a public, wait-free result. */
25
+ export declare function describeAbortDelivery(capture: HarnessAbortCapture): AbortSignalDeliveryResult;
26
+ //# sourceMappingURL=abort-delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort-delivery.d.ts","sourceRoot":"","sources":["../../src/harness/abort-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,qBAAqB,EAAwB,MAAM,gCAAgC,CAAC;AAElG,wEAAwE;AACxE,MAAM,WAAW,yBAAyB;IACzC,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,kFAAkF;IAClF,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CAClC;AAWD,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAIlF;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,yBAAyB,CAM7F","sourcesContent":["/**\n * Pure abort-delivery vocabulary, extracted from `AgentHarness`.\n *\n * Aborting has two halves that callers need separately: delivering the signal\n * (safe from anywhere, including an operation's own callbacks, because it never\n * waits) and waiting for the target's settlement (which a callback of that same\n * operation must never do — settlement awaits the callback). Keeping the refusal\n * table and the delivery description here means the oversized harness module only\n * gains thin delegation, and the rules stay testable without a harness instance.\n */\n\nimport { AgentHarnessError } from \"./errors.ts\";\nimport type { HarnessAbortCapture } from \"./operation-lifecycle-controller.ts\";\nimport type { HarnessLifecycleState, HarnessOperationKind } from \"./operation-lifecycle-types.ts\";\n\n/** What one abort-signal delivery did, without waiting for anything. */\nexport interface AbortSignalDeliveryResult {\n\t/** The operation the signal targeted, when one was active or settling. */\n\treadonly operationId?: string;\n\t/** True only when the abort signal was newly delivered to that operation. */\n\treadonly signalDelivered: boolean;\n\t/** True when the target was already settling, so no signal could be delivered. */\n\treadonly alreadySettling: boolean;\n}\n\n/**\n * Operations that refuse an abort: cancelling them mid-flight would leave their\n * work half-applied, so the caller gets an explicit `invalid_state` instead.\n */\nconst ABORT_REFUSED_OPERATIONS: ReadonlyMap<HarnessOperationKind, string> = new Map([\n\t[\"manual_compaction\", \"Cannot abort during compaction\"],\n\t[\"tree_navigation\", \"Cannot abort during branch_summary\"],\n]);\n\n/** Throw when the active operation is one that refuses an abort. */\nexport function assertAbortAllowed(snapshot: Readonly<HarnessLifecycleState>): void {\n\tif (snapshot.tag !== \"active\") return;\n\tconst refused = ABORT_REFUSED_OPERATIONS.get(snapshot.operation.kind);\n\tif (refused !== undefined) throw new AgentHarnessError(\"invalid_state\", refused);\n}\n\n/** Describe one captured abort delivery for a public, wait-free result. */\nexport function describeAbortDelivery(capture: HarnessAbortCapture): AbortSignalDeliveryResult {\n\treturn {\n\t\t...(capture.target === undefined ? {} : { operationId: capture.target.operation.operationId }),\n\t\tsignalDelivered: capture.signalDelivered,\n\t\talreadySettling: capture.target !== undefined && !capture.signalDelivered,\n\t};\n}\n"]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Pure abort-delivery vocabulary, extracted from `AgentHarness`.
3
+ *
4
+ * Aborting has two halves that callers need separately: delivering the signal
5
+ * (safe from anywhere, including an operation's own callbacks, because it never
6
+ * waits) and waiting for the target's settlement (which a callback of that same
7
+ * operation must never do — settlement awaits the callback). Keeping the refusal
8
+ * table and the delivery description here means the oversized harness module only
9
+ * gains thin delegation, and the rules stay testable without a harness instance.
10
+ */
11
+ import { AgentHarnessError } from "./errors.js";
12
+ /**
13
+ * Operations that refuse an abort: cancelling them mid-flight would leave their
14
+ * work half-applied, so the caller gets an explicit `invalid_state` instead.
15
+ */
16
+ const ABORT_REFUSED_OPERATIONS = new Map([
17
+ ["manual_compaction", "Cannot abort during compaction"],
18
+ ["tree_navigation", "Cannot abort during branch_summary"],
19
+ ]);
20
+ /** Throw when the active operation is one that refuses an abort. */
21
+ export function assertAbortAllowed(snapshot) {
22
+ if (snapshot.tag !== "active")
23
+ return;
24
+ const refused = ABORT_REFUSED_OPERATIONS.get(snapshot.operation.kind);
25
+ if (refused !== undefined)
26
+ throw new AgentHarnessError("invalid_state", refused);
27
+ }
28
+ /** Describe one captured abort delivery for a public, wait-free result. */
29
+ export function describeAbortDelivery(capture) {
30
+ return {
31
+ ...(capture.target === undefined ? {} : { operationId: capture.target.operation.operationId }),
32
+ signalDelivered: capture.signalDelivered,
33
+ alreadySettling: capture.target !== undefined && !capture.signalDelivered,
34
+ };
35
+ }
36
+ //# sourceMappingURL=abort-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abort-delivery.js","sourceRoot":"","sources":["../../src/harness/abort-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAchD;;;GAGG;AACH,MAAM,wBAAwB,GAA8C,IAAI,GAAG,CAAC;IACnF,CAAC,mBAAmB,EAAE,gCAAgC,CAAC;IACvD,CAAC,iBAAiB,EAAE,oCAAoC,CAAC;CACzD,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,UAAU,kBAAkB,CAAC,QAAyC,EAAQ;IACnF,IAAI,QAAQ,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO;IACtC,MAAM,OAAO,GAAG,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtE,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,iBAAiB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAAA,CACjF;AAED,2EAA2E;AAC3E,MAAM,UAAU,qBAAqB,CAAC,OAA4B,EAA6B;IAC9F,OAAO;QACN,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC9F,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,eAAe,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,eAAe;KACzE,CAAC;AAAA,CACF","sourcesContent":["/**\n * Pure abort-delivery vocabulary, extracted from `AgentHarness`.\n *\n * Aborting has two halves that callers need separately: delivering the signal\n * (safe from anywhere, including an operation's own callbacks, because it never\n * waits) and waiting for the target's settlement (which a callback of that same\n * operation must never do — settlement awaits the callback). Keeping the refusal\n * table and the delivery description here means the oversized harness module only\n * gains thin delegation, and the rules stay testable without a harness instance.\n */\n\nimport { AgentHarnessError } from \"./errors.ts\";\nimport type { HarnessAbortCapture } from \"./operation-lifecycle-controller.ts\";\nimport type { HarnessLifecycleState, HarnessOperationKind } from \"./operation-lifecycle-types.ts\";\n\n/** What one abort-signal delivery did, without waiting for anything. */\nexport interface AbortSignalDeliveryResult {\n\t/** The operation the signal targeted, when one was active or settling. */\n\treadonly operationId?: string;\n\t/** True only when the abort signal was newly delivered to that operation. */\n\treadonly signalDelivered: boolean;\n\t/** True when the target was already settling, so no signal could be delivered. */\n\treadonly alreadySettling: boolean;\n}\n\n/**\n * Operations that refuse an abort: cancelling them mid-flight would leave their\n * work half-applied, so the caller gets an explicit `invalid_state` instead.\n */\nconst ABORT_REFUSED_OPERATIONS: ReadonlyMap<HarnessOperationKind, string> = new Map([\n\t[\"manual_compaction\", \"Cannot abort during compaction\"],\n\t[\"tree_navigation\", \"Cannot abort during branch_summary\"],\n]);\n\n/** Throw when the active operation is one that refuses an abort. */\nexport function assertAbortAllowed(snapshot: Readonly<HarnessLifecycleState>): void {\n\tif (snapshot.tag !== \"active\") return;\n\tconst refused = ABORT_REFUSED_OPERATIONS.get(snapshot.operation.kind);\n\tif (refused !== undefined) throw new AgentHarnessError(\"invalid_state\", refused);\n}\n\n/** Describe one captured abort delivery for a public, wait-free result. */\nexport function describeAbortDelivery(capture: HarnessAbortCapture): AbortSignalDeliveryResult {\n\treturn {\n\t\t...(capture.target === undefined ? {} : { operationId: capture.target.operation.operationId }),\n\t\tsignalDelivered: capture.signalDelivered,\n\t\talreadySettling: capture.target !== undefined && !capture.signalDelivered,\n\t};\n}\n"]}
@@ -1,14 +1,14 @@
1
1
  import { type AssistantMessage, type ImageContent, type Model } from "omk-ai";
2
2
  import type { AgentMessage, AgentTool, QueueMode, ThinkingLevel } from "../types.ts";
3
+ import { type AbortSignalDeliveryResult } from "./abort-delivery.ts";
4
+ import { type CommandRef, type DeferredHarnessCommand } from "./deferred-commands.ts";
3
5
  import type { AbortResult, AgentHarnessEvent, AgentHarnessEventResultMap, AgentHarnessOptions, AgentHarnessOwnEvent, AgentHarnessResources, AgentHarnessStreamOptions, CompactResult, ExecutionEnv, HarnessSession, NavigateTreeResult, PromptTemplate, Skill } from "./types.ts";
4
6
  export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate extends PromptTemplate = PromptTemplate, TTool extends AgentTool = AgentTool> {
5
7
  readonly env: ExecutionEnv;
6
8
  private session;
7
9
  private readonly sessionFacade;
8
- private phase;
9
- private runAbortController?;
10
- private runPromise?;
11
- private pendingSessionWrites;
10
+ private readonly lifecycle;
11
+ private readonly sessionWrites;
12
12
  private model;
13
13
  private thinkingLevel;
14
14
  private systemPrompt;
@@ -24,14 +24,25 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
24
24
  private followUpQueueMode;
25
25
  private nextTurnQueue;
26
26
  private handlers;
27
+ private readonly subscribers;
28
+ private readonly deferredCommands;
27
29
  constructor(options: AgentHarnessOptions<TSkill, TPromptTemplate, TTool>);
28
30
  private emitOwn;
29
31
  private emitAny;
32
+ /** Fail closed when an awaited listener tries to wait on its own operation. */
33
+ private rejectCurrentOperationSelfWait;
30
34
  private emitHook;
31
35
  private emitBeforeProviderRequest;
32
36
  private emitBeforeProviderPayload;
33
37
  private emitQueueUpdate;
34
- private startRunPromise;
38
+ /**
39
+ * Facade write-gate vocabulary mapped from lifecycle state. `settling` maps
40
+ * to "idle": the queue is drained by the settlement finalizer first, and
41
+ * listener writes persist after it through the coordinator tail.
42
+ */
43
+ private currentPhase;
44
+ private persistConfigChange;
45
+ private runOperation;
35
46
  private createTurnState;
36
47
  private createContext;
37
48
  private createStreamFn;
@@ -39,10 +50,10 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
39
50
  private createLoopConfig;
40
51
  private validateUniqueNames;
41
52
  private validateToolNames;
42
- private flushPendingSessionWrites;
43
53
  private handleAgentEvent;
44
54
  private emitRunFailure;
45
55
  private executeTurn;
56
+ private runAttempt;
46
57
  private executeAgentRun;
47
58
  private recoverContextOverflow;
48
59
  prompt(text: string, options?: {
@@ -50,6 +61,12 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
50
61
  }): Promise<AssistantMessage>;
51
62
  skill(name: string, additionalInstructions?: string): Promise<AssistantMessage>;
52
63
  promptFromTemplate(name: string, args?: string[]): Promise<AssistantMessage>;
64
+ /**
65
+ * Steering and follow-up input is consumed only by a running agent attempt.
66
+ * A structural operation (`compact`, `navigateTree`) runs none, so accepting
67
+ * input there would silently inject it into an unrelated later prompt.
68
+ */
69
+ private expectQueueConsumer;
53
70
  steer(text: string, options?: {
54
71
  images?: ImageContent[];
55
72
  }): Promise<void>;
@@ -86,6 +103,21 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
86
103
  setResources(resources: AgentHarnessResources<TSkill, TPromptTemplate>): Promise<void>;
87
104
  getStreamOptions(): AgentHarnessStreamOptions;
88
105
  setStreamOptions(streamOptions: AgentHarnessStreamOptions): Promise<void>;
106
+ /**
107
+ * Deliver the abort signal to the current operation without waiting for it to
108
+ * settle. Safe from an operation's own callbacks: nothing here awaits
109
+ * settlement, so it cannot form the cycle `abort()` has to refuse.
110
+ */
111
+ requestAbort(): AbortSignalDeliveryResult;
112
+ /**
113
+ * Queue work to run once the harness is idle and return its ref immediately.
114
+ *
115
+ * This is the callback-safe way to schedule follow-up work: awaiting
116
+ * `waitForIdle()` or `abort()` from a callback of the operation being settled
117
+ * deadlocks, because settlement awaits that callback. The ref reports the
118
+ * command's outcome and cancels it while it is still queued.
119
+ */
120
+ runWhenIdle(command: DeferredHarnessCommand): Promise<CommandRef>;
89
121
  abort(): Promise<AbortResult>;
90
122
  waitForIdle(): Promise<void>;
91
123
  subscribe(listener: (event: AgentHarnessEvent<TSkill, TPromptTemplate>, signal?: AbortSignal) => Promise<void> | void): () => void;