@lark-base-open/base-site-channel 0.1.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/LICENSE +6 -0
- package/README.md +797 -0
- package/dist/binary_fetch-0a477817.d.ts +88 -0
- package/dist/client.d.ts +52 -0
- package/dist/client.mjs +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.mjs +288 -0
- package/dist/runtime-contract.d.ts +313 -0
- package/dist/runtime-contract.mjs +1 -0
- package/dist/runtime.d.ts +115 -0
- package/dist/runtime.mjs +4 -0
- package/package.json +1 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
declare const SITE_RUNTIME_PROTOCOL_VERSION: "site.v1";
|
|
2
|
+
declare const SiteRuntimeApi: {
|
|
3
|
+
readonly AIFunctionStreamClose: "site.v1.ai.function.stream.close";
|
|
4
|
+
readonly AIFunctionStreamOpen: "site.v1.ai.function.stream.open";
|
|
5
|
+
readonly AttachmentUpload: "site.v1.attachment.upload";
|
|
6
|
+
readonly AttachmentUploadCancel: "site.v1.attachment.upload.cancel";
|
|
7
|
+
readonly FunctionInvoke: "site.v1.function.invoke";
|
|
8
|
+
readonly HttpRequest: "site.v1.http.request";
|
|
9
|
+
readonly HttpRequestCancel: "site.v1.http.request.cancel";
|
|
10
|
+
readonly RuntimeContext: "site.v1.runtime.context";
|
|
11
|
+
readonly StreamClose: "site.v1.chatbot.stream.close";
|
|
12
|
+
readonly StreamOpen: "site.v1.chatbot.stream.open";
|
|
13
|
+
};
|
|
14
|
+
declare const SiteRuntimeEvent: {
|
|
15
|
+
readonly AIFunctionStreamDone: "site.v1.ai.function.stream.done";
|
|
16
|
+
readonly AIFunctionStreamError: "site.v1.ai.function.stream.error";
|
|
17
|
+
readonly AIFunctionStreamMessage: "site.v1.ai.function.stream.message";
|
|
18
|
+
readonly AttachmentUploadProgress: "site.v1.attachment.upload.progress";
|
|
19
|
+
readonly LifecycleLoadFailed: "site.v1.lifecycle.load-failed";
|
|
20
|
+
readonly LifecycleReady: "site.v1.lifecycle.ready";
|
|
21
|
+
readonly ModeChanged: "site.v1.runtime.mode-changed";
|
|
22
|
+
readonly StreamError: "site.v1.chatbot.stream.error";
|
|
23
|
+
readonly StreamMessage: "site.v1.chatbot.stream.message";
|
|
24
|
+
};
|
|
25
|
+
declare const SiteRuntimeFunction: {
|
|
26
|
+
readonly GetCurrentUser: "function.runtime.getCurrentUser";
|
|
27
|
+
readonly Logout: "function.runtime.logout";
|
|
28
|
+
readonly RequestEdit: "function.runtime.requestEdit";
|
|
29
|
+
};
|
|
30
|
+
declare const SiteRuntimeErrorCode: {
|
|
31
|
+
readonly AttachmentUnavailable: "ATTACHMENT_UNAVAILABLE";
|
|
32
|
+
readonly AttachmentUploadCanceled: "ATTACHMENT_UPLOAD_CANCELED";
|
|
33
|
+
readonly AttachmentUploadFailed: "ATTACHMENT_UPLOAD_FAILED";
|
|
34
|
+
readonly AttachmentUploadStalled: "ATTACHMENT_UPLOAD_STALLED";
|
|
35
|
+
readonly ChannelDestroyed: "CHANNEL_DESTROYED";
|
|
36
|
+
readonly FunctionNotAllowed: "FUNCTION_NOT_ALLOWED";
|
|
37
|
+
readonly FunctionRequestFailed: "FUNCTION_REQUEST_FAILED";
|
|
38
|
+
readonly InvalidAIFunctionTask: "INVALID_AI_FUNCTION_TASK";
|
|
39
|
+
readonly HttpRequestFailed: "HTTP_REQUEST_FAILED";
|
|
40
|
+
readonly HttpResponseTypeUnsupported: "HTTP_RESPONSE_TYPE_UNSUPPORTED";
|
|
41
|
+
readonly HttpRequestCanceled: "HTTP_REQUEST_CANCELED";
|
|
42
|
+
readonly InvalidAttachmentTarget: "INVALID_ATTACHMENT_TARGET";
|
|
43
|
+
readonly InvalidFunctionName: "INVALID_FUNCTION_NAME";
|
|
44
|
+
readonly InvalidHttpHeader: "INVALID_HTTP_HEADER";
|
|
45
|
+
readonly InvalidHttpUrl: "INVALID_HTTP_URL";
|
|
46
|
+
readonly LogoutFailed: "LOGOUT_FAILED";
|
|
47
|
+
readonly ProtocolMismatch: "PROTOCOL_MISMATCH";
|
|
48
|
+
readonly RequestTimeout: "REQUEST_TIMEOUT";
|
|
49
|
+
readonly StreamDisconnected: "STREAM_DISCONNECTED";
|
|
50
|
+
readonly StreamHealthTimeout: "STREAM_HEALTH_TIMEOUT";
|
|
51
|
+
readonly StreamInterrupted: "STREAM_INTERRUPTED";
|
|
52
|
+
readonly StreamOpenFailed: "STREAM_OPEN_FAILED";
|
|
53
|
+
readonly StreamSeqGap: "STREAM_SEQ_GAP";
|
|
54
|
+
readonly StreamUnavailable: "STREAM_UNAVAILABLE";
|
|
55
|
+
readonly UnsupportedHttpBody: "UNSUPPORTED_HTTP_BODY";
|
|
56
|
+
readonly UserInfoUnavailable: "USER_INFO_UNAVAILABLE";
|
|
57
|
+
};
|
|
58
|
+
type SiteRuntimeErrorCode = (typeof SiteRuntimeErrorCode)[keyof typeof SiteRuntimeErrorCode];
|
|
59
|
+
interface SiteRuntimeError {
|
|
60
|
+
code: SiteRuntimeErrorCode;
|
|
61
|
+
message: string;
|
|
62
|
+
retryable: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 附件上传的目标坐标:只描述业务位置,不含任何 box / Drive 参数。
|
|
66
|
+
*
|
|
67
|
+
* 挂载点、`mount_node_token`、身份 header 全部由宿主决定,子页面不感知,box 协议变化时
|
|
68
|
+
* 代码无需跟改。
|
|
69
|
+
*
|
|
70
|
+
* 不含 `fieldId`:上传把文件挂在**底表**上,字段只在随后写单元格时才有意义,而那一步由
|
|
71
|
+
* 子页面自己走记录写接口完成。宿主用 `(baseToken, tableId)` 对站点绑定白名单做归属校验。
|
|
72
|
+
*/
|
|
73
|
+
interface SiteAttachmentTarget {
|
|
74
|
+
baseToken: string;
|
|
75
|
+
tableId: string;
|
|
76
|
+
}
|
|
77
|
+
/** `file` 必须是 `File`(宿主的上传 SDK 要求);由 postMessage 结构化克隆传递,宿主收到的是等价副本而非同一引用。 */
|
|
78
|
+
interface SiteAttachmentUploadRequest extends SiteAttachmentTarget {
|
|
79
|
+
file: File;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 子页面侧的调用参数。
|
|
83
|
+
*
|
|
84
|
+
* `onProgress` **不过通道**:函数无法被结构化克隆,直接放进 postMessage 载荷会抛
|
|
85
|
+
* `DataCloneError`。client 会把它摘下来留在本地,改用 `uploadId` 与宿主派发的进度事件对账。
|
|
86
|
+
*/
|
|
87
|
+
interface SiteAttachmentUploadOptions extends SiteAttachmentUploadRequest {
|
|
88
|
+
onProgress?: (progress: SiteAttachmentUploadProgress) => void;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 真正过 postMessage 的载荷。
|
|
92
|
+
*
|
|
93
|
+
* `uploadId` 由 client 生成,用于把宿主派发的进度事件路由回发起这次上传的调用方——同一子页面
|
|
94
|
+
* 可能并发传多个文件,事件是广播的,没有它无法区分。
|
|
95
|
+
* 旧宿主不认识该字段,忽略即可:调用方的 `onProgress` 不会被触发,上传本身不受影响。
|
|
96
|
+
*/
|
|
97
|
+
interface SiteAttachmentUploadPayload extends SiteAttachmentUploadRequest {
|
|
98
|
+
uploadId?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 放弃一次进行中的上传。宿主据 `uploadId` 找到任务并让上传 SDK 真的停活。
|
|
102
|
+
* 找不到即已落地或从未存在,宿主忽略——取消是尽力而为,晚到不该报错。
|
|
103
|
+
*/
|
|
104
|
+
interface SiteAttachmentUploadCancelRequest {
|
|
105
|
+
uploadId: string;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 上传进度。字节数取自宿主上传 SDK 的任务快照,非单调递增无意义值已由宿主过滤。
|
|
109
|
+
*
|
|
110
|
+
* `total` 是宿主看到的文件体积,正常与子页面的 `file.size` 一致;分母以本字段为准,
|
|
111
|
+
* 不要混用两侧的值去算百分比。
|
|
112
|
+
*/
|
|
113
|
+
interface SiteAttachmentUploadProgress {
|
|
114
|
+
loaded: number;
|
|
115
|
+
total: number;
|
|
116
|
+
uploadId: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* 除 `fileToken` 外都是**客户端自报值**:上传 SDK 的成功回调只返回 token 与版本号,不带服务端
|
|
120
|
+
* fileMeta。够用于上传后的即时展示;持久化后的权威值以 SQL 读回的为准(服务端写入时会以
|
|
121
|
+
* fileMeta 补 name / size / mimeType)。
|
|
122
|
+
*
|
|
123
|
+
* `width` / `height` 仅图片可能有,拿不到时省略——调用方不应据此判断是否为图片;
|
|
124
|
+
* 写单元格时要把它们透传给 `image_width` / `image_height`,缺失会渲染成占位方块。
|
|
125
|
+
*/
|
|
126
|
+
interface SiteAttachmentUploadResult {
|
|
127
|
+
fileToken: string;
|
|
128
|
+
height?: number;
|
|
129
|
+
mimeType?: string;
|
|
130
|
+
name: string;
|
|
131
|
+
size: number;
|
|
132
|
+
width?: number;
|
|
133
|
+
}
|
|
134
|
+
type SiteHttpMethod = 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';
|
|
135
|
+
type SiteHttpResponseType = 'text' | 'arrayBuffer';
|
|
136
|
+
interface SiteHttpRequestInit {
|
|
137
|
+
responseType?: SiteHttpResponseType;
|
|
138
|
+
body?: string;
|
|
139
|
+
headers?: Record<string, string>;
|
|
140
|
+
method?: SiteHttpMethod;
|
|
141
|
+
timeoutMs?: number;
|
|
142
|
+
}
|
|
143
|
+
interface SiteHttpRequest {
|
|
144
|
+
requestId?: string;
|
|
145
|
+
init?: SiteHttpRequestInit;
|
|
146
|
+
url: string;
|
|
147
|
+
}
|
|
148
|
+
/** signal 仅在 iframe 使用,不进入消息载荷。 */
|
|
149
|
+
interface SiteHttpRequestOptions extends SiteHttpRequest {
|
|
150
|
+
signal?: AbortSignal;
|
|
151
|
+
}
|
|
152
|
+
interface SiteHttpCancelRequest {
|
|
153
|
+
requestId: string;
|
|
154
|
+
}
|
|
155
|
+
interface SiteHttpResponse {
|
|
156
|
+
body: string | ArrayBuffer;
|
|
157
|
+
bodyType?: SiteHttpResponseType;
|
|
158
|
+
headers: Record<string, string>;
|
|
159
|
+
status: number;
|
|
160
|
+
statusText: string;
|
|
161
|
+
}
|
|
162
|
+
interface SiteFunctionDefinition<Params = unknown, Result = unknown> {
|
|
163
|
+
params: Params;
|
|
164
|
+
result: Result;
|
|
165
|
+
}
|
|
166
|
+
interface SiteFunctionInvokeRequest {
|
|
167
|
+
functionName: string;
|
|
168
|
+
params?: unknown;
|
|
169
|
+
}
|
|
170
|
+
interface SiteChatbotStreamOpenRequest {
|
|
171
|
+
chatbotId: string;
|
|
172
|
+
subscriptionId: string;
|
|
173
|
+
threadId: string;
|
|
174
|
+
}
|
|
175
|
+
interface SiteChatbotStreamCloseRequest {
|
|
176
|
+
subscriptionId: string;
|
|
177
|
+
}
|
|
178
|
+
interface SiteChatbotStreamMessage<T = unknown> {
|
|
179
|
+
data: T;
|
|
180
|
+
seq: number;
|
|
181
|
+
subscriptionId: string;
|
|
182
|
+
}
|
|
183
|
+
interface SiteChatbotStreamError {
|
|
184
|
+
code: string;
|
|
185
|
+
retryable: boolean;
|
|
186
|
+
subscriptionId: string;
|
|
187
|
+
}
|
|
188
|
+
type SiteAIMessageRole = 'assistant' | 'system' | 'user';
|
|
189
|
+
interface SiteAIStreamMessageParam {
|
|
190
|
+
content: string;
|
|
191
|
+
role: SiteAIMessageRole;
|
|
192
|
+
}
|
|
193
|
+
interface SiteAIStreamDelta {
|
|
194
|
+
content?: string;
|
|
195
|
+
raw: unknown;
|
|
196
|
+
reasoningContent?: string;
|
|
197
|
+
requestId?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* text/vision 流式增量的推荐消费形态:把「最终回答」与「思考过程」拆成两个必有的字符串,
|
|
201
|
+
* 业务页面不必再理解 OpenAI 原始字段、双层 SSE 或不同宿主分支的细节。
|
|
202
|
+
*/
|
|
203
|
+
interface SiteAITextDelta {
|
|
204
|
+
/** 最终回答增量,适合进入正式结果区。 */
|
|
205
|
+
answer: string;
|
|
206
|
+
/** 模型思考过程增量,适合放在较小的过程区域。 */
|
|
207
|
+
reasoning: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 从流式增量中读出 { answer, reasoning },降低「只消费 content 导致思考过程一直为空」的误用概率。
|
|
211
|
+
*
|
|
212
|
+
* reasoning 模型会先持续返回 reasoningContent、再返回 content;页面应分别渲染两个区域,
|
|
213
|
+
* 并且只对最终 answer 做结构化解析,不要基于 reasoning 内容解析(建议 5)。
|
|
214
|
+
*/
|
|
215
|
+
declare const readSiteAITextDelta: (delta: SiteAIStreamDelta) => SiteAITextDelta;
|
|
216
|
+
interface SiteAIFunctionError extends Error {
|
|
217
|
+
code: string;
|
|
218
|
+
}
|
|
219
|
+
type SiteAIFunctionVariables = Record<string, unknown>;
|
|
220
|
+
interface SiteAIFunctionStreamOpenRequest {
|
|
221
|
+
env?: SiteProjectEnv;
|
|
222
|
+
functionKey: string;
|
|
223
|
+
messages?: SiteAIStreamMessageParam[];
|
|
224
|
+
requestId?: string;
|
|
225
|
+
siteToken?: string;
|
|
226
|
+
subscriptionId: string;
|
|
227
|
+
variables?: SiteAIFunctionVariables;
|
|
228
|
+
}
|
|
229
|
+
interface SiteAIFunctionStreamCloseRequest {
|
|
230
|
+
subscriptionId: string;
|
|
231
|
+
}
|
|
232
|
+
type SiteAIFunctionStreamMessage = SiteChatbotStreamMessage<SiteAIStreamDelta | string>;
|
|
233
|
+
interface SiteAIFunctionStreamError extends SiteChatbotStreamError {
|
|
234
|
+
message?: string;
|
|
235
|
+
}
|
|
236
|
+
interface SiteAIFunctionStreamDone {
|
|
237
|
+
subscriptionId: string;
|
|
238
|
+
}
|
|
239
|
+
type SiteAITaskStatus = 'cancelled' | 'failed' | 'queued' | 'running' | 'succeeded';
|
|
240
|
+
type SiteAICapabilityType = 'image' | 'text' | 'video' | 'vision';
|
|
241
|
+
interface SiteAIImageAsset {
|
|
242
|
+
safetyStatus: string;
|
|
243
|
+
size?: string;
|
|
244
|
+
token?: string;
|
|
245
|
+
url?: string;
|
|
246
|
+
}
|
|
247
|
+
interface SiteAIVideoAsset {
|
|
248
|
+
durationSeconds?: number;
|
|
249
|
+
token?: string;
|
|
250
|
+
url?: string;
|
|
251
|
+
}
|
|
252
|
+
interface SiteAIMediaTaskBase {
|
|
253
|
+
capabilityType?: 'image' | 'video';
|
|
254
|
+
errCode?: string;
|
|
255
|
+
errMessage?: string;
|
|
256
|
+
progress?: number;
|
|
257
|
+
requestId: string;
|
|
258
|
+
status: SiteAITaskStatus;
|
|
259
|
+
taskId: string;
|
|
260
|
+
}
|
|
261
|
+
interface SiteAIImageTask extends SiteAIMediaTaskBase {
|
|
262
|
+
imageAssets?: SiteAIImageAsset[];
|
|
263
|
+
type: 'image_task';
|
|
264
|
+
}
|
|
265
|
+
interface SiteAIVideoTask extends SiteAIMediaTaskBase {
|
|
266
|
+
type: 'video_task';
|
|
267
|
+
videoAsset?: SiteAIVideoAsset;
|
|
268
|
+
}
|
|
269
|
+
type SiteAIMediaTask = SiteAIImageTask | SiteAIVideoTask;
|
|
270
|
+
type SiteAIFunctionResult = {
|
|
271
|
+
content: string;
|
|
272
|
+
requestId: string;
|
|
273
|
+
type: 'text';
|
|
274
|
+
} | {
|
|
275
|
+
assets: SiteAIImageAsset[];
|
|
276
|
+
requestId: string;
|
|
277
|
+
type: 'image';
|
|
278
|
+
} | SiteAIImageTask | SiteAIVideoTask;
|
|
279
|
+
interface SiteRuntimeReadyEvent {
|
|
280
|
+
protocolVersion: typeof SITE_RUNTIME_PROTOCOL_VERSION;
|
|
281
|
+
}
|
|
282
|
+
interface SiteRuntimeLoadFailedEvent {
|
|
283
|
+
code?: string;
|
|
284
|
+
}
|
|
285
|
+
interface SiteRuntimeModeChangedEvent {
|
|
286
|
+
mode: 'editing' | 'reading';
|
|
287
|
+
}
|
|
288
|
+
type SiteProjectEnv = 'preview' | 'prod';
|
|
289
|
+
interface SiteRuntimeContext {
|
|
290
|
+
colorScheme: string;
|
|
291
|
+
/**
|
|
292
|
+
* 当前挂载的产物环境。宿主按 mode 在线上 / 预览产物链接间选择时即已确定,
|
|
293
|
+
* 由宿主下发,子页面不必从产物路径反推。
|
|
294
|
+
* 旧版本宿主不下发该字段,子页面需保留自身的兜底推断。
|
|
295
|
+
*/
|
|
296
|
+
env?: SiteProjectEnv;
|
|
297
|
+
locale: string;
|
|
298
|
+
mode: 'editing' | 'reading';
|
|
299
|
+
protocolVersion: typeof SITE_RUNTIME_PROTOCOL_VERSION;
|
|
300
|
+
/**
|
|
301
|
+
* 当前站点 token(BaseApp 形态下即 app_token)。理由同 env:宿主已知,
|
|
302
|
+
* 下发后子页面不再依赖 CDN 产物路径约定。旧版本宿主不下发该字段。
|
|
303
|
+
*/
|
|
304
|
+
siteToken?: string;
|
|
305
|
+
}
|
|
306
|
+
interface SiteRuntimeUserInfo {
|
|
307
|
+
[key: string]: unknown;
|
|
308
|
+
avatarUrl: string;
|
|
309
|
+
name: string;
|
|
310
|
+
}
|
|
311
|
+
declare const isValidSiteFunctionName: (functionName: string) => boolean;
|
|
312
|
+
|
|
313
|
+
export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAICapabilityType, SiteAIFunctionError, SiteAIFunctionResult, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIFunctionVariables, SiteAIImageAsset, SiteAIImageTask, SiteAIMediaTask, SiteAIMediaTaskBase, SiteAIMessageRole, SiteAIStreamDelta, SiteAIStreamMessageParam, SiteAITaskStatus, SiteAITextDelta, SiteAIVideoAsset, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadOptions, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteAttachmentUploadResult, SiteChatbotStreamCloseRequest, SiteChatbotStreamError, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionDefinition, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpRequestOptions, SiteHttpResponse, SiteHttpResponseType, SiteProjectEnv, SiteRuntimeApi, SiteRuntimeContext, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeModeChangedEvent, SiteRuntimeReadyEvent, SiteRuntimeUserInfo, isValidSiteFunctionName, readSiteAITextDelta };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var r="site.v1",s={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},a={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},o={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},c={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},p=e=>{var t,n;return{answer:(t=e.content)!=null?t:"",reasoning:(n=e.reasoningContent)!=null?n:""}},i=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,S=e=>i.test(e);export{r as SITE_RUNTIME_PROTOCOL_VERSION,s as SiteRuntimeApi,c as SiteRuntimeErrorCode,a as SiteRuntimeEvent,o as SiteRuntimeFunction,S as isValidSiteFunctionName,p as readSiteAITextDelta};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { SiteAttachmentUploadOptions, SiteAttachmentUploadResult, SiteHttpRequestOptions, SiteRuntimeContext, SiteRuntimeUserInfo, SiteRuntimeModeChangedEvent, SiteFunctionDefinition, SiteProjectEnv, SiteAIStreamMessageParam, SiteAIFunctionVariables, SiteAIFunctionError, SiteAIStreamDelta, SiteAIMediaTask, SiteAIFunctionResult } from './runtime-contract.js';
|
|
2
|
+
export { SITE_RUNTIME_PROTOCOL_VERSION, SiteAICapabilityType, SiteAIFunctionStreamCloseRequest, SiteAIFunctionStreamDone, SiteAIFunctionStreamError, SiteAIFunctionStreamMessage, SiteAIFunctionStreamOpenRequest, SiteAIImageAsset, SiteAIImageTask, SiteAIMediaTaskBase, SiteAIMessageRole, SiteAITaskStatus, SiteAITextDelta, SiteAIVideoAsset, SiteAIVideoTask, SiteAttachmentTarget, SiteAttachmentUploadCancelRequest, SiteAttachmentUploadPayload, SiteAttachmentUploadProgress, SiteAttachmentUploadRequest, SiteChatbotStreamCloseRequest, SiteChatbotStreamMessage, SiteChatbotStreamOpenRequest, SiteFunctionInvokeRequest, SiteHttpCancelRequest, SiteHttpMethod, SiteHttpRequest, SiteHttpRequestInit, SiteHttpResponse, SiteHttpResponseType, SiteRuntimeApi, SiteRuntimeError, SiteRuntimeErrorCode, SiteRuntimeEvent, SiteRuntimeFunction, SiteRuntimeLoadFailedEvent, SiteRuntimeReadyEvent, isValidSiteFunctionName, readSiteAITextDelta } from './runtime-contract.js';
|
|
3
|
+
|
|
4
|
+
interface RuntimeChannel {
|
|
5
|
+
emitEvent: <T>(key: string, params: T) => Promise<void>;
|
|
6
|
+
invokeApi: <T, P>(key: string, params: T, options?: {
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
}) => Promise<P>;
|
|
9
|
+
subscribeEvent: <T>(key: string, handler: (params: T) => void | Promise<void>) => () => void;
|
|
10
|
+
}
|
|
11
|
+
interface FunctionMap {
|
|
12
|
+
}
|
|
13
|
+
type FunctionName<Map> = Extract<keyof Map, string>;
|
|
14
|
+
type FunctionParams<Map, Name extends FunctionName<Map>> = Map[Name] extends SiteFunctionDefinition<infer Params, unknown> ? Params : never;
|
|
15
|
+
type FunctionResult<Map, Name extends FunctionName<Map>> = Map[Name] extends SiteFunctionDefinition<unknown, infer Result> ? Result : never;
|
|
16
|
+
declare class SiteRuntimeInvocationError extends Error {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
constructor(code: string, message: string);
|
|
19
|
+
}
|
|
20
|
+
declare class SiteRuntimeClient<Map = FunctionMap> {
|
|
21
|
+
private readonly channel;
|
|
22
|
+
constructor(channel: RuntimeChannel);
|
|
23
|
+
uploadAttachment: ({ onProgress, ...request }: SiteAttachmentUploadOptions) => Promise<SiteAttachmentUploadResult>;
|
|
24
|
+
invokeHttp: (request: SiteHttpRequestOptions) => Promise<Response>;
|
|
25
|
+
invokeApi: <Name extends FunctionName<Map>>(functionName: Name, params: FunctionParams<Map, Name>) => Promise<FunctionResult<Map, Name>>;
|
|
26
|
+
getRuntimeContext: () => Promise<SiteRuntimeContext>;
|
|
27
|
+
getCurrentUser: () => Promise<SiteRuntimeUserInfo>;
|
|
28
|
+
logout: () => Promise<void>;
|
|
29
|
+
requestEdit: () => Promise<void>;
|
|
30
|
+
ready: () => Promise<void>;
|
|
31
|
+
reportLoadFailed: (code?: string) => Promise<void>;
|
|
32
|
+
subscribeModeChanged: (handler: (mode: SiteRuntimeModeChangedEvent["mode"]) => void) => () => void;
|
|
33
|
+
}
|
|
34
|
+
declare const createSiteRuntimeClient: <Map = FunctionMap>(channel?: RuntimeChannel) => SiteRuntimeClient<Map>;
|
|
35
|
+
declare const siteRuntime: SiteRuntimeClient<FunctionMap>;
|
|
36
|
+
declare const invokeHttp: (request: SiteHttpRequestOptions) => Promise<Response>;
|
|
37
|
+
declare const invokeApi: <Name extends never>(functionName: Name, params: FunctionParams<FunctionMap, Name>) => Promise<FunctionResult<FunctionMap, Name>>;
|
|
38
|
+
declare const getCurrentUser: () => Promise<SiteRuntimeUserInfo>;
|
|
39
|
+
declare const logout: () => Promise<void>;
|
|
40
|
+
declare const requestEdit: () => Promise<void>;
|
|
41
|
+
declare const uploadAttachment: ({ onProgress, ...request }: SiteAttachmentUploadOptions) => Promise<SiteAttachmentUploadResult>;
|
|
42
|
+
|
|
43
|
+
type RuntimeHttpClient = Pick<SiteRuntimeClient, 'invokeHttp'>;
|
|
44
|
+
declare const createSiteRuntimeFetch: (runtime?: RuntimeHttpClient, timeoutMs?: number) => typeof globalThis.fetch;
|
|
45
|
+
declare const fetch: typeof globalThis.fetch;
|
|
46
|
+
|
|
47
|
+
declare class SiteChatbotStreamError extends Error {
|
|
48
|
+
readonly code: string;
|
|
49
|
+
readonly retryable: boolean;
|
|
50
|
+
constructor(code: string, retryable: boolean);
|
|
51
|
+
}
|
|
52
|
+
declare class SiteChatbotStreamAdapter<Message = unknown> {
|
|
53
|
+
private readonly options;
|
|
54
|
+
private current?;
|
|
55
|
+
private onErrorCallback?;
|
|
56
|
+
private onMessageCallback?;
|
|
57
|
+
private readonly channel;
|
|
58
|
+
constructor(options: {
|
|
59
|
+
chatbotId: string;
|
|
60
|
+
channel?: RuntimeChannel;
|
|
61
|
+
});
|
|
62
|
+
init: (threadId: string) => void;
|
|
63
|
+
onMessage: (callback: (message: Message) => void) => void;
|
|
64
|
+
onError: (callback: (error: Error) => void) => void;
|
|
65
|
+
destroy: () => void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface SiteAIImageGenerationInput {
|
|
69
|
+
image?: string | string[];
|
|
70
|
+
prompt?: string;
|
|
71
|
+
size?: string;
|
|
72
|
+
}
|
|
73
|
+
interface SiteAIVideoGenerationInput {
|
|
74
|
+
duration?: number;
|
|
75
|
+
image_url?: string;
|
|
76
|
+
prompt?: string;
|
|
77
|
+
}
|
|
78
|
+
interface CallSiteAIFunctionBaseParams {
|
|
79
|
+
functionKey: string;
|
|
80
|
+
messages?: SiteAIStreamMessageParam[];
|
|
81
|
+
variables?: SiteAIFunctionVariables;
|
|
82
|
+
}
|
|
83
|
+
type CallSiteAIFunctionParams = CallSiteAIFunctionBaseParams & ({
|
|
84
|
+
capability: 'image';
|
|
85
|
+
input?: SiteAIImageGenerationInput;
|
|
86
|
+
} | {
|
|
87
|
+
capability: 'video';
|
|
88
|
+
input?: SiteAIVideoGenerationInput;
|
|
89
|
+
} | {
|
|
90
|
+
capability?: 'text' | 'vision';
|
|
91
|
+
input?: Record<string, unknown>;
|
|
92
|
+
});
|
|
93
|
+
interface SiteAIFunctionOptions {
|
|
94
|
+
channel?: RuntimeChannel;
|
|
95
|
+
env?: SiteProjectEnv;
|
|
96
|
+
requestId?: string;
|
|
97
|
+
siteToken?: string;
|
|
98
|
+
}
|
|
99
|
+
interface InvokeSiteAIFunctionStreamParams {
|
|
100
|
+
functionKey: string;
|
|
101
|
+
messages: SiteAIStreamMessageParam[];
|
|
102
|
+
variables?: SiteAIFunctionVariables;
|
|
103
|
+
}
|
|
104
|
+
interface SiteAIFunctionStreamHandle {
|
|
105
|
+
destroy(): void;
|
|
106
|
+
onDone(cb: () => void): void;
|
|
107
|
+
onError(cb: (err: SiteAIFunctionError) => void): void;
|
|
108
|
+
onMessage(cb: (delta: SiteAIStreamDelta) => void): void;
|
|
109
|
+
}
|
|
110
|
+
declare const invokeSiteAIFunctionStream: (params: InvokeSiteAIFunctionStreamParams, options?: SiteAIFunctionOptions) => SiteAIFunctionStreamHandle;
|
|
111
|
+
declare const createSiteAIFunctionTask: (params: CallSiteAIFunctionParams, options?: SiteAIFunctionOptions) => Promise<SiteAIMediaTask>;
|
|
112
|
+
declare const getSiteAIFunctionTask: (functionKey: string, taskId: string, options?: SiteAIFunctionOptions) => Promise<SiteAIMediaTask>;
|
|
113
|
+
declare const callSiteAIFunction: (params: CallSiteAIFunctionParams, options?: SiteAIFunctionOptions) => Promise<SiteAIFunctionResult>;
|
|
114
|
+
|
|
115
|
+
export { CallSiteAIFunctionParams, FunctionMap, InvokeSiteAIFunctionStreamParams, RuntimeChannel, SiteAIFunctionError, SiteAIFunctionOptions, SiteAIFunctionResult, SiteAIFunctionStreamHandle, SiteAIFunctionVariables, SiteAIImageGenerationInput, SiteAIMediaTask, SiteAIStreamDelta, SiteAIStreamMessageParam, SiteAIVideoGenerationInput, SiteAttachmentUploadOptions, SiteAttachmentUploadResult, SiteChatbotStreamAdapter, SiteChatbotStreamError, SiteFunctionDefinition, SiteHttpRequestOptions, SiteProjectEnv, SiteRuntimeClient, SiteRuntimeContext, SiteRuntimeInvocationError, SiteRuntimeModeChangedEvent, SiteRuntimeUserInfo, callSiteAIFunction, createSiteAIFunctionTask, createSiteRuntimeClient, createSiteRuntimeFetch, fetch, getCurrentUser, getSiteAIFunctionTask, invokeApi, invokeHttp, invokeSiteAIFunctionStream, logout, requestEdit, siteRuntime, uploadAttachment };
|
package/dist/runtime.mjs
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var ct=Object.defineProperty,dt=Object.defineProperties;var ut=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var ve=Object.prototype.hasOwnProperty,be=Object.prototype.propertyIsEnumerable;var Ae=(t,e,n)=>e in t?ct(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,a=(t,e)=>{for(var n in e||(e={}))ve.call(e,n)&&Ae(t,n,e[n]);if(N)for(var n of N(e))be.call(e,n)&&Ae(t,n,e[n]);return t},f=(t,e)=>dt(t,ut(e));var Te=(t,e)=>{var n={};for(var r in t)ve.call(t,r)&&e.indexOf(r)<0&&(n[r]=t[r]);if(t!=null&&N)for(var r of N(t))e.indexOf(r)<0&&be.call(t,r)&&(n[r]=t[r]);return n};var p=(t,e,n)=>new Promise((r,i)=>{var o=c=>{try{d(n.next(c))}catch(m){i(m)}},s=c=>{try{d(n.throw(c))}catch(m){i(m)}},d=c=>c.done?r(c.value):Promise.resolve(c.value).then(o,s);d((n=n.apply(t,e)).next())});import{uniqueId as ee}from"lodash-es";var W="same-origin",Ce="__internal_fetchBinaryList__",Re="__internal_cancelBinaryFetch__",ke="__internal_binaryFetchProgress__";function $(t){return Number.isFinite(t)?Math.max(1,Math.floor(t)):4}function Y(t){return t==="omit"||t==="include"?t:W}var L=(i=>(i.IFRAME_LOAD_ERROR="iframeLoadError",i.NOT_ALLOWED_URL="notAllowedUrl",i.HANDSHAKE_TIME_OUT="handshakeTimeout",i.CHANNEL_UNAVAILABLE="channelUnavailable",i))(L||{});var b=class extends Error{constructor(n,r){super(r);this.code=n,this.name="ChannelCallbackError"}};function Me(t){return new b(10004,`api "${t}" is not registered`)}function Fe(t){return new b(10005,`api "${t}" timed out`)}function G(){return new b(10006,"channel has been destroyed")}function Pe(t){return new b(10008,`request "${t}" was superseded by a new one`)}var lt="unknown error";function we(t){return typeof t=="object"&&t!==null}function pt(t){if(typeof t=="string"&&t)return t;if(t instanceof b&&t.message||t instanceof Error&&t.message)return t.message;if(we(t)){let{msg:e,message:n}=t;if(typeof e=="string"&&e)return e;if(typeof n=="string"&&n)return n}return lt}function ht(t){if(t instanceof b)return t.code;if(!we(t))return-1;let{code:e}=t;return typeof e=="string"&&e||typeof e=="number"&&Number.isFinite(e)?e:-1}function A(t){return{code:ht(t),msg:pt(t)}}function _e(t){return t instanceof ArrayBuffer||ArrayBuffer.isView(t)||typeof Blob!="undefined"&&t instanceof Blob}function mt(t){return _e(t)||Object.values(t).some(e=>_e(e))}function He(t){return t&&typeof t=="object"?mt(t)?t:JSON.parse(JSON.stringify(t)):t}var ft={["iframeLoadError"]:10001,["notAllowedUrl"]:10002,["handshakeTimeout"]:10003,["channelUnavailable"]:10009};function gt(t){return typeof t=="object"&&t!==null}function St(t){if(!gt(t))return!1;let{type:e}=t;return typeof e=="string"&&Object.values(L).includes(e)}function J(t){return St(t)?{code:ft[t.type],msg:t.message||t.type}:A(t)}function X(t){let e=Promise.reject(t);return e.catch(()=>{}),e}var P=class{constructor(e,n){this._target=e,this._options=n}sendMsg(e,n){if(!this._target)throw new Error("target window is not found");this._target.postMessage(e,this._options.targetOrigin,n!=null?n:[])}listenMsg(e){this._eventHandler=n=>{n.source===this._options.sourceWindow&&this._options.allowedOrigins.includes(n.origin)&&e(n)},typeof window!="undefined"&&window.addEventListener("message",this._eventHandler)}destroy(){typeof window!="undefined"&&this._eventHandler&&window.removeEventListener("message",this._eventHandler),this._eventHandler=void 0}};var x=class{constructor(e,n,r){e==="host"?this.channelManager=new P(n,r):e==="client"&&(this.channelManager=new P(window.parent,r))}static createInstance(e,n,r){return new x(e,n,r)}sendMsg(e,n){var r;(r=this.channelManager)==null||r.sendMsg(e,n)}listenMsg(e){var n;(n=this.channelManager)==null||n.listenMsg(e)}destroy(){var e;(e=this.channelManager)==null||e.destroy()}};var O=class{constructor(){this.requests=new Map}create(e,n,r=3e4){return this.reject(e,A(Pe(e))),new Promise((i,o)=>{let s=setTimeout(()=>{var d;((d=this.requests.get(e))==null?void 0:d.timeout)===s&&(this.requests.delete(e),o(A(Fe(n))))},r);this.requests.set(e,{reject:o,resolve:i,timeout:s})})}resolve(e,n){let r=this.take(e);return r?(r.resolve(n),!0):!1}reject(e,n){let r=this.take(e);return r?(r.reject(n),!0):!1}rejectAll(e){for(let n of this.requests.keys())this.reject(n,e)}take(e){let n=this.requests.get(e);if(n)return this.requests.delete(e),clearTimeout(n.timeout),n}};var Q=t=>typeof t=="object"&&t!==null,Et=new Set(["blockId","expectedPrefixId","id","jobId","prefixId","url"]),C=t=>{let e={};for(let[n,r]of Object.entries(t))if(!(n==="inputParams"||n==="outputParams")){if(Et.has(n)){e[`${n}Present`]=!!r;continue}if(n==="error"){Object.assign(e,R(r));continue}if(n==="errorInfo"&&Q(r)){e.errorType=typeof r.type=="string"?r.type:"object";continue}(typeof r=="string"||typeof r=="number"||typeof r=="boolean")&&(e[n]=r)}return e},M=t=>{let e={idPresent:!!t.id,type:t.type},n=Q(t.payload)?t.payload:{};return typeof n.key=="string"&&(e.key=n.key),t.type==="callback"&&typeof n.code=="number"&&(e.callbackCode=n.code),t.type==="handshake"&&typeof n.proactive=="boolean"&&(e.proactive=n.proactive),e},Z=t=>t.type!=="invoke"&&t.type!=="callback",R=t=>{if(!Q(t))return{errorType:typeof t};let e={errorType:t instanceof Error?t.name:"object"};return(typeof t.code=="number"||typeof t.code=="string")&&(e.errorCode=t.code),e};var At=()=>{let t=Reflect.get(globalThis,"BearWebSlardarWeb");return typeof t=="function"?t:void 0},vt=t=>{let e={};for(let[n,r]of Object.entries(C(t)))typeof r=="string"||typeof r=="number"?e[n]=r:typeof r=="boolean"&&(e[n]=String(r));return e},Ne=(t,e,n,r)=>{console[e](`[base-site-channel][${t}]`,n,r)},U=(t,e,n,r={})=>{let i=C(r),o=At();if(!o){Ne(t,e,n,i);return}try{o("sendLog",{content:`[base-site-channel][${t}] ${n}`,extra:a({event_name:"Runtime_SiteChannel_Message",bizType:"Runtime",subType:"SiteChannel",action:"Message",channel_side:t,channel_message:n},vt(i)),level:e})}catch(s){Ne(t,e,n,f(a({},i),{slardarFallback:!0,slardarErrorType:s instanceof Error?s.name:typeof s}))}};var Ct=()=>{var n;if(typeof window=="undefined")return null;let e=((n=window.location.ancestorOrigins)==null?void 0:n[0])||document.referrer;if(!e)return null;try{return new URL(e).origin}catch(r){return null}},Rt=t=>{try{return new URL(t).origin}catch(e){return null}},te=class{constructor(e={}){this.pendingRequests=new O;this.eventMap=new Map;this.eventHandlerMap=new Map;this._msgChannel=null;this._invokeId="";this._handshakePromise=X({type:"channelUnavailable",message:"channel handshake is not initialized"});this._handshakeResolve=null;this._handshakeReject=null;this._handshakeRetryTimes=0;this._handshakeStatus=0;this._handshakeTimeout=null;this._prefixId="";this._destroyed=!1;let n=e.hostOrigin?Rt(e.hostOrigin):null;if(this.hostOrigin=n!=null?n:Ct(),e.hostOrigin&&!n&&this.logWarn("invalid hostOrigin, fallback to parent origin"),typeof window=="undefined"||window.parent===window){this.failHandshake("invalid window context",{hasWindow:typeof window!="undefined",isTopWindow:typeof window!="undefined"?window.parent===window:!0});return}if(!this.hostOrigin){this.failHandshake("host origin unavailable");return}this._msgChannel=x.createInstance("client",window.parent,{allowedOrigins:[this.hostOrigin],sourceWindow:window.parent,targetOrigin:this.hostOrigin}),this.listeningHostMsg(),this.startHandshake()}logInfo(e,n={}){U("client","info",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logWarn(e,n={}){U("client","warn",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}logError(e,n={}){U("client","error",e,a({hasPrefixId:!!this._prefixId,handshakeStatus:this._handshakeStatus},C(n)))}failHandshake(e,n={}){this._handshakeStatus=2,this._handshakePromise=X({type:"channelUnavailable",message:e}),this.logError(`init failed: ${e}`,n)}sendProactiveHandshakeMsg(){var n;let e={id:ee("handshake-"),type:"handshake",payload:{proactive:!0}};this.logInfo("send proactive handshake",M(e)),(n=this._msgChannel)==null||n.sendMsg(e)}_initHandshake(){this._handshakeRetryTimes=0,clearTimeout(this._handshakeTimeout),this._handshakeStatus=0,this.logInfo("init handshake"),this._handshakePromise=new Promise((e,n)=>{this._handshakeResolve=e,this._handshakeReject=n,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(n),2e3)})}startHandshake(){this._initHandshake(),this._handshakePromise.then(()=>{this._handshakeStatus=1,this.logInfo("handshake success")}).catch(e=>{this._handshakeStatus=2,this.logError("handshake failed",{error:e})}),this.sendProactiveHandshakeMsg()}retryHandshake(e){this._handshakeStatus===0&&(this._handshakeRetryTimes<5?(this.logWarn("retry handshake",{retryTimes:this._handshakeRetryTimes+1}),this.sendProactiveHandshakeMsg(),this._handshakeRetryTimes++,this._handshakeTimeout=setTimeout(()=>this.retryHandshake(e),2e3+2**this._handshakeRetryTimes)):(this.logError("handshake retry timeout",{retryTimes:this._handshakeRetryTimes}),e({type:"handshakeTimeout",message:"iframe handshake time out"})))}updateInvokeId(){this._invokeId=ee(`${this._prefixId}-invoke-`)}handleChannelMessage(e){let{data:n}=e;Z(n)&&this.logInfo("receive host message",M(n));let{type:r}=n;r==="callback"?this.handleHostCallback(n):r==="handshake"?this.handleHandshakeCallback(n):r==="invoke"?this.handleHostInvoke(n).catch(i=>{this.logError("handle host invoke error",a(a({},M(n)),R(i)))}):r==="event"&&this.handleHostEvent(n).catch(i=>{this.logError("handle host event error",a(a({},M(n)),R(i)))})}handleHostCallback(e){let{id:n,payload:r}=e,i={logId:n,key:r.key,callbackCode:r.code};if(r.code===1){if(this.pendingRequests.reject(n,r.res)){this.logWarn("api response received",i);return}}else if(this.pendingRequests.resolve(n,r.res)){this.logInfo("api response received",i);return}this.logWarn("host callback request not found",{id:n,key:r.key})}handleHostInvoke(e){return p(this,null,function*(){yield this._handshakePromise;let{id:n,payload:r}=e,{key:i,params:o,prefixId:s}=r;if(s!==this._prefixId){this.logWarn("ignore host invoke because prefixId mismatch",{id:n,key:i,prefixId:s,expectedPrefixId:this._prefixId});return}let d=this.eventMap.get(i);if(typeof d!="function"){this.logWarn("host invoke handler not found",{id:n,key:i}),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(Me(i)),code:1}});return}this.logInfo("handle host invoke",{id:n,key:i});try{let c=He(yield d(o));this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:c,code:0}}),this.logInfo("host invoke success",{id:n,key:i})}catch(c){this.logError("host invoke failed",a({id:n,key:i},R(c))),this.sendMsg2Host({id:n,type:"callback",payload:{key:i,res:A(c),code:1}})}})}handleHostEvent(e){return p(this,null,function*(){yield this._handshakePromise;let{payload:n}=e,{key:r,params:i,prefixId:o}=n;if(o!==this._prefixId){this.logWarn("ignore host event because prefixId mismatch",{key:r,prefixId:o,expectedPrefixId:this._prefixId});return}let s=this.eventHandlerMap.get(r);if(!(s!=null&&s.size)){this.logWarn("host event handler not found",{key:r});return}this.logInfo("handle host event",{key:r,handlerCount:s.size}),yield Promise.allSettled(Array.from(s,d=>d(i)))})}handleHandshakeCallback(e){var o,s;let{id:n,payload:r}=e;this._prefixId=(o=r==null?void 0:r.prefixId)!=null?o:"",this.logInfo("receive handshake callback",{id:n,prefixId:this._prefixId}),(s=this._handshakeResolve)==null||s.call(this);let i={id:n,type:"handshake",payload:{proactive:!1,info:{isHandshakeSuccess:!0}}};this.sendMsg2Host(i)}listeningHostMsg(){var e;this.logInfo("start listening host messages"),(e=this._msgChannel)==null||e.listenMsg(this.handleChannelMessage.bind(this))}sendMsg2Host(e,n){var r;Z(e)&&this.logInfo("send message to host",M(e)),(r=this._msgChannel)==null||r.sendMsg(e,n)}invokeApi(e,n,r){return p(this,null,function*(){if(this._destroyed)return Promise.reject(A(G()));try{yield this._handshakePromise}catch(s){return this.logError("invoke api blocked by handshake error",a({key:e},R(s))),Promise.reject(J(s))}this._invokeId||this.updateInvokeId();let i=this._invokeId,o=this.pendingRequests.create(i,e,r==null?void 0:r.timeoutMs);return this.logInfo("api request sent",{key:e,logId:i}),this.sendMsg2Host({type:"invoke",id:i,payload:{key:e,params:n,prefixId:this._prefixId}}),this.updateInvokeId(),o})}registerApi(e,n){if(this.eventMap.has(e)){this.logWarn("register api ignored because key already exists",{key:e});return}this.eventMap.set(e,n),this.logInfo("register api",{key:e})}emitEvent(e,n){return p(this,null,function*(){try{yield this._handshakePromise}catch(r){return this.logError("emit event blocked by handshake error",a({key:e},R(r))),Promise.reject(J(r))}this.logInfo("emit event",{key:e}),this.sendMsg2Host({type:"event",id:ee(`${this._prefixId}-event-`),payload:{key:e,params:n,prefixId:this._prefixId}})})}fetchBinaryList(e){return p(this,null,function*(){var n;return this.logInfo("invoke built-in binary fetch",{status:"start",itemCount:e.items.length,concurrency:$(e.concurrency),credentials:Y(e.credentials)}),this.invokeApi(Ce,{items:e.items,concurrency:$(e.concurrency),credentials:Y((n=e.credentials)!=null?n:W)})})}subscribeBinaryFetchProgress(e){return this.subscribeEvent(ke,e)}cancelBinaryFetch(e){return p(this,null,function*(){this.logInfo("invoke built-in binary fetch cancel",{jobId:e,status:"cancel-requested"}),yield this.invokeApi(Re,{jobId:e})})}destroy(){var n,r;if(this._destroyed)return;this._destroyed=!0,this.logInfo("destroy client"),(n=this._msgChannel)==null||n.destroy(),clearTimeout(this._handshakeTimeout);let e=A(G());(r=this._handshakeReject)==null||r.call(this,{type:"handshakeTimeout",message:e.msg}),this.pendingRequests.rejectAll(e),this.eventMap.clear(),this.eventHandlerMap.clear()}subscribeEvent(e,n){var i;let r=(i=this.eventHandlerMap.get(e))!=null?i:new Set;return r.add(n),this.eventHandlerMap.set(e,r),this.logInfo("subscribe event",{key:e,handlerCount:r.size}),()=>this.unsubscribeEvent(e,n)}unsubscribeEvent(e,n){let r=this.eventHandlerMap.get(e);if(!r){this.logWarn("unsubscribe event ignored because key is not subscribed",{key:e});return}if(!n){this.eventHandlerMap.delete(e),this.logInfo("unsubscribe all event handlers",{key:e,handlerCount:0});return}r.delete(n),r.size===0&&this.eventHandlerMap.delete(e),this.logInfo("unsubscribe event",{key:e,handlerCount:r.size})}},kt=t=>new te(t),k=kt();var Oe="site.v1",g={AIFunctionStreamClose:"site.v1.ai.function.stream.close",AIFunctionStreamOpen:"site.v1.ai.function.stream.open",AttachmentUpload:"site.v1.attachment.upload",AttachmentUploadCancel:"site.v1.attachment.upload.cancel",FunctionInvoke:"site.v1.function.invoke",HttpRequest:"site.v1.http.request",HttpRequestCancel:"site.v1.http.request.cancel",RuntimeContext:"site.v1.runtime.context",StreamClose:"site.v1.chatbot.stream.close",StreamOpen:"site.v1.chatbot.stream.open"},y={AIFunctionStreamDone:"site.v1.ai.function.stream.done",AIFunctionStreamError:"site.v1.ai.function.stream.error",AIFunctionStreamMessage:"site.v1.ai.function.stream.message",AttachmentUploadProgress:"site.v1.attachment.upload.progress",LifecycleLoadFailed:"site.v1.lifecycle.load-failed",LifecycleReady:"site.v1.lifecycle.ready",ModeChanged:"site.v1.runtime.mode-changed",StreamError:"site.v1.chatbot.stream.error",StreamMessage:"site.v1.chatbot.stream.message"},D={GetCurrentUser:"function.runtime.getCurrentUser",Logout:"function.runtime.logout",RequestEdit:"function.runtime.requestEdit"},u={AttachmentUnavailable:"ATTACHMENT_UNAVAILABLE",AttachmentUploadCanceled:"ATTACHMENT_UPLOAD_CANCELED",AttachmentUploadFailed:"ATTACHMENT_UPLOAD_FAILED",AttachmentUploadStalled:"ATTACHMENT_UPLOAD_STALLED",ChannelDestroyed:"CHANNEL_DESTROYED",FunctionNotAllowed:"FUNCTION_NOT_ALLOWED",FunctionRequestFailed:"FUNCTION_REQUEST_FAILED",InvalidAIFunctionTask:"INVALID_AI_FUNCTION_TASK",HttpRequestFailed:"HTTP_REQUEST_FAILED",HttpResponseTypeUnsupported:"HTTP_RESPONSE_TYPE_UNSUPPORTED",HttpRequestCanceled:"HTTP_REQUEST_CANCELED",InvalidAttachmentTarget:"INVALID_ATTACHMENT_TARGET",InvalidFunctionName:"INVALID_FUNCTION_NAME",InvalidHttpHeader:"INVALID_HTTP_HEADER",InvalidHttpUrl:"INVALID_HTTP_URL",LogoutFailed:"LOGOUT_FAILED",ProtocolMismatch:"PROTOCOL_MISMATCH",RequestTimeout:"REQUEST_TIMEOUT",StreamDisconnected:"STREAM_DISCONNECTED",StreamHealthTimeout:"STREAM_HEALTH_TIMEOUT",StreamInterrupted:"STREAM_INTERRUPTED",StreamOpenFailed:"STREAM_OPEN_FAILED",StreamSeqGap:"STREAM_SEQ_GAP",StreamUnavailable:"STREAM_UNAVAILABLE",UnsupportedHttpBody:"UNSUPPORTED_HTTP_BODY",UserInfoUnavailable:"USER_INFO_UNAVAILABLE"},_r=t=>{var e,n;return{answer:(e=t.content)!=null?e:"",reasoning:(n=t.reasoningContent)!=null?n:""}},_t=/^function(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/,Ue=t=>_t.test(t);var xt=0,De=(i,o)=>p(void 0,[i,o],function*(t,{init:e,url:n,signal:r}){if((e==null?void 0:e.responseType)!==void 0&&!["text","arrayBuffer"].includes(e.responseType))throw new I(u.HttpResponseTypeUnsupported,"\u4E0D\u652F\u6301\u7684 HTTP \u54CD\u5E94\u7C7B\u578B");let s=()=>new DOMException("The operation was aborted","AbortError");if(r!=null&&r.aborted)throw s();let d=typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`http-${Date.now()}-${++xt}`,c=()=>{},m=new Promise((h,_)=>{c=()=>{_(s()),t.invokeApi(g.HttpRequestCancel,{requestId:d}).catch(()=>{})}});r==null||r.addEventListener("abort",c,{once:!0});try{let h=yield Promise.race([t.invokeApi(g.HttpRequest,{requestId:d,url:n,init:e},{timeoutMs:(e==null?void 0:e.timeoutMs)===void 0?void 0:Math.min(e.timeoutMs,6e4)+1e3}),m]);if((e==null?void 0:e.responseType)==="arrayBuffer"&&(h.bodyType!=="arrayBuffer"||!(h.body instanceof ArrayBuffer)))throw new I(u.HttpResponseTypeUnsupported,"\u5F53\u524D\u5BBF\u4E3B\u4E0D\u652F\u6301 HTTP \u4E8C\u8FDB\u5236\u54CD\u5E94\uFF0C\u8BF7\u5347\u7EA7\u5BBF\u4E3B");return new Response([204,205,304].includes(h.status)?null:h.body,{headers:h.headers,status:h.status,statusText:h.statusText})}finally{r==null||r.removeEventListener("abort",c)}});var I=class extends Error{constructor(n,r){super(r);this.code=n;this.name="SiteRuntimeInvocationError"}},Be=t=>typeof t=="string"&&t.trim().length>0,Mt=t=>typeof File!="undefined"&&t instanceof File,qe=12e4,Ft=2*60*60*1e3,je=0,Pt=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(je+=1,`site-upload-${je}`),wt=t=>typeof t=="object"&&t!==null&&"code"in t?t.code:void 0,Ht=t=>{if(t instanceof Error&&t.message)return t.message;if(typeof t=="object"&&t!==null){if("message"in t&&typeof t.message=="string")return t.message;if("msg"in t&&typeof t.msg=="string")return t.msg}return String(t)},Nt=new Set([u.AttachmentUnavailable,u.AttachmentUploadCanceled,u.AttachmentUploadFailed,u.AttachmentUploadStalled,u.InvalidAttachmentTarget]),Lt=(t,e)=>{if(t instanceof I)return t;let n=wt(t),r=Ht(t);return String(n)===String(10004)?new I(u.AttachmentUnavailable,r):typeof n=="string"&&Nt.has(n)?new I(n,r):new I(e,r)},B=(t,e,n)=>p(void 0,null,function*(){if(!Ue(e))throw new I(u.InvalidFunctionName,"Function name \u5FC5\u987B\u4F7F\u7528 function \u5F00\u5934\u7684\u70B9\u53F7\u8DEF\u5F84");return t.invokeApi(g.FunctionInvoke,{functionName:e,params:n})}),q=class{constructor(e){this.channel=e;this.uploadAttachment=r=>p(this,null,function*(){var i=r,{onProgress:e}=i,n=Te(i,["onProgress"]);if(!Be(n==null?void 0:n.baseToken)||!Be(n==null?void 0:n.tableId)||!Mt(n==null?void 0:n.file))throw new I(u.InvalidAttachmentTarget,"\u9644\u4EF6\u4E0A\u4F20\u76EE\u6807\u5FC5\u987B\u5305\u542B baseToken\u3001tableId\uFF0C\u4E14 file \u4E3A File");let o=Pt(),s,d=()=>{},c=()=>{this.channel.invokeApi(g.AttachmentUploadCancel,{uploadId:o}).catch(()=>{})},m=new Promise((h,_)=>{let H=()=>{clearTimeout(s),s=setTimeout(()=>{c(),_(new I(u.AttachmentUploadStalled,`\u9644\u4EF6\u4E0A\u4F20\u5DF2\u505C\u6EDE\u8D85\u8FC7 ${qe/1e3}s`))},qe)};d=this.channel.subscribeEvent(y.AttachmentUploadProgress,T=>{(T==null?void 0:T.uploadId)===o&&(H(),Promise.resolve(e==null?void 0:e(T)).catch(()=>{console.error("[base-site-channel][runtime] Attachment progress callback failed")}))})});try{return yield Promise.race([this.channel.invokeApi(g.AttachmentUpload,f(a({},n),{uploadId:o}),{timeoutMs:Ft}),m])}catch(h){throw Lt(h,u.AttachmentUploadFailed)}finally{clearTimeout(s),d()}});this.invokeHttp=e=>De(this.channel,e);this.invokeApi=(e,n)=>B(this.channel,e,n);this.getRuntimeContext=()=>this.channel.invokeApi(g.RuntimeContext,void 0);this.getCurrentUser=()=>B(this.channel,D.GetCurrentUser,void 0);this.logout=()=>B(this.channel,D.Logout,void 0);this.requestEdit=()=>B(this.channel,D.RequestEdit,void 0);this.ready=()=>this.channel.emitEvent(y.LifecycleReady,{protocolVersion:Oe});this.reportLoadFailed=e=>this.channel.emitEvent(y.LifecycleLoadFailed,{code:e});this.subscribeModeChanged=e=>this.channel.subscribeEvent(y.ModeChanged,({mode:n})=>e(n))}},j=(t=k)=>new q(t),v=j(),Ot=v.invokeHttp,Ut=v.invokeApi,Dt=v.getCurrentUser,Bt=v.logout,qt=v.requestEdit,jt=v.uploadAttachment;var Kt=new Set(["open.feishu.cn","open.feishu-pre.cn","open.feishu-boe.cn"]),Ke="/open-apis",Vt="/base-site/api/openapi",zt=new Set(["DELETE","GET","PATCH","POST","PUT"]),Wt=()=>(typeof globalThis.location=="undefined"?"":globalThis.location.pathname).replace(/^\/+/,"").startsWith("preview")?[["x-project-env","preview"]]:[],$t=t=>{if(typeof Request!="undefined"&&t instanceof Request)throw new TypeError("Site Runtime fetch \u6682\u4E0D\u652F\u6301 Request \u5165\u53C2");let e=String(t);if(e.startsWith("//"))throw new TypeError("Site Runtime fetch \u4E0D\u652F\u6301 scheme-relative URL");if(e.startsWith("/"))return e;let n=new URL(e);if(Kt.has(n.hostname)&&n.pathname.startsWith(Ke))return`${Vt}${n.pathname.slice(Ke.length)}${n.search}`;throw new TypeError("Site Runtime fetch \u4EC5\u652F\u6301\u76F8\u5BF9\u4E1A\u52A1\u8DEF\u5F84")},Yt=t=>{let e=new Headers(t);Wt().forEach(([r,i])=>e.set(r,i));let n={};return e.forEach((r,i)=>{n[i]=r}),n},Gt=(t,e)=>{var r,i,o;let n=(i=(r=t==null?void 0:t.method)==null?void 0:r.toUpperCase())!=null?i:"GET";if(!zt.has(n))throw new TypeError(`Site Runtime fetch \u4E0D\u652F\u6301 ${n} \u65B9\u6CD5`);if((t==null?void 0:t.body)!==void 0&&t.body!==null&&typeof t.body!="string")throw new TypeError("Site Runtime fetch body \u4EC5\u652F\u6301\u5B57\u7B26\u4E32");if((o=t==null?void 0:t.signal)!=null&&o.aborted)throw new DOMException("The operation was aborted","AbortError");return{body:typeof(t==null?void 0:t.body)=="string"?t.body:void 0,headers:Yt(t==null?void 0:t.headers),method:n,timeoutMs:e}},K=(t=v,e)=>(n,r)=>t.invokeHttp(f(a({init:Gt(r,e)},r!=null&&r.signal?{signal:r.signal}:{}),{url:$t(n)})),Jt=K();var Ve=0,Xt=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(Ve+=1,`site-chatbot-${Ve}`),V=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] Chatbot callback failed")}},F=class extends Error{constructor(n,r){super(`Chatbot stream error: ${n}`);this.code=n;this.retryable=r;this.name="SiteChatbotStreamError"}},ne=class{constructor(e){this.options=e;this.init=e=>{this.destroy();let n=Xt(),r={lastSeq:0,subscriptionId:n,unsubscribeError:()=>{},unsubscribeMessage:()=>{}};r.unsubscribeMessage=this.channel.subscribeEvent(y.StreamMessage,i=>{i.subscriptionId!==n||i.seq<=r.lastSeq||(i.seq>r.lastSeq+1&&V(this.onErrorCallback,new F(u.StreamSeqGap,!0)),r.lastSeq=i.seq,V(this.onMessageCallback,i.data))}),r.unsubscribeError=this.channel.subscribeEvent(y.StreamError,i=>{i.subscriptionId===n&&V(this.onErrorCallback,new F(i.code,i.retryable))}),this.current=r,this.channel.invokeApi(g.StreamOpen,{chatbotId:this.options.chatbotId,subscriptionId:n,threadId:e}).catch(()=>{var i;((i=this.current)==null?void 0:i.subscriptionId)===n&&V(this.onErrorCallback,new F(u.StreamOpenFailed,!0))})};this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.destroy=()=>{let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),this.current=void 0,this.channel.invokeApi(g.StreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] Chatbot stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k}};var ie="prod",ze=0,Ye=()=>typeof crypto!="undefined"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():(ze+=1,`site-ai-fn-${ze}`),E=(t,e)=>{try{t==null||t(e)}catch(n){console.error("[base-site-channel][runtime] AI function callback failed")}},l=(t,e)=>{let n=new Error(e||`AI function error: ${t}`);return n.name="SiteAIFunctionError",n.code=t,n},Ge=()=>l(u.InvalidHttpUrl,"siteToken is required to invoke site AI function"),oe=()=>typeof window!="undefined"&&window.parent!==window,se=t=>{if(typeof queueMicrotask=="function"){queueMicrotask(t);return}Promise.resolve().then(t)},ae=t=>{let e={data:[],event:"message"};for(let n of t.split(/\r?\n/))n.startsWith("event:")?e.event=n.slice(6).trim():n.startsWith("data:")&&e.data.push(n.slice(5).trimStart());return e},re=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string")return r}},Je=t=>{let e=[t];if(t&&typeof t=="object"){let n=t;e.push(n.response,n.data)}for(let n of e){if(!n||typeof n!="object")continue;let r=re(n,["request_id","requestId","RequestID","id"]);if(r)return r}},Xe=t=>{if(!t||typeof t!="object")return{};let e=t;return{content:re(e,["content","text","answer"]),reasoningContent:re(e,["reasoning_content","reasoningContent","reasoning"])}},Qt=t=>{if(!t||typeof t!="object")return{};let e=t.choices;if(!Array.isArray(e))return{};for(let n of e){let r=n.delta,{content:i,reasoningContent:o}=Xe(r);if(i!==void 0||o!==void 0)return{content:i,reasoningContent:o}}return{}},Qe=t=>{var n;let e=[t];if(t&&typeof t=="object"){let r=t;e.push(r.response,r.data)}for(let r of e){let i=Qt(r);if(i.content!==void 0||i.reasoningContent!==void 0)return i;let o=Xe(r&&typeof r=="object"&&(n=r.delta)!=null?n:r);if(o.content!==void 0||o.reasoningContent!==void 0)return o}return{}},z=t=>{try{let e=JSON.parse(t),n=Qe(e),r=Je(e);return f(a(a(a({},n.content!==void 0?{content:n.content}:{}),n.reasoningContent!==void 0?{reasoningContent:n.reasoningContent}:{}),r?{requestId:r}:{}),{raw:e})}catch(e){return{content:t,raw:t}}},Ze=t=>{if(typeof t=="string")return z(t);let e=Qe(t),n=Je(t),r=t&&typeof t=="object"&&"raw"in t?t.raw:t;return f(a(a(a({},e.content!==void 0?{content:e.content}:{}),e.reasoningContent!==void 0?{reasoningContent:e.reasoningContent}:{}),n?{requestId:n}:{}),{raw:r})},Zt=t=>{var e,n;try{let r=JSON.parse(t),i=(e=r.Code)!=null?e:r.code,o=(n=r.Message)!=null?n:r.message,s=typeof i=="string"||typeof i=="number"?String(i):"STREAM_FAILED";return l(s||"STREAM_FAILED",typeof o=="string"&&o?o:t)}catch(r){return l("STREAM_FAILED",t)}},ce=()=>({text:""}),en=t=>/(^|\n)(data|event|id|retry):/.test(t),We=t=>{if(!t||t==="[DONE]")return!!t;try{return JSON.parse(t),!0}catch(e){return!1}},tn=t=>{if(t){if(en(t)){let n=ae(t).data.join(`
|
|
2
|
+
`);return We(n)?n:void 0}return We(t)?t:void 0}},de=(t,e)=>{var o;t.text+=e;let n=t.text.split(/\r?\n\r?\n/);t.text=(o=n.pop())!=null?o:"";let r=n.map(s=>ae(s).data.join(`
|
|
3
|
+
`)).filter(Boolean),i=tn(t.text);return i!==void 0&&(r.push(i),t.text=""),r},nn=(t,e)=>t==="[DONE]"?(E(e.onDone,void 0),!0):(E(e.onMessage,z(t)),!1),$e=(t,e,n)=>{let r=ae(t);if(r.data.length===0)return!1;let i=r.data.join(`
|
|
4
|
+
`);if(r.event==="error")return E(n.onError,Zt(i)),!0;for(let o of de(e,i))if(nn(o,n))return!0;return!1},et=(t,e)=>p(void 0,null,function*(){var s;if(!t.body)throw l(u.StreamUnavailable,"SSE body missing");let n=t.body.getReader(),r=new TextDecoder,i=ce(),o="";try{for(;;){let{done:d,value:c}=yield n.read();o+=r.decode(c,{stream:!d});let m=o.split(/\r?\n\r?\n/);o=(s=m.pop())!=null?s:"";for(let h of m)if($e(h,i,e))return;if(d){if(o&&$e(o,i,e))return;E(e.onError,l(u.StreamInterrupted,"SSE stream ended without [DONE]"));return}}}finally{n.releaseLock()}}),ue=()=>{var n;let t=typeof globalThis.location=="undefined"?"":globalThis.location.pathname,e=/^\/?(preview\/)?app\/([^/]+)(\/|$)/.exec(t);return e?{env:e[1]?"preview":ie,siteToken:decodeURIComponent((n=e[2])!=null?n:"")}:{}},tt=(t,e,n)=>{if(!t.startsWith("/")||t.startsWith("//"))throw l(u.InvalidHttpUrl,"AI function endpoint must be a same-origin relative path");let r=t.replace("{siteToken}",encodeURIComponent(e.siteToken)).replace(":token",encodeURIComponent(e.siteToken)).replace("{functionKey}","").replace(":function_key",""),i=new URL(r,"https://base.site");if(i.searchParams.set("env",e.env),n)for(let[o,s]of Object.entries(n))i.searchParams.set(o,s);return`${i.pathname}${i.search}`};var rn="/space/api/bitable/streaming/site/v1/:token/ai_functions/:function_key/invoke",rt="/space/api/bitable/site/v1/:token/ai_functions/:function_key/tasks",on=6e4,sn=/^([1-9][0-9]{1,4})x([1-9][0-9]{1,4})$/i,an=3686400,cn=16777216,dn=14,un=t=>{let e=t.trim().replace("\xD7","x");if(/^[234]K$/i.test(e))return!0;let n=sn.exec(e);if(!n)return!1;let r=Number(n[1]),i=Number(n[2]),o=r*i;return o>=an&&o<=cn&&r<=i*16&&i<=r*16},ln=t=>{if(!t)return;let e=typeof t.image=="string"?[t.image]:t.image;if(e&&(e.length<1||e.length>dn||e.some(n=>!n.trim())))throw l(u.InvalidAIFunctionTask,"input.image must contain 1 to 14 non-empty strings");if(t.size!==void 0&&!un(t.size))throw l(u.InvalidAIFunctionTask,"input.size must follow the Seedream 5.0 lite size limits")},fe=t=>{var n;let e=(n=t.siteToken)==null?void 0:n.trim();return a(a(a({},t.env?{env:t.env}:{}),t.requestId?{requestId:t.requestId}:{}),e?{siteToken:e}:{})},ge=t=>{var r,i,o;let e=ue(),n=((r=t.siteToken)==null?void 0:r.trim())||e.siteToken;if(!n)throw Ge();return{env:(o=(i=t.env)!=null?i:e.env)!=null?o:ie,requestId:t.requestId,siteToken:n}},Se=(t,e,n)=>tt(t.replace(":function_key",encodeURIComponent(e)),n),it=t=>f(a({},t.requestId?{"X-Request-Id":t.requestId}:{}),{Accept:"application/json","Content-Type":"application/json"}),ot=t=>{var e;return!t.channel&&!oe()?globalThis.fetch:K(j((e=t.channel)!=null?e:k),on)},pe=class{constructor(e,n){this.params=e;this.context=n;this.callbacks={};this.controller=new AbortController;this.closed=!1;this.onMessage=e=>{this.callbacks.onMessage=e};this.onError=e=>{this.callbacks.onError=e};this.onDone=e=>{this.callbacks.onDone=e};this.destroy=()=>{this.closed||(this.closed=!0,this.controller.abort())};se(()=>{this.start()})}start(){return p(this,null,function*(){var e;if(!this.closed)try{let n=yield fetch(Se(rn,this.params.functionKey,this.context),{body:JSON.stringify({messages:this.params.messages,variables:(e=this.params.variables)!=null?e:{}}),credentials:"include",headers:f(a({},this.context.requestId?{"X-Request-Id":this.context.requestId}:{}),{Accept:"text/event-stream","Content-Type":"application/json"}),method:"POST",signal:this.controller.signal});if(!n.ok)throw l("HTTP_ERROR",`${n.status} ${n.statusText}`);yield et(n,this.callbacks)}catch(n){this.closed||E(this.callbacks.onError,n instanceof Error?n:l("STREAM_FAILED"))}})}},he=class{constructor(e){this.options=e;this.closed=!1;this.onMessage=e=>{this.onMessageCallback=e};this.onError=e=>{this.onErrorCallback=e};this.onDone=e=>{this.onDoneCallback=e};this.destroy=()=>{this.closed=!0;let e=this.current;e&&(this.cleanup(),this.channel.invokeApi(g.AIFunctionStreamClose,{subscriptionId:e.subscriptionId}).catch(()=>console.error("[base-site-channel][runtime] AI function stream close failed")))};var n;this.channel=(n=e.channel)!=null?n:k,se(()=>this.init())}init(){var i;if(this.closed)return;this.cleanup();let e=Ye(),n={lastSeq:0,subscriptionId:e,unsubscribeDone:()=>{},unsubscribeError:()=>{},unsubscribeMessage:()=>{},upstream:ce()};n.unsubscribeMessage=this.channel.subscribeEvent(y.AIFunctionStreamMessage,o=>this.handleMessage(o,n)),n.unsubscribeError=this.channel.subscribeEvent(y.AIFunctionStreamError,o=>this.handleError(o,e)),n.unsubscribeDone=this.channel.subscribeEvent(y.AIFunctionStreamDone,o=>this.handleDone(o,e)),this.current=n;let r=a(a(a({functionKey:this.options.params.functionKey,messages:this.options.params.messages,subscriptionId:e,variables:(i=this.options.params.variables)!=null?i:{}},this.options.context.env?{env:this.options.context.env}:{}),this.options.context.requestId?{requestId:this.options.context.requestId}:{}),this.options.context.siteToken?{siteToken:this.options.context.siteToken}:{});this.channel.invokeApi(g.AIFunctionStreamOpen,r).catch(()=>{var o;((o=this.current)==null?void 0:o.subscriptionId)===e&&E(this.onErrorCallback,l(u.StreamOpenFailed))})}handleMessage(e,n){if(e.subscriptionId===n.subscriptionId&&!(e.seq<=n.lastSeq)){if(e.seq>n.lastSeq+1&&E(this.onErrorCallback,l(u.StreamSeqGap)),n.lastSeq=e.seq,typeof e.data!="string"){E(this.onMessageCallback,Ze(e.data));return}de(n.upstream,e.data).forEach(r=>{r!=="[DONE]"&&E(this.onMessageCallback,z(r))})}}handleError(e,n){e.subscriptionId===n&&(E(this.onErrorCallback,l(e.code,e.message)),this.cleanup())}handleDone(e,n){e.subscriptionId===n&&(E(this.onDoneCallback,void 0),this.cleanup())}cleanup(){let e=this.current;e&&(e.unsubscribeMessage(),e.unsubscribeError(),e.unsubscribeDone(),this.current=void 0)}},st=(t,e={})=>{var r;if(!((r=t.functionKey)!=null&&r.trim()))throw l(u.InvalidFunctionName,"functionKey is required");let n=a(a({},ue()),fe(e));return e.channel||oe()?new he({channel:e.channel,context:n,params:t}):new pe(t,ge(e))},pn=t=>p(void 0,null,function*(){if(!t.ok){let e=yield t.text().catch(()=>"");throw l("HTTP_ERROR",`${t.status} ${t.statusText} ${e}`)}try{return yield t.json()}catch(e){throw l(u.InvalidAIFunctionTask,"AI function task response is invalid")}}),w=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),hn=t=>t==="cancelled"||t==="failed"||t==="queued"||t==="running"||t==="succeeded",S=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="string"&&r.trim())return r}},mn=(t,e)=>{for(let n of e){let r=t[n];if(typeof r=="number"&&Number.isFinite(r))return r}},fn=t=>{let e=S(t,["capabilityType","capability_type","CapabilityType"]);return e==="image"||e==="video"?e:void 0},gn=t=>{if(Array.isArray(t))return t.filter(w).map(e=>{var o;let n=S(e,["size","Size"]),r=S(e,["token","Token"]),i=S(e,["url","URL"]);return a(a(a({safetyStatus:(o=S(e,["safetyStatus","safety_status","SafetyStatus"]))!=null?o:""},n?{size:n}:{}),r?{token:r}:{}),i?{url:i}:{})})},Sn=t=>{var i,o;if(!w(t))return;let e=(o=(i=t.durationSeconds)!=null?i:t.duration_seconds)!=null?o:t.DurationSeconds,n=S(t,["token","Token"]),r=S(t,["url","URL"]);return a(a(a({},typeof e=="number"?{durationSeconds:e}:{}),n?{token:n}:{}),r?{url:r}:{})},le=t=>{var _,H,T,Ie,ye,Ee;if(!w(t))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let e=S(t,["type","Type"]),n=S(t,["taskId","task_id","TaskID"]),r=(_=t.status)!=null?_:t.Status;if(e!=="image_task"&&e!=="video_task"||!n||!hn(r))throw l(u.InvalidAIFunctionTask,"AI function task response is invalid");let i=(H=S(t,["requestId","request_id","RequestID"]))!=null?H:"",o=mn(t,["progress","Progress"]),s=fn(t),d=S(t,["errCode","err_code","ErrCode"]),c=S(t,["errMessage","err_message","ErrMessage"]),m=gn((Ie=(T=t.imageAssets)!=null?T:t.image_assets)!=null?Ie:t.ImageAssets),h=Sn((Ee=(ye=t.videoAsset)!=null?ye:t.video_asset)!=null?Ee:t.VideoAsset);return f(a(a(a(a(a(a({},s?{capabilityType:s}:{}),d?{errCode:d}:{}),c?{errMessage:c}:{}),m?{imageAssets:m}:{}),o!==void 0?{progress:o}:{}),h?{videoAsset:h}:{}),{requestId:i,status:r,taskId:n,type:e})},In=t=>{var i,o,s,d,c,m,h;let e=(i=t.code)!=null?i:t.Code;if(typeof e=="number"&&e!==0||typeof e=="string"&&e&&e!=="0")return{code:String(e),message:(o=S(t,["msg","message","Message"]))!=null?o:"AI function task failed"};let n=(d=(s=t.BaseResp)!=null?s:t.base_resp)!=null?d:t.baseResp;if(!w(n))return;let r=(m=(c=n.StatusCode)!=null?c:n.status_code)!=null?m:n.statusCode;if(typeof r=="number"&&r!==0||typeof r=="string"&&r&&r!=="0")return{code:String(r),message:(h=S(n,["StatusMessage","status_message","statusMessage"]))!=null?h:"AI function task failed"}},yn=t=>{if(!w(t))return le(t);let e=In(t);if(e)throw l(e.code,e.message);return"data"in t&&t.data!==void 0?le(t.data):le(t)},at=t=>p(void 0,null,function*(){return yn(yield pn(t))}),me=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var s,d,c;if(!((s=t.functionKey)!=null&&s.trim()))throw l(u.InvalidFunctionName,"functionKey is required");t.capability==="image"&&ln(t.input);let i=ge(a(a({},e),fe(e))),o=yield ot(e)(Se(rt,t.functionKey,i),{body:JSON.stringify({input:(d=t.input)!=null?d:{},variables:(c=t.variables)!=null?c:{}}),credentials:"include",headers:it(i),method:"POST"});return at(o)}),En=(r,i,...o)=>p(void 0,[r,i,...o],function*(t,e,n={}){if(!(t!=null&&t.trim()))throw l(u.InvalidFunctionName,"functionKey is required");if(typeof e!="string"||!e.trim())throw l(u.InvalidAIFunctionTask,"taskId is required");let s=ge(a(a({},n),fe(n))),d=Se(rt,t,s),c=d.includes("?")?`${d.replace("?",`/${encodeURIComponent(e)}?`)}`:`${d}/${encodeURIComponent(e)}`,m=yield ot(n)(c,{credentials:"include",headers:it(s),method:"GET"});return at(m)}),nt=(t,e)=>new Promise((n,r)=>{var d;let i="",o="",s=st({functionKey:t.functionKey,messages:(d=t.messages)!=null?d:[],variables:t.variables},e);s.onMessage(c=>{typeof c.content=="string"&&(i+=c.content),!o&&typeof c.requestId=="string"&&c.requestId&&(o=c.requestId)}),s.onError(c=>{s.destroy(),r(c)}),s.onDone(()=>{s.destroy(),n({content:i,requestId:o||e.requestId||"",type:"text"})})}),An=(n,...r)=>p(void 0,[n,...r],function*(t,e={}){var i;if(!((i=t.functionKey)!=null&&i.trim()))throw l(u.InvalidFunctionName,"functionKey is required");return t.capability==="image"||t.capability==="video"?me(t,e):t.capability==="text"||t.capability==="vision"?nt(t,e):t.input&&!t.messages?me(t,e):nt(t,e)});export{Oe as SITE_RUNTIME_PROTOCOL_VERSION,ne as SiteChatbotStreamAdapter,F as SiteChatbotStreamError,g as SiteRuntimeApi,q as SiteRuntimeClient,u as SiteRuntimeErrorCode,y as SiteRuntimeEvent,D as SiteRuntimeFunction,I as SiteRuntimeInvocationError,An as callSiteAIFunction,me as createSiteAIFunctionTask,j as createSiteRuntimeClient,K as createSiteRuntimeFetch,Jt as fetch,Dt as getCurrentUser,En as getSiteAIFunctionTask,Ut as invokeApi,Ot as invokeHttp,st as invokeSiteAIFunctionStream,Ue as isValidSiteFunctionName,Bt as logout,_r as readSiteAITextDelta,qt as requestEdit,v as siteRuntime,jt as uploadAttachment};
|
package/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"@lark-base-open/base-site-channel","version":"0.1.1","description":"","main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs"},"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs"},"./runtime":{"types":"./dist/runtime.d.ts","import":"./dist/runtime.mjs"},"./runtime-contract":{"types":"./dist/runtime-contract.d.ts","import":"./dist/runtime-contract.mjs"}},"files":["dist"],"scripts":{"test":"npm run build && node --import tsx --test test/*.test.ts && npm run test:types","test:types":"tsc --noEmit --strict --skipLibCheck --module esnext --moduleResolution bundler --target es2022 test-types/function-map.ts","build":"tsup","dev":"NODE_ENV=development tsup --watch","upload:alpha":"pnpm build && npx @bitable/pack-dev-cli upload"},"keywords":[],"author":"","devDependencies":{"@types/node":"^22.15.0","tsup":"^6.7.0","tsx":"^4.20.3","typescript":"^5.8.3"},"dependencies":{"lodash-es":"^4.17.21"}}
|