diff --git a/CHANGELOG.md b/CHANGELOG.md index f41c3fe..3b8ed94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **Docs sync (post–#12)** — INDEX, ROADMAP, integration guides, follow-ups backlog, OTel/observer sections aligned with PR #43 closure ([#41](https://github.com/ARPAHLS/aura/issues/41), [#22](https://github.com/ARPAHLS/aura/issues/22)). - +- **Examples layout** — examples use a flat top-level script layout ([#21](https://github.com/ARPAHLS/aura/issues/21)). - **Example 06** — compress step skips when scan `is_safe` is false (sequencer `when`). - **PR CI** — `lint-test` now covers Python 3.10–3.13 on Ubuntu (`fail-fast`); publish remains a 3.12 release gate ([GH #10](https://github.com/ARPAHLS/aura/issues/10)). - **`AgentRegistry.update_profile`** — registry ref/alias maps stay consistent when `agent_ref` changes. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d449201..1d9fb64 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -158,7 +158,7 @@ Pure internal refactors with no user-visible effect may omit CHANGELOG; ask on t | Skillware host / egress | `integrations/skillware/` (when shipped), `docs/skillware-integration.md` redirect, CHANGELOG | | Integration example (Ollama, API, framework) | `integrations//`, `docs/integrations/README.md`, `.env.example`, CHANGELOG | | CLI commands or flags | `docs/getting-started.md`, `README.md` quick start line, `docs/outputs.md` (export/compare shapes), CHANGELOG | -| New core example | `examples/README.md`, optional link from `docs/getting-started.md` | +| New core example | Flat script in `examples/`, `examples/README.md`, optional link from `docs/getting-started.md` | | Architecture terminology | `docs/architecture.md`, `README.md` diagrams (keep in sync) | | Release / PyPI behavior | `docs/PUBLISHING.md`, `.github/workflows/publish-pypi.yml`, CHANGELOG | | PR CI workflow | `.github/workflows/ci.yml`, `docs/TESTING.md`, `CONTRIBUTING.md`; keep publish test job in sync | diff --git a/docs/INDEX.md b/docs/INDEX.md index 8c33140..87467e6 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -15,7 +15,7 @@ | [comparison.md](comparison.md) | vs orchestrators, eval harnesses, tracing | | [architecture.md](architecture.md) | v0.2 modules | | [ROADMAP.md](ROADMAP.md) | Shipped vs deferred | -| [examples/](../examples/README.md) | Eight runnable demos (01–08) | +| [examples/](../examples/README.md) | Four runnable core demos plus Skillware / ToolHost demos | | [guides/reference-tool-host-capstone.md](guides/reference-tool-host-capstone.md) | ToolHost integration checklist (AURA-first) | --- diff --git a/docs/TESTING.md b/docs/TESTING.md index dc3de29..48ad2c2 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -101,7 +101,7 @@ Integration tests **fail** (not skip) if Ollama or Skillware is missing — that | CLI | Version, agent CRUD, run, logs, export, export-otel, compare (`test_cli.py`) | | Config / runtime | YAML merge, `run_script`, middleware, session modes (`test_core_gaps.py`) | | Compare / OTel | Summary diff incl. `agent_ref` + `hash_chain_valid`, OTel JSONL export (`test_v03.py`, `test_core_gaps.py`) | -| Examples | Smoke run all `examples/*/main.py` (`test_examples_smoke.py`) — includes 05–06 (mock by default) | +| Examples | Smoke run all `examples/*.py` (`test_examples_smoke.py`) | | Skillware | Live registry skills via `test_skillware_integration.py` (CI **skillware-live** job) | | Integration | `tests/integration/` — Ollama + Skillware + example 06 (local only) | @@ -112,4 +112,3 @@ Integration tests **fail** (not skip) if Ollama or Skillware is missing — that 3. `flake8 aura tests` 4. CHANGELOG entry under `[Unreleased]` or release section 5. Docs updated if behavior or CLI changed - diff --git a/docs/contributing/ai_native_workflow.md b/docs/contributing/ai_native_workflow.md index 6eeb921..7dd5270 100644 --- a/docs/contributing/ai_native_workflow.md +++ b/docs/contributing/ai_native_workflow.md @@ -34,7 +34,7 @@ Written for **autonomous and semi-autonomous agents** working on AURA Harness. H | `aura/api.py` | Public SDK (`agent()`, `session()`, `emit()`) | | `aura/runtime/` | Script wrap helpers | | `tests/` | pytest suite (see below) | -| `examples/` | Runnable demos (nested folders today; flat restructure planned) | +| `examples/` | Runnable flat core demos | | `docs/` | User and contributor documentation | | `spec/` | JSON schemas (contracts) | | `.github/` | Issue templates, labels, workflows | diff --git a/docs/getting-started.md b/docs/getting-started.md index a54886d..badf86f 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -114,7 +114,7 @@ ids: ## Examples -See [examples/](../examples/README.md) — eight demos (01–08), including [07-observer-presets](../examples/07-observer-presets/) and the ToolHost capstone checklist in [reference-tool-host-capstone.md](guides/reference-tool-host-capstone.md). +See [examples/](../examples/README.md) — including [sequencer_pipeline.py](../examples/sequencer_pipeline.py), [07-observer-presets](../examples/07-observer-presets/), and the ToolHost capstone checklist in [reference-tool-host-capstone.md](guides/reference-tool-host-capstone.md). ## Next diff --git a/docs/guides/aura-on-skillware.md b/docs/guides/aura-on-skillware.md index 760b3ba..019002c 100644 --- a/docs/guides/aura-on-skillware.md +++ b/docs/guides/aura-on-skillware.md @@ -258,7 +258,7 @@ python examples/06-skillware-sequencer-chain/main.py | `aura/observers/presets/` | Monitor + Break packaged presets | | `integrations/skillware/` | Ollama + reference scripts | | `integrations/openai/`, `anthropic/`, `google/` | Cloud body loops | -| `examples/04-*` | Sequencer with mocks | +| `examples/sequencer_pipeline.py` | Sequencer with mocks | | `examples/05-*` … `08-*` | ToolHost tour: skills, chain, observers, emit-only | | `docs/skillware-integration.md` | API-focused reference | | `docs/guides/reference-tool-host-capstone.md` | AURA-first 360° checklist | diff --git a/docs/integrations/README.md b/docs/integrations/README.md index c79f5f2..31a8d36 100644 --- a/docs/integrations/README.md +++ b/docs/integrations/README.md @@ -26,7 +26,7 @@ Use the project **`.venv`** for installs (`pip install -e ".[integrations]"`), n | [06-skillware-sequencer-chain](../examples/06-skillware-sequencer-chain/) | Sequencer chain with conditional `when` steps | | [07-observer-presets](../examples/07-observer-presets/) | Monitor + Break observer presets | | [08-emit-only-loop](../examples/08-emit-only-loop/) | Emit-only coat — no tool host | -| [04-sequencer-pipeline](../examples/04-sequencer-pipeline/) | Sequencer with mocks | +| [sequencer_pipeline.py](../examples/sequencer_pipeline.py) | Sequencer with mocks | ## Related docs diff --git a/docs/sequencer.md b/docs/sequencer.md index c4b43ac..7b1f79c 100644 --- a/docs/sequencer.md +++ b/docs/sequencer.md @@ -141,4 +141,4 @@ On session close, declared step ids are compared to `sequencer.step.end` events Implementation: `aura/sequencer/` — `SequencerRunner`, `SequencerEngine` -Example: [examples/04-sequencer-pipeline](../examples/04-sequencer-pipeline/) +Example: [examples/sequencer_pipeline.py](../examples/sequencer_pipeline.py) diff --git a/docs/skillware-integration.md b/docs/skillware-integration.md index 793849b..5556eea 100644 --- a/docs/skillware-integration.md +++ b/docs/skillware-integration.md @@ -201,7 +201,7 @@ sequencer: args: { to: "team@example.com", subject: "Brief" } ``` -Runnable example: [examples/04-sequencer-pipeline](../examples/04-sequencer-pipeline/). Conditional steps via `when` (prior step result): [examples/06-skillware-sequencer-chain](../examples/06-skillware-sequencer-chain/) · [sequencer.md](sequencer.md). +Runnable example: [examples/sequencer_pipeline.py](../examples/sequencer_pipeline.py). Conditional steps via `when` (prior step result): [examples/06-skillware-sequencer-chain](../examples/06-skillware-sequencer-chain/) · [sequencer.md](sequencer.md). --- @@ -224,7 +224,7 @@ See [outputs.md](outputs.md) and [reference-tool-host-capstone.md](guides/refere ```bash pip install -e ".[dev]" -python examples/04-sequencer-pipeline/main.py # MockSkill +python examples/sequencer_pipeline.py # MockSkill pip install -e ".[skillware]" pytest -m skillware tests/test_skillware_integration.py # real registry skills pytest -m "not ollama" # default CI (no Ollama daemon) diff --git a/docs/using-aura.md b/docs/using-aura.md index c091b21..3236e57 100644 --- a/docs/using-aura.md +++ b/docs/using-aura.md @@ -114,7 +114,7 @@ aura config show # merged config + resolved paths aura paths # view paths; set-project / set-storage persist YAML aura agent create my-bot --purpose "compliance" aura agent set my-bot --ref acme/my-bot --skill research --variable model=llama3.2 -aura run my-bot examples/04-sequencer-pipeline/main.py +aura run my-bot examples/sequencer_pipeline.py aura logs aura_sess_xxxxxxxxxxxx aura export aura_sess_xxxxxxxxxxxx ``` diff --git a/examples/01-minimal-loop/README.md b/examples/01-minimal-loop/README.md deleted file mode 100644 index 538e22f..0000000 --- a/examples/01-minimal-loop/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Minimal loop - -Wraps a two-event loop under AURA. Creates agent `minimal-demo` on first run. - -```bash -pip install -e .. -python main.py -``` - -Shows: auto agent registration, `AURA-000n`, JSONL + summary export under `~/.aura/sessions/`. diff --git a/examples/02-guarded-tools/README.md b/examples/02-guarded-tools/README.md deleted file mode 100644 index 440f34c..0000000 --- a/examples/02-guarded-tools/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Guarded tools - -Token limit, tool allowlist, and human confirm before `gmail.send`. - -```bash -pip install -e .. -python main.py -``` - -Shows: constraint engine, `ApprovalRequired`, audit events for violations and approvals. diff --git a/examples/03-task-mode/README.md b/examples/03-task-mode/README.md deleted file mode 100644 index 4db5a60..0000000 --- a/examples/03-task-mode/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Task mode - -Session runs in `task` mode and closes after `complete_goal()`. - -```bash -pip install -e .. -python main.py -``` - -Shows: purpose on agent profile, task events, conformance summary on close. diff --git a/examples/04-sequencer-pipeline/README.md b/examples/04-sequencer-pipeline/README.md deleted file mode 100644 index 8724367..0000000 --- a/examples/04-sequencer-pipeline/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Example 04 — Sequencer + Skillware host - -Prescriptive pipeline: **research → draft → human confirm → notify**. - -Uses `MockSkill` so the example runs without installing Skillware. Swap in real Skillware skills via `SkillwareHost.from_skillware()` when `pip install "aura-harness[skillware]"` is available. - -```bash -python examples/04-sequencer-pipeline/main.py -``` - -See [skillware-integration.md](../docs/skillware-integration.md) and [sequencer.md](../docs/sequencer.md). diff --git a/examples/README.md b/examples/README.md index 1a59c62..7f8d1c7 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,25 +2,40 @@ Runnable demos for AURA Harness. -| Example | Shows | +Runnable core AURA patterns. From the repo root: + +```bash +pip install -e . +python examples/minimal_loop.py +python examples/guarded_tools.py +python examples/task_mode.py +python examples/sequencer_pipeline.py +``` + +Set `AURA_HOME` to isolate storage during tests or demos. + +| Script | What it demonstrates | Why use it | Choose it when | Edge cases / failure modes | Customization knobs | +|---|---|---|---|---|---| +| [minimal_loop.py](minimal_loop.py) | Auto agent registration, session events, JSONL and summary export | Wrap a small loop with AURA audit output | You only need a script-mode session and export path | Misconfigured `AURA_HOME`; unwritable export directory | Agent name, emitted event names, `AURA_HOME` | +| [guarded_tools.py](guarded_tools.py) | Rules, approval gates, allowlist, token limit | Show membrane behavior around guarded tool events | You need policy and approval examples without a sequencer | Approval denied or missing; rule violation; blocked disallowed tool | Rules, tool names, token limits, approval handling, mock vs live tool events | +| [task_mode.py](task_mode.py) | Task mode, profile purpose, goal completion | Model work that closes only after an explicit goal result | You need task lifecycle and conformance summary output | Goal never completed; missing purpose; invalid task state | Purpose, task steps, completion payload, `AURA_HOME` | +| [sequencer_pipeline.py](sequencer_pipeline.py) | Sequencer steps with mock Skillware-compatible skills and human confirm gate | Exercise an ordered pipeline with approval and host execution | You need prescribed step order rather than ad hoc events | Approval denied; missing skill; unknown step ref; rule violation | `PIPELINE` / sequencer YAML path, mock vs live host, skill names, gates, `AURA_HOME` | + +| Integration demo | Shows | |---|---| -| [01-minimal-loop](01-minimal-loop/) | Auto agent ID, emit events, JSONL export | -| [02-guarded-tools](02-guarded-tools/) | Rules, approval gates, token limit | -| [03-task-mode](03-task-mode/) | Task mode, goal completion | -| [04-sequencer-pipeline](04-sequencer-pipeline/) | Sequencer + Skillware host (mock skills) | | [05-skillware-skill-types](05-skillware-skill-types/) | Three Skillware categories (security, optimization, monitoring) | | [06-skillware-sequencer-chain](06-skillware-sequencer-chain/) | Sequencer chain with conditional `when` steps | | [07-observer-presets](07-observer-presets/) | Monitor + Break observer presets on ToolHost | | [08-emit-only-loop](08-emit-only-loop/) | Loose coat — emit-only, no tool host | ```bash -pip install -e .. -cd examples/01-minimal-loop && python main.py -cd ../07-observer-presets && python main.py +python examples/07-observer-presets/main.py ``` Live registry skills (examples 05–06): `$env:SKILLWARE_LIVE="1"` (PowerShell). -Set `AURA_HOME` to isolate storage during tests. - → Capstone checklist: [docs/guides/reference-tool-host-capstone.md](../docs/guides/reference-tool-host-capstone.md) + +## Script excerpts + +Each script uses a top module docstring, then section comments for setup, session, emit, and close / expected export. Core examples stay as flat scripts here; stack-specific demos belong under `docs/integrations/`. diff --git a/examples/02-guarded-tools/main.py b/examples/guarded_tools.py similarity index 95% rename from examples/02-guarded-tools/main.py rename to examples/guarded_tools.py index e6df13f..29e70fa 100644 --- a/examples/02-guarded-tools/main.py +++ b/examples/guarded_tools.py @@ -2,6 +2,7 @@ from aura import ApprovalRequired, agent, configure +# Setup configure() @@ -15,7 +16,9 @@ def main() -> None: ], ) + # Session with ag.session(mode="script") as run: + # Emit run.emit("turn.start", {"input": "research tire companies"}) run.emit("tool.call", {"tool": "search.web", "query": "tire manufacturers EU"}) run.emit("tool.call", {"tool": "gmail.draft", "tokens": 500}) @@ -36,6 +39,7 @@ def main() -> None: run.emit("turn.end", {"output": "drafts ready", "tokens": 700}) + # Close / expected export print(f"session: {run.session_id}") print(f"exports: {run.exports}") diff --git a/examples/01-minimal-loop/main.py b/examples/minimal_loop.py similarity index 86% rename from examples/01-minimal-loop/main.py rename to examples/minimal_loop.py index 7f293f0..d2c17b5 100644 --- a/examples/01-minimal-loop/main.py +++ b/examples/minimal_loop.py @@ -2,14 +2,20 @@ from aura import agent, configure +# Setup configure() def main() -> None: ag = agent("minimal-demo") + + # Session with ag.session(mode="script") as run: + # Emit run.emit("turn.start", {"input": "hello"}) run.emit("turn.end", {"output": "done", "tokens": 42}) + + # Close / expected export print(f"session: {run.session_id}") print(f"exports: {run.exports}") diff --git a/examples/04-sequencer-pipeline/main.py b/examples/sequencer_pipeline.py similarity index 92% rename from examples/04-sequencer-pipeline/main.py rename to examples/sequencer_pipeline.py index bccadaf..59d7bcd 100644 --- a/examples/04-sequencer-pipeline/main.py +++ b/examples/sequencer_pipeline.py @@ -1,4 +1,4 @@ -"""Example 04 — Sequencer pipeline with mock skills (Skillware-compatible host).""" +"""Sequencer pipeline — ordered steps with mock skills and approval gates.""" from __future__ import annotations @@ -30,6 +30,7 @@ def main() -> None: + # Setup configure() ag = agent( "compliance-pipeline", @@ -38,6 +39,7 @@ def main() -> None: sequencer=PIPELINE, ) + # Session with ag.session(mode="task") as run: host = SkillwareHost(run._session) host.register( @@ -53,6 +55,7 @@ def main() -> None: ) ) + # Emit while True: try: result = run.run_sequencer(host=host) @@ -61,6 +64,7 @@ def main() -> None: print(f"Approval required: {exc.request_id}") run.approve(exc.request_id) + # Close / expected export print("Completed steps:", result["completed"]) print("Session:", run.session_id) print("Exports:", run.exports) diff --git a/examples/03-task-mode/main.py b/examples/task_mode.py similarity index 91% rename from examples/03-task-mode/main.py rename to examples/task_mode.py index dddb3c9..27de542 100644 --- a/examples/03-task-mode/main.py +++ b/examples/task_mode.py @@ -2,6 +2,7 @@ from aura import agent, configure +# Setup configure() @@ -12,12 +13,15 @@ def main() -> None: default_mode="task", ) + # Session with ag.session(mode="task") as run: + # Emit run.emit("task.start", {"goal": ag.profile.purpose}) run.emit("step.complete", {"step": "research", "findings": 12}) run.emit("step.complete", {"step": "draft_emails", "count": 5}) run.complete_goal({"status": "emails_drafted", "awaiting_approval": True}) + # Close / expected export print(f"session: {run.session_id}") print(f"exports: {run.exports}") diff --git a/integrations/skillware/README.md b/integrations/skillware/README.md index 581db82..1923fb4 100644 --- a/integrations/skillware/README.md +++ b/integrations/skillware/README.md @@ -35,7 +35,7 @@ skillware doctor security/prompt_injection_firewall |---|---| | [05-skillware-skill-types](../../examples/05-skillware-skill-types/) | Security + optimization + monitoring skills | | [06-skillware-sequencer-chain](../../examples/06-skillware-sequencer-chain/) | Declarative scan → compress → budget pipeline | -| [04-sequencer-pipeline](../../examples/04-sequencer-pipeline/) | Sequencer concepts with mocks | +| [sequencer_pipeline.py](../../examples/sequencer_pipeline.py) | Sequencer concepts with mocks | Set `$env:SKILLWARE_LIVE = "1"` for live registry skills in examples 05 and 06. diff --git a/tests/conftest.py b/tests/conftest.py index f9566d1..4ac08c7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,7 +5,6 @@ import os import subprocess import sys -from collections.abc import Sequence from pathlib import Path import pytest @@ -68,9 +67,3 @@ def run_example(main_py: Path, aura_home: Path) -> subprocess.CompletedProcess[s cwd=str(main_py.parent), timeout=30, ) - - -@pytest.fixture -def example_scripts() -> Sequence[Path]: - root = Path(__file__).resolve().parents[1] / "examples" - return sorted(root.glob("*/main.py")) diff --git a/tests/test_examples_smoke.py b/tests/test_examples_smoke.py index 053671f..f04f5cb 100644 --- a/tests/test_examples_smoke.py +++ b/tests/test_examples_smoke.py @@ -11,7 +11,7 @@ @pytest.mark.parametrize( "main_py", - sorted((Path(__file__).resolve().parents[1] / "examples").glob("*/main.py")), + sorted((Path(__file__).resolve().parents[1] / "examples").glob("*.py")), ) def test_example_runs(main_py: Path, aura_home): result = run_example(main_py, aura_home)