Skip to content

Fix OpenAI Chat stream: prevent tool_calls[].type becoming "functionf…#296

Open
plusor wants to merge 2 commits intoactiveagents:mainfrom
plusor:main
Open

Fix OpenAI Chat stream: prevent tool_calls[].type becoming "functionf…#296
plusor wants to merge 2 commits intoactiveagents:mainfrom
plusor:main

Conversation

@plusor
Copy link

@plusor plusor commented Jan 26, 2026

…unction..."

When merging streaming deltas, delta was converted with as_json.deep_symbolize_keys, which left tool_calls[].type as the string "function". hash_merge_delta concatenates when the existing value is a String (hash[key] += value), so each chunk appended "function" and produced "functionfunctionfunction...".

  • Use delta.deep_to_h so the gem returns symbol-keyed hashes with :type => :function. Merges then hit the replace branch and type stays :function.
  • Match when :function in process_function_calls for consistency.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an OpenAI Chat streaming merge issue where tool_calls[].type could become "functionfunctionfunction..." due to string concatenation during delta merges.

Changes:

  • Convert streaming deltas via api_message.delta.deep_to_h to preserve non-string enum values (preventing hash_merge_delta string concatenation on :type).
  • Normalize tool call type handling by switching process_function_calls to compare api_function_call[:type].to_s against "function".

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@plusor plusor force-pushed the main branch 2 times, most recently from 674a691 to 3df2617 Compare January 30, 2026 14:50
…unction..."

When merging streaming deltas, delta was converted with as_json.deep_symbolize_keys, which left tool_calls[].type as the string "function". hash_merge_delta concatenates when the existing value is a String (hash[key] += value), so each chunk appended "function" and produced "functionfunctionfunction...".

- Use delta.deep_to_h so the gem returns symbol-keyed hashes with :type => :function. Merges then hit the replace branch and type stays :function.
- Match when :function in process_function_calls for consistency.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


def stub_streaming_response(response_body, request_options = {})
default_request = {
messages: [{ content: "What's the weather in Boston?",role: "user" }],
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after comma. The code has "What's the weather in Boston?",role: "user" but should have a space after the comma for consistency with Ruby style conventions.

Suggested change
messages: [{ content: "What's the weather in Boston?",role: "user" }],
messages: [{ content: "What's the weather in Boston?", role: "user" }],

Copilot uses AI. Check for mistakes.
- Remove extra empty line at class body beginning
- Add spaces inside array brackets per rubocop style rules
- Add missing space after comma

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@TonsOfFun
Copy link
Contributor

I've reviewed the PR and addressed the linting issues. Here's a summary:

Linting Fixes Applied

The rubocop issues were in test/providers/open_ai/chat_provider_test.rb:

  • Removed extra empty line at class body beginning
  • Added spaces inside array brackets per project style rules
  • Added missing space after comma

The linting fixes are available in branch pr-296-lint-fix which can be cherry-picked or merged.

Test Validation

  • ✅ The test passes successfully
  • ✅ The test correctly asserts that type: :function is a symbol (not string) after streaming delta merging
  • ✅ The test verifies that arguments are properly concatenated from streaming deltas

The fix properly addresses the original issue where tool_calls[].type was becoming "functionfunctionfunction..." due to string concatenation during delta merges.

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.

3 participants