Skip to main content

aihi-agent

[English] | 简体中文

Provider-neutral, recoverable agent runtime for AIHI.

aihi-agent turns model contracts into a durable execution system. It provides the loop, sessions, tools, policy, approvals, sandbox boundary, context management, integrations, and observability that an application can compose for a specific product.

Responsibilities

  • Run bounded model/tool turns with explicit runtime composition.
  • Persist an append-only event log and recover sessions after interruption.
  • Compile stable-prefix-aware context and compact it into derived state without rewriting history.
  • Register and execute tools through validation, policy, approvals, and hooks.
  • Execute model-authored commands through an explicitly selected command Sandbox backend.
  • Integrate Skills, MCP servers, subagents, memory, artifacts, telemetry, replay, and evaluations.

The package does not select a provider, implement a UI, provide a model router/gateway, or hide tool defaults. Applications pass those choices to RuntimeBuilder.

Architecture

Model Provider (aihi-models)
              │
              ▼
RuntimeBuilder ──► Runtime / RunCoordinator ──► EventStore
              │                  │
              │                  ├── ContextCompiler / Compaction
              │                  ├── ToolRegistry ──► Policy ──► Approval ──► Hooks ──► Tool
              │                  │                                               │
              │                  │                                command Tool ──┘
              │                  │                                      │
              │                  │                                      ▼
              │                  │                         SandboxBackend.run_command
              │
              └── Skills / MCP / Subagents / Memory / Artifacts / Telemetry

The event store is the source of truth. Tool calls are recorded before execution and have exactly one result. An approval decision of ASK suspends the run so it can be resumed later.

Installation

Published release:

python -m pip install aihi-agent==0.1.0

See the PyPI project page. It installs the compatible aihi-models dependency automatically. For repository development:

From the workspace:

uv sync

For a local editable install:

uv pip install -e packages/aihi/agent

aihi-agent requires Python 3.11+ and depends on aihi-models 0.1.x.

Minimal runtime

from aihi.agent import (
    InMemoryEventStore,
    RuntimeBuilder,
    Session,
    ToolContext,
    ToolExecutionResult,
    ToolSpec,
)
from aihi.models import FakeProvider, FakeStep, Message


class InspectTool:
    spec = ToolSpec.define(
        name="inspect",
        description="Return application-owned inspection data.",
        input_schema={"type": "object", "properties": {}},
        concurrency_safe=True,
        mutates=False,
    )

    async def run(self, input, context: ToolContext) -> ToolExecutionResult:
        return ToolExecutionResult("Application inspection completed.")


provider = FakeProvider([FakeStep(text="I inspected the workspace.")])
runtime = (
    RuntimeBuilder(
        provider=provider,
        model="fake-model",
        tools=[InspectTool()],
    )
    .with_max_turns(20)
    .build()
)

session = Session.create(InMemoryEventStore(), metadata={"application": "example"})

result = await runtime.coordinator.run(
    session,
    model=runtime.model,
    user_message=Message.text("user", "Inspect this project."),
)
print(result.state)

Sandbox backends expose command execution only. They do not provide file read, glob, or write APIs. For real command tools, prefer an isolated backend when available. HostBackend is a controlled local execution backend, not a security isolation boundary, and requires an explicit unsafe=True acknowledgement.

Runtime composition

RuntimeBuilder requires the application-wide dependencies up front:

  • provider and model;
  • the application-approved tools collection.

A command tool may separately require a SandboxBackend in its own constructor. The Runtime does not own or distribute a global Sandbox.

Session.create(...) accepts only application-owned JSON metadata plus generic identity and observer options. The Harness persists and forks that metadata opaquely; it does not require or interpret a cwd, provider, model, workspace, or product permission mode.

Optional extensions are added explicitly with methods such as:

  • .with_max_turns(...) and .with_context_window(...);
  • .with_policy(...), .with_approvals(...), and .with_hooks(...);
  • .with_skills(...), .with_memory(...), .with_compaction(...);
  • .with_subagents(...), .with_artifacts(...), and .with_telemetry(...).

Generic subagent governance covers capability and budget subsets, depth, and child count. The Harness does not interpret a workspace or product permission mode. An application that enables subagents must provide a child-context factory that derives its own opaque application authority and durable run profile for every child Run, plus a Session factory that decides where and how child Sessions live.

The default coordinator turn budget is finite (100) and can be lowered for a product-specific safety envelope.

Core modules

Area Main API
Runtime and runs Runtime, RuntimeBuilder, RunCoordinator, RunResult, RunState
Sessions and storage Session, EventStore, InMemoryEventStore, SQLiteEventStore, Event
Context ContextCompiler, CompactionPolicy, ContextState, summaries and compaction generators
Tools Tool, ToolSpec, ToolContext, PreparedToolCall, ToolRegistry
Policy and approval PermissionContext, DefaultPolicyEngine, Approval, approval resolvers
Sandbox HostBackend, LocalIsolatedBackend, DockerBackend
Integrations Skills, MCP, plugins, subagents, memory, artifacts
Observability Telemetry, JsonlTelemetrySink, InMemoryTelemetrySink
Verification replay, golden tasks, evals, and contract helpers

Tool and approval model

