@tanzerfe/page-use 0.0.12 → 0.0.14

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.
@@ -1,4 +1,4 @@
1
- import { $ as showFlowMask, B as acquireFlowExecution, C as createIndexedDbFlowRepository, Ct as readLauncherQuery, Et as resolveTtsEngine, F as sceneKey, Ft as cancelRegionPicker, G as getPageUseSnapshot, H as configurePageUse, I as scopeKey, It as hasRegionPicker, J as isRunning, K as hideFlowMask, M as parseFlowRegion, N as parseFlowScene, Ot as SIMULATOR_MASK_ID, P as parseFlowSceneDraft, Q as runTaskForFlow, R as validateRegionPreviewInputs, S as previewFlowImport, St as normalizeOptions, T as cloneJson, Tt as listTtsEngines, U as getElapsedSeconds, V as clearPageUseLog, W as getPageUseConfig, X as registerQuestionUi, Y as pageUseStore, Z as runTask, _ as createFlowApiAdapter, at as pageUseHistory, b as exportFlowBundle, ct as narrate, dt as previewStore, et as stopTask, f as composedParent, ft as startPreview, g as validateRegionPages, gt as createStore, h as regionAbortable, ht as pageUseSettings, i as definePageUseManagerElement, it as pageUsePresets, j as parseFlowKnowledge, jt as isSpeechSupported, k as newRevision, kt as BROWSER_ENGINE_ID, l as createFlowRunner, lt as narrationMute, m as locateFlowRegion, nt as subscribePageUse, ot as hideTourHighlight, p as createRegionSelector, pt as stopPreview, rt as updateFlowExecution, st as showTourHighlight, tt as stopTaskForFlow, u as createCompletionEvaluator, ut as registerNarrationPanelName, v as validateFlowApiOptions, w as FLOW_SEGMENT_MAX_CHARS, x as importFlowBundle, y as createFlowCloud, z as validateSceneBindings, zt as FlowError } from "./tool-CvEvIsN9.mjs";
1
+ import { $ as showFlowMask, At as listTtsEngines, B as acquireFlowExecution, Bt as cancelRegionPicker, C as createIndexedDbFlowRepository, Dt as normalizeOptions, F as sceneKey, G as getPageUseSnapshot, H as configurePageUse, I as scopeKey, It as isSpeechSupported, J as isRunning, K as hideFlowMask, M as parseFlowRegion, N as parseFlowScene, Nt as SIMULATOR_MASK_ID, Ot as readLauncherQuery, P as parseFlowSceneDraft, Pt as BROWSER_ENGINE_ID, Q as runTaskForFlow, R as validateRegionPreviewInputs, S as previewFlowImport, T as cloneJson, U as getElapsedSeconds, V as clearPageUseLog, Vt as hasRegionPicker, W as getPageUseConfig, Wt as FlowError, X as registerQuestionUi, Y as pageUseStore, Z as runTask, _ as createFlowApiAdapter, _t as startPreview, at as decidePageUseSubmit, b as exportFlowBundle, bt as pageUseSettings, ct as pageUseHistory, dt as hideTourHighlight, et as stopTask, f as composedParent, ft as showTourHighlight, g as validateRegionPages, gt as previewStore, h as regionAbortable, ht as registerNarrationPanelName, i as definePageUseManagerElement, it as cancelPageUseSubmit, j as parseFlowKnowledge, jt as resolveTtsEngine, k as newRevision, l as createFlowRunner, lt as completionRequestBody, m as locateFlowRegion, mt as narrationMute, nt as subscribePageUse, ot as pageUseSubmitStore, p as createRegionSelector, pt as narrate, rt as updateFlowExecution, st as pageUsePresets, tt as stopTaskForFlow, u as createCompletionEvaluator, ut as readCompletionResponse, v as validateFlowApiOptions, vt as stopPreview, w as FLOW_SEGMENT_MAX_CHARS, x as importFlowBundle, xt as createStore, y as createFlowCloud, z as validateSceneBindings } from "./tool-DBeaEt3g.mjs";
2
2
  import { LitElement, css, html, nothing, svg } from "lit";
