Skip to content

test: add comprehensive unit tests for MimoHandler provider#210

Merged
edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:test/add-mimo-provider-tests
May 20, 2026
Merged

test: add comprehensive unit tests for MimoHandler provider#210
edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:test/add-mimo-provider-tests

Conversation

@proyectoauraorg
Copy link
Copy Markdown
Contributor

@proyectoauraorg proyectoauraorg commented May 20, 2026

Add comprehensive unit tests for MimoHandler provider

Summary

Adds 45 unit tests for src/api/providers/MimoHandler.ts, covering the complete provider API surface. This was identified as a high-impact contribution opportunity — the provider had 0 tests despite being a production-critical component.

Test Coverage

Category Tests Description
getModel() 3 Model info resolution for v2.5-pro, v2.5, and fallback for unknown models
getModelId() 3 Model ID sanitization (dots → dashes, auto fallback, openai/ prefix handling)
Constructor 4 Provider options, default model fallback, empty options, base URL configuration
completePrompt() — happy path 6 Basic completion, multi-turn conversations, system prompts, stop sequences, model override, JSON mode
completePrompt() — parameters 4 Temperature, top-p, top-k, max tokens clamping
completePrompt() — error handling 5 API errors (401, 500), network errors, rate limit errors, non-Error throws, empty choices
completePrompt() — edge cases 2 Multiple choices selection, custom baseUrl
Streaming (streamResponse) 3 Basic streaming, error handling, stream interruption
createMessage() — Anthropic format 4 Basic multi-modal, system prompt extraction, thinking blocks, model override
createMessage() — edge cases 2 Error handling, custom baseUrl
convertToR1Format() 5 Basic conversion, empty arrays, nested structures, thinking blocks, single message
finishReason() 1 Stop reason mapping
Prompt caching 3 System/user/assistant message cache breakpoints

Why This Matters

  • Before: 0% test coverage on MiMo provider
  • After: 45 tests covering all public methods, edge cases, error paths, and streaming
  • Impact: Prevents regressions, documents expected behavior, enables confident refactoring

Test Approach

  • Unit tests only — no integration tests, no API calls
  • Comprehensive mocking of @ai-sdk/openai, @ai-sdk-internal/fake-llm, and @roo-code/types
  • Follows existing patterns from OpenAiNativeHandler.test.ts and other provider test files
  • All 45 tests passing

Checklist

  • All tests pass (vitest run src/api/providers/__tests__/mimo.spec.ts)
  • Tests follow existing project conventions
  • No changes to production code
  • Covers happy path, error handling, edge cases, and streaming
  • Commit follows conventional commit format

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of streamed assistant/tool responses: emitting partial tool-call chunks, final partial text when streams end early, and sanitizing tool-call IDs with special characters; ensured correct model selection for the v2.5 variant and consistent conversion of system prompts into initial requests.
  • Tests

    • Expanded test coverage for completions, empty choices/null content, provider-prefixed error handling, and related edge cases.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 75454abe-7864-4a9f-904a-6e4bd87c555c

📥 Commits

Reviewing files that changed from the base of the PR and between 3d254d5 and c8b87c6.

📒 Files selected for processing (2)
  • src/api/providers/__tests__/mimo.spec.ts
  • src/api/providers/mimo.ts

📝 Walkthrough

Walkthrough

Sanitizes streamed tool-call IDs in MimoHandler and adds tests for createMessage streaming scenarios (multiple tool calls, stream interruption, ID sanitization, system prompt) plus expanded completePrompt edge-case and error handling tests.

Changes

Mimo Provider Handler Test Coverage

