@nylorun/runtime 0.26.0-beta → 0.28.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 +171 -0
- package/README.md +18 -14
- package/dist/adapters/execution/restate.d.ts +15 -18
- package/dist/adapters/execution/restate.js +31 -27
- package/dist/adapters/replication/pgoutput.d.ts +1 -1
- package/dist/adapters/replication/pgoutput.js +3 -2
- package/dist/adapters/sandbox/local.js +8 -5
- package/dist/adapters/sandbox/virtual.js +2 -2
- package/dist/adapters/streams/s2.d.ts +1 -1
- package/dist/adapters/streams/s2.js +18 -14
- package/dist/api/a2a/card.d.ts +4 -3
- package/dist/api/a2a/card.js +4 -4
- package/dist/api/a2a/endpoint.js +3 -4
- package/dist/api/a2a/protocol.js +4 -0
- package/dist/api/a2a/routes.d.ts +2 -6
- package/dist/api/a2a/routes.js +30 -25
- package/dist/api/ag-ui/endpoint.js +2 -3
- package/dist/api/ag-ui/routes.js +8 -11
- package/dist/api/components.d.ts +6789 -3405
- package/dist/api/components.js +43 -30
- package/dist/api/gate/keys.js +7 -4
- package/dist/api/gate/routes.d.ts +6 -2
- package/dist/api/gate/routes.js +15 -11
- package/dist/api/http/app.js +9 -4
- package/dist/api/http/body.d.ts +17 -3
- package/dist/api/http/body.js +35 -7
- package/dist/api/http/respond.js +6 -2
- package/dist/api/http/routes/access.js +5 -4
- package/dist/api/http/routes/agent-manifests.d.ts +10 -0
- package/dist/api/http/routes/agent-manifests.js +135 -0
- package/dist/api/http/routes/agents.d.ts +11 -0
- package/dist/api/http/routes/agents.js +418 -0
- package/dist/api/http/routes/artifacts.js +21 -9
- package/dist/api/http/routes/coverage.d.ts +4 -4
- package/dist/api/http/routes/coverage.js +13 -7
- package/dist/api/http/routes/files.d.ts +2 -1
- package/dist/api/http/routes/files.js +31 -5
- package/dist/api/http/routes/mcp.js +3 -3
- package/dist/api/http/routes/me.d.ts +1 -1
- package/dist/api/http/routes/me.js +1 -2
- package/dist/api/http/routes/memories.d.ts +9 -0
- package/dist/api/http/routes/memories.js +152 -0
- package/dist/api/http/routes/reads.d.ts +10 -111
- package/dist/api/http/routes/reads.js +51 -29
- package/dist/api/http/routes/sessions.js +26 -54
- package/dist/api/http/routes/tenant.d.ts +2 -2
- package/dist/api/http/routes/tenant.js +77 -24
- package/dist/api/http/routes/triggers.d.ts +10 -0
- package/dist/api/http/routes/triggers.js +180 -0
- package/dist/api/inbound-files.d.ts +3 -9
- package/dist/api/inbound-files.js +18 -24
- package/dist/api/openapi.js +73 -47
- package/dist/artifacts/disk.d.ts +10 -14
- package/dist/artifacts/disk.js +99 -95
- package/dist/artifacts/files.d.ts +13 -4
- package/dist/artifacts/files.js +27 -9
- package/dist/artifacts/folder-upload.d.ts +75 -0
- package/dist/artifacts/folder-upload.js +263 -0
- package/dist/artifacts/folders.d.ts +14 -8
- package/dist/artifacts/folders.js +19 -11
- package/dist/artifacts/links.js +7 -6
- package/dist/artifacts/parts.d.ts +9 -14
- package/dist/artifacts/parts.js +11 -9
- package/dist/artifacts/pipe.d.ts +15 -0
- package/dist/artifacts/pipe.js +71 -0
- package/dist/artifacts/quota.d.ts +36 -0
- package/dist/artifacts/quota.js +44 -0
- package/dist/artifacts/service.d.ts +25 -1
- package/dist/artifacts/service.js +72 -27
- package/dist/blob/fs.js +2 -1
- package/dist/blob/s3.d.ts +6 -2
- package/dist/blob/s3.js +9 -7
- package/dist/blob/types.d.ts +1 -1
- package/dist/blob/types.js +1 -1
- package/dist/core/flow-host.d.ts +0 -1
- package/dist/core/limits.d.ts +11 -35
- package/dist/core/limits.js +5 -73
- package/dist/core/sandbox-routes.js +0 -1
- package/dist/core/turn-manifest.d.ts +1 -2
- package/dist/core/turn-manifest.js +4 -28
- package/dist/execution/memory.d.ts +8 -5
- package/dist/execution/memory.js +8 -6
- package/dist/execution/types.d.ts +1 -6
- package/dist/execution/types.js +0 -5
- package/dist/gates/contract.d.ts +3 -2
- package/dist/gates/contract.js +1 -1
- package/dist/gates/egress-credentials.js +5 -4
- package/dist/gates/egress.d.ts +13 -13
- package/dist/gates/egress.js +19 -21
- package/dist/gates/fixture-model.js +13 -2
- package/dist/gates/handler.d.ts +1 -3
- package/dist/gates/handler.js +4 -3
- package/dist/gates/http-client.d.ts +4 -3
- package/dist/gates/http-client.js +5 -7
- package/dist/gates/http-tool.d.ts +24 -4
- package/dist/gates/http-tool.js +41 -13
- package/dist/gates/in-process.d.ts +2 -1
- package/dist/gates/in-process.js +17 -9
- package/dist/gates/inflight.d.ts +2 -2
- package/dist/gates/inflight.js +3 -2
- package/dist/gates/journal.js +5 -7
- package/dist/gates/mcp-handler.d.ts +4 -3
- package/dist/gates/mcp-handler.js +15 -5
- package/dist/gates/meter.js +6 -5
- package/dist/gates/model-gate.d.ts +11 -2
- package/dist/gates/policy.d.ts +34 -6
- package/dist/gates/policy.js +66 -18
- package/dist/gates/provider-gate.d.ts +22 -0
- package/dist/gates/provider-gate.js +30 -0
- package/dist/gates/tool-calls.d.ts +1 -3
- package/dist/gates/tool-calls.js +2 -3
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +5 -6
- package/dist/gates/tool-contract.d.ts +8 -5
- package/dist/gates/tool-contract.js +1 -1
- package/dist/gates/tool-gate.d.ts +18 -7
- package/dist/gates/tool-gate.js +49 -7
- package/dist/harness/calls.d.ts +27 -25
- package/dist/harness/calls.js +40 -46
- package/dist/harness/executors.d.ts +10 -3
- package/dist/harness/executors.js +53 -23
- package/dist/harness/main.js +2 -2
- package/dist/harness/pod.d.ts +2 -2
- package/dist/harness/pod.js +7 -6
- package/dist/harness/run-tokens.d.ts +4 -1
- package/dist/harness/run-tokens.js +6 -2
- package/dist/harness/service.d.ts +17 -14
- package/dist/harness/service.js +21 -35
- package/dist/harness/setup.d.ts +0 -2
- package/dist/harness/setup.js +21 -15
- package/dist/harness/ws-client.d.ts +2 -2
- package/dist/harness/ws-client.js +7 -5
- package/dist/harness/ws-port.d.ts +3 -4
- package/dist/harness/ws-port.js +3 -4
- package/dist/harness-api/artifacts.d.ts +20 -0
- package/dist/harness-api/artifacts.js +478 -0
- package/dist/harness-api/in-process.d.ts +2 -2
- package/dist/harness-api/in-process.js +18 -16
- package/dist/harness-api/record.d.ts +10 -9
- package/dist/harness-api/record.js +113 -157
- package/dist/harness-api/renew.d.ts +1 -1
- package/dist/harness-api/renew.js +2 -2
- package/dist/harness-api/server.d.ts +1 -16
- package/dist/harness-api/server.js +86 -73
- package/dist/harness-api/start.d.ts +27 -5
- package/dist/harness-api/start.js +102 -19
- package/dist/harness-api/tool-journal.d.ts +15 -10
- package/dist/harness-api/tool-journal.js +26 -24
- package/dist/harness-api/workspace.d.ts +0 -4
- package/dist/harness-api/workspace.js +4 -47
- package/dist/harness-api/ws-server.js +10 -10
- package/dist/host/create-host.js +2 -3
- package/dist/host/execution.js +2 -3
- package/dist/host/gates.d.ts +2 -9
- package/dist/host/gates.js +15 -12
- package/dist/host/http.d.ts +2 -4
- package/dist/host/http.js +5 -29
- package/dist/host/main.js +10 -3
- package/dist/host/operate.js +12 -3
- package/dist/host/stack-config.d.ts +11 -0
- package/dist/host/stack-config.js +21 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/index.js +2 -1
- package/dist/infra/readiness.d.ts +0 -2
- package/dist/infra/readiness.js +4 -3
- package/dist/keys/client.d.ts +1 -0
- package/dist/keys/client.js +2 -3
- package/dist/keys/contract.d.ts +0 -2
- package/dist/keys/contract.js +0 -2
- package/dist/keys/egress-ca.d.ts +0 -2
- package/dist/keys/egress-ca.js +2 -3
- package/dist/keys/keys.d.ts +15 -4
- package/dist/keys/keys.js +22 -1
- package/dist/keys/webhooks.d.ts +25 -0
- package/dist/keys/webhooks.js +62 -0
- package/dist/keys/x509.d.ts +8 -4
- package/dist/keys/x509.js +14 -5
- package/dist/management-openapi.json +3043 -1954
- package/dist/mcp/connect.d.ts +35 -26
- package/dist/mcp/connect.js +112 -141
- package/dist/mcp/pool.d.ts +27 -22
- package/dist/mcp/pool.js +34 -48
- package/dist/mcp/preview.d.ts +12 -5
- package/dist/mcp/preview.js +43 -26
- package/dist/mcp/snapshot.d.ts +35 -86
- package/dist/mcp/snapshot.js +93 -135
- package/dist/memory/service.d.ts +97 -0
- package/dist/memory/service.js +335 -0
- package/dist/memory/tool.d.ts +36 -0
- package/dist/memory/tool.js +84 -0
- package/dist/model/auth-store.js +5 -3
- package/dist/model/capabilities.d.ts +1 -1
- package/dist/model/catalog.d.ts +9 -36
- package/dist/model/catalog.js +6 -33
- package/dist/model/descriptor.d.ts +51 -0
- package/dist/model/descriptor.js +83 -0
- package/dist/model/models.d.ts +0 -3
- package/dist/model/models.js +3 -5
- package/dist/model/native-blocks.js +1 -1
- package/dist/model/pi-model.d.ts +16 -5
- package/dist/model/pi-model.js +86 -105
- package/dist/openapi.json +13653 -9986
- package/dist/reads/cursor.js +3 -1
- package/dist/reads/types.d.ts +3 -3
- package/dist/record/agent.d.ts +27 -0
- package/dist/record/agent.js +46 -0
- package/dist/record/append.d.ts +34 -2
- package/dist/record/append.js +50 -1
- package/dist/record/index.d.ts +2 -2
- package/dist/record/index.js +2 -2
- package/dist/redact.d.ts +1 -1
- package/dist/redact.js +3 -2
- package/dist/sandbox/egress-token.d.ts +3 -3
- package/dist/sandbox/egress-token.js +3 -3
- package/dist/sandbox/join.js +8 -7
- package/dist/sandbox/manager.d.ts +41 -41
- package/dist/sandbox/manager.js +112 -44
- package/dist/sandbox/placement.d.ts +2 -2
- package/dist/sandbox/placement.js +7 -10
- package/dist/sandbox/pods/client.d.ts +1 -10
- package/dist/sandbox/pods/client.js +8 -4
- package/dist/sandbox/pods/lifecycle.d.ts +25 -17
- package/dist/sandbox/pods/lifecycle.js +51 -29
- package/dist/sandbox/pods/network-gate.d.ts +4 -5
- package/dist/sandbox/pods/network-gate.js +7 -7
- package/dist/sandbox/pods/reconcile.js +14 -3
- package/dist/sandbox/pods/spec.js +8 -5
- package/dist/sandbox/policy.d.ts +7 -1
- package/dist/sandbox/policy.js +10 -3
- package/dist/sandbox/resolve.d.ts +11 -6
- package/dist/sandbox/resolve.js +19 -9
- package/dist/sandbox/setup.d.ts +6 -2
- package/dist/sandbox/setup.js +47 -14
- package/dist/sandbox/share.d.ts +5 -14
- package/dist/sandbox/share.js +5 -34
- package/dist/sandbox/skills.d.ts +7 -13
- package/dist/sandbox/skills.js +16 -31
- package/dist/sandbox/tenant-config.d.ts +2 -2
- package/dist/sandbox/tenant-config.js +4 -3
- package/dist/sandbox/tools.d.ts +7 -1
- package/dist/sandbox/tools.js +26 -26
- package/dist/sandbox/types.d.ts +10 -3
- package/dist/sandbox/types.js +9 -0
- package/dist/store/postgres/connect.d.ts +6 -5
- package/dist/store/postgres/connect.js +14 -11
- package/dist/store/postgres/control.js +13 -13
- package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
- package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
- package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
- package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
- package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
- package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
- package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
- package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
- package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +63 -0
- package/dist/store/postgres/reads.js +17 -82
- package/dist/store/postgres/record-writer.d.ts +4 -4
- package/dist/store/postgres/record-writer.js +9 -9
- package/dist/store/postgres/schema.d.ts +1382 -151
- package/dist/store/postgres/schema.js +191 -37
- package/dist/store/postgres/store.js +384 -105
- package/dist/store/postgres/tenant.js +1 -2
- package/dist/store/types.d.ts +172 -57
- package/dist/store/types.js +0 -1
- package/dist/streams/relay/core.d.ts +3 -3
- package/dist/streams/relay/core.js +9 -10
- package/dist/tenant/advance.js +41 -39
- package/dist/tenant/agent-manifests.d.ts +72 -0
- package/dist/tenant/agent-manifests.js +359 -0
- package/dist/tenant/agent-versions.d.ts +126 -0
- package/dist/tenant/agent-versions.js +389 -0
- package/dist/tenant/agents.d.ts +230 -0
- package/dist/tenant/{environments.js → agents.js} +493 -328
- package/dist/tenant/auth.d.ts +1 -1
- package/dist/tenant/auth.js +3 -3
- package/dist/tenant/commands.d.ts +63 -2
- package/dist/tenant/commands.js +240 -90
- package/dist/tenant/context.d.ts +57 -33
- package/dist/tenant/context.js +6 -2
- package/dist/tenant/definition-files.d.ts +25 -4
- package/dist/tenant/definition-files.js +85 -47
- package/dist/tenant/effects.js +15 -51
- package/dist/tenant/ephemeral.js +2 -1
- package/dist/tenant/history.d.ts +1 -1
- package/dist/tenant/history.js +1 -1
- package/dist/tenant/host-token.d.ts +3 -3
- package/dist/tenant/host-token.js +11 -10
- package/dist/tenant/http.d.ts +5 -8
- package/dist/tenant/http.js +9 -0
- package/dist/tenant/identity-file.d.ts +29 -6
- package/dist/tenant/identity-file.js +45 -15
- package/dist/tenant/issuers.d.ts +5 -5
- package/dist/tenant/issuers.js +34 -26
- package/dist/tenant/jwt.d.ts +8 -2
- package/dist/tenant/jwt.js +10 -2
- package/dist/tenant/limits.d.ts +87 -0
- package/dist/tenant/limits.js +172 -0
- package/dist/tenant/memories.d.ts +38 -0
- package/dist/tenant/memories.js +119 -0
- package/dist/tenant/module.d.ts +4 -1
- package/dist/tenant/module.js +9 -8
- package/dist/tenant/outbound.d.ts +11 -14
- package/dist/tenant/outbound.js +10 -15
- package/dist/tenant/reset.js +2 -2
- package/dist/tenant/run-grants.d.ts +6 -0
- package/dist/tenant/run-grants.js +7 -2
- package/dist/tenant/run-token.d.ts +0 -4
- package/dist/tenant/run-token.js +6 -11
- package/dist/tenant/runtime-limits.d.ts +24 -0
- package/dist/tenant/runtime-limits.js +27 -0
- package/dist/tenant/runtime.d.ts +1 -1
- package/dist/tenant/runtime.js +38 -43
- package/dist/tenant/session-streams.js +7 -6
- package/dist/tenant/session.d.ts +1 -1
- package/dist/tenant/session.js +1 -1
- package/dist/tenant/sessions.d.ts +28 -45
- package/dist/tenant/sessions.js +89 -209
- package/dist/tenant/signing-keys.d.ts +1 -1
- package/dist/tenant/signing-keys.js +5 -6
- package/dist/tenant/status.js +10 -10
- package/dist/tenant/streams.js +18 -20
- package/dist/tenant/sweep.d.ts +1 -21
- package/dist/tenant/sweep.js +51 -51
- package/dist/tenant/transcript.d.ts +70 -23
- package/dist/tenant/transcript.js +28 -22
- package/dist/tenant/triggers.d.ts +143 -0
- package/dist/tenant/triggers.js +715 -0
- package/dist/tenant/turn-timing.d.ts +11 -1
- package/dist/tenant/turn-timing.js +3 -1
- package/dist/tenant/types.d.ts +9 -14
- package/dist/tenant/worker.d.ts +4 -10
- package/dist/tenant/worker.js +10 -14
- package/dist/traces/ids.js +5 -1
- package/dist/traces/map.d.ts +10 -7
- package/dist/traces/map.js +16 -12
- package/dist/traces/otlp.d.ts +3 -3
- package/dist/traces/otlp.js +5 -3
- package/dist/traces/projector.d.ts +9 -4
- package/dist/traces/projector.js +13 -7
- package/dist/traces/read.js +6 -1
- package/dist/tuning.d.ts +390 -0
- package/dist/tuning.js +677 -0
- package/dist/vault/headers.js +4 -2
- package/dist/vault/service.d.ts +13 -8
- package/dist/vault/service.js +61 -17
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +13 -12
- package/dist/api/http/routes/environment-manifests.d.ts +0 -9
- package/dist/api/http/routes/environment-manifests.js +0 -118
- package/dist/api/http/routes/environments.d.ts +0 -11
- package/dist/api/http/routes/environments.js +0 -332
- package/dist/artifacts/export.d.ts +0 -8
- package/dist/artifacts/export.js +0 -204
- package/dist/artifacts/media-types.d.ts +0 -30
- package/dist/artifacts/media-types.js +0 -137
- package/dist/artifacts/workspace.d.ts +0 -60
- package/dist/artifacts/workspace.js +0 -45
- package/dist/media.d.ts +0 -10
- package/dist/media.js +0 -58
- package/dist/record/environment.d.ts +0 -25
- package/dist/record/environment.js +0 -44
- package/dist/sandbox/runtime-tools.d.ts +0 -9
- package/dist/sandbox/runtime-tools.js +0 -16
- package/dist/sandbox/session-sandbox.d.ts +0 -16
- package/dist/sandbox/session-sandbox.js +0 -77
- package/dist/tenant/artifact-tool.d.ts +0 -13
- package/dist/tenant/artifact-tool.js +0 -243
- package/dist/tenant/environment-manifests.d.ts +0 -57
- package/dist/tenant/environment-manifests.js +0 -200
- package/dist/tenant/environments.d.ts +0 -174
- package/dist/tenant/skill-tool.d.ts +0 -20
- package/dist/tenant/skill-tool.js +0 -67
- package/dist/tenant/tool-results.d.ts +0 -57
- package/dist/tenant/tool-results.js +0 -298
- package/dist/tenant/tool-search.d.ts +0 -39
- package/dist/tenant/tool-search.js +0 -103
package/dist/tenant/context.d.ts
CHANGED
|
@@ -19,8 +19,6 @@ import type { IssuerScope, SubjectScope, TenantEnvelope } from "@nylorun/core/co
|
|
|
19
19
|
import type { DurableCheckpoint, FlowCheckpoint } from "@nylorun/harness/run";
|
|
20
20
|
import type { AgentManifest, JsonValue, SandboxManifest } from "@nylorun/core/define";
|
|
21
21
|
import type { OutboxRequest, SessionStore, Tx } from "../store/types.js";
|
|
22
|
-
import type { FlowLimits } from "../core/limits.js";
|
|
23
|
-
import type { ModelProvider } from "../core/provider.js";
|
|
24
22
|
import type { ModelGate } from "../gates/model-gate.js";
|
|
25
23
|
import type { ToolGate } from "../gates/tool-gate.js";
|
|
26
24
|
import type { Keys } from "../keys/keys.js";
|
|
@@ -37,25 +35,33 @@ import type { StuckInvocation, Wake } from "../execution/types.js";
|
|
|
37
35
|
import type { WorkState } from "./scheduler.js";
|
|
38
36
|
import type { SigningKeys } from "./signing-keys.js";
|
|
39
37
|
import type { BlobStore } from "../blob/index.js";
|
|
40
|
-
import type { WorkspaceReader } from "../artifacts/workspace.js";
|
|
41
38
|
import type { RunGrants } from "./run-grants.js";
|
|
42
39
|
import type { TraceOptions } from "../traces/options.js";
|
|
43
40
|
import type { TraceContext } from "../traces/ids.js";
|
|
44
41
|
export interface Session {
|
|
45
42
|
id: string;
|
|
43
|
+
/** The Agent the session runs on (protocol 16; a definition id before). */
|
|
46
44
|
agentId: string;
|
|
47
45
|
ownerUserId: string;
|
|
48
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Session pin: the loop manifest the session runs, its Agent's manifest version's harness
|
|
48
|
+
* section as the harness runs it (`loopManifestOf`), or a flow's leaf agent.
|
|
49
|
+
*/
|
|
49
50
|
manifest: any;
|
|
50
51
|
manifestHash: string;
|
|
51
52
|
/**
|
|
52
|
-
* The
|
|
53
|
-
*
|
|
53
|
+
* The agent manifest version the session runs (protocol 16): its Agent's when it opened, and
|
|
54
|
+
* again at a turn's first segment when its Agent's version changed since (T3, `repinTurn`).
|
|
55
|
+
* Absent on a session opened before protocol 16.
|
|
54
56
|
*/
|
|
55
|
-
|
|
57
|
+
definition?: {
|
|
58
|
+
name: string;
|
|
59
|
+
version: number;
|
|
60
|
+
};
|
|
61
|
+
/** The pinned version's `harness.loop`: passed to the harness, never read by the Runtime. */
|
|
62
|
+
loop?: Record<string, unknown>;
|
|
56
63
|
/** Validated turn-manifest variants, keyed by hash (loops.md §4.2). */
|
|
57
64
|
variants?: Record<string, AgentManifest>;
|
|
58
|
-
implementationVersion: string;
|
|
59
65
|
info?: any;
|
|
60
66
|
status: string;
|
|
61
67
|
activeTurnId: string | null;
|
|
@@ -86,26 +92,35 @@ export interface Session {
|
|
|
86
92
|
* and the context core hands on (to the harness, tools and sandbox commands) is in it.
|
|
87
93
|
*/
|
|
88
94
|
turnTrace?: TraceContext;
|
|
95
|
+
/**
|
|
96
|
+
* What started the active turn when not a client (track T4): the trigger's run, or the session's
|
|
97
|
+
* own booked wake. A memory version written in the turn names its run (track T5).
|
|
98
|
+
*/
|
|
99
|
+
turnCause?: {
|
|
100
|
+
kind: "trigger" | "self";
|
|
101
|
+
triggerId: string;
|
|
102
|
+
runId: string;
|
|
103
|
+
};
|
|
89
104
|
creation: unknown;
|
|
90
105
|
mcpSnapshot?: McpSnapshot;
|
|
91
106
|
mcpDiagnostics?: readonly McpDiagnostic[];
|
|
92
107
|
/**
|
|
93
|
-
* The
|
|
94
|
-
* session's (the
|
|
108
|
+
* The Agent's environment the session runs on: since protocol 16 always its Agent's id. Its
|
|
109
|
+
* sandbox is the session's (the id keys the workspace) and its vault holds the session's
|
|
95
110
|
* credentials. It outlives the session.
|
|
96
111
|
*/
|
|
97
112
|
environmentId?: string;
|
|
98
|
-
/** The
|
|
113
|
+
/** The Agent's recipe version when the session last pinned (shown, never enforced). */
|
|
99
114
|
environmentVersion?: number;
|
|
100
115
|
/**
|
|
101
|
-
* The harness that runs the session's turns (R4.1), pinned when it opened: its
|
|
102
|
-
* harness
|
|
116
|
+
* The harness that runs the session's turns (R4.1), pinned when it opened: its manifest's
|
|
117
|
+
* `harness.id`, else `nylorun`. Absent on a session opened before R4: ours (`harnessOf`).
|
|
103
118
|
*/
|
|
104
119
|
harness?: string;
|
|
105
120
|
/**
|
|
106
121
|
* A flow agent's linked session: the session whose turn opened the flow tree. Its sessions
|
|
107
122
|
* share the tree's Environment, and their turns nest in the root's, so they do not hold the
|
|
108
|
-
* Environment against each other (`
|
|
123
|
+
* Environment against each other (`checkAgentTurn`).
|
|
109
124
|
*/
|
|
110
125
|
flowRootId?: string;
|
|
111
126
|
/**
|
|
@@ -115,8 +130,10 @@ export interface Session {
|
|
|
115
130
|
sandbox?: SandboxManifest;
|
|
116
131
|
/**
|
|
117
132
|
* Why the session takes no new turn: `protocol_11` for a session opened before protocol 11
|
|
118
|
-
* (migration 0020), `protocol_13` for one opened before protocol 13 (migration 0024)
|
|
119
|
-
*
|
|
133
|
+
* (migration 0020), `protocol_13` for one opened before protocol 13 (migration 0024),
|
|
134
|
+
* `protocol_15` for an agent session that pinned a `runtime` block before protocol 15
|
|
135
|
+
* (migrations 0029, 0030), `protocol_16` for one opened from a definition before protocol 16
|
|
136
|
+
* (migration 0032). Its history stays readable.
|
|
120
137
|
*/
|
|
121
138
|
closedReason?: string;
|
|
122
139
|
/**
|
|
@@ -140,7 +157,7 @@ export type AuthScope = {
|
|
|
140
157
|
}
|
|
141
158
|
/**
|
|
142
159
|
* A trusted issuer's token (Host feature `trusted-issuers`, F9-D12): one subject, with the
|
|
143
|
-
* issuer's scopes
|
|
160
|
+
* issuer's scopes and Agent grants, until `expiresAt` (ms). Only its expiry ends it.
|
|
144
161
|
*/
|
|
145
162
|
| {
|
|
146
163
|
kind: "token";
|
|
@@ -149,9 +166,8 @@ export type AuthScope = {
|
|
|
149
166
|
subject: string;
|
|
150
167
|
/** The issuer's scopes the token holds, which may add `studio`. */
|
|
151
168
|
scopes: ReadonlySet<IssuerScope>;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
environments?: readonly string[];
|
|
169
|
+
/** The Agents it reaches: `*`, else exact ids or `p/*` prefixes; empty reaches none. */
|
|
170
|
+
agents: readonly string[] | "*";
|
|
155
171
|
expiresAt: number;
|
|
156
172
|
/** The token's `jti`, or a hash of it. */
|
|
157
173
|
tokenId: string;
|
|
@@ -185,11 +201,15 @@ export interface TenantContext {
|
|
|
185
201
|
* else the harness that serves workspaces (`harness-api/workspace.ts`).
|
|
186
202
|
*/
|
|
187
203
|
readonly sandbox: WorkspacePort;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
204
|
+
/**
|
|
205
|
+
* True when the Runtime's model is not the vault's (scripted, the fixture model, an embedder's
|
|
206
|
+
* provider): `modelGate` serves it, and no vault model need be configured.
|
|
207
|
+
*/
|
|
208
|
+
readonly scriptedModel: boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Serves every model call (blueprint §15, protocol 15): the vault's model in this process or
|
|
211
|
+
* the gates service, or a scripted model (`providerModelGate`).
|
|
212
|
+
*/
|
|
193
213
|
readonly modelGate: ModelGate;
|
|
194
214
|
/**
|
|
195
215
|
* Serves remote MCP servers and HTTP tools (blueprint §12, F4.1): in this process, or the
|
|
@@ -208,11 +228,6 @@ export interface TenantContext {
|
|
|
208
228
|
* they mean, and a blob counts once a committed row names its key.
|
|
209
229
|
*/
|
|
210
230
|
readonly blobs: BlobStore;
|
|
211
|
-
/**
|
|
212
|
-
* How core reads a session's sandbox workspace at turn end, to export its outputs (F8.2): over
|
|
213
|
-
* this process's `sandbox` today; over the Harness API's `workspace.read` from F6.2.
|
|
214
|
-
*/
|
|
215
|
-
readonly workspaces: WorkspaceReader;
|
|
216
231
|
/**
|
|
217
232
|
* How the trace route (R7.5) makes spans: the resource and the content the installation exports
|
|
218
233
|
* (R7.2). Absent: `service.name` `nylorun`, no content.
|
|
@@ -267,7 +282,7 @@ export interface TenantContext {
|
|
|
267
282
|
abortLocal(sessionId: string, turnId?: string): void;
|
|
268
283
|
/**
|
|
269
284
|
* Sandbox pods (F7.2): the sandboxes service and the Runtime image pods copy the engine from.
|
|
270
|
-
* Absent without a cluster (`nylorun local sandbox enable`): kind `pod` is `
|
|
285
|
+
* Absent without a cluster (`nylorun local sandbox enable`): kind `pod` is `agent_unavailable`.
|
|
271
286
|
*/
|
|
272
287
|
readonly pods?: TenantPods;
|
|
273
288
|
/**
|
|
@@ -277,6 +292,12 @@ export interface TenantContext {
|
|
|
277
292
|
* sent); `true` without sandbox pods, where there is nothing to send.
|
|
278
293
|
*/
|
|
279
294
|
sandboxSignal(sandboxId: string, signal: SandboxSignal): Promise<boolean>;
|
|
295
|
+
/**
|
|
296
|
+
* Seam: arm a durable timer (`DurableExecution.timer`; track T4's triggers), outside any tx. The
|
|
297
|
+
* latest time for a key wins. `false` while the Tenant is closing (not armed): what it was for
|
|
298
|
+
* is in Postgres, and the sweep arms it again.
|
|
299
|
+
*/
|
|
300
|
+
timer(key: string, at: Date): Promise<boolean>;
|
|
280
301
|
/** This Tenant's execution invocations that need an operator, for Tenant status. */
|
|
281
302
|
readonly stuckInvocations?: () => Promise<StuckInvocation[]>;
|
|
282
303
|
/** Callbacks the Tenant sweep runs after its own steps (`sweep.ts`). */
|
|
@@ -286,12 +307,15 @@ export interface TenantContext {
|
|
|
286
307
|
}
|
|
287
308
|
/**
|
|
288
309
|
* What a request acting for a person may reach: that person's sessions, and, for a token
|
|
289
|
-
* caller, only sessions
|
|
310
|
+
* caller, only sessions on the Agents its grants reach (ids and `p/*` prefixes). Undefined means
|
|
311
|
+
* the whole Tenant.
|
|
290
312
|
*/
|
|
291
313
|
export interface SessionAccess {
|
|
292
314
|
readonly owner: string;
|
|
293
|
-
readonly agents?:
|
|
315
|
+
readonly agents?: readonly string[];
|
|
294
316
|
}
|
|
317
|
+
/** Whether `access` reaches sessions on Agent `agentId`. */
|
|
318
|
+
export declare function reachesAgent(access: SessionAccess | undefined, agentId: string): boolean;
|
|
295
319
|
/** The session, or a 404. Reads without locking. */
|
|
296
320
|
export declare function sessionOf(t: Tx, id: string, access?: SessionAccess): Promise<Session>;
|
|
297
321
|
/** Locks the session for the rest of the transaction and returns it, or a 404. */
|
package/dist/tenant/context.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { DEFAULT_HARNESS } from "@nylorun/core/contracts";
|
|
1
|
+
import { DEFAULT_HARNESS, agentGranted } from "@nylorun/core/contracts";
|
|
2
2
|
import { fail } from "./http.js";
|
|
3
|
+
/** Whether `access` reaches sessions on Agent `agentId`. */
|
|
4
|
+
export function reachesAgent(access, agentId) {
|
|
5
|
+
return access?.agents === undefined || agentGranted(access.agents, agentId);
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* `access`, when set, limits the request to the owner's sessions of the allowed agents:
|
|
5
9
|
* anything else is the same 404 as a missing session, so a subject cannot learn which session
|
|
@@ -9,7 +13,7 @@ function owned(session, access) {
|
|
|
9
13
|
if (!session ||
|
|
10
14
|
(access !== undefined &&
|
|
11
15
|
(session.ownerUserId !== access.owner ||
|
|
12
|
-
(access
|
|
16
|
+
!reachesAgent(access, session.agentId))))
|
|
13
17
|
return fail(404, "Session not found");
|
|
14
18
|
return session;
|
|
15
19
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DefinitionFileView } from "@nylorun/core/contracts";
|
|
2
|
-
import type
|
|
2
|
+
import { type BlobStore } from "../blob/index.js";
|
|
3
3
|
import type { Tx } from "../store/types.js";
|
|
4
4
|
import type { TenantContext } from "./context.js";
|
|
5
5
|
/** Where a definition file's bytes are in the Object store. */
|
|
@@ -8,7 +8,10 @@ export declare function definitionFileKey(sha256: string): string;
|
|
|
8
8
|
export declare function hasDefinitionFile(ctx: TenantContext, file: string): Promise<boolean>;
|
|
9
9
|
/**
|
|
10
10
|
* Stores the bytes of definition file `file`: `201` when they are new, `200` when the Tenant
|
|
11
|
-
* holds them already (the body is not read). Bytes that do not hash to `file` are a `400
|
|
11
|
+
* holds them already (the body is not read). Bytes that do not hash to `file` are a `400`; more
|
|
12
|
+
* than the Tenant's skill limit (`skills.config`) a `413`. The body streams to a staging key and is copied to
|
|
13
|
+
* the file's key only once its hash is checked, so no file is held in memory and bytes of
|
|
14
|
+
* another hash never replace a file at its key.
|
|
12
15
|
*/
|
|
13
16
|
export declare function putDefinitionFile(ctx: TenantContext, file: string, request: {
|
|
14
17
|
body: ReadableStream<Uint8Array> | null;
|
|
@@ -18,7 +21,25 @@ export declare function putDefinitionFile(ctx: TenantContext, file: string, requ
|
|
|
18
21
|
status: 200 | 201;
|
|
19
22
|
view: DefinitionFileView;
|
|
20
23
|
}>;
|
|
21
|
-
/**
|
|
22
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Why `document` cannot be stored for the files it names: the files the Tenant does not hold
|
|
26
|
+
* (`missing`), else each skill whose files hold more than `limitBytes` together (`oversized`).
|
|
27
|
+
* A file a skill names at two paths counts twice: a sandbox holds both.
|
|
28
|
+
*/
|
|
29
|
+
export declare function definitionFileIssues(t: Tx, document: unknown, limitBytes: number): Promise<{
|
|
30
|
+
missing: string[];
|
|
31
|
+
oversized: {
|
|
32
|
+
name: string;
|
|
33
|
+
bytes: number;
|
|
34
|
+
}[];
|
|
35
|
+
}>;
|
|
36
|
+
/** A definition file's bytes as a stream, or undefined when the Object store does not have them. */
|
|
37
|
+
export declare function openDefinitionFile(blobs: BlobStore, sha256: string, options?: {
|
|
38
|
+
range?: {
|
|
39
|
+
start: number;
|
|
40
|
+
end?: number;
|
|
41
|
+
};
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
}): Promise<ReadableStream<Uint8Array> | undefined>;
|
|
23
44
|
/** A definition file's bytes, or undefined when the Object store does not have them. */
|
|
24
45
|
export declare function readDefinitionFile(blobs: BlobStore, sha256: string, signal?: AbortSignal): Promise<Uint8Array | undefined>;
|
|
@@ -3,15 +3,22 @@
|
|
|
3
3
|
* today a skill's folder (`SkillManifest.files`). A client uploads each one once
|
|
4
4
|
* (`PUT /v1/files/sha256:<hex>`); its bytes go to the Object store at
|
|
5
5
|
* `definitions/sha256/<hex>`, and a `definition_files` row says the Tenant holds it. A
|
|
6
|
-
* definition naming a file the Tenant does not hold is refused (`definition_files_missing`)
|
|
7
|
-
*
|
|
6
|
+
* definition naming a file the Tenant does not hold is refused (`definition_files_missing`), and
|
|
7
|
+
* one whose skill's files hold more than the Tenant's skill limit together (`limit_exceeded`,
|
|
8
|
+
* `skills.config`, default 2 GiB). One file may be as large as a whole skill.
|
|
9
|
+
* The Runtime serves them to a run's harness (`definition.file`: our engine's skill tools read
|
|
10
|
+
* them) and gives a sandbox the skills' files.
|
|
8
11
|
*
|
|
9
12
|
* Files are never deleted here: `definition_file_uses` records which definition version names
|
|
10
13
|
* which file, for a later sweep.
|
|
11
14
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
15
|
+
import { randomUUID } from "node:crypto";
|
|
16
|
+
import { definitionFilesOf, isDefinitionFileHash, skillsOf, } from "@nylorun/core/contracts";
|
|
17
|
+
import { BlobTooLargeError } from "../blob/index.js";
|
|
14
18
|
import { fail } from "./http.js";
|
|
19
|
+
import { readSkillLimits } from "./limits.js";
|
|
20
|
+
/** Where an upload's bytes wait while their hash is checked; never read as a definition file. */
|
|
21
|
+
const STAGING_PREFIX = "definitions/uploads/";
|
|
15
22
|
/** Where a definition file's bytes are in the Object store. */
|
|
16
23
|
export function definitionFileKey(sha256) {
|
|
17
24
|
return `definitions/sha256/${sha256.slice("sha256:".length)}`;
|
|
@@ -26,73 +33,104 @@ export async function hasDefinitionFile(ctx, file) {
|
|
|
26
33
|
const sha256 = checkHash(file);
|
|
27
34
|
return (await ctx.store.tx((t) => t.definitionFile(sha256))) !== undefined;
|
|
28
35
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const tooLarge = () => fail(413, `A definition file may hold at most ${DEFINITION_FILE_MAX_BYTES} bytes`, {
|
|
36
|
+
function tooLarge(limitBytes) {
|
|
37
|
+
return fail(413, `A definition file may hold at most ${limitBytes} bytes, the Tenant's limit for a whole skill`, {
|
|
32
38
|
code: "limit_exceeded",
|
|
33
|
-
details: { limitBytes
|
|
39
|
+
details: { limitBytes },
|
|
34
40
|
});
|
|
35
|
-
if (declared !== undefined && declared > DEFINITION_FILE_MAX_BYTES) {
|
|
36
|
-
await body?.cancel().catch(() => undefined);
|
|
37
|
-
tooLarge();
|
|
38
|
-
}
|
|
39
|
-
if (body === null)
|
|
40
|
-
return new Uint8Array();
|
|
41
|
-
const chunks = [];
|
|
42
|
-
let size = 0;
|
|
43
|
-
const reader = body.getReader();
|
|
44
|
-
for (;;) {
|
|
45
|
-
const { done, value } = await reader.read();
|
|
46
|
-
if (done)
|
|
47
|
-
break;
|
|
48
|
-
size += value.byteLength;
|
|
49
|
-
if (size > DEFINITION_FILE_MAX_BYTES) {
|
|
50
|
-
await reader.cancel().catch(() => undefined);
|
|
51
|
-
tooLarge();
|
|
52
|
-
}
|
|
53
|
-
chunks.push(value);
|
|
54
|
-
}
|
|
55
|
-
return Buffer.concat(chunks);
|
|
56
41
|
}
|
|
57
42
|
/**
|
|
58
43
|
* Stores the bytes of definition file `file`: `201` when they are new, `200` when the Tenant
|
|
59
|
-
* holds them already (the body is not read). Bytes that do not hash to `file` are a `400
|
|
44
|
+
* holds them already (the body is not read). Bytes that do not hash to `file` are a `400`; more
|
|
45
|
+
* than the Tenant's skill limit (`skills.config`) a `413`. The body streams to a staging key and is copied to
|
|
46
|
+
* the file's key only once its hash is checked, so no file is held in memory and bytes of
|
|
47
|
+
* another hash never replace a file at its key.
|
|
60
48
|
*/
|
|
61
49
|
export async function putDefinitionFile(ctx, file, request, signal) {
|
|
62
50
|
const sha256 = checkHash(file);
|
|
63
|
-
const held = await ctx.store.tx((t) =>
|
|
51
|
+
const { held, maxBytes } = await ctx.store.tx(async (t) => ({
|
|
52
|
+
held: await t.definitionFile(sha256),
|
|
53
|
+
maxBytes: (await readSkillLimits(t)).totalBytes,
|
|
54
|
+
}));
|
|
64
55
|
if (held) {
|
|
65
56
|
await request.body?.cancel().catch(() => undefined);
|
|
66
57
|
return { status: 200, view: { sha256, size: held.size } };
|
|
67
58
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
details: { expected: sha256, actual },
|
|
74
|
-
});
|
|
75
|
-
// The key is the content's hash: a concurrent upload of the same file writes the same bytes.
|
|
76
|
-
await ctx.blobs.put(definitionFileKey(sha256), bytes, {
|
|
59
|
+
if (request.declaredBytes !== undefined && request.declaredBytes > maxBytes) {
|
|
60
|
+
await request.body?.cancel().catch(() => undefined);
|
|
61
|
+
tooLarge(maxBytes);
|
|
62
|
+
}
|
|
63
|
+
const options = {
|
|
77
64
|
...(request.contentType === undefined ? {} : { contentType: request.contentType }),
|
|
78
65
|
...(signal ? { signal } : {}),
|
|
79
|
-
}
|
|
66
|
+
};
|
|
67
|
+
const staging = `${STAGING_PREFIX}${randomUUID()}`;
|
|
68
|
+
let size;
|
|
69
|
+
try {
|
|
70
|
+
let staged;
|
|
71
|
+
try {
|
|
72
|
+
staged = await ctx.blobs.put(staging, request.body ?? new Uint8Array(), {
|
|
73
|
+
...options,
|
|
74
|
+
maxBytes,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (error instanceof BlobTooLargeError)
|
|
79
|
+
tooLarge(maxBytes);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
const actual = `sha256:${staged.sha256}`;
|
|
83
|
+
if (actual !== sha256)
|
|
84
|
+
fail(400, `The body's SHA-256 is ${actual}, not ${sha256}: upload a file at its own hash`, {
|
|
85
|
+
code: "invalid_request",
|
|
86
|
+
details: { expected: sha256, actual },
|
|
87
|
+
});
|
|
88
|
+
const got = await ctx.blobs.get(staging, signal ? { signal } : {});
|
|
89
|
+
if (!got)
|
|
90
|
+
throw new Error(`The Object store lost the upload of ${sha256} at ${staging}`);
|
|
91
|
+
// The key is the content's hash: a concurrent upload of the same file writes the same bytes.
|
|
92
|
+
await ctx.blobs.put(definitionFileKey(sha256), got.body, options);
|
|
93
|
+
size = staged.size;
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await ctx.blobs.delete(staging).catch(() => undefined);
|
|
97
|
+
}
|
|
80
98
|
const inserted = await ctx.store.tx((t) => t.insertDefinitionFile({
|
|
81
99
|
sha256,
|
|
82
100
|
kind: "skill",
|
|
83
|
-
size
|
|
101
|
+
size,
|
|
84
102
|
contentType: request.contentType ?? null,
|
|
85
103
|
createdAt: new Date().toISOString(),
|
|
86
104
|
}));
|
|
87
|
-
return { status: inserted ? 201 : 200, view: { sha256, size
|
|
105
|
+
return { status: inserted ? 201 : 200, view: { sha256, size } };
|
|
88
106
|
}
|
|
89
|
-
/**
|
|
90
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Why `document` cannot be stored for the files it names: the files the Tenant does not hold
|
|
109
|
+
* (`missing`), else each skill whose files hold more than `limitBytes` together (`oversized`).
|
|
110
|
+
* A file a skill names at two paths counts twice: a sandbox holds both.
|
|
111
|
+
*/
|
|
112
|
+
export async function definitionFileIssues(t, document, limitBytes) {
|
|
91
113
|
const named = [...definitionFilesOf(document)].sort();
|
|
92
114
|
if (named.length === 0)
|
|
93
|
-
return [];
|
|
115
|
+
return { missing: [], oversized: [] };
|
|
94
116
|
const held = await t.heldDefinitionFiles(named);
|
|
95
|
-
|
|
117
|
+
const missing = named.filter((sha256) => !held.has(sha256));
|
|
118
|
+
if (missing.length > 0)
|
|
119
|
+
return { missing, oversized: [] };
|
|
120
|
+
const oversized = [];
|
|
121
|
+
for (const skill of skillsOf(document)) {
|
|
122
|
+
let bytes = 0;
|
|
123
|
+
for (const hash of Object.values(skill.files ?? {}))
|
|
124
|
+
if (typeof hash === "string")
|
|
125
|
+
bytes += held.get(hash) ?? 0;
|
|
126
|
+
if (bytes > limitBytes)
|
|
127
|
+
oversized.push({ name: String(skill.name), bytes });
|
|
128
|
+
}
|
|
129
|
+
return { missing, oversized };
|
|
130
|
+
}
|
|
131
|
+
/** A definition file's bytes as a stream, or undefined when the Object store does not have them. */
|
|
132
|
+
export async function openDefinitionFile(blobs, sha256, options = {}) {
|
|
133
|
+
return (await blobs.get(definitionFileKey(sha256), options))?.body;
|
|
96
134
|
}
|
|
97
135
|
/** A definition file's bytes, or undefined when the Object store does not have them. */
|
|
98
136
|
export async function readDefinitionFile(blobs, sha256, signal) {
|
package/dist/tenant/effects.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { embeddedAgent, flowDelegateManifest, hashManifest, } from "@nylorun/core/define";
|
|
2
2
|
import { countActiveFlowWork, deriveAgentEffectSessionId, isFlowToolEffect, isWorkflowManifest, linkedMessageInput, linkedMessageKey, linkedTurnEnd, settleAgentEffect, } from "../core/flow-host.js";
|
|
3
3
|
import { mayDispatchMore } from "../core/limits.js";
|
|
4
|
+
import { readRuntimeLimits } from "./runtime-limits.js";
|
|
4
5
|
import { sessionCredentials } from "../vault/sources.js";
|
|
5
6
|
import { isRemoteMcpCall } from "../harness/calls.js";
|
|
6
7
|
import { isHttpToolCall } from "../gates/http-tool.js";
|
|
7
|
-
import { sandboxSpecOf } from "../sandbox/share.js";
|
|
8
|
-
import { withRuntimeTools, withSandbox } from "../sandbox/session-sandbox.js";
|
|
9
8
|
import { loadSession, ownedSession, sessionOf, } from "./context.js";
|
|
10
9
|
import { fail } from "./http.js";
|
|
11
10
|
import { turnManifestOf } from "./session.js";
|
|
@@ -41,7 +40,7 @@ export function recoversToolCalls(ctx) {
|
|
|
41
40
|
}
|
|
42
41
|
/** True when `request` calls a tool of a declared MCP server (every one is remote) or an HTTP tool. */
|
|
43
42
|
export function isGateToolEffect(s, request) {
|
|
44
|
-
return (isRemoteMcpCall({ rootManifest: s.manifest
|
|
43
|
+
return (isRemoteMcpCall({ rootManifest: s.manifest }, request) ||
|
|
45
44
|
isHttpToolCall(s.manifest, request));
|
|
46
45
|
}
|
|
47
46
|
/**
|
|
@@ -50,7 +49,7 @@ export function isGateToolEffect(s, request) {
|
|
|
50
49
|
* the running call or gets its outcome, instead of becoming `uncertain`.
|
|
51
50
|
*/
|
|
52
51
|
export function recoversModelCalls(ctx) {
|
|
53
|
-
return ctx.
|
|
52
|
+
return ctx.modelGate.recovers === true;
|
|
54
53
|
}
|
|
55
54
|
/** Journal and dispatch a new flow effect (agent or tool node). */
|
|
56
55
|
export async function resolveNewFlowEffect(ctx, request, signal, lease) {
|
|
@@ -87,7 +86,7 @@ export async function resolveNewFlowEffect(ctx, request, signal, lease) {
|
|
|
87
86
|
const active = await countActiveFlowWork(t, request.sessionId, request.turnId);
|
|
88
87
|
// When the run journaled the effect (R7.1); a queued effect keeps it once dispatched.
|
|
89
88
|
const startedAt = existing?.startedAt ?? new Date().toISOString();
|
|
90
|
-
if (!mayDispatchMore(active,
|
|
89
|
+
if (!mayDispatchMore(active, await readRuntimeLimits(t))) {
|
|
91
90
|
if (!existing || existing.status !== "queued")
|
|
92
91
|
await t.put("effects", request.effectId, {
|
|
93
92
|
request,
|
|
@@ -162,25 +161,22 @@ export async function resolveNewFlowEffect(ctx, request, signal, lease) {
|
|
|
162
161
|
if (exists)
|
|
163
162
|
return;
|
|
164
163
|
const definition = leafDefinition(workflow, body, request);
|
|
165
|
-
// The
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const pinned = inherited?.manifest ? inherited : runtimeTools(definition.manifest);
|
|
164
|
+
// The flow's Agent (Q6) reaches every agent in the tree: its sandbox and its vault. Each leaf
|
|
165
|
+
// session runs on it, with the flow's manifest version, and its leaf agent's loop manifest.
|
|
166
|
+
const sandbox = workflow.sandbox;
|
|
169
167
|
const created = {
|
|
170
168
|
id: agentSessionId,
|
|
171
|
-
agentId:
|
|
169
|
+
agentId: workflow.agentId,
|
|
172
170
|
ownerUserId: workflow.ownerUserId,
|
|
173
|
-
manifest:
|
|
174
|
-
manifestHash:
|
|
175
|
-
|
|
176
|
-
implementationVersion: definition.implementationVersion,
|
|
171
|
+
manifest: definition.manifest,
|
|
172
|
+
manifestHash: definition.manifestHash,
|
|
173
|
+
...(workflow.definition === undefined ? {} : { definition: workflow.definition }),
|
|
177
174
|
status: "idle",
|
|
178
175
|
activeTurnId: null,
|
|
179
176
|
creation: {
|
|
180
177
|
requestId: `flow-put-${request.effectId}`,
|
|
181
|
-
|
|
178
|
+
agent: workflow.agentId,
|
|
182
179
|
ownerUserId: workflow.ownerUserId,
|
|
183
|
-
...(workflow.environmentId === undefined ? {} : { environment: workflow.environmentId }),
|
|
184
180
|
},
|
|
185
181
|
flowRootId: workflow.flowRootId ?? workflow.id,
|
|
186
182
|
...(workflow.environmentId === undefined
|
|
@@ -191,7 +187,7 @@ export async function resolveNewFlowEffect(ctx, request, signal, lease) {
|
|
|
191
187
|
? {}
|
|
192
188
|
: { environmentVersion: workflow.environmentVersion }),
|
|
193
189
|
}),
|
|
194
|
-
...(
|
|
190
|
+
...(sandbox === undefined ? {} : { sandbox }),
|
|
195
191
|
};
|
|
196
192
|
await t.put("sessions", agentSessionId, created);
|
|
197
193
|
});
|
|
@@ -247,30 +243,6 @@ export async function resolveNewFlowEffect(ctx, request, signal, lease) {
|
|
|
247
243
|
return { status: "pending" };
|
|
248
244
|
});
|
|
249
245
|
}
|
|
250
|
-
/**
|
|
251
|
-
* The sandbox a linked session inherits from its tree's owner when that sandbox was chosen at
|
|
252
|
-
* open (pinned on the owner). A definition that declares its own sandbox keeps it, as before.
|
|
253
|
-
*/
|
|
254
|
-
function inheritedSandbox(owner, definition) {
|
|
255
|
-
const spec = owner?.sandbox;
|
|
256
|
-
if (!spec || sandboxSpecOf(definition.manifest))
|
|
257
|
-
return undefined;
|
|
258
|
-
if (isWorkflowManifest(definition.manifest))
|
|
259
|
-
return { spec };
|
|
260
|
-
const sandboxed = withSandbox(definition.manifest, spec);
|
|
261
|
-
if (!sandboxed.ok)
|
|
262
|
-
throw new Error(sandboxed.message);
|
|
263
|
-
return { spec, manifest: sandboxed.manifest, manifestHash: sandboxed.manifestHash };
|
|
264
|
-
}
|
|
265
|
-
/** A linked agent session's `runtime` block without a sandbox (R2b C11); undefined for a workflow. */
|
|
266
|
-
function runtimeTools(manifest) {
|
|
267
|
-
if (isWorkflowManifest(manifest))
|
|
268
|
-
return undefined;
|
|
269
|
-
const pinned = withRuntimeTools(manifest);
|
|
270
|
-
if (!pinned.ok)
|
|
271
|
-
throw new Error(pinned.message);
|
|
272
|
-
return { manifest: pinned.manifest, manifestHash: pinned.manifestHash };
|
|
273
|
-
}
|
|
274
246
|
/**
|
|
275
247
|
* The credential of an MCP server or HTTP tool request made on behalf of a session: from its
|
|
276
248
|
* Environment's vault (`vault/sources.ts`).
|
|
@@ -289,11 +261,7 @@ function leafDefinition(workflow, body, request) {
|
|
|
289
261
|
const flow = flowDelegateManifest(turnManifestOf(workflow), body.agentId);
|
|
290
262
|
if (!flow)
|
|
291
263
|
return fail(404, `Agent '${body.agentId}' is not a flow agent used as a tool`);
|
|
292
|
-
return {
|
|
293
|
-
manifest: flow,
|
|
294
|
-
manifestHash: hashManifest(flow),
|
|
295
|
-
implementationVersion: workflow.implementationVersion,
|
|
296
|
-
};
|
|
264
|
+
return { manifest: flow, manifestHash: hashManifest(flow) };
|
|
297
265
|
}
|
|
298
266
|
const leaf = isWorkflowManifest(workflow.manifest)
|
|
299
267
|
? embeddedAgent(workflow.manifest, body.flow ?? [], body.agentId)
|
|
@@ -301,9 +269,5 @@ function leafDefinition(workflow, body, request) {
|
|
|
301
269
|
if (!leaf || isWorkflowManifest(leaf))
|
|
302
270
|
return fail(404, `Agent '${body.agentId}' is not embedded in workflow '${workflow.manifest.id}'`);
|
|
303
271
|
const manifest = leaf;
|
|
304
|
-
return {
|
|
305
|
-
manifest,
|
|
306
|
-
manifestHash: hashManifest(manifest),
|
|
307
|
-
implementationVersion: workflow.implementationVersion,
|
|
308
|
-
};
|
|
272
|
+
return { manifest, manifestHash: hashManifest(manifest) };
|
|
309
273
|
}
|
package/dist/tenant/ephemeral.js
CHANGED
|
@@ -25,6 +25,7 @@ import { hostPaths, tenantPaths } from "./paths.js";
|
|
|
25
25
|
import { hostPrincipals } from "./principals.js";
|
|
26
26
|
import { openTenantRuntime } from "./runtime.js";
|
|
27
27
|
import { createTrustedIssuers } from "./issuers.js";
|
|
28
|
+
import { hostTuning } from "../tuning.js";
|
|
28
29
|
const nodeRequire = createRequire(import.meta.url);
|
|
29
30
|
function coreVersion() {
|
|
30
31
|
try {
|
|
@@ -127,7 +128,7 @@ export async function startEphemeralRuntime(options) {
|
|
|
127
128
|
await host?.close();
|
|
128
129
|
await module.close();
|
|
129
130
|
await streams.close();
|
|
130
|
-
await ownPool?.end({ timeout:
|
|
131
|
+
await ownPool?.end({ timeout: hostTuning().postgres.closeTimeoutSeconds });
|
|
131
132
|
if (!options.retainRoot)
|
|
132
133
|
rmSync(hostRoot, { recursive: true, force: true });
|
|
133
134
|
};
|
package/dist/tenant/history.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* transcript on the row too and checks the fold against it at every segment start.
|
|
17
17
|
*/
|
|
18
18
|
import type { LiveEvent } from "@nylorun/core/contracts";
|
|
19
|
-
export {
|
|
19
|
+
export { TranscriptFoldError, applyUpdate, applyUpdates, transcriptOf, transcriptUpdates, withTranscript, type TranscriptUpdate, } from "@nylorun/core/harness-api";
|
|
20
20
|
/** Where a session's fold starts. */
|
|
21
21
|
export interface SessionHistory {
|
|
22
22
|
/** The fold reads the record from this seq: a snapshot at or before the turn's start. */
|
package/dist/tenant/history.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { applyUpdate, transcriptOf } from "@nylorun/core/harness-api";
|
|
2
|
-
export {
|
|
2
|
+
export { TranscriptFoldError, applyUpdate, applyUpdates, transcriptOf, transcriptUpdates, withTranscript, } from "@nylorun/core/harness-api";
|
|
3
3
|
let shadow = false;
|
|
4
4
|
/** Shadow mode: keep the transcript on the session row and check the fold against it. */
|
|
5
5
|
export function transcriptShadow() {
|
|
@@ -5,8 +5,8 @@ export declare const HOST_TOKEN_TYP = "nylorun-host+jwt";
|
|
|
5
5
|
export declare const HOST_TOKEN_AUD = "nylorun-harness-api";
|
|
6
6
|
export declare const EGRESS_TOKEN_TYP = "nylorun-egress+jwt";
|
|
7
7
|
export declare const EGRESS_TOKEN_AUD = "nylorun-egress";
|
|
8
|
-
/** How long a host or egress token lives. The engine renews them before. */
|
|
9
|
-
export declare const
|
|
8
|
+
/** How long a host or egress token lives (`keys.hostTokenTtlSeconds`). The engine renews them before. */
|
|
9
|
+
export declare const hostTokenTtlSeconds: () => number;
|
|
10
10
|
/** What a verified host or egress token says. */
|
|
11
11
|
export interface HostClaims {
|
|
12
12
|
readonly tenantId: string;
|
|
@@ -37,7 +37,7 @@ export interface EgressTokenRequest {
|
|
|
37
37
|
/** The host epoch the join set. */
|
|
38
38
|
readonly epoch: number;
|
|
39
39
|
readonly podUid: string;
|
|
40
|
-
/** Seconds. Default and maximum `
|
|
40
|
+
/** Seconds. Default and maximum `keys.hostTokenTtlSeconds`. */
|
|
41
41
|
readonly ttl?: number;
|
|
42
42
|
}
|
|
43
43
|
/**
|