diff --git a/.changeset/cute-lines-pump.md b/.changeset/cute-lines-pump.md new file mode 100644 index 00000000000..460a52dd531 --- /dev/null +++ b/.changeset/cute-lines-pump.md @@ -0,0 +1,7 @@ +--- +"kilocode-docs": minor +"@kilocode/cli": minor +"kilo-code": minor +--- + +Add support for Claude Code Native integration. diff --git a/apps/kilocode-docs/docs/providers/claude-code-native.md b/apps/kilocode-docs/docs/providers/claude-code-native.md new file mode 100644 index 00000000000..befb16045c7 --- /dev/null +++ b/apps/kilocode-docs/docs/providers/claude-code-native.md @@ -0,0 +1,41 @@ +--- +sidebar_label: Claude Code Native +--- + +# Using Claude Code With Kilo Code + +Claude Code is Anthropic's official CLI that provides direct access to Claude models from your terminal. Using Claude Code with Kilo Code lets you leverage your existing CLI setup without needing separate API keys. This implementation uses an updated technique to speak directly to the Claude API, eliminating many of the downsides of the previous implementation. It is cache efficient, and token efficient. + +## Supported Models + +Kilo Code supports the following Claude models through Claude Code: + +- **Claude Opus 4.5** (Most capable) +- **Claude Sonnet 4.5** (Latest, recommended) +- **Claude 4.5 Haiku** (Fast responses) + +## Preparing to Configure + +1. Install `claude` using the Homebrew or 'native' [installation methods](https://claudelog.com/install-claude-code/): + +- macOS or Linux: `curl -fsSL https://claude.ai/install.sh | bash` +- macOS: `brew install --cask claude-code` +- Windows: `irm https://claude.ai/install.ps1 | iex` + +2. Login to `claude` and get a long lived token (good for one year): `claude setup-token` + +3. Record the token value - it will not be shown again. + +## Configuration in Kilo Code + +1. **Open Kilo Code Settings:** Click the gear icon () in the Kilo Code panel. +2. **Select Provider:** Choose "Claude Code Native" from the "API Provider" dropdown. +3. **Select Model:** Choose your desired Claude model from the "Model" dropdown. +4. **Enter your Token:** Using the token from recorded above, enter it as your API key +5. Use claude as normal! + +## Tips and Notes + +- **Advanced Reasoning:** Full support for Claude's thinking modes and reasoning capabilities when available. +- **Context Windows:** Claude models have large context windows, allowing you to include significant amounts of code and context in your prompts. +- **Enhance Prompt Feature:** Full compatibility with Kilo Code's Enhance Prompt feature, allowing you to automatically improve and refine your prompts before sending them to Claude. diff --git a/apps/kilocode-docs/sidebars.ts b/apps/kilocode-docs/sidebars.ts index 1b40ad47756..f755ea22c20 100644 --- a/apps/kilocode-docs/sidebars.ts +++ b/apps/kilocode-docs/sidebars.ts @@ -56,6 +56,7 @@ const sidebars: SidebarsConfig = { "providers/cerebras", // kilocode_change "providers/chutes-ai", "providers/claude-code", + "providers/claude-code-native", "providers/deepseek", "providers/fireworks", "providers/gemini", diff --git a/cli/src/constants/providers/labels.ts b/cli/src/constants/providers/labels.ts index 27e0b73e245..ccda98c6c88 100644 --- a/cli/src/constants/providers/labels.ts +++ b/cli/src/constants/providers/labels.ts @@ -13,6 +13,7 @@ export const PROVIDER_LABELS: Record = { gemini: "Google Gemini", vertex: "GCP Vertex AI", "claude-code": "Claude Code", + claudecodenative: "Claude Code Native", mistral: "Mistral", groq: "Groq", deepseek: "DeepSeek", diff --git a/cli/src/constants/providers/models.ts b/cli/src/constants/providers/models.ts index 20ba42460d1..6e9f447f9f5 100644 --- a/cli/src/constants/providers/models.ts +++ b/cli/src/constants/providers/models.ts @@ -43,6 +43,8 @@ import { rooDefaultModelId, claudeCodeModels, claudeCodeDefaultModelId, + claudecodenativeModels, + claudecodenativeDefaultModelId, geminiCliModels, geminiCliDefaultModelId, minimaxModels, @@ -158,6 +160,7 @@ export const PROVIDER_TO_ROUTER_NAME: Record = featherless: null, roo: null, "claude-code": null, + claudecodenative: null, "gemini-cli": null, "virtual-quota-fallback": null, huggingface: null, @@ -210,6 +213,7 @@ export const PROVIDER_MODEL_FIELD: Record = { featherless: null, roo: null, "claude-code": null, + claudecodenative: "apiModelId", "gemini-cli": null, "virtual-quota-fallback": null, huggingface: null, @@ -271,6 +275,7 @@ export const DEFAULT_MODEL_IDS: Partial> = { litellm: "gpt-4", "qwen-code": qwenCodeDefaultModelId, "claude-code": claudeCodeDefaultModelId, + claudecodenative: claudecodenativeDefaultModelId, doubao: doubaoDefaultModelId, fireworks: fireworksDefaultModelId, "io-intelligence": "deepseek-ai/DeepSeek-R1-0528", @@ -413,6 +418,11 @@ export function getModelsByProvider(params: { models: claudeCodeModels as ModelRecord, defaultModel: claudeCodeDefaultModelId, } + case "claudecodenative": + return { + models: claudecodenativeModels as ModelRecord, + defaultModel: claudecodenativeDefaultModelId, + } case "gemini-cli": return { models: geminiCliModels as ModelRecord, diff --git a/cli/src/constants/providers/settings.ts b/cli/src/constants/providers/settings.ts index f75af199fd1..bab24db4762 100644 --- a/cli/src/constants/providers/settings.ts +++ b/cli/src/constants/providers/settings.ts @@ -839,6 +839,13 @@ export const getProviderSettings = (provider: ProviderName, config: ProviderSett createFieldConfig("claudeCodeMaxOutputTokens", config, "8000"), ] + case "claudecodenative": + return [ + createFieldConfig("apiKey", config), + createFieldConfig("apiModelId", config, "claude-sonnet-4-5"), + createFieldConfig("anthropicBaseUrl", config, "Default"), + ] + case "mistral": return [ createFieldConfig("mistralApiKey", config), @@ -1059,6 +1066,7 @@ export const PROVIDER_DEFAULT_MODELS: Record = { gemini: "gemini-1.5-pro-latest", vertex: "claude-3-5-sonnet@20241022", "claude-code": "claude-3-5-sonnet-20241022", + claudecodenative: "claude-sonnet-4-5", mistral: "mistral-large-latest", groq: "llama-3.1-70b-versatile", deepseek: "deepseek-chat", diff --git a/cli/src/constants/providers/validation.ts b/cli/src/constants/providers/validation.ts index 27926585f08..6d67fe70fdd 100644 --- a/cli/src/constants/providers/validation.ts +++ b/cli/src/constants/providers/validation.ts @@ -14,6 +14,7 @@ export const PROVIDER_REQUIRED_FIELDS: Record = { bedrock: ["awsAccessKey", "awsSecretKey", "awsRegion", "apiModelId"], gemini: ["geminiApiKey", "apiModelId"], "claude-code": ["claudeCodePath", "apiModelId"], + claudecodenative: ["apiKey", "apiModelId"], mistral: ["mistralApiKey", "apiModelId"], groq: ["groqApiKey", "apiModelId"], deepseek: ["deepSeekApiKey", "apiModelId"], diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index bfb7e17b009..d9d7cfc7c39 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -29,6 +29,7 @@ import { xaiModels, internationalZAiModels, minimaxModels, + claudecodenativeModels, } from "./providers/index.js" /** @@ -162,6 +163,7 @@ export const providerNames = [ "vertex", "xai", "zai", + "claudecodenative", ] as const export const providerNamesSchema = z.enum(providerNames) @@ -226,6 +228,8 @@ const anthropicSchema = apiModelIdProviderModelSchema.extend({ anthropicBeta1MContext: z.boolean().optional(), // Enable 'context-1m-2025-08-07' beta for 1M context window. }) +const claudecodenativeSchema = anthropicSchema + const claudeCodeSchema = apiModelIdProviderModelSchema.extend({ claudeCodePath: z.string().optional(), claudeCodeMaxOutputTokens: z.number().int().min(1).max(200000).optional(), @@ -588,6 +592,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv rooSchema.merge(z.object({ apiProvider: z.literal("roo") })), vercelAiGatewaySchema.merge(z.object({ apiProvider: z.literal("vercel-ai-gateway") })), sapAiCoreSchema.merge(z.object({ apiProvider: z.literal("sap-ai-core") })), // kilocode_change + claudecodenativeSchema.merge(z.object({ apiProvider: z.literal("claudecodenative") })), defaultSchema, ]) @@ -640,6 +645,7 @@ export const providerSettingsSchema = z.object({ ...rooSchema.shape, ...vercelAiGatewaySchema.shape, ...sapAiCoreSchema.shape, // kilocode_change + ...claudecodenativeSchema.shape, ...codebaseIndexProviderSchema.shape, }) @@ -741,6 +747,7 @@ export const modelIdKeysByProvider: Record = { roo: "apiModelId", "vercel-ai-gateway": "vercelAiGatewayModelId", "virtual-quota-fallback": "apiModelId", + claudecodenative: "apiModelId", } /** @@ -748,7 +755,13 @@ export const modelIdKeysByProvider: Record = { */ // Providers that use Anthropic-style API protocol. -export const ANTHROPIC_STYLE_PROVIDERS: ProviderName[] = ["anthropic", "claude-code", "bedrock", "minimax"] +export const ANTHROPIC_STYLE_PROVIDERS: ProviderName[] = [ + "anthropic", + "claude-code", + "bedrock", + "minimax", + "claudecodenative", +] export const getApiProtocol = (provider: ProviderName | undefined, modelId?: string): "anthropic" | "openai" => { if (provider && ANTHROPIC_STYLE_PROVIDERS.includes(provider)) { @@ -894,4 +907,9 @@ export const MODELS_BY_PROVIDER: Record< // Local providers; models discovered from localhost endpoints. lmstudio: { id: "lmstudio", label: "LM Studio", models: [] }, ollama: { id: "ollama", label: "Ollama", models: [] }, + claudecodenative: { + id: "claudecodenative", + label: "Claude Code Native", + models: Object.keys(claudecodenativeModels), + }, } diff --git a/packages/types/src/providers/anthropic.ts b/packages/types/src/providers/anthropic.ts index b9ba3a09d84..91aaa38ec99 100644 --- a/packages/types/src/providers/anthropic.ts +++ b/packages/types/src/providers/anthropic.ts @@ -63,6 +63,19 @@ export const anthropicModels = { supportsReasoningBudget: true, supportsVerbosity: true, // kilocode_change }, + "claude-opus-4-5": { + maxTokens: 32_000, // Overridden to 8k if `enableReasoningEffort` is false. + contextWindow: 200_000, + supportsImages: true, + supportsPromptCache: true, + supportsNativeTools: true, + inputPrice: 5.0, // $5 per million input tokens + outputPrice: 25.0, // $25 per million output tokens + cacheWritesPrice: 6.25, // $6.25 per million tokens + cacheReadsPrice: 0.5, // $0.50 per million tokens + supportsReasoningBudget: true, + supportsVerbosity: true, // kilocode_change + }, "claude-opus-4-1-20250805": { maxTokens: 32_000, // Overridden to 8k if `enableReasoningEffort` is false. contextWindow: 200_000, @@ -170,6 +183,21 @@ export const anthropicModels = { description: "Claude Haiku 4.5 delivers near-frontier intelligence at lightning speeds with extended thinking, vision, and multilingual support.", }, + "claude-haiku-4-5": { + maxTokens: 64_000, + contextWindow: 200_000, + supportsImages: true, + supportsPromptCache: true, + supportsNativeTools: true, + defaultToolProtocol: "native", // kilocode_change + inputPrice: 1.0, + outputPrice: 5.0, + cacheWritesPrice: 1.25, + cacheReadsPrice: 0.1, + supportsReasoningBudget: true, + description: + "Claude Haiku 4.5 delivers near-frontier intelligence at lightning speeds with extended thinking, vision, and multilingual support.", + }, } as const satisfies Record export const ANTHROPIC_DEFAULT_MAX_TOKENS = 8192 diff --git a/packages/types/src/providers/claudecodenative.ts b/packages/types/src/providers/claudecodenative.ts new file mode 100644 index 00000000000..3b3bb511b01 --- /dev/null +++ b/packages/types/src/providers/claudecodenative.ts @@ -0,0 +1,11 @@ +import type { ModelInfo } from "../model.js" +import { anthropicModels } from "./anthropic.js" + +export type ClaudeCodeNativeModelId = keyof typeof claudecodenativeModels +export const claudecodenativeDefaultModelId: ClaudeCodeNativeModelId = "claude-sonnet-4-5" + +export const claudecodenativeModels = { + "claude-sonnet-4-5": anthropicModels["claude-sonnet-4-5"], + "claude-opus-4-5": anthropicModels["claude-opus-4-5"], + "claude-haiku-4-5": anthropicModels["claude-haiku-4-5"], +} as const satisfies Record diff --git a/packages/types/src/providers/index.ts b/packages/types/src/providers/index.ts index 95550d70474..fb1a13592bc 100644 --- a/packages/types/src/providers/index.ts +++ b/packages/types/src/providers/index.ts @@ -10,6 +10,7 @@ export * from "./featherless.js" export * from "./fireworks.js" export * from "./gemini.js" // kilocode_change start +export * from "./claudecodenative.js" export * from "./gemini-cli.js" export * from "./ovhcloud.js" export * from "./synthetic.js" @@ -71,6 +72,7 @@ import { vercelAiGatewayDefaultModelId } from "./vercel-ai-gateway.js" import { internationalZAiDefaultModelId, mainlandZAiDefaultModelId } from "./zai.js" import { deepInfraDefaultModelId } from "./deepinfra.js" import { minimaxDefaultModelId } from "./minimax.js" +import { claudecodenativeDefaultModelId } from "./claudecodenative.js" // Import the ProviderName type from provider-settings to avoid duplication import type { ProviderName } from "../provider-settings.js" @@ -155,6 +157,8 @@ export function getProviderDefaultModelId( return qwenCodeDefaultModelId case "vercel-ai-gateway": return vercelAiGatewayDefaultModelId + case "claudecodenative": + return claudecodenativeDefaultModelId case "anthropic": case "gemini-cli": case "human-relay": diff --git a/src/api/index.ts b/src/api/index.ts index 7bbac561cc1..33834cc7462 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -51,6 +51,7 @@ import { DeepInfraHandler, MiniMaxHandler, BasetenHandler, + ClaudeCodeNativeHandler, } from "./providers" // kilocode_change start import { KilocodeOpenrouterHandler } from "./providers/kilocode-openrouter" @@ -156,6 +157,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler { return new AnthropicHandler(options) case "claude-code": return new ClaudeCodeHandler(options) + case "claudecodenative": + return new ClaudeCodeNativeHandler(options) // kilocode_change start case "glama": return new GlamaHandler(options) diff --git a/src/api/providers/__tests__/claudecodenative.spec.ts b/src/api/providers/__tests__/claudecodenative.spec.ts new file mode 100644 index 00000000000..522a72d5387 --- /dev/null +++ b/src/api/providers/__tests__/claudecodenative.spec.ts @@ -0,0 +1,90 @@ +import { ClaudeCodeNativeHandler } from "../claudecodenative" +import { AnthropicHandler } from "../anthropic" +import { ApiHandlerOptions } from "../../../shared/api" +import { Anthropic } from "@anthropic-ai/sdk" + +const mockCreate = vitest.fn() + +vitest.mock("@anthropic-ai/sdk", () => { + return { + Anthropic: vitest.fn().mockImplementation(() => ({ + messages: { + create: mockCreate, + countTokens: vitest.fn(), + }, + })), + } +}) + +describe("ClaudeCodeNativeHandler", () => { + let handler: ClaudeCodeNativeHandler + let mockOptions: ApiHandlerOptions + + beforeEach(() => { + mockOptions = { + apiKey: "test-api-key", + apiModelId: "claude-3-5-sonnet-20241022", + } + handler = new ClaudeCodeNativeHandler(mockOptions) + mockCreate.mockClear() + }) + + it("should be an instance of AnthropicHandler", () => { + expect(handler).toBeInstanceOf(AnthropicHandler) + }) + + it("should be an instance of ClaudeCodeNativeHandler", () => { + expect(handler).toBeInstanceOf(ClaudeCodeNativeHandler) + }) + + it("should initialize with provided options", () => { + expect(handler.getModel().id).toBe(mockOptions.apiModelId) + }) + + it("should include the required system message", async () => { + const systemPrompt = "User provided system prompt" + const messages: Anthropic.Messages.MessageParam[] = [{ role: "user", content: "Hello" }] + + // Mock the stream response + mockCreate.mockResolvedValue({ + [Symbol.asyncIterator]: async function* () { + yield { type: "message_start", message: { usage: {} } } + yield { type: "message_stop" } + }, + }) + + const stream = handler.createMessage(systemPrompt, messages) + for await (const _ of stream) { + // Consume stream + } + + expect(mockCreate).toHaveBeenCalledWith( + expect.objectContaining({ + system: expect.arrayContaining([ + { + type: "text", + text: "You are Claude Code, Anthropic's official CLI for Claude.", + }, + expect.objectContaining({ + type: "text", + text: systemPrompt, + }), + ]), + }), + expect.anything(), + ) + + // Verify order: required message first + const callArgs = mockCreate.mock.calls[0][0] + expect(callArgs.system[0]).toEqual({ + type: "text", + text: "You are Claude Code, Anthropic's official CLI for Claude.", + }) + expect(callArgs.system[1]).toEqual( + expect.objectContaining({ + type: "text", + text: systemPrompt, + }), + ) + }) +}) diff --git a/src/api/providers/anthropic.ts b/src/api/providers/anthropic.ts index 6f931e6333a..a2cf75d625a 100644 --- a/src/api/providers/anthropic.ts +++ b/src/api/providers/anthropic.ts @@ -23,8 +23,8 @@ import { calculateApiCostAnthropic } from "../../shared/cost" import { convertOpenAIToolsToAnthropic, ToolCallAccumulatorAnthropic } from "./kilocode/nativeToolCallHelpers" export class AnthropicHandler extends BaseProvider implements SingleCompletionHandler { - private options: ApiHandlerOptions - private client: Anthropic + protected options: ApiHandlerOptions // kilocode_change + protected client: Anthropic // kilocode_change constructor(options: ApiHandlerOptions) { super() @@ -125,7 +125,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa temperature, thinking, // Setting cache breakpoint for system prompt so new tasks can reuse it. - system: [{ text: systemPrompt, type: "text", cache_control: cacheControl }], + system: this.getSystemPrompt(systemPrompt, cacheControl), //kilocode_change messages: sanitizedMessages.map((message, index) => { if (index === lastUserMsgIndex || index === secondLastMsgUserIndex) { return { @@ -186,7 +186,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa model: apiModelId, // kilocode_change max_tokens: maxTokens ?? ANTHROPIC_DEFAULT_MAX_TOKENS, temperature, - system: [{ text: systemPrompt, type: "text" }], + system: this.getSystemPrompt(systemPrompt), // kilocode_change messages: sanitizedMessages, stream: true, ...nativeToolParams, @@ -498,5 +498,19 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa return super.countTokens(content) } } + + protected getSystemPrompt( + systemPrompt: string, + cacheControl?: CacheControlEphemeral, + ): Anthropic.Messages.TextBlockParam[] { + const content: Anthropic.Messages.TextBlockParam = { + type: "text", + text: systemPrompt, + } + if (cacheControl) { + content.cache_control = cacheControl + } + return [content] + } // kilocode_change end } diff --git a/src/api/providers/claudecodenative.ts b/src/api/providers/claudecodenative.ts new file mode 100644 index 00000000000..5c00a5c8098 --- /dev/null +++ b/src/api/providers/claudecodenative.ts @@ -0,0 +1,40 @@ +import { Anthropic } from "@anthropic-ai/sdk" +import { CacheControlEphemeral } from "@anthropic-ai/sdk/resources" +import { AnthropicHandler } from "./anthropic" +import type { ApiHandlerOptions } from "../../shared/api" + +export class ClaudeCodeNativeHandler extends AnthropicHandler { + constructor(options: ApiHandlerOptions) { + // Force anthropicUseAuthToken to true so that the Anthropic SDK uses 'Authorization: Bearer' + // instead of 'x-api-key'. + // Also force anthropicDeploymentName to undefined to prevent using Azure/AWS deployments. + super({ + ...options, + anthropicUseAuthToken: true, + anthropicDeploymentName: undefined, + }) + + // Override the client with custom headers + this["client"] = new Anthropic({ + baseURL: options.anthropicBaseUrl || undefined, + authToken: options.apiKey, + defaultHeaders: { + "anthropic-beta": "oauth-2025-04-20", + "anthropic-version": "2023-06-01", + }, + }) + } + + protected override getSystemPrompt( + systemPrompt: string, + cacheControl?: CacheControlEphemeral, + ): Anthropic.Messages.TextBlockParam[] { + return [ + { + type: "text", + text: "You are Claude Code, Anthropic's official CLI for Claude.", + }, + ...super.getSystemPrompt(systemPrompt, cacheControl), + ] + } +} diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index aaf6f03171b..9d1563bd917 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -4,6 +4,7 @@ export { AwsBedrockHandler } from "./bedrock" export { CerebrasHandler } from "./cerebras" export { ChutesHandler } from "./chutes" export { ClaudeCodeHandler } from "./claude-code" +export { ClaudeCodeNativeHandler } from "./claudecodenative" export { DeepSeekHandler } from "./deepseek" export { DoubaoHandler } from "./doubao" export { MoonshotHandler } from "./moonshot" diff --git a/webview-ui/src/components/kilocode/hooks/useProviderModels.ts b/webview-ui/src/components/kilocode/hooks/useProviderModels.ts index ebe9e9bcbcf..3e6714a53cd 100644 --- a/webview-ui/src/components/kilocode/hooks/useProviderModels.ts +++ b/webview-ui/src/components/kilocode/hooks/useProviderModels.ts @@ -54,6 +54,8 @@ import { inceptionDefaultModelId, minimaxModels, minimaxDefaultModelId, + claudecodenativeModels, + claudecodenativeDefaultModelId, } from "@roo-code/types" import type { ModelRecord, RouterModels } from "@roo/api" import { useRouterModels } from "../../ui/hooks/useRouterModels" @@ -310,6 +312,12 @@ export const getModelsByProvider = ({ defaultModel: basetenDefaultModelId, } } + case "claudecodenative": { + return { + models: claudecodenativeModels, + defaultModel: claudecodenativeDefaultModelId, + } + } default: return { models: {}, diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index d978449e695..aaabd8321ab 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -83,6 +83,7 @@ import { Cerebras, Chutes, ClaudeCode, + ClaudeCodeNative, DeepSeek, Doubao, Gemini, @@ -391,6 +392,7 @@ const ApiOptions = ({ anthropic: { field: "apiModelId", default: anthropicDefaultModelId }, cerebras: { field: "apiModelId", default: cerebrasDefaultModelId }, "claude-code": { field: "apiModelId", default: claudeCodeDefaultModelId }, + claudecodenative: { field: "apiModelId", default: anthropicDefaultModelId }, "qwen-code": { field: "apiModelId", default: qwenCodeDefaultModelId }, "openai-native": { field: "apiModelId", default: openAiNativeDefaultModelId }, gemini: { field: "apiModelId", default: geminiDefaultModelId }, @@ -668,6 +670,14 @@ const ApiOptions = ({ /> )} + {selectedProvider === "claudecodenative" && ( + + )} + {selectedProvider === "openai-native" && ( >> = { @@ -53,6 +54,7 @@ export const MODELS_BY_PROVIDER: Partial a.label.localeCompare(b.label)) PROVIDERS.unshift({ value: "kilocode", label: "Kilo Gateway" }) // kilocode_change diff --git a/webview-ui/src/components/settings/providers/ClaudeCodeNative.tsx b/webview-ui/src/components/settings/providers/ClaudeCodeNative.tsx new file mode 100644 index 00000000000..c896da0514e --- /dev/null +++ b/webview-ui/src/components/settings/providers/ClaudeCodeNative.tsx @@ -0,0 +1,89 @@ +import { useCallback, useState } from "react" +import { Checkbox } from "vscrui" +import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" + +import type { ProviderSettings } from "@roo-code/types" + +import { useAppTranslation } from "@src/i18n/TranslationContext" +import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel" + +import { inputEventTransform } from "../transforms" + +type ClaudeCodeNativeProps = { + apiConfiguration: ProviderSettings + setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void + simplifySettings?: boolean +} + +export const ClaudeCodeNative = ({ apiConfiguration, setApiConfigurationField }: ClaudeCodeNativeProps) => { + const { t } = useAppTranslation() + const selectedModel = useSelectedModel(apiConfiguration) + + const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) + + // Check if the current model supports 1M context beta + const supports1MContextBeta = selectedModel?.id === "claude-sonnet-4-5" + + const handleInputChange = useCallback( + ( + field: K, + transform: (event: E) => ProviderSettings[K] = inputEventTransform, + ) => + (event: E | Event) => { + setApiConfigurationField(field, transform(event as E)) + }, + [setApiConfigurationField], + ) + + return ( + <> + + + +
+ {t("settings:providers.apiKeyStorageNotice")} +
+
+ { + setAnthropicBaseUrlSelected(checked) + + if (!checked) { + setApiConfigurationField("anthropicBaseUrl", "") + } + }}> + {t("settings:providers.useCustomBaseUrl")} + + {anthropicBaseUrlSelected && ( + + )} +
+ {supports1MContextBeta && ( +
+ { + setApiConfigurationField("anthropicBeta1MContext", checked) + }}> + {t("settings:providers.anthropic1MContextBetaLabel")} + +
+ {t("settings:providers.anthropic1MContextBetaDescription")} +
+
+ )} + + ) +} diff --git a/webview-ui/src/components/settings/providers/index.ts b/webview-ui/src/components/settings/providers/index.ts index 6af98e438fd..211152d8b5f 100644 --- a/webview-ui/src/components/settings/providers/index.ts +++ b/webview-ui/src/components/settings/providers/index.ts @@ -3,6 +3,7 @@ export { Bedrock } from "./Bedrock" export { Cerebras } from "./Cerebras" export { Chutes } from "./Chutes" export { ClaudeCode } from "./ClaudeCode" +export { ClaudeCodeNative } from "./ClaudeCodeNative" export { DeepSeek } from "./DeepSeek" export { Doubao } from "./Doubao" export { Gemini } from "./Gemini" diff --git a/webview-ui/src/components/ui/hooks/useSelectedModel.ts b/webview-ui/src/components/ui/hooks/useSelectedModel.ts index 99668eb74fc..91182059479 100644 --- a/webview-ui/src/components/ui/hooks/useSelectedModel.ts +++ b/webview-ui/src/components/ui/hooks/useSelectedModel.ts @@ -530,7 +530,14 @@ function getSelectedModel({ // case "human-relay": // case "fake-ai": default: { - provider satisfies "anthropic" | "gemini-cli" | "qwen-code" | "human-relay" | "fake-ai" | "kilocode" + provider satisfies + | "anthropic" + | "gemini-cli" + | "qwen-code" + | "human-relay" + | "fake-ai" + | "kilocode" + | "claudecodenative" const id = apiConfiguration.apiModelId ?? anthropicDefaultModelId const baseInfo = anthropicModels[id as keyof typeof anthropicModels] diff --git a/webview-ui/src/i18n/locales/ar/settings.json b/webview-ui/src/i18n/locales/ar/settings.json index 4bb57148c69..e825220782b 100644 --- a/webview-ui/src/i18n/locales/ar/settings.json +++ b/webview-ui/src/i18n/locales/ar/settings.json @@ -630,7 +630,8 @@ "description": "مسار CLI اختياري (الافتراضي 'claude').", "placeholder": "الافتراضي: claude", "maxTokensLabel": "أقصى توكنات المخرجات", - "maxTokensDescription": "الحد الأقصى لعدد توكنات المخرجات لردود Claude Code. الافتراضي هو 8000." + "maxTokensDescription": "الحد الأقصى لعدد توكنات المخرجات لردود Claude Code. الافتراضي هو 8000.", + "LongLivedToken": "رمز Claude Code طويل الأمد" }, "geminiCli": { "description": "يستخدم OAuth من أداة Gemini CLI ولا يحتاج مفاتيح.", diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index c7a1f577afe..ba31ec9f9e7 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -591,7 +591,8 @@ "description": "Ruta opcional al teu CLI de Claude Code. Per defecte, 'claude' si no s'estableix.", "placeholder": "Per defecte: claude", "maxTokensLabel": "Tokens màxims de sortida", - "maxTokensDescription": "Nombre màxim de tokens de sortida per a les respostes de Claude Code. El valor per defecte és 8000." + "maxTokensDescription": "Nombre màxim de tokens de sortida per a les respostes de Claude Code. El valor per defecte és 8000.", + "LongLivedToken": "Token de llarga durada de Claude Code" }, "geminiCli": { "description": "Aquest proveïdor utilitza l'autenticació OAuth de l'eina Gemini CLI i no requereix claus d'API.", diff --git a/webview-ui/src/i18n/locales/cs/settings.json b/webview-ui/src/i18n/locales/cs/settings.json index b30ef443623..339a2ea0ecb 100644 --- a/webview-ui/src/i18n/locales/cs/settings.json +++ b/webview-ui/src/i18n/locales/cs/settings.json @@ -621,7 +621,8 @@ "description": "Volitelná cesta k vašemu CLI Claude Code. Ve výchozím nastavení 'claude', pokud není nastaveno.", "placeholder": "Výchozí: claude", "maxTokensLabel": "Maximální počet výstupních tokenů", - "maxTokensDescription": "Maximální počet výstupních tokenů pro odpovědi Claude Code. Výchozí je 8000." + "maxTokensDescription": "Maximální počet výstupních tokenů pro odpovědi Claude Code. Výchozí je 8000.", + "LongLivedToken": "Dlouhodobý token Claude Code" }, "geminiCli": { "description": "Tento poskytovatel používá OAuth autentizaci z nástroje Gemini CLI a nevyžaduje klíče API.", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 9cce9de263a..f7762403816 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -600,7 +600,8 @@ "description": "Optionaler Pfad zu Ihrer Claude Code CLI. Standard ist 'claude', wenn nicht festgelegt.", "placeholder": "Standard: claude", "maxTokensLabel": "Maximale Ausgabe-Tokens", - "maxTokensDescription": "Maximale Anzahl an Ausgabe-Tokens für Claude Code-Antworten. Standard ist 8000." + "maxTokensDescription": "Maximale Anzahl an Ausgabe-Tokens für Claude Code-Antworten. Standard ist 8000.", + "LongLivedToken": "Claude Code Long Lived Token" }, "geminiCli": { "description": "Dieser Anbieter verwendet OAuth-Authentifizierung vom Gemini CLI-Tool und benötigt keine API-Schlüssel.", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 26e31178007..9868f021aaa 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -611,7 +611,8 @@ "description": "Optional path to your Claude Code CLI. Defaults to 'claude' if not set.", "placeholder": "Default: claude", "maxTokensLabel": "Max Output Tokens", - "maxTokensDescription": "Maximum number of output tokens for Claude Code responses. Default is 8000." + "maxTokensDescription": "Maximum number of output tokens for Claude Code responses. Default is 8000.", + "LongLivedToken": "Claude Code Long Lived Token" }, "geminiCli": { "description": "This provider uses OAuth authentication from the Gemini CLI tool and does not require API keys.", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index 96a2abd3c59..ee93c2d3122 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -574,7 +574,8 @@ "description": "Ruta opcional a su CLI de Claude Code. Por defecto, es 'claude' si no se establece.", "placeholder": "Por defecto: claude", "maxTokensLabel": "Tokens máximos de salida", - "maxTokensDescription": "Número máximo de tokens de salida para las respuestas de Claude Code. El valor predeterminado es 8000." + "maxTokensDescription": "Número máximo de tokens de salida para las respuestas de Claude Code. El valor predeterminado es 8000.", + "LongLivedToken": "Token de larga duración de Claude Code" }, "geminiCli": { "description": "Este proveedor usa autenticación OAuth de la herramienta Gemini CLI y no requiere claves API.", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index c713296abb9..f813479775b 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -574,7 +574,8 @@ "description": "Chemin facultatif vers votre CLI Claude Code. La valeur par défaut est 'claude' si non défini.", "placeholder": "Défaut : claude", "maxTokensLabel": "Jetons de sortie max", - "maxTokensDescription": "Nombre maximum de jetons de sortie pour les réponses de Claude Code. La valeur par défaut est 8000." + "maxTokensDescription": "Nombre maximum de jetons de sortie pour les réponses de Claude Code. La valeur par défaut est 8000.", + "LongLivedToken": "Jeton de longue durée Claude Code" }, "geminiCli": { "description": "Ce fournisseur utilise l'authentification OAuth de l'outil Gemini CLI et ne nécessite pas de clés API.", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 5f170c81e49..38afa9523cf 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -591,7 +591,8 @@ "description": "आपके क्लाउड कोड सीएलआई का वैकल्पिक पथ। यदि सेट नहीं है तो डिफ़ॉल्ट 'claude' है।", "placeholder": "डिफ़ॉल्ट: claude", "maxTokensLabel": "अधिकतम आउटपुट टोकन", - "maxTokensDescription": "Claude Code प्रतिक्रियाओं के लिए आउटपुट टोकन की अधिकतम संख्या। डिफ़ॉल्ट 8000 है।" + "maxTokensDescription": "Claude Code प्रतिक्रियाओं के लिए आउटपुट टोकन की अधिकतम संख्या। डिफ़ॉल्ट 8000 है।", + "LongLivedToken": "Claude Code लॉन्ग लिव्ड टोकन" }, "geminiCli": { "description": "यह प्रदाता Gemini CLI टूल से OAuth प्रमाणीकरण का उपयोग करता है और API कुंजियों की आवश्यकता नहीं है।", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 1f2969b257f..bb64c36e571 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -591,7 +591,8 @@ "description": "Jalur opsional ke Claude Code CLI Anda. Defaultnya adalah 'claude' jika tidak diatur.", "placeholder": "Default: claude", "maxTokensLabel": "Token Output Maks", - "maxTokensDescription": "Jumlah maksimum token output untuk respons Claude Code. Default adalah 8000." + "maxTokensDescription": "Jumlah maksimum token output untuk respons Claude Code. Default adalah 8000.", + "LongLivedToken": "Token Berumur Panjang Claude Code" }, "geminiCli": { "description": "Penyedia ini menggunakan autentikasi OAuth dari alat Gemini CLI dan tidak memerlukan kunci API.", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 70455bee4e5..809f3cf733d 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -601,7 +601,8 @@ "description": "Percorso facoltativo per la tua CLI Claude Code. Predefinito 'claude' se non impostato.", "placeholder": "Predefinito: claude", "maxTokensLabel": "Token di output massimi", - "maxTokensDescription": "Numero massimo di token di output per le risposte di Claude Code. Il valore predefinito è 8000." + "maxTokensDescription": "Numero massimo di token di output per le risposte di Claude Code. Il valore predefinito è 8000.", + "LongLivedToken": "Token a lunga durata Claude Code" }, "geminiCli": { "description": "Questo provider utilizza l'autenticazione OAuth dallo strumento Gemini CLI e non richiede chiavi API.", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index ccf1e2b664b..1853d6b0731 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -592,7 +592,8 @@ "description": "Claude Code CLIへのオプションパス。設定されていない場合、デフォルトは「claude」です。", "placeholder": "デフォルト:claude", "maxTokensLabel": "最大出力トークン", - "maxTokensDescription": "Claude Codeレスポンスの最大出力トークン数。デフォルトは8000です。" + "maxTokensDescription": "Claude Codeレスポンスの最大出力トークン数。デフォルトは8000です。", + "LongLivedToken": "Claude Code 長期トークン" }, "geminiCli": { "description": "このプロバイダーはGemini CLIツールからのOAuth認証を使用し、APIキーは必要ありません。", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 8f6079715ef..73f55c24d2a 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -591,7 +591,8 @@ "description": "Claude Code CLI의 선택적 경로입니다. 설정하지 않으면 'claude'가 기본값입니다.", "placeholder": "기본값: claude", "maxTokensLabel": "최대 출력 토큰", - "maxTokensDescription": "Claude Code 응답의 최대 출력 토큰 수. 기본값은 8000입니다." + "maxTokensDescription": "Claude Code 응답의 최대 출력 토큰 수. 기본값은 8000입니다.", + "LongLivedToken": "Claude Code 장기 토큰" }, "geminiCli": { "description": "이 공급자는 Gemini CLI 도구의 OAuth 인증을 사용하며 API 키가 필요하지 않습니다.", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 6e9e5d29768..40ce5bcffa6 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -591,7 +591,8 @@ "description": "Optioneel pad naar uw Claude Code CLI. Standaard 'claude' als niet ingesteld.", "placeholder": "Standaard: claude", "maxTokensLabel": "Max Output Tokens", - "maxTokensDescription": "Maximaal aantal output-tokens voor Claude Code-reacties. Standaard is 8000." + "maxTokensDescription": "Maximaal aantal output-tokens voor Claude Code-reacties. Standaard is 8000.", + "LongLivedToken": "Claude Code Long Lived Token" }, "geminiCli": { "description": "Deze provider gebruikt OAuth-authenticatie van de Gemini CLI-tool en vereist geen API-sleutels.", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index df1b606903e..434bee8c16f 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -591,7 +591,8 @@ "description": "Opcjonalna ścieżka do Twojego CLI Claude Code. Domyślnie 'claude', jeśli nie ustawiono.", "placeholder": "Domyślnie: claude", "maxTokensLabel": "Maksymalna liczba tokenów wyjściowych", - "maxTokensDescription": "Maksymalna liczba tokenów wyjściowych dla odpowiedzi Claude Code. Domyślnie 8000." + "maxTokensDescription": "Maksymalna liczba tokenów wyjściowych dla odpowiedzi Claude Code. Domyślnie 8000.", + "LongLivedToken": "Długotrwały token Claude Code" }, "geminiCli": { "description": "Ten dostawca używa uwierzytelniania OAuth z narzędzia Gemini CLI i nie wymaga kluczy API.", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 05254deeebe..42a98267e6b 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -565,7 +565,8 @@ "description": "Caminho opcional para o seu Claude Code CLI. O padrão é 'claude' se não for definido.", "placeholder": "Padrão: claude", "maxTokensLabel": "Tokens de saída máximos", - "maxTokensDescription": "Número máximo de tokens de saída para respostas do Claude Code. O padrão é 8000." + "maxTokensDescription": "Número máximo de tokens de saída para respostas do Claude Code. O padrão é 8000.", + "LongLivedToken": "Token de longa duração do Claude Code" }, "geminiCli": { "description": "Este provedor usa autenticação OAuth da ferramenta Gemini CLI e não requer chaves de API.", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 80f8af0d31f..d809e80e94e 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -591,7 +591,8 @@ "description": "Необязательный путь к вашему Claude Code CLI. По умолчанию используется 'claude', если не установлено.", "placeholder": "По умолчанию: claude", "maxTokensLabel": "Макс. выходных токенов", - "maxTokensDescription": "Максимальное количество выходных токенов для ответов Claude Code. По умолчанию 8000." + "maxTokensDescription": "Максимальное количество выходных токенов для ответов Claude Code. По умолчанию 8000.", + "LongLivedToken": "Долговечный токен Claude Code" }, "geminiCli": { "description": "Этот провайдер использует OAuth-аутентификацию из инструмента Gemini CLI и не требует API-ключей.", diff --git a/webview-ui/src/i18n/locales/th/settings.json b/webview-ui/src/i18n/locales/th/settings.json index 6920f3b78cf..95bff2a8c2f 100644 --- a/webview-ui/src/i18n/locales/th/settings.json +++ b/webview-ui/src/i18n/locales/th/settings.json @@ -589,7 +589,8 @@ "description": "เส้นทางที่ไม่บังคับไปยัง Claude Code CLI ของคุณ ค่าเริ่มต้นคือ 'claude' หากไม่ได้ตั้งค่า", "placeholder": "ค่าเริ่มต้น: claude", "maxTokensLabel": "โทเค็นเอาต์พุตสูงสุด", - "maxTokensDescription": "จำนวนโทเค็นเอาต์พุตสูงสุดสำหรับการตอบสนองของ Claude Code ค่าเริ่มต้นคือ 8000" + "maxTokensDescription": "จำนวนโทเค็นเอาต์พุตสูงสุดสำหรับการตอบสนองของ Claude Code ค่าเริ่มต้นคือ 8000", + "LongLivedToken": "โทเค็นอายุยืนของ Claude Code" }, "geminiCli": { "description": "ผู้ให้บริการนี้ใช้การยืนยันตัวตน OAuth จากเครื่องมือ Gemini CLI และไม่ต้องการกุญแจ API", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 03253251547..5a6c5071963 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -566,7 +566,8 @@ "description": "Claude Code CLI'nize isteğe bağlı yol. Ayarlanmazsa varsayılan olarak 'claude' kullanılır.", "placeholder": "Varsayılan: claude", "maxTokensLabel": "Maksimum Çıktı Token sayısı", - "maxTokensDescription": "Claude Code yanıtları için maksimum çıktı token sayısı. Varsayılan 8000'dir." + "maxTokensDescription": "Claude Code yanıtları için maksimum çıktı token sayısı. Varsayılan 8000'dir.", + "LongLivedToken": "Claude Code Uzun Ömürlü Token" }, "geminiCli": { "description": "Bu sağlayıcı Gemini CLI aracından OAuth kimlik doğrulaması kullanır ve API anahtarları gerektirmez.", diff --git a/webview-ui/src/i18n/locales/uk/settings.json b/webview-ui/src/i18n/locales/uk/settings.json index a64c5be61ca..9b3e4cd9f31 100644 --- a/webview-ui/src/i18n/locales/uk/settings.json +++ b/webview-ui/src/i18n/locales/uk/settings.json @@ -629,7 +629,8 @@ "description": "Необов'язковий шлях до вашого Claude Code CLI. За замовчуванням 'claude', якщо не встановлено.", "placeholder": "За замовчуванням: claude", "maxTokensLabel": "Макс. вихідних токенів", - "maxTokensDescription": "Максимальна кількість вихідних токенів для відповідей Claude Code. За замовчуванням 8000." + "maxTokensDescription": "Максимальна кількість вихідних токенів для відповідей Claude Code. За замовчуванням 8000.", + "LongLivedToken": "Довговічний токен Claude Code" }, "geminiCli": { "description": "Цей провайдер використовує OAuth-аутентифікацію інструменту Gemini CLI і не потребує API-ключів.", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index b7a24d909a8..2791bb76676 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -591,7 +591,8 @@ "description": "Đường dẫn tùy chọn đến Claude Code CLI của bạn. Mặc định là 'claude' nếu không được đặt.", "placeholder": "Mặc định: claude", "maxTokensLabel": "Số token đầu ra tối đa", - "maxTokensDescription": "Số lượng token đầu ra tối đa cho các phản hồi của Claude Code. Mặc định là 8000." + "maxTokensDescription": "Số lượng token đầu ra tối đa cho các phản hồi của Claude Code. Mặc định là 8000.", + "LongLivedToken": "Token Claude Code dài hạn" }, "geminiCli": { "description": "Nhà cung cấp này sử dụng xác thực OAuth từ công cụ Gemini CLI và không yêu cầu khóa API.", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index d4db3a3c159..31cfe2ebd0b 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -591,7 +591,8 @@ "description": "您的 Claude Code CLI 的可选路径。如果未设置,则默认为 “claude”。", "placeholder": "默认:claude", "maxTokensLabel": "最大输出 Token", - "maxTokensDescription": "Claude Code 响应的最大输出 Token 数量。默认为 8000。" + "maxTokensDescription": "Claude Code 响应的最大输出 Token 数量。默认为 8000。", + "LongLivedToken": "Claude Code 长期 Token" }, "geminiCli": { "description": "此提供商使用 Gemini CLI 工具的 OAuth 身份验证,不需要 API 密钥。", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 3303f9bc025..2db4065bf02 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -566,7 +566,8 @@ "description": "可選的 Claude Code CLI 路徑。如果未設定,則預設為 'claude'。", "placeholder": "預設:claude", "maxTokensLabel": "最大輸出 Token", - "maxTokensDescription": "Claude Code 回應的最大輸出 Token 數量。預設為 8000。" + "maxTokensDescription": "Claude Code 回應的最大輸出 Token 數量。預設為 8000。", + "LongLivedToken": "Claude Code 長期 Token" }, "geminiCli": { "description": "此供應商使用 Gemini CLI 工具的 OAuth 身份驗證,不需要 API 金鑰。",