@pactor-app/chat 1.18.0 → 1.18.1

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 CHANGED
@@ -73,7 +73,7 @@ driver.complete();
73
73
  - **`<ChatView store transport? onSend? safeRegistry? capabilities? permission? confirm? conversationId? user? params? greeting? subtitle? suggestions?>`**:消息列表 + Composer。发送时 `onSend` 回调先行,注入 `transport` 时同时驱动一轮 turn。空会话渲染 `<EmptyState>`:问候语(`--pactor-chat-font-display` 衬线展示字体)+ 副标题 + `suggestions` 起始建议(字符串或 `{ label, prompt? }`,点击即发送,空数组不渲染建议区)。Composer 扩展 props(`attachments` / `onAttachmentsChange` / `onAttachFiles` / `onAttachmentClick` / `toolbarStart` / `toolbarEnd` / `onMentionTrigger` / `onPlusMenu`)原样透传给内建 Composer,语义见下方 `<Composer>`。
74
74
  - **`<MessageBubble>` / `<PartRenderer>`**:按 role 区分气泡;parts 按类型渲染(text / markdown / dsl / error 附重试入口 / status / artifact 产出物卡片——整卡可点击:着色图标盒 + 标题 + 元信息行「尺寸 · 类型」+ 右上箭头,图标经 `resolveArtifactIcon` 按扩展名优先、kind 兜底解析并带 tone 着色档位,与面板下拉 / 目录树一致;卡片即 `ChatArtifactCard` 内部组件,DSL 片段与 fallback 共用,包入口导出可直接复用;同一消息内连续 artifact part 归并为卡片组,多于 4 个收起为前 4 张 + 「展开 / 收起」与「查看所有产物(n) ›」(打开面板定位产物目录视图,回调 `onOpenArtifactList`));thinking 折叠卡与 tool-call / tool-result 配对轨迹移交 `<ActivityTrace>`;assistant 终态消息底部展示时间戳(当天 HH:mm、非当天带日期,`formatMessageTime`;流式中与无 createdAt 的历史消息不展示,user / system 不展示)。
75
75
  - **`<ActivityTrace>`**:流式状态头(动画图标 + 呼吸文案 + 秒级计时,结束定格)+ 配对工具轨迹条目(单行:名称 + 参数摘要 + 状态图标,展开显示参数与结果/错误)+ thinking 折叠卡(与工具列表为独立块);状态头统一折叠/展开全部内容——流式展开 → 答案阶段自动折叠(单向闩锁:折叠一次后 mode 回跳不重新自动展开,防闪烁)→ 用户 pin 后不再自动变更(按消息记忆)。
76
- - **`<ArtifactPanel artifact? artifacts? inspector? artifactViewers? onClose? onSelectArtifact?>`**:产出物预览面板——标题栏(可选目录列表钮 + 标题 + kind 角标 + 下载钮 + 关闭钮)+ 内容区。内建渲染 markdown / code / text / dsl(Safe Registry 活预览)+ 图片类文件(png / jpg / svg / webp 等,经 `fileType` 或 title 扩展名识别,svg 支持原始标记);`artifactViewers` 按键(扩展名 / kind)对特定格式自定义预览,优先内建;多产物时 header 文件名处为切换下拉,左端目录钮展示产物目录列表(目录视图下返回钮隐藏、标题显示"产物目录");下载钮把当前产物存为本地文件(dsl 存 JSON,图片 URL fetch 失败降级新标签);桌面固定宽右栏(默认宽 = `--pactor-chat-content-width`,宽度夹取 `--pactor-chat-inspector-min-width` 480px ~ host 宽 2/3),背景 `--pactor-chat-inspector-bg` 略深于聊天区,窄屏覆盖抽屉。
76
+ - **`<ArtifactPanel artifact? artifacts? inspector? artifactViewers? onClose? onSelectArtifact?>`**:产出物预览面板——标题栏(可选目录列表钮 + 标题 + kind 角标 + 下载钮 + 关闭钮)+ 内容区。内建渲染 markdown / code / text / dsl(Safe Registry 活预览)+ 图片类文件(png / jpg / svg / webp 等,经 `fileType` 或 title 扩展名识别,svg 支持原始标记);`artifactViewers` 按键(扩展名 / kind)对特定格式自定义预览,优先内建;多产物时 header 文件名处为切换下拉,左端目录钮展示产物目录列表(目录视图下返回钮隐藏、标题显示"产物目录");下载钮把当前产物存为本地文件(dsl 存 JSON,图片 URL fetch 失败降级新标签);桌面固定宽右栏(默认宽 = `--pactor-chat-content-width`,宽度夹取 `--pactor-chat-inspector-min-width` 480px ~ min(`--pactor-chat-inspector-max-width` 600px, host 宽 2/3)),背景 `--pactor-chat-inspector-bg` 略深于聊天区,窄屏覆盖抽屉。
77
77
  - **`ArtifactStore` / `collectArtifacts` / `mergeArtifacts`**(零 React):产出物列表容器——`open` 按 id upsert 并激活、`list()`(引用稳定)/ `activate(id)` / `update(patch)`(补丁激活项)/ `close()`(只关面板,列表保留)/ `subscribe`;`collectArtifacts(messages)` 从消息流归集 ready 产出物(tabs / 目录列表默认数据源),`mergeArtifacts(stream, opened)` 合并归集与打开记录(store 补丁版本优先)。
78
78
  - **`downloadArtifact` / `resolveArtifactFilename` / `buildArtifactBlob`**(产物下载):文件名按 title(无扩展名补 fileType / kind 缺省);文本类存 UTF-8 Blob,dsl 存格式化 JSON,svg 原始标记存 image/svg+xml,图片 http(s) URL fetch 取回(失败降级新标签打开)。
79
79
  - **`<MessageActions>`**:消息操作条(hover 显现),数据驱动渲染——`actions` 缺省为 `['copy', 'regenerate', 'retry', 'edit']`:复制(`collectMessageText` 汇总文本写入剪贴板)、末条 completed assistant 重新生成、user 消息气泡内联编辑重发(确认 → 截断 + 重跑,取消不改 store)、error 消息重试。传入数组时严格按数组渲染(数组即真相),内建动作可按字段覆盖 label / icon / roles / visibleWhen,自定义动作经 `callService(service, { actionId, message })` 派发;图标名走 `MESSAGE_ACTION_ICONS` 白名单(未知名渲染占位图标)。详见下文「消息操作条:messageActions」。
