Files
paseo/packages/server/src/server/persistence-hooks.test.ts
T
Mohamed Boudra bf69ebeddf Stop persisting agent prompt as the backend title
config.title is now strictly the caller's creation intent and is never
mutated. The prompt-derived placeholder lives only in record.title at
creation, so the metadata generator's upfront gate (hasExplicitTitle) is
the only one and writes unconditionally when it runs. Drops the two
projection fallbacks to record.config.title that were the second
hidden path for the prompt to surface as a title.
2026-05-26 10:42:36 +07:00

136 lines
3.5 KiB
TypeScript

import { describe, expect, test } from "vitest";
import type { StoredAgentRecord } from "./agent/agent-storage.js";
import {
buildConfigOverrides,
buildSessionConfig,
toAgentPersistenceHandle,
} from "./persistence-hooks.js";
function createRecord(overrides?: Partial<StoredAgentRecord>): StoredAgentRecord {
const now = new Date().toISOString();
return {
id: "agent-record",
provider: "claude",
cwd: "/tmp/project",
createdAt: now,
updatedAt: now,
title: null,
lastStatus: "idle",
lastModeId: "plan",
config: { modeId: "plan", model: "claude-3.5-sonnet" },
persistence: {
provider: "claude",
sessionId: "session-123",
},
...overrides,
};
}
describe("persistence hooks", () => {
test("buildConfigOverrides carries systemPrompt and mcpServers", () => {
const record = createRecord({
title: "Voice agent (current)",
config: {
modeId: "default",
model: "gpt-5.4-mini",
thinkingOptionId: "minimal",
systemPrompt: "Use speak first.",
mcpServers: {
paseo: {
type: "stdio",
command: "node",
args: ["/tmp/bridge.mjs", "--socket", "/tmp/agent.sock"],
},
},
},
});
expect(buildConfigOverrides(record)).toMatchObject({
cwd: "/tmp/project",
modeId: "plan",
model: "gpt-5.4-mini",
thinkingOptionId: "minimal",
systemPrompt: "Use speak first.",
mcpServers: {
paseo: {
type: "stdio",
command: "node",
args: ["/tmp/bridge.mjs", "--socket", "/tmp/agent.sock"],
},
},
});
});
test("buildSessionConfig includes persisted systemPrompt and mcpServers", () => {
const record = createRecord({
provider: "codex",
title: "Renamed title",
config: {
modeId: "default",
model: "gpt-5.4-mini",
systemPrompt: "Confirm and speak first.",
mcpServers: {
paseo: {
type: "stdio",
command: "node",
args: ["/tmp/bridge.mjs", "--socket", "/tmp/agent.sock"],
},
},
},
});
expect(buildSessionConfig(record)).toMatchObject({
provider: "codex",
cwd: "/tmp/project",
modeId: "plan",
model: "gpt-5.4-mini",
systemPrompt: "Confirm and speak first.",
mcpServers: {
paseo: {
type: "stdio",
command: "node",
args: ["/tmp/bridge.mjs", "--socket", "/tmp/agent.sock"],
},
},
});
});
test("buildSessionConfig accepts providers from the canonical manifest", () => {
const record = createRecord({
provider: "claude",
persistence: {
provider: "claude",
sessionId: "session-123",
},
config: {},
});
expect(buildSessionConfig(record)).toMatchObject({
provider: "claude",
cwd: "/tmp/project",
});
});
test("buildSessionConfig skips records whose provider is missing from the registry", () => {
const record = createRecord({
id: "agent-missing-provider",
provider: "zai",
});
expect(
buildSessionConfig(record, {
validProviders: ["claude", "codex"],
}),
).toBeNull();
});
test("toAgentPersistenceHandle rejects handles for unavailable providers", () => {
const handle = toAgentPersistenceHandle(["claude", "codex"], {
provider: "gemini",
sessionId: "session-123",
});
expect(handle).toBeNull();
});
});