kimiflare 0.32.0 → 0.33.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 +213 -65
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -945,6 +945,87 @@ var init_cost_debug = __esm({
|
|
|
945
945
|
}
|
|
946
946
|
});
|
|
947
947
|
|
|
948
|
+
// src/memory/extractors.ts
|
|
949
|
+
function safeJsonParse(text) {
|
|
950
|
+
try {
|
|
951
|
+
return JSON.parse(text);
|
|
952
|
+
} catch {
|
|
953
|
+
return null;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
var EXTRACTORS;
|
|
957
|
+
var init_extractors = __esm({
|
|
958
|
+
"src/memory/extractors.ts"() {
|
|
959
|
+
"use strict";
|
|
960
|
+
EXTRACTORS = [
|
|
961
|
+
{
|
|
962
|
+
id: "package_json",
|
|
963
|
+
match: (tool, file) => tool === "read" && /package\.json$/.test(file || ""),
|
|
964
|
+
extract: (content, file) => {
|
|
965
|
+
const pkg = safeJsonParse(content);
|
|
966
|
+
if (!pkg) return null;
|
|
967
|
+
const deps = Object.keys(pkg.dependencies || {}).slice(0, 10);
|
|
968
|
+
const devDeps = Object.keys(pkg.devDependencies || {}).slice(0, 5);
|
|
969
|
+
const scripts = Object.keys(pkg.scripts || {}).slice(0, 5);
|
|
970
|
+
return {
|
|
971
|
+
content: `Project dependencies: ${deps.join(", ") || "none"}. Dev dependencies: ${devDeps.join(", ") || "none"}. Scripts: ${scripts.join(", ") || "none"}. Type: ${pkg.type || "commonjs"}.`,
|
|
972
|
+
category: "fact",
|
|
973
|
+
importance: 4,
|
|
974
|
+
topicKey: "project_dependencies",
|
|
975
|
+
relatedFiles: file ? [file] : void 0
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
id: "tsconfig",
|
|
981
|
+
match: (tool, file) => tool === "read" && /tsconfig.*\.json$/.test(file || ""),
|
|
982
|
+
extract: (content, file) => {
|
|
983
|
+
const ts = safeJsonParse(content);
|
|
984
|
+
if (!ts) return null;
|
|
985
|
+
const opts2 = ts.compilerOptions || {};
|
|
986
|
+
return {
|
|
987
|
+
content: `TypeScript config: target=${opts2.target || "default"}, module=${opts2.module || "default"}, strict=${opts2.strict || false}, jsx=${opts2.jsx || "none"}.`,
|
|
988
|
+
category: "fact",
|
|
989
|
+
importance: 4,
|
|
990
|
+
topicKey: "project_tsconfig",
|
|
991
|
+
relatedFiles: file ? [file] : void 0
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
{
|
|
996
|
+
id: "entry_point",
|
|
997
|
+
match: (tool, file) => tool === "read" && /src\/(index|main)\.(ts|tsx|js|jsx)$/.test(file || ""),
|
|
998
|
+
extract: (content, file) => {
|
|
999
|
+
const exports = content.match(/export\s+(?:default\s+)?(?:function|class|const|interface|type)\s+(\w+)/g);
|
|
1000
|
+
const exportNames = exports ? exports.map((e) => e.split(/\s+/).pop()).filter((n) => !!n).slice(0, 5) : [];
|
|
1001
|
+
return {
|
|
1002
|
+
content: `Entry point ${file} exports: ${exportNames.join(", ") || "default export or side effects"}.`,
|
|
1003
|
+
category: "fact",
|
|
1004
|
+
importance: 3,
|
|
1005
|
+
topicKey: "project_entry_point",
|
|
1006
|
+
relatedFiles: file ? [file] : void 0
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
id: "edit_event",
|
|
1012
|
+
match: (tool, file) => (tool === "edit" || tool === "write") && !!file,
|
|
1013
|
+
extract: (_content, file) => {
|
|
1014
|
+
if (!file) return null;
|
|
1015
|
+
const safeKey = file.replace(/[^a-zA-Z0-9]/g, "_");
|
|
1016
|
+
return {
|
|
1017
|
+
content: `File modified: ${file}.`,
|
|
1018
|
+
category: "event",
|
|
1019
|
+
importance: 2,
|
|
1020
|
+
topicKey: `event_edit_${safeKey}`,
|
|
1021
|
+
relatedFiles: [file]
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
];
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
948
1029
|
// src/agent/strip-reasoning.ts
|
|
949
1030
|
function stripHistoricalReasoning(messages, opts2 = {}) {
|
|
950
1031
|
const keepLast = opts2.keepLast ?? DEFAULT_KEEP_LAST;
|
|
@@ -1328,7 +1409,28 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1328
1409
|
const webFetchHistory = [];
|
|
1329
1410
|
const MAX_WEB_FETCH_PER_TURN = 5;
|
|
1330
1411
|
const WEB_FETCH_DOMAIN_THRESHOLD = 2;
|
|
1331
|
-
|
|
1412
|
+
let cumulativePromptTokens = 0;
|
|
1413
|
+
let iter = 0;
|
|
1414
|
+
let budgetExhausted = false;
|
|
1415
|
+
while (true) {
|
|
1416
|
+
if (budgetExhausted) {
|
|
1417
|
+
opts2.messages.push({
|
|
1418
|
+
role: "system",
|
|
1419
|
+
content: "You have reached the cumulative input token budget for this session. Please synthesize your findings and provide a final summary of what was accomplished."
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
if (iter >= max) {
|
|
1423
|
+
if (opts2.continueOnLimit) {
|
|
1424
|
+
opts2.messages.push({
|
|
1425
|
+
role: "system",
|
|
1426
|
+
content: "You have reached the tool-call limit for this session. The counter has been reset so you can continue working. Please proceed with your task."
|
|
1427
|
+
});
|
|
1428
|
+
iter = 0;
|
|
1429
|
+
} else {
|
|
1430
|
+
throw new Error(`kimiflare: tool iteration limit reached (${max})`);
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
iter++;
|
|
1332
1434
|
turn++;
|
|
1333
1435
|
const previousMessages = opts2.messages.slice();
|
|
1334
1436
|
const toolCalls = [];
|
|
@@ -1426,7 +1528,13 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1426
1528
|
}
|
|
1427
1529
|
}
|
|
1428
1530
|
if (opts2.signal.aborted) throw new DOMException("aborted", "AbortError");
|
|
1429
|
-
if (lastUsage)
|
|
1531
|
+
if (lastUsage) {
|
|
1532
|
+
opts2.callbacks.onUsageFinal?.(lastUsage, gatewayMeta);
|
|
1533
|
+
cumulativePromptTokens += lastUsage.prompt_tokens;
|
|
1534
|
+
if (!budgetExhausted && opts2.maxInputTokens !== void 0 && opts2.maxInputTokens > 0 && cumulativePromptTokens >= opts2.maxInputTokens && toolCalls.length > 0) {
|
|
1535
|
+
budgetExhausted = true;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1430
1538
|
const assistantMsg = {
|
|
1431
1539
|
role: "assistant",
|
|
1432
1540
|
content: content ? sanitizeString(content) : null,
|
|
@@ -1455,6 +1563,9 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1455
1563
|
shadowStrip: shadowStripMetrics
|
|
1456
1564
|
});
|
|
1457
1565
|
}
|
|
1566
|
+
if (budgetExhausted) {
|
|
1567
|
+
throw new BudgetExhaustedError();
|
|
1568
|
+
}
|
|
1458
1569
|
return;
|
|
1459
1570
|
}
|
|
1460
1571
|
for (const tc of toolCalls) {
|
|
@@ -1589,6 +1700,30 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1589
1700
|
name: result.name
|
|
1590
1701
|
});
|
|
1591
1702
|
opts2.callbacks.onToolResult?.(result);
|
|
1703
|
+
if (opts2.memoryManager) {
|
|
1704
|
+
let filePath;
|
|
1705
|
+
try {
|
|
1706
|
+
const args = JSON.parse(tc.function.arguments || "{}");
|
|
1707
|
+
filePath = args.path;
|
|
1708
|
+
} catch {
|
|
1709
|
+
}
|
|
1710
|
+
for (const extractor of EXTRACTORS) {
|
|
1711
|
+
if (extractor.match(tc.function.name, filePath)) {
|
|
1712
|
+
const memory = extractor.extract(result.content, filePath);
|
|
1713
|
+
if (memory) {
|
|
1714
|
+
void opts2.memoryManager.remember(
|
|
1715
|
+
memory.content,
|
|
1716
|
+
memory.category,
|
|
1717
|
+
memory.importance,
|
|
1718
|
+
opts2.cwd,
|
|
1719
|
+
opts2.sessionId ?? "unknown",
|
|
1720
|
+
opts2.signal
|
|
1721
|
+
).catch(() => {
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1592
1727
|
recentToolCalls.push(loopSignature);
|
|
1593
1728
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
1594
1729
|
}
|
|
@@ -1604,8 +1739,10 @@ ${sandboxResult.output}` : sandboxResult.output;
|
|
|
1604
1739
|
shadowStrip: shadowStripMetrics
|
|
1605
1740
|
});
|
|
1606
1741
|
}
|
|
1742
|
+
if (budgetExhausted) {
|
|
1743
|
+
throw new BudgetExhaustedError();
|
|
1744
|
+
}
|
|
1607
1745
|
}
|
|
1608
|
-
throw new Error(`kimiflare: tool iteration limit reached (${opts2.maxToolIterations ?? 50})`);
|
|
1609
1746
|
}
|
|
1610
1747
|
function validateToolArguments(raw) {
|
|
1611
1748
|
if (!raw || !raw.trim()) return "{}";
|
|
@@ -1616,7 +1753,7 @@ function validateToolArguments(raw) {
|
|
|
1616
1753
|
return "{}";
|
|
1617
1754
|
}
|
|
1618
1755
|
}
|
|
1619
|
-
var codeModeApiCache;
|
|
1756
|
+
var BudgetExhaustedError, codeModeApiCache;
|
|
1620
1757
|
var init_loop = __esm({
|
|
1621
1758
|
"src/agent/loop.ts"() {
|
|
1622
1759
|
"use strict";
|
|
@@ -1624,8 +1761,15 @@ var init_loop = __esm({
|
|
|
1624
1761
|
init_registry();
|
|
1625
1762
|
init_messages();
|
|
1626
1763
|
init_cost_debug();
|
|
1764
|
+
init_extractors();
|
|
1627
1765
|
init_strip_reasoning();
|
|
1628
1766
|
init_code_mode();
|
|
1767
|
+
BudgetExhaustedError = class extends Error {
|
|
1768
|
+
constructor(message2 = "Cumulative input token budget exhausted") {
|
|
1769
|
+
super(message2);
|
|
1770
|
+
this.name = "BudgetExhaustedError";
|
|
1771
|
+
}
|
|
1772
|
+
};
|
|
1629
1773
|
codeModeApiCache = /* @__PURE__ */ new Map();
|
|
1630
1774
|
}
|
|
1631
1775
|
});
|
|
@@ -7413,7 +7557,7 @@ var init_help_menu = __esm({
|
|
|
7413
7557
|
commands: [
|
|
7414
7558
|
{ command: "/init", description: "scan this repo and write a KIMI.md" },
|
|
7415
7559
|
{ command: "/logout", description: "clear credentials" },
|
|
7416
|
-
{ command: "filePicker", description: "
|
|
7560
|
+
{ command: "filePicker", description: "enabled by default; disable with KIMIFLARE_FILE_PICKER=0 or filePicker: false in config", selectable: false }
|
|
7417
7561
|
]
|
|
7418
7562
|
}
|
|
7419
7563
|
];
|
|
@@ -11026,7 +11170,7 @@ function App({
|
|
|
11026
11170
|
const [draftInput, setDraftInput] = useState9("");
|
|
11027
11171
|
const [mode, setMode] = useState9("edit");
|
|
11028
11172
|
const [codeMode, setCodeMode] = useState9(initialCfg?.codeMode ?? false);
|
|
11029
|
-
const filePickerEnabled = initialCfg?.filePicker ??
|
|
11173
|
+
const filePickerEnabled = initialCfg?.filePicker ?? true;
|
|
11030
11174
|
const [effort, setEffort] = useState9(
|
|
11031
11175
|
initialCfg?.reasoningEffort ?? DEFAULT_REASONING_EFFORT
|
|
11032
11176
|
);
|
|
@@ -11833,23 +11977,13 @@ function App({
|
|
|
11833
11977
|
return;
|
|
11834
11978
|
}
|
|
11835
11979
|
const cwd = process.cwd();
|
|
11836
|
-
|
|
11837
|
-
|
|
11838
|
-
|
|
11839
|
-
|
|
11840
|
-
{
|
|
11841
|
-
kind: "info",
|
|
11842
|
-
key: mkKey(),
|
|
11843
|
-
text: `${name} already exists at ${join17(cwd, name)} \u2014 delete it first if you want to regenerate`
|
|
11844
|
-
}
|
|
11845
|
-
]);
|
|
11846
|
-
return;
|
|
11847
|
-
}
|
|
11848
|
-
}
|
|
11849
|
-
const prompt = [
|
|
11850
|
-
"Generate a KIMI.md at the repository root so future agents have project context.",
|
|
11980
|
+
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find((n) => existsSync2(join17(cwd, n)));
|
|
11981
|
+
const isRefresh = existingName !== void 0;
|
|
11982
|
+
const promptParts = [
|
|
11983
|
+
isRefresh ? `Regenerate ${existingName} at the repository root to refresh project context. If the file already exists, read it first and preserve anything still accurate, updating only what has changed.` : "Generate a KIMI.md at the repository root so future agents have project context.",
|
|
11851
11984
|
"",
|
|
11852
11985
|
"First, use the `glob`, `read`, and `grep` tools to understand the project: read `package.json`, the top-level `README.md` if present, the tsconfig / build config, and skim the top-level source directory structure.",
|
|
11986
|
+
isRefresh ? `Also read the existing ${existingName} so you know what to keep vs. update.` : null,
|
|
11853
11987
|
"",
|
|
11854
11988
|
"Then call the `write` tool to create `KIMI.md` at the repo root with these sections, terse (aim \u2264 100 lines total):",
|
|
11855
11989
|
"",
|
|
@@ -11860,8 +11994,9 @@ function App({
|
|
|
11860
11994
|
"- **Do / Don't** \u2014 quirks or rules future agents should know.",
|
|
11861
11995
|
"",
|
|
11862
11996
|
"Do not call `tasks_set` for this. Just read what you need, then write the file."
|
|
11863
|
-
]
|
|
11864
|
-
|
|
11997
|
+
];
|
|
11998
|
+
const prompt = promptParts.filter((p) => p !== null).join("\n");
|
|
11999
|
+
setEvents((e) => [...e, { kind: "user", key: mkKey(), text: isRefresh ? `/init (refreshing ${existingName})` : "/init" }]);
|
|
11865
12000
|
messagesRef.current.push({ role: "user", content: sanitizeString(prompt) });
|
|
11866
12001
|
setBusy(true);
|
|
11867
12002
|
setTurnStartedAt(Date.now());
|
|
@@ -13433,7 +13568,7 @@ init_update_check();
|
|
|
13433
13568
|
init_version();
|
|
13434
13569
|
import { Command } from "commander";
|
|
13435
13570
|
var program = new Command();
|
|
13436
|
-
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(getAppVersion()).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)");
|
|
13571
|
+
program.name("kimiflare").description("Terminal coding agent powered by Kimi-K2.6 on Cloudflare Workers AI.").version(getAppVersion()).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)").option("--continue-on-limit", "reset tool-call counter and continue when the 50-call limit is hit (print mode only)").option("--max-input-tokens <n>", "cumulative prompt token budget; exits 42 when exhausted (print mode only)", (v) => parseInt(v, 10));
|
|
13437
13572
|
program.command("cost").description("Show cost attribution by task type (requires costAttribution enabled)").option("-w, --week", "last 7 days (default)").option("-m, --month", "last 30 days").option("-d, --day", "today only").option("-s, --session <id>", "single session detail").option("-c, --category <name>", "filter by category").option("--json", "machine-readable output").option("--reclassify", "re-run classification on all sessions").option("--local-only", "skip Cloudflare reconciliation").action(async (cmdOpts) => {
|
|
13438
13573
|
const cfg = await loadConfig();
|
|
13439
13574
|
const enabled = cfg?.costAttribution ?? false;
|
|
@@ -13482,6 +13617,8 @@ async function main() {
|
|
|
13482
13617
|
allowAll: !!opts.dangerouslyAllowAll,
|
|
13483
13618
|
showReasoning: !!opts.reasoning,
|
|
13484
13619
|
codeMode: cfg.codeMode,
|
|
13620
|
+
continueOnLimit: !!opts.continueOnLimit,
|
|
13621
|
+
maxInputTokens: opts.maxInputTokens,
|
|
13485
13622
|
updateResult
|
|
13486
13623
|
});
|
|
13487
13624
|
return;
|
|
@@ -13529,52 +13666,63 @@ async function runPrintMode(opts2) {
|
|
|
13529
13666
|
process.on("SIGINT", () => controller.abort());
|
|
13530
13667
|
let printedReasoningHeader = false;
|
|
13531
13668
|
let printedAnswerHeader = false;
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
|
|
13560
|
-
|
|
13669
|
+
try {
|
|
13670
|
+
await runAgentTurn({
|
|
13671
|
+
accountId: opts2.accountId,
|
|
13672
|
+
apiToken: opts2.apiToken,
|
|
13673
|
+
model: opts2.model,
|
|
13674
|
+
gateway: gatewayFromPrintOpts(opts2),
|
|
13675
|
+
messages,
|
|
13676
|
+
tools: ALL_TOOLS,
|
|
13677
|
+
executor,
|
|
13678
|
+
cwd,
|
|
13679
|
+
signal: controller.signal,
|
|
13680
|
+
codeMode: opts2.codeMode,
|
|
13681
|
+
continueOnLimit: opts2.continueOnLimit,
|
|
13682
|
+
maxInputTokens: opts2.maxInputTokens,
|
|
13683
|
+
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
13684
|
+
callbacks: {
|
|
13685
|
+
onReasoningDelta: opts2.showReasoning ? (delta) => {
|
|
13686
|
+
if (!printedReasoningHeader) {
|
|
13687
|
+
process.stderr.write("\x1B[2m--- reasoning ---\n");
|
|
13688
|
+
printedReasoningHeader = true;
|
|
13689
|
+
}
|
|
13690
|
+
process.stderr.write(delta);
|
|
13691
|
+
} : void 0,
|
|
13692
|
+
onTextDelta: (delta) => {
|
|
13693
|
+
if (opts2.showReasoning && printedReasoningHeader && !printedAnswerHeader) {
|
|
13694
|
+
process.stderr.write("\n--- answer ---\x1B[0m\n");
|
|
13695
|
+
printedAnswerHeader = true;
|
|
13696
|
+
}
|
|
13697
|
+
process.stdout.write(delta);
|
|
13698
|
+
},
|
|
13699
|
+
onToolCallFinalized: (call) => {
|
|
13700
|
+
process.stderr.write(`\x1B[2m[tool ${call.function.name}(${call.function.arguments})]\x1B[0m
|
|
13561
13701
|
`);
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13702
|
+
},
|
|
13703
|
+
onToolResult: (result) => {
|
|
13704
|
+
const snippet = result.content.length > 400 ? result.content.slice(0, 400) + "..." : result.content;
|
|
13705
|
+
process.stderr.write(`\x1B[2m[result: ${snippet.replace(/\n/g, " \u23CE ")}]\x1B[0m
|
|
13566
13706
|
`);
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13707
|
+
},
|
|
13708
|
+
askPermission: async ({ tool, args }) => {
|
|
13709
|
+
if (opts2.allowAll) return "allow";
|
|
13710
|
+
process.stderr.write(
|
|
13711
|
+
`\x1B[31m[permission denied: ${tool.name}(${JSON.stringify(args)}) \u2014 pass --dangerously-allow-all to approve in print mode]\x1B[0m
|
|
13572
13712
|
`
|
|
13573
|
-
|
|
13574
|
-
|
|
13713
|
+
);
|
|
13714
|
+
return "deny";
|
|
13715
|
+
}
|
|
13575
13716
|
}
|
|
13717
|
+
});
|
|
13718
|
+
} catch (err) {
|
|
13719
|
+
if (err instanceof BudgetExhaustedError) {
|
|
13720
|
+
process.stderr.write("\n\x1B[33m[Budget exhausted \u2014 exiting with code 42]\x1B[0m\n");
|
|
13721
|
+
process.exitCode = 42;
|
|
13722
|
+
return;
|
|
13576
13723
|
}
|
|
13577
|
-
|
|
13724
|
+
throw err;
|
|
13725
|
+
}
|
|
13578
13726
|
process.stdout.write("\n");
|
|
13579
13727
|
}
|
|
13580
13728
|
//# sourceMappingURL=index.js.map
|