@ant-design/agentic-ui 2.30.21 → 2.30.22
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/Bubble/MessagesContent/MarkdownPreview.js +6 -5
- package/dist/Bubble/OpenAIMessageBubble/index.d.ts +11 -0
- package/dist/Bubble/OpenAIMessageBubble/index.js +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOllamaMessages.js +136 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.d.ts +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenAIMessages.js +156 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.d.ts +8 -0
- package/dist/Bubble/OpenAIMessageBubble/mapOpenClawMessages.js +127 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.d.ts +16 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOllamaMessages.js +110 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.d.ts +10 -0
- package/dist/Bubble/OpenAIMessageBubble/normalizeOpenClawMessages.js +61 -0
- package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.d.ts +48 -0
- package/dist/Bubble/OpenAIMessageBubble/ollamaTypes.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/openClawTypes.d.ts +27 -0
- package/dist/Bubble/OpenAIMessageBubble/openClawTypes.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/types.d.ts +71 -0
- package/dist/Bubble/OpenAIMessageBubble/types.js +1 -0
- package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/useOllamaMessageBubbleData.js +23 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.d.ts +6 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenAIMessageBubbleData.js +20 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.d.ts +7 -0
- package/dist/Bubble/OpenAIMessageBubble/useOpenClawMessageBubbleData.js +22 -0
- package/dist/Bubble/index.d.ts +2 -0
- package/dist/Bubble/index.js +1 -0
- package/dist/MarkdownEditor/editor/Editor.js +24 -12
- package/dist/MarkdownEditor/editor/elements/Table/SimpleTable.js +5 -1
- package/dist/MarkdownEditor/editor/elements/Table/commands/tableCommands.js +24 -8
- package/dist/MarkdownEditor/editor/elements/index.js +18 -14
- package/dist/MarkdownEditor/editor/store.d.ts +12 -0
- package/dist/MarkdownEditor/editor/store.js +30 -5
- package/dist/MarkdownEditor/editor/tools/InsertAutocomplete.js +15 -11
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts +1 -1
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.js +4 -5
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/index.d.ts +1 -1
- package/dist/MarkdownInputField/AttachmentButton/index.d.ts +1 -1
- package/dist/MarkdownInputField/MarkdownInputField.js +6 -1
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldHandlers.js +6 -2
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.d.ts +1 -0
- package/dist/MarkdownInputField/hooks/useMarkdownInputFieldRefs.js +36 -5
- package/dist/MarkdownInputField/utils/renderHelpers.js +5 -0
- package/dist/MarkdownRenderer/FncRefForMarkdown.d.ts +24 -0
- package/dist/MarkdownRenderer/FncRefForMarkdown.js +65 -0
- package/dist/MarkdownRenderer/MarkdownRenderer.js +24 -9
- package/dist/MarkdownRenderer/extractFootnoteDefinitions.d.ts +13 -0
- package/dist/MarkdownRenderer/extractFootnoteDefinitions.js +40 -0
- package/dist/MarkdownRenderer/markdownReactShared.d.ts +4 -1
- package/dist/MarkdownRenderer/markdownReactShared.js +20 -10
- package/dist/MarkdownRenderer/renderers/CodeRenderer.d.ts +4 -1
- package/dist/MarkdownRenderer/renderers/CodeRenderer.js +27 -3
- package/dist/MarkdownRenderer/renderers/SchemaRenderer.d.ts +2 -0
- package/dist/MarkdownRenderer/renderers/SchemaRenderer.js +33 -5
- package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +2 -1
- package/dist/MarkdownRenderer/types.d.ts +5 -9
- package/dist/MarkdownRenderer/useMarkdownToReact.js +1 -1
- package/dist/Plugins/mermaid/MermaidRendererImpl.js +481 -7
- package/dist/Plugins/mermaid/style.js +71 -22
- package/dist/Plugins/mermaid/useMermaidRender.d.ts +2 -1
- package/dist/Plugins/mermaid/useMermaidRender.js +41 -13
- package/dist/Plugins/mermaid/utils.d.ts +16 -0
- package/dist/Plugins/mermaid/utils.js +197 -5
- package/dist/Workspace/Browser/index.js +19 -1
- package/package.json +8 -7
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
function _object_without_properties(source, excluded) {
|
|
2
|
+
if (source == null) return {};
|
|
3
|
+
var target = {}, sourceKeys, key, i;
|
|
4
|
+
if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
|
|
5
|
+
sourceKeys = Reflect.ownKeys(source);
|
|
6
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
7
|
+
key = sourceKeys[i];
|
|
8
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
9
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
10
|
+
target[key] = source[key];
|
|
11
|
+
}
|
|
12
|
+
return target;
|
|
13
|
+
}
|
|
14
|
+
target = _object_without_properties_loose(source, excluded);
|
|
15
|
+
if (Object.getOwnPropertySymbols) {
|
|
16
|
+
sourceKeys = Object.getOwnPropertySymbols(source);
|
|
17
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
18
|
+
key = sourceKeys[i];
|
|
19
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
20
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
21
|
+
target[key] = source[key];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
function _object_without_properties_loose(source, excluded) {
|
|
27
|
+
if (source == null) return {};
|
|
28
|
+
var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
|
|
29
|
+
for(i = 0; i < sourceKeys.length; i++){
|
|
30
|
+
key = sourceKeys[i];
|
|
31
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
32
|
+
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
33
|
+
target[key] = source[key];
|
|
34
|
+
}
|
|
35
|
+
return target;
|
|
36
|
+
}
|
|
37
|
+
import { extractTextFromContent } from "./mapOpenAIMessages";
|
|
38
|
+
/**
|
|
39
|
+
* 将单条 OpenClaw 风格消息转为可与 {@link mapOpenAIMessagesToMessageBubbleData} 兼容的 OpenAI 形状(`toolResult` → `tool`)。
|
|
40
|
+
*/ export function normalizeOpenClawMessageToOpenAI(msg) {
|
|
41
|
+
if (msg.role === 'toolResult') {
|
|
42
|
+
var m = msg;
|
|
43
|
+
var content = m.content === undefined || m.content === null ? '' : typeof m.content === 'string' ? m.content : extractTextFromContent(m.content);
|
|
44
|
+
return {
|
|
45
|
+
role: 'tool',
|
|
46
|
+
id: m.id,
|
|
47
|
+
name: m.name,
|
|
48
|
+
content: content,
|
|
49
|
+
tool_call_id: m.tool_call_id
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
var _ts = msg.timestamp, rest = _object_without_properties(msg, [
|
|
53
|
+
"timestamp"
|
|
54
|
+
]);
|
|
55
|
+
return rest;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 批量将 OpenClaw transcript 消息转为 OpenAI Chat Completions 兼容结构
|
|
59
|
+
*/ export function normalizeOpenClawMessagesToOpenAI(messages) {
|
|
60
|
+
return messages.map(normalizeOpenClawMessageToOpenAI);
|
|
61
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { OpenAIMessagesMapOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Ollama Chat API 中 ToolCall(见官方 OpenAPI `ToolCall`)
|
|
4
|
+
*/
|
|
5
|
+
export interface OllamaToolCall {
|
|
6
|
+
function?: {
|
|
7
|
+
name: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
arguments?: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
/** 部分实现会带 id */
|
|
12
|
+
id?: string;
|
|
13
|
+
type?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Ollama POST /api/chat 请求体中的单条 `messages[]`(见官方 `ChatMessage`)
|
|
17
|
+
*/
|
|
18
|
+
export interface OllamaChatMessage {
|
|
19
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
20
|
+
/** 流式片段可能为空字符串 */
|
|
21
|
+
content: string;
|
|
22
|
+
/** 客户端为稳定列表 key 可带 id */
|
|
23
|
+
id?: string;
|
|
24
|
+
/** 多模态:base64 图片列表 */
|
|
25
|
+
images?: string[];
|
|
26
|
+
/** assistant 上模型发起的工具调用 */
|
|
27
|
+
tool_calls?: OllamaToolCall[];
|
|
28
|
+
/** `think` 开启时的思考过程(流式或完整响应) */
|
|
29
|
+
thinking?: string;
|
|
30
|
+
/** `role: tool` 时常用,与 OpenAI 的 tool 名称对应 */
|
|
31
|
+
tool_name?: string;
|
|
32
|
+
tool_call_id?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Ollama 映射选项 */
|
|
35
|
+
export interface OllamaMessagesMapOptions extends OpenAIMessagesMapOptions {
|
|
36
|
+
/**
|
|
37
|
+
* 为 true(默认)时,将 `thinking` 拼入展示用正文(映射后的 OpenAI assistant 文本)
|
|
38
|
+
*/
|
|
39
|
+
appendThinkingToContent?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* 为 true(默认)时,若有 `images`,在正文中追加占位说明(不嵌入 base64)
|
|
42
|
+
*/
|
|
43
|
+
appendImagesPlaceholder?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* 为 true(默认)时,在 `extra.ollama.raw` 保留原始 Ollama 消息
|
|
46
|
+
*/
|
|
47
|
+
preserveOllamaRawInExtra?: boolean;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/** Ollama 映射选项 */ export { };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OpenAIChatContentPart, OpenAIChatMessageAssistant, OpenAIChatMessageFunction, OpenAIChatMessageSystem, OpenAIChatMessageTool, OpenAIChatMessageUser, OpenAIMessagesMapOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw 会话 / transcript 常见字段:毫秒时间戳
|
|
4
|
+
*/
|
|
5
|
+
export type OpenClawChatMeta = {
|
|
6
|
+
id?: string;
|
|
7
|
+
timestamp?: number;
|
|
8
|
+
name?: string;
|
|
9
|
+
};
|
|
10
|
+
/** OpenClaw transcript 中工具结果常用 `toolResult`,与 OpenAI 的 `tool` 对应 */
|
|
11
|
+
export interface OpenClawChatMessageToolResult extends OpenClawChatMeta {
|
|
12
|
+
role: 'toolResult';
|
|
13
|
+
content: string | OpenAIChatContentPart[] | null;
|
|
14
|
+
tool_call_id?: string;
|
|
15
|
+
}
|
|
16
|
+
export type OpenClawChatMessage = (OpenAIChatMessageSystem & OpenClawChatMeta) | (OpenAIChatMessageUser & OpenClawChatMeta) | (OpenAIChatMessageAssistant & OpenClawChatMeta) | (OpenAIChatMessageTool & OpenClawChatMeta) | (OpenAIChatMessageFunction & OpenClawChatMeta) | OpenClawChatMessageToolResult;
|
|
17
|
+
/** OpenClaw 映射选项(在 OpenAI 选项基础上增加 transcript 行为) */
|
|
18
|
+
export interface OpenClawMessagesMapOptions extends OpenAIMessagesMapOptions {
|
|
19
|
+
/**
|
|
20
|
+
* 为 true(默认)时,若消息含 `timestamp`(毫秒),写入 `createAt` / `updateAt`
|
|
21
|
+
*/
|
|
22
|
+
useOpenClawTimestamps?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 为 true(默认)时,在 `extra.openclaw.raw` 保留原始 OpenClaw 消息
|
|
25
|
+
*/
|
|
26
|
+
preserveOpenClawRawInExtra?: boolean;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/** OpenClaw 映射选项(在 OpenAI 选项基础上增加 transcript 行为) */ export { };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { MessageBubbleData } from '../../Types/message';
|
|
2
|
+
import type { RoleType } from '../../Types/common';
|
|
3
|
+
/**
|
|
4
|
+
* OpenAI Chat Completions 风格的多段 content(与官方结构兼容,库内自建)
|
|
5
|
+
*/
|
|
6
|
+
export interface OpenAIChatTextPart {
|
|
7
|
+
type: 'text';
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface OpenAIChatRefusalPart {
|
|
11
|
+
type?: 'refusal';
|
|
12
|
+
refusal?: string;
|
|
13
|
+
}
|
|
14
|
+
/** 多模态等其它 part 以弱类型保留 */
|
|
15
|
+
export interface OpenAIChatContentPartFallback {
|
|
16
|
+
type: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export type OpenAIChatContentPart = OpenAIChatTextPart | OpenAIChatRefusalPart | OpenAIChatContentPartFallback;
|
|
20
|
+
export interface OpenAIChatMessageBase {
|
|
21
|
+
id?: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
tool_calls?: unknown[];
|
|
24
|
+
function_call?: {
|
|
25
|
+
name?: string;
|
|
26
|
+
arguments?: string;
|
|
27
|
+
} | null;
|
|
28
|
+
}
|
|
29
|
+
export interface OpenAIChatMessageSystem extends OpenAIChatMessageBase {
|
|
30
|
+
role: 'system';
|
|
31
|
+
content: string | null;
|
|
32
|
+
}
|
|
33
|
+
export interface OpenAIChatMessageUser extends OpenAIChatMessageBase {
|
|
34
|
+
role: 'user';
|
|
35
|
+
content: string | OpenAIChatContentPart[] | null;
|
|
36
|
+
}
|
|
37
|
+
export interface OpenAIChatMessageAssistant extends OpenAIChatMessageBase {
|
|
38
|
+
role: 'assistant';
|
|
39
|
+
content: string | OpenAIChatContentPart[] | null;
|
|
40
|
+
tool_calls?: unknown[];
|
|
41
|
+
function_call?: OpenAIChatMessageBase['function_call'];
|
|
42
|
+
}
|
|
43
|
+
export interface OpenAIChatMessageTool extends OpenAIChatMessageBase {
|
|
44
|
+
role: 'tool';
|
|
45
|
+
content: string | null;
|
|
46
|
+
tool_call_id?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface OpenAIChatMessageFunction extends OpenAIChatMessageBase {
|
|
49
|
+
role: 'function';
|
|
50
|
+
content: string | null;
|
|
51
|
+
name?: string;
|
|
52
|
+
}
|
|
53
|
+
export type OpenAIChatMessage = OpenAIChatMessageSystem | OpenAIChatMessageUser | OpenAIChatMessageAssistant | OpenAIChatMessageTool | OpenAIChatMessageFunction;
|
|
54
|
+
/** 单条映射覆盖 */
|
|
55
|
+
export type OpenAIMessagesMapMessage = (msg: OpenAIChatMessage, index: number, draft: MessageBubbleData) => MessageBubbleData;
|
|
56
|
+
export interface OpenAIMessagesMapOptions {
|
|
57
|
+
/** createAt / updateAt 基准(毫秒) */
|
|
58
|
+
baseTime?: number;
|
|
59
|
+
/** 第 i 条:createAt = baseTime + i * timeStepMs */
|
|
60
|
+
timeStepMs?: number;
|
|
61
|
+
/** 为 true 时最后一条的 updateAt 使用 Date.now()(流式可选) */
|
|
62
|
+
bumpUpdateAtOnLastMessage?: boolean;
|
|
63
|
+
/** 生成 MessageBubbleData.id,默认不用 content,避免 SSE 抖动 */
|
|
64
|
+
getMessageId?: (msg: OpenAIChatMessage, index: number) => string;
|
|
65
|
+
/** tool / function 行映射到的 RoleType */
|
|
66
|
+
toolRoleAs?: RoleType;
|
|
67
|
+
/** assistant 是否将 tool_calls 等拼入展示文案 */
|
|
68
|
+
appendToolCallsToContent?: boolean;
|
|
69
|
+
/** 在 extra.openai 中保留原始 role 与 raw */
|
|
70
|
+
preserveRawInExtra?: boolean;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MessageBubbleData } from '../../Types/message';
|
|
2
|
+
import type { OpenAIMessagesMapMessage } from './types';
|
|
3
|
+
import type { OllamaChatMessage, OllamaMessagesMapOptions } from './ollamaTypes';
|
|
4
|
+
/**
|
|
5
|
+
* 将 Ollama `/api/chat` 的 messages 转为 MessageBubbleData[](与 {@link mapOllamaMessagesToMessageBubbleData} 一致,带 memo)。
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOllamaMessageBubbleData(messages: OllamaChatMessage[], mapOptions?: OllamaMessagesMapOptions, mapMessage?: OpenAIMessagesMapMessage): MessageBubbleData[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { mapOllamaMessagesToMessageBubbleData } from "./mapOllamaMessages";
|
|
3
|
+
/**
|
|
4
|
+
* 将 Ollama `/api/chat` 的 messages 转为 MessageBubbleData[](与 {@link mapOllamaMessagesToMessageBubbleData} 一致,带 memo)。
|
|
5
|
+
*/ export function useOllamaMessageBubbleData(messages, mapOptions, mapMessage) {
|
|
6
|
+
var _ref = mapOptions !== null && mapOptions !== void 0 ? mapOptions : {}, baseTime = _ref.baseTime, timeStepMs = _ref.timeStepMs, bumpUpdateAtOnLastMessage = _ref.bumpUpdateAtOnLastMessage, getMessageId = _ref.getMessageId, toolRoleAs = _ref.toolRoleAs, appendToolCallsToContent = _ref.appendToolCallsToContent, preserveRawInExtra = _ref.preserveRawInExtra, appendThinkingToContent = _ref.appendThinkingToContent, appendImagesPlaceholder = _ref.appendImagesPlaceholder, preserveOllamaRawInExtra = _ref.preserveOllamaRawInExtra;
|
|
7
|
+
return useMemo(function() {
|
|
8
|
+
return mapOllamaMessagesToMessageBubbleData(messages, mapOptions, mapMessage);
|
|
9
|
+
}, [
|
|
10
|
+
messages,
|
|
11
|
+
baseTime,
|
|
12
|
+
timeStepMs,
|
|
13
|
+
bumpUpdateAtOnLastMessage,
|
|
14
|
+
getMessageId,
|
|
15
|
+
toolRoleAs,
|
|
16
|
+
appendToolCallsToContent,
|
|
17
|
+
preserveRawInExtra,
|
|
18
|
+
appendThinkingToContent,
|
|
19
|
+
appendImagesPlaceholder,
|
|
20
|
+
preserveOllamaRawInExtra,
|
|
21
|
+
mapMessage
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { MessageBubbleData } from '../../Types/message';
|
|
2
|
+
import type { OpenAIChatMessage, OpenAIMessagesMapMessage, OpenAIMessagesMapOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 将 OpenAI Chat Completions 风格的 messages 转为 MessageBubbleData[](与 {@link mapOpenAIMessagesToMessageBubbleData} 一致,带 memo)。
|
|
5
|
+
*/
|
|
6
|
+
export declare function useOpenAIMessageBubbleData(messages: OpenAIChatMessage[], mapOptions?: OpenAIMessagesMapOptions, mapMessage?: OpenAIMessagesMapMessage): MessageBubbleData[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { mapOpenAIMessagesToMessageBubbleData } from "./mapOpenAIMessages";
|
|
3
|
+
/**
|
|
4
|
+
* 将 OpenAI Chat Completions 风格的 messages 转为 MessageBubbleData[](与 {@link mapOpenAIMessagesToMessageBubbleData} 一致,带 memo)。
|
|
5
|
+
*/ export function useOpenAIMessageBubbleData(messages, mapOptions, mapMessage) {
|
|
6
|
+
var _ref = mapOptions !== null && mapOptions !== void 0 ? mapOptions : {}, baseTime = _ref.baseTime, timeStepMs = _ref.timeStepMs, bumpUpdateAtOnLastMessage = _ref.bumpUpdateAtOnLastMessage, getMessageId = _ref.getMessageId, toolRoleAs = _ref.toolRoleAs, appendToolCallsToContent = _ref.appendToolCallsToContent, preserveRawInExtra = _ref.preserveRawInExtra;
|
|
7
|
+
return useMemo(function() {
|
|
8
|
+
return mapOpenAIMessagesToMessageBubbleData(messages, mapOptions, mapMessage);
|
|
9
|
+
}, [
|
|
10
|
+
messages,
|
|
11
|
+
baseTime,
|
|
12
|
+
timeStepMs,
|
|
13
|
+
bumpUpdateAtOnLastMessage,
|
|
14
|
+
getMessageId,
|
|
15
|
+
toolRoleAs,
|
|
16
|
+
appendToolCallsToContent,
|
|
17
|
+
preserveRawInExtra,
|
|
18
|
+
mapMessage
|
|
19
|
+
]);
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MessageBubbleData } from '../../Types/message';
|
|
2
|
+
import type { OpenAIMessagesMapMessage } from './types';
|
|
3
|
+
import type { OpenClawChatMessage, OpenClawMessagesMapOptions } from './openClawTypes';
|
|
4
|
+
/**
|
|
5
|
+
* 将 OpenClaw 会话 / transcript 风格的 messages 转为 MessageBubbleData[](与 {@link mapOpenClawMessagesToMessageBubbleData} 一致,带 memo)。
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOpenClawMessageBubbleData(messages: OpenClawChatMessage[], mapOptions?: OpenClawMessagesMapOptions, mapMessage?: OpenAIMessagesMapMessage): MessageBubbleData[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { mapOpenClawMessagesToMessageBubbleData } from "./mapOpenClawMessages";
|
|
3
|
+
/**
|
|
4
|
+
* 将 OpenClaw 会话 / transcript 风格的 messages 转为 MessageBubbleData[](与 {@link mapOpenClawMessagesToMessageBubbleData} 一致,带 memo)。
|
|
5
|
+
*/ export function useOpenClawMessageBubbleData(messages, mapOptions, mapMessage) {
|
|
6
|
+
var _ref = mapOptions !== null && mapOptions !== void 0 ? mapOptions : {}, baseTime = _ref.baseTime, timeStepMs = _ref.timeStepMs, bumpUpdateAtOnLastMessage = _ref.bumpUpdateAtOnLastMessage, getMessageId = _ref.getMessageId, toolRoleAs = _ref.toolRoleAs, appendToolCallsToContent = _ref.appendToolCallsToContent, preserveRawInExtra = _ref.preserveRawInExtra, useOpenClawTimestamps = _ref.useOpenClawTimestamps, preserveOpenClawRawInExtra = _ref.preserveOpenClawRawInExtra;
|
|
7
|
+
return useMemo(function() {
|
|
8
|
+
return mapOpenClawMessagesToMessageBubbleData(messages, mapOptions, mapMessage);
|
|
9
|
+
}, [
|
|
10
|
+
messages,
|
|
11
|
+
baseTime,
|
|
12
|
+
timeStepMs,
|
|
13
|
+
bumpUpdateAtOnLastMessage,
|
|
14
|
+
getMessageId,
|
|
15
|
+
toolRoleAs,
|
|
16
|
+
appendToolCallsToContent,
|
|
17
|
+
preserveRawInExtra,
|
|
18
|
+
useOpenClawTimestamps,
|
|
19
|
+
preserveOpenClawRawInExtra,
|
|
20
|
+
mapMessage
|
|
21
|
+
]);
|
|
22
|
+
}
|
package/dist/Bubble/index.d.ts
CHANGED
package/dist/Bubble/index.js
CHANGED
|
@@ -12,3 +12,4 @@ export * from "./MessagesContent/BubbleContext";
|
|
|
12
12
|
export * from "./type";
|
|
13
13
|
export { UserBubble } from "./UserBubble";
|
|
14
14
|
/** Schema Editor 相关导出 */ export * from "./schema-editor";
|
|
15
|
+
/** OpenAI Chat messages → MessageBubbleData */ export * from "./OpenAIMessageBubble";
|
|
@@ -633,10 +633,14 @@ var defaultAllowedTypes = [
|
|
|
633
633
|
// 2. 检查目标元素是否可编辑,如果不可编辑,则从DOM选区中获取编辑器选区
|
|
634
634
|
if (operationType === 'copy' && !hasEditableTarget(markdownEditorRef.current, event.target)) {
|
|
635
635
|
var domSelection = window.getSelection();
|
|
636
|
-
|
|
636
|
+
if (domSelection) {
|
|
637
|
+
markdownEditorRef.current.selection = getSelectionFromDomSelection(markdownEditorRef.current, domSelection);
|
|
638
|
+
}
|
|
637
639
|
} else if (operationType === 'cut') {
|
|
638
640
|
var domSelection1 = window.getSelection();
|
|
639
|
-
|
|
641
|
+
if (domSelection1) {
|
|
642
|
+
markdownEditorRef.current.selection = getSelectionFromDomSelection(markdownEditorRef.current, domSelection1);
|
|
643
|
+
}
|
|
640
644
|
}
|
|
641
645
|
// 如果无法获取选区,则直接返回
|
|
642
646
|
if (!markdownEditorRef.current.selection) {
|
|
@@ -970,12 +974,16 @@ var defaultAllowedTypes = [
|
|
|
970
974
|
var _markdownEditorRef_current_selection1;
|
|
971
975
|
var node = Node.get(markdownEditorRef.current, ((_markdownEditorRef_current_selection1 = markdownEditorRef.current.selection) === null || _markdownEditorRef_current_selection1 === void 0 ? void 0 : _markdownEditorRef_current_selection1.focus.path) || []);
|
|
972
976
|
if (node) {
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
tagInput
|
|
977
|
+
try {
|
|
978
|
+
var dom = ReactEditor.toDOMNode(markdownEditorRef.current, node);
|
|
979
|
+
if (dom) {
|
|
980
|
+
var tagInput = dom.querySelector('[data-tag-popup-input]');
|
|
981
|
+
if (tagInput) {
|
|
982
|
+
tagInput.setAttribute('data-composition', '');
|
|
983
|
+
}
|
|
978
984
|
}
|
|
985
|
+
} catch (unused) {
|
|
986
|
+
// node may not be mounted yet; ignore
|
|
979
987
|
}
|
|
980
988
|
}
|
|
981
989
|
}
|
|
@@ -1003,12 +1011,16 @@ var defaultAllowedTypes = [
|
|
|
1003
1011
|
var _markdownEditorRef_current_selection1;
|
|
1004
1012
|
var node = Node.get(markdownEditorRef.current, ((_markdownEditorRef_current_selection1 = markdownEditorRef.current.selection) === null || _markdownEditorRef_current_selection1 === void 0 ? void 0 : _markdownEditorRef_current_selection1.focus.path) || []);
|
|
1005
1013
|
if (node) {
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
tagInput
|
|
1014
|
+
try {
|
|
1015
|
+
var dom = ReactEditor.toDOMNode(markdownEditorRef.current, node);
|
|
1016
|
+
if (dom) {
|
|
1017
|
+
var tagInput = dom.querySelector('[data-tag-popup-input]');
|
|
1018
|
+
if (tagInput) {
|
|
1019
|
+
tagInput.removeAttribute('data-composition');
|
|
1020
|
+
}
|
|
1011
1021
|
}
|
|
1022
|
+
} catch (unused) {
|
|
1023
|
+
// node may have been unmounted during composition; ignore
|
|
1012
1024
|
}
|
|
1013
1025
|
}
|
|
1014
1026
|
}
|
|
@@ -64,7 +64,11 @@ import { TablePropsProvider } from "./TableContext";
|
|
|
64
64
|
var baseCls = getPrefixCls('agentic-md-editor-content-table');
|
|
65
65
|
var editor = useSlate();
|
|
66
66
|
var tablePath = useMemo(function() {
|
|
67
|
-
|
|
67
|
+
try {
|
|
68
|
+
return ReactEditor.findPath(editor, props.element);
|
|
69
|
+
} catch (unused) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
68
72
|
}, [
|
|
69
73
|
props.element
|
|
70
74
|
]);
|
|
@@ -114,8 +114,12 @@ function forEachCellPath(editor, tablePath, callback) {
|
|
|
114
114
|
}
|
|
115
115
|
export function clearTableSelection(editor, tablePath) {
|
|
116
116
|
forEachCellPath(editor, tablePath, function(_, cellNode) {
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
try {
|
|
118
|
+
var domNode = ReactEditor.toDOMNode(editor, cellNode);
|
|
119
|
+
domNode === null || domNode === void 0 ? void 0 : domNode.removeAttribute('data-select');
|
|
120
|
+
} catch (unused) {
|
|
121
|
+
// cell may not be mounted yet
|
|
122
|
+
}
|
|
119
123
|
});
|
|
120
124
|
}
|
|
121
125
|
export function selectTableRow(editor, tablePath, rowIndex) {
|
|
@@ -137,8 +141,12 @@ export function selectTableRow(editor, tablePath, rowIndex) {
|
|
|
137
141
|
if (tableCellNode.type !== 'table-cell') {
|
|
138
142
|
continue;
|
|
139
143
|
}
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
try {
|
|
145
|
+
var domNode = ReactEditor.toDOMNode(editor, tableCellNode);
|
|
146
|
+
domNode === null || domNode === void 0 ? void 0 : domNode.setAttribute('data-select', 'true');
|
|
147
|
+
} catch (unused) {
|
|
148
|
+
// cell may not be mounted yet
|
|
149
|
+
}
|
|
142
150
|
}
|
|
143
151
|
}
|
|
144
152
|
export function selectTableColumn(editor, tablePath, columnIndex) {
|
|
@@ -158,14 +166,22 @@ export function selectTableColumn(editor, tablePath, columnIndex) {
|
|
|
158
166
|
if (tableCellNode.type !== 'table-cell') {
|
|
159
167
|
continue;
|
|
160
168
|
}
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
try {
|
|
170
|
+
var domNode = ReactEditor.toDOMNode(editor, tableCellNode);
|
|
171
|
+
domNode === null || domNode === void 0 ? void 0 : domNode.setAttribute('data-select', 'true');
|
|
172
|
+
} catch (unused) {
|
|
173
|
+
// cell may not be mounted yet
|
|
174
|
+
}
|
|
163
175
|
}
|
|
164
176
|
}
|
|
165
177
|
export function selectWholeTable(editor, tablePath) {
|
|
166
178
|
forEachCellPath(editor, tablePath, function(_, cellNode) {
|
|
167
|
-
|
|
168
|
-
|
|
179
|
+
try {
|
|
180
|
+
var domNode = ReactEditor.toDOMNode(editor, cellNode);
|
|
181
|
+
domNode === null || domNode === void 0 ? void 0 : domNode.setAttribute('data-select', 'true');
|
|
182
|
+
} catch (unused) {
|
|
183
|
+
// cell may not be mounted yet
|
|
184
|
+
}
|
|
169
185
|
});
|
|
170
186
|
}
|
|
171
187
|
export function removeTableRow(editor, tablePath, rowIndex) {
|
|
@@ -387,20 +387,24 @@ var MLeafComponent = function MLeafComponent(props) {
|
|
|
387
387
|
setTimeout(function() {
|
|
388
388
|
if (!markdownEditorRef.current) return;
|
|
389
389
|
if (!(path === null || path === void 0 ? void 0 : path.length)) return;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
390
|
+
try {
|
|
391
|
+
var nextPath = Path.next(path);
|
|
392
|
+
if (!Editor.hasPath(markdownEditorRef.current, nextPath)) {
|
|
393
|
+
Transforms.insertNodes(markdownEditorRef.current, [
|
|
394
|
+
{
|
|
395
|
+
text: ' '
|
|
396
|
+
}
|
|
397
|
+
], {
|
|
398
|
+
select: true
|
|
399
|
+
});
|
|
400
|
+
} else {
|
|
401
|
+
Transforms.select(markdownEditorRef.current, {
|
|
402
|
+
anchor: Editor.end(markdownEditorRef.current, path),
|
|
403
|
+
focus: Editor.end(markdownEditorRef.current, path)
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
} catch (unused) {
|
|
407
|
+
// path may have become stale after the timeout; ignore
|
|
404
408
|
}
|
|
405
409
|
}, 0);
|
|
406
410
|
},
|
|
@@ -203,6 +203,18 @@ export declare class EditorStore {
|
|
|
203
203
|
* 取消当前正在进行的 setMDContent 操作
|
|
204
204
|
*/
|
|
205
205
|
cancelSetMDContent(): void;
|
|
206
|
+
/**
|
|
207
|
+
* 安全地取消编辑器选区。
|
|
208
|
+
*
|
|
209
|
+
* ReactEditor.deselect() 内部调用 window.getSelection().removeAllRanges(),
|
|
210
|
+
* 当编辑器处于聚焦状态时,浏览器要求必须存在活跃选区才能操作,
|
|
211
|
+
* 否则抛出 InvalidStateError("Failed to execute 'collapseToEnd' on 'Selection'")。
|
|
212
|
+
*
|
|
213
|
+
* 双重防御策略:
|
|
214
|
+
* 1. isFocused 检查 —— 大多数情况下直接跳过(性能优先)
|
|
215
|
+
* 2. try-catch —— 覆盖 isFocused 与 deselect 之间的竞态窗口
|
|
216
|
+
*/
|
|
217
|
+
private _safeDeselect;
|
|
206
218
|
/**
|
|
207
219
|
* 使用 requestAnimationFrame 分批解析和设置内容
|
|
208
220
|
* 边解析边插入,实时显示内容
|
|
@@ -237,9 +237,13 @@ export var EditorStoreContext = createContext(null);
|
|
|
237
237
|
value: function focus() {
|
|
238
238
|
var editor = this._editor.current;
|
|
239
239
|
try {
|
|
240
|
-
// 1.
|
|
240
|
+
// 1. 确保编辑器获得焦点(异步,需要单独 try-catch 防止白屏)
|
|
241
241
|
setTimeout(function() {
|
|
242
|
-
|
|
242
|
+
try {
|
|
243
|
+
ReactEditor.focus(editor);
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.error('ReactEditor.focus 失败:', e);
|
|
246
|
+
}
|
|
243
247
|
}, 0);
|
|
244
248
|
// 2. 处理空文档情况
|
|
245
249
|
if (editor.children.length === 0) {
|
|
@@ -476,7 +480,7 @@ export var EditorStoreContext = createContext(null);
|
|
|
476
480
|
var nodeList = parserMdToSchema(md, plugins).schema;
|
|
477
481
|
this.setContent(nodeList);
|
|
478
482
|
this._editor.current.children = nodeList;
|
|
479
|
-
|
|
483
|
+
this._safeDeselect();
|
|
480
484
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress(1);
|
|
481
485
|
} catch (error) {
|
|
482
486
|
console.error('Failed to set MD content:', error);
|
|
@@ -494,7 +498,7 @@ export var EditorStoreContext = createContext(null);
|
|
|
494
498
|
if (allNodes.length > 0) {
|
|
495
499
|
this.setContent(allNodes);
|
|
496
500
|
this._editor.current.children = allNodes;
|
|
497
|
-
|
|
501
|
+
this._safeDeselect();
|
|
498
502
|
}
|
|
499
503
|
onProgress === null || onProgress === void 0 ? void 0 : onProgress(1);
|
|
500
504
|
} catch (error) {
|
|
@@ -547,6 +551,27 @@ export var EditorStoreContext = createContext(null);
|
|
|
547
551
|
}
|
|
548
552
|
}
|
|
549
553
|
},
|
|
554
|
+
{
|
|
555
|
+
key: "_safeDeselect",
|
|
556
|
+
value: /**
|
|
557
|
+
* 安全地取消编辑器选区。
|
|
558
|
+
*
|
|
559
|
+
* ReactEditor.deselect() 内部调用 window.getSelection().removeAllRanges(),
|
|
560
|
+
* 当编辑器处于聚焦状态时,浏览器要求必须存在活跃选区才能操作,
|
|
561
|
+
* 否则抛出 InvalidStateError("Failed to execute 'collapseToEnd' on 'Selection'")。
|
|
562
|
+
*
|
|
563
|
+
* 双重防御策略:
|
|
564
|
+
* 1. isFocused 检查 —— 大多数情况下直接跳过(性能优先)
|
|
565
|
+
* 2. try-catch —— 覆盖 isFocused 与 deselect 之间的竞态窗口
|
|
566
|
+
*/ function _safeDeselect() {
|
|
567
|
+
if (ReactEditor.isFocused(this._editor.current)) return;
|
|
568
|
+
try {
|
|
569
|
+
ReactEditor.deselect(this._editor.current);
|
|
570
|
+
} catch (unused) {
|
|
571
|
+
// InvalidStateError:编辑器在 isFocused 检查与 deselect 调用之间获得了焦点,忽略即可
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
},
|
|
550
575
|
{
|
|
551
576
|
key: "_parseAndSetContentWithRAF",
|
|
552
577
|
value: /**
|
|
@@ -634,7 +659,7 @@ export var EditorStoreContext = createContext(null);
|
|
|
634
659
|
rafId = requestAnimationFrame(parseAndInsertNextBatch);
|
|
635
660
|
} else {
|
|
636
661
|
// 所有内容处理完成
|
|
637
|
-
|
|
662
|
+
_this._safeDeselect();
|
|
638
663
|
rafId = null;
|
|
639
664
|
_this._currentAbortController = null;
|
|
640
665
|
resolve();
|
|
@@ -936,18 +936,22 @@ export var InsertAutocomplete = function InsertAutocomplete(props) {
|
|
|
936
936
|
isTop: EditorUtils.isTop(markdownEditorRef.current, node[1])
|
|
937
937
|
};
|
|
938
938
|
if ((node === null || node === void 0 ? void 0 : (_node_ = node[0]) === null || _node_ === void 0 ? void 0 : _node_.type) === 'paragraph') {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
939
|
+
try {
|
|
940
|
+
var el = ReactEditor.toDOMNode(markdownEditorRef.current, node[0]);
|
|
941
|
+
if (el) {
|
|
942
|
+
var position = calculatePosition(el, document.body);
|
|
943
|
+
if (position) {
|
|
944
|
+
setState(position);
|
|
945
|
+
} else {
|
|
946
|
+
setState({
|
|
947
|
+
top: 0,
|
|
948
|
+
left: 0,
|
|
949
|
+
bottom: undefined
|
|
950
|
+
});
|
|
951
|
+
}
|
|
950
952
|
}
|
|
953
|
+
} catch (unused) {
|
|
954
|
+
// node may not be mounted yet; position update skipped
|
|
951
955
|
}
|
|
952
956
|
}
|
|
953
957
|
setupEventListeners();
|
package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileListItem.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { AttachmentFile } from '../types';
|
|
|
3
3
|
interface FileListItemProps {
|
|
4
4
|
file: AttachmentFile;
|
|
5
5
|
onDelete: (file: AttachmentFile) => void;
|
|
6
|
-
onPreview?: (file: AttachmentFile) => void
|
|
6
|
+
onPreview?: (file: AttachmentFile) => void | Promise<void>;
|
|
7
7
|
onDownload?: (file: AttachmentFile) => void;
|
|
8
8
|
onRetry?: (file: AttachmentFile) => void;
|
|
9
9
|
className?: string;
|