Skip to content

Conversation

@anubra266
Copy link
Contributor

No description provided.

- Implemented `SSEStreamHelper` and `VercelDataStreamHelper` for streaming tool input and output.
- Added methods for writing tool input start, delta, availability, and output (both success and error).
- Created unit tests for tool streaming functionality in `tool-streaming.test.ts` to ensure proper behavior.
- Updated `Agent` class to utilize streaming helpers for user-visible tool calls.
- Mocked streaming methods in `AgentSession.test.ts` for testing purposes.
- Enhanced documentation for new streaming methods in `stream-helpers.ts`.
@changeset-bot
Copy link

changeset-bot bot commented Jan 16, 2026

⚠️ No Changeset found

Latest commit: 5e41638

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jan 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
agents-eval-api Ready Ready Preview, Comment Jan 17, 2026 1:00am
agents-manage-api Ready Ready Preview, Comment Jan 17, 2026 1:00am
agents-manage-ui Ready Ready Preview, Comment Jan 17, 2026 1:00am
agents-run-api Ready Ready Preview, Comment Jan 17, 2026 1:00am
1 Skipped Deployment
Project Deployment Review Updated (UTC)
agents-docs Skipped Skipped Jan 17, 2026 1:00am

Request Review

@anubra266 anubra266 changed the title Add tool streaming functionality with comprehensive unit tests Add tool streaming Jan 16, 2026
@claude
Copy link

claude bot commented Jan 16, 2026

Claude finished @anubra266's task —— View job


Comprehensive Code Review: Tool Streaming Implementation

I've completed a thorough technical review of this tool streaming feature from both engineering and system architecture perspectives.

Todo List:

  • Analyze changed files and understand tool streaming implementation
  • Research existing streaming and tool patterns in codebase
  • Review architecture and design decisions
  • Evaluate test coverage and quality
  • Check for potential issues and improvements
  • Provide comprehensive feedback

Summary

This PR implements a comprehensive tool streaming system that provides real-time visibility into tool execution across dual streaming protocols. The implementation is generally well-architected with proper separation of concerns and comprehensive test coverage.

Key Strengths

1. Clean Architecture & Abstraction

  • Polymorphic stream helpers: SSEStreamHelper, VercelDataStreamHelper, and BufferingStreamHelper all implement the same StreamHelper interface
  • Protocol-agnostic design: Tool streaming works seamlessly across Chat Completions API and Vercel AI SDK
  • Consistent API surface: All 7 tool streaming methods follow the same parameter pattern with toolCallId

2. Comprehensive Test Coverage

  • 138 lines of focused tests covering both streaming protocols
  • Complete lifecycle testing: From writeToolInputStart through writeToolOutputDenied
  • Proper mocking strategy: Uses Vitest with realistic stream mock behavior

3. Robust Integration

  • Agent lifecycle hooks: Seamlessly integrated into existing tool execution flow in Agent.ts:520-641
  • Memory management: Proper cleanup with connection drop timers and buffer management
  • Error boundaries: Graceful handling of stream completion states

Areas for Consideration

1. Type Safety & Interface Consistency

Medium Priority: Consider strengthening type constraints for tool streaming parameters:

// Current (line 24-35 in stream-helpers.ts)
writeToolInputStart(params: { toolCallId: string; toolName: string }): Promise<void>;

// Consider adding branded types for better type safety
type ToolCallId = string & { readonly __brand: unique symbol };
type ToolName = string & { readonly __brand: unique symbol };

Rationale: Tool call IDs and tool names are critical identifiers that should maintain referential integrity across the streaming lifecycle.

2. Error Handling & Recovery Patterns

Medium Priority: The error handling could be more granular, particularly around stream state validation:

// In stream-helpers.ts:575-580, consider more specific error types
async writeToolInputStart(params: { toolCallId: string; toolName: string }): Promise<void> {
  if (this.isCompleted) {
    // Consider throwing a specific error type vs. silent return
    throw new StreamCompletedError('Cannot write tool input to completed stream');
  }
  // ... rest of implementation
}

Rationale: Silent failures in streaming contexts can lead to confusing user experiences where tool execution appears to hang.

3. Potential Race Conditions

