Skip to main content
You want proof that Noēsis is actually recording how your agent thinks. This quickstart runs a minimal agent once, shows where the episode lands on disk, and reads the timeline so you see observe → interpret → plan → act → reflect in a few lines of code. Why this matters (the “wow”): after one run you get a sealed evidence bundle you can diff, audit, and gate in CI.
Learning path:
  1. Hello Episode (this page) → traces in 5 minutes.
  2. Governed Side Effects → enforce action_candidate → governance → act.
  3. Trace-Based Evals → score behavior over traces.

What you’ll build

  • A one-call episode using a local adapter (no LLM required)
  • A recorded episode under .noesis/episodes/<episode-id>/
  • A sealed evidence bundle you can diff (final.json + manifest.json)
  • A timeline with phases and a couple of quick metrics

Prerequisites

  • Python environment with noesis installed (uv add noesis or pip install noesis)
  • Optional: An OpenAI-compatible key in OPENAI_API_KEY if you later wire an LLM-backed adapter

1) Run your first episode (Python-first)

quickstart.py
from __future__ import annotations

from pathlib import Path
import noesis as ns


DEMO_ROOT = Path("/tmp/noesis-demo")


def summarize_demo_files(task: str) -> str:
    _ = task
    readme = (DEMO_ROOT / "readme.txt").read_text(encoding="utf-8").strip()
    todo = (DEMO_ROOT / "todo.txt").read_text(encoding="utf-8").strip()
    todos = [line.strip("- ").strip() for line in todo.splitlines() if line.strip().startswith("-")]
    lines = [
        "Summary:",
        f"- README: {readme.splitlines()[0] if readme else '(empty)'}",
        f"- TODO items: {len(todos)}",
    ]
    if todos:
        lines.append("Next actions:")
        lines.extend([f"- {item}" for item in todos[:2]])
    return "\n".join(lines)


def main() -> None:
    DEMO_ROOT.mkdir(parents=True, exist_ok=True)
    (DEMO_ROOT / "readme.txt").write_text("Noesis demo workspace", encoding="utf-8")
    (DEMO_ROOT / "todo.txt").write_text("TODO\n- Add a safety policy\n- Write a short summary\n", encoding="utf-8")

    verify = [
        ns.file_exists("readme.txt"),
        ns.file_exists("todo.txt"),
        ns.file_contains("todo.txt", "TODO"),
    ]
    episode_id = ns.solve(
        "Summarize the demo files and propose next actions.",
        using=summarize_demo_files,
        workspace=str(DEMO_ROOT),
        verify=verify,
    )
    print("Episode ID:", episode_id)


if __name__ == "__main__":
    main()
Run it:
python quickstart.py
Auth reminder: Noēsis does not create API keys for you. Set OPENAI_API_KEY before running any LLM-backed adapters.

2) Open the episode folder

Episodes are written to .noesis/episodes/<episode-id>/. Inspect the files:
ls .noesis/episodes/<episode-id>/
FileWhat it tells you
events.jsonlThe full timeline: observe, plan, act, reflect (plus timestamps and causal links)
summary.jsonOutcome and metrics (success, plan_count, act_count, latencies)
state.jsonThe persisted plan/state at the end of the run
manifest.jsonChecksums for integrity
final.jsonThe seal: if present, the episode is finalized

3) Read the timeline

read_timeline.py
import noesis as ns


def show_timeline(episode_id: str):
    for event in ns.events.read(episode_id):
        phase = event["phase"]
        payload = event.get("payload", {})
        status = payload.get("status") or payload.get("reason") or "ok"
        print(f"[{phase:<8}] {status}")


if __name__ == "__main__":
    eid = "<episode-id>"  # paste from the previous step
    show_timeline(eid)
You should see phases like observe, interpret, plan, act, reflect with concise statuses. That is the “agent brain” trace users keep asking for.

4) Inspect a couple of metrics

read_metrics.py
import noesis as ns
import json


def load_metrics(episode_id: str):
    summary = ns.summary.read(episode_id)
    metrics = summary.get("metrics", {})
    print(json.dumps({
        "success": metrics.get("success"),
        "plan_count": metrics.get("plan_count"),
        "act_count": metrics.get("act_count"),
        "latency_ms": metrics.get("latencies", {}).get("total_ms"),
    }, indent=2))


if __name__ == "__main__":
    load_metrics("<episode-id>")  # paste the same ID
This is enough to prove that Noēsis is capturing the agent’s trajectory, not just the final answer.

Next steps