@nervekit/agent 0.1.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/LICENSE +201 -0
- package/NOTICE +5 -0
- package/dist/agent-loop.d.ts +2 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +2 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent.d.ts +125 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +427 -0
- package/dist/agent.js.map +1 -0
- package/dist/harness/agent-harness.d.ts +114 -0
- package/dist/harness/agent-harness.d.ts.map +1 -0
- package/dist/harness/agent-harness.js +474 -0
- package/dist/harness/agent-harness.js.map +1 -0
- package/dist/harness/compaction/branch-summarization.d.ts +54 -0
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/harness/compaction/branch-summarization.js +183 -0
- package/dist/harness/compaction/branch-summarization.js.map +1 -0
- package/dist/harness/compaction/compaction.d.ts +19 -0
- package/dist/harness/compaction/compaction.d.ts.map +1 -0
- package/dist/harness/compaction/compaction.js +335 -0
- package/dist/harness/compaction/compaction.js.map +1 -0
- package/dist/harness/compaction/cut-points.d.ts +7 -0
- package/dist/harness/compaction/cut-points.d.ts.map +1 -0
- package/dist/harness/compaction/cut-points.js +106 -0
- package/dist/harness/compaction/cut-points.js.map +1 -0
- package/dist/harness/compaction/overflow.d.ts +3 -0
- package/dist/harness/compaction/overflow.d.ts.map +1 -0
- package/dist/harness/compaction/overflow.js +54 -0
- package/dist/harness/compaction/overflow.js.map +1 -0
- package/dist/harness/compaction/policy.d.ts +8 -0
- package/dist/harness/compaction/policy.d.ts.map +1 -0
- package/dist/harness/compaction/policy.js +57 -0
- package/dist/harness/compaction/policy.js.map +1 -0
- package/dist/harness/compaction/types.d.ts +79 -0
- package/dist/harness/compaction/types.d.ts.map +1 -0
- package/dist/harness/compaction/types.js +2 -0
- package/dist/harness/compaction/types.js.map +1 -0
- package/dist/harness/compaction/usage.d.ts +30 -0
- package/dist/harness/compaction/usage.d.ts.map +1 -0
- package/dist/harness/compaction/usage.js +177 -0
- package/dist/harness/compaction/usage.js.map +1 -0
- package/dist/harness/compaction/utils.d.ts +25 -0
- package/dist/harness/compaction/utils.d.ts.map +1 -0
- package/dist/harness/compaction/utils.js +131 -0
- package/dist/harness/compaction/utils.js.map +1 -0
- package/dist/harness/configuration.d.ts +34 -0
- package/dist/harness/configuration.d.ts.map +1 -0
- package/dist/harness/configuration.js +75 -0
- package/dist/harness/configuration.js.map +1 -0
- package/dist/harness/conversation/context.d.ts +24 -0
- package/dist/harness/conversation/context.d.ts.map +1 -0
- package/dist/harness/conversation/context.js +76 -0
- package/dist/harness/conversation/context.js.map +1 -0
- package/dist/harness/conversation/conversation.d.ts +36 -0
- package/dist/harness/conversation/conversation.d.ts.map +1 -0
- package/dist/harness/conversation/conversation.js +163 -0
- package/dist/harness/conversation/conversation.js.map +1 -0
- package/dist/harness/conversation/entries.d.ts +117 -0
- package/dist/harness/conversation/entries.d.ts.map +1 -0
- package/dist/harness/conversation/entries.js +2 -0
- package/dist/harness/conversation/entries.js.map +1 -0
- package/dist/harness/conversation/jsonl-repo.d.ts +27 -0
- package/dist/harness/conversation/jsonl-repo.d.ts.map +1 -0
- package/dist/harness/conversation/jsonl-repo.js +110 -0
- package/dist/harness/conversation/jsonl-repo.js.map +1 -0
- package/dist/harness/conversation/jsonl-storage.d.ts +34 -0
- package/dist/harness/conversation/jsonl-storage.d.ts.map +1 -0
- package/dist/harness/conversation/jsonl-storage.js +213 -0
- package/dist/harness/conversation/jsonl-storage.js.map +1 -0
- package/dist/harness/conversation/memory-repo.d.ts +18 -0
- package/dist/harness/conversation/memory-repo.d.ts.map +1 -0
- package/dist/harness/conversation/memory-repo.js +45 -0
- package/dist/harness/conversation/memory-repo.js.map +1 -0
- package/dist/harness/conversation/memory-storage.d.ts +25 -0
- package/dist/harness/conversation/memory-storage.d.ts.map +1 -0
- package/dist/harness/conversation/memory-storage.js +88 -0
- package/dist/harness/conversation/memory-storage.js.map +1 -0
- package/dist/harness/conversation/repo-utils.d.ts +13 -0
- package/dist/harness/conversation/repo-utils.d.ts.map +1 -0
- package/dist/harness/conversation/repo-utils.js +39 -0
- package/dist/harness/conversation/repo-utils.js.map +1 -0
- package/dist/harness/conversation/storage-utils.d.ts +11 -0
- package/dist/harness/conversation/storage-utils.d.ts.map +1 -0
- package/dist/harness/conversation/storage-utils.js +32 -0
- package/dist/harness/conversation/storage-utils.js.map +1 -0
- package/dist/harness/conversation/text-extraction.d.ts +8 -0
- package/dist/harness/conversation/text-extraction.d.ts.map +1 -0
- package/dist/harness/conversation/text-extraction.js +24 -0
- package/dist/harness/conversation/text-extraction.js.map +1 -0
- package/dist/harness/conversation/uuid.d.ts +2 -0
- package/dist/harness/conversation/uuid.d.ts.map +1 -0
- package/dist/harness/conversation/uuid.js +54 -0
- package/dist/harness/conversation/uuid.js.map +1 -0
- package/dist/harness/conversation-writes.d.ts +9 -0
- package/dist/harness/conversation-writes.d.ts.map +1 -0
- package/dist/harness/conversation-writes.js +54 -0
- package/dist/harness/conversation-writes.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +53 -0
- package/dist/harness/env/nodejs.d.ts.map +1 -0
- package/dist/harness/env/nodejs.js +497 -0
- package/dist/harness/env/nodejs.js.map +1 -0
- package/dist/harness/env/types.d.ts +106 -0
- package/dist/harness/env/types.d.ts.map +1 -0
- package/dist/harness/env/types.js +2 -0
- package/dist/harness/env/types.js.map +1 -0
- package/dist/harness/errors.d.ts +48 -0
- package/dist/harness/errors.d.ts.map +1 -0
- package/dist/harness/errors.js +63 -0
- package/dist/harness/errors.js.map +1 -0
- package/dist/harness/events.d.ts +238 -0
- package/dist/harness/events.d.ts.map +1 -0
- package/dist/harness/events.js +2 -0
- package/dist/harness/events.js.map +1 -0
- package/dist/harness/harness-configuration-methods.d.ts +36 -0
- package/dist/harness/harness-configuration-methods.d.ts.map +1 -0
- package/dist/harness/harness-configuration-methods.js +145 -0
- package/dist/harness/harness-configuration-methods.js.map +1 -0
- package/dist/harness/harness-continuation.d.ts +18 -0
- package/dist/harness/harness-continuation.d.ts.map +1 -0
- package/dist/harness/harness-continuation.js +56 -0
- package/dist/harness/harness-continuation.js.map +1 -0
- package/dist/harness/harness-events.d.ts +23 -0
- package/dist/harness/harness-events.d.ts.map +1 -0
- package/dist/harness/harness-events.js +129 -0
- package/dist/harness/harness-events.js.map +1 -0
- package/dist/harness/harness-invocations.d.ts +20 -0
- package/dist/harness/harness-invocations.d.ts.map +1 -0
- package/dist/harness/harness-invocations.js +22 -0
- package/dist/harness/harness-invocations.js.map +1 -0
- package/dist/harness/harness-maintenance.d.ts +30 -0
- package/dist/harness/harness-maintenance.d.ts.map +1 -0
- package/dist/harness/harness-maintenance.js +155 -0
- package/dist/harness/harness-maintenance.js.map +1 -0
- package/dist/harness/harness-queue-methods.d.ts +45 -0
- package/dist/harness/harness-queue-methods.d.ts.map +1 -0
- package/dist/harness/harness-queue-methods.js +51 -0
- package/dist/harness/harness-queue-methods.js.map +1 -0
- package/dist/harness/messages.d.ts +76 -0
- package/dist/harness/messages.d.ts.map +1 -0
- package/dist/harness/messages.js +147 -0
- package/dist/harness/messages.js.map +1 -0
- package/dist/harness/options.d.ts +95 -0
- package/dist/harness/options.d.ts.map +1 -0
- package/dist/harness/options.js +2 -0
- package/dist/harness/options.js.map +1 -0
- package/dist/harness/prompt-templates.d.ts +49 -0
- package/dist/harness/prompt-templates.d.ts.map +1 -0
- package/dist/harness/prompt-templates.js +230 -0
- package/dist/harness/prompt-templates.js.map +1 -0
- package/dist/harness/result.d.ts +19 -0
- package/dist/harness/result.d.ts.map +1 -0
- package/dist/harness/result.js +32 -0
- package/dist/harness/result.js.map +1 -0
- package/dist/harness/run/messages.d.ts +5 -0
- package/dist/harness/run/messages.d.ts.map +1 -0
- package/dist/harness/run/messages.js +37 -0
- package/dist/harness/run/messages.js.map +1 -0
- package/dist/harness/skills/format.d.ts +6 -0
- package/dist/harness/skills/format.d.ts.map +1 -0
- package/dist/harness/skills/format.js +38 -0
- package/dist/harness/skills/format.js.map +1 -0
- package/dist/harness/skills/index.d.ts +5 -0
- package/dist/harness/skills/index.d.ts.map +1 -0
- package/dist/harness/skills/index.js +5 -0
- package/dist/harness/skills/index.js.map +1 -0
- package/dist/harness/skills/loader.d.ts +43 -0
- package/dist/harness/skills/loader.d.ts.map +1 -0
- package/dist/harness/skills/loader.js +279 -0
- package/dist/harness/skills/loader.js.map +1 -0
- package/dist/harness/skills/parser.d.ts +12 -0
- package/dist/harness/skills/parser.d.ts.map +1 -0
- package/dist/harness/skills/parser.js +22 -0
- package/dist/harness/skills/parser.js.map +1 -0
- package/dist/harness/skills/validation.d.ts +3 -0
- package/dist/harness/skills/validation.d.ts.map +1 -0
- package/dist/harness/skills/validation.js +28 -0
- package/dist/harness/skills/validation.js.map +1 -0
- package/dist/harness/skills.d.ts +2 -0
- package/dist/harness/skills.d.ts.map +1 -0
- package/dist/harness/skills.js +2 -0
- package/dist/harness/skills.js.map +1 -0
- package/dist/harness/stream-options.d.ts +5 -0
- package/dist/harness/stream-options.d.ts.map +1 -0
- package/dist/harness/stream-options.js +67 -0
- package/dist/harness/stream-options.js.map +1 -0
- package/dist/harness/system-prompt.d.ts +2 -0
- package/dist/harness/system-prompt.d.ts.map +1 -0
- package/dist/harness/system-prompt.js +2 -0
- package/dist/harness/system-prompt.js.map +1 -0
- package/dist/harness/turn-state.d.ts +27 -0
- package/dist/harness/turn-state.d.ts.map +1 -0
- package/dist/harness/turn-state.js +35 -0
- package/dist/harness/turn-state.js.map +1 -0
- package/dist/harness/types.d.ts +9 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +8 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/harness/utils/env-path.d.ts +14 -0
- package/dist/harness/utils/env-path.d.ts.map +1 -0
- package/dist/harness/utils/env-path.js +99 -0
- package/dist/harness/utils/env-path.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +16 -0
- package/dist/harness/utils/shell-output.d.ts.map +1 -0
- package/dist/harness/utils/shell-output.js +137 -0
- package/dist/harness/utils/shell-output.js.map +1 -0
- package/dist/harness/utils/truncate.d.ts +70 -0
- package/dist/harness/utils/truncate.d.ts.map +1 -0
- package/dist/harness/utils/truncate.js +289 -0
- package/dist/harness/utils/truncate.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +3 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +3 -0
- package/dist/node.js.map +1 -0
- package/dist/proxy.d.ts +67 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +299 -0
- package/dist/proxy.js.map +1 -0
- package/dist/runtime/loop/agent-loop.d.ts +24 -0
- package/dist/runtime/loop/agent-loop.d.ts.map +1 -0
- package/dist/runtime/loop/agent-loop.js +72 -0
- package/dist/runtime/loop/agent-loop.js.map +1 -0
- package/dist/runtime/loop/events.d.ts +5 -0
- package/dist/runtime/loop/events.d.ts.map +1 -0
- package/dist/runtime/loop/events.js +5 -0
- package/dist/runtime/loop/events.js.map +1 -0
- package/dist/runtime/loop/index.d.ts +6 -0
- package/dist/runtime/loop/index.d.ts.map +1 -0
- package/dist/runtime/loop/index.js +6 -0
- package/dist/runtime/loop/index.js.map +1 -0
- package/dist/runtime/loop/stream-assistant.d.ts +9 -0
- package/dist/runtime/loop/stream-assistant.d.ts.map +1 -0
- package/dist/runtime/loop/stream-assistant.js +87 -0
- package/dist/runtime/loop/stream-assistant.js.map +1 -0
- package/dist/runtime/loop/tool-execution.d.ts +15 -0
- package/dist/runtime/loop/tool-execution.d.ts.map +1 -0
- package/dist/runtime/loop/tool-execution.js +271 -0
- package/dist/runtime/loop/tool-execution.js.map +1 -0
- package/dist/runtime/loop/turn-loop.d.ts +7 -0
- package/dist/runtime/loop/turn-loop.d.ts.map +1 -0
- package/dist/runtime/loop/turn-loop.js +84 -0
- package/dist/runtime/loop/turn-loop.js.map +1 -0
- package/dist/runtime.d.ts +63 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +170 -0
- package/dist/runtime.js.map +1 -0
- package/dist/suspension.d.ts +18 -0
- package/dist/suspension.d.ts.map +1 -0
- package/dist/suspension.js +19 -0
- package/dist/suspension.js.map +1 -0
- package/dist/types.d.ts +395 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +88 -0
- package/dist/worker.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { completeSimple } from "@earendil-works/pi-ai";
|
|
2
|
+
import { BranchSummaryError, ConversationError } from "../errors.js";
|
|
3
|
+
import { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "../messages.js";
|
|
4
|
+
import { err, ok } from "../result.js";
|
|
5
|
+
import { estimateTokens, SUMMARIZATION_SYSTEM_PROMPT } from "./compaction.js";
|
|
6
|
+
import { computeFileLists, createFileOps, extractFileOpsFromMessage, formatFileOperations, serializeConversation, } from "./utils.js";
|
|
7
|
+
/** Collect entries that should be summarized before navigating to a different conversation tree entry. */
|
|
8
|
+
export async function collectEntriesForBranchSummary(conversation, oldLeafId, targetId) {
|
|
9
|
+
if (!oldLeafId) {
|
|
10
|
+
return { entries: [], commonAncestorId: null };
|
|
11
|
+
}
|
|
12
|
+
const oldPath = new Set((await conversation.getBranch(oldLeafId)).map((e) => e.id));
|
|
13
|
+
const targetPath = await conversation.getBranch(targetId);
|
|
14
|
+
let commonAncestorId = null;
|
|
15
|
+
for (let i = targetPath.length - 1; i >= 0; i--) {
|
|
16
|
+
if (oldPath.has(targetPath[i].id)) {
|
|
17
|
+
commonAncestorId = targetPath[i].id;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const entries = [];
|
|
22
|
+
let current = oldLeafId;
|
|
23
|
+
while (current && current !== commonAncestorId) {
|
|
24
|
+
const entry = await conversation.getEntry(current);
|
|
25
|
+
if (!entry)
|
|
26
|
+
throw new ConversationError("invalid_conversation", `Entry ${current} not found`);
|
|
27
|
+
entries.push(entry);
|
|
28
|
+
current = entry.parentId;
|
|
29
|
+
}
|
|
30
|
+
entries.reverse();
|
|
31
|
+
return { entries, commonAncestorId };
|
|
32
|
+
}
|
|
33
|
+
function getMessageFromEntry(entry) {
|
|
34
|
+
switch (entry.type) {
|
|
35
|
+
case "message":
|
|
36
|
+
if (entry.message.role === "toolResult")
|
|
37
|
+
return undefined;
|
|
38
|
+
return entry.message;
|
|
39
|
+
case "custom_message":
|
|
40
|
+
return createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);
|
|
41
|
+
case "branch_summary":
|
|
42
|
+
return createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);
|
|
43
|
+
case "compaction":
|
|
44
|
+
return createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);
|
|
45
|
+
case "thinking_level_change":
|
|
46
|
+
case "model_change":
|
|
47
|
+
case "active_tools_change":
|
|
48
|
+
case "custom":
|
|
49
|
+
case "label":
|
|
50
|
+
case "conversation_info":
|
|
51
|
+
case "leaf":
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Prepare branch entries for summarization within an optional token budget. */
|
|
56
|
+
export function prepareBranchEntries(entries, tokenBudget = 0) {
|
|
57
|
+
const messages = [];
|
|
58
|
+
const fileOps = createFileOps();
|
|
59
|
+
let totalTokens = 0;
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
if (entry.type === "branch_summary" && !entry.fromHook && entry.details) {
|
|
62
|
+
const details = entry.details;
|
|
63
|
+
if (Array.isArray(details.readFiles)) {
|
|
64
|
+
for (const f of details.readFiles)
|
|
65
|
+
fileOps.read.add(f);
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(details.modifiedFiles)) {
|
|
68
|
+
for (const f of details.modifiedFiles) {
|
|
69
|
+
fileOps.edited.add(f);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
75
|
+
const entry = entries[i];
|
|
76
|
+
const message = getMessageFromEntry(entry);
|
|
77
|
+
if (!message)
|
|
78
|
+
continue;
|
|
79
|
+
extractFileOpsFromMessage(message, fileOps);
|
|
80
|
+
const tokens = estimateTokens(message);
|
|
81
|
+
if (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {
|
|
82
|
+
if (entry.type === "compaction" || entry.type === "branch_summary") {
|
|
83
|
+
if (totalTokens < tokenBudget * 0.9) {
|
|
84
|
+
messages.unshift(message);
|
|
85
|
+
totalTokens += tokens;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
messages.unshift(message);
|
|
91
|
+
totalTokens += tokens;
|
|
92
|
+
}
|
|
93
|
+
return { messages, fileOps, totalTokens };
|
|
94
|
+
}
|
|
95
|
+
const BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.
|
|
96
|
+
Summary of that exploration:
|
|
97
|
+
|
|
98
|
+
`;
|
|
99
|
+
const BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.
|
|
100
|
+
|
|
101
|
+
Use this EXACT format:
|
|
102
|
+
|
|
103
|
+
## Goal
|
|
104
|
+
[What was the user trying to accomplish in this branch?]
|
|
105
|
+
|
|
106
|
+
## Constraints & Preferences
|
|
107
|
+
- [Any constraints, preferences, or requirements mentioned]
|
|
108
|
+
- [Or "(none)" if none were mentioned]
|
|
109
|
+
|
|
110
|
+
## Progress
|
|
111
|
+
### Done
|
|
112
|
+
- [x] [Completed tasks/changes]
|
|
113
|
+
|
|
114
|
+
### In Progress
|
|
115
|
+
- [ ] [Work that was started but not finished]
|
|
116
|
+
|
|
117
|
+
### Blocked
|
|
118
|
+
- [Issues preventing progress, if any]
|
|
119
|
+
|
|
120
|
+
## Key Decisions
|
|
121
|
+
- **[Decision]**: [Brief rationale]
|
|
122
|
+
|
|
123
|
+
## Next Steps
|
|
124
|
+
1. [What should happen next to continue this work]
|
|
125
|
+
|
|
126
|
+
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
|
|
127
|
+
/** Generate a summary for abandoned branch entries. */
|
|
128
|
+
export async function generateBranchSummary(entries, options) {
|
|
129
|
+
const { model, apiKey, headers, signal, customInstructions, replaceInstructions, reserveTokens = 16384, } = options;
|
|
130
|
+
const contextWindow = model.contextWindow || 128000;
|
|
131
|
+
const tokenBudget = contextWindow - reserveTokens;
|
|
132
|
+
const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);
|
|
133
|
+
if (messages.length === 0) {
|
|
134
|
+
return ok({
|
|
135
|
+
summary: "No content to summarize",
|
|
136
|
+
readFiles: [],
|
|
137
|
+
modifiedFiles: [],
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const llmMessages = convertToLlm(messages);
|
|
141
|
+
const conversationText = serializeConversation(llmMessages);
|
|
142
|
+
let instructions;
|
|
143
|
+
if (replaceInstructions && customInstructions) {
|
|
144
|
+
instructions = customInstructions;
|
|
145
|
+
}
|
|
146
|
+
else if (customInstructions) {
|
|
147
|
+
instructions = `${BRANCH_SUMMARY_PROMPT}\n\nAdditional focus: ${customInstructions}`;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
instructions = BRANCH_SUMMARY_PROMPT;
|
|
151
|
+
}
|
|
152
|
+
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${instructions}`;
|
|
153
|
+
const summarizationMessages = [
|
|
154
|
+
{
|
|
155
|
+
role: "user",
|
|
156
|
+
content: [{ type: "text", text: promptText }],
|
|
157
|
+
timestamp: Date.now(),
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
const response = await completeSimple(model, {
|
|
161
|
+
systemPrompt: SUMMARIZATION_SYSTEM_PROMPT,
|
|
162
|
+
messages: summarizationMessages,
|
|
163
|
+
}, { apiKey, headers, signal, maxTokens: 2048 });
|
|
164
|
+
if (response.stopReason === "aborted") {
|
|
165
|
+
return err(new BranchSummaryError("aborted", response.errorMessage || "Branch summary aborted"));
|
|
166
|
+
}
|
|
167
|
+
if (response.stopReason === "error") {
|
|
168
|
+
return err(new BranchSummaryError("summarization_failed", `Branch summary failed: ${response.errorMessage || "Unknown error"}`));
|
|
169
|
+
}
|
|
170
|
+
let summary = response.content
|
|
171
|
+
.filter((c) => c.type === "text")
|
|
172
|
+
.map((c) => c.text)
|
|
173
|
+
.join("\n");
|
|
174
|
+
summary = BRANCH_SUMMARY_PREAMBLE + summary;
|
|
175
|
+
const { readFiles, modifiedFiles } = computeFileLists(fileOps);
|
|
176
|
+
summary += formatFileOperations(readFiles, modifiedFiles);
|
|
177
|
+
return ok({
|
|
178
|
+
summary: summary || "No summary generated",
|
|
179
|
+
readFiles,
|
|
180
|
+
modifiedFiles,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=branch-summarization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../../src/harness/compaction/branch-summarization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AgentMessage, AnyModel, ThinkingLevel } from "../../types.js";
|
|
2
|
+
import type { ConversationTreeEntry } from "../conversation/entries.js";
|
|
3
|
+
import { CompactionError } from "../errors.js";
|
|
4
|
+
import { type Result } from "../result.js";
|
|
5
|
+
import type { CompactionPreparation, CompactionResult, CompactionSettings } from "./types.js";
|
|
6
|
+
export { findCutPoint, findTurnStartIndex } from "./cut-points.js";
|
|
7
|
+
export { isContextOverflowAssistantMessage } from "./overflow.js";
|
|
8
|
+
export { DEFAULT_COMPACTION_SETTINGS, deriveAutoCompactionPolicy, shouldAutoCompact, shouldCompact, } from "./policy.js";
|
|
9
|
+
export type { AutoCompactionPolicy, AutoCompactionReason, CompactionDetails, CompactionPreparation, CompactionResult, CompactionSettings, ContextUsageEstimate, CutPointResult, } from "./types.js";
|
|
10
|
+
export { calculateContextTokens, computeContextUsage, estimateContextTokens, estimateTokens, getLastAssistantUsage, getLatestCompactionEntry, } from "./usage.js";
|
|
11
|
+
export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.";
|
|
12
|
+
/** Generate or update a conversation summary for compaction. */
|
|
13
|
+
export declare function generateSummary(currentMessages: AgentMessage[], model: AnyModel, reserveTokens: number, apiKey: string, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel): Promise<Result<string, CompactionError>>;
|
|
14
|
+
/** Prepare conversation entries for compaction, or return undefined when compaction is not applicable. */
|
|
15
|
+
export declare function prepareCompaction(pathEntries: ConversationTreeEntry[], settings: CompactionSettings): Result<CompactionPreparation | undefined, CompactionError>;
|
|
16
|
+
export { serializeConversation } from "./utils.js";
|
|
17
|
+
/** Generate compaction summary data from prepared conversation history. */
|
|
18
|
+
export declare function compact(preparation: CompactionPreparation, model: AnyModel, apiKey: string, headers?: Record<string, string>, customInstructions?: string, signal?: AbortSignal, thinkingLevel?: ThinkingLevel): Promise<Result<CompactionResult, CompactionError>>;
|
|
19
|
+
//# sourceMappingURL=compaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../../../src/harness/compaction/compaction.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAO/C,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA8FpB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,2BAA2B,oUAEmF,CAAC;AA6E5H,gEAAgE;AAChE,wBAAsB,eAAe,CACnC,eAAe,EAAE,YAAY,EAAE,EAC/B,KAAK,EAAE,QAAQ,EACf,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,CAAC,EAAE,WAAW,EACpB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA+D1C;AAED,0GAA0G;AAC1G,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,qBAAqB,EAAE,EACpC,QAAQ,EAAE,kBAAkB,GAC3B,MAAM,CAAC,qBAAqB,GAAG,SAAS,EAAE,eAAe,CAAC,CA0F5D;AAiBD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,2EAA2E;AAC3E,wBAAsB,OAAO,CAC3B,WAAW,EAAE,qBAAqB,EAClC,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,kBAAkB,CAAC,EAAE,MAAM,EAC3B,MAAM,CAAC,EAAE,WAAW,EACpB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC,CA4EpD"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { completeSimple } from "@earendil-works/pi-ai";
|
|
2
|
+
import { buildConversationContext } from "../conversation/conversation.js";
|
|
3
|
+
import { CompactionError } from "../errors.js";
|
|
4
|
+
import { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "../messages.js";
|
|
5
|
+
import { err, ok } from "../result.js";
|
|
6
|
+
import { findCutPoint } from "./cut-points.js";
|
|
7
|
+
import { estimateContextTokens } from "./usage.js";
|
|
8
|
+
import { computeFileLists, createFileOps, extractFileOpsFromMessage, formatFileOperations, serializeConversation, } from "./utils.js";
|
|
9
|
+
function extractFileOperations(messages, entries, prevCompactionIndex) {
|
|
10
|
+
const fileOps = createFileOps();
|
|
11
|
+
if (prevCompactionIndex >= 0) {
|
|
12
|
+
const prevCompaction = entries[prevCompactionIndex];
|
|
13
|
+
if (!prevCompaction.fromHook && prevCompaction.details) {
|
|
14
|
+
const details = prevCompaction.details;
|
|
15
|
+
if (Array.isArray(details.readFiles)) {
|
|
16
|
+
for (const f of details.readFiles)
|
|
17
|
+
fileOps.read.add(f);
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(details.modifiedFiles)) {
|
|
20
|
+
for (const f of details.modifiedFiles)
|
|
21
|
+
fileOps.edited.add(f);
|
|
22
|
+
}
|
|
23
|
+
const detailsRecord = details;
|
|
24
|
+
if (Array.isArray(detailsRecord.fileOps?.read)) {
|
|
25
|
+
for (const f of detailsRecord.fileOps.read) {
|
|
26
|
+
if (typeof f === "string")
|
|
27
|
+
fileOps.read.add(f);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(detailsRecord.fileOps?.written)) {
|
|
31
|
+
for (const f of detailsRecord.fileOps.written) {
|
|
32
|
+
if (typeof f === "string")
|
|
33
|
+
fileOps.written.add(f);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(detailsRecord.fileOps?.edited)) {
|
|
37
|
+
for (const f of detailsRecord.fileOps.edited) {
|
|
38
|
+
if (typeof f === "string")
|
|
39
|
+
fileOps.edited.add(f);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const msg of messages) {
|
|
45
|
+
extractFileOpsFromMessage(msg, fileOps);
|
|
46
|
+
}
|
|
47
|
+
return fileOps;
|
|
48
|
+
}
|
|
49
|
+
function getMessageFromEntry(entry) {
|
|
50
|
+
if (entry.type === "message") {
|
|
51
|
+
return entry.message;
|
|
52
|
+
}
|
|
53
|
+
if (entry.type === "custom_message") {
|
|
54
|
+
return createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);
|
|
55
|
+
}
|
|
56
|
+
if (entry.type === "branch_summary") {
|
|
57
|
+
return createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);
|
|
58
|
+
}
|
|
59
|
+
if (entry.type === "compaction") {
|
|
60
|
+
return createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
function getMessageFromEntryForCompaction(entry) {
|
|
65
|
+
if (entry.type === "compaction") {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
return getMessageFromEntry(entry);
|
|
69
|
+
}
|
|
70
|
+
export { findCutPoint, findTurnStartIndex } from "./cut-points.js";
|
|
71
|
+
export { isContextOverflowAssistantMessage } from "./overflow.js";
|
|
72
|
+
export { DEFAULT_COMPACTION_SETTINGS, deriveAutoCompactionPolicy, shouldAutoCompact, shouldCompact, } from "./policy.js";
|
|
73
|
+
export { calculateContextTokens, computeContextUsage, estimateContextTokens, estimateTokens, getLastAssistantUsage, getLatestCompactionEntry, } from "./usage.js";
|
|
74
|
+
export const SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.
|
|
75
|
+
|
|
76
|
+
Do NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;
|
|
77
|
+
const SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Another agent will read ONLY this summary (not the original transcript) and immediately continue the work, so write it as a handover that lets them resume without re-reading anything.
|
|
78
|
+
|
|
79
|
+
Prioritize what is needed to continue. Keep finished work terse, and drop abandoned tangents, superseded approaches, and dead ends.
|
|
80
|
+
|
|
81
|
+
Use this EXACT format:
|
|
82
|
+
|
|
83
|
+
## Goal
|
|
84
|
+
[What is the user trying to accomplish? Can be multiple items if the conversation covers different tasks.]
|
|
85
|
+
|
|
86
|
+
## Constraints & Preferences
|
|
87
|
+
- [Any constraints, preferences, or requirements mentioned by user that still apply]
|
|
88
|
+
- [Or "(none)" if none were mentioned]
|
|
89
|
+
|
|
90
|
+
## Progress
|
|
91
|
+
### Done
|
|
92
|
+
- [x] [Completed tasks/changes - ONE terse line each, no narration]
|
|
93
|
+
|
|
94
|
+
### In Progress
|
|
95
|
+
- [ ] [Current work, with enough detail to pick it back up]
|
|
96
|
+
|
|
97
|
+
### Blocked
|
|
98
|
+
- [Issues preventing progress, if any]
|
|
99
|
+
|
|
100
|
+
## Key Decisions
|
|
101
|
+
- **[Decision]**: [Brief rationale - only decisions that still constrain the remaining work]
|
|
102
|
+
|
|
103
|
+
## Next Steps
|
|
104
|
+
1. [Concrete, ordered list of exactly what to do next to finish the task]
|
|
105
|
+
|
|
106
|
+
## Critical Context
|
|
107
|
+
- [Data, examples, exact file paths, function names, commands, or error messages needed to continue]
|
|
108
|
+
- [Or "(none)" if not applicable]
|
|
109
|
+
|
|
110
|
+
Keep each section concise. Expand detail for unfinished work and Next Steps; compress everything already done. Preserve exact file paths, function names, commands, and error messages verbatim.`;
|
|
111
|
+
const UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.
|
|
112
|
+
|
|
113
|
+
Another agent will read ONLY this summary (not the original transcript) and immediately continue the work, so keep it a tight handover focused on what remains.
|
|
114
|
+
|
|
115
|
+
Update the existing structured summary with new information. RULES:
|
|
116
|
+
- PRESERVE information still needed to continue; compress or drop details about work that is finished or no longer relevant
|
|
117
|
+
- ADD new progress, decisions, and context from the new messages
|
|
118
|
+
- UPDATE the Progress section: move items from "In Progress" to "Done" (and keep Done terse, one line each)
|
|
119
|
+
- UPDATE "Next Steps" so they are the concrete, ordered actions to finish the task
|
|
120
|
+
- PRESERVE exact file paths, function names, commands, and error messages verbatim
|
|
121
|
+
|
|
122
|
+
Use this EXACT format:
|
|
123
|
+
|
|
124
|
+
## Goal
|
|
125
|
+
[Preserve existing goals, add new ones if the task expanded]
|
|
126
|
+
|
|
127
|
+
## Constraints & Preferences
|
|
128
|
+
- [Preserve existing, add new ones discovered]
|
|
129
|
+
|
|
130
|
+
## Progress
|
|
131
|
+
### Done
|
|
132
|
+
- [x] [Include previously done items AND newly completed items]
|
|
133
|
+
|
|
134
|
+
### In Progress
|
|
135
|
+
- [ ] [Current work - update based on progress]
|
|
136
|
+
|
|
137
|
+
### Blocked
|
|
138
|
+
- [Current blockers - remove if resolved]
|
|
139
|
+
|
|
140
|
+
## Key Decisions
|
|
141
|
+
- **[Decision]**: [Brief rationale] (preserve all previous, add new)
|
|
142
|
+
|
|
143
|
+
## Next Steps
|
|
144
|
+
1. [Concrete, ordered list of exactly what to do next to finish the task]
|
|
145
|
+
|
|
146
|
+
## Critical Context
|
|
147
|
+
- [Preserve context still needed to continue; add new if needed]
|
|
148
|
+
|
|
149
|
+
Keep each section concise. Expand detail for unfinished work and Next Steps; compress everything already done. Preserve exact file paths, function names, commands, and error messages verbatim.`;
|
|
150
|
+
/** Generate or update a conversation summary for compaction. */
|
|
151
|
+
export async function generateSummary(currentMessages, model, reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel) {
|
|
152
|
+
const maxTokens = Math.min(Math.floor(0.8 * reserveTokens), model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);
|
|
153
|
+
let basePrompt = previousSummary
|
|
154
|
+
? UPDATE_SUMMARIZATION_PROMPT
|
|
155
|
+
: SUMMARIZATION_PROMPT;
|
|
156
|
+
if (customInstructions) {
|
|
157
|
+
basePrompt = `${basePrompt}\n\nAdditional focus: ${customInstructions}`;
|
|
158
|
+
}
|
|
159
|
+
const llmMessages = convertToLlm(currentMessages);
|
|
160
|
+
const conversationText = serializeConversation(llmMessages);
|
|
161
|
+
let promptText = `<conversation>\n${conversationText}\n</conversation>\n\n`;
|
|
162
|
+
if (previousSummary) {
|
|
163
|
+
promptText += `<previous-summary>\n${previousSummary}\n</previous-summary>\n\n`;
|
|
164
|
+
}
|
|
165
|
+
promptText += basePrompt;
|
|
166
|
+
const summarizationMessages = [
|
|
167
|
+
{
|
|
168
|
+
role: "user",
|
|
169
|
+
content: [{ type: "text", text: promptText }],
|
|
170
|
+
timestamp: Date.now(),
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
const completionOptions = model.reasoning && thinkingLevel && thinkingLevel !== "off"
|
|
174
|
+
? { maxTokens, signal, apiKey, headers, reasoning: thinkingLevel }
|
|
175
|
+
: { maxTokens, signal, apiKey, headers };
|
|
176
|
+
const response = await completeSimple(model, {
|
|
177
|
+
systemPrompt: SUMMARIZATION_SYSTEM_PROMPT,
|
|
178
|
+
messages: summarizationMessages,
|
|
179
|
+
}, completionOptions);
|
|
180
|
+
if (response.stopReason === "aborted") {
|
|
181
|
+
return err(new CompactionError("aborted", response.errorMessage || "Summarization aborted"));
|
|
182
|
+
}
|
|
183
|
+
if (response.stopReason === "error") {
|
|
184
|
+
return err(new CompactionError("summarization_failed", `Summarization failed: ${response.errorMessage || "Unknown error"}`));
|
|
185
|
+
}
|
|
186
|
+
const textContent = response.content
|
|
187
|
+
.filter((c) => c.type === "text")
|
|
188
|
+
.map((c) => c.text)
|
|
189
|
+
.join("\n");
|
|
190
|
+
return ok(textContent);
|
|
191
|
+
}
|
|
192
|
+
/** Prepare conversation entries for compaction, or return undefined when compaction is not applicable. */
|
|
193
|
+
export function prepareCompaction(pathEntries, settings) {
|
|
194
|
+
if (pathEntries.length === 0 ||
|
|
195
|
+
pathEntries[pathEntries.length - 1].type === "compaction") {
|
|
196
|
+
return ok(undefined);
|
|
197
|
+
}
|
|
198
|
+
let prevCompactionIndex = -1;
|
|
199
|
+
for (let i = pathEntries.length - 1; i >= 0; i--) {
|
|
200
|
+
if (pathEntries[i].type === "compaction") {
|
|
201
|
+
prevCompactionIndex = i;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
let previousSummary;
|
|
206
|
+
let boundaryStart = 0;
|
|
207
|
+
if (prevCompactionIndex >= 0) {
|
|
208
|
+
const prevCompaction = pathEntries[prevCompactionIndex];
|
|
209
|
+
previousSummary = prevCompaction.summary;
|
|
210
|
+
const firstKeptEntryIndex = pathEntries.findIndex((entry) => entry.id === prevCompaction.firstKeptEntryId);
|
|
211
|
+
boundaryStart =
|
|
212
|
+
firstKeptEntryIndex >= 0 ? firstKeptEntryIndex : prevCompactionIndex + 1;
|
|
213
|
+
}
|
|
214
|
+
const boundaryEnd = pathEntries.length;
|
|
215
|
+
const tokensBefore = estimateContextTokens(buildConversationContext(pathEntries).messages).tokens;
|
|
216
|
+
const cutPoint = findCutPoint(pathEntries, boundaryStart, boundaryEnd, settings.keepRecentTokens);
|
|
217
|
+
const firstKeptEntry = pathEntries[cutPoint.firstKeptEntryIndex];
|
|
218
|
+
if (!firstKeptEntry?.id) {
|
|
219
|
+
return err(new CompactionError("invalid_conversation", "First kept entry has no UUID - conversation history is invalid"));
|
|
220
|
+
}
|
|
221
|
+
const firstKeptEntryId = firstKeptEntry.id;
|
|
222
|
+
const historyEnd = cutPoint.isSplitTurn
|
|
223
|
+
? cutPoint.turnStartIndex
|
|
224
|
+
: cutPoint.firstKeptEntryIndex;
|
|
225
|
+
const messagesToSummarize = [];
|
|
226
|
+
for (let i = boundaryStart; i < historyEnd; i++) {
|
|
227
|
+
const msg = getMessageFromEntryForCompaction(pathEntries[i]);
|
|
228
|
+
if (msg)
|
|
229
|
+
messagesToSummarize.push(msg);
|
|
230
|
+
}
|
|
231
|
+
const turnPrefixMessages = [];
|
|
232
|
+
if (cutPoint.isSplitTurn) {
|
|
233
|
+
for (let i = cutPoint.turnStartIndex; i < cutPoint.firstKeptEntryIndex; i++) {
|
|
234
|
+
const msg = getMessageFromEntryForCompaction(pathEntries[i]);
|
|
235
|
+
if (msg)
|
|
236
|
+
turnPrefixMessages.push(msg);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
const fileOps = extractFileOperations(messagesToSummarize, pathEntries, prevCompactionIndex);
|
|
240
|
+
if (cutPoint.isSplitTurn) {
|
|
241
|
+
for (const msg of turnPrefixMessages) {
|
|
242
|
+
extractFileOpsFromMessage(msg, fileOps);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return ok({
|
|
246
|
+
firstKeptEntryId,
|
|
247
|
+
messagesToSummarize,
|
|
248
|
+
turnPrefixMessages,
|
|
249
|
+
isSplitTurn: cutPoint.isSplitTurn,
|
|
250
|
+
tokensBefore,
|
|
251
|
+
previousSummary,
|
|
252
|
+
fileOps,
|
|
253
|
+
settings,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
|
|
257
|
+
|
|
258
|
+
Summarize the prefix to provide context for the retained suffix:
|
|
259
|
+
|
|
260
|
+
## Original Request
|
|
261
|
+
[What did the user ask for in this turn?]
|
|
262
|
+
|
|
263
|
+
## Early Progress
|
|
264
|
+
- [Key decisions and work done in the prefix]
|
|
265
|
+
|
|
266
|
+
## Context for Suffix
|
|
267
|
+
- [Information needed to understand the retained recent work]
|
|
268
|
+
|
|
269
|
+
Be concise. Focus on what's needed to understand the kept suffix.`;
|
|
270
|
+
export { serializeConversation } from "./utils.js";
|
|
271
|
+
/** Generate compaction summary data from prepared conversation history. */
|
|
272
|
+
export async function compact(preparation, model, apiKey, headers, customInstructions, signal, thinkingLevel) {
|
|
273
|
+
const { firstKeptEntryId, messagesToSummarize, turnPrefixMessages, isSplitTurn, tokensBefore, previousSummary, fileOps, settings, } = preparation;
|
|
274
|
+
if (!firstKeptEntryId) {
|
|
275
|
+
return err(new CompactionError("invalid_conversation", "First kept entry has no UUID - conversation history is invalid"));
|
|
276
|
+
}
|
|
277
|
+
let summary;
|
|
278
|
+
if (isSplitTurn && turnPrefixMessages.length > 0) {
|
|
279
|
+
const [historyResult, turnPrefixResult] = await Promise.all([
|
|
280
|
+
messagesToSummarize.length > 0
|
|
281
|
+
? generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel)
|
|
282
|
+
: Promise.resolve(ok("No prior history.")),
|
|
283
|
+
generateTurnPrefixSummary(turnPrefixMessages, model, settings.reserveTokens, apiKey, headers, signal, thinkingLevel),
|
|
284
|
+
]);
|
|
285
|
+
if (!historyResult.ok)
|
|
286
|
+
return err(historyResult.error);
|
|
287
|
+
if (!turnPrefixResult.ok)
|
|
288
|
+
return err(turnPrefixResult.error);
|
|
289
|
+
summary = `${historyResult.value}\n\n---\n\n**Turn Context (split turn):**\n\n${turnPrefixResult.value}`;
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
const summaryResult = await generateSummary(messagesToSummarize, model, settings.reserveTokens, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel);
|
|
293
|
+
if (!summaryResult.ok)
|
|
294
|
+
return err(summaryResult.error);
|
|
295
|
+
summary = summaryResult.value;
|
|
296
|
+
}
|
|
297
|
+
const { readFiles, modifiedFiles } = computeFileLists(fileOps);
|
|
298
|
+
summary += formatFileOperations(readFiles, modifiedFiles);
|
|
299
|
+
return ok({
|
|
300
|
+
summary,
|
|
301
|
+
firstKeptEntryId,
|
|
302
|
+
tokensBefore,
|
|
303
|
+
details: { readFiles, modifiedFiles },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
async function generateTurnPrefixSummary(messages, model, reserveTokens, apiKey, headers, signal, thinkingLevel) {
|
|
307
|
+
const maxTokens = Math.min(Math.floor(0.5 * reserveTokens), model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);
|
|
308
|
+
const llmMessages = convertToLlm(messages);
|
|
309
|
+
const conversationText = serializeConversation(llmMessages);
|
|
310
|
+
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${TURN_PREFIX_SUMMARIZATION_PROMPT}`;
|
|
311
|
+
const summarizationMessages = [
|
|
312
|
+
{
|
|
313
|
+
role: "user",
|
|
314
|
+
content: [{ type: "text", text: promptText }],
|
|
315
|
+
timestamp: Date.now(),
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
const response = await completeSimple(model, {
|
|
319
|
+
systemPrompt: SUMMARIZATION_SYSTEM_PROMPT,
|
|
320
|
+
messages: summarizationMessages,
|
|
321
|
+
}, model.reasoning && thinkingLevel && thinkingLevel !== "off"
|
|
322
|
+
? { maxTokens, signal, apiKey, headers, reasoning: thinkingLevel }
|
|
323
|
+
: { maxTokens, signal, apiKey, headers });
|
|
324
|
+
if (response.stopReason === "aborted") {
|
|
325
|
+
return err(new CompactionError("aborted", response.errorMessage || "Turn prefix summarization aborted"));
|
|
326
|
+
}
|
|
327
|
+
if (response.stopReason === "error") {
|
|
328
|
+
return err(new CompactionError("summarization_failed", `Turn prefix summarization failed: ${response.errorMessage || "Unknown error"}`));
|
|
329
|
+
}
|
|
330
|
+
return ok(response.content
|
|
331
|
+
.filter((c) => c.type === "text")
|
|
332
|
+
.map((c) => c.text)
|
|
333
|
+
.join("\n"));
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=compaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../../src/harness/compaction/compaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConversationTreeEntry } from "../conversation/entries.js";
|
|
2
|
+
import type { CutPointResult } from "./types.js";
|
|
3
|
+
/** Find the user-visible message that starts the turn containing an entry. */
|
|
4
|
+
export declare function findTurnStartIndex(entries: ConversationTreeEntry[], entryIndex: number, startIndex: number): number;
|
|
5
|
+
/** Find the compaction cut point that keeps approximately the requested recent-token budget. */
|
|
6
|
+
export declare function findCutPoint(entries: ConversationTreeEntry[], startIndex: number, endIndex: number, keepRecentTokens: number): CutPointResult;
|
|
7
|
+
//# sourceMappingURL=cut-points.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cut-points.d.ts","sourceRoot":"","sources":["../../../src/harness/compaction/cut-points.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA+CjD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAcR;AAED,gGAAgG;AAChG,wBAAgB,YAAY,CAC1B,OAAO,EAAE,qBAAqB,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GACvB,cAAc,CAkDhB"}
|