@nylorun/harness 0.12.0-beta → 0.15.0-beta

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 (137) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/HOST_CONTRACT.md +27 -0
  3. package/README.md +86 -5
  4. package/dist/compatibility.d.ts +3 -0
  5. package/dist/compatibility.js +3 -0
  6. package/dist/definition/agent-definition.d.ts +19 -0
  7. package/dist/definition/agent-definition.js +20 -0
  8. package/dist/definition/compatibility.d.ts +11 -0
  9. package/dist/definition/compatibility.js +30 -0
  10. package/dist/definition/registry.d.ts +10 -0
  11. package/dist/definition/registry.js +49 -0
  12. package/dist/index.d.ts +4 -15
  13. package/dist/index.js +1 -6
  14. package/dist/loop/dispatch.d.ts +2 -0
  15. package/dist/loop/dispatch.js +327 -0
  16. package/dist/loop/host-suspension.d.ts +6 -0
  17. package/dist/loop/host-suspension.js +10 -0
  18. package/dist/loop/initial-state.d.ts +13 -0
  19. package/dist/loop/initial-state.js +30 -0
  20. package/dist/loop/invocation.d.ts +24 -0
  21. package/dist/loop/invocation.js +37 -0
  22. package/dist/{model → loop/model}/adapters.d.ts +4 -2
  23. package/dist/{model → loop/model}/adapters.js +3 -2
  24. package/dist/{model → loop/model}/normalize.d.ts +2 -2
  25. package/dist/{model → loop/model}/normalize.js +2 -2
  26. package/dist/{model → loop/model}/prepared.d.ts +3 -3
  27. package/dist/{step → loop/model}/project.d.ts +1 -1
  28. package/dist/{step → loop/model}/project.js +2 -10
  29. package/dist/loop/observe.d.ts +17 -0
  30. package/dist/loop/observe.js +53 -0
  31. package/dist/loop/options.d.ts +11 -0
  32. package/dist/loop/options.js +69 -0
  33. package/dist/loop/resume.d.ts +4 -0
  34. package/dist/loop/resume.js +52 -0
  35. package/dist/loop/run.d.ts +5 -0
  36. package/dist/loop/run.js +264 -0
  37. package/dist/loop/state.d.ts +8 -0
  38. package/dist/loop/state.js +218 -0
  39. package/dist/{step → loop/step}/canonicalize.d.ts +2 -2
  40. package/dist/{step → loop/step}/canonicalize.js +2 -2
  41. package/dist/{step → loop/step}/compose.d.ts +3 -2
  42. package/dist/{step → loop/step}/compose.js +8 -5
  43. package/dist/loop/step/context-draft.d.ts +8 -0
  44. package/dist/{step → loop/step}/context-draft.js +5 -22
  45. package/dist/loop/step/describe.d.ts +9 -0
  46. package/dist/loop/step/describe.js +22 -0
  47. package/dist/loop/step/dynamics.d.ts +29 -0
  48. package/dist/loop/step/dynamics.js +147 -0
  49. package/dist/{step → loop/step}/model-configuration.d.ts +4 -3
  50. package/dist/{step → loop/step}/model-configuration.js +3 -3
  51. package/dist/loop/step/resolve.d.ts +11 -0
  52. package/dist/{step → loop/step}/resolve.js +5 -3
  53. package/dist/loop/step/run.d.ts +30 -0
  54. package/dist/{step → loop/step}/run.js +104 -53
  55. package/dist/loop/step/runtime.d.ts +40 -0
  56. package/dist/{step → loop/step}/seal.d.ts +13 -8
  57. package/dist/{step → loop/step}/seal.js +8 -6
  58. package/dist/{step → loop/step}/slot-assembly.d.ts +4 -4
  59. package/dist/{step → loop/step}/slot-assembly.js +4 -4
  60. package/dist/{step → loop/step}/step-context.d.ts +11 -12
  61. package/dist/{step → loop/step}/step-context.js +5 -27
  62. package/dist/loop/tool-result.d.ts +4 -0
  63. package/dist/loop/tool-result.js +30 -0
  64. package/dist/loop/transcript.d.ts +2 -0
  65. package/dist/{session/seed.js → loop/transcript.js} +11 -41
  66. package/dist/loop/waits.d.ts +50 -0
  67. package/dist/loop/waits.js +11 -0
  68. package/dist/run/durable.d.ts +71 -0
  69. package/dist/run/durable.js +164 -0
  70. package/dist/run/index.d.ts +33 -0
  71. package/dist/run/index.js +38 -0
  72. package/dist/types/client.d.ts +88 -0
  73. package/dist/types/execution.d.ts +114 -0
  74. package/dist/utils/ids.d.ts +1 -0
  75. package/dist/utils/ids.js +11 -1
  76. package/package.json +18 -6
  77. package/dist/build/agent.d.ts +0 -17
  78. package/dist/build/agent.js +0 -32
  79. package/dist/build/assemble.d.ts +0 -7
  80. package/dist/build/assemble.js +0 -41
  81. package/dist/build/bind-tool.d.ts +0 -3
  82. package/dist/build/bind-tool.js +0 -18
  83. package/dist/build/builder.d.ts +0 -38
  84. package/dist/build/builder.js +0 -136
  85. package/dist/build/helpers.d.ts +0 -6
  86. package/dist/build/helpers.js +0 -4
  87. package/dist/build/manifest.d.ts +0 -7
  88. package/dist/build/manifest.js +0 -20
  89. package/dist/build/schema.d.ts +0 -14
  90. package/dist/build/schema.js +0 -205
  91. package/dist/errors.d.ts +0 -17
  92. package/dist/errors.js +0 -17
  93. package/dist/session/capability-state.d.ts +0 -14
  94. package/dist/session/capability-state.js +0 -67
  95. package/dist/session/event-log.d.ts +0 -12
  96. package/dist/session/event-log.js +0 -63
  97. package/dist/session/input-queue.d.ts +0 -41
  98. package/dist/session/input-queue.js +0 -94
  99. package/dist/session/output-contract.d.ts +0 -6
  100. package/dist/session/output-contract.js +0 -12
  101. package/dist/session/record.d.ts +0 -11
  102. package/dist/session/record.js +0 -26
  103. package/dist/session/scheduler.d.ts +0 -62
  104. package/dist/session/scheduler.js +0 -475
  105. package/dist/session/seed.d.ts +0 -10
  106. package/dist/session/session.d.ts +0 -17
  107. package/dist/session/session.js +0 -101
  108. package/dist/session/state.d.ts +0 -15
  109. package/dist/session/state.js +0 -48
  110. package/dist/session/submission-stream.d.ts +0 -16
  111. package/dist/session/submission-stream.js +0 -46
  112. package/dist/step/context-draft.d.ts +0 -10
  113. package/dist/step/resolve.d.ts +0 -10
  114. package/dist/step/run.d.ts +0 -33
  115. package/dist/turn/plan-runner.d.ts +0 -72
  116. package/dist/turn/plan-runner.js +0 -389
  117. package/dist/turn/runner.d.ts +0 -69
  118. package/dist/turn/runner.js +0 -159
  119. package/dist/types/manifest.d.ts +0 -19
  120. package/dist/types/middleware.d.ts +0 -95
  121. package/dist/types/model.d.ts +0 -184
  122. package/dist/types/session.d.ts +0 -230
  123. package/dist/types/session.js +0 -1
  124. package/dist/types/shared.d.ts +0 -249
  125. package/dist/types/shared.js +0 -1
  126. package/dist/types/tool.d.ts +0 -139
  127. package/dist/types/tool.js +0 -1
  128. package/dist/utils/immutable.d.ts +0 -5
  129. package/dist/utils/immutable.js +0 -68
  130. package/dist/utils/maps.d.ts +0 -1
  131. package/dist/utils/maps.js +0 -37
  132. package/dist/utils/observe.d.ts +0 -3
  133. package/dist/utils/observe.js +0 -13
  134. /package/dist/{model → loop/model}/prepared.js +0 -0
  135. /package/dist/{types/manifest.js → loop/step/runtime.js} +0 -0
  136. /package/dist/types/{middleware.js → client.js} +0 -0
  137. /package/dist/types/{model.js → execution.js} +0 -0
