Skip to content

bug(MimoHandler): Type safety gaps and unhandled stream abort scenarios #20

@proyectoauraorg

Description

@proyectoauraorg

Description

The MimoHandler.createMessage() method in src/api/providers/mimo.ts has several type safety issues and missing edge-case handling that could lead to runtime errors or silent failures in production.

Current Behavior

1. any[] parameter type for messages

// src/api/providers/mimo.ts:70
override async *createMessage(
    systemPrompt: string,
    messages: any[],  // Should be Anthropic.Messages.MessageParam[]
    metadata?: ApiHandlerCreateMessageMetadata,
): ApiStream {

The parent OpenAiHandler uses Anthropic.Messages.MessageParam[] for the messages parameter. The override in MimoHandler widens this to any[], losing compile-time safety.

2. Multiple as any casts hiding potential issues

// Line 102 — double cast
stream = (await this.client.chat.completions.create(params as any)) as any

// Line 147 — unsafe access to prompt_tokens_details
const cacheWriteTokens = (lastUsage?.prompt_tokens_details as any)?.cache_write_tokens || 0

The double as any on the API call bypasses the OpenAI SDK type checking entirely. If MiMo's API changes its response shape, TypeScript will not catch it.

3. No AbortController / stream cancellation handling

The createMessage method streams via for await (const chunk of stream) but has no mechanism to:

  • Cancel an in-flight request when the user aborts
  • Handle AbortError if the underlying fetch is cancelled
  • Clean up resources on early termination

Other handlers like OpenAiNativeHandler and AnthropicHandler use an AbortController and handle cancellation signals.

Proposed Fix

override async *createMessage(
    systemPrompt: string,
    messages: Anthropic.Messages.MessageParam[],  // proper type
    metadata?: ApiHandlerCreateMessageMetadata,
): ApiStream {
    // ...
    const controller = new AbortController()
    
    try {
        stream = await this.client.chat.completions.create(
            params as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,
            { signal: controller.signal }
        )
    } catch (error) {
        if ((error as Error).name === "AbortError") return
        throw handleProviderError(error, "MiMo")
    }
    // ...
}

Impact

  • Severity: Medium — Works today but is fragile to API changes
  • Scope: src/api/providers/mimo.ts only
  • Risk of fix: Low — tightening types is non-breaking

Additional Context

The mimo-v2-flash model is explicitly excluded from mimoModels in packages/types/src/providers/mimo.ts due to reasoning_content passthrough issues. A well-typed handler would make it easier to validate and add flash support in the future.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions