feat: add Kimi OpenAI-compatible provider - #713
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
WalkthroughThis PR adds an OpenAI-compatible provider (OpenAICompatibleProvider), integrates it into ai-provider-factory with aliasing/config defaults and discovery, updates SubagentDispatcher fallback resolution to consult factory config, and adds tests, README/docs, config templates, and a regenerated install manifest. ChangesOpenAI-Compatible Kimi Provider
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsTimed out fetching pipeline failures after 30000ms 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. Comment |
📊 Coverage ReportCoverage report not available
Generated by PR Automation (Story 6.1) |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
.aiox-core/infrastructure/integrations/ai-providers/openai-compatible-provider.js (1)
256-269: ⚡ Quick winMissing
awaitonresponse.json()— async best practice violation.
return response.json()(line 260) returns the raw Promise. Since the function isasync, this works correctly for the caller, but ifresponse.json()rejects (e.g., a server sendsContent-Type: application/jsonwith a malformed body), the rejection bypasses any future localtry/catchin_readResponseBodyand loses the intermediate stack frame. The text path on line 263 correctly usesawait.♻️ Proposed fix
if (contentType.includes('application/json')) { - return response.json(); + return await response.json(); }As per coding guidelines: "Check for async/await best practices."
🤖 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 @.aiox-core/infrastructure/integrations/ai-providers/openai-compatible-provider.js around lines 256 - 269, In _readResponseBody, change the JSON branch so you await response.json() instead of returning the raw Promise; specifically update the branch in the _readResponseBody method that currently does return response.json() to use await (and optionally wrap that await in the same try/catch pattern used for the text path) so parsing failures are caught inside _readResponseBody and preserve the local stack frame and error handling..aiox-core/infrastructure/integrations/ai-providers/README.md (1)
108-113: 💤 Low valueConsider adding a Kimi column to the provider comparison table.
Now that Kimi is a first-class provider, the table only covers Claude vs Gemini. Adding a Kimi column would help users make an informed routing choice between all three options.
🤖 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 @.aiox-core/infrastructure/integrations/ai-providers/README.md around lines 108 - 113, Add a third "Kimi" column to the provider comparison table by updating the header row that currently lists "Claude" and "Gemini" and adding corresponding cells for each feature row ("Best for", "JSON output", "Cost", "SWE-bench"); ensure the table pipe counts and alignment (the separator row with dashes) are adjusted to include the new column and populate Kimi-specific values (e.g., "Best for", "JSON output", "Cost", "SWE-bench") consistent with the existing Claude and Gemini entries.
🤖 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 @.aiox-core/infrastructure/integrations/ai-providers/ai-provider-factory.js:
- Line 148: The current cache key construction in getProvider uses
JSON.stringify(config) and may embed sensitive fields (e.g., apiKey), so update
the cache key logic where cacheKey is built: create a sanitizedConfig by cloning
config and removing sensitive keys (at minimum "apiKey", "password", "token",
"secret") or alternatively whitelist allowed non-sensitive fields, then use
JSON.stringify(sanitizedConfig) together with normalizedName to form cacheKey
before accessing providerCache; ensure the change is applied in the same scope
where cacheKey is defined so providerCache keys never contain raw secrets.
In
@.aiox-core/infrastructure/integrations/ai-providers/openai-compatible-provider.js:
- Around line 41-51: The current spread of ...config into the options property
causes sensitive fields like config.apiKey and config.fetch to be persisted on
this.options (via AIProvider's this.options), risking secret leakage; remove the
catch-all spread and instead explicitly pass only safe, whitelisted fields
(e.g., model, headers, requestOptions, extraBody, messages, temperature,
maxTokens, topP, presencePenalty, frequencyPenalty, etc.) when constructing
options in openai-compatible-provider.js, ensuring you do not include apiKey,
fetch, or any other secret-bearing keys; update the constructor that sets
this.options and verify getInfo still omits sensitive data.
In @.aiox-core/product/templates/aiox-ai-config.yaml:
- Around line 82-91: The openai_compatible template currently points to real
OpenAI production values; replace those with unambiguous placeholders so users
must override them: change keys in the openai_compatible block (baseURL,
endpoint, apiKeyEnv, model, timeout/maxRetries if desired) to clearly
placeholder values (e.g. BASE_URL_PLACEHOLDER, ENDPOINT_PLACEHOLDER,
API_KEY_ENV_PLACEHOLDER, MODEL_PLACEHOLDER) and ensure the placeholder syntax
matches other .aiox-core/product/templates files so it’s obvious this config
must be customized before use.
In `@tests/core/subagent-dispatcher.test.js`:
- Around line 256-263: The test name claims configured fallbacks take precedence
but it instantiates SubagentDispatcher without any config; update the test to
either rename it to reflect legacy-only behavior or (preferred) add a case that
constructs SubagentDispatcher with an explicit ai_providers.fallback in the
config and assert SubagentDispatcher.getFallbackProviderName('kimi') returns
that configured value (verifying configured fallback wins over the legacy
claude↔gemini chain); also add or adjust a second assertion or a separate test
to surface the potential infinite retry cycle by checking
getFallbackProviderName('gemini') and getFallbackProviderName('claude') behavior
or confirming the dispatcher exposes a circuit-breaker mechanism to avoid
looping.
---
Nitpick comments:
In
@.aiox-core/infrastructure/integrations/ai-providers/openai-compatible-provider.js:
- Around line 256-269: In _readResponseBody, change the JSON branch so you await
response.json() instead of returning the raw Promise; specifically update the
branch in the _readResponseBody method that currently does return
response.json() to use await (and optionally wrap that await in the same
try/catch pattern used for the text path) so parsing failures are caught inside
_readResponseBody and preserve the local stack frame and error handling.
In @.aiox-core/infrastructure/integrations/ai-providers/README.md:
- Around line 108-113: Add a third "Kimi" column to the provider comparison
table by updating the header row that currently lists "Claude" and "Gemini" and
adding corresponding cells for each feature row ("Best for", "JSON output",
"Cost", "SWE-bench"); ensure the table pipe counts and alignment (the separator
row with dashes) are adjusted to include the new column and populate
Kimi-specific values (e.g., "Best for", "JSON output", "Cost", "SWE-bench")
consistent with the existing Claude and Gemini entries.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d4c9989f-1039-4e0f-b69a-7e45a84b8dd4
📒 Files selected for processing (13)
.aiox-core/core/execution/subagent-dispatcher.js.aiox-core/infrastructure/integrations/ai-providers/README.md.aiox-core/infrastructure/integrations/ai-providers/ai-provider-factory.js.aiox-core/infrastructure/integrations/ai-providers/ai-provider.js.aiox-core/infrastructure/integrations/ai-providers/index.js.aiox-core/infrastructure/integrations/ai-providers/openai-compatible-provider.js.aiox-core/install-manifest.yaml.aiox-core/product/templates/aiox-ai-config.yamldocs/stories/epic-184-kimi-provider/EPIC-184-KIMI-K2-5-PROVIDER.mddocs/stories/epic-184-kimi-provider/STORY-184.1-OPENAI-COMPATIBLE-KIMI-PROVIDER.mdtests/core/subagent-dispatcher.test.jstests/infrastructure/ai-providers/ai-provider-factory.test.jstests/infrastructure/ai-providers/openai-compatible-provider.test.js
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
Addressed CodeRabbit findings in commit 2e4447b and revalidated CI successfully.
Summary
Validation
Closes #184
Summary by CodeRabbit
New Features
Documentation
Tests