@nexface/tools 0.1.4 → 0.1.6

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 (46) hide show
  1. package/dist/browser/actions.d.ts +8 -0
  2. package/dist/browser/actions.js +73 -0
  3. package/dist/browser/actions.js.map +1 -0
  4. package/dist/browser/controller.d.ts +1 -1
  5. package/dist/browser/controller.js +49 -8
  6. package/dist/browser/controller.js.map +1 -1
  7. package/dist/browser/diagnostics.d.ts +1 -0
  8. package/dist/browser/diagnostics.js +20 -0
  9. package/dist/browser/diagnostics.js.map +1 -0
  10. package/dist/browser/dom.js +12 -4
  11. package/dist/browser/dom.js.map +1 -1
  12. package/dist/browser/focus.d.ts +2 -0
  13. package/dist/browser/focus.js +14 -0
  14. package/dist/browser/focus.js.map +1 -1
  15. package/dist/browser/prompt.d.ts +1 -1
  16. package/dist/browser/prompt.generated.d.ts +1 -1
  17. package/dist/browser/prompt.generated.js +9 -2
  18. package/dist/browser/prompt.generated.js.map +1 -1
  19. package/dist/browser/snapshot.d.ts +2 -2
  20. package/dist/browser/snapshot.js +11 -3
  21. package/dist/browser/snapshot.js.map +1 -1
  22. package/dist/browser/toolset.d.ts +4 -1
  23. package/dist/browser/toolset.js +164 -70
  24. package/dist/browser/toolset.js.map +1 -1
  25. package/dist/browser/types.d.ts +21 -2
  26. package/dist/browser/types.js.map +1 -1
  27. package/dist/definition.js +3 -5
  28. package/dist/definition.js.map +1 -1
  29. package/dist/errors.d.ts +1 -1
  30. package/dist/errors.js +1 -0
  31. package/dist/errors.js.map +1 -1
  32. package/dist/internal.d.ts +1 -1
  33. package/dist/internal.js +1 -1
  34. package/dist/internal.js.map +1 -1
  35. package/dist/operation-lock.js +3 -1
  36. package/dist/operation-lock.js.map +1 -1
  37. package/dist/operation-surface.js +49 -3
  38. package/dist/operation-surface.js.map +1 -1
  39. package/dist/operation-view.d.ts +2 -1
  40. package/dist/operation-view.js +54 -33
  41. package/dist/operation-view.js.map +1 -1
  42. package/dist/runtime.d.ts +2 -0
  43. package/dist/runtime.js +27 -6
  44. package/dist/runtime.js.map +1 -1
  45. package/dist/styles.css +3 -0
  46. package/package.json +1 -1
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const TOOL_ERROR_CODES: readonly ["ACTION_IN_FLIGHT", "ACTION_NOT_HANDLED", "ACTION_TARGET_UNAVAILABLE", "BROWSER_EXECUTION_FAILED", "BROWSER_SNAPSHOT_REQUIRED", "BROWSER_TOOLS_UNAVAILABLE", "CONTRACT_MISMATCH", "DUPLICATE_BINDING", "INVALID_INPUT", "INVALID_TOOL_RUNTIME", "OPERATION_BUSY", "TOOL_CANCELLED", "TOOL_CONFIRMATION_INVALIDATED", "TOOL_CONFIRMATION_REJECTED", "TOOL_ERROR", "TOOL_REGISTRATION_TIMEOUT", "TOOL_SKIPPED", "TOOL_UNAVAILABLE", "UNKNOWN_TOOL"];
1
+ export declare const TOOL_ERROR_CODES: readonly ["EXECUTION_OUTCOME_UNKNOWN", "ACTION_IN_FLIGHT", "ACTION_NOT_HANDLED", "ACTION_TARGET_UNAVAILABLE", "BROWSER_EXECUTION_FAILED", "BROWSER_SNAPSHOT_REQUIRED", "BROWSER_TOOLS_UNAVAILABLE", "CONTRACT_MISMATCH", "DUPLICATE_BINDING", "INVALID_INPUT", "INVALID_TOOL_RUNTIME", "OPERATION_BUSY", "TOOL_CANCELLED", "TOOL_CONFIRMATION_INVALIDATED", "TOOL_CONFIRMATION_REJECTED", "TOOL_ERROR", "TOOL_REGISTRATION_TIMEOUT", "TOOL_SKIPPED", "TOOL_UNAVAILABLE", "UNKNOWN_TOOL"];
2
2
  type AgentToolErrorCode = typeof TOOL_ERROR_CODES[number];
