5.9 KiB
5.9 KiB
1. Split core/ into driver/ and device/
- 1.1
git mv core/driver.py driver/base.py, adddriver/__init__.py, update its internal imports if any - 1.2
git mv core/wda_driver.py driver/wda_driver.py, update its import ofcore.driver→driver.base - 1.3
git mv core/device_manager.py device/manager.py, adddevice/__init__.py, update its imports ofcore.driver/core.errors/core.models→driver.base/core.errors/core.models - 1.4 Confirm
core/__init__.py,core/models.py,core/errors.pyremain in place unchanged (shared domain types only)
2. Rename vision/ to perception/
- 2.1
git mv vision perception(carriesocr.py,ui_parser.py,scene_builder.py,icon_detector.py,__init__.py) - 2.2 Update internal imports within the renamed package if any reference
vision.*
3. Introduce the PerceptionProvider port
- 3.1 Create
perception/provider.pywith aPerceptionProviderABC (build_scene(screenshot, tree) -> Scene) - 3.2 Add a default provider that wraps the existing
scene_builder.pyfusion logic unmodified (same inputs, sameSceneoutput — no behavior change) - 3.3 Add
NullPerceptionProviderreturning an emptyScene(correctwidth/height, zero elements), usable without any OCR dependency installed - 3.4 Point
tools/describe_screen.py(and any other caller ofscene_builderdirectly) at thePerceptionProviderport instead of importingscene_builderdirectly - 3.5 Confirm
tests/test_scene_builder.pystill passes unchanged against the default provider
4. Relocate the Driver Registry
- 4.1 Create
driver/registry.py; moveSUPPORTED_DRIVER_TYPES,DriverFactoryBuilder,build_wda_driver_factory, andbuild_driver_factoryout ofapi/console.pyinto it, importingWDADriver/WDADriverConfigfromdriver.wda_driverandDriverFactoryfromdevice.manager - 4.2 Update
api/console.pyto importbuild_driver_factory(andSUPPORTED_DRIVER_TYPESif referenced) fromdriver.registryinstead of defining them locally - 4.3 Update
tests/test_console_api.py(and any other test importing these names fromapi.console) to import fromdriver.registrywhere appropriate
5. Rename the shared error base
- 5.1 In
core/errors.py, renameApexAgentError→DeviceRuntimeError(subclassesDriverError,DeviceNotFoundError,DeviceOfflineError,DeviceBusyError,ElementNotFoundError,TaskFailedErrorkeep their names, just re-parented) - 5.2 Update every
ApexAgentErrorreference acrossapi/,tools/,runtime/,core/,driver/,device/,perception/, andtests/toDeviceRuntimeError
6. Fix up all import sites and re-point package config
- 6.1 Grep the full tree for
core.driver,core.device_manager,core.wda_driver, andvision.and update every remaining import (spanstools/,runtime/,storage/,api/,tests/) to the newdriver.*/device.*/perception.*paths - 6.2 Update
pyproject.toml:[tool.setuptools.packages.find].includeto listdriver*,device*,perception*alongside the existingapi*,core*,runtime*,storage*,tools* - 6.3 Run the full
pytestsuite and fix any remaining import errors until it is fully green with no test-logic changes
7. Rebrand project identity
- 7.1 Update
pyproject.toml:name = "device-agent-runtime", add a one-linedescriptionreflecting the new positioning - 7.2 Create root
README.md: project positioning as a device-agnostic Device Agent Runtime (iPhone/WDA as the first driver), link todocs/ROADMAP.mdanddocs/CONSTITUTION.md
8. Planning artifacts
- 8.1 Create
docs/ROADMAP.mdwith the Milestone 0–10 sequence, the three delivery phases, and the long-term "DeviceOS" / Universal Device Runtime direction (v2.0, explicitly not started); explicitly map Milestones 1–4 to already-implementedapex-agent-mvpcapabilities (device-management,scene-perception,agent-runtime,task-memory) rather than treating them as separate future work - 8.2 Create
docs/adr/0001-device-agnostic-runtime.mdrecording this repositioning decision (context, decision, alternatives considered, consequences), referencing this change's design.md decisions - 8.3 Create
docs/adr/0002-layered-hexagonal-architecture.mdrecording the Hexagonal/Ports-and-Adapters + DDD layering decision (D7): dependency direction (coredomain has zero framework/LLM/HTTP deps;driver/deviceadapt external SDKs;toolsis the capability/port layer;perceptionsits behindPerceptionProvider;runtimeis the application layer where an LLM first enters via the Planner;apiis the outermost transport adapter) and the bottom-up build order future milestones must respect - 8.4 Create
docs/CONSTITUTION.mdcapturing durable invariants:Driveris the only device-capability contract;tools/only calls into device/driver capabilities, never a concrete driver;Sceneis the only perception artifact the LLM ever sees, produced throughPerceptionProvider; drivers are stateless; Planner produces a plan, Executor is the only thing that calls tools and retries; no LLM, HTTP, or MCP dependency may appear incore,driver,device, ortools— those enter only atruntime(Planner) andapirespectively; every future milestone change must state in its design.md how it upholds this boundary - 8.5 Create
research/001-scene-model/README.mdthroughresearch/007-ui-understanding/README.md(scene-model, world-model, skill, agent, memory, planner, ui-understanding), each a short placeholder stating the track's purpose and that it holds papers/experiments/benchmarks, not code
9. Final verification
- 9.1 Run
pytestonce more after all doc additions to confirm nothing intests/was accidentally affected - 9.2 Manually skim every touched file's diff to confirm no behavior changed — only paths, names, new port, and net-new docs