100 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 21b511f665 CI/CD takes the pipeline's default runner
ci / python (push) Canceled after 0s
ci / go (push) Canceled after 0s
ci / wheel (3.12) (push) Canceled after 0s
ci / wheel (3.9) (push) Canceled after 0s
Hanzo CI/CD / cicd (push) Canceled after 0s
CI/CD / cicd (push) Canceled after 0s
deploy / image (push) Canceled after 0s
linux-amd64 is the label the forge starts runners for. hanzo.yml's
comments now name the workflow paths that exist.


Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 14:05:24 -07:00
zeekayandHanzo Dev 7439a34aff hanzo-agent 0.1.2
__version__ read the metadata of a distribution named agents, which is
not this package, so it and the User-Agent said 0.0.0. It reads
hanzo-agent now. The extensions package declared its own 0.1.0, which
nothing read.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 13:59:51 -07:00
zeekayandHanzo Dev 29d076a7d8 A leading think block is not the answer
Reasoning models served over OpenAI-compatible APIs can open a reply
with <think>...</think>. It stayed in final_output, in the history sent
back on the next turn, and in front of structured output, where it
failed JSON parsing. process_model_response, where every model's output
becomes run items, now drops a leading block from the message text.
Text that only mentions the tag, or an unclosed block, is unchanged;
tool call arguments and result.raw_responses keep what the model sent.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 13:59:49 -07:00
zeekayandHanzo Dev 79273cfa53 A 200 carrying an error object raises APIError
An OpenAI-compatible server can answer HTTP 200 with {"error": {...}}.
The openai client parses that as a result with no choices or output, and
the run died in a TypeError. Both model classes now raise
openai.APIError with the server's message and body, as the client does
for an error object inside a stream.

The test drives both routes through a local server. conftest imports
the Responses resource before swapping two of its classes for
factories; imported after, it subclasses a function and fails.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 13:55:06 -07:00
zeekayandHanzo Dev e1cd400abd The docs export only variables the SDK reads
The backend guide exported HANZO_ROUTER_URL and HANZO_API_KEY as a setup
step, but the SDK takes its endpoint and key from the client it is
given, and the openai client falls back to OPENAI_BASE_URL and
OPENAI_API_KEY. Reading HANZO_ROUTER_URL as well would be a second way
to set one thing, so the step is gone and the pooling example names
https://api.hanzo.ai/v1. A test fails when the docs export a variable
that neither package reads.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 13:50:13 -07:00
zeekayandHanzo Dev 9e1118f21d Traces go nowhere unless a processor sends them
Importing agents registered an exporter that posted every trace and
span to api.openai.com with the default client's key, so a run against
any other server sent its traces there and logged a 401. Nothing is
registered now. BackendSpanExporter takes the endpoint it posts to, with
no default and no OPENAI_* fallback. set_tracing_export_api_key and
use_for_tracing only fed that upload, so they are gone.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 13:48:35 -07:00
zeekayandHanzo Dev 3894aaaea6 A hanzo_agents tag publishes the SDKs
The wheel joins hanzo.yml's pypi lane and CI starts on hanzo_agents-v*
tags. release.yml publishes @hanzo/agents from the same tag, with the npm
credential read from KMS. The Go module resolves from an sdk/go/v* tag
beside it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 12:12:32 -07:00
zeekayandHanzo Dev ca8a8eb4b7 The SDKs here are the ones that shipped, under this repo's module path
hanzoai/agents carried the reconciled Go, TypeScript and Python SDKs:
memory in Base with one record schema across all three, scope ids
resolved the way the control plane resolves them, /v1 paths, one address
per vector operation, agents that start under Express 5, and suites that
run (Go green, 92 TypeScript, 527 Python). They come home here.

The Go module is github.com/hanzoai/agent/sdk/go, because the path has to
name the repository it is fetched from. The TypeScript manifest names its
versions directly and keeps npm's lockfile; this repo is not a pnpm
workspace. Versions are 0.2.10.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 12:12:32 -07:00
zeekayandHanzo Dev 56add66c20 The README runs, and make tests collects only tests/
The old README showed Web3Agent, a marketplace and a cli extension that
do not import from hanzo-agent 0.1.1, a HANZO_ROUTER_URL nothing reads,
and examples on gpt-4. It now shows a first agent and a function tool
that ran on Python 3.9 and 3.12 against a local OpenAI-compatible
server, how to point the client at api.hanzo.ai, and the extras whose
names import.

It also says what the defaults do: the Responses route unless
chat_completions is set, traces posted to api.openai.com with the
client's key unless tracing is off, the openai client's retry rules,
and a <think> block kept in final_output.

pytest picked up the stray scripts at the repo root, and
test_simple_anthropic.py exits on import, so make tests stopped at
collection. testpaths keeps it to tests/: 369 passed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 11:01:26 -07:00
zeekayandHanzo Dev 56ff389fc7 Every SDK calls /v1/, and they agree on the addresses
A sweep in May moved the Python SDK's paths to /v1/ per the estate rule
and recorded that the Go SDK already matched. It did not: the Go and
TypeScript SDKs still sent /api/v1/ everywhere, so the three clients for
one control plane disagreed about where it is. Python's own client was
missed too, which is why twelve of its tests failed the moment its suite
could be collected again.

