Files
zeekay c6dc8ac2f7 Hanzo Team
The Go transactor and account service for Hanzo Team.

History starts here. The previous 107 commits carried the fork's origin in
their messages and their tree, and none of it described this code: the Go
under pkg/transactor is Hanzo's own work implementing a wire protocol, not
a port of anyone's implementation.

pkg/transactor/model.json remains, and remains attributed. It is a compiled
platform model this transactor loads through go:embed, governed by EPL-2.0
and named in NOTICE. Removing it is a replacement project -- a new compiler
and a move off the protocol -- not a deletion.
2026-08-30 17:07:38 -07:00

53 lines
1.8 KiB
TypeScript

/// <reference path="./types.d.ts" />
//
// AI assistant — formerly the `ai-bot` + `love-agent` pods in the upstream
// Node stack. Now runs inside Goja, one goroutine per request, served
// by the team binary on /v1/ai/*.
//
// Real chat + tool calling is delegated to hanzo.bot via
// pkg/bot/bot.go (/v1/bot/*). This handler is a small helper that
// the Svelte UI calls for inline "explain" / "summarize" actions
// where we want a single completion, not a streaming chat.
routerAdd("POST", "/v1/ai/complete", (e) => {
// platform plugin already validated the JWT; e.auth is set.
if (!e.auth) {
return e.json(401, { error: "auth required" });
}
const body = e.requestInfo().body as { prompt?: string; model?: string };
if (!body?.prompt) {
return e.json(400, { error: "prompt required" });
}
const endpoint = $os.getenv("LLM_GATEWAY_URL") || "https://api.hanzo.ai/v1";
const apiKey = $os.getenv("HANZO_API_KEY");
if (!apiKey) {
return e.json(503, { error: "LLM_GATEWAY not configured" });
}
// Talk to the Hanzo LLM Gateway (api.hanzo.ai/v1/chat/completions)
// using the request's owner as the billing tenant header.
const owner = e.auth.get("owner") || "";
const res = $http.send({
method: "POST",
url: `${endpoint}/chat/completions`,
headers: {
"Authorization": `Bearer ${apiKey}`,
"X-Org-Id": owner,
"X-User-Id": e.auth.id,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: body.model || "zen",
messages: [{ role: "user", content: body.prompt }],
max_tokens: 512,
}),
timeout: 30,
});
if (res.statusCode >= 400) {
return e.json(res.statusCode, { error: "llm upstream error", upstream: res.body });
}
return e.json(200, JSON.parse(res.body));
});