Skip to content
Closed
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
15 changes: 15 additions & 0 deletions src/main/presenter/configPresenter/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,21 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [
defaultBaseUrl: 'https://openrouter.ai/api/v1/'
}
},
{
id: 'poe',
name: 'Poe',
apiType: 'poe',
apiKey: '',
baseUrl: 'https://api.poe.com/v1',
enable: false,
websites: {
official: 'https://poe.com/',
apiKey: 'https://poe.com/api_key',
docs: 'https://creator.poe.com/docs/external-applications/openai-compatible-api',
models: 'https://api.poe.com/v1/models',
defaultBaseUrl: 'https://api.poe.com/v1'
}
},
{
id: '302ai',
name: '302.AI',
Expand Down
5 changes: 5 additions & 0 deletions src/main/presenter/llmProviderPresenter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { AihubmixProvider } from './providers/aihubmixProvider'
import { _302AIProvider } from './providers/_302AIProvider'
import { ModelscopeProvider } from './providers/modelscopeProvider'
import { VercelAIGatewayProvider } from './providers/vercelAIGatewayProvider'
import { PoeProvider } from './providers/poeProvider'

// Rate limit configuration interface
interface RateLimitConfig {
Expand Down Expand Up @@ -212,6 +213,8 @@ export class LLMProviderPresenter implements ILlmProviderPresenter {
return new GroqProvider(provider, this.configPresenter)
case 'vercel-ai-gateway':
return new VercelAIGatewayProvider(provider, this.configPresenter)
case 'poe':
return new PoeProvider(provider, this.configPresenter)
case 'aws-bedrock':
return new AwsBedrockProvider(provider, this.configPresenter)
default:
Expand Down Expand Up @@ -264,6 +267,8 @@ export class LLMProviderPresenter implements ILlmProviderPresenter {
return new GrokProvider(provider, this.configPresenter)
case 'vercel-ai-gateway':
return new VercelAIGatewayProvider(provider, this.configPresenter)
case 'poe':
return new PoeProvider(provider, this.configPresenter)
case 'aws-bedrock':
return new AwsBedrockProvider(provider, this.configPresenter)
default:
Expand Down
25 changes: 25 additions & 0 deletions src/main/presenter/llmProviderPresenter/providers/poeProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { LLM_PROVIDER, MODEL_META, IConfigPresenter } from '@shared/presenter'
import { OpenAICompatibleProvider } from './openAICompatibleProvider'

/**
* PoeProvider integrates Poe's OpenAI-compatible API surface with the shared
* BaseLLMProvider contract so the rest of the app can treat it just like
* any other OpenAI-style backend.
*
* Poe exposes hundreds of community and frontier models through a single
* endpoint. We reuse the OpenAICompatibleProvider implementation and only
* tweak metadata so the renderer can present a clearer group name.
*/
export class PoeProvider extends OpenAICompatibleProvider {
constructor(provider: LLM_PROVIDER, configPresenter: IConfigPresenter) {
super(provider, configPresenter)
}

protected async fetchOpenAIModels(options?: { timeout: number }): Promise<MODEL_META[]> {
const models = await super.fetchOpenAIModels(options)
return models.map((model) => ({
...model,
group: 'Poe'
}))
}
}
31 changes: 31 additions & 0 deletions src/renderer/settings/components/DisplaySettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,29 @@
</ButtonGroup>
</div>

<!-- 代码字体大小设置 -->
<div class="flex flex-col gap-2 px-2 py-2">
<span
class="flex items-center gap-2 text-sm font-medium shrink-0 min-w-[220px]"
:dir="languageStore.dir"
>
<Icon icon="lucide:code" class="w-4 h-4 text-muted-foreground" />
<span class="truncate">{{ t('settings.display.codeFontSize') }}</span>
</span>
<ButtonGroup class="flex-wrap">
<Button
v-for="(sizeOption, index) in codeFontSizeOptions"
:key="index"
:variant="codeFontSizeLevel === index ? 'default' : 'outline'"
size="sm"
class="px-2 py-1.5 text-xs shrink-0"
@click="codeFontSizeLevel = index"
>
{{ sizeOption }}
</Button>
</ButtonGroup>
</div>

<!-- 投屏保护开关 -->
<div class="flex items-center gap-3 px-2 py-2">
<span
Expand Down Expand Up @@ -410,6 +433,14 @@ const fontSizeLevel = computed({
set: (value) => settingsStore.updateFontSizeLevel(value)
})

// --- Code Font Size Settings ---
const codeFontSizeOptions = ['12px', '14px', '16px', '18px', '20px']

const codeFontSizeLevel = computed({
get: () => settingsStore.codeFontSizeLevel,
set: (value) => settingsStore.updateCodeFontSizeLevel(value)
})

// --- Content Protection Settings ---
const contentProtectionEnabled = computed({
get: () => {
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ThreadView from '@/components/ThreadView.vue'
import ModelCheckDialog from '@/components/settings/ModelCheckDialog.vue'
import { useModelCheckStore } from '@/stores/modelCheck'
import MessageDialog from './components/ui/MessageDialog.vue'
import { useCodeFontSize } from '@/composables/useCodeFontSize'
import 'vue-sonner/style.css' // vue-sonner v2 requires this import

const route = useRoute()
Expand All @@ -30,6 +31,9 @@ const themeStore = useThemeStore()
const langStore = useLanguageStore()
const modelCheckStore = useModelCheckStore()
const { t } = useI18n()

// Initialize code font size
useCodeFontSize()
// Error notification queue and currently displayed error
const errorQueue = ref<Array<{ id: string; title: string; message: string; type: string }>>([])
const currentErrorId = ref<string | null>(null)
Expand Down
10 changes: 10 additions & 0 deletions src/renderer/src/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@

html {
--dc-font-scale: 1;
--dc-code-font-size: 14px;
}

html.text-sm {
Expand Down Expand Up @@ -979,3 +980,12 @@
font-weight: var(--text-weight);
}
}

/* Code font size customization */
.prose pre,
.prose code,
.prose pre code,
.cm-editor .cm-content,
.cm-editor .cm-line {
font-size: var(--dc-code-font-size) !important;
}
2 changes: 1 addition & 1 deletion src/renderer/src/components/ChatInput.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div
class="w-full max-w-4xl mx-auto"
class="w-full"
@dragenter.prevent="handleDragEnter"
@dragover.prevent="handleDragOver"
@drop.prevent="handleDrop"
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/src/components/icons/ModelIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import ppioColorIcon from '@/assets/llm-icons/ppio-color.svg?url'
import tokenfluxColorIcon from '@/assets/llm-icons/tokenflux-color.svg?url'
import moonshotColorIcon from '@/assets/llm-icons/moonshot.svg?url'
import openrouterColorIcon from '@/assets/llm-icons/openrouter.svg?url'
import poeColorIcon from '@/assets/llm-icons/poe-color.svg?url'
import geminiColorIcon from '@/assets/llm-icons/gemini-color.svg?url'
import githubColorIcon from '@/assets/llm-icons/github.svg?url'
import azureOpenaiColorIcon from '@/assets/llm-icons/azure-color.svg?url'
Expand Down Expand Up @@ -119,6 +120,7 @@ const icons = {
qwen: qwenColorIcon,
moonshot: moonshotColorIcon,
openrouter: openrouterColorIcon,
poe: poeColorIcon,
gemini: geminiColorIcon,
github: githubColorIcon,
anthropic: claudeColorIcon,
Expand Down
25 changes: 25 additions & 0 deletions src/renderer/src/composables/useCodeFontSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { watch } from 'vue'
import { useSettingsStore } from '@/stores/settings'

/**
* Composable for managing code font size
* Updates the CSS custom property when the setting changes
*/
export function useCodeFontSize() {
const settingsStore = useSettingsStore()

// Update CSS custom property when code font size changes
watch(
() => settingsStore.codeFontSizeValue,
(newSize) => {
document.documentElement.style.setProperty('--dc-code-font-size', newSize)
},
{ immediate: true }
)

return {
codeFontSizeLevel: settingsStore.codeFontSizeLevel,
codeFontSizeValue: settingsStore.codeFontSizeValue,
updateCodeFontSizeLevel: settingsStore.updateCodeFontSizeLevel
}
}
1 change: 1 addition & 0 deletions src/renderer/src/i18n/en-US/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@
"text-lg": "Large",
"text-xl": "X-Large",
"text-2xl": "XX-Large",
"codeFontSize": "Code font size",
"floatingButton": "Floating Button",
"floatingButtonDesc": "Display a floating button on the desktop to quickly activate the application window"
},
Expand Down
1 change: 1 addition & 0 deletions src/renderer/src/i18n/zh-CN/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@
"text-lg": "大",
"text-xl": "特大",
"text-2xl": "超大",
"codeFontSize": "代码字体大小",
"floatingButton": "悬浮按钮",
"floatingButtonDesc": "在桌面显示一个悬浮按钮,可以快速唤起应用窗口"
},
Expand Down
30 changes: 30 additions & 0 deletions src/renderer/src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import { useThrottleFn } from '@vueuse/core'
const FONT_SIZE_CLASSES = ['text-sm', 'text-base', 'text-lg', 'text-xl', 'text-2xl']
const DEFAULT_FONT_SIZE_LEVEL = 1 // 对应 'text-base'

// 定义代码字体大小级别对应的 CSS 值
const CODE_FONT_SIZE_VALUES = ['12px', '14px', '16px', '18px', '20px']
const DEFAULT_CODE_FONT_SIZE_LEVEL = 1 // 对应 '14px'

export const useSettingsStore = defineStore('settings', () => {
const configP = usePresenter('configPresenter')
const llmP = usePresenter('llmproviderPresenter')
Expand All @@ -35,6 +39,7 @@ export const useSettingsStore = defineStore('settings', () => {
const copyWithCotEnabled = ref<boolean>(true)
const notificationsEnabled = ref<boolean>(true) // 系统通知是否启用,默认启用
const fontSizeLevel = ref<number>(DEFAULT_FONT_SIZE_LEVEL) // 字体大小级别,默认为 1
const codeFontSizeLevel = ref<number>(DEFAULT_CODE_FONT_SIZE_LEVEL) // 代码字体大小级别,默认为 1
// Ollama 相关状态
const ollamaRunningModels = ref<OllamaModel[]>([])
const ollamaLocalModels = ref<OllamaModel[]>([])
Expand Down Expand Up @@ -231,6 +236,11 @@ export const useSettingsStore = defineStore('settings', () => {
() => FONT_SIZE_CLASSES[fontSizeLevel.value] || FONT_SIZE_CLASSES[DEFAULT_FONT_SIZE_LEVEL]
)

// 代码字体大小对应的 CSS 值
const codeFontSizeValue = computed(
() => CODE_FONT_SIZE_VALUES[codeFontSizeLevel.value] || CODE_FONT_SIZE_VALUES[DEFAULT_CODE_FONT_SIZE_LEVEL]
)

// 维护 provider 状态变更时间戳的映射
const providerTimestamps = ref<Record<string, number>>({})

Expand Down Expand Up @@ -312,6 +322,14 @@ export const useSettingsStore = defineStore('settings', () => {
fontSizeLevel.value = DEFAULT_FONT_SIZE_LEVEL
}

// 获取代码字体大小级别
codeFontSizeLevel.value =
(await configP.getSetting<number>('codeFontSizeLevel')) ?? DEFAULT_CODE_FONT_SIZE_LEVEL
// 确保级别在有效范围内
if (codeFontSizeLevel.value < 0 || codeFontSizeLevel.value >= CODE_FONT_SIZE_VALUES.length) {
codeFontSizeLevel.value = DEFAULT_CODE_FONT_SIZE_LEVEL
}

// 获取搜索预览设置
searchPreviewEnabled.value = await configP.getSearchPreviewEnabled()

Expand Down Expand Up @@ -642,6 +660,15 @@ export const useSettingsStore = defineStore('settings', () => {
}
}

// 更新代码字体大小级别
const updateCodeFontSizeLevel = async (level: number) => {
const validLevel = Math.max(0, Math.min(level, CODE_FONT_SIZE_VALUES.length - 1))
if (codeFontSizeLevel.value !== validLevel) {
codeFontSizeLevel.value = validLevel
await configP.setSetting('codeFontSizeLevel', validLevel)
}
}

// 监听 provider 设置变化
const setupProviderListener = () => {
// 监听配置变更事件
Expand Down Expand Up @@ -1750,6 +1777,8 @@ export const useSettingsStore = defineStore('settings', () => {
providers,
fontSizeLevel, // Expose font size level
fontSizeClass, // Expose font size class
codeFontSizeLevel, // Expose code font size level
codeFontSizeValue, // Expose code font size CSS value
enabledModels,
allProviderModels,
customModels,
Expand All @@ -1763,6 +1792,7 @@ export const useSettingsStore = defineStore('settings', () => {
loggingEnabled,
updateProvider,
updateFontSizeLevel, // Expose update function
updateCodeFontSizeLevel, // Expose code font size update function
initSettings,
searchModels,
refreshAllModels,
Expand Down