pricing

package
v1.801.462 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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. 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

func GateRootData(data map[string]any, snap map[string]Overlay, org string, isAdmin bool)

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 Mount

func Mount(app cloud.Router, deps cloud.Deps) error

Mount registers the pricing surface on app per HIP-0106.

func RunSync

func RunSync(ctx context.Context) (string, error)

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 Shutdown

func Shutdown(context.Context) error

Shutdown drops the goja host and closes the catalog overlay store. Idempotent.

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

type Model map[string]any

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

func VisibleCatalog(full []Model, snap map[string]Overlay, org string, isAdmin bool) []Model

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.

func (Overlay) State

func (o Overlay) State() string

State is the tri-state label (off|beta|ga) an operator sets and the console renders. Derived from (Enabled, Beta) so there is ONE source of truth.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL