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
5 changes: 5 additions & 0 deletions src/renderer/components/icons/ProviderIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export default function ProviderIcon(props: { className?: string; size?: number;
<path d="M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z"></path>
</>
)}
{provider === ModelProviderEnum.GreenPT && (
<g transform="scale(0.2790697674)">
<path d="M43 0C19.252 0 0 19.252 0 43s19.252 43 43 43 43-19.252 43-43S66.748 0 43 0Zm1.362 66.507c-12.864 0-23.292-10.493-23.292-23.435 0-12.943 10.428-23.435 23.292-23.435 12.863 0 23.291 10.492 23.291 23.435 0 12.942-10.428 23.435-23.291 23.435Z" />
</g>
)}
{provider === ModelProviderEnum.Gemini && (
<>
<path d="M12 24A14.304 14.304 0 000 12 14.304 14.304 0 0012 0a14.305 14.305 0 0012 12 14.305 14.305 0 00-12 12"></path>
Expand Down
6 changes: 6 additions & 0 deletions src/shared/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const aiProviderNameHash: Record<ModelProviderEnum, string> = {
[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',
Expand Down Expand Up @@ -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],
Expand Down
22 changes: 22 additions & 0 deletions src/shared/providers/definitions/greenpt.test.ts
Original file line number Diff line number Diff line change
@@ -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' }),
])
)
})
})
55 changes: 55 additions & 0 deletions src/shared/providers/definitions/greenpt.ts
Original file line number Diff line number Diff line change
@@ -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})`
},
})
5 changes: 5 additions & 0 deletions src/shared/providers/definitions/models/greenpt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import OpenAICompatible from '../../../models/openai-compatible'

export default class GreenPT extends OpenAICompatible {
public name = 'GreenPT'
}
1 change: 1 addition & 0 deletions src/shared/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
1 change: 1 addition & 0 deletions src/shared/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum ModelProviderEnum {
Ollama = 'ollama',
Groq = 'groq',
DeepSeek = 'deepseek',
GreenPT = 'greenpt',
SiliconFlow = 'siliconflow',
VolcEngine = 'volcengine',
MistralAI = 'mistral-ai',
Expand Down
14 changes: 13 additions & 1 deletion src/shared/utils/llm_utils.test.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
1 change: 1 addition & 0 deletions src/shared/utils/llm_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down