kimiflare 0.17.0 → 0.19.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
@@ -39,6 +39,8 @@ async function loadConfig() {
39
39
  const cacheStablePrompts = envCacheStable === "0" || envCacheStable === "false" ? false : true;
40
40
  const envCompiled = process.env.KIMIFLARE_COMPILED_CONTEXT;
41
41
  const compiledContext = envCompiled === "1" || envCompiled === "true" ? true : false;
42
+ const envImageTurns = process.env.KIMIFLARE_IMAGE_HISTORY_TURNS;
43
+ const imageHistoryTurns = envImageTurns ? parseInt(envImageTurns, 10) : void 0;
42
44
  if (envAccount && envToken) {
43
45
  return {
44
46
  accountId: envAccount,
@@ -50,7 +52,8 @@ async function loadConfig() {
50
52
  coauthorName: envCoauthor?.name,
51
53
  coauthorEmail: envCoauthor?.email,
52
54
  cacheStablePrompts,
53
- compiledContext
55
+ compiledContext,
56
+ imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns
54
57
  };
55
58
  }
56
59
  try {
@@ -68,7 +71,8 @@ async function loadConfig() {
68
71
  coauthorEmail: envCoauthor?.email ?? parsed.coauthorEmail,
69
72
  mcpServers: parsed.mcpServers,
70
73
  cacheStablePrompts: parsed.cacheStablePrompts ?? cacheStablePrompts,
71
- compiledContext: parsed.compiledContext ?? compiledContext
74
+ compiledContext: parsed.compiledContext ?? compiledContext,
75
+ imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns
72
76
  };
73
77
  }
74
78
  } catch {
@@ -175,6 +179,30 @@ function stableStringify(value, replacer, space) {
175
179
  const sorted = sortKeys(value);
176
180
  return JSON.stringify(sorted, replacer, space);
177
181
  }
182
+ function stripOldImages(messages, keepLastTurns) {
183
+ if (keepLastTurns < 0) return messages;
184
+ let userCount = 0;
185
+ let cutoffIndex = messages.length;
186
+ for (let i = messages.length - 1; i >= 0; i--) {
187
+ if (messages[i].role === "user") {
188
+ userCount++;
189
+ if (userCount === keepLastTurns) {
190
+ cutoffIndex = i;
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ return messages.map((m, idx) => {
196
+ if (m.role !== "user" || idx >= cutoffIndex) return m;
197
+ if (!Array.isArray(m.content)) return m;
198
+ const stripped = m.content.filter((p) => p.type !== "image_url");
199
+ if (stripped.length === m.content.length) return m;
200
+ return {
201
+ ...m,
202
+ content: stripped.length > 0 ? stripped : "[image omitted]"
203
+ };
204
+ });
205
+ }
178
206
  var init_messages = __esm({
179
207
  "src/agent/messages.ts"() {
180
208
  "use strict";
@@ -653,7 +681,8 @@ async function logTurnDebug(ctx) {
653
681
  toolTotalReducedBytes: toolTotalReduced,
654
682
  toolSavingsPct: toolTotalRaw > 0 ? Math.round((toolTotalRaw - toolTotalReduced) / toolTotalRaw * 100) : 0,
655
683
  cacheDiagnostics,
656
- compaction: ctx.compaction
684
+ compaction: ctx.compaction,
685
+ shadowStrip: ctx.shadowStrip
657
686
  });
658
687
  }
659
688
  var LOG_VERSION;
@@ -665,6 +694,53 @@ var init_cost_debug = __esm({
665
694
  }
666
695
  });
667
696
 
697
+ // src/agent/strip-reasoning.ts
698
+ function stripHistoricalReasoning(messages, opts2 = {}) {
699
+ const keepLast = opts2.keepLast ?? DEFAULT_KEEP_LAST;
700
+ const assistantIndices = [];
701
+ for (let i = 0; i < messages.length; i++) {
702
+ if (messages[i].role === "assistant") {
703
+ assistantIndices.push(i);
704
+ }
705
+ }
706
+ const preservedSet = keepLast === 0 ? /* @__PURE__ */ new Set() : new Set(assistantIndices.slice(-keepLast));
707
+ return messages.map((m, idx) => {
708
+ if (m.role !== "assistant") return m;
709
+ if (preservedSet.has(idx)) return m;
710
+ const next = { ...m };
711
+ delete next.reasoning_content;
712
+ if (next.tool_calls && next.tool_calls.length > 0) {
713
+ if (typeof next.content === "string") {
714
+ next.content = "";
715
+ } else if (Array.isArray(next.content)) {
716
+ next.content = next.content.map(
717
+ (part) => part.type === "text" ? { ...part, text: "" } : part
718
+ );
719
+ }
720
+ return next;
721
+ }
722
+ const textLen = typeof next.content === "string" ? next.content.length : Array.isArray(next.content) ? next.content.filter((p) => p.type === "text").reduce((sum, p) => sum + p.text.length, 0) : 0;
723
+ if (textLen <= SUBSTANTIVE_TEXT_THRESHOLD) {
724
+ if (typeof next.content === "string") {
725
+ next.content = "";
726
+ } else if (Array.isArray(next.content)) {
727
+ next.content = next.content.map(
728
+ (part) => part.type === "text" ? { ...part, text: "" } : part
729
+ );
730
+ }
731
+ }
732
+ return next;
733
+ });
734
+ }
735
+ var DEFAULT_KEEP_LAST, SUBSTANTIVE_TEXT_THRESHOLD;
736
+ var init_strip_reasoning = __esm({
737
+ "src/agent/strip-reasoning.ts"() {
738
+ "use strict";
739
+ DEFAULT_KEEP_LAST = 1;
740
+ SUBSTANTIVE_TEXT_THRESHOLD = 200;
741
+ }
742
+ });
743
+
668
744
  // src/agent/loop.ts
669
745
  async function runAgentTurn(opts2) {
670
746
  const max = opts2.maxToolIterations ?? 50;
@@ -679,11 +755,47 @@ async function runAgentTurn(opts2) {
679
755
  let content = "";
680
756
  let reasoning = "";
681
757
  opts2.callbacks.onAssistantStart?.();
758
+ const stripReasoning = process.env.KIMIFLARE_STRIP_REASONING === "1";
759
+ const shadowStrip = process.env.KIMIFLARE_SHADOW_STRIP === "1";
760
+ const keepLastRaw = process.env.KIMIFLARE_REASONING_KEEP_LAST;
761
+ const keepLast = keepLastRaw ? parseInt(keepLastRaw, 10) : 1;
762
+ let apiMessages = opts2.messages;
763
+ let shadowStripMetrics;
764
+ if (stripReasoning || shadowStrip) {
765
+ const stripped = stripHistoricalReasoning(opts2.messages, {
766
+ keepLast: Number.isNaN(keepLast) ? 1 : keepLast
767
+ });
768
+ if (shadowStrip) {
769
+ const originalSections = analyzePrompt(opts2.messages);
770
+ const strippedSections = analyzePrompt(stripped);
771
+ const originalApproxTokens = originalSections.reduce(
772
+ (sum, s) => sum + s.approxTokens,
773
+ 0
774
+ );
775
+ const strippedApproxTokens = strippedSections.reduce(
776
+ (sum, s) => sum + s.approxTokens,
777
+ 0
778
+ );
779
+ shadowStripMetrics = {
780
+ originalApproxTokens,
781
+ strippedApproxTokens,
782
+ savingsPct: originalApproxTokens > 0 ? Math.round(
783
+ (originalApproxTokens - strippedApproxTokens) / originalApproxTokens * 100
784
+ ) : 0
785
+ };
786
+ }
787
+ if (stripReasoning) {
788
+ apiMessages = stripped;
789
+ }
790
+ }
791
+ if (opts2.keepLastImageTurns !== void 0) {
792
+ apiMessages = stripOldImages(apiMessages, opts2.keepLastImageTurns);
793
+ }
682
794
  const events = runKimi({
683
795
  accountId: opts2.accountId,
684
796
  apiToken: opts2.apiToken,
685
797
  model: opts2.model,
686
- messages: opts2.messages,
798
+ messages: apiMessages,
687
799
  tools: toolDefs,
688
800
  signal: opts2.signal,
689
801
  temperature: opts2.temperature,
@@ -750,7 +862,8 @@ async function runAgentTurn(opts2) {
750
862
  messages: opts2.messages,
751
863
  previousMessages,
752
864
  toolResults,
753
- usage: lastUsage
865
+ usage: lastUsage,
866
+ shadowStrip: shadowStripMetrics
754
867
  });
755
868
  }
756
869
  return;
@@ -778,7 +891,8 @@ async function runAgentTurn(opts2) {
778
891
  messages: opts2.messages,
779
892
  previousMessages,
780
893
  toolResults,
781
- usage: lastUsage
894
+ usage: lastUsage,
895
+ shadowStrip: shadowStripMetrics
782
896
  });
783
897
  }
784
898
  }
@@ -800,6 +914,7 @@ var init_loop = __esm({
800
914
  init_registry();
801
915
  init_messages();
802
916
  init_cost_debug();
917
+ init_strip_reasoning();
803
918
  }
804
919
  });
805
920
 
@@ -5987,6 +6102,7 @@ use: /thinking low | medium | high`
5987
6102
  reasoningEffort: effortRef.current,
5988
6103
  coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
5989
6104
  sessionId: ensureSessionId(),
6105
+ keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
5990
6106
  callbacks: {
5991
6107
  onAssistantStart: () => {
5992
6108
  const id = nextAssistantId++;