3
3
  import { keyed } from "lit/directives/keyed.js";
4
4
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
@@ -24,35 +24,73 @@ const pageUseCapability = {
24
24
 
25
25
  //#endregion
26
26
  //#region src/ui/launcherControl.ts
27
- /**
28
- * 调试入口的显示控制:供业务系统通过模块导出或全局对象调出 / 隐藏调试面板。
29
- * 显示状态写入设置 launcherVisible(localStorage 持久化),刷新后保持;
30
- * 不依赖 lit,全局桥接引用本模块不会引入 UI 组件。
31
- */
32
- /** 已挂载 launcher 登记的「展开面板」回调;未挂载时为空 */
33
- const openers = /* @__PURE__ */ new Set();
34
- /** launcher 挂载时登记展开回调,返回注销函数 */
35
- function registerLauncherOpener(open) {
36
- openers.add(open);
27
+ /** 面板运行期控制,不依赖 Lit;旧 show/hide 接口保留持久化语义。 */
28
+ const controllers = /* @__PURE__ */ new Set();
29
+ const listeners = /* @__PURE__ */ new Set();
30
+ let lastSnapshot = {
31
+ mounted: false,
32
+ entryVisible: false,
33
+ panelOpen: false
34
+ };
35
+ /** 多面板时取任意可见;通常每个宿主只挂载一个面板。 */
36
+ function getPageUsePanelSnapshot() {
37
+ const states = [...controllers].map((controller) => controller.snapshot());
38
+ return {
39
+ mounted: controllers.size > 0,
40
+ entryVisible: states.some((state) => state.entryVisible),
41
+ panelOpen: states.some((state) => state.panelOpen)
42
+ };
43
+ }
44
+ function notifyPageUsePanelState() {
45
+ const snapshot = getPageUsePanelSnapshot();
46
+ if (snapshot.mounted === lastSnapshot.mounted && snapshot.entryVisible === lastSnapshot.entryVisible && snapshot.panelOpen === lastSnapshot.panelOpen) return;
47
+ lastSnapshot = snapshot;
48
+ for (const listener of listeners) try {
49
+ listener({ ...snapshot });
50
+ } catch (error) {
51
+ console.warn("[PageUse] 面板订阅回调异常", error);
52
+ }
53
+ }
54
+ function subscribePageUsePanel(listener) {
55
+ listeners.add(listener);
37
56
  return () => {
38
- openers.delete(open);
57
+ listeners.delete(listener);
39
58
  };
40
59
  }
41
- /**
42
- * 显示调试入口并展开面板,状态持久化。
43
- * 宿主未挂载调试面板时只保存状态并警告,之后挂载的面板按该状态显示。
44
- */
60
+ function registerLauncherController(controller) {
61
+ controllers.add(controller);
62
+ notifyPageUsePanelState();
63
+ return () => {
64
+ controllers.delete(controller);
65
+ notifyPageUsePanelState();
66
+ };
67
+ }
68
+ /** 临时打开面板,不写入设置;未挂载时返回 false,不排队等待挂载。 */
69
+ async function openPageUsePanel() {
70
+ if (!controllers.size) return false;
71
+ await Promise.all([...controllers].map((controller) => controller.open(true)));
72
+ notifyPageUsePanelState();
73
+ return getPageUsePanelSnapshot().panelOpen;
74
+ }
75
+ /** 临时收起面板,保留原有入口设置、输入和任务;可在 onUserSubmit 内调用。 */
76
+ async function closePageUsePanel() {
77
+ await Promise.all([...controllers].map((controller) => controller.close()));
78
+ notifyPageUsePanelState();
79
+ }
80
+ /** 旧接口:显示入口并展开,持久化设置。 */
45
81
  function showPageUseLauncher() {
46
82
  pageUseSettings.update({ launcherVisible: true });
47
- if (!openers.size) {
83
+ if (!controllers.size) {
48
84
  console.warn("[PageUse] 调试面板未挂载,显示状态已保存,挂载后生效(mountPageUseUI 需传入 launcher)");
49
85
  return;
50
86
  }
51
- openers.forEach((open) => open());
87
+ for (const controller of controllers) controller.open(false);
52
88
  }
53
- /** 隐藏调试入口(面板与浮动入口),状态持久化;效果与面板标题栏的关闭按钮相同 */
89
+ /** 旧接口:隐藏面板和入口并持久化;不停止页面任务。 */
54
90
  function hidePageUseLauncher() {
91
+ cancelPageUseSubmit();
55
92
  pageUseSettings.update({ launcherVisible: false });
93
+ closePageUsePanel();
56
94
  }
57
95
 
58
96
  //#endregion
@@ -149,7 +187,11 @@ function installPageUseGlobal() {
149
187
  tool: PAGE_USE_TOOL,
150
188
  runTool: runPageUseTool,
151
189
  showLauncher: showPageUseLauncher,
152
- hideLauncher: hidePageUseLauncher
190
+ hideLauncher: hidePageUseLauncher,
191
+ openPanel: openPageUsePanel,
192
+ closePanel: closePageUsePanel,
193
+ getPanelSnapshot: getPageUsePanelSnapshot,
194
+ subscribePanel: subscribePageUsePanel
153
195
  };
154
196
  window[PAGE_USE_GLOBAL_KEY] = api;
155
197
  return () => {
@@ -282,14 +324,14 @@ function createFlowGenerator(llm) {
282
324
  const headers = new Headers({ "Content-Type": "application/json" });
283
325
  if (llm.apiKey) headers.set("Authorization", `Bearer ${llm.apiKey}`);
284
326
  if (llm.sessionHeader) headers.set(llm.sessionHeader, context.sessionId);
327
+ const { tools: _tools, tool_choice: _choice, functions: _functions, function_call: _call, ...extra } = llm.extraBody;
285
328
  const response = await fetch(`${llm.baseURL}/chat/completions`, {
286
329
  method: "POST",
287
330
  headers,
288
331
  signal,
289
- body: JSON.stringify({
290
- ...llm.extraBody,
332
+ body: JSON.stringify(completionRequestBody({
333
+ ...extra,
291
334
  model: llm.model,
292
- stream: false,
293
335
  temperature: .2,
294
336
  messages: [{
295
337
  role: "system",
@@ -310,10 +352,12 @@ function createFlowGenerator(llm) {
310
352
  outputs: context.outputs
311
353
  })
312
354
  }]
313
- })
355
+ }, llm))
314
356
  });
315
357
  if (!response.ok) throw new Error(`讲解模型请求失败(HTTP ${response.status})`);
316
- const content = (await response.json()).choices?.[0]?.message?.content;
358
+ const body = await readCompletionResponse(response, signal);
359
+ if (body.choices?.[0]?.message?.tool_calls?.length || body.choices?.[0]?.message?.function_call) throw new Error("讲解模型返回了工具调用");
360
+ const content = body.choices?.[0]?.message?.content;
317
361
  if (typeof content !== "string") throw new Error("讲解模型未返回文本");
318
362
  return content;
319
363
  };
@@ -1266,7 +1310,7 @@ var PageUseGlowElement = class extends LitElement {
1266
1310
 
1267
1311
  //#endregion
1268
1312
  //#region package.json
1269
- var version = "0.0.12";
1313
+ var version = "0.0.14";
1270
1314
 
1271
1315
  //#endregion
1272
1316
  //#region src/ui/drag.ts
@@ -2807,7 +2851,12 @@ var PageUseLauncherElement = class extends LitElement {
2807
2851
  } });
2808
2852
  }
2809
2853
  });
