Metadata-Version: 2.5
Name: agnoclaw
Version: 0.13.0
Summary: A hackable, model-agnostic agent harness built on Agno — with Claude Code's prompt wisdom, OpenClaw's UX patterns, and full Python extensibility
Project-URL: Homepage, https://github.com/yogin16/agnoclaw
Project-URL: Documentation, https://github.com/yogin16/agnoclaw#readme
Project-URL: Repository, https://github.com/yogin16/agnoclaw
Project-URL: Issues, https://github.com/yogin16/agnoclaw/issues
Author: agnoclaw contributors
License: MIT
License-File: LICENSE
Keywords: agents,agno,ai,autonomous,claude,harness,llm
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: <3.15,>=3.11
Requires-Dist: agno<3.1,>=2.6.4
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic-settings>=2.14.2
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: sqlalchemy>=2.0.0
Provides-Extra: all-models
Requires-Dist: anthropic>=0.83.0; extra == 'all-models'
Requires-Dist: google-genai>=1.52.0; extra == 'all-models'
Requires-Dist: groq>=0.11.0; extra == 'all-models'
Requires-Dist: ollama>=0.6.1; extra == 'all-models'
Requires-Dist: openai>=2.0.0; extra == 'all-models'
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.83.0; extra == 'anthropic'
Provides-Extra: browser
Requires-Dist: playwright>=1.40.0; extra == 'browser'
Provides-Extra: cli
Requires-Dist: click>=8.3.3; extra == 'cli'
Requires-Dist: prompt-toolkit>=3.0.0; extra == 'cli'
Requires-Dist: rich>=13.0.0; extra == 'cli'
Provides-Extra: code
Requires-Dist: agno[code]<3.1,>=3.0.2; extra == 'code'
Provides-Extra: dev
Requires-Dist: anthropic>=0.83.0; extra == 'dev'
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'dev'
Requires-Dist: croniter>=1.3.0; extra == 'dev'
Requires-Dist: ddgs<10,>=9.0.0; extra == 'dev'
Requires-Dist: dill>=0.4.1; extra == 'dev'
Requires-Dist: ipykernel>=7.3.0; extra == 'dev'
Requires-Dist: mypy>=1.11.0; extra == 'dev'
Requires-Dist: nbformat>=5.9.0; extra == 'dev'
Requires-Dist: openai>=2.0.0; extra == 'dev'
Requires-Dist: pip-audit==2.10.1; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=9.0.3; extra == 'dev'
Requires-Dist: ruff>=0.6.0; extra == 'dev'
Requires-Dist: textual-dev>=1.0.0; extra == 'dev'
Requires-Dist: twine>=6.0.0; extra == 'dev'
Requires-Dist: types-croniter>=1.3.2; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.12; extra == 'dev'
Provides-Extra: full
Requires-Dist: agno[code]<3.1,>=3.0.2; extra == 'full'
Requires-Dist: anthropic>=0.83.0; extra == 'full'
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'full'
Requires-Dist: click>=8.3.3; extra == 'full'
Requires-Dist: croniter>=1.3.0; extra == 'full'
Requires-Dist: ddgs<10,>=9.0.0; extra == 'full'
Requires-Dist: prompt-toolkit>=3.0.0; extra == 'full'
Requires-Dist: textual>=0.85.0; extra == 'full'
Provides-Extra: google
Requires-Dist: google-genai>=1.52.0; extra == 'google'
Provides-Extra: groq
Requires-Dist: groq>=0.11.0; extra == 'groq'
Provides-Extra: llm-sandbox
Requires-Dist: llm-sandbox[docker]>=0.3.31; extra == 'llm-sandbox'
Provides-Extra: local
Requires-Dist: ollama>=0.6.1; extra == 'local'
Requires-Dist: openai>=2.0.0; extra == 'local'
Provides-Extra: mcp
Requires-Dist: mcp<3,>=2.0.0; extra == 'mcp'
Provides-Extra: media
Requires-Dist: pymupdf>=1.23.0; extra == 'media'
Provides-Extra: media-gcs
Requires-Dist: agno[gcs]<3.1,>=3.0.1; extra == 'media-gcs'
Provides-Extra: media-s3
Requires-Dist: agno[s3]<3.1,>=3.0.1; extra == 'media-s3'
Provides-Extra: notebook
Requires-Dist: nbformat>=5.9.0; extra == 'notebook'
Provides-Extra: openai
Requires-Dist: openai>=2.0.0; extra == 'openai'
Provides-Extra: otel
Requires-Dist: opentelemetry-api<2,>=1.44.0; extra == 'otel'
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.44.0; extra == 'otel'
Requires-Dist: opentelemetry-sdk<2,>=1.44.0; extra == 'otel'
Provides-Extra: postgres
Requires-Dist: psycopg[binary,pool]>=3.2.0; extra == 'postgres'
Provides-Extra: rag
Requires-Dist: lancedb>=0.4.0; extra == 'rag'
Requires-Dist: pymupdf>=1.23.0; extra == 'rag'
Requires-Dist: tantivy>=0.22.0; extra == 'rag'
Provides-Extra: scheduler
Requires-Dist: croniter>=1.3.0; extra == 'scheduler'
Provides-Extra: server
Requires-Dist: fastapi>=0.115.0; extra == 'server'
Requires-Dist: python-multipart>=0.0.31; extra == 'server'
Requires-Dist: uvicorn>=0.30.0; extra == 'server'
Provides-Extra: tui
Requires-Dist: click>=8.3.3; extra == 'tui'
Requires-Dist: prompt-toolkit>=3.0.0; extra == 'tui'
Requires-Dist: textual>=0.85.0; extra == 'tui'
Provides-Extra: web
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'web'
Requires-Dist: ddgs<10,>=9.0.0; extra == 'web'
Description-Content-Type: text/markdown

