The tool put ~120 actions in a Literal enum and ~60 parameters in its
schema, all of it in every agent's context, and most of it Playwright
locator builders that returned a count. Three hand-kept lists (the enum,
extension_actions, _zap_method_for) disagreed: snapshot, wait and
select_option routed to the extension under names it did not answer.
ACTIONS is now the one table: each action once, its topic, its usage
line, and the extension method that serves it. The schema carries the
core loop (navigate, snapshot, click, fill, type, press, read,
screenshot, evaluate, wait, tabs, help) with an open `action` string;
help prints the rest by topic, and their parameters travel in `args`.
snapshot, click-by-ref and friends go to the extension's page engine
(hanzo.snapshot / hanzo.act / hanzo.read / hanzo.wait / hanzo.navigate,
screenshot annotate=true to hanzo.annotate). A tree or a page answers as
text; a refusal ("Stale ref @e4 … run snapshot again", "covered by
<div#consent>") is the error, not a success wrapping "ERR:", and is
never retried on Playwright, which has no refs to act on.
Aliases and no-ops are gone: select_option (select), get_inner_text and
get_value (get_text), clear (fill), content (get_html), new_page
(new_tab), press_key, mouse_wheel (scroll), list_browsers and
list_mcp_instances (browsers), use_browser, set_default_browser,
claim/release_browser, the locator/get_by_*/first/last/nth/filter/all
builders, is_hidden, frame, main_frame, on and off.
Claude-Session: https://claude.ai/code/session_01Dc8DXc3fEQCRHUa6XWK4Ku
Hanzo CI/CD / test (linux-amd64) (push) Successful in 2m42s
Hanzo CI/CD / test (linux-arm64) (push) Successful in 5m16s
Hanzo CI/CD / cicd (push) Failing after 2m2s
CI/CD / cicd (push) Failing after 9m50s
hanzoai 8 requires Python 3.12, and PyPI serves 2.1.3 to 3.9-3.11. An
unpinned `pip install hanzoai` there installed the 2.1 client without a word,
and every example here failed on `from hanzoai.cloud import ...`. Every install
line now carries the floor, which pip 21 on Python 3.9 answers with "No
matching distribution found for hanzoai>=8", and the quickstart no longer says
Python 3.9.
Co-authored-by: Hanzo Dev <[email protected]>
Ranges drift once nothing moves them: a caret that has not been rewritten
since it was written pins whatever was current that day, and an exact pin
cannot even take a patch. Both are updated here.
One line per package, so a surface reads the same components, the same
tokens and the same face as every other one.
Ranges drift once nothing moves them: a caret that has not been rewritten
since it was written pins whatever was current that day, and an exact pin
cannot even take a patch. Both are updated here.
One line per package, so a surface reads the same components, the same
tokens and the same face as every other one.
The lock sat at 574d1f1d while the product moved on. The team surface
stopped at rooms — no messages path, no way to open one — so anything
built on this client had to reach past it with its own HTTP calls, which
is the duplication a generated client exists to prevent.
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.
Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
288 of hanzoai/ai's 294 operations now declare a response, against 1 before.
GET /v1/models, POST /v1/chat/completions, /v1/embeddings, /v1/messages —
every address a client actually calls — used to reach this client untyped,
because cloud's relay carried an operation's sentence and dropped the shapes
it named. It carries both now.
Fleet-wide the document goes from 69% to 81% of operations declaring what
comes back, which is where the ~208 new models here come from.
Every dependency on a @hanzo/@luxfi/@zooai package names the same version across
the repo: a catalog entry where pnpm supports one, an exact pin where it does
not, and a range only where a peer genuinely means one.
pnpm itself is pinned too — the estate ran eighteen different versions, five of
them too old to read a catalog.
The name table of Zen-Variable.woff2 read "Geist" and ZenMono-Variable.woff2
read "Geist Mono". The filename, the @font-face and the licence beside them all
said Zen; only the bytes disagreed, so every grep passed and the surface
rendered Vercel's face.
This is the fourth instance in the estate — @hanzo/design shipped the same thing
under the same filename, zoo's foundation declared Zen over inter-var-latin,
and hanzo.sh had Zen declared over a Geist file. A filename proves nothing; the
check is the name table:
python3 -c "from fontTools.ttLib import TTFont; print(TTFont(P)[\"name\"].getDebugName(1))"
The bytes are @hanzo/font 1.9.2's now, verified that way: family Zen and Zen
Mono. LICENSE-Zen.txt beside them already carried both copyright holders, which
is what OFL §2 asks of the copy that travels.
The filenames read Zen-*.woff2 and the glyphs are right; only the name
table said family='Geist', designer='Basement.studio, Andres Briganti,
Mateo Zaragoza', vendorURL=basement.studio. Nothing visual can see that —
a font picker, a local() match and a licence audit can.
Replaced with the corrected bytes from hanzoai/font, matched by glyph
content rather than by filename, so the drawing is provably the same face.
README: PyPI serves 3.2.1 and this tree is 3.2.11, so the install line is the
git one. Between the two the default version left the operation ids — 3.2.1
carries get_v1_keys/get_v1_tools (182 api modules, 2172 models) and this carries
get_keys/get_tools — so `pip install hanzoai` above a `get_keys()` quickstart
hands the reader a client that cannot run it. Counts are measured off the pinned
document: 1814 paths, 2479 operations, 191 tags + default_api = 192 API classes
over 2460 models, 2659 importable modules.
Auth was wrong everywhere and it was the same root cause: the document declares
no securityScheme, so every operation got an empty auth_settings and
Configuration(access_token=…) is read by nothing. Serializing get_keys from such
a Configuration produces a request with no Authorization header at all — the
five flows have been calling anonymously and reading the refusal as a bad key.
examples/client.py now passes the bearer through ApiClient's header_name/value
pair, verified against a local server that echoes what it received, and a smoke
test pins both halves so the day cloud emits the scheme, the test fails and the
header moves back into Configuration.
The examples gate resolved class names and stopped there, which is how `money`
and `tools` once passed it while every call in them named a method that no
longer existed. It now walks the syntax tree for attribute accesses on anything
bound to a *Api and asks the class: ten names resolve, and a stale get_v1_tools
fails in the same second the import passes.
Deleted five example scripts that imported hanzoai.Hanzo, hanzoai.cluster,
hanzoai.agents and hanzoai.completion — none of which exist — or were dict
literals captioned "in practice this would be called through the MCP interface";
compileall passed all five, because syntax is not a claim. Deleted three docs
that were fabrication rather than drift and that nothing rendered: FEATURES.md,
QUICKSTART.md, GPT5_ORCHESTRATION.md.
pkg/hanzo-agent said `pip install hanzoai` and `from hanzoai import Agent,
Runner`; the client has no Agent. Its own `full` extra resolved to
hanzoai[web3,tee,marketplace,cli], extras the client does not declare, so it
installed the client and none of the extensions. pyproject said BSD-3-Clause
while LICENSE is the Apache 2.0 text. test_smoke imported tracker_api and no
/v1/tracker path is emitted any more, so the suite carried a failing test naming
a module the client does not have; it reads analytics_api now, off the client.
No duplication: the SDK must not carry copies of governance proposals.
HIP-0300 duplicated canonical hip-0300; the rest diverge. Canonical home is
hanzoai/HIPs (git history preserves these). Forwards-only, no backcompat.
- Update docs/mcp/tools/ placeholders with quick refs and links
- Create docs/ref/tools/index.md with full package table
- Create docs/ref/agent/index.md with topic links
- Create docs/ref/mcp/index.md with tool categories
- Create docs/tools/index.md as main entry point
- Add consistent cross-references between sections
- Replace default logo with Hanzo logo (white for dark header)
- Add Hanzo favicon
- Configure Geist font family from jsdelivr CDN
- Configure Geist Mono for code blocks
- Implement shadcn/ui zinc color palette
- Set pure black header (#000000) matching shadcn dark mode
- Set slate scheme as default (dark mode first)
- Style code blocks, tables, admonitions with rounded corners
- Remove footer, add scrollbar styling
- Fix mkdocstrings config (deprecated selection option)
- Add root-level mkdocs.yml with comprehensive navigation
- Create docs/ directory with:
- Getting started (installation, quickstart)
- MCP tools documentation (shell, browser, memory, etc.)
- Agent SDK documentation structure
- API reference stubs
- Update GitHub workflow to build from root mkdocs.yml
- Add Material theme with dark/light mode toggle
The docs site will be available at hanzoai.github.io/python-sdk/
- Added comprehensive anti-stub test suite that detects:
- TODO/FIXME/STUB/FAKE/UNFINISHED patterns
- Empty functions with only pass/ellipsis
- NotImplementedError raises
- Mock implementations in production
- Debug prints in production
- Skipped tests
- Created strict GitHub Actions workflow that:
- BLOCKS deployment if ANY forbidden patterns found
- Requires ALL tests to pass (no skips allowed)
- Runs security scans
- Verifies all functions are implemented
- Only allows PyPI publish after ALL checks pass
- Added pre-commit hooks to catch issues locally before push
- Updated Makefile with 'make check' that runs all quality gates
- Fixed stub function issue in tools/__init__.py
This ensures we NEVER deploy incomplete or stub code to production again!
- Implement dual-mode orchestration: router-based (via hanzo-router) and direct API access
- Add GPT-5 Pro + Codex hybrid configuration for ultimate code development
- Create orchestrator_config.py with predefined configurations
- Support for router:model, direct:model, codex, and hybrid modes
- Add intelligent task routing based on complexity and cost
- Create comprehensive demos showing GPT-5 Pro via Codex usage
- Update CLI to support --orchestrator-mode and --router-endpoint options
- Document cost comparisons showing 29-90% savings with different configs
- Enable seamless switching between hanzo-router and direct API access
Configurations available:
- gpt-5-pro-codex: GPT-5 Pro + Codex hybrid (best for code)
- router:gpt-5: Access any model via hanzo-router
- direct:gpt-4o: Direct OpenAI API access
- codex: Pure Codex mode for code generation
- cost-optimized: Local + API hybrid (90% cost reduction)