2854
+ unsubscribeSubmit;
2855
+ submitError = "";
2856
+ temporaryPanel = false;
2857
+ panelCommand = 0;
2810
2858
  connectedCallback() {
2859
+ this.unsubscribeSubmit = pageUseSubmitStore.subscribe(() => this.requestUpdate());
2811
2860
  super.connectedCallback();
2812
2861
  definePageUseManagerElement();
2813
2862
  this.wasRunning = isRunning();
@@ -2829,7 +2878,17 @@ var PageUseLauncherElement = class extends LitElement {
2829
2878
  pageUsePresets.store.subscribe(() => this.requestUpdate()),
2830
2879
  narrationMute.subscribe(() => this.requestUpdate()),
2831
2880
  previewStore.subscribe(() => this.requestUpdate()),
2832
- registerLauncherOpener(() => void this.expand()),
2881
+ registerLauncherController({
2882
+ open: (temporary) => this.expand(temporary),
2883
+ close: () => this.closeTemporaryPanel(),
2884
+ snapshot: () => {
2885
+ const entryVisible = this.isVisible(pageUseSettings.get());
2886
+ return {
2887
+ entryVisible,
2888
+ panelOpen: entryVisible && this.open
2889
+ };
2890
+ }
2891
+ }),
2833
2892
  registerQuestionUi(),
2834
2893
  this.watchVoices()
2835
2894
  ];
@@ -2838,6 +2897,9 @@ var PageUseLauncherElement = class extends LitElement {
2838
2897
  window.addEventListener("resize", this.onResize);
2839
2898
  }
2840
2899
  disconnectedCallback() {
2900
+ ++this.panelCommand;
2901
+ this.unsubscribeSubmit?.();
2902
+ cancelPageUseSubmit();
2841
2903
  super.disconnectedCallback();
2842
2904
  this.cleanups.forEach((off) => off());
2843
2905
  this.cleanups = [];
@@ -2952,6 +3014,7 @@ var PageUseLauncherElement = class extends LitElement {
2952
3014
  this.measureFab();
2953
3015
  }
2954
3016
  updated(_changed) {
3017
+ notifyPageUsePanelState();
2955
3018
  this.autosizeTextarea();
2956
3019
  this.animateFabWidth();
2957
3020
  this.animatePanelResize();
@@ -3075,7 +3138,7 @@ var PageUseLauncherElement = class extends LitElement {
3075
3138
  }
3076
3139
  /** 调试入口是否显示:持久化状态优先,未操作过时跟随宿主 defaultHidden */
3077
3140
  isVisible(settings) {
3078
- return settings.launcherVisible ?? !this._config.defaultHidden;
3141
+ return this.temporaryPanel || (settings.launcherVisible ?? !this._config.defaultHidden);
3079
3142
  }
3080
3143
  /**
3081
3144
  * 入口按下:先清掉上一次手势遗留的拖动标记,本次是否为拖动由 fabDrag 判定。
@@ -3105,17 +3168,33 @@ var PageUseLauncherElement = class extends LitElement {
3105
3168
  this.requestUpdate();
3106
3169
  };
3107
3170
  /** 展开面板(showPageUseLauncher 调用):等入口按新的显示状态渲染后再测量定位 */
3108
- async expand() {
3171
+ async expand(temporary = false) {
3172
+ const command = ++this.panelCommand;
3173
+ this.temporaryPanel = temporary;
3174
+ this.requestUpdate();
3109
3175
  await this.updateComplete;
3176
+ if (!this.isConnected || command !== this.panelCommand) return;
3110
3177
  this.measureFab();
3111
3178
  this.resolvePanelAnchor();
3112
3179
  this.cancelSheetAnimation();
3113
3180
  if (this.view === "manager") this.shadowRoot?.querySelector("tz-page-use-manager")?.openSceneManager();
3114
3181
  this.open = true;
3115
3182
  this.requestUpdate();
3183
+ await this.updateComplete;
3184
+ }
3185
+ async closeTemporaryPanel() {
3186
+ ++this.panelCommand;
3187
+ this.cancelSheetAnimation();
3188
+ this.cancelPanelResize();
3189
+ stopPreview();
3190
+ this.open = false;
3191
+ this.temporaryPanel = false;
3192
+ this.requestUpdate();
3193
+ await this.updateComplete;
3116
3194
  }
3117
3195
  /** 关闭调试入口:收起面板并持久化隐藏状态,之后需调用显示方法或 URL 参数调出 */
3118
3196
  close() {
3197
+ cancelPageUseSubmit();
3119
3198
  this.cancelPanelResize();
3120
3199
  stopPreview();
3121
3200
  this.open = false;
@@ -3342,7 +3421,21 @@ var PageUseLauncherElement = class extends LitElement {
3342
3421
  /** tourStyle:快捷指令携带的讲解风格;输入框提交时不传,按面板设置与宿主默认 */
3343
3422
  async submit(tourStyle) {
3344
3423
  const text = this.task.trim();
3345
- if (isRunning() || !text) return;
3424
+ if (isRunning() || pageUseSubmitStore.get().pending || !text) return;
3425
+ this.submitError = "";
3426
+ const handler = getPageUseConfig()?.onUserSubmit;
3427
+ const decision = handler ? await decidePageUseSubmit(text, handler) : { action: "continue" };
3428
+ if (decision.action === "reject") {
3429
+ this.submitError = decision.message;
3430
+ this.requestUpdate();
3431
+ return;
3432
+ }
3433
+ if (decision.action === "cancelled" || decision.action === "busy") return;
3434
+ if (decision.action === "handled") {
3435
+ this.task = "";
3436
+ this.requestUpdate();
3437
+ return;
3438
+ }
3346
3439
  this.task = "";
3347
3440
  this.requestUpdate();
3348
3441
  if (this.collapseOnRun) this.collapse();
@@ -3352,6 +3445,7 @@ var PageUseLauncherElement = class extends LitElement {
3352
3445
  });
3353
3446
  }
3354
3447
  applyPreset(text, tourStyle) {
3448
+ if (isRunning() || pageUseSubmitStore.get().pending) return;
3355
3449
  this.task = text;
3356
3450
  this.submit(tourStyle);
3357
3451
  }
@@ -3730,7 +3824,7 @@ var PageUseLauncherElement = class extends LitElement {
3730
3824
  @click=${() => playing ? stopPreview() : startPreview(engine, {
3731
3825
  rate: settings.voiceRate,
3732
3826
  voice: voiceName
3733
- })}
3827
+ }, getPageUseConfig()?.appName || "Page Use")}
3734
3828
  >
3735
3829
  ${playing ? "停止" : "试听"}
3736
3830
  </button>`;
@@ -3985,11 +4079,13 @@ var PageUseLauncherElement = class extends LitElement {
3985
4079
  </div>` : nothing}
3986
4080
  ${isFlowActive(this.flowSnapshot) ? this.renderFlowControls() : html`
3987
4081
  ${this.tray && !running ? this.renderTray() : nothing}
4082
+ ${this.submitError ? html`<div class="alert warning" role="alert">${this.submitError}</div>` : nothing}
4083
+ ${pageUseSubmitStore.get().pending ? html`<button type="button" class="btn tiny" @click=${cancelPageUseSubmit}>取消判断</button>` : nothing}
3988
4084
  <textarea
3989
4085
  class="textarea"
3990
4086
  rows=${TEXTAREA_MIN_ROWS}
3991
4087
  placeholder=${running ? "执行中,可点击「终止」中断" : "输入指令,回车执行,Shift+回车换行"}
3992
- ?disabled=${running}
4088
+ ?disabled=${running || pageUseSubmitStore.get().pending}
3993
4089
  .value=${this.task}
3994
4090
  @input=${this.onTaskInput}
3995
4091
  @keydown=${this.onTaskKeydown}
@@ -3998,7 +4094,7 @@ var PageUseLauncherElement = class extends LitElement {
3998
4094
  <button
3999
4095
  type="button"
4000
4096
  class="btn tiny ${this.tray === "presets" ? "secondary accent" : "ghost"}"
4001
- ?disabled=${running}
4097
+ ?disabled=${running || pageUseSubmitStore.get().pending}
4002
4098
  @click=${() => this.toggleTray("presets")}
4003
4099
  >
4004
4100
  快捷指令
@@ -4006,7 +4102,7 @@ var PageUseLauncherElement = class extends LitElement {
4006
4102
  <button
4007
4103
  type="button"
4008
4104
  class="btn tiny ${this.tray === "history" ? "secondary accent" : "ghost"}"
4009
- ?disabled=${running}
4105
+ ?disabled=${running || pageUseSubmitStore.get().pending}
4010
4106
  @click=${() => this.toggleTray("history")}
4011
4107
  >
4012
4108
  历史${historyCount ? `(${historyCount})` : ""}
@@ -4026,7 +4122,7 @@ var PageUseLauncherElement = class extends LitElement {
4026
4122
  <button
4027
4123
  type="button"
4028
4124
  class="btn push-right"
4029
- ?disabled=${!lastTask}
4125
+ ?disabled=${!lastTask || pageUseSubmitStore.get().pending}
4030
4126
  title=${lastTask ? `重跑:${lastTask}` : "暂无可重跑的指令"}
4031
4127
  @click=${() => lastTask && this.applyPreset(lastTask)}
4032
4128
  >
@@ -4035,10 +4131,10 @@ var PageUseLauncherElement = class extends LitElement {
4035
4131
  <button
4036
4132
  type="button"
4037
4133
  class="btn primary"
4038
- ?disabled=${!this.task.trim()}
4134
+ ?disabled=${!this.task.trim() || pageUseSubmitStore.get().pending}
4039
4135
  @click=${() => void this.submit()}
4040
4136
  >
4041
- 执行
4137
+ ${pageUseSubmitStore.get().pending ? "正在判断…" : "执行"}
4042
4138
  </button>
4043
4139
  `}
4044
4140
  </div>`}
@@ -4194,4 +4290,4 @@ function mountPageUseUI(options = {}) {
4194
4290
  }
4195
4291
 
4196
4292
  //#endregion
4197
- export { isPageUseCommand as _, PAGE_USE_STATIC_PRESETS as a, showPageUseLauncher as b, PAGE_USE_GLOW_TAG as c, getPageUseFlow as d, PAGE_USE_GLOBAL_KEY as f, formatPageUseResultForModel as g, PAGE_USE_TOOL_NAME as h, PageUseLauncherElement as i, PageUseGlowElement as l, PAGE_USE_TOOL as m, mountPageUseUI as n, buildMenuPresets as o, PAGE_USE_COMMAND_TYPE as p, PAGE_USE_LAUNCHER_TAG as r, PAGE_USE_ROBOT_ICON_SVG as s, definePageUseElements as t, createPageUse as u, runPageUseTool as v, pageUseCapability as x, hidePageUseLauncher as y };
4293
+ export { showPageUseLauncher as C, openPageUsePanel as S, pageUseCapability as T, isPageUseCommand as _, PAGE_USE_STATIC_PRESETS as a, getPageUsePanelSnapshot as b, PAGE_USE_GLOW_TAG as c, getPageUseFlow as d, PAGE_USE_GLOBAL_KEY as f, formatPageUseResultForModel as g, PAGE_USE_TOOL_NAME as h, PageUseLauncherElement as i, PageUseGlowElement as l, PAGE_USE_TOOL as m, mountPageUseUI as n, buildMenuPresets as o, PAGE_USE_COMMAND_TYPE as p, PAGE_USE_LAUNCHER_TAG as r, PAGE_USE_ROBOT_ICON_SVG as s, definePageUseElements as t, createPageUse as u, runPageUseTool as v, subscribePageUsePanel as w, hidePageUseLauncher as x, closePageUsePanel as y };