# agnoclaw

**A small, embeddable, model-agnostic agent harness built on Agno.**

`agnoclaw` combines Agno's model portability with an opinionated workspace, Agent
Skills, policy and permission hooks, a transactional run lifecycle, scoped artifacts,
and governed learning. It is a Python library first: no required gateway, editor, or
hosted control plane.

> **0.13 release:** Agno 3.0.6 is the default lock, with native large-result/media offloading, opt-in CodeMode, bounded normalized history, durable human-input continuation, and inert model-authored learning proposals. CodeMode is a trusted host-kernel interface; RuntimeBackend/LLMSandbox owns containment, and the operation ledger remains the durable effect authority. Agno 2.6.4 and 2.9.0 remain compatibility lanes. See the
> [compatibility matrix](docs/compatibility.md) for exact evidence and limitations.

## Install

Python 3.11–3.14 is supported. The core is provider-neutral; install only the extras you use.

```bash
pip install agnoclaw                    # core; strings or an AgnoModelFactory
pip install "agnoclaw[anthropic]"       # recommended Claude setup
pip install "agnoclaw[local]"           # local Ollama
pip install "agnoclaw[cli]"             # CLI and async REPL
pip install "agnoclaw[postgres]"        # PostgreSQL runtime stores
pip install "agnoclaw[mcp]"             # MCP 2.0 deferred tool ingress
pip install "agnoclaw[server]"          # AgentOS + remote lifecycle HTTP edge
pip install "agnoclaw[code]"            # opt-in Agno 3 host-kernel CodeMode
pip install "agnoclaw[media-s3]"        # Agno 3 S3-compatible media offloading
pip install "agnoclaw[media-gcs]"       # Agno 3 Google Cloud media offloading
pip install "agnoclaw[full]"            # Claude + opt-in host CodeMode + web/scheduler/TUI
```

## Run an agent

The default model is Claude, so this example requires `ANTHROPIC_API_KEY` and the `anthropic` extra.

```python
from agnoclaw import AgentHarness

harness = AgentHarness()
result = harness.run("Summarize the files in this directory")
print(result.content)
```

Use any Agno-supported model with `"provider:model_id"`:

```python
harness = AgentHarness("openai:gpt-4o")
harness = AgentHarness("google:gemini-2.0-flash")
harness = AgentHarness("ollama:qwen3:8b")  # local; Ollama must be running
```

## Choose runtime semantics

The preview exposes `quick`, `durable`, and `service` profiles; the no-argument `legacy` default remains only for migration compatibility. Start new short-running work with `HarnessConfig.quick()` or `AgentHarness(profile="quick")`. Durable/service construction requires explicit runtime and artifact stores; service additionally requires PostgreSQL runtime and Agno storage. See
[configuration reference](docs/configuration.md#runtime-profiles).

For streaming compatibility:

```python
async for event in harness.arun(
    "Analyze this repository",
    stream=True,
    stream_events=True,
):
    print(event)
```

Read the [getting-started tutorial](docs/getting-started.md) for provider setup, trusted execution context, sessions, cleanup, and expected failure behavior.

## Control a run

`start()` returns the preview lifecycle facade without waiting for completion:

```python
run = await harness.start(
    "Investigate the incident",
    session_id="incident-42",
    idempotency_key="incident-42:v1",
)
async for event in run.events():
    print(event.sequence, event.event_type)
result = await run.wait()
await harness.aclose(policy="drain")
```

If Agno pauses a durable run for confirmation, user input, feedback, or an external
execution result, `wait()` raises `RunInputRequiredError`. Inspect the bounded request
and continue it from the same or a reattached harness:

```python
from agnoclaw import Respond, RunInputRequiredError

try:
    result = await run.wait()
except RunInputRequiredError:
    pending = await run.pending_requirements()
    await run.command(Respond(pending[0].request_id, {"name": "Ada"}))
    result = await run.wait()
```

The lifecycle persists intent, state, terminal results, and content-minimized normalized trajectory through a `RuntimeStore`; ambiguous outcomes are never blindly retried. Recovery continues from settled pre-model/result/evidence boundaries; exact-owner startup and reconciliation scans do not promise general mid-model restart. See [run lifecycle](docs/runtime-lifecycle.md),
[operations and recovery](docs/operations-and-recovery.md), and [artifacts](docs/artifacts.md).

With a durable artifact store, `start(..., persist_output=True)` uses bounded provider streaming and `run.output()` replays authorized text segments by cursor. Authenticated remote starts default it to true. The final `wait()` result remains authoritative; replay does not imply an interrupted provider call is safe to resume.

## Embed with trusted identity

Resolve identity in the host, then pass one immutable context to the harness:

```python
from agnoclaw import AgentHarness, ExecutionContext

harness = AgentHarness(
    workspace_dir="/srv/agent/workspace",
    permission_mode="default",
    permission_require_approver=True,
)
context = ExecutionContext.create(
    tenant_id="acme",
    user_id="user-42",
    session_id="case-7",
    workspace_id="support",
    roles=["analyst"],
    scopes=["agents.run"],
)
result = await harness.arun("Continue the case", context=context)
```

The effect-safe model/capability slice can overlap through isolated Agno Agents. Local
built-ins get fresh run-owned tools but remain typed single-flight with custom/streaming paths. Read the
[embedding guide](docs/embedding/README.md) before service deployment.

## Use Agno learning safely

Learning is intent- and scope-driven. Personal/session stores can write directly with
explicit consent; institutional observations become governed candidates first.

```python
from agnoclaw import AgentHarness, LearningProfile

harness = AgentHarness(
    learning=LearningProfile.personal_and_session(
        user_profile="always",
        user_memory="agentic",
        session_context="always",
        max_updates_per_run=5,
    )
)
result = await harness.arun(
    "Remember that I prefer concise incident summaries",
    context=context,
    learning_consent=True,
)
```

With reviewed Learned Knowledge enabled, the model may call `propose_learning` under
the policy's per-run update budget. The call only creates an inert candidate; an
independent evaluator and authorized host must still promote it before future recall.

Scoped read/replace/forget administration is post-verified. Candidate capture, evaluation, promotion/rollback, unknown-effect discovery, evidence-bound reconciliation, and the leased/fenced maintenance worker are implemented on SQLite and PostgreSQL. Automatic promotion remains off pending custom-backend observers, production worker certification, deletion proof, and model-backed no-learning benefit. Start with
[learning](docs/learning.md), [administration](docs/learning-administration.md), and [governed candidates](docs/learning-candidates.md).

## Skills, workspace, tools, and backends

- Workspace instructions and memory are plain Markdown with explicit size limits and
  precedence. See [workspace files](docs/workspace.md).
- Agent Skills are loaded progressively and carry trust/tool restrictions. See the
  [SKILL.md reference](docs/skills.md).
- Built-in shell, file, skill, and browser execution share one injectable runtime
  backend. See [runtime backends](docs/embedding/workspace-backends.md).
- Capabilities use immutable descriptors and an operation-gated executor. Specs passed
  through `AgentHarness(capabilities=[...])` receive version-pinned Agno binding,
  policy, durable approval-before-effect, active-lease fencing, and governed replay.
  Raw `tools=` are normalized as opaque, remain serialized only on named-legacy
  `run/arun`, and are rejected by `start()` and explicit-profile convenience calls
  until converted to explicit specs. See
  [capabilities](docs/capabilities.md).

```python
result = await harness.arun("Review the authentication module", skill="code-review")
print(result.content)
```

## CLI

```bash
agnoclaw init
agnoclaw chat
agnoclaw run "Review src/" --skill code-review
agnoclaw tui
agnoclaw heartbeat start
agnoclaw migrate 0.12 service --help
agnoclaw schedule worker --runtime-db ~/.agnoclaw/runtime.db
```

Install the relevant extra first. The [CLI reference](docs/cli.md) records command groups,
automation limits, and current durability boundaries; the [configuration
reference](docs/configuration.md) covers TOML, environment variables, and safe service defaults.
Use [durable scheduling](docs/durable-scheduling.md) for unattended jobs; JSON remains
compatibility-only. The PostgreSQL migration lifecycle needs `cli,postgres,scheduler`; production certification remains open.

## Why this shape

- **Tiny public grammar:** `run`, `arun`, `start`, `get_run`, `session`, and typed run
  controls instead of a second orchestration framework.
- **Short and long work, one kernel:** quick calls avoid unnecessary machinery while
  controllable work gains identity, intent, state, events, effects, and artifacts.
- **Truth before retries:** external effects have durable intent and explicit unknown
  outcomes; exactly-once external execution is never implied.
- **Learning is a governed data plane:** consent, scope, provenance, candidates,
  evaluation, reversible promotion, and deletion are separate concerns.
- **Progressive power:** local defaults stay approachable; service guarantees are
  enabled only with the stores, policy, and evidence they require.

The [architecture](docs/architecture.md) and [declared child-run contract](docs/child-runs.md) cover host, model-visible
`DeclaredChildTemplate`, and authenticated remote delegation. Competitive decisions
are in [World-class strategy](docs/world-class-harness.md), the [Agno release audit](docs/agno-release-practices.md),
and the [Lilian Weng research audit](docs/lilian-weng-harness-audit.md).

## Compatibility and quality

The development lock is Agno 3.0.6; 2.6.4 remains legacy and 2.9.0 stable-v2. Schema-v12 is current. Token-free contracts and deterministic restart probes certify all three boundaries; real-service, chaos, soak, provider-backed, and hosted-CI gates remain separate.

- [Compatibility matrix](docs/compatibility.md)
- [Evaluation and release gates](docs/evaluation.md)
- [Migration to 0.12](docs/migration-0.12.md)
- [Changelog](CHANGELOG.md)

## Documentation

Use the [documentation index](docs/README.md) for tutorials, how-to guides, reference,
explanations, operations, research, and release planning. `HarnessAgent`
remains a backward-compatible alias for `AgentHarness`.

## Development

```bash
uv sync --extra dev
uv run ruff check src/ tests/ scripts/
```
See [CONTRIBUTING.md](CONTRIBUTING.md), [support](SUPPORT.md), [security](SECURITY.md),
and [DEVELOPMENT.md](DEVELOPMENT.md).

## License

MIT — fork it, inspect it, and embed it.
