kimiflare 0.66.0 → 0.67.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/index.js CHANGED
@@ -3150,6 +3150,15 @@ var init_system_prompt = __esm({
3150
3150
  });
3151
3151
 
3152
3152
  // src/agent/loop.ts
3153
+ function getSessionWebFetchHistory(sessionId) {
3154
+ const key = sessionId ?? "default";
3155
+ let arr = sessionWebFetchHistory.get(key);
3156
+ if (!arr) {
3157
+ arr = [];
3158
+ sessionWebFetchHistory.set(key, arr);
3159
+ }
3160
+ return arr;
3161
+ }
3153
3162
  function isHighSignalMemory(memory) {
3154
3163
  return memory.topicKey === "project_dependencies" || memory.topicKey === "project_tsconfig" || memory.topicKey === "project_entry_point" || memory.category === "instruction" || memory.category === "preference" || memory.category === "event" && memory.importance >= 3;
3155
3164
  }
@@ -3304,7 +3313,8 @@ Use console.log() to return results. Only console.log output will be sent back t
3304
3313
  const recentToolCalls = [];
3305
3314
  const LOOP_WINDOW = 8;
3306
3315
  const LOOP_THRESHOLD = 2;
3307
- const webFetchHistory = [];
3316
+ const webFetchHistory = getSessionWebFetchHistory(opts2.sessionId);
3317
+ let webFetchesThisTurn = 0;
3308
3318
  const MAX_WEB_FETCH_PER_TURN = 5;
3309
3319
  const WEB_FETCH_DOMAIN_THRESHOLD = 2;
3310
3320
  let cumulativePromptTokens = 0;
@@ -3543,8 +3553,8 @@ Use console.log() to return results. Only console.log output will be sent back t
3543
3553
  try {
3544
3554
  const domain = new URL(url).hostname;
3545
3555
  const domainCount = webFetchHistory.filter((h) => h.domain === domain).length;
3546
- const totalWebFetches = webFetchHistory.length;
3547
- if (totalWebFetches >= MAX_WEB_FETCH_PER_TURN) {
3556
+ const totalSessionFetches = webFetchHistory.length;
3557
+ if (webFetchesThisTurn >= MAX_WEB_FETCH_PER_TURN) {
3548
3558
  const warning = `Research budget exceeded: you have already made ${MAX_WEB_FETCH_PER_TURN} web requests this turn. Synthesize what you have learned instead of fetching more pages.`;
3549
3559
  const budgetResult = {
3550
3560
  tool_call_id: tc.id,
@@ -3565,6 +3575,27 @@ Use console.log() to return results. Only console.log output will be sent back t
3565
3575
  blockedCount++;
3566
3576
  continue;
3567
3577
  }
3578
+ if (totalSessionFetches >= SESSION_WEB_FETCH_CAP) {
3579
+ const warning = `Session research budget exceeded: ${totalSessionFetches} web fetches across this session. Synthesize what you have learned from prior fetches instead of starting another page.`;
3580
+ const sessionCapResult = {
3581
+ tool_call_id: tc.id,
3582
+ name: "web_fetch",
3583
+ content: warning,
3584
+ ok: false
3585
+ };
3586
+ toolResults.push(sessionCapResult);
3587
+ opts2.messages.push({
3588
+ role: "tool",
3589
+ tool_call_id: tc.id,
3590
+ content: sanitizeString(warning),
3591
+ name: "web_fetch"
3592
+ });
3593
+ opts2.callbacks.onToolResult?.(sessionCapResult);
3594
+ recentToolCalls.push(loopSignature);
3595
+ if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
3596
+ blockedCount++;
3597
+ continue;
3598
+ }
3568
3599
  if (domainCount >= WEB_FETCH_DOMAIN_THRESHOLD) {
3569
3600
  const warning = `Loop detected: you have fetched from ${domain} multiple times. Consider a different approach or synthesize existing findings.`;
3570
3601
  const loopResult = {
@@ -3587,6 +3618,7 @@ Use console.log() to return results. Only console.log output will be sent back t
3587
3618
  continue;
3588
3619
  }
3589
3620
  webFetchHistory.push({ url, domain });
3621
+ webFetchesThisTurn++;
3590
3622
  } catch {
3591
3623
  }
3592
3624
  }
@@ -3622,9 +3654,16 @@ Use console.log() to return results. Only console.log output will be sent back t
3622
3654
  Output:
3623
3655
  ${sandboxResult.output}` : sandboxResult.output;
3624
3656
  if (resultContent.length > MAX_TOOL_CONTENT_CHARS) {
3657
+ const rawBytes = resultContent.length;
3625
3658
  resultContent = resultContent.slice(0, MAX_TOOL_CONTENT_CHARS) + `
3626
3659
 
3627
- [truncated: ${resultContent.length - MAX_TOOL_CONTENT_CHARS} chars omitted]`;
3660
+ [truncated: ${rawBytes - MAX_TOOL_CONTENT_CHARS} chars omitted]`;
3661
+ opts2.callbacks.onTruncation?.({
3662
+ tool: "execute_code",
3663
+ toolCallId: tc.id,
3664
+ rawBytes,
3665
+ reducedBytes: resultContent.length
3666
+ });
3628
3667
  }
3629
3668
  const result = {
3630
3669
  tool_call_id: tc.id,
@@ -3653,9 +3692,17 @@ ${sandboxResult.output}` : sandboxResult.output;
3653
3692
  );
3654
3693
  let content2 = result.content;
3655
3694
  if (content2.length > MAX_TOOL_CONTENT_CHARS) {
3695
+ const rawBytes = content2.length;
3656
3696
  content2 = content2.slice(0, MAX_TOOL_CONTENT_CHARS) + `
3657
3697
 
3658
- [truncated: ${content2.length - MAX_TOOL_CONTENT_CHARS} chars omitted]`;
3698
+ [truncated: ${rawBytes - MAX_TOOL_CONTENT_CHARS} chars omitted]`;
3699
+ opts2.callbacks.onTruncation?.({
3700
+ tool: tc.function.name,
3701
+ toolCallId: tc.id,
3702
+ rawBytes,
3703
+ reducedBytes: content2.length,
3704
+ artifactId: result.artifactId
3705
+ });
3659
3706
  }
3660
3707
  logger.debug("turn:tool_end", { sessionId: opts2.sessionId, tool: tc.function.name, toolCallId: tc.id, ok: result.ok });
3661
3708
  toolResults.push(result);
@@ -3679,6 +3726,7 @@ ${sandboxResult.output}` : sandboxResult.output;
3679
3726
  );
3680
3727
  const assistantMessage = lastAssistant?.content ?? "";
3681
3728
  const llmOpts = opts2.memoryManager.getExtractionLlmOpts();
3729
+ const turnAtMemoryCommit = turn;
3682
3730
  for (const extractor of EXTRACTORS) {
3683
3731
  if (extractor.match(tc.function.name, filePath)) {
3684
3732
  void (async () => {
@@ -3704,11 +3752,14 @@ ${sandboxResult.output}` : sandboxResult.output;
3704
3752
  );