3
3
  export declare class AgentToolError extends Error {
4
4
  readonly code: AgentToolErrorCode;
package/dist/errors.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export const TOOL_ERROR_CODES = [
2
+ "EXECUTION_OUTCOME_UNKNOWN",
2
3
  "ACTION_IN_FLIGHT",
3
4
  "ACTION_NOT_HANDLED",
4
5
  "ACTION_TARGET_UNAVAILABLE",
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,kBAAkB;IAClB,oBAAoB;IACpB,2BAA2B;IAC3B,0BAA0B;IAC1B,2BAA2B;IAC3B,2BAA2B;IAC3B,mBAAmB;IACnB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,gBAAgB;IAChB,gBAAgB;IAChB,+BAA+B;IAC/B,4BAA4B;IAC5B,YAAY;IACZ,2BAA2B;IAC3B,cAAc;IACd,kBAAkB;IAClB,cAAc;CACN,CAAC;AAIX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAK5B;IAEA;IANF,IAAI,GAAG,oBAA6B,CAAC;IACrC,MAAM,GAAG,MAAe,CAAC;IAElC,YACW,IAAwB,EACjC,OAAe,EACN,OAAiB;QAE1B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,SAAI,GAAJ,IAAI,CAAoB;QAExB,YAAO,GAAP,OAAO,CAAU;QAG1B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF","sourcesContent":["export const TOOL_ERROR_CODES = [\n \"ACTION_IN_FLIGHT\",\n \"ACTION_NOT_HANDLED\",\n \"ACTION_TARGET_UNAVAILABLE\",\n \"BROWSER_EXECUTION_FAILED\",\n \"BROWSER_SNAPSHOT_REQUIRED\",\n \"BROWSER_TOOLS_UNAVAILABLE\",\n \"CONTRACT_MISMATCH\",\n \"DUPLICATE_BINDING\",\n \"INVALID_INPUT\",\n \"INVALID_TOOL_RUNTIME\",\n \"OPERATION_BUSY\",\n \"TOOL_CANCELLED\",\n \"TOOL_CONFIRMATION_INVALIDATED\",\n \"TOOL_CONFIRMATION_REJECTED\",\n \"TOOL_ERROR\",\n \"TOOL_REGISTRATION_TIMEOUT\",\n \"TOOL_SKIPPED\",\n \"TOOL_UNAVAILABLE\",\n \"UNKNOWN_TOOL\",\n] as const;\n\ntype AgentToolErrorCode = typeof TOOL_ERROR_CODES[number];\n\nexport class AgentToolError extends Error {\n readonly type = \"tool_runtime_error\" as const;\n readonly domain = \"tool\" as const;\n\n constructor(\n readonly code: AgentToolErrorCode,\n message: string,\n readonly details?: unknown,\n ) {\n super(message);\n this.name = \"ToolRuntimeError\";\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,2BAA2B;IAC3B,kBAAkB;IAClB,oBAAoB;IACpB,2BAA2B;IAC3B,0BAA0B;IAC1B,2BAA2B;IAC3B,2BAA2B;IAC3B,mBAAmB;IACnB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,gBAAgB;IAChB,gBAAgB;IAChB,+BAA+B;IAC/B,4BAA4B;IAC5B,YAAY;IACZ,2BAA2B;IAC3B,cAAc;IACd,kBAAkB;IAClB,cAAc;CACN,CAAC;AAIX,MAAM,OAAO,cAAe,SAAQ,KAAK;IAK5B;IAEA;IANF,IAAI,GAAG,oBAA6B,CAAC;IACrC,MAAM,GAAG,MAAe,CAAC;IAElC,YACW,IAAwB,EACjC,OAAe,EACN,OAAiB;QAE1B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,SAAI,GAAJ,IAAI,CAAoB;QAExB,YAAO,GAAP,OAAO,CAAU;QAG1B,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF","sourcesContent":["export const TOOL_ERROR_CODES = [\n \"EXECUTION_OUTCOME_UNKNOWN\",\n \"ACTION_IN_FLIGHT\",\n \"ACTION_NOT_HANDLED\",\n \"ACTION_TARGET_UNAVAILABLE\",\n \"BROWSER_EXECUTION_FAILED\",\n \"BROWSER_SNAPSHOT_REQUIRED\",\n \"BROWSER_TOOLS_UNAVAILABLE\",\n \"CONTRACT_MISMATCH\",\n \"DUPLICATE_BINDING\",\n \"INVALID_INPUT\",\n \"INVALID_TOOL_RUNTIME\",\n \"OPERATION_BUSY\",\n \"TOOL_CANCELLED\",\n \"TOOL_CONFIRMATION_INVALIDATED\",\n \"TOOL_CONFIRMATION_REJECTED\",\n \"TOOL_ERROR\",\n \"TOOL_REGISTRATION_TIMEOUT\",\n \"TOOL_SKIPPED\",\n \"TOOL_UNAVAILABLE\",\n \"UNKNOWN_TOOL\",\n] as const;\n\ntype AgentToolErrorCode = typeof TOOL_ERROR_CODES[number];\n\nexport class AgentToolError extends Error {\n readonly type = \"tool_runtime_error\" as const;\n readonly domain = \"tool\" as const;\n\n constructor(\n readonly code: AgentToolErrorCode,\n message: string,\n readonly details?: unknown,\n ) {\n super(message);\n this.name = \"ToolRuntimeError\";\n }\n}\n"]}
@@ -2,7 +2,7 @@ export { AgentContextError, ToolRuntimeImplementation, ToolRuntimeImplementation
2
2
  export type { ToolRuntime as PublicToolRuntime, ToolRuntimeOptions, ToolOperation, InternalToolRuntime, } from "./runtime.js";
3
3
  export type { AgentToolExecutionEvent } from "./internal-types.js";
4
4
  export { defineSystemAgentTool } from "./definition.js";
5
- export { browserToolsAvailable, createBrowserToolset, executeActionTool, getSnapshotTool, startPageTransitionTracker, } from "./browser/toolset.js";
5
+ export { browserToolsAvailable, createBrowserToolset, executeActionTool, applyActionTool, getSnapshotTool, startPageTransitionTracker, } from "./browser/toolset.js";
6
6
  export { BROWSER_TOOLS_SKILL, serializeBrowserToolsSkill, } from "./browser/prompt.js";
7
7
  export type { BrowserToolHandler, PageAutomationOptions, BrowserToolset, PageTransitionSettleResult, PageTransitionTracker, } from "./browser/toolset.js";
8
8
  export type * from "./browser/types.js";
package/dist/internal.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { AgentContextError, ToolRuntimeImplementation, ToolRuntimeImplementation as ToolRuntime, AgentToolError, createToolRuntime, getInternalToolRuntime, } from "./runtime.js";
2
2
  export { defineSystemAgentTool } from "./definition.js";
3
- export { browserToolsAvailable, createBrowserToolset, executeActionTool, getSnapshotTool, startPageTransitionTracker, } from "./browser/toolset.js";
3
+ export { browserToolsAvailable, createBrowserToolset, executeActionTool, applyActionTool, getSnapshotTool, startPageTransitionTracker, } from "./browser/toolset.js";
4
4
  export { BROWSER_TOOLS_SKILL, serializeBrowserToolsSkill, } from "./browser/prompt.js";
5
5
  export { assertAgentToolInputSchema, validateAgentToolInput } from "./schema.js";
6
6
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,IAAI,WAAW,EACxC,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAQtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAW7B,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export {\n AgentContextError,\n ToolRuntimeImplementation,\n ToolRuntimeImplementation as ToolRuntime,\n AgentToolError,\n createToolRuntime,\n getInternalToolRuntime,\n} from \"./runtime.js\";\nexport type {\n ToolRuntime as PublicToolRuntime,\n ToolRuntimeOptions,\n ToolOperation,\n InternalToolRuntime,\n} from \"./runtime.js\";\nexport type { AgentToolExecutionEvent } from \"./internal-types.js\";\nexport { defineSystemAgentTool } from \"./definition.js\";\nexport {\n browserToolsAvailable,\n createBrowserToolset,\n executeActionTool,\n getSnapshotTool,\n startPageTransitionTracker,\n} from \"./browser/toolset.js\";\nexport {\n BROWSER_TOOLS_SKILL,\n serializeBrowserToolsSkill,\n} from \"./browser/prompt.js\";\nexport type {\n BrowserToolHandler,\n PageAutomationOptions,\n BrowserToolset,\n PageTransitionSettleResult,\n PageTransitionTracker,\n} from \"./browser/toolset.js\";\nexport type * from \"./browser/types.js\";\nexport type { AgentContextRegistration } from \"./types.js\";\n\nexport { assertAgentToolInputSchema, validateAgentToolInput } from \"./schema.js\";\n"]}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,IAAI,WAAW,EACxC,cAAc,EACd,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAQtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAW7B,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export {\n AgentContextError,\n ToolRuntimeImplementation,\n ToolRuntimeImplementation as ToolRuntime,\n AgentToolError,\n createToolRuntime,\n getInternalToolRuntime,\n} from \"./runtime.js\";\nexport type {\n ToolRuntime as PublicToolRuntime,\n ToolRuntimeOptions,\n ToolOperation,\n InternalToolRuntime,\n} from \"./runtime.js\";\nexport type { AgentToolExecutionEvent } from \"./internal-types.js\";\nexport { defineSystemAgentTool } from \"./definition.js\";\nexport {\n browserToolsAvailable,\n createBrowserToolset,\n executeActionTool,\n applyActionTool,\n getSnapshotTool,\n startPageTransitionTracker,\n} from \"./browser/toolset.js\";\nexport {\n BROWSER_TOOLS_SKILL,\n serializeBrowserToolsSkill,\n} from \"./browser/prompt.js\";\nexport type {\n BrowserToolHandler,\n PageAutomationOptions,\n BrowserToolset,\n PageTransitionSettleResult,\n PageTransitionTracker,\n} from \"./browser/toolset.js\";\nexport type * from \"./browser/types.js\";\nexport type { AgentContextRegistration } from \"./types.js\";\n\nexport { assertAgentToolInputSchema, validateAgentToolInput } from \"./schema.js\";\n"]}
@@ -1,4 +1,4 @@
1
- import { isAgentFocus } from "./browser/focus.js";
1
+ import { isAgentActivation, isAgentFocus } from "./browser/focus.js";
2
2
  const lockedSurfaces = new WeakSet();
