@tablestore/tablestore-agent-cli 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard-runtime/dashboard/.next/BUILD_ID +1 -1
- package/dist/dashboard-runtime/dashboard/.next/build-manifest.json +3 -3
- package/dist/dashboard-runtime/dashboard/.next/prerender-manifest.json +3 -3
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/documents/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/documents/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/qa/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/qa/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/retrieval/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/retrieval/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/settings/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/settings/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/create/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/[id]/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/new/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/messages/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/messages/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/requests/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/requests/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/search/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/search/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/settings/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/settings/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/units/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/units/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/create/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/api/v1/knowledge-bases/[name]/documents/upload/route.js.nft.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.rsc +3 -3
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_full.segment.rsc +3 -3
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_index.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_tree.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/0b1r_app_(dashboard)_knowledge-base_[name]_documents_documents-client_tsx_0g2uxmt._.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09_30hi._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0kaiok7._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0l937k4._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0-dlo4s._.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_01pp~xx._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0476v7r._.js → _08j6p-z._.js} +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0ct0n55._.js → _09eom0_._.js} +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0mzxmfh._.js → _0f-may2._.js} +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0fp_nnb._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0l6jz-5._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0fg6iap._.js → _0ntv66s._.js} +2 -2
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0sc0tpz._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0tyxwr3._.js +3 -0
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0u9md36._.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/dashboard_src_065m1.j._.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/dashboard_src_app_(dashboard)_knowledge-base_[name]_layout-client_tsx_05momc5._.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/middleware-build-manifest.js +3 -3
- package/dist/dashboard-runtime/dashboard/.next/server/pages/404.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/pages/500.html +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0-xqk6wfme5fu.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0ltmkqogn8g3t.js → 00.fyg_t3xjc~.js} +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/01k-.wkndubwy.js +138 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/07r22x5uhjxjb.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0cbu3udngtx-v.js +4 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0h7d69g2fdgs6.js +138 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0iv0g360z0ja5.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0jf4ytf.izmzh.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/{17nx_vdk_qemm.js → 0m42mmyxmgn-i.js} +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0odz1whf-ozqn.css +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0ouxv_2qvf6.9.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0rbkgj._oqsb3.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0u6u.649ou67b.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0vf7~eysvh9bq.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/{09qsmnfvk8dm3.js → 0wmaq.ay~r2sn.js} +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0i5aqiffpm9jr.js → 0xb0_9t-vmo6e.js} +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0yp_2ea75d19v.js +1 -0
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0s3mvx9_dr13c.js → 11cizim1aug~b.js} +1 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/13-2ei295hl0-.js +1 -0
- package/dist/dashboard-runtime/dashboard/src/app/(dashboard)/knowledge-base/[name]/qa/page.tsx +23 -1
- package/dist/dashboard-runtime/dashboard/src/components/chat/chat-mount-config.tsx +29 -8
- package/dist/dashboard-runtime/dashboard/src/components/documents/doc-upload-dialog.tsx +370 -91
- package/dist/dashboard-runtime/dashboard/src/components/knowledge-base/kb-card.tsx +8 -5
- package/dist/dashboard-runtime/dashboard/src/components/knowledge-base/kb-header.tsx +23 -13
- package/dist/dashboard-runtime/dashboard/src/components/memory/memory-header.tsx +8 -12
- package/dist/dashboard-runtime/dashboard/src/components/qa/qa-chat-panel.tsx +45 -4
- package/dist/dashboard-runtime/dashboard/src/components/qa/qa-message.tsx +636 -36
- package/dist/dashboard-runtime/dashboard/src/components/shared/confirm-dialog.tsx +8 -1
- package/dist/dashboard-runtime/dashboard/src/components/shared/refresh-button.tsx +102 -86
- package/dist/dashboard-runtime/dashboard/src/hooks/use-qa-chat.ts +261 -58
- package/dist/dashboard-runtime/dashboard/src/lib/chat-message-ops.ts +76 -0
- package/dist/dashboard-runtime/dashboard/src/lib/dev-flags.ts +24 -0
- package/dist/dashboard-runtime/dashboard/src/types/llm-chat.ts +19 -0
- package/package.json +1 -1
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0i0y9.r._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0r_6wpx._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0y8rrcu._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_02e0c00._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0doczxg._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0e9y.xc._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0ti~om_._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0~s~e-0._.js +0 -3
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/055_bo6_3nt-s.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/07l4dodn5t6l4.js +0 -4
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0a5ass8u78k90.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0j~63ld9lbb25.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0l6znnjqw.4yw.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0o-c2g8y5pw-c.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0o0i2ke2jbdvq.js +0 -138
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0prl6hk4v0k3i.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0u2lo2lzizxy_.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/0v.hno.6q74nn.css +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/14ti2gx~1fiub.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/14vqmdm7sosj2.js +0 -1
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/17h~onnkksf44.js +0 -138
- package/dist/dashboard-runtime/dashboard/.next/static/chunks/186jubvt5xyuj.js +0 -1
- /package/dist/dashboard-runtime/dashboard/.next/static/{MjeKF5uLzEvAqWkR9O6Ts → BGnMIk4OPjFx_qvLFMTBc}/_buildManifest.js +0 -0
- /package/dist/dashboard-runtime/dashboard/.next/static/{MjeKF5uLzEvAqWkR9O6Ts → BGnMIk4OPjFx_qvLFMTBc}/_clientMiddlewareManifest.js +0 -0
- /package/dist/dashboard-runtime/dashboard/.next/static/{MjeKF5uLzEvAqWkR9O6Ts → BGnMIk4OPjFx_qvLFMTBc}/_ssgManifest.js +0 -0
|
@@ -4,7 +4,13 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
|
|
4
4
|
|
|
5
5
|
import { streamChat } from "@/services/llm-chat";
|
|
6
6
|
import { newId } from "@/lib/random-id";
|
|
7
|
-
import
|
|
7
|
+
import { devFlag } from "@/lib/dev-flags";
|
|
8
|
+
import {
|
|
9
|
+
removeAt,
|
|
10
|
+
removePair,
|
|
11
|
+
truncateUpToAndIncluding,
|
|
12
|
+
} from "@/lib/chat-message-ops";
|
|
13
|
+
import type { ChatMessage, ChatRequestBody, ChatRole } from "@/types/llm-chat";
|
|
8
14
|
|
|
9
15
|
/**
|
|
10
16
|
* Token deltas can arrive faster than React can profitably re-render
|
|
@@ -35,6 +41,17 @@ export interface UseQaChatResult {
|
|
|
35
41
|
isStreaming: boolean;
|
|
36
42
|
error: string | null;
|
|
37
43
|
send(userInput: string): Promise<void>;
|
|
44
|
+
/** Truncate to and including the given user message, then re-run the
|
|
45
|
+
* assistant pipeline. Powers resend / regenerate / edit-and-resend. */
|
|
46
|
+
reissueTurn(anchorUserId: string): Promise<void>;
|
|
47
|
+
/** Remove a message by id. When the target is a user message and
|
|
48
|
+
* `withNextAssistant` is true, the immediately-following assistant
|
|
49
|
+
* message (if any) is removed too. Persists immediately. */
|
|
50
|
+
deleteMessage(id: string, opts?: { withNextAssistant?: boolean }): void;
|
|
51
|
+
/** Rewrite the content of a user message in place. Returns the message
|
|
52
|
+
* id on success so the caller can chain `reissueTurn(id)` for the
|
|
53
|
+
* edit-and-resend flow, or null if the id wasn't a user message. */
|
|
54
|
+
editUserMessage(id: string, nextContent: string): string | null;
|
|
38
55
|
stop(): void;
|
|
39
56
|
clear(): void;
|
|
40
57
|
/** Replace the entire message list, e.g. when switching sessions. */
|
|
@@ -133,57 +150,51 @@ export function useQaChat(options: UseQaChatOptions): UseQaChatResult {
|
|
|
133
150
|
|
|
134
151
|
const clear = useCallback(() => {
|
|
135
152
|
abortRef.current?.abort();
|
|
153
|
+
// Sync the ref before triggering the async setMessages so a `send` that
|
|
154
|
+
// happens to land in the same JS task — between this call and React's
|
|
155
|
+
// next commit — sees an empty history instead of the previous session's
|
|
156
|
+
// messages. The render-body assignment below catches the steady state;
|
|
157
|
+
// this assignment closes the in-flight window.
|
|
158
|
+
messagesRef.current = [];
|
|
136
159
|
setMessages([]);
|
|
137
160
|
setError(null);
|
|
138
161
|
}, []);
|
|
139
162
|
|
|
140
163
|
const replaceMessages = useCallback((next: ChatMessage[]) => {
|
|
141
164
|
abortRef.current?.abort();
|
|
165
|
+
// Same race-window guard as in `clear` — see the comment there.
|
|
166
|
+
messagesRef.current = next;
|
|
142
167
|
setMessages(next);
|
|
143
168
|
setError(null);
|
|
144
169
|
}, []);
|
|
145
170
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Internal: run one assistant turn against an already-prepared message
|
|
173
|
+
* list. Shared between `send` (which prepends a fresh user+assistant
|
|
174
|
+
* placeholder) and `reissueTurn` (which truncates and re-anchors on an
|
|
175
|
+
* existing user message).
|
|
176
|
+
*
|
|
177
|
+
* Pre-conditions:
|
|
178
|
+
* - `assistantId` matches a message in the current list (the placeholder)
|
|
179
|
+
* - `historyToSend` is the exact wire payload, already trimmed
|
|
180
|
+
* - the caller has already set isStreaming = true and abortRef
|
|
181
|
+
*/
|
|
182
|
+
const _runAssistantTurn = useCallback(
|
|
183
|
+
async (
|
|
184
|
+
assistantId: string,
|
|
185
|
+
historyToSend: Array<{ role: ChatRole; content: string }>,
|
|
186
|
+
) => {
|
|
150
187
|
const opts = optionsRef.current;
|
|
151
|
-
if (!opts.providerId || !opts.model) {
|
|
152
|
-
setError("请先选择模型与 Provider");
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
setError(null);
|
|
157
|
-
const userMsg: ChatMessage = {
|
|
158
|
-
id: newId(),
|
|
159
|
-
role: "user",
|
|
160
|
-
content: trimmed,
|
|
161
|
-
createdAt: Date.now(),
|
|
162
|
-
status: "done",
|
|
163
|
-
};
|
|
164
|
-
const assistantId = newId();
|
|
165
|
-
const assistantMsg: ChatMessage = {
|
|
166
|
-
id: assistantId,
|
|
167
|
-
role: "assistant",
|
|
168
|
-
content: "",
|
|
169
|
-
reasoning: "",
|
|
170
|
-
createdAt: Date.now(),
|
|
171
|
-
status: "streaming",
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// Capture the history to send BEFORE inserting the placeholder so we
|
|
175
|
-
// don't include an empty assistant turn in the request payload.
|
|
176
|
-
const historyToSend = [...messagesRef.current, userMsg].map((m) => ({
|
|
177
|
-
role: m.role,
|
|
178
|
-
content: m.content,
|
|
179
|
-
}));
|
|
180
|
-
|
|
181
|
-
setMessages((prev) => [...prev, userMsg, assistantMsg]);
|
|
182
|
-
setIsStreaming(true);
|
|
183
|
-
|
|
184
188
|
const controller = new AbortController();
|
|
185
189
|
abortRef.current = controller;
|
|
186
190
|
|
|
191
|
+
// Per-turn one-shot latches for the reasoning timing stamps. Refs
|
|
192
|
+
// (not state) because we observe them from inside the streaming loop
|
|
193
|
+
// closure — re-rendering on every flip would defeat the rAF batching
|
|
194
|
+
// that keeps token streaming at 60fps.
|
|
195
|
+
const reasoningStartedRef = { current: false };
|
|
196
|
+
const reasoningCompletedRef = { current: false };
|
|
197
|
+
|
|
187
198
|
const updateAssistant = (patch: Partial<ChatMessage>) => {
|
|
188
199
|
setMessages((prev) =>
|
|
189
200
|
prev.map((m) => (m.id === assistantId ? { ...m, ...patch } : m)),
|
|
@@ -200,6 +211,18 @@ export function useQaChat(options: UseQaChatOptions): UseQaChatResult {
|
|
|
200
211
|
rag: opts.rag,
|
|
201
212
|
};
|
|
202
213
|
|
|
214
|
+
if (devFlag("logChatRequest")) {
|
|
215
|
+
// Diagnostic surface for the cross-session bleed investigation.
|
|
216
|
+
// Off by default; enable via
|
|
217
|
+
// localStorage.setItem("tsagent.dev.logChatRequest","1")
|
|
218
|
+
// in the browser devtools console.
|
|
219
|
+
console.groupCollapsed("[chat] outgoing turn");
|
|
220
|
+
console.log("assistantId", assistantId);
|
|
221
|
+
console.log("messages", historyToSend);
|
|
222
|
+
console.log("rag.knowledgeBases", opts.rag?.knowledgeBases);
|
|
223
|
+
console.groupEnd();
|
|
224
|
+
}
|
|
225
|
+
|
|
203
226
|
for await (const event of streamChat(body, controller.signal)) {
|
|
204
227
|
if (event.type === "query.rewritten") {
|
|
205
228
|
updateAssistant({
|
|
@@ -207,11 +230,14 @@ export function useQaChat(options: UseQaChatOptions): UseQaChatResult {
|
|
|
207
230
|
retrievalQueryRewritten: event.query !== event.original,
|
|
208
231
|
});
|
|
209
232
|
} else if (event.type === "query.fallback") {
|
|
210
|
-
// Rewriter failed;
|
|
211
|
-
//
|
|
233
|
+
// Rewriter failed; record the failure so the UI can surface a
|
|
234
|
+
// non-blocking warning chip while the pipeline continues with
|
|
235
|
+
// the original query.
|
|
212
236
|
updateAssistant({
|
|
213
237
|
retrievalQuery: event.original,
|
|
214
238
|
retrievalQueryRewritten: false,
|
|
239
|
+
queryRewriteFailed: true,
|
|
240
|
+
queryRewriteError: event.reason,
|
|
215
241
|
});
|
|
216
242
|
} else if (event.type === "retrieval.done") {
|
|
217
243
|
updateAssistant({
|
|
@@ -222,52 +248,72 @@ export function useQaChat(options: UseQaChatOptions): UseQaChatResult {
|
|
|
222
248
|
const buf = pendingDeltasRef.current.get(assistantId) ?? {};
|
|
223
249
|
buf.reasoning = (buf.reasoning ?? "") + event.delta;
|
|
224
250
|
pendingDeltasRef.current.set(assistantId, buf);
|
|
251
|
+
if (!reasoningStartedRef.current) {
|
|
252
|
+
reasoningStartedRef.current = true;
|
|
253
|
+
updateAssistant({ reasoningStartedAt: Date.now() });
|
|
254
|
+
}
|
|
225
255
|
scheduleFlush();
|
|
226
256
|
} else if (event.type === "content.delta") {
|
|
227
257
|
const buf = pendingDeltasRef.current.get(assistantId) ?? {};
|
|
228
258
|
buf.content = (buf.content ?? "") + event.delta;
|
|
229
259
|
pendingDeltasRef.current.set(assistantId, buf);
|
|
260
|
+
if (reasoningStartedRef.current && !reasoningCompletedRef.current) {
|
|
261
|
+
reasoningCompletedRef.current = true;
|
|
262
|
+
updateAssistant({ reasoningCompletedAt: Date.now() });
|
|
263
|
+
}
|
|
230
264
|
scheduleFlush();
|
|
231
265
|
} else if (event.type === "error") {
|
|
232
|
-
// Terminal event: drain any buffered deltas synchronously
|
|
233
|
-
// before applying the status patch so the user sees the full
|
|
234
|
-
// partial answer alongside the error badge.
|
|
235
266
|
cancelScheduledFlush();
|
|
236
267
|
flushDeltas();
|
|
237
|
-
|
|
268
|
+
const patch: Partial<ChatMessage> = {
|
|
238
269
|
status: "error",
|
|
239
270
|
errorMessage: `${event.code}: ${event.message}`,
|
|
240
|
-
}
|
|
271
|
+
};
|
|
272
|
+
if (reasoningStartedRef.current && !reasoningCompletedRef.current) {
|
|
273
|
+
patch.reasoningCompletedAt = Date.now();
|
|
274
|
+
}
|
|
275
|
+
updateAssistant(patch);
|
|
241
276
|
setError(event.message);
|
|
242
277
|
break;
|
|
243
278
|
} else if (event.type === "done") {
|
|
244
279
|
cancelScheduledFlush();
|
|
245
280
|
flushDeltas();
|
|
246
|
-
|
|
281
|
+
const patch: Partial<ChatMessage> = { status: "done" };
|
|
282
|
+
if (reasoningStartedRef.current && !reasoningCompletedRef.current) {
|
|
283
|
+
patch.reasoningCompletedAt = Date.now();
|
|
284
|
+
}
|
|
285
|
+
updateAssistant(patch);
|
|
247
286
|
break;
|
|
248
287
|
}
|
|
249
288
|
}
|
|
250
289
|
} catch (err) {
|
|
251
|
-
// AbortError is expected when the user clicks "stop"
|
|
252
|
-
// it as a hard failure. Either way
|
|
253
|
-
//
|
|
290
|
+
// AbortError is expected when the user clicks "stop" or starts a new
|
|
291
|
+
// turn; do not treat it as a hard failure. Either way drain buffered
|
|
292
|
+
// deltas so any partial answer is preserved.
|
|
254
293
|
cancelScheduledFlush();
|
|
255
294
|
flushDeltas();
|
|
256
295
|
const isAbort =
|
|
257
296
|
err instanceof DOMException && err.name === "AbortError";
|
|
297
|
+
const closeReasoning =
|
|
298
|
+
reasoningStartedRef.current && !reasoningCompletedRef.current
|
|
299
|
+
? { reasoningCompletedAt: Date.now() }
|
|
300
|
+
: undefined;
|
|
258
301
|
if (!isAbort) {
|
|
259
302
|
const message = err instanceof Error ? err.message : String(err);
|
|
260
|
-
updateAssistant({
|
|
303
|
+
updateAssistant({
|
|
304
|
+
status: "error",
|
|
305
|
+
errorMessage: message,
|
|
306
|
+
...closeReasoning,
|
|
307
|
+
});
|
|
261
308
|
setError(message);
|
|
262
309
|
} else {
|
|
263
|
-
updateAssistant({ status: "done" });
|
|
310
|
+
updateAssistant({ status: "done", ...closeReasoning });
|
|
264
311
|
}
|
|
265
312
|
} finally {
|
|
266
313
|
setIsStreaming(false);
|
|
267
314
|
abortRef.current = null;
|
|
268
|
-
// Flush the latest snapshot to the persist handler.
|
|
269
|
-
// setter avoids racing with the in-flight closure
|
|
270
|
-
// the reducer has just committed.
|
|
315
|
+
// Flush the latest snapshot to the persist handler. Functional
|
|
316
|
+
// setter avoids racing with the in-flight closure.
|
|
271
317
|
const persist = onPersistRef.current;
|
|
272
318
|
if (persist) {
|
|
273
319
|
setMessages((prev) => {
|
|
@@ -277,18 +323,175 @@ export function useQaChat(options: UseQaChatOptions): UseQaChatResult {
|
|
|
277
323
|
}
|
|
278
324
|
}
|
|
279
325
|
},
|
|
280
|
-
// No `messages`/`options`/`isStreaming` in deps: we read them through
|
|
281
|
-
// refs above so the callback identity stays stable across the entire
|
|
282
|
-
// streaming session, which prevents downstream memos (composer, message
|
|
283
|
-
// list) from invalidating on every token.
|
|
284
326
|
[scheduleFlush, flushDeltas, cancelScheduledFlush],
|
|
285
327
|
);
|
|
286
328
|
|
|
329
|
+
const send = useCallback(
|
|
330
|
+
async (userInput: string) => {
|
|
331
|
+
const trimmed = userInput.trim();
|
|
332
|
+
if (!trimmed || isStreamingRef.current) return;
|
|
333
|
+
const opts = optionsRef.current;
|
|
334
|
+
if (!opts.providerId || !opts.model) {
|
|
335
|
+
setError("请先选择模型与 Provider");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
setError(null);
|
|
340
|
+
const userMsg: ChatMessage = {
|
|
341
|
+
id: newId(),
|
|
342
|
+
role: "user",
|
|
343
|
+
content: trimmed,
|
|
344
|
+
createdAt: Date.now(),
|
|
345
|
+
status: "done",
|
|
346
|
+
};
|
|
347
|
+
const assistantId = newId();
|
|
348
|
+
// Snapshot whether this turn is RAG-enabled. The pill uses this to pick
|
|
349
|
+
// pre-stream labels (intent extraction → retrieval → thinking) instead
|
|
350
|
+
// of a single generic "正在思考" that sits unchanged for several
|
|
351
|
+
// seconds while the server runs the rewriter and KB queries.
|
|
352
|
+
const usingRag = (opts.rag?.knowledgeBases?.length ?? 0) > 0;
|
|
353
|
+
const assistantMsg: ChatMessage = {
|
|
354
|
+
id: assistantId,
|
|
355
|
+
role: "assistant",
|
|
356
|
+
content: "",
|
|
357
|
+
reasoning: "",
|
|
358
|
+
createdAt: Date.now(),
|
|
359
|
+
status: "streaming",
|
|
360
|
+
usingRag,
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
// Capture the history to send BEFORE inserting the placeholder so we
|
|
364
|
+
// don't include an empty assistant turn in the request payload.
|
|
365
|
+
const historyToSend = [...messagesRef.current, userMsg].map((m) => ({
|
|
366
|
+
role: m.role,
|
|
367
|
+
content: m.content,
|
|
368
|
+
}));
|
|
369
|
+
|
|
370
|
+
// Sync the ref alongside setMessages so a follow-up reissueTurn or a
|
|
371
|
+
// racing read sees the new state immediately, not on the next commit.
|
|
372
|
+
const nextMessages = [...messagesRef.current, userMsg, assistantMsg];
|
|
373
|
+
messagesRef.current = nextMessages;
|
|
374
|
+
setMessages(nextMessages);
|
|
375
|
+
setIsStreaming(true);
|
|
376
|
+
|
|
377
|
+
await _runAssistantTurn(assistantId, historyToSend);
|
|
378
|
+
},
|
|
379
|
+
[_runAssistantTurn],
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Truncate to and including `anchorUserId`, then re-run the assistant
|
|
384
|
+
* pipeline against that user message. Powers UI-level「重新发送」、
|
|
385
|
+
*「重新生成」、「编辑后保存」 — the editing path mutates the anchor's
|
|
386
|
+
* content via `editUserMessage` first and then calls this.
|
|
387
|
+
*
|
|
388
|
+
* No-op if streaming is already in flight, the anchor is missing, or
|
|
389
|
+
* the anchor isn't a user message.
|
|
390
|
+
*/
|
|
391
|
+
const reissueTurn = useCallback(
|
|
392
|
+
async (anchorUserId: string) => {
|
|
393
|
+
if (isStreamingRef.current) return;
|
|
394
|
+
const opts = optionsRef.current;
|
|
395
|
+
if (!opts.providerId || !opts.model) {
|
|
396
|
+
setError("请先选择模型与 Provider");
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const truncated = truncateUpToAndIncluding(
|
|
401
|
+
messagesRef.current,
|
|
402
|
+
anchorUserId,
|
|
403
|
+
);
|
|
404
|
+
const anchor = truncated[truncated.length - 1];
|
|
405
|
+
if (!anchor || anchor.role !== "user") return;
|
|
406
|
+
|
|
407
|
+
setError(null);
|
|
408
|
+
|
|
409
|
+
const assistantId = newId();
|
|
410
|
+
const usingRag = (opts.rag?.knowledgeBases?.length ?? 0) > 0;
|
|
411
|
+
const assistantMsg: ChatMessage = {
|
|
412
|
+
id: assistantId,
|
|
413
|
+
role: "assistant",
|
|
414
|
+
content: "",
|
|
415
|
+
reasoning: "",
|
|
416
|
+
createdAt: Date.now(),
|
|
417
|
+
status: "streaming",
|
|
418
|
+
usingRag,
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const historyToSend = truncated.map((m) => ({
|
|
422
|
+
role: m.role,
|
|
423
|
+
content: m.content,
|
|
424
|
+
}));
|
|
425
|
+
|
|
426
|
+
const nextMessages = [...truncated, assistantMsg];
|
|
427
|
+
messagesRef.current = nextMessages;
|
|
428
|
+
setMessages(nextMessages);
|
|
429
|
+
setIsStreaming(true);
|
|
430
|
+
|
|
431
|
+
await _runAssistantTurn(assistantId, historyToSend);
|
|
432
|
+
},
|
|
433
|
+
[_runAssistantTurn],
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Remove a single message by id. When `withNextAssistant` is true and the
|
|
438
|
+
* target is a user message immediately followed by an assistant message,
|
|
439
|
+
* remove that assistant too (the "paired delete" semantic from the spec).
|
|
440
|
+
*
|
|
441
|
+
* Persists immediately via the registered onPersist callback — pure
|
|
442
|
+
* deletes don't trigger a streaming turn so we cannot rely on the
|
|
443
|
+
* `finally` block in `_runAssistantTurn` to write to localStorage.
|
|
444
|
+
*/
|
|
445
|
+
const deleteMessage = useCallback(
|
|
446
|
+
(id: string, opts?: { withNextAssistant?: boolean }) => {
|
|
447
|
+
if (isStreamingRef.current) return;
|
|
448
|
+
const list = messagesRef.current;
|
|
449
|
+
const target = list.find((m) => m.id === id);
|
|
450
|
+
if (!target) return;
|
|
451
|
+
|
|
452
|
+
const next =
|
|
453
|
+
target.role === "user" && opts?.withNextAssistant
|
|
454
|
+
? removePair(list, id)
|
|
455
|
+
: removeAt(list, id);
|
|
456
|
+
|
|
457
|
+
messagesRef.current = next;
|
|
458
|
+
setMessages(next);
|
|
459
|
+
onPersistRef.current?.(next);
|
|
460
|
+
},
|
|
461
|
+
[],
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Replace the textual content of a user message in place — used by the
|
|
466
|
+
* inline edit affordance before it calls `reissueTurn` to rerun the
|
|
467
|
+
* assistant pipeline against the new content. Returns the message id on
|
|
468
|
+
* success so the caller can chain `reissueTurn(id)` without re-querying;
|
|
469
|
+
* returns null when the id isn't a user message.
|
|
470
|
+
*/
|
|
471
|
+
const editUserMessage = useCallback(
|
|
472
|
+
(id: string, nextContent: string) => {
|
|
473
|
+
const list = messagesRef.current;
|
|
474
|
+
const idx = list.findIndex((m) => m.id === id);
|
|
475
|
+
if (idx < 0 || list[idx].role !== "user") return null;
|
|
476
|
+
const updated = list.slice();
|
|
477
|
+
updated[idx] = { ...list[idx], content: nextContent };
|
|
478
|
+
messagesRef.current = updated;
|
|
479
|
+
setMessages(updated);
|
|
480
|
+
// Do NOT persist here — the typical caller follows up with
|
|
481
|
+
// reissueTurn, which will persist after the stream settles.
|
|
482
|
+
return id;
|
|
483
|
+
},
|
|
484
|
+
[],
|
|
485
|
+
);
|
|
486
|
+
|
|
287
487
|
return {
|
|
288
488
|
messages,
|
|
289
489
|
isStreaming,
|
|
290
490
|
error,
|
|
291
491
|
send,
|
|
492
|
+
reissueTurn,
|
|
493
|
+
deleteMessage,
|
|
494
|
+
editUserMessage,
|
|
292
495
|
stop,
|
|
293
496
|
clear,
|
|
294
497
|
setMessages: replaceMessages,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure message-list mutators powering the chat surface's destructive
|
|
3
|
+
* operations (delete, truncate-and-rerun). Kept free of React, of the
|
|
4
|
+
* concrete `ChatMessage` shape, and of any side effects so we can test
|
|
5
|
+
* the rules in isolation under vitest's existing node environment.
|
|
6
|
+
*
|
|
7
|
+
* Consumers thread their own `ChatMessage` (or a structural subtype) — we
|
|
8
|
+
* only need `id` and `role`.
|
|
9
|
+
*/
|
|
10
|
+
export interface MinimalMsg {
|
|
11
|
+
id: string;
|
|
12
|
+
role: "user" | "assistant" | "system";
|
|
13
|
+
content?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Identity-preserving slice: returns the input array unchanged when the
|
|
17
|
+
* anchor isn't present, so React reference equality keeps memoised
|
|
18
|
+
* consumers from re-rendering on a no-op. */
|
|
19
|
+
export function truncateUpToAndIncluding<T extends MinimalMsg>(
|
|
20
|
+
list: T[],
|
|
21
|
+
anchorId: string,
|
|
22
|
+
): T[] {
|
|
23
|
+
const idx = list.findIndex((m) => m.id === anchorId);
|
|
24
|
+
if (idx < 0) return list;
|
|
25
|
+
return list.slice(0, idx + 1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Drops the anchor and everything after it. */
|
|
29
|
+
export function truncateBefore<T extends MinimalMsg>(
|
|
30
|
+
list: T[],
|
|
31
|
+
anchorId: string,
|
|
32
|
+
): T[] {
|
|
33
|
+
const idx = list.findIndex((m) => m.id === anchorId);
|
|
34
|
+
if (idx < 0) return list;
|
|
35
|
+
return list.slice(0, idx);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Remove a single message by id. */
|
|
39
|
+
export function removeAt<T extends MinimalMsg>(list: T[], id: string): T[] {
|
|
40
|
+
const idx = list.findIndex((m) => m.id === id);
|
|
41
|
+
if (idx < 0) return list;
|
|
42
|
+
const next = list.slice();
|
|
43
|
+
next.splice(idx, 1);
|
|
44
|
+
return next;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Remove a user message AND the immediately-following assistant message
|
|
49
|
+
* (the "paired delete" semantic). When the next slot isn't an assistant —
|
|
50
|
+
* either because it's another user message or because the user message is
|
|
51
|
+
* at the tail — only the user message is removed.
|
|
52
|
+
*/
|
|
53
|
+
export function removePair<T extends MinimalMsg>(list: T[], userId: string): T[] {
|
|
54
|
+
const idx = list.findIndex((m) => m.id === userId);
|
|
55
|
+
if (idx < 0) return list;
|
|
56
|
+
const next = list.slice();
|
|
57
|
+
const removeCount =
|
|
58
|
+
list[idx + 1] && list[idx + 1].role === "assistant" ? 2 : 1;
|
|
59
|
+
next.splice(idx, removeCount);
|
|
60
|
+
return next;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Walk backwards from the given assistant message and return the nearest
|
|
64
|
+
* user message above it. Returns null when none exists or the target id
|
|
65
|
+
* isn't in the list. */
|
|
66
|
+
export function findUserAnchorAbove<T extends MinimalMsg>(
|
|
67
|
+
list: T[],
|
|
68
|
+
fromId: string,
|
|
69
|
+
): T | null {
|
|
70
|
+
const idx = list.findIndex((m) => m.id === fromId);
|
|
71
|
+
if (idx < 0) return null;
|
|
72
|
+
for (let i = idx - 1; i >= 0; i -= 1) {
|
|
73
|
+
if (list[i].role === "user") return list[i];
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny dev-only feature toggle reader. Backed by localStorage so a developer
|
|
3
|
+
* can flip a flag from the browser devtools console without rebuilding:
|
|
4
|
+
*
|
|
5
|
+
* localStorage.setItem("tsagent.dev.logChatRequest", "1")
|
|
6
|
+
*
|
|
7
|
+
* Production builds keep behaviour off by default — these flags are debug
|
|
8
|
+
* aids, not user-facing settings. Returns false during SSR so server code
|
|
9
|
+
* paths never accidentally enable verbose logging.
|
|
10
|
+
*/
|
|
11
|
+
export type DevFlagName = "logChatRequest";
|
|
12
|
+
|
|
13
|
+
const KEY_PREFIX = "tsagent.dev.";
|
|
14
|
+
|
|
15
|
+
export function devFlag(name: DevFlagName): boolean {
|
|
16
|
+
if (typeof window === "undefined") return false;
|
|
17
|
+
try {
|
|
18
|
+
return window.localStorage.getItem(KEY_PREFIX + name) === "1";
|
|
19
|
+
} catch {
|
|
20
|
+
// Safari private mode and similar can throw on localStorage access; treat
|
|
21
|
+
// as flag off rather than crashing the caller.
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -24,6 +24,25 @@ export interface ChatMessage {
|
|
|
24
24
|
content: string;
|
|
25
25
|
/** Reasoning trace exposed by providers that stream `reasoning_content`. */
|
|
26
26
|
reasoning?: string;
|
|
27
|
+
/** Wall-clock timestamp (ms) of the first `reasoning.delta` chunk. Used to
|
|
28
|
+
* compute the "thought for X seconds" indicator on the assistant bubble. */
|
|
29
|
+
reasoningStartedAt?: number;
|
|
30
|
+
/** Wall-clock timestamp (ms) when reasoning ended — set on the first
|
|
31
|
+
* `content.delta` (model has moved past thinking) or on the terminal
|
|
32
|
+
* `done` / `error` event when no content followed. */
|
|
33
|
+
reasoningCompletedAt?: number;
|
|
34
|
+
/** True when the assistant turn is RAG-enabled (≥ 1 KB mounted). Stamped
|
|
35
|
+
* client-side at send time so the thinking pill can label the pre-stream
|
|
36
|
+
* gap as 「检索意图提取」 / 「正在检索知识库」 rather than a generic
|
|
37
|
+
* thinking spinner during the rewriter LLM call and KB queries. */
|
|
38
|
+
usingRag?: boolean;
|
|
39
|
+
/** True when the server emitted a `query.fallback` event for this turn
|
|
40
|
+
* (i.e. the rewriter LLM call failed). The pipeline continues with the
|
|
41
|
+
* original user query; the UI surfaces a non-blocking warning chip. */
|
|
42
|
+
queryRewriteFailed?: boolean;
|
|
43
|
+
/** Human-readable reason from the `query.fallback` event, shown when the
|
|
44
|
+
* user expands the warning chip. */
|
|
45
|
+
queryRewriteError?: string;
|
|
27
46
|
/** The query actually used for retrieval; may differ from the raw user input. */
|
|
28
47
|
retrievalQuery?: string;
|
|
29
48
|
/** True when the retrieval query was rewritten from multi-turn history. */
|
package/package.json
CHANGED
package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0i0y9.r._.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
module.exports=[50227,(a,b,c)=>{b.exports=a.x("node:path",()=>require("node:path"))},68826,a=>{"use strict";let b=(0,a.i(50053).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);a.s(["RefreshCw",0,b],68826)},55295,a=>{"use strict";let b=(0,a.i(50053).default)("trash-2",[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]]);a.s(["Trash2",0,b],55295)},9380,a=>{"use strict";let b=(0,a.i(50053).default)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);a.s(["Search",0,b],9380)},10215,a=>{"use strict";var b=a.i(34020);a.s(["EmptyState",0,function({icon:a,title:c,description:d,action:e,illustration:f}){return(0,b.jsxs)("div",{className:"flex flex-col items-center justify-center py-16 px-4 text-center",children:[f??(0,b.jsx)("div",{className:"mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-[hsl(var(--primary)/0.08)] ring-8 ring-[hsl(var(--primary)/0.04)]",children:(0,b.jsx)(a,{className:"text-primary",size:36,strokeWidth:1.75})}),(0,b.jsx)("h3",{className:"mb-2 font-display text-lg font-semibold text-foreground",children:c}),(0,b.jsx)("p",{className:"mb-6 max-w-sm text-sm text-muted-foreground",children:d}),e&&(0,b.jsx)("div",{children:e})]})}])},81619,a=>{"use strict";let b=(0,a.i(50053).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);a.s(["Loader2",0,b],81619)},37255,83917,a=>{"use strict";var b=a.i(83366),c=a.i(53141);async function d(){return(await (0,c.apiGet)("/api/v1/llm/providers")).providers}async function e(a){return(await (0,c.apiGet)(`/api/v1/llm/providers/${encodeURIComponent(a)}`)).provider}async function f(a){return(await (0,c.apiPost)("/api/v1/llm/providers",a)).provider}async function g(a,b){return(await (0,c.apiPut)(`/api/v1/llm/providers/${encodeURIComponent(a)}`,b)).provider}async function h(a){await (0,c.apiDelete)(`/api/v1/llm/providers/${encodeURIComponent(a)}`)}async function i(a){return(await (0,c.apiGet)(`/api/v1/llm/providers/${encodeURIComponent(a)}/models`)).models}async function j(a){return(await (0,c.apiPost)(`/api/v1/llm/providers/${encodeURIComponent(a)}/test`)).result}a.s(["createProvider",0,f,"deleteProvider",0,h,"fetchProviderModels",0,i,"getProvider",0,e,"listProviders",0,d,"testProviderConnectivity",0,j,"updateProvider",0,g],83917);let k=["llm-providers"];a.s(["LLM_PROVIDERS_QUERY_KEY",0,k,"useLLMProviders",0,function(){return(0,b.useQuery)({queryKey:k,queryFn:d,staleTime:3e4})}],37255)},69024,a=>{"use strict";var b=a.i(53141);async function c(){return(0,b.apiGet)("/api/v1/knowledge-bases")}async function d(a){return(0,b.apiGet)(`/api/v1/knowledge-bases/${encodeURIComponent(a)}`)}async function e(a){await (0,b.apiPost)("/api/v1/knowledge-bases",a)}async function f(a){let{knowledgeBaseName:c,...d}=a;await (0,b.apiPut)(`/api/v1/knowledge-bases/${encodeURIComponent(c)}`,d)}async function g(a){await (0,b.apiDelete)(`/api/v1/knowledge-bases/${encodeURIComponent(a)}`)}a.s(["createKnowledgeBase",0,e,"deleteKnowledgeBase",0,g,"describeKnowledgeBase",0,d,"listKnowledgeBases",0,c,"updateKnowledgeBase",0,f])},78388,a=>{"use strict";var b=a.i(34020),c=a.i(71938),d=a.i(80470);let e=(0,c.createContext)(null);a.s(["SubspaceProvider",0,function({knowledgeBaseName:a,children:f}){let g=(0,d.useSearchParams)(),h=g.toString(),i=(0,d.usePathname)(),j=(0,d.useRouter)(),{history:k,addToHistory:l}=function(a){let[b,d]=(0,c.useState)([]);return(0,c.useEffect)(()=>{d([])},[a]),{history:b,addToHistory:(0,c.useCallback)(a=>{a&&d(b=>[a,...b.filter(b=>b!==a)].slice(0,10))},[a]),clearHistory:(0,c.useCallback)(()=>{d([])},[a])}}(a),m=g.get("subspace"),n=(0,c.useRef)(!1);(0,c.useEffect)(()=>{n.current||(n.current=!0)},[a,m,h,i,j]),(0,c.useEffect)(()=>{m&&l(m)},[m,a,l]);let o=(0,c.useCallback)(a=>{let b=a.trim();if(!b)return;let c=new URLSearchParams(h);c.set("subspace",b),j.replace(`${i}?${c.toString()}`)},[h,i,j]),p=(0,c.useCallback)(()=>{let a=new URLSearchParams(h);a.delete("subspace");let b=a.toString();j.replace(b?`${i}?${b}`:i)},[h,i,j]);return(0,b.jsx)(e.Provider,{value:{subspace:m,setSubspace:o,clearSubspace:p,history:k,addToHistory:l},children:f})},"useSubspace",0,function(){let a=(0,c.useContext)(e);if(!a)throw Error("useSubspace must be used within a SubspaceProvider");return a},"useSubspaceOptional",0,function(){return(0,c.useContext)(e)}],78388)},36965,23331,a=>{"use strict";var b=a.i(34020),c=a.i(71938),d=a.i(84694),e=a.i(58036),f=a.i(56620),g=a.i(59653),h=a.i(83370),i="Toggle",j=c.forwardRef((a,c)=>{let{pressed:d,defaultPressed:f,onPressedChange:j,...k}=a,[l,m]=(0,h.useControllableState)({prop:d,onChange:j,defaultProp:f??!1,caller:i});return(0,b.jsx)(e.Primitive.button,{type:"button","aria-pressed":l,"data-state":l?"on":"off","data-disabled":a.disabled?"":void 0,...k,ref:c,onClick:(0,g.composeEventHandlers)(a.onClick,()=>{a.disabled||m(!l)})})});j.displayName=i;var k=a.i(74974),l="ToggleGroup",[m,n]=(0,d.createContextScope)(l,[f.createRovingFocusGroupScope]),o=(0,f.createRovingFocusGroupScope)(),p=c.default.forwardRef((a,c)=>{let{type:d,...e}=a;if("single"===d)return(0,b.jsx)(s,{...e,ref:c});if("multiple"===d)return(0,b.jsx)(t,{...e,ref:c});throw Error(`Missing prop \`type\` expected on \`${l}\``)});p.displayName=l;var[q,r]=m(l),s=c.default.forwardRef((a,d)=>{let{value:e,defaultValue:f,onValueChange:g=()=>{},...i}=a,[j,k]=(0,h.useControllableState)({prop:e,defaultProp:f??"",onChange:g,caller:l});return(0,b.jsx)(q,{scope:a.__scopeToggleGroup,type:"single",value:c.default.useMemo(()=>j?[j]:[],[j]),onItemActivate:k,onItemDeactivate:c.default.useCallback(()=>k(""),[k]),children:(0,b.jsx)(w,{...i,ref:d})})}),t=c.default.forwardRef((a,d)=>{let{value:e,defaultValue:f,onValueChange:g=()=>{},...i}=a,[j,k]=(0,h.useControllableState)({prop:e,defaultProp:f??[],onChange:g,caller:l}),m=c.default.useCallback(a=>k((b=[])=>[...b,a]),[k]),n=c.default.useCallback(a=>k((b=[])=>b.filter(b=>b!==a)),[k]);return(0,b.jsx)(q,{scope:a.__scopeToggleGroup,type:"multiple",value:j,onItemActivate:m,onItemDeactivate:n,children:(0,b.jsx)(w,{...i,ref:d})})});p.displayName=l;var[u,v]=m(l),w=c.default.forwardRef((a,c)=>{let{__scopeToggleGroup:d,disabled:g=!1,rovingFocus:h=!0,orientation:i,dir:j,loop:l=!0,...m}=a,n=o(d),p=(0,k.useDirection)(j),q={role:"group",dir:p,...m};return(0,b.jsx)(u,{scope:d,rovingFocus:h,disabled:g,children:h?(0,b.jsx)(f.Root,{asChild:!0,...n,orientation:i,dir:p,loop:l,children:(0,b.jsx)(e.Primitive.div,{...q,ref:c})}):(0,b.jsx)(e.Primitive.div,{...q,ref:c})})}),x="ToggleGroupItem",y=c.default.forwardRef((a,d)=>{let e=r(x,a.__scopeToggleGroup),g=v(x,a.__scopeToggleGroup),h=o(a.__scopeToggleGroup),i=e.value.includes(a.value),j=g.disabled||a.disabled,k={...a,pressed:i,disabled:j},l=c.default.useRef(null);return g.rovingFocus?(0,b.jsx)(f.Item,{asChild:!0,...h,focusable:!j,active:i,ref:l,children:(0,b.jsx)(z,{...k,ref:d})}):(0,b.jsx)(z,{...k,ref:d})});y.displayName=x;var z=c.default.forwardRef((a,c)=>{let{__scopeToggleGroup:d,value:e,...f}=a,g=r(x,d),h={role:"radio","aria-checked":a.pressed,"aria-pressed":void 0},i="single"===g.type?h:void 0;return(0,b.jsx)(j,{...i,...f,ref:c,onPressedChange:a=>{a?g.onItemActivate(e):g.onItemDeactivate(e)}})}),A=a.i(64565);let B=c.createContext({size:"default",variant:"default"}),C=c.forwardRef(({className:a,variant:c="default",size:d="default",children:e,...f},g)=>(0,b.jsx)(p,{ref:g,className:(0,A.cn)("inline-flex items-center justify-center gap-1",a),...f,children:(0,b.jsx)(B.Provider,{value:{variant:c,size:d},children:e})}));C.displayName=p.displayName;let D=c.forwardRef(({className:a,children:c,...d},e)=>(0,b.jsx)(y,{ref:e,className:(0,A.cn)("relative inline-flex items-center justify-center whitespace-nowrap","text-sm font-medium transition-all","first:rounded-l-[7px] last:rounded-r-[7px]","border-l border-[hsl(var(--border)/0.6)]","first:border-l-0","data-[state=on]:border-l-transparent","[&[data-state=on]+*]:border-l-transparent","ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:pointer-events-none disabled:opacity-50","hover:bg-[hsl(var(--muted)/0.6)] hover:text-[hsl(var(--foreground))]","data-[state=on]:bg-[hsl(var(--background))] data-[state=on]:text-[hsl(var(--foreground))] data-[state=on]:shadow-sm",a),...d,children:c}));D.displayName=y.displayName,a.s(["ToggleGroup",0,C,"ToggleGroupItem",0,D],36965);var E=a.i(14151);a.s(["TagInput",0,function({value:a,onChange:d,placeholder:e="输入后按回车添加"}){let[f,g]=(0,c.useState)(""),h=(0,c.useCallback)(b=>{let c=b.trim();c&&!a.includes(c)&&d([...a,c]),g("")},[a,d]),i=(0,c.useCallback)(b=>{d(a.filter((a,c)=>c!==b))},[a,d]);return(0,b.jsxs)("div",{className:(0,A.cn)("flex flex-wrap items-center gap-1.5 rounded-md border border-[hsl(var(--input))] bg-background px-3 py-2","focus-within:border-[hsl(var(--ring))] focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-0","min-h-10 transition-colors"),children:[a.map((a,c)=>(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-full border border-primary-200 bg-primary-100 px-2 py-0.5 text-xs font-medium text-primary-700",children:[a,(0,b.jsx)("button",{type:"button",onClick:()=>i(c),className:"inline-flex items-center justify-center rounded-full p-0.5 hover:opacity-70 transition-opacity","aria-label":`删除标签 ${a}`,children:(0,b.jsx)(E.X,{size:12})})]},`${a}-${c}`)),(0,b.jsx)("input",{type:"text",value:f,onChange:a=>g(a.target.value),onKeyDown:b=>{("Enter"===b.key||","===b.key)&&(b.preventDefault(),h(f)),"Backspace"===b.key&&""===f&&a.length>0&&i(a.length-1)},placeholder:0===a.length?e:"",className:"flex-1 min-w-20 bg-transparent text-sm outline-none placeholder:text-muted-foreground"})]})}],23331)},27692,a=>{"use strict";var b=a.i(71938),c=a.i(59653),d=a.i(84694),e=a.i(83370),f=a.i(39166),g=a.i(68189),h=a.i(58036),i=a.i(98392),j=a.i(59231),k=a.i(34020),l="Collapsible",[m,n]=(0,d.createContextScope)(l),[o,p]=m(l),q=b.forwardRef((a,c)=>{let{__scopeCollapsible:d,open:f,defaultOpen:g,disabled:i,onOpenChange:m,...n}=a,[p,q]=(0,e.useControllableState)({prop:f,defaultProp:g??!1,onChange:m,caller:l});return(0,k.jsx)(o,{scope:d,disabled:i,contentId:(0,j.useId)(),open:p,onOpenToggle:b.useCallback(()=>q(a=>!a),[q]),children:(0,k.jsx)(h.Primitive.div,{"data-state":w(p),"data-disabled":i?"":void 0,...n,ref:c})})});q.displayName=l;var r="CollapsibleTrigger",s=b.forwardRef((a,b)=>{let{__scopeCollapsible:d,...e}=a,f=p(r,d);return(0,k.jsx)(h.Primitive.button,{type:"button","aria-controls":f.contentId,"aria-expanded":f.open||!1,"data-state":w(f.open),"data-disabled":f.disabled?"":void 0,disabled:f.disabled,...e,ref:b,onClick:(0,c.composeEventHandlers)(a.onClick,f.onOpenToggle)})});s.displayName=r;var t="CollapsibleContent",u=b.forwardRef((a,b)=>{let{forceMount:c,...d}=a,e=p(t,a.__scopeCollapsible);return(0,k.jsx)(i.Presence,{present:c||e.open,children:({present:a})=>(0,k.jsx)(v,{...d,ref:b,present:a})})});u.displayName=t;var v=b.forwardRef((a,c)=>{let{__scopeCollapsible:d,present:e,children:i,...j}=a,l=p(t,d),[m,n]=b.useState(e),o=b.useRef(null),q=(0,g.useComposedRefs)(c,o),r=b.useRef(0),s=r.current,u=b.useRef(0),v=u.current,x=l.open||m,y=b.useRef(x),z=b.useRef(void 0);return b.useEffect(()=>{let a=requestAnimationFrame(()=>y.current=!1);return()=>cancelAnimationFrame(a)},[]),(0,f.useLayoutEffect)(()=>{let a=o.current;if(a){z.current=z.current||{transitionDuration:a.style.transitionDuration,animationName:a.style.animationName},a.style.transitionDuration="0s",a.style.animationName="none";let b=a.getBoundingClientRect();r.current=b.height,u.current=b.width,y.current||(a.style.transitionDuration=z.current.transitionDuration,a.style.animationName=z.current.animationName),n(e)}},[l.open,e]),(0,k.jsx)(h.Primitive.div,{"data-state":w(l.open),"data-disabled":l.disabled?"":void 0,id:l.contentId,hidden:!x,...j,ref:q,style:{"--radix-collapsible-content-height":s?`${s}px`:void 0,"--radix-collapsible-content-width":v?`${v}px`:void 0,...a.style},children:x&&i})});function w(a){return a?"open":"closed"}a.s(["Collapsible",0,q,"CollapsibleContent",0,u,"CollapsibleTrigger",0,s],27692)},16772,a=>{"use strict";let b=(0,a.i(50053).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);a.s(["Copy",0,b],16772)},9367,a=>{"use strict";var b=a.i(83366),c=a.i(69024);a.s(["useKnowledgeBases",0,function(){return(0,b.useQuery)({queryKey:["knowledge-bases"],queryFn:c.listKnowledgeBases,staleTime:3e4})}])},11097,a=>{a.v(b=>Promise.all(["server/chunks/ssr/0w08_streamdown_dist_highlighted-body-OFNGDK62_03c0toy.js"].map(b=>a.l(b))).then(()=>b(37971)))},91275,a=>{a.v(b=>Promise.all(["server/chunks/ssr/0w08_streamdown_dist_mermaid-GHXKKRXX_03ew1fz.js"].map(b=>a.l(b))).then(()=>b(91395)))}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%5D__0i0y9.r._.js.map
|
package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0r_6wpx._.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
module.exports=[50227,(a,b,c)=>{b.exports=a.x("node:path",()=>require("node:path"))},68826,a=>{"use strict";let b=(0,a.i(50053).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);a.s(["RefreshCw",0,b],68826)},9380,a=>{"use strict";let b=(0,a.i(50053).default)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);a.s(["Search",0,b],9380)},10215,a=>{"use strict";var b=a.i(34020);a.s(["EmptyState",0,function({icon:a,title:c,description:d,action:e,illustration:f}){return(0,b.jsxs)("div",{className:"flex flex-col items-center justify-center py-16 px-4 text-center",children:[f??(0,b.jsx)("div",{className:"mb-5 flex h-20 w-20 items-center justify-center rounded-full bg-[hsl(var(--primary)/0.08)] ring-8 ring-[hsl(var(--primary)/0.04)]",children:(0,b.jsx)(a,{className:"text-primary",size:36,strokeWidth:1.75})}),(0,b.jsx)("h3",{className:"mb-2 font-display text-lg font-semibold text-foreground",children:c}),(0,b.jsx)("p",{className:"mb-6 max-w-sm text-sm text-muted-foreground",children:d}),e&&(0,b.jsx)("div",{children:e})]})}])},81619,a=>{"use strict";let b=(0,a.i(50053).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);a.s(["Loader2",0,b],81619)},37255,83917,a=>{"use strict";var b=a.i(83366),c=a.i(53141);async function d(){return(await (0,c.apiGet)("/api/v1/llm/providers")).providers}async function e(a){return(await (0,c.apiGet)(`/api/v1/llm/providers/${encodeURIComponent(a)}`)).provider}async function f(a){return(await (0,c.apiPost)("/api/v1/llm/providers",a)).provider}async function g(a,b){return(await (0,c.apiPut)(`/api/v1/llm/providers/${encodeURIComponent(a)}`,b)).provider}async function h(a){await (0,c.apiDelete)(`/api/v1/llm/providers/${encodeURIComponent(a)}`)}async function i(a){return(await (0,c.apiGet)(`/api/v1/llm/providers/${encodeURIComponent(a)}/models`)).models}async function j(a){return(await (0,c.apiPost)(`/api/v1/llm/providers/${encodeURIComponent(a)}/test`)).result}a.s(["createProvider",0,f,"deleteProvider",0,h,"fetchProviderModels",0,i,"getProvider",0,e,"listProviders",0,d,"testProviderConnectivity",0,j,"updateProvider",0,g],83917);let k=["llm-providers"];a.s(["LLM_PROVIDERS_QUERY_KEY",0,k,"useLLMProviders",0,function(){return(0,b.useQuery)({queryKey:k,queryFn:d,staleTime:3e4})}],37255)},36965,23331,a=>{"use strict";var b=a.i(34020),c=a.i(71938),d=a.i(84694),e=a.i(58036),f=a.i(56620),g=a.i(59653),h=a.i(83370),i="Toggle",j=c.forwardRef((a,c)=>{let{pressed:d,defaultPressed:f,onPressedChange:j,...k}=a,[l,m]=(0,h.useControllableState)({prop:d,onChange:j,defaultProp:f??!1,caller:i});return(0,b.jsx)(e.Primitive.button,{type:"button","aria-pressed":l,"data-state":l?"on":"off","data-disabled":a.disabled?"":void 0,...k,ref:c,onClick:(0,g.composeEventHandlers)(a.onClick,()=>{a.disabled||m(!l)})})});j.displayName=i;var k=a.i(74974),l="ToggleGroup",[m,n]=(0,d.createContextScope)(l,[f.createRovingFocusGroupScope]),o=(0,f.createRovingFocusGroupScope)(),p=c.default.forwardRef((a,c)=>{let{type:d,...e}=a;if("single"===d)return(0,b.jsx)(s,{...e,ref:c});if("multiple"===d)return(0,b.jsx)(t,{...e,ref:c});throw Error(`Missing prop \`type\` expected on \`${l}\``)});p.displayName=l;var[q,r]=m(l),s=c.default.forwardRef((a,d)=>{let{value:e,defaultValue:f,onValueChange:g=()=>{},...i}=a,[j,k]=(0,h.useControllableState)({prop:e,defaultProp:f??"",onChange:g,caller:l});return(0,b.jsx)(q,{scope:a.__scopeToggleGroup,type:"single",value:c.default.useMemo(()=>j?[j]:[],[j]),onItemActivate:k,onItemDeactivate:c.default.useCallback(()=>k(""),[k]),children:(0,b.jsx)(w,{...i,ref:d})})}),t=c.default.forwardRef((a,d)=>{let{value:e,defaultValue:f,onValueChange:g=()=>{},...i}=a,[j,k]=(0,h.useControllableState)({prop:e,defaultProp:f??[],onChange:g,caller:l}),m=c.default.useCallback(a=>k((b=[])=>[...b,a]),[k]),n=c.default.useCallback(a=>k((b=[])=>b.filter(b=>b!==a)),[k]);return(0,b.jsx)(q,{scope:a.__scopeToggleGroup,type:"multiple",value:j,onItemActivate:m,onItemDeactivate:n,children:(0,b.jsx)(w,{...i,ref:d})})});p.displayName=l;var[u,v]=m(l),w=c.default.forwardRef((a,c)=>{let{__scopeToggleGroup:d,disabled:g=!1,rovingFocus:h=!0,orientation:i,dir:j,loop:l=!0,...m}=a,n=o(d),p=(0,k.useDirection)(j),q={role:"group",dir:p,...m};return(0,b.jsx)(u,{scope:d,rovingFocus:h,disabled:g,children:h?(0,b.jsx)(f.Root,{asChild:!0,...n,orientation:i,dir:p,loop:l,children:(0,b.jsx)(e.Primitive.div,{...q,ref:c})}):(0,b.jsx)(e.Primitive.div,{...q,ref:c})})}),x="ToggleGroupItem",y=c.default.forwardRef((a,d)=>{let e=r(x,a.__scopeToggleGroup),g=v(x,a.__scopeToggleGroup),h=o(a.__scopeToggleGroup),i=e.value.includes(a.value),j=g.disabled||a.disabled,k={...a,pressed:i,disabled:j},l=c.default.useRef(null);return g.rovingFocus?(0,b.jsx)(f.Item,{asChild:!0,...h,focusable:!j,active:i,ref:l,children:(0,b.jsx)(z,{...k,ref:d})}):(0,b.jsx)(z,{...k,ref:d})});y.displayName=x;var z=c.default.forwardRef((a,c)=>{let{__scopeToggleGroup:d,value:e,...f}=a,g=r(x,d),h={role:"radio","aria-checked":a.pressed,"aria-pressed":void 0},i="single"===g.type?h:void 0;return(0,b.jsx)(j,{...i,...f,ref:c,onPressedChange:a=>{a?g.onItemActivate(e):g.onItemDeactivate(e)}})}),A=a.i(64565);let B=c.createContext({size:"default",variant:"default"}),C=c.forwardRef(({className:a,variant:c="default",size:d="default",children:e,...f},g)=>(0,b.jsx)(p,{ref:g,className:(0,A.cn)("inline-flex items-center justify-center gap-1",a),...f,children:(0,b.jsx)(B.Provider,{value:{variant:c,size:d},children:e})}));C.displayName=p.displayName;let D=c.forwardRef(({className:a,children:c,...d},e)=>(0,b.jsx)(y,{ref:e,className:(0,A.cn)("relative inline-flex items-center justify-center whitespace-nowrap","text-sm font-medium transition-all","first:rounded-l-[7px] last:rounded-r-[7px]","border-l border-[hsl(var(--border)/0.6)]","first:border-l-0","data-[state=on]:border-l-transparent","[&[data-state=on]+*]:border-l-transparent","ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:pointer-events-none disabled:opacity-50","hover:bg-[hsl(var(--muted)/0.6)] hover:text-[hsl(var(--foreground))]","data-[state=on]:bg-[hsl(var(--background))] data-[state=on]:text-[hsl(var(--foreground))] data-[state=on]:shadow-sm",a),...d,children:c}));D.displayName=y.displayName,a.s(["ToggleGroup",0,C,"ToggleGroupItem",0,D],36965);var E=a.i(14151);a.s(["TagInput",0,function({value:a,onChange:d,placeholder:e="输入后按回车添加"}){let[f,g]=(0,c.useState)(""),h=(0,c.useCallback)(b=>{let c=b.trim();c&&!a.includes(c)&&d([...a,c]),g("")},[a,d]),i=(0,c.useCallback)(b=>{d(a.filter((a,c)=>c!==b))},[a,d]);return(0,b.jsxs)("div",{className:(0,A.cn)("flex flex-wrap items-center gap-1.5 rounded-md border border-[hsl(var(--input))] bg-background px-3 py-2","focus-within:border-[hsl(var(--ring))] focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-0","min-h-10 transition-colors"),children:[a.map((a,c)=>(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-full border border-primary-200 bg-primary-100 px-2 py-0.5 text-xs font-medium text-primary-700",children:[a,(0,b.jsx)("button",{type:"button",onClick:()=>i(c),className:"inline-flex items-center justify-center rounded-full p-0.5 hover:opacity-70 transition-opacity","aria-label":`删除标签 ${a}`,children:(0,b.jsx)(E.X,{size:12})})]},`${a}-${c}`)),(0,b.jsx)("input",{type:"text",value:f,onChange:a=>g(a.target.value),onKeyDown:b=>{("Enter"===b.key||","===b.key)&&(b.preventDefault(),h(f)),"Backspace"===b.key&&""===f&&a.length>0&&i(a.length-1)},placeholder:0===a.length?e:"",className:"flex-1 min-w-20 bg-transparent text-sm outline-none placeholder:text-muted-foreground"})]})}],23331)},27692,a=>{"use strict";var b=a.i(71938),c=a.i(59653),d=a.i(84694),e=a.i(83370),f=a.i(39166),g=a.i(68189),h=a.i(58036),i=a.i(98392),j=a.i(59231),k=a.i(34020),l="Collapsible",[m,n]=(0,d.createContextScope)(l),[o,p]=m(l),q=b.forwardRef((a,c)=>{let{__scopeCollapsible:d,open:f,defaultOpen:g,disabled:i,onOpenChange:m,...n}=a,[p,q]=(0,e.useControllableState)({prop:f,defaultProp:g??!1,onChange:m,caller:l});return(0,k.jsx)(o,{scope:d,disabled:i,contentId:(0,j.useId)(),open:p,onOpenToggle:b.useCallback(()=>q(a=>!a),[q]),children:(0,k.jsx)(h.Primitive.div,{"data-state":w(p),"data-disabled":i?"":void 0,...n,ref:c})})});q.displayName=l;var r="CollapsibleTrigger",s=b.forwardRef((a,b)=>{let{__scopeCollapsible:d,...e}=a,f=p(r,d);return(0,k.jsx)(h.Primitive.button,{type:"button","aria-controls":f.contentId,"aria-expanded":f.open||!1,"data-state":w(f.open),"data-disabled":f.disabled?"":void 0,disabled:f.disabled,...e,ref:b,onClick:(0,c.composeEventHandlers)(a.onClick,f.onOpenToggle)})});s.displayName=r;var t="CollapsibleContent",u=b.forwardRef((a,b)=>{let{forceMount:c,...d}=a,e=p(t,a.__scopeCollapsible);return(0,k.jsx)(i.Presence,{present:c||e.open,children:({present:a})=>(0,k.jsx)(v,{...d,ref:b,present:a})})});u.displayName=t;var v=b.forwardRef((a,c)=>{let{__scopeCollapsible:d,present:e,children:i,...j}=a,l=p(t,d),[m,n]=b.useState(e),o=b.useRef(null),q=(0,g.useComposedRefs)(c,o),r=b.useRef(0),s=r.current,u=b.useRef(0),v=u.current,x=l.open||m,y=b.useRef(x),z=b.useRef(void 0);return b.useEffect(()=>{let a=requestAnimationFrame(()=>y.current=!1);return()=>cancelAnimationFrame(a)},[]),(0,f.useLayoutEffect)(()=>{let a=o.current;if(a){z.current=z.current||{transitionDuration:a.style.transitionDuration,animationName:a.style.animationName},a.style.transitionDuration="0s",a.style.animationName="none";let b=a.getBoundingClientRect();r.current=b.height,u.current=b.width,y.current||(a.style.transitionDuration=z.current.transitionDuration,a.style.animationName=z.current.animationName),n(e)}},[l.open,e]),(0,k.jsx)(h.Primitive.div,{"data-state":w(l.open),"data-disabled":l.disabled?"":void 0,id:l.contentId,hidden:!x,...j,ref:q,style:{"--radix-collapsible-content-height":s?`${s}px`:void 0,"--radix-collapsible-content-width":v?`${v}px`:void 0,...a.style},children:x&&i})});function w(a){return a?"open":"closed"}a.s(["Collapsible",0,q,"CollapsibleContent",0,u,"CollapsibleTrigger",0,s],27692)},16772,a=>{"use strict";let b=(0,a.i(50053).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);a.s(["Copy",0,b],16772)},99016,a=>{"use strict";var b=a.i(34020),c=a.i(71938),d=a.i(71562),e=a.i(71071),f=a.i(9380),g=a.i(1927),h=a.i(7704),i=a.i(76192),j=a.i(72518),k=a.i(92942),l=a.i(18236),m=a.i(93078),n=a.i(15325);function o(a,b,c){let d=(0,m.assembleRetrievalConfiguration)(b,b.topK)??{};c&&(d.filter=c);let e={knowledgeBaseName:a,retrievalQuery:{type:"TEXT",text:b.query??""}};return b.subspace?.length&&(e.subspace=b.subspace),Object.keys(d).length>0&&(e.retrievalConfiguration=d),e}function p(a,b){let c=b?.retrievalConfiguration?.searchType??["DENSE_VECTOR"],d=b?.retrievalConfiguration?.rerankingConfiguration,e=d?.rrfConfiguration,f=d?.weightConfiguration,g=d?.modelConfiguration,h=c.includes("DENSE_VECTOR")&&c.includes("FULL_TEXT"),i=d?.type==="RRF"||d?.type==="WEIGHT"?h?d.type:"MODEL":d?.type==="MODEL"?"MODEL":"WEIGHT";return{knowledgeBaseName:a,query:"",subspace:[],topK:d?.numberOfResults??5,searchType:c,rerankType:i,rrfK:e?.k??60,rrfDenseWeight:e?.denseVectorSearchWeight??.5,rrfFullTextWeight:e?.fullTextSearchWeight??.5,weightDense:f?.denseVectorSearchWeight??.5,weightFullText:f?.fullTextSearchWeight??.5,modelProvider:g?.provider??"bailian",modelName:g?.model??"gte-rerank-v2"}}function q({buildRequestJson:a}){let[d,e]=(0,c.useState)(!1);return(0,b.jsxs)("div",{className:"border border-[hsl(var(--border))] rounded-md overflow-hidden",children:[(0,b.jsxs)("button",{type:"button",className:"flex w-full items-center gap-1 px-3 py-2 text-xs text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))]",onClick:()=>e(a=>!a),children:[d?(0,b.jsx)(g.ChevronDown,{className:"h-3 w-3"}):(0,b.jsx)(h.ChevronRight,{className:"h-3 w-3"}),"请求预览"]}),d&&(0,b.jsx)("pre",{className:"px-3 pb-3 text-xs overflow-auto max-h-60 text-[hsl(var(--foreground))]",children:JSON.stringify(a(),null,2)})]})}a.s(["RetrievalForm",0,function({knowledgeBaseName:a,knowledgeBase:g,onSubmit:h,isLoading:m}){let r=(0,c.useRef)(null),s=(0,d.useForm)({resolver:(0,e.zodResolver)(n.retrievalSchema),defaultValues:p(a,g)});return(0,b.jsx)(k.Form,{...s,children:(0,b.jsxs)("form",{onSubmit:s.handleSubmit(function(b){h(o(a,b,r.current?.getFilter()))}),className:"space-y-5",children:[(0,b.jsx)(k.FormField,{control:s.control,name:"query",render:({field:a})=>(0,b.jsxs)(k.FormItem,{children:[(0,b.jsx)(k.FormLabel,{children:"查询内容"}),(0,b.jsx)(k.FormControl,{children:(0,b.jsxs)("div",{className:"relative",children:[(0,b.jsx)(f.Search,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[hsl(var(--muted-foreground))]"}),(0,b.jsx)(j.Input,{placeholder:"输入检索查询...",className:"pl-9",maxLength:128,...a})]})}),(0,b.jsx)(k.FormMessage,{})]})}),(0,b.jsx)(l.RetrievalParamsFields,{form:s,knowledgeBase:g,filterRef:r}),(0,b.jsx)(q,{buildRequestJson:()=>o(a,s.getValues(),r.current?.getFilter())}),(0,b.jsxs)(i.Button,{type:"submit",disabled:m,className:"w-full",children:[(0,b.jsx)(f.Search,{className:"mr-2 h-4 w-4"}),m?"检索中...":"执行检索"]})]})})},"assembleRetrievalRequest",0,o,"retrievalDefaultsFromKB",0,p])},89104,a=>{"use strict";var b=a.i(34020),c=a.i(71938),d=a.i(71562),e=a.i(71071),f=a.i(9380),g=a.i(76192),h=a.i(72518),i=a.i(92942),j=a.i(18236),k=a.i(99016),l=a.i(15325),m=a.i(64363),n=a.i(32191),o=a.i(87951);let p="你是基于知识库回答问题的助手。请严格依据下方「检索结果」作答;若检索结果未涵盖相关信息,请如实说明未在知识库中找到,不要编造。";a.s(["QaForm",0,function({knowledgeBaseName:a,knowledgeBase:q,onChange:r,onClearConversation:s,disabled:t}){let u=(0,c.useRef)(null),v=(0,d.useForm)({resolver:(0,e.zodResolver)(l.retrievalSchema),defaultValues:{...(0,k.retrievalDefaultsFromKB)(a,q),query:"__qa_placeholder__"}}),[w,x]=(0,c.useState)(""),[y,z]=(0,c.useState)(""),[A,B]=(0,c.useState)(.7),[C,D]=(0,c.useState)(p),E=v.watch(),F=JSON.stringify(E);return(0,c.useEffect)(()=>{if(!w||!y)return;let b=u.current?.getFilter(),c=(0,k.assembleRetrievalRequest)(a,{...E,query:"placeholder"},b);r({providerId:w,model:y,temperature:A,systemPrompt:C,rag:{knowledgeBases:[{knowledgeBaseName:a,...c.subspace?.length?{subspace:c.subspace}:{},...c.retrievalConfiguration?{retrievalConfiguration:c.retrievalConfiguration}:{}}]}})},[w,y,A,C,F,a]),(0,b.jsx)(i.Form,{...v,children:(0,b.jsxs)("form",{className:"space-y-5",onSubmit:a=>a.preventDefault(),children:[(0,b.jsxs)("div",{className:"space-y-4 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.25)] p-4",children:[(0,b.jsx)(m.LLMModelSelector,{providerId:w,model:y,onProviderChange:(a,b)=>{x(a),z(b??"")},onModelChange:z,allowFreeText:!0,autoSelectFirst:!0,providerLabel:"大模型",modelLabel:"模型"}),(0,b.jsx)(o.TemperatureSlider,{value:A,onChange:B})]}),(0,b.jsx)(n.SystemPromptInput,{value:C,onChange:D,placeholder:p,helperText:"检索到的 chunks 会自动拼接在提示词之后作为上下文",rows:4}),(0,b.jsx)(i.FormField,{control:v.control,name:"query",render:()=>(0,b.jsxs)(i.FormItem,{className:"sr-only",children:[(0,b.jsx)(i.FormLabel,{children:"query placeholder"}),(0,b.jsx)(i.FormControl,{children:(0,b.jsx)(h.Input,{})}),(0,b.jsx)(i.FormMessage,{})]})}),(0,b.jsx)("div",{className:"space-y-5",children:(0,b.jsx)(j.RetrievalParamsFields,{form:v,knowledgeBase:q,filterRef:u,topKLabel:"检索 TopK"})}),(0,b.jsxs)("p",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[(0,b.jsx)(f.Search,{className:"h-3 w-3"}),"每轮用户消息都会触发一次检索,结果注入系统提示词"]}),(0,b.jsx)(g.Button,{type:"button",variant:"outline",className:"w-full",disabled:t,onClick:s,children:"清空对话"})]})})}])},93693,a=>a.a(async(b,c)=>{try{var d=a.i(34020),e=a.i(71938),f=a.i(57900),g=a.i(89104),h=a.i(33280),i=a.i(9135),j=b([f]);[f]=j.then?(await j)():j,a.s(["default",0,function({params:a}){let{name:b}=(0,e.use)(a),c=decodeURIComponent(b),{data:j}=(0,h.useKnowledgeBase)(c),[k,l]=(0,e.useState)(null),m=(0,i.useQaChat)({providerId:k?.providerId??"",model:k?.model??"",systemPrompt:k?.systemPrompt??"",temperature:k?.temperature??.7,rag:k?.rag}),n=!!(k?.providerId&&k?.model);return(0,d.jsxs)("div",{className:"grid gap-6 lg:grid-cols-[360px_1fr]",children:[(0,d.jsx)("aside",{className:"lg:sticky lg:top-20 lg:max-h-[calc(100vh-6rem)] lg:overflow-y-auto",children:(0,d.jsx)(g.QaForm,{knowledgeBaseName:c,knowledgeBase:j,onChange:l,onClearConversation:m.clear,disabled:m.isStreaming})}),(0,d.jsx)("section",{className:"min-h-[640px]",children:(0,d.jsx)(f.QaChatPanel,{messages:m.messages,isStreaming:m.isStreaming,canSend:n,error:m.error,onSend:m.send,onStop:m.stop})})]})}]),c()}catch(a){c(a)}},!1),11097,a=>{a.v(b=>Promise.all(["server/chunks/ssr/0w08_streamdown_dist_highlighted-body-OFNGDK62_03c0toy.js"].map(b=>a.l(b))).then(()=>b(37971)))},91275,a=>{a.v(b=>Promise.all(["server/chunks/ssr/0w08_streamdown_dist_mermaid-GHXKKRXX_03ew1fz.js"].map(b=>a.l(b))).then(()=>b(91395)))}];
|
|
2
|
-
|
|
3
|
-
//# sourceMappingURL=%5Broot-of-the-server%5D__0r_6wpx._.js.map
|