Skip to content

feat(models): add streaming support and utility function - #338

Merged
steebchen merged 7 commits into
mainfrom
feat/models
Jun 11, 2025
Merged

feat(models): add streaming support and utility function#338
steebchen merged 7 commits into
mainfrom
feat/models

Conversation

@steebchen

@steebchen steebchen commented Jun 11, 2025

Copy link
Copy Markdown
Member

Introduced a streaming property to model and provider definitions to clearly indicate support for streaming. Added a utility function getModelStreamingSupport to determine streaming compatibility for model-provider combinations. Updated related files to use the centralized logic for improved maintainability.

Summary by CodeRabbit

  • New Features
    • Improved detection of streaming support for models and providers, allowing for more accurate streaming availability checks.
  • Bug Fixes
    • Error messages now specify when a model-provider combination does not support streaming, rather than just the provider.
  • Refactor
    • Centralized streaming support logic into a new helper function for consistent use across the application.
  • Chores
    • Updated data to explicitly indicate streaming support for individual models and providers.

Introduced a `streaming` property to model and provider definitions to clearly indicate support for streaming.
Added a utility function `getModelStreamingSupport` to determine streaming compatibility for model-provider combinations.
Updated related files to use the centralized logic for improved maintainability.
@coderabbitai

coderabbitai Bot commented Jun 11, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The changes introduce a new helper function to determine streaming support for models and providers, update the data structures to include mandatory streaming flags at the model-provider level, and refactor related logic across the codebase to utilize the new function. Exports and error messages are updated accordingly.

Changes

File(s) Change Summary
packages/models/src/helpers.ts Added getModelStreamingSupport function to check streaming support for models and providers.
packages/models/src/index.ts Exported getModelStreamingSupport from the package.
packages/models/src/models.ts Made streaming property mandatory in ProviderModelMapping; updated model entries with explicit streaming flags; removed duplicate commented entry.
apps/gateway/src/api.e2e.ts Changed filtering logic for streaming models to use new function and updated streaming support checks with layered streaming logic; added explicit error handling on streaming request failure.
apps/gateway/src/chat/chat.ts Added logic to determine base model name for streaming check; replaced streaming check with new function; updated error messages for model/provider streaming support.
apps/ui/src/routes/playground.tsx Replaced local streaming support logic with imported getModelStreamingSupport; removed redundant code.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UI/Route
    participant ModelsHelper
    participant ModelsData

    Client->>UI/Route: Request streaming model info
    UI/Route->>ModelsHelper: getModelStreamingSupport(modelName, providerId)
    ModelsHelper->>ModelsData: Look up model and provider streaming flags
    ModelsData-->>ModelsHelper: Return streaming support status
    ModelsHelper-->>UI/Route: Return boolean
    UI/Route-->>Client: Respond with streaming support info
Loading
sequenceDiagram
    participant User
    participant ChatAPI
    participant ModelsHelper
    participant ModelsData

    User->>ChatAPI: Request streaming chat with model/provider
    ChatAPI->>ModelsHelper: getModelStreamingSupport(modelName, providerId)
    ModelsHelper->>ModelsData: Lookup streaming flags
    ModelsData-->>ModelsHelper: Return streaming support status
    ModelsHelper-->>ChatAPI: Return boolean
    alt Streaming not supported
        ChatAPI-->>User: Return error: Model/provider does not support streaming
    else Streaming supported
        ChatAPI-->>User: Proceed with streaming chat
    end
Loading

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a92506 and 71ec0d0.

