@beeos-ai/device-agent 0.4.0
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/.pi/extensions/android-tools.ts +139 -0
- package/.pi/skills/.gitkeep +0 -0
- package/.pi/skills/ground-mobile-fallback/SKILL.md +50 -0
- package/LICENSE +201 -0
- package/dist/action/handler.d.ts +9 -0
- package/dist/action/handler.js +124 -0
- package/dist/action/handler.js.map +1 -0
- package/dist/adapters/agent-gateway-client.d.ts +256 -0
- package/dist/adapters/agent-gateway-client.js +332 -0
- package/dist/adapters/agent-gateway-client.js.map +1 -0
- package/dist/adapters/agentcore-inner-loop.d.ts +29 -0
- package/dist/adapters/agentcore-inner-loop.js +72 -0
- package/dist/adapters/agentcore-inner-loop.js.map +1 -0
- package/dist/adapters/agentcore-pi.d.ts +215 -0
- package/dist/adapters/agentcore-pi.js +464 -0
- package/dist/adapters/agentcore-pi.js.map +1 -0
- package/dist/adapters/agentcore-runner.d.ts +70 -0
- package/dist/adapters/agentcore-runner.js +255 -0
- package/dist/adapters/agentcore-runner.js.map +1 -0
- package/dist/adapters/device-android-adb.d.ts +41 -0
- package/dist/adapters/device-android-adb.js +279 -0
- package/dist/adapters/device-android-adb.js.map +1 -0
- package/dist/adapters/device-desktop.d.ts +37 -0
- package/dist/adapters/device-desktop.js +101 -0
- package/dist/adapters/device-desktop.js.map +1 -0
- package/dist/adapters/identity-file.d.ts +30 -0
- package/dist/adapters/identity-file.js +50 -0
- package/dist/adapters/identity-file.js.map +1 -0
- package/dist/adapters/transport-bridge-ws.d.ts +39 -0
- package/dist/adapters/transport-bridge-ws.js +49 -0
- package/dist/adapters/transport-bridge-ws.js.map +1 -0
- package/dist/adapters/vlm-inner-loop.d.ts +88 -0
- package/dist/adapters/vlm-inner-loop.js +199 -0
- package/dist/adapters/vlm-inner-loop.js.map +1 -0
- package/dist/agent-runtime/adapters/base.d.ts +145 -0
- package/dist/agent-runtime/adapters/base.js +29 -0
- package/dist/agent-runtime/adapters/base.js.map +1 -0
- package/dist/agent-runtime/adapters/index.d.ts +17 -0
- package/dist/agent-runtime/adapters/index.js +17 -0
- package/dist/agent-runtime/adapters/index.js.map +1 -0
- package/dist/agent-runtime/adapters/mock.d.ts +44 -0
- package/dist/agent-runtime/adapters/mock.js +54 -0
- package/dist/agent-runtime/adapters/mock.js.map +1 -0
- package/dist/agent-runtime/adapters/openai.d.ts +63 -0
- package/dist/agent-runtime/adapters/openai.js +302 -0
- package/dist/agent-runtime/adapters/openai.js.map +1 -0
- package/dist/agent-runtime/adapters/registry.d.ts +49 -0
- package/dist/agent-runtime/adapters/registry.js +129 -0
- package/dist/agent-runtime/adapters/registry.js.map +1 -0
- package/dist/agent-runtime/adapters/ui-tars.d.ts +13 -0
- package/dist/agent-runtime/adapters/ui-tars.js +22 -0
- package/dist/agent-runtime/adapters/ui-tars.js.map +1 -0
- package/dist/agent-runtime/agent-runner.d.ts +149 -0
- package/dist/agent-runtime/agent-runner.js +356 -0
- package/dist/agent-runtime/agent-runner.js.map +1 -0
- package/dist/agent-runtime/core.d.ts +170 -0
- package/dist/agent-runtime/core.js +624 -0
- package/dist/agent-runtime/core.js.map +1 -0
- package/dist/agent-runtime/index.d.ts +16 -0
- package/dist/agent-runtime/index.js +17 -0
- package/dist/agent-runtime/index.js.map +1 -0
- package/dist/agent-runtime/plan-executor.d.ts +118 -0
- package/dist/agent-runtime/plan-executor.js +501 -0
- package/dist/agent-runtime/plan-executor.js.map +1 -0
- package/dist/agent-runtime/planner/base.d.ts +128 -0
- package/dist/agent-runtime/planner/base.js +157 -0
- package/dist/agent-runtime/planner/base.js.map +1 -0
- package/dist/agent-runtime/planner/llm-planner.d.ts +58 -0
- package/dist/agent-runtime/planner/llm-planner.js +112 -0
- package/dist/agent-runtime/planner/llm-planner.js.map +1 -0
- package/dist/agent-runtime/planner/noop-planner.d.ts +13 -0
- package/dist/agent-runtime/planner/noop-planner.js +30 -0
- package/dist/agent-runtime/planner/noop-planner.js.map +1 -0
- package/dist/agent-runtime/planner/prompts.d.ts +33 -0
- package/dist/agent-runtime/planner/prompts.js +165 -0
- package/dist/agent-runtime/planner/prompts.js.map +1 -0
- package/dist/agent-runtime/reflection.d.ts +81 -0
- package/dist/agent-runtime/reflection.js +189 -0
- package/dist/agent-runtime/reflection.js.map +1 -0
- package/dist/agent-runtime/reflectors/action-reflector.d.ts +97 -0
- package/dist/agent-runtime/reflectors/action-reflector.js +233 -0
- package/dist/agent-runtime/reflectors/action-reflector.js.map +1 -0
- package/dist/agent-runtime/reflectors/policy.d.ts +53 -0
- package/dist/agent-runtime/reflectors/policy.js +106 -0
- package/dist/agent-runtime/reflectors/policy.js.map +1 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.d.ts +94 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.js +223 -0
- package/dist/agent-runtime/reflectors/trajectory-reflector.js.map +1 -0
- package/dist/agent-runtime/skills/embedding.d.ts +53 -0
- package/dist/agent-runtime/skills/embedding.js +134 -0
- package/dist/agent-runtime/skills/embedding.js.map +1 -0
- package/dist/agent-runtime/skills/fs-store.d.ts +88 -0
- package/dist/agent-runtime/skills/fs-store.js +483 -0
- package/dist/agent-runtime/skills/fs-store.js.map +1 -0
- package/dist/agent-runtime/skills/index.d.ts +10 -0
- package/dist/agent-runtime/skills/index.js +10 -0
- package/dist/agent-runtime/skills/index.js.map +1 -0
- package/dist/agent-runtime/skills/matcher-evolver.d.ts +88 -0
- package/dist/agent-runtime/skills/matcher-evolver.js +110 -0
- package/dist/agent-runtime/skills/matcher-evolver.js.map +1 -0
- package/dist/agent-runtime/skills/memory-store.d.ts +23 -0
- package/dist/agent-runtime/skills/memory-store.js +94 -0
- package/dist/agent-runtime/skills/memory-store.js.map +1 -0
- package/dist/agent-runtime/skills/normalise.d.ts +40 -0
- package/dist/agent-runtime/skills/normalise.js +152 -0
- package/dist/agent-runtime/skills/normalise.js.map +1 -0
- package/dist/agent-runtime/skills/replay.d.ts +46 -0
- package/dist/agent-runtime/skills/replay.js +106 -0
- package/dist/agent-runtime/skills/replay.js.map +1 -0
- package/dist/agent-runtime/skills/sqlite-store.d.ts +60 -0
- package/dist/agent-runtime/skills/sqlite-store.js +234 -0
- package/dist/agent-runtime/skills/sqlite-store.js.map +1 -0
- package/dist/agent-runtime/skills/types.d.ts +99 -0
- package/dist/agent-runtime/skills/types.js +14 -0
- package/dist/agent-runtime/skills/types.js.map +1 -0
- package/dist/agent.d.ts +110 -0
- package/dist/agent.js +162 -0
- package/dist/agent.js.map +1 -0
- package/dist/api.d.ts +27 -0
- package/dist/api.js +48 -0
- package/dist/api.js.map +1 -0
- package/dist/app/agent-host.d.ts +59 -0
- package/dist/app/agent-host.js +263 -0
- package/dist/app/agent-host.js.map +1 -0
- package/dist/app/device-manager.d.ts +28 -0
- package/dist/app/device-manager.js +64 -0
- package/dist/app/device-manager.js.map +1 -0
- package/dist/app/message-store.d.ts +55 -0
- package/dist/app/message-store.js +99 -0
- package/dist/app/message-store.js.map +1 -0
- package/dist/app/session-manager.d.ts +132 -0
- package/dist/app/session-manager.js +350 -0
- package/dist/app/session-manager.js.map +1 -0
- package/dist/bootstrap.d.ts +94 -0
- package/dist/bootstrap.js +459 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/chat.d.ts +16 -0
- package/dist/chat.js +175 -0
- package/dist/chat.js.map +1 -0
- package/dist/config/loader.d.ts +77 -0
- package/dist/config/loader.js +292 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +162 -0
- package/dist/config/schema.js +243 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/actions.d.ts +60 -0
- package/dist/core/actions.js +120 -0
- package/dist/core/actions.js.map +1 -0
- package/dist/core/errors.d.ts +8 -0
- package/dist/core/errors.js +9 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/screen.d.ts +7 -0
- package/dist/core/screen.js +8 -0
- package/dist/core/screen.js.map +1 -0
- package/dist/core/session.d.ts +42 -0
- package/dist/core/session.js +29 -0
- package/dist/core/session.js.map +1 -0
- package/dist/debug/dump-system-prompt.d.ts +1 -0
- package/dist/debug/dump-system-prompt.js +34 -0
- package/dist/debug/dump-system-prompt.js.map +1 -0
- package/dist/device/android.d.ts +25 -0
- package/dist/device/android.js +231 -0
- package/dist/device/android.js.map +1 -0
- package/dist/device/apps.d.ts +3 -0
- package/dist/device/apps.js +77 -0
- package/dist/device/apps.js.map +1 -0
- package/dist/device/base.d.ts +20 -0
- package/dist/device/base.js +2 -0
- package/dist/device/base.js.map +1 -0
- package/dist/device/ui-xml.d.ts +29 -0
- package/dist/device/ui-xml.js +194 -0
- package/dist/device/ui-xml.js.map +1 -0
- package/dist/fleet/adapters/process/node-process-manager.d.ts +157 -0
- package/dist/fleet/adapters/process/node-process-manager.js +664 -0
- package/dist/fleet/adapters/process/node-process-manager.js.map +1 -0
- package/dist/fleet/adapters/sources/local-adb.d.ts +105 -0
- package/dist/fleet/adapters/sources/local-adb.js +353 -0
- package/dist/fleet/adapters/sources/local-adb.js.map +1 -0
- package/dist/fleet/adapters/sources/remote-adb.d.ts +97 -0
- package/dist/fleet/adapters/sources/remote-adb.js +138 -0
- package/dist/fleet/adapters/sources/remote-adb.js.map +1 -0
- package/dist/fleet/adapters/state/beeos-cli-store.d.ts +72 -0
- package/dist/fleet/adapters/state/beeos-cli-store.js +250 -0
- package/dist/fleet/adapters/state/beeos-cli-store.js.map +1 -0
- package/dist/fleet/adapters/state/port-allocator.d.ts +43 -0
- package/dist/fleet/adapters/state/port-allocator.js +173 -0
- package/dist/fleet/adapters/state/port-allocator.js.map +1 -0
- package/dist/fleet/domain/device.d.ts +138 -0
- package/dist/fleet/domain/device.js +49 -0
- package/dist/fleet/domain/device.js.map +1 -0
- package/dist/fleet/domain/events.d.ts +102 -0
- package/dist/fleet/domain/events.js +15 -0
- package/dist/fleet/domain/events.js.map +1 -0
- package/dist/fleet/domain/fsm.d.ts +122 -0
- package/dist/fleet/domain/fsm.js +475 -0
- package/dist/fleet/domain/fsm.js.map +1 -0
- package/dist/fleet/http/status-client.d.ts +31 -0
- package/dist/fleet/http/status-client.js +115 -0
- package/dist/fleet/http/status-client.js.map +1 -0
- package/dist/fleet/http/status-server.d.ts +64 -0
- package/dist/fleet/http/status-server.js +200 -0
- package/dist/fleet/http/status-server.js.map +1 -0
- package/dist/fleet/index.d.ts +27 -0
- package/dist/fleet/index.js +17 -0
- package/dist/fleet/index.js.map +1 -0
- package/dist/fleet/installer/index.d.ts +12 -0
- package/dist/fleet/installer/index.js +13 -0
- package/dist/fleet/installer/index.js.map +1 -0
- package/dist/fleet/installer/launchd-mac.d.ts +73 -0
- package/dist/fleet/installer/launchd-mac.js +291 -0
- package/dist/fleet/installer/launchd-mac.js.map +1 -0
- package/dist/fleet/installer/service-spec.d.ts +70 -0
- package/dist/fleet/installer/service-spec.js +43 -0
- package/dist/fleet/installer/service-spec.js.map +1 -0
- package/dist/fleet/installer/spawn-env.d.ts +45 -0
- package/dist/fleet/installer/spawn-env.js +224 -0
- package/dist/fleet/installer/spawn-env.js.map +1 -0
- package/dist/fleet/ports/clock.d.ts +19 -0
- package/dist/fleet/ports/clock.js +26 -0
- package/dist/fleet/ports/clock.js.map +1 -0
- package/dist/fleet/ports/device-source.d.ts +28 -0
- package/dist/fleet/ports/device-source.js +18 -0
- package/dist/fleet/ports/device-source.js.map +1 -0
- package/dist/fleet/ports/process-manager.d.ts +110 -0
- package/dist/fleet/ports/process-manager.js +27 -0
- package/dist/fleet/ports/process-manager.js.map +1 -0
- package/dist/fleet/ports/state-registry.d.ts +49 -0
- package/dist/fleet/ports/state-registry.js +12 -0
- package/dist/fleet/ports/state-registry.js.map +1 -0
- package/dist/fleet/supervisor.d.ts +107 -0
- package/dist/fleet/supervisor.js +508 -0
- package/dist/fleet/supervisor.js.map +1 -0
- package/dist/grounding/grounder.d.ts +46 -0
- package/dist/grounding/grounder.js +82 -0
- package/dist/grounding/grounder.js.map +1 -0
- package/dist/inbound/acp/handlers/device.d.ts +43 -0
- package/dist/inbound/acp/handlers/device.js +153 -0
- package/dist/inbound/acp/handlers/device.js.map +1 -0
- package/dist/inbound/acp/handlers/initialize.d.ts +71 -0
- package/dist/inbound/acp/handlers/initialize.js +53 -0
- package/dist/inbound/acp/handlers/initialize.js.map +1 -0
- package/dist/inbound/acp/handlers/models.d.ts +16 -0
- package/dist/inbound/acp/handlers/models.js +23 -0
- package/dist/inbound/acp/handlers/models.js.map +1 -0
- package/dist/inbound/acp/handlers/session.d.ts +51 -0
- package/dist/inbound/acp/handlers/session.js +61 -0
- package/dist/inbound/acp/handlers/session.js.map +1 -0
- package/dist/inbound/acp/handlers/skills.d.ts +8 -0
- package/dist/inbound/acp/handlers/skills.js +9 -0
- package/dist/inbound/acp/handlers/skills.js.map +1 -0
- package/dist/inbound/acp/notifier.d.ts +35 -0
- package/dist/inbound/acp/notifier.js +45 -0
- package/dist/inbound/acp/notifier.js.map +1 -0
- package/dist/inbound/acp/router.d.ts +67 -0
- package/dist/inbound/acp/router.js +179 -0
- package/dist/inbound/acp/router.js.map +1 -0
- package/dist/inbound/cli/fleet-command.d.ts +34 -0
- package/dist/inbound/cli/fleet-command.js +792 -0
- package/dist/inbound/cli/fleet-command.js.map +1 -0
- package/dist/inbound/cli/main.d.ts +38 -0
- package/dist/inbound/cli/main.js +364 -0
- package/dist/inbound/cli/main.js.map +1 -0
- package/dist/inbound/cli/run-command.d.ts +101 -0
- package/dist/inbound/cli/run-command.js +405 -0
- package/dist/inbound/cli/run-command.js.map +1 -0
- package/dist/inbound/cli/skills-command.d.ts +39 -0
- package/dist/inbound/cli/skills-command.js +333 -0
- package/dist/inbound/cli/skills-command.js.map +1 -0
- package/dist/inbound/http/server.d.ts +7 -0
- package/dist/inbound/http/server.js +8 -0
- package/dist/inbound/http/server.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/index.d.ts +37 -0
- package/dist/logger/index.js +84 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/mcp-client/autospawn.d.ts +67 -0
- package/dist/mcp-client/autospawn.js +173 -0
- package/dist/mcp-client/autospawn.js.map +1 -0
- package/dist/mcp-client/client.d.ts +78 -0
- package/dist/mcp-client/client.js +168 -0
- package/dist/mcp-client/client.js.map +1 -0
- package/dist/mcp-client/index.d.ts +7 -0
- package/dist/mcp-client/index.js +4 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/inproc.d.ts +47 -0
- package/dist/mcp-client/inproc.js +229 -0
- package/dist/mcp-client/inproc.js.map +1 -0
- package/dist/mcp-client/runtime.d.ts +34 -0
- package/dist/mcp-client/runtime.js +15 -0
- package/dist/mcp-client/runtime.js.map +1 -0
- package/dist/model/adapters/autoglm.d.ts +31 -0
- package/dist/model/adapters/autoglm.js +409 -0
- package/dist/model/adapters/autoglm.js.map +1 -0
- package/dist/model/adapters/base.d.ts +13 -0
- package/dist/model/adapters/base.js +27 -0
- package/dist/model/adapters/base.js.map +1 -0
- package/dist/model/adapters/guiowl.d.ts +1 -0
- package/dist/model/adapters/guiowl.js +253 -0
- package/dist/model/adapters/guiowl.js.map +1 -0
- package/dist/model/adapters/index.d.ts +6 -0
- package/dist/model/adapters/index.js +8 -0
- package/dist/model/adapters/index.js.map +1 -0
- package/dist/model/adapters/maiui.d.ts +1 -0
- package/dist/model/adapters/maiui.js +117 -0
- package/dist/model/adapters/maiui.js.map +1 -0
- package/dist/model/adapters/qwenvl.d.ts +1 -0
- package/dist/model/adapters/qwenvl.js +108 -0
- package/dist/model/adapters/qwenvl.js.map +1 -0
- package/dist/model/adapters/showui.d.ts +1 -0
- package/dist/model/adapters/showui.js +132 -0
- package/dist/model/adapters/showui.js.map +1 -0
- package/dist/model/adapters/tool-call.d.ts +6 -0
- package/dist/model/adapters/tool-call.js +102 -0
- package/dist/model/adapters/tool-call.js.map +1 -0
- package/dist/model/adapters/uitars.d.ts +1 -0
- package/dist/model/adapters/uitars.js +180 -0
- package/dist/model/adapters/uitars.js.map +1 -0
- package/dist/model/base.d.ts +32 -0
- package/dist/model/base.js +2 -0
- package/dist/model/base.js.map +1 -0
- package/dist/model/client.d.ts +26 -0
- package/dist/model/client.js +300 -0
- package/dist/model/client.js.map +1 -0
- package/dist/model/image/compress.d.ts +53 -0
- package/dist/model/image/compress.js +89 -0
- package/dist/model/image/compress.js.map +1 -0
- package/dist/model/image/transport.d.ts +134 -0
- package/dist/model/image/transport.js +154 -0
- package/dist/model/image/transport.js.map +1 -0
- package/dist/orchestrator-system-prompt.d.ts +6 -0
- package/dist/orchestrator-system-prompt.js +81 -0
- package/dist/orchestrator-system-prompt.js.map +1 -0
- package/dist/pi-context.d.ts +82 -0
- package/dist/pi-context.js +62 -0
- package/dist/pi-context.js.map +1 -0
- package/dist/pi-local-skills.d.ts +17 -0
- package/dist/pi-local-skills.js +24 -0
- package/dist/pi-local-skills.js.map +1 -0
- package/dist/plugins/acp/index.d.ts +46 -0
- package/dist/plugins/acp/index.js +111 -0
- package/dist/plugins/acp/index.js.map +1 -0
- package/dist/plugins/agent-sync/index.d.ts +40 -0
- package/dist/plugins/agent-sync/index.js +98 -0
- package/dist/plugins/agent-sync/index.js.map +1 -0
- package/dist/plugins/http-debug/index.d.ts +30 -0
- package/dist/plugins/http-debug/index.js +64 -0
- package/dist/plugins/http-debug/index.js.map +1 -0
- package/dist/plugins/http-debug/server.d.ts +92 -0
- package/dist/plugins/http-debug/server.js +464 -0
- package/dist/plugins/http-debug/server.js.map +1 -0
- package/dist/ports/agent-core.d.ts +158 -0
- package/dist/ports/agent-core.js +2 -0
- package/dist/ports/agent-core.js.map +1 -0
- package/dist/ports/agent-host.d.ts +125 -0
- package/dist/ports/agent-host.js +23 -0
- package/dist/ports/agent-host.js.map +1 -0
- package/dist/ports/device.d.ts +53 -0
- package/dist/ports/device.js +13 -0
- package/dist/ports/device.js.map +1 -0
- package/dist/ports/identity.d.ts +22 -0
- package/dist/ports/identity.js +9 -0
- package/dist/ports/identity.js.map +1 -0
- package/dist/ports/plugin.d.ts +62 -0
- package/dist/ports/plugin.js +35 -0
- package/dist/ports/plugin.js.map +1 -0
- package/dist/ports/transport.d.ts +32 -0
- package/dist/ports/transport.js +12 -0
- package/dist/ports/transport.js.map +1 -0
- package/dist/ports/vlm.d.ts +59 -0
- package/dist/ports/vlm.js +14 -0
- package/dist/ports/vlm.js.map +1 -0
- package/dist/test-lan-autoglm.d.ts +7 -0
- package/dist/test-lan-autoglm.js +46 -0
- package/dist/test-lan-autoglm.js.map +1 -0
- package/dist/test-mem-breakdown.d.ts +1 -0
- package/dist/test-mem-breakdown.js +103 -0
- package/dist/test-mem-breakdown.js.map +1 -0
- package/dist/test-mem.d.ts +1 -0
- package/dist/test-mem.js +60 -0
- package/dist/test-mem.js.map +1 -0
- package/dist/test-mobile-use.d.ts +1 -0
- package/dist/test-mobile-use.js +18 -0
- package/dist/test-mobile-use.js.map +1 -0
- package/dist/test-screenshot-loop.d.ts +1 -0
- package/dist/test-screenshot-loop.js +43 -0
- package/dist/test-screenshot-loop.js.map +1 -0
- package/dist/test-screenshot.d.ts +1 -0
- package/dist/test-screenshot.js +10 -0
- package/dist/test-screenshot.js.map +1 -0
- package/dist/test-ui-xml-dump.d.ts +15 -0
- package/dist/test-ui-xml-dump.js +49 -0
- package/dist/test-ui-xml-dump.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beeos-ai/device-agent — agent-runtime barrel.
|
|
3
|
+
*
|
|
4
|
+
* Public API for the new Plan-Act-Reflect loop and adapter registry.
|
|
5
|
+
*/
|
|
6
|
+
export { AgentLoop, type AgentErrorCode, type AgentErrorEvent, type AgentLoopTerminator, type AgentRunHooks, type AgentRunOptions, type AgentRunResult, type AgentStepEvent, type AgentToolEvent, } from "./core.js";
|
|
7
|
+
export { HierarchicalReflector, actionsEqual, type HierarchicalReflectorOptions, type PreActionVeto, } from "./reflection.js";
|
|
8
|
+
export { HIGH_RISK_VERBS, LLMActionReflector, type ActionReflectCtx, type ActionReflectVerdict, type ActionReflectorGating, type IActionReflector, type LLMActionReflectorOptions, } from "./reflectors/action-reflector.js";
|
|
9
|
+
export { buildReflectorPolicyFromEnv, resolveActionReflector, resolveTrajectoryReflector, type ReflectorPolicy, } from "./reflectors/policy.js";
|
|
10
|
+
export { availableAdapters, clearAdapters, makePrediction, MockAdapter, OpenAIAdapter, parsedToAction, registerAdapter, resolveAdapter, resolveAdapterSync, UITarsAdapter, type AdapterDescriptor, type IModelAdapter, type MockAdapterOptions, type ModelUsage, type OpenAIAdapterOptions, type PredictHooks, type PredictOptions, type Prediction, type StepHistory, } from "./adapters/index.js";
|
|
11
|
+
export { extractFirstJson, makePlanResult, normalisePlanPayload, type IPlanner, type Plan, type PlanContext, type PlanOptions, type PlanResult, type PlanStep, } from "./planner/base.js";
|
|
12
|
+
export { LLMPlanner, type LLMPlannerOptions } from "./planner/llm-planner.js";
|
|
13
|
+
export { NoOpPlanner } from "./planner/noop-planner.js";
|
|
14
|
+
export { PlanExecutor, type PlanExecutorOptions, type PlanExecutorResult, } from "./plan-executor.js";
|
|
15
|
+
export { AgentRunner, type AgentPlanMode, type AgentRunnerOptions, type AgentRunnerResult, } from "./agent-runner.js";
|
|
16
|
+
export { bufferToEmbedding, cosine, DEFAULT_EMBEDDING_DIM, defaultSkillCachePath, embeddingToBuffer, evolveSkill, FileSystemSkillCacheStore, HashEmbeddingProvider, InMemorySkillCacheStore, matchSkill, normaliseActionSequence, similarityRatio, type EmbeddingProvider, type FileSystemSkillCacheStoreOptions, type NewSkillInput, type Skill, type SkillActionSequence, type SkillCacheStore, type SkillEvolverOptions, type SkillMatch, type SkillMatcherOptions, type SkillMatchOutcome, type SkillSummary, } from "./skills/index.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beeos-ai/device-agent — agent-runtime barrel.
|
|
3
|
+
*
|
|
4
|
+
* Public API for the new Plan-Act-Reflect loop and adapter registry.
|
|
5
|
+
*/
|
|
6
|
+
export { AgentLoop, } from "./core.js";
|
|
7
|
+
export { HierarchicalReflector, actionsEqual, } from "./reflection.js";
|
|
8
|
+
export { HIGH_RISK_VERBS, LLMActionReflector, } from "./reflectors/action-reflector.js";
|
|
9
|
+
export { buildReflectorPolicyFromEnv, resolveActionReflector, resolveTrajectoryReflector, } from "./reflectors/policy.js";
|
|
10
|
+
export { availableAdapters, clearAdapters, makePrediction, MockAdapter, OpenAIAdapter, parsedToAction, registerAdapter, resolveAdapter, resolveAdapterSync, UITarsAdapter, } from "./adapters/index.js";
|
|
11
|
+
export { extractFirstJson, makePlanResult, normalisePlanPayload, } from "./planner/base.js";
|
|
12
|
+
export { LLMPlanner } from "./planner/llm-planner.js";
|
|
13
|
+
export { NoOpPlanner } from "./planner/noop-planner.js";
|
|
14
|
+
export { PlanExecutor, } from "./plan-executor.js";
|
|
15
|
+
export { AgentRunner, } from "./agent-runner.js";
|
|
16
|
+
export { bufferToEmbedding, cosine, DEFAULT_EMBEDDING_DIM, defaultSkillCachePath, embeddingToBuffer, evolveSkill, FileSystemSkillCacheStore, HashEmbeddingProvider, InMemorySkillCacheStore, matchSkill, normaliseActionSequence, similarityRatio, } from "./skills/index.js";
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-runtime/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,SAAS,GASV,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,YAAY,GAGb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,eAAe,EACf,kBAAkB,GAMnB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,0BAA0B,GAE3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,aAAa,GAUd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,oBAAoB,GAOrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA0B,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,GAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,iBAAiB,EACjB,MAAM,EACN,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACX,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,EACV,uBAAuB,EACvB,eAAe,GAYhB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/plan-executor — runs a structured Plan by spinning up
|
|
3
|
+
* one `AgentLoop` per `PlanStep`.
|
|
4
|
+
*
|
|
5
|
+
* This is the bridge between the *strategy* tier (`IPlanner`) and the
|
|
6
|
+
* *act* tier (`AgentLoop` + `IModelAdapter` + `IMcpRuntime`):
|
|
7
|
+
*
|
|
8
|
+
* - For each `PlanStep`, we spawn a focused `AgentLoop` whose
|
|
9
|
+
* `task` is the step description (the inner adapter sees only this
|
|
10
|
+
* mini-goal and natural-language target hints) and whose step
|
|
11
|
+
* budget is `step.maxSteps ?? perStepBudget`.
|
|
12
|
+
* - When a step's loop terminates with `done` we move on; with
|
|
13
|
+
* `fail` / `step_budget` / `reflection_veto` / `timeout` we ask
|
|
14
|
+
* the planner to `replan()` (up to `maxReplans` times). The
|
|
15
|
+
* replanned `Plan` replaces the remainder of the current plan.
|
|
16
|
+
* - When all replans are exhausted we make a single ReAct fallback
|
|
17
|
+
* attempt — a fresh `AgentLoop` over the original goal — and
|
|
18
|
+
* accept its result as terminal.
|
|
19
|
+
*
|
|
20
|
+
* Mirrors the spirit (not the line-by-line shape) of the Python
|
|
21
|
+
* reference at
|
|
22
|
+
* /Users/heat/workspace/deviceagent_research/deviceagent/agent_runtime/loop/plan_executor.py
|
|
23
|
+
*
|
|
24
|
+
* Differences from the reference:
|
|
25
|
+
* - We delegate per-step grounding + acting back to a full
|
|
26
|
+
* `AgentLoop`, instead of explicit Grounder + Verifier passes —
|
|
27
|
+
* AutoGLM-Phone-9B does both in one VLM call already.
|
|
28
|
+
* - We don't keep a `Verifier` tier yet; the inner loop's
|
|
29
|
+
* `done` / `fail` short-circuit is the verification signal.
|
|
30
|
+
* - We don't pull `accessibility_tree` (the v0.2.3 mcp-server doesn't
|
|
31
|
+
* expose it).
|
|
32
|
+
*/
|
|
33
|
+
import type { Action, Observation } from "@beeos-ai/device-common";
|
|
34
|
+
import type { IMcpRuntime } from "../mcp-client/runtime.js";
|
|
35
|
+
import type { IModelAdapter, ModelUsage, StepHistory } from "./adapters/base.js";
|
|
36
|
+
import { type AgentLoopTerminator, type AgentRunHooks } from "./core.js";
|
|
37
|
+
import type { IPlanner } from "./planner/base.js";
|
|
38
|
+
import type { HierarchicalReflector } from "./reflection.js";
|
|
39
|
+
export interface PlanExecutorOptions {
|
|
40
|
+
planner: IPlanner;
|
|
41
|
+
adapter: IModelAdapter;
|
|
42
|
+
mcp: IMcpRuntime;
|
|
43
|
+
goal: string;
|
|
44
|
+
env: Observation["env"];
|
|
45
|
+
/** Total step budget across the entire run. Defaults to 30. */
|
|
46
|
+
maxSteps?: number;
|
|
47
|
+
/** Per sub-task default step budget. Defaults to `ceil(maxSteps / steps)`. */
|
|
48
|
+
perStepBudget?: number;
|
|
49
|
+
/** Wall-clock deadline. Defaults to 5 minutes. */
|
|
50
|
+
timeoutMs?: number;
|
|
51
|
+
/** Maximum number of `planner.replan()` calls allowed. Defaults to 2. */
|
|
52
|
+
maxReplans?: number;
|
|
53
|
+
/** Optional outside cancellation. */
|
|
54
|
+
signal?: AbortSignal;
|
|
55
|
+
/** Streaming hooks forwarded to the inner `AgentLoop`. */
|
|
56
|
+
hooks?: AgentRunHooks;
|
|
57
|
+
/**
|
|
58
|
+
* When `true` (default), exhausting replans triggers a single ReAct
|
|
59
|
+
* fallback over the original goal. Set to `false` for tests / when the
|
|
60
|
+
* caller wants to handle escalation themselves.
|
|
61
|
+
*/
|
|
62
|
+
reactFallback?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Optional reflector shared with the parent {@link AgentRunner}. When
|
|
65
|
+
* provided, every spawned `AgentLoop` reuses the same instance so that
|
|
66
|
+
* Phase 1.4 (model-based action reflector) and Phase 2.2 (trajectory
|
|
67
|
+
* reflector) configuration is applied uniformly across sub-tasks and
|
|
68
|
+
* the ReAct fallback. When omitted, each `AgentLoop` constructs its
|
|
69
|
+
* own (heuristic-only) reflector — preserving legacy behaviour.
|
|
70
|
+
*/
|
|
71
|
+
reflector?: HierarchicalReflector;
|
|
72
|
+
}
|
|
73
|
+
export interface PlanExecutorResult {
|
|
74
|
+
/** Strict success only when the last `AgentLoop` ended with `done`. */
|
|
75
|
+
ok: boolean;
|
|
76
|
+
finalText: string;
|
|
77
|
+
steps: number;
|
|
78
|
+
/** Aggregated usage across all loops + planner calls. */
|
|
79
|
+
usage: ModelUsage;
|
|
80
|
+
history: StepHistory[];
|
|
81
|
+
/** Number of distinct plans the executor went through (1 + replans). */
|
|
82
|
+
plansEmitted: number;
|
|
83
|
+
/** Number of replan calls (≤ `maxReplans`). */
|
|
84
|
+
replans: number;
|
|
85
|
+
/** Whether the ReAct fallback was used. */
|
|
86
|
+
reactFallbackUsed: boolean;
|
|
87
|
+
/** Final terminator of the *last* AgentLoop. */
|
|
88
|
+
terminator: AgentLoopTerminator;
|
|
89
|
+
cancelled: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Phase 2.1 — flat union of every note collected by inner AgentLoops,
|
|
92
|
+
* preserved in observation order. Surfaced through {@link AgentRunner}
|
|
93
|
+
* to the caller so they can stitch notes into downstream UX.
|
|
94
|
+
*/
|
|
95
|
+
notes: string[];
|
|
96
|
+
}
|
|
97
|
+
export declare class PlanExecutor {
|
|
98
|
+
private readonly opts;
|
|
99
|
+
private static readonly DEFAULT_MAX_STEPS;
|
|
100
|
+
private static readonly DEFAULT_TIMEOUT_MS;
|
|
101
|
+
private static readonly DEFAULT_MAX_REPLANS;
|
|
102
|
+
constructor(opts: PlanExecutorOptions);
|
|
103
|
+
run(): Promise<PlanExecutorResult>;
|
|
104
|
+
private firePlan;
|
|
105
|
+
private fireError;
|
|
106
|
+
private finish;
|
|
107
|
+
/**
|
|
108
|
+
* Build a fresh `Observation` snapshot to feed the (text-only) planner on
|
|
109
|
+
* the replan path. Always pulls the screenshot (cheap; needed for
|
|
110
|
+
* `screenW/screenH`) and unconditionally tries `mcp.uiDump()` — for the
|
|
111
|
+
* planner the UI hierarchy is genuinely useful (it can't see pixels), and
|
|
112
|
+
* this is independent of whether the inner adapter consumes ui_dump.
|
|
113
|
+
* Returns `undefined` only when even the screenshot fails, so the replan
|
|
114
|
+
* still has a chance to fire with the previous plan + history alone.
|
|
115
|
+
*/
|
|
116
|
+
private snapshotForPlanner;
|
|
117
|
+
}
|
|
118
|
+
export type { Action };
|
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/plan-executor — runs a structured Plan by spinning up
|
|
3
|
+
* one `AgentLoop` per `PlanStep`.
|
|
4
|
+
*
|
|
5
|
+
* This is the bridge between the *strategy* tier (`IPlanner`) and the
|
|
6
|
+
* *act* tier (`AgentLoop` + `IModelAdapter` + `IMcpRuntime`):
|
|
7
|
+
*
|
|
8
|
+
* - For each `PlanStep`, we spawn a focused `AgentLoop` whose
|
|
9
|
+
* `task` is the step description (the inner adapter sees only this
|
|
10
|
+
* mini-goal and natural-language target hints) and whose step
|
|
11
|
+
* budget is `step.maxSteps ?? perStepBudget`.
|
|
12
|
+
* - When a step's loop terminates with `done` we move on; with
|
|
13
|
+
* `fail` / `step_budget` / `reflection_veto` / `timeout` we ask
|
|
14
|
+
* the planner to `replan()` (up to `maxReplans` times). The
|
|
15
|
+
* replanned `Plan` replaces the remainder of the current plan.
|
|
16
|
+
* - When all replans are exhausted we make a single ReAct fallback
|
|
17
|
+
* attempt — a fresh `AgentLoop` over the original goal — and
|
|
18
|
+
* accept its result as terminal.
|
|
19
|
+
*
|
|
20
|
+
* Mirrors the spirit (not the line-by-line shape) of the Python
|
|
21
|
+
* reference at
|
|
22
|
+
* /Users/heat/workspace/deviceagent_research/deviceagent/agent_runtime/loop/plan_executor.py
|
|
23
|
+
*
|
|
24
|
+
* Differences from the reference:
|
|
25
|
+
* - We delegate per-step grounding + acting back to a full
|
|
26
|
+
* `AgentLoop`, instead of explicit Grounder + Verifier passes —
|
|
27
|
+
* AutoGLM-Phone-9B does both in one VLM call already.
|
|
28
|
+
* - We don't keep a `Verifier` tier yet; the inner loop's
|
|
29
|
+
* `done` / `fail` short-circuit is the verification signal.
|
|
30
|
+
* - We don't pull `accessibility_tree` (the v0.2.3 mcp-server doesn't
|
|
31
|
+
* expose it).
|
|
32
|
+
*/
|
|
33
|
+
import { AgentLoop, } from "./core.js";
|
|
34
|
+
/* ──────────────────────────────────────────────────────────────────────── */
|
|
35
|
+
/* PlanExecutor */
|
|
36
|
+
/* ──────────────────────────────────────────────────────────────────────── */
|
|
37
|
+
const SUCCESS_TERMINATORS = new Set(["done"]);
|
|
38
|
+
/** Subtask terminators we treat as recoverable enough to attempt a replan. */
|
|
39
|
+
const REPLAN_TERMINATORS = new Set([
|
|
40
|
+
"fail",
|
|
41
|
+
"step_budget",
|
|
42
|
+
"timeout",
|
|
43
|
+
"reflection_veto",
|
|
44
|
+
"error",
|
|
45
|
+
"call_for_user",
|
|
46
|
+
]);
|
|
47
|
+
export class PlanExecutor {
|
|
48
|
+
opts;
|
|
49
|
+
static DEFAULT_MAX_STEPS = 30;
|
|
50
|
+
static DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
51
|
+
static DEFAULT_MAX_REPLANS = 2;
|
|
52
|
+
constructor(opts) {
|
|
53
|
+
this.opts = opts;
|
|
54
|
+
}
|
|
55
|
+
async run() {
|
|
56
|
+
const maxSteps = this.opts.maxSteps ?? PlanExecutor.DEFAULT_MAX_STEPS;
|
|
57
|
+
const timeoutMs = this.opts.timeoutMs ?? PlanExecutor.DEFAULT_TIMEOUT_MS;
|
|
58
|
+
const maxReplans = this.opts.maxReplans ?? PlanExecutor.DEFAULT_MAX_REPLANS;
|
|
59
|
+
const deadline = Date.now() + timeoutMs;
|
|
60
|
+
const reactFallback = this.opts.reactFallback ?? true;
|
|
61
|
+
const usage = { inputTokens: 0, outputTokens: 0 };
|
|
62
|
+
const history = [];
|
|
63
|
+
const notes = [];
|
|
64
|
+
let stepsConsumed = 0;
|
|
65
|
+
let plansEmitted = 0;
|
|
66
|
+
let replans = 0;
|
|
67
|
+
let reactFallbackUsed = false;
|
|
68
|
+
let lastTerminator = "error";
|
|
69
|
+
let lastFinalText = "";
|
|
70
|
+
/**
|
|
71
|
+
* Phase 2.2 / 2.3 — most recent non-`on_track` verdict from any inner
|
|
72
|
+
* AgentLoop. Threaded into the next `PlanContext.trajectoryVerdict`
|
|
73
|
+
* so the planner can pivot the plan rather than re-deriving the
|
|
74
|
+
* failure mode.
|
|
75
|
+
*/
|
|
76
|
+
let lastTrajectoryVerdict;
|
|
77
|
+
// ── Initial plan ────────────────────────────────────────────────────
|
|
78
|
+
// The planner round-trip can fail intermittently (upstream LLM 5xx /
|
|
79
|
+
// network reset). Don't let that bubble up as a fatal task error —
|
|
80
|
+
// when `reactFallback` is enabled we degrade gracefully into a pure
|
|
81
|
+
// ReAct loop so the user-visible task can still make progress.
|
|
82
|
+
let firstPlanRes;
|
|
83
|
+
try {
|
|
84
|
+
firstPlanRes = await this.opts.planner.makePlan({ goal: this.opts.goal, history: [] }, { signal: this.opts.signal });
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
await this.fireError(`makePlan failed: ${errMsg(e)}`);
|
|
88
|
+
if (reactFallback) {
|
|
89
|
+
const planFbRemaining = deadline - Date.now();
|
|
90
|
+
if (planFbRemaining <= 0) {
|
|
91
|
+
return this.finish({
|
|
92
|
+
ok: false,
|
|
93
|
+
finalText: `plan executor exceeded ${timeoutMs}ms budget`,
|
|
94
|
+
stepsConsumed,
|
|
95
|
+
usage,
|
|
96
|
+
history,
|
|
97
|
+
notes,
|
|
98
|
+
plansEmitted,
|
|
99
|
+
replans,
|
|
100
|
+
reactFallbackUsed,
|
|
101
|
+
terminator: "timeout",
|
|
102
|
+
cancelled: false,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
reactFallbackUsed = true;
|
|
106
|
+
const fb = await new AgentLoop({
|
|
107
|
+
task: this.opts.goal,
|
|
108
|
+
env: this.opts.env,
|
|
109
|
+
mcp: this.opts.mcp,
|
|
110
|
+
adapter: this.opts.adapter,
|
|
111
|
+
maxSteps: Math.max(1, maxSteps - stepsConsumed),
|
|
112
|
+
timeoutMs: planFbRemaining,
|
|
113
|
+
signal: this.opts.signal,
|
|
114
|
+
hooks: this.opts.hooks,
|
|
115
|
+
reflector: this.opts.reflector,
|
|
116
|
+
}).run();
|
|
117
|
+
stepsConsumed += fb.steps;
|
|
118
|
+
accumulateUsage(usage, fb.usage);
|
|
119
|
+
history.push(...fb.history);
|
|
120
|
+
notes.push(...fb.notes);
|
|
121
|
+
return this.finish({
|
|
122
|
+
ok: SUCCESS_TERMINATORS.has(fb.terminator),
|
|
123
|
+
finalText: fb.finalText,
|
|
124
|
+
stepsConsumed,
|
|
125
|
+
usage,
|
|
126
|
+
history,
|
|
127
|
+
notes,
|
|
128
|
+
plansEmitted,
|
|
129
|
+
replans,
|
|
130
|
+
reactFallbackUsed,
|
|
131
|
+
terminator: fb.terminator,
|
|
132
|
+
cancelled: fb.terminator === "cancelled",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
throw e;
|
|
136
|
+
}
|
|
137
|
+
let plan = firstPlanRes.plan;
|
|
138
|
+
accumulateUsage(usage, firstPlanRes.usage);
|
|
139
|
+
plansEmitted += 1;
|
|
140
|
+
await this.firePlan(plan, /*isReplan*/ false, replans);
|
|
141
|
+
// ── Main loop: walk the plan ───────────────────────────────────────
|
|
142
|
+
let cur = 0;
|
|
143
|
+
while (cur < plan.steps.length) {
|
|
144
|
+
if (this.opts.signal?.aborted) {
|
|
145
|
+
return this.finish({
|
|
146
|
+
ok: false,
|
|
147
|
+
finalText: "Task cancelled",
|
|
148
|
+
stepsConsumed,
|
|
149
|
+
usage,
|
|
150
|
+
history,
|
|
151
|
+
notes,
|
|
152
|
+
plansEmitted,
|
|
153
|
+
replans,
|
|
154
|
+
reactFallbackUsed,
|
|
155
|
+
terminator: "cancelled",
|
|
156
|
+
cancelled: true,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (Date.now() > deadline) {
|
|
160
|
+
return this.finish({
|
|
161
|
+
ok: false,
|
|
162
|
+
finalText: `plan executor exceeded ${timeoutMs}ms budget`,
|
|
163
|
+
stepsConsumed,
|
|
164
|
+
usage,
|
|
165
|
+
history,
|
|
166
|
+
notes,
|
|
167
|
+
plansEmitted,
|
|
168
|
+
replans,
|
|
169
|
+
reactFallbackUsed,
|
|
170
|
+
terminator: "timeout",
|
|
171
|
+
cancelled: false,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const stepsLeft = maxSteps - stepsConsumed;
|
|
175
|
+
if (stepsLeft <= 0) {
|
|
176
|
+
return this.finish({
|
|
177
|
+
ok: false,
|
|
178
|
+
finalText: `hit step budget ${maxSteps}`,
|
|
179
|
+
stepsConsumed,
|
|
180
|
+
usage,
|
|
181
|
+
history,
|
|
182
|
+
notes,
|
|
183
|
+
plansEmitted,
|
|
184
|
+
replans,
|
|
185
|
+
reactFallbackUsed,
|
|
186
|
+
terminator: "step_budget",
|
|
187
|
+
cancelled: false,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const step = plan.steps[cur];
|
|
191
|
+
const subBudget = clamp(step.maxSteps ?? this.opts.perStepBudget ?? defaultPerStepBudget(plan.steps.length, maxSteps), 1, stepsLeft);
|
|
192
|
+
const innerTask = formatStepAsTask(this.opts.goal, plan, cur);
|
|
193
|
+
// CRITICAL: do NOT clamp the inner timeout to a floor (1000ms) —
|
|
194
|
+
// when the wall-clock budget is already exhausted that floor
|
|
195
|
+
// makes the child AgentLoop pretend it still has 1s, which
|
|
196
|
+
// immediately re-fires `agent exceeded 1000ms budget`. The user
|
|
197
|
+
// sees absurd "94220ms → 1000ms" budget messages back-to-back
|
|
198
|
+
// because every replan stage spawns one of these doomed children.
|
|
199
|
+
// Honour the real remaining budget; if it's already gone, end
|
|
200
|
+
// the executor with `timeout` directly.
|
|
201
|
+
const innerRemaining = deadline - Date.now();
|
|
202
|
+
if (innerRemaining <= 0) {
|
|
203
|
+
return this.finish({
|
|
204
|
+
ok: false,
|
|
205
|
+
finalText: `plan executor exceeded ${timeoutMs}ms budget`,
|
|
206
|
+
stepsConsumed,
|
|
207
|
+
usage,
|
|
208
|
+
history,
|
|
209
|
+
notes,
|
|
210
|
+
plansEmitted,
|
|
211
|
+
replans,
|
|
212
|
+
reactFallbackUsed,
|
|
213
|
+
terminator: "timeout",
|
|
214
|
+
cancelled: false,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const result = await new AgentLoop({
|
|
218
|
+
task: innerTask,
|
|
219
|
+
env: this.opts.env,
|
|
220
|
+
mcp: this.opts.mcp,
|
|
221
|
+
adapter: this.opts.adapter,
|
|
222
|
+
maxSteps: subBudget,
|
|
223
|
+
timeoutMs: innerRemaining,
|
|
224
|
+
signal: this.opts.signal,
|
|
225
|
+
hooks: this.opts.hooks,
|
|
226
|
+
reflector: this.opts.reflector,
|
|
227
|
+
}).run();
|
|
228
|
+
stepsConsumed += result.steps;
|
|
229
|
+
accumulateUsage(usage, result.usage);
|
|
230
|
+
history.push(...result.history);
|
|
231
|
+
notes.push(...result.notes);
|
|
232
|
+
if (result.trajectoryVerdict)
|
|
233
|
+
lastTrajectoryVerdict = result.trajectoryVerdict;
|
|
234
|
+
lastTerminator = result.terminator;
|
|
235
|
+
lastFinalText = result.finalText;
|
|
236
|
+
if (SUCCESS_TERMINATORS.has(result.terminator)) {
|
|
237
|
+
cur += 1;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
// Sub-task did not finish cleanly — try a replan if we still can.
|
|
241
|
+
if (result.terminator === "cancelled") {
|
|
242
|
+
return this.finish({
|
|
243
|
+
ok: false,
|
|
244
|
+
finalText: result.finalText,
|
|
245
|
+
stepsConsumed,
|
|
246
|
+
usage,
|
|
247
|
+
history,
|
|
248
|
+
notes,
|
|
249
|
+
plansEmitted,
|
|
250
|
+
replans,
|
|
251
|
+
reactFallbackUsed,
|
|
252
|
+
terminator: "cancelled",
|
|
253
|
+
cancelled: true,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
if (replans < maxReplans && REPLAN_TERMINATORS.has(result.terminator)) {
|
|
257
|
+
replans += 1;
|
|
258
|
+
// Take a fresh observation snapshot so the (text-only) planner can
|
|
259
|
+
// see what the screen looks like *now* — the inner AgentLoop's last
|
|
260
|
+
// observation is gone by this point, and the screen state may have
|
|
261
|
+
// shifted between the loop ending and the replan firing. Both the
|
|
262
|
+
// screenshot and ui_dump are best-effort: a failure here must not
|
|
263
|
+
// block the replan attempt itself.
|
|
264
|
+
const ctx = {
|
|
265
|
+
goal: this.opts.goal,
|
|
266
|
+
observation: await this.snapshotForPlanner(),
|
|
267
|
+
history,
|
|
268
|
+
previousPlan: plan,
|
|
269
|
+
failureReason: `step ${step.idx} (${step.description}) ended with ${result.terminator}: ${result.finalText}`,
|
|
270
|
+
lastStepIdx: step.idx,
|
|
271
|
+
// Phase 2.1 / 2.3 — surface accumulated notes to the planner.
|
|
272
|
+
notes: notes.length > 0 ? [...notes] : undefined,
|
|
273
|
+
// Phase 2.2 / 2.3 — surface the most recent trajectory verdict so
|
|
274
|
+
// the planner can react to "off_track" / "stuck" explicitly.
|
|
275
|
+
trajectoryVerdict: lastTrajectoryVerdict,
|
|
276
|
+
};
|
|
277
|
+
try {
|
|
278
|
+
const repl = await this.opts.planner.replan(ctx, { signal: this.opts.signal });
|
|
279
|
+
accumulateUsage(usage, repl.usage);
|
|
280
|
+
plan = repl.plan;
|
|
281
|
+
plansEmitted += 1;
|
|
282
|
+
cur = 0;
|
|
283
|
+
await this.firePlan(plan, /*isReplan*/ true, replans);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
catch (e) {
|
|
287
|
+
// planner blew up — fall through to ReAct fallback
|
|
288
|
+
await this.fireError(`replan failed: ${errMsg(e)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Replans exhausted (or planner threw). Optional ReAct fallback.
|
|
292
|
+
if (reactFallback && !reactFallbackUsed) {
|
|
293
|
+
const fbRemaining = deadline - Date.now();
|
|
294
|
+
if (fbRemaining <= 0) {
|
|
295
|
+
return this.finish({
|
|
296
|
+
ok: false,
|
|
297
|
+
finalText: `plan executor exceeded ${timeoutMs}ms budget`,
|
|
298
|
+
stepsConsumed,
|
|
299
|
+
usage,
|
|
300
|
+
history,
|
|
301
|
+
notes,
|
|
302
|
+
plansEmitted,
|
|
303
|
+
replans,
|
|
304
|
+
reactFallbackUsed,
|
|
305
|
+
terminator: "timeout",
|
|
306
|
+
cancelled: false,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
reactFallbackUsed = true;
|
|
310
|
+
const fallback = await new AgentLoop({
|
|
311
|
+
task: this.opts.goal,
|
|
312
|
+
env: this.opts.env,
|
|
313
|
+
mcp: this.opts.mcp,
|
|
314
|
+
adapter: this.opts.adapter,
|
|
315
|
+
maxSteps: Math.max(1, maxSteps - stepsConsumed),
|
|
316
|
+
timeoutMs: fbRemaining,
|
|
317
|
+
signal: this.opts.signal,
|
|
318
|
+
hooks: this.opts.hooks,
|
|
319
|
+
reflector: this.opts.reflector,
|
|
320
|
+
}).run();
|
|
321
|
+
stepsConsumed += fallback.steps;
|
|
322
|
+
accumulateUsage(usage, fallback.usage);
|
|
323
|
+
history.push(...fallback.history);
|
|
324
|
+
notes.push(...fallback.notes);
|
|
325
|
+
lastTerminator = fallback.terminator;
|
|
326
|
+
lastFinalText = fallback.finalText;
|
|
327
|
+
return this.finish({
|
|
328
|
+
ok: SUCCESS_TERMINATORS.has(fallback.terminator),
|
|
329
|
+
finalText: fallback.finalText,
|
|
330
|
+
stepsConsumed,
|
|
331
|
+
usage,
|
|
332
|
+
history,
|
|
333
|
+
notes,
|
|
334
|
+
plansEmitted,
|
|
335
|
+
replans,
|
|
336
|
+
reactFallbackUsed,
|
|
337
|
+
terminator: fallback.terminator,
|
|
338
|
+
cancelled: fallback.terminator === "cancelled",
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
// No fallback (or already used) — bail out with the failure.
|
|
342
|
+
return this.finish({
|
|
343
|
+
ok: false,
|
|
344
|
+
finalText: result.finalText,
|
|
345
|
+
stepsConsumed,
|
|
346
|
+
usage,
|
|
347
|
+
history,
|
|
348
|
+
notes,
|
|
349
|
+
plansEmitted,
|
|
350
|
+
replans,
|
|
351
|
+
reactFallbackUsed,
|
|
352
|
+
terminator: result.terminator,
|
|
353
|
+
cancelled: false,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return this.finish({
|
|
357
|
+
ok: lastTerminator === "done" || (cur > 0 && plan.steps.length > 0),
|
|
358
|
+
finalText: lastFinalText || "task complete",
|
|
359
|
+
stepsConsumed,
|
|
360
|
+
usage,
|
|
361
|
+
history,
|
|
362
|
+
notes,
|
|
363
|
+
plansEmitted,
|
|
364
|
+
replans,
|
|
365
|
+
reactFallbackUsed,
|
|
366
|
+
terminator: lastTerminator || "done",
|
|
367
|
+
cancelled: false,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
async firePlan(plan, isReplan, replanCount) {
|
|
371
|
+
if (!this.opts.hooks?.onReasoning)
|
|
372
|
+
return;
|
|
373
|
+
try {
|
|
374
|
+
await this.opts.hooks.onReasoning(`[planner] ${isReplan ? `replan #${replanCount}` : "plan"}: ${describePlan(plan)}`);
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// never let hooks bubble up
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async fireError(message) {
|
|
381
|
+
if (!this.opts.hooks?.onError)
|
|
382
|
+
return;
|
|
383
|
+
try {
|
|
384
|
+
await this.opts.hooks.onError({ code: "MODEL_PREDICT_FAILED", message, fatal: false });
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
// ditto
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
finish(args) {
|
|
391
|
+
return {
|
|
392
|
+
ok: args.ok,
|
|
393
|
+
finalText: args.finalText,
|
|
394
|
+
steps: args.stepsConsumed,
|
|
395
|
+
usage: args.usage,
|
|
396
|
+
history: args.history,
|
|
397
|
+
notes: args.notes,
|
|
398
|
+
plansEmitted: args.plansEmitted,
|
|
399
|
+
replans: args.replans,
|
|
400
|
+
reactFallbackUsed: args.reactFallbackUsed,
|
|
401
|
+
terminator: args.terminator,
|
|
402
|
+
cancelled: args.cancelled,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Build a fresh `Observation` snapshot to feed the (text-only) planner on
|
|
407
|
+
* the replan path. Always pulls the screenshot (cheap; needed for
|
|
408
|
+
* `screenW/screenH`) and unconditionally tries `mcp.uiDump()` — for the
|
|
409
|
+
* planner the UI hierarchy is genuinely useful (it can't see pixels), and
|
|
410
|
+
* this is independent of whether the inner adapter consumes ui_dump.
|
|
411
|
+
* Returns `undefined` only when even the screenshot fails, so the replan
|
|
412
|
+
* still has a chance to fire with the previous plan + history alone.
|
|
413
|
+
*/
|
|
414
|
+
async snapshotForPlanner() {
|
|
415
|
+
let ss;
|
|
416
|
+
try {
|
|
417
|
+
ss = await this.opts.mcp.screenshot();
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
return undefined;
|
|
421
|
+
}
|
|
422
|
+
let uiDump;
|
|
423
|
+
try {
|
|
424
|
+
const dump = await this.opts.mcp.uiDump();
|
|
425
|
+
if (dump.supported && dump.content)
|
|
426
|
+
uiDump = dump.content;
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// best-effort — desktop / iOS backends can't always produce one
|
|
430
|
+
}
|
|
431
|
+
return {
|
|
432
|
+
task: this.opts.goal,
|
|
433
|
+
env: this.opts.env,
|
|
434
|
+
screenW: ss.deviceWidth ?? ss.width ?? 0,
|
|
435
|
+
screenH: ss.deviceHeight ?? ss.height ?? 0,
|
|
436
|
+
screenshotB64: ss.b64,
|
|
437
|
+
uiDump,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/* ──────────────────────────────────────────────────────────────────────── */
|
|
442
|
+
/* helpers */
|
|
443
|
+
/* ──────────────────────────────────────────────────────────────────────── */
|
|
444
|
+
function defaultPerStepBudget(planSteps, maxSteps) {
|
|
445
|
+
if (planSteps <= 0)
|
|
446
|
+
return Math.max(1, maxSteps);
|
|
447
|
+
return Math.max(1, Math.ceil(maxSteps / Math.max(1, planSteps)));
|
|
448
|
+
}
|
|
449
|
+
function clamp(n, lo, hi) {
|
|
450
|
+
return Math.max(lo, Math.min(hi, n));
|
|
451
|
+
}
|
|
452
|
+
function accumulateUsage(into, src) {
|
|
453
|
+
into.inputTokens += src.inputTokens;
|
|
454
|
+
into.outputTokens += src.outputTokens;
|
|
455
|
+
if (src.cachedInputTokens)
|
|
456
|
+
into.cachedInputTokens = (into.cachedInputTokens ?? 0) + src.cachedInputTokens;
|
|
457
|
+
if (src.costUsd)
|
|
458
|
+
into.costUsd = (into.costUsd ?? 0) + src.costUsd;
|
|
459
|
+
}
|
|
460
|
+
function describePlan(plan) {
|
|
461
|
+
if (plan.steps.length === 0)
|
|
462
|
+
return "(empty plan)";
|
|
463
|
+
const lines = plan.steps
|
|
464
|
+
.slice(0, 8)
|
|
465
|
+
.map((s) => ` ${s.idx}. ${s.description}${s.targetDesc ? ` → ${s.targetDesc}` : ""}`)
|
|
466
|
+
.join("\n");
|
|
467
|
+
return `\n${lines}`;
|
|
468
|
+
}
|
|
469
|
+
function errMsg(e) {
|
|
470
|
+
if (e instanceof Error)
|
|
471
|
+
return e.message;
|
|
472
|
+
return String(e);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Format a `PlanStep` as the inner `AgentLoop`'s `task` string. We splice
|
|
476
|
+
* in a few light directives so the inner adapter knows what high-level
|
|
477
|
+
* goal it serves and what the upcoming sub-tasks look like, but the
|
|
478
|
+
* primary instruction is still the current step's description.
|
|
479
|
+
*/
|
|
480
|
+
function formatStepAsTask(rootGoal, plan, idx) {
|
|
481
|
+
const step = plan.steps[idx];
|
|
482
|
+
const upcoming = plan.steps
|
|
483
|
+
.slice(idx + 1, idx + 4)
|
|
484
|
+
.map((s) => `${s.idx}. ${s.description}`)
|
|
485
|
+
.join("; ");
|
|
486
|
+
const targetHint = step.targetDesc ? `\n# Target: ${step.targetDesc}` : "";
|
|
487
|
+
const expectedOutcome = step.expectedOutcome ? `\n# Expected: ${step.expectedOutcome}` : "";
|
|
488
|
+
const upcomingLine = upcoming ? `\n# Upcoming: ${upcoming}` : "";
|
|
489
|
+
return [
|
|
490
|
+
`# Goal: ${rootGoal}`,
|
|
491
|
+
`# Sub-task ${idx + 1}/${plan.steps.length}: ${step.description}`,
|
|
492
|
+
targetHint,
|
|
493
|
+
expectedOutcome,
|
|
494
|
+
upcomingLine,
|
|
495
|
+
"",
|
|
496
|
+
"Focus only on this sub-task. Call finish() when this sub-task is complete.",
|
|
497
|
+
]
|
|
498
|
+
.filter((line) => line !== "")
|
|
499
|
+
.join("\n");
|
|
500
|
+
}
|
|
501
|
+
//# sourceMappingURL=plan-executor.js.map
|