@nexface/tools 0.1.15-alpha.1 → 0.1.15-alpha.10

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.
Files changed (87) hide show
  1. package/dist/browser/actions.js +34 -10
  2. package/dist/browser/controller.js +53 -74
  3. package/dist/browser/diagnostics.js +8 -3
  4. package/dist/browser/dom.js +12 -28
  5. package/dist/browser/feedback.js +6 -5
  6. package/dist/browser/focus.d.ts +0 -1
  7. package/dist/browser/focus.js +1 -13
  8. package/dist/browser/locator.js +3 -9
  9. package/dist/browser/prompt.d.ts +1 -1
  10. package/dist/browser/prompt.generated.d.ts +1 -1
  11. package/dist/browser/prompt.generated.js +6 -3
  12. package/dist/browser/prompt.js +0 -1
  13. package/dist/browser/snapshot.js +141 -120
  14. package/dist/browser/toolset.js +42 -36
  15. package/dist/browser/types.d.ts +1 -1
  16. package/dist/browser/types.js +0 -1
  17. package/dist/browser/worker-runner.js +0 -1
  18. package/dist/definition.d.ts +1 -3
  19. package/dist/definition.js +2 -2
  20. package/dist/index.browser.js +0 -1
  21. package/dist/index.js +0 -1
  22. package/dist/internal-react.d.ts +1 -1
  23. package/dist/internal-react.js +3 -4
  24. package/dist/internal-types.js +0 -1
  25. package/dist/navigation.js +0 -1
  26. package/dist/operation-lock.d.ts +1 -1
  27. package/dist/operation-lock.js +36 -19
  28. package/dist/operation-runtime.js +41 -13
  29. package/dist/operation-surface.js +118 -41
  30. package/dist/operation-types.js +0 -1
  31. package/dist/operation-view.d.ts +1 -1
  32. package/dist/operation-view.js +232 -82
  33. package/dist/react.js +9 -14
  34. package/dist/registration.js +4 -3
  35. package/dist/runtime.d.ts +4 -2
  36. package/dist/runtime.js +114 -52
  37. package/dist/shared/definition.js +2 -3
  38. package/dist/shared/errors.d.ts +1 -1
  39. package/dist/shared/errors.js +0 -1
  40. package/dist/shared/page-protocol.js +0 -1
  41. package/dist/shared/page-tools.js +2 -3
  42. package/dist/shared/runtime-controller.d.ts +1 -0
  43. package/dist/shared/runtime-controller.js +0 -1
  44. package/dist/shared/runtime-execution.js +0 -1
  45. package/dist/shared/schema.js +45 -19
  46. package/dist/styles.css +882 -109
  47. package/dist/tool-search.d.ts +11 -0
  48. package/dist/tool-search.js +117 -0
  49. package/dist/types.js +0 -1
  50. package/dist/webmcp.js +39 -13
  51. package/package.json +8 -4
  52. package/dist/browser/actions.js.map +0 -1
  53. package/dist/browser/controller.js.map +0 -1
  54. package/dist/browser/diagnostics.js.map +0 -1
  55. package/dist/browser/dom.js.map +0 -1
  56. package/dist/browser/feedback.js.map +0 -1
  57. package/dist/browser/focus.js.map +0 -1
  58. package/dist/browser/locator.js.map +0 -1
  59. package/dist/browser/prompt.generated.js.map +0 -1
  60. package/dist/browser/prompt.js.map +0 -1
  61. package/dist/browser/snapshot.js.map +0 -1
  62. package/dist/browser/toolset.js.map +0 -1
  63. package/dist/browser/types.js.map +0 -1
  64. package/dist/browser/worker-runner.js.map +0 -1
  65. package/dist/definition.js.map +0 -1
  66. package/dist/index.browser.js.map +0 -1
  67. package/dist/index.js.map +0 -1
  68. package/dist/internal-react.js.map +0 -1
  69. package/dist/internal-types.js.map +0 -1
  70. package/dist/navigation.js.map +0 -1
  71. package/dist/operation-lock.js.map +0 -1
  72. package/dist/operation-runtime.js.map +0 -1
  73. package/dist/operation-surface.js.map +0 -1
  74. package/dist/operation-types.js.map +0 -1
  75. package/dist/operation-view.js.map +0 -1
  76. package/dist/react.js.map +0 -1
  77. package/dist/registration.js.map +0 -1
  78. package/dist/runtime.js.map +0 -1
  79. package/dist/shared/definition.js.map +0 -1
  80. package/dist/shared/errors.js.map +0 -1
  81. package/dist/shared/page-protocol.js.map +0 -1
  82. package/dist/shared/page-tools.js.map +0 -1
  83. package/dist/shared/runtime-controller.js.map +0 -1
  84. package/dist/shared/runtime-execution.js.map +0 -1
  85. package/dist/shared/schema.js.map +0 -1
  86. package/dist/types.js.map +0 -1
  87. package/dist/webmcp.js.map +0 -1
