From 0f029f960a835f307f045eb9b7e01b448d4b539e Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Sun, 21 Dec 2025 22:27:36 -0500 Subject: [PATCH] feat(ui): integrate Kiro and Copilot providers, rename to CLIProxy Plus - Rename sidebar/header from CLIProxy to CLIProxy Plus - Add Kiro and Copilot to all provider lists and type unions - Add provider logos and color configs - Add model catalogs with upstream CLIProxyAPIPlus models - Update Quick Setup Wizard with new providers --- .../components/cliproxy/cliproxy-dialog.tsx | 4 +- .../components/cliproxy/cliproxy-header.tsx | 7 +- .../cliproxy/provider-editor/index.tsx | 2 + ui/src/components/cliproxy/provider-logo.tsx | 4 + ui/src/components/layout/app-sidebar.tsx | 2 +- ui/src/components/setup/wizard/constants.ts | 2 + ui/src/lib/api-client.ts | 8 +- ui/src/lib/model-catalogs.ts | 115 ++++++++++++++++++ ui/src/lib/provider-config.ts | 6 + ui/src/lib/utils.ts | 2 + ui/src/pages/cliproxy.tsx | 2 +- 11 files changed, 143 insertions(+), 11 deletions(-) diff --git a/ui/src/components/cliproxy/cliproxy-dialog.tsx b/ui/src/components/cliproxy/cliproxy-dialog.tsx index f699305d..cd01df4f 100644 --- a/ui/src/components/cliproxy/cliproxy-dialog.tsx +++ b/ui/src/components/cliproxy/cliproxy-dialog.tsx @@ -14,7 +14,7 @@ import { Label } from '@/components/ui/label'; import { useCreateVariant, useCliproxyAuth } from '@/hooks/use-cliproxy'; import { usePrivacy } from '@/contexts/privacy-context'; -const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow'] as const; +const providers = ['gemini', 'codex', 'agy', 'qwen', 'iflow', 'kiro', 'copilot'] as const; const schema = z.object({ name: z @@ -39,6 +39,8 @@ const providerOptions = [ { value: 'agy', label: 'Antigravity' }, { value: 'qwen', label: 'Alibaba Qwen' }, { value: 'iflow', label: 'iFlow' }, + { value: 'kiro', label: 'Kiro (AWS)' }, + { value: 'copilot', label: 'GitHub Copilot' }, ]; export function CliproxyDialog({ open, onClose }: CliproxyDialogProps) { diff --git a/ui/src/components/cliproxy/cliproxy-header.tsx b/ui/src/components/cliproxy/cliproxy-header.tsx index c610c60c..790e58c8 100644 --- a/ui/src/components/cliproxy/cliproxy-header.tsx +++ b/ui/src/components/cliproxy/cliproxy-header.tsx @@ -116,6 +116,7 @@ export function CliproxyHeader({ { id: 'gemini', displayName: 'Gemini' }, { id: 'codex', displayName: 'Codex' }, { id: 'agy', displayName: 'Agy' }, + { id: 'kiro', displayName: 'Kiro' }, ]; const getProviderStatus = (providerId: string) => { @@ -131,10 +132,8 @@ export function CliproxyHeader({ {/* Top row: Title and Login Buttons */}
-

CLIProxy

-

- Manage OAuth providers and configuration -

+

CLIProxy Plus

+

CCS-level account management

