mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-24 10:12:44 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37fd9259e0 | ||
|
|
f4ba16a0b3 |
@@ -210,6 +210,17 @@ describe("stream presentation through installed plugins", () => {
|
||||
expect(result.head).toMatchObject([{ text: "```ts\nconst a = 1;\n\nconst b = 2;" }]);
|
||||
});
|
||||
|
||||
// Codex streams a line break and the next line's indent as their own chunks.
|
||||
it("keeps a line break when a chunk ends in the next line's indent", () => {
|
||||
const harness = streamHarness();
|
||||
harness.send(assistant("```mermaid\nflowchart TD\n A[Start] --> B[Review]\n"));
|
||||
harness.send(assistant(" "));
|
||||
const result = harness.send(assistant(" B --> C[Finish]\n```"));
|
||||
expect(result.head).toMatchObject([
|
||||
{ text: "```mermaid\nflowchart TD\n A[Start] --> B[Review]\n B --> C[Finish]\n```" },
|
||||
]);
|
||||
});
|
||||
|
||||
// One rendering path: a fetched message is the same block group as a streamed one,
|
||||
// which is what lets find, scroll-to-message and history reveal address it by id.
|
||||
// A link reference definition stays with the paragraph that uses it, so the split
|
||||
|
||||
@@ -112,8 +112,10 @@ export function createStreamPresentation() {
|
||||
const index = prefix.length + offset;
|
||||
let blockText = text;
|
||||
if (offset === textBlocks.length - 1) {
|
||||
const trailingNewlines = /\n+$/.exec(item.text)?.[0] ?? "";
|
||||
blockText += trailingNewlines;
|
||||
// The split drops trailing blank lines, including a line break followed only
|
||||
// by the next line's indent. Keep them so the next append continues that line.
|
||||
const trailingBlankLines = /\n\s*$/.exec(item.text)?.[0] ?? "";
|
||||
blockText += trailingBlankLines;
|
||||
}
|
||||
const existing = previous?.[index];
|
||||
const id = `${item.id}:block:${index}`;
|
||||
|
||||
@@ -5066,6 +5066,42 @@ test("session config drift events update state through the stream channel", asyn
|
||||
expect(streams.map((event) => event.type)).toEqual([]);
|
||||
});
|
||||
|
||||
test("provider-side model switch survives reload and daemon restart", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-provider-model-switch-"));
|
||||
const storage = new AgentStorage(join(workdir, "agents"), logger);
|
||||
let capturedSession: TestAgentSession | null = null;
|
||||
class ModelSwitchClient extends TestAgentClient {
|
||||
override async createSession(config: AgentSessionConfig): Promise<AgentSession> {
|
||||
capturedSession = new TestAgentSession(config);
|
||||
return capturedSession;
|
||||
}
|
||||
}
|
||||
const client = new ModelSwitchClient();
|
||||
const manager = new AgentManager({
|
||||
clients: { codex: client },
|
||||
registry: storage,
|
||||
logger,
|
||||
idFactory: () => "00000000-0000-4000-8000-000000000134",
|
||||
});
|
||||
|
||||
const snapshot = await manager.createAgent(
|
||||
{ provider: "codex", cwd: workdir, model: "gpt-5.2-codex" },
|
||||
undefined,
|
||||
{ workspaceId: undefined },
|
||||
);
|
||||
capturedSession!.pushEvent({
|
||||
type: "model_changed",
|
||||
provider: "codex",
|
||||
runtimeInfo: { provider: "codex", sessionId: capturedSession!.id, model: "gpt-5.4" },
|
||||
});
|
||||
await manager.flush();
|
||||
|
||||
await manager.reloadAgentSession(snapshot.id);
|
||||
expect(client.resumeOverrides.at(-1)?.model).toBe("gpt-5.4");
|
||||
expect((await storage.get(snapshot.id))?.config?.model).toBe("gpt-5.4");
|
||||
rmSync(workdir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test("setLabels merges and persists labels", async () => {
|
||||
const workdir = mkdtempSync(join(tmpdir(), "agent-manager-set-labels-"));
|
||||
const storagePath = join(workdir, "agents");
|
||||
|
||||
@@ -4310,6 +4310,7 @@ export class AgentManager {
|
||||
return undefined;
|
||||
case "model_changed":
|
||||
agent.runtimeInfo = event.runtimeInfo;
|
||||
agent.config.model = event.runtimeInfo.model ?? agent.config.model;
|
||||
if (!agent.persistence && event.runtimeInfo.sessionId) {
|
||||
agent.persistence = attachPersistenceCwd(
|
||||
{ provider: agent.provider, sessionId: event.runtimeInfo.sessionId },
|
||||
|
||||
Reference in New Issue
Block a user