@pageops/sdk 0.1.36 → 0.1.37

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 CHANGED
@@ -7,6 +7,11 @@ 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
+
10
15
  `src/index.js` is the readable ESM runtime baseline, `src/styles.css` preserves
11
16
  the 0.1.34 styles, and `src/extensions.css` contains the new non-minified style
12
17
  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;
@@ -89,6 +91,8 @@ declare class PageOpsSDKController {
89
91
  private renderSourceItem;
90
92
  private renderSteps;
91
93
  private renderThinkingProcess;
94
+ private renderThinkingSteps;
95
+ private renderThinkingTimeline;
92
96
  private renderExecutionSteps;
93
97
  private bindPanelEvents;
94
98
  }
@@ -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("服务未返回有效的流式响应,请稍后重试。");
@@ -484,6 +485,10 @@ class V {
484
485
  this.upsertStep(t), this.renderExecutionSteps(!0);
485
486
  return;
486
487
  }
488
+ if (e === "thought") {
489
+ this.upsertThought(t), this.renderThinkingTimeline();
490
+ return;
491
+ }
487
492
  if (e === "delta") {
488
493
  const n = String((s = t.content) != null ? s : "");
489
494
  if (!n) return;
@@ -516,16 +521,20 @@ class V {
516
521
  const t = this.steps.findIndex((s) => s.id === e.id);
517
522
  this.steps = t === -1 ? [...this.steps, e] : this.steps.map((s) => s.id === e.id ? { ...s, ...e } : s);
518
523
  }
524
+ upsertThought(e) {
525
+ const t = this.thoughts.findIndex((s) => s.id === e.id);
526
+ this.thoughts = t === -1 ? [...this.thoughts, e] : this.thoughts.map((s) => s.id === e.id ? { ...s, ...e } : s);
527
+ }
519
528
  async loadAgentRun(e) {
520
529
  if (!(!this.client || !e)) {
521
530
  this.selectedAgentRunId = e, this.runLoading = !0, this.runLoadError = "", this.renderPanel();
522
531
  try {
523
532
  const t = await this.client.getAgentRun(e);
524
533
  if (this.selectedAgentRunId !== e) return;
525
- this.steps = t.steps;
534
+ this.steps = t.steps, this.thoughts = t.thoughts || [];
526
535
  } catch (t) {
527
536
  if (this.selectedAgentRunId !== e) return;
528
- this.steps = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
537
+ this.steps = [], this.thoughts = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
529
538
  } finally {
530
539
  this.selectedAgentRunId === e && (this.runLoading = !1, this.renderPanel());
531
540
  }
@@ -689,24 +698,28 @@ class V {
689
698
  }).join("");
690
699
  }
691
700
  renderThinkingProcess() {
692
- if (!this.asking && !this.steps.length && !this.runLoading && !this.runLoadError) return "";
693
- const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.steps, this.activeQuestionStartedAt);
701
+ if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
702
+ const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.thoughts, this.activeQuestionStartedAt);
694
703
  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
704
  }