3705
3753
  if (isHighSignalMemory(memory)) {
3706
3754
  const sid = opts2.sessionId ?? "default";
3707
- const current = (driftAccumulator.get(sid) ?? 0) + 1;
3708
- driftAccumulator.set(sid, current);
3709
- if (current >= DRIFT_THRESHOLD) {
3755
+ const events2 = driftEvents.get(sid) ?? [];
3756
+ events2.push(turnAtMemoryCommit);
3757
+ const cutoff = turnAtMemoryCommit - DRIFT_WINDOW + 1;
3758
+ const recent = events2.filter((t) => t >= cutoff);
3759
+ driftEvents.set(sid, recent);
3760
+ if (recent.length >= DRIFT_THRESHOLD) {
3710
3761
  opts2.callbacks.onKimiMdStale?.();
3711
- driftAccumulator.set(sid, 0);
3762
+ driftEvents.set(sid, []);
3712
3763
  }
3713
3764
  }
3714
3765
  }
@@ -3740,12 +3791,6 @@ ${sandboxResult.output}` : sandboxResult.output;
3740
3791
  if (blockedCount === toolCalls.length && toolCalls.length > 0) {
3741
3792
  loopExhausted = true;
3742
3793
  }
3743
- if (opts2.sessionId) {
3744
- const current = driftAccumulator.get(opts2.sessionId) ?? 0;
3745
- if (current > 0) {
3746
- driftAccumulator.set(opts2.sessionId, Math.max(0, current - 1));
3747
- }
3748
- }
3749
3794
  if (opts2.onIterationEnd) {
3750
3795
  opts2.messages = await opts2.onIterationEnd(opts2.messages, opts2.signal);
3751
3796
  if (opts2.signal.aborted) throw new DOMException("aborted", "AbortError");
@@ -3804,7 +3849,7 @@ function validateToolArguments(raw) {
3804
3849
  return "{}";
3805
3850
  }
3806
3851
  }
3807
- var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD, memoryExtractionErrorCounts, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
3852
+ var BudgetExhaustedError, AgentLoopError, codeModeApiCache, driftEvents, DRIFT_WINDOW, DRIFT_THRESHOLD, memoryExtractionErrorCounts, sessionWebFetchHistory, SESSION_WEB_FETCH_CAP, MAX_PROMPT_TOKENS, MAX_TOOL_CONTENT_CHARS;
3808
3853
  var init_loop = __esm({
3809
3854
  "src/agent/loop.ts"() {
3810
3855
  "use strict";
@@ -3832,9 +3877,12 @@ var init_loop = __esm({
3832
3877
  }
3833
3878
  };
3834
3879
  codeModeApiCache = /* @__PURE__ */ new Map();
3835
- driftAccumulator = /* @__PURE__ */ new Map();
3836
- DRIFT_THRESHOLD = 5;
3880
+ driftEvents = /* @__PURE__ */ new Map();
3881
+ DRIFT_WINDOW = 10;
3882
+ DRIFT_THRESHOLD = 3;
3837
3883
  memoryExtractionErrorCounts = /* @__PURE__ */ new Map();
3884
+ sessionWebFetchHistory = /* @__PURE__ */ new Map();
3885
+ SESSION_WEB_FETCH_CAP = 25;
3838
3886
  MAX_PROMPT_TOKENS = 24e4;
3839
3887
  MAX_TOOL_CONTENT_CHARS = 1e4;
3840
3888
  }