@qfei-design/make-ai-assistant 0.2.16 → 0.3.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/PUBLIC_API.md +40 -0
- package/README.md +25 -11
- package/capabilities.json +27 -0
- package/dist/client-types.d.ts +1 -0
- package/dist/client.cjs +2 -2
- package/dist/client.mjs +46 -41
- package/dist/core/conversation-management.d.ts +1 -0
- package/dist/react/use-conversation-manager.d.ts +3 -0
- package/dist/react.cjs +6 -4
- package/dist/react.mjs +1339 -1311
- package/dist/styles.css +31 -14
- package/docs/make-app-integration.md +56 -1
- package/examples/make-app/README.md +21 -3
- package/package.ai.json +1 -1
- package/package.json +1 -1
package/PUBLIC_API.md
CHANGED
|
@@ -70,6 +70,41 @@ Fetch SSE 实现时,从 `/sse` 入口导入 `createSseAssistantTransport`。
|
|
|
70
70
|
- `ReactArtifactTemplateRegistry`
|
|
71
71
|
- `formatArtifactValue`
|
|
72
72
|
|
|
73
|
+
## 组件参数速查
|
|
74
|
+
|
|
75
|
+
`MakeAiAssistant`(抽屉)和 `AssistantPanel`(嵌入面板)共用下列属性。一个应用只绑定一个应用内 Agent;宿主为该 Agent 创建 `transport` 并传给组件,包不提供 Agent 选择器。
|
|
76
|
+
|
|
77
|
+
| 属性 | 用途与责任 |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `context` | 必填,宿主提供当前 App、路由、语言与时区;`resource`、`selection`、`extensions` 可选。上下文不等于服务端授权。 |
|
|
80
|
+
| `transport` | 必填,宿主创建已绑定应用内 Agent 的 `AssistantTransport`。 |
|
|
81
|
+
| `registry` | 可选,宿主定制安全的 Artifact React 模板注册表。 |
|
|
82
|
+
| `brandName` / `title` / `assistantName` | 可选,品牌标题、完整标题覆盖和 AI 消息显示名称。 |
|
|
83
|
+
| `userName` / `userAvatarUrl` | 可选,当前登录人的展示名称和头像,不进入请求。 |
|
|
84
|
+
| `theme` / `headerHeight` | 可选,局部主题及标题栏高度。 |
|
|
85
|
+
| `suggestions` | 可选,省略使用内置推荐问题,传 `[]` 隐藏。 |
|
|
86
|
+
| `onAction` / `onActionError` | 可选,宿主执行已校验的 Artifact 动作及处理其失败。 |
|
|
87
|
+
| `onNewConversation` / `onClose` | 可选,新建会话和关闭面板的通知;`onClose` 仅限 `AssistantPanel`。 |
|
|
88
|
+
| `subtitle` / `privacyNotice` | 兼容保留,接受但不渲染,新接入不要使用。 |
|
|
89
|
+
|
|
90
|
+
`MakeAiAssistant` 还支持 `open` / `onOpenChange`(受控开关)、`defaultOpen`、
|
|
91
|
+
`launcher` / `hideLauncher` / `launcherPosition` 和 `maxDrawerWidth`(桌面抽屉宽度上限)。
|
|
92
|
+
完整类型以 `/react` 入口导出的 `AssistantPanelProps` 和 `MakeAiAssistantProps` 为准。
|
|
93
|
+
|
|
94
|
+
`transport.features` 是运行时能力门控,不是 `capabilities.json`(供宿主/工具发现包功能的静态目录):
|
|
95
|
+
|
|
96
|
+
| 功能 | transport 合同与显示条件 |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| 历史恢复 | 实现 `loadConversation` 时加载历史;Make App 多会话还需 `conversationManagement: true` 及会话方法。 |
|
|
99
|
+
| 任务列表 | `conversationManagement: true` 且 `listConversations`、`createConversation`、`getConversation`、`loadConversation` 方法齐全;缺少时显示配置错误并禁用输入,不会停留在加载中。改名/置顶另需 `conversationEditing !== false` 和 `updateConversation`;删除另需该标志与 `deleteConversation`。 |
|
|
100
|
+
| 新建对话 | 默认显示;显式 `newConversation: false` 时隐藏。 |
|
|
101
|
+
| 反馈 | `feedback: true`、持久消息和 `setFeedback` 方法同时具备时才展示喜欢/不喜欢。 |
|
|
102
|
+
| 附件 | 会话管理已就绪(见上)、`attachments: true`,且 `startUpload`、`getUpload`、`uploadPart`、`completeUpload` 方法齐全时才显示上传入口;`modelInputKinds` 单独说明模型可接受的内容类型,上传成功不等于模型可理解。 |
|
|
103
|
+
| 重新生成 | 提供 `regenerate` 且 `regeneration !== false`,服务端必须支持替换旧回答。 |
|
|
104
|
+
| 停止 | `remoteCancellation: false` 时仅停止接收;有远程取消能力时由 transport 实现对应语义。 |
|
|
105
|
+
|
|
106
|
+
单 Agent 宿主接入示例见 [Make App 接入示例](examples/make-app/README.md)。
|
|
107
|
+
|
|
73
108
|
`MakeAiAssistant`、`AssistantPanel` 和 `ArtifactRenderer` 均支持 `theme?: MakeAiTheme`。标题栏、内容区背景与用户提问气泡默认跟随宿主主题色;输入承载面固定白色,正文、通用边框保持包内中性色。
|
|
74
109
|
除标题栏、内容区背景与用户提问气泡外,主题色只用于竖线、圆点、图标、输入框焦点、发送按钮和标签等强调元素;Markdown 表格滚动条固定为中性灰。`primary` 为必填,
|
|
75
110
|
`primaryHover` 与 `onPrimary` 可选;内置强调色依次读取 `theme` 属性、`--make-ai-theme-primary` 系列、
|
|
@@ -179,6 +214,11 @@ UI 会拒绝孤立、迟到、重复或跨 run 混入的事件,避免静默丢
|
|
|
179
214
|
|
|
180
215
|
`/make-app` 导出异步 createMakeAppAssistantTransport({ client, agentId, historyLimit?, signal? }),通过能力发现后返回 AssistantTransport。宿主只注入一个正式认证 HTTP 传输、App/身份和 Agent;身份变化时调用 client.dispose() 并重建实例。
|
|
181
216
|
|
|
217
|
+
首次选取 Agent 时,宿主先通过 `client.agents.list()` 读完分页并选定 `agentId`,再创建
|
|
218
|
+
Make App transport;工厂已要求 `agentId`,不能用创建后的 `transport.listAgents()` 做首次选取。
|
|
219
|
+
两个列表方法都透传可选的 `agentType` 字符串(包括 `app_internal`、`channel` 和未来新值),
|
|
220
|
+
旧响应缺失时不补默认值。包不筛选类型,选择规则由宿主负责。
|
|
221
|
+
|
|
182
222
|
标准 SDK 将新增响应元数据安全投影;未知事件保留名称/游标,未知内容块保留 originalKind/textFallback,不执行未知动作。输入仍严格验证。v1 的 cursor 为不透明字符串,ResponseSnapshot 必含 terminal 和 snapshotRevision。框架中立的 AssistantTransport 仍允许 Console/测试适配器的本地序号,但 Make App v1 不接受数字 cursor。
|
|
183
223
|
|
|
184
224
|
Chat.titlePending 缺失按 false;摘要完成通过同一 Client 的详情刷新立即反映到会话列表。SSE 只更新响应视图,反馈使用历史中真正的 messageId,关闭订阅不会远程取消运行。
|
package/README.md
CHANGED
|
@@ -13,29 +13,40 @@ VERSION 替换为完成本地验收的发布版本,提交 lockfile 固定制
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
15
|
```tsx
|
|
16
|
+
import type {
|
|
17
|
+
ArtifactActionErrorHandler,
|
|
18
|
+
ArtifactActionHandler,
|
|
19
|
+
AssistantTransport,
|
|
20
|
+
MakeAssistantHostContext,
|
|
21
|
+
} from "@qfei-design/make-ai-assistant";
|
|
16
22
|
import { MakeAiAssistant } from "@qfei-design/make-ai-assistant/react";
|
|
17
23
|
import "@qfei-design/make-ai-assistant/styles.css";
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
// context、transport 和动作回调均由宿主创建并传入;此处不读取凭据或直接请求 Make API。
|
|
26
|
+
export function AppAssistant({ context, transport, onAction, onActionError }: {
|
|
27
|
+
context: MakeAssistantHostContext;
|
|
28
|
+
transport: AssistantTransport;
|
|
29
|
+
onAction?: ArtifactActionHandler;
|
|
30
|
+
onActionError?: ArtifactActionErrorHandler;
|
|
31
|
+
}) {
|
|
20
32
|
return (
|
|
21
33
|
<MakeAiAssistant
|
|
22
|
-
brandName=
|
|
34
|
+
brandName={context.app.name}
|
|
23
35
|
theme={{ primary: "#0f8277" }}
|
|
24
|
-
context={
|
|
25
|
-
|
|
26
|
-
location: { pathname: window.location.pathname },
|
|
27
|
-
locale: "zh-CN",
|
|
28
|
-
timezone: "Asia/Shanghai",
|
|
29
|
-
}}
|
|
30
|
-
transport={assistantTransport}
|
|
36
|
+
context={context}
|
|
37
|
+
transport={transport}
|
|
31
38
|
suggestions={["总结当前页面", "找出需要关注的记录"]}
|
|
32
|
-
onAction={
|
|
33
|
-
onActionError={
|
|
39
|
+
onAction={onAction}
|
|
40
|
+
onActionError={onActionError}
|
|
34
41
|
/>
|
|
35
42
|
);
|
|
36
43
|
}
|
|
37
44
|
```
|
|
38
45
|
|
|
46
|
+
这是单 Agent 的最小接入:宿主提供带当前 App/路径/语言/时区的 `context`,以及已绑定 Agent 的
|
|
47
|
+
`transport`;需要 Artifact 动作时再提供经过宿主权限校验的回调。Make App 接入参考
|
|
48
|
+
[完整宿主示例](examples/make-app/README.md);各组件属性与功能开关见 [公共 API](PUBLIC_API.md#组件参数速查)。
|
|
49
|
+
|
|
39
50
|
`MakeAiAssistant` 默认渲染右下角的动效入口和右侧抽屉。宿主可以使用 `open` / `onOpenChange`
|
|
40
51
|
受控管理开关,也可以用 `AssistantPanel` 嵌入自己的容器。内置浮动入口可通过 `launcherPosition`
|
|
41
52
|
设置为 `bottom-left`、`bottom-right`、`top-left`、`top-right`、`left-center` 或 `right-center`;默认值为
|
|
@@ -210,6 +221,9 @@ const assistantTransport = await createMakeAppAssistantTransport({ client, agent
|
|
|
210
221
|
// App、用户或租户改变时,取消旧连接并 client.dispose(),重新创建实例。
|
|
211
222
|
```
|
|
212
223
|
|
|
224
|
+
一个 Make App 只绑定一个应用内 Agent。宿主负责取得该 Agent 的 `agentId`,并创建对应的
|
|
225
|
+
`transport` 传给组件;包不提供 Agent 选择器。模型选择是独立能力,当前不在组件合同中。
|
|
226
|
+
|
|
213
227
|
`AuthenticatedTransport.request` 只执行一次已认证 I/O,返回 status、headers 和 AsyncIterable<Uint8Array>。`retryOwner: "sdk"` 由 SDK 按幂等语义做有限重试;`retryOwner: "transport"` 不叠加 SDK 重试。宿主沿正式 auth.api 处理登录、401/403 和 Cookie,SSE/二进制成功体不经过 JSON 或 text() 缓冲。SDK 不读取 Token、Cookie、LocalStorage 或 Provider key。
|
|
214
228
|
|
|
215
229
|
Make Console 可以使用独立 adapter:
|
package/capabilities.json
CHANGED
|
@@ -53,6 +53,33 @@
|
|
|
53
53
|
"platformArtifactTemplates"
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
|
+
{
|
|
57
|
+
"id": "managed-conversations",
|
|
58
|
+
"name": "Conversation management",
|
|
59
|
+
"category": "ui",
|
|
60
|
+
"status": "experimental",
|
|
61
|
+
"summary": "多会话历史、任务列表和持久新建对话需要完整的核心会话方法;编辑标题、置顶和删除另受 conversationEditing 与对应方法控制。",
|
|
62
|
+
"docPath": "PUBLIC_API.md",
|
|
63
|
+
"relatedExports": ["AssistantTransport", "AssistantPanel"]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "message-feedback",
|
|
67
|
+
"name": "Assistant message feedback",
|
|
68
|
+
"category": "ui",
|
|
69
|
+
"status": "experimental",
|
|
70
|
+
"summary": "持久化 AI 回答的喜欢/不喜欢操作;由 transport.features.feedback 和反馈方法控制。",
|
|
71
|
+
"docPath": "PUBLIC_API.md",
|
|
72
|
+
"relatedExports": ["AssistantTransport", "AssistantPanel"]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"id": "typed-attachments",
|
|
76
|
+
"name": "Typed attachment composer",
|
|
77
|
+
"category": "ui",
|
|
78
|
+
"status": "experimental",
|
|
79
|
+
"summary": "输入区图片与文件附件、上传进度和预览;上传入口需要 transport.features.attachments 与完整上传方法,模型可接收的类型取决于 modelInputKinds。",
|
|
80
|
+
"docPath": "docs/make-app-integration.md",
|
|
81
|
+
"relatedExports": ["AssistantTransport", "AssistantPanel"]
|
|
82
|
+
},
|
|
56
83
|
{
|
|
57
84
|
"id": "sse-transport",
|
|
58
85
|
"name": "SSE transport",
|
package/dist/client-types.d.ts
CHANGED
package/dist/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Y=require("./conversation-management-f1y0yRvt.cjs"),A=Y.protocolRecord,g=Y.protocolId,f=Y.protocolText,p=Y.protocolInteger,G=Y.protocolBoolean,K=Y.protocolArray;function E(o,a){if(Object.keys(o).some(n=>!a.includes(n)))throw new Error("Invalid request: unknown field")}function Z(o){const a=f(o,36);if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(a))throw new Error("Invalid request: UUID");return a}function W(o,a=!1){return f(o,8192,a)}const se=o=>{const a=f(o,64);if(!Number.isFinite(Date.parse(a)))throw new Error("Invalid response: timestamp");return a};function Ie(o){const a=W(o.nextCursor,!0),n=G(o.hasMore);if(n!==!!a)throw new Error("Invalid response: page cursor");return{nextCursor:a,hasMore:n}}function ae(o,a,n,l){const i=A(o);if(i.appKey!==a||n&&i.agentId!==n||l&&i.chatId!==l||!["active","deleted"].includes(String(i.status)))throw new Error("Invalid response: chat scope");return{chatId:g(i.chatId),appKey:a,agentId:g(i.agentId),title:f(i.title,255,!0),titlePending:i.titlePending===void 0?!1:G(i.titlePending),status:i.status,revision:p(i.revision,1),pinned:G(i.pinned),pinnedAt:i.pinnedAt==null?null:se(i.pinnedAt),createdAt:se(i.createdAt),lastActivityAt:se(i.lastActivityAt)}}function be(o,a,n){const l=A(o),i=K(l.chats,100).map(m=>ae(m,a,n));if(new Set(i.map(m=>m.chatId)).size!==i.length)throw new Error("Invalid response: duplicate chat");return{chats:i,...Ie(l)}}function xe(o,a){const n=A(o);return{agents:K(n.agents,100).map(i=>{const m=A(i);if(m.appKey!==a)throw new Error("Invalid response: agent scope");return{agentId:g(m.agentId),appKey:a,name:f(m.name,255)}}),...Ie(n)}}function ve(o){const a=A(o),n=f(a.digestSha256,64);if(!/^[0-9a-f]{64}$/.test(n))throw new Error("Invalid response: digest");return{contentRef:g(a.contentRef),contentType:f(a.contentType,256),sizeBytes:p(a.sizeBytes),digestSha256:n}}function Ee(o){return K(o,32).map(a=>{const n=A(a),l=f(n.kind,128),i=n.id===void 0?{}:{id:g(n.id)};return l==="text"?{...i,kind:l,text:f(n.text,1e5,!0)}:["image","file","audio","video"].includes(l)?{...i,kind:l,...n.name===void 0?{}:{name:f(n.name,512,!0)},media:ve(n.media)}:{...i,kind:"unknown",originalKind:l,...n.textFallback===void 0?{}:{textFallback:f(n.textFallback,1e5,!0)}}})}function Re(o){const a=A(o);if(!["like","dislike","none"].includes(String(a.rating)))throw new Error("Invalid response: feedback");return{id:g(a.id),rating:a.rating,revision:p(a.revision,1),...a.reason===void 0?{}:{reason:f(a.reason,128,!0)},...a.comment===void 0?{}:{comment:f(a.comment,4e3,!0)}}}function ke(o){const a=A(o);let n=0;const l=K(a.messages,200).map(i=>{const m=A(i);if(m.role!=="user"&&m.role!=="assistant")throw new Error("Invalid response: history role");const P=f(m.text,1e5,!0);return n+=[...P].length,{messageId:g(m.messageId),role:m.role,cursor:W(m.cursor),createdAt:se(m.createdAt),text:P,...m.responseId===void 0?{}:{responseId:g(m.responseId)},...m.parts===void 0?{}:{parts:Ee(m.parts)},...m.feedback===void 0?{}:{feedback:Re(m.feedback)}}});if(n>1e6||new Set(l.map(i=>i.messageId)).size!==l.length)throw new Error("Invalid response: history budget or duplicate identity");return{messages:l,...Ie(a)}}function ue(o,a,n){const l=A(o);if(l.chatId!==a||l.responseId!==n)throw new Error("Invalid response: response scope");const i=f(l.status,64),m=G(l.terminal);if(["completed","failed","cancelled"].includes(i)&&!m||["queued","dispatched","running"].includes(i)&&m)throw new Error("Invalid response: contradictory terminal");const P=K(l.items,20).map(k=>{const _=A(k);return{itemId:g(_.itemId),partId:g(_.partId),text:f(_.text,1e5,!0),final:G(_.final),revision:p(_.revision,1),..._.parts===void 0?{}:{parts:Ee(_.parts)}}});if(P.reduce((k,_)=>k+[..._.text].length,0)>1e5||new Set(P.map(k=>k.itemId)).size!==P.length)throw new Error("Invalid response: output budget or identity");return{chatId:a,responseId:n,status:i,terminal:m,snapshotRevision:p(l.snapshotRevision,1),items:P,...l.cancelRequested===void 0?{}:{cancelRequested:G(l.cancelRequested)}}}function he(o,a){const n=A(o),l=g(n.id),i=f(n.status,64),m=p(n.sizeBytes),P=p(n.partSize,1);if(a&&l!==a)throw new Error("Invalid response: upload identity");const k=K(n.completedParts,65536).map(M=>p(M,0,Math.max(0,Math.ceil(m/P)-1)));if(new Set(k).size!==k.length)throw new Error("Invalid response: upload receipt");const _={id:l,status:i,name:f(n.name,512),contentType:f(n.contentType,256),sizeBytes:m,partSize:P,completedParts:k,...n.expiresAt===void 0?{}:{expiresAt:se(n.expiresAt)}};if(i==="ready"){const M=A(n.content);if(M.kind!=="reference"||M.sizeBytes!==m||!/^[0-9a-f]{64}$/.test(String(M.digestSha256)))throw new Error("Invalid response: upload content");return{..._,content:{kind:"reference",contentRef:g(M.contentRef),sizeBytes:m,digestSha256:String(M.digestSha256)}}}if(i==="uploading"&&!_.expiresAt)throw new Error("Invalid response: upload expiry");return _}function Se(o,a,n){const l=A(o),i=A(l.limits);if(l.apiVersion!=="v1"||l.appKey!==a||l.agentId!==n)throw new Error("Invalid response: capability scope");return{apiVersion:"v1",appKey:a,agentId:n,features:K(l.features,256).map(m=>f(m,128)),modelInputKinds:K(l.modelInputKinds,64).map(m=>f(m,64)),limits:{maxInputTextBytes:p(i.maxInputTextBytes,1),maxMessageBytes:p(i.maxMessageBytes,1),maxInputParts:p(i.maxInputParts,1),maxUploadBytes:p(i.maxUploadBytes,1),uploadPartBytes:p(i.uploadPartBytes,1),maxConcurrentUploads:p(i.maxConcurrentUploads,1),maxSseEventBytes:p(i.maxSseEventBytes,1)}}}class u extends Error{status;code;requestId;retryAfterMs;outcome;lastCursor;constructor(a,n={}){super(a),this.name="ApiError",this.code=a,this.status=n.status,this.requestId=n.requestId,this.retryAfterMs=n.retryAfterMs,this.outcome=n.outcome??"known",this.lastCursor=n.lastCursor}}const ee=new TextEncoder,q=(o,a)=>Object.entries(o.headers).find(([n])=>n.toLowerCase()===a.toLowerCase())?.[1],H=o=>new URLSearchParams(Object.entries(o).filter(([,a])=>a!==void 0).map(([a,n])=>[a,String(n)])).toString(),J=o=>encodeURIComponent(g(o));function te(o,a){return new Promise((n,l)=>{const i=()=>l(new u("AI_CLIENT_ABORTED"));if(a.aborted){o.catch(()=>{}),i();return}a.addEventListener("abort",i,{once:!0}),o.then(n,l).finally(()=>a.removeEventListener("abort",i))})}async function*me(o,a){const n=o.body?.[Symbol.asyncIterator]();if(n)try{for(;;){const l=await te(n.next(),a);if(l.done)return;yield l.value}}finally{n.return?.().catch(()=>{})}}function Pe(o){const a=o.apiVersion??"v1";if(a!=="v1")throw new u("AI_API_VERSION_UNSUPPORTED",{outcome:"notSent"});if(!["sdk","transport"].includes(o.transport.retryOwner))throw new u("AI_BAD_REQUEST",{outcome:"notSent"});const n=Object.freeze({appKey:g(o.scope.appKey),identityKey:f(o.scope.identityKey,8192)}),l=o.basePath??"/api/make/app/ai";if(!/^\/(?!\/)[A-Za-z0-9/_-]+$/.test(l)||/\/v\d+\/?$/.test(l))throw new Error("Invalid request: basePath");if(o.transport.retryOwner==="transport"&&o.retry)throw new Error("Invalid request: multiple retry owners");const i=p(o.retry?.maxAttempts??3,1,5),m=p(o.maxJsonBytes??8*1024*1024,1,32*1024*1024),P=p(o.maxEventBytes??1024*1024,1,4*1024*1024),k=new Set;let _=!1;const M=(e,s,r,t)=>{try{o.onDiagnostic?.({operation:e,code:s,requestId:r,attempts:t})}catch{}},X=(e,s)=>{if(_||e?.signal?.aborted)throw new u("AI_CLIENT_ABORTED",{outcome:"notSent"});const r=p(e?.timeoutMs??s,1,1440*60*1e3),t=new AbortController;k.add(t);const c=()=>t.abort();e?.signal?.addEventListener("abort",c,{once:!0});let h=!1;const d=setTimeout(()=>{h=!0,c()},r);return{controller:t,deadline:Date.now()+r,failure:(I="known")=>new u(h?"AI_CLIENT_TIMEOUT":"AI_CLIENT_ABORTED",{outcome:I}),close:()=>{clearTimeout(d),e?.signal?.removeEventListener("abort",c),k.delete(t),t.abort()}}},re=async(e,s)=>{if(s.aborted)throw new u("AI_CLIENT_ABORTED");await new Promise((r,t)=>{const h=setTimeout(()=>{s.removeEventListener("abort",d),r()},e),d=()=>{clearTimeout(h),s.removeEventListener("abort",d),t(new u("AI_CLIENT_ABORTED"))};s.addEventListener("abort",d,{once:!0})})},fe=async(e,s,r)=>{let t=0;const c=[];for await(const I of me(e,r)){if(t+=I.byteLength,t>s)throw new u("AI_RESPONSE_TOO_LARGE",{status:e.status});c.push(I)}const h=new Uint8Array(t);let d=0;for(const I of c)h.set(I,d),d+=I.length;return h},oe=async(e,s)=>{let r="AI_HTTP_ERROR";try{const h=A(JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(await fe(e,m,s))));typeof h.code=="string"&&h.code.length<128&&(r=h.code)}catch{}const t=q(e,"retry-after"),c=t===void 0?void 0:/^\d+$/.test(t)?Number(t)*1e3:Math.max(0,Date.parse(t)-Date.now());return new u(r,{status:e.status,requestId:q(e,"x-request-id"),retryAfterMs:Number.isFinite(c)?c:void 0})},O=(e,s,r,t)=>({method:e,path:l.replace(/\/$/,"")+"/"+a+s,headers:{accept:"application/json",...r===void 0&&t===void 0?{}:{"content-type":t?"application/octet-stream":"application/json"}},...t===void 0?r===void 0?{}:{body:ee.encode(JSON.stringify(r))}:{body:new Uint8Array(t)}});async function b(e,s,r,t,c=!0,h=[200]){const d=X(t,o.timeoutMs??3e4),I=c&&o.transport.retryOwner==="sdk"?i:1;let y=!1;M(e),console.info("[make-ai-assistant] client operation start",{operation:e});try{for(let R=1;R<=I;R++)try{if(d.controller.signal.aborted||Date.now()>=d.deadline)throw new u("AI_CLIENT_TIMEOUT",{outcome:y?"unknown":"notSent"});y=!0;const w=await te(o.transport.request(s,{signal:d.controller.signal,timeoutMs:Math.max(1,d.deadline-Date.now())}),d.controller.signal);if(w.status<200||w.status>=300)throw await oe(w,d.controller.signal);if(q(w,"make-ai-api-version")!==a||!h.includes(w.status))throw new u("AI_PROTOCOL_ERROR",{status:w.status});let v;if(w.status!==204){if(!q(w,"content-type")?.toLowerCase().includes("application/json"))throw new u("AI_PROTOCOL_ERROR",{status:w.status});try{v=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(await fe(w,m,d.controller.signal)))}catch(S){throw S instanceof u?S:new u("AI_PROTOCOL_ERROR",{status:w.status})}}try{const S=r(v);return M(e,void 0,q(w,"x-request-id"),R),S}catch{throw new u("AI_PROTOCOL_ERROR",{status:w.status,requestId:q(w,"x-request-id")})}}catch(w){if(d.controller.signal.aborted)throw d.failure(y?"unknown":"notSent");let v=w instanceof u?w:new u("AI_TRANSPORT_ERROR",{outcome:y?"unknown":"notSent"});s.method!=="GET"&&y&&((v.status??0)>=500||v.status===408||["AI_PROTOCOL_ERROR","AI_RESPONSE_TOO_LARGE"].includes(v.code))&&(v=new u(v.code,{...v,outcome:"unknown"}));const S=v.code==="AI_TRANSPORT_ERROR"||[429,502,503,504].includes(v.status??0)&&v.code!=="AI_QUOTA_EXCEEDED",T=v.retryAfterMs??Math.min(o.retry?.maxDelayMs??5e3,100*2**(R-1)*(.5+Math.random()));if(!S||R===I||d.controller.signal.aborted||Date.now()+T>=d.deadline)throw v;await re(T,d.controller.signal)}throw new u("AI_TRANSPORT_ERROR",{outcome:"unknown"})}catch(R){throw M(e,R instanceof u?R.code:"AI_CLIENT_ERROR"),console.warn("[make-ai-assistant] client operation failed",{operation:e}),R}finally{d.close()}}const C=e=>"/chats/"+J(e),pe=e=>C(e.chatId)+"/responses/"+J(e.responseId),ie=(e,s)=>({...e.cursor===void 0?{}:{cursor:W(e.cursor)},...e.limit===void 0?{}:{limit:p(e.limit,1,s)}}),Te=e=>{if(E(e,["chatId","messageId","text","parts"]),g(e.chatId),Z(e.messageId),e.text===void 0==(e.parts===void 0))throw new Error("Invalid request: text and parts are exclusive");let s=e.text??"";if(e.parts!==void 0){const c=new Set;for(const h of K(e.parts,32)){const d=A(h),I=Z(d.id);if(c.has(I))throw new Error("Invalid request: duplicate part");if(c.add(I),d.kind==="text")E(d,["id","kind","text"]),s+=f(d.text,8192,!0);else{if(E(d,["id","kind","name","media"]),!["image","file","audio","video"].includes(String(d.kind)))throw new Error("Invalid request: part kind");E(A(d.media),["contentRef","contentType","sizeBytes","digestSha256"]);const y=ve(d.media);if(d.name!==void 0&&/[\r\n/\\]/.test(f(d.name,512)))throw new u("AI_BAD_REQUEST",{outcome:"notSent"});if(!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(y.contentType)||d.kind!=="file"&&(!y.contentType.startsWith(String(d.kind)+"/")||y.contentType==="image/svg+xml"))throw new u("AI_BAD_REQUEST",{outcome:"notSent"})}}if(!e.parts.length||!s.trim()&&e.parts.every(h=>h.kind==="text"))throw new Error("Invalid request: empty message")}else f(e.text,8192);if(ee.encode(s).length>8192)throw new Error("Invalid request: text exceeds 8 KiB");const{chatId:r,...t}=e;if(ee.encode(JSON.stringify(t)).length>65536)throw new Error("Invalid request: message too large");return t},ce=new Map;async function*we(e,s,r,t){p(r,1,1e4),p(t,1);const c=new Set;let h=s,d=0;for(let I=0;I<r;I++){const y=await e(h);for(const R of y.values){if(++d>t)throw new u("AI_ITERATION_LIMIT",{lastCursor:h});yield R}if(!y.hasMore)return;if(y.nextCursor===h||c.has(y.nextCursor))throw new u("AI_PROTOCOL_ERROR");c.add(y.nextCursor),h=y.nextCursor}throw new u("AI_ITERATION_LIMIT",{lastCursor:h})}const N={apiVersion:a,scope:n,capabilities:{async get(e,s){E(e,["agentId"]);const r=g(e.agentId),t=ce.get(r);if(!_&&!s?.signal?.aborted&&t&&t.expires>Date.now())return t.value;const c=await b("capabilities.get",O("GET","/capabilities?"+H({appKey:n.appKey,agentId:r})),h=>Se(h,n.appKey,r),s);return ce.set(r,{value:c,expires:Date.now()+6e4}),c}},agents:{async list(e={},s){return E(e,["cursor","limit"]),b("agents.list",O("GET","/agents?"+H({appKey:n.appKey,...ie(e,100)})),r=>xe(r,n.appKey),s)}},chats:{async create(e,s){E(e,["agentId","requestId","title"]);const r=g(e.agentId);return Z(e.requestId),e.title!==void 0&&f(e.title,255),b("chats.create",O("POST","/chats",{appKey:n.appKey,...e}),t=>ae(t,n.appKey,r),s,!0,[201])},async list(e,s){E(e,["agentId","cursor","limit"]);const r=g(e.agentId);return b("chats.list",O("GET","/chats?"+H({appKey:n.appKey,agentId:r,...ie(e,100)})),t=>be(t,n.appKey,r),s)},async get(e,s){return E(e,["chatId"]),b("chats.get",O("GET",C(e.chatId)),r=>ae(r,n.appKey,void 0,e.chatId),s)},async update(e,s){if(E(e,["chatId","expectedRevision","title","pinned"]),p(e.expectedRevision,1),e.title===void 0&&e.pinned===void 0)throw new Error("Invalid request: empty patch");e.title!==void 0&&f(e.title,255),e.pinned!==void 0&&G(e.pinned);const{chatId:r,...t}=e;return b("chats.update",O("PATCH",C(r),t),c=>ae(c,n.appKey,void 0,r),s,!1)},async delete(e,s){E(e,["chatId","expectedRevision"]),p(e.expectedRevision,1),await b("chats.delete",O("DELETE",C(e.chatId)+"?"+H({expectedRevision:e.expectedRevision})),()=>{},s,!1,[204])},iterate(e,s){return we(async r=>{const t=await N.chats.list({...e,cursor:r},s);return{...t,values:t.chats}},e.cursor,s.maxPages,s.maxItems)}},messages:{async send(e,s){const r=Te(e);return b("messages.send",O("POST",C(e.chatId)+"/messages",r),t=>{const c=A(t);if(c.chatId!==e.chatId||c.messageId!==e.messageId)throw new Error("Invalid response: accepted scope");return{chatId:e.chatId,messageId:e.messageId,responseId:g(c.responseId),...c.acceptedCursor===void 0?{}:{acceptedCursor:W(c.acceptedCursor)}}},s,!0,[202])},async list(e,s){E(e,["chatId","cursor","limit"]);const r=H(ie(e,200));return b("messages.list",O("GET",C(e.chatId)+"/messages"+(r?"?"+r:"")),ke,s)},iterate(e,s){return we(async r=>{const t=await N.messages.list({...e,cursor:r},s);return{...t,values:t.messages}},e.cursor,s.maxPages,s.maxItems)},async sendAndWatch(e,s){const r=Date.now(),t=await N.messages.send(e,s),c=(s?.timeoutMs??o.stream?.maxDurationMs??6e5)-(Date.now()-r);if(c<=0)throw new u("AI_CLIENT_TIMEOUT",{outcome:"known"});return{accepted:t,events:N.responses.subscribe({chatId:t.chatId,responseId:t.responseId},{...s,timeoutMs:c})}}},responses:{async get(e,s){return E(e,["chatId","responseId"]),b("responses.get",O("GET",pe(e)),r=>ue(r,e.chatId,e.responseId),s)},subscribe(e,s){return Ae(e,s)},async cancel(e,s){return E(e,["chatId","responseId"]),b("responses.cancel",O("POST",pe(e)+"/cancel",{}),r=>ue(r,e.chatId,e.responseId),s,!0,[200,202])},async waitForTerminal(e,s){const r=X(s,s.timeoutMs);try{for(;!r.controller.signal.aborted;){const t=await N.responses.get(e,{signal:r.controller.signal,timeoutMs:Math.max(1,r.deadline-Date.now())});if(t.terminal)return t;await re(s.pollIntervalMs??1e3,r.controller.signal)}throw new u("AI_CLIENT_TIMEOUT")}finally{r.close()}}},feedback:{async set(e,s){if(E(e,["chatId","messageId","requestId","rating","reason","comment"]),Z(e.requestId),!["like","dislike","none"].includes(e.rating))throw new Error("Invalid request: rating");e.reason!==void 0&&f(e.reason,128,!0),e.comment!==void 0&&f(e.comment,4e3,!0);const{chatId:r,messageId:t,...c}=e;return b("feedback.set",O("PUT",C(r)+"/messages/"+J(t)+"/feedback",c),Re,s)}},uploads:{async start(e,s){E(e,["chatId","fileId","name","contentType","sizeBytes","digestSha256"]),Z(e.fileId),f(e.name,512),f(e.contentType,256),p(e.sizeBytes,1);const{chatId:r,...t}=e;return b("uploads.start",O("POST",C(r)+"/uploads",t),c=>he(c),s)},async get(e,s){return E(e,["chatId","uploadId"]),b("uploads.get",O("GET",C(e.chatId)+"/uploads/"+J(e.uploadId)),r=>he(r,e.uploadId),s)},async putPart(e,s){if(E(e,["chatId","uploadId","part","bytes"]),p(e.part),!(e.bytes instanceof Uint8Array)||e.bytes.length>m)throw new Error("Invalid request: upload bytes");await b("uploads.putPart",O("PUT",C(e.chatId)+"/uploads/"+J(e.uploadId)+"/parts/"+e.part,void 0,e.bytes),()=>{},s,!0,[204])},async complete(e,s){return E(e,["chatId","uploadId"]),b("uploads.complete",O("POST",C(e.chatId)+"/uploads/"+J(e.uploadId)+"/complete",{}),r=>he(r,e.uploadId),s)},async uploadFile(e,s){const r=p(s?.concurrency??2,1,8),t=X(s,o.timeoutMs??3e5),c=()=>({signal:t.controller.signal,timeoutMs:Math.max(1,t.deadline-Date.now())});try{const{source:h,...d}=e,I=await N.uploads.start({...d,sizeBytes:h.sizeBytes},c());if(I.status==="ready")return I;if(I.status!=="uploading"||I.partSize>m||I.sizeBytes!==h.sizeBytes)throw new u("AI_UPLOAD_UNAVAILABLE");const y=new Set(I.completedParts),R=Math.ceil(h.sizeBytes/I.partSize);let w=0,v=I.completedParts.reduce((T,L)=>T+Math.min(I.partSize,h.sizeBytes-L*I.partSize),0);const S=Array.from({length:r},async()=>{for(;w<R;){if(t.controller.signal.aborted)throw t.failure();const T=w++;if(y.has(T))continue;const L=Math.min(I.partSize,h.sizeBytes-T*I.partSize),z=await te(h.read(T*I.partSize,L,c()),t.controller.signal);if(!(z instanceof Uint8Array)||z.length!==L)throw new u("AI_CONTENT_INTEGRITY_ERROR");await N.uploads.putPart({chatId:e.chatId,uploadId:I.id,part:T,bytes:z},c()),v+=L;try{s?.onProgress?.(v)}catch{}}});try{await Promise.all(S)}catch(T){throw t.controller.abort(),await Promise.allSettled(S),T}return await N.uploads.complete({chatId:e.chatId,uploadId:I.id},c())}finally{t.close()}}},content:{async read(e,s){M("content.read"),console.info("[make-ai-assistant] client operation start",{operation:"content.read"}),E(e,["chatId","contentRef","maxBytes"]),p(e.maxBytes,1);const r=X(s,o.timeoutMs??3e4);try{const t=await te(o.transport.request(O("GET",C(e.chatId)+"/content/"+J(e.contentRef)),{signal:r.controller.signal}),r.controller.signal);if(t.status!==200)throw await oe(t,r.controller.signal);if(q(t,"make-ai-api-version")!==a)throw new u("AI_PROTOCOL_ERROR");const c=q(t,"content-length"),h=c===void 0?void 0:Number(c);if(h!==void 0&&(!Number.isSafeInteger(h)||h<0||h>e.maxBytes))throw new u("AI_RESPONSE_TOO_LARGE");return{contentType:q(t,"content-type"),contentLength:h,body:(async function*(){let d=0;try{for await(const I of me(t,r.controller.signal)){if(d+=I.length,d>e.maxBytes)throw new u("AI_RESPONSE_TOO_LARGE");yield I}if(h!==void 0&&h!==d)throw new u("AI_CONTENT_INTEGRITY_ERROR")}finally{r.close()}})()}}catch(t){throw r.close(),t}}},dispose(){_=!0,ce.clear();for(const e of k)e.abort();k.clear()}};async function*Ae(e,s){M("responses.subscribe"),console.info("[make-ai-assistant] client operation start",{operation:"responses.subscribe"}),E(e,["chatId","responseId","cursor"]),g(e.chatId),g(e.responseId);let r=e.cursor===void 0?void 0:W(e.cursor);const t=X(s,o.stream?.maxDurationMs??6e5),c=new Map;let h=0,d=!1;const I=o.transport.retryOwner==="sdk"?i:1;try{for(let y=1;y<=I;y++){const R=new AbortController,w=()=>R.abort();t.controller.signal.addEventListener("abort",w,{once:!0});let v,S=!1;try{if(t.controller.signal.aborted)throw t.failure();const T=O("GET",C(e.chatId)+"/events?"+H({responseId:e.responseId,cursor:r})),L=setTimeout(w,o.stream?.connectTimeoutMs??3e4);let z;try{z=await te(o.transport.request({...T,headers:{...T.headers,accept:"text/event-stream"}},{signal:R.signal}),R.signal)}finally{clearTimeout(L)}if(z.status!==200)throw await oe(z,R.signal);if(q(z,"make-ai-api-version")!==a||!q(z,"content-type")?.startsWith("text/event-stream"))throw new u("AI_PROTOCOL_ERROR");const ye=new TextDecoder("utf-8",{fatal:!0});let V="";v=setTimeout(w,o.stream?.idleTimeoutMs??6e4);for await(const Oe of me(z,R.signal)){if(clearTimeout(v),v=setTimeout(w,o.stream?.idleTimeoutMs??6e4),S=!0,V+=ye.decode(Oe,{stream:!0}),ee.encode(V).length>P*2)throw new u("AI_RESPONSE_TOO_LARGE");let ne;for(;ne=/\r?\n\r?\n/.exec(V);){const _e=V.slice(0,ne.index);V=V.slice(ne.index+ne[0].length);let $="message",U;const de=[];for(const D of _e.split(/\r?\n/)){const F=D.indexOf(":");if(F<0||F===0)continue;const Q=D.slice(0,F),le=D.slice(F+1).replace(/^ /,"");Q==="event"&&($=le),Q==="id"&&(U=le||void 0),Q==="data"&&de.push(le)}if(!de.length)continue;const ge=de.join(`
|
|
2
|
-
`);if(ee.encode(ge).length>P)throw new u("AI_RESPONSE_TOO_LARGE");U&&W(U);const B=A(JSON.parse(ge));if(B.responseId!==e.responseId)throw new u("AI_PROTOCOL_ERROR");const j={responseId:e.responseId,...U?{cursor:U}:{}};let x;switch($){case"response.subscribed":x={kind:"subscribed",...j};break;case"response.state":x={kind:"state",...j,status:f(B.status,64)};break;case"response.reset":x={kind:"reset",...j,reason:f(B.reason,128)};break;case"response.snapshot":x={kind:"snapshot",...j,snapshot:ue(B,e.chatId,e.responseId)};break;case"response.completed":case"response.failed":case"response.cancelled":x={kind:$.slice(9),...j,...B.code===void 0?{}:{code:f(B.code,128)}};break;case"response.output_item.added":case"response.output_text.delta":case"response.output_item.done":{const D={...j,itemId:g(B.itemId),partId:g(B.partId),sequence:p(B.sequence,1)};x=$==="response.output_item.added"?{kind:"itemAdded",...D}:$==="response.output_text.delta"?{kind:"textDelta",...D,delta:f(B.delta,1e5,!0)}:{kind:"itemDone",...D,text:f(B.text,1e5,!0),final:G(B.final)};break}default:x={kind:"unknown",...j,name:f($,128)}}if(x.kind==="failed"&&x.code==="AI_UPSTREAM_ERROR")throw new u("AI_STREAM_INTERRUPTED",{lastCursor:r});if((x.kind==="reset"||x.kind==="snapshot")&&(d=!0),U){r=U;const D=$+"\0"+JSON.stringify(x),F=c.get(U);if(F!==void 0){if(F!==D)throw new u("AI_PROTOCOL_ERROR");continue}for(c.set(U,D),h+=D.length;c.size>512||h>4e6;){const Q=c.keys().next().value;h-=c.get(Q).length,c.delete(Q)}}if(yield x,["completed","failed","cancelled"].includes(x.kind)||x.kind==="snapshot"&&x.snapshot.terminal)return}S=!1}throw S=!0,ye.decode(),new u("AI_STREAM_INTERRUPTED",{lastCursor:r})}catch(
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Y=require("./conversation-management-f1y0yRvt.cjs"),A=Y.protocolRecord,g=Y.protocolId,f=Y.protocolText,p=Y.protocolInteger,G=Y.protocolBoolean,K=Y.protocolArray;function E(o,a){if(Object.keys(o).some(n=>!a.includes(n)))throw new Error("Invalid request: unknown field")}function Z(o){const a=f(o,36);if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(a))throw new Error("Invalid request: UUID");return a}function W(o,a=!1){return f(o,8192,a)}const se=o=>{const a=f(o,64);if(!Number.isFinite(Date.parse(a)))throw new Error("Invalid response: timestamp");return a};function Ie(o){const a=W(o.nextCursor,!0),n=G(o.hasMore);if(n!==!!a)throw new Error("Invalid response: page cursor");return{nextCursor:a,hasMore:n}}function ae(o,a,n,l){const i=A(o);if(i.appKey!==a||n&&i.agentId!==n||l&&i.chatId!==l||!["active","deleted"].includes(String(i.status)))throw new Error("Invalid response: chat scope");return{chatId:g(i.chatId),appKey:a,agentId:g(i.agentId),title:f(i.title,255,!0),titlePending:i.titlePending===void 0?!1:G(i.titlePending),status:i.status,revision:p(i.revision,1),pinned:G(i.pinned),pinnedAt:i.pinnedAt==null?null:se(i.pinnedAt),createdAt:se(i.createdAt),lastActivityAt:se(i.lastActivityAt)}}function be(o,a,n){const l=A(o),i=K(l.chats,100).map(m=>ae(m,a,n));if(new Set(i.map(m=>m.chatId)).size!==i.length)throw new Error("Invalid response: duplicate chat");return{chats:i,...Ie(l)}}function xe(o,a){const n=A(o);return{agents:K(n.agents,100).map(i=>{const m=A(i);if(m.appKey!==a)throw new Error("Invalid response: agent scope");return{agentId:g(m.agentId),appKey:a,name:f(m.name,255),...m.agentType===void 0?{}:{agentType:f(m.agentType,128)}}}),...Ie(n)}}function ve(o){const a=A(o),n=f(a.digestSha256,64);if(!/^[0-9a-f]{64}$/.test(n))throw new Error("Invalid response: digest");return{contentRef:g(a.contentRef),contentType:f(a.contentType,256),sizeBytes:p(a.sizeBytes),digestSha256:n}}function Ee(o){return K(o,32).map(a=>{const n=A(a),l=f(n.kind,128),i=n.id===void 0?{}:{id:g(n.id)};return l==="text"?{...i,kind:l,text:f(n.text,1e5,!0)}:["image","file","audio","video"].includes(l)?{...i,kind:l,...n.name===void 0?{}:{name:f(n.name,512,!0)},media:ve(n.media)}:{...i,kind:"unknown",originalKind:l,...n.textFallback===void 0?{}:{textFallback:f(n.textFallback,1e5,!0)}}})}function Te(o){const a=A(o);if(!["like","dislike","none"].includes(String(a.rating)))throw new Error("Invalid response: feedback");return{id:g(a.id),rating:a.rating,revision:p(a.revision,1),...a.reason===void 0?{}:{reason:f(a.reason,128,!0)},...a.comment===void 0?{}:{comment:f(a.comment,4e3,!0)}}}function ke(o){const a=A(o);let n=0;const l=K(a.messages,200).map(i=>{const m=A(i);if(m.role!=="user"&&m.role!=="assistant")throw new Error("Invalid response: history role");const P=f(m.text,1e5,!0);return n+=[...P].length,{messageId:g(m.messageId),role:m.role,cursor:W(m.cursor),createdAt:se(m.createdAt),text:P,...m.responseId===void 0?{}:{responseId:g(m.responseId)},...m.parts===void 0?{}:{parts:Ee(m.parts)},...m.feedback===void 0?{}:{feedback:Te(m.feedback)}}});if(n>1e6||new Set(l.map(i=>i.messageId)).size!==l.length)throw new Error("Invalid response: history budget or duplicate identity");return{messages:l,...Ie(a)}}function ue(o,a,n){const l=A(o);if(l.chatId!==a||l.responseId!==n)throw new Error("Invalid response: response scope");const i=f(l.status,64),m=G(l.terminal);if(["completed","failed","cancelled"].includes(i)&&!m||["queued","dispatched","running"].includes(i)&&m)throw new Error("Invalid response: contradictory terminal");const P=K(l.items,20).map(k=>{const _=A(k);return{itemId:g(_.itemId),partId:g(_.partId),text:f(_.text,1e5,!0),final:G(_.final),revision:p(_.revision,1),..._.parts===void 0?{}:{parts:Ee(_.parts)}}});if(P.reduce((k,_)=>k+[..._.text].length,0)>1e5||new Set(P.map(k=>k.itemId)).size!==P.length)throw new Error("Invalid response: output budget or identity");return{chatId:a,responseId:n,status:i,terminal:m,snapshotRevision:p(l.snapshotRevision,1),items:P,...l.cancelRequested===void 0?{}:{cancelRequested:G(l.cancelRequested)}}}function he(o,a){const n=A(o),l=g(n.id),i=f(n.status,64),m=p(n.sizeBytes),P=p(n.partSize,1);if(a&&l!==a)throw new Error("Invalid response: upload identity");const k=K(n.completedParts,65536).map(M=>p(M,0,Math.max(0,Math.ceil(m/P)-1)));if(new Set(k).size!==k.length)throw new Error("Invalid response: upload receipt");const _={id:l,status:i,name:f(n.name,512),contentType:f(n.contentType,256),sizeBytes:m,partSize:P,completedParts:k,...n.expiresAt===void 0?{}:{expiresAt:se(n.expiresAt)}};if(i==="ready"){const M=A(n.content);if(M.kind!=="reference"||M.sizeBytes!==m||!/^[0-9a-f]{64}$/.test(String(M.digestSha256)))throw new Error("Invalid response: upload content");return{..._,content:{kind:"reference",contentRef:g(M.contentRef),sizeBytes:m,digestSha256:String(M.digestSha256)}}}if(i==="uploading"&&!_.expiresAt)throw new Error("Invalid response: upload expiry");return _}function Se(o,a,n){const l=A(o),i=A(l.limits);if(l.apiVersion!=="v1"||l.appKey!==a||l.agentId!==n)throw new Error("Invalid response: capability scope");return{apiVersion:"v1",appKey:a,agentId:n,features:K(l.features,256).map(m=>f(m,128)),modelInputKinds:K(l.modelInputKinds,64).map(m=>f(m,64)),limits:{maxInputTextBytes:p(i.maxInputTextBytes,1),maxMessageBytes:p(i.maxMessageBytes,1),maxInputParts:p(i.maxInputParts,1),maxUploadBytes:p(i.maxUploadBytes,1),uploadPartBytes:p(i.uploadPartBytes,1),maxConcurrentUploads:p(i.maxConcurrentUploads,1),maxSseEventBytes:p(i.maxSseEventBytes,1)}}}class u extends Error{status;code;requestId;retryAfterMs;outcome;lastCursor;constructor(a,n={}){super(a),this.name="ApiError",this.code=a,this.status=n.status,this.requestId=n.requestId,this.retryAfterMs=n.retryAfterMs,this.outcome=n.outcome??"known",this.lastCursor=n.lastCursor}}const ee=new TextEncoder,q=(o,a)=>Object.entries(o.headers).find(([n])=>n.toLowerCase()===a.toLowerCase())?.[1],H=o=>new URLSearchParams(Object.entries(o).filter(([,a])=>a!==void 0).map(([a,n])=>[a,String(n)])).toString(),J=o=>encodeURIComponent(g(o));function te(o,a){return new Promise((n,l)=>{const i=()=>l(new u("AI_CLIENT_ABORTED"));if(a.aborted){o.catch(()=>{}),i();return}a.addEventListener("abort",i,{once:!0}),o.then(n,l).finally(()=>a.removeEventListener("abort",i))})}async function*me(o,a){const n=o.body?.[Symbol.asyncIterator]();if(n)try{for(;;){const l=await te(n.next(),a);if(l.done)return;yield l.value}}finally{n.return?.().catch(()=>{})}}function Pe(o){const a=o.apiVersion??"v1";if(a!=="v1")throw new u("AI_API_VERSION_UNSUPPORTED",{outcome:"notSent"});if(!["sdk","transport"].includes(o.transport.retryOwner))throw new u("AI_BAD_REQUEST",{outcome:"notSent"});const n=Object.freeze({appKey:g(o.scope.appKey),identityKey:f(o.scope.identityKey,8192)}),l=o.basePath??"/api/make/app/ai";if(!/^\/(?!\/)[A-Za-z0-9/_-]+$/.test(l)||/\/v\d+\/?$/.test(l))throw new Error("Invalid request: basePath");if(o.transport.retryOwner==="transport"&&o.retry)throw new Error("Invalid request: multiple retry owners");const i=p(o.retry?.maxAttempts??3,1,5),m=p(o.maxJsonBytes??8*1024*1024,1,32*1024*1024),P=p(o.maxEventBytes??1024*1024,1,4*1024*1024),k=new Set;let _=!1;const M=(e,s,r,t)=>{try{o.onDiagnostic?.({operation:e,code:s,requestId:r,attempts:t})}catch{}},X=(e,s)=>{if(_||e?.signal?.aborted)throw new u("AI_CLIENT_ABORTED",{outcome:"notSent"});const r=p(e?.timeoutMs??s,1,1440*60*1e3),t=new AbortController;k.add(t);const c=()=>t.abort();e?.signal?.addEventListener("abort",c,{once:!0});let h=!1;const d=setTimeout(()=>{h=!0,c()},r);return{controller:t,deadline:Date.now()+r,failure:(I="known")=>new u(h?"AI_CLIENT_TIMEOUT":"AI_CLIENT_ABORTED",{outcome:I}),close:()=>{clearTimeout(d),e?.signal?.removeEventListener("abort",c),k.delete(t),t.abort()}}},re=async(e,s)=>{if(s.aborted)throw new u("AI_CLIENT_ABORTED");await new Promise((r,t)=>{const h=setTimeout(()=>{s.removeEventListener("abort",d),r()},e),d=()=>{clearTimeout(h),s.removeEventListener("abort",d),t(new u("AI_CLIENT_ABORTED"))};s.addEventListener("abort",d,{once:!0})})},fe=async(e,s,r)=>{let t=0;const c=[];for await(const I of me(e,r)){if(t+=I.byteLength,t>s)throw new u("AI_RESPONSE_TOO_LARGE",{status:e.status});c.push(I)}const h=new Uint8Array(t);let d=0;for(const I of c)h.set(I,d),d+=I.length;return h},oe=async(e,s)=>{let r="AI_HTTP_ERROR";try{const h=A(JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(await fe(e,m,s))));typeof h.code=="string"&&h.code.length<128&&(r=h.code)}catch{}const t=q(e,"retry-after"),c=t===void 0?void 0:/^\d+$/.test(t)?Number(t)*1e3:Math.max(0,Date.parse(t)-Date.now());return new u(r,{status:e.status,requestId:q(e,"x-request-id"),retryAfterMs:Number.isFinite(c)?c:void 0})},O=(e,s,r,t)=>({method:e,path:l.replace(/\/$/,"")+"/"+a+s,headers:{accept:"application/json",...r===void 0&&t===void 0?{}:{"content-type":t?"application/octet-stream":"application/json"}},...t===void 0?r===void 0?{}:{body:ee.encode(JSON.stringify(r))}:{body:new Uint8Array(t)}});async function b(e,s,r,t,c=!0,h=[200]){const d=X(t,o.timeoutMs??3e4),I=c&&o.transport.retryOwner==="sdk"?i:1;let y=!1;M(e),console.info("[make-ai-assistant] client operation start",{operation:e});try{for(let T=1;T<=I;T++)try{if(d.controller.signal.aborted||Date.now()>=d.deadline)throw new u("AI_CLIENT_TIMEOUT",{outcome:y?"unknown":"notSent"});y=!0;const w=await te(o.transport.request(s,{signal:d.controller.signal,timeoutMs:Math.max(1,d.deadline-Date.now())}),d.controller.signal);if(w.status<200||w.status>=300)throw await oe(w,d.controller.signal);if(q(w,"make-ai-api-version")!==a||!h.includes(w.status))throw new u("AI_PROTOCOL_ERROR",{status:w.status});let v;if(w.status!==204){if(!q(w,"content-type")?.toLowerCase().includes("application/json"))throw new u("AI_PROTOCOL_ERROR",{status:w.status});try{v=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(await fe(w,m,d.controller.signal)))}catch(S){throw S instanceof u?S:new u("AI_PROTOCOL_ERROR",{status:w.status})}}try{const S=r(v);return M(e,void 0,q(w,"x-request-id"),T),S}catch{throw new u("AI_PROTOCOL_ERROR",{status:w.status,requestId:q(w,"x-request-id")})}}catch(w){if(d.controller.signal.aborted)throw d.failure(y?"unknown":"notSent");let v=w instanceof u?w:new u("AI_TRANSPORT_ERROR",{outcome:y?"unknown":"notSent"});s.method!=="GET"&&y&&((v.status??0)>=500||v.status===408||["AI_PROTOCOL_ERROR","AI_RESPONSE_TOO_LARGE"].includes(v.code))&&(v=new u(v.code,{...v,outcome:"unknown"}));const S=v.code==="AI_TRANSPORT_ERROR"||[429,502,503,504].includes(v.status??0)&&v.code!=="AI_QUOTA_EXCEEDED",R=v.retryAfterMs??Math.min(o.retry?.maxDelayMs??5e3,100*2**(T-1)*(.5+Math.random()));if(!S||T===I||d.controller.signal.aborted||Date.now()+R>=d.deadline)throw v;await re(R,d.controller.signal)}throw new u("AI_TRANSPORT_ERROR",{outcome:"unknown"})}catch(T){throw M(e,T instanceof u?T.code:"AI_CLIENT_ERROR"),console.warn("[make-ai-assistant] client operation failed",{operation:e}),T}finally{d.close()}}const C=e=>"/chats/"+J(e),pe=e=>C(e.chatId)+"/responses/"+J(e.responseId),ie=(e,s)=>({...e.cursor===void 0?{}:{cursor:W(e.cursor)},...e.limit===void 0?{}:{limit:p(e.limit,1,s)}}),Re=e=>{if(E(e,["chatId","messageId","text","parts"]),g(e.chatId),Z(e.messageId),e.text===void 0==(e.parts===void 0))throw new Error("Invalid request: text and parts are exclusive");let s=e.text??"";if(e.parts!==void 0){const c=new Set;for(const h of K(e.parts,32)){const d=A(h),I=Z(d.id);if(c.has(I))throw new Error("Invalid request: duplicate part");if(c.add(I),d.kind==="text")E(d,["id","kind","text"]),s+=f(d.text,8192,!0);else{if(E(d,["id","kind","name","media"]),!["image","file","audio","video"].includes(String(d.kind)))throw new Error("Invalid request: part kind");E(A(d.media),["contentRef","contentType","sizeBytes","digestSha256"]);const y=ve(d.media);if(d.name!==void 0&&/[\r\n/\\]/.test(f(d.name,512)))throw new u("AI_BAD_REQUEST",{outcome:"notSent"});if(!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(y.contentType)||d.kind!=="file"&&(!y.contentType.startsWith(String(d.kind)+"/")||y.contentType==="image/svg+xml"))throw new u("AI_BAD_REQUEST",{outcome:"notSent"})}}if(!e.parts.length||!s.trim()&&e.parts.every(h=>h.kind==="text"))throw new Error("Invalid request: empty message")}else f(e.text,8192);if(ee.encode(s).length>8192)throw new Error("Invalid request: text exceeds 8 KiB");const{chatId:r,...t}=e;if(ee.encode(JSON.stringify(t)).length>65536)throw new Error("Invalid request: message too large");return t},ce=new Map;async function*we(e,s,r,t){p(r,1,1e4),p(t,1);const c=new Set;let h=s,d=0;for(let I=0;I<r;I++){const y=await e(h);for(const T of y.values){if(++d>t)throw new u("AI_ITERATION_LIMIT",{lastCursor:h});yield T}if(!y.hasMore)return;if(y.nextCursor===h||c.has(y.nextCursor))throw new u("AI_PROTOCOL_ERROR");c.add(y.nextCursor),h=y.nextCursor}throw new u("AI_ITERATION_LIMIT",{lastCursor:h})}const N={apiVersion:a,scope:n,capabilities:{async get(e,s){E(e,["agentId"]);const r=g(e.agentId),t=ce.get(r);if(!_&&!s?.signal?.aborted&&t&&t.expires>Date.now())return t.value;const c=await b("capabilities.get",O("GET","/capabilities?"+H({appKey:n.appKey,agentId:r})),h=>Se(h,n.appKey,r),s);return ce.set(r,{value:c,expires:Date.now()+6e4}),c}},agents:{async list(e={},s){return E(e,["cursor","limit"]),b("agents.list",O("GET","/agents?"+H({appKey:n.appKey,...ie(e,100)})),r=>xe(r,n.appKey),s)}},chats:{async create(e,s){E(e,["agentId","requestId","title"]);const r=g(e.agentId);return Z(e.requestId),e.title!==void 0&&f(e.title,255),b("chats.create",O("POST","/chats",{appKey:n.appKey,...e}),t=>ae(t,n.appKey,r),s,!0,[201])},async list(e,s){E(e,["agentId","cursor","limit"]);const r=g(e.agentId);return b("chats.list",O("GET","/chats?"+H({appKey:n.appKey,agentId:r,...ie(e,100)})),t=>be(t,n.appKey,r),s)},async get(e,s){return E(e,["chatId"]),b("chats.get",O("GET",C(e.chatId)),r=>ae(r,n.appKey,void 0,e.chatId),s)},async update(e,s){if(E(e,["chatId","expectedRevision","title","pinned"]),p(e.expectedRevision,1),e.title===void 0&&e.pinned===void 0)throw new Error("Invalid request: empty patch");e.title!==void 0&&f(e.title,255),e.pinned!==void 0&&G(e.pinned);const{chatId:r,...t}=e;return b("chats.update",O("PATCH",C(r),t),c=>ae(c,n.appKey,void 0,r),s,!1)},async delete(e,s){E(e,["chatId","expectedRevision"]),p(e.expectedRevision,1),await b("chats.delete",O("DELETE",C(e.chatId)+"?"+H({expectedRevision:e.expectedRevision})),()=>{},s,!1,[204])},iterate(e,s){return we(async r=>{const t=await N.chats.list({...e,cursor:r},s);return{...t,values:t.chats}},e.cursor,s.maxPages,s.maxItems)}},messages:{async send(e,s){const r=Re(e);return b("messages.send",O("POST",C(e.chatId)+"/messages",r),t=>{const c=A(t);if(c.chatId!==e.chatId||c.messageId!==e.messageId)throw new Error("Invalid response: accepted scope");return{chatId:e.chatId,messageId:e.messageId,responseId:g(c.responseId),...c.acceptedCursor===void 0?{}:{acceptedCursor:W(c.acceptedCursor)}}},s,!0,[202])},async list(e,s){E(e,["chatId","cursor","limit"]);const r=H(ie(e,200));return b("messages.list",O("GET",C(e.chatId)+"/messages"+(r?"?"+r:"")),ke,s)},iterate(e,s){return we(async r=>{const t=await N.messages.list({...e,cursor:r},s);return{...t,values:t.messages}},e.cursor,s.maxPages,s.maxItems)},async sendAndWatch(e,s){const r=Date.now(),t=await N.messages.send(e,s),c=(s?.timeoutMs??o.stream?.maxDurationMs??6e5)-(Date.now()-r);if(c<=0)throw new u("AI_CLIENT_TIMEOUT",{outcome:"known"});return{accepted:t,events:N.responses.subscribe({chatId:t.chatId,responseId:t.responseId},{...s,timeoutMs:c})}}},responses:{async get(e,s){return E(e,["chatId","responseId"]),b("responses.get",O("GET",pe(e)),r=>ue(r,e.chatId,e.responseId),s)},subscribe(e,s){return Ae(e,s)},async cancel(e,s){return E(e,["chatId","responseId"]),b("responses.cancel",O("POST",pe(e)+"/cancel",{}),r=>ue(r,e.chatId,e.responseId),s,!0,[200,202])},async waitForTerminal(e,s){const r=X(s,s.timeoutMs);try{for(;!r.controller.signal.aborted;){const t=await N.responses.get(e,{signal:r.controller.signal,timeoutMs:Math.max(1,r.deadline-Date.now())});if(t.terminal)return t;await re(s.pollIntervalMs??1e3,r.controller.signal)}throw new u("AI_CLIENT_TIMEOUT")}finally{r.close()}}},feedback:{async set(e,s){if(E(e,["chatId","messageId","requestId","rating","reason","comment"]),Z(e.requestId),!["like","dislike","none"].includes(e.rating))throw new Error("Invalid request: rating");e.reason!==void 0&&f(e.reason,128,!0),e.comment!==void 0&&f(e.comment,4e3,!0);const{chatId:r,messageId:t,...c}=e;return b("feedback.set",O("PUT",C(r)+"/messages/"+J(t)+"/feedback",c),Te,s)}},uploads:{async start(e,s){E(e,["chatId","fileId","name","contentType","sizeBytes","digestSha256"]),Z(e.fileId),f(e.name,512),f(e.contentType,256),p(e.sizeBytes,1);const{chatId:r,...t}=e;return b("uploads.start",O("POST",C(r)+"/uploads",t),c=>he(c),s)},async get(e,s){return E(e,["chatId","uploadId"]),b("uploads.get",O("GET",C(e.chatId)+"/uploads/"+J(e.uploadId)),r=>he(r,e.uploadId),s)},async putPart(e,s){if(E(e,["chatId","uploadId","part","bytes"]),p(e.part),!(e.bytes instanceof Uint8Array)||e.bytes.length>m)throw new Error("Invalid request: upload bytes");await b("uploads.putPart",O("PUT",C(e.chatId)+"/uploads/"+J(e.uploadId)+"/parts/"+e.part,void 0,e.bytes),()=>{},s,!0,[204])},async complete(e,s){return E(e,["chatId","uploadId"]),b("uploads.complete",O("POST",C(e.chatId)+"/uploads/"+J(e.uploadId)+"/complete",{}),r=>he(r,e.uploadId),s)},async uploadFile(e,s){const r=p(s?.concurrency??2,1,8),t=X(s,o.timeoutMs??3e5),c=()=>({signal:t.controller.signal,timeoutMs:Math.max(1,t.deadline-Date.now())});try{const{source:h,...d}=e,I=await N.uploads.start({...d,sizeBytes:h.sizeBytes},c());if(I.status==="ready")return I;if(I.status!=="uploading"||I.partSize>m||I.sizeBytes!==h.sizeBytes)throw new u("AI_UPLOAD_UNAVAILABLE");const y=new Set(I.completedParts),T=Math.ceil(h.sizeBytes/I.partSize);let w=0,v=I.completedParts.reduce((R,L)=>R+Math.min(I.partSize,h.sizeBytes-L*I.partSize),0);const S=Array.from({length:r},async()=>{for(;w<T;){if(t.controller.signal.aborted)throw t.failure();const R=w++;if(y.has(R))continue;const L=Math.min(I.partSize,h.sizeBytes-R*I.partSize),z=await te(h.read(R*I.partSize,L,c()),t.controller.signal);if(!(z instanceof Uint8Array)||z.length!==L)throw new u("AI_CONTENT_INTEGRITY_ERROR");await N.uploads.putPart({chatId:e.chatId,uploadId:I.id,part:R,bytes:z},c()),v+=L;try{s?.onProgress?.(v)}catch{}}});try{await Promise.all(S)}catch(R){throw t.controller.abort(),await Promise.allSettled(S),R}return await N.uploads.complete({chatId:e.chatId,uploadId:I.id},c())}finally{t.close()}}},content:{async read(e,s){M("content.read"),console.info("[make-ai-assistant] client operation start",{operation:"content.read"}),E(e,["chatId","contentRef","maxBytes"]),p(e.maxBytes,1);const r=X(s,o.timeoutMs??3e4);try{const t=await te(o.transport.request(O("GET",C(e.chatId)+"/content/"+J(e.contentRef)),{signal:r.controller.signal}),r.controller.signal);if(t.status!==200)throw await oe(t,r.controller.signal);if(q(t,"make-ai-api-version")!==a)throw new u("AI_PROTOCOL_ERROR");const c=q(t,"content-length"),h=c===void 0?void 0:Number(c);if(h!==void 0&&(!Number.isSafeInteger(h)||h<0||h>e.maxBytes))throw new u("AI_RESPONSE_TOO_LARGE");return{contentType:q(t,"content-type"),contentLength:h,body:(async function*(){let d=0;try{for await(const I of me(t,r.controller.signal)){if(d+=I.length,d>e.maxBytes)throw new u("AI_RESPONSE_TOO_LARGE");yield I}if(h!==void 0&&h!==d)throw new u("AI_CONTENT_INTEGRITY_ERROR")}finally{r.close()}})()}}catch(t){throw r.close(),t}}},dispose(){_=!0,ce.clear();for(const e of k)e.abort();k.clear()}};async function*Ae(e,s){M("responses.subscribe"),console.info("[make-ai-assistant] client operation start",{operation:"responses.subscribe"}),E(e,["chatId","responseId","cursor"]),g(e.chatId),g(e.responseId);let r=e.cursor===void 0?void 0:W(e.cursor);const t=X(s,o.stream?.maxDurationMs??6e5),c=new Map;let h=0,d=!1;const I=o.transport.retryOwner==="sdk"?i:1;try{for(let y=1;y<=I;y++){const T=new AbortController,w=()=>T.abort();t.controller.signal.addEventListener("abort",w,{once:!0});let v,S=!1;try{if(t.controller.signal.aborted)throw t.failure();const R=O("GET",C(e.chatId)+"/events?"+H({responseId:e.responseId,cursor:r})),L=setTimeout(w,o.stream?.connectTimeoutMs??3e4);let z;try{z=await te(o.transport.request({...R,headers:{...R.headers,accept:"text/event-stream"}},{signal:T.signal}),T.signal)}finally{clearTimeout(L)}if(z.status!==200)throw await oe(z,T.signal);if(q(z,"make-ai-api-version")!==a||!q(z,"content-type")?.startsWith("text/event-stream"))throw new u("AI_PROTOCOL_ERROR");const ye=new TextDecoder("utf-8",{fatal:!0});let V="";v=setTimeout(w,o.stream?.idleTimeoutMs??6e4);for await(const Oe of me(z,T.signal)){if(clearTimeout(v),v=setTimeout(w,o.stream?.idleTimeoutMs??6e4),S=!0,V+=ye.decode(Oe,{stream:!0}),ee.encode(V).length>P*2)throw new u("AI_RESPONSE_TOO_LARGE");let ne;for(;ne=/\r?\n\r?\n/.exec(V);){const _e=V.slice(0,ne.index);V=V.slice(ne.index+ne[0].length);let $="message",U;const de=[];for(const D of _e.split(/\r?\n/)){const F=D.indexOf(":");if(F<0||F===0)continue;const Q=D.slice(0,F),le=D.slice(F+1).replace(/^ /,"");Q==="event"&&($=le),Q==="id"&&(U=le||void 0),Q==="data"&&de.push(le)}if(!de.length)continue;const ge=de.join(`
|
|
2
|
+
`);if(ee.encode(ge).length>P)throw new u("AI_RESPONSE_TOO_LARGE");U&&W(U);const B=A(JSON.parse(ge));if(B.responseId!==e.responseId)throw new u("AI_PROTOCOL_ERROR");const j={responseId:e.responseId,...U?{cursor:U}:{}};let x;switch($){case"response.subscribed":x={kind:"subscribed",...j};break;case"response.state":x={kind:"state",...j,status:f(B.status,64)};break;case"response.reset":x={kind:"reset",...j,reason:f(B.reason,128)};break;case"response.snapshot":x={kind:"snapshot",...j,snapshot:ue(B,e.chatId,e.responseId)};break;case"response.completed":case"response.failed":case"response.cancelled":x={kind:$.slice(9),...j,...B.code===void 0?{}:{code:f(B.code,128)}};break;case"response.output_item.added":case"response.output_text.delta":case"response.output_item.done":{const D={...j,itemId:g(B.itemId),partId:g(B.partId),sequence:p(B.sequence,1)};x=$==="response.output_item.added"?{kind:"itemAdded",...D}:$==="response.output_text.delta"?{kind:"textDelta",...D,delta:f(B.delta,1e5,!0)}:{kind:"itemDone",...D,text:f(B.text,1e5,!0),final:G(B.final)};break}default:x={kind:"unknown",...j,name:f($,128)}}if(x.kind==="failed"&&x.code==="AI_UPSTREAM_ERROR")throw new u("AI_STREAM_INTERRUPTED",{lastCursor:r});if((x.kind==="reset"||x.kind==="snapshot")&&(d=!0),U){r=U;const D=$+"\0"+JSON.stringify(x),F=c.get(U);if(F!==void 0){if(F!==D)throw new u("AI_PROTOCOL_ERROR");continue}for(c.set(U,D),h+=D.length;c.size>512||h>4e6;){const Q=c.keys().next().value;h-=c.get(Q).length,c.delete(Q)}}if(yield x,["completed","failed","cancelled"].includes(x.kind)||x.kind==="snapshot"&&x.snapshot.terminal)return}S=!1}throw S=!0,ye.decode(),new u("AI_STREAM_INTERRUPTED",{lastCursor:r})}catch(R){if(t.controller.signal.aborted)throw t.failure();if(!(R instanceof u)&&S)throw new u("AI_PROTOCOL_ERROR",{lastCursor:r});if(R instanceof u&&!["AI_STREAM_INTERRUPTED","AI_CLIENT_ABORTED"].includes(R.code)&&![429,502,503,504].includes(R.status??0))throw R;if(d){for(console.info("[make-ai-assistant] stream recovery uses confirmed snapshots");!t.controller.signal.aborted;){const L=await N.responses.get({chatId:e.chatId,responseId:e.responseId},{signal:t.controller.signal,timeoutMs:Math.max(1,t.deadline-Date.now())});if(yield{kind:"snapshot",snapshot:L},L.terminal)return;await re(1e3,t.controller.signal)}throw t.failure()}if(y===I){const L=await N.responses.get({chatId:e.chatId,responseId:e.responseId},{signal:t.controller.signal,timeoutMs:Math.max(1,t.deadline-Date.now())});if(yield{kind:"snapshot",snapshot:L},L.terminal)return;throw new u("AI_STREAM_INTERRUPTED",{lastCursor:r})}await re(Math.min(o.retry?.maxDelayMs??2e3,500*y),t.controller.signal)}finally{clearTimeout(v),t.controller.signal.removeEventListener("abort",w),T.abort()}}}finally{t.close()}}return N}exports.ApiError=u;exports.createMakeAgentClient=Pe;
|
package/dist/client.mjs
CHANGED
|
@@ -56,7 +56,12 @@ function Ce(o, a) {
|
|
|
56
56
|
return { agents: K(n.agents, 100).map((i) => {
|
|
57
57
|
const m = A(i);
|
|
58
58
|
if (m.appKey !== a) throw new Error("Invalid response: agent scope");
|
|
59
|
-
return {
|
|
59
|
+
return {
|
|
60
|
+
agentId: g(m.agentId),
|
|
61
|
+
appKey: a,
|
|
62
|
+
name: f(m.name, 255),
|
|
63
|
+
...m.agentType === void 0 ? {} : { agentType: f(m.agentType, 128) }
|
|
64
|
+
};
|
|
60
65
|
}), ...me(n) };
|
|
61
66
|
}
|
|
62
67
|
function ge(o) {
|
|
@@ -364,7 +369,7 @@ function De(o) {
|
|
|
364
369
|
let y = !1;
|
|
365
370
|
M(e), console.info("[make-ai-assistant] client operation start", { operation: e });
|
|
366
371
|
try {
|
|
367
|
-
for (let
|
|
372
|
+
for (let T = 1; T <= I; T++)
|
|
368
373
|
try {
|
|
369
374
|
if (d.controller.signal.aborted || Date.now() >= d.deadline)
|
|
370
375
|
throw new h("AI_CLIENT_TIMEOUT", {
|
|
@@ -412,7 +417,7 @@ function De(o) {
|
|
|
412
417
|
e,
|
|
413
418
|
void 0,
|
|
414
419
|
q(w, "x-request-id"),
|
|
415
|
-
|
|
420
|
+
T
|
|
416
421
|
), S;
|
|
417
422
|
} catch {
|
|
418
423
|
throw new h("AI_PROTOCOL_ERROR", {
|
|
@@ -432,22 +437,22 @@ function De(o) {
|
|
|
432
437
|
...v,
|
|
433
438
|
outcome: "unknown"
|
|
434
439
|
}));
|
|
435
|
-
const S = v.code === "AI_TRANSPORT_ERROR" || [429, 502, 503, 504].includes(v.status ?? 0) && v.code !== "AI_QUOTA_EXCEEDED",
|
|
440
|
+
const S = v.code === "AI_TRANSPORT_ERROR" || [429, 502, 503, 504].includes(v.status ?? 0) && v.code !== "AI_QUOTA_EXCEEDED", R = v.retryAfterMs ?? Math.min(
|
|
436
441
|
o.retry?.maxDelayMs ?? 5e3,
|
|
437
|
-
100 * 2 ** (
|
|
442
|
+
100 * 2 ** (T - 1) * (0.5 + Math.random())
|
|
438
443
|
);
|
|
439
|
-
if (!S ||
|
|
444
|
+
if (!S || T === I || d.controller.signal.aborted || Date.now() + R >= d.deadline)
|
|
440
445
|
throw v;
|
|
441
|
-
await se(
|
|
446
|
+
await se(R, d.controller.signal);
|
|
442
447
|
}
|
|
443
448
|
throw new h("AI_TRANSPORT_ERROR", { outcome: "unknown" });
|
|
444
|
-
} catch (
|
|
449
|
+
} catch (T) {
|
|
445
450
|
throw M(
|
|
446
451
|
e,
|
|
447
|
-
|
|
452
|
+
T instanceof h ? T.code : "AI_CLIENT_ERROR"
|
|
448
453
|
), console.warn("[make-ai-assistant] client operation failed", {
|
|
449
454
|
operation: e
|
|
450
|
-
}),
|
|
455
|
+
}), T;
|
|
451
456
|
} finally {
|
|
452
457
|
d.close();
|
|
453
458
|
}
|
|
@@ -455,7 +460,7 @@ function De(o) {
|
|
|
455
460
|
const C = (e) => "/chats/" + J(e), fe = (e) => C(e.chatId) + "/responses/" + J(e.responseId), oe = (e, s) => ({
|
|
456
461
|
...e.cursor === void 0 ? {} : { cursor: W(e.cursor) },
|
|
457
462
|
...e.limit === void 0 ? {} : { limit: p(e.limit, 1, s) }
|
|
458
|
-
}),
|
|
463
|
+
}), Te = (e) => {
|
|
459
464
|
if (E(e, ["chatId", "messageId", "text", "parts"]), g(e.chatId), X(e.messageId), e.text === void 0 == (e.parts === void 0))
|
|
460
465
|
throw new Error("Invalid request: text and parts are exclusive");
|
|
461
466
|
let s = e.text ?? "";
|
|
@@ -501,10 +506,10 @@ function De(o) {
|
|
|
501
506
|
let u = s, d = 0;
|
|
502
507
|
for (let I = 0; I < r; I++) {
|
|
503
508
|
const y = await e(u);
|
|
504
|
-
for (const
|
|
509
|
+
for (const T of y.values) {
|
|
505
510
|
if (++d > t)
|
|
506
511
|
throw new h("AI_ITERATION_LIMIT", { lastCursor: u });
|
|
507
|
-
yield
|
|
512
|
+
yield T;
|
|
508
513
|
}
|
|
509
514
|
if (!y.hasMore) return;
|
|
510
515
|
if (y.nextCursor === u || c.has(y.nextCursor))
|
|
@@ -634,7 +639,7 @@ function De(o) {
|
|
|
634
639
|
},
|
|
635
640
|
messages: {
|
|
636
641
|
async send(e, s) {
|
|
637
|
-
const r =
|
|
642
|
+
const r = Te(e);
|
|
638
643
|
return b(
|
|
639
644
|
"messages.send",
|
|
640
645
|
O("POST", C(e.chatId) + "/messages", r),
|
|
@@ -701,7 +706,7 @@ function De(o) {
|
|
|
701
706
|
);
|
|
702
707
|
},
|
|
703
708
|
subscribe(e, s) {
|
|
704
|
-
return
|
|
709
|
+
return Re(e, s);
|
|
705
710
|
},
|
|
706
711
|
async cancel(e, s) {
|
|
707
712
|
return E(e, ["chatId", "responseId"]), b(
|
|
@@ -827,30 +832,30 @@ function De(o) {
|
|
|
827
832
|
if (I.status === "ready") return I;
|
|
828
833
|
if (I.status !== "uploading" || I.partSize > m || I.sizeBytes !== u.sizeBytes)
|
|
829
834
|
throw new h("AI_UPLOAD_UNAVAILABLE");
|
|
830
|
-
const y = new Set(I.completedParts),
|
|
835
|
+
const y = new Set(I.completedParts), T = Math.ceil(u.sizeBytes / I.partSize);
|
|
831
836
|
let w = 0, v = I.completedParts.reduce(
|
|
832
|
-
(
|
|
837
|
+
(R, L) => R + Math.min(
|
|
833
838
|
I.partSize,
|
|
834
839
|
u.sizeBytes - L * I.partSize
|
|
835
840
|
),
|
|
836
841
|
0
|
|
837
842
|
);
|
|
838
843
|
const S = Array.from({ length: r }, async () => {
|
|
839
|
-
for (; w <
|
|
844
|
+
for (; w < T; ) {
|
|
840
845
|
if (t.controller.signal.aborted) throw t.failure();
|
|
841
|
-
const
|
|
842
|
-
if (y.has(
|
|
846
|
+
const R = w++;
|
|
847
|
+
if (y.has(R)) continue;
|
|
843
848
|
const L = Math.min(
|
|
844
849
|
I.partSize,
|
|
845
|
-
u.sizeBytes -
|
|
850
|
+
u.sizeBytes - R * I.partSize
|
|
846
851
|
), z = await ee(
|
|
847
|
-
u.read(
|
|
852
|
+
u.read(R * I.partSize, L, c()),
|
|
848
853
|
t.controller.signal
|
|
849
854
|
);
|
|
850
855
|
if (!(z instanceof Uint8Array) || z.length !== L)
|
|
851
856
|
throw new h("AI_CONTENT_INTEGRITY_ERROR");
|
|
852
857
|
await N.uploads.putPart(
|
|
853
|
-
{ chatId: e.chatId, uploadId: I.id, part:
|
|
858
|
+
{ chatId: e.chatId, uploadId: I.id, part: R, bytes: z },
|
|
854
859
|
c()
|
|
855
860
|
), v += L;
|
|
856
861
|
try {
|
|
@@ -861,8 +866,8 @@ function De(o) {
|
|
|
861
866
|
});
|
|
862
867
|
try {
|
|
863
868
|
await Promise.all(S);
|
|
864
|
-
} catch (
|
|
865
|
-
throw t.controller.abort(), await Promise.allSettled(S),
|
|
869
|
+
} catch (R) {
|
|
870
|
+
throw t.controller.abort(), await Promise.allSettled(S), R;
|
|
866
871
|
}
|
|
867
872
|
return await N.uploads.complete(
|
|
868
873
|
{ chatId: e.chatId, uploadId: I.id },
|
|
@@ -929,7 +934,7 @@ function De(o) {
|
|
|
929
934
|
k.clear();
|
|
930
935
|
}
|
|
931
936
|
};
|
|
932
|
-
async function*
|
|
937
|
+
async function* Re(e, s) {
|
|
933
938
|
M("responses.subscribe"), console.info("[make-ai-assistant] client operation start", {
|
|
934
939
|
operation: "responses.subscribe"
|
|
935
940
|
}), E(e, ["chatId", "responseId", "cursor"]), g(e.chatId), g(e.responseId);
|
|
@@ -939,14 +944,14 @@ function De(o) {
|
|
|
939
944
|
const I = o.transport.retryOwner === "sdk" ? i : 1;
|
|
940
945
|
try {
|
|
941
946
|
for (let y = 1; y <= I; y++) {
|
|
942
|
-
const
|
|
947
|
+
const T = new AbortController(), w = () => T.abort();
|
|
943
948
|
t.controller.signal.addEventListener("abort", w, {
|
|
944
949
|
once: !0
|
|
945
950
|
});
|
|
946
951
|
let v, S = !1;
|
|
947
952
|
try {
|
|
948
953
|
if (t.controller.signal.aborted) throw t.failure();
|
|
949
|
-
const
|
|
954
|
+
const R = O(
|
|
950
955
|
"GET",
|
|
951
956
|
C(e.chatId) + "/events?" + H({ responseId: e.responseId, cursor: r })
|
|
952
957
|
), L = setTimeout(
|
|
@@ -958,18 +963,18 @@ function De(o) {
|
|
|
958
963
|
z = await ee(
|
|
959
964
|
o.transport.request(
|
|
960
965
|
{
|
|
961
|
-
...
|
|
962
|
-
headers: { ...
|
|
966
|
+
...R,
|
|
967
|
+
headers: { ...R.headers, accept: "text/event-stream" }
|
|
963
968
|
},
|
|
964
|
-
{ signal:
|
|
969
|
+
{ signal: T.signal }
|
|
965
970
|
),
|
|
966
|
-
|
|
971
|
+
T.signal
|
|
967
972
|
);
|
|
968
973
|
} finally {
|
|
969
974
|
clearTimeout(L);
|
|
970
975
|
}
|
|
971
976
|
if (z.status !== 200)
|
|
972
|
-
throw await ae(z,
|
|
977
|
+
throw await ae(z, T.signal);
|
|
973
978
|
if (q(z, "make-ai-api-version") !== a || !q(z, "content-type")?.startsWith("text/event-stream"))
|
|
974
979
|
throw new h("AI_PROTOCOL_ERROR");
|
|
975
980
|
const we = new TextDecoder("utf-8", { fatal: !0 });
|
|
@@ -978,7 +983,7 @@ function De(o) {
|
|
|
978
983
|
w,
|
|
979
984
|
o.stream?.idleTimeoutMs ?? 6e4
|
|
980
985
|
);
|
|
981
|
-
for await (const Ae of he(z,
|
|
986
|
+
for await (const Ae of he(z, T.signal)) {
|
|
982
987
|
if (clearTimeout(v), v = setTimeout(
|
|
983
988
|
w,
|
|
984
989
|
o.stream?.idleTimeoutMs ?? 6e4
|
|
@@ -1099,14 +1104,14 @@ function De(o) {
|
|
|
1099
1104
|
S = !1;
|
|
1100
1105
|
}
|
|
1101
1106
|
throw S = !0, we.decode(), new h("AI_STREAM_INTERRUPTED", { lastCursor: r });
|
|
1102
|
-
} catch (
|
|
1107
|
+
} catch (R) {
|
|
1103
1108
|
if (t.controller.signal.aborted) throw t.failure();
|
|
1104
|
-
if (!(
|
|
1109
|
+
if (!(R instanceof h) && S)
|
|
1105
1110
|
throw new h("AI_PROTOCOL_ERROR", { lastCursor: r });
|
|
1106
|
-
if (
|
|
1107
|
-
|
|
1108
|
-
) && ![429, 502, 503, 504].includes(
|
|
1109
|
-
throw
|
|
1111
|
+
if (R instanceof h && !["AI_STREAM_INTERRUPTED", "AI_CLIENT_ABORTED"].includes(
|
|
1112
|
+
R.code
|
|
1113
|
+
) && ![429, 502, 503, 504].includes(R.status ?? 0))
|
|
1114
|
+
throw R;
|
|
1110
1115
|
if (d) {
|
|
1111
1116
|
for (console.info(
|
|
1112
1117
|
"[make-ai-assistant] stream recovery uses confirmed snapshots"
|
|
@@ -1139,7 +1144,7 @@ function De(o) {
|
|
|
1139
1144
|
t.controller.signal
|
|
1140
1145
|
);
|
|
1141
1146
|
} finally {
|
|
1142
|
-
clearTimeout(v), t.controller.signal.removeEventListener("abort", w),
|
|
1147
|
+
clearTimeout(v), t.controller.signal.removeEventListener("abort", w), T.abort();
|
|
1143
1148
|
}
|
|
1144
1149
|
}
|
|
1145
1150
|
} finally {
|
|
@@ -49,6 +49,7 @@ export interface AssistantAgent {
|
|
|
49
49
|
agentId: string;
|
|
50
50
|
appKey: string;
|
|
51
51
|
name: string;
|
|
52
|
+
agentType?: "app_internal" | "channel" | (string & {});
|
|
52
53
|
}
|
|
53
54
|
export type AssistantResponseStatus = "queued" | "dispatched" | "running" | "completed" | "failed" | "cancelled" | (string & {});
|
|
54
55
|
export interface AssistantOutputItem {
|
|
@@ -4,7 +4,10 @@ export declare const newRequestId: () => `${string}-${string}-${string}-${string
|
|
|
4
4
|
export declare const operationError: (error: unknown) => string;
|
|
5
5
|
export declare function useConversationManager(context: MakeAssistantHostContext, transport: AssistantTransport): {
|
|
6
6
|
enabled: boolean;
|
|
7
|
+
available: boolean;
|
|
8
|
+
configurationError: string | undefined;
|
|
7
9
|
canEdit: boolean;
|
|
10
|
+
canDelete: boolean;
|
|
8
11
|
state: AssistantConversationState;
|
|
9
12
|
setState: Dispatch<SetStateAction<AssistantConversationState>>;
|
|
10
13
|
chats: AssistantChat[];
|