feat(ai): add DtpLog logging of all OpenAI API responses
- Fix broken chunkCount reference in generate() usage chunk log
- Add generate() complete log with usage, response/thinking lengths
- Add readStreamingChatCompletion() usage chunk log (full chunk dump)
- Add readStreamingChatCompletion() iteration complete log
- Add readNonStreamingChatCompletion() full response dump
- Add chat() streaming iteration usage log
- Add chat() non-streaming fallback usage log
- Add chat() final response stats log
All logs use info level and 'OpenAI {method}: {event}' naming for
easy grep/filtering. Streaming chunks use JSON.parse(JSON.stringify())
to serialize the full OpenAI SDK response objects.
This commit is contained in:
parent
2483161663
commit
51b3013659
@ -242,6 +242,11 @@ export class OpenAiApi extends AiApi {
|
||||
promptTokens: chunk.usage.prompt_tokens,
|
||||
completionTokens: chunk.usage.completion_tokens,
|
||||
};
|
||||
// LOG: dump entire usage chunk from OpenAI generate streaming response
|
||||
this.log.info("OpenAI generate: streaming chunk with usage", {
|
||||
usage: JSON.parse(JSON.stringify(chunk.usage)),
|
||||
chunk: JSON.parse(JSON.stringify(chunk)),
|
||||
});
|
||||
}
|
||||
|
||||
const delta = chunk.choices[0]?.delta;
|
||||
@ -270,6 +275,14 @@ export class OpenAiApi extends AiApi {
|
||||
const endTime = Date.now();
|
||||
const durationMs = endTime - startTime;
|
||||
|
||||
// LOG: dump final usage and accumulated stats from generate()
|
||||
this.log.info("OpenAI generate: complete", {
|
||||
usage,
|
||||
responseLength: accumulatedResponse.length,
|
||||
thinkingLength: accumulatedThinking.length,
|
||||
durationMs,
|
||||
});
|
||||
|
||||
return {
|
||||
done: true,
|
||||
response: accumulatedResponse,
|
||||
@ -320,6 +333,12 @@ export class OpenAiApi extends AiApi {
|
||||
finishReason: iteration.finishReason,
|
||||
});
|
||||
|
||||
// LOG: dump usage from streaming chat iteration
|
||||
this.log.info("OpenAI chat: streaming iteration usage", {
|
||||
usage: iteration.usage,
|
||||
finishReason: iteration.finishReason,
|
||||
});
|
||||
|
||||
if (this.isEmptyIteration(iteration)) {
|
||||
iteration = await this.readNonStreamingChatCompletion(model, messages, tools, options.signal);
|
||||
if (streamCallback && iteration.response) {
|
||||
@ -331,6 +350,11 @@ export class OpenAiApi extends AiApi {
|
||||
toolCallCount: iteration.toolCalls.length,
|
||||
finishReason: iteration.finishReason,
|
||||
});
|
||||
// LOG: dump usage from non-streaming fallback
|
||||
this.log.info("OpenAI chat: non-streaming fallback usage", {
|
||||
usage: iteration.usage,
|
||||
finishReason: iteration.finishReason,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.isEmptyIteration(iteration)) {
|
||||
@ -351,6 +375,12 @@ export class OpenAiApi extends AiApi {
|
||||
toolCalls: iteration.toolCalls.length > 0 ? iteration.toolCalls : undefined,
|
||||
stats: this.buildStats(startTime, iteration.usage),
|
||||
};
|
||||
// LOG: dump final chat response stats
|
||||
this.log.info("OpenAI chat: final response", {
|
||||
usage: iteration.usage,
|
||||
stats: finalResponse.stats,
|
||||
finishReason: iteration.finishReason,
|
||||
});
|
||||
this.assertNonEmptyChatResponse(finalResponse);
|
||||
return finalResponse;
|
||||
}
|
||||
@ -455,6 +485,11 @@ export class OpenAiApi extends AiApi {
|
||||
promptTokens: chunk.usage.prompt_tokens,
|
||||
completionTokens: chunk.usage.completion_tokens,
|
||||
};
|
||||
// LOG: dump entire usage chunk from OpenAI chat streaming response
|
||||
this.log.info("OpenAI chat stream: streaming chunk with usage", {
|
||||
usage: JSON.parse(JSON.stringify(chunk.usage)),
|
||||
chunk: JSON.parse(JSON.stringify(chunk)),
|
||||
});
|
||||
}
|
||||
|
||||
const delta = chunk.choices[0]?.delta;
|
||||
@ -481,6 +516,18 @@ export class OpenAiApi extends AiApi {
|
||||
}
|
||||
}
|
||||
|
||||
// LOG: dump final streaming chat completion iteration result
|
||||
this.log.info("OpenAI chat stream: iteration complete", {
|
||||
chunkCount,
|
||||
contentDeltaCount,
|
||||
toolDeltaCount,
|
||||
finishReason,
|
||||
usage,
|
||||
responseLength: content.length,
|
||||
thinkingLength: thinking.length,
|
||||
toolCallCount: toolCallMap.size,
|
||||
});
|
||||
|
||||
return {
|
||||
response: content,
|
||||
thinking: thinking || undefined,
|
||||
@ -522,6 +569,10 @@ export class OpenAiApi extends AiApi {
|
||||
}
|
||||
: {}),
|
||||
}, signal ? { signal } : undefined);
|
||||
// LOG: dump entire non-streaming response from OpenAI
|
||||
this.log.info("OpenAI chat non-streaming: response", {
|
||||
response: JSON.parse(JSON.stringify(response)),
|
||||
});
|
||||
const choice = response.choices[0];
|
||||
const message = choice?.message;
|
||||
const content = typeof message?.content === "string" ? message.content : "";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user