📒 Files selected for processing (1)
  • packages/models/src/models.ts (33 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/models/src/models.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: e2e / run
  • GitHub Check: build / run
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/ui/src/routes/playground.tsx (1)

169-180: 🛠️ Refactor suggestion

⚠️ Potential issue

Streaming falsely disabled when model is prefixed with provider

selectedModel may contain strings like "openai/gpt-4o-mini".
Passing that verbatim to getModelStreamingSupport (with no provider ID) fails the lookup and returns false, so the UI falls back to non-streaming even though the backend accepts streaming.

-      const supportsStreaming = getModelStreamingSupport(selectedModel);
+      // De-compose "<provider>/<model>" if the user selects a provider-prefixed entry
+      let modelName = selectedModel;
+      let providerId: string | undefined;
+      if (selectedModel.includes("/")) {
+        const parts = selectedModel.split("/");
+        providerId = parts.shift();
+        modelName = parts.join("/");
+      }
+      const supportsStreaming = getModelStreamingSupport(modelName, providerId);
🧹 Nitpick comments (5)
apps/gateway/src/api.e2e.ts (1)

43-51: Avoid copy-pasted streaming logic – call the central helper instead

The inline some() check duplicates the logic already encapsulated in getModelStreamingSupport, risking divergence when the helper evolves.

-import { models, providers } from "@llmgateway/models";
+import { models, providers, getModelStreamingSupport } from "@llmgateway/models";
@@
-const streamingModels = testModels.filter((m) =>
-  m.providers.some((p: any) => {
-    if (p.streaming !== undefined) {
-      return p.streaming;
-    }
-    const provider = providers.find((pr) => pr.id === p.providerId);
-    return provider?.streaming;
-  }),
-);
+const streamingModels = testModels.filter((m) =>
+  m.providers.some((p: any) =>
+    getModelStreamingSupport(m.model, p.providerId),
+  ),
+);
packages/models/src/models.ts (1)

39-43: ModelDefinition.streaming is never consulted by the helper

getModelStreamingSupport only inspects the provider-level flag and, if absent, falls back to the provider definition – it never looks at model.streaming. Either:

  1. Wire the fallback into the helper, or
  2. Drop the property to avoid dead config.

Keeping unused metadata invites confusion.

packages/models/src/helpers.ts (3)

18-26: Avoid O(n²) look-ups by pre-computing a provider → streaming map

Inside the .some() you perform a linear providers.find for every provider mapping.
For large provider lists this turns the overall complexity into O(p²). Building a simple map once per function call drops the inner look-up to O(1) and keeps the whole branch O(p).

-	return modelInfo.providers.some((provider: ProviderModelMapping) => {
-		// Check model-level streaming first, then fall back to provider-level
-		if (provider.streaming !== undefined) {
-			return provider.streaming;
-		}
-		// Fall back to provider-level streaming support
-		const providerInfo = providers.find((p) => p.id === provider.providerId);
-		return providerInfo?.streaming === true;
-	});
+	const providerStreaming = new Map(
+		providers.map((p) => [p.id, p.streaming === true]),
+	);
+
+	return modelInfo.providers.some((provider: ProviderModelMapping) => {
+		if (provider.streaming !== undefined) {
+			return provider.streaming;
+		}
+		return providerStreaming.get(provider.providerId) === true;
+	});

30-44: DRY: Extract repeated fallback logic into a tiny helper

Lines 30-44 repeat the same precedence check implemented above (model-level, then provider-level). Pulling this into an internal helper (supportsProviderStreaming(mapping)) eliminates duplication, keeps both branches aligned, and makes future fixes one-shot.


7-45: Unit-test the precedence matrix

Given the three-level precedence (model absent → provider absent → explicit false overriding provider true) a regression here would be hard to spot manually. Recommend adding table-driven tests that cover:

• model with provider-level true | false | undefined
• provider-only streaming flags true | false | undefined
• specified vs. unspecified providerId

Happy to draft the tests if useful.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0981ddc and e7a7154.

📒 Files selected for processing (6)
  • apps/gateway/src/api.e2e.ts (1 hunks)
  • apps/gateway/src/chat/chat.ts (2 hunks)
  • apps/ui/src/routes/playground.tsx (1 hunks)
  • packages/models/src/helpers.ts (1 hunks)
  • packages/models/src/index.ts (1 hunks)
  • packages/models/src/models.ts (30 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/gateway/src/chat/chat.ts (1)
packages/models/src/helpers.ts (1)
  • getModelStreamingSupport (7-45)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build / run
  • GitHub Check: e2e / run
🔇 Additional comments (2)
packages/models/src/index.ts (1)

4-4: Public re-export looks fine.

Exposing getModelStreamingSupport from the package root keeps consumers unaware of the helpers file layout. No issues spotted.

apps/gateway/src/chat/chat.ts (1)

1111-1116: 👍 Switched to model + provider level streaming guard

Great move from provider-only checks to getModelStreamingSupport.
This prevents false positives when a provider offers mixed streaming capabilities across models.

Log response body and throw an error when the status code
is not 200 in the API end-to-end test. This improves
debugging and test reliability.
Added `baseModelName` to track the base model name for streaming support validation. Updated streaming checks to use the base model instead of the provider-specific model name, ensuring proper compatibility checks and error handling.
Ensure `baseModelName` accurately reflects the final `usedModel` after routing. Fallback to `usedModel` if no corresponding model definition is found.
Removed redundant `baseModelName` assignments and centralized the logic using optional chaining and fallback to `usedModel` for clarity and maintainability.
Removed optional streaming definition in model configurations and
ensured all models explicitly specify streaming support. Updated
model entries accordingly to include streaming properties.
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.

1 participant