@nylorun/runtime 0.15.2-beta → 0.17.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 +134 -0
- package/README.md +68 -29
- package/dist/adapters/execution/restate.d.ts +9 -1
- package/dist/adapters/execution/restate.js +64 -5
- package/dist/adapters/sandbox/local.d.ts +10 -0
- package/dist/adapters/sandbox/local.js +195 -0
- package/dist/adapters/sandbox/virtual.js +36 -1
- package/dist/admin-openapi.json +341 -7
- package/dist/api/a2a/tasks.js +6 -1
- package/dist/api/ag-ui/endpoint.js +1 -2
- package/dist/api/ag-ui/history.js +6 -1
- package/dist/api/ag-ui/routes.d.ts +1 -1
- package/dist/api/ag-ui/routes.js +15 -13
- package/dist/api/components.d.ts +2667 -711
- package/dist/api/components.js +24 -11
- package/dist/api/gate/keys.d.ts +4 -3
- package/dist/api/gate/routes.d.ts +19 -3
- package/dist/api/gate/routes.js +162 -53
- package/dist/api/http/app.js +6 -0
- package/dist/api/http/define.d.ts +19 -12
- package/dist/api/http/define.js +13 -27
- package/dist/api/http/routes/access.d.ts +3 -19
- package/dist/api/http/routes/access.js +12 -172
- package/dist/api/http/routes/actions.js +0 -1
- package/dist/api/http/routes/artifacts.d.ts +11 -0
- package/dist/api/http/routes/artifacts.js +516 -0
- package/dist/api/http/routes/me.d.ts +13 -0
- package/dist/api/http/routes/me.js +45 -0
- package/dist/api/http/routes/sandboxes.d.ts +9 -0
- package/dist/api/http/routes/sandboxes.js +150 -0
- package/dist/api/http/routes/sessions.js +9 -13
- package/dist/api/http/routes/tenant.js +36 -2
- package/dist/api/http/routes/vaults.d.ts +12 -3
- package/dist/api/http/routes/vaults.js +122 -54
- package/dist/api/openapi.js +4 -10
- package/dist/artifacts/config.d.ts +23 -0
- package/dist/artifacts/config.js +27 -0
- package/dist/artifacts/export.d.ts +8 -0
- package/dist/artifacts/export.js +205 -0
- package/dist/artifacts/files.d.ts +36 -0
- package/dist/artifacts/files.js +45 -0
- package/dist/artifacts/folders.d.ts +60 -0
- package/dist/artifacts/folders.js +209 -0
- package/dist/artifacts/links.d.ts +28 -0
- package/dist/artifacts/links.js +92 -0
- package/dist/artifacts/media-types.d.ts +13 -0
- package/dist/artifacts/media-types.js +80 -0
- package/dist/artifacts/parts.d.ts +34 -0
- package/dist/artifacts/parts.js +38 -0
- package/dist/artifacts/service.d.ts +74 -0
- package/dist/artifacts/service.js +301 -0
- package/dist/artifacts/workspace.d.ts +60 -0
- package/dist/artifacts/workspace.js +57 -0
- package/dist/artifacts/zip.d.ts +10 -0
- package/dist/artifacts/zip.js +126 -0
- package/dist/blob/fs.d.ts +13 -0
- package/dist/blob/fs.js +194 -0
- package/dist/blob/index.d.ts +9 -0
- package/dist/blob/index.js +9 -0
- package/dist/blob/s3.d.ts +42 -0
- package/dist/blob/s3.js +366 -0
- package/dist/blob/types.d.ts +108 -0
- package/dist/blob/types.js +85 -0
- package/dist/core/sandbox-routes.d.ts +2 -2
- package/dist/core/sandbox-routes.js +4 -3
- package/dist/execution/memory.d.ts +11 -1
- package/dist/execution/memory.js +77 -3
- package/dist/execution/types.d.ts +54 -1
- package/dist/execution/types.js +31 -0
- package/dist/gates/contract.d.ts +14 -13
- package/dist/gates/contract.js +13 -12
- package/dist/gates/egress.d.ts +72 -0
- package/dist/gates/egress.js +319 -0
- package/dist/gates/handler.d.ts +3 -0
- package/dist/gates/handler.js +3 -2
- package/dist/gates/http-client.d.ts +3 -2
- package/dist/gates/http-client.js +17 -6
- package/dist/gates/in-process.d.ts +13 -1
- package/dist/gates/in-process.js +11 -0
- package/dist/gates/inflight.d.ts +23 -4
- package/dist/gates/inflight.js +18 -4
- package/dist/gates/mcp-handler.js +5 -1
- package/dist/gates/model-gate.d.ts +6 -2
- package/dist/gates/tenant-vaults.d.ts +18 -9
- package/dist/gates/tenant-vaults.js +17 -12
- package/dist/gates/tool-calls.d.ts +9 -5
- package/dist/gates/tool-calls.js +6 -6
- package/dist/gates/tool-client.d.ts +9 -2
- package/dist/gates/tool-client.js +56 -22
- package/dist/gates/tool-contract.d.ts +12 -7
- package/dist/gates/tool-contract.js +10 -4
- package/dist/gates/tool-gate.d.ts +1 -0
- package/dist/harness/calls.d.ts +52 -0
- package/dist/harness/calls.js +113 -0
- package/dist/harness/executors.d.ts +22 -0
- package/dist/harness/executors.js +96 -0
- package/dist/harness/main.d.ts +6 -0
- package/dist/harness/main.js +103 -0
- package/dist/harness/pod.d.ts +21 -0
- package/dist/harness/pod.js +119 -0
- package/dist/harness/run-tokens.d.ts +18 -0
- package/dist/harness/run-tokens.js +15 -0
- package/dist/harness/service.d.ts +46 -0
- package/dist/harness/service.js +179 -0
- package/dist/harness/ws-client.d.ts +43 -0
- package/dist/harness/ws-client.js +122 -0
- package/dist/harness/ws-port.d.ts +22 -0
- package/dist/harness/ws-port.js +78 -0
- package/dist/harness-api/in-process.d.ts +24 -0
- package/dist/harness-api/in-process.js +119 -0
- package/dist/harness-api/record.d.ts +44 -0
- package/dist/harness-api/record.js +250 -0
- package/dist/harness-api/renew.d.ts +37 -0
- package/dist/harness-api/renew.js +77 -0
- package/dist/harness-api/server.d.ts +104 -0
- package/dist/harness-api/server.js +408 -0
- package/dist/harness-api/start.d.ts +36 -0
- package/dist/harness-api/start.js +118 -0
- package/dist/harness-api/workspace.d.ts +53 -0
- package/dist/harness-api/workspace.js +201 -0
- package/dist/harness-api/ws-server.d.ts +34 -0
- package/dist/harness-api/ws-server.js +227 -0
- package/dist/host/admin-api.d.ts +12 -5
- package/dist/host/admin-api.js +72 -6
- package/dist/host/app.d.ts +0 -1
- package/dist/host/app.js +35 -24
- package/dist/host/config-for.d.ts +4 -0
- package/dist/host/config-for.js +2 -0
- package/dist/host/config.d.ts +0 -6
- package/dist/host/create-host.d.ts +3 -10
- package/dist/host/create-host.js +4 -1
- package/dist/host/gates.d.ts +27 -2
- package/dist/host/gates.js +52 -2
- package/dist/host/http.d.ts +4 -1
- package/dist/host/http.js +6 -1
- package/dist/host/main.js +167 -37
- package/dist/host/stack-config.d.ts +112 -9
- package/dist/host/stack-config.js +222 -20
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/keys/client.js +9 -1
- package/dist/keys/keys.d.ts +12 -2
- package/dist/keys/keys.js +8 -0
- package/dist/mcp/connect.js +2 -1
- package/dist/mcp/pool.d.ts +1 -0
- package/dist/mcp/pool.js +1 -0
- package/dist/mcp/snapshot.d.ts +8 -1
- package/dist/mcp/snapshot.js +28 -0
- package/dist/media.d.ts +5 -24
- package/dist/media.js +5 -0
- package/dist/model/pi-model.d.ts +6 -2
- package/dist/model/pi-model.js +39 -22
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +1 -1
- package/dist/openapi.json +14084 -9426
- package/dist/record/index.d.ts +1 -0
- package/dist/record/index.js +1 -0
- package/dist/record/sandbox.d.ts +25 -0
- package/dist/record/sandbox.js +43 -0
- package/dist/sandbox/capability.d.ts +3 -0
- package/dist/sandbox/capability.js +10 -0
- package/dist/sandbox/egress-token.d.ts +26 -0
- package/dist/sandbox/egress-token.js +8 -0
- package/dist/sandbox/join.d.ts +37 -0
- package/dist/sandbox/join.js +165 -0
- package/dist/sandbox/manager.d.ts +99 -34
- package/dist/sandbox/manager.js +216 -84
- package/dist/sandbox/placement.d.ts +27 -0
- package/dist/sandbox/placement.js +44 -0
- package/dist/sandbox/pods/client.d.ts +90 -0
- package/dist/sandbox/pods/client.js +79 -0
- package/dist/sandbox/pods/lifecycle.d.ts +91 -0
- package/dist/sandbox/pods/lifecycle.js +178 -0
- package/dist/sandbox/pods/name.d.ts +1 -0
- package/dist/sandbox/pods/name.js +28 -0
- package/dist/sandbox/pods/network-gate.d.ts +25 -0
- package/dist/sandbox/pods/network-gate.js +71 -0
- package/dist/sandbox/pods/reconcile.d.ts +11 -0
- package/dist/sandbox/pods/reconcile.js +152 -0
- package/dist/sandbox/pods/spec.d.ts +45 -0
- package/dist/sandbox/pods/spec.js +62 -0
- package/dist/sandbox/records.d.ts +29 -0
- package/dist/sandbox/records.js +79 -0
- package/dist/sandbox/resolve.d.ts +5 -0
- package/dist/sandbox/resolve.js +3 -2
- package/dist/sandbox/session-sandbox.js +7 -5
- package/dist/sandbox/share.d.ts +11 -0
- package/dist/sandbox/share.js +10 -0
- package/dist/sandbox/tenant-config.d.ts +16 -1
- package/dist/sandbox/tenant-config.js +9 -0
- package/dist/sandbox/types.d.ts +29 -1
- package/dist/sandbox/types.js +13 -1
- package/dist/store/postgres/drizzle/0004_sandbox_resources.sql +20 -0
- package/dist/store/postgres/drizzle/0005_artifacts.sql +27 -0
- package/dist/store/postgres/drizzle/0006_folder_artifacts.sql +12 -0
- package/dist/store/postgres/drizzle/0007_sandbox_pods.sql +14 -0
- package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
- package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
- package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
- package/dist/store/postgres/record-writer.d.ts +6 -1
- package/dist/store/postgres/record-writer.js +20 -2
- package/dist/store/postgres/schema.d.ts +1168 -250
- package/dist/store/postgres/schema.js +174 -28
- package/dist/store/postgres/store.js +339 -103
- package/dist/store/postgres/tenant.d.ts +1 -1
- package/dist/store/postgres/tenant.js +2 -2
- package/dist/store/types.d.ts +163 -32
- package/dist/streams/control.d.ts +2 -5
- package/dist/streams/control.js +5 -8
- package/dist/streams/types.d.ts +8 -8
- package/dist/streams/types.js +1 -1
- package/dist/tenant/advance.js +218 -160
- package/dist/tenant/artifact-tool.d.ts +5 -0
- package/dist/tenant/artifact-tool.js +119 -0
- package/dist/tenant/auth.d.ts +13 -9
- package/dist/tenant/auth.js +25 -32
- package/dist/tenant/commands.js +31 -10
- package/dist/tenant/context.d.ts +83 -26
- package/dist/tenant/delivery-token.js +4 -4
- package/dist/tenant/effects.d.ts +24 -14
- package/dist/tenant/effects.js +10 -398
- package/dist/tenant/ephemeral.d.ts +14 -2
- package/dist/tenant/ephemeral.js +8 -1
- package/dist/tenant/history.d.ts +13 -23
- package/dist/tenant/history.js +14 -62
- package/dist/tenant/host-token.d.ts +92 -0
- package/dist/tenant/host-token.js +179 -0
- package/dist/tenant/identity-file.d.ts +75 -0
- package/dist/tenant/identity-file.js +202 -0
- package/dist/tenant/issuers.d.ts +48 -0
- package/dist/tenant/issuers.js +311 -0
- package/dist/tenant/jwt.js +3 -3
- package/dist/tenant/module.js +1 -0
- package/dist/tenant/operator-keys.d.ts +18 -0
- package/dist/tenant/operator-keys.js +55 -0
- package/dist/tenant/outbound.d.ts +30 -0
- package/dist/tenant/outbound.js +142 -10
- package/dist/tenant/paths.d.ts +2 -1
- package/dist/tenant/paths.js +3 -1
- package/dist/tenant/principals.d.ts +2 -11
- package/dist/tenant/principals.js +10 -30
- package/dist/tenant/reset.d.ts +5 -2
- package/dist/tenant/reset.js +22 -2
- package/dist/tenant/run-grants.d.ts +49 -0
- package/dist/tenant/run-grants.js +62 -0
- package/dist/tenant/run-token.d.ts +70 -0
- package/dist/tenant/run-token.js +138 -0
- package/dist/tenant/runtime.d.ts +42 -0
- package/dist/tenant/runtime.js +134 -33
- package/dist/tenant/sandboxes.d.ts +119 -0
- package/dist/tenant/sandboxes.js +551 -0
- package/dist/tenant/session-streams.d.ts +6 -10
- package/dist/tenant/session-streams.js +9 -27
- package/dist/tenant/session.d.ts +2 -13
- package/dist/tenant/session.js +4 -28
- package/dist/tenant/sessions.d.ts +6 -1
- package/dist/tenant/sessions.js +29 -2
- package/dist/tenant/signing-keys.d.ts +2 -1
- package/dist/tenant/signing-keys.js +2 -2
- package/dist/tenant/status.d.ts +8 -3
- package/dist/tenant/status.js +5 -0
- package/dist/tenant/streams.d.ts +8 -2
- package/dist/tenant/streams.js +25 -6
- package/dist/tenant/sweep.js +37 -4
- package/dist/tenant/types.d.ts +39 -1
- package/dist/tenant/worker.d.ts +11 -5
- package/dist/tenant/worker.js +12 -6
- package/dist/vault/crypto.d.ts +7 -0
- package/dist/vault/crypto.js +16 -0
- package/dist/vault/oauth.d.ts +55 -0
- package/dist/vault/oauth.js +186 -0
- package/dist/vault/service.d.ts +54 -7
- package/dist/vault/service.js +261 -17
- package/dist/vault/sources.d.ts +54 -0
- package/dist/vault/sources.js +185 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -10
- package/dist/adapters/media.d.ts +0 -24
- package/dist/adapters/media.js +0 -111
- package/dist/host/cors.d.ts +0 -27
- package/dist/host/cors.js +0 -64
- package/dist/tenant/access-policy.d.ts +0 -30
- package/dist/tenant/access-policy.js +0 -52
- package/dist/tenant/browser.d.ts +0 -15
- package/dist/tenant/browser.js +0 -39
- package/dist/tenant/subject-limits.d.ts +0 -16
- package/dist/tenant/subject-limits.js +0 -45
- package/dist/tenant/tokens.d.ts +0 -14
- package/dist/tenant/tokens.js +0 -180
package/dist/tenant/auth.d.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tenant request authentication and authorization: a bearer token resolves to an application
|
|
3
|
-
* principal, a
|
|
4
|
-
* An application principal may act for a subject (`Nylorun-Subject`, `Nylorun-Scopes`);
|
|
5
|
-
*
|
|
6
|
-
* allow, decided from the route alone.
|
|
3
|
+
* principal, a trusted issuer's token or a delivery token; anything else is the opaque 404
|
|
4
|
+
* (D5). An application principal may act for a subject (`Nylorun-Subject`, `Nylorun-Scopes`);
|
|
5
|
+
* an issuer token names its subject itself. `requireScopes` limits them to the routes their
|
|
6
|
+
* scopes allow, decided from the route alone.
|
|
7
|
+
*
|
|
8
|
+
* Browsers: a request with `Origin` may carry an issuer token (CORS is the operator's proxy's),
|
|
9
|
+
* never an application key or a delivery token, which are server secrets.
|
|
7
10
|
*/
|
|
8
11
|
import type { IncomingMessage } from "node:http";
|
|
9
12
|
import { type Action, type SubjectScope } from "@nylorun/core/contracts";
|
|
10
13
|
import type { AuthScope, SessionAccess, TenantContext } from "./context.js";
|
|
11
|
-
|
|
12
|
-
export declare function authenticate(ctx: TenantContext, request: IncomingMessage, client?: BrowserClient): Promise<AuthScope>;
|
|
14
|
+
export declare function authenticate(ctx: TenantContext, request: IncomingMessage): Promise<AuthScope>;
|
|
13
15
|
/**
|
|
14
16
|
* What a subject needs for a route: any one of the scopes, nothing grants it (`never`), or
|
|
15
17
|
* any caller may (`any`, public data such as the JWKS). Each route declares it
|
|
@@ -17,12 +19,12 @@ export declare function authenticate(ctx: TenantContext, request: IncomingMessag
|
|
|
17
19
|
*/
|
|
18
20
|
export type SubjectAccess = readonly SubjectScope[] | "never" | "any";
|
|
19
21
|
/**
|
|
20
|
-
* A subject
|
|
21
|
-
*
|
|
22
|
+
* A subject or a token caller reaches a route only with one of the scopes it declares:
|
|
23
|
+
* `403 scope_required`, decided from the route alone before anything is read.
|
|
22
24
|
*/
|
|
23
25
|
export declare function requireScopes(scope: AuthScope, access: SubjectAccess): void;
|
|
24
26
|
export declare function accessOf(scope: AuthScope): SessionAccess | undefined;
|
|
25
|
-
/** The subject whose sessions
|
|
27
|
+
/** The subject whose sessions the request is limited to, if it acts for one. */
|
|
26
28
|
export declare function ownerOf(scope: AuthScope): string | undefined;
|
|
27
29
|
/** The application principal behind the request, acting for a subject or not. */
|
|
28
30
|
export declare function requirePrincipal(scope: AuthScope): string;
|
|
@@ -31,4 +33,6 @@ export declare function requirePrincipal(scope: AuthScope): string;
|
|
|
31
33
|
* is still the Action's is checked by each callback.
|
|
32
34
|
*/
|
|
33
35
|
export declare function scoped(scope: AuthScope, action: Action): void;
|
|
36
|
+
/** True when a token caller may reach `agentId` (its issuer's allowlist). Other callers always may. */
|
|
37
|
+
export declare function mayUseAgent(scope: AuthScope, agentId: string): boolean;
|
|
34
38
|
export declare function requireApplication(scope: AuthScope): string;
|
package/dist/tenant/auth.js
CHANGED
|
@@ -2,10 +2,9 @@ import { SCOPES_HEADER, SUBJECT_HEADER, } from "@nylorun/core/compatibility";
|
|
|
2
2
|
import { DELIVERY_TOKEN_TYPE, parseSubjectHeaders, } from "@nylorun/core/contracts";
|
|
3
3
|
import { hashToken } from "../core/bearer.js";
|
|
4
4
|
import { fail, failOpaque } from "./http.js";
|
|
5
|
-
import { looksLikeToken, verifySubjectToken } from "./tokens.js";
|
|
6
5
|
import { verifyDeliveryToken } from "./delivery-token.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { verifyIssuerToken } from "./issuers.js";
|
|
7
|
+
import { looksLikeToken, tokenType } from "./jwt.js";
|
|
9
8
|
const SUBJECT_INVALID = { code: "subject_invalid" };
|
|
10
9
|
/** One header's value, or `undefined`; a header sent twice is refused. */
|
|
11
10
|
function singleHeader(request, name) {
|
|
@@ -18,20 +17,10 @@ function singleHeader(request, name) {
|
|
|
18
17
|
return fail(400, `${name} must be sent once`, SUBJECT_INVALID);
|
|
19
18
|
return values[0];
|
|
20
19
|
}
|
|
21
|
-
export async function authenticate(ctx, request
|
|
20
|
+
export async function authenticate(ctx, request) {
|
|
22
21
|
const header = request.headers.authorization;
|
|
23
22
|
const token = header?.startsWith("Bearer ") ? header.slice(7) : "";
|
|
24
23
|
if (!token || !header?.startsWith("Bearer ")) {
|
|
25
|
-
// A publishable key alone: what the policy grants `anon` (nothing by default).
|
|
26
|
-
if (client && header === undefined) {
|
|
27
|
-
const { anon } = await ctx.store.tx((t) => readPolicy(t));
|
|
28
|
-
return {
|
|
29
|
-
kind: "publishable",
|
|
30
|
-
keyId: client.keyId,
|
|
31
|
-
scopes: new Set(anon.scopes),
|
|
32
|
-
agents: anon.agents === "*" ? "*" : new Set(anon.agents),
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
24
|
ctx.config.logger.warn("credential rejected", {
|
|
36
25
|
reason: "missing_bearer",
|
|
37
26
|
});
|
|
@@ -47,24 +36,27 @@ export async function authenticate(ctx, request, client) {
|
|
|
47
36
|
fail(403, "A delivery token cannot act for a subject");
|
|
48
37
|
return scope;
|
|
49
38
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
// A trusted issuer's token (Host feature `trusted-issuers`), from a server or a browser: its
|
|
40
|
+
// unverified `iss` names an issuer of the identity file, and only that issuer verifies it.
|
|
41
|
+
const issuer = ctx.config.issuers?.claimed(token);
|
|
42
|
+
if (issuer) {
|
|
43
|
+
const scope = await verifyIssuerToken(ctx, issuer, token);
|
|
53
44
|
if (singleHeader(request, SUBJECT_HEADER) !== undefined ||
|
|
54
45
|
singleHeader(request, SCOPES_HEADER) !== undefined)
|
|
55
|
-
fail(403, "
|
|
46
|
+
fail(403, "An issuer token cannot act for another subject");
|
|
56
47
|
return scope;
|
|
57
48
|
}
|
|
49
|
+
// Any other JWT: no issuer of this Host signed it (subject tokens are gone, protocol 7).
|
|
50
|
+
if (looksLikeToken(token)) {
|
|
51
|
+
ctx.config.logger.warn("credential rejected", { reason: "token_unknown_issuer" });
|
|
52
|
+
return failOpaque();
|
|
53
|
+
}
|
|
58
54
|
// Application keys never come from a browser or a shipped app: refused before they are even
|
|
59
55
|
// looked up.
|
|
60
56
|
if (request.headers.origin !== undefined)
|
|
61
57
|
fail(403, "Application keys are not accepted from browsers", {
|
|
62
58
|
code: "origin_rejected",
|
|
63
59
|
});
|
|
64
|
-
if (client)
|
|
65
|
-
fail(400, "Nylorun-Key is for browser and mobile clients, not with a Tenant key", {
|
|
66
|
-
code: "invalid_request",
|
|
67
|
-
});
|
|
68
60
|
const tokenHash = hashToken(token);
|
|
69
61
|
const principal = await ctx.store.tx((t) => t.principalByTokenHash(tokenHash));
|
|
70
62
|
if (!principal) {
|
|
@@ -92,13 +84,11 @@ export async function authenticate(ctx, request, client) {
|
|
|
92
84
|
};
|
|
93
85
|
}
|
|
94
86
|
/**
|
|
95
|
-
* A subject
|
|
96
|
-
*
|
|
87
|
+
* A subject or a token caller reaches a route only with one of the scopes it declares:
|
|
88
|
+
* `403 scope_required`, decided from the route alone before anything is read.
|
|
97
89
|
*/
|
|
98
90
|
export function requireScopes(scope, access) {
|
|
99
|
-
if (scope.kind !== "subject" &&
|
|
100
|
-
scope.kind !== "token" &&
|
|
101
|
-
scope.kind !== "publishable")
|
|
91
|
+
if (scope.kind !== "subject" && scope.kind !== "token")
|
|
102
92
|
return;
|
|
103
93
|
if (access === "any")
|
|
104
94
|
return;
|
|
@@ -107,7 +97,8 @@ export function requireScopes(scope, access) {
|
|
|
107
97
|
code: "scope_required",
|
|
108
98
|
details: { scopes: [] },
|
|
109
99
|
});
|
|
110
|
-
|
|
100
|
+
const held = scope.scopes;
|
|
101
|
+
if (!access.some((name) => held.has(name)))
|
|
111
102
|
fail(403, `Scope ${access.join(" or ")} required`, {
|
|
112
103
|
code: "scope_required",
|
|
113
104
|
details: { scopes: access },
|
|
@@ -124,9 +115,7 @@ export function accessOf(scope) {
|
|
|
124
115
|
owner: scope.subject,
|
|
125
116
|
...(scope.agents === "*" ? {} : { agents: scope.agents }),
|
|
126
117
|
};
|
|
127
|
-
// A
|
|
128
|
-
case "publishable":
|
|
129
|
-
// Nor does a request with no credential, on a route that serves public data.
|
|
118
|
+
// A request with no credential, on a route that serves public data, owns nothing.
|
|
130
119
|
case "anonymous":
|
|
131
120
|
return fail(404, "Not found");
|
|
132
121
|
// A delivery token reaches its Action's callbacks, never a session or vault.
|
|
@@ -138,7 +127,7 @@ export function accessOf(scope) {
|
|
|
138
127
|
}
|
|
139
128
|
}
|
|
140
129
|
}
|
|
141
|
-
/** The subject whose sessions
|
|
130
|
+
/** The subject whose sessions the request is limited to, if it acts for one. */
|
|
142
131
|
export function ownerOf(scope) {
|
|
143
132
|
return accessOf(scope)?.owner;
|
|
144
133
|
}
|
|
@@ -159,6 +148,10 @@ export function scoped(scope, action) {
|
|
|
159
148
|
return;
|
|
160
149
|
fail(403, "This delivery token is for another Action");
|
|
161
150
|
}
|
|
151
|
+
/** True when a token caller may reach `agentId` (its issuer's allowlist). Other callers always may. */
|
|
152
|
+
export function mayUseAgent(scope, agentId) {
|
|
153
|
+
return scope.kind !== "token" || scope.agents === "*" || scope.agents.has(agentId);
|
|
154
|
+
}
|
|
162
155
|
export function requireApplication(scope) {
|
|
163
156
|
if (scope.kind === "application")
|
|
164
157
|
return scope.principalId;
|
package/dist/tenant/commands.js
CHANGED
|
@@ -24,11 +24,12 @@ import { canonical } from "../store/canonical.js";
|
|
|
24
24
|
import { lockedSession, } from "./context.js";
|
|
25
25
|
import { fail } from "./http.js";
|
|
26
26
|
import { accessOf } from "./auth.js";
|
|
27
|
-
import {
|
|
27
|
+
import { checkSandboxTurn } from "./sandboxes.js";
|
|
28
28
|
import { actionTarget, rebaseSessionState, turnManifestOf, variantStore, } from "./session.js";
|
|
29
|
-
import { signalSessionCancel } from "./streams.js";
|
|
29
|
+
import { signalActionOutcome, signalSessionCancel } from "./streams.js";
|
|
30
30
|
import { toolIds } from "./transcript.js";
|
|
31
31
|
import { slimModelEffects } from "./slim.js";
|
|
32
|
+
import { resolveMessageParts } from "../artifacts/parts.js";
|
|
32
33
|
/** `outcome`, or a failed one when a tool's output does not match its stored output schema. */
|
|
33
34
|
export function acceptedOutcome(action, outcome) {
|
|
34
35
|
if (action.kind !== "tool" || !action.outputSchema)
|
|
@@ -95,7 +96,7 @@ export async function command(ctx, id, input, scope) {
|
|
|
95
96
|
if (scope.kind === "token" &&
|
|
96
97
|
command.type === "message" &&
|
|
97
98
|
command.manifest !== undefined)
|
|
98
|
-
fail(403, "A
|
|
99
|
+
fail(403, "A token caller cannot send message.manifest", {
|
|
99
100
|
code: "scope_required",
|
|
100
101
|
});
|
|
101
102
|
const key = commandKey(id, command.idempotencyKey);
|
|
@@ -178,16 +179,25 @@ export async function command(ctx, id, input, scope) {
|
|
|
178
179
|
if (command.type === "message") {
|
|
179
180
|
if (!["idle", "completed", "failed", "cancelled"].includes(s.status))
|
|
180
181
|
fail(409, "Session has active or unresolved work");
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
// Every turn start on a sandbox: it exists, the token's grants reach it, and no other
|
|
183
|
+
// session's turn holds it.
|
|
184
|
+
await checkSandboxTurn(t, s, scope, ctx);
|
|
184
185
|
s.turnStartState = s.state;
|
|
185
186
|
// A new turn folds from the latest snapshot: a cancel or failure only reverts this turn.
|
|
186
187
|
if (s.history?.snapshot !== undefined)
|
|
187
188
|
s.history = { ...s.history, from: s.history.snapshot };
|
|
188
189
|
s.activeTurnId = randomUUID();
|
|
190
|
+
// File parts name artifacts the caller may read; each is pinned to a version now.
|
|
191
|
+
const parts = "parts" in command
|
|
192
|
+
? await resolveMessageParts(t, command.parts, id, accessOf(scope))
|
|
193
|
+
: undefined;
|
|
194
|
+
const data = "data" in command ? command.data : undefined;
|
|
189
195
|
if (isWorkflowManifest(s.manifest)) {
|
|
190
|
-
const input = "content" in command
|
|
196
|
+
const input = "content" in command
|
|
197
|
+
? command.content
|
|
198
|
+
: parts
|
|
199
|
+
? { parts: parts.pinned }
|
|
200
|
+
: data;
|
|
191
201
|
s.checkpoint = createFlowCheckpoint({
|
|
192
202
|
manifest: s.manifest,
|
|
193
203
|
sessionId: id,
|
|
@@ -214,9 +224,11 @@ export async function command(ctx, id, input, scope) {
|
|
|
214
224
|
turnId: s.activeTurnId,
|
|
215
225
|
input: "content" in command
|
|
216
226
|
? command.content
|
|
217
|
-
:
|
|
218
|
-
?
|
|
219
|
-
:
|
|
227
|
+
: parts
|
|
228
|
+
? { content: parts.engine }
|
|
229
|
+
: typeof data === "string"
|
|
230
|
+
? data
|
|
231
|
+
: JSON.stringify(data),
|
|
220
232
|
state: s.state,
|
|
221
233
|
info: s.info,
|
|
222
234
|
});
|
|
@@ -334,6 +346,15 @@ export async function recordActionOutcome(t, ctx, s, action, received, options =
|
|
|
334
346
|
dedupeKey: `action_result:${action.turnId}:${action.actionId}:${action.generation}`,
|
|
335
347
|
};
|
|
336
348
|
t.afterCommit(() => ctx.wake(s.id, resultWake));
|
|
349
|
+
// A run held while the Action was pending goes on with it in the same lease (F6.2): here, or
|
|
350
|
+
// on the process whose harness holds it. The wake finds the session settled, or resumes it
|
|
351
|
+
// by replay when the run had already ended.
|
|
352
|
+
t.afterCommit(() => {
|
|
353
|
+
if (ctx.harness.holds(s.id))
|
|
354
|
+
ctx.harness.resolved(s.id, action.actionId, outcome);
|
|
355
|
+
else
|
|
356
|
+
signalActionOutcome(ctx, s.id, action.actionId);
|
|
357
|
+
});
|
|
337
358
|
const event = await t.event(s.id, s.activeTurnId, "action.completed", {
|
|
338
359
|
actionId: action.actionId,
|
|
339
360
|
...actionTarget(action),
|
package/dist/tenant/context.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* under ownership (§10.6); `abortLocal` aborts an advance running on this process.
|
|
15
15
|
*/
|
|
16
16
|
import type { SessionHistory } from "./history.js";
|
|
17
|
-
import type {
|
|
17
|
+
import type { IssuerScope, SubjectScope, TenantEnvelope } from "@nylorun/core/contracts";
|
|
18
18
|
import type { DurableCheckpoint, FlowCheckpoint } from "@nylorun/harness/run";
|
|
19
19
|
import type { AgentManifest, JsonValue, SandboxManifest } from "@nylorun/core/define";
|
|
20
20
|
import type { CredentialSelection } from "@nylorun/core/contracts";
|
|
@@ -25,14 +25,21 @@ import type { ModelGate } from "../gates/model-gate.js";
|
|
|
25
25
|
import type { ToolGate } from "../gates/tool-gate.js";
|
|
26
26
|
import type { Keys } from "../keys/keys.js";
|
|
27
27
|
import type { VaultService } from "../vault/service.js";
|
|
28
|
+
import type { CredentialSources } from "../vault/sources.js";
|
|
28
29
|
import type { McpPool } from "../mcp/pool.js";
|
|
29
30
|
import type { McpDiagnostic, McpSnapshot } from "../mcp/snapshot.js";
|
|
30
|
-
import type {
|
|
31
|
+
import type { HarnessApiServer } from "../harness-api/server.js";
|
|
32
|
+
import type { WorkspacePort } from "../harness-api/workspace.js";
|
|
33
|
+
import type { SandboxesClient } from "../sandbox/pods/client.js";
|
|
34
|
+
import type { SandboxSignal } from "../execution/types.js";
|
|
31
35
|
import type { TenantConfig } from "./types.js";
|
|
32
36
|
import type { SessionStreams } from "./session-streams.js";
|
|
33
37
|
import type { StuckInvocation, Wake } from "../execution/types.js";
|
|
34
38
|
import type { WorkState } from "./scheduler.js";
|
|
35
39
|
import type { SigningKeys } from "./signing-keys.js";
|
|
40
|
+
import type { BlobStore } from "../blob/index.js";
|
|
41
|
+
import type { WorkspaceReader } from "../artifacts/workspace.js";
|
|
42
|
+
import type { RunGrants } from "./run-grants.js";
|
|
36
43
|
export interface Session {
|
|
37
44
|
id: string;
|
|
38
45
|
agentId: string;
|
|
@@ -70,34 +77,43 @@ export interface Session {
|
|
|
70
77
|
mcpDiagnostics?: readonly McpDiagnostic[];
|
|
71
78
|
/** Session id that keys the shared sandbox; absent means this session owns it. */
|
|
72
79
|
sandboxOwnerId?: string;
|
|
80
|
+
/**
|
|
81
|
+
* The sandbox resource the session is attached to (`sandbox: { id }`): its workspace is the
|
|
82
|
+
* sandbox's, shared with every session attached to it, and it outlives the session.
|
|
83
|
+
*/
|
|
84
|
+
sandboxId?: string;
|
|
73
85
|
/**
|
|
74
86
|
* The sandbox chosen when the session was opened, resolved against the Tenant's limits, or
|
|
75
87
|
* inherited from the session it shares with. Absent when the session has no sandbox or its
|
|
76
88
|
* definition declares one (`.sandbox()`).
|
|
77
89
|
*/
|
|
78
90
|
sandbox?: SandboxManifest;
|
|
79
|
-
/** Where `sandbox` came from. */
|
|
80
|
-
sandboxSource?: "default" | "inline" | "shared";
|
|
91
|
+
/** Where `sandbox` came from: `sandbox` is a sandbox resource's spec. */
|
|
92
|
+
sandboxSource?: "default" | "inline" | "shared" | "sandbox";
|
|
81
93
|
}
|
|
82
94
|
export type AuthScope = {
|
|
83
95
|
kind: "application";
|
|
84
96
|
principalId: string;
|
|
85
97
|
}
|
|
86
98
|
/**
|
|
87
|
-
* A
|
|
88
|
-
*
|
|
99
|
+
* A trusted issuer's token (Host feature `trusted-issuers`, F9-D12): one subject, with the
|
|
100
|
+
* issuer's scopes, agents and sandbox grants, until `expiresAt` (ms). Only its expiry ends it.
|
|
89
101
|
*/
|
|
90
102
|
| {
|
|
91
103
|
kind: "token";
|
|
104
|
+
/** The identity file's issuer that signed it. */
|
|
105
|
+
issuer: string;
|
|
92
106
|
subject: string;
|
|
93
|
-
scopes
|
|
107
|
+
/** The issuer's scopes the token holds, which may add `studio`. */
|
|
108
|
+
scopes: ReadonlySet<IssuerScope>;
|
|
94
109
|
agents: ReadonlySet<string> | "*";
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
epoch: number;
|
|
110
|
+
/** The sandboxes it reaches: exact ids or `p/*` prefixes. Absent or empty reaches none. */
|
|
111
|
+
sandboxes?: readonly string[];
|
|
98
112
|
expiresAt: number;
|
|
113
|
+
/** The token's `jti`, or a hash of it. */
|
|
99
114
|
tokenId: string;
|
|
100
|
-
|
|
115
|
+
/** The issuer key's `kid`, when it has one. */
|
|
116
|
+
keyId?: string;
|
|
101
117
|
}
|
|
102
118
|
/** An application principal acting for `subject` (`Nylorun-Subject`), narrowed to `scopes`. */
|
|
103
119
|
| {
|
|
@@ -122,24 +138,27 @@ export type AuthScope = {
|
|
|
122
138
|
expiresAt: number;
|
|
123
139
|
tokenId: string;
|
|
124
140
|
keyId: string;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* A publishable key with no bearer (Host feature `browser-access`): what the policy grants
|
|
128
|
-
* `anon`, at most `agents:read`. It owns no session or vault.
|
|
129
|
-
*/
|
|
130
|
-
| {
|
|
131
|
-
kind: "publishable";
|
|
132
|
-
keyId: string;
|
|
133
|
-
scopes: ReadonlySet<SubjectScope>;
|
|
134
|
-
agents: ReadonlySet<string> | "*";
|
|
135
141
|
};
|
|
136
142
|
export interface TenantContext {
|
|
137
143
|
readonly config: TenantConfig;
|
|
138
144
|
readonly envelope: TenantEnvelope;
|
|
139
145
|
readonly store: SessionStore;
|
|
140
146
|
readonly vault: VaultService;
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
/**
|
|
148
|
+
* A session's MCP credentials, for the in-process MCP pool: its attached vaults, then the
|
|
149
|
+
* operator's credential resolver (`TenantConfig.resolver`, F9 C1).
|
|
150
|
+
*/
|
|
151
|
+
readonly credentials: CredentialSources;
|
|
152
|
+
/**
|
|
153
|
+
* The MCP pool of the Tenant's in-process harness. Absent when harnesses run elsewhere
|
|
154
|
+
* (`NYLORUN_HARNESS=remote`): each keeps its own (F6.2).
|
|
155
|
+
*/
|
|
156
|
+
readonly mcp?: McpPool;
|
|
157
|
+
/**
|
|
158
|
+
* The workspace capability (F6.2): the Tenant's SandboxManager with an in-process harness,
|
|
159
|
+
* else the harness that serves workspaces (`harness-api/workspace.ts`).
|
|
160
|
+
*/
|
|
161
|
+
readonly sandbox: WorkspacePort;
|
|
143
162
|
readonly flowLimits: FlowLimits;
|
|
144
163
|
readonly modelProvider: ModelProvider;
|
|
145
164
|
/** True when the model comes from the Tenant vault selection, served by `modelGate`. */
|
|
@@ -157,6 +176,28 @@ export interface TenantContext {
|
|
|
157
176
|
* `signingKeys`' private key.
|
|
158
177
|
*/
|
|
159
178
|
readonly keys: Keys;
|
|
179
|
+
/**
|
|
180
|
+
* The Object store's `BlobStore` seam (D35): the Host's `s3` store (RustFS in the local
|
|
181
|
+
* stack), or the `fs` store under `paths.blobs` without one. Bytes only; Postgres holds what
|
|
182
|
+
* they mean, and a blob counts once a committed row names its key.
|
|
183
|
+
*/
|
|
184
|
+
readonly blobs: BlobStore;
|
|
185
|
+
/**
|
|
186
|
+
* How core reads a session's sandbox workspace at turn end, to export its outputs (F8.2): over
|
|
187
|
+
* this process's `sandbox` today; over the Harness API's `workspace.read` from F6.2.
|
|
188
|
+
*/
|
|
189
|
+
readonly workspaces: WorkspaceReader;
|
|
190
|
+
/**
|
|
191
|
+
* The run token of each session an advance of this process owns (F5): the credential the
|
|
192
|
+
* HTTP gate clients present for that session's model and MCP calls (`run-grants.ts`).
|
|
193
|
+
* Absent when the gates run in this process, which needs no token (G6).
|
|
194
|
+
*/
|
|
195
|
+
readonly runGrants?: RunGrants;
|
|
196
|
+
/**
|
|
197
|
+
* The Harness API server (D37): advances offer their segments here, and the Tenant's
|
|
198
|
+
* harnesses (the in-process one, or attached ones) run them.
|
|
199
|
+
*/
|
|
200
|
+
readonly harness: HarnessApiServer;
|
|
160
201
|
/** Set by drain/close; reset clears it again. Stops new advances. */
|
|
161
202
|
closing: boolean;
|
|
162
203
|
/** Set once close has finished releasing resources. */
|
|
@@ -165,7 +206,7 @@ export interface TenantContext {
|
|
|
165
206
|
readonly work: WorkState;
|
|
166
207
|
/** Live delivery over Durable Streams: one `SessionStream` per observed session, and the streams wiring. */
|
|
167
208
|
readonly sessionStreams: SessionStreams;
|
|
168
|
-
/** The Tenant's signing keys
|
|
209
|
+
/** The Tenant's signing keys: delivery tokens, capability links, run and host tokens. */
|
|
169
210
|
readonly signingKeys: SigningKeys;
|
|
170
211
|
/** The Worker id this process writes as session `owner` (§10.6). */
|
|
171
212
|
readonly workerId: string;
|
|
@@ -187,6 +228,16 @@ export interface TenantContext {
|
|
|
187
228
|
* from `t.afterCommit`. Dropped while the Tenant is closing; the sweep re-sends it.
|
|
188
229
|
*/
|
|
189
230
|
deliver(actionId: string): Promise<void>;
|
|
231
|
+
/**
|
|
232
|
+
* Sandbox pods (F7.2): the sandboxes service and the Runtime image pods copy the engine from.
|
|
233
|
+
* Absent without a cluster (`nylorun sandbox enable`): kind `pod` is `sandbox_unavailable`.
|
|
234
|
+
*/
|
|
235
|
+
readonly pods?: TenantPods;
|
|
236
|
+
/**
|
|
237
|
+
* Seam: reconcile a pod sandbox, or arm one of its timers (`DurableExecution.sandbox`). Call
|
|
238
|
+
* it from `t.afterCommit`. Dropped while the Tenant is closing; the sweep re-sends reconciles.
|
|
239
|
+
*/
|
|
240
|
+
sandboxSignal(sandboxId: string, signal: SandboxSignal): Promise<void>;
|
|
190
241
|
/** This Tenant's execution invocations that need an operator, for Tenant status. */
|
|
191
242
|
readonly stuckInvocations?: () => Promise<StuckInvocation[]>;
|
|
192
243
|
/** Callbacks the Tenant sweep runs after its own steps (`sweep.ts`). */
|
|
@@ -195,8 +246,8 @@ export interface TenantContext {
|
|
|
195
246
|
onSweep(hook: () => Promise<void>): () => void;
|
|
196
247
|
}
|
|
197
248
|
/**
|
|
198
|
-
* What a request acting for a person may reach: that person's sessions
|
|
199
|
-
*
|
|
249
|
+
* What a request acting for a person may reach: that person's sessions, and, for a token
|
|
250
|
+
* caller, only sessions of the agents its issuer allows. Undefined means the whole Tenant.
|
|
200
251
|
*/
|
|
201
252
|
export interface SessionAccess {
|
|
202
253
|
readonly owner: string;
|
|
@@ -225,3 +276,9 @@ export declare function loadSession(ctx: TenantContext, id: string, access?: Ses
|
|
|
225
276
|
* the sandbox-sharing helpers, which walk that chain synchronously.
|
|
226
277
|
*/
|
|
227
278
|
export declare function sandboxLookup(t: Tx, start: string | undefined): Promise<(id: string) => Session | undefined>;
|
|
279
|
+
/** The sandboxes service a Tenant drives its pod sandboxes with (`TenantContext.pods`). */
|
|
280
|
+
export interface TenantPods {
|
|
281
|
+
readonly client: SandboxesClient;
|
|
282
|
+
/** The Runtime image the pods copy the engine from (`NYLORUN_SANDBOX_HARNESS_IMAGE`). */
|
|
283
|
+
readonly harnessImage: string;
|
|
284
|
+
}
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* Tenant's public keys, and comes back as the bearer of that Action's callbacks (a background
|
|
6
6
|
* result, heartbeats, sandbox tools).
|
|
7
7
|
*
|
|
8
|
-
* A token lives at most `DELIVERY_TOKEN_MAX_TTL_SECONDS
|
|
8
|
+
* A token lives at most `DELIVERY_TOKEN_MAX_TTL_SECONDS` (`TOKEN_TTL_MAX_SECONDS`), and key
|
|
9
9
|
* rotation waits at least that long before it revokes the previous key
|
|
10
10
|
* (`signing-keys.ts`), so a rotation never revokes a live token.
|
|
11
11
|
*/
|
|
12
12
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
13
|
import { errors, jwtVerify } from "jose";
|
|
14
|
-
import { DELIVERY_TOKEN_MAX_TTL_SECONDS, DELIVERY_TOKEN_TYPE,
|
|
14
|
+
import { DELIVERY_TOKEN_MAX_TTL_SECONDS, DELIVERY_TOKEN_TYPE, tenantTokenIssuer, } from "@nylorun/core/contracts";
|
|
15
15
|
import { failOpaque, HttpError } from "./http.js";
|
|
16
16
|
import { CLOCK_TOLERANCE_SECONDS, tokenKeyId } from "./jwt.js";
|
|
17
17
|
/** base64url SHA-256 of a request body: the token's `bdy` claim. */
|
|
@@ -34,7 +34,7 @@ export async function mintDeliveryToken(ctx, options) {
|
|
|
34
34
|
agt: delivery.agentId,
|
|
35
35
|
gen: delivery.kind === "action" ? delivery.generation : 0,
|
|
36
36
|
bdy: bodyHash(options.body),
|
|
37
|
-
iss:
|
|
37
|
+
iss: tenantTokenIssuer(ctx.config.tenantId),
|
|
38
38
|
aud: options.audience,
|
|
39
39
|
sub: delivery.kind === "action" ? delivery.actionId : "ping",
|
|
40
40
|
iat,
|
|
@@ -62,7 +62,7 @@ export async function verifyDeliveryToken(ctx, raw) {
|
|
|
62
62
|
try {
|
|
63
63
|
const verified = await jwtVerify(raw, await ctx.signingKeys.publicKey(row), {
|
|
64
64
|
algorithms: ["ES256"],
|
|
65
|
-
issuer:
|
|
65
|
+
issuer: tenantTokenIssuer(ctx.config.tenantId),
|
|
66
66
|
typ: DELIVERY_TOKEN_TYPE,
|
|
67
67
|
clockTolerance: CLOCK_TOLERANCE_SECONDS,
|
|
68
68
|
requiredClaims: ["sub", "aud", "iat", "exp", "jti"],
|
package/dist/tenant/effects.d.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core's side of effects: `resolveNewFlowEffect` journals and dispatches new workflow effects
|
|
3
|
+
* (linked agent sessions, tool nodes, fn, verify); the takeover helpers say which calls their
|
|
4
|
+
* gate recovers. Also vault authorization for MCP servers. The journal of a run's effects is
|
|
5
|
+
* `harness-api/record.ts`; a harness readies the session's MCP servers itself (`session.mcp`).
|
|
6
|
+
*
|
|
7
|
+
* Every journal write runs in a transaction that locks the effect's session first and checks
|
|
8
|
+
* the advance's ownership epoch (`ownedSession`): after another Worker takes over, the next
|
|
9
|
+
* write throws `ownership.lost` and nothing is written. The model, MCP, sandbox and vault
|
|
10
|
+
* calls run between transactions, never inside one.
|
|
11
|
+
*/
|
|
12
|
+
import type { ActionOutcome } from "@nylorun/core/contracts";
|
|
1
13
|
import type { EffectResolution, HostEffect } from "@nylorun/harness/run";
|
|
14
|
+
import type { Tx } from "../store/types.js";
|
|
2
15
|
import type { AuthorizeResult } from "../vault/service.js";
|
|
3
16
|
import { type Lease, type Session, type TenantContext } from "./context.js";
|
|
4
|
-
import type { ModelProvider } from "../core/provider.js";
|
|
5
|
-
/** What one advance's segment decides for all its effects. */
|
|
6
|
-
export interface SegmentOptions {
|
|
7
|
-
/** Overrides the Tenant's model (the fixture-model Tenant setting, `model-setting.ts`). */
|
|
8
|
-
model?: ModelProvider;
|
|
9
|
-
}
|
|
10
17
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* advance decides what the abort means.
|
|
18
|
+
* The outcome of a flow `agent` effect once the linked turn it started ended, or undefined
|
|
19
|
+
* while it has not. The linked session may still show an earlier iteration's turn.
|
|
14
20
|
*/
|
|
15
|
-
export declare function
|
|
21
|
+
export declare function linkedOutcome(t: Tx, effect: {
|
|
22
|
+
request: HostEffect;
|
|
23
|
+
agentSessionId?: string;
|
|
24
|
+
}, agent: Session | undefined): Promise<ActionOutcome | undefined>;
|
|
16
25
|
/**
|
|
17
26
|
* True when this Tenant's remote MCP calls outlive the process that sent them (the gates
|
|
18
27
|
* service, F4.1 G3): after a takeover or a shutdown, the journaled call is re-sent and joins
|
|
@@ -27,13 +36,14 @@ export declare function isRemoteMcpEffect(s: Session, request: HostEffect): bool
|
|
|
27
36
|
* the running call or gets its outcome, instead of becoming `uncertain`.
|
|
28
37
|
*/
|
|
29
38
|
export declare function recoversModelCalls(ctx: TenantContext): boolean;
|
|
30
|
-
export declare function resolveEffect(ctx: TenantContext, request: HostEffect, signal: AbortSignal, lease: Lease, segment?: SegmentOptions): Promise<EffectResolution>;
|
|
31
39
|
/** Journal and dispatch a new flow effect (agent / tool node / fn / verify). */
|
|
32
40
|
export declare function resolveNewFlowEffect(ctx: TenantContext, request: HostEffect, signal: AbortSignal, lease: Lease): Promise<EffectResolution>;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
/**
|
|
42
|
+
* The credential of an MCP server request made on behalf of a session: from its attached vaults,
|
|
43
|
+
* else the operator's credential resolver (`vault/sources.ts`).
|
|
44
|
+
*/
|
|
36
45
|
export declare function authorize(ctx: TenantContext, sessionId: string, request: {
|
|
37
46
|
url: string;
|
|
38
47
|
serverName?: string;
|
|
48
|
+
agentId?: string;
|
|
39
49
|
}): Promise<AuthorizeResult>;
|