@nylorun/harness 0.5.0-beta.1 → 0.7.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +22 -108
- package/dist/build/agent.d.ts +4 -7
- package/dist/build/agent.js +12 -7
- package/dist/build/assemble.d.ts +2 -6
- package/dist/build/assemble.js +4 -47
- package/dist/build/bind-tool.d.ts +2 -3
- package/dist/build/bind-tool.js +6 -4
- package/dist/build/builder.d.ts +5 -8
- package/dist/build/builder.js +34 -13
- package/dist/build/helpers.d.ts +2 -3
- package/dist/build/helpers.js +0 -1
- package/dist/build/manifest.d.ts +0 -4
- package/dist/build/manifest.js +0 -8
- package/dist/errors.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1 -1
- package/dist/session/capability-state.d.ts +14 -0
- package/dist/session/capability-state.js +67 -0
- package/dist/session/input-queue.d.ts +11 -2
- package/dist/session/input-queue.js +5 -1
- package/dist/session/record.d.ts +11 -0
- package/dist/session/record.js +26 -0
- package/dist/session/scheduler.d.ts +17 -3
- package/dist/session/scheduler.js +181 -48
- package/dist/session/seed.d.ts +10 -0
- package/dist/session/seed.js +219 -0
- package/dist/session/session.d.ts +3 -2
- package/dist/session/session.js +15 -3
- package/dist/session/state.d.ts +8 -3
- package/dist/session/state.js +16 -4
- package/dist/session/submission-stream.d.ts +2 -0
- package/dist/session/submission-stream.js +11 -1
- package/dist/step/model-configuration.d.ts +1 -3
- package/dist/step/model-configuration.js +2 -4
- package/dist/step/project.js +4 -2
- package/dist/step/run.d.ts +6 -1
- package/dist/step/run.js +35 -13
- package/dist/step/seal.d.ts +6 -2
- package/dist/step/seal.js +4 -3
- package/dist/step/step-context.d.ts +5 -2
- package/dist/step/step-context.js +19 -11
- package/dist/turn/plan-runner.d.ts +28 -13
- package/dist/turn/plan-runner.js +165 -182
- package/dist/turn/runner.d.ts +18 -4
- package/dist/turn/runner.js +73 -45
- package/dist/types/manifest.d.ts +0 -6
- package/dist/types/middleware.d.ts +25 -4
- package/dist/types/model.d.ts +3 -2
- package/dist/types/session.d.ts +86 -2
- package/dist/types/shared.d.ts +65 -9
- package/dist/types/tool.d.ts +37 -39
- package/dist/utils/immutable.js +16 -2
- package/package.json +1 -2
- package/dist/build/adapters.d.ts +0 -11
- package/dist/build/adapters.js +0 -91
- package/docs/loop.md +0 -47
- package/docs/model-call-projection.md +0 -112
- package/docs/reference.md +0 -122
package/dist/turn/runner.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { InputEvent, SessionEvent, SessionSnapshot } from "../types/session.js";
|
|
1
|
+
import type { ActiveExecutionRecord, InputEvent, SessionEvent, SessionRecord, SessionSnapshot } from "../types/session.js";
|
|
2
2
|
import type { JsonObject, Tripwire } from "../types/shared.js";
|
|
3
3
|
import type { RequiredInteraction } from "../types/tool.js";
|
|
4
4
|
import type { LoopAgent } from "../build/agent.js";
|
|
5
5
|
import type { ObserveEmit } from "../utils/observe.js";
|
|
6
6
|
import { ToolPlanRunner } from "./plan-runner.js";
|
|
7
|
+
import type { CapabilityStateRegistry } from "../session/capability-state.js";
|
|
7
8
|
export interface PendingTurn {
|
|
8
9
|
readonly plan: ToolPlanRunner;
|
|
9
10
|
readonly turnId: string;
|
|
@@ -21,6 +22,12 @@ export type TurnProgress = {
|
|
|
21
22
|
readonly state: SessionSnapshot;
|
|
22
23
|
readonly pending: PendingTurn;
|
|
23
24
|
readonly interaction: RequiredInteraction;
|
|
25
|
+
} | {
|
|
26
|
+
readonly kind: "deferred";
|
|
27
|
+
readonly state: SessionSnapshot;
|
|
28
|
+
readonly turnId: string;
|
|
29
|
+
readonly stepId: string;
|
|
30
|
+
readonly active: ActiveExecutionRecord;
|
|
24
31
|
} | {
|
|
25
32
|
readonly kind: "tripwire";
|
|
26
33
|
readonly state: SessionSnapshot;
|
|
@@ -30,14 +37,18 @@ export type TurnProgress = {
|
|
|
30
37
|
};
|
|
31
38
|
export interface TurnRunContext {
|
|
32
39
|
readonly signal: AbortSignal;
|
|
40
|
+
readonly states: CapabilityStateRegistry;
|
|
33
41
|
readonly observe: ObserveEmit;
|
|
34
42
|
readonly assertCurrent: () => void;
|
|
35
43
|
readonly onPlanActive: (pending: PendingTurn | undefined) => void;
|
|
36
|
-
readonly
|
|
44
|
+
readonly commit: (state: SessionSnapshot, transition: SessionRecord["transition"], active?: ActiveExecutionRecord) => Promise<SessionSnapshot>;
|
|
37
45
|
readonly onConversation: (event: SessionEvent) => void;
|
|
38
|
-
readonly claimInterrupts: (turnId: string) =>
|
|
46
|
+
readonly claimInterrupts: (state: SessionSnapshot, turnId: string) => Promise<{
|
|
47
|
+
readonly state: SessionSnapshot;
|
|
48
|
+
readonly arrivals: readonly InputEvent[];
|
|
49
|
+
}>;
|
|
39
50
|
}
|
|
40
|
-
/** Advances one Turn until it finalizes, trips
|
|
51
|
+
/** Advances one Turn until it finalizes, trips policy, or reaches a waiting barrier. */
|
|
41
52
|
export declare class TurnRunner {
|
|
42
53
|
private readonly agent;
|
|
43
54
|
private readonly sessionId;
|
|
@@ -47,7 +58,10 @@ export declare class TurnRunner {
|
|
|
47
58
|
readonly context?: JsonObject;
|
|
48
59
|
}>);
|
|
49
60
|
start(state: SessionSnapshot, event: InputEvent, context: TurnRunContext): Promise<TurnProgress>;
|
|
61
|
+
continue(state: SessionSnapshot, context: TurnRunContext): Promise<TurnProgress>;
|
|
50
62
|
resume(state: SessionSnapshot, pending: PendingTurn, event: InputEvent, context: TurnRunContext): Promise<TurnProgress>;
|
|
51
63
|
private advance;
|
|
64
|
+
private waitForInteraction;
|
|
65
|
+
private waitForDeferred;
|
|
52
66
|
private runPlan;
|
|
53
67
|
}
|
package/dist/turn/runner.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { beginTurn, commitCandidate, commitFinal,
|
|
1
|
+
import { beginTurn, commitCandidate, commitFinal, commitToolResults, withStatus, } from "../session/state.js";
|
|
2
2
|
import { runStep } from "../step/run.js";
|
|
3
3
|
import { createId } from "../utils/ids.js";
|
|
4
4
|
import { copyJson } from "../utils/immutable.js";
|
|
5
5
|
import { ToolPlanRunner } from "./plan-runner.js";
|
|
6
|
-
/** Advances one Turn until it finalizes, trips
|
|
6
|
+
/** Advances one Turn until it finalizes, trips policy, or reaches a waiting barrier. */
|
|
7
7
|
export class TurnRunner {
|
|
8
8
|
agent;
|
|
9
9
|
sessionId;
|
|
@@ -15,19 +15,27 @@ export class TurnRunner {
|
|
|
15
15
|
}
|
|
16
16
|
async start(state, event, context) {
|
|
17
17
|
const turnId = createId("turn");
|
|
18
|
-
|
|
19
|
-
context.onState(started);
|
|
18
|
+
state = await context.commit(beginTurn(state, turnId, event), "input");
|
|
20
19
|
context.onConversation({ type: "input", event, turnId });
|
|
21
|
-
return this.advance(
|
|
20
|
+
return this.advance(state, turnId, 1, [event], [], context);
|
|
21
|
+
}
|
|
22
|
+
async continue(state, context) {
|
|
23
|
+
const turnId = createId("turn");
|
|
24
|
+
return this.advance(beginTurn(state, turnId), turnId, 1, [], [], context);
|
|
22
25
|
}
|
|
23
26
|
async resume(state, pending, event, context) {
|
|
27
|
+
const resume = pending.plan.interactionResume(event);
|
|
28
|
+
const active = pending.plan.activeInteractionRecord(pending.turnId, pending.stepId, resume);
|
|
29
|
+
state = await context.commit(withStatus(state, "running", undefined, active), "input", active);
|
|
24
30
|
context.onConversation({ type: "input", event, turnId: pending.turnId });
|
|
25
31
|
const progress = await this.runPlan(pending, context, event);
|
|
26
32
|
if (progress.kind === "interaction-required")
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
return this.waitForInteraction(state, pending, progress.interaction, context);
|
|
34
|
+
if (progress.kind === "deferred")
|
|
35
|
+
return this.waitForDeferred(state, pending, pending.plan.activeToolsRecord(pending.turnId, pending.stepId), context);
|
|
36
|
+
state = await context.commit(commitToolResults(state, pending.turnId, pending.stepId, progress.results), "tool-results");
|
|
37
|
+
pending.plan.publishSettlements(context.observe);
|
|
38
|
+
const claimed = await context.claimInterrupts(state, pending.turnId);
|
|
31
39
|
return this.advance(claimed.state, pending.turnId, pending.stepNumber + 1, claimed.arrivals, progress.results, context);
|
|
32
40
|
}
|
|
33
41
|
async advance(initialState, turnId, firstStep, arrivals, initialResults, context) {
|
|
@@ -49,80 +57,100 @@ export class TurnRunner {
|
|
|
49
57
|
toolResults,
|
|
50
58
|
signal: context.signal,
|
|
51
59
|
session: this.session,
|
|
60
|
+
states: context.states,
|
|
61
|
+
recordModelRequested: (next, active) => context.commit(next, "model-requested", active),
|
|
52
62
|
});
|
|
53
63
|
context.assertCurrent();
|
|
64
|
+
state = run.state;
|
|
65
|
+
const pending = run.output.kind === "tools"
|
|
66
|
+
? {
|
|
67
|
+
plan: new ToolPlanRunner(run.output.plan),
|
|
68
|
+
turnId,
|
|
69
|
+
stepId,
|
|
70
|
+
stepNumber,
|
|
71
|
+
}
|
|
72
|
+
: undefined;
|
|
54
73
|
if (run.candidate) {
|
|
55
|
-
|
|
56
|
-
context.
|
|
74
|
+
const active = pending?.plan.activeToolsRecord(turnId, stepId);
|
|
75
|
+
state = await context.commit(commitCandidate(state, turnId, stepId, run.candidate), "candidate", active);
|
|
76
|
+
context.observe({
|
|
77
|
+
type: "model.completed",
|
|
78
|
+
turnId,
|
|
79
|
+
stepId,
|
|
80
|
+
...(run.requestedModelId === undefined ? {} : { requestedModelId: run.requestedModelId }),
|
|
81
|
+
attributes: run.candidate,
|
|
82
|
+
});
|
|
57
83
|
context.onConversation({ type: "candidate", turnId, stepId, candidate: run.candidate });
|
|
58
84
|
}
|
|
59
85
|
if (run.output.kind === "tripwire")
|
|
60
86
|
return { kind: "tripwire", state, turnId, stepId, tripwire: run.output.tripwire };
|
|
61
|
-
if (run.output.kind === "
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
87
|
+
if (run.output.kind === "deferred-model") {
|
|
88
|
+
state = await context.commit(withStatus(state, "waiting", undefined, run.output.active), "waiting", run.output.active);
|
|
89
|
+
return { kind: "deferred", state, turnId, stepId, active: run.output.active };
|
|
90
|
+
}
|
|
91
|
+
if (run.output.kind === "final") {
|
|
92
|
+
state = await context.commit(withStatus(commitFinal(state, turnId, stepId, run.output.output), "idle"), "final");
|
|
93
|
+
return { kind: "final", state, turnId, stepId, output: run.output.output };
|
|
94
|
+
}
|
|
95
|
+
const toolPlan = run.output.plan;
|
|
70
96
|
context.observe(() => ({
|
|
71
97
|
type: "tool.sealed",
|
|
72
98
|
turnId,
|
|
73
99
|
stepId,
|
|
74
100
|
attributes: {
|
|
75
|
-
executable: Object.freeze(
|
|
101
|
+
executable: Object.freeze(toolPlan.executable.map((entry) => Object.freeze({
|
|
76
102
|
callId: entry.call.callId,
|
|
77
103
|
toolName: entry.call.toolName,
|
|
78
104
|
args: copyJson(entry.call.args),
|
|
79
|
-
executeWith: entry.call.executeWith,
|
|
80
105
|
invocationId: entry.invocationId,
|
|
81
|
-
|
|
106
|
+
owner: entry.owner,
|
|
82
107
|
...(entry.interaction === undefined
|
|
83
108
|
? {}
|
|
84
109
|
: { interaction: copyJson(entry.interaction) }),
|
|
85
110
|
}))),
|
|
86
|
-
immediate: copyJson(
|
|
111
|
+
immediate: copyJson(toolPlan.immediateResults),
|
|
87
112
|
},
|
|
88
113
|
}));
|
|
89
|
-
const pending = {
|
|
90
|
-
plan: new ToolPlanRunner(run.output.plan),
|
|
91
|
-
turnId,
|
|
92
|
-
stepId,
|
|
93
|
-
stepNumber,
|
|
94
|
-
};
|
|
95
114
|
const progress = await this.runPlan(pending, context);
|
|
96
115
|
if (progress.kind === "interaction-required")
|
|
97
|
-
return
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
116
|
+
return this.waitForInteraction(state, pending, progress.interaction, context);
|
|
117
|
+
if (progress.kind === "deferred")
|
|
118
|
+
return this.waitForDeferred(state, pending, pending.plan.activeToolsRecord(turnId, stepId), context);
|
|
119
|
+
state = await context.commit(commitToolResults(state, turnId, stepId, progress.results), "tool-results");
|
|
120
|
+
pending.plan.publishSettlements(context.observe);
|
|
121
|
+
const claimed = await context.claimInterrupts(state, turnId);
|
|
101
122
|
state = claimed.state;
|
|
102
123
|
stepArrivals = claimed.arrivals;
|
|
103
124
|
toolResults = progress.results;
|
|
104
125
|
}
|
|
105
126
|
}
|
|
127
|
+
async waitForInteraction(state, pending, interaction, context) {
|
|
128
|
+
const active = pending.plan.activeInteractionRecord(pending.turnId, pending.stepId);
|
|
129
|
+
state = await context.commit(withStatus(state, "waiting", interaction, active), "waiting", active);
|
|
130
|
+
pending.plan.publishSettlements(context.observe);
|
|
131
|
+
return { kind: "interaction-required", state, pending, interaction };
|
|
132
|
+
}
|
|
133
|
+
async waitForDeferred(state, pending, active, context) {
|
|
134
|
+
state = await context.commit(withStatus(state, "waiting", undefined, active), "waiting", active);
|
|
135
|
+
pending.plan.publishSettlements(context.observe);
|
|
136
|
+
return {
|
|
137
|
+
kind: "deferred",
|
|
138
|
+
state,
|
|
139
|
+
turnId: pending.turnId,
|
|
140
|
+
stepId: pending.stepId,
|
|
141
|
+
active,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
106
144
|
async runPlan(pending, context, resume) {
|
|
107
145
|
context.onPlanActive(pending);
|
|
108
146
|
const progress = await pending.plan.run({
|
|
109
|
-
adapters: this.agent.adapters,
|
|
110
147
|
signal: context.signal,
|
|
111
148
|
observe: context.observe,
|
|
112
149
|
ids: { sessionId: this.sessionId, turnId: pending.turnId, stepId: pending.stepId },
|
|
150
|
+
states: context.states,
|
|
113
151
|
}, resume);
|
|
114
152
|
context.assertCurrent();
|
|
115
153
|
context.onPlanActive(undefined);
|
|
116
154
|
return progress;
|
|
117
155
|
}
|
|
118
156
|
}
|
|
119
|
-
function claimAndRecord(state, turnId, context) {
|
|
120
|
-
const arrivals = context.claimInterrupts(turnId);
|
|
121
|
-
if (arrivals.length === 0)
|
|
122
|
-
return { state, arrivals };
|
|
123
|
-
let next = state;
|
|
124
|
-
for (const event of arrivals)
|
|
125
|
-
next = commitInput(next, turnId, event);
|
|
126
|
-
context.onState(next);
|
|
127
|
-
return { state: next, arrivals };
|
|
128
|
-
}
|
package/dist/types/manifest.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import type { BoundMiddleware } from "./middleware.js";
|
|
2
|
-
import type { ModelDirective } from "./model.js";
|
|
3
2
|
import type { BuildDiagnostic } from "./shared.js";
|
|
4
3
|
export interface AgentManifest {
|
|
5
4
|
readonly middleware: readonly {
|
|
6
5
|
readonly id: string;
|
|
7
6
|
}[];
|
|
8
|
-
readonly model?: ModelDirective;
|
|
9
|
-
readonly adapters: readonly {
|
|
10
|
-
readonly id: string;
|
|
11
|
-
readonly maxConcurrentCalls?: number;
|
|
12
|
-
}[];
|
|
13
7
|
}
|
|
14
8
|
export type BuildResult<Agent> = {
|
|
15
9
|
readonly ok: true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContextMutationOptions, ModelCandidate, ModelDirective, ModelToolCall, ModelConfigurationMutationOptions } from "./model.js";
|
|
2
|
-
import type { InputEvent, TranscriptEntry } from "./session.js";
|
|
2
|
+
import type { InputEvent, SessionIdentity, TranscriptEntry } from "./session.js";
|
|
3
3
|
import type { ContextItem, JsonObject, Tripwire } from "./shared.js";
|
|
4
4
|
import type { Interaction, ToolDefinition, ToolResult } from "./tool.js";
|
|
5
5
|
export interface StepInput {
|
|
@@ -18,7 +18,7 @@ export interface StepInput {
|
|
|
18
18
|
readonly toolResults: readonly ToolResult[];
|
|
19
19
|
readonly transcript: readonly TranscriptEntry[];
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
interface StepRequestBase {
|
|
22
22
|
/** Opaque identity of the Session that owns this Step. */
|
|
23
23
|
readonly sessionId: string;
|
|
24
24
|
/** Opaque identity of the Turn that owns this Step. */
|
|
@@ -49,17 +49,38 @@ export interface StepRequest {
|
|
|
49
49
|
};
|
|
50
50
|
tripwire(error: Tripwire): StepResponse;
|
|
51
51
|
}
|
|
52
|
+
export type StepRequest<State = never> = StepRequestBase & ([State] extends [never] ? object : {
|
|
53
|
+
readonly state: Promise<State>;
|
|
54
|
+
});
|
|
52
55
|
export interface StepResponse {
|
|
53
56
|
candidate(): Readonly<ModelCandidate> | undefined;
|
|
54
57
|
toolCalls(): readonly ModelToolCall[];
|
|
55
58
|
replace(candidate: ModelCandidate): void;
|
|
56
59
|
deny(callId: string, reason: string): void;
|
|
57
60
|
requireInteraction(callId: string, interaction: Interaction): void;
|
|
58
|
-
requirePreflight(callId: string, kind: "sandbox" | "validation"): void;
|
|
59
61
|
tripwire(error: Tripwire): StepResponse;
|
|
60
62
|
}
|
|
61
|
-
export type StepMiddleware = (request: StepRequest
|
|
63
|
+
export type StepMiddleware<State = never> = (request: StepRequest<State>, next: () => Promise<StepResponse>) => Promise<StepResponse>;
|
|
64
|
+
export interface CapabilityState<State> {
|
|
65
|
+
create(session: SessionIdentity, signal: AbortSignal): State | Promise<State>;
|
|
66
|
+
dispose?(value: State): void | Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
export type CapabilityItems<Item> = readonly Item[] | Readonly<{
|
|
69
|
+
readonly slot: string;
|
|
70
|
+
readonly items: readonly Item[];
|
|
71
|
+
}>;
|
|
72
|
+
/** A named capability that may supply static model surface and one typed middleware handler. */
|
|
73
|
+
export interface CapabilityDeclaration<State = never> {
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly tools?: CapabilityItems<ToolDefinition<ToolDefinition["parameters"], State>>;
|
|
76
|
+
readonly instructions?: CapabilityItems<string>;
|
|
77
|
+
readonly model?: ModelDirective;
|
|
78
|
+
readonly state?: CapabilityState<State>;
|
|
79
|
+
readonly middleware?: StepMiddleware<State>;
|
|
80
|
+
}
|
|
62
81
|
export interface BoundMiddleware {
|
|
63
82
|
readonly id: string;
|
|
64
83
|
readonly handle: StepMiddleware;
|
|
84
|
+
readonly state?: CapabilityState<unknown>;
|
|
65
85
|
}
|
|
86
|
+
export {};
|
package/dist/types/model.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ContextItem, JsonObject } from "./shared.js";
|
|
1
|
+
import type { ContextItem, DeferredOutcome, JsonObject } from "./shared.js";
|
|
2
2
|
import type { InputEvent, TranscriptEntry } from "./session.js";
|
|
3
3
|
import type { BoundToolDefinition, ToolResult } from "./tool.js";
|
|
4
4
|
export interface ModelToolCall {
|
|
@@ -161,6 +161,7 @@ export interface ModelCall {
|
|
|
161
161
|
}
|
|
162
162
|
export interface ModelAdapterContext {
|
|
163
163
|
readonly request: ModelRequest;
|
|
164
|
+
readonly invocationId: string;
|
|
164
165
|
readonly signal: AbortSignal;
|
|
165
166
|
}
|
|
166
|
-
export type ModelAdapter = (call: ModelCall, context: ModelAdapterContext) => Promise<ModelCandidate | string>;
|
|
167
|
+
export type ModelAdapter = (call: ModelCall, context: ModelAdapterContext) => Promise<ModelCandidate | string | DeferredOutcome>;
|
package/dist/types/session.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ModelCandidate } from "./model.js";
|
|
1
|
+
import type { ModelCall, ModelCandidate } from "./model.js";
|
|
2
2
|
import type { JsonObject, JsonValue, Observer, Tripwire } from "./shared.js";
|
|
3
|
-
import type { RequiredInteraction, ToolResult } from "./tool.js";
|
|
3
|
+
import type { RequiredInteraction, ToolExecutionResume, ToolOwner, ToolResult } from "./tool.js";
|
|
4
4
|
export type InputEvent = {
|
|
5
5
|
readonly kind: "user-message";
|
|
6
6
|
readonly text: string;
|
|
@@ -39,6 +39,10 @@ export type SessionEvent = {
|
|
|
39
39
|
readonly type: "tripwire";
|
|
40
40
|
readonly tripwire: Tripwire;
|
|
41
41
|
readonly turnId: string;
|
|
42
|
+
} | {
|
|
43
|
+
readonly type: "execution.deferred";
|
|
44
|
+
readonly active: ActiveExecutionRecord;
|
|
45
|
+
readonly turnId: string;
|
|
42
46
|
} | {
|
|
43
47
|
readonly type: "input.queued";
|
|
44
48
|
readonly inputId: string;
|
|
@@ -67,7 +71,23 @@ export interface SessionOptions {
|
|
|
67
71
|
readonly id?: string;
|
|
68
72
|
readonly userId?: string;
|
|
69
73
|
readonly context?: JsonObject;
|
|
74
|
+
readonly seed?: never;
|
|
75
|
+
readonly recorder?: SessionRecorder;
|
|
76
|
+
}
|
|
77
|
+
/** Stable host-owned facts available while a capability creates session-local state. */
|
|
78
|
+
export interface SessionIdentity {
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly userId?: string;
|
|
81
|
+
readonly context?: JsonObject;
|
|
82
|
+
}
|
|
83
|
+
export interface SeededSessionOptions {
|
|
84
|
+
readonly seed: SessionSeed;
|
|
85
|
+
readonly recorder?: SessionRecorder;
|
|
86
|
+
readonly id?: never;
|
|
87
|
+
readonly userId?: never;
|
|
88
|
+
readonly context?: never;
|
|
70
89
|
}
|
|
90
|
+
export type SessionRunOptions = SessionOptions | SeededSessionOptions;
|
|
71
91
|
export interface InputOptions {
|
|
72
92
|
readonly signal?: AbortSignal;
|
|
73
93
|
}
|
|
@@ -108,14 +128,78 @@ export interface SessionSnapshot {
|
|
|
108
128
|
readonly id: string;
|
|
109
129
|
readonly status: "idle" | "running" | "waiting" | "stopped";
|
|
110
130
|
readonly turnCount: number;
|
|
131
|
+
readonly revision: number;
|
|
111
132
|
readonly transcript: readonly TranscriptEntry[];
|
|
112
133
|
readonly pendingInteraction?: RequiredInteraction;
|
|
134
|
+
readonly active?: ActiveExecutionRecord;
|
|
135
|
+
}
|
|
136
|
+
export interface SessionSeed {
|
|
137
|
+
readonly id?: string;
|
|
138
|
+
readonly userId?: string;
|
|
139
|
+
readonly context?: JsonObject;
|
|
140
|
+
readonly turnCount?: number;
|
|
141
|
+
readonly revision?: number;
|
|
142
|
+
readonly transcript: readonly TranscriptEntry[];
|
|
143
|
+
}
|
|
144
|
+
export interface ActiveModelExecutionRecord {
|
|
145
|
+
readonly kind: "model";
|
|
146
|
+
readonly turnId: string;
|
|
147
|
+
readonly stepId: string;
|
|
148
|
+
readonly invocationId: string;
|
|
149
|
+
readonly call: ModelCall;
|
|
150
|
+
readonly token?: JsonValue;
|
|
151
|
+
}
|
|
152
|
+
export interface ActiveToolCallRecord {
|
|
153
|
+
readonly callId: string;
|
|
154
|
+
readonly toolName: string;
|
|
155
|
+
readonly args: JsonValue;
|
|
156
|
+
readonly invocationId: string;
|
|
157
|
+
readonly owner: ToolOwner;
|
|
158
|
+
readonly status: "pending" | "settled" | "deferred";
|
|
159
|
+
readonly result?: ToolResult;
|
|
160
|
+
readonly token?: JsonValue;
|
|
161
|
+
}
|
|
162
|
+
export interface ActiveToolsExecutionRecord {
|
|
163
|
+
readonly kind: "tools";
|
|
164
|
+
readonly turnId: string;
|
|
165
|
+
readonly stepId: string;
|
|
166
|
+
readonly calls: readonly ActiveToolCallRecord[];
|
|
167
|
+
}
|
|
168
|
+
export interface ActiveInteractionExecutionRecord {
|
|
169
|
+
readonly kind: "interaction";
|
|
170
|
+
readonly turnId: string;
|
|
171
|
+
readonly stepId: string;
|
|
172
|
+
readonly callId: string;
|
|
173
|
+
readonly toolName: string;
|
|
174
|
+
readonly interaction: RequiredInteraction;
|
|
175
|
+
readonly token?: JsonValue;
|
|
176
|
+
readonly resume?: ToolExecutionResume;
|
|
177
|
+
readonly tools: ActiveToolsExecutionRecord;
|
|
178
|
+
}
|
|
179
|
+
export type ActiveExecutionRecord = ActiveModelExecutionRecord | ActiveToolsExecutionRecord | ActiveInteractionExecutionRecord;
|
|
180
|
+
export interface SessionRecord {
|
|
181
|
+
readonly version: 1;
|
|
182
|
+
readonly revision: number;
|
|
183
|
+
readonly transition: "input" | "model-requested" | "candidate" | "tool-results" | "waiting" | "final" | "stopped";
|
|
184
|
+
readonly session: {
|
|
185
|
+
readonly id: string;
|
|
186
|
+
readonly userId?: string;
|
|
187
|
+
readonly context?: JsonObject;
|
|
188
|
+
readonly turnCount: number;
|
|
189
|
+
readonly status: SessionSnapshot["status"];
|
|
190
|
+
};
|
|
191
|
+
readonly transcript: readonly TranscriptEntry[];
|
|
192
|
+
readonly active?: ActiveExecutionRecord;
|
|
193
|
+
}
|
|
194
|
+
export interface SessionRecorder {
|
|
195
|
+
record(value: SessionRecord): Promise<void>;
|
|
113
196
|
}
|
|
114
197
|
export interface Session {
|
|
115
198
|
readonly id: string;
|
|
116
199
|
readonly state: SessionSnapshot;
|
|
117
200
|
input(event: SessionInput, options?: InputOptions): InputHandle;
|
|
118
201
|
interrupt(event: MessageInput, options?: InputOptions): InputHandle;
|
|
202
|
+
continue(options?: InputOptions): InputHandle;
|
|
119
203
|
stream(): AsyncIterable<SessionEvent>;
|
|
120
204
|
observe(listener: Observer): () => void;
|
|
121
205
|
stop(reason?: string): Promise<void>;
|
package/dist/types/shared.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
|
|
|
6
6
|
export type JsonObject = {
|
|
7
7
|
readonly [key: string]: JsonValue;
|
|
8
8
|
};
|
|
9
|
+
export interface DeferredOutcome {
|
|
10
|
+
readonly kind: "deferred";
|
|
11
|
+
readonly token?: JsonValue;
|
|
12
|
+
}
|
|
9
13
|
export interface BuildDiagnostic {
|
|
10
14
|
readonly code: string;
|
|
11
15
|
readonly message: string;
|
|
@@ -25,7 +29,10 @@ export interface Tripwire {
|
|
|
25
29
|
export interface ObserveToolSnapshot {
|
|
26
30
|
readonly name: string;
|
|
27
31
|
readonly description?: string;
|
|
28
|
-
readonly
|
|
32
|
+
readonly owner: {
|
|
33
|
+
readonly middlewareId: string;
|
|
34
|
+
readonly slot: string;
|
|
35
|
+
};
|
|
29
36
|
readonly parameters: {
|
|
30
37
|
readonly jsonSchema: JsonObject;
|
|
31
38
|
};
|
|
@@ -38,9 +45,11 @@ export interface ObserveSealedCall {
|
|
|
38
45
|
readonly callId: string;
|
|
39
46
|
readonly toolName: string;
|
|
40
47
|
readonly args: JsonValue;
|
|
41
|
-
readonly executeWith: string;
|
|
42
48
|
readonly invocationId: string;
|
|
43
|
-
readonly
|
|
49
|
+
readonly owner: {
|
|
50
|
+
readonly middlewareId: string;
|
|
51
|
+
readonly slot: string;
|
|
52
|
+
};
|
|
44
53
|
readonly interaction?: RequiredInteraction;
|
|
45
54
|
}
|
|
46
55
|
export interface ObserveModelRequested {
|
|
@@ -54,6 +63,25 @@ export interface ObserveModelRequested {
|
|
|
54
63
|
export type ObserveEvent = {
|
|
55
64
|
readonly type: "session.stopped";
|
|
56
65
|
readonly reason: string;
|
|
66
|
+
} | {
|
|
67
|
+
readonly type: "capability.state.dispose.failed";
|
|
68
|
+
readonly capabilityId: string;
|
|
69
|
+
readonly attributes: {
|
|
70
|
+
readonly message: string;
|
|
71
|
+
};
|
|
72
|
+
} | {
|
|
73
|
+
readonly type: "session.seeded";
|
|
74
|
+
readonly revision: number;
|
|
75
|
+
readonly transcriptEntries: number;
|
|
76
|
+
} | {
|
|
77
|
+
readonly type: "session.continued";
|
|
78
|
+
readonly inputId?: string;
|
|
79
|
+
} | {
|
|
80
|
+
readonly type: "session.record.failed";
|
|
81
|
+
readonly code: string;
|
|
82
|
+
readonly attributes: {
|
|
83
|
+
readonly message: string;
|
|
84
|
+
};
|
|
57
85
|
} | {
|
|
58
86
|
readonly type: "input.received";
|
|
59
87
|
readonly inputId: string;
|
|
@@ -83,6 +111,15 @@ export type ObserveEvent = {
|
|
|
83
111
|
readonly inputId?: string;
|
|
84
112
|
readonly requestedModelId?: string;
|
|
85
113
|
readonly attributes: ModelCandidate;
|
|
114
|
+
} | {
|
|
115
|
+
readonly type: "model.deferred";
|
|
116
|
+
readonly turnId: string;
|
|
117
|
+
readonly stepId: string;
|
|
118
|
+
readonly inputId?: string;
|
|
119
|
+
readonly invocationId: string;
|
|
120
|
+
readonly attributes: {
|
|
121
|
+
readonly token?: JsonValue;
|
|
122
|
+
};
|
|
86
123
|
} | {
|
|
87
124
|
readonly type: "step.started";
|
|
88
125
|
readonly turnId: string;
|
|
@@ -122,28 +159,47 @@ export type ObserveEvent = {
|
|
|
122
159
|
readonly immediate: readonly ToolResult[];
|
|
123
160
|
};
|
|
124
161
|
} | {
|
|
125
|
-
readonly type: "
|
|
162
|
+
readonly type: "tool.started";
|
|
163
|
+
readonly sessionId: string;
|
|
126
164
|
readonly turnId: string;
|
|
127
165
|
readonly stepId: string;
|
|
128
166
|
readonly inputId?: string;
|
|
129
|
-
readonly adapterId: string;
|
|
130
167
|
readonly toolName: string;
|
|
131
168
|
readonly callId: string;
|
|
132
|
-
readonly invocationId
|
|
169
|
+
readonly invocationId: string;
|
|
170
|
+
readonly middlewareId: string;
|
|
171
|
+
readonly slot: string;
|
|
133
172
|
readonly attributes: {
|
|
134
173
|
readonly args: JsonValue;
|
|
135
174
|
};
|
|
136
175
|
} | {
|
|
137
|
-
readonly type: "
|
|
176
|
+
readonly type: "tool.completed";
|
|
177
|
+
readonly sessionId: string;
|
|
138
178
|
readonly turnId: string;
|
|
139
179
|
readonly stepId: string;
|
|
140
180
|
readonly inputId?: string;
|
|
141
|
-
readonly adapterId: string;
|
|
142
181
|
readonly toolName: string;
|
|
143
182
|
readonly callId: string;
|
|
183
|
+
readonly invocationId: string;
|
|
184
|
+
readonly middlewareId: string;
|
|
185
|
+
readonly slot: string;
|
|
144
186
|
readonly outcome: string;
|
|
145
187
|
readonly code?: string;
|
|
146
188
|
readonly attributes?: ToolResult;
|
|
189
|
+
} | {
|
|
190
|
+
readonly type: "tool.deferred";
|
|
191
|
+
readonly sessionId: string;
|
|
192
|
+
readonly turnId: string;
|
|
193
|
+
readonly stepId: string;
|
|
194
|
+
readonly inputId?: string;
|
|
195
|
+
readonly toolName: string;
|
|
196
|
+
readonly callId: string;
|
|
197
|
+
readonly invocationId: string;
|
|
198
|
+
readonly middlewareId: string;
|
|
199
|
+
readonly slot: string;
|
|
200
|
+
readonly attributes: {
|
|
201
|
+
readonly token?: JsonValue;
|
|
202
|
+
};
|
|
147
203
|
} | {
|
|
148
204
|
readonly type: "turn.completed";
|
|
149
205
|
readonly turnId: string;
|
|
@@ -161,7 +217,7 @@ export type ObserveEvent = {
|
|
|
161
217
|
readonly kind: string;
|
|
162
218
|
readonly callId?: string;
|
|
163
219
|
readonly toolName?: string;
|
|
164
|
-
readonly phase?: "interaction" | "
|
|
220
|
+
readonly phase?: "interaction" | "execute";
|
|
165
221
|
readonly attributes: {
|
|
166
222
|
readonly prompt: string;
|
|
167
223
|
readonly metadata?: JsonObject;
|