Hanzo

Code

Package code is search and symbols across your repos, for you and your agents.

Package code is search and symbols across your repos, for you and your agents.

Base URLhttps://api.hanzo.ai
Operations7
AuthAuthorization: Bearer $HANZO_API_KEY

Specification

HIP-1114 · Code — Search and Symbols — Draft · read the specification →

/v1/code is search and symbols across an org's repositories, for people and for their agents: a per-org code-intelligence engine implemented in hanzoai/cloud apps/code. Retrieval is hybrid — lexical, symbolic and semantic tiers fused with reciprocal-rank fusion — because embeddings alone under-serve code search (apps/code/code.go:3-6). This HIP states the three tiers, the physical org boundary of the store, and how the one paid dependency (embeddings) is attributed.

Motivation

An agent editing code needs three different questions answered well: "where does this string appear" (exact, including operators and case conventions), "where is this symbol defined and used" (structural), and "what code means this" (semantic). Each tier serves one of them and fails at the others; a single-tier engine forces every question through the wrong index.

Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.

§1 The three tiers

  • lexical — FTS5 trigram over code-tokenized text: camelCase and snake_case split, operators kept; substring and regex in the Zoekt model (apps/code/store.go, tokenize.go).
  • symbolicgo/parser for Go, with real def→ref edges; compact lexical extractors for TS/JS, Python, Rust and Solidity (apps/code/parse.go).
  • semantic — AST-boundary chunks embedded through the same gateway /embeddings the knowledge plane uses, ranked by cosine over a float32 vector table; the schema is kept compatible with a sqlite-vec vec0 KNN as a future seam, not a linked dependency today (apps/code/store.go:561).

hybrid fuses the tiers; a caller may also pin one with type=.

§2 The store

One SQLite file per org at {DataDir}/orgs/{slug}/code.db (HIP-0302): the org boundary is physical, so a query in one org's file can never reach another org's rows (apps/code/code.go:17-19). Stores open lazily through the shared cloud.OrgStore cache, and storeFor is the one way the package reaches one (apps/code/code.go:91, code.go:141-150). Bounds cap what one request can amplify into the shared file or the gateway (apps/code/code.go:47-58).

§3 The addresses

Everything is under /v1/code: search, context (a budget-packed context bundle), ask (a cited RAG answer), index (incremental, with prune), file and tree. All operations are typed (apps/code/typed_wire_test.go). /v1/code/lsp is NOT this capability: the live language server is its own capability routed by prefix specificity (manifest/apps.go:315,325), folded under this address because static index and live server are two reads of one repository.

§4 Tenancy and money

Every request resolves its org through principal.Org (HIP-0026): no validated principal, 403; a client X-Org-Id is never trusted. The surface itself is free (plugin/code/main.go:21, cloud.Free). Its embedding calls are billed where inference is always billed — on the AI plane — attributed to principal.Ledger and the server-minted project, neither of which may be an input field (apps/code/code.go:176-189). Off the HTTP path both are empty, which is the unbilled default — and principal.Acting has already refused before any op runs.

§5 Events, telemetry, stage, upstreams

It publishes no events on the bus and emits nothing to observability beyond the request span. Its stage is ga: the manifest row (manifest/apps.go:315) declares no stage, and absent means ga. It embeds no third-party engine: parsing is the Go standard library plus this package's own extractors, storage is the hanzoai/sqlite facade, and the lexical design follows the trigram model Zoekt demonstrated without importing it.

Rationale

The alternative to per-org files is one index with an org column — cheaper to operate, and one forgotten predicate away from serving one tenant's source to another. Source code is the asset tenants trust the platform with least willingly, so the boundary is physical and the cost (an open file per active org, amortized by the store cache) is accepted.

The alternative to fusing three tiers is picking one. Embeddings-only misses exact identifiers; lexical-only cannot answer "what code does this"; fusion is the measured lesson of code retrieval and each tier stays independently testable (apps/code/search.go).

Security Considerations

The store is an index of private source. The wrong implementation leaks it two ways: across tenants (closed physically, §2) or through the paid seam — an attacker who can set the billing org or project on an embedding call can charge inference to a victim, which is why payer and project come only from validated, server-minted values (§4). ask answers only from the caller's own org's index, so the RAG surface cannot become a cross-tenant oracle.

Four surfaces

SurfaceReaches this capability asCoverage
RESTcode at its own prefix7 operations
CLIhanzo code …7 of 7
SDKCodeApi in every published client7 methods
MCPtool code on https://api.hanzo.ai/v1/mcp7 operations, 4 under the document's own id — ask describe for the rest

Quickstart

export HANZO_API_KEY=sk-...   # console.hanzo.ai → API keys

Then the first call — a read that needs nothing but the key. GET /v1/code/ask, operation get_code_ask:

hanzo code ask get

Answers 200 with object — ok.

Endpoints

EndpointWhat it does
GET /v1/code/askAnswers a question about the caller org's code with a CITED answer: retrieval packs grounding context, then the synthesizer writes the answer over…
POST /v1/code/askIs askGet with the question in the request BODY, for a question too long or too awkward to put in a URL.
POST /v1/code/contextPacks the most relevant code for a query into a token budget — THE primitive for a coding agent that has to decide what to put in a prompt.
GET /v1/code/fileReturns the INDEXED content of one file — read_file over the chunks the search tiers hold, for pulling up code an agent just found.
POST /v1/code/index(re)indexes a repository for the caller's org, incrementally: files whose content hash is unchanged are skipped, so re-sending a whole tree is cheap.
GET /v1/code/searchFinds code in the caller org's index across three orthogonal retrieval tiers fused by reciprocal-rank fusion: lexical (FTS5 trigram over…
GET /v1/code/treeReturns one repository's file structure with a per-file symbol count — get_repo_structure over the org's own index, with no git checkout involved.

All Hanzo APIs · Interactive reference

How is this guide?

On this page