@kenkaiiii/ggcoder 5.13.3 → 5.15.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 +158 -48
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.d.ts +7 -0
- package/dist/chat-agents/general.d.ts.map +1 -0
- package/dist/chat-agents/general.js +16 -0
- package/dist/chat-agents/general.js.map +1 -0
- package/dist/chat-agents/general.test.d.ts +2 -0
- package/dist/chat-agents/general.test.d.ts.map +1 -0
- package/dist/chat-agents/general.test.js +47 -0
- package/dist/chat-agents/general.test.js.map +1 -0
- package/dist/chat-agents/index.d.ts +11 -0
- package/dist/chat-agents/index.d.ts.map +1 -0
- package/dist/chat-agents/index.js +89 -0
- package/dist/chat-agents/index.js.map +1 -0
- package/dist/chat-agents/memory.d.ts +53 -0
- package/dist/chat-agents/memory.d.ts.map +1 -0
- package/dist/chat-agents/memory.js +362 -0
- package/dist/chat-agents/memory.js.map +1 -0
- package/dist/chat-agents/memory.test.d.ts +2 -0
- package/dist/chat-agents/memory.test.d.ts.map +1 -0
- package/dist/chat-agents/memory.test.js +155 -0
- package/dist/chat-agents/memory.test.js.map +1 -0
- package/dist/chat-agents/research.d.ts +7 -0
- package/dist/chat-agents/research.d.ts.map +1 -0
- package/dist/chat-agents/research.js +18 -0
- package/dist/chat-agents/research.js.map +1 -0
- package/dist/chat-agents/shared.d.ts +11 -0
- package/dist/chat-agents/shared.d.ts.map +1 -0
- package/dist/chat-agents/shared.js +48 -0
- package/dist/chat-agents/shared.js.map +1 -0
- package/dist/chat-agents/specialists.test.d.ts +2 -0
- package/dist/chat-agents/specialists.test.d.ts.map +1 -0
- package/dist/chat-agents/specialists.test.js +97 -0
- package/dist/chat-agents/specialists.test.js.map +1 -0
- package/dist/chat-agents/therapist.d.ts +7 -0
- package/dist/chat-agents/therapist.d.ts.map +1 -0
- package/dist/chat-agents/therapist.js +20 -0
- package/dist/chat-agents/therapist.js.map +1 -0
- package/dist/chat-agents/types.d.ts +4 -0
- package/dist/chat-agents/types.d.ts.map +1 -0
- package/dist/chat-agents/types.js +7 -0
- package/dist/chat-agents/types.js.map +1 -0
- package/dist/core/agent-session-memory-tail.test.d.ts +2 -0
- package/dist/core/agent-session-memory-tail.test.d.ts.map +1 -0
- package/dist/core/agent-session-memory-tail.test.js +122 -0
- package/dist/core/agent-session-memory-tail.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +25 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +128 -65
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.d.ts +1 -1
- package/dist/core/agents.d.ts.map +1 -1
- package/dist/core/agents.js +4 -2
- package/dist/core/agents.js.map +1 -1
- package/dist/core/progress/rebuild.d.ts +3 -3
- package/dist/core/progress/rebuild.d.ts.map +1 -1
- package/dist/core/progress/rebuild.js +33 -27
- package/dist/core/progress/rebuild.js.map +1 -1
- package/dist/core/progress/rebuild.test.js +15 -0
- package/dist/core/progress/rebuild.test.js.map +1 -1
- package/dist/core/project-discovery.d.ts +1 -1
- package/dist/core/project-discovery.d.ts.map +1 -1
- package/dist/core/project-discovery.js +1 -2
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/project-discovery.test.js +14 -1
- package/dist/core/project-discovery.test.js.map +1 -1
- package/dist/core/session-manager.d.ts +1 -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/session-manager.test.js +18 -0
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +4 -0
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +5 -1
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/tools/generate-image.d.ts.map +1 -1
- package/dist/tools/generate-image.js +10 -3
- package/dist/tools/generate-image.js.map +1 -1
- package/dist/tools/generate-image.test.js +17 -0
- package/dist/tools/generate-image.test.js.map +1 -1
- package/dist/tools/web-fetch.d.ts +1 -0
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +112 -35
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-fetch.test.js +146 -1
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/tools/web-search.d.ts +10 -0
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +236 -28
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/web-search.test.js +77 -6
- package/dist/tools/web-search.test.js.map +1 -1
- package/package.json +4 -4
package/dist/app-sidecar.js
CHANGED
|
@@ -22,6 +22,8 @@ import { formatError } from "@kenkaiiii/gg-ai";
|
|
|
22
22
|
import { runJsonMode } from "./modes/json-mode.js";
|
|
23
23
|
import { runSubagentWorkerMode } from "./modes/subagent-worker-mode.js";
|
|
24
24
|
import { AgentSession } from "./core/agent-session.js";
|
|
25
|
+
import { CHAT_AGENT_IDS, chatAgentSessionsDir, createChatAgent, parseChatAgentId, sessionsDirForChatAgent, switchChatAgent, } from "./chat-agents/index.js";
|
|
26
|
+
import { buildMemoryTools, MemoryStore } from "./chat-agents/memory.js";
|
|
25
27
|
import { buildKenSystemPrompt, buildKenAutopilotSystemPrompt } from "./core/ken-prompt.js";
|
|
26
28
|
import { buildKenDigest, buildKenAutopilotContext, buildKenAutopilotPlanContext, } from "./core/ken-context.js";
|
|
27
29
|
import { parseAutopilotVerdict } from "./core/autopilot-verdict.js";
|
|
@@ -508,6 +510,13 @@ async function main() {
|
|
|
508
510
|
// request to its window's session via the `x-gg-session` header (and the
|
|
509
511
|
// `?session=` query for the SSE /events stream).
|
|
510
512
|
const sessions = new Map();
|
|
513
|
+
const memoryStore = new MemoryStore({
|
|
514
|
+
onChange: ({ memories }) => {
|
|
515
|
+
for (const ctx of sessions.values()) {
|
|
516
|
+
ctx.broadcast("memory_change", { count: memories.length });
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
});
|
|
511
520
|
// XP/rank progress — loaded once per daemon; awards fan out to every window.
|
|
512
521
|
// Each frame is tagged `origin: true` only for the session that earned the
|
|
513
522
|
// XP, so that window alone plays sounds/chips while the rest just re-render.
|
|
@@ -606,7 +615,7 @@ async function main() {
|
|
|
606
615
|
return;
|
|
607
616
|
}
|
|
608
617
|
// ── Daemon-level routes (session lifecycle) ──────────────────────────
|
|
609
|
-
// Create a session for a window: { cwd, sessionPath? } → { sessionId }.
|
|
618
|
+
// Create a session for a window: { mode?, cwd, sessionPath? } → { sessionId }.
|
|
610
619
|
if (method === "POST" && url === "/session") {
|
|
611
620
|
void daemonReadBody(req).then(async (raw) => {
|
|
612
621
|
let body = {};
|
|
@@ -616,15 +625,22 @@ async function main() {
|
|
|
616
625
|
catch {
|
|
617
626
|
/* empty/invalid body → defaults below */
|
|
618
627
|
}
|
|
628
|
+
const mode = body.mode === "chat" ? "chat" : "code";
|
|
629
|
+
const chatAgent = parseChatAgentId(body.chatAgent);
|
|
619
630
|
const sessionCwd = typeof body.cwd === "string" && body.cwd
|
|
620
631
|
? body.cwd
|
|
621
632
|
: (process.env.GG_APP_CWD ?? process.cwd());
|
|
622
633
|
const sessionPath = typeof body.sessionPath === "string" && body.sessionPath ? body.sessionPath : undefined;
|
|
623
634
|
const id = randomUUID();
|
|
624
635
|
try {
|
|
625
|
-
const ctx = await createSession({ auth, paths, progress }, { id, cwd: sessionCwd, sessionPath });
|
|
636
|
+
const ctx = await createSession({ auth, paths, progress, memoryStore }, { id, mode, chatAgent, cwd: sessionCwd, sessionPath });
|
|
626
637
|
sessions.set(id, ctx);
|
|
627
|
-
log("INFO", "app-sidecar", "session created", {
|
|
638
|
+
log("INFO", "app-sidecar", "session created", {
|
|
639
|
+
id,
|
|
640
|
+
mode,
|
|
641
|
+
chatAgent,
|
|
642
|
+
cwd: sessionCwd,
|
|
643
|
+
});
|
|
628
644
|
daemonJson(res, 200, { sessionId: id });
|
|
629
645
|
}
|
|
630
646
|
catch (err) {
|
|
@@ -775,8 +791,14 @@ function buildKenContext(buildSession, cwd, gitBranch, question, workflowCommand
|
|
|
775
791
|
});
|
|
776
792
|
}
|
|
777
793
|
async function createProgressManager(agentDir, broadcastAll) {
|
|
778
|
-
// Boot: recovery chain main → backup →
|
|
779
|
-
|
|
794
|
+
// Boot: recovery chain main → backup → coding + chat session rebuild → empty.
|
|
795
|
+
const coderSessionsDir = path.join(agentDir, "sessions");
|
|
796
|
+
let file = await loadProgress({
|
|
797
|
+
rebuild: () => rebuildFromSessions([
|
|
798
|
+
coderSessionsDir,
|
|
799
|
+
...CHAT_AGENT_IDS.map((agentId) => chatAgentSessionsDir(coderSessionsDir, agentId)),
|
|
800
|
+
]),
|
|
801
|
+
});
|
|
780
802
|
// Don't re-celebrate an old levelUp event on boot.
|
|
781
803
|
let lastSeenNonce = file.lastEvent?.nonce ?? null;
|
|
782
804
|
log("INFO", "app-sidecar", "progress loaded", {
|
|
@@ -864,8 +886,10 @@ async function createProgressManager(agentDir, broadcastAll) {
|
|
|
864
886
|
* logger, PATH, shared auth file, and radio live at the daemon level.
|
|
865
887
|
*/
|
|
866
888
|
async function createSession(deps, opts) {
|
|
867
|
-
const { auth, progress } = deps;
|
|
889
|
+
const { auth, progress, memoryStore } = deps;
|
|
868
890
|
const paths = deps.paths;
|
|
891
|
+
const mode = opts.mode;
|
|
892
|
+
let chatAgent = opts.chatAgent;
|
|
869
893
|
const cwd = opts.cwd;
|
|
870
894
|
// Base host for parsing request-URL query params (value is irrelevant to
|
|
871
895
|
// parsing); the daemon owns the real listen host.
|
|
@@ -968,51 +992,69 @@ async function createSession(deps, opts) {
|
|
|
968
992
|
// empty/unset starts a fresh session.
|
|
969
993
|
const resumeSessionPath = opts.sessionPath;
|
|
970
994
|
let abort = new AbortController();
|
|
971
|
-
const
|
|
995
|
+
const baseSessionOptions = {
|
|
972
996
|
provider,
|
|
973
997
|
model,
|
|
974
998
|
cwd,
|
|
975
999
|
thinkingLevel,
|
|
976
1000
|
sessionId: resumeSessionPath,
|
|
977
1001
|
signal: abort.signal,
|
|
978
|
-
//
|
|
979
|
-
// can't fire until initialize() resolves. Connect MCP in the background so a
|
|
980
|
-
// slow or hanging stdio server (e.g. a first-run `npx -y @playwright/mcp`
|
|
981
|
-
// download) can't delay the sidecar past the webview's startup timeout
|
|
982
|
-
// ("sidecar did not start in time"). Tools attach when the servers come up.
|
|
1002
|
+
// Keep MCP startup off the readiness path in both modes.
|
|
983
1003
|
backgroundMcpConnect: true,
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
//
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1004
|
+
};
|
|
1005
|
+
let session;
|
|
1006
|
+
if (mode === "chat") {
|
|
1007
|
+
session = createChatAgent(chatAgent, {
|
|
1008
|
+
...baseSessionOptions,
|
|
1009
|
+
sessionsDir: paths.sessionsDir,
|
|
1010
|
+
additionalTools: buildMemoryTools(memoryStore),
|
|
1011
|
+
getSystemPromptTail: () => memoryStore.renderForPrompt(),
|
|
1012
|
+
onAgentChange: async (nextAgent) => {
|
|
1013
|
+
chatAgent = nextAgent;
|
|
1014
|
+
broadcast("chat_agent_change", { chatAgent: nextAgent });
|
|
1015
|
+
await session.persistAppMarker("agent_handoff", { chatAgent: nextAgent }).catch((error) => {
|
|
1016
|
+
log("WARN", "app-sidecar", "agent handoff marker persist failed", {
|
|
1017
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1018
|
+
});
|
|
1019
|
+
});
|
|
1020
|
+
},
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
session = new AgentSession({
|
|
1025
|
+
...baseSessionOptions,
|
|
1026
|
+
// Plan mode belongs only to the coding agent.
|
|
1027
|
+
onEnterPlan: async (reason) => {
|
|
1028
|
+
await session.setPlanMode(true);
|
|
1029
|
+
broadcast("plan_enter", { reason: reason ?? "" });
|
|
1030
|
+
void session.persistAppMarker("plan", { reason: reason ?? "" }).catch(() => { });
|
|
1031
|
+
},
|
|
1032
|
+
onExitPlan: async (planPath) => {
|
|
1033
|
+
await session.setPlanMode(false);
|
|
1034
|
+
let content;
|
|
1035
|
+
try {
|
|
1036
|
+
content = await fs.readFile(planPath, "utf-8");
|
|
1037
|
+
}
|
|
1038
|
+
catch {
|
|
1039
|
+
content = "";
|
|
1040
|
+
}
|
|
1041
|
+
setPendingPlan(planPath, content);
|
|
1042
|
+
broadcast("plan_exit", { planPath, content });
|
|
1043
|
+
return "Plan submitted for user review. Wait for the user to approve, reject, or dismiss it before implementing.";
|
|
1044
|
+
},
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1014
1047
|
await session.initialize();
|
|
1015
|
-
|
|
1048
|
+
if (mode === "chat") {
|
|
1049
|
+
const restoredAgent = [...session.getAppMarkers()]
|
|
1050
|
+
.reverse()
|
|
1051
|
+
.find((marker) => marker.kind === "agent_handoff")?.data.chatAgent;
|
|
1052
|
+
if (typeof restoredAgent === "string") {
|
|
1053
|
+
chatAgent = parseChatAgentId(restoredAgent);
|
|
1054
|
+
await switchChatAgent(session, chatAgent, false);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
log("INFO", "app-sidecar", "session ready", { provider, model, mode, chatAgent, cwd });
|
|
1016
1058
|
// Footer extras (context window, git branch, background tasks). The git
|
|
1017
1059
|
// branch is resolved once at startup and refreshed lazily; the context
|
|
1018
1060
|
// window follows the active model.
|
|
@@ -1081,7 +1123,7 @@ async function createSession(deps, opts) {
|
|
|
1081
1123
|
// gg-app.json on boot; flipped via POST /autopilot. When on, POST /prompt runs
|
|
1082
1124
|
// runAutopilotCycle after the user's turn settles — Ken auto-reviews the work
|
|
1083
1125
|
// and drives the review→prompt→review loop.
|
|
1084
|
-
let autopilot = await loadAutopilot(cwd);
|
|
1126
|
+
let autopilot = mode === "code" && (await loadAutopilot(cwd));
|
|
1085
1127
|
// True while an autopilot review is in flight (used to defer kenAuto model
|
|
1086
1128
|
// switches, like kenRunning does for chat Ken, and to drive the spinner).
|
|
1087
1129
|
let autopilotReviewing = false;
|
|
@@ -1758,6 +1800,8 @@ async function createSession(deps, opts) {
|
|
|
1758
1800
|
const st = session.getState();
|
|
1759
1801
|
json(res, 200, {
|
|
1760
1802
|
...st,
|
|
1803
|
+
mode,
|
|
1804
|
+
chatAgent,
|
|
1761
1805
|
running,
|
|
1762
1806
|
ready: true,
|
|
1763
1807
|
thinkingLevel: session.getThinkingLevel() ?? null,
|
|
@@ -1773,6 +1817,26 @@ async function createSession(deps, opts) {
|
|
|
1773
1817
|
json(res, 200, progress.snapshot());
|
|
1774
1818
|
return;
|
|
1775
1819
|
}
|
|
1820
|
+
if (method === "GET" && url === "/memories") {
|
|
1821
|
+
void memoryStore
|
|
1822
|
+
.snapshot()
|
|
1823
|
+
.then((snapshot) => json(res, 200, snapshot))
|
|
1824
|
+
.catch((error) => json(res, 500, { error: error instanceof Error ? error.message : String(error) }));
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
if (method === "DELETE" && url.startsWith("/memories/")) {
|
|
1828
|
+
const id = decodeURIComponent(url.slice("/memories/".length));
|
|
1829
|
+
if (!id) {
|
|
1830
|
+
json(res, 400, { error: "memory id is required" });
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
void memoryStore
|
|
1834
|
+
.forget(id)
|
|
1835
|
+
.then(() => memoryStore.snapshot())
|
|
1836
|
+
.then((snapshot) => json(res, 200, snapshot))
|
|
1837
|
+
.catch((error) => json(res, 500, { error: error instanceof Error ? error.message : String(error) }));
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1776
1840
|
if (method === "GET" && (url === "/events" || url.startsWith("/events?"))) {
|
|
1777
1841
|
res.writeHead(200, {
|
|
1778
1842
|
"content-type": "text/event-stream",
|
|
@@ -1788,6 +1852,8 @@ async function createSession(deps, opts) {
|
|
|
1788
1852
|
type: "ready",
|
|
1789
1853
|
data: {
|
|
1790
1854
|
...st,
|
|
1855
|
+
mode,
|
|
1856
|
+
chatAgent,
|
|
1791
1857
|
running,
|
|
1792
1858
|
thinkingLevel: session.getThinkingLevel() ?? null,
|
|
1793
1859
|
supportedThinkingLevels: getSupportedThinkingLevels(st.provider, st.model),
|
|
@@ -1903,7 +1969,33 @@ async function createSession(deps, opts) {
|
|
|
1903
1969
|
json(res, 400, { error: "missing cwd query param" });
|
|
1904
1970
|
return;
|
|
1905
1971
|
}
|
|
1906
|
-
|
|
1972
|
+
const requestedAgent = new URL(url, `http://${host}`).searchParams.get("chatAgent");
|
|
1973
|
+
if (requestedAgent === "all") {
|
|
1974
|
+
void Promise.all(CHAT_AGENT_IDS.map(async (agentId) => {
|
|
1975
|
+
const agentSessions = await listRecentSessions(target, 5, chatAgentSessionsDir(paths.sessionsDir, agentId));
|
|
1976
|
+
return agentSessions.map((item) => ({ ...item, chatAgent: agentId }));
|
|
1977
|
+
}))
|
|
1978
|
+
.then(async (groups) => {
|
|
1979
|
+
const dated = await Promise.all(groups.flat().map(async (item) => ({
|
|
1980
|
+
item,
|
|
1981
|
+
mtime: await fs
|
|
1982
|
+
.stat(item.path)
|
|
1983
|
+
.then((stat) => stat.mtimeMs)
|
|
1984
|
+
.catch(() => 0),
|
|
1985
|
+
})));
|
|
1986
|
+
const recent = dated
|
|
1987
|
+
.sort((left, right) => right.mtime - left.mtime)
|
|
1988
|
+
.slice(0, 5)
|
|
1989
|
+
.map(({ item }) => item);
|
|
1990
|
+
json(res, 200, { sessions: recent });
|
|
1991
|
+
})
|
|
1992
|
+
.catch(() => json(res, 200, { sessions: [] }));
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
const sessionsDir = mode === "chat" || requestedAgent
|
|
1996
|
+
? sessionsDirForChatAgent(paths.sessionsDir, requestedAgent ?? chatAgent)
|
|
1997
|
+
: paths.sessionsDir;
|
|
1998
|
+
void listRecentSessions(target, 5, sessionsDir)
|
|
1907
1999
|
.then((sessions) => json(res, 200, { sessions }))
|
|
1908
2000
|
.catch(() => json(res, 200, { sessions: [] }));
|
|
1909
2001
|
return;
|
|
@@ -2210,9 +2302,12 @@ async function createSession(deps, opts) {
|
|
|
2210
2302
|
return;
|
|
2211
2303
|
}
|
|
2212
2304
|
if (method === "GET" && url === "/commands") {
|
|
2305
|
+
if (mode === "chat") {
|
|
2306
|
+
json(res, 200, { commands: [] });
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2213
2309
|
// Workflow commands with agent functionality: built-in prompt templates +
|
|
2214
|
-
// the user's own `.gg/commands/*.md`.
|
|
2215
|
-
// handled webview-side and intentionally excluded.
|
|
2310
|
+
// the user's own `.gg/commands/*.md`.
|
|
2216
2311
|
void (async () => {
|
|
2217
2312
|
const builtins = PROMPT_COMMANDS.map((c) => ({
|
|
2218
2313
|
name: c.name,
|
|
@@ -2350,6 +2445,10 @@ async function createSession(deps, opts) {
|
|
|
2350
2445
|
// webview keeps the bubbles separate. The context digest is assembled fresh
|
|
2351
2446
|
// from the BUILD session's transcript each turn (one-way mirror).
|
|
2352
2447
|
if (method === "POST" && url === "/ken/prompt") {
|
|
2448
|
+
if (mode === "chat") {
|
|
2449
|
+
json(res, 404, { error: "Ken is not available in GG Chat." });
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2353
2452
|
void readBody(req).then(async (raw) => {
|
|
2354
2453
|
let text;
|
|
2355
2454
|
try {
|
|
@@ -2405,6 +2504,10 @@ async function createSession(deps, opts) {
|
|
|
2405
2504
|
return;
|
|
2406
2505
|
}
|
|
2407
2506
|
if (method === "POST" && url === "/autopilot") {
|
|
2507
|
+
if (mode === "chat") {
|
|
2508
|
+
json(res, 404, { error: "Autopilot is not available in GG Chat." });
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2408
2511
|
void readBody(req).then(async (raw) => {
|
|
2409
2512
|
let enabled;
|
|
2410
2513
|
try {
|
|
@@ -2761,7 +2864,10 @@ async function createSession(deps, opts) {
|
|
|
2761
2864
|
}
|
|
2762
2865
|
void session
|
|
2763
2866
|
.newSession()
|
|
2764
|
-
.then(() => {
|
|
2867
|
+
.then(async () => {
|
|
2868
|
+
if (mode === "chat") {
|
|
2869
|
+
await session.persistAppMarker("agent_handoff", { chatAgent });
|
|
2870
|
+
}
|
|
2765
2871
|
injectedAutopilotPrompts = [];
|
|
2766
2872
|
clearPendingPlan();
|
|
2767
2873
|
broadcast("session_reset", {});
|
|
@@ -3260,6 +3366,10 @@ async function createSession(deps, opts) {
|
|
|
3260
3366
|
}
|
|
3261
3367
|
return {
|
|
3262
3368
|
id: opts.id,
|
|
3369
|
+
mode,
|
|
3370
|
+
get chatAgent() {
|
|
3371
|
+
return chatAgent;
|
|
3372
|
+
},
|
|
3263
3373
|
cwd,
|
|
3264
3374
|
sessionPath: opts.sessionPath,
|
|
3265
3375
|
session,
|