Skip to content

feat: add DeepChat deeplink support#4668

Open
yyhhyyyyyy wants to merge 1 commit intoQuantumNous:mainfrom
yyhhyyyyyy:feat/deepchat-deeplink
Open

feat: add DeepChat deeplink support#4668
yyhhyyyyyy wants to merge 1 commit intoQuantumNous:mainfrom
yyhhyyyyyy:feat/deepchat-deeplink

Conversation

@yyhhyyyyyy
Copy link
Copy Markdown
Contributor

@yyhhyyyyyy yyhhyyyyyy commented May 7, 2026

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

  • 添加 DeepChat deeplink 支持
  • 修复 default UI 聊天入口生成 deeplink 时误使用脱敏 API Key 的问题:现在会先定位启用中的 token,再通过真实 key 接口获取完整 sk-...,确保 Cherry Studio、AionUI、DeepChat 等客户端导入时拿到可用密钥。
  • 收敛 default UI 侧边栏的真实 key 获取逻辑,改为点击外部客户端入口时按需获取,并按当前用户隔离缓存,避免跨会话复用旧用户的真实 key。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)
image

Summary by CodeRabbit

  • New Features

    • Added DeepChat as a new supported chat provider for enhanced integration options.
  • Improvements

    • Enhanced loading state tracking when opening external chat presets for a smoother user experience.
    • Refactored API key handling for more reliable chat provider integration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Walkthrough

This PR integrates DeepChat support across backend and frontend systems. It adds DeepChat as a chat provider in the configuration, introduces a reusable API key fetching hook, extends URL resolution logic to handle DeepChat configuration placeholders, updates UI components to use per-item loading states, and wires the new hook into existing chat routing flows.

Changes

DeepChat Provider Integration

Layer / File(s) Summary
Backend Configuration
setting/chat.go
DeepChat provider entry added to Chats slice with URL pattern deepchat://provider/install?v=1&data={deepchatConfig}.
Chat Link Resolution Library
web/default/src/features/chat/lib/chat-links.ts
Added chatLinkRequiresApiKey() to detect API-key-dependent templates. Extended resolveChatUrl() to replace {deepchatConfig} placeholder with base64-encoded JSON payload (baseUrl + apiKey).
API Key Fetching Hook
web/default/src/features/chat/hooks/use-active-chat-key.ts
Introduced fetchActiveChatKey() async helper that fetches enabled API keys, loads token key, and returns sk-${key} string. Refactored useActiveChatKey to use the new helper and include userId in query key.
Route Wiring
web/default/src/routes/_authenticated/chat/$chatId.tsx, web/default/src/routes/_authenticated/chat2link.tsx
Routes now compute requiresActiveKey via chatLinkRequiresApiKey() and use useActiveChatKey() hook instead of inline useQuery, removing direct API key fetching logic.
Preset Item UI
web/default/src/components/layout/components/chat-presets-item.tsx
Replaced global loading state with per-preset loadingPresetId. ChatMenuItem and DropdownPresetItem now accept loading flag to disable actions and show spinner. handleOpenExternal calls fetchActiveChatKey() on demand.
Sidebar & Templates
web/classic/src/components/layout/SiderBar.jsx, web/classic/src/hooks/tokens/useTokensData.jsx, web/classic/src/pages/Setting/Chat/SettingsChats.jsx
SiderBar filters out deepchat:// links from localStorage. useTokensData recognizes {deepchatConfig} placeholder and encodes config. SettingsChats adds DeepChat to BUILTIN_TEMPLATES dropdown.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as Chat UI<br/>(Preset Item)
    participant Hook as useActiveChatKey<br/>Hook
    participant API as Backend<br/>API Keys Service
    participant Token as Token Service
    participant Chat as DeepChat<br/>Provider

    User->>UI: Click "Open DeepChat"
    activate UI
    UI->>UI: Detect preset requires API key<br/>(via chatLinkRequiresApiKey)
    UI->>Hook: useActiveChatKey(true)
    activate Hook
    Hook->>API: getApiKeys() for enabled keys
    activate API
    API-->>Hook: [enabled key, ...]
    deactivate API
    Hook->>Token: fetchTokenKey(keyId)
    activate Token
    Token-->>Hook: {key: "abc123"}
    deactivate Token
    Hook->>Hook: Return "sk-abc123"
    deactivate Hook
    UI->>UI: Resolve chat URL with config<br/>(resolveChatUrl)
    UI->>UI: Encode {deepchatConfig}<br/>to base64 JSON payload
    UI->>Chat: window.open(resolved_url)
    activate Chat
    Chat-->>User: DeepChat interface loads
    deactivate Chat
    deactivate UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • QuantumNous/new-api#1541: Adds DeepChat provider entry to backend configuration and updates chat link filtering in the sidebar component, directly overlapping with this PR's provider setup and localStorage chat handling.