Where they disagreed on more than the prefix, the majority decides. Go
alone posted a vector to the collection address rather than
/memory/vector/set, and alone deleted one by a keyed DELETE rather than
posting to /memory/vector/delete — no server serving the other two would
have answered either.

Notes now go to /v1/ui/executions/note from all three, built by
appending rather than by rewriting the first version segment found.

openrouter.ai/api/v1 is a third party's own address and is untouched.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 04:10:09 -07:00
zeekayandHanzo Dev 39557b9041 A Python agent can keep its memory in Base
BaseMemory stands where MemoryClient stands, with the same eight methods,
reading the same collection and schema as the Go and TypeScript stores so
all three SDKs see each other's records. Agent takes it as `store`, since
`memory` already names the property a handler reads through.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 04:10:09 -07:00
zeekayandHanzo Dev 116fc35319 The web3 extension imports, and says what is missing
eth-account was declared nowhere, so importing the shipped extension
failed on a clean install and its tests took the suite's collection with
them. It is a web3 extra now, which dev names once.

web3_agent and web3_network are no longer exported: they are written
against an agent model this package does not have — InferenceResult,
State, Router, RouterFn, a network module, and two sibling modules that
do not exist either. Importing them from the package __init__ made all
of it unimportable, including the two modules that are sound. Whether
this SDK grows a network model is a decision, not a rename.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 04:10:09 -07:00
zeekayandHanzo Dev 41b460b760 The Python client calls /v1/, which is what its tests assert
Every path in this suite registers /v1/... and none registers /api/v1/,
while the client built its base as {url}/api/v1 — so twelve client tests
failed the moment collection worked again. The extra segment is not a
shape this estate serves and nothing asserted it.

The UI subtree was built by replacing the first "/v1" found, under a
comment claiming it replaced the last. Appended instead, so a base url
carrying its own version segment cannot be rewritten. The test stub kept
a second copy of the client's base and had drifted from it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 04:10:08 -07:00
zeekayandHanzo Dev 183a0ff6fd The Python test suite can be collected
A rebrand pass rewrote HanzoAgents to "Hanzo Agents" inside identifiers,
53 times across twelve files. Two of them were class statements, so the
conftest was a syntax error and pytest could collect nothing at all: not
one test in this SDK has run since. The same pass damaged the TypeScript
SDK the same way.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 04:10:08 -07:00
zeekayandHanzo Dev 42b6746ff9 TypeScript agents start, and keep memory in Base
The agent's own server declared /api/v1/reasoners/* and /api/v1/skills/*
beside /reasoners/:name and /skills/:name. Express 5 rejects a bare `*`,
so the server threw on construction and 15 tests failed. The duplicates
are gone; the remaining routes match the Python SDK.

BaseMemory is the Base store in TypeScript, reading the same records the
Go backend writes. MemoryInterface takes a MemoryBackend rather than one
class, and AgentConfig.memory selects it.

The leak check collected garbage only under --expose-gc, so a normal run
measured collection timing: 30MB alone, under 25MB after other files had
warmed the heap. It now asks v8 for gc itself.

The default-provider test still asserted gpt-4o.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-11 00:04:20 -07:00
zeekayandHanzo Dev d4b80dd383 A clean install of the TypeScript SDK works
The committed lockfile named @hanzo/agents-sdk 0.1.25 while the manifest
says @hanzo/agents 0.1.41-rc.2, and every dependency in it was a major
version behind. npm ci refuses outright on that disagreement, so no
clean install of this SDK has succeeded — only an incremental one over
an already-populated tree.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 23:51:43 -07:00
zeekayandHanzo Dev 6a7d9ee935 Agent memory lives in Base
An agent can now keep its memory in Hanzo Base, so its state sits in the
same single binary as everything it runs beside: one record per scope and
key, in one collection, visible in Base's own admin view while the agent
is running. The collection ships as a schema to import rather than being
built on first write — a client that writes its own schema can write the
wrong one from a typo and then read nothing from the collection everyone
else is looking at.

The similarity search that every backend needs now exists once. The
in-memory backend answered every search with an empty list, which is the
one answer a caller cannot tell from "nothing was similar", and it holds
the vectors already. Filters were honoured by nobody. Both read the same
cosine and the same matcher now, so they cannot drift.

A scope id is caller data and rides a quoted filter clause, so the order
of escaping is load-bearing: backslashes double first, then quotes. The
other order lets a value ending in a backslash escape the closing quote
and end the literal where the caller chose.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 23:51:43 -07:00
zeekayandHanzo Dev 4a9e5e5dcc An SDK of ours points at us by default
Both clients defaulted to another company. Go's DefaultConfig read
OPENAI_API_KEY and api.openai.com; TypeScript's provider resolved to 'openai'
and its type union named ten third parties without naming Hanzo at all — so
the type itself said Hanzo was not a provider of its own SDK. A caller who set
an API key and nothing else sent that key elsewhere, and the examples in this
repo had to write the address out by hand to avoid teaching it.

Now HANZO_API_KEY selects api.hanzo.ai in Go, and `hanzo` is both a member of
the TypeScript union and the value an unset provider resolves to. It speaks the
OpenAI dialect, so it needs an address rather than a client.