{/* Login Buttons - Wrap on mobile */} diff --git a/ui/src/components/cliproxy/provider-editor/index.tsx b/ui/src/components/cliproxy/provider-editor/index.tsx index a153dbbd..69af143f 100644 --- a/ui/src/components/cliproxy/provider-editor/index.tsx +++ b/ui/src/components/cliproxy/provider-editor/index.tsx @@ -54,6 +54,8 @@ export function ProviderEditor({ codex: ['openai'], qwen: ['alibaba', 'qwen'], iflow: ['iflow'], + kiro: ['kiro', 'aws'], + copilot: ['github', 'copilot'], }; const owners = ownerMap[provider.toLowerCase()] || [provider.toLowerCase()]; return modelsData.models.filter((m) => diff --git a/ui/src/components/cliproxy/provider-logo.tsx b/ui/src/components/cliproxy/provider-logo.tsx index 3c7bb486..683ef8ba 100644 --- a/ui/src/components/cliproxy/provider-logo.tsx +++ b/ui/src/components/cliproxy/provider-logo.tsx @@ -18,6 +18,8 @@ const PROVIDER_IMAGES: Record = { agy: '/assets/providers/agy.png', qwen: '/assets/providers/qwen-color.svg', iflow: '/assets/providers/iflow.png', + kiro: '/assets/providers/kiro.png', + copilot: '/assets/providers/copilot.svg', }; /** Provider color configuration (for fallback only - no background for image logos) */ @@ -28,6 +30,8 @@ const PROVIDER_CONFIG: Record = { agy: { text: 'text-violet-600', letter: 'A' }, qwen: { text: 'text-cyan-600', letter: 'Q' }, iflow: { text: 'text-indigo-600', letter: 'i' }, + kiro: { text: 'text-teal-600', letter: 'K' }, + copilot: { text: 'text-green-600', letter: 'C' }, }; /** Size configuration */ diff --git a/ui/src/components/layout/app-sidebar.tsx b/ui/src/components/layout/app-sidebar.tsx index 6aeaac7b..bd5b489a 100644 --- a/ui/src/components/layout/app-sidebar.tsx +++ b/ui/src/components/layout/app-sidebar.tsx @@ -54,7 +54,7 @@ const navGroups = [ { path: '/cliproxy', icon: Zap, - label: 'CLIProxy', + label: 'CLIProxy Plus', isCollapsible: true, children: [ { path: '/cliproxy', label: 'Overview' }, diff --git a/ui/src/components/setup/wizard/constants.ts b/ui/src/components/setup/wizard/constants.ts index 6ac80cff..bef68bcb 100644 --- a/ui/src/components/setup/wizard/constants.ts +++ b/ui/src/components/setup/wizard/constants.ts @@ -10,6 +10,8 @@ export const PROVIDERS: ProviderOption[] = [ { id: 'agy', name: 'Antigravity', description: 'Antigravity AI models' }, { id: 'qwen', name: 'Alibaba Qwen', description: 'Qwen Code models' }, { id: 'iflow', name: 'iFlow', description: 'iFlow AI models' }, + { id: 'kiro', name: 'Kiro (AWS)', description: 'AWS CodeWhisperer models' }, + { id: 'copilot', name: 'GitHub Copilot', description: 'GitHub Copilot models' }, ]; export const ALL_STEPS = ['provider', 'auth', 'variant', 'success']; diff --git a/ui/src/lib/api-client.ts b/ui/src/lib/api-client.ts index 840965cc..ea699f8e 100644 --- a/ui/src/lib/api-client.ts +++ b/ui/src/lib/api-client.ts @@ -47,20 +47,20 @@ export interface UpdateProfile { export interface Variant { name: string; - provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; + provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot'; settings: string; account?: string; } export interface CreateVariant { name: string; - provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; + provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot'; model?: string; account?: string; } export interface UpdateVariant { - provider?: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; + provider?: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot'; model?: string; account?: string; } @@ -69,7 +69,7 @@ export interface UpdateVariant { export interface OAuthAccount { id: string; email?: string; - provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow'; + provider: 'gemini' | 'codex' | 'agy' | 'qwen' | 'iflow' | 'kiro' | 'copilot'; isDefault: boolean; tokenFile: string; createdAt: string; diff --git a/ui/src/lib/model-catalogs.ts b/ui/src/lib/model-catalogs.ts index 06f78c71..70edf061 100644 --- a/ui/src/lib/model-catalogs.ts +++ b/ui/src/lib/model-catalogs.ts @@ -151,4 +151,119 @@ export const MODEL_CATALOGS: Record = { }, ], }, + kiro: { + provider: 'kiro', + displayName: 'Kiro (AWS)', + defaultModel: 'kiro-claude-sonnet-4-5', + models: [ + { + id: 'kiro-claude-opus-4-5', + name: 'Kiro Claude Opus 4.5', + description: 'Claude Opus 4.5 via Kiro (2.2x credit)', + presetMapping: { + default: 'kiro-claude-opus-4-5', + opus: 'kiro-claude-opus-4-5', + sonnet: 'kiro-claude-sonnet-4-5', + haiku: 'kiro-claude-haiku-4-5', + }, + }, + { + id: 'kiro-claude-sonnet-4-5', + name: 'Kiro Claude Sonnet 4.5', + description: 'Claude Sonnet 4.5 via Kiro (1.3x credit)', + presetMapping: { + default: 'kiro-claude-sonnet-4-5', + opus: 'kiro-claude-opus-4-5', + sonnet: 'kiro-claude-sonnet-4-5', + haiku: 'kiro-claude-haiku-4-5', + }, + }, + { + id: 'kiro-claude-sonnet-4', + name: 'Kiro Claude Sonnet 4', + description: 'Claude Sonnet 4 via Kiro (1.3x credit)', + presetMapping: { + default: 'kiro-claude-sonnet-4', + opus: 'kiro-claude-opus-4-5', + sonnet: 'kiro-claude-sonnet-4', + haiku: 'kiro-claude-haiku-4-5', + }, + }, + { + id: 'kiro-claude-haiku-4-5', + name: 'Kiro Claude Haiku 4.5', + description: 'Claude Haiku 4.5 via Kiro (0.4x credit)', + }, + ], + }, + copilot: { + provider: 'copilot', + displayName: 'GitHub Copilot', + defaultModel: 'claude-sonnet-4.5', + models: [ + { + id: 'claude-opus-4.5', + name: 'Claude Opus 4.5', + description: 'Anthropic Claude Opus 4.5 via GitHub Copilot', + presetMapping: { + default: 'claude-opus-4.5', + opus: 'claude-opus-4.5', + sonnet: 'claude-sonnet-4.5', + haiku: 'claude-haiku-4.5', + }, + }, + { + id: 'claude-sonnet-4.5', + name: 'Claude Sonnet 4.5', + description: 'Anthropic Claude Sonnet 4.5 via GitHub Copilot', + presetMapping: { + default: 'claude-sonnet-4.5', + opus: 'claude-opus-4.5', + sonnet: 'claude-sonnet-4.5', + haiku: 'claude-haiku-4.5', + }, + }, + { + id: 'claude-sonnet-4', + name: 'Claude Sonnet 4', + description: 'Anthropic Claude Sonnet 4 via GitHub Copilot', + }, + { + id: 'claude-haiku-4.5', + name: 'Claude Haiku 4.5', + description: 'Anthropic Claude Haiku 4.5 via GitHub Copilot', + }, + { + id: 'gpt-5.2', + name: 'GPT-5.2', + description: 'OpenAI GPT-5.2 via GitHub Copilot', + presetMapping: { + default: 'gpt-5.2', + opus: 'gpt-5.2', + sonnet: 'gpt-5.1', + haiku: 'gpt-5-mini', + }, + }, + { + id: 'gpt-5.1', + name: 'GPT-5.1', + description: 'OpenAI GPT-5.1 via GitHub Copilot', + }, + { + id: 'gpt-5', + name: 'GPT-5', + description: 'OpenAI GPT-5 via GitHub Copilot', + }, + { + id: 'gpt-5-mini', + name: 'GPT-5 Mini', + description: 'OpenAI GPT-5 Mini via GitHub Copilot', + }, + { + id: 'gemini-3-pro', + name: 'Gemini 3 Pro', + description: 'Google Gemini 3 Pro via GitHub Copilot', + }, + ], + }, }; diff --git a/ui/src/lib/provider-config.ts b/ui/src/lib/provider-config.ts index 299e8145..52d494d5 100644 --- a/ui/src/lib/provider-config.ts +++ b/ui/src/lib/provider-config.ts @@ -9,6 +9,8 @@ export const PROVIDER_ASSETS: Record = { agy: '/assets/providers/agy.png', codex: '/assets/providers/openai.svg', qwen: '/assets/providers/qwen-color.svg', + kiro: '/assets/providers/kiro.png', + copilot: '/assets/providers/copilot.svg', }; // Provider brand colors @@ -19,6 +21,8 @@ export const PROVIDER_COLORS: Record = { vertex: '#4285F4', iflow: '#f94144', qwen: '#6236FF', + kiro: '#4d908e', // Dark Cyan (AWS-inspired) + copilot: '#43aa8b', // Seaweed (GitHub-inspired) }; // Provider display names @@ -29,6 +33,8 @@ const PROVIDER_NAMES: Record = { vertex: 'Vertex AI', iflow: 'iFlow', qwen: 'Qwen', + kiro: 'Kiro (AWS)', + copilot: 'GitHub Copilot', }; // Map provider to display name diff --git a/ui/src/lib/utils.ts b/ui/src/lib/utils.ts index 326a4440..29bdb99d 100644 --- a/ui/src/lib/utils.ts +++ b/ui/src/lib/utils.ts @@ -27,6 +27,8 @@ const PROVIDER_COLORS: Record = { vertex: '#577590', // Blue Slate iflow: '#f94144', // Strawberry qwen: '#f9c74f', // Tuscan + kiro: '#4d908e', // Dark Cyan (AWS-inspired) + copilot: '#43aa8b', // Seaweed (GitHub-inspired) }; // Status colors (from Analytics Cost breakdown) - darker for light theme contrast diff --git a/ui/src/pages/cliproxy.tsx b/ui/src/pages/cliproxy.tsx index b9fc21a9..9a5840fa 100644 --- a/ui/src/pages/cliproxy.tsx +++ b/ui/src/pages/cliproxy.tsx @@ -235,7 +235,7 @@ export function CliproxyPage() {
-

CLIProxy

+

CLIProxy Plus