This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

summarize via llm during compacts

+44 -1
+44 -1
src/runner/loop.ts
··· 15 15 import type { LoopHooks, LoopState } from "./types.js" 16 16 import { 17 17 API_BASE, 18 + CONTEXT_COMPACT_TRIGGER_TOKENS, 18 19 FALLBACK_MODEL, 19 20 FALLBACK_TOOL_CHOICE, 20 21 FALLBACK_TOKEN_NUDGE_THRESHOLD, ··· 36 37 shouldFallback, 37 38 summarizeConversationViaLLM, 38 39 } from "./util.js" 40 + 41 + const LLM_POST_TURN_RECENT_MESSAGES = 40 39 42 40 43 type FunctionToolCall = OpenAI.Chat.ChatCompletionMessageToolCall & { type: "function" } 41 44 type ToolArgs = { ··· 936 939 } 937 940 938 941 /** 942 + * Post-turn compaction: when observed context crosses the compaction trigger, 943 + * replace the middle of the conversation with a single LLM-generated summary so 944 + * older history keeps its narrative/emotional texture instead of being reduced 945 + * to bullet lines. Falls back to the heuristic compactor on failure. 946 + */ 947 + async function applyPostTurnCompaction(state: LoopState): Promise<boolean> { 948 + if (state.contextSize >= CONTEXT_COMPACT_TRIGGER_TOKENS) { 949 + const summaryClient = USE_FALLBACK ? fallbackClient : client 950 + const summaryModel = USE_FALLBACK ? FALLBACK_MODEL : MODEL 951 + if (summaryClient && summaryModel) { 952 + const beforeCount = state.conversation.length 953 + const beforeEstimate = estimatePromptTokens(state.conversation) 954 + const summarized = await summarizeConversationViaLLM( 955 + state.conversation, 956 + summaryClient, 957 + summaryModel, 958 + { recentKeep: LLM_POST_TURN_RECENT_MESSAGES }, 959 + ) 960 + if (summarized) { 961 + const afterEstimate = estimatePromptTokens(summarized) 962 + if (afterEstimate < beforeEstimate) { 963 + state.conversation = summarized 964 + state.contextSize = afterEstimate 965 + console.log( 966 + `[context] post-turn llm-summarized (${beforeCount} -> ${summarized.length} msgs, ${beforeEstimate} -> ${afterEstimate})`, 967 + ) 968 + return true 969 + } 970 + console.warn( 971 + `[context] post-turn llm summary not smaller (${beforeEstimate} -> ${afterEstimate}); falling back to heuristic`, 972 + ) 973 + } else { 974 + console.warn(`[context] post-turn llm summary unavailable; falling back to heuristic`) 975 + } 976 + } 977 + } 978 + return applyRollingCompaction(state, "post-turn") 979 + } 980 + 981 + /** 939 982 * Executes the main assistant/tool loop for an active conversation. 940 983 * 941 984 * The loop repeatedly: ··· 957 1000 const outcome = await processAssistantTurn(convId, state, hooks) 958 1001 if (outcome === CycleOutcome.Rest) break 959 1002 960 - applyRollingCompaction(state, "post-turn") 1003 + await applyPostTurnCompaction(state) 961 1004 if (outcome !== CycleOutcome.NoTools) { 962 1005 applyContextNudge(state) 963 1006 }