Skip to content

Commit 234bf28

Browse files
fix(chat): prompt for OpenCSG API keys
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 6b9b0b1 commit 234bf28

4 files changed

Lines changed: 114 additions & 150 deletions

File tree

web/src/i18n.ts

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ const en: Record<string, string> = {
183183
"aiApps.currentModelHint": "Select the model ID to use for launch, then copy it for `csghub-lite launch --model` if needed.",
184184
"aiApps.openDocs": "Open docs",
185185
"aiApps.openSettings": "Open Settings",
186-
"aiApps.error.noLocalModelsOpenCSG": "No local models are available yet. Pull a model first, or open Settings to save an Access Token and use OpenCSG models.",
186+
"aiApps.error.noLocalModelsOpenCSG": "No local models are available yet. Pull a model first, or open Settings to save an API Key and use OpenCSG models.",
187187
"aiApps.error.noLocalOrCloudModels": "No local or OpenCSG models are available yet. Pull a model first, or check OpenCSG model access in Settings.",
188188
"aiApps.error.noModelsFound": "No available models were found. Pull a model first and then open the app.",
189-
"aiApps.error.modelUnavailableWithCloudHint": "Model \"{0}\" isn't available for AI Apps. If you want to use an OpenCSG model, open Settings and save an Access Token first.",
190-
"aiApps.error.modelUnavailableCloudHint": "This model isn't available for AI Apps. If you want to use an OpenCSG model, open Settings and save an Access Token first.",
189+
"aiApps.error.modelUnavailableWithCloudHint": "Model \"{0}\" isn't available for AI Apps. If you want to use an OpenCSG model, open Settings and save an API Key first.",
190+
"aiApps.error.modelUnavailableCloudHint": "This model isn't available for AI Apps. If you want to use an OpenCSG model, open Settings and save an API Key first.",
191191
"aiApps.error.modelUnavailable": "Model \"{0}\" isn't available for AI Apps.",
192192
"aiApps.cnHint": "China-Friendly Notes",
193193
"aiApps.plannedSteps": "Planned Steps",
@@ -301,8 +301,8 @@ const en: Record<string, string> = {
301301
"settings.autostartDesc": "Automatically start csghub-lite when you log in to your computer.",
302302
"settings.autostartOn": "Enabled",
303303
"settings.autostartOff": "Disabled",
304-
"settings.account": "Account",
305-
"settings.accountDesc": "View your current OpenCSG login and sign out if needed.",
304+
"settings.account": "OpenCSG API Key",
305+
"settings.accountDesc": "Manage the API Key used for OpenCSG AI Gateway cloud models.",
306306
"settings.providers": "Third-party Providers",
307307
"settings.providersDesc": "Add OpenAI-compatible providers so their models appear in Chat alongside local and OpenCSG models.",
308308
"settings.providersConfigured": "{0} providers configured",
@@ -333,15 +333,14 @@ const en: Record<string, string> = {
333333
"settings.apiDocsTitle": "Local API reference",
334334
"settings.apiDocsHint": "Swagger UI for `/api/*`, OpenAI-compatible, and Anthropic-compatible endpoints.",
335335
"settings.openApiDocs": "Open API Docs",
336-
"settings.loggedOut": "Not logged in",
337-
"settings.loggedOutDesc": "Sign in to OpenCSG and save an Access Token to use OpenCSG models.",
338-
"settings.login": "Open Login",
339-
"settings.openTokenPage": "Open Access Token Page",
340-
"settings.tokenSaved": "Access Token saved",
341-
"settings.tokenSavedDesc": "We couldn't load profile details right now. You can sign in again or log out.",
342-
"settings.tokenInputHint": "Paste an OpenCSG Access Token here to sign in or replace the saved token.",
343-
"settings.logout": "Log out",
344-
"settings.loggingOut": "Logging out...",
336+
"settings.loggedOut": "API Key not configured",
337+
"settings.loggedOutDesc": "Create an API Key in OpenCSG settings, then paste it below to use OpenCSG models.",
338+
"settings.openTokenPage": "Open API Key Page",
339+
"settings.tokenSaved": "API Key saved",
340+
"settings.tokenSavedDesc": "The saved API Key can be used for OpenCSG AI Gateway requests. You can replace or remove it below.",
341+
"settings.tokenInputHint": "Paste an OpenCSG API Key here to enable or replace cloud model access.",
342+
"settings.logout": "Remove API Key",
343+
"settings.loggingOut": "Removing...",
345344

346345
// Library
347346
"lib.title": "Models",
@@ -474,18 +473,20 @@ const en: Record<string, string> = {
474473
"chat.cloud": "OpenCSG",
475474
"chat.local": "Local",
476475
"chat.provider": "Provider",
477-
"chat.cloudLoginTitle": "Login required for OpenCSG models",
478-
"chat.cloudLoginDesc": "OpenCSG models run on OpenCSG AI Space. Open the login page in your browser, then paste an Access Token here so csghub-lite can proxy requests securely.",
479-
"chat.cloudOpenLogin": "Open Login",
480-
"chat.cloudOpenTokenPage": "Open Access Token Page",
481-
"chat.cloudTokenLabel": "Access Token",
482-
"chat.cloudTokenPlaceholder": "Paste your OpenCSG access token",
483-
"chat.cloudSaveToken": "Save Token",
484-
"chat.cloudSavingToken": "Saving...",
485476
"chat.cloudCancel": "Not now",
486-
"chat.cloudLoginRequired": "OpenCSG models require an OpenCSG login.",
487-
"chat.cloudLoginExpired": "OpenCSG login expired or token is invalid. Please log in again and update your Access Token.",
488-
"chat.cloudTokenEmpty": "Please paste an Access Token.",
477+
"chat.cloudApiKeyTitle": "OpenCSG AI Gateway API Key",
478+
"chat.cloudApiKeyDesc": "OpenCSG models use the OpenCSG AI Gateway. Enter your API Key here to enable cloud model requests from csghub-lite.",
479+
"chat.cloudGatewayLabel": "AI Gateway URL",
480+
"chat.cloudGatewayValue": "https://ai.space.opencsg.com",
481+
"chat.cloudApiKeyLabel": "API Key",
482+
"chat.cloudApiKeyPlaceholder": "Paste your OpenCSG API Key",
483+
"chat.cloudApiKeyHint": "Create or copy an API Key from your OpenCSG account settings, then paste it here.",
484+
"chat.cloudApiKeyHelp": "Get API Key",
485+
"chat.cloudApiKeyRequired": "OpenCSG cloud models require an AI Gateway API Key.",
486+
"chat.cloudApiKeyInvalid": "The API Key is invalid or has expired. Please create a new API Key and save it again.",
487+
"chat.cloudApiKeyEmpty": "Please paste an API Key.",
488+
"chat.cloudApiKeySave": "Save API Key",
489+
"chat.cloudApiKeySaving": "Saving...",
489490
"chat.copyModel": "Copy model name",
490491
"chat.conversations": "Conversations",
491492
"chat.conversationHistory": "Conversation History",
@@ -718,11 +719,11 @@ const zh: Record<string, string> = {
718719
"aiApps.currentModelHint": "可在这里切换要用于启动的模型 ID,并按需复制给 `csghub-lite launch --model` 使用。",
719720
"aiApps.openDocs": "打开文档",
720721
"aiApps.openSettings": "前往设置",
721-
"aiApps.error.noLocalModelsOpenCSG": "当前还没有本地模型。你可以先拉取本地模型,或前往设置保存 Access Token,直接使用 OpenCSG 模型。",
722+
"aiApps.error.noLocalModelsOpenCSG": "当前还没有本地模型。你可以先拉取本地模型,或前往设置保存 API Key,直接使用 OpenCSG 模型。",
722723
"aiApps.error.noLocalOrCloudModels": "当前既没有本地模型,也没有可用的 OpenCSG 模型。你可以先拉取本地模型,或前往设置检查 OpenCSG 模型访问权限。",
723724
"aiApps.error.noModelsFound": "当前没有可用模型,请先拉取模型后再打开应用。",
724-
"aiApps.error.modelUnavailableWithCloudHint": "模型“{0}”当前不能用于 AI 应用。如果你想使用 OpenCSG 模型,请先前往设置保存 Access Token。",
725-
"aiApps.error.modelUnavailableCloudHint": "当前模型不能用于 AI 应用。如果你想使用 OpenCSG 模型,请先前往设置保存 Access Token。",
725+
"aiApps.error.modelUnavailableWithCloudHint": "模型“{0}”当前不能用于 AI 应用。如果你想使用 OpenCSG 模型,请先前往设置保存 API Key。",
726+
"aiApps.error.modelUnavailableCloudHint": "当前模型不能用于 AI 应用。如果你想使用 OpenCSG 模型,请先前往设置保存 API Key。",
726727
"aiApps.error.modelUnavailable": "模型“{0}”当前不能用于 AI 应用。",
727728
"aiApps.cnHint": "国内环境提示",
728729
"aiApps.plannedSteps": "计划步骤",
@@ -823,8 +824,8 @@ const zh: Record<string, string> = {
823824
"settings.autostartDesc": "登录计算机时自动启动 csghub-lite。",
824825
"settings.autostartOn": "已开启",
825826
"settings.autostartOff": "已关闭",
826-
"settings.account": "账号",
827-
"settings.accountDesc": "查看当前 OpenCSG 登录账号,并在需要时退出登录。",
827+
"settings.account": "OpenCSG API Key",
828+
"settings.accountDesc": "管理用于 OpenCSG AI Gateway 云端模型的 API Key。",
828829
"settings.providers": "第三方 Provider",
829830
"settings.providersDesc": "添加 OpenAI 兼容 Provider,让它们的模型和本地、OpenCSG 模型一起出现在 Chat 中。",
830831
"settings.providersConfigured": "已配置 {0} 个 Provider",
@@ -855,15 +856,14 @@ const zh: Record<string, string> = {
855856
"settings.apiDocsTitle": "本地 API 参考",
856857
"settings.apiDocsHint": "包含 `/api/*`、OpenAI 兼容接口和 Anthropic 兼容接口的 Swagger UI。",
857858
"settings.openApiDocs": "打开 API 文档",
858-
"settings.loggedOut": "未登录",
859-
"settings.loggedOutDesc": "登录 OpenCSG 并保存 Access Token 后,才可以使用 OpenCSG 模型。",
860-
"settings.login": "打开登录页",
861-
"settings.openTokenPage": "打开 Access Token 页面",
862-
"settings.tokenSaved": "已保存 Access Token",
863-
"settings.tokenSavedDesc": "暂时无法加载用户资料,你可以重新登录或直接退出登录。",
864-
"settings.tokenInputHint": "在这里粘贴 OpenCSG Access Token,即可登录或替换当前已保存的 token。",
865-
"settings.logout": "退出登录",
866-
"settings.loggingOut": "退出中...",
859+
"settings.loggedOut": "未配置 API Key",
860+
"settings.loggedOutDesc": "请先在 OpenCSG 设置中创建 API Key,然后粘贴到下方即可使用 OpenCSG 模型。",
861+
"settings.openTokenPage": "打开 API Key 页面",
862+
"settings.tokenSaved": "已保存 API Key",
863+
"settings.tokenSavedDesc": "已保存的 API Key 可用于 OpenCSG AI Gateway 请求,你可以在下方替换或移除。",
864+
"settings.tokenInputHint": "在这里粘贴 OpenCSG API Key,即可启用或替换云端模型访问凭证。",
865+
"settings.logout": "移除 API Key",
866+
"settings.loggingOut": "移除中...",
867867

868868
// Library
869869
"lib.title": "模型库",
@@ -996,18 +996,20 @@ const zh: Record<string, string> = {
996996
"chat.cloud": "OpenCSG",
997997
"chat.local": "本地",
998998
"chat.provider": "Provider",
999-
"chat.cloudLoginTitle": "OpenCSG 模型需要登录",
1000-
"chat.cloudLoginDesc": "OpenCSG 模型运行在 OpenCSG AI Space。请先在浏览器中完成登录,再把 Access Token 粘贴到这里,csghub-lite 才能安全代理你的请求。",
1001-
"chat.cloudOpenLogin": "打开登录页",
1002-
"chat.cloudOpenTokenPage": "打开 Access Token 页面",
1003-
"chat.cloudTokenLabel": "Access Token",
1004-
"chat.cloudTokenPlaceholder": "请粘贴你的 OpenCSG Access Token",
1005-
"chat.cloudSaveToken": "保存 Token",
1006-
"chat.cloudSavingToken": "保存中...",
1007999
"chat.cloudCancel": "稍后再说",
1008-
"chat.cloudLoginRequired": "使用 OpenCSG 模型前需要先登录 OpenCSG。",
1009-
"chat.cloudLoginExpired": "OpenCSG 登录已失效,或当前 token 无效,请重新登录并更新 Access Token。",
1010-
"chat.cloudTokenEmpty": "请先粘贴 Access Token。",
1000+
"chat.cloudApiKeyTitle": "OpenCSG AI Gateway API Key",
1001+
"chat.cloudApiKeyDesc": "OpenCSG 模型通过 OpenCSG AI Gateway 调用。请在这里填写 API Key,csghub-lite 会用它发起云端模型请求。",
1002+
"chat.cloudGatewayLabel": "AI Gateway URL",
1003+
"chat.cloudGatewayValue": "https://ai.space.opencsg.com",
1004+
"chat.cloudApiKeyLabel": "API Key",
1005+
"chat.cloudApiKeyPlaceholder": "请粘贴你的 OpenCSG API Key",
1006+
"chat.cloudApiKeyHint": "可在 OpenCSG 账号设置中创建或复制 API Key,然后粘贴到这里。",
1007+
"chat.cloudApiKeyHelp": "获取 API Key",
1008+
"chat.cloudApiKeyRequired": "使用 OpenCSG 云端模型需要先填写 AI Gateway API Key。",
1009+
"chat.cloudApiKeyInvalid": "API Key 无效或已过期,请重新创建 API Key 后保存。",
1010+
"chat.cloudApiKeyEmpty": "请先粘贴 API Key。",
1011+
"chat.cloudApiKeySave": "保存 API Key",
1012+
"chat.cloudApiKeySaving": "保存中...",
10111013
"chat.conversations": "对话记录",
10121014
"chat.conversationHistory": "对话记录",
10131015
"chat.noConversations": "暂无对话记录",

web/src/pages/AIApps.tsx

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -741,10 +741,10 @@ function LiveLogsDrawer({
741741
return true;
742742
}
743743
} catch {
744-
/* fall through to login dialog */
744+
/* fall through to API key dialog */
745745
}
746746

747-
await openCloudAuthDialog(t("chat.cloudLoginRequired"));
747+
await openCloudAuthDialog(t("chat.cloudApiKeyRequired"));
748748
return false;
749749
};
750750

@@ -764,24 +764,10 @@ function LiveLogsDrawer({
764764
onOpenChat(currentModelID || undefined, currentModelInfo?.source);
765765
};
766766

767-
const handleOpenCloudLogin = () => {
768-
const url = cloudAuth?.login_url;
769-
if (url) {
770-
window.open(url, "_blank", "noopener,noreferrer");
771-
}
772-
};
773-
774-
const handleOpenCloudTokenPage = () => {
775-
const url = cloudAuth?.access_token_url;
776-
if (url) {
777-
window.open(url, "_blank", "noopener,noreferrer");
778-
}
779-
};
780-
781767
const handleSaveCloudToken = async () => {
782768
const token = cloudTokenInput.trim();
783769
if (!token) {
784-
setCloudAuthError(t("chat.cloudTokenEmpty"));
770+
setCloudAuthError(t("chat.cloudApiKeyEmpty"));
785771
return;
786772
}
787773

@@ -791,7 +777,7 @@ function LiveLogsDrawer({
791777
const status = await saveCloudToken(token);
792778
setCloudAuth(status);
793779
if (!hasCloudAuth(status)) {
794-
setCloudAuthError(t("chat.cloudLoginExpired"));
780+
setCloudAuthError(t("chat.cloudApiKeyInvalid"));
795781
return;
796782
}
797783
try {
@@ -1115,8 +1101,8 @@ function LiveLogsDrawer({
11151101
)}
11161102
<div class="flex items-start justify-between gap-4">
11171103
<div>
1118-
<h3 class="text-lg font-semibold text-gray-900">{t("chat.cloudLoginTitle")}</h3>
1119-
<p class="mt-2 text-sm leading-6 text-gray-500">{t("chat.cloudLoginDesc")}</p>
1104+
<h3 class="text-lg font-semibold text-gray-900">{t("chat.cloudApiKeyTitle")}</h3>
1105+
<p class="mt-2 text-sm leading-6 text-gray-500">{t("chat.cloudApiKeyDesc")}</p>
11201106
</div>
11211107
<button
11221108
onClick={() => {
@@ -1132,38 +1118,39 @@ function LiveLogsDrawer({
11321118
</button>
11331119
</div>
11341120

1121+
<div class="mt-5 rounded-xl border border-gray-200 bg-gray-50 px-4 py-3">
1122+
<div class="text-xs font-medium uppercase tracking-wide text-gray-400">{t("chat.cloudGatewayLabel")}</div>
1123+
<div class="mt-1 text-sm font-medium text-gray-800">{t("chat.cloudGatewayValue")}</div>
1124+
</div>
1125+
11351126
{cloudAuthError && (
11361127
<div class="mt-4 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
11371128
{cloudAuthError}
11381129
</div>
11391130
)}
11401131

1141-
<div class="mt-5 flex flex-wrap gap-2">
1142-
<button
1143-
onClick={handleOpenCloudLogin}
1144-
class="rounded-lg border border-gray-200 px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
1145-
>
1146-
{t("chat.cloudOpenLogin")}
1147-
</button>
1148-
<button
1149-
onClick={handleOpenCloudTokenPage}
1150-
class="rounded-lg border border-gray-200 px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 transition-colors"
1151-
>
1152-
{t("chat.cloudOpenTokenPage")}
1153-
</button>
1154-
</div>
1155-
11561132
<div class="mt-5">
1157-
<label class="mb-2 block text-sm font-medium text-gray-700">{t("chat.cloudTokenLabel")}</label>
1133+
<div class="mb-2 flex items-center justify-between gap-3">
1134+
<label class="block text-sm font-medium text-gray-700">{t("chat.cloudApiKeyLabel")}</label>
1135+
<a
1136+
href="https://opencsg.com/settings/api-keys"
1137+
target="_blank"
1138+
rel="noopener noreferrer"
1139+
class="text-sm font-medium text-indigo-600 hover:text-indigo-700"
1140+
>
1141+
{t("chat.cloudApiKeyHelp")}
1142+
</a>
1143+
</div>
11581144
<input
11591145
type="password"
11601146
autoComplete="off"
11611147
spellcheck={false}
11621148
class="w-full rounded-lg border border-gray-200 px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500"
1163-
placeholder={t("chat.cloudTokenPlaceholder")}
1149+
placeholder={t("chat.cloudApiKeyPlaceholder")}
11641150
value={cloudTokenInput}
11651151
onInput={(e) => setCloudTokenInput((e.currentTarget as HTMLInputElement).value)}
11661152
/>
1153+
<p class="mt-2 text-xs leading-5 text-gray-500">{t("chat.cloudApiKeyHint")}</p>
11671154
</div>
11681155

11691156
<div class="mt-5 flex justify-end gap-2">
@@ -1181,7 +1168,7 @@ function LiveLogsDrawer({
11811168
disabled={isSavingCloudToken}
11821169
class="rounded-lg bg-indigo-600 px-4 py-2 text-sm text-white hover:bg-indigo-700 disabled:opacity-60 transition-colors"
11831170
>
1184-
{isSavingCloudToken ? t("chat.cloudSavingToken") : t("chat.cloudSaveToken")}
1171+
{isSavingCloudToken ? t("chat.cloudApiKeySaving") : t("chat.cloudApiKeySave")}
11851172
</button>
11861173
</div>
11871174
</div>

0 commit comments

Comments
 (0)