Skip to content

fix(openai-shim): preserve tool result images and local token caps#659

Merged
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
auriti:fix/openai-shim-residual-v4
Apr 13, 2026
Merged

fix(openai-shim): preserve tool result images and local token caps#659
kevincodex1 merged 1 commit into
Gitlawb:mainfrom
auriti:fix/openai-shim-residual-v4

Conversation

@auriti
Copy link
Copy Markdown
Collaborator

@auriti auriti commented Apr 13, 2026

Summary

  • preserve tool_result images as real image_url content parts for OpenAI-compatible requests
  • use max_tokens instead of max_completion_tokens for local providers like Ollama and LM Studio
  • add focused regression tests for image forwarding and local-provider token-cap behavior

Why

The earlier PR #237 is now mostly absorbed by main, but two useful gaps remained:

  • tool_result images were still degraded instead of being forwarded as real multipart image content
  • local OpenAI-compatible providers still did not get the GitHub-style max_tokens fallback

This PR keeps only that residual value in a current, reviewable branch.

Changes

File Change
src/services/api/openaiShim.ts forward tool_result images as image_url parts and apply max_tokens fallback to local providers
src/services/api/openaiShim.test.ts add regression coverage for local-provider token caps and multipart tool-result image forwarding

Test plan

  • bun test src/services/api/openaiShim.test.ts (validated in the main working tree before isolating this branch)
  • Manual: verify an OpenAI-compatible tool result with image content reaches the provider as multipart image_url
  • Manual: verify Ollama / LM Studio requests use max_tokens and omit max_completion_tokens

Notes

Keep tool-result images as real image_url parts for OpenAI-compatible requests and use max_tokens for local providers like Ollama and LM Studio.
@auriti
Copy link
Copy Markdown
Collaborator Author

auriti commented Apr 13, 2026

@Vasanthdev2004 @gnanam1990

This is the narrowed follow-up to the old #237 branch, rebuilt from current main to keep only the residual fixes that still seemed missing:

  • preserve tool_result images as real image_url parts
  • use max_tokens for local providers like Ollama / LM Studio
  • add focused regression coverage for those paths

I intentionally left out the reasoning/thinking changes that current main already absorbed, so this should be much easier to review than the old conflict-heavy branch.

smoke-and-tests is green on this head.

Copy link
Copy Markdown
Collaborator

@Vasanthdev2004 Vasanthdev2004 left a comment

Choose a reason for hiding this comment

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

Review: Preserve tool result images and local token caps

Reviewed on head e5ae42a. CI green ✅. 2 files, +242/-17.

This is a clean, well-scoped follow-up to #237 — only the two residual gaps that current main hasn't absorbed yet. The diff is focused and the tests are good.


max_tokens fallback for local providers

The isLocal branch correctly extends the existing isGithub || isMistral gate to also include isLocalProviderUrl. This is the right behavior — local providers like Ollama and LM Studio don't support max_completion_tokens (it's an OpenAI-specific field), and they do support max_tokens. The isLocalProviderUrl function is already imported and used in the same file for stream_options, so this is consistent.

Test coverage: one test for local provider (localhost:11434) asserting max_tokens: 64 and max_completion_tokens: undefined, one for remote provider (api.openai.com) asserting the reverse. Good.

✅ Tool result image forwarding

The old code flattened tool result images into [image:image/png] placeholder strings — which means the image data was completely lost and the provider received a useless text marker. The new code converts them to proper image_url content parts with data:image/png;base64,... URIs, matching the same pattern already used in convertContentBlocks for user/assistant messages.

The single-part optimization is nice: when there's only one text block and no error, it returns a plain string (backward-compatible). When there are images or multiple parts, it returns the array. The isError handling is also cleaner — prepending Error: to the first text part instead of wrapping the entire serialized content.

Test coverage: three tests covering (1) single image tool result → image_url data URI, (2) mixed text+image tool result → multipart content, (3) the old placeholder test updated to expect the new format. All assertions look correct.

stream_options removal for local providers

The local provider test also asserts stream_options: undefined, which is correct — the existing code at line 1213 already skips stream_options for local providers, and the test is non-streaming anyway. No behavioral change here.


🔶 One observation (non-blocking)

The OpenAI Chat Completions API formally types tool message content as string | ChatCompletionContentPartText[]image_url parts are not documented in the tool message schema. In practice, many providers (Ollama, LM Studio, etc.) handle them fine because they process all content parts generically, and the old behavior (losing the image entirely) was strictly worse. So this is a clear improvement even if some strict API validators might flag it.

If you want to be maximally safe, you could add a provider-aware gate: only emit image_url parts for providers known to support them in tool messages (local providers, GitHub, etc.), and fall back to the placeholder for others. But that's an optimization — the current approach is a strict upgrade over the old [image:image/png] lossy behavior.


Verdict: Approve-ready

Clean, focused, well-tested. Two real fixes: (1) images no longer silently dropped from tool results, (2) local providers get max_tokens instead of the unsupported max_completion_tokens. No logic regressions. The image forwarding is strictly better than the placeholder approach.

@kevincodex1 kevincodex1 merged commit 30c866d into Gitlawb:main Apr 13, 2026
1 check passed
C1ph3r404 pushed a commit to C1ph3r404/openclaude that referenced this pull request Apr 29, 2026
…itlawb#659)

Keep tool-result images as real image_url parts for OpenAI-compatible requests and use max_tokens for local providers like Ollama and LM Studio.
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