feat(llm): add ChatTemplateKwargs to CompletionRequest for provider-specific template params
- Add ChatTemplateKwargs field to llm.CompletionRequest - Propagate kwargs through agent loop in both Run() and RunStream() - Pass kwargs to llama.cpp client chat request - Fix tool schema marshaling to include type/function wrapper - Fix stream indentation logic in RunStream with responseBuilder - Remove indirect marker from uuid dependency
This commit is contained in:
parent
0054ca793c
commit
1a8f1557f6
4 changed files with 58 additions and 42 deletions
2
go.mod
2
go.mod
|
|
@ -4,4 +4,4 @@ go 1.26
|
|||
|
||||
require gopkg.in/yaml.v3 v3.0.1
|
||||
|
||||
require github.com/google/uuid v1.6.0 // indirect
|
||||
require github.com/google/uuid v1.6.0
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"iter"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/VictorVargas/rony-llm-agent/pkg/llm"
|
||||
|
|
@ -40,6 +41,7 @@ type Config struct {
|
|||
Approver Approver
|
||||
OnIteration OnIterationHook
|
||||
ToolTimeout time.Duration
|
||||
ChatTemplateKwargs map[string]any // passed to the LLM provider (e.g. Qwen enable_thinking)
|
||||
}
|
||||
|
||||
// Iteration represents a single cycle of the agent loop.
|
||||
|
|
@ -88,6 +90,7 @@ func (l *Loop) Run(ctx context.Context, input string) (Response, error) {
|
|||
resp, err := l.cfg.LLM.Generate(ctx, llm.CompletionRequest{
|
||||
Messages: messages,
|
||||
Tools: l.getToolSchemas(),
|
||||
ChatTemplateKwargs: l.cfg.ChatTemplateKwargs,
|
||||
})
|
||||
if err != nil {
|
||||
return Response{}, fmt.Errorf("LLM generate failed: %w", err)
|
||||
|
|
@ -145,9 +148,11 @@ func (l *Loop) RunStream(ctx context.Context, input string) iter.Seq2[llm.Stream
|
|||
stream := l.cfg.LLM.Stream(ctx, llm.CompletionRequest{
|
||||
Messages: messages,
|
||||
Tools: l.getToolSchemas(),
|
||||
ChatTemplateKwargs: l.cfg.ChatTemplateKwargs,
|
||||
})
|
||||
|
||||
var hasToolCalls bool
|
||||
var responseBuilder strings.Builder
|
||||
for chunk, err := range stream {
|
||||
if err != nil {
|
||||
yield(llm.StreamChunk{}, err)
|
||||
|
|
@ -173,6 +178,7 @@ func (l *Loop) RunStream(ctx context.Context, input string) iter.Seq2[llm.Stream
|
|||
}
|
||||
|
||||
if !hasToolCalls && chunk.Delta != "" {
|
||||
responseBuilder.WriteString(chunk.Delta)
|
||||
if !yield(chunk, nil) {
|
||||
return
|
||||
}
|
||||
|
|
@ -184,11 +190,9 @@ func (l *Loop) RunStream(ctx context.Context, input string) iter.Seq2[llm.Stream
|
|||
}
|
||||
}
|
||||
|
||||
if iterations >= l.cfg.MaxIters {
|
||||
yield(llm.StreamChunk{}, fmt.Errorf("max iterations (%d) reached", l.cfg.MaxIters))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loop) buildInitialMessages(input string) []llm.Message {
|
||||
systemPrompt := persona.AssembleSystemPrompt(l.cfg.Persona, "")
|
||||
|
|
@ -201,7 +205,16 @@ func (l *Loop) buildInitialMessages(input string) []llm.Message {
|
|||
func (l *Loop) getToolSchemas() []json.RawMessage {
|
||||
var schemas []json.RawMessage
|
||||
for _, tool := range l.cfg.Tools.List() {
|
||||
schemas = append(schemas, tool.InputSchema)
|
||||
def := map[string]interface{}{
|
||||
"type": "function",
|
||||
"function": map[string]interface{}{
|
||||
"name": tool.Name,
|
||||
"description": tool.Description,
|
||||
"parameters": json.RawMessage(tool.InputSchema),
|
||||
},
|
||||
}
|
||||
data, _ := json.Marshal(def)
|
||||
schemas = append(schemas, data)
|
||||
}
|
||||
return schemas
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ func (c *Client) buildRequest(req llm.CompletionRequest, stream bool) (io.Reader
|
|||
Model: req.Model,
|
||||
Messages: messages,
|
||||
Stream: stream,
|
||||
ChatTemplateKwargs: req.ChatTemplateKwargs,
|
||||
}
|
||||
if len(tools) > 0 {
|
||||
openReq.Tools = tools
|
||||
|
|
@ -242,6 +243,7 @@ type llamaChatRequest struct {
|
|||
TopP float32 `json:"top_p,omitempty"`
|
||||
Stop []string `json:"stop,omitempty"`
|
||||
Stream bool `json:"stream"`
|
||||
ChatTemplateKwargs map[string]any `json:"chat_template_kwargs,omitempty"`
|
||||
}
|
||||
|
||||
type llamaMessage struct {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ type CompletionRequest struct {
|
|||
MaxTokens *int `json:"max_tokens,omitempty"`
|
||||
Stop []string `json:"stop,omitempty"`
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
ChatTemplateKwargs map[string]any `json:"chat_template_kwargs,omitempty"` // model-specific chat template params, e.g. Qwen enable_thinking
|
||||
}
|
||||
|
||||
// CompletionResponse is returned from an LLM provider.
|
||||
|
|
|
|||
Loading…
Reference in a new issue