Add reasoning effort

This commit is contained in:
dwrz
2026-07-07 15:14:07 +00:00
parent c730ecdc22
commit 27fa702071
9 changed files with 192 additions and 122 deletions

View File

@@ -25,6 +25,15 @@ type CompletionsResult struct {
Timings *Timings
}
// CompletionsParams holds parameters for Completions and CompletionsStream.
type CompletionsParams struct {
Model string
SystemMessage string
MaxIterations int
Messages []Message
ThinkingBudgetTokens *int
}
// Completions sends messages to the LLM using the specified model.
// If systemMessage is non-empty, it overrides the configured system message.
// maxIterations caps the number of agent loop iterations.
@@ -32,15 +41,14 @@ type CompletionsResult struct {
// Returns all messages generated during the completions request, including
// tool calls and tool results, along with usage and timings from the final response.
func (c *Client) Completions(
ctx context.Context,
model string,
systemMessage string,
maxIterations int,
messages []Message,
ctx context.Context, p CompletionsParams,
) (*CompletionsResult, error) {
ctx, cancel := context.WithTimeout(ctx, c.timeout)
defer cancel()
model, systemMessage, maxIterations, messages, thinkingBudgetTokens :=
p.Model, p.SystemMessage, p.MaxIterations, p.Messages, p.ThinkingBudgetTokens
// Use request system message if provided, config default otherwise.
smsg := c.systemMessage
if systemMessage != "" {
@@ -68,7 +76,7 @@ func (c *Client) Completions(
var finalUsage *Usage
var finalTimings *Timings
for i := 0; maxIterations == 0 || i < maxIterations; i++ {
cr, err := c.completions(ctx, model, messages)
cr, err := c.completions(ctx, model, thinkingBudgetTokens, messages)
if err != nil {
return nil, fmt.Errorf("completions: %w", err)
}
@@ -106,12 +114,18 @@ func (c *Client) Completions(
// completions sends a single non-streaming request and returns the
// full API response.
func (c *Client) completions(
ctx context.Context, model string, messages []Message,
ctx context.Context, model string, thinkingBudgetTokens *int, messages []Message,
) (*ChatResponse, error) {
kwargs := map[string]any{}
if thinkingBudgetTokens != nil {
kwargs["enable_thinking"] = *thinkingBudgetTokens != 0
}
body, err := json.Marshal(ChatRequest{
Model: model,
Messages: messages,
Tools: c.tools,
Model: model,
Messages: messages,
Tools: c.tools,
ThinkingBudgetTokens: thinkingBudgetTokens,
ChatTemplateKWARGS: kwargs,
})
if err != nil {
return nil, fmt.Errorf(
@@ -232,17 +246,15 @@ const (
// means unlimited (no cap).
// Returns ErrMaxIterations if the iteration limit is exceeded.
func (c *Client) CompletionsStream(
ctx context.Context,
model string,
systemMessage string,
maxIterations int,
messages []Message,
events chan<- StreamEvent,
ctx context.Context, p CompletionsParams, events chan<- StreamEvent,
) error {
defer close(events)
ctx, cancel := context.WithTimeout(ctx, c.timeout)
defer cancel()
model, systemMessage, maxIterations, messages, thinkingBudgetTokens :=
p.Model, p.SystemMessage, p.MaxIterations, p.Messages, p.ThinkingBudgetTokens
// Use request system message if provided, config default otherwise.
smsg := c.systemMessage
if systemMessage != "" {
@@ -265,7 +277,7 @@ func (c *Client) CompletionsStream(
// Loop for tool calls. maxIterations == 0 means unlimited.
for i := 0; maxIterations == 0 || i < maxIterations; i++ {
choices, err := c.completionsStream(ctx, messages, model, events)
choices, err := c.completionsStream(ctx, messages, model, thinkingBudgetTokens, events)
if err != nil {
return fmt.Errorf("completions stream: %w", err)
}
@@ -304,13 +316,19 @@ type streamAccum struct {
// response, and returns all assistant messages from the response choices.
// Sends each message to the events channel. Usage and timings are included
// on the done event for the last message.
func (c *Client) completionsStream(ctx context.Context, messages []Message, model string, events chan<- StreamEvent) ([]Message, error) {
func (c *Client) completionsStream(ctx context.Context, messages []Message, model string, thinkingBudgetTokens *int, events chan<- StreamEvent) ([]Message, error) {
kwargs := map[string]any{}
if thinkingBudgetTokens != nil {
kwargs["enable_thinking"] = *thinkingBudgetTokens != 0
}
body, err := json.Marshal(ChatRequest{
Model: model,
Messages: messages,
Stream: true,
Tools: c.tools,
StreamOptions: &StreamOptions{IncludeUsage: true},
Model: model,
Messages: messages,
Stream: true,
Tools: c.tools,
ThinkingBudgetTokens: thinkingBudgetTokens,
ChatTemplateKWARGS: kwargs,
StreamOptions: &StreamOptions{IncludeUsage: true},
})
if err != nil {
return nil, fmt.Errorf(