awf 1.0.0__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.
- awf-1.0.0/LICENSE +21 -0
- awf-1.0.0/PKG-INFO +189 -0
- awf-1.0.0/README.md +159 -0
- awf-1.0.0/awf/__init__.py +3 -0
- awf-1.0.0/awf/__main__.py +6 -0
- awf-1.0.0/awf/_atomic.py +37 -0
- awf-1.0.0/awf/_env.py +90 -0
- awf-1.0.0/awf/_log.py +24 -0
- awf-1.0.0/awf/agent_stage.py +275 -0
- awf-1.0.0/awf/api/__init__.py +128 -0
- awf-1.0.0/awf/api/_background.py +158 -0
- awf-1.0.0/awf/api/_errors.py +10 -0
- awf-1.0.0/awf/api/_helpers.py +71 -0
- awf-1.0.0/awf/api/_results.py +286 -0
- awf-1.0.0/awf/api/_stack.py +130 -0
- awf-1.0.0/awf/api/_templates.py +110 -0
- awf-1.0.0/awf/api/context.py +420 -0
- awf-1.0.0/awf/api/dashboard.py +909 -0
- awf-1.0.0/awf/api/dashboard_server.py +76 -0
- awf-1.0.0/awf/api/dispatch.py +182 -0
- awf-1.0.0/awf/api/lifecycle.py +683 -0
- awf-1.0.0/awf/api/model_check.py +246 -0
- awf-1.0.0/awf/api/pipeline.py +764 -0
- awf-1.0.0/awf/api/planning.py +95 -0
- awf-1.0.0/awf/api/roles.py +448 -0
- awf-1.0.0/awf/api/setup.py +453 -0
- awf-1.0.0/awf/api/wait_event.py +186 -0
- awf-1.0.0/awf/cli.py +232 -0
- awf-1.0.0/awf/cmd_add_role.py +42 -0
- awf-1.0.0/awf/cmd_analyze_roles.py +82 -0
- awf-1.0.0/awf/cmd_approve.py +24 -0
- awf-1.0.0/awf/cmd_baseline.py +40 -0
- awf-1.0.0/awf/cmd_init.py +218 -0
- awf-1.0.0/awf/cmd_report.py +56 -0
- awf-1.0.0/awf/cmd_reset.py +78 -0
- awf-1.0.0/awf/cmd_rollback.py +51 -0
- awf-1.0.0/awf/cmd_start.py +70 -0
- awf-1.0.0/awf/cmd_status.py +71 -0
- awf-1.0.0/awf/commit_gate.py +272 -0
- awf-1.0.0/awf/config.py +36 -0
- awf-1.0.0/awf/git_utils.py +81 -0
- awf-1.0.0/awf/opencode_agents.py +159 -0
- awf-1.0.0/awf/orchestrator.py +189 -0
- awf-1.0.0/awf/paths.py +73 -0
- awf-1.0.0/awf/phase.py +170 -0
- awf-1.0.0/awf/pipeline.py +153 -0
- awf-1.0.0/awf/pipeline_engine.py +583 -0
- awf-1.0.0/awf/pipeline_state.py +135 -0
- awf-1.0.0/awf/plan_checkpoint.py +605 -0
- awf-1.0.0/awf/plan_progress.py +172 -0
- awf-1.0.0/awf/signal_watch.py +203 -0
- awf-1.0.0/awf/signals.py +152 -0
- awf-1.0.0/awf/supervisor.py +907 -0
- awf-1.0.0/awf/templates/dashboard.html.j2 +420 -0
- awf-1.0.0/awf/templates/roles/supervisor/_core.md +44 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-brief.md +61 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-form.md +29 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-goal.md +25 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-init.md +17 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-normalize.md +35 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-run.md +17 -0
- awf-1.0.0/awf/templates/roles/supervisor/phase-verify.md +28 -0
- awf-1.0.0/awf/templates/roles/supervisor.md +633 -0
- awf-1.0.0/awf/todos.py +161 -0
- awf-1.0.0/awf/transitions.py +54 -0
- awf-1.0.0/awf/verify.py +202 -0
- awf-1.0.0/awf/xdg.py +43 -0
- awf-1.0.0/awf.egg-info/PKG-INFO +189 -0
- awf-1.0.0/awf.egg-info/SOURCES.txt +72 -0
- awf-1.0.0/awf.egg-info/dependency_links.txt +1 -0
- awf-1.0.0/awf.egg-info/requires.txt +8 -0
- awf-1.0.0/awf.egg-info/top_level.txt +1 -0
- awf-1.0.0/pyproject.toml +76 -0
- awf-1.0.0/setup.cfg +4 -0
awf-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EnerJize
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
awf-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: awf
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Agentic Workflow Framework — declarative multi-agent pipeline orchestrator for opencode
|
|
5
|
+
Author: EnerJize
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/EnerJizeIT/agentic-workflow
|
|
8
|
+
Project-URL: Repository, https://github.com/EnerJizeIT/agentic-workflow
|
|
9
|
+
Project-URL: Issues, https://github.com/EnerJizeIT/agentic-workflow/issues
|
|
10
|
+
Keywords: opencode,mcp,ai-agent,pipeline,multi-agent,orchestrator,workflow
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: PyYAML>=6.0
|
|
23
|
+
Requires-Dist: jinja2>=3.1
|
|
24
|
+
Requires-Dist: markdown>=3.4
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-timeout>=2.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# Agentic Workflow (awf)
|
|
32
|
+
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
[](https://www.python.org/downloads/)
|
|
35
|
+
[](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml)
|
|
36
|
+
|
|
37
|
+
> **Multi-agent pipeline orchestrator for opencode. Plan → build → verify → commit — through typed MCP tools, not bash.**
|
|
38
|
+
|
|
39
|
+
## The problem it solves
|
|
40
|
+
|
|
41
|
+
AI coding agents are powerful but chaotic. They jump straight to code without planning, skip review, leave bugs. You watch helplessly as tokens burn.
|
|
42
|
+
|
|
43
|
+
**awf** adds structure: a supervisor agent plans the work, worker agents execute through a pipeline you design (any roles, any depth — from a single worker to a multi-stage chain), and you approve each result before it commits. All through natural language — *"start working on the backlog"*, *"verify and approve"*, *"reject — the DOMParser fix is missing"*.
|
|
44
|
+
|
|
45
|
+
You stay in control. The agent stays on rails.
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Install
|
|
51
|
+
pip install -e .
|
|
52
|
+
pip install -e ./agent_workflow_ui
|
|
53
|
+
|
|
54
|
+
# 2. Configure opencode — add to ~/.config/opencode/opencode.json:
|
|
55
|
+
# {
|
|
56
|
+
# "mcp": {
|
|
57
|
+
# "agent-workflow-ui": {
|
|
58
|
+
# "type": "local",
|
|
59
|
+
# "command": ["python3", "-m", "agent_workflow_ui"],
|
|
60
|
+
# "enabled": true
|
|
61
|
+
# }
|
|
62
|
+
# }
|
|
63
|
+
# }
|
|
64
|
+
|
|
65
|
+
# 3. Run — just talk to opencode:
|
|
66
|
+
# "Initialize awf in my project"
|
|
67
|
+
# "Develop the MVP based on the backlog"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Requirements
|
|
71
|
+
|
|
72
|
+
| Component | Requirement |
|
|
73
|
+
|---|---|
|
|
74
|
+
| **Python** | 3.10+ |
|
|
75
|
+
| **opencode** | any recent version with MCP support |
|
|
76
|
+
| **OS** | Linux (tested), macOS (should work), Windows (untested) |
|
|
77
|
+
| **Models** | Model-agnostic. Tested with Qwen vLLM. Should work with Claude, GPT, or any opencode-supported provider. |
|
|
78
|
+
| **Git** | Required (commit gate, baselines, rollback) |
|
|
79
|
+
|
|
80
|
+
## Features
|
|
81
|
+
|
|
82
|
+
- 🎯 **State-Machine Orchestration (SMO)** — awf guides the supervisor through phases: `init → goal → form → normalize → brief → run → verify → done`. Every tool returns a `next_action` hint — even weak models follow the full flow without getting lost.
|
|
83
|
+
- 🔧 **29 MCP tools** — typed pipeline control: init, dispatch, start, approve, reject, rollback, dashboard, model validation. No bash, no manual file editing.
|
|
84
|
+
- 📊 **Live Dashboard** — HTTP server with real-time polling. Chat-style agent handoffs, TODO content, TODO timeline, worker status, browser notifications. No page reloads.
|
|
85
|
+
- 🧱 **Custom pipelines** — any roles, any depth. 1 stage or 10. You choose in the setup form.
|
|
86
|
+
- ✅ **Approve / Reject** — symmetric verify tools. Approve commits and archives. Reject kills the pipeline and asks for fixes.
|
|
87
|
+
- 🔍 **Pre-dispatch check** — before launching a pipeline, awf greps your codebase for keywords from the TODO. Warning if the task might already be done.
|
|
88
|
+
- 🔄 **Crash recovery** — salvage path when workers don't signal, orphan TODO cleanup, state reconciliation on startup.
|
|
89
|
+
- 📋 **Increment planning** — decomposition variants (vertical, horizontal, risk-first) presented as an HTML form for user choice.
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
Talk in natural language — the supervisor agent calls the right tools:
|
|
94
|
+
|
|
95
|
+
| You say | What happens |
|
|
96
|
+
|---|---|
|
|
97
|
+
| *"Initialize awf in my project"* | Creates `.agentic/`, detects stack, asks for your goal |
|
|
98
|
+
| *"Develop the MVP"* | Opens setup form → configures pipeline → plans first TODO |
|
|
99
|
+
| *"Verify"* | Supervisor reads handoffs, checks git diff, approves or rejects |
|
|
100
|
+
| *"Reject — the cache is missing"* | Pipeline killed, new TODO dispatched with fix instructions |
|
|
101
|
+
|
|
102
|
+
See [USAGE.md](USAGE.md) for full scenarios and tool reference.
|
|
103
|
+
|
|
104
|
+
### SMO Flow
|
|
105
|
+
|
|
106
|
+
```mermaid
|
|
107
|
+
graph LR
|
|
108
|
+
init --> goal --> form --> normalize --> brief --> run --> verify --> done
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
| Phase | You do | Supervisor does |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| init | — | Creates `.agentic/`, detects stack |
|
|
114
|
+
| goal | Answer "what do you want?" | Stores goal |
|
|
115
|
+
| form | Fill setup form in browser | Opens form, recommends roles |
|
|
116
|
+
| normalize | — | Analyzes role overlaps |
|
|
117
|
+
| brief | — | Studies project, dispatches TODO |
|
|
118
|
+
| run | Monitor dashboard | **IDLE** — waits for you |
|
|
119
|
+
| verify | Say *"verify"* | Reviews, approves/rejects |
|
|
120
|
+
| done | "continue" or "stop" | Waits for instruction |
|
|
121
|
+
|
|
122
|
+
## Architecture
|
|
123
|
+
|
|
124
|
+
```mermaid
|
|
125
|
+
graph TD
|
|
126
|
+
A[opencode supervisor LLM] -->|MCP stdio - 29 tools| B[agent-workflow-ui plugin]
|
|
127
|
+
B -->|Python import| C[awf orchestrator]
|
|
128
|
+
C -->|subprocess| D[opencode run - worker agents]
|
|
129
|
+
C -->|HTTP daemon| E[Dashboard - live /api/state]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Two packages:
|
|
133
|
+
- **`awf`** — Python core. Pipeline engine, phase state machine, signals, commit gate, dashboard server.
|
|
134
|
+
- **`agent_workflow_ui`** — MCP plugin. Thin async wrappers + `next_action` guidance + HTML forms.
|
|
135
|
+
|
|
136
|
+
## Comparison
|
|
137
|
+
|
|
138
|
+
| | awf | Aider | Claude Code | Devin |
|
|
139
|
+
|---|---|---|---|---|
|
|
140
|
+
| Planning before code | ✅ | ❌ | ⚠️ | ✅ |
|
|
141
|
+
| Human approve/reject | ✅ | ❌ | ❌ | ✅ |
|
|
142
|
+
| Custom pipelines | ✅ | ❌ | ❌ | ❌ |
|
|
143
|
+
| MCP-native | ✅ | ❌ | ❌ | ❌ |
|
|
144
|
+
| Self-hosted / free | ✅ | ✅ | ❌ | ❌ |
|
|
145
|
+
| Any LLM provider | ✅ | ✅ | ❌ | ❌ |
|
|
146
|
+
|
|
147
|
+
## Dashboard
|
|
148
|
+
|
|
149
|
+
Live HTTP dashboard opens automatically when pipeline starts:
|
|
150
|
+
|
|
151
|
+
- **Two-panel layout** — pipeline sidebar (stages, progress, worker) + content tabs
|
|
152
|
+
- **💬 Agent Chat** — handoffs as conversation messages with chain visualization
|
|
153
|
+
- **📝 Задача** — full TODO content in rendered markdown
|
|
154
|
+
- **📊 События** — meaningful events, newest first
|
|
155
|
+
- **TODO timeline** — `[✅ TODO-0001] ─ [✅ TODO-0002] ─ [🔄 TODO-0003]`
|
|
156
|
+
- **Browser notification** when pipeline reaches verify
|
|
157
|
+
|
|
158
|
+
## Real-world results
|
|
159
|
+
|
|
160
|
+
6 sessions on jira-epic-presenter (Qwen vLLM):
|
|
161
|
+
- Full SMO flow end-to-end: init → goal → form → normalize → brief → run → verify
|
|
162
|
+
- 4 TODOs per session, 1× approve (no loops), zero polling
|
|
163
|
+
- Reject flow tested: supervisor found missing work, rejected, re-dispatched with fix
|
|
164
|
+
- Pre-dispatch check caught already-implemented tasks
|
|
165
|
+
|
|
166
|
+
## Roadmap
|
|
167
|
+
|
|
168
|
+
- **SMO escape-hatch'и** — manual phase jumps, interruptions (from real session edge cases)
|
|
169
|
+
- **Coverage** — critical paths (verify, plan_checkpoint, context)
|
|
170
|
+
- **PyPI** — `pip install awf agent-workflow-ui` (no git clone needed)
|
|
171
|
+
- **Dashboard v3** — stage timing bars, session summary, sound notifications
|
|
172
|
+
- **Standalone mode** — awf without opencode (API-only)
|
|
173
|
+
|
|
174
|
+
Full backlog: [BACKLOG.md](BACKLOG.md)
|
|
175
|
+
|
|
176
|
+
## Documentation
|
|
177
|
+
|
|
178
|
+
- [USAGE.md](USAGE.md) — usage scenarios and tool reference
|
|
179
|
+
- [Architecture](vision/architecture.md) — components, data flow, design decisions
|
|
180
|
+
- [Product Vision](vision/agent-ui-plugin.md) — competitive advantages
|
|
181
|
+
- [Supervisor Flow (SMO)](vision/supervisor-flow.md) — phase system, next_action pattern
|
|
182
|
+
- [CHANGELOG.md](CHANGELOG.md) — version history
|
|
183
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) — how to contribute
|
|
184
|
+
- [BACKLOG.md](BACKLOG.md) — open tasks
|
|
185
|
+
- [README.ru.md](README.ru.md) — Russian README
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT — see [LICENSE](LICENSE).
|
awf-1.0.0/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Agentic Workflow (awf)
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.python.org/downloads/)
|
|
5
|
+
[](https://github.com/EnerJizeIT/agentic-workflow/actions/workflows/test.yml)
|
|
6
|
+
|
|
7
|
+
> **Multi-agent pipeline orchestrator for opencode. Plan → build → verify → commit — through typed MCP tools, not bash.**
|
|
8
|
+
|
|
9
|
+
## The problem it solves
|
|
10
|
+
|
|
11
|
+
AI coding agents are powerful but chaotic. They jump straight to code without planning, skip review, leave bugs. You watch helplessly as tokens burn.
|
|
12
|
+
|
|
13
|
+
**awf** adds structure: a supervisor agent plans the work, worker agents execute through a pipeline you design (any roles, any depth — from a single worker to a multi-stage chain), and you approve each result before it commits. All through natural language — *"start working on the backlog"*, *"verify and approve"*, *"reject — the DOMParser fix is missing"*.
|
|
14
|
+
|
|
15
|
+
You stay in control. The agent stays on rails.
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Install
|
|
21
|
+
pip install -e .
|
|
22
|
+
pip install -e ./agent_workflow_ui
|
|
23
|
+
|
|
24
|
+
# 2. Configure opencode — add to ~/.config/opencode/opencode.json:
|
|
25
|
+
# {
|
|
26
|
+
# "mcp": {
|
|
27
|
+
# "agent-workflow-ui": {
|
|
28
|
+
# "type": "local",
|
|
29
|
+
# "command": ["python3", "-m", "agent_workflow_ui"],
|
|
30
|
+
# "enabled": true
|
|
31
|
+
# }
|
|
32
|
+
# }
|
|
33
|
+
# }
|
|
34
|
+
|
|
35
|
+
# 3. Run — just talk to opencode:
|
|
36
|
+
# "Initialize awf in my project"
|
|
37
|
+
# "Develop the MVP based on the backlog"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
| Component | Requirement |
|
|
43
|
+
|---|---|
|
|
44
|
+
| **Python** | 3.10+ |
|
|
45
|
+
| **opencode** | any recent version with MCP support |
|
|
46
|
+
| **OS** | Linux (tested), macOS (should work), Windows (untested) |
|
|
47
|
+
| **Models** | Model-agnostic. Tested with Qwen vLLM. Should work with Claude, GPT, or any opencode-supported provider. |
|
|
48
|
+
| **Git** | Required (commit gate, baselines, rollback) |
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- 🎯 **State-Machine Orchestration (SMO)** — awf guides the supervisor through phases: `init → goal → form → normalize → brief → run → verify → done`. Every tool returns a `next_action` hint — even weak models follow the full flow without getting lost.
|
|
53
|
+
- 🔧 **29 MCP tools** — typed pipeline control: init, dispatch, start, approve, reject, rollback, dashboard, model validation. No bash, no manual file editing.
|
|
54
|
+
- 📊 **Live Dashboard** — HTTP server with real-time polling. Chat-style agent handoffs, TODO content, TODO timeline, worker status, browser notifications. No page reloads.
|
|
55
|
+
- 🧱 **Custom pipelines** — any roles, any depth. 1 stage or 10. You choose in the setup form.
|
|
56
|
+
- ✅ **Approve / Reject** — symmetric verify tools. Approve commits and archives. Reject kills the pipeline and asks for fixes.
|
|
57
|
+
- 🔍 **Pre-dispatch check** — before launching a pipeline, awf greps your codebase for keywords from the TODO. Warning if the task might already be done.
|
|
58
|
+
- 🔄 **Crash recovery** — salvage path when workers don't signal, orphan TODO cleanup, state reconciliation on startup.
|
|
59
|
+
- 📋 **Increment planning** — decomposition variants (vertical, horizontal, risk-first) presented as an HTML form for user choice.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
Talk in natural language — the supervisor agent calls the right tools:
|
|
64
|
+
|
|
65
|
+
| You say | What happens |
|
|
66
|
+
|---|---|
|
|
67
|
+
| *"Initialize awf in my project"* | Creates `.agentic/`, detects stack, asks for your goal |
|
|
68
|
+
| *"Develop the MVP"* | Opens setup form → configures pipeline → plans first TODO |
|
|
69
|
+
| *"Verify"* | Supervisor reads handoffs, checks git diff, approves or rejects |
|
|
70
|
+
| *"Reject — the cache is missing"* | Pipeline killed, new TODO dispatched with fix instructions |
|
|
71
|
+
|
|
72
|
+
See [USAGE.md](USAGE.md) for full scenarios and tool reference.
|
|
73
|
+
|
|
74
|
+
### SMO Flow
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
graph LR
|
|
78
|
+
init --> goal --> form --> normalize --> brief --> run --> verify --> done
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Phase | You do | Supervisor does |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| init | — | Creates `.agentic/`, detects stack |
|
|
84
|
+
| goal | Answer "what do you want?" | Stores goal |
|
|
85
|
+
| form | Fill setup form in browser | Opens form, recommends roles |
|
|
86
|
+
| normalize | — | Analyzes role overlaps |
|
|
87
|
+
| brief | — | Studies project, dispatches TODO |
|
|
88
|
+
| run | Monitor dashboard | **IDLE** — waits for you |
|
|
89
|
+
| verify | Say *"verify"* | Reviews, approves/rejects |
|
|
90
|
+
| done | "continue" or "stop" | Waits for instruction |
|
|
91
|
+
|
|
92
|
+
## Architecture
|
|
93
|
+
|
|
94
|
+
```mermaid
|
|
95
|
+
graph TD
|
|
96
|
+
A[opencode supervisor LLM] -->|MCP stdio - 29 tools| B[agent-workflow-ui plugin]
|
|
97
|
+
B -->|Python import| C[awf orchestrator]
|
|
98
|
+
C -->|subprocess| D[opencode run - worker agents]
|
|
99
|
+
C -->|HTTP daemon| E[Dashboard - live /api/state]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Two packages:
|
|
103
|
+
- **`awf`** — Python core. Pipeline engine, phase state machine, signals, commit gate, dashboard server.
|
|
104
|
+
- **`agent_workflow_ui`** — MCP plugin. Thin async wrappers + `next_action` guidance + HTML forms.
|
|
105
|
+
|
|
106
|
+
## Comparison
|
|
107
|
+
|
|
108
|
+
| | awf | Aider | Claude Code | Devin |
|
|
109
|
+
|---|---|---|---|---|
|
|
110
|
+
| Planning before code | ✅ | ❌ | ⚠️ | ✅ |
|
|
111
|
+
| Human approve/reject | ✅ | ❌ | ❌ | ✅ |
|
|
112
|
+
| Custom pipelines | ✅ | ❌ | ❌ | ❌ |
|
|
113
|
+
| MCP-native | ✅ | ❌ | ❌ | ❌ |
|
|
114
|
+
| Self-hosted / free | ✅ | ✅ | ❌ | ❌ |
|
|
115
|
+
| Any LLM provider | ✅ | ✅ | ❌ | ❌ |
|
|
116
|
+
|
|
117
|
+
## Dashboard
|
|
118
|
+
|
|
119
|
+
Live HTTP dashboard opens automatically when pipeline starts:
|
|
120
|
+
|
|
121
|
+
- **Two-panel layout** — pipeline sidebar (stages, progress, worker) + content tabs
|
|
122
|
+
- **💬 Agent Chat** — handoffs as conversation messages with chain visualization
|
|
123
|
+
- **📝 Задача** — full TODO content in rendered markdown
|
|
124
|
+
- **📊 События** — meaningful events, newest first
|
|
125
|
+
- **TODO timeline** — `[✅ TODO-0001] ─ [✅ TODO-0002] ─ [🔄 TODO-0003]`
|
|
126
|
+
- **Browser notification** when pipeline reaches verify
|
|
127
|
+
|
|
128
|
+
## Real-world results
|
|
129
|
+
|
|
130
|
+
6 sessions on jira-epic-presenter (Qwen vLLM):
|
|
131
|
+
- Full SMO flow end-to-end: init → goal → form → normalize → brief → run → verify
|
|
132
|
+
- 4 TODOs per session, 1× approve (no loops), zero polling
|
|
133
|
+
- Reject flow tested: supervisor found missing work, rejected, re-dispatched with fix
|
|
134
|
+
- Pre-dispatch check caught already-implemented tasks
|
|
135
|
+
|
|
136
|
+
## Roadmap
|
|
137
|
+
|
|
138
|
+
- **SMO escape-hatch'и** — manual phase jumps, interruptions (from real session edge cases)
|
|
139
|
+
- **Coverage** — critical paths (verify, plan_checkpoint, context)
|
|
140
|
+
- **PyPI** — `pip install awf agent-workflow-ui` (no git clone needed)
|
|
141
|
+
- **Dashboard v3** — stage timing bars, session summary, sound notifications
|
|
142
|
+
- **Standalone mode** — awf without opencode (API-only)
|
|
143
|
+
|
|
144
|
+
Full backlog: [BACKLOG.md](BACKLOG.md)
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
- [USAGE.md](USAGE.md) — usage scenarios and tool reference
|
|
149
|
+
- [Architecture](vision/architecture.md) — components, data flow, design decisions
|
|
150
|
+
- [Product Vision](vision/agent-ui-plugin.md) — competitive advantages
|
|
151
|
+
- [Supervisor Flow (SMO)](vision/supervisor-flow.md) — phase system, next_action pattern
|
|
152
|
+
- [CHANGELOG.md](CHANGELOG.md) — version history
|
|
153
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) — how to contribute
|
|
154
|
+
- [BACKLOG.md](BACKLOG.md) — open tasks
|
|
155
|
+
- [README.ru.md](README.ru.md) — Russian README
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT — see [LICENSE](LICENSE).
|
awf-1.0.0/awf/_atomic.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Atomic file write helpers for awf-core.
|
|
2
|
+
|
|
3
|
+
Centralized so all modules use the same temp+rename pattern.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import tempfile
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def atomic_write_text(path: Path, content: str, encoding: str = "utf-8") -> None:
|
|
13
|
+
"""Write text file atomically via temp + rename.
|
|
14
|
+
|
|
15
|
+
Creates parent dir if missing. Uses tempfile in same dir to guarantee
|
|
16
|
+
same-filesystem rename (atomic on POSIX).
|
|
17
|
+
|
|
18
|
+
H5 fix: plan_progress.py was direct write_text — crash mid-write
|
|
19
|
+
corrupted plan.md (the only persistent progress artifact).
|
|
20
|
+
"""
|
|
21
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
22
|
+
fd, tmp_path = tempfile.mkstemp(
|
|
23
|
+
prefix=f".{path.name}.",
|
|
24
|
+
suffix=".tmp",
|
|
25
|
+
dir=str(path.parent),
|
|
26
|
+
)
|
|
27
|
+
try:
|
|
28
|
+
with os.fdopen(fd, "w", encoding=encoding) as f:
|
|
29
|
+
f.write(content)
|
|
30
|
+
os.replace(tmp_path, path)
|
|
31
|
+
except Exception:
|
|
32
|
+
# Clean up temp file on failure
|
|
33
|
+
try:
|
|
34
|
+
os.unlink(tmp_path)
|
|
35
|
+
except OSError:
|
|
36
|
+
pass
|
|
37
|
+
raise
|
awf-1.0.0/awf/_env.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""BD-22/25: subprocess environment setup for opencode run.
|
|
2
|
+
|
|
3
|
+
Centralized so signal_watch + supervisor + agent_stage can use it without
|
|
4
|
+
circular imports through orchestrator.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _pdeathsig_preexec() -> None:
|
|
14
|
+
"""DF6-8: Set PR_SET_PDEATHSIG so child dies when parent (orchestrator) dies.
|
|
15
|
+
|
|
16
|
+
Linux-only. On other platforms, no-op (best effort).
|
|
17
|
+
Prevents orphan worker subprocesses from continuing after orchestrator crash.
|
|
18
|
+
"""
|
|
19
|
+
if sys.platform != "linux":
|
|
20
|
+
return
|
|
21
|
+
try:
|
|
22
|
+
import ctypes
|
|
23
|
+
import signal as _signal
|
|
24
|
+
|
|
25
|
+
libc = ctypes.CDLL("libc.so.6", use_errno=True)
|
|
26
|
+
PR_SET_PDEATHSIG = 1
|
|
27
|
+
libc.prctl(PR_SET_PDEATHSIG, _signal.SIGTERM)
|
|
28
|
+
except Exception:
|
|
29
|
+
pass # best effort — don't crash if libc/prctl unavailable
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def awf_subprocess_env() -> dict[str, str]:
|
|
33
|
+
"""BD-22/KAUD-5: env for opencode subprocess spawned by awf.
|
|
34
|
+
|
|
35
|
+
Sets ``OPENCODE_CONFIG_CONTENT`` to override permission rules so
|
|
36
|
+
the subprocess can run ``edit``/``bash``/``write`` without prompting.
|
|
37
|
+
|
|
38
|
+
KAUD-5: MERGES with user's existing opencode.json instead of replacing.
|
|
39
|
+
Reads user's config, adds our permission overrides on top, preserves
|
|
40
|
+
user's other settings (theme, providers, agents, etc.).
|
|
41
|
+
|
|
42
|
+
BD-25: strip ``OPENCODE_SERVER_*`` env vars so the subprocess does NOT
|
|
43
|
+
attach to a running ``opencode serve`` instance.
|
|
44
|
+
"""
|
|
45
|
+
env = os.environ.copy()
|
|
46
|
+
|
|
47
|
+
# KAUD-5: Start from user's existing config, then merge our overrides
|
|
48
|
+
user_config: dict = {}
|
|
49
|
+
try:
|
|
50
|
+
from .xdg import opencode_config_file
|
|
51
|
+
config_path = opencode_config_file()
|
|
52
|
+
if config_path.is_file():
|
|
53
|
+
user_config = json.loads(config_path.read_text(encoding="utf-8"))
|
|
54
|
+
if not isinstance(user_config, dict):
|
|
55
|
+
user_config = {}
|
|
56
|
+
except (OSError, json.JSONDecodeError):
|
|
57
|
+
pass # If user config is unreadable, start from empty
|
|
58
|
+
|
|
59
|
+
# Merge: user config + our permission overrides (ours take priority)
|
|
60
|
+
merged = user_config.copy()
|
|
61
|
+
merged_permissions = merged.get("permission", {})
|
|
62
|
+
if not isinstance(merged_permissions, dict):
|
|
63
|
+
merged_permissions = {}
|
|
64
|
+
merged_permissions.update({
|
|
65
|
+
"edit": "allow",
|
|
66
|
+
"bash": "allow",
|
|
67
|
+
"write": "allow",
|
|
68
|
+
"webfetch": "allow",
|
|
69
|
+
})
|
|
70
|
+
merged["permission"] = merged_permissions
|
|
71
|
+
|
|
72
|
+
# P1 security: only serialize permission overrides to env — never API keys,
|
|
73
|
+
# providers, or other sensitive fields from opencode.json. Workers only
|
|
74
|
+
# need the permission overrides; everything else is loaded by opencode
|
|
75
|
+
# itself from the real config file.
|
|
76
|
+
config_json = json.dumps({"permission": merged_permissions})
|
|
77
|
+
env["OPENCODE_CONFIG_CONTENT"] = config_json
|
|
78
|
+
|
|
79
|
+
# BD-25: strip server env vars
|
|
80
|
+
strip_keys = (
|
|
81
|
+
"OPENCODE_SERVER",
|
|
82
|
+
"OPENCODE_SERVER_URL",
|
|
83
|
+
"OPENCODE_SERVER_TOKEN",
|
|
84
|
+
"OPENCODE_HOST",
|
|
85
|
+
"OPENCODE_HOST_TOKEN",
|
|
86
|
+
)
|
|
87
|
+
for key in list(env.keys()):
|
|
88
|
+
if key in strip_keys:
|
|
89
|
+
env.pop(key, None)
|
|
90
|
+
return env
|
awf-1.0.0/awf/_log.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Lightweight file-based logger for awf.
|
|
2
|
+
|
|
3
|
+
Centralized so any module can log without circular imports.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import datetime as _dt
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def log(logs_dir: Path, message: str) -> None:
|
|
12
|
+
"""Append a timestamped message to ``logs_dir/orchestrator.log``."""
|
|
13
|
+
if not logs_dir.exists():
|
|
14
|
+
try:
|
|
15
|
+
logs_dir.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
except OSError:
|
|
17
|
+
return
|
|
18
|
+
log_file = logs_dir / "orchestrator.log"
|
|
19
|
+
ts = _dt.datetime.now(_dt.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
20
|
+
try:
|
|
21
|
+
with open(log_file, "a", encoding="utf-8") as f:
|
|
22
|
+
f.write(f"[{ts}] {message}\n")
|
|
23
|
+
except OSError:
|
|
24
|
+
pass
|