@sammorrowdrums/mcpi-agent-core 0.85.0-bootstrap.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 +21 -0
- package/README.md +513 -0
- package/dist/agent-loop.d.ts +24 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +553 -0
- package/dist/agent-loop.js.map +1 -0
- package/dist/agent.d.ts +122 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +422 -0
- package/dist/agent.js.map +1 -0
- package/dist/harness/agent-harness.d.ts +461 -0
- package/dist/harness/agent-harness.d.ts.map +1 -0
- package/dist/harness/agent-harness.js +252 -0
- package/dist/harness/agent-harness.js.map +1 -0
- package/dist/harness/compaction/branch-summarization.d.ts +62 -0
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/harness/compaction/branch-summarization.js +169 -0
- package/dist/harness/compaction/branch-summarization.js.map +1 -0
- package/dist/harness/compaction/compaction.d.ts +104 -0
- package/dist/harness/compaction/compaction.d.ts.map +1 -0
- package/dist/harness/compaction/compaction.js +570 -0
- package/dist/harness/compaction/compaction.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 +120 -0
- package/dist/harness/compaction/utils.js.map +1 -0
- package/dist/harness/env/nodejs.d.ts +46 -0
- package/dist/harness/env/nodejs.d.ts.map +1 -0
- package/dist/harness/env/nodejs.js +639 -0
- package/dist/harness/env/nodejs.js.map +1 -0
- package/dist/harness/events.d.ts +43 -0
- package/dist/harness/events.d.ts.map +1 -0
- package/dist/harness/events.js +65 -0
- package/dist/harness/events.js.map +1 -0
- package/dist/harness/messages.d.ts +51 -0
- package/dist/harness/messages.d.ts.map +1 -0
- package/dist/harness/messages.js +102 -0
- package/dist/harness/messages.js.map +1 -0
- package/dist/harness/prompt-templates.d.ts +48 -0
- package/dist/harness/prompt-templates.d.ts.map +1 -0
- package/dist/harness/prompt-templates.js +225 -0
- package/dist/harness/prompt-templates.js.map +1 -0
- package/dist/harness/reducer.d.ts +100 -0
- package/dist/harness/reducer.d.ts.map +1 -0
- package/dist/harness/reducer.js +415 -0
- package/dist/harness/reducer.js.map +1 -0
- package/dist/harness/result.d.ts +40 -0
- package/dist/harness/result.d.ts.map +1 -0
- package/dist/harness/result.js +41 -0
- package/dist/harness/result.js.map +1 -0
- package/dist/harness/session/context.d.ts +22 -0
- package/dist/harness/session/context.d.ts.map +1 -0
- package/dist/harness/session/context.js +67 -0
- package/dist/harness/session/context.js.map +1 -0
- package/dist/harness/session/index.d.ts +7 -0
- package/dist/harness/session/index.d.ts.map +1 -0
- package/dist/harness/session/index.js +6 -0
- package/dist/harness/session/index.js.map +1 -0
- package/dist/harness/session/jsonl/codec.d.ts +10 -0
- package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
- package/dist/harness/session/jsonl/codec.js +229 -0
- package/dist/harness/session/jsonl/codec.js.map +1 -0
- package/dist/harness/session/jsonl/errors.d.ts +9 -0
- package/dist/harness/session/jsonl/errors.d.ts.map +1 -0
- package/dist/harness/session/jsonl/errors.js +19 -0
- package/dist/harness/session/jsonl/errors.js.map +1 -0
- package/dist/harness/session/jsonl/repo.d.ts +27 -0
- package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
- package/dist/harness/session/jsonl/repo.js +175 -0
- package/dist/harness/session/jsonl/repo.js.map +1 -0
- package/dist/harness/session/jsonl/storage.d.ts +43 -0
- package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
- package/dist/harness/session/jsonl/storage.js +217 -0
- package/dist/harness/session/jsonl/storage.js.map +1 -0
- package/dist/harness/session/jsonl/types.d.ts +38 -0
- package/dist/harness/session/jsonl/types.d.ts.map +1 -0
- package/dist/harness/session/jsonl/types.js +2 -0
- package/dist/harness/session/jsonl/types.js.map +1 -0
- package/dist/harness/session/jsonl.d.ts +3 -0
- package/dist/harness/session/jsonl.d.ts.map +1 -0
- package/dist/harness/session/jsonl.js +2 -0
- package/dist/harness/session/jsonl.js.map +1 -0
- package/dist/harness/session/memory.d.ts +44 -0
- package/dist/harness/session/memory.d.ts.map +1 -0
- package/dist/harness/session/memory.js +141 -0
- package/dist/harness/session/memory.js.map +1 -0
- package/dist/harness/session/session.d.ts +50 -0
- package/dist/harness/session/session.d.ts.map +1 -0
- package/dist/harness/session/session.js +227 -0
- package/dist/harness/session/session.js.map +1 -0
- package/dist/harness/session/state.d.ts +65 -0
- package/dist/harness/session/state.d.ts.map +1 -0
- package/dist/harness/session/state.js +319 -0
- package/dist/harness/session/state.js.map +1 -0
- package/dist/harness/session/testing/conformance.d.ts +4 -0
- package/dist/harness/session/testing/conformance.d.ts.map +1 -0
- package/dist/harness/session/testing/conformance.js +762 -0
- package/dist/harness/session/testing/conformance.js.map +1 -0
- package/dist/harness/session/testing/index.d.ts +3 -0
- package/dist/harness/session/testing/index.d.ts.map +1 -0
- package/dist/harness/session/testing/index.js +2 -0
- package/dist/harness/session/testing/index.js.map +1 -0
- package/dist/harness/session/testing/types.d.ts +14 -0
- package/dist/harness/session/testing/types.d.ts.map +1 -0
- package/dist/harness/session/testing/types.js +2 -0
- package/dist/harness/session/testing/types.js.map +1 -0
- package/dist/harness/session/types.d.ts +346 -0
- package/dist/harness/session/types.d.ts.map +1 -0
- package/dist/harness/session/types.js +10 -0
- package/dist/harness/session/types.js.map +1 -0
- package/dist/harness/skills.d.ts +44 -0
- package/dist/harness/skills.d.ts.map +1 -0
- package/dist/harness/skills.js +313 -0
- package/dist/harness/skills.js.map +1 -0
- package/dist/harness/system-prompt.d.ts +3 -0
- package/dist/harness/system-prompt.d.ts.map +1 -0
- package/dist/harness/system-prompt.js +30 -0
- package/dist/harness/system-prompt.js.map +1 -0
- package/dist/harness/telemetry.d.ts +1221 -0
- package/dist/harness/telemetry.d.ts.map +1 -0
- package/dist/harness/telemetry.js +508 -0
- package/dist/harness/telemetry.js.map +1 -0
- package/dist/harness/tools/bash.d.ts +27 -0
- package/dist/harness/tools/bash.d.ts.map +1 -0
- package/dist/harness/tools/bash.js +132 -0
- package/dist/harness/tools/bash.js.map +1 -0
- package/dist/harness/tools/edit-diff.d.ts +89 -0
- package/dist/harness/tools/edit-diff.d.ts.map +1 -0
- package/dist/harness/tools/edit-diff.js +386 -0
- package/dist/harness/tools/edit-diff.js.map +1 -0
- package/dist/harness/tools/edit.d.ts +19 -0
- package/dist/harness/tools/edit.d.ts.map +1 -0
- package/dist/harness/tools/edit.js +95 -0
- package/dist/harness/tools/edit.js.map +1 -0
- package/dist/harness/tools/file-mutation-queue.d.ts +4 -0
- package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/harness/tools/file-mutation-queue.js +46 -0
- package/dist/harness/tools/file-mutation-queue.js.map +1 -0
- package/dist/harness/tools/image.d.ts +3 -0
- package/dist/harness/tools/image.d.ts.map +1 -0
- package/dist/harness/tools/image.js +106 -0
- package/dist/harness/tools/image.js.map +1 -0
- package/dist/harness/tools/index.d.ts +6 -0
- package/dist/harness/tools/index.d.ts.map +1 -0
- package/dist/harness/tools/index.js +5 -0
- package/dist/harness/tools/index.js.map +1 -0
- package/dist/harness/tools/path-utils.d.ts +4 -0
- package/dist/harness/tools/path-utils.d.ts.map +1 -0
- package/dist/harness/tools/path-utils.js +26 -0
- package/dist/harness/tools/path-utils.js.map +1 -0
- package/dist/harness/tools/read.d.ts +34 -0
- package/dist/harness/tools/read.d.ts.map +1 -0
- package/dist/harness/tools/read.js +110 -0
- package/dist/harness/tools/read.js.map +1 -0
- package/dist/harness/tools/tool-context.d.ts +6 -0
- package/dist/harness/tools/tool-context.d.ts.map +1 -0
- package/dist/harness/tools/tool-context.js +2 -0
- package/dist/harness/tools/tool-context.js.map +1 -0
- package/dist/harness/tools/write.d.ts +11 -0
- package/dist/harness/tools/write.d.ts.map +1 -0
- package/dist/harness/tools/write.js +31 -0
- package/dist/harness/tools/write.js.map +1 -0
- package/dist/harness/types.d.ts +228 -0
- package/dist/harness/types.d.ts.map +1 -0
- package/dist/harness/types.js +75 -0
- package/dist/harness/types.js.map +1 -0
- package/dist/harness/utils/shell-output.d.ts +22 -0
- package/dist/harness/utils/shell-output.d.ts.map +1 -0
- package/dist/harness/utils/shell-output.js +181 -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 +296 -0
- package/dist/harness/utils/truncate.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -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 +70 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +280 -0
- package/dist/proxy.js.map +1 -0
- package/dist/search/index.d.ts +21 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +2 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/scanning.d.ts +29 -0
- package/dist/search/scanning.d.ts.map +1 -0
- package/dist/search/scanning.js +103 -0
- package/dist/search/scanning.js.map +1 -0
- package/dist/stream-fn.d.ts +10 -0
- package/dist/stream-fn.d.ts.map +1 -0
- package/dist/stream-fn.js +17 -0
- package/dist/stream-fn.js.map +1 -0
- package/dist/types.d.ts +413 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { TaggedError } from "./result.js";
|
|
2
|
+
export class LaneBusy extends TaggedError("LaneBusy") {
|
|
3
|
+
}
|
|
4
|
+
export class MissingIdentities extends TaggedError("MissingIdentities") {
|
|
5
|
+
}
|
|
6
|
+
export class NoActiveRun extends TaggedError("NoActiveRun") {
|
|
7
|
+
}
|
|
8
|
+
export class NoActiveOperation extends TaggedError("NoActiveOperation") {
|
|
9
|
+
}
|
|
10
|
+
export class NothingToResume extends TaggedError("NothingToResume") {
|
|
11
|
+
}
|
|
12
|
+
export class InvalidMessage extends TaggedError("InvalidMessage") {
|
|
13
|
+
}
|
|
14
|
+
export class UnknownSkill extends TaggedError("UnknownSkill") {
|
|
15
|
+
}
|
|
16
|
+
export class UnknownTemplate extends TaggedError("UnknownTemplate") {
|
|
17
|
+
}
|
|
18
|
+
export class UnknownTarget extends TaggedError("UnknownTarget") {
|
|
19
|
+
}
|
|
20
|
+
export class UnknownQueueItem extends TaggedError("UnknownQueueItem") {
|
|
21
|
+
}
|
|
22
|
+
export class LaneExists extends TaggedError("LaneExists") {
|
|
23
|
+
}
|
|
24
|
+
export class InvalidLane extends TaggedError("InvalidLane") {
|
|
25
|
+
}
|
|
26
|
+
export class NothingToCompact extends TaggedError("NothingToCompact") {
|
|
27
|
+
}
|
|
28
|
+
export class Closed extends TaggedError("Closed") {
|
|
29
|
+
}
|
|
30
|
+
export class HarnessFault extends Error {
|
|
31
|
+
cause;
|
|
32
|
+
constructor(message, cause) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = "HarnessFault";
|
|
35
|
+
this.cause = cause;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class HarnessClosed extends Error {
|
|
39
|
+
constructor() {
|
|
40
|
+
super("AgentHarness was closed while the operation was active");
|
|
41
|
+
this.name = "HarnessClosed";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export class HarnessNotImplemented extends Error {
|
|
45
|
+
operation;
|
|
46
|
+
constructor(operation) {
|
|
47
|
+
super(`AgentHarness.${operation} is not implemented yet`);
|
|
48
|
+
this.name = "HarnessNotImplemented";
|
|
49
|
+
this.operation = operation;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
class UnavailableRegistry {
|
|
53
|
+
operation;
|
|
54
|
+
isClosed;
|
|
55
|
+
constructor(operation, isClosed) {
|
|
56
|
+
this.operation = operation;
|
|
57
|
+
this.isClosed = isClosed;
|
|
58
|
+
}
|
|
59
|
+
on(_name, _handler, _options) {
|
|
60
|
+
throw this.isClosed() ? new HarnessClosed() : new HarnessNotImplemented(this.operation);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class AgentHarness {
|
|
64
|
+
name = "main";
|
|
65
|
+
session;
|
|
66
|
+
hooks;
|
|
67
|
+
events;
|
|
68
|
+
durableSession;
|
|
69
|
+
model;
|
|
70
|
+
thinkingLevel;
|
|
71
|
+
activeToolNames;
|
|
72
|
+
tools;
|
|
73
|
+
resources;
|
|
74
|
+
streamOptions;
|
|
75
|
+
retryPolicy;
|
|
76
|
+
compactionSettings;
|
|
77
|
+
steeringMode;
|
|
78
|
+
followUpMode;
|
|
79
|
+
closed = false;
|
|
80
|
+
constructor(options) {
|
|
81
|
+
this.durableSession = options.session;
|
|
82
|
+
this.session = options.session;
|
|
83
|
+
this.hooks = new UnavailableRegistry("hooks.on", () => this.closed);
|
|
84
|
+
this.events = new UnavailableRegistry("events.on", () => this.closed);
|
|
85
|
+
this.model = options.model;
|
|
86
|
+
this.thinkingLevel = options.thinkingLevel ?? "off";
|
|
87
|
+
this.activeToolNames = [...(options.activeToolNames ?? options.tools?.map((tool) => tool.name) ?? [])];
|
|
88
|
+
this.tools = [...(options.tools ?? [])];
|
|
89
|
+
this.resources = {
|
|
90
|
+
skills: options.resources?.skills ? [...options.resources.skills] : undefined,
|
|
91
|
+
promptTemplates: options.resources?.promptTemplates ? [...options.resources.promptTemplates] : undefined,
|
|
92
|
+
};
|
|
93
|
+
this.streamOptions = { ...(options.streamOptions ?? {}) };
|
|
94
|
+
this.retryPolicy = options.retry ?? { enabled: false, maxRetries: 0, baseDelayMs: 1000 };
|
|
95
|
+
this.compactionSettings = options.compaction ?? {
|
|
96
|
+
enabled: true,
|
|
97
|
+
reserveTokens: 16384,
|
|
98
|
+
keepRecentTokens: 20000,
|
|
99
|
+
};
|
|
100
|
+
this.steeringMode = options.steeringMode ?? "one-at-a-time";
|
|
101
|
+
this.followUpMode = options.followUpMode ?? "one-at-a-time";
|
|
102
|
+
}
|
|
103
|
+
static async create(options) {
|
|
104
|
+
const [record] = await options.session.findRecords({ limit: 1 });
|
|
105
|
+
if (record !== undefined)
|
|
106
|
+
throw new HarnessNotImplemented("create.restore");
|
|
107
|
+
return { harness: new AgentHarness(options), suspended: [] };
|
|
108
|
+
}
|
|
109
|
+
unavailable(operation) {
|
|
110
|
+
return Promise.reject(this.closed ? new HarnessClosed() : new HarnessNotImplemented(operation));
|
|
111
|
+
}
|
|
112
|
+
async getLeafId() {
|
|
113
|
+
return this.durableSession.getLeafId();
|
|
114
|
+
}
|
|
115
|
+
async prompt(_input, _images) {
|
|
116
|
+
return this.unavailable("prompt");
|
|
117
|
+
}
|
|
118
|
+
async skill(_name, _additionalInstructions) {
|
|
119
|
+
return this.unavailable("skill");
|
|
120
|
+
}
|
|
121
|
+
async promptFromTemplate(_name, _args) {
|
|
122
|
+
return this.unavailable("promptFromTemplate");
|
|
123
|
+
}
|
|
124
|
+
async compact(_options) {
|
|
125
|
+
return this.unavailable("compact");
|
|
126
|
+
}
|
|
127
|
+
async navigateTree(_targetId, _options) {
|
|
128
|
+
return this.unavailable("navigateTree");
|
|
129
|
+
}
|
|
130
|
+
async resume() {
|
|
131
|
+
return this.unavailable("resume");
|
|
132
|
+
}
|
|
133
|
+
async abort() {
|
|
134
|
+
return this.unavailable("abort");
|
|
135
|
+
}
|
|
136
|
+
async steer(_input, _images) {
|
|
137
|
+
return this.unavailable("steer");
|
|
138
|
+
}
|
|
139
|
+
async followUp(_input, _images) {
|
|
140
|
+
return this.unavailable("followUp");
|
|
141
|
+
}
|
|
142
|
+
async nextRun(_input, _images) {
|
|
143
|
+
return this.unavailable("nextRun");
|
|
144
|
+
}
|
|
145
|
+
async cancelQueued(_entryId) {
|
|
146
|
+
return this.unavailable("cancelQueued");
|
|
147
|
+
}
|
|
148
|
+
async recordUsage(_usage, _options) {
|
|
149
|
+
return this.unavailable("recordUsage");
|
|
150
|
+
}
|
|
151
|
+
async waitForIdle() {
|
|
152
|
+
return this.unavailable("waitForIdle");
|
|
153
|
+
}
|
|
154
|
+
async runWhenIdle(_callback) {
|
|
155
|
+
return this.unavailable("runWhenIdle");
|
|
156
|
+
}
|
|
157
|
+
async peekAction() {
|
|
158
|
+
return this.unavailable("peekAction");
|
|
159
|
+
}
|
|
160
|
+
async executeAction() {
|
|
161
|
+
return this.unavailable("executeAction");
|
|
162
|
+
}
|
|
163
|
+
async runToCompletion() {
|
|
164
|
+
return this.unavailable("runToCompletion");
|
|
165
|
+
}
|
|
166
|
+
async getModel() {
|
|
167
|
+
return this.model;
|
|
168
|
+
}
|
|
169
|
+
async setModel(model) {
|
|
170
|
+
this.model = model;
|
|
171
|
+
}
|
|
172
|
+
async getThinkingLevel() {
|
|
173
|
+
return this.thinkingLevel;
|
|
174
|
+
}
|
|
175
|
+
async setThinkingLevel(level) {
|
|
176
|
+
this.thinkingLevel = level;
|
|
177
|
+
}
|
|
178
|
+
async getActiveTools() {
|
|
179
|
+
return [...this.activeToolNames];
|
|
180
|
+
}
|
|
181
|
+
async setActiveTools(names) {
|
|
182
|
+
this.activeToolNames = [...names];
|
|
183
|
+
}
|
|
184
|
+
async watch() {
|
|
185
|
+
return this.unavailable("watch");
|
|
186
|
+
}
|
|
187
|
+
async lane(_name) {
|
|
188
|
+
return this.unavailable("lane");
|
|
189
|
+
}
|
|
190
|
+
async createLane(_name, _at) {
|
|
191
|
+
return this.unavailable("createLane");
|
|
192
|
+
}
|
|
193
|
+
async lanes() {
|
|
194
|
+
return this.unavailable("lanes");
|
|
195
|
+
}
|
|
196
|
+
async getTools() {
|
|
197
|
+
return [...this.tools];
|
|
198
|
+
}
|
|
199
|
+
async setTools(tools, activeNames) {
|
|
200
|
+
this.tools = [...tools];
|
|
201
|
+
this.activeToolNames = [...(activeNames ?? tools.map((tool) => tool.name))];
|
|
202
|
+
}
|
|
203
|
+
async getResources() {
|
|
204
|
+
return {
|
|
205
|
+
skills: this.resources.skills ? [...this.resources.skills] : undefined,
|
|
206
|
+
promptTemplates: this.resources.promptTemplates ? [...this.resources.promptTemplates] : undefined,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async setResources(resources) {
|
|
210
|
+
this.resources = {
|
|
211
|
+
skills: resources.skills ? [...resources.skills] : undefined,
|
|
212
|
+
promptTemplates: resources.promptTemplates ? [...resources.promptTemplates] : undefined,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async getStreamOptions() {
|
|
216
|
+
return { ...this.streamOptions };
|
|
217
|
+
}
|
|
218
|
+
async setStreamOptions(options) {
|
|
219
|
+
this.streamOptions = { ...options };
|
|
220
|
+
}
|
|
221
|
+
async getRetryPolicy() {
|
|
222
|
+
return { ...this.retryPolicy };
|
|
223
|
+
}
|
|
224
|
+
async setRetryPolicy(policy) {
|
|
225
|
+
this.retryPolicy = { ...policy };
|
|
226
|
+
}
|
|
227
|
+
async getCompactionSettings() {
|
|
228
|
+
return { ...this.compactionSettings };
|
|
229
|
+
}
|
|
230
|
+
async setCompactionSettings(settings) {
|
|
231
|
+
this.compactionSettings = { ...settings };
|
|
232
|
+
}
|
|
233
|
+
async getSteeringMode() {
|
|
234
|
+
return this.steeringMode;
|
|
235
|
+
}
|
|
236
|
+
async setSteeringMode(mode) {
|
|
237
|
+
this.steeringMode = mode;
|
|
238
|
+
}
|
|
239
|
+
async getFollowUpMode() {
|
|
240
|
+
return this.followUpMode;
|
|
241
|
+
}
|
|
242
|
+
async setFollowUpMode(mode) {
|
|
243
|
+
this.followUpMode = mode;
|
|
244
|
+
}
|
|
245
|
+
async watchSession() {
|
|
246
|
+
return this.unavailable("watchSession");
|
|
247
|
+
}
|
|
248
|
+
async close() {
|
|
249
|
+
this.closed = true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=agent-harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-harness.js","sourceRoot":"","sources":["../../src/harness/agent-harness.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tApi,\n\tAssistantMessage,\n\tDeferredHandle,\n\tImageContent,\n\tMessage,\n\tModel,\n\tModels,\n\tRetryPolicy,\n\tSimpleStreamOptions,\n\tUsage,\n} from \"@sammorrowdrums/mcpi-ai\";\nimport type { AgentMessage, AgentTool, QueueMode, ThinkingLevel } from \"../types.ts\";\nimport type { CompactionSettings } from \"./compaction/compaction.ts\";\nimport { type Result as ResultValue, TaggedError } from \"./result.ts\";\nimport type {\n\tBranchSummaryEntry,\n\tCompactionEntry,\n\tEntry,\n\tJsonValue,\n\tProvisionedEntry,\n\tSession,\n\tSessionTree,\n} from \"./session/index.ts\";\nimport type { TelemetryContext } from \"./telemetry.ts\";\nimport type { AgentHarnessResources, PromptTemplate, Skill } from \"./types.ts\";\n\nexport class LaneBusy extends TaggedError(\"LaneBusy\")<{\n\tlane: string;\n\toperationId: string;\n\toperationKind: \"run\" | \"compaction\" | \"navigation\";\n\tmessage: string;\n}> {}\nexport class MissingIdentities extends TaggedError(\"MissingIdentities\")<{\n\tlane: string;\n\ttools: string[];\n\tmodels: string[];\n\tmessage: string;\n}> {}\nexport class NoActiveRun extends TaggedError(\"NoActiveRun\")<{ lane: string; message: string }> {}\nexport class NoActiveOperation extends TaggedError(\"NoActiveOperation\")<{ lane: string; message: string }> {}\nexport class NothingToResume extends TaggedError(\"NothingToResume\")<{ lane: string; message: string }> {}\nexport class InvalidMessage extends TaggedError(\"InvalidMessage\")<{ lane: string; reason: string; message: string }> {}\nexport class UnknownSkill extends TaggedError(\"UnknownSkill\")<{ name: string; message: string }> {}\nexport class UnknownTemplate extends TaggedError(\"UnknownTemplate\")<{ name: string; message: string }> {}\nexport class UnknownTarget extends TaggedError(\"UnknownTarget\")<{ targetId: string; message: string }> {}\nexport class UnknownQueueItem extends TaggedError(\"UnknownQueueItem\")<{\n\tlane: string;\n\tentryId: string;\n\tmessage: string;\n}> {}\nexport class LaneExists extends TaggedError(\"LaneExists\")<{ lane: string; message: string }> {}\nexport class InvalidLane extends TaggedError(\"InvalidLane\")<{ lane: string; reason: string; message: string }> {}\nexport class NothingToCompact extends TaggedError(\"NothingToCompact\")<{ lane: string; message: string }> {}\nexport class Closed extends TaggedError(\"Closed\")<{ message: string }> {}\n\nexport class HarnessFault extends Error {\n\treadonly cause: unknown;\n\n\tconstructor(message: string, cause: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"HarnessFault\";\n\t\tthis.cause = cause;\n\t}\n}\n\nexport class HarnessClosed extends Error {\n\tconstructor() {\n\t\tsuper(\"AgentHarness was closed while the operation was active\");\n\t\tthis.name = \"HarnessClosed\";\n\t}\n}\n\nexport class HarnessNotImplemented extends Error {\n\treadonly operation: string;\n\n\tconstructor(operation: string) {\n\t\tsuper(`AgentHarness.${operation} is not implemented yet`);\n\t\tthis.name = \"HarnessNotImplemented\";\n\t\tthis.operation = operation;\n\t}\n}\n\nexport interface OperationError {\n\tcode: string;\n\tmessage: string;\n}\n\nexport type RunOutcome =\n\t| { kind: \"completed\"; leafId: string; finalEntryId: string; finalMessage: AssistantMessage }\n\t| { kind: \"aborted\"; leafId: string; finalEntryId: string; finalMessage: AssistantMessage }\n\t| { kind: \"failed\"; leafId: string; error: OperationError; finalEntryId?: string; finalMessage?: AssistantMessage }\n\t| { kind: \"suspended\"; leafId: string; finalEntryId: string; deferred: DeferredHandle };\n\nexport type CompactionOutcome =\n\t| { kind: \"completed\"; leafId: string; entry: CompactionEntry }\n\t| { kind: \"declined\" | \"aborted\"; leafId: string }\n\t| { kind: \"failed\"; leafId: string; error: OperationError };\n\nexport type NavigationOutcome =\n\t| { kind: \"completed\"; newLeafId: string | null; summaryEntry?: BranchSummaryEntry }\n\t| { kind: \"declined\" | \"aborted\"; leafId: string | null }\n\t| { kind: \"failed\"; leafId: string | null; error: OperationError };\n\nexport type RunRejected = LaneBusy | InvalidMessage | UnknownSkill | UnknownTemplate | Closed;\nexport type CompactionRejected = LaneBusy | NothingToCompact | Closed;\nexport type NavigationRejected = LaneBusy | UnknownTarget | Closed;\nexport type ResumeRejected = LaneBusy | NothingToResume | MissingIdentities | Closed;\nexport type QueueRejected = NoActiveRun | InvalidMessage | Closed;\nexport type CancelQueuedRejected = UnknownQueueItem | Closed;\nexport type AbortRejected = NoActiveOperation | Closed;\n\nexport type RunResult = ResultValue<{ runId: string } & RunOutcome, RunRejected>;\nexport type CompactionResult = ResultValue<{ runId: string } & CompactionOutcome, CompactionRejected>;\nexport type NavigationResult = ResultValue<{ runId: string } & NavigationOutcome, NavigationRejected>;\nexport type QueueResult = ResultValue<{ entryId: string }, QueueRejected>;\nexport type CancelQueuedResult = ResultValue<\n\t{ outcome: \"cancelled\" | \"already_consumed\" | \"already_cleared\" },\n\tCancelQueuedRejected\n>;\nexport type RecordUsageResult = ResultValue<void, Closed>;\nexport type AbortResult = ResultValue<\n\t{ runId: string; steer: AgentMessage[]; followUp: AgentMessage[] },\n\tAbortRejected\n>;\n\nexport type ResumeOutcome =\n\t| ({ operation: \"run\"; runId: string } & RunOutcome)\n\t| ({ operation: \"compaction\"; runId: string } & CompactionOutcome)\n\t| ({ operation: \"navigation\"; runId: string } & NavigationOutcome);\nexport type ResumeResult = ResultValue<ResumeOutcome, ResumeRejected>;\nexport type CreateLaneResult = ResultValue<AgentLane, LaneExists | InvalidLane | UnknownTarget | Closed>;\n\nexport interface NavigateOptions {\n\tsummarize?: boolean;\n\tcustomInstructions?: string;\n\tlabel?: string;\n}\n\nexport interface SuspendedOperation {\n\tlane: string;\n\tkind: \"run\" | \"compaction\" | \"navigation\";\n\tid: string;\n\tstartedAt: number;\n\treason: \"crash\" | \"deferred\";\n\tprompt?: AgentMessage[];\n\tdeferred?: DeferredHandle;\n\taborting?: { steer: AgentMessage[]; followUp: AgentMessage[] };\n\tmissing: { tools: string[]; models: string[] };\n}\n\nexport interface LaneInfo {\n\tname: string;\n\tleafId: string | null;\n\toperation: null | {\n\t\tid: string;\n\t\tkind: \"run\" | \"compaction\" | \"navigation\";\n\t\tstatus: \"running\" | \"suspended\" | \"aborting\";\n\t};\n}\n\nexport interface QueuedItem {\n\tentryId: string;\n\tmessage: AgentMessage;\n}\n\nexport interface LaneSnapshot {\n\tlane: string;\n\ttranscript: Entry[];\n\tleafId: string | null;\n\toperation: LaneInfo[\"operation\"];\n\tqueues: { steer: QueuedItem[]; followUp: QueuedItem[]; nextRun: QueuedItem[] };\n\tpendingWrites: { id: string; entry: ProvisionedEntry }[];\n\tfaulted: boolean;\n}\n\nexport interface SessionSnapshot {\n\tlanes: (LaneInfo & { suspended?: SuspendedOperation })[];\n\tfaulted: boolean;\n}\n\nexport type ActionInfo =\n\t| { kind: \"append_entry\"; entryType: Entry[\"type\"]; entryId: string }\n\t| { kind: \"append_record\"; recordType: string }\n\t| { kind: \"move_lane\"; to: string | null }\n\t| { kind: \"set_fact\"; fact: \"name\" | \"label\" }\n\t| { kind: \"try_finish_run\"; outcome: \"completed\" | \"failed\" }\n\t| { kind: \"finish_operation\"; outcome: \"completed\" | \"declined\" | \"failed\" | \"aborted\" }\n\t| { kind: \"commit_follow_up\" }\n\t| { kind: \"consume_queue_item\"; queue: \"steer\" | \"followUp\"; entryId: string }\n\t| { kind: \"apply_pending_write\"; entryId: string }\n\t| { kind: \"stream_assistant\"; step: \"assistant\" | \"compaction\" | \"branch_summary\"; attempt: number }\n\t| { kind: \"execute_tool\"; toolCallId: string; toolName: string }\n\t| { kind: \"fetch_deferred\" | \"cancel_deferred\"; provider: string; id: string }\n\t| { kind: \"hook\"; name: HookName }\n\t| { kind: \"sleep\"; delayMs: number };\n\nexport type HookName =\n\t| \"before_run\"\n\t| \"before_resume\"\n\t| \"before_run_end\"\n\t| \"transform_context\"\n\t| \"before_request\"\n\t| \"before_payload\"\n\t| \"after_response\"\n\t| \"before_tool\"\n\t| \"after_tool\"\n\t| \"before_compaction\"\n\t| \"before_navigation\";\n\nexport interface Hooks {\n\ton(name: HookName, handler: (event: unknown) => unknown | Promise<unknown>, options?: { id?: string }): () => void;\n}\n\nexport interface Events {\n\ton(type: string, listener: (event: unknown) => void | Promise<void>): () => void;\n}\n\nclass UnavailableRegistry implements Hooks, Events {\n\tprivate readonly operation: string;\n\tprivate readonly isClosed: () => boolean;\n\n\tconstructor(operation: string, isClosed: () => boolean) {\n\t\tthis.operation = operation;\n\t\tthis.isClosed = isClosed;\n\t}\n\n\ton(\n\t\t_name: HookName | string,\n\t\t_handler: (event: unknown) => unknown | Promise<unknown>,\n\t\t_options?: { id?: string },\n\t): () => void {\n\t\tthrow this.isClosed() ? new HarnessClosed() : new HarnessNotImplemented(this.operation);\n\t}\n}\n\nexport type HarnessTool = AgentTool & { replay?: \"never\" | \"safe\" };\nexport type Resources = AgentHarnessResources<Skill, PromptTemplate>;\nexport type StreamOptions = SimpleStreamOptions;\nexport type StreamOptionsPatch = Partial<SimpleStreamOptions>;\nexport type EntryProjector = (entry: Entry) => AgentMessage[] | Promise<AgentMessage[]>;\n\nexport interface AgentHarnessOptions {\n\tsession: Session;\n\tmodels: Models;\n\tmodel: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tactiveToolNames?: string[];\n\ttools?: HarnessTool[];\n\ttoolContext?: object | (() => object | Promise<object>);\n\tsystemPrompt?: string | (() => string | Promise<string>);\n\tresources?: Resources;\n\tstreamOptions?: StreamOptions;\n\tretry?: RetryPolicy;\n\tcompaction?: CompactionSettings;\n\tsteeringMode?: QueueMode;\n\tfollowUpMode?: QueueMode;\n\ttoolExecution?: \"sequential\" | \"parallel\";\n\tdrive?: \"automatic\" | \"manual\";\n\ttoProviderMessages?: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;\n\tentryProjectors?: Record<string, EntryProjector>;\n\tcontext?: TelemetryContext;\n}\n\nexport interface WatchHandle<TSnapshot> {\n\tsnapshot: TSnapshot;\n\tstart(listener: (event: unknown) => void): void;\n\tunsubscribe(): void;\n}\n\nexport interface AgentLane {\n\treadonly name: string;\n\tgetLeafId(): Promise<string | null>;\n\tprompt(text: string, images?: ImageContent[]): Promise<RunResult>;\n\tprompt(message: AgentMessage | AgentMessage[]): Promise<RunResult>;\n\tskill(name: string, additionalInstructions?: string): Promise<RunResult>;\n\tpromptFromTemplate(name: string, args?: string[]): Promise<RunResult>;\n\tcompact(options?: { customInstructions?: string }): Promise<CompactionResult>;\n\tnavigateTree(targetId: string | null, options?: NavigateOptions): Promise<NavigationResult>;\n\tresume(): Promise<ResumeResult>;\n\tabort(): Promise<AbortResult>;\n\tsteer(text: string, images?: ImageContent[]): Promise<QueueResult>;\n\tsteer(message: AgentMessage): Promise<QueueResult>;\n\tfollowUp(text: string, images?: ImageContent[]): Promise<QueueResult>;\n\tfollowUp(message: AgentMessage): Promise<QueueResult>;\n\tnextRun(text: string, images?: ImageContent[]): Promise<QueueResult>;\n\tnextRun(message: AgentMessage): Promise<QueueResult>;\n\tcancelQueued(entryId: string): Promise<CancelQueuedResult>;\n\trecordUsage(usage: Usage, options?: { entryId?: string; details?: JsonValue }): Promise<RecordUsageResult>;\n\twaitForIdle(): Promise<void>;\n\trunWhenIdle(callback: () => void | Promise<void>): Promise<void>;\n\tpeekAction(): Promise<ActionInfo | undefined>;\n\texecuteAction(): Promise<ActionInfo | undefined>;\n\trunToCompletion(): Promise<void>;\n\tgetModel(): Promise<Model<Api>>;\n\tsetModel(model: Model<Api>): Promise<void>;\n\tgetThinkingLevel(): Promise<ThinkingLevel>;\n\tsetThinkingLevel(level: ThinkingLevel): Promise<void>;\n\tgetActiveTools(): Promise<string[]>;\n\tsetActiveTools(names: string[]): Promise<void>;\n\treadonly session: SessionTree;\n\twatch(): Promise<WatchHandle<LaneSnapshot>>;\n}\n\nexport class AgentHarness implements AgentLane {\n\treadonly name = \"main\";\n\treadonly session: SessionTree;\n\treadonly hooks: Hooks;\n\treadonly events: Events;\n\tprivate readonly durableSession: Session;\n\tprivate model: Model<Api>;\n\tprivate thinkingLevel: ThinkingLevel;\n\tprivate activeToolNames: string[];\n\tprivate tools: HarnessTool[];\n\tprivate resources: Resources;\n\tprivate streamOptions: StreamOptions;\n\tprivate retryPolicy: RetryPolicy;\n\tprivate compactionSettings: CompactionSettings;\n\tprivate steeringMode: QueueMode;\n\tprivate followUpMode: QueueMode;\n\tprivate closed = false;\n\n\tprivate constructor(options: AgentHarnessOptions) {\n\t\tthis.durableSession = options.session;\n\t\tthis.session = options.session;\n\t\tthis.hooks = new UnavailableRegistry(\"hooks.on\", () => this.closed);\n\t\tthis.events = new UnavailableRegistry(\"events.on\", () => this.closed);\n\t\tthis.model = options.model;\n\t\tthis.thinkingLevel = options.thinkingLevel ?? \"off\";\n\t\tthis.activeToolNames = [...(options.activeToolNames ?? options.tools?.map((tool) => tool.name) ?? [])];\n\t\tthis.tools = [...(options.tools ?? [])];\n\t\tthis.resources = {\n\t\t\tskills: options.resources?.skills ? [...options.resources.skills] : undefined,\n\t\t\tpromptTemplates: options.resources?.promptTemplates ? [...options.resources.promptTemplates] : undefined,\n\t\t};\n\t\tthis.streamOptions = { ...(options.streamOptions ?? {}) };\n\t\tthis.retryPolicy = options.retry ?? { enabled: false, maxRetries: 0, baseDelayMs: 1000 };\n\t\tthis.compactionSettings = options.compaction ?? {\n\t\t\tenabled: true,\n\t\t\treserveTokens: 16384,\n\t\t\tkeepRecentTokens: 20000,\n\t\t};\n\t\tthis.steeringMode = options.steeringMode ?? \"one-at-a-time\";\n\t\tthis.followUpMode = options.followUpMode ?? \"one-at-a-time\";\n\t}\n\n\tstatic async create(\n\t\toptions: AgentHarnessOptions,\n\t): Promise<{ harness: AgentHarness; suspended: SuspendedOperation[] }> {\n\t\tconst [record] = await options.session.findRecords({ limit: 1 });\n\t\tif (record !== undefined) throw new HarnessNotImplemented(\"create.restore\");\n\t\treturn { harness: new AgentHarness(options), suspended: [] };\n\t}\n\n\tprivate unavailable<T>(operation: string): Promise<T> {\n\t\treturn Promise.reject(this.closed ? new HarnessClosed() : new HarnessNotImplemented(operation));\n\t}\n\n\tasync getLeafId(): Promise<string | null> {\n\t\treturn this.durableSession.getLeafId();\n\t}\n\n\tasync prompt(_text: string, _images?: ImageContent[]): Promise<RunResult>;\n\tasync prompt(_message: AgentMessage | AgentMessage[]): Promise<RunResult>;\n\tasync prompt(_input: string | AgentMessage | AgentMessage[], _images?: ImageContent[]): Promise<RunResult> {\n\t\treturn this.unavailable(\"prompt\");\n\t}\n\tasync skill(_name: string, _additionalInstructions?: string): Promise<RunResult> {\n\t\treturn this.unavailable(\"skill\");\n\t}\n\tasync promptFromTemplate(_name: string, _args?: string[]): Promise<RunResult> {\n\t\treturn this.unavailable(\"promptFromTemplate\");\n\t}\n\tasync compact(_options?: { customInstructions?: string }): Promise<CompactionResult> {\n\t\treturn this.unavailable(\"compact\");\n\t}\n\tasync navigateTree(_targetId: string | null, _options?: NavigateOptions): Promise<NavigationResult> {\n\t\treturn this.unavailable(\"navigateTree\");\n\t}\n\tasync resume(): Promise<ResumeResult> {\n\t\treturn this.unavailable(\"resume\");\n\t}\n\tasync abort(): Promise<AbortResult> {\n\t\treturn this.unavailable(\"abort\");\n\t}\n\tasync steer(_text: string, _images?: ImageContent[]): Promise<QueueResult>;\n\tasync steer(_message: AgentMessage): Promise<QueueResult>;\n\tasync steer(_input: string | AgentMessage, _images?: ImageContent[]): Promise<QueueResult> {\n\t\treturn this.unavailable(\"steer\");\n\t}\n\tasync followUp(_text: string, _images?: ImageContent[]): Promise<QueueResult>;\n\tasync followUp(_message: AgentMessage): Promise<QueueResult>;\n\tasync followUp(_input: string | AgentMessage, _images?: ImageContent[]): Promise<QueueResult> {\n\t\treturn this.unavailable(\"followUp\");\n\t}\n\tasync nextRun(_text: string, _images?: ImageContent[]): Promise<QueueResult>;\n\tasync nextRun(_message: AgentMessage): Promise<QueueResult>;\n\tasync nextRun(_input: string | AgentMessage, _images?: ImageContent[]): Promise<QueueResult> {\n\t\treturn this.unavailable(\"nextRun\");\n\t}\n\tasync cancelQueued(_entryId: string): Promise<CancelQueuedResult> {\n\t\treturn this.unavailable(\"cancelQueued\");\n\t}\n\tasync recordUsage(_usage: Usage, _options?: { entryId?: string; details?: JsonValue }): Promise<RecordUsageResult> {\n\t\treturn this.unavailable(\"recordUsage\");\n\t}\n\tasync waitForIdle(): Promise<void> {\n\t\treturn this.unavailable(\"waitForIdle\");\n\t}\n\tasync runWhenIdle(_callback: () => void | Promise<void>): Promise<void> {\n\t\treturn this.unavailable(\"runWhenIdle\");\n\t}\n\tasync peekAction(): Promise<ActionInfo | undefined> {\n\t\treturn this.unavailable(\"peekAction\");\n\t}\n\tasync executeAction(): Promise<ActionInfo | undefined> {\n\t\treturn this.unavailable(\"executeAction\");\n\t}\n\tasync runToCompletion(): Promise<void> {\n\t\treturn this.unavailable(\"runToCompletion\");\n\t}\n\tasync getModel(): Promise<Model<Api>> {\n\t\treturn this.model;\n\t}\n\tasync setModel(model: Model<Api>): Promise<void> {\n\t\tthis.model = model;\n\t}\n\tasync getThinkingLevel(): Promise<ThinkingLevel> {\n\t\treturn this.thinkingLevel;\n\t}\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tthis.thinkingLevel = level;\n\t}\n\tasync getActiveTools(): Promise<string[]> {\n\t\treturn [...this.activeToolNames];\n\t}\n\tasync setActiveTools(names: string[]): Promise<void> {\n\t\tthis.activeToolNames = [...names];\n\t}\n\tasync watch(): Promise<WatchHandle<LaneSnapshot>> {\n\t\treturn this.unavailable(\"watch\");\n\t}\n\n\tasync lane(_name: string): Promise<AgentLane | undefined> {\n\t\treturn this.unavailable(\"lane\");\n\t}\n\tasync createLane(_name: string, _at: string | null): Promise<CreateLaneResult> {\n\t\treturn this.unavailable(\"createLane\");\n\t}\n\tasync lanes(): Promise<LaneInfo[]> {\n\t\treturn this.unavailable(\"lanes\");\n\t}\n\tasync getTools(): Promise<HarnessTool[]> {\n\t\treturn [...this.tools];\n\t}\n\tasync setTools(tools: HarnessTool[], activeNames?: string[]): Promise<void> {\n\t\tthis.tools = [...tools];\n\t\tthis.activeToolNames = [...(activeNames ?? tools.map((tool) => tool.name))];\n\t}\n\tasync getResources(): Promise<Resources> {\n\t\treturn {\n\t\t\tskills: this.resources.skills ? [...this.resources.skills] : undefined,\n\t\t\tpromptTemplates: this.resources.promptTemplates ? [...this.resources.promptTemplates] : undefined,\n\t\t};\n\t}\n\tasync setResources(resources: Resources): Promise<void> {\n\t\tthis.resources = {\n\t\t\tskills: resources.skills ? [...resources.skills] : undefined,\n\t\t\tpromptTemplates: resources.promptTemplates ? [...resources.promptTemplates] : undefined,\n\t\t};\n\t}\n\tasync getStreamOptions(): Promise<StreamOptions> {\n\t\treturn { ...this.streamOptions };\n\t}\n\tasync setStreamOptions(options: StreamOptions): Promise<void> {\n\t\tthis.streamOptions = { ...options };\n\t}\n\tasync getRetryPolicy(): Promise<RetryPolicy> {\n\t\treturn { ...this.retryPolicy };\n\t}\n\tasync setRetryPolicy(policy: RetryPolicy): Promise<void> {\n\t\tthis.retryPolicy = { ...policy };\n\t}\n\tasync getCompactionSettings(): Promise<CompactionSettings> {\n\t\treturn { ...this.compactionSettings };\n\t}\n\tasync setCompactionSettings(settings: CompactionSettings): Promise<void> {\n\t\tthis.compactionSettings = { ...settings };\n\t}\n\tasync getSteeringMode(): Promise<QueueMode> {\n\t\treturn this.steeringMode;\n\t}\n\tasync setSteeringMode(mode: QueueMode): Promise<void> {\n\t\tthis.steeringMode = mode;\n\t}\n\tasync getFollowUpMode(): Promise<QueueMode> {\n\t\treturn this.followUpMode;\n\t}\n\tasync setFollowUpMode(mode: QueueMode): Promise<void> {\n\t\tthis.followUpMode = mode;\n\t}\n\tasync watchSession(): Promise<WatchHandle<SessionSnapshot>> {\n\t\treturn this.unavailable(\"watchSession\");\n\t}\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type Api, type Model, type Models, type RetryCallbacks, type RetryPolicy, type Usage } from "@sammorrowdrums/mcpi-ai";
|
|
2
|
+
import type { AgentMessage } from "../../types.ts";
|
|
3
|
+
import { type Entry, type Session } from "../session/index.ts";
|
|
4
|
+
import { BranchSummaryError, type Result } from "../types.ts";
|
|
5
|
+
import { type FileOperations } from "./utils.ts";
|
|
6
|
+
/** Generated branch summary data ready to be persisted as a branch-summary entry. */
|
|
7
|
+
export interface BranchSummaryResult {
|
|
8
|
+
summary: string;
|
|
9
|
+
usage?: Usage;
|
|
10
|
+
readFiles: string[];
|
|
11
|
+
modifiedFiles: string[];
|
|
12
|
+
}
|
|
13
|
+
/** File-operation details stored on generated branch summary entries. */
|
|
14
|
+
export interface BranchSummaryDetails {
|
|
15
|
+
/** Files read while exploring the summarized branch. */
|
|
16
|
+
readFiles: string[];
|
|
17
|
+
/** Files modified while exploring the summarized branch. */
|
|
18
|
+
modifiedFiles: string[];
|
|
19
|
+
}
|
|
20
|
+
export type { FileOperations } from "./utils.ts";
|
|
21
|
+
/** Prepared branch content for summarization. */
|
|
22
|
+
export interface BranchPreparation {
|
|
23
|
+
/** Messages selected for the branch summary. */
|
|
24
|
+
messages: AgentMessage[];
|
|
25
|
+
/** File operations extracted from the branch. */
|
|
26
|
+
fileOps: FileOperations;
|
|
27
|
+
/** Estimated token count for selected messages. */
|
|
28
|
+
totalTokens: number;
|
|
29
|
+
}
|
|
30
|
+
/** Entries selected for branch summarization. */
|
|
31
|
+
export interface CollectEntriesResult {
|
|
32
|
+
/** Entries to summarize in chronological order. */
|
|
33
|
+
entries: Entry[];
|
|
34
|
+
/** Deepest common ancestor between the previous leaf and target entry. */
|
|
35
|
+
commonAncestorId: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** Options for generating a branch summary. */
|
|
38
|
+
export interface GenerateBranchSummaryOptions {
|
|
39
|
+
/** Provider collection the summarization request goes through; owns auth resolution. */
|
|
40
|
+
models: Models;
|
|
41
|
+
/** Model used for summarization. */
|
|
42
|
+
model: Model<Api>;
|
|
43
|
+
/** Abort signal for the summarization request. */
|
|
44
|
+
signal: AbortSignal;
|
|
45
|
+
/** Optional instructions appended to or replacing the default prompt. */
|
|
46
|
+
customInstructions?: string;
|
|
47
|
+
/** Replace the default prompt with custom instructions instead of appending them. */
|
|
48
|
+
replaceInstructions?: boolean;
|
|
49
|
+
/** Tokens reserved for prompt and model output. Defaults to 16384. */
|
|
50
|
+
reserveTokens?: number;
|
|
51
|
+
/** Optional retry policy for transient summarization errors. */
|
|
52
|
+
retry?: RetryPolicy;
|
|
53
|
+
/** Optional callbacks for retry reporting. */
|
|
54
|
+
callbacks?: RetryCallbacks;
|
|
55
|
+
}
|
|
56
|
+
/** Collect entries that should be summarized before navigating to a different session tree entry. */
|
|
57
|
+
export declare function collectEntriesForBranchSummary(session: Session, oldLeafId: string | null, targetId: string): Promise<CollectEntriesResult>;
|
|
58
|
+
/** Prepare branch entries for summarization within an optional token budget. */
|
|
59
|
+
export declare function prepareBranchEntries(entries: Entry[], tokenBudget?: number): BranchPreparation;
|
|
60
|
+
/** Generate a summary for abandoned branch entries. */
|
|
61
|
+
export declare function generateBranchSummary(entries: Entry[], options: GenerateBranchSummaryOptions): Promise<Result<BranchSummaryResult, BranchSummaryError>>;
|
|
62
|
+
//# sourceMappingURL=branch-summarization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../../src/harness/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,GAAG,EAER,KAAK,KAAK,EACV,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AAEpB,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACpC,wDAAwD;IACxD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IACjC,gDAAgD;IAChD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,iDAAiD;IACjD,OAAO,EAAE,cAAc,CAAC;IACxB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,KAAK,EAAE,CAAC;IACjB,0EAA0E;IAC1E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,+CAA+C;AAC/C,MAAM,WAAW,4BAA4B;IAC5C,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,kDAAkD;IAClD,MAAM,EAAE,WAAW,CAAC;IACpB,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,qGAAqG;AACrG,wBAAsB,8BAA8B,CACnD,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CAyB/B;AAoBD,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CAuCjG;AAoCD,uDAAuD;AACvD,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,KAAK,EAAE,EAChB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC,CAqE1D","sourcesContent":["import {\n\ttype Api,\n\tcontentText,\n\ttype Model,\n\ttype Models,\n\ttype RetryCallbacks,\n\ttype RetryPolicy,\n\ttype Usage,\n} from \"@sammorrowdrums/mcpi-ai\";\n\nimport type { AgentMessage } from \"../../types.ts\";\nimport { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage } from \"../messages.ts\";\nimport { type Entry, type Session, SessionError } from \"../session/index.ts\";\nimport { BranchSummaryError, err, ok, type Result } from \"../types.ts\";\nimport { completeSimpleWithRetries, estimateTokens, SUMMARIZATION_SYSTEM_PROMPT } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n/** Generated branch summary data ready to be persisted as a branch-summary entry. */\nexport interface BranchSummaryResult {\n\tsummary: string;\n\tusage?: Usage;\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\n/** File-operation details stored on generated branch summary entries. */\nexport interface BranchSummaryDetails {\n\t/** Files read while exploring the summarized branch. */\n\treadFiles: string[];\n\t/** Files modified while exploring the summarized branch. */\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\n/** Prepared branch content for summarization. */\nexport interface BranchPreparation {\n\t/** Messages selected for the branch summary. */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from the branch. */\n\tfileOps: FileOperations;\n\t/** Estimated token count for selected messages. */\n\ttotalTokens: number;\n}\n\n/** Entries selected for branch summarization. */\nexport interface CollectEntriesResult {\n\t/** Entries to summarize in chronological order. */\n\tentries: Entry[];\n\t/** Deepest common ancestor between the previous leaf and target entry. */\n\tcommonAncestorId: string | null;\n}\n\n/** Options for generating a branch summary. */\nexport interface GenerateBranchSummaryOptions {\n\t/** Provider collection the summarization request goes through; owns auth resolution. */\n\tmodels: Models;\n\t/** Model used for summarization. */\n\tmodel: Model<Api>;\n\t/** Abort signal for the summarization request. */\n\tsignal: AbortSignal;\n\t/** Optional instructions appended to or replacing the default prompt. */\n\tcustomInstructions?: string;\n\t/** Replace the default prompt with custom instructions instead of appending them. */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved for prompt and model output. Defaults to 16384. */\n\treserveTokens?: number;\n\t/** Optional retry policy for transient summarization errors. */\n\tretry?: RetryPolicy;\n\t/** Optional callbacks for retry reporting. */\n\tcallbacks?: RetryCallbacks;\n}\n\n/** Collect entries that should be summarized before navigating to a different session tree entry. */\nexport async function collectEntriesForBranchSummary(\n\tsession: Session,\n\toldLeafId: string | null,\n\ttargetId: string,\n): Promise<CollectEntriesResult> {\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\tconst oldPath = new Set((await session.findEntriesOnBranch({ start: oldLeafId })).map((entry) => entry.id));\n\tconst targetPath = await session.findEntriesOnBranch({ start: targetId });\n\tlet commonAncestorId: string | null = null;\n\tfor (const entry of targetPath) {\n\t\tif (oldPath.has(entry.id)) {\n\t\t\tcommonAncestorId = entry.id;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst entries: Entry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = await session.getEntry(current);\n\t\tif (!entry) throw new SessionError(\"invalid_entry\", `Entry ${current} not found`);\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\nfunction getMessageFromEntry(entry: Entry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"active_tools_change\":\n\t\tcase \"custom\":\n\t\t\treturn undefined;\n\t}\n}\n\n/** Prepare branch entries for summarization within an optional token budget. */\nexport function prepareBranchEntries(entries: Entry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\nconst BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.\n\nUse this EXACT format:\n\n## Goal\n[What was the user trying to accomplish in this branch?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Work that was started but not finished]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [What should happen next to continue this work]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\n/** Generate a summary for abandoned branch entries. */\nexport async function generateBranchSummary(\n\tentries: Entry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<Result<BranchSummaryResult, BranchSummaryError>> {\n\tconst {\n\t\tmodels,\n\t\tmodel,\n\t\tsignal,\n\t\tcustomInstructions,\n\t\treplaceInstructions,\n\t\treserveTokens = 16384,\n\t\tretry,\n\t\tcallbacks,\n\t} = options;\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn ok({ summary: \"No content to summarize\", readFiles: [], modifiedFiles: [] });\n\t}\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst summarizationMessages = [\n\t\t{\n\t\t\trole: \"user\" as const,\n\t\t\tcontent: [{ type: \"text\" as const, text: promptText }],\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t];\n\tconst response = await completeSimpleWithRetries(\n\t\tmodels,\n\t\tmodel,\n\t\t{ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n\t\t{ signal, maxTokens: 2048 },\n\t\tretry,\n\t\tcallbacks,\n\t);\n\tif (response.stopReason === \"aborted\") {\n\t\treturn err(new BranchSummaryError(\"aborted\", response.errorMessage || \"Branch summary aborted\"));\n\t}\n\tif (response.stopReason === \"error\") {\n\t\treturn err(\n\t\t\tnew BranchSummaryError(\n\t\t\t\t\"summarization_failed\",\n\t\t\t\t`Branch summary failed: ${response.errorMessage || \"Unknown error\"}`,\n\t\t\t),\n\t\t);\n\t}\n\n\tlet summary = contentText(response.content);\n\tsummary = BRANCH_SUMMARY_PREAMBLE + summary;\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn ok({\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: response.usage,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t});\n}\n"]}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { contentText, } from "@sammorrowdrums/mcpi-ai";
|
|
2
|
+
import { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage } from "../messages.js";
|
|
3
|
+
import { SessionError } from "../session/index.js";
|
|
4
|
+
import { BranchSummaryError, err, ok } from "../types.js";
|
|
5
|
+
import { completeSimpleWithRetries, 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 session tree entry. */
|
|
8
|
+
export async function collectEntriesForBranchSummary(session, oldLeafId, targetId) {
|
|
9
|
+
if (!oldLeafId) {
|
|
10
|
+
return { entries: [], commonAncestorId: null };
|
|
11
|
+
}
|
|
12
|
+
const oldPath = new Set((await session.findEntriesOnBranch({ start: oldLeafId })).map((entry) => entry.id));
|
|
13
|
+
const targetPath = await session.findEntriesOnBranch({ start: targetId });
|
|
14
|
+
let commonAncestorId = null;
|
|
15
|
+
for (const entry of targetPath) {
|
|
16
|
+
if (oldPath.has(entry.id)) {
|
|
17
|
+
commonAncestorId = entry.id;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const entries = [];
|
|
22
|
+
let current = oldLeafId;
|
|
23
|
+
while (current && current !== commonAncestorId) {
|
|
24
|
+
const entry = await session.getEntry(current);
|
|
25
|
+
if (!entry)
|
|
26
|
+
throw new SessionError("invalid_entry", `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 "branch_summary":
|
|
40
|
+
return createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);
|
|
41
|
+
case "compaction":
|
|
42
|
+
return createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);
|
|
43
|
+
case "thinking_level_change":
|
|
44
|
+
case "model_change":
|
|
45
|
+
case "active_tools_change":
|
|
46
|
+
case "custom":
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Prepare branch entries for summarization within an optional token budget. */
|
|
51
|
+
export function prepareBranchEntries(entries, tokenBudget = 0) {
|
|
52
|
+
const messages = [];
|
|
53
|
+
const fileOps = createFileOps();
|
|
54
|
+
let totalTokens = 0;
|
|
55
|
+
for (const entry of entries) {
|
|
56
|
+
if (entry.type === "branch_summary" && entry.details) {
|
|
57
|
+
const details = entry.details;
|
|
58
|
+
if (Array.isArray(details.readFiles)) {
|
|
59
|
+
for (const f of details.readFiles)
|
|
60
|
+
fileOps.read.add(f);
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(details.modifiedFiles)) {
|
|
63
|
+
for (const f of details.modifiedFiles) {
|
|
64
|
+
fileOps.edited.add(f);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
70
|
+
const entry = entries[i];
|
|
71
|
+
const message = getMessageFromEntry(entry);
|
|
72
|
+
if (!message)
|
|
73
|
+
continue;
|
|
74
|
+
extractFileOpsFromMessage(message, fileOps);
|
|
75
|
+
const tokens = estimateTokens(message);
|
|
76
|
+
if (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {
|
|
77
|
+
if (entry.type === "compaction" || entry.type === "branch_summary") {
|
|
78
|
+
if (totalTokens < tokenBudget * 0.9) {
|
|
79
|
+
messages.unshift(message);
|
|
80
|
+
totalTokens += tokens;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
messages.unshift(message);
|
|
86
|
+
totalTokens += tokens;
|
|
87
|
+
}
|
|
88
|
+
return { messages, fileOps, totalTokens };
|
|
89
|
+
}
|
|
90
|
+
const BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.
|
|
91
|
+
Summary of that exploration:
|
|
92
|
+
|
|
93
|
+
`;
|
|
94
|
+
const BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.
|
|
95
|
+
|
|
96
|
+
Use this EXACT format:
|
|
97
|
+
|
|
98
|
+
## Goal
|
|
99
|
+
[What was the user trying to accomplish in this branch?]
|
|
100
|
+
|
|
101
|
+
## Constraints & Preferences
|
|
102
|
+
- [Any constraints, preferences, or requirements mentioned]
|
|
103
|
+
- [Or "(none)" if none were mentioned]
|
|
104
|
+
|
|
105
|
+
## Progress
|
|
106
|
+
### Done
|
|
107
|
+
- [x] [Completed tasks/changes]
|
|
108
|
+
|
|
109
|
+
### In Progress
|
|
110
|
+
- [ ] [Work that was started but not finished]
|
|
111
|
+
|
|
112
|
+
### Blocked
|
|
113
|
+
- [Issues preventing progress, if any]
|
|
114
|
+
|
|
115
|
+
## Key Decisions
|
|
116
|
+
- **[Decision]**: [Brief rationale]
|
|
117
|
+
|
|
118
|
+
## Next Steps
|
|
119
|
+
1. [What should happen next to continue this work]
|
|
120
|
+
|
|
121
|
+
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
|
|
122
|
+
/** Generate a summary for abandoned branch entries. */
|
|
123
|
+
export async function generateBranchSummary(entries, options) {
|
|
124
|
+
const { models, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384, retry, callbacks, } = options;
|
|
125
|
+
const contextWindow = model.contextWindow || 128000;
|
|
126
|
+
const tokenBudget = contextWindow - reserveTokens;
|
|
127
|
+
const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);
|
|
128
|
+
if (messages.length === 0) {
|
|
129
|
+
return ok({ summary: "No content to summarize", readFiles: [], modifiedFiles: [] });
|
|
130
|
+
}
|
|
131
|
+
const llmMessages = convertToLlm(messages);
|
|
132
|
+
const conversationText = serializeConversation(llmMessages);
|
|
133
|
+
let instructions;
|
|
134
|
+
if (replaceInstructions && customInstructions) {
|
|
135
|
+
instructions = customInstructions;
|
|
136
|
+
}
|
|
137
|
+
else if (customInstructions) {
|
|
138
|
+
instructions = `${BRANCH_SUMMARY_PROMPT}\n\nAdditional focus: ${customInstructions}`;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
instructions = BRANCH_SUMMARY_PROMPT;
|
|
142
|
+
}
|
|
143
|
+
const promptText = `<conversation>\n${conversationText}\n</conversation>\n\n${instructions}`;
|
|
144
|
+
const summarizationMessages = [
|
|
145
|
+
{
|
|
146
|
+
role: "user",
|
|
147
|
+
content: [{ type: "text", text: promptText }],
|
|
148
|
+
timestamp: Date.now(),
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
const response = await completeSimpleWithRetries(models, model, { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }, { signal, maxTokens: 2048 }, retry, callbacks);
|
|
152
|
+
if (response.stopReason === "aborted") {
|
|
153
|
+
return err(new BranchSummaryError("aborted", response.errorMessage || "Branch summary aborted"));
|
|
154
|
+
}
|
|
155
|
+
if (response.stopReason === "error") {
|
|
156
|
+
return err(new BranchSummaryError("summarization_failed", `Branch summary failed: ${response.errorMessage || "Unknown error"}`));
|
|
157
|
+
}
|
|
158
|
+
let summary = contentText(response.content);
|
|
159
|
+
summary = BRANCH_SUMMARY_PREAMBLE + summary;
|
|
160
|
+
const { readFiles, modifiedFiles } = computeFileLists(fileOps);
|
|
161
|
+
summary += formatFileOperations(readFiles, modifiedFiles);
|
|
162
|
+
return ok({
|
|
163
|
+
summary: summary || "No summary generated",
|
|
164
|
+
usage: response.usage,
|
|
165
|
+
readFiles,
|
|
166
|
+
modifiedFiles,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//# 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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","sourcesContent":["import {\n\ttype Api,\n\tcontentText,\n\ttype Model,\n\ttype Models,\n\ttype RetryCallbacks,\n\ttype RetryPolicy,\n\ttype Usage,\n} from \"@sammorrowdrums/mcpi-ai\";\n\nimport type { AgentMessage } from \"../../types.ts\";\nimport { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage } from \"../messages.ts\";\nimport { type Entry, type Session, SessionError } from \"../session/index.ts\";\nimport { BranchSummaryError, err, ok, type Result } from \"../types.ts\";\nimport { completeSimpleWithRetries, estimateTokens, SUMMARIZATION_SYSTEM_PROMPT } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n/** Generated branch summary data ready to be persisted as a branch-summary entry. */\nexport interface BranchSummaryResult {\n\tsummary: string;\n\tusage?: Usage;\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\n/** File-operation details stored on generated branch summary entries. */\nexport interface BranchSummaryDetails {\n\t/** Files read while exploring the summarized branch. */\n\treadFiles: string[];\n\t/** Files modified while exploring the summarized branch. */\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\n/** Prepared branch content for summarization. */\nexport interface BranchPreparation {\n\t/** Messages selected for the branch summary. */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from the branch. */\n\tfileOps: FileOperations;\n\t/** Estimated token count for selected messages. */\n\ttotalTokens: number;\n}\n\n/** Entries selected for branch summarization. */\nexport interface CollectEntriesResult {\n\t/** Entries to summarize in chronological order. */\n\tentries: Entry[];\n\t/** Deepest common ancestor between the previous leaf and target entry. */\n\tcommonAncestorId: string | null;\n}\n\n/** Options for generating a branch summary. */\nexport interface GenerateBranchSummaryOptions {\n\t/** Provider collection the summarization request goes through; owns auth resolution. */\n\tmodels: Models;\n\t/** Model used for summarization. */\n\tmodel: Model<Api>;\n\t/** Abort signal for the summarization request. */\n\tsignal: AbortSignal;\n\t/** Optional instructions appended to or replacing the default prompt. */\n\tcustomInstructions?: string;\n\t/** Replace the default prompt with custom instructions instead of appending them. */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved for prompt and model output. Defaults to 16384. */\n\treserveTokens?: number;\n\t/** Optional retry policy for transient summarization errors. */\n\tretry?: RetryPolicy;\n\t/** Optional callbacks for retry reporting. */\n\tcallbacks?: RetryCallbacks;\n}\n\n/** Collect entries that should be summarized before navigating to a different session tree entry. */\nexport async function collectEntriesForBranchSummary(\n\tsession: Session,\n\toldLeafId: string | null,\n\ttargetId: string,\n): Promise<CollectEntriesResult> {\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\tconst oldPath = new Set((await session.findEntriesOnBranch({ start: oldLeafId })).map((entry) => entry.id));\n\tconst targetPath = await session.findEntriesOnBranch({ start: targetId });\n\tlet commonAncestorId: string | null = null;\n\tfor (const entry of targetPath) {\n\t\tif (oldPath.has(entry.id)) {\n\t\t\tcommonAncestorId = entry.id;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst entries: Entry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = await session.getEntry(current);\n\t\tif (!entry) throw new SessionError(\"invalid_entry\", `Entry ${current} not found`);\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\nfunction getMessageFromEntry(entry: Entry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"active_tools_change\":\n\t\tcase \"custom\":\n\t\t\treturn undefined;\n\t}\n}\n\n/** Prepare branch entries for summarization within an optional token budget. */\nexport function prepareBranchEntries(entries: Entry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\nconst BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.\n\nUse this EXACT format:\n\n## Goal\n[What was the user trying to accomplish in this branch?]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Work that was started but not finished]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [What should happen next to continue this work]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\n/** Generate a summary for abandoned branch entries. */\nexport async function generateBranchSummary(\n\tentries: Entry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<Result<BranchSummaryResult, BranchSummaryError>> {\n\tconst {\n\t\tmodels,\n\t\tmodel,\n\t\tsignal,\n\t\tcustomInstructions,\n\t\treplaceInstructions,\n\t\treserveTokens = 16384,\n\t\tretry,\n\t\tcallbacks,\n\t} = options;\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn ok({ summary: \"No content to summarize\", readFiles: [], modifiedFiles: [] });\n\t}\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst summarizationMessages = [\n\t\t{\n\t\t\trole: \"user\" as const,\n\t\t\tcontent: [{ type: \"text\" as const, text: promptText }],\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t];\n\tconst response = await completeSimpleWithRetries(\n\t\tmodels,\n\t\tmodel,\n\t\t{ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n\t\t{ signal, maxTokens: 2048 },\n\t\tretry,\n\t\tcallbacks,\n\t);\n\tif (response.stopReason === \"aborted\") {\n\t\treturn err(new BranchSummaryError(\"aborted\", response.errorMessage || \"Branch summary aborted\"));\n\t}\n\tif (response.stopReason === \"error\") {\n\t\treturn err(\n\t\t\tnew BranchSummaryError(\n\t\t\t\t\"summarization_failed\",\n\t\t\t\t`Branch summary failed: ${response.errorMessage || \"Unknown error\"}`,\n\t\t\t),\n\t\t);\n\t}\n\n\tlet summary = contentText(response.content);\n\tsummary = BRANCH_SUMMARY_PREAMBLE + summary;\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn ok({\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: response.usage,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t});\n}\n"]}
|