Tools are registered with explicit ToolSpec metadata. The policy engine decides whether an invocation is allowed, denied, or must ask for approval. Approval leases can scope a decision to a request, a tool, or a run according to the application policy.

An application may pass typed, opaque state through ToolContext.app_context and PermissionContext.app_context. A Tool can implement a deterministic, side-effect-free prepare() method that returns PreparedToolCall; the normalized input is then shared by Policy and execution. RunCoordinator.run_profile persists a JSON application authority snapshot and rejects a different snapshot when the same Run is resumed.

The Harness ships no product file or shell tools. Applications own their tool set and local resource semantics. A model-authored command tool should receive a command Sandbox explicitly at construction; ordinary tools do not receive Sandbox access through ToolContext.

Observability

Telemetry is an observation stream, not the event log. JsonlTelemetrySink emits redacted, bounded records and creates owner-only files by default. Use the event store for recovery and audit the telemetry stream for operational diagnosis; do not use UI output as a source of truth.

Stable context prefix

ContextCompiler keeps the application-owned base system prompt in a stable TextBlock and places runtime ContextSection values in the dynamic suffix. RunCoordinator derives one cache-family key from that stable prefix and canonical model-visible tool definitions. Dynamic memory, skills, compaction state and current turns remain after the cache boundary. Cache availability never changes Event replay, policy, approval, command execution or tool persistence semantics.

ContextPressureController measures the complete normalized request against ContextBudget.input_capacity. It uses the conservative local estimate by default, asks a capable Provider for an exact count at 65%, and falls back without failing the run when counting is unavailable. CompactionPolicy applies the 60% target, 70% soft trigger and 85% hard trigger; a hard decision below 85% is allowed only when the reserved next output would exhaust the following request. Each durable model.usage event records the count method, current/projected pressure, trigger, reason and target. It also records Provider-reported cache read/write tokens and a SHA-256 of the cache-family key, never the key or prompt itself.

At 70% pressure or above, the Runtime makes at most one batched soft-pruning attempt before the Provider call. It removes only old, successful, read-only Tool Result bodies whose original Messages are durable and whose session-scoped Artifacts pass access, manifest and payload-integrity checks. Tool calls, result identity/error state, Artifact references, the recent complete-group tail and the stable cache prefix remain unchanged. A batch is discarded unless it reclaims the configured minimum; the immutable Event history is never rewritten.

At 85% pressure, or when reserved output predicts exhaustion, the Runtime replaces older complete groups with a schema-v2 ContextState and keeps a token-bounded recent raw tail (20%, capped at 32K, with at least four complete groups). Files, verification receipts, failures, pending approvals, subagents and Artifacts are projected deterministically from immutable Events, Tool Result metadata and Artifact manifests before optional model enrichment. Model output may add semantic constraints, decisions, questions and next steps, but cannot assert file changes or successful verification. Each compaction.created v2 event records evidence references, policy/count metadata and the retained tail; v1 events remain replayable. Hard compaction must reach the 60% target or fail with context_window_exceeded.

Applications can derive cache and compaction diagnostics entirely from durable Events:

usage = [event for event in session.events if event.type == "model.usage"]
compactions = [event for event in session.events if event.type == "compaction.created"]
cached = sum(int(event.data["cached_input_tokens"]) for event in usage)
input_tokens = sum(int(event.data["input_tokens"]) for event in usage)
cache_hit_ratio = cached / input_tokens if input_tokens else 0.0

Run python3 -m scripts.evals.run --mode pr from a source checkout to execute the replay golden Trace, the paired long-session cache/compaction gate and the Coding Agent smoke benchmark.

Development

uv run pytest packages/aihi/agent/tests
uv run ruff check packages/aihi/agent
uv run mypy
uv run python -m build --wheel --no-isolation packages/aihi/agent

See the repository architecture guide and the code-agent README for an application-level composition.

Security model

  • Keep credentials in the application/provider boundary, never in prompts or event payloads.
  • Treat model output, tool arguments, Skills, MCP responses, and subagent output as untrusted.
  • Do not claim that HostBackend isolates a process; use LocalIsolatedBackend or DockerBackend when isolation is required.
  • Set a finite turn limit and review approval/policy defaults before exposing tools to a model.

Metadata

Release files for aihi-agent 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aihi-agent 0.2.0
File Size Uploaded Provenance
aihi_agent-0.2.0.tar.gz 211.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for aihi-agent 0.2.0
File Interpreter ABI Platform
aihi_agent-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 400.3 kB

Release files / aihi_agent-0.2.0.tar.gz

Download URL aihi_agent-0.2.0.tar.gz
Size 211.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7a66c6b394a78bd260cc4501fa8a152212c384acce3c4ea8e8403eabd1d5aa3c
BLAKE2b-256 checksum
How to use checksums
518661a3b771c55416a4a8206de986dce08bd100eb2667e81d0eee2ec813189b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / aihi_agent-0.2.0-py3-none-any.whl

Download URL aihi_agent-0.2.0-py3-none-any.whl
Size 189.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4f69ea2151203199eec80c4faa1c7a39f430f01b8700bbfed683f8de8a36c5c3
BLAKE2b-256 checksum
How to use checksums
e0e80a23d0ca5875da28ba599b327a438a4ef8fdf989e4447a47df7d7e8a1236
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Security for aihi-agent 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page