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:用户找不到关闭模态框的显式入口 */} +