From 0835912cd8bf3291df8a52ac3cc3accd9a4ca1ea Mon Sep 17 00:00:00 2001 From: longsizhuo Date: Thu, 16 Apr 2026 19:30:36 +0000 Subject: [PATCH] =?UTF-8?q?fix(assistant):=20=E5=88=87=E6=8D=A2=E5=85=8D?= =?UTF-8?q?=E8=B4=B9=E6=A8=A1=E5=9E=8B=20Intern-S1=20=E2=86=92=20GLM-4.6V-?= =?UTF-8?q?Flash=20+=20=E5=8A=A0=E5=85=B3=E9=97=AD=E6=8C=89=E9=92=AE=20(#2?= =?UTF-8?q?85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 免费模型 Intern-S1 key 过期导致匿名用户发消息报 unauthorized。 改接智谱 GLM-4.6V-Flash(128K 上下文、多模态、免费),用 ZHIPU_API_KEY 走 OpenAI-compatible 接口。保留 provider 名 `intern` 避免 localStorage 迁移。 - 匿名请求跳过 Java 后端代理:/openai/responses/stream 有 @SaCheckLogin, 匿名必 401,短路省 5s 超时、避免错误文案透传。 - 模态框右上角加 X 关闭按钮(改用受控 open state),解决 "边框悬浮但找不到关闭入口" 的 UX 问题。 - SettingsDialog 文案更新:标注 GLM-4.6V-Flash,保留对书生 Intern-S1 首发算力赞助的致谢。 - .env.sample 新增 ZHIPU_API_KEY 占位。 Closes #285 --- .env.sample | 5 ++- app/api/chat/route.ts | 7 ++++ .../assistant-ui/SettingsDialog.tsx | 16 +++++---- .../assistant-ui/assistant-modal.tsx | 25 ++++++++++--- lib/ai/providers/intern.ts | 35 ++++++++++++------- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/.env.sample b/.env.sample index f63cdb0d..b300c42d 100644 --- a/.env.sample +++ b/.env.sample @@ -24,8 +24,11 @@ INDEXNOW_API_TOKEN= #Open的Key INDEXNOW_KEY=5b6ef14a7406496b8a2ce8ab17820b34 NEXT_PUBLIC_SITE_URL=https://involutionhell.com -# 内部识别/认证 Key +# 书生 Intern-S1 Key(已弃用:默认免费模型已切换至 GLM-4.6V-Flash) INTERN_KEY= +# 智谱 AI 开放平台 API Key,聊天与建议接口的默认免费模型 GLM-4.6V-Flash +# 在 https://open.bigmodel.cn/ 注册后获取 +ZHIPU_API_KEY= # Neon 项目 ID NEON_PROJECT_ID= # Neon 提供的 Postgres 连接。 diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 0864dbe1..fb144d07 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -33,9 +33,16 @@ export async function POST(req: Request) { const proxyReq = req.clone(); // ====== 尝试优雅降级代理到 Java 后端 ====== + // Java 后端 /openai/responses/stream 带 @SaCheckLogin,匿名请求必 401; + // 直接跳过代理省掉 5s 超时,也避免 401 文案被上游误显示为"unauthorized"。 + const hasAuthToken = Boolean(req.headers.get("x-satoken")); try { + if (!hasAuthToken) { + throw new Error("Anonymous request, skip backend proxy."); + } const backendUrl = process.env.BACKEND_URL; if (!backendUrl) throw new Error("BACKEND_URL is not configured."); + const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时 diff --git a/app/components/assistant-ui/SettingsDialog.tsx b/app/components/assistant-ui/SettingsDialog.tsx index e6f75861..ba9ad168 100644 --- a/app/components/assistant-ui/SettingsDialog.tsx +++ b/app/components/assistant-ui/SettingsDialog.tsx @@ -58,7 +58,7 @@ export const SettingsDialog = ({ >
- +
@@ -176,11 +176,15 @@ export const SettingsDialog = ({ )} {provider === "intern" && ( -
-
- 感谢上海AILab的书生大模型对本项目的算力支持,Intern-AI - 模型已预配置,无需提供 API Key。 -
+
+

+ 当前免费模型为智谱 GLM-4.6V-Flash(128K + 上下文,支持多模态),由站点统一承担费用,无需提供 API Key。 +

+

+ 🙏 特别鸣谢上海 AI Lab 书生 Intern-S1 + 为本项目提供首发算力支持——第一个金主,永远铭记。 +

)}
diff --git a/app/components/assistant-ui/assistant-modal.tsx b/app/components/assistant-ui/assistant-modal.tsx index 68d96e0e..6f37aa72 100644 --- a/app/components/assistant-ui/assistant-modal.tsx +++ b/app/components/assistant-ui/assistant-modal.tsx @@ -1,8 +1,8 @@ "use client"; -import { BotIcon, ChevronDownIcon } from "lucide-react"; +import { BotIcon, ChevronDownIcon, XIcon } from "lucide-react"; -import { type FC, forwardRef, useState, useEffect } from "react"; +import { type FC, forwardRef, useState, useEffect, useCallback } from "react"; import { AssistantModalPrimitive } from "@assistant-ui/react"; import { Thread } from "@/app/components/assistant-ui/thread"; @@ -30,6 +30,13 @@ export const AssistantModal: FC = ({ isLoadingWelcome, }) => { const [showBubble, setShowBubble] = useState(false); + // 受控状态:允许模态框内部的 X 按钮主动关闭窗口 + // issue #285: 原先只能靠 Trigger/点击外部/Esc 关闭,用户反馈不知道怎么关窗 + const [open, setOpen] = useState(false); + + const handleCloseModal = useCallback(() => { + setOpen(false); + }, []); useEffect(() => { // 检查本次访问是否已关闭过气泡 @@ -61,7 +68,7 @@ export const AssistantModal: FC = ({ }; return ( - + {/* 自定义气泡组件 */} {showBubble && ( @@ -88,8 +95,18 @@ export const AssistantModal: FC = ({ + {/* 右上角关闭按钮,issue #285:用户找不到关闭模态框的显式入口 */} +