feat: OpenAI 兼容端点完整实现 + reasoning_content 输出通道

- StageContext 新增 ReasoningContent + TokenUsage 字段
- emitResponse 将 reasoning_content / usage 传入 Payload
- /v1/chat/completions:
  - 非流式返回 reasoning_content + token_usage
  - 流式 (stream=true) SSE 分块返回 reasoning/content/finish chunk
  - token_usage 来自精确 LLM 回报而非估算
This commit is contained in:
root
2026-07-03 20:49:43 +08:00
parent 239a22899b
commit d4956c23f0
3 changed files with 129 additions and 22 deletions

View File

@ -358,17 +358,25 @@ func (a *Agent) emitResponse(evt *agentIO.InputEvent, response string) {
ch = evt.Source
}
a.io.EmitOutputTo(evt.Source, ch, "text", map[string]interface{}{
payload := map[string]interface{}{
"content": response,
"request_id": evt.RequestID,
})
}
if stageCtx.ReasoningContent != "" {
payload["reasoning_content"] = stageCtx.ReasoningContent
}
if stageCtx.TokenUsage != nil {
payload["usage"] = stageCtx.TokenUsage
}
a.io.EmitOutputTo(evt.Source, ch, "text", payload)
if evt.ResponseCh != nil {
evt.ResponseCh <- &agentIO.OutputEvent{
RequestID: evt.RequestID,
Target: evt.Source,
Type: "text",
Payload: map[string]interface{}{"content": response},
Payload: payload,
Done: true,
OutputChannel: ch,
}
@ -459,6 +467,12 @@ func (a *Agent) process(input string, stageCtx *sdk.StageContext) (response stri
// === Stage: post_action — LLM 返回,插件可审查/修改 ===
stageCtx.LLMText = resp.Content
stageCtx.ReasoningContent = resp.ReasoningContent
stageCtx.TokenUsage = map[string]int{
"prompt_tokens": resp.TokenUsage.Prompt,
"completion_tokens": resp.TokenUsage.Completion,
"total_tokens": resp.TokenUsage.Total,
}
stageCtx.ToolCalls = convertToolCalls(resp.ToolCalls)
if a.runStage(sdk.StagePostAction, stageCtx) {
return *stageCtx.Response, toolsUsed, nil