agentforge-py 0.2.1__py3-none-any.whl
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/__init__.py +114 -0
- agentforge/_testing/__init__.py +19 -0
- agentforge/_testing/fake_llm.py +126 -0
- agentforge/_testing/fake_tool.py +122 -0
- agentforge/_tools/__init__.py +14 -0
- agentforge/_tools/calculator.py +102 -0
- agentforge/_tools/decorator.py +300 -0
- agentforge/_tools/file_read.py +112 -0
- agentforge/_tools/shell.py +134 -0
- agentforge/_tools/web_search.py +207 -0
- agentforge/agent.py +817 -0
- agentforge/auth.py +42 -0
- agentforge/cli/__init__.py +18 -0
- agentforge/cli/_build.py +323 -0
- agentforge/cli/_scaffold_state.py +250 -0
- agentforge/cli/_shared_scaffold.py +174 -0
- agentforge/cli/config_cmd.py +174 -0
- agentforge/cli/db_cmd.py +262 -0
- agentforge/cli/debug_cmd.py +168 -0
- agentforge/cli/docs_cmd.py +217 -0
- agentforge/cli/eval_cmd.py +181 -0
- agentforge/cli/health_cmd.py +139 -0
- agentforge/cli/list_modules.py +85 -0
- agentforge/cli/main.py +81 -0
- agentforge/cli/manifest_apply.py +368 -0
- agentforge/cli/module_cmd.py +247 -0
- agentforge/cli/new_cmd.py +171 -0
- agentforge/cli/run_cmd.py +234 -0
- agentforge/cli/upgrade_cmd.py +230 -0
- agentforge/config/__init__.py +45 -0
- agentforge/eval/__init__.py +18 -0
- agentforge/eval/consistency.py +107 -0
- agentforge/eval/coverage.py +100 -0
- agentforge/eval/format_compliance.py +107 -0
- agentforge/eval/regression.py +143 -0
- agentforge/findings.py +166 -0
- agentforge/guardrails/__init__.py +32 -0
- agentforge/guardrails/allowlist.py +49 -0
- agentforge/guardrails/capability_check.py +58 -0
- agentforge/guardrails/engine.py +289 -0
- agentforge/guardrails/pii_redact_basic.py +61 -0
- agentforge/guardrails/prompt_injection_basic.py +90 -0
- agentforge/memory/__init__.py +16 -0
- agentforge/memory/in_memory.py +130 -0
- agentforge/memory/in_memory_graph.py +262 -0
- agentforge/memory/in_memory_vector.py +167 -0
- agentforge/pipeline/__init__.py +26 -0
- agentforge/pipeline/engine.py +189 -0
- agentforge/pipeline/errors.py +19 -0
- agentforge/pipeline/tool.py +93 -0
- agentforge/py.typed +0 -0
- agentforge/recording.py +189 -0
- agentforge/renderers/__init__.py +28 -0
- agentforge/renderers/_defaults.py +32 -0
- agentforge/renderers/markdown.py +44 -0
- agentforge/renderers/patch_applier.py +46 -0
- agentforge/renderers/registry.py +108 -0
- agentforge/renderers/scorecard.py +59 -0
- agentforge/renderers/span_table.py +71 -0
- agentforge/replay.py +260 -0
- agentforge/resolver_register.py +41 -0
- agentforge/retrieval.py +410 -0
- agentforge/runtime.py +63 -0
- agentforge/strategies/__init__.py +27 -0
- agentforge/strategies/_base.py +280 -0
- agentforge/strategies/_plan.py +93 -0
- agentforge/strategies/multi_agent.py +541 -0
- agentforge/strategies/plan_execute.py +506 -0
- agentforge/strategies/react.py +237 -0
- agentforge/strategies/tot.py +472 -0
- agentforge/templates/_shared/.cursorrules +12 -0
- agentforge/templates/_shared/.github/copilot-instructions.md +13 -0
- agentforge/templates/_shared/.gitkeep +0 -0
- agentforge/templates/_shared/AGENTS.md.tmpl +123 -0
- agentforge/templates/_shared/CLAUDE.md +13 -0
- agentforge/templates/_shared/docs/runbooks/01-set-up-new-agent.md.tmpl +67 -0
- agentforge/templates/_shared/docs/runbooks/02-add-a-tool.md +67 -0
- agentforge/templates/_shared/docs/runbooks/03-add-a-pipeline-task.md +69 -0
- agentforge/templates/_shared/docs/runbooks/04-pick-reasoning-strategy.md +67 -0
- agentforge/templates/_shared/docs/runbooks/05-write-prompts.md +75 -0
- agentforge/templates/_shared/docs/runbooks/06-test-your-agent.md +75 -0
- agentforge/templates/_shared/docs/runbooks/07-debug-a-run.md +70 -0
- agentforge/templates/_shared/docs/runbooks/08-add-memory.md +75 -0
- agentforge/templates/_shared/docs/runbooks/09-add-mcp.md +78 -0
- agentforge/templates/_shared/docs/runbooks/10-add-evaluators.md +76 -0
- agentforge/templates/_shared/docs/runbooks/11-add-safety-guardrails.md +83 -0
- agentforge/templates/_shared/docs/runbooks/12-add-observability.md +77 -0
- agentforge/templates/_shared/docs/runbooks/13-configure-multi-provider.md +91 -0
- agentforge/templates/_shared/docs/runbooks/14-deploy-your-agent.md +70 -0
- agentforge/templates/_shared/docs/runbooks/15-upgrade-your-agent.md +67 -0
- agentforge/templates/_shared/docs/runbooks/16-configuration-reference.md +81 -0
- agentforge/templates/_shared/docs/runbooks/17-add-reranker.md +78 -0
- agentforge/templates/_shared/docs/runbooks/18-add-hybrid-search.md +78 -0
- agentforge/templates/_shared/docs/runbooks/19-add-graphrag.md +83 -0
- agentforge/templates/_shared/docs/runbooks/20-apply-schema-migrations.md +92 -0
- agentforge/templates/_shared/docs/runbooks/21-use-streaming-guardrails.md +82 -0
- agentforge/templates/_shared/docs/runbooks/README.md.tmpl +68 -0
- agentforge/templates/code-reviewer/.env.example +8 -0
- agentforge/templates/code-reviewer/.gitignore +7 -0
- agentforge/templates/code-reviewer/README.md +12 -0
- agentforge/templates/code-reviewer/agentforge.yaml +23 -0
- agentforge/templates/code-reviewer/copier.yml +34 -0
- agentforge/templates/code-reviewer/pyproject.toml +18 -0
- agentforge/templates/code-reviewer/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/code-reviewer/src/{{project_slug.replace('-', '_')}}/main.py +32 -0
- agentforge/templates/docs-qa/.env.example +8 -0
- agentforge/templates/docs-qa/.gitignore +7 -0
- agentforge/templates/docs-qa/README.md +14 -0
- agentforge/templates/docs-qa/agentforge.yaml +19 -0
- agentforge/templates/docs-qa/copier.yml +31 -0
- agentforge/templates/docs-qa/pyproject.toml +18 -0
- agentforge/templates/docs-qa/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/docs-qa/src/{{project_slug.replace('-', '_')}}/main.py +32 -0
- agentforge/templates/minimal/.env.example +11 -0
- agentforge/templates/minimal/.gitignore +10 -0
- agentforge/templates/minimal/README.md +28 -0
- agentforge/templates/minimal/agentforge.yaml +10 -0
- agentforge/templates/minimal/copier.yml +52 -0
- agentforge/templates/minimal/pyproject.toml +18 -0
- agentforge/templates/minimal/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/minimal/src/{{project_slug.replace('-', '_')}}/main.py +34 -0
- agentforge/templates/patch-bot/.env.example +8 -0
- agentforge/templates/patch-bot/.gitignore +7 -0
- agentforge/templates/patch-bot/README.md +13 -0
- agentforge/templates/patch-bot/agentforge.yaml +15 -0
- agentforge/templates/patch-bot/copier.yml +31 -0
- agentforge/templates/patch-bot/pyproject.toml +18 -0
- agentforge/templates/patch-bot/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/patch-bot/src/{{project_slug.replace('-', '_')}}/main.py +32 -0
- agentforge/templates/research/.env.example +8 -0
- agentforge/templates/research/.gitignore +7 -0
- agentforge/templates/research/README.md +14 -0
- agentforge/templates/research/agentforge.yaml +17 -0
- agentforge/templates/research/copier.yml +31 -0
- agentforge/templates/research/pyproject.toml +18 -0
- agentforge/templates/research/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/research/src/{{project_slug.replace('-', '_')}}/main.py +31 -0
- agentforge/templates/triage/.env.example +8 -0
- agentforge/templates/triage/.gitignore +7 -0
- agentforge/templates/triage/README.md +14 -0
- agentforge/templates/triage/agentforge.yaml +25 -0
- agentforge/templates/triage/copier.yml +31 -0
- agentforge/templates/triage/pyproject.toml +18 -0
- agentforge/templates/triage/src/{{project_slug.replace('-', '_')}}/__init__.py +5 -0
- agentforge/templates/triage/src/{{project_slug.replace('-', '_')}}/main.py +30 -0
- agentforge/testing/__init__.py +69 -0
- agentforge/testing/conformance.py +40 -0
- agentforge/testing/factory.py +89 -0
- agentforge/testing/fixtures.py +42 -0
- agentforge/testing/llm.py +235 -0
- agentforge/testing/recording.py +177 -0
- agentforge/tools/__init__.py +41 -0
- agentforge_py-0.2.1.dist-info/METADATA +158 -0
- agentforge_py-0.2.1.dist-info/RECORD +157 -0
- agentforge_py-0.2.1.dist-info/WHEEL +4 -0
- agentforge_py-0.2.1.dist-info/entry_points.txt +2 -0
- agentforge_py-0.2.1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Entry point for {{ project_name }}.
|
|
2
|
+
|
|
3
|
+
Docs / source Q&A. Wires `file_read` + `web_search` so the agent
|
|
4
|
+
can pull both local docs and external context. Outputs
|
|
5
|
+
`NarrativeFinding`s (feat-008).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
from agentforge import Agent
|
|
14
|
+
from agentforge.tools import file_read, web_search
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def run_agent(task: str) -> str:
|
|
18
|
+
async with Agent(tools=[file_read, web_search]) as agent:
|
|
19
|
+
result = await agent.run(task)
|
|
20
|
+
return str(result.output)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> None:
|
|
24
|
+
if len(sys.argv) < 2:
|
|
25
|
+
print('Usage: python -m {{ project_slug | replace("-", "_") }} "<question>"')
|
|
26
|
+
sys.exit(1)
|
|
27
|
+
output = asyncio.run(run_agent(" ".join(sys.argv[1:])))
|
|
28
|
+
print(output)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Environment variables for {{ project_name }}.
|
|
2
|
+
# Copy this file to `.env` and fill in real values.
|
|
3
|
+
|
|
4
|
+
{% if llm_provider == 'bedrock' -%}
|
|
5
|
+
# AWS Bedrock credentials (or use AWS_PROFILE / instance role).
|
|
6
|
+
AWS_REGION=us-east-1
|
|
7
|
+
{% elif llm_provider == 'anthropic' -%}
|
|
8
|
+
ANTHROPIC_API_KEY=
|
|
9
|
+
{% else -%}
|
|
10
|
+
OPENAI_API_KEY=
|
|
11
|
+
{% endif %}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
{{ description }}
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
cp .env.example .env
|
|
10
|
+
# Fill in credentials in .env, then:
|
|
11
|
+
python -m {{ project_slug | replace('-', '_') }} "your task here"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
`agentforge.yaml` is the agent's wiring — model, budget, modules.
|
|
17
|
+
See `agentforge config show` for the resolved config and
|
|
18
|
+
`agentforge config validate` to check it.
|
|
19
|
+
|
|
20
|
+
## Upgrades
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
agentforge upgrade
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Pulls in framework updates while preserving your customisations.
|
|
27
|
+
See `agentforge status` for what's managed-by-the-framework vs
|
|
28
|
+
forked-by-you.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
name: "{{ project_slug }}"
|
|
3
|
+
model: "{% if llm_provider == 'bedrock' %}bedrock:us.anthropic.claude-sonnet-4-5-20250929{% elif llm_provider == 'anthropic' %}anthropic:claude-sonnet-4-5{% else %}openai:gpt-4o{% endif %}"
|
|
4
|
+
budget:
|
|
5
|
+
usd: 2.0
|
|
6
|
+
max_iterations: 25
|
|
7
|
+
|
|
8
|
+
logging:
|
|
9
|
+
level: "INFO"
|
|
10
|
+
format: "text"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copier template: minimal AgentForge agent (feat-011).
|
|
2
|
+
#
|
|
3
|
+
# Simplest working starter: one Agent, one tool, one test. No
|
|
4
|
+
# persistence, no evaluators, no observability. Good for proofs of
|
|
5
|
+
# concept and for learning what a working agent looks like.
|
|
6
|
+
|
|
7
|
+
_min_copier_version: "9.4.0"
|
|
8
|
+
|
|
9
|
+
# Render the answer file so `agentforge upgrade` knows what to ask.
|
|
10
|
+
_answers_file: ".agentforge-state/answers.yml"
|
|
11
|
+
|
|
12
|
+
# Render every file's content as a Jinja template (Cookiecutter-
|
|
13
|
+
# style). Default (templates_suffix=".jinja") would force every
|
|
14
|
+
# file to be named `foo.py.jinja`, which is ugly.
|
|
15
|
+
_templates_suffix: ""
|
|
16
|
+
|
|
17
|
+
# No `_subdirectory` — template files live at the root and render
|
|
18
|
+
# directly into the destination directory. The CLI passes
|
|
19
|
+
# `dst_path = ./<project_slug>` so the rendered output has a clean
|
|
20
|
+
# project root.
|
|
21
|
+
|
|
22
|
+
project_name:
|
|
23
|
+
type: str
|
|
24
|
+
help: "Human-readable project name (e.g. 'My PR Reviewer')."
|
|
25
|
+
default: "My Agent"
|
|
26
|
+
|
|
27
|
+
project_slug:
|
|
28
|
+
type: str
|
|
29
|
+
help: "Python package + directory name (kebab-case-ok, becomes snake_case in Python imports)."
|
|
30
|
+
default: "my-agent"
|
|
31
|
+
validator: >-
|
|
32
|
+
{% if not (project_slug | regex_search('^[a-z][a-z0-9-]*$')) %}
|
|
33
|
+
Must be lowercase alphanumeric + dashes, starting with a letter.
|
|
34
|
+
{% endif %}
|
|
35
|
+
|
|
36
|
+
llm_provider:
|
|
37
|
+
type: str
|
|
38
|
+
help: "Which LLM provider to use?"
|
|
39
|
+
choices:
|
|
40
|
+
Bedrock (AWS): bedrock
|
|
41
|
+
Anthropic (direct): anthropic
|
|
42
|
+
OpenAI: openai
|
|
43
|
+
default: bedrock
|
|
44
|
+
|
|
45
|
+
description:
|
|
46
|
+
type: str
|
|
47
|
+
help: "One-line description of the agent."
|
|
48
|
+
default: "An AgentForge agent."
|
|
49
|
+
|
|
50
|
+
# Template metadata pulled into the lock-file marker header by the
|
|
51
|
+
# `agentforge new` CLI after Copier finishes rendering.
|
|
52
|
+
_template_name: "minimal"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_slug }}"
|
|
3
|
+
version = "0.0.0"
|
|
4
|
+
description = "{{ description }}"
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"agentforge-py",
|
|
8
|
+
{%- if llm_provider == 'bedrock' %}
|
|
9
|
+
"agentforge-bedrock",
|
|
10
|
+
{%- endif %}
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[build-system]
|
|
14
|
+
requires = ["hatchling>=1.27"]
|
|
15
|
+
build-backend = "hatchling.build"
|
|
16
|
+
|
|
17
|
+
[tool.hatch.build.targets.wheel]
|
|
18
|
+
packages = ["src/{{ project_slug | replace('-', '_') }}"]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Entry point for {{ project_name }}.
|
|
2
|
+
|
|
3
|
+
Edit this file to add tools, prompts, evaluators, etc. The
|
|
4
|
+
`Agent` constructor surface is feat-001's locked Public API — see
|
|
5
|
+
`docs/features/feat-001-core-contracts-and-agent.md` in the
|
|
6
|
+
agentforge-py repo for every kwarg.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
from agentforge import Agent
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def run_agent(task: str) -> str:
|
|
18
|
+
"""Run the agent against `task` and return its output."""
|
|
19
|
+
async with Agent() as agent:
|
|
20
|
+
result = await agent.run(task)
|
|
21
|
+
return str(result.output)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main() -> None:
|
|
25
|
+
if len(sys.argv) < 2:
|
|
26
|
+
print('Usage: python -m {{ project_slug | replace("-", "_") }} "<task>"')
|
|
27
|
+
sys.exit(1)
|
|
28
|
+
task = " ".join(sys.argv[1:])
|
|
29
|
+
output = asyncio.run(run_agent(task))
|
|
30
|
+
print(output)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
main()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
{{ description }} Emits `PatchFinding`s — structured unified diffs
|
|
4
|
+
with rationale + confidence — for downstream consumers to apply.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
uv sync
|
|
8
|
+
cp .env.example .env
|
|
9
|
+
python -m {{ project_slug | replace('-', '_') }} "replace deprecated time.clock() in src/"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The agent does NOT apply the patches itself — the consumer (CI
|
|
13
|
+
bot, codemod script, etc.) reads `result.findings` and decides.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
name: "{{ project_slug }}"
|
|
3
|
+
model: "{% if llm_provider == 'bedrock' %}bedrock:us.anthropic.claude-sonnet-4-5-20250929{% elif llm_provider == 'anthropic' %}anthropic:claude-sonnet-4-5{% else %}openai:gpt-4o{% endif %}"
|
|
4
|
+
system_prompt: |
|
|
5
|
+
You generate patches. For each fix, emit a `PatchFinding` with
|
|
6
|
+
a unified-diff `patch`, a one-line `rationale`, and a
|
|
7
|
+
`confidence` in [0, 1]. Only return patches you can defend with
|
|
8
|
+
evidence from the source.
|
|
9
|
+
budget:
|
|
10
|
+
usd: 5.0
|
|
11
|
+
max_iterations: 40
|
|
12
|
+
|
|
13
|
+
logging:
|
|
14
|
+
level: "INFO"
|
|
15
|
+
format: "text"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copier template: patch-bot agent (feat-011).
|
|
2
|
+
#
|
|
3
|
+
# Emits PatchFinding — structured diffs with rationale and
|
|
4
|
+
# confidence. Use for codemod / auto-fix workflows where the
|
|
5
|
+
# downstream consumer applies the patch.
|
|
6
|
+
|
|
7
|
+
_min_copier_version: "9.4.0"
|
|
8
|
+
_answers_file: ".agentforge-state/answers.yml"
|
|
9
|
+
_templates_suffix: ""
|
|
10
|
+
|
|
11
|
+
project_name:
|
|
12
|
+
type: str
|
|
13
|
+
default: "Patch Bot"
|
|
14
|
+
|
|
15
|
+
project_slug:
|
|
16
|
+
type: str
|
|
17
|
+
default: "patch-bot"
|
|
18
|
+
|
|
19
|
+
llm_provider:
|
|
20
|
+
type: str
|
|
21
|
+
choices:
|
|
22
|
+
Bedrock (AWS): bedrock
|
|
23
|
+
Anthropic (direct): anthropic
|
|
24
|
+
OpenAI: openai
|
|
25
|
+
default: bedrock
|
|
26
|
+
|
|
27
|
+
description:
|
|
28
|
+
type: str
|
|
29
|
+
default: "A patch-emitting AgentForge agent."
|
|
30
|
+
|
|
31
|
+
_template_name: "patch-bot"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_slug }}"
|
|
3
|
+
version = "0.0.0"
|
|
4
|
+
description = "{{ description }}"
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"agentforge-py",
|
|
8
|
+
{%- if llm_provider == 'bedrock' %}
|
|
9
|
+
"agentforge-bedrock",
|
|
10
|
+
{%- endif %}
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[build-system]
|
|
14
|
+
requires = ["hatchling>=1.27"]
|
|
15
|
+
build-backend = "hatchling.build"
|
|
16
|
+
|
|
17
|
+
[tool.hatch.build.targets.wheel]
|
|
18
|
+
packages = ["src/{{ project_slug | replace('-', '_') }}"]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Entry point for {{ project_name }}.
|
|
2
|
+
|
|
3
|
+
Emits PatchFinding (feat-008) — structured unified diffs with
|
|
4
|
+
rationale + confidence. Tools include `file_read` so the bot can
|
|
5
|
+
pull source context before proposing a patch.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import asyncio
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
from agentforge import Agent
|
|
14
|
+
from agentforge.tools import file_read
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def run_agent(task: str) -> str:
|
|
18
|
+
async with Agent(tools=[file_read]) as agent:
|
|
19
|
+
result = await agent.run(task)
|
|
20
|
+
return str(result.output)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> None:
|
|
24
|
+
if len(sys.argv) < 2:
|
|
25
|
+
print('Usage: python -m {{ project_slug | replace("-", "_") }} "<task>"')
|
|
26
|
+
sys.exit(1)
|
|
27
|
+
output = asyncio.run(run_agent(" ".join(sys.argv[1:])))
|
|
28
|
+
print(output)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
main()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
{{ description }} Open-ended research with citations. Uses the
|
|
4
|
+
Plan-Execute strategy + web_search to break a complex question
|
|
5
|
+
into sub-tasks, then synthesises a `NarrativeFinding`.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
cp .env.example .env
|
|
10
|
+
python -m {{ project_slug | replace('-', '_') }} "what changed in claude-sonnet 4.5 vs 4.7?"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Defaults to `web_search` (DuckDuckGo HTML scrape). Replace with a
|
|
14
|
+
serper / tavily backend by passing `search_fn=` to `WebSearchTool`.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
name: "{{ project_slug }}"
|
|
3
|
+
model: "{% if llm_provider == 'bedrock' %}bedrock:us.anthropic.claude-sonnet-4-5-20250929{% elif llm_provider == 'anthropic' %}anthropic:claude-sonnet-4-5{% else %}openai:gpt-4o{% endif %}"
|
|
4
|
+
strategy: "plan-execute"
|
|
5
|
+
system_prompt: |
|
|
6
|
+
You answer open-ended research questions. Plan the sub-tasks,
|
|
7
|
+
execute them (use web_search liberally), then synthesise into a
|
|
8
|
+
NarrativeFinding: `body` is the markdown answer; `references`
|
|
9
|
+
is every URL you actually used. Don't cite sources you didn't
|
|
10
|
+
open.
|
|
11
|
+
budget:
|
|
12
|
+
usd: 5.0
|
|
13
|
+
max_iterations: 50
|
|
14
|
+
|
|
15
|
+
logging:
|
|
16
|
+
level: "INFO"
|
|
17
|
+
format: "text"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copier template: research agent (feat-011).
|
|
2
|
+
#
|
|
3
|
+
# Long-form research with citations. Uses Plan-Execute strategy for
|
|
4
|
+
# multi-step questions, web_search for sources, NarrativeFinding for
|
|
5
|
+
# the output shape.
|
|
6
|
+
|
|
7
|
+
_min_copier_version: "9.4.0"
|
|
8
|
+
_answers_file: ".agentforge-state/answers.yml"
|
|
9
|
+
_templates_suffix: ""
|
|
10
|
+
|
|
11
|
+
project_name:
|
|
12
|
+
type: str
|
|
13
|
+
default: "Research Agent"
|
|
14
|
+
|
|
15
|
+
project_slug:
|
|
16
|
+
type: str
|
|
17
|
+
default: "research-agent"
|
|
18
|
+
|
|
19
|
+
llm_provider:
|
|
20
|
+
type: str
|
|
21
|
+
choices:
|
|
22
|
+
Bedrock (AWS): bedrock
|
|
23
|
+
Anthropic (direct): anthropic
|
|
24
|
+
OpenAI: openai
|
|
25
|
+
default: bedrock
|
|
26
|
+
|
|
27
|
+
description:
|
|
28
|
+
type: str
|
|
29
|
+
default: "A research AgentForge agent."
|
|
30
|
+
|
|
31
|
+
_template_name: "research"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_slug }}"
|
|
3
|
+
version = "0.0.0"
|
|
4
|
+
description = "{{ description }}"
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"agentforge-py",
|
|
8
|
+
{%- if llm_provider == 'bedrock' %}
|
|
9
|
+
"agentforge-bedrock",
|
|
10
|
+
{%- endif %}
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[build-system]
|
|
14
|
+
requires = ["hatchling>=1.27"]
|
|
15
|
+
build-backend = "hatchling.build"
|
|
16
|
+
|
|
17
|
+
[tool.hatch.build.targets.wheel]
|
|
18
|
+
packages = ["src/{{ project_slug | replace('-', '_') }}"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Entry point for {{ project_name }}.
|
|
2
|
+
|
|
3
|
+
Research with citations. Plan-Execute strategy + web_search.
|
|
4
|
+
Outputs NarrativeFinding (feat-008).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
from agentforge import Agent
|
|
13
|
+
from agentforge.tools import web_search
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def run_agent(question: str) -> str:
|
|
17
|
+
async with Agent(tools=[web_search]) as agent:
|
|
18
|
+
result = await agent.run(question)
|
|
19
|
+
return str(result.output)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def main() -> None:
|
|
23
|
+
if len(sys.argv) < 2:
|
|
24
|
+
print('Usage: python -m {{ project_slug | replace("-", "_") }} "<research question>"')
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
output = asyncio.run(run_agent(" ".join(sys.argv[1:])))
|
|
27
|
+
print(output)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if __name__ == "__main__":
|
|
31
|
+
main()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# {{ project_name }}
|
|
2
|
+
|
|
3
|
+
{{ description }} Classifies incoming items by severity + category.
|
|
4
|
+
Uses Haiku-tier models — triage is high-volume; the smaller model
|
|
5
|
+
keeps cost bounded.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
cp .env.example .env
|
|
10
|
+
python -m {{ project_slug | replace('-', '_') }} "triage this issue text..."
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Add a `Coverage` evaluator with a known-issue reference set to
|
|
14
|
+
score how completely the agent classifies a batch.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
agent:
|
|
2
|
+
name: "{{ project_slug }}"
|
|
3
|
+
model: "{% if llm_provider == 'bedrock' %}bedrock:us.anthropic.claude-haiku-4-5{% elif llm_provider == 'anthropic' %}anthropic:claude-haiku-4-5{% else %}openai:gpt-4o-mini{% endif %}"
|
|
4
|
+
system_prompt: |
|
|
5
|
+
You triage incoming issues / tickets / alerts. For each item
|
|
6
|
+
emit a `SimpleFinding` with `severity` in
|
|
7
|
+
{critical, warning, suggestion, info}, a one-word `category`,
|
|
8
|
+
a one-line `message`, and an actionable `recommendation`.
|
|
9
|
+
Classify, don't speculate.
|
|
10
|
+
budget:
|
|
11
|
+
usd: 1.0
|
|
12
|
+
max_iterations: 15
|
|
13
|
+
|
|
14
|
+
# Pair with a Coverage evaluator once you have a known-issue
|
|
15
|
+
# reference set:
|
|
16
|
+
#
|
|
17
|
+
# modules:
|
|
18
|
+
# evaluators:
|
|
19
|
+
# - name: coverage
|
|
20
|
+
# config:
|
|
21
|
+
# reference: ["security-issue-1", "perf-issue-2", ...]
|
|
22
|
+
|
|
23
|
+
logging:
|
|
24
|
+
level: "INFO"
|
|
25
|
+
format: "text"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copier template: triage agent (feat-011).
|
|
2
|
+
#
|
|
3
|
+
# Classifies incoming issues / tickets / alerts by severity +
|
|
4
|
+
# category. Emits SimpleFinding per item; pairs well with a
|
|
5
|
+
# Coverage evaluator against a known-issue set.
|
|
6
|
+
|
|
7
|
+
_min_copier_version: "9.4.0"
|
|
8
|
+
_answers_file: ".agentforge-state/answers.yml"
|
|
9
|
+
_templates_suffix: ""
|
|
10
|
+
|
|
11
|
+
project_name:
|
|
12
|
+
type: str
|
|
13
|
+
default: "Triage"
|
|
14
|
+
|
|
15
|
+
project_slug:
|
|
16
|
+
type: str
|
|
17
|
+
default: "triage"
|
|
18
|
+
|
|
19
|
+
llm_provider:
|
|
20
|
+
type: str
|
|
21
|
+
choices:
|
|
22
|
+
Bedrock (AWS): bedrock
|
|
23
|
+
Anthropic (direct): anthropic
|
|
24
|
+
OpenAI: openai
|
|
25
|
+
default: bedrock
|
|
26
|
+
|
|
27
|
+
description:
|
|
28
|
+
type: str
|
|
29
|
+
default: "A triage AgentForge agent."
|
|
30
|
+
|
|
31
|
+
_template_name: "triage"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "{{ project_slug }}"
|
|
3
|
+
version = "0.0.0"
|
|
4
|
+
description = "{{ description }}"
|
|
5
|
+
requires-python = ">=3.13"
|
|
6
|
+
dependencies = [
|
|
7
|
+
"agentforge-py",
|
|
8
|
+
{%- if llm_provider == 'bedrock' %}
|
|
9
|
+
"agentforge-bedrock",
|
|
10
|
+
{%- endif %}
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[build-system]
|
|
14
|
+
requires = ["hatchling>=1.27"]
|
|
15
|
+
build-backend = "hatchling.build"
|
|
16
|
+
|
|
17
|
+
[tool.hatch.build.targets.wheel]
|
|
18
|
+
packages = ["src/{{ project_slug | replace('-', '_') }}"]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Entry point for {{ project_name }}.
|
|
2
|
+
|
|
3
|
+
Triage: classify incoming items into severity + category. No
|
|
4
|
+
external tools by default — the agent works from the text alone.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
from agentforge import Agent
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def run_agent(item: str) -> str:
|
|
16
|
+
async with Agent() as agent:
|
|
17
|
+
result = await agent.run(item)
|
|
18
|
+
return str(result.output)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main() -> None:
|
|
22
|
+
if len(sys.argv) < 2:
|
|
23
|
+
print('Usage: python -m {{ project_slug | replace("-", "_") }} "<item to triage>"')
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
output = asyncio.run(run_agent(" ".join(sys.argv[1:])))
|
|
26
|
+
print(output)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == "__main__":
|
|
30
|
+
main()
|