petrarca-agent-flow 0.1.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.
- petrarca_agent_flow-0.1.0/.github/workflows/ci.yml +97 -0
- petrarca_agent_flow-0.1.0/.github/workflows/publish.yml +82 -0
- petrarca_agent_flow-0.1.0/.github/workflows/release.yml +29 -0
- petrarca_agent_flow-0.1.0/.gitignore +21 -0
- petrarca_agent_flow-0.1.0/.pre-commit-config.yaml +37 -0
- petrarca_agent_flow-0.1.0/AGENTS.md +193 -0
- petrarca_agent_flow-0.1.0/CONTRIBUTING.md +121 -0
- petrarca_agent_flow-0.1.0/LICENSE +190 -0
- petrarca_agent_flow-0.1.0/PKG-INFO +360 -0
- petrarca_agent_flow-0.1.0/README.md +324 -0
- petrarca_agent_flow-0.1.0/Taskfile.yml +157 -0
- petrarca_agent_flow-0.1.0/deploy/docker-compose.yml +63 -0
- petrarca_agent_flow-0.1.0/docs/README.md +13 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/backend.md +117 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/cli-events.md +150 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/control-file.md +93 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/engine.md +114 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/flowdef.md +174 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/gates.md +106 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/index.md +145 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/input-plane.md +192 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/node_builder.md +82 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/result-schema.md +77 -0
- petrarca_agent_flow-0.1.0/docs/design/orchestrator/supervision.md +127 -0
- petrarca_agent_flow-0.1.0/docs/usage/advanced-recipes.md +495 -0
- petrarca_agent_flow-0.1.0/docs/usage/getting-started.md +212 -0
- petrarca_agent_flow-0.1.0/docs/usage/index.md +74 -0
- petrarca_agent_flow-0.1.0/docs/usage/recipes.md +187 -0
- petrarca_agent_flow-0.1.0/docs/usage/writing-agents.md +120 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/analyst.md +41 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/architecture-analyst.md +37 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/architecture-verifier.md +33 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/coupling-analyst.md +35 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/coupling-verifier.md +33 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/domain-analyst.md +37 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/domain-verifier.md +33 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/executive-summary.md +38 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/extractor.md +38 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/summary-verifier.md +33 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/tech-stack-analyst.md +37 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/tech-stack-verifier.md +33 -0
- petrarca_agent_flow-0.1.0/examples/.opencode/agent/verifier.md +36 -0
- petrarca_agent_flow-0.1.0/examples/README.md +66 -0
- petrarca_agent_flow-0.1.0/examples/__init__.py +0 -0
- petrarca_agent_flow-0.1.0/examples/custom_flow.py +422 -0
- petrarca_agent_flow-0.1.0/examples/declarative.py +154 -0
- petrarca_agent_flow-0.1.0/examples/imperative.py +92 -0
- petrarca_agent_flow-0.1.0/examples/inprocess.py +180 -0
- petrarca_agent_flow-0.1.0/pyproject.toml +86 -0
- petrarca_agent_flow-0.1.0/setup.cfg +4 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/__init__.py +222 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/backends/__init__.py +68 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/backends/_prefect_env.py +94 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/backends/base.py +107 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/backends/inprocess.py +80 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/backends/prefect.py +102 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/__init__.py +38 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/app.py +126 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/commands/__init__.py +7 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/commands/nodes.py +82 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/commands/run.py +248 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/console.py +22 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/context.py +28 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/events.py +216 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/progress.py +56 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/cli/tables.py +62 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/__init__.py +72 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/_mock_agent.py +232 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/agent_runtime.py +425 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/context.py +86 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/control_protocol.py +96 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/env.py +50 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/report_signals.py +57 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/schema.py +112 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/core/schema_pydantic.py +39 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/engine.py +813 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/flowdef/__init__.py +15 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/flowdef/compile.py +129 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/flowdef/models.py +109 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/gates.py +224 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/node_builder.py +266 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/preflight.py +103 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/registry.py +258 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/run_config.py +257 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/run_context.py +126 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/__init__.py +77 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/base.py +236 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/claude_code.py +52 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/executor.py +93 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/inprocess.py +119 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/mock.py +34 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/runners/opencode.py +252 -0
- petrarca_agent_flow-0.1.0/src/agent_flow/utils.py +97 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/PKG-INFO +360 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/SOURCES.txt +130 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/dependency_links.txt +1 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/requires.txt +25 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/scm_file_list.json +127 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/scm_version.json +8 -0
- petrarca_agent_flow-0.1.0/src/petrarca_agent_flow.egg-info/top_level.txt +1 -0
- petrarca_agent_flow-0.1.0/tests/conftest.py +52 -0
- petrarca_agent_flow-0.1.0/tests/fixtures/opencode/agent/selftest-analyst.md +18 -0
- petrarca_agent_flow-0.1.0/tests/integration/test_flow_backends.py +79 -0
- petrarca_agent_flow-0.1.0/tests/integration/test_flow_progress.py +53 -0
- petrarca_agent_flow-0.1.0/tests/integration/test_run_agent_mock.py +125 -0
- petrarca_agent_flow-0.1.0/tests/integration/test_run_agent_opencode.py +57 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_backends.py +164 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_cli_summary.py +63 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_context.py +49 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_control_protocol.py +22 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_engine.py +196 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_env.py +31 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_events.py +252 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_flowdef.py +98 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_inprocess.py +175 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_instructions.py +128 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_node_builder.py +243 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_on_event.py +45 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_only.py +119 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_prefect_isolation.py +139 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_preflight.py +115 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_progress.py +68 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_registry.py +241 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_report_signals.py +98 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_require_extra.py +24 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_run_config.py +146 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_run_context.py +169 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_runners.py +105 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_schema.py +99 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_start_from.py +84 -0
- petrarca_agent_flow-0.1.0/tests/unit/test_utils.py +53 -0
- petrarca_agent_flow-0.1.0/uv.lock +1936 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# Build-only CI: lint, format-check, tests, and build the package.
|
|
4
|
+
# Publishing to PyPI + the GitHub Release happen on a version tag (v*) via
|
|
5
|
+
# publish.yml / release.yml, not here.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
paths-ignore:
|
|
11
|
+
- '**/*.md'
|
|
12
|
+
pull_request:
|
|
13
|
+
branches: [main]
|
|
14
|
+
paths-ignore:
|
|
15
|
+
- '**/*.md'
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
test:
|
|
23
|
+
name: Lint + Test
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
timeout-minutes: 20
|
|
26
|
+
strategy:
|
|
27
|
+
matrix:
|
|
28
|
+
python-version: ['3.14']
|
|
29
|
+
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout repository
|
|
32
|
+
uses: actions/checkout@v7
|
|
33
|
+
with:
|
|
34
|
+
fetch-depth: 0 # setuptools-scm needs full history for the version
|
|
35
|
+
|
|
36
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
37
|
+
uses: actions/setup-python@v7
|
|
38
|
+
with:
|
|
39
|
+
python-version: ${{ matrix.python-version }}
|
|
40
|
+
|
|
41
|
+
- name: Install uv
|
|
42
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
43
|
+
with:
|
|
44
|
+
enable-cache: true
|
|
45
|
+
|
|
46
|
+
- name: Install Task
|
|
47
|
+
uses: arduino/setup-task@v3.0.0
|
|
48
|
+
with:
|
|
49
|
+
version: 3.x
|
|
50
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
51
|
+
|
|
52
|
+
- name: Install dependencies (editable + dev extras)
|
|
53
|
+
run: task install
|
|
54
|
+
|
|
55
|
+
- name: Lint + format check (read-only)
|
|
56
|
+
run: task verify
|
|
57
|
+
|
|
58
|
+
- name: Unit + integration tests (mock; opencode e2e is skipped)
|
|
59
|
+
run: task test:all
|
|
60
|
+
|
|
61
|
+
build:
|
|
62
|
+
name: Build package
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
timeout-minutes: 15
|
|
65
|
+
needs: test
|
|
66
|
+
|
|
67
|
+
steps:
|
|
68
|
+
- name: Checkout repository
|
|
69
|
+
uses: actions/checkout@v7
|
|
70
|
+
with:
|
|
71
|
+
fetch-depth: 0
|
|
72
|
+
|
|
73
|
+
- name: Set up Python 3.14
|
|
74
|
+
uses: actions/setup-python@v7
|
|
75
|
+
with:
|
|
76
|
+
python-version: '3.14'
|
|
77
|
+
|
|
78
|
+
- name: Install uv
|
|
79
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
80
|
+
with:
|
|
81
|
+
enable-cache: true
|
|
82
|
+
|
|
83
|
+
- name: Install Task
|
|
84
|
+
uses: arduino/setup-task@v3.0.0
|
|
85
|
+
with:
|
|
86
|
+
version: 3.x
|
|
87
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
88
|
+
|
|
89
|
+
- name: Build sdist + wheel
|
|
90
|
+
run: task build
|
|
91
|
+
|
|
92
|
+
- name: Upload build artifacts
|
|
93
|
+
uses: actions/upload-artifact@v7
|
|
94
|
+
with:
|
|
95
|
+
name: dist-${{ github.sha }}
|
|
96
|
+
path: dist/
|
|
97
|
+
retention-days: 7
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publish on a version tag. setuptools-scm derives the version from the tag
|
|
4
|
+
# (see [tool.setuptools_scm] tag_regex "^v..."), so tagging vX.Y.Z is the release
|
|
5
|
+
# trigger. Trusted publishing (OIDC) is used — no API token secret needed; the
|
|
6
|
+
# PyPI project must have this repo configured as a trusted publisher for the
|
|
7
|
+
# `pypi` environment.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
tags:
|
|
12
|
+
- 'v*'
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
id-token: write # Required for trusted publishing (OIDC)
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
test:
|
|
20
|
+
name: Lint + Test
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 20
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout repository
|
|
26
|
+
uses: actions/checkout@v7
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0 # setuptools-scm needs full history for the version
|
|
29
|
+
|
|
30
|
+
- name: Set up Python 3.14
|
|
31
|
+
uses: actions/setup-python@v7
|
|
32
|
+
with:
|
|
33
|
+
python-version: '3.14'
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
37
|
+
with:
|
|
38
|
+
enable-cache: true
|
|
39
|
+
|
|
40
|
+
- name: Install Task
|
|
41
|
+
uses: arduino/setup-task@v3.0.0
|
|
42
|
+
with:
|
|
43
|
+
version: 3.x
|
|
44
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
45
|
+
|
|
46
|
+
- name: Install dependencies (editable + dev extras)
|
|
47
|
+
run: task install
|
|
48
|
+
|
|
49
|
+
- name: Lint + format check (read-only)
|
|
50
|
+
run: task verify
|
|
51
|
+
|
|
52
|
+
- name: Unit + integration tests (mock; opencode e2e is skipped)
|
|
53
|
+
run: task test:all
|
|
54
|
+
|
|
55
|
+
publish:
|
|
56
|
+
name: Build + Publish to PyPI
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
timeout-minutes: 15
|
|
59
|
+
needs: test
|
|
60
|
+
environment: pypi
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- name: Checkout repository
|
|
64
|
+
uses: actions/checkout@v7
|
|
65
|
+
with:
|
|
66
|
+
fetch-depth: 0 # Required for setuptools-scm
|
|
67
|
+
|
|
68
|
+
- name: Set up Python 3.14
|
|
69
|
+
uses: actions/setup-python@v7
|
|
70
|
+
with:
|
|
71
|
+
python-version: '3.14'
|
|
72
|
+
|
|
73
|
+
- name: Install uv
|
|
74
|
+
uses: astral-sh/setup-uv@v9.0.0
|
|
75
|
+
with:
|
|
76
|
+
enable-cache: true
|
|
77
|
+
|
|
78
|
+
- name: Build sdist + wheel
|
|
79
|
+
run: uv build
|
|
80
|
+
|
|
81
|
+
- name: Publish to PyPI
|
|
82
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Create a GitHub Release with auto-generated notes on a version tag. Runs
|
|
4
|
+
# alongside publish.yml (both trigger on 'v*'); this one only creates the
|
|
5
|
+
# Release entry, publish.yml uploads to PyPI.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- 'v*'
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
release:
|
|
17
|
+
name: Create GitHub Release
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 5
|
|
20
|
+
steps:
|
|
21
|
+
- name: Checkout repository
|
|
22
|
+
uses: actions/checkout@v7
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
|
|
26
|
+
- name: Create GitHub Release
|
|
27
|
+
uses: softprops/action-gh-release@v3
|
|
28
|
+
with:
|
|
29
|
+
generate_release_notes: true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
.prefect/
|
|
3
|
+
.env
|
|
4
|
+
__pycache__/
|
|
5
|
+
*.pyc
|
|
6
|
+
*.egg-info/
|
|
7
|
+
.ruff_cache/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
|
|
11
|
+
.DS_Store
|
|
12
|
+
|
|
13
|
+
# Example RUN ARTIFACTS — reports/sidecars agents write during a demo run when
|
|
14
|
+
# run_dir/REPORT resolves into the example dir (normal runs go to /tmp). Agent
|
|
15
|
+
# DEFINITIONS under examples/**/.opencode/agent/ are tracked and NOT ignored.
|
|
16
|
+
examples/*/*.md
|
|
17
|
+
examples/*/*.json
|
|
18
|
+
examples/*/*.control.json
|
|
19
|
+
|
|
20
|
+
# JS deps accidentally created under an example's .opencode/
|
|
21
|
+
node_modules/
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
###############################
|
|
2
|
+
# pre-commit configuration
|
|
3
|
+
#
|
|
4
|
+
# Strategy:
|
|
5
|
+
# - Use only "local" hooks so we orchestrate via Taskfile tasks (single source
|
|
6
|
+
# of truth for how we lint/format/test).
|
|
7
|
+
# - Split fast feedback (pre-commit) from deeper validation (pre-push).
|
|
8
|
+
# - pass_filenames: false because the tasks already know what to operate on.
|
|
9
|
+
#
|
|
10
|
+
# Tips:
|
|
11
|
+
# - Skip all hooks: git commit -m "msg" --no-verify
|
|
12
|
+
# - Run manually: task fct
|
|
13
|
+
# - Install the hooks: task pre-commit:install
|
|
14
|
+
# - Update the hooks: task pre-commit:update
|
|
15
|
+
###############################
|
|
16
|
+
repos:
|
|
17
|
+
- repo: local
|
|
18
|
+
hooks:
|
|
19
|
+
# Pre-commit (fast): format + lint(+fix) + unit tests.
|
|
20
|
+
- id: fct
|
|
21
|
+
name: "format + check + unit tests (quick)"
|
|
22
|
+
entry: bash -c 'task fct'
|
|
23
|
+
language: system
|
|
24
|
+
pass_filenames: false
|
|
25
|
+
files: \.py$
|
|
26
|
+
|
|
27
|
+
# Pre-push (deeper): read-only lint/format gate + unit tests. Integration
|
|
28
|
+
# (mock subprocess) and the real-opencode e2e are deliberately NOT run here
|
|
29
|
+
# — they are slower / opt-in; run them explicitly with `task test:all` /
|
|
30
|
+
# `task test:opencode` when needed.
|
|
31
|
+
- id: verify-and-test
|
|
32
|
+
name: "pre-push: verify + unit tests"
|
|
33
|
+
entry: bash -c 'task verify && task test'
|
|
34
|
+
language: system
|
|
35
|
+
pass_filenames: false
|
|
36
|
+
files: \.py$
|
|
37
|
+
stages: [pre-push]
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
This file contains project-specific rules and conventions for AI coding
|
|
4
|
+
assistants working on **agent-flow**.
|
|
5
|
+
|
|
6
|
+
## Project Overview
|
|
7
|
+
|
|
8
|
+
agent-flow is a Python library for **deterministic orchestration of coding-agent
|
|
9
|
+
pipelines**. It replaces the fragile "LLM orchestrator agent" pattern with a
|
|
10
|
+
deterministic engine that supervises coding-agent subprocesses (opencode today)
|
|
11
|
+
and runs them as a graph — with parallelism, bounded re-runs, cross-node
|
|
12
|
+
jump-back, telemetry, and optional typed output. The execution backend
|
|
13
|
+
(in-process default / opt-in Prefect) and the agent runtime (opencode / Claude
|
|
14
|
+
Code / …) are both pluggable.
|
|
15
|
+
|
|
16
|
+
### The three usage tiers (high level → low level)
|
|
17
|
+
|
|
18
|
+
- **Tier 3 — declarative**: declare `Node`s, call `build_flow` → a runnable flow
|
|
19
|
+
callable that dispatches execution to the selected backend. `agent_node` builds
|
|
20
|
+
a node that runs one agent in one call.
|
|
21
|
+
- **Tier 2 — primitives in your own flow**: call `run_agent` as the leaf of a
|
|
22
|
+
hand-written flow (a consumer may hand-write a Prefect flow around it — the toy
|
|
23
|
+
example does).
|
|
24
|
+
- **Tier 1 — engine core**: `run_agent` spawns + liveness-supervises + kills +
|
|
25
|
+
reads the control sidecar. Runtime-agnostic; no Prefect.
|
|
26
|
+
|
|
27
|
+
The dependency direction is strictly downward: **Tier 3 (`engine.py`) must not
|
|
28
|
+
import Tier 1** (`core.agent_runtime`/`runners`) — they meet only through a
|
|
29
|
+
node's `run` callable. `batteries.py` is the single module allowed to bridge
|
|
30
|
+
both.
|
|
31
|
+
|
|
32
|
+
## Project Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
src/agent_flow/
|
|
36
|
+
__init__.py # Public API exports (keep in sync with what ships)
|
|
37
|
+
engine.py # Node / RunContext / build_flow / plan_groups / interpret / _walk (Tier 3)
|
|
38
|
+
batteries.py # agent_node — one-call node (bridges engine + run_agent)
|
|
39
|
+
gates.py # Directive (Continue/Restart/GoTo/Stop) + GateContext + ready gates
|
|
40
|
+
run_config.py # RunConfig (pydantic-settings) / build_run_config / get_settings lifecycle
|
|
41
|
+
run_context.py # RunContextService — open domain params + exports
|
|
42
|
+
preflight.py # runtime pre-flight checks (opencode/agent_dir/prefect) -> Check results
|
|
43
|
+
utils.py # resolve_run_dir / default_temp_base / require_extra (pure top-level leaf)
|
|
44
|
+
core/ # Tier-1 primitives, GUARANTEED backend-free (run_agent,
|
|
45
|
+
# control protocol, result-schema, context ingestion, env)
|
|
46
|
+
runners/ # agent-runtime seam (AgentRunner Protocol) + get_runner registry
|
|
47
|
+
backends/ # execution seam (FlowBackend ABC) + get_backend;
|
|
48
|
+
# inprocess default, prefect opt-in (DEFAULT_BACKEND="inprocess")
|
|
49
|
+
cli/ # run_cli + display helpers (typer/rich, opt-in [cli] extra)
|
|
50
|
+
examples/
|
|
51
|
+
toy_pipeline/ # Tier-2 demo (hand-written flow) + its .opencode/agent/*.md
|
|
52
|
+
tech_assessment/ # Tier-3 demo (declared graph) + its .opencode/agent/*.md
|
|
53
|
+
docs/
|
|
54
|
+
usage/ # consumer OKF bundle (getting-started, writing-agents, recipes)
|
|
55
|
+
design/orchestrator/ # design OKF bundle (one concept per file; start at index.md)
|
|
56
|
+
deploy/ # docker-compose (Prefect server + Postgres) for persistent mode
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Running commands (full output)
|
|
60
|
+
|
|
61
|
+
When running a command whose output matters, capture and read the FULL output —
|
|
62
|
+
do not truncate with `tail`, `head`, `grep`, or similar. Truncation hides errors,
|
|
63
|
+
stack traces, and warnings that appear outside the visible window. Prefer piping
|
|
64
|
+
through `tee` to a file and reading the whole file:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
some-command 2>&1 | tee /tmp/out.log # then read /tmp/out.log in full
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This is especially important for `task fct`, the examples, and any run that can
|
|
71
|
+
fail partway — the interesting line is rarely the last one.
|
|
72
|
+
|
|
73
|
+
## Build & Test
|
|
74
|
+
|
|
75
|
+
House-standard task names (same across petrarca repos):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
task setup # create the venv
|
|
79
|
+
task install # editable install with dev tools
|
|
80
|
+
task fct # format + check (lint) + test — run before committing
|
|
81
|
+
task format # ruff format
|
|
82
|
+
task check # ruff check --fix
|
|
83
|
+
task verify # CI gate: lint + format check, read-only
|
|
84
|
+
task test # unit tests (fast)
|
|
85
|
+
task test:unit # unit tests only
|
|
86
|
+
task test:integration # integration (mock subprocess)
|
|
87
|
+
task test:all # unit + integration
|
|
88
|
+
task test:opencode # opt-in real-opencode e2e (needs opencode; run OUTSIDE an opencode session)
|
|
89
|
+
task build # build sdist + wheel
|
|
90
|
+
task rebuild:all # clean + install + format + check + test:all + build
|
|
91
|
+
task clean # remove build artifacts and caches
|
|
92
|
+
task pre-commit:install # install git pre-commit + pre-push hooks
|
|
93
|
+
task pre-commit:update # update pinned hook versions
|
|
94
|
+
task pre-commit:run # run all hooks against the tree
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Run the examples:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
task example:toy:mock TOPIC="Ports and Adapters"
|
|
101
|
+
task example:tech:mock PRODUCT=my-product
|
|
102
|
+
task example:tech PRODUCT=my-product RUNTIME=opencode SHOW_EVENTS=--show-events
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
> Real-opencode runs must start from a normal shell **outside** an opencode
|
|
106
|
+
> session (a nested opencode raises `UnknownError`).
|
|
107
|
+
|
|
108
|
+
## Core Concepts (do not violate)
|
|
109
|
+
|
|
110
|
+
### The control-file contract
|
|
111
|
+
|
|
112
|
+
An agent signals completion by writing a JSON **control sidecar** — the SOLE
|
|
113
|
+
verdict. The library injects the protocol into the prompt
|
|
114
|
+
(`build_control_preamble`); agent `.md` files carry only domain instructions.
|
|
115
|
+
|
|
116
|
+
- **Envelope (engine reads):** `status` (`ok`/`verified`/`error`), `agent`,
|
|
117
|
+
`reason`, and `rerun_required` (a flow-control signal a gate consumes).
|
|
118
|
+
- **Payload (only gates/consumers read):** `result` — free-form dict. The engine
|
|
119
|
+
never looks inside.
|
|
120
|
+
- **No `artifact` field** — what an agent produces is expressed in the files it
|
|
121
|
+
was told to write, not reported back.
|
|
122
|
+
- **No sidecar → error.** The engine never inspects artifacts to guess success.
|
|
123
|
+
|
|
124
|
+
### Two directories (never conflate)
|
|
125
|
+
|
|
126
|
+
- **`run_dir`** — where control sidecars + relative artifact paths resolve. NOT a
|
|
127
|
+
cwd. Unset → a fresh temp dir under `<temp>/agent-flow/` (ephemeral; pass an
|
|
128
|
+
explicit `run_dir` for output you keep). Resolved once per run via
|
|
129
|
+
`utils.resolve_run_dir`.
|
|
130
|
+
- **`agent_dir`** — where agent DEFINITIONS live (opencode `--dir`); becomes the
|
|
131
|
+
subprocess cwd. Global default via `build_flow(agent_dir=)`, per-node override
|
|
132
|
+
via `agent_node(agent_dir=)`.
|
|
133
|
+
|
|
134
|
+
### Gates are the consumer's optional hook
|
|
135
|
+
|
|
136
|
+
A gate `(GateContext) -> Directive` decides flow control AFTER an agent runs. The
|
|
137
|
+
engine never auto-fails on schema/artifact issues — a gate does. A verifier is
|
|
138
|
+
NOT a library concept: it is just another node that `depends_on` its subject and
|
|
139
|
+
returns `GoTo(subject)`.
|
|
140
|
+
|
|
141
|
+
### Typed output
|
|
142
|
+
|
|
143
|
+
`result_schema` is an opt-in convenience. `ctx.result["result"]` is always the
|
|
144
|
+
dict (validated if a schema was attached). `ctx.result["_result_obj"]` is a
|
|
145
|
+
Pydantic model instance ONLY when a `PydanticSchema` was used, else `None` (a
|
|
146
|
+
dict schema / no schema add no new object).
|
|
147
|
+
|
|
148
|
+
### The input plane (prompt composition order)
|
|
149
|
+
|
|
150
|
+
`[control protocol] [run-wide context] [run-wide brief] [per-node context]
|
|
151
|
+
[per-node instructions] [work order]`. "Context" = FILE CONTENT ingested by the
|
|
152
|
+
library (the fix for "agents don't read the rules"); "instructions" = inline
|
|
153
|
+
text. Any `pipeline(**params)` key is a `{name}` template usable in
|
|
154
|
+
inputs/context/paths. To hand a value TO the agent, put it in `inputs`.
|
|
155
|
+
|
|
156
|
+
## Code Quality
|
|
157
|
+
|
|
158
|
+
- Ruff `E, F, B, I, C90`, line length **150**, McCabe max-complexity **10**.
|
|
159
|
+
- No bare `except Exception`; catch concrete types. `except A, B:` (no `as`) is
|
|
160
|
+
valid Python 3.14 (PEP 758) — do not flag it.
|
|
161
|
+
- Dependencies are a lean core plus opt-in extras. Core (always installed):
|
|
162
|
+
pydantic, pydantic-settings, pyyaml, jsonschema, python-dotenv — enough to
|
|
163
|
+
declare a pipeline and run it on the default InProcessBackend. The heavy pieces are
|
|
164
|
+
extras matching the runtime seams: `[prefect]` (the opt-in PrefectBackend) and
|
|
165
|
+
`[cli]` (typer + rich for `run_cli` / display); `[all]` is both, `[dev]` adds
|
|
166
|
+
the tooling. An optional dep is lazy-imported at its entry point only — prefect
|
|
167
|
+
inside `backends/prefect.py`, rich/typer inside `cli/` — guarded by
|
|
168
|
+
`utils.require_extra(...)` so a missing extra fails with an actionable
|
|
169
|
+
"install agent-flow[...]" message.
|
|
170
|
+
- When adding a public symbol, export it in `src/agent_flow/__init__.py` and keep
|
|
171
|
+
the module-docstring "Public API" example current.
|
|
172
|
+
|
|
173
|
+
## Git Conventions
|
|
174
|
+
|
|
175
|
+
- Commit prefixes: `feat:`, `fix:`, `refactor:`, `chore:`, `docs:`, `test:`.
|
|
176
|
+
- Short messages, max ~two sentences per point.
|
|
177
|
+
- **Run `task fct` (format + check + test) before every commit** and make sure it
|
|
178
|
+
passes. The pre-commit hook enforces this, but run it yourself first — never
|
|
179
|
+
commit code that has not passed `task fct`.
|
|
180
|
+
- **Never commit or push implicitly.** Do not run any git write operation
|
|
181
|
+
(`commit`, `push`, `merge`, `rebase`, `tag`, `reset --hard`, etc.) unless the
|
|
182
|
+
user has explicitly instructed it for that specific action. Do not chain a
|
|
183
|
+
commit/push onto another task on your own initiative. When in doubt, stop and
|
|
184
|
+
ask. Read-only git (`status`, `log`, `diff`) is fine without asking.
|
|
185
|
+
- `main` is the default branch. Do not commit `work*`, `.venv`, `.env`, caches,
|
|
186
|
+
or `node_modules` (all gitignored).
|
|
187
|
+
|
|
188
|
+
## Documentation
|
|
189
|
+
|
|
190
|
+
Docs are OKF bundles (`docs/usage/`, `docs/design/orchestrator/`) — every file
|
|
191
|
+
has a `type` frontmatter field. When you change behavior, update the matching
|
|
192
|
+
concept doc and verify code snippets run. The README covers install + the three
|
|
193
|
+
tiers + running the examples.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Contributing to agent-flow
|
|
2
|
+
|
|
3
|
+
Thank you for considering contributing to agent-flow! This document outlines the
|
|
4
|
+
process for contributing and the conventions that keep the project consistent.
|
|
5
|
+
|
|
6
|
+
## Code of Conduct
|
|
7
|
+
|
|
8
|
+
By participating in this project, you agree to maintain a respectful and
|
|
9
|
+
inclusive environment for everyone.
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
### Prerequisites
|
|
14
|
+
|
|
15
|
+
- Python 3.14+
|
|
16
|
+
- [`uv`](https://docs.astral.sh/uv/) package manager
|
|
17
|
+
- [`task`](https://taskfile.dev/) (go-task)
|
|
18
|
+
- For real (non-mock) runs: `opencode` on `PATH`, configured with model access
|
|
19
|
+
|
|
20
|
+
### Setting up the development environment
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone <your-fork-url>
|
|
24
|
+
cd agent-flow
|
|
25
|
+
task install # editable install with dev tools (ruff, pytest, pydantic, jsonschema, typer, rich, pyyaml)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Development workflow
|
|
29
|
+
|
|
30
|
+
### Branch naming
|
|
31
|
+
|
|
32
|
+
Use descriptive branch names with prefixes:
|
|
33
|
+
|
|
34
|
+
- `feat/` — new features
|
|
35
|
+
- `fix/` — bug fixes
|
|
36
|
+
- `docs/` — documentation changes
|
|
37
|
+
- `refactor/` — code refactoring
|
|
38
|
+
- `test/` — tests only
|
|
39
|
+
|
|
40
|
+
Example: `feat/claude-code-runner`
|
|
41
|
+
|
|
42
|
+
### Coding standards
|
|
43
|
+
|
|
44
|
+
- Ruff for linting and formatting, rules `E, F, B, I, C90`, line length **150**.
|
|
45
|
+
- McCabe max complexity **10** — refactor complex functions into helpers.
|
|
46
|
+
- Type-annotate public functions.
|
|
47
|
+
- No bare `except Exception` — catch concrete types (note: `except A, B:` without
|
|
48
|
+
`as` is valid Python 3.14 per PEP 758; do not "fix" it to parentheses).
|
|
49
|
+
- Keep the **core** dependency-light. Core deps (always installed): `pydantic`,
|
|
50
|
+
`pydantic-settings`, `pyyaml`, `jsonschema`, `python-dotenv`. Optional extras:
|
|
51
|
+
`[prefect]` (the Prefect backend) and `[cli]` (`typer` + `rich`). An optional
|
|
52
|
+
dep must be **lazy-imported at its entry point**, never at module-import time —
|
|
53
|
+
`prefect` only inside `backends/prefect.py`, `rich`/`typer` only inside `cli/`.
|
|
54
|
+
Guard the entry-point import with `utils.require_extra(...)` so a missing extra
|
|
55
|
+
fails with an actionable "install agent-flow[...]" message. The
|
|
56
|
+
`test_prefect_isolation` guard proves core + runners + InProcessBackend import and
|
|
57
|
+
run with `prefect` blocked.
|
|
58
|
+
- Respect the layering: the engine (Tier 3) must not import the runtime core
|
|
59
|
+
(Tier 1); they meet only through a node's `run` callable (`batteries` is the
|
|
60
|
+
one bridge). See `docs/design/orchestrator/index.md`.
|
|
61
|
+
|
|
62
|
+
### Testing
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
task test # unit tests (fast, no subprocess)
|
|
66
|
+
task test:all # unit + integration (mock subprocess; opencode e2e skipped)
|
|
67
|
+
task test:opencode # opt-in real-opencode e2e (needs opencode + creds; run OUTSIDE an opencode session)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Run real-opencode examples/e2e from a normal shell **outside** an opencode
|
|
71
|
+
session — a nested opencode raises `UnknownError`.
|
|
72
|
+
|
|
73
|
+
### The local loop
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
task fct # format + check (lint) + test — run before every commit
|
|
77
|
+
task verify # CI gate: lint + format check, read-only (no fixes)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
Design docs and consumer docs are [OKF](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
|
|
83
|
+
bundles under `docs/`:
|
|
84
|
+
|
|
85
|
+
- `docs/usage/` — task-oriented consumer guides (start at `index.md`)
|
|
86
|
+
- `docs/design/orchestrator/` — architecture + one concept per file
|
|
87
|
+
|
|
88
|
+
When you change behavior, update the relevant doc and keep every OKF file's
|
|
89
|
+
`type` frontmatter intact. Verify code snippets actually run.
|
|
90
|
+
|
|
91
|
+
## Pull request process
|
|
92
|
+
|
|
93
|
+
1. Update docs and the README for any behavior/API change.
|
|
94
|
+
2. Run `task fct` — lint, format, and tests must pass.
|
|
95
|
+
3. Submit a PR with a clear description of the change.
|
|
96
|
+
4. Address review feedback.
|
|
97
|
+
|
|
98
|
+
## Commit messages
|
|
99
|
+
|
|
100
|
+
Short, clear, category-prefixed (conventional-commits style):
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
<type>(<optional scope>): <description>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`.
|
|
107
|
+
Example: `feat(cli): add --config run-file support`.
|
|
108
|
+
|
|
109
|
+
## Reporting bugs
|
|
110
|
+
|
|
111
|
+
Include: a clear title, steps to reproduce, expected vs. actual behavior, and
|
|
112
|
+
environment details (OS, Python version, opencode version if relevant).
|
|
113
|
+
|
|
114
|
+
## Feature requests
|
|
115
|
+
|
|
116
|
+
Provide a clear description, the motivation, and any implementation thoughts.
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
By contributing, you agree that your contributions will be licensed under the
|
|
121
|
+
Apache License 2.0 (see `LICENSE`).
|