feat: model selection at spawn (POST /api/spawn model -> LVMH_MODEL -> bridge createAgentSession); ops prepare resets ops session (fresh context per prepare)

This commit is contained in:
Raphael Westphal
2026-08-20 12:43:55 +02:00
parent 5292a69d66
commit 2d0839357d
11 changed files with 553 additions and 48 deletions
+28 -2
View File
@@ -4,7 +4,10 @@
// Global npm layout: resolve pi via absolute path (NODE_PATH does not apply to ESM).
import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { createAgentSession } from "/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/dist/index.js";
import {
createAgentSession,
ModelRuntime,
} from "/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/dist/index.js";
const SETUP_PATH = "/workspace/.lvmh/setup.sh";
const SETUP_TIMEOUT_MS = 10 * 60 * 1000;
@@ -57,7 +60,30 @@ process.on("unhandledRejection", (err) => {
try {
await runRepoSetup();
const { session } = await createAgentSession();
// Optional initial model: LVMH_MODEL="provider/model-id" from the spawn
// request. Resolved against the session's model registry; a bad value is
// logged and falls back to the default model.
const requested = process.env.LVMH_MODEL ?? "";
let model;
if (requested.includes("/")) {
const slashIdx = requested.indexOf("/");
const provider = requested.slice(0, slashIdx);
const modelId = requested.slice(slashIdx + 1);
try {
const runtime = await ModelRuntime.create();
const models = await runtime.getAvailable(provider);
const found = models.find((m) => m.id === modelId);
if (found === undefined) {
console.error(`[lvmh-bridge] LVMH_MODEL ${requested} not found; using default`);
} else {
model = found;
console.error(`[lvmh-bridge] initial model: ${requested}`);
}
} catch (err) {
console.error(`[lvmh-bridge] model resolution failed:`, err);
}
}
const { session } = await createAgentSession(model === undefined ? {} : { model });
// SDK does not bind extensions implicitly (unlike TUI/RPC modes); without
// bindExtensions the session_start event never fires, so the lvmh plugin
// would never dial the daemon.