MCPcopy Create free account
hub / github.com/betta-tech/byo-coding-agent / Send

Method Send

internal/provider/openai.go:75–126  ·  view source on GitHub ↗
(ctx context.Context, messages []api.Message, tools []api.ToolDef)

Source from the content-addressed store, hash-verified

73}
74
75func (p *OpenAIProvider) Send(ctx context.Context, messages []api.Message, tools []api.ToolDef) (api.Response, error) {
76 p.mu.Lock()
77 model := p.model
78 p.mu.Unlock()
79
80 reqSummary := fmt.Sprintf("→ openai.Send model=%s msgs=%d tools=%d", model, len(messages), len(tools))
81 reqID := debug.Recordp("provider", debug.LevelInfo, reqSummary, marshalRequestPayload(model, p.system, p.maxTokens, messages, tools))
82 start := time.Now()
83 resp, err := p.client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
84 Model: shared.ChatModel(model),
85 Messages: p.toMessages(messages),
86 Tools: p.toTools(tools),
87 MaxCompletionTokens: param.NewOpt(p.maxTokens),
88 })
89 elapsed := time.Since(start).Round(time.Millisecond)
90 if err != nil {
91 debug.Recordfc(reqID, "provider", debug.LevelError, "← openai.Send error (%v): %v", elapsed, err)
92 return api.Response{}, err
93 }
94 if len(resp.Choices) == 0 {
95 return api.Response{StopReason: api.StopOther}, nil
96 }
97 choice := resp.Choices[0]
98
99 out := api.Response{StopReason: fromFinishReason(choice.FinishReason)}
100 if choice.Message.Content != "" {
101 out.Content = append(out.Content, api.Block{Type: api.BlockText, Text: choice.Message.Content})
102 }
103 for _, tc := range choice.Message.ToolCalls {
104 out.Content = append(out.Content, api.Block{
105 Type: api.BlockToolUse,
106 ToolUseID: tc.ID,
107 ToolName: tc.Function.Name,
108 ToolInput: tc.Function.Arguments,
109 })
110 }
111
112 out.Usage = api.Usage{
113 InputTokens: int(resp.Usage.PromptTokens),
114 OutputTokens: int(resp.Usage.CompletionTokens),
115 CacheReadTokens: int(resp.Usage.PromptTokensDetails.CachedTokens),
116 // OpenAI doesn't expose cache-creation separately; cached_tokens is
117 // the only cache figure they return, and it maps to cache reads.
118 }
119 p.mu.Lock()
120 p.total = p.total.Add(out.Usage)
121 p.mu.Unlock()
122 respSummary := fmt.Sprintf("← openai.Send (%v in=%d out=%d cache=%d stop=%s)",
123 elapsed, out.Usage.InputTokens, out.Usage.OutputTokens, out.Usage.CacheReadTokens, out.StopReason)
124 debug.Recordpc(reqID, "provider", debug.LevelInfo, respSummary, marshalResponsePayload(out, elapsed))
125 return out, nil
126}
127
128// toMessages translates our generic Message slice into the OpenAI chat-message
129// shape. Two notable splits:

Callers

nothing calls this directly

Calls 9

toMessagesMethod · 0.95
toToolsMethod · 0.95
RecordpFunction · 0.92
RecordfcFunction · 0.92
RecordpcFunction · 0.92
marshalRequestPayloadFunction · 0.85
fromFinishReasonFunction · 0.85
marshalResponsePayloadFunction · 0.85
AddMethod · 0.80

Tested by

no test coverage detected