repoburg 1.3.261 → 1.3.262
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/agent-pane/backend/dist/index.js +131 -38
- package/agent-pane/backend/dist/server.js +131 -38
- package/agent-pane/frontend/dist/assets/{index-Dy-xZ6tt.js → index-D8AvfHKw.js} +18 -18
- package/agent-pane/frontend/dist/index.html +1 -1
- package/daemon/dist/index.js +0 -0
- package/package.json +1 -1
|
@@ -16108,20 +16108,20 @@ var require_resolve = __commonJS({
|
|
|
16108
16108
|
return false;
|
|
16109
16109
|
}
|
|
16110
16110
|
function countKeys(schema) {
|
|
16111
|
-
let
|
|
16111
|
+
let count2 = 0;
|
|
16112
16112
|
for (const key in schema) {
|
|
16113
16113
|
if (key === "$ref")
|
|
16114
16114
|
return Infinity;
|
|
16115
|
-
|
|
16115
|
+
count2++;
|
|
16116
16116
|
if (SIMPLE_INLINED.has(key))
|
|
16117
16117
|
continue;
|
|
16118
16118
|
if (typeof schema[key] == "object") {
|
|
16119
|
-
(0, util_1.eachItem)(schema[key], (sch) =>
|
|
16119
|
+
(0, util_1.eachItem)(schema[key], (sch) => count2 += countKeys(sch));
|
|
16120
16120
|
}
|
|
16121
|
-
if (
|
|
16121
|
+
if (count2 === Infinity)
|
|
16122
16122
|
return Infinity;
|
|
16123
16123
|
}
|
|
16124
|
-
return
|
|
16124
|
+
return count2;
|
|
16125
16125
|
}
|
|
16126
16126
|
function getFullPath(resolver, id = "", normalize) {
|
|
16127
16127
|
if (normalize !== false)
|
|
@@ -19319,8 +19319,8 @@ var require_contains = __commonJS({
|
|
|
19319
19319
|
cxt.result(valid, () => cxt.reset());
|
|
19320
19320
|
function validateItemsWithCount() {
|
|
19321
19321
|
const schValid = gen.name("_valid");
|
|
19322
|
-
const
|
|
19323
|
-
validateItems(schValid, () => gen.if(schValid, () => checkLimits(
|
|
19322
|
+
const count2 = gen.let("count", 0);
|
|
19323
|
+
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count2)));
|
|
19324
19324
|
}
|
|
19325
19325
|
function validateItems(_valid, block) {
|
|
19326
19326
|
gen.forRange("i", 0, len, (i) => {
|
|
@@ -19333,16 +19333,16 @@ var require_contains = __commonJS({
|
|
|
19333
19333
|
block();
|
|
19334
19334
|
});
|
|
19335
19335
|
}
|
|
19336
|
-
function checkLimits(
|
|
19337
|
-
gen.code((0, codegen_1._)`${
|
|
19336
|
+
function checkLimits(count2) {
|
|
19337
|
+
gen.code((0, codegen_1._)`${count2}++`);
|
|
19338
19338
|
if (max === void 0) {
|
|
19339
|
-
gen.if((0, codegen_1._)`${
|
|
19339
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true).break());
|
|
19340
19340
|
} else {
|
|
19341
|
-
gen.if((0, codegen_1._)`${
|
|
19341
|
+
gen.if((0, codegen_1._)`${count2} > ${max}`, () => gen.assign(valid, false).break());
|
|
19342
19342
|
if (min === 1)
|
|
19343
19343
|
gen.assign(valid, true);
|
|
19344
19344
|
else
|
|
19345
|
-
gen.if((0, codegen_1._)`${
|
|
19345
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true));
|
|
19346
19346
|
}
|
|
19347
19347
|
}
|
|
19348
19348
|
}
|
|
@@ -21689,9 +21689,9 @@ var require_parseJson = __commonJS({
|
|
|
21689
21689
|
pos++;
|
|
21690
21690
|
} else if (c === "u") {
|
|
21691
21691
|
pos++;
|
|
21692
|
-
let
|
|
21692
|
+
let count2 = 4;
|
|
21693
21693
|
let code = 0;
|
|
21694
|
-
while (
|
|
21694
|
+
while (count2--) {
|
|
21695
21695
|
code <<= 4;
|
|
21696
21696
|
c = s[pos];
|
|
21697
21697
|
if (c === void 0) {
|
|
@@ -36953,7 +36953,7 @@ var require_fastify_plugin = __commonJS({
|
|
|
36953
36953
|
"use strict";
|
|
36954
36954
|
var getPluginName = require_getPluginName();
|
|
36955
36955
|
var toCamelCase = require_toCamelCase();
|
|
36956
|
-
var
|
|
36956
|
+
var count2 = 0;
|
|
36957
36957
|
function plugin(fn, options = {}) {
|
|
36958
36958
|
let autoName = false;
|
|
36959
36959
|
if (fn.default !== void 0) {
|
|
@@ -36977,7 +36977,7 @@ var require_fastify_plugin = __commonJS({
|
|
|
36977
36977
|
}
|
|
36978
36978
|
if (!options.name) {
|
|
36979
36979
|
autoName = true;
|
|
36980
|
-
options.name = getPluginName(fn) + "-auto-" +
|
|
36980
|
+
options.name = getPluginName(fn) + "-auto-" + count2++;
|
|
36981
36981
|
}
|
|
36982
36982
|
fn[Symbol.for("skip-override")] = options.encapsulate !== true;
|
|
36983
36983
|
fn[Symbol.for("fastify.display-name")] = options.name;
|
|
@@ -45478,6 +45478,100 @@ var EFFORT_LABELS2 = {
|
|
|
45478
45478
|
max: "Max"
|
|
45479
45479
|
};
|
|
45480
45480
|
|
|
45481
|
+
// src/claude/claude-context.ts
|
|
45482
|
+
function count(n) {
|
|
45483
|
+
return typeof n === "number" && Number.isFinite(n) ? n : 0;
|
|
45484
|
+
}
|
|
45485
|
+
function lastMessageIteration(iterations) {
|
|
45486
|
+
if (!Array.isArray(iterations)) return null;
|
|
45487
|
+
for (let i = iterations.length - 1; i >= 0; i--) {
|
|
45488
|
+
const it = iterations[i];
|
|
45489
|
+
if (!it || typeof it !== "object") continue;
|
|
45490
|
+
if ((it.type === "message" || it.type === "fallback_message") && typeof it.input_tokens === "number") return it;
|
|
45491
|
+
}
|
|
45492
|
+
return null;
|
|
45493
|
+
}
|
|
45494
|
+
function contextTokensFromUsage(usage) {
|
|
45495
|
+
if (!usage || typeof usage !== "object") return null;
|
|
45496
|
+
const u = lastMessageIteration(usage.iterations) ?? usage;
|
|
45497
|
+
const read = count(u.input_tokens) + count(u.cache_creation_input_tokens) + count(u.cache_read_input_tokens);
|
|
45498
|
+
if (read <= 0) return null;
|
|
45499
|
+
return read + count(u.output_tokens);
|
|
45500
|
+
}
|
|
45501
|
+
function counterOf(entry) {
|
|
45502
|
+
if (!entry.context) {
|
|
45503
|
+
entry.context = {
|
|
45504
|
+
window: null,
|
|
45505
|
+
autoCompactThreshold: null,
|
|
45506
|
+
tokens: null,
|
|
45507
|
+
measured: false,
|
|
45508
|
+
apiMessageId: null,
|
|
45509
|
+
seq: 0,
|
|
45510
|
+
windowRequested: false,
|
|
45511
|
+
lastPublished: null
|
|
45512
|
+
};
|
|
45513
|
+
}
|
|
45514
|
+
return entry.context;
|
|
45515
|
+
}
|
|
45516
|
+
function publish(entry, sessionId, db2) {
|
|
45517
|
+
const ctx = counterOf(entry);
|
|
45518
|
+
if (ctx.tokens === null) return;
|
|
45519
|
+
if (!ctx.window) {
|
|
45520
|
+
if (!ctx.windowRequested) void refreshContext(entry, sessionId, db2);
|
|
45521
|
+
return;
|
|
45522
|
+
}
|
|
45523
|
+
const usage = {
|
|
45524
|
+
totalTokens: ctx.tokens,
|
|
45525
|
+
contextWindow: ctx.window,
|
|
45526
|
+
percentage: Math.round(ctx.tokens / ctx.window * 100),
|
|
45527
|
+
...ctx.autoCompactThreshold ? { autoCompactThreshold: ctx.autoCompactThreshold } : {}
|
|
45528
|
+
};
|
|
45529
|
+
const json = JSON.stringify(usage);
|
|
45530
|
+
if (json === ctx.lastPublished) return;
|
|
45531
|
+
ctx.lastPublished = json;
|
|
45532
|
+
broadcast("turn:contextUsage", { sessionId, ...usage });
|
|
45533
|
+
db2.prepare("UPDATE sessions SET context_usage = ? WHERE id = ?").run(json, sessionId);
|
|
45534
|
+
}
|
|
45535
|
+
function recordApiUsage(entry, sessionId, db2, apiMessageId, usage) {
|
|
45536
|
+
if (entry.threadId) return;
|
|
45537
|
+
const tokens = contextTokensFromUsage(usage);
|
|
45538
|
+
if (tokens === null) return;
|
|
45539
|
+
const ctx = counterOf(entry);
|
|
45540
|
+
const id = apiMessageId ?? ctx.apiMessageId;
|
|
45541
|
+
if (ctx.measured && id !== null && id === ctx.apiMessageId && ctx.tokens !== null && tokens <= ctx.tokens) return;
|
|
45542
|
+
ctx.apiMessageId = id;
|
|
45543
|
+
ctx.tokens = tokens;
|
|
45544
|
+
ctx.measured = true;
|
|
45545
|
+
ctx.seq++;
|
|
45546
|
+
publish(entry, sessionId, db2);
|
|
45547
|
+
}
|
|
45548
|
+
function resetContext(entry, sessionId, db2) {
|
|
45549
|
+
if (entry.threadId) return;
|
|
45550
|
+
const ctx = counterOf(entry);
|
|
45551
|
+
ctx.tokens = null;
|
|
45552
|
+
ctx.measured = false;
|
|
45553
|
+
ctx.apiMessageId = null;
|
|
45554
|
+
ctx.seq++;
|
|
45555
|
+
void refreshContext(entry, sessionId, db2);
|
|
45556
|
+
}
|
|
45557
|
+
async function refreshContext(entry, sessionId, db2) {
|
|
45558
|
+
if (entry.threadId) return;
|
|
45559
|
+
const ctx = counterOf(entry);
|
|
45560
|
+
ctx.windowRequested = true;
|
|
45561
|
+
const seq = ctx.seq;
|
|
45562
|
+
try {
|
|
45563
|
+
const snap = await entry.query.getContextUsage({ detail: "summary" });
|
|
45564
|
+
if (snap.maxTokens > 0) {
|
|
45565
|
+
ctx.window = snap.maxTokens;
|
|
45566
|
+
ctx.autoCompactThreshold = snap.isAutoCompactEnabled && snap.autoCompactThreshold && snap.autoCompactThreshold > 0 ? snap.autoCompactThreshold : null;
|
|
45567
|
+
}
|
|
45568
|
+
if (ctx.seq === seq && !ctx.measured && snap.totalTokens > 0) ctx.tokens = snap.totalTokens;
|
|
45569
|
+
} catch {
|
|
45570
|
+
return;
|
|
45571
|
+
}
|
|
45572
|
+
publish(entry, sessionId, db2);
|
|
45573
|
+
}
|
|
45574
|
+
|
|
45481
45575
|
// src/claude/claude-provider.ts
|
|
45482
45576
|
var PromptQueue = class {
|
|
45483
45577
|
buffer = [];
|
|
@@ -45736,6 +45830,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45736
45830
|
turnId,
|
|
45737
45831
|
db2
|
|
45738
45832
|
);
|
|
45833
|
+
resetContext(entry, sessionId, db2);
|
|
45739
45834
|
} else if (sub === "task_started") {
|
|
45740
45835
|
handleTaskStarted(
|
|
45741
45836
|
message,
|
|
@@ -45772,7 +45867,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45772
45867
|
break;
|
|
45773
45868
|
}
|
|
45774
45869
|
case "assistant": {
|
|
45775
|
-
handleAssistantMessage(message, sessionId, turnId, db2);
|
|
45870
|
+
handleAssistantMessage(message, sessionId, turnId, entry, db2);
|
|
45776
45871
|
break;
|
|
45777
45872
|
}
|
|
45778
45873
|
case "user": {
|
|
@@ -45780,19 +45875,23 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45780
45875
|
break;
|
|
45781
45876
|
}
|
|
45782
45877
|
case "stream_event": {
|
|
45783
|
-
handleStreamEvent(message, sessionId, turnId);
|
|
45878
|
+
handleStreamEvent(message, sessionId, turnId, entry, db2);
|
|
45784
45879
|
break;
|
|
45785
45880
|
}
|
|
45786
45881
|
case "result": {
|
|
45787
45882
|
handleResultMessage(message, sessionId, turnId, entry, db2);
|
|
45788
45883
|
break;
|
|
45789
45884
|
}
|
|
45885
|
+
case "conversation_reset": {
|
|
45886
|
+
resetContext(entry, sessionId, db2);
|
|
45887
|
+
break;
|
|
45888
|
+
}
|
|
45790
45889
|
default:
|
|
45791
45890
|
break;
|
|
45792
45891
|
}
|
|
45793
45892
|
}
|
|
45794
45893
|
var TOOL_CALL_TYPES = /* @__PURE__ */ new Set(["command_execution", "file_change", "mcp_tool_call"]);
|
|
45795
|
-
function handleAssistantMessage(message, sessionId, turnId, db2) {
|
|
45894
|
+
function handleAssistantMessage(message, sessionId, turnId, entry, db2) {
|
|
45796
45895
|
const messageId = message.uuid;
|
|
45797
45896
|
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
45798
45897
|
if (parentToolUseId) {
|
|
@@ -45802,6 +45901,9 @@ function handleAssistantMessage(message, sessionId, turnId, db2) {
|
|
|
45802
45901
|
db2.prepare("UPDATE turns SET external_turn_id = ?, updated_at = ? WHERE id = ?").run(messageId, nowExt2, turnId);
|
|
45803
45902
|
return;
|
|
45804
45903
|
}
|
|
45904
|
+
if (message.message?.model !== "<synthetic>") {
|
|
45905
|
+
recordApiUsage(entry, sessionId, db2, message.message?.id ?? null, message.message?.usage);
|
|
45906
|
+
}
|
|
45805
45907
|
const content = message.message.content;
|
|
45806
45908
|
const anthropicMsgId = message.message?.id ?? messageId;
|
|
45807
45909
|
const thinkingTexts = thinkingAccumulator.get(messageId);
|
|
@@ -45858,12 +45960,19 @@ function handleUserMessage(message, sessionId, turnId, db2) {
|
|
|
45858
45960
|
);
|
|
45859
45961
|
}
|
|
45860
45962
|
}
|
|
45861
|
-
function handleStreamEvent(message, sessionId, turnId) {
|
|
45963
|
+
function handleStreamEvent(message, sessionId, turnId, entry, db2) {
|
|
45862
45964
|
const rawEvent = message.event;
|
|
45863
45965
|
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
45864
45966
|
if (rawEvent.type === "message_start" && rawEvent.message?.id && !parentToolUseId) {
|
|
45865
45967
|
streamingMessageIds.set(turnId, rawEvent.message.id);
|
|
45866
45968
|
}
|
|
45969
|
+
if (!parentToolUseId) {
|
|
45970
|
+
if (rawEvent.type === "message_start" && rawEvent.message?.id) {
|
|
45971
|
+
recordApiUsage(entry, sessionId, db2, rawEvent.message.id, rawEvent.message.usage);
|
|
45972
|
+
} else if (rawEvent.type === "message_delta") {
|
|
45973
|
+
recordApiUsage(entry, sessionId, db2, null, rawEvent.usage);
|
|
45974
|
+
}
|
|
45975
|
+
}
|
|
45867
45976
|
const delta = mapPartialDelta(message.event);
|
|
45868
45977
|
if (!delta) return;
|
|
45869
45978
|
if (parentToolUseId) return;
|
|
@@ -46042,24 +46151,7 @@ async function handleResultMessage(message, sessionId, turnId, entry, db2) {
|
|
|
46042
46151
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
46043
46152
|
db2.prepare("UPDATE turns SET token_usage = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(usage), now, turnId);
|
|
46044
46153
|
broadcast("turn:tokenUsage", { sessionId, turnId, usage });
|
|
46045
|
-
|
|
46046
|
-
const ctx = await entry.query.getContextUsage();
|
|
46047
|
-
if (ctx.totalTokens > 0 && ctx.maxTokens > 0) {
|
|
46048
|
-
const contextUsage = {
|
|
46049
|
-
totalTokens: ctx.totalTokens,
|
|
46050
|
-
contextWindow: ctx.maxTokens,
|
|
46051
|
-
percentage: Math.round(ctx.percentage)
|
|
46052
|
-
};
|
|
46053
|
-
broadcast("turn:contextUsage", { sessionId, ...contextUsage });
|
|
46054
|
-
const cuNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
46055
|
-
db2.prepare("UPDATE sessions SET context_usage = ?, updated_at = ? WHERE id = ?").run(
|
|
46056
|
-
JSON.stringify(contextUsage),
|
|
46057
|
-
cuNow,
|
|
46058
|
-
sessionId
|
|
46059
|
-
);
|
|
46060
|
-
}
|
|
46061
|
-
} catch {
|
|
46062
|
-
}
|
|
46154
|
+
await refreshContext(entry, sessionId, db2);
|
|
46063
46155
|
completeTurn(db2, sessionId, turnId, usage);
|
|
46064
46156
|
} else {
|
|
46065
46157
|
const errorMsg = message.errors?.join("; ") ?? "Claude turn failed";
|
|
@@ -46219,6 +46311,7 @@ async function setModel(sessionId, model) {
|
|
|
46219
46311
|
const entry = sessionMap2.get(sessionId);
|
|
46220
46312
|
if (!entry) return;
|
|
46221
46313
|
await entry.query.setModel(model);
|
|
46314
|
+
void refreshContext(entry, sessionId, getDb());
|
|
46222
46315
|
}
|
|
46223
46316
|
async function stopTask(sessionId, taskId) {
|
|
46224
46317
|
const entry = sessionMap2.get(sessionId);
|
|
@@ -16108,20 +16108,20 @@ var require_resolve = __commonJS({
|
|
|
16108
16108
|
return false;
|
|
16109
16109
|
}
|
|
16110
16110
|
function countKeys(schema) {
|
|
16111
|
-
let
|
|
16111
|
+
let count2 = 0;
|
|
16112
16112
|
for (const key in schema) {
|
|
16113
16113
|
if (key === "$ref")
|
|
16114
16114
|
return Infinity;
|
|
16115
|
-
|
|
16115
|
+
count2++;
|
|
16116
16116
|
if (SIMPLE_INLINED.has(key))
|
|
16117
16117
|
continue;
|
|
16118
16118
|
if (typeof schema[key] == "object") {
|
|
16119
|
-
(0, util_1.eachItem)(schema[key], (sch) =>
|
|
16119
|
+
(0, util_1.eachItem)(schema[key], (sch) => count2 += countKeys(sch));
|
|
16120
16120
|
}
|
|
16121
|
-
if (
|
|
16121
|
+
if (count2 === Infinity)
|
|
16122
16122
|
return Infinity;
|
|
16123
16123
|
}
|
|
16124
|
-
return
|
|
16124
|
+
return count2;
|
|
16125
16125
|
}
|
|
16126
16126
|
function getFullPath(resolver, id = "", normalize) {
|
|
16127
16127
|
if (normalize !== false)
|
|
@@ -19319,8 +19319,8 @@ var require_contains = __commonJS({
|
|
|
19319
19319
|
cxt.result(valid, () => cxt.reset());
|
|
19320
19320
|
function validateItemsWithCount() {
|
|
19321
19321
|
const schValid = gen.name("_valid");
|
|
19322
|
-
const
|
|
19323
|
-
validateItems(schValid, () => gen.if(schValid, () => checkLimits(
|
|
19322
|
+
const count2 = gen.let("count", 0);
|
|
19323
|
+
validateItems(schValid, () => gen.if(schValid, () => checkLimits(count2)));
|
|
19324
19324
|
}
|
|
19325
19325
|
function validateItems(_valid, block) {
|
|
19326
19326
|
gen.forRange("i", 0, len, (i) => {
|
|
@@ -19333,16 +19333,16 @@ var require_contains = __commonJS({
|
|
|
19333
19333
|
block();
|
|
19334
19334
|
});
|
|
19335
19335
|
}
|
|
19336
|
-
function checkLimits(
|
|
19337
|
-
gen.code((0, codegen_1._)`${
|
|
19336
|
+
function checkLimits(count2) {
|
|
19337
|
+
gen.code((0, codegen_1._)`${count2}++`);
|
|
19338
19338
|
if (max === void 0) {
|
|
19339
|
-
gen.if((0, codegen_1._)`${
|
|
19339
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true).break());
|
|
19340
19340
|
} else {
|
|
19341
|
-
gen.if((0, codegen_1._)`${
|
|
19341
|
+
gen.if((0, codegen_1._)`${count2} > ${max}`, () => gen.assign(valid, false).break());
|
|
19342
19342
|
if (min === 1)
|
|
19343
19343
|
gen.assign(valid, true);
|
|
19344
19344
|
else
|
|
19345
|
-
gen.if((0, codegen_1._)`${
|
|
19345
|
+
gen.if((0, codegen_1._)`${count2} >= ${min}`, () => gen.assign(valid, true));
|
|
19346
19346
|
}
|
|
19347
19347
|
}
|
|
19348
19348
|
}
|
|
@@ -21689,9 +21689,9 @@ var require_parseJson = __commonJS({
|
|
|
21689
21689
|
pos++;
|
|
21690
21690
|
} else if (c === "u") {
|
|
21691
21691
|
pos++;
|
|
21692
|
-
let
|
|
21692
|
+
let count2 = 4;
|
|
21693
21693
|
let code = 0;
|
|
21694
|
-
while (
|
|
21694
|
+
while (count2--) {
|
|
21695
21695
|
code <<= 4;
|
|
21696
21696
|
c = s[pos];
|
|
21697
21697
|
if (c === void 0) {
|
|
@@ -36953,7 +36953,7 @@ var require_fastify_plugin = __commonJS({
|
|
|
36953
36953
|
"use strict";
|
|
36954
36954
|
var getPluginName = require_getPluginName();
|
|
36955
36955
|
var toCamelCase = require_toCamelCase();
|
|
36956
|
-
var
|
|
36956
|
+
var count2 = 0;
|
|
36957
36957
|
function plugin(fn, options = {}) {
|
|
36958
36958
|
let autoName = false;
|
|
36959
36959
|
if (fn.default !== void 0) {
|
|
@@ -36977,7 +36977,7 @@ var require_fastify_plugin = __commonJS({
|
|
|
36977
36977
|
}
|
|
36978
36978
|
if (!options.name) {
|
|
36979
36979
|
autoName = true;
|
|
36980
|
-
options.name = getPluginName(fn) + "-auto-" +
|
|
36980
|
+
options.name = getPluginName(fn) + "-auto-" + count2++;
|
|
36981
36981
|
}
|
|
36982
36982
|
fn[Symbol.for("skip-override")] = options.encapsulate !== true;
|
|
36983
36983
|
fn[Symbol.for("fastify.display-name")] = options.name;
|
|
@@ -45465,6 +45465,100 @@ var EFFORT_LABELS2 = {
|
|
|
45465
45465
|
max: "Max"
|
|
45466
45466
|
};
|
|
45467
45467
|
|
|
45468
|
+
// src/claude/claude-context.ts
|
|
45469
|
+
function count(n) {
|
|
45470
|
+
return typeof n === "number" && Number.isFinite(n) ? n : 0;
|
|
45471
|
+
}
|
|
45472
|
+
function lastMessageIteration(iterations) {
|
|
45473
|
+
if (!Array.isArray(iterations)) return null;
|
|
45474
|
+
for (let i = iterations.length - 1; i >= 0; i--) {
|
|
45475
|
+
const it = iterations[i];
|
|
45476
|
+
if (!it || typeof it !== "object") continue;
|
|
45477
|
+
if ((it.type === "message" || it.type === "fallback_message") && typeof it.input_tokens === "number") return it;
|
|
45478
|
+
}
|
|
45479
|
+
return null;
|
|
45480
|
+
}
|
|
45481
|
+
function contextTokensFromUsage(usage) {
|
|
45482
|
+
if (!usage || typeof usage !== "object") return null;
|
|
45483
|
+
const u = lastMessageIteration(usage.iterations) ?? usage;
|
|
45484
|
+
const read = count(u.input_tokens) + count(u.cache_creation_input_tokens) + count(u.cache_read_input_tokens);
|
|
45485
|
+
if (read <= 0) return null;
|
|
45486
|
+
return read + count(u.output_tokens);
|
|
45487
|
+
}
|
|
45488
|
+
function counterOf(entry) {
|
|
45489
|
+
if (!entry.context) {
|
|
45490
|
+
entry.context = {
|
|
45491
|
+
window: null,
|
|
45492
|
+
autoCompactThreshold: null,
|
|
45493
|
+
tokens: null,
|
|
45494
|
+
measured: false,
|
|
45495
|
+
apiMessageId: null,
|
|
45496
|
+
seq: 0,
|
|
45497
|
+
windowRequested: false,
|
|
45498
|
+
lastPublished: null
|
|
45499
|
+
};
|
|
45500
|
+
}
|
|
45501
|
+
return entry.context;
|
|
45502
|
+
}
|
|
45503
|
+
function publish(entry, sessionId, db2) {
|
|
45504
|
+
const ctx = counterOf(entry);
|
|
45505
|
+
if (ctx.tokens === null) return;
|
|
45506
|
+
if (!ctx.window) {
|
|
45507
|
+
if (!ctx.windowRequested) void refreshContext(entry, sessionId, db2);
|
|
45508
|
+
return;
|
|
45509
|
+
}
|
|
45510
|
+
const usage = {
|
|
45511
|
+
totalTokens: ctx.tokens,
|
|
45512
|
+
contextWindow: ctx.window,
|
|
45513
|
+
percentage: Math.round(ctx.tokens / ctx.window * 100),
|
|
45514
|
+
...ctx.autoCompactThreshold ? { autoCompactThreshold: ctx.autoCompactThreshold } : {}
|
|
45515
|
+
};
|
|
45516
|
+
const json = JSON.stringify(usage);
|
|
45517
|
+
if (json === ctx.lastPublished) return;
|
|
45518
|
+
ctx.lastPublished = json;
|
|
45519
|
+
broadcast("turn:contextUsage", { sessionId, ...usage });
|
|
45520
|
+
db2.prepare("UPDATE sessions SET context_usage = ? WHERE id = ?").run(json, sessionId);
|
|
45521
|
+
}
|
|
45522
|
+
function recordApiUsage(entry, sessionId, db2, apiMessageId, usage) {
|
|
45523
|
+
if (entry.threadId) return;
|
|
45524
|
+
const tokens = contextTokensFromUsage(usage);
|
|
45525
|
+
if (tokens === null) return;
|
|
45526
|
+
const ctx = counterOf(entry);
|
|
45527
|
+
const id = apiMessageId ?? ctx.apiMessageId;
|
|
45528
|
+
if (ctx.measured && id !== null && id === ctx.apiMessageId && ctx.tokens !== null && tokens <= ctx.tokens) return;
|
|
45529
|
+
ctx.apiMessageId = id;
|
|
45530
|
+
ctx.tokens = tokens;
|
|
45531
|
+
ctx.measured = true;
|
|
45532
|
+
ctx.seq++;
|
|
45533
|
+
publish(entry, sessionId, db2);
|
|
45534
|
+
}
|
|
45535
|
+
function resetContext(entry, sessionId, db2) {
|
|
45536
|
+
if (entry.threadId) return;
|
|
45537
|
+
const ctx = counterOf(entry);
|
|
45538
|
+
ctx.tokens = null;
|
|
45539
|
+
ctx.measured = false;
|
|
45540
|
+
ctx.apiMessageId = null;
|
|
45541
|
+
ctx.seq++;
|
|
45542
|
+
void refreshContext(entry, sessionId, db2);
|
|
45543
|
+
}
|
|
45544
|
+
async function refreshContext(entry, sessionId, db2) {
|
|
45545
|
+
if (entry.threadId) return;
|
|
45546
|
+
const ctx = counterOf(entry);
|
|
45547
|
+
ctx.windowRequested = true;
|
|
45548
|
+
const seq = ctx.seq;
|
|
45549
|
+
try {
|
|
45550
|
+
const snap = await entry.query.getContextUsage({ detail: "summary" });
|
|
45551
|
+
if (snap.maxTokens > 0) {
|
|
45552
|
+
ctx.window = snap.maxTokens;
|
|
45553
|
+
ctx.autoCompactThreshold = snap.isAutoCompactEnabled && snap.autoCompactThreshold && snap.autoCompactThreshold > 0 ? snap.autoCompactThreshold : null;
|
|
45554
|
+
}
|
|
45555
|
+
if (ctx.seq === seq && !ctx.measured && snap.totalTokens > 0) ctx.tokens = snap.totalTokens;
|
|
45556
|
+
} catch {
|
|
45557
|
+
return;
|
|
45558
|
+
}
|
|
45559
|
+
publish(entry, sessionId, db2);
|
|
45560
|
+
}
|
|
45561
|
+
|
|
45468
45562
|
// src/claude/claude-provider.ts
|
|
45469
45563
|
var PromptQueue = class {
|
|
45470
45564
|
buffer = [];
|
|
@@ -45723,6 +45817,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45723
45817
|
turnId,
|
|
45724
45818
|
db2
|
|
45725
45819
|
);
|
|
45820
|
+
resetContext(entry, sessionId, db2);
|
|
45726
45821
|
} else if (sub === "task_started") {
|
|
45727
45822
|
handleTaskStarted(
|
|
45728
45823
|
message,
|
|
@@ -45759,7 +45854,7 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45759
45854
|
break;
|
|
45760
45855
|
}
|
|
45761
45856
|
case "assistant": {
|
|
45762
|
-
handleAssistantMessage(message, sessionId, turnId, db2);
|
|
45857
|
+
handleAssistantMessage(message, sessionId, turnId, entry, db2);
|
|
45763
45858
|
break;
|
|
45764
45859
|
}
|
|
45765
45860
|
case "user": {
|
|
@@ -45767,19 +45862,23 @@ async function handleMessage(message, sessionId, turnId, entry, db2) {
|
|
|
45767
45862
|
break;
|
|
45768
45863
|
}
|
|
45769
45864
|
case "stream_event": {
|
|
45770
|
-
handleStreamEvent(message, sessionId, turnId);
|
|
45865
|
+
handleStreamEvent(message, sessionId, turnId, entry, db2);
|
|
45771
45866
|
break;
|
|
45772
45867
|
}
|
|
45773
45868
|
case "result": {
|
|
45774
45869
|
handleResultMessage(message, sessionId, turnId, entry, db2);
|
|
45775
45870
|
break;
|
|
45776
45871
|
}
|
|
45872
|
+
case "conversation_reset": {
|
|
45873
|
+
resetContext(entry, sessionId, db2);
|
|
45874
|
+
break;
|
|
45875
|
+
}
|
|
45777
45876
|
default:
|
|
45778
45877
|
break;
|
|
45779
45878
|
}
|
|
45780
45879
|
}
|
|
45781
45880
|
var TOOL_CALL_TYPES = /* @__PURE__ */ new Set(["command_execution", "file_change", "mcp_tool_call"]);
|
|
45782
|
-
function handleAssistantMessage(message, sessionId, turnId, db2) {
|
|
45881
|
+
function handleAssistantMessage(message, sessionId, turnId, entry, db2) {
|
|
45783
45882
|
const messageId = message.uuid;
|
|
45784
45883
|
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
45785
45884
|
if (parentToolUseId) {
|
|
@@ -45789,6 +45888,9 @@ function handleAssistantMessage(message, sessionId, turnId, db2) {
|
|
|
45789
45888
|
db2.prepare("UPDATE turns SET external_turn_id = ?, updated_at = ? WHERE id = ?").run(messageId, nowExt2, turnId);
|
|
45790
45889
|
return;
|
|
45791
45890
|
}
|
|
45891
|
+
if (message.message?.model !== "<synthetic>") {
|
|
45892
|
+
recordApiUsage(entry, sessionId, db2, message.message?.id ?? null, message.message?.usage);
|
|
45893
|
+
}
|
|
45792
45894
|
const content = message.message.content;
|
|
45793
45895
|
const anthropicMsgId = message.message?.id ?? messageId;
|
|
45794
45896
|
const thinkingTexts = thinkingAccumulator.get(messageId);
|
|
@@ -45845,12 +45947,19 @@ function handleUserMessage(message, sessionId, turnId, db2) {
|
|
|
45845
45947
|
);
|
|
45846
45948
|
}
|
|
45847
45949
|
}
|
|
45848
|
-
function handleStreamEvent(message, sessionId, turnId) {
|
|
45950
|
+
function handleStreamEvent(message, sessionId, turnId, entry, db2) {
|
|
45849
45951
|
const rawEvent = message.event;
|
|
45850
45952
|
const parentToolUseId = message.parent_tool_use_id ?? null;
|
|
45851
45953
|
if (rawEvent.type === "message_start" && rawEvent.message?.id && !parentToolUseId) {
|
|
45852
45954
|
streamingMessageIds.set(turnId, rawEvent.message.id);
|
|
45853
45955
|
}
|
|
45956
|
+
if (!parentToolUseId) {
|
|
45957
|
+
if (rawEvent.type === "message_start" && rawEvent.message?.id) {
|
|
45958
|
+
recordApiUsage(entry, sessionId, db2, rawEvent.message.id, rawEvent.message.usage);
|
|
45959
|
+
} else if (rawEvent.type === "message_delta") {
|
|
45960
|
+
recordApiUsage(entry, sessionId, db2, null, rawEvent.usage);
|
|
45961
|
+
}
|
|
45962
|
+
}
|
|
45854
45963
|
const delta = mapPartialDelta(message.event);
|
|
45855
45964
|
if (!delta) return;
|
|
45856
45965
|
if (parentToolUseId) return;
|
|
@@ -46029,24 +46138,7 @@ async function handleResultMessage(message, sessionId, turnId, entry, db2) {
|
|
|
46029
46138
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
46030
46139
|
db2.prepare("UPDATE turns SET token_usage = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(usage), now, turnId);
|
|
46031
46140
|
broadcast("turn:tokenUsage", { sessionId, turnId, usage });
|
|
46032
|
-
|
|
46033
|
-
const ctx = await entry.query.getContextUsage();
|
|
46034
|
-
if (ctx.totalTokens > 0 && ctx.maxTokens > 0) {
|
|
46035
|
-
const contextUsage = {
|
|
46036
|
-
totalTokens: ctx.totalTokens,
|
|
46037
|
-
contextWindow: ctx.maxTokens,
|
|
46038
|
-
percentage: Math.round(ctx.percentage)
|
|
46039
|
-
};
|
|
46040
|
-
broadcast("turn:contextUsage", { sessionId, ...contextUsage });
|
|
46041
|
-
const cuNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
46042
|
-
db2.prepare("UPDATE sessions SET context_usage = ?, updated_at = ? WHERE id = ?").run(
|
|
46043
|
-
JSON.stringify(contextUsage),
|
|
46044
|
-
cuNow,
|
|
46045
|
-
sessionId
|
|
46046
|
-
);
|
|
46047
|
-
}
|
|
46048
|
-
} catch {
|
|
46049
|
-
}
|
|
46141
|
+
await refreshContext(entry, sessionId, db2);
|
|
46050
46142
|
completeTurn(db2, sessionId, turnId, usage);
|
|
46051
46143
|
} else {
|
|
46052
46144
|
const errorMsg = message.errors?.join("; ") ?? "Claude turn failed";
|
|
@@ -46206,6 +46298,7 @@ async function setModel(sessionId, model) {
|
|
|
46206
46298
|
const entry = sessionMap2.get(sessionId);
|
|
46207
46299
|
if (!entry) return;
|
|
46208
46300
|
await entry.query.setModel(model);
|
|
46301
|
+
void refreshContext(entry, sessionId, getDb());
|
|
46209
46302
|
}
|
|
46210
46303
|
async function stopTask(sessionId, taskId) {
|
|
46211
46304
|
const entry = sessionMap2.get(sessionId);
|