agentexec 0.1.2__tar.gz → 0.1.3__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.
Files changed (124) hide show
  1. agentexec-0.1.3/.github/workflows/docker-publish.yml +65 -0
  2. agentexec-0.1.3/.github/workflows/npm-publish.yml +48 -0
  3. agentexec-0.1.3/CHANGELOG.md +171 -0
  4. {agentexec-0.1.2 → agentexec-0.1.3}/PKG-INFO +47 -2
  5. {agentexec-0.1.2 → agentexec-0.1.3}/README.md +46 -1
  6. agentexec-0.1.3/docker/Dockerfile +77 -0
  7. agentexec-0.1.3/docker/README.md +149 -0
  8. agentexec-0.1.3/docker/entrypoint.py +78 -0
  9. agentexec-0.1.3/docs/api-reference/activity.md +455 -0
  10. agentexec-0.1.3/docs/api-reference/core.md +476 -0
  11. agentexec-0.1.3/docs/api-reference/pipeline.md +475 -0
  12. agentexec-0.1.3/docs/api-reference/runner.md +430 -0
  13. agentexec-0.1.3/docs/concepts/activity-tracking.md +520 -0
  14. agentexec-0.1.3/docs/concepts/architecture.md +344 -0
  15. agentexec-0.1.3/docs/concepts/task-lifecycle.md +435 -0
  16. agentexec-0.1.3/docs/concepts/worker-pool.md +499 -0
  17. agentexec-0.1.3/docs/contributing.md +341 -0
  18. agentexec-0.1.3/docs/deployment/docker.md +557 -0
  19. agentexec-0.1.3/docs/deployment/production.md +597 -0
  20. agentexec-0.1.3/docs/getting-started/configuration.md +295 -0
  21. agentexec-0.1.3/docs/getting-started/installation.md +34 -0
  22. agentexec-0.1.3/docs/getting-started/quickstart.md +262 -0
  23. agentexec-0.1.3/docs/guides/basic-usage.md +437 -0
  24. agentexec-0.1.3/docs/guides/custom-runners.md +595 -0
  25. agentexec-0.1.3/docs/guides/fastapi-integration.md +301 -0
  26. agentexec-0.1.3/docs/guides/openai-runner.md +468 -0
  27. agentexec-0.1.3/docs/guides/pipelines.md +553 -0
  28. agentexec-0.1.3/docs/index.md +129 -0
  29. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/README.md +45 -1
  30. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/pipeline.py +1 -1
  31. agentexec-0.1.3/examples/openai-agents-fastapi/ui/.gitignore +3 -0
  32. agentexec-0.1.3/examples/openai-agents-fastapi/ui/bun.lock +418 -0
  33. agentexec-0.1.3/examples/openai-agents-fastapi/ui/index.html +13 -0
  34. agentexec-0.1.3/examples/openai-agents-fastapi/ui/package.json +27 -0
  35. agentexec-0.1.3/examples/openai-agents-fastapi/ui/public/vite.svg +4 -0
  36. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/App.tsx +35 -0
  37. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/api/agents.ts +37 -0
  38. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/api/queries.ts +51 -0
  39. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/components/Layout.tsx +38 -0
  40. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/index.css +263 -0
  41. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/main.tsx +10 -0
  42. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/pages/AgentDetailPage.tsx +45 -0
  43. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/pages/AgentListPage.tsx +68 -0
  44. agentexec-0.1.3/examples/openai-agents-fastapi/ui/src/styles/github-dark.css +617 -0
  45. agentexec-0.1.3/examples/openai-agents-fastapi/ui/tsconfig.json +21 -0
  46. agentexec-0.1.3/examples/openai-agents-fastapi/ui/tsconfig.node.json +11 -0
  47. agentexec-0.1.3/examples/openai-agents-fastapi/ui/vite.config.ts +19 -0
  48. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/views.py +19 -0
  49. {agentexec-0.1.2 → agentexec-0.1.3}/pyproject.toml +1 -1
  50. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/__init__.py +2 -2
  51. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/activity/__init__.py +2 -0
  52. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/activity/models.py +39 -0
  53. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/activity/tracker.py +12 -0
  54. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/config.py +12 -0
  55. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/core/queue.py +13 -16
  56. agentexec-0.1.3/src/agentexec/core/results.py +64 -0
  57. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/core/task.py +58 -22
  58. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/pipeline.py +4 -8
  59. agentexec-0.1.3/src/agentexec/state/__init__.py +214 -0
  60. agentexec-0.1.3/src/agentexec/state/backend.py +210 -0
  61. agentexec-0.1.3/src/agentexec/state/redis_backend.py +352 -0
  62. agentexec-0.1.3/src/agentexec/worker/event.py +48 -0
  63. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/worker/logging.py +9 -10
  64. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/worker/pool.py +25 -24
  65. agentexec-0.1.3/tests/test_activity_schemas.py +224 -0
  66. agentexec-0.1.3/tests/test_activity_tracking.py +354 -0
  67. agentexec-0.1.3/tests/test_config.py +204 -0
  68. agentexec-0.1.3/tests/test_db.py +134 -0
  69. agentexec-0.1.3/tests/test_pipeline.py +270 -0
  70. {agentexec-0.1.2 → agentexec-0.1.3}/tests/test_public_api.py +0 -17
  71. agentexec-0.1.3/tests/test_queue.py +209 -0
  72. agentexec-0.1.3/tests/test_results.py +172 -0
  73. agentexec-0.1.3/tests/test_runners.py +573 -0
  74. agentexec-0.1.3/tests/test_self_describing_results.py +126 -0
  75. agentexec-0.1.3/tests/test_state.py +185 -0
  76. agentexec-0.1.3/tests/test_state_backend.py +272 -0
  77. agentexec-0.1.3/tests/test_task.py +319 -0
  78. agentexec-0.1.3/tests/test_worker_event.py +133 -0
  79. agentexec-0.1.3/tests/test_worker_logging.py +280 -0
  80. {agentexec-0.1.2 → agentexec-0.1.3}/tests/test_worker_pool.py +122 -26
  81. agentexec-0.1.3/ui/.gitignore +3 -0
  82. agentexec-0.1.3/ui/README.md +148 -0
  83. agentexec-0.1.3/ui/bun.lock +397 -0
  84. agentexec-0.1.3/ui/package.json +52 -0
  85. agentexec-0.1.3/ui/src/components/ActiveAgentsBadge.tsx +20 -0
  86. agentexec-0.1.3/ui/src/components/ProgressBar.tsx +24 -0
  87. agentexec-0.1.3/ui/src/components/StatusBadge.tsx +42 -0
  88. agentexec-0.1.3/ui/src/components/TaskDetail.tsx +121 -0
  89. agentexec-0.1.3/ui/src/components/TaskList.tsx +119 -0
  90. agentexec-0.1.3/ui/src/components/index.ts +5 -0
  91. agentexec-0.1.3/ui/src/index.ts +23 -0
  92. agentexec-0.1.3/ui/src/types.ts +59 -0
  93. agentexec-0.1.3/ui/tsconfig.json +24 -0
  94. agentexec-0.1.3/ui/vite.config.ts +34 -0
  95. agentexec-0.1.2/CHANGELOG.md +0 -82
  96. agentexec-0.1.2/src/agentexec/core/redis_client.py +0 -71
  97. agentexec-0.1.2/src/agentexec/core/results.py +0 -62
  98. agentexec-0.1.2/src/agentexec/worker/event.py +0 -43
  99. agentexec-0.1.2/tests/test_activity_tracking.py +0 -89
  100. agentexec-0.1.2/tests/test_redis_client.py +0 -63
  101. agentexec-0.1.2/tests/test_task.py +0 -169
  102. {agentexec-0.1.2 → agentexec-0.1.3}/.github/workflows/publish.yml +0 -0
  103. {agentexec-0.1.2 → agentexec-0.1.3}/.gitignore +0 -0
  104. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/alembic/README +0 -0
  105. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/alembic/env.py +0 -0
  106. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/alembic/script.py.mako +0 -0
  107. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/alembic.ini +0 -0
  108. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/compose.yml +0 -0
  109. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/context.py +0 -0
  110. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/db.py +0 -0
  111. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/main.py +0 -0
  112. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/models.py +0 -0
  113. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/pyproject.toml +0 -0
  114. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/tools.py +0 -0
  115. {agentexec-0.1.2 → agentexec-0.1.3}/examples/openai-agents-fastapi/worker.py +0 -0
  116. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/activity/schemas.py +0 -0
  117. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/core/__init__.py +0 -0
  118. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/core/db.py +0 -0
  119. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/core/logging.py +0 -0
  120. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/runners/__init__.py +0 -0
  121. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/runners/base.py +0 -0
  122. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/runners/openai.py +0 -0
  123. {agentexec-0.1.2 → agentexec-0.1.3}/src/agentexec/worker/__init__.py +0 -0
  124. {agentexec-0.1.2 → agentexec-0.1.3}/tests/test_activity_tracking.py.bak +0 -0
@@ -0,0 +1,65 @@
1
+ name: Publish Docker Image
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ # Allow manual trigger for testing
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag:
10
+ description: 'Image tag (defaults to "dev")'
11
+ required: false
12
+ default: 'dev'
13
+
14
+ env:
15
+ REGISTRY: ghcr.io
16
+ IMAGE_NAME: agent-ci/agentexec-worker
17
+
18
+ permissions:
19
+ contents: read
20
+ packages: write
21
+
22
+ jobs:
23
+ build-and-push:
24
+ runs-on: ubuntu-latest
25
+
26
+ steps:
27
+ - name: Checkout repository
28
+ uses: actions/checkout@v4
29
+
30
+ - name: Set up Docker Buildx
31
+ uses: docker/setup-buildx-action@v3
32
+
33
+ - name: Log in to Container Registry
34
+ uses: docker/login-action@v3
35
+ with:
36
+ registry: ${{ env.REGISTRY }}
37
+ username: ${{ github.actor }}
38
+ password: ${{ secrets.GITHUB_TOKEN }}
39
+
40
+ - name: Extract metadata for Docker
41
+ id: meta
42
+ uses: docker/metadata-action@v5
43
+ with:
44
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
45
+ tags: |
46
+ # Tag with version on release (e.g., v0.1.2 -> 0.1.2)
47
+ type=semver,pattern={{version}}
48
+ # Tag with major.minor on release (e.g., v0.1.2 -> 0.1)
49
+ type=semver,pattern={{major}}.{{minor}}
50
+ # Tag as "latest" on release
51
+ type=raw,value=latest,enable=${{ github.event_name == 'release' }}
52
+ # Tag with input value on manual dispatch
53
+ type=raw,value=${{ inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }}
54
+
55
+ - name: Build and push Docker image
56
+ uses: docker/build-push-action@v5
57
+ with:
58
+ context: ./docker
59
+ file: ./docker/Dockerfile
60
+ push: true
61
+ tags: ${{ steps.meta.outputs.tags }}
62
+ labels: ${{ steps.meta.outputs.labels }}
63
+ cache-from: type=gha
64
+ cache-to: type=gha,mode=max
65
+ platforms: linux/amd64,linux/arm64
@@ -0,0 +1,48 @@
1
+ name: Publish agentexec-ui to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ version:
9
+ description: 'Version to publish (leave empty to use package.json version)'
10
+ required: false
11
+ type: string
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ publish:
18
+ # Only run for releases tagged with ui-v* or manual triggers
19
+ if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/ui-v')
20
+ runs-on: ubuntu-latest
21
+
22
+ defaults:
23
+ run:
24
+ working-directory: ui
25
+
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+
29
+ - name: Setup Node.js
30
+ uses: actions/setup-node@v4
31
+ with:
32
+ node-version: '20'
33
+ registry-url: 'https://registry.npmjs.org'
34
+
35
+ - name: Install dependencies
36
+ run: npm install
37
+
38
+ - name: Update version (if specified)
39
+ if: inputs.version != ''
40
+ run: npm version ${{ inputs.version }} --no-git-tag-version
41
+
42
+ - name: Build package
43
+ run: npm run build
44
+
45
+ - name: Publish to npm
46
+ run: npm publish --access public
47
+ env:
48
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,171 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ### Breaking Changes
6
+
7
+ **Self-describing JSON serialization replaces pickle**
8
+ - Task results now use JSON serialization with embedded type information (similar to pickle)
9
+ - Automatically stores fully qualified class name with data for type reconstruction
10
+ - No longer requires `TaskDefinition` registry for result deserialization
11
+ - `ax.gather()` now works with tasks created via `ax.enqueue()` without pool context
12
+ - **Migration**: Clear Redis or wait for TTL expiry on old pickled results
13
+
14
+ **TaskHandler Protocol enforces BaseModel returns**
15
+ - Task handlers must return a Pydantic `BaseModel` instance (not `None` or arbitrary objects)
16
+ - Return type is automatically inferred and validated at registration time
17
+ - Enables type-safe result retrieval and automatic serialization
18
+
19
+ ### New Features
20
+
21
+ **State backend abstraction**
22
+ - Introduced `StateBackend` Protocol for pluggable state storage implementations
23
+ - Current Redis implementation moved to `agentexec.state.redis_backend`
24
+ - Backend modules verified against protocol at import time via `cast()`
25
+ - Prepares foundation for alternative backends (in-memory, DynamoDB, etc.)
26
+
27
+ **Improved async patterns**
28
+ - `brpop()` is now a proper async function (was sync returning coroutine)
29
+ - Consistent async/await usage across state operations
30
+ - Better type hints and IDE support
31
+
32
+ **Enhanced type safety**
33
+ - `TaskHandler` Protocol with support for both sync and async handlers
34
+ - Proper type annotations for all state backend operations
35
+ - `serialize()` and `deserialize()` type-enforced for `BaseModel` only
36
+
37
+ ### Documentation
38
+
39
+ **Comprehensive documentation added**
40
+ - API reference for core modules (activity, pipeline, runner, task)
41
+ - Conceptual guides (architecture, task lifecycle, worker pool)
42
+ - Deployment guides (Docker, production best practices)
43
+ - Usage guides (basic usage, pipelines, FastAPI integration, OpenAI runner)
44
+ - Getting started (installation, quickstart, configuration)
45
+ - Contributing guide
46
+
47
+ ### UI & Tooling
48
+
49
+ **React frontend and component library**
50
+ - Added `agentexec-ui` npm package with reusable React components
51
+ - Pre-built UI for agent monitoring and activity tracking
52
+ - TanStack Query integration for real-time updates
53
+ - React Router for navigation between agent list and detail views
54
+
55
+ **Docker deployment**
56
+ - Docker worker image for containerized deployments
57
+ - GitHub Actions for automated Docker image publishing to GitHub Container Registry
58
+ - GitHub Actions for automated npm publishing of UI components
59
+
60
+ ### Testing
61
+
62
+ **Comprehensive test coverage**
63
+ - Achieved 89% code coverage
64
+ - Added unit tests for all core modules:
65
+ - State backend and serialization (`test_state.py`, `test_state_backend.py`)
66
+ - Self-describing results (`test_self_describing_results.py`)
67
+ - Activity tracking schemas (`test_activity_schemas.py`)
68
+ - Pipeline orchestration (`test_pipeline.py`)
69
+ - Task queue operations (`test_queue.py`)
70
+ - Worker events and logging (`test_worker_event.py`, `test_worker_logging.py`)
71
+ - Database operations (`test_db.py`)
72
+ - Configuration (`test_config.py`)
73
+
74
+ ### Internal Improvements
75
+
76
+ **Redis client refactoring**
77
+ - Removed `core/redis_client.py` in favor of state backend abstraction
78
+ - Lazy connection initialization for both async and sync Redis clients
79
+ - Proper connection cleanup in `backend.close()`
80
+
81
+ **Key formatting consistency**
82
+ - All state keys use consistent `agentexec:` prefix via `backend.format_key()`
83
+ - Results: `agentexec:result:{agent_id}`
84
+ - Events: `agentexec:event:{name}:{id}`
85
+ - Logs channel: `agentexec:logs`
86
+
87
+ **Standardized function signatures**
88
+ - `get_result()` and `gather()` return `BaseModel` directly (not JSON strings)
89
+ - Consistent parameter ordering across state module functions
90
+ - Better docstrings with type information
91
+
92
+ ## v0.1.2
93
+
94
+ ### New Features
95
+
96
+ **Pipelines**
97
+ - Multi-step workflow orchestration with `ax.Pipeline`
98
+ - Define steps with `@pipeline.step(order)` decorator
99
+ - Parallel task execution with `ax.gather()`
100
+ - Result retrieval with `ax.get_result()`
101
+
102
+ **Worker logging via Redis pubsub**
103
+ - Workers publish logs to Redis, collected by main process
104
+ - Use `pool.run()` to see worker logs in real-time
105
+
106
+ ### Internal Improvements
107
+
108
+ **Reorganized worker module**
109
+ - Worker code moved to `agentexec.worker` subpackage
110
+ - `RedisEvent` for cross-process shutdown coordination
111
+ - `get_worker_logger()` configures logging and returns logger in one call
112
+
113
+ **Refactored Redis client usage**
114
+ - Added `get_redis_sync()` for synchronous Redis operations
115
+ - Sync/async Redis clients for different contexts
116
+
117
+ ## v0.1.1
118
+
119
+ ### Breaking Changes
120
+
121
+ **Async `enqueue()` function**
122
+ - `ax.enqueue()` is now async and must be awaited:
123
+ ```python
124
+ task = await ax.enqueue("task_name", MyContext(key="value"))
125
+ ```
126
+
127
+ **Type-safe context with Pydantic BaseModel**
128
+ - Task context must be a Pydantic `BaseModel` instead of a raw `dict`
129
+ - Context class is automatically inferred from handler type hints:
130
+ ```python
131
+ class ResearchContext(BaseModel):
132
+ company: str
133
+
134
+ @pool.task("research")
135
+ async def research(agent_id: UUID, context: ResearchContext):
136
+ company = context.company # Type-safe with IDE autocomplete
137
+ ```
138
+
139
+ **Redis URL now required**
140
+ - `redis_url` defaults to `None` and must be explicitly configured via `REDIS_URL`
141
+ - Prevents accidental connections to wrong Redis instances
142
+
143
+ ### New Features
144
+
145
+ **Configurable activity messages**
146
+ - Activity status messages are configurable via environment variables:
147
+ ```bash
148
+ AGENTEXEC_ACTIVITY_MESSAGE_CREATE="Waiting to start."
149
+ AGENTEXEC_ACTIVITY_MESSAGE_STARTED="Task started."
150
+ AGENTEXEC_ACTIVITY_MESSAGE_COMPLETE="Task completed successfully."
151
+ AGENTEXEC_ACTIVITY_MESSAGE_ERROR="Task failed with error: {error}"
152
+ ```
153
+
154
+ **Improved Task architecture**
155
+ - `Task` is now the primary execution object with `execute()` method
156
+ - `TaskDefinition` handles registration metadata and context class inference
157
+ - Full lifecycle management (QUEUED → RUNNING → COMPLETE/ERROR) encapsulated in `Task.execute()`
158
+
159
+ **Better SQLAlchemy session management**
160
+ - New `scoped_session` pattern for worker processes
161
+ - Proper session cleanup on worker shutdown
162
+
163
+ ### Internal Improvements
164
+
165
+ - Switched to async Redis client (`redis.asyncio`)
166
+ - Consolidated cleanup code in worker `_run()` method
167
+ - Removed unused `debug` config option
168
+
169
+ ## v0.1.0
170
+
171
+ Initial release.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentexec
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Production-ready orchestration for OpenAI Agents with Redis-backed coordination, activity tracking, and workflow management
5
5
  Project-URL: Homepage, https://github.com/Agent-CI/agentexec
6
6
  Project-URL: Documentation, https://github.com/Agent-CI/agentexec#readme
@@ -25,6 +25,8 @@ Description-Content-Type: text/markdown
25
25
 
26
26
  # `agentexec`
27
27
 
28
+ [![codecov](https://codecov.io/gh/Agent-CI/agentexec/branch/main/graph/badge.svg)](https://codecov.io/gh/Agent-CI/agentexec)
29
+
28
30
  **Production-ready orchestration for OpenAI Agents SDK** with Redis-backed task queues, SQLAlchemy activity tracking, and multiprocessing worker pools.
29
31
 
30
32
  Build reliable, scalable AI agent applications with automatic lifecycle management, progress tracking, and fault tolerance.
@@ -243,7 +245,7 @@ class MyPipeline(pipeline.Base):
243
245
  async def analyze(self, brand_result, market_result):
244
246
  """Combine results from previous step."""
245
247
  task = await ax.enqueue("analyze", AnalysisContext(...))
246
- return await ax.get_result(task.agent_id)
248
+ return await ax.get_result(task)
247
249
 
248
250
 
249
251
  # Run the pipeline
@@ -394,6 +396,49 @@ AgentExec creates two tables (prefix configurable):
394
396
 
395
397
  ---
396
398
 
399
+ ## Docker Deployment
400
+
401
+ Deploy workers using the official Docker image:
402
+
403
+ ### 1. Create your worker Dockerfile
404
+
405
+ ```dockerfile
406
+ FROM ghcr.io/agent-ci/agentexec-worker:latest
407
+
408
+ COPY ./src /app/src
409
+ ENV AGENTEXEC_WORKER_MODULE=src.worker
410
+ ```
411
+
412
+ ### 2. Create your worker module
413
+
414
+ ```python
415
+ # src/worker.py
416
+ import os
417
+ import agentexec as ax
418
+
419
+ pool = ax.WorkerPool(database_url=os.environ["DATABASE_URL"])
420
+
421
+ @pool.task("my_task")
422
+ async def my_task(agent_id, context):
423
+ # Your task implementation
424
+ pass
425
+ ```
426
+
427
+ ### 3. Run with Docker
428
+
429
+ ```bash
430
+ docker build -t my-worker .
431
+ docker run \
432
+ -e DATABASE_URL=postgresql://... \
433
+ -e REDIS_URL=redis://... \
434
+ -e OPENAI_API_KEY=sk-... \
435
+ my-worker
436
+ ```
437
+
438
+ See **[docker/README.md](docker/README.md)** for full documentation including Docker Compose examples.
439
+
440
+ ---
441
+
397
442
  ## Development
398
443
 
399
444
  ```bash
@@ -1,5 +1,7 @@
1
1
  # `agentexec`
2
2
 
3
+ [![codecov](https://codecov.io/gh/Agent-CI/agentexec/branch/main/graph/badge.svg)](https://codecov.io/gh/Agent-CI/agentexec)
4
+
3
5
  **Production-ready orchestration for OpenAI Agents SDK** with Redis-backed task queues, SQLAlchemy activity tracking, and multiprocessing worker pools.
4
6
 
5
7
  Build reliable, scalable AI agent applications with automatic lifecycle management, progress tracking, and fault tolerance.
@@ -218,7 +220,7 @@ class MyPipeline(pipeline.Base):
218
220
  async def analyze(self, brand_result, market_result):
219
221
  """Combine results from previous step."""
220
222
  task = await ax.enqueue("analyze", AnalysisContext(...))
221
- return await ax.get_result(task.agent_id)
223
+ return await ax.get_result(task)
222
224
 
223
225
 
224
226
  # Run the pipeline
@@ -369,6 +371,49 @@ AgentExec creates two tables (prefix configurable):
369
371
 
370
372
  ---
371
373
 
374
+ ## Docker Deployment
375
+
376
+ Deploy workers using the official Docker image:
377
+
378
+ ### 1. Create your worker Dockerfile
379
+
380
+ ```dockerfile
381
+ FROM ghcr.io/agent-ci/agentexec-worker:latest
382
+
383
+ COPY ./src /app/src
384
+ ENV AGENTEXEC_WORKER_MODULE=src.worker
385
+ ```
386
+
387
+ ### 2. Create your worker module
388
+
389
+ ```python
390
+ # src/worker.py
391
+ import os
392
+ import agentexec as ax
393
+
394
+ pool = ax.WorkerPool(database_url=os.environ["DATABASE_URL"])
395
+
396
+ @pool.task("my_task")
397
+ async def my_task(agent_id, context):
398
+ # Your task implementation
399
+ pass
400
+ ```
401
+
402
+ ### 3. Run with Docker
403
+
404
+ ```bash
405
+ docker build -t my-worker .
406
+ docker run \
407
+ -e DATABASE_URL=postgresql://... \
408
+ -e REDIS_URL=redis://... \
409
+ -e OPENAI_API_KEY=sk-... \
410
+ my-worker
411
+ ```
412
+
413
+ See **[docker/README.md](docker/README.md)** for full documentation including Docker Compose examples.
414
+
415
+ ---
416
+
372
417
  ## Development
373
418
 
374
419
  ```bash
@@ -0,0 +1,77 @@
1
+ # agentexec-worker base image
2
+ #
3
+ # This image provides the agentexec framework for running background workers.
4
+ # Users extend this image with their own task definitions.
5
+ #
6
+ # Usage:
7
+ # FROM ghcr.io/agent-ci/agentexec-worker:latest
8
+ # COPY ./src /app/src
9
+ # ENV AGENTEXEC_WORKER_MODULE=src.worker
10
+ #
11
+ # Required environment variables at runtime:
12
+ # DATABASE_URL - Database connection URL (e.g., postgresql://...)
13
+ # REDIS_URL - Redis connection URL (e.g., redis://...)
14
+ # AGENTEXEC_WORKER_MODULE - Python module path with pool definition
15
+ #
16
+ # Optional environment variables:
17
+ # OPENAI_API_KEY - Required if using OpenAI agents
18
+ # AGENTEXEC_NUM_WORKERS - Number of worker processes (default: 4)
19
+ # AGENTEXEC_QUEUE_NAME - Redis queue name (default: agentexec_tasks)
20
+
21
+ FROM python:3.11-slim AS base
22
+
23
+ # Prevent Python from writing pyc files and buffering stdout/stderr
24
+ ENV PYTHONDONTWRITEBYTECODE=1 \
25
+ PYTHONUNBUFFERED=1 \
26
+ # Ensure Python can find modules in /app
27
+ PYTHONPATH=/app
28
+
29
+ WORKDIR /app
30
+
31
+ # Install system dependencies for database drivers
32
+ RUN apt-get update && apt-get install -y --no-install-recommends \
33
+ # PostgreSQL client library (for psycopg2)
34
+ libpq5 \
35
+ && rm -rf /var/lib/apt/lists/*
36
+
37
+ # Build stage for compiling dependencies
38
+ FROM base AS builder
39
+
40
+ RUN apt-get update && apt-get install -y --no-install-recommends \
41
+ # Build tools
42
+ gcc \
43
+ # PostgreSQL dev headers (for psycopg2)
44
+ libpq-dev \
45
+ && rm -rf /var/lib/apt/lists/*
46
+
47
+ # Install pip dependencies
48
+ RUN pip install --no-cache-dir --upgrade pip
49
+
50
+ # Install agentexec with common database drivers
51
+ # Users can extend with additional drivers as needed
52
+ RUN pip install --no-cache-dir \
53
+ agentexec \
54
+ psycopg2-binary \
55
+ # For async PostgreSQL (optional, commonly used)
56
+ asyncpg
57
+
58
+ # Final stage
59
+ FROM base AS runtime
60
+
61
+ # Copy installed packages from builder
62
+ COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
63
+ COPY --from=builder /usr/local/bin /usr/local/bin
64
+
65
+ # Copy entrypoint script
66
+ COPY entrypoint.py /app/entrypoint.py
67
+
68
+ # Create non-root user for security
69
+ RUN useradd --create-home --shell /bin/bash worker
70
+ USER worker
71
+
72
+ # Health check - verify Python and agentexec are available
73
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
74
+ CMD python -c "import agentexec" || exit 1
75
+
76
+ # Default command runs the worker entrypoint
77
+ ENTRYPOINT ["python", "/app/entrypoint.py"]
@@ -0,0 +1,149 @@
1
+ # agentexec-worker Docker Image
2
+
3
+ Base Docker image for deploying agentexec workers.
4
+
5
+ ## Quick Start
6
+
7
+ ### 1. Create your worker module
8
+
9
+ ```python
10
+ # src/worker.py
11
+ import os
12
+ import agentexec as ax
13
+
14
+ pool = ax.WorkerPool(database_url=os.environ["DATABASE_URL"])
15
+
16
+ @pool.task("my_task")
17
+ async def my_task(agent_id, context):
18
+ # Your task implementation
19
+ pass
20
+ ```
21
+
22
+ ### 2. Create your Dockerfile
23
+
24
+ ```dockerfile
25
+ FROM ghcr.io/agent-ci/agentexec-worker:latest
26
+
27
+ # Copy your application code
28
+ COPY ./src /app/src
29
+
30
+ # Point to your worker module
31
+ ENV AGENTEXEC_WORKER_MODULE=src.worker
32
+ ```
33
+
34
+ ### 3. Build and run
35
+
36
+ ```bash
37
+ # Build your image
38
+ docker build -t my-worker .
39
+
40
+ # Run with required environment variables
41
+ docker run \
42
+ -e DATABASE_URL=postgresql://user:pass@host:5432/db \
43
+ -e REDIS_URL=redis://host:6379 \
44
+ -e OPENAI_API_KEY=sk-... \
45
+ my-worker
46
+ ```
47
+
48
+ ## Environment Variables
49
+
50
+ ### Required
51
+
52
+ | Variable | Description |
53
+ |----------|-------------|
54
+ | `DATABASE_URL` | Database connection URL |
55
+ | `REDIS_URL` | Redis connection URL |
56
+ | `AGENTEXEC_WORKER_MODULE` | Python module path containing `pool` |
57
+
58
+ ### Optional
59
+
60
+ | Variable | Default | Description |
61
+ |----------|---------|-------------|
62
+ | `OPENAI_API_KEY` | - | Required if using OpenAI agents |
63
+ | `AGENTEXEC_NUM_WORKERS` | 4 | Number of worker processes |
64
+ | `AGENTEXEC_QUEUE_NAME` | agentexec_tasks | Redis queue name |
65
+ | `AGENTEXEC_GRACEFUL_SHUTDOWN_TIMEOUT` | 300 | Shutdown timeout (seconds) |
66
+ | `AGENTEXEC_RESULT_TTL` | 3600 | Task result TTL (seconds) |
67
+
68
+ ## Worker Module Requirements
69
+
70
+ Your worker module must expose either:
71
+
72
+ 1. A `pool` variable (recommended):
73
+ ```python
74
+ pool = ax.WorkerPool(database_url=os.environ["DATABASE_URL"])
75
+ ```
76
+
77
+ 2. Or a `create_pool()` function:
78
+ ```python
79
+ def create_pool():
80
+ return ax.WorkerPool(database_url=os.environ["DATABASE_URL"])
81
+ ```
82
+
83
+ ## Docker Compose Example
84
+
85
+ ```yaml
86
+ version: '3.8'
87
+
88
+ services:
89
+ worker:
90
+ build: .
91
+ environment:
92
+ - DATABASE_URL=postgresql://postgres:postgres@db:5432/app
93
+ - REDIS_URL=redis://redis:6379
94
+ - OPENAI_API_KEY=${OPENAI_API_KEY}
95
+ - AGENTEXEC_NUM_WORKERS=2
96
+ depends_on:
97
+ - db
98
+ - redis
99
+
100
+ db:
101
+ image: postgres:15
102
+ environment:
103
+ POSTGRES_PASSWORD: postgres
104
+ POSTGRES_DB: app
105
+
106
+ redis:
107
+ image: redis:7-alpine
108
+ ```
109
+
110
+ ## Extending the Image
111
+
112
+ ### Adding Python dependencies
113
+
114
+ ```dockerfile
115
+ FROM ghcr.io/agent-ci/agentexec-worker:latest
116
+
117
+ # Install additional packages
118
+ RUN pip install --no-cache-dir \
119
+ httpx \
120
+ beautifulsoup4
121
+
122
+ COPY ./src /app/src
123
+ ENV AGENTEXEC_WORKER_MODULE=src.worker
124
+ ```
125
+
126
+ ### Using a different database
127
+
128
+ The base image includes `psycopg2-binary` for PostgreSQL. For other databases:
129
+
130
+ ```dockerfile
131
+ FROM ghcr.io/agent-ci/agentexec-worker:latest
132
+
133
+ # For MySQL
134
+ RUN pip install --no-cache-dir mysqlclient
135
+
136
+ # For SQLite (included in Python stdlib, but you may want async driver)
137
+ RUN pip install --no-cache-dir aiosqlite
138
+ ```
139
+
140
+ ## Building Locally
141
+
142
+ ```bash
143
+ cd docker
144
+ docker build -t agentexec-worker .
145
+ ```
146
+
147
+ ## Multi-Architecture Support
148
+
149
+ The published image supports both `linux/amd64` and `linux/arm64` architectures.