fix(stage-web,stage-tamagotchi): i18n (#246)

This commit is contained in:
LiliumNeko
2025-06-29 21:50:30 +08:00
committed by GitHub
parent 77a48d9971
commit ad1afb4bd1
6 changed files with 143 additions and 104 deletions
+10 -10
View File
@@ -150,18 +150,18 @@ settings:
provider-model-selection:
collapse: 折叠
custom_model_placeholder: 输入自订模型名字
description: 为意识选择合适的 LLM 提供商
description: 为意识选择合适的 LLM 服务来源
error: 获取出错啦
expand: 展开
loading: 获取模型中...
manual_model_name: 模型名字
manual_model_placeholder: 输入与该提供商一起使用的模型名字
manual_model_placeholder: 输入与该服务来源一起使用的模型名字
no_models: 没有任何可用的模型
no_models_description: 提供商的模型列表没有返回任何的数据
no_models_description: 服务来源的模型列表没有返回任何的数据
no_search_results: 没有匹配的模型
no_search_results_description: 没有模型匹配 '{query}' 关键字,请尝试一下别的关键词呢
not_supported: 无法列出模型
not_supported_description: 提供商不支持列出模型的功能
not_supported_description: 服务来源不支持列出模型的功能
search_placeholder: 搜索模型...
search_results: 找到 {count} / {total} 个模型
show_less: 显示更多
@@ -201,11 +201,11 @@ settings:
provider-voice-selection:
custom_model_placeholder: 输入指定模型名字...
custom_voice_placeholder: 输入指定声线 ID...
description: 选择合适的语音提供商
description: 选择合适的语音服务来源
no_models: 没有任何可用的模型
no_models_description: 提供商的模型列表没有返回任何的数据
no_models_description: 服务来源的模型列表没有返回任何的数据
no_voices: 没有任何可用的声线
no_voices_description: 提供商的声线列表没有返回任何的数据
no_voices_description: 服务来源的声线列表没有返回任何的数据
pause: Pause
play_sample: Play
search_models_placeholder: 搜索模型...
@@ -214,7 +214,7 @@ settings:
search_voices_results: 找到 {count} / {total} 个声线
show_less: 显示更少
show_more: 显示更多
title: 选择语音合成提供商
title: 选择语音合成服务来源
voice-settings:
input-ssml:
placeholder: 请输入 SSML 文本
@@ -255,7 +255,7 @@ settings:
title: 基础配置
voice:
title: 声音配置
description: LLM,语音合成,语音识别提供商
description: LLM,语音合成,语音识别服务来源
provider:
alibaba-cloud-model-studio:
description: bailian.console.aliyun.com
@@ -377,7 +377,7 @@ settings:
xai:
description: X.AI
title: xAI
title: 提供商
title: 服务来源
scene:
description: 配置角色所在环境
title: 场景
+29
View File
@@ -244,6 +244,14 @@ settings:
description: Connect and manage MCP server and tools
title: MCP Server
providers:
explained:
chat: Text generation model providers. e.g. OpenRouter, OpenAI, Ollama.
Speech: Speech (text-to-speech) model providers. e.g. ElevenLabs, Azure Speech.
Transcription: Transcription (speech-to-text) model providers. e.g. Whisper.cpp, OpenAI, Azure Speech
helpinfo:
title: First time here?
description: >
AIRI requires at least one {chat} provider to be configured to think, and behave properly. You could think of it as the brain of the characters living in AIRI system.
common:
fields:
field:
@@ -268,12 +276,27 @@ settings:
title: Voice Settings
description: LLMs, speech providers, etc.
provider:
app-local-audio-speech:
title: Browser (Local)
description: https://github.com/moeru-ai/xsai-transformers
browser-local-audio-speech:
title: Browser (Local)
description: https://github.com/moeru-ai/xsai-transformers
alibaba-cloud-model-studio:
description: bailian.console.aliyun.com
title: Alibaba Cloud Model Studio
anthropic:
description: anthropic.com
title: Anthropic | Claude
helpinfo:
title: Before you start
description:
part1: While Anthropic recently did announce that they are having a beta support for OpenAI SDK compatibility
part2: (you can read more here)
part3: but due to the implementation details comes with
part4: restrictions which not aligned with the OpenAI SDK, it's currently not possible to use this provider in the browser.
part5: If you do need to use this provider, you will need a dedicated proxy backend like a Serverless Function running on
part6: or some CORS bypassing services to bypass the CORS restrictions.
cloudflare-workers-ai:
description: cloudflare.com
fields:
@@ -379,6 +402,12 @@ settings:
together:
description: together.ai
title: Together.ai
google-generative-ai:
description: gemini.google.com
title: Google Gemini
featherless:
description: featherless.ai
title: Featherless AI
vllm:
description: vllm.ai
title: vLLM
+58 -17
View File
@@ -146,19 +146,19 @@ settings:
section:
provider-model-selection:
collapse: 折叠
custom_model_placeholder: 输入自订模型名
description: 为意识选择合适的 LLM 提供商
custom_model_placeholder: 输入自订模型名
description: 为意识选择合适的 LLM 服务来源
error: 获取出错啦
expand: 展开
loading: 获取模型中...
manual_model_name: 模型名字
manual_model_placeholder: 输入与该提供商一起使用的模型名
manual_model_placeholder: 输入与该服务来源一起使用的模型名
no_models: 没有任何可用的模型
no_models_description: 提供商的模型列表没有返回任何的数据
no_models_description: 服务来源的模型列表没有返回任何的数据
no_search_results: 没有匹配的模型
no_search_results_description: 没有模型匹配 '{query}' 关键字,请尝试一下别的关键词呢
not_supported: 无法列出模型
not_supported_description: 提供商不支持列出模型的功能
not_supported_description: 服务来源不支持列出模型的功能
search_placeholder: 搜索模型...
search_results: 找到 {count} / {total} 个模型
show_less: 显示更多
@@ -171,7 +171,7 @@ settings:
description: 一起玩 Factorio
title: 异星工厂 Factorio
gaming-minecraft:
description: 一起 Minecraft
description: 一起 Minecraft
title: 我的世界 Minecraft
hearing:
description: 语音识别
@@ -196,13 +196,13 @@ settings:
select-voice:
required: 请选择声线
provider-voice-selection:
custom_model_placeholder: 输入指定模型名...
custom_model_placeholder: 输入指定模型名...
custom_voice_placeholder: 输入指定声线 ID...
description: 选择合适的语音提供商
description: 选择合适的语音服务来源
no_models: 没有任何可用的模型
no_models_description: 提供商的模型列表没有返回任何的数据
no_models_description: 服务来源的模型列表没有返回任何的数据
no_voices: 没有任何可用的声线
no_voices_description: 提供商的声线列表没有返回任何的数据
no_voices_description: 服务来源的声线列表没有返回任何的数据
pause: Pause
play_sample: Play
search_models_placeholder: 搜索模型...
@@ -211,7 +211,7 @@ settings:
search_voices_results: 找到 {count} / {total} 个声线
show_less: 显示更少
show_more: 显示更多
title: 选择语音合成提供商
title: 选择语音合成服务来源
voice-settings:
input-ssml:
placeholder: 请输入 SSML 文本
@@ -230,6 +230,14 @@ settings:
description: 连接和管理 MCP 服务器及工具
title: MCP 服务器
providers:
explained:
chat: 文本生成模型服务来源,例如 OpenRouter, OpenAI, Ollama
Speech: 语音(文本转语音)模型服务来源,例如 ElevenLabs, Azure Speech
Transcription: 转录(语音转文本)模型服务来源,例如 Whisper.cpp, OpenAI, Azure Speech
helpinfo:
title: 第一次使用?
description: >
AIRI 需要配置至少一个 {chat} 服务来源,才能正常思考和运作。你可以把它看作是 AIRI 系统中角色的大脑。
common:
fields:
field:
@@ -252,14 +260,29 @@ settings:
title: 基础配置
voice:
title: 声音配置
description: LLM,语音合成,语音识别提供商
description: LLM,语音合成,语音识别服务来源
provider:
app-local-audio-speech:
title: 浏览器内(本地)
description: https://github.com/moeru-ai/xsai-transformers
browser-local-audio-speech:
title: 浏览器内(本地)
description: https://github.com/moeru-ai/xsai-transformers
alibaba-cloud-model-studio:
description: bailian.console.aliyun.com
title: 阿里百炼
anthropic:
description: anthropic.com
title: Anthropic | Claude
helpinfo:
title: 开始之前
description:
part1: 虽然 Anthropic 最近宣布他们正在提供对 OpenAI SDK 兼容性的 Beta 版支持
part2: (您可以在此处阅读更多信息)
part3: 但由于实现细节附带
part4: 与 OpenAI SDK 不一致,目前无法在浏览器中使用此提供程序。
part5: 如果您确实需要使用此提供程序,则需要一个专用的代理后端,例如在
part6: 上运行的Serverless Function,或者一些绕过 CORS 的服务,以绕过 CORS 限制。
cloudflare-workers-ai:
description: Cloudflare.com
fields:
@@ -275,7 +298,7 @@ settings:
fields:
field:
pitch:
description: 调节合成语音的音高(比如更尖锐或更粗旷)
description: 调节合成语音的音高(比如更尖锐或更粗旷)
label: 音高
speed:
description: 调节说话的语速
@@ -291,7 +314,7 @@ settings:
fields:
field:
simularity-boost:
description: 声音相似性依从性
description: 声音相似性依从性
label: 相似度修正
speaker-boost:
description: 增强说话者的相似性
@@ -303,7 +326,7 @@ settings:
description: 语音稳定性和随机性
label: 稳定性
style:
description: 语音风格夸张
description: 夸张的语音风格
label: 风格
playground:
buttons:
@@ -357,9 +380,18 @@ settings:
perplexity:
description: perplexity.ai
title: Perplexity
player2:
description: player2.game
title: Player2 API
together:
description: 一起
description: together.ai
title: Together.ai
google-generative-ai:
description: gemini.google.com
title: Google Gemini
featherless:
description: featherless.ai
title: Featherless AI
vllm:
description: vllm.ai
title: vLLM
@@ -374,11 +406,20 @@ settings:
xai:
description: X.AI
title: xAI
title: 提供商
title: 服务来源
scene:
description: 配置角色所在环境
title: 场景
themes:
color-scheme:
description: 更改舞台的配色方案
title: 配色方案
developer:
description: 为开发者提供的选项
title: 开发者
general:
description: 深色主题、语言等选项
title: 通用
description: 自定义你的舞台外观!
sections:
section:
@@ -81,18 +81,18 @@ function handleResetSettings() {
:on-back="() => router.back()"
>
<div bg="orange-50 dark:orange-900/20" rounded-xl p-4 flex="~ col gap-3">
<h2 text-xl font-normal text="orange-700 dark:orange-500">
Before you start
<h2 text-xl font-semibold text="orange-700 dark:orange-500">
{{ t('settings.pages.providers.provider.anthropic.helpinfo.title') }}
</h2>
<p>
While Anthropic recently did announce that they are having a beta support for
OpenAI SDK compatibility <a underline href="https://docs.anthropic.com/en/api/openai-sdk">(you can read more here)</a>,
but due to the implementation details comes with <a underline href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS">CORS</a>
restrictions which not aligned with the OpenAI SDK, it's currently not possible to use this provider in the browser.
{{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part1') }}
<a underline href="https://docs.anthropic.com/en/api/openai-sdk">{{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part2') }}</a>,
{{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part3') }} <a underline href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS">CORS</a>
{{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part4') }}
</p>
<p>
If you do need to use this provider, you will need a dedicated proxy backend like a Serverless Function running on
<a underline href="https://workers.cloudflare.com/">Cloudflare Workers</a> or some CORS bypassing services to bypass the CORS restrictions.
{{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part5') }}
<a underline href="https://workers.cloudflare.com/">Cloudflare Workers</a> {{ t('settings.pages.providers.provider.anthropic.helpinfo.description.part6') }}
</p>
</div>
<ProviderSettingsContainer>
@@ -2,10 +2,13 @@
import { IconStatusItem } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores'
import { storeToRefs } from 'pinia'
import { useI18n } from 'vue-i18n'
import IconAnimation from '../../../components/IconAnimation.vue'
import { useIconAnimation } from '../../../composables/useIconAnimation'
const { t } = useI18n()
const providersStore = useProvidersStore()
const {
allChatProvidersMetadata,
@@ -22,22 +25,26 @@ const {
<template>
<div flex flex-col gap-5>
<div bg="primary-500/10 dark:primary-800/25" rounded-lg p-4>
<div mb-2 text-xl font-normal text="primary-800 dark:primary-100">
First time here?
<div class="rounded-lg bg-primary-500/10 p-4 dark:bg-primary-800/25">
<div class="mb-2 text-xl text-primary-800 font-semibold dark:text-primary-100">
{{ $t('settings.pages.providers.helpinfo.title') }}
</div>
<div text="primary-700 dark:primary-300">
AIRI requires at least one <div bg="primary-500/10 dark:primary-800/25" inline-flex items-center gap-1 rounded-lg px-2 py-0.5 translate-y="[0.25lh]">
<div i-solar:chat-square-like-bold-duotone /><strong font-normal>Chat</strong>
</div> provider to be configured to think, and behave properly. You could think of
it as the brain of the characters living in AIRI system.
<div class="text-primary-700 dark:text-primary-300">
<i18n-t keypath="settings.pages.providers.helpinfo.description">
<template #chat>
<span class="inline-flex translate-y-[0.25lh] items-center gap-1 rounded-lg bg-primary-500/10 px-2 py-0.5 dark:bg-primary-800/25">
<div class="i-solar:chat-square-like-bold-duotone" />
<strong class="font-semibold">Chat</strong>
</span>
</template>
</i18n-t>
</div>
</div>
<div flex="~ row items-center gap-2">
<div i-solar:chat-square-like-bold-duotone text="neutral-500 dark:neutral-400 4xl" />
<div>
<div>
<span text="neutral-300 dark:neutral-500">Text generation model providers. e.g. OpenRouter, OpenAI, Ollama.</span>
<span text="neutral-300 dark:neutral-500">{{ t('settings.pages.providers.explained.chat') }} </span>
</div>
<div flex text-nowrap text-3xl font-normal>
<div>
@@ -48,19 +55,10 @@ const {
</div>
<div grid="~ cols-2 gap-4">
<IconStatusItem
v-for="(provider, index) of allChatProvidersMetadata"
:key="provider.id"
v-motion
:initial="{ opacity: 0, y: 10 }"
:enter="{ opacity: 1, y: 0 }"
:duration="250 + index * 10"
:delay="index * 50"
:title="provider.localizedName || 'Unknown'"
:description="provider.localizedDescription"
:icon="provider.icon"
:icon-color="provider.iconColor"
:icon-image="provider.iconImage"
:to="`/settings/providers/${provider.id}`"
v-for="(provider, index) of allChatProvidersMetadata" :key="provider.id" v-motion
:initial="{ opacity: 0, y: 10 }" :enter="{ opacity: 1, y: 0 }" :duration="250 + index * 10" :delay="index * 50"
:title="provider.localizedName || 'Unknown'" :description="provider.localizedDescription" :icon="provider.icon"
:icon-color="provider.iconColor" :icon-image="provider.iconImage" :to="`/settings/providers/${provider.id}`"
:configured="provider.configured"
/>
</div>
@@ -68,7 +66,7 @@ const {
<div i-solar:user-speak-rounded-bold-duotone text="neutral-500 dark:neutral-400 4xl" />
<div>
<div>
<span text="neutral-300 dark:neutral-500">Speech (text-to-speech) model providers. e.g. ElevenLabs, Azure Speech.</span>
<span text="neutral-300 dark:neutral-500">{{ t('settings.pages.providers.explained.Speech') }}</span>
</div>
<div flex text-nowrap text-3xl font-normal>
<div>
@@ -79,27 +77,18 @@ const {
</div>
<div grid="~ cols-2 gap-4">
<IconStatusItem
v-for="(provider, index) of allAudioSpeechProvidersMetadata"
:key="provider.id"
v-motion
:initial="{ opacity: 0, y: 10 }"
:enter="{ opacity: 1, y: 0 }"
:duration="250 + index * 10"
:delay="(allChatProvidersMetadata.length + index) * 50"
:title="provider.localizedName || 'Unknown'"
:description="provider.localizedDescription"
:icon="provider.icon"
:icon-color="provider.iconColor"
:icon-image="provider.iconImage"
:to="`/settings/providers/${provider.id}`"
:configured="provider.configured"
v-for="(provider, index) of allAudioSpeechProvidersMetadata" :key="provider.id" v-motion
:initial="{ opacity: 0, y: 10 }" :enter="{ opacity: 1, y: 0 }" :duration="250 + index * 10"
:delay="(allChatProvidersMetadata.length + index) * 50" :title="provider.localizedName || 'Unknown'"
:description="provider.localizedDescription" :icon="provider.icon" :icon-color="provider.iconColor"
:icon-image="provider.iconImage" :to="`/settings/providers/${provider.id}`" :configured="provider.configured"
/>
</div>
<div flex="~ row items-center gap-2" my-5>
<div i-solar:microphone-3-bold-duotone text="neutral-500 dark:neutral-400 4xl" />
<div>
<div>
<span text="neutral-300 dark:neutral-500">Transcription (speech-to-text) model providers. e.g. Whisper.cpp, OpenAI, Azure Speech</span>
<span text="neutral-300 dark:neutral-500">{{ t('settings.pages.providers.explained.Transcription') }}</span>
</div>
<div flex text-nowrap text-3xl font-normal>
<div>
@@ -110,44 +99,24 @@ const {
</div>
<div grid="~ cols-2 gap-4">
<IconStatusItem
v-for="(provider, index) of allAudioTranscriptionProvidersMetadata"
:key="provider.id"
v-motion
:initial="{ opacity: 0, y: 10 }"
:enter="{ opacity: 1, y: 0 }"
:duration="250 + index * 10"
v-for="(provider, index) of allAudioTranscriptionProvidersMetadata" :key="provider.id" v-motion
:initial="{ opacity: 0, y: 10 }" :enter="{ opacity: 1, y: 0 }" :duration="250 + index * 10"
:delay="(allChatProvidersMetadata.length + allAudioSpeechProvidersMetadata.length + index) * 50"
:title="provider.localizedName || 'Unknown'"
:description="provider.localizedDescription"
:icon="provider.icon"
:icon-color="provider.iconColor"
:icon-image="provider.iconImage"
:to="`/settings/providers/${provider.id}`"
:title="provider.localizedName || 'Unknown'" :description="provider.localizedDescription" :icon="provider.icon"
:icon-color="provider.iconColor" :icon-image="provider.iconImage" :to="`/settings/providers/${provider.id}`"
:configured="provider.configured"
/>
</div>
</div>
<IconAnimation
v-if="showIconAnimation"
:z-index="-1"
:icon="animationIcon"
:icon-size="12"
:duration="1000"
:started="iconAnimationStarted"
:is-reverse="true"
position="calc(100dvw - 9.5rem), calc(100dvh - 9.5rem)"
v-if="showIconAnimation" :z-index="-1" :icon="animationIcon" :icon-size="12" :duration="1000"
:started="iconAnimationStarted" :is-reverse="true" position="calc(100dvw - 9.5rem), calc(100dvh - 9.5rem)"
text-color="text-neutral-200/50 dark:text-neutral-600/20"
/>
<div
v-else
v-motion
text="neutral-500/50 dark:neutral-600/20" pointer-events-none
fixed top="[calc(100dvh-15rem)]" bottom-0 right--5 z--1
:initial="{ scale: 0.9, opacity: 0, y: 20 }"
:enter="{ scale: 1, opacity: 1, y: 0 }"
:duration="500"
size-60
flex items-center justify-center
v-else v-motion text="neutral-500/50 dark:neutral-600/20" pointer-events-none fixed top="[calc(100dvh-15rem)]"
bottom-0 right--5 z--1 :initial="{ scale: 0.9, opacity: 0, y: 20 }" :enter="{ scale: 1, opacity: 1, y: 0 }"
:duration="500" size-60 flex items-center justify-center
>
<div text="60" i-solar:box-minimalistic-bold-duotone />
</div>
+2 -2
View File
@@ -135,7 +135,7 @@ pnpm -F @proj-airi/stage-web dev
pnpm -F @proj-airi/stage-tamagotchi dev
```
## 原生支持的 LLM API 提供商列表(由 [xsai](https://github.com/moeru-ai/xsai) 驱动)
## 原生支持的 LLM API 服务来源列表(由 [xsai](https://github.com/moeru-ai/xsai) 驱动)
- [x] [OpenRouter](https://openrouter.ai/)
- [x] [vLLM](https://github.com/vllm-project/vllm)
@@ -179,7 +179,7 @@ pnpm -F @proj-airi/stage-tamagotchi dev
- [🥺 SAD](https://github.com/moeru-ai/sad): 自托管和浏览器运行 LLM 的文档和说明
- [Velin](https://github.com/luoling8192/velin): 用 Vue SFC 和 Markdown 文件来为 LLM 书写简单好用的提示词
- [`demodel`](https://github.com/moeru-ai/demodel): 轻松加速各种推理引擎和模型下载器拉/下载模型或数据集的速度
- [`inventory`](https://github.com/moeru-ai/inventory): 中心化模型目录和默认提供商配置的公开 API 服务
- [`inventory`](https://github.com/moeru-ai/inventory): 中心化模型目录和默认服务来源配置的公开 API 服务
- [MCP Launcher](https://github.com/moeru-ai/mcp-launcher): 易于使用的 MCP 启动器,适用于所有可能的 MCP Server,就像用于模型推理的 Ollama 一样!
- ~~[`@proj-airi/elevenlabs`](https://github.com/moeru-ai/airi/tree/main/packages/elevenlabs): ElevenLabs API 的类型定义~~