kimiflare 0.20.0 → 0.20.1
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 +61 -559
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,12 +41,6 @@ async function loadConfig() {
|
|
|
41
41
|
const compiledContext = envCompiled === "1" || envCompiled === "true" ? true : false;
|
|
42
42
|
const envImageTurns = process.env.KIMIFLARE_IMAGE_HISTORY_TURNS;
|
|
43
43
|
const imageHistoryTurns = envImageTurns ? parseInt(envImageTurns, 10) : void 0;
|
|
44
|
-
const envMaxToolIterations = process.env.KIMIFLARE_MAX_TOOL_ITERATIONS;
|
|
45
|
-
const maxToolIterations = envMaxToolIterations ? parseInt(envMaxToolIterations, 10) : void 0;
|
|
46
|
-
const envMaxInputTokens = process.env.KIMIFLARE_MAX_INPUT_TOKENS;
|
|
47
|
-
const maxInputTokens = envMaxInputTokens ? parseInt(envMaxInputTokens, 10) : void 0;
|
|
48
|
-
const envMaxCompletionTokens = process.env.KIMIFLARE_MAX_COMPLETION_TOKENS;
|
|
49
|
-
const maxCompletionTokens = envMaxCompletionTokens ? parseInt(envMaxCompletionTokens, 10) : void 0;
|
|
50
44
|
if (envAccount && envToken) {
|
|
51
45
|
return {
|
|
52
46
|
accountId: envAccount,
|
|
@@ -59,10 +53,7 @@ async function loadConfig() {
|
|
|
59
53
|
coauthorEmail: envCoauthor?.email,
|
|
60
54
|
cacheStablePrompts,
|
|
61
55
|
compiledContext,
|
|
62
|
-
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns
|
|
63
|
-
maxToolIterations: Number.isNaN(maxToolIterations) ? void 0 : maxToolIterations,
|
|
64
|
-
maxInputTokens: Number.isNaN(maxInputTokens) ? void 0 : maxInputTokens,
|
|
65
|
-
maxCompletionTokens: Number.isNaN(maxCompletionTokens) ? void 0 : maxCompletionTokens
|
|
56
|
+
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? void 0 : imageHistoryTurns
|
|
66
57
|
};
|
|
67
58
|
}
|
|
68
59
|
try {
|
|
@@ -81,10 +72,7 @@ async function loadConfig() {
|
|
|
81
72
|
mcpServers: parsed.mcpServers,
|
|
82
73
|
cacheStablePrompts: parsed.cacheStablePrompts ?? cacheStablePrompts,
|
|
83
74
|
compiledContext: parsed.compiledContext ?? compiledContext,
|
|
84
|
-
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns
|
|
85
|
-
maxToolIterations: Number.isNaN(maxToolIterations) ? parsed.maxToolIterations : maxToolIterations,
|
|
86
|
-
maxInputTokens: Number.isNaN(maxInputTokens) ? parsed.maxInputTokens : maxInputTokens,
|
|
87
|
-
maxCompletionTokens: Number.isNaN(maxCompletionTokens) ? parsed.maxCompletionTokens : maxCompletionTokens
|
|
75
|
+
imageHistoryTurns: Number.isNaN(imageHistoryTurns) ? parsed.imageHistoryTurns : imageHistoryTurns
|
|
88
76
|
};
|
|
89
77
|
}
|
|
90
78
|
} catch {
|
|
@@ -191,14 +179,14 @@ function stableStringify(value, replacer, space) {
|
|
|
191
179
|
const sorted = sortKeys(value);
|
|
192
180
|
return JSON.stringify(sorted, replacer, space);
|
|
193
181
|
}
|
|
194
|
-
function stripOldImages(messages,
|
|
195
|
-
if (
|
|
182
|
+
function stripOldImages(messages, keepLastTurns) {
|
|
183
|
+
if (keepLastTurns < 0) return messages;
|
|
196
184
|
let userCount = 0;
|
|
197
185
|
let cutoffIndex = messages.length;
|
|
198
186
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
199
187
|
if (messages[i].role === "user") {
|
|
200
188
|
userCount++;
|
|
201
|
-
if (userCount ===
|
|
189
|
+
if (userCount === keepLastTurns) {
|
|
202
190
|
cutoffIndex = i;
|
|
203
191
|
break;
|
|
204
192
|
}
|
|
@@ -239,7 +227,7 @@ async function* runKimi(opts2) {
|
|
|
239
227
|
...opts2.tools && opts2.tools.length ? { tools: opts2.tools, tool_choice: "auto", parallel_tool_calls: true } : {},
|
|
240
228
|
stream: true,
|
|
241
229
|
temperature: opts2.temperature ?? 0.2,
|
|
242
|
-
max_completion_tokens: opts2.maxCompletionTokens ??
|
|
230
|
+
max_completion_tokens: opts2.maxCompletionTokens ?? 16384
|
|
243
231
|
};
|
|
244
232
|
if (opts2.reasoningEffort) {
|
|
245
233
|
body.reasoning_effort = opts2.reasoningEffort;
|
|
@@ -429,7 +417,7 @@ var init_client = __esm({
|
|
|
429
417
|
init_errors();
|
|
430
418
|
init_messages();
|
|
431
419
|
RETRYABLE_CODES = /* @__PURE__ */ new Set([3040]);
|
|
432
|
-
MAX_ATTEMPTS =
|
|
420
|
+
MAX_ATTEMPTS = 5;
|
|
433
421
|
}
|
|
434
422
|
});
|
|
435
423
|
|
|
@@ -609,37 +597,6 @@ async function logCostDebug(entry) {
|
|
|
609
597
|
await rotateJsonl(debugPath(), RETENTION.costDebugMaxBytes, RETENTION.costDebugRotations);
|
|
610
598
|
await appendFile(debugPath(), JSON.stringify(entry) + "\n", "utf8");
|
|
611
599
|
}
|
|
612
|
-
function usageDir() {
|
|
613
|
-
return join3(homedir2(), ".kimiflare");
|
|
614
|
-
}
|
|
615
|
-
function usagePath() {
|
|
616
|
-
return join3(usageDir(), "usage.jsonl");
|
|
617
|
-
}
|
|
618
|
-
async function logTurnTokenMetrics(metrics) {
|
|
619
|
-
await mkdir2(usageDir(), { recursive: true });
|
|
620
|
-
await rotateJsonl(usagePath(), RETENTION.costDebugMaxBytes, RETENTION.costDebugRotations);
|
|
621
|
-
await appendFile(usagePath(), JSON.stringify(metrics) + "\n", "utf8");
|
|
622
|
-
}
|
|
623
|
-
function buildTurnTokenMetrics(sessionId, turn, breakdown, estimatedOutputTokenCap, wasCompacted, removedCount, exceedsLimit) {
|
|
624
|
-
return {
|
|
625
|
-
v: LOG_VERSION,
|
|
626
|
-
ts: now(),
|
|
627
|
-
sessionId,
|
|
628
|
-
turn,
|
|
629
|
-
estimatedInputTokens: breakdown.total,
|
|
630
|
-
estimatedOutputTokenCap,
|
|
631
|
-
messageCount: breakdown.messageCount,
|
|
632
|
-
toolOutputCount: breakdown.toolOutputCount,
|
|
633
|
-
tokensFromSystem: breakdown.fromSystem,
|
|
634
|
-
tokensFromSession: breakdown.fromSession,
|
|
635
|
-
tokensFromTools: breakdown.fromTools,
|
|
636
|
-
tokensFromHistory: breakdown.fromHistory,
|
|
637
|
-
tokensFromUserInput: breakdown.fromUserInput,
|
|
638
|
-
wasCompacted,
|
|
639
|
-
removedCount,
|
|
640
|
-
exceedsLimit
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
600
|
function serializePrefix(messages) {
|
|
644
601
|
let end = 0;
|
|
645
602
|
while (end < messages.length && messages[end].role === "system") {
|
|
@@ -784,282 +741,12 @@ var init_strip_reasoning = __esm({
|
|
|
784
741
|
}
|
|
785
742
|
});
|
|
786
743
|
|
|
787
|
-
// src/agent/token-limits.ts
|
|
788
|
-
function loadSafetyLimits() {
|
|
789
|
-
return {
|
|
790
|
-
maxInputTokensPerRequest: parseIntEnv("KIMIFLARE_MAX_INPUT_TOKENS", DEFAULT_SAFETY_LIMITS.maxInputTokensPerRequest),
|
|
791
|
-
warningThreshold: parseIntEnv("KIMIFLARE_WARNING_TOKENS", DEFAULT_SAFETY_LIMITS.warningThreshold),
|
|
792
|
-
maxLlmCallsPerUserAction: parseIntEnv("KIMIFLARE_MAX_LLM_CALLS", DEFAULT_SAFETY_LIMITS.maxLlmCallsPerUserAction),
|
|
793
|
-
maxRetriesPerLlmCall: parseIntEnv("KIMIFLARE_MAX_RETRIES", DEFAULT_SAFETY_LIMITS.maxRetriesPerLlmCall),
|
|
794
|
-
maxCompletionTokens: parseIntEnv("KIMIFLARE_MAX_COMPLETION_TOKENS", DEFAULT_SAFETY_LIMITS.maxCompletionTokens),
|
|
795
|
-
maxToolIterations: parseIntEnv("KIMIFLARE_MAX_TOOL_ITERATIONS", DEFAULT_SAFETY_LIMITS.maxToolIterations),
|
|
796
|
-
maxRecentMessages: parseIntEnv("KIMIFLARE_MAX_RECENT_MESSAGES", DEFAULT_SAFETY_LIMITS.maxRecentMessages),
|
|
797
|
-
maxToolOutputChars: parseIntEnv("KIMIFLARE_MAX_TOOL_OUTPUT_CHARS", DEFAULT_SAFETY_LIMITS.maxToolOutputChars)
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
function parseIntEnv(name, fallback) {
|
|
801
|
-
const raw = process.env[name];
|
|
802
|
-
if (!raw) return fallback;
|
|
803
|
-
const n = parseInt(raw, 10);
|
|
804
|
-
return Number.isNaN(n) ? fallback : n;
|
|
805
|
-
}
|
|
806
|
-
function estimateTokens(text) {
|
|
807
|
-
return Math.ceil(text.length / 4);
|
|
808
|
-
}
|
|
809
|
-
function estimateMessageTokens(m) {
|
|
810
|
-
let chars = 0;
|
|
811
|
-
if (typeof m.content === "string") {
|
|
812
|
-
chars = m.content.length;
|
|
813
|
-
} else if (Array.isArray(m.content)) {
|
|
814
|
-
for (const part of m.content) {
|
|
815
|
-
if (part.type === "text") chars += part.text.length;
|
|
816
|
-
else if (part.type === "image_url") chars += 1e3;
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
if (m.reasoning_content) chars += m.reasoning_content.length;
|
|
820
|
-
if (m.tool_calls) {
|
|
821
|
-
for (const tc of m.tool_calls) {
|
|
822
|
-
chars += tc.function.name.length;
|
|
823
|
-
chars += tc.function.arguments.length;
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
return Math.ceil(chars / 4) + 4;
|
|
827
|
-
}
|
|
828
|
-
function estimateMessagesTokens(messages) {
|
|
829
|
-
return messages.reduce((sum, m) => sum + estimateMessageTokens(m), 0);
|
|
830
|
-
}
|
|
831
|
-
function estimateToolDefsTokens(tools) {
|
|
832
|
-
return estimateTokens(JSON.stringify(tools));
|
|
833
|
-
}
|
|
834
|
-
function breakdownTokens(systemMessages, sessionMessages, toolDefs, historyMessages, userMessage) {
|
|
835
|
-
const fromSystem = estimateMessagesTokens(systemMessages);
|
|
836
|
-
const fromSession = estimateMessagesTokens(sessionMessages);
|
|
837
|
-
const fromTools = estimateToolDefsTokens(toolDefs);
|
|
838
|
-
const fromHistory = estimateMessagesTokens(historyMessages);
|
|
839
|
-
const fromUserInput = userMessage ? estimateMessageTokens(userMessage) : 0;
|
|
840
|
-
return {
|
|
841
|
-
total: fromSystem + fromSession + fromTools + fromHistory + fromUserInput,
|
|
842
|
-
fromSystem,
|
|
843
|
-
fromSession,
|
|
844
|
-
fromTools,
|
|
845
|
-
fromHistory,
|
|
846
|
-
fromUserInput,
|
|
847
|
-
messageCount: systemMessages.length + sessionMessages.length + historyMessages.length + (userMessage ? 1 : 0),
|
|
848
|
-
toolOutputCount: historyMessages.filter((m) => m.role === "tool").length
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
function compactHistoryForSafety(messages, targetTokens) {
|
|
852
|
-
let compacted = messages.map((m) => {
|
|
853
|
-
if (m.role === "tool" && typeof m.content === "string" && m.content.length > 200) {
|
|
854
|
-
const lines = m.content.split("\n");
|
|
855
|
-
const firstLine2 = lines[0] ?? "";
|
|
856
|
-
const truncated = lines.length > 3 || m.content.length > 200;
|
|
857
|
-
return {
|
|
858
|
-
...m,
|
|
859
|
-
content: `[${m.name ?? "tool"} result${truncated ? " (truncated)" : ""}] ${firstLine2.slice(0, 120)}`
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
return m;
|
|
863
|
-
});
|
|
864
|
-
let removedCount = 0;
|
|
865
|
-
while (estimateMessagesTokens(compacted) > targetTokens && compacted.length > 2) {
|
|
866
|
-
const dropIndex = compacted.findIndex((m, i) => i > 0 && m.role !== "system" && m.role !== "user");
|
|
867
|
-
if (dropIndex === -1) break;
|
|
868
|
-
compacted.splice(dropIndex, 1);
|
|
869
|
-
removedCount++;
|
|
870
|
-
}
|
|
871
|
-
return { messages: compacted, removedCount };
|
|
872
|
-
}
|
|
873
|
-
var DEFAULT_SAFETY_LIMITS;
|
|
874
|
-
var init_token_limits = __esm({
|
|
875
|
-
"src/agent/token-limits.ts"() {
|
|
876
|
-
"use strict";
|
|
877
|
-
DEFAULT_SAFETY_LIMITS = {
|
|
878
|
-
maxInputTokensPerRequest: 3e4,
|
|
879
|
-
warningThreshold: 15e3,
|
|
880
|
-
maxLlmCallsPerUserAction: 10,
|
|
881
|
-
maxRetriesPerLlmCall: 2,
|
|
882
|
-
maxCompletionTokens: 4096,
|
|
883
|
-
maxToolIterations: 10,
|
|
884
|
-
maxRecentMessages: 4,
|
|
885
|
-
maxToolOutputChars: 800
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
});
|
|
889
|
-
|
|
890
|
-
// src/agent/tool-output-summarizer.ts
|
|
891
|
-
import { createHash } from "crypto";
|
|
892
|
-
function normalizeForHash(text) {
|
|
893
|
-
return text.toLowerCase().replace(/\s+/g, " ").trim().slice(0, 5e3);
|
|
894
|
-
}
|
|
895
|
-
function stableHash(text) {
|
|
896
|
-
return createHash("sha256").update(text).digest("hex").slice(0, 16);
|
|
897
|
-
}
|
|
898
|
-
function clearOutputHashCache() {
|
|
899
|
-
outputHashCache.clear();
|
|
900
|
-
}
|
|
901
|
-
function summarizeToolOutput(toolCallId, name, rawContent, maxChars = DEFAULT_MAX_CHARS) {
|
|
902
|
-
const normalized = normalizeForHash(rawContent);
|
|
903
|
-
const hash = stableHash(normalized);
|
|
904
|
-
const cached = outputHashCache.get(hash);
|
|
905
|
-
if (cached && cached.firstSeenId !== toolCallId) {
|
|
906
|
-
const ref = `same as previous ${cached.name ?? "tool"} call (result_id=${hash})`;
|
|
907
|
-
return {
|
|
908
|
-
tool_call_id: toolCallId,
|
|
909
|
-
name,
|
|
910
|
-
content: ref,
|
|
911
|
-
truncated: false
|
|
912
|
-
};
|
|
913
|
-
}
|
|
914
|
-
if (!cached) {
|
|
915
|
-
const preview = rawContent.slice(0, 120).replace(/\s+/g, " ");
|
|
916
|
-
outputHashCache.set(hash, { name, firstSeenId: toolCallId, preview });
|
|
917
|
-
}
|
|
918
|
-
const isFailure = rawContent.startsWith("Error:") || rawContent.startsWith("error:") || rawContent.includes("exit code") || rawContent.includes("not found") || rawContent.includes("No such file");
|
|
919
|
-
const isNoisy = rawContent.length > 0 && (rawContent.split("\n").length > 100 || rawContent.length > maxChars * 2);
|
|
920
|
-
if (isFailure && rawContent.length > 200) {
|
|
921
|
-
const firstLine2 = rawContent.split("\n")[0] ?? "";
|
|
922
|
-
return {
|
|
923
|
-
tool_call_id: toolCallId,
|
|
924
|
-
name,
|
|
925
|
-
content: `[${name ?? "tool"} failed] ${firstLine2.slice(0, 160)}`,
|
|
926
|
-
truncated: true
|
|
927
|
-
};
|
|
928
|
-
}
|
|
929
|
-
if (rawContent.length <= maxChars) {
|
|
930
|
-
return {
|
|
931
|
-
tool_call_id: toolCallId,
|
|
932
|
-
name,
|
|
933
|
-
content: rawContent,
|
|
934
|
-
truncated: false
|
|
935
|
-
};
|
|
936
|
-
}
|
|
937
|
-
const truncated = rawContent.slice(0, maxChars);
|
|
938
|
-
const lastNewline = truncated.lastIndexOf("\n");
|
|
939
|
-
const clean = lastNewline > maxChars * 0.5 ? truncated.slice(0, lastNewline) : truncated;
|
|
940
|
-
return {
|
|
941
|
-
tool_call_id: toolCallId,
|
|
942
|
-
name,
|
|
943
|
-
content: `${clean}
|
|
944
|
-
... (${rawContent.length - clean.length} more chars truncated)`,
|
|
945
|
-
truncated: true
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
function summarizeToolMessage(msg, maxChars = DEFAULT_MAX_CHARS) {
|
|
949
|
-
if (msg.role !== "tool" || typeof msg.content !== "string") {
|
|
950
|
-
return msg;
|
|
951
|
-
}
|
|
952
|
-
const summary = summarizeToolOutput(msg.tool_call_id ?? "", msg.name, msg.content, maxChars);
|
|
953
|
-
return {
|
|
954
|
-
...msg,
|
|
955
|
-
content: summary.content
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
function summarizeToolMessages(messages, maxChars = DEFAULT_MAX_CHARS) {
|
|
959
|
-
return messages.map((m) => m.role === "tool" ? summarizeToolMessage(m, maxChars) : m);
|
|
960
|
-
}
|
|
961
|
-
var DEFAULT_MAX_CHARS, outputHashCache;
|
|
962
|
-
var init_tool_output_summarizer = __esm({
|
|
963
|
-
"src/agent/tool-output-summarizer.ts"() {
|
|
964
|
-
"use strict";
|
|
965
|
-
DEFAULT_MAX_CHARS = 800;
|
|
966
|
-
outputHashCache = /* @__PURE__ */ new Map();
|
|
967
|
-
}
|
|
968
|
-
});
|
|
969
|
-
|
|
970
|
-
// src/agent/context-builder.ts
|
|
971
|
-
function buildContext(opts2) {
|
|
972
|
-
const { allMessages, systemMessages, sessionMessages, toolDefs, limits, currentUserMessage } = opts2;
|
|
973
|
-
const prefixLength = systemMessages.length + sessionMessages.length;
|
|
974
|
-
let history = allMessages.slice(prefixLength);
|
|
975
|
-
history = summarizeToolMessages(history, limits.maxToolOutputChars);
|
|
976
|
-
const recentHistory = keepLastTurns(history, limits.maxRecentMessages);
|
|
977
|
-
const contextMessages = [
|
|
978
|
-
...systemMessages,
|
|
979
|
-
...sessionMessages,
|
|
980
|
-
...recentHistory
|
|
981
|
-
];
|
|
982
|
-
if (currentUserMessage) {
|
|
983
|
-
contextMessages.push(currentUserMessage);
|
|
984
|
-
}
|
|
985
|
-
let breakdown = breakdownTokens(
|
|
986
|
-
systemMessages,
|
|
987
|
-
sessionMessages,
|
|
988
|
-
toolDefs,
|
|
989
|
-
recentHistory,
|
|
990
|
-
currentUserMessage ?? null
|
|
991
|
-
);
|
|
992
|
-
let wasCompacted = false;
|
|
993
|
-
let removedCount = 0;
|
|
994
|
-
if (breakdown.total > limits.maxInputTokensPerRequest) {
|
|
995
|
-
const target = limits.maxInputTokensPerRequest;
|
|
996
|
-
const compacted = compactHistoryForSafety(recentHistory, target - breakdown.fromSystem - breakdown.fromSession - breakdown.fromTools - breakdown.fromUserInput);
|
|
997
|
-
if (compacted.removedCount > 0) {
|
|
998
|
-
wasCompacted = true;
|
|
999
|
-
removedCount = compacted.removedCount;
|
|
1000
|
-
const newContext = [
|
|
1001
|
-
...systemMessages,
|
|
1002
|
-
...sessionMessages,
|
|
1003
|
-
...compacted.messages
|
|
1004
|
-
];
|
|
1005
|
-
if (currentUserMessage) {
|
|
1006
|
-
newContext.push(currentUserMessage);
|
|
1007
|
-
}
|
|
1008
|
-
breakdown = breakdownTokens(
|
|
1009
|
-
systemMessages,
|
|
1010
|
-
sessionMessages,
|
|
1011
|
-
toolDefs,
|
|
1012
|
-
compacted.messages,
|
|
1013
|
-
currentUserMessage ?? null
|
|
1014
|
-
);
|
|
1015
|
-
return {
|
|
1016
|
-
messages: newContext,
|
|
1017
|
-
breakdown,
|
|
1018
|
-
wasCompacted,
|
|
1019
|
-
removedCount,
|
|
1020
|
-
exceedsLimit: breakdown.total > limits.maxInputTokensPerRequest
|
|
1021
|
-
};
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return {
|
|
1025
|
-
messages: contextMessages,
|
|
1026
|
-
breakdown,
|
|
1027
|
-
wasCompacted,
|
|
1028
|
-
removedCount,
|
|
1029
|
-
exceedsLimit: breakdown.total > limits.maxInputTokensPerRequest
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
function keepLastTurns(messages, maxTurns) {
|
|
1033
|
-
if (maxTurns <= 0) return [];
|
|
1034
|
-
const turnStarts = [];
|
|
1035
|
-
for (let i = 0; i < messages.length; i++) {
|
|
1036
|
-
if (messages[i].role === "user") {
|
|
1037
|
-
turnStarts.push(i);
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
if (turnStarts.length <= maxTurns) {
|
|
1041
|
-
return messages;
|
|
1042
|
-
}
|
|
1043
|
-
const startIndex = turnStarts[turnStarts.length - maxTurns] ?? 0;
|
|
1044
|
-
return messages.slice(startIndex);
|
|
1045
|
-
}
|
|
1046
|
-
var init_context_builder = __esm({
|
|
1047
|
-
"src/agent/context-builder.ts"() {
|
|
1048
|
-
"use strict";
|
|
1049
|
-
init_token_limits();
|
|
1050
|
-
init_tool_output_summarizer();
|
|
1051
|
-
}
|
|
1052
|
-
});
|
|
1053
|
-
|
|
1054
744
|
// src/agent/loop.ts
|
|
1055
745
|
async function runAgentTurn(opts2) {
|
|
1056
|
-
const
|
|
1057
|
-
const max = opts2.maxToolIterations ?? limits.maxToolIterations;
|
|
746
|
+
const max = opts2.maxToolIterations ?? 50;
|
|
1058
747
|
const toolDefs = toOpenAIToolDefs(opts2.tools);
|
|
1059
748
|
let turn = 0;
|
|
1060
749
|
let lastUsage = null;
|
|
1061
|
-
const systemMessages = opts2.systemMessages ?? extractSystemMessages(opts2.messages);
|
|
1062
|
-
const sessionMessages = opts2.sessionMessages ?? [];
|
|
1063
750
|
for (let iter = 0; iter < max; iter++) {
|
|
1064
751
|
turn++;
|
|
1065
752
|
const previousMessages = opts2.messages.slice();
|
|
@@ -1079,8 +766,8 @@ async function runAgentTurn(opts2) {
|
|
|
1079
766
|
keepLast: Number.isNaN(keepLast) ? 1 : keepLast
|
|
1080
767
|
});
|
|
1081
768
|
if (shadowStrip) {
|
|
1082
|
-
const originalSections =
|
|
1083
|
-
const strippedSections =
|
|
769
|
+
const originalSections = analyzePrompt(opts2.messages);
|
|
770
|
+
const strippedSections = analyzePrompt(stripped);
|
|
1084
771
|
const originalApproxTokens = originalSections.reduce(
|
|
1085
772
|
(sum, s) => sum + s.approxTokens,
|
|
1086
773
|
0
|
|
@@ -1104,46 +791,15 @@ async function runAgentTurn(opts2) {
|
|
|
1104
791
|
if (opts2.keepLastImageTurns !== void 0) {
|
|
1105
792
|
apiMessages = stripOldImages(apiMessages, opts2.keepLastImageTurns);
|
|
1106
793
|
}
|
|
1107
|
-
const currentUserMessage = findCurrentUserMessage(apiMessages);
|
|
1108
|
-
const context = buildContext({
|
|
1109
|
-
allMessages: apiMessages,
|
|
1110
|
-
systemMessages,
|
|
1111
|
-
sessionMessages,
|
|
1112
|
-
toolDefs,
|
|
1113
|
-
limits,
|
|
1114
|
-
currentUserMessage
|
|
1115
|
-
});
|
|
1116
|
-
if (opts2.sessionId) {
|
|
1117
|
-
void logTurnTokenMetrics(
|
|
1118
|
-
buildTurnTokenMetrics(
|
|
1119
|
-
opts2.sessionId,
|
|
1120
|
-
turn,
|
|
1121
|
-
context.breakdown,
|
|
1122
|
-
opts2.maxCompletionTokens ?? limits.maxCompletionTokens,
|
|
1123
|
-
context.wasCompacted,
|
|
1124
|
-
context.removedCount,
|
|
1125
|
-
context.exceedsLimit
|
|
1126
|
-
)
|
|
1127
|
-
);
|
|
1128
|
-
}
|
|
1129
|
-
if (context.exceedsLimit) {
|
|
1130
|
-
const assistantMsg3 = {
|
|
1131
|
-
role: "assistant",
|
|
1132
|
-
content: `I cannot continue: the conversation context exceeds the safety limit of ${limits.maxInputTokensPerRequest} tokens. Try running /compact or /clear to reduce context size.`
|
|
1133
|
-
};
|
|
1134
|
-
opts2.messages.push(assistantMsg3);
|
|
1135
|
-
opts2.callbacks.onAssistantFinal?.(assistantMsg3);
|
|
1136
|
-
return;
|
|
1137
|
-
}
|
|
1138
794
|
const events = runKimi({
|
|
1139
795
|
accountId: opts2.accountId,
|
|
1140
796
|
apiToken: opts2.apiToken,
|
|
1141
797
|
model: opts2.model,
|
|
1142
|
-
messages:
|
|
798
|
+
messages: apiMessages,
|
|
1143
799
|
tools: toolDefs,
|
|
1144
800
|
signal: opts2.signal,
|
|
1145
801
|
temperature: opts2.temperature,
|
|
1146
|
-
maxCompletionTokens: opts2.maxCompletionTokens
|
|
802
|
+
maxCompletionTokens: opts2.maxCompletionTokens,
|
|
1147
803
|
reasoningEffort: opts2.reasoningEffort,
|
|
1148
804
|
sessionId: opts2.sessionId
|
|
1149
805
|
});
|
|
@@ -1182,7 +838,7 @@ async function runAgentTurn(opts2) {
|
|
|
1182
838
|
break;
|
|
1183
839
|
}
|
|
1184
840
|
}
|
|
1185
|
-
const
|
|
841
|
+
const assistantMsg = {
|
|
1186
842
|
role: "assistant",
|
|
1187
843
|
content: content ? sanitizeString(content) : null,
|
|
1188
844
|
...reasoning ? { reasoning_content: sanitizeString(reasoning) } : {},
|
|
@@ -1196,8 +852,8 @@ async function runAgentTurn(opts2) {
|
|
|
1196
852
|
}))
|
|
1197
853
|
} : {}
|
|
1198
854
|
};
|
|
1199
|
-
opts2.messages.push(
|
|
1200
|
-
opts2.callbacks.onAssistantFinal?.(
|
|
855
|
+
opts2.messages.push(assistantMsg);
|
|
856
|
+
opts2.callbacks.onAssistantFinal?.(assistantMsg);
|
|
1201
857
|
if (toolCalls.length === 0) {
|
|
1202
858
|
if (opts2.sessionId && lastUsage) {
|
|
1203
859
|
void logTurnDebug({
|
|
@@ -1240,36 +896,7 @@ async function runAgentTurn(opts2) {
|
|
|
1240
896
|
});
|
|
1241
897
|
}
|
|
1242
898
|
}
|
|
1243
|
-
|
|
1244
|
-
const assistantMsg = {
|
|
1245
|
-
role: "assistant",
|
|
1246
|
-
content: `I reached the tool iteration limit (${max}). There ${remaining === 1 ? "is" : "are"} ${remaining} pending tool call${remaining === 1 ? "" : "s"} that could not be executed. Run /compact or /clear to reset context, or rephrase your request.`
|
|
1247
|
-
};
|
|
1248
|
-
opts2.messages.push(assistantMsg);
|
|
1249
|
-
opts2.callbacks.onAssistantFinal?.(assistantMsg);
|
|
1250
|
-
}
|
|
1251
|
-
function extractSystemMessages(messages) {
|
|
1252
|
-
const end = messages.findIndex((m) => m.role !== "system");
|
|
1253
|
-
return end === -1 ? messages.slice() : messages.slice(0, end);
|
|
1254
|
-
}
|
|
1255
|
-
function findCurrentUserMessage(messages) {
|
|
1256
|
-
const prefixEnd = messages.findIndex((m) => m.role !== "system");
|
|
1257
|
-
const history = prefixEnd === -1 ? [] : messages.slice(prefixEnd);
|
|
1258
|
-
for (let i = history.length - 1; i >= 0; i--) {
|
|
1259
|
-
if (history[i].role === "user") {
|
|
1260
|
-
return history[i];
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
return null;
|
|
1264
|
-
}
|
|
1265
|
-
function toolCallsFromMessages(messages) {
|
|
1266
|
-
let count = 0;
|
|
1267
|
-
for (const m of messages) {
|
|
1268
|
-
if (m.role === "assistant" && m.tool_calls) {
|
|
1269
|
-
count += m.tool_calls.length;
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
return count;
|
|
899
|
+
throw new Error(`kimiflare: tool iteration limit reached (${opts2.maxToolIterations ?? 50})`);
|
|
1273
900
|
}
|
|
1274
901
|
function validateToolArguments(raw) {
|
|
1275
902
|
if (!raw || !raw.trim()) return "{}";
|
|
@@ -1280,25 +907,6 @@ function validateToolArguments(raw) {
|
|
|
1280
907
|
return "{}";
|
|
1281
908
|
}
|
|
1282
909
|
}
|
|
1283
|
-
function analyzePromptSections(messages) {
|
|
1284
|
-
return messages.map((m) => {
|
|
1285
|
-
let chars = 0;
|
|
1286
|
-
if (typeof m.content === "string") {
|
|
1287
|
-
chars = m.content.length;
|
|
1288
|
-
} else if (Array.isArray(m.content)) {
|
|
1289
|
-
for (const p of m.content) {
|
|
1290
|
-
if (p.type === "text") chars += p.text.length;
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
if (m.reasoning_content) chars += m.reasoning_content.length;
|
|
1294
|
-
if (m.tool_calls) {
|
|
1295
|
-
for (const tc of m.tool_calls) {
|
|
1296
|
-
chars += tc.function.name.length + tc.function.arguments.length;
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
return { role: m.role, chars, approxTokens: Math.ceil(chars / 4) };
|
|
1300
|
-
});
|
|
1301
|
-
}
|
|
1302
910
|
var init_loop = __esm({
|
|
1303
911
|
"src/agent/loop.ts"() {
|
|
1304
912
|
"use strict";
|
|
@@ -1307,8 +915,6 @@ var init_loop = __esm({
|
|
|
1307
915
|
init_messages();
|
|
1308
916
|
init_cost_debug();
|
|
1309
917
|
init_strip_reasoning();
|
|
1310
|
-
init_token_limits();
|
|
1311
|
-
init_context_builder();
|
|
1312
918
|
}
|
|
1313
919
|
});
|
|
1314
920
|
|
|
@@ -2793,77 +2399,6 @@ var init_update_check = __esm({
|
|
|
2793
2399
|
}
|
|
2794
2400
|
});
|
|
2795
2401
|
|
|
2796
|
-
// src/usage-cli.ts
|
|
2797
|
-
var usage_cli_exports = {};
|
|
2798
|
-
__export(usage_cli_exports, {
|
|
2799
|
-
showUsageLog: () => showUsageLog
|
|
2800
|
-
});
|
|
2801
|
-
import { readFile as readFile7 } from "fs/promises";
|
|
2802
|
-
import { homedir as homedir6 } from "os";
|
|
2803
|
-
import { join as join7 } from "path";
|
|
2804
|
-
function usagePath2() {
|
|
2805
|
-
return join7(homedir6(), ".kimiflare", "usage.jsonl");
|
|
2806
|
-
}
|
|
2807
|
-
function fmt(n) {
|
|
2808
|
-
return n.toLocaleString();
|
|
2809
|
-
}
|
|
2810
|
-
async function showUsageLog() {
|
|
2811
|
-
const path = usagePath2();
|
|
2812
|
-
let raw;
|
|
2813
|
-
try {
|
|
2814
|
-
raw = await readFile7(path, "utf8");
|
|
2815
|
-
} catch {
|
|
2816
|
-
console.log("No usage log found at " + path);
|
|
2817
|
-
return;
|
|
2818
|
-
}
|
|
2819
|
-
const lines = raw.trim().split("\n").filter(Boolean);
|
|
2820
|
-
if (lines.length === 0) {
|
|
2821
|
-
console.log("Usage log is empty.");
|
|
2822
|
-
return;
|
|
2823
|
-
}
|
|
2824
|
-
const entries = [];
|
|
2825
|
-
for (const line of lines) {
|
|
2826
|
-
try {
|
|
2827
|
-
entries.push(JSON.parse(line));
|
|
2828
|
-
} catch {
|
|
2829
|
-
}
|
|
2830
|
-
}
|
|
2831
|
-
if (entries.length === 0) {
|
|
2832
|
-
console.log("No valid entries in usage log.");
|
|
2833
|
-
return;
|
|
2834
|
-
}
|
|
2835
|
-
const bySession = /* @__PURE__ */ new Map();
|
|
2836
|
-
for (const e of entries) {
|
|
2837
|
-
const arr = bySession.get(e.sessionId) ?? [];
|
|
2838
|
-
arr.push(e);
|
|
2839
|
-
bySession.set(e.sessionId, arr);
|
|
2840
|
-
}
|
|
2841
|
-
console.log(`Usage log: ${lines.length} entries, ${bySession.size} session(s)
|
|
2842
|
-
`);
|
|
2843
|
-
for (const [sessionId, sessEntries] of bySession) {
|
|
2844
|
-
const last = sessEntries[sessEntries.length - 1];
|
|
2845
|
-
const totalInput = sessEntries.reduce((s, e) => s + e.estimatedInputTokens, 0);
|
|
2846
|
-
const avgInput = Math.round(totalInput / sessEntries.length);
|
|
2847
|
-
console.log(`Session: ${sessionId.slice(0, 16)}\u2026 Turns: ${sessEntries.length}`);
|
|
2848
|
-
console.log(` Last turn: ${fmt(last.estimatedInputTokens)} input tokens / ${fmt(last.estimatedOutputTokenCap)} output cap`);
|
|
2849
|
-
console.log(` Avg input: ${fmt(avgInput)} tokens`);
|
|
2850
|
-
console.log(` Messages: ${last.messageCount} | Tool outputs: ${last.toolOutputCount}`);
|
|
2851
|
-
console.log(` Breakdown: system=${fmt(last.tokensFromSystem)} session=${fmt(last.tokensFromSession)} tools=${fmt(last.tokensFromTools)} history=${fmt(last.tokensFromHistory)} user=${fmt(last.tokensFromUserInput)}`);
|
|
2852
|
-
if (last.wasCompacted) {
|
|
2853
|
-
console.log(` \u26A0\uFE0F Compacted: removed ${last.removedCount} messages`);
|
|
2854
|
-
}
|
|
2855
|
-
if (last.exceedsLimit) {
|
|
2856
|
-
console.log(` \u274C EXCEEDS LIMIT`);
|
|
2857
|
-
}
|
|
2858
|
-
console.log("");
|
|
2859
|
-
}
|
|
2860
|
-
}
|
|
2861
|
-
var init_usage_cli = __esm({
|
|
2862
|
-
"src/usage-cli.ts"() {
|
|
2863
|
-
"use strict";
|
|
2864
|
-
}
|
|
2865
|
-
});
|
|
2866
|
-
|
|
2867
2402
|
// src/agent/compact.ts
|
|
2868
2403
|
function indexOfNthUserFromEnd(messages, n) {
|
|
2869
2404
|
let seen = 0;
|
|
@@ -3070,7 +2605,7 @@ var init_session_state = __esm({
|
|
|
3070
2605
|
function approxTokens2(n) {
|
|
3071
2606
|
return Math.round(n / 4);
|
|
3072
2607
|
}
|
|
3073
|
-
function
|
|
2608
|
+
function estimateMessageTokens(m) {
|
|
3074
2609
|
let chars = 0;
|
|
3075
2610
|
if (typeof m.content === "string") {
|
|
3076
2611
|
chars = m.content.length;
|
|
@@ -3086,7 +2621,7 @@ function estimateMessageTokens2(m) {
|
|
|
3086
2621
|
return approxTokens2(chars);
|
|
3087
2622
|
}
|
|
3088
2623
|
function estimatePromptTokens(messages) {
|
|
3089
|
-
return messages.reduce((sum, m) => sum +
|
|
2624
|
+
return messages.reduce((sum, m) => sum + estimateMessageTokens(m), 0);
|
|
3090
2625
|
}
|
|
3091
2626
|
function groupIntoTurns(messages) {
|
|
3092
2627
|
const prefix = [];
|
|
@@ -3266,10 +2801,10 @@ function shouldCompact(opts2) {
|
|
|
3266
2801
|
return tokens > tokenThreshold || turns.length > turnThreshold;
|
|
3267
2802
|
}
|
|
3268
2803
|
function compactMessages2(opts2) {
|
|
3269
|
-
const
|
|
2804
|
+
const keepLastTurns = opts2.keepLastTurns ?? 4;
|
|
3270
2805
|
const { prefix, turns } = groupIntoTurns(opts2.messages);
|
|
3271
2806
|
const tokensBefore = estimatePromptTokens(opts2.messages);
|
|
3272
|
-
if (turns.length <=
|
|
2807
|
+
if (turns.length <= keepLastTurns) {
|
|
3273
2808
|
return {
|
|
3274
2809
|
newMessages: opts2.messages,
|
|
3275
2810
|
newState: opts2.state,
|
|
@@ -3283,8 +2818,8 @@ function compactMessages2(opts2) {
|
|
|
3283
2818
|
}
|
|
3284
2819
|
};
|
|
3285
2820
|
}
|
|
3286
|
-
const toCompact = turns.slice(0, turns.length -
|
|
3287
|
-
const toKeep = turns.slice(turns.length -
|
|
2821
|
+
const toCompact = turns.slice(0, turns.length - keepLastTurns);
|
|
2822
|
+
const toKeep = turns.slice(turns.length - keepLastTurns);
|
|
3288
2823
|
let newState = { ...opts2.state };
|
|
3289
2824
|
let archivedCount = 0;
|
|
3290
2825
|
for (let i = 0; i < toCompact.length; i++) {
|
|
@@ -5315,12 +4850,12 @@ __export(sessions_exports, {
|
|
|
5315
4850
|
pruneSessions: () => pruneSessions,
|
|
5316
4851
|
saveSession: () => saveSession
|
|
5317
4852
|
});
|
|
5318
|
-
import { readFile as
|
|
5319
|
-
import { homedir as
|
|
5320
|
-
import { join as
|
|
4853
|
+
import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir5, readdir as readdir2, stat as stat3 } from "fs/promises";
|
|
4854
|
+
import { homedir as homedir6 } from "os";
|
|
4855
|
+
import { join as join7 } from "path";
|
|
5321
4856
|
function sessionsDir() {
|
|
5322
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
5323
|
-
return
|
|
4857
|
+
const xdg = process.env.XDG_DATA_HOME || join7(homedir6(), ".local", "share");
|
|
4858
|
+
return join7(xdg, "kimiflare", "sessions");
|
|
5324
4859
|
}
|
|
5325
4860
|
function sanitize(text) {
|
|
5326
4861
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
|
|
@@ -5333,7 +4868,7 @@ function makeSessionId(firstPrompt) {
|
|
|
5333
4868
|
async function saveSession(file) {
|
|
5334
4869
|
const dir = sessionsDir();
|
|
5335
4870
|
await mkdir5(dir, { recursive: true });
|
|
5336
|
-
const path =
|
|
4871
|
+
const path = join7(dir, `${file.id}.json`);
|
|
5337
4872
|
await writeFile5(path, JSON.stringify(file, null, 2), "utf8");
|
|
5338
4873
|
return path;
|
|
5339
4874
|
}
|
|
@@ -5353,9 +4888,9 @@ async function listSessions(limit = 30) {
|
|
|
5353
4888
|
const summaries = [];
|
|
5354
4889
|
for (const name of entries) {
|
|
5355
4890
|
if (!name.endsWith(".json")) continue;
|
|
5356
|
-
const path =
|
|
4891
|
+
const path = join7(dir, name);
|
|
5357
4892
|
try {
|
|
5358
|
-
const [s, raw] = await Promise.all([stat3(path),
|
|
4893
|
+
const [s, raw] = await Promise.all([stat3(path), readFile7(path, "utf8")]);
|
|
5359
4894
|
const parsed = JSON.parse(raw);
|
|
5360
4895
|
const firstUser = parsed.messages.find((m) => m.role === "user");
|
|
5361
4896
|
const firstPrompt = typeof firstUser?.content === "string" ? firstUser.content : firstUser?.content ? firstUser.content.find((p) => p.type === "text")?.text ?? "(no prompt)" : "(no prompt)";
|
|
@@ -5374,7 +4909,7 @@ async function listSessions(limit = 30) {
|
|
|
5374
4909
|
return summaries.slice(0, limit);
|
|
5375
4910
|
}
|
|
5376
4911
|
async function loadSession(filePath) {
|
|
5377
|
-
const raw = await
|
|
4912
|
+
const raw = await readFile7(filePath, "utf8");
|
|
5378
4913
|
return JSON.parse(raw);
|
|
5379
4914
|
}
|
|
5380
4915
|
var init_sessions = __esm({
|
|
@@ -5385,10 +4920,10 @@ var init_sessions = __esm({
|
|
|
5385
4920
|
});
|
|
5386
4921
|
|
|
5387
4922
|
// src/util/image.ts
|
|
5388
|
-
import { readFile as
|
|
4923
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
5389
4924
|
import { basename as basename2 } from "path";
|
|
5390
4925
|
async function encodeImageFile(filePath) {
|
|
5391
|
-
const buf = await
|
|
4926
|
+
const buf = await readFile8(filePath);
|
|
5392
4927
|
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
5393
4928
|
throw new Error(
|
|
5394
4929
|
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
@@ -5424,15 +4959,15 @@ var init_image = __esm({
|
|
|
5424
4959
|
});
|
|
5425
4960
|
|
|
5426
4961
|
// src/usage-tracker.ts
|
|
5427
|
-
import { readFile as
|
|
5428
|
-
import { homedir as
|
|
5429
|
-
import { join as
|
|
5430
|
-
function
|
|
5431
|
-
const xdg = process.env.XDG_DATA_HOME ||
|
|
5432
|
-
return
|
|
4962
|
+
import { readFile as readFile9, writeFile as writeFile6, mkdir as mkdir6 } from "fs/promises";
|
|
4963
|
+
import { homedir as homedir7 } from "os";
|
|
4964
|
+
import { join as join8 } from "path";
|
|
4965
|
+
function usageDir() {
|
|
4966
|
+
const xdg = process.env.XDG_DATA_HOME || join8(homedir7(), ".local", "share");
|
|
4967
|
+
return join8(xdg, "kimiflare");
|
|
5433
4968
|
}
|
|
5434
|
-
function
|
|
5435
|
-
return
|
|
4969
|
+
function usagePath() {
|
|
4970
|
+
return join8(usageDir(), "usage.json");
|
|
5436
4971
|
}
|
|
5437
4972
|
function today() {
|
|
5438
4973
|
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -5443,7 +4978,7 @@ function cutoffDate(daysBack) {
|
|
|
5443
4978
|
}
|
|
5444
4979
|
async function loadLog() {
|
|
5445
4980
|
try {
|
|
5446
|
-
const raw = await
|
|
4981
|
+
const raw = await readFile9(usagePath(), "utf8");
|
|
5447
4982
|
const parsed = JSON.parse(raw);
|
|
5448
4983
|
if (parsed.version === LOG_VERSION2) return parsed;
|
|
5449
4984
|
} catch {
|
|
@@ -5451,8 +4986,8 @@ async function loadLog() {
|
|
|
5451
4986
|
return { version: LOG_VERSION2, days: [], sessions: [] };
|
|
5452
4987
|
}
|
|
5453
4988
|
async function saveLog(log) {
|
|
5454
|
-
await mkdir6(
|
|
5455
|
-
await writeFile6(
|
|
4989
|
+
await mkdir6(usageDir(), { recursive: true });
|
|
4990
|
+
await writeFile6(usagePath(), JSON.stringify(log, null, 2), "utf8");
|
|
5456
4991
|
}
|
|
5457
4992
|
function getOrCreateDay(log, date) {
|
|
5458
4993
|
let day = log.days.find((d) => d.date === date);
|
|
@@ -5569,7 +5104,7 @@ __export(app_exports, {
|
|
|
5569
5104
|
import { useState as useState6, useRef as useRef3, useEffect as useEffect4, useCallback } from "react";
|
|
5570
5105
|
import { Box as Box12, Text as Text13, useApp, useInput as useInput2, render } from "ink";
|
|
5571
5106
|
import { existsSync } from "fs";
|
|
5572
|
-
import { join as
|
|
5107
|
+
import { join as join9 } from "path";
|
|
5573
5108
|
import { unlink as unlink2 } from "fs/promises";
|
|
5574
5109
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5575
5110
|
function capEvents(prev) {
|
|
@@ -5635,10 +5170,9 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5635
5170
|
const [hasUpdate, setHasUpdate] = useState6(initialUpdateResult?.hasUpdate ?? false);
|
|
5636
5171
|
const [latestVersion, setLatestVersion] = useState6(initialUpdateResult?.latestVersion ?? null);
|
|
5637
5172
|
const cacheStableRef = useRef3(initialCfg?.cacheStablePrompts !== false);
|
|
5638
|
-
const
|
|
5173
|
+
const messagesRef = useRef3(
|
|
5639
5174
|
makePrefixMessages(cacheStableRef.current, cfg?.model ?? DEFAULT_MODEL, "edit", ALL_TOOLS)
|
|
5640
5175
|
);
|
|
5641
|
-
const messagesRef = useRef3(systemMessagesRef.current.slice());
|
|
5642
5176
|
const executorRef = useRef3(new ToolExecutor(ALL_TOOLS));
|
|
5643
5177
|
const activeAsstIdRef = useRef3(null);
|
|
5644
5178
|
const activeControllerRef = useRef3(null);
|
|
@@ -5723,7 +5257,7 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5723
5257
|
useEffect4(() => {
|
|
5724
5258
|
modeRef.current = mode;
|
|
5725
5259
|
if (cacheStableRef.current) {
|
|
5726
|
-
|
|
5260
|
+
messagesRef.current[1] = {
|
|
5727
5261
|
role: "system",
|
|
5728
5262
|
content: buildSessionPrefix({
|
|
5729
5263
|
cwd: process.cwd(),
|
|
@@ -5732,10 +5266,8 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5732
5266
|
mode
|
|
5733
5267
|
})
|
|
5734
5268
|
};
|
|
5735
|
-
messagesRef.current[1] = sessionMsg;
|
|
5736
|
-
systemMessagesRef.current[1] = sessionMsg;
|
|
5737
5269
|
} else {
|
|
5738
|
-
|
|
5270
|
+
messagesRef.current[0] = {
|
|
5739
5271
|
role: "system",
|
|
5740
5272
|
content: buildSystemPrompt({
|
|
5741
5273
|
cwd: process.cwd(),
|
|
@@ -5744,8 +5276,6 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5744
5276
|
mode
|
|
5745
5277
|
})
|
|
5746
5278
|
};
|
|
5747
|
-
messagesRef.current[0] = sysMsg;
|
|
5748
|
-
systemMessagesRef.current[0] = sysMsg;
|
|
5749
5279
|
}
|
|
5750
5280
|
if (mode === "plan") {
|
|
5751
5281
|
executorRef.current.clearSessionPermissions();
|
|
@@ -5820,7 +5350,7 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5820
5350
|
}
|
|
5821
5351
|
if (totalTools > 0) {
|
|
5822
5352
|
if (cacheStableRef.current) {
|
|
5823
|
-
|
|
5353
|
+
messagesRef.current[1] = {
|
|
5824
5354
|
role: "system",
|
|
5825
5355
|
content: buildSessionPrefix({
|
|
5826
5356
|
cwd: process.cwd(),
|
|
@@ -5829,10 +5359,8 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5829
5359
|
mode: modeRef.current
|
|
5830
5360
|
})
|
|
5831
5361
|
};
|
|
5832
|
-
messagesRef.current[1] = sessionMsg;
|
|
5833
|
-
systemMessagesRef.current[1] = sessionMsg;
|
|
5834
5362
|
} else {
|
|
5835
|
-
|
|
5363
|
+
messagesRef.current[0] = {
|
|
5836
5364
|
role: "system",
|
|
5837
5365
|
content: buildSystemPrompt({
|
|
5838
5366
|
cwd: process.cwd(),
|
|
@@ -5841,8 +5369,6 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
5841
5369
|
mode: modeRef.current
|
|
5842
5370
|
})
|
|
5843
5371
|
};
|
|
5844
|
-
messagesRef.current[0] = sysMsg;
|
|
5845
|
-
systemMessagesRef.current[0] = sysMsg;
|
|
5846
5372
|
}
|
|
5847
5373
|
setEvents((e) => [
|
|
5848
5374
|
...e,
|
|
@@ -6019,13 +5545,13 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6019
5545
|
}
|
|
6020
5546
|
const cwd = process.cwd();
|
|
6021
5547
|
for (const name of ["KIMI.md", "KIMIFLARE.md", "AGENT.md"]) {
|
|
6022
|
-
if (existsSync(
|
|
5548
|
+
if (existsSync(join9(cwd, name))) {
|
|
6023
5549
|
setEvents((e) => [
|
|
6024
5550
|
...e,
|
|
6025
5551
|
{
|
|
6026
5552
|
kind: "info",
|
|
6027
5553
|
key: mkKey(),
|
|
6028
|
-
text: `${name} already exists at ${
|
|
5554
|
+
text: `${name} already exists at ${join9(cwd, name)} \u2014 delete it first if you want to regenerate`
|
|
6029
5555
|
}
|
|
6030
5556
|
]);
|
|
6031
5557
|
return;
|
|
@@ -6065,7 +5591,6 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6065
5591
|
reasoningEffort: effortRef.current,
|
|
6066
5592
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
6067
5593
|
sessionId: ensureSessionId(),
|
|
6068
|
-
systemMessages: systemMessagesRef.current,
|
|
6069
5594
|
callbacks: {
|
|
6070
5595
|
onAssistantStart: () => {
|
|
6071
5596
|
const id = nextAssistantId++;
|
|
@@ -6143,9 +5668,9 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6143
5668
|
})
|
|
6144
5669
|
}
|
|
6145
5670
|
});
|
|
6146
|
-
if (existsSync(
|
|
5671
|
+
if (existsSync(join9(cwd, "KIMI.md"))) {
|
|
6147
5672
|
if (cacheStableRef.current) {
|
|
6148
|
-
|
|
5673
|
+
messagesRef.current[1] = {
|
|
6149
5674
|
role: "system",
|
|
6150
5675
|
content: buildSessionPrefix({
|
|
6151
5676
|
cwd,
|
|
@@ -6154,10 +5679,8 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6154
5679
|
mode: modeRef.current
|
|
6155
5680
|
})
|
|
6156
5681
|
};
|
|
6157
|
-
messagesRef.current[1] = sessionMsg;
|
|
6158
|
-
systemMessagesRef.current[1] = sessionMsg;
|
|
6159
5682
|
} else {
|
|
6160
|
-
|
|
5683
|
+
messagesRef.current[0] = {
|
|
6161
5684
|
role: "system",
|
|
6162
5685
|
content: buildSystemPrompt({
|
|
6163
5686
|
cwd,
|
|
@@ -6166,8 +5689,6 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6166
5689
|
mode: modeRef.current
|
|
6167
5690
|
})
|
|
6168
5691
|
};
|
|
6169
|
-
messagesRef.current[0] = sysMsg;
|
|
6170
|
-
systemMessagesRef.current[0] = sysMsg;
|
|
6171
5692
|
}
|
|
6172
5693
|
setEvents((e) => [
|
|
6173
5694
|
...e,
|
|
@@ -6194,10 +5715,7 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6194
5715
|
if (!picked) return;
|
|
6195
5716
|
try {
|
|
6196
5717
|
const file = await loadSession(picked.filePath);
|
|
6197
|
-
const prefixEnd = file.messages.findIndex((m) => m.role !== "system");
|
|
6198
|
-
systemMessagesRef.current = prefixEnd === -1 ? file.messages.slice() : file.messages.slice(0, prefixEnd);
|
|
6199
5718
|
messagesRef.current = file.messages;
|
|
6200
|
-
clearOutputHashCache();
|
|
6201
5719
|
sessionIdRef.current = file.id;
|
|
6202
5720
|
if (file.sessionState && compiledContextRef.current) {
|
|
6203
5721
|
sessionStateRef.current = file.sessionState;
|
|
@@ -6260,12 +5778,10 @@ function App({ initialCfg, initialUpdateResult }) {
|
|
|
6260
5778
|
}
|
|
6261
5779
|
if (c === "/clear") {
|
|
6262
5780
|
if (cacheStableRef.current && messagesRef.current.length >= 2) {
|
|
6263
|
-
|
|
5781
|
+
messagesRef.current = [messagesRef.current[0], messagesRef.current[1]];
|
|
6264
5782
|
} else {
|
|
6265
|
-
|
|
5783
|
+
messagesRef.current = [messagesRef.current[0]];
|
|
6266
5784
|
}
|
|
6267
|
-
messagesRef.current = systemMessagesRef.current.slice();
|
|
6268
|
-
clearOutputHashCache();
|
|
6269
5785
|
sessionIdRef.current = null;
|
|
6270
5786
|
sessionStateRef.current = emptySessionState();
|
|
6271
5787
|
artifactStoreRef.current = new ArtifactStore();
|
|
@@ -6587,7 +6103,6 @@ use: /thinking low | medium | high`
|
|
|
6587
6103
|
coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
6588
6104
|
sessionId: ensureSessionId(),
|
|
6589
6105
|
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
6590
|
-
systemMessages: systemMessagesRef.current,
|
|
6591
6106
|
callbacks: {
|
|
6592
6107
|
onAssistantStart: () => {
|
|
6593
6108
|
const id = nextAssistantId++;
|
|
@@ -6918,7 +6433,6 @@ var init_app = __esm({
|
|
|
6918
6433
|
init_sessions();
|
|
6919
6434
|
init_image();
|
|
6920
6435
|
init_usage_tracker();
|
|
6921
|
-
init_tool_output_summarizer();
|
|
6922
6436
|
CONTEXT_LIMIT = 262e3;
|
|
6923
6437
|
AUTO_COMPACT_SUGGEST_PCT = 0.8;
|
|
6924
6438
|
MAX_EVENTS = 500;
|
|
@@ -6943,30 +6457,22 @@ init_update_check();
|
|
|
6943
6457
|
import { Command } from "commander";
|
|
6944
6458
|
import { readFileSync as readFileSync2 } from "fs";
|
|
6945
6459
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
6946
|
-
import { dirname as dirname3, join as
|
|
6460
|
+
import { dirname as dirname3, join as join10 } from "path";
|
|
6947
6461
|
function readPackageVersion() {
|
|
6948
6462
|
try {
|
|
6949
6463
|
const here = dirname3(fileURLToPath2(import.meta.url));
|
|
6950
|
-
const pkg = JSON.parse(readFileSync2(
|
|
6464
|
+
const pkg = JSON.parse(readFileSync2(join10(here, "..", "package.json"), "utf8"));
|
|
6951
6465
|
return pkg.version ?? "0.0.0";
|
|
6952
6466
|
} catch {
|
|
6953
6467
|
return "0.0.0";
|
|
6954
6468
|
}
|
|
6955
6469
|
}
|
|
6956
6470
|
var program = new Command();
|
|
6957
|
-
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(readPackageVersion()).option("-p, --print <prompt>", "one-shot mode: send prompt, stream reply to stdout, exit").option("-m, --model <id>", "model id (defaults to @cf/moonshotai/kimi-k2.6)").option("--dangerously-allow-all", "auto-approve every permission prompt (print mode only)").option("--reasoning", "include reasoning in stdout (print mode only)").
|
|
6958
|
-
const { showUsageLog: showUsageLog2 } = await Promise.resolve().then(() => (init_usage_cli(), usage_cli_exports));
|
|
6959
|
-
await showUsageLog2();
|
|
6960
|
-
});
|
|
6961
|
-
program.parse();
|
|
6471
|
+
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(readPackageVersion()).option("-p, --print <prompt>", "one-shot mode: send prompt, stream reply to stdout, exit").option("-m, --model <id>", "model id (defaults to @cf/moonshotai/kimi-k2.6)").option("--dangerously-allow-all", "auto-approve every permission prompt (print mode only)").option("--reasoning", "include reasoning in stdout (print mode only)").parse();
|
|
6962
6472
|
var opts = program.opts();
|
|
6963
6473
|
async function main() {
|
|
6964
6474
|
const cfg = await loadConfig();
|
|
6965
6475
|
const updateResult = await checkForUpdate();
|
|
6966
|
-
const args = program.args;
|
|
6967
|
-
if (args[0] === "usage") {
|
|
6968
|
-
return;
|
|
6969
|
-
}
|
|
6970
6476
|
if (opts.print !== void 0) {
|
|
6971
6477
|
if (!cfg) {
|
|
6972
6478
|
console.error(
|
|
@@ -7010,11 +6516,8 @@ async function runPrintMode(opts2) {
|
|
|
7010
6516
|
}
|
|
7011
6517
|
const cwd = process.cwd();
|
|
7012
6518
|
const executor = new ToolExecutor(ALL_TOOLS);
|
|
7013
|
-
const systemMessages = [
|
|
7014
|
-
{ role: "system", content: buildSystemPrompt({ cwd, tools: ALL_TOOLS, model: opts2.model }) }
|
|
7015
|
-
];
|
|
7016
6519
|
const messages = [
|
|
7017
|
-
|
|
6520
|
+
{ role: "system", content: buildSystemPrompt({ cwd, tools: ALL_TOOLS, model: opts2.model }) },
|
|
7018
6521
|
{ role: "user", content: opts2.prompt }
|
|
7019
6522
|
];
|
|
7020
6523
|
const controller = new AbortController();
|
|
@@ -7030,7 +6533,6 @@ async function runPrintMode(opts2) {
|
|
|
7030
6533
|
executor,
|
|
7031
6534
|
cwd,
|
|
7032
6535
|
signal: controller.signal,
|
|
7033
|
-
systemMessages,
|
|
7034
6536
|
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
7035
6537
|
callbacks: {
|
|
7036
6538
|
onReasoningDelta: opts2.showReasoning ? (delta) => {
|