thebird 1.2.95 → 1.2.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/app.js CHANGED
@@ -29,7 +29,7 @@ class BirdChat extends HTMLElement {
29
29
  connectedCallback() {
30
30
  this.render();
31
31
  Object.assign(window.__debug, { acp: { baseUrl: this.state.baseUrl, provider: this.state.providerType } });
32
- if (this.state.apiKey || ['kilo','opencode','acp2openai'].includes(this.state.providerType)) this.loadModels();
32
+ if (this.state.apiKey || ['kilo','opencode','acp2openai','ollama','lmstudio'].includes(this.state.providerType)) this.loadModels();
33
33
  this.statsTimer = setInterval(() => this.updateStats(), 250);
34
34
  }
35
35
  disconnectedCallback() { if (this.statsTimer) clearInterval(this.statsTimer); }
@@ -62,20 +62,20 @@ class BirdChat extends HTMLElement {
62
62
  localStorage.setItem('provider_base_url', baseUrl);
63
63
  localStorage.setItem('provider_model', model);
64
64
  this.setState({ providerType: type, baseUrl, model, models: [], apiKey: localStorage.getItem('provider_api_key') || '' });
65
- if (['kilo','opencode','acp2openai'].includes(type)) this.loadModels();
65
+ if (['kilo','opencode','acp2openai','ollama','lmstudio'].includes(type)) this.loadModels();
66
66
  }
67
67
 
68
68
  renderBaseUrlInput() {
69
69
  const { providerType, baseUrl } = this.state;
70
- if (providerType !== 'custom' && providerType !== 'kilo' && providerType !== 'opencode' && providerType !== 'acp2openai') return null;
71
- const phMap = { kilo: 'http://localhost:4780', opencode: 'http://localhost:4790', acp2openai: 'http://localhost:4800/v1', custom: 'https://your-endpoint/v1' };
70
+ if (!['custom','kilo','opencode','acp2openai','ollama'].includes(providerType)) return null;
71
+ const phMap = { kilo: 'http://localhost:4780', opencode: 'http://localhost:4790', acp2openai: 'http://localhost:4800/v1', ollama: 'http://localhost:11434/v1', lmstudio: 'http://localhost:1234/v1', custom: 'https://your-endpoint/v1' };
72
72
  const ph = phMap[providerType] || phMap.custom;
73
73
  return html`<input type="text" class="tui-input" style="flex:1;min-width:140px" placeholder=${ph} value=${baseUrl}
74
74
  onchange=${e => { localStorage.setItem('provider_base_url', e.target.value); this.setState({ baseUrl: e.target.value }); }} />`;
75
75
  }
76
76
  renderApiKeyInput() {
77
77
  const { providerType, apiKey } = this.state;
78
- if (providerType === 'kilo' || providerType === 'opencode' || providerType === 'acp2openai') return null;
78
+ if (['kilo','opencode','acp2openai','ollama','lmstudio'].includes(providerType)) return null;
79
79
  const provDef = PROVIDERS[providerType] || PROVIDERS.custom;
80
80
  return html`<input id="api-key-input" type="password" class="tui-input" style="flex:1;min-width:120px" placeholder=${provDef.keyPlaceholder} value=${apiKey}
81
81
  onchange=${e => { const v = e.target.value.trim(); localStorage.setItem('provider_api_key', v); this.setState({ apiKey: v }); if (v) this.loadModels(); }} />`;
@@ -130,7 +130,7 @@ class BirdChat extends HTMLElement {
130
130
  const text = input?.value.trim();
131
131
  if (!text || this.state.streaming) return;
132
132
  const { apiKey, model, providerType, baseUrl } = this.state;
133
- if (!apiKey && providerType !== 'kilo' && providerType !== 'opencode' && providerType !== 'acp2openai') { this.setState({ status: 'Enter an API key above.' }); return; }
133
+ if (!apiKey && !['kilo','opencode','acp2openai','ollama','lmstudio'].includes(providerType)) { this.setState({ status: 'Enter an API key above.' }); return; }
134
134
  input.value = '';
135
135
  input.style.height = 'auto';
136
136
  const normalizedMessages = [...this.state.messages, { role: 'user', content: text }].map(m => ({
@@ -6,6 +6,23 @@ export const PROVIDERS = {
6
6
  mistral: { label: 'Mistral', baseUrl: 'https://api.mistral.ai/v1', keyPlaceholder: 'MISTRAL_API_KEY', models: ['mistral-large-latest', 'mistral-small-latest', 'codestral-latest'] },
7
7
  deepseek: { label: 'DeepSeek', baseUrl: 'https://api.deepseek.com/v1', keyPlaceholder: 'DEEPSEEK_API_KEY', models: ['deepseek-chat', 'deepseek-reasoner'] },
8
8
  cerebras: { label: 'Cerebras', baseUrl: 'https://api.cerebras.ai/v1', keyPlaceholder: 'CEREBRAS_API_KEY', models: ['gpt-oss-120b', 'llama3.1-8b'] },
9
+ openrouter: { label: 'OpenRouter', baseUrl: 'https://openrouter.ai/api/v1', keyPlaceholder: 'OPENROUTER_API_KEY', models: ['anthropic/claude-sonnet-4.5', 'anthropic/claude-opus-4.1', 'google/gemini-2.5-flash', 'google/gemini-2.5-pro', 'openai/gpt-4.1', 'openai/gpt-4o-mini', 'x-ai/grok-code-fast-1', 'meta-llama/llama-3.3-70b-instruct', 'deepseek/deepseek-chat', 'qwen/qwen-2.5-coder-32b-instruct'] },
10
+ together: { label: 'Together AI', baseUrl: 'https://api.together.xyz/v1', keyPlaceholder: 'TOGETHER_API_KEY', models: ['meta-llama/Llama-3.3-70B-Instruct-Turbo', 'Qwen/Qwen2.5-Coder-32B-Instruct', 'deepseek-ai/DeepSeek-V3', 'mistralai/Mixtral-8x22B-Instruct-v0.1'] },
11
+ fireworks: { label: 'Fireworks AI', baseUrl: 'https://api.fireworks.ai/inference/v1', keyPlaceholder: 'FIREWORKS_API_KEY', models: ['accounts/fireworks/models/llama-v3p3-70b-instruct', 'accounts/fireworks/models/deepseek-v3', 'accounts/fireworks/models/qwen2p5-coder-32b-instruct'] },
12
+ perplexity: { label: 'Perplexity', baseUrl: 'https://api.perplexity.ai', keyPlaceholder: 'PERPLEXITY_API_KEY', models: ['sonar', 'sonar-pro', 'sonar-reasoning', 'sonar-reasoning-pro'] },
13
+ sambanova: { label: 'SambaNova', baseUrl: 'https://api.sambanova.ai/v1', keyPlaceholder: 'SAMBANOVA_API_KEY', models: ['Meta-Llama-3.3-70B-Instruct', 'DeepSeek-V3-0324', 'Qwen2.5-Coder-32B-Instruct'] },
14
+ hyperbolic: { label: 'Hyperbolic', baseUrl: 'https://api.hyperbolic.xyz/v1', keyPlaceholder: 'HYPERBOLIC_API_KEY', models: ['meta-llama/Llama-3.3-70B-Instruct', 'deepseek-ai/DeepSeek-V3', 'Qwen/Qwen2.5-Coder-32B-Instruct'] },
15
+ nvidia: { label: 'NVIDIA NIM', baseUrl: 'https://integrate.api.nvidia.com/v1', keyPlaceholder: 'NVIDIA_API_KEY', models: ['meta/llama-3.3-70b-instruct', 'nvidia/nemotron-4-340b-instruct', 'deepseek-ai/deepseek-r1'] },
16
+ ollama: { label: 'Ollama (local)', baseUrl: 'http://localhost:11434/v1', keyPlaceholder: '(no key needed)', models: ['llama3.3', 'qwen2.5-coder', 'deepseek-r1'] },
17
+ lmstudio: { label: 'LM Studio (local)', baseUrl: 'http://localhost:1234/v1', keyPlaceholder: '(no key needed)', models: [] },
18
+ deepinfra: { label: 'DeepInfra', baseUrl: 'https://api.deepinfra.com/v1/openai', keyPlaceholder: 'DEEPINFRA_API_KEY', models: ['meta-llama/Llama-3.3-70B-Instruct', 'deepseek-ai/DeepSeek-V3', 'Qwen/Qwen2.5-Coder-32B-Instruct'] },
19
+ novita: { label: 'Novita AI', baseUrl: 'https://api.novita.ai/v3/openai', keyPlaceholder: 'NOVITA_API_KEY', models: ['meta-llama/llama-3.3-70b-instruct', 'deepseek/deepseek-v3', 'qwen/qwen-2.5-coder-32b-instruct'] },
20
+ moonshot: { label: 'Moonshot (Kimi)', baseUrl: 'https://api.moonshot.ai/v1', keyPlaceholder: 'MOONSHOT_API_KEY', models: ['kimi-k2-turbo-preview', 'moonshot-v1-128k', 'moonshot-v1-32k'] },
21
+ zhipu: { label: 'Zhipu (GLM)', baseUrl: 'https://open.bigmodel.cn/api/paas/v4', keyPlaceholder: 'ZHIPU_API_KEY', models: ['glm-4.6', 'glm-4-plus', 'glm-4-air'] },
22
+ lambda: { label: 'Lambda Inference', baseUrl: 'https://api.lambda.ai/v1', keyPlaceholder: 'LAMBDA_API_KEY', models: ['llama-3.3-70b-instruct-fp8', 'deepseek-v3-0324', 'qwen25-coder-32b-instruct'] },
23
+ github: { label: 'GitHub Models', baseUrl: 'https://models.github.ai/inference', keyPlaceholder: 'GITHUB_TOKEN', models: ['openai/gpt-4.1', 'openai/gpt-4o-mini', 'meta/llama-3.3-70b-instruct', 'deepseek/deepseek-v3'] },
24
+ vercel: { label: 'Vercel AI Gateway', baseUrl: 'https://ai-gateway.vercel.sh/v1', keyPlaceholder: 'AI_GATEWAY_API_KEY', models: ['anthropic/claude-sonnet-4.5', 'openai/gpt-4.1', 'google/gemini-2.5-flash', 'xai/grok-code-fast-1'] },
25
+ cohere: { label: 'Cohere', baseUrl: 'https://api.cohere.com/compatibility/v1', keyPlaceholder: 'COHERE_API_KEY', models: ['command-a-03-2025', 'command-r-plus-08-2024', 'command-r-08-2024'] },
9
26
  kilo: { label: 'Kilo Code', baseUrl: 'http://localhost:4780', keyPlaceholder: '(no key needed)', models: ['x-ai/grok-code-fast-1:optimized:free', 'kilo-auto/free', 'openrouter/free', 'stepfun/step-3.5-flash:free', 'nvidia/nemotron-3-super-120b-a12b:free', 'bytedance-seed/dola-seed-2.0-pro:free'] },
10
27
  opencode: { label: 'opencode (zen)', baseUrl: 'http://localhost:4790', keyPlaceholder: '(needs opencode auth login)', models: ['minimax-m2.5-free', 'nemotron-3-super-free'] },
11
28
  acp2openai: { label: 'acp2openai (OpenAI-compat)', baseUrl: 'http://localhost:4800/v1', keyPlaceholder: '(no key needed)', models: ['kilo/x-ai/grok-code-fast-1:optimized:free', 'kilo/kilo-auto/free', 'kilo/openrouter/free', 'opencode/minimax-m2.5-free'] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thebird",
3
- "version": "1.2.95",
3
+ "version": "1.2.97",
4
4
  "description": "Anthropic SDK to Gemini streaming bridge — drop-in proxy that translates Anthropic message format and tool calls to Google Gemini",
5
5
  "scripts": {
6
6
  "start": "node serve.js"