Skip to content

chat.send() overloads do not narrow the response type #796

Open

Description

@kritikmodi

Environment

  • openrouter/sdk@1.2.27
  • TypeScript 5.9.3
  • NodeNext module resolution

Problem

chat.send() has separate overloads for stream?: false and stream: true, but both return:

ChatResult | EventStream<ChatStreamChunk>

This makes both documented usage patterns fail TypeScript.

Non-streaming

const completion = await client.chat.send({
  chatRequest: {
    model: "openai/gpt-5-mini",
    messages: [{ role: "user", content: "Hello" }],
    stream: false,
  },
});

console.log(completion.choices[0]);
TS2339: Property 'choices' does not exist on type
'SendChatCompletionRequestResponse'.

Streaming

const stream = await client.chat.send({
  chatRequest: {
    model: "openai/gpt-5-mini",
    messages: [{ role: "user", content: "Hello" }],
    stream: true,
  },
});

for await (const chunk of stream) {
  console.log(chunk);
}
TS2504: SendChatCompletionRequestResponse must have a
[Symbol.asyncIterator]() method.

Expected

The overloads should return:

stream?: false → Promise<ChatResult>
stream: true   → Promise<EventStream<ChatStreamChunk>>

The union is only necessary when the streaming mode is not statically known.

Activity

  1. kritikmodi commented on Aug 11, 2026

    @kritikmodi
    Author

    Related docs issue : OpenRouterTeam/docs#238

  2. slegarraga commented on Aug 21, 2026

    @slegarraga

    Confirmed against the current source. One thing worth adding for whoever picks this up upstream: this repository is fully generated by Speakeasy (see CONTRIBUTING.md), so the overload signatures can't be fixed by editing src/sdk/chat.ts directly.

    The root cause is visible in the generated file anyway: the existing overloads all return operations.SendChatCompletionRequestResponse, which is itself the ChatResult | EventStream<ChatStreamChunk> union. For the generator to emit discriminated returns (stream?: false -> Promise<ChatResult>, stream: true -> Promise<EventStream<ChatStreamChunk>>), the upstream OpenAPI spec needs to expose stream as a request-level discriminator so Speakeasy can split the response per variant. The durable fix therefore lives in the spec/monorepo side rather than in this repo.

    Happy to test the next generated release against both usage patterns from this report once it lands.

  3. f3tchcodes commented on Oct 7, 2026

    @f3tchcodes

    Facing this issue, has anyone opened a PR to fix this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions