droidrun 0.4.0.dev5__tar.gz → 0.4.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.4.0.dev5 → droidrun-0.4.0.dev7}/.gitignore +3 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/PKG-INFO +1 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/structured-output.mdx +1 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/overview.mdx +31 -23
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/codeact/codeact_agent.py +1 -77
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/codeact/events.py +0 -5
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/droid/__init__.py +2 -2
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/droid/droid_agent.py +62 -40
- droidrun-0.4.0.dev7/droidrun/agent/droid/events.py +124 -0
- droidrun-0.4.0.dev5/droidrun/agent/droid/events.py → droidrun-0.4.0.dev7/droidrun/agent/droid/state.py +1 -127
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/executor/executor_agent.py +28 -8
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/manager/events.py +4 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/manager/manager_agent.py +35 -56
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/manager/prompts.py +24 -5
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/scripter/scripter_agent.py +5 -3
- droidrun-0.4.0.dev7/droidrun/agent/utils/__init__.py +52 -0
- droidrun-0.4.0.dev7/droidrun/agent/utils/chat_utils.py +255 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/llm_picker.py +8 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/tools.py +32 -4
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/cli/main.py +25 -20
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/manager/rev1.jinja2 +11 -3
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/manager/system.jinja2 +18 -6
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_manager/config_manager.py +12 -236
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/tools/adb.py +2 -2
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/tools/portal_client.py +1 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/pyproject.toml +1 -1
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/uv.lock +1 -1
- droidrun-0.4.0.dev5/droidrun/agent/context/__init__.py +0 -12
- droidrun-0.4.0.dev5/droidrun/agent/context/episodic_memory.py +0 -15
- droidrun-0.4.0.dev5/droidrun/agent/context/task_manager.py +0 -149
- droidrun-0.4.0.dev5/droidrun/agent/utils/__init__.py +0 -13
- droidrun-0.4.0.dev5/droidrun/agent/utils/chat_utils.py +0 -394
- droidrun-0.4.0.dev5/droidrun/agent/utils/message_utils.py +0 -85
- droidrun-0.4.0.dev5/examples/custom_prompts_example.py +0 -148
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/.github/workflows/black.yml +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/.github/workflows/bounty.yml +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/.github/workflows/publish.yml +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/.python-version +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/CHANGELOG.md +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/CONTRIBUTING.md +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/LICENSE +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/MANIFEST.in +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/README.md +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/docs.json +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/favicon.png +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/logo/dark.svg +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/logo/light.svg +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v1/concepts/agent.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v1/concepts/android-control.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v1/concepts/portal-app.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v1/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v1/quickstart.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/concepts/agent.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/concepts/android-control.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/concepts/planning.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/concepts/portal-app.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/concepts/tracing.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v2/quickstart.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/concepts/agent.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/concepts/android-tools.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/concepts/models.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/concepts/portal-app.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/cli.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/gemini.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/ollama.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/openailike.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/guides/telemetry.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/images/portal_apk.png +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v3/quickstart.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/agent-architecture.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/events-and-workflows.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/prompts.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/scripter-agent.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/concepts/shared-state.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/app-cards.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/cli.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/custom-tools-credentials.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/custom-variables.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/device-setup.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/overview.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/guides/telemetry-tracing.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/quickstart.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk/adb-tools.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk/base-tools.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk/configuration.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk/droid-agent.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk/ios-tools.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/docs/v4/sdk.mdx +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/__main__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/codeact/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/common/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/common/constants.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/common/events.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/executor/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/executor/events.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/executor/prompts.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/manager/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/oneflows/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/oneflows/app_starter_workflow.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/oneflows/structured_output_agent.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/oneflows/text_manipulator.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/scripter/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/scripter/events.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/usage.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/async_utils.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/device_state_formatter.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/executer.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/inference.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/llm_loader.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/prompt_resolver.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/agent/utils/trajectory.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/app_card_provider.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/providers/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/providers/composite_provider.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/providers/local_provider.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/app_cards/providers/server_provider.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/cli/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/cli/logs.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/app_cards/README.md +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/app_cards/app_cards.json +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/app_cards/gmail.md +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/credentials_example.yaml +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/codeact/system.jinja2 +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/codeact/user.jinja2 +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/executor/rev1.jinja2 +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/executor/system.jinja2 +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config/prompts/scripter/system.jinja2 +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_example.yaml +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_manager/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_manager/path_resolver.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_manager/prompt_loader.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/config_manager/safe_execution.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/credential_manager/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/credential_manager/credential_loader.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/credential_manager/credential_manager.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/macro/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/macro/__main__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/macro/cli.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/macro/replay.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/portal.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/telemetry/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/telemetry/events.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/telemetry/phoenix.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/telemetry/tracker.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/tools/__init__.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/tools/ios.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/droidrun/tools/tools.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/gen-docs-sdk-ref.sh +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/setup.py +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/static/droidrun-dark.png +0 -0
- {droidrun-0.4.0.dev5 → droidrun-0.4.0.dev7}/static/droidrun.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: droidrun
|
|
3
|
-
Version: 0.4.0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -51,24 +51,28 @@ Droidrun v4 introduces a hierarchical multi-agent system with specialized agents
|
|
|
51
51
|
Monitor and debug agent execution in real-time with Droidrun's comprehensive event system:
|
|
52
52
|
|
|
53
53
|
```python
|
|
54
|
+
import asyncio
|
|
54
55
|
from droidrun import DroidAgent, ResultEvent
|
|
55
56
|
from droidrun.agent.droid.events import ManagerPlanEvent, ExecutorResultEvent
|
|
56
57
|
from droidrun.config_manager.config_manager import DroidrunConfig
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
config
|
|
59
|
+
async def main():
|
|
60
|
+
# Create config with defaults
|
|
61
|
+
config = DroidrunConfig()
|
|
62
|
+
|
|
63
|
+
agent = DroidAgent(goal="Open Settings and enable WiFi", config=config)
|
|
64
|
+
handler = agent.run()
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
# Stream events in real-time
|
|
67
|
+
async for event in handler.stream_events():
|
|
68
|
+
if isinstance(event, ManagerPlanEvent):
|
|
69
|
+
print(f"Plan: {event.plan}")
|
|
70
|
+
elif isinstance(event, ExecutorResultEvent):
|
|
71
|
+
print(f"Action: {event.action}")
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
async for event in handler.stream_events():
|
|
66
|
-
if isinstance(event, ManagerPlanEvent):
|
|
67
|
-
print(f"Plan: {event.plan}")
|
|
68
|
-
elif isinstance(event, ExecutorResultEvent):
|
|
69
|
-
print(f"Action: {event.action}")
|
|
73
|
+
result: ResultEvent = await handler
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
asyncio.run(main())
|
|
72
76
|
```
|
|
73
77
|
|
|
74
78
|
Events provide rich metadata for:
|
|
@@ -125,6 +129,7 @@ llm_profiles:
|
|
|
125
129
|
Extract type-safe, validated data from device interactions using Pydantic models:
|
|
126
130
|
|
|
127
131
|
```python
|
|
132
|
+
import asyncio
|
|
128
133
|
from pydantic import BaseModel, Field
|
|
129
134
|
from droidrun import DroidAgent, ResultEvent
|
|
130
135
|
from droidrun.config_manager.config_manager import DroidrunConfig
|
|
@@ -135,21 +140,24 @@ class ContactInfo(BaseModel):
|
|
|
135
140
|
phone: str = Field(description="Phone number")
|
|
136
141
|
email: str = Field(description="Email address")
|
|
137
142
|
|
|
138
|
-
|
|
139
|
-
config
|
|
143
|
+
async def main():
|
|
144
|
+
# Create config with defaults
|
|
145
|
+
config = DroidrunConfig()
|
|
140
146
|
|
|
141
|
-
agent = DroidAgent(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
147
|
+
agent = DroidAgent(
|
|
148
|
+
goal="Find John Smith's contact and extract details",
|
|
149
|
+
config=config,
|
|
150
|
+
output_model=ContactInfo # Automatic structured extraction
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
handler = agent.run()
|
|
154
|
+
result: ResultEvent = await handler
|
|
146
155
|
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
if result.success and result.structured_output:
|
|
157
|
+
contact: ContactInfo = result.structured_output
|
|
158
|
+
print(f"Phone: {contact.phone}")
|
|
149
159
|
|
|
150
|
-
|
|
151
|
-
contact: ContactInfo = result.structured_output
|
|
152
|
-
print(f"Phone: {contact.phone}")
|
|
160
|
+
asyncio.run(main())
|
|
153
161
|
```
|
|
154
162
|
|
|
155
163
|
<Card title="Structured Output Guide" icon="table" href="/v4/guides/structured-output">
|
|
@@ -18,7 +18,6 @@ from llama_index.core.memory import Memory
|
|
|
18
18
|
from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow, step
|
|
19
19
|
|
|
20
20
|
from droidrun.agent.codeact.events import (
|
|
21
|
-
EpisodicMemoryEvent,
|
|
22
21
|
TaskEndEvent,
|
|
23
22
|
TaskExecutionEvent,
|
|
24
23
|
TaskExecutionResultEvent,
|
|
@@ -27,7 +26,6 @@ from droidrun.agent.codeact.events import (
|
|
|
27
26
|
)
|
|
28
27
|
from droidrun.agent.common.constants import LLM_HISTORY_LIMIT
|
|
29
28
|
from droidrun.agent.common.events import RecordUIStateEvent, ScreenshotEvent
|
|
30
|
-
from droidrun.agent.context.episodic_memory import EpisodicMemory, EpisodicMemoryStep
|
|
31
29
|
from droidrun.agent.usage import get_usage_from_response
|
|
32
30
|
from droidrun.agent.utils import chat_utils
|
|
33
31
|
from droidrun.agent.utils.device_state_formatter import format_device_state
|
|
@@ -43,7 +41,7 @@ from droidrun.config_manager.prompt_loader import PromptLoader
|
|
|
43
41
|
from droidrun.tools import Tools
|
|
44
42
|
|
|
45
43
|
if TYPE_CHECKING:
|
|
46
|
-
from droidrun.agent.droid
|
|
44
|
+
from droidrun.agent.droid import DroidAgentState
|
|
47
45
|
|
|
48
46
|
logger = logging.getLogger("droidrun")
|
|
49
47
|
|
|
@@ -85,7 +83,6 @@ class CodeActAgent(Workflow):
|
|
|
85
83
|
self.prompt_resolver = prompt_resolver or PromptResolver()
|
|
86
84
|
|
|
87
85
|
self.chat_memory = None
|
|
88
|
-
self.episodic_memory = EpisodicMemory()
|
|
89
86
|
self.remembered_info = None
|
|
90
87
|
|
|
91
88
|
self.goal = None
|
|
@@ -459,10 +456,6 @@ Now, describe the next step you will take to address the original goal: {goal}""
|
|
|
459
456
|
self.tools.finished = False
|
|
460
457
|
await ctx.store.set("chat_memory", self.chat_memory)
|
|
461
458
|
|
|
462
|
-
# Add final state observation to episodic memory
|
|
463
|
-
if self.vision:
|
|
464
|
-
await self._add_final_state_observation(ctx)
|
|
465
|
-
|
|
466
459
|
result = {}
|
|
467
460
|
result.update(
|
|
468
461
|
{
|
|
@@ -472,10 +465,6 @@ Now, describe the next step you will take to address the original goal: {goal}""
|
|
|
472
465
|
}
|
|
473
466
|
)
|
|
474
467
|
|
|
475
|
-
ctx.write_event_to_stream(
|
|
476
|
-
EpisodicMemoryEvent(episodic_memory=self.episodic_memory)
|
|
477
|
-
)
|
|
478
|
-
|
|
479
468
|
return StopEvent(result)
|
|
480
469
|
|
|
481
470
|
async def _get_llm_response(
|
|
@@ -500,26 +489,6 @@ Now, describe the next step you will take to address the original goal: {goal}""
|
|
|
500
489
|
]
|
|
501
490
|
filtered_chat_history.append(filtered_msg)
|
|
502
491
|
|
|
503
|
-
# Convert chat history and response to JSON strings
|
|
504
|
-
chat_history_str = json.dumps(
|
|
505
|
-
[
|
|
506
|
-
{"role": msg.role, "content": msg.content}
|
|
507
|
-
for msg in filtered_chat_history
|
|
508
|
-
]
|
|
509
|
-
)
|
|
510
|
-
response_str = json.dumps(
|
|
511
|
-
{"role": response.message.role, "content": response.message.content}
|
|
512
|
-
)
|
|
513
|
-
|
|
514
|
-
step = EpisodicMemoryStep(
|
|
515
|
-
chat_history=chat_history_str,
|
|
516
|
-
response=response_str,
|
|
517
|
-
timestamp=time.time(),
|
|
518
|
-
screenshot=(await ctx.store.get("screenshot", None)),
|
|
519
|
-
)
|
|
520
|
-
|
|
521
|
-
self.episodic_memory.steps.append(step)
|
|
522
|
-
|
|
523
492
|
assert hasattr(
|
|
524
493
|
response, "message"
|
|
525
494
|
), f"LLM response does not have a message attribute.\nResponse: {response}"
|
|
@@ -577,48 +546,3 @@ Now, describe the next step you will take to address the original goal: {goal}""
|
|
|
577
546
|
preserved_head = []
|
|
578
547
|
|
|
579
548
|
return preserved_head + tail
|
|
580
|
-
|
|
581
|
-
async def _add_final_state_observation(self, ctx: Context) -> None:
|
|
582
|
-
"""Add the current UI state and screenshot as the final observation step."""
|
|
583
|
-
try:
|
|
584
|
-
# Get current screenshot and UI state
|
|
585
|
-
screenshot = None
|
|
586
|
-
|
|
587
|
-
try:
|
|
588
|
-
_, screenshot_bytes = self.tools.take_screenshot()
|
|
589
|
-
screenshot = screenshot_bytes
|
|
590
|
-
except Exception as e:
|
|
591
|
-
logger.warning(f"Failed to capture final screenshot: {e}")
|
|
592
|
-
|
|
593
|
-
try:
|
|
594
|
-
state = self.tools.get_state()
|
|
595
|
-
a11y_tree = state.get("a11y_tree", "")
|
|
596
|
-
phone_state = state.get("phone_state", "") # noqa: F841
|
|
597
|
-
except Exception as e:
|
|
598
|
-
raise Exception(f"Failed to capture final UI state: {e}") from e
|
|
599
|
-
|
|
600
|
-
# Create final observation chat history and response
|
|
601
|
-
final_chat_history = [
|
|
602
|
-
{
|
|
603
|
-
"role": "system",
|
|
604
|
-
"content": "Final state observation after task completion",
|
|
605
|
-
}
|
|
606
|
-
]
|
|
607
|
-
final_response = {
|
|
608
|
-
"role": "user",
|
|
609
|
-
"content": f"Final State Observation:\nUI State: {a11y_tree}\nScreenshot: {'Available' if screenshot else 'Not available'}",
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
# Create final episodic memory step
|
|
613
|
-
final_step = EpisodicMemoryStep(
|
|
614
|
-
chat_history=json.dumps(final_chat_history),
|
|
615
|
-
response=json.dumps(final_response),
|
|
616
|
-
timestamp=time.time(),
|
|
617
|
-
screenshot=screenshot,
|
|
618
|
-
)
|
|
619
|
-
|
|
620
|
-
self.episodic_memory.steps.append(final_step)
|
|
621
|
-
logger.info("Added final state observation to episodic memory")
|
|
622
|
-
|
|
623
|
-
except Exception as e:
|
|
624
|
-
logger.error(f"Failed to add final state observation: {e}")
|
|
@@ -3,7 +3,6 @@ from typing import Optional
|
|
|
3
3
|
from llama_index.core.llms import ChatMessage
|
|
4
4
|
from llama_index.core.workflow import Event
|
|
5
5
|
|
|
6
|
-
from droidrun.agent.context.episodic_memory import EpisodicMemory
|
|
7
6
|
from droidrun.agent.usage import UsageResult
|
|
8
7
|
|
|
9
8
|
|
|
@@ -30,7 +29,3 @@ class TaskExecutionResultEvent(Event):
|
|
|
30
29
|
class TaskEndEvent(Event):
|
|
31
30
|
success: bool
|
|
32
31
|
reason: str
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class EpisodicMemoryEvent(Event):
|
|
36
|
-
episodic_memory: EpisodicMemory
|
|
@@ -4,7 +4,7 @@ Droidrun Agent Module.
|
|
|
4
4
|
This module provides a ReAct agent for automating Android devices using reasoning and acting.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from droidrun.agent.codeact.codeact_agent import CodeActAgent
|
|
8
7
|
from droidrun.agent.droid.droid_agent import DroidAgent
|
|
8
|
+
from droidrun.agent.droid.state import DroidAgentState
|
|
9
9
|
|
|
10
|
-
__all__ = ["
|
|
10
|
+
__all__ = ["DroidAgent", "DroidAgentState"]
|
|
@@ -18,13 +18,10 @@ from llama_index.core.workflow import Context, StartEvent, StopEvent, Workflow,
|
|
|
18
18
|
from workflows.events import Event
|
|
19
19
|
from workflows.handler import WorkflowHandler
|
|
20
20
|
from droidrun.agent.codeact import CodeActAgent
|
|
21
|
-
from droidrun.agent.codeact.events import EpisodicMemoryEvent
|
|
22
21
|
from droidrun.agent.common.events import MacroEvent, RecordUIStateEvent, ScreenshotEvent
|
|
23
|
-
from droidrun.agent.context.task_manager import Task, TaskManager
|
|
24
22
|
from droidrun.agent.droid.events import (
|
|
25
23
|
CodeActExecuteEvent,
|
|
26
24
|
CodeActResultEvent,
|
|
27
|
-
DroidAgentState,
|
|
28
25
|
ExecutorInputEvent,
|
|
29
26
|
ExecutorResultEvent,
|
|
30
27
|
FinalizeEvent,
|
|
@@ -34,6 +31,7 @@ from droidrun.agent.droid.events import (
|
|
|
34
31
|
ScripterExecutorInputEvent,
|
|
35
32
|
ScripterExecutorResultEvent,
|
|
36
33
|
)
|
|
34
|
+
from droidrun.agent.droid.state import DroidAgentState
|
|
37
35
|
from droidrun.agent.executor import ExecutorAgent
|
|
38
36
|
from droidrun.agent.manager import ManagerAgent
|
|
39
37
|
from droidrun.agent.scripter import ScripterAgent
|
|
@@ -269,9 +267,6 @@ class DroidAgent(Workflow):
|
|
|
269
267
|
self.structured_output_llm = llms
|
|
270
268
|
|
|
271
269
|
self.trajectory = Trajectory(goal=self.shared_state.instruction)
|
|
272
|
-
self.task_manager = TaskManager()
|
|
273
|
-
self.task_iter = None
|
|
274
|
-
self.current_episodic_memory = None
|
|
275
270
|
|
|
276
271
|
self.atomic_tools = ATOMIC_ACTION_SIGNATURES.copy()
|
|
277
272
|
|
|
@@ -378,14 +373,13 @@ class DroidAgent(Workflow):
|
|
|
378
373
|
Execute a single task using the CodeActAgent.
|
|
379
374
|
|
|
380
375
|
Args:
|
|
381
|
-
|
|
376
|
+
instruction: task of what the agent shall do
|
|
382
377
|
|
|
383
378
|
Returns:
|
|
384
379
|
Tuple of (success, reason)
|
|
385
380
|
"""
|
|
386
|
-
task: Task = ev.task
|
|
387
381
|
|
|
388
|
-
logger.info(f"🔧 Executing task: {
|
|
382
|
+
logger.info(f"🔧 Executing task: {ev.instruction}")
|
|
389
383
|
|
|
390
384
|
try:
|
|
391
385
|
codeact_agent = CodeActAgent(
|
|
@@ -403,7 +397,7 @@ class DroidAgent(Workflow):
|
|
|
403
397
|
)
|
|
404
398
|
|
|
405
399
|
handler = codeact_agent.run(
|
|
406
|
-
input=
|
|
400
|
+
input=ev.instruction,
|
|
407
401
|
remembered_info=self.tools_instance.memory,
|
|
408
402
|
)
|
|
409
403
|
|
|
@@ -413,17 +407,21 @@ class DroidAgent(Workflow):
|
|
|
413
407
|
result = await handler
|
|
414
408
|
|
|
415
409
|
if "success" in result and result["success"]:
|
|
416
|
-
|
|
410
|
+
event = CodeActResultEvent(
|
|
417
411
|
success=True,
|
|
418
412
|
reason=result["reason"],
|
|
419
|
-
|
|
413
|
+
instruction=ev.instruction,
|
|
420
414
|
)
|
|
415
|
+
ctx.write_event_to_stream(event)
|
|
416
|
+
return event
|
|
421
417
|
else:
|
|
422
|
-
|
|
418
|
+
event = CodeActResultEvent(
|
|
423
419
|
success=False,
|
|
424
420
|
reason=result["reason"],
|
|
425
|
-
|
|
421
|
+
instruction=ev.instruction,
|
|
426
422
|
)
|
|
423
|
+
ctx.write_event_to_stream(event)
|
|
424
|
+
return event
|
|
427
425
|
|
|
428
426
|
except Exception as e:
|
|
429
427
|
logger.error(f"Error during task execution: {e}")
|
|
@@ -431,26 +429,32 @@ class DroidAgent(Workflow):
|
|
|
431
429
|
import traceback
|
|
432
430
|
|
|
433
431
|
logger.error(traceback.format_exc())
|
|
434
|
-
|
|
435
|
-
success=False, reason=f"Error: {str(e)}",
|
|
432
|
+
event = CodeActResultEvent(
|
|
433
|
+
success=False, reason=f"Error: {str(e)}", instruction=ev.instruction
|
|
436
434
|
)
|
|
435
|
+
ctx.write_event_to_stream(event)
|
|
436
|
+
return event
|
|
437
437
|
|
|
438
438
|
@step
|
|
439
439
|
async def handle_codeact_execute(
|
|
440
440
|
self, ctx: Context, ev: CodeActResultEvent
|
|
441
441
|
) -> FinalizeEvent:
|
|
442
442
|
try:
|
|
443
|
-
|
|
443
|
+
event = FinalizeEvent(success=ev.success, reason=ev.reason)
|
|
444
|
+
ctx.write_event_to_stream(event)
|
|
445
|
+
return event
|
|
444
446
|
except Exception as e:
|
|
445
447
|
logger.error(f"❌ Error during DroidAgent execution: {e}")
|
|
446
448
|
if self.config.logging.debug:
|
|
447
449
|
import traceback
|
|
448
450
|
|
|
449
451
|
logger.error(traceback.format_exc())
|
|
450
|
-
|
|
452
|
+
event = FinalizeEvent(
|
|
451
453
|
success=False,
|
|
452
454
|
reason=str(e),
|
|
453
455
|
)
|
|
456
|
+
ctx.write_event_to_stream(event)
|
|
457
|
+
return event
|
|
454
458
|
|
|
455
459
|
@step
|
|
456
460
|
async def start_handler(
|
|
@@ -480,15 +484,14 @@ class DroidAgent(Workflow):
|
|
|
480
484
|
logger.info(
|
|
481
485
|
f"🔄 Direct execution mode - executing goal: {self.shared_state.instruction}"
|
|
482
486
|
)
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
agent_type="Default",
|
|
487
|
-
)
|
|
488
|
-
return CodeActExecuteEvent(task=task)
|
|
487
|
+
event = CodeActExecuteEvent(instruction=self.shared_state.instruction)
|
|
488
|
+
ctx.write_event_to_stream(event)
|
|
489
|
+
return event
|
|
489
490
|
|
|
490
491
|
logger.info("🧠 Reasoning mode - initializing Manager/Executor workflow")
|
|
491
|
-
|
|
492
|
+
event = ManagerInputEvent()
|
|
493
|
+
ctx.write_event_to_stream(event)
|
|
494
|
+
return event
|
|
492
495
|
|
|
493
496
|
# ========================================================================
|
|
494
497
|
# Manager/Executor Workflow Steps
|
|
@@ -506,10 +509,12 @@ class DroidAgent(Workflow):
|
|
|
506
509
|
"""
|
|
507
510
|
if self.shared_state.step_number >= self.config.agent.max_steps:
|
|
508
511
|
logger.warning(f"⚠️ Reached maximum steps ({self.config.agent.max_steps})")
|
|
509
|
-
|
|
512
|
+
event = FinalizeEvent(
|
|
510
513
|
success=False,
|
|
511
514
|
reason=f"Reached maximum steps ({self.config.agent.max_steps})",
|
|
512
515
|
)
|
|
516
|
+
ctx.write_event_to_stream(event)
|
|
517
|
+
return event
|
|
513
518
|
|
|
514
519
|
logger.info(
|
|
515
520
|
f"📋 Running Manager for planning... (step {self.shared_state.step_number}/{self.config.agent.max_steps})"
|
|
@@ -525,12 +530,15 @@ class DroidAgent(Workflow):
|
|
|
525
530
|
result = await handler
|
|
526
531
|
|
|
527
532
|
# Manager already updated shared_state, just return event with results
|
|
528
|
-
|
|
533
|
+
event = ManagerPlanEvent(
|
|
529
534
|
plan=result["plan"],
|
|
530
535
|
current_subgoal=result["current_subgoal"],
|
|
531
536
|
thought=result["thought"],
|
|
532
537
|
manager_answer=result.get("manager_answer", ""),
|
|
538
|
+
success=result.get("success"),
|
|
533
539
|
)
|
|
540
|
+
ctx.write_event_to_stream(event)
|
|
541
|
+
return event
|
|
534
542
|
|
|
535
543
|
@step
|
|
536
544
|
async def handle_manager_plan(
|
|
@@ -543,10 +551,16 @@ class DroidAgent(Workflow):
|
|
|
543
551
|
"""
|
|
544
552
|
# Check for answer-type termination
|
|
545
553
|
if ev.manager_answer.strip():
|
|
546
|
-
|
|
554
|
+
# Use success field from manager, default to True if not set for backward compatibility
|
|
555
|
+
success = ev.success if ev.success is not None else True
|
|
556
|
+
logger.info(
|
|
557
|
+
f"💬 Manager provided answer (success={success}): {ev.manager_answer}"
|
|
558
|
+
)
|
|
547
559
|
self.shared_state.progress_status = f"Answer: {ev.manager_answer}"
|
|
548
560
|
|
|
549
|
-
|
|
561
|
+
event = FinalizeEvent(success=success, reason=ev.manager_answer)
|
|
562
|
+
ctx.write_event_to_stream(event)
|
|
563
|
+
return event
|
|
550
564
|
|
|
551
565
|
# Check for <script> tag in current_subgoal, then extract from full plan
|
|
552
566
|
if "<script>" in ev.current_subgoal:
|
|
@@ -558,7 +572,9 @@ class DroidAgent(Workflow):
|
|
|
558
572
|
# Extract content between first <script> and first </script> in plan
|
|
559
573
|
task = ev.plan[start_idx + len("<script>") : end_idx].strip()
|
|
560
574
|
logger.info(f"🐍 Routing to ScripterAgent: {task[:80]}...")
|
|
561
|
-
|
|
575
|
+
event = ScripterExecutorInputEvent(task=task)
|
|
576
|
+
ctx.write_event_to_stream(event)
|
|
577
|
+
return event
|
|
562
578
|
else:
|
|
563
579
|
# <script> found in subgoal but not properly closed in plan - log warning
|
|
564
580
|
logger.warning(
|
|
@@ -567,7 +583,9 @@ class DroidAgent(Workflow):
|
|
|
567
583
|
|
|
568
584
|
# Continue to Executor with current subgoal
|
|
569
585
|
logger.info(f"▶️ Proceeding to Executor with subgoal: {ev.current_subgoal}")
|
|
570
|
-
|
|
586
|
+
event = ExecutorInputEvent(current_subgoal=ev.current_subgoal)
|
|
587
|
+
ctx.write_event_to_stream(event)
|
|
588
|
+
return event
|
|
571
589
|
|
|
572
590
|
@step
|
|
573
591
|
async def run_executor(
|
|
@@ -599,12 +617,14 @@ class DroidAgent(Workflow):
|
|
|
599
617
|
self.shared_state.last_action_thought = result.get("thought", "")
|
|
600
618
|
self.shared_state.action_pool.append(result["action_json"])
|
|
601
619
|
|
|
602
|
-
|
|
620
|
+
event = ExecutorResultEvent(
|
|
603
621
|
action=result["action"],
|
|
604
622
|
outcome=result["outcome"],
|
|
605
623
|
error=result["error"],
|
|
606
624
|
summary=result["summary"],
|
|
607
625
|
)
|
|
626
|
+
ctx.write_event_to_stream(event)
|
|
627
|
+
return event
|
|
608
628
|
|
|
609
629
|
@step
|
|
610
630
|
async def handle_executor_result(
|
|
@@ -635,7 +655,9 @@ class DroidAgent(Workflow):
|
|
|
635
655
|
f"🔄 Step {self.shared_state.step_number}/{self.config.agent.max_steps} complete, looping to Manager"
|
|
636
656
|
)
|
|
637
657
|
|
|
638
|
-
|
|
658
|
+
event = ManagerInputEvent()
|
|
659
|
+
ctx.write_event_to_stream(event)
|
|
660
|
+
return event
|
|
639
661
|
|
|
640
662
|
# ========================================================================
|
|
641
663
|
# Script Executor Workflow Steps
|
|
@@ -682,12 +704,14 @@ class DroidAgent(Workflow):
|
|
|
682
704
|
|
|
683
705
|
logger.info(f"🐍 ScripterAgent finished: {result['message'][:2000]}...")
|
|
684
706
|
|
|
685
|
-
|
|
707
|
+
event = ScripterExecutorResultEvent(
|
|
686
708
|
task=ev.task,
|
|
687
709
|
message=result["message"],
|
|
688
710
|
success=result["success"],
|
|
689
711
|
code_executions=result.get("code_executions", 0),
|
|
690
712
|
)
|
|
713
|
+
ctx.write_event_to_stream(event)
|
|
714
|
+
return event
|
|
691
715
|
|
|
692
716
|
@step
|
|
693
717
|
async def handle_scripter_result(
|
|
@@ -710,7 +734,9 @@ class DroidAgent(Workflow):
|
|
|
710
734
|
)
|
|
711
735
|
|
|
712
736
|
# Loop back to Manager (script result in shared_state)
|
|
713
|
-
|
|
737
|
+
event = ManagerInputEvent()
|
|
738
|
+
ctx.write_event_to_stream(event)
|
|
739
|
+
return event
|
|
714
740
|
|
|
715
741
|
# ========================================================================
|
|
716
742
|
# End Manager/Executor/Script Workflow Steps
|
|
@@ -751,7 +777,7 @@ class DroidAgent(Workflow):
|
|
|
751
777
|
timeout=self.timeout,
|
|
752
778
|
)
|
|
753
779
|
|
|
754
|
-
handler =
|
|
780
|
+
handler = structured_agent.run()
|
|
755
781
|
|
|
756
782
|
# Stream nested events
|
|
757
783
|
async for nested_ev in handler.stream_events():
|
|
@@ -782,10 +808,6 @@ class DroidAgent(Workflow):
|
|
|
782
808
|
return result
|
|
783
809
|
|
|
784
810
|
def handle_stream_event(self, ev: Event, ctx: Context):
|
|
785
|
-
if isinstance(ev, EpisodicMemoryEvent):
|
|
786
|
-
self.current_episodic_memory = ev.episodic_memory
|
|
787
|
-
return
|
|
788
|
-
|
|
789
811
|
if not isinstance(ev, StopEvent):
|
|
790
812
|
ctx.write_event_to_stream(ev)
|
|
791
813
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DroidAgent coordination events.
|
|
3
|
+
|
|
4
|
+
These events are used for WORKFLOW COORDINATION between DroidAgent and its child agents.
|
|
5
|
+
They carry minimal data needed for routing workflow steps.
|
|
6
|
+
|
|
7
|
+
For internal events with full debugging metadata, see:
|
|
8
|
+
- manager/events.py (ManagerInternalPlanEvent)
|
|
9
|
+
- executor/events.py (ExecutorInternalActionEvent, ExecutorInternalResultEvent)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Dict
|
|
13
|
+
|
|
14
|
+
from llama_index.core.workflow import Event, StopEvent
|
|
15
|
+
from pydantic import BaseModel
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CodeActExecuteEvent(Event):
|
|
19
|
+
instruction: str
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CodeActResultEvent(Event):
|
|
23
|
+
success: bool
|
|
24
|
+
reason: str
|
|
25
|
+
instruction: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FinalizeEvent(Event):
|
|
29
|
+
success: bool
|
|
30
|
+
reason: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ResultEvent(StopEvent):
|
|
34
|
+
"""
|
|
35
|
+
DroidAgent final result event.
|
|
36
|
+
|
|
37
|
+
Returned by DroidAgent.run() with attributes:
|
|
38
|
+
- success: Whether the task completed successfully
|
|
39
|
+
- reason: Explanation of the result or error message
|
|
40
|
+
- steps: Number of steps taken
|
|
41
|
+
- structured_output: Extracted structured data (if output_model was provided)
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
success: bool
|
|
45
|
+
reason: str
|
|
46
|
+
steps: int
|
|
47
|
+
structured_output: BaseModel | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TaskRunnerEvent(Event):
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ============================================================================
|
|
55
|
+
# Manager/Executor coordination events
|
|
56
|
+
# ============================================================================
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ManagerInputEvent(Event):
|
|
60
|
+
"""Trigger Manager workflow for planning"""
|
|
61
|
+
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ManagerPlanEvent(Event):
|
|
66
|
+
"""
|
|
67
|
+
Coordination event from ManagerAgent to DroidAgent.
|
|
68
|
+
|
|
69
|
+
Used for workflow step routing only (NOT streamed to frontend).
|
|
70
|
+
For internal events with memory_update metadata, see ManagerInternalPlanEvent.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
plan: str
|
|
74
|
+
current_subgoal: str
|
|
75
|
+
thought: str
|
|
76
|
+
manager_answer: str = ""
|
|
77
|
+
success: bool | None = (
|
|
78
|
+
None # True/False if task complete, None if still in progress
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class ExecutorInputEvent(Event):
|
|
83
|
+
"""Trigger Executor workflow for action execution"""
|
|
84
|
+
|
|
85
|
+
current_subgoal: str
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ExecutorResultEvent(Event):
|
|
89
|
+
"""
|
|
90
|
+
Coordination event from ExecutorAgent to DroidAgent.
|
|
91
|
+
|
|
92
|
+
Used for workflow step routing only (NOT streamed to frontend).
|
|
93
|
+
For internal events with thought/action_json metadata, see ExecutorInternalResultEvent.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
action: Dict
|
|
97
|
+
outcome: bool
|
|
98
|
+
error: str
|
|
99
|
+
summary: str
|
|
100
|
+
full_response: str = ""
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ============================================================================
|
|
104
|
+
# Script executor coordination events
|
|
105
|
+
# ============================================================================
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class ScripterExecutorInputEvent(Event):
|
|
109
|
+
"""Trigger ScripterAgent workflow for off-device operations"""
|
|
110
|
+
|
|
111
|
+
task: str
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ScripterExecutorResultEvent(Event):
|
|
115
|
+
"""
|
|
116
|
+
Coordination event from ScripterAgent to DroidAgent.
|
|
117
|
+
|
|
118
|
+
Used for workflow step routing only (NOT streamed to frontend).
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
task: str
|
|
122
|
+
message: str # Response from response() function
|
|
123
|
+
success: bool
|
|
124
|
+
code_executions: int
|