Documentation
¶
Overview ¶
Package adapters includes multiple adapters to convert one ProviderFoo interface into another one.
Index ¶
- func GenStreamWithToolCallLoop(ctx context.Context, p genai.Provider, msgs genai.Messages, ...) (iter.Seq[genai.Reply], func() (genai.Messages, genai.Usage, error))
- func GenSyncWithToolCallLoop(ctx context.Context, p genai.Provider, msgs genai.Messages, ...) (genai.Messages, genai.Usage, error)
- func WrapReasoning(c genai.Provider) genai.Provider
- type ProviderAppend
- func (c *ProviderAppend) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
- func (c *ProviderAppend) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
- func (c *ProviderAppend) Unwrap() genai.Provider
- type ProviderReasoning
- func (c *ProviderReasoning) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
- func (c *ProviderReasoning) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
- func (c *ProviderReasoning) Unwrap() genai.Provider
- type ProviderUsage
- func (c *ProviderUsage) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
- func (c *ProviderUsage) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
- func (c *ProviderUsage) GetAccumulatedUsage() genai.Usage
- func (c *ProviderUsage) Unwrap() genai.Provider
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenStreamWithToolCallLoop ¶
func GenStreamWithToolCallLoop(ctx context.Context, p genai.Provider, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Messages, genai.Usage, error))
GenStreamWithToolCallLoop runs a conversation loop with an LLM that handles tool calls via streaming until there are no more. It will repeatedly call GenStream(), collect fragments into a complete message, process tool calls with DoToolCalls(), and continue the conversation until the LLM response has no more tool calls.
The function will return early if any error occurs. The returned Messages will include all the messages including the original ones, the LLM's responses, and the tool call result messages.
Warning: If opts.Force == ToolCallRequired, it will be mutated to ToolCallAny after the first tool call.
No need to process the tool calls or accumulate the Reply fragments.
Example ¶
package main
import (
"context"
"log"
"os"
"time"
"github.com/maruel/genai"
"github.com/maruel/genai/adapters"
"github.com/maruel/genai/providers/gemini"
)
func main() {
// Supported by Anthropic, Cerebras, Cloudflare, Cohere, DeepSeek, Gemini, Groq, HuggingFace, Mistral,
// Ollama, OpenAI, TogetherAI.
// Using a free small model for testing.
// See https://ai.google.dev/gemini-api/docs/models/gemini?hl=en
ctx := context.Background()
c, err := gemini.New(ctx, genai.ProviderOptionModel("gemini-2.5-flash"))
if err != nil {
log.Fatal(err)
}
msgs := genai.Messages{genai.NewTextMessage("What season are we in?")}
opts := genai.GenOptionTools{
// GetTodayClockTime returns the current time and day in a format that the LLM
// can understand. It includes the weekend.
Tools: []genai.ToolDef{GetTodayClockTime},
// Force the LLM to do a tool call first.
Force: genai.ToolCallRequired,
}
fragments, finish := adapters.GenStreamWithToolCallLoop(ctx, c, msgs, &opts)
for f := range fragments {
_, _ = os.Stdout.WriteString(f.Text)
}
if _, _, err = finish(); err != nil {
log.Fatal(err)
}
}
var GetTodayClockTime = genai.ToolDef{
Name: "get_today_date_current_clock_time",
Description: "Get the current clock time and today's date.",
Callback: func(ctx context.Context, e *empty) (string, error) {
return time.Now().Format("Monday 2006-01-02 15:04:05"), nil
},
}
type empty struct{}
func GenSyncWithToolCallLoop ¶
func GenSyncWithToolCallLoop(ctx context.Context, p genai.Provider, msgs genai.Messages, opts ...genai.GenOption) (genai.Messages, genai.Usage, error)
GenSyncWithToolCallLoop runs a conversation with the LLM, handling tool calls in a loop until there are no more tool calls.
It calls the provided Provider.GenSync() method, processes any tool calls using Message.DoToolCalls(), and continues the conversation in a loop until the LLM's response has no more tool calls.
Warning: If opts.Force == ToolCallRequired, it will be mutated to ToolCallAny after the first tool call.
It returns the messages to accumulate to the thread. The last message is the LLM's response.
Example ¶
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/maruel/genai"
"github.com/maruel/genai/adapters"
"github.com/maruel/genai/providers/gemini"
)
func main() {
// Supported by Anthropic, Cerebras, Cloudflare, Cohere, DeepSeek, Gemini, Groq, HuggingFace, Mistral,
// Ollama, OpenAI, TogetherAI.
// Using a free small model for testing.
// See https://ai.google.dev/gemini-api/docs/models/gemini?hl=en
ctx := context.Background()
c, err := gemini.New(ctx, genai.ProviderOptionModel("gemini-2.5-flash"))
if err != nil {
log.Fatal(err)
}
msgs := genai.Messages{genai.NewTextMessage("What season are we in?")}
opts := genai.GenOptionTools{
// GetTodayClockTime returns the current time and day in a format that the LLM
// can understand. It includes the weekend.
Tools: []genai.ToolDef{GetTodayClockTime},
// Force the LLM to do a tool call first.
Force: genai.ToolCallRequired,
}
newMsgs, _, err := adapters.GenSyncWithToolCallLoop(ctx, c, msgs, &opts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", newMsgs[len(newMsgs)-1].String())
}
var GetTodayClockTime = genai.ToolDef{
Name: "get_today_date_current_clock_time",
Description: "Get the current clock time and today's date.",
Callback: func(ctx context.Context, e *empty) (string, error) {
return time.Now().Format("Monday 2006-01-02 15:04:05"), nil
},
}
type empty struct{}
Types ¶
type ProviderAppend ¶
ProviderAppend wraps a Provider and appends a Request before processing when the messages end with a user message.
Useful to inject a "/think" for Qwen3 models.
func (*ProviderAppend) GenStream ¶
func (c *ProviderAppend) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
GenStream implements genai.Provider.
func (*ProviderAppend) GenSync ¶
func (c *ProviderAppend) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
GenSync implements genai.Provider.
func (*ProviderAppend) Unwrap ¶
func (c *ProviderAppend) Unwrap() genai.Provider
type ProviderReasoning ¶
type ProviderReasoning struct {
genai.Provider
// ReasoningTokenStart is the start reasoning token. It is often "<think>\n" but there are cases when it can
// be never output, like "qwen-3-235b-a22b-thinking-2507".
ReasoningTokenStart string
// ReasoningTokenEnd is the end reasoning token, where the explicit answer lies after. It is often
// "\n</think>\n".
ReasoningTokenEnd string
// contains filtered or unexported fields
}
ProviderReasoning wraps a Provider and processes its output to extract reasoning blocks.
It looks for content within tags ReasoningTokenStart and ReasoningTokenEnd and places it in Reasoning Content blocks instead of Text.
It requires the starting reasoning tag. Otherwise, the content is assumed to be text. This is necessary for JSON formatted responses.
func (*ProviderReasoning) GenStream ¶
func (c *ProviderReasoning) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
GenStream implements the Provider interface for streaming by delegating to the wrapped provider and processing each fragment to extract reasoning blocks. If no reasoning tags are present, the first part of the message is assumed to be reasoning.
func (*ProviderReasoning) GenSync ¶
func (c *ProviderReasoning) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
GenSync implements the Provider interface by delegating to the wrapped provider and processing the result to extract reasoning blocks.
func (*ProviderReasoning) Unwrap ¶
func (c *ProviderReasoning) Unwrap() genai.Provider
type ProviderUsage ¶
ProviderUsage wraps a Provider and accumulates Usage values across multiple requests to track total token consumption.
func (*ProviderUsage) GenStream ¶
func (c *ProviderUsage) GenStream(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (iter.Seq[genai.Reply], func() (genai.Result, error))
GenStream implements the Provider interface and accumulates usage statistics.
func (*ProviderUsage) GenSync ¶
func (c *ProviderUsage) GenSync(ctx context.Context, msgs genai.Messages, opts ...genai.GenOption) (genai.Result, error)
GenSync implements the Provider interface and accumulates usage statistics.
func (*ProviderUsage) GetAccumulatedUsage ¶
func (c *ProviderUsage) GetAccumulatedUsage() genai.Usage
GetAccumulatedUsage returns the current accumulated usage values.
func (*ProviderUsage) Unwrap ¶
func (c *ProviderUsage) Unwrap() genai.Provider