mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
feat(api): add Fireworks AI provider preset (#1543)
Promotes Fireworks AI to a first-class discoverable preset over the existing Anthropic-compatible Bearer path. Closes #890.
This commit is contained in:
1 parent
5320b4f418
commit
a472c44015
3 files changed
+67
-1
No files matched your search
@@ -64,7 +64,7 @@ CCS gives you one stable command surface while letting you switch between:
|
||||
- OAuth providers like Codex, Kiro, Claude, Qwen, Kimi, and more, with legacy
|
||||
Copilot compatibility for existing setups
|
||||
- API and local-model profiles like GLM, Kimi, OpenRouter, Ollama, llama.cpp,
|
||||
Novita, and Alibaba Coding Plan
|
||||
Novita, Fireworks AI, and Alibaba Coding Plan
|
||||
|
||||
The goal is simple: stop rewriting config files, stop breaking active sessions,
|
||||
and move between providers in seconds.
|
||||
|
||||
@@ -23,6 +23,7 @@ export const PROVIDER_PRESET_IDS = [
|
||||
'qwen',
|
||||
'ollama-cloud',
|
||||
'novita',
|
||||
'fireworks',
|
||||
] as const;
|
||||
|
||||
export type ProviderPresetId = (typeof PROVIDER_PRESET_IDS)[number];
|
||||
@@ -266,6 +267,19 @@ const RAW_PROVIDER_PRESET_DEFINITIONS: readonly ProviderPresetDefinition[] = [
|
||||
badge: 'Anthropic-compatible',
|
||||
icon: '/icons/novita.svg',
|
||||
},
|
||||
{
|
||||
id: 'fireworks',
|
||||
name: 'Fireworks AI',
|
||||
description: 'Anthropic-compatible inference (Kimi, Qwen, Llama) via api.fireworks.ai',
|
||||
baseUrl: 'https://api.fireworks.ai/inference',
|
||||
defaultProfileName: 'fireworks',
|
||||
defaultModel: 'accounts/fireworks/models/kimi-k2p5',
|
||||
apiKeyPlaceholder: 'fw_...',
|
||||
apiKeyHint: 'Get your API key at fireworks.ai/api-keys',
|
||||
category: 'alternative',
|
||||
requiresApiKey: true,
|
||||
badge: 'Anthropic-compatible',
|
||||
},
|
||||
];
|
||||
|
||||
function clonePresetDefinition(preset: ProviderPresetDefinition): ProviderPresetDefinition {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import { getPresetById, isValidPresetId } from '../../../src/api/services/provider-presets';
|
||||
import { PROVIDER_PRESET_IDS } from '../../../src/shared/provider-preset-catalog';
|
||||
|
||||
describe('provider-presets-fireworks', () => {
|
||||
it('resolves fireworks preset id', () => {
|
||||
const preset = getPresetById('fireworks');
|
||||
expect(preset?.id).toBe('fireworks');
|
||||
expect(preset?.baseUrl).toBe('https://api.fireworks.ai/inference');
|
||||
expect(preset?.defaultProfileName).toBe('fireworks');
|
||||
});
|
||||
|
||||
it('registers fireworks in PROVIDER_PRESET_IDS', () => {
|
||||
expect(PROVIDER_PRESET_IDS).toContain('fireworks');
|
||||
});
|
||||
|
||||
it('uses the Anthropic-compatible base URL without a /v1 suffix', () => {
|
||||
const preset = getPresetById('fireworks');
|
||||
expect(preset?.baseUrl).toBe('https://api.fireworks.ai/inference');
|
||||
expect(preset?.baseUrl.endsWith('/v1')).toBe(false);
|
||||
});
|
||||
|
||||
it('pins a fully-qualified Fireworks model id as default', () => {
|
||||
const preset = getPresetById('fireworks');
|
||||
expect(preset?.defaultModel).toMatch(/^accounts\/fireworks\/(models|routers)\//);
|
||||
});
|
||||
|
||||
it('validates fireworks preset requires API key with the fw_ placeholder', () => {
|
||||
const preset = getPresetById('fireworks');
|
||||
expect(preset?.requiresApiKey).toBe(true);
|
||||
expect(preset?.apiKeyPlaceholder).toBe('fw_...');
|
||||
});
|
||||
|
||||
it('treats fireworks as a valid preset id', () => {
|
||||
expect(isValidPresetId('fireworks')).toBe(true);
|
||||
});
|
||||
|
||||
it('handles whitespace in fireworks preset id', () => {
|
||||
const preset = getPresetById(' fireworks ');
|
||||
expect(preset?.id).toBe('fireworks');
|
||||
});
|
||||
|
||||
it('handles uppercase fireworks preset id', () => {
|
||||
const preset = getPresetById('FIREWORKS');
|
||||
expect(preset?.id).toBe('fireworks');
|
||||
});
|
||||
|
||||
it('does not resolve partial or invalid fireworks ids', () => {
|
||||
expect(getPresetById('fireworks-invalid')).toBeUndefined();
|
||||
expect(isValidPresetId('fireworks-invalid')).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user