@nylorun/harness 0.11.1-beta → 0.12.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.
- package/CHANGELOG.md +6 -0
- package/dist/build/agent.d.ts +2 -3
- package/dist/build/agent.js +6 -11
- package/dist/build/assemble.d.ts +1 -2
- package/dist/build/assemble.js +2 -5
- package/dist/build/builder.d.ts +1 -9
- package/dist/build/builder.js +19 -34
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/session/scheduler.d.ts +2 -2
- package/dist/session/scheduler.js +5 -15
- package/dist/session/session.d.ts +1 -2
- package/dist/session/session.js +1 -3
- package/dist/turn/plan-runner.d.ts +2 -0
- package/dist/turn/plan-runner.js +1 -0
- package/dist/turn/runner.js +1 -0
- package/dist/types/session.d.ts +5 -2
- package/dist/types/tool.d.ts +3 -0
- package/dist/utils/observe.d.ts +1 -6
- package/dist/utils/observe.js +12 -28
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 4badb5b: Move model execution to session startup, provide Runtime as a mountable Hono router, and generate Hono-first projects with supervised application and Studio development. Studio now resolves root-relative Runtime endpoints correctly for custom mount paths.
|
|
8
|
+
|
|
3
9
|
## 0.11.1-beta
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/build/agent.d.ts
CHANGED
|
@@ -7,12 +7,11 @@ export interface LoopAgent {
|
|
|
7
7
|
readonly invoke: ModelAdapter;
|
|
8
8
|
}
|
|
9
9
|
export declare class BuiltAgent {
|
|
10
|
-
#private;
|
|
11
10
|
readonly middleware: readonly BoundMiddleware[];
|
|
12
11
|
readonly manifest: AgentManifest;
|
|
13
12
|
readonly id: string;
|
|
14
13
|
readonly name: string;
|
|
15
14
|
private constructor();
|
|
16
|
-
run(options
|
|
15
|
+
run(options: SessionRunOptions): Session;
|
|
17
16
|
}
|
|
18
|
-
export declare function bindAgent(middleware: readonly BoundMiddleware[],
|
|
17
|
+
export declare function bindAgent(middleware: readonly BoundMiddleware[], manifest: AgentManifest): BuiltAgent;
|
package/dist/build/agent.js
CHANGED
|
@@ -7,21 +7,16 @@ export class BuiltAgent {
|
|
|
7
7
|
manifest;
|
|
8
8
|
id;
|
|
9
9
|
name;
|
|
10
|
-
|
|
11
|
-
constructor(middleware, invoke, manifest) {
|
|
10
|
+
constructor(middleware, manifest) {
|
|
12
11
|
this.middleware = middleware;
|
|
13
12
|
this.manifest = manifest;
|
|
14
13
|
this.id = manifest.id;
|
|
15
14
|
this.name = manifest.name;
|
|
16
|
-
this.#loopAgent = Object.freeze({
|
|
17
|
-
middleware,
|
|
18
|
-
invoke,
|
|
19
|
-
});
|
|
20
15
|
}
|
|
21
16
|
static {
|
|
22
|
-
createBoundAgent = (middleware,
|
|
17
|
+
createBoundAgent = (middleware, manifest) => new BuiltAgent(middleware, manifest);
|
|
23
18
|
}
|
|
24
|
-
run(options
|
|
19
|
+
run(options) {
|
|
25
20
|
const seeded = "seed" in options && options.seed !== undefined;
|
|
26
21
|
if (seeded &&
|
|
27
22
|
(("id" in options && options.id !== undefined) ||
|
|
@@ -29,9 +24,9 @@ export class BuiltAgent {
|
|
|
29
24
|
("context" in options && options.context !== undefined)))
|
|
30
25
|
throw new HarnessError("session.invalid-seed", "Seeded run options cannot include id, userId, or context outside the seed");
|
|
31
26
|
const id = (seeded ? options.seed.id : "id" in options ? options.id : undefined) ?? createId("session");
|
|
32
|
-
return new LiveSession(id, this
|
|
27
|
+
return new LiveSession(id, Object.freeze({ middleware: this.middleware, invoke: options.onModelCall }), options);
|
|
33
28
|
}
|
|
34
29
|
}
|
|
35
|
-
export function bindAgent(middleware,
|
|
36
|
-
return createBoundAgent(middleware,
|
|
30
|
+
export function bindAgent(middleware, manifest) {
|
|
31
|
+
return createBoundAgent(middleware, manifest);
|
|
37
32
|
}
|
package/dist/build/assemble.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { BuildResult } from "../types/manifest.js";
|
|
2
2
|
import type { BoundMiddleware } from "../types/middleware.js";
|
|
3
|
-
import type { ModelAdapter } from "../types/model.js";
|
|
4
3
|
import { type BuiltAgent } from "./agent.js";
|
|
5
|
-
export declare function assembleAgent(middleware: readonly BoundMiddleware[],
|
|
4
|
+
export declare function assembleAgent(middleware: readonly BoundMiddleware[], identity: Readonly<{
|
|
6
5
|
id: string;
|
|
7
6
|
name: string;
|
|
8
7
|
}>): BuildResult<BuiltAgent>;
|
package/dist/build/assemble.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { bindAgent } from "./agent.js";
|
|
2
2
|
import { createManifest } from "./manifest.js";
|
|
3
3
|
const diagnostic = (code, message, extra = {}) => Object.freeze({ code, message, ...extra });
|
|
4
|
-
export function assembleAgent(middleware,
|
|
4
|
+
export function assembleAgent(middleware, identity) {
|
|
5
5
|
const diagnostics = [];
|
|
6
6
|
if (typeof identity.id !== "string" || identity.id.length === 0) {
|
|
7
7
|
diagnostics.push(diagnostic("agent.invalid-id", "Agent id must be a non-empty string"));
|
|
@@ -9,9 +9,6 @@ export function assembleAgent(middleware, invoke, identity) {
|
|
|
9
9
|
if (typeof identity.name !== "string" || identity.name.length === 0) {
|
|
10
10
|
diagnostics.push(diagnostic("agent.invalid-name", "Agent name must be a non-empty string"));
|
|
11
11
|
}
|
|
12
|
-
if (typeof invoke !== "function") {
|
|
13
|
-
diagnostics.push(diagnostic("harness.invalid-model", "A model invoke function is required"));
|
|
14
|
-
}
|
|
15
12
|
const middlewareIds = new Set();
|
|
16
13
|
const frozen = [];
|
|
17
14
|
for (const item of middleware) {
|
|
@@ -39,6 +36,6 @@ export function assembleAgent(middleware, invoke, identity) {
|
|
|
39
36
|
name: identity.name,
|
|
40
37
|
middleware: frozenMiddleware,
|
|
41
38
|
});
|
|
42
|
-
const agent = bindAgent(frozenMiddleware,
|
|
39
|
+
const agent = bindAgent(frozenMiddleware, manifest);
|
|
43
40
|
return Object.freeze({ ok: true, agent, manifest });
|
|
44
41
|
}
|
package/dist/build/builder.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { BoundMiddleware, CapabilityDeclaration, StepMiddleware } from "../types/middleware.js";
|
|
2
|
-
import type { ModelAdapter } from "../types/model.js";
|
|
3
2
|
import type { BuildDiagnostic } from "../types/shared.js";
|
|
4
3
|
import { HarnessError } from "../errors.js";
|
|
5
4
|
import type { BuiltAgent } from "./agent.js";
|
|
@@ -12,8 +11,6 @@ interface BuilderState {
|
|
|
12
11
|
readonly id: string;
|
|
13
12
|
readonly name: string;
|
|
14
13
|
readonly middleware: BoundMiddleware[];
|
|
15
|
-
invoke?: ModelAdapter;
|
|
16
|
-
bound: boolean;
|
|
17
14
|
sealed: boolean;
|
|
18
15
|
agent?: BuiltAgent;
|
|
19
16
|
error?: AgentBuildError;
|
|
@@ -33,14 +30,9 @@ export declare class AgentBuilder {
|
|
|
33
30
|
use(middleware: StepMiddleware): this;
|
|
34
31
|
use(id: string, middleware: StepMiddleware): this;
|
|
35
32
|
use<State>(declaration: CapabilityDeclaration<State>): this;
|
|
36
|
-
|
|
33
|
+
build(): BuiltAgent;
|
|
37
34
|
private nextMiddlewareId;
|
|
38
35
|
private push;
|
|
39
36
|
private assertOpen;
|
|
40
37
|
}
|
|
41
|
-
export declare class BoundAgentBuilder {
|
|
42
|
-
private readonly state;
|
|
43
|
-
constructor(state: BuilderState);
|
|
44
|
-
build(): BuiltAgent;
|
|
45
|
-
}
|
|
46
38
|
export {};
|
package/dist/build/builder.js
CHANGED
|
@@ -30,45 +30,13 @@ export class AgentBuilder {
|
|
|
30
30
|
return this.push(compileDeclaration(idOrMiddleware));
|
|
31
31
|
return this.push({ id: idOrMiddleware, handle: middleware });
|
|
32
32
|
}
|
|
33
|
-
with(onModelCall) {
|
|
34
|
-
this.assertOpen("with()");
|
|
35
|
-
this.state.bound = true;
|
|
36
|
-
this.state.invoke = onModelCall;
|
|
37
|
-
return new BoundAgentBuilder(this.state);
|
|
38
|
-
}
|
|
39
|
-
nextMiddlewareId() {
|
|
40
|
-
const taken = new Set(this.state.middleware.map((item) => item.id));
|
|
41
|
-
let id;
|
|
42
|
-
do {
|
|
43
|
-
this.state.middlewareSeq += 1;
|
|
44
|
-
id = `middleware-${this.state.middlewareSeq}`;
|
|
45
|
-
} while (taken.has(id));
|
|
46
|
-
return id;
|
|
47
|
-
}
|
|
48
|
-
push(entry) {
|
|
49
|
-
this.assertOpen("build()");
|
|
50
|
-
this.state.middleware.push(entry);
|
|
51
|
-
return this;
|
|
52
|
-
}
|
|
53
|
-
assertOpen(after) {
|
|
54
|
-
if (this.state.bound)
|
|
55
|
-
throw new AgentLifecycleError("AgentBuilder cannot be changed after with()");
|
|
56
|
-
if (this.state.sealed)
|
|
57
|
-
throw new AgentLifecycleError(`AgentBuilder cannot be changed after ${after}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
export class BoundAgentBuilder {
|
|
61
|
-
state;
|
|
62
|
-
constructor(state) {
|
|
63
|
-
this.state = state;
|
|
64
|
-
}
|
|
65
33
|
build() {
|
|
66
34
|
if (this.state.agent)
|
|
67
35
|
return this.state.agent;
|
|
68
36
|
if (this.state.error)
|
|
69
37
|
throw this.state.error;
|
|
70
38
|
this.state.sealed = true;
|
|
71
|
-
const result = assembleAgent(this.state.middleware,
|
|
39
|
+
const result = assembleAgent(this.state.middleware, {
|
|
72
40
|
id: this.state.id,
|
|
73
41
|
name: this.state.name,
|
|
74
42
|
});
|
|
@@ -79,6 +47,24 @@ export class BoundAgentBuilder {
|
|
|
79
47
|
this.state.agent = result.agent;
|
|
80
48
|
return this.state.agent;
|
|
81
49
|
}
|
|
50
|
+
nextMiddlewareId() {
|
|
51
|
+
const taken = new Set(this.state.middleware.map((item) => item.id));
|
|
52
|
+
let id;
|
|
53
|
+
do {
|
|
54
|
+
this.state.middlewareSeq += 1;
|
|
55
|
+
id = `middleware-${this.state.middlewareSeq}`;
|
|
56
|
+
} while (taken.has(id));
|
|
57
|
+
return id;
|
|
58
|
+
}
|
|
59
|
+
push(entry) {
|
|
60
|
+
this.assertOpen();
|
|
61
|
+
this.state.middleware.push(entry);
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
assertOpen() {
|
|
65
|
+
if (this.state.sealed)
|
|
66
|
+
throw new AgentLifecycleError("AgentBuilder cannot be changed after build()");
|
|
67
|
+
}
|
|
82
68
|
}
|
|
83
69
|
function createState(options) {
|
|
84
70
|
const middleware = [];
|
|
@@ -90,7 +76,6 @@ function createState(options) {
|
|
|
90
76
|
id: options.id,
|
|
91
77
|
name: options.name,
|
|
92
78
|
middleware,
|
|
93
|
-
bound: false,
|
|
94
79
|
sealed: false,
|
|
95
80
|
middlewareSeq: 0,
|
|
96
81
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Agent, AgentBuilder, AgentBuildError, AgentLifecycleError
|
|
1
|
+
export { Agent, AgentBuilder, AgentBuildError, AgentLifecycleError } from "./build/builder.js";
|
|
2
2
|
export type { AgentOptions } from "./build/builder.js";
|
|
3
3
|
export { HarnessError, isHarnessError } from "./errors.js";
|
|
4
4
|
export type { HarnessErrorCode, HarnessErrorDetails, HarnessErrorOptions } from "./errors.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Agent, AgentBuilder, AgentBuildError, AgentLifecycleError
|
|
1
|
+
export { Agent, AgentBuilder, AgentBuildError, AgentLifecycleError } from "./build/builder.js";
|
|
2
2
|
export { HarnessError, isHarnessError } from "./errors.js";
|
|
3
3
|
export { BuiltAgent } from "./build/agent.js";
|
|
4
4
|
export { middleware, model, tool } from "./build/helpers.js";
|
|
@@ -23,7 +23,6 @@ export declare class SessionScheduler {
|
|
|
23
23
|
private generation;
|
|
24
24
|
private stopPromise?;
|
|
25
25
|
private recordFailure?;
|
|
26
|
-
private readonly observers;
|
|
27
26
|
private readonly turns;
|
|
28
27
|
private readonly states;
|
|
29
28
|
constructor(id: string, agent: LoopAgent, session: Readonly<{
|
|
@@ -32,11 +31,12 @@ export declare class SessionScheduler {
|
|
|
32
31
|
}>, options?: {
|
|
33
32
|
readonly seed?: NormalizedSessionSeed;
|
|
34
33
|
readonly recorder?: SessionRecorder;
|
|
34
|
+
readonly observer?: Observer;
|
|
35
35
|
});
|
|
36
36
|
private readonly session;
|
|
37
37
|
private readonly recorder?;
|
|
38
|
+
private readonly observer?;
|
|
38
39
|
get snapshot(): SessionSnapshot;
|
|
39
|
-
observe(listener: Observer): () => void;
|
|
40
40
|
submit(event: InputEvent, options?: InputOptions): SubmissionStream;
|
|
41
41
|
continue(options?: InputOptions): SubmissionStream;
|
|
42
42
|
private submitWork;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HarnessError } from "../errors.js";
|
|
2
2
|
import { createId } from "../utils/ids.js";
|
|
3
|
-
import {
|
|
3
|
+
import { emitObserve } from "../utils/observe.js";
|
|
4
4
|
import { InputQueue, isInteractionReply, snapshotWork, watchInputAbort, } from "./input-queue.js";
|
|
5
5
|
import { SessionEventLog } from "./event-log.js";
|
|
6
6
|
import { SubmissionStream } from "./submission-stream.js";
|
|
@@ -28,7 +28,6 @@ export class SessionScheduler {
|
|
|
28
28
|
generation = 0;
|
|
29
29
|
stopPromise;
|
|
30
30
|
recordFailure;
|
|
31
|
-
observers = createObserverRegistry();
|
|
32
31
|
turns;
|
|
33
32
|
states;
|
|
34
33
|
constructor(id, agent, session, options = {}) {
|
|
@@ -37,6 +36,7 @@ export class SessionScheduler {
|
|
|
37
36
|
this.turns = new TurnRunner(agent, id, session);
|
|
38
37
|
this.session = session;
|
|
39
38
|
this.recorder = options.recorder;
|
|
39
|
+
this.observer = options.observer;
|
|
40
40
|
this.states = new CapabilityStateRegistry(agent.middleware, Object.freeze({ id, ...session }), (event) => this.emitObserve(event));
|
|
41
41
|
if (options.seed) {
|
|
42
42
|
const event = Object.freeze({
|
|
@@ -44,24 +44,15 @@ export class SessionScheduler {
|
|
|
44
44
|
revision: options.seed.revision,
|
|
45
45
|
transcriptEntries: options.seed.transcript.length,
|
|
46
46
|
});
|
|
47
|
-
|
|
48
|
-
// by one microtask so callers can subscribe immediately after run({ seed }).
|
|
49
|
-
queueMicrotask(() => {
|
|
50
|
-
if (!this.stopped)
|
|
51
|
-
this.emitObserve(event);
|
|
52
|
-
});
|
|
47
|
+
this.emitObserve(event);
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
50
|
session;
|
|
56
51
|
recorder;
|
|
52
|
+
observer;
|
|
57
53
|
get snapshot() {
|
|
58
54
|
return this.snapshotValue;
|
|
59
55
|
}
|
|
60
|
-
observe(listener) {
|
|
61
|
-
if (this.stopped)
|
|
62
|
-
return () => undefined;
|
|
63
|
-
return this.observers.observe(listener);
|
|
64
|
-
}
|
|
65
56
|
submit(event, options) {
|
|
66
57
|
return this.submitWork(event, options);
|
|
67
58
|
}
|
|
@@ -130,7 +121,6 @@ export class SessionScheduler {
|
|
|
130
121
|
}
|
|
131
122
|
this.emitObserve({ type: "session.stopped", reason });
|
|
132
123
|
await this.states.shutdown(stopError);
|
|
133
|
-
this.observers.clear();
|
|
134
124
|
})();
|
|
135
125
|
return this.stopPromise;
|
|
136
126
|
}
|
|
@@ -377,7 +367,7 @@ export class SessionScheduler {
|
|
|
377
367
|
}
|
|
378
368
|
}
|
|
379
369
|
emitObserve(event) {
|
|
380
|
-
this.
|
|
370
|
+
emitObserve(this.observer, event);
|
|
381
371
|
}
|
|
382
372
|
async commitCancelledPlan(pending, reason) {
|
|
383
373
|
this.snapshotValue = await this.commit(commitToolResults(this.snapshotValue, pending.turnId, pending.stepId, pending.plan.cancelledResults(reason)), "tool-results");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { InputHandle, InputOptions, MessageInput, Session, SessionEvent, SessionRunOptions, SessionSnapshot, SessionInput } from "../types/session.js";
|
|
2
2
|
import type { ToolSchemaSource } from "../types/tool.js";
|
|
3
|
-
import type { JsonValue
|
|
3
|
+
import type { JsonValue } from "../types/shared.js";
|
|
4
4
|
import type { LoopAgent } from "../build/agent.js";
|
|
5
5
|
export declare class LiveSession implements Session {
|
|
6
6
|
readonly id: string;
|
|
@@ -13,6 +13,5 @@ export declare class LiveSession implements Session {
|
|
|
13
13
|
interrupt(event: MessageInput, options?: InputOptions): InputHandle<any>;
|
|
14
14
|
continue(options?: InputOptions): InputHandle<any>;
|
|
15
15
|
stream(): AsyncIterable<SessionEvent<JsonValue>>;
|
|
16
|
-
observe(listener: Observer): () => void;
|
|
17
16
|
stop(reason?: string): Promise<void>;
|
|
18
17
|
}
|
package/dist/session/session.js
CHANGED
|
@@ -20,6 +20,7 @@ export class LiveSession {
|
|
|
20
20
|
this.scheduler = new SessionScheduler(id, agent, session, {
|
|
21
21
|
...(seed === undefined ? {} : { seed }),
|
|
22
22
|
...(options.recorder === undefined ? {} : { recorder: options.recorder }),
|
|
23
|
+
...(options.observer === undefined ? {} : { observer: options.observer }),
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
26
|
get state() {
|
|
@@ -43,9 +44,6 @@ export class LiveSession {
|
|
|
43
44
|
stream() {
|
|
44
45
|
return this.scheduler.events;
|
|
45
46
|
}
|
|
46
|
-
observe(listener) {
|
|
47
|
-
return this.scheduler.observe(listener);
|
|
48
|
-
}
|
|
49
47
|
stop(reason) {
|
|
50
48
|
return this.scheduler.stop(reason);
|
|
51
49
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ObserveEmit } from "../utils/observe.js";
|
|
2
|
+
import type { ModelAdapter } from "../types/model.js";
|
|
2
3
|
import type { InputEvent } from "../types/session.js";
|
|
3
4
|
import type { ActiveInteractionExecutionRecord, ActiveToolsExecutionRecord } from "../types/session.js";
|
|
4
5
|
import type { RequiredInteraction, ToolExecutionResume, ToolResult } from "../types/tool.js";
|
|
@@ -33,6 +34,7 @@ export interface ToolPlanRunContext {
|
|
|
33
34
|
readonly stepId: string;
|
|
34
35
|
};
|
|
35
36
|
readonly states?: CapabilityStateRegistry;
|
|
37
|
+
readonly onModelCall: ModelAdapter;
|
|
36
38
|
}
|
|
37
39
|
/** Owns one sealed plan's deterministic interaction and concurrent execution progress. */
|
|
38
40
|
export declare class ToolPlanRunner {
|
package/dist/turn/plan-runner.js
CHANGED
|
@@ -179,6 +179,7 @@ export class ToolPlanRunner {
|
|
|
179
179
|
callId: entry.call.callId,
|
|
180
180
|
invocationId: entry.invocationId,
|
|
181
181
|
signal: context.signal,
|
|
182
|
+
onModelCall: context.onModelCall,
|
|
182
183
|
resume: this.takeResume(entry.call.callId),
|
|
183
184
|
};
|
|
184
185
|
if (context.states?.has(entry.owner.middlewareId))
|
package/dist/turn/runner.js
CHANGED
|
@@ -150,6 +150,7 @@ export class TurnRunner {
|
|
|
150
150
|
observe: context.observe,
|
|
151
151
|
ids: { sessionId: this.sessionId, turnId: pending.turnId, stepId: pending.stepId },
|
|
152
152
|
states: context.states,
|
|
153
|
+
onModelCall: this.agent.invoke,
|
|
153
154
|
}, resume);
|
|
154
155
|
context.assertCurrent();
|
|
155
156
|
context.onPlanActive(undefined);
|
package/dist/types/session.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModelCall, ModelCandidate } from "./model.js";
|
|
1
|
+
import type { ModelAdapter, ModelCall, ModelCandidate } from "./model.js";
|
|
2
2
|
import type { JsonObject, JsonValue, Observer, Tripwire } from "./shared.js";
|
|
3
3
|
import type { RequiredInteraction, SchemaOutput, ToolExecutionResume, ToolOwner, ToolResult, ToolSchemaSource } from "./tool.js";
|
|
4
4
|
export type InputEvent = {
|
|
@@ -70,11 +70,13 @@ export interface InputHandle<Output = string> {
|
|
|
70
70
|
readonly completed: Promise<InputCompletion<Output>>;
|
|
71
71
|
}
|
|
72
72
|
export interface SessionOptions {
|
|
73
|
+
readonly onModelCall: ModelAdapter;
|
|
73
74
|
readonly id?: string;
|
|
74
75
|
readonly userId?: string;
|
|
75
76
|
readonly context?: JsonObject;
|
|
76
77
|
readonly seed?: never;
|
|
77
78
|
readonly recorder?: SessionRecorder;
|
|
79
|
+
readonly observer?: Observer;
|
|
78
80
|
}
|
|
79
81
|
/** Stable host-owned facts available while a capability creates session-local state. */
|
|
80
82
|
export interface SessionIdentity {
|
|
@@ -83,8 +85,10 @@ export interface SessionIdentity {
|
|
|
83
85
|
readonly context?: JsonObject;
|
|
84
86
|
}
|
|
85
87
|
export interface SeededSessionOptions {
|
|
88
|
+
readonly onModelCall: ModelAdapter;
|
|
86
89
|
readonly seed: SessionSeed;
|
|
87
90
|
readonly recorder?: SessionRecorder;
|
|
91
|
+
readonly observer?: Observer;
|
|
88
92
|
readonly id?: never;
|
|
89
93
|
readonly userId?: never;
|
|
90
94
|
readonly context?: never;
|
|
@@ -222,6 +226,5 @@ export interface Session {
|
|
|
222
226
|
interrupt(event: MessageInput, options?: InputOptions): InputHandle;
|
|
223
227
|
continue(options?: InputOptions): InputHandle;
|
|
224
228
|
stream(): AsyncIterable<SessionEvent<JsonValue>>;
|
|
225
|
-
observe(listener: Observer): () => void;
|
|
226
229
|
stop(reason?: string): Promise<void>;
|
|
227
230
|
}
|
package/dist/types/tool.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ZodType } from "zod";
|
|
2
2
|
import type { DeferredOutcome, JsonObject, JsonValue } from "./shared.js";
|
|
3
|
+
import type { ModelAdapter } from "./model.js";
|
|
3
4
|
export interface SchemaIssue {
|
|
4
5
|
readonly path: readonly (string | number)[];
|
|
5
6
|
readonly code: string;
|
|
@@ -90,6 +91,8 @@ interface ToolExecutionContextBase {
|
|
|
90
91
|
readonly callId: string;
|
|
91
92
|
readonly invocationId: string;
|
|
92
93
|
readonly signal: AbortSignal;
|
|
94
|
+
/** The session's model callable, for tools that explicitly run a child agent. */
|
|
95
|
+
readonly onModelCall?: ModelAdapter;
|
|
93
96
|
readonly resume?: ToolExecutionResume;
|
|
94
97
|
}
|
|
95
98
|
export type ToolExecutionContext<State = never> = ToolExecutionContextBase & ([State] extends [never] ? object : {
|
package/dist/utils/observe.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
import type { ObserveEvent, Observer } from "../types/shared.js";
|
|
2
2
|
export type ObserveEmit = (event: ObserveEvent | (() => ObserveEvent)) => void;
|
|
3
|
-
export
|
|
4
|
-
observe(listener: Observer): () => void;
|
|
5
|
-
emit(event: ObserveEvent | (() => ObserveEvent)): void;
|
|
6
|
-
clear(): void;
|
|
7
|
-
}
|
|
8
|
-
export declare function createObserverRegistry(): ObserverRegistry;
|
|
3
|
+
export declare function emitObserve(listener: Observer | undefined, event: ObserveEvent | (() => ObserveEvent)): void;
|
package/dist/utils/observe.js
CHANGED
|
@@ -1,29 +1,13 @@
|
|
|
1
|
-
export function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for (const listener of [...listeners]) {
|
|
14
|
-
try {
|
|
15
|
-
const result = listener(snapshot);
|
|
16
|
-
if (result && typeof result.then === "function") {
|
|
17
|
-
void Promise.resolve(result).catch(() => undefined);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
// Observation is deliberately fail-open.
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
clear() {
|
|
26
|
-
listeners.clear();
|
|
27
|
-
},
|
|
28
|
-
};
|
|
1
|
+
export function emitObserve(listener, event) {
|
|
2
|
+
if (!listener)
|
|
3
|
+
return;
|
|
4
|
+
const snapshot = Object.freeze({ ...(typeof event === "function" ? event() : event) });
|
|
5
|
+
try {
|
|
6
|
+
const result = listener(snapshot);
|
|
7
|
+
if (result && typeof result.then === "function")
|
|
8
|
+
void Promise.resolve(result).catch(() => undefined);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
// Observation is deliberately fail-open.
|
|
12
|
+
}
|
|
29
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0-beta",
|
|
4
4
|
"description": "Nylorun's TypeScript agent runtime. See github.com/nylorun/harness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"prepack": "npm run build"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^
|
|
62
|
+
"@types/node": "^26.5.0",
|
|
63
63
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
64
64
|
"prettier": "^3.9.6",
|
|
65
65
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
66
|
-
"vitest": "^
|
|
66
|
+
"vitest": "^5.0.0",
|
|
67
67
|
"zod": "^4.1.12"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|