@kenkaiiii/ggcoder 4.3.196 → 4.3.198
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/cli.js +18 -4
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +28 -13
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts +2 -0
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +6 -1
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-registry.d.ts +12 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-registry.test.d.ts +2 -0
- package/dist/core/model-registry.test.d.ts.map +1 -0
- package/dist/core/model-registry.test.js +19 -0
- package/dist/core/model-registry.test.js.map +1 -0
- package/dist/core/session-compaction.d.ts +15 -0
- package/dist/core/session-compaction.d.ts.map +1 -0
- package/dist/core/session-compaction.js +31 -0
- package/dist/core/session-compaction.js.map +1 -0
- package/dist/core/session-compaction.test.d.ts +2 -0
- package/dist/core/session-compaction.test.d.ts.map +1 -0
- package/dist/core/session-compaction.test.js +70 -0
- package/dist/core/session-compaction.test.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +4 -2
- package/dist/interactive.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +69 -23
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +3 -1
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js +4 -4
- package/dist/ui/components/Footer.js.map +1 -1
- package/package.json +3 -3
package/dist/ui/App.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Box, Text, Static, useStdout } from "ink";
|
|
|
4
4
|
import { useTerminalSize } from "./hooks/useTerminalSize.js";
|
|
5
5
|
import { useDoublePress } from "./hooks/useDoublePress.js";
|
|
6
6
|
import { useTaskBarStore, useTaskBarPolling, focusTaskBar, exitTaskBar, expandTaskBar, collapseTaskBar, navigateTaskBar, killTask, } from "./stores/taskbar-store.js";
|
|
7
|
-
import
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
8
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { join } from "node:path";
|
|
@@ -40,6 +40,7 @@ import { useTerminalTitle } from "./hooks/useTerminalTitle.js";
|
|
|
40
40
|
import { getGitBranch } from "../utils/git.js";
|
|
41
41
|
import { getModel, getContextWindow, getMaxThinkingLevel } from "../core/model-registry.js";
|
|
42
42
|
import { SessionManager } from "../core/session-manager.js";
|
|
43
|
+
import { appendMessagesToSession as appendSessionMessages, createCompactedSessionCheckpoint, } from "../core/session-compaction.js";
|
|
43
44
|
import { log } from "../core/logger.js";
|
|
44
45
|
import { getPendingUpdate, startPeriodicUpdateCheck, stopPeriodicUpdateCheck, } from "../core/auto-update.js";
|
|
45
46
|
import { generateSessionTitle } from "../utils/session-title.js";
|
|
@@ -455,6 +456,7 @@ export function App(props) {
|
|
|
455
456
|
const activeApiKey = currentCreds?.accessToken ?? props.apiKey;
|
|
456
457
|
const activeAccountId = currentCreds?.accountId ?? props.accountId;
|
|
457
458
|
const activeBaseUrl = currentCreds?.baseUrl ?? props.baseUrl;
|
|
459
|
+
const contextWindowOptions = useMemo(() => ({ provider: currentProvider, accountId: activeAccountId }), [currentProvider, activeAccountId]);
|
|
458
460
|
// Load git branch — re-runs whenever the displayed cwd changes (e.g. when
|
|
459
461
|
// a pixel fix moves the agent into a different project root).
|
|
460
462
|
useEffect(() => {
|
|
@@ -639,27 +641,42 @@ export function App(props) {
|
|
|
639
641
|
};
|
|
640
642
|
}
|
|
641
643
|
}, [props.onExitPlanRef, replaceSystemPrompt, stdout]);
|
|
642
|
-
const
|
|
644
|
+
const appendMessagesToSession = useCallback(async (sessionPath, messages, startIndex) => {
|
|
645
|
+
const sm = sessionManagerRef.current;
|
|
646
|
+
if (!sm)
|
|
647
|
+
return;
|
|
648
|
+
await appendSessionMessages(sm, sessionPath, messages, startIndex);
|
|
649
|
+
}, []);
|
|
650
|
+
const persistCompactedSession = useCallback(async (compactedMessages) => {
|
|
643
651
|
const sm = sessionManagerRef.current;
|
|
652
|
+
if (!sm)
|
|
653
|
+
return;
|
|
654
|
+
const session = await createCompactedSessionCheckpoint(sm, {
|
|
655
|
+
cwd: cwdRef.current,
|
|
656
|
+
provider: currentProvider,
|
|
657
|
+
model: currentModel,
|
|
658
|
+
messages: compactedMessages,
|
|
659
|
+
});
|
|
660
|
+
sessionPathRef.current = session.path;
|
|
661
|
+
persistedIndexRef.current = compactedMessages.length;
|
|
662
|
+
if (sessionStore) {
|
|
663
|
+
sessionStore.sessionPath = session.path;
|
|
664
|
+
sessionStore.messages = [...compactedMessages];
|
|
665
|
+
}
|
|
666
|
+
log("INFO", "compaction", "Persisted compacted session checkpoint", { path: session.path });
|
|
667
|
+
}, [currentModel, currentProvider, sessionStore]);
|
|
668
|
+
const persistNewMessages = useCallback(async () => {
|
|
644
669
|
const sp = sessionPathRef.current;
|
|
645
|
-
if (!
|
|
670
|
+
if (!sp)
|
|
646
671
|
return;
|
|
647
672
|
const allMsgs = messagesRef.current;
|
|
648
|
-
|
|
649
|
-
const msg = allMsgs[i];
|
|
650
|
-
if (msg.role === "system")
|
|
651
|
-
continue;
|
|
652
|
-
const entry = {
|
|
653
|
-
type: "message",
|
|
654
|
-
id: crypto.randomUUID(),
|
|
655
|
-
parentId: null,
|
|
656
|
-
timestamp: new Date().toISOString(),
|
|
657
|
-
message: msg,
|
|
658
|
-
};
|
|
659
|
-
await sm.appendEntry(sp, entry);
|
|
660
|
-
}
|
|
673
|
+
await appendMessagesToSession(sp, allMsgs, persistedIndexRef.current);
|
|
661
674
|
persistedIndexRef.current = allMsgs.length;
|
|
662
|
-
|
|
675
|
+
if (sessionStore) {
|
|
676
|
+
sessionStore.messages = [...allMsgs];
|
|
677
|
+
sessionStore.sessionPath = sp;
|
|
678
|
+
}
|
|
679
|
+
}, [appendMessagesToSession, sessionStore]);
|
|
663
680
|
/**
|
|
664
681
|
* Run the language detector against the current cwd. If the detected set is a
|
|
665
682
|
* strict superset of what's already injected, rebuild the system prompt with
|
|
@@ -695,7 +712,7 @@ export function App(props) {
|
|
|
695
712
|
}
|
|
696
713
|
}, [props.settingsFile]);
|
|
697
714
|
const compactConversation = useCallback(async (messages) => {
|
|
698
|
-
const contextWindow = getContextWindow(currentModel);
|
|
715
|
+
const contextWindow = getContextWindow(currentModel, contextWindowOptions);
|
|
699
716
|
const tokensBefore = estimateConversationTokens(messages);
|
|
700
717
|
const spinId = getId();
|
|
701
718
|
log("INFO", "compaction", `Running compaction`, {
|
|
@@ -708,14 +725,20 @@ export function App(props) {
|
|
|
708
725
|
try {
|
|
709
726
|
// Resolve fresh credentials for compaction too
|
|
710
727
|
let compactApiKey = activeApiKey;
|
|
728
|
+
let compactAccountId = activeAccountId;
|
|
729
|
+
let compactBaseUrl = activeBaseUrl;
|
|
711
730
|
if (props.authStorage) {
|
|
712
731
|
const creds = await props.authStorage.resolveCredentials(currentProvider);
|
|
713
732
|
compactApiKey = creds.accessToken;
|
|
733
|
+
compactAccountId = creds.accountId;
|
|
734
|
+
compactBaseUrl = creds.baseUrl ?? compactBaseUrl;
|
|
714
735
|
}
|
|
715
736
|
const result = await compact(messages, {
|
|
716
737
|
provider: currentProvider,
|
|
717
738
|
model: currentModel,
|
|
718
739
|
apiKey: compactApiKey,
|
|
740
|
+
accountId: compactAccountId,
|
|
741
|
+
baseUrl: compactBaseUrl,
|
|
719
742
|
contextWindow,
|
|
720
743
|
signal: undefined,
|
|
721
744
|
approvedPlanPath: approvedPlanPathRef.current,
|
|
@@ -747,7 +770,15 @@ export function App(props) {
|
|
|
747
770
|
setLiveItems((prev) => prev.map((item) => item.id === spinId ? toErrorItem(err, spinId, "Compaction failed") : item));
|
|
748
771
|
return messages; // Return unchanged on failure
|
|
749
772
|
}
|
|
750
|
-
}, [
|
|
773
|
+
}, [
|
|
774
|
+
currentModel,
|
|
775
|
+
currentProvider,
|
|
776
|
+
activeApiKey,
|
|
777
|
+
activeAccountId,
|
|
778
|
+
activeBaseUrl,
|
|
779
|
+
contextWindowOptions,
|
|
780
|
+
props.authStorage,
|
|
781
|
+
]);
|
|
751
782
|
const getRepoMapSignalCount = useCallback(() => {
|
|
752
783
|
return ((props.repoMapChangedFilesRef?.current.size ?? 0) +
|
|
753
784
|
(props.repoMapReadFilesRef?.current.size ?? 0));
|
|
@@ -812,6 +843,10 @@ export function App(props) {
|
|
|
812
843
|
// Force-compact on context overflow regardless of settings
|
|
813
844
|
if (options?.force) {
|
|
814
845
|
const result = await compactConversation(stripped);
|
|
846
|
+
if (result !== stripped) {
|
|
847
|
+
messagesRef.current = result;
|
|
848
|
+
await persistCompactedSession(result);
|
|
849
|
+
}
|
|
815
850
|
lastCompactionTimeRef.current = Date.now();
|
|
816
851
|
return injectRepoMapContext(result);
|
|
817
852
|
}
|
|
@@ -822,18 +857,29 @@ export function App(props) {
|
|
|
822
857
|
log("INFO", "compaction", `Skipping compaction — cooldown active`);
|
|
823
858
|
return injectRepoMapContext(stripped);
|
|
824
859
|
}
|
|
825
|
-
const contextWindow = getContextWindow(currentModel);
|
|
860
|
+
const contextWindow = getContextWindow(currentModel, contextWindowOptions);
|
|
826
861
|
const modelInfo = getModel(currentModel);
|
|
827
862
|
const reserveTokens = (modelInfo?.maxOutputTokens ?? 0) + 5_000;
|
|
828
863
|
const tokensFresh = lastActualTokensTimestampRef.current > lastCompactionTimeRef.current;
|
|
829
864
|
const actualTokens = lastActualTokensRef.current > 0 && tokensFresh ? lastActualTokensRef.current : undefined;
|
|
830
865
|
if (shouldCompact(stripped, contextWindow, threshold, actualTokens, reserveTokens)) {
|
|
831
866
|
const result = await compactConversation(stripped);
|
|
867
|
+
if (result !== stripped) {
|
|
868
|
+
messagesRef.current = result;
|
|
869
|
+
await persistCompactedSession(result);
|
|
870
|
+
}
|
|
832
871
|
lastCompactionTimeRef.current = Date.now();
|
|
833
872
|
return injectRepoMapContext(result);
|
|
834
873
|
}
|
|
835
874
|
return injectRepoMapContext(stripped);
|
|
836
|
-
}, [
|
|
875
|
+
}, [
|
|
876
|
+
currentModel,
|
|
877
|
+
compactConversation,
|
|
878
|
+
contextWindowOptions,
|
|
879
|
+
injectRepoMapContext,
|
|
880
|
+
persistCompactedSession,
|
|
881
|
+
stripRepoMapMessages,
|
|
882
|
+
]);
|
|
837
883
|
// ── Background task bar state (external store) ──────────
|
|
838
884
|
const { bgTasks, focused: taskBarFocused, expanded: taskBarExpanded, selectedIndex: selectedTaskIndex, } = useTaskBarStore();
|
|
839
885
|
useTaskBarPolling(props.processManager);
|
|
@@ -1644,7 +1690,7 @@ export function App(props) {
|
|
|
1644
1690
|
const compacted = await compactConversation(messagesRef.current);
|
|
1645
1691
|
if (compacted !== messagesRef.current) {
|
|
1646
1692
|
messagesRef.current = compacted;
|
|
1647
|
-
|
|
1693
|
+
await persistCompactedSession(compacted);
|
|
1648
1694
|
}
|
|
1649
1695
|
return;
|
|
1650
1696
|
}
|
|
@@ -2709,7 +2755,7 @@ export function App(props) {
|
|
|
2709
2755
|
id: getId(),
|
|
2710
2756
|
},
|
|
2711
2757
|
]);
|
|
2712
|
-
}, cwd: props.cwd, commands: allCommands, eyesCount: eyesCount }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider })) : overlay === "theme" ? (_jsx(ThemeSelector, { onSelect: handleThemeSelect, onCancel: () => setOverlay(null), currentTheme: theme.name })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, cwd: displayedCwd, gitBranch: gitBranch, thinkingLevel: thinkingEnabled ? getMaxThinkingLevel(currentModel) : undefined, planMode: planMode, exitPending: exitPending })), (bgTasks.length > 0 || (eyesCount !== undefined && eyesCount > 0) || updatePending) && (_jsxs(Box, { children: [bgTasks.length > 0 && (_jsx(BackgroundTasksBar, { tasks: bgTasks, focused: taskBarFocused, expanded: taskBarExpanded, selectedIndex: selectedTaskIndex, onExpand: handleTaskBarExpand, onCollapse: handleTaskBarCollapse, onKill: handleTaskKill, onExit: handleTaskBarExit, onNavigate: handleTaskNavigate })), eyesCount !== undefined && eyesCount > 0 && (_jsx(Box, { paddingLeft: bgTasks.length > 0 ? 2 : 1, paddingRight: 1, children: _jsx(Text, { color: theme.accent, bold: true, children: `${eyesCount} eyes signal${eyesCount === 1 ? "" : "s"} · Run /eyes-improve to enhance GG Coder` }) })), updatePending && (_jsx(Box, { paddingLeft: bgTasks.length > 0 || (eyesCount !== undefined && eyesCount > 0) ? 2 : 1, paddingRight: 1, children: _jsx(Text, { color: theme.success, bold: true, children: "\u2728 Update ready \u00B7 restart to apply" }) }))] }))] }))] }));
|
|
2758
|
+
}, cwd: props.cwd, commands: allCommands, eyesCount: eyesCount }), overlay === "model" ? (_jsx(ModelSelector, { onSelect: handleModelSelect, onCancel: () => setOverlay(null), loggedInProviders: props.loggedInProviders ?? [currentProvider], currentModel: currentModel, currentProvider: currentProvider })) : overlay === "theme" ? (_jsx(ThemeSelector, { onSelect: handleThemeSelect, onCancel: () => setOverlay(null), currentTheme: theme.name })) : (_jsx(Footer, { model: currentModel, tokensIn: agentLoop.contextUsed, contextWindowOptions: contextWindowOptions, cwd: displayedCwd, gitBranch: gitBranch, thinkingLevel: thinkingEnabled ? getMaxThinkingLevel(currentModel) : undefined, planMode: planMode, exitPending: exitPending })), (bgTasks.length > 0 || (eyesCount !== undefined && eyesCount > 0) || updatePending) && (_jsxs(Box, { children: [bgTasks.length > 0 && (_jsx(BackgroundTasksBar, { tasks: bgTasks, focused: taskBarFocused, expanded: taskBarExpanded, selectedIndex: selectedTaskIndex, onExpand: handleTaskBarExpand, onCollapse: handleTaskBarCollapse, onKill: handleTaskKill, onExit: handleTaskBarExit, onNavigate: handleTaskNavigate })), eyesCount !== undefined && eyesCount > 0 && (_jsx(Box, { paddingLeft: bgTasks.length > 0 ? 2 : 1, paddingRight: 1, children: _jsx(Text, { color: theme.accent, bold: true, children: `${eyesCount} eyes signal${eyesCount === 1 ? "" : "s"} · Run /eyes-improve to enhance GG Coder` }) })), updatePending && (_jsx(Box, { paddingLeft: bgTasks.length > 0 || (eyesCount !== undefined && eyesCount > 0) ? 2 : 1, paddingRight: 1, children: _jsx(Text, { color: theme.success, bold: true, children: "\u2728 Update ready \u00B7 restart to apply" }) }))] }))] }))] }));
|
|
2713
2759
|
}
|
|
2714
2760
|
function formatRepoMapCommandOutput(enabled, markdown, refreshed) {
|
|
2715
2761
|
const status = enabled ? "on" : "off";
|