696
705
  renderThinkingSteps() {
697
706
  if (this.runLoading) return '<div class="po-thinking-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复思考过程</span></div>';
698
707
  if (this.runLoadError) return `<div class="po-thinking-state failed">${l(this.runLoadError)}</div>`;
699
- const e = this.steps.length ? this.steps : [{ id: "idle", kind: "thinking", title: "理解问题", status: "running", summary: "正在判断问题并规划需要核对的信息。" }];
708
+ const e = this.thoughts.length ? this.thoughts : [{ id: "idle", kind: "thinking", label: "理解问题", status: "running", text: "正在判断问题并规划需要核对的信息。" }];
700
709
  return e.map((t) => {
701
- const s = String(t.kind || (String(t.id || "").startsWith("model-turn-") ? "thinking" : "status")), 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("");
702
- if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.title)}</strong><p>${l(t.summary || "")}</p>${n}</div></div>`;
703
- return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.title)}</strong><span>${l(t.summary || "")}</span>${n}${p}</div></div>`;
710
+ 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("");
711
+ 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>`;
712
+ 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
713
  }).join("");
705
714
  }
715
+ renderThinkingTimeline() {
716
+ var e;
717
+ (e = this.panel) == null || e.querySelectorAll(".po-thinking-content").forEach((t) => t.innerHTML = this.renderThinkingSteps());
718
+ }
706
719
  renderExecutionSteps(e = !1) {
707
720
  var s, r;
708
721
  const t = (s = this.panel) == null ? void 0 : s.querySelector(".po-steps");
709
- if (t && (t.innerHTML = this.renderSteps(), this.panel == null || this.panel.querySelectorAll(".po-thinking-content").forEach((n) => n.innerHTML = this.renderThinkingSteps()), e)) {
722
+ if (t && (t.innerHTML = this.renderSteps(), e)) {
710
723
  const n = (r = this.panel) == null ? void 0 : r.querySelector(".po-trace > section");
711
724
  n && (n.scrollTop = n.scrollHeight);
712
725
  }
@@ -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("服务未返回有效的流式响应,请稍后重试。");
@@ -484,6 +485,10 @@ class V {
484
485
  this.upsertStep(t), this.renderExecutionSteps(!0);
485
486
  return;
486
487
  }
488
+ if (e === "thought") {
489
+ this.upsertThought(t), this.renderThinkingTimeline();
490
+ return;
491
+ }
487
492
  if (e === "delta") {
488
493
  const n = String((s = t.content) != null ? s : "");
489
494
  if (!n) return;
@@ -516,16 +521,20 @@ class V {
516
521
  const t = this.steps.findIndex((s) => s.id === e.id);
517
522
  this.steps = t === -1 ? [...this.steps, e] : this.steps.map((s) => s.id === e.id ? { ...s, ...e } : s);
518
523
  }
524
+ upsertThought(e) {
525
+ const t = this.thoughts.findIndex((s) => s.id === e.id);
526
+ this.thoughts = t === -1 ? [...this.thoughts, e] : this.thoughts.map((s) => s.id === e.id ? { ...s, ...e } : s);
527
+ }
519
528
  async loadAgentRun(e) {
520
529
  if (!(!this.client || !e)) {
521
530
  this.selectedAgentRunId = e, this.runLoading = !0, this.runLoadError = "", this.renderPanel();
522
531
  try {
523
532
  const t = await this.client.getAgentRun(e);
524
533
  if (this.selectedAgentRunId !== e) return;
525
- this.steps = t.steps;
534
+ this.steps = t.steps, this.thoughts = t.thoughts || [];
526
535
  } catch (t) {
527
536
  if (this.selectedAgentRunId !== e) return;
528
- this.steps = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
537
+ this.steps = [], this.thoughts = [], this.runLoadError = t instanceof Error ? t.message : "执行过程加载失败";
529
538
  } finally {
530
539
  this.selectedAgentRunId === e && (this.runLoading = !1, this.renderPanel());
531
540
  }
@@ -689,24 +698,28 @@ class V {
689
698
  }).join("");
690
699
  }
691
700
  renderThinkingProcess() {
692
- if (!this.asking && !this.steps.length && !this.runLoading && !this.runLoadError) return "";
693
- const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.steps, this.activeQuestionStartedAt);
701
+ if (!this.asking && !this.thoughts.length && !this.runLoading && !this.runLoadError) return "";
702
+ const e = this.asking && !this.streaming, t = this.asking && !this.streaming ? "思考中" : this.runLoading ? "加载中" : this.runLoadError ? "加载失败" : "已思考完成", s = thinkingDuration(this.thoughts, this.activeQuestionStartedAt);
694
703
  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
704
  }
696
705
  renderThinkingSteps() {
697
706
  if (this.runLoading) return '<div class="po-thinking-state"><span class="po-ai-spinner" aria-hidden="true"></span><span>正在恢复思考过程</span></div>';
698
707
  if (this.runLoadError) return `<div class="po-thinking-state failed">${l(this.runLoadError)}</div>`;
699
- const e = this.steps.length ? this.steps : [{ id: "idle", kind: "thinking", title: "理解问题", status: "running", summary: "正在判断问题并规划需要核对的信息。" }];
708
+ const e = this.thoughts.length ? this.thoughts : [{ id: "idle", kind: "thinking", label: "理解问题", status: "running", text: "正在判断问题并规划需要核对的信息。" }];
700
709
  return e.map((t) => {
701
- const s = String(t.kind || (String(t.id || "").startsWith("model-turn-") ? "thinking" : "status")), 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("");
702
- if (s === "thinking") return `<div class="po-thinking-note ${t.status}">${r}<div><strong>${l(t.title)}</strong><p>${l(t.summary || "")}</p>${n}</div></div>`;
703
- return `<div class="po-thinking-activity ${t.status}">${r}<div class="po-thinking-activity-copy"><strong>${l(t.title)}</strong><span>${l(t.summary || "")}</span>${n}${p}</div></div>`;
710
+ 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("");
711
+ 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>`;
712
+ 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
713
  }).join("");
705
714
  }
715
+ renderThinkingTimeline() {
716
+ var e;
717
+ (e = this.panel) == null || e.querySelectorAll(".po-thinking-content").forEach((t) => t.innerHTML = this.renderThinkingSteps());
718
+ }
706
719
  renderExecutionSteps(e = !1) {
707
720
  var s, r;
708
721
  const t = (s = this.panel) == null ? void 0 : s.querySelector(".po-steps");
709
- if (t && (t.innerHTML = this.renderSteps(), this.panel == null || this.panel.querySelectorAll(".po-thinking-content").forEach((n) => n.innerHTML = this.renderThinkingSteps()), e)) {
722
+ if (t && (t.innerHTML = this.renderSteps(), e)) {
710
723
  const n = (r = this.panel) == null ? void 0 : r.querySelector(".po-trace > section");
711
724
  n && (n.scrollTop = n.scrollHeight);
712
725
  }
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageops/sdk",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "PageOps embeddable frontend SDK",
5
5
  "type": "module",
6
6
  "main": "dist/pageops-sdk.umd.cjs",