@cuylabs/agent-core 0.9.0 → 0.10.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/README.md +33 -17
- package/dist/chunk-2O4MCSQS.js +780 -0
- package/dist/chunk-2TTOLHBT.js +198 -0
- package/dist/chunk-5FMSGQVX.js +281 -0
- package/dist/chunk-5NVVNXPQ.js +288 -0
- package/dist/{chunk-EKR6PKXU.js → chunk-6HZBHFOL.js} +3 -3
- package/dist/chunk-CJI7PVS2.js +58 -0
- package/dist/{chunk-WKHDSSXG.js → chunk-CMYN2RCB.js} +146 -46
- package/dist/chunk-FII65CN7.js +117 -0
- package/dist/{chunk-UHCJEM2E.js → chunk-ICZ66572.js} +13 -6
- package/dist/chunk-KYLPMBHD.js +316 -0
- package/dist/chunk-MXAP4UG6.js +2956 -0
- package/dist/{chunk-4QFNWPIF.js → chunk-N3VX7FEE.js} +35 -2
- package/dist/{chunk-MAZ5DY5B.js → chunk-NDZWXCBZ.js} +213 -78
- package/dist/{chunk-MHKK374K.js → chunk-Q742PSH3.js} +11 -27
- package/dist/{chunk-WGZAPU6N.js → chunk-QAL3OMI3.js} +15 -1
- package/dist/{chunk-UDCZ673N.js → chunk-RN6WZEUF.js} +27 -23
- package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
- package/dist/chunk-SPBFQXOT.js +0 -0
- package/dist/chunk-SSFBF3US.js +602 -0
- package/dist/chunk-SZ2XBPTW.js +8 -0
- package/dist/chunk-T4UIX5D7.js +115 -0
- package/dist/{chunk-IYWQOJMQ.js → chunk-TIHPYVAJ.js} +34 -34
- package/dist/{chunk-RKEW5WXI.js → chunk-TOTDGK3P.js} +1 -1
- package/dist/chunk-V4RFNEET.js +563 -0
- package/dist/chunk-VOUEJSW6.js +0 -0
- package/dist/{chunk-J4QDGZIA.js → chunk-WBPOZ7CL.js} +659 -275
- package/dist/chunk-X4VN4GIJ.js +185 -0
- package/dist/dispatch/index.d.ts +93 -0
- package/dist/dispatch/index.js +37 -0
- package/dist/events/index.d.ts +93 -0
- package/dist/events/index.js +6 -0
- package/dist/{runtime → execution}/index.d.ts +120 -35
- package/dist/{runtime → execution}/index.js +17 -11
- package/dist/index.d.ts +489 -115
- package/dist/index.js +1665 -462
- package/dist/inference/errors/index.js +1 -1
- package/dist/inference/index.d.ts +13 -21
- package/dist/inference/index.js +15 -12
- package/dist/instance-BqV2D5pc.d.ts +5723 -0
- package/dist/logger/index.d.ts +50 -0
- package/dist/logger/index.js +11 -0
- package/dist/mcp/index.d.ts +5 -9
- package/dist/mcp/index.js +2 -3
- package/dist/middleware/index.d.ts +10 -150
- package/dist/middleware/index.js +10 -2
- package/dist/model-messages-B4nK9D1-.d.ts +13 -0
- package/dist/models/index.d.ts +5 -2
- package/dist/models/index.js +2 -1
- package/dist/models/reasoning/index.js +2 -1
- package/dist/plugin/index.d.ts +55 -11
- package/dist/plugin/index.js +1 -1
- package/dist/profiles/index.d.ts +55 -0
- package/dist/{presets → profiles}/index.js +10 -10
- package/dist/prompt/index.d.ts +8 -13
- package/dist/safety/index.d.ts +109 -14
- package/dist/safety/index.js +59 -3
- package/dist/sandbox/index.d.ts +81 -0
- package/dist/sandbox/index.js +1 -0
- package/dist/skill/index.d.ts +10 -8
- package/dist/skill/index.js +2 -2
- package/dist/storage/index.d.ts +12 -4
- package/dist/storage/index.js +1 -1
- package/dist/subagents/index.d.ts +177 -0
- package/dist/subagents/index.js +78 -0
- package/dist/team/index.d.ts +544 -0
- package/dist/team/index.js +41 -0
- package/dist/tool/host/index.d.ts +41 -0
- package/dist/tool/host/index.js +10 -0
- package/dist/tool/index.d.ts +111 -21
- package/dist/tool/index.js +20 -13
- package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
- package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
- package/dist/types-RSCv7nQ4.d.ts +59 -0
- package/package.json +46 -47
- package/dist/builder-BgZ_j4Vs.d.ts +0 -35
- package/dist/chunk-5ARZJWD2.js +0 -259
- package/dist/chunk-DXFBQMXP.js +0 -53
- package/dist/chunk-H3FUYU52.js +0 -81
- package/dist/chunk-JLXG2SH7.js +0 -905
- package/dist/chunk-N7P4PN3O.js +0 -84
- package/dist/chunk-OFDKHNCX.js +0 -727
- package/dist/chunk-SDSBEQXG.js +0 -157
- package/dist/chunk-VEKUXUVF.js +0 -41
- package/dist/chunk-VNQBHPCT.js +0 -398
- package/dist/chunk-WWYYNWEW.js +0 -259
- package/dist/context/index.d.ts +0 -259
- package/dist/context/index.js +0 -26
- package/dist/events-CE72w8W4.d.ts +0 -149
- package/dist/host/index.d.ts +0 -45
- package/dist/host/index.js +0 -8
- package/dist/index-DQuTZ8xL.d.ts +0 -1335
- package/dist/messages-BYWGn8TY.d.ts +0 -110
- package/dist/presets/index.d.ts +0 -53
- package/dist/registry-DwYqsQkX.d.ts +0 -164
- package/dist/runner-CI-XeR16.d.ts +0 -91
- package/dist/scope/index.d.ts +0 -10
- package/dist/scope/index.js +0 -14
- package/dist/session-manager-KbYt2WUh.d.ts +0 -282
- package/dist/signal/index.d.ts +0 -28
- package/dist/signal/index.js +0 -6
- package/dist/sub-agent/index.d.ts +0 -24
- package/dist/sub-agent/index.js +0 -32
- package/dist/tool-CZWN3KbO.d.ts +0 -141
- package/dist/tool-DkhSCV2Y.d.ts +0 -145
- package/dist/tracker-DClqYqTj.d.ts +0 -96
- package/dist/tracking/index.d.ts +0 -111
- package/dist/tracking/index.js +0 -20
- package/dist/types-BfNpU8NS.d.ts +0 -270
- package/dist/types-BlOKk-Bb.d.ts +0 -330
- package/dist/types-BlZwmnuW.d.ts +0 -50
- package/dist/types-CQL-SvTn.d.ts +0 -29
- package/dist/types-CWm-7rvB.d.ts +0 -55
- package/dist/types-DTSkxakL.d.ts +0 -651
- package/dist/types-DmDwi2zI.d.ts +0 -339
- package/dist/types-YuWV4ag7.d.ts +0 -72
package/dist/chunk-WWYYNWEW.js
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
// src/context/estimation.ts
|
|
2
|
-
function estimateTokens(text) {
|
|
3
|
-
return Math.ceil(text.length / 4);
|
|
4
|
-
}
|
|
5
|
-
function estimateMessageTokens(message) {
|
|
6
|
-
if (typeof message.content === "string") {
|
|
7
|
-
return estimateTokens(message.content);
|
|
8
|
-
}
|
|
9
|
-
if (Array.isArray(message.content)) {
|
|
10
|
-
let total = 0;
|
|
11
|
-
for (const part of message.content) {
|
|
12
|
-
if (typeof part === "string") {
|
|
13
|
-
total += estimateTokens(part);
|
|
14
|
-
} else if ("text" in part && typeof part.text === "string") {
|
|
15
|
-
total += estimateTokens(part.text);
|
|
16
|
-
} else if ("type" in part && part.type === "image") {
|
|
17
|
-
total += 765;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return total;
|
|
21
|
-
}
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
function estimateConversationTokens(messages) {
|
|
25
|
-
let total = 0;
|
|
26
|
-
for (const message of messages) {
|
|
27
|
-
total += estimateMessageTokens(message);
|
|
28
|
-
total += 4;
|
|
29
|
-
}
|
|
30
|
-
return total;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// src/agent/types/compaction.ts
|
|
34
|
-
var PRUNE_PROTECTED_TOOLS = ["skill"];
|
|
35
|
-
|
|
36
|
-
// src/context/pruning.ts
|
|
37
|
-
var DEFAULT_CONTEXT_LIMITS = {
|
|
38
|
-
contextWindow: 128e3,
|
|
39
|
-
reserveTokens: 16e3,
|
|
40
|
-
// Reserve for output
|
|
41
|
-
protectedTokens: 4e4,
|
|
42
|
-
// Keep recent 40 k tokens
|
|
43
|
-
pruneMinimum: 2e4
|
|
44
|
-
// Don't prune until 20 k tokens
|
|
45
|
-
};
|
|
46
|
-
function isContextOverflowing(tokens, limits = DEFAULT_CONTEXT_LIMITS) {
|
|
47
|
-
const threshold = limits.contextWindow - limits.reserveTokens;
|
|
48
|
-
return tokens > threshold;
|
|
49
|
-
}
|
|
50
|
-
function shouldPruneContext(tokens, limits = DEFAULT_CONTEXT_LIMITS) {
|
|
51
|
-
if (tokens < limits.pruneMinimum) return false;
|
|
52
|
-
return isContextOverflowing(tokens, limits);
|
|
53
|
-
}
|
|
54
|
-
function findCutPoint(messages, protectedTokens = DEFAULT_CONTEXT_LIMITS.protectedTokens) {
|
|
55
|
-
if (messages.length === 0) return 0;
|
|
56
|
-
let tokensFromEnd = 0;
|
|
57
|
-
let cutIndex = messages.length;
|
|
58
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
59
|
-
tokensFromEnd += estimateMessageTokens(messages[i]);
|
|
60
|
-
if (tokensFromEnd >= protectedTokens) {
|
|
61
|
-
cutIndex = i;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (cutIndex <= 1) return 0;
|
|
66
|
-
const startIndex = cutIndex >= messages.length ? messages.length - 1 : cutIndex;
|
|
67
|
-
for (let i = startIndex; i >= 1; i--) {
|
|
68
|
-
const msg = messages[i];
|
|
69
|
-
const prevMsg = messages[i - 1];
|
|
70
|
-
if (!msg || !prevMsg) continue;
|
|
71
|
-
if (msg.role === "tool") continue;
|
|
72
|
-
if (prevMsg.role === "assistant" || prevMsg.role === "user") {
|
|
73
|
-
return i;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return 0;
|
|
77
|
-
}
|
|
78
|
-
function pruneToolResults(messages, protectedTokens = DEFAULT_CONTEXT_LIMITS.protectedTokens, options) {
|
|
79
|
-
const protectedToolSet = /* @__PURE__ */ new Set([
|
|
80
|
-
...PRUNE_PROTECTED_TOOLS,
|
|
81
|
-
...options?.protectedTools ?? []
|
|
82
|
-
]);
|
|
83
|
-
let tokensFromEnd = 0;
|
|
84
|
-
const tokenPositions = [];
|
|
85
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
86
|
-
tokensFromEnd += estimateMessageTokens(messages[i]);
|
|
87
|
-
tokenPositions[i] = tokensFromEnd;
|
|
88
|
-
}
|
|
89
|
-
return messages.map((msg, i) => {
|
|
90
|
-
if (tokenPositions[i] < protectedTokens) return msg;
|
|
91
|
-
if (!("role" in msg) || msg.role !== "tool") return msg;
|
|
92
|
-
const toolMsg = msg;
|
|
93
|
-
if ("compactedAt" in toolMsg && toolMsg.compactedAt) return msg;
|
|
94
|
-
if (toolMsg.toolName && protectedToolSet.has(toolMsg.toolName)) return msg;
|
|
95
|
-
const currentTokens = estimateTokens(toolMsg.content);
|
|
96
|
-
if (currentTokens < 500) return msg;
|
|
97
|
-
return {
|
|
98
|
-
...toolMsg,
|
|
99
|
-
content: `[Output pruned - was ${currentTokens} tokens]`,
|
|
100
|
-
compactedAt: Date.now()
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// src/context/summarization.ts
|
|
106
|
-
import { generateText } from "ai";
|
|
107
|
-
var DEFAULT_SUMMARY_PROMPT = `You are summarizing a conversation to continue it with context.
|
|
108
|
-
|
|
109
|
-
Create a structured summary that captures:
|
|
110
|
-
1. **Goal**: What the user is trying to accomplish
|
|
111
|
-
2. **Progress**: What has been done so far
|
|
112
|
-
3. **Decisions**: Key decisions made during the conversation
|
|
113
|
-
4. **Current State**: Where we left off
|
|
114
|
-
5. **Next Steps**: What should happen next
|
|
115
|
-
|
|
116
|
-
Be concise but comprehensive. Include specific file paths, function names, and technical details that would be lost otherwise.
|
|
117
|
-
|
|
118
|
-
Format as a clear summary that could be given to another assistant to continue the work.`;
|
|
119
|
-
async function generateSummary(messages, options) {
|
|
120
|
-
const conversationText = messages.map((m) => {
|
|
121
|
-
const role = m.role.toUpperCase();
|
|
122
|
-
const content = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
|
|
123
|
-
return `[${role}]: ${content}`;
|
|
124
|
-
}).join("\n\n");
|
|
125
|
-
const prompt = options.customPrompt || DEFAULT_SUMMARY_PROMPT;
|
|
126
|
-
const { text } = await generateText({
|
|
127
|
-
model: options.model,
|
|
128
|
-
maxOutputTokens: options.maxTokens ?? 2e3,
|
|
129
|
-
system: prompt,
|
|
130
|
-
prompt: `Summarize this conversation:
|
|
131
|
-
|
|
132
|
-
${conversationText}`
|
|
133
|
-
});
|
|
134
|
-
return text;
|
|
135
|
-
}
|
|
136
|
-
async function pruneContext(messages, options = {}) {
|
|
137
|
-
const limits = options.limits ?? DEFAULT_CONTEXT_LIMITS;
|
|
138
|
-
let currentMessages = [...messages];
|
|
139
|
-
let tokensRemoved = 0;
|
|
140
|
-
let removedCount = 0;
|
|
141
|
-
let summarized = false;
|
|
142
|
-
let summary;
|
|
143
|
-
const initialTokens = estimateConversationTokens(currentMessages);
|
|
144
|
-
if (!shouldPruneContext(initialTokens, limits)) {
|
|
145
|
-
return { messages: currentMessages, removedCount: 0, tokensRemoved: 0, summarized: false };
|
|
146
|
-
}
|
|
147
|
-
const prunedMessages = pruneToolResults(currentMessages, limits.protectedTokens);
|
|
148
|
-
const afterPruneTokens = estimateConversationTokens(prunedMessages);
|
|
149
|
-
tokensRemoved = initialTokens - afterPruneTokens;
|
|
150
|
-
currentMessages = prunedMessages;
|
|
151
|
-
if (!isContextOverflowing(afterPruneTokens, limits)) {
|
|
152
|
-
return { messages: currentMessages, removedCount: 0, tokensRemoved, summarized: false };
|
|
153
|
-
}
|
|
154
|
-
const cutIndex = findCutPoint(currentMessages, limits.protectedTokens);
|
|
155
|
-
if (cutIndex === 0) {
|
|
156
|
-
return { messages: currentMessages, removedCount: 0, tokensRemoved, summarized: false };
|
|
157
|
-
}
|
|
158
|
-
const toSummarize = currentMessages.slice(0, cutIndex);
|
|
159
|
-
const toKeep = currentMessages.slice(cutIndex);
|
|
160
|
-
removedCount = toSummarize.length;
|
|
161
|
-
tokensRemoved += estimateConversationTokens(toSummarize);
|
|
162
|
-
if (options.model) {
|
|
163
|
-
summary = await generateSummary(toSummarize, {
|
|
164
|
-
model: options.model,
|
|
165
|
-
customPrompt: options.summaryPrompt
|
|
166
|
-
});
|
|
167
|
-
summarized = true;
|
|
168
|
-
const summaryMessage = {
|
|
169
|
-
id: crypto.randomUUID(),
|
|
170
|
-
role: "system",
|
|
171
|
-
content: `## Previous Conversation Summary
|
|
172
|
-
|
|
173
|
-
${summary}`,
|
|
174
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
175
|
-
};
|
|
176
|
-
currentMessages = [summaryMessage, ...toKeep];
|
|
177
|
-
} else {
|
|
178
|
-
currentMessages = toKeep;
|
|
179
|
-
}
|
|
180
|
-
return { messages: currentMessages, removedCount, tokensRemoved, summarized, summary };
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// src/context/manager.ts
|
|
184
|
-
var ContextManager = class {
|
|
185
|
-
limits;
|
|
186
|
-
model;
|
|
187
|
-
summaryPrompt;
|
|
188
|
-
constructor(options) {
|
|
189
|
-
this.limits = { ...DEFAULT_CONTEXT_LIMITS, ...options?.limits };
|
|
190
|
-
this.model = options?.model;
|
|
191
|
-
this.summaryPrompt = options?.summaryPrompt;
|
|
192
|
-
}
|
|
193
|
-
/** Get a copy of the current context limits. */
|
|
194
|
-
getLimits() {
|
|
195
|
-
return { ...this.limits };
|
|
196
|
-
}
|
|
197
|
-
/** Update context limits (e.g. when switching models). */
|
|
198
|
-
setLimits(limits) {
|
|
199
|
-
this.limits = { ...this.limits, ...limits };
|
|
200
|
-
}
|
|
201
|
-
/** Set the model used for summarisation. */
|
|
202
|
-
setModel(model) {
|
|
203
|
-
this.model = model;
|
|
204
|
-
}
|
|
205
|
-
/** Estimate total tokens for a message array. */
|
|
206
|
-
estimateTokens(messages) {
|
|
207
|
-
return estimateConversationTokens(messages);
|
|
208
|
-
}
|
|
209
|
-
/** Check whether the context is overflowing. */
|
|
210
|
-
isOverflowing(messages) {
|
|
211
|
-
const tokens = this.estimateTokens(messages);
|
|
212
|
-
return isContextOverflowing(tokens, this.limits);
|
|
213
|
-
}
|
|
214
|
-
/** Check whether pruning should be triggered. */
|
|
215
|
-
shouldPrune(messages) {
|
|
216
|
-
const tokens = this.estimateTokens(messages);
|
|
217
|
-
return shouldPruneContext(tokens, this.limits);
|
|
218
|
-
}
|
|
219
|
-
/** Prune context to fit within limits. */
|
|
220
|
-
async prune(messages) {
|
|
221
|
-
return pruneContext(messages, {
|
|
222
|
-
model: this.model,
|
|
223
|
-
limits: this.limits,
|
|
224
|
-
summaryPrompt: this.summaryPrompt
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Get a snapshot of token statistics.
|
|
229
|
-
*
|
|
230
|
-
* Useful for dashboards, logging, or deciding whether to prune.
|
|
231
|
-
*/
|
|
232
|
-
getStats(messages) {
|
|
233
|
-
const tokens = this.estimateTokens(messages);
|
|
234
|
-
const limit = this.limits.contextWindow - this.limits.reserveTokens;
|
|
235
|
-
return {
|
|
236
|
-
tokens,
|
|
237
|
-
limit,
|
|
238
|
-
available: Math.max(0, limit - tokens),
|
|
239
|
-
utilizationPercent: Math.round(tokens / limit * 100),
|
|
240
|
-
isOverflowing: isContextOverflowing(tokens, this.limits),
|
|
241
|
-
shouldPrune: shouldPruneContext(tokens, this.limits)
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
export {
|
|
247
|
-
estimateTokens,
|
|
248
|
-
estimateMessageTokens,
|
|
249
|
-
estimateConversationTokens,
|
|
250
|
-
PRUNE_PROTECTED_TOOLS,
|
|
251
|
-
DEFAULT_CONTEXT_LIMITS,
|
|
252
|
-
isContextOverflowing,
|
|
253
|
-
shouldPruneContext,
|
|
254
|
-
findCutPoint,
|
|
255
|
-
pruneToolResults,
|
|
256
|
-
generateSummary,
|
|
257
|
-
pruneContext,
|
|
258
|
-
ContextManager
|
|
259
|
-
};
|
package/dist/context/index.d.ts
DELETED
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
import { M as Message } from '../messages-BYWGn8TY.js';
|
|
2
|
-
import { ModelMessage, LanguageModel } from 'ai';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Token Estimation Utilities
|
|
6
|
-
*
|
|
7
|
-
* Provides lightweight heuristic-based token counting for messages
|
|
8
|
-
* and conversations. Uses the chars/4 approximation — simple but
|
|
9
|
-
* effective for context-window planning decisions.
|
|
10
|
-
*
|
|
11
|
-
* These are *estimates*, not exact counts. For billing or hard limits,
|
|
12
|
-
* use the provider's native tokeniser instead.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Estimate token count for a plain string.
|
|
17
|
-
*
|
|
18
|
-
* Uses the widely-accepted `chars / 4` heuristic.
|
|
19
|
-
*
|
|
20
|
-
* @param text - Text to estimate
|
|
21
|
-
* @returns Estimated token count (always ≥ 1 for non-empty input)
|
|
22
|
-
*/
|
|
23
|
-
declare function estimateTokens(text: string): number;
|
|
24
|
-
/**
|
|
25
|
-
* Estimate token count for a single message.
|
|
26
|
-
*
|
|
27
|
-
* Handles:
|
|
28
|
-
* - Plain string content
|
|
29
|
-
* - Multi-part / multimodal arrays (text parts + images)
|
|
30
|
-
*
|
|
31
|
-
* @param message - A `Message` (internal) or `ModelMessage` (AI SDK)
|
|
32
|
-
* @returns Estimated token count
|
|
33
|
-
*/
|
|
34
|
-
declare function estimateMessageTokens(message: Message | ModelMessage): number;
|
|
35
|
-
/**
|
|
36
|
-
* Estimate total tokens for an entire conversation.
|
|
37
|
-
*
|
|
38
|
-
* Adds a small per-message overhead (≈ 4 tokens) for message
|
|
39
|
-
* framing (`role`, delimiters, etc.).
|
|
40
|
-
*
|
|
41
|
-
* @param messages - Array of messages to estimate
|
|
42
|
-
* @returns Estimated total token count
|
|
43
|
-
*/
|
|
44
|
-
declare function estimateConversationTokens(messages: (Message | ModelMessage)[]): number;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Context Overflow Detection & Pruning
|
|
48
|
-
*
|
|
49
|
-
* Detects when a conversation is approaching the model's context-window
|
|
50
|
-
* limit and prunes old / redundant content to stay within bounds.
|
|
51
|
-
*
|
|
52
|
-
* Two pruning strategies are available:
|
|
53
|
-
* 1. **Tool-result pruning** — replaces large, stale tool outputs with
|
|
54
|
-
* compact placeholders (lightweight, no model call).
|
|
55
|
-
* 2. **Conversation cutting** — identifies a safe cut-point and removes
|
|
56
|
-
* older messages entirely (optionally summarised by the manager).
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Context limits configuration.
|
|
61
|
-
*
|
|
62
|
-
* All values are in *estimated* tokens (see {@link estimateTokens}).
|
|
63
|
-
*/
|
|
64
|
-
interface ContextLimits {
|
|
65
|
-
/** Maximum context window size in tokens */
|
|
66
|
-
contextWindow: number;
|
|
67
|
-
/** Reserve tokens for output generation */
|
|
68
|
-
reserveTokens: number;
|
|
69
|
-
/** Protect this many recent tokens from pruning */
|
|
70
|
-
protectedTokens: number;
|
|
71
|
-
/** Minimum tokens to trigger pruning (avoid pruning tiny contexts) */
|
|
72
|
-
pruneMinimum: number;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Default context limits.
|
|
76
|
-
* Based on typical 128 k context-window models.
|
|
77
|
-
*/
|
|
78
|
-
declare const DEFAULT_CONTEXT_LIMITS: ContextLimits;
|
|
79
|
-
/**
|
|
80
|
-
* Check whether the context is overflowing.
|
|
81
|
-
*
|
|
82
|
-
* @param tokens - Current estimated token count
|
|
83
|
-
* @param limits - Context limits (defaults to 128 k window)
|
|
84
|
-
* @returns `true` if context exceeds the safe threshold
|
|
85
|
-
*/
|
|
86
|
-
declare function isContextOverflowing(tokens: number, limits?: ContextLimits): boolean;
|
|
87
|
-
/**
|
|
88
|
-
* Check whether pruning should be triggered.
|
|
89
|
-
*
|
|
90
|
-
* Returns `false` when the conversation is still small enough that
|
|
91
|
-
* pruning would be wasteful (below {@link ContextLimits.pruneMinimum}).
|
|
92
|
-
*/
|
|
93
|
-
declare function shouldPruneContext(tokens: number, limits?: ContextLimits): boolean;
|
|
94
|
-
/**
|
|
95
|
-
* Result of a pruning operation.
|
|
96
|
-
*/
|
|
97
|
-
interface PruneResult {
|
|
98
|
-
/** Messages after pruning (may include a summary message) */
|
|
99
|
-
messages: Message[];
|
|
100
|
-
/** Number of messages removed */
|
|
101
|
-
removedCount: number;
|
|
102
|
-
/** Estimated tokens removed */
|
|
103
|
-
tokensRemoved: number;
|
|
104
|
-
/** Whether summarisation was used */
|
|
105
|
-
summarized: boolean;
|
|
106
|
-
/** The summary content, if generated */
|
|
107
|
-
summary?: string;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Find a safe index at which the conversation can be "cut".
|
|
111
|
-
*
|
|
112
|
-
* Rules:
|
|
113
|
-
* - Never cut in the middle of a tool-call sequence
|
|
114
|
-
* - Prefer cutting after assistant / user messages
|
|
115
|
-
* - Keep at least {@link protectedTokens} tokens at the end
|
|
116
|
-
*
|
|
117
|
-
* @param messages - Full message array
|
|
118
|
-
* @param protectedTokens - Tokens to preserve at the end
|
|
119
|
-
* @returns Cut index (exclusive — remove messages *before* this index).
|
|
120
|
-
* Returns `0` when no safe cut-point exists.
|
|
121
|
-
*/
|
|
122
|
-
declare function findCutPoint(messages: Message[], protectedTokens?: number): number;
|
|
123
|
-
/**
|
|
124
|
-
* Prune old, large tool results from the conversation.
|
|
125
|
-
*
|
|
126
|
-
* Prune strategy:
|
|
127
|
-
* - Walks backwards through messages
|
|
128
|
-
* - Protects recent outputs (within {@link protectedTokens})
|
|
129
|
-
* - Skips protected tools (e.g. "skill")
|
|
130
|
-
* - Stamps pruned messages with a `compactedAt` timestamp
|
|
131
|
-
*
|
|
132
|
-
* @param messages - Messages to prune
|
|
133
|
-
* @param protectedTokens - Don't prune tool results in the last N tokens
|
|
134
|
-
* @param options - Extra tool names to protect
|
|
135
|
-
* @returns New message array with large tool outputs replaced
|
|
136
|
-
*/
|
|
137
|
-
declare function pruneToolResults(messages: Message[], protectedTokens?: number, options?: {
|
|
138
|
-
/** Additional tools to protect from pruning */
|
|
139
|
-
protectedTools?: string[];
|
|
140
|
-
}): Message[];
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Context Summarisation
|
|
144
|
-
*
|
|
145
|
-
* When tool-result pruning alone isn't enough to stay within the
|
|
146
|
-
* context window, the manager can *cut* the conversation and replace
|
|
147
|
-
* the removed portion with an LLM-generated summary.
|
|
148
|
-
*
|
|
149
|
-
* This module provides the summary-generation logic and the
|
|
150
|
-
* top-level `pruneContext()` orchestration function.
|
|
151
|
-
*/
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Options for summary generation.
|
|
155
|
-
*/
|
|
156
|
-
interface SummarizationOptions {
|
|
157
|
-
/** Model used to generate the summary */
|
|
158
|
-
model: LanguageModel;
|
|
159
|
-
/** Max tokens for the summary output */
|
|
160
|
-
maxTokens?: number;
|
|
161
|
-
/** Custom summarisation system prompt */
|
|
162
|
-
customPrompt?: string;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Options for {@link pruneContext}.
|
|
166
|
-
*/
|
|
167
|
-
interface PruneContextOptions {
|
|
168
|
-
/** Model for summarisation (omit to skip summary generation) */
|
|
169
|
-
model?: LanguageModel;
|
|
170
|
-
/** Context limits to enforce */
|
|
171
|
-
limits?: ContextLimits;
|
|
172
|
-
/** Custom summarisation prompt */
|
|
173
|
-
summaryPrompt?: string;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Generate a natural-language summary of a message sequence.
|
|
177
|
-
*
|
|
178
|
-
* @param messages - Messages to summarise
|
|
179
|
-
* @param options - Model & prompt configuration
|
|
180
|
-
* @returns Summary text
|
|
181
|
-
*/
|
|
182
|
-
declare function generateSummary(messages: Message[], options: SummarizationOptions): Promise<string>;
|
|
183
|
-
/**
|
|
184
|
-
* Prune a conversation to fit within context-window limits.
|
|
185
|
-
*
|
|
186
|
-
* Strategy (in order):
|
|
187
|
-
* 1. Prune old tool outputs (lightweight, no model call)
|
|
188
|
-
* 2. If still overflowing, find a safe cut-point and remove
|
|
189
|
-
* older messages — optionally generating an LLM summary.
|
|
190
|
-
*
|
|
191
|
-
* @param messages - Current message array
|
|
192
|
-
* @param options - Limits, model, and prompt overrides
|
|
193
|
-
* @returns A {@link PruneResult} with the trimmed messages
|
|
194
|
-
*/
|
|
195
|
-
declare function pruneContext(messages: Message[], options?: PruneContextOptions): Promise<PruneResult>;
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Context Manager
|
|
199
|
-
*
|
|
200
|
-
* Stateful wrapper around the context-management primitives.
|
|
201
|
-
* Tracks per-session context limits and provides a single entry
|
|
202
|
-
* point for token estimation, overflow detection, and pruning.
|
|
203
|
-
*/
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Per-session context manager.
|
|
207
|
-
*
|
|
208
|
-
* Holds the active context-window limits and provides convenience
|
|
209
|
-
* methods for checking, reporting, and pruning context.
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* ```typescript
|
|
213
|
-
* const ctx = new ContextManager({ limits: { contextWindow: 200_000 } });
|
|
214
|
-
*
|
|
215
|
-
* if (ctx.shouldPrune(messages)) {
|
|
216
|
-
* const result = await ctx.prune(messages);
|
|
217
|
-
* console.log(`Removed ${result.removedCount} messages`);
|
|
218
|
-
* }
|
|
219
|
-
* ```
|
|
220
|
-
*/
|
|
221
|
-
declare class ContextManager {
|
|
222
|
-
private limits;
|
|
223
|
-
private model?;
|
|
224
|
-
private summaryPrompt?;
|
|
225
|
-
constructor(options?: {
|
|
226
|
-
limits?: Partial<ContextLimits>;
|
|
227
|
-
model?: LanguageModel;
|
|
228
|
-
summaryPrompt?: string;
|
|
229
|
-
});
|
|
230
|
-
/** Get a copy of the current context limits. */
|
|
231
|
-
getLimits(): ContextLimits;
|
|
232
|
-
/** Update context limits (e.g. when switching models). */
|
|
233
|
-
setLimits(limits: Partial<ContextLimits>): void;
|
|
234
|
-
/** Set the model used for summarisation. */
|
|
235
|
-
setModel(model: LanguageModel): void;
|
|
236
|
-
/** Estimate total tokens for a message array. */
|
|
237
|
-
estimateTokens(messages: (Message | ModelMessage)[]): number;
|
|
238
|
-
/** Check whether the context is overflowing. */
|
|
239
|
-
isOverflowing(messages: (Message | ModelMessage)[]): boolean;
|
|
240
|
-
/** Check whether pruning should be triggered. */
|
|
241
|
-
shouldPrune(messages: (Message | ModelMessage)[]): boolean;
|
|
242
|
-
/** Prune context to fit within limits. */
|
|
243
|
-
prune(messages: Message[]): Promise<PruneResult>;
|
|
244
|
-
/**
|
|
245
|
-
* Get a snapshot of token statistics.
|
|
246
|
-
*
|
|
247
|
-
* Useful for dashboards, logging, or deciding whether to prune.
|
|
248
|
-
*/
|
|
249
|
-
getStats(messages: (Message | ModelMessage)[]): {
|
|
250
|
-
tokens: number;
|
|
251
|
-
limit: number;
|
|
252
|
-
available: number;
|
|
253
|
-
utilizationPercent: number;
|
|
254
|
-
isOverflowing: boolean;
|
|
255
|
-
shouldPrune: boolean;
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export { type ContextLimits, ContextManager, DEFAULT_CONTEXT_LIMITS, type PruneContextOptions, type PruneResult, type SummarizationOptions, estimateConversationTokens, estimateMessageTokens, estimateTokens, findCutPoint, generateSummary, isContextOverflowing, pruneContext, pruneToolResults, shouldPruneContext };
|
package/dist/context/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ContextManager,
|
|
3
|
-
DEFAULT_CONTEXT_LIMITS,
|
|
4
|
-
estimateConversationTokens,
|
|
5
|
-
estimateMessageTokens,
|
|
6
|
-
estimateTokens,
|
|
7
|
-
findCutPoint,
|
|
8
|
-
generateSummary,
|
|
9
|
-
isContextOverflowing,
|
|
10
|
-
pruneContext,
|
|
11
|
-
pruneToolResults,
|
|
12
|
-
shouldPruneContext
|
|
13
|
-
} from "../chunk-WWYYNWEW.js";
|
|
14
|
-
export {
|
|
15
|
-
ContextManager,
|
|
16
|
-
DEFAULT_CONTEXT_LIMITS,
|
|
17
|
-
estimateConversationTokens,
|
|
18
|
-
estimateMessageTokens,
|
|
19
|
-
estimateTokens,
|
|
20
|
-
findCutPoint,
|
|
21
|
-
generateSummary,
|
|
22
|
-
isContextOverflowing,
|
|
23
|
-
pruneContext,
|
|
24
|
-
pruneToolResults,
|
|
25
|
-
shouldPruneContext
|
|
26
|
-
};
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import * as ai from 'ai';
|
|
2
|
-
import { T as TokenUsage, M as Message } from './messages-BYWGn8TY.js';
|
|
3
|
-
|
|
4
|
-
/** Agent status for UI display */
|
|
5
|
-
type AgentStatus = "idle" | "processing" | "thinking" | "reasoning" | "calling-tool" | "waiting-approval" | "error";
|
|
6
|
-
/** Approval request for UI */
|
|
7
|
-
interface ApprovalEvent {
|
|
8
|
-
id: string;
|
|
9
|
-
tool: string;
|
|
10
|
-
args: unknown;
|
|
11
|
-
description: string;
|
|
12
|
-
risk: "safe" | "moderate" | "dangerous";
|
|
13
|
-
}
|
|
14
|
-
/** Neutral turn-commit boundaries for runtime/durability integrations */
|
|
15
|
-
type AgentTurnBoundaryKind = "input-commit-start" | "input-commit-finish" | "intervention-commit-start" | "intervention-commit-finish" | "step-commit-start" | "step-commit-finish" | "output-commit-start" | "output-commit-finish";
|
|
16
|
-
/**
|
|
17
|
-
* Events emitted during agent execution
|
|
18
|
-
*
|
|
19
|
-
* These events are designed for UI consumption:
|
|
20
|
-
* - status: Overall agent state for status indicators
|
|
21
|
-
* - approval-request: User confirmation needed
|
|
22
|
-
* - progress: Step counts for progress bars
|
|
23
|
-
*/
|
|
24
|
-
type AgentEvent = {
|
|
25
|
-
type: "status";
|
|
26
|
-
status: AgentStatus;
|
|
27
|
-
} | {
|
|
28
|
-
type: "approval-request";
|
|
29
|
-
request: ApprovalEvent;
|
|
30
|
-
} | {
|
|
31
|
-
type: "approval-resolved";
|
|
32
|
-
id: string;
|
|
33
|
-
action: "allow" | "deny" | "remember";
|
|
34
|
-
} | {
|
|
35
|
-
type: "step-start";
|
|
36
|
-
step: number;
|
|
37
|
-
maxSteps: number;
|
|
38
|
-
} | {
|
|
39
|
-
type: "step-finish";
|
|
40
|
-
step: number;
|
|
41
|
-
usage?: TokenUsage;
|
|
42
|
-
finishReason?: string;
|
|
43
|
-
} | {
|
|
44
|
-
type: "turn-boundary";
|
|
45
|
-
boundary: AgentTurnBoundaryKind;
|
|
46
|
-
step?: number;
|
|
47
|
-
messageRole?: Message["role"];
|
|
48
|
-
pendingToolCallCount?: number;
|
|
49
|
-
} | {
|
|
50
|
-
type: "message";
|
|
51
|
-
message: Message;
|
|
52
|
-
} | {
|
|
53
|
-
type: "text-start";
|
|
54
|
-
} | {
|
|
55
|
-
type: "text-delta";
|
|
56
|
-
text: string;
|
|
57
|
-
} | {
|
|
58
|
-
type: "text-end";
|
|
59
|
-
} | {
|
|
60
|
-
type: "reasoning-start";
|
|
61
|
-
id: string;
|
|
62
|
-
} | {
|
|
63
|
-
type: "reasoning-delta";
|
|
64
|
-
id: string;
|
|
65
|
-
text: string;
|
|
66
|
-
} | {
|
|
67
|
-
type: "reasoning-end";
|
|
68
|
-
id: string;
|
|
69
|
-
} | {
|
|
70
|
-
type: "tool-start";
|
|
71
|
-
toolName: string;
|
|
72
|
-
toolCallId: string;
|
|
73
|
-
input: unknown;
|
|
74
|
-
} | {
|
|
75
|
-
type: "tool-result";
|
|
76
|
-
toolName: string;
|
|
77
|
-
toolCallId: string;
|
|
78
|
-
result: unknown;
|
|
79
|
-
} | {
|
|
80
|
-
type: "tool-error";
|
|
81
|
-
toolName: string;
|
|
82
|
-
toolCallId: string;
|
|
83
|
-
error: string;
|
|
84
|
-
} | {
|
|
85
|
-
type: "computer-call";
|
|
86
|
-
callId: string;
|
|
87
|
-
action: unknown;
|
|
88
|
-
pendingSafetyChecks?: unknown[];
|
|
89
|
-
} | {
|
|
90
|
-
type: "computer-result";
|
|
91
|
-
callId: string;
|
|
92
|
-
result: unknown;
|
|
93
|
-
} | {
|
|
94
|
-
type: "intervention-applied";
|
|
95
|
-
id: string;
|
|
96
|
-
message: string;
|
|
97
|
-
} | {
|
|
98
|
-
type: "doom-loop";
|
|
99
|
-
toolName: string;
|
|
100
|
-
repeatCount: number;
|
|
101
|
-
} | {
|
|
102
|
-
type: "context-overflow";
|
|
103
|
-
inputTokens: number;
|
|
104
|
-
limit: number;
|
|
105
|
-
} | {
|
|
106
|
-
type: "turn-summary";
|
|
107
|
-
turnId: string;
|
|
108
|
-
files: Array<{
|
|
109
|
-
path: string;
|
|
110
|
-
type: "created" | "modified" | "deleted" | "unchanged";
|
|
111
|
-
additions: number;
|
|
112
|
-
deletions: number;
|
|
113
|
-
}>;
|
|
114
|
-
additions: number;
|
|
115
|
-
deletions: number;
|
|
116
|
-
} | {
|
|
117
|
-
type: "retry";
|
|
118
|
-
attempt: number;
|
|
119
|
-
delayMs: number;
|
|
120
|
-
error: Error;
|
|
121
|
-
} | {
|
|
122
|
-
type: "error";
|
|
123
|
-
error: Error;
|
|
124
|
-
} | {
|
|
125
|
-
type: "complete";
|
|
126
|
-
usage?: TokenUsage;
|
|
127
|
-
output?: string;
|
|
128
|
-
};
|
|
129
|
-
/**
|
|
130
|
-
* Step-processing result - what happens after reducing one streamed step
|
|
131
|
-
*/
|
|
132
|
-
type StepProcessingResult = "continue" | "stop" | "compact";
|
|
133
|
-
/**
|
|
134
|
-
* @deprecated Use `StepProcessingResult`.
|
|
135
|
-
*/
|
|
136
|
-
type ProcessorResult = StepProcessingResult;
|
|
137
|
-
/**
|
|
138
|
-
* Stream input for model inference
|
|
139
|
-
*/
|
|
140
|
-
interface StreamInput {
|
|
141
|
-
sessionID: string;
|
|
142
|
-
model: ai.LanguageModel;
|
|
143
|
-
system: string[];
|
|
144
|
-
messages: ai.ModelMessage[];
|
|
145
|
-
abort: AbortSignal;
|
|
146
|
-
tools: Record<string, unknown>;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export type { AgentEvent as A, ProcessorResult as P, StepProcessingResult as S, AgentStatus as a, AgentTurnBoundaryKind as b, ApprovalEvent as c, StreamInput as d };
|