@tablestore/tablestore-agent-cli 0.1.7 → 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.
Files changed (153) hide show
  1. package/dist/dashboard-runtime/dashboard/.next/BUILD_ID +1 -1
  2. package/dist/dashboard-runtime/dashboard/.next/build-manifest.json +3 -3
  3. package/dist/dashboard-runtime/dashboard/.next/prerender-manifest.json +3 -3
  4. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  5. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  6. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/documents/page.js.nft.json +1 -1
  7. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/documents/page_client-reference-manifest.js +1 -1
  8. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/page.js.nft.json +1 -1
  9. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/page_client-reference-manifest.js +1 -1
  10. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/qa/page.js.nft.json +1 -1
  11. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/qa/page_client-reference-manifest.js +1 -1
  12. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/retrieval/page.js.nft.json +1 -1
  13. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/retrieval/page_client-reference-manifest.js +1 -1
  14. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/settings/page.js.nft.json +1 -1
  15. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/[name]/settings/page_client-reference-manifest.js +1 -1
  16. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/create/page_client-reference-manifest.js +1 -1
  17. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/page.js.nft.json +1 -1
  18. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/knowledge-base/page_client-reference-manifest.js +1 -1
  19. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/[id]/page_client-reference-manifest.js +1 -1
  20. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/new/page_client-reference-manifest.js +1 -1
  21. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/page.js.nft.json +1 -1
  22. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  23. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/messages/page.js.nft.json +1 -1
  24. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/messages/page_client-reference-manifest.js +1 -1
  25. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/page.js.nft.json +1 -1
  26. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/page_client-reference-manifest.js +1 -1
  27. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/requests/page.js.nft.json +1 -1
  28. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/requests/page_client-reference-manifest.js +1 -1
  29. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/search/page.js.nft.json +1 -1
  30. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/search/page_client-reference-manifest.js +1 -1
  31. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/settings/page.js.nft.json +1 -1
  32. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/settings/page_client-reference-manifest.js +1 -1
  33. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/units/page.js.nft.json +1 -1
  34. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/[store]/units/page_client-reference-manifest.js +1 -1
  35. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/create/page_client-reference-manifest.js +1 -1
  36. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/page.js.nft.json +1 -1
  37. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/memory/page_client-reference-manifest.js +1 -1
  38. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  39. package/dist/dashboard-runtime/dashboard/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  40. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.html +1 -1
  41. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.rsc +1 -1
  42. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  43. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  44. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  45. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  46. package/dist/dashboard-runtime/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  47. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  48. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.html +1 -1
  49. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.rsc +2 -2
  50. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  51. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  52. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  53. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  54. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  55. package/dist/dashboard-runtime/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  56. package/dist/dashboard-runtime/dashboard/.next/server/app/api/v1/knowledge-bases/[name]/documents/upload/route.js.nft.json +1 -1
  57. package/dist/dashboard-runtime/dashboard/.next/server/app/index.html +1 -1
  58. package/dist/dashboard-runtime/dashboard/.next/server/app/index.rsc +2 -2
  59. package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  60. package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_full.segment.rsc +2 -2
  61. package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  62. package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
  63. package/dist/dashboard-runtime/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  64. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  65. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.html +1 -1
  66. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.rsc +3 -3
  67. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_full.segment.rsc +3 -3
  68. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  69. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_index.segment.rsc +2 -2
  70. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/_tree.segment.rsc +2 -2
  71. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +2 -2
  72. package/dist/dashboard-runtime/dashboard/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  73. package/dist/dashboard-runtime/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  74. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/0b1r_app_(dashboard)_knowledge-base_[name]_documents_documents-client_tsx_0g2uxmt._.js +1 -1
  75. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__09_30hi._.js +3 -0
  76. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0kaiok7._.js +3 -0
  77. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0l937k4._.js +3 -0
  78. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0-dlo4s._.js +1 -1
  79. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_01pp~xx._.js +3 -0
  80. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0476v7r._.js → _08j6p-z._.js} +2 -2
  81. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0ct0n55._.js → _09eom0_._.js} +2 -2
  82. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0mzxmfh._.js → _0f-may2._.js} +2 -2
  83. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0fp_nnb._.js +3 -0
  84. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0l6jz-5._.js +3 -0
  85. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/{_0fg6iap._.js → _0ntv66s._.js} +2 -2
  86. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0sc0tpz._.js +3 -0
  87. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0tyxwr3._.js +3 -0
  88. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0u9md36._.js +1 -1
  89. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/dashboard_src_065m1.j._.js +1 -1
  90. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/dashboard_src_app_(dashboard)_knowledge-base_[name]_layout-client_tsx_05momc5._.js +1 -1
  91. package/dist/dashboard-runtime/dashboard/.next/server/middleware-build-manifest.js +3 -3
  92. package/dist/dashboard-runtime/dashboard/.next/server/pages/404.html +1 -1
  93. package/dist/dashboard-runtime/dashboard/.next/server/pages/500.html +1 -1
  94. package/dist/dashboard-runtime/dashboard/.next/server/server-reference-manifest.js +1 -1
  95. package/dist/dashboard-runtime/dashboard/.next/server/server-reference-manifest.json +1 -1
  96. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0-xqk6wfme5fu.js +1 -0
  97. package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0jeb9kxtd_jq..js → 00.fyg_t3xjc~.js} +1 -1
  98. package/dist/dashboard-runtime/dashboard/.next/static/chunks/01k-.wkndubwy.js +138 -0
  99. package/dist/dashboard-runtime/dashboard/.next/static/chunks/07r22x5uhjxjb.js +1 -0
  100. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0cbu3udngtx-v.js +4 -0
  101. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0h7d69g2fdgs6.js +138 -0
  102. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0iv0g360z0ja5.js +1 -0
  103. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0jf4ytf.izmzh.js +1 -0
  104. package/dist/dashboard-runtime/dashboard/.next/static/chunks/{17nx_vdk_qemm.js → 0m42mmyxmgn-i.js} +1 -1
  105. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0odz1whf-ozqn.css +1 -0
  106. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0ouxv_2qvf6.9.js +1 -0
  107. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0rbkgj._oqsb3.js +1 -0
  108. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0u6u.649ou67b.js +1 -0
  109. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0vf7~eysvh9bq.js +1 -0
  110. package/dist/dashboard-runtime/dashboard/.next/static/chunks/{09qsmnfvk8dm3.js → 0wmaq.ay~r2sn.js} +1 -1
  111. package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0i5aqiffpm9jr.js → 0xb0_9t-vmo6e.js} +1 -1
  112. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0yp_2ea75d19v.js +1 -0
  113. package/dist/dashboard-runtime/dashboard/.next/static/chunks/{0s3mvx9_dr13c.js → 11cizim1aug~b.js} +1 -1
  114. package/dist/dashboard-runtime/dashboard/.next/static/chunks/13-2ei295hl0-.js +1 -0
  115. package/dist/dashboard-runtime/dashboard/src/app/(dashboard)/knowledge-base/[name]/qa/page.tsx +23 -1
  116. package/dist/dashboard-runtime/dashboard/src/components/documents/doc-upload-dialog.tsx +370 -91
  117. package/dist/dashboard-runtime/dashboard/src/components/knowledge-base/kb-card.tsx +8 -5
  118. package/dist/dashboard-runtime/dashboard/src/components/knowledge-base/kb-header.tsx +18 -10
  119. package/dist/dashboard-runtime/dashboard/src/components/memory/memory-header.tsx +8 -12
  120. package/dist/dashboard-runtime/dashboard/src/components/qa/qa-chat-panel.tsx +45 -4
  121. package/dist/dashboard-runtime/dashboard/src/components/qa/qa-message.tsx +636 -36
  122. package/dist/dashboard-runtime/dashboard/src/components/shared/confirm-dialog.tsx +8 -1
  123. package/dist/dashboard-runtime/dashboard/src/components/shared/refresh-button.tsx +102 -86
  124. package/dist/dashboard-runtime/dashboard/src/hooks/use-qa-chat.ts +261 -58
  125. package/dist/dashboard-runtime/dashboard/src/lib/chat-message-ops.ts +76 -0
  126. package/dist/dashboard-runtime/dashboard/src/lib/dev-flags.ts +24 -0
  127. package/dist/dashboard-runtime/dashboard/src/types/llm-chat.ts +19 -0
  128. package/package.json +1 -1
  129. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0i0y9.r._.js +0 -3
  130. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0r_6wpx._.js +0 -3
  131. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/[root-of-the-server]__0y8rrcu._.js +0 -3
  132. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_02e0c00._.js +0 -3
  133. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0doczxg._.js +0 -3
  134. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0e9y.xc._.js +0 -3
  135. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0ti~om_._.js +0 -3
  136. package/dist/dashboard-runtime/dashboard/.next/server/chunks/ssr/_0~s~e-0._.js +0 -3
  137. package/dist/dashboard-runtime/dashboard/.next/static/chunks/055_bo6_3nt-s.js +0 -1
  138. package/dist/dashboard-runtime/dashboard/.next/static/chunks/07l4dodn5t6l4.js +0 -4
  139. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0a5ass8u78k90.js +0 -1
  140. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0j~63ld9lbb25.js +0 -1
  141. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0l6znnjqw.4yw.js +0 -1
  142. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0o-c2g8y5pw-c.js +0 -1
  143. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0o0i2ke2jbdvq.js +0 -138
  144. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0u2lo2lzizxy_.js +0 -1
  145. package/dist/dashboard-runtime/dashboard/.next/static/chunks/0v.hno.6q74nn.css +0 -1
  146. package/dist/dashboard-runtime/dashboard/.next/static/chunks/100.ax5hitxko.js +0 -1
  147. package/dist/dashboard-runtime/dashboard/.next/static/chunks/14ti2gx~1fiub.js +0 -1
  148. package/dist/dashboard-runtime/dashboard/.next/static/chunks/14vqmdm7sosj2.js +0 -1
  149. package/dist/dashboard-runtime/dashboard/.next/static/chunks/17h~onnkksf44.js +0 -138
  150. package/dist/dashboard-runtime/dashboard/.next/static/chunks/186jubvt5xyuj.js +0 -1
  151. /package/dist/dashboard-runtime/dashboard/.next/static/{wWmSSYUu4w4mIF1R_7UoM → BGnMIk4OPjFx_qvLFMTBc}/_buildManifest.js +0 -0
  152. /package/dist/dashboard-runtime/dashboard/.next/static/{wWmSSYUu4w4mIF1R_7UoM → BGnMIk4OPjFx_qvLFMTBc}/_clientMiddlewareManifest.js +0 -0
  153. /package/dist/dashboard-runtime/dashboard/.next/static/{wWmSSYUu4w4mIF1R_7UoM → 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 type { ChatMessage, ChatRequestBody } from "@/types/llm-chat";
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
- const send = useCallback(
147
- async (userInput: string) => {
148
- const trimmed = userInput.trim();
149
- if (!trimmed || isStreamingRef.current) return;
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; surface the original query without the
211
- // "rewritten" badge so the UI stays quiet.
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
- updateAssistant({
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
- updateAssistant({ status: "done" });
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"; do not treat
252
- // it as a hard failure. Either way, drain any buffered deltas so
253
- // the partial answer is preserved on screen.
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({ status: "error", errorMessage: message });
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. Using the functional
269
- // setter avoids racing with the in-flight closure: we observe whatever
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tablestore/tablestore-agent-cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "main": "./dist/main.js",
6
6
  "bin": {
@@ -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
@@ -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