@zero-library/chat-copilot 1.0.8 → 1.0.10

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/index.d.mts CHANGED
@@ -163,6 +163,7 @@ declare const createChatService: (request: ReturnType<typeof createRequest>, con
163
163
  feedbackUpdate: (params: FeedbackUpdate) => Promise<R<null>>;
164
164
  chatUpload: (agentId: string, data: FormData, conversationId: string, signal?: AbortSignal) => Promise<R<InputFile[]>>;
165
165
  getPreviewUrl: (agentId: string, conversationId: string, path: string) => string;
166
+ docQuery: (params: string) => Promise<R<DocType>>;
166
167
  };
167
168
 
168
169
  type RequestInstance = ReturnType<typeof createChatService>;
@@ -576,7 +577,16 @@ interface PlanEvent {
576
577
  content?: string;
577
578
  plan?: any;
578
579
  }
579
- type MessageEvent = RunStartedEvent | TextEvent | FilesEvent | StepStartedEvent | StepFinishedEvent | StepErrorEvent | RunFinishedEvent | RunStoppedEvent | ConversationNewTitleEvent | ToolCallEvent | ToolResultEvent | RunFailedEvent | A2uiCommandEvent | A2uiSchemaEvent | PlanEvent;
580
+ interface Citation {
581
+ citationId?: string;
582
+ citationUrl?: string;
583
+ citationName?: string;
584
+ }
585
+ interface CitationEvent {
586
+ type: 'citation';
587
+ citations?: Citation[];
588
+ }
589
+ type MessageEvent = RunStartedEvent | TextEvent | FilesEvent | StepStartedEvent | StepFinishedEvent | StepErrorEvent | RunFinishedEvent | RunStoppedEvent | ConversationNewTitleEvent | ToolCallEvent | ToolResultEvent | RunFailedEvent | A2uiCommandEvent | A2uiSchemaEvent | PlanEvent | CitationEvent;
580
590
  /**
581
591
  * 消息类型
582
592
  * 定义智能体和用户之间的消息结构
@@ -1471,6 +1481,25 @@ interface ProviderModel {
1471
1481
  icon?: string;
1472
1482
  models: Model[];
1473
1483
  }
1484
+ /**
1485
+ * 文档类型接口
1486
+ */
1487
+ interface DocType {
1488
+ /** 文档内容 */
1489
+ content: string;
1490
+ /** 文档唯一标识 */
1491
+ docId: string;
1492
+ /** 文档关键字列表 */
1493
+ keywords?: string[];
1494
+ /** 文档位置 */
1495
+ position?: number;
1496
+ /** 文档分段ID */
1497
+ sid?: string;
1498
+ /** 文档令牌数量 */
1499
+ tokens?: number;
1500
+ /** 文档字数 */
1501
+ wordCount?: number;
1502
+ }
1474
1503
 
1475
1504
  /**
1476
1505
  * 附件组件属性接口
package/dist/index.d.ts CHANGED
@@ -163,6 +163,7 @@ declare const createChatService: (request: ReturnType<typeof createRequest>, con
163
163
  feedbackUpdate: (params: FeedbackUpdate) => Promise<R<null>>;
164
164
  chatUpload: (agentId: string, data: FormData, conversationId: string, signal?: AbortSignal) => Promise<R<InputFile[]>>;
165
165
  getPreviewUrl: (agentId: string, conversationId: string, path: string) => string;
166
+ docQuery: (params: string) => Promise<R<DocType>>;
166
167
  };
167
168
 
168
169
  type RequestInstance = ReturnType<typeof createChatService>;
@@ -576,7 +577,16 @@ interface PlanEvent {
576
577
  content?: string;
577
578
  plan?: any;
578
579
  }
579
- type MessageEvent = RunStartedEvent | TextEvent | FilesEvent | StepStartedEvent | StepFinishedEvent | StepErrorEvent | RunFinishedEvent | RunStoppedEvent | ConversationNewTitleEvent | ToolCallEvent | ToolResultEvent | RunFailedEvent | A2uiCommandEvent | A2uiSchemaEvent | PlanEvent;
580
+ interface Citation {
581
+ citationId?: string;
582
+ citationUrl?: string;
583
+ citationName?: string;
584
+ }
585
+ interface CitationEvent {
586
+ type: 'citation';
587
+ citations?: Citation[];
588
+ }
589
+ type MessageEvent = RunStartedEvent | TextEvent | FilesEvent | StepStartedEvent | StepFinishedEvent | StepErrorEvent | RunFinishedEvent | RunStoppedEvent | ConversationNewTitleEvent | ToolCallEvent | ToolResultEvent | RunFailedEvent | A2uiCommandEvent | A2uiSchemaEvent | PlanEvent | CitationEvent;
580
590
  /**
581
591
  * 消息类型
582
592
  * 定义智能体和用户之间的消息结构
@@ -1471,6 +1481,25 @@ interface ProviderModel {
1471
1481
  icon?: string;
1472
1482
  models: Model[];
1473
1483
  }
1484
+ /**
1485
+ * 文档类型接口
1486
+ */
1487
+ interface DocType {
1488
+ /** 文档内容 */
1489
+ content: string;
1490
+ /** 文档唯一标识 */
1491
+ docId: string;
1492
+ /** 文档关键字列表 */
1493
+ keywords?: string[];
1494
+ /** 文档位置 */
1495
+ position?: number;
1496
+ /** 文档分段ID */
1497
+ sid?: string;
1498
+ /** 文档令牌数量 */
1499
+ tokens?: number;
1500
+ /** 文档字数 */
1501
+ wordCount?: number;
1502
+ }
1474
1503
 
1475
1504
  /**
1476
1505
  * 附件组件属性接口
package/dist/index.esm.js CHANGED
@@ -1,7 +1,7 @@
1
- import { CloudUploadOutlined, PaperClipOutlined, LoadingOutlined, createFromIconfontCN, EnterOutlined, DownloadOutlined, CloseOutlined, PlusOutlined, CommentOutlined, FileTextOutlined, CopyOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, RedoOutlined, PlayCircleOutlined, DotChartOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined } from '@ant-design/icons';
2
- import { Attachments, Sender, Think, FileCard, Bubble, XProvider, Conversations, Welcome, Prompts, Mermaid, CodeHighlighter } from '@ant-design/x-v2';
3
- import { useRefState, useDebounce, useSyncInput, createTokenManager, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, isBoolean, UserAvatar, htmlToMarkdown, copyText, deepCopy, transforms, deepMerge, buildUrlParams, createRequest, HttpStatus, isArray, isString, FileIcon, LazyComponent, formatSize, isDef, isNull, transform, emit, getWebSocketUrl, safeParseJson } from '@zero-library/common';
4
- import { App, Badge, Button, Flex, Typography, Tooltip, Tag as Tag$1, Spin, Splitter, theme, Collapse, Avatar, Space, Popover, Form, Empty, Input, InputNumber, Switch as Switch$1, message, List, Skeleton, Alert, Upload, Card, Table, Progress as Progress$1, Divider as Divider$1, Select as Select$1 } from 'antd';
1
+ import { CloudUploadOutlined, PaperClipOutlined, LoadingOutlined, createFromIconfontCN, EnterOutlined, DownloadOutlined, CloseOutlined, PlusOutlined, CommentOutlined, FileTextOutlined, CopyOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, PlayCircleOutlined, DotChartOutlined, RedoOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined } from '@ant-design/icons';
2
+ import { Attachments, Sender, Think, FileCard, Bubble, XProvider, Mermaid, CodeHighlighter, Conversations, Welcome, Prompts } from '@ant-design/x-v2';
3
+ import { useRefState, useDebounce, useSyncInput, createTokenManager, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, isBoolean, UserAvatar, htmlToMarkdown, copyText, FileIcon, LazyComponent, deepCopy, transforms, deepMerge, buildUrlParams, createRequest, HttpStatus, isArray, isString, isExternal, formatSize, isDef, isNull, transform, emit, getWebSocketUrl, safeParseJson } from '@zero-library/common';
4
+ import { App, Badge, Button, Flex, Typography, Tooltip, Tag, Spin, Splitter, theme, Collapse, Avatar, Space, Popover, Form, Skeleton, Alert, Empty, Input, InputNumber, Switch as Switch$1, message, List, Drawer, Upload, Card, Table, Progress as Progress$1, Divider as Divider$1, Select as Select$1 } from 'antd';
5
5
  import React6, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, memo, useState, useContext, useCallback } from 'react';
6
6
  import { useSnapshot, proxy } from 'valtio';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -434,6 +434,9 @@ var createChatService = (request, config) => {
434
434
  const getPreviewUrl = (agentId, conversationId, path) => {
435
435
  return `${config?.baseURL}/agents/${agentId}/${conversationId}/files/download?path=${encodeURIComponent(path)}&${TOKEN_KEY}=${tokenManager.get()}`;
436
436
  };
437
+ const docQuery = (params) => {
438
+ return request.get(`/library/cloud/document?${params}`);
439
+ };
437
440
  return {
438
441
  fetchModelList,
439
442
  fetchAgentInfo,
@@ -447,7 +450,8 @@ var createChatService = (request, config) => {
447
450
  getAgentUserInput,
448
451
  feedbackUpdate,
449
452
  chatUpload,
450
- getPreviewUrl
453
+ getPreviewUrl,
454
+ docQuery
451
455
  };
452
456
  };
453
457
 
@@ -1149,7 +1153,7 @@ function createChatStore() {
1149
1153
  messages.push(finalMsg);
1150
1154
  } else {
1151
1155
  const prevContent = messages[idx]?.content || [];
1152
- messages[idx].content = [...prevContent, newMessage.content[0]];
1156
+ messages[idx].content = [...prevContent, ...newMessage.content];
1153
1157
  }
1154
1158
  conversation.messages[newMessage.conversationId].loading = true;
1155
1159
  break;
@@ -1549,7 +1553,7 @@ function getArtifactFallbackTitle(type) {
1549
1553
  return "\u672A\u547D\u540D\u5185\u5BB9";
1550
1554
  }
1551
1555
  var ArtifactCard = ({ type, title }) => /* @__PURE__ */ jsx(Card, { size: "small", style: { borderRadius: 12 }, children: /* @__PURE__ */ jsxs(Space, { align: "center", wrap: true, children: [
1552
- /* @__PURE__ */ jsx(Tag$1, { color: "blue", children: type }),
1556
+ /* @__PURE__ */ jsx(Tag, { color: "blue", children: type }),
1553
1557
  /* @__PURE__ */ jsx(AText, { strong: true, children: title || getArtifactFallbackTitle(type) })
1554
1558
  ] }) });
1555
1559
  function renderMiniChart(spec, opts) {
@@ -2065,6 +2069,45 @@ var FileView_default = ({ data, loading }) => {
2065
2069
  /* @__PURE__ */ jsx("div", { className: "text-ellipsis", title: data.fileName, children: data.fileName })
2066
2070
  ] }) });
2067
2071
  };
2072
+ var DocDrawer_default = ({ title, open, onClose, paramsStr }) => {
2073
+ const chatStore = useChatStore();
2074
+ const configState = useSnapshot(chatStore.config);
2075
+ const [content, setContent] = useState("");
2076
+ const [loading, setLoading] = useState(false);
2077
+ const getContent = async () => {
2078
+ try {
2079
+ setLoading(true);
2080
+ const res = await configState.services.request.docQuery(paramsStr);
2081
+ setContent(res.data?.content || "");
2082
+ } finally {
2083
+ setLoading(false);
2084
+ }
2085
+ };
2086
+ useEffect(() => {
2087
+ getContent();
2088
+ }, [paramsStr]);
2089
+ return /* @__PURE__ */ jsx(Drawer, { title, push: false, size: "100%", open, onClose, children: /* @__PURE__ */ jsx(Spin, { spinning: loading, children: content ? /* @__PURE__ */ jsx(XMarkdown, { content }) : /* @__PURE__ */ jsx(Empty, { className: "m-t-32" }) }) });
2090
+ };
2091
+ var IndexQuote_default = ({ data, loading, message: message3 }) => {
2092
+ const [open, setOpen] = useState(false);
2093
+ const citation = useMemo(() => {
2094
+ const citations = message3.content?.find((item) => item.type === "citation")?.citations ?? [];
2095
+ return citations?.find((item) => String(item.citationId) === String(data.citationId));
2096
+ }, [data.citationId, message3.content]);
2097
+ const onClick = () => {
2098
+ if (!citation?.citationUrl) return;
2099
+ if (isExternal(citation.citationUrl)) {
2100
+ window.open(citation.citationUrl, "_blank");
2101
+ } else {
2102
+ setOpen(true);
2103
+ }
2104
+ };
2105
+ const Content = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Flex, { align: "center", gap: 8, children: /* @__PURE__ */ jsx("a", { onClick, children: citation?.citationName }) }) });
2106
+ return /* @__PURE__ */ jsxs("div", { className: "inline-block m-l-8", children: [
2107
+ /* @__PURE__ */ jsx(Spin, { spinning: loading, size: "small", children: /* @__PURE__ */ jsx(Popover, { content: Content, children: /* @__PURE__ */ jsx(Tag, { variant: "filled", color: "processing", className: "cursor-pointer", children: data?.citationName }) }) }),
2108
+ open && /* @__PURE__ */ jsx(DocDrawer_default, { paramsStr: citation?.citationUrl, title: citation?.citationName, open, onClose: () => setOpen(false) })
2109
+ ] });
2110
+ };
2068
2111
  var MdEdit_default = ({ data, loading }) => {
2069
2112
  const chatStore = useChatStore();
2070
2113
  const [value, setValue] = useState("");
@@ -2122,11 +2165,15 @@ var PreviewLink_default = ({ data, loading, domNode, ...rest }) => {
2122
2165
  };
2123
2166
  return /* @__PURE__ */ jsx("a", { ...rest, onClick: handleClick, children: data });
2124
2167
  };
2168
+ var Think_default = ({ data }) => {
2169
+ return /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", className: "m-b-16", children: data });
2170
+ };
2125
2171
 
2126
2172
  // src/components/XMarkdown/styles.module.less
2127
2173
  var styles_module_default4 = {
2128
2174
  xMarkdownStyle: "styles_module_xMarkdownStyle"
2129
2175
  };
2176
+ var MARKDOWN_PAYLOAD_PLACEHOLDER_PREFIX = "XMD_PAYLOAD_";
2130
2177
  var singleTildeExtension = {
2131
2178
  name: "singleTilde",
2132
2179
  level: "inline",
@@ -2153,44 +2200,86 @@ var getMarkdownConfig = (options) => {
2153
2200
  breaks: options?.breaks ?? false
2154
2201
  };
2155
2202
  };
2156
- var adaptMarkdownComponent = (Component, message3) => {
2157
- const WrappedComponent = ({ children, streamStatus, ...rest }) => /* @__PURE__ */ jsx(Component, { message: message3, ...rest, data: safeParseJson(children, { repair: true }), loading: streamStatus === "loading" });
2158
- WrappedComponent.displayName = `AdaptedMarkdownComponent(${Component.displayName || Component.name || "Anonymous"})`;
2159
- return WrappedComponent;
2160
- };
2161
- var adaptMarkdownComponents = (components, message3) => Object.fromEntries(Object.entries(components ?? {}).map(([key, Component]) => [key, adaptMarkdownComponent(Component, message3)]));
2203
+ function makeMarkdownPayloadPlaceholder(index) {
2204
+ return `${MARKDOWN_PAYLOAD_PLACEHOLDER_PREFIX}${index}`;
2205
+ }
2206
+ function resolveMappedMarkdownPayload(value, payloadMap) {
2207
+ if (isString(value)) {
2208
+ if (new RegExp(`^${MARKDOWN_PAYLOAD_PLACEHOLDER_PREFIX}\\d+$`).test(value)) {
2209
+ return safeParseJson(payloadMap.get(value), { repair: true });
2210
+ }
2211
+ }
2212
+ return value;
2213
+ }
2162
2214
  function formatMixedContent(content) {
2163
2215
  return content.replace(/<!DOCTYPE html>[\s\S]*?<\/html>/gi, (match) => `\`\`\`html
2164
2216
  ${match}
2165
2217
  \`\`\``);
2166
2218
  }
2167
- var XMarkdown_default = ({ message: message3, components, content, ...rest }) => {
2219
+ function preprocessCustomTagPayloads(content = "", payloadTagPattern) {
2220
+ let id = 0;
2221
+ const payloadMap = /* @__PURE__ */ new Map();
2222
+ const processedContent = content.replace(
2223
+ new RegExp(`(?<opening><(?<tag>${payloadTagPattern})\\b[^>]*>)(?<inner>[\\s\\S]*?)(?<closing><\\/\\k<tag>\\s*>|$)`, "gi"),
2224
+ (match, _opening, _tag, _inner, _closing, _offset, _source, groups) => {
2225
+ const openingText = groups?.opening ?? "";
2226
+ if (!openingText) {
2227
+ return match;
2228
+ }
2229
+ const innerText = groups?.inner ?? "";
2230
+ const closingText = groups?.closing ?? "";
2231
+ const placeholder = makeMarkdownPayloadPlaceholder(id++);
2232
+ payloadMap.set(placeholder, innerText.trim());
2233
+ return `${openingText}${placeholder}${closingText}`;
2234
+ }
2235
+ );
2236
+ return {
2237
+ content: processedContent,
2238
+ payloadMap
2239
+ };
2240
+ }
2241
+ var adaptMarkdownComponent = (Component, payloadMap = /* @__PURE__ */ new Map(), message3) => {
2242
+ const WrappedComponent = ({ children, streamStatus, ...rest }) => {
2243
+ const rawData = resolveMappedMarkdownPayload(children, payloadMap);
2244
+ return /* @__PURE__ */ jsx(Component, { message: message3, ...rest, data: rawData, loading: streamStatus === "loading" });
2245
+ };
2246
+ WrappedComponent.displayName = `AdaptedMarkdownComponent(${Component.displayName || Component.name || "Anonymous"})`;
2247
+ return WrappedComponent;
2248
+ };
2249
+ var adaptMarkdownComponents = (components, payloadMap = /* @__PURE__ */ new Map(), message3) => Object.fromEntries(Object.entries(components ?? {}).map(([key, Component]) => [key, adaptMarkdownComponent(Component, payloadMap, message3)]));
2250
+ var XMarkdown_default = ({ message: message3, components = {}, content = "", ...rest }) => {
2168
2251
  const config = useMemo(() => getMarkdownConfig(), []);
2169
- const markdownComponents = useMemo(
2170
- () => adaptMarkdownComponents(
2171
- {
2172
- code: CodeHighlight_default,
2173
- agentnavigate: AgentNavigate_default,
2174
- a: PreviewLink_default,
2175
- appcard: AppCard_default,
2176
- fileview: FileView_default,
2177
- charts: Charts_default,
2178
- // indexquote: IndexQuote,
2179
- mdedit: MdEdit_default,
2180
- fileedit: FileEdit_default,
2181
- ...components
2182
- },
2183
- message3
2184
- ),
2185
- [components, message3]
2252
+ const formattedContent = useMemo(() => formatMixedContent(content), [content]);
2253
+ const newComponents = useMemo(
2254
+ () => ({
2255
+ think: Think_default,
2256
+ code: CodeHighlight_default,
2257
+ agentnavigate: AgentNavigate_default,
2258
+ a: PreviewLink_default,
2259
+ appcard: AppCard_default,
2260
+ fileview: FileView_default,
2261
+ charts: Charts_default,
2262
+ indexquote: IndexQuote_default,
2263
+ mdedit: MdEdit_default,
2264
+ fileedit: FileEdit_default,
2265
+ ...components
2266
+ }),
2267
+ [components]
2268
+ );
2269
+ const componentKeys = useMemo(() => Object.keys(newComponents), [newComponents]);
2270
+ const payloadTagPattern = useMemo(() => componentKeys.join("|"), [componentKeys]);
2271
+ const { content: processedContent, payloadMap } = useMemo(
2272
+ () => preprocessCustomTagPayloads(formattedContent, payloadTagPattern),
2273
+ [formattedContent, payloadTagPattern]
2186
2274
  );
2275
+ const markdownComponents = useMemo(() => adaptMarkdownComponents(newComponents, payloadMap, message3), [componentKeys, message3, payloadMap]);
2187
2276
  return /* @__PURE__ */ jsx(
2188
2277
  XMarkdown,
2189
2278
  {
2190
2279
  className: classNames2("x-markdown-light", styles_module_default4.xMarkdownStyle),
2191
2280
  config,
2192
2281
  ...rest,
2193
- content: formatMixedContent(content),
2282
+ content: processedContent,
2194
2283
  components: markdownComponents
2195
2284
  }
2196
2285
  );
@@ -2546,7 +2635,7 @@ var Button7 = ({ label, variant = "default", onClick, action, onAction }) => {
2546
2635
  return /* @__PURE__ */ jsx(Button, { type: variant === "primary" ? "primary" : "default", danger: variant === "danger", onClick: handleClick, style: { borderRadius: 8 }, children: label });
2547
2636
  };
2548
2637
  var Divider = () => /* @__PURE__ */ jsx(Divider$1, { style: { margin: "8px 0" } });
2549
- var Tag = ({ text, color }) => /* @__PURE__ */ jsx(Tag$1, { color, children: text });
2638
+ var Tag2 = ({ text, color }) => /* @__PURE__ */ jsx(Tag, { color, children: text });
2550
2639
  var Progress = ({
2551
2640
  percent,
2552
2641
  status = "normal",
@@ -2564,7 +2653,7 @@ var A2uiComponents = {
2564
2653
  Switch,
2565
2654
  Button: Button7,
2566
2655
  Divider,
2567
- Tag,
2656
+ Tag: Tag2,
2568
2657
  Progress,
2569
2658
  ArtifactCard,
2570
2659
  TableViewer,
@@ -4818,7 +4907,7 @@ var ChatPreviewPanel = memo(({ file }) => {
4818
4907
  }
4819
4908
  });
4820
4909
  },
4821
- extraNav: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tag$1, { variant: "filled", color: "default", className: "cursor-pointer", onClick: () => chatStore.setPreview(), children: /* @__PURE__ */ jsx(CloseOutlined, {}) }) })
4910
+ extraNav: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Tag, { variant: "filled", color: "default", className: "cursor-pointer", onClick: () => chatStore.setPreview(), children: /* @__PURE__ */ jsx(CloseOutlined, {}) }) })
4822
4911
  }
4823
4912
  )
4824
4913
  ] });