@nylorun/harness 0.13.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.
- package/CHANGELOG.md +48 -0
- package/HOST_CONTRACT.md +27 -0
- package/README.md +62 -100
- package/dist/compatibility.d.ts +3 -0
- package/dist/compatibility.js +3 -0
- package/dist/definition/agent-definition.d.ts +11 -3
- package/dist/definition/agent-definition.js +18 -10
- package/dist/definition/compatibility.d.ts +11 -0
- package/dist/definition/compatibility.js +30 -0
- package/dist/definition/registry.d.ts +2 -2
- package/dist/definition/registry.js +7 -6
- package/dist/index.d.ts +4 -18
- package/dist/index.js +1 -6
- package/dist/loop/dispatch.js +327 -0
- package/dist/loop/host-suspension.d.ts +6 -0
- package/dist/loop/host-suspension.js +10 -0
- package/dist/loop/initial-state.d.ts +13 -0
- package/dist/loop/initial-state.js +30 -0
- package/dist/{execution → loop}/invocation.d.ts +5 -2
- package/dist/{execution → loop}/invocation.js +8 -3
- package/dist/{execution → loop}/model/adapters.d.ts +4 -2
- package/dist/{execution → loop}/model/adapters.js +3 -2
- package/dist/{execution → loop}/model/normalize.d.ts +2 -2
- package/dist/{execution → loop}/model/normalize.js +2 -2
- package/dist/{execution → loop}/model/prepared.d.ts +2 -2
- package/dist/{execution → loop}/model/project.d.ts +1 -1
- package/dist/{execution → loop}/model/project.js +1 -1
- package/dist/{execution → loop}/observe.d.ts +2 -2
- package/dist/{execution → loop}/observe.js +1 -1
- package/dist/{execution → loop}/options.d.ts +2 -1
- package/dist/{execution → loop}/options.js +28 -8
- package/dist/{execution → loop}/resume.d.ts +1 -1
- package/dist/{execution → loop}/resume.js +2 -2
- package/dist/{execution → loop}/run.d.ts +1 -1
- package/dist/{execution → loop}/run.js +9 -1
- package/dist/{execution → loop}/state.d.ts +2 -2
- package/dist/{execution → loop}/state.js +13 -3
- package/dist/{execution → loop}/step/canonicalize.d.ts +2 -2
- package/dist/{execution → loop}/step/canonicalize.js +1 -1
- package/dist/{execution → loop}/step/compose.d.ts +2 -2
- package/dist/{execution → loop}/step/compose.js +4 -1
- package/dist/{execution → loop}/step/context-draft.d.ts +2 -2
- package/dist/{execution → loop}/step/context-draft.js +2 -2
- package/dist/{execution → loop}/step/describe.d.ts +3 -3
- package/dist/{execution → loop}/step/describe.js +1 -1
- package/dist/loop/step/dynamics.d.ts +29 -0
- package/dist/loop/step/dynamics.js +147 -0
- package/dist/{execution → loop}/step/model-configuration.d.ts +2 -2
- package/dist/{execution → loop}/step/model-configuration.js +3 -3
- package/dist/{execution → loop}/step/resolve.d.ts +4 -4
- package/dist/{execution → loop}/step/run.d.ts +5 -4
- package/dist/{execution → loop}/step/run.js +87 -2
- package/dist/{execution → loop}/step/runtime.d.ts +12 -4
- package/dist/{execution → loop}/step/seal.d.ts +5 -5
- package/dist/{execution → loop}/step/seal.js +2 -2
- package/dist/{execution → loop}/step/slot-assembly.d.ts +1 -1
- package/dist/{execution → loop}/step/slot-assembly.js +1 -1
- package/dist/{execution → loop}/step/step-context.d.ts +5 -5
- package/dist/{execution → loop}/step/step-context.js +2 -2
- package/dist/{execution → loop}/tool-result.d.ts +2 -2
- package/dist/{execution → loop}/tool-result.js +2 -2
- package/dist/{execution → loop}/transcript.d.ts +1 -1
- package/dist/{execution → loop}/transcript.js +2 -2
- package/dist/loop/waits.d.ts +50 -0
- package/dist/loop/waits.js +11 -0
- package/dist/run/durable.d.ts +71 -0
- package/dist/run/durable.js +164 -0
- package/dist/run/index.d.ts +33 -0
- package/dist/run/index.js +38 -0
- package/dist/types/client.d.ts +88 -0
- package/dist/types/execution.d.ts +22 -5
- package/dist/utils/ids.d.ts +1 -0
- package/dist/utils/ids.js +11 -1
- package/package.json +18 -6
- package/dist/definition/assemble.d.ts +0 -22
- package/dist/definition/assemble.js +0 -43
- package/dist/definition/bind-agent.d.ts +0 -9
- package/dist/definition/bind-agent.js +0 -21
- package/dist/definition/bind-tool.d.ts +0 -4
- package/dist/definition/bind-tool.js +0 -19
- package/dist/definition/bound.d.ts +0 -16
- package/dist/definition/builder.d.ts +0 -30
- package/dist/definition/builder.js +0 -94
- package/dist/definition/declaration.d.ts +0 -3
- package/dist/definition/declaration.js +0 -53
- package/dist/definition/helpers.d.ts +0 -6
- package/dist/definition/helpers.js +0 -4
- package/dist/definition/manifest.d.ts +0 -9
- package/dist/definition/manifest.js +0 -45
- package/dist/definition/output-contract.d.ts +0 -6
- package/dist/definition/output-contract.js +0 -12
- package/dist/definition/schema.d.ts +0 -14
- package/dist/definition/schema.js +0 -205
- package/dist/errors.d.ts +0 -17
- package/dist/errors.js +0 -17
- package/dist/execution/dispatch.js +0 -164
- package/dist/execution/initial-state.d.ts +0 -3
- package/dist/execution/initial-state.js +0 -14
- package/dist/types/agent.d.ts +0 -9
- package/dist/types/agent.js +0 -1
- package/dist/types/manifest.d.ts +0 -22
- package/dist/types/manifest.js +0 -1
- package/dist/types/middleware.d.ts +0 -66
- package/dist/types/middleware.js +0 -1
- package/dist/types/model.d.ts +0 -184
- package/dist/types/model.js +0 -1
- package/dist/types/observe.d.ts +0 -165
- package/dist/types/observe.js +0 -1
- package/dist/types/shared.d.ts +0 -25
- package/dist/types/shared.js +0 -1
- package/dist/types/tool.d.ts +0 -138
- package/dist/types/tool.js +0 -1
- package/dist/types/transcript.d.ts +0 -65
- package/dist/types/transcript.js +0 -1
- package/dist/utils/canonical.d.ts +0 -1
- package/dist/utils/canonical.js +0 -10
- package/dist/utils/immutable.d.ts +0 -6
- package/dist/utils/immutable.js +0 -76
- /package/dist/{execution → loop}/dispatch.d.ts +0 -0
- /package/dist/{execution → loop}/model/prepared.js +0 -0
- /package/dist/{execution → loop}/step/resolve.js +0 -0
- /package/dist/{execution → loop}/step/runtime.js +0 -0
- /package/dist/{definition/bound.js → types/client.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.0-beta
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2898d02: Extract shared definitions and contracts into core and local orchestration into
|
|
8
|
+
CLI. Harness becomes execution-only; the SDK no longer installs the engine and
|
|
9
|
+
Runtime no longer depends on the SDK. Author applications through agents and
|
|
10
|
+
install cli for the unchanged nylorun commands. See the package architecture and
|
|
11
|
+
migration guide. Cloud installs published packages from npm independently.
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 41e613c: Ship the local SDK registry workflow with an independent SQLite Runtime, connected tool executor, authenticated Studio proxy, and a text-and-tool starter. Replace the legacy Hono starter and AG-UI transport. Require Node 24 and include the SDK in exact release compatibility pins.
|
|
16
|
+
|
|
17
|
+
Break the Harness execution import from `/engine` to `/run` and rename hosted execution APIs to durable execution APIs, including RunBinding, BoundRunOptions, and createRunState. Update all consumers without compatibility aliases; retain persisted checkpoint fields and version pins.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Pin core to the tested release.
|
|
22
|
+
- Updated dependencies [2898d02]
|
|
23
|
+
- @nylorun/core@0.1.1-beta
|
|
24
|
+
|
|
25
|
+
## Unreleased
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- Breaking beta: replace `/engine` with `/run`; rename hosted execution to durable execution.
|
|
30
|
+
Use `runDurable`, `createDurableCheckpoint`, `DurableCheckpoint`, `DurableResult`,
|
|
31
|
+
`DurableHost`, `RunBinding`, `BoundRunOptions`, and `createRunState`. No aliases remain.
|
|
32
|
+
Persisted checkpoint fields and the `hosted-1` compatibility pin are unchanged.
|
|
33
|
+
|
|
34
|
+
- Breaking beta: the package root is now an alias of `/define`. Import
|
|
35
|
+
`createExecutionState` / `validateExecutionState` from `@nylorun/harness/run` and
|
|
36
|
+
`preparedModel` from `@nylorun/harness/model/adapters`. Authoring and wire-contract specifiers remain unchanged.
|
|
37
|
+
- Internal source folder `execution/` is now `loop/` (one `run()` invocation). The
|
|
38
|
+
`/model/adapters` specifier is unchanged.
|
|
39
|
+
- DX v5.6: Agent usable without `.build()`; `.use()` returns a new agent; top-level `tools` /
|
|
40
|
+
`instructions` (no `model` on `Agent({})`). `tool()` accepts `input` / `output` / `run`; plain
|
|
41
|
+
returns complete; export `ToolError`; tool `approval` / `effects`; `ctx.idempotencyKey`,
|
|
42
|
+
`redelivery`, `state`, `session`, `progress`, and durable waits (`ask` / `approve` / `sleep` /
|
|
43
|
+
`waitFor` / `step`).
|
|
44
|
+
- Agent-as-JSON: versioned manifest (`schemaVersion: 2`), `toJSON` / `Agent.from`, `hashManifest`,
|
|
45
|
+
`checkCompatibility`; identity by manifest hash (not WeakMap-only). Session memory on
|
|
46
|
+
`ExecutionState.state`. Capability `model` is no longer projected into the published manifest.
|
|
47
|
+
- Dynamics: `beforeModelCall` / `afterModelCall` with `Patch` / `Decision`; middleware deprecated
|
|
48
|
+
but kept through 1.0. Export `@nylorun/harness/run` for run-from-checkpoint; `agent.run` is a
|
|
49
|
+
1.0 alias. Export type-only `Session` / `Turn` / `Event` / `Result`.
|
|
50
|
+
|
|
3
51
|
## 0.13.0-beta
|
|
4
52
|
|
|
5
53
|
### Minor Changes
|
package/HOST_CONTRACT.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Durable execution and session protocol — beta freeze
|
|
2
|
+
|
|
3
|
+
Artifact: `@nylorun/harness@0.14.0-beta.3`. Package version is separate from protocol 1, definition schema 2, durable checkpoint 1 / engine `hosted-1`, and inner execution checkpoint 1. Public execution API and shared contracts are the compatibility boundary. Cloud installs published npm packages and does not import the OSS Runtime.
|
|
4
|
+
|
|
5
|
+
## HTTP (both hosts)
|
|
6
|
+
|
|
7
|
+
Bearer application credentials: `PUT /v1/agents/:agentId` (`PutAgentRequest`: requestId, complete manifest, implementationVersion); `PUT /v1/sessions/:sessionId` (`PutSessionRequest`: requestId, agentId, trusted ownerUserId, optional info); `GET /v1/sessions/:sessionId`; `POST /v1/sessions/:sessionId/commands`; `GET /v1/sessions/:sessionId/items?cursor=...`; `GET /v1/sessions/:sessionId/events?cursor=...` (SSE, Last-Event-ID also accepted). Commands use `SessionCommandSchema`. Message input is `content`, not text. Runtime configuration selects models; saved definitions do not. Session creation pins manifest hash and implementation version. GET session returns id, agentId, ownerUserId, status, activeTurnId, plus inspectable waits/uncertainty as available. History returns `{items: LiveEvent[], cursor: string|null}`; empty history cursor is null.
|
|
8
|
+
|
|
9
|
+
Separate scoped executor bearer credentials: `GET /v1/executors/connect` emits `event: work_available` / `data: {"type":"work_available"}` after connection and committed work; `GET /v1/actions` returns `{actions: Action[]}`; `POST /v1/actions/:actionId/claim` uses ActionClaimRequest; `POST /v1/actions/:actionId/heartbeat` uses ActionHeartbeatRequest and returns leaseExpiresAt. Claim returns ActionClaim. Action result is the `action_result` session command with executor authorization, never observer authorization. Claim identity is server-generated and generation monotonically increases. Credentials limit agentId, manifestHash, and implementationVersion; clients cannot broaden their scope. Subscribe before discovery; rediscover after reconnect; notifications never authorize execution.
|
|
10
|
+
|
|
11
|
+
All command idempotency keys bind to canonical request content within a session; requestId is transport metadata and is excluded from content comparison; exact semantic duplicates return the stored original response; changed content conflicts (409). A completed action's matching claim/generation/outcome returns its original receipt even after expiry. Conflicting duplicates and any other stale/expired claim are rejected. Heartbeat cannot resurrect an expired claim. Expired in-flight customer work is uncertain, not automatically reoffered. Results after cancellation cannot resume a turn. Application observers cannot claim or submit action results. No hardcoded production credentials.
|
|
12
|
+
|
|
13
|
+
## Engine host
|
|
14
|
+
|
|
15
|
+
`createDurableCheckpoint({manifest,sessionId,turnId,input,state?,info?,segment?})`, `runDurable({manifest,checkpoint,host,signal?})` from `/run`. `DurableHost.resolveEffect(HostEffect)` atomically creates or reads an individually identified effect and returns `{status:'completed',outcome:{value,statePatch?}}` or `{status:'pending'|'uncertain'}`. Model effect `input` is the complete ModelCall (instructions/history/tools/output schema); context contains a JSON projection of ModelRequest and invocationId. Its completed value is a ModelCandidate or string. Runtime provider code owns credentials and invocation. Tools/hooks have capabilityId, toolName for tools, serialized input and context. Tool result value is a ToolOutcome or a plain tool output; statePatch contains changed session keys. Before/after hook values are Patch/Decision. Tool context includes invocationId, resume, state, info and stable idempotencyKey. Customer implementationVersion is pinned by the runtime outside durable checkpoints.
|
|
16
|
+
|
|
17
|
+
Persist checkpoint BEFORE scheduling, effect intent BEFORE provider invocation or notification, and outcome BEFORE resumption. Journaling an entire runDurable call as one replayable operation is forbidden. The durable path deterministically reconstructs a segment from its immutable starting checkpoint and individually cached effect outcomes. A waiting result returns that starting checkpoint: do not replace it with an intermediate preview. The journal is required continuation data and must be retained with the checkpoint. Stable IDs include turn/segment and deterministic invocation identity. There is no live continuation or request-held promise while waiting. Runtimes serialize work per session, check cancellation before effects and before settlement, and fence ownership. Lost provider acknowledgement becomes uncertain; do not repeat it merely because a worker restarts.
|
|
18
|
+
|
|
19
|
+
A terminal/paused result includes `result.state`. Save it. A new message uses a new turnId with prior completed state. Approval/response resumes paused state via a new checkpoint, same turnId, `segment + 1`, with `{kind:'approve',interactionId,approved}` or `{kind:'respond',interactionId,value}`. An action result simply reruns the SAME suspended checkpoint/segment after recording the outcome. Paused plan records pending interactions/deferred calls; waiting on remote action is distinct from a human wait. Cancellation is host-owned and must fence both running and pending work. Runtime supplies canonical events; execution observations are not wire events and reconstruction must not republish duplicate history.
|
|
20
|
+
|
|
21
|
+
Host resolveEffect must bind the effect ID to the original request and reject drift. Intent/outcome, action transitions, checkpoint settlement and canonical event/outbox writes must use runtime transactions. Restate journals individual effect boundaries, not the loop. Scheduling, storage, publication, lease policy and reconciliation remain runtime-owned.
|
|
22
|
+
|
|
23
|
+
## Definitions, validation, compatibility
|
|
24
|
+
|
|
25
|
+
`/define` is execution-free and browser-bundleable; Agent has no `.run()`. Explicit local execution uses `/run` run + bindingFromAgent(agent.build()). `/contracts` never imports checkpoint internals. Tools and before/after hooks are supported remotely. Arbitrary legacy middleware closures are rejected for durable definitions because they cannot be reconstructed from manifests. JSON schemas are reconstructed through Zod's JSON Schema importer; unsupported schemas fail closed. The original manifest hash must survive reconstruction. Model configuration is host-owned. The executor validates its local manifest hash and implementationVersion before claiming and validates tool inputs/outputs locally.
|
|
26
|
+
|
|
27
|
+
No session migration, arbitrary checkpoint migration, broad model-support, or conformance claims follow from compiling this interface. Studio and conformance tooling remain outside production harness.
|
package/README.md
CHANGED
|
@@ -1,129 +1,91 @@
|
|
|
1
1
|
# `@nylorun/harness`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Execution engine, checkpoints and durable host effects. Shared authoring and wire
|
|
4
|
+
contracts live in `@nylorun/core`; applications use `@nylorun/agents`.
|
|
5
|
+
OSS publishes harness for local Runtime; Cloud installs published packages from
|
|
6
|
+
npm independently. See the
|
|
7
|
+
[package architecture](../docs/design/package-architecture.md).
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
Use `/run` for explicit execution, `/model/adapters` for provider format adapters,
|
|
10
|
+
and `/compatibility` for checkpoint compatibility. Definitions and protocol
|
|
11
|
+
schemas are no longer harness exports.
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
> **DX v5.6:** definition ⊥ engine. `model` is not on `Agent({})` — Runtime injects `onModelCall`. Host data stays `info` (not `user`); session memory is `state`.
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
import { Agent } from "@nylorun/harness";
|
|
15
|
+
## Compose an agent
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
onModelCall: async (call) => "Hello back!", // Your model adapter
|
|
16
|
-
});
|
|
17
|
-
if (result.status === "completed") console.log(result.output);
|
|
17
|
+
```ts
|
|
18
|
+
import { Agent, tool, ToolError, capability } from "@nylorun/agents/define";
|
|
19
|
+
import { z } from "zod";
|
|
18
20
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
input:
|
|
22
|
-
|
|
21
|
+
const lookup = tool({
|
|
22
|
+
name: "lookup_order",
|
|
23
|
+
input: z.object({ orderId: z.string() }),
|
|
24
|
+
effects: "read",
|
|
25
|
+
async run({ orderId }, ctx) {
|
|
26
|
+
const order = await orders.find(orderId, { info: ctx.info, signal: ctx.signal });
|
|
27
|
+
if (!order) throw new ToolError("not_found", "No such order.");
|
|
28
|
+
return order; // plain return = completed
|
|
29
|
+
},
|
|
23
30
|
});
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Every call returns a Promise. Omitted state starts an empty execution. The built agent retains definitions, not progress; supplied state is never mutated. Multiple calls may use the same agent concurrently. Applications must coordinate concurrent updates to the same conversation.
|
|
27
|
-
|
|
28
|
-
Outcomes are `completed` (with `output`), `paused` (with `pending`), `cancelled`, or `failed` (with `error`). Each includes serializable `state`. Invalid options, incompatible state, and invalid continuation inputs reject before model/tool execution. Operational failures return `failed`. Recording failures reject.
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
export const supportAgent = Agent({
|
|
33
|
+
id: "support",
|
|
34
|
+
name: "Support",
|
|
35
|
+
instructions: "You help customers with orders. Be brief.",
|
|
36
|
+
tools: [lookup],
|
|
37
|
+
})
|
|
38
|
+
.use(capability({ id: "policy", afterModelCall: ({ text }) => ({}) }))
|
|
39
|
+
.beforeModelCall(({ info, state }) => ({ instructions: [`Tenant ${info?.tenantId}`] }));
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
// Optional: .build() is a no-op facade
|
|
42
|
+
const agent = supportAgent.build();
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Model adapters receive immutable `ToolDescriptor` values in `context.request.tools` and `context.request.configuration.tools`. Descriptors preserve `name`, optional `description`, `owner`, `inputSchema.jsonSchema`, and optional `outputSchema.jsonSchema`. They contain no executable tool, original definition, or validator. Implement tools through registered capabilities; adapters return tool-call candidates for Harness to validate and dispatch.
|
|
37
|
-
|
|
38
|
-
## Optional controls
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
const result = await agent.run({
|
|
42
|
-
state,
|
|
43
|
-
input,
|
|
44
|
-
onModelCall,
|
|
45
|
-
info: { userId, tenantId },
|
|
46
|
-
signal: controller.signal,
|
|
47
|
-
onEvent: (event) => console.log(event),
|
|
48
|
-
record: (state) => sessionStore.save(sessionId, state),
|
|
49
|
-
});
|
|
44
|
+
JSON.stringify(supportAgent); // manifest
|
|
45
|
+
Agent.from(supportAgent.toJSON(), implementations);
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
`signal` is cooperative: Harness checks before further work, forwards it to adapters and tools, and waits for dispatched work to settle. Cancellation preserves settled results, cannot undo external effects, and cannot forcibly stop an uncooperative dependency. Harness has no cancellation or shutdown method. The developer owns clients, connections, subprocesses, and their cleanup.
|
|
55
|
-
|
|
56
|
-
To cancel a saved pause, call `run({ state, input: { kind: "continue" }, signal: AbortSignal.abort(), onModelCall })`. This settles the pending plan without dispatching it. `state.cancelledCalls` retains unresolved invocation references and deferred tokens for reconciliation, outside the model transcript; cancelling a deferred job does not stop external work by itself. Runtime's `host.cancel(agent, sessionId)` applies this transition and persists it before accepting replacement work.
|
|
48
|
+
`.use()` returns a **new** agent. Top-level `tools` / `instructions` are first-class. Do **not** put `model` on `Agent({})` — Runtime resolves and calls the model.
|
|
57
49
|
|
|
58
|
-
|
|
50
|
+
## Run the loop
|
|
59
51
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
## Final output contracts
|
|
52
|
+
Taught path for hosts/Runtime:
|
|
63
53
|
|
|
64
54
|
```ts
|
|
65
|
-
import {
|
|
66
|
-
const agent = Agent({
|
|
67
|
-
id: "extractor",
|
|
68
|
-
name: "Extractor",
|
|
69
|
-
outputSchema: z.object({ answer: z.string() }),
|
|
70
|
-
}).build();
|
|
71
|
-
// A completed result.output is inferred as { answer: string }.
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
The schema belongs to the agent definition, is supplied to adapters, and validates the accepted final response after middleware. Adapters return a JSON output block for structured results. There is no per-run or per-turn schema override. Tool output schemas remain tool-specific. With an explicitly typed info bag and output schema, use `Agent<MyInfo, typeof schema>({...})`.
|
|
55
|
+
import { run, bindingFromAgent } from "@nylorun/harness/run";
|
|
75
56
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
kind: "completed" as const,
|
|
84
|
-
output: await database.lookup(id, { info, signal }),
|
|
85
|
-
}),
|
|
86
|
-
};
|
|
87
|
-
const agent = Agent({ id: "assistant", name: "Assistant" })
|
|
88
|
-
.use({ id: "database", tools: [lookup] })
|
|
89
|
-
.build();
|
|
57
|
+
const result = await run({
|
|
58
|
+
binding: bindingFromAgent(supportAgent.build()),
|
|
59
|
+
input: "Hello",
|
|
60
|
+
onModelCall: async () => "Hello back!",
|
|
61
|
+
info: { tenantId: "acme" },
|
|
62
|
+
record: (state) => store.save(state),
|
|
63
|
+
});
|
|
90
64
|
```
|
|
91
65
|
|
|
92
|
-
|
|
66
|
+
This is a breaking beta: `agent.run()` has been removed. Application execution uses SDK sessions. Durable execution uses `createDurableCheckpoint` and `runDurable` with individually persisted model/tool/hook effects; a suspended checkpoint requires its effect journal.
|
|
93
67
|
|
|
94
|
-
|
|
68
|
+
## Tools
|
|
95
69
|
|
|
96
|
-
|
|
97
|
-
const queryTable = {
|
|
98
|
-
name: "query_table",
|
|
99
|
-
inputSchema: z.object({ table: z.string(), query: z.string() }),
|
|
100
|
-
execute: async ({ table, query }, { info, signal }) => ({
|
|
101
|
-
kind: "completed" as const,
|
|
102
|
-
output: await warehouse.query({ table, query, principal: info, signal }),
|
|
103
|
-
}),
|
|
104
|
-
};
|
|
105
|
-
```
|
|
70
|
+
Prefer `input` / `output` / `run`. Legacy `inputSchema` / `execute` and tagged `{ kind: "completed" }` outcomes still work.
|
|
106
71
|
|
|
107
|
-
|
|
72
|
+
- `approval` — declarative pause before execute (code-only; not in the manifest)
|
|
73
|
+
- `effects` — `"read" | "idempotent" | "write"` (code-only)
|
|
74
|
+
- `ctx.idempotencyKey`, `ctx.redelivery`, `ctx.state`, `ctx.session`, `ctx.progress`
|
|
75
|
+
- Durable waits: `ctx.ask`, `ctx.approve`, `ctx.sleep`, `ctx.waitFor`, `ctx.step`
|
|
108
76
|
|
|
109
|
-
|
|
77
|
+
Definitions must not import `@nylorun/runtime`.
|
|
110
78
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
onModelCall,
|
|
117
|
-
});
|
|
118
|
-
// A response uses { kind: "respond", interactionId, value }.
|
|
119
|
-
// A deferred settlement uses { kind: "settle", invocationId, outcome:
|
|
120
|
-
// { kind: "completed", output: jobResult } }.
|
|
121
|
-
```
|
|
79
|
+
## Dynamics
|
|
80
|
+
|
|
81
|
+
`beforeModelCall` → `Patch` (capabilities/tools/instructions/state/block — no `model`).
|
|
82
|
+
`afterModelCall` → `Decision` (text/deny/approve/retry/block).
|
|
83
|
+
Local explicit engine execution retains middleware. Durable manifests reject arbitrary middleware closures; use before/after hooks.
|
|
122
84
|
|
|
123
|
-
|
|
85
|
+
## Checkpoint / durability
|
|
124
86
|
|
|
125
|
-
`
|
|
87
|
+
`ExecutionState` is the continuation token (plus `manifestHash`). Runtime persists `record(state)` at durable boundaries and resumes with `continue` / `approve` / `respond` / `settle`. `checkCompatibility(manifest, state)` fails on hash mismatch.
|
|
126
88
|
|
|
127
|
-
|
|
89
|
+
## Client types
|
|
128
90
|
|
|
129
|
-
|
|
91
|
+
The authoritative session/action wire schemas live in `/contracts` and do not import durable checkpoint types. Use `@nylorun/agents` for the session client and SSE executor. Historical root client types remain for deferred local tooling; they are not the new wire contract.
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import type { BoundMiddleware } from "
|
|
1
|
+
import type { BoundMiddleware } from "@nylorun/core/define";
|
|
2
2
|
import type { ToolRegistry } from "./registry.js";
|
|
3
|
-
import type { TurnOutputContract } from "
|
|
3
|
+
import type { TurnOutputContract } from "@nylorun/core/define";
|
|
4
|
+
import type { AgentManifest } from "@nylorun/core/define";
|
|
5
|
+
import type { Implementations } from "@nylorun/core/define";
|
|
4
6
|
export interface AgentDefinition {
|
|
5
7
|
readonly id: string;
|
|
6
8
|
readonly middleware: readonly BoundMiddleware[];
|
|
7
9
|
readonly registry: ToolRegistry;
|
|
8
10
|
readonly output?: TurnOutputContract;
|
|
11
|
+
readonly manifest: AgentManifest;
|
|
12
|
+
readonly hash: string;
|
|
13
|
+
readonly implementations: Implementations;
|
|
9
14
|
}
|
|
10
|
-
export
|
|
15
|
+
export type { Implementations };
|
|
16
|
+
import type { AgentBinding } from "@nylorun/core/define";
|
|
11
17
|
export declare function definitionFor(agent: object): AgentDefinition;
|
|
18
|
+
export declare function definitionFromBinding(binding: AgentBinding): AgentDefinition;
|
|
19
|
+
export declare function tryDefinitionFor(agent: object): AgentDefinition | undefined;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export function registerDefinition(agent, definition) {
|
|
5
|
-
definitions.set(agent, definition);
|
|
6
|
-
}
|
|
1
|
+
import { bindingFromAgent, bindOutputContract } from "@nylorun/core/define";
|
|
2
|
+
import { ToolRegistry as Registry } from "./registry.js";
|
|
3
|
+
import { hashManifest } from "@nylorun/core/compatibility";
|
|
7
4
|
export function definitionFor(agent) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return
|
|
5
|
+
return definitionFromBinding(bindingFromAgent(agent));
|
|
6
|
+
}
|
|
7
|
+
export function definitionFromBinding(binding) {
|
|
8
|
+
return Object.freeze({
|
|
9
|
+
id: binding.manifest.id,
|
|
10
|
+
manifest: binding.manifest,
|
|
11
|
+
hash: hashManifest(binding.manifest),
|
|
12
|
+
middleware: binding.declarations,
|
|
13
|
+
implementations: binding.implementations,
|
|
14
|
+
registry: new Registry(binding.declarations, binding.tools),
|
|
15
|
+
...(binding.outputSchema ? { output: bindOutputContract(binding.outputSchema) } : {}),
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export function tryDefinitionFor(agent) {
|
|
19
|
+
return typeof agent.getBinding === "function" ? definitionFor(agent) : undefined;
|
|
12
20
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HarnessError } from "@nylorun/core/define";
|
|
2
|
+
import type { AgentManifest } from "@nylorun/core/define";
|
|
3
|
+
import type { ExecutionState } from "../types/execution.js";
|
|
4
|
+
export type CompatibilityResult = {
|
|
5
|
+
readonly ok: true;
|
|
6
|
+
} | {
|
|
7
|
+
readonly ok: false;
|
|
8
|
+
readonly error: HarnessError;
|
|
9
|
+
};
|
|
10
|
+
/** Fail loud when a checkpoint was bound to a different definition. */
|
|
11
|
+
export declare function checkCompatibility(manifest: AgentManifest, state: ExecutionState): CompatibilityResult;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HarnessError } from "@nylorun/core/define";
|
|
2
|
+
import { hashManifest } from "@nylorun/core/define";
|
|
3
|
+
/** Fail loud when a checkpoint was bound to a different definition. */
|
|
4
|
+
export function checkCompatibility(manifest, state) {
|
|
5
|
+
const expected = hashManifest(manifest);
|
|
6
|
+
if (state.manifestHash && state.manifestHash !== expected) {
|
|
7
|
+
return {
|
|
8
|
+
ok: false,
|
|
9
|
+
error: new HarnessError("execution.incompatible", "Saved state manifestHash does not match the supplied agent manifest", {
|
|
10
|
+
details: {
|
|
11
|
+
expected: expected.slice(0, 12),
|
|
12
|
+
actual: state.manifestHash.slice(0, 12),
|
|
13
|
+
},
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (state.agentId !== manifest.id) {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
error: new HarnessError("execution.incompatible", "Saved state agentId does not match the supplied agent manifest", { details: { expected: manifest.id, actual: state.agentId } }),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (state.version !== 1) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
error: new HarnessError("execution.incompatible", `Unsupported ExecutionState version ${state.version}`),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { ok: true };
|
|
30
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { BoundMiddleware, BoundToolDefinition } from "
|
|
1
|
+
import type { BoundMiddleware, BoundToolDefinition } from "@nylorun/core/define";
|
|
2
2
|
import type { ToolReference } from "../types/execution.js";
|
|
3
3
|
/** Definition-only lookup; no per-run selections or progress live here. */
|
|
4
4
|
export declare class ToolRegistry {
|
|
5
5
|
private readonly tools;
|
|
6
6
|
private readonly owners;
|
|
7
|
-
constructor(middleware: readonly BoundMiddleware[]);
|
|
7
|
+
constructor(middleware: readonly BoundMiddleware[], snapshots?: readonly BoundToolDefinition[]);
|
|
8
8
|
reference(tool: BoundToolDefinition): ToolReference;
|
|
9
9
|
restore(reference: ToolReference): BoundToolDefinition;
|
|
10
10
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { bindTool } from "
|
|
2
|
-
import { HarnessError } from "
|
|
3
|
-
import { canonical } from "
|
|
4
|
-
import { copyJson } from "
|
|
1
|
+
import { bindTool } from "@nylorun/core/define";
|
|
2
|
+
import { HarnessError } from "@nylorun/core/define";
|
|
3
|
+
import { canonical } from "@nylorun/core/define";
|
|
4
|
+
import { copyJson } from "@nylorun/core/define";
|
|
5
5
|
/** Definition-only lookup; no per-run selections or progress live here. */
|
|
6
6
|
export class ToolRegistry {
|
|
7
7
|
tools = new Map();
|
|
8
8
|
owners = new WeakMap();
|
|
9
|
-
constructor(middleware) {
|
|
9
|
+
constructor(middleware, snapshots) {
|
|
10
10
|
for (const capability of middleware) {
|
|
11
11
|
for (const tool of capability.tools ?? []) {
|
|
12
12
|
const key = JSON.stringify([capability.id, tool.name]);
|
|
13
13
|
if (this.tools.has(key) || this.owners.has(tool))
|
|
14
14
|
throw new HarnessError("tool.invalid", `Duplicate registered tool '${tool.name}' in '${capability.id}'`);
|
|
15
|
-
this.tools.set(key,
|
|
15
|
+
this.tools.set(key, snapshots?.find((snapshot) => snapshot.source === tool) ??
|
|
16
|
+
bindTool(tool, { middlewareId: capability.id, slot: capability.id }));
|
|
16
17
|
this.owners.set(tool, capability.id);
|
|
17
18
|
}
|
|
18
19
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type
|
|
3
|
-
export
|
|
4
|
-
export type {
|
|
5
|
-
export type { BuiltAgent } from "./types/agent.js";
|
|
6
|
-
export { middleware, model, tool } from "./definition/helpers.js";
|
|
7
|
-
export { defineSchema } from "./definition/schema.js";
|
|
8
|
-
export { preparedModel } from "./execution/model/prepared.js";
|
|
9
|
-
export type { PreparedModelOptions } from "./execution/model/prepared.js";
|
|
10
|
-
export type { AgentManifest, CapabilityManifest, ManifestTool } from "./types/manifest.js";
|
|
11
|
-
export type { CapabilityDeclaration, CapabilityItems, MiddlewareContributions, StepMiddleware, StepRequest, StepResponse, } from "./types/middleware.js";
|
|
12
|
-
export type { ModelCandidate, ModelControls, ModelDirective, ModelEvidence, ModelFinishReason, ModelAdapter, ModelAdapterContext, ModelPreparedCall, ContextContributor, ContextMutationOptions, ContextSnapshot, ModelCall, ModelCallTool, ModelOutputBlock, PromptContentPart, PromptItem, ModelConfigurationContributor, ModelConfigurationInstruction, ModelConfigurationMutationOptions, ModelConfigurationSnapshot, ModelConfigurationTool, ModelRequest, ModelToolCall, ModelUsage, } from "./types/model.js";
|
|
13
|
-
export type { BuildDiagnostic, ContextItem, DeferredOutcome, JsonObject, JsonPrimitive, JsonValue, Tripwire, } from "./types/shared.js";
|
|
14
|
-
export type { ObserveEvent, ObserveModelConfigurationSnapshot, ObserveModelRequested, ObserveSealedCall, ObserveToolSnapshot, Observer, } from "./types/observe.js";
|
|
15
|
-
export type { InputEvent, MessageInput, InteractionReply, TranscriptEntry, UserContentPart, } from "./types/transcript.js";
|
|
16
|
-
export type { ExecutionInput, ExecutionState, ExecutionEvent, RunOptions, RunResult, SavedToolCall, ExecutionPlan, ToolReference, } from "./types/execution.js";
|
|
17
|
-
export { createExecutionState, validateExecutionState } from "./execution/state.js";
|
|
18
|
-
export type { Interaction, RequiredInteraction, ToolContent, ToolDefinition, ToolDescriptor, ToolExecutionContext, ToolExecutionResume, ToolInputSchema, ToolOutputSchema, ToolSchema, ToolSchemaSource, StandardToolSchema, StandardSchemaIssue, SchemaIssue, SchemaValidation, SchemaOutput, ToolOwner, ToolOutcome, ToolResult, ToolValidationFailureDetails, } from "./types/tool.js";
|
|
1
|
+
export * from "./run/index.js";
|
|
2
|
+
export type * from "./types/execution.js";
|
|
3
|
+
export type * from "./types/client.js";
|
|
4
|
+
export type { PreparedModelOptions } from "./loop/model/prepared.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { HarnessError, isHarnessError } from "./errors.js";
|
|
3
|
-
export { middleware, model, tool } from "./definition/helpers.js";
|
|
4
|
-
export { defineSchema } from "./definition/schema.js";
|
|
5
|
-
export { preparedModel } from "./execution/model/prepared.js";
|
|
6
|
-
export { createExecutionState, validateExecutionState } from "./execution/state.js";
|
|
1
|
+
export * from "./run/index.js";
|