@ashx-j/lunr 0.2.25 → 0.2.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +1 -0
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
- package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-computer-use.js +179 -0
- package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
- package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +11 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +3 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +15 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -0
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +5 -3
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts +28 -0
- package/dist/core/computer-use/adapter.d.ts.map +1 -0
- package/dist/core/computer-use/adapter.js +133 -0
- package/dist/core/computer-use/adapter.js.map +1 -0
- package/dist/core/computer-use/image.d.ts +27 -0
- package/dist/core/computer-use/image.d.ts.map +1 -0
- package/dist/core/computer-use/image.js +72 -0
- package/dist/core/computer-use/image.js.map +1 -0
- package/dist/core/computer-use/lease.d.ts +18 -0
- package/dist/core/computer-use/lease.d.ts.map +1 -0
- package/dist/core/computer-use/lease.js +129 -0
- package/dist/core/computer-use/lease.js.map +1 -0
- package/dist/core/computer-use/macos-runtime.d.ts +14 -0
- package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
- package/dist/core/computer-use/macos-runtime.js +148 -0
- package/dist/core/computer-use/macos-runtime.js.map +1 -0
- package/dist/core/computer-use/policy.d.ts +19 -0
- package/dist/core/computer-use/policy.d.ts.map +1 -0
- package/dist/core/computer-use/policy.js +67 -0
- package/dist/core/computer-use/policy.js.map +1 -0
- package/dist/core/computer-use/release.generated.d.ts +31 -0
- package/dist/core/computer-use/release.generated.d.ts.map +1 -0
- package/dist/core/computer-use/release.generated.js +36 -0
- package/dist/core/computer-use/release.generated.js.map +1 -0
- package/dist/core/computer-use/runtime.d.ts +13 -0
- package/dist/core/computer-use/runtime.d.ts.map +1 -0
- package/dist/core/computer-use/runtime.js +158 -0
- package/dist/core/computer-use/runtime.js.map +1 -0
- package/dist/core/computer-use/schemas.d.ts +100 -0
- package/dist/core/computer-use/schemas.d.ts.map +1 -0
- package/dist/core/computer-use/schemas.js +79 -0
- package/dist/core/computer-use/schemas.js.map +1 -0
- package/dist/core/computer-use/windows-desktop.d.ts +3 -0
- package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
- package/dist/core/computer-use/windows-desktop.js +48 -0
- package/dist/core/computer-use/windows-desktop.js.map +1 -0
- package/dist/core/computer-use/workflow.d.ts +38 -0
- package/dist/core/computer-use/workflow.d.ts.map +1 -0
- package/dist/core/computer-use/workflow.js +560 -0
- package/dist/core/computer-use/workflow.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +4 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/permissions.d.ts +1 -1
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +14 -3
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +9 -0
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-event-transport.d.ts +3 -0
- package/dist/core/subagent-event-transport.d.ts.map +1 -0
- package/dist/core/subagent-event-transport.js +61 -0
- package/dist/core/subagent-event-transport.js.map +1 -0
- package/dist/gateway/adapters/discord.d.ts.map +1 -1
- package/dist/gateway/adapters/discord.js +2 -2
- package/dist/gateway/adapters/discord.js.map +1 -1
- package/dist/gateway/approval.d.ts.map +1 -1
- package/dist/gateway/approval.js +3 -3
- package/dist/gateway/approval.js.map +1 -1
- package/dist/gateway/authz.d.ts +4 -4
- package/dist/gateway/authz.d.ts.map +1 -1
- package/dist/gateway/authz.js +8 -12
- package/dist/gateway/authz.js.map +1 -1
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +2 -6
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +20 -6
- package/dist/gateway/cron.js.map +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +3 -3
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/mobile-commands.d.ts.map +1 -1
- package/dist/gateway/mobile-commands.js +8 -8
- package/dist/gateway/mobile-commands.js.map +1 -1
- package/dist/gateway/presenter.d.ts.map +1 -1
- package/dist/gateway/presenter.js +3 -3
- package/dist/gateway/presenter.js.map +1 -1
- package/dist/gateway/router.d.ts.map +1 -1
- package/dist/gateway/router.js +5 -7
- package/dist/gateway/router.js.map +1 -1
- package/dist/gateway/setup.d.ts.map +1 -1
- package/dist/gateway/setup.js +6 -4
- package/dist/gateway/setup.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +8 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +9 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/node-runtime/adapter-VFG7WNPX.js +17 -0
- package/dist/node-runtime/{agent-session-services-YXXFCP5J.js → agent-session-services-5YXS2PLF.js} +10 -8
- package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-I2HIFEMY.js} +3 -2
- package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-2CFDTH5B.js} +7 -3
- package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
- package/dist/node-runtime/{chunk-QTU6AKNJ.js → chunk-3MISGG4S.js} +11 -15
- package/dist/node-runtime/chunk-4SBQAI4T.js +2185 -0
- package/dist/node-runtime/{chunk-TORR5XBV.js → chunk-5B5QN3ZQ.js} +12 -12
- package/dist/node-runtime/chunk-5B6VKFEV.js +180 -0
- package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-5Q4A37RB.js} +15 -104
- package/dist/node-runtime/{chunk-4TLO4PO2.js → chunk-7IQGBKBJ.js} +7 -1401
- package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-D5UCKPBQ.js} +12 -1
- package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-DVQSHCVP.js} +1 -1
- package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-E75WFZ33.js} +2 -2
- package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
- package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-I74LN5JG.js} +15 -0
- package/dist/node-runtime/chunk-IKU6Y7DL.js +287 -0
- package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-L24TPBS4.js} +5 -4
- package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-LJTIVM7I.js} +7 -7
- package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-LWJXTA6Z.js} +274 -2433
- package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-P7XBVXGT.js} +6 -7
- package/dist/node-runtime/{chunk-OVX6X377.js → chunk-PTFBPO3C.js} +1 -1
- package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-RCR3XAQY.js} +34 -6
- package/dist/node-runtime/chunk-RGQAEOM5.js +81 -0
- package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-SN2KSMPQ.js} +6 -3
- package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-SPVDBUOS.js} +1 -1
- package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-T4DA4XE7.js} +19 -19
- package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
- package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-UVWCDQYF.js} +27 -18
- package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-WIF24I7G.js} +21 -5
- package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-X3PGBLQ7.js} +2 -2
- package/dist/node-runtime/chunk-XHIRAZ26.js +108 -0
- package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-YWOJIGFY.js} +1 -1
- package/dist/node-runtime/{command-6WDOYKS6.js → command-FSBU2EVZ.js} +3 -3
- package/dist/node-runtime/{commands-NZLSOHPE.js → commands-EMBQQVVT.js} +4 -2
- package/dist/node-runtime/{commands-QC6VUZJQ.js → commands-NAAL7KNT.js} +5 -4
- package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-4D7UXYU4.js} +7 -4
- package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-DQM333YV.js} +18 -19
- package/dist/node-runtime/index.js +23 -19
- package/dist/node-runtime/{init-HS6NQXSK.js → init-P5AUV77I.js} +4 -2
- package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-NN4YAU44.js} +1 -1
- package/dist/node-runtime/{interactive-mode-Z5M7WYYZ.js → interactive-mode-YOHZVMKX.js} +11 -9
- package/dist/node-runtime/lunr-computer-use-Y23CCDIJ.js +158 -0
- package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-USHC4LXH.js} +6 -4
- package/dist/node-runtime/main.js +16 -14
- package/dist/node-runtime/{mcp-auth-flow-QIXHW6QN.js → mcp-auth-flow-QVLFVLEO.js} +2 -1
- package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-O5LCHL32.js} +4 -3
- package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-Q7BL6KZO.js} +7 -6
- package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-3PHF4KZ4.js} +5 -5
- package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-7IBSSGEW.js} +24 -18
- package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-XQ76CYMT.js} +2 -1
- package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-5FAPSZEZ.js} +7 -4
- package/dist/node-runtime/rpc-entry.js +16 -14
- package/dist/node-runtime/runtime-EFPPD2UW.js +21 -0
- package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-7WVCLI76.js} +3 -2
- package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-DJDM5AHM.js} +2 -1
- package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-PFBWRNUI.js} +10 -9
- package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-LPZ4BHWE.js} +29 -11
- package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-HNMOTNGX.js} +2 -1
- package/dist/node-runtime/workflow-OHPBEFO4.js +637 -0
- package/dist/utils/image-resize-core.d.ts +2 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +10 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/docs/computer-use.md +362 -0
- package/docs/features.md +8 -6
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/install-lock/package-lock.json +3841 -0
- package/install-lock/package.json +18 -0
- package/native/computer-use/LICENSE.md +21 -0
- package/npm-shrinkwrap.json +3822 -0
- package/package.json +15 -9
- package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-RAK2QA2B.js} +3 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
export declare const computerSchemas: {
|
|
3
|
+
computer_load: Type.TObject<{}>;
|
|
4
|
+
computer_apps: Type.TObject<{
|
|
5
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
6
|
+
query: Type.TOptional<Type.TString>;
|
|
7
|
+
include_windows: Type.TOptional<Type.TBoolean>;
|
|
8
|
+
offset: Type.TOptional<Type.TInteger>;
|
|
9
|
+
}>;
|
|
10
|
+
computer_observe: Type.TObject<{
|
|
11
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
12
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
13
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
14
|
+
observation: Type.TOptional<Type.TString>;
|
|
15
|
+
crop: Type.TOptional<Type.TObject<{
|
|
16
|
+
x: Type.TNumber;
|
|
17
|
+
y: Type.TNumber;
|
|
18
|
+
width: Type.TNumber;
|
|
19
|
+
height: Type.TNumber;
|
|
20
|
+
}>>;
|
|
21
|
+
}>;
|
|
22
|
+
computer_click: Type.TObject<{
|
|
23
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
24
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
25
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
26
|
+
observation: Type.TString;
|
|
27
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
28
|
+
x: Type.TNumber;
|
|
29
|
+
y: Type.TNumber;
|
|
30
|
+
button: Type.TOptional<Type.TUnion<[Type.TLiteral<"left">, Type.TLiteral<"right">]>>;
|
|
31
|
+
count: Type.TOptional<Type.TInteger>;
|
|
32
|
+
modifier: Type.TOptional<Type.TArray<Type.TString>>;
|
|
33
|
+
}>;
|
|
34
|
+
computer_hover: Type.TObject<{
|
|
35
|
+
x: Type.TNumber;
|
|
36
|
+
y: Type.TNumber;
|
|
37
|
+
desktop: Type.TLiteral<true>;
|
|
38
|
+
foreground: Type.TLiteral<true>;
|
|
39
|
+
observation: Type.TString;
|
|
40
|
+
}>;
|
|
41
|
+
computer_drag: Type.TObject<{
|
|
42
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
43
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
44
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
45
|
+
observation: Type.TString;
|
|
46
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
47
|
+
from_x: Type.TNumber;
|
|
48
|
+
from_y: Type.TNumber;
|
|
49
|
+
to_x: Type.TNumber;
|
|
50
|
+
to_y: Type.TNumber;
|
|
51
|
+
}>;
|
|
52
|
+
computer_key: Type.TObject<{
|
|
53
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
54
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
55
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
56
|
+
observation: Type.TString;
|
|
57
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
58
|
+
x: Type.TOptional<Type.TNumber>;
|
|
59
|
+
y: Type.TOptional<Type.TNumber>;
|
|
60
|
+
key: Type.TOptional<Type.TString>;
|
|
61
|
+
keys: Type.TOptional<Type.TArray<Type.TString>>;
|
|
62
|
+
}>;
|
|
63
|
+
computer_text: Type.TObject<{
|
|
64
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
65
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
66
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
67
|
+
observation: Type.TString;
|
|
68
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
69
|
+
x: Type.TOptional<Type.TNumber>;
|
|
70
|
+
y: Type.TOptional<Type.TNumber>;
|
|
71
|
+
text: Type.TString;
|
|
72
|
+
}>;
|
|
73
|
+
computer_window: Type.TObject<{
|
|
74
|
+
pid: Type.TInteger;
|
|
75
|
+
window_id: Type.TInteger;
|
|
76
|
+
observation: Type.TString;
|
|
77
|
+
action: Type.TUnion<[Type.TLiteral<"frame">, Type.TLiteral<"focus">]>;
|
|
78
|
+
x: Type.TOptional<Type.TNumber>;
|
|
79
|
+
y: Type.TOptional<Type.TNumber>;
|
|
80
|
+
width: Type.TOptional<Type.TInteger>;
|
|
81
|
+
height: Type.TOptional<Type.TInteger>;
|
|
82
|
+
}>;
|
|
83
|
+
computer_launch: Type.TObject<{
|
|
84
|
+
name: Type.TString;
|
|
85
|
+
}>;
|
|
86
|
+
computer_scroll: Type.TObject<{
|
|
87
|
+
pid: Type.TOptional<Type.TInteger>;
|
|
88
|
+
window_id: Type.TOptional<Type.TInteger>;
|
|
89
|
+
desktop: Type.TOptional<Type.TBoolean>;
|
|
90
|
+
observation: Type.TString;
|
|
91
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
92
|
+
x: Type.TNumber;
|
|
93
|
+
y: Type.TNumber;
|
|
94
|
+
direction: Type.TUnion<[Type.TLiteral<"up">, Type.TLiteral<"down">, Type.TLiteral<"left">, Type.TLiteral<"right">]>;
|
|
95
|
+
amount: Type.TInteger;
|
|
96
|
+
by: Type.TUnion<[Type.TLiteral<"line">, Type.TLiteral<"page">]>;
|
|
97
|
+
}>;
|
|
98
|
+
computer_end: Type.TObject<{}>;
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAmBzC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsF3B,CAAC","sourcesContent":["import { Type } from \"@sinclair/typebox\";\n\nconst target = {\n\tpid: Type.Integer({ minimum: 1 }),\n\twindow_id: Type.Integer({ minimum: 1 }),\n};\nconst observation = Type.String({\n\tdescription: \"Copy the latest image token exactly for this target. Single action, expires after 30 seconds. Failed actions consume it; capture again before acting.\",\n});\nconst grounded = {\n\tpid: Type.Optional(target.pid),\n\twindow_id: Type.Optional(target.window_id),\n\tdesktop: Type.Optional(Type.Boolean({ description: \"Primary desktop instead of a window; requires foreground=true.\" })),\n\tobservation,\n\tforeground: Type.Optional(Type.Boolean({ description: \"Window focus escalation after verified background failure. Settings may forbid it.\" })),\n};\nconst coordinate = Type.Number({ minimum: 0 });\nconst pixels = { x: coordinate, y: coordinate };\nconst optionalPixels = { x: Type.Optional(coordinate), y: Type.Optional(coordinate) };\nexport const computerSchemas = {\n\tcomputer_load: Type.Object({}, { additionalProperties: false }),\n\tcomputer_apps: Type.Object({\n\t\tpid: Type.Optional(target.pid),\n\t\tquery: Type.Optional(Type.String({ minLength: 1, maxLength: 240, description: \"Case-insensitive literal substring in the requested app or window collection before pagination. Omit to list all. Required with include_windows.\" })),\n\t\tinclude_windows: Type.Optional(Type.Boolean({ description: \"With a named app query and no pid, include windows for matching running PIDs (at most 5 PIDs and 50 window rows). Narrow the query or use pid if more match.\" })),\n\t\toffset: Type.Optional(Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER, description: \"Zero-based row offset, default 0. Pass the result's next_offset to retrieve the next 50 apps or windows.\" })),\n\t}, { additionalProperties: false }),\n\tcomputer_observe: Type.Object(\n\t\t{\n\t\t\tpid: Type.Optional(target.pid),\n\t\t\twindow_id: Type.Optional(target.window_id),\n\t\t\tdesktop: Type.Optional(Type.Boolean({ description: \"Capture the primary desktop instead of a window.\" })),\n\t\t\tobservation: Type.Optional(observation),\n\t\t\tcrop: Type.Optional(Type.Object({\n\t\t\t\tx: coordinate,\n\t\t\t\ty: coordinate,\n\t\t\t\twidth: Type.Number({ exclusiveMinimum: 0 }),\n\t\t\t\theight: Type.Number({ exclusiveMinimum: 0 }),\n\t\t\t}, { additionalProperties: false, description: \"Region in the latest returned image's pixels; requires its observation token. Captures fresh pixels. Omit for full target.\" })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_click: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...pixels,\n\t\t\tbutton: Type.Optional(Type.Union([Type.Literal(\"left\"), Type.Literal(\"right\")])),\n\t\t\tcount: Type.Optional(Type.Integer({ minimum: 1, maximum: 2 })),\n\t\t\tmodifier: Type.Optional(Type.Array(Type.String({ minLength: 1 }), { maxItems: 4 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_hover: Type.Object(\n\t\t{\n\t\t\tdesktop: Type.Literal(true, { description: \"Primary desktop only; no window/PID hover.\" }),\n\t\t\tforeground: Type.Literal(true, { description: \"Moves the real pointer to the visible desktop target; foreground control must be allowed.\" }),\n\t\t\tobservation,\n\t\t\t...pixels,\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_drag: Type.Object(\n\t\t{ ...grounded, from_x: coordinate, from_y: coordinate, to_x: coordinate, to_y: coordinate },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_key: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...optionalPixels,\n\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: 100 })),\n\t\t\tkeys: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 100 }), { minItems: 2, maxItems: 5 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_text: Type.Object(\n\t\t{ ...grounded, ...optionalPixels, text: Type.String({ maxLength: 20000 }) },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_window: Type.Object(\n\t\t{\n\t\t\t...target,\n\t\t\tobservation,\n\t\t\taction: Type.Union([Type.Literal(\"frame\"), Type.Literal(\"focus\")]),\n\t\t\tx: Type.Optional(Type.Number()),\n\t\t\ty: Type.Optional(Type.Number()),\n\t\t\twidth: Type.Optional(Type.Integer({ minimum: 1 })),\n\t\t\theight: Type.Optional(Type.Integer({ minimum: 1 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_launch: Type.Object(\n\t\t{ name: Type.String({ minLength: 1, maxLength: 500 }) },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_scroll: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...pixels,\n\t\t\tdirection: Type.Union([Type.Literal(\"up\"), Type.Literal(\"down\"), Type.Literal(\"left\"), Type.Literal(\"right\")]),\n\t\t\tamount: Type.Integer({ minimum: 1, maximum: 50 }),\n\t\t\tby: Type.Union([Type.Literal(\"line\"), Type.Literal(\"page\")]),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_end: Type.Object({}, { additionalProperties: false }),\n};\n"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
const target = {
|
|
3
|
+
pid: Type.Integer({ minimum: 1 }),
|
|
4
|
+
window_id: Type.Integer({ minimum: 1 }),
|
|
5
|
+
};
|
|
6
|
+
const observation = Type.String({
|
|
7
|
+
description: "Copy the latest image token exactly for this target. Single action, expires after 30 seconds. Failed actions consume it; capture again before acting.",
|
|
8
|
+
});
|
|
9
|
+
const grounded = {
|
|
10
|
+
pid: Type.Optional(target.pid),
|
|
11
|
+
window_id: Type.Optional(target.window_id),
|
|
12
|
+
desktop: Type.Optional(Type.Boolean({ description: "Primary desktop instead of a window; requires foreground=true." })),
|
|
13
|
+
observation,
|
|
14
|
+
foreground: Type.Optional(Type.Boolean({ description: "Window focus escalation after verified background failure. Settings may forbid it." })),
|
|
15
|
+
};
|
|
16
|
+
const coordinate = Type.Number({ minimum: 0 });
|
|
17
|
+
const pixels = { x: coordinate, y: coordinate };
|
|
18
|
+
const optionalPixels = { x: Type.Optional(coordinate), y: Type.Optional(coordinate) };
|
|
19
|
+
export const computerSchemas = {
|
|
20
|
+
computer_load: Type.Object({}, { additionalProperties: false }),
|
|
21
|
+
computer_apps: Type.Object({
|
|
22
|
+
pid: Type.Optional(target.pid),
|
|
23
|
+
query: Type.Optional(Type.String({ minLength: 1, maxLength: 240, description: "Case-insensitive literal substring in the requested app or window collection before pagination. Omit to list all. Required with include_windows." })),
|
|
24
|
+
include_windows: Type.Optional(Type.Boolean({ description: "With a named app query and no pid, include windows for matching running PIDs (at most 5 PIDs and 50 window rows). Narrow the query or use pid if more match." })),
|
|
25
|
+
offset: Type.Optional(Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER, description: "Zero-based row offset, default 0. Pass the result's next_offset to retrieve the next 50 apps or windows." })),
|
|
26
|
+
}, { additionalProperties: false }),
|
|
27
|
+
computer_observe: Type.Object({
|
|
28
|
+
pid: Type.Optional(target.pid),
|
|
29
|
+
window_id: Type.Optional(target.window_id),
|
|
30
|
+
desktop: Type.Optional(Type.Boolean({ description: "Capture the primary desktop instead of a window." })),
|
|
31
|
+
observation: Type.Optional(observation),
|
|
32
|
+
crop: Type.Optional(Type.Object({
|
|
33
|
+
x: coordinate,
|
|
34
|
+
y: coordinate,
|
|
35
|
+
width: Type.Number({ exclusiveMinimum: 0 }),
|
|
36
|
+
height: Type.Number({ exclusiveMinimum: 0 }),
|
|
37
|
+
}, { additionalProperties: false, description: "Region in the latest returned image's pixels; requires its observation token. Captures fresh pixels. Omit for full target." })),
|
|
38
|
+
}, { additionalProperties: false }),
|
|
39
|
+
computer_click: Type.Object({
|
|
40
|
+
...grounded,
|
|
41
|
+
...pixels,
|
|
42
|
+
button: Type.Optional(Type.Union([Type.Literal("left"), Type.Literal("right")])),
|
|
43
|
+
count: Type.Optional(Type.Integer({ minimum: 1, maximum: 2 })),
|
|
44
|
+
modifier: Type.Optional(Type.Array(Type.String({ minLength: 1 }), { maxItems: 4 })),
|
|
45
|
+
}, { additionalProperties: false }),
|
|
46
|
+
computer_hover: Type.Object({
|
|
47
|
+
desktop: Type.Literal(true, { description: "Primary desktop only; no window/PID hover." }),
|
|
48
|
+
foreground: Type.Literal(true, { description: "Moves the real pointer to the visible desktop target; foreground control must be allowed." }),
|
|
49
|
+
observation,
|
|
50
|
+
...pixels,
|
|
51
|
+
}, { additionalProperties: false }),
|
|
52
|
+
computer_drag: Type.Object({ ...grounded, from_x: coordinate, from_y: coordinate, to_x: coordinate, to_y: coordinate }, { additionalProperties: false }),
|
|
53
|
+
computer_key: Type.Object({
|
|
54
|
+
...grounded,
|
|
55
|
+
...optionalPixels,
|
|
56
|
+
key: Type.Optional(Type.String({ minLength: 1, maxLength: 100 })),
|
|
57
|
+
keys: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 100 }), { minItems: 2, maxItems: 5 })),
|
|
58
|
+
}, { additionalProperties: false }),
|
|
59
|
+
computer_text: Type.Object({ ...grounded, ...optionalPixels, text: Type.String({ maxLength: 20000 }) }, { additionalProperties: false }),
|
|
60
|
+
computer_window: Type.Object({
|
|
61
|
+
...target,
|
|
62
|
+
observation,
|
|
63
|
+
action: Type.Union([Type.Literal("frame"), Type.Literal("focus")]),
|
|
64
|
+
x: Type.Optional(Type.Number()),
|
|
65
|
+
y: Type.Optional(Type.Number()),
|
|
66
|
+
width: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
67
|
+
height: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
68
|
+
}, { additionalProperties: false }),
|
|
69
|
+
computer_launch: Type.Object({ name: Type.String({ minLength: 1, maxLength: 500 }) }, { additionalProperties: false }),
|
|
70
|
+
computer_scroll: Type.Object({
|
|
71
|
+
...grounded,
|
|
72
|
+
...pixels,
|
|
73
|
+
direction: Type.Union([Type.Literal("up"), Type.Literal("down"), Type.Literal("left"), Type.Literal("right")]),
|
|
74
|
+
amount: Type.Integer({ minimum: 1, maximum: 50 }),
|
|
75
|
+
by: Type.Union([Type.Literal("line"), Type.Literal("page")]),
|
|
76
|
+
}, { additionalProperties: false }),
|
|
77
|
+
computer_end: Type.Object({}, { additionalProperties: false }),
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/core/computer-use/schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@sinclair/typebox\";\n\nconst target = {\n\tpid: Type.Integer({ minimum: 1 }),\n\twindow_id: Type.Integer({ minimum: 1 }),\n};\nconst observation = Type.String({\n\tdescription: \"Copy the latest image token exactly for this target. Single action, expires after 30 seconds. Failed actions consume it; capture again before acting.\",\n});\nconst grounded = {\n\tpid: Type.Optional(target.pid),\n\twindow_id: Type.Optional(target.window_id),\n\tdesktop: Type.Optional(Type.Boolean({ description: \"Primary desktop instead of a window; requires foreground=true.\" })),\n\tobservation,\n\tforeground: Type.Optional(Type.Boolean({ description: \"Window focus escalation after verified background failure. Settings may forbid it.\" })),\n};\nconst coordinate = Type.Number({ minimum: 0 });\nconst pixels = { x: coordinate, y: coordinate };\nconst optionalPixels = { x: Type.Optional(coordinate), y: Type.Optional(coordinate) };\nexport const computerSchemas = {\n\tcomputer_load: Type.Object({}, { additionalProperties: false }),\n\tcomputer_apps: Type.Object({\n\t\tpid: Type.Optional(target.pid),\n\t\tquery: Type.Optional(Type.String({ minLength: 1, maxLength: 240, description: \"Case-insensitive literal substring in the requested app or window collection before pagination. Omit to list all. Required with include_windows.\" })),\n\t\tinclude_windows: Type.Optional(Type.Boolean({ description: \"With a named app query and no pid, include windows for matching running PIDs (at most 5 PIDs and 50 window rows). Narrow the query or use pid if more match.\" })),\n\t\toffset: Type.Optional(Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER, description: \"Zero-based row offset, default 0. Pass the result's next_offset to retrieve the next 50 apps or windows.\" })),\n\t}, { additionalProperties: false }),\n\tcomputer_observe: Type.Object(\n\t\t{\n\t\t\tpid: Type.Optional(target.pid),\n\t\t\twindow_id: Type.Optional(target.window_id),\n\t\t\tdesktop: Type.Optional(Type.Boolean({ description: \"Capture the primary desktop instead of a window.\" })),\n\t\t\tobservation: Type.Optional(observation),\n\t\t\tcrop: Type.Optional(Type.Object({\n\t\t\t\tx: coordinate,\n\t\t\t\ty: coordinate,\n\t\t\t\twidth: Type.Number({ exclusiveMinimum: 0 }),\n\t\t\t\theight: Type.Number({ exclusiveMinimum: 0 }),\n\t\t\t}, { additionalProperties: false, description: \"Region in the latest returned image's pixels; requires its observation token. Captures fresh pixels. Omit for full target.\" })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_click: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...pixels,\n\t\t\tbutton: Type.Optional(Type.Union([Type.Literal(\"left\"), Type.Literal(\"right\")])),\n\t\t\tcount: Type.Optional(Type.Integer({ minimum: 1, maximum: 2 })),\n\t\t\tmodifier: Type.Optional(Type.Array(Type.String({ minLength: 1 }), { maxItems: 4 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_hover: Type.Object(\n\t\t{\n\t\t\tdesktop: Type.Literal(true, { description: \"Primary desktop only; no window/PID hover.\" }),\n\t\t\tforeground: Type.Literal(true, { description: \"Moves the real pointer to the visible desktop target; foreground control must be allowed.\" }),\n\t\t\tobservation,\n\t\t\t...pixels,\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_drag: Type.Object(\n\t\t{ ...grounded, from_x: coordinate, from_y: coordinate, to_x: coordinate, to_y: coordinate },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_key: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...optionalPixels,\n\t\t\tkey: Type.Optional(Type.String({ minLength: 1, maxLength: 100 })),\n\t\t\tkeys: Type.Optional(Type.Array(Type.String({ minLength: 1, maxLength: 100 }), { minItems: 2, maxItems: 5 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_text: Type.Object(\n\t\t{ ...grounded, ...optionalPixels, text: Type.String({ maxLength: 20000 }) },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_window: Type.Object(\n\t\t{\n\t\t\t...target,\n\t\t\tobservation,\n\t\t\taction: Type.Union([Type.Literal(\"frame\"), Type.Literal(\"focus\")]),\n\t\t\tx: Type.Optional(Type.Number()),\n\t\t\ty: Type.Optional(Type.Number()),\n\t\t\twidth: Type.Optional(Type.Integer({ minimum: 1 })),\n\t\t\theight: Type.Optional(Type.Integer({ minimum: 1 })),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_launch: Type.Object(\n\t\t{ name: Type.String({ minLength: 1, maxLength: 500 }) },\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_scroll: Type.Object(\n\t\t{\n\t\t\t...grounded,\n\t\t\t...pixels,\n\t\t\tdirection: Type.Union([Type.Literal(\"up\"), Type.Literal(\"down\"), Type.Literal(\"left\"), Type.Literal(\"right\")]),\n\t\t\tamount: Type.Integer({ minimum: 1, maximum: 50 }),\n\t\t\tby: Type.Union([Type.Literal(\"line\"), Type.Literal(\"page\")]),\n\t\t},\n\t\t{ additionalProperties: false },\n\t),\n\tcomputer_end: Type.Object({}, { additionalProperties: false }),\n};\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const WINDOWS_DESKTOP_PROBE = "\n$ErrorActionPreference = 'Stop'\nAdd-Type -TypeDefinition @'\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Text;\npublic static class LunrDesktopProbe {\n [DllImport(\"user32.dll\", SetLastError=true)] static extern IntPtr OpenInputDesktop(uint flags, bool inherit, uint access);\n [DllImport(\"user32.dll\")] static extern bool CloseDesktop(IntPtr desktop);\n [DllImport(\"user32.dll\", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool GetUserObjectInformation(IntPtr handle, int index, StringBuilder info, uint length, out uint needed);\n [DllImport(\"wtsapi32.dll\", SetLastError=true)] static extern bool WTSQuerySessionInformation(IntPtr server, int session, int info, out IntPtr buffer, out uint bytes);\n [DllImport(\"wtsapi32.dll\")] static extern void WTSFreeMemory(IntPtr buffer);\n public static bool Ready() {\n int session = Process.GetCurrentProcess().SessionId;\n if (session == 0) return false;\n IntPtr buffer; uint bytes;\n if (!WTSQuerySessionInformation(IntPtr.Zero, session, 8, out buffer, out bytes)) return false;\n try { if (bytes < 4 || Marshal.ReadInt32(buffer) != 0) return false; }\n finally { WTSFreeMemory(buffer); }\n IntPtr desktop = OpenInputDesktop(0, false, 1);\n if (desktop == IntPtr.Zero) return false;\n try {\n var name = new StringBuilder(256); uint needed;\n return GetUserObjectInformation(desktop, 2, name, 512, out needed) && name.ToString() == \"Default\";\n } finally { CloseDesktop(desktop); }\n }\n}\n'@\nif ([LunrDesktopProbe]::Ready()) { 'ready' } else { 'unavailable' }\n";
|
|
2
|
+
export declare function assertInteractiveDesktop(signal?: AbortSignal): Promise<void>;
|
|
3
|
+
//# sourceMappingURL=windows-desktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windows-desktop.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/windows-desktop.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,wkDA8BjC,CAAC;AAEF,wBAAsB,wBAAwB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBlF","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\nexport const WINDOWS_DESKTOP_PROBE = `\n$ErrorActionPreference = 'Stop'\nAdd-Type -TypeDefinition @'\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Text;\npublic static class LunrDesktopProbe {\n [DllImport(\"user32.dll\", SetLastError=true)] static extern IntPtr OpenInputDesktop(uint flags, bool inherit, uint access);\n [DllImport(\"user32.dll\")] static extern bool CloseDesktop(IntPtr desktop);\n [DllImport(\"user32.dll\", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool GetUserObjectInformation(IntPtr handle, int index, StringBuilder info, uint length, out uint needed);\n [DllImport(\"wtsapi32.dll\", SetLastError=true)] static extern bool WTSQuerySessionInformation(IntPtr server, int session, int info, out IntPtr buffer, out uint bytes);\n [DllImport(\"wtsapi32.dll\")] static extern void WTSFreeMemory(IntPtr buffer);\n public static bool Ready() {\n int session = Process.GetCurrentProcess().SessionId;\n if (session == 0) return false;\n IntPtr buffer; uint bytes;\n if (!WTSQuerySessionInformation(IntPtr.Zero, session, 8, out buffer, out bytes)) return false;\n try { if (bytes < 4 || Marshal.ReadInt32(buffer) != 0) return false; }\n finally { WTSFreeMemory(buffer); }\n IntPtr desktop = OpenInputDesktop(0, false, 1);\n if (desktop == IntPtr.Zero) return false;\n try {\n var name = new StringBuilder(256); uint needed;\n return GetUserObjectInformation(desktop, 2, name, 512, out needed) && name.ToString() == \"Default\";\n } finally { CloseDesktop(desktop); }\n }\n}\n'@\nif ([LunrDesktopProbe]::Ready()) { 'ready' } else { 'unavailable' }\n`;\n\nexport async function assertInteractiveDesktop(signal?: AbortSignal): Promise<void> {\n\tif (process.platform !== \"win32\") return;\n\tconst command = join(\n\t\tprocess.env.SystemRoot ?? \"C:\\\\Windows\",\n\t\t\"System32\",\n\t\t\"WindowsPowerShell\",\n\t\t\"v1.0\",\n\t\t\"powershell.exe\",\n\t);\n\tconst { stdout } = await exec(command, [\"-NoProfile\", \"-NonInteractive\", \"-Command\", WINDOWS_DESKTOP_PROBE], {\n\t\ttimeout: 5000,\n\t\twindowsHide: true,\n\t\tsignal,\n\t});\n\tif (stdout.trim() !== \"ready\")\n\t\tthrow new Error(\n\t\t\t\"Computer use requires an active, unlocked Windows desktop. No login, unlock, or elevation is attempted.\",\n\t\t);\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
const exec = promisify(execFile);
|
|
5
|
+
export const WINDOWS_DESKTOP_PROBE = `
|
|
6
|
+
$ErrorActionPreference = 'Stop'
|
|
7
|
+
Add-Type -TypeDefinition @'
|
|
8
|
+
using System;
|
|
9
|
+
using System.Diagnostics;
|
|
10
|
+
using System.Runtime.InteropServices;
|
|
11
|
+
using System.Text;
|
|
12
|
+
public static class LunrDesktopProbe {
|
|
13
|
+
[DllImport("user32.dll", SetLastError=true)] static extern IntPtr OpenInputDesktop(uint flags, bool inherit, uint access);
|
|
14
|
+
[DllImport("user32.dll")] static extern bool CloseDesktop(IntPtr desktop);
|
|
15
|
+
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool GetUserObjectInformation(IntPtr handle, int index, StringBuilder info, uint length, out uint needed);
|
|
16
|
+
[DllImport("wtsapi32.dll", SetLastError=true)] static extern bool WTSQuerySessionInformation(IntPtr server, int session, int info, out IntPtr buffer, out uint bytes);
|
|
17
|
+
[DllImport("wtsapi32.dll")] static extern void WTSFreeMemory(IntPtr buffer);
|
|
18
|
+
public static bool Ready() {
|
|
19
|
+
int session = Process.GetCurrentProcess().SessionId;
|
|
20
|
+
if (session == 0) return false;
|
|
21
|
+
IntPtr buffer; uint bytes;
|
|
22
|
+
if (!WTSQuerySessionInformation(IntPtr.Zero, session, 8, out buffer, out bytes)) return false;
|
|
23
|
+
try { if (bytes < 4 || Marshal.ReadInt32(buffer) != 0) return false; }
|
|
24
|
+
finally { WTSFreeMemory(buffer); }
|
|
25
|
+
IntPtr desktop = OpenInputDesktop(0, false, 1);
|
|
26
|
+
if (desktop == IntPtr.Zero) return false;
|
|
27
|
+
try {
|
|
28
|
+
var name = new StringBuilder(256); uint needed;
|
|
29
|
+
return GetUserObjectInformation(desktop, 2, name, 512, out needed) && name.ToString() == "Default";
|
|
30
|
+
} finally { CloseDesktop(desktop); }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
'@
|
|
34
|
+
if ([LunrDesktopProbe]::Ready()) { 'ready' } else { 'unavailable' }
|
|
35
|
+
`;
|
|
36
|
+
export async function assertInteractiveDesktop(signal) {
|
|
37
|
+
if (process.platform !== "win32")
|
|
38
|
+
return;
|
|
39
|
+
const command = join(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
40
|
+
const { stdout } = await exec(command, ["-NoProfile", "-NonInteractive", "-Command", WINDOWS_DESKTOP_PROBE], {
|
|
41
|
+
timeout: 5000,
|
|
42
|
+
windowsHide: true,
|
|
43
|
+
signal,
|
|
44
|
+
});
|
|
45
|
+
if (stdout.trim() !== "ready")
|
|
46
|
+
throw new Error("Computer use requires an active, unlocked Windows desktop. No login, unlock, or elevation is attempted.");
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=windows-desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windows-desktop.js","sourceRoot":"","sources":["../../../src/core/computer-use/windows-desktop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AACjC,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BpC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAoB,EAAiB;IACnF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IACzC,MAAM,OAAO,GAAG,IAAI,CACnB,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,aAAa,EACvC,UAAU,EACV,mBAAmB,EACnB,MAAM,EACN,gBAAgB,CAChB,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,qBAAqB,CAAC,EAAE;QAC5G,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,IAAI;QACjB,MAAM;KACN,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,OAAO;QAC5B,MAAM,IAAI,KAAK,CACd,yGAAyG,CACzG,CAAC;AAAA,CACH","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst exec = promisify(execFile);\nexport const WINDOWS_DESKTOP_PROBE = `\n$ErrorActionPreference = 'Stop'\nAdd-Type -TypeDefinition @'\nusing System;\nusing System.Diagnostics;\nusing System.Runtime.InteropServices;\nusing System.Text;\npublic static class LunrDesktopProbe {\n [DllImport(\"user32.dll\", SetLastError=true)] static extern IntPtr OpenInputDesktop(uint flags, bool inherit, uint access);\n [DllImport(\"user32.dll\")] static extern bool CloseDesktop(IntPtr desktop);\n [DllImport(\"user32.dll\", CharSet=CharSet.Unicode, SetLastError=true)] static extern bool GetUserObjectInformation(IntPtr handle, int index, StringBuilder info, uint length, out uint needed);\n [DllImport(\"wtsapi32.dll\", SetLastError=true)] static extern bool WTSQuerySessionInformation(IntPtr server, int session, int info, out IntPtr buffer, out uint bytes);\n [DllImport(\"wtsapi32.dll\")] static extern void WTSFreeMemory(IntPtr buffer);\n public static bool Ready() {\n int session = Process.GetCurrentProcess().SessionId;\n if (session == 0) return false;\n IntPtr buffer; uint bytes;\n if (!WTSQuerySessionInformation(IntPtr.Zero, session, 8, out buffer, out bytes)) return false;\n try { if (bytes < 4 || Marshal.ReadInt32(buffer) != 0) return false; }\n finally { WTSFreeMemory(buffer); }\n IntPtr desktop = OpenInputDesktop(0, false, 1);\n if (desktop == IntPtr.Zero) return false;\n try {\n var name = new StringBuilder(256); uint needed;\n return GetUserObjectInformation(desktop, 2, name, 512, out needed) && name.ToString() == \"Default\";\n } finally { CloseDesktop(desktop); }\n }\n}\n'@\nif ([LunrDesktopProbe]::Ready()) { 'ready' } else { 'unavailable' }\n`;\n\nexport async function assertInteractiveDesktop(signal?: AbortSignal): Promise<void> {\n\tif (process.platform !== \"win32\") return;\n\tconst command = join(\n\t\tprocess.env.SystemRoot ?? \"C:\\\\Windows\",\n\t\t\"System32\",\n\t\t\"WindowsPowerShell\",\n\t\t\"v1.0\",\n\t\t\"powershell.exe\",\n\t);\n\tconst { stdout } = await exec(command, [\"-NoProfile\", \"-NonInteractive\", \"-Command\", WINDOWS_DESKTOP_PROBE], {\n\t\ttimeout: 5000,\n\t\twindowsHide: true,\n\t\tsignal,\n\t});\n\tif (stdout.trim() !== \"ready\")\n\t\tthrow new Error(\n\t\t\t\"Computer use requires an active, unlocked Windows desktop. No login, unlock, or elevation is attempted.\",\n\t\t);\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ImageContent, TextContent } from "@ashx-j/lunr-ai";
|
|
2
|
+
import { type ComputerDriver, type DriverReply } from "./adapter.ts";
|
|
3
|
+
import { DesktopLease } from "./lease.ts";
|
|
4
|
+
export declare function driverData(reply: DriverReply): Record<string, unknown>;
|
|
5
|
+
export declare function driverRefused(reply: DriverReply): boolean;
|
|
6
|
+
type WorkflowState = "ready" | "stopped" | "cleanup_unconfirmed";
|
|
7
|
+
type Result = {
|
|
8
|
+
content: (ImageContent | TextContent)[];
|
|
9
|
+
details: {
|
|
10
|
+
observation?: string;
|
|
11
|
+
computer: {
|
|
12
|
+
failed: boolean;
|
|
13
|
+
workflow: WorkflowState;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
isError: boolean;
|
|
17
|
+
};
|
|
18
|
+
export declare class ComputerWorkflow {
|
|
19
|
+
private observation?;
|
|
20
|
+
private lastCapture?;
|
|
21
|
+
private lastAction?;
|
|
22
|
+
private readonly abort;
|
|
23
|
+
private closing?;
|
|
24
|
+
private readonly driver;
|
|
25
|
+
private readonly lease;
|
|
26
|
+
constructor(driver: ComputerDriver, lease?: DesktopLease);
|
|
27
|
+
private fresh;
|
|
28
|
+
private capture;
|
|
29
|
+
private imageResult;
|
|
30
|
+
private crop;
|
|
31
|
+
private action;
|
|
32
|
+
execute(name: string, input: Record<string, unknown>, signal?: AbortSignal): Promise<Result>;
|
|
33
|
+
private finish;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
private stop;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/workflow.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,cAAc,EAAmB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWtE;AAaD,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAWzD;AAsHD,KAAK,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,qBAAqB,CAAC;AACjE,KAAK,MAAM,GAAG;IAAE,OAAO,EAAE,CAAC,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE;YAAE,MAAM,EAAE,OAAO,CAAC;YAAC,QAAQ,EAAE,aAAa,CAAA;SAAE,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAiBvK,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,WAAW,CAAC,CAA2D;IAC/E,OAAO,CAAC,UAAU,CAAC,CAAiE;IACpF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,YAAY,MAAM,EAAE,cAAc,EAAE,KAAK,eAAqB,EAI7D;IAED,OAAO,CAAC,KAAK;YAQC,OAAO;IAwBrB,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,IAAI;IAcZ,OAAO,CAAC,MAAM;IAuER,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA6LjG;YAEa,MAAM;IAUpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrB;YAEa,IAAI;CAIlB","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport type { ImageContent, TextContent } from \"@ashx-j/lunr-ai\";\nimport { type ComputerDriver, DriverCallError, type DriverReply } from \"./adapter.ts\";\nimport { type ImageRegion, prepareComputerImage, screenshotDimensions } from \"./image.ts\";\nimport { DesktopLease } from \"./lease.ts\";\nimport { computerSchemas } from \"./schemas.ts\";\n\nexport function driverData(reply: DriverReply): Record<string, unknown> {\n\tif (reply.structuredContent && typeof reply.structuredContent === \"object\" && !Array.isArray(reply.structuredContent))\n\t\treturn Object.fromEntries(Object.entries(reply.structuredContent));\n\tif (Array.isArray(reply.content)) for (const item of reply.content) {\n\t\tif (item.type !== \"text\" || typeof item.text !== \"string\") continue;\n\t\ttry {\n\t\t\tconst value: unknown = JSON.parse(item.text);\n\t\t\tif (value && typeof value === \"object\" && !Array.isArray(value)) return Object.fromEntries(Object.entries(value));\n\t\t} catch {}\n\t}\n\treturn {};\n}\n\nfunction plainLaunchReason(reply: DriverReply): string | undefined {\n\tif (reply.structuredContent || !Array.isArray(reply.content)) return undefined;\n\tconst text = reply.content.find((item) => item.type === \"text\")?.text;\n\tif (typeof text !== \"string\") return undefined;\n\tif (/^App name lookup for .+ is (?:temporarily unavailable|unavailable).+No app was launched;/s.test(text)) return \"app_lookup_unavailable\";\n\tif (/^App .+ was not found in shell:AppsFolder or by Windows PATH\\/association lookup:/s.test(text)) return \"app_not_found\";\n\tif (/^Launch of .+ timed out after 15s/s.test(text)) return \"launch_timeout_unknown\";\n\tif (/^(?:Failed to launch|Task error): /s.test(text)) return \"launch_native_error_unknown\";\n\treturn undefined;\n}\n\nexport function driverRefused(reply: DriverReply): boolean {\n\tconst data = driverData(reply);\n\tconst acknowledged = data.activated === true || data.success === true || data.verified === true || data.effect === \"confirmed\";\n\tconst uncertain = [data.status, data.effect].some((value) => value === \"partial\" || value === \"unverifiable\");\n\treturn reply.isError === true || plainLaunchReason(reply) !== undefined ||\n\t\t(data.refusal !== undefined && data.refusal !== null && data.refusal !== false) ||\n\t\t(data.error !== undefined && data.error !== null && data.error !== false) ||\n\t\tdata.effect === \"refused\" || data.status === \"refused\" || data.status === \"failed\" || data.success === false ||\n\t\t[\"window_target_mismatch\", \"window_target_not_found\", \"background_unavailable\", \"foreground_unavailable\", \"type_text_incomplete\", \"verification_failed\"].includes(String(data.code)) ||\n\t\t(data.status !== undefined && !acknowledged && !uncertain && ![\"ok\", \"success\", \"completed\"].includes(String(data.status))) ||\n\t\t(data.code !== undefined && data.code !== 0 && !acknowledged && !uncertain);\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value) ? Object.fromEntries(Object.entries(value)) : {};\n}\n\nfunction select(data: Record<string, unknown>, keys: readonly string[]): Record<string, string | number | boolean> {\n\tconst result: Record<string, string | number | boolean> = {};\n\tfor (const key of keys) {\n\t\tconst value = data[key];\n\t\tif ([\"name\", \"app_name\", \"title\"].includes(key) && typeof value === \"string\") result[key] = value.slice(0, 240);\n\t\telse if ([\"active\", \"running\", \"is_on_screen\", \"minimized\"].includes(key) && typeof value === \"boolean\") result[key] = value;\n\t\telse if ([\"pid\", \"window_id\", \"x\", \"y\", \"width\", \"height\"].includes(key) && typeof value === \"number\" && Number.isSafeInteger(value)) result[key] = value;\n\t}\n\treturn result;\n}\n\nfunction typingRecovery(data: Record<string, unknown>, text: unknown) {\n\tif (typeof text !== \"string\") return {};\n\tconst requested = data.requested_chars;\n\tconst delivered = data.delivered_chars;\n\tif (typeof requested !== \"number\" || !Number.isSafeInteger(requested) || requested < 0 ||\n\t\trequested > 20000 || requested !== Array.from(text).length) return {};\n\tconst validDelivered = typeof delivered === \"number\" && Number.isSafeInteger(delivered) && delivered >= 0 && delivered <= requested;\n\treturn {\n\t\trequested_chars: requested,\n\t\tdelivered_chars: validDelivered ? delivered : undefined,\n\t\tretryable: validDelivered && data.retry_from_character === delivered && typeof data.retryable === \"boolean\" ? data.retryable : undefined,\n\t\tretry_from_character: validDelivered && data.retry_from_character === delivered ? delivered : undefined,\n\t};\n}\n\nconst nativeCodes = new Set([\"background_unavailable\", \"background_occluded\", \"background_uipi_blocked\", \"window_target_mismatch\", \"window_target_not_found\", \"type_text_incomplete\", \"foreground_unavailable\", \"foreground_rejected\", \"stale_target\", \"target_not_found\", \"verification_failed\", \"tool_invocation_failed\"]);\nfunction safeCode(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && nativeCodes.has(value) ? value : undefined;\n}\nfunction nativeReason(reply: DriverReply): string {\n\tconst data = driverData(reply);\n\tconst code = safeCode(data.code) ?? safeCode(record(data.refusal).code) ?? safeCode(record(data.error).code) ?? safeCode(data.refusal) ?? safeCode(data.error);\n\tif (code) return code;\n\tif (plainLaunchReason(reply)) return plainLaunchReason(reply)!;\n\treturn \"native_error_unknown\";\n}\ntype FailurePhase = \"validation\" | \"adapter_preflight\" | \"native_request\" | \"native_result\" | \"observation_capture\" | \"post_action_capture\" | \"cleanup\";\ntype InputState = \"not_dispatched\" | \"dispatched\" | \"partial\" | \"uncertain\";\ntype NativeOutcome = {\n\tphase: FailurePhase;\n\tcode?: string;\n\tnative_code?: string;\n\tstatus?: string;\n\teffect?: string;\n\tverified?: boolean;\n\tsuccess?: boolean;\n\tactivated?: boolean;\n\tescalation?: \"foreground\";\n\tinput: InputState;\n\tapplicationEffect: \"unverified\";\n\trequested_chars?: number;\n\tdelivered_chars?: number;\n\tretryable?: boolean;\n\tretry_from_character?: number;\n};\nfunction outcome(reply: DriverReply, text?: unknown): NativeOutcome {\n\tconst data = driverData(reply);\n\tconst refused = driverRefused(reply);\n\tconst partial = data.effect === \"partial\" || data.status === \"partial\";\n\treturn {\n\t\tphase: refused || partial ? \"native_result\" : \"native_request\",\n\t\tcode: refused || partial ? nativeReason(reply) : undefined,\n\t\tnative_code: safeCode(data.code) ?? safeCode(record(data.refusal).code) ?? safeCode(record(data.error).code),\n\t\tstatus: typeof data.status === \"string\" && [\"ok\", \"success\", \"completed\", \"partial\", \"refused\", \"failed\"].includes(data.status) ? data.status : undefined,\n\t\teffect: typeof data.effect === \"string\" && [\"confirmed\", \"partial\", \"unverifiable\", \"refused\"].includes(data.effect) ? data.effect : undefined,\n\t\tverified: typeof data.verified === \"boolean\" ? data.verified : undefined,\n\t\tsuccess: typeof data.success === \"boolean\" ? data.success : undefined,\n\t\tactivated: typeof data.activated === \"boolean\" ? data.activated : undefined,\n\t\tescalation: record(data.escalation).recommended === \"foreground\" ? \"foreground\" : undefined,\n\t\tinput: partial && typingRecovery(data, text).delivered_chars !== undefined ? \"partial\" : refused || partial ? \"uncertain\" : \"dispatched\",\n\t\tapplicationEffect: \"unverified\",\n\t\t...typingRecovery(data, text),\n\t};\n}\n\nfunction abortable<T>(pending: Promise<T>, signal: AbortSignal): Promise<T> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst abort = () => {\n\t\t\tsignal.removeEventListener(\"abort\", abort);\n\t\t\treject(signal.reason ?? new Error(\"Computer operation cancelled.\"));\n\t\t};\n\t\tsignal.addEventListener(\"abort\", abort, { once: true });\n\t\tpending.then((value) => {\n\t\t\tsignal.removeEventListener(\"abort\", abort);\n\t\t\tresolve(value);\n\t\t}, (error) => {\n\t\t\tsignal.removeEventListener(\"abort\", abort);\n\t\t\treject(error);\n\t\t});\n\t\tif (signal.aborted) abort();\n\t});\n}\n\nconst freshActionGuidance = \"Get a fresh capture of the exact target before any next action, including window focus. Copy its token exactly. No input was sent by this call; earlier calls may have had an effect.\";\n\nclass CaptureError extends Error {\n\treadonly code: string;\n\tconstructor(code: string) { super(code); this.code = code; }\n}\n\nclass ObservationError extends Error {\n\treadonly code: string;\n\tconstructor(code: string, message: string) {\n\t\tsuper(`Stale observation. ${message}`);\n\t\tthis.code = code;\n\t}\n}\n\ntype Target = { desktop: true } | { pid: number; window_id: number; desktop?: false };\ntype PreparedImage = Awaited<ReturnType<typeof prepareComputerImage>>;\ntype Observation = PreparedImage & { token: string; target: Target; time: number; fingerprint: string; geometry: string };\ntype WorkflowState = \"ready\" | \"stopped\" | \"cleanup_unconfirmed\";\ntype Result = { content: (ImageContent | TextContent)[]; details: { observation?: string; computer: { failed: boolean; workflow: WorkflowState } }; isError: boolean };\n\nfunction targetFrom(input: Record<string, unknown>): Target {\n\tif (input.desktop === true) {\n\t\tif (input.pid !== undefined || input.window_id !== undefined) throw new Error(\"Desktop target cannot include pid/window_id.\");\n\t\treturn { desktop: true };\n\t}\n\tif (typeof input.pid !== \"number\" || !Number.isInteger(input.pid) || input.pid < 1 ||\n\t\ttypeof input.window_id !== \"number\" || !Number.isInteger(input.window_id) || input.window_id < 1)\n\t\tthrow new Error(\"Window target requires positive integer pid and window_id.\");\n\treturn { pid: input.pid, window_id: input.window_id };\n}\n\nfunction sameTarget(a: Target, b: Target): boolean {\n\treturn a.desktop === true ? b.desktop === true : b.desktop !== true && a.pid === b.pid && a.window_id === b.window_id;\n}\n\nexport class ComputerWorkflow {\n\tprivate observation?: Observation;\n\tprivate lastCapture?: { fingerprint: string; target: Target; repeats: number };\n\tprivate lastAction?: { signature: string; fingerprint: string; unchanged: boolean };\n\tprivate readonly abort = new AbortController();\n\tprivate closing?: Promise<void>;\n\tprivate readonly driver: ComputerDriver;\n\tprivate readonly lease: DesktopLease;\n\tconstructor(driver: ComputerDriver, lease = new DesktopLease()) {\n\t\tthis.driver = driver;\n\t\tthis.lease = lease;\n\t\tthis.driver.setProcessObserver?.((pid) => this.lease.trackProcess(pid));\n\t}\n\n\tprivate fresh(input: Record<string, unknown>, previous?: Observation): Observation {\n\t\tif (!previous) throw new ObservationError(\"observation_unavailable\", \"No active observation is available.\");\n\t\tif (previous.token !== input.observation) throw new ObservationError(\"observation_mismatch\", \"Token does not match the active observation.\");\n\t\tif (!sameTarget(previous.target, targetFrom(input))) throw new ObservationError(\"observation_target_mismatch\", \"Token belongs to a different target.\");\n\t\tif (Date.now() - previous.time > 30000) throw new ObservationError(\"observation_expired\", \"The active observation is older than 30 seconds.\");\n\t\treturn previous;\n\t}\n\n\tprivate async capture(target: Target, signal: AbortSignal, previous?: Observation, crop?: ImageRegion): Promise<Observation> {\n\t\tconst time = Date.now();\n\t\tconst reply = await abortable(this.driver.call(target.desktop ? \"get_desktop_state\" : \"get_window_state\",\n\t\t\ttarget.desktop ? {} : { pid: target.pid, window_id: target.window_id, include_accessibility_tree: false, include_screenshot: true, max_dimension: 2560 }, signal), signal);\n\t\tif (driverRefused(reply)) throw new CaptureError(nativeReason(reply));\n\t\tconst data = driverData(reply);\n\t\tconst images = Array.isArray(reply.content) ? reply.content.filter((item) => item.type === \"image\") : [];\n\t\tif (images.length !== 1 || typeof images[0].data !== \"string\" || typeof images[0].mimeType !== \"string\")\n\t\t\tthrow new CaptureError(\"screenshot_unavailable\");\n\t\tconst image: ImageContent = { type: \"image\", data: images[0].data, mimeType: images[0].mimeType };\n\t\tlet dimensions: { width: number; height: number };\n\t\ttry { dimensions = screenshotDimensions(image); } catch { throw new CaptureError(\"image_decode_failed\"); }\n\t\tif (data.screenshot_frame_valid === false || data.screenshot_error != null || dimensions.width !== data.screenshot_width || dimensions.height !== data.screenshot_height)\n\t\t\tthrow new CaptureError(\"image_frame_invalid\");\n\t\tconst geometry = JSON.stringify(select(record(data.window_bounds), [\"x\", \"y\", \"width\", \"height\"]));\n\t\tif (crop && previous && (previous.sourceWidth !== dimensions.width || previous.sourceHeight !== dimensions.height || previous.geometry !== geometry))\n\t\t\tthrow new CaptureError(\"target_geometry_changed\");\n\t\tlet prepared: PreparedImage;\n\t\ttry { prepared = await abortable(prepareComputerImage(image, crop), signal); }\n\t\tcatch (error) { if (signal.aborted) throw error; throw new CaptureError(\"image_decode_failed\"); }\n\t\tsignal.throwIfAborted();\n\t\treturn { ...prepared, token: randomUUID(), target, time, fingerprint: prepared.fingerprint, geometry };\n\t}\n\n\tprivate imageResult(observation: Observation, extra: Record<string, unknown> = {}): Result {\n\t\tthis.observation = observation;\n\t\tconst { width, height, region, sourceWidth, sourceHeight, scaleX, scaleY, target, token } = observation;\n\t\tconst failed = extra.failed === true;\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text: JSON.stringify({\n\t\t\t\t...extra, observation: token, target, captured_at: observation.time, expires_at: observation.time + 30000, image: { width, height },\n\t\t\t\tmapping: { sourceWidth, sourceHeight, ...region, scaleX, scaleY },\n\t\t\t\tcoordinates: \"Use returned-image pixels; mapping is applied automatically.\",\n\t\t\t}) }, observation.image],\n\t\t\tdetails: { observation: token, computer: { failed, workflow: \"ready\" } }, isError: failed,\n\t\t};\n\t}\n\n\tprivate crop(input: Record<string, unknown>, previous: Observation): ImageRegion {\n\t\tconst crop = record(input.crop);\n\t\tconst { x, y, width, height } = crop;\n\t\tif (typeof x !== \"number\" || typeof y !== \"number\" || typeof width !== \"number\" || typeof height !== \"number\" ||\n\t\t\t![x, y, width, height].every(Number.isFinite) || x < 0 || y < 0 || width <= 0 || height <= 0 ||\n\t\t\tx + width > previous.width || y + height > previous.height || Object.keys(crop).some((key) => ![\"x\", \"y\", \"width\", \"height\"].includes(key)))\n\t\t\tthrow new Error(\"Crop must fit the latest returned image.\");\n\t\tconst left = Math.floor(previous.region.x + x * previous.scaleX);\n\t\tconst top = Math.floor(previous.region.y + y * previous.scaleY);\n\t\tconst right = Math.min(previous.sourceWidth, Math.ceil(previous.region.x + (x + width) * previous.scaleX));\n\t\tconst bottom = Math.min(previous.sourceHeight, Math.ceil(previous.region.y + (y + height) * previous.scaleY));\n\t\treturn { x: left, y: top, width: right - left, height: bottom - top };\n\t}\n\n\tprivate action(name: string, input: Record<string, unknown>, previous: Observation) {\n\t\tconst args: Record<string, unknown> = previous.target.desktop ? { scope: \"desktop\" } : { pid: previous.target.pid, window_id: previous.target.window_id };\n\t\tif (previous.target.desktop && input.foreground !== true) throw new Error(\"Desktop input requires foreground=true.\");\n\t\tif (name !== \"computer_window\" && name !== \"computer_hover\") args.delivery_mode = input.foreground === true ? \"foreground\" : \"background\";\n\t\tfor (const key of [\"x\", \"y\", \"from_x\", \"from_y\", \"to_x\", \"to_y\"]) {\n\t\t\tif (name === \"computer_window\") break;\n\t\t\tconst value = input[key];\n\t\t\tif (value === undefined) continue;\n\t\t\tconst horizontal = key.endsWith(\"x\");\n\t\t\tif (typeof value !== \"number\" || !Number.isFinite(value) || value < 0 || value >= (horizontal ? previous.width : previous.height))\n\t\t\t\tthrow new Error(\"Coordinate outside the observed image.\");\n\t\t\targs[key] = (horizontal ? previous.region.x : previous.region.y) + value * (horizontal ? previous.scaleX : previous.scaleY);\n\t\t}\n\t\tif ((input.x === undefined) !== (input.y === undefined)) throw new Error(\"Provide a complete x/y pair.\");\n\t\tif (previous.target.desktop && [\"computer_key\", \"computer_text\"].includes(name) && input.x !== undefined)\n\t\t\tthrow new Error(\"Desktop keyboard input uses the observed focused field. Change focus with a separate grounded click.\");\n\t\tlet operation: string;\n\t\tswitch (name) {\n\t\t\tcase \"computer_hover\":\n\t\t\t\tif (process.platform !== \"win32\" || !previous.target.desktop || input.desktop !== true || input.foreground !== true ||\n\t\t\t\t\tinput.x === undefined || input.y === undefined) throw new Error(\"Hover requires a Windows foreground desktop image and x/y coordinates.\");\n\t\t\t\toperation = \"move_cursor\";\n\t\t\t\tbreak;\n\t\t\tcase \"computer_click\":\n\t\t\tcase \"computer_scroll\":\n\t\t\t\tif (input.x === undefined || input.y === undefined) throw new Error(\"This action requires x/y image coordinates.\");\n\t\t\t\toperation = name === \"computer_click\" ? \"click\" : \"scroll\";\n\t\t\t\tfor (const key of name === \"computer_click\" ? [\"button\", \"count\", \"modifier\"] : [\"direction\", \"amount\", \"by\"])\n\t\t\t\t\tif (input[key] !== undefined) args[key] = input[key];\n\t\t\t\tbreak;\n\t\t\tcase \"computer_drag\":\n\t\t\t\tif (![\"from_x\", \"from_y\", \"to_x\", \"to_y\"].every((key) => typeof args[key] === \"number\")) throw new Error(\"Drag requires both endpoints.\");\n\t\t\t\toperation = \"drag\";\n\t\t\t\tbreak;\n\t\t\tcase \"computer_key\": {\n\t\t\t\tif ((input.key === undefined) === (input.keys === undefined)) throw new Error(\"Provide key OR keys.\");\n\t\t\t\tconst keys: readonly unknown[] | undefined = Array.isArray(input.keys) ? input.keys : undefined;\n\t\t\t\tconst last = keys?.at(-1);\n\t\t\t\tconst modifiers = new Set([\"ctrl\", \"control\", \"shift\", \"alt\", \"win\", \"windows\", \"cmd\", \"command\"]);\n\t\t\t\tconst foregroundShortcut = process.platform === \"win32\" && input.foreground === true && input.x === undefined &&\n\t\t\t\t\tkeys !== undefined && keys.length >= 2 && keys.slice(0, -1).every((key) => typeof key === \"string\" && modifiers.has(key.toLowerCase())) &&\n\t\t\t\t\ttypeof last === \"string\" && !modifiers.has(last.toLowerCase());\n\t\t\t\t// Pinned Windows hotkey routes XAML through UIA before honoring foreground; press_key honors SendInput.\n\t\t\t\toperation = input.keys === undefined || foregroundShortcut ? \"press_key\" : \"hotkey\";\n\t\t\t\tif (foregroundShortcut) {\n\t\t\t\t\targs.key = last;\n\t\t\t\t\targs.modifiers = keys.slice(0, -1);\n\t\t\t\t} else args[input.keys === undefined ? \"key\" : \"keys\"] = input.keys ?? input.key;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"computer_text\":\n\t\t\t\toperation = \"type_text\";\n\t\t\t\targs.text = input.text;\n\t\t\t\tbreak;\n\t\t\tcase \"computer_window\":\n\t\t\t\tif (previous.target.desktop) throw new Error(\"Window management requires an exact window target.\");\n\t\t\t\tif (input.action === \"frame\") {\n\t\t\t\t\tfor (const key of [\"x\", \"y\", \"width\", \"height\"]) {\n\t\t\t\t\t\tconst value = input[key];\n\t\t\t\t\t\tif (typeof value !== \"number\" || !Number.isFinite(value) || ([\"width\", \"height\"].includes(key) && value <= 0)) throw new Error(\"Frame requires valid x/y/width/height.\");\n\t\t\t\t\t\targs[key] = value;\n\t\t\t\t\t}\n\t\t\t\t\toperation = \"set_window_frame\";\n\t\t\t\t} else if (input.action === \"focus\" && [\"x\", \"y\", \"width\", \"height\"].every((key) => input[key] === undefined)) operation = \"bring_to_front\";\n\t\t\t\telse throw new Error(\"Use frame or focus. Minimize/restore uses a fresh image click on the visible control.\");\n\t\t\t\tbreak;\n\t\t\tdefault: throw new Error(\"Unknown computer action.\");\n\t\t}\n\t\treturn { operation, args };\n\t}\n\n\tasync execute(name: string, input: Record<string, unknown>, signal?: AbortSignal): Promise<Result> {\n\t\tconst combined = AbortSignal.any([this.abort.signal, this.lease.signal, AbortSignal.timeout(90000), ...(signal ? [signal] : [])]);\n\t\tlet inputDispatched = false;\n\t\tlet failureCode = \"workflow_unavailable\";\n\t\tlet phase: FailurePhase = \"validation\";\n\t\tconst currentPhase = (): FailurePhase => phase;\n\t\tlet operationName = name;\n\t\tlet actionTarget: Target | undefined;\n\t\tlet actionOutcome: ReturnType<typeof outcome> | undefined;\n\t\ttry {\n\t\t\tconst result = await this.lease.run(async (): Promise<Result> => {\n\t\t\t\tfailureCode = \"invalid_arguments\";\n\t\t\t\tconst previous = this.observation;\n\t\t\t\tif (name !== \"computer_apps\") this.observation = undefined;\n\t\t\t\tif (!Object.hasOwn(computerSchemas, name)) throw new Error(\"Unknown computer operation.\");\n\t\t\t\tconst schema = computerSchemas[name as keyof typeof computerSchemas];\n\t\t\t\tif (Object.keys(input).some((key) => !Object.hasOwn(schema.properties, key))) throw new Error(\"Unsupported computer argument. Use image coordinates only.\");\n\t\t\t\tif (name === \"computer_apps\" || name === \"computer_launch\") {\n\t\t\t\t\tconst operation = name === \"computer_launch\" ? \"launch_app\" : input.pid === undefined ? \"list_apps\" : \"list_windows\";\n\t\t\t\t\toperationName = operation;\n\t\t\t\t\tif (input.include_windows !== undefined && (name !== \"computer_apps\" || typeof input.include_windows !== \"boolean\" || (input.include_windows && (input.pid !== undefined || typeof input.query !== \"string\" || !input.query.trim()))))\n\t\t\t\t\t\tthrow new Error(\"include_windows requires a named app query without pid.\");\n\t\t\t\t\tif (input.pid !== undefined && (typeof input.pid !== \"number\" || !Number.isSafeInteger(input.pid) || input.pid < 1)) throw new Error(\"Window lookup requires a positive pid.\");\n\t\t\t\t\tif (name === \"computer_launch\" && (typeof input.name !== \"string\" || !input.name.trim() || input.name.length > 500)) throw new Error(\"Launch requires a nonblank name.\");\n\t\t\t\t\tif (input.query !== undefined && (typeof input.query !== \"string\" || !input.query.trim() || Array.from(input.query).length > 240))\n\t\t\t\t\t\tthrow new Error(\"Discovery query must be a nonblank string of at most 240 characters.\");\n\t\t\t\t\tconst query = typeof input.query === \"string\" ? input.query.trim() : undefined;\n\t\t\t\t\tconst needle = query?.toLowerCase();\n\t\t\t\t\tconst offset = input.offset ?? 0;\n\t\t\t\t\tif (typeof offset !== \"number\" || !Number.isSafeInteger(offset) || offset < 0)\n\t\t\t\t\t\tthrow new Error(\"Discovery offset must be a nonnegative safe integer.\");\n\t\t\t\t\tconst args = name === \"computer_launch\" ? { name: input.name } : input.pid === undefined ? {} : { pid: input.pid };\n\t\t\t\t\tcombined.throwIfAborted();\n\t\t\t\t\tinputDispatched = name === \"computer_launch\";\n\t\t\t\t\tphase = \"native_request\";\n\t\t\t\t\tfailureCode = \"discovery_failed\";\n\t\t\t\t\tconst reply = await abortable(this.driver.call(operation, args, combined), combined);\n\t\t\t\t\tconst data = driverData(reply);\n\t\t\t\t\tconst discovered = data.apps ?? data.windows;\n\t\t\t\t\tconst rows = Array.isArray(discovered) && needle ? discovered.filter((row) => {\n\t\t\t\t\t\tconst item = record(row);\n\t\t\t\t\t\treturn [item.name, item.app_name, item.title].some((value) => typeof value === \"string\" && value.toLowerCase().includes(needle));\n\t\t\t\t\t}) : discovered;\n\t\t\t\t\tconst metadata = Array.isArray(rows) ? rows.slice(offset, offset + 50).map((row) => {\n\t\t\t\t\t\tconst item = record(row);\n\t\t\t\t\t\treturn { ...select(item, [\"pid\", \"window_id\", \"name\", \"app_name\", \"title\", \"active\", \"running\", \"is_on_screen\", \"minimized\"]),\n\t\t\t\t\t\t\tbounds: item.bounds ? select(record(item.bounds), [\"x\", \"y\", \"width\", \"height\"]) : undefined };\n\t\t\t\t\t}) : undefined;\n\t\t\t\t\tconst remaining = Array.isArray(rows) ? Math.max(0, rows.length - offset - (metadata?.length ?? 0)) : 0;\n\t\t\t\t\tconst failed = driverRefused(reply);\n\t\t\t\t\tconst pid = typeof data.pid === \"number\" && Number.isSafeInteger(data.pid) && data.pid > 0 ? data.pid : undefined;\n\t\t\t\t\tconst launchWindows = Array.isArray(data.windows) ? data.windows.slice(0, 50).map((row) => {\n\t\t\t\t\t\tconst item = record(row);\n\t\t\t\t\t\treturn { ...select(item, [\"window_id\", \"title\", \"is_on_screen\", \"minimized\"]), bounds: item.bounds ? select(record(item.bounds), [\"x\", \"y\", \"width\", \"height\"]) : undefined };\n\t\t\t\t\t}) : [];\n\t\t\t\t\tconst returnedId = data.window_id ?? (Array.isArray(data.windows) && data.windows.length === 1 ? record(data.windows[0]).window_id : undefined);\n\t\t\t\t\tconst windowId = typeof returnedId === \"number\" && Number.isSafeInteger(returnedId) && returnedId > 0 ? returnedId : undefined;\n\t\t\t\t\tlet windowsByPid: { pid: number; windows?: typeof metadata; error?: string; omitted?: number; next_offset?: number }[] | undefined;\n\t\t\t\t\tlet guidance = remaining ? \"Pass next_offset as offset with the same pid and query. Lists refresh per call.\" : input.pid !== undefined\n\t\t\t\t\t\t? \"Use computer_observe({pid,window_id}) for an exact returned window.\"\n\t\t\t\t\t\t: \"App query filters app identities, not every window title. Use computer_apps({pid}) to find windows for a running app.\";\n\t\t\t\t\tif (name === \"computer_apps\" && input.include_windows === true && !failed) {\n\t\t\t\t\t\tconst pids = [...new Set((Array.isArray(rows) ? rows : []).map((row) => record(row).pid).filter((value): value is number => typeof value === \"number\" && Number.isSafeInteger(value) && value > 0))];\n\t\t\t\t\t\tif (pids.length > 5) guidance = \"More than five running processes matched. Narrow the query or choose one positive pid with computer_apps({pid}); no arbitrary process was selected.\";\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\twindowsByPid = [];\n\t\t\t\t\t\t\tlet budget = 50;\n\t\t\t\t\t\t\tfor (const matchingPid of pids) {\n\t\t\t\t\t\t\t\tcombined.throwIfAborted();\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst windowsReply = await abortable(this.driver.call(\"list_windows\", { pid: matchingPid }, combined), combined);\n\t\t\t\t\t\t\t\t\tconst windows = driverData(windowsReply).windows;\n\t\t\t\t\t\t\t\t\tif (driverRefused(windowsReply) || !Array.isArray(windows)) { windowsByPid.push({ pid: matchingPid, error: driverRefused(windowsReply) ? nativeReason(windowsReply) : \"windows_unavailable\" }); continue; }\n\t\t\t\t\t\t\t\t\tconst subset = windows.slice(0, budget).map((row) => {\n\t\t\t\t\t\t\t\t\t\tconst item = record(row);\n\t\t\t\t\t\t\t\t\t\treturn { ...select(item, [\"pid\", \"window_id\", \"name\", \"app_name\", \"title\", \"active\", \"running\", \"is_on_screen\", \"minimized\"]),\n\t\t\t\t\t\t\t\t\t\t\tbounds: item.bounds ? select(record(item.bounds), [\"x\", \"y\", \"width\", \"height\"]) : undefined };\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\tconst omitted = windows.length - subset.length;\n\t\t\t\t\t\t\t\t\twindowsByPid.push({ pid: matchingPid, windows: subset, omitted: omitted || undefined, next_offset: omitted ? subset.length : undefined });\n\t\t\t\t\t\t\t\t\tbudget -= subset.length;\n\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\tif (combined.aborted) throw error;\n\t\t\t\t\t\t\t\t\tif (error instanceof DriverCallError) throw error;\n\t\t\t\t\t\t\t\t\twindowsByPid.push({ pid: matchingPid, error: \"window_lookup_failed\" });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tguidance = \"Use computer_observe({pid,window_id}) for a returned window. For omitted windows use computer_apps({pid,offset:next_offset}). Per-PID failures need a targeted lookup.\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (name === \"computer_launch\") guidance = pid && windowId && !failed\n\t\t\t\t\t\t? `Use computer_observe({pid:${pid},window_id:${windowId}}) before input.`\n\t\t\t\t\t\t: `Launch ${failed ? \"may have completed despite an unsuccessful reply\" : \"returned no exact window\"}. Use computer_apps({${pid ? `pid:${pid}` : `query:${JSON.stringify(input.name)}`}}) before another launch or input.`;\n\t\t\t\t\treturn { content: [{ type: \"text\", text: JSON.stringify({\n\t\t\t\t\t\tkind: name === \"computer_launch\" ? \"launch\" : input.pid === undefined ? \"apps\" : \"windows\", operation,\n\t\t\t\t\t\t...(name === \"computer_launch\" ? outcome(reply) : { phase: \"native_result\", code: failed ? nativeReason(reply) : undefined }),\n\t\t\t\t\t\tinput: name === \"computer_launch\" ? \"not_applicable\" : undefined,\n\t\t\t\t\t\tlaunch: name === \"computer_launch\" ? plainLaunchReason(reply) === \"app_lookup_unavailable\" ? \"not_started\" : failed ? \"completion_uncertain\" : \"acknowledged\" : undefined,\n\t\t\t\t\t\t...select(data, [\"pid\", \"window_id\", \"name\", \"title\"]), window_id: name === \"computer_launch\" ? windowId : select(data, [\"window_id\"]).window_id,\n\t\t\t\t\t\twindows: name === \"computer_launch\" ? launchWindows : undefined, items: name === \"computer_launch\" ? undefined : metadata,\n\t\t\t\t\t\twindows_by_pid: windowsByPid, query, offset, total: Array.isArray(rows) ? rows.length : undefined,\n\t\t\t\t\t\tomitted: remaining || undefined, next_offset: remaining ? offset + 50 : undefined, guidance,\n\t\t\t\t\t}) }], details: { computer: { failed, workflow: \"ready\" } }, isError: failed };\n\t\t\t\t}\n\t\t\t\tconst target = targetFrom(input);\n\t\t\t\tactionTarget = target;\n\t\t\t\tif (name === \"computer_observe\") {\n\t\t\t\t\tphase = \"observation_capture\";\n\t\t\t\t\tconst crop = input.crop === undefined ? undefined : this.crop(input, this.fresh(input, previous));\n\t\t\t\t\tfailureCode = \"capture_failed\";\n\t\t\t\t\tconst captured = await this.capture(target, combined, previous, crop);\n\t\t\t\t\tconst unchanged = this.lastCapture?.fingerprint === captured.fingerprint && sameTarget(this.lastCapture.target, target);\n\t\t\t\t\tconst repeats = crop ? 0 : unchanged ? (this.lastCapture?.repeats ?? 0) + 1 : 1;\n\t\t\t\t\tthis.lastCapture = { fingerprint: captured.fingerprint, target, repeats };\n\t\t\t\t\tif (repeats >= 3) return {\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: JSON.stringify({ phase: \"observation_capture\", code: \"unchanged_polling_limit\", guidance: \"Three captures are unchanged. Stop polling and reconsider the target or approach. No input token issued.\" }) }],\n\t\t\t\t\t\tdetails: { computer: { failed: true, workflow: \"stopped\" } }, isError: true,\n\t\t\t\t\t};\n\t\t\t\t\treturn this.imageResult(captured, { unchanged });\n\t\t\t\t}\n\t\t\t\tconst grounded = this.fresh(input, previous);\n\t\t\t\tconst { operation, args } = this.action(name, input, grounded);\n\t\t\t\tconst { button = \"left\", count = 1, modifier = [], ...clickArgs } = args;\n\t\t\t\tconst signature = JSON.stringify({ operation, args: operation === \"click\"\n\t\t\t\t\t? { ...clickArgs, button, count, modifier: Array.isArray(modifier) ? [...new Set(modifier)].sort() : modifier }\n\t\t\t\t\t: args });\n\t\t\t\tif (this.lastAction?.unchanged && this.lastAction.signature === signature && this.lastAction.fingerprint === grounded.fingerprint)\n\t\t\t\t\tthrow new Error(\"The identical action had no visible change. Choose a different grounded action; never retry blindly.\");\n\t\t\t\tcombined.throwIfAborted();\n\t\t\t\tinputDispatched = true;\n\t\t\t\tphase = \"native_request\";\n\t\t\t\toperationName = operation;\n\t\t\t\tconst reply = await abortable(this.driver.call(operation, args, combined), combined);\n\t\t\t\tcombined.throwIfAborted();\n\t\t\t\tactionOutcome = outcome(reply, name === \"computer_text\" ? input.text : undefined);\n\t\t\t\tconst recoveryGuidance = actionOutcome.retry_from_character !== undefined\n\t\t\t\t\t? \"Verify the field in a fresh image before considering any remaining suffix. retry_from_character is a zero-based Unicode code-point offset, not UTF-16. retryable is driver advice, not authorization to retry.\"\n\t\t\t\t\t: undefined;\n\t\t\t\tconst failed = driverRefused(reply) || driverData(reply).effect === \"partial\" || driverData(reply).status === \"partial\";\n\t\t\t\tconst backgroundUnavailable = actionOutcome.code === \"background_unavailable\";\n\t\t\t\tif (name === \"computer_hover\") await delay(700, undefined, { signal: combined });\n\t\t\t\tphase = \"post_action_capture\";\n\t\t\t\ttry {\n\t\t\t\t\tconst after = await this.capture(target, combined);\n\t\t\t\t\tconst unchanged = after.fingerprint === grounded.fingerprint;\n\t\t\t\t\tthis.lastAction = { signature, fingerprint: after.fingerprint, unchanged };\n\t\t\t\t\tthis.lastCapture = { fingerprint: after.fingerprint, target, repeats: failed && this.lastCapture?.fingerprint === after.fingerprint && sameTarget(this.lastCapture.target, target)\n\t\t\t\t\t\t? this.lastCapture.repeats : 0 };\n\t\t\t\t\treturn this.imageResult(after, { kind: \"action\", operation, target, ...actionOutcome, failed, unchanged,\n\t\t\t\t\t\tguidance: [\"Inspect the post-action image before another action. No visible change does not prove failure; never repeat blindly.\",\n\t\t\t\t\t\t\tbackgroundUnavailable ? \"After this fresh capture, foreground input may be considered if permitted, not another background shortcut.\" : undefined,\n\t\t\t\t\t\t\trecoveryGuidance].filter(Boolean).join(\" \") });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcombined.throwIfAborted();\n\t\t\t\t\tif (!(error instanceof CaptureError)) throw error;\n\t\t\t\t\tthis.lastAction = { signature, fingerprint: grounded.fingerprint, unchanged: true };\n\t\t\t\t\treturn { content: [{ type: \"text\", text: JSON.stringify({ kind: \"action\", operation, target, ...actionOutcome, phase: \"post_action_capture\",\n\t\t\t\t\t\tcapture_error: error.code, observation: \"unavailable\", guidance: `Input may have taken effect. ${[\"target_not_found\", \"window_target_not_found\", \"window_target_mismatch\"].includes(error.code)\n\t\t\t\t\t\t\t? \"Use computer_apps({pid}) or observe the desktop to find the target.\" : \"Get a fresh capture of the exact target\"} before another action; never repeat blindly. ${recoveryGuidance ?? \"\"}`,\n\t\t\t\t\t}) }], details: { computer: { failed: true, workflow: \"ready\" } }, isError: true };\n\t\t\t\t}\n\t\t\t}, combined);\n\t\t\tif (result.details.computer.workflow !== \"ready\") return this.finish(result);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (error instanceof DriverCallError && !(currentPhase() === \"post_action_capture\" && actionOutcome)) {\n\t\t\t\tphase = error.phase;\n\t\t\t\tinputDispatched = error.dispatched;\n\t\t\t}\n\t\t\tconst failurePhase = currentPhase();\n\t\t\tconst fatal = combined.aborted || this.abort.signal.aborted || this.lease.signal.aborted || error instanceof DriverCallError ||\n\t\t\t\t!(error instanceof ObservationError || error instanceof CaptureError || failurePhase === \"validation\" || failurePhase === \"observation_capture\" && !inputDispatched);\n\t\t\tconst code = error instanceof ObservationError || error instanceof CaptureError ? error.code\n\t\t\t\t: inputDispatched && failurePhase === \"post_action_capture\" ? \"capture_transport_failed\"\n\t\t\t\t: error instanceof DriverCallError ? error.dispatched ? \"input_dispatch_failed\" : \"adapter_preflight_failed\"\n\t\t\t\t: inputDispatched ? \"input_dispatch_failed\" : failurePhase === \"validation\" ? \"invalid_arguments\" : failureCode;\n\t\t\tconst message = name === \"computer_launch\" ? inputDispatched ? \"Launch request began; activation may have occurred.\" : \"No launch request was sent by this call.\"\n\t\t\t\t: inputDispatched ? \"Input may have taken effect; request began.\" : \"No input was sent by this call.\";\n\t\t\tconst guidance = inputDispatched ? name === \"computer_launch\"\n\t\t\t\t? `Use computer_apps({query:${JSON.stringify(input.name)}) before considering another launch.`\n\t\t\t\t: `Get a fresh capture of the exact target before another action. Input may have taken effect; inspect the field before deciding and never repeat blindly. ${actionOutcome?.retry_from_character !== undefined ? \"Verify the field in a fresh image before considering any remaining suffix. retry_from_character is a zero-based Unicode code-point offset, not UTF-16.\" : \"\"}`\n\t\t\t\t: freshActionGuidance;\n\t\t\tconst result: Result = { content: [{ type: \"text\", text: JSON.stringify({ kind: name === \"computer_apps\" ? \"apps\" : name === \"computer_launch\" ? \"launch\" : name === \"computer_observe\" ? \"observation\" : \"action\",\n\t\t\t\toperation: operationName, target: actionTarget, ...actionOutcome, action_outcome: actionOutcome, phase: failurePhase, code,\n\t\t\t\tinput: name === \"computer_apps\" ? undefined : name === \"computer_launch\" ? \"not_applicable\" : inputDispatched ? \"uncertain\" : \"not_dispatched\",\n\t\t\t\trequest: name === \"computer_launch\" ? inputDispatched ? \"sent\" : \"not_sent\" : undefined, applicationEffect: \"unverified\",\n\t\t\t\tobservation: \"unavailable\", capture_error: failurePhase === \"post_action_capture\" ? code : undefined, message, guidance }) }], details: { computer: { failed: true, workflow: fatal ? \"stopped\" : \"ready\" } }, isError: true };\n\t\t\treturn fatal ? this.finish(result) : result;\n\t\t}\n\t}\n\n\tprivate async finish(result: Result): Promise<Result> {\n\t\ttry {\n\t\t\tawait this.close();\n\t\t\treturn { ...result, details: { ...result.details, computer: { failed: result.details.computer.failed, workflow: \"stopped\" } } };\n\t\t} catch {\n\t\t\treturn { content: [...result.content, { type: \"text\", text: JSON.stringify({ phase: \"cleanup\", cleanup: \"unconfirmed\", guidance: \"Desktop ownership retained until shutdown is confirmed.\" }) }],\n\t\t\t\tdetails: { ...result.details, computer: { failed: true, workflow: \"cleanup_unconfirmed\" } }, isError: true };\n\t\t}\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.abort.abort();\n\t\tthis.observation = undefined;\n\t\tthis.closing ??= this.stop();\n\t\treturn this.closing;\n\t}\n\n\tprivate async stop(): Promise<void> {\n\t\tawait this.driver.close();\n\t\tawait this.lease.close();\n\t}\n}\n"]}
|