@nylorun/runtime 0.22.0-beta → 0.24.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 +161 -0
- package/README.md +95 -30
- package/dist/adapters/execution/restate.d.ts +15 -3
- package/dist/adapters/execution/restate.js +78 -84
- package/dist/adapters/replication/pgoutput.d.ts +2 -0
- package/dist/adapters/replication/pgoutput.js +6 -3
- package/dist/adapters/sandbox/local.d.ts +9 -1
- package/dist/adapters/sandbox/local.js +16 -4
- package/dist/adapters/sandbox/virtual.js +4 -1
- package/dist/adapters/streams/s2.js +1 -13
- package/dist/api/a2a/endpoint.js +5 -1
- package/dist/api/a2a/routes.d.ts +2 -0
- package/dist/api/a2a/routes.js +2 -2
- package/dist/api/a2a/tasks.js +2 -1
- package/dist/api/ag-ui/endpoint.js +4 -2
- package/dist/api/ag-ui/history.js +4 -1
- package/dist/api/ag-ui/routes.d.ts +4 -1
- package/dist/api/ag-ui/routes.js +11 -10
- package/dist/api/ag-ui/translate.js +3 -2
- package/dist/api/components.d.ts +4953 -1204
- package/dist/api/components.js +25 -16
- package/dist/api/gate/keys.js +7 -1
- package/dist/api/gate/routes.d.ts +6 -0
- package/dist/api/gate/routes.js +39 -3
- package/dist/api/http/app.js +4 -4
- package/dist/api/http/define.d.ts +6 -0
- package/dist/api/http/define.js +13 -1
- package/dist/api/http/respond.js +1 -1
- package/dist/api/http/routes/artifacts.js +35 -8
- package/dist/api/http/routes/coverage.d.ts +9 -0
- package/dist/api/http/routes/coverage.js +34 -0
- package/dist/api/http/routes/environments.d.ts +11 -0
- package/dist/api/http/routes/environments.js +283 -0
- package/dist/api/http/routes/mcp.d.ts +1 -1
- package/dist/api/http/routes/mcp.js +2 -2
- package/dist/api/http/routes/me.js +1 -1
- package/dist/api/http/routes/reads.d.ts +45 -9
- package/dist/api/http/routes/reads.js +54 -5
- package/dist/api/http/routes/sessions.js +11 -6
- package/dist/api/http/routes/tenant.js +32 -10
- package/dist/api/openapi.js +31 -26
- package/dist/artifacts/disk.d.ts +59 -0
- package/dist/artifacts/disk.js +563 -0
- package/dist/artifacts/export.d.ts +1 -1
- package/dist/artifacts/export.js +2 -3
- package/dist/artifacts/folders.d.ts +6 -3
- package/dist/artifacts/folders.js +17 -12
- package/dist/artifacts/service.d.ts +2 -1
- package/dist/artifacts/service.js +6 -1
- package/dist/artifacts/workspace.d.ts +1 -1
- package/dist/artifacts/workspace.js +1 -1
- package/dist/core/flow-host.d.ts +3 -22
- package/dist/core/flow-host.js +11 -37
- package/dist/core/provider.d.ts +3 -2
- package/dist/core/provider.js +5 -37
- package/dist/core/sandbox-routes.d.ts +2 -21
- package/dist/core/sandbox-routes.js +10 -43
- package/dist/execution/types.d.ts +11 -9
- package/dist/execution/types.js +5 -7
- package/dist/gates/contract.d.ts +3 -24
- package/dist/gates/contract.js +1 -36
- package/dist/gates/egress-credentials.d.ts +9 -0
- package/dist/gates/egress-credentials.js +11 -4
- package/dist/gates/egress.d.ts +28 -1
- package/dist/gates/egress.js +115 -10
- package/dist/gates/fixture-model.d.ts +28 -0
- package/dist/gates/fixture-model.js +92 -0
- package/dist/gates/handler.js +4 -4
- package/dist/gates/http-tool.d.ts +6 -2
- package/dist/gates/http-tool.js +3 -5
- package/dist/gates/in-process.d.ts +5 -0
- package/dist/gates/in-process.js +12 -1
- package/dist/gates/journal.d.ts +30 -0
- package/dist/gates/journal.js +52 -0
- package/dist/gates/mcp-handler.d.ts +4 -0
- package/dist/gates/mcp-handler.js +5 -1
- package/dist/gates/meter.d.ts +10 -2
- package/dist/gates/meter.js +20 -5
- package/dist/gates/policy.d.ts +49 -0
- package/dist/gates/policy.js +134 -0
- package/dist/gates/tenant-vaults.d.ts +7 -7
- package/dist/gates/tenant-vaults.js +5 -5
- package/dist/gates/tool-calls.d.ts +10 -5
- package/dist/gates/tool-calls.js +28 -10
- package/dist/gates/tool-client.d.ts +8 -0
- package/dist/gates/tool-client.js +27 -11
- package/dist/gates/tool-contract.d.ts +10 -68
- package/dist/gates/tool-contract.js +1 -85
- package/dist/gates/tool-gate.d.ts +1 -1
- package/dist/harness/calls.d.ts +12 -5
- package/dist/harness/calls.js +21 -12
- package/dist/harness/executors.js +12 -9
- package/dist/harness/main.js +18 -5
- package/dist/harness/pod.d.ts +34 -0
- package/dist/harness/pod.js +41 -0
- package/dist/harness/service.d.ts +0 -1
- package/dist/harness/service.js +13 -5
- package/dist/harness/setup.d.ts +27 -0
- package/dist/harness/setup.js +150 -0
- package/dist/harness/ws-client.js +3 -2
- package/dist/harness/ws-port.d.ts +1 -5
- package/dist/harness/ws-port.js +1 -5
- package/dist/harness-api/in-process.js +3 -3
- package/dist/harness-api/record.d.ts +15 -1
- package/dist/harness-api/record.js +174 -44
- package/dist/harness-api/redact.d.ts +3 -0
- package/dist/harness-api/redact.js +45 -0
- package/dist/harness-api/server.d.ts +8 -0
- package/dist/harness-api/server.js +93 -13
- package/dist/harness-api/start.d.ts +10 -3
- package/dist/harness-api/start.js +40 -10
- package/dist/harness-api/tool-journal.d.ts +96 -0
- package/dist/harness-api/tool-journal.js +102 -0
- package/dist/harness-api/tool-status.d.ts +13 -0
- package/dist/harness-api/tool-status.js +26 -0
- package/dist/harness-api/workspace.d.ts +6 -3
- package/dist/harness-api/workspace.js +27 -11
- package/dist/harness-api/ws-server.d.ts +11 -3
- package/dist/harness-api/ws-server.js +94 -15
- package/dist/host/execution.d.ts +8 -6
- package/dist/host/gates.d.ts +2 -1
- package/dist/host/gates.js +10 -2
- package/dist/host/main.js +64 -21
- package/dist/host/operate.js +67 -5
- package/dist/host/stack-config.d.ts +70 -0
- package/dist/host/stack-config.js +67 -1
- package/dist/infra/execution.d.ts +18 -1
- package/dist/infra/execution.js +28 -4
- package/dist/infra/index.d.ts +1 -1
- package/dist/keys/client.js +4 -1
- package/dist/keys/keys.d.ts +5 -5
- package/dist/keys/keys.js +5 -7
- package/dist/management-openapi.json +999 -2211
- package/dist/mcp/connect.d.ts +25 -20
- package/dist/mcp/connect.js +29 -30
- package/dist/mcp/pool.d.ts +2 -2
- package/dist/mcp/pool.js +1 -1
- package/dist/mcp/preview.d.ts +3 -3
- package/dist/mcp/preview.js +10 -20
- package/dist/mcp/snapshot.d.ts +5 -11
- package/dist/mcp/snapshot.js +6 -7
- package/dist/model/pi-model.js +8 -0
- package/dist/openapi.json +6955 -2526
- package/dist/reads/types.d.ts +16 -3
- package/dist/record/append.d.ts +3 -1
- package/dist/record/append.js +1 -0
- package/dist/record/envelope.d.ts +5 -1
- package/dist/record/envelope.js +7 -3
- package/dist/record/environment.d.ts +25 -0
- package/dist/record/environment.js +44 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- package/dist/retry.d.ts +21 -0
- package/dist/retry.js +34 -0
- package/dist/sandbox/disk-fs.d.ts +95 -0
- package/dist/sandbox/disk-fs.js +206 -0
- package/dist/sandbox/join.d.ts +17 -18
- package/dist/sandbox/join.js +46 -20
- package/dist/sandbox/manager.d.ts +16 -8
- package/dist/sandbox/manager.js +33 -17
- package/dist/sandbox/placement.d.ts +13 -12
- package/dist/sandbox/placement.js +29 -12
- package/dist/sandbox/pods/client.d.ts +6 -1
- package/dist/sandbox/pods/lifecycle.d.ts +28 -27
- package/dist/sandbox/pods/lifecycle.js +14 -26
- package/dist/sandbox/pods/reconcile.js +21 -15
- package/dist/sandbox/pods/spec.d.ts +15 -13
- package/dist/sandbox/pods/spec.js +16 -20
- package/dist/sandbox/records.d.ts +2 -2
- package/dist/sandbox/records.js +3 -3
- package/dist/sandbox/resolve.d.ts +35 -27
- package/dist/sandbox/resolve.js +66 -41
- package/dist/sandbox/session-sandbox.js +1 -1
- package/dist/sandbox/setup.d.ts +61 -0
- package/dist/sandbox/setup.js +123 -0
- package/dist/sandbox/share.d.ts +11 -21
- package/dist/sandbox/share.js +12 -41
- package/dist/sandbox/tenant-config.d.ts +12 -14
- package/dist/sandbox/tenant-config.js +12 -17
- package/dist/sandbox/types.d.ts +6 -0
- package/dist/store/postgres/control.js +8 -1
- package/dist/store/postgres/drizzle/0018_wake_outbox_retries.sql +3 -0
- package/dist/store/postgres/drizzle/0019_sandbox_signal_outbox.sql +18 -0
- package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
- package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
- package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +42 -0
- package/dist/store/postgres/reads.js +117 -17
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/record.d.ts +7 -0
- package/dist/store/postgres/record.js +23 -2
- package/dist/store/postgres/schema.d.ts +1213 -779
- package/dist/store/postgres/schema.js +136 -76
- package/dist/store/postgres/store.js +283 -117
- package/dist/store/types.d.ts +206 -88
- package/dist/streams/relay/core.js +1 -13
- package/dist/tenant/advance.d.ts +7 -6
- package/dist/tenant/advance.js +121 -49
- package/dist/tenant/artifact-tool.js +3 -4
- package/dist/tenant/commands.d.ts +15 -2
- package/dist/tenant/commands.js +94 -14
- package/dist/tenant/context.d.ts +67 -33
- package/dist/tenant/context.js +4 -15
- package/dist/tenant/control.d.ts +8 -1
- package/dist/tenant/control.js +2 -0
- package/dist/tenant/effects.d.ts +1 -1
- package/dist/tenant/effects.js +37 -20
- package/dist/tenant/environments.d.ts +167 -0
- package/dist/tenant/environments.js +823 -0
- package/dist/tenant/harness-tokens.d.ts +21 -0
- package/dist/tenant/harness-tokens.js +61 -0
- package/dist/tenant/host-token.d.ts +1 -1
- package/dist/tenant/host-token.js +2 -4
- package/dist/tenant/identity-file.d.ts +4 -4
- package/dist/tenant/identity-file.js +17 -8
- package/dist/tenant/issuers.js +3 -3
- package/dist/tenant/principals.js +1 -1
- package/dist/tenant/reset.js +3 -3
- package/dist/tenant/runtime.d.ts +6 -1
- package/dist/tenant/runtime.js +30 -4
- package/dist/tenant/scheduler.d.ts +7 -0
- package/dist/tenant/scheduler.js +38 -7
- package/dist/tenant/session-streams.d.ts +0 -1
- package/dist/tenant/session-streams.js +1 -13
- package/dist/tenant/session.d.ts +3 -3
- package/dist/tenant/session.js +0 -14
- package/dist/tenant/sessions.d.ts +13 -13
- package/dist/tenant/sessions.js +61 -138
- package/dist/tenant/signing-keys.d.ts +5 -1
- package/dist/tenant/status.js +3 -3
- package/dist/tenant/streams.js +14 -29
- package/dist/tenant/sweep.d.ts +39 -12
- package/dist/tenant/sweep.js +168 -63
- package/dist/tenant/transcript.d.ts +210 -20
- package/dist/tenant/transcript.js +62 -11
- package/dist/tenant/turn-timing.d.ts +43 -0
- package/dist/tenant/turn-timing.js +39 -0
- package/dist/tenant/types.d.ts +2 -0
- package/dist/traces/ids.d.ts +42 -0
- package/dist/traces/ids.js +85 -0
- package/dist/traces/key.d.ts +6 -0
- package/dist/traces/key.js +37 -0
- package/dist/traces/map.d.ts +113 -0
- package/dist/traces/map.js +317 -0
- package/dist/traces/options.d.ts +7 -0
- package/dist/traces/options.js +1 -0
- package/dist/traces/otlp.d.ts +42 -0
- package/dist/traces/otlp.js +84 -0
- package/dist/traces/projector.d.ts +58 -0
- package/dist/traces/projector.js +200 -0
- package/dist/traces/read.d.ts +23 -0
- package/dist/traces/read.js +16 -0
- package/dist/vault/coverage.d.ts +26 -0
- package/dist/vault/coverage.js +64 -0
- package/dist/vault/error.d.ts +11 -1
- package/dist/vault/error.js +5 -1
- package/dist/vault/service.d.ts +47 -48
- package/dist/vault/service.js +321 -382
- package/dist/vault/sources.d.ts +5 -16
- package/dist/vault/sources.js +6 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/package.json +14 -13
- package/dist/api/http/routes/sandboxes.d.ts +0 -9
- package/dist/api/http/routes/sandboxes.js +0 -153
- package/dist/api/http/routes/vaults.d.ts +0 -10
- package/dist/api/http/routes/vaults.js +0 -139
- package/dist/record/sandbox.d.ts +0 -25
- package/dist/record/sandbox.js +0 -43
- package/dist/tenant/sandboxes.d.ts +0 -122
- package/dist/tenant/sandboxes.js +0 -562
|
@@ -66,7 +66,8 @@ export declare function folderContent(ctx: TenantContext, id: string, version: n
|
|
|
66
66
|
/**
|
|
67
67
|
* Deletes the artifact and every version: its rows and, for a session's artifact, its
|
|
68
68
|
* `artifact.deleted` event in one transaction, then its bytes. A folder's content-addressed
|
|
69
|
-
* files go too, those no other version names, under the quota lock (`folders.ts`).
|
|
69
|
+
* files go too, those no other version names, under the quota lock (`folders.ts`). An
|
|
70
|
+
* Environment's disk artifact is refused: its own routes delete its versions.
|
|
70
71
|
*/
|
|
71
72
|
export declare function deleteArtifact(ctx: TenantContext, id: string, access: ArtifactAccess): Promise<{
|
|
72
73
|
artifactId: string;
|
|
@@ -52,6 +52,7 @@ export function artifactView(row, versions) {
|
|
|
52
52
|
name: row.name,
|
|
53
53
|
contentType: row.contentType,
|
|
54
54
|
...(row.sessionId === null ? {} : { sessionId: row.sessionId }),
|
|
55
|
+
...(row.environmentId === null ? {} : { environmentId: row.environmentId }),
|
|
55
56
|
latestVersion: row.latestVersion,
|
|
56
57
|
...(row.labelsJson === null ? {} : { labels: JSON.parse(row.labelsJson) }),
|
|
57
58
|
createdAt: row.createdAt,
|
|
@@ -194,6 +195,7 @@ export async function uploadArtifact(ctx, input, body, access, signal) {
|
|
|
194
195
|
: JSON.stringify(input.labels),
|
|
195
196
|
createdAt,
|
|
196
197
|
updatedAt: createdAt,
|
|
198
|
+
environmentId: null,
|
|
197
199
|
};
|
|
198
200
|
version = {
|
|
199
201
|
artifactId,
|
|
@@ -278,11 +280,14 @@ export async function folderContent(ctx, id, version, access) {
|
|
|
278
280
|
/**
|
|
279
281
|
* Deletes the artifact and every version: its rows and, for a session's artifact, its
|
|
280
282
|
* `artifact.deleted` event in one transaction, then its bytes. A folder's content-addressed
|
|
281
|
-
* files go too, those no other version names, under the quota lock (`folders.ts`).
|
|
283
|
+
* files go too, those no other version names, under the quota lock (`folders.ts`). An
|
|
284
|
+
* Environment's disk artifact is refused: its own routes delete its versions.
|
|
282
285
|
*/
|
|
283
286
|
export async function deleteArtifact(ctx, id, access) {
|
|
284
287
|
const keys = await ctx.store.tx(async (t) => {
|
|
285
288
|
const found = await readableArtifact(t, id, access);
|
|
289
|
+
if (found.environmentId !== null)
|
|
290
|
+
fail(409, `Artifact ${id} holds Environment ${found.environmentId}'s disk versions: delete them with DELETE /v1/environments/{id}/versions/{version}, or delete the Environment.`);
|
|
286
291
|
if (found.sessionId !== null)
|
|
287
292
|
await lockedSession(t, found.sessionId, access);
|
|
288
293
|
if (found.kind === "folder")
|
|
@@ -22,7 +22,7 @@ export interface WorkspaceSession {
|
|
|
22
22
|
/** The session that owns the workspace (one hop through `sandboxOwnerId`). */
|
|
23
23
|
readonly ownerId: string;
|
|
24
24
|
/** The sandbox resource the workspace belongs to, when the owner is attached to one. */
|
|
25
|
-
readonly
|
|
25
|
+
readonly environmentId?: string;
|
|
26
26
|
/** The session's pinned manifest: its sandbox capability carries the sandbox's spec. */
|
|
27
27
|
readonly manifest: AgentManifest;
|
|
28
28
|
}
|
|
@@ -24,7 +24,7 @@ export function sandboxWorkspaceReader(sandbox) {
|
|
|
24
24
|
id: session.ownerId,
|
|
25
25
|
activeTurnId: session.turnId,
|
|
26
26
|
manifest: session.manifest,
|
|
27
|
-
...(session.
|
|
27
|
+
...(session.environmentId === undefined ? {} : { environmentId: session.environmentId }),
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
};
|
package/dist/core/flow-host.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { EffectOutcome } from "@nylorun/core/contracts";
|
|
2
2
|
import { type JsonValue, type WorkflowManifest } from "@nylorun/core/define";
|
|
3
3
|
import type { HostEffect } from "@nylorun/harness/run";
|
|
4
|
-
import type { EffectDoc, Tx
|
|
5
|
-
import { type
|
|
4
|
+
import type { EffectDoc, Tx } from "../store/types.js";
|
|
5
|
+
import { type TurnTiming } from "../tenant/turn-timing.js";
|
|
6
6
|
/** Deterministic agent session id: derive(workflowSessionId, path, …parts). */
|
|
7
7
|
export declare function deriveSessionId(workflowSessionId: string, path: string, ...parts: string[]): string;
|
|
8
8
|
/**
|
|
@@ -60,15 +60,13 @@ export type FlowHostSession = {
|
|
|
60
60
|
status: string;
|
|
61
61
|
activeTurnId: string | null;
|
|
62
62
|
info?: any;
|
|
63
|
-
vaultIds?: readonly string[];
|
|
64
|
-
credentialSelections?: readonly unknown[];
|
|
65
63
|
creation?: unknown;
|
|
66
64
|
waits?: unknown;
|
|
67
65
|
lastOutput?: JsonValue;
|
|
68
66
|
/** The turn `status`, `lastOutput` and `error` describe, once it ended. */
|
|
69
67
|
lastTurnId?: string;
|
|
70
68
|
error?: string;
|
|
71
|
-
};
|
|
69
|
+
} & TurnTiming;
|
|
72
70
|
/** How a linked agent turn ended. */
|
|
73
71
|
export type LinkedTurnEnd = {
|
|
74
72
|
readonly turnId: string;
|
|
@@ -97,8 +95,6 @@ export type CascadeCancelPlan = {
|
|
|
97
95
|
/** Linked agent sessions to cancel, deepest path first. */
|
|
98
96
|
readonly agentSessionIds: string[];
|
|
99
97
|
};
|
|
100
|
-
/** Wakes a session after commit (`DurableExecution.wake` through the Tenant context). */
|
|
101
|
-
type Schedule = WakeDelivery;
|
|
102
98
|
/** Effect documents as the flow host writes them. */
|
|
103
99
|
export type FlowEffect = EffectDoc & {
|
|
104
100
|
agentSessionId?: string;
|
|
@@ -135,7 +131,6 @@ export declare function wakeLinkedWorkflow(input: {
|
|
|
135
131
|
readonly failed?: boolean;
|
|
136
132
|
readonly cancelled?: boolean;
|
|
137
133
|
readonly error?: string;
|
|
138
|
-
readonly schedule: Schedule;
|
|
139
134
|
}): Promise<void>;
|
|
140
135
|
/** Pending workflow `agent` effects with a linked session, for the Tenant sweep. */
|
|
141
136
|
export declare function pendingAgentEffects(t: Tx): Promise<FlowEffect[]>;
|
|
@@ -152,7 +147,6 @@ export declare function pendingAgentEffects(t: Tx): Promise<FlowEffect[]>;
|
|
|
152
147
|
export declare function reconcilePendingAgentEffect(input: {
|
|
153
148
|
readonly t: Tx;
|
|
154
149
|
readonly effectId: string;
|
|
155
|
-
readonly schedule: Schedule;
|
|
156
150
|
}): Promise<boolean>;
|
|
157
151
|
/** Path depth for deepest-first cancel ordering. */
|
|
158
152
|
export declare function pathDepth(path: string): number;
|
|
@@ -222,16 +216,3 @@ export declare function foreignInteractionConflict(input: {
|
|
|
222
216
|
message: string;
|
|
223
217
|
ownerSessionId: string;
|
|
224
218
|
} | undefined>;
|
|
225
|
-
/**
|
|
226
|
-
* When concurrency slots free, re-enter the workflow so queued effects can start
|
|
227
|
-
* (status stays `queued` until the effect resolver dispatches them). Returns
|
|
228
|
-
* true when a wake was scheduled.
|
|
229
|
-
*/
|
|
230
|
-
export declare function wakeForQueuedEffects(input: {
|
|
231
|
-
readonly t: Tx;
|
|
232
|
-
readonly workflowSessionId: string;
|
|
233
|
-
readonly turnId: string;
|
|
234
|
-
readonly limits: FlowLimits;
|
|
235
|
-
readonly schedule: Schedule;
|
|
236
|
-
}): Promise<boolean>;
|
|
237
|
-
export {};
|
package/dist/core/flow-host.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Every function that touches state takes the caller's transaction `t: Tx` and
|
|
5
5
|
* is async. Nothing here publishes, notifies or schedules directly (seam rule
|
|
6
6
|
* 1): events go through `t.event(...)`, which the store publishes after
|
|
7
|
-
* commit, and wakes go through `t.wake(id, wake
|
|
8
|
-
*
|
|
7
|
+
* commit, and wakes go through `t.wake(id, wake)`, the wake outbox, which the store
|
|
8
|
+
* delivers after commit. Functions
|
|
9
9
|
* that rewrite a session-scoped document lock that session first with
|
|
10
10
|
* `t.lockSession` (a no-op when the caller already holds it).
|
|
11
11
|
*
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
* - `linkedMessageKey(request): string`
|
|
25
25
|
* - `linkedTurnOf(t, agentSessionId, request): Promise<string | undefined>`
|
|
26
26
|
* - `linkedTurnEnd(t, effect, agent): Promise<LinkedTurnEnd | undefined>`
|
|
27
|
-
* - `wakeLinkedWorkflow({ t, agentSessionId, turnId, output?, failed?, cancelled?, error
|
|
27
|
+
* - `wakeLinkedWorkflow({ t, agentSessionId, turnId, output?, failed?, cancelled?, error? }): Promise<void>`
|
|
28
28
|
* - `pendingAgentEffects(t): Promise<FlowEffect[]>`
|
|
29
|
-
* - `reconcilePendingAgentEffect({ t, effectId
|
|
29
|
+
* - `reconcilePendingAgentEffect({ t, effectId }): Promise<boolean>`
|
|
30
30
|
* - `planCancelCascade({ t, workflowSessionId, turnId }): Promise<CascadeCancelPlan>`
|
|
31
31
|
* - `cancelSiblingWork({ t, workflowSessionId, turnId, siblingPaths?, cancelEffectIds? }): Promise<CancelSiblingResult>`
|
|
32
32
|
* - `cancelQueuedEffects({ t, workflowSessionId, turnId }): Promise<string[]>`
|
|
@@ -34,11 +34,10 @@
|
|
|
34
34
|
* - `flowInteractionOf(waits, workflowSessionId, interactionId): { id; kind } | undefined`
|
|
35
35
|
* - `findInteractionOwner({ t, workflowSessionId, interactionId }): Promise<{ sessionId; path } | undefined>`
|
|
36
36
|
* - `foreignInteractionConflict({ t, workflowSessionId, interactionId }): Promise<{ status: 409; message; ownerSessionId } | undefined>`
|
|
37
|
-
* - `wakeForQueuedEffects({ t, workflowSessionId, turnId, limits, schedule }): Promise<boolean>`
|
|
38
37
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* A wake carries the reason (`linked`, `flow`) and, where the cause has one, a dedupe key.
|
|
39
|
+
* The store delivers it after commit, never inside `t`; one it does not deliver stays in the
|
|
40
|
+
* outbox for the Tenant sweep (`Tx.wake`).
|
|
42
41
|
*
|
|
43
42
|
* An `agent` effect settles only from the linked turn it started. A linked agent session is
|
|
44
43
|
* reused by every iteration of a Loop (its id derives from the workflow and the path), so its
|
|
@@ -51,7 +50,7 @@
|
|
|
51
50
|
*/
|
|
52
51
|
import { createHash } from "node:crypto";
|
|
53
52
|
import { isVerdict } from "@nylorun/core/define";
|
|
54
|
-
import {
|
|
53
|
+
import { resumeTurn } from "../tenant/turn-timing.js";
|
|
55
54
|
/** Deterministic agent session id: derive(workflowSessionId, path, …parts). */
|
|
56
55
|
export function deriveSessionId(workflowSessionId, path, ...parts) {
|
|
57
56
|
const digest = createHash("sha256")
|
|
@@ -140,10 +139,6 @@ export async function recordVerdict(t, request, value) {
|
|
|
140
139
|
...(verdict.data !== undefined ? { data: verdict.data } : {}),
|
|
141
140
|
});
|
|
142
141
|
}
|
|
143
|
-
/** Writes the wake to the outbox; `schedule` delivers it after commit. */
|
|
144
|
-
function requestWake(t, schedule, id, wake) {
|
|
145
|
-
return t.wake(id, wake, schedule);
|
|
146
|
-
}
|
|
147
142
|
/** Active agent turns + tool nodes in flight for one workflow turn. */
|
|
148
143
|
export async function countActiveFlowWork(t, workflowSessionId, turnId) {
|
|
149
144
|
const effects = await t.effectsForTurn(workflowSessionId, turnId);
|
|
@@ -243,9 +238,11 @@ export async function wakeLinkedWorkflow(input) {
|
|
|
243
238
|
}
|
|
244
239
|
: { value: input.output ?? null };
|
|
245
240
|
await settleAgentEffect({ t, effect, outcome });
|
|
241
|
+
// A workflow paused on its agents' interactions goes on (R7.1, `tenant/turn-timing.ts`).
|
|
242
|
+
resumeTurn(workflow);
|
|
246
243
|
workflow.status = "runnable";
|
|
247
244
|
await t.put("sessions", workflow.id, workflow);
|
|
248
|
-
await
|
|
245
|
+
await t.wake(workflow.id, {
|
|
249
246
|
reason: "linked",
|
|
250
247
|
dedupeKey: `linked:${link.turnId}:${link.effectId}`,
|
|
251
248
|
});
|
|
@@ -288,7 +285,6 @@ export async function reconcilePendingAgentEffect(input) {
|
|
|
288
285
|
: end.status === "failed"
|
|
289
286
|
? { failed: true, error: end.error }
|
|
290
287
|
: { cancelled: true, error: end.error }),
|
|
291
|
-
schedule: input.schedule,
|
|
292
288
|
});
|
|
293
289
|
return true;
|
|
294
290
|
}
|
|
@@ -457,25 +453,3 @@ export async function foreignInteractionConflict(input) {
|
|
|
457
453
|
ownerSessionId: owner.sessionId,
|
|
458
454
|
};
|
|
459
455
|
}
|
|
460
|
-
/**
|
|
461
|
-
* When concurrency slots free, re-enter the workflow so queued effects can start
|
|
462
|
-
* (status stays `queued` until the effect resolver dispatches them). Returns
|
|
463
|
-
* true when a wake was scheduled.
|
|
464
|
-
*/
|
|
465
|
-
export async function wakeForQueuedEffects(input) {
|
|
466
|
-
const { t } = input;
|
|
467
|
-
if (!mayDispatchMore(await countActiveFlowWork(t, input.workflowSessionId, input.turnId), input.limits))
|
|
468
|
-
return false;
|
|
469
|
-
const queued = await t.effectsForTurn(input.workflowSessionId, input.turnId, ["queued"]);
|
|
470
|
-
if (queued.length === 0)
|
|
471
|
-
return false;
|
|
472
|
-
const workflow = await t.lockSession(input.workflowSessionId);
|
|
473
|
-
if (workflow && workflow.status === "waiting") {
|
|
474
|
-
workflow.status = "runnable";
|
|
475
|
-
await t.put("sessions", workflow.id, workflow);
|
|
476
|
-
}
|
|
477
|
-
await requestWake(t, input.schedule, input.workflowSessionId, {
|
|
478
|
-
reason: "flow",
|
|
479
|
-
});
|
|
480
|
-
return true;
|
|
481
|
-
}
|
package/dist/core/provider.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ export declare function gatewayModel(options: {
|
|
|
9
9
|
model: string;
|
|
10
10
|
}): ModelProvider;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* The fixture model as a provider (`model: {kind: "fixture"}` in the Runtime's config). The Tenant
|
|
13
|
+
* setting `model.fixture` is answered by the Model Gate instead (R4.3); both answer the same way
|
|
14
|
+
* (`gates/fixture-model.ts`).
|
|
14
15
|
*/
|
|
15
16
|
export declare function toolFixtureModel(): ModelProvider;
|
package/dist/core/provider.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fixtureAnswer } from "../gates/fixture-model.js";
|
|
1
2
|
export function scriptedModel(output = "Scripted development response") {
|
|
2
3
|
return async () => ({ output: [{ type: "text", text: output }] });
|
|
3
4
|
}
|
|
@@ -23,43 +24,10 @@ export function gatewayModel(options) {
|
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* The fixture model as a provider (`model: {kind: "fixture"}` in the Runtime's config). The Tenant
|
|
28
|
+
* setting `model.fixture` is answered by the Model Gate instead (R4.3); both answer the same way
|
|
29
|
+
* (`gates/fixture-model.ts`).
|
|
28
30
|
*/
|
|
29
31
|
export function toolFixtureModel() {
|
|
30
|
-
return async (effect) =>
|
|
31
|
-
const call = effect.input;
|
|
32
|
-
const last = call.prompt.at(-1);
|
|
33
|
-
if (last?.kind === "tool-result")
|
|
34
|
-
return {
|
|
35
|
-
output: [
|
|
36
|
-
{
|
|
37
|
-
type: "text",
|
|
38
|
-
text: `Order lookup complete: ${last.content.map((part) => (part.type === "text" ? part.text : JSON.stringify(part))).join(" ")}`,
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
};
|
|
42
|
-
const users = call.prompt.filter((p) => p.kind === "message" && p.role === "user");
|
|
43
|
-
if (users.length > 1)
|
|
44
|
-
return {
|
|
45
|
-
output: [
|
|
46
|
-
{
|
|
47
|
-
type: "text",
|
|
48
|
-
text: `I remember: ${users[0].content.map((part) => (part.type === "text" ? part.text : "")).join(" ")}`,
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
};
|
|
52
|
-
if (!call.tools.some((tool) => tool.name === "lookup_order"))
|
|
53
|
-
return { output: [{ type: "text", text: "Hello from the fixture model." }] };
|
|
54
|
-
return {
|
|
55
|
-
output: [
|
|
56
|
-
{
|
|
57
|
-
type: "tool-call",
|
|
58
|
-
id: "fixture_lookup",
|
|
59
|
-
name: "lookup_order",
|
|
60
|
-
args: { orderId: "demo-123" },
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
};
|
|
32
|
+
return async (effect, signal) => fixtureAnswer(effect.input, signal);
|
|
65
33
|
}
|
|
@@ -9,32 +9,13 @@ export type SandboxRouteSession = SessionSandboxRef & {
|
|
|
9
9
|
readonly activeTurnId: string | null;
|
|
10
10
|
readonly status: string;
|
|
11
11
|
};
|
|
12
|
-
/** A session together with a synchronous lookup over its sandbox owner chain. */
|
|
13
|
-
export type SandboxRouteRead = {
|
|
14
|
-
readonly session: SandboxRouteSession;
|
|
15
|
-
readonly lookup: (id: string) => SessionSandboxRef | undefined;
|
|
16
|
-
};
|
|
17
12
|
export type SandboxRouteDeps = {
|
|
18
13
|
readonly sandbox: Pick<WorkspacePort, "run">;
|
|
19
|
-
/** The session
|
|
20
|
-
readonly session: (id: string) => Promise<
|
|
14
|
+
/** The session; rejects when it is missing. */
|
|
15
|
+
readonly session: (id: string) => Promise<SandboxRouteSession>;
|
|
21
16
|
};
|
|
22
17
|
/**
|
|
23
18
|
* `POST /v1/sessions/:id/sandbox/:tool` — application principal.
|
|
24
19
|
* Refused while the session has an active agent turn.
|
|
25
20
|
*/
|
|
26
21
|
export declare function handleSessionSandboxTool(deps: SandboxRouteDeps, sessionId: string, toolName: string, body: unknown, signal: AbortSignal): Promise<SandboxToolOutcome>;
|
|
27
|
-
/**
|
|
28
|
-
* Validate PutSession.sandbox attach: same owner, and a sandbox to share. A session whose
|
|
29
|
-
* definition declares a sandbox must declare the owner's spec; one whose definition declares
|
|
30
|
-
* none inherits it (`inherit`).
|
|
31
|
-
*/
|
|
32
|
-
export declare function validateSandboxAttach(body: {
|
|
33
|
-
ownerUserId: string;
|
|
34
|
-
sandbox?: unknown;
|
|
35
|
-
}, newManifest: SessionSandboxRef["manifest"], lookup: (id: string) => SessionSandboxRef | undefined,
|
|
36
|
-
/** Acting for a subject: another owner's session is the 404 of a missing one. */
|
|
37
|
-
options?: {
|
|
38
|
-
opaque?: boolean;
|
|
39
|
-
inherit?: boolean;
|
|
40
|
-
}): string | undefined;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP handlers for the session-scoped sandbox tool route (`POST /v1/sessions/:id/sandbox/:tool`)
|
|
3
|
-
*
|
|
2
|
+
* HTTP handlers for the session-scoped sandbox tool route (`POST /v1/sessions/:id/sandbox/:tool`):
|
|
3
|
+
* a tool run in the sandbox of the session's Environment.
|
|
4
4
|
*/
|
|
5
5
|
import { isSandboxToolName, } from "@nylorun/core/define";
|
|
6
|
-
import { capabilityForSandbox,
|
|
6
|
+
import { capabilityForSandbox, sandboxWorkspaceOf, sessionSandboxSpec, } from "../sandbox/share.js";
|
|
7
7
|
export class SandboxRouteError extends Error {
|
|
8
8
|
status;
|
|
9
9
|
constructor(status, message) {
|
|
@@ -12,10 +12,8 @@ export class SandboxRouteError extends Error {
|
|
|
12
12
|
this.name = "SandboxRouteError";
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
function resolveSpec(session
|
|
16
|
-
const
|
|
17
|
-
const owner = ownerId === session.id ? session : lookup(ownerId) ?? session;
|
|
18
|
-
const spec = sessionSandboxSpec(owner) ?? sessionSandboxSpec(session);
|
|
15
|
+
function resolveSpec(session) {
|
|
16
|
+
const spec = sessionSandboxSpec(session);
|
|
19
17
|
if (!spec)
|
|
20
18
|
throw new SandboxRouteError(404, "Session has no sandbox");
|
|
21
19
|
return spec;
|
|
@@ -34,14 +32,14 @@ function toolInput(body) {
|
|
|
34
32
|
const { requestId: _r, ...input } = record;
|
|
35
33
|
return input;
|
|
36
34
|
}
|
|
37
|
-
async function runTool(deps,
|
|
38
|
-
const spec = resolveSpec(session
|
|
39
|
-
const workspace = sandboxWorkspaceOf(session
|
|
35
|
+
async function runTool(deps, session, tool, input, signal) {
|
|
36
|
+
const spec = resolveSpec(session);
|
|
37
|
+
const workspace = sandboxWorkspaceOf(session);
|
|
40
38
|
const ref = {
|
|
41
39
|
id: workspace.ownerId,
|
|
42
40
|
activeTurnId: session.activeTurnId,
|
|
43
41
|
manifest: session.manifest,
|
|
44
|
-
...(workspace.
|
|
42
|
+
...(workspace.environmentId === undefined ? {} : { environmentId: workspace.environmentId }),
|
|
45
43
|
};
|
|
46
44
|
return deps.sandbox.run(ref, capabilityForSandbox(spec), tool, input, signal);
|
|
47
45
|
}
|
|
@@ -51,39 +49,8 @@ async function runTool(deps, { session, lookup }, tool, input, signal) {
|
|
|
51
49
|
*/
|
|
52
50
|
export async function handleSessionSandboxTool(deps, sessionId, toolName, body, signal) {
|
|
53
51
|
const read = await deps.session(sessionId);
|
|
54
|
-
if (read.
|
|
52
|
+
if (read.activeTurnId)
|
|
55
53
|
throw new SandboxRouteError(409, "Sandbox is unavailable while the session has an active agent turn");
|
|
56
54
|
const tool = parseTool(toolName);
|
|
57
55
|
return runTool(deps, read, tool, toolInput(body), signal);
|
|
58
56
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Validate PutSession.sandbox attach: same owner, and a sandbox to share. A session whose
|
|
61
|
-
* definition declares a sandbox must declare the owner's spec; one whose definition declares
|
|
62
|
-
* none inherits it (`inherit`).
|
|
63
|
-
*/
|
|
64
|
-
export function validateSandboxAttach(body, newManifest, lookup,
|
|
65
|
-
/** Acting for a subject: another owner's session is the 404 of a missing one. */
|
|
66
|
-
options = {}) {
|
|
67
|
-
const request = body.sandbox;
|
|
68
|
-
const share = typeof request === "object" && request !== null && "session" in request
|
|
69
|
-
? String(request.session)
|
|
70
|
-
: undefined;
|
|
71
|
-
if (!share)
|
|
72
|
-
return undefined;
|
|
73
|
-
const owner = lookup(share);
|
|
74
|
-
if (!owner || (options.opaque && owner.ownerUserId !== body.ownerUserId))
|
|
75
|
-
throw new SandboxRouteError(404, "Sandbox session not found");
|
|
76
|
-
if (owner.ownerUserId !== body.ownerUserId)
|
|
77
|
-
throw new SandboxRouteError(403, "Sandbox session must belong to the same owner");
|
|
78
|
-
const ownerSpec = sessionSandboxSpec(owner);
|
|
79
|
-
if (!ownerSpec)
|
|
80
|
-
throw new SandboxRouteError(400, "Target session has no sandbox to share");
|
|
81
|
-
if (options.inherit)
|
|
82
|
-
return owningSandboxSessionId(owner, lookup);
|
|
83
|
-
const newSpec = sandboxSpecOf(newManifest);
|
|
84
|
-
if (!newSpec)
|
|
85
|
-
throw new SandboxRouteError(400, "Session must declare a sandbox identical to the shared session");
|
|
86
|
-
if (!sandboxSpecsEqual(ownerSpec, newSpec))
|
|
87
|
-
throw new SandboxRouteError(409, "Sandbox specs must be identical to share a sandbox");
|
|
88
|
-
return owningSandboxSessionId(owner, lookup);
|
|
89
|
-
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Durable Session Execution seam (architecture §12.3).
|
|
3
3
|
*
|
|
4
|
-
* Durable Session Execution decides when to look at a session again
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* checkpoint, the effect journal, the events) and the wake outbox that bridges the
|
|
9
|
-
* two. Restate is the supported implementation
|
|
4
|
+
* Durable Session Execution decides when to look at a session again; `advance` is
|
|
5
|
+
* safe to repeat (§10.1). What it owns and what the Session Store owns is said once,
|
|
6
|
+
* under "Durable Session Execution" in `src/CONTEXT.md`. Restate is the supported
|
|
7
|
+
* implementation
|
|
10
8
|
* (`adapters/execution/restate.ts`); `execution/memory.ts` is the in-process
|
|
11
9
|
* implementation used by unit tests, `startEphemeralRuntime` and a Host
|
|
12
10
|
* started without Restate endpoints.
|
|
@@ -19,7 +17,7 @@
|
|
|
19
17
|
* - **At least once after a wake.** When `wake` resolves, an `advance` for the
|
|
20
18
|
* key will start after that point (possibly merged with other wakes). Wakes
|
|
21
19
|
* are sent after the Session Store transaction that caused them commits, never
|
|
22
|
-
* inside it: the transaction writes the wake to
|
|
20
|
+
* inside it: the transaction writes the wake to the outbox (`Tx.wake`), and the
|
|
23
21
|
* wake is sent after commit, or by the Tenant sweep when that send failed or a
|
|
24
22
|
* crash cut it off. A wake may therefore be sent more than once, always with the
|
|
25
23
|
* same `dedupeKey`.
|
|
@@ -74,10 +72,14 @@ export type AdvanceResult = {
|
|
|
74
72
|
retryAfterMs: number;
|
|
75
73
|
};
|
|
76
74
|
/** A pod sandbox's timers. */
|
|
77
|
-
export type SandboxTimer = "idle"
|
|
78
|
-
/**
|
|
75
|
+
export type SandboxTimer = "idle";
|
|
76
|
+
/**
|
|
77
|
+
* What `DurableExecution.sandbox` asks for: a reconcile, or a timer. A reconcile's `key` merges
|
|
78
|
+
* repeated sends of one request (the outbox's `signal:<row id>`); without one, every send runs.
|
|
79
|
+
*/
|
|
79
80
|
export type SandboxSignal = {
|
|
80
81
|
kind: "reconcile";
|
|
82
|
+
key?: string;
|
|
81
83
|
} | {
|
|
82
84
|
kind: "arm";
|
|
83
85
|
timer: SandboxTimer;
|
package/dist/execution/types.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Durable Session Execution seam (architecture §12.3).
|
|
3
3
|
*
|
|
4
|
-
* Durable Session Execution decides when to look at a session again
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* checkpoint, the effect journal, the events) and the wake outbox that bridges the
|
|
9
|
-
* two. Restate is the supported implementation
|
|
4
|
+
* Durable Session Execution decides when to look at a session again; `advance` is
|
|
5
|
+
* safe to repeat (§10.1). What it owns and what the Session Store owns is said once,
|
|
6
|
+
* under "Durable Session Execution" in `src/CONTEXT.md`. Restate is the supported
|
|
7
|
+
* implementation
|
|
10
8
|
* (`adapters/execution/restate.ts`); `execution/memory.ts` is the in-process
|
|
11
9
|
* implementation used by unit tests, `startEphemeralRuntime` and a Host
|
|
12
10
|
* started without Restate endpoints.
|
|
@@ -19,7 +17,7 @@
|
|
|
19
17
|
* - **At least once after a wake.** When `wake` resolves, an `advance` for the
|
|
20
18
|
* key will start after that point (possibly merged with other wakes). Wakes
|
|
21
19
|
* are sent after the Session Store transaction that caused them commits, never
|
|
22
|
-
* inside it: the transaction writes the wake to
|
|
20
|
+
* inside it: the transaction writes the wake to the outbox (`Tx.wake`), and the
|
|
23
21
|
* wake is sent after commit, or by the Tenant sweep when that send failed or a
|
|
24
22
|
* crash cut it off. A wake may therefore be sent more than once, always with the
|
|
25
23
|
* same `dedupeKey`.
|
package/dist/gates/contract.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The gates service's wire format (blueprint §15, P1.1).
|
|
3
|
-
* it
|
|
2
|
+
* The gates service's wire format (blueprint §15, P1.1). Not in the published OpenAPI documents:
|
|
3
|
+
* harnesses call it, and its bodies are published in `@nylorun/core/harness-api` (R4.5).
|
|
4
4
|
*
|
|
5
5
|
* `POST /nylorun/v1/model-calls`
|
|
6
6
|
* - Headers: `Authorization: Bearer <run token>` (F5, `tenant/run-token.ts`), `Idempotency-Key:
|
|
@@ -22,31 +22,10 @@
|
|
|
22
22
|
* whether or not it exists, `403 gate_forbidden` when it is another session's call. The token
|
|
23
23
|
* need not be live: a user cancel makes it stale, and still stops its call.
|
|
24
24
|
*/
|
|
25
|
-
import { z } from "zod";
|
|
26
25
|
import type { ModelGateOutcome } from "./model-gate.js";
|
|
27
|
-
export
|
|
26
|
+
export { MAX_MODEL_CALL_BYTES, MODEL_CALLS_PATH, ModelCallBodySchema, type GateErrorBody, type ModelCallBody, } from "@nylorun/core/harness-api";
|
|
28
27
|
/** Header naming the Tenant a call is for: optional, and checked against the gate's Tenant. */
|
|
29
28
|
export declare const TENANT_HEADER = "nylorun-tenant";
|
|
30
|
-
/** Largest request body the gate reads: one `ModelCall` with its whole projected history. */
|
|
31
|
-
export declare const MAX_MODEL_CALL_BYTES: number;
|
|
32
|
-
export declare const ModelCallBodySchema: z.ZodObject<{
|
|
33
|
-
effectId: z.ZodString;
|
|
34
|
-
invocationId: z.ZodString;
|
|
35
|
-
call: z.ZodObject<{
|
|
36
|
-
prompt: z.ZodArray<z.ZodUnknown>;
|
|
37
|
-
tools: z.ZodArray<z.ZodObject<{
|
|
38
|
-
name: z.ZodString;
|
|
39
|
-
}, z.core.$loose>>;
|
|
40
|
-
}, z.core.$loose>;
|
|
41
|
-
}, z.core.$strict>;
|
|
42
|
-
export type ModelCallBody = z.infer<typeof ModelCallBodySchema>;
|
|
43
29
|
export interface ModelCallResponse {
|
|
44
30
|
readonly outcome: ModelGateOutcome;
|
|
45
31
|
}
|
|
46
|
-
/** An error answer: `{error: {code, message}}`. */
|
|
47
|
-
export interface GateErrorBody {
|
|
48
|
-
readonly error: {
|
|
49
|
-
readonly code: "gate_unauthorized" | "gate_forbidden" | "run_stale" | "invalid_request" | "gate_conflict";
|
|
50
|
-
readonly message: string;
|
|
51
|
-
};
|
|
52
|
-
}
|
package/dist/gates/contract.js
CHANGED
|
@@ -1,38 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
* The gates service's wire format (blueprint §15, P1.1). Internal: only the loop calls it, so
|
|
3
|
-
* it is not in the published OpenAPI documents.
|
|
4
|
-
*
|
|
5
|
-
* `POST /nylorun/v1/model-calls`
|
|
6
|
-
* - Headers: `Authorization: Bearer <run token>` (F5, `tenant/run-token.ts`), `Idempotency-Key:
|
|
7
|
-
* <effect id>`, and optionally `Nylorun-Tenant: <tenant id>`, which must then be the token's
|
|
8
|
-
* Tenant. Core's credential (`NYLORUN_GATES_TOKEN`) is refused: only a run calls the model.
|
|
9
|
-
* - Body: `ModelCallBody`, at most `MAX_MODEL_CALL_BYTES`. It names no session, turn or agent:
|
|
10
|
-
* the gate takes them from the token, and refuses a body that names them.
|
|
11
|
-
* - `200 {outcome}` once the call has finished, whether the outcome is a candidate or a
|
|
12
|
-
* failure; nothing is sent while it runs. `401 gate_unauthorized` for a missing, malformed,
|
|
13
|
-
* expired or foreign token, `409 run_stale` when the token's lease is no longer the
|
|
14
|
-
* session's (a cancel, a new turn, a takeover), `400 invalid_request` for a malformed Tenant
|
|
15
|
-
* header or a bad body, `409 gate_conflict` when a different request already runs under the
|
|
16
|
-
* same key.
|
|
17
|
-
* - With an `Idempotency-Key` the call outlives its client (P1.2): a re-send with the same key
|
|
18
|
-
* and body joins it, or gets its outcome for 30 minutes. Without one, a client that goes
|
|
19
|
-
* away aborts the call.
|
|
20
|
-
*
|
|
21
|
-
* `POST /nylorun/v1/model-calls/{key}/cancel` (same headers): aborts the keyed call; `204`
|
|
22
|
-
* whether or not it exists, `403 gate_forbidden` when it is another session's call. The token
|
|
23
|
-
* need not be live: a user cancel makes it stale, and still stops its call.
|
|
24
|
-
*/
|
|
25
|
-
import { z } from "zod";
|
|
26
|
-
export const MODEL_CALLS_PATH = "/nylorun/v1/model-calls";
|
|
1
|
+
export { MAX_MODEL_CALL_BYTES, MODEL_CALLS_PATH, ModelCallBodySchema, } from "@nylorun/core/harness-api";
|
|
27
2
|
/** Header naming the Tenant a call is for: optional, and checked against the gate's Tenant. */
|
|
28
3
|
export const TENANT_HEADER = "nylorun-tenant";
|
|
29
|
-
/** Largest request body the gate reads: one `ModelCall` with its whole projected history. */
|
|
30
|
-
export const MAX_MODEL_CALL_BYTES = 32 * 1024 * 1024;
|
|
31
|
-
export const ModelCallBodySchema = z.strictObject({
|
|
32
|
-
effectId: z.string().min(1),
|
|
33
|
-
invocationId: z.string().min(1),
|
|
34
|
-
call: z.looseObject({
|
|
35
|
-
prompt: z.array(z.unknown()),
|
|
36
|
-
tools: z.array(z.looseObject({ name: z.string() })),
|
|
37
|
-
}),
|
|
38
|
-
});
|
|
@@ -27,6 +27,13 @@ export interface EgressCredentials {
|
|
|
27
27
|
/** Tests: the port requests are sent to, instead of 443. */
|
|
28
28
|
readonly upstreamPort?: number;
|
|
29
29
|
}
|
|
30
|
+
/** The answer to a CONNECT the gate serves; a tunnel's byte counts leave it out. */
|
|
31
|
+
export declare const CONNECT_ESTABLISHED = "HTTP/1.1 200 Connection Established\r\n\r\n";
|
|
32
|
+
/** What one terminated connection did so far (R7.3): requests read, credentials set (ids). */
|
|
33
|
+
export interface EgressTally {
|
|
34
|
+
requests: number;
|
|
35
|
+
readonly credentialIds: Set<string>;
|
|
36
|
+
}
|
|
30
37
|
export interface CredentialTerminator {
|
|
31
38
|
/**
|
|
32
39
|
* Answers the CONNECT, terminates TLS for `host` and serves its requests, sending each to one
|
|
@@ -39,6 +46,8 @@ export interface CredentialTerminator {
|
|
|
39
46
|
address: string;
|
|
40
47
|
family: number;
|
|
41
48
|
}[];
|
|
49
|
+
/** Counted as requests are served, read when the connection closes. */
|
|
50
|
+
readonly tally: EgressTally;
|
|
42
51
|
}): Promise<void>;
|
|
43
52
|
}
|
|
44
53
|
export declare function credentialTerminator(options: {
|