@nylorun/runtime 0.25.0-beta → 0.27.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 +169 -0
- package/README.md +26 -16
- 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.js +1 -1
- 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 +12 -18
- package/dist/api/ag-ui/endpoint.js +2 -3
- package/dist/api/ag-ui/routes.js +4 -4
- package/dist/api/components.d.ts +326 -45
- package/dist/api/components.js +5 -1
- 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.d.ts +2 -2
- package/dist/api/http/app.js +2 -2
- package/dist/api/http/body.d.ts +15 -3
- package/dist/api/http/body.js +15 -7
- package/dist/api/http/define.d.ts +1 -1
- package/dist/api/http/respond.js +7 -3
- package/dist/api/http/routes/access.js +5 -4
- package/dist/api/http/routes/artifacts.js +19 -7
- package/dist/api/http/routes/coverage.js +1 -1
- package/dist/api/http/routes/environment-manifests.js +1 -1
- package/dist/api/http/routes/environments.js +6 -6
- 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 +1 -1
- package/dist/api/http/routes/reads.d.ts +35 -0
- package/dist/api/http/routes/reads.js +50 -22
- package/dist/api/http/routes/sessions.js +12 -11
- package/dist/api/http/routes/tenant.d.ts +2 -2
- package/dist/api/http/routes/tenant.js +69 -16
- package/dist/api/inbound-files.d.ts +3 -9
- package/dist/api/inbound-files.js +18 -24
- package/dist/api/openapi.js +6 -2
- package/dist/artifacts/disk.d.ts +0 -4
- package/dist/artifacts/disk.js +77 -73
- 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 +70 -25
- 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/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 +4 -3
- package/dist/gates/egress.d.ts +9 -9
- package/dist/gates/egress.js +19 -19
- 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 +53 -17
- 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/model-gate.d.ts +11 -2
- package/dist/gates/policy.d.ts +28 -5
- package/dist/gates/policy.js +60 -17
- 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 +0 -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 +4 -9
- 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 +102 -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 +82 -73
- package/dist/harness-api/start.d.ts +20 -2
- package/dist/harness-api/start.js +57 -18
- 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 +2 -45
- 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 +0 -2
- package/dist/host/http.js +0 -27
- 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 +1 -3
- package/dist/keys/contract.js +1 -3
- package/dist/keys/egress-ca.d.ts +0 -2
- package/dist/keys/egress-ca.js +2 -3
- package/dist/keys/keys.js +6 -1
- package/dist/keys/x509.d.ts +8 -4
- package/dist/keys/x509.js +14 -5
- package/dist/management-openapi.json +1961 -994
- 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 +13 -6
- package/dist/mcp/preview.js +37 -20
- package/dist/mcp/snapshot.d.ts +35 -86
- package/dist/mcp/snapshot.js +93 -135
- 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 +866 -1218
- package/dist/reads/cursor.js +3 -1
- package/dist/record/append.d.ts +34 -2
- package/dist/record/append.js +50 -1
- package/dist/record/environment.d.ts +2 -0
- package/dist/record/environment.js +2 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- 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 +3 -2
- package/dist/sandbox/manager.d.ts +41 -41
- package/dist/sandbox/manager.js +112 -44
- package/dist/sandbox/placement.d.ts +1 -1
- package/dist/sandbox/placement.js +5 -8
- package/dist/sandbox/pods/client.d.ts +1 -10
- package/dist/sandbox/pods/client.js +8 -4
- package/dist/sandbox/pods/lifecycle.d.ts +19 -11
- package/dist/sandbox/pods/lifecycle.js +45 -23
- 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 +4 -1
- 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 +8 -3
- package/dist/sandbox/resolve.js +12 -2
- package/dist/sandbox/setup.d.ts +3 -1
- package/dist/sandbox/setup.js +34 -11
- 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/meta/_journal.json +28 -0
- package/dist/store/postgres/migrate.js +1 -1
- package/dist/store/postgres/reads.js +10 -2
- package/dist/store/postgres/schema.d.ts +19 -0
- package/dist/store/postgres/schema.js +7 -0
- package/dist/store/postgres/store.js +55 -26
- package/dist/store/types.d.ts +17 -7
- package/dist/streams/relay/core.d.ts +3 -3
- package/dist/streams/relay/core.js +9 -10
- package/dist/tenant/advance.js +21 -31
- package/dist/tenant/commands.js +9 -16
- package/dist/tenant/context.d.ts +14 -17
- package/dist/tenant/definition-files.d.ts +25 -4
- package/dist/tenant/definition-files.js +85 -47
- package/dist/tenant/effects.js +9 -36
- package/dist/tenant/environment-manifests.js +9 -1
- package/dist/tenant/environments.d.ts +0 -2
- package/dist/tenant/environments.js +54 -30
- package/dist/tenant/ephemeral.d.ts +1 -1
- 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 +12 -11
- package/dist/tenant/http.d.ts +5 -8
- package/dist/tenant/http.js +9 -0
- package/dist/tenant/identity-file.d.ts +24 -1
- package/dist/tenant/identity-file.js +35 -7
- package/dist/tenant/issuers.d.ts +5 -5
- package/dist/tenant/issuers.js +31 -23
- package/dist/tenant/jwt.d.ts +8 -2
- package/dist/tenant/jwt.js +10 -2
- package/dist/tenant/limits.d.ts +90 -0
- package/dist/tenant/limits.js +175 -0
- package/dist/tenant/module.d.ts +4 -1
- package/dist/tenant/module.js +9 -8
- package/dist/tenant/outbound.d.ts +17 -19
- package/dist/tenant/outbound.js +18 -21
- package/dist/tenant/run-grants.js +3 -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.js +30 -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.js +32 -29
- package/dist/tenant/signing-keys.d.ts +1 -1
- package/dist/tenant/signing-keys.js +5 -6
- package/dist/tenant/status.js +4 -3
- package/dist/tenant/streams.js +18 -20
- package/dist/tenant/sweep.d.ts +1 -21
- package/dist/tenant/sweep.js +39 -48
- package/dist/tenant/transcript.d.ts +70 -23
- package/dist/tenant/transcript.js +28 -22
- package/dist/tenant/types.d.ts +11 -16
- package/dist/tenant/worker.d.ts +2 -10
- package/dist/tenant/worker.js +5 -14
- package/dist/traces/ids.js +5 -1
- package/dist/traces/map.d.ts +9 -6
- package/dist/traces/map.js +9 -11
- 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 +383 -0
- package/dist/tuning.js +658 -0
- package/dist/vault/headers.js +4 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- 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/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/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/harness/calls.d.ts
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The calls a harness executes, as pure helpers over what routes them: the Model Gate
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The calls a harness executes, as pure helpers over what routes them: the Model Gate, the Tool
|
|
3
|
+
* Gate, the MCP pool, the SandboxManager. No store, no record: the session's routing comes with
|
|
4
|
+
* the run (`TurnStart.routing`). Every model call goes through the Model Gate, in a harness
|
|
5
|
+
* process and in core's alike (protocol 15): a Runtime with a scripted model serves it from a
|
|
6
|
+
* gate too (`providerModelGate`).
|
|
5
7
|
*/
|
|
6
|
-
import { type AgentManifest } from "@nylorun/core/define";
|
|
8
|
+
import { type AgentManifest, type SandboxManifest } from "@nylorun/core/define";
|
|
7
9
|
import type { HostEffect } from "@nylorun/harness/run";
|
|
10
|
+
import type { SandboxToolLimits } from "@nylorun/harness";
|
|
8
11
|
import type { AbortReason } from "@nylorun/core/harness-api";
|
|
9
|
-
import type { ModelProvider } from "../core/provider.js";
|
|
10
12
|
import type { ModelGate } from "../gates/model-gate.js";
|
|
11
13
|
import type { ToolGate } from "../gates/tool-gate.js";
|
|
12
14
|
import { type McpPool } from "../mcp/pool.js";
|
|
13
|
-
import { type McpSnapshot } from "../mcp/snapshot.js";
|
|
14
15
|
import type { SandboxManager } from "../sandbox/manager.js";
|
|
15
|
-
/** Where a Tenant's model calls go. */
|
|
16
|
+
/** Where a Tenant's model calls go: its Model Gate. */
|
|
16
17
|
export interface ModelRoute {
|
|
17
18
|
readonly tenantId: string;
|
|
18
19
|
readonly modelGate: ModelGate;
|
|
19
|
-
readonly modelProvider: ModelProvider;
|
|
20
|
-
/** True when the model comes from the Tenant vault selection, served by `modelGate`. */
|
|
21
|
-
readonly useVaultModel: boolean;
|
|
22
20
|
}
|
|
23
21
|
/** What a session's tool calls are routed by. */
|
|
24
22
|
export interface ToolRouting {
|
|
25
23
|
readonly rootManifest: AgentManifest;
|
|
26
|
-
readonly mcpSnapshot?: McpSnapshot;
|
|
27
24
|
/** The session that owns the tree's sandbox, and the sandbox resource it is attached to. */
|
|
28
25
|
readonly sandboxOwnerId: string;
|
|
26
|
+
/** The sandbox spec the session pinned (`routing.sandbox.spec`); absent without a sandbox. */
|
|
27
|
+
readonly spec?: SandboxManifest;
|
|
29
28
|
readonly environmentId?: string;
|
|
30
29
|
/** Variables every sandbox command gets (R2c): secret names set to the sentinel, plain values. */
|
|
31
30
|
readonly environment?: Readonly<Record<string, string>>;
|
|
@@ -34,14 +33,12 @@ export interface ToolRouting {
|
|
|
34
33
|
readonly claim?: string;
|
|
35
34
|
}
|
|
36
35
|
/**
|
|
37
|
-
* Call the model for one effect. A provider failure comes back as a
|
|
38
|
-
* (Model Calls §6), whichever provider serves the call; only an abort throws, and
|
|
39
|
-
* advance decides what the abort means.
|
|
40
|
-
*
|
|
36
|
+
* Call the model for one effect, through the Model Gate. A provider failure comes back as a
|
|
37
|
+
* failure outcome (Model Calls §6), whichever provider serves the call; only an abort throws, and
|
|
38
|
+
* the advance decides what the abort means. The Tenant's fixture model is answered at the gate
|
|
39
|
+
* too (R4.3).
|
|
41
40
|
*/
|
|
42
|
-
export declare function invokeModel(route: ModelRoute, request: HostEffect, signal: AbortSignal
|
|
43
|
-
readonly atGate?: boolean;
|
|
44
|
-
}): Promise<unknown>;
|
|
41
|
+
export declare function invokeModel(route: ModelRoute, request: HostEffect, signal: AbortSignal): Promise<unknown>;
|
|
45
42
|
/**
|
|
46
43
|
* A signal that follows `signal` only for the abort kinds in `kinds`. An MCP call stops on a
|
|
47
44
|
* cancel; at the Tool Gate it also stops waiting on a shutdown, since the gate keeps the call
|
|
@@ -49,13 +46,14 @@ export declare function invokeModel(route: ModelRoute, request: HostEffect, sign
|
|
|
49
46
|
* so the next advance replays it.
|
|
50
47
|
*/
|
|
51
48
|
export declare function abortOn(signal: AbortSignal, kinds: readonly AbortReason[]): AbortSignal;
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
export declare function isRemoteMcpCall(routing: Pick<ToolRouting, "rootManifest" | "mcpSnapshot">, request: HostEffect): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* True when `request` calls a tool of an MCP server its agent declares (every one is remote): an
|
|
51
|
+
* `mcp` call, by its target's `server` (protocol 15).
|
|
52
|
+
*/
|
|
53
|
+
export declare function isRemoteMcpCall(routing: Pick<ToolRouting, "rootManifest">, request: HostEffect): boolean;
|
|
58
54
|
export declare function callMcpTool(mcp: McpPool, routing: ToolRouting, request: HostEffect, signal: AbortSignal,
|
|
55
|
+
/** The run's Runtime limit `toolAnswerBytes`: the largest answer kept where this process holds the connection. */
|
|
56
|
+
maxResultBytes: number,
|
|
59
57
|
/** The call's span context (R7.4), sent as `traceparent` where this process holds the connection. */
|
|
60
58
|
traceparent?: string): Promise<unknown>;
|
|
61
59
|
/**
|
|
@@ -66,4 +64,8 @@ traceparent?: string): Promise<unknown>;
|
|
|
66
64
|
export declare function callHttpTool(gate: Pick<ToolGate, "callHttp">, request: HostEffect, signal: AbortSignal,
|
|
67
65
|
/** The call's span context (R7.4); the gates service reads its own from the journal. */
|
|
68
66
|
traceparent?: string): Promise<unknown>;
|
|
69
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Runs a `sandbox` call: the operation it names, in the session's sandbox (the one its agents
|
|
69
|
+
* used as tools share), held to the harness's sandbox tool limits.
|
|
70
|
+
*/
|
|
71
|
+
export declare function callSandboxTool(sandbox: SandboxManager, routing: ToolRouting, request: HostEffect, signal: AbortSignal, limits?: SandboxToolLimits): Promise<unknown>;
|
package/dist/harness/calls.js
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The calls a harness executes, as pure helpers over what routes them: the Model Gate
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The calls a harness executes, as pure helpers over what routes them: the Model Gate, the Tool
|
|
3
|
+
* Gate, the MCP pool, the SandboxManager. No store, no record: the session's routing comes with
|
|
4
|
+
* the run (`TurnStart.routing`). Every model call goes through the Model Gate, in a harness
|
|
5
|
+
* process and in core's alike (protocol 15): a Runtime with a scripted model serves it from a
|
|
6
|
+
* gate too (`providerModelGate`).
|
|
5
7
|
*/
|
|
6
|
-
import {
|
|
8
|
+
import { isSandboxToolName } from "@nylorun/core/define";
|
|
7
9
|
import { runAbortKind } from "@nylorun/harness/api";
|
|
8
10
|
import { httpToolRefOf } from "../gates/http-tool.js";
|
|
9
11
|
import { classifyThrown } from "../model/classify.js";
|
|
10
12
|
import { findServer } from "../mcp/pool.js";
|
|
11
|
-
import { manifestFor, mcpToolOf } from "../mcp/snapshot.js";
|
|
12
|
-
import { isPinnedRuntimeTool, sandboxToolSpec } from "../sandbox/runtime-tools.js";
|
|
13
13
|
/**
|
|
14
|
-
* Call the model for one effect. A provider failure comes back as a
|
|
15
|
-
* (Model Calls §6), whichever provider serves the call; only an abort throws, and
|
|
16
|
-
* advance decides what the abort means.
|
|
17
|
-
*
|
|
14
|
+
* Call the model for one effect, through the Model Gate. A provider failure comes back as a
|
|
15
|
+
* failure outcome (Model Calls §6), whichever provider serves the call; only an abort throws, and
|
|
16
|
+
* the advance decides what the abort means. The Tenant's fixture model is answered at the gate
|
|
17
|
+
* too (R4.3).
|
|
18
18
|
*/
|
|
19
|
-
export async function invokeModel(route, request, signal
|
|
20
|
-
const atGate = route.useVaultModel || options.atGate === true;
|
|
19
|
+
export async function invokeModel(route, request, signal) {
|
|
21
20
|
try {
|
|
22
|
-
if (!atGate)
|
|
23
|
-
return await route.modelProvider(request, signal);
|
|
24
21
|
return await route.modelGate.call({
|
|
25
22
|
tenantId: route.tenantId,
|
|
26
23
|
sessionId: request.sessionId,
|
|
@@ -28,6 +25,8 @@ export async function invokeModel(route, request, signal, options = {}) {
|
|
|
28
25
|
agentId: request.agentId,
|
|
29
26
|
effectId: request.effectId,
|
|
30
27
|
invocationId: String(request.context.invocationId),
|
|
28
|
+
...(request.agent === undefined ? {} : { agent: request.agent }),
|
|
29
|
+
...(request.purpose === undefined ? {} : { purpose: request.purpose }),
|
|
31
30
|
call: request.input,
|
|
32
31
|
}, signal);
|
|
33
32
|
}
|
|
@@ -35,7 +34,7 @@ export async function invokeModel(route, request, signal, options = {}) {
|
|
|
35
34
|
if (signal.aborted) {
|
|
36
35
|
// A call that outlives this process stops only when told to: on a user cancel. After a
|
|
37
36
|
// shutdown or a lost lease the next owner re-sends it and picks up its outcome (P1.2).
|
|
38
|
-
if (
|
|
37
|
+
if (runAbortKind(signal) === "cancel" && route.modelGate.cancel)
|
|
39
38
|
await route.modelGate.cancel({
|
|
40
39
|
tenantId: route.tenantId,
|
|
41
40
|
sessionId: request.sessionId,
|
|
@@ -65,43 +64,34 @@ export function abortOn(signal, kinds) {
|
|
|
65
64
|
signal.addEventListener("abort", follow, { once: true });
|
|
66
65
|
return controller.signal;
|
|
67
66
|
}
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/** True when `request` calls `read_artifact` (R2b C11), which the Runtime pinned on `manifest`. */
|
|
73
|
-
export function isReadArtifactCall(manifest, request) {
|
|
74
|
-
return isArtifactsToolCall(manifest, request, READ_ARTIFACT_TOOL);
|
|
75
|
-
}
|
|
76
|
-
function isArtifactsToolCall(manifest, request, toolName) {
|
|
77
|
-
return (request.kind === "tool" &&
|
|
78
|
-
request.toolName === toolName &&
|
|
79
|
-
isPinnedRuntimeTool(manifest, toolName));
|
|
80
|
-
}
|
|
81
|
-
/** True when `request` calls a tool of a declared MCP server (every one is remote). */
|
|
67
|
+
/**
|
|
68
|
+
* True when `request` calls a tool of an MCP server its agent declares (every one is remote): an
|
|
69
|
+
* `mcp` call, by its target's `server` (protocol 15).
|
|
70
|
+
*/
|
|
82
71
|
export function isRemoteMcpCall(routing, request) {
|
|
83
|
-
if (request.kind !== "tool")
|
|
72
|
+
if (request.kind !== "tool" || request.target?.kind !== "mcp")
|
|
84
73
|
return false;
|
|
85
|
-
|
|
86
|
-
if (!tool)
|
|
87
|
-
return false;
|
|
88
|
-
return findServer(routing.rootManifest, tool.agentId, tool.serverName) !== undefined;
|
|
74
|
+
return findServer(routing.rootManifest, request.agent?.id, request.target.server) !== undefined;
|
|
89
75
|
}
|
|
90
76
|
export async function callMcpTool(mcp, routing, request, signal,
|
|
77
|
+
/** The run's Runtime limit `toolAnswerBytes`: the largest answer kept where this process holds the connection. */
|
|
78
|
+
maxResultBytes,
|
|
91
79
|
/** The call's span context (R7.4), sent as `traceparent` where this process holds the connection. */
|
|
92
80
|
traceparent) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
81
|
+
// The call names its tool by its identity (protocol 15): the server, and its own name there.
|
|
82
|
+
const target = request.target;
|
|
83
|
+
if (target?.kind !== "mcp")
|
|
84
|
+
throw new Error(`'${request.toolName ?? ""}' is not an MCP tool call`);
|
|
96
85
|
return mcp.call({
|
|
97
86
|
sessionId: request.sessionId,
|
|
98
|
-
...(
|
|
99
|
-
serverName:
|
|
100
|
-
serverToolName: tool
|
|
87
|
+
...(request.agent === undefined ? {} : { agentId: request.agent.id }),
|
|
88
|
+
serverName: target.server,
|
|
89
|
+
serverToolName: target.tool,
|
|
101
90
|
args: request.input,
|
|
102
91
|
manifest: routing.rootManifest,
|
|
103
92
|
effectId: request.effectId,
|
|
104
93
|
...(traceparent ? { traceparent } : {}),
|
|
94
|
+
maxResultBytes,
|
|
105
95
|
signal,
|
|
106
96
|
});
|
|
107
97
|
}
|
|
@@ -123,17 +113,21 @@ traceparent) {
|
|
|
123
113
|
...(traceparent ? { traceparent } : {}),
|
|
124
114
|
}, signal);
|
|
125
115
|
}
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Runs a `sandbox` call: the operation it names, in the session's sandbox (the one its agents
|
|
118
|
+
* used as tools share), held to the harness's sandbox tool limits.
|
|
119
|
+
*/
|
|
120
|
+
export async function callSandboxTool(sandbox, routing, request, signal, limits) {
|
|
121
|
+
const { spec } = routing;
|
|
128
122
|
if (!spec)
|
|
129
|
-
throw new Error(`'${request.toolName ?? ""}'
|
|
130
|
-
|
|
123
|
+
throw new Error(`This session has no sandbox to run '${request.toolName ?? ""}' in`);
|
|
124
|
+
if (request.toolName === undefined || !isSandboxToolName(request.toolName))
|
|
125
|
+
throw new Error(`'${request.toolName ?? ""}' is not a sandbox operation`);
|
|
131
126
|
return sandbox.run({
|
|
132
127
|
id: routing.sandboxOwnerId,
|
|
133
128
|
activeTurnId: routing.activeTurnId,
|
|
134
|
-
manifest: routing.rootManifest,
|
|
135
129
|
...(routing.environmentId === undefined ? {} : { environmentId: routing.environmentId }),
|
|
136
130
|
...(routing.environment === undefined ? {} : { environment: routing.environment }),
|
|
137
131
|
...(routing.claim === undefined ? {} : { claim: routing.claim }),
|
|
138
|
-
}, spec, request.toolName, request.input, signal);
|
|
132
|
+
}, spec, request.toolName, request.input, signal, limits);
|
|
139
133
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SandboxToolLimits } from "@nylorun/harness";
|
|
1
2
|
import type { HarnessExecutors, HarnessRun, McpRecorder, PreparedRun } from "@nylorun/harness/api";
|
|
2
3
|
import type { ToolGate } from "../gates/tool-gate.js";
|
|
3
4
|
import { type McpPool } from "../mcp/pool.js";
|
|
@@ -10,12 +11,18 @@ export interface HarnessExecutorsOptions {
|
|
|
10
11
|
readonly mcp: McpPool;
|
|
11
12
|
/** The SandboxManager; a harness process creates it once `hello` names the Tenant. */
|
|
12
13
|
readonly sandbox: () => SandboxManager;
|
|
14
|
+
/**
|
|
15
|
+
* The sandbox tools' limits the calls run with: the harness's configuration, the same it gives
|
|
16
|
+
* `createHarness({ sandboxTools })`. Each left out is its default.
|
|
17
|
+
*/
|
|
18
|
+
readonly sandboxTools?: Partial<SandboxToolLimits>;
|
|
13
19
|
}
|
|
14
20
|
export declare function harnessExecutors(options: HarnessExecutorsOptions): HarnessExecutors;
|
|
15
21
|
/**
|
|
16
|
-
* Readies the run's MCP servers (§10.5 step 3):
|
|
17
|
-
* tools and records the snapshot (the first recorded wins);
|
|
18
|
-
* what failed.
|
|
22
|
+
* Readies the run's MCP servers (§10.5 step 3): a run without MCP facts (`turn.start.mcp`, the
|
|
23
|
+
* session's first) discovers their tools and records the snapshot (the first recorded wins);
|
|
24
|
+
* later ones reconnect the snapshot's servers and record what failed. Answers the facts the run
|
|
25
|
+
* goes on with. Nothing for a session without MCP servers.
|
|
19
26
|
*/
|
|
20
27
|
export declare function prepareMcp(pool: McpPool, run: HarnessRun, record: McpRecorder): Promise<PreparedRun | undefined>;
|
|
21
28
|
/** A run's routing, as the call helpers take it. Its sandbox events are claimed for the run. */
|
|
@@ -8,36 +8,42 @@
|
|
|
8
8
|
* (`--service harness`, `main.ts`) its own, whose sandbox events it claims from core.
|
|
9
9
|
*/
|
|
10
10
|
import { hashManifest } from "@nylorun/core/define";
|
|
11
|
+
import { sandboxToolLimitsOf } from "@nylorun/harness";
|
|
11
12
|
import { GateCallLost } from "../gates/tool-client.js";
|
|
12
13
|
import { serversOf } from "../mcp/pool.js";
|
|
13
|
-
import { mcpToolOf } from "../mcp/snapshot.js";
|
|
14
14
|
import { isHttpToolCall } from "../gates/http-tool.js";
|
|
15
|
-
import { abortOn, callHttpTool, callMcpTool, callSandboxTool, invokeModel, isRemoteMcpCall,
|
|
15
|
+
import { abortOn, callHttpTool, callMcpTool, callSandboxTool, invokeModel, isRemoteMcpCall, } from "./calls.js";
|
|
16
16
|
export function harnessExecutors(options) {
|
|
17
17
|
const recoversTools = options.toolGate.recovers === true;
|
|
18
|
+
const sandboxTools = sandboxToolLimitsOf(options.sandboxTools);
|
|
18
19
|
const atGate = (effect, run) => {
|
|
19
20
|
const routing = routingOf(run);
|
|
20
21
|
return isRemoteMcpCall(routing, effect) || isHttpToolCall(routing.rootManifest, effect);
|
|
21
22
|
};
|
|
22
23
|
const recovered = (effect, run) => recoversTools && atGate(effect, run);
|
|
23
24
|
return {
|
|
24
|
-
//
|
|
25
|
-
|
|
25
|
+
// Every call goes through the Model Gate (protocol 15); with the Tenant's fixture model on,
|
|
26
|
+
// the gate answers it (R4.3), metered like any call.
|
|
27
|
+
model: (effect, signal) => invokeModel(options.model, effect, signal),
|
|
26
28
|
tool(effect, signal, run, call) {
|
|
27
29
|
const routing = routingOf(run);
|
|
28
30
|
const traceparent = call?.traceparent;
|
|
29
31
|
// A call at the Tool Gate outlives a shutdown there; a local one finishes and is recorded.
|
|
30
32
|
const kinds = recovered(effect, run) ? ["cancel", "shutdown"] : ["cancel"];
|
|
33
|
+
// A call is routed by what it names as its target (protocol 15); a flow's HTTP stage names
|
|
34
|
+
// its stage.
|
|
31
35
|
if (isHttpToolCall(routing.rootManifest, effect))
|
|
32
36
|
return callHttpTool(options.toolGate, effect, abortOn(signal, kinds), traceparent);
|
|
33
37
|
// A sandbox command joins its call's span (R7.4): a CLI that reads TRACEPARENT traces under it.
|
|
34
|
-
if (
|
|
35
|
-
return callSandboxTool(options.sandbox(), traceparent ? { ...routing, environment: { ...routing.environment, TRACEPARENT: traceparent } } : routing, effect, signal);
|
|
36
|
-
|
|
38
|
+
if (effect.target?.kind === "sandbox")
|
|
39
|
+
return callSandboxTool(options.sandbox(), traceparent ? { ...routing, environment: { ...routing.environment, TRACEPARENT: traceparent } } : routing, effect, signal, sandboxTools);
|
|
40
|
+
if (effect.target?.kind !== "mcp")
|
|
41
|
+
throw new Error(`This harness runs no ${effect.target?.kind ?? "untargeted"} call of '${effect.toolName ?? ""}'`);
|
|
42
|
+
return callMcpTool(options.mcp, routing, effect, abortOn(signal, kinds), run.start.limits.toolAnswerBytes, traceparent);
|
|
37
43
|
},
|
|
38
44
|
recovers: {
|
|
39
45
|
get model() {
|
|
40
|
-
return options.model.
|
|
46
|
+
return options.model.modelGate.recovers === true;
|
|
41
47
|
},
|
|
42
48
|
tool: recovered,
|
|
43
49
|
},
|
|
@@ -51,12 +57,42 @@ export function harnessExecutors(options) {
|
|
|
51
57
|
});
|
|
52
58
|
},
|
|
53
59
|
prepare: (run, record) => prepareMcp(options.mcp, run, record),
|
|
60
|
+
files: {
|
|
61
|
+
read: (run, path, maxBytes, signal) => withSandbox(run, (session, spec) => options.sandbox().readBytes(session, spec, path, maxBytes, signal)),
|
|
62
|
+
write: (run, path, body, signal) => withSandbox(run, (session, spec) => options.sandbox().writeBytes(session, spec, path, body, signal)),
|
|
63
|
+
list: (run, dir, maxEntries, signal) => withSandbox(run, async (session, spec) => {
|
|
64
|
+
const listed = await options.sandbox().listFiles(session, spec, dir, maxEntries, signal);
|
|
65
|
+
return listed.kind === "listed"
|
|
66
|
+
? { kind: "listed", entries: listed.listing.entries, truncated: listed.listing.truncated }
|
|
67
|
+
: listed.kind === "missing"
|
|
68
|
+
? { kind: "missing" }
|
|
69
|
+
: listed;
|
|
70
|
+
}),
|
|
71
|
+
mount: (run, folder, files, read, signal) => withSandbox(run, (session, spec) => options.sandbox().mountFolder(session, spec, folder, files, read, signal)),
|
|
72
|
+
},
|
|
54
73
|
};
|
|
55
74
|
}
|
|
56
75
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
|
|
76
|
+
* Runs `use` on the run's sandbox (the session's, which its agents used as tools share), or
|
|
77
|
+
* answers `artifact.no_sandbox` for a session without one.
|
|
78
|
+
*/
|
|
79
|
+
async function withSandbox(run, use) {
|
|
80
|
+
const routing = routingOf(run);
|
|
81
|
+
const { spec } = routing;
|
|
82
|
+
if (spec === undefined)
|
|
83
|
+
return { kind: "failed", code: "artifact.no_sandbox", message: "This session has no sandbox." };
|
|
84
|
+
return use({
|
|
85
|
+
id: routing.sandboxOwnerId,
|
|
86
|
+
activeTurnId: routing.activeTurnId,
|
|
87
|
+
...(routing.environmentId === undefined ? {} : { environmentId: routing.environmentId }),
|
|
88
|
+
...(routing.claim === undefined ? {} : { claim: routing.claim }),
|
|
89
|
+
}, spec);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Readies the run's MCP servers (§10.5 step 3): a run without MCP facts (`turn.start.mcp`, the
|
|
93
|
+
* session's first) discovers their tools and records the snapshot (the first recorded wins);
|
|
94
|
+
* later ones reconnect the snapshot's servers and record what failed. Answers the facts the run
|
|
95
|
+
* goes on with. Nothing for a session without MCP servers.
|
|
60
96
|
*/
|
|
61
97
|
export async function prepareMcp(pool, run, record) {
|
|
62
98
|
const routing = routingOf(run);
|
|
@@ -65,38 +101,32 @@ export async function prepareMcp(pool, run, record) {
|
|
|
65
101
|
return undefined;
|
|
66
102
|
const sessionId = run.grant.sessionId;
|
|
67
103
|
let answer;
|
|
68
|
-
|
|
104
|
+
const facts = run.start.mcp;
|
|
105
|
+
if (!facts) {
|
|
69
106
|
const found = await pool.discover({
|
|
70
107
|
sessionId,
|
|
71
108
|
manifest,
|
|
72
109
|
manifestHash: hashManifest(manifest),
|
|
110
|
+
maxInstructionBytes: run.start.limits.recordEntryBytes,
|
|
73
111
|
signal: run.signal,
|
|
74
112
|
});
|
|
75
113
|
answer = await record({ snapshot: found.snapshot, diagnostics: found.diagnostics });
|
|
76
114
|
}
|
|
77
115
|
else {
|
|
78
|
-
const diagnostics = await pool.reconnect({
|
|
79
|
-
sessionId,
|
|
80
|
-
manifest,
|
|
81
|
-
tools: routing.mcpSnapshot.mcpTools,
|
|
82
|
-
signal: run.signal,
|
|
83
|
-
});
|
|
116
|
+
const diagnostics = await pool.reconnect({ sessionId, manifest, servers: facts.servers, signal: run.signal });
|
|
84
117
|
if (diagnostics.length === 0)
|
|
85
118
|
return undefined;
|
|
86
119
|
answer = await record({ diagnostics });
|
|
87
120
|
}
|
|
88
|
-
return {
|
|
89
|
-
sessionTools: answer.sessionTools,
|
|
90
|
-
...(answer.snapshot === undefined ? {} : { mcpSnapshot: answer.snapshot }),
|
|
91
|
-
};
|
|
121
|
+
return answer.mcp === undefined ? undefined : { mcp: answer.mcp };
|
|
92
122
|
}
|
|
93
123
|
/** A run's routing, as the call helpers take it. Its sandbox events are claimed for the run. */
|
|
94
124
|
export function routingOf(run) {
|
|
95
125
|
const { routing } = run.start;
|
|
96
126
|
return {
|
|
97
127
|
rootManifest: routing.rootManifest,
|
|
98
|
-
...(routing.mcpSnapshot ? { mcpSnapshot: routing.mcpSnapshot } : {}),
|
|
99
128
|
sandboxOwnerId: routing.sandbox?.ownerId ?? run.grant.sessionId,
|
|
129
|
+
...(routing.sandbox?.spec === undefined ? {} : { spec: routing.sandbox.spec }),
|
|
100
130
|
...(routing.sandbox?.environmentId === undefined ? {} : { environmentId: routing.sandbox.environmentId }),
|
|
101
131
|
...(routing.sandbox?.environment === undefined ? {} : { environment: routing.sandbox.environment }),
|
|
102
132
|
activeTurnId: run.grant.turnId,
|
package/dist/harness/main.js
CHANGED
|
@@ -28,6 +28,7 @@ import { podHost } from "./pod.js";
|
|
|
28
28
|
import { prepareDisk } from "./setup.js";
|
|
29
29
|
import { harnessRunTokens } from "./run-tokens.js";
|
|
30
30
|
import { startHarnessService } from "./service.js";
|
|
31
|
+
import { hostTuning } from "../tuning.js";
|
|
31
32
|
/**
|
|
32
33
|
* `baseline` is the allowlisted environment of a pod's sandbox tools (`baselineEnvironment`),
|
|
33
34
|
* read by `host/main.ts`: nothing here reads the process environment.
|
|
@@ -77,7 +78,6 @@ export async function runHarness(stack, baseline) {
|
|
|
77
78
|
: {}),
|
|
78
79
|
paths,
|
|
79
80
|
modelGate: httpModelGate({ url: config.gatesUrl, runTokens }),
|
|
80
|
-
useVaultModel: true,
|
|
81
81
|
toolGate: httpToolGate({ url: config.gatesUrl, runTokens }),
|
|
82
82
|
logger,
|
|
83
83
|
version: RUNTIME_VERSION,
|
|
@@ -107,7 +107,7 @@ export async function runHarness(stack, baseline) {
|
|
|
107
107
|
// Runs are given back (core resumes them in its next advance), then MCP and sandboxes stop.
|
|
108
108
|
pod?.stop();
|
|
109
109
|
void service
|
|
110
|
-
.stop(pod ?
|
|
110
|
+
.stop(pod ? hostTuning().harness.podStopMs : hostTuning().harness.stopMs)
|
|
111
111
|
.catch((error) => logger.warn("harness_stop_failed", { message: error instanceof Error ? error.message : String(error) }))
|
|
112
112
|
.finally(() => {
|
|
113
113
|
health.close();
|
package/dist/harness/pod.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { PodHostConfig } from "../host/stack-config.js";
|
|
2
|
-
/** How often the host and egress tokens are renewed. */
|
|
3
|
-
export declare const RENEW_MS: number;
|
|
4
2
|
/** What to run and copy on a new disk (`sandbox/setup.ts` in core), from the join answer. */
|
|
5
3
|
export interface DiskSetup {
|
|
6
4
|
readonly recipeVersion: number;
|
package/dist/harness/pod.js
CHANGED
|
@@ -15,8 +15,7 @@ import { randomUUID } from "node:crypto";
|
|
|
15
15
|
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
16
16
|
import { rootCertificates } from "node:tls";
|
|
17
17
|
import { dirname } from "node:path";
|
|
18
|
-
|
|
19
|
-
export const RENEW_MS = 5 * 60_000;
|
|
18
|
+
import { hostTuning } from "../tuning.js";
|
|
20
19
|
/** The variables CLIs read their trust bundle from: OpenSSL, Node, Python, curl, git, AWS. */
|
|
21
20
|
const TRUST_VARIABLES = [
|
|
22
21
|
"SSL_CERT_FILE",
|
|
@@ -44,7 +43,7 @@ export function podHost(config, logger, options = {}) {
|
|
|
44
43
|
...(init.bearer ? { authorization: `Bearer ${init.bearer}` } : {}),
|
|
45
44
|
},
|
|
46
45
|
...(init.body === undefined ? {} : { body: JSON.stringify(init.body) }),
|
|
47
|
-
signal: AbortSignal.timeout(
|
|
46
|
+
signal: AbortSignal.timeout(hostTuning().harness.podJoinTimeoutMs),
|
|
48
47
|
});
|
|
49
48
|
const text = await response.text();
|
|
50
49
|
if (response.status === 401 || response.status === 400)
|
|
@@ -109,11 +108,13 @@ export function podHost(config, logger, options = {}) {
|
|
|
109
108
|
};
|
|
110
109
|
/** A request with a current host token: the held one, renewed near expiry, or a new join. */
|
|
111
110
|
const authorized = async (path, init) => {
|
|
112
|
-
const current = held && held.expiresAt - Date.now() >
|
|
111
|
+
const current = held && held.expiresAt - Date.now() > hostTuning().harness.podRenewEarlyMs
|
|
112
|
+
? held
|
|
113
|
+
: ((await renew()) ?? (await join()));
|
|
113
114
|
return call(`${config.httpUrl}/nylorun/harness/v1/host/${path}`, {
|
|
114
115
|
...init,
|
|
115
116
|
headers: { ...init.headers, authorization: `Bearer ${current.hostToken}` },
|
|
116
|
-
signal: AbortSignal.timeout(
|
|
117
|
+
signal: AbortSignal.timeout(hostTuning().harness.podRequestTimeoutMs),
|
|
117
118
|
});
|
|
118
119
|
};
|
|
119
120
|
const renew = async () => {
|
|
@@ -134,7 +135,7 @@ export function podHost(config, logger, options = {}) {
|
|
|
134
135
|
};
|
|
135
136
|
const timer = setInterval(() => {
|
|
136
137
|
void renew().catch((error) => logger.warn("sandbox_host_renew_failed", { message: error instanceof Error ? error.message : String(error) }));
|
|
137
|
-
}, options.renewMs ??
|
|
138
|
+
}, options.renewMs ?? hostTuning().harness.podRenewMs);
|
|
138
139
|
timer.unref();
|
|
139
140
|
return {
|
|
140
141
|
async token() {
|
|
@@ -14,5 +14,8 @@ export interface HarnessRunTokens {
|
|
|
14
14
|
/** Keeps a run's grant: `createHarness({ onGrant })`. */
|
|
15
15
|
grant(grant: RunGrant): void;
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Remembers the last token of at most `limit` sessions (least recently granted dropped first).
|
|
19
|
+
* Default `harness.runTokensMax` (Host tuning, 10,000).
|
|
20
|
+
*/
|
|
18
21
|
export declare function harnessRunTokens(limit?: number): HarnessRunTokens;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { hostTuning } from "../tuning.js";
|
|
2
|
+
/**
|
|
3
|
+
* Remembers the last token of at most `limit` sessions (least recently granted dropped first).
|
|
4
|
+
* Default `harness.runTokensMax` (Host tuning, 10,000).
|
|
5
|
+
*/
|
|
6
|
+
export function harnessRunTokens(limit = hostTuning().harness.runTokensMax) {
|
|
3
7
|
const tokens = new Map();
|
|
4
8
|
return {
|
|
5
9
|
token: (sessionId) => tokens.get(sessionId),
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { HarnessOptions } from "@nylorun/harness/api";
|
|
2
|
-
import type { ModelProvider } from "../core/provider.js";
|
|
3
2
|
import type { ModelGate } from "../gates/model-gate.js";
|
|
4
|
-
import type
|
|
5
|
-
import { McpPool } from "../mcp/pool.js";
|
|
3
|
+
import { type ToolGate } from "../gates/tool-gate.js";
|
|
6
4
|
import type { SandboxBackend } from "../sandbox/types.js";
|
|
7
5
|
import { type HarnessClient, type HarnessClientOptions } from "./ws-client.js";
|
|
6
|
+
import { type EngineTuning } from "../tuning.js";
|
|
8
7
|
export interface HarnessServiceOptions {
|
|
9
8
|
readonly url: string;
|
|
10
9
|
readonly token: HarnessClientOptions["token"];
|
|
@@ -12,24 +11,23 @@ export interface HarnessServiceOptions {
|
|
|
12
11
|
readonly paths: {
|
|
13
12
|
readonly sandboxes: string;
|
|
14
13
|
};
|
|
15
|
-
/**
|
|
14
|
+
/** Every model call (the gates service's client; a scripted model's gate in tests). */
|
|
16
15
|
readonly modelGate: ModelGate;
|
|
17
|
-
/** Models served without the vault; a harness process has none (`useVaultModel`). */
|
|
18
|
-
readonly modelProvider?: ModelProvider;
|
|
19
|
-
readonly useVaultModel: boolean;
|
|
20
|
-
/** Remote MCP servers (`openMcp`) and keyed cancels; the gates service's client. */
|
|
21
|
-
readonly toolGate: Pick<ToolGate, "recovers" | "cancel" | "openMcp" | "callHttp">;
|
|
22
16
|
/**
|
|
23
|
-
*
|
|
24
|
-
* opens
|
|
17
|
+
* Remote MCP servers (`openMcp`), HTTP tools and keyed cancels: the gates service's client. A
|
|
18
|
+
* harness process has no vault: it opens MCP servers only through the Tool Gate.
|
|
25
19
|
*/
|
|
26
|
-
readonly
|
|
27
|
-
/** How remote MCP servers opened in this process are reached (`TenantConfig.delivery`). */
|
|
28
|
-
readonly delivery?: ConstructorParameters<typeof McpPool>[0]["policy"];
|
|
20
|
+
readonly toolGate: Pick<ToolGate, "recovers" | "cancel" | "openMcp" | "callHttp">;
|
|
29
21
|
/** Default: the virtual backend under `paths.sandboxes`. */
|
|
30
22
|
readonly sandboxBackends?: readonly SandboxBackend[];
|
|
31
23
|
/** Delete the workspaces on stop (an ephemeral Runtime's loopback harness). */
|
|
32
24
|
readonly ephemeral?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* The sandbox tools' limits: what our engine's schemas name and what this harness runs them
|
|
27
|
+
* with. Default the Host tuning's `engine.sandboxTools`; each left out is its default
|
|
28
|
+
* (`DEFAULT_SANDBOX_TOOL_LIMITS`).
|
|
29
|
+
*/
|
|
30
|
+
readonly sandboxTools?: HarnessOptions["sandboxTools"];
|
|
33
31
|
readonly logger: HarnessClientOptions["logger"];
|
|
34
32
|
readonly version?: string;
|
|
35
33
|
readonly onGrant?: HarnessOptions["onGrant"];
|
|
@@ -41,4 +39,9 @@ export interface HarnessService {
|
|
|
41
39
|
/** Stops leasing and gives runs back (at most `waitMs`), then closes MCP and sandboxes. */
|
|
42
40
|
stop(waitMs?: number): Promise<void>;
|
|
43
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* The options of `createHarness` the Host tuning's `engine` group sets (`tuning.ts`): only the
|
|
44
|
+
* ones set, so the engine keeps its own default for the rest.
|
|
45
|
+
*/
|
|
46
|
+
export declare function engineOptionsOf(engine: EngineTuning): Pick<HarnessOptions, keyof EngineTuning>;
|
|
44
47
|
export declare function startHarnessService(options: HarnessServiceOptions): HarnessService;
|