@@ -1,41 +0,0 @@
1
- import type { InputEvent, InputOptions } from "../types/session.js";
2
- import type { TurnOutputContract } from "./output-contract.js";
3
- import { SubmissionStream } from "./submission-stream.js";
4
- export type WorkEvent = InputEvent | {
5
- readonly kind: "continue";
6
- };
7
- export interface QueuedInput {
8
- readonly event: WorkEvent;
9
- readonly options?: InputOptions & {
10
- readonly output?: TurnOutputContract;
11
- };
12
- readonly stream: SubmissionStream;
13
- cancelled: boolean;
14
- }
15
- export type QueuedInterrupt = Omit<QueuedInput, "event"> & {
16
- readonly event: InputEvent & {
17
- readonly kind: "interrupt";
18
- };
19
- };
20
- export interface QueueAbortHandlers {
21
- readonly isActive: () => boolean;
22
- readonly abortActive: (reason: unknown) => void;
23
- readonly cancelQueued: () => void;
24
- }
25
- export declare function isInteractionReply(event: InputEvent): event is Extract<InputEvent, {
26
- kind: "approve" | "respond";
27
- }>;
28
- export declare function snapshotInput(event: InputEvent): InputEvent;
29
- export declare function snapshotWork(event: WorkEvent): WorkEvent;
30
- /** Serializes ordinary input while allowing a matching interaction reply to resume immediately. */
31
- export declare class InputQueue {
32
- private readonly values;
33
- get size(): number;
34
- add(input: QueuedInput, priority?: boolean): void;
35
- take(waitingForInteraction: boolean): QueuedInput | undefined;
36
- takeInterrupts(): QueuedInterrupt[];
37
- remove(input: QueuedInput): boolean;
38
- drain(): readonly QueuedInput[];
39
- }
40
- /** Binds one caller-provided signal to its queue entry and always removes the listener at completion. */
41
- export declare function watchInputAbort(input: QueuedInput, handlers: QueueAbortHandlers): void;
@@ -1,94 +0,0 @@
1
- import { copyJson, copyJsonObject } from "../utils/immutable.js";
2
- import { SubmissionStream } from "./submission-stream.js";
3
- export function isInteractionReply(event) {
4
- return event.kind === "approve" || event.kind === "respond";
5
- }
6
- export function snapshotInput(event) {
7
- switch (event.kind) {
8
- case "user-message":
9
- case "interrupt":
10
- if ("content" in event)
11
- return Object.freeze({
12
- kind: event.kind,
13
- content: Object.freeze(event.content.map((part) => part.type === "text"
14
- ? Object.freeze({ type: "text", text: part.text })
15
- : Object.freeze({
16
- type: "media",
17
- mediaType: part.mediaType,
18
- reference: copyJson(part.reference),
19
- }))),
20
- ...(event.metadata ? { metadata: copyJsonObject(event.metadata, "input metadata") } : {}),
21
- });
22
- return Object.freeze({
23
- kind: event.kind,
24
- text: event.text,
25
- ...(event.metadata ? { metadata: copyJsonObject(event.metadata, "input metadata") } : {}),
26
- });
27
- case "approve":
28
- return Object.freeze({ ...event });
29
- case "respond":
30
- return Object.freeze({ ...event, value: copyJson(event.value) });
31
- }
32
- }
33
- export function snapshotWork(event) {
34
- return event.kind === "continue" ? Object.freeze({ kind: "continue" }) : snapshotInput(event);
35
- }
36
- /** Serializes ordinary input while allowing a matching interaction reply to resume immediately. */
37
- export class InputQueue {
38
- values = [];
39
- get size() {
40
- return this.values.length;
41
- }
42
- add(input, priority = false) {
43
- if (priority)
44
- this.values.unshift(input);
45
- else
46
- this.values.push(input);
47
- }
48
- take(waitingForInteraction) {
49
- const next = this.values[0];
50
- if (!next ||
51
- (waitingForInteraction && (next.event.kind === "continue" || !isInteractionReply(next.event))))
52
- return undefined;
53
- return this.values.shift();
54
- }
55
- takeInterrupts() {
56
- const claimed = [];
57
- for (let index = 0; index < this.values.length;) {
58
- const item = this.values[index];
59
- if (item.event.kind !== "interrupt") {
60
- index += 1;
61
- continue;
62
- }
63
- this.values.splice(index, 1);
64
- if (!item.cancelled)
65
- claimed.push(item);
66
- }
67
- return claimed;
68
- }
69
- remove(input) {
70
- const index = this.values.indexOf(input);
71
- if (index < 0)
72
- return false;
73
- this.values.splice(index, 1);
74
- return true;
75
- }
76
- drain() {
77
- return this.values.splice(0);
78
- }
79
- }
80
- /** Binds one caller-provided signal to its queue entry and always removes the listener at completion. */
81
- export function watchInputAbort(input, handlers) {
82
- const signal = input.options?.signal;
83
- if (!signal)
84
- return;
85
- const onAbort = () => {
86
- input.cancelled = true;
87
- if (handlers.isActive())
88
- handlers.abortActive(signal.reason);
89
- else
90
- handlers.cancelQueued();
91
- };
92
- signal.addEventListener("abort", onAbort, { once: true });
93
- input.stream.onFinish(() => signal.removeEventListener("abort", onAbort));
94
- }
@@ -1,6 +0,0 @@
1
- import type { BoundToolSchema, ToolSchemaSource } from "../types/tool.js";
2
- /** Runtime-only validator paired with the portable JSON Schema projected to models. */
3
- export interface TurnOutputContract {
4
- readonly schema: BoundToolSchema<unknown>;
5
- }
6
- export declare function bindOutputContract(source: ToolSchemaSource): TurnOutputContract;
@@ -1,12 +0,0 @@
1
- import { HarnessError, isHarnessError } from "../errors.js";
2
- import { normalizeSchema } from "../build/schema.js";
3
- export function bindOutputContract(source) {
4
- try {
5
- return Object.freeze({ schema: normalizeSchema(source, "output") });
6
- }
7
- catch (cause) {
8
- if (isHarnessError(cause))
9
- throw new HarnessError("output.invalid-schema", cause.message, { cause });
10
- throw new HarnessError("output.invalid-schema", String(cause), { cause });
11
- }
12
- }
@@ -1,11 +0,0 @@
1
- import type { ActiveExecutionRecord, SessionRecord, SessionSnapshot } from "../types/session.js";
2
- import type { JsonObject } from "../types/shared.js";
3
- export declare function sessionRecord(input: {
4
- readonly state: SessionSnapshot;
5
- readonly transition: SessionRecord["transition"];
6
- readonly session: Readonly<{
7
- readonly userId?: string;
8
- readonly context?: JsonObject;
9
- }>;
10
- readonly active?: ActiveExecutionRecord;
11
- }): SessionRecord;
@@ -1,26 +0,0 @@
1
- import { copyJson } from "../utils/immutable.js";
2
- export function sessionRecord(input) {
3
- const value = {
4
- version: 1,
5
- revision: input.state.revision,
6
- transition: input.transition,
7
- session: {
8
- id: input.state.id,
9
- ...(input.session.userId === undefined ? {} : { userId: input.session.userId }),
10
- ...(input.session.context === undefined ? {} : { context: copyJson(input.session.context) }),
11
- turnCount: input.state.turnCount,
12
- status: input.state.status,
13
- },
14
- transcript: copyJson(input.state.transcript),
15
- ...(input.active === undefined ? {} : { active: copyJson(input.active) }),
16
- };
17
- return deepFreeze(value);
18
- }
19
- function deepFreeze(value, seen = new WeakSet()) {
20
- if (!value || typeof value !== "object" || seen.has(value))
21
- return value;
22
- seen.add(value);
23
- for (const child of Object.values(value))
24
- deepFreeze(child, seen);
25
- return Object.freeze(value);
26
- }
@@ -1,62 +0,0 @@
1
- import type { InputEvent, InputOptions, SessionRecorder, SessionSnapshot } from "../types/session.js";
2
- import type { Observer } from "../types/shared.js";
3
- import { SessionEventLog } from "./event-log.js";
4
- import { SubmissionStream } from "./submission-stream.js";
5
- import { type LoopAgent } from "../build/agent.js";
6
- import type { NormalizedSessionSeed } from "./seed.js";
7
- /** Coordinates one active turn at a time; TurnRunner owns the turn's internal state machine. */
8
- export declare class SessionScheduler {
9
- readonly id: string;
10
- readonly events: SessionEventLog;
11
- private snapshotValue;
12
- private readonly queue;
13
- private readonly sessionController;
14
- private activeController?;
15
- private activeSubmission?;
16
- private activeWork?;
17
- private pending?;
18
- private inFlightPlan?;
19
- private running;
20
- private stopping;
21
- private stopped;
22
- private suspended;
23
- private generation;
24
- private stopPromise?;
25
- private recordFailure?;
26
- private readonly turns;
27
- private readonly states;
28
- constructor(id: string, agent: LoopAgent, session: Readonly<{
29
- readonly userId?: string;
30
- readonly context?: import("../types/shared.js").JsonObject;
31
- }>, options?: {
32
- readonly seed?: NormalizedSessionSeed;
33
- readonly recorder?: SessionRecorder;
34
- readonly observer?: Observer;
35
- });
36
- private readonly session;
37
- private readonly recorder?;
38
- private readonly observer?;
39
- get snapshot(): SessionSnapshot;
40
- submit(event: InputEvent, options?: InputOptions): SubmissionStream;
41
- continue(options?: InputOptions): SubmissionStream;
42
- private submitWork;
43
- stop(reason?: string): Promise<void>;
44
- private enqueueReply;
45
- private enqueueOrdinaryInput;
46
- private watchAbort;
47
- private reject;
48
- private finishCancelled;
49
- private finishStopped;
50
- private publish;
51
- private pump;
52
- private run;
53
- private resumeTurn;
54
- private applyTurnOutcome;
55
- private emitObserve;
56
- private commitCancelledPlan;
57
- private claimInterrupts;
58
- private commit;
59
- private assertRecordable;
60
- private failRecording;
61
- private assertCurrent;
62
- }