@qfei-design/make-ai-assistant 0.1.2 → 0.1.3
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/PUBLIC_API.md +4 -2
- package/README.md +4 -1
- package/dist/react/make-ai-assistant.d.ts +3 -1
- package/dist/react.cjs +1 -1
- package/dist/react.mjs +556 -463
- package/dist/styles.css +103 -87
- package/package.ai.json +4 -4
- package/package.json +1 -1
package/PUBLIC_API.md
CHANGED
|
@@ -36,8 +36,10 @@ Fetch SSE 实现时,从 `/sse` 入口导入 `createSseAssistantTransport`。
|
|
|
36
36
|
|
|
37
37
|
## React exports
|
|
38
38
|
|
|
39
|
-
- `MakeAiAssistant
|
|
40
|
-
|
|
39
|
+
- `MakeAiAssistant`:默认浮动入口与右侧抽屉;支持受控开关、自定义 launcher,以及
|
|
40
|
+
`assistantName` / `userName` 对双方消息显示名称的覆盖。
|
|
41
|
+
- `AssistantPanel`:不带 Drawer 的嵌入式会话面板;支持 `assistantName` / `userName`,
|
|
42
|
+
默认显示“AI 助手”和“你”。
|
|
41
43
|
- `ArtifactRenderer`:注册表驱动的单 Artifact 渲染器。
|
|
42
44
|
- `createPlatformArtifactRegistry`
|
|
43
45
|
- `platformArtifactTemplates`
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @qfei-design/make-ai-assistant@^0.1.
|
|
8
|
+
pnpm add @qfei-design/make-ai-assistant@^0.1.2
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick start
|
|
@@ -34,6 +34,9 @@ export function AppAssistant() {
|
|
|
34
34
|
|
|
35
35
|
`MakeAiAssistant` 默认渲染右下角动效入口和右侧抽屉。宿主可以使用 `open` / `onOpenChange` 受控管理开关,也可以用 `AssistantPanel` 嵌入自己的容器。
|
|
36
36
|
|
|
37
|
+
默认会话会以“你”和“AI 助手”区分双方消息。宿主可以通过 `userName` 与
|
|
38
|
+
`assistantName` 覆盖这两个显示名称;进度和可重试错误会显示在对应的 AI 回合中。
|
|
39
|
+
|
|
37
40
|
## Package provides
|
|
38
41
|
|
|
39
42
|
- Artifact V1 类型、运行时校验与 JSON Schema;
|
|
@@ -5,6 +5,8 @@ export interface AssistantPanelProps {
|
|
|
5
5
|
context: MakeAssistantHostContext;
|
|
6
6
|
transport: AssistantTransport;
|
|
7
7
|
registry?: ReactArtifactTemplateRegistry;
|
|
8
|
+
assistantName?: string;
|
|
9
|
+
userName?: string;
|
|
8
10
|
title?: string;
|
|
9
11
|
subtitle?: string;
|
|
10
12
|
suggestions?: string[];
|
|
@@ -13,7 +15,7 @@ export interface AssistantPanelProps {
|
|
|
13
15
|
onClose?: () => void;
|
|
14
16
|
onNewConversation?: () => void;
|
|
15
17
|
}
|
|
16
|
-
export declare function AssistantPanel({ context, onAction, onActionError, onClose, onNewConversation, registry: registryProp, subtitle, suggestions, title, transport, }: AssistantPanelProps): import("react").JSX.Element;
|
|
18
|
+
export declare function AssistantPanel({ assistantName, context, onAction, onActionError, onClose, onNewConversation, registry: registryProp, subtitle, suggestions, title, transport, userName, }: AssistantPanelProps): import("react").JSX.Element;
|
|
17
19
|
export interface MakeAiAssistantProps extends Omit<AssistantPanelProps, "onClose"> {
|
|
18
20
|
open?: boolean;
|
|
19
21
|
defaultOpen?: boolean;
|
package/dist/react.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),N=require("./index.cjs"),p=require("react"),c=require("./conversation-Yku9Lzj_.cjs");function ne({artifact:a,context:t,fallback:s,onAction:l,onActionError:o,registry:n}){const m=N.resolveArtifactTemplate(n,a,t);if(!m)return s?s(a):e.jsxs("section",{className:"make-ai-artifact make-ai-artifact--unsupported",role:"status",children:[e.jsx("strong",{children:"暂不支持展示此结果"}),e.jsxs("span",{children:["结果类型:",a.kind]})]});const f={context:t,onAction:l,onActionError:o};return m.template.render(a,t,f)}const y=(a,t,s)=>{if(a==null||a==="")return"—";if(typeof a=="boolean")return a?"是":"否";if(typeof a!="number")return`${a}${t?.unit??""}`;const l=t?.precision,o={maximumFractionDigits:l??2,minimumFractionDigits:l};t?.style==="currency"&&t.currency?(o.style="currency",o.currency=t.currency):t?.style==="percent"&&(o.style="percent");try{const n=t?.style==="percent"?a/100:a;return`${new Intl.NumberFormat(s,o).format(n)}${t?.unit??""}`}catch{return`${a}${t?.unit??""}`}},re=a=>{let t=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const l of a)t=Math.min(t,l),s=Math.max(s,l);return Number.isFinite(t)&&Number.isFinite(s)?{min:t,max:s}:{min:0,max:0}},ie=(a,t,s)=>{if(!s.onAction)return;const l=n=>{console.error("[make-ai-assistant] host action error handler failed",{actionId:a.id,artifactId:t.artifact.id,errorType:n instanceof Error?n.name:typeof n,intent:a.intent})},o=n=>{if(s.onActionError){try{Promise.resolve(s.onActionError(n,a,t)).catch(l)}catch(m){l(m)}return}console.error("[make-ai-assistant] host action failed",{actionId:a.id,artifactId:t.artifact.id,errorType:n instanceof Error?n.name:typeof n,intent:a.intent})};try{Promise.resolve(s.onAction(a,t)).catch(o)}catch(n){o(n)}},O=(a,t)=>a.actions?.length&&t.onAction?e.jsx("div",{className:"make-ai-artifact__actions",children:a.actions.map(s=>e.jsxs("button",{className:`make-ai-artifact__action make-ai-artifact__action--${s.appearance??"link"}`,type:"button",onClick:()=>ie(s,{artifact:a,context:t.context},t),children:[s.label,e.jsx("span",{"aria-hidden":"true",children:"→"})]},s.id))}):null,F=(a,t,s="")=>e.jsxs("section",{"aria-label":a.title??`${a.kind} result`,className:`make-ai-artifact ${s}`.trim(),"data-artifact-density":a.presentation?.density,"data-artifact-kind":a.kind,children:[a.title?e.jsx("h4",{className:"make-ai-artifact__title",children:a.title}):null,a.summary?e.jsx("p",{className:"make-ai-artifact__summary",children:a.summary}):null,t]}),Ie=({artifact:a,renderContext:t})=>{const s=a.data.delta,l=s?y(s.value,s.format==="percent"?{style:"percent"}:void 0,t.context.locale):void 0;return F(a,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__metric-value",children:y(a.data.value,a.data.format,t.context.locale)}),s?e.jsxs("div",{className:`make-ai-artifact__delta make-ai-artifact__delta--${s.direction??"flat"}`,children:[e.jsx("span",{"aria-hidden":"true",children:s.direction==="up"?"↗":s.direction==="down"?"↘":"→"}),e.jsx("span",{children:l}),s.label?e.jsx("span",{children:s.label}):null]}):null,a.data.context?e.jsx("p",{className:"make-ai-artifact__context",children:a.data.context}):null,O(a,t)]}),"make-ai-artifact--metric")},je=({artifact:a,renderContext:t})=>F(a,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__comparison",children:a.data.items.map(s=>e.jsxs("div",{className:"make-ai-artifact__comparison-item",children:[e.jsx("span",{children:s.label}),e.jsx("strong",{children:y(s.value,s.format,t.context.locale)}),s.hint?e.jsx("small",{children:s.hint}):null]},s.id))}),O(a,t)]}),"make-ai-artifact--comparison"),ve=({artifact:a,renderContext:t})=>{const s=a.data.series.flatMap(m=>m.points.map(f=>f.y)),{max:l,min:o}=re(s),n=l-o||1;return F(a,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__trend",children:a.data.series.map(m=>e.jsxs("div",{className:"make-ai-artifact__trend-series",children:[e.jsx("div",{className:"make-ai-artifact__trend-label",children:m.label}),e.jsx("div",{className:"make-ai-artifact__trend-bars",children:m.points.map((f,b)=>{const u=18+(f.y-o)/n*70;return e.jsxs("div",{className:"make-ai-artifact__trend-point",children:[e.jsx("span",{"aria-label":`${f.x}: ${y(f.y,m.format,t.context.locale)}`,className:"make-ai-artifact__trend-bar",role:"img",style:{height:`${u}%`},title:`${f.x}: ${y(f.y,m.format,t.context.locale)}`}),e.jsx("small",{children:f.x})]},`${f.x}-${b}`)})})]},m.id))}),O(a,t)]}),"make-ai-artifact--trend")},ge=({artifact:a,renderContext:t})=>{const{max:s}=re(a.data.items.map(o=>Math.abs(o.value))),l=Math.max(s,1);return F(a,e.jsxs(e.Fragment,{children:[e.jsx("ol",{className:"make-ai-artifact__ranking",children:a.data.items.map((o,n)=>e.jsxs("li",{children:[e.jsx("span",{className:"make-ai-artifact__rank",children:n+1}),e.jsxs("span",{className:"make-ai-artifact__ranking-label",children:[e.jsx("span",{children:o.label}),o.description?e.jsx("small",{children:o.description}):null]}),e.jsx("span",{className:"make-ai-artifact__ranking-track","aria-hidden":"true",children:e.jsx("span",{style:{width:`${Math.abs(o.value)/l*100}%`}})}),e.jsx("strong",{children:y(o.value,o.format,t.context.locale)})]},o.id))}),O(a,t)]}),"make-ai-artifact--ranking")},ke=(a,t)=>t.action??{id:`open-${t.id}`,label:t.title??t.id,intent:"open-record",target:{entityKey:a.data.entity.key,recordId:t.id}},ye=({artifact:a,renderContext:t})=>F(a,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__record-list",children:a.data.records.length===0?e.jsx("p",{className:"make-ai-artifact__empty",children:"没有符合条件的记录"}):a.data.records.map(s=>{const l=ke(a,s),o=e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:s.title??s.id}),e.jsx("span",{className:"make-ai-artifact__record-values",children:a.data.columns.map(n=>e.jsxs("span",{children:[e.jsx("small",{children:n.label}),y(s.values[n.key],n.format,t.context.locale)]},n.key))}),t.onAction?e.jsx("span",{"aria-hidden":"true",children:"›"}):null]});return t.onAction?e.jsx("button",{className:"make-ai-artifact__record",type:"button",onClick:()=>ie(l,{artifact:a,context:t.context},t),children:o},s.id):e.jsx("div",{className:"make-ai-artifact__record",children:o},s.id)})}),a.data.total!==void 0?e.jsxs("p",{className:"make-ai-artifact__record-total",children:["共 ",a.data.total," 条"]}):null,O(a,t)]}),"make-ai-artifact--record-list"),Ne=({artifact:a,renderContext:t})=>F(a,e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:`make-ai-artifact__notice make-ai-artifact__notice--${a.data.tone}`,children:[e.jsx("span",{"aria-hidden":"true",children:a.data.tone==="success"?"✓":a.data.tone==="warning"?"!":a.data.tone==="danger"?"×":"i"}),e.jsx("p",{children:a.data.body})]}),O(a,t)]}),"make-ai-artifact--notice"),$=(a,t,s)=>({id:a,kinds:[t],priority:0,render:s}),be=[$("platform.metric.default","metric",(a,t,s)=>e.jsx(Ie,{artifact:a,renderContext:s})),$("platform.comparison.default","comparison",(a,t,s)=>e.jsx(je,{artifact:a,renderContext:s})),$("platform.trend.default","trend",(a,t,s)=>e.jsx(ve,{artifact:a,renderContext:s})),$("platform.ranking.default","ranking",(a,t,s)=>e.jsx(ge,{artifact:a,renderContext:s})),$("platform.record-list.default","record-list",(a,t,s)=>e.jsx(ye,{artifact:a,renderContext:s})),$("platform.notice.default","notice",(a,t,s)=>e.jsx(Ne,{artifact:a,renderContext:s}))],oe=N.createArtifactTemplateRegistry(be).templates,ce=(a=oe)=>N.createArtifactTemplateRegistry(a),Te=a=>`${a}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`;class h extends Error{}const se=a=>{try{const t=a?.return?.();if(!t)return;Promise.resolve(t).catch(s=>{console.error("[make-ai-assistant] transport iterator close failed",{errorType:s instanceof Error?s.name:typeof s})})}catch(t){console.error("[make-ai-assistant] transport iterator close failed",{errorType:t instanceof Error?t.name:typeof t})}},le=()=>e.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"M12 2.8c.5 4.4 2.8 6.8 7.2 7.2-4.4.5-6.8 2.8-7.2 7.2-.5-4.4-2.8-6.8-7.2-7.2 4.4-.5 6.8-2.8 7.2-7.2Z"}),e.jsx("path",{d:"M18.3 16.1c.2 1.8 1.2 2.8 3 3-1.8.2-2.8 1.2-3 3-.2-1.8-1.2-2.8-3-3 1.8-.2 2.8-1.2 3-3Z"})]}),Ee=()=>e.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:e.jsx("path",{d:"m6 6 12 12M18 6 6 18"})}),Me=()=>e.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:e.jsx("path",{d:"M12 5v14M5 12h14"})}),we=()=>e.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"m4 4 17 8-17 8 3-8-3-8Z"}),e.jsx("path",{d:"M7 12h14"})]}),D=()=>e.jsx("span",{className:"make-ai-assistant__avatar","aria-hidden":"true",children:e.jsx(le,{})}),Se=(a,t,s,l,o)=>a.messages.map(n=>e.jsxs("article",{className:`make-ai-assistant__message make-ai-assistant__message--${n.role}`,children:[n.role==="assistant"?e.jsx(D,{}):null,e.jsxs("div",{className:"make-ai-assistant__message-stack",children:[n.content?e.jsx("div",{className:"make-ai-assistant__bubble",children:n.content}):n.status==="streaming"?e.jsxs("div",{className:"make-ai-assistant__typing","aria-label":"AI 正在思考",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]}):null,n.artifacts.map(m=>e.jsx(ne,{artifact:m,context:t,onAction:l,onActionError:o,registry:s},m.id))]})]},n.id));function de({context:a,onAction:t,onActionError:s,onClose:l,onNewConversation:o,registry:n,subtitle:m,suggestions:f=[],title:b="Make AI 助手",transport:u}){const[g,T]=p.useState(""),[d,j]=p.useState(c.createAssistantConversationState),[q,K]=p.useState(void 0),[me,ue]=p.useState(0),[E,H]=p.useState(()=>u.loadConversation?"loading":"ready"),M=p.useRef(void 0),w=p.useRef(void 0),S=p.useRef(0),Z=p.useRef(null),z=p.useRef(!0),G=p.useRef(a.app.id),J=p.useMemo(()=>n??ce(),[n]),U=i=>{const x=M.current,A=w.current?.iterator;return!x&&!A?!1:(S.current+=1,M.current=void 0,w.current=void 0,console.info("[make-ai-assistant] local run cancellation requested",{reason:i}),x?.abort(),se(A),!0)};p.useEffect(()=>()=>{U("unmount")},[]),p.useEffect(()=>{const i=u.loadConversation,x=G.current!==a.app.id;if(G.current=a.app.id,U("reinitialize"),x&&(T(""),z.current=!0),K(void 0),j(c.createAssistantConversationState()),!i){H("ready");return}const A=new AbortController;return H("loading"),console.info("[make-ai-assistant] conversation load start",{appId:a.app.id}),i.call(u,a,{signal:A.signal}).then(I=>{A.signal.aborted||(j(c.createAssistantConversationState(I)),H("ready"),console.info("[make-ai-assistant] conversation load success",{appId:a.app.id,messageCount:I.messages.length}))}).catch(I=>{A.signal.aborted||(console.error("[make-ai-assistant] conversation load failed",{appId:a.app.id,errorType:I instanceof Error?I.name:typeof I}),H("error"))}),()=>A.abort()},[a.app.id,me,u]),p.useEffect(()=>{const i=Z.current;if(!i||!z.current)return;const x=requestAnimationFrame(()=>{if(!z.current)return;const A=d.status==="streaming"||window.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth";typeof i.scrollTo=="function"?i.scrollTo({top:i.scrollHeight,behavior:A}):i.scrollTop=i.scrollHeight});return()=>cancelAnimationFrame(x)},[d.messages,d.status]);const pe=()=>{const i=Z.current;i&&(z.current=i.scrollHeight-i.scrollTop-i.clientHeight<=48)},Y=async i=>{const x=i.trim();if(!x||E!=="ready"||d.status==="streaming"||M.current)return;if(c.countCodePointsUpTo(x,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters){K(`输入内容过长,请控制在 ${c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters} 个字符以内`);return}const A={id:Te("user"),content:x},I=new AbortController,C=S.current+1;S.current=C,M.current=I,K(void 0),T(""),j(v=>c.appendUserMessage(v,A));try{let v=!1,_,Q=0,W=0,V=0;const L=new Map,X=new Set,ee=new Set([...d.messages.map(B=>B.id),A.id]),P=new Set,ae=u.run({threadId:d.threadId,message:A,context:a,capabilities:N.createArtifactCapabilities(J)},{signal:I.signal})[Symbol.asyncIterator]();for(w.current={iterator:ae,requestVersion:C};;){const B=await ae.next();if(S.current!==C||B.done)break;let r;try{r=c.parseAssistantEvent(B.value)}catch(k){throw new h(k instanceof Error?k.message:"Invalid assistant event")}if(r.type==="message.start"){if(_!==void 0&&_!==r.runId)throw new h("AI 助手响应 run id 不一致");if(_??=r.runId,W+=1,W>c.MAKE_AI_CONVERSATION_LIMITS.assistantMessagesPerRun)throw new h("AI 助手单次响应消息数量超过限制");if(ee.has(r.messageId))throw new h("AI 助手响应包含重复的 message id");ee.add(r.messageId),P.add(r.messageId),L.set(r.messageId,0)}if(r.type==="message.delta"){if(!P.has(r.messageId))throw new h("AI 助手响应事件顺序无效");const k=L.get(r.messageId)??0,R=c.countCodePointsUpTo(r.delta,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters-V);if(V+R>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)throw new h("AI 助手响应文本超过大小限制");V+=R,L.set(r.messageId,k+R)}if(r.type==="message.replace"){if(!P.has(r.messageId))throw new h("AI 助手响应事件顺序无效");const k=L.get(r.messageId)??0,R=c.countCodePointsUpTo(r.content,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters),te=V-k+R;if(te>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)throw new h("AI 助手响应文本超过大小限制");V=te,L.set(r.messageId,R)}if(r.type==="run.progress"){if(_!==void 0&&_!==r.runId)throw new h("AI 助手响应 run id 不一致");_??=r.runId}if(r.type==="artifact"){if(!P.has(r.messageId))throw new h("AI 助手响应事件顺序无效");if(Q+=1,Q>c.MAKE_AI_CONVERSATION_LIMITS.artifactsPerRun)throw new h("AI 助手单次响应 Artifact 数量超过限制");if(X.has(r.artifact.id))throw new h("AI 助手响应包含重复的 Artifact id");X.add(r.artifact.id)}if(r.type==="message.complete"&&!P.delete(r.messageId))throw new h("AI 助手响应事件顺序无效");if(r.type==="run.complete"&&_!==void 0&&_!==r.runId)throw new h("AI 助手响应 run id 不一致");if(r.type==="run.cancelled"&&r.runId!==void 0&&_!==void 0&&_!==r.runId)throw new h("AI 助手响应 run id 不一致");if(j(k=>c.reduceAssistantEvent(k,r)),r.type==="error"||r.type==="run.cancelled"||r.type==="run.complete"){v=!0;break}}if(!v)throw new h("AI 助手流式响应在终止事件前结束")}catch(v){if(S.current!==C)return;if(I.signal.aborted){j(_=>c.reduceAssistantEvent(_,{type:"run.cancelled"}));return}console.error("[make-ai-assistant] assistant run failed",{appId:a.app.id,errorType:v instanceof Error?v.name:typeof v}),j(_=>c.reduceAssistantEvent(_,{type:"error",code:"TRANSPORT_ERROR",message:v instanceof h?v.message:"连接失败,请重试",retryable:!0}))}finally{S.current===C&&M.current===I&&(M.current=void 0),w.current?.requestVersion===C&&(se(w.current.iterator),w.current=void 0)}},he=i=>{i.preventDefault(),Y(g)},fe=i=>{i.key==="Enter"&&!i.shiftKey&&!i.nativeEvent.isComposing&&(i.preventDefault(),Y(g))},_e=()=>{U("stop")&&j(i=>c.reduceAssistantEvent(i,{type:"run.cancelled"}))},Ae=()=>{U("new-conversation"),T(""),K(void 0),j(c.createAssistantConversationState()),o?.()},xe=u.features?.remoteCancellation===!1?"停止接收":"停止生成";return e.jsxs("section",{className:"make-ai-assistant make-ai-assistant__panel",children:[e.jsxs("header",{className:"make-ai-assistant__header",children:[e.jsx(D,{}),e.jsxs("div",{children:[e.jsx("h2",{children:b}),e.jsxs("p",{children:[e.jsx("span",{className:"make-ai-assistant__online-dot"}),m??a.app.name??"当前应用"]})]}),e.jsxs("div",{className:"make-ai-assistant__header-actions",children:[u.features?.newConversation!==!1?e.jsx("button",{"aria-label":"新建对话",className:"make-ai-assistant__icon-button",type:"button",onClick:Ae,children:e.jsx(Me,{})}):null,l?e.jsx("button",{"aria-label":"关闭 Make AI 助手",className:"make-ai-assistant__icon-button",type:"button",onClick:l,children:e.jsx(Ee,{})}):null]})]}),e.jsxs("div",{className:"make-ai-assistant__privacy-note",role:"note",children:[e.jsx("span",{"aria-hidden":"true",children:"◇"}),"当前页面上下文会随请求发送,数据权限以宿主服务端校验结果为准"]}),e.jsxs("div",{className:"make-ai-assistant__body","aria-live":"polite",ref:Z,onScroll:pe,children:[E==="loading"?e.jsxs("div",{className:"make-ai-assistant__empty",role:"status",children:[e.jsx(D,{}),e.jsx("h3",{children:"正在恢复对话"}),e.jsx("p",{children:"正在读取当前 App 的历史消息…"})]}):E==="error"?e.jsxs("div",{className:"make-ai-assistant__empty",role:"alert",children:[e.jsx(D,{}),e.jsx("h3",{children:"暂时无法加载对话"}),e.jsx("p",{children:"请检查网络后重试。"}),e.jsx("button",{className:"make-ai-assistant__retry",type:"button",onClick:()=>ue(i=>i+1),children:"重新加载"})]}):d.messages.length===0?e.jsxs("div",{className:"make-ai-assistant__empty",children:[e.jsx(D,{}),e.jsx("h3",{children:"有什么可以帮你?"}),e.jsx("p",{children:"我会结合当前 App 和页面上下文理解问题,并用适合的方式展示结果。"})]}):Se(d,a,J,t,s),d.progress?e.jsxs("div",{className:"make-ai-assistant__progress",role:"status",children:[e.jsx("span",{"aria-hidden":"true"}),d.progress.message]}):null,d.error?e.jsxs("div",{className:"make-ai-assistant__error",role:"alert",children:[e.jsx("strong",{children:"暂时无法完成"}),e.jsx("span",{children:d.error.message})]}):null]}),e.jsxs("footer",{className:"make-ai-assistant__composer-region",children:[E==="ready"&&f.length>0&&d.messages.length===0?e.jsx("div",{className:"make-ai-assistant__suggestions","aria-label":"推荐问题",children:f.map((i,x)=>e.jsx("button",{type:"button",onClick:()=>{Y(i)},children:i},`${x}-${i}`))}):null,e.jsxs("form",{className:"make-ai-assistant__composer",onSubmit:he,children:[e.jsx("textarea",{"aria-label":"向 Make AI 助手提问","aria-describedby":q?"make-ai-composer-error":void 0,"aria-invalid":q?!0:void 0,autoFocus:!0,disabled:E!=="ready"||d.status==="streaming",placeholder:`询问当前 ${a.app.name??"App"} 中的数据…`,rows:2,value:g,onChange:i=>{T(i.currentTarget.value),K(void 0)},onKeyDown:fe}),d.status==="streaming"?e.jsx("button",{"aria-label":xe,className:"make-ai-assistant__send make-ai-assistant__send--stop",type:"button",onClick:_e,children:e.jsx("span",{"aria-hidden":"true"})}):e.jsx("button",{"aria-label":"发送",className:"make-ai-assistant__send",disabled:E!=="ready"||!g.trim(),type:"submit",children:e.jsx(we,{})})]}),q?e.jsx("p",{id:"make-ai-composer-error",role:"alert",children:q}):null,e.jsx("p",{children:"AI 生成的结果可能存在偏差,重要数据请核对明细。"})]})]})}function Ce({defaultOpen:a=!1,hideLauncher:t=!1,launcher:s,onOpenChange:l,open:o,...n}){const[m,f]=p.useState(a),b=p.useRef(null),u=o??m,g=d=>{o===void 0&&f(d),l?.(d),d||requestAnimationFrame(()=>b.current?.focus())},T=()=>g(!u);return p.useEffect(()=>{if(!u)return;const d=j=>{j.key==="Escape"&&(g(!1),requestAnimationFrame(()=>b.current?.focus()))};return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[l,u]),e.jsxs("div",{className:"make-ai-assistant","data-open":u||void 0,children:[!t&&(!u||s)?s?s({open:u,toggle:T}):e.jsxs("button",{"aria-label":u?"关闭 Make AI 助手":"打开 Make AI 助手","aria-expanded":u,className:"make-ai-assistant__launcher",ref:b,type:"button",onClick:T,children:[e.jsx("span",{className:"make-ai-assistant__launcher-orbit","aria-hidden":"true"}),e.jsx(le,{})]}):null,u?e.jsx("aside",{"aria-label":"Make AI 助手","aria-modal":"false",className:"make-ai-assistant__drawer",role:"dialog",children:e.jsx(de,{...n,onClose:()=>g(!1)})}):null]})}exports.createArtifactCapabilities=N.createArtifactCapabilities;exports.createArtifactTemplateRegistry=N.createArtifactTemplateRegistry;exports.extendArtifactTemplateRegistry=N.extendArtifactTemplateRegistry;exports.resolveArtifactTemplate=N.resolveArtifactTemplate;exports.MAKE_AI_ARTIFACT_KINDS=c.MAKE_AI_ARTIFACT_KINDS;exports.MAKE_AI_ARTIFACT_LIMITS=c.MAKE_AI_ARTIFACT_LIMITS;exports.MAKE_AI_ARTIFACT_SCHEMA_VERSION=c.MAKE_AI_ARTIFACT_SCHEMA_VERSION;exports.MAKE_AI_CONVERSATION_LIMITS=c.MAKE_AI_CONVERSATION_LIMITS;exports.appendUserMessage=c.appendUserMessage;exports.createAssistantConversationState=c.createAssistantConversationState;exports.parseArtifact=c.parseArtifact;exports.parseAssistantEvent=c.parseAssistantEvent;exports.reduceAssistantEvent=c.reduceAssistantEvent;exports.validateArtifact=c.validateArtifact;exports.ArtifactRenderer=ne;exports.AssistantPanel=de;exports.MakeAiAssistant=Ce;exports.createPlatformArtifactRegistry=ce;exports.formatArtifactValue=y;exports.platformArtifactTemplates=oe;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),M=require("./index.cjs"),p=require("react"),c=require("./conversation-Yku9Lzj_.cjs");function le({artifact:s,context:a,fallback:t,onAction:l,onActionError:r,registry:o}){const u=M.resolveArtifactTemplate(o,s,a);if(!u)return t?t(s):e.jsxs("section",{className:"make-ai-artifact make-ai-artifact--unsupported",role:"status",children:[e.jsx("strong",{children:"暂不支持展示此结果"}),e.jsxs("span",{children:["结果类型:",s.kind]})]});const h={context:a,onAction:l,onActionError:r};return u.template.render(s,a,h)}const T=(s,a,t)=>{if(s==null||s==="")return"—";if(typeof s=="boolean")return s?"是":"否";if(typeof s!="number")return`${s}${a?.unit??""}`;const l=a?.precision,r={maximumFractionDigits:l??2,minimumFractionDigits:l};a?.style==="currency"&&a.currency?(r.style="currency",r.currency=a.currency):a?.style==="percent"&&(r.style="percent");try{const o=a?.style==="percent"?s/100:s;return`${new Intl.NumberFormat(t,r).format(o)}${a?.unit??""}`}catch{return`${s}${a?.unit??""}`}},de=s=>{let a=Number.POSITIVE_INFINITY,t=Number.NEGATIVE_INFINITY;for(const l of s)a=Math.min(a,l),t=Math.max(t,l);return Number.isFinite(a)&&Number.isFinite(t)?{min:a,max:t}:{min:0,max:0}},me=(s,a,t)=>{if(!t.onAction)return;const l=o=>{console.error("[make-ai-assistant] host action error handler failed",{actionId:s.id,artifactId:a.artifact.id,errorType:o instanceof Error?o.name:typeof o,intent:s.intent})},r=o=>{if(t.onActionError){try{Promise.resolve(t.onActionError(o,s,a)).catch(l)}catch(u){l(u)}return}console.error("[make-ai-assistant] host action failed",{actionId:s.id,artifactId:a.artifact.id,errorType:o instanceof Error?o.name:typeof o,intent:s.intent})};try{Promise.resolve(t.onAction(s,a)).catch(r)}catch(o){r(o)}},V=(s,a)=>s.actions?.length&&a.onAction?e.jsx("div",{className:"make-ai-artifact__actions",children:s.actions.map(t=>e.jsxs("button",{className:`make-ai-artifact__action make-ai-artifact__action--${t.appearance??"link"}`,type:"button",onClick:()=>me(t,{artifact:s,context:a.context},a),children:[t.label,e.jsx("span",{"aria-hidden":"true",children:"→"})]},t.id))}):null,L=(s,a,t="")=>e.jsxs("section",{"aria-label":s.title??`${s.kind} result`,className:`make-ai-artifact ${t}`.trim(),"data-artifact-density":s.presentation?.density,"data-artifact-kind":s.kind,children:[s.title?e.jsx("h4",{className:"make-ai-artifact__title",children:s.title}):null,s.summary?e.jsx("p",{className:"make-ai-artifact__summary",children:s.summary}):null,a]}),Ee=({artifact:s,renderContext:a})=>{const t=s.data.delta,l=t?T(t.value,t.format==="percent"?{style:"percent"}:void 0,a.context.locale):void 0;return L(s,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__metric-value",children:T(s.data.value,s.data.format,a.context.locale)}),t?e.jsxs("div",{className:`make-ai-artifact__delta make-ai-artifact__delta--${t.direction??"flat"}`,children:[e.jsx("span",{"aria-hidden":"true",children:t.direction==="up"?"↗":t.direction==="down"?"↘":"→"}),e.jsx("span",{children:l}),t.label?e.jsx("span",{children:t.label}):null]}):null,s.data.context?e.jsx("p",{className:"make-ai-artifact__context",children:s.data.context}):null,V(s,a)]}),"make-ai-artifact--metric")},Se=({artifact:s,renderContext:a})=>L(s,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__comparison",children:s.data.items.map(t=>e.jsxs("div",{className:"make-ai-artifact__comparison-item",children:[e.jsx("span",{children:t.label}),e.jsx("strong",{children:T(t.value,t.format,a.context.locale)}),t.hint?e.jsx("small",{children:t.hint}):null]},t.id))}),V(s,a)]}),"make-ai-artifact--comparison"),we=({artifact:s,renderContext:a})=>{const t=s.data.series.flatMap(u=>u.points.map(h=>h.y)),{max:l,min:r}=de(t),o=l-r||1;return L(s,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__trend",children:s.data.series.map(u=>e.jsxs("div",{className:"make-ai-artifact__trend-series",children:[e.jsx("div",{className:"make-ai-artifact__trend-label",children:u.label}),e.jsx("div",{className:"make-ai-artifact__trend-bars",children:u.points.map((h,k)=>{const _=18+(h.y-r)/o*70;return e.jsxs("div",{className:"make-ai-artifact__trend-point",children:[e.jsx("span",{"aria-label":`${h.x}: ${T(h.y,u.format,a.context.locale)}`,className:"make-ai-artifact__trend-bar",role:"img",style:{height:`${_}%`},title:`${h.x}: ${T(h.y,u.format,a.context.locale)}`}),e.jsx("small",{children:h.x})]},`${h.x}-${k}`)})})]},u.id))}),V(s,a)]}),"make-ai-artifact--trend")},Ce=({artifact:s,renderContext:a})=>{const{max:t}=de(s.data.items.map(r=>Math.abs(r.value))),l=Math.max(t,1);return L(s,e.jsxs(e.Fragment,{children:[e.jsx("ol",{className:"make-ai-artifact__ranking",children:s.data.items.map((r,o)=>e.jsxs("li",{children:[e.jsx("span",{className:"make-ai-artifact__rank",children:o+1}),e.jsxs("span",{className:"make-ai-artifact__ranking-label",children:[e.jsx("span",{children:r.label}),r.description?e.jsx("small",{children:r.description}):null]}),e.jsx("span",{className:"make-ai-artifact__ranking-track","aria-hidden":"true",children:e.jsx("span",{style:{width:`${Math.abs(r.value)/l*100}%`}})}),e.jsx("strong",{children:T(r.value,r.format,a.context.locale)})]},r.id))}),V(s,a)]}),"make-ai-artifact--ranking")},Re=(s,a)=>a.action??{id:`open-${a.id}`,label:a.title??a.id,intent:"open-record",target:{entityKey:s.data.entity.key,recordId:a.id}},$e=({artifact:s,renderContext:a})=>L(s,e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"make-ai-artifact__record-list",children:s.data.records.length===0?e.jsx("p",{className:"make-ai-artifact__empty",children:"没有符合条件的记录"}):s.data.records.map(t=>{const l=Re(s,t),r=e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:t.title??t.id}),e.jsx("span",{className:"make-ai-artifact__record-values",children:s.data.columns.map(o=>e.jsxs("span",{children:[e.jsx("small",{children:o.label}),T(t.values[o.key],o.format,a.context.locale)]},o.key))}),a.onAction?e.jsx("span",{"aria-hidden":"true",children:"›"}):null]});return a.onAction?e.jsx("button",{className:"make-ai-artifact__record",type:"button",onClick:()=>me(l,{artifact:s,context:a.context},a),children:r},t.id):e.jsx("div",{className:"make-ai-artifact__record",children:r},t.id)})}),s.data.total!==void 0?e.jsxs("p",{className:"make-ai-artifact__record-total",children:["共 ",s.data.total," 条"]}):null,V(s,a)]}),"make-ai-artifact--record-list"),Oe=({artifact:s,renderContext:a})=>L(s,e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:`make-ai-artifact__notice make-ai-artifact__notice--${s.data.tone}`,children:[e.jsx("span",{"aria-hidden":"true",children:s.data.tone==="success"?"✓":s.data.tone==="warning"?"!":s.data.tone==="danger"?"×":"i"}),e.jsx("p",{children:s.data.body})]}),V(s,a)]}),"make-ai-artifact--notice"),F=(s,a,t)=>({id:s,kinds:[a],priority:0,render:t}),Fe=[F("platform.metric.default","metric",(s,a,t)=>e.jsx(Ee,{artifact:s,renderContext:t})),F("platform.comparison.default","comparison",(s,a,t)=>e.jsx(Se,{artifact:s,renderContext:t})),F("platform.trend.default","trend",(s,a,t)=>e.jsx(we,{artifact:s,renderContext:t})),F("platform.ranking.default","ranking",(s,a,t)=>e.jsx(Ce,{artifact:s,renderContext:t})),F("platform.record-list.default","record-list",(s,a,t)=>e.jsx($e,{artifact:s,renderContext:t})),F("platform.notice.default","notice",(s,a,t)=>e.jsx(Oe,{artifact:s,renderContext:t}))],ue=M.createArtifactTemplateRegistry(Fe).templates,pe=(s=ue)=>M.createArtifactTemplateRegistry(s),Ke=s=>`${s}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`;class f extends Error{}const oe=s=>{try{const a=s?.return?.();if(!a)return;Promise.resolve(a).catch(t=>{console.error("[make-ai-assistant] transport iterator close failed",{errorType:t instanceof Error?t.name:typeof t})})}catch(a){console.error("[make-ai-assistant] transport iterator close failed",{errorType:a instanceof Error?a.name:typeof a})}},he=()=>e.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"M12 2.8c.5 4.4 2.8 6.8 7.2 7.2-4.4.5-6.8 2.8-7.2 7.2-.5-4.4-2.8-6.8-7.2-7.2 4.4-.5 6.8-2.8 7.2-7.2Z"}),e.jsx("path",{d:"M18.3 16.1c.2 1.8 1.2 2.8 3 3-1.8.2-2.8 1.2-3 3-.2-1.8-1.2-2.8-3-3 1.8-.2 2.8-1.2 3-3Z"})]}),Ve=()=>e.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:e.jsx("path",{d:"m6 6 12 12M18 6 6 18"})}),Le=()=>e.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:e.jsx("path",{d:"M12 5v14M5 12h14"})}),Pe=()=>e.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[e.jsx("path",{d:"m4 4 17 8-17 8 3-8-3-8Z"}),e.jsx("path",{d:"M7 12h14"})]}),K=()=>e.jsx("span",{className:"make-ai-assistant__avatar","aria-hidden":"true",children:e.jsx(he,{})}),fe=s=>{for(let a=s.messages.length-1;a>=0;a-=1){const t=s.messages[a];if(t.role==="assistant"&&t.status==="streaming")return t.id}},qe=s=>{for(let a=s.messages.length-1;a>=0;a-=1)if(s.messages[a].role==="user")return a;return-1},_e=s=>{const a=qe(s);if(!(a<0))for(let t=s.messages.length-1;t>a;t-=1){const l=s.messages[t];if(l.role==="assistant")return l.id}},ge=({error:s,onRetry:a})=>e.jsxs("div",{className:"make-ai-assistant__message-status make-ai-assistant__message-status--error",role:"alert",children:[e.jsx("strong",{children:"本次请求未完成"}),e.jsx("span",{children:s.message}),s.retryable&&a?e.jsx("button",{className:"make-ai-assistant__retry",type:"button",onClick:a,children:"重新发送"}):null]}),ce=({assistantName:s,error:a,onRetry:t,progress:l})=>{const r=a?"error":"progress",o=a?.message??l;return o?e.jsxs("article",{"aria-label":`${s}的${r==="error"?"错误消息":"状态消息"}`,className:`make-ai-assistant__message make-ai-assistant__message--assistant make-ai-assistant__message--${r}`,"data-message-role":"assistant","data-message-state":r,children:[e.jsx(K,{}),e.jsxs("div",{className:"make-ai-assistant__message-stack",children:[e.jsx("span",{className:"make-ai-assistant__message-sender",children:s}),a?e.jsx(ge,{error:a,onRetry:t}):e.jsxs("div",{className:"make-ai-assistant__progress",role:"status",children:[e.jsx("span",{"aria-hidden":"true"}),e.jsx("span",{children:o})]})]})]}):null},De=(s,a,t,l,r,o,u,h)=>{const k=_e(s),_=fe(s);return s.messages.map(d=>{const E=d.role==="assistant",A=d.id===_,y=d.id===k&&s.error,m=E?o:h;return e.jsxs("article",{"aria-label":`${m}的消息`,className:`make-ai-assistant__message make-ai-assistant__message--${d.role}`,"data-message-role":d.role,"data-message-state":y?"error":void 0,"data-message-status":d.status,children:[E?e.jsx(K,{}):null,e.jsxs("div",{className:"make-ai-assistant__message-stack",children:[e.jsx("span",{className:"make-ai-assistant__message-sender",children:m}),d.content?e.jsx("div",{className:"make-ai-assistant__bubble",children:d.content}):d.status==="streaming"?e.jsxs("div",{className:"make-ai-assistant__typing","aria-label":`${o}正在思考`,children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]}):null,A&&s.progress?e.jsxs("div",{className:"make-ai-assistant__progress",role:"status",children:[e.jsx("span",{"aria-hidden":"true"}),e.jsx("span",{children:s.progress.message})]}):null,y?e.jsx(ge,{error:y,onRetry:u}):null,d.artifacts.map(j=>e.jsx(le,{artifact:j,context:a,onAction:l,onActionError:r,registry:t},j.id))]})]},d.id)})};function Ae({assistantName:s="AI 助手",context:a,onAction:t,onActionError:l,onClose:r,onNewConversation:o,registry:u,subtitle:h,suggestions:k=[],title:_="Make AI 助手",transport:d,userName:E="你"}){const[A,y]=p.useState(""),[m,j]=p.useState(c.createAssistantConversationState),[H,P]=p.useState(void 0),[xe,Ie]=p.useState(0),[S,z]=p.useState(()=>d.loadConversation?"loading":"ready"),w=p.useRef(void 0),C=p.useRef(void 0),R=p.useRef(0),Q=p.useRef(null),B=p.useRef(!0),W=p.useRef(a.app.id),X=p.useMemo(()=>u??pe(),[u]),Z=n=>{const I=w.current,x=C.current?.iterator;return!I&&!x?!1:(R.current+=1,w.current=void 0,C.current=void 0,console.info("[make-ai-assistant] local run cancellation requested",{reason:n}),I?.abort(),oe(x),!0)};p.useEffect(()=>()=>{Z("unmount")},[]),p.useEffect(()=>{const n=d.loadConversation,I=W.current!==a.app.id;if(W.current=a.app.id,Z("reinitialize"),I&&(y(""),B.current=!0),P(void 0),j(c.createAssistantConversationState()),!n){z("ready");return}const x=new AbortController;return z("loading"),console.info("[make-ai-assistant] conversation load start",{appId:a.app.id}),n.call(d,a,{signal:x.signal}).then(v=>{x.signal.aborted||(j(c.createAssistantConversationState(v)),z("ready"),console.info("[make-ai-assistant] conversation load success",{appId:a.app.id,messageCount:v.messages.length}))}).catch(v=>{x.signal.aborted||(console.error("[make-ai-assistant] conversation load failed",{appId:a.app.id,errorType:v instanceof Error?v.name:typeof v}),z("error"))}),()=>x.abort()},[a.app.id,xe,d]),p.useEffect(()=>{const n=Q.current;if(!n||!B.current)return;const I=requestAnimationFrame(()=>{if(!B.current)return;const x=m.status==="streaming"||window.matchMedia?.("(prefers-reduced-motion: reduce)").matches?"auto":"smooth";typeof n.scrollTo=="function"?n.scrollTo({top:n.scrollHeight,behavior:x}):n.scrollTop=n.scrollHeight});return()=>cancelAnimationFrame(I)},[m.messages,m.status]);const je=()=>{const n=Q.current;n&&(B.current=n.scrollHeight-n.scrollTop-n.clientHeight<=48)},Y=async n=>{const I=n.trim();if(!I||S!=="ready"||m.status==="streaming"||w.current)return;if(c.countCodePointsUpTo(I,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters){P(`输入内容过长,请控制在 ${c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters} 个字符以内`);return}const x={id:Ke("user"),content:I},v=new AbortController,$=R.current+1;R.current=$,w.current=v,P(void 0),y(""),j(N=>c.appendUserMessage(N,x));try{let N=!1,g,se=0,ae=0,q=0;const D=new Map,te=new Set,re=new Set([...m.messages.map(J=>J.id),x.id]),U=new Set,ne=d.run({threadId:m.threadId,message:x,context:a,capabilities:M.createArtifactCapabilities(X)},{signal:v.signal})[Symbol.asyncIterator]();for(C.current={iterator:ne,requestVersion:$};;){const J=await ne.next();if(R.current!==$||J.done)break;let i;try{i=c.parseAssistantEvent(J.value)}catch(b){throw new f(b instanceof Error?b.message:"Invalid assistant event")}if(i.type==="message.start"){if(g!==void 0&&g!==i.runId)throw new f("AI 助手响应 run id 不一致");if(g??=i.runId,ae+=1,ae>c.MAKE_AI_CONVERSATION_LIMITS.assistantMessagesPerRun)throw new f("AI 助手单次响应消息数量超过限制");if(re.has(i.messageId))throw new f("AI 助手响应包含重复的 message id");re.add(i.messageId),U.add(i.messageId),D.set(i.messageId,0)}if(i.type==="message.delta"){if(!U.has(i.messageId))throw new f("AI 助手响应事件顺序无效");const b=D.get(i.messageId)??0,O=c.countCodePointsUpTo(i.delta,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters-q);if(q+O>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)throw new f("AI 助手响应文本超过大小限制");q+=O,D.set(i.messageId,b+O)}if(i.type==="message.replace"){if(!U.has(i.messageId))throw new f("AI 助手响应事件顺序无效");const b=D.get(i.messageId)??0,O=c.countCodePointsUpTo(i.content,c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters),ie=q-b+O;if(ie>c.MAKE_AI_CONVERSATION_LIMITS.messageCharacters)throw new f("AI 助手响应文本超过大小限制");q=ie,D.set(i.messageId,O)}if(i.type==="run.progress"){if(g!==void 0&&g!==i.runId)throw new f("AI 助手响应 run id 不一致");g??=i.runId}if(i.type==="artifact"){if(!U.has(i.messageId))throw new f("AI 助手响应事件顺序无效");if(se+=1,se>c.MAKE_AI_CONVERSATION_LIMITS.artifactsPerRun)throw new f("AI 助手单次响应 Artifact 数量超过限制");if(te.has(i.artifact.id))throw new f("AI 助手响应包含重复的 Artifact id");te.add(i.artifact.id)}if(i.type==="message.complete"&&!U.delete(i.messageId))throw new f("AI 助手响应事件顺序无效");if(i.type==="run.complete"&&g!==void 0&&g!==i.runId)throw new f("AI 助手响应 run id 不一致");if(i.type==="run.cancelled"&&i.runId!==void 0&&g!==void 0&&g!==i.runId)throw new f("AI 助手响应 run id 不一致");if(j(b=>c.reduceAssistantEvent(b,i)),i.type==="error"||i.type==="run.cancelled"||i.type==="run.complete"){N=!0;break}}if(!N)throw new f("AI 助手流式响应在终止事件前结束")}catch(N){if(R.current!==$)return;if(v.signal.aborted){j(g=>c.reduceAssistantEvent(g,{type:"run.cancelled"}));return}console.error("[make-ai-assistant] assistant run failed",{appId:a.app.id,errorType:N instanceof Error?N.name:typeof N}),j(g=>c.reduceAssistantEvent(g,{type:"error",code:"TRANSPORT_ERROR",message:N instanceof f?N.message:"连接失败,请重试",retryable:!0}))}finally{R.current===$&&w.current===v&&(w.current=void 0),C.current?.requestVersion===$&&(oe(C.current.iterator),C.current=void 0)}},ve=n=>{n.preventDefault(),Y(A)},ke=n=>{n.key==="Enter"&&!n.shiftKey&&!n.nativeEvent.isComposing&&(n.preventDefault(),Y(A))},ye=()=>{Z("stop")&&j(n=>c.reduceAssistantEvent(n,{type:"run.cancelled"}))},Ne=()=>{Z("new-conversation"),y(""),P(void 0),j(c.createAssistantConversationState()),o?.()},be=d.features?.remoteCancellation===!1?"停止接收":"停止生成",Te=fe(m),Me=_e(m),G=[...m.messages].reverse().find(n=>n.role==="user"),ee=()=>{G&&Y(G.content)};return e.jsxs("section",{className:"make-ai-assistant make-ai-assistant__panel",children:[e.jsxs("header",{className:"make-ai-assistant__header",children:[e.jsx(K,{}),e.jsxs("div",{children:[e.jsx("h2",{children:_}),e.jsx("p",{children:h??`当前应用:${a.app.name??"未命名应用"}`})]}),e.jsxs("div",{className:"make-ai-assistant__header-actions",children:[d.features?.newConversation!==!1?e.jsx("button",{"aria-label":"新建对话",className:"make-ai-assistant__icon-button",type:"button",onClick:Ne,children:e.jsx(Le,{})}):null,r?e.jsx("button",{"aria-label":"关闭 Make AI 助手",className:"make-ai-assistant__icon-button",type:"button",onClick:r,children:e.jsx(Ve,{})}):null]})]}),e.jsxs("div",{className:"make-ai-assistant__privacy-note",role:"note",children:[e.jsx("span",{"aria-hidden":"true",children:"◇"}),"当前页面上下文会随请求发送,数据权限以宿主服务端校验结果为准"]}),e.jsxs("div",{className:"make-ai-assistant__body","aria-live":"polite","aria-relevant":"additions text",ref:Q,role:"log",onScroll:je,children:[S==="loading"?e.jsxs("div",{className:"make-ai-assistant__empty",role:"status",children:[e.jsx(K,{}),e.jsx("h3",{children:"正在恢复对话"}),e.jsx("p",{children:"正在读取当前 App 的历史消息…"})]}):S==="error"?e.jsxs("div",{className:"make-ai-assistant__empty",role:"alert",children:[e.jsx(K,{}),e.jsx("h3",{children:"暂时无法加载对话"}),e.jsx("p",{children:"请检查网络后重试。"}),e.jsx("button",{className:"make-ai-assistant__retry",type:"button",onClick:()=>Ie(n=>n+1),children:"重新加载"})]}):m.messages.length===0?e.jsxs("div",{className:"make-ai-assistant__empty",children:[e.jsx(K,{}),e.jsx("h3",{children:"有什么可以帮你?"}),e.jsx("p",{children:"我会结合当前 App 和页面上下文理解问题,并用适合的方式展示结果。"})]}):De(m,a,X,t,l,s,G?ee:void 0,E),m.progress&&!Te?e.jsx(ce,{assistantName:s,progress:m.progress.message}):null,m.error&&!Me?e.jsx(ce,{assistantName:s,error:m.error,onRetry:G?ee:void 0}):null]}),e.jsxs("footer",{className:"make-ai-assistant__composer-region",children:[S==="ready"&&k.length>0&&m.messages.length===0?e.jsx("div",{className:"make-ai-assistant__suggestions","aria-label":"推荐问题",children:k.map((n,I)=>e.jsx("button",{type:"button",onClick:()=>{Y(n)},children:n},`${I}-${n}`))}):null,e.jsxs("form",{className:"make-ai-assistant__composer",onSubmit:ve,children:[e.jsx("textarea",{"aria-label":`向 ${s} 提问`,"aria-describedby":H?"make-ai-composer-error":void 0,"aria-invalid":H?!0:void 0,autoFocus:!0,disabled:S!=="ready"||m.status==="streaming",placeholder:`询问当前 ${a.app.name??"App"} 中的数据…`,rows:2,value:A,onChange:n=>{y(n.currentTarget.value),P(void 0)},onKeyDown:ke}),m.status==="streaming"?e.jsx("button",{"aria-label":be,className:"make-ai-assistant__send make-ai-assistant__send--stop",type:"button",onClick:ye,children:e.jsx("span",{"aria-hidden":"true"})}):e.jsx("button",{"aria-label":"发送",className:"make-ai-assistant__send",disabled:S!=="ready"||!A.trim(),type:"submit",children:e.jsx(Pe,{})})]}),H?e.jsx("p",{id:"make-ai-composer-error",role:"alert",children:H}):null,e.jsx("p",{children:"AI 生成的结果可能存在偏差,重要数据请核对明细。"})]})]})}function Ue({defaultOpen:s=!1,hideLauncher:a=!1,launcher:t,onOpenChange:l,open:r,...o}){const[u,h]=p.useState(s),k=p.useRef(null),_=r??u,d=A=>{r===void 0&&h(A),l?.(A),A||requestAnimationFrame(()=>k.current?.focus())},E=()=>d(!_);return p.useEffect(()=>{if(!_)return;const A=y=>{y.key==="Escape"&&(d(!1),requestAnimationFrame(()=>k.current?.focus()))};return document.addEventListener("keydown",A),()=>document.removeEventListener("keydown",A)},[l,_]),e.jsxs("div",{className:"make-ai-assistant","data-open":_||void 0,children:[!a&&(!_||t)?t?t({open:_,toggle:E}):e.jsxs("button",{"aria-label":_?"关闭 Make AI 助手":"打开 Make AI 助手","aria-expanded":_,className:"make-ai-assistant__launcher",ref:k,type:"button",onClick:E,children:[e.jsx("span",{className:"make-ai-assistant__launcher-orbit","aria-hidden":"true"}),e.jsx(he,{})]}):null,_?e.jsx("aside",{"aria-label":"Make AI 助手","aria-modal":"false",className:"make-ai-assistant__drawer",role:"dialog",children:e.jsx(Ae,{...o,onClose:()=>d(!1)})}):null]})}exports.createArtifactCapabilities=M.createArtifactCapabilities;exports.createArtifactTemplateRegistry=M.createArtifactTemplateRegistry;exports.extendArtifactTemplateRegistry=M.extendArtifactTemplateRegistry;exports.resolveArtifactTemplate=M.resolveArtifactTemplate;exports.MAKE_AI_ARTIFACT_KINDS=c.MAKE_AI_ARTIFACT_KINDS;exports.MAKE_AI_ARTIFACT_LIMITS=c.MAKE_AI_ARTIFACT_LIMITS;exports.MAKE_AI_ARTIFACT_SCHEMA_VERSION=c.MAKE_AI_ARTIFACT_SCHEMA_VERSION;exports.MAKE_AI_CONVERSATION_LIMITS=c.MAKE_AI_CONVERSATION_LIMITS;exports.appendUserMessage=c.appendUserMessage;exports.createAssistantConversationState=c.createAssistantConversationState;exports.parseArtifact=c.parseArtifact;exports.parseAssistantEvent=c.parseAssistantEvent;exports.reduceAssistantEvent=c.reduceAssistantEvent;exports.validateArtifact=c.validateArtifact;exports.ArtifactRenderer=le;exports.AssistantPanel=Ae;exports.MakeAiAssistant=Ue;exports.createPlatformArtifactRegistry=pe;exports.formatArtifactValue=T;exports.platformArtifactTemplates=ue;
|