- 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
101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { registerFauxProvider } from "@mariozechner/pi-ai";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import {
|
|
type CreateAgentSessionRuntimeFactory,
|
|
createAgentSessionFromServices,
|
|
createAgentSessionRuntime,
|
|
createAgentSessionServices,
|
|
} from "../../../src/core/agent-session-runtime.js";
|
|
import { AuthStorage } from "../../../src/core/auth-storage.js";
|
|
import { SessionManager } from "../../../src/core/session-manager.js";
|
|
|
|
describe("issue #2753 reload stale resource settings", () => {
|
|
const cleanups: Array<() => void> = [];
|
|
|
|
afterEach(() => {
|
|
while (cleanups.length > 0) {
|
|
cleanups.pop()?.();
|
|
}
|
|
});
|
|
|
|
it("applies updated top-level prompt settings on reload after startup", async () => {
|
|
const tempDir = join(tmpdir(), `pi-2753-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
const agentDir = join(tempDir, "agent");
|
|
const promptsDir = join(agentDir, "prompts");
|
|
mkdirSync(promptsDir, { recursive: true });
|
|
writeFileSync(join(promptsDir, "test.md"), "Echo test prompt\n");
|
|
|
|
const faux = registerFauxProvider({
|
|
models: [{ id: "faux-1", reasoning: false }],
|
|
});
|
|
const authStorage = AuthStorage.inMemory();
|
|
authStorage.setRuntimeApiKey(faux.getModel().provider, "faux-key");
|
|
|
|
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
const services = await createAgentSessionServices({
|
|
cwd,
|
|
agentDir,
|
|
authStorage,
|
|
resourceLoaderOptions: {
|
|
extensionFactories: [
|
|
(pi) => {
|
|
pi.registerProvider(faux.getModel().provider, {
|
|
baseUrl: faux.getModel().baseUrl,
|
|
apiKey: "faux-key",
|
|
api: faux.api,
|
|
models: faux.models.map((registeredModel) => ({
|
|
id: registeredModel.id,
|
|
name: registeredModel.name,
|
|
api: registeredModel.api,
|
|
reasoning: registeredModel.reasoning,
|
|
input: registeredModel.input,
|
|
cost: registeredModel.cost,
|
|
contextWindow: registeredModel.contextWindow,
|
|
maxTokens: registeredModel.maxTokens,
|
|
})),
|
|
});
|
|
},
|
|
],
|
|
noSkills: true,
|
|
noThemes: true,
|
|
},
|
|
});
|
|
return {
|
|
...(await createAgentSessionFromServices({
|
|
services,
|
|
sessionManager,
|
|
sessionStartEvent,
|
|
model: faux.getModel(),
|
|
})),
|
|
services,
|
|
diagnostics: services.diagnostics,
|
|
};
|
|
};
|
|
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
cwd: tempDir,
|
|
agentDir,
|
|
sessionManager: SessionManager.create(tempDir),
|
|
});
|
|
|
|
cleanups.push(() => {
|
|
runtime.session.dispose();
|
|
faux.unregister();
|
|
if (existsSync(tempDir)) {
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
expect(runtime.session.promptTemplates.map((prompt) => prompt.name)).toContain("test");
|
|
|
|
writeFileSync(join(agentDir, "settings.json"), `${JSON.stringify({ prompts: ["-prompts/test.md"] }, null, 2)}\n`);
|
|
|
|
await runtime.session.reload();
|
|
|
|
expect(runtime.services.settingsManager.getGlobalSettings().prompts).toEqual(["-prompts/test.md"]);
|
|
expect(runtime.session.promptTemplates.map((prompt) => prompt.name)).not.toContain("test");
|
|
});
|
|
});
|