@botiverse/kimi-code-sdk 0.9.4 → 0.16.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/NOTICE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # NOTICE
2
2
 
3
3
  @botiverse/kimi-code-sdk is a repackage of the built **@moonshot-ai/kimi-code-sdk** node-sdk
4
- from [MoonshotAI/kimi-code](https://github.com/MoonshotAI/kimi-code) at `@moonshot-ai/kimi-code@0.15.0`, distributed under upstream's MIT License (see LICENSE). Sibling packages are bundled into `dist`.
4
+ from [MoonshotAI/kimi-code](https://github.com/MoonshotAI/kimi-code) at `@moonshot-ai/kimi-code@0.16.0`, distributed under upstream's MIT License (see LICENSE). Sibling packages are bundled into `dist`.
5
5
  Mirror + provenance: https://github.com/botiverse/kimi-code-sdk
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @botiverse/kimi-code-sdk
2
2
 
3
- Built repackage of `@moonshot-ai/kimi-code-sdk` (kimi-code @moonshot-ai/kimi-code@0.15.0) for Slock/Botiverse.
3
+ Built repackage of `@moonshot-ai/kimi-code-sdk` (kimi-code @moonshot-ai/kimi-code@0.16.0) for Slock/Botiverse.
4
4
  Read-only mirror + release notes: https://github.com/botiverse/kimi-code-sdk
5
5
 
6
6
  > Not affiliated with Moonshot AI. MIT (see LICENSE).
package/dist/index.d.mts CHANGED
@@ -78,6 +78,7 @@ declare class Agent {
78
78
  readonly log: Logger;
79
79
  readonly telemetry: TelemetryClient;
80
80
  readonly experimentalFlags: ExperimentalFlagResolver;
81
+ readonly llmRequestLogger: LlmRequestLogger;
81
82
  readonly blobStore: BlobStore | undefined;
82
83
  readonly records: AgentRecords;
83
84
  readonly fullCompaction: FullCompaction;
@@ -96,15 +97,12 @@ declare class Agent {
96
97
  readonly cron: CronManager | null;
97
98
  readonly goal: GoalMode;
98
99
  readonly replayBuilder: ReplayBuilder;
99
- private lastLlmConfigLogSignature?;
100
100
  constructor(options: AgentOptions);
101
101
  setKaos(kaos: Kaos): void;
102
102
  get generate(): typeof generate;
103
103
  get llm(): KosongLLM;
104
- private logLlmRequest;
105
- private logLlmConfigIfChanged;
106
104
  useProfile(profile: ResolvedAgentProfile, context?: PreparedSystemPromptContext): void;
107
- resume(): Promise<{
105
+ resume(options?: AgentRecordsReplayOptions): Promise<{
108
106
  warning?: string;
109
107
  }>;
110
108
  get rpcMethods(): PromisableMethods<AgentAPI>;
@@ -215,6 +213,7 @@ declare interface AgentOptions {
215
213
  readonly telemetry?: TelemetryClient | undefined;
216
214
  readonly pluginSessionStarts?: readonly EnabledPluginSessionStart[];
217
215
  readonly experimentalFlags?: ExperimentalFlagResolver;
216
+ readonly replay?: ReplayBuilderOptions;
218
217
  }
219
218
 
220
219
  declare type AgentRecord = {
@@ -326,13 +325,17 @@ declare class AgentRecords {
326
325
  constructor(agent: Agent, persistence?: AgentRecordPersistence | undefined);
327
326
  get restoring(): RestoringContext | null;
328
327
  logRecord(record: AgentRecord): void;
329
- restore(record: AgentRecord): void;
330
- replay(): Promise<{
328
+ restore(record: AgentRecord): boolean;
329
+ replay(options?: AgentRecordsReplayOptions): Promise<{
331
330
  warning?: string;
332
331
  }>;
333
332
  flush(): Promise<void>;
334
333
  }
335
334
 
335
+ declare interface AgentRecordsReplayOptions {
336
+ readonly rewriteMigratedRecords?: boolean;
337
+ }
338
+
336
339
  export declare type AgentReplayRecord = {
337
340
  readonly time: number;
338
341
  } & AgentReplayRecordPayload;
@@ -918,10 +921,6 @@ declare interface CloseSessionPayload {
918
921
  readonly sessionId: string;
919
922
  }
920
923
 
921
- declare interface CompactedHistory {
922
- text: string;
923
- }
924
-
925
924
  declare interface CompactionBeginData {
926
925
  instruction?: string;
927
926
  source: CompactionSource;
@@ -957,8 +956,6 @@ declare interface CompactionSummaryOrigin {
957
956
  readonly kind: 'compaction_summary';
958
957
  }
959
958
 
960
- declare type CompactionTelemetryTrigger = CompactionBeginData['source'] | 'manual-with-prompt' | 'unknown';
961
-
962
959
  export declare interface CompactOptions {
963
960
  readonly instruction?: string | undefined;
964
961
  }
@@ -1833,20 +1830,14 @@ declare class FullCompaction {
1833
1830
  protected compactionCountInTurn: number;
1834
1831
  protected compacting: {
1835
1832
  abortController: AbortController;
1836
- startedAt: number;
1837
- telemetryTrigger: CompactionTelemetryTrigger;
1838
1833
  promise: Promise<void>;
1839
1834
  blockedByTurn: boolean;
1840
1835
  } | null;
1841
- protected _compactedHistory: CompactedHistory[];
1842
1836
  protected readonly strategy: CompactionStrategy;
1843
1837
  constructor(agent: Agent, strategy?: CompactionStrategy);
1844
1838
  get isCompacting(): boolean;
1845
- get compactedHistory(): readonly CompactedHistory[];
1846
1839
  begin(data: Readonly<CompactionBeginData>): void;
1847
- private startCompactionWorker;
1848
1840
  cancel(): void;
1849
- private markCanceled;
1850
1841
  markCompleted(): void;
1851
1842
  private get tokenCountWithPending();
1852
1843
  resetForTurn(): void;
@@ -1857,6 +1848,7 @@ declare class FullCompaction {
1857
1848
  private beginAutoCompaction;
1858
1849
  private block;
1859
1850
  private compactionWorker;
1851
+ private compactionRound;
1860
1852
  private triggerPreCompactHook;
1861
1853
  private triggerPostCompactHook;
1862
1854
  private postProcessSummary;
@@ -3531,7 +3523,6 @@ declare class KosongLLM implements LLM {
3531
3523
 
3532
3524
  declare interface KosongLLMConfig {
3533
3525
  readonly provider: ChatProvider;
3534
- readonly modelName: string;
3535
3526
  readonly systemPrompt: string;
3536
3527
  readonly capability?: ModelCapability | undefined;
3537
3528
  /**
@@ -3569,7 +3560,7 @@ declare interface LLMChatParams {
3569
3560
  messages: Message[];
3570
3561
  tools: readonly Tool[];
3571
3562
  signal: AbortSignal;
3572
- requestLogContext?: LLMRequestLogContext;
3563
+ requestLogFields?: LLMRequestLogFields;
3573
3564
  onTextDelta?: ((delta: string) => void) | undefined;
3574
3565
  onThinkDelta?: ((delta: string) => void) | undefined;
3575
3566
  onToolCallDelta?: ((delta: ToolCallDelta) => void) | undefined;
@@ -3597,12 +3588,23 @@ declare interface LLMChatResponse {
3597
3588
  streamTiming?: LLMStreamTiming;
3598
3589
  }
3599
3590
 
3600
- declare interface LLMRequestLogContext {
3601
- readonly turnId?: string;
3602
- readonly step?: number;
3603
- readonly stepUuid?: string;
3604
- readonly attempt?: number;
3605
- readonly maxAttempts?: number;
3591
+ declare interface LLMRequestLogFields {
3592
+ readonly turnStep: string;
3593
+ readonly attempt?: string;
3594
+ }
3595
+
3596
+ declare class LlmRequestLogger {
3597
+ private readonly log;
3598
+ private lastConfigLogSignature;
3599
+ constructor(log: Logger);
3600
+ logRequest(input: {
3601
+ readonly provider: ChatProvider;
3602
+ readonly modelAlias?: string;
3603
+ readonly systemPrompt: string;
3604
+ readonly tools: readonly Tool[];
3605
+ readonly messages: readonly Message[];
3606
+ readonly fields: LLMRequestLogFields | undefined;
3607
+ }): void;
3606
3608
  }
3607
3609
 
3608
3610
  declare interface LLMStreamTiming {
@@ -4798,16 +4800,30 @@ declare type RenameSessionRequest = SessionScopedPayload<RenameSessionPayload>;
4798
4800
 
4799
4801
  declare class ReplayBuilder {
4800
4802
  readonly agent: Agent;
4803
+ private readonly options;
4801
4804
  postRestoring: boolean;
4802
4805
  captureLiveRecords: boolean;
4803
4806
  protected readonly records: AgentReplayRecord[];
4804
- constructor(agent: Agent);
4807
+ private frozen;
4808
+ private segmentStart;
4809
+ constructor(agent: Agent, options?: ReplayBuilderOptions);
4805
4810
  push(record: AgentReplayRecordPayload): void;
4806
4811
  patchLast<T extends AgentReplayRecord['type']>(type: T, patch: Partial<Extract<AgentReplayRecord, {
4807
4812
  type: T;
4808
4813
  }>>): void;
4809
4814
  removeLastMessages(removedMessages: ReadonlySet<ContextMessage>): void;
4815
+ finishRestoringRecord(type: string): boolean;
4810
4816
  buildResult(): readonly AgentReplayRecord[];
4817
+ private removeMessagesFrom;
4818
+ }
4819
+
4820
+ declare interface ReplayBuilderOptions {
4821
+ readonly range?: ReplayRangeOptions;
4822
+ }
4823
+
4824
+ declare interface ReplayRangeOptions {
4825
+ readonly start?: number;
4826
+ readonly count?: number;
4811
4827
  }
4812
4828
 
4813
4829
  declare interface ResolvedAgentProfile {
package/dist/index.mjs CHANGED
@@ -3,7 +3,6 @@ import { dirname as __cjsShimDirname } from 'node:path';
3
3
  const __filename = __cjsShimFileURLToPath(import.meta.url);
4
4
  const __dirname = __cjsShimDirname(__filename);
5
5
  import { createRequire } from "node:module";
6
- import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
7
6
  import I, { createWriteStream } from "fs";
8
7
  import Kr, { EventEmitter } from "events";
9
8
  import * as path$1$1 from "path";
@@ -21,6 +20,7 @@ import * as path$9 from "node:path";
21
20
  import path, { basename, dirname as dirname$1, join, posix, win32 } from "node:path";
22
21
  import { Blob as Blob$1, File as File$1 } from "node:buffer";
23
22
  import jn, { access, appendFile, chmod, copyFile, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile as writeFile$1 } from "node:fs/promises";
23
+ import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
24
24
  import { createControlledPromise, objectMap, sleep, uniq } from "@antfu/utils";
25
25
  import { z } from "zod";
26
26
  import { execFile, execFileSync, spawn } from "node:child_process";
@@ -1014,6 +1014,17 @@ function mergeInPlace(target, source) {
1014
1014
  function extractText(message, sep = "") {
1015
1015
  return message.content.filter((part) => part.type === "text").map((part) => part.text).join(sep);
1016
1016
  }
1017
+ /** Create a simple user message with a single text part. */
1018
+ function createUserMessage(content) {
1019
+ return {
1020
+ role: "user",
1021
+ content: [{
1022
+ type: "text",
1023
+ text: content
1024
+ }],
1025
+ toolCalls: []
1026
+ };
1027
+ }
1017
1028
  /** Create a tool result message. */
1018
1029
  function createToolMessage(toolCallId, output) {
1019
1030
  return {
@@ -9351,8 +9362,7 @@ var AnthropicChatProvider = class {
9351
9362
  this._stream = options.stream ?? true;
9352
9363
  this._metadata = options.metadata;
9353
9364
  this._adaptiveThinking = options.adaptiveThinking;
9354
- const apiKey = options.apiKey ?? process.env["ANTHROPIC_API_KEY"];
9355
- this._apiKey = apiKey === void 0 || apiKey.length === 0 ? void 0 : apiKey;
9365
+ this._apiKey = options.apiKey === void 0 || options.apiKey.length === 0 ? void 0 : options.apiKey;
9356
9366
  this._baseUrl = options.baseUrl;
9357
9367
  this._defaultHeaders = options.defaultHeaders;
9358
9368
  this._clientFactory = options.clientFactory;
@@ -9458,13 +9468,38 @@ var AnthropicChatProvider = class {
9458
9468
  return resolveAuthBackedClient({
9459
9469
  cachedClient: this._client,
9460
9470
  clientFactory: this._clientFactory
9461
- }, auth, (a) => this._buildClient(requireProviderApiKey("AnthropicChatProvider", a, this._apiKey)));
9471
+ }, auth, (a) => this._buildClient(this._requireApiKey(a)));
9472
+ }
9473
+ _requireApiKey(auth) {
9474
+ const apiKey = auth?.apiKey ?? this._apiKey;
9475
+ if (apiKey === void 0 || apiKey.length === 0) throw new ChatProviderError("AnthropicChatProvider: apiKey is required. Provide it via constructor options, options.auth.apiKey on each request, or an OAuth login. The Anthropic adapter does not read shell API-key environment variables.");
9476
+ return apiKey;
9477
+ }
9478
+ _anthropicCustomHeaderEnvNames() {
9479
+ const customHeaders = process.env["ANTHROPIC_CUSTOM_HEADERS"];
9480
+ if (customHeaders === void 0 || customHeaders.length === 0) return [];
9481
+ const names = [];
9482
+ for (const line of customHeaders.split("\n")) {
9483
+ const colonIndex = line.indexOf(":");
9484
+ if (colonIndex < 0) continue;
9485
+ const name = line.slice(0, colonIndex).trim().toLowerCase();
9486
+ if (name.length > 0) names.push(name);
9487
+ }
9488
+ return names;
9489
+ }
9490
+ _buildDefaultHeaders(apiKey) {
9491
+ const defaultHeaders = { authorization: null };
9492
+ for (const name of this._anthropicCustomHeaderEnvNames()) defaultHeaders[name] = null;
9493
+ for (const [name, value] of Object.entries(this._defaultHeaders ?? {})) defaultHeaders[name.toLowerCase()] = value;
9494
+ defaultHeaders["x-api-key"] = apiKey;
9495
+ return defaultHeaders;
9462
9496
  }
9463
9497
  _buildClient(apiKey) {
9464
9498
  return new Anthropic({
9465
9499
  apiKey,
9466
- baseURL: this._baseUrl,
9467
- defaultHeaders: this._defaultHeaders
9500
+ authToken: null,
9501
+ baseURL: this._baseUrl ?? null,
9502
+ defaultHeaders: this._buildDefaultHeaders(apiKey)
9468
9503
  });
9469
9504
  }
9470
9505
  withThinking(effort) {
@@ -49791,14 +49826,12 @@ function logRequestFailure(input, error, attempt, maxAttempts) {
49791
49826
  });
49792
49827
  }
49793
49828
  function paramsForAttempt(input, attempt, maxAttempts) {
49829
+ const turnStep = `${input.turnId}.${String(input.currentStep)}`;
49794
49830
  return {
49795
49831
  ...input.params,
49796
- requestLogContext: {
49797
- turnId: input.turnId,
49798
- step: input.currentStep,
49799
- stepUuid: input.stepUuid,
49800
- attempt,
49801
- maxAttempts
49832
+ requestLogFields: attempt === 1 ? { turnStep } : {
49833
+ turnStep,
49834
+ attempt: `${String(attempt)}/${String(maxAttempts)}`
49802
49835
  }
49803
49836
  };
49804
49837
  }
@@ -54712,6 +54745,7 @@ function renderPrompt(template, vars) {
54712
54745
  }
54713
54746
  //#endregion
54714
54747
  //#region ../agent-core/src/utils/tokens.ts
54748
+ const messageTokenEstimateCache = /* @__PURE__ */ new WeakMap();
54715
54749
  /**
54716
54750
  * Estimate token count from text using a character-based heuristic.
54717
54751
  * - ASCII (~4 chars per token)
@@ -54733,12 +54767,15 @@ function estimateTokensForMessages(messages) {
54733
54767
  return total;
54734
54768
  }
54735
54769
  function estimateTokensForMessage(message) {
54770
+ const cached = messageTokenEstimateCache.get(message);
54771
+ if (cached !== void 0) return cached;
54736
54772
  let total = estimateTokens(message.role);
54737
54773
  total += estimateTokensForContentParts(message.content);
54738
54774
  if (message.toolCalls !== void 0) for (const call of message.toolCalls) {
54739
54775
  total += estimateTokens(call.name);
54740
54776
  total += estimateTokens(JSON.stringify(call.arguments));
54741
54777
  }
54778
+ messageTokenEstimateCache.set(message, total);
54742
54779
  return total;
54743
54780
  }
54744
54781
  function estimateTokensForContentParts(parts) {
@@ -54807,77 +54844,6 @@ function applyCompletionBudget(args) {
54807
54844
  //#region ../agent-core/src/agent/compaction/compaction-instruction.md?raw
54808
54845
  var compaction_instruction_default = "\n--- This message is a direct task, not part of the above conversation ---\n\nYou are now given a task to compact this conversation context according to specific priorities and output requirements.\n\nOutput text only. DO NOT CALL ANY TOOLS. Calling tools will be rejected and fails the task. You already have all the information you need in the conversation history. You have only one chance.\n\nThe goal of compaction is to keep essential code patterns, technical details, and architectural decisions for continuing development without losing context after the above messages are cleared work.\n\n{{ customInstruction }}\n\n<!-- Compression Priorities (in order) -->\n\n1. **Current Task State**: What is being worked on RIGHT NOW\n2. **Errors & Solutions**: All encountered errors and their resolutions\n3. **Code Evolution**: Final working versions only (remove intermediate attempts)\n4. **System Context**: Project structure, dependencies, environment setup\n5. **Design Decisions**: Architectural choices and their rationale\n6. **TODO Items**: Unfinished tasks and known issues\n\n<!-- Required Output Structure -->\n\n## Current Focus\n\n[What we're working on now]\n\n## Environment\n\n- [Key setup/config points]\n- ...\n\n## Completed Tasks\n\n- [Task]: [Brief outcome]\n- ...\n\n## Active Issues\n\n- [Issue]: [Status/Next steps]\n- ...\n\n## Code State\n\n### [Critical file name]\n\n[Brief description of the file's purpose and current state]\n\n```\n[The latest version of critical code snippets in this file, <20 lines]\n```\n\n### [Critical file name]\n\n- [Useful classes/methods/functions]: [Brief description/usage]\n- ...\n\n<!-- Omit non-critical code, intermediate attempts, and resolved errors -->\n\n## Important Context\n\n- [Any crucial information not covered above]\n- ...\n\n## All User Messages\n\n- [Detailed non tool use user message]\n- ...\n\n<!-- Must output a summary matching the above template in the **final answer**, not in thinking. -->\n";
54809
54846
  //#endregion
54810
- //#region ../agent-core/src/agent/compaction/render-messages.ts
54811
- function renderMessagesToText(messages) {
54812
- return messages.map((message, index) => renderMessageToText(message, index)).join("\n\n");
54813
- }
54814
- function renderMessageToText(message, index) {
54815
- const header = [`message ${String(index + 1)}`, `role=${message.role}`];
54816
- if (message.name !== void 0) header.push(`name=${JSON.stringify(message.name)}`);
54817
- if (message.toolCallId !== void 0) header.push(`toolCallId=${JSON.stringify(message.toolCallId)}`);
54818
- if (message.partial === true) header.push("partial=true");
54819
- const lines = [`--- ${header.join(" ")} ---`];
54820
- if (message.content.length === 0) lines.push("[empty content]");
54821
- else lines.push(...message.content.map(renderContentPartToText));
54822
- if (message.toolCalls.length > 0) {
54823
- lines.push("tool calls:");
54824
- for (const toolCall of message.toolCalls) lines.push(renderToolCallToText(toolCall));
54825
- }
54826
- return lines.join("\n");
54827
- }
54828
- function renderContentPartToText(part) {
54829
- switch (part.type) {
54830
- case "text": return renderBlock("text", part.text);
54831
- case "think": return renderBlock("think", part.think);
54832
- case "image_url": return renderMediaPart("image_url", part.imageUrl.url, part.imageUrl.id);
54833
- case "audio_url": return renderMediaPart("audio_url", part.audioUrl.url, part.audioUrl.id);
54834
- case "video_url": return renderMediaPart("video_url", part.videoUrl.url, part.videoUrl.id);
54835
- default: return renderBlock("content", stringifyJsonish(part));
54836
- }
54837
- }
54838
- function renderToolCallToText(toolCall) {
54839
- const lines = [`- ${toolCall.id}: ${toolCall.name}`, renderBlock("arguments", renderToolCallArguments(toolCall.arguments))];
54840
- if (toolCall.extras !== void 0) lines.push(renderBlock("extras", stringifyJsonish(toolCall.extras)));
54841
- return lines.join("\n");
54842
- }
54843
- function renderToolCallArguments(args) {
54844
- if (args === null) return "null";
54845
- try {
54846
- return stringifyJsonish(JSON.parse(args));
54847
- } catch {
54848
- return args;
54849
- }
54850
- }
54851
- function renderMediaPart(type, url, id) {
54852
- if (id === void 0) return `${type}: ${url}`;
54853
- return `${type}: ${url} (id=${id})`;
54854
- }
54855
- function renderBlock(label, value) {
54856
- return `${label}:\n${indentBlock(value)}`;
54857
- }
54858
- function indentBlock(value) {
54859
- if (value.length === 0) return " ";
54860
- return value.split("\n").map((line) => ` ${line}`).join("\n");
54861
- }
54862
- function stringifyJsonish(value) {
54863
- const seen = /* @__PURE__ */ new WeakSet();
54864
- const replacer = (_key, nested) => {
54865
- if (typeof nested === "bigint") return `${nested.toString()}n`;
54866
- if (typeof nested === "function") return `[Function ${nested.name || "anonymous"}]`;
54867
- if (typeof nested === "symbol") return nested.toString();
54868
- if (nested !== null && typeof nested === "object") {
54869
- if (seen.has(nested)) return "[Circular]";
54870
- seen.add(nested);
54871
- }
54872
- return nested;
54873
- };
54874
- try {
54875
- return JSON.stringify(value, replacer, 2) ?? String(value);
54876
- } catch {
54877
- return String(value);
54878
- }
54879
- }
54880
- //#endregion
54881
54847
  //#region ../agent-core/src/tools/support/input-schema.ts
54882
54848
  /**
54883
54849
  * Shared helper for deriving the JSON Schema that a tool advertises to the
@@ -55050,7 +55016,7 @@ var DefaultCompactionStrategy = class {
55050
55016
  }
55051
55017
  computeCompactCount(messages, source) {
55052
55018
  if (source === "manual") {
55053
- for (let i = messages.length - 1; i > 0; i--) if (canSplitAfter(messages, i)) return i + 1;
55019
+ for (let i = messages.length - 1; i > 0; i--) if (canSplitAfter(messages, i)) return this.fitCompactCountToWindow(messages, i + 1);
55054
55020
  return 0;
55055
55021
  }
55056
55022
  let recentMessages = 1;
@@ -55065,7 +55031,7 @@ var DefaultCompactionStrategy = class {
55065
55031
  if (canSplitAfter(messages, splitIndex)) bestN = splitIndex + 1;
55066
55032
  if ((recentMessages >= this.config.maxRecentMessages || recentUserMessages >= this.config.maxRecentUserMessages || recentSize >= this.maxSize * this.config.maxRecentSizeRatio) && bestN !== void 0) break;
55067
55033
  }
55068
- return bestN ?? 0;
55034
+ return this.fitCompactCountToWindow(messages, bestN ?? 0);
55069
55035
  }
55070
55036
  reduceCompactOnOverflow(messages) {
55071
55037
  const minReducedSize = Math.max(1, Math.ceil(this.maxSize * this.config.minOverflowReductionRatio));
@@ -55080,6 +55046,20 @@ var DefaultCompactionStrategy = class {
55080
55046
  }
55081
55047
  return bestN ?? messages.length;
55082
55048
  }
55049
+ fitCompactCountToWindow(messages, compactedCount) {
55050
+ if (this.maxSize <= 0 || compactedCount <= 0) return compactedCount;
55051
+ let compactedSize = 0;
55052
+ for (let i = 0; i < compactedCount; i++) compactedSize += estimateTokensForMessage(messages[i]);
55053
+ if (compactedSize <= this.maxSize) return compactedCount;
55054
+ let bestN;
55055
+ for (let n = compactedCount - 1; n > 0; n--) {
55056
+ compactedSize -= estimateTokensForMessage(messages[n]);
55057
+ if (!canSplitAfter(messages, n - 1)) continue;
55058
+ bestN = n;
55059
+ if (compactedSize <= this.maxSize) return n;
55060
+ }
55061
+ return bestN ?? compactedCount;
55062
+ }
55083
55063
  get checkAfterStep() {
55084
55064
  return this.config.triggerRatio !== this.config.blockRatio;
55085
55065
  }
@@ -55135,7 +55115,6 @@ var FullCompaction = class {
55135
55115
  agent;
55136
55116
  compactionCountInTurn = 0;
55137
55117
  compacting = null;
55138
- _compactedHistory = [];
55139
55118
  strategy;
55140
55119
  constructor(agent, strategy) {
55141
55120
  this.agent = agent;
@@ -55147,9 +55126,6 @@ var FullCompaction = class {
55147
55126
  get isCompacting() {
55148
55127
  return this.compacting !== null;
55149
55128
  }
55150
- get compactedHistory() {
55151
- return this._compactedHistory;
55152
- }
55153
55129
  begin(data) {
55154
55130
  if (this.compacting) return;
55155
55131
  if (data.source === "manual") this.compactionCountInTurn = 0;
@@ -55168,29 +55144,19 @@ var FullCompaction = class {
55168
55144
  type: "full_compaction.begin",
55169
55145
  ...data
55170
55146
  });
55171
- this.startCompactionWorker(data, compactedCount);
55172
- }
55173
- startCompactionWorker(data, compactedCount) {
55174
- const abortController = new AbortController();
55175
55147
  this.agent.emitEvent({
55176
55148
  type: "compaction.started",
55177
55149
  trigger: data.source,
55178
55150
  instruction: data.instruction
55179
55151
  });
55180
- const active = {
55152
+ const abortController = new AbortController();
55153
+ this.compacting = {
55181
55154
  abortController,
55182
- startedAt: Date.now(),
55183
- telemetryTrigger: compactionTelemetryTrigger(data.source, data.instruction),
55184
- promise: Promise.resolve(),
55155
+ promise: this.compactionWorker(abortController.signal, data, compactedCount),
55185
55156
  blockedByTurn: false
55186
55157
  };
55187
- this.compacting = active;
55188
- active.promise = this.compactionWorker(abortController.signal, data, compactedCount);
55189
55158
  }
55190
55159
  cancel() {
55191
- this.markCanceled();
55192
- }
55193
- markCanceled() {
55194
55160
  this.agent.replayBuilder.patchLast("compaction", { result: "cancelled" });
55195
55161
  if (!this.compacting) return;
55196
55162
  this.agent.records.logRecord({ type: "full_compaction.cancel" });
@@ -55201,7 +55167,6 @@ var FullCompaction = class {
55201
55167
  markCompleted() {
55202
55168
  this.agent.records.logRecord({ type: "full_compaction.complete" });
55203
55169
  this.compacting = null;
55204
- this._compactedHistory.push({ text: renderMessagesToText(this.agent.context.history) });
55205
55170
  }
55206
55171
  get tokenCountWithPending() {
55207
55172
  return this.agent.context.tokenCountWithPending;
@@ -55252,7 +55217,46 @@ var FullCompaction = class {
55252
55217
  await active.promise;
55253
55218
  }
55254
55219
  }
55255
- async compactionWorker(signal, data, initialCompactedCount) {
55220
+ async compactionWorker(signal, data, compactedCount) {
55221
+ try {
55222
+ const finalResult = {
55223
+ summary: "",
55224
+ compactedCount: 1,
55225
+ tokensBefore: 0,
55226
+ tokensAfter: 0
55227
+ };
55228
+ for (let round = 1;; round++) {
55229
+ const result = await this.compactionRound(round, signal, data, compactedCount);
55230
+ if (!result) return;
55231
+ finalResult.summary = result.summary;
55232
+ finalResult.compactedCount += result.compactedCount - 1;
55233
+ finalResult.tokensBefore += result.tokensBefore - finalResult.tokensAfter;
55234
+ finalResult.tokensAfter = result.tokensAfter;
55235
+ if (result.tokensBefore - result.tokensAfter < 1024) break;
55236
+ if (!this.strategy.shouldBlock(result.tokensAfter)) break;
55237
+ compactedCount = this.strategy.computeCompactCount(this.agent.context.history, data.source);
55238
+ if (compactedCount === 0) break;
55239
+ }
55240
+ this.markCompleted();
55241
+ this.agent.emitEvent({
55242
+ type: "compaction.completed",
55243
+ result: finalResult
55244
+ });
55245
+ await this.agent.injection.injectGoal();
55246
+ this.triggerPostCompactHook(data, finalResult);
55247
+ } catch (error) {
55248
+ if (isAbortError(error)) return;
55249
+ const blockedByTurn = this.compacting?.blockedByTurn === true;
55250
+ this.cancel();
55251
+ this.agent.log.error("compaction failed", { error });
55252
+ if (blockedByTurn) throw error;
55253
+ this.agent.emitEvent({
55254
+ type: "error",
55255
+ ...toKimiErrorPayload(error)
55256
+ });
55257
+ }
55258
+ }
55259
+ async compactionRound(round, signal, data, initialCompactedCount) {
55256
55260
  const startedAt = Date.now();
55257
55261
  const originalHistory = [...this.agent.context.history];
55258
55262
  const tokensBefore = estimateTokensForMessages(originalHistory);
@@ -55271,14 +55275,7 @@ var FullCompaction = class {
55271
55275
  let summary;
55272
55276
  while (true) {
55273
55277
  const messagesToCompact = originalHistory.slice(0, compactedCount);
55274
- const messages = [...this.agent.context.project(messagesToCompact), {
55275
- role: "user",
55276
- content: [{
55277
- type: "text",
55278
- text: COMPACTION_INSTRUCTION(data.instruction)
55279
- }],
55280
- toolCalls: []
55281
- }];
55278
+ const messages = [...this.agent.context.project(messagesToCompact), createUserMessage(renderPrompt(compaction_instruction_default, { customInstruction: data.instruction ?? "" }))];
55282
55279
  try {
55283
55280
  const response = await this.agent.generate(provider, this.agent.config.systemPrompt, [...this.agent.tools.loopTools], messages, void 0, { signal });
55284
55281
  if (response.finishReason === "truncated") throw new CompactionTruncatedError();
@@ -55308,51 +55305,30 @@ var FullCompaction = class {
55308
55305
  tokensBefore,
55309
55306
  tokensAfter
55310
55307
  };
55311
- const active = this.compacting;
55312
55308
  this.agent.telemetry.track("compaction_finished", {
55313
- trigger_type: active.telemetryTrigger,
55314
- before_tokens: result.tokensBefore,
55315
- after_tokens: result.tokensAfter,
55316
- duration_ms: Date.now() - active.startedAt,
55317
- compacted_count: result.compactedCount,
55318
- retry_count: retryCount,
55319
- ...usage
55320
- });
55321
- this.markCompleted();
55322
- this.agent.emitEvent({
55323
- type: "compaction.completed",
55324
- result
55309
+ tokensBefore: result.tokensBefore,
55310
+ tokensAfter: result.tokensAfter,
55311
+ duration: Date.now() - startedAt,
55312
+ compactedCount: result.compactedCount,
55313
+ retryCount,
55314
+ round,
55315
+ ...usage,
55316
+ ...data
55325
55317
  });
55326
55318
  this.agent.context.applyCompaction(result);
55327
- await this.agent.injection.injectGoal();
55328
- this.triggerPostCompactHook(data, result);
55319
+ return result;
55329
55320
  } catch (error) {
55330
- if (!isAbortError(error)) {
55331
- const blockedByTurn = this.compacting?.blockedByTurn === true;
55332
- this.agent.log.error("compaction failed", {
55333
- code: isKimiError(error) ? error.code : void 0,
55334
- error
55335
- });
55336
- this.markCanceled();
55337
- if (!blockedByTurn) {
55338
- const payload = isKimiError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED ? toKimiErrorPayload(error) : makeErrorPayload(ErrorCodes.COMPACTION_FAILED, String(error));
55339
- this.agent.emitEvent({
55340
- type: "error",
55341
- ...payload
55342
- });
55343
- }
55344
- this.agent.telemetry.track("compaction_failed", {
55345
- trigger_type: compactionTelemetryTrigger(data.source, data.instruction),
55346
- before_tokens: tokensBefore,
55347
- duration_ms: Date.now() - startedAt,
55348
- retry_count: retryCount,
55349
- error_type: error instanceof Error ? error.name : "Unknown"
55350
- });
55351
- if (blockedByTurn) {
55352
- if (isKimiError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED) throw error;
55353
- throw new KimiError(ErrorCodes.COMPACTION_FAILED, String(error), { cause: error });
55354
- }
55355
- }
55321
+ if (isAbortError(error)) return;
55322
+ this.agent.telemetry.track("compaction_failed", {
55323
+ ...data,
55324
+ tokensBefore,
55325
+ duration: Date.now() - startedAt,
55326
+ round,
55327
+ retryCount,
55328
+ errorType: error instanceof Error ? error.name : "Unknown"
55329
+ });
55330
+ if (isKimiError(error) && error.code === ErrorCodes.AUTH_LOGIN_REQUIRED) throw error;
55331
+ throw new KimiError(ErrorCodes.COMPACTION_FAILED, String(error), { cause: error });
55356
55332
  }
55357
55333
  }
55358
55334
  async triggerPreCompactHook(data, tokenCount, signal) {
@@ -55388,12 +55364,6 @@ function extractCompactionSummary(response) {
55388
55364
  if (summary.trim().length === 0) throw new APIEmptyResponseError("The compaction response did not contain a non-empty summary.");
55389
55365
  return summary;
55390
55366
  }
55391
- const COMPACTION_INSTRUCTION = (customInstruction = "") => renderPrompt(compaction_instruction_default, { customInstruction });
55392
- function compactionTelemetryTrigger(trigger, instruction) {
55393
- if (trigger === void 0) return "unknown";
55394
- if (trigger === "manual" && instruction !== void 0 && instruction.length > 0) return "manual-with-prompt";
55395
- return trigger;
55396
- }
55397
55367
  //#endregion
55398
55368
  //#region ../agent-core/src/agent/compaction/micro.ts
55399
55369
  const DEFAULT_CONFIG = {
@@ -56771,7 +56741,7 @@ var CronManager = class {
56771
56741
  }
56772
56742
  };
56773
56743
  //#endregion
56774
- //#region ../agent-core/src/agent/kimi-env-params.ts
56744
+ //#region ../agent-core/src/config/kimi-env-params.ts
56775
56745
  /**
56776
56746
  * Apply Kimi sampling params (`KIMI_MODEL_TEMPERATURE`, `KIMI_MODEL_TOP_P`) from
56777
56747
  * the environment to a chat provider. Applied at provider construction
@@ -56795,7 +56765,7 @@ function applyKimiEnvSamplingParams(provider, env = process.env) {
56795
56765
  }
56796
56766
  /**
56797
56767
  * Apply the Moonshot preserved-thinking passthrough (`KIMI_MODEL_THINKING_KEEP`
56798
- * -> `thinking.keep`) to a chat provider. Applied in `Agent.llm` after
56768
+ * -> `thinking.keep`) to a chat provider. Applied in `ConfigState.provider` after
56799
56769
  * `withThinking`, and only while thinking is on — otherwise the API would
56800
56770
  * receive a `thinking.keep` with no accompanying `thinking.type` it honors.
56801
56771
  * (Compaction uses a raw provider with thinking off, so it correctly skips this.)
@@ -62523,17 +62493,20 @@ var AgentRecords = class {
62523
62493
  this._restoring = { time: record.time ?? Date.now() };
62524
62494
  try {
62525
62495
  restoreAgentRecord(this.agent, record);
62496
+ return this.agent.replayBuilder.finishRestoringRecord(record.type);
62526
62497
  } finally {
62527
62498
  this._restoring = null;
62528
62499
  }
62529
62500
  }
62530
- async replay() {
62501
+ async replay(options = {}) {
62531
62502
  if (!this.persistence) throw new Error("No persistence provided for AgentRecords");
62503
+ const rewriteMigratedRecords = options.rewriteMigratedRecords ?? true;
62532
62504
  let migrations = [];
62533
62505
  let hasMetadata = false;
62534
62506
  let shouldRewrite = false;
62535
62507
  let warning;
62536
- const replayedRecords = [];
62508
+ const replayedRecords = rewriteMigratedRecords ? [] : void 0;
62509
+ let completed = true;
62537
62510
  for await (const record of this.persistence.read()) {
62538
62511
  if (!hasMetadata) {
62539
62512
  if (record.type !== "metadata") throw new Error("AgentRecords replay expected metadata as the first record");
@@ -62553,14 +62526,17 @@ var AgentRecords = class {
62553
62526
  ...migratedRecord,
62554
62527
  protocol_version: "1.4"
62555
62528
  };
62556
- replayedRecords.push(migratedRecord);
62557
- this.restore(migratedRecord);
62529
+ replayedRecords?.push(migratedRecord);
62530
+ if (this.restore(migratedRecord)) {
62531
+ completed = false;
62532
+ break;
62533
+ }
62558
62534
  }
62559
- if (shouldRewrite) {
62535
+ if (completed && shouldRewrite && replayedRecords !== void 0) {
62560
62536
  this.persistence.rewrite(replayedRecords);
62561
62537
  await this.persistence.flush();
62562
62538
  }
62563
- if (this.agent.blobStore !== void 0) for (const msg of this.agent.context.history) await this.agent.blobStore.rehydrateParts(msg.content);
62539
+ if (completed && this.agent.blobStore !== void 0) for (const msg of this.agent.context.history) await this.agent.blobStore.rehydrateParts(msg.content);
62564
62540
  return { warning };
62565
62541
  }
62566
62542
  async flush() {
@@ -62569,36 +62545,78 @@ var AgentRecords = class {
62569
62545
  };
62570
62546
  //#endregion
62571
62547
  //#region ../agent-core/src/agent/replay/index.ts
62548
+ const UNDO_BOUNDARY_RECORD_TYPES = new Set(["context.clear", "context.apply_compaction"]);
62572
62549
  var ReplayBuilder = class {
62573
62550
  agent;
62551
+ options;
62574
62552
  postRestoring = false;
62575
62553
  captureLiveRecords = false;
62576
62554
  records = [];
62577
- constructor(agent) {
62555
+ frozen = false;
62556
+ segmentStart = 0;
62557
+ constructor(agent, options = {}) {
62578
62558
  this.agent = agent;
62559
+ this.options = options;
62579
62560
  }
62580
62561
  push(record) {
62581
- if (this.captureLiveRecords || this.agent.records.restoring || this.postRestoring) this.records.push({
62582
- ...record,
62583
- time: this.agent.records.restoring?.time ?? Date.now()
62584
- });
62562
+ if (this.captureLiveRecords || this.agent.records.restoring || this.postRestoring) {
62563
+ if (this.frozen) return;
62564
+ const stamped = {
62565
+ ...record,
62566
+ time: this.agent.records.restoring?.time ?? Date.now()
62567
+ };
62568
+ this.records.push(stamped);
62569
+ }
62585
62570
  }
62586
62571
  patchLast(type, patch) {
62572
+ if (this.frozen) return;
62587
62573
  if (this.agent.records.restoring) {
62588
62574
  const last = this.records.at(-1);
62589
62575
  if (last && last.type === type) Object.assign(last, patch);
62590
62576
  }
62591
62577
  }
62592
62578
  removeLastMessages(removedMessages) {
62579
+ if (this.frozen) return;
62593
62580
  if (removedMessages.size === 0) return;
62594
- for (let i = this.records.length - 1; i >= 0; i--) {
62595
- const record = this.records[i];
62596
- if (record.type === "message" && removedMessages.has(record.message)) this.records.splice(i, 1);
62581
+ this.removeMessagesFrom(this.records, removedMessages);
62582
+ }
62583
+ finishRestoringRecord(type) {
62584
+ const range = this.options.range;
62585
+ if (range === void 0) return false;
62586
+ if (this.frozen) return true;
62587
+ if (!UNDO_BOUNDARY_RECORD_TYPES.has(type)) return false;
62588
+ if (range.start === void 0) return false;
62589
+ const start = range.start;
62590
+ const nextSegmentStart = this.segmentStart + this.records.length;
62591
+ if (nextSegmentStart > start) {
62592
+ this.frozen = true;
62593
+ return true;
62597
62594
  }
62595
+ this.segmentStart = nextSegmentStart;
62596
+ this.records.splice(0);
62597
+ return false;
62598
62598
  }
62599
62599
  buildResult() {
62600
+ const range = this.options.range;
62601
+ if (range !== void 0) {
62602
+ if (range.start === void 0 && range.count !== void 0) {
62603
+ const offset = Math.max(0, this.records.length - range.count);
62604
+ return this.records.slice(offset);
62605
+ }
62606
+ const start = range.start ?? 0;
62607
+ const offset = Math.max(0, start - this.segmentStart);
62608
+ const count = range.count;
62609
+ const end = count === void 0 ? void 0 : offset + count;
62610
+ return this.records.slice(offset, end);
62611
+ }
62600
62612
  return this.records;
62601
62613
  }
62614
+ removeMessagesFrom(records, removedMessages) {
62615
+ for (let i = records.length - 1; i >= 0; i--) {
62616
+ const record = records[i];
62617
+ if (record.type === "message" && removedMessages.has(record.message)) records.splice(i, 1);
62618
+ }
62619
+ }
62602
62620
  };
62603
62621
  //#endregion
62604
62622
  //#region ../../node_modules/.pnpm/js-yaml@4.1.1/node_modules/js-yaml/dist/js-yaml.mjs
@@ -91476,7 +91494,6 @@ var ToolManager = class {
91476
91494
  * derives loop control from the normalized response shape, not from the
91477
91495
  * provider's finish-reason spelling.
91478
91496
  */
91479
- const GENERATE_REQUEST_LOG_CONTEXT = "__kimiRequestLogContext";
91480
91497
  var KosongLLM = class {
91481
91498
  systemPrompt;
91482
91499
  modelName;
@@ -91486,7 +91503,7 @@ var KosongLLM = class {
91486
91503
  completionBudgetConfig;
91487
91504
  constructor(config) {
91488
91505
  this.provider = config.provider;
91489
- this.modelName = config.modelName;
91506
+ this.modelName = config.provider.modelName;
91490
91507
  this.systemPrompt = config.systemPrompt;
91491
91508
  this.capability = config.capability;
91492
91509
  this.generate = config.generate ?? generate;
@@ -91503,7 +91520,7 @@ var KosongLLM = class {
91503
91520
  streamEndedAt = Date.now();
91504
91521
  };
91505
91522
  const markStreamOutput = () => {
91506
- if (firstChunkAt === void 0) firstChunkAt = Date.now();
91523
+ firstChunkAt ??= Date.now();
91507
91524
  };
91508
91525
  const callbacks = buildKosongCallbacks(params, markStreamOutput);
91509
91526
  const effectiveProvider = applyCompletionBudget({
@@ -91511,10 +91528,13 @@ var KosongLLM = class {
91511
91528
  budget: this.completionBudgetConfig,
91512
91529
  capability: this.capability
91513
91530
  });
91514
- const result = await this.generate(effectiveProvider, this.systemPrompt, [...params.tools], params.messages, callbacks, generateOptions(params, {
91531
+ const options = {
91532
+ signal: params.signal,
91515
91533
  onRequestStart: markRequestStart,
91516
- onStreamEnd: markStreamEnd
91517
- }));
91534
+ onStreamEnd: markStreamEnd,
91535
+ requestLogFields: params.requestLogFields
91536
+ };
91537
+ const result = await this.generate(effectiveProvider, this.systemPrompt, [...params.tools], params.messages, callbacks, options);
91518
91538
  if (params.onTextPart !== void 0 || params.onThinkPart !== void 0) {
91519
91539
  for (const part of result.message.content) if (part.type === "text" && params.onTextPart !== void 0) await params.onTextPart(part);
91520
91540
  else if (part.type === "think" && params.onThinkPart !== void 0) await params.onThinkPart(part);
@@ -91538,14 +91558,6 @@ function buildStreamTiming(requestStartedAt, firstChunkAt, streamEndedAt) {
91538
91558
  streamDurationMs: Math.max(0, outputEndedAt - firstChunkAt)
91539
91559
  };
91540
91560
  }
91541
- function generateOptions(params, hooks) {
91542
- return {
91543
- signal: params.signal,
91544
- onRequestStart: hooks.onRequestStart,
91545
- onStreamEnd: hooks.onStreamEnd,
91546
- [GENERATE_REQUEST_LOG_CONTEXT]: params.requestLogContext
91547
- };
91548
- }
91549
91561
  function buildKosongCallbacks(params, markStreamOutput) {
91550
91562
  const toolCallIdentities = /* @__PURE__ */ new Map();
91551
91563
  const pendingIndexedToolCallDeltas = /* @__PURE__ */ new Map();
@@ -91674,6 +91686,64 @@ function totalUsage(byModel) {
91674
91686
  return total;
91675
91687
  }
91676
91688
  //#endregion
91689
+ //#region ../agent-core/src/agent/llm-request-logger.ts
91690
+ var LlmRequestLogger = class {
91691
+ log;
91692
+ lastConfigLogSignature;
91693
+ constructor(log) {
91694
+ this.log = log;
91695
+ }
91696
+ logRequest(input) {
91697
+ const { provider, modelAlias, systemPrompt, tools, messages, fields } = input;
91698
+ const requestLogFields = fields ?? {};
91699
+ const config = {
91700
+ provider: provider.name,
91701
+ model: provider.modelName,
91702
+ modelAlias,
91703
+ thinkingEffort: provider.thinkingEffort ?? void 0,
91704
+ systemPromptChars: systemPrompt.length,
91705
+ toolCount: tools.length
91706
+ };
91707
+ const signature = JSON.stringify({
91708
+ ...config,
91709
+ systemPromptHash: fingerprint(systemPrompt),
91710
+ toolsHash: fingerprint(JSON.stringify(toolSignature(tools)))
91711
+ });
91712
+ if (signature !== this.lastConfigLogSignature) {
91713
+ this.lastConfigLogSignature = signature;
91714
+ this.log.info("llm config", {
91715
+ ...requestLogFields,
91716
+ ...config
91717
+ });
91718
+ }
91719
+ const partialMessageCount = messages.filter((message) => message.partial === true).length;
91720
+ const requestFields = { ...requestLogFields };
91721
+ if (partialMessageCount > 0) requestFields.partialMessageCount = partialMessageCount;
91722
+ this.log.info("llm request", requestFields);
91723
+ }
91724
+ };
91725
+ function splitGenerateOptions(options) {
91726
+ if (options === void 0) return {
91727
+ requestLogFields: void 0,
91728
+ generateOptions: void 0
91729
+ };
91730
+ const { requestLogFields, ...generateOptions } = options;
91731
+ return {
91732
+ requestLogFields,
91733
+ generateOptions
91734
+ };
91735
+ }
91736
+ function toolSignature(tools) {
91737
+ return tools.map(({ name, description, parameters }) => ({
91738
+ name,
91739
+ description,
91740
+ parameters
91741
+ }));
91742
+ }
91743
+ function fingerprint(content) {
91744
+ return createHash("sha256").update(content).digest("hex");
91745
+ }
91746
+ //#endregion
91677
91747
  //#region ../agent-core/src/agent/index.ts
91678
91748
  var Agent$1 = class {
91679
91749
  type;
@@ -91694,6 +91764,7 @@ var Agent$1 = class {
91694
91764
  log;
91695
91765
  telemetry;
91696
91766
  experimentalFlags;
91767
+ llmRequestLogger;
91697
91768
  blobStore;
91698
91769
  records;
91699
91770
  fullCompaction;
@@ -91712,7 +91783,6 @@ var Agent$1 = class {
91712
91783
  cron;
91713
91784
  goal;
91714
91785
  replayBuilder;
91715
- lastLlmConfigLogSignature;
91716
91786
  constructor(options) {
91717
91787
  this.type = options.type ?? "main";
91718
91788
  this._kaos = options.kaos;
@@ -91729,6 +91799,7 @@ var Agent$1 = class {
91729
91799
  this.log = options.log ?? log;
91730
91800
  this.telemetry = options.telemetry ?? noopTelemetryClient;
91731
91801
  this.experimentalFlags = options.experimentalFlags ?? new FlagResolver();
91802
+ this.llmRequestLogger = new LlmRequestLogger(this.log);
91732
91803
  this.blobStore = options.homedir ? new BlobStore({ blobsDir: join$1(options.homedir, "blobs") }) : void 0;
91733
91804
  this.records = new AgentRecords(this, options.persistence ?? (options.homedir ? new FileSystemAgentRecordPersistence(join$1(options.homedir, "wire.jsonl"), {
91734
91805
  onError: (error) => {
@@ -91751,35 +91822,38 @@ var Agent$1 = class {
91751
91822
  this.background = new BackgroundManager(this, this.homedir === void 0 ? void 0 : new BackgroundTaskPersistence(this.homedir));
91752
91823
  this.cron = this.type === "sub" ? null : new CronManager(this);
91753
91824
  this.goal = new GoalMode(this);
91754
- this.replayBuilder = new ReplayBuilder(this);
91825
+ this.replayBuilder = new ReplayBuilder(this, options.replay);
91755
91826
  }
91756
91827
  setKaos(kaos) {
91757
91828
  this._kaos = kaos;
91758
91829
  }
91759
91830
  get generate() {
91760
91831
  return async (provider, systemPrompt, tools, history, callbacks, options) => {
91761
- if (options?.auth !== void 0) {
91762
- this.logLlmRequest(provider, systemPrompt, tools, history, options);
91763
- return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, options);
91764
- }
91832
+ const { requestLogFields, generateOptions } = splitGenerateOptions(options);
91765
91833
  const modelAlias = this.config.modelAlias;
91834
+ const run = (requestOptions) => {
91835
+ this.llmRequestLogger.logRequest({
91836
+ provider,
91837
+ modelAlias,
91838
+ systemPrompt,
91839
+ tools,
91840
+ messages: history,
91841
+ fields: requestLogFields
91842
+ });
91843
+ return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, requestOptions);
91844
+ };
91845
+ if (generateOptions?.auth !== void 0) return run(generateOptions);
91766
91846
  const withAuth = modelAlias === void 0 ? void 0 : this.modelProvider?.resolveAuth?.(modelAlias, { log: this.log });
91767
- if (withAuth === void 0) {
91768
- this.logLlmRequest(provider, systemPrompt, tools, history, options);
91769
- return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, options);
91770
- }
91847
+ if (withAuth === void 0) return run(generateOptions);
91771
91848
  return withAuth((auth) => {
91772
- const requestOptions = {
91773
- ...options,
91849
+ return run({
91850
+ ...generateOptions,
91774
91851
  auth
91775
- };
91776
- this.logLlmRequest(provider, systemPrompt, tools, history, requestOptions);
91777
- return this.rawGenerate(provider, systemPrompt, tools, history, callbacks, requestOptions);
91852
+ });
91778
91853
  });
91779
91854
  };
91780
91855
  }
91781
91856
  get llm() {
91782
- const model = this.config.model;
91783
91857
  const provider = this.config.provider;
91784
91858
  const loopControl = this.kimiConfig?.loopControl;
91785
91859
  const completionBudgetConfig = resolveCompletionBudget({
@@ -91788,34 +91862,12 @@ var Agent$1 = class {
91788
91862
  });
91789
91863
  return new KosongLLM({
91790
91864
  provider,
91791
- modelName: model,
91792
91865
  systemPrompt: this.config.systemPrompt,
91793
91866
  capability: this.config.modelCapabilities,
91794
91867
  generate: this.generate,
91795
91868
  completionBudgetConfig
91796
91869
  });
91797
91870
  }
91798
- logLlmRequest(provider, systemPrompt, tools, history, options) {
91799
- const context = buildLlmRequestContext(options);
91800
- const configMetadata = buildLlmConfigMetadata(provider, this.config.modelAlias, systemPrompt, tools);
91801
- this.logLlmConfigIfChanged(context, configMetadata, buildLlmConfigSignature(configMetadata, systemPrompt, tools));
91802
- let partialMessageCount = 0;
91803
- for (const message of history) if (message.partial === true) partialMessageCount += 1;
91804
- const requestMetadata = {};
91805
- if (partialMessageCount > 0) requestMetadata.partialMessageCount = partialMessageCount;
91806
- this.log.info("llm request", {
91807
- ...context,
91808
- ...requestMetadata
91809
- });
91810
- }
91811
- logLlmConfigIfChanged(context, metadata, signature) {
91812
- if (signature === this.lastLlmConfigLogSignature) return;
91813
- this.lastLlmConfigLogSignature = signature;
91814
- this.log.info("llm config", {
91815
- ...context,
91816
- ...metadata
91817
- });
91818
- }
91819
91871
  useProfile(profile, context) {
91820
91872
  const systemPrompt = profile.systemPrompt({
91821
91873
  osEnv: this.kaos.osEnv,
@@ -91830,8 +91882,8 @@ var Agent$1 = class {
91830
91882
  });
91831
91883
  this.tools.setActiveTools(profile.tools);
91832
91884
  }
91833
- async resume() {
91834
- const result = await this.records.replay();
91885
+ async resume(options) {
91886
+ const result = await this.records.replay(options);
91835
91887
  try {
91836
91888
  this.replayBuilder.postRestoring = true;
91837
91889
  this.goal.normalizeAfterReplay();
@@ -91988,41 +92040,6 @@ var Agent$1 = class {
91988
92040
  });
91989
92041
  }
91990
92042
  };
91991
- function buildLlmRequestContext(options) {
91992
- const context = requestLogContext(options);
91993
- if (context === void 0) return {};
91994
- const fields = { turnStep: context.turnId === void 0 || context.step === void 0 ? void 0 : `${context.turnId}.${String(context.step)}` };
91995
- if (context.attempt !== void 0 && context.maxAttempts !== void 0 && context.attempt > 1) fields.attempt = `${String(context.attempt)}/${String(context.maxAttempts)}`;
91996
- return fields;
91997
- }
91998
- function buildLlmConfigMetadata(provider, modelAlias, systemPrompt, tools) {
91999
- return {
92000
- provider: provider.name,
92001
- model: provider.modelName,
92002
- modelAlias,
92003
- thinkingEffort: provider.thinkingEffort ?? void 0,
92004
- systemPromptChars: systemPrompt.length,
92005
- toolCount: tools.length
92006
- };
92007
- }
92008
- function buildLlmConfigSignature(metadata, systemPrompt, tools) {
92009
- const toolsForSignature = tools.map(({ name, description, parameters }) => ({
92010
- name,
92011
- description,
92012
- parameters
92013
- }));
92014
- return JSON.stringify({
92015
- ...metadata,
92016
- systemPromptHash: fingerprint(systemPrompt),
92017
- toolsHash: fingerprint(JSON.stringify(toolsForSignature))
92018
- });
92019
- }
92020
- function fingerprint(content) {
92021
- return createHash("sha256").update(content).digest("hex");
92022
- }
92023
- function requestLogContext(options) {
92024
- return options?.[GENERATE_REQUEST_LOG_CONTEXT];
92025
- }
92026
92043
  //#endregion
92027
92044
  //#region ../agent-core/src/rpc/types.ts
92028
92045
  function proxyWithExtraPayload(methods, extraPayload) {
@@ -122945,7 +122962,11 @@ var Session$1 = class {
122945
122962
  defaultValue: false,
122946
122963
  parseEnv: parseBooleanEnv
122947
122964
  })) return;
122948
- await Promise.all(Array.from(this.readyAgents(), (agent) => agent.background.stopAll("Session closed")));
122965
+ await Promise.all(Array.from(this.readyAgents(), async (agent) => {
122966
+ const activeTasks = agent.background.list(true);
122967
+ await Promise.all(activeTasks.map((task) => agent.background.suppressTerminalNotification(task.taskId)));
122968
+ await agent.background.stopAll("Session closed");
122969
+ }));
122949
122970
  }
122950
122971
  async createAgent(config, options = {}) {
122951
122972
  await this.skillsReady;
@@ -138706,6 +138727,7 @@ var BufferedReadable = class extends Readable {
138706
138727
  this._source.off("end", this._onEnd);
138707
138728
  this._source.off("close", this._onClose);
138708
138729
  this._source.off("error", this._onError);
138730
+ this._source.destroy();
138709
138731
  callback(error);
138710
138732
  }
138711
138733
  _onData = (chunk) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@botiverse/kimi-code-sdk",
3
- "version": "0.9.4",
4
- "description": "Botiverse repackage of @moonshot-ai/kimi-code-sdk (from kimi-code @moonshot-ai/kimi-code@0.15.0) — built node-sdk bundle for Slock. Mirror of MoonshotAI/kimi-code.",
3
+ "version": "0.16.0",
4
+ "description": "Botiverse repackage of @moonshot-ai/kimi-code-sdk (from kimi-code @moonshot-ai/kimi-code@0.16.0) — built node-sdk bundle for Slock. Mirror of MoonshotAI/kimi-code.",
5
5
  "license": "MIT",
6
6
  "author": "Moonshot AI",
7
7
  "homepage": "https://github.com/botiverse/kimi-code-sdk#readme",
@@ -54,7 +54,7 @@
54
54
  "types": "./dist/index.d.mts",
55
55
  "botiverse": {
56
56
  "upstream": "@moonshot-ai/kimi-code-sdk",
57
- "kimiRelease": "@moonshot-ai/kimi-code@0.15.0",
57
+ "kimiRelease": "@moonshot-ai/kimi-code@0.16.0",
58
58
  "source": "https://github.com/MoonshotAI/kimi-code"
59
59
  }
60
60
  }