yao/agent/robot/executor/standard/agent_stream_test.go
Max 3fee0e3fc3 Enhance execution listing and interaction with pagination and streaming support
- Refactor execution listing to support pagination with `Page` and `PageSize` options, replacing previous `Limit` and `Offset` parameters.
- Introduce `ExcludeStatuses` in execution queries to filter out specific execution statuses.
- Implement streaming interaction methods in the manager, allowing real-time responses from the host agent during interactions.
- Update API endpoints to accommodate new query parameters and enhance interaction capabilities with streaming support.
- Modify tests to ensure coverage for new pagination and streaming functionalities.
2026-02-27 16:38:30 +08:00

102 lines
2.7 KiB
Go

package standard_test
import (
"context"
"strings"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
agentcontext "github.com/yaoapp/yao/agent/context"
"github.com/yaoapp/yao/agent/robot/executor/standard"
"github.com/yaoapp/yao/agent/robot/types"
"github.com/yaoapp/yao/agent/testutils"
)
func TestAgentCallerCallStream(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test (requires LLM)")
}
testutils.Prepare(t)
defer testutils.Clean(t)
caller := standard.NewAgentCaller()
ctx := types.NewContext(context.Background(), testAuth())
t.Run("streams text chunks and returns result", func(t *testing.T) {
var mu sync.Mutex
var chunks []string
streamFn := func(chunk *standard.StreamChunk) int {
mu.Lock()
defer mu.Unlock()
if chunk.Type == "text" && chunk.Delta {
chunks = append(chunks, chunk.Content)
}
return 0
}
result, err := caller.CallWithMessagesStream(ctx, "tests.robot-single", "Hello, test message", streamFn)
require.NoError(t, err)
require.NotNil(t, result)
assert.False(t, result.IsEmpty())
mu.Lock()
combined := strings.Join(chunks, "")
chunkCount := len(chunks)
mu.Unlock()
t.Logf("Received %d text chunks, total length: %d", chunkCount, len(combined))
assert.Greater(t, chunkCount, 0, "should have received at least one text chunk")
assert.NotEmpty(t, combined, "combined chunks should not be empty")
})
t.Run("nil callback works like non-stream call", func(t *testing.T) {
result, err := caller.CallStream(ctx, "tests.robot-single",
[]agentcontext.Message{{Role: "user", Content: "Hello"}},
nil,
)
require.NoError(t, err)
require.NotNil(t, result)
assert.False(t, result.IsEmpty())
})
t.Run("stream returns parseable JSON", func(t *testing.T) {
var mu sync.Mutex
var chunks []string
streamFn := func(chunk *standard.StreamChunk) int {
mu.Lock()
defer mu.Unlock()
if chunk.Type == "text" && chunk.Delta {
chunks = append(chunks, chunk.Content)
}
return 0
}
result, err := caller.CallWithMessagesStream(ctx, "tests.robot-single", "Generate inspiration report", streamFn)
require.NoError(t, err)
require.NotNil(t, result)
data, err := result.GetJSON()
require.NoError(t, err)
assert.NotNil(t, data)
assert.Contains(t, data, "type")
mu.Lock()
chunkCount := len(chunks)
mu.Unlock()
t.Logf("Received %d chunks for JSON response", chunkCount)
})
t.Run("assistant not found returns error", func(t *testing.T) {
result, err := caller.CallWithMessagesStream(ctx, "non.existent", "hello", nil)
assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "assistant not found")
})
}