@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,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/planner/prompts — system + user prompt builders for the
|
|
3
|
+
* LLM-driven `LLMPlanner`. Mirrors the Python reference at
|
|
4
|
+
* /Users/heat/workspace/deviceagent_research/deviceagent/agent_runtime/planner/prompts.py
|
|
5
|
+
*
|
|
6
|
+
* The planner is *strategy-only*: it never picks pixel coordinates, never
|
|
7
|
+
* emits a single Action — it emits a Plan (ordered list of small,
|
|
8
|
+
* verifiable sub-tasks) that the inner `AgentLoop` then executes one by
|
|
9
|
+
* one with a vision-grounding adapter (AutoGLM-Phone-9B today).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The ALLOW-LIST surfaced into the system prompt, kept in lock-step with
|
|
13
|
+
* `device-common` `ActionType`. We intentionally drop the terminal verbs
|
|
14
|
+
* (`done`, `fail`, `call_for_user`) — those are reserved for the inner
|
|
15
|
+
* adapter's last step, not for plan items.
|
|
16
|
+
*/
|
|
17
|
+
const ACTION_KIND_ENUM = [
|
|
18
|
+
"click",
|
|
19
|
+
"double_click",
|
|
20
|
+
"right_click",
|
|
21
|
+
"tap",
|
|
22
|
+
"long_press",
|
|
23
|
+
"drag",
|
|
24
|
+
"swipe",
|
|
25
|
+
"scroll",
|
|
26
|
+
"type",
|
|
27
|
+
"key",
|
|
28
|
+
"hotkey",
|
|
29
|
+
"back",
|
|
30
|
+
"home",
|
|
31
|
+
"navigate",
|
|
32
|
+
"launch_app",
|
|
33
|
+
"wait",
|
|
34
|
+
"screenshot",
|
|
35
|
+
"ui_dump",
|
|
36
|
+
"execute_command",
|
|
37
|
+
"run_code",
|
|
38
|
+
].join("|");
|
|
39
|
+
const SYSTEM_PROMPT_TEMPLATE = `\
|
|
40
|
+
You are DeviceAgent's PLANNER — a strategist that decomposes a user goal into
|
|
41
|
+
an ordered list of small, verifiable steps that another agent (the GROUNDER /
|
|
42
|
+
mobile VLM) will execute on a {ENV}.
|
|
43
|
+
|
|
44
|
+
You DO NOT pick pixel coordinates. The GROUNDER does that. You DO describe each
|
|
45
|
+
step using natural language ("the blue 'Submit' button", "the search input at
|
|
46
|
+
the top") so that the grounder can localise it from a screenshot or
|
|
47
|
+
accessibility tree.
|
|
48
|
+
|
|
49
|
+
Reply in **strict JSON only**, matching this schema:
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
"rationale": "<one paragraph, 60 words max>",
|
|
53
|
+
"plan": {
|
|
54
|
+
"goal": "<echo of the user goal>",
|
|
55
|
+
"steps": [
|
|
56
|
+
{
|
|
57
|
+
"idx": 0,
|
|
58
|
+
"description": "<one short sentence, present tense>",
|
|
59
|
+
"action_kind": "{ACTION_KIND_ENUM}",
|
|
60
|
+
"target_desc": "<English description of which element, or null for non-targeted actions>",
|
|
61
|
+
"payload": { },
|
|
62
|
+
"expected_outcome": "<short post-condition you can visually verify>"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Rules:
|
|
69
|
+
- Plans should be 2–8 steps. Prefer SHORT plans; the executor will replan
|
|
70
|
+
if a step fails, so you do not need to plan every micro-tap.
|
|
71
|
+
- One coarse user-visible action per step ("open WeChat", "tap Moments",
|
|
72
|
+
"type the message"). Do NOT split a single tap into pre/post screenshots.
|
|
73
|
+
- Coordinates are NEVER part of your plan; let the grounder pick them.
|
|
74
|
+
- Screen size is {SCREEN_W}x{SCREEN_H}. Use English / 中文 descriptors that
|
|
75
|
+
pinpoint elements ("top-right camera icon", "bottom 'Send' button") if it
|
|
76
|
+
helps disambiguation.
|
|
77
|
+
- When the user can authenticate / solve a captcha faster than the agent,
|
|
78
|
+
insert an explicit step with action_kind="wait" and an expected_outcome
|
|
79
|
+
that keys off the post-login state.
|
|
80
|
+
- The current local date is {DATE}. Inject it when a task references "today"
|
|
81
|
+
/ "now".
|
|
82
|
+
- If a "Notes" section is present, treat it as authoritative ground truth
|
|
83
|
+
captured by the agent during execution (verification codes, prices, user
|
|
84
|
+
inputs, etc.). DO NOT plan steps to re-collect already-recorded info.
|
|
85
|
+
- If a "Trajectory verdict" is present, the inner loop bailed mid-execution
|
|
86
|
+
because progress stalled ("off_track" / "stuck"). Address the cited
|
|
87
|
+
"reason" head-on: pivot the plan, drop the failing branch, or insert an
|
|
88
|
+
explicit recovery step (e.g. "go back", "wait for captcha", etc.).
|
|
89
|
+
|
|
90
|
+
Reply ONLY with valid JSON matching the schema. No markdown. No prose.
|
|
91
|
+
`;
|
|
92
|
+
const REPLAN_SUFFIX_TEMPLATE = `
|
|
93
|
+
|
|
94
|
+
REPLAN CONTEXT
|
|
95
|
+
The previous plan failed at step {LAST_STEP_IDX}. Failure reason:
|
|
96
|
+
{FAILURE_REASON}
|
|
97
|
+
|
|
98
|
+
Inspect the latest observation, then emit a NEW plan that takes the current
|
|
99
|
+
state into account. You may keep, drop, or reorder steps.`;
|
|
100
|
+
export function renderSystemPrompt(opts) {
|
|
101
|
+
const date = opts.date ?? new Date().toISOString().slice(0, 10);
|
|
102
|
+
return SYSTEM_PROMPT_TEMPLATE
|
|
103
|
+
.replace("{ENV}", opts.env || "device")
|
|
104
|
+
.replace("{ACTION_KIND_ENUM}", ACTION_KIND_ENUM)
|
|
105
|
+
.replace("{SCREEN_W}", String(opts.screenW || 0))
|
|
106
|
+
.replace("{SCREEN_H}", String(opts.screenH || 0))
|
|
107
|
+
.replace("{DATE}", date);
|
|
108
|
+
}
|
|
109
|
+
export function renderUserPrompt(opts) {
|
|
110
|
+
const lines = [];
|
|
111
|
+
lines.push(`Task: ${opts.goal}`);
|
|
112
|
+
if (opts.observation) {
|
|
113
|
+
lines.push(`Screen: ${opts.observation.screenW}x${opts.observation.screenH}`);
|
|
114
|
+
if (opts.observation.uiDump) {
|
|
115
|
+
lines.push(`UI dump (truncated): ${opts.observation.uiDump.slice(0, 4000)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (opts.notes && opts.notes.length > 0) {
|
|
119
|
+
lines.push("");
|
|
120
|
+
lines.push("Notes (authoritative — captured by the agent mid-task):");
|
|
121
|
+
for (const note of opts.notes) {
|
|
122
|
+
lines.push(` - ${note}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (opts.trajectoryVerdict) {
|
|
126
|
+
lines.push("");
|
|
127
|
+
lines.push(`Trajectory verdict: ${opts.trajectoryVerdict.verdict} — ${opts.trajectoryVerdict.reason}`);
|
|
128
|
+
}
|
|
129
|
+
lines.push("");
|
|
130
|
+
lines.push("Recent actions:");
|
|
131
|
+
lines.push(renderHistoryBlock(opts.history));
|
|
132
|
+
if (opts.failureReason !== undefined) {
|
|
133
|
+
lines.push(REPLAN_SUFFIX_TEMPLATE
|
|
134
|
+
.replace("{LAST_STEP_IDX}", opts.lastStepIdx !== undefined ? String(opts.lastStepIdx) : "-1")
|
|
135
|
+
.replace("{FAILURE_REASON}", opts.failureReason)
|
|
136
|
+
.trimEnd());
|
|
137
|
+
}
|
|
138
|
+
return lines.join("\n");
|
|
139
|
+
}
|
|
140
|
+
function renderHistoryBlock(history) {
|
|
141
|
+
if (history.length === 0)
|
|
142
|
+
return "(no prior steps)";
|
|
143
|
+
const lines = [];
|
|
144
|
+
for (const h of history.slice(-8)) {
|
|
145
|
+
const verb = h.action?.type ?? "noop";
|
|
146
|
+
const target = formatTarget(h.action?.target);
|
|
147
|
+
const summary = h.observationSummary ? ` :: ${h.observationSummary}` : "";
|
|
148
|
+
const rationale = h.rationale ? ` (${h.rationale.slice(0, 80)})` : "";
|
|
149
|
+
lines.push(` - step ${h.stepIdx}: ${verb}${target}${rationale}${summary}`);
|
|
150
|
+
}
|
|
151
|
+
return lines.join("\n");
|
|
152
|
+
}
|
|
153
|
+
function formatTarget(t) {
|
|
154
|
+
if (!t)
|
|
155
|
+
return "";
|
|
156
|
+
if (t.kind === "point")
|
|
157
|
+
return ` @(${t.x},${t.y})`;
|
|
158
|
+
if (t.kind === "box")
|
|
159
|
+
return ` [box ${t.x1},${t.y1}->${t.x2},${t.y2}]`;
|
|
160
|
+
if (t.kind === "text")
|
|
161
|
+
return ` "${String(t.value).slice(0, 40)}"`;
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
export const STRICT_SCHEMA_HINT = "Reply ONLY with valid JSON matching the schema. No markdown, no prose.";
|
|
165
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/agent-runtime/planner/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/reflection — hierarchical reflection layer for AgentLoop.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the Python reference at
|
|
5
|
+
* /Users/heat/workspace/deviceagent_research/deviceagent/agent_runtime/loop/reflection.py
|
|
6
|
+
*
|
|
7
|
+
* Phase-1 reflector is heuristic-only (cheap):
|
|
8
|
+
* - **Action reflection** — 4 identical actions in a row → stall.
|
|
9
|
+
* - **Trajectory reflection** — ≥5 screenshots in the last 6 steps → stall
|
|
10
|
+
* (the model is staring at the screen instead of acting).
|
|
11
|
+
* - **Pre-action sanity** — block obviously-broken `nextAction` candidates
|
|
12
|
+
* *before* dispatch (zero-cost; mirrors mobile-use `enable_pre_reflection`).
|
|
13
|
+
* - **Model-based action reflection** is plumbed via `IActionReflector` —
|
|
14
|
+
* composed by AgentLoop after `act()` returns, gated by confidence /
|
|
15
|
+
* `actionResult` so the heuristic layer fires first.
|
|
16
|
+
*/
|
|
17
|
+
import type { Action } from "@beeos-ai/device-common";
|
|
18
|
+
import type { IActionReflector } from "./reflectors/action-reflector.js";
|
|
19
|
+
import type { ITrajectoryReflector } from "./reflectors/trajectory-reflector.js";
|
|
20
|
+
import type { IModelAdapter, StepHistory } from "./adapters/base.js";
|
|
21
|
+
/**
|
|
22
|
+
* Veto reason returned by {@link HierarchicalReflector.maybeBlockAction}.
|
|
23
|
+
* - `reason` — short human-readable string, copied into the next StepHistory
|
|
24
|
+
* rationale so the grounder sees *why* its previous attempt was blocked.
|
|
25
|
+
* - `code` — stable identifier for telemetry / metrics tagging.
|
|
26
|
+
*/
|
|
27
|
+
export interface PreActionVeto {
|
|
28
|
+
code: "double_type_without_focus" | "double_tap_same_coords" | "blind_swipe" | "vlm_emitted_shell";
|
|
29
|
+
reason: string;
|
|
30
|
+
}
|
|
31
|
+
export interface HierarchicalReflectorOptions {
|
|
32
|
+
/** Optional VLM adapter — reserved for future model-based reflection hooks. */
|
|
33
|
+
adapter?: IModelAdapter;
|
|
34
|
+
/**
|
|
35
|
+
* Optional model-based reflector composed after `act()` returns. AgentLoop
|
|
36
|
+
* calls `actionReflector?.shouldReflect(...)` first; the heuristic veto
|
|
37
|
+
* still runs before any model invocation.
|
|
38
|
+
*/
|
|
39
|
+
actionReflector?: IActionReflector;
|
|
40
|
+
/**
|
|
41
|
+
* Optional trajectory reflector (Phase 2.2). AgentLoop fires it every N
|
|
42
|
+
* steps to assess global progress; bail-out verdicts (`off_track` /
|
|
43
|
+
* `stuck`) are converted into a reflection veto so the PlanExecutor can
|
|
44
|
+
* trigger a replan.
|
|
45
|
+
*/
|
|
46
|
+
trajectoryReflector?: ITrajectoryReflector;
|
|
47
|
+
}
|
|
48
|
+
export declare class HierarchicalReflector {
|
|
49
|
+
private readonly adapter?;
|
|
50
|
+
readonly actionReflector?: IActionReflector;
|
|
51
|
+
readonly trajectoryReflector?: ITrajectoryReflector;
|
|
52
|
+
constructor(adapterOrOptions?: IModelAdapter | HierarchicalReflectorOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Returns a non-empty veto reason when the loop should stop, or `null` if
|
|
55
|
+
* the run is healthy and may continue.
|
|
56
|
+
*/
|
|
57
|
+
maybeVeto(history: StepHistory[], step: number, _maxSteps: number): string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Pre-action sanity — block obviously-broken `nextAction` candidates
|
|
60
|
+
* **before** AgentLoop dispatches them to MCP. Returns a veto when the
|
|
61
|
+
* action looks like a known-bad pattern; the AgentLoop should then skip
|
|
62
|
+
* the dispatch and record the step with `actionResult: "skipped"`.
|
|
63
|
+
*
|
|
64
|
+
* Rules (cover ~80% of common grounder mistakes — see plan Task 1.3):
|
|
65
|
+
* 1. Two consecutive `type` actions with no intervening `tap` /
|
|
66
|
+
* `long_press` → focus probably wasn't established (mobile-use
|
|
67
|
+
* `pre_reflection` rule).
|
|
68
|
+
* 2. Two consecutive `tap` actions on the same point (≤ 8px tolerance)
|
|
69
|
+
* → looks like a double-click misclassified as two taps.
|
|
70
|
+
* 3. Two consecutive `swipe` actions in the same direction without an
|
|
71
|
+
* intervening `screenshot` → blind scrolling without re-grounding.
|
|
72
|
+
* 4. The grounder emitted `execute_command` (the VLM should never produce
|
|
73
|
+
* shell). This is exactly the "Baidu image" failure mode that
|
|
74
|
+
* motivated this rule set.
|
|
75
|
+
*
|
|
76
|
+
* Heuristics are conservative — when in doubt, return `null` (let the
|
|
77
|
+
* action through). Repeated stalls are still caught by `maybeVeto`.
|
|
78
|
+
*/
|
|
79
|
+
maybeBlockAction(history: StepHistory[], nextAction: Action): PreActionVeto | null;
|
|
80
|
+
}
|
|
81
|
+
export declare function actionsEqual(a: Action, b: Action): boolean;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/reflection — hierarchical reflection layer for AgentLoop.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the Python reference at
|
|
5
|
+
* /Users/heat/workspace/deviceagent_research/deviceagent/agent_runtime/loop/reflection.py
|
|
6
|
+
*
|
|
7
|
+
* Phase-1 reflector is heuristic-only (cheap):
|
|
8
|
+
* - **Action reflection** — 4 identical actions in a row → stall.
|
|
9
|
+
* - **Trajectory reflection** — ≥5 screenshots in the last 6 steps → stall
|
|
10
|
+
* (the model is staring at the screen instead of acting).
|
|
11
|
+
* - **Pre-action sanity** — block obviously-broken `nextAction` candidates
|
|
12
|
+
* *before* dispatch (zero-cost; mirrors mobile-use `enable_pre_reflection`).
|
|
13
|
+
* - **Model-based action reflection** is plumbed via `IActionReflector` —
|
|
14
|
+
* composed by AgentLoop after `act()` returns, gated by confidence /
|
|
15
|
+
* `actionResult` so the heuristic layer fires first.
|
|
16
|
+
*/
|
|
17
|
+
export class HierarchicalReflector {
|
|
18
|
+
adapter;
|
|
19
|
+
actionReflector;
|
|
20
|
+
trajectoryReflector;
|
|
21
|
+
constructor(adapterOrOptions) {
|
|
22
|
+
if (adapterOrOptions && "name" in adapterOrOptions) {
|
|
23
|
+
this.adapter = adapterOrOptions;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const opts = adapterOrOptions ?? {};
|
|
27
|
+
this.adapter = opts.adapter;
|
|
28
|
+
this.actionReflector = opts.actionReflector;
|
|
29
|
+
this.trajectoryReflector = opts.trajectoryReflector;
|
|
30
|
+
}
|
|
31
|
+
void this.adapter; // reserved for future model-based reflection
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns a non-empty veto reason when the loop should stop, or `null` if
|
|
35
|
+
* the run is healthy and may continue.
|
|
36
|
+
*/
|
|
37
|
+
maybeVeto(history, step, _maxSteps) {
|
|
38
|
+
if (step <= 2 || history.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const last = history[history.length - 1].action;
|
|
41
|
+
if (!last)
|
|
42
|
+
return null;
|
|
43
|
+
// Action reflection — 4 identical actions in a row.
|
|
44
|
+
const recent = history
|
|
45
|
+
.slice(-4)
|
|
46
|
+
.map((h) => h.action)
|
|
47
|
+
.filter((a) => a !== null);
|
|
48
|
+
if (recent.length === 4 && recent.every((a) => actionsEqual(a, recent[0]))) {
|
|
49
|
+
return `stalled: action ${recent[0].type} repeated 4 consecutive times`;
|
|
50
|
+
}
|
|
51
|
+
// Trajectory reflection — screenshot-heavy stall.
|
|
52
|
+
const recentTypes = history
|
|
53
|
+
.slice(-6)
|
|
54
|
+
.map((h) => h.action?.type)
|
|
55
|
+
.filter((t) => Boolean(t));
|
|
56
|
+
if (recentTypes.filter((t) => t === "screenshot").length >= 5) {
|
|
57
|
+
return "stalled: screenshot-heavy trajectory with no actuation";
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Pre-action sanity — block obviously-broken `nextAction` candidates
|
|
63
|
+
* **before** AgentLoop dispatches them to MCP. Returns a veto when the
|
|
64
|
+
* action looks like a known-bad pattern; the AgentLoop should then skip
|
|
65
|
+
* the dispatch and record the step with `actionResult: "skipped"`.
|
|
66
|
+
*
|
|
67
|
+
* Rules (cover ~80% of common grounder mistakes — see plan Task 1.3):
|
|
68
|
+
* 1. Two consecutive `type` actions with no intervening `tap` /
|
|
69
|
+
* `long_press` → focus probably wasn't established (mobile-use
|
|
70
|
+
* `pre_reflection` rule).
|
|
71
|
+
* 2. Two consecutive `tap` actions on the same point (≤ 8px tolerance)
|
|
72
|
+
* → looks like a double-click misclassified as two taps.
|
|
73
|
+
* 3. Two consecutive `swipe` actions in the same direction without an
|
|
74
|
+
* intervening `screenshot` → blind scrolling without re-grounding.
|
|
75
|
+
* 4. The grounder emitted `execute_command` (the VLM should never produce
|
|
76
|
+
* shell). This is exactly the "Baidu image" failure mode that
|
|
77
|
+
* motivated this rule set.
|
|
78
|
+
*
|
|
79
|
+
* Heuristics are conservative — when in doubt, return `null` (let the
|
|
80
|
+
* action through). Repeated stalls are still caught by `maybeVeto`.
|
|
81
|
+
*/
|
|
82
|
+
maybeBlockAction(history, nextAction) {
|
|
83
|
+
if (!nextAction)
|
|
84
|
+
return null;
|
|
85
|
+
// Rule 4 — VLM emitted shell. Always block.
|
|
86
|
+
if (nextAction.type === "execute_command") {
|
|
87
|
+
return {
|
|
88
|
+
code: "vlm_emitted_shell",
|
|
89
|
+
reason: "grounder emitted execute_command — VLMs should never produce shell; planner should route shell via tools",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (history.length === 0)
|
|
93
|
+
return null;
|
|
94
|
+
const prev = lastNonNullAction(history);
|
|
95
|
+
if (!prev)
|
|
96
|
+
return null;
|
|
97
|
+
// Rule 1 — double-type without re-focus.
|
|
98
|
+
if (nextAction.type === "type" && prev.action.type === "type") {
|
|
99
|
+
return {
|
|
100
|
+
code: "double_type_without_focus",
|
|
101
|
+
reason: "two consecutive `type` actions without a tap/long_press between — focus probably wasn't established",
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Rule 2 — double-tap as two taps on (almost) the same point.
|
|
105
|
+
if (nextAction.type === "tap" &&
|
|
106
|
+
prev.action.type === "tap" &&
|
|
107
|
+
isPointTarget(nextAction.target) &&
|
|
108
|
+
isPointTarget(prev.action.target)) {
|
|
109
|
+
const dx = Math.abs(nextAction.target.x - prev.action.target.x);
|
|
110
|
+
const dy = Math.abs(nextAction.target.y - prev.action.target.y);
|
|
111
|
+
if (dx <= 8 && dy <= 8) {
|
|
112
|
+
return {
|
|
113
|
+
code: "double_tap_same_coords",
|
|
114
|
+
reason: `two consecutive tap on (${prev.action.target.x},${prev.action.target.y}) → looks like a misclassified double_tap`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Rule 3 — blind swipe (same direction, no screenshot in between).
|
|
119
|
+
if (nextAction.type === "swipe" &&
|
|
120
|
+
prev.action.type === "swipe" &&
|
|
121
|
+
isBoxTarget(nextAction.target) &&
|
|
122
|
+
isBoxTarget(prev.action.target)) {
|
|
123
|
+
const sameDir = sign(nextAction.target.x2 - nextAction.target.x1) ===
|
|
124
|
+
sign(prev.action.target.x2 - prev.action.target.x1) &&
|
|
125
|
+
sign(nextAction.target.y2 - nextAction.target.y1) ===
|
|
126
|
+
sign(prev.action.target.y2 - prev.action.target.y1);
|
|
127
|
+
const sawScreenshotBetween = anyActionBetween(history, prev.idx, history.length, (a) => a.type === "screenshot");
|
|
128
|
+
if (sameDir && !sawScreenshotBetween) {
|
|
129
|
+
return {
|
|
130
|
+
code: "blind_swipe",
|
|
131
|
+
reason: "swipe in the same direction as the previous step with no intervening screenshot — re-ground before scrolling further",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/* -------------------------------------------------------------------------- */
|
|
139
|
+
/* helpers */
|
|
140
|
+
/* -------------------------------------------------------------------------- */
|
|
141
|
+
export function actionsEqual(a, b) {
|
|
142
|
+
if (a.type !== b.type)
|
|
143
|
+
return false;
|
|
144
|
+
if (!targetsEqual(a.target, b.target))
|
|
145
|
+
return false;
|
|
146
|
+
return jsonEquals(a.payload, b.payload);
|
|
147
|
+
}
|
|
148
|
+
function targetsEqual(a, b) {
|
|
149
|
+
if (!a && !b)
|
|
150
|
+
return true;
|
|
151
|
+
if (!a || !b)
|
|
152
|
+
return false;
|
|
153
|
+
if (a.kind !== b.kind)
|
|
154
|
+
return false;
|
|
155
|
+
return jsonEquals(a, b);
|
|
156
|
+
}
|
|
157
|
+
function jsonEquals(a, b) {
|
|
158
|
+
if (Object.is(a, b))
|
|
159
|
+
return true;
|
|
160
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
|
|
161
|
+
return false;
|
|
162
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
163
|
+
}
|
|
164
|
+
function isPointTarget(t) {
|
|
165
|
+
return !!t && t.kind === "point";
|
|
166
|
+
}
|
|
167
|
+
function isBoxTarget(t) {
|
|
168
|
+
return !!t && t.kind === "box";
|
|
169
|
+
}
|
|
170
|
+
function sign(n) {
|
|
171
|
+
return n > 0 ? 1 : n < 0 ? -1 : 0;
|
|
172
|
+
}
|
|
173
|
+
function lastNonNullAction(history) {
|
|
174
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
175
|
+
const a = history[i].action;
|
|
176
|
+
if (a)
|
|
177
|
+
return { idx: i, action: a };
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
function anyActionBetween(history, startExclusive, endExclusive, pred) {
|
|
182
|
+
for (let i = startExclusive + 1; i < endExclusive; i++) {
|
|
183
|
+
const a = history[i].action;
|
|
184
|
+
if (a && pred(a))
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=reflection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.js","sourceRoot":"","sources":["../../src/agent-runtime/reflection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-runtime/reflectors/action-reflector — model-based action reflection.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1.4 of the device-agent reflector upgrade plan
|
|
5
|
+
* ([../../../../../../.cursor/plans/device-agent-reflector-skills_d5599350.plan.md]).
|
|
6
|
+
*
|
|
7
|
+
* Goal: catch *the same step* the grounder just emitted when it's likely
|
|
8
|
+
* wrong (low confidence, or the MCP `act` failed) and feed back a textual
|
|
9
|
+
* verdict the next predict call can read. Concretely:
|
|
10
|
+
* - heuristic veto (`HierarchicalReflector.maybeVeto`) runs first and
|
|
11
|
+
* terminates the loop with a hard stop on stalls;
|
|
12
|
+
* - if the heuristics are quiet, we ask the action reflector whether to
|
|
13
|
+
* take a closer look. The default {@link LLMActionReflector} fires on
|
|
14
|
+
* `actionResult === "act_failed"` OR on low-confidence predictions
|
|
15
|
+
* OR (as a defensive fallback) on a small whitelist of high-risk verbs
|
|
16
|
+
* so we still help even when the adapter doesn't expose logprobs.
|
|
17
|
+
* - the reflector verdict is **advisory**: a `passed: false` result is
|
|
18
|
+
* spliced into the next StepHistory rationale ("act_failed: …") so the
|
|
19
|
+
* grounder retries with that context. We do NOT terminate the loop —
|
|
20
|
+
* stalls are still the heuristic layer's job.
|
|
21
|
+
*
|
|
22
|
+
* The cost model is documented in
|
|
23
|
+
* `agents/device-agent/docs/reflectors.md` (Phase 2.4). Per-task budget
|
|
24
|
+
* with default config is ≤ 4 cheap text glm-4-flash calls / task, ~600-1200
|
|
25
|
+
* input tokens / 50 output tokens each.
|
|
26
|
+
*/
|
|
27
|
+
import OpenAI from "openai";
|
|
28
|
+
import type { Action } from "@beeos-ai/device-common";
|
|
29
|
+
import type { ModelUsage, Prediction, StepHistory } from "../adapters/base.js";
|
|
30
|
+
/** Verbs that warrant a reflection on Branch C of the logprobs spike. */
|
|
31
|
+
export declare const HIGH_RISK_VERBS: ReadonlySet<Action["type"]>;
|
|
32
|
+
export type ActionReflectorGating = "logprob" | "logprob-degraded" | "whitelist";
|
|
33
|
+
export interface ActionReflectCtx {
|
|
34
|
+
/** Goal of the surrounding task. */
|
|
35
|
+
goal: string;
|
|
36
|
+
/** Up to N previous step entries (most recent last). */
|
|
37
|
+
history: StepHistory[];
|
|
38
|
+
/** The prediction we want to reflect on. */
|
|
39
|
+
prediction: Prediction;
|
|
40
|
+
/** Last observation summary (no base64 — text only). */
|
|
41
|
+
observationSummary: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ActionReflectVerdict {
|
|
44
|
+
/**
|
|
45
|
+
* `true` — reflector agrees with the action; nothing to do.
|
|
46
|
+
* `false` — reflector flagged the action; the AgentLoop should record
|
|
47
|
+
* `act_failed: <reason>` and let the grounder retry.
|
|
48
|
+
*/
|
|
49
|
+
passed: boolean;
|
|
50
|
+
reason: string;
|
|
51
|
+
usage: ModelUsage;
|
|
52
|
+
}
|
|
53
|
+
export interface IActionReflector {
|
|
54
|
+
/**
|
|
55
|
+
* Should the loop invoke {@link reflect} on this prediction? Cheap to
|
|
56
|
+
* call — only returns true on the small subset that warrants the LLM
|
|
57
|
+
* round-trip.
|
|
58
|
+
*/
|
|
59
|
+
shouldReflect(history: StepHistory[], lastPrediction: Prediction, actionResult: StepHistory["actionResult"]): boolean;
|
|
60
|
+
/** Run the actual reflection. */
|
|
61
|
+
reflect(ctx: ActionReflectCtx, signal?: AbortSignal): Promise<ActionReflectVerdict>;
|
|
62
|
+
/** Optional cleanup. */
|
|
63
|
+
close?(): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export interface LLMActionReflectorOptions {
|
|
66
|
+
/** Override `process.env.PLANNER_BASE_URL` (planner endpoint reused). */
|
|
67
|
+
baseUrl?: string;
|
|
68
|
+
apiKey?: string;
|
|
69
|
+
/** Defaults to `glm-4-flash`. */
|
|
70
|
+
modelName?: string;
|
|
71
|
+
/** Confidence threshold; predictions below this fire the reflector. Defaults 0.6. */
|
|
72
|
+
confidenceThreshold?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Spike branch (see {@link ActionReflectorGating}). Defaults to "whitelist"
|
|
75
|
+
* which is the safe fallback when the AutoGLM-Phone-9B endpoint doesn't
|
|
76
|
+
* expose logprobs.
|
|
77
|
+
*/
|
|
78
|
+
gating?: ActionReflectorGating;
|
|
79
|
+
/** Sampling temperature. Defaults to 0. */
|
|
80
|
+
temperature?: number;
|
|
81
|
+
/** Max output tokens. Defaults to 80. */
|
|
82
|
+
maxTokens?: number;
|
|
83
|
+
/** Reused OpenAI client for tests. */
|
|
84
|
+
client?: OpenAI;
|
|
85
|
+
}
|
|
86
|
+
export declare class LLMActionReflector implements IActionReflector {
|
|
87
|
+
readonly name = "llm-action-reflector";
|
|
88
|
+
private readonly client;
|
|
89
|
+
private readonly modelName;
|
|
90
|
+
private readonly confidenceThreshold;
|
|
91
|
+
private readonly gating;
|
|
92
|
+
private readonly maxTokens;
|
|
93
|
+
private readonly temperature;
|
|
94
|
+
constructor(opts?: LLMActionReflectorOptions);
|
|
95
|
+
shouldReflect(_history: StepHistory[], lastPrediction: Prediction, actionResult: StepHistory["actionResult"]): boolean;
|
|
96
|
+
reflect(ctx: ActionReflectCtx, signal?: AbortSignal): Promise<ActionReflectVerdict>;
|
|
97
|
+
}
|