Files
zeekayandHanzo Dev d5ce906725 ci: restore the image build under .hanzo/workflows
Every workflow in this repo was deleted and nothing replaced them, so the sole
producer of ghcr.io/hanzoai/agent no longer existed anywhere and there was no CI
at all. That is silent staleness: no failing run, just an artifact that quietly
stops being rebuilt.

.github/workflows now holds sync.yml and nothing else, copied verbatim from
universe infra/ci/sync.yml. It replaces a mirror-nudge file that POSTed
/api/v1/repos/.../mirror-sync and described git.hanzo.ai as a downstream pull
mirror; the forge is canonical and refs are pushed to it. Without it a
.hanzo/workflows file has nothing to trigger it.

deploy.yml restores docker-publish.yml. Two things could not come across as-is:

- Its body was one `uses: hanzoai/.github/.github/workflows/docker-build.yml@main`.
  A private cross-repo reusable workflow does not resolve on the forge, so the
  amd64 build/push is vendored inline, as hanzoai/bot already does.
- It built `context: control-plane`, and no control-plane directory exists on
  main; the orchestrator was hoisted to the root module in v0.1.1 and the
  directory survives only on the unmerged consolidate/held-work branch.
  Restoring that context restores a build that cannot run. It builds
  Dockerfile.sdk — the one Dockerfile on main whose context exists, previously
  referenced by nothing despite sdk-* tags being live on the image — and tags it
  sdk-* so the two Dockerfiles cannot collide in one tag namespace.

The tag rule is shell rather than docker/metadata-action, so it is two readable
lines with no action semantics to guess at, and it was tested standalone:
v* -> :sdk-X.Y.Z + :sdk-latest, main -> :sdk-sha-<sha7> + :sdk-latest.

ci.yml replaces tests.yml and test.yml, which checked the same things twice, the
second with `|| true` on most steps so it could not fail. It gates what is
verifiable on main today — gofmt/build/vet/test for the Go module, and the
locked install plus `import agents` for Python, which is what Dockerfile.sdk's
builder stage and HEALTHCHECK do. It deliberately does not run ruff, mypy or
pytest: `make sync` cannot resolve (requires-python >=3.9, a transitive numpy
needs >=3.10), ruff reports 2337 errors, and pytest INTERNALERRORs at collection
because a test module sys.exit(1)s at import. tests.yml ran `make sync` first in
all five jobs, so none of them could have gone green. Those four are written down
in LLM.md as work rather than shipped as a permanently red check, which gets read
as broken CI instead of broken code.

gofmt over eight files so that gate is real instead of omitted; build, vet and
test re-run green afterwards. Alignment whitespace only.