@@ -3,7 +3,7 @@ import { type ToolRuntime, type InternalToolRuntime } from "./runtime.js";
3
3
  export interface InternalToolRuntimeHostProps {
4
4
  children: ReactNode;
5
5
  }
6
- export declare function InternalToolRuntimeHost({ children, }: InternalToolRuntimeHostProps): ReactElement;
6
+ export declare function InternalToolRuntimeHost({ children }: InternalToolRuntimeHostProps): ReactElement;
7
7
  export declare function InternalToolRuntimeScope({ children, runtime, }: {
8
8
  children: ReactNode;
9
9
  runtime: ToolRuntime;
@@ -1,10 +1,10 @@
1
1
  import * as React from "react";
2
- import { createContext, useContext, useMemo, } from "react";
2
+ import { createContext, useContext, useMemo } from "react";
3
3
  import { createToolRuntime, getInternalToolRuntime, } from "./runtime.js";
4
4
  const InternalToolRuntimeContext = createContext(null);
5
- export function InternalToolRuntimeHost({ children, }) {
5
+ export function InternalToolRuntimeHost({ children }) {
6
6
  const runtime = useMemo(() => createToolRuntime(), []);
7
- return (React.createElement(InternalToolRuntimeScope, { runtime: runtime }, children));
7
+ return React.createElement(InternalToolRuntimeScope, { runtime: runtime }, children);
8
8
  }
9
9
  export function InternalToolRuntimeScope({ children, runtime, }) {
10
10
  const internalRuntime = getInternalToolRuntime(runtime);
@@ -20,4 +20,3 @@ export function useInternalToolRuntime() {
20
20
  export function useOptionalInternalToolRuntime() {
21
21
  return useContext(InternalToolRuntimeContext);
22
22
  }
23
- //# sourceMappingURL=internal-react.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=internal-types.js.map
@@ -37,4 +37,3 @@ export function getAgentNavigationEntries(navigation) {
37
37
  }
38
38
  return entries;
39
39
  }
40
- //# sourceMappingURL=navigation.js.map
@@ -1,3 +1,3 @@
1
1
  export declare function isOperationSurfaceLocked(surface: HTMLElement): boolean;
2
2
  /** Block user input inside the surface without hiding DOM from page tools. */
3
- export declare function lockOperationSurface(surface: HTMLElement, redirectFocus?: () => void): () => void;
3
+ export declare function lockOperationSurface(surface: HTMLElement): () => void;
@@ -1,36 +1,54 @@
1
- import { isAgentActivation, isAgentFocus } from "./browser/focus.js";
1
+ import { isAgentActivation } from "./browser/focus.js";
2
2
  const lockedSurfaces = new WeakSet();
3
3
  export function isOperationSurfaceLocked(surface) {
4
4
  return lockedSurfaces.has(surface);
5
5
  }
6
6
  /** Block user input inside the surface without hiding DOM from page tools. */
7
- export function lockOperationSurface(surface, redirectFocus) {
7
+ export function lockOperationSurface(surface) {
8
8
  const previousBusy = surface.getAttribute("aria-busy");
9
9
  const block = (event) => {
10
10
  if ((event.type === "submit" || event.type === "reset") && isAgentActivation())
11
11
  return;
12
12
  if (!event.isTrusted)
13
13
  return;
14
- if (event.type === "focus" || event.type === "focusin") {
15
- if (isAgentFocus())
16
- return;
17
- event.stopImmediatePropagation();
18
- if (event.target instanceof HTMLElement)
19
- event.target.blur();
20
- redirectFocus?.();
21
- return;
22
- }
23
- if (event.type === "keydown" && event.key === "Tab") {
24
- event.preventDefault();
25
- event.stopImmediatePropagation();
26
- redirectFocus?.();
27
- return;
28
- }
29
14
  event.preventDefault();
30
15
  event.stopImmediatePropagation();
31
16
  };
32
17
  // Wheel and touch defaults are blocked here: React delegates them passively.
33
- const events = ["focus", "focusin", "mouseenter", "mouseleave", "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "pointerover", "pointerout", "mousedown", "mouseup", "mousemove", "mouseover", "mouseout", "click", "dblclick", "auxclick", "contextmenu", "keydown", "keyup", "beforeinput", "paste", "cut", "drop", "dragstart", "touchstart", "touchmove", "touchend", "touchcancel", "wheel", "submit", "reset"];
18
+ const events = [
19
+ "mouseenter",
20
+ "mouseleave",
21
+ "pointerenter",
22
+ "pointerleave",
23
+ "pointerdown",
24
+ "pointerup",
25
+ "pointermove",
26
+ "pointerover",
27
+ "pointerout",
28
+ "mousedown",
29
+ "mouseup",
30
+ "mousemove",
31
+ "mouseover",
32
+ "mouseout",
33
+ "click",
34
+ "dblclick",
35
+ "auxclick",
36
+ "contextmenu",
37
+ "keydown",
38
+ "keyup",
39
+ "beforeinput",
40
+ "paste",
41
+ "cut",
42
+ "drop",
43
+ "dragstart",
44
+ "touchstart",
45
+ "touchmove",
46
+ "touchend",
47
+ "touchcancel",
48
+ "wheel",
49
+ "submit",
50
+ "reset",
51
+ ];
34
52
  lockedSurfaces.add(surface);
35
53
  surface.setAttribute("aria-busy", "true");
36
54
  for (const name of events)
@@ -45,4 +63,3 @@ export function lockOperationSurface(surface, redirectFocus) {
45
63
  surface.setAttribute("aria-busy", previousBusy);
46
64
  };
47
65
  }
48
- //# sourceMappingURL=operation-lock.js.map
@@ -4,17 +4,24 @@ export class OperationTracker {
4
4
  #unscoped = 0;
5
5
  #executions = new Map();
6
6
  #listeners = new Set();
7
- #snapshot = Object.freeze({ operation: null, executions: Object.freeze([]) });
7
+ #snapshot = Object.freeze({
8
+ operation: null,
9
+ executions: Object.freeze([]),
10
+ });
8
11
  getSnapshot = () => this.#snapshot;
9
12
  subscribe = (listener) => {
10
13
  this.#listeners.add(listener);
11
- return () => { this.#listeners.delete(listener); };
14
+ return () => {
15
+ this.#listeners.delete(listener);
16
+ };
12
17
  };
13
18
  begin(options = {}) {
14
19
  options.signal?.throwIfAborted();
15
20
  const previous = this.#operation;
16
- const replacing = previous && previous.handle === options.replaceWaiting
17
- && previous.snapshot.status === "waiting" && previous.pending === 0;
21
+ const replacing = previous &&
22
+ previous.handle === options.replaceWaiting &&
23
+ previous.snapshot.status === "waiting" &&
24
+ previous.pending === 0;
18
25
  if (this.#unscoped || (previous && !replacing)) {
19
26
  throw new AgentToolError("OPERATION_BUSY", "The Runtime already has an operation or outstanding tool calls.");
20
27
  }
@@ -23,11 +30,22 @@ export class OperationTracker {
23
30
  previous.resolveEnd();
24
31
  }
25
32
  let resolveEnd;
26
- const endPromise = new Promise((resolve) => { resolveEnd = resolve; });
33
+ const endPromise = new Promise((resolve) => {
34
+ resolveEnd = resolve;
35
+ });
27
36
  const id = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`;
28
37
  const operation = {
29
- snapshot: Object.freeze({ id, source: options.source ?? "host", status: "running", hasExecuted: false, canCancel: Boolean(options.onCancel), ...(options.taskProgress ? { taskProgress: Object.freeze(options.taskProgress) } : {}) }),
30
- handle: undefined, pending: 0, resolveEnd,
38
+ snapshot: Object.freeze({
39
+ id,
40
+ source: options.source ?? "host",
41
+ status: "running",
42
+ hasExecuted: false,
43
+ canCancel: Boolean(options.onCancel),
44
+ ...(options.taskProgress ? { taskProgress: Object.freeze(options.taskProgress) } : {}),
45
+ }),
46
+ handle: undefined,
47
+ pending: 0,
48
+ resolveEnd,
31
49
  ...(options.onCancel ? { onCancel: options.onCancel } : {}),
32
50
  removeAbort: () => options.signal?.removeEventListener("abort", onAbort),
33
51
  };
@@ -42,7 +60,11 @@ export class OperationTracker {
42
60
  if (this.#operation !== operation || operation.snapshot.status === "ending")
43
61
  return endPromise;
44
62
  operation.removeAbort();
45
- operation.snapshot = Object.freeze({ ...operation.snapshot, status: "ending", outcome: endOptions?.outcome ?? "completed" });
63
+ operation.snapshot = Object.freeze({
64
+ ...operation.snapshot,
65
+ status: "ending",
66
+ outcome: endOptions?.outcome ?? "completed",
67
+ });
46
68
  this.#publish();
47
69
  if (this.#finish(operation))
48
70
  this.#publish();
@@ -77,8 +99,11 @@ export class OperationTracker {
77
99
  }
78
100
  requestCancel(id) {
79
101
  const operation = this.#operation;
80
- if (!operation || operation.snapshot.id !== id || !operation.onCancel
81
- || operation.snapshot.status === "ending" || operation.snapshot.status === "cancelling")
102
+ if (!operation ||
103
+ operation.snapshot.id !== id ||
104
+ !operation.onCancel ||
105
+ operation.snapshot.status === "ending" ||
106
+ operation.snapshot.status === "cancelling")
82
107
  return;
83
108
  const previous = operation.snapshot.status;
84
109
  this.#update(operation, { status: "cancelling" });
@@ -123,7 +148,9 @@ export class OperationTracker {
123
148
  if (event.status === "running") {
124
149
  this.#executions.set(event.id, event);
125
150
  const operation = this.#operation;
126
- if (operation && event.operationId === operation.snapshot.id && !operation.snapshot.hasExecuted) {
151
+ if (operation &&
152
+ event.operationId === operation.snapshot.id &&
153
+ !operation.snapshot.hasExecuted) {
127
154
  operation.snapshot = Object.freeze({ ...operation.snapshot, hasExecuted: true });
128
155
  }
129
156
  }
@@ -132,7 +159,9 @@ export class OperationTracker {
132
159
  this.#publish();
133
160
  }
134
161
  #finish(operation) {
135
- if (operation.pending || operation.snapshot.status !== "ending" || this.#operation !== operation)
162
+ if (operation.pending ||
163
+ operation.snapshot.status !== "ending" ||
164
+ this.#operation !== operation)
136
165
  return false;
137
166
  this.#operation = undefined;
138
167
  operation.resolveEnd();
@@ -151,4 +180,3 @@ export class OperationTracker {
151
180
  listener();
152
181
  }
153
182
  }
154
- //# sourceMappingURL=operation-runtime.js.map
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { flushSync } from "react-dom";
3
- import { useCallback, useLayoutEffect, useRef, useState } from "react";
3
+ import { useCallback, useLayoutEffect, useRef, useState, } from "react";
4
4
  import { useSyncExternalStore } from "use-sync-external-store/shim";
5
5
  import { PageCommandError } from "./browser/locator.js";
6
6
  import { getInternalToolRuntime } from "./runtime.js";
@@ -9,7 +9,8 @@ import { isAgentActivation } from "./browser/focus.js";
9
9
  import { OperationOverlayView } from "./operation-view.js";
10
10
  const BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction", "nxf_applyAction"]);
11
11
  const belongsToOperation = (event, operation) => !operation || event.operationId === operation.id;
12
- const canPresentInOperation = (event, operation) => belongsToOperation(event, operation) && (!operation || operation.status === "running" || operation.status === "ending");
12
+ const canPresentInOperation = (event, operation) => belongsToOperation(event, operation) &&
13
+ (!operation || operation.status === "running" || operation.status === "ending");
13
14
  const surfaces = new WeakSet();
14
15
  export function AgentOperationSurface(props) {
15
16
  const element = useRef(null);
@@ -21,28 +22,34 @@ export function AgentOperationSurface(props) {
21
22
  if (surfaces.has(props.toolRuntime))
22
23
  throw new Error("Only one AgentOperationSurface is supported per Runtime.");
23
24
  surfaces.add(props.toolRuntime);
24
- return () => { surfaces.delete(props.toolRuntime); };
25
+ return () => {
26
+ surfaces.delete(props.toolRuntime);
27
+ };
25
28
  }, [props.toolRuntime]);
26
29
  const blockUserInput = useCallback((event) => {
27
30
  if ((event.type === "submit" || event.type === "reset") && isAgentActivation())
28
31
  return;
29
- if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted)
32
+ if (!element.current ||
33
+ !isOperationSurfaceLocked(element.current) ||
34
+ !event.nativeEvent.isTrusted)
30
35
  return;
31
36
  event.preventDefault();
32
37
  event.stopPropagation();
33
38
  }, []);
34
39
  const blockPassiveUserInput = useCallback((event) => {
35
- if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted)
40
+ if (!element.current ||
41
+ !isOperationSurfaceLocked(element.current) ||
42
+ !event.nativeEvent.isTrusted)
36
43
  return;
37
44
  // Stop React's capture dispatch, but let the native event reach our non-passive
38
45
  // surface listener. React's passive root listener cannot prevent scrolling.
39
46
  event.isPropagationStopped = () => true;
40
47
  }, []);
41
- return React.createElement(React.Fragment, null,
48
+ return (React.createElement(React.Fragment, null,
42
49
  React.createElement("div", { ref: element, className: "nexface-operation-surface", onClickCapture: blockUserInput, onDoubleClickCapture: blockUserInput, onAuxClickCapture: blockUserInput, onPointerDownCapture: blockUserInput, onPointerUpCapture: blockUserInput, onPointerMoveCapture: blockUserInput, onPointerOverCapture: blockUserInput, onPointerOutCapture: blockUserInput, onMouseDownCapture: blockUserInput, onMouseUpCapture: blockUserInput, onContextMenuCapture: blockUserInput, onMouseMoveCapture: blockUserInput, onMouseOverCapture: blockUserInput, onMouseOutCapture: blockUserInput, onWheelCapture: blockPassiveUserInput, onTouchStartCapture: blockPassiveUserInput, onTouchMoveCapture: blockPassiveUserInput, onTouchEndCapture: blockUserInput, onTouchCancelCapture: blockUserInput, onKeyDownCapture: blockUserInput, onKeyUpCapture: blockUserInput, onKeyPressCapture: blockUserInput, onBeforeInputCapture: blockUserInput, onPasteCapture: blockUserInput, onCutCapture: blockUserInput, onDropCapture: blockUserInput, onDragStartCapture: blockUserInput, onSubmitCapture: blockUserInput, onResetCapture: blockUserInput }, props.children),
43
- React.createElement(OperationSurfaceContent, { ...props, element: element }));
50
+ React.createElement(OperationSurfaceContent, { ...props, element: element })));
44
51
  }
45
- function OperationSurfaceContent({ toolRuntime, element }) {
52
+ function OperationSurfaceContent({ toolRuntime, element, }) {
46
53
  const runtime = getInternalToolRuntime(toolRuntime);
47
54
  const activity = useSyncExternalStore(runtime.subscribeActivity, runtime.getActivitySnapshot, runtime.getActivitySnapshot);
48
55
  const cycle = activity.operation;
@@ -58,15 +65,24 @@ function OperationSurfaceContent({ toolRuntime, element }) {
58
65
  useLayoutEffect(() => runtime.setPageActionFeedback((event, feedback, signal) => {
59
66
  const operation = runtime.getActivitySnapshot().operation;
60
67
  if (signal?.aborted || !canPresentInOperation(event, operation))
61
- throw new PageCommandError({ code: "EXECUTION_CANCELLED", message: "Page action presentation was interrupted." });
68
+ throw new PageCommandError({
69
+ code: "EXECUTION_CANCELLED",
70
+ message: "Page action presentation was interrupted.",
71
+ });
62
72
  const target = feedback.target;
63
- if (!feedback.effect || (feedback.effect === "action" && (!target?.isConnected || !element.current?.contains(target)))) {
73
+ if (!feedback.effect ||
74
+ (feedback.effect === "action" &&
75
+ (!target?.isConnected || !element.current?.contains(target)))) {
64
76
  setVisual(undefined);
65
77
  return;
66
78
  }
67
79
  const next = {
68
- id: crypto.randomUUID(), effect: feedback.effect, label: label(event),
69
- centered: feedback.effect === "read", persistentCursor: true, requiresTarget: feedback.effect === "action",
80
+ id: crypto.randomUUID(),
81
+ effect: feedback.effect,
82
+ label: label(event),
83
+ centered: feedback.effect === "read",
84
+ persistentCursor: true,
85
+ requiresTarget: feedback.effect === "action",
70
86
  ...(target ? { target } : {}),
71
87
  };
72
88
  if (feedback.effect !== "action") {
@@ -98,32 +114,61 @@ function OperationSurfaceContent({ toolRuntime, element }) {
98
114
  const page = BROWSER_TOOL_NAMES.has(event.name);
99
115
  if (canDisplay && event.status === "running") {
100
116
  if (page)
101
- setVisual(event.name === "nxf_getSnapshot" ? { event, feedback: {
102
- id: event.id, effect: "read", label: label(event), centered: true,
103
- } } : undefined);
117
+ setVisual(event.name === "nxf_getSnapshot"
118
+ ? {
119
+ event,
120
+ feedback: {
121
+ id: event.id,
122
+ effect: "read",
123
+ label: label(event),
124
+ centered: true,
125
+ },
126
+ }
127
+ : undefined);
104
128
  else {
105
- const target = event.tool.definition.effect === "navigate" ? element.current : runtime.resolveTarget(event.tool, event.input);
129
+ const target = event.tool.definition.effect === "navigate"
130
+ ? element.current
131
+ : runtime.resolveTarget(event.tool, event.input);
106
132
  if (target?.isConnected && element.current?.contains(target)) {
107
133
  const rect = target.getBoundingClientRect();
108
- setVisual({ event, feedback: { id: event.id, effect: event.tool.definition.effect ?? "action", label: label(event),
109
- resolveTarget: () => event.tool.definition.effect === "navigate" ? element.current ?? undefined : runtime.resolveTarget(event.tool, event.input),
110
- position: { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 } } });
134
+ setVisual({
135
+ event,
136
+ feedback: {
137
+ id: event.id,
138
+ effect: event.tool.definition.effect ?? "action",
139
+ label: label(event),
140
+ resolveTarget: () => event.tool.definition.effect === "navigate"
141
+ ? (element.current ?? undefined)
142
+ : runtime.resolveTarget(event.tool, event.input),
143
+ position: { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 },
144
+ },
145
+ });
111
146
  }
112
147
  }
113
148
  }
114
149
  else if (canDisplay)
115
150
  setVisual((current) => current?.event.id === event.id && current.event.operationId === event.operationId
116
- ? page ? undefined : { ...current, event } : current);
151
+ ? page
152
+ ? undefined
153
+ : { ...current, event }
154
+ : current);
117
155
  if (page && !operation && event.status === "error")
118
156
  setOutcome({ id: scope, status: event.cancelled ? "cancelled" : "failed" });
119
157
  setHistory((current) => {
120
- if (!belongsToOperation(event, operation) || (event.status !== "running" && current.scope !== scope))
158
+ if (!belongsToOperation(event, operation) ||
159
+ (event.status !== "running" && current.scope !== scope))
121
160
  return current;
122
161
  const entries = current.scope === scope ? current.entries : [];
123
- const entry = { toolCallId: event.id,
124
- progressLabel: `${event.progressLabel || "正在处理你的请求"} · ${event.cancelled ? "已取消" : event.status === "running" ? "执行中" : event.status === "success" ? "已完成" : "失败"}` };
125
- return { scope, entries: entries.some((item) => item.toolCallId === event.id)
126
- ? entries.map((item) => item.toolCallId === event.id ? entry : item) : [...entries, entry] };
162
+ const entry = {
163
+ toolCallId: event.id,
164
+ progressLabel: `${event.progressLabel || "正在处理你的请求"} · ${event.cancelled ? "已取消" : event.status === "running" ? "执行中" : event.status === "success" ? "已完成" : "失败"}`,
165
+ };
166
+ return {
167
+ scope,
168
+ entries: entries.some((item) => item.toolCallId === event.id)
169
+ ? entries.map((item) => (item.toolCallId === event.id ? entry : item))
170
+ : [...entries, entry],
171
+ };
127
172
  });
128
173
  };
129
174
  const unsubscribe = toolRuntime.on("toolexecution", onExecution);
@@ -136,25 +181,57 @@ function OperationSurfaceContent({ toolRuntime, element }) {
136
181
  const waiting = cycle?.status === "waiting" && !executing;
137
182
  const running = executing || (activated && cycle?.status !== "waiting");
138
183
  const stopping = cycle?.status === "cancelling";
139
- useLayoutEffect(() => { if (!running || waiting)
140
- setVisual(undefined); }, [running, waiting]);
184
+ useLayoutEffect(() => {
185
+ if (!running || waiting)
186
+ setVisual(undefined);
187
+ }, [running, waiting]);
141
188
  const serverExecuting = cycle?.taskProgress?.phase === "tool";
142
189
  const visualExecuting = Boolean(visual && activity.executions.some((event) => event.id === visual.event.id));
143
- const currentVisual = !stopping && !waiting && visual
144
- && (!serverExecuting || (BROWSER_TOOL_NAMES.has(visual.event.name) && visualExecuting))
145
- && canPresentInOperation(visual.event, cycle) && (cycle || visualExecuting) ? visual : undefined;
190
+ const currentVisual = !stopping &&
191
+ !waiting &&
192
+ visual &&
193
+ (!serverExecuting || (BROWSER_TOOL_NAMES.has(visual.event.name) && visualExecuting)) &&
194
+ canPresentInOperation(visual.event, cycle) &&
195
+ (cycle || visualExecuting)
196
+ ? visual
197
+ : undefined;
146
198
  const browserExecution = activity.executions.find((event) => BROWSER_TOOL_NAMES.has(event.name));
147
- const progressLabel = currentVisual?.feedback.label ?? (waiting ? "等待你完成操作" : stopping ? "正在终止"
148
- : browserExecution ? browserExecution.progressLabel || "正在浏览网页"
149
- : cycle?.taskProgress?.phase === "tool" ? cycle.taskProgress.progressLabel || "正在执行工具"
150
- : cycle?.taskProgress ? "正在处理" : "正在处理你的请求");
151
- const operation = { progressLabel, status: currentVisual
152
- ? currentVisual.event.status === "running" ? "running" : currentVisual.event.status === "success" ? "completed" : "failed"
153
- : running || waiting ? "running" : outcome?.id === history.scope ? outcome.status : "completed" };
154
- const feedback = currentVisual?.feedback ?? (serverExecuting && running && !waiting && !stopping
155
- ? { id: cycle.taskProgress.toolCallId, effect: "read", label: progressLabel, centered: true } : undefined);
199
+ const progressLabel = currentVisual?.feedback.label ??
200
+ (waiting
201
+ ? "等待你完成操作"
202
+ : stopping
203
+ ? "正在终止"
204
+ : browserExecution
205
+ ? browserExecution.progressLabel || "正在浏览网页"
206
+ : cycle?.taskProgress?.phase === "tool"
207
+ ? cycle.taskProgress.progressLabel || "正在执行工具"
208
+ : cycle?.taskProgress
209
+ ? "正在处理"
210
+ : "正在处理你的请求");
211
+ const operation = {
212
+ progressLabel,
213
+ status: currentVisual
214
+ ? currentVisual.event.status === "running"
215
+ ? "running"
216
+ : currentVisual.event.status === "success"
217
+ ? "completed"
218
+ : "failed"
219
+ : running || waiting
220
+ ? "running"
221
+ : outcome?.id === history.scope
222
+ ? outcome.status
223
+ : "completed",
224
+ };
225
+ const feedback = currentVisual?.feedback ??
226
+ (serverExecuting && running && !waiting && !stopping
227
+ ? {
228
+ id: cycle.taskProgress.toolCallId,
229
+ effect: "read",
230
+ label: progressLabel,
231
+ centered: true,
232
+ }
233
+ : undefined);
156
234
  const resolveSurface = useCallback(() => element.current ?? undefined, [element]);
157
235
  const entries = !cycle || history.scope === cycle.id ? history.entries : [];
158
- return activated || executing || entries.length ? React.createElement(OperationOverlayView, { key: cycle?.id ?? history.scope, operation: operation, progressHistory: entries, running: running, humanHasControl: waiting, cancelling: stopping, ...(feedback ? { feedback } : {}), ...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {}), resolveSurface: resolveSurface }) : null;
236
+ return activated || executing || entries.length ? (React.createElement(OperationOverlayView, { key: cycle?.id ?? history.scope, operation: operation, progressHistory: entries, running: running, humanHasControl: waiting, cancelling: stopping, ...(feedback ? { feedback } : {}), ...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {}), resolveSurface: resolveSurface })) : null;
159
237
  }
160
- //# sourceMappingURL=operation-surface.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=operation-types.js.map
@@ -10,4 +10,4 @@ export interface OperationOverlayViewProps {
10
10
  onCancel?(): void;
11
11
  resolveSurface?(): HTMLElement | undefined;
12
12
  }
13
- export declare function OperationOverlayView({ operation, feedback, progressHistory, running, humanHasControl, cancelling, onCancel: cancel, resolveSurface }: OperationOverlayViewProps): React.ReactPortal | null;
13
+ export declare function OperationOverlayView({ operation, feedback, progressHistory, running, humanHasControl, cancelling, onCancel: cancel, resolveSurface, }: OperationOverlayViewProps): React.ReactPortal | null;