Documentation
¶
Overview ¶
Package pricing is the price list: what every model, provider, GPU tier, tool and hosting plan costs.
It serves /v1/pricing/* — plus the enablement registry that decides which catalog entries a caller may even see (/v1/enablement{,/optin,/optout} and the SuperAdmin /v1/admin/{catalog,enablement}).
It shares the @hanzo/plans catalog with apps/plan, so eight of its sections (cloud, subscriptions, blockchain, gpu, tools, policy, and the cloud/{regions,storage} pair) answer the same data /v1/plans/* answers at a second address.
HONEST GOJA STATUS: @hanzo/pricing is an EXPRESS app. Express needs Node's http/net stack and CANNOT run in goja. So the Express *transport* is dropped and replaced by native zip routes; the pricing *handlers* (pure transforms over data/pricing.json + the @hanzo/plans catalog) run in goja via the goja/bundle.js shipped by github.com/hanzoai/pricing. The sync.mjs MARKUP logic (toMTok/roundPrice/processOpenRouterModel/…) also runs in goja through the bundle's applyMarkup(); the only thing that does NOT run in goja is the live network fetch (OpenRouter/HuggingFace — no fetch/AbortController in goja), which this wrapper performs with Go's net/http and then feeds the raw JSON into applyMarkup. See SyncEnabled.
Module boundary: pricing source + markup logic live in hanzoai/pricing. This wrapper is glue. No pricing data or markup math is reimplemented in Go.
IAM gating + X-Org-Id: read endpoints are open to any authenticated caller (the public pricing catalog). The sync trigger is admin-only (c.IsAdmin()).
Index ¶
- Variables
- func GateRootData(data map[string]any, snap map[string]Overlay, org string, isAdmin bool)
- func Mount(app cloud.Router, deps cloud.Deps) error
- func RunSync(ctx context.Context) (string, error)
- func Shutdown(context.Context) error
- func VisibleProviders(providers map[string]any, snap map[string]Overlay, org string, isAdmin bool) map[string]any
- type Model
- type Overlay
Constants ¶
This section is empty.
Variables ¶
var Prefixes = []string{
"/v1/admin/catalog",
"/v1/admin/enablement",
"/v1/enablement",
"/v1/pricing",
}
Prefixes are the absolute subtrees this subsystem answers on. It serves four, not the one the /v1/<name> convention would assume: the catalog read plane (/v1/pricing), the self-service enablement plane (/v1/enablement) and the two admin planes over the same overlay store (/v1/admin/catalog, /v1/admin/enablement).
Declaring them is not decoration. cloud.Declare builds the prefix table that resolves a request's subsystem label and its declared Price from this, and cloud's scope refuses middleware a subsystem installs outside what it declared — so an undeclared subtree is one whose requests are attributed to somebody else and on which this subsystem cannot install the typed-op Bridge. The same four are listed in manifest/apps.go, which the light host reads to route to this plugin; that copy is a literal on purpose (the host must not import an app package), so the two are kept equal by hand.
Functions ¶
func GateRootData ¶
GateRootData gates the kitchen-sink root payload (GET /v1/pricing returns the whole pricing blob) IN PLACE, so the root shows the exact same gated catalog as the leaf routes — never an un-gated second source. It filters every field that carries a model or provider identity:
- hanzoModels + thirdPartyModels via VisibleCatalog,
- providers via VisibleProviders,
- the id-reference lists freeModels and families[].models, kept only if the referenced model survived the gate (customers); admins keep every ref.
Aggregate summary counts and non-catalog sections (tools/infrastructure/cloud) carry no catalog identity and are left untouched.
func RunSync ¶
RunSync performs the live third-party model sync: fetch upstream listings (network — Go's net/http, since goja has no fetch), run the markup transform in goja via the bundle's applyMarkup(), and swap the shaped third-party section into the served catalog. Returns an ISO timestamp.
This is the HONEST split: network IO in Go, markup math in JS. Only the dynamic third-party section is refreshed here; the Zen catalog + cloud/DO pricing in sync.mjs need the zen-gateway + DO credentials and stay on the standalone sync path for now.
func VisibleProviders ¶
func VisibleProviders(providers map[string]any, snap map[string]Overlay, org string, isAdmin bool) map[string]any
VisibleProviders filters a provider dict (name -> info) by the provider overlay for org, merging provider overrides (RFC 7386). isAdmin callers get every provider with state annotated under each provider's "_overlay".
Types ¶
type Model ¶
Model is one catalog entry exactly as the @hanzo/pricing bundle emits it (see goja/bundle.js 'models'): an opaque JSON object. The gate reads only the identifier (id, falling back to name) and provider, and passes every other field through untouched — keeping the bundle authoritative for shape.
func VisibleCatalog ¶
VisibleCatalog applies the enablement overlay to the bundle's full model list for org. A model is visible iff its OWN overlay AND its provider's overlay both admit org (enabled, or org on the beta list); an entry with no overlay row is visible by default, so a provider with no row never hides its models. Returned models carry any admin override merged on top (RFC 7386). isAdmin callers receive EVERY model — disabled ones included — each annotated under "_overlay" so the admin UI can render and toggle it.
Pure over (full, snap, org, isAdmin): no IO, no globals. This is the unit under test; the wiring layer fetches `full` from goja and `snap` from the store, then calls it.
type Overlay ¶
type Overlay struct {
Kind string `json:"kind"`
ID string `json:"id"`
Enabled bool `json:"enabled"`
Beta bool `json:"beta,omitempty"`
BetaOrgs []string `json:"betaOrgs,omitempty"`
Overrides json.RawMessage `json:"overrides,omitempty"`
UpdatedAt int64 `json:"updatedAt,omitempty"`
}
Overlay is the mutable enablement STATE for one catalog entry. Zero value (no row) == enabled, no beta orgs, no override; the gate treats an absent row as visible, so an empty store is a no-op.
Tri-state (the #30/#31 enablement model), encoded by (Enabled, Beta):
- ga = Enabled → visible to EVERYONE.
- beta = !Enabled && Beta → hidden from the public; visible to opted-in/ granted orgs (BetaOrgs). Users may SELF-OPT-IN to a beta item.
- off = !Enabled && !Beta → hidden from EVERYONE, absolutely. BetaOrgs are IGNORED — a self-opt-in can never bypass an `off` kill switch.