Poem

🐰 A chatty new friend named DeepChat arrives,
With tokens encoded to help features thrive,
Hooks now fetch keys with grace and with care,
Per-item spinners spin through the air! ✨
Our burrow's expanded, the paths more complete,
Each preset now loading with rhythm and beat! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add DeepChat deeplink support' directly and clearly summarizes the primary change—adding DeepChat deeplink support—which is the main objective of the PR across multiple modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/default/src/features/chat/hooks/use-active-chat-key.ts (1)

6-39: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explicit return types on exported functions.

fetchActiveChatKey (line 6) and useActiveChatKey (line 29) lack explicit return type annotations and should be added for clarity and consistency with TypeScript best practices.

Suggested type annotations
-import { useQuery } from '@tanstack/react-query'
+import { useQuery, type UseQueryResult } from '@tanstack/react-query'
@@
-export async function fetchActiveChatKey() {
+export async function fetchActiveChatKey(): Promise<string> {
@@
-export function useActiveChatKey(enabled: boolean) {
+export function useActiveChatKey(enabled: boolean): UseQueryResult<string, Error> {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/chat/hooks/use-active-chat-key.ts` around lines 6 -
39, Both exported functions lack explicit return types; add a Promise<string>
return annotation to fetchActiveChatKey and annotate useActiveChatKey to return
the proper query result type (e.g. UseQueryResult<string, Error> or the
project's equivalent) so callers get correct typing. Update the function
signatures (fetchActiveChatKey and useActiveChatKey) to include these return
types and import the appropriate type (e.g. UseQueryResult) from your query
library, ensuring the existing enabled parameter and useQuery call remain
unchanged.
🧹 Nitpick comments (2)
web/classic/src/hooks/tokens/useTokensData.jsx (1)

234-268: ⚡ Quick win

Consider extracting the {xxxConfig} placeholder builders into a single helper.

The DeepChat branch repeats the same encode-base64-then-URI pattern already used for {cherryConfig} and {aionuiConfig}, with only the payload shape differing. As more providers are added, divergence between branches (typos in baseUrl, missing id/platform, etc.) becomes more likely. A small lookup/iteration would keep the providers consistent and shrink the function.

♻️ Sketch of the refactor
const CONFIG_PLACEHOLDERS = [
  {
    token: '{cherryConfig}',
    build: (addr, key) => ({ id: 'new-api', baseUrl: addr, apiKey: key }),
  },
  {
    token: '{aionuiConfig}',
    build: (addr, key) => ({ platform: 'new-api', baseUrl: addr, apiKey: key }),
  },
  {
    token: '{deepchatConfig}',
    build: (addr, key) => ({ id: 'new-api', baseUrl: addr, apiKey: key }),
  },
];

const placeholder = CONFIG_PLACEHOLDERS.find((p) => url.includes(p.token));
if (placeholder) {
  const encoded = encodeURIComponent(
    encodeToBase64(JSON.stringify(placeholder.build(serverAddress, `sk-${fullKey}`))),
  );
  url = url.replaceAll(placeholder.token, encoded);
} else {
  url = url
    .replaceAll('{address}', encodeURIComponent(serverAddress))
    .replaceAll('{key}', `sk-${fullKey}`);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/classic/src/hooks/tokens/useTokensData.jsx` around lines 234 - 268, The
repeated placeholder handling in useTokensData.jsx should be replaced with a
single helper: create a CONFIG_PLACEHOLDERS array (or map) that lists each token
string (e.g., '{cherryConfig}', '{aionuiConfig}', '{deepchatConfig}') and a
build function returning the correct payload shape (use serverAddress and
`sk-${fullKey}`), then in the token-replacement logic find the matching
placeholder, call its build function, JSON.stringify -> encodeToBase64 ->
encodeURIComponent, and replaceAll the token with the encoded value; fall back
to the existing '{address}'/'{key}' branch when no placeholder is found. Ensure
you reuse encodeToBase64, reference serverAddress and fullKey, and remove the
duplicated branches.
web/default/src/features/chat/lib/chat-links.ts (1)

138-166: ⚡ Quick win

Consolidate the {xxxConfig} placeholder branches into a config-driven loop.

{cherryConfig}, {aionuiConfig}, and the new {deepchatConfig} all share the identical encodeURIComponent(toBase64(JSON.stringify(payload))) pipeline and only differ in the payload shape. Centralizing them keeps the file a single source of truth and prevents the per-provider branches from drifting (e.g. one branch forgetting to URI-encode, or using a different key set than the corresponding useTokensData.jsx builder).

♻️ Suggested refactor
type ConfigPlaceholder = {
  token: string
  build: (serverAddress: string, apiKey: string) => Record<string, string>
}

const CONFIG_PLACEHOLDERS: ConfigPlaceholder[] = [
  {
    token: '{cherryConfig}',
    build: (baseUrl, apiKey) => ({ id: 'new-api', baseUrl, apiKey }),
  },
  {
    token: '{aionuiConfig}',
    build: (baseUrl, apiKey) => ({ platform: 'new-api', baseUrl, apiKey }),
  },
  {
    token: '{deepchatConfig}',
    build: (baseUrl, apiKey) => ({ id: 'new-api', baseUrl, apiKey }),
  },
]

// inside resolveChatUrl, before the {address}/{key} fallbacks:
const placeholder = CONFIG_PLACEHOLDERS.find((p) => url.includes(p.token))
if (placeholder) {
  const encoded = encodeURIComponent(
    toBase64(JSON.stringify(placeholder.build(safeServerAddress, safeApiKey))),
  )
  return replaceToken(url, placeholder.token, encoded)
}

chatLinkRequiresApiKey could also derive its placeholder list from the same array to keep both helpers in sync.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/chat/lib/chat-links.ts` around lines 138 - 166, The
three separate branches handling '{cherryConfig}', '{aionuiConfig}', and
'{deepchatConfig}' should be consolidated into a config-driven loop to avoid
duplicated encodeURIComponent(toBase64(JSON.stringify(...))) logic; add a
CONFIG_PLACEHOLDERS array of {token, build(serverAddress, apiKey)} entries and
in resolveChatUrl find the matching placeholder, call
placeholder.build(safeServerAddress, safeApiKey), base64+URI-encode it via
toBase64 and encodeURIComponent, then return replaceToken(url,
placeholder.token, encoded); also update chatLinkRequiresApiKey to derive its
checks from the same CONFIG_PLACEHOLDERS to keep helpers in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/default/src/features/chat/hooks/use-active-chat-key.ts`:
- Around line 7-15: The current code calls getApiKeys({ p: 1, size: 50 }) and
only searches that first page for an API_KEY_STATUS.ENABLED key, which can
falsely throw if an enabled key exists on a later page; change the logic in
useActiveChatKey to page-scan: call getApiKeys in a loop (increment p) until you
find an item with status === API_KEY_STATUS.ENABLED or until you've exhausted
pages (use result.data.total/size or stop when returned items length is 0),
return the first enabled key when found, and only throw the "No enabled API keys
found" error after all pages have been checked; keep references to getApiKeys,
API_KEY_STATUS.ENABLED, and the variables result/items/active when updating the
implementation.
- Around line 9-20: Replace the three user-facing hardcoded error strings in the
use-active-chat-key flow with i18n calls: use t() from i18next for the 'Failed
to load API keys', 'No enabled API keys found. Create or enable one first.' and
'Failed to load API key' messages; update the code around the items/result
checks and the fetchTokenKey handling (references: result, items, active,
API_KEY_STATUS, fetchTokenKey) to throw new Error(t('...')) with appropriate
translation keys, and add an import for t from 'i18next' at the top if it's not
already imported.

---

Outside diff comments:
In `@web/default/src/features/chat/hooks/use-active-chat-key.ts`:
- Around line 6-39: Both exported functions lack explicit return types; add a
Promise<string> return annotation to fetchActiveChatKey and annotate
useActiveChatKey to return the proper query result type (e.g.
UseQueryResult<string, Error> or the project's equivalent) so callers get
correct typing. Update the function signatures (fetchActiveChatKey and
useActiveChatKey) to include these return types and import the appropriate type
(e.g. UseQueryResult) from your query library, ensuring the existing enabled
parameter and useQuery call remain unchanged.

---

Nitpick comments:
In `@web/classic/src/hooks/tokens/useTokensData.jsx`:
- Around line 234-268: The repeated placeholder handling in useTokensData.jsx
should be replaced with a single helper: create a CONFIG_PLACEHOLDERS array (or
map) that lists each token string (e.g., '{cherryConfig}', '{aionuiConfig}',
'{deepchatConfig}') and a build function returning the correct payload shape
(use serverAddress and `sk-${fullKey}`), then in the token-replacement logic
find the matching placeholder, call its build function, JSON.stringify ->
encodeToBase64 -> encodeURIComponent, and replaceAll the token with the encoded
value; fall back to the existing '{address}'/'{key}' branch when no placeholder
is found. Ensure you reuse encodeToBase64, reference serverAddress and fullKey,
and remove the duplicated branches.

In `@web/default/src/features/chat/lib/chat-links.ts`:
- Around line 138-166: The three separate branches handling '{cherryConfig}',
'{aionuiConfig}', and '{deepchatConfig}' should be consolidated into a
config-driven loop to avoid duplicated
encodeURIComponent(toBase64(JSON.stringify(...))) logic; add a
CONFIG_PLACEHOLDERS array of {token, build(serverAddress, apiKey)} entries and
in resolveChatUrl find the matching placeholder, call
placeholder.build(safeServerAddress, safeApiKey), base64+URI-encode it via
toBase64 and encodeURIComponent, then return replaceToken(url,
placeholder.token, encoded); also update chatLinkRequiresApiKey to derive its
checks from the same CONFIG_PLACEHOLDERS to keep helpers in sync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c4cd7864-2f98-48ad-937c-bdbbe4a59764

📥 Commits

Reviewing files that changed from the base of the PR and between 415d21d and 6364d4b.

📒 Files selected for processing (9)
  • setting/chat.go
  • web/classic/src/components/layout/SiderBar.jsx
  • web/classic/src/hooks/tokens/useTokensData.jsx
  • web/classic/src/pages/Setting/Chat/SettingsChats.jsx
  • web/default/src/components/layout/components/chat-presets-item.tsx
  • web/default/src/features/chat/hooks/use-active-chat-key.ts
  • web/default/src/features/chat/lib/chat-links.ts
  • web/default/src/routes/_authenticated/chat/$chatId.tsx
  • web/default/src/routes/_authenticated/chat2link.tsx

Comment on lines +7 to +15
const result = await getApiKeys({ p: 1, size: 50 })
if (!result.success) {
throw new Error(result.message || 'Failed to load API keys')
}

const items = result.data?.items ?? []
const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (!active) {
throw new Error('No enabled API keys found. Create or enable one first.')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enabled-key detection is limited to page 1.

Line 7 fetches only the first 50 keys, and Line 13 only searches that slice. If the first enabled key is on a later page, Line 15 throws a false “No enabled API keys found” error.

💡 Suggested fix (scan pages until an enabled key is found)
 export async function fetchActiveChatKey() {
-  const result = await getApiKeys({ p: 1, size: 50 })
-  if (!result.success) {
-    throw new Error(result.message || 'Failed to load API keys')
-  }
-
-  const items = result.data?.items ?? []
-  const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
+  const pageSize = 50
+  let page = 1
+  let active: { id: string | number } | undefined
+
+  while (!active) {
+    const result = await getApiKeys({ p: page, size: pageSize })
+    if (!result.success) {
+      throw new Error(result.message || 'Failed to load API keys')
+    }
+
+    const items = result.data?.items ?? []
+    active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
+    if (active || items.length < pageSize) break
+    page += 1
+  }
+
   if (!active) {
     throw new Error('No enabled API keys found. Create or enable one first.')
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = await getApiKeys({ p: 1, size: 50 })
if (!result.success) {
throw new Error(result.message || 'Failed to load API keys')
}
const items = result.data?.items ?? []
const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (!active) {
throw new Error('No enabled API keys found. Create or enable one first.')
const pageSize = 50
let page = 1
let active: { id: string | number } | undefined
while (!active) {
const result = await getApiKeys({ p: page, size: pageSize })
if (!result.success) {
throw new Error(result.message || 'Failed to load API keys')
}
const items = result.data?.items ?? []
active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (active || items.length < pageSize) break
page += 1
}
if (!active) {
throw new Error('No enabled API keys found. Create or enable one first.')
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/chat/hooks/use-active-chat-key.ts` around lines 7 -
15, The current code calls getApiKeys({ p: 1, size: 50 }) and only searches that
first page for an API_KEY_STATUS.ENABLED key, which can falsely throw if an
enabled key exists on a later page; change the logic in useActiveChatKey to
page-scan: call getApiKeys in a loop (increment p) until you find an item with
status === API_KEY_STATUS.ENABLED or until you've exhausted pages (use
result.data.total/size or stop when returned items length is 0), return the
first enabled key when found, and only throw the "No enabled API keys found"
error after all pages have been checked; keep references to getApiKeys,
API_KEY_STATUS.ENABLED, and the variables result/items/active when updating the
implementation.

Comment on lines +9 to +20
throw new Error(result.message || 'Failed to load API keys')
}

const items = result.data?.items ?? []
const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (!active) {
throw new Error('No enabled API keys found. Create or enable one first.')
}

const keyResult = await fetchTokenKey(active.id)
if (!keyResult.success || !keyResult.data?.key) {
throw new Error(keyResult.message || 'Failed to load API key')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there are no remaining hardcoded string literals in throw-new-Error calls in this hook.
rg -n "throw new Error\\(['\"][^'\"]+['\"]\\)" web/default/src/features/chat/hooks/use-active-chat-key.ts

Repository: QuantumNous/new-api

Length of output: 144


🏁 Script executed:

cat -n web/default/src/features/chat/hooks/use-active-chat-key.ts

Repository: QuantumNous/new-api

Length of output: 1564


🏁 Script executed:

# Verify the file follows the expected pattern for non-React utility functions
head -5 web/default/src/features/chat/hooks/use-active-chat-key.ts | grep -E "(React|useTranslation|i18next)"

Repository: QuantumNous/new-api

Length of output: 45


Use t() from i18next for user-visible error messages in this utility function.

Lines 9, 15, and 20 contain hardcoded error strings that violate the i18n requirement for .ts files. Replace with t() calls:

Suggested refactor
+import { t } from 'i18next'
 import { useQuery } from '@tanstack/react-query'
 import { fetchTokenKey, getApiKeys } from '@/features/keys/api'
 import { API_KEY_STATUS } from '@/features/keys/constants'
 import { useAuthStore } from '@/stores/auth-store'

 export async function fetchActiveChatKey() {
   const result = await getApiKeys({ p: 1, size: 50 })
   if (!result.success) {
-    throw new Error(result.message || 'Failed to load API keys')
+    throw new Error(result.message || t('chat.errors.failedToLoadApiKeys'))
   }

   const items = result.data?.items ?? []
   const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
   if (!active) {
-    throw new Error('No enabled API keys found. Create or enable one first.')
+    throw new Error(t('chat.errors.noEnabledApiKeys'))
   }

   const keyResult = await fetchTokenKey(active.id)
   if (!keyResult.success || !keyResult.data?.key) {
-    throw new Error(keyResult.message || 'Failed to load API key')
+    throw new Error(keyResult.message || t('chat.errors.failedToLoadApiKey'))
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
throw new Error(result.message || 'Failed to load API keys')
}
const items = result.data?.items ?? []
const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (!active) {
throw new Error('No enabled API keys found. Create or enable one first.')
}
const keyResult = await fetchTokenKey(active.id)
if (!keyResult.success || !keyResult.data?.key) {
throw new Error(keyResult.message || 'Failed to load API key')
import { t } from 'i18next'
import { useQuery } from '@tanstack/react-query'
import { fetchTokenKey, getApiKeys } from '@/features/keys/api'
import { API_KEY_STATUS } from '@/features/keys/constants'
import { useAuthStore } from '@/stores/auth-store'
export async function fetchActiveChatKey() {
const result = await getApiKeys({ p: 1, size: 50 })
if (!result.success) {
throw new Error(result.message || t('chat.errors.failedToLoadApiKeys'))
}
const items = result.data?.items ?? []
const active = items.find((item) => item.status === API_KEY_STATUS.ENABLED)
if (!active) {
throw new Error(t('chat.errors.noEnabledApiKeys'))
}
const keyResult = await fetchTokenKey(active.id)
if (!keyResult.success || !keyResult.data?.key) {
throw new Error(keyResult.message || t('chat.errors.failedToLoadApiKey'))
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/default/src/features/chat/hooks/use-active-chat-key.ts` around lines 9 -
20, Replace the three user-facing hardcoded error strings in the
use-active-chat-key flow with i18n calls: use t() from i18next for the 'Failed
to load API keys', 'No enabled API keys found. Create or enable one first.' and
'Failed to load API key' messages; update the code around the items/result
checks and the fetchTokenKey handling (references: result, items, active,
API_KEY_STATUS, fetchTokenKey) to throw new Error(t('...')) with appropriate
translation keys, and add an import for t from 'i18next' at the top if it's not
already imported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant