Compare commits
2
Commits
27fa702071
...
6592bae15d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6592bae15d
|
||
|
|
f85a9eeb3f
|
@@ -1,6 +1,6 @@
|
|||||||
module code.chimeric.al/chimerical/odidere
|
module code.chimeric.al/chimerical/odidere
|
||||||
|
|
||||||
go 1.25.5
|
go 1.26
|
||||||
|
|
||||||
tool (
|
tool (
|
||||||
golang.org/x/tools/cmd/deadcode
|
golang.org/x/tools/cmd/deadcode
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/sashabaranov/go-openai v1.41.2 h1:vfPRBZNMpnqu8ELsclWcAvF19lDNgh1t6TVfFFOPiSM=
|
|
||||||
github.com/sashabaranov/go-openai v1.41.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
|
||||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=
|
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ=
|
||||||
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||||
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||||
|
|||||||
@@ -97,10 +97,7 @@ func (c *Client) Completions(
|
|||||||
Timings: finalTimings,
|
Timings: finalTimings,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
toolResults, err := c.callTools(ctx, *message)
|
toolResults := c.callTools(ctx, *message)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("completions: %w", err)
|
|
||||||
}
|
|
||||||
messages = append(messages, toolResults...)
|
messages = append(messages, toolResults...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +123,7 @@ func (c *Client) completions(
|
|||||||
Tools: c.tools,
|
Tools: c.tools,
|
||||||
ThinkingBudgetTokens: thinkingBudgetTokens,
|
ThinkingBudgetTokens: thinkingBudgetTokens,
|
||||||
ChatTemplateKWARGS: kwargs,
|
ChatTemplateKWARGS: kwargs,
|
||||||
|
ParallelToolCalls: new(true),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(
|
return nil, fmt.Errorf(
|
||||||
@@ -286,10 +284,7 @@ func (c *Client) CompletionsStream(
|
|||||||
if len(message.ToolCalls) == 0 {
|
if len(message.ToolCalls) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
toolResults, err := c.callTools(ctx, message)
|
toolResults := c.callTools(ctx, message)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("completions stream: %w", err)
|
|
||||||
}
|
|
||||||
for _, tr := range toolResults {
|
for _, tr := range toolResults {
|
||||||
events <- StreamEvent{
|
events <- StreamEvent{
|
||||||
Type: streamEventMessage,
|
Type: streamEventMessage,
|
||||||
@@ -328,6 +323,7 @@ func (c *Client) completionsStream(ctx context.Context, messages []Message, mode
|
|||||||
Tools: c.tools,
|
Tools: c.tools,
|
||||||
ThinkingBudgetTokens: thinkingBudgetTokens,
|
ThinkingBudgetTokens: thinkingBudgetTokens,
|
||||||
ChatTemplateKWARGS: kwargs,
|
ChatTemplateKWARGS: kwargs,
|
||||||
|
ParallelToolCalls: new(true),
|
||||||
StreamOptions: &StreamOptions{IncludeUsage: true},
|
StreamOptions: &StreamOptions{IncludeUsage: true},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -4,58 +4,70 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// callTools executes each tool call in the message and returns the
|
// callTools executes each tool call in the message concurrently and returns
|
||||||
// resulting tool result messages.
|
// the resulting tool result messages in the same order as the input calls.
|
||||||
func (c *Client) callTools(ctx context.Context, msg Message) (
|
func (c *Client) callTools(ctx context.Context, msg Message) []Message {
|
||||||
results []Message, err error,
|
var (
|
||||||
) {
|
results = make([]Message, len(msg.ToolCalls))
|
||||||
for _, tc := range msg.ToolCalls {
|
sem = make(chan struct{}, runtime.NumCPU()*2)
|
||||||
c.log.InfoContext(
|
wg sync.WaitGroup
|
||||||
ctx,
|
)
|
||||||
"calling tool",
|
for i, tc := range msg.ToolCalls {
|
||||||
slog.String("name", tc.Function.Name),
|
wg.Add(1)
|
||||||
slog.String("args", tc.Function.Arguments),
|
go func(idx int, tc ToolCall) {
|
||||||
)
|
defer wg.Done()
|
||||||
|
sem <- struct{}{}
|
||||||
|
defer func() { <-sem }()
|
||||||
|
|
||||||
result, err := c.registry.Execute(
|
|
||||||
ctx, tc.Function.Name, tc.Function.Arguments,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
c.log.ErrorContext(
|
|
||||||
ctx,
|
|
||||||
"failed to call tool",
|
|
||||||
slog.Any("error", err),
|
|
||||||
slog.String("name", tc.Function.Name),
|
|
||||||
)
|
|
||||||
result = fmt.Sprintf(
|
|
||||||
`{"ok": false, "error": %q}`, err,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
c.log.InfoContext(
|
c.log.InfoContext(
|
||||||
ctx,
|
ctx,
|
||||||
"called tool",
|
"calling tool",
|
||||||
slog.String("name", tc.Function.Name),
|
slog.String("name", tc.Function.Name),
|
||||||
|
slog.String("args", tc.Function.Arguments),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// Content cannot be empty.
|
result, err := c.registry.Execute(
|
||||||
if strings.TrimSpace(result) == "" {
|
ctx, tc.Function.Name, tc.Function.Arguments,
|
||||||
result = `{"ok": true, "result": null}`
|
)
|
||||||
}
|
if err != nil {
|
||||||
|
c.log.ErrorContext(
|
||||||
|
ctx,
|
||||||
|
"failed to call tool",
|
||||||
|
slog.Any("error", err),
|
||||||
|
slog.String("name", tc.Function.Name),
|
||||||
|
)
|
||||||
|
result = fmt.Sprintf(
|
||||||
|
`{"ok": false, "error": %q}`, err,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
c.log.InfoContext(
|
||||||
|
ctx,
|
||||||
|
"called tool",
|
||||||
|
slog.String("name", tc.Function.Name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
toolResult := Message{
|
// Content cannot be empty.
|
||||||
Role: RoleTool,
|
if strings.TrimSpace(result) == "" {
|
||||||
ContentParts: []ContentPart{{
|
result = `{"ok": true, "result": null}`
|
||||||
Type: ContentTypeText, Text: result,
|
}
|
||||||
}},
|
|
||||||
Name: tc.Function.Name,
|
results[idx] = Message{
|
||||||
ToolCallID: tc.ID,
|
Role: RoleTool,
|
||||||
}
|
ContentParts: []ContentPart{{
|
||||||
results = append(results, toolResult)
|
Type: ContentTypeText, Text: result,
|
||||||
|
}},
|
||||||
|
Name: tc.Function.Name,
|
||||||
|
ToolCallID: tc.ID,
|
||||||
|
}
|
||||||
|
}(i, tc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return results, nil
|
wg.Wait()
|
||||||
|
return results
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -8,7 +8,6 @@ github.com/google/uuid
|
|||||||
# github.com/robfig/cron/v3 v3.0.1
|
# github.com/robfig/cron/v3 v3.0.1
|
||||||
## explicit; go 1.12
|
## explicit; go 1.12
|
||||||
github.com/robfig/cron/v3
|
github.com/robfig/cron/v3
|
||||||
## explicit; go 1.18
|
|
||||||
# golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678
|
# golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/exp/typeparams
|
golang.org/x/exp/typeparams
|
||||||
|
|||||||
Reference in New Issue
Block a user