@pageops/sdk 0.1.36 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.d.ts +4 -2
- package/dist/pageops-sdk.es.js +46 -47
- package/dist/pageops-sdk.umd.cjs +46 -47
- package/dist/types.d.ts +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,16 @@ controls and conversation presentation behavior directly to the SDK. Version
|
|
|
7
7
|
activity, collapses it when answer text starts, and allows casual chat without
|
|
8
8
|
injecting page/source business context.
|
|
9
9
|
|
|
10
|
+
Version `0.1.37` separates the answer-local `thoughts` stream/history contract
|
|
11
|
+
from the right-side `steps` contract. The middle timeline no longer re-renders
|
|
12
|
+
the execution cards; it receives only selected model decisions and evidence
|
|
13
|
+
activities shaped by the backend thought presenter.
|
|
14
|
+
|
|
15
|
+
Version `0.1.38` hides node progress in the right sidebar and keeps it only
|
|
16
|
+
inside chat answers, including live updates and historical Run selection. The
|
|
17
|
+
sidebar source-package controls remain available; backend step data is retained
|
|
18
|
+
for cancellation and history.
|
|
19
|
+
|
|
10
20
|
`src/index.js` is the readable ESM runtime baseline, `src/styles.css` preserves
|
|
11
21
|
the 0.1.34 styles, and `src/extensions.css` contains the new non-minified style
|
|
12
22
|
rules. `npm run build` synchronizes ESM, UMD, and CSS under `dist/` without
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ declare class PageOpsSDKController {
|
|
|
12
12
|
private conversations;
|
|
13
13
|
private messages;
|
|
14
14
|
private steps;
|
|
15
|
+
private thoughts;
|
|
15
16
|
private selectedAgentRunId;
|
|
16
17
|
private runLoading;
|
|
17
18
|
private runLoadError;
|
|
@@ -73,6 +74,7 @@ declare class PageOpsSDKController {
|
|
|
73
74
|
private updateStreamingMessage;
|
|
74
75
|
private resetAnswerState;
|
|
75
76
|
private upsertStep;
|
|
77
|
+
private upsertThought;
|
|
76
78
|
private loadAgentRun;
|
|
77
79
|
private copyAgentRunId;
|
|
78
80
|
private updateCopyFeedback;
|
|
@@ -87,9 +89,9 @@ declare class PageOpsSDKController {
|
|
|
87
89
|
private renderMessage;
|
|
88
90
|
private renderSourceUploader;
|
|
89
91
|
private renderSourceItem;
|
|
90
|
-
private renderSteps;
|
|
91
92
|
private renderThinkingProcess;
|
|
92
|
-
private
|
|
93
|
+
private renderThinkingSteps;
|
|
94
|
+
private renderThinkingTimeline;
|
|
93
95
|
private bindPanelEvents;
|
|
94
96
|
}
|
|
95
97
|
export declare const PageOpsSDK: PageOpsSDKController;
|
package/dist/pageops-sdk.es.js
CHANGED
|
@@ -192,6 +192,7 @@ class V {
|
|
|
192
192
|
i(this, "conversations", []);
|
|
193
193
|
i(this, "messages", []);
|
|
194
194
|
i(this, "steps", []);
|
|
195
|
+
i(this, "thoughts", []);
|
|
195
196
|
i(this, "selectedAgentRunId", "");
|
|
196
197
|
i(this, "runLoading", !1);
|
|
197
198
|
i(this, "runLoadError", "");
|
|
@@ -232,7 +233,7 @@ class V {
|
|
|
232
233
|
}
|
|
233
234
|
unmount() {
|
|
234
235
|
var e;
|
|
235
|
-
this.cleanupFloatingLauncher(), 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.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
|
|
236
|
+
this.cleanupFloatingLauncher(), 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.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
|
|
236
237
|
}
|
|
237
238
|
open() {
|
|
238
239
|
this.root && (this.cleanupFloatingLauncher(), this.root.innerHTML = "", this.panel = document.createElement("div"), this.panel.className = "po-panel", this.root.appendChild(this.panel), this.loadDeveloperAccess(), this.loadSources(), this.loadConversations(), this.renderPanel());
|
|
@@ -245,7 +246,7 @@ class V {
|
|
|
245
246
|
const t = this.options.appId, s = String(this.options.ownerId || "").trim();
|
|
246
247
|
this.options = { ...this.options, ...e }, this.client = new K(this.options);
|
|
247
248
|
const r = String(this.options.ownerId || "").trim(), n = this.options.appId !== t;
|
|
248
|
-
(n || r !== s) && (n && (this.answerAudience = this.loadAnswerAudience(this.options.appId), this.selectedSourceSnapshotId = null), this.currentThread = null, this.selectedPageKey = "", this.conversations = [], this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = ""), this.context = null, this.contextKey = "", r !== s && this.loadDeveloperAccess(), this.panel && this.loadConversations(), this.renderPanel();
|
|
249
|
+
(n || r !== s) && (n && (this.answerAudience = this.loadAnswerAudience(this.options.appId), this.selectedSourceSnapshotId = null), this.currentThread = null, this.selectedPageKey = "", this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = ""), this.context = null, this.contextKey = "", r !== s && this.loadDeveloperAccess(), this.panel && this.loadConversations(), this.renderPanel();
|
|
249
250
|
}
|
|
250
251
|
renderClosed() {
|
|
251
252
|
var e;
|
|
@@ -367,7 +368,7 @@ class V {
|
|
|
367
368
|
if (this.asking) return;
|
|
368
369
|
const s = e === "" ? null : e;
|
|
369
370
|
if ((this.selectedSourceSnapshotId == null ? "" : String(this.selectedSourceSnapshotId)) === (s == null ? "" : String(s))) return;
|
|
370
|
-
this.selectedSourceSnapshotId = s, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
371
|
+
this.selectedSourceSnapshotId = s, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
371
372
|
}
|
|
372
373
|
sourceSnapshotValue(e) {
|
|
373
374
|
var t, s;
|
|
@@ -382,7 +383,7 @@ class V {
|
|
|
382
383
|
if (this.client) {
|
|
383
384
|
try {
|
|
384
385
|
const e = await this.client.listSources(), t = e[0], s = t ? this.sourceSnapshotValue(t) : null, r = this.context && this.context.source_snapshot_id != null ? String(this.context.source_snapshot_id) : null, n = this.selectedSourceSnapshotId == null && s != null && r !== s && (this.context != null || this.currentThread != null);
|
|
385
|
-
this.sourceSnapshots = e, this.sourceLoadError = "", n && (this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1);
|
|
386
|
+
this.sourceSnapshots = e, this.sourceLoadError = "", n && (this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1);
|
|
386
387
|
} catch (e) {
|
|
387
388
|
this.sourceLoadError = "源码包状态加载失败,连接恢复后将自动重试。";
|
|
388
389
|
}
|
|
@@ -396,11 +397,11 @@ class V {
|
|
|
396
397
|
var s;
|
|
397
398
|
if (!this.client) return;
|
|
398
399
|
const t = await this.ensureContext(), r = e ? conversationTitle(t, e) : (s = t.menu_path) != null && s.length ? t.menu_path.join(" / ") : t.route || document.title || "新的问答";
|
|
399
|
-
this.currentThread = await this.client.createConversation(t.id, r), this.selectedPageKey = this.contextKey, this.conversations = [this.currentThread, ...this.conversations], this.messages = [], this.steps = [], this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
400
|
+
this.currentThread = await this.client.createConversation(t.id, r), this.selectedPageKey = this.contextKey, this.conversations = [this.currentThread, ...this.conversations], this.messages = [], this.steps = [], this.thoughts = [], this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
400
401
|
}
|
|
401
402
|
async selectThread(e) {
|
|
402
403
|
if (!this.client) return;
|
|
403
|
-
this.currentThread = e, this.selectedPageKey = this.getPageContextKey(this.getPageContext()), this.messages = await this.client.listMessages(e.id), this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
404
|
+
this.currentThread = e, this.selectedPageKey = this.getPageContextKey(this.getPageContext()), this.messages = await this.client.listMessages(e.id), this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
404
405
|
const t = [...this.messages].reverse().map(M).find(Boolean);
|
|
405
406
|
t && await this.loadAgentRun(t);
|
|
406
407
|
}
|
|
@@ -410,7 +411,7 @@ class V {
|
|
|
410
411
|
this.deletingThreadId = e.id, this.conversationError = "", this.renderPanel();
|
|
411
412
|
try {
|
|
412
413
|
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) {
|
|
413
|
-
this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1;
|
|
414
|
+
this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1;
|
|
414
415
|
const s = this.conversations[0];
|
|
415
416
|
s && await this.selectThread(s);
|
|
416
417
|
}
|
|
@@ -449,7 +450,7 @@ class V {
|
|
|
449
450
|
try {
|
|
450
451
|
const n = this.getPageContextKey(this.getPageContext());
|
|
451
452
|
if (this.currentThread && this.selectedPageKey && this.selectedPageKey !== n && (this.currentThread = null), this.currentThread || await this.newConversation(e), !this.currentThread) throw new Error("无法创建问答会话,请稍后重试。");
|
|
452
|
-
this.messages.push({ id: `local-${Date.now()}`, role: "user", content: e, metadata_json: {}, created_at: this.activeQuestionStartedAt }), this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.renderPanel();
|
|
453
|
+
this.messages.push({ id: `local-${Date.now()}`, role: "user", content: e, metadata_json: {}, created_at: this.activeQuestionStartedAt }), this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.renderPanel();
|
|
453
454
|
const c = await this.client.streamQuestion(this.currentThread.id, e, this.answerAudience, r.signal);
|
|
454
455
|
if (!c.ok) throw new Error(await z(c, "服务暂时无法回答,请稍后重试。"));
|
|
455
456
|
if (!c.body) throw new Error("服务未返回有效的流式响应,请稍后重试。");
|
|
@@ -478,10 +479,22 @@ class V {
|
|
|
478
479
|
this.typewriter.clear(), this.waitingForFirstContent = !1, (t = this.abortController) == null || t.abort(), this.abortController = null, e && this.renderPanel();
|
|
479
480
|
}
|
|
480
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Consume an SSE event without duplicating node progress in the sidebar.
|
|
484
|
+
* Full steps remain available for cancellation; public thoughts update only
|
|
485
|
+
* the answer-local timeline. This method does not make remote requests.
|
|
486
|
+
* @param {string} e Backend event name.
|
|
487
|
+
* @param {object} t Event payload for steps, thoughts, content or completion.
|
|
488
|
+
* @returns {void}
|
|
489
|
+
*/
|
|
481
490
|
handleStreamEvent(e, t) {
|
|
482
491
|
var s, r;
|
|
483
492
|
if (e === "step") {
|
|
484
|
-
this.upsertStep(t)
|
|
493
|
+
this.upsertStep(t);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
if (e === "thought") {
|
|
497
|
+
this.upsertThought(t), this.renderThinkingTimeline();
|
|
485
498
|
return;
|
|
486
499
|
}
|
|
487
500
|
if (e === "delta") {
|
|
@@ -516,16 +529,20 @@ class V {
|
|
|
516
529
|
const t = this.steps.findIndex((s) => s.id === e.id);
|
|
517
530
|
this.steps = t === -1 ? [...this.steps, e] : this.steps.map((s) => s.id === e.id ? { ...s, ...e } : s);
|
|
518
531
|
}
|
|
532
|
+
upsertThought(e) {
|
|
533
|
+
const t = this.thoughts.findIndex((s) => s.id === e.id);
|
|
534
|
+
this.thoughts = t === -1 ? [...this.thoughts, e] : this.thoughts.map((s) => s.id === e.id ? { ...s, ...e } : s);
|
|
535
|
+
}
|
|
519
536
|
async loadAgentRun(e) {
|
|
520
537
|
if (!(!this.client || !e)) {
|
|
521
538
|
this.selectedAgentRunId = e, this.runLoading = !0, this.runLoadError = "", this.renderPanel();
|
|
522
539
|
try {
|
|
523
540
|
const t = await this.client.getAgentRun(e);
|
|
524
541
|
if (this.selectedAgentRunId !== e) return;
|
|
525
|
-
this.steps = t.steps;
|
|
542
|
+
this.steps = t.steps, this.thoughts = t.thoughts || [];
|
|
526
543
|
} catch (t) {
|
|
527
544
|
if (this.selectedAgentRunId !== e) return;
|
|
528
|
-
this.steps = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
|
|
545
|
+
this.steps = [], this.thoughts = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
|
|
529
546
|
} finally {
|
|
530
547
|
this.selectedAgentRunId === e && (this.runLoading = !1, this.renderPanel());
|
|
531
548
|
}
|
|
@@ -578,7 +595,14 @@ class V {
|
|
|
578
595
|
stopSourceRefresh() {
|
|
579
596
|
this.sourceRefreshTimer && clearTimeout(this.sourceRefreshTimer), this.sourceRefreshTimer = null;
|
|
580
597
|
}
|
|
581
|
-
|
|
598
|
+
/**
|
|
599
|
+
* Recreate the chat shell and source controls while keeping progress in answers.
|
|
600
|
+
* Preserve chat scroll unless following the active answer; bind DOM listeners
|
|
601
|
+
* after replacement. The sidebar contains no node progress or auto-scroll.
|
|
602
|
+
* @param {boolean} e Whether to scroll the chat to its latest message.
|
|
603
|
+
* @returns {void} No-op when the SDK panel is closed; no remote requests.
|
|
604
|
+
*/
|
|
605
|
+
renderPanel(e = this.asking) {
|
|
582
606
|
var g;
|
|
583
607
|
if (!this.panel) return;
|
|
584
608
|
const s = (g = this.panel.querySelector(".po-messages")) == null ? void 0 : g.scrollTop, r = this.questionUnavailableReason(), n = r || (this.asking ? "回答生成中,请稍候" : this.sourceSnapshots.length ? "请输入页面分析问题,Enter 发送,Shift + Enter 换行" : "可直接闲聊;业务问题需先上传代码包"), c = !!(r || this.asking), p = r ? '<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>', m = C.map((o) => `
|
|
@@ -609,7 +633,7 @@ class V {
|
|
|
609
633
|
</section>
|
|
610
634
|
<form class="po-composer"><textarea ${c ? "disabled" : ""} placeholder="${l(n)}"></textarea>${p}</form>
|
|
611
635
|
</main>
|
|
612
|
-
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}
|
|
636
|
+
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}</section></aside>
|
|
613
637
|
`, this.bindPanelEvents(), e) {
|
|
614
638
|
const o = this.panel.querySelector(".po-messages");
|
|
615
639
|
o && (o.scrollTop = o.scrollHeight);
|
|
@@ -617,10 +641,6 @@ class V {
|
|
|
617
641
|
const o = this.panel.querySelector(".po-messages");
|
|
618
642
|
o && (o.scrollTop = s);
|
|
619
643
|
}
|
|
620
|
-
if (t) {
|
|
621
|
-
const o = this.panel.querySelector(".po-trace > section");
|
|
622
|
-
o && (o.scrollTop = o.scrollHeight);
|
|
623
|
-
}
|
|
624
644
|
}
|
|
625
645
|
renderAnswerState() {
|
|
626
646
|
const n = messageTime(this.activeQuestionStartedAt), c = this.renderThinkingProcess(), e = this.asking && this.waitingForFirstContent ? `<article class="po-message assistant waiting" role="status" aria-live="polite">${n}<b>PageOps 分析</b><div class="po-ai-waiting"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在理解问题并检索证据</span></div>${c}</article>` : "", t = this.streaming ? `<article class="po-message assistant streaming">${n}<b>PageOps 分析</b><div><span data-streaming-content>${R(this.streaming)}</span>${this.asking ? '<span class="po-typing-cursor" aria-hidden="true"></span>' : ""}</div>${c}</article>` : "", s = this.answerError ? `<article class="po-message assistant answer-error" role="alert">${n}<b>PageOps 分析</b><strong>本次回答失败</strong><div>${l(this.answerError)}</div></article>` : "", r = this.answerStopped ? '<div class="po-stream-stopped" role="status">已停止输出</div>' : "";
|
|
@@ -674,42 +694,24 @@ class V {
|
|
|
674
694
|
const t = e.filename || "未命名代码包", s = e.created_at ? O(e.created_at) : "刚刚上传", r = G(e.archive_bytes || e.total_bytes || 0), n = String((b = (w = e.metadata) == null ? void 0 : w.analysis_status) != null ? b : "unknown"), c = typeof ((S = e.metadata) == null ? void 0 : S.tag) == "string" ? e.metadata.tag : "", p = typeof (($ = e.metadata) == null ? void 0 : $.branch) == "string" ? e.metadata.branch : "", m = c ? `Tag: ${c}` : p ? `Branch: ${p}` : "未记录代码引用", g = typeof ((E = e.metadata) == null ? void 0 : E.remark) == "string" && e.metadata.remark ? e.metadata.remark : "无备注", o = typeof ((A = e.metadata) == null ? void 0 : A.uploader) == "string" ? e.metadata.uploader : "未知用户", y = (T = { pending: "项目记忆等待更新", running: "项目记忆更新中", ready: "项目记忆已就绪", failed: "项目记忆更新失败" }[n]) != null ? T : "项目记忆状态未知";
|
|
675
695
|
return `<article class="po-source-item ${this.selectedSourceSnapshotId != null && this.sourceSnapshotValue(e) === String(this.selectedSourceSnapshotId) || this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "selected" : ""}"><strong>${l(t)}</strong><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)} · 当前问答${this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "默认" : ""}引用</span></article>`;
|
|
676
696
|
}
|
|
677
|
-
renderSteps() {
|
|
678
|
-
return this.runLoading ? '<div class="po-trace-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复本次执行过程</span></div>' : this.runLoadError ? `<div class="po-trace-state failed" role="alert">${l(this.runLoadError)}</div>` : (this.steps.length ? this.steps : [{ id: "idle", title: "等待任务", status: "pending", summary: "发送问题后,这里会展示完整分析过程。" }]).map((t) => {
|
|
679
|
-
var c, p, m;
|
|
680
|
-
const s = (c = t.metrics) != null && c.length ? `<div class="po-step-metrics">${t.metrics.map((g) => `<span>${l(g)}</span>`).join("")}</div>` : "", r = (p = t.details) != null && p.length ? `<div class="po-step-details">${t.details.map((g) => `<div><span>${l(g.label)}</span><p>${l(g.value)}</p></div>`).join("")}</div>` : "", n = !!(s || r);
|
|
681
|
-
return `<details class="po-step ${t.status}" ${t.status === "running" || t.status === "failed" ? "open" : ""} ${n ? "" : "data-static"}>
|
|
682
|
-
<summary>
|
|
683
|
-
<span class="po-step-dot" aria-hidden="true"></span>
|
|
684
|
-
<span class="po-step-copy"><strong>${l(t.title)}</strong><small>${l((m = t.summary) != null ? m : "")}</small>${s}</span>
|
|
685
|
-
<span class="po-step-status">${Z(t.status)}</span>
|
|
686
|
-
</summary>
|
|
687
|
-
${r}
|
|
688
|
-
</details>`;
|
|
689
|
-
}).join("");
|
|
690
|
-
}
|
|
691
697
|
renderThinkingProcess() {
|
|
692
|
-
if (!this.asking && !this.
|
|
693
|
-
const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.
|
|
698
|
+
if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
|
|
699
|
+
const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.thoughts, this.activeQuestionStartedAt);
|
|
694
700
|
return `<details class="po-thinking-process" ${e ? "open" : ""}><summary><strong>${s ? `用时 ${l(s)}` : "思考过程"}</strong><span>${t}</span></summary><div class="po-thinking-content">${this.renderThinkingSteps()}</div></details>`;
|
|
695
701
|
}
|
|
696
702
|
renderThinkingSteps() {
|
|
697
703
|
if (this.runLoading) return '<div class="po-thinking-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复思考过程</span></div>';
|
|
698
704
|
if (this.runLoadError) return `<div class="po-thinking-state failed">${l(this.runLoadError)}</div>`;
|
|
699
|
-
const e = this.
|
|
705
|
+
const e = this.thoughts.length ? this.thoughts : [{ id: "idle", kind: "thinking", label: "理解问题", status: "running", text: "正在判断问题并规划需要核对的信息。" }];
|
|
700
706
|
return e.map((t) => {
|
|
701
|
-
const s = String(t.kind ||
|
|
702
|
-
if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.
|
|
703
|
-
return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.
|
|
707
|
+
const s = String(t.kind || "thinking"), r = thinkingIcon(s), n = (t.metrics || []).length ? `<span class="po-thinking-metrics">${t.metrics.map((c) => l(c)).join(" · ")}</span>` : "", p = (t.details || []).map((c) => `<div class="po-thinking-detail"><span>${l(c.label)}</span>${String(c.value || "").split("\n").filter(Boolean).map((m) => `<code>${l(m)}</code>`).join("")}</div>`).join("");
|
|
708
|
+
if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.label)}</strong><p>${l(t.text || "")}</p>${n}</div></div>`;
|
|
709
|
+
return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.label)}</strong><span>${l(t.text || "")}</span>${n}${p}</div></div>`;
|
|
704
710
|
}).join("");
|
|
705
711
|
}
|
|
706
|
-
|
|
707
|
-
var
|
|
708
|
-
|
|
709
|
-
if (t && (t.innerHTML = this.renderSteps(), this.panel == null || this.panel.querySelectorAll(".po-thinking-content").forEach((n) => n.innerHTML = this.renderThinkingSteps()), e)) {
|
|
710
|
-
const n = (r = this.panel) == null ? void 0 : r.querySelector(".po-trace > section");
|
|
711
|
-
n && (n.scrollTop = n.scrollHeight);
|
|
712
|
-
}
|
|
712
|
+
renderThinkingTimeline() {
|
|
713
|
+
var e;
|
|
714
|
+
(e = this.panel) == null || e.querySelectorAll(".po-thinking-content").forEach((t) => t.innerHTML = this.renderThinkingSteps());
|
|
713
715
|
}
|
|
714
716
|
bindPanelEvents() {
|
|
715
717
|
var e, t, s, r, n, c, p, m, g, o, y, w, b, S, $, E, A, T, h, d;
|
|
@@ -829,9 +831,6 @@ function G(a) {
|
|
|
829
831
|
t /= 1024, s += 1;
|
|
830
832
|
return `${t >= 10 || s === 0 ? t.toFixed(0) : t.toFixed(1)} ${e[s]}`;
|
|
831
833
|
}
|
|
832
|
-
function Z(a) {
|
|
833
|
-
return { pending: "等待中", running: "执行中", completed: "已完成", failed: "失败", cancelled: "已停止" }[a];
|
|
834
|
-
}
|
|
835
834
|
const Y = new V();
|
|
836
835
|
export {
|
|
837
836
|
Y as PageOpsSDK
|
package/dist/pageops-sdk.umd.cjs
CHANGED
|
@@ -192,6 +192,7 @@ class V {
|
|
|
192
192
|
i(this, "conversations", []);
|
|
193
193
|
i(this, "messages", []);
|
|
194
194
|
i(this, "steps", []);
|
|
195
|
+
i(this, "thoughts", []);
|
|
195
196
|
i(this, "selectedAgentRunId", "");
|
|
196
197
|
i(this, "runLoading", !1);
|
|
197
198
|
i(this, "runLoadError", "");
|
|
@@ -232,7 +233,7 @@ class V {
|
|
|
232
233
|
}
|
|
233
234
|
unmount() {
|
|
234
235
|
var e;
|
|
235
|
-
this.cleanupFloatingLauncher(), 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.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
|
|
236
|
+
this.cleanupFloatingLauncher(), 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.thoughts = [], this.selectedAgentRunId = "", this.runLoading = !1, this.runLoadError = "", this.clearCopyFeedback(), this.sourceSnapshots = [], this.selectedSourceSnapshotId = null, this.sourceUploadStatus = "", this.sourceUploadProgress = null, this.sourceUploadError = "", this.sourceLoadError = "", this.sourceUploading = !1, this.developerAccess = !1, this.activeQuestionStartedAt = "", this.answerAudience = "developer";
|
|
236
237
|
}
|
|
237
238
|
open() {
|
|
238
239
|
this.root && (this.cleanupFloatingLauncher(), this.root.innerHTML = "", this.panel = document.createElement("div"), this.panel.className = "po-panel", this.root.appendChild(this.panel), this.loadDeveloperAccess(), this.loadSources(), this.loadConversations(), this.renderPanel());
|
|
@@ -245,7 +246,7 @@ class V {
|
|
|
245
246
|
const t = this.options.appId, s = String(this.options.ownerId || "").trim();
|
|
246
247
|
this.options = { ...this.options, ...e }, this.client = new K(this.options);
|
|
247
248
|
const r = String(this.options.ownerId || "").trim(), n = this.options.appId !== t;
|
|
248
|
-
(n || r !== s) && (n && (this.answerAudience = this.loadAnswerAudience(this.options.appId), this.selectedSourceSnapshotId = null), this.currentThread = null, this.selectedPageKey = "", this.conversations = [], this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = ""), this.context = null, this.contextKey = "", r !== s && this.loadDeveloperAccess(), this.panel && this.loadConversations(), this.renderPanel();
|
|
249
|
+
(n || r !== s) && (n && (this.answerAudience = this.loadAnswerAudience(this.options.appId), this.selectedSourceSnapshotId = null), this.currentThread = null, this.selectedPageKey = "", this.conversations = [], this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = ""), this.context = null, this.contextKey = "", r !== s && this.loadDeveloperAccess(), this.panel && this.loadConversations(), this.renderPanel();
|
|
249
250
|
}
|
|
250
251
|
renderClosed() {
|
|
251
252
|
var e;
|
|
@@ -367,7 +368,7 @@ class V {
|
|
|
367
368
|
if (this.asking) return;
|
|
368
369
|
const s = e === "" ? null : e;
|
|
369
370
|
if ((this.selectedSourceSnapshotId == null ? "" : String(this.selectedSourceSnapshotId)) === (s == null ? "" : String(s))) return;
|
|
370
|
-
this.selectedSourceSnapshotId = s, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
371
|
+
this.selectedSourceSnapshotId = s, this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
371
372
|
}
|
|
372
373
|
sourceSnapshotValue(e) {
|
|
373
374
|
var t, s;
|
|
@@ -382,7 +383,7 @@ class V {
|
|
|
382
383
|
if (this.client) {
|
|
383
384
|
try {
|
|
384
385
|
const e = await this.client.listSources(), t = e[0], s = t ? this.sourceSnapshotValue(t) : null, r = this.context && this.context.source_snapshot_id != null ? String(this.context.source_snapshot_id) : null, n = this.selectedSourceSnapshotId == null && s != null && r !== s && (this.context != null || this.currentThread != null);
|
|
385
|
-
this.sourceSnapshots = e, this.sourceLoadError = "", n && (this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1);
|
|
386
|
+
this.sourceSnapshots = e, this.sourceLoadError = "", n && (this.context = null, this.contextKey = "", this.selectedPageKey = "", this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1);
|
|
386
387
|
} catch (e) {
|
|
387
388
|
this.sourceLoadError = "源码包状态加载失败,连接恢复后将自动重试。";
|
|
388
389
|
}
|
|
@@ -396,11 +397,11 @@ class V {
|
|
|
396
397
|
var s;
|
|
397
398
|
if (!this.client) return;
|
|
398
399
|
const t = await this.ensureContext(), r = e ? conversationTitle(t, e) : (s = t.menu_path) != null && s.length ? t.menu_path.join(" / ") : t.route || document.title || "新的问答";
|
|
399
|
-
this.currentThread = await this.client.createConversation(t.id, r), this.selectedPageKey = this.contextKey, this.conversations = [this.currentThread, ...this.conversations], this.messages = [], this.steps = [], this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
400
|
+
this.currentThread = await this.client.createConversation(t.id, r), this.selectedPageKey = this.contextKey, this.conversations = [this.currentThread, ...this.conversations], this.messages = [], this.steps = [], this.thoughts = [], this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
400
401
|
}
|
|
401
402
|
async selectThread(e) {
|
|
402
403
|
if (!this.client) return;
|
|
403
|
-
this.currentThread = e, this.selectedPageKey = this.getPageContextKey(this.getPageContext()), this.messages = await this.client.listMessages(e.id), this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
404
|
+
this.currentThread = e, this.selectedPageKey = this.getPageContextKey(this.getPageContext()), this.messages = await this.client.listMessages(e.id), this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1, this.renderPanel();
|
|
404
405
|
const t = [...this.messages].reverse().map(M).find(Boolean);
|
|
405
406
|
t && await this.loadAgentRun(t);
|
|
406
407
|
}
|
|
@@ -410,7 +411,7 @@ class V {
|
|
|
410
411
|
this.deletingThreadId = e.id, this.conversationError = "", this.renderPanel();
|
|
411
412
|
try {
|
|
412
413
|
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) {
|
|
413
|
-
this.currentThread = null, this.messages = [], this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1;
|
|
414
|
+
this.currentThread = null, this.messages = [], this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.streaming = "", this.answerError = "", this.answerStopped = !1;
|
|
414
415
|
const s = this.conversations[0];
|
|
415
416
|
s && await this.selectThread(s);
|
|
416
417
|
}
|
|
@@ -449,7 +450,7 @@ class V {
|
|
|
449
450
|
try {
|
|
450
451
|
const n = this.getPageContextKey(this.getPageContext());
|
|
451
452
|
if (this.currentThread && this.selectedPageKey && this.selectedPageKey !== n && (this.currentThread = null), this.currentThread || await this.newConversation(e), !this.currentThread) throw new Error("无法创建问答会话,请稍后重试。");
|
|
452
|
-
this.messages.push({ id: `local-${Date.now()}`, role: "user", content: e, metadata_json: {}, created_at: this.activeQuestionStartedAt }), this.steps = [], this.selectedAgentRunId = "", this.runLoadError = "", this.renderPanel();
|
|
453
|
+
this.messages.push({ id: `local-${Date.now()}`, role: "user", content: e, metadata_json: {}, created_at: this.activeQuestionStartedAt }), this.steps = [], this.thoughts = [], this.selectedAgentRunId = "", this.runLoadError = "", this.renderPanel();
|
|
453
454
|
const c = await this.client.streamQuestion(this.currentThread.id, e, this.answerAudience, r.signal);
|
|
454
455
|
if (!c.ok) throw new Error(await z(c, "服务暂时无法回答,请稍后重试。"));
|
|
455
456
|
if (!c.body) throw new Error("服务未返回有效的流式响应,请稍后重试。");
|
|
@@ -478,10 +479,22 @@ class V {
|
|
|
478
479
|
this.typewriter.clear(), this.waitingForFirstContent = !1, (t = this.abortController) == null || t.abort(), this.abortController = null, e && this.renderPanel();
|
|
479
480
|
}
|
|
480
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Consume an SSE event without duplicating node progress in the sidebar.
|
|
484
|
+
* Full steps remain available for cancellation; public thoughts update only
|
|
485
|
+
* the answer-local timeline. This method does not make remote requests.
|
|
486
|
+
* @param {string} e Backend event name.
|
|
487
|
+
* @param {object} t Event payload for steps, thoughts, content or completion.
|
|
488
|
+
* @returns {void}
|
|
489
|
+
*/
|
|
481
490
|
handleStreamEvent(e, t) {
|
|
482
491
|
var s, r;
|
|
483
492
|
if (e === "step") {
|
|
484
|
-
this.upsertStep(t)
|
|
493
|
+
this.upsertStep(t);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
if (e === "thought") {
|
|
497
|
+
this.upsertThought(t), this.renderThinkingTimeline();
|
|
485
498
|
return;
|
|
486
499
|
}
|
|
487
500
|
if (e === "delta") {
|
|
@@ -516,16 +529,20 @@ class V {
|
|
|
516
529
|
const t = this.steps.findIndex((s) => s.id === e.id);
|
|
517
530
|
this.steps = t === -1 ? [...this.steps, e] : this.steps.map((s) => s.id === e.id ? { ...s, ...e } : s);
|
|
518
531
|
}
|
|
532
|
+
upsertThought(e) {
|
|
533
|
+
const t = this.thoughts.findIndex((s) => s.id === e.id);
|
|
534
|
+
this.thoughts = t === -1 ? [...this.thoughts, e] : this.thoughts.map((s) => s.id === e.id ? { ...s, ...e } : s);
|
|
535
|
+
}
|
|
519
536
|
async loadAgentRun(e) {
|
|
520
537
|
if (!(!this.client || !e)) {
|
|
521
538
|
this.selectedAgentRunId = e, this.runLoading = !0, this.runLoadError = "", this.renderPanel();
|
|
522
539
|
try {
|
|
523
540
|
const t = await this.client.getAgentRun(e);
|
|
524
541
|
if (this.selectedAgentRunId !== e) return;
|
|
525
|
-
this.steps = t.steps;
|
|
542
|
+
this.steps = t.steps, this.thoughts = t.thoughts || [];
|
|
526
543
|
} catch (t) {
|
|
527
544
|
if (this.selectedAgentRunId !== e) return;
|
|
528
|
-
this.steps = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
|
|
545
|
+
this.steps = [], this.thoughts = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
|
|
529
546
|
} finally {
|
|
530
547
|
this.selectedAgentRunId === e && (this.runLoading = !1, this.renderPanel());
|
|
531
548
|
}
|
|
@@ -578,7 +595,14 @@ class V {
|
|
|
578
595
|
stopSourceRefresh() {
|
|
579
596
|
this.sourceRefreshTimer && clearTimeout(this.sourceRefreshTimer), this.sourceRefreshTimer = null;
|
|
580
597
|
}
|
|
581
|
-
|
|
598
|
+
/**
|
|
599
|
+
* Recreate the chat shell and source controls while keeping progress in answers.
|
|
600
|
+
* Preserve chat scroll unless following the active answer; bind DOM listeners
|
|
601
|
+
* after replacement. The sidebar contains no node progress or auto-scroll.
|
|
602
|
+
* @param {boolean} e Whether to scroll the chat to its latest message.
|
|
603
|
+
* @returns {void} No-op when the SDK panel is closed; no remote requests.
|
|
604
|
+
*/
|
|
605
|
+
renderPanel(e = this.asking) {
|
|
582
606
|
var g;
|
|
583
607
|
if (!this.panel) return;
|
|
584
608
|
const s = (g = this.panel.querySelector(".po-messages")) == null ? void 0 : g.scrollTop, r = this.questionUnavailableReason(), n = r || (this.asking ? "回答生成中,请稍候" : this.sourceSnapshots.length ? "请输入页面分析问题,Enter 发送,Shift + Enter 换行" : "可直接闲聊;业务问题需先上传代码包"), c = !!(r || this.asking), p = r ? '<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>', m = C.map((o) => `
|
|
@@ -609,7 +633,7 @@ class V {
|
|
|
609
633
|
</section>
|
|
610
634
|
<form class="po-composer"><textarea ${c ? "disabled" : ""} placeholder="${l(n)}"></textarea>${p}</form>
|
|
611
635
|
</main>
|
|
612
|
-
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}
|
|
636
|
+
<aside class="po-trace"><header><h2>执行过程</h2><button data-action="close">×</button></header><section>${this.renderSourceUploader()}</section></aside>
|
|
613
637
|
`, this.bindPanelEvents(), e) {
|
|
614
638
|
const o = this.panel.querySelector(".po-messages");
|
|
615
639
|
o && (o.scrollTop = o.scrollHeight);
|
|
@@ -617,10 +641,6 @@ class V {
|
|
|
617
641
|
const o = this.panel.querySelector(".po-messages");
|
|
618
642
|
o && (o.scrollTop = s);
|
|
619
643
|
}
|
|
620
|
-
if (t) {
|
|
621
|
-
const o = this.panel.querySelector(".po-trace > section");
|
|
622
|
-
o && (o.scrollTop = o.scrollHeight);
|
|
623
|
-
}
|
|
624
644
|
}
|
|
625
645
|
renderAnswerState() {
|
|
626
646
|
const n = messageTime(this.activeQuestionStartedAt), c = this.renderThinkingProcess(), e = this.asking && this.waitingForFirstContent ? `<article class="po-message assistant waiting" role="status" aria-live="polite">${n}<b>PageOps 分析</b><div class="po-ai-waiting"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在理解问题并检索证据</span></div>${c}</article>` : "", t = this.streaming ? `<article class="po-message assistant streaming">${n}<b>PageOps 分析</b><div><span data-streaming-content>${R(this.streaming)}</span>${this.asking ? '<span class="po-typing-cursor" aria-hidden="true"></span>' : ""}</div>${c}</article>` : "", s = this.answerError ? `<article class="po-message assistant answer-error" role="alert">${n}<b>PageOps 分析</b><strong>本次回答失败</strong><div>${l(this.answerError)}</div></article>` : "", r = this.answerStopped ? '<div class="po-stream-stopped" role="status">已停止输出</div>' : "";
|
|
@@ -674,42 +694,24 @@ class V {
|
|
|
674
694
|
const t = e.filename || "未命名代码包", s = e.created_at ? O(e.created_at) : "刚刚上传", r = G(e.archive_bytes || e.total_bytes || 0), n = String((b = (w = e.metadata) == null ? void 0 : w.analysis_status) != null ? b : "unknown"), c = typeof ((S = e.metadata) == null ? void 0 : S.tag) == "string" ? e.metadata.tag : "", p = typeof (($ = e.metadata) == null ? void 0 : $.branch) == "string" ? e.metadata.branch : "", m = c ? `Tag: ${c}` : p ? `Branch: ${p}` : "未记录代码引用", g = typeof ((E = e.metadata) == null ? void 0 : E.remark) == "string" && e.metadata.remark ? e.metadata.remark : "无备注", o = typeof ((A = e.metadata) == null ? void 0 : A.uploader) == "string" ? e.metadata.uploader : "未知用户", y = (T = { pending: "项目记忆等待更新", running: "项目记忆更新中", ready: "项目记忆已就绪", failed: "项目记忆更新失败" }[n]) != null ? T : "项目记忆状态未知";
|
|
675
695
|
return `<article class="po-source-item ${this.selectedSourceSnapshotId != null && this.sourceSnapshotValue(e) === String(this.selectedSourceSnapshotId) || this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "selected" : ""}"><strong>${l(t)}</strong><span>${l(m)}</span><span>备注:${l(g)}</span><span>上传人:${l(o)} · ${l(s)} · ${l(r)}</span><span>${l(y)} · 当前问答${this.selectedSourceSnapshotId == null && e === this.sourceSnapshots[0] ? "默认" : ""}引用</span></article>`;
|
|
676
696
|
}
|
|
677
|
-
renderSteps() {
|
|
678
|
-
return this.runLoading ? '<div class="po-trace-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复本次执行过程</span></div>' : this.runLoadError ? `<div class="po-trace-state failed" role="alert">${l(this.runLoadError)}</div>` : (this.steps.length ? this.steps : [{ id: "idle", title: "等待任务", status: "pending", summary: "发送问题后,这里会展示完整分析过程。" }]).map((t) => {
|
|
679
|
-
var c, p, m;
|
|
680
|
-
const s = (c = t.metrics) != null && c.length ? `<div class="po-step-metrics">${t.metrics.map((g) => `<span>${l(g)}</span>`).join("")}</div>` : "", r = (p = t.details) != null && p.length ? `<div class="po-step-details">${t.details.map((g) => `<div><span>${l(g.label)}</span><p>${l(g.value)}</p></div>`).join("")}</div>` : "", n = !!(s || r);
|
|
681
|
-
return `<details class="po-step ${t.status}" ${t.status === "running" || t.status === "failed" ? "open" : ""} ${n ? "" : "data-static"}>
|
|
682
|
-
<summary>
|
|
683
|
-
<span class="po-step-dot" aria-hidden="true"></span>
|
|
684
|
-
<span class="po-step-copy"><strong>${l(t.title)}</strong><small>${l((m = t.summary) != null ? m : "")}</small>${s}</span>
|
|
685
|
-
<span class="po-step-status">${Z(t.status)}</span>
|
|
686
|
-
</summary>
|
|
687
|
-
${r}
|
|
688
|
-
</details>`;
|
|
689
|
-
}).join("");
|
|
690
|
-
}
|
|
691
697
|
renderThinkingProcess() {
|
|
692
|
-
if (!this.asking && !this.
|
|
693
|
-
const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.
|
|
698
|
+
if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
|
|
699
|
+
const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.thoughts, this.activeQuestionStartedAt);
|
|
694
700
|
return `<details class="po-thinking-process" ${e ? "open" : ""}><summary><strong>${s ? `用时 ${l(s)}` : "思考过程"}</strong><span>${t}</span></summary><div class="po-thinking-content">${this.renderThinkingSteps()}</div></details>`;
|
|
695
701
|
}
|
|
696
702
|
renderThinkingSteps() {
|
|
697
703
|
if (this.runLoading) return '<div class="po-thinking-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复思考过程</span></div>';
|
|
698
704
|
if (this.runLoadError) return `<div class="po-thinking-state failed">${l(this.runLoadError)}</div>`;
|
|
699
|
-
const e = this.
|
|
705
|
+
const e = this.thoughts.length ? this.thoughts : [{ id: "idle", kind: "thinking", label: "理解问题", status: "running", text: "正在判断问题并规划需要核对的信息。" }];
|
|
700
706
|
return e.map((t) => {
|
|
701
|
-
const s = String(t.kind ||
|
|
702
|
-
if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.
|
|
703
|
-
return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.
|
|
707
|
+
const s = String(t.kind || "thinking"), r = thinkingIcon(s), n = (t.metrics || []).length ? `<span class="po-thinking-metrics">${t.metrics.map((c) => l(c)).join(" · ")}</span>` : "", p = (t.details || []).map((c) => `<div class="po-thinking-detail"><span>${l(c.label)}</span>${String(c.value || "").split("\n").filter(Boolean).map((m) => `<code>${l(m)}</code>`).join("")}</div>`).join("");
|
|
708
|
+
if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.label)}</strong><p>${l(t.text || "")}</p>${n}</div></div>`;
|
|
709
|
+
return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.label)}</strong><span>${l(t.text || "")}</span>${n}${p}</div></div>`;
|
|
704
710
|
}).join("");
|
|
705
711
|
}
|
|
706
|
-
|
|
707
|
-
var
|
|
708
|
-
|
|
709
|
-
if (t && (t.innerHTML = this.renderSteps(), this.panel == null || this.panel.querySelectorAll(".po-thinking-content").forEach((n) => n.innerHTML = this.renderThinkingSteps()), e)) {
|
|
710
|
-
const n = (r = this.panel) == null ? void 0 : r.querySelector(".po-trace > section");
|
|
711
|
-
n && (n.scrollTop = n.scrollHeight);
|
|
712
|
-
}
|
|
712
|
+
renderThinkingTimeline() {
|
|
713
|
+
var e;
|
|
714
|
+
(e = this.panel) == null || e.querySelectorAll(".po-thinking-content").forEach((t) => t.innerHTML = this.renderThinkingSteps());
|
|
713
715
|
}
|
|
714
716
|
bindPanelEvents() {
|
|
715
717
|
var e, t, s, r, n, c, p, m, g, o, y, w, b, S, $, E, A, T, h, d;
|
|
@@ -829,8 +831,5 @@ function G(a) {
|
|
|
829
831
|
t /= 1024, s += 1;
|
|
830
832
|
return `${t >= 10 || s === 0 ? t.toFixed(0) : t.toFixed(1)} ${e[s]}`;
|
|
831
833
|
}
|
|
832
|
-
function Z(a) {
|
|
833
|
-
return { pending: "等待中", running: "执行中", completed: "已完成", failed: "失败", cancelled: "已停止" }[a];
|
|
834
|
-
}
|
|
835
834
|
const Y = new V();
|
|
836
835
|
exports.PageOpsSDK=Y;}));
|
package/dist/types.d.ts
CHANGED
|
@@ -68,6 +68,20 @@ export interface AgentRunHistory {
|
|
|
68
68
|
tool_call_count: number;
|
|
69
69
|
active_skill?: string | null;
|
|
70
70
|
steps: ExecutionStep[];
|
|
71
|
+
thoughts: AgentRunThought[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface AgentRunThought {
|
|
75
|
+
id: string;
|
|
76
|
+
kind: 'thinking' | 'read' | 'search' | 'data' | 'tool' | 'status';
|
|
77
|
+
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
78
|
+
label: string;
|
|
79
|
+
text: string;
|
|
80
|
+
metrics?: string[];
|
|
81
|
+
details?: Array<{
|
|
82
|
+
label: string;
|
|
83
|
+
value: string;
|
|
84
|
+
}>;
|
|
71
85
|
}
|
|
72
86
|
export interface SourceSnapshot {
|
|
73
87
|
id?: number | string;
|