3
3
  export function isOperationSurfaceLocked(surface) {
4
4
  return lockedSurfaces.has(surface);
@@ -7,6 +7,8 @@ export function isOperationSurfaceLocked(surface) {
7
7
  export function lockOperationSurface(surface, redirectFocus) {
8
8
  const previousBusy = surface.getAttribute("aria-busy");
9
9
  const block = (event) => {
10
+ if ((event.type === "submit" || event.type === "reset") && isAgentActivation())
11
+ return;
10
12
  if (!event.isTrusted)
11
13
  return;
12
14
  if (event.type === "focus" || event.type === "focusin") {
@@ -1 +1 @@
1
- {"version":3,"file":"operation-lock.js","sourceRoot":"","sources":["../src/operation-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,cAAc,GAAG,IAAI,OAAO,EAAe,CAAC;AAElD,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB,CAAC,OAAoB,EAAE,aAA0B;IACnF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE;QAC7B,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACvD,IAAI,YAAY,EAAE;gBAAE,OAAO;YAC3B,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW;gBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7D,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAK,KAAuB,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YACvE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACnC,CAAC,CAAC;IACF,6EAA6E;IAC7E,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChb,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM;QAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACpG,OAAO,GAAG,EAAE;QACV,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,MAAM;YAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1E,IAAI,YAAY,KAAK,IAAI;YAAE,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;;YAC3D,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { isAgentFocus } from \"./browser/focus.js\";\n\nconst lockedSurfaces = new WeakSet<HTMLElement>();\n\nexport function isOperationSurfaceLocked(surface: HTMLElement): boolean {\n return lockedSurfaces.has(surface);\n}\n\n/** Block user input inside the surface without hiding DOM from page tools. */\nexport function lockOperationSurface(surface: HTMLElement, redirectFocus?: () => void): () => void {\n const previousBusy = surface.getAttribute(\"aria-busy\");\n const block = (event: Event) => {\n if (!event.isTrusted) return;\n if (event.type === \"focus\" || event.type === \"focusin\") {\n if (isAgentFocus()) return;\n event.stopImmediatePropagation();\n if (event.target instanceof HTMLElement) event.target.blur();\n redirectFocus?.();\n return;\n }\n if (event.type === \"keydown\" && (event as KeyboardEvent).key === \"Tab\") {\n event.preventDefault();\n event.stopImmediatePropagation();\n redirectFocus?.();\n return;\n }\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n // Wheel and touch defaults are blocked here: React delegates them passively.\n 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\"];\n lockedSurfaces.add(surface);\n surface.setAttribute(\"aria-busy\", \"true\");\n for (const name of events) surface.addEventListener(name, block, { capture: true, passive: false });\n return () => {\n lockedSurfaces.delete(surface);\n for (const name of events) surface.removeEventListener(name, block, true);\n if (previousBusy === null) surface.removeAttribute(\"aria-busy\");\n else surface.setAttribute(\"aria-busy\", previousBusy);\n };\n}\n"]}
1
+ {"version":3,"file":"operation-lock.js","sourceRoot":"","sources":["../src/operation-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,cAAc,GAAG,IAAI,OAAO,EAAe,CAAC;AAElD,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB,CAAC,OAAoB,EAAE,aAA0B;IACnF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,iBAAiB,EAAE;YAAE,OAAO;QACvF,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,OAAO;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACvD,IAAI,YAAY,EAAE;gBAAE,OAAO;YAC3B,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW;gBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7D,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAK,KAAuB,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;YACvE,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;YACjC,aAAa,EAAE,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACnC,CAAC,CAAC;IACF,6EAA6E;IAC7E,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChb,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,MAAM;QAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACpG,OAAO,GAAG,EAAE;QACV,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,MAAM;YAAE,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC1E,IAAI,YAAY,KAAK,IAAI;YAAE,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;;YAC3D,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { isAgentActivation, isAgentFocus } from \"./browser/focus.js\";\n\nconst lockedSurfaces = new WeakSet<HTMLElement>();\n\nexport function isOperationSurfaceLocked(surface: HTMLElement): boolean {\n return lockedSurfaces.has(surface);\n}\n\n/** Block user input inside the surface without hiding DOM from page tools. */\nexport function lockOperationSurface(surface: HTMLElement, redirectFocus?: () => void): () => void {\n const previousBusy = surface.getAttribute(\"aria-busy\");\n const block = (event: Event) => {\n if ((event.type === \"submit\" || event.type === \"reset\") && isAgentActivation()) return;\n if (!event.isTrusted) return;\n if (event.type === \"focus\" || event.type === \"focusin\") {\n if (isAgentFocus()) return;\n event.stopImmediatePropagation();\n if (event.target instanceof HTMLElement) event.target.blur();\n redirectFocus?.();\n return;\n }\n if (event.type === \"keydown\" && (event as KeyboardEvent).key === \"Tab\") {\n event.preventDefault();\n event.stopImmediatePropagation();\n redirectFocus?.();\n return;\n }\n event.preventDefault();\n event.stopImmediatePropagation();\n };\n // Wheel and touch defaults are blocked here: React delegates them passively.\n 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\"];\n lockedSurfaces.add(surface);\n surface.setAttribute(\"aria-busy\", \"true\");\n for (const name of events) surface.addEventListener(name, block, { capture: true, passive: false });\n return () => {\n lockedSurfaces.delete(surface);\n for (const name of events) surface.removeEventListener(name, block, true);\n if (previousBusy === null) surface.removeAttribute(\"aria-busy\");\n else surface.setAttribute(\"aria-busy\", previousBusy);\n };\n}\n"]}
@@ -2,8 +2,9 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useCallback, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { getInternalToolRuntime } from "./runtime.js";
4
4
  import { isOperationSurfaceLocked } from "./operation-lock.js";
5
+ import { isAgentActivation } from "./browser/focus.js";
5
6
  import { OperationOverlayView } from "./operation-view.js";
6
- const BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction"]);
7
+ const CENTER_BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction"]);
7
8
  const surfaces = new WeakSet();
8
9
  export function AgentOperationSurface(props) {
9
10
  const element = useRef(null);
@@ -18,6 +19,8 @@ export function AgentOperationSurface(props) {
18
19
  return () => { surfaces.delete(props.toolRuntime); };
19
20
  }, [props.toolRuntime]);
20
21
  const blockUserInput = useCallback((event) => {
22
+ if ((event.type === "submit" || event.type === "reset") && isAgentActivation())
23
+ return;
21
24
  if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted)
22
25
  return;
23
26
  event.preventDefault();
@@ -49,6 +52,46 @@ function OperationSurfaceContent({ toolRuntime, element }) {
49
52
  setOutcome({ id: current.id, status: current.outcome });
50
53
  }), [runtime]);
51
54
  const [visual, setVisual] = useState();
55
+ const pendingPresentation = useRef(undefined);
56
+ useLayoutEffect(() => {
57
+ const dispose = runtime.setPageActionPresentation((event, signal) => {
58
+ const target = runtime.resolveTarget(event.tool, event.input);
59
+ if (!target || !element.current?.contains(target))
60
+ return Promise.resolve();
61
+ return new Promise((resolve, reject) => {
62
+ let finished = false;
63
+ const settle = (error) => {
64
+ if (finished)
65
+ return;
66
+ finished = true;
67
+ clearTimeout(timer);
68
+ signal?.removeEventListener("abort", finish);
69
+ if (pendingPresentation.current?.id === event.id)
70
+ pendingPresentation.current = undefined;
71
+ if (error)
72
+ reject(error);
73
+ else
74
+ resolve();
75
+ };
76
+ const finish = () => settle();
77
+ const timer = setTimeout(finish, 750);
78
+ pendingPresentation.current = {
79
+ id: event.id,
80
+ finish,
81
+ interrupt: () => settle(new Error("Page action presentation was interrupted.")),
82
+ };
83
+ if (signal?.aborted)
84
+ finish();
85
+ else
86
+ signal?.addEventListener("abort", finish, { once: true });
87
+ });
88
+ });
89
+ return () => { pendingPresentation.current?.interrupt(); dispose(); };
90
+ }, [runtime, element]);
91
+ const onPointerReady = useCallback((id) => {
92
+ if (pendingPresentation.current?.id === id)
93
+ pendingPresentation.current.finish();
94
+ }, []);
52
95
  const [history, setHistory] = useState({ scope: "", entries: [] });
53
96
  useLayoutEffect(() => {
54
97
  const onExecution = (event) => {
@@ -63,9 +106,12 @@ function OperationSurfaceContent({ toolRuntime, element }) {
63
106
  const rect = target.getBoundingClientRect();
64
107
  setVisual({ event, target, position: { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 } });
65
108
  }
66
- else if (BROWSER_TOOL_NAMES.has(event.name)) {
109
+ else if (CENTER_BROWSER_TOOL_NAMES.has(event.name)) {
67
110
  setVisual({ event });
68
111
  }
112
+ else if (event.name === "nxf_applyAction") {
113
+ setVisual(undefined);
114
+ }
69
115
  }
70
116
  else if (canDisplay) {
71
117
  setVisual((current) => current?.event.id === event.id && current.event.operationId === event.operationId
@@ -126,6 +172,6 @@ function OperationSurfaceContent({ toolRuntime, element }) {
126
172
  status: running || waiting ? "running" : outcome?.id === history.scope ? outcome.status : "completed",
127
173
  };
128
174
  const entries = !cycle || history.scope === cycle.id ? history.entries : [];
129
- return activated || executing || entries.length ? _jsx(OperationOverlayView, { operation: operation, progressHistory: entries, running: running, feedbackActive: Boolean(currentVisual) && running && !waiting && !stopping, humanHasControl: waiting, ...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {}), cancelling: cycle?.status === "cancelling" || cycle?.status === "ending", ...(currentVisual?.position ? { fallbackPosition: currentVisual.position } : {}), resolveSurface: resolveSurface, resolveTarget: resolveTarget }) : null;
175
+ return activated || executing || entries.length ? _jsx(OperationOverlayView, { operation: operation, progressHistory: entries, running: running, feedbackActive: Boolean(currentVisual) && running && !waiting && !stopping, humanHasControl: waiting, ...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {}), cancelling: cycle?.status === "cancelling" || cycle?.status === "ending", ...(currentVisual?.position ? { fallbackPosition: currentVisual.position } : {}), resolveSurface: resolveSurface, resolveTarget: resolveTarget, onPointerReady: onPointerReady }) : null;
130
176
  }
131
177
  //# sourceMappingURL=operation-surface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"operation-surface.js","sourceRoot":"","sources":["../src/operation-surface.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState, useSyncExternalStore, type ReactNode, type RefObject, type SyntheticEvent } from \"react\";\nimport type { AgentToolExecutionEvent } from \"./internal-types.js\";\nimport { getInternalToolRuntime, type ToolRuntime } from \"./runtime.js\";\nimport { isOperationSurfaceLocked } from \"./operation-lock.js\";\nimport { OperationOverlayView } from \"./operation-view.js\";\nimport type { AgentOperation, AgentOperationProgressEntry } from \"./operation-types.js\";\n\nconst BROWSER_TOOL_NAMES = new Set([\"nxf_getSnapshot\", \"nxf_executeAction\"]);\n\nexport interface AgentOperationSurfaceProps {\n toolRuntime: ToolRuntime;\n children: ReactNode;\n}\n\nconst surfaces = new WeakSet<ToolRuntime>();\n\nexport function AgentOperationSurface(props: AgentOperationSurfaceProps) {\n const element = useRef<HTMLDivElement>(null);\n const initial = useRef(props.toolRuntime);\n if (initial.current !== props.toolRuntime) {\n throw new Error(\"AgentOperationSurface requires a stable Runtime. Remount it to change Runtime.\");\n }\n useLayoutEffect(() => {\n if (surfaces.has(props.toolRuntime)) throw new Error(\"Only one AgentOperationSurface is supported per Runtime.\");\n surfaces.add(props.toolRuntime);\n return () => { surfaces.delete(props.toolRuntime); };\n }, [props.toolRuntime]);\n const blockUserInput = useCallback((event: SyntheticEvent) => {\n if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted) return;\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const blockPassiveUserInput = useCallback((event: SyntheticEvent) => {\n if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted) return;\n // Stop React's capture dispatch, but let the native event reach our non-passive\n // surface listener. React's passive root listener cannot prevent scrolling.\n event.isPropagationStopped = () => true;\n }, []);\n return <>\n <div ref={element} className=\"nexface-operation-surface\"\n onClickCapture={blockUserInput} onDoubleClickCapture={blockUserInput} onAuxClickCapture={blockUserInput}\n onPointerDownCapture={blockUserInput} onPointerUpCapture={blockUserInput}\n onPointerMoveCapture={blockUserInput} onPointerOverCapture={blockUserInput} onPointerOutCapture={blockUserInput}\n onMouseDownCapture={blockUserInput} onMouseUpCapture={blockUserInput} onContextMenuCapture={blockUserInput}\n onMouseMoveCapture={blockUserInput} onMouseOverCapture={blockUserInput} onMouseOutCapture={blockUserInput}\n onWheelCapture={blockPassiveUserInput} onTouchStartCapture={blockPassiveUserInput} onTouchMoveCapture={blockPassiveUserInput}\n onTouchEndCapture={blockUserInput} onTouchCancelCapture={blockUserInput}\n onKeyDownCapture={blockUserInput} onKeyUpCapture={blockUserInput} onKeyPressCapture={blockUserInput}\n onBeforeInputCapture={blockUserInput} onPasteCapture={blockUserInput} onCutCapture={blockUserInput}\n onDropCapture={blockUserInput} onDragStartCapture={blockUserInput}\n onSubmitCapture={blockUserInput} onResetCapture={blockUserInput}\n >{props.children}</div>\n <OperationSurfaceContent {...props} element={element} />\n </>;\n}\n\nfunction OperationSurfaceContent({ toolRuntime, element }: AgentOperationSurfaceProps & { element: RefObject<HTMLDivElement | null> }) {\n const runtime = getInternalToolRuntime(toolRuntime);\n const activity = useSyncExternalStore(runtime.subscribeActivity, runtime.getActivitySnapshot, runtime.getActivitySnapshot);\n const cycle = activity.operation;\n const [outcome, setOutcome] = useState<{ id: string; status: \"completed\" | \"failed\" | \"cancelled\" }>();\n useLayoutEffect(() => runtime.subscribeActivity(() => {\n const current = runtime.getActivitySnapshot().operation;\n // Task progress does not replace page feedback. Only lifecycle boundaries clear it.\n setVisual((visual) => {\n if (current) return current.status === \"running\" && visual?.event.operationId === current.id ? visual : undefined;\n return visual && runtime.getActivitySnapshot().executions.some((event) => event.id === visual.event.id) ? visual : undefined;\n });\n if (current?.status === \"ending\" && current.outcome) setOutcome({ id: current.id, status: current.outcome });\n }), [runtime]);\n const [visual, setVisual] = useState<{ event: AgentToolExecutionEvent; target?: HTMLElement; position?: { left: number; top: number } }>();\n const [history, setHistory] = useState<{ scope: string; entries: AgentOperationProgressEntry[] }>({ scope: \"\", entries: [] });\n useLayoutEffect(() => {\n const onExecution = (event: AgentToolExecutionEvent) => {\n const scope = event.operationId ?? event.id;\n const operation = runtime.getActivitySnapshot().operation;\n const canDisplay = !event.operationId || (operation?.id === event.operationId && operation.status === \"running\");\n if (canDisplay && event.status === \"running\") {\n const target = event.tool.definition.effect === \"navigate\"\n ? element.current\n : runtime.resolveTarget(event.tool, event.input);\n if (target?.isConnected && element.current?.contains(target)) {\n const rect = target.getBoundingClientRect();\n setVisual({ event, target, position: { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 } });\n } else if (BROWSER_TOOL_NAMES.has(event.name)) {\n setVisual({ event });\n }\n } else if (canDisplay) {\n setVisual((current) => current?.event.id === event.id && current.event.operationId === event.operationId\n ? { ...current, event: { ...current.event, ...event } }\n : current);\n }\n setHistory((current) => {\n if ((operation && event.operationId !== operation.id) || (event.status !== \"running\" && current.scope !== scope)) return current;\n const entries = current.scope === scope ? current.entries : [];\n const entry = {\n toolCallId: event.id,\n progressLabel: `${event.progressLabel || \"正在处理你的请求\"} · ${event.cancelled ? \"已取消\" : event.status === \"running\" ? \"执行中\" : event.status === \"success\" ? \"已完成\" : \"失败\"}`,\n };\n return { scope, entries: entries.some((item) => item.toolCallId === event.id)\n ? entries.map((item) => item.toolCallId === event.id ? entry : item)\n : [...entries, entry] };\n });\n };\n const unsubscribe = toolRuntime.on(\"toolexecution\", onExecution);\n for (const event of runtime.getActivitySnapshot().executions) onExecution(event);\n return unsubscribe;\n }, [runtime, toolRuntime, element]);\n const activated = Boolean(cycle && (cycle.hasStartedTool || cycle.source === \"webmcp\" || cycle.hasExecuted));\n const executing = activity.executions.length > 0;\n const waiting = cycle?.status === \"waiting\" && !executing;\n const running = executing || (activated && cycle?.status !== \"waiting\");\n const stopping = cycle?.status === \"cancelling\" || cycle?.status === \"ending\";\n useLayoutEffect(() => {\n if (!running || waiting) setVisual(undefined);\n }, [running, waiting]);\n const currentVisual = !stopping && !waiting && visual && (cycle\n ? cycle.status === \"running\" && visual.event.operationId === cycle.id\n : activity.executions.some((event) => event.id === visual.event.id)) ? visual : undefined;\n const resolveSurface = useCallback(() => element.current ?? undefined, [element]);\n const resolveTarget = useCallback(() => {\n if (!currentVisual) return undefined;\n const target = currentVisual.target;\n if (target?.isConnected && element.current?.contains(target)\n && (currentVisual.event.tool.definition.effect === \"navigate\" || toolRuntime.getTools().includes(currentVisual.event.tool))) return { element: target };\n return undefined;\n }, [currentVisual, element, toolRuntime]);\n const operation: AgentOperation = currentVisual ? {\n toolCallId: currentVisual.event.id,\n name: currentVisual.event.name,\n input: currentVisual.event.input,\n effect: currentVisual.event.tool.definition.effect,\n progressLabel: currentVisual.event.progressLabel || \"正在处理你的请求\",\n status: currentVisual.event.status === \"running\" ? \"running\" : currentVisual.event.status === \"success\" ? \"completed\" : \"failed\",\n } : {\n toolCallId: cycle?.taskProgress?.phase === \"tool\" ? cycle.taskProgress.toolCallId : cycle?.id ?? history.scope,\n name: \"agent\",\n progressLabel: waiting ? \"等待你完成操作\" : cycle?.status === \"cancelling\" ? \"正在终止\" : cycle?.taskProgress?.phase === \"tool\" ? cycle.taskProgress.progressLabel || \"正在执行工具\" : cycle?.taskProgress ? \"正在处理\" : \"正在处理你的请求\",\n status: running || waiting ? \"running\" : outcome?.id === history.scope ? outcome.status : \"completed\",\n };\n const entries = !cycle || history.scope === cycle.id ? history.entries : [];\n return activated || executing || entries.length ? <OperationOverlayView\n operation={operation}\n progressHistory={entries}\n running={running}\n feedbackActive={Boolean(currentVisual) && running && !waiting && !stopping}\n humanHasControl={waiting}\n {...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {})}\n cancelling={cycle?.status === \"cancelling\" || cycle?.status === \"ending\"}\n {...(currentVisual?.position ? { fallbackPosition: currentVisual.position } : {})}\n resolveSurface={resolveSurface}\n resolveTarget={resolveTarget}\n /> : null;\n}\n"]}
1
+ {"version":3,"file":"operation-surface.js","sourceRoot":"","sources":["../src/operation-surface.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useLayoutEffect, useRef, useState, useSyncExternalStore, type ReactNode, type RefObject, type SyntheticEvent } from \"react\";\nimport type { AgentToolExecutionEvent } from \"./internal-types.js\";\nimport { getInternalToolRuntime, type ToolRuntime } from \"./runtime.js\";\nimport { isOperationSurfaceLocked } from \"./operation-lock.js\";\nimport { isAgentActivation } from \"./browser/focus.js\";\nimport { OperationOverlayView } from \"./operation-view.js\";\nimport type { AgentOperation, AgentOperationProgressEntry } from \"./operation-types.js\";\n\nconst CENTER_BROWSER_TOOL_NAMES = new Set([\"nxf_getSnapshot\", \"nxf_executeAction\"]);\n\nexport interface AgentOperationSurfaceProps {\n toolRuntime: ToolRuntime;\n children: ReactNode;\n}\n\nconst surfaces = new WeakSet<ToolRuntime>();\n\nexport function AgentOperationSurface(props: AgentOperationSurfaceProps) {\n const element = useRef<HTMLDivElement>(null);\n const initial = useRef(props.toolRuntime);\n if (initial.current !== props.toolRuntime) {\n throw new Error(\"AgentOperationSurface requires a stable Runtime. Remount it to change Runtime.\");\n }\n useLayoutEffect(() => {\n if (surfaces.has(props.toolRuntime)) throw new Error(\"Only one AgentOperationSurface is supported per Runtime.\");\n surfaces.add(props.toolRuntime);\n return () => { surfaces.delete(props.toolRuntime); };\n }, [props.toolRuntime]);\n const blockUserInput = useCallback((event: SyntheticEvent) => {\n if ((event.type === \"submit\" || event.type === \"reset\") && isAgentActivation()) return;\n if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted) return;\n event.preventDefault();\n event.stopPropagation();\n }, []);\n const blockPassiveUserInput = useCallback((event: SyntheticEvent) => {\n if (!element.current || !isOperationSurfaceLocked(element.current) || !event.nativeEvent.isTrusted) return;\n // Stop React's capture dispatch, but let the native event reach our non-passive\n // surface listener. React's passive root listener cannot prevent scrolling.\n event.isPropagationStopped = () => true;\n }, []);\n return <>\n <div ref={element} className=\"nexface-operation-surface\"\n onClickCapture={blockUserInput} onDoubleClickCapture={blockUserInput} onAuxClickCapture={blockUserInput}\n onPointerDownCapture={blockUserInput} onPointerUpCapture={blockUserInput}\n onPointerMoveCapture={blockUserInput} onPointerOverCapture={blockUserInput} onPointerOutCapture={blockUserInput}\n onMouseDownCapture={blockUserInput} onMouseUpCapture={blockUserInput} onContextMenuCapture={blockUserInput}\n onMouseMoveCapture={blockUserInput} onMouseOverCapture={blockUserInput} onMouseOutCapture={blockUserInput}\n onWheelCapture={blockPassiveUserInput} onTouchStartCapture={blockPassiveUserInput} onTouchMoveCapture={blockPassiveUserInput}\n onTouchEndCapture={blockUserInput} onTouchCancelCapture={blockUserInput}\n onKeyDownCapture={blockUserInput} onKeyUpCapture={blockUserInput} onKeyPressCapture={blockUserInput}\n onBeforeInputCapture={blockUserInput} onPasteCapture={blockUserInput} onCutCapture={blockUserInput}\n onDropCapture={blockUserInput} onDragStartCapture={blockUserInput}\n onSubmitCapture={blockUserInput} onResetCapture={blockUserInput}\n >{props.children}</div>\n <OperationSurfaceContent {...props} element={element} />\n </>;\n}\n\nfunction OperationSurfaceContent({ toolRuntime, element }: AgentOperationSurfaceProps & { element: RefObject<HTMLDivElement | null> }) {\n const runtime = getInternalToolRuntime(toolRuntime);\n const activity = useSyncExternalStore(runtime.subscribeActivity, runtime.getActivitySnapshot, runtime.getActivitySnapshot);\n const cycle = activity.operation;\n const [outcome, setOutcome] = useState<{ id: string; status: \"completed\" | \"failed\" | \"cancelled\" }>();\n useLayoutEffect(() => runtime.subscribeActivity(() => {\n const current = runtime.getActivitySnapshot().operation;\n // Task progress does not replace page feedback. Only lifecycle boundaries clear it.\n setVisual((visual) => {\n if (current) return current.status === \"running\" && visual?.event.operationId === current.id ? visual : undefined;\n return visual && runtime.getActivitySnapshot().executions.some((event) => event.id === visual.event.id) ? visual : undefined;\n });\n if (current?.status === \"ending\" && current.outcome) setOutcome({ id: current.id, status: current.outcome });\n }), [runtime]);\n const [visual, setVisual] = useState<{ event: AgentToolExecutionEvent; target?: HTMLElement; position?: { left: number; top: number } }>();\n const pendingPresentation = useRef<{ id: string; finish(): void; interrupt(): void } | undefined>(undefined);\n useLayoutEffect(() => {\n const dispose = runtime.setPageActionPresentation((event, signal) => {\n const target = runtime.resolveTarget(event.tool, event.input);\n if (!target || !element.current?.contains(target)) return Promise.resolve();\n return new Promise<void>((resolve, reject) => {\n let finished = false;\n const settle = (error?: Error) => {\n if (finished) return;\n finished = true;\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", finish);\n if (pendingPresentation.current?.id === event.id) pendingPresentation.current = undefined;\n if (error) reject(error);\n else resolve();\n };\n const finish = () => settle();\n const timer = setTimeout(finish, 750);\n pendingPresentation.current = {\n id: event.id,\n finish,\n interrupt: () => settle(new Error(\"Page action presentation was interrupted.\")),\n };\n if (signal?.aborted) finish();\n else signal?.addEventListener(\"abort\", finish, { once: true });\n });\n });\n return () => { pendingPresentation.current?.interrupt(); dispose(); };\n }, [runtime, element]);\n const onPointerReady = useCallback((id: string) => {\n if (pendingPresentation.current?.id === id) pendingPresentation.current.finish();\n }, []);\n const [history, setHistory] = useState<{ scope: string; entries: AgentOperationProgressEntry[] }>({ scope: \"\", entries: [] });\n useLayoutEffect(() => {\n const onExecution = (event: AgentToolExecutionEvent) => {\n const scope = event.operationId ?? event.id;\n const operation = runtime.getActivitySnapshot().operation;\n const canDisplay = !event.operationId || (operation?.id === event.operationId && operation.status === \"running\");\n if (canDisplay && event.status === \"running\") {\n const target = event.tool.definition.effect === \"navigate\"\n ? element.current\n : runtime.resolveTarget(event.tool, event.input);\n if (target?.isConnected && element.current?.contains(target)) {\n const rect = target.getBoundingClientRect();\n setVisual({ event, target, position: { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 } });\n } else if (CENTER_BROWSER_TOOL_NAMES.has(event.name)) {\n setVisual({ event });\n } else if (event.name === \"nxf_applyAction\") {\n setVisual(undefined);\n }\n } else if (canDisplay) {\n setVisual((current) => current?.event.id === event.id && current.event.operationId === event.operationId\n ? { ...current, event: { ...current.event, ...event } }\n : current);\n }\n setHistory((current) => {\n if ((operation && event.operationId !== operation.id) || (event.status !== \"running\" && current.scope !== scope)) return current;\n const entries = current.scope === scope ? current.entries : [];\n const entry = {\n toolCallId: event.id,\n progressLabel: `${event.progressLabel || \"正在处理你的请求\"} · ${event.cancelled ? \"已取消\" : event.status === \"running\" ? \"执行中\" : event.status === \"success\" ? \"已完成\" : \"失败\"}`,\n };\n return { scope, entries: entries.some((item) => item.toolCallId === event.id)\n ? entries.map((item) => item.toolCallId === event.id ? entry : item)\n : [...entries, entry] };\n });\n };\n const unsubscribe = toolRuntime.on(\"toolexecution\", onExecution);\n for (const event of runtime.getActivitySnapshot().executions) onExecution(event);\n return unsubscribe;\n }, [runtime, toolRuntime, element]);\n const activated = Boolean(cycle && (cycle.hasStartedTool || cycle.source === \"webmcp\" || cycle.hasExecuted));\n const executing = activity.executions.length > 0;\n const waiting = cycle?.status === \"waiting\" && !executing;\n const running = executing || (activated && cycle?.status !== \"waiting\");\n const stopping = cycle?.status === \"cancelling\" || cycle?.status === \"ending\";\n useLayoutEffect(() => {\n if (!running || waiting) setVisual(undefined);\n }, [running, waiting]);\n const currentVisual = !stopping && !waiting && visual && (cycle\n ? cycle.status === \"running\" && visual.event.operationId === cycle.id\n : activity.executions.some((event) => event.id === visual.event.id)) ? visual : undefined;\n const resolveSurface = useCallback(() => element.current ?? undefined, [element]);\n const resolveTarget = useCallback(() => {\n if (!currentVisual) return undefined;\n const target = currentVisual.target;\n if (target?.isConnected && element.current?.contains(target)\n && (currentVisual.event.tool.definition.effect === \"navigate\" || toolRuntime.getTools().includes(currentVisual.event.tool))) return { element: target };\n return undefined;\n }, [currentVisual, element, toolRuntime]);\n const operation: AgentOperation = currentVisual ? {\n toolCallId: currentVisual.event.id,\n name: currentVisual.event.name,\n input: currentVisual.event.input,\n effect: currentVisual.event.tool.definition.effect,\n progressLabel: currentVisual.event.progressLabel || \"正在处理你的请求\",\n status: currentVisual.event.status === \"running\" ? \"running\" : currentVisual.event.status === \"success\" ? \"completed\" : \"failed\",\n } : {\n toolCallId: cycle?.taskProgress?.phase === \"tool\" ? cycle.taskProgress.toolCallId : cycle?.id ?? history.scope,\n name: \"agent\",\n progressLabel: waiting ? \"等待你完成操作\" : cycle?.status === \"cancelling\" ? \"正在终止\" : cycle?.taskProgress?.phase === \"tool\" ? cycle.taskProgress.progressLabel || \"正在执行工具\" : cycle?.taskProgress ? \"正在处理\" : \"正在处理你的请求\",\n status: running || waiting ? \"running\" : outcome?.id === history.scope ? outcome.status : \"completed\",\n };\n const entries = !cycle || history.scope === cycle.id ? history.entries : [];\n return activated || executing || entries.length ? <OperationOverlayView\n operation={operation}\n progressHistory={entries}\n running={running}\n feedbackActive={Boolean(currentVisual) && running && !waiting && !stopping}\n humanHasControl={waiting}\n {...(cycle?.canCancel ? { onCancel: () => runtime.requestOperationCancel(cycle.id) } : {})}\n cancelling={cycle?.status === \"cancelling\" || cycle?.status === \"ending\"}\n {...(currentVisual?.position ? { fallbackPosition: currentVisual.position } : {})}\n resolveSurface={resolveSurface}\n resolveTarget={resolveTarget}\n onPointerReady={onPointerReady}\n /> : null;\n}\n"]}
@@ -15,6 +15,7 @@ export interface OperationOverlayViewProps {
15
15
  onCancel?(): void;
16
16
  resolveSurface?(): HTMLElement | undefined;
17
17
  resolveTarget?(operation: AgentOperation): AgentOperationTarget | undefined;
18
+ onPointerReady?(toolCallId: string): void;
18
19
  }
19
- export declare function OperationOverlayView({ operation, progressHistory, running, feedbackActive, labelActive, humanHasControl, cancelling, onCancel, resolveSurface, resolveTarget, fallbackPosition }: OperationOverlayViewProps): import("react").ReactPortal | null;
20
+ export declare function OperationOverlayView({ operation, progressHistory, running, feedbackActive, labelActive, humanHasControl, cancelling, onCancel, resolveSurface, resolveTarget, fallbackPosition, onPointerReady }: OperationOverlayViewProps): import("react").ReactPortal | null;
20
21
  export {};
@@ -2,9 +2,10 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
2
2
  import { CursorIcon as Cursor } from "@phosphor-icons/react/Cursor";
3
3
  import { SparkleIcon as Sparkle } from "@phosphor-icons/react/Sparkle";
4
4
  import { useLayoutEffect, useEffect, useId, useRef, useState } from "react";
5
- import { createPortal } from "react-dom";
5
+ import { createPortal, flushSync } from "react-dom";
6
6
  import { lockOperationSurface } from "./operation-lock.js";
7
- const BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction"]);
7
+ const BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction", "nxf_applyAction"]);
8
+ const CENTER_BROWSER_TOOL_NAMES = new Set(["nxf_getSnapshot", "nxf_executeAction"]);
8
9
  const POINTER_EXIT_DURATION_MS = 120;
9
10
  const CONTROLLER_EXIT_DURATION_MS = 300;
10
11
  function operationProgressLabel(operation) {
@@ -39,12 +40,12 @@ function pointerReachedTarget(element, target) {
39
40
  const rect = element.getBoundingClientRect();
40
41
  return Math.hypot(rect.left - target.left, rect.top - target.top) < 2;
41
42
  }
42
- function AgentPointer({ active, initialPosition, label, labelActive, operation, targetElement, targetPosition, visible }) {
43
+ function AgentPointer({ active, initialPosition, label, labelActive, operation, targetElement, targetPosition, visible, onPointerReady }) {
43
44
  const pointerRef = useRef(null);
44
45
  const activeOperationRef = useRef(undefined);
45
46
  const activeTargetRef = useRef(undefined);
46
47
  const exitTimerRef = useRef(undefined);
47
- const feedbackTimerRef = useRef(undefined);
48
+ const movementTimerRef = useRef(undefined);
48
49
  const motionRevisionRef = useRef(0);
49
50
  const latestActiveRef = useRef(active);
50
51
  const latestOperationRef = useRef(operation);
@@ -57,25 +58,38 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
57
58
  clearTimeout(exitTimerRef.current);
58
59
  exitTimerRef.current = undefined;
59
60
  };
60
- const clearFeedbackTimer = () => {
61
- if (!feedbackTimerRef.current)
61
+ const clearMovementTimer = () => {
62
+ if (!movementTimerRef.current)
62
63
  return;
63
- clearTimeout(feedbackTimerRef.current);
64
- feedbackTimerRef.current = undefined;
64
+ clearTimeout(movementTimerRef.current);
65
+ movementTimerRef.current = undefined;
65
66
  };
66
- const beginFeedback = (revision, toolCallId) => {
67
+ const finishMovement = (revision, toolCallId) => {
67
68
  const latestOperation = latestOperationRef.current;
68
69
  if (!latestActiveRef.current
69
70
  || motionRevisionRef.current !== revision
70
71
  || latestOperation.toolCallId !== toolCallId)
71
72
  return;
72
- setMotion((current) => current?.revision === revision
73
- ? { ...current, phase: "resting" }
74
- : current);
73
+ clearMovementTimer();
74
+ const settle = () => setMotion((current) => current?.revision === revision ? { ...current, phase: "resting" } : current);
75
+ if (latestOperation.name !== "nxf_applyAction" || !onPointerReady) {
76
+ settle();
77
+ return;
78
+ }
79
+ queueMicrotask(() => {
80
+ if (!latestActiveRef.current || motionRevisionRef.current !== revision || latestOperationRef.current.toolCallId !== toolCallId)
81
+ return;
82
+ flushSync(settle);
83
+ requestAnimationFrame(() => requestAnimationFrame(() => {
84
+ if (latestActiveRef.current && motionRevisionRef.current === revision
85
+ && latestOperationRef.current.toolCallId === toolCallId && activeTargetRef.current?.isConnected)
86
+ onPointerReady(toolCallId);
87
+ }));
88
+ });
75
89
  };
76
90
  useEffect(() => () => {
77
91
  clearExitTimer();
78
- clearFeedbackTimer();
92
+ clearMovementTimer();
79
93
  }, []);
80
94
  useEffect(() => {
81
95
  if (!visible || !initialPosition) {
@@ -83,7 +97,7 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
83
97
  return;
84
98
  activeOperationRef.current = undefined;
85
99
  activeTargetRef.current = undefined;
86
- clearFeedbackTimer();
100
+ clearMovementTimer();
87
101
  const revision = ++motionRevisionRef.current;
88
102
  setMotion((current) => current
89
103
  ? { ...current, durationMs: POINTER_EXIT_DURATION_MS, phase: "hidden", revision }
@@ -112,7 +126,7 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
112
126
  if (!active) {
113
127
  activeOperationRef.current = undefined;
114
128
  activeTargetRef.current = undefined;
115
- clearFeedbackTimer();
129
+ clearMovementTimer();
116
130
  if (motion.phase !== "resting") {
117
131
  const revision = ++motionRevisionRef.current;
118
132
  setMotion((current) => current
@@ -125,7 +139,7 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
125
139
  if (operationChanged) {
126
140
  activeOperationRef.current = operation.toolCallId;
127
141
  activeTargetRef.current = undefined;
128
- clearFeedbackTimer();
142
+ clearMovementTimer();
129
143
  }
130
144
  else if (motion.phase === "hidden") {
131
145
  setMotion((current) => current
@@ -133,11 +147,11 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
133
147
  : current);
134
148
  }
135
149
  if (!targetElement || !targetPosition) {
136
- const positionChanged = BROWSER_TOOL_NAMES.has(operation.name)
150
+ const positionChanged = CENTER_BROWSER_TOOL_NAMES.has(operation.name)
137
151
  && (motion.position.left !== initialPosition.left || motion.position.top !== initialPosition.top);
138
152
  if (operationChanged || activeTargetRef.current || positionChanged) {
139
153
  activeTargetRef.current = undefined;
140
- clearFeedbackTimer();
154
+ clearMovementTimer();
141
155
  const revision = ++motionRevisionRef.current;
142
156
  const pointerRect = pointerRef.current?.getBoundingClientRect();
143
157
  setMotion((current) => current
@@ -159,13 +173,20 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
159
173
  if (!targetChanged) {
160
174
  if (motion.position.left === targetPosition.left && motion.position.top === targetPosition.top)
161
175
  return;
176
+ clearMovementTimer();
177
+ const revision = ++motionRevisionRef.current;
178
+ const durationMs = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? 0 : 180;
162
179
  setMotion((current) => current
163
- ? { ...current, durationMs: 180, position: targetPosition }
180
+ ? { ...current, durationMs, phase: "moving", position: targetPosition, revision }
164
181
  : current);
182
+ if (durationMs === 0)
183
+ finishMovement(revision, operation.toolCallId);
184
+ else
185
+ movementTimerRef.current = setTimeout(() => finishMovement(revision, operation.toolCallId), durationMs + 50);
165
186
  return;
166
187
  }
167
188
  activeTargetRef.current = targetElement;
168
- clearFeedbackTimer();
189
+ clearMovementTimer();
169
190
  const revision = ++motionRevisionRef.current;
170
191
  const pointerRect = pointerRef.current?.getBoundingClientRect();
171
192
  const currentPosition = pointerRect
@@ -184,10 +205,10 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
184
205
  }
185
206
  : current);
186
207
  if (durationMs === 0)
187
- beginFeedback(revision, operation.toolCallId);
208
+ finishMovement(revision, operation.toolCallId);
188
209
  else {
189
210
  // A first-frame position update may not dispatch transitionend.
190
- feedbackTimerRef.current = setTimeout(() => beginFeedback(revision, operation.toolCallId), durationMs + 50);
211
+ movementTimerRef.current = setTimeout(() => finishMovement(revision, operation.toolCallId), durationMs + 50);
191
212
  }
192
213
  }, [
193
214
  active,
@@ -204,25 +225,22 @@ function AgentPointer({ active, initialPosition, label, labelActive, operation,
204
225
  return null;
205
226
  const effect = operationEffect(operation);
206
227
  const activeEffect = active ? effect : undefined;
207
- const browserTool = BROWSER_TOOL_NAMES.has(operation.name);
228
+ const browserTool = CENTER_BROWSER_TOOL_NAMES.has(operation.name);
208
229
  return (_jsxs("div", { "aria-hidden": true, className: "agent-operation__pointer-effect", "data-active": active ? "true" : "false", "data-operation-effect": activeEffect, "data-phase": motion.phase, onTransitionEnd: (event) => {
209
230
  if (event.currentTarget !== event.target
210
231
  || event.propertyName !== "transform"
211
232
  || motion.phase !== "moving"
212
233
  || !pointerReachedTarget(event.currentTarget, motion.position))
213
234
  return;
214
- beginFeedback(motion.revision, motion.toolCallId);
235
+ finishMovement(motion.revision, motion.toolCallId);
215
236
  }, ref: pointerRef, style: {
216
237
  "--agent-operation-pointer-duration": `${motion.durationMs}ms`,
217
238
  "--agent-operation-pointer-x": `${motion.position.left}px`,
218
239
  "--agent-operation-pointer-y": `${motion.position.top}px`,
219
- }, children: [active && visible && motion.toolCallId === operation.toolCallId
220
- && browserTool && effect === "action" && motion.phase !== "hidden" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "agent-operation__browser-halo" }), labelActive ? _jsx("span", { className: "agent-operation__browser-label", title: label, children: label }) : null] })) : null, active && visible && motion.toolCallId === operation.toolCallId
221
- && !browserTool && effect === "action"
222
- && motion.phase !== "hidden" ? (_jsx("span", { className: "agent-operation__pointer-cursor", children: _jsx(Cursor, { className: "agent-operation__pointer", size: 24, weight: "fill" }) })) : null, active && (!browserTool || (effect === "read" && visible && motion.toolCallId === operation.toolCallId))
240
+ }, children: [active && visible && motion.toolCallId === operation.toolCallId && browserTool && effect === "action" && motion.phase !== "hidden" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "agent-operation__browser-halo" }), labelActive ? _jsx("span", { className: "agent-operation__browser-label", title: label, children: label }) : null] })) : null, active && visible && motion.toolCallId === operation.toolCallId && !browserTool && effect === "action" && motion.phase !== "hidden" ? (_jsx(_Fragment, { children: _jsx("span", { className: "agent-operation__pointer-cursor", children: _jsx(Cursor, { className: "agent-operation__pointer", size: 24, weight: "fill" }) }) })) : null, active && (!browserTool || (effect === "read" && visible && motion.toolCallId === operation.toolCallId))
223
241
  && motion.phase !== "hidden" && (labelActive || effect !== "action") ? (_jsxs("span", { className: labelActive ? "agent-operation__pointer-label" : "agent-operation__pointer-indicator", "data-browser-tool": browserTool ? "true" : undefined, "data-operation-effect": activeEffect, title: labelActive ? label : undefined, children: [activeEffect === "processing" ? _jsx("span", { className: "agent-operation__pointer-processing" }) : null, activeEffect === "read" ? (_jsxs("span", { className: "agent-operation__pointer-read-scan", children: [_jsx("i", {}), _jsx("i", {}), _jsx("i", {}), _jsx("i", {}), _jsx("i", {})] })) : null, activeEffect === "navigate" ? _jsx("span", { className: "agent-operation__pointer-navigation-trail" }) : null, labelActive ? _jsx("span", { className: "agent-operation__pointer-label-text", children: label }) : null] })) : null] }));
224
242
  }
225
- export function OperationOverlayView({ operation, progressHistory = [], running, feedbackActive = running, labelActive = feedbackActive, humanHasControl = false, cancelling = false, onCancel, resolveSurface, resolveTarget, fallbackPosition }) {
243
+ export function OperationOverlayView({ operation, progressHistory = [], running, feedbackActive = running, labelActive = feedbackActive, humanHasControl = false, cancelling = false, onCancel, resolveSurface, resolveTarget, fallbackPosition, onPointerReady }) {
226
244
  const [, setGeometry] = useState("");
227
245
  useLayoutEffect(() => {
228
246
  const rect = resolveSurface?.()?.getBoundingClientRect();
@@ -310,6 +328,7 @@ export function OperationOverlayView({ operation, progressHistory = [], running,
310
328
  const target = resolvedTarget && (!surfaceElement || surfaceElement.contains(resolvedTarget.element))
311
329
  ? resolvedTarget
312
330
  : undefined;
331
+ const structuredTargetLost = visibleOperation.name === "nxf_applyAction" && !target;
313
332
  const progressLabel = operationProgressLabel(visibleOperation);
314
333
  const effect = operationEffect(visibleOperation);
315
334
  const targetLabel = operationTargetLabel(visibleOperation, target);
@@ -328,8 +347,8 @@ export function OperationOverlayView({ operation, progressHistory = [], running,
328
347
  const highlightedRect = effect === "navigate" ? undefined : rect;
329
348
  const surfaceRect = surfaceElement?.isConnected ? surfaceElement.getBoundingClientRect() : undefined;
330
349
  const agentControlsSurface = running && !humanHasControl;
331
- const operationFeedbackActive = feedbackActive && !humanHasControl && visibleOperation.status !== "cancelled";
332
- const pointerVisible = Boolean(surfaceRect) && feedbackActive && !humanHasControl && visibleOperation.status !== "cancelled";
350
+ const operationFeedbackActive = feedbackActive && !structuredTargetLost && !humanHasControl && visibleOperation.status !== "cancelled";
351
+ const pointerVisible = Boolean(surfaceRect) && operationFeedbackActive;
333
352
  const pointerPosition = rect ? {
334
353
  left: rect.left + rect.width / 2,
335
354
  top: rect.top + rect.height / 2,
@@ -337,7 +356,7 @@ export function OperationOverlayView({ operation, progressHistory = [], running,
337
356
  const cancel = onCancel ? () => {
338
357
  onCancel();
339
358
  } : undefined;
340
- return createPortal(_jsxs("div", { className: "agent-operation", "data-nexface-ignore": true, "data-feedback-active": feedbackActive, "data-human-control": humanHasControl, "data-operation-effect": effect, "data-run-active": running, "data-status": visibleOperation.status, children: [agentControlsSurface && surfaceRect ? _jsx("div", { "aria-hidden": true, className: "agent-operation__surface", style: {
359
+ return createPortal(_jsxs("div", { className: "agent-operation", "data-nexface-ignore": true, "data-feedback-active": operationFeedbackActive, "data-structured-target-lost": structuredTargetLost, "data-human-control": humanHasControl, "data-operation-effect": effect, "data-run-active": running, "data-status": visibleOperation.status, children: [agentControlsSurface && surfaceRect ? _jsx("div", { "aria-hidden": true, className: "agent-operation__surface", style: {
341
360
  ...(highlightedRect ? {
342
361
  "--agent-operation-cutout-height": `${highlightedRect.height}px`,
343
362
  "--agent-operation-cutout-left": `${highlightedRect.left - surfaceRect.left}px`,
@@ -345,6 +364,8 @@ export function OperationOverlayView({ operation, progressHistory = [], running,
345
364
  "--agent-operation-cutout-width": `${highlightedRect.width}px`,
346
365
  } : {}),
347
366
  height: surfaceRect.height, left: surfaceRect.left, top: surfaceRect.top, width: surfaceRect.width,
348
- } }) : null, operationFeedbackActive && highlightedRect ? _jsx("div", { "aria-hidden": true, className: "agent-operation__target", "data-operation-effect": effect, style: { height: highlightedRect.height, left: highlightedRect.left, top: highlightedRect.top, width: highlightedRect.width } }) : null, _jsx(AgentPointer, { active: operationFeedbackActive, initialPosition: pointerPosition ?? fallbackPosition ?? (surfaceRect ? { left: surfaceRect.left + surfaceRect.width / 2, top: surfaceRect.top + surfaceRect.height / 2 } : undefined), label: pointerLabel, labelActive: labelActive, operation: visibleOperation, targetElement: target?.element, targetPosition: pointerPosition, visible: pointerVisible }), controllerMounted ? _jsxs("section", { "aria-live": "polite", className: "agent-operation__controller", "data-visibility": controllerExiting ? "exiting" : "visible", style: surfaceRect ? { left: surfaceRect.left + surfaceRect.width / 2, right: "auto", "--agent-operation-controller-x": "-50%", maxWidth: Math.max(0, surfaceRect.width - 32) } : undefined, children: [historyOpen ? _jsxs("aside", { "aria-label": "\u672C\u6B21\u8FD0\u884C\u7684\u64CD\u4F5C\u8BB0\u5F55", className: "agent-operation__history", id: historyId, children: [_jsxs("header", { children: [_jsx("strong", { children: "\u64CD\u4F5C\u8BB0\u5F55" }), _jsx("span", { children: progressHistory.length })] }), _jsx("ol", { children: progressHistory.map(({ progressLabel: label, toolCallId }, index) => _jsxs("li", { children: [_jsx("span", { "aria-hidden": true, children: index + 1 }), _jsx("p", { children: label })] }, toolCallId)) })] }) : null, _jsx("span", { "aria-hidden": true, className: "agent-operation__edge-flow" }), _jsxs("span", { "aria-hidden": true, className: "agent-operation__pause-mark", children: [_jsx("i", {}), _jsx("i", {})] }), _jsxs("button", { "aria-controls": historyId, "aria-expanded": historyOpen, "aria-label": "\u67E5\u770B\u672C\u6B21\u8FD0\u884C\u7684\u64CD\u4F5C\u8BB0\u5F55", className: "agent-operation__activity", "data-open": historyOpen ? "true" : "false", disabled: progressHistory.length === 0, onClick: () => setHistoryOpen((current) => !current), title: progressHistory.length === 0 ? "暂无操作记录" : "查看本次运行的操作记录", type: "button", children: [_jsx(Sparkle, { className: "agent-operation__activity-icon", size: 16, weight: "fill" }), _jsx("i", {}), _jsx("b", { children: "\u2726" })] }), _jsxs("div", { children: [_jsx("span", { className: "agent-operation__heading", children: _jsx("strong", { children: controllerLabel }) }), statusLabel ? _jsx("small", { className: "agent-operation__description", children: _jsx("span", { className: "agent-operation__status", children: statusLabel }) }) : null] }), (running || humanHasControl) && visibleOperation.status !== "cancelled" ? _jsx("span", { className: "agent-operation__compact-status", title: compactStatusLabel, children: compactStatusLabel }) : null, cancel && (running || humanHasControl) && visibleOperation.status !== "cancelled" ? _jsx("button", { ref: cancelButtonRef, className: "agent-operation__stop", type: "button", disabled: cancelling, onClick: cancel, children: cancelling ? "正在终止" : "终止任务" }) : null] }) : null] }), document.body);
367
+ } }) : null, operationFeedbackActive && highlightedRect ? _jsx("div", { "aria-hidden": true, className: "agent-operation__target", "data-operation-effect": effect, style: { height: highlightedRect.height, left: highlightedRect.left, top: highlightedRect.top, width: highlightedRect.width } }) : null, _jsx(AgentPointer, { active: operationFeedbackActive, initialPosition: visibleOperation.name === "nxf_applyAction" && surfaceRect
368
+ ? { left: surfaceRect.left + surfaceRect.width / 2, top: surfaceRect.top + surfaceRect.height / 2 }
369
+ : pointerPosition ?? fallbackPosition ?? (surfaceRect ? { left: surfaceRect.left + surfaceRect.width / 2, top: surfaceRect.top + surfaceRect.height / 2 } : undefined), label: pointerLabel, labelActive: labelActive, operation: visibleOperation, targetElement: target?.element, targetPosition: pointerPosition, visible: pointerVisible, ...(onPointerReady ? { onPointerReady } : {}) }), controllerMounted ? _jsxs("section", { "aria-live": "polite", className: "agent-operation__controller", "data-visibility": controllerExiting ? "exiting" : "visible", style: surfaceRect ? { left: surfaceRect.left + surfaceRect.width / 2, right: "auto", "--agent-operation-controller-x": "-50%", maxWidth: Math.max(0, surfaceRect.width - 32) } : undefined, children: [historyOpen ? _jsxs("aside", { "aria-label": "\u672C\u6B21\u8FD0\u884C\u7684\u64CD\u4F5C\u8BB0\u5F55", className: "agent-operation__history", id: historyId, children: [_jsxs("header", { children: [_jsx("strong", { children: "\u64CD\u4F5C\u8BB0\u5F55" }), _jsx("span", { children: progressHistory.length })] }), _jsx("ol", { children: progressHistory.map(({ progressLabel: label, toolCallId }, index) => _jsxs("li", { children: [_jsx("span", { "aria-hidden": true, children: index + 1 }), _jsx("p", { children: label })] }, toolCallId)) })] }) : null, _jsx("span", { "aria-hidden": true, className: "agent-operation__edge-flow" }), _jsxs("span", { "aria-hidden": true, className: "agent-operation__pause-mark", children: [_jsx("i", {}), _jsx("i", {})] }), _jsxs("button", { "aria-controls": historyId, "aria-expanded": historyOpen, "aria-label": "\u67E5\u770B\u672C\u6B21\u8FD0\u884C\u7684\u64CD\u4F5C\u8BB0\u5F55", className: "agent-operation__activity", "data-open": historyOpen ? "true" : "false", disabled: progressHistory.length === 0, onClick: () => setHistoryOpen((current) => !current), title: progressHistory.length === 0 ? "暂无操作记录" : "查看本次运行的操作记录", type: "button", children: [_jsx(Sparkle, { className: "agent-operation__activity-icon", size: 16, weight: "fill" }), _jsx("i", {}), _jsx("b", { children: "\u2726" })] }), _jsxs("div", { children: [_jsx("span", { className: "agent-operation__heading", children: _jsx("strong", { children: controllerLabel }) }), statusLabel ? _jsx("small", { className: "agent-operation__description", children: _jsx("span", { className: "agent-operation__status", children: statusLabel }) }) : null] }), (running || humanHasControl) && visibleOperation.status !== "cancelled" ? _jsx("span", { className: "agent-operation__compact-status", title: compactStatusLabel, children: compactStatusLabel }) : null, cancel && (running || humanHasControl) && visibleOperation.status !== "cancelled" ? _jsx("button", { ref: cancelButtonRef, className: "agent-operation__stop", type: "button", disabled: cancelling, onClick: cancel, children: cancelling ? "正在终止" : "终止任务" }) : null] }) : null] }), document.body);
349
370
  }
350
371
  //# sourceMappingURL=operation-view.js.map