refactor(coding-agent): replace AgentSessionRuntimeHost with closure-based AgentSessionRuntime

- Replace AgentSessionRuntimeHost and bootstrap abstractions with AgentSessionRuntime
- Runtime creation is now closure-based via CreateAgentSessionRuntimeFactory
- Factory closes over process-global fixed inputs, recreates cwd-bound services per effective cwd
- Session config (model, thinking, tools, scoped models) re-resolved per target cwd
- CLI resource paths resolved once at startup as absolute paths
- Swap lifecycle: teardown old, create next, apply next (hard fail on creation error)
- Unified diagnostics model (info/warning/error) for args, services, session resolution, resources
- No logging or process exits inside creation/parsing logic
- Removed session_directory support
- Removed session_switch and session_fork extension events (use session_start with reason)
- Moved package/config CLI to package-manager-cli.ts
- Fixed theme init for --resume session picker
- Fixed flaky reftable footer test (content-based polling)
- Fixed silent drop of unknown single-dash CLI flags
- Added error diagnostics for missing explicit CLI resource paths
- Updated SDK docs, examples, plans, exports, tests, changelog

fixes #2753
This commit is contained in:
Mario Zechner
2026-04-03 20:14:12 +02:00
parent 042066b982
commit 9f9277ccdd
38 changed files with 2180 additions and 1366 deletions

View File

@@ -14,9 +14,11 @@ import { getModel } from "@mariozechner/pi-ai";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import type { AgentSession } from "../src/core/agent-session.js";
import {
type AgentSessionRuntimeHost,
type AgentSessionRuntime,
type CreateAgentSessionRuntimeFactory,
createAgentSessionFromServices,
createAgentSessionRuntime,
AgentSessionRuntimeHost as RuntimeHost,
createAgentSessionServices,
} from "../src/core/agent-session-runtime.js";
import { AuthStorage } from "../src/core/auth-storage.js";
import { SessionManager } from "../src/core/session-manager.js";
@@ -25,7 +27,7 @@ import { API_KEY } from "./utilities.js";
describe.skipIf(!API_KEY)("AgentSession forking", () => {
let session: AgentSession;
let runtimeHost: AgentSessionRuntimeHost;
let runtimeHost: AgentSessionRuntime;
let tempDir: string;
let sessionManager: SessionManager;
@@ -50,23 +52,38 @@ describe.skipIf(!API_KEY)("AgentSession forking", () => {
const authStorage = AuthStorage.create(join(tempDir, "auth.json"));
authStorage.setRuntimeApiKey("anthropic", API_KEY!);
const bootstrap = {
const servicesOptions = {
agentDir: tempDir,
authStorage,
model,
tools: codingTools,
resourceLoader: {
resourceLoaderOptions: {
noExtensions: true,
noSkills: true,
noPromptTemplates: true,
noThemes: true,
},
};
const runtime = await createAgentSessionRuntime(bootstrap, {
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({
...servicesOptions,
cwd,
});
return {
...(await createAgentSessionFromServices({
services,
sessionManager,
sessionStartEvent,
model,
tools: codingTools,
})),
services,
diagnostics: services.diagnostics,
};
};
runtimeHost = await createAgentSessionRuntime(createRuntime, {
cwd: tempDir,
agentDir: tempDir,
sessionManager,
});
runtimeHost = new RuntimeHost(bootstrap, runtime);
session = runtimeHost.session;
session.subscribe(() => {});
return session;