@@ -136,7 +136,7 @@ body:
136
136
  ```
137
137
 
138
138
  - **菜单**:`menu: ChatMenuItem[]`(`key / label / icon? / badge? / disabled? / group?`)驱动内建侧栏;`icon` 为字符串名,映射内置 lucide 子集(plus / chat / history / settings / star / search / user / folder),未知名渲染占位圆点不抛错;`group` 渲染分组标题行;`activeMenuKey` 为受控 prop,典型用法是 `${state.x}` 绑定 + `events.onMenuSelect` 调 `setState` 闭环;disabled 项不触发 `onMenuSelect`。
139
- - **Header 三层**:`title` 标量 → `headerExtra?: DslNode | ReactNode`(标题右侧槽)→ `header?: DslNode | ReactNode`(整体替换内建 header);`showHeader: false` 关闭。header 收进产物面板 host 的 `__main` 左列(header + 对话区纵向堆叠):面板打开时与对话区同宽、不覆盖面板上方(面板独占右列全高),面板关闭时随 `__main` 通栏;均不随对话列限宽。DslNode 槽仅在页面运行时(DslRenderer)上下文内经 `useRenderer().renderChildren` 渲染;纯 React 场景传 ReactNode,误传 DslNode 时告警并跳过(不抛错)。
139
+ - **Header 三层**:`title` 标量 → `headerExtra?: DslNode | ReactNode`(标题右侧槽)→ `header?: DslNode | ReactNode`(整体替换内建 header);`showHeader: false` 关闭。header 收进产物面板 host 的 `__main` 左列(header + 对话区纵向堆叠):面板打开时随 `__main` 通栏(左贴宿主边缘、右贴面板分隔线)、不覆盖面板上方(面板独占右列全高),面板关闭时同样通栏;均不随对话列限宽。DslNode 槽仅在页面运行时(DslRenderer)上下文内经 `useRenderer().renderChildren` 渲染;纯 React 场景传 ReactNode,误传 DslNode 时告警并跳过(不抛错)。
140
140
  - **侧栏槽**:`sidebar?: DslNode | ReactNode` 提供时整体替代内建菜单侧栏(仍以 AppShell 承载)。
141
141
  - **产出物面板**:`artifact` / `panelOpen` 受控 props(典型 `${state.x}` 绑定),事件 `onArtifact`(part 就绪)/ `onOpenArtifact`(卡片打开)/ `onOpenArtifactList`(卡片区"查看所有产物",典型接法 `setState panelOpen=true`,面板自动定位产物目录视图)/ `onPanelClose` / `onSelectArtifact`(下拉 / 目录列表切换,典型接法 `setState artifact=${event.artifact}`);多产物清单由组合层自动从消息流归集,无需 DSL 接线;自定义预览经 `ChatServicesProvider` 注入 `artifactViewers`(函数不进 DSL)。详见上文 `<ArtifactPanel>` 与 `examples/chat/src/chat.page.yaml`。
142
142
  - **React 直连**:`<ChatServicesProvider>` + `<Chat>` 同样可直接作为 React 组件使用(events 即普通函数 props:`onSend?(text)` / `onMenuSelect?(key, item)`)。`createChatWorkspace` 工厂保留为兼容路径,内部已改为 provider + 同一组合逻辑(`ChatComposition`),行为不变。
package/dist/index.cjs CHANGED
@@ -2015,7 +2015,7 @@ function ArtifactPanel({
2015
2015
  const onMove = (moveEvent) => {
2016
2016
  const hostRect = panel.parentElement?.getBoundingClientRect();
2017
2017
  const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
2018
- const maxWidth = hostWidth * 2 / 3;
2018
+ const maxWidth = Math.min(600, hostWidth * 2 / 3);
2019
2019
  const next = startWidth + (startX - moveEvent.clientX);
2020
2020
  setWidth(Math.round(Math.min(Math.max(next, 480), maxWidth)));
2021
2021
  };
@@ -2098,7 +2098,7 @@ function ArtifactPanel({
2098
2098
  }
2099
2099
 
2100
2100
  // src/view/ChatView.tsx
2101
- var import_components11 = require("@pactor-app/ui/components");
2101
+ var import_components12 = require("@pactor-app/ui/components");
2102
2102
  var import_core4 = require("@pactor-app/core");
2103
2103
  var import_react17 = require("react");
2104
2104
 
@@ -3109,6 +3109,7 @@ function EmptyState({
3109
3109
 
3110
3110
  // src/view/MessageBubble.tsx
3111
3111
  var import_react16 = require("react");
3112
+ var import_components11 = require("@pactor-app/ui/components");
3112
3113
 
3113
3114
  // src/view/ActivityTrace.tsx
3114
3115
  var import_components9 = require("@pactor-app/ui/components");
@@ -3645,8 +3646,26 @@ function MessageEditForm({
3645
3646
  ] })
3646
3647
  ] });
3647
3648
  }
3649
+ function isAgentIconUrl(icon) {
3650
+ return /^(https?:|data:|\/)/.test(icon);
3651
+ }
3652
+ function AgentHeader({ agent }) {
3653
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__agent", children: [
3654
+ agent.icon !== void 0 && (isAgentIconUrl(agent.icon) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3655
+ "img",
3656
+ {
3657
+ className: "pactor-chat-message__agent-icon",
3658
+ src: agent.icon,
3659
+ alt: "",
3660
+ "aria-hidden": true
3661
+ }
3662
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "pactor-chat-message__agent-icon", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components11.Icon, { name: agent.icon }) })),
3663
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "pactor-chat-message__agent-name", children: agent.name })
3664
+ ] });
3665
+ }
3648
3666
  function MessageBubble({
3649
3667
  message,
3668
+ agent,
3650
3669
  runtime,
3651
3670
  scope,
3652
3671
  showRegenerate = false,
@@ -3673,6 +3692,7 @@ function MessageBubble({
3673
3692
  (part) => part.type === "thinking" || part.type === "tool-call" || part.type === "tool-result"
3674
3693
  ));
3675
3694
  const showTime = message.role === "assistant" && !live && message.createdAt !== void 0;
3695
+ const agentIdentity = message.role === "assistant" ? message.agent ?? agent : void 0;
3676
3696
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3677
3697
  "div",
3678
3698
  {
@@ -3691,6 +3711,7 @@ function MessageBubble({
3691
3711
  onCancel: () => setEditing(false)
3692
3712
  }
3693
3713
  ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-message__body", children: [
3714
+ agentIdentity && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentHeader, { agent: agentIdentity }),
3694
3715
  showTrace && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ActivityTrace, { message }),
3695
3716
  message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "pactor-chat-message__pending", children: "\u2026" }) : groupArtifactParts(message.parts).map(
3696
3717
  (segment, index) => Array.isArray(segment) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -3770,6 +3791,7 @@ function lastContentLength(messages) {
3770
3791
  function ChatView({
3771
3792
  store,
3772
3793
  transport,
3794
+ agent,
3773
3795
  onSend,
3774
3796
  safeRegistry,
3775
3797
  capabilities,
@@ -3977,6 +3999,7 @@ function ChatView({
3977
3999
  MessageBubble,
3978
4000
  {
3979
4001
  message,
4002
+ agent,
3980
4003
  runtime,
3981
4004
  scope,
3982
4005
  showRegenerate: message.id === regenerableMessageId,
@@ -3996,7 +4019,7 @@ function ChatView({
3996
4019
  className: "pactor-chat-scroll-bottom",
3997
4020
  onClick: scrollToBottom,
3998
4021
  children: [
3999
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "arrow-down", size: 13 }),
4022
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components12.Icon, { name: "arrow-down", size: 13 }),
4000
4023
  "\u56DE\u5230\u5E95\u90E8"
4001
4024
  ]
4002
4025
  }
@@ -4009,7 +4032,7 @@ function ChatView({
4009
4032
  }
4010
4033
 
4011
4034
  // src/view/WorkspaceHeader.tsx
4012
- var import_components12 = require("@pactor-app/ui/components");
4035
+ var import_components13 = require("@pactor-app/ui/components");
4013
4036
  var import_react18 = require("react");
4014
4037
 
4015
4038
  // src/export-markdown.ts
@@ -4170,7 +4193,7 @@ function WorkspaceHeader({
4170
4193
  title: "\u5BFC\u51FA Markdown",
4171
4194
  "aria-label": "\u5BFC\u51FA Markdown",
4172
4195
  onClick: handleExport,
4173
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "download", size: 15 })
4196
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components13.Icon, { name: "download", size: 15 })
4174
4197
  },
4175
4198
  "export"
4176
4199
  ),
@@ -4182,7 +4205,7 @@ function WorkspaceHeader({
4182
4205
  title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
4183
4206
  "aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
4184
4207
  onClick: handleTheme,
4185
- children: theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "sun", size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "moon", size: 15 })
4208
+ children: theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components13.Icon, { name: "sun", size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components13.Icon, { name: "moon", size: 15 })
4186
4209
  },
4187
4210
  "theme"
4188
4211
  ),
@@ -4194,7 +4217,7 @@ function WorkspaceHeader({
4194
4217
  title: "\u6E05\u7A7A\u4F1A\u8BDD",
4195
4218
  "aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
4196
4219
  onClick: handleClear,
4197
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components12.Icon, { name: "trash", size: 15 })
4220
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_components13.Icon, { name: "trash", size: 15 })
4198
4221
  },
4199
4222
  "clear"
4200
4223
  )
@@ -4295,6 +4318,7 @@ function ChatComposition({
4295
4318
  services,
4296
4319
  title,
4297
4320
  greeting,
4321
+ agent,
4298
4322
  subtitle,
4299
4323
  suggestions,
4300
4324
  conversationId,
@@ -4464,6 +4488,7 @@ function ChatComposition({
4464
4488
  {
4465
4489
  store,
4466
4490
  transport: services.transport,
4491
+ agent,
4467
4492
  onSend: handleSend,
4468
4493
  safeRegistry: services.safeRegistry,
4469
4494
  capabilities: services.capabilities,
@@ -4645,7 +4670,7 @@ function createChatWorkspace(services) {
4645
4670
  }
4646
4671
 
4647
4672
  // src/view/Chat.tsx
4648
- var import_components13 = require("@pactor-app/ui/components");
4673
+ var import_components14 = require("@pactor-app/ui/components");
4649
4674
  var import_react21 = require("react");
4650
4675
 
4651
4676
  // src/view/chrome/menu.tsx
@@ -4774,7 +4799,7 @@ function ChatSidebarMenu({
4774
4799
  drawer?.close();
4775
4800
  },
4776
4801
  children: [
4777
- item.icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components13.Icon, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
4802
+ item.icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components14.Icon, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
4778
4803
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__label", children: item.label }),
4779
4804
  item.dot === true ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
4780
4805
  item.badge !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
@@ -4783,7 +4808,7 @@ function ChatSidebarMenu({
4783
4808
  );
4784
4809
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react21.Fragment, { children: [
4785
4810
  groupLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "pactor-chat-menu__group", children: groupLabel }) : null,
4786
- collapsed ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components13.RailTooltip, { label: item.label, children: button }) : button
4811
+ collapsed ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_components14.RailTooltip, { label: item.label, children: button }) : button
4787
4812
  ] }, item.key);
4788
4813
  }) });
4789
4814
  })();
@@ -4798,6 +4823,7 @@ function ChatSidebarMenu({
4798
4823
  function Chat({
4799
4824
  title,
4800
4825
  greeting,
4826
+ agent,
4801
4827
  subtitle,
4802
4828
  suggestions,
4803
4829
  conversationId,
@@ -4865,6 +4891,7 @@ function Chat({
4865
4891
  services,
4866
4892
  title,
4867
4893
  greeting,
4894
+ agent,
4868
4895
  subtitle,
4869
4896
  suggestions,
4870
4897
  conversationId,
@@ -4951,7 +4978,7 @@ function registerChatComponent(registry) {
4951
4978
  registerChatShellComponent(registry);
4952
4979
  }
4953
4980
  function createChatComponentRegistry() {
4954
- const registry = (0, import_components13.createComponentRegistry)();
4981
+ const registry = (0, import_components14.createComponentRegistry)();
4955
4982
  registerChatComponent(registry);
4956
4983
  return registry;
4957
4984
  }
package/dist/index.d.cts CHANGED
@@ -251,6 +251,19 @@ interface ChatMessageAction {
251
251
  /** 自定义动作的派发服务名(经注入的 callService 解析) */
252
252
  service?: string;
253
253
  }
254
+ /**
255
+ * 消息归属 Agent 身份:assistant 消息顶部以「图标 + 加粗名称」展示
256
+ * 返回该消息的 Agent。DSL 可表达的纯数据对象。
257
+ */
258
+ interface ChatAgentIdentity {
259
+ /** Agent 展示名(加粗渲染) */
260
+ name: string;
261
+ /**
262
+ * 图标:@pactor-app/ui Icon 白名单名(未知名渲染占位图标),
263
+ * 或图片 URL(http(s): / data: / 绝对路径开头按 <img> 渲染)
264
+ */
265
+ icon?: string;
266
+ }
254
267
  /** Chat 消息 */
255
268
  interface ChatMessage {
256
269
  id: string;
@@ -259,6 +272,8 @@ interface ChatMessage {
259
272
  parts: ChatPart[];
260
273
  createdAt?: number;
261
274
  attachments?: ChatAttachment[];
275
+ /** 返回该消息的 Agent 身份(assistant 消息顶部展示) */
276
+ agent?: ChatAgentIdentity;
262
277
  }
263
278
  /** updatePart 的定位参数:数组下标或 part id */
264
279
  type PartRef = number | string;
@@ -1053,6 +1068,12 @@ interface ChatProps {
1053
1068
  title?: string;
1054
1069
  /** 空会话问候语 */
1055
1070
  greeting?: string;
1071
+ /**
1072
+ * 会话级 Agent 身份(DSL 可表达对象):assistant 消息顶部以
1073
+ * 「图标 + 加粗名称」展示返回消息的 Agent;消息自带
1074
+ * message.agent 时以消息为准;未配置不渲染身份行
1075
+ */
1076
+ agent?: ChatAgentIdentity;
1056
1077
  /** 空会话副标题 */
1057
1078
  subtitle?: string;
1058
1079
  /** 空会话起始建议;空数组 / 未传时不渲染建议区 */
@@ -1176,7 +1197,7 @@ declare function ChatSidebarMenu({ menu, activeMenuKey, onMenuSelect, }: {
1176
1197
  * 「未配置聊天服务」提示并 console.warn,不抛错。组合逻辑与
1177
1198
  * createChatWorkspace 共用内部 ChatComposition(决策 D5)。
1178
1199
  */
1179
- declare function Chat({ title, greeting, subtitle, suggestions, conversationId, params, showHeader, menu, activeMenuKey, sidebar, toolbarStart, toolbarEnd, composerFooter, composerBottom, hideToolbar, headerExtra, header, headerActions, editableTitle, onExport, onThemeChange, onClear, onTitleChange, models, model, onModelChange, modelPlacement, contexts, onContextsChange, messageActions, onMessageAction, artifact, panelOpen, onPanelClose, inspector, onArtifact, onOpenArtifact, onOpenArtifactList, onSelectArtifact, className, onSend, onMenuSelect, }: ChatProps): ReactNode;
1200
+ declare function Chat({ title, greeting, agent, subtitle, suggestions, conversationId, params, showHeader, menu, activeMenuKey, sidebar, toolbarStart, toolbarEnd, composerFooter, composerBottom, hideToolbar, headerExtra, header, headerActions, editableTitle, onExport, onThemeChange, onClear, onTitleChange, models, model, onModelChange, modelPlacement, contexts, onContextsChange, messageActions, onMessageAction, artifact, panelOpen, onPanelClose, inspector, onArtifact, onOpenArtifact, onOpenArtifactList, onSelectArtifact, className, onSend, onMenuSelect, }: ChatProps): ReactNode;
1180
1201
  /** Chat 的 DSL 组件类型名 */
1181
1202
  declare const CHAT_COMPONENT_TYPE = "Chat";
1182
1203
  /**
@@ -1421,6 +1442,11 @@ interface ChatViewProps extends Pick<ComposerProps, 'attachments' | 'onAttachmen
1421
1442
  store: ConversationStore;
1422
1443
  /** 注入后发送即驱动 turn;缺省时仅触发 onSend */
1423
1444
  transport?: ChatTransport;
1445
+ /**
1446
+ * 会话级 Agent 身份(assistant 消息顶部「图标 + 加粗名称」展示的兜底,
1447
+ * 消息自带 message.agent 时以消息为准);未配置不渲染身份行
1448
+ */
1449
+ agent?: ChatAgentIdentity;
1424
1450
  onSend?: (text: string) => void;
1425
1451
  /** Safe Registry(createSafeRegistry 包装后的白名单注册表) */
1426
1452
  safeRegistry?: Registry<unknown>;
@@ -1489,7 +1515,7 @@ interface ChatViewProps extends Pick<ComposerProps, 'attachments' | 'onAttachmen
1489
1515
  composerBottom?: ReactNode;
1490
1516
  className?: string;
1491
1517
  }
1492
- declare function ChatView({ store, transport, onSend, safeRegistry, capabilities, permission, confirm, conversationId, user, params, greeting, subtitle, suggestions, className, onArtifact, onOpenArtifact, onOpenArtifactList, attachments, onAttachmentsChange, onAttachFiles, onAttachmentClick, toolbarStart, toolbarEnd, composerFooter, hideToolbar, onMentionTrigger, onPlusMenu, models, model, onModelChange, modelPlacement, contexts, onContextsChange, callService, messageActions, onMessageAction, composerBottom, }: ChatViewProps): react.JSX.Element;
1518
+ declare function ChatView({ store, transport, agent, onSend, safeRegistry, capabilities, permission, confirm, conversationId, user, params, greeting, subtitle, suggestions, className, onArtifact, onOpenArtifact, onOpenArtifactList, attachments, onAttachmentsChange, onAttachFiles, onAttachmentClick, toolbarStart, toolbarEnd, composerFooter, hideToolbar, onMentionTrigger, onPlusMenu, models, model, onModelChange, modelPlacement, contexts, onContextsChange, callService, messageActions, onMessageAction, composerBottom, }: ChatViewProps): react.JSX.Element;
1493
1519
 
1494
1520
  /**
1495
1521
  * ActivityTrace(spec: chat-activity-trace,设计决策 D1/D4):
@@ -1524,6 +1550,11 @@ declare function ActivityTrace({ message }: ActivityTraceProps): react.JSX.Eleme
1524
1550
  */
1525
1551
  interface MessageBubbleProps {
1526
1552
  message: ChatMessage;
1553
+ /**
1554
+ * 会话级 Agent 身份兜底:assistant 消息未自带 message.agent 时
1555
+ * 以其在消息顶部展示「图标 + 加粗名称」(单 Agent 会话的便捷配置)
1556
+ */
1557
+ agent?: ChatAgentIdentity;
1527
1558
  /** 透传给 dsl part 的渲染运行时与作用域 */
1528
1559
  runtime?: ChatRuntime;
1529
1560
  scope?: Omit<ChatScope, 'message'>;
@@ -1555,7 +1586,7 @@ interface MessageBubbleProps {
1555
1586
  * 当天 HH:mm;非当天 M月d日 HH:mm
1556
1587
  */
1557
1588
  declare function formatMessageTime(ts: number, now?: number): string;
1558
- declare function MessageBubble({ message, runtime, scope, showRegenerate, onRegenerate, onRetry, onEditResend, messageActions, callService, onMessageAction, }: MessageBubbleProps): react.JSX.Element;
1589
+ declare function MessageBubble({ message, agent, runtime, scope, showRegenerate, onRegenerate, onRetry, onEditResend, messageActions, callService, onMessageAction, }: MessageBubbleProps): react.JSX.Element;
1559
1590
 
1560
1591
  /**
1561
1592
  * MessageActions(spec: chat-message-actions / 消息操作条):
@@ -1655,4 +1686,4 @@ interface ChatLayoutRegistry {
1655
1686
  /** 注册 chat 布局(已注册时不覆盖,与 createLayoutRegistry 约定一致) */
1656
1687
  declare function registerChatLayout(layoutRegistry: ChatLayoutRegistry): void;
1657
1688
 
1658
- export { ARTIFACT_IMAGE_EXTENSIONS, ActivityTrace, type ActivityTraceProps, AppShell, type AppShellProps, type ArtifactIconSpec, type ArtifactIconTone, ArtifactPanel, type ArtifactPanelProps, type ArtifactPatch, ArtifactStore, type ArtifactTreeNode, type ArtifactViewer, type ArtifactViewers, type BuiltinMessageAction, CHAT_COMPONENT_TYPE, CHAT_DENIED_TYPE, CHAT_LAYOUT_TYPE, CHAT_SHELL_COMPONENT_TYPE, type CapabilityActionDeps, type CapabilityHandler, Chat, type ChatArtifact, ChatArtifactCard, type ChatAttachment, type ChatCapabilityRegistry, type ChatConfirm, type ChatConfirmRequest, type ChatContextItem, type ChatContextSource, ChatDenied, type ChatEvent, type ChatHeaderAction, type ChatInput, ChatLayout, type ChatLayoutProps, type ChatLayoutRegistry, type ChatMenuItem, type ChatMessage, type ChatMessageAction, type ChatModelOption, type ChatPart, type ChatPermissionChecker, type ChatProps, type ChatRole, type ChatRuntime, type ChatScope, type ChatServices, ChatServicesProvider, ChatShell, type ChatShellProps, ChatSidebarMenu, type ChatSuggestion, type ChatTransport, type ChatTurnResult, ChatView, type ChatViewProps, type ChatWorkspaceProps, type ChatWorkspaceServices, Composer, type ComposerProps, ConversationStore, type CreateChatRuntimeOptions, DEFAULT_CHAT_GREETING, EmptyState, type EmptyStateProps, type ManualChatDriver, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, type MessagePatch, type MessageStatus, type PartPatch, type PartRef, PartRenderer, type PartRendererProps, type PartStatus, type RunChatTurnOptions, type StreamingMode, type ToolCallStatus, type ToolTraceEntry, type UseChatAutoScrollOptions, type UseChatAutoScrollResult, type UseSmoothStreamTextOptions, applyChatEvent, artifactCardMeta, buildArtifactBlob, buildArtifactTree, buildChatScope, collectArtifacts, collectMessageText, createChatComponentRegistry, createChatId, createChatRuntime, createChatWorkspace, createManualDriver, createSafeRegistry, detectStreamingMode, downloadArtifact, formatArtifactSize, formatMessageTime, guardChatDsl, isImageArtifact, mergeArtifacts, pairToolTraces, registerCapabilityAction, registerChatComponent, registerChatLayout, registerChatShellComponent, resolveArtifactFileType, resolveArtifactFilename, resolveArtifactIcon, resolveArtifactIconName, runChatTurn, runRegenerateTurn, saveBlob, useChatAutoScroll, useChatServices, useSidebarDrawer, useSmoothStreamText };
1689
+ export { ARTIFACT_IMAGE_EXTENSIONS, ActivityTrace, type ActivityTraceProps, AppShell, type AppShellProps, type ArtifactIconSpec, type ArtifactIconTone, ArtifactPanel, type ArtifactPanelProps, type ArtifactPatch, ArtifactStore, type ArtifactTreeNode, type ArtifactViewer, type ArtifactViewers, type BuiltinMessageAction, CHAT_COMPONENT_TYPE, CHAT_DENIED_TYPE, CHAT_LAYOUT_TYPE, CHAT_SHELL_COMPONENT_TYPE, type CapabilityActionDeps, type CapabilityHandler, Chat, type ChatAgentIdentity, type ChatArtifact, ChatArtifactCard, type ChatAttachment, type ChatCapabilityRegistry, type ChatConfirm, type ChatConfirmRequest, type ChatContextItem, type ChatContextSource, ChatDenied, type ChatEvent, type ChatHeaderAction, type ChatInput, ChatLayout, type ChatLayoutProps, type ChatLayoutRegistry, type ChatMenuItem, type ChatMessage, type ChatMessageAction, type ChatModelOption, type ChatPart, type ChatPermissionChecker, type ChatProps, type ChatRole, type ChatRuntime, type ChatScope, type ChatServices, ChatServicesProvider, ChatShell, type ChatShellProps, ChatSidebarMenu, type ChatSuggestion, type ChatTransport, type ChatTurnResult, ChatView, type ChatViewProps, type ChatWorkspaceProps, type ChatWorkspaceServices, Composer, type ComposerProps, ConversationStore, type CreateChatRuntimeOptions, DEFAULT_CHAT_GREETING, EmptyState, type EmptyStateProps, type ManualChatDriver, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, type MessagePatch, type MessageStatus, type PartPatch, type PartRef, PartRenderer, type PartRendererProps, type PartStatus, type RunChatTurnOptions, type StreamingMode, type ToolCallStatus, type ToolTraceEntry, type UseChatAutoScrollOptions, type UseChatAutoScrollResult, type UseSmoothStreamTextOptions, applyChatEvent, artifactCardMeta, buildArtifactBlob, buildArtifactTree, buildChatScope, collectArtifacts, collectMessageText, createChatComponentRegistry, createChatId, createChatRuntime, createChatWorkspace, createManualDriver, createSafeRegistry, detectStreamingMode, downloadArtifact, formatArtifactSize, formatMessageTime, guardChatDsl, isImageArtifact, mergeArtifacts, pairToolTraces, registerCapabilityAction, registerChatComponent, registerChatLayout, registerChatShellComponent, resolveArtifactFileType, resolveArtifactFilename, resolveArtifactIcon, resolveArtifactIconName, runChatTurn, runRegenerateTurn, saveBlob, useChatAutoScroll, useChatServices, useSidebarDrawer, useSmoothStreamText };
package/dist/index.d.ts CHANGED
@@ -251,6 +251,19 @@ interface ChatMessageAction {
251
251
  /** 自定义动作的派发服务名(经注入的 callService 解析) */
252
252
  service?: string;
253
253
  }
254
+ /**
255
+ * 消息归属 Agent 身份:assistant 消息顶部以「图标 + 加粗名称」展示
256
+ * 返回该消息的 Agent。DSL 可表达的纯数据对象。
257
+ */
258
+ interface ChatAgentIdentity {
259
+ /** Agent 展示名(加粗渲染) */
260
+ name: string;
261
+ /**
262
+ * 图标:@pactor-app/ui Icon 白名单名(未知名渲染占位图标),
263
+ * 或图片 URL(http(s): / data: / 绝对路径开头按 <img> 渲染)
264
+ */
265
+ icon?: string;
266
+ }
254
267
  /** Chat 消息 */
255
268
  interface ChatMessage {
256
269
  id: string;
@@ -259,6 +272,8 @@ interface ChatMessage {
259
272
  parts: ChatPart[];
260
273
  createdAt?: number;
261
274
  attachments?: ChatAttachment[];
275
+ /** 返回该消息的 Agent 身份(assistant 消息顶部展示) */
276
+ agent?: ChatAgentIdentity;
262
277
  }
263
278
  /** updatePart 的定位参数:数组下标或 part id */
264
279
  type PartRef = number | string;
@@ -1053,6 +1068,12 @@ interface ChatProps {
1053
1068
  title?: string;
1054
1069
  /** 空会话问候语 */
1055
1070
  greeting?: string;
1071
+ /**
1072
+ * 会话级 Agent 身份(DSL 可表达对象):assistant 消息顶部以
1073
+ * 「图标 + 加粗名称」展示返回消息的 Agent;消息自带
1074
+ * message.agent 时以消息为准;未配置不渲染身份行
1075
+ */
1076
+ agent?: ChatAgentIdentity;
1056
1077
  /** 空会话副标题 */
1057
1078
  subtitle?: string;
1058
1079
  /** 空会话起始建议;空数组 / 未传时不渲染建议区 */
@@ -1176,7 +1197,7 @@ declare function ChatSidebarMenu({ menu, activeMenuKey, onMenuSelect, }: {
1176
1197
  * 「未配置聊天服务」提示并 console.warn,不抛错。组合逻辑与
1177
1198
  * createChatWorkspace 共用内部 ChatComposition(决策 D5)。
1178
1199
  */
1179
- declare function Chat({ title, greeting, subtitle, suggestions, conversationId, params, showHeader, menu, activeMenuKey, sidebar, toolbarStart, toolbarEnd, composerFooter, composerBottom, hideToolbar, headerExtra, header, headerActions, editableTitle, onExport, onThemeChange, onClear, onTitleChange, models, model, onModelChange, modelPlacement, contexts, onContextsChange, messageActions, onMessageAction, artifact, panelOpen, onPanelClose, inspector, onArtifact, onOpenArtifact, onOpenArtifactList, onSelectArtifact, className, onSend, onMenuSelect, }: ChatProps): ReactNode;
1200
+ declare function Chat({ title, greeting, agent, subtitle, suggestions, conversationId, params, showHeader, menu, activeMenuKey, sidebar, toolbarStart, toolbarEnd, composerFooter, composerBottom, hideToolbar, headerExtra, header, headerActions, editableTitle, onExport, onThemeChange, onClear, onTitleChange, models, model, onModelChange, modelPlacement, contexts, onContextsChange, messageActions, onMessageAction, artifact, panelOpen, onPanelClose, inspector, onArtifact, onOpenArtifact, onOpenArtifactList, onSelectArtifact, className, onSend, onMenuSelect, }: ChatProps): ReactNode;
1180
1201
  /** Chat 的 DSL 组件类型名 */
1181
1202
  declare const CHAT_COMPONENT_TYPE = "Chat";
1182
1203
  /**
@@ -1421,6 +1442,11 @@ interface ChatViewProps extends Pick<ComposerProps, 'attachments' | 'onAttachmen
1421
1442
  store: ConversationStore;
1422
1443
  /** 注入后发送即驱动 turn;缺省时仅触发 onSend */
1423
1444
  transport?: ChatTransport;
1445
+ /**
1446
+ * 会话级 Agent 身份(assistant 消息顶部「图标 + 加粗名称」展示的兜底,
1447
+ * 消息自带 message.agent 时以消息为准);未配置不渲染身份行
1448
+ */
1449
+ agent?: ChatAgentIdentity;
1424
1450
  onSend?: (text: string) => void;
1425
1451
  /** Safe Registry(createSafeRegistry 包装后的白名单注册表) */
1426
1452
  safeRegistry?: Registry<unknown>;
@@ -1489,7 +1515,7 @@ interface ChatViewProps extends Pick<ComposerProps, 'attachments' | 'onAttachmen
1489
1515
  composerBottom?: ReactNode;
1490
1516
  className?: string;
1491
1517
  }
1492
- declare function ChatView({ store, transport, onSend, safeRegistry, capabilities, permission, confirm, conversationId, user, params, greeting, subtitle, suggestions, className, onArtifact, onOpenArtifact, onOpenArtifactList, attachments, onAttachmentsChange, onAttachFiles, onAttachmentClick, toolbarStart, toolbarEnd, composerFooter, hideToolbar, onMentionTrigger, onPlusMenu, models, model, onModelChange, modelPlacement, contexts, onContextsChange, callService, messageActions, onMessageAction, composerBottom, }: ChatViewProps): react.JSX.Element;
1518
+ declare function ChatView({ store, transport, agent, onSend, safeRegistry, capabilities, permission, confirm, conversationId, user, params, greeting, subtitle, suggestions, className, onArtifact, onOpenArtifact, onOpenArtifactList, attachments, onAttachmentsChange, onAttachFiles, onAttachmentClick, toolbarStart, toolbarEnd, composerFooter, hideToolbar, onMentionTrigger, onPlusMenu, models, model, onModelChange, modelPlacement, contexts, onContextsChange, callService, messageActions, onMessageAction, composerBottom, }: ChatViewProps): react.JSX.Element;
1493
1519
 
1494
1520
  /**
1495
1521
  * ActivityTrace(spec: chat-activity-trace,设计决策 D1/D4):
@@ -1524,6 +1550,11 @@ declare function ActivityTrace({ message }: ActivityTraceProps): react.JSX.Eleme
1524
1550
  */
1525
1551
  interface MessageBubbleProps {
1526
1552
  message: ChatMessage;
1553
+ /**
1554
+ * 会话级 Agent 身份兜底:assistant 消息未自带 message.agent 时
1555
+ * 以其在消息顶部展示「图标 + 加粗名称」(单 Agent 会话的便捷配置)
1556
+ */
1557
+ agent?: ChatAgentIdentity;
1527
1558
  /** 透传给 dsl part 的渲染运行时与作用域 */
1528
1559
  runtime?: ChatRuntime;
1529
1560
  scope?: Omit<ChatScope, 'message'>;
@@ -1555,7 +1586,7 @@ interface MessageBubbleProps {
1555
1586
  * 当天 HH:mm;非当天 M月d日 HH:mm
1556
1587
  */
1557
1588
  declare function formatMessageTime(ts: number, now?: number): string;
1558
- declare function MessageBubble({ message, runtime, scope, showRegenerate, onRegenerate, onRetry, onEditResend, messageActions, callService, onMessageAction, }: MessageBubbleProps): react.JSX.Element;
1589
+ declare function MessageBubble({ message, agent, runtime, scope, showRegenerate, onRegenerate, onRetry, onEditResend, messageActions, callService, onMessageAction, }: MessageBubbleProps): react.JSX.Element;
1559
1590
 
1560
1591
  /**
1561
1592
  * MessageActions(spec: chat-message-actions / 消息操作条):
@@ -1655,4 +1686,4 @@ interface ChatLayoutRegistry {
1655
1686
  /** 注册 chat 布局(已注册时不覆盖,与 createLayoutRegistry 约定一致) */
1656
1687
  declare function registerChatLayout(layoutRegistry: ChatLayoutRegistry): void;
1657
1688
 
1658
- export { ARTIFACT_IMAGE_EXTENSIONS, ActivityTrace, type ActivityTraceProps, AppShell, type AppShellProps, type ArtifactIconSpec, type ArtifactIconTone, ArtifactPanel, type ArtifactPanelProps, type ArtifactPatch, ArtifactStore, type ArtifactTreeNode, type ArtifactViewer, type ArtifactViewers, type BuiltinMessageAction, CHAT_COMPONENT_TYPE, CHAT_DENIED_TYPE, CHAT_LAYOUT_TYPE, CHAT_SHELL_COMPONENT_TYPE, type CapabilityActionDeps, type CapabilityHandler, Chat, type ChatArtifact, ChatArtifactCard, type ChatAttachment, type ChatCapabilityRegistry, type ChatConfirm, type ChatConfirmRequest, type ChatContextItem, type ChatContextSource, ChatDenied, type ChatEvent, type ChatHeaderAction, type ChatInput, ChatLayout, type ChatLayoutProps, type ChatLayoutRegistry, type ChatMenuItem, type ChatMessage, type ChatMessageAction, type ChatModelOption, type ChatPart, type ChatPermissionChecker, type ChatProps, type ChatRole, type ChatRuntime, type ChatScope, type ChatServices, ChatServicesProvider, ChatShell, type ChatShellProps, ChatSidebarMenu, type ChatSuggestion, type ChatTransport, type ChatTurnResult, ChatView, type ChatViewProps, type ChatWorkspaceProps, type ChatWorkspaceServices, Composer, type ComposerProps, ConversationStore, type CreateChatRuntimeOptions, DEFAULT_CHAT_GREETING, EmptyState, type EmptyStateProps, type ManualChatDriver, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, type MessagePatch, type MessageStatus, type PartPatch, type PartRef, PartRenderer, type PartRendererProps, type PartStatus, type RunChatTurnOptions, type StreamingMode, type ToolCallStatus, type ToolTraceEntry, type UseChatAutoScrollOptions, type UseChatAutoScrollResult, type UseSmoothStreamTextOptions, applyChatEvent, artifactCardMeta, buildArtifactBlob, buildArtifactTree, buildChatScope, collectArtifacts, collectMessageText, createChatComponentRegistry, createChatId, createChatRuntime, createChatWorkspace, createManualDriver, createSafeRegistry, detectStreamingMode, downloadArtifact, formatArtifactSize, formatMessageTime, guardChatDsl, isImageArtifact, mergeArtifacts, pairToolTraces, registerCapabilityAction, registerChatComponent, registerChatLayout, registerChatShellComponent, resolveArtifactFileType, resolveArtifactFilename, resolveArtifactIcon, resolveArtifactIconName, runChatTurn, runRegenerateTurn, saveBlob, useChatAutoScroll, useChatServices, useSidebarDrawer, useSmoothStreamText };
1689
+ export { ARTIFACT_IMAGE_EXTENSIONS, ActivityTrace, type ActivityTraceProps, AppShell, type AppShellProps, type ArtifactIconSpec, type ArtifactIconTone, ArtifactPanel, type ArtifactPanelProps, type ArtifactPatch, ArtifactStore, type ArtifactTreeNode, type ArtifactViewer, type ArtifactViewers, type BuiltinMessageAction, CHAT_COMPONENT_TYPE, CHAT_DENIED_TYPE, CHAT_LAYOUT_TYPE, CHAT_SHELL_COMPONENT_TYPE, type CapabilityActionDeps, type CapabilityHandler, Chat, type ChatAgentIdentity, type ChatArtifact, ChatArtifactCard, type ChatAttachment, type ChatCapabilityRegistry, type ChatConfirm, type ChatConfirmRequest, type ChatContextItem, type ChatContextSource, ChatDenied, type ChatEvent, type ChatHeaderAction, type ChatInput, ChatLayout, type ChatLayoutProps, type ChatLayoutRegistry, type ChatMenuItem, type ChatMessage, type ChatMessageAction, type ChatModelOption, type ChatPart, type ChatPermissionChecker, type ChatProps, type ChatRole, type ChatRuntime, type ChatScope, type ChatServices, ChatServicesProvider, ChatShell, type ChatShellProps, ChatSidebarMenu, type ChatSuggestion, type ChatTransport, type ChatTurnResult, ChatView, type ChatViewProps, type ChatWorkspaceProps, type ChatWorkspaceServices, Composer, type ComposerProps, ConversationStore, type CreateChatRuntimeOptions, DEFAULT_CHAT_GREETING, EmptyState, type EmptyStateProps, type ManualChatDriver, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, type MessagePatch, type MessageStatus, type PartPatch, type PartRef, PartRenderer, type PartRendererProps, type PartStatus, type RunChatTurnOptions, type StreamingMode, type ToolCallStatus, type ToolTraceEntry, type UseChatAutoScrollOptions, type UseChatAutoScrollResult, type UseSmoothStreamTextOptions, applyChatEvent, artifactCardMeta, buildArtifactBlob, buildArtifactTree, buildChatScope, collectArtifacts, collectMessageText, createChatComponentRegistry, createChatId, createChatRuntime, createChatWorkspace, createManualDriver, createSafeRegistry, detectStreamingMode, downloadArtifact, formatArtifactSize, formatMessageTime, guardChatDsl, isImageArtifact, mergeArtifacts, pairToolTraces, registerCapabilityAction, registerChatComponent, registerChatLayout, registerChatShellComponent, resolveArtifactFileType, resolveArtifactFilename, resolveArtifactIcon, resolveArtifactIconName, runChatTurn, runRegenerateTurn, saveBlob, useChatAutoScroll, useChatServices, useSidebarDrawer, useSmoothStreamText };
package/dist/index.js CHANGED
@@ -1950,7 +1950,7 @@ function ArtifactPanel({
1950
1950
  const onMove = (moveEvent) => {
1951
1951
  const hostRect = panel.parentElement?.getBoundingClientRect();
1952
1952
  const hostWidth = hostRect !== void 0 && hostRect.width > 0 ? hostRect.width : window.innerWidth;
1953
- const maxWidth = hostWidth * 2 / 3;
1953
+ const maxWidth = Math.min(600, hostWidth * 2 / 3);
1954
1954
  const next = startWidth + (startX - moveEvent.clientX);
1955
1955
  setWidth(Math.round(Math.min(Math.max(next, 480), maxWidth)));
1956
1956
  };
@@ -2033,7 +2033,7 @@ function ArtifactPanel({
2033
2033
  }
2034
2034
 
2035
2035
  // src/view/ChatView.tsx
2036
- import { Icon as Icon10 } from "@pactor-app/ui/components";
2036
+ import { Icon as Icon11 } from "@pactor-app/ui/components";
2037
2037
  import { Registry as Registry3 } from "@pactor-app/core";
2038
2038
  import { useEffect as useEffect9, useMemo as useMemo3, useRef as useRef11, useState as useState14, useSyncExternalStore } from "react";
2039
2039
 
@@ -3049,6 +3049,7 @@ function EmptyState({
3049
3049
 
3050
3050
  // src/view/MessageBubble.tsx
3051
3051
  import { useRef as useRef10, useState as useState13 } from "react";
3052
+ import { Icon as Icon10 } from "@pactor-app/ui/components";
3052
3053
 
3053
3054
  // src/view/ActivityTrace.tsx
3054
3055
  import { Icon as Icon8 } from "@pactor-app/ui/components";
@@ -3585,8 +3586,26 @@ function MessageEditForm({
3585
3586
  ] })
3586
3587
  ] });
3587
3588
  }
3589
+ function isAgentIconUrl(icon) {
3590
+ return /^(https?:|data:|\/)/.test(icon);
3591
+ }
3592
+ function AgentHeader({ agent }) {
3593
+ return /* @__PURE__ */ jsxs11("div", { className: "pactor-chat-message__agent", children: [
3594
+ agent.icon !== void 0 && (isAgentIconUrl(agent.icon) ? /* @__PURE__ */ jsx15(
3595
+ "img",
3596
+ {
3597
+ className: "pactor-chat-message__agent-icon",
3598
+ src: agent.icon,
3599
+ alt: "",
3600
+ "aria-hidden": true
3601
+ }
3602
+ ) : /* @__PURE__ */ jsx15("span", { className: "pactor-chat-message__agent-icon", "aria-hidden": true, children: /* @__PURE__ */ jsx15(Icon10, { name: agent.icon }) })),
3603
+ /* @__PURE__ */ jsx15("span", { className: "pactor-chat-message__agent-name", children: agent.name })
3604
+ ] });
3605
+ }
3588
3606
  function MessageBubble({
3589
3607
  message,
3608
+ agent,
3590
3609
  runtime,
3591
3610
  scope,
3592
3611
  showRegenerate = false,
@@ -3613,6 +3632,7 @@ function MessageBubble({
3613
3632
  (part) => part.type === "thinking" || part.type === "tool-call" || part.type === "tool-result"
3614
3633
  ));
3615
3634
  const showTime = message.role === "assistant" && !live && message.createdAt !== void 0;
3635
+ const agentIdentity = message.role === "assistant" ? message.agent ?? agent : void 0;
3616
3636
  return /* @__PURE__ */ jsxs11(
3617
3637
  "div",
3618
3638
  {
@@ -3631,6 +3651,7 @@ function MessageBubble({
3631
3651
  onCancel: () => setEditing(false)
3632
3652
  }
3633
3653
  ) : /* @__PURE__ */ jsxs11("div", { className: "pactor-chat-message__body", children: [
3654
+ agentIdentity && /* @__PURE__ */ jsx15(AgentHeader, { agent: agentIdentity }),
3634
3655
  showTrace && /* @__PURE__ */ jsx15(ActivityTrace, { message }),
3635
3656
  message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ jsx15("span", { className: "pactor-chat-message__pending", children: "\u2026" }) : groupArtifactParts(message.parts).map(
3636
3657
  (segment, index) => Array.isArray(segment) ? /* @__PURE__ */ jsx15(
@@ -3710,6 +3731,7 @@ function lastContentLength(messages) {
3710
3731
  function ChatView({
3711
3732
  store,
3712
3733
  transport,
3734
+ agent,
3713
3735
  onSend,
3714
3736
  safeRegistry,
3715
3737
  capabilities,
@@ -3917,6 +3939,7 @@ function ChatView({
3917
3939
  MessageBubble,
3918
3940
  {
3919
3941
  message,
3942
+ agent,
3920
3943
  runtime,
3921
3944
  scope,
3922
3945
  showRegenerate: message.id === regenerableMessageId,
@@ -3936,7 +3959,7 @@ function ChatView({
3936
3959
  className: "pactor-chat-scroll-bottom",
3937
3960
  onClick: scrollToBottom,
3938
3961
  children: [
3939
- /* @__PURE__ */ jsx16(Icon10, { name: "arrow-down", size: 13 }),
3962
+ /* @__PURE__ */ jsx16(Icon11, { name: "arrow-down", size: 13 }),
3940
3963
  "\u56DE\u5230\u5E95\u90E8"
3941
3964
  ]
3942
3965
  }
@@ -3949,7 +3972,7 @@ function ChatView({
3949
3972
  }
3950
3973
 
3951
3974
  // src/view/WorkspaceHeader.tsx
3952
- import { Icon as Icon11 } from "@pactor-app/ui/components";
3975
+ import { Icon as Icon12 } from "@pactor-app/ui/components";
3953
3976
  import { useEffect as useEffect10, useRef as useRef12, useState as useState15 } from "react";
3954
3977
 
3955
3978
  // src/export-markdown.ts
@@ -4110,7 +4133,7 @@ function WorkspaceHeader({
4110
4133
  title: "\u5BFC\u51FA Markdown",
4111
4134
  "aria-label": "\u5BFC\u51FA Markdown",
4112
4135
  onClick: handleExport,
4113
- children: /* @__PURE__ */ jsx17(Icon11, { name: "download", size: 15 })
4136
+ children: /* @__PURE__ */ jsx17(Icon12, { name: "download", size: 15 })
4114
4137
  },
4115
4138
  "export"
4116
4139
  ),
@@ -4122,7 +4145,7 @@ function WorkspaceHeader({
4122
4145
  title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
4123
4146
  "aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
4124
4147
  onClick: handleTheme,
4125
- children: theme === "dark" ? /* @__PURE__ */ jsx17(Icon11, { name: "sun", size: 15 }) : /* @__PURE__ */ jsx17(Icon11, { name: "moon", size: 15 })
4148
+ children: theme === "dark" ? /* @__PURE__ */ jsx17(Icon12, { name: "sun", size: 15 }) : /* @__PURE__ */ jsx17(Icon12, { name: "moon", size: 15 })
4126
4149
  },
4127
4150
  "theme"
4128
4151
  ),
@@ -4134,7 +4157,7 @@ function WorkspaceHeader({
4134
4157
  title: "\u6E05\u7A7A\u4F1A\u8BDD",
4135
4158
  "aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
4136
4159
  onClick: handleClear,
4137
- children: /* @__PURE__ */ jsx17(Icon11, { name: "trash", size: 15 })
4160
+ children: /* @__PURE__ */ jsx17(Icon12, { name: "trash", size: 15 })
4138
4161
  },
4139
4162
  "clear"
4140
4163
  )
@@ -4235,6 +4258,7 @@ function ChatComposition({
4235
4258
  services,
4236
4259
  title,
4237
4260
  greeting,
4261
+ agent,
4238
4262
  subtitle,
4239
4263
  suggestions,
4240
4264
  conversationId,
@@ -4404,6 +4428,7 @@ function ChatComposition({
4404
4428
  {
4405
4429
  store,
4406
4430
  transport: services.transport,
4431
+ agent,
4407
4432
  onSend: handleSend,
4408
4433
  safeRegistry: services.safeRegistry,
4409
4434
  capabilities: services.capabilities,
@@ -4585,7 +4610,7 @@ function createChatWorkspace(services) {
4585
4610
  }
4586
4611
 
4587
4612
  // src/view/Chat.tsx
4588
- import { createComponentRegistry, Icon as Icon12, RailTooltip } from "@pactor-app/ui/components";
4613
+ import { createComponentRegistry, Icon as Icon13, RailTooltip } from "@pactor-app/ui/components";
4589
4614
  import { Fragment as Fragment10, useEffect as useEffect11, useRef as useRef14 } from "react";
4590
4615
 
4591
4616
  // src/view/chrome/menu.tsx
@@ -4714,7 +4739,7 @@ function ChatSidebarMenu({
4714
4739
  drawer?.close();
4715
4740
  },
4716
4741
  children: [
4717
- item.icon !== void 0 ? /* @__PURE__ */ jsx22("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ jsx22(Icon12, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
4742
+ item.icon !== void 0 ? /* @__PURE__ */ jsx22("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ jsx22(Icon13, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
4718
4743
  /* @__PURE__ */ jsx22("span", { className: "pactor-chat-menu__label", children: item.label }),
4719
4744
  item.dot === true ? /* @__PURE__ */ jsx22("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
4720
4745
  item.badge !== void 0 ? /* @__PURE__ */ jsx22("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
@@ -4738,6 +4763,7 @@ function ChatSidebarMenu({
4738
4763
  function Chat({
4739
4764
  title,
4740
4765
  greeting,
4766
+ agent,
4741
4767
  subtitle,
4742
4768
  suggestions,
4743
4769
  conversationId,
@@ -4805,6 +4831,7 @@ function Chat({
4805
4831
  services,
4806
4832
  title,
4807
4833
  greeting,
4834
+ agent,
4808
4835
  subtitle,
4809
4836
  suggestions,
4810
4837
  conversationId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactor-app/chat",
3
- "version": "1.18.0",
3
+ "version": "1.18.1",
4
4
  "description": "Pactor chat: AI message rendering protocol (message model, streaming reducer, safe registry, capability action) and chat runtime view (ChatView / MessageBubble / PartRenderer / Composer / chat layout)",
5
5
  "keywords": [
6
6
  "pactor",
@@ -49,11 +49,11 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@pactor-app/core": "1.18.0",
53
- "@pactor-app/permission": "1.18.0",
54
- "@pactor-app/markdown": "1.18.0",
55
- "@pactor-app/runtime": "1.18.0",
56
- "@pactor-app/ui": "1.18.0"
52
+ "@pactor-app/core": "1.18.1",
53
+ "@pactor-app/markdown": "1.18.1",
54
+ "@pactor-app/ui": "1.18.1",
55
+ "@pactor-app/runtime": "1.18.1",
56
+ "@pactor-app/permission": "1.18.1"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "react": ">=18"
package/styles.css CHANGED
@@ -88,10 +88,12 @@
88
88
  --pactor-chat-shell-scrim: rgb(0 0 0 / 40%);
89
89
  /* 产出物面板(spec: chat-artifact-panel):桌面固定宽右栏。
90
90
  默认宽与对话列一致(--pactor-chat-content-width),
91
- 宽度夹取 [--pactor-chat-inspector-min-width, host 宽 2/3];
91
+ 宽度夹取 [--pactor-chat-inspector-min-width,
92
+ min(--pactor-chat-inspector-max-width, host 宽 2/3)];
92
93
  背景略深于聊天区底色,视觉上与消息流区分 */
93
94
  --pactor-chat-inspector-width: var(--pactor-chat-content-width);
94
95
  --pactor-chat-inspector-min-width: 480px;
96
+ --pactor-chat-inspector-max-width: 600px;
95
97
  --pactor-chat-inspector-bg: color-mix(
96
98
  in srgb,
97
99
  var(--pactor-chat-bg) 96%,
@@ -102,6 +104,10 @@
102
104
  /* 对话列左右最小内间距(spec: chat-artifact-panel / 拖拽调宽):
103
105
  面板调宽挤压剩余空间时,对话列左右始终保留该间距 */
104
106
  --pactor-chat-content-gutter: 16px;
107
+ /* 聊天区 header 与产物面板 header 的公共高度(min-height,border-box):
108
+ 两边内容自然高度不同(面板侧 menu-trigger 更高),经统一 min-height
109
+ 对齐,面板打开时两条分隔线同高;内容更高时自然撑开 */
110
+ --pactor-chat-header-height: 48px;
105
111
  }
106
112
 
107
113
  .pactor-chat-view {
@@ -221,8 +227,8 @@
221
227
  /* ------------------------------------------------------------
222
228
  * ChatWorkspace(spec: chat-dsl-page):createChatWorkspace 工厂
223
229
  * 返回组件的外层容器 = 对话列(ChatView);工作区头部(header)
224
- * 收进面板 host 的 __main 左列——面板打开时与对话区同宽(不覆盖
225
- * 面板上方),面板关闭时随 __main 通栏;不随对话列限宽。
230
+ * 收进面板 host 的 __main 左列——面板打开时随 __main 通栏(左贴
231
+ * 宿主边缘、右贴面板分隔线,不覆盖面板上方),不随对话列限宽。
226
232
  * ------------------------------------------------------------ */
227
233
 
228
234
  .pactor-chat-workspace {
@@ -232,8 +238,9 @@
232
238
  min-height: 0;
233
239
  /* 对话列缺省限宽居中(spec: chat-app-shell 嵌入契约):
234
240
  * shell content / 面板 host / 独立块级容器三场景统一生效。
235
- * width 用 calc 预留 gutter——产物栏调宽挤压时,max-width 限宽
236
- * 失效(剩余空间不足)后左右仍恒保留 --pactor-chat-content-gutter
241
+ * width 用 calc 预留 gutter——对话列包含块是 __main 左列(面板
242
+ * 宽度不计入 100% 基准),产物栏调宽挤压、max-width 限宽失效
243
+ * (剩余空间不足)后左右仍恒保留 --pactor-chat-content-gutter
237
244
  * 内间距,不会贴到容器边缘或面板分隔线 */
238
245
  width: calc(100% - 2 * var(--pactor-chat-content-gutter));
239
246
  max-width: var(--pactor-chat-content-width);
@@ -265,6 +272,9 @@
265
272
  padding: 10px 16px;
266
273
  border-bottom: 1px solid var(--pactor-chat-border);
267
274
  flex-shrink: 0;
275
+ /* 与产物面板 header 等高(--pactor-chat-header-height) */
276
+ box-sizing: border-box;
277
+ min-height: var(--pactor-chat-header-height);
268
278
  }
269
279
 
270
280
  .pactor-chat-workspace__title {
@@ -359,8 +369,8 @@
359
369
  * ------------------------------------------------------------ */
360
370
 
361
371
  /* 面板打开时的容器:行内容器 __row 承载左右两列——__main 左列
362
- * (header + 对话区,同宽;header 不覆盖面板上方)与面板右列
363
- * (独占全高);host 在 shell content 内撑满剩余高度与宽度 */
372
+ * (header + 对话区纵向堆叠;header 通栏、不覆盖面板上方)与面板
373
+ * 右列(独占全高);host 在 shell content 内撑满剩余高度与宽度 */
364
374
  .pactor-chat-inspector-host {
365
375
  display: flex;
366
376
  flex-direction: column;
@@ -371,8 +381,10 @@
371
381
  background: var(--pactor-chat-bg);
372
382
  }
373
383
 
374
- /* host 行内容器:__main 左列与面板的 flex 行(gutter 契约挂在行上——
375
- * __main 内的 header / 对话列共享行 padding 的左 gutter) */
384
+ /* host 行内容器:__main 左列与面板的 flex 行。对话列 gutter 契约
385
+ * 由对话列自身 calc 宽度保证(见 .pactor-chat-workspace)——容器侧
386
+ * 不加 padding/margin,否则 __main 内的 header 会被内缩,两端无法
387
+ * 贴到宿主边缘与面板分隔线 */
376
388
  .pactor-chat-inspector-host__row {
377
389
  display: flex;
378
390
  flex: 1;
@@ -381,7 +393,7 @@
381
393
  }
382
394
 
383
395
  /* __main 左列:header + 主区(AppShell / workspace)纵向堆叠,
384
- * 宽度 = 行宽减去面板宽(面板打开时 header 与对话区同宽) */
396
+ * 宽度 = 行宽减去面板宽(header 通栏:左贴宿主边缘、右贴面板分隔线) */
385
397
  .pactor-chat-inspector-host__main {
386
398
  display: flex;
387
399
  flex-direction: column;
@@ -397,28 +409,20 @@
397
409
  min-width: 0;
398
410
  }
399
411
 
400
- /* 对话列左右最小内间距(gutter 契约,spec: chat-artifact-panel / 拖拽调宽):
401
- * 对话列自身的 calc 宽度在 flex 行内会把面板宽度一并计入 100% 基准,
402
- * shrink 后 margin auto 塌到 0;因此面板打开时的 gutter 由容器侧保证——
403
- * 左:row padding-left;右:面板 margin-left(对话列与分隔线的间距)。
404
- * 面板关闭(:has 不命中)时不加 row padding,避免与对话列 calc 重复计算 */
405
- .pactor-chat-inspector-host__row:has(> .pactor-chat-inspector) {
406
- padding-left: var(--pactor-chat-content-gutter);
407
- }
408
-
409
- .pactor-chat-inspector-host__row > .pactor-chat-inspector {
410
- margin-left: var(--pactor-chat-content-gutter);
411
- }
412
-
413
412
  .pactor-chat-inspector {
414
413
  position: relative;
415
414
  display: flex;
416
415
  flex-direction: column;
417
- /* 默认宽对齐对话列;上限 host 宽 2/3(与拖拽夹取一致),下限 min-width 令牌。
416
+ /* 默认宽对齐对话列;上限 min(max-width 令牌 600px, host 宽 2/3)(与拖拽夹取一致),
417
+ * 下限 min-width 令牌。
418
418
  * max-width 是拖拽 inline 宽度的硬兜底:inline width 不能覆盖 max-width,
419
- * 拖拽夹取偏差 / 拖拽后窗口尺寸变化时面板也不会突破 2/3 上限 */
420
- width: min(var(--pactor-chat-inspector-width), calc(100% * 2 / 3));
421
- max-width: calc(100% * 2 / 3);
419
+ * 拖拽夹取偏差 / 拖拽后窗口尺寸变化时面板也不会突破上限 */
420
+ width: min(
421
+ var(--pactor-chat-inspector-width),
422
+ var(--pactor-chat-inspector-max-width),
423
+ calc(100% * 2 / 3)
424
+ );
425
+ max-width: min(var(--pactor-chat-inspector-max-width), calc(100% * 2 / 3));
422
426
  min-width: var(--pactor-chat-inspector-min-width);
423
427
  flex-shrink: 0;
424
428
  border-left: 1px solid var(--pactor-chat-border);
@@ -449,6 +453,9 @@
449
453
  padding: 10px 12px;
450
454
  border-bottom: 1px solid var(--pactor-chat-border);
451
455
  flex-shrink: 0;
456
+ /* 与聊天区 header 等高(--pactor-chat-header-height) */
457
+ box-sizing: border-box;
458
+ min-height: var(--pactor-chat-header-height);
452
459
  }
453
460
 
454
461
  .pactor-chat-inspector__title {
@@ -495,7 +502,9 @@
495
502
  gap: 6px;
496
503
  min-width: 0;
497
504
  max-width: 100%;
498
- padding: 3px 6px;
505
+ /* 纵向 padding 2px:自身 26.4px + header padding 20px + border 1px
506
+ * ≤ --pactor-chat-header-height(48px),不撑破两侧 header 等高 */
507
+ padding: 2px 6px;
499
508
  border-radius: var(--pactor-chat-radius-sm);
500
509
  cursor: pointer;
501
510
  color: var(--pactor-chat-fg);
@@ -1060,6 +1069,40 @@
1060
1069
  align-items: stretch;
1061
1070
  }
1062
1071
 
1072
+ /* assistant 消息顶部 Agent 身份行:图标 + 加粗名称 */
1073
+ .pactor-chat-message__agent {
1074
+ display: flex;
1075
+ align-items: center;
1076
+ gap: 6px;
1077
+ min-width: 0;
1078
+ font-size: 13px;
1079
+ line-height: 18px;
1080
+ color: var(--pactor-chat-fg);
1081
+ }
1082
+
1083
+ .pactor-chat-message__agent-icon {
1084
+ display: inline-flex;
1085
+ align-items: center;
1086
+ justify-content: center;
1087
+ flex-shrink: 0;
1088
+ width: 1.1em;
1089
+ height: 1.1em;
1090
+ color: var(--pactor-chat-muted-fg);
1091
+ }
1092
+
1093
+ img.pactor-chat-message__agent-icon {
1094
+ border-radius: var(--pactor-chat-radius-sm, 4px);
1095
+ object-fit: cover;
1096
+ }
1097
+
1098
+ .pactor-chat-message__agent-name {
1099
+ font-size: 1.1em;
1100
+ font-weight: 600;
1101
+ overflow: hidden;
1102
+ text-overflow: ellipsis;
1103
+ white-space: nowrap;
1104
+ }
1105
+
1063
1106
  /* system:居中弱提示 */
1064
1107
  .pactor-chat-message--system {
1065
1108
  align-items: center;