@nylorun/runtime 0.17.0-beta → 0.19.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 +149 -0
- package/README.md +88 -58
- package/dist/adapters/execution/restate.d.ts +1 -3
- package/dist/adapters/execution/restate.js +4 -31
- package/dist/adapters/replication/pgoutput.js +1 -1
- package/dist/adapters/sandbox/local.js +1 -1
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/api/ag-ui/routes.js +1 -1
- package/dist/api/ag-ui/translate.d.ts +1 -3
- package/dist/api/ag-ui/translate.js +2 -17
- package/dist/api/components.d.ts +4871 -2614
- package/dist/api/components.js +12 -11
- package/dist/api/gate/routes.d.ts +7 -8
- package/dist/api/gate/routes.js +58 -52
- package/dist/api/http/app.d.ts +6 -0
- package/dist/api/http/app.js +18 -14
- package/dist/api/http/define.d.ts +14 -2
- package/dist/api/http/define.js +34 -15
- package/dist/api/http/routes/access.d.ts +3 -3
- package/dist/api/http/routes/access.js +18 -17
- package/dist/api/http/routes/artifacts.js +2 -4
- package/dist/api/http/routes/files.d.ts +8 -0
- package/dist/api/http/routes/files.js +77 -0
- package/dist/api/http/routes/keys.d.ts +10 -0
- package/dist/api/http/routes/keys.js +64 -0
- package/dist/api/http/routes/me.js +5 -2
- package/dist/api/http/routes/reads.d.ts +66 -0
- package/dist/api/http/routes/reads.js +127 -0
- package/dist/api/http/routes/sandboxes.js +7 -4
- package/dist/api/http/routes/sessions.js +25 -8
- package/dist/api/http/routes/tenant.js +15 -18
- package/dist/api/http/routes/vaults.d.ts +10 -9
- package/dist/api/http/routes/vaults.js +27 -23
- package/dist/api/openapi.d.ts +10 -11
- package/dist/api/openapi.js +291 -61
- package/dist/artifacts/links.js +1 -1
- package/dist/core/flow-host.d.ts +44 -23
- package/dist/core/flow-host.js +88 -106
- package/dist/core/provider.d.ts +4 -1
- package/dist/core/provider.js +6 -1
- package/dist/core/sandbox-routes.d.ts +0 -9
- package/dist/core/sandbox-routes.js +2 -21
- package/dist/execution/memory.d.ts +4 -5
- package/dist/execution/memory.js +11 -25
- package/dist/execution/types.d.ts +3 -33
- package/dist/execution/types.js +2 -12
- package/dist/gates/http-tool.d.ts +86 -0
- package/dist/gates/http-tool.js +197 -0
- package/dist/gates/mcp-handler.d.ts +3 -0
- package/dist/gates/mcp-handler.js +1 -3
- package/dist/gates/meter.d.ts +2 -2
- package/dist/gates/meter.js +6 -0
- package/dist/gates/tenant-vaults.d.ts +5 -9
- package/dist/gates/tool-calls.d.ts +7 -15
- package/dist/gates/tool-calls.js +4 -4
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +23 -47
- package/dist/gates/tool-contract.d.ts +27 -39
- package/dist/gates/tool-contract.js +30 -21
- package/dist/gates/tool-gate.d.ts +25 -24
- package/dist/gates/tool-gate.js +11 -7
- package/dist/harness/calls.d.ts +10 -4
- package/dist/harness/calls.js +15 -6
- package/dist/harness/executors.d.ts +1 -1
- package/dist/harness/executors.js +17 -12
- package/dist/harness/main.d.ts +2 -2
- package/dist/harness/main.js +5 -13
- package/dist/harness/service.d.ts +4 -5
- package/dist/harness/service.js +9 -2
- package/dist/harness-api/in-process.js +2 -2
- package/dist/harness-api/record.d.ts +6 -3
- package/dist/harness-api/record.js +65 -72
- package/dist/harness-api/server.d.ts +1 -9
- package/dist/harness-api/server.js +19 -17
- package/dist/harness-api/start.js +1 -5
- package/dist/harness-api/workspace.js +2 -3
- package/dist/harness-api/ws-server.js +1 -1
- package/dist/host/app.d.ts +2 -9
- package/dist/host/app.js +15 -25
- package/dist/host/config-for.d.ts +1 -5
- package/dist/host/config-for.js +0 -3
- package/dist/host/config.d.ts +0 -5
- package/dist/host/create-host.d.ts +3 -33
- package/dist/host/create-host.js +18 -94
- package/dist/host/environment.d.ts +0 -3
- package/dist/host/environment.js +0 -9
- package/dist/host/gates.d.ts +4 -1
- package/dist/host/gates.js +3 -2
- package/dist/host/http.d.ts +1 -2
- package/dist/host/http.js +1 -7
- package/dist/host/index.d.ts +2 -2
- package/dist/host/index.js +2 -2
- package/dist/host/main.js +27 -34
- package/dist/host/operate.d.ts +29 -0
- package/dist/host/operate.js +223 -0
- package/dist/host/stack-config.d.ts +12 -12
- package/dist/host/stack-config.js +5 -32
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/infra/workers.d.ts +1 -1
- package/dist/keys/keys.js +2 -2
- package/dist/management-openapi.json +6491 -0
- package/dist/mcp/connect.d.ts +8 -4
- package/dist/mcp/connect.js +6 -26
- package/dist/mcp/pool.d.ts +5 -9
- package/dist/mcp/pool.js +8 -19
- package/dist/mcp/snapshot.d.ts +8 -2
- package/dist/mcp/snapshot.js +29 -2
- package/dist/media.d.ts +1 -1
- package/dist/media.js +1 -1
- package/dist/model/pi-model.js +3 -0
- package/dist/openapi.json +4700 -12350
- package/dist/reads/access.d.ts +4 -0
- package/dist/reads/access.js +12 -0
- package/dist/reads/cursor.d.ts +11 -0
- package/dist/reads/cursor.js +80 -0
- package/dist/reads/types.d.ts +25 -0
- package/dist/reads/types.js +1 -0
- package/dist/sandbox/manager.d.ts +16 -0
- package/dist/sandbox/manager.js +40 -0
- package/dist/sandbox/session-sandbox.js +13 -3
- package/dist/sandbox/skills.d.ts +13 -0
- package/dist/sandbox/skills.js +46 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/ownership.d.ts +9 -0
- package/dist/store/ownership.js +13 -0
- package/dist/store/postgres/connect.d.ts +2 -0
- package/dist/store/postgres/connect.js +29 -0
- package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
- package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
- package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
- package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
- package/dist/store/postgres/reads.d.ts +3 -0
- package/dist/store/postgres/reads.js +272 -0
- package/dist/store/postgres/schema.d.ts +294 -489
- package/dist/store/postgres/schema.js +41 -76
- package/dist/store/postgres/store.js +51 -154
- package/dist/store/postgres/tenant.d.ts +34 -2
- package/dist/store/postgres/tenant.js +16 -32
- package/dist/store/types.d.ts +27 -96
- package/dist/store/types.js +0 -1
- package/dist/streams/control.d.ts +0 -2
- package/dist/streams/control.js +0 -5
- package/dist/streams/types.d.ts +1 -10
- package/dist/tenant/advance.d.ts +3 -3
- package/dist/tenant/advance.js +10 -7
- package/dist/tenant/auth.d.ts +14 -9
- package/dist/tenant/auth.js +24 -28
- package/dist/tenant/cause.d.ts +3 -3
- package/dist/tenant/cause.js +1 -1
- package/dist/tenant/commands.d.ts +2 -18
- package/dist/tenant/commands.js +35 -172
- package/dist/tenant/context.d.ts +14 -24
- package/dist/tenant/definition-files.d.ts +24 -0
- package/dist/tenant/definition-files.js +103 -0
- package/dist/tenant/effects.d.ts +18 -20
- package/dist/tenant/effects.js +56 -119
- package/dist/tenant/ephemeral.d.ts +7 -6
- package/dist/tenant/ephemeral.js +3 -11
- package/dist/tenant/host-token.js +1 -1
- package/dist/tenant/jwt.js +1 -1
- package/dist/tenant/module.d.ts +1 -4
- package/dist/tenant/module.js +3 -12
- package/dist/tenant/operator-keys.d.ts +34 -8
- package/dist/tenant/operator-keys.js +50 -18
- package/dist/tenant/outbound.d.ts +10 -1
- package/dist/tenant/outbound.js +44 -27
- package/dist/tenant/paths.d.ts +1 -1
- package/dist/tenant/paths.js +1 -3
- package/dist/tenant/principals.d.ts +11 -2
- package/dist/tenant/principals.js +27 -8
- package/dist/tenant/run-token.js +3 -3
- package/dist/tenant/runtime.d.ts +4 -6
- package/dist/tenant/runtime.js +19 -18
- package/dist/tenant/sandboxes.d.ts +4 -1
- package/dist/tenant/sandboxes.js +11 -0
- package/dist/tenant/scheduler.d.ts +1 -5
- package/dist/tenant/scheduler.js +2 -5
- package/dist/tenant/session-streams.d.ts +2 -1
- package/dist/tenant/session-streams.js +39 -5
- package/dist/tenant/session.d.ts +8 -41
- package/dist/tenant/session.js +0 -37
- package/dist/tenant/sessions.js +16 -8
- package/dist/tenant/signing-keys.d.ts +3 -3
- package/dist/tenant/signing-keys.js +5 -5
- package/dist/tenant/skill-tool.d.ts +20 -0
- package/dist/tenant/skill-tool.js +72 -0
- package/dist/tenant/slim.d.ts +1 -1
- package/dist/tenant/slim.js +1 -1
- package/dist/tenant/status.js +7 -12
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +7 -3
- package/dist/tenant/streams.d.ts +3 -10
- package/dist/tenant/streams.js +1 -24
- package/dist/tenant/sweep.js +0 -5
- package/dist/tenant/transcript.d.ts +2 -2
- package/dist/tenant/transcript.js +2 -2
- package/dist/tenant/types.d.ts +15 -22
- package/dist/tenant/worker.d.ts +1 -3
- package/dist/tenant/worker.js +3 -8
- package/dist/vault/sources.d.ts +7 -1
- package/dist/vault/sources.js +22 -11
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
- package/dist/admin-openapi.json +0 -904
- package/dist/api/http/routes/actions.d.ts +0 -8
- package/dist/api/http/routes/actions.js +0 -75
- package/dist/api/http/routes/endpoints.d.ts +0 -7
- package/dist/api/http/routes/endpoints.js +0 -100
- package/dist/host/admin-api.d.ts +0 -30
- package/dist/host/admin-api.js +0 -140
- package/dist/mcp/stdio.d.ts +0 -17
- package/dist/mcp/stdio.js +0 -82
- package/dist/tenant/actions.d.ts +0 -14
- package/dist/tenant/actions.js +0 -29
- package/dist/tenant/delivery-token.d.ts +0 -41
- package/dist/tenant/delivery-token.js +0 -104
- package/dist/tenant/delivery.d.ts +0 -62
- package/dist/tenant/delivery.js +0 -481
- package/dist/tenant/endpoints.d.ts +0 -67
- package/dist/tenant/endpoints.js +0 -90
package/dist/store/types.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* error `fn` threw.
|
|
15
15
|
* 2. **Session-scoped writes lock the session row first.** `lockSession` takes
|
|
16
16
|
* a row lock (`SELECT … FOR UPDATE`) held until the transaction ends. Effect
|
|
17
|
-
* intent and outcome,
|
|
17
|
+
* intent and outcome, checkpoint settlement and event
|
|
18
18
|
* writes for one session are serialized through it. Idempotency comparisons
|
|
19
19
|
* (`canonical(...)`) run inside the same locked transaction. `event` and the
|
|
20
20
|
* ownership methods take the lock themselves.
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* generation, `streams/basin.ts`), and the cursor is
|
|
26
26
|
* `base64url("<sessionId>:<seq>")` (see `record/cursor.ts`).
|
|
27
27
|
* 4. **No external I/O inside `fn`.** No model, tool, MCP, sandbox, Restate or
|
|
28
|
-
* S2 call, and no `fetch`, runs inside a transaction. Wakes
|
|
28
|
+
* S2 call, and no `fetch`, runs inside a transaction. Wakes go
|
|
29
29
|
* through `afterCommit`, and events are delivered to commit listeners after
|
|
30
30
|
* commit (seam rule 1 and 2).
|
|
31
31
|
* 5. **No nested transactions.** Calling `store.tx` from inside `fn` rejects.
|
|
@@ -45,29 +45,28 @@
|
|
|
45
45
|
* ## Typed queries, no scans
|
|
46
46
|
*
|
|
47
47
|
* There is no generic table scan. Every read the Runtime needs is a typed
|
|
48
|
-
* method on `Tx` (`sessionsWithStatus`, `
|
|
49
|
-
* `
|
|
50
|
-
*
|
|
48
|
+
* method on `Tx` (`sessionsWithStatus`, `effectsForTurn`, `linkedSessions`,
|
|
49
|
+
* `counts`, …) that an implementation can back with an index, and principals,
|
|
50
|
+
* vaults and Tenant settings
|
|
51
51
|
* have their own methods rather than raw SQL outside the store. Session history
|
|
52
52
|
* is not read from the store: every event is written to the record (Postgres
|
|
53
53
|
* `nylorun_streams.session_events`) in its transaction, the stream relay
|
|
54
54
|
* (`streams/relay/`) feeds Durable Streams from it, and history and SSE read
|
|
55
55
|
* them there (`tenant/session-streams.ts`).
|
|
56
56
|
*/
|
|
57
|
+
import type { KeyRole } from "@nylorun/core/compatibility";
|
|
57
58
|
import type { RecordReader } from "../streams/relay/types.js";
|
|
58
|
-
import type {
|
|
59
|
+
import type { EventPayload, EventType, LiveEvent, SandboxEvent, SandboxEventPayload, SandboxEventType, SandboxKind, SandboxPodDesired, SandboxPodObserved, SessionEventOf } from "@nylorun/core/contracts";
|
|
59
60
|
import type { SandboxManifest } from "@nylorun/core/define";
|
|
60
61
|
import type { HostEffect } from "@nylorun/harness/run";
|
|
61
|
-
import type { ArtifactRow, ArtifactVersionRow, ModelBudgetRow, ModelUsageRow, PrincipalRow, ToolCrossingRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow } from "./postgres/schema.js";
|
|
62
|
+
import type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, PrincipalRow, ToolCrossingRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow } from "./postgres/schema.js";
|
|
62
63
|
/** Tables holding JSON documents keyed by `id`. */
|
|
63
|
-
export type DocTable = "definitions" | "sessions" | "commands" | "effects" | "
|
|
64
|
+
export type DocTable = "definitions" | "sessions" | "commands" | "effects" | "sandboxes" | "links";
|
|
64
65
|
export declare const DOC_TABLES: readonly DocTable[];
|
|
65
66
|
/** Session lifecycle (architecture §10.2). */
|
|
66
67
|
export type SessionStatus = "idle" | "runnable" | "running" | "waiting" | "paused" | "uncertain" | "completed" | "failed" | "cancelled";
|
|
67
68
|
/** Effect states (§10.3), plus the flow host's `queued` and `cancelled`. */
|
|
68
69
|
export type EffectStatus = "pending" | "invoking" | "completed" | "uncertain" | "queued" | "cancelled";
|
|
69
|
-
export type ActionStatus = Action["status"];
|
|
70
|
-
export type ActionKind = Action["kind"];
|
|
71
70
|
export type EffectKind = HostEffect["kind"];
|
|
72
71
|
/**
|
|
73
72
|
* Ownership of a session by a Worker (§10.6). Read with the session; written
|
|
@@ -103,8 +102,6 @@ export interface EffectDoc {
|
|
|
103
102
|
request: HostEffect;
|
|
104
103
|
status: EffectStatus | (string & {});
|
|
105
104
|
}
|
|
106
|
-
/** Actions are stored as the wire `Action`. Indexed: `sessionId`, `turnId`, `agentId`, `status`, `kind`, `deadlineAt`. */
|
|
107
|
-
export type ActionDoc = Action;
|
|
108
105
|
/** A workflow → agent session link, keyed by the linked agent session id. Indexed: `workflowSessionId`. */
|
|
109
106
|
export interface LinkDoc {
|
|
110
107
|
workflowSessionId: string;
|
|
@@ -192,59 +189,13 @@ export interface BasinGenerations {
|
|
|
192
189
|
retired: number[];
|
|
193
190
|
}
|
|
194
191
|
export type CommitListener = (commit: Commit) => void;
|
|
195
|
-
/**
|
|
196
|
-
* An Action endpoint: the URL the Runtime delivers one agent's Actions to, and what recent
|
|
197
|
-
* deliveries and the last ping say about it.
|
|
198
|
-
*/
|
|
199
|
-
export interface EndpointRow {
|
|
200
|
-
agentId: string;
|
|
201
|
-
url: string;
|
|
202
|
-
implementationVersion: string;
|
|
203
|
-
manifestHash?: string;
|
|
204
|
-
timeoutMs: number;
|
|
205
|
-
maxConcurrent: number;
|
|
206
|
-
/** Application principal that registered it, when known. */
|
|
207
|
-
principalId?: string;
|
|
208
|
-
lastDeliveryAt?: string;
|
|
209
|
-
lastSuccessAt?: string;
|
|
210
|
-
lastErrorCode?: string;
|
|
211
|
-
lastErrorMessage?: string;
|
|
212
|
-
consecutiveFailures: number;
|
|
213
|
-
/** What the endpoint reported serving on the last ping. */
|
|
214
|
-
servedImplementationVersion?: string;
|
|
215
|
-
servedManifestHash?: string;
|
|
216
|
-
createdAt: string;
|
|
217
|
-
updatedAt: string;
|
|
218
|
-
}
|
|
219
|
-
/** The registration part of an endpoint, as `putEndpoint` writes it. */
|
|
220
|
-
export type EndpointRegistrationRow = Pick<EndpointRow, "agentId" | "url" | "implementationVersion" | "manifestHash" | "timeoutMs" | "maxConcurrent" | "principalId" | "updatedAt">;
|
|
221
|
-
/** One observation about an endpoint (`recordEndpointHealth`). */
|
|
222
|
-
export type EndpointHealthUpdate =
|
|
223
|
-
/** A delivery was answered. */
|
|
224
|
-
{
|
|
225
|
-
kind: "success";
|
|
226
|
-
at: string;
|
|
227
|
-
}
|
|
228
|
-
/** A delivery failed: not reached, refused, or lost. */
|
|
229
|
-
| {
|
|
230
|
-
kind: "failure";
|
|
231
|
-
at: string;
|
|
232
|
-
code: string;
|
|
233
|
-
message: string;
|
|
234
|
-
}
|
|
235
|
-
/** A ping was answered with what the endpoint serves. */
|
|
236
|
-
| {
|
|
237
|
-
kind: "served";
|
|
238
|
-
implementationVersion: string;
|
|
239
|
-
manifestHash?: string;
|
|
240
|
-
};
|
|
241
192
|
/**
|
|
242
193
|
* The rows of the typed tables, inferred from the tables Drizzle defines
|
|
243
194
|
* (`store/postgres/schema.ts`): a principal, a vault and its credentials (secrets sealed in
|
|
244
195
|
* `bytea` columns, never inside a JSON body), the vault's audit and idempotency records, the
|
|
245
196
|
* Tenant's signing keys, a model call in the usage ledger and a model budget.
|
|
246
197
|
*/
|
|
247
|
-
export type { ArtifactRow, ArtifactVersionRow, ModelBudgetRow, ModelUsageRow, ToolCrossingRow, PrincipalRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow, };
|
|
198
|
+
export type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, ToolCrossingRow, PrincipalRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, OAuthPendingRow, };
|
|
248
199
|
/** Which rows of the usage ledger a total covers. */
|
|
249
200
|
export interface ModelUsageQuery {
|
|
250
201
|
scope: "tenant" | "agent" | "turn";
|
|
@@ -265,18 +216,11 @@ export interface SessionEffectFilter {
|
|
|
265
216
|
turnId?: string;
|
|
266
217
|
statuses?: readonly (EffectStatus | (string & {}))[];
|
|
267
218
|
}
|
|
268
|
-
export interface SessionActionFilter {
|
|
269
|
-
/** Only this turn. Absent means every turn. */
|
|
270
|
-
turnId?: string;
|
|
271
|
-
statuses?: readonly ActionStatus[];
|
|
272
|
-
}
|
|
273
219
|
/** Counts used by Tenant status, `summary` and `drain`. */
|
|
274
220
|
export interface StoreCounts {
|
|
275
221
|
sessions: number;
|
|
276
222
|
/** Sessions `running` or `runnable`. */
|
|
277
223
|
runningSessions: number;
|
|
278
|
-
/** Actions `pending` or `delivering`. */
|
|
279
|
-
pendingActions: number;
|
|
280
224
|
/** Effects `uncertain`. */
|
|
281
225
|
uncertainEffects: number;
|
|
282
226
|
sandboxes: number;
|
|
@@ -439,18 +383,6 @@ export interface Tx {
|
|
|
439
383
|
fromSeq?: number;
|
|
440
384
|
limit?: number;
|
|
441
385
|
}): Promise<SandboxEvent[]>;
|
|
442
|
-
/** One agent's `pending` actions, delivered when its endpoint is registered. */
|
|
443
|
-
pendingActions(agentId: string): Promise<ActionDoc[]>;
|
|
444
|
-
/** How many of one agent's actions are `delivering` (Action endpoints). */
|
|
445
|
-
deliveringCount(agentId: string): Promise<number>;
|
|
446
|
-
/** `pending` actions of agents that have an Action endpoint, by id. */
|
|
447
|
-
pendingActionsWithEndpoint(limit: number): Promise<ActionDoc[]>;
|
|
448
|
-
/** `delivering` actions whose deadline is at or before `now`, earliest first. */
|
|
449
|
-
expiredDeliveries(now: Date, limit: number): Promise<ActionDoc[]>;
|
|
450
|
-
actionsForSession(sessionId: string, filter?: SessionActionFilter): Promise<ActionDoc[]>;
|
|
451
|
-
actionsWithStatus(statuses: readonly ActionStatus[], filter?: {
|
|
452
|
-
kinds?: readonly ActionKind[];
|
|
453
|
-
}): Promise<ActionDoc[]>;
|
|
454
386
|
/** `invoking` effects of one session; takeover turns them `uncertain`. */
|
|
455
387
|
invokingEffects<T extends EffectDoc = EffectDoc>(sessionId: string): Promise<T[]>;
|
|
456
388
|
effectsForSession<T extends EffectDoc = EffectDoc>(sessionId: string, filter?: SessionEffectFilter): Promise<T[]>;
|
|
@@ -464,29 +396,19 @@ export interface Tx {
|
|
|
464
396
|
basinGenerations(): Promise<BasinGenerations>;
|
|
465
397
|
/** Forgets a retired generation once its basin is deleted. */
|
|
466
398
|
forgetRetiredGeneration(generation: number): Promise<void>;
|
|
467
|
-
listEndpoints(): Promise<EndpointRow[]>;
|
|
468
|
-
getEndpoint(agentId: string): Promise<EndpointRow | undefined>;
|
|
469
|
-
/**
|
|
470
|
-
* Inserts or updates by `agentId`, keeping `createdAt`. Health is kept, except that a new
|
|
471
|
-
* `url` starts with none.
|
|
472
|
-
*/
|
|
473
|
-
putEndpoint(row: EndpointRegistrationRow): Promise<void>;
|
|
474
|
-
deleteEndpoint(agentId: string): Promise<void>;
|
|
475
|
-
/** Records one observation. Nothing happens when the endpoint does not exist. */
|
|
476
|
-
recordEndpointHealth(agentId: string, update: EndpointHealthUpdate): Promise<void>;
|
|
477
399
|
/** Rejects when the id or token hash already exists. */
|
|
478
400
|
insertPrincipal(row: PrincipalRow): Promise<void>;
|
|
479
401
|
principalByTokenHash(tokenHash: string): Promise<PrincipalRow | undefined>;
|
|
480
402
|
principalById(id: string): Promise<PrincipalRow | undefined>;
|
|
481
|
-
applicationTokenHashes(): Promise<string[]>;
|
|
482
403
|
/** Every principal, ordered by id. */
|
|
483
404
|
listPrincipals(): Promise<PrincipalRow[]>;
|
|
484
405
|
/**
|
|
485
|
-
* Creates
|
|
486
|
-
* (and `createdAt`): its previous key stops authenticating. Rejects
|
|
487
|
-
* holds the hash
|
|
406
|
+
* Creates principal `id` with `tokenHash` and `role` (default `application`), or gives an
|
|
407
|
+
* existing one this hash (and `createdAt`): its previous key stops authenticating. Rejects
|
|
408
|
+
* when another principal holds the hash, and with `PrincipalRoleConflict` when `id` holds
|
|
409
|
+
* another role.
|
|
488
410
|
*/
|
|
489
|
-
putPrincipal(id: string, tokenHash: string, createdAt: string): Promise<PrincipalRow>;
|
|
411
|
+
putPrincipal(id: string, tokenHash: string, createdAt: string, role?: KeyRole): Promise<PrincipalRow>;
|
|
490
412
|
/** Deletes principal `id`; false when there was none. */
|
|
491
413
|
deletePrincipal(id: string): Promise<boolean>;
|
|
492
414
|
/** Rejects on a duplicate id, or a second `host` vault. */
|
|
@@ -545,7 +467,7 @@ export interface Tx {
|
|
|
545
467
|
setSigningKeyState(id: string, from: SigningKeyRow["state"], to: SigningKeyRow["state"], at: string): Promise<boolean>;
|
|
546
468
|
countSigningKeys(): Promise<number>;
|
|
547
469
|
/** Appends a row, setting `duplicate` when one with the same `effectKey` exists; returns it. */
|
|
548
|
-
recordModelUsage(row:
|
|
470
|
+
recordModelUsage(row: ModelUsageWrite): Promise<ModelUsageRow>;
|
|
549
471
|
modelUsageTotals(query: ModelUsageQuery): Promise<ModelUsageTotals>;
|
|
550
472
|
/** Every budget, ordered by scope, then scope id. */
|
|
551
473
|
listModelBudgets(): Promise<ModelBudgetRow[]>;
|
|
@@ -607,16 +529,25 @@ export interface Tx {
|
|
|
607
529
|
artifactContentShas(scope: "sessions" | "all" | {
|
|
608
530
|
artifactId: string;
|
|
609
531
|
}): Promise<string[]>;
|
|
532
|
+
/** The definition file `sha256` (`sha256:<hex>`) names, once its bytes are stored. */
|
|
533
|
+
definitionFile(sha256: string): Promise<DefinitionFileRow | undefined>;
|
|
534
|
+
/** Records a stored definition file; false when the Tenant held it already. */
|
|
535
|
+
insertDefinitionFile(row: DefinitionFileRow): Promise<boolean>;
|
|
536
|
+
/** Those of `shas` the Tenant holds. */
|
|
537
|
+
heldDefinitionFiles(shas: readonly string[]): Promise<Set<string>>;
|
|
538
|
+
/** Records that version `manifestHash` of definition `agentId` names each of `shas`. */
|
|
539
|
+
insertDefinitionFileUses(agentId: string, manifestHash: string, shas: readonly string[]): Promise<void>;
|
|
610
540
|
getSetting(key: string): Promise<string | undefined>;
|
|
611
541
|
putSetting(key: string, value: string): Promise<void>;
|
|
612
542
|
/**
|
|
613
543
|
* Deletes Tenant state by scope, in this transaction:
|
|
614
|
-
* - `sessions`: sessions, commands, effects,
|
|
544
|
+
* - `sessions`: sessions, commands, effects, links, the artifacts of sessions (their blobs are the caller's to delete) and the
|
|
615
545
|
* Tenant's record rows and log heads. The Tenant moves to the next basin
|
|
616
546
|
* generation and the current one is retired, so session ids it frees start again in an
|
|
617
547
|
* empty basin;
|
|
618
548
|
* - `sandboxes`: sandbox records, sandbox resources and their lifecycle streams;
|
|
619
|
-
* - `all`: both, plus definitions
|
|
549
|
+
* - `all`: both, plus definitions (and which definition files they use),
|
|
550
|
+
* user vaults with their credentials,
|
|
620
551
|
* the model usage ledger, the model budgets and Tenant-wide artifacts. The host vault, principals, signing keys,
|
|
621
552
|
* settings, audit and vault idempotency rows stay.
|
|
622
553
|
*/
|
package/dist/store/types.js
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
import { type DurableStreams } from "./types.js";
|
|
7
7
|
/** Appends a `session.cancel` signal: the process running the session's advance aborts it. */
|
|
8
8
|
export declare function signalCancel(streams: DurableStreams, basin: string, sessionId: string, turnId?: string): Promise<void>;
|
|
9
|
-
/** Appends an `action.resolved` signal: a run held for the Action goes on with its outcome. */
|
|
10
|
-
export declare function signalActionResolved(streams: DurableStreams, basin: string, sessionId: string, actionId: string): Promise<void>;
|
|
11
9
|
/**
|
|
12
10
|
* Appends a `sessions.reset` signal to the old generation's basin: every process with the
|
|
13
11
|
* Tenant open moves its readers to `generation` and ends the streams of deleted sessions.
|
package/dist/streams/control.js
CHANGED
|
@@ -15,11 +15,6 @@ export async function signalCancel(streams, basin, sessionId, turnId) {
|
|
|
15
15
|
};
|
|
16
16
|
await streams.append(basin, CONTROL_STREAM, [signal]);
|
|
17
17
|
}
|
|
18
|
-
/** Appends an `action.resolved` signal: a run held for the Action goes on with its outcome. */
|
|
19
|
-
export async function signalActionResolved(streams, basin, sessionId, actionId) {
|
|
20
|
-
const signal = { type: "action.resolved", sessionId, actionId };
|
|
21
|
-
await streams.append(basin, CONTROL_STREAM, [signal]);
|
|
22
|
-
}
|
|
23
18
|
/**
|
|
24
19
|
* Appends a `sessions.reset` signal to the old generation's basin: every process with the
|
|
25
20
|
* Tenant open moves its readers to `generation` and ends the streams of deleted sessions.
|
package/dist/streams/types.d.ts
CHANGED
|
@@ -138,13 +138,4 @@ export interface SessionsResetSignal {
|
|
|
138
138
|
type: "sessions.reset";
|
|
139
139
|
generation?: number;
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
* An Action of `sessionId` has its outcome (F6.2): the process whose harness holds the
|
|
143
|
-
* session's run while the Action is pending passes it on (`effect.resolved`).
|
|
144
|
-
*/
|
|
145
|
-
export interface ActionResolvedSignal {
|
|
146
|
-
type: "action.resolved";
|
|
147
|
-
sessionId: string;
|
|
148
|
-
actionId: string;
|
|
149
|
-
}
|
|
150
|
-
export type ControlSignal = SessionCancelSignal | SessionsResetSignal | ActionResolvedSignal;
|
|
141
|
+
export type ControlSignal = SessionCancelSignal | SessionsResetSignal;
|
package/dist/tenant/advance.d.ts
CHANGED
|
@@ -9,12 +9,12 @@ export declare function advance(ctx: TenantContext, id: string, signal: AbortSig
|
|
|
9
9
|
/**
|
|
10
10
|
* Takeover (§10.5 step 2, §11.4), inside the transaction that took ownership: the dead
|
|
11
11
|
* owner's `invoking` effects become `uncertain` and are never invoked again, except model
|
|
12
|
-
* calls when the gate recovers them (P1.2) and remote MCP calls when the Tool
|
|
13
|
-
* G3): those stay `invoking`, and the replay re-sends them. When one belongs
|
|
12
|
+
* calls when the gate recovers them (P1.2) and remote MCP and HTTP tool calls when the Tool
|
|
13
|
+
* Gate does (F4.1 G3): those stay `invoking`, and the replay re-sends them. When one belongs
|
|
14
14
|
* to the active turn, the session becomes `uncertain` too, with an `effect.uncertain` event.
|
|
15
15
|
* Mutates and writes `s`. Returns the effect ids it marked.
|
|
16
16
|
*/
|
|
17
17
|
export declare function takeOver(t: Tx, s: Session, options?: {
|
|
18
18
|
recoversModelCalls?: boolean;
|
|
19
|
-
|
|
19
|
+
recoversToolCalls?: boolean;
|
|
20
20
|
}): Promise<string[]>;
|
package/dist/tenant/advance.js
CHANGED
|
@@ -42,8 +42,7 @@
|
|
|
42
42
|
import { runDurable, runFlowDurable, } from "@nylorun/harness/run";
|
|
43
43
|
import { aggregateWaits, cancelSiblingWork, isWorkflowManifest, wakeLinkedWorkflow, } from "../core/flow-host.js";
|
|
44
44
|
import { isOwnershipLost, ownedTx } from "../store/ownership.js";
|
|
45
|
-
import {
|
|
46
|
-
import { isRemoteMcpEffect, recoversMcpCalls, recoversModelCalls } from "./effects.js";
|
|
45
|
+
import { isGateToolEffect, recoversModelCalls, recoversToolCalls } from "./effects.js";
|
|
47
46
|
import { slimModelEffects } from "./slim.js";
|
|
48
47
|
import { applyUpdates, leanState, transcriptShadow, withTranscript, } from "./history.js";
|
|
49
48
|
import { command } from "./commands.js";
|
|
@@ -232,7 +231,7 @@ async function takeOwnership(ctx, id) {
|
|
|
232
231
|
if (taken.takeover)
|
|
233
232
|
await takeOver(t, s, {
|
|
234
233
|
recoversModelCalls: recoversModelCalls(ctx),
|
|
235
|
-
|
|
234
|
+
recoversToolCalls: recoversToolCalls(ctx),
|
|
236
235
|
});
|
|
237
236
|
if (!s.checkpoint || !["running", "runnable"].includes(s.status)) {
|
|
238
237
|
await t.releaseOwnership(id, lease.owner, lease.epoch);
|
|
@@ -246,8 +245,8 @@ async function takeOwnership(ctx, id) {
|
|
|
246
245
|
/**
|
|
247
246
|
* Takeover (§10.5 step 2, §11.4), inside the transaction that took ownership: the dead
|
|
248
247
|
* owner's `invoking` effects become `uncertain` and are never invoked again, except model
|
|
249
|
-
* calls when the gate recovers them (P1.2) and remote MCP calls when the Tool
|
|
250
|
-
* G3): those stay `invoking`, and the replay re-sends them. When one belongs
|
|
248
|
+
* calls when the gate recovers them (P1.2) and remote MCP and HTTP tool calls when the Tool
|
|
249
|
+
* Gate does (F4.1 G3): those stay `invoking`, and the replay re-sends them. When one belongs
|
|
251
250
|
* to the active turn, the session becomes `uncertain` too, with an `effect.uncertain` event.
|
|
252
251
|
* Mutates and writes `s`. Returns the effect ids it marked.
|
|
253
252
|
*/
|
|
@@ -257,7 +256,7 @@ export async function takeOver(t, s, options = {}) {
|
|
|
257
256
|
// Still running at the gate, or finished there: the replay re-sends it (P1.2).
|
|
258
257
|
if (options.recoversModelCalls && effect.request.kind === "model")
|
|
259
258
|
continue;
|
|
260
|
-
if (options.
|
|
259
|
+
if (options.recoversToolCalls && isGateToolEffect(s, effect.request))
|
|
261
260
|
continue;
|
|
262
261
|
effect.status = "uncertain";
|
|
263
262
|
effect.error ??= "The Worker running this effect stopped before its outcome was recorded";
|
|
@@ -390,7 +389,7 @@ async function wakeWorkflowOf(ctx, t, agent, turnId, type, payload) {
|
|
|
390
389
|
agentSessionId: agent.id,
|
|
391
390
|
turnId,
|
|
392
391
|
output: type === "turn.completed"
|
|
393
|
-
?
|
|
392
|
+
? payload.output ?? null
|
|
394
393
|
: undefined,
|
|
395
394
|
failed: type === "turn.failed",
|
|
396
395
|
error: type === "turn.failed"
|
|
@@ -526,9 +525,13 @@ async function settle(ctx, lease, s, result, updates = [], cursor) {
|
|
|
526
525
|
? {
|
|
527
526
|
interactions: (result.result.pending ?? []).map((call) => ({
|
|
528
527
|
invocationId: call.invocationId,
|
|
528
|
+
...(typeof call.callId === "string" ? { callId: call.callId } : {}),
|
|
529
529
|
interaction: call.interaction,
|
|
530
530
|
wait: call.wait,
|
|
531
531
|
status: call.status,
|
|
532
|
+
// A flow's tool node that asked.
|
|
533
|
+
...(typeof call.path === "string" ? { path: call.path } : {}),
|
|
534
|
+
...(typeof call.toolName === "string" ? { toolName: call.toolName } : {}),
|
|
532
535
|
})),
|
|
533
536
|
}
|
|
534
537
|
: result.status === "failed"
|
package/dist/tenant/auth.d.ts
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tenant request authentication and authorization: a bearer token resolves to an application
|
|
3
|
-
* principal
|
|
3
|
+
* principal or a trusted issuer's token; anything else is the opaque 404
|
|
4
4
|
* (D5). An application principal may act for a subject (`Nylorun-Subject`, `Nylorun-Scopes`);
|
|
5
5
|
* an issuer token names its subject itself. `requireScopes` limits them to the routes their
|
|
6
6
|
* scopes allow, decided from the route alone.
|
|
7
7
|
*
|
|
8
8
|
* Browsers: a request with `Origin` may carry an issuer token (CORS is the operator's proxy's),
|
|
9
|
-
* never an application key
|
|
9
|
+
* never an application key, which is a server secret.
|
|
10
10
|
*/
|
|
11
11
|
import type { IncomingMessage } from "node:http";
|
|
12
|
-
import { type
|
|
12
|
+
import { type SubjectScope } from "@nylorun/core/contracts";
|
|
13
13
|
import type { AuthScope, SessionAccess, TenantContext } from "./context.js";
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Which keys a route takes (protocol 8): an application key (alone or acting for a subject) on
|
|
16
|
+
* the Runtime API, a management key on the Management API. `/v1/me` takes both.
|
|
17
|
+
*/
|
|
18
|
+
export interface KeyAccess {
|
|
19
|
+
readonly application: boolean;
|
|
20
|
+
readonly management: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Every route that does not say otherwise is a Runtime API route. */
|
|
23
|
+
export declare const RUNTIME_KEYS: KeyAccess;
|
|
24
|
+
export declare function authenticate(ctx: TenantContext, request: IncomingMessage, keys?: KeyAccess): Promise<AuthScope>;
|
|
15
25
|
/**
|
|
16
26
|
* What a subject needs for a route: any one of the scopes, nothing grants it (`never`), or
|
|
17
27
|
* any caller may (`any`, public data such as the JWKS). Each route declares it
|
|
@@ -28,11 +38,6 @@ export declare function accessOf(scope: AuthScope): SessionAccess | undefined;
|
|
|
28
38
|
export declare function ownerOf(scope: AuthScope): string | undefined;
|
|
29
39
|
/** The application principal behind the request, acting for a subject or not. */
|
|
30
40
|
export declare function requirePrincipal(scope: AuthScope): string;
|
|
31
|
-
/**
|
|
32
|
-
* The caller may act on `action`: only the delivery token minted for it. Whether its generation
|
|
33
|
-
* is still the Action's is checked by each callback.
|
|
34
|
-
*/
|
|
35
|
-
export declare function scoped(scope: AuthScope, action: Action): void;
|
|
36
41
|
/** True when a token caller may reach `agentId` (its issuer's allowlist). Other callers always may. */
|
|
37
42
|
export declare function mayUseAgent(scope: AuthScope, agentId: string): boolean;
|
|
38
43
|
export declare function requireApplication(scope: AuthScope): string;
|
package/dist/tenant/auth.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { SCOPES_HEADER, SUBJECT_HEADER, } from "@nylorun/core/compatibility";
|
|
2
|
-
import {
|
|
2
|
+
import { parseSubjectHeaders } from "@nylorun/core/contracts";
|
|
3
3
|
import { hashToken } from "../core/bearer.js";
|
|
4
4
|
import { fail, failOpaque } from "./http.js";
|
|
5
|
-
import { verifyDeliveryToken } from "./delivery-token.js";
|
|
6
5
|
import { verifyIssuerToken } from "./issuers.js";
|
|
7
|
-
import { looksLikeToken
|
|
6
|
+
import { looksLikeToken } from "./jwt.js";
|
|
8
7
|
const SUBJECT_INVALID = { code: "subject_invalid" };
|
|
9
8
|
/** One header's value, or `undefined`; a header sent twice is refused. */
|
|
10
9
|
function singleHeader(request, name) {
|
|
@@ -17,7 +16,9 @@ function singleHeader(request, name) {
|
|
|
17
16
|
return fail(400, `${name} must be sent once`, SUBJECT_INVALID);
|
|
18
17
|
return values[0];
|
|
19
18
|
}
|
|
20
|
-
|
|
19
|
+
/** Every route that does not say otherwise is a Runtime API route. */
|
|
20
|
+
export const RUNTIME_KEYS = { application: true, management: false };
|
|
21
|
+
export async function authenticate(ctx, request, keys = RUNTIME_KEYS) {
|
|
21
22
|
const header = request.headers.authorization;
|
|
22
23
|
const token = header?.startsWith("Bearer ") ? header.slice(7) : "";
|
|
23
24
|
if (!token || !header?.startsWith("Bearer ")) {
|
|
@@ -26,16 +27,6 @@ export async function authenticate(ctx, request) {
|
|
|
26
27
|
});
|
|
27
28
|
return failOpaque();
|
|
28
29
|
}
|
|
29
|
-
if (looksLikeToken(token) && tokenType(token) === DELIVERY_TOKEN_TYPE) {
|
|
30
|
-
// Delivery tokens come back from the application's server, never from a browser.
|
|
31
|
-
if (request.headers.origin !== undefined)
|
|
32
|
-
fail(403, "Delivery tokens are not accepted from browsers", { code: "origin_rejected" });
|
|
33
|
-
const scope = await verifyDeliveryToken(ctx, token);
|
|
34
|
-
if (singleHeader(request, SUBJECT_HEADER) !== undefined ||
|
|
35
|
-
singleHeader(request, SCOPES_HEADER) !== undefined)
|
|
36
|
-
fail(403, "A delivery token cannot act for a subject");
|
|
37
|
-
return scope;
|
|
38
|
-
}
|
|
39
30
|
// A trusted issuer's token (Host feature `trusted-issuers`), from a server or a browser: its
|
|
40
31
|
// unverified `iss` names an issuer of the identity file, and only that issuer verifies it.
|
|
41
32
|
const issuer = ctx.config.issuers?.claimed(token);
|
|
@@ -68,6 +59,22 @@ export async function authenticate(ctx, request) {
|
|
|
68
59
|
// Read only after authentication, so an unknown caller sees the opaque 404 either way.
|
|
69
60
|
const subject = singleHeader(request, SUBJECT_HEADER);
|
|
70
61
|
const scopes = singleHeader(request, SCOPES_HEADER);
|
|
62
|
+
// A management key acts as itself on the Management API; Studio's key does too on a route
|
|
63
|
+
// that takes no application key. Neither acts for a subject there.
|
|
64
|
+
const asManagement = principal.role === "management" || (principal.role === "studio" && !keys.application);
|
|
65
|
+
if (asManagement) {
|
|
66
|
+
if (!keys.management)
|
|
67
|
+
fail(403, "A management key reaches only the Management API (/v1/tenant/*)", {
|
|
68
|
+
code: "key_role_mismatch",
|
|
69
|
+
});
|
|
70
|
+
if (subject !== undefined || scopes !== undefined)
|
|
71
|
+
fail(403, "A management key acts as itself, never for a subject", SUBJECT_INVALID);
|
|
72
|
+
return { kind: "management", principalId: principal.id };
|
|
73
|
+
}
|
|
74
|
+
if (!keys.application)
|
|
75
|
+
fail(403, "This is the Management API: it takes a management key, not an application key", {
|
|
76
|
+
code: "key_role_mismatch",
|
|
77
|
+
});
|
|
71
78
|
if (subject === undefined) {
|
|
72
79
|
if (scopes !== undefined)
|
|
73
80
|
fail(400, `${SCOPES_HEADER} requires ${SUBJECT_HEADER}`, SUBJECT_INVALID);
|
|
@@ -108,6 +115,9 @@ export function accessOf(scope) {
|
|
|
108
115
|
switch (scope.kind) {
|
|
109
116
|
case "application":
|
|
110
117
|
return undefined;
|
|
118
|
+
// A management key reaches the Management API only: no session is its.
|
|
119
|
+
case "management":
|
|
120
|
+
return fail(404, "Not found");
|
|
111
121
|
case "subject":
|
|
112
122
|
return { owner: scope.subject };
|
|
113
123
|
case "token":
|
|
@@ -118,9 +128,6 @@ export function accessOf(scope) {
|
|
|
118
128
|
// A request with no credential, on a route that serves public data, owns nothing.
|
|
119
129
|
case "anonymous":
|
|
120
130
|
return fail(404, "Not found");
|
|
121
|
-
// A delivery token reaches its Action's callbacks, never a session or vault.
|
|
122
|
-
case "delivery":
|
|
123
|
-
return fail(404, "Not found");
|
|
124
131
|
default: {
|
|
125
132
|
const unknown = scope;
|
|
126
133
|
return fail(404, `Unknown credential ${String(unknown.kind)}`);
|
|
@@ -137,17 +144,6 @@ export function requirePrincipal(scope) {
|
|
|
137
144
|
return scope.principalId;
|
|
138
145
|
return fail(403, "Application credential required");
|
|
139
146
|
}
|
|
140
|
-
/**
|
|
141
|
-
* The caller may act on `action`: only the delivery token minted for it. Whether its generation
|
|
142
|
-
* is still the Action's is checked by each callback.
|
|
143
|
-
*/
|
|
144
|
-
export function scoped(scope, action) {
|
|
145
|
-
if (scope.kind === "delivery" &&
|
|
146
|
-
scope.actionId === action.actionId &&
|
|
147
|
-
scope.agentId === action.agentId)
|
|
148
|
-
return;
|
|
149
|
-
fail(403, "This delivery token is for another Action");
|
|
150
|
-
}
|
|
151
147
|
/** True when a token caller may reach `agentId` (its issuer's allowlist). Other callers always may. */
|
|
152
148
|
export function mayUseAgent(scope, agentId) {
|
|
153
149
|
return scope.kind !== "token" || scope.agents === "*" || scope.agents.has(agentId);
|
package/dist/tenant/cause.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Why the Host's Tenant could not be opened (tenancy.md §5). A cause is about the Tenant's
|
|
3
3
|
* own data or files (its database is newer than this Runtime, its vault key is missing, the
|
|
4
|
-
* database has an old layout): the Host fails readiness, names the cause in
|
|
5
|
-
*
|
|
4
|
+
* database has an old layout): the Host fails readiness, names the cause in the logs (and
|
|
5
|
+
* `nylorun-operate status` reads it from the database), and answers Tenant requests with the opaque 404 until it is
|
|
6
6
|
* repaired and the Host restarted. A failure outside the Tenant (Postgres unreachable) is not
|
|
7
7
|
* a cause: it is `TenantUnavailableError`, and the next request tries again.
|
|
8
8
|
*/
|
|
@@ -12,7 +12,7 @@ export type { TenantCause };
|
|
|
12
12
|
export declare class TenantOpenError extends Error {
|
|
13
13
|
readonly code: TenantCause["code"];
|
|
14
14
|
readonly repair: string;
|
|
15
|
-
/** The Tenant, when it was read before opening failed
|
|
15
|
+
/** The Tenant, when it was read before opening failed. */
|
|
16
16
|
envelope?: TenantEnvelope;
|
|
17
17
|
constructor(fields: TenantCause);
|
|
18
18
|
toCause(): TenantCause;
|
package/dist/tenant/cause.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export class TenantOpenError extends Error {
|
|
3
3
|
code;
|
|
4
4
|
repair;
|
|
5
|
-
/** The Tenant, when it was read before opening failed
|
|
5
|
+
/** The Tenant, when it was read before opening failed. */
|
|
6
6
|
envelope;
|
|
7
7
|
constructor(fields) {
|
|
8
8
|
super(fields.message);
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type
|
|
3
|
-
import { type AuthScope, type Session, type TenantContext } from "./context.js";
|
|
4
|
-
/** `outcome`, or a failed one when a tool's output does not match its stored output schema. */
|
|
5
|
-
export declare function acceptedOutcome(action: Action, outcome: ActionOutcome): ActionOutcome;
|
|
1
|
+
import type { SessionCommand } from "@nylorun/core/contracts";
|
|
2
|
+
import { type AuthScope, type TenantContext } from "./context.js";
|
|
6
3
|
export declare function command(ctx: TenantContext, id: string, input: SessionCommand, scope: AuthScope): Promise<unknown>;
|
|
7
|
-
/**
|
|
8
|
-
* Completes a delivered Action with `outcome`, in the caller's transaction, which
|
|
9
|
-
* holds the lock of the Action's session `s`: the Action and its effect, the
|
|
10
|
-
* `action.completed` event (and `loop.verified` or `loop.decided`), the wake that resumes the
|
|
11
|
-
* turn, and queued workflow effects. The Action deliverer and the background-result callback
|
|
12
|
-
* both record outcomes here. It sets `s.status`; the caller writes `s`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function recordActionOutcome(t: Tx, ctx: TenantContext, s: Session, action: Action, received: ActionOutcome, options?: {
|
|
15
|
-
requestId?: string;
|
|
16
|
-
}): Promise<{
|
|
17
|
-
event: LiveEvent;
|
|
18
|
-
receipt: Record<string, unknown>;
|
|
19
|
-
}>;
|