@kenkaiiii/ggcoder 5.24.0 → 5.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-sidecar.js +330 -12
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +12 -0
- package/dist/config.test.js.map +1 -1
- package/dist/core/agent-notifications.d.ts +62 -0
- package/dist/core/agent-notifications.d.ts.map +1 -0
- package/dist/core/agent-notifications.js +92 -0
- package/dist/core/agent-notifications.js.map +1 -0
- package/dist/core/agent-notifications.test.d.ts +2 -0
- package/dist/core/agent-notifications.test.d.ts.map +1 -0
- package/dist/core/agent-notifications.test.js +97 -0
- package/dist/core/agent-notifications.test.js.map +1 -0
- package/dist/core/agent-session-add-dir.test.js +16 -0
- package/dist/core/agent-session-add-dir.test.js.map +1 -1
- package/dist/core/agent-session-model-switch.test.d.ts +2 -0
- package/dist/core/agent-session-model-switch.test.d.ts.map +1 -0
- package/dist/core/agent-session-model-switch.test.js +161 -0
- package/dist/core/agent-session-model-switch.test.js.map +1 -0
- package/dist/core/agent-session-notifications.test.d.ts +2 -0
- package/dist/core/agent-session-notifications.test.d.ts.map +1 -0
- package/dist/core/agent-session-notifications.test.js +114 -0
- package/dist/core/agent-session-notifications.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +76 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +246 -25
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/event-bus.d.ts +6 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +7 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/local-endpoint-store.d.ts +50 -0
- package/dist/core/local-endpoint-store.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.js +201 -0
- package/dist/core/local-endpoint-store.js.map +1 -0
- package/dist/core/local-endpoint-store.test.d.ts +2 -0
- package/dist/core/local-endpoint-store.test.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.test.js +131 -0
- package/dist/core/local-endpoint-store.test.js.map +1 -0
- package/dist/core/memory/compaction-notes.d.ts +31 -0
- package/dist/core/memory/compaction-notes.d.ts.map +1 -0
- package/dist/core/memory/compaction-notes.js +162 -0
- package/dist/core/memory/compaction-notes.js.map +1 -0
- package/dist/core/memory/compaction-notes.test.d.ts +2 -0
- package/dist/core/memory/compaction-notes.test.d.ts.map +1 -0
- package/dist/core/memory/compaction-notes.test.js +110 -0
- package/dist/core/memory/compaction-notes.test.js.map +1 -0
- package/dist/core/memory/journal.d.ts +55 -0
- package/dist/core/memory/journal.d.ts.map +1 -0
- package/dist/core/memory/journal.js +212 -0
- package/dist/core/memory/journal.js.map +1 -0
- package/dist/core/memory/journal.test.d.ts +2 -0
- package/dist/core/memory/journal.test.d.ts.map +1 -0
- package/dist/core/memory/journal.test.js +184 -0
- package/dist/core/memory/journal.test.js.map +1 -0
- package/dist/core/process-manager-notifications.test.d.ts +2 -0
- package/dist/core/process-manager-notifications.test.d.ts.map +1 -0
- package/dist/core/process-manager-notifications.test.js +113 -0
- package/dist/core/process-manager-notifications.test.js.map +1 -0
- package/dist/core/process-manager.d.ts +29 -0
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +123 -0
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +7 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts +8 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +17 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/slash-commands.test.js +11 -0
- package/dist/core/slash-commands.test.js.map +1 -1
- package/dist/core/steering.d.ts +12 -0
- package/dist/core/steering.d.ts.map +1 -1
- package/dist/core/steering.js +16 -0
- package/dist/core/steering.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +13 -0
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +30 -0
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +16 -0
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/modes/json-mode.d.ts.map +1 -1
- package/dist/modes/json-mode.js +5 -0
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +3 -1
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/subagent-control.d.ts.map +1 -1
- package/dist/tools/subagent-control.js +6 -2
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +6 -0
- package/dist/tools/subagent-shared.d.ts.map +1 -1
- package/dist/tools/subagent-shared.js +6 -0
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/task-output.d.ts.map +1 -1
- package/dist/tools/task-output.js +3 -1
- package/dist/tools/task-output.js.map +1 -1
- package/dist/ui/App.d.ts +2 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +35 -1
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/render.d.ts +2 -0
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +1 -0
- package/dist/ui/render.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { AgentNotificationQueue, NOTIFICATION_DRAIN_MAX_CHARS, NOTIFICATION_MAX_CHARS, } from "./agent-notifications.js";
|
|
3
|
+
describe("AgentNotificationQueue", () => {
|
|
4
|
+
it("drains in insertion order and clears itself", () => {
|
|
5
|
+
const q = new AgentNotificationQueue();
|
|
6
|
+
q.enqueue("subagent", "a", "first");
|
|
7
|
+
q.enqueue("subagent", "b", "second");
|
|
8
|
+
expect(q.drain().map((n) => n.text)).toEqual(["first", "second"]);
|
|
9
|
+
expect(q.size).toBe(0);
|
|
10
|
+
expect(q.drain()).toEqual([]);
|
|
11
|
+
});
|
|
12
|
+
it("keeps only the latest entry per (kind, id)", () => {
|
|
13
|
+
const q = new AgentNotificationQueue();
|
|
14
|
+
q.enqueue("process", "p1", "10% done");
|
|
15
|
+
q.enqueue("process", "p1", "90% done");
|
|
16
|
+
const drained = q.drain();
|
|
17
|
+
expect(drained).toHaveLength(1);
|
|
18
|
+
expect(drained[0].text).toBe("90% done");
|
|
19
|
+
});
|
|
20
|
+
it("keys dedupe by kind as well as id", () => {
|
|
21
|
+
const q = new AgentNotificationQueue();
|
|
22
|
+
q.enqueue("process", "1", "process one");
|
|
23
|
+
q.enqueue("subagent", "1", "child one");
|
|
24
|
+
expect(q.drain()).toHaveLength(2);
|
|
25
|
+
});
|
|
26
|
+
it("preserves queue position when an entry is updated", () => {
|
|
27
|
+
const q = new AgentNotificationQueue();
|
|
28
|
+
q.enqueue("process", "p1", "old");
|
|
29
|
+
q.enqueue("process", "p2", "other");
|
|
30
|
+
q.enqueue("process", "p1", "new");
|
|
31
|
+
expect(q.drain().map((n) => n.text)).toEqual(["new", "other"]);
|
|
32
|
+
});
|
|
33
|
+
it("lets a terminal entry supersede a pending progress entry", () => {
|
|
34
|
+
const q = new AgentNotificationQueue();
|
|
35
|
+
q.enqueue("process", "p1", "still building");
|
|
36
|
+
expect(q.enqueue("process", "p1", "exited 0", { terminal: true })).toBe(true);
|
|
37
|
+
const drained = q.drain();
|
|
38
|
+
expect(drained).toHaveLength(1);
|
|
39
|
+
expect(drained[0]).toMatchObject({ text: "exited 0", terminal: true });
|
|
40
|
+
});
|
|
41
|
+
it("refuses to overwrite a terminal entry with a late progress tick", () => {
|
|
42
|
+
const q = new AgentNotificationQueue();
|
|
43
|
+
q.enqueue("process", "p1", "exited 1", { terminal: true });
|
|
44
|
+
expect(q.enqueue("process", "p1", "50% done")).toBe(false);
|
|
45
|
+
expect(q.drain()[0]).toMatchObject({ text: "exited 1", terminal: true });
|
|
46
|
+
});
|
|
47
|
+
it("allows a terminal entry to replace an earlier terminal entry", () => {
|
|
48
|
+
const q = new AgentNotificationQueue();
|
|
49
|
+
q.enqueue("subagent", "a", "failed", { terminal: true });
|
|
50
|
+
q.enqueue("subagent", "a", "done", { terminal: true });
|
|
51
|
+
expect(q.drain()[0].text).toBe("done");
|
|
52
|
+
});
|
|
53
|
+
it("caps a single notification at NOTIFICATION_MAX_CHARS", () => {
|
|
54
|
+
const q = new AgentNotificationQueue();
|
|
55
|
+
q.enqueue("subagent", "a", "x".repeat(NOTIFICATION_MAX_CHARS * 3));
|
|
56
|
+
const [entry] = q.drain();
|
|
57
|
+
expect(entry.text.length).toBe(NOTIFICATION_MAX_CHARS);
|
|
58
|
+
expect(entry.text.endsWith("\u2026")).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
it("collapses whitespace so multi-line output cannot inflate a notification", () => {
|
|
61
|
+
const q = new AgentNotificationQueue();
|
|
62
|
+
q.enqueue("process", "p1", " build\n\n failed \t badly ");
|
|
63
|
+
expect(q.drain()[0].text).toBe("build failed badly");
|
|
64
|
+
});
|
|
65
|
+
it("caps one drain at NOTIFICATION_DRAIN_MAX_CHARS and requeues the rest", () => {
|
|
66
|
+
const q = new AgentNotificationQueue();
|
|
67
|
+
for (let i = 0; i < 6; i++)
|
|
68
|
+
q.enqueue("subagent", `a${i}`, "y".repeat(NOTIFICATION_MAX_CHARS));
|
|
69
|
+
const first = q.drain();
|
|
70
|
+
const firstChars = first.reduce((sum, n) => sum + n.text.length, 0);
|
|
71
|
+
expect(firstChars).toBeLessThanOrEqual(NOTIFICATION_DRAIN_MAX_CHARS);
|
|
72
|
+
expect(first).toHaveLength(2);
|
|
73
|
+
// Nothing is lost — the remainder waits for the next drain.
|
|
74
|
+
expect(q.size).toBe(4);
|
|
75
|
+
});
|
|
76
|
+
it("never deadlocks on an oversized head entry", () => {
|
|
77
|
+
const q = new AgentNotificationQueue();
|
|
78
|
+
// Two max-size entries fill the drain budget exactly; add a third.
|
|
79
|
+
q.enqueue("subagent", "a", "y".repeat(NOTIFICATION_MAX_CHARS));
|
|
80
|
+
q.enqueue("subagent", "b", "y".repeat(NOTIFICATION_MAX_CHARS));
|
|
81
|
+
q.enqueue("subagent", "c", "z".repeat(NOTIFICATION_MAX_CHARS));
|
|
82
|
+
expect(q.drain()).toHaveLength(2);
|
|
83
|
+
const rest = q.drain();
|
|
84
|
+
expect(rest).toHaveLength(1);
|
|
85
|
+
expect(q.size).toBe(0);
|
|
86
|
+
});
|
|
87
|
+
it("clears a single producer and everything", () => {
|
|
88
|
+
const q = new AgentNotificationQueue();
|
|
89
|
+
q.enqueue("process", "p1", "a");
|
|
90
|
+
q.enqueue("process", "p2", "b");
|
|
91
|
+
q.clear("process", "p1");
|
|
92
|
+
expect(q.size).toBe(1);
|
|
93
|
+
q.clearAll();
|
|
94
|
+
expect(q.size).toBe(0);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=agent-notifications.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-notifications.test.js","sourceRoot":"","sources":["../../src/core/agent-notifications.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -74,6 +74,22 @@ describe("AgentSession.addDirectory", () => {
|
|
|
74
74
|
await session.dispose();
|
|
75
75
|
}
|
|
76
76
|
}, 20_000);
|
|
77
|
+
it("removes an added root and rejects roots that were never added", async () => {
|
|
78
|
+
const session = await createSession();
|
|
79
|
+
try {
|
|
80
|
+
expect(await session.removeDirectory(sibling)).toMatchObject({ ok: false });
|
|
81
|
+
expect(await session.addDirectory(sibling)).toMatchObject({ ok: true });
|
|
82
|
+
expect(await session.removeDirectory(sibling)).toEqual({
|
|
83
|
+
ok: true,
|
|
84
|
+
root: path.resolve(sibling),
|
|
85
|
+
});
|
|
86
|
+
expect(session.getAdditionalRoots()).toEqual([]);
|
|
87
|
+
expect(String(session.getMessages()[0]?.content ?? "")).not.toContain("Additional roots:");
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
await session.dispose();
|
|
91
|
+
}
|
|
92
|
+
}, 20_000);
|
|
77
93
|
it("rejects a file, a missing path, and a duplicate", async () => {
|
|
78
94
|
const session = await createSession();
|
|
79
95
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-add-dir.test.js","sourceRoot":"","sources":["../../src/core/agent-session-add-dir.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agent-session-add-dir.test.js","sourceRoot":"","sources":["../../src/core/agent-session-add-dir.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-model-switch.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-model-switch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A mid-session model switch must be replayable state, not a silent mutation:
|
|
3
|
+
* recorded as a durable marker, injected as its own trailing message, and — the
|
|
4
|
+
* expensive part — kept OFF the cached system prefix so the next turn still
|
|
5
|
+
* reads from cache.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import os from "node:os";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
|
+
import { useFakeHome } from "../test-support/fake-home.js";
|
|
12
|
+
const agentLoopMock = vi.hoisted(() => vi.fn());
|
|
13
|
+
vi.mock("@kenkaiiii/gg-agent", async () => {
|
|
14
|
+
const actual = await vi.importActual("@kenkaiiii/gg-agent");
|
|
15
|
+
return { ...actual, agentLoop: agentLoopMock };
|
|
16
|
+
});
|
|
17
|
+
vi.mock("./mcp/index.js", async () => {
|
|
18
|
+
const actual = await vi.importActual("./mcp/index.js");
|
|
19
|
+
return {
|
|
20
|
+
...actual,
|
|
21
|
+
MCPClientManager: vi.fn(function MCPClientManagerMock() {
|
|
22
|
+
return { connectAll: vi.fn(async () => []), dispose: vi.fn(async () => { }) };
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
let restoreHome;
|
|
27
|
+
let tempHome;
|
|
28
|
+
let tempProject;
|
|
29
|
+
const CACHE_MARKER = "<!-- uncached -->";
|
|
30
|
+
beforeEach(async () => {
|
|
31
|
+
tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "agent-switch-home-"));
|
|
32
|
+
tempProject = await fs.mkdtemp(path.join(os.tmpdir(), "agent-switch-project-"));
|
|
33
|
+
restoreHome = useFakeHome(tempHome);
|
|
34
|
+
agentLoopMock.mockReset();
|
|
35
|
+
await fs.mkdir(path.join(tempHome, ".gg"), { recursive: true });
|
|
36
|
+
await fs.writeFile(path.join(tempHome, ".gg", "auth.json"), JSON.stringify({
|
|
37
|
+
anthropic: { accessToken: "t", refreshToken: "t", expiresAt: Date.now() + 3_600_000 },
|
|
38
|
+
openai: { accessToken: "t", refreshToken: "t", expiresAt: Date.now() + 3_600_000 },
|
|
39
|
+
}));
|
|
40
|
+
});
|
|
41
|
+
afterEach(async () => {
|
|
42
|
+
restoreHome?.();
|
|
43
|
+
await Promise.all([
|
|
44
|
+
fs.rm(tempHome, { recursive: true, force: true }),
|
|
45
|
+
fs.rm(tempProject, { recursive: true, force: true }),
|
|
46
|
+
]);
|
|
47
|
+
vi.clearAllMocks();
|
|
48
|
+
});
|
|
49
|
+
async function createSession() {
|
|
50
|
+
const { AgentSession } = await import("./agent-session.js");
|
|
51
|
+
const session = new AgentSession({
|
|
52
|
+
provider: "openai",
|
|
53
|
+
model: "gpt-5.6-sol",
|
|
54
|
+
// Repo cwd so the bundled agent definitions register spawn_agent — the
|
|
55
|
+
// Sol/Ultra orchestration block only renders when that tool exists, and it
|
|
56
|
+
// is the model-dependent prompt content this test is about.
|
|
57
|
+
cwd: process.cwd(),
|
|
58
|
+
systemPrompt: "stable role prompt",
|
|
59
|
+
thinkingLevel: "ultra",
|
|
60
|
+
transient: true,
|
|
61
|
+
selfCorrectionHooks: false,
|
|
62
|
+
});
|
|
63
|
+
await session.initialize();
|
|
64
|
+
// A conversation must already exist for the switch note to have a job.
|
|
65
|
+
session
|
|
66
|
+
.getMessages()
|
|
67
|
+
.push({ role: "user", content: "start the work" }, { role: "assistant", content: "on it" });
|
|
68
|
+
return session;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* System-prompt bytes that carry cache_control. Mirrors the provider split in
|
|
72
|
+
* gg-ai `transform.ts`: everything before the marker, trimmed at the end.
|
|
73
|
+
*/
|
|
74
|
+
function cachedPrefix(content) {
|
|
75
|
+
const index = content.indexOf(CACHE_MARKER);
|
|
76
|
+
return (index === -1 ? content : content.slice(0, index)).trimEnd();
|
|
77
|
+
}
|
|
78
|
+
describe("AgentSession model switch", () => {
|
|
79
|
+
it("keeps the cached system prefix byte-identical across a switch", async () => {
|
|
80
|
+
const session = await createSession();
|
|
81
|
+
try {
|
|
82
|
+
const before = String(session.getMessages()[0].content);
|
|
83
|
+
// Sol/Ultra guidance is live, so the switch really does change the prompt.
|
|
84
|
+
expect(before).toContain(CACHE_MARKER);
|
|
85
|
+
expect(before).toContain("Proactively use spawn_agent");
|
|
86
|
+
await session.switchModel("openai", "gpt-5.5-codex");
|
|
87
|
+
const after = String(session.getMessages()[0].content);
|
|
88
|
+
expect(cachedPrefix(after)).toBe(cachedPrefix(before));
|
|
89
|
+
// Model-dependent guidance followed the model, out of the cached region.
|
|
90
|
+
expect(after).not.toContain("Proactively use spawn_agent");
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
await session.dispose();
|
|
94
|
+
}
|
|
95
|
+
}, 30_000);
|
|
96
|
+
it("appends the switch as its own trailing message", async () => {
|
|
97
|
+
const session = await createSession();
|
|
98
|
+
try {
|
|
99
|
+
await session.switchModel("openai", "gpt-5.5-codex");
|
|
100
|
+
const messages = session.getMessages();
|
|
101
|
+
const last = messages[messages.length - 1];
|
|
102
|
+
expect(last.role).toBe("user");
|
|
103
|
+
expect(String(last.content)).toContain("gpt-5.6-sol");
|
|
104
|
+
expect(String(last.content)).toContain("gpt-5.5-codex");
|
|
105
|
+
// Cross-provider switches name the provider on both sides.
|
|
106
|
+
await session.switchModel("anthropic", "claude-test");
|
|
107
|
+
expect(String(session.getMessages().at(-1).content)).toContain("anthropic/claude-test");
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await session.dispose();
|
|
111
|
+
}
|
|
112
|
+
}, 30_000);
|
|
113
|
+
it("records a replayable model_switch marker", async () => {
|
|
114
|
+
const session = await createSession();
|
|
115
|
+
try {
|
|
116
|
+
await session.switchModel("openai", "gpt-5.5-codex");
|
|
117
|
+
const markers = session.getAppMarkers().filter((m) => m.kind === "model_switch");
|
|
118
|
+
expect(markers).toHaveLength(1);
|
|
119
|
+
expect(markers[0].data).toMatchObject({
|
|
120
|
+
from: "gpt-5.6-sol",
|
|
121
|
+
to: "gpt-5.5-codex",
|
|
122
|
+
provider: "openai",
|
|
123
|
+
fromProvider: "openai",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
await session.dispose();
|
|
128
|
+
}
|
|
129
|
+
}, 30_000);
|
|
130
|
+
it("does nothing when the model did not actually change", async () => {
|
|
131
|
+
const session = await createSession();
|
|
132
|
+
try {
|
|
133
|
+
const before = [...session.getMessages()];
|
|
134
|
+
await session.switchModel("openai", "gpt-5.6-sol");
|
|
135
|
+
expect(session.getMessages()).toHaveLength(before.length);
|
|
136
|
+
expect(session.getAppMarkers().filter((m) => m.kind === "model_switch")).toHaveLength(0);
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
await session.dispose();
|
|
140
|
+
}
|
|
141
|
+
}, 30_000);
|
|
142
|
+
it("does not break tool pairing when a switch lands mid tool call", async () => {
|
|
143
|
+
const session = await createSession();
|
|
144
|
+
try {
|
|
145
|
+
session.getMessages().push({
|
|
146
|
+
role: "assistant",
|
|
147
|
+
content: [{ type: "tool_call", id: "t1", name: "read", args: {} }],
|
|
148
|
+
});
|
|
149
|
+
const count = session.getMessages().length;
|
|
150
|
+
await session.switchModel("openai", "gpt-5.5-codex");
|
|
151
|
+
// No user message may sit between tool_use and its tool_result.
|
|
152
|
+
expect(session.getMessages()).toHaveLength(count);
|
|
153
|
+
// The switch is still recorded durably.
|
|
154
|
+
expect(session.getAppMarkers().filter((m) => m.kind === "model_switch")).toHaveLength(1);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
await session.dispose();
|
|
158
|
+
}
|
|
159
|
+
}, 30_000);
|
|
160
|
+
});
|
|
161
|
+
//# sourceMappingURL=agent-session-model-switch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-model-switch.test.js","sourceRoot":"","sources":["../../src/core/agent-session-model-switch.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-notifications.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-notifications.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pushed notifications must reach the model on the steering path — a finished
|
|
3
|
+
* child or an exited background build should arrive on its own, without the
|
|
4
|
+
* agent spending a turn on wait_agent/task_output, and without displacing
|
|
5
|
+
* anything the user queued.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import os from "node:os";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
|
+
import { useFakeHome } from "../test-support/fake-home.js";
|
|
12
|
+
import { NOTIFICATION_DRAIN_MAX_CHARS } from "./agent-notifications.js";
|
|
13
|
+
import { NOTIFICATION_PREFIX, STEERING_PREFIX } from "./steering.js";
|
|
14
|
+
const agentLoopMock = vi.hoisted(() => vi.fn());
|
|
15
|
+
vi.mock("@kenkaiiii/gg-agent", async () => {
|
|
16
|
+
const actual = await vi.importActual("@kenkaiiii/gg-agent");
|
|
17
|
+
return { ...actual, agentLoop: agentLoopMock };
|
|
18
|
+
});
|
|
19
|
+
vi.mock("./mcp/index.js", async () => {
|
|
20
|
+
const actual = await vi.importActual("./mcp/index.js");
|
|
21
|
+
return {
|
|
22
|
+
...actual,
|
|
23
|
+
MCPClientManager: vi.fn(function MCPClientManagerMock() {
|
|
24
|
+
return { connectAll: vi.fn(async () => []), dispose: vi.fn(async () => { }) };
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
let restoreHome;
|
|
29
|
+
let tmpHome;
|
|
30
|
+
let tmpProject;
|
|
31
|
+
beforeEach(async () => {
|
|
32
|
+
tmpHome = await fs.mkdtemp(path.join(os.tmpdir(), "agent-session-notify-home-"));
|
|
33
|
+
tmpProject = await fs.mkdtemp(path.join(os.tmpdir(), "agent-session-notify-project-"));
|
|
34
|
+
restoreHome = useFakeHome(tmpHome);
|
|
35
|
+
agentLoopMock.mockReset();
|
|
36
|
+
await fs.mkdir(path.join(tmpHome, ".gg"), { recursive: true });
|
|
37
|
+
await fs.writeFile(path.join(tmpHome, ".gg", "auth.json"), JSON.stringify({
|
|
38
|
+
anthropic: {
|
|
39
|
+
accessToken: "test",
|
|
40
|
+
refreshToken: "test",
|
|
41
|
+
expiresAt: Date.now() + 3_600_000,
|
|
42
|
+
},
|
|
43
|
+
}), "utf-8");
|
|
44
|
+
});
|
|
45
|
+
afterEach(async () => {
|
|
46
|
+
restoreHome?.();
|
|
47
|
+
await fs.rm(tmpHome, { recursive: true, force: true });
|
|
48
|
+
await fs.rm(tmpProject, { recursive: true, force: true });
|
|
49
|
+
vi.clearAllMocks();
|
|
50
|
+
});
|
|
51
|
+
async function makeSession() {
|
|
52
|
+
const { AgentSession } = await import("./agent-session.js");
|
|
53
|
+
const session = new AgentSession({
|
|
54
|
+
provider: "anthropic",
|
|
55
|
+
model: "claude-test",
|
|
56
|
+
cwd: tmpProject,
|
|
57
|
+
systemPrompt: "test system prompt",
|
|
58
|
+
transient: true,
|
|
59
|
+
});
|
|
60
|
+
await session.initialize();
|
|
61
|
+
const internals = session;
|
|
62
|
+
return { session, internals };
|
|
63
|
+
}
|
|
64
|
+
describe("AgentSession pushed notifications", () => {
|
|
65
|
+
it("injects queued notifications as one framed steering message", async () => {
|
|
66
|
+
const { session, internals } = await makeSession();
|
|
67
|
+
try {
|
|
68
|
+
internals.notifications.enqueue("subagent", "a1", 'Child agent "one" is completed.', {
|
|
69
|
+
terminal: true,
|
|
70
|
+
});
|
|
71
|
+
internals.notifications.enqueue("process", "p1", "Build exited 0.", { terminal: true });
|
|
72
|
+
const messages = internals.getHookSteeringMessages();
|
|
73
|
+
expect(messages).toHaveLength(1);
|
|
74
|
+
const content = messages[0].content;
|
|
75
|
+
expect(content.startsWith(NOTIFICATION_PREFIX)).toBe(true);
|
|
76
|
+
expect(content).toContain('Child agent "one" is completed.');
|
|
77
|
+
expect(content).toContain("Build exited 0.");
|
|
78
|
+
expect(content.length).toBeLessThanOrEqual(NOTIFICATION_PREFIX.length + NOTIFICATION_DRAIN_MAX_CHARS + 8);
|
|
79
|
+
// Consumed exactly once — a second poll must not re-inject them.
|
|
80
|
+
expect(internals.getHookSteeringMessages()).toBeNull();
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
await session.dispose();
|
|
84
|
+
}
|
|
85
|
+
}, 15_000);
|
|
86
|
+
it("never displaces user steering — both ride out in the same batch", async () => {
|
|
87
|
+
const { session, internals } = await makeSession();
|
|
88
|
+
try {
|
|
89
|
+
session.queueMessage("also check the tests");
|
|
90
|
+
internals.notifications.enqueue("subagent", "a1", 'Child agent "one" is completed.', {
|
|
91
|
+
terminal: true,
|
|
92
|
+
});
|
|
93
|
+
const messages = internals.getHookSteeringMessages();
|
|
94
|
+
expect(messages).toHaveLength(2);
|
|
95
|
+
// User steering first: it is an instruction, the notification is a fact.
|
|
96
|
+
expect(messages[0].content).toBe(`${STEERING_PREFIX}also check the tests`);
|
|
97
|
+
expect(messages[1].content).toContain(NOTIFICATION_PREFIX);
|
|
98
|
+
expect(session.getQueuedCount()).toBe(0);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
await session.dispose();
|
|
102
|
+
}
|
|
103
|
+
}, 15_000);
|
|
104
|
+
it("returns null when nothing is pending", async () => {
|
|
105
|
+
const { session, internals } = await makeSession();
|
|
106
|
+
try {
|
|
107
|
+
expect(internals.getHookSteeringMessages()).toBeNull();
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await session.dispose();
|
|
111
|
+
}
|
|
112
|
+
}, 15_000);
|
|
113
|
+
});
|
|
114
|
+
//# sourceMappingURL=agent-session-notifications.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-session-notifications.test.js","sourceRoot":"","sources":["../../src/core/agent-session-notifications.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAGzE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErE,MAAM,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAEhD,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;IACxC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAAuB,qBAAqB,CAAC,CAAC;IAClF,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;IACnC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,YAAY,CAAmB,gBAAgB,CAAC,CAAC;IACzE,OAAO;QACL,GAAG,MAAM;QACT,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC,SAAS,oBAAoB;YACnD,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC,EAAE,CAAC;QAC/E,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,WAAqC,CAAC;AAC1C,IAAI,OAAe,CAAC;AACpB,IAAI,UAAkB,CAAC;AAEvB,UAAU,CAAC,KAAK,IAAI,EAAE;IACpB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,4BAA4B,CAAC,CAAC,CAAC;IACjF,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,+BAA+B,CAAC,CAAC,CAAC;IACvF,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,aAAa,CAAC,SAAS,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,EACtC,IAAI,CAAC,SAAS,CAAC;QACb,SAAS,EAAE;YACT,WAAW,EAAE,MAAM;YACnB,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SAClC;KACF,CAAC,EACF,OAAO,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,WAAW,EAAE,EAAE,CAAC;IAChB,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,EAAE,CAAC,aAAa,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAQH,KAAK,UAAU,WAAW;IACxB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAC/B,QAAQ,EAAE,WAAW;QACrB,KAAK,EAAE,aAAa;QACpB,GAAG,EAAE,UAAU;QACf,YAAY,EAAE,oBAAoB;QAClC,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,OAAsC,CAAC;IACzD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAChC,CAAC;AAED,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,iCAAiC,EAAE;gBACnF,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAExF,MAAM,QAAQ,GAAG,SAAS,CAAC,uBAAuB,EAAE,CAAC;YACrD,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,OAAO,GAAG,QAAS,CAAC,CAAC,CAAE,CAAC,OAAiB,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,mBAAmB,CACxC,mBAAmB,CAAC,MAAM,GAAG,4BAA4B,GAAG,CAAC,CAC9D,CAAC;YAEF,iEAAiE;YACjE,MAAM,CAAC,SAAS,CAAC,uBAAuB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzD,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC,EAAE,MAAM,CAAC,CAAC;IAEX,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;YAC7C,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,iCAAiC,EAAE;gBACnF,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,SAAS,CAAC,uBAAuB,EAAE,CAAC;YACrD,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,yEAAyE;YACzE,MAAM,CAAC,QAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,eAAe,sBAAsB,CAAC,CAAC;YAC7E,MAAM,CAAC,QAAS,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC,EAAE,MAAM,CAAC,CAAC;IAEX,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,CAAC,SAAS,CAAC,uBAAuB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzD,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC,CAAC,CAAC"}
|
|
@@ -27,6 +27,13 @@ export interface AgentSessionOptions {
|
|
|
27
27
|
continueRecent?: boolean;
|
|
28
28
|
maxTokens?: number;
|
|
29
29
|
maxTurns?: number;
|
|
30
|
+
/**
|
|
31
|
+
* How many times the turn budget may be extended when the agent is still
|
|
32
|
+
* making progress. Defaults to the agent-loop default (2); sub-agents pass a
|
|
33
|
+
* stricter cap because a child's extensions multiply against the parent's
|
|
34
|
+
* own budget.
|
|
35
|
+
*/
|
|
36
|
+
maxTurnExtensions?: number;
|
|
30
37
|
thinkingLevel?: ThinkingLevel;
|
|
31
38
|
signal?: AbortSignal;
|
|
32
39
|
/** Prefix used for provider prompt-cache routing keys. */
|
|
@@ -192,6 +199,18 @@ export declare class AgentSession {
|
|
|
192
199
|
private processManager?;
|
|
193
200
|
private lspManager?;
|
|
194
201
|
private subAgentManager?;
|
|
202
|
+
/**
|
|
203
|
+
* Out-of-band push notifications (finished children, background-process
|
|
204
|
+
* progress). Producers enqueue; `getHookSteeringMessages` drains into the
|
|
205
|
+
* live turn so the agent never has to spend a turn asking.
|
|
206
|
+
*/
|
|
207
|
+
private readonly notifications;
|
|
208
|
+
/**
|
|
209
|
+
* Durable cross-session journal at `<project>/.gg/memory.md`. Written only by
|
|
210
|
+
* the compactor, and only as past-tense history — see `memory/journal.ts` for
|
|
211
|
+
* why nothing else may write it. Undefined when `memoryEnabled` is off.
|
|
212
|
+
*/
|
|
213
|
+
private journal?;
|
|
195
214
|
private managerAbortSignal?;
|
|
196
215
|
private readonly managerAbortHandler;
|
|
197
216
|
private mcpManager?;
|
|
@@ -316,12 +335,19 @@ export declare class AgentSession {
|
|
|
316
335
|
*/
|
|
317
336
|
private trackHookEvent;
|
|
318
337
|
/**
|
|
319
|
-
* Mid-loop steering hook:
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
338
|
+
* Mid-loop steering hook: delivers pushed notifications and queued user
|
|
339
|
+
* steering, fires the loop-breaker when the agent looks stuck, then
|
|
340
|
+
* post-compaction re-grounding. At most one loop-break/re-grounding per run.
|
|
341
|
+
* Mirrors the TUI's getSteeringMessages ordering.
|
|
323
342
|
*/
|
|
324
343
|
private getHookSteeringMessages;
|
|
344
|
+
/**
|
|
345
|
+
* Turn-budget extension gate. The loop consults this instead of stopping
|
|
346
|
+
* mid-task when it exhausts `maxTurns`. Grant ONLY on evidence of progress —
|
|
347
|
+
* handing more turns to a spinning agent just buys it more tokens to spin
|
|
348
|
+
* with — so reuse the same stuck signals that drive the loop-breaker.
|
|
349
|
+
*/
|
|
350
|
+
private shouldExtendTurnBudget;
|
|
325
351
|
/**
|
|
326
352
|
* Pre-stop Ideal review phase machine. Once review starts, completion is
|
|
327
353
|
* blocked until harness-owned post-injection reads cover every changed file.
|
|
@@ -332,6 +358,18 @@ export declare class AgentSession {
|
|
|
332
358
|
/** Auto-compact if needed, run agent loop with auth retry, and persist messages. */
|
|
333
359
|
private runLoop;
|
|
334
360
|
switchModel(provider: string, model: string): Promise<void>;
|
|
361
|
+
/**
|
|
362
|
+
* Record the switch as its own trailing message at the point it happened,
|
|
363
|
+
* rather than by rewriting the system prompt. Two reasons: the system prompt
|
|
364
|
+
* is the cached prefix and rewriting it costs a full cache write, and a
|
|
365
|
+
* resumed transcript can only attribute output to the right model if the
|
|
366
|
+
* switch sits in message order.
|
|
367
|
+
*
|
|
368
|
+
* Skipped before the conversation starts (nothing to disambiguate) and while
|
|
369
|
+
* an assistant turn has unresolved tool calls, where inserting a user message
|
|
370
|
+
* would break tool_use/tool_result pairing.
|
|
371
|
+
*/
|
|
372
|
+
private appendModelSwitchNote;
|
|
335
373
|
compact(existingCredentials?: {
|
|
336
374
|
accessToken: string;
|
|
337
375
|
accountId?: string;
|
|
@@ -417,11 +455,38 @@ export declare class AgentSession {
|
|
|
417
455
|
ok: false;
|
|
418
456
|
error: string;
|
|
419
457
|
}>;
|
|
458
|
+
/** Remove an exact root previously added with `/add-dir`. */
|
|
459
|
+
removeDirectory(dir: string): Promise<{
|
|
460
|
+
ok: true;
|
|
461
|
+
root: string;
|
|
462
|
+
} | {
|
|
463
|
+
ok: false;
|
|
464
|
+
error: string;
|
|
465
|
+
}>;
|
|
420
466
|
/** Environment facts that vary per session rather than per host. */
|
|
421
467
|
private promptEnvironment;
|
|
422
468
|
/** Rebuild messages[0] from current plan-mode + approved-plan state. */
|
|
423
469
|
private rebuildSystemPromptInPlace;
|
|
470
|
+
/**
|
|
471
|
+
* Compose the system message: stable prefix, then everything volatile behind
|
|
472
|
+
* the `<!-- uncached -->` marker that providers split on for cache control.
|
|
473
|
+
*
|
|
474
|
+
* Anything that varies with the live model/provider/thinking level belongs in
|
|
475
|
+
* the tail. Putting it in the prefix means every model switch rewrites cached
|
|
476
|
+
* bytes and the next turn pays a full cache write instead of a read.
|
|
477
|
+
*/
|
|
424
478
|
private withSystemPromptTail;
|
|
479
|
+
/**
|
|
480
|
+
* Sol/Terra async-orchestration guidance for the CURRENT model and thinking
|
|
481
|
+
* level. Per-switch volatile by definition, so it is rendered as a tail part
|
|
482
|
+
* rather than spliced into the cached prefix.
|
|
483
|
+
*/
|
|
484
|
+
private orchestrationPolicyTail;
|
|
485
|
+
/**
|
|
486
|
+
* Re-render the uncached tail of messages[0] in place. The cached prefix is
|
|
487
|
+
* byte-identical afterwards, so this is safe to call on every model /
|
|
488
|
+
* thinking-level change.
|
|
489
|
+
*/
|
|
425
490
|
private refreshSystemPromptTail;
|
|
426
491
|
getMessages(): Message[];
|
|
427
492
|
getTurnMetrics(): TurnMetricPayload[];
|
|
@@ -481,6 +546,13 @@ export declare class AgentSession {
|
|
|
481
546
|
* No-op persistence for transient sessions.
|
|
482
547
|
*/
|
|
483
548
|
persistAppMarker(kind: AppMarkerPayload["kind"], data: Record<string, unknown>, anchorOffset?: number): Promise<void>;
|
|
549
|
+
/**
|
|
550
|
+
* Record what this compaction is about to discard as past-tense journal
|
|
551
|
+
* entries. Compaction is one-way — without this the specifics are gone for
|
|
552
|
+
* good, which is precisely the hole the journal exists to fill. No-op when
|
|
553
|
+
* memory is off, and bounded to a few entries so the file stays readable.
|
|
554
|
+
*/
|
|
555
|
+
private writeCompactionJournal;
|
|
484
556
|
/** Re-append the in-memory app markers to the current session file. Mirrors
|
|
485
557
|
* `rePersistKenTurns` — called after a continuation/compaction file is
|
|
486
558
|
* created so display-only rows survive the rewrite. */
|
|
@@ -498,8 +570,6 @@ export declare class AgentSession {
|
|
|
498
570
|
/** Set the reasoning/thinking level (undefined turns thinking off). Takes
|
|
499
571
|
* effect on the next prompt, since the in-flight loop reads it at start. */
|
|
500
572
|
setThinkingLevel(level: ThinkingLevel | undefined): void;
|
|
501
|
-
/** Sol/Terra Ultra delegates proactively; lower levels require an explicit request. */
|
|
502
|
-
private syncUltraOrchestrationPrompt;
|
|
503
573
|
/** Replace the abort signal (e.g. after cancellation). */
|
|
504
574
|
setSignal(signal: AbortSignal): void;
|
|
505
575
|
private bindManagerCancellation;
|