@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/mcp/snapshot.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { delegatesOf, pluginOf, delegateManifest, mcpToolSettings, } from "@nylorun/core/define";
|
|
2
|
+
import { findServer } from "./pool.js";
|
|
3
3
|
/**
|
|
4
|
-
* The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot
|
|
5
|
-
*
|
|
4
|
+
* The `mcp.discovered` payload: each server's outcome, with the tools it added to the snapshot
|
|
5
|
+
* that its settings in `manifest` (the session's pinned one) leave enabled, and the Agent Plugin
|
|
6
|
+
* that brought the server.
|
|
6
7
|
*/
|
|
7
8
|
export function mcpDiscovered(snapshot, diagnostics, manifest) {
|
|
8
9
|
const agents = new Map(manifest === undefined
|
|
9
10
|
? []
|
|
10
11
|
: [[undefined, manifest], ...delegatesOf(manifest).map(({ manifest: child }) => [child.id, child])]);
|
|
11
|
-
const key = (
|
|
12
|
+
const key = (agentId, serverName) => JSON.stringify([agentId ?? null, serverName]);
|
|
12
13
|
const tools = new Map();
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
tools.set(key(
|
|
16
|
-
if (tool.deferred)
|
|
17
|
-
deferred.set(key(tool), (deferred.get(key(tool)) ?? 0) + 1);
|
|
14
|
+
for (const server of snapshot.servers) {
|
|
15
|
+
const enabled = server.tools.filter((tool) => manifest === undefined || isEnabledIn(manifest, server.agentId, server.name, tool.name));
|
|
16
|
+
tools.set(key(server.agentId, server.name), enabled.length);
|
|
18
17
|
}
|
|
19
18
|
return {
|
|
20
19
|
servers: diagnostics.map((item) => ({
|
|
@@ -23,149 +22,108 @@ export function mcpDiscovered(snapshot, diagnostics, manifest) {
|
|
|
23
22
|
...withPlugin(pluginOf(agents.get(item.agentId), { server: item.serverName })),
|
|
24
23
|
outcome: item.outcome,
|
|
25
24
|
message: item.message,
|
|
26
|
-
tools: tools.get(key(item)) ?? 0,
|
|
27
|
-
...(deferred.has(key(item)) ? { deferred: deferred.get(key(item)) } : {}),
|
|
25
|
+
tools: tools.get(key(item.agentId, item.serverName)) ?? 0,
|
|
28
26
|
...(item.disabled ? { disabled: item.disabled } : {}),
|
|
29
27
|
...(item.unknownTools?.length ? { unknownTools: [...item.unknownTools] } : {}),
|
|
30
28
|
...(item.credentialIds === undefined ? {} : { credentialIds: [...item.credentialIds] }),
|
|
31
|
-
...(item.renamed?.length ? { renamed: item.renamed.map((tool) => ({ ...tool })) } : {}),
|
|
32
29
|
})),
|
|
33
30
|
};
|
|
34
31
|
}
|
|
35
32
|
function withPlugin(plugin) {
|
|
36
33
|
return plugin === undefined ? {} : { plugin };
|
|
37
34
|
}
|
|
38
|
-
/** The
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* Bedrock and Gemini on Vertex do not. A name over 64 characters, or one that collides
|
|
44
|
-
* (`suffixed`), keeps 55 and adds `_` and 8 hex characters of the SHA-256 of the raw
|
|
45
|
-
* `server/tool`.
|
|
46
|
-
*/
|
|
47
|
-
export function normalizeToolName(serverName, serverToolName, options = {}) {
|
|
48
|
-
const name = `${serverName}__${serverToolName}`.replace(/[^A-Za-z0-9_-]/gu, "_");
|
|
49
|
-
if (name.length <= MODEL_TOOL_NAME_MAX && !options.suffixed)
|
|
50
|
-
return name;
|
|
51
|
-
const hash = createHash("sha256")
|
|
52
|
-
.update(`${serverName}/${serverToolName}`)
|
|
53
|
-
.digest("hex")
|
|
54
|
-
.slice(0, 8);
|
|
55
|
-
return `${name.slice(0, MODEL_TOOL_NAME_MAX - 9)}_${hash}`;
|
|
56
|
-
}
|
|
57
|
-
/** The names of the agent's tools: its own and those the Runtime pinned. */
|
|
58
|
-
export function declaredToolNames(manifest) {
|
|
59
|
-
return new Set([...(manifest.tools ?? []), ...(manifest.runtime?.tools ?? [])].map((tool) => tool.name));
|
|
60
|
-
}
|
|
61
|
-
/** The declaration of the server a tool of the snapshot comes from, in `manifest`. */
|
|
62
|
-
function serverOf(manifest, tool) {
|
|
63
|
-
const agent = tool.agentId === undefined ? manifest : delegateManifest(manifest, tool.agentId);
|
|
64
|
-
return agent?.mcpServers?.[tool.serverName];
|
|
35
|
+
/** The tool `tool` of server `server` of agent `agentId` (the root when absent), as discovered. */
|
|
36
|
+
export function mcpToolIn(snapshot, agentId, server, tool) {
|
|
37
|
+
return snapshot?.servers
|
|
38
|
+
.find((item) => item.agentId === agentId && item.name === server)
|
|
39
|
+
?.tools.find((item) => item.name === tool);
|
|
65
40
|
}
|
|
66
41
|
/** The tool's settings in `manifest` (R2b C9); the defaults when its server is not there. */
|
|
67
|
-
export function mcpToolSettingsIn(manifest, tool) {
|
|
68
|
-
const
|
|
69
|
-
return
|
|
42
|
+
export function mcpToolSettingsIn(manifest, agentId, server, tool) {
|
|
43
|
+
const declared = findServer(manifest, agentId, server);
|
|
44
|
+
return declared ? mcpToolSettings(declared.server, tool) : { enabled: true, approval: "never" };
|
|
45
|
+
}
|
|
46
|
+
/** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
|
|
47
|
+
export function isEnabledIn(manifest, agentId, server, tool) {
|
|
48
|
+
return mcpToolSettingsIn(manifest, agentId, server, tool).enabled;
|
|
70
49
|
}
|
|
71
50
|
/**
|
|
72
|
-
* The
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* or the Tenant's tool policy asks a person about (R5 step 2);
|
|
77
|
-
* - a deferred tool (R2b C10) is marked so, out of the model's list, and its agent gets the
|
|
78
|
-
* session tools `tool_search`, with the note on the servers it holds deferred tools of, and
|
|
79
|
-
* `tool_call`. Their names are reserved: no tool of the agent's own takes them.
|
|
80
|
-
*
|
|
81
|
-
* Nothing here changes between the steps of a turn, so neither does the model's tool list.
|
|
51
|
+
* The snapshot's facts for a turn whose manifest is `manifest` (the session's pin, or a turn
|
|
52
|
+
* variant that tightened its MCP servers' tools): each tool with whether its settings leave it
|
|
53
|
+
* `enabled` and, when they say, whether to defer it. A server the turn's manifest no longer
|
|
54
|
+
* declares is left out.
|
|
82
55
|
*/
|
|
83
|
-
export function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
notes.set(tool.agentId, servers);
|
|
110
|
-
}
|
|
111
|
-
const session = [];
|
|
112
|
-
for (const [agentId, tools] of deferred) {
|
|
113
|
-
const servers = [...notes.get(agentId)].map(([serverName, count]) => {
|
|
114
|
-
const instructions = snapshot.servers?.find((item) => item.agentId === agentId && item.serverName === serverName)?.instructions;
|
|
115
|
-
return { serverName, tools: count, ...(instructions ? { instructions } : {}) };
|
|
116
|
-
});
|
|
117
|
-
const [search, call] = deferredToolsTools();
|
|
118
|
-
for (const tool of [
|
|
119
|
-
{ ...search, instructions: [deferredToolsInstructions(servers)] },
|
|
120
|
-
call,
|
|
121
|
-
])
|
|
122
|
-
session.push({ ...(agentId === undefined ? {} : { agentId }), ...tool });
|
|
123
|
-
session.push(...tools);
|
|
124
|
-
}
|
|
125
|
-
return [...inline, ...session];
|
|
56
|
+
export function mcpFactsOf(snapshot, manifest) {
|
|
57
|
+
return {
|
|
58
|
+
servers: snapshot.servers.flatMap((server) => {
|
|
59
|
+
if (!findServer(manifest, server.agentId, server.name))
|
|
60
|
+
return [];
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
...(server.agentId === undefined ? {} : { agentId: server.agentId }),
|
|
64
|
+
name: server.name,
|
|
65
|
+
...(server.instructions === undefined ? {} : { instructions: server.instructions }),
|
|
66
|
+
tools: server.tools.map((tool) => {
|
|
67
|
+
const settings = mcpToolSettingsIn(manifest, server.agentId, server.name, tool.name);
|
|
68
|
+
return {
|
|
69
|
+
...tool,
|
|
70
|
+
enabled: settings.enabled,
|
|
71
|
+
...(settings.deferred === undefined ? {} : { deferred: settings.deferred }),
|
|
72
|
+
};
|
|
73
|
+
}),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** The manifest of the agent an effect belongs to: the root, or an agent it uses as a tool. */
|
|
80
|
+
export function manifestFor(manifest, agent) {
|
|
81
|
+
return agent ? delegateManifest(manifest, agent.id) : manifest;
|
|
126
82
|
}
|
|
127
|
-
/** The share of the model's context window past which an agent's MCP tools are deferred (Q21). */
|
|
128
|
-
export const DEFER_CONTEXT_SHARE = 0.1;
|
|
129
|
-
/** Characters per token, to estimate what tool definitions take of a context window (Q21). */
|
|
130
|
-
export const CHARS_PER_TOKEN = 4;
|
|
131
83
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* the
|
|
84
|
+
* `snapshot` within the Tenant's Runtime limit `mcpSnapshotBytes` (its JSON, which every
|
|
85
|
+
* `turn.start.mcp` carries): its servers in order while they fit. A server that does not is left
|
|
86
|
+
* out, so the session never offers its tools, and its diagnostic says so (`failed`, replacing
|
|
87
|
+
* the one it had). Unchanged when the whole snapshot fits.
|
|
136
88
|
*/
|
|
137
|
-
export function
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
89
|
+
export function fitSnapshot(snapshot, diagnostics, limitBytes) {
|
|
90
|
+
const bytes = (value) => Buffer.byteLength(JSON.stringify(value));
|
|
91
|
+
if (bytes(snapshot) <= limitBytes)
|
|
92
|
+
return { snapshot, diagnostics: [...diagnostics] };
|
|
93
|
+
const kept = [];
|
|
94
|
+
const dropped = new Map();
|
|
95
|
+
const key = (agentId, serverName) => JSON.stringify([agentId ?? null, serverName]);
|
|
96
|
+
for (const server of snapshot.servers) {
|
|
97
|
+
const next = { ...snapshot, servers: [...kept, server] };
|
|
98
|
+
const size = bytes(next);
|
|
99
|
+
if (size <= limitBytes)
|
|
100
|
+
kept.push(server);
|
|
101
|
+
else
|
|
102
|
+
dropped.set(key(server.agentId, server.name), bytes(server));
|
|
103
|
+
}
|
|
104
|
+
const tooLarge = (agentId, serverName, size) => ({
|
|
105
|
+
...(agentId === undefined ? {} : { agentId }),
|
|
106
|
+
serverName,
|
|
107
|
+
outcome: "failed",
|
|
108
|
+
message: `The server's tools and instructions take ${size} bytes, past what the session may pin with the rest: the Runtime limit mcpSnapshotBytes (${limitBytes} bytes; PUT /v1/tenant/limits). Its tools are not offered.`,
|
|
146
109
|
});
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
return defer ? { ...rest, deferred: true } : rest;
|
|
110
|
+
const out = diagnostics.map((item) => {
|
|
111
|
+
const size = dropped.get(key(item.agentId, item.serverName));
|
|
112
|
+
return size === undefined ? item : tooLarge(item.agentId, item.serverName, size);
|
|
151
113
|
});
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
export function mcpToolOf(snapshot, request, manifest) {
|
|
159
|
-
const tool = snapshot?.mcpTools.find((tool) => tool.agentId === request.agent?.id && tool.name === request.toolName);
|
|
160
|
-
if (tool && manifest && !isEnabledIn(manifest, tool))
|
|
161
|
-
return undefined;
|
|
162
|
-
return tool;
|
|
163
|
-
}
|
|
164
|
-
/** True when the tool's settings in `manifest` leave it enabled (R2b C9). */
|
|
165
|
-
export function isEnabledIn(manifest, tool) {
|
|
166
|
-
return mcpToolSettingsIn(manifest, tool).enabled;
|
|
114
|
+
for (const server of snapshot.servers) {
|
|
115
|
+
const size = dropped.get(key(server.agentId, server.name));
|
|
116
|
+
if (size !== undefined && !out.some((item) => key(item.agentId, item.serverName) === key(server.agentId, server.name)))
|
|
117
|
+
out.push(tooLarge(server.agentId, server.name, size));
|
|
118
|
+
}
|
|
119
|
+
return { snapshot: { ...snapshot, servers: kept }, diagnostics: out };
|
|
167
120
|
}
|
|
168
|
-
/**
|
|
169
|
-
export function
|
|
170
|
-
|
|
121
|
+
/** True for a snapshot of the shape this Runtime pins (`snapshotSchemaVersion` 2). */
|
|
122
|
+
export function isSnapshot(value) {
|
|
123
|
+
const snapshot = value;
|
|
124
|
+
return (typeof snapshot === "object" &&
|
|
125
|
+
snapshot !== null &&
|
|
126
|
+
snapshot.snapshotSchemaVersion === 2 &&
|
|
127
|
+
typeof snapshot.manifestHash === "string" &&
|
|
128
|
+
Array.isArray(snapshot.servers));
|
|
171
129
|
}
|
package/dist/model/auth-store.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
var _a;
|
|
2
2
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
|
+
import { hostTuning } from "../tuning.js";
|
|
4
5
|
export class ProjectCredentialStore {
|
|
5
6
|
file;
|
|
6
7
|
legacyFile;
|
|
@@ -68,7 +69,8 @@ export class ProjectCredentialStore {
|
|
|
68
69
|
async #locked(operation) {
|
|
69
70
|
await mkdir(dirname(this.file), { recursive: true });
|
|
70
71
|
const lock = this.file + ".lock";
|
|
71
|
-
|
|
72
|
+
const { credentialLockPollMs: pollMs, credentialLockAttempts: attempts } = hostTuning().host;
|
|
73
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
72
74
|
try {
|
|
73
75
|
await mkdir(lock);
|
|
74
76
|
break;
|
|
@@ -76,9 +78,9 @@ export class ProjectCredentialStore {
|
|
|
76
78
|
catch (error) {
|
|
77
79
|
if (error.code !== "EEXIST")
|
|
78
80
|
throw error;
|
|
79
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
81
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
80
82
|
}
|
|
81
|
-
if (attempt ===
|
|
83
|
+
if (attempt === attempts - 1)
|
|
82
84
|
throw new Error("Timed out waiting for the credential store.");
|
|
83
85
|
}
|
|
84
86
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a model reads (protocol 12): its pi-ai catalog's `input` (text, image) and what the
|
|
3
3
|
* operator added. One function, `capabilitiesOf`, serves the catalog, the accept check, the Model
|
|
4
|
-
* Gate
|
|
4
|
+
* Gate.
|
|
5
5
|
*
|
|
6
6
|
* The operator may add only an input our provider path sends natively for the model's API
|
|
7
7
|
* (`NATIVE_INPUTS`): an image on every API; a PDF on the APIs below; Office documents on the
|
package/dist/model/catalog.d.ts
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
2
|
-
import type { HostModelCatalog,
|
|
3
|
-
import type
|
|
2
|
+
import type { HostModelCatalog, ModelInput } from "@nylorun/core/contracts";
|
|
3
|
+
import { type ModelBindingView } from "./descriptor.js";
|
|
4
4
|
export type { HostModelCatalog };
|
|
5
|
-
/**
|
|
6
|
-
* The context window, in tokens, of the Tenant's model (`GET /v1/tenant/model`'s view): the
|
|
7
|
-
* custom endpoint's setting, else the provider catalog's. A model the catalog does not know, or
|
|
8
|
-
* none configured, is assumed small (`CUSTOM_CONTEXT_WINDOW`), as for a custom endpoint.
|
|
9
|
-
*/
|
|
10
|
-
export declare function contextWindowOf(view: {
|
|
11
|
-
configured: boolean;
|
|
12
|
-
provider?: string;
|
|
13
|
-
model?: string;
|
|
14
|
-
baseUrl?: string;
|
|
15
|
-
settings?: {
|
|
16
|
-
contextWindow?: number;
|
|
17
|
-
};
|
|
18
|
-
}): number;
|
|
19
5
|
/**
|
|
20
6
|
* Public provider and model names, and what each model reads with the operator's additions
|
|
21
7
|
* (`added`, by `<provider>/<model>`) and what may be added (protocol 12). No credentials.
|
|
@@ -25,25 +11,12 @@ export declare function hostModelCatalog(added?: Readonly<Record<string, readonl
|
|
|
25
11
|
export declare function catalogModel(provider: string, model: string): Model<Api> | undefined;
|
|
26
12
|
/**
|
|
27
13
|
* What a configured model reads (protocol 12): a custom endpoint's `settings.inputs` (text only
|
|
28
|
-
* by default), else its catalog's inputs and the operator's additions (`added`)
|
|
29
|
-
* model, or one the catalog does not
|
|
14
|
+
* by default), else its catalog's inputs and the operator's additions (`added`), as its
|
|
15
|
+
* descriptor says (`hostModelDescriptor`). Undefined for no model, or one the catalog does not
|
|
16
|
+
* know.
|
|
30
17
|
*/
|
|
31
18
|
export declare function inputsOfHostModel(view: {
|
|
32
|
-
configured:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
settings?: {
|
|
37
|
-
inputs?: readonly ModelInput[];
|
|
38
|
-
};
|
|
39
|
-
}, added?: Readonly<Record<string, readonly ModelInput[]>>): ModelInput[] | undefined;
|
|
40
|
-
/**
|
|
41
|
-
* What the Tenant's model reads now, for the accept check and `read_artifact`: undefined when no
|
|
42
|
-
* model is in the vault (a test's fake provider, say), and the check is skipped.
|
|
43
|
-
*/
|
|
44
|
-
export declare function currentModelInputs(ctx: {
|
|
45
|
-
readonly store: SessionStore;
|
|
46
|
-
readonly vault: {
|
|
47
|
-
getHostModel(): Promise<HostModelView>;
|
|
48
|
-
};
|
|
49
|
-
}): Promise<ModelInput[] | undefined>;
|
|
19
|
+
readonly configured: false;
|
|
20
|
+
} | ({
|
|
21
|
+
readonly configured: true;
|
|
22
|
+
} & ModelBindingView), added?: Readonly<Record<string, readonly ModelInput[]>>): ModelInput[] | undefined;
|
package/dist/model/catalog.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readAddedInputs } from "../tenant/model-setting.js";
|
|
2
1
|
import { addableInputs, capabilitiesOf } from "./capabilities.js";
|
|
3
|
-
import {
|
|
2
|
+
import { hostModelDescriptor } from "./descriptor.js";
|
|
3
|
+
import { modelsFor } from "./models.js";
|
|
4
4
|
const emptyStore = {
|
|
5
5
|
async read() {
|
|
6
6
|
return undefined;
|
|
@@ -13,19 +13,6 @@ const emptyStore = {
|
|
|
13
13
|
},
|
|
14
14
|
async delete() { },
|
|
15
15
|
};
|
|
16
|
-
/**
|
|
17
|
-
* The context window, in tokens, of the Tenant's model (`GET /v1/tenant/model`'s view): the
|
|
18
|
-
* custom endpoint's setting, else the provider catalog's. A model the catalog does not know, or
|
|
19
|
-
* none configured, is assumed small (`CUSTOM_CONTEXT_WINDOW`), as for a custom endpoint.
|
|
20
|
-
*/
|
|
21
|
-
export function contextWindowOf(view) {
|
|
22
|
-
if (!view.configured || !view.provider || !view.model)
|
|
23
|
-
return CUSTOM_CONTEXT_WINDOW;
|
|
24
|
-
if (view.baseUrl)
|
|
25
|
-
return view.settings?.contextWindow ?? CUSTOM_CONTEXT_WINDOW;
|
|
26
|
-
const models = modelsFor({ provider: "", model: "" }, emptyStore, { environment: false });
|
|
27
|
-
return models.getModel(view.provider, view.model)?.contextWindow ?? CUSTOM_CONTEXT_WINDOW;
|
|
28
|
-
}
|
|
29
16
|
/**
|
|
30
17
|
* Public provider and model names, and what each model reads with the operator's additions
|
|
31
18
|
* (`added`, by `<provider>/<model>`) and what may be added (protocol 12). No credentials.
|
|
@@ -53,26 +40,12 @@ export function catalogModel(provider, model) {
|
|
|
53
40
|
}
|
|
54
41
|
/**
|
|
55
42
|
* What a configured model reads (protocol 12): a custom endpoint's `settings.inputs` (text only
|
|
56
|
-
* by default), else its catalog's inputs and the operator's additions (`added`)
|
|
57
|
-
* model, or one the catalog does not
|
|
43
|
+
* by default), else its catalog's inputs and the operator's additions (`added`), as its
|
|
44
|
+
* descriptor says (`hostModelDescriptor`). Undefined for no model, or one the catalog does not
|
|
45
|
+
* know.
|
|
58
46
|
*/
|
|
59
47
|
export function inputsOfHostModel(view, added = {}) {
|
|
60
|
-
if (!view.configured || !view.provider || !view.model)
|
|
61
|
-
return undefined;
|
|
62
|
-
if (view.baseUrl) {
|
|
63
|
-
const inputs = view.settings?.inputs ?? [];
|
|
64
|
-
return capabilitiesOf({ api: "openai-completions", input: inputs.includes("image") ? ["text", "image"] : ["text"] }, inputs).inputs;
|
|
65
|
-
}
|
|
66
|
-
const model = catalogModel(view.provider, view.model);
|
|
67
|
-
return model && capabilitiesOf(model, added[`${view.provider}/${view.model}`]).inputs;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* What the Tenant's model reads now, for the accept check and `read_artifact`: undefined when no
|
|
71
|
-
* model is in the vault (a test's fake provider, say), and the check is skipped.
|
|
72
|
-
*/
|
|
73
|
-
export async function currentModelInputs(ctx) {
|
|
74
|
-
const view = await ctx.vault.getHostModel();
|
|
75
48
|
if (!view.configured)
|
|
76
49
|
return undefined;
|
|
77
|
-
return
|
|
50
|
+
return hostModelDescriptor(view, added)?.inputs;
|
|
78
51
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model descriptor (protocol 15): the Tenant's model as a harness learns it in
|
|
3
|
+
* `turn.start.model` — its provider and id, what it reads, its context window and output limit.
|
|
4
|
+
* One resolution serves the descriptor, the catalog's inputs and the Model Gate: the binding
|
|
5
|
+
* becomes a pi-ai `Selection` (`selectionOf`), the registry finds the model, and
|
|
6
|
+
* `describeModel` reads it with the operator's additions. So what a harness is told and what the
|
|
7
|
+
* gate takes cannot disagree.
|
|
8
|
+
*/
|
|
9
|
+
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
10
|
+
import { type CustomModelSettings, type HostModelView, type ModelInput } from "@nylorun/core/contracts";
|
|
11
|
+
import type { ModelDescriptor } from "@nylorun/core/harness-api";
|
|
12
|
+
import type { SessionStore } from "../store/types.js";
|
|
13
|
+
import { type Selection } from "./models.js";
|
|
14
|
+
/** A configured model: its provider and model, and a custom endpoint's address and settings. */
|
|
15
|
+
export interface ModelBindingView {
|
|
16
|
+
readonly provider: string;
|
|
17
|
+
readonly model: string;
|
|
18
|
+
readonly baseUrl?: string;
|
|
19
|
+
readonly settings?: CustomModelSettings;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The pi-ai selection for `binding`. A call may name another model of the same provider
|
|
23
|
+
* (`requested`, as `<model>` or `<provider>/<model>`); a custom endpoint carries its settings.
|
|
24
|
+
*/
|
|
25
|
+
export declare function selectionOf(binding: ModelBindingView, requested?: string): Selection;
|
|
26
|
+
/** The inputs the operator added that apply to `selection`: a custom endpoint's own, or the Tenant's. */
|
|
27
|
+
export declare function addedInputsOf(selection: Selection, binding: Pick<ModelBindingView, "settings">, added: Readonly<Record<string, readonly ModelInput[]>>): readonly ModelInput[] | undefined;
|
|
28
|
+
/** A pi-ai model as a descriptor, with the inputs the operator added (`capabilitiesOf`). */
|
|
29
|
+
export declare function describeModel(found: Model<Api>, added?: readonly ModelInput[]): ModelDescriptor;
|
|
30
|
+
/** The fixture model (`model.fixture`): it reads every input, since it ignores files. */
|
|
31
|
+
export declare const FIXTURE_DESCRIPTOR: ModelDescriptor;
|
|
32
|
+
/**
|
|
33
|
+
* The descriptor of a configured model (`binding`), with the Tenant's added inputs; undefined
|
|
34
|
+
* for a model the catalog does not know. No credential is read.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hostModelDescriptor(binding: ModelBindingView, added?: Readonly<Record<string, readonly ModelInput[]>>): ModelDescriptor | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* The model the Tenant's turns use now: the fixture model's descriptor when the Tenant uses it,
|
|
39
|
+
* else its active model's; undefined when none is configured (a test's scripted provider, say).
|
|
40
|
+
*/
|
|
41
|
+
export declare function currentModelDescriptor(ctx: {
|
|
42
|
+
readonly store: SessionStore;
|
|
43
|
+
readonly vault: {
|
|
44
|
+
getHostModel(): Promise<HostModelView>;
|
|
45
|
+
};
|
|
46
|
+
}): Promise<ModelDescriptor | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* The context window, in tokens, of the Tenant's model now; without one, or one the catalog does
|
|
49
|
+
* not know, it is assumed small (`CUSTOM_MODEL_SETTING_DEFAULTS`), as for a custom endpoint.
|
|
50
|
+
*/
|
|
51
|
+
export declare function currentContextWindow(ctx: Parameters<typeof currentModelDescriptor>[0]): Promise<number>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { MODEL_INPUTS, } from "@nylorun/core/contracts";
|
|
2
|
+
import { readAddedInputs, usesFixtureModel } from "../tenant/model-setting.js";
|
|
3
|
+
import { capabilitiesOf } from "./capabilities.js";
|
|
4
|
+
import { CUSTOM_MODEL_SETTING_DEFAULTS } from "@nylorun/core/contracts";
|
|
5
|
+
import { modelsFor } from "./models.js";
|
|
6
|
+
/**
|
|
7
|
+
* The pi-ai selection for `binding`. A call may name another model of the same provider
|
|
8
|
+
* (`requested`, as `<model>` or `<provider>/<model>`); a custom endpoint carries its settings.
|
|
9
|
+
*/
|
|
10
|
+
export function selectionOf(binding, requested) {
|
|
11
|
+
return {
|
|
12
|
+
provider: binding.provider,
|
|
13
|
+
model: requested?.startsWith(`${binding.provider}/`)
|
|
14
|
+
? requested.slice(binding.provider.length + 1)
|
|
15
|
+
: (requested ?? binding.model),
|
|
16
|
+
...(binding.baseUrl ? { custom: { baseUrl: binding.baseUrl, ...(binding.settings ?? {}) } } : {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** The inputs the operator added that apply to `selection`: a custom endpoint's own, or the Tenant's. */
|
|
20
|
+
export function addedInputsOf(selection, binding, added) {
|
|
21
|
+
return selection.custom ? binding.settings?.inputs : added[`${selection.provider}/${selection.model}`];
|
|
22
|
+
}
|
|
23
|
+
/** A pi-ai model as a descriptor, with the inputs the operator added (`capabilitiesOf`). */
|
|
24
|
+
export function describeModel(found, added) {
|
|
25
|
+
return {
|
|
26
|
+
provider: found.provider,
|
|
27
|
+
id: found.id,
|
|
28
|
+
inputs: capabilitiesOf(found, added).inputs,
|
|
29
|
+
contextWindow: found.contextWindow,
|
|
30
|
+
maxOutputTokens: found.maxTokens,
|
|
31
|
+
...(found.reasoning === undefined ? {} : { reasoning: found.reasoning }),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** The fixture model (`model.fixture`): it reads every input, since it ignores files. */
|
|
35
|
+
export const FIXTURE_DESCRIPTOR = Object.freeze({
|
|
36
|
+
provider: "fixture",
|
|
37
|
+
id: "fixture",
|
|
38
|
+
inputs: [...MODEL_INPUTS],
|
|
39
|
+
contextWindow: CUSTOM_MODEL_SETTING_DEFAULTS.contextWindow,
|
|
40
|
+
maxOutputTokens: CUSTOM_MODEL_SETTING_DEFAULTS.maxTokens,
|
|
41
|
+
});
|
|
42
|
+
const emptyStore = {
|
|
43
|
+
async read() {
|
|
44
|
+
return undefined;
|
|
45
|
+
},
|
|
46
|
+
async list() {
|
|
47
|
+
return [];
|
|
48
|
+
},
|
|
49
|
+
async modify(_providerId, fn) {
|
|
50
|
+
return fn(undefined);
|
|
51
|
+
},
|
|
52
|
+
async delete() { },
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The descriptor of a configured model (`binding`), with the Tenant's added inputs; undefined
|
|
56
|
+
* for a model the catalog does not know. No credential is read.
|
|
57
|
+
*/
|
|
58
|
+
export function hostModelDescriptor(binding, added = {}) {
|
|
59
|
+
const selection = selectionOf(binding);
|
|
60
|
+
const found = modelsFor(selection, emptyStore, { environment: false }).getModel(selection.provider, selection.model);
|
|
61
|
+
return found && describeModel(found, addedInputsOf(selection, binding, added));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The model the Tenant's turns use now: the fixture model's descriptor when the Tenant uses it,
|
|
65
|
+
* else its active model's; undefined when none is configured (a test's scripted provider, say).
|
|
66
|
+
*/
|
|
67
|
+
export async function currentModelDescriptor(ctx) {
|
|
68
|
+
const { fixture, added } = await ctx.store.tx(async (t) => ({
|
|
69
|
+
fixture: await usesFixtureModel(t),
|
|
70
|
+
added: await readAddedInputs(t),
|
|
71
|
+
}));
|
|
72
|
+
if (fixture)
|
|
73
|
+
return FIXTURE_DESCRIPTOR;
|
|
74
|
+
const view = await ctx.vault.getHostModel();
|
|
75
|
+
return view.configured ? hostModelDescriptor(view, added) : undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The context window, in tokens, of the Tenant's model now; without one, or one the catalog does
|
|
79
|
+
* not know, it is assumed small (`CUSTOM_MODEL_SETTING_DEFAULTS`), as for a custom endpoint.
|
|
80
|
+
*/
|
|
81
|
+
export async function currentContextWindow(ctx) {
|
|
82
|
+
return (await currentModelDescriptor(ctx))?.contextWindow ?? CUSTOM_MODEL_SETTING_DEFAULTS.contextWindow;
|
|
83
|
+
}
|
package/dist/model/models.d.ts
CHANGED
|
@@ -13,9 +13,6 @@ export type Selection = Readonly<{
|
|
|
13
13
|
compat?: Readonly<Record<string, unknown>>;
|
|
14
14
|
}>;
|
|
15
15
|
}>;
|
|
16
|
-
/** A custom endpoint whose window is unknown is assumed small: an early compaction beats a failed call. */
|
|
17
|
-
export declare const CUSTOM_CONTEXT_WINDOW = 32768;
|
|
18
|
-
export declare const CUSTOM_MAX_TOKENS = 8192;
|
|
19
16
|
/**
|
|
20
17
|
* Build the pi-ai model registry from explicit credentials only.
|
|
21
18
|
* Ambient process environment / provider env auth is never consulted (A7, A10).
|
package/dist/model/models.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { createProvider, } from "@earendil-works/pi-ai";
|
|
2
2
|
import { stream, streamSimple, } from "@earendil-works/pi-ai/api/openai-completions";
|
|
3
3
|
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
4
|
-
|
|
5
|
-
export const CUSTOM_CONTEXT_WINDOW = 32_768;
|
|
6
|
-
export const CUSTOM_MAX_TOKENS = 8_192;
|
|
4
|
+
import { CUSTOM_MODEL_SETTING_DEFAULTS } from "@nylorun/core/contracts";
|
|
7
5
|
/**
|
|
8
6
|
* Build the pi-ai model registry from explicit credentials only.
|
|
9
7
|
* Ambient process environment / provider env auth is never consulted (A7, A10).
|
|
@@ -27,8 +25,8 @@ export function modelsFor(selection, credentials, options = {}) {
|
|
|
27
25
|
reasoning: selection.custom.reasoning ?? false,
|
|
28
26
|
input: selection.custom.inputs?.includes("image") ? ["text", "image"] : ["text"],
|
|
29
27
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
30
|
-
contextWindow: selection.custom.contextWindow ??
|
|
31
|
-
maxTokens: selection.custom.maxTokens ??
|
|
28
|
+
contextWindow: selection.custom.contextWindow ?? CUSTOM_MODEL_SETTING_DEFAULTS.contextWindow,
|
|
29
|
+
maxTokens: selection.custom.maxTokens ?? CUSTOM_MODEL_SETTING_DEFAULTS.maxTokens,
|
|
32
30
|
...(selection.custom.compat
|
|
33
31
|
? { compat: { ...selection.custom.compat } }
|
|
34
32
|
: {}),
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* sending a marker to the model.
|
|
14
14
|
*/
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
16
|
-
import { essence } from "
|
|
16
|
+
import { essence } from "@nylorun/core/contracts";
|
|
17
17
|
import { NATIVE_INPUTS } from "./capabilities.js";
|
|
18
18
|
/**
|
|
19
19
|
* The kinds each pi-ai API has a native block for here: the model inputs an operator may add
|