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") }) }