Low-Medium Priority: In VercelDataStreamHelper.ts:814-817, the timing-based queuing logic could theoretically have edge cases:

// Current logic (lines 814-817)
if (this.isTextStreaming || gapFromLastTextEnd < STREAM_TEXT_GAP_THRESHOLD_MS) {
  this.queuedEvents.push({ type: 'data-summary', event: summary });
  return;
}

Consideration: What happens if isTextStreaming changes between the condition check and the queue push? Consider using atomic state transitions or locks for critical timing decisions.

4. Memory Management Optimization

Low Priority: The toolCallIndexById Map in SSEStreamHelper grows indefinitely during a session:

// In SSEStreamHelper.ts:122-128
private getToolIndex(toolCallId: string): number {
  const existing = this.toolCallIndexById.get(toolCallId);
  if (existing !== undefined) return existing;
  const next = this.toolCallIndexById.size; // This only grows
  this.toolCallIndexById.set(toolCallId, next);
  return next;
}

Suggestion: Consider cleanup strategies for long-running sessions or implement bounded growth patterns.

5. API Design Considerations

Low Priority: The tool streaming API is quite granular with 7 methods. Consider whether some consolidation might improve developer experience:

// Current approach requires multiple calls:
await helper.writeToolInputStart({ toolCallId, toolName });
await helper.writeToolInputDelta({ toolCallId, inputTextDelta });
await helper.writeToolInputAvailable({ toolCallId, toolName, input });

// Alternative fluent API consideration:
await helper.toolStream(toolCallId)
  .inputStart(toolName)
  .inputDelta(inputTextDelta)
  .inputAvailable(input);

Trade-off: Current approach is more explicit and easier to test, but fluent APIs can reduce boilerplate.

System-Level Architecture Assessment

Positive Design Decisions

  1. Consistent with existing patterns: Follows the established StreamHelper interface pattern used throughout the codebase
  2. Protocol abstraction: Smart choice to abstract tool streaming concepts away from specific transport mechanisms
  3. Event queuing strategy: Thoughtful approach to handle text streaming vs. operation conflicts
  4. Test-driven approach: Comprehensive test suite demonstrates the API contracts clearly

Extensibility Considerations

  1. Future streaming protocols: The interface design supports easy addition of new streaming protocols
  2. Tool approval workflow: Well-integrated with existing approval mechanisms (writeToolApprovalRequest)
  3. Monitoring capabilities: Good foundation for adding metrics and observability

Recommendations

For Immediate Consideration:

  1. Add changeset as noted by the changeset bot - this feature merits at least a patch version bump
  2. Consider error type hierarchy for better debugging experience
  3. Document tool streaming lifecycle in the codebase - this is a significant new capability

For Future Enhancement:

  1. Add performance benchmarks for high-throughput tool streaming scenarios
  2. Consider implementing tool streaming metrics for operational monitoring
  3. Evaluate batch tool streaming APIs for bulk operations

Verdict

This is a high-quality implementation that follows TypeScript and system architecture best practices. The code is clean, well-tested, and properly integrated. The identified considerations are mostly about future-proofing and edge case handling rather than fundamental flaws.

Recommendation: ✅ Approve with minor considerations

The implementation successfully achieves its goals while maintaining consistency with existing patterns. The tool streaming functionality will significantly improve user experience by providing real-time visibility into agent tool execution.

- Enhanced the `/api/chat` endpoint to handle approval responses for tool calls.
- Implemented validation for conversation IDs in approval responses to ensure they are explicitly provided.
- Updated the Zod schema to include a new part type for tool approval responses.
- Added comprehensive unit tests to verify the behavior of approval response handling, including success and idempotent cases.
- Ensured proper error handling for missing conversation IDs and unknown tool call IDs.
- Integrated ToolApprovalUiBus to manage approval requests and responses in the chat and data stream routes.
- Enhanced the `/api/chat` and `/api/chatDataStream` endpoints to publish and subscribe to approval events.
- Implemented unit tests to verify the behavior of approval UI event handling, including success and error cases.
- Updated the Agent class to support delegated agent approval workflows.
- Ensured proper error handling and validation for tool approval events.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants