Add Novita AI provider support#697
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (24)
✅ Files skipped from review due to trivial changes (18)
🚧 Files skipped from review as they are similar to previous changes (6)
📝 WalkthroughWalkthroughThis PR integrates Novita AI as a new provider across the full stack: type definitions (model registry, Zod schemas, secrets), API handler implementation and routing, CLI configuration and documentation, webview settings UI with 18-locale translations and validation, component unit tests, and a comprehensive VSCode E2E test suite with mock fixtures. ChangesNovita AI Provider Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 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 unit tests (beta)
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 |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 17
🤖 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 `@apps/cli/README.md`:
- Around line 79-80: The example documentation for Novita AI configuration is
incomplete because it exports the NOVITA_API_KEY environment variable but the
accompanying command example does not include the --provider novita flag
required to actually use Novita as the provider. Add the --provider novita flag
to the example command that follows the NOVITA_API_KEY export statement so users
understand they must specify the provider to use the Novita API key.
In `@webview-ui/src/i18n/locales/ca/settings.json`:
- Around line 411-413: The Catalan locale file contains three untranslated
English strings for Novita AI settings that need to be localized. Replace the
English values for the keys novitaApiKey, getNovitaApiKey, and novitaBaseUrl
with their proper Catalan translations to ensure Catalan users see consistent
localized UI text instead of mixed-language content.
In `@webview-ui/src/i18n/locales/de/settings.json`:
- Around line 411-413: The three Novita AI related strings in the German locale
file are currently in English instead of German. Translate the values for the
keys novitaApiKey, getNovitaApiKey, and novitaBaseUrl from English to their
appropriate German equivalents to ensure the German UI displays properly
localized labels.
In `@webview-ui/src/i18n/locales/es/settings.json`:
- Around line 411-413: The three Novita provider settings strings novitaApiKey,
getNovitaApiKey, and novitaBaseUrl in the Spanish localization file have English
values instead of Spanish translations. Translate each of these string values
from English to their appropriate Spanish equivalents to maintain consistent
localization across the settings.
In `@webview-ui/src/i18n/locales/fr/settings.json`:
- Around line 411-413: The French locale file contains three untranslated
English strings for Novita AI settings. In the fr/settings.json file, locate the
properties "novitaApiKey", "getNovitaApiKey", and "novitaBaseUrl" and replace
their English values with appropriate French translations. Ensure the
translations are contextually appropriate and consistent with the rest of the
French localization in the file.
In `@webview-ui/src/i18n/locales/hi/settings.json`:
- Around line 411-413: The three Novita provider strings (novitaApiKey,
getNovitaApiKey, and novitaBaseUrl) in the Hindi settings.json file are still in
English while neighboring provider entries are properly localized to Hindi.
Translate these three string values from English to their appropriate Hindi
equivalents to maintain consistency with the rest of the localized content in
the file.
In `@webview-ui/src/i18n/locales/id/settings.json`:
- Around line 411-413: The Indonesian locale file contains three Novita AI
settings labels (novitaApiKey, getNovitaApiKey, and novitaBaseUrl) with English
text values instead of Indonesian translations. Translate these three label
values from English to Indonesian to ensure consistency throughout the
Indonesian locale file and provide a cohesive user interface experience for
Indonesian users.
In `@webview-ui/src/i18n/locales/it/settings.json`:
- Around line 411-413: The values for the Novita provider keys (novitaApiKey,
getNovitaApiKey, and novitaBaseUrl) in the Italian locale file are currently in
English instead of Italian. Translate these three key-value pairs to Italian to
maintain consistency with the rest of the Italian settings locale file. Replace
the English text values for each of these keys with appropriate Italian
translations while keeping the key names unchanged.
In `@webview-ui/src/i18n/locales/ja/settings.json`:
- Around line 411-413: The Novita AI configuration strings (novitaApiKey,
getNovitaApiKey, and novitaBaseUrl) in the Japanese locale file
(ja/settings.json) are currently in English, which creates an inconsistent user
experience. Translate these three string values to Japanese to match the rest of
the Japanese locale while keeping the property keys unchanged.
In `@webview-ui/src/i18n/locales/ko/settings.json`:
- Around line 411-413: The three Novita provider label strings in the Korean
locale file have values in English instead of Korean, creating mixed-language
content. Translate the values for the keys novitaApiKey, getNovitaApiKey, and
novitaBaseUrl from English to Korean to maintain consistency with the rest of
the Korean settings locale file.
In `@webview-ui/src/i18n/locales/nl/settings.json`:
- Around line 411-413: Translate the three Novita AI related entries in the
Dutch locale file to Dutch. The keys "novitaApiKey", "getNovitaApiKey", and
"novitaBaseUrl" currently have English values in the nl/settings.json file, but
should be translated to Dutch to maintain consistency with the locale and
provide a seamless user experience for Dutch-speaking users. Replace each
English value with its appropriate Dutch translation.
In `@webview-ui/src/i18n/locales/pl/settings.json`:
- Around line 411-413: The Novita provider entries (novitaApiKey,
getNovitaApiKey, and novitaBaseUrl) in the Polish locale file are currently in
English, breaking locale consistency. Translate the values for these three
entries from English to Polish to maintain consistency with the rest of the
Polish settings locale file.
In `@webview-ui/src/i18n/locales/pt-BR/settings.json`:
- Around line 411-413: The Novita AI label values in the pt-BR locale file are
currently in English instead of Portuguese, causing mixed language display.
Translate the values for the keys novitaApiKey, getNovitaApiKey, and
novitaBaseUrl from English to their Portuguese (Brazil) equivalents to maintain
consistent localization throughout the settings interface.
In `@webview-ui/src/i18n/locales/ru/settings.json`:
- Around line 411-413: The Russian locale file (ru/settings.json) contains
English strings for the Novita provider labels in keys "novitaApiKey",
"getNovitaApiKey", and "novitaBaseUrl". These values need to be translated to
Russian to maintain consistency with other localized strings in the Russian UI.
Replace each English value with its appropriate Russian translation for these
three keys.
In `@webview-ui/src/i18n/locales/tr/settings.json`:
- Around line 411-413: The three Novita-related entries (novitaApiKey,
getNovitaApiKey, and novitaBaseUrl) in the Turkish locale file are currently in
English while the rest of the file is in Turkish. Translate these three string
values to Turkish to maintain consistency with the rest of the locale and
provide a proper localized user interface.
In `@webview-ui/src/i18n/locales/vi/settings.json`:
- Around line 411-413: The properties novitaApiKey, getNovitaApiKey, and
novitaBaseUrl in the Vietnamese locale file have English values instead of
Vietnamese translations. Translate each of these three property values from
English to their appropriate Vietnamese equivalents to maintain consistency with
the rest of the Vietnamese locale and ensure the settings panel displays
properly in Vietnamese.
In `@webview-ui/src/i18n/locales/zh-TW/settings.json`:
- Around line 438-440: In the zh-TW/settings.json locale file, the three new
Novita-related keys (novitaApiKey, getNovitaApiKey, and novitaBaseUrl) currently
have English string values instead of Traditional Chinese translations. Replace
the English values for each of these three keys with their appropriate
Traditional Chinese translations to maintain consistency with the rest of the
Traditional Chinese locale file.
🪄 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: 3bf02952-44d5-4692-9d81-6ac83e9c7ce8
📒 Files selected for processing (46)
README.mdapps/cli/README.mdapps/cli/src/lib/utils/__tests__/provider.test.tsapps/cli/src/lib/utils/provider.tsapps/cli/src/types/types.tsapps/vscode-e2e/AGENTS.mdapps/vscode-e2e/fixtures/novita.jsonapps/vscode-e2e/src/runTest.tsapps/vscode-e2e/src/suite/providers/novita.test.tspackages/types/src/__tests__/provider-settings.test.tspackages/types/src/global-settings.tspackages/types/src/provider-settings.tspackages/types/src/providers/index.tspackages/types/src/providers/novita.tssrc/api/index.tssrc/api/providers/__tests__/novita.spec.tssrc/api/providers/index.tssrc/api/providers/novita.tssrc/shared/ProfileValidator.tssrc/shared/__tests__/ProfileValidator.spec.tswebview-ui/src/components/settings/ApiOptions.tsxwebview-ui/src/components/settings/constants.tswebview-ui/src/components/settings/providers/Novita.tsxwebview-ui/src/components/settings/providers/index.tswebview-ui/src/components/settings/utils/providerModelConfig.tswebview-ui/src/components/ui/hooks/useSelectedModel.tswebview-ui/src/i18n/locales/ca/settings.jsonwebview-ui/src/i18n/locales/de/settings.jsonwebview-ui/src/i18n/locales/en/settings.jsonwebview-ui/src/i18n/locales/es/settings.jsonwebview-ui/src/i18n/locales/fr/settings.jsonwebview-ui/src/i18n/locales/hi/settings.jsonwebview-ui/src/i18n/locales/id/settings.jsonwebview-ui/src/i18n/locales/it/settings.jsonwebview-ui/src/i18n/locales/ja/settings.jsonwebview-ui/src/i18n/locales/ko/settings.jsonwebview-ui/src/i18n/locales/nl/settings.jsonwebview-ui/src/i18n/locales/pl/settings.jsonwebview-ui/src/i18n/locales/pt-BR/settings.jsonwebview-ui/src/i18n/locales/ru/settings.jsonwebview-ui/src/i18n/locales/tr/settings.jsonwebview-ui/src/i18n/locales/vi/settings.jsonwebview-ui/src/i18n/locales/zh-CN/settings.jsonwebview-ui/src/i18n/locales/zh-TW/settings.jsonwebview-ui/src/utils/__tests__/validate.spec.tswebview-ui/src/utils/validate.ts
f761431 to
9024681
Compare
9024681 to
dbb482a
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@apps/vscode-e2e/src/suite/providers/novita.test.ts`:
- Around line 184-187: The setConfiguration call for the novita provider needs
to guard against undefined API keys when in record mode with AIMOCK_URL. The
current logic uses NOVITA_API_KEY! without ensuring it's defined; update the
novitaApiKey assignment to check that NOVITA_API_KEY exists before using it, or
skip the configuration entirely if it's absent. Additionally, apply the same
defensive check to any teardown configuration that uses OPENROUTER_API_KEY to
avoid passing undefined environment variables into the teardown.
- Around line 323-326: The assertion in the Novita test is too permissive
because it allows result.completionText to be missing or empty via the
`!result.completionText ||` condition. Remove the `!result.completionText ||`
portion and require that result.completionText strictly equals the marker
variable, ensuring the test validates that the expected final marker is actually
returned instead of passing when the completion is missing.
- Around line 247-249: The filter condition for requests in the
requests.filter() call is too permissive by allowing requests without a probeTag
through the condition `!request.probeTag || request.probeTag === probeTag`. This
can include stale or background requests from previous tests. Remove the
`!request.probeTag ||` part from the filter condition so that only requests with
a probeTag matching the current probeTag are included, changing the condition to
strictly check `request.model === modelId && request.probeTag === probeTag`.
🪄 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: 7691b242-0238-4ad8-8b3b-b4ee575ef110
📒 Files selected for processing (48)
README.mdapps/cli/README.mdapps/cli/src/lib/utils/__tests__/provider.test.tsapps/cli/src/lib/utils/provider.tsapps/cli/src/types/types.tsapps/vscode-e2e/AGENTS.mdapps/vscode-e2e/fixtures/novita.jsonapps/vscode-e2e/src/runTest.tsapps/vscode-e2e/src/suite/providers/novita.test.tspackages/types/src/__tests__/provider-settings.test.tspackages/types/src/global-settings.tspackages/types/src/provider-settings.tspackages/types/src/providers/index.tspackages/types/src/providers/novita.tssrc/api/index.tssrc/api/providers/__tests__/novita.spec.tssrc/api/providers/index.tssrc/api/providers/novita.tssrc/shared/ProfileValidator.tssrc/shared/__tests__/ProfileValidator.spec.tswebview-ui/src/components/settings/ApiOptions.tsxwebview-ui/src/components/settings/constants.tswebview-ui/src/components/settings/providers/Novita.tsxwebview-ui/src/components/settings/providers/__tests__/Novita.spec.tsxwebview-ui/src/components/settings/providers/index.tswebview-ui/src/components/settings/utils/providerModelConfig.tswebview-ui/src/components/ui/hooks/__tests__/useSelectedModel.spec.tswebview-ui/src/components/ui/hooks/useSelectedModel.tswebview-ui/src/i18n/locales/ca/settings.jsonwebview-ui/src/i18n/locales/de/settings.jsonwebview-ui/src/i18n/locales/en/settings.jsonwebview-ui/src/i18n/locales/es/settings.jsonwebview-ui/src/i18n/locales/fr/settings.jsonwebview-ui/src/i18n/locales/hi/settings.jsonwebview-ui/src/i18n/locales/id/settings.jsonwebview-ui/src/i18n/locales/it/settings.jsonwebview-ui/src/i18n/locales/ja/settings.jsonwebview-ui/src/i18n/locales/ko/settings.jsonwebview-ui/src/i18n/locales/nl/settings.jsonwebview-ui/src/i18n/locales/pl/settings.jsonwebview-ui/src/i18n/locales/pt-BR/settings.jsonwebview-ui/src/i18n/locales/ru/settings.jsonwebview-ui/src/i18n/locales/tr/settings.jsonwebview-ui/src/i18n/locales/vi/settings.jsonwebview-ui/src/i18n/locales/zh-CN/settings.jsonwebview-ui/src/i18n/locales/zh-TW/settings.jsonwebview-ui/src/utils/__tests__/validate.spec.tswebview-ui/src/utils/validate.ts
✅ Files skipped from review due to trivial changes (22)
- src/api/providers/index.ts
- webview-ui/src/i18n/locales/nl/settings.json
- webview-ui/src/i18n/locales/fr/settings.json
- webview-ui/src/i18n/locales/ko/settings.json
- webview-ui/src/i18n/locales/ca/settings.json
- webview-ui/src/components/settings/providers/index.ts
- webview-ui/src/i18n/locales/pt-BR/settings.json
- webview-ui/src/i18n/locales/ja/settings.json
- webview-ui/src/i18n/locales/zh-CN/settings.json
- webview-ui/src/i18n/locales/hi/settings.json
- webview-ui/src/i18n/locales/ru/settings.json
- apps/cli/README.md
- webview-ui/src/i18n/locales/pl/settings.json
- webview-ui/src/i18n/locales/vi/settings.json
- README.md
- webview-ui/src/i18n/locales/zh-TW/settings.json
- webview-ui/src/i18n/locales/it/settings.json
- webview-ui/src/i18n/locales/en/settings.json
- webview-ui/src/i18n/locales/es/settings.json
- webview-ui/src/i18n/locales/de/settings.json
- webview-ui/src/i18n/locales/id/settings.json
- webview-ui/src/i18n/locales/tr/settings.json
🚧 Files skipped from review as they are similar to previous changes (21)
- webview-ui/src/components/settings/constants.ts
- webview-ui/src/utils/validate.ts
- webview-ui/src/utils/tests/validate.spec.ts
- packages/types/src/tests/provider-settings.test.ts
- packages/types/src/providers/novita.ts
- src/api/providers/tests/novita.spec.ts
- packages/types/src/global-settings.ts
- apps/vscode-e2e/src/runTest.ts
- webview-ui/src/components/settings/ApiOptions.tsx
- src/shared/ProfileValidator.ts
- webview-ui/src/components/settings/providers/Novita.tsx
- src/api/index.ts
- src/shared/tests/ProfileValidator.spec.ts
- apps/cli/src/lib/utils/provider.ts
- packages/types/src/providers/index.ts
- webview-ui/src/components/settings/utils/providerModelConfig.ts
- webview-ui/src/components/ui/hooks/useSelectedModel.ts
- src/api/providers/novita.ts
- packages/types/src/provider-settings.ts
- apps/cli/src/types/types.ts
- apps/vscode-e2e/AGENTS.md
| await api.setConfiguration({ | ||
| apiProvider: "novita" as const, | ||
| novitaApiKey: aimockUrl && !isRecord ? "mock-key" : NOVITA_API_KEY!, | ||
| ...(aimockUrl && { novitaBaseUrl: `${aimockUrl}/v1` }), |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Guard the record/live key paths before configuring providers.
Record mode with AIMOCK_URL still needs a real Novita key, but the current setup() does not skip that case and line 186 can pass undefined. Also avoid passing OPENROUTER_API_KEY! into teardown when the env var is absent.
Based on learnings, “Record mode uses record-on-miss: if an existing fixture already matches a request, aimock serves it and does not re-record. Only unmatched requests are proxied to the real API and saved as openai-*.json files.”
🛠️ Proposed fix
setup(function () {
- if (!process.env.AIMOCK_URL && !NOVITA_API_KEY) {
+ const needsRealNovitaKey = process.env.AIMOCK_RECORD === "true" || !process.env.AIMOCK_URL
+
+ if (needsRealNovitaKey && !NOVITA_API_KEY) {
this.skip()
}
})
@@
const aimockUrl = process.env.AIMOCK_URL
const isRecord = process.env.AIMOCK_RECORD === "true"
+ const openRouterApiKey = aimockUrl
+ ? isRecord
+ ? (process.env.OPENROUTER_API_KEY ?? "mock-key")
+ : "mock-key"
+ : process.env.OPENROUTER_API_KEY
+
await globalThis.api.setConfiguration({
apiProvider: "openrouter" as const,
- openRouterApiKey: aimockUrl
- ? isRecord
- ? (process.env.OPENROUTER_API_KEY ?? "mock-key")
- : "mock-key"
- : process.env.OPENROUTER_API_KEY!,
+ ...(openRouterApiKey && { openRouterApiKey }),
openRouterModelId: "openai/gpt-4.1",
...(aimockUrl && { openRouterBaseUrl: `${aimockUrl}/v1` }),
})Also applies to: 277-305
🤖 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 `@apps/vscode-e2e/src/suite/providers/novita.test.ts` around lines 184 - 187,
The setConfiguration call for the novita provider needs to guard against
undefined API keys when in record mode with AIMOCK_URL. The current logic uses
NOVITA_API_KEY! without ensuring it's defined; update the novitaApiKey
assignment to check that NOVITA_API_KEY exists before using it, or skip the
configuration entirely if it's absent. Additionally, apply the same defensive
check to any teardown configuration that uses OPENROUTER_API_KEY to avoid
passing undefined environment variables into the teardown.
Source: Learnings
| requests: requests.filter( | ||
| (request) => request.model === modelId && (!request.probeTag || request.probeTag === probeTag), | ||
| ), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Filter captured requests strictly to this probe tag.
Allowing !request.probeTag can include untagged background or stale same-model requests in firstRequest. Since the prompt injects novita-e2e:tool-use, keep assertions scoped to that tag.
As per coding guidelines, “In provider tests using fetch interceptors, scope request-shape assertions to the current probe or test tag only; do not pull in older requests from previous tests.”
🛠️ Proposed fix
- requests: requests.filter(
- (request) => request.model === modelId && (!request.probeTag || request.probeTag === probeTag),
- ),
+ requests: requests.filter((request) => request.model === modelId && request.probeTag === probeTag),🤖 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 `@apps/vscode-e2e/src/suite/providers/novita.test.ts` around lines 247 - 249,
The filter condition for requests in the requests.filter() call is too
permissive by allowing requests without a probeTag through the condition
`!request.probeTag || request.probeTag === probeTag`. This can include stale or
background requests from previous tests. Remove the `!request.probeTag ||` part
from the filter condition so that only requests with a probeTag matching the
current probeTag are included, changing the condition to strictly check
`request.model === modelId && request.probeTag === probeTag`.
Source: Coding guidelines
| assert.ok( | ||
| !result.completionText || result.completionText === marker, | ||
| `Novita should not return an incorrect marker.\n${diagnostics}`, | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Require the final marker instead of allowing a missing completion.
!result.completionText || ... lets the test pass without verifying the expected final answer. The probe asks for the exact marker, so assert that directly.
🛠️ Proposed fix
- assert.ok(
- !result.completionText || result.completionText === marker,
- `Novita should not return an incorrect marker.\n${diagnostics}`,
- )
+ assert.strictEqual(
+ result.completionText,
+ marker,
+ `Novita should return the exact marker.\n${diagnostics}`,
+ )🤖 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 `@apps/vscode-e2e/src/suite/providers/novita.test.ts` around lines 323 - 326,
The assertion in the Novita test is too permissive because it allows
result.completionText to be missing or empty via the `!result.completionText ||`
condition. Remove the `!result.completionText ||` portion and require that
result.completionText strictly equals the marker variable, ensuring the test
validates that the expected final marker is actually returned instead of passing
when the completion is missing.
Summary
--provider novitaandNOVITA_API_KEYTesting
git diff --checkvitest packages/types/src/__tests__/provider-settings.test.tsvitest apps/cli/src/lib/utils/__tests__/provider.test.tsvitest webview-ui/src/utils/__tests__/validate.spec.tsvitest src/shared/__tests__/ProfileValidator.spec.ts src/api/providers/__tests__/novita.spec.tstsc -p apps/vscode-e2e/tsconfig.esm.json --noEmitmoonshotai/kimi-k2.7-codeSummary by CodeRabbit
Release Notes