kimiflare 0.40.0 → 0.41.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 +136 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1861,6 +1861,9 @@ var init_code_mode = __esm({
|
|
|
1861
1861
|
});
|
|
1862
1862
|
|
|
1863
1863
|
// src/agent/loop.ts
|
|
1864
|
+
function isHighSignalMemory(memory) {
|
|
1865
|
+
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;
|
|
1866
|
+
}
|
|
1864
1867
|
async function runAgentTurn(opts2) {
|
|
1865
1868
|
const turnStart = performance.now();
|
|
1866
1869
|
const max = opts2.maxToolIterations ?? 50;
|
|
@@ -2260,6 +2263,15 @@ ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
|
|
|
2260
2263
|
void 0,
|
|
2261
2264
|
memory.topicKey
|
|
2262
2265
|
);
|
|
2266
|
+
if (isHighSignalMemory(memory)) {
|
|
2267
|
+
const sid = opts2.sessionId ?? "default";
|
|
2268
|
+
const current = (driftAccumulator.get(sid) ?? 0) + 1;
|
|
2269
|
+
driftAccumulator.set(sid, current);
|
|
2270
|
+
if (current >= DRIFT_THRESHOLD) {
|
|
2271
|
+
opts2.callbacks.onKimiMdStale?.();
|
|
2272
|
+
driftAccumulator.set(sid, 0);
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2263
2275
|
}
|
|
2264
2276
|
} catch {
|
|
2265
2277
|
}
|
|
@@ -2271,6 +2283,12 @@ ${sandboxResult.output}` : `${warningPrefix}${sandboxResult.output}`;
|
|
|
2271
2283
|
if (recentToolCalls.length > LOOP_WINDOW) recentToolCalls.shift();
|
|
2272
2284
|
}
|
|
2273
2285
|
}
|
|
2286
|
+
if (opts2.sessionId) {
|
|
2287
|
+
const current = driftAccumulator.get(opts2.sessionId) ?? 0;
|
|
2288
|
+
if (current > 0) {
|
|
2289
|
+
driftAccumulator.set(opts2.sessionId, Math.max(0, current - 1));
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2274
2292
|
if (opts2.onIterationEnd) {
|
|
2275
2293
|
opts2.messages = await opts2.onIterationEnd(opts2.messages, opts2.signal);
|
|
2276
2294
|
if (opts2.signal.aborted) throw new DOMException("aborted", "AbortError");
|
|
@@ -2303,7 +2321,7 @@ function validateToolArguments(raw) {
|
|
|
2303
2321
|
return "{}";
|
|
2304
2322
|
}
|
|
2305
2323
|
}
|
|
2306
|
-
var BudgetExhaustedError, codeModeApiCache;
|
|
2324
|
+
var BudgetExhaustedError, codeModeApiCache, driftAccumulator, DRIFT_THRESHOLD;
|
|
2307
2325
|
var init_loop = __esm({
|
|
2308
2326
|
"src/agent/loop.ts"() {
|
|
2309
2327
|
"use strict";
|
|
@@ -2321,6 +2339,8 @@ var init_loop = __esm({
|
|
|
2321
2339
|
}
|
|
2322
2340
|
};
|
|
2323
2341
|
codeModeApiCache = /* @__PURE__ */ new Map();
|
|
2342
|
+
driftAccumulator = /* @__PURE__ */ new Map();
|
|
2343
|
+
DRIFT_THRESHOLD = 5;
|
|
2324
2344
|
}
|
|
2325
2345
|
});
|
|
2326
2346
|
|
|
@@ -7253,7 +7273,7 @@ import { useEffect, useState } from "react";
|
|
|
7253
7273
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
7254
7274
|
import Spinner3 from "ink-spinner";
|
|
7255
7275
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
7256
|
-
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget }) {
|
|
7276
|
+
function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode, effort, contextLimit, hasUpdate, latestVersion, gatewayMeta, codeMode, cloudMode, cloudBudget, kimiMdStale }) {
|
|
7257
7277
|
const theme = useTheme();
|
|
7258
7278
|
const [now2, setNow] = useState(Date.now());
|
|
7259
7279
|
const modeColor = mode === "plan" ? theme.modeBadge.plan : mode === "auto" ? theme.modeBadge.auto : theme.modeBadge.edit;
|
|
@@ -7296,6 +7316,10 @@ function StatusBar({ model, usage, sessionUsage, thinking, turnStartedAt, mode,
|
|
|
7296
7316
|
"update available",
|
|
7297
7317
|
latestVersion ? ` \u2192 ${latestVersion}` : "",
|
|
7298
7318
|
" \xB7 run /update"
|
|
7319
|
+
] }) : null,
|
|
7320
|
+
kimiMdStale ? /* @__PURE__ */ jsxs5(Text5, { color: theme.warn, bold: true, children: [
|
|
7321
|
+
" \xB7 ",
|
|
7322
|
+
"\u26A0 KIMI.md stale \xB7 run /init"
|
|
7299
7323
|
] }) : null
|
|
7300
7324
|
] })
|
|
7301
7325
|
] });
|
|
@@ -9712,11 +9736,21 @@ var init_usage_tracker = __esm({
|
|
|
9712
9736
|
}
|
|
9713
9737
|
});
|
|
9714
9738
|
|
|
9739
|
+
// src/memory/schema.ts
|
|
9740
|
+
var DEFAULT_EMBEDDING_DIM;
|
|
9741
|
+
var init_schema = __esm({
|
|
9742
|
+
"src/memory/schema.ts"() {
|
|
9743
|
+
"use strict";
|
|
9744
|
+
DEFAULT_EMBEDDING_DIM = 768;
|
|
9745
|
+
}
|
|
9746
|
+
});
|
|
9747
|
+
|
|
9715
9748
|
// src/memory/db.ts
|
|
9716
9749
|
var db_exports = {};
|
|
9717
9750
|
__export(db_exports, {
|
|
9718
9751
|
clearMemoriesForRepo: () => clearMemoriesForRepo,
|
|
9719
9752
|
closeMemoryDb: () => closeMemoryDb,
|
|
9753
|
+
countHighSignalMemoriesSince: () => countHighSignalMemoriesSince,
|
|
9720
9754
|
deleteExcessMemories: () => deleteExcessMemories,
|
|
9721
9755
|
deleteMemoriesByIds: () => deleteMemoriesByIds,
|
|
9722
9756
|
deleteOldMemories: () => deleteOldMemories,
|
|
@@ -10103,6 +10137,19 @@ function getMemoryById(db, id) {
|
|
|
10103
10137
|
const row = db.prepare("SELECT * FROM memories WHERE id = ?").get(id);
|
|
10104
10138
|
return row ? rowToMemory(row) : null;
|
|
10105
10139
|
}
|
|
10140
|
+
function countHighSignalMemoriesSince(db, repoPath, since) {
|
|
10141
|
+
const row = db.prepare(
|
|
10142
|
+
`SELECT COUNT(*) as count FROM memories
|
|
10143
|
+
WHERE repo_path = ? AND created_at > ?
|
|
10144
|
+
AND forgotten = 0 AND superseded_by IS NULL
|
|
10145
|
+
AND (
|
|
10146
|
+
topic_key IN ('project_dependencies', 'project_tsconfig', 'project_entry_point')
|
|
10147
|
+
OR category IN ('instruction', 'preference')
|
|
10148
|
+
OR (category = 'event' AND importance >= 3)
|
|
10149
|
+
)`
|
|
10150
|
+
).get(repoPath, since);
|
|
10151
|
+
return row?.count ?? 0;
|
|
10152
|
+
}
|
|
10106
10153
|
var dbInstance, dbPathInstance;
|
|
10107
10154
|
var init_db = __esm({
|
|
10108
10155
|
"src/memory/db.ts"() {
|
|
@@ -10464,6 +10511,7 @@ var init_manager3 = __esm({
|
|
|
10464
10511
|
"src/memory/manager.ts"() {
|
|
10465
10512
|
"use strict";
|
|
10466
10513
|
init_client();
|
|
10514
|
+
init_schema();
|
|
10467
10515
|
init_db();
|
|
10468
10516
|
init_embeddings();
|
|
10469
10517
|
init_retrieval();
|
|
@@ -10593,6 +10641,48 @@ Return a JSON array of strings. Example:
|
|
|
10593
10641
|
}
|
|
10594
10642
|
return { id: memory.id, superseded: supersededIds.length > 0 ? supersededIds : void 0 };
|
|
10595
10643
|
}
|
|
10644
|
+
/**
|
|
10645
|
+
* Count high-signal memories created since the given timestamp.
|
|
10646
|
+
* Used for KIMI.md drift detection (Trigger A: session-start check).
|
|
10647
|
+
*/
|
|
10648
|
+
countHighSignalMemoriesSince(repoPath, since) {
|
|
10649
|
+
if (!this.db) return 0;
|
|
10650
|
+
return countHighSignalMemoriesSince(this.db, repoPath, since);
|
|
10651
|
+
}
|
|
10652
|
+
/**
|
|
10653
|
+
* Get the timestamp of the most recent KIMI.md refresh memory.
|
|
10654
|
+
* Returns 0 if none exists.
|
|
10655
|
+
*/
|
|
10656
|
+
getLastKimiMdRefreshTime(repoPath) {
|
|
10657
|
+
if (!this.db) return 0;
|
|
10658
|
+
const rows = this.db.prepare(
|
|
10659
|
+
`SELECT created_at FROM memories
|
|
10660
|
+
WHERE repo_path = ? AND topic_key = 'kimi_md_refresh'
|
|
10661
|
+
AND forgotten = 0 AND superseded_by IS NULL
|
|
10662
|
+
ORDER BY created_at DESC LIMIT 1`
|
|
10663
|
+
).all(repoPath);
|
|
10664
|
+
return rows[0]?.created_at ?? 0;
|
|
10665
|
+
}
|
|
10666
|
+
/**
|
|
10667
|
+
* Record that KIMI.md was refreshed. Creates a lightweight memory
|
|
10668
|
+
* so drift detection knows when the snapshot was last updated.
|
|
10669
|
+
*/
|
|
10670
|
+
async recordKimiMdRefresh(repoPath, sessionId) {
|
|
10671
|
+
if (!this.db) return;
|
|
10672
|
+
const embedding = new Float32Array(DEFAULT_EMBEDDING_DIM);
|
|
10673
|
+
insertMemory(
|
|
10674
|
+
this.db,
|
|
10675
|
+
{
|
|
10676
|
+
content: `KIMI.md refreshed for ${repoPath}`,
|
|
10677
|
+
category: "event",
|
|
10678
|
+
sourceSessionId: sessionId,
|
|
10679
|
+
repoPath,
|
|
10680
|
+
importance: 2,
|
|
10681
|
+
topicKey: "kimi_md_refresh"
|
|
10682
|
+
},
|
|
10683
|
+
embedding
|
|
10684
|
+
);
|
|
10685
|
+
}
|
|
10596
10686
|
/**
|
|
10597
10687
|
* Recall memories using the full hybrid retrieval pipeline.
|
|
10598
10688
|
*/
|
|
@@ -13476,6 +13566,7 @@ function App({
|
|
|
13476
13566
|
const [latestVersion, setLatestVersion] = useState10(initialUpdateResult?.latestVersion ?? null);
|
|
13477
13567
|
const [theme, setTheme] = useState10(resolveTheme(initialCfg?.theme));
|
|
13478
13568
|
const [showThemePicker, setShowThemePicker] = useState10(false);
|
|
13569
|
+
const [kimiMdStale, setKimiMdStale] = useState10(false);
|
|
13479
13570
|
useEffect6(() => {
|
|
13480
13571
|
if (!cfg?.cloudMode || !initialCloudToken) return;
|
|
13481
13572
|
let cancelled = false;
|
|
@@ -13531,6 +13622,8 @@ function App({
|
|
|
13531
13622
|
const busyRef = useRef3(busy);
|
|
13532
13623
|
const memoryManagerRef = useRef3(null);
|
|
13533
13624
|
const sessionStartRecallRef = useRef3(null);
|
|
13625
|
+
const kimiMdStaleNudgedRef = useRef3(false);
|
|
13626
|
+
const turnCounterRef = useRef3(0);
|
|
13534
13627
|
const pendingTextRef = useRef3(/* @__PURE__ */ new Map());
|
|
13535
13628
|
const flushTimeoutRef = useRef3(null);
|
|
13536
13629
|
const customCommandsRef = useRef3([]);
|
|
@@ -13760,6 +13853,13 @@ function App({
|
|
|
13760
13853
|
} catch {
|
|
13761
13854
|
}
|
|
13762
13855
|
})();
|
|
13856
|
+
if (existsSync3(join22(cwd, "KIMI.md"))) {
|
|
13857
|
+
const lastRefresh = manager.getLastKimiMdRefreshTime(cwd);
|
|
13858
|
+
const driftCount = manager.countHighSignalMemoriesSince(cwd, lastRefresh);
|
|
13859
|
+
if (driftCount >= 5) {
|
|
13860
|
+
setKimiMdStale(true);
|
|
13861
|
+
}
|
|
13862
|
+
}
|
|
13763
13863
|
} else {
|
|
13764
13864
|
memoryManagerRef.current?.close();
|
|
13765
13865
|
memoryManagerRef.current = null;
|
|
@@ -14531,7 +14631,17 @@ function App({
|
|
|
14531
14631
|
}
|
|
14532
14632
|
permResolveRef.current = resolve2;
|
|
14533
14633
|
setPerm({ tool: req.tool, args: req.args, resolve: resolve2 });
|
|
14534
|
-
})
|
|
14634
|
+
}),
|
|
14635
|
+
onKimiMdStale: () => {
|
|
14636
|
+
if (!kimiMdStaleNudgedRef.current) {
|
|
14637
|
+
kimiMdStaleNudgedRef.current = true;
|
|
14638
|
+
setKimiMdStale(true);
|
|
14639
|
+
setEvents((e) => [
|
|
14640
|
+
...e,
|
|
14641
|
+
{ kind: "info", key: mkKey(), text: "Project context may be stale. Run /init to refresh KIMI.md based on recent changes." }
|
|
14642
|
+
]);
|
|
14643
|
+
}
|
|
14644
|
+
}
|
|
14535
14645
|
}
|
|
14536
14646
|
});
|
|
14537
14647
|
if (existsSync3(join22(cwd, "KIMI.md"))) {
|
|
@@ -14560,6 +14670,9 @@ function App({
|
|
|
14560
14670
|
...e,
|
|
14561
14671
|
{ kind: "info", key: mkKey(), text: "KIMI.md generated; context loaded for future turns" }
|
|
14562
14672
|
]);
|
|
14673
|
+
void memoryManagerRef.current?.recordKimiMdRefresh(cwd, ensureSessionId());
|
|
14674
|
+
setKimiMdStale(false);
|
|
14675
|
+
kimiMdStaleNudgedRef.current = false;
|
|
14563
14676
|
}
|
|
14564
14677
|
} catch (e) {
|
|
14565
14678
|
if (e.name === "AbortError") {
|
|
@@ -15506,6 +15619,13 @@ ${lines.join("\n")}` }]);
|
|
|
15506
15619
|
};
|
|
15507
15620
|
}
|
|
15508
15621
|
}
|
|
15622
|
+
turnCounterRef.current += 1;
|
|
15623
|
+
if (turnCounterRef.current % 15 === 0 && existsSync3(join22(process.cwd(), "KIMI.md")) && !kimiMdStale) {
|
|
15624
|
+
setEvents((e) => [
|
|
15625
|
+
...e,
|
|
15626
|
+
{ kind: "info", key: mkKey(), text: "Tip: Rerunning /init occasionally helps KimiFlare stay accurate as your project evolves." }
|
|
15627
|
+
]);
|
|
15628
|
+
}
|
|
15509
15629
|
setBusy(true);
|
|
15510
15630
|
gatewayMetaRef.current = null;
|
|
15511
15631
|
setGatewayMeta(null);
|
|
@@ -15643,7 +15763,17 @@ ${lines.join("\n")}` }]);
|
|
|
15643
15763
|
onToolLimitReached: () => new Promise((resolve2) => {
|
|
15644
15764
|
limitResolveRef.current = resolve2;
|
|
15645
15765
|
setLimitModal({ limit: 50, resolve: resolve2 });
|
|
15646
|
-
})
|
|
15766
|
+
}),
|
|
15767
|
+
onKimiMdStale: () => {
|
|
15768
|
+
if (!kimiMdStaleNudgedRef.current) {
|
|
15769
|
+
kimiMdStaleNudgedRef.current = true;
|
|
15770
|
+
setKimiMdStale(true);
|
|
15771
|
+
setEvents((e) => [
|
|
15772
|
+
...e,
|
|
15773
|
+
{ kind: "info", key: mkKey(), text: "Project context may be stale. Run /init to refresh KIMI.md based on recent changes." }
|
|
15774
|
+
]);
|
|
15775
|
+
}
|
|
15776
|
+
}
|
|
15647
15777
|
};
|
|
15648
15778
|
try {
|
|
15649
15779
|
await runAgentTurn({
|
|
@@ -16100,7 +16230,8 @@ ${lines.join("\n")}` }]);
|
|
|
16100
16230
|
gatewayMeta,
|
|
16101
16231
|
codeMode,
|
|
16102
16232
|
cloudMode: cfg.cloudMode,
|
|
16103
|
-
cloudBudget
|
|
16233
|
+
cloudBudget,
|
|
16234
|
+
kimiMdStale
|
|
16104
16235
|
}
|
|
16105
16236
|
),
|
|
16106
16237
|
activePicker?.kind === "file" && /* @__PURE__ */ jsx23(
|