diff --git a/src/renderer/components/icons/ProviderIcon.tsx b/src/renderer/components/icons/ProviderIcon.tsx
index 0aceb77af4..ea6047a44d 100644
--- a/src/renderer/components/icons/ProviderIcon.tsx
+++ b/src/renderer/components/icons/ProviderIcon.tsx
@@ -69,6 +69,11 @@ export default function ProviderIcon(props: { className?: string; size?: number;
>
)}
+ {provider === ModelProviderEnum.GreenPT && (
+
+
+
+ )}
{provider === ModelProviderEnum.Gemini && (
<>
diff --git a/src/shared/models/index.ts b/src/shared/models/index.ts
index 304c6909a5..ab1a31b5a1 100644
--- a/src/shared/models/index.ts
+++ b/src/shared/models/index.ts
@@ -21,6 +21,7 @@ export const aiProviderNameHash: Record = {
[ModelProviderEnum.Ollama]: 'Ollama API',
[ModelProviderEnum.Groq]: 'Groq API',
[ModelProviderEnum.DeepSeek]: 'DeepSeek API',
+ [ModelProviderEnum.GreenPT]: 'GreenPT API',
[ModelProviderEnum.SiliconFlow]: 'SiliconFlow API',
[ModelProviderEnum.VolcEngine]: 'VolcEngine API',
[ModelProviderEnum.MistralAI]: 'MistralAI',
@@ -75,6 +76,11 @@ export const AIModelProviderMenuOptionList = [
label: aiProviderNameHash[ModelProviderEnum.DeepSeek],
disabled: false,
},
+ {
+ value: ModelProviderEnum.GreenPT,
+ label: aiProviderNameHash[ModelProviderEnum.GreenPT],
+ disabled: false,
+ },
{
value: ModelProviderEnum.Qwen,
label: aiProviderNameHash[ModelProviderEnum.Qwen],
diff --git a/src/shared/providers/definitions/greenpt.test.ts b/src/shared/providers/definitions/greenpt.test.ts
new file mode 100644
index 0000000000..e5b2350038
--- /dev/null
+++ b/src/shared/providers/definitions/greenpt.test.ts
@@ -0,0 +1,22 @@
+import { describe, expect, it } from 'vitest'
+import { ModelProviderEnum, ModelProviderType } from '../../types'
+import { greenPTProvider } from './greenpt'
+
+describe('GreenPT provider', () => {
+ it('registers the OpenAI-compatible endpoint and flagship models', () => {
+ expect(greenPTProvider).toMatchObject({
+ id: ModelProviderEnum.GreenPT,
+ type: ModelProviderType.OpenAI,
+ defaultSettings: {
+ apiHost: 'https://api.greenpt.ai/v1',
+ },
+ })
+ expect(greenPTProvider.defaultSettings?.models).toEqual(
+ expect.arrayContaining([
+ expect.objectContaining({ modelId: 'glm-5.2' }),
+ expect.objectContaining({ modelId: 'kimi-k2.7-code' }),
+ expect.objectContaining({ modelId: 'green-embedding', type: 'embedding' }),
+ ])
+ )
+ })
+})
diff --git a/src/shared/providers/definitions/greenpt.ts b/src/shared/providers/definitions/greenpt.ts
new file mode 100644
index 0000000000..1935d1cf6a
--- /dev/null
+++ b/src/shared/providers/definitions/greenpt.ts
@@ -0,0 +1,55 @@
+import { ModelProviderEnum, ModelProviderType } from '../../types'
+import { defineProvider } from '../registry'
+import GreenPT from './models/greenpt'
+
+export const greenPTProvider = defineProvider({
+ id: ModelProviderEnum.GreenPT,
+ name: 'GreenPT',
+ type: ModelProviderType.OpenAI,
+ description:
+ 'GreenPT is a European AI provider running optimized inference in data centers powered by 100% renewable energy.',
+ curatedModelIds: ['glm-5.2', 'kimi-k2.7-code', 'green-embedding'],
+ urls: {
+ website: 'https://greenpt.com/',
+ apiKey: 'https://account.greenpt.ai/api/keys',
+ docs: 'https://docs.greenpt.ai/get-started',
+ models: 'https://docs.greenpt.ai/models',
+ },
+ defaultSettings: {
+ apiHost: 'https://api.greenpt.ai/v1',
+ models: [
+ {
+ modelId: 'glm-5.2',
+ contextWindow: 1_000_000,
+ capabilities: ['reasoning', 'tool_use'],
+ },
+ {
+ modelId: 'kimi-k2.7-code',
+ contextWindow: 256_000,
+ maxOutput: 256_000,
+ capabilities: ['reasoning', 'tool_use'],
+ },
+ {
+ modelId: 'green-embedding',
+ type: 'embedding',
+ },
+ ],
+ },
+ createModel: (config) => {
+ return new GreenPT(
+ {
+ apiKey: config.effectiveApiKey,
+ apiHost: config.formattedApiHost,
+ model: config.model,
+ temperature: config.settings.temperature,
+ topP: config.settings.topP,
+ maxOutputTokens: config.settings.maxTokens,
+ stream: config.settings.stream,
+ },
+ config.dependencies
+ )
+ },
+ getDisplayName: (modelId, providerSettings) => {
+ return `GreenPT API (${providerSettings?.models?.find((model) => model.modelId === modelId)?.nickname || modelId})`
+ },
+})
diff --git a/src/shared/providers/definitions/models/greenpt.ts b/src/shared/providers/definitions/models/greenpt.ts
new file mode 100644
index 0000000000..dc293222e0
--- /dev/null
+++ b/src/shared/providers/definitions/models/greenpt.ts
@@ -0,0 +1,5 @@
+import OpenAICompatible from '../../../models/openai-compatible'
+
+export default class GreenPT extends OpenAICompatible {
+ public name = 'GreenPT'
+}
diff --git a/src/shared/providers/index.ts b/src/shared/providers/index.ts
index 06742110e7..2dafe452fa 100644
--- a/src/shared/providers/index.ts
+++ b/src/shared/providers/index.ts
@@ -11,6 +11,7 @@ import './definitions/openai-responses'
import './definitions/gemini'
import './definitions/claude'
import './definitions/deepseek'
+import './definitions/greenpt'
import './definitions/qwen'
import './definitions/qwen-portal'
import './definitions/minimax'
diff --git a/src/shared/types/provider.ts b/src/shared/types/provider.ts
index 8f12db4f03..370326f5c8 100644
--- a/src/shared/types/provider.ts
+++ b/src/shared/types/provider.ts
@@ -18,6 +18,7 @@ export enum ModelProviderEnum {
Ollama = 'ollama',
Groq = 'groq',
DeepSeek = 'deepseek',
+ GreenPT = 'greenpt',
SiliconFlow = 'siliconflow',
VolcEngine = 'volcengine',
MistralAI = 'mistral-ai',
diff --git a/src/shared/utils/llm_utils.test.ts b/src/shared/utils/llm_utils.test.ts
index 7aa06422c3..c57098e901 100644
--- a/src/shared/utils/llm_utils.test.ts
+++ b/src/shared/utils/llm_utils.test.ts
@@ -1,5 +1,17 @@
import { describe, expect, it } from 'vitest'
-import { normalizeClaudeHost, normalizeGeminiHost, normalizeOpenAIApiHostAndPath } from './llm_utils'
+import { ModelProviderEnum } from '../types'
+import {
+ isOpenAICompatible,
+ normalizeClaudeHost,
+ normalizeGeminiHost,
+ normalizeOpenAIApiHostAndPath,
+} from './llm_utils'
+
+describe('isOpenAICompatible', () => {
+ it('recognizes GreenPT', () => {
+ expect(isOpenAICompatible(ModelProviderEnum.GreenPT, 'glm-5.2')).toBe(true)
+ })
+})
describe('normalizeOpenAIApiHostAndPath', () => {
it('returns defaults when apiHost is empty', () => {
diff --git a/src/shared/utils/llm_utils.ts b/src/shared/utils/llm_utils.ts
index 2df5666a1a..de89a599db 100644
--- a/src/shared/utils/llm_utils.ts
+++ b/src/shared/utils/llm_utils.ts
@@ -134,6 +134,7 @@ export function isOpenAICompatible(providerId: string, _modelId: string) {
ModelProviderEnum.XAI,
ModelProviderEnum.Groq,
ModelProviderEnum.DeepSeek,
+ ModelProviderEnum.GreenPT,
ModelProviderEnum.LMStudio,
ModelProviderEnum.Qwen,
ModelProviderEnum.QwenPortal,