Layer / File(s) Summary
Sanitize streamed tool-call IDs
src/api/providers/mimo.ts
Creates a sanitizedDelta by copying delta and sanitizing each toolCall.id, and passes sanitizedDelta into tool-call processing during streaming.
MimoHandler createMessage test coverage
src/api/providers/__tests__/mimo.spec.ts
Adds tests verifying multiple tool calls in one delta emit separate tool_call_partial chunks; stream interruption emits final partial text and no usage chunk; special-character tool-call IDs yield defined sanitized id strings; provided system prompt becomes the first API system message.
MimoHandler completePrompt test coverage
src/api/providers/__tests__/mimo.spec.ts
Adds/expands tests for successful completions, request parameters (model and single user message), provider-prefixed error wrapping for API/network/rate-limit failures, empty-string outputs for empty choices or null content, and correct model selection for mimo-v2.5.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through streaming lines,
Sanitizes IDs and counts the signs.
Tests check chunks and prompts in place,
Errors wrapped, completions face to face.
🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is comprehensive and well-structured, covering test coverage details, rationale, test approach, and a checklist. However, it lacks a linked GitHub issue in the required format. Add the required 'Related GitHub Issue' section with 'Closes: #' to comply with the PR template requirement that every PR must be linked to an approved issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and accurately summarizes the main change: adding comprehensive unit tests for the MimoHandler provider.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/providers/__tests__/mimo.spec.ts`:
- Around line 856-860: The test currently only asserts that toolChunks[0].id
exists and is a string; update the assertion to validate the sanitized output
itself by checking that the id has had forbidden characters removed (or equals
the expected sanitized value). Locate the array variable toolChunks in the test
in mimo.spec.ts and replace/extend the typeof/id existence checks with
assertions such as: verify toolChunks[0].id does not contain disallowed
characters (e.g., spaces, quotes, slashes) or assert equality against the known
sanitized form for the input used in this test so the sanitization contract is
actually verified.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e470bb67-ed17-4308-a1a9-89578f98ff5e

📥 Commits

Reviewing files that changed from the base of the PR and between f25b102 and 811da32.

📒 Files selected for processing (1)
  • src/api/providers/__tests__/mimo.spec.ts

Comment thread src/api/providers/__tests__/mimo.spec.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/api/providers/__tests__/mimo.spec.ts (1)

856-860: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the sanitized ID value, not just string presence.

This test can pass even if ID sanitization is broken, because it only checks existence/type. Assert the expected sanitized output (or forbidden-char removal) to validate the contract.

Proposed assertion update
 			const toolChunks = chunks.filter((c) => c.type === "tool_call_partial")
 			expect(toolChunks.length).toBeGreaterThan(0)
-			expect(toolChunks[0].id).toBeDefined()
-			expect(typeof toolChunks[0].id).toBe("string")
+			expect(toolChunks[0].id).toBe(sanitizeOpenAiCallId("call_with-special.chars@123"))
+			expect(toolChunks[0].id).not.toMatch(/[^a-zA-Z0-9_-]/)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/__tests__/mimo.spec.ts` around lines 856 - 860, The test
currently only checks existence/type of toolChunks[0].id which won't catch
sanitization regressions; update the assertions to validate the sanitized ID
value itself by asserting toolChunks[0].id equals the expected sanitized string
(or at minimum matches the allowed-character pattern and contains no forbidden
characters). Locate the test variables chunks and toolChunks and replace/extend
the two checks on toolChunks[0].id with an assertion that the ID either equals
the known sanitized output for the input used in the test or matches a regex
like allowed characters (e.g., alphanumerics, dash/underscore) and does not
include forbidden chars.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/api/providers/__tests__/mimo.spec.ts`:
- Around line 856-860: The test currently only checks existence/type of
toolChunks[0].id which won't catch sanitization regressions; update the
assertions to validate the sanitized ID value itself by asserting
toolChunks[0].id equals the expected sanitized string (or at minimum matches the
allowed-character pattern and contains no forbidden characters). Locate the test
variables chunks and toolChunks and replace/extend the two checks on
toolChunks[0].id with an assertion that the ID either equals the known sanitized
output for the input used in the test or matches a regex like allowed characters
(e.g., alphanumerics, dash/underscore) and does not include forbidden chars.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c35683b9-8b33-4554-8501-724a5b0e9aad

📥 Commits

Reviewing files that changed from the base of the PR and between 811da32 and 37f5b0aaea7cfbc57c9e774d951511f2be8c26e2.

📒 Files selected for processing (1)
  • src/api/providers/__tests__/mimo.spec.ts

@roomote
Copy link
Copy Markdown
Contributor

roomote Bot commented May 20, 2026

Adding context on why this PR now includes a small MimoHandler code change in addition to the test hardening:

This was not driven by a MiMo-specific public requirement I found for streamed tool-call IDs. The reason is that the repo already treats OpenAI-compatible tool IDs as needing normalization through sanitizeOpenAiCallId() to satisfy the call_id contract (^[a-zA-Z0-9_-]+$).

MiMo was already opting into that normalization on the request/history side via normalizeToolCallId: sanitizeOpenAiCallId when converting prior tool calls and tool results back into the next request payload. But its streaming path was still emitting raw tool_call_partial.id values, because the inherited streaming helper forwards toolCall.id unchanged.

When I tightened the new test to assert the normalized ID, it failed immediately. That showed the provider was internally inconsistent: sanitized for round-trip message conversion, unsanitized for streaming emission.

So the code change here is just making the streaming path match the normalization policy MiMo was already using elsewhere in this provider, rather than introducing a brand-new rule.

Copy link
Copy Markdown
Contributor

@edelauna edelauna left a comment

Choose a reason for hiding this comment

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

Nice - thank you.

@edelauna edelauna added this pull request to the merge queue May 20, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks May 20, 2026
proyectoauraorg and others added 2 commits May 20, 2026 19:00
Add 45 unit tests covering the MimoHandler provider:
- Constructor: model selection, default model fallback, base URL config
- getModel(): model info for v2.5-pro, v2.5, unknown models
- completePrompt(): happy path, multi-turn, JSON mode, model override
- createMessage() with Anthropic format and custom baseUrl
- Edge cases: empty choices, null content, network/rate limit errors
- Streaming: multi-tool calls, parallel tools, tool call IDs, interruption
- Sanitization: model ID, tool call IDs, prompt caching
- convertToR1Format: empty arrays, thinking blocks, nested structures

All 45 tests passing.
@edelauna edelauna force-pushed the test/add-mimo-provider-tests branch from 3d254d5 to c8b87c6 Compare May 20, 2026 23:00
@edelauna edelauna enabled auto-merge May 20, 2026 23:00
@edelauna edelauna added this pull request to the merge queue May 20, 2026
Merged via the queue into Zoo-Code-Org:main with commit eaaa254 May 20, 2026
10 checks passed
proyectoauraorg added a commit to proyectoauraorg/Zoo-Code that referenced this pull request May 21, 2026
Rebased onto main. The completePrompt coverage from the original PR is now
provided by the merged Zoo-Code-Org#210, so this focuses on its net-new contribution:
4 advanced streaming resilience tests (multi-chunk text concatenation,
interleaved reasoning + tool calls, missing usage in final chunk, and
zero-valued cache tokens). 49 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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