From 3df54e5fbf2dfec6faf186964727051c6d21f84d Mon Sep 17 00:00:00 2001 From: qer Date: Fri, 29 May 2026 12:41:40 +0800 Subject: [PATCH] refactor(agent-core): slim llm request log line Merge turnId/step into a single `turnStep` field ("0.1") and attempt/maxAttempts into `attempt` ("2/3"), and drop the messageCount/toolCallCount fields. The per-request `llm request` line goes from up to 8 fields down to ~3; the `llm config` line (including thinkingEffort, logged for all providers) is unchanged. --- .changeset/slim-llm-request-log.md | 6 ++ packages/agent-core/src/agent/index.ts | 62 +++++++------------ packages/agent-core/src/loop/retry.ts | 6 +- packages/agent-core/test/agent/turn.test.ts | 20 +++--- .../test/loop/error-paths.e2e.test.ts | 6 +- 5 files changed, 42 insertions(+), 58 deletions(-) create mode 100644 .changeset/slim-llm-request-log.md diff --git a/.changeset/slim-llm-request-log.md b/.changeset/slim-llm-request-log.md new file mode 100644 index 0000000000..fe5ed7348f --- /dev/null +++ b/.changeset/slim-llm-request-log.md @@ -0,0 +1,6 @@ +--- +"@moonshot-ai/agent-core": patch +"@moonshot-ai/kimi-code": patch +--- + +Slim the LLM diagnostic logs with fewer, more compact fields. diff --git a/packages/agent-core/src/agent/index.ts b/packages/agent-core/src/agent/index.ts index 6151c7bad2..d7c4124706 100644 --- a/packages/agent-core/src/agent/index.ts +++ b/packages/agent-core/src/agent/index.ts @@ -221,9 +221,23 @@ export class Agent { configMetadata, buildLlmConfigSignature(configMetadata, systemPrompt, tools), ); + + let partialMessageCount = 0; + for (const message of history) { + if (message.partial === true) partialMessageCount += 1; + } + const requestMetadata: LlmRequestMetadata = { + estimatedInputTokens: + estimateTokens(systemPrompt) + + estimateTokensForMessages(history) + + estimateTokensForTools(tools), + }; + if (partialMessageCount > 0) { + requestMetadata.partialMessageCount = partialMessageCount; + } this.log.info('llm request', { ...context, - ...buildLlmRequestMetadata(systemPrompt, tools, history), + ...requestMetadata, }); } @@ -414,16 +428,12 @@ export class Agent { } interface LlmRequestContextFields { - turnId?: string; - step?: number; - attempt?: number; - maxAttempts?: number; + turnStep?: string; + attempt?: string; } interface LlmRequestMetadata { estimatedInputTokens: number; - messageCount: number; - toolCallCount: number; partialMessageCount?: number; } @@ -447,49 +457,21 @@ function buildLlmRequestContext(options: Parameters[5]): LlmReq if (context === undefined) return {}; const fields: LlmRequestContextFields = { - turnId: context.turnId, - step: context.step, + turnStep: + context.turnId === undefined || context.step === undefined + ? undefined + : `${context.turnId}.${String(context.step)}`, }; if ( context.attempt !== undefined && context.maxAttempts !== undefined && context.attempt > 1 ) { - fields.attempt = context.attempt; - fields.maxAttempts = context.maxAttempts; + fields.attempt = `${String(context.attempt)}/${String(context.maxAttempts)}`; } return fields; } -function buildLlmRequestMetadata( - systemPrompt: string, - tools: readonly Tool[], - history: readonly Message[], -): LlmRequestMetadata { - let toolCallCount = 0; - let partialMessageCount = 0; - - for (const message of history) { - if (message.partial === true) partialMessageCount += 1; - toolCallCount += message.toolCalls.length; - } - - const estimatedInputTokens = - estimateTokens(systemPrompt) + - estimateTokensForMessages(history) + - estimateTokensForTools(tools); - - const metadata: LlmRequestMetadata = { - estimatedInputTokens, - messageCount: history.length, - toolCallCount, - }; - if (partialMessageCount > 0) { - metadata.partialMessageCount = partialMessageCount; - } - return metadata; -} - function buildLlmConfigMetadata( provider: ChatProvider, modelAlias: string | undefined, diff --git a/packages/agent-core/src/loop/retry.ts b/packages/agent-core/src/loop/retry.ts index eba9247bd5..b47d082975 100644 --- a/packages/agent-core/src/loop/retry.ts +++ b/packages/agent-core/src/loop/retry.ts @@ -75,10 +75,8 @@ function logRequestFailure( ): void { if (isAbortError(error) || input.params.signal.aborted) return; input.log?.warn('llm request failed', { - turnId: input.turnId, - step: input.currentStep, - attempt, - maxAttempts, + turnStep: `${input.turnId}.${String(input.currentStep)}`, + attempt: `${String(attempt)}/${String(maxAttempts)}`, model: input.llm.modelName, ...retryErrorFields(error), }); diff --git a/packages/agent-core/test/agent/turn.test.ts b/packages/agent-core/test/agent/turn.test.ts index f7b6549720..2c8328bb62 100644 --- a/packages/agent-core/test/agent/turn.test.ts +++ b/packages/agent-core/test/agent/turn.test.ts @@ -718,8 +718,7 @@ describe('Agent turn flow', () => { expect(configLogs).toHaveLength(1); const configPayload = configLogs[0]?.payload as Record; expect(configPayload).toMatchObject({ - turnId: '0', - step: 1, + turnStep: '0.1', provider: 'kimi', model: 'mock-model', modelAlias: 'mock-model', @@ -731,12 +730,11 @@ describe('Agent turn flow', () => { expect(requestLogs).toHaveLength(1); const payload = requestLogs[0]?.payload as Record; expect(payload).toMatchObject({ - turnId: '0', - step: 1, - messageCount: 1, - toolCallCount: 0, + turnStep: '0.1', }); expect(payload['estimatedInputTokens']).toEqual(expect.any(Number)); + expect(payload).not.toHaveProperty('turnId'); + expect(payload).not.toHaveProperty('step'); expect(payload).not.toHaveProperty('attempt'); expect(payload).not.toHaveProperty('maxAttempts'); expect(payload).not.toHaveProperty('stepUuid'); @@ -746,6 +744,8 @@ describe('Agent turn flow', () => { expect(payload).not.toHaveProperty('thinkingEffort'); expect(payload).not.toHaveProperty('systemPromptChars'); expect(payload).not.toHaveProperty('partialMessageCount'); + expect(payload).not.toHaveProperty('messageCount'); + expect(payload).not.toHaveProperty('toolCallCount'); expect(payload).not.toHaveProperty('toolCount'); expect(payload).not.toHaveProperty('systemPromptHash'); expect(payload).not.toHaveProperty('toolsHash'); @@ -1152,10 +1152,10 @@ describe('Agent turn flow', () => { }), ); const requestLogs = entries.filter((entry) => entry.message === 'llm request'); - expect(requestLogs.map((entry) => entry.payload)).toEqual([ - expect.not.objectContaining({ attempt: expect.any(Number), maxAttempts: expect.any(Number) }), - expect.objectContaining({ attempt: 2, maxAttempts: 3 }), - ]); + const payloads = requestLogs.map((entry) => entry.payload as Record); + expect(payloads[0]).toMatchObject({ turnStep: '0.1' }); + expect(payloads[0]).not.toHaveProperty('attempt'); + expect(payloads[1]).toMatchObject({ turnStep: '0.1', attempt: '2/3' }); }); it('force-refreshes OAuth credentials on video upload 401 and falls back to login_required when replay 401', async () => { diff --git a/packages/agent-core/test/loop/error-paths.e2e.test.ts b/packages/agent-core/test/loop/error-paths.e2e.test.ts index 5a3fb2a380..66bd88cb4b 100644 --- a/packages/agent-core/test/loop/error-paths.e2e.test.ts +++ b/packages/agent-core/test/loop/error-paths.e2e.test.ts @@ -57,10 +57,8 @@ describe('runTurn — error paths', () => { level: 'warn', message: 'llm request failed', payload: { - turnId: 'turn-1', - step: 1, - attempt: 1, - maxAttempts: 3, + turnStep: 'turn-1.1', + attempt: '1/3', model: 'fake-model', errorName: 'Error', errorMessage: 'upstream blew up',