Skip to content

Commit bcaac83

Browse files
author
siyoon
committed
feat(friendli): add provider + 4 models
Friendli OpenAI-compatible provider. Models: GLM-5.2, GLM-5.1, DeepSeek-V3.2, MiniMax-M2.5. Pricing from friendli.ai pricing API. Mirror fireworks provider pattern (commit 4a9222b): - types: model info, schema, secret key, provider name - api: BaseOpenAiCompatibleProvider handler at api.friendli.ai/serverless/v1 - webview: provider UI, model picker, validation, i18n (18 locales) - tests: handler spec, ProfileValidator entry Reasoning streams back via base handler's reasoning_content extraction. Friendli defaults parse_reasoning=true for GLM reasoning models.
1 parent 6670962 commit bcaac83

36 files changed

Lines changed: 560 additions & 0 deletions

‎.github/ISSUE_TEMPLATE/bug_report.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ body:
8181
- DeepSeek
8282
- Featherless AI
8383
- Fireworks AI
84+
- Friendli
8485
- Google Gemini
8586
- Google Vertex AI
8687
- Groq

‎packages/types/src/global-settings.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ export const SECRET_STATE_KEYS = [
302302
"sambaNovaApiKey",
303303
"zaiApiKey",
304304
"fireworksApiKey",
305+
"friendliApiKey",
305306
"vercelAiGatewayApiKey",
306307
"opencodeGoApiKey",
307308
"basetenApiKey",

‎packages/types/src/provider-settings.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
bedrockModels,
99
deepSeekModels,
1010
fireworksModels,
11+
friendliModels,
1112
geminiModels,
1213
mistralModels,
1314
moonshotModels,
@@ -119,6 +120,7 @@ export const providerNames = [
119120
"baseten",
120121
"deepseek",
121122
"fireworks",
123+
"friendli",
122124
"gemini",
123125
"gemini-cli",
124126
"mistral",
@@ -393,6 +395,10 @@ const fireworksSchema = apiModelIdProviderModelSchema.extend({
393395
fireworksApiKey: z.string().optional(),
394396
})
395397

398+
const friendliSchema = apiModelIdProviderModelSchema.extend({
399+
friendliApiKey: z.string().optional(),
400+
})
401+
396402
const qwenCodeSchema = apiModelIdProviderModelSchema.extend({
397403
qwenCodeOauthPath: z.string().optional(),
398404
})
@@ -449,6 +455,7 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
449455
sambaNovaSchema.merge(z.object({ apiProvider: z.literal("sambanova") })),
450456
zaiSchema.merge(z.object({ apiProvider: z.literal("zai") })),
451457
fireworksSchema.merge(z.object({ apiProvider: z.literal("fireworks") })),
458+
friendliSchema.merge(z.object({ apiProvider: z.literal("friendli") })),
452459
qwenCodeSchema.merge(z.object({ apiProvider: z.literal("qwen-code") })),
453460
vercelAiGatewaySchema.merge(z.object({ apiProvider: z.literal("vercel-ai-gateway") })),
454461
opencodeGoSchema.merge(z.object({ apiProvider: z.literal("opencode-go") })),
@@ -485,6 +492,7 @@ export const providerSettingsSchema = z.object({
485492
...sambaNovaSchema.shape,
486493
...zaiSchema.shape,
487494
...fireworksSchema.shape,
495+
...friendliSchema.shape,
488496
...qwenCodeSchema.shape,
489497
...vercelAiGatewaySchema.shape,
490498
...opencodeGoSchema.shape,
@@ -565,6 +573,7 @@ export const modelIdKeysByProvider: Record<TypicalProvider, ModelIdKey> = {
565573
sambanova: "apiModelId",
566574
zai: "apiModelId",
567575
fireworks: "apiModelId",
576+
friendli: "apiModelId",
568577
"vercel-ai-gateway": "vercelAiGatewayModelId",
569578
"opencode-go": "opencodeGoModelId",
570579
"zoo-gateway": "zooGatewayModelId",
@@ -638,6 +647,11 @@ export const MODELS_BY_PROVIDER: Record<
638647
label: "Fireworks",
639648
models: Object.keys(fireworksModels),
640649
},
650+
friendli: {
651+
id: "friendli",
652+
label: "Friendli",
653+
models: Object.keys(friendliModels),
654+
},
641655
gemini: {
642656
id: "gemini",
643657
label: "Google Gemini",
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { ModelInfo } from "../model.js"
2+
3+
export type FriendliModelId =
4+
| "zai-org/GLM-5.2"
5+
| "zai-org/GLM-5.1"
6+
| "deepseek-ai/DeepSeek-V3.2"
7+
| "MiniMaxAI/MiniMax-M2.5"
8+
9+
export const friendliDefaultModelId: FriendliModelId = "zai-org/GLM-5.2"
10+
11+
// Pricing sourced from https://friendli.ai/api/public/model-apis (per 1M tokens).
12+
export const friendliModels = {
13+
"zai-org/GLM-5.2": {
14+
maxTokens: 131_072,
15+
contextWindow: 1_000_000,
16+
supportsImages: false,
17+
supportsPromptCache: true,
18+
supportsMaxTokens: true,
19+
inputPrice: 1.4,
20+
outputPrice: 4.4,
21+
cacheWritesPrice: 0,
22+
cacheReadsPrice: 0.26,
23+
description:
24+
"GLM-5.2 is Zhipu's flagship model with a 1M context window and 128k max output, served via Friendli Model APIs. It delivers top-tier long-context reasoning, coding, and agentic performance for extended engineering sessions.",
25+
},
26+
"zai-org/GLM-5.1": {
27+
maxTokens: 131_072,
28+
contextWindow: 200_000,
29+
supportsImages: false,
30+
supportsPromptCache: true,
31+
supportsMaxTokens: true,
32+
inputPrice: 1.4,
33+
outputPrice: 4.4,
34+
cacheWritesPrice: 0,
35+
cacheReadsPrice: 0.26,
36+
description:
37+
"GLM-5.1 is Zhipu's most capable model with a 200k context window and 128k max output, served via Friendli Model APIs. It delivers top-tier reasoning, coding, and agentic performance.",
38+
},
39+
"deepseek-ai/DeepSeek-V3.2": {
40+
maxTokens: 16384,
41+
contextWindow: 163_840,
42+
supportsImages: false,
43+
supportsPromptCache: true,
44+
inputPrice: 0.5,
45+
outputPrice: 1.5,
46+
cacheWritesPrice: 0,
47+
cacheReadsPrice: 0.25,
48+
description:
49+
"DeepSeek V3.2 is the latest iteration of the V3 model family with enhanced reasoning capabilities, improved code generation, and better instruction following, served via Friendli Model APIs.",
50+
},
51+
"MiniMaxAI/MiniMax-M2.5": {
52+
maxTokens: 4096,
53+
contextWindow: 204_800,
54+
supportsImages: false,
55+
supportsPromptCache: true,
56+
inputPrice: 0.3,
57+
outputPrice: 1.2,
58+
cacheWritesPrice: 0,
59+
cacheReadsPrice: 0.06,
60+
description:
61+
"MiniMax M2.5 is a high-performance language model with a 204.8K context window, optimized for long-context understanding and generation tasks, served via Friendli Model APIs.",
62+
},
63+
} as const satisfies Record<string, ModelInfo>

‎packages/types/src/providers/index.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from "./baseten.js"
33
export * from "./bedrock.js"
44
export * from "./deepseek.js"
55
export * from "./fireworks.js"
6+
export * from "./friendli.js"
67
export * from "./gemini.js"
78
export * from "./lite-llm.js"
89
export * from "./lm-studio.js"
@@ -33,6 +34,7 @@ import { basetenDefaultModelId } from "./baseten.js"
3334
import { bedrockDefaultModelId } from "./bedrock.js"
3435
import { deepSeekDefaultModelId } from "./deepseek.js"
3536
import { fireworksDefaultModelId } from "./fireworks.js"
37+
import { friendliDefaultModelId } from "./friendli.js"
3638
import { geminiDefaultModelId } from "./gemini.js"
3739
import { litellmDefaultModelId } from "./lite-llm.js"
3840
import { mistralDefaultModelId } from "./mistral.js"
@@ -111,6 +113,8 @@ export function getProviderDefaultModelId(
111113
return sambaNovaDefaultModelId
112114
case "fireworks":
113115
return fireworksDefaultModelId
116+
case "friendli":
117+
return friendliDefaultModelId
114118
case "qwen-code":
115119
return qwenCodeDefaultModelId
116120
case "poe":

‎src/api/index.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
SambaNovaHandler,
3232
ZAiHandler,
3333
FireworksHandler,
34+
FriendliHandler,
3435
VercelAiGatewayHandler,
3536
OpencodeGoHandler,
3637
ZooGatewayHandler,
@@ -182,6 +183,8 @@ export function buildApiHandler(configuration: ProviderSettings): ApiHandler {
182183
return new ZAiHandler(options)
183184
case "fireworks":
184185
return new FireworksHandler(options)
186+
case "friendli":
187+
return new FriendliHandler(options)
185188
case "vercel-ai-gateway":
186189
return new VercelAiGatewayHandler(options)
187190
case "opencode-go":

0 commit comments

Comments
 (0)