kimiflare 0.89.1 → 0.90.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
@@ -26805,6 +26805,179 @@ var init_plan_complete_picker = __esm({
26805
26805
  }
26806
26806
  });
26807
26807
 
26808
+ // src/agent/distill.ts
26809
+ function distillSessionPlan(messages) {
26810
+ for (let i = messages.length - 1; i >= 0; i--) {
26811
+ const m = messages[i];
26812
+ if (m?.role !== "assistant") continue;
26813
+ let text = "";
26814
+ if (typeof m.content === "string") {
26815
+ text = m.content;
26816
+ } else if (Array.isArray(m.content)) {
26817
+ text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
26818
+ }
26819
+ text = text.trim();
26820
+ if (text.length > 20) {
26821
+ return text;
26822
+ }
26823
+ }
26824
+ return null;
26825
+ }
26826
+ var init_distill = __esm({
26827
+ "src/agent/distill.ts"() {
26828
+ "use strict";
26829
+ }
26830
+ });
26831
+
26832
+ // src/agent/continuation-summary.ts
26833
+ import { execSync as execSync4 } from "child_process";
26834
+ function extractFirstUserGoal(messages) {
26835
+ const texts = [];
26836
+ for (const m of messages) {
26837
+ if (m.role !== "user") continue;
26838
+ let text = "";
26839
+ if (typeof m.content === "string") {
26840
+ text = m.content;
26841
+ } else if (Array.isArray(m.content)) {
26842
+ text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
26843
+ }
26844
+ text = text.trim();
26845
+ if (text.length > 5) {
26846
+ texts.push(text);
26847
+ if (texts.length >= 3) break;
26848
+ }
26849
+ }
26850
+ return texts.join("\n---\n");
26851
+ }
26852
+ function extractRecentAssistantMessages(messages, count = 3) {
26853
+ const texts = [];
26854
+ for (let i = messages.length - 1; i >= 0 && texts.length < count; i--) {
26855
+ const m = messages[i];
26856
+ if (m?.role !== "assistant") continue;
26857
+ let text = "";
26858
+ if (typeof m.content === "string") {
26859
+ text = m.content;
26860
+ } else if (Array.isArray(m.content)) {
26861
+ text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
26862
+ }
26863
+ text = text.trim();
26864
+ if (text.length > 10) {
26865
+ texts.unshift(text);
26866
+ }
26867
+ }
26868
+ return texts.join("\n---\n");
26869
+ }
26870
+ function gatherGitEvidence() {
26871
+ const pieces = [];
26872
+ try {
26873
+ const branch = execSync4("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim();
26874
+ if (branch) pieces.push(`Branch: ${branch}`);
26875
+ } catch {
26876
+ }
26877
+ try {
26878
+ const log2 = execSync4("git log --oneline -5", { cwd: process.cwd(), encoding: "utf8" }).trim();
26879
+ if (log2) pieces.push(`Recent commits:
26880
+ ${log2}`);
26881
+ } catch {
26882
+ }
26883
+ try {
26884
+ const status = execSync4("git status --short", { cwd: process.cwd(), encoding: "utf8" }).trim();
26885
+ if (status) pieces.push(`Working tree changes:
26886
+ ${status}`);
26887
+ } catch {
26888
+ }
26889
+ return pieces.join("\n\n");
26890
+ }
26891
+ async function gatherMemoryEvidence(manager, enabled, signal) {
26892
+ if (!enabled) return "";
26893
+ try {
26894
+ const cwd = process.cwd();
26895
+ const results = await manager.recall({ text: cwd, repoPath: cwd, limit: 10 });
26896
+ const highSignal = results.filter(
26897
+ (r) => ["edit_event", "task", "instruction"].includes(r.memory.category)
26898
+ );
26899
+ if (highSignal.length === 0) return "";
26900
+ const synthesized = await manager.synthesizeRecalled(highSignal, signal);
26901
+ return synthesized ? `Recorded work log:
26902
+ ${synthesized}` : "";
26903
+ } catch {
26904
+ return "";
26905
+ }
26906
+ }
26907
+ async function runKimiText2(opts2) {
26908
+ const events = runKimi({
26909
+ accountId: opts2.accountId,
26910
+ apiToken: opts2.apiToken,
26911
+ model: opts2.model,
26912
+ messages: opts2.messages,
26913
+ temperature: 0.1,
26914
+ reasoningEffort: "low",
26915
+ gateway: opts2.gateway,
26916
+ signal: opts2.signal
26917
+ });
26918
+ let text = "";
26919
+ for await (const ev of events) {
26920
+ if (ev.type === "text") text += ev.delta;
26921
+ }
26922
+ return text.trim();
26923
+ }
26924
+ async function generateContinuationSummary(opts2) {
26925
+ const { messages, mode } = opts2;
26926
+ if (mode === "plan") {
26927
+ return distillSessionPlan(messages);
26928
+ }
26929
+ const goal = extractFirstUserGoal(messages);
26930
+ const recentAssistant = extractRecentAssistantMessages(messages);
26931
+ const gitEvidence = gatherGitEvidence();
26932
+ const memoryEvidence = opts2.memoryManager ? await gatherMemoryEvidence(opts2.memoryManager, opts2.memoryEnabled ?? false, opts2.signal) : "";
26933
+ const evidenceParts = [];
26934
+ if (goal) evidenceParts.push(`## Original goal(s)
26935
+ ${goal}`);
26936
+ if (recentAssistant) evidenceParts.push(`## Recent assistant messages
26937
+ ${recentAssistant}`);
26938
+ if (gitEvidence) evidenceParts.push(`## Git state
26939
+ ${gitEvidence}`);
26940
+ if (memoryEvidence) evidenceParts.push(`## ${memoryEvidence}`);
26941
+ if (evidenceParts.length === 0) {
26942
+ return null;
26943
+ }
26944
+ const userPrompt = evidenceParts.join("\n\n");
26945
+ const summary = await runKimiText2({
26946
+ accountId: opts2.accountId,
26947
+ apiToken: opts2.apiToken,
26948
+ model: opts2.model,
26949
+ gateway: opts2.gateway,
26950
+ signal: opts2.signal,
26951
+ messages: [
26952
+ { role: "system", content: HANDOFF_SYSTEM },
26953
+ { role: "user", content: userPrompt }
26954
+ ]
26955
+ });
26956
+ return summary || null;
26957
+ }
26958
+ var HANDOFF_SYSTEM;
26959
+ var init_continuation_summary = __esm({
26960
+ "src/agent/continuation-summary.ts"() {
26961
+ "use strict";
26962
+ init_client();
26963
+ init_distill();
26964
+ HANDOFF_SYSTEM = `You are a session-continuation engine. Given evidence from a coding session, produce a dense handoff document so a new agent can pick up exactly where this one left off.
26965
+
26966
+ Output format (use these exact headings):
26967
+ Goal: what the user originally asked for.
26968
+ Completed: files modified, tests added, key decisions, commits made.
26969
+ Remaining: what still needs to be done.
26970
+ Current state: any open errors, incomplete refactors, or pending work.
26971
+ Context: relevant file paths or architectural notes.
26972
+
26973
+ Rules:
26974
+ - Be terse but complete. A new agent with zero prior context must be able to continue.
26975
+ - Do not include chat-style pleasantries.
26976
+ - Do not speculate beyond the evidence provided.
26977
+ - Aim for ~300-600 tokens.`;
26978
+ }
26979
+ });
26980
+
26808
26981
  // src/ui/use-session-manager.ts
26809
26982
  import { useCallback as useCallback8, useRef as useRef5, useState as useState27 } from "react";
26810
26983
  function extractFirstUserText(messages) {
@@ -26819,6 +26992,17 @@ function extractFirstUserText(messages) {
26819
26992
  }
26820
26993
  return "session";
26821
26994
  }
26995
+ function buildLocalResumeSummary(state) {
26996
+ const parts = [];
26997
+ if (state.task) parts.push(`Task: ${state.task}`);
26998
+ if (state.files_modified.length > 0) {
26999
+ parts.push(`Modified: ${state.files_modified.join(", ")}`);
27000
+ }
27001
+ if (state.next_actions.length > 0) {
27002
+ parts.push(`Next: ${state.next_actions.slice(0, 3).join("; ")}`);
27003
+ }
27004
+ return parts.length > 0 ? parts.join(" | ") : null;
27005
+ }
26822
27006
  function useSessionManager(deps) {
26823
27007
  const sessionIdRef = useRef5(null);
26824
27008
  const sessionCreatedAtRef = useRef5(null);
@@ -26898,6 +27082,43 @@ function useSessionManager(deps) {
26898
27082
  const nonSystemCount = file.messages.filter((m) => m.role !== "system").length;
26899
27083
  const msg = checkpointId ? `resumed session ${file.id} from checkpoint` : `resumed session ${file.id} (${nonSystemCount} msgs)`;
26900
27084
  d.setEvents([{ kind: "info", key: d.mkKey(), text: msg }]);
27085
+ const localSummary = buildLocalResumeSummary(d.sessionStateRef.current);
27086
+ if (localSummary) {
27087
+ d.setEvents((es) => [
27088
+ ...es,
27089
+ { kind: "info", key: d.mkKey(), text: localSummary }
27090
+ ]);
27091
+ }
27092
+ if (d.cfg && d.cfg.accountId && d.cfg.apiToken) {
27093
+ d.setEvents((es) => [
27094
+ ...es,
27095
+ { kind: "info", key: d.mkKey(), text: "generating session summary\u2026" }
27096
+ ]);
27097
+ try {
27098
+ const summary = await generateContinuationSummary({
27099
+ messages: d.messagesRef.current,
27100
+ mode: d.mode,
27101
+ accountId: d.cfg.accountId,
27102
+ apiToken: d.cfg.apiToken,
27103
+ model: d.cfg.plumbingModel ?? "@cf/moonshotai/kimi-k2.5",
27104
+ gateway: gatewayFromConfig(d.cfg),
27105
+ memoryManager: d.memoryManagerRef.current,
27106
+ memoryEnabled: d.cfg.memoryEnabled
27107
+ });
27108
+ if (summary) {
27109
+ d.setEvents((es) => [
27110
+ ...es,
27111
+ { kind: "info", key: d.mkKey(), text: summary }
27112
+ ]);
27113
+ d.messagesRef.current.push({
27114
+ role: "system",
27115
+ content: `[session resume summary]
27116
+ ${summary}`
27117
+ });
27118
+ }
27119
+ } catch {
27120
+ }
27121
+ }
26901
27122
  if (!checkpointId) {
26902
27123
  const threshold = d.cfg?.autoFreshSuggestionTurns ?? DEFAULT_AUTO_FRESH_SUGGESTION_TURNS;
26903
27124
  if (threshold > 0 && nonSystemCount >= threshold && (d.mode === "auto" || d.mode === "edit" || d.mode === "multi-agent-experimental")) {
@@ -27011,6 +27232,7 @@ var init_use_session_manager = __esm({
27011
27232
  init_usage_tracker();
27012
27233
  init_log_sink();
27013
27234
  init_app_helpers();
27235
+ init_continuation_summary();
27014
27236
  }
27015
27237
  });
27016
27238
 
@@ -27465,30 +27687,6 @@ var init_manager5 = __esm({
27465
27687
  }
27466
27688
  });
27467
27689
 
27468
- // src/agent/distill.ts
27469
- function distillSessionPlan(messages) {
27470
- for (let i = messages.length - 1; i >= 0; i--) {
27471
- const m = messages[i];
27472
- if (m?.role !== "assistant") continue;
27473
- let text = "";
27474
- if (typeof m.content === "string") {
27475
- text = m.content;
27476
- } else if (Array.isArray(m.content)) {
27477
- text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
27478
- }
27479
- text = text.trim();
27480
- if (text.length > 20) {
27481
- return text;
27482
- }
27483
- }
27484
- return null;
27485
- }
27486
- var init_distill = __esm({
27487
- "src/agent/distill.ts"() {
27488
- "use strict";
27489
- }
27490
- });
27491
-
27492
27690
  // src/agent/plan-resolver.ts
27493
27691
  function resolvePlanForFresh(opts2) {
27494
27692
  const { mode, messages, sessionPlan, memoryManager, memoryEnabled, repoPath } = opts2;
@@ -27515,155 +27713,6 @@ var init_plan_resolver = __esm({
27515
27713
  }
27516
27714
  });
27517
27715
 
27518
- // src/agent/continuation-summary.ts
27519
- import { execSync as execSync4 } from "child_process";
27520
- function extractFirstUserGoal(messages) {
27521
- const texts = [];
27522
- for (const m of messages) {
27523
- if (m.role !== "user") continue;
27524
- let text = "";
27525
- if (typeof m.content === "string") {
27526
- text = m.content;
27527
- } else if (Array.isArray(m.content)) {
27528
- text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
27529
- }
27530
- text = text.trim();
27531
- if (text.length > 5) {
27532
- texts.push(text);
27533
- if (texts.length >= 3) break;
27534
- }
27535
- }
27536
- return texts.join("\n---\n");
27537
- }
27538
- function extractRecentAssistantMessages(messages, count = 3) {
27539
- const texts = [];
27540
- for (let i = messages.length - 1; i >= 0 && texts.length < count; i--) {
27541
- const m = messages[i];
27542
- if (m?.role !== "assistant") continue;
27543
- let text = "";
27544
- if (typeof m.content === "string") {
27545
- text = m.content;
27546
- } else if (Array.isArray(m.content)) {
27547
- text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
27548
- }
27549
- text = text.trim();
27550
- if (text.length > 10) {
27551
- texts.unshift(text);
27552
- }
27553
- }
27554
- return texts.join("\n---\n");
27555
- }
27556
- function gatherGitEvidence() {
27557
- const pieces = [];
27558
- try {
27559
- const branch = execSync4("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim();
27560
- if (branch) pieces.push(`Branch: ${branch}`);
27561
- } catch {
27562
- }
27563
- try {
27564
- const log2 = execSync4("git log --oneline -5", { cwd: process.cwd(), encoding: "utf8" }).trim();
27565
- if (log2) pieces.push(`Recent commits:
27566
- ${log2}`);
27567
- } catch {
27568
- }
27569
- try {
27570
- const status = execSync4("git status --short", { cwd: process.cwd(), encoding: "utf8" }).trim();
27571
- if (status) pieces.push(`Working tree changes:
27572
- ${status}`);
27573
- } catch {
27574
- }
27575
- return pieces.join("\n\n");
27576
- }
27577
- async function gatherMemoryEvidence(manager, enabled, signal) {
27578
- if (!enabled) return "";
27579
- try {
27580
- const cwd = process.cwd();
27581
- const results = await manager.recall({ text: cwd, repoPath: cwd, limit: 10 });
27582
- const highSignal = results.filter(
27583
- (r) => ["edit_event", "task", "instruction"].includes(r.memory.category)
27584
- );
27585
- if (highSignal.length === 0) return "";
27586
- const synthesized = await manager.synthesizeRecalled(highSignal, signal);
27587
- return synthesized ? `Recorded work log:
27588
- ${synthesized}` : "";
27589
- } catch {
27590
- return "";
27591
- }
27592
- }
27593
- async function runKimiText2(opts2) {
27594
- const events = runKimi({
27595
- accountId: opts2.accountId,
27596
- apiToken: opts2.apiToken,
27597
- model: opts2.model,
27598
- messages: opts2.messages,
27599
- temperature: 0.1,
27600
- reasoningEffort: "low",
27601
- gateway: opts2.gateway,
27602
- signal: opts2.signal
27603
- });
27604
- let text = "";
27605
- for await (const ev of events) {
27606
- if (ev.type === "text") text += ev.delta;
27607
- }
27608
- return text.trim();
27609
- }
27610
- async function generateContinuationSummary(opts2) {
27611
- const { messages, mode } = opts2;
27612
- if (mode === "plan") {
27613
- return distillSessionPlan(messages);
27614
- }
27615
- const goal = extractFirstUserGoal(messages);
27616
- const recentAssistant = extractRecentAssistantMessages(messages);
27617
- const gitEvidence = gatherGitEvidence();
27618
- const memoryEvidence = opts2.memoryManager ? await gatherMemoryEvidence(opts2.memoryManager, opts2.memoryEnabled ?? false, opts2.signal) : "";
27619
- const evidenceParts = [];
27620
- if (goal) evidenceParts.push(`## Original goal(s)
27621
- ${goal}`);
27622
- if (recentAssistant) evidenceParts.push(`## Recent assistant messages
27623
- ${recentAssistant}`);
27624
- if (gitEvidence) evidenceParts.push(`## Git state
27625
- ${gitEvidence}`);
27626
- if (memoryEvidence) evidenceParts.push(`## ${memoryEvidence}`);
27627
- if (evidenceParts.length === 0) {
27628
- return null;
27629
- }
27630
- const userPrompt = evidenceParts.join("\n\n");
27631
- const summary = await runKimiText2({
27632
- accountId: opts2.accountId,
27633
- apiToken: opts2.apiToken,
27634
- model: opts2.model,
27635
- gateway: opts2.gateway,
27636
- signal: opts2.signal,
27637
- messages: [
27638
- { role: "system", content: HANDOFF_SYSTEM },
27639
- { role: "user", content: userPrompt }
27640
- ]
27641
- });
27642
- return summary || null;
27643
- }
27644
- var HANDOFF_SYSTEM;
27645
- var init_continuation_summary = __esm({
27646
- "src/agent/continuation-summary.ts"() {
27647
- "use strict";
27648
- init_client();
27649
- init_distill();
27650
- HANDOFF_SYSTEM = `You are a session-continuation engine. Given evidence from a coding session, produce a dense handoff document so a new agent can pick up exactly where this one left off.
27651
-
27652
- Output format (use these exact headings):
27653
- Goal: what the user originally asked for.
27654
- Completed: files modified, tests added, key decisions, commits made.
27655
- Remaining: what still needs to be done.
27656
- Current state: any open errors, incomplete refactors, or pending work.
27657
- Context: relevant file paths or architectural notes.
27658
-
27659
- Rules:
27660
- - Be terse but complete. A new agent with zero prior context must be able to continue.
27661
- - Do not include chat-style pleasantries.
27662
- - Do not speculate beyond the evidence provided.
27663
- - Aim for ~300-600 tokens.`;
27664
- }
27665
- });
27666
-
27667
27716
  // src/util/clipboard.ts
27668
27717
  import { execSync as execSync5 } from "child_process";
27669
27718
  import { platform as platform6 } from "os";