negotium 0.6.17 → 0.7.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/dist/agent-helpers.js +235 -24
- package/dist/agent-helpers.js.map +9 -8
- package/dist/{chunk-ypbe1gc9.js → chunk-06zc96py.js} +1 -1
- package/dist/{chunk-ax6tqx0s.js → chunk-9h53kw24.js} +3 -3
- package/dist/{chunk-ax6tqx0s.js.map → chunk-9h53kw24.js.map} +2 -2
- package/dist/{chunk-rsmbwyzv.js → chunk-pp6dvrzq.js} +3 -3
- package/dist/{chunk-rsmbwyzv.js.map → chunk-pp6dvrzq.js.map} +3 -3
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +251 -40
- package/dist/main.js.map +9 -8
- package/dist/mcp-factories.js +243 -32
- package/dist/mcp-factories.js.map +9 -8
- package/dist/registry.js +3 -3
- package/dist/rollout.js +2 -2
- package/dist/runtime/src/agents/compaction-tool-projection.ts +125 -0
- package/dist/runtime/src/agents/idle-compact.ts +51 -4
- package/dist/runtime/src/agents/rollout/shared.ts +13 -5
- package/dist/runtime/src/runtime/turn-event-stream.ts +15 -1
- package/dist/runtime/src/topics/session.ts +91 -4
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/agents/compaction-tool-projection.d.ts +9 -0
- package/dist/types/packages/core/src/agents/idle-compact.d.ts +9 -0
- package/dist/types/packages/core/src/agents/rollout/shared.d.ts +8 -2
- package/dist/types/packages/core/src/topics/session.d.ts +8 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +2 -2
- /package/dist/{chunk-ypbe1gc9.js.map → chunk-06zc96py.js.map} +0 -0
package/dist/agent-helpers.js
CHANGED
|
@@ -2053,12 +2053,12 @@ ${toolBuffer.join(`
|
|
|
2053
2053
|
break;
|
|
2054
2054
|
case "tool_use": {
|
|
2055
2055
|
const u = ev;
|
|
2056
|
-
toolBuffer.push(`<!-- Tool: ${u.name} ${truncate(JSON.stringify(u.input), 200)} -->`);
|
|
2056
|
+
toolBuffer.push(opts.formatToolUse?.(u) ?? `<!-- Tool: ${u.name} ${truncate(JSON.stringify(u.input), 200)} -->`);
|
|
2057
2057
|
break;
|
|
2058
2058
|
}
|
|
2059
2059
|
case "tool_result": {
|
|
2060
2060
|
const u = ev;
|
|
2061
|
-
toolBuffer.push(`<!-- Tool result: ${truncate(u.content, 200)} -->`);
|
|
2061
|
+
toolBuffer.push(opts.formatToolResult?.(u) ?? `<!-- Tool result: ${truncate(u.content, 200)} -->`);
|
|
2062
2062
|
break;
|
|
2063
2063
|
}
|
|
2064
2064
|
case "error": {
|
|
@@ -3001,7 +3001,7 @@ var init_codex = __esm(async () => {
|
|
|
3001
3001
|
});
|
|
3002
3002
|
|
|
3003
3003
|
// ../../packages/core/src/version.ts
|
|
3004
|
-
var NEGOTIUM_VERSION = "0.
|
|
3004
|
+
var NEGOTIUM_VERSION = "0.7.0";
|
|
3005
3005
|
|
|
3006
3006
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3007
3007
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -12123,8 +12123,117 @@ RULES:
|
|
|
12123
12123
|
- Do NOT invent file paths or facts not present in the transcript.
|
|
12124
12124
|
- Keep the entire summary under 1500 words.`, CHARS_PER_TEXT_TOKEN = 3.5, CHARS_PER_CJK_TOKEN = 0.9;
|
|
12125
12125
|
|
|
12126
|
-
// ../../packages/core/src/
|
|
12126
|
+
// ../../packages/core/src/agents/compaction-tool-projection.ts
|
|
12127
12127
|
import { createHash as createHash5 } from "crypto";
|
|
12128
|
+
function digest(value) {
|
|
12129
|
+
return createHash5("sha256").update(value).digest("hex").slice(0, 16);
|
|
12130
|
+
}
|
|
12131
|
+
function boundedEdges(value, edgeChars) {
|
|
12132
|
+
if (value.length <= edgeChars * 2)
|
|
12133
|
+
return value;
|
|
12134
|
+
const omitted = value.length - edgeChars * 2;
|
|
12135
|
+
return `${value.slice(0, edgeChars)}
|
|
12136
|
+
[\u2026 omitted ${omitted.toLocaleString()} chars \u2026]
|
|
12137
|
+
${value.slice(-edgeChars)}`;
|
|
12138
|
+
}
|
|
12139
|
+
function quoted(value) {
|
|
12140
|
+
return JSON.stringify(value);
|
|
12141
|
+
}
|
|
12142
|
+
function salientLines(value) {
|
|
12143
|
+
const selected = [];
|
|
12144
|
+
let chars = 0;
|
|
12145
|
+
for (const line of value.split(`
|
|
12146
|
+
`)) {
|
|
12147
|
+
if (!SALIENT_LINE_RE.test(line))
|
|
12148
|
+
continue;
|
|
12149
|
+
const trimmed = line.trim();
|
|
12150
|
+
if (!trimmed || selected.includes(trimmed))
|
|
12151
|
+
continue;
|
|
12152
|
+
if (chars + trimmed.length + 1 > TOOL_OUTPUT_SALIENT_CHARS)
|
|
12153
|
+
break;
|
|
12154
|
+
selected.push(trimmed);
|
|
12155
|
+
chars += trimmed.length + 1;
|
|
12156
|
+
}
|
|
12157
|
+
return selected.join(`
|
|
12158
|
+
`);
|
|
12159
|
+
}
|
|
12160
|
+
function formatToolUse2(event) {
|
|
12161
|
+
const input = JSON.stringify(event.input ?? {});
|
|
12162
|
+
const projected = estimateTextTokens(input) <= MAX_TOOL_INPUT_TOKENS ? input : boundedEdges(input, TOOL_INPUT_EDGE_CHARS);
|
|
12163
|
+
return [
|
|
12164
|
+
"[Negotium tool use \u2014 quoted untrusted data]",
|
|
12165
|
+
`id_json: ${quoted(event.toolUseId ?? "unknown")}`,
|
|
12166
|
+
`name_json: ${quoted(event.name)}`,
|
|
12167
|
+
"quoted_untrusted_data: true",
|
|
12168
|
+
`input_json: ${quoted(projected)}`,
|
|
12169
|
+
"[/Negotium tool use]"
|
|
12170
|
+
].join(`
|
|
12171
|
+
`);
|
|
12172
|
+
}
|
|
12173
|
+
function formatToolResult(event, hash, duplicate) {
|
|
12174
|
+
const metadata = event.metadata;
|
|
12175
|
+
const header = [
|
|
12176
|
+
"[Negotium tool result \u2014 quoted untrusted data]",
|
|
12177
|
+
`id_json: ${quoted(event.toolUseId)}`,
|
|
12178
|
+
`status: ${event.isError ? "error" : "success"}`,
|
|
12179
|
+
"quoted_untrusted_data: true",
|
|
12180
|
+
`hash: sha256:${hash}`,
|
|
12181
|
+
`original_bytes: ${metadata?.originalBytes ?? Buffer.byteLength(event.content)}`,
|
|
12182
|
+
...metadata?.returnedBytes !== undefined ? [`returned_bytes: ${metadata.returnedBytes}`] : [],
|
|
12183
|
+
...metadata?.omittedBytes !== undefined ? [`omitted_bytes: ${metadata.omittedBytes}`] : [],
|
|
12184
|
+
...metadata?.outputPath ? [`output_path_json: ${quoted(metadata.outputPath)}`] : []
|
|
12185
|
+
];
|
|
12186
|
+
if (duplicate) {
|
|
12187
|
+
return [
|
|
12188
|
+
...header,
|
|
12189
|
+
"content: [duplicate of the most recent result with this hash]",
|
|
12190
|
+
"[/Negotium tool result]"
|
|
12191
|
+
].join(`
|
|
12192
|
+
`);
|
|
12193
|
+
}
|
|
12194
|
+
if (estimateTextTokens(event.content) <= MAX_TOOL_OUTPUT_TOKENS) {
|
|
12195
|
+
return [...header, `content_json: ${quoted(event.content)}`, "[/Negotium tool result]"].join(`
|
|
12196
|
+
`);
|
|
12197
|
+
}
|
|
12198
|
+
const salient = salientLines(event.content);
|
|
12199
|
+
return [
|
|
12200
|
+
...header,
|
|
12201
|
+
"content: [bounded projection; full output remains in the raw conversation log]",
|
|
12202
|
+
`head_tail_json: ${quoted(boundedEdges(event.content, TOOL_OUTPUT_EDGE_CHARS))}`,
|
|
12203
|
+
...salient ? [`salient_lines_json: ${quoted(salient)}`] : [],
|
|
12204
|
+
"[/Negotium tool result]"
|
|
12205
|
+
].join(`
|
|
12206
|
+
`);
|
|
12207
|
+
}
|
|
12208
|
+
function extractCompactionChatPairs(entries) {
|
|
12209
|
+
const remainingByHash = new Map;
|
|
12210
|
+
const hashByEvent = new WeakMap;
|
|
12211
|
+
for (const entry of entries) {
|
|
12212
|
+
if (entry.event.type !== "tool_result")
|
|
12213
|
+
continue;
|
|
12214
|
+
const hash = digest(entry.event.content);
|
|
12215
|
+
hashByEvent.set(entry.event, hash);
|
|
12216
|
+
remainingByHash.set(hash, (remainingByHash.get(hash) ?? 0) + 1);
|
|
12217
|
+
}
|
|
12218
|
+
return extractChatPairs(entries, {
|
|
12219
|
+
includeToolAnnotations: true,
|
|
12220
|
+
formatToolUse: formatToolUse2,
|
|
12221
|
+
formatToolResult: (event) => {
|
|
12222
|
+
const hash = hashByEvent.get(event) ?? digest(event.content);
|
|
12223
|
+
const remaining = Math.max(0, (remainingByHash.get(hash) ?? 1) - 1);
|
|
12224
|
+
remainingByHash.set(hash, remaining);
|
|
12225
|
+
return formatToolResult(event, hash, remaining > 0);
|
|
12226
|
+
}
|
|
12227
|
+
});
|
|
12228
|
+
}
|
|
12229
|
+
var MAX_TOOL_INPUT_TOKENS = 2000, MAX_TOOL_OUTPUT_TOKENS = 8000, TOOL_INPUT_EDGE_CHARS = 1000, TOOL_OUTPUT_EDGE_CHARS = 2000, TOOL_OUTPUT_SALIENT_CHARS = 2000, SALIENT_LINE_RE;
|
|
12230
|
+
var init_compaction_tool_projection = __esm(() => {
|
|
12231
|
+
init_shared();
|
|
12232
|
+
SALIENT_LINE_RE = /\b(error|failed?|failure|warning|exit(?:ed)?|expected|received|not found|denied|passed|tests?|assert|timeout|exception)\b/i;
|
|
12233
|
+
});
|
|
12234
|
+
|
|
12235
|
+
// ../../packages/core/src/storage/token-stats.ts
|
|
12236
|
+
import { createHash as createHash6 } from "crypto";
|
|
12128
12237
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
12129
12238
|
import { join as join21 } from "path";
|
|
12130
12239
|
function emptyBucket() {
|
|
@@ -12139,7 +12248,7 @@ function emptyBucket() {
|
|
|
12139
12248
|
}
|
|
12140
12249
|
function tokenStatsFileId(userId) {
|
|
12141
12250
|
const rawUserId = String(userId);
|
|
12142
|
-
return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${
|
|
12251
|
+
return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash6("sha256").update(rawUserId).digest("hex")}`;
|
|
12143
12252
|
}
|
|
12144
12253
|
function queriesPath(userId) {
|
|
12145
12254
|
const fileId = tokenStatsFileId(userId);
|
|
@@ -12270,11 +12379,14 @@ var init_token_stats = __esm(async () => {
|
|
|
12270
12379
|
// ../../packages/core/src/agents/idle-compact.ts
|
|
12271
12380
|
function cancelIdleCompactForTopic(topicId) {
|
|
12272
12381
|
const timer = timers2.get(topicId);
|
|
12273
|
-
|
|
12274
|
-
|
|
12275
|
-
|
|
12382
|
+
const contextLimitTimer = contextLimitTimers.get(topicId);
|
|
12383
|
+
if (timer)
|
|
12384
|
+
clearTimeout(timer);
|
|
12385
|
+
if (contextLimitTimer)
|
|
12386
|
+
clearTimeout(contextLimitTimer);
|
|
12276
12387
|
timers2.delete(topicId);
|
|
12277
|
-
|
|
12388
|
+
contextLimitTimers.delete(topicId);
|
|
12389
|
+
return Boolean(timer || contextLimitTimer);
|
|
12278
12390
|
}
|
|
12279
12391
|
function envFlagEnabled2(name, fallback) {
|
|
12280
12392
|
const raw = process.env[name]?.trim().toLowerCase();
|
|
@@ -12316,6 +12428,38 @@ function scheduleIdleCompactForTopic(topicId, userId) {
|
|
|
12316
12428
|
timers2.set(topicId, timer);
|
|
12317
12429
|
return "scheduled";
|
|
12318
12430
|
}
|
|
12431
|
+
function scheduleContextLimitCompactForTopic(topicId, userId, contextTokens, contextWindow) {
|
|
12432
|
+
if (!idleCompactEnabled())
|
|
12433
|
+
return "disabled";
|
|
12434
|
+
if (!Number.isFinite(contextWindow) || contextWindow <= 0)
|
|
12435
|
+
return "below-threshold";
|
|
12436
|
+
const percent = contextTokens / contextWindow * 100;
|
|
12437
|
+
if (!Number.isFinite(percent) || percent < CONTEXT_LIMIT_COMPACT_PERCENT) {
|
|
12438
|
+
return "below-threshold";
|
|
12439
|
+
}
|
|
12440
|
+
const topic = getTopic(topicId);
|
|
12441
|
+
if (!topic)
|
|
12442
|
+
return "topic-not-found";
|
|
12443
|
+
if (!topic.agent)
|
|
12444
|
+
return "not-ai-invited";
|
|
12445
|
+
if (topic.aiMode === "mention")
|
|
12446
|
+
return "mention-only-channel";
|
|
12447
|
+
const existing = contextLimitTimers.get(topicId);
|
|
12448
|
+
if (existing)
|
|
12449
|
+
clearTimeout(existing);
|
|
12450
|
+
const retry = () => scheduleContextLimitCompactForTopic(topicId, userId, contextTokens, contextWindow);
|
|
12451
|
+
const timer = setTimeout(() => {
|
|
12452
|
+
contextLimitTimers.delete(topicId);
|
|
12453
|
+
runIdleCompactForTopic(topicId, userId, {
|
|
12454
|
+
minContextPercent: CONTEXT_LIMIT_COMPACT_PERCENT,
|
|
12455
|
+
reason: "context-limit-compact",
|
|
12456
|
+
onBusy: retry
|
|
12457
|
+
});
|
|
12458
|
+
}, DEFAULT_CONTEXT_LIMIT_DELAY_MS);
|
|
12459
|
+
timer.unref?.();
|
|
12460
|
+
contextLimitTimers.set(topicId, timer);
|
|
12461
|
+
return "scheduled";
|
|
12462
|
+
}
|
|
12319
12463
|
async function runIdleCompactForTopic(topicId, userId, options = {}) {
|
|
12320
12464
|
if (!idleCompactEnabled())
|
|
12321
12465
|
return "disabled";
|
|
@@ -12354,7 +12498,7 @@ async function runIdleCompactForTopic(topicId, userId, options = {}) {
|
|
|
12354
12498
|
return compactTopicSession(id, actorId, reason, { preemptive: false });
|
|
12355
12499
|
});
|
|
12356
12500
|
try {
|
|
12357
|
-
const result = await compact(topicId, owner, "idle-compact");
|
|
12501
|
+
const result = await compact(topicId, owner, options.reason ?? "idle-compact");
|
|
12358
12502
|
if (result.busy) {
|
|
12359
12503
|
logger.debug({ topicId, percent: Math.round(percent) }, "idle-compact: topic became busy, rescheduling");
|
|
12360
12504
|
if (options.onBusy)
|
|
@@ -12374,7 +12518,7 @@ async function runIdleCompactForTopic(topicId, userId, options = {}) {
|
|
|
12374
12518
|
return "failed";
|
|
12375
12519
|
}
|
|
12376
12520
|
}
|
|
12377
|
-
var DEFAULT_IDLE_DELAY_MS2, DEFAULT_MIN_CONTEXT_PERCENT = 50, timers2;
|
|
12521
|
+
var DEFAULT_IDLE_DELAY_MS2, DEFAULT_CONTEXT_LIMIT_DELAY_MS = 1000, CONTEXT_LIMIT_COMPACT_PERCENT = 90, DEFAULT_MIN_CONTEXT_PERCENT = 50, timers2, contextLimitTimers;
|
|
12378
12522
|
var init_idle_compact = __esm(async () => {
|
|
12379
12523
|
init_logger();
|
|
12380
12524
|
await init_active_rooms();
|
|
@@ -12383,6 +12527,7 @@ var init_idle_compact = __esm(async () => {
|
|
|
12383
12527
|
await init_token_stats();
|
|
12384
12528
|
DEFAULT_IDLE_DELAY_MS2 = 6 * 60 * 60 * 1000;
|
|
12385
12529
|
timers2 = new Map;
|
|
12530
|
+
contextLimitTimers = new Map;
|
|
12386
12531
|
});
|
|
12387
12532
|
|
|
12388
12533
|
// ../../packages/core/src/agents/topic-cleanup.ts
|
|
@@ -12907,11 +13052,13 @@ var init_runtime_turn_requests = __esm(async () => {
|
|
|
12907
13052
|
// ../../packages/core/src/topics/session.ts
|
|
12908
13053
|
var exports_session = {};
|
|
12909
13054
|
__export(exports_session, {
|
|
13055
|
+
splitCompactionPairs: () => splitCompactionPairs,
|
|
12910
13056
|
shouldUseCompactionLog: () => shouldUseCompactionLog,
|
|
12911
13057
|
shouldCompactForkEntries: () => shouldCompactForkEntries,
|
|
12912
13058
|
restartTopicSession: () => restartTopicSession,
|
|
12913
13059
|
createCompactedRolloutEntries: () => createCompactedRolloutEntries,
|
|
12914
13060
|
compactTopicSession: () => compactTopicSession,
|
|
13061
|
+
COMPACTION_RETAINED_TAIL_TOKENS: () => COMPACTION_RETAINED_TAIL_TOKENS,
|
|
12915
13062
|
AUTO_FORK_COMPACTION_TOKENS: () => AUTO_FORK_COMPACTION_TOKENS
|
|
12916
13063
|
});
|
|
12917
13064
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
@@ -13059,6 +13206,61 @@ The assistant response is the authoritative summary of all earlier context.` &&
|
|
|
13059
13206
|
}
|
|
13060
13207
|
return;
|
|
13061
13208
|
}
|
|
13209
|
+
function withoutCompactionSentinels(entries) {
|
|
13210
|
+
const filtered = [];
|
|
13211
|
+
for (let index = 0;index < entries.length; index++) {
|
|
13212
|
+
const current2 = entries[index]?.event;
|
|
13213
|
+
const next = entries[index + 1]?.event;
|
|
13214
|
+
if (current2?.type === "user_message" && current2.synthetic === "compaction" && next?.type === "result") {
|
|
13215
|
+
index += 1;
|
|
13216
|
+
continue;
|
|
13217
|
+
}
|
|
13218
|
+
const entry = entries[index];
|
|
13219
|
+
if (entry)
|
|
13220
|
+
filtered.push(entry);
|
|
13221
|
+
}
|
|
13222
|
+
return filtered;
|
|
13223
|
+
}
|
|
13224
|
+
function pairTokens(pair) {
|
|
13225
|
+
return estimateConversationTokens([{ content: pair.userText }, { content: pair.assistantText }]);
|
|
13226
|
+
}
|
|
13227
|
+
function splitCompactionPairs(entries, retainedTailTokens = COMPACTION_RETAINED_TAIL_TOKENS) {
|
|
13228
|
+
const pairs = extractCompactionChatPairs(withoutCompactionSentinels(entries));
|
|
13229
|
+
let retainedStart = pairs.length;
|
|
13230
|
+
let retainedTokens = 0;
|
|
13231
|
+
for (let index = pairs.length - 1;index >= 0; index--) {
|
|
13232
|
+
const pair = pairs[index];
|
|
13233
|
+
if (!pair)
|
|
13234
|
+
continue;
|
|
13235
|
+
const tokens = pairTokens(pair);
|
|
13236
|
+
if (retainedTokens + tokens > retainedTailTokens)
|
|
13237
|
+
break;
|
|
13238
|
+
retainedTokens += tokens;
|
|
13239
|
+
retainedStart = index;
|
|
13240
|
+
}
|
|
13241
|
+
if (retainedStart === 0)
|
|
13242
|
+
return { summaryPairs: pairs, retainedPairs: [] };
|
|
13243
|
+
return {
|
|
13244
|
+
summaryPairs: pairs.slice(0, retainedStart),
|
|
13245
|
+
retainedPairs: pairs.slice(retainedStart)
|
|
13246
|
+
};
|
|
13247
|
+
}
|
|
13248
|
+
function retainedPairEntries(agent, pairs) {
|
|
13249
|
+
const entries = [];
|
|
13250
|
+
for (const pair of pairs) {
|
|
13251
|
+
const now = new Date().toISOString();
|
|
13252
|
+
entries.push({
|
|
13253
|
+
ts: now,
|
|
13254
|
+
agent,
|
|
13255
|
+
event: { type: "user_message", content: pair.userText }
|
|
13256
|
+
}, {
|
|
13257
|
+
ts: now,
|
|
13258
|
+
agent,
|
|
13259
|
+
event: { type: "result", content: pair.assistantText, stopReason: "end_turn" }
|
|
13260
|
+
});
|
|
13261
|
+
}
|
|
13262
|
+
return entries;
|
|
13263
|
+
}
|
|
13062
13264
|
function fitCompactionChunk(text2, limit) {
|
|
13063
13265
|
if (text2.length <= limit)
|
|
13064
13266
|
return text2;
|
|
@@ -13072,7 +13274,7 @@ function fitCompactionChunk(text2, limit) {
|
|
|
13072
13274
|
const tailChars = available - headChars;
|
|
13073
13275
|
return `${text2.slice(0, headChars)}${marker}${text2.slice(-tailChars)}`;
|
|
13074
13276
|
}
|
|
13075
|
-
function buildCompactionSource(topicId, userId, entries, visibleMessages) {
|
|
13277
|
+
function buildCompactionSource(topicId, userId, entries, visibleMessages, providerPairs) {
|
|
13076
13278
|
const sections = [];
|
|
13077
13279
|
const previous = previousCompactedSummary(entries);
|
|
13078
13280
|
if (previous)
|
|
@@ -13084,10 +13286,10 @@ ${previous}`);
|
|
|
13084
13286
|
sections.push(`## Durable topic memory
|
|
13085
13287
|
${fitCompactionChunk(memory, COMPACTION_MEMORY_CHARS)}`);
|
|
13086
13288
|
}
|
|
13087
|
-
const rows = (visibleMessages ?? getAllMessagesForTopic(topicId)).filter((row) => row.author_id !== "system" && row.kind !== "system" && row.kind !== "tool" && !row.id.startsWith("tasks-") && row.text.trim());
|
|
13289
|
+
const rows = (previous ? [] : visibleMessages ?? getAllMessagesForTopic(topicId)).filter((row) => row.author_id !== "system" && row.kind !== "system" && row.kind !== "tool" && !row.id.startsWith("tasks-") && row.text.trim());
|
|
13088
13290
|
const usedByContext = sections.reduce((sum, section) => sum + section.length + 2, 0);
|
|
13089
13291
|
const conversationBudget = Math.max(0, COMPACTION_SOURCE_CHARS - usedByContext);
|
|
13090
|
-
const pairs =
|
|
13292
|
+
const pairs = providerPairs ?? extractCompactionChatPairs(entries);
|
|
13091
13293
|
const hasVisibleRows = rows.length > 0;
|
|
13092
13294
|
const providerBudget = pairs.length > 0 ? hasVisibleRows ? Math.floor(conversationBudget * 0.65) : conversationBudget : 0;
|
|
13093
13295
|
const providerTranscript = [];
|
|
@@ -13400,12 +13602,14 @@ function shouldCompactForkEntries(entries, thresholdTokens = AUTO_FORK_COMPACTIO
|
|
|
13400
13602
|
return estimateConversationTokens(messages) >= thresholdTokens;
|
|
13401
13603
|
}
|
|
13402
13604
|
async function createCompactedRolloutEntries(request, summarize = summarizeTopicContext) {
|
|
13403
|
-
const
|
|
13605
|
+
const { summaryPairs, retainedPairs } = splitCompactionPairs(request.entries, request.retainedTailTokens);
|
|
13606
|
+
const source = buildCompactionSource(request.topicId, request.userId, request.entries, request.visibleMessages, summaryPairs);
|
|
13404
13607
|
if (!source)
|
|
13405
13608
|
throw new Error(`Nothing to compact in "${request.topicTitle}".`);
|
|
13406
13609
|
const {
|
|
13407
13610
|
entries: _entries,
|
|
13408
13611
|
visibleMessages: _visibleMessages,
|
|
13612
|
+
retainedTailTokens: _retainedTailTokens,
|
|
13409
13613
|
timeoutMs = shouldUseCompactionLog(source) ? COMPACTION_LOG_TIMEOUT_MS : COMPACTION_TIMEOUT_MS,
|
|
13410
13614
|
summaryModel,
|
|
13411
13615
|
summaryEffort,
|
|
@@ -13419,7 +13623,10 @@ async function createCompactedRolloutEntries(request, summarize = summarizeTopic
|
|
|
13419
13623
|
}, summarize, timeoutMs)).trim();
|
|
13420
13624
|
if (!summary)
|
|
13421
13625
|
throw new Error("Context compaction returned an empty summary.");
|
|
13422
|
-
return
|
|
13626
|
+
return [
|
|
13627
|
+
...compactEntries(request.agent, summary.slice(0, COMPACTION_OUTPUT_CHARS)),
|
|
13628
|
+
...retainedPairEntries(request.agent, retainedPairs)
|
|
13629
|
+
];
|
|
13423
13630
|
}
|
|
13424
13631
|
async function cleanupNewRollout(agent, cwd, sessionId) {
|
|
13425
13632
|
try {
|
|
@@ -13576,8 +13783,9 @@ async function compactTopicSession(topicId, userId, reason = "topic-session-comp
|
|
|
13576
13783
|
maintenance.finish();
|
|
13577
13784
|
}
|
|
13578
13785
|
}
|
|
13579
|
-
var RESET_TURN_WAIT_MS = 5000, RESET_MEMORY_ARCHIVE_WAIT_MS, COMPACTION_INLINE_CHARS = 1e5, COMPACTION_SOURCE_CHARS, COMPACTION_MEMORY_CHARS = 80000, COMPACTION_OUTPUT_CHARS = 30000, COMPACTION_TIMEOUT_MS, COMPACTION_LOG_TIMEOUT_MS, COMPACTION_LOG_MAX_CALLS = 12, COMPACTION_LOG_MAX_TOTAL_BYTES, COMPACTION_LOG_MAX_CHUNK_BYTES, COMPACT_CONTEXT_MARKER = "[Negotium compacted context]", AUTO_FORK_COMPACTION_TOKENS = 28000;
|
|
13786
|
+
var RESET_TURN_WAIT_MS = 5000, RESET_MEMORY_ARCHIVE_WAIT_MS, COMPACTION_INLINE_CHARS = 1e5, COMPACTION_SOURCE_CHARS, COMPACTION_MEMORY_CHARS = 80000, COMPACTION_OUTPUT_CHARS = 30000, COMPACTION_RETAINED_TAIL_TOKENS = 64000, COMPACTION_TIMEOUT_MS, COMPACTION_LOG_TIMEOUT_MS, COMPACTION_LOG_MAX_CALLS = 12, COMPACTION_LOG_MAX_TOTAL_BYTES, COMPACTION_LOG_MAX_CHUNK_BYTES, COMPACT_CONTEXT_MARKER = "[Negotium compacted context]", AUTO_FORK_COMPACTION_TOKENS = 28000;
|
|
13580
13787
|
var init_session = __esm(async () => {
|
|
13788
|
+
init_compaction_tool_projection();
|
|
13581
13789
|
await init_idle_archiver();
|
|
13582
13790
|
await init_idle_compact();
|
|
13583
13791
|
await init_agents();
|
|
@@ -13622,7 +13830,7 @@ __export(exports_derive, {
|
|
|
13622
13830
|
TopicForkCompactionError: () => TopicForkCompactionError,
|
|
13623
13831
|
TopicDeriveBusyError: () => TopicDeriveBusyError
|
|
13624
13832
|
});
|
|
13625
|
-
import { createHash as
|
|
13833
|
+
import { createHash as createHash7, randomUUID as randomUUID12 } from "crypto";
|
|
13626
13834
|
import { mkdirSync as mkdirSync14, rmSync as rmSync5, unlinkSync as unlinkSync13 } from "fs";
|
|
13627
13835
|
function getTopics(opts = {}) {
|
|
13628
13836
|
return listTopics(opts).filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
@@ -13688,7 +13896,7 @@ function captureForkSnapshot(sourceTopicId, userId, topicTitle) {
|
|
|
13688
13896
|
maxRowid: messageRows.at(-1)?.rowid ?? 0
|
|
13689
13897
|
},
|
|
13690
13898
|
active: isTopicRunning(sourceTopicId),
|
|
13691
|
-
canonicalDigest:
|
|
13899
|
+
canonicalDigest: createHash7("sha256").update(entries.map((entry) => JSON.stringify(entry)).join(`
|
|
13692
13900
|
`)).digest("hex")
|
|
13693
13901
|
};
|
|
13694
13902
|
}
|
|
@@ -14227,7 +14435,7 @@ __export(exports_session_asks, {
|
|
|
14227
14435
|
clearPendingAsk: () => clearPendingAsk,
|
|
14228
14436
|
PENDING_ASK_TTL_MS: () => PENDING_ASK_TTL_MS
|
|
14229
14437
|
});
|
|
14230
|
-
import { createHash as
|
|
14438
|
+
import { createHash as createHash8 } from "crypto";
|
|
14231
14439
|
import {
|
|
14232
14440
|
closeSync as closeSync2,
|
|
14233
14441
|
mkdirSync as mkdirSync16,
|
|
@@ -14241,15 +14449,15 @@ import {
|
|
|
14241
14449
|
import { dirname as dirname14, join as join27 } from "path";
|
|
14242
14450
|
function pendingAskDir(userId) {
|
|
14243
14451
|
const rawUserId = String(userId);
|
|
14244
|
-
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${
|
|
14452
|
+
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash8("sha256").update(rawUserId).digest("hex")}`;
|
|
14245
14453
|
return join27(resolveStorageSessionAsksDir(), safeUserId);
|
|
14246
14454
|
}
|
|
14247
14455
|
function encodeAskKey(key) {
|
|
14248
14456
|
return JSON.stringify([key.from, key.to]);
|
|
14249
14457
|
}
|
|
14250
14458
|
function pendingAskPath(key) {
|
|
14251
|
-
const
|
|
14252
|
-
return join27(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${
|
|
14459
|
+
const digest2 = createHash8("sha256").update(encodeAskKey(key)).digest("hex");
|
|
14460
|
+
return join27(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest2}.pending`);
|
|
14253
14461
|
}
|
|
14254
14462
|
function v2PendingAskPath(key) {
|
|
14255
14463
|
const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
|
|
@@ -16348,6 +16556,9 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
16348
16556
|
if (!silent) {
|
|
16349
16557
|
scheduleIdleArchiveForTopic(topicId, execution?.actorUserId ?? userId);
|
|
16350
16558
|
scheduleIdleCompactForTopic(topicId, execution?.actorUserId ?? userId);
|
|
16559
|
+
if (event.usage?.contextTokens !== undefined && event.usage.contextWindow !== undefined) {
|
|
16560
|
+
scheduleContextLimitCompactForTopic(topicId, execution?.actorUserId ?? userId, event.usage.contextTokens, event.usage.contextWindow);
|
|
16561
|
+
}
|
|
16351
16562
|
hub.broadcastDone(topicId, queryId, event.usage ? {
|
|
16352
16563
|
input: event.usage.inputTokens,
|
|
16353
16564
|
output: event.usage.outputTokens,
|
|
@@ -19957,4 +20168,4 @@ export {
|
|
|
19957
20168
|
DEFAULT_SELF_CONFIG_PRODUCT
|
|
19958
20169
|
};
|
|
19959
20170
|
|
|
19960
|
-
//# debugId=
|
|
20171
|
+
//# debugId=5098AD5EB3D2D82464756E2164756E21
|