@themoltnet/pi-runtime 0.13.1 → 0.14.1

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/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ import { LoadSkillsResult } from '@earendil-works/pi-coding-agent';
31
31
  import { LsOperations } from '@earendil-works/pi-coding-agent';
32
32
  import { ManagedVm } from '@themoltnet/sandbox-gondolin';
33
33
  import { Model } from '@earendil-works/pi-ai';
34
- import { ModelRegistry } from '@earendil-works/pi-coding-agent';
34
+ import { ModelRuntime } from '@earendil-works/pi-coding-agent';
35
35
  import { prepareBrokeredHttpSecrets } from '@themoltnet/sandbox-gondolin';
36
36
  import { Readable } from 'node:stream';
37
37
  import { ReadOperations } from '@earendil-works/pi-coding-agent';
@@ -158,8 +158,8 @@ declare interface BuildAgentSessionArgs {
158
158
  piAuthDir: string;
159
159
  /** Resolved pi model handle (provider + model id). */
160
160
  modelHandle: Model<Api>;
161
- /** Registry that resolved modelHandle, including custom providers/auth. */
162
- modelRegistry?: ModelRegistry;
161
+ /** Runtime that resolved modelHandle, including custom providers/auth. */
162
+ modelRuntime?: ModelRuntime;
163
163
  /** Optional runtime-profile thinking/reasoning level applied at session start. */
164
164
  thinkingLevel?: PiThinkingLevel | null;
165
165
  /** Optional runtime-profile sampling temperature applied to provider requests. */
@@ -306,6 +306,7 @@ export declare function createPiOtelExtension(options?: PiOtelOptions): (pi: Ext
306
306
 
307
307
  export declare function createPiRetryTriage(options: {
308
308
  model: Model<Api>;
309
+ modelRuntime?: ModelRuntime;
309
310
  thinkingLevel?: PiRetryTriageThinkingLevel | null;
310
311
  piAgentDir: string;
311
312
  timeoutMs?: number;
@@ -335,8 +336,8 @@ export declare interface CreateSubagentToolArgs {
335
336
  piAuthDir: string;
336
337
  /** Resolved pi model handle — subagents share it. */
337
338
  modelHandle: Model<Api>;
338
- /** Registry that resolved modelHandle — subagents share it. */
339
- modelRegistry?: ModelRegistry;
339
+ /** Runtime that resolved modelHandle — subagents share it. */
340
+ modelRuntime?: ModelRuntime;
340
341
  /** Runtime-profile thinking/reasoning level — subagents inherit it. */
341
342
  thinkingLevel?: PiThinkingLevel | null;
342
343
  /** Runtime-profile sampling temperature — subagents inherit it. */
@@ -1298,6 +1299,16 @@ export declare interface ResolvedGondolinTemplate {
1298
1299
 
1299
1300
  export declare function resolveHostExecBaseEnv(agentEnv: Readonly<Record<string, string | undefined>>): Set<string>;
1300
1301
 
1302
+ /**
1303
+ * Resolve the exact runtime-profile model through Pi's custom-model registry.
1304
+ *
1305
+ * `getModel()` from pi-ai only knows generated built-in models. Runtime
1306
+ * profiles commonly select providers declared in the active Pi directory's
1307
+ * models.json, so an unresolved lookup must fail closed rather than letting
1308
+ * createAgentSession silently choose the default from settings.json.
1309
+ */
1310
+ export declare function resolveRuntimeProfileModel(piAuthDir: string, provider: string, modelId: string, runtimeProfileId?: string): Promise<RuntimeModelSelection>;
1311
+
1301
1312
  /**
1302
1313
  * Resolve the session's tool policy at start-up.
1303
1314
  *
@@ -1399,6 +1410,15 @@ declare interface RuntimeInstructorToolPolicy {
1399
1410
  degraded: boolean;
1400
1411
  }
1401
1412
 
1413
+ export declare interface RuntimeModelSelection {
1414
+ modelHandle: Model<Api>;
1415
+ modelRuntime: ModelRuntime;
1416
+ }
1417
+
1418
+ export declare class RuntimeProfileModelResolutionError extends Error {
1419
+ constructor(message: string);
1420
+ }
1421
+
1402
1422
  export { SandboxConfig }
1403
1423
 
1404
1424
  /** The resolved allow-set + enforcement mode for a runtime session. */
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { mkdir, realpath, stat } from "node:fs/promises";
9
9
  import path, { isAbsolute, join, relative, resolve, sep } from "node:path";
10
10
  import { pipeline } from "node:stream/promises";
11
11
  import { Type as Type$1 } from "@earendil-works/pi-ai";
12
- import { AuthStorage, DEFAULT_MAX_BYTES, DefaultResourceLoader, ModelRegistry, SessionManager, createAgentSession, createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLsToolDefinition, createReadToolDefinition, createSyntheticSourceInfo, createWriteToolDefinition, defineTool, formatSize, parseFrontmatter, truncateHead, truncateLine } from "@earendil-works/pi-coding-agent";
12
+ import { DEFAULT_MAX_BYTES, DefaultResourceLoader, ModelRuntime, SessionManager, createAgentSession, createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLsToolDefinition, createReadToolDefinition, createSyntheticSourceInfo, createWriteToolDefinition, defineTool, formatSize, parseFrontmatter, truncateHead, truncateLine } from "@earendil-works/pi-coding-agent";
13
13
  import { sha256 } from "@noble/hashes/sha2";
14
14
  import { base32 } from "multiformats/bases/base32";
15
15
  import { CID } from "multiformats/cid";
@@ -1506,7 +1506,7 @@ async function buildAgentSession(args) {
1506
1506
  agentDir: args.piAuthDir,
1507
1507
  cwd: args.cwdPath,
1508
1508
  model: args.modelHandle,
1509
- ...args.modelRegistry ? { modelRegistry: args.modelRegistry } : {},
1509
+ ...args.modelRuntime ? { modelRuntime: args.modelRuntime } : {},
1510
1510
  thinkingLevel: args.thinkingLevel ?? void 0,
1511
1511
  tools: args.tools,
1512
1512
  customTools: args.customTools,
@@ -4281,20 +4281,22 @@ var RuntimeProfileModelResolutionError = class extends Error {
4281
4281
  * models.json, so an unresolved lookup must fail closed rather than letting
4282
4282
  * createAgentSession silently choose the default from settings.json.
4283
4283
  */
4284
- function resolveRuntimeProfileModel(piAuthDir, provider, modelId, runtimeProfileId) {
4285
- const authStorage = AuthStorage.create(join(piAuthDir, "auth.json"));
4284
+ async function resolveRuntimeProfileModel(piAuthDir, provider, modelId, runtimeProfileId) {
4286
4285
  const modelsPath = join(piAuthDir, "models.json");
4287
- const modelRegistry = ModelRegistry.create(authStorage, modelsPath);
4288
- const modelHandle = modelRegistry.find(provider, modelId);
4286
+ const modelRuntime = await ModelRuntime.create({
4287
+ authPath: join(piAuthDir, "auth.json"),
4288
+ modelsPath
4289
+ });
4290
+ const modelHandle = modelRuntime.getModel(provider, modelId);
4289
4291
  if (!modelHandle) {
4290
- const registryError = modelRegistry.getError();
4292
+ const registryError = modelRuntime.getError();
4291
4293
  const detail = registryError ? ` Registry error: ${registryError}` : "";
4292
- const alternatives = modelRegistry.getAvailable().slice(0, 8).map((model) => `${model.provider}/${model.id}`);
4294
+ const alternatives = modelRuntime.getModels().slice(0, 8).map((model) => `${model.provider}/${model.id}`);
4293
4295
  throw new RuntimeProfileModelResolutionError(`${runtimeProfileId ? `Runtime profile "${runtimeProfileId}"` : "Runtime profile"} model "${provider}/${modelId}" was not found in ${modelsPath}; refusing Pi default-model fallback.` + (alternatives.length > 0 ? ` Available models include: ${alternatives.join(", ")}.` : "") + detail);
4294
4296
  }
4295
4297
  return {
4296
4298
  modelHandle,
4297
- modelRegistry
4299
+ modelRuntime
4298
4300
  };
4299
4301
  }
4300
4302
  //#endregion
@@ -4346,6 +4348,7 @@ function createPiRetryTriage(options) {
4346
4348
  agentDir: options.piAgentDir,
4347
4349
  cwd,
4348
4350
  model: options.model,
4351
+ ...options.modelRuntime ? { modelRuntime: options.modelRuntime } : {},
4349
4352
  thinkingLevel: options.thinkingLevel ?? void 0,
4350
4353
  customTools: [capture.tool],
4351
4354
  sessionManager,
@@ -4876,7 +4879,7 @@ function createSubagentTool(args) {
4876
4879
  cwdPath: args.cwdPath ?? args.mountPath,
4877
4880
  piAuthDir: args.piAuthDir,
4878
4881
  modelHandle: args.modelHandle,
4879
- modelRegistry: args.modelRegistry,
4882
+ modelRuntime: args.modelRuntime,
4880
4883
  thinkingLevel: args.thinkingLevel,
4881
4884
  temperature: args.temperature,
4882
4885
  topP: args.topP,
@@ -6359,7 +6362,7 @@ async function executePiTask(claimedTask, reporter, opts) {
6359
6362
  })
6360
6363
  });
6361
6364
  const piAuthDir = resolvePiCodingAgentDir();
6362
- const { modelHandle, modelRegistry } = resolveRuntimeProfileModel(piAuthDir, opts.provider, opts.model, opts.runtimeProfileId);
6365
+ const { modelHandle, modelRuntime } = await resolveRuntimeProfileModel(piAuthDir, opts.provider, opts.model, opts.runtimeProfileId);
6363
6366
  const injectedSkills = injectedContext.skills;
6364
6367
  const toolPolicyExtensions = [];
6365
6368
  let resolvedToolPolicy;
@@ -6513,7 +6516,7 @@ async function executePiTask(claimedTask, reporter, opts) {
6513
6516
  cwdPath,
6514
6517
  piAuthDir,
6515
6518
  modelHandle,
6516
- modelRegistry,
6519
+ modelRuntime,
6517
6520
  thinkingLevel: opts.thinkingLevel,
6518
6521
  temperature: opts.temperature,
6519
6522
  topP: opts.topP,
@@ -6550,7 +6553,7 @@ async function executePiTask(claimedTask, reporter, opts) {
6550
6553
  cwdPath,
6551
6554
  piAuthDir,
6552
6555
  modelHandle,
6553
- modelRegistry,
6556
+ modelRuntime,
6554
6557
  thinkingLevel: opts.thinkingLevel,
6555
6558
  temperature: opts.temperature,
6556
6559
  topP: opts.topP,
@@ -7477,4 +7480,4 @@ function describeToolErrorMessage(result) {
7477
7480
  }
7478
7481
  }
7479
7482
  //#endregion
7480
- export { BrokeredHttpSecretBoundaryError, DEFAULT_BROKERED_HTTP_SECRET_RESOLUTION_TIMEOUT_MS, GONDOLIN_BASE_EXECUTABLES, GONDOLIN_TOOL_NAMES, GUEST_ALLOWED_SIGNERS_PATH, GUEST_GITCONFIG_PATH, GUEST_SIGNER_SOCKET, GondolinVmRetiredError, GuestEnvironmentBoundaryError, HOST_EXEC_DEFAULT_BASE_ENV, MOLTNET_TOOL_NAMES, PI_EXECUTOR_MANIFEST_VERSION, PI_RUNTIME_DEFINITION_VERSION, PiBrokeredHttpSecretResolutionError, activateAgentEnv, agentSigningCapability, assertGuestEnvironmentBoundary, assertHostAuthenticatedGuestEnvironment, buildAgentSession, buildPiExecutorManifest, buildRuntimeKernel, buildWorkspaceMountInstructions, createGondolinBashOps, createGondolinEditOps, createGondolinFindOps, createGondolinLsOps, createGondolinReadOps, createGondolinToolDefinitions, createGondolinToolLifecycle, createGondolinWriteOps, createMoltNetTools, createPiOtelExtension, createPiRetryTriage, createPiTaskExecutor, createSubagentTool, createToolPolicyExtension, decideForEvent, decideToolCall, defineGondolinTemplate, definePiBrokeredHttpSecret, definePiExtension, definePiRuntime, definePiTool, enabledPiToolNames, ensureSnapshot, executeGondolinGrep, executePiTask, filterModelVisibleTools, findMainWorktree, guardGondolinToolDefinitions, injectRuntimeContext as injectTaskContext, isKernelTool, isResolvedPathInsideRoot, isToolVisible, loadCredentials, materializePiBrokeredHttpSecrets, materializePiExtensions, materializePiTools, normalizeRetryTriageResult, prepareBrokeredHttpSecrets, redactRetryTriageSecrets, resolveHostExecBaseEnv, resolveSessionToolPolicy, resolveTaskWorktreePath, resumeVm, toGuestPath };
7483
+ export { BrokeredHttpSecretBoundaryError, DEFAULT_BROKERED_HTTP_SECRET_RESOLUTION_TIMEOUT_MS, GONDOLIN_BASE_EXECUTABLES, GONDOLIN_TOOL_NAMES, GUEST_ALLOWED_SIGNERS_PATH, GUEST_GITCONFIG_PATH, GUEST_SIGNER_SOCKET, GondolinVmRetiredError, GuestEnvironmentBoundaryError, HOST_EXEC_DEFAULT_BASE_ENV, MOLTNET_TOOL_NAMES, PI_EXECUTOR_MANIFEST_VERSION, PI_RUNTIME_DEFINITION_VERSION, PiBrokeredHttpSecretResolutionError, RuntimeProfileModelResolutionError, activateAgentEnv, agentSigningCapability, assertGuestEnvironmentBoundary, assertHostAuthenticatedGuestEnvironment, buildAgentSession, buildPiExecutorManifest, buildRuntimeKernel, buildWorkspaceMountInstructions, createGondolinBashOps, createGondolinEditOps, createGondolinFindOps, createGondolinLsOps, createGondolinReadOps, createGondolinToolDefinitions, createGondolinToolLifecycle, createGondolinWriteOps, createMoltNetTools, createPiOtelExtension, createPiRetryTriage, createPiTaskExecutor, createSubagentTool, createToolPolicyExtension, decideForEvent, decideToolCall, defineGondolinTemplate, definePiBrokeredHttpSecret, definePiExtension, definePiRuntime, definePiTool, enabledPiToolNames, ensureSnapshot, executeGondolinGrep, executePiTask, filterModelVisibleTools, findMainWorktree, guardGondolinToolDefinitions, injectRuntimeContext as injectTaskContext, isKernelTool, isResolvedPathInsideRoot, isToolVisible, loadCredentials, materializePiBrokeredHttpSecrets, materializePiExtensions, materializePiTools, normalizeRetryTriageResult, prepareBrokeredHttpSecrets, redactRetryTriageSecrets, resolveHostExecBaseEnv, resolveRuntimeProfileModel, resolveSessionToolPolicy, resolveTaskWorktreePath, resumeVm, toGuestPath };
@@ -0,0 +1,53 @@
1
+ export declare interface WriteMultiProviderPiConfigInput extends WritePiConfigBase {
2
+ /** Provider registry keyed by Pi provider id. */
3
+ providers: Readonly<Record<string, WritePiProviderInput>>;
4
+ provider?: never;
5
+ model?: never;
6
+ baseUrl?: never;
7
+ apiKeyEnvRef?: never;
8
+ }
9
+
10
+ /**
11
+ * Write Pi `models.json` + `settings.json`. Eval callers use the single-provider
12
+ * form so scores stay attributable; serve callers may supply many providers.
13
+ */
14
+ export declare function writePiConfig(input: WritePiConfigInput): void;
15
+
16
+ declare interface WritePiConfigBase {
17
+ /** `PI_CODING_AGENT_DIR` — where `models.json` + `settings.json` land. */
18
+ piDir: string;
19
+ /** Overrides or extends the generated settings document. */
20
+ settings?: Readonly<Record<string, unknown>>;
21
+ }
22
+
23
+ export declare type WritePiConfigInput = WriteSingleProviderPiConfigInput | WriteMultiProviderPiConfigInput;
24
+
25
+ export declare interface WritePiProviderInput {
26
+ /** Pi provider API kind, e.g. `openai-completions`. */
27
+ api: string;
28
+ /** Provider base URL. */
29
+ baseUrl: string;
30
+ /** Model ids exposed by this provider. */
31
+ models: readonly string[];
32
+ /** Optional Pi environment placeholder, e.g. `$OLLAMA_API_KEY`. */
33
+ apiKeyEnvRef?: string;
34
+ }
35
+
36
+ export declare interface WriteSingleProviderPiConfigInput extends WritePiConfigBase {
37
+ /** Pi provider id, e.g. `ollama-cloud`. */
38
+ provider: string;
39
+ /** Pi model id, e.g. `qwen3-coder:480b-cloud`. */
40
+ model: string;
41
+ /**
42
+ * OpenAI-completions base URL for the provider. Defaults to Ollama Cloud.
43
+ */
44
+ baseUrl?: string;
45
+ /**
46
+ * Env-var reference (with `$`) holding the provider API key. Defaults to
47
+ * `$OLLAMA_API_KEY`.
48
+ */
49
+ apiKeyEnvRef?: string;
50
+ providers?: never;
51
+ }
52
+
53
+ export { }
@@ -0,0 +1,38 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ //#region src/pi-config.ts
4
+ /** Node-only writer used by daemon serve runs and live evals. */
5
+ /**
6
+ * Write Pi `models.json` + `settings.json`. Eval callers use the single-provider
7
+ * form so scores stay attributable; serve callers may supply many providers.
8
+ */
9
+ function writePiConfig(input) {
10
+ const multiProvider = "providers" in input && input.providers !== void 0;
11
+ const providers = multiProvider ? Object.fromEntries(Object.entries(input.providers).map(([id, provider]) => [id, {
12
+ api: provider.api,
13
+ ...provider.apiKeyEnvRef ? { apiKey: provider.apiKeyEnvRef } : {},
14
+ baseUrl: provider.baseUrl,
15
+ models: provider.models.map((id) => ({ id }))
16
+ }])) : { [input.provider]: {
17
+ api: "openai-completions",
18
+ apiKey: input.apiKeyEnvRef ?? "$OLLAMA_API_KEY",
19
+ baseUrl: input.baseUrl ?? "https://ollama.com/v1",
20
+ models: [{ id: input.model }]
21
+ } };
22
+ writeFileSync(join(input.piDir, "models.json"), JSON.stringify({ providers }, null, 2) + "\n", "utf8");
23
+ const defaultSettings = multiProvider ? { enableInstallTelemetry: false } : {
24
+ defaultModel: input.model,
25
+ defaultProvider: input.provider,
26
+ enableInstallTelemetry: false,
27
+ enabledModels: [`${input.provider}/${input.model}`],
28
+ packages: ["npm:@themoltnet/pi-extension"],
29
+ transport: "sse",
30
+ treeFilterMode: "default"
31
+ };
32
+ writeFileSync(join(input.piDir, "settings.json"), JSON.stringify({
33
+ ...defaultSettings,
34
+ ...input.settings
35
+ }, null, 2) + "\n", "utf8");
36
+ }
37
+ //#endregion
38
+ export { writePiConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@themoltnet/pi-runtime",
3
- "version": "0.13.1",
3
+ "version": "0.14.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Composable MoltNet runtime kernel for Pi agents in Gondolin VMs",
@@ -16,6 +16,10 @@
16
16
  ".": {
17
17
  "types": "./dist/index.d.ts",
18
18
  "import": "./dist/index.js"
19
+ },
20
+ "./pi-config": {
21
+ "types": "./dist/pi-config.d.ts",
22
+ "import": "./dist/pi-config.js"
19
23
  }
20
24
  },
21
25
  "files": [
@@ -31,19 +35,19 @@
31
35
  "@opentelemetry/api": "^1.9.1",
32
36
  "multiformats": "^13.3.0",
33
37
  "typebox": "^1.2.8",
34
- "@themoltnet/os-keyring": "0.3.0",
35
- "@themoltnet/sdk": "0.139.0",
38
+ "@themoltnet/agent-runtime": "0.45.2",
36
39
  "@themoltnet/sandbox-gondolin": "0.5.1",
37
- "@themoltnet/shell-command-analyzer": "0.3.0",
38
- "@themoltnet/agent-runtime": "0.45.1"
40
+ "@themoltnet/os-keyring": "0.3.0",
41
+ "@themoltnet/sdk": "0.140.0",
42
+ "@themoltnet/shell-command-analyzer": "0.3.0"
39
43
  },
40
44
  "peerDependencies": {
41
- "@earendil-works/pi-ai": "0.79.4",
42
- "@earendil-works/pi-coding-agent": "0.79.4"
45
+ "@earendil-works/pi-ai": "0.84.4",
46
+ "@earendil-works/pi-coding-agent": "0.84.4"
43
47
  },
44
48
  "devDependencies": {
45
- "@earendil-works/pi-ai": "0.79.4",
46
- "@earendil-works/pi-coding-agent": "0.79.4",
49
+ "@earendil-works/pi-ai": "0.84.4",
50
+ "@earendil-works/pi-coding-agent": "0.84.4",
47
51
  "@opentelemetry/sdk-metrics": "^2.5.1",
48
52
  "@opentelemetry/sdk-trace-base": "^2.5.1",
49
53
  "@types/node": "^22.19.0",
@@ -52,10 +56,10 @@
52
56
  "vite": "^8.0.0",
53
57
  "vite-plugin-dts": "^4.5.4",
54
58
  "vitest": "^3.0.0",
55
- "@moltnet/runtime-profiles": "0.1.0",
56
59
  "@moltnet/crypto-service": "0.1.0",
57
- "@moltnet/tasks": "0.1.0",
58
- "@moltnet/models": "0.1.0"
60
+ "@moltnet/models": "0.1.0",
61
+ "@moltnet/runtime-profiles": "0.1.0",
62
+ "@moltnet/tasks": "0.1.0"
59
63
  },
60
64
  "engines": {
61
65
  "node": ">=24"
@@ -77,6 +81,7 @@
77
81
  },
78
82
  "scripts": {
79
83
  "check:pack": "tsx ../../tools/src/check-pack.ts --package . && pnpm run smoke:pack",
80
- "smoke:pack": "node scripts/smoke-packed-analyzer.mjs"
84
+ "smoke:pack": "node scripts/smoke-packed-analyzer.mjs",
85
+ "test": "vitest run --passWithNoTests"
81
86
  }
82
87
  }