droidrun 0.5.0.dev5__tar.gz → 0.5.0.dev7__tar.gz
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.
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/PKG-INFO +1 -1
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/codeact/codeact_agent.py +54 -33
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/codeact/tools_agent.py +60 -34
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/droid/droid_agent.py +18 -7
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/droid/state.py +3 -2
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/executor/executor_agent.py +7 -10
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/manager/manager_agent.py +37 -29
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/chat_utils.py +9 -9
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/inference.py +8 -2
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/pyproject.toml +1 -1
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/uv.lock +1 -1
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.dockerignore +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/black.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/bounty.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/claude-code-review.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/claude.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/docker.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.github/workflows/publish.yml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.gitignore +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/.python-version +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/CHANGELOG.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/CONTRIBUTING.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/Dockerfile +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/LICENSE +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/MANIFEST.in +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/README.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/SKILL.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/ favicon.svg +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/custom.css +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/docs.json +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/favicon-dark.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/favicon.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/logo/dark.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/logo/light.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/concepts/agent.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/concepts/android-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/concepts/models.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/concepts/portal-app.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/cli.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/gemini.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/ollama.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/openailike.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/guides/telemetry.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/images/portal_apk.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v3/quickstart.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/concepts/architecture.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/concepts/events-and-workflows.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/concepts/prompts.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/concepts/scripter-agent.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/concepts/shared-state.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/app-cards.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/credentials.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/custom-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/custom-variables.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/structured-output.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/telemetry.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/features/tracing.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/guides/cli.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/guides/device-setup.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/guides/docker.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/guides/migration-v3-to-v4.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/guides/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/quickstart.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/adb-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/base-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/configuration.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/droid-agent.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/ios-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v4/sdk/reference.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/concepts/architecture.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/concepts/events-and-workflows.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/concepts/prompts.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/concepts/scripter-agent.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/concepts/shared-state.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/app-cards.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/credentials.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/custom-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/custom-variables.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/structured-output.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/telemetry.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/features/tracing.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/guides/cli.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/guides/device-setup.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/guides/docker.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/guides/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/overview.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/quickstart.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/adb-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/base-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/configuration.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/droid-agent.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/ios-tools.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/docs/v5/sdk/reference.mdx +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/__main__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/action_context.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/action_result.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/codeact/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/codeact/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/codeact/xml_parser.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/common/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/common/constants.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/common/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/droid/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/droid/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/executor/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/executor/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/executor/prompts.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/external/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/external/autoglm.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/external/mai_ui.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/manager/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/manager/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/manager/prompts.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/manager/stateless_manager_agent.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/oneflows/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/oneflows/app_starter_workflow.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/oneflows/structured_output_agent.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/oneflows/text_manipulator.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/scripter/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/scripter/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/scripter/scripter_agent.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/tool_registry.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/trajectory/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/trajectory/writer.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/usage.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/actions.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/code_checker.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/executer.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/llm_loader.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/llm_picker.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/prompt_resolver.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/signatures.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/tracing_setup.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/agent/utils/trajectory.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/app_card_provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/providers/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/providers/composite_provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/providers/local_provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/app_cards/providers/server_provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/doctor.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/event_handler.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/logs.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/main.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/app.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/commands.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/css/advanced_tab.tcss +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/css/app.tcss +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/css/models_tab.tcss +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/css/settings_screen.tcss +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/advanced_tab.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/agent_tab.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/data.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/models_tab.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/section.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/settings/settings_screen.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/command_dropdown.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/device_picker.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/input_bar.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/log_view.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/cli/tui/widgets/status_bar.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/app_cards/README.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/app_cards/app_cards.json +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/app_cards/gmail.md +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/credentials_example.yaml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/codeact/system.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/codeact/tools_system.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/codeact/tools_user.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/codeact/user.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/executor/rev1.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/executor/system.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/manager/rev1.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/manager/stateless.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/manager/system.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/manager/trained.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config/prompts/scripter/system.jinja2 +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_example.yaml +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/config_manager.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/env_keys.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/loader.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/migrations/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/migrations/v002_add_code_exec.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/path_resolver.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/prompt_loader.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/config_manager/safe_execution.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/credential_manager/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/credential_manager/credential_manager.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/credential_manager/file_credential_manager.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/log_handlers.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/macro/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/macro/__main__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/macro/cli.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/macro/replay.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/mcp/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/mcp/adapter.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/mcp/client.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/mcp/config.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/portal.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/telemetry/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/telemetry/events.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/telemetry/langfuse_processor.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/telemetry/phoenix.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/telemetry/tracker.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/android/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/android/portal_client.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/android.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/base.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/cloud.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/ios.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/recording.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/driver/stealth.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/filters/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/filters/base.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/filters/concise_filter.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/filters/detailed_filter.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/formatters/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/formatters/base.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/formatters/indexed_formatter.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/helpers/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/helpers/coordinate.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/helpers/element_search.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/helpers/geometry.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ios/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ui/__init__.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ui/ios_provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ui/provider.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ui/state.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/droidrun/tools/ui/stealth_state.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/gen-docs-sdk-ref.sh +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/setup.py +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/static/droidrun-dark.png +0 -0
- {droidrun-0.5.0.dev5 → droidrun-0.5.0.dev7}/static/droidrun.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: droidrun
|
|
3
|
-
Version: 0.5.0.
|
|
3
|
+
Version: 0.5.0.dev7
|
|
4
4
|
Summary: A framework for controlling Android devices through LLM agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/droidrun/droidrun
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/droidrun/droidrun/issues
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import copy
|
|
2
3
|
import inspect
|
|
3
4
|
import logging
|
|
4
5
|
from typing import TYPE_CHECKING, Optional, Type
|
|
5
6
|
|
|
7
|
+
from llama_index.core.base.llms.types import ChatMessage, ImageBlock, TextBlock
|
|
6
8
|
from llama_index.core.llms.llm import LLM
|
|
7
9
|
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
|
|
8
10
|
from opentelemetry import trace
|
|
@@ -21,7 +23,6 @@ from droidrun.agent.usage import get_usage_from_response
|
|
|
21
23
|
from droidrun.agent.utils.chat_utils import (
|
|
22
24
|
extract_code_and_thought,
|
|
23
25
|
limit_history,
|
|
24
|
-
to_chat_messages,
|
|
25
26
|
)
|
|
26
27
|
from droidrun.agent.utils.executer import ExecuterState, SimpleCodeExecutor
|
|
27
28
|
from droidrun.agent.utils.inference import acall_with_retries
|
|
@@ -52,7 +53,7 @@ class CodeActAgent(Workflow):
|
|
|
52
53
|
Agent that generates and executes Python code using atomic actions.
|
|
53
54
|
|
|
54
55
|
Uses ReAct cycle: Thought -> Code -> Observation -> repeat until complete().
|
|
55
|
-
Messages stored as list[
|
|
56
|
+
Messages stored as list[ChatMessage] to preserve thinking tokens across turns.
|
|
56
57
|
"""
|
|
57
58
|
|
|
58
59
|
def __init__(
|
|
@@ -90,7 +91,7 @@ class CodeActAgent(Workflow):
|
|
|
90
91
|
self.prompt_resolver = prompt_resolver or PromptResolver()
|
|
91
92
|
self.tracing_config = tracing_config
|
|
92
93
|
|
|
93
|
-
self.system_prompt:
|
|
94
|
+
self.system_prompt: ChatMessage | None = None
|
|
94
95
|
self.code_exec_counter = 0
|
|
95
96
|
self.remembered_info: list[str] | None = None
|
|
96
97
|
|
|
@@ -150,7 +151,7 @@ class CodeActAgent(Workflow):
|
|
|
150
151
|
|
|
151
152
|
logger.debug("CodeActAgent initialized.")
|
|
152
153
|
|
|
153
|
-
async def _build_system_prompt(self) ->
|
|
154
|
+
async def _build_system_prompt(self) -> ChatMessage:
|
|
154
155
|
"""Build system prompt message."""
|
|
155
156
|
# Build template context with available tools for conditional examples
|
|
156
157
|
template_context = {
|
|
@@ -178,9 +179,9 @@ class CodeActAgent(Workflow):
|
|
|
178
179
|
str(PathResolver.resolve(prompt_path, must_exist=True)),
|
|
179
180
|
template_context,
|
|
180
181
|
)
|
|
181
|
-
return
|
|
182
|
+
return ChatMessage(role="system", content=system_text)
|
|
182
183
|
|
|
183
|
-
async def _build_user_prompt(self, goal: str) ->
|
|
184
|
+
async def _build_user_prompt(self, goal: str) -> ChatMessage:
|
|
184
185
|
"""Build initial user prompt message."""
|
|
185
186
|
custom_user_prompt = self.prompt_resolver.get_prompt("fast_agent_user")
|
|
186
187
|
if custom_user_prompt:
|
|
@@ -207,7 +208,7 @@ class CodeActAgent(Workflow):
|
|
|
207
208
|
),
|
|
208
209
|
},
|
|
209
210
|
)
|
|
210
|
-
return
|
|
211
|
+
return ChatMessage(role="user", content=user_text)
|
|
211
212
|
|
|
212
213
|
@step
|
|
213
214
|
async def prepare_chat(self, ctx: Context, ev: StartEvent) -> CodeActInputEvent:
|
|
@@ -240,8 +241,8 @@ class CodeActAgent(Workflow):
|
|
|
240
241
|
for idx, item in enumerate(remembered_info, 1):
|
|
241
242
|
memory_text += f"{idx}. {item}\n"
|
|
242
243
|
# Append to first user message
|
|
243
|
-
self.shared_state.message_history[0]
|
|
244
|
-
|
|
244
|
+
self.shared_state.message_history[0].blocks.append(
|
|
245
|
+
TextBlock(text=memory_text)
|
|
245
246
|
)
|
|
246
247
|
|
|
247
248
|
return CodeActInputEvent()
|
|
@@ -296,7 +297,10 @@ class CodeActAgent(Workflow):
|
|
|
296
297
|
ui_state = await self.state_provider.get_state()
|
|
297
298
|
self.action_ctx.ui = ui_state
|
|
298
299
|
|
|
299
|
-
# Update shared state
|
|
300
|
+
# Update shared state (previous ← current, current ← new)
|
|
301
|
+
self.shared_state.previous_formatted_device_state = (
|
|
302
|
+
self.shared_state.formatted_device_state
|
|
303
|
+
)
|
|
300
304
|
self.shared_state.formatted_device_state = ui_state.formatted_text
|
|
301
305
|
self.shared_state.focused_text = ui_state.focused_text
|
|
302
306
|
self.shared_state.a11y_tree = ui_state.elements
|
|
@@ -311,11 +315,6 @@ class CodeActAgent(Workflow):
|
|
|
311
315
|
# Stream formatted state for trajectory
|
|
312
316
|
ctx.write_event_to_stream(RecordUIStateEvent(ui_state=ui_state.elements))
|
|
313
317
|
|
|
314
|
-
# Add device state to last user message
|
|
315
|
-
self.shared_state.message_history[-1]["content"].append(
|
|
316
|
-
{"text": f"\n{ui_state.formatted_text}\n"}
|
|
317
|
-
)
|
|
318
|
-
|
|
319
318
|
except DeviceDisconnectedError:
|
|
320
319
|
raise
|
|
321
320
|
except Exception as e:
|
|
@@ -323,27 +322,51 @@ class CodeActAgent(Workflow):
|
|
|
323
322
|
if self.debug:
|
|
324
323
|
logger.error("State retrieval error details:", exc_info=True)
|
|
325
324
|
|
|
326
|
-
#
|
|
327
|
-
if self.vision and screenshot:
|
|
328
|
-
self.shared_state.message_history[-1]["content"].append(
|
|
329
|
-
{"image": screenshot}
|
|
330
|
-
)
|
|
331
|
-
|
|
332
|
-
# Limit history and prepare for LLM
|
|
325
|
+
# Limit history and build ephemeral copy for LLM
|
|
333
326
|
limited_history = limit_history(
|
|
334
327
|
self.shared_state.message_history,
|
|
335
328
|
LLM_HISTORY_LIMIT * 2,
|
|
336
329
|
preserve_first=True,
|
|
337
330
|
)
|
|
331
|
+
messages_to_send = [self.system_prompt] + copy.deepcopy(limited_history)
|
|
332
|
+
|
|
333
|
+
# Inject device state and screenshot into the copy (not the original)
|
|
334
|
+
user_indices = [
|
|
335
|
+
i for i, msg in enumerate(messages_to_send) if msg.role == "user"
|
|
336
|
+
]
|
|
337
|
+
if user_indices:
|
|
338
|
+
last_user_idx = user_indices[-1]
|
|
339
|
+
|
|
340
|
+
# Current device state → last user message
|
|
341
|
+
current_state = self.shared_state.formatted_device_state.strip()
|
|
342
|
+
if current_state:
|
|
343
|
+
messages_to_send[last_user_idx].blocks.append(
|
|
344
|
+
TextBlock(
|
|
345
|
+
text=f"\n<device_state>\n{current_state}\n</device_state>\n"
|
|
346
|
+
)
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
# Screenshot → last user message
|
|
350
|
+
if self.vision and screenshot:
|
|
351
|
+
messages_to_send[last_user_idx].blocks.append(
|
|
352
|
+
ImageBlock(image=screenshot)
|
|
353
|
+
)
|
|
338
354
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
355
|
+
# Previous device state → second-to-last user message
|
|
356
|
+
if len(user_indices) >= 2:
|
|
357
|
+
second_last_idx = user_indices[-2]
|
|
358
|
+
prev_state = self.shared_state.previous_formatted_device_state.strip()
|
|
359
|
+
if prev_state:
|
|
360
|
+
messages_to_send[second_last_idx].blocks.append(
|
|
361
|
+
TextBlock(
|
|
362
|
+
text=f"\n<previous_device_state>\n{prev_state}\n</previous_device_state>\n"
|
|
363
|
+
)
|
|
364
|
+
)
|
|
342
365
|
|
|
343
366
|
# Call LLM
|
|
344
367
|
logger.info("CodeAct response:", extra={"color": "yellow"})
|
|
345
368
|
response = await acall_with_retries(
|
|
346
|
-
self.llm,
|
|
369
|
+
self.llm, messages_to_send, stream=self.agent_config.streaming
|
|
347
370
|
)
|
|
348
371
|
|
|
349
372
|
if response is None:
|
|
@@ -360,11 +383,9 @@ class CodeActAgent(Workflow):
|
|
|
360
383
|
except Exception as e:
|
|
361
384
|
logger.warning(f"Could not get usage: {e}")
|
|
362
385
|
|
|
363
|
-
# Store assistant response
|
|
386
|
+
# Store assistant response (preserves ThinkingBlock, additional_kwargs, etc.)
|
|
387
|
+
self.shared_state.message_history.append(response.message)
|
|
364
388
|
response_text = response.message.content
|
|
365
|
-
self.shared_state.message_history.append(
|
|
366
|
-
{"role": "assistant", "content": [{"text": response_text}]}
|
|
367
|
-
)
|
|
368
389
|
|
|
369
390
|
# Extract thought and code
|
|
370
391
|
code, thought = extract_code_and_thought(response_text)
|
|
@@ -391,7 +412,7 @@ class CodeActAgent(Workflow):
|
|
|
391
412
|
"Now, describe the next step you will take to address the original goal."
|
|
392
413
|
)
|
|
393
414
|
self.shared_state.message_history.append(
|
|
394
|
-
|
|
415
|
+
ChatMessage(role="user", content=no_thoughts_text)
|
|
395
416
|
)
|
|
396
417
|
else:
|
|
397
418
|
logger.debug(f"Reasoning: {ev.thought}")
|
|
@@ -408,7 +429,7 @@ class CodeActAgent(Workflow):
|
|
|
408
429
|
"function within a <python></python> code block."
|
|
409
430
|
)
|
|
410
431
|
self.shared_state.message_history.append(
|
|
411
|
-
|
|
432
|
+
ChatMessage(role="user", content=no_code_text)
|
|
412
433
|
)
|
|
413
434
|
return CodeActInputEvent()
|
|
414
435
|
|
|
@@ -482,7 +503,7 @@ class CodeActAgent(Workflow):
|
|
|
482
503
|
# Add execution output as user message
|
|
483
504
|
observation_text = f"Execution Result:\n<result>\n{output}\n</result>"
|
|
484
505
|
self.shared_state.message_history.append(
|
|
485
|
-
|
|
506
|
+
ChatMessage(role="user", content=observation_text)
|
|
486
507
|
)
|
|
487
508
|
|
|
488
509
|
return CodeActInputEvent()
|
|
@@ -9,9 +9,12 @@ compatibility with DroidAgent's execute_task() method.
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import asyncio
|
|
12
|
+
import copy
|
|
12
13
|
import logging
|
|
14
|
+
import os
|
|
13
15
|
from typing import TYPE_CHECKING, Optional, Type
|
|
14
16
|
|
|
17
|
+
from llama_index.core.base.llms.types import ChatMessage, ImageBlock, TextBlock
|
|
15
18
|
from llama_index.core.llms.llm import LLM
|
|
16
19
|
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
|
|
17
20
|
from opentelemetry import trace
|
|
@@ -35,7 +38,7 @@ from droidrun.agent.codeact.xml_parser import (
|
|
|
35
38
|
from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
|
|
36
39
|
from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
|
|
37
40
|
from droidrun.agent.usage import get_usage_from_response
|
|
38
|
-
from droidrun.agent.utils.chat_utils import limit_history
|
|
41
|
+
from droidrun.agent.utils.chat_utils import limit_history
|
|
39
42
|
from droidrun.agent.utils.inference import acall_with_retries
|
|
40
43
|
from droidrun.agent.utils.prompt_resolver import PromptResolver
|
|
41
44
|
from droidrun.agent.utils.tracing_setup import record_langfuse_screenshot
|
|
@@ -56,7 +59,7 @@ class FastAgent(Workflow):
|
|
|
56
59
|
"""Agent that uses XML tool-calling instead of code generation.
|
|
57
60
|
|
|
58
61
|
Uses ReAct cycle: Thought -> Tool Call -> Observation -> repeat until complete().
|
|
59
|
-
Messages stored as list[
|
|
62
|
+
Messages stored as list[ChatMessage] to preserve thinking tokens across turns.
|
|
60
63
|
"""
|
|
61
64
|
|
|
62
65
|
def __init__(
|
|
@@ -88,12 +91,15 @@ class FastAgent(Workflow):
|
|
|
88
91
|
self.action_ctx = action_ctx
|
|
89
92
|
self.state_provider = state_provider
|
|
90
93
|
self.save_trajectory = save_trajectory
|
|
94
|
+
self._stream_screenshots = os.environ.get(
|
|
95
|
+
"DROIDRUN_STREAM_SCREENSHOTS", ""
|
|
96
|
+
).lower() in ("1", "true")
|
|
91
97
|
self.shared_state = shared_state
|
|
92
98
|
self.output_model = output_model
|
|
93
99
|
self.prompt_resolver = prompt_resolver or PromptResolver()
|
|
94
100
|
self.tracing_config = tracing_config
|
|
95
101
|
|
|
96
|
-
self.system_prompt:
|
|
102
|
+
self.system_prompt: ChatMessage | None = None
|
|
97
103
|
self.tool_call_counter = 0
|
|
98
104
|
self.remembered_info: list[str] | None = None
|
|
99
105
|
|
|
@@ -108,7 +114,7 @@ class FastAgent(Workflow):
|
|
|
108
114
|
|
|
109
115
|
logger.debug("FastAgent initialized.")
|
|
110
116
|
|
|
111
|
-
async def _build_system_prompt(self) ->
|
|
117
|
+
async def _build_system_prompt(self) -> ChatMessage:
|
|
112
118
|
"""Build system prompt message."""
|
|
113
119
|
template_context = {
|
|
114
120
|
"tool_descriptions": self.tool_descriptions,
|
|
@@ -133,9 +139,9 @@ class FastAgent(Workflow):
|
|
|
133
139
|
self.agent_config.get_fast_agent_system_prompt_path(),
|
|
134
140
|
template_context,
|
|
135
141
|
)
|
|
136
|
-
return
|
|
142
|
+
return ChatMessage(role="system", content=system_text)
|
|
137
143
|
|
|
138
|
-
async def _build_user_prompt(self, goal: str) ->
|
|
144
|
+
async def _build_user_prompt(self, goal: str) -> ChatMessage:
|
|
139
145
|
"""Build initial user prompt message."""
|
|
140
146
|
custom_user_prompt = self.prompt_resolver.get_prompt("fast_agent_user")
|
|
141
147
|
if custom_user_prompt:
|
|
@@ -158,7 +164,7 @@ class FastAgent(Workflow):
|
|
|
158
164
|
),
|
|
159
165
|
},
|
|
160
166
|
)
|
|
161
|
-
return
|
|
167
|
+
return ChatMessage(role="user", content=user_text)
|
|
162
168
|
|
|
163
169
|
@step
|
|
164
170
|
async def prepare_chat(self, ctx: Context, ev: StartEvent) -> FastAgentInputEvent:
|
|
@@ -190,8 +196,8 @@ class FastAgent(Workflow):
|
|
|
190
196
|
memory_text = "\n### Remembered Information:\n"
|
|
191
197
|
for idx, item in enumerate(remembered_info, 1):
|
|
192
198
|
memory_text += f"{idx}. {item}\n"
|
|
193
|
-
self.shared_state.message_history[0]
|
|
194
|
-
|
|
199
|
+
self.shared_state.message_history[0].blocks.append(
|
|
200
|
+
TextBlock(text=memory_text)
|
|
195
201
|
)
|
|
196
202
|
|
|
197
203
|
return FastAgentInputEvent()
|
|
@@ -218,7 +224,7 @@ class FastAgent(Workflow):
|
|
|
218
224
|
|
|
219
225
|
# Capture screenshot if needed
|
|
220
226
|
screenshot = None
|
|
221
|
-
if self.vision or self.save_trajectory != "none":
|
|
227
|
+
if self.vision or self._stream_screenshots or self.save_trajectory != "none":
|
|
222
228
|
try:
|
|
223
229
|
screenshot = await self.action_ctx.driver.screenshot()
|
|
224
230
|
|
|
@@ -246,7 +252,10 @@ class FastAgent(Workflow):
|
|
|
246
252
|
ui_state = await self.state_provider.get_state()
|
|
247
253
|
self.action_ctx.ui = ui_state
|
|
248
254
|
|
|
249
|
-
# Update shared state
|
|
255
|
+
# Update shared state (previous ← current, current ← new)
|
|
256
|
+
self.shared_state.previous_formatted_device_state = (
|
|
257
|
+
self.shared_state.formatted_device_state
|
|
258
|
+
)
|
|
250
259
|
self.shared_state.formatted_device_state = ui_state.formatted_text
|
|
251
260
|
self.shared_state.focused_text = ui_state.focused_text
|
|
252
261
|
self.shared_state.a11y_tree = ui_state.elements
|
|
@@ -261,11 +270,6 @@ class FastAgent(Workflow):
|
|
|
261
270
|
# Stream formatted state for trajectory
|
|
262
271
|
ctx.write_event_to_stream(RecordUIStateEvent(ui_state=ui_state.elements))
|
|
263
272
|
|
|
264
|
-
# Add device state to last user message
|
|
265
|
-
self.shared_state.message_history[-1]["content"].append(
|
|
266
|
-
{"text": f"\n{ui_state.formatted_text}\n"}
|
|
267
|
-
)
|
|
268
|
-
|
|
269
273
|
except DeviceDisconnectedError:
|
|
270
274
|
raise
|
|
271
275
|
except Exception as e:
|
|
@@ -273,27 +277,51 @@ class FastAgent(Workflow):
|
|
|
273
277
|
if self.debug:
|
|
274
278
|
logger.error("State retrieval error details:", exc_info=True)
|
|
275
279
|
|
|
276
|
-
#
|
|
277
|
-
if self.vision and screenshot:
|
|
278
|
-
self.shared_state.message_history[-1]["content"].append(
|
|
279
|
-
{"image": screenshot}
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
# Limit history and prepare for LLM
|
|
280
|
+
# Limit history and build ephemeral copy for LLM
|
|
283
281
|
limited_history = limit_history(
|
|
284
282
|
self.shared_state.message_history,
|
|
285
283
|
LLM_HISTORY_LIMIT * 2,
|
|
286
284
|
preserve_first=True,
|
|
287
285
|
)
|
|
286
|
+
messages_to_send = [self.system_prompt] + copy.deepcopy(limited_history)
|
|
287
|
+
|
|
288
|
+
# Inject device state and screenshot into the copy (not the original)
|
|
289
|
+
user_indices = [
|
|
290
|
+
i for i, msg in enumerate(messages_to_send) if msg.role == "user"
|
|
291
|
+
]
|
|
292
|
+
if user_indices:
|
|
293
|
+
last_user_idx = user_indices[-1]
|
|
294
|
+
|
|
295
|
+
# Current device state → last user message
|
|
296
|
+
current_state = self.shared_state.formatted_device_state.strip()
|
|
297
|
+
if current_state:
|
|
298
|
+
messages_to_send[last_user_idx].blocks.append(
|
|
299
|
+
TextBlock(
|
|
300
|
+
text=f"\n<device_state>\n{current_state}\n</device_state>\n"
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Screenshot → last user message
|
|
305
|
+
if self.vision and screenshot:
|
|
306
|
+
messages_to_send[last_user_idx].blocks.append(
|
|
307
|
+
ImageBlock(image=screenshot)
|
|
308
|
+
)
|
|
288
309
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
310
|
+
# Previous device state → second-to-last user message
|
|
311
|
+
if len(user_indices) >= 2:
|
|
312
|
+
second_last_idx = user_indices[-2]
|
|
313
|
+
prev_state = self.shared_state.previous_formatted_device_state.strip()
|
|
314
|
+
if prev_state:
|
|
315
|
+
messages_to_send[second_last_idx].blocks.append(
|
|
316
|
+
TextBlock(
|
|
317
|
+
text=f"\n<previous_device_state>\n{prev_state}\n</previous_device_state>\n"
|
|
318
|
+
)
|
|
319
|
+
)
|
|
292
320
|
|
|
293
321
|
# Call LLM
|
|
294
322
|
logger.info("FastAgent response:", extra={"color": "yellow"})
|
|
295
323
|
response = await acall_with_retries(
|
|
296
|
-
self.llm,
|
|
324
|
+
self.llm, messages_to_send, stream=self.agent_config.streaming
|
|
297
325
|
)
|
|
298
326
|
|
|
299
327
|
if response is None:
|
|
@@ -310,11 +338,9 @@ class FastAgent(Workflow):
|
|
|
310
338
|
except Exception as e:
|
|
311
339
|
logger.warning(f"Could not get usage: {e}")
|
|
312
340
|
|
|
313
|
-
# Store assistant response
|
|
341
|
+
# Store assistant response (preserves ThinkingBlock, additional_kwargs, etc.)
|
|
342
|
+
self.shared_state.message_history.append(response.message)
|
|
314
343
|
response_text = response.message.content
|
|
315
|
-
self.shared_state.message_history.append(
|
|
316
|
-
{"role": "assistant", "content": [{"text": response_text}]}
|
|
317
|
-
)
|
|
318
344
|
|
|
319
345
|
# Parse tool calls from response
|
|
320
346
|
thought, tool_calls = parse_tool_calls(response_text, self.param_types)
|
|
@@ -360,7 +386,7 @@ class FastAgent(Workflow):
|
|
|
360
386
|
"Now, describe the next step you will take to address the original goal."
|
|
361
387
|
)
|
|
362
388
|
self.shared_state.message_history.append(
|
|
363
|
-
|
|
389
|
+
ChatMessage(role="user", content=no_thoughts_text)
|
|
364
390
|
)
|
|
365
391
|
else:
|
|
366
392
|
logger.debug(f"Reasoning: {ev.thought}")
|
|
@@ -382,7 +408,7 @@ class FastAgent(Workflow):
|
|
|
382
408
|
"</function_calls>"
|
|
383
409
|
)
|
|
384
410
|
self.shared_state.message_history.append(
|
|
385
|
-
|
|
411
|
+
ChatMessage(role="user", content=no_tools_text)
|
|
386
412
|
)
|
|
387
413
|
return FastAgentInputEvent()
|
|
388
414
|
|
|
@@ -469,7 +495,7 @@ class FastAgent(Workflow):
|
|
|
469
495
|
|
|
470
496
|
# Add results as user message
|
|
471
497
|
self.shared_state.message_history.append(
|
|
472
|
-
|
|
498
|
+
ChatMessage(role="user", content=output)
|
|
473
499
|
)
|
|
474
500
|
|
|
475
501
|
return FastAgentInputEvent()
|
|
@@ -8,6 +8,7 @@ Architecture:
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
|
+
import os
|
|
11
12
|
import traceback
|
|
12
13
|
from typing import TYPE_CHECKING, Awaitable, Type, Union
|
|
13
14
|
|
|
@@ -208,6 +209,10 @@ class DroidAgent(Workflow):
|
|
|
208
209
|
# Check if using external agent - skip LLM loading
|
|
209
210
|
self._using_external_agent = self.config.agent.name != "droidrun"
|
|
210
211
|
|
|
212
|
+
self._stream_screenshots = os.environ.get(
|
|
213
|
+
"DROIDRUN_STREAM_SCREENSHOTS", ""
|
|
214
|
+
).lower() in ("1", "true")
|
|
215
|
+
|
|
211
216
|
self.timeout = timeout
|
|
212
217
|
|
|
213
218
|
# Store user custom tools
|
|
@@ -1039,17 +1044,21 @@ class DroidAgent(Workflow):
|
|
|
1039
1044
|
if self.config.logging.debug:
|
|
1040
1045
|
logger.error(traceback.format_exc())
|
|
1041
1046
|
|
|
1042
|
-
# Capture final screenshot
|
|
1043
|
-
|
|
1047
|
+
# Capture final screenshot (independent of trajectory persistence)
|
|
1048
|
+
vision_any = (
|
|
1049
|
+
self.config.agent.manager.vision
|
|
1050
|
+
or self.config.agent.executor.vision
|
|
1051
|
+
or self.config.agent.fast_agent.vision
|
|
1052
|
+
)
|
|
1053
|
+
if (
|
|
1054
|
+
vision_any
|
|
1055
|
+
or self._stream_screenshots
|
|
1056
|
+
or self.config.logging.save_trajectory != "none"
|
|
1057
|
+
):
|
|
1044
1058
|
try:
|
|
1045
1059
|
screenshot = await self.action_ctx.driver.screenshot()
|
|
1046
1060
|
if screenshot:
|
|
1047
1061
|
ctx.write_event_to_stream(ScreenshotEvent(screenshot=screenshot))
|
|
1048
|
-
vision_any = (
|
|
1049
|
-
self.config.agent.manager.vision
|
|
1050
|
-
or self.config.agent.executor.vision
|
|
1051
|
-
or self.config.agent.fast_agent.vision
|
|
1052
|
-
)
|
|
1053
1062
|
parent_span = trace.get_current_span()
|
|
1054
1063
|
record_langfuse_screenshot(
|
|
1055
1064
|
screenshot,
|
|
@@ -1061,6 +1070,8 @@ class DroidAgent(Workflow):
|
|
|
1061
1070
|
except Exception as e:
|
|
1062
1071
|
logger.warning(f"Failed to capture final screenshot: {e}")
|
|
1063
1072
|
|
|
1073
|
+
# Save trajectory to disk
|
|
1074
|
+
if self.config.logging.save_trajectory != "none":
|
|
1064
1075
|
# Populate macro data from RecordingDriver log
|
|
1065
1076
|
if isinstance(self.driver, RecordingDriver):
|
|
1066
1077
|
self.trajectory.macro = list(self.driver.log)
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
|
+
from llama_index.core.base.llms.types import ChatMessage
|
|
5
6
|
from pydantic import BaseModel, ConfigDict, Field
|
|
6
7
|
|
|
7
8
|
from droidrun.telemetry import PackageVisitEvent, capture
|
|
@@ -86,9 +87,9 @@ class DroidAgentState(BaseModel):
|
|
|
86
87
|
success: Optional[bool] = None
|
|
87
88
|
|
|
88
89
|
# ========================================================================
|
|
89
|
-
# Message History (for stateful agents -
|
|
90
|
+
# Message History (for stateful agents - preserves ChatMessage blocks)
|
|
90
91
|
# ========================================================================
|
|
91
|
-
message_history: List[
|
|
92
|
+
message_history: List[ChatMessage] = Field(default_factory=list)
|
|
92
93
|
|
|
93
94
|
# ========================================================================
|
|
94
95
|
# Error Handling
|
|
@@ -14,18 +14,18 @@ import json
|
|
|
14
14
|
import logging
|
|
15
15
|
from typing import TYPE_CHECKING, Optional
|
|
16
16
|
|
|
17
|
+
from llama_index.core.base.llms.types import ChatMessage, ImageBlock, TextBlock
|
|
17
18
|
from llama_index.core.llms.llm import LLM
|
|
18
19
|
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
|
|
19
20
|
|
|
20
21
|
from droidrun.agent.executor.events import (
|
|
21
22
|
ExecutorActionEvent,
|
|
23
|
+
ExecutorActionResultEvent,
|
|
22
24
|
ExecutorContextEvent,
|
|
23
25
|
ExecutorResponseEvent,
|
|
24
|
-
ExecutorActionResultEvent,
|
|
25
26
|
)
|
|
26
27
|
from droidrun.agent.executor.prompts import parse_executor_response
|
|
27
28
|
from droidrun.agent.usage import get_usage_from_response
|
|
28
|
-
from droidrun.agent.utils.chat_utils import to_chat_messages
|
|
29
29
|
from droidrun.agent.utils.inference import acall_with_retries
|
|
30
30
|
from droidrun.agent.utils.prompt_resolver import PromptResolver
|
|
31
31
|
from droidrun.config_manager.config_manager import AgentConfig
|
|
@@ -44,7 +44,7 @@ class ExecutorAgent(Workflow):
|
|
|
44
44
|
Action execution agent that performs specific actions.
|
|
45
45
|
|
|
46
46
|
Single-turn agent: receives subgoal, selects action, executes it.
|
|
47
|
-
Uses
|
|
47
|
+
Uses ChatMessage objects directly for LLM calls.
|
|
48
48
|
"""
|
|
49
49
|
|
|
50
50
|
# Flow-control tools hidden from executor's LLM prompt
|
|
@@ -123,14 +123,14 @@ class ExecutorAgent(Workflow):
|
|
|
123
123
|
variables,
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
-
# Build message
|
|
127
|
-
messages = [
|
|
126
|
+
# Build message
|
|
127
|
+
messages = [ChatMessage(role="user", blocks=[TextBlock(text=prompt_text)])]
|
|
128
128
|
|
|
129
129
|
# Add screenshot if vision enabled
|
|
130
130
|
if self.vision:
|
|
131
131
|
screenshot = self.shared_state.screenshot
|
|
132
132
|
if screenshot is not None:
|
|
133
|
-
messages[0]
|
|
133
|
+
messages[0].blocks.append(ImageBlock(image=screenshot))
|
|
134
134
|
logger.debug("📸 Using screenshot for Executor")
|
|
135
135
|
else:
|
|
136
136
|
logger.warning("⚠️ Vision enabled but no screenshot available")
|
|
@@ -149,13 +149,10 @@ class ExecutorAgent(Workflow):
|
|
|
149
149
|
# Get messages from context
|
|
150
150
|
messages = await ctx.store.get("executor_messages")
|
|
151
151
|
|
|
152
|
-
# Convert to ChatMessage and call LLM
|
|
153
|
-
chat_messages = to_chat_messages(messages)
|
|
154
|
-
|
|
155
152
|
try:
|
|
156
153
|
logger.info("Executor response:", extra={"color": "green"})
|
|
157
154
|
response = await acall_with_retries(
|
|
158
|
-
self.llm,
|
|
155
|
+
self.llm, messages, stream=self.agent_config.streaming
|
|
159
156
|
)
|
|
160
157
|
response_text = str(response)
|
|
161
158
|
except ValueError as e:
|