Not restored, with reasons in LLM.md: docs.yml (mkdocs gh-deploy is GitHub Pages,
never published anything, and Pages is not how we serve sites), publish.yml
(pointed at the PyPI package hanzoai/python-sdk owns; deliberately removed
earlier), issues.yml (upstream's stale-issue bot).

LLM.md documents the chain, records the four broken Python checks, and states
the open question this repo actually has: nothing in hanzoai/universe references
ghcr.io/hanzoai/agent, so the image has no consumer and no App CR.

.gitignore ignored .hanzo/ under an "# IDE" heading, which silently dropped
both new workflows from the commit — the same silent-staleness shape this is
meant to remove, one level down. Narrowed to .hanzo/* with .hanzo/workflows/
re-included.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 09:01:00 -07:00

5.5 KiB

Hanzo AI Agent SDK

Overview

Python framework for building AI agents and multi-agent systems with orchestration, MCP tools, memory, and observability via Hanzo Cloud.

Architecture

agent/
├── src/agents/            # Core agent SDK (multi-agent, routing, orchestration)
├── sdk/                   # Extended SDK packages
├── control-plane/         # Agent control plane
├── deployments/           # K8s deployment manifests
├── docs/                  # Documentation (MkDocs)
├── examples/              # Usage examples
├── tests/                 # Test suite
└── scripts/               # Dev/build scripts

Tech Stack

  • Language: Python 3.9+
  • Package: hanzo-agent on PyPI (v0.0.4) — hanzoai is the API client from hanzoai/python-sdk
  • Dependencies: openai, pydantic, griffe, requests
  • Optional extras: [web3], [tee], [marketplace], [cli]
  • Docs: MkDocs
  • Build: uv, Makefile

Build & Run

uv sync --all-extras        # Install with all extras
uv run pytest               # Run tests
make dev                    # Development mode
make test                   # Run test suite

Key Concepts

  1. Agents: LLMs with instructions, tools, and memory
  2. Networks: Multi-agent systems with semantic/rule-based/load-balanced routing
  3. Workflows: Orchestrated multi-step processes (parallel, conditional, loop)
  4. State & Memory: Shared state + vector search long-term memory
  5. Tools: Enhanced tool system with MCP support
  6. Tracing: Built-in observability via Hanzo Cloud

Key Files

  • pyproject.toml — Package config and dependencies
  • src/agents/ — Core agent implementation
  • docs/agents.md — Agent documentation
  • docs/networks-and-orchestration.md — Multi-agent docs
  • examples/ — Working examples

Patterns

  • OpenAI Chat Completions API compatible (works with 100+ providers via Hanzo Router)
  • Pydantic models for configuration
  • Async-first design
  • MCP (Model Context Protocol) for tool integration

How this ships

One way, and it runs on our own stack:

push  ->  github.com/hanzoai/agent          (a mirror)
          .github/workflows/sync.yml         carries refs onward
  ->  git.hanzo.ai/hanzoai/agent             CANONICAL
          .hanzo/workflows/ci.yml            the checks
          .hanzo/workflows/deploy.yml        builds ghcr.io/hanzoai/agent

git.hanzo.ai is canonical; GitHub is a mirror. .github/workflows/ holds exactly one file, sync.yml, and its only job is getting refs to the forge. Every build, check and deploy is a workflow under .hanzo/workflows/, which the forge reads. .hanzo/workflows uses GitHub Actions syntax, so a workflow moves between the two by changing directory and nothing else.

deploy.yml builds Dockerfile.sdk and tags sdk-*. It does not build control-plane, which is what the workflow it replaces did: there is no control-plane/ directory on main. The orchestrator was hoisted into the root Go module (tag v0.1.1, "drop control-plane/pkg nesting"), and the directory survives only on the unmerged consolidate/held-work branch. Two things still point at the old layout and are therefore stale, not load-bearing: deployments/docker/Dockerfile.control-plane (COPYs from control-plane/) and Makefile.agents (cd control-plane && go build).

A build never deploys itself. Nothing in hanzoai/universe references ghcr.io/hanzoai/agent, so this image has no consumer and no App CR. That is a real open question rather than an oversight: either a CR should exist, or the image should stop being published. It is published today because it was published yesterday, and because deleting the only producer of a live artifact is how something goes stale with nothing red to show it.

What is checked, and what is not

ci.yml gates the Go module (gofmt, go build, go vet, go test — all pass) and the Python install the image depends on (uv sync --frozen --no-dev, then import agents, matching Dockerfile.sdk's HEALTHCHECK).

It deliberately does not run the Python lint/type/test suite, because none of it passes on main:

Command State
make sync cannot resolve — requires-python is >=3.9, a transitive numpy needs >=3.10
make lint (ruff check) 2337 errors
make tests (pytest) INTERNALERROR at collection; a test module sys.exit(1)s at import without ANTHROPIC_API_KEY
make old_version_tests runs 3.9, the version make sync cannot resolve

tests.yml ran make sync as the first step of all five of its jobs, so none of them could have gone green. Fixing those four is real work with an owner; a permanently red check is read as broken CI rather than as broken code, so the debt is written down here instead.

Deleted rather than migrated

  • test.yml — a second copy of tests.yml with || true on most steps, so it could not fail. Folded into one ci.yml.
  • docs.yml — make deploy-docs is mkdocs gh-deploy, i.e. GitHub Pages. There is no gh-pages branch and hanzoai.github.io/agent 404s, so it never published anything. Pages is not how Hanzo serves sites.
  • publish.yml — published this repo's dist to PyPI. pyproject.toml is hanzo-agent 0.0.4; when it was named hanzoai this workflow pointed at the package hanzoai/python-sdk owns (now 3.1.1), so a release here could have published a downgrade over it. Removed in "fix(pypi): stop publishing this repo's dist as hanzoai" and deliberately not restored.
  • issues.yml — upstream's stale-issue bot.