Every explicit choice still does what it did. A third-party key selects that
provider's endpoint and a model it serves; naming a provider selects it.
OpenRouter still wins over OpenAI where both keys are present, which is the
precedence this package already had — their test named it, and my first attempt
inverted it.

The model default moves with the address, because "gpt-4o" against
api.hanzo.ai is not a request anybody can serve. zen3-vl, which is the default
the MCP runtime already carries, so the estate answers with one model rather
than each client picking its own.

TypeScript's two switches now share one provider-to-address function. They both
route the same four providers through the same client, and a copy of that
mapping in each is how they come to disagree about where `hanzo` lives.

The tests are hermetic now. They cleared three environment variables and not
HANZO_API_KEY, so once that variable meant something the suite passed or failed
according to the developer's shell. t.Setenv clears it and restores whatever
was there.

Both examples shrink to the short form, which is the point: `ai.NewClient(nil)`
and `new AIClient({ apiKey })` now reach our stack with nothing else said.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 23:35:33 -07:00
zeekayandHanzo Dev d789cf3aff Runnable examples for the two SDKs that had none
Thirty-five examples in this repo and every one of them is Python. Go and
TypeScript shipped clients with nothing showing how to call them, which is why
an outside adopter with working SDKs in front of them wrote their own.

Go's are Example functions rather than a main.go, so `go test` compiles them on
every run and `go doc` attaches them to Client.Complete. An example nobody
builds is prose that rots; this kind cannot drift from the API without turning
the build red.

TypeScript's two are in tsconfig's include for the same reason — outside it
they would typecheck never. tsup takes only src/index.ts and the package ships
only dist, so nothing here reaches the tarball.

Both set the endpoint explicitly, and that is the point rather than
boilerplate. Go's Config defaults BaseURL to api.openai.com and TypeScript's
provider union names ten third parties without naming Hanzo, so an example that
set only the provider would send our key to somebody else's endpoint. Worth
fixing in the clients; meanwhile the examples do not teach it.

Small things the examples make explicit because the first one a person copies
is the one they keep: a deadline on a network call, Choices checked rather than
indexed at zero, and an error printed as its message rather than as an object
that can carry a key into a log.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 23:29:28 -07:00
zeekayandHanzo Dev 6eba62c42f The TypeScript agent SDK did not parse
Three defects, and the first one meant `tsc` never reached the other two.

A rename had written the package name into an identifier:

    hanzo-agentsServerId: string;

A hyphen is not valid in an identifier, so this was a syntax error, not a type
error — the file could not be parsed at all. Three sites across DidClient and
DidManager. The wire field beside it is `hanzo_agents_server_id`, so the
property is `hanzoAgentsServerId`.

Behind it, two migrations the code never got although package.json asks for
zod ^4. `z.Schema<T, z.ZodTypeDef, any>` names a type v4 removed along with
that third generic; it is `z.ZodType<T>` now. And `zod-to-json-schema` reads
v3's internals and cannot type a v4 schema at all, so the converter was one
major version behind the schemas being handed to it — zod v4 ships its own,
and `openApi-3.0` emits no `$schema`, which is the property the old path
stripped by hand afterwards. Verified against the installed zod before
swapping it.

`mode` stays on this SDK's own options and is no longer forwarded: the ai
package removed it from generateObject, which now chooses for itself. Passing
it was one of the type errors, so nothing downstream had ever received it.

tsc --noEmit is clean. `npm run build` still fails, and not for our reasons:
tsup 8.5.1 calls TypeScript internals that TypeScript 7.0.2 removed, and it
fails the same way on a one-line file. That is a toolchain pin to raise, not
code to change.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 23:24:05 -07:00
zeekayandHanzo Dev bcfd76fe89 Release the wheel under its own name
`v*` belongs to the Go module -- Go reads the version off the tag and
the sumdb makes each one immutable, so v0.1.1 has named a Go commit
since long before the wheel wanted the number. Naming the distribution
in its tag gives the two artifacts one namespace each.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 22:00:09 -07:00
zeekayandHanzo Dev ebc42aa9a1 Build hanzo-agent on arm64
The wheel is py3-none-any, so nothing this repo publishes is a function
of the machine that built it, and asking for the default amd64 label
buys nothing while costing the only pool with capacity.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 21:53:46 -07:00
zeekayandHanzo Dev 5c7fe83dfc Release 0.1.1
0.1.0 is on PyPI unimportable -- no numpy in its metadata on 3.9, no
httpx on 3.12 -- and the fix for it has been on main since #12, reaching
nobody: pip takes the highest version, and this repo had no way to
publish a higher one. It built a wheel, installed it at both ends of its
classifiers, imported it and threw it away.

`pypi: [.]` is the lane. 0.1.1 because 0.1.0 is the highest published.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 21:45:38 -07:00
zeekayandHanzo Dev 20a823bd71 Pin the caller at @v2
@v1 resolves this pipeline's own tools from the CALLER's ref, so a v*
tag here made it clone hanzoai/[email protected] -- a ref that names nothing --
and the run died at step one. It also predates the publish lane, so
even a green one would ship nothing.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 21:45:38 -07:00
zeekayandHanzo Dev 6840a34cbb go 1.26.8
One toolchain across the estate. The tree carried 1.26.0, .1, .3, .4 and .5
at once, so which compiler built a binary depended on which repo it came
from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 23:51:00 -07:00
zeekayandHanzo Dev 13914817c0 Move the workflows to .github/workflows
The forge reads .github/workflows natively and github.com reads nothing else,
so one directory serves both planes instead of two conventions that disagree
about which one is live. The reusable in hanzoai/ci already lives there, so a
caller naming that path now resolves to a file that exists.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 19:31:58 -07:00
zeekayandHanzo Dev 12c4b724e6 ci: a runner label names the platform, not the org
hanzo-build-linux-amd64, lux-build-linux-amd64, zoo-build-linux-amd64 and
every other org-prefixed spelling all meant the same machine. Which org a
job belongs to does not change which host can build it, so the org bought
one pool name per org per arch and each could go stale on its own -- the
evo host alone answered to fourteen names for one label.

One vocabulary now: linux-amd64, linux-arm64, macos-arm64, win-amd64. The
generic labels every plain workflow uses (ubuntu-latest, self-hosted) are
untouched, so naive CI keeps working.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 12:09:47 -07:00
zeekayandHanzo Dev ecd6901fcf fix: call the pipeline at the address it actually lives
hanzoai/ci keeps the reusable at .github/workflows/build.yml — the one path
both planes resolve, since github.com reads a reusable only from there and the
forge reads it too. The v1 tag moved with it, so a caller still naming
.hanzo/workflows/build.yml asks for a blob that is not in the tree:

  InsertRun: read hanzoai/ci@v1:.hanzo/workflows/build.yml: object does not exist

The caller itself stays at .hanzo/workflows/cicd.yml on purpose: github.com has
no runner for these labels, so a caller placed there could never be scheduled.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 01:14:10 -07:00
zeekay 8a9138ab0c build ghcr.io/hanzoai/agent for arm64 as well as amd64
The lab runs both architectures, so an amd64-only image starts on half of
it. binfmt is registered before the builder so the arm64 layers can run
under emulation on this pool, and the resolve check now counts the
platforms the manifest carries: a list with one entry pulls fine on the
machine that built it and fails everywhere else, silently.
2026-09-05 19:07:02 -07:00
zeekayandHanzo Dev ee93678571 drop the rival PaaS deploy guide; simplify a redundant URL check
The internal-container check already covers the railway.internal
suffix, so the extra clause was dead weight.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-04 01:56:35 -07:00
zeekayandHanzo Dev be38b0bf34 chore: symlink AGENTS.md + GEMINI.md + CLAUDE.md -> LLM.md
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-02 02:23:54 -07:00
zeekay 6846f2d438 State a version once
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.
2026-08-29 18:13:22 -07:00
zeekay 24bebe3dfd the job asks for its runner the way the fleet answers
runs-on was a bare scalar. Jobs written that way queue and are never
picked up — link and quest have waited since 10 August, painter since the
5th, none of them with a single success — while repos writing the same
label as a sequence drain within seconds of a push on the same fleet.

Same label, same runners, different shape. It fails silently: nothing errors,
the job simply never starts, so the lane looks configured and does nothing.
2026-08-29 13:30:42 -07:00
zeekay 4e478099df Name Zen in the hero card's font stack
The social card asked for Inter first. That is not a face this estate
licenses, ships or ever drew, so a renderer with Inter installed painted
the wrong face and one without it silently fell through to system-ui.
Zen leads now; the same tail follows it.
2026-08-28 11:15:11 -07:00
zeekay e360ce8949 Depend on github.com/zap-proto/zip v1.34.2 2026-08-22 17:01:46 -07:00
zeekay 8ba9c6dc1f Depend on github.com/zap-proto/zip v1.34.1 2026-08-22 14:47:48 -07:00
zeekay d42c416b4f the address is the composer's, not this package's
The four routes were written at the literal /v1/agent, which is fine for the
standalone daemon and wrong for anyone else: a host whose router already spends
that address had no way to take this surface at all. It now composes off one
prefix — MountAt(app, prefix, ...) registers there, Mount(app, ...) is
MountAt at DefaultPrefix, so the daemon is unchanged and the host says where.

A prefix that is not an absolute path is refused at mount rather than
registering routes nothing can reach, and a trailing slash is the same address.
Nothing in the round reads the prefix, so the doc comments that named the old
literal now name the route.
2026-08-20 20:21:19 -07:00
zeekayandHanzo Dev 30139787e4 upstream attribution belongs in NOTICE, not in the README
The README is the product's front door and carries our brand. NOTICE is where a
fork's provenance is legally required to live, and it is the file a licence audit
reads. Naming the upstream in the README put attribution in the one place nobody
checks for it and branding in a place that had to share.

Where the NOTICE already named the same upstream, the moved line was dropped
rather than duplicated, and markdown link syntax was flattened -- NOTICE is plain
text, not a rendered document.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-20 20:21:19 -07:00
zeekayandHanzo Dev e923b630cf take the logger from the process, not from Deps
luxfi/log publishes a process default — Root, Default, and the bare Info/Warn/
Error — and cloud now installs it at the composition root, so a mount no longer
has to be HANDED a logger to have one.

Backward compatible on purpose: Default() resolves against any cloud, so this
lands before cloud removes the field rather than after. Nothing here reads
Deps.Logger now, which is what lets that field go.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-09 22:17:07 -07:00
zeekayandHanzo Dev 95bf3c587a ci: canonical pair — hanzo.yml + forge caller
github.com has no runner for hanzo-build-linux-amd64, so a caller under
.github/workflows is a gate that can never be scheduled. This is the ~7-line
caller on the plane that can (git.hanzo.ai git-runner fleet), pinned @v1.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-06 02:36:33 -07:00
zeekayandHanzo Dev bbe038af9d Point every Discord invite at the current Hanzo server (discord.gg/CJCyAsm9Vr)
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 21:45:22 -07:00
zeekayandHanzo Dev 9b08909e91 Point the Discord invite at the one that resolves
discord.gg/hanzo and discord.gg/hanzoai are both dead (no vanity configured
yet); discord.gg/XthHQQj is the live Hanzo guild invite. A vanity flip is one
find-replace away once the boosts land.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 21:13:11 -07:00
zeekayandHanzo Dev a9887d5bd1 deps: zip v1.23.0 -> v1.24.2
v1.24.2 is latest. No API changes here either: agent declares no typed ops
and no Group, so the op-id qualification that v1.23 introduced and v1.24
reverted never applied to it, and it has no zip Use call for v1.24's
lexical middleware scoping to reach.

agent_test.go's app.Fiber() is still the concrete *zip.App, which keeps
Fiber(); v1.24 removed it from (*wrapRouter), not from App. go vet
compiles the test package and passes.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 09:22:19 -07:00
zeekayandHanzo Dev 8c516ef678 deps: zip v1.18.22 -> v1.23.0
No API changes. agent registers four absolute /v1/agent paths directly on
*zip.App with untyped func(*zip.Ctx) error handlers and never calls Use,
Group, Load, Add, Graft or Prepare, so none of the v1.23 breaking changes
reach this module.

agent_test.go calls app.Fiber(), which is unaffected: v1.23 removed Fiber()
from the zip.Router interface, and this is the concrete *zip.App, which
still exposes it. go vet compiles the test package and passes.

Build, vet and test all clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-04 09:19:17 -07:00
zeekayandHanzo Dev 973ba3280a deps: zip v1.18.1 -> v1.18.22
Ten zip versions were live across the estate while the zipdoc/graft refactor
landed at v1.18.22. Verified by building this module against it, not assumed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 20:35:34 -07:00
zeekayandHanzo Dev b4ad07e8f2 deps: zip v1.17.2 -> v1.18.1
v1.18.0 added OpScope() to the Router interface and deleted zip/zaprpc. This
module implements neither and imports neither, so the upgrade is a pin move.
Verified by building and running this repo's own test gate before and after the
bump — no new failures.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 18:33:37 -07:00
zeekayandHanzo Dev 7f4619ea36 deps: zip v1.17.2 (+ http v0.3.1)
v1.17.2 is the fleet standard and agent sat seven minors back on v1.10.0.
Neither API break in that span reaches this package: AdaptNetHTTPFunc was
removed (agent adapts no net/http handler) and zip.Load was curried to
Load(p Plugin, prefixes ...string) (agent loads no plugin). agent uses only
zip.App / zip.Ctx / zip.Err* / zip.Errorf plus its own Mount seam, so the
move is go.mod-only.

http v0.3.1 rides along. It keeps v0.3.0's length-prefixed header frame and
only drops the remaining decode allocations, so there is no wire break
against peers already on v0.3.x — but a v0.2.x peer still cannot talk to
one, which is why the fleet moves together.

Builds clean; 10 tests pass.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 17:55:51 -07:00
zeekayandHanzo Dev 517817d579 chore(go): bump go directive to 1.26.5
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 16:10:08 -07:00
zeekayandHanzo Dev 887c29eca1 deps: zap-proto/zip v1.10.0 (+ hanzoai/orm v0.6.16)
zip v1.10.0 picks up zap-proto/http v0.3.0, where headers on the wire are
length-prefixed name/value pairs instead of a JSON map. That is a wire break — a
v1.10.0 process cannot talk to a v1.9.x one — so every ZAP service moves together.

orm moves in the same commit where it is a dependency: v0.6.14 called
zaphttp.NewTransport, which http v0.3.0 removed, so the two versions cannot be
split across a build.

Builds clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 10:28:58 -07:00
zeekay b1d0c00e13 ci: drop the Gitea mirror-sync nudge
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.

One mechanism, in one place, instead of ~350 copies of a cron.
2026-07-27 10:24:17 -07:00
zeekayandHanzo Dev 0ebad156a8 deps: zip v1.10.0 (+ http v0.3.0)
http v0.3.0 replaces the JSON header map in the ZAP frame with
length-prefixed name/value pairs ([u32 count][u32 nameLen][name]
[u32 valueLen][value]); decode is 0 allocs/op. This is a wire break —
a v0.2.x peer cannot talk to a v0.3.0 peer — so every zip consumer
moves together. Deployment is operator-managed GitOps, so merging
aligns code without shipping anything.

No source change: agent uses only zip.App / zip.Ctx / zip.Err* and its
own agent.Mount(app, deps, ...) seam, none of the APIs that moved
(zaphttp.NewTransport -> Dial, zip.RegisterTransport's Transport
struct, zip.App.Mount's remote-address proxy).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 10:08:38 -07:00
zeekayandHanzo Dev 31f32d57d5 deps: zip v1.9.0 (+ http v0.2.2, orm v0.6.15)
zip v1.9.0 brings Service/Add/Load/Reload/Unload, Mount(prefix, addr),
unix-socket ZAP, and Transport{Serve,Dial}; it requires zap-proto/http
v0.2.2. This package touches none of the changed surface — it uses only
zip.App/Ctx/New/Config and the zip.Err* constructors — so the bump is
a dependency move, not an API port.

The one break was transitive: orm v0.6.14's ZAP driver still called the
removed zaphttp.NewTransport. Fixed at its source in orm v0.6.15
(Dial("tcp", addr)) rather than pinned around here — a compile break in
a dependency is that dependency's bug.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 09:40:16 -07:00
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
zeekay ddb88d54a9 ci: nudge git.hanzo.ai to pull on push
git.hanzo.ai mirrors this repo by PULL on a ~10-minute interval, and arcd runs
CI/CD there — so every push waited out that interval before anything built.
This asks Gitea to pull HEAD immediately.

Latency only: the repo already mirrors via the App webhook, so a missing
HANZO_GIT_TOKEN or a failed curl is non-fatal and never fails the push.
Idempotent (mirror-sync just pulls HEAD) and concurrency-coalesced.
2026-07-27 08:07:35 -07:00
zeekay 71061cc337 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:53:51 -07:00
zeekay 6122f64166 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:53:50 -07:00
zeekay 4d12e71555 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:53:48 -07:00
zeekay 3a8830664f ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:53:46 -07:00
zeekay b1ea0829fe ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:53:45 -07:00
zeekayandHanzo Dev 790e1bdfdc deps: orm v0.6.14
Picks up the fixes that matter to any multi-tenant server on this stack:
With honours its context while a namespace is opening (a caller that had given
up used to stay parked for the whole S3 restore, and every retry parked
another); the shared open no longer runs on the triggering caller context, so
one client disconnect cannot fail the requests queued behind it; and Close
drains instead of closing a database out from under a live query.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 20:47:06 -07:00
zeekayandHanzo Dev 5c25684d98 fix(pypi): stop publishing this repo's dist as hanzoai
hanzoai on PyPI is the API client from hanzoai/python-sdk (3.1.1; all 12
releases carry that provenance). This repo declared the same dist name and
had a release-triggered PyPI publisher, so a release here would land a
different package under the name consumers expect to be the API client.

- remove .github/workflows/publish.yml; python-sdk is the one Python
  publisher and it already ships this SDK as hanzo-agent
- name the dist hanzo-agent, matching the PyPI project whose homepage is
  this repo, and carry the rename through the self-referential full extra
  so hatchling stops resolving it against hanzoai
- README/docs: install hanzo-agent, import agents, the top-level module
  the wheel ships
- docker-publish: build on hanzo-build-linux-amd64, not ubuntu-latest

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 19:28:29 -07:00
zeekay 0cf152af19 chore(deps): hanzokv/go v9.21.1 -> v9.22.0
v9.22.0 renames the package identifier from redis to kv. Nothing here imports
it — it is an indirect dependency — so this is a graph bump only, keeping the
version aligned with the repos that do import it.
2026-07-26 08:53:59 -07:00
zeekay 82cd170efb refactor(deps): follow the KV client to github.com/hanzokv/go
The KV client moved orgs (hanzoai/kv-go -> hanzokv/go) and this module reached
it transitively via hanzoai/orm, which has already migrated. Bumping orm lets
tidy drop the old path — no source here imported either client directly, so
there was nothing to edit, only a dependency to advance.
2026-07-26 00:55:16 -07:00
zeekay c400dcf69c merge: integrate held feature work onto main 2026-07-22 03:02:33 -07:00
zeekay bc429ccc89 consolidate: fork-hygiene NOTICE/branding sweep
# Conflicts:
#	README.md
2026-07-22 02:46:21 -07:00
zeekayandHanzo Dev 317b6344f9 refactor(go-openai): adopt the hanzoai/go-openai fork directly
The Completer interface + preset/round/agent exposed sashabaranov/go-openai
types, forcing every embedder (cloud) to stay on upstream go-openai or hit a
type mismatch at the hz.Mount boundary. Import the fork (github.com/hanzoai/
go-openai v1.41.0) directly so the whole stack shares ONE openai type set — no
replace, no per-consumer copy. Build + tests green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-17 22:10:44 -07:00
zeekay df6f881955 round: pass a completion refusal (402 insufficient_balance, 429, 403) through verbatim
The round masked every completion failure as a 502 "agent: completion: ...", so a
caller with no credits saw an opaque gateway error instead of the real billing
message. Add UpstreamError{Status,Body}: a Completer returns it for a caller-facing
4xx, and the round passes the status + body through unchanged (a client shows "add
credits"). A non-4xx failure (5xx/transport) stays a 502 — that IS a gateway fault.
Tests: 402 verbatim passthrough + 5xx-stays-502.
2026-07-16 23:51:18 -07:00
zeekay 181871a82b agent: ToolPlane.Dispatch takes the request — host resolves the caller the one canonical way (PrincipalFrom), no reconstructed principal/shim 2026-07-16 17:35:23 -07:00
zeekay 45a04c56e4 agent: hoist orchestrator to github.com/hanzoai/agent (one word, drop control-plane/pkg nesting)
The agent IS github.com/hanzoai/agent — package agent at repo root. POST /v1/agent
+ presets + per-org conversation history (zip+orm). Importable directly by ai/cloud.
2026-07-16 16:51:02 -07:00
zeekay 30f087fb0b docs: credit upstream openai/openai-agents-python (MIT) in README 2026-07-16 09:19:09 -07:00
zeekay 7cab8e2d11 chore(notice): pin OpenAI Agents SDK provenance and deviations; sweep product branding 2026-07-13 16:08:42 -07:00
zeekay 51bc6cc276 docs(brand): add hero banner 2026-06-28 20:14:48 -07:00
zeekay 080e5634db chore(brand): dynamic hero banner 2026-06-28 20:14:46 -07:00
zeekay 0ffe57e78b chore: restore upstream attribution + NOTICE (OSS compliance) 2026-06-21 02:10:06 -07:00
a53c6e348d ci: run on self-hosted ARC pool (hanzo-build-linux-amd64/deploy), not GitHub-hosted (#9)
Co-authored-by: zeekay <[email protected]>
2026-06-19 20:32:26 -07:00
zeekay b848086f01 corona→corona: academic Corona now only in lp-220-p3q-corona 2026-06-11 10:24:27 -07:00
zeekay 7bf7b5f8a4 deps: bump nested go.mod Go to 1.26.4
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); nested module catch-up.
2026-06-07 12:41:07 -07:00
zeekay d24511f5f0 docs: gRPC -> ZAP-native (LP-200) for control plane APIs 2026-06-07 12:41:07 -07:00
zeekayandGitHub c74d0bbf93 Merge pull request #4 from abhicris/feat/web3-mpc-signing-integration
feat(web3): MPC-signing integration for Web3 agents (closes #3)
2026-06-03 13:11:09 -07:00
zeekayandGitHub 0dc99595de Merge pull request #5 from abhicris/feat/2026-06-01-web3-src-mpc-parity
feat(web3): src/ tree MPC-wallet parity (closes #3, unblocks #4)
2026-06-03 13:07:35 -07:00
zeekay d2e47c44c3 network: wire cross-process agent dispatch over ZAP, gated on HANZO_AGENT_WIRE=zap
Closes the Hanzo-side LP-201 Tier 1 control-plane migration step. ZapClient
+ ZapAgent + consensus primitives already shipped in src/agents/zap/; this
landing wires the AgentNetwork-side cross-process lookup path.

New: agents/network/remote.py
  - RemoteAgentProxy: value-shaped facade quacking like Agent on the routing
    side (name + handoff_description) and dispatching invocations through
    ZapClient.call_tool(`agent/<name>`, …) on the wire side.
  - is_zap_wire_enabled(): single source of truth for the feature flag —
    one function, one place (Hickey-style profile gate). Reads HANZO_AGENT_WIRE
    case-insensitively; only the literal "zap" enables. Anything else
    fail-closed (json, "true", "1", unset → JSON/local-agent path).

AgentNetwork.add_remote_agent(name, zap_uri, …): cross-process counterpart
of add_agent. Holds a NetworkNode pointing at a RemoteAgentProxy; the router
reads it like a local agent (same capabilities/metadata surface). At
dispatch the proxy's invoke() pushes over the ZAP wire — and raises with a
clear message if the operator forgot to set the env var.

Default path (no env) keeps the JSON/OpenAI-compatible wire — external API
consumers see no change. ZAP is intra-cluster only.

Tests: 7 unit tests covering both feature-flag combinations + the clone()
mirror + the fail-loud guard, all green via --noconftest (existing conftest
pulls heavy deps; tests load remote.py directly via importlib, mirroring
test_zap.py).
2026-06-03 12:37:27 -07:00
zeekay 6430482a64 dockerfile: scratch + ghcr.io/hanzoai bases, drop gcr.io
deployments/docker/Dockerfile.demo-go-agent: switch runtime from
gcr.io/distroless/static-debian12:nonroot to FROM scratch. CA certs,
tzdata, /etc/passwd and /etc/group (nonroot uid/gid 65532) come from
the builder.

deployments/docker/Dockerfile.control-plane: switch runtime from
gcr.io/distroless/base-debian12 (glibc + sqlite_fts5 CGO needs libc)
to ghcr.io/hanzoai/debian12:base. TODO flagged for ghcr-auth in CI.
2026-06-02 03:41:38 -07:00
zeekay ab229f404f refactor: /v1/ canonical paths (sweep)
Per global rule: /v1/ only, never /api/. Internal Hanzo Agents control
plane URLs in the Python SDK now use /v1/* and /v1/ui/* canonically,
matching the Go SDK + control plane updates in hanzoai/agents.

Files touched: agent, agent_field_handler, agent_workflow, async_config,
async_execution_manager, did_manager, memory_events, vc_generator, plus
tests and perf tool. pyproject.toml left untouched (pre-existing dirty
state from unrelated numpy bump).
2026-05-18 22:35:16 -07:00
zeekay 2a584fc200 go.mod: bump go directive to 1.26.3 (security advisory) 2026-05-12 20:54:16 -07:00
zeekay eb0a25d64e ci: add id-token: write to caller permissions
Required for hanzoai/.github/.github/workflows/docker-build.yml@main —
without it the workflow_call dies as startup_failure with no jobs
dispatched. Caller permissions are a CEILING.
2026-05-07 09:09:12 -07:00
zeekay 6a191f0d7f fix(agent): close Red P0 findings — APIKeyAuth bypass + timing-safe + migration backfill order + NetworkPolicy
P0-1: internal/server/middleware/auth.go + grpc_auth.go — APIKeyAuth no
longer runs in series after RequireIdentity. The API key is the trust
boundary when apiAuth.enabled=true: identity headers become
informational, the key's bound org_id (loaded at validation) is
authoritative. Rejects 403 on X-Org-Id mismatch with key-bound org.
No more X-API-Key + attacker-chosen X-Org-Id = cross-tenant access.

P0-2: APIKeyAuth uses crypto/subtle.ConstantTimeCompare. Closes timing
leak on bearer-token compare.

P0-3: migrations/020_backfill_org_id.sql + 021_org_id_not_null.sql
sequence + scripts/audit-org-id.sh + MIGRATION_ORDER.md document the
deploy order: 019 add column → audit → 020 backfill from
created_by/users.org_id → verify zero empty rows → 021 NOT NULL +
CHECK constraint → flip AGENTD_REQUIRE_IDENTITY=true. Hard prereq
before any production migration.

CC: deployments/helm/hanzo-agents/templates/networkpolicy.yaml allows
ingress only from podSelector matchLabels app=hanzoai-gateway. Empty
X-Org-Id rejected at middleware in cloud mode (defense-in-depth).

Tests: pkg/auth + internal/server/middleware both PASS.
Closes Red 2026-04-27 agent findings.
2026-04-28 08:42:16 -07:00
zeekay fc05633a73 feat(helm): canonical Hanzo binary values for agentd
Updates deployments/helm/hanzo-agents/values.yaml to the canonical
Hanzo Go binary shape:
  - Image: ghcr.io/hanzoai/agents:v0.1.0 (CI-built per
    ~/.claude/CLAUDE.md, never local docker build)
  - Ingress: hanzoai/ingress className (NEVER nginx/caddy)
  - Domain: agents.hanzo.ai
  - Env:
      AGENTD_DATA_DIR=/data
      AGENTD_HTTP_ADDR=:8080
      AGENTD_REQUIRE_IDENTITY=true   ← multitenant gateway-trust

Older HANZO_AGENTS_* env names still work via the binary's
backward-compat reader; operator migrates by replacing the
canonical names in their values overlays.
2026-04-27 18:58:46 -07:00
zeekay ec02f14236 chore: symlink AGENTS.md and CLAUDE.md to LLM.md
Canonical project context lives in LLM.md. Symlinks ensure
agentic coding tools (Claude Code, Cursor, etc.) find context
automatically regardless of which filename they look for.
2026-04-01 14:10:38 -07:00
zeekay 18cf34a464 chore: cleanup — remove docker-compose.yml (use compose.yml), delete dead files 2026-03-25 01:52:10 -07:00
zeekay de451bfcbe fix: use ubuntu-latest for Docker build, drop arm64
The arm64 self-hosted runner (hanzo-build-linux-arm64) is offline,
causing build-arm64 to queue indefinitely then get cancelled. Switch
to ubuntu-latest for amd64-only builds since DOKS runs amd64.
2026-03-22 20:01:32 -07:00
zeekay eaea611118 chore: update dependencies to latest 2026-03-21 11:00:56 -07:00
zeekay e739d9241d fix: upgrade all Dockerfiles to golang:1.26 matching go.mod 2026-03-12 16:27:18 -07:00
zeekay 4441b8341a docs: add LLM.md project guide 2026-03-11 10:24:28 -07:00
zeekay b2237854e9 chore: update IAM auth integration and Go dependencies 2026-03-09 23:27:21 -07:00
zeekay 5b8d1f013f fix: correct Docker build context for control-plane 2026-03-02 10:23:17 -08:00
zeekay b344ff438d fix(ci): specify control-plane/Dockerfile for agent build 2026-03-02 08:54:15 -08:00
c4800c3e8d ci: switch to org-wide reusable Docker build workflow (#2)
Native amd64 (hanzo-build) + arm64 (hanzo-build-arm64) builds.
No QEMU. Uses hanzoai/.github/.github/workflows/docker-build.yml

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-02 08:28:24 -08:00
zeekay 853a86b8da rebrand: rename litellm module to llm — imports, providers, tests
LiteLLMProvider → LLMProvider, all imports and test fixtures renamed.
2026-02-25 15:13:18 -08:00
zeekay f977609b28 rebrand: replace litellm dep with hanzo-llm 2026-02-25 14:39:43 -08:00
zeekay e17b206ead feat: add agent canvas, collaboration, and IAM auth to control plane
- Add agent canvas with visual node editor, chat view, and collaboration cursors
- Add real-time collaboration infrastructure (contexts, hooks, presence)
- Add command palette, spaces, terminal panel, and side chat components
- Add IAM auth middleware and route handlers for server
- Add Hanzo branding (favicons, config, navigation updates)
- Update AuthContext/AuthGuard with enhanced auth flow
- Update Dockerfile and Makefile for control-plane builds
- Rebrand UI references and update dependencies across web client
2026-02-21 13:58:11 -08:00