mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-19 09:27:21 +02:00
119 lines
3.4 KiB
Go
119 lines
3.4 KiB
Go
package multiagent
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/cloudwego/eino/components/model"
|
|
"github.com/cloudwego/eino/schema"
|
|
)
|
|
|
|
type capturingAgenticToolCallingModel struct {
|
|
input []*schema.AgenticMessage
|
|
options *model.Options
|
|
}
|
|
|
|
func (m *capturingAgenticToolCallingModel) Generate(
|
|
_ context.Context,
|
|
input []*schema.AgenticMessage,
|
|
opts ...model.Option,
|
|
) (*schema.AgenticMessage, error) {
|
|
m.input = input
|
|
m.options = model.GetCommonOptions(nil, opts...)
|
|
return &schema.AgenticMessage{
|
|
Role: schema.AgenticRoleTypeAssistant,
|
|
ContentBlocks: []*schema.ContentBlock{
|
|
schema.NewContentBlock(&schema.FunctionToolCall{
|
|
CallID: "call-1",
|
|
Name: "emit_plan",
|
|
Arguments: `{"steps":["inspect"]}`,
|
|
}),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (m *capturingAgenticToolCallingModel) Stream(
|
|
context.Context,
|
|
[]*schema.AgenticMessage,
|
|
...model.Option,
|
|
) (*schema.StreamReader[*schema.AgenticMessage], error) {
|
|
return schema.StreamReaderFromArray([]*schema.AgenticMessage{
|
|
{
|
|
Role: schema.AgenticRoleTypeAssistant,
|
|
ContentBlocks: []*schema.ContentBlock{
|
|
schema.NewContentBlockChunk(&schema.FunctionToolCall{
|
|
CallID: "call-1",
|
|
Name: "emit_plan",
|
|
Arguments: `{"steps":[`,
|
|
}, &schema.StreamingMeta{Index: 0}),
|
|
},
|
|
},
|
|
{
|
|
Role: schema.AgenticRoleTypeAssistant,
|
|
ContentBlocks: []*schema.ContentBlock{
|
|
schema.NewContentBlockChunk(&schema.FunctionToolCall{
|
|
Arguments: `"inspect"]}`,
|
|
}, &schema.StreamingMeta{Index: 0}),
|
|
},
|
|
},
|
|
}), nil
|
|
}
|
|
|
|
func TestAgenticToolCallingAdapterConvertsForcedToolChoice(t *testing.T) {
|
|
t.Parallel()
|
|
native := &capturingAgenticToolCallingModel{}
|
|
adapter, err := newAgenticToolCallingChatModelAdapter(native).WithTools([]*schema.ToolInfo{{
|
|
Name: "emit_plan",
|
|
Desc: "emit a structured plan",
|
|
}})
|
|
if err != nil {
|
|
t.Fatalf("WithTools: %v", err)
|
|
}
|
|
|
|
out, err := adapter.Generate(
|
|
context.Background(),
|
|
[]*schema.Message{schema.UserMessage("plan this task")},
|
|
model.WithToolChoice(schema.ToolChoiceForced),
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("Generate: %v", err)
|
|
}
|
|
if len(native.input) != 1 || native.input[0].Role != schema.AgenticRoleTypeUser {
|
|
t.Fatalf("native input = %#v", native.input)
|
|
}
|
|
if native.options == nil || len(native.options.Tools) != 1 || native.options.Tools[0].Name != "emit_plan" {
|
|
t.Fatalf("native tools = %#v", native.options)
|
|
}
|
|
if native.options.AgenticToolChoice == nil || native.options.AgenticToolChoice.Type != schema.ToolChoiceForced {
|
|
t.Fatalf("agentic tool choice = %#v", native.options.AgenticToolChoice)
|
|
}
|
|
if len(out.ToolCalls) != 1 || out.ToolCalls[0].Function.Name != "emit_plan" {
|
|
t.Fatalf("classic output = %#v", out)
|
|
}
|
|
}
|
|
|
|
func TestAgenticToolCallingAdapterPreservesStreamingToolCallIndex(t *testing.T) {
|
|
t.Parallel()
|
|
adapter := newAgenticToolCallingChatModelAdapter(&capturingAgenticToolCallingModel{})
|
|
stream, err := adapter.Stream(context.Background(), []*schema.Message{
|
|
schema.UserMessage("plan this task"),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Stream: %v", err)
|
|
}
|
|
out, err := schema.ConcatMessageStream(stream)
|
|
if err != nil {
|
|
t.Fatalf("ConcatMessageStream: %v", err)
|
|
}
|
|
if len(out.ToolCalls) != 1 {
|
|
t.Fatalf("tool calls = %#v, want one merged call", out.ToolCalls)
|
|
}
|
|
call := out.ToolCalls[0]
|
|
if call.Index == nil || *call.Index != 0 {
|
|
t.Fatalf("tool call index = %#v", call.Index)
|
|
}
|
|
if call.Function.Name != "emit_plan" || call.Function.Arguments != `{"steps":["inspect"]}` {
|
|
t.Fatalf("merged tool call = %#v", call)
|
|
}
|
|
}
|