@blade-hq/agent-react 2612.0.0-beta.3 → 2612.0.0-beta.5
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/README.md +10 -0
- package/dist/chat/customization.d.ts +1 -1
- package/dist/chat/runtime/actions.d.ts +1 -0
- package/dist/chat/runtime/composer-channels.d.ts +4 -0
- package/dist/{chunk-WCMGQJLE.js → chunk-7IPINZHT.js} +2 -2
- package/dist/{chunk-5J54S5BK.js → chunk-T5WGKZN4.js} +106 -3
- package/dist/chunk-T5WGKZN4.js.map +1 -0
- package/dist/{chunk-FQQJP2GJ.js → chunk-XULCQP3Q.js} +22 -6
- package/dist/{chunk-FQQJP2GJ.js.map → chunk-XULCQP3Q.js.map} +1 -1
- package/dist/components/TopicAssetSubmitDialog.d.ts +14 -0
- package/dist/embed/entry.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -4
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +7 -3
- package/dist/internal.js.map +1 -1
- package/dist/rich-input/FileCompletionMenu.d.ts +3 -2
- package/dist/rich-input/extensions/topic-asset-mention.d.ts +13 -0
- package/dist/rich-input/index.d.ts +2 -0
- package/dist/rich-input/lib/composer-content.d.ts +6 -1
- package/dist/rich-input/lib/topic-asset-suggestions.d.ts +6 -0
- package/dist/rich-input/use-input-history.d.ts +3 -1
- package/dist/rich-input.js +5689 -5529
- package/dist/rich-input.js.map +1 -1
- package/dist/style.full.css +1 -1
- package/package.json +2 -2
- package/public-api.md +23 -1
- package/dist/chunk-5J54S5BK.js.map +0 -1
- /package/dist/{chunk-WCMGQJLE.js.map → chunk-7IPINZHT.js.map} +0 -0
package/README.md
CHANGED
|
@@ -471,3 +471,13 @@ blade-chat::part(input-toolbar) { gap: 12px; }
|
|
|
471
471
|
完整签名见 [public-api.md](./public-api.md)。本包公开声明:`BladeProvider`、`BladeProviderProps`、`BladeHost`、`HostAttachment`、`HostCatalogItem`、`useBladeClient`、`useAgentSession`、`UseAgentSessionOptions`、`UseAgentSessionResult`、`useReplay`、`UseReplayResult`、`ReplayMismatch`、`ReplayBar`、`ReplayBarProps`、`ReplayMismatchPrompt`、`ReplayMismatchPromptProps`、`ChatView`、`ChatViewProps`、`ChatViewClassNames`、`ChatViewRenderers`、`ChatViewSlots`、`UserMessageRendererProps`、`AssistantTextRendererProps`、`AskUserQuestionRendererProps`、`AskUserQuestionData`、`PlanUpdateRendererProps`、`PlanUpdateData`、`PlanStepStatus`、`ToolCallRenderer`、`ToolRendererProps`、`FollowupInteractionEvent`、`LlmChatHandle`、`LlmChatOptions`、`ChatCompletionTool`、`LlmToolCall`、`MarkdownContent`、`MarkdownContentProps`。
|
|
472
472
|
|
|
473
473
|
`@blade-hq/agent-client` 不再从本包转出,`BladeClient`、`AgentSession` 等直接从 `@blade-hq/agent-client` import。
|
|
474
|
+
|
|
475
|
+
## 主题资产 @
|
|
476
|
+
|
|
477
|
+
主题资产候选通过当前主题的资产列表获取,使用专用 `TopicAssetMention` 药丸;没有关联主题时不展示候选。首页与会话输入框复用候选查询、引用序列化和展示结构。
|
|
478
|
+
|
|
479
|
+
`queueTopicAssetReference(sessionId, { topic_id, path })`(`@blade-hq/agent-react/rich-input`)可在导航到当前用户的同主题会话前预填引用。发送只携带引用身份,元数据和权限由服务端重新判断;本轮续跑保留引用,下一条消息默认不继承。
|
|
480
|
+
|
|
481
|
+
会话文件树可通过宿主提供的提交动作显示“提交到资产”;只读或未关联主题时不显示写入口,服务端仍会独立检查权限。
|
|
482
|
+
|
|
483
|
+
文件提交共享组件:`TopicAssetSubmitDialog`(属性 `TopicAssetSubmitDialogProps`)提供目录选择和提交说明;`useTopicAssetSubmissionAccess` 查询当前会话的主题及写权限。二者用于宿主文件树接入,不能替代服务端鉴权。
|
|
@@ -30,7 +30,7 @@ export type ChatViewClassNames = Partial<{
|
|
|
30
30
|
skillStatusBarInner: string;
|
|
31
31
|
}>;
|
|
32
32
|
/** 输入框提交时的附加项(模型、推理档位、知识库等由富输入给出)。 */
|
|
33
|
-
export interface ChatSendOptions extends Pick<ChatSendExtras, "thinkingOverride" | "reasoningLevel" | "kbIds" | "queueWhenRunning"> {
|
|
33
|
+
export interface ChatSendOptions extends Pick<ChatSendExtras, "thinkingOverride" | "reasoningLevel" | "kbIds" | "topicAssetRefs" | "queueWhenRunning"> {
|
|
34
34
|
/** 附件实际上传到的会话(首页新建会话时由输入框给出)。 */
|
|
35
35
|
targetSessionId?: string;
|
|
36
36
|
/** 本条消息用的模型;null 表示沿用会话已保存的模型。 */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type TopicAssetRef } from "@blade-hq/agent-client";
|
|
1
2
|
export interface PendingContextSignal {
|
|
2
3
|
id: string;
|
|
3
4
|
label: string;
|
|
@@ -13,6 +14,7 @@ export interface SendRequestSignal {
|
|
|
13
14
|
id: string;
|
|
14
15
|
}
|
|
15
16
|
export interface ComposerChannelsState {
|
|
17
|
+
topicAssetReferences: Record<string, TopicAssetRef[]>;
|
|
16
18
|
pendingContexts: Record<string, PendingContextSignal[]>;
|
|
17
19
|
draftAppends: Record<string, DraftAppendSignal[]>;
|
|
18
20
|
sendRequests: Record<string, SendRequestSignal[]>;
|
|
@@ -21,6 +23,8 @@ export interface ComposerChannelsState {
|
|
|
21
23
|
}
|
|
22
24
|
export declare const composerChannels: {
|
|
23
25
|
getState: () => ComposerChannelsState;
|
|
26
|
+
addTopicAssetReference(sessionId: string, ref: TopicAssetRef): void;
|
|
27
|
+
consumeTopicAssetReferences: (sessionId: string) => TopicAssetRef[];
|
|
24
28
|
subscribe(listener: () => void): () => void;
|
|
25
29
|
addPendingContext(sessionId: string, context: Omit<PendingContextSignal, "id">): void;
|
|
26
30
|
removePendingContext(sessionId: string, contextId: string): void;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
catalogToConnectorItems,
|
|
7
7
|
filterConnectorItems,
|
|
8
8
|
useSessionPluginActivation
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XULCQP3Q.js";
|
|
10
10
|
|
|
11
11
|
// src/components/connector-panel-types.ts
|
|
12
12
|
function selectionFromItem(item) {
|
|
@@ -255,4 +255,4 @@ export {
|
|
|
255
255
|
ConnectorPanel,
|
|
256
256
|
PluginTriggerStack
|
|
257
257
|
};
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
258
|
+
//# sourceMappingURL=chunk-7IPINZHT.js.map
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
Dialog,
|
|
25
25
|
DialogClose,
|
|
26
26
|
DialogContent,
|
|
27
|
+
DialogDescription,
|
|
27
28
|
DialogTitle,
|
|
28
29
|
Download,
|
|
29
30
|
Earth,
|
|
@@ -120,7 +121,7 @@ import {
|
|
|
120
121
|
useSessionSource,
|
|
121
122
|
useSessionState,
|
|
122
123
|
useSingleSessionSource
|
|
123
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-XULCQP3Q.js";
|
|
124
125
|
import {
|
|
125
126
|
__export
|
|
126
127
|
} from "./chunk-PR4QN5HX.js";
|
|
@@ -38728,9 +38729,14 @@ function UserMessageBubble({ message, className }) {
|
|
|
38728
38729
|
contexts: textContexts
|
|
38729
38730
|
} = extractTextAttachments(message.content);
|
|
38730
38731
|
const trimmedClean = cleanText.trim();
|
|
38732
|
+
const topicAssetPills = message.topic_asset_refs?.length ? /* @__PURE__ */ jsx34("div", { className: "flex max-w-full flex-wrap justify-end gap-1.5", "aria-label": "\u5F15\u7528\u7684\u4E3B\u9898\u8D44\u4EA7", children: message.topic_asset_refs.map((ref) => /* @__PURE__ */ jsxs29("span", { title: ref.path, className: "max-w-full truncate rounded-full border border-border bg-muted px-2.5 py-1 text-xs text-foreground", children: [
|
|
38733
|
+
"\u4E3B\u9898\u8D44\u4EA7 \xB7 ",
|
|
38734
|
+
ref.path
|
|
38735
|
+
] }, `${ref.topic_id}:${ref.path}`)) }) : null;
|
|
38731
38736
|
const whatifParsed = trimmedClean && imageParts.length === 0 && fileParts.length === 0 && textAttachments.length === 0 ? parseWhatIfPrompt(cleanText) : null;
|
|
38732
38737
|
if (whatifParsed && customBubble == null) {
|
|
38733
38738
|
return /* @__PURE__ */ jsx34("div", { part: "user-row", className: "blade-chat-user-row flex justify-end", children: /* @__PURE__ */ jsxs29("div", { className: "blade-chat-user-col group flex max-w-[72%] flex-col items-end gap-2", children: [
|
|
38739
|
+
topicAssetPills,
|
|
38734
38740
|
/* @__PURE__ */ jsx34(WhatIfUserBubble, { parsed: whatifParsed }),
|
|
38735
38741
|
whatifParsed.userText && /* @__PURE__ */ jsx34(
|
|
38736
38742
|
MessageActions,
|
|
@@ -38866,6 +38872,7 @@ function UserMessageBubble({ message, className }) {
|
|
|
38866
38872
|
}
|
|
38867
38873
|
),
|
|
38868
38874
|
/* @__PURE__ */ jsx34(MessageContextPills, { contexts: textContexts }),
|
|
38875
|
+
topicAssetPills,
|
|
38869
38876
|
trimmedClean && // 原型:不对称圆角(指向发送侧的一角收窄),无边框、无内阴影。
|
|
38870
38877
|
(customBubble != null ? customBubble : /* @__PURE__ */ jsx34(
|
|
38871
38878
|
"div",
|
|
@@ -48240,6 +48247,7 @@ function ChatPanel({
|
|
|
48240
48247
|
thinkingOverride: options?.thinkingOverride,
|
|
48241
48248
|
reasoningLevel: options?.reasoningLevel,
|
|
48242
48249
|
kbIds: options?.kbIds,
|
|
48250
|
+
topicAssetRefs: options?.topicAssetRefs,
|
|
48243
48251
|
queueWhenRunning: options?.queueWhenRunning
|
|
48244
48252
|
});
|
|
48245
48253
|
},
|
|
@@ -49291,6 +49299,99 @@ function ChatView(props) {
|
|
|
49291
49299
|
return /* @__PURE__ */ jsx54(AgentChat, { ...rest });
|
|
49292
49300
|
}
|
|
49293
49301
|
|
|
49302
|
+
// src/components/TopicAssetSubmitDialog.tsx
|
|
49303
|
+
import { useRef as useRef29, useState as useState40 } from "react";
|
|
49304
|
+
import { jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
49305
|
+
function useTopicAssetSubmissionAccess(sessionId) {
|
|
49306
|
+
const client = useBladeClient();
|
|
49307
|
+
return useAsyncValue(sessionId, async (signal) => {
|
|
49308
|
+
if (!sessionId) return null;
|
|
49309
|
+
const [session, groups] = await Promise.all([
|
|
49310
|
+
client.sessions.getSession(sessionId, { signal }),
|
|
49311
|
+
client.chatGroups.list()
|
|
49312
|
+
]);
|
|
49313
|
+
if (session.runtime_type !== "sandbox" || !session.chat_group_id || session.viewer_role === "viewer") return null;
|
|
49314
|
+
const group = groups.find((item) => item.id === session.chat_group_id);
|
|
49315
|
+
return group && (group.role === "owner" || group.role === "editor") ? group : null;
|
|
49316
|
+
});
|
|
49317
|
+
}
|
|
49318
|
+
function TopicAssetSubmitDialog({ sessionId, topicId, path: path2, onClose, onSubmitted }) {
|
|
49319
|
+
const client = useBladeClient();
|
|
49320
|
+
const [folder, setFolder] = useState40("");
|
|
49321
|
+
const [message, setMessage] = useState40("");
|
|
49322
|
+
const [error61, setError] = useState40(null);
|
|
49323
|
+
const [busy, setBusy] = useState40(false);
|
|
49324
|
+
const submitting = useRef29(false);
|
|
49325
|
+
const [revision, setRevision] = useState40(0);
|
|
49326
|
+
const assets = useAsyncValue(`${sessionId}:${topicId}:${revision}`, async () => {
|
|
49327
|
+
const [session, groups, result] = await Promise.all([
|
|
49328
|
+
client.sessions.getSession(sessionId),
|
|
49329
|
+
client.chatGroups.list(),
|
|
49330
|
+
client.chatGroups.listAssets(topicId)
|
|
49331
|
+
]);
|
|
49332
|
+
const role = groups.find((item) => item.id === topicId)?.role;
|
|
49333
|
+
if (session.runtime_type !== "sandbox" || session.chat_group_id !== topicId || session.viewer_role === "viewer") throw new Error("\u8FD9\u4E2A\u4F1A\u8BDD\u4E0D\u80FD\u63D0\u4EA4\u5230\u8BE5\u4E3B\u9898");
|
|
49334
|
+
if (role !== "owner" && role !== "editor") throw new Error("\u4F60\u5728\u8FD9\u4E2A\u4E3B\u9898\u6CA1\u6709\u63D0\u4EA4\u6743\u9650");
|
|
49335
|
+
const folders = /* @__PURE__ */ new Set();
|
|
49336
|
+
for (const asset of result.items) {
|
|
49337
|
+
if (asset.is_dir) folders.add(asset.path);
|
|
49338
|
+
const parts = asset.path.split("/");
|
|
49339
|
+
for (let i2 = 1; i2 < parts.length; i2 += 1) folders.add(parts.slice(0, i2).join("/"));
|
|
49340
|
+
}
|
|
49341
|
+
return [...folders].sort((a, b2) => a.localeCompare(b2));
|
|
49342
|
+
});
|
|
49343
|
+
const submit = async () => {
|
|
49344
|
+
if (submitting.current || !assets.data) return;
|
|
49345
|
+
submitting.current = true;
|
|
49346
|
+
setBusy(true);
|
|
49347
|
+
setError(null);
|
|
49348
|
+
try {
|
|
49349
|
+
const name = path2.split("/").at(-1) ?? path2;
|
|
49350
|
+
await client.chatGroups.submitSessionAsset({ session_id: sessionId, path: path2, target_path: folder ? `${folder}/${name}` : name, message: message.trim() });
|
|
49351
|
+
onSubmitted?.();
|
|
49352
|
+
onClose();
|
|
49353
|
+
} catch (cause) {
|
|
49354
|
+
setError(cause instanceof Error ? cause.message : "\u63D0\u4EA4\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5");
|
|
49355
|
+
} finally {
|
|
49356
|
+
submitting.current = false;
|
|
49357
|
+
setBusy(false);
|
|
49358
|
+
}
|
|
49359
|
+
};
|
|
49360
|
+
return /* @__PURE__ */ jsx55(Dialog, { open: true, onOpenChange: (open2) => {
|
|
49361
|
+
if (!open2 && !busy) onClose();
|
|
49362
|
+
}, children: /* @__PURE__ */ jsxs48(DialogContent, { className: "max-w-md", children: [
|
|
49363
|
+
/* @__PURE__ */ jsx55(DialogTitle, { children: "\u63D0\u4EA4\u5230\u8D44\u4EA7" }),
|
|
49364
|
+
/* @__PURE__ */ jsx55(DialogDescription, { children: "\u5C06\u6587\u4EF6\u590D\u5236\u5230\u4E3B\u9898\u4F9B\u6210\u5458\u4F7F\u7528\uFF0C\u5DE5\u4F5C\u533A\u539F\u6587\u4EF6\u4F1A\u4FDD\u7559\u3002\u540C\u540D\u8D44\u4EA7\u4F1A\u88AB\u66FF\u6362\u3002" }),
|
|
49365
|
+
/* @__PURE__ */ jsxs48("form", { onSubmit: (event) => {
|
|
49366
|
+
event.preventDefault();
|
|
49367
|
+
void submit();
|
|
49368
|
+
}, className: "flex flex-col gap-4", children: [
|
|
49369
|
+
/* @__PURE__ */ jsx55("p", { className: "break-all text-sm text-secondary-foreground", children: path2 }),
|
|
49370
|
+
/* @__PURE__ */ jsxs48("label", { className: "flex flex-col gap-1 text-sm", children: [
|
|
49371
|
+
"\u76EE\u6807\u6587\u4EF6\u5939",
|
|
49372
|
+
/* @__PURE__ */ jsxs48("select", { "aria-label": "\u76EE\u6807\u6587\u4EF6\u5939", value: folder, onChange: (event) => setFolder(event.target.value), disabled: busy || !assets.data, className: "rounded-md border border-border bg-background p-2", children: [
|
|
49373
|
+
/* @__PURE__ */ jsx55("option", { value: "", children: "\u8D44\u4EA7\u6839\u76EE\u5F55" }),
|
|
49374
|
+
assets.data?.map((item) => /* @__PURE__ */ jsx55("option", { value: item, children: item }, item))
|
|
49375
|
+
] })
|
|
49376
|
+
] }),
|
|
49377
|
+
/* @__PURE__ */ jsxs48("label", { className: "flex flex-col gap-1 text-sm", children: [
|
|
49378
|
+
"\u8BF4\u660E\uFF08\u53EF\u9009\uFF09",
|
|
49379
|
+
/* @__PURE__ */ jsx55("textarea", { "aria-label": "\u63D0\u4EA4\u8BF4\u660E", value: message, onChange: (event) => setMessage(event.target.value), maxLength: 1e3, disabled: busy, className: "min-h-20 rounded-md border border-border bg-background p-2" })
|
|
49380
|
+
] }),
|
|
49381
|
+
assets.error ? /* @__PURE__ */ jsxs48("div", { role: "alert", className: "text-sm text-muted-foreground", children: [
|
|
49382
|
+
assets.error instanceof Error ? assets.error.message : "\u8D44\u4EA7\u52A0\u8F7D\u5931\u8D25",
|
|
49383
|
+
" ",
|
|
49384
|
+
/* @__PURE__ */ jsx55("button", { type: "button", onClick: () => setRevision((n2) => n2 + 1), className: "underline", children: "\u91CD\u8BD5" })
|
|
49385
|
+
] }) : !assets.data ? /* @__PURE__ */ jsx55("output", { className: "text-sm text-muted-foreground", children: "\u6B63\u5728\u52A0\u8F7D\u8D44\u4EA7\u2026" }) : null,
|
|
49386
|
+
error61 ? /* @__PURE__ */ jsx55("p", { role: "alert", className: "text-sm text-muted-foreground", children: error61 }) : null,
|
|
49387
|
+
/* @__PURE__ */ jsxs48("div", { className: "flex justify-end gap-2", children: [
|
|
49388
|
+
/* @__PURE__ */ jsx55("button", { type: "button", disabled: busy, onClick: onClose, className: "rounded-md border border-border px-3 py-2 text-sm", children: "\u53D6\u6D88" }),
|
|
49389
|
+
/* @__PURE__ */ jsx55("button", { type: "submit", disabled: busy || !assets.data, className: "rounded-md bg-primary px-3 py-2 text-sm text-primary-foreground disabled:opacity-50", children: busy ? "\u63D0\u4EA4\u4E2D\u2026" : "\u63D0\u4EA4" })
|
|
49390
|
+
] })
|
|
49391
|
+
] })
|
|
49392
|
+
] }) });
|
|
49393
|
+
}
|
|
49394
|
+
|
|
49294
49395
|
export {
|
|
49295
49396
|
useAgentSession,
|
|
49296
49397
|
useReplay,
|
|
@@ -49319,7 +49420,9 @@ export {
|
|
|
49319
49420
|
AgentChat,
|
|
49320
49421
|
useLlmChat,
|
|
49321
49422
|
LlmChat,
|
|
49322
|
-
ChatView
|
|
49423
|
+
ChatView,
|
|
49424
|
+
useTopicAssetSubmissionAccess,
|
|
49425
|
+
TopicAssetSubmitDialog
|
|
49323
49426
|
};
|
|
49324
49427
|
/*! Bundled license information:
|
|
49325
49428
|
|
|
@@ -49340,4 +49443,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
49340
49443
|
js-yaml/dist/js-yaml.mjs:
|
|
49341
49444
|
(*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
|
|
49342
49445
|
*/
|
|
49343
|
-
//# sourceMappingURL=chunk-
|
|
49446
|
+
//# sourceMappingURL=chunk-T5WGKZN4.js.map
|