kimiflare 0.88.1 → 0.88.3

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
@@ -3418,15 +3418,87 @@ async function fetchWithRetry(url, init, retries = 3) {
3418
3418
  }
3419
3419
  throw lastError ?? new Error("embeddings request failed after retries");
3420
3420
  }
3421
+ function parseOpenAiEmbeddingResponse(json2) {
3422
+ if (!json2 || typeof json2 !== "object") {
3423
+ throw new Error("embeddings response was not an object");
3424
+ }
3425
+ const data = json2.data;
3426
+ if (!Array.isArray(data)) {
3427
+ throw new Error("embeddings response contained no data array");
3428
+ }
3429
+ const indexed = [];
3430
+ for (const item of data) {
3431
+ if (!item || typeof item !== "object") continue;
3432
+ const embedding = item.embedding;
3433
+ const idx = item.index;
3434
+ if (!Array.isArray(embedding)) continue;
3435
+ indexed.push({
3436
+ index: typeof idx === "number" ? idx : indexed.length,
3437
+ vector: new Float32Array(embedding)
3438
+ });
3439
+ }
3440
+ if (indexed.length === 0) {
3441
+ throw new Error("embeddings response contained no vectors");
3442
+ }
3443
+ indexed.sort((a, b) => a.index - b.index);
3444
+ return indexed.map((item) => {
3445
+ if (item.vector.length === 0) {
3446
+ throw new Error("embeddings response contained empty vector");
3447
+ }
3448
+ return item.vector;
3449
+ });
3450
+ }
3451
+ function parseWorkersAiEmbeddingResponse(json2) {
3452
+ let vectors = [];
3453
+ if (json2 && typeof json2 === "object") {
3454
+ const result = json2.result;
3455
+ if (result && typeof result === "object") {
3456
+ const data = result.data;
3457
+ if (Array.isArray(data)) {
3458
+ if (Array.isArray(data[0])) {
3459
+ vectors = data;
3460
+ } else {
3461
+ const shape = result.shape;
3462
+ if (shape && shape.length === 2) {
3463
+ const dim = shape[1];
3464
+ const flat = data;
3465
+ vectors = [];
3466
+ for (let i = 0; i < flat.length; i += dim) {
3467
+ vectors.push(flat.slice(i, i + dim));
3468
+ }
3469
+ }
3470
+ }
3471
+ }
3472
+ }
3473
+ }
3474
+ if (vectors.length === 0) {
3475
+ throw new Error("embeddings response contained no vectors");
3476
+ }
3477
+ return vectors.map((vec) => {
3478
+ const arr = new Float32Array(vec);
3479
+ if (arr.length === 0) {
3480
+ throw new Error("embeddings response contained empty vector");
3481
+ }
3482
+ return arr;
3483
+ });
3484
+ }
3421
3485
  async function fetchEmbeddings(opts2) {
3422
3486
  const model = opts2.model ?? DEFAULT_MODEL2;
3487
+ const texts = opts2.texts.map(truncateForEmbedding);
3488
+ if (texts.length === 0) {
3489
+ return [];
3490
+ }
3423
3491
  let url;
3424
3492
  const headers = {
3425
3493
  "Content-Type": "application/json",
3426
3494
  "User-Agent": getUserAgent()
3427
3495
  };
3496
+ let body;
3497
+ let parseResponse;
3428
3498
  if (opts2.gateway) {
3429
- url = `https://gateway.ai.cloudflare.com/v1/${opts2.accountId}/${opts2.gateway.id}/workers-ai/${model}`;
3499
+ url = `https://gateway.ai.cloudflare.com/v1/${encodeURIComponent(
3500
+ opts2.accountId
3501
+ )}/${encodeURIComponent(opts2.gateway.id)}/compat/embeddings`;
3430
3502
  headers.Authorization = `Bearer ${opts2.apiToken}`;
3431
3503
  const merged = {
3432
3504
  ...opts2.gateway.metadata ?? {},
@@ -3440,48 +3512,22 @@ async function fetchEmbeddings(opts2) {
3440
3512
  if (opts2.gateway.skipCache !== void 0) {
3441
3513
  headers["cf-aig-skip-cache"] = String(opts2.gateway.skipCache);
3442
3514
  }
3515
+ body = JSON.stringify({
3516
+ model: `workers-ai/${model}`,
3517
+ input: texts
3518
+ });
3519
+ parseResponse = parseOpenAiEmbeddingResponse;
3443
3520
  } else {
3444
- url = `https://api.cloudflare.com/client/v4/accounts/${opts2.accountId}/ai/run/${model}`;
3521
+ url = `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(
3522
+ opts2.accountId
3523
+ )}/ai/run/${encodeURIComponent(model)}`;
3445
3524
  headers.Authorization = `Bearer ${opts2.apiToken}`;
3525
+ body = JSON.stringify({ text: texts });
3526
+ parseResponse = parseWorkersAiEmbeddingResponse;
3446
3527
  }
3447
- const results = [];
3448
- for (const text of opts2.texts) {
3449
- const truncated = truncateForEmbedding(text);
3450
- const body = JSON.stringify({ text: [truncated] });
3451
- const res = await fetchWithRetry(url, { method: "POST", headers, body });
3452
- const json2 = await res.json();
3453
- let vectors = [];
3454
- if (json2 && typeof json2 === "object") {
3455
- const result = json2.result;
3456
- if (result && typeof result === "object") {
3457
- const data = result.data;
3458
- if (Array.isArray(data)) {
3459
- if (Array.isArray(data[0])) {
3460
- vectors = data;
3461
- } else {
3462
- const shape = result.shape;
3463
- if (shape && shape.length === 2) {
3464
- const dim = shape[1];
3465
- const flat = data;
3466
- vectors = [];
3467
- for (let i = 0; i < flat.length; i += dim) {
3468
- vectors.push(flat.slice(i, i + dim));
3469
- }
3470
- }
3471
- }
3472
- }
3473
- }
3474
- }
3475
- if (vectors.length === 0) {
3476
- throw new Error("embeddings response contained no vectors");
3477
- }
3478
- const vec = new Float32Array(vectors[0]);
3479
- if (vec.length === 0) {
3480
- throw new Error("embeddings response contained empty vector");
3481
- }
3482
- results.push(vec);
3483
- }
3484
- return results;
3528
+ const res = await fetchWithRetry(url, { method: "POST", headers, body });
3529
+ const json2 = await res.json();
3530
+ return parseResponse(json2);
3485
3531
  }
3486
3532
  function cosineSimilarity(a, b) {
3487
3533
  if (a.length !== b.length) {
@@ -11191,6 +11237,50 @@ Return a JSON array of strings. Example:
11191
11237
  }
11192
11238
  return { id: memory.id, superseded: supersededIds.length > 0 ? supersededIds : void 0 };
11193
11239
  }
11240
+ /**
11241
+ * Store a plan directly under a deterministic topic key.
11242
+ * Skips embedding, verification, and hypothetical queries so it is fast and
11243
+ * deterministic. Supersedes any previous plan stored under the same key.
11244
+ */
11245
+ async rememberPlan(plan, repoPath, sessionId, topicKey = "current_dev_plan") {
11246
+ if (!this.db) throw new Error("Memory DB not open");
11247
+ const safeContent = this.shouldRedact() ? redactSecrets(plan) : plan;
11248
+ if (!safeContent.trim()) {
11249
+ throw new Error("Plan content is empty after redaction");
11250
+ }
11251
+ const normalizedKey = topicKey.trim();
11252
+ if (!normalizedKey) {
11253
+ throw new Error("Plan topic key cannot be empty");
11254
+ }
11255
+ const supersededIds = [];
11256
+ const existing = findMemoriesByTopicKey(this.db, repoPath, normalizedKey);
11257
+ for (const old of existing) {
11258
+ supersedeMemory(this.db, old.id, "pending");
11259
+ supersededIds.push(old.id);
11260
+ }
11261
+ const zeroEmbedding = new Float32Array(DEFAULT_EMBEDDING_DIM);
11262
+ const memory = insertMemory(this.db, {
11263
+ content: safeContent,
11264
+ category: "task",
11265
+ sourceSessionId: sessionId,
11266
+ repoPath,
11267
+ importance: 4,
11268
+ topicKey: normalizedKey
11269
+ }, zeroEmbedding);
11270
+ for (const oldId of supersededIds) {
11271
+ supersedeMemory(this.db, oldId, memory.id);
11272
+ }
11273
+ return { id: memory.id, superseded: supersededIds.length > 0 ? supersededIds : void 0 };
11274
+ }
11275
+ /**
11276
+ * Recall the latest memory for an exact topic key.
11277
+ * Does not use embeddings; returns null if no matching memory exists.
11278
+ */
11279
+ getByTopicKey(repoPath, topicKey) {
11280
+ if (!this.db) return null;
11281
+ const rows = findMemoriesByTopicKey(this.db, repoPath, topicKey);
11282
+ return rows[0] ?? null;
11283
+ }
11194
11284
  /**
11195
11285
  * Count high-signal memories created since the given timestamp.
11196
11286
  * Used for KIMI.md drift detection (Trigger A: session-start check).
@@ -16777,6 +16867,32 @@ var init_distill = __esm({
16777
16867
  }
16778
16868
  });
16779
16869
 
16870
+ // src/agent/plan-resolver.ts
16871
+ function resolvePlanForFresh(opts2) {
16872
+ const { mode, messages, sessionPlan, memoryManager, memoryEnabled, repoPath } = opts2;
16873
+ if (mode !== "plan") {
16874
+ return null;
16875
+ }
16876
+ if (sessionPlan) {
16877
+ return sessionPlan;
16878
+ }
16879
+ if (memoryEnabled && memoryManager) {
16880
+ const stored = memoryManager.getByTopicKey(repoPath, PLAN_MEMORY_TOPIC_KEY);
16881
+ if (stored?.content) {
16882
+ return stored.content;
16883
+ }
16884
+ }
16885
+ return distillSessionPlan(messages);
16886
+ }
16887
+ var PLAN_MEMORY_TOPIC_KEY;
16888
+ var init_plan_resolver = __esm({
16889
+ "src/agent/plan-resolver.ts"() {
16890
+ "use strict";
16891
+ init_distill();
16892
+ PLAN_MEMORY_TOPIC_KEY = "current_dev_plan";
16893
+ }
16894
+ });
16895
+
16780
16896
  // src/agent/continuation-summary.ts
16781
16897
  import { execSync as execSync4 } from "child_process";
16782
16898
  function extractFirstUserGoal(messages) {
@@ -19863,6 +19979,10 @@ Executor opened PR: ${prUrl}` : plan });
19863
19979
  const plan = distillSessionPlan(messages);
19864
19980
  if (plan) {
19865
19981
  sessionPlan = plan;
19982
+ if (startupCfg?.memoryEnabled && memoryManager) {
19983
+ void memoryManager.rememberPlan(plan, process.cwd(), randomUUID2()).catch(() => {
19984
+ });
19985
+ }
19866
19986
  }
19867
19987
  }
19868
19988
  if (planOptionsRef.current && !currentController?.signal.aborted) {
@@ -21609,7 +21729,14 @@ changelog-image failed: ${err instanceof Error ? err.message : String(err)}
21609
21729
  return true;
21610
21730
  }
21611
21731
  void (async () => {
21612
- const summary = await generateContinuationSummary({
21732
+ const summary = currentMode === "plan" ? resolvePlanForFresh({
21733
+ mode: currentMode,
21734
+ messages,
21735
+ sessionPlan,
21736
+ memoryManager,
21737
+ memoryEnabled: startupCfg?.memoryEnabled,
21738
+ repoPath: process.cwd()
21739
+ }) : await generateContinuationSummary({
21613
21740
  messages,
21614
21741
  mode: currentMode,
21615
21742
  accountId: opts2.accountId,
@@ -21908,6 +22035,7 @@ var init_ui_mode = __esm({
21908
22035
  init_sessions();
21909
22036
  init_llm_summarize();
21910
22037
  init_distill();
22038
+ init_plan_resolver();
21911
22039
  init_continuation_summary();
21912
22040
  init_greetings();
21913
22041
  init_theme();
@@ -31461,6 +31589,7 @@ var init_slash_commands = __esm({
31461
31589
  init_session_store();
31462
31590
  init_deploy();
31463
31591
  init_tui_auth();
31592
+ init_plan_resolver();
31464
31593
  init_continuation_summary();
31465
31594
  init_clipboard();
31466
31595
  handleExit = (ctx) => {
@@ -31513,7 +31642,14 @@ var init_slash_commands = __esm({
31513
31642
  ]);
31514
31643
  return true;
31515
31644
  }
31516
- const summary = await generateContinuationSummary({
31645
+ const summary = ctx.mode === "plan" ? resolvePlanForFresh({
31646
+ mode: ctx.mode,
31647
+ messages: ctx.messagesRef.current,
31648
+ sessionPlan: ctx.sessionPlanRef.current,
31649
+ memoryManager: ctx.memoryManagerRef.current,
31650
+ memoryEnabled: cfg?.memoryEnabled,
31651
+ repoPath: process.cwd()
31652
+ }) : await generateContinuationSummary({
31517
31653
  messages: ctx.messagesRef.current,
31518
31654
  mode: ctx.mode,
31519
31655
  accountId: cfg?.accountId ?? "",
@@ -34953,7 +35089,14 @@ ${wcagWarnings.join("\n")}` }
34953
35089
  (picked) => {
34954
35090
  setShowPlanCompletePicker(false);
34955
35091
  if (!picked || picked === "continue") return;
34956
- const plan = sessionPlanRef.current ?? distillSessionPlan(messagesRef.current);
35092
+ const plan = resolvePlanForFresh({
35093
+ mode: "plan",
35094
+ messages: messagesRef.current,
35095
+ sessionPlan: sessionPlanRef.current,
35096
+ memoryManager: memoryManagerRef.current,
35097
+ memoryEnabled: cfg?.memoryEnabled,
35098
+ repoPath: process.cwd()
35099
+ });
34957
35100
  if (!plan) {
34958
35101
  setEvents((e) => [
34959
35102
  ...e,
@@ -35657,6 +35800,10 @@ ${conflicts.join("\n")}` }
35657
35800
  const plan = distillSessionPlan(messagesRef.current);
35658
35801
  if (plan) {
35659
35802
  sessionPlanRef.current = plan;
35803
+ if (cfg?.memoryEnabled && memoryManagerRef.current && sessionIdRef.current) {
35804
+ void memoryManagerRef.current.rememberPlan(plan, process.cwd(), sessionIdRef.current).catch(() => {
35805
+ });
35806
+ }
35660
35807
  setShowPlanCompletePicker(true);
35661
35808
  }
35662
35809
  }
@@ -36245,6 +36392,7 @@ var init_app = __esm({
36245
36392
  init_manager_init();
36246
36393
  init_run_compact();
36247
36394
  init_distill();
36395
+ init_plan_resolver();
36248
36396
  init_command_handlers();
36249
36397
  init_app_helpers();
36250
36398
  }