Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ Clients must send `Authorization: Bearer <token>`. The current bridge is designe
|---|---|
| Frontend | React 19, TypeScript 6, Vite 8 |
| Editing core | Immutable timeline state, command layer, and proposal-based application |
| Agent | Vercel AI SDK 7 (Anthropic, OpenAI, Gemini, Kimi, Qwen, GLM, DeepSeek, MiniMax, Xiaomi MiMo, Mistral, xAI Grok by API key or SuperGrok/X Premium+ subscription sign-in, and compatible APIs), Agent Skills, MCP SDK |
| Agent | Vercel AI SDK 7 (Anthropic, OpenAI, Gemini, Kimi, Qwen, GLM, DeepSeek, MiniMax, Xiaomi MiMo, Mistral, xAI Grok by API key or SuperGrok/X Premium+ subscription sign-in, OpenRouter, OrcaRouter, and compatible APIs), Agent Skills, MCP SDK |
| Preview and visuals | Remotion Player, WebGL / GLSL |
| Server | Dual-host Vite / Electron plugins and a server-side keystore |
| Persistence | Shared local project store under `~/.openchatcut`, IndexedDB cache, configurable local media directory, optional Cloudflare R2 |
Expand Down
2 changes: 1 addition & 1 deletion README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ OPENCHATCUT_EDITOR_URL=https://your-editor.example.com
|---|---|
| 前端 | React 19、TypeScript 6、Vite 8 |
| 编辑核心 | 不可变时间线状态、命令层、提案式应用 |
| Agent | Vercel AI SDK 7(Anthropic、OpenAI、Gemini、Kimi、Qwen、GLM、DeepSeek、MiniMax、小米 MiMo、Mistral、xAI Grok(API Key 或 SuperGrok/X Premium+ 订阅登录)与兼容接口)、Agent Skills、MCP SDK |
| Agent | Vercel AI SDK 7(Anthropic、OpenAI、Gemini、Kimi、Qwen、GLM、DeepSeek、MiniMax、小米 MiMo、Mistral、xAI Grok(API Key 或 SuperGrok/X Premium+ 订阅登录)、OpenRouter、OrcaRouter 与兼容接口)、Agent Skills、MCP SDK |
| 预览与视觉 | Remotion Player、WebGL / GLSL |
| 服务端 | Vite / Electron 双宿主插件、服务端密钥仓 |
| 持久化 | `~/.openchatcut` 下的本机共享工程库、IndexedDB 缓存、可配置本地素材目录、可选 Cloudflare R2 |
Expand Down
3 changes: 3 additions & 0 deletions server/keystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ export const KEY_NAMES = [
"LLM_OPENROUTER_API_KEY",
"LLM_OPENROUTER_BASE_URL",
"LLM_OPENROUTER_MODEL",
"LLM_ORCAROUTER_API_KEY",
"LLM_ORCAROUTER_BASE_URL",
"LLM_ORCAROUTER_MODEL",
"LLM_OLLAMA_API_KEY",
"LLM_OLLAMA_BASE_URL",
"LLM_OLLAMA_MODEL",
Expand Down
7 changes: 7 additions & 0 deletions shared/llm-providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ export const LLM_PROVIDER_PRESETS = [
baseUrl: 'https://openrouter.ai/api/v1',
defaultModel: 'openrouter/auto',
},
{
id: 'orcarouter',
label: 'OrcaRouter',
protocol: 'openai-compatible',
baseUrl: 'https://api.orcarouter.ai/v1',
defaultModel: 'orcarouter/auto',
},
{
id: 'ollama',
label: 'Ollama (Local)',
Expand Down
4 changes: 4 additions & 0 deletions src/agent/ai-sdk.verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,22 @@ assert.equal(normalizeLlmProvider('KIMI'), 'kimi');
assert.equal(normalizeLlmProvider('qwen'), 'qwen');
assert.equal(normalizeLlmProvider('glm'), 'glm');
assert.equal(normalizeLlmProvider('OpenRouter'), 'openrouter');
assert.equal(normalizeLlmProvider('OrcaRouter'), 'orcarouter');
assert.equal(normalizeLlmProvider('unexpected'), 'anthropic');
assert.equal(defaultModelForProvider('anthropic'), 'claude-fable-5');
assert.equal(defaultModelForProvider('openai'), 'gpt-5');
assert.equal(defaultModelForProvider('kimi'), 'kimi-k3');
assert.equal(defaultModelForProvider('qwen'), 'qwen-plus');
assert.equal(defaultModelForProvider('glm'), 'glm-5.2');
assert.equal(defaultModelForProvider('openrouter'), 'openrouter/auto');
assert.equal(defaultModelForProvider('orcarouter'), 'orcarouter/auto');
assert.equal(providerApiPath('anthropic'), '/messages');
assert.equal(providerApiPath('openai'), '/responses');
assert.equal(providerApiPath('openai', 'chat'), '/chat/completions');
assert.equal(providerApiPath('kimi'), '/chat/completions');
assert.equal(providerApiPath('gemini'), '/models');
assert.equal(providerApiPath('openrouter'), '/chat/completions');
assert.equal(providerApiPath('orcarouter'), '/chat/completions');

const strippedVisualMessages = withoutModelImages([{
role: 'user',
Expand All @@ -83,6 +86,7 @@ assert.equal((await getLanguageModel('openai', 'test-model', 'chat')).provider,
assert.equal((await getLanguageModel('kimi', 'test-model')).provider, 'moonshotai.chat');
assert.equal((await getLanguageModel('gemini', 'test-model')).provider, 'google.generative-ai');
assert.equal((await getLanguageModel('openrouter', 'openrouter/auto')).provider, 'openrouter.chat');
assert.equal((await getLanguageModel('orcarouter', 'orcarouter/auto')).provider, 'orcarouter.chat');
assert.deepEqual(getLanguageModelProviderOptions('openai'), { openai: { store: false } });
assert.equal(getLanguageModelProviderOptions('openai', 'chat'), undefined);
assert.deepEqual(getLanguageModelProviderOptions('minimax'), {
Expand Down
1 change: 1 addition & 0 deletions src/components/settings/VisionModelPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const PROVIDER_LABELS: Record<LlmProvider, string> = {
xai: 'xAI',
'xai-oauth': 'xAI (订阅登录)',
openrouter: 'OpenRouter',
orcarouter: 'OrcaRouter',
ollama: 'Ollama',
lmstudio: 'LM Studio',
};
Expand Down
3 changes: 2 additions & 1 deletion src/components/settings/vendorIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import lmstudioSvg from '../../../assets/vendor-icons/lmstudio-color.svg?raw';
import visionSvg from '../../../assets/vendor-icons/vision.svg?raw';

export type VendorId =
| 'llm' | 'anthropic' | 'openai' | 'gemini' | 'kimi' | 'qwen' | 'glm' | 'deepseek' | 'mistral' | 'openrouter'
| 'llm' | 'anthropic' | 'openai' | 'gemini' | 'kimi' | 'qwen' | 'glm' | 'deepseek' | 'mistral' | 'openrouter' | 'orcarouter'
| 'ollama' | 'lmstudio' | 'xiaomi' | 'minimax' | 'hailuo' | 'elevenlabs' | 'doubao'
| 'seedance' | 'kling' | 'mureka' | 'sonilo' | 'pexels' | 'pixabay' | 'unsplash' | 'freesound'
| 'assemblyai' | 'deepgram' | 'groq' | 'cartesia' | 'e2b' | 'firecrawl' | 'r2' | 'localdisk' | 'localasr'
Expand Down Expand Up @@ -103,6 +103,7 @@ const MONOGRAMS: Partial<Record<VendorId, { bg: string; mono: string; fg?: strin
sonilo: { bg: '#101828', mono: 'SO', fg: '#e8f6f2' }, // Sonilo, no official SVG vendored yet
xai: { bg: '#101010', mono: 'x', fg: '#f7f7f8' }, // xAI Grok, no official SVG vendored yet
'xai-oauth': { bg: '#101010', mono: 'x', fg: '#f7f7f8' }, // xAI subscription login, shares the Grok monogram
orcarouter: { bg: '#0F172A', mono: 'OR', fg: '#38BDF8' }, // OrcaRouter gateway, no official SVG vendored yet
};

interface VendorIconProps {
Expand Down