@pageops/sdk 0.1.11 → 0.1.12
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/dist/index.d.ts +1 -0
- package/dist/pageops-sdk.es.js +71 -61
- package/dist/pageops-sdk.umd.cjs +8 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/pageops-sdk.es.js
CHANGED
|
@@ -6,16 +6,16 @@ class P {
|
|
|
6
6
|
this.options = e;
|
|
7
7
|
}
|
|
8
8
|
async createContext(e = ((i) => (i = ((t) => ((s) => (s = (t = this.options).getPageContext) == null ? void 0 : s.call(t))())()) != null ? i : {})()) {
|
|
9
|
-
var
|
|
9
|
+
var r, l, n;
|
|
10
10
|
return this.request("/context/session", {
|
|
11
11
|
method: "POST",
|
|
12
12
|
body: JSON.stringify({
|
|
13
13
|
app_id: this.options.appId,
|
|
14
14
|
env: this.options.env,
|
|
15
15
|
route: e.route,
|
|
16
|
-
url: (
|
|
16
|
+
url: (r = e.url) != null ? r : location.href,
|
|
17
17
|
title: (l = e.title) != null ? l : document.title,
|
|
18
|
-
menu_path: (
|
|
18
|
+
menu_path: (n = e.menuPath) != null ? n : [],
|
|
19
19
|
tenant_id: e.tenantId,
|
|
20
20
|
user_role: e.userRole,
|
|
21
21
|
build_version: e.buildVersion
|
|
@@ -55,12 +55,12 @@ class P {
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
async request(e, t) {
|
|
58
|
-
var l,
|
|
58
|
+
var l, n;
|
|
59
59
|
const s = (t == null ? void 0 : t.body) instanceof FormData ? t.headers : { "content-type": "application/json", ...(l = t == null ? void 0 : t.headers) != null ? l : {} }, i = await fetch(`${this.base()}${e}`, { ...t, headers: s });
|
|
60
60
|
if (i.status === 204) return;
|
|
61
|
-
const
|
|
62
|
-
if (!i.ok) throw new Error((
|
|
63
|
-
return
|
|
61
|
+
const r = await i.json();
|
|
62
|
+
if (!i.ok) throw new Error((n = r.message) != null ? n : "PageOps 请求失败");
|
|
63
|
+
return r;
|
|
64
64
|
}
|
|
65
65
|
base() {
|
|
66
66
|
const e = this.options.apiBase.replace(/\/$/, "");
|
|
@@ -77,15 +77,15 @@ function I(a) {
|
|
|
77
77
|
function v(a) {
|
|
78
78
|
return I(a).replace(/`([^`]+)`/g, "<code>$1</code>").replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
79
79
|
}
|
|
80
|
-
function
|
|
80
|
+
function q(a, e) {
|
|
81
81
|
const t = a[e], s = a[e + 1];
|
|
82
82
|
if (!(t != null && t.includes("|")) || !/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(s != null ? s : "")) return null;
|
|
83
83
|
const i = [];
|
|
84
|
-
let
|
|
85
|
-
for (;
|
|
86
|
-
i.push(a[
|
|
87
|
-
const l = (p) => p.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((f) => v(f.trim())),
|
|
88
|
-
return { html: `<table><thead><tr>${
|
|
84
|
+
let r = e;
|
|
85
|
+
for (; r < a.length && a[r].includes("|") && a[r].trim(); )
|
|
86
|
+
i.push(a[r]), r += 1;
|
|
87
|
+
const l = (p) => p.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((f) => v(f.trim())), n = l(i[0]).map((p) => `<th>${p}</th>`).join(""), d = i.slice(2).map((p) => `<tr>${l(p).map((f) => `<td>${f}</td>`).join("")}</tr>`).join("");
|
|
88
|
+
return { html: `<table><thead><tr>${n}</tr></thead><tbody>${d}</tbody></table>`, next: r };
|
|
89
89
|
}
|
|
90
90
|
function w(a) {
|
|
91
91
|
const e = a.split(`
|
|
@@ -100,35 +100,35 @@ function w(a) {
|
|
|
100
100
|
`))}</code></pre>`);
|
|
101
101
|
continue;
|
|
102
102
|
}
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
t.push(
|
|
103
|
+
const r = q(e, s);
|
|
104
|
+
if (r) {
|
|
105
|
+
t.push(r.html), s = r.next - 1;
|
|
106
106
|
continue;
|
|
107
107
|
}
|
|
108
108
|
i.startsWith("### ") ? t.push(`<h4>${v(i.slice(4))}</h4>`) : i.startsWith("## ") ? t.push(`<h3>${v(i.slice(3))}</h3>`) : i.startsWith("# ") ? t.push(`<h2>${v(i.slice(2))}</h2>`) : i.startsWith("- ") ? t.push(`<li>${v(i.slice(2))}</li>`) : i.trim() ? t.push(`<p>${v(i)}</p>`) : t.push("<br>");
|
|
109
109
|
}
|
|
110
110
|
return t.join("");
|
|
111
111
|
}
|
|
112
|
-
async function
|
|
113
|
-
var
|
|
112
|
+
async function U(a, e) {
|
|
113
|
+
var r;
|
|
114
114
|
const t = a.getReader(), s = new TextDecoder();
|
|
115
115
|
let i = "";
|
|
116
116
|
for (; ; ) {
|
|
117
|
-
const { done: l, value:
|
|
117
|
+
const { done: l, value: n } = await t.read();
|
|
118
118
|
if (l) {
|
|
119
119
|
i += s.decode();
|
|
120
120
|
break;
|
|
121
121
|
}
|
|
122
|
-
i += s.decode(
|
|
122
|
+
i += s.decode(n, { stream: !0 });
|
|
123
123
|
const d = i.split(/\r?\n\r?\n/);
|
|
124
|
-
i = (
|
|
124
|
+
i = (r = d.pop()) != null ? r : "";
|
|
125
125
|
for (const p of d) T(p, e);
|
|
126
126
|
}
|
|
127
127
|
i.trim() && T(i, e);
|
|
128
128
|
}
|
|
129
129
|
function T(a, e) {
|
|
130
|
-
var i,
|
|
131
|
-
const t = (i = a.match(/^event:\s*(.+)$/m)) == null ? void 0 : i[1], s = (
|
|
130
|
+
var i, r;
|
|
131
|
+
const t = (i = a.match(/^event:\s*(.+)$/m)) == null ? void 0 : i[1], s = (r = a.match(/^data:\s*(.+)$/m)) == null ? void 0 : r[1];
|
|
132
132
|
t && s && e(t, JSON.parse(s));
|
|
133
133
|
}
|
|
134
134
|
class K {
|
|
@@ -181,6 +181,7 @@ class F {
|
|
|
181
181
|
o(this, "sourceSnapshots", []);
|
|
182
182
|
o(this, "sourceUploadStatus", "");
|
|
183
183
|
o(this, "sourceUploadError", "");
|
|
184
|
+
o(this, "sourceLoadError", "");
|
|
184
185
|
o(this, "sourceUploading", !1);
|
|
185
186
|
o(this, "sourceRefreshTimer", null);
|
|
186
187
|
o(this, "streaming", "");
|
|
@@ -207,7 +208,7 @@ class F {
|
|
|
207
208
|
}
|
|
208
209
|
unmount() {
|
|
209
210
|
var e;
|
|
210
|
-
this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.sourceSnapshots = [], this.sourceUploadStatus = "", this.sourceUploadError = "", this.sourceUploading = !1, this.answerAudience = "business", this.audienceChanging = !1;
|
|
211
|
+
this.stopSourceRefresh(), this.cancelActiveAnswer(!1), this.resetAnswerState(), (e = this.root) == null || e.remove(), this.root = null, this.panel = null, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.conversations = [], this.messages = [], this.steps = [], this.sourceSnapshots = [], this.sourceUploadStatus = "", this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.answerAudience = "business", this.audienceChanging = !1;
|
|
211
212
|
}
|
|
212
213
|
open() {
|
|
213
214
|
this.root && (this.root.innerHTML = "", this.panel = document.createElement("div"), this.panel.className = "po-panel", this.root.appendChild(this.panel), this.loadSources(), this.loadConversations(), this.renderPanel());
|
|
@@ -270,21 +271,21 @@ class F {
|
|
|
270
271
|
}
|
|
271
272
|
}
|
|
272
273
|
getPageContextKey(e) {
|
|
273
|
-
var t, s, i,
|
|
274
|
+
var t, s, i, r, l;
|
|
274
275
|
return JSON.stringify([
|
|
275
276
|
(t = e.route) != null ? t : "",
|
|
276
277
|
(s = e.url) != null ? s : location.href,
|
|
277
278
|
(i = e.title) != null ? i : document.title,
|
|
278
|
-
(
|
|
279
|
+
(r = e.menuPath) != null ? r : [],
|
|
279
280
|
(l = e.userRole) != null ? l : ""
|
|
280
281
|
]);
|
|
281
282
|
}
|
|
282
283
|
async loadSources() {
|
|
283
284
|
if (this.client) {
|
|
284
285
|
try {
|
|
285
|
-
this.sourceSnapshots = await this.client.listSources(), this.
|
|
286
|
+
this.sourceSnapshots = await this.client.listSources(), this.sourceLoadError = "";
|
|
286
287
|
} catch (e) {
|
|
287
|
-
this.
|
|
288
|
+
this.sourceLoadError = "源码包状态加载失败,连接恢复后将自动重试。";
|
|
288
289
|
}
|
|
289
290
|
this.scheduleSourceRefresh(), this.renderPanel();
|
|
290
291
|
}
|
|
@@ -341,20 +342,20 @@ class F {
|
|
|
341
342
|
const s = ++this.activeRunId, i = new AbortController();
|
|
342
343
|
this.abortController = i, this.stoppedRunId = -1, this.asking = !0, this.waitingForFirstContent = !0, this.renderPanel();
|
|
343
344
|
try {
|
|
344
|
-
const
|
|
345
|
-
if (this.currentThread && this.selectedPageKey && this.selectedPageKey !==
|
|
345
|
+
const r = this.getPageContextKey(this.getPageContext());
|
|
346
|
+
if (this.currentThread && this.selectedPageKey && this.selectedPageKey !== r && (this.currentThread = null), this.currentThread || await this.newConversation(), !this.currentThread) throw new Error("无法创建问答会话,请稍后重试。");
|
|
346
347
|
this.messages.push({ id: `local-${Date.now()}`, role: "user", content: e, metadata_json: {} }), this.steps = [], this.renderPanel();
|
|
347
348
|
const l = await this.client.streamQuestion(this.currentThread.id, e, i.signal);
|
|
348
349
|
if (!l.ok) throw new Error(await R(l, "服务暂时无法回答,请稍后重试。"));
|
|
349
350
|
if (!l.body) throw new Error("服务未返回有效的流式响应,请稍后重试。");
|
|
350
|
-
if (await
|
|
351
|
+
if (await U(l.body, (n, d) => this.handleStreamEvent(n, d)), s === this.stoppedRunId) throw new DOMException("输出已停止", "AbortError");
|
|
351
352
|
if (this.streamFailure) throw new Error(this.streamFailure);
|
|
352
353
|
if (!this.streamDone) throw new Error("服务响应意外中断,请稍后重试。");
|
|
353
354
|
if (await this.typewriter.drain(), s === this.stoppedRunId) throw new DOMException("输出已停止", "AbortError");
|
|
354
355
|
await this.selectThread(this.currentThread);
|
|
355
|
-
} catch (
|
|
356
|
+
} catch (r) {
|
|
356
357
|
if (s !== this.activeRunId) return;
|
|
357
|
-
this.typewriter.clear(), this.waitingForFirstContent = !1, s === this.stoppedRunId ? this.answerStopped = !0 : (this.answerError =
|
|
358
|
+
this.typewriter.clear(), this.waitingForFirstContent = !1, s === this.stoppedRunId ? this.answerStopped = !0 : (this.answerError = r instanceof Error ? r.message : "服务异常,请稍后重试。", this.upsertStep({ id: "error", title: "执行失败", status: "failed", details: { message: this.answerError } }));
|
|
358
359
|
} finally {
|
|
359
360
|
if (s !== this.activeRunId) return;
|
|
360
361
|
this.asking = !1, this.waitingForFirstContent = !1, this.abortController === i && (this.abortController = null), this.renderPanel(!0);
|
|
@@ -379,9 +380,9 @@ class F {
|
|
|
379
380
|
return;
|
|
380
381
|
}
|
|
381
382
|
if (e === "delta") {
|
|
382
|
-
const
|
|
383
|
-
if (!
|
|
384
|
-
this.waitingForFirstContent = !1, this.typewriter.enqueue(
|
|
383
|
+
const r = String((s = t.content) != null ? s : "");
|
|
384
|
+
if (!r) return;
|
|
385
|
+
this.waitingForFirstContent = !1, this.typewriter.enqueue(r);
|
|
385
386
|
return;
|
|
386
387
|
}
|
|
387
388
|
e === "done" && (this.streamDone = t), e === "error" && (this.streamFailure = String((i = t.message) != null ? i : "服务异常,请稍后重试。"));
|
|
@@ -412,18 +413,18 @@ class F {
|
|
|
412
413
|
return ["pending", "running"].includes(this.latestAnalysisStatus());
|
|
413
414
|
}
|
|
414
415
|
questionUnavailableReason() {
|
|
415
|
-
return this.sourceSnapshots.length ? this.isProjectMemoryUpdating() ? "项目记忆正在更新,完成前暂不能问答。" : this.latestAnalysisStatus() === "failed" ? "项目记忆更新失败,请重新上传或重新索引。" : "" : "请先上传代码包后再提问。";
|
|
416
|
+
return this.sourceLoadError && !this.sourceSnapshots.length ? "暂时无法读取项目共享代码包,请检查 PageOps 服务连接。" : this.sourceSnapshots.length ? this.isProjectMemoryUpdating() ? "项目记忆正在更新,完成前暂不能问答。" : this.latestAnalysisStatus() === "failed" ? "项目记忆更新失败,请重新上传或重新索引。" : "" : "请先上传代码包后再提问。";
|
|
416
417
|
}
|
|
417
418
|
scheduleSourceRefresh() {
|
|
418
|
-
this.stopSourceRefresh(), this.isProjectMemoryUpdating() && (this.sourceRefreshTimer = setTimeout(() => void this.loadSources(), 1500));
|
|
419
|
+
this.stopSourceRefresh(), !(!this.sourceLoadError && !this.isProjectMemoryUpdating()) && (this.sourceRefreshTimer = setTimeout(() => void this.loadSources(), 1500));
|
|
419
420
|
}
|
|
420
421
|
stopSourceRefresh() {
|
|
421
422
|
this.sourceRefreshTimer && clearTimeout(this.sourceRefreshTimer), this.sourceRefreshTimer = null;
|
|
422
423
|
}
|
|
423
424
|
renderPanel(e = this.asking) {
|
|
424
425
|
if (!this.panel) return;
|
|
425
|
-
const t = this.questionUnavailableReason(), s = t || (this.asking ? "回答生成中,请稍候" : "请输入页面分析问题,Enter 发送,Shift + Enter 换行"), i = !!(t || this.asking),
|
|
426
|
-
<button type="button" data-audience="${
|
|
426
|
+
const t = this.questionUnavailableReason(), s = t || (this.asking ? "回答生成中,请稍候" : "请输入页面分析问题,Enter 发送,Shift + Enter 换行"), i = !!(t || this.asking), r = t ? '<button type="submit" disabled>暂不可提问</button>' : this.asking ? '<button class="po-stop" type="button" data-action="stop-answer" aria-label="停止输出" title="停止输出"><span aria-hidden="true"></span></button>' : '<button type="submit">发送</button>', l = y.map((n) => `
|
|
427
|
+
<button type="button" data-audience="${n.value}" aria-pressed="${n.value === this.answerAudience}" ${this.asking || this.audienceChanging ? "disabled" : ""}>${n.label}</button>
|
|
427
428
|
`).join("");
|
|
428
429
|
if (this.panel.innerHTML = `
|
|
429
430
|
<aside class="po-sidebar">
|
|
@@ -431,29 +432,29 @@ class F {
|
|
|
431
432
|
<button class="po-new" data-action="new" ${this.asking ? "disabled" : ""}>+ 新建问答</button>
|
|
432
433
|
<input class="po-search" placeholder="搜索问答" />
|
|
433
434
|
${this.conversationError ? `<p class="po-conversation-error" role="alert">${c(this.conversationError)}</p>` : ""}
|
|
434
|
-
<div class="po-thread-list">${this.conversations.map((
|
|
435
|
+
<div class="po-thread-list">${this.conversations.map((n) => {
|
|
435
436
|
var d;
|
|
436
437
|
return `
|
|
437
|
-
<div class="po-thread-row ${
|
|
438
|
-
<button class="po-thread" data-thread="${c(
|
|
439
|
-
<strong>${c(
|
|
438
|
+
<div class="po-thread-row ${n.id === ((d = this.currentThread) == null ? void 0 : d.id) ? "active" : ""}">
|
|
439
|
+
<button class="po-thread" data-thread="${c(n.id)}" ${this.asking ? "disabled" : ""}>
|
|
440
|
+
<strong>${c(n.title)}</strong><span>${A(n.created_at)}</span>
|
|
440
441
|
</button>
|
|
441
|
-
<button class="po-thread-delete" type="button" data-delete-thread="${c(
|
|
442
|
+
<button class="po-thread-delete" type="button" data-delete-thread="${c(n.id)}" aria-label="删除会话:${c(n.title)}" title="删除会话" ${this.asking || this.deletingThreadId === n.id ? "disabled" : ""}><span class="po-trash-icon" aria-hidden="true"></span></button>
|
|
442
443
|
</div>`;
|
|
443
444
|
}).join("")}</div>
|
|
444
445
|
</aside>
|
|
445
446
|
<main class="po-chat">
|
|
446
447
|
<header><div class="po-chat-title"><p>问数回答</p><h2>${this.currentThread ? c(this.currentThread.title) : "未选择问答"}</h2></div><div class="po-audience"><span>回答角色</span><div class="po-audience-options" role="group" aria-label="回答角色">${l}</div></div></header>
|
|
447
448
|
<section class="po-messages">
|
|
448
|
-
${this.messages.map((
|
|
449
|
+
${this.messages.map((n) => `<article class="po-message ${n.role}"><b>${n.role === "user" ? "你" : "PageOps 分析"}</b><div>${n.role === "assistant" ? w(n.content) : c(n.content)}</div></article>`).join("")}
|
|
449
450
|
${this.renderAnswerState()}
|
|
450
451
|
</section>
|
|
451
|
-
<form class="po-composer"><textarea ${i ? "disabled" : ""} placeholder="${c(s)}"></textarea>${
|
|
452
|
+
<form class="po-composer"><textarea ${i ? "disabled" : ""} placeholder="${c(s)}"></textarea>${r}</form>
|
|
452
453
|
</main>
|
|
453
454
|
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}${this.renderSteps()}</section></aside>
|
|
454
455
|
`, this.bindPanelEvents(), e) {
|
|
455
|
-
const
|
|
456
|
-
|
|
456
|
+
const n = this.panel.querySelector(".po-messages");
|
|
457
|
+
n && (n.scrollTop = n.scrollHeight);
|
|
457
458
|
}
|
|
458
459
|
}
|
|
459
460
|
renderAnswerState() {
|
|
@@ -461,34 +462,36 @@ class F {
|
|
|
461
462
|
return `${e}${t}${i}${s}`;
|
|
462
463
|
}
|
|
463
464
|
renderSourceUploader() {
|
|
465
|
+
const e = this.sourceLoadError ? "暂时无法读取项目共享代码包,连接恢复后将自动重试。" : "当前项目暂无代码包,请先上传后再提问。";
|
|
464
466
|
return `
|
|
465
467
|
<div class="po-source-uploader">
|
|
466
468
|
<strong>源码包</strong>
|
|
467
|
-
<p
|
|
469
|
+
<p>同一项目的所有回答角色共享代码包。上传 zip、tar、tar.gz 或 tgz 后,PageOps 将基于代码证据回答问题。</p>
|
|
468
470
|
<label class="po-upload-button">
|
|
469
471
|
<span>${this.sourceUploading ? "上传中..." : "选择代码包"}</span>
|
|
470
472
|
<input type="file" accept=".zip,.tar,.gz,.tgz" data-action="upload-source" ${this.sourceUploading ? "disabled" : ""} />
|
|
471
473
|
</label>
|
|
472
474
|
${this.sourceUploadStatus ? `<p class="po-upload-status">${c(this.sourceUploadStatus)}</p>` : ""}
|
|
473
|
-
${this.sourceSnapshots.length ? `<div class="po-source-list">${this.sourceSnapshots.map((
|
|
475
|
+
${this.sourceSnapshots.length ? `<div class="po-source-list">${this.sourceSnapshots.map((t) => this.renderSourceItem(t)).join("")}</div>` : `<p class="po-upload-empty">${e}</p>`}
|
|
476
|
+
${this.sourceLoadError ? `<p class="po-upload-error">${c(this.sourceLoadError)}</p>` : ""}
|
|
474
477
|
${this.sourceUploadError ? `<p class="po-upload-error">${c(this.sourceUploadError)}</p>` : ""}
|
|
475
478
|
</div>
|
|
476
479
|
`;
|
|
477
480
|
}
|
|
478
481
|
renderSourceItem(e) {
|
|
479
|
-
var
|
|
480
|
-
const t = e.filename || "未命名代码包", s = e.created_at ? A(e.created_at) : "刚刚上传", i =
|
|
482
|
+
var n, d, p;
|
|
483
|
+
const t = e.filename || "未命名代码包", s = e.created_at ? A(e.created_at) : "刚刚上传", i = O(e.archive_bytes || e.total_bytes || 0), r = String((d = (n = e.metadata) == null ? void 0 : n.analysis_status) != null ? d : "unknown"), l = (p = { pending: "项目记忆等待更新", running: "项目记忆更新中", ready: "项目记忆已就绪", failed: "项目记忆更新失败" }[r]) != null ? p : "项目记忆状态未知";
|
|
481
484
|
return `<article class="po-source-item"><strong>${c(t)}</strong><span>${c(s)} · ${c(i)}</span><span>${c(l)}</span></article>`;
|
|
482
485
|
}
|
|
483
486
|
renderSteps() {
|
|
484
487
|
return (this.steps.length ? this.steps : [{ id: "idle", title: "等待任务", status: "pending", details: { message: "发送消息后展示执行过程。" } }]).map((t) => {
|
|
485
488
|
var s;
|
|
486
|
-
return `<details class="po-step ${t.status}" ${t.status === "running" || t.status === "failed" ? "open" : ""}><summary><strong>${c(t.title)}</strong><span>${
|
|
489
|
+
return `<details class="po-step ${t.status}" ${t.status === "running" || t.status === "failed" ? "open" : ""}><summary><strong>${c(t.title)}</strong><span>${_(t.status)}</span></summary><pre>${c(JSON.stringify((s = t.details) != null ? s : {}, null, 2))}</pre></details>`;
|
|
487
490
|
}).join("");
|
|
488
491
|
}
|
|
489
492
|
bindPanelEvents() {
|
|
490
|
-
var e, t, s, i,
|
|
491
|
-
(t = (e = this.panel) == null ? void 0 : e.querySelector('[data-action="new"]')) == null || t.addEventListener("click", () => void this.newConversation()), (i = (s = this.panel) == null ? void 0 : s.querySelector('[data-action="close"]')) == null || i.addEventListener("click", () => this.close()), (l = (
|
|
493
|
+
var e, t, s, i, r, l, n, d, p, f, b, S, $, E, C;
|
|
494
|
+
(t = (e = this.panel) == null ? void 0 : e.querySelector('[data-action="new"]')) == null || t.addEventListener("click", () => void this.newConversation()), (i = (s = this.panel) == null ? void 0 : s.querySelector('[data-action="close"]')) == null || i.addEventListener("click", () => this.close()), (l = (r = this.panel) == null ? void 0 : r.querySelector('[data-action="stop-answer"]')) == null || l.addEventListener("click", () => this.cancelActiveAnswer(!0)), (n = this.panel) == null || n.querySelectorAll("[data-audience]").forEach((u) => {
|
|
492
495
|
u.addEventListener("click", () => {
|
|
493
496
|
var h;
|
|
494
497
|
return void this.changeAnswerAudience((h = u.dataset.audience) != null ? h : "");
|
|
@@ -524,9 +527,16 @@ function c(a) {
|
|
|
524
527
|
return a.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
525
528
|
}
|
|
526
529
|
function A(a) {
|
|
527
|
-
return new Intl.DateTimeFormat("zh-CN", {
|
|
530
|
+
return new Intl.DateTimeFormat("zh-CN", {
|
|
531
|
+
timeZone: "Asia/Shanghai",
|
|
532
|
+
month: "2-digit",
|
|
533
|
+
day: "2-digit",
|
|
534
|
+
hour: "2-digit",
|
|
535
|
+
minute: "2-digit",
|
|
536
|
+
hourCycle: "h23"
|
|
537
|
+
}).format(new Date(a));
|
|
528
538
|
}
|
|
529
|
-
function
|
|
539
|
+
function O(a) {
|
|
530
540
|
if (!a) return "0 B";
|
|
531
541
|
const e = ["B", "KB", "MB", "GB"];
|
|
532
542
|
let t = a, s = 0;
|
|
@@ -534,10 +544,10 @@ function _(a) {
|
|
|
534
544
|
t /= 1024, s += 1;
|
|
535
545
|
return `${t >= 10 || s === 0 ? t.toFixed(0) : t.toFixed(1)} ${e[s]}`;
|
|
536
546
|
}
|
|
537
|
-
function
|
|
547
|
+
function _(a) {
|
|
538
548
|
return { pending: "等待中", running: "执行中", completed: "已完成", failed: "失败", cancelled: "已停止" }[a];
|
|
539
549
|
}
|
|
540
|
-
const
|
|
550
|
+
const j = new F();
|
|
541
551
|
export {
|
|
542
|
-
|
|
552
|
+
j as PageOpsSDK
|
|
543
553
|
};
|
package/dist/pageops-sdk.umd.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
(function(m,u){typeof exports=="object"&&typeof module!="undefined"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(m=typeof globalThis!="undefined"?globalThis:m||self,u(m.PageOpsSDK={}))})(this,(function(m){"use strict";var _=Object.defineProperty;var D=(m,u,w)=>u in m?_(m,u,{enumerable:!0,configurable:!0,writable:!0,value:w}):m[u]=w;var a=(m,u,w)=>D(m,typeof u!="symbol"?u+"":u,w);class u{constructor(e){this.options=e}async createContext(e=(i=>(i=(t=>(s=>(s=(t=this.options).getPageContext)==null?void 0:s.call(t))())())!=null?i:{})()){var n,l,r;return this.request("/context/session",{method:"POST",body:JSON.stringify({app_id:this.options.appId,env:this.options.env,route:e.route,url:(n=e.url)!=null?n:location.href,title:(l=e.title)!=null?l:document.title,menu_path:(r=e.menuPath)!=null?r:[],tenant_id:e.tenantId,user_role:e.userRole,build_version:e.buildVersion})})}async listConversations(){return(await this.request(`/conversations?app_id=${encodeURIComponent(this.options.appId)}`)).conversations}async createConversation(e,t){return this.request("/conversations",{method:"POST",body:JSON.stringify({app_id:this.options.appId,context_session_id:e,title:t})})}async deleteConversation(e){return this.request(`/conversations/${encodeURIComponent(e)}?app_id=${encodeURIComponent(this.options.appId)}`,{method:"DELETE"})}async listMessages(e){return(await this.request(`/conversations/${encodeURIComponent(e)}/messages?app_id=${encodeURIComponent(this.options.appId)}`)).messages}async listSources(){return(await this.request(`/sources?project_id=${encodeURIComponent(this.options.appId)}`)).sources}uploadSource(e){const t=new FormData;return t.append("file",e),this.request(`/sources/upload?project_id=${encodeURIComponent(this.options.appId)}`,{method:"POST",body:t,headers:{}})}streamQuestion(e,t,s){return fetch(`${this.base()}/question/stream`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:this.options.appId,thread_id:e,question:t}),signal:s})}async request(e,t){var l,r;const s=(t==null?void 0:t.body)instanceof FormData?t.headers:{"content-type":"application/json",...(l=t==null?void 0:t.headers)!=null?l:{}},i=await fetch(`${this.base()}${e}`,{...t,headers:s});if(i.status===204)return;const n=await i.json();if(!i.ok)throw new Error((r=n.message)!=null?r:"PageOps 请求失败");return n}base(){const e=this.options.apiBase.replace(/\/$/,"");return e.endsWith("/api")?e:`${e}/api`}}async function w(o,e){const t=await o.json().catch(()=>null);return typeof(t==null?void 0:t.message)=="string"&&t.message.trim()?t.message:e}function E(o){return o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function y(o){return E(o).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>")}function R(o,e){const t=o[e],s=o[e+1];if(!(t!=null&&t.includes("|"))||!/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(s!=null?s:""))return null;const i=[];let n=e;for(;n<o.length&&o[n].includes("|")&&o[n].trim();)i.push(o[n]),n+=1;const l=g=>g.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(
|
|
1
|
+
(function(m,u){typeof exports=="object"&&typeof module!="undefined"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(m=typeof globalThis!="undefined"?globalThis:m||self,u(m.PageOpsSDK={}))})(this,(function(m){"use strict";var _=Object.defineProperty;var D=(m,u,w)=>u in m?_(m,u,{enumerable:!0,configurable:!0,writable:!0,value:w}):m[u]=w;var a=(m,u,w)=>D(m,typeof u!="symbol"?u+"":u,w);class u{constructor(e){this.options=e}async createContext(e=(i=>(i=(t=>(s=>(s=(t=this.options).getPageContext)==null?void 0:s.call(t))())())!=null?i:{})()){var n,l,r;return this.request("/context/session",{method:"POST",body:JSON.stringify({app_id:this.options.appId,env:this.options.env,route:e.route,url:(n=e.url)!=null?n:location.href,title:(l=e.title)!=null?l:document.title,menu_path:(r=e.menuPath)!=null?r:[],tenant_id:e.tenantId,user_role:e.userRole,build_version:e.buildVersion})})}async listConversations(){return(await this.request(`/conversations?app_id=${encodeURIComponent(this.options.appId)}`)).conversations}async createConversation(e,t){return this.request("/conversations",{method:"POST",body:JSON.stringify({app_id:this.options.appId,context_session_id:e,title:t})})}async deleteConversation(e){return this.request(`/conversations/${encodeURIComponent(e)}?app_id=${encodeURIComponent(this.options.appId)}`,{method:"DELETE"})}async listMessages(e){return(await this.request(`/conversations/${encodeURIComponent(e)}/messages?app_id=${encodeURIComponent(this.options.appId)}`)).messages}async listSources(){return(await this.request(`/sources?project_id=${encodeURIComponent(this.options.appId)}`)).sources}uploadSource(e){const t=new FormData;return t.append("file",e),this.request(`/sources/upload?project_id=${encodeURIComponent(this.options.appId)}`,{method:"POST",body:t,headers:{}})}streamQuestion(e,t,s){return fetch(`${this.base()}/question/stream`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:this.options.appId,thread_id:e,question:t}),signal:s})}async request(e,t){var l,r;const s=(t==null?void 0:t.body)instanceof FormData?t.headers:{"content-type":"application/json",...(l=t==null?void 0:t.headers)!=null?l:{}},i=await fetch(`${this.base()}${e}`,{...t,headers:s});if(i.status===204)return;const n=await i.json();if(!i.ok)throw new Error((r=n.message)!=null?r:"PageOps 请求失败");return n}base(){const e=this.options.apiBase.replace(/\/$/,"");return e.endsWith("/api")?e:`${e}/api`}}async function w(o,e){const t=await o.json().catch(()=>null);return typeof(t==null?void 0:t.message)=="string"&&t.message.trim()?t.message:e}function E(o){return o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function y(o){return E(o).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>")}function R(o,e){const t=o[e],s=o[e+1];if(!(t!=null&&t.includes("|"))||!/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(s!=null?s:""))return null;const i=[];let n=e;for(;n<o.length&&o[n].includes("|")&&o[n].trim();)i.push(o[n]),n+=1;const l=g=>g.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(S=>y(S.trim())),r=l(i[0]).map(g=>`<th>${g}</th>`).join(""),d=i.slice(2).map(g=>`<tr>${l(g).map(S=>`<td>${S}</td>`).join("")}</tr>`).join("");return{html:`<table><thead><tr>${r}</tr></thead><tbody>${d}</tbody></table>`,next:n}}function b(o){const e=o.split(`
|
|
2
2
|
`),t=[];for(let s=0;s<e.length;s+=1){const i=e[s];if(i.trim().startsWith("```")){const l=[];for(s+=1;s<e.length&&!e[s].trim().startsWith("```");)l.push(e[s]),s+=1;t.push(`<pre><code>${E(l.join(`
|
|
3
|
-
`))}</code></pre>`);continue}const n=R(e,s);if(n){t.push(n.html),s=n.next-1;continue}i.startsWith("### ")?t.push(`<h4>${y(i.slice(4))}</h4>`):i.startsWith("## ")?t.push(`<h3>${y(i.slice(3))}</h3>`):i.startsWith("# ")?t.push(`<h2>${y(i.slice(2))}</h2>`):i.startsWith("- ")?t.push(`<li>${y(i.slice(2))}</li>`):i.trim()?t.push(`<p>${y(i)}</p>`):t.push("<br>")}return t.join("")}async function U(o,e){var n;const t=o.getReader(),s=new TextDecoder;let i="";for(;;){const{done:l,value:r}=await t.read();if(l){i+=s.decode();break}i+=s.decode(r,{stream:!0});const d=i.split(/\r?\n\r?\n/);i=(n=d.pop())!=null?n:"";for(const g of d)P(g,e)}i.trim()&&P(i,e)}function P(o,e){var i,n;const t=(i=o.match(/^event:\s*(.+)$/m))==null?void 0:i[1],s=(n=o.match(/^data:\s*(.+)$/m))==null?void 0:n[1];t&&s&&e(t,JSON.parse(s))}class q{constructor(e,t=16){a(this,"queue",[]);a(this,"timer",null);a(this,"drainWaiters",[]);this.onChunk=e,this.interval=t}enqueue(e){this.queue.push(...Array.from(e)),this.timer||this.tick()}async drain(){!this.timer&&!this.queue.length||await new Promise(e=>this.drainWaiters.push(e))}clear(){this.timer&&clearTimeout(this.timer),this.timer=null,this.queue=[],this.resolveDrainWaiters()}tick(){const e=Math.max(1,Math.ceil(this.queue.length/90)),t=this.queue.splice(0,e).join("");if(t&&this.onChunk(t),!this.queue.length){this.timer=null,this.resolveDrainWaiters();return}this.timer=setTimeout(()=>this.tick(),this.interval)}resolveDrainWaiters(){for(const e of this.drainWaiters.splice(0))e()}}const $=[{value:"product",label:"产品"},{value:"business",label:"业务"},{value:"developer",label:"研发"},{value:"tester",label:"测试"}];class K{constructor(){a(this,"client",null);a(this,"options",null);a(this,"root",null);a(this,"panel",null);a(this,"context",null);a(this,"contextKey","");a(this,"selectedPageKey","");a(this,"currentThread",null);a(this,"conversations",[]);a(this,"messages",[]);a(this,"steps",[]);a(this,"sourceSnapshots",[]);a(this,"sourceUploadStatus","");a(this,"sourceUploadError","");a(this,"sourceUploading",!1);a(this,"sourceRefreshTimer",null);a(this,"streaming","");a(this,"asking",!1);a(this,"waitingForFirstContent",!1);a(this,"abortController",null);a(this,"activeRunId",0);a(this,"stoppedRunId",-1);a(this,"answerStopped",!1);a(this,"answerError","");a(this,"conversationError","");a(this,"deletingThreadId","");a(this,"streamFailure","");a(this,"streamDone",null);a(this,"answerAudience","business");a(this,"audienceChanging",!1);a(this,"typewriter",new q(e=>{this.streaming+=e,this.updateStreamingMessage()}))}mount(e){var t;this.unmount(),this.options=e,this.client=new u(e),this.answerAudience=this.loadAnswerAudience(e.appId),this.root=document.createElement("div"),this.root.className="pageops-sdk",((t=e.container)!=null?t:document.body).appendChild(this.root),this.renderClosed()}unmount(){var e;this.stopSourceRefresh(),this.cancelActiveAnswer(!1),this.resetAnswerState(),(e=this.root)==null||e.remove(),this.root=null,this.panel=null,this.context=null,this.contextKey="",this.selectedPageKey="",this.currentThread=null,this.conversations=[],this.messages=[],this.steps=[],this.sourceSnapshots=[],this.sourceUploadStatus="",this.sourceUploadError="",this.sourceUploading=!1,this.answerAudience="business",this.audienceChanging=!1}open(){this.root&&(this.root.innerHTML="",this.panel=document.createElement("div"),this.panel.className="po-panel",this.root.appendChild(this.panel),this.loadSources(),this.loadConversations(),this.renderPanel())}close(){this.stopSourceRefresh(),this.cancelActiveAnswer(!1),this.renderClosed()}updateContext(e){if(!this.options)return;const t=this.options.appId;this.options={...this.options,...e},this.client=new u(this.options),this.options.appId!==t&&(this.answerAudience=this.loadAnswerAudience(this.options.appId),this.currentThread=null,this.selectedPageKey="",this.messages=[],this.steps=[]),this.context=null,this.contextKey="",this.renderPanel()}renderClosed(){var e;this.root&&(this.root.innerHTML='<button class="po-fab" type="button">多轮问答</button>',(e=this.root.querySelector("button"))==null||e.addEventListener("click",()=>this.open()))}async ensureContext(){if(!this.client||!this.options)throw new Error("PageOps SDK 未初始化");const e=this.getPageContext(),t=this.getPageContextKey(e);return this.context&&this.contextKey===t?this.context:(this.context=await this.client.createContext(e),this.contextKey=t,this.context)}getPageContext(){var e,t,s;return{...(s=(t=(e=this.options)==null?void 0:e.getPageContext)==null?void 0:t.call(e))!=null?s:{},userRole:this.answerAudience}}answerAudienceStorageKey(e){return`pageops:answer-audience:${e}`}loadAnswerAudience(e){try{const t=localStorage.getItem(this.answerAudienceStorageKey(e));return $.some(s=>s.value===t)?t:"business"}catch(t){return"business"}}saveAnswerAudience(){if(this.options)try{localStorage.setItem(this.answerAudienceStorageKey(this.options.appId),this.answerAudience)}catch(e){}}async changeAnswerAudience(e){var s;if(this.asking||this.audienceChanging)return;const t=(s=$.find(i=>i.value===e))==null?void 0:s.value;if(!(!t||t===this.answerAudience)){this.answerAudience=t,this.saveAnswerAudience(),this.audienceChanging=!0,this.context=null,this.contextKey="",this.selectedPageKey="",this.currentThread=null,this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.conversationError="",this.renderPanel();try{await this.newConversation()}catch(i){this.conversationError=i instanceof Error?i.message:"切换回答角色失败,请稍后重试。"}finally{this.audienceChanging=!1,this.renderPanel()}}}getPageContextKey(e){var t,s,i,n,l;return JSON.stringify([(t=e.route)!=null?t:"",(s=e.url)!=null?s:location.href,(i=e.title)!=null?i:document.title,(n=e.menuPath)!=null?n:[],(l=e.userRole)!=null?l:""])}async loadSources(){if(this.client){try{this.sourceSnapshots=await this.client.listSources(),this.sourceUploadError=""}catch(e){this.sourceUploadError=e instanceof Error?e.message:"源码包状态加载失败"}this.scheduleSourceRefresh(),this.renderPanel()}}async loadConversations(){this.client&&(this.conversations=await this.client.listConversations(),this.renderPanel())}async newConversation(){var s;if(!this.client)return;const e=await this.ensureContext(),t=(s=e.menu_path)!=null&&s.length?e.menu_path.join(" / "):e.route||document.title||"新的问答";this.currentThread=await this.client.createConversation(e.id,t),this.selectedPageKey=this.contextKey,this.conversations=[this.currentThread,...this.conversations],this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.renderPanel()}async selectThread(e){this.client&&(this.currentThread=e,this.selectedPageKey=this.getPageContextKey(this.getPageContext()),this.messages=await this.client.listMessages(e.id),this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.renderPanel())}async deleteConversation(e){var t;if(!(!this.client||this.asking||this.deletingThreadId)&&window.confirm(`确定删除会话“${e.title}”吗?此操作无法撤销。`)){this.deletingThreadId=e.id,this.conversationError="",this.renderPanel();try{if(await this.client.deleteConversation(e.id),this.conversations=this.conversations.filter(s=>s.id!==e.id),((t=this.currentThread)==null?void 0:t.id)===e.id){this.currentThread=null,this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1;const s=this.conversations[0];s&&await this.selectThread(s)}}catch(s){this.conversationError=s instanceof Error?s.message:"删除问答会话失败"}finally{this.deletingThreadId="",this.renderPanel()}}}async uploadSource(e){if(this.client){this.sourceUploading=!0,this.sourceUploadStatus="上传中...",this.sourceUploadError="",this.renderPanel();try{await this.client.uploadSource(e),this.sourceSnapshots=await this.client.listSources(),this.sourceUploadStatus=this.isProjectMemoryUpdating()?"源码上传完成,项目记忆更新中...":"上传完成",this.scheduleSourceRefresh()}catch(t){this.sourceUploadError=t instanceof Error?t.message:"源码包上传失败",this.sourceUploadStatus=""}finally{this.sourceUploading=!1,this.renderPanel()}}}async ask(e){if(!this.client||this.asking)return;const t=this.questionUnavailableReason();if(t){this.sourceUploadError=t,this.renderPanel();return}this.resetAnswerState();const s=++this.activeRunId,i=new AbortController;this.abortController=i,this.stoppedRunId=-1,this.asking=!0,this.waitingForFirstContent=!0,this.renderPanel();try{const n=this.getPageContextKey(this.getPageContext());if(this.currentThread&&this.selectedPageKey&&this.selectedPageKey!==n&&(this.currentThread=null),this.currentThread||await this.newConversation(),!this.currentThread)throw new Error("无法创建问答会话,请稍后重试。");this.messages.push({id:`local-${Date.now()}`,role:"user",content:e,metadata_json:{}}),this.steps=[],this.renderPanel();const l=await this.client.streamQuestion(this.currentThread.id,e,i.signal);if(!l.ok)throw new Error(await w(l,"服务暂时无法回答,请稍后重试。"));if(!l.body)throw new Error("服务未返回有效的流式响应,请稍后重试。");if(await U(l.body,(r,d)=>this.handleStreamEvent(r,d)),s===this.stoppedRunId)throw new DOMException("输出已停止","AbortError");if(this.streamFailure)throw new Error(this.streamFailure);if(!this.streamDone)throw new Error("服务响应意外中断,请稍后重试。");if(await this.typewriter.drain(),s===this.stoppedRunId)throw new DOMException("输出已停止","AbortError");await this.selectThread(this.currentThread)}catch(n){if(s!==this.activeRunId)return;this.typewriter.clear(),this.waitingForFirstContent=!1,s===this.stoppedRunId?this.answerStopped=!0:(this.answerError=n instanceof Error?n.message:"服务异常,请稍后重试。",this.upsertStep({id:"error",title:"执行失败",status:"failed",details:{message:this.answerError}}))}finally{if(s!==this.activeRunId)return;this.asking=!1,this.waitingForFirstContent=!1,this.abortController===i&&(this.abortController=null),this.renderPanel(!0)}}cancelActiveAnswer(e){var t;if(!(!this.asking&&!this.abortController)){if(e){this.stoppedRunId=this.activeRunId,this.answerStopped=!0;const s=this.steps.map(i=>i.status==="running"?{...i,status:"cancelled"}:i);this.steps=s.some(i=>i.status==="cancelled")?s:[...s,{id:"stopped",title:"已停止",status:"cancelled"}]}else this.activeRunId+=1,this.asking=!1;this.typewriter.clear(),this.waitingForFirstContent=!1,(t=this.abortController)==null||t.abort(),this.abortController=null,e&&this.renderPanel()}}handleStreamEvent(e,t){var s,i;if(e==="step"){this.upsertStep(t),this.renderPanel();return}if(e==="delta"){const n=String((s=t.content)!=null?s:"");if(!n)return;this.waitingForFirstContent=!1,this.typewriter.enqueue(n);return}e==="done"&&(this.streamDone=t),e==="error"&&(this.streamFailure=String((i=t.message)!=null?i:"服务异常,请稍后重试。"))}updateStreamingMessage(){var s,i;const e=(s=this.panel)==null?void 0:s.querySelector("[data-streaming-content]");if(!e){this.renderPanel();return}e.innerHTML=S(this.streaming);const t=(i=this.panel)==null?void 0:i.querySelector(".po-messages");t&&(t.scrollTop=t.scrollHeight)}resetAnswerState(){this.typewriter.clear(),this.asking=!1,this.waitingForFirstContent=!1,this.answerError="",this.answerStopped=!1,this.streamFailure="",this.streamDone=null,this.streaming=""}upsertStep(e){const t=this.steps.findIndex(s=>s.id===e.id);this.steps=t===-1?[...this.steps,e]:this.steps.map(s=>s.id===e.id?{...s,...e}:s)}latestAnalysisStatus(){var e,t,s;return String((s=(t=(e=this.sourceSnapshots[0])==null?void 0:e.metadata)==null?void 0:t.analysis_status)!=null?s:"")}isProjectMemoryUpdating(){return["pending","running"].includes(this.latestAnalysisStatus())}questionUnavailableReason(){return this.sourceSnapshots.length?this.isProjectMemoryUpdating()?"项目记忆正在更新,完成前暂不能问答。":this.latestAnalysisStatus()==="failed"?"项目记忆更新失败,请重新上传或重新索引。":"":"请先上传代码包后再提问。"}scheduleSourceRefresh(){this.stopSourceRefresh(),this.isProjectMemoryUpdating()&&(this.sourceRefreshTimer=setTimeout(()=>void this.loadSources(),1500))}stopSourceRefresh(){this.sourceRefreshTimer&&clearTimeout(this.sourceRefreshTimer),this.sourceRefreshTimer=null}renderPanel(e=this.asking){if(!this.panel)return;const t=this.questionUnavailableReason(),s=t||(this.asking?"回答生成中,请稍候":"请输入页面分析问题,Enter 发送,Shift + Enter 换行"),i=!!(t||this.asking),n=t?'<button type="submit" disabled>暂不可提问</button>':this.asking?'<button class="po-stop" type="button" data-action="stop-answer" aria-label="停止输出" title="停止输出"><span aria-hidden="true"></span></button>':'<button type="submit">发送</button>',l=$.map(r=>`
|
|
3
|
+
`))}</code></pre>`);continue}const n=R(e,s);if(n){t.push(n.html),s=n.next-1;continue}i.startsWith("### ")?t.push(`<h4>${y(i.slice(4))}</h4>`):i.startsWith("## ")?t.push(`<h3>${y(i.slice(3))}</h3>`):i.startsWith("# ")?t.push(`<h2>${y(i.slice(2))}</h2>`):i.startsWith("- ")?t.push(`<li>${y(i.slice(2))}</li>`):i.trim()?t.push(`<p>${y(i)}</p>`):t.push("<br>")}return t.join("")}async function q(o,e){var n;const t=o.getReader(),s=new TextDecoder;let i="";for(;;){const{done:l,value:r}=await t.read();if(l){i+=s.decode();break}i+=s.decode(r,{stream:!0});const d=i.split(/\r?\n\r?\n/);i=(n=d.pop())!=null?n:"";for(const g of d)P(g,e)}i.trim()&&P(i,e)}function P(o,e){var i,n;const t=(i=o.match(/^event:\s*(.+)$/m))==null?void 0:i[1],s=(n=o.match(/^data:\s*(.+)$/m))==null?void 0:n[1];t&&s&&e(t,JSON.parse(s))}class U{constructor(e,t=16){a(this,"queue",[]);a(this,"timer",null);a(this,"drainWaiters",[]);this.onChunk=e,this.interval=t}enqueue(e){this.queue.push(...Array.from(e)),this.timer||this.tick()}async drain(){!this.timer&&!this.queue.length||await new Promise(e=>this.drainWaiters.push(e))}clear(){this.timer&&clearTimeout(this.timer),this.timer=null,this.queue=[],this.resolveDrainWaiters()}tick(){const e=Math.max(1,Math.ceil(this.queue.length/90)),t=this.queue.splice(0,e).join("");if(t&&this.onChunk(t),!this.queue.length){this.timer=null,this.resolveDrainWaiters();return}this.timer=setTimeout(()=>this.tick(),this.interval)}resolveDrainWaiters(){for(const e of this.drainWaiters.splice(0))e()}}const $=[{value:"product",label:"产品"},{value:"business",label:"业务"},{value:"developer",label:"研发"},{value:"tester",label:"测试"}];class K{constructor(){a(this,"client",null);a(this,"options",null);a(this,"root",null);a(this,"panel",null);a(this,"context",null);a(this,"contextKey","");a(this,"selectedPageKey","");a(this,"currentThread",null);a(this,"conversations",[]);a(this,"messages",[]);a(this,"steps",[]);a(this,"sourceSnapshots",[]);a(this,"sourceUploadStatus","");a(this,"sourceUploadError","");a(this,"sourceLoadError","");a(this,"sourceUploading",!1);a(this,"sourceRefreshTimer",null);a(this,"streaming","");a(this,"asking",!1);a(this,"waitingForFirstContent",!1);a(this,"abortController",null);a(this,"activeRunId",0);a(this,"stoppedRunId",-1);a(this,"answerStopped",!1);a(this,"answerError","");a(this,"conversationError","");a(this,"deletingThreadId","");a(this,"streamFailure","");a(this,"streamDone",null);a(this,"answerAudience","business");a(this,"audienceChanging",!1);a(this,"typewriter",new U(e=>{this.streaming+=e,this.updateStreamingMessage()}))}mount(e){var t;this.unmount(),this.options=e,this.client=new u(e),this.answerAudience=this.loadAnswerAudience(e.appId),this.root=document.createElement("div"),this.root.className="pageops-sdk",((t=e.container)!=null?t:document.body).appendChild(this.root),this.renderClosed()}unmount(){var e;this.stopSourceRefresh(),this.cancelActiveAnswer(!1),this.resetAnswerState(),(e=this.root)==null||e.remove(),this.root=null,this.panel=null,this.context=null,this.contextKey="",this.selectedPageKey="",this.currentThread=null,this.conversations=[],this.messages=[],this.steps=[],this.sourceSnapshots=[],this.sourceUploadStatus="",this.sourceUploadError="",this.sourceLoadError="",this.sourceUploading=!1,this.answerAudience="business",this.audienceChanging=!1}open(){this.root&&(this.root.innerHTML="",this.panel=document.createElement("div"),this.panel.className="po-panel",this.root.appendChild(this.panel),this.loadSources(),this.loadConversations(),this.renderPanel())}close(){this.stopSourceRefresh(),this.cancelActiveAnswer(!1),this.renderClosed()}updateContext(e){if(!this.options)return;const t=this.options.appId;this.options={...this.options,...e},this.client=new u(this.options),this.options.appId!==t&&(this.answerAudience=this.loadAnswerAudience(this.options.appId),this.currentThread=null,this.selectedPageKey="",this.messages=[],this.steps=[]),this.context=null,this.contextKey="",this.renderPanel()}renderClosed(){var e;this.root&&(this.root.innerHTML='<button class="po-fab" type="button">多轮问答</button>',(e=this.root.querySelector("button"))==null||e.addEventListener("click",()=>this.open()))}async ensureContext(){if(!this.client||!this.options)throw new Error("PageOps SDK 未初始化");const e=this.getPageContext(),t=this.getPageContextKey(e);return this.context&&this.contextKey===t?this.context:(this.context=await this.client.createContext(e),this.contextKey=t,this.context)}getPageContext(){var e,t,s;return{...(s=(t=(e=this.options)==null?void 0:e.getPageContext)==null?void 0:t.call(e))!=null?s:{},userRole:this.answerAudience}}answerAudienceStorageKey(e){return`pageops:answer-audience:${e}`}loadAnswerAudience(e){try{const t=localStorage.getItem(this.answerAudienceStorageKey(e));return $.some(s=>s.value===t)?t:"business"}catch(t){return"business"}}saveAnswerAudience(){if(this.options)try{localStorage.setItem(this.answerAudienceStorageKey(this.options.appId),this.answerAudience)}catch(e){}}async changeAnswerAudience(e){var s;if(this.asking||this.audienceChanging)return;const t=(s=$.find(i=>i.value===e))==null?void 0:s.value;if(!(!t||t===this.answerAudience)){this.answerAudience=t,this.saveAnswerAudience(),this.audienceChanging=!0,this.context=null,this.contextKey="",this.selectedPageKey="",this.currentThread=null,this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.conversationError="",this.renderPanel();try{await this.newConversation()}catch(i){this.conversationError=i instanceof Error?i.message:"切换回答角色失败,请稍后重试。"}finally{this.audienceChanging=!1,this.renderPanel()}}}getPageContextKey(e){var t,s,i,n,l;return JSON.stringify([(t=e.route)!=null?t:"",(s=e.url)!=null?s:location.href,(i=e.title)!=null?i:document.title,(n=e.menuPath)!=null?n:[],(l=e.userRole)!=null?l:""])}async loadSources(){if(this.client){try{this.sourceSnapshots=await this.client.listSources(),this.sourceLoadError=""}catch(e){this.sourceLoadError="源码包状态加载失败,连接恢复后将自动重试。"}this.scheduleSourceRefresh(),this.renderPanel()}}async loadConversations(){this.client&&(this.conversations=await this.client.listConversations(),this.renderPanel())}async newConversation(){var s;if(!this.client)return;const e=await this.ensureContext(),t=(s=e.menu_path)!=null&&s.length?e.menu_path.join(" / "):e.route||document.title||"新的问答";this.currentThread=await this.client.createConversation(e.id,t),this.selectedPageKey=this.contextKey,this.conversations=[this.currentThread,...this.conversations],this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.renderPanel()}async selectThread(e){this.client&&(this.currentThread=e,this.selectedPageKey=this.getPageContextKey(this.getPageContext()),this.messages=await this.client.listMessages(e.id),this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1,this.renderPanel())}async deleteConversation(e){var t;if(!(!this.client||this.asking||this.deletingThreadId)&&window.confirm(`确定删除会话“${e.title}”吗?此操作无法撤销。`)){this.deletingThreadId=e.id,this.conversationError="",this.renderPanel();try{if(await this.client.deleteConversation(e.id),this.conversations=this.conversations.filter(s=>s.id!==e.id),((t=this.currentThread)==null?void 0:t.id)===e.id){this.currentThread=null,this.messages=[],this.steps=[],this.streaming="",this.answerError="",this.answerStopped=!1;const s=this.conversations[0];s&&await this.selectThread(s)}}catch(s){this.conversationError=s instanceof Error?s.message:"删除问答会话失败"}finally{this.deletingThreadId="",this.renderPanel()}}}async uploadSource(e){if(this.client){this.sourceUploading=!0,this.sourceUploadStatus="上传中...",this.sourceUploadError="",this.renderPanel();try{await this.client.uploadSource(e),this.sourceSnapshots=await this.client.listSources(),this.sourceUploadStatus=this.isProjectMemoryUpdating()?"源码上传完成,项目记忆更新中...":"上传完成",this.scheduleSourceRefresh()}catch(t){this.sourceUploadError=t instanceof Error?t.message:"源码包上传失败",this.sourceUploadStatus=""}finally{this.sourceUploading=!1,this.renderPanel()}}}async ask(e){if(!this.client||this.asking)return;const t=this.questionUnavailableReason();if(t){this.sourceUploadError=t,this.renderPanel();return}this.resetAnswerState();const s=++this.activeRunId,i=new AbortController;this.abortController=i,this.stoppedRunId=-1,this.asking=!0,this.waitingForFirstContent=!0,this.renderPanel();try{const n=this.getPageContextKey(this.getPageContext());if(this.currentThread&&this.selectedPageKey&&this.selectedPageKey!==n&&(this.currentThread=null),this.currentThread||await this.newConversation(),!this.currentThread)throw new Error("无法创建问答会话,请稍后重试。");this.messages.push({id:`local-${Date.now()}`,role:"user",content:e,metadata_json:{}}),this.steps=[],this.renderPanel();const l=await this.client.streamQuestion(this.currentThread.id,e,i.signal);if(!l.ok)throw new Error(await w(l,"服务暂时无法回答,请稍后重试。"));if(!l.body)throw new Error("服务未返回有效的流式响应,请稍后重试。");if(await q(l.body,(r,d)=>this.handleStreamEvent(r,d)),s===this.stoppedRunId)throw new DOMException("输出已停止","AbortError");if(this.streamFailure)throw new Error(this.streamFailure);if(!this.streamDone)throw new Error("服务响应意外中断,请稍后重试。");if(await this.typewriter.drain(),s===this.stoppedRunId)throw new DOMException("输出已停止","AbortError");await this.selectThread(this.currentThread)}catch(n){if(s!==this.activeRunId)return;this.typewriter.clear(),this.waitingForFirstContent=!1,s===this.stoppedRunId?this.answerStopped=!0:(this.answerError=n instanceof Error?n.message:"服务异常,请稍后重试。",this.upsertStep({id:"error",title:"执行失败",status:"failed",details:{message:this.answerError}}))}finally{if(s!==this.activeRunId)return;this.asking=!1,this.waitingForFirstContent=!1,this.abortController===i&&(this.abortController=null),this.renderPanel(!0)}}cancelActiveAnswer(e){var t;if(!(!this.asking&&!this.abortController)){if(e){this.stoppedRunId=this.activeRunId,this.answerStopped=!0;const s=this.steps.map(i=>i.status==="running"?{...i,status:"cancelled"}:i);this.steps=s.some(i=>i.status==="cancelled")?s:[...s,{id:"stopped",title:"已停止",status:"cancelled"}]}else this.activeRunId+=1,this.asking=!1;this.typewriter.clear(),this.waitingForFirstContent=!1,(t=this.abortController)==null||t.abort(),this.abortController=null,e&&this.renderPanel()}}handleStreamEvent(e,t){var s,i;if(e==="step"){this.upsertStep(t),this.renderPanel();return}if(e==="delta"){const n=String((s=t.content)!=null?s:"");if(!n)return;this.waitingForFirstContent=!1,this.typewriter.enqueue(n);return}e==="done"&&(this.streamDone=t),e==="error"&&(this.streamFailure=String((i=t.message)!=null?i:"服务异常,请稍后重试。"))}updateStreamingMessage(){var s,i;const e=(s=this.panel)==null?void 0:s.querySelector("[data-streaming-content]");if(!e){this.renderPanel();return}e.innerHTML=b(this.streaming);const t=(i=this.panel)==null?void 0:i.querySelector(".po-messages");t&&(t.scrollTop=t.scrollHeight)}resetAnswerState(){this.typewriter.clear(),this.asking=!1,this.waitingForFirstContent=!1,this.answerError="",this.answerStopped=!1,this.streamFailure="",this.streamDone=null,this.streaming=""}upsertStep(e){const t=this.steps.findIndex(s=>s.id===e.id);this.steps=t===-1?[...this.steps,e]:this.steps.map(s=>s.id===e.id?{...s,...e}:s)}latestAnalysisStatus(){var e,t,s;return String((s=(t=(e=this.sourceSnapshots[0])==null?void 0:e.metadata)==null?void 0:t.analysis_status)!=null?s:"")}isProjectMemoryUpdating(){return["pending","running"].includes(this.latestAnalysisStatus())}questionUnavailableReason(){return this.sourceLoadError&&!this.sourceSnapshots.length?"暂时无法读取项目共享代码包,请检查 PageOps 服务连接。":this.sourceSnapshots.length?this.isProjectMemoryUpdating()?"项目记忆正在更新,完成前暂不能问答。":this.latestAnalysisStatus()==="failed"?"项目记忆更新失败,请重新上传或重新索引。":"":"请先上传代码包后再提问。"}scheduleSourceRefresh(){this.stopSourceRefresh(),!(!this.sourceLoadError&&!this.isProjectMemoryUpdating())&&(this.sourceRefreshTimer=setTimeout(()=>void this.loadSources(),1500))}stopSourceRefresh(){this.sourceRefreshTimer&&clearTimeout(this.sourceRefreshTimer),this.sourceRefreshTimer=null}renderPanel(e=this.asking){if(!this.panel)return;const t=this.questionUnavailableReason(),s=t||(this.asking?"回答生成中,请稍候":"请输入页面分析问题,Enter 发送,Shift + Enter 换行"),i=!!(t||this.asking),n=t?'<button type="submit" disabled>暂不可提问</button>':this.asking?'<button class="po-stop" type="button" data-action="stop-answer" aria-label="停止输出" title="停止输出"><span aria-hidden="true"></span></button>':'<button type="submit">发送</button>',l=$.map(r=>`
|
|
4
4
|
<button type="button" data-audience="${r.value}" aria-pressed="${r.value===this.answerAudience}" ${this.asking||this.audienceChanging?"disabled":""}>${r.label}</button>
|
|
5
5
|
`).join("");if(this.panel.innerHTML=`
|
|
6
6
|
<aside class="po-sidebar">
|
|
@@ -19,22 +19,23 @@
|
|
|
19
19
|
<main class="po-chat">
|
|
20
20
|
<header><div class="po-chat-title"><p>问数回答</p><h2>${this.currentThread?c(this.currentThread.title):"未选择问答"}</h2></div><div class="po-audience"><span>回答角色</span><div class="po-audience-options" role="group" aria-label="回答角色">${l}</div></div></header>
|
|
21
21
|
<section class="po-messages">
|
|
22
|
-
${this.messages.map(r=>`<article class="po-message ${r.role}"><b>${r.role==="user"?"你":"PageOps 分析"}</b><div>${r.role==="assistant"?
|
|
22
|
+
${this.messages.map(r=>`<article class="po-message ${r.role}"><b>${r.role==="user"?"你":"PageOps 分析"}</b><div>${r.role==="assistant"?b(r.content):c(r.content)}</div></article>`).join("")}
|
|
23
23
|
${this.renderAnswerState()}
|
|
24
24
|
</section>
|
|
25
25
|
<form class="po-composer"><textarea ${i?"disabled":""} placeholder="${c(s)}"></textarea>${n}</form>
|
|
26
26
|
</main>
|
|
27
27
|
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}${this.renderSteps()}</section></aside>
|
|
28
|
-
`,this.bindPanelEvents(),e){const r=this.panel.querySelector(".po-messages");r&&(r.scrollTop=r.scrollHeight)}}renderAnswerState(){const e=this.asking&&this.waitingForFirstContent?'<article class="po-message assistant waiting" role="status" aria-live="polite"><b>PageOps 分析</b><div class="po-ai-waiting"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在理解问题并检索证据</span></div></article>':"",t=this.streaming?`<article class="po-message assistant streaming"><b>PageOps 分析</b><div><span data-streaming-content>${
|
|
28
|
+
`,this.bindPanelEvents(),e){const r=this.panel.querySelector(".po-messages");r&&(r.scrollTop=r.scrollHeight)}}renderAnswerState(){const e=this.asking&&this.waitingForFirstContent?'<article class="po-message assistant waiting" role="status" aria-live="polite"><b>PageOps 分析</b><div class="po-ai-waiting"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在理解问题并检索证据</span></div></article>':"",t=this.streaming?`<article class="po-message assistant streaming"><b>PageOps 分析</b><div><span data-streaming-content>${b(this.streaming)}</span>${this.asking?'<span class="po-typing-cursor" aria-hidden="true"></span>':""}</div></article>`:"",s=this.answerError?`<article class="po-message assistant answer-error" role="alert"><b>PageOps 分析</b><strong>本次回答失败</strong><div>${c(this.answerError)}</div></article>`:"",i=this.answerStopped?'<div class="po-stream-stopped" role="status">已停止输出</div>':"";return`${e}${t}${i}${s}`}renderSourceUploader(){const e=this.sourceLoadError?"暂时无法读取项目共享代码包,连接恢复后将自动重试。":"当前项目暂无代码包,请先上传后再提问。";return`
|
|
29
29
|
<div class="po-source-uploader">
|
|
30
30
|
<strong>源码包</strong>
|
|
31
|
-
<p
|
|
31
|
+
<p>同一项目的所有回答角色共享代码包。上传 zip、tar、tar.gz 或 tgz 后,PageOps 将基于代码证据回答问题。</p>
|
|
32
32
|
<label class="po-upload-button">
|
|
33
33
|
<span>${this.sourceUploading?"上传中...":"选择代码包"}</span>
|
|
34
34
|
<input type="file" accept=".zip,.tar,.gz,.tgz" data-action="upload-source" ${this.sourceUploading?"disabled":""} />
|
|
35
35
|
</label>
|
|
36
36
|
${this.sourceUploadStatus?`<p class="po-upload-status">${c(this.sourceUploadStatus)}</p>`:""}
|
|
37
|
-
${this.sourceSnapshots.length?`<div class="po-source-list">${this.sourceSnapshots.map(
|
|
37
|
+
${this.sourceSnapshots.length?`<div class="po-source-list">${this.sourceSnapshots.map(t=>this.renderSourceItem(t)).join("")}</div>`:`<p class="po-upload-empty">${e}</p>`}
|
|
38
|
+
${this.sourceLoadError?`<p class="po-upload-error">${c(this.sourceLoadError)}</p>`:""}
|
|
38
39
|
${this.sourceUploadError?`<p class="po-upload-error">${c(this.sourceUploadError)}</p>`:""}
|
|
39
40
|
</div>
|
|
40
|
-
`}renderSourceItem(e){var r,d,g;const t=e.filename||"未命名代码包",s=e.created_at?C(e.created_at):"刚刚上传",i=O(e.archive_bytes||e.total_bytes||0),n=String((d=(r=e.metadata)==null?void 0:r.analysis_status)!=null?d:"unknown"),l=(g={pending:"项目记忆等待更新",running:"项目记忆更新中",ready:"项目记忆已就绪",failed:"项目记忆更新失败"}[n])!=null?g:"项目记忆状态未知";return`<article class="po-source-item"><strong>${c(t)}</strong><span>${c(s)} · ${c(i)}</span><span>${c(l)}</span></article>`}renderSteps(){return(this.steps.length?this.steps:[{id:"idle",title:"等待任务",status:"pending",details:{message:"发送消息后展示执行过程。"}}]).map(t=>{var s;return`<details class="po-step ${t.status}" ${t.status==="running"||t.status==="failed"?"open":""}><summary><strong>${c(t.title)}</strong><span>${F(t.status)}</span></summary><pre>${c(JSON.stringify((s=t.details)!=null?s:{},null,2))}</pre></details>`}).join("")}bindPanelEvents(){var e,t,s,i,n,l,r,d,g,
|
|
41
|
+
`}renderSourceItem(e){var r,d,g;const t=e.filename||"未命名代码包",s=e.created_at?C(e.created_at):"刚刚上传",i=O(e.archive_bytes||e.total_bytes||0),n=String((d=(r=e.metadata)==null?void 0:r.analysis_status)!=null?d:"unknown"),l=(g={pending:"项目记忆等待更新",running:"项目记忆更新中",ready:"项目记忆已就绪",failed:"项目记忆更新失败"}[n])!=null?g:"项目记忆状态未知";return`<article class="po-source-item"><strong>${c(t)}</strong><span>${c(s)} · ${c(i)}</span><span>${c(l)}</span></article>`}renderSteps(){return(this.steps.length?this.steps:[{id:"idle",title:"等待任务",status:"pending",details:{message:"发送消息后展示执行过程。"}}]).map(t=>{var s;return`<details class="po-step ${t.status}" ${t.status==="running"||t.status==="failed"?"open":""}><summary><strong>${c(t.title)}</strong><span>${F(t.status)}</span></summary><pre>${c(JSON.stringify((s=t.details)!=null?s:{},null,2))}</pre></details>`}).join("")}bindPanelEvents(){var e,t,s,i,n,l,r,d,g,S,T,A,I,x,k;(t=(e=this.panel)==null?void 0:e.querySelector('[data-action="new"]'))==null||t.addEventListener("click",()=>void this.newConversation()),(i=(s=this.panel)==null?void 0:s.querySelector('[data-action="close"]'))==null||i.addEventListener("click",()=>this.close()),(l=(n=this.panel)==null?void 0:n.querySelector('[data-action="stop-answer"]'))==null||l.addEventListener("click",()=>this.cancelActiveAnswer(!0)),(r=this.panel)==null||r.querySelectorAll("[data-audience]").forEach(p=>{p.addEventListener("click",()=>{var h;return void this.changeAnswerAudience((h=p.dataset.audience)!=null?h:"")})}),(g=(d=this.panel)==null?void 0:d.querySelector('[data-action="upload-source"]'))==null||g.addEventListener("change",p=>{var f;const h=(f=p.target.files)==null?void 0:f[0];h&&this.uploadSource(h)}),(S=this.panel)==null||S.querySelectorAll("[data-thread]").forEach(p=>{p.addEventListener("click",()=>{const h=this.conversations.find(f=>f.id===p.dataset.thread);h&&this.selectThread(h)})}),(T=this.panel)==null||T.querySelectorAll("[data-delete-thread]").forEach(p=>{p.addEventListener("click",h=>{h.stopPropagation();const f=this.conversations.find(v=>v.id===p.dataset.deleteThread);f&&this.deleteConversation(f)})}),(I=(A=this.panel)==null?void 0:A.querySelector("form"))==null||I.addEventListener("submit",p=>{var v;p.preventDefault();const h=(v=this.panel)==null?void 0:v.querySelector("textarea"),f=h==null?void 0:h.value.trim();f&&(h.value="",this.ask(f))}),(k=(x=this.panel)==null?void 0:x.querySelector("textarea"))==null||k.addEventListener("keydown",p=>{var f,v;const h=p;h.key==="Enter"&&!h.shiftKey&&(h.preventDefault(),(v=(f=this.panel)==null?void 0:f.querySelector("form"))==null||v.requestSubmit())})}}function c(o){return o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function C(o){return new Intl.DateTimeFormat("zh-CN",{timeZone:"Asia/Shanghai",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).format(new Date(o))}function O(o){if(!o)return"0 B";const e=["B","KB","MB","GB"];let t=o,s=0;for(;t>=1024&&s<e.length-1;)t/=1024,s+=1;return`${t>=10||s===0?t.toFixed(0):t.toFixed(1)} ${e[s]}`}function F(o){return{pending:"等待中",running:"执行中",completed:"已完成",failed:"失败",cancelled:"已停止"}[o]}const j=new K;m.PageOpsSDK=j,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
|