agentforge-framework 0.2.3__tar.gz → 0.2.4__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.
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/PKG-INFO +26 -4
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/README.md +25 -3
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/pyproject.toml +1 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/__init__.py +1 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/__init__.py +21 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/architect.py +7 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/implementer.py +7 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/orchestrator.py +2 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/reviewer.py +2 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/security.py +19 -7
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/tester.py +15 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/config.py +56 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/contracts.py +36 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/runtime.py +10 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/providers/base.py +27 -4
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/providers/claude.py +55 -11
- agentforge_framework-0.2.4/src/agentforge_framework/providers/codex.py +196 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/PKG-INFO +26 -4
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_agents.py +2 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_architect.py +1 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_cli.py +1 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_config.py +60 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_docs.py +6 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_execution_posture.py +81 -19
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_providers.py +70 -2
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_reviewer.py +1 -1
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_runtime.py +91 -19
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_security.py +23 -5
- agentforge_framework-0.2.3/src/agentforge_framework/providers/codex.py +0 -143
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/LICENSE +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/setup.cfg +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/.claude-plugin/plugin.json +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/decomposer.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/cli.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/extractors/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/extractors/base.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/extractors/python.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/extractors/sql.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/extractors/yaml.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/prompt.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/context/resolver.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/commands.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/gates.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/issues.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/plan_format.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/process.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/project.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/registry.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/repo.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/router.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/skills.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/workflow.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/plugins/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/plugins/databricks/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/plugins/pyspark/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/plugins/python/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/plugins/sql/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/providers/__init__.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/MANIFEST.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/NOTICE +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/domain-modeling/ADR-FORMAT.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/domain-modeling/CONTEXT-FORMAT.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/domain-modeling/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/domain-modeling/agents/openai.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/grill-with-docs/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/grilling/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/grilling/agents/openai.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/to-spec/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/to-spec/agents/openai.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/to-tickets/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/to-tickets/agents/openai.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/evals/fixtures/silhouette/human_reference.json +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/_lang.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/banned_phrase_scan.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/calibrate_pairs.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/calibrate_score.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/check_packs.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/check_suggestions.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/contribute.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/diff_check.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/extract_constraints.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/harvest_classify.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/harvest_samples.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/readability_metrics.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/refresh_status.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/silhouette_scan.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/structure_scan.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/suggest.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/validate_preservation.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/voice_card.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/voice_profile.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/voice_score.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/unslop/scripts/wiki_sync.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/skills/write-plainly/SKILL.md +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/workflows/bugfix.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/workflows/feature.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/workflows/review.yaml +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/SOURCES.txt +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/dependency_links.txt +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/entry_points.txt +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/requires.txt +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework.egg-info/top_level.txt +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_context.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_contracts.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_decompose.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_gates.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_interview.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_issues.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_plan_format.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_plugins.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_project.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_skills.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_tester.py +0 -0
- {agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/tests/test_workflow.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentforge-framework
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A modular framework for coordinating specialized software agents.
|
|
5
5
|
Author: Yash Mhatre
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -99,7 +99,10 @@ ADR-0015.
|
|
|
99
99
|
|
|
100
100
|
Without `--allow-commands`, the Implementer remains default-deny and the Tester
|
|
101
101
|
reports that it could not run the suite; it never substitutes reading tests and
|
|
102
|
-
claims completion.
|
|
102
|
+
claims completion. That gate is held by the `claude` adapter. The `codex` CLI
|
|
103
|
+
cannot hold it — `codex exec` discards its approval flag — so a denied Run on
|
|
104
|
+
`codex` is refused before it starts rather than run under a guarantee nothing
|
|
105
|
+
enforces (ADR-0007, amended). Security, the Reviewer, and the Architect need no such flag —
|
|
103
106
|
auditing, reviewing, and designing are reading. All six Roles `CONTEXT.md` names
|
|
104
107
|
now run. Plugins have landed, and with them the data-engineering ones: a
|
|
105
108
|
repository whose files import `pyspark` has its Roles told to write DataFrame
|
|
@@ -145,7 +148,7 @@ without notice. See
|
|
|
145
148
|
```console
|
|
146
149
|
$ pip install agentforge-framework
|
|
147
150
|
$ agentforge --version
|
|
148
|
-
agentforge 0.2.
|
|
151
|
+
agentforge 0.2.4
|
|
149
152
|
```
|
|
150
153
|
|
|
151
154
|
That is the whole of it. The two routes below the naming note are for a machine
|
|
@@ -169,7 +172,7 @@ from the [latest release](https://github.com/yashmhatre/AgentForge/releases/late
|
|
|
169
172
|
and install the file:
|
|
170
173
|
|
|
171
174
|
```console
|
|
172
|
-
$ pip install agentforge_framework-0.2.
|
|
175
|
+
$ pip install agentforge_framework-0.2.4-py3-none-any.whl
|
|
173
176
|
```
|
|
174
177
|
|
|
175
178
|
Publishing a release is a wizard rather than a checklist:
|
|
@@ -282,14 +285,33 @@ defaults are Claude `native` and every other Provider `fragment`, and the
|
|
|
282
285
|
providers:
|
|
283
286
|
claude:
|
|
284
287
|
capability_tier: native
|
|
288
|
+
# Optional. Overrides the adapter's own tier-to-model table; name only the
|
|
289
|
+
# tiers you disagree about, and the rest keep the shipped defaults.
|
|
290
|
+
models:
|
|
291
|
+
deep: claude-opus-5
|
|
285
292
|
codex:
|
|
286
293
|
capability_tier: fragment
|
|
287
294
|
|
|
295
|
+
# Optional. A Role's two declared axes: which class of model runs it, and how
|
|
296
|
+
# hard that model thinks. Both default to the table in ADR-0004.
|
|
297
|
+
roles:
|
|
298
|
+
security:
|
|
299
|
+
tier: deep
|
|
300
|
+
effort: max
|
|
301
|
+
|
|
288
302
|
gates:
|
|
289
303
|
tests:
|
|
290
304
|
suite: pytest
|
|
291
305
|
```
|
|
292
306
|
|
|
307
|
+
There is no `roles.<name>.model` key, and naming one is an error rather than a
|
|
308
|
+
line that gets ignored. A Role declares a tier; the Provider maps that tier onto
|
|
309
|
+
a model. A model named per Role does not survive the next CLI release and does
|
|
310
|
+
not port to another Provider, which is what
|
|
311
|
+
[ADR-0004](docs/adr/0004-model-tiers-declared-not-named.md) exists to prevent --
|
|
312
|
+
override `providers.<name>.models.<tier>` if the mapping is what you disagree
|
|
313
|
+
with.
|
|
314
|
+
|
|
293
315
|
There is no `plugins:` key. Which Plugins answer for a repository is decided per
|
|
294
316
|
Run from the frozen plan's blast radius (ADR-0016), so a repository-level list
|
|
295
317
|
would be inert and misleading -- init prints what it detected instead. The file
|
|
@@ -81,7 +81,10 @@ ADR-0015.
|
|
|
81
81
|
|
|
82
82
|
Without `--allow-commands`, the Implementer remains default-deny and the Tester
|
|
83
83
|
reports that it could not run the suite; it never substitutes reading tests and
|
|
84
|
-
claims completion.
|
|
84
|
+
claims completion. That gate is held by the `claude` adapter. The `codex` CLI
|
|
85
|
+
cannot hold it — `codex exec` discards its approval flag — so a denied Run on
|
|
86
|
+
`codex` is refused before it starts rather than run under a guarantee nothing
|
|
87
|
+
enforces (ADR-0007, amended). Security, the Reviewer, and the Architect need no such flag —
|
|
85
88
|
auditing, reviewing, and designing are reading. All six Roles `CONTEXT.md` names
|
|
86
89
|
now run. Plugins have landed, and with them the data-engineering ones: a
|
|
87
90
|
repository whose files import `pyspark` has its Roles told to write DataFrame
|
|
@@ -127,7 +130,7 @@ without notice. See
|
|
|
127
130
|
```console
|
|
128
131
|
$ pip install agentforge-framework
|
|
129
132
|
$ agentforge --version
|
|
130
|
-
agentforge 0.2.
|
|
133
|
+
agentforge 0.2.4
|
|
131
134
|
```
|
|
132
135
|
|
|
133
136
|
That is the whole of it. The two routes below the naming note are for a machine
|
|
@@ -151,7 +154,7 @@ from the [latest release](https://github.com/yashmhatre/AgentForge/releases/late
|
|
|
151
154
|
and install the file:
|
|
152
155
|
|
|
153
156
|
```console
|
|
154
|
-
$ pip install agentforge_framework-0.2.
|
|
157
|
+
$ pip install agentforge_framework-0.2.4-py3-none-any.whl
|
|
155
158
|
```
|
|
156
159
|
|
|
157
160
|
Publishing a release is a wizard rather than a checklist:
|
|
@@ -264,14 +267,33 @@ defaults are Claude `native` and every other Provider `fragment`, and the
|
|
|
264
267
|
providers:
|
|
265
268
|
claude:
|
|
266
269
|
capability_tier: native
|
|
270
|
+
# Optional. Overrides the adapter's own tier-to-model table; name only the
|
|
271
|
+
# tiers you disagree about, and the rest keep the shipped defaults.
|
|
272
|
+
models:
|
|
273
|
+
deep: claude-opus-5
|
|
267
274
|
codex:
|
|
268
275
|
capability_tier: fragment
|
|
269
276
|
|
|
277
|
+
# Optional. A Role's two declared axes: which class of model runs it, and how
|
|
278
|
+
# hard that model thinks. Both default to the table in ADR-0004.
|
|
279
|
+
roles:
|
|
280
|
+
security:
|
|
281
|
+
tier: deep
|
|
282
|
+
effort: max
|
|
283
|
+
|
|
270
284
|
gates:
|
|
271
285
|
tests:
|
|
272
286
|
suite: pytest
|
|
273
287
|
```
|
|
274
288
|
|
|
289
|
+
There is no `roles.<name>.model` key, and naming one is an error rather than a
|
|
290
|
+
line that gets ignored. A Role declares a tier; the Provider maps that tier onto
|
|
291
|
+
a model. A model named per Role does not survive the next CLI release and does
|
|
292
|
+
not port to another Provider, which is what
|
|
293
|
+
[ADR-0004](docs/adr/0004-model-tiers-declared-not-named.md) exists to prevent --
|
|
294
|
+
override `providers.<name>.models.<tier>` if the mapping is what you disagree
|
|
295
|
+
with.
|
|
296
|
+
|
|
275
297
|
There is no `plugins:` key. Which Plugins answer for a repository is decided per
|
|
276
298
|
Run from the frozen plan's blast radius (ADR-0016), so a repository-level list
|
|
277
299
|
would be inert and misleading -- init prints what it detected instead. The file
|
|
@@ -12,7 +12,7 @@ would be the most expensive default in the project.
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
-
from ..core.contracts import ModelTier, Role
|
|
15
|
+
from ..core.contracts import Effort, ModelTier, Role
|
|
16
16
|
from .architect import ARCHITECT, Architect
|
|
17
17
|
from .implementer import IMPLEMENTER, Implementer
|
|
18
18
|
from .orchestrator import ORCHESTRATOR
|
|
@@ -53,12 +53,30 @@ RUNNERS: dict[str, type] = {
|
|
|
53
53
|
KNOWN_TIERS: dict[str, ModelTier] = {
|
|
54
54
|
"orchestrator": ModelTier.DEEP,
|
|
55
55
|
"architect": ModelTier.DEEP,
|
|
56
|
-
"security": ModelTier.DEEP,
|
|
57
56
|
"reviewer": ModelTier.DEEP,
|
|
58
57
|
"implementer": ModelTier.STANDARD,
|
|
58
|
+
"security": ModelTier.STANDARD,
|
|
59
59
|
"tester": ModelTier.CHEAP,
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
#: The second axis, keyed the same way. A tier says which model runs; this says
|
|
63
|
+
#: how hard it thinks, and the two are set independently — see ADR-0004's
|
|
64
|
+
#: 2026-09-03 amendment for why they were ever one thing.
|
|
65
|
+
#:
|
|
66
|
+
#: The Security row is the reason the axes split. It reads `standard` above and
|
|
67
|
+
#: `high` here, which is not a demotion: ADR-0004 bought it `deep` because a
|
|
68
|
+
#: missed finding is silent, and that argument was about reasoning depth. It
|
|
69
|
+
#: keeps the depth — above the Implementer whose work it audits — and stops
|
|
70
|
+
#: buying a frontier model to get it.
|
|
71
|
+
KNOWN_EFFORTS: dict[str, Effort] = {
|
|
72
|
+
"orchestrator": Effort.HIGH,
|
|
73
|
+
"architect": Effort.HIGH,
|
|
74
|
+
"reviewer": Effort.HIGH,
|
|
75
|
+
"security": Effort.HIGH,
|
|
76
|
+
"implementer": Effort.MEDIUM,
|
|
77
|
+
"tester": Effort.MEDIUM,
|
|
78
|
+
}
|
|
79
|
+
|
|
62
80
|
|
|
63
81
|
class UnknownRole(LookupError):
|
|
64
82
|
"""A Roster names a Role this version of AgentForge cannot run."""
|
|
@@ -80,6 +98,7 @@ def resolve_role(name: str) -> Role:
|
|
|
80
98
|
__all__ = [
|
|
81
99
|
"ARCHITECT",
|
|
82
100
|
"IMPLEMENTER",
|
|
101
|
+
"KNOWN_EFFORTS",
|
|
83
102
|
"KNOWN_TIERS",
|
|
84
103
|
"ORCHESTRATOR",
|
|
85
104
|
"REVIEWER",
|
|
@@ -27,7 +27,7 @@ from __future__ import annotations
|
|
|
27
27
|
from pathlib import Path
|
|
28
28
|
|
|
29
29
|
from ..context.prompt import render_context_block
|
|
30
|
-
from ..core.contracts import AgentResult, ContextPack, ModelTier, Plan, Role
|
|
30
|
+
from ..core.contracts import AgentResult, ContextPack, Effort, ModelTier, Plan, Role
|
|
31
31
|
from ..core.plan_format import RESULT_CLOSE, RESULT_OPEN
|
|
32
32
|
from .implementer import render_steps
|
|
33
33
|
|
|
@@ -90,7 +90,12 @@ step and the mismatch in `summary`.\
|
|
|
90
90
|
"""
|
|
91
91
|
|
|
92
92
|
#: The Architect runs `deep`: a boundary in the wrong place outlives the Run.
|
|
93
|
-
ARCHITECT = Role(
|
|
93
|
+
ARCHITECT = Role(
|
|
94
|
+
name="architect",
|
|
95
|
+
tier=ModelTier.DEEP,
|
|
96
|
+
effort=Effort.HIGH,
|
|
97
|
+
instructions=INSTRUCTIONS,
|
|
98
|
+
)
|
|
94
99
|
|
|
95
100
|
|
|
96
101
|
def build_prompt(
|
|
@@ -19,7 +19,7 @@ from __future__ import annotations
|
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
|
|
21
21
|
from ..context.prompt import render_context_block
|
|
22
|
-
from ..core.contracts import AgentResult, ContextPack, ModelTier, Plan, Role
|
|
22
|
+
from ..core.contracts import AgentResult, ContextPack, Effort, ModelTier, Plan, Role
|
|
23
23
|
from ..core.plan_format import RESULT_CLOSE, RESULT_OPEN
|
|
24
24
|
|
|
25
25
|
INSTRUCTIONS = """\
|
|
@@ -77,7 +77,12 @@ actually contains. Change no files when you escalate.\
|
|
|
77
77
|
"""
|
|
78
78
|
|
|
79
79
|
#: The Implementer runs at `standard`: it executes a plan it did not write.
|
|
80
|
-
IMPLEMENTER = Role(
|
|
80
|
+
IMPLEMENTER = Role(
|
|
81
|
+
name="implementer",
|
|
82
|
+
tier=ModelTier.STANDARD,
|
|
83
|
+
effort=Effort.MEDIUM,
|
|
84
|
+
instructions=INSTRUCTIONS,
|
|
85
|
+
)
|
|
81
86
|
|
|
82
87
|
|
|
83
88
|
def render_steps(plan: Plan) -> str:
|
|
@@ -38,6 +38,7 @@ from ..core.contracts import (
|
|
|
38
38
|
DEFAULT_WORKFLOW,
|
|
39
39
|
AgentResult,
|
|
40
40
|
ContextPack,
|
|
41
|
+
Effort,
|
|
41
42
|
ModelTier,
|
|
42
43
|
Outcome,
|
|
43
44
|
Plan,
|
|
@@ -239,6 +240,7 @@ repository itself uses them, and do not start a glossary during an interview.\
|
|
|
239
240
|
ORCHESTRATOR = Role(
|
|
240
241
|
name="orchestrator",
|
|
241
242
|
tier=ModelTier.DEEP,
|
|
243
|
+
effort=Effort.HIGH,
|
|
242
244
|
instructions=INSTRUCTIONS,
|
|
243
245
|
#: What a planning pass works with: the project's vocabulary, the synthesis
|
|
244
246
|
#: of a conversation into a spec, and the breakdown of that spec into work.
|
|
@@ -33,6 +33,7 @@ from ..context.prompt import render_context_block
|
|
|
33
33
|
from ..core.contracts import (
|
|
34
34
|
AgentResult,
|
|
35
35
|
ContextPack,
|
|
36
|
+
Effort,
|
|
36
37
|
ModelTier,
|
|
37
38
|
Outcome,
|
|
38
39
|
Plan,
|
|
@@ -158,6 +159,7 @@ End your reply with this block and nothing after it:
|
|
|
158
159
|
REVIEWER = Role(
|
|
159
160
|
name="reviewer",
|
|
160
161
|
tier=ModelTier.DEEP,
|
|
162
|
+
effort=Effort.HIGH,
|
|
161
163
|
instructions=INSTRUCTIONS,
|
|
162
164
|
skills=WRITING_SKILLS,
|
|
163
165
|
)
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"""The Security Role: audits the change, and fixes nothing.
|
|
2
2
|
|
|
3
|
-
It runs at `
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Role that cannot be run cheaply.
|
|
3
|
+
It runs at `standard` and thinks at `high` (ADR-0004, amended 2026-09-03). The
|
|
4
|
+
tier used to be `deep`, on the one argument in the table that was not about
|
|
5
|
+
cost: a missed finding is silent — nobody reviews the audit that did not happen
|
|
6
|
+
— so the Role that looks for what nobody asked about cannot be run cheaply.
|
|
7
|
+
|
|
8
|
+
That argument survives; it was only ever about reasoning. When effort became a
|
|
9
|
+
Role's own axis, the depth it was really buying became purchasable on its own,
|
|
10
|
+
and Security kept it — `high`, above the Implementer whose work it reads —
|
|
11
|
+
while the tier came down. If audits start missing what a human then finds at
|
|
12
|
+
Sign-off, the tier is the half to move back.
|
|
7
13
|
|
|
8
14
|
Its output is a list of Findings rather than prose, because the Gate downstream
|
|
9
15
|
of it has to tell "audited, nothing found" from "did not audit", and a paragraph
|
|
@@ -16,7 +22,7 @@ from __future__ import annotations
|
|
|
16
22
|
from pathlib import Path
|
|
17
23
|
|
|
18
24
|
from ..context.prompt import render_context_block
|
|
19
|
-
from ..core.contracts import AgentResult, ContextPack, ModelTier, Plan, Role
|
|
25
|
+
from ..core.contracts import AgentResult, ContextPack, Effort, ModelTier, Plan, Role
|
|
20
26
|
from ..core.plan_format import RESULT_CLOSE, RESULT_OPEN
|
|
21
27
|
from .implementer import render_steps
|
|
22
28
|
|
|
@@ -86,8 +92,14 @@ Use `"outcome": "escalated"` only when the Plan does not match the repository, \
|
|
|
86
92
|
or when you could not audit the change at all. Say which in `summary`.\
|
|
87
93
|
"""
|
|
88
94
|
|
|
89
|
-
#:
|
|
90
|
-
|
|
95
|
+
#: A finding nobody makes is a finding nobody reviews — bought as depth rather
|
|
96
|
+
#: than as model size. See the module docstring and ADR-0004.
|
|
97
|
+
SECURITY = Role(
|
|
98
|
+
name="security",
|
|
99
|
+
tier=ModelTier.STANDARD,
|
|
100
|
+
effort=Effort.HIGH,
|
|
101
|
+
instructions=INSTRUCTIONS,
|
|
102
|
+
)
|
|
91
103
|
|
|
92
104
|
|
|
93
105
|
def build_prompt(
|
{agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/agents/tester.py
RENAMED
|
@@ -5,7 +5,15 @@ from __future__ import annotations
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
from ..context.prompt import render_context_block
|
|
8
|
-
from ..core.contracts import
|
|
8
|
+
from ..core.contracts import (
|
|
9
|
+
AgentResult,
|
|
10
|
+
ContextPack,
|
|
11
|
+
Effort,
|
|
12
|
+
ModelTier,
|
|
13
|
+
Outcome,
|
|
14
|
+
Plan,
|
|
15
|
+
Role,
|
|
16
|
+
)
|
|
9
17
|
from ..core.plan_format import RESULT_CLOSE, RESULT_OPEN
|
|
10
18
|
from .implementer import render_steps
|
|
11
19
|
|
|
@@ -66,7 +74,12 @@ from verifying. Reading tests is not a substitute for running them.\
|
|
|
66
74
|
#: recorded in ADR-0004 — reasoning about an edge case nobody wrote a test for is
|
|
67
75
|
#: the part that gets worse here, and it is the part a human reads the findings
|
|
68
76
|
#: for anyway.
|
|
69
|
-
TESTER = Role(
|
|
77
|
+
TESTER = Role(
|
|
78
|
+
name="tester",
|
|
79
|
+
tier=ModelTier.CHEAP,
|
|
80
|
+
effort=Effort.MEDIUM,
|
|
81
|
+
instructions=INSTRUCTIONS,
|
|
82
|
+
)
|
|
70
83
|
|
|
71
84
|
|
|
72
85
|
def build_prompt(
|
{agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/config.py
RENAMED
|
@@ -9,6 +9,8 @@ from pathlib import Path
|
|
|
9
9
|
|
|
10
10
|
import yaml
|
|
11
11
|
|
|
12
|
+
from .contracts import Effort, ModelTier
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
class CapabilityTier(StrEnum):
|
|
14
16
|
"""How a Provider receives a Role's declared Vendored Skills."""
|
|
@@ -48,9 +50,27 @@ class Config:
|
|
|
48
50
|
#: code's turns this on. See ADR-0024.
|
|
49
51
|
publish_pack_inventory: bool = False
|
|
50
52
|
|
|
53
|
+
#: Per-Provider overrides of the adapter's tier-to-model table, keyed by
|
|
54
|
+
#: provider name and then by tier. ADR-0004 promised this in its first
|
|
55
|
+
#: paragraph and nothing read it until 2026-09-03. A tier absent here keeps
|
|
56
|
+
#: the adapter's default, so a project pins the one tier it disagrees about
|
|
57
|
+
#: rather than restating all three.
|
|
58
|
+
provider_models: dict[str, dict[ModelTier, str]] = field(default_factory=dict)
|
|
59
|
+
|
|
60
|
+
#: Per-Role overrides of the two declared axes. The Role still never names a
|
|
61
|
+
#: model — it names a tier, and the Provider maps that. `roles.x.model` is
|
|
62
|
+
#: deliberately not a key: a model named per Role does not survive a release
|
|
63
|
+
#: and does not port across Providers, which is the whole of ADR-0004.
|
|
64
|
+
role_tiers: dict[str, ModelTier] = field(default_factory=dict)
|
|
65
|
+
role_efforts: dict[str, Effort] = field(default_factory=dict)
|
|
66
|
+
|
|
51
67
|
def capability_for(self, provider: str) -> CapabilityTier:
|
|
52
68
|
return self.provider_capabilities.get(provider, CapabilityTier.FRAGMENT)
|
|
53
69
|
|
|
70
|
+
def model_for(self, provider: str, tier: ModelTier) -> str | None:
|
|
71
|
+
"""The configured model for a tier, or None to keep the adapter's own."""
|
|
72
|
+
return self.provider_models.get(provider, {}).get(tier)
|
|
73
|
+
|
|
54
74
|
|
|
55
75
|
def load_config(root: Path | str) -> Config:
|
|
56
76
|
"""Read ``.agentforge/config.yaml``, or return documented defaults."""
|
|
@@ -60,17 +80,52 @@ def load_config(root: Path | str) -> Config:
|
|
|
60
80
|
|
|
61
81
|
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
62
82
|
capabilities = dict(DEFAULT_CAPABILITIES)
|
|
83
|
+
models: dict[str, dict[ModelTier, str]] = {}
|
|
63
84
|
for name, provider in (data.get("providers") or {}).items():
|
|
64
|
-
|
|
85
|
+
if "capability_tier" in provider:
|
|
86
|
+
capabilities[str(name)] = CapabilityTier(provider["capability_tier"])
|
|
87
|
+
if provider.get("models"):
|
|
88
|
+
models[str(name)] = {
|
|
89
|
+
ModelTier(tier): str(slug) for tier, slug in provider["models"].items()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
tiers, efforts = _role_overrides(data)
|
|
65
93
|
return Config(
|
|
66
94
|
provider_capabilities=capabilities,
|
|
67
95
|
test_suite=_test_suite(data),
|
|
68
96
|
publish_pack_inventory=bool(
|
|
69
97
|
(data.get("context") or {}).get("publish_inventory", False)
|
|
70
98
|
),
|
|
99
|
+
provider_models=models,
|
|
100
|
+
role_tiers=tiers,
|
|
101
|
+
role_efforts=efforts,
|
|
71
102
|
)
|
|
72
103
|
|
|
73
104
|
|
|
105
|
+
def _role_overrides(data: dict) -> tuple[dict[str, ModelTier], dict[str, Effort]]:
|
|
106
|
+
"""`roles.<name>.tier` and `roles.<name>.effort`, the two declared axes.
|
|
107
|
+
|
|
108
|
+
A `model` key here is refused rather than ignored. Silently dropping it
|
|
109
|
+
would leave a project believing it had pinned a model per Role, which reads
|
|
110
|
+
as working right up until a Provider changes — and the whole reason
|
|
111
|
+
ADR-0004 gives a Role a tier is that the failure is otherwise invisible.
|
|
112
|
+
"""
|
|
113
|
+
tiers: dict[str, ModelTier] = {}
|
|
114
|
+
efforts: dict[str, Effort] = {}
|
|
115
|
+
for name, role in (data.get("roles") or {}).items():
|
|
116
|
+
if "model" in role:
|
|
117
|
+
raise ValueError(
|
|
118
|
+
f"`roles.{name}.model` names a model per Role, which ADR-0004 "
|
|
119
|
+
f"does not allow; set `roles.{name}.tier` and override "
|
|
120
|
+
f"`providers.<name>.models.<tier>` if the mapping is wrong"
|
|
121
|
+
)
|
|
122
|
+
if "tier" in role:
|
|
123
|
+
tiers[str(name)] = ModelTier(role["tier"])
|
|
124
|
+
if "effort" in role:
|
|
125
|
+
efforts[str(name)] = Effort(role["effort"])
|
|
126
|
+
return tiers, efforts
|
|
127
|
+
|
|
128
|
+
|
|
74
129
|
def _test_suite(data: dict) -> tuple[str, ...]:
|
|
75
130
|
"""`gates.tests.suite`: what the test-suite Gate runs in this repository.
|
|
76
131
|
|
{agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/contracts.py
RENAMED
|
@@ -45,6 +45,28 @@ class ModelTier(StrEnum):
|
|
|
45
45
|
CHEAP = "cheap"
|
|
46
46
|
|
|
47
47
|
|
|
48
|
+
class Effort(StrEnum):
|
|
49
|
+
"""How hard a Role thinks, named by intent and independent of its tier.
|
|
50
|
+
|
|
51
|
+
The second axis ADR-0004 originally folded into the first. A Model Tier
|
|
52
|
+
chooses which model runs; an Effort chooses how much reasoning it spends
|
|
53
|
+
getting there, and the two are not the same purchase -- the Security Role
|
|
54
|
+
is the case that proves it, auditing at `standard` and thinking at `high`.
|
|
55
|
+
|
|
56
|
+
The levels are the intersection of what the shipped adapters' CLIs accept:
|
|
57
|
+
`claude --effort` takes low through max, and every slug in a real codex
|
|
58
|
+
install takes the same five. `ultra` is offered by one codex model alone
|
|
59
|
+
and is deliberately absent -- a level a Role could declare and most
|
|
60
|
+
Providers could not honor is not an intent-named level.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
LOW = "low"
|
|
64
|
+
MEDIUM = "medium"
|
|
65
|
+
HIGH = "high"
|
|
66
|
+
XHIGH = "xhigh"
|
|
67
|
+
MAX = "max"
|
|
68
|
+
|
|
69
|
+
|
|
48
70
|
class Outcome(StrEnum):
|
|
49
71
|
"""How an Agent finished.
|
|
50
72
|
|
|
@@ -278,11 +300,25 @@ class Role:
|
|
|
278
300
|
tier: ModelTier
|
|
279
301
|
instructions: str = ""
|
|
280
302
|
skills: tuple[str, ...] = ()
|
|
303
|
+
#: How much reasoning the Role spends, independent of which model runs it.
|
|
304
|
+
#: `medium` rather than a tier-derived value: a Role that has not thought
|
|
305
|
+
#: about the question gets the level both CLIs already default most models
|
|
306
|
+
#: to, and the ones that have thought about it say so.
|
|
307
|
+
effort: Effort = Effort.MEDIUM
|
|
281
308
|
|
|
282
309
|
def at_tier(self, tier: ModelTier) -> Role:
|
|
283
310
|
"""The same Role with its tier overridden, per user request or config."""
|
|
284
311
|
return replace(self, tier=tier)
|
|
285
312
|
|
|
313
|
+
def at_effort(self, effort: Effort) -> Role:
|
|
314
|
+
"""The same Role with its effort overridden, per config.
|
|
315
|
+
|
|
316
|
+
Separate from `at_tier` because the axes move separately -- overriding
|
|
317
|
+
one has never implied anything about the other, which is the whole
|
|
318
|
+
reason there are two.
|
|
319
|
+
"""
|
|
320
|
+
return replace(self, effort=effort)
|
|
321
|
+
|
|
286
322
|
|
|
287
323
|
@dataclass(frozen=True)
|
|
288
324
|
class Roster:
|
{agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/core/runtime.py
RENAMED
|
@@ -482,9 +482,18 @@ class Forge:
|
|
|
482
482
|
),
|
|
483
483
|
)
|
|
484
484
|
role = resolve_role(step.role)
|
|
485
|
+
# Effort is the Role's own axis, so it is settled here once and
|
|
486
|
+
# never enters the tier precedence chain below — the two are
|
|
487
|
+
# overridden independently or the split means nothing.
|
|
488
|
+
if role.name in config.role_efforts:
|
|
489
|
+
role = role.at_effort(config.role_efforts[role.name])
|
|
485
490
|
at = overrides.get(
|
|
486
491
|
role.name,
|
|
487
|
-
tier
|
|
492
|
+
tier
|
|
493
|
+
or step.tier
|
|
494
|
+
or chosen.get(role.name)
|
|
495
|
+
or config.role_tiers.get(role.name)
|
|
496
|
+
or role.tier,
|
|
488
497
|
)
|
|
489
498
|
# Derived from the Run Log rather than enumerated, because a
|
|
490
499
|
# resumed Run starts partway through and would otherwise tell a
|
{agentforge_framework-0.2.3 → agentforge_framework-0.2.4}/src/agentforge_framework/providers/base.py
RENAMED
|
@@ -27,6 +27,7 @@ from ..core.config import CapabilityTier, Config
|
|
|
27
27
|
from ..core.contracts import (
|
|
28
28
|
AgentResult,
|
|
29
29
|
ContextPack,
|
|
30
|
+
Effort,
|
|
30
31
|
Finding,
|
|
31
32
|
ModelTier,
|
|
32
33
|
Outcome,
|
|
@@ -111,7 +112,8 @@ class CliProvider(Provider):
|
|
|
111
112
|
self.runner = runner
|
|
112
113
|
self.timeout = timeout
|
|
113
114
|
self.allow_commands = allow_commands
|
|
114
|
-
self.
|
|
115
|
+
self.config = config or Config()
|
|
116
|
+
self.capability_tier = self.config.capability_for(self.name)
|
|
115
117
|
|
|
116
118
|
def preflight(self) -> None:
|
|
117
119
|
try:
|
|
@@ -125,6 +127,16 @@ class CliProvider(Provider):
|
|
|
125
127
|
raise ProviderError(str(exc)) from exc
|
|
126
128
|
|
|
127
129
|
def model_for(self, tier: ModelTier) -> str:
|
|
130
|
+
"""The project's model for this tier, or the adapter's own.
|
|
131
|
+
|
|
132
|
+
Configuration wins, which is ADR-0004's first paragraph finally doing
|
|
133
|
+
something: a project whose account cannot reach the pinned model, or
|
|
134
|
+
which reads the three tiers differently, says so in a file rather than
|
|
135
|
+
editing an adapter it does not own.
|
|
136
|
+
"""
|
|
137
|
+
configured = self.config.model_for(self.name, tier)
|
|
138
|
+
if configured:
|
|
139
|
+
return configured
|
|
128
140
|
try:
|
|
129
141
|
return self.models[tier]
|
|
130
142
|
except KeyError as exc:
|
|
@@ -133,8 +145,19 @@ class CliProvider(Provider):
|
|
|
133
145
|
) from exc
|
|
134
146
|
|
|
135
147
|
@abstractmethod
|
|
136
|
-
def build_argv(
|
|
137
|
-
|
|
148
|
+
def build_argv(
|
|
149
|
+
self,
|
|
150
|
+
model: str,
|
|
151
|
+
effort: Effort,
|
|
152
|
+
native_skills: tuple[str, ...] = (),
|
|
153
|
+
) -> Sequence[str]:
|
|
154
|
+
"""The invocation, without the prompt. See `invoke` for why it is absent.
|
|
155
|
+
|
|
156
|
+
Both axes arrive resolved: `model` is what `model_for` made of the tier,
|
|
157
|
+
and `effort` is what the Role declared. An adapter whose CLI exposes no
|
|
158
|
+
effort flag drops it, the same way one with no model flag collapses the
|
|
159
|
+
tiers — ADR-0004's coarse-instrument consequence, on a second axis.
|
|
160
|
+
"""
|
|
138
161
|
...
|
|
139
162
|
|
|
140
163
|
@abstractmethod
|
|
@@ -161,7 +184,7 @@ class CliProvider(Provider):
|
|
|
161
184
|
time a prompt landed the other side of it.
|
|
162
185
|
"""
|
|
163
186
|
prompt, native_skills = self._deliver_skills(role, prompt)
|
|
164
|
-
argv = self.build_argv(self.model_for(tier), native_skills)
|
|
187
|
+
argv = self.build_argv(self.model_for(tier), role.effort, native_skills)
|
|
165
188
|
completed = self.runner.run(argv, cwd=cwd, stdin=prompt, timeout=self.timeout)
|
|
166
189
|
output = self.parse_output(completed)
|
|
167
190
|
return to_agent_result(role=role, tier=tier, output=output)
|