extractModelThoughts extracts model thoughts from response output items. It captures both reasoning summary items and commentary messages (message output items with "phase": "commentary") as model thoughts.
(response *responses.Response)
| 271 | // It captures both reasoning summary items and commentary messages (message |
| 272 | // output items with "phase": "commentary") as model thoughts. |
| 273 | func (*responsesInterceptionBase) extractModelThoughts(response *responses.Response) []*recorder.ModelThoughtRecord { |
| 274 | if response == nil { |
| 275 | return nil |
| 276 | } |
| 277 | |
| 278 | var thoughts []*recorder.ModelThoughtRecord |
| 279 | for _, item := range response.Output { |
| 280 | switch item.Type { |
| 281 | case string(constant.ValueOf[constant.Reasoning]()): |
| 282 | reasoning := item.AsReasoning() |
| 283 | for _, summary := range reasoning.Summary { |
| 284 | if summary.Text == "" { |
| 285 | continue |
| 286 | } |
| 287 | thoughts = append(thoughts, &recorder.ModelThoughtRecord{ |
| 288 | Content: summary.Text, |
| 289 | Metadata: recorder.Metadata{"source": recorder.ThoughtSourceReasoningSummary}, |
| 290 | }) |
| 291 | } |
| 292 | |
| 293 | case string(constant.ValueOf[constant.Message]()): |
| 294 | // The API sometimes returns commentary messages instead of reasoning |
| 295 | // summaries. These are assistant message output items with "phase": "commentary". |
| 296 | // The SDK doesn't expose a Phase field, so we extract it from raw JSON. |
| 297 | // TODO: revisit when the OpenAI SDK adds a proper Phase field. |
| 298 | raw := item.RawJSON() |
| 299 | if gjson.Get(raw, "role").String() != string(constant.ValueOf[constant.Assistant]()) || |
| 300 | gjson.Get(raw, "phase").String() != "commentary" { |
| 301 | continue |
| 302 | } |
| 303 | msg := item.AsMessage() |
| 304 | for _, part := range msg.Content { |
| 305 | if part.Type != string(constant.ValueOf[constant.OutputText]()) { |
| 306 | continue |
| 307 | } |
| 308 | if part.Text == "" { |
| 309 | continue |
| 310 | } |
| 311 | thoughts = append(thoughts, &recorder.ModelThoughtRecord{ |
| 312 | Content: part.Text, |
| 313 | Metadata: recorder.Metadata{"source": recorder.ThoughtSourceCommentary}, |
| 314 | }) |
| 315 | } |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | return thoughts |
| 320 | } |
| 321 | |
| 322 | func (i *responsesInterceptionBase) hasInjectableTools() bool { |
| 323 | return i.mcpProxy != nil && len(i.mcpProxy.ListTools()) > 0 |
no test coverage detected