Platform
AI gateway in Go
A Go package that every model call in a GoCommerce store goes through. On an install with an Anthropic key of its own, every store has AI with nothing to set up, paid from its AI credit; a store may bring its own key and a monthly cap instead. Every run is recorded, and switches decide which kinds of data may leave the store. Beside it sits a queue where a person approves what an agent proposes.
- Platform module
- 28 settings
- 100 tests
- 16 API operations
- ext/ai-gateway
What it does
In the package’s own words, it “is the one place in the engine that calls a model.” A module that wants model work does not write a prompt and call an API; it registers a named task in Go, with its instructions, the JSON Schema its answer must satisfy, a small and a strong model to try in turn, and a check of its own. The gateway runs it, records it and holds it to the store’s credit or cap.
Give the install an Anthropic key of its own, ANTHROPIC_API_KEY on the reference binary, and the AI gateway plugin is on for every store from the start. A store that enters no key runs on the install’s key, at the models and prices the install names, and each call is paid from the store’s AI credit: a free trial allowance it starts with, plus what the install’s operator tops up with the admin token. A store may paste its own Anthropic or OpenAI key instead; it is then billed by its provider and draws no credit. Without an install key the gateway installs idle, and a store needs a key, a monthly cap and a price for each model before anything is called.
Every run leaves one row in ai_executions: the task and its version, each step tried, the model that answered, the input, output and cache tokens, how long it took, the outcome, and the cost, which is tokens times the price per million in millionths of a minor unit, an integer with no rounding. The owner decides which kinds of store data may leave: the catalogue, order lines, contact details, message bodies and documents. Contact details and message bodies stay in until switched on, and documents too unless the install runs AI on its own key.
The panel gains an AI section with three screens: Usage, which sets this month’s spend by day, task and model beside the store’s AI credit; Jobs, the queue of model work with retry and cancel; and Approvals, where a person decides what an agent proposed. Four modules use the gateway today: Create from photos (photo-products), Improve with AI (catalog-ai), review summaries (reviews), and the Amazon importer’s rewrite of a listing. None has registered an action for the approval queue yet.
Configuration
The install’s own key, models, prices and currency rates are Config fields, which the reference binary reads from ANTHROPIC_API_KEY and the AI_PLATFORM_ variables. Everything a store chooses is a setting of the AI gateway plugin, under Settings › Plugins, read again on every run so a key or a cap typed a moment ago counts. The reference binary installs the module with -ai-gateway, and -photo-products and -catalog-ai bring it with them.
| Setting | Environment variable | Required | What it does |
|---|---|---|---|
PlatformAnthropicKey | ANTHROPIC_API_KEY | No | The install’s own Anthropic key. A store with no key of its own makes its calls on it and pays from its AI credit; the store never sees it. Empty: only a store with a key of its own has AI. |
PlatformSmallModel | AI_PLATFORM_SMALL_MODEL | No | The small model calls on the install’s key use. Empty is claude-haiku-5-5. |
PlatformStrongModel | AI_PLATFORM_STRONG_MODEL | No | The strong model calls on the install’s key use. Empty is claude-sonnet-5-5. |
PlatformSmallPrices | AI_PLATFORM_SMALL_PRICES | No | What Anthropic charges for the small model, in US dollars per million tokens: input, output, cache read and cache write. Empty is Anthropic’s published price for the default model. A model named without prices is not called on the install’s key. |
PlatformStrongPrices | AI_PLATFORM_STRONG_PRICES | No | The same, for the strong model. |
PlatformUSDRates | AI_PLATFORM_USD_RATES | No | Units of each currency to one US dollar, as comma-separated CODE=rate pairs. A store in US dollars needs none; a store in a currency with no rate cannot use the install’s key, because no rate is assumed. |
FreeTrialMinor | — | No | The AI credit each new store starts with, in minor units of its currency. The figure shipped is a placeholder for the install’s operator to set, and it can also be set per store with the admin token. Go only. |
providerProvider | — | No | anthropic or openai; anthropic by default. Used only with the store’s own key. Each provider’s API address is a constant in the code, so there is no custom address to set. |
api_keyAPI key | — | No | The store’s own key, from console.anthropic.com or platform.openai.com; calls are billed to it and draw no AI credit. Needed when the install has no key of its own; on one that has, the field reads “Use your own key instead” and may stay empty. A secret field, never handed to the storefront, and stored sealed when the install sets GOCOMMERCE_SECRETS_KEY. |
small_modelSmall model | — | No | Tried first, with the store’s own key. Defaults to claude-haiku-5-5, so a store on OpenAI names one of OpenAI’s models here. A store that saved its settings earlier keeps the model it saved. |
strong_modelStrong model | — | No | Asked when the small model’s answer fails its checks, with the store’s own key. Defaults to claude-sonnet-5-5. |
monthly_capMonthly cap | — | No | The most the store spends on models in a calendar month (UTC), in minor units of its currency: 5000 is 50.00 in a two-decimal currency. A fraction rounds down. Needed with the store’s own key; optional on the install’s, where the AI credit is the limit, and held there too when set. Work that would pass it waits for a person. |
small_price_inputSmall model: input price | — | No | Minor units per million input tokens, from your provider’s price list: $1.00 per million is 100. Needed with the store’s own key: a model without an input and an output price, or priced at 0, is never called. |
small_price_outputSmall model: output price | — | No | Minor units per million output tokens. A fraction rounds up, so it can only make the cap stricter. |
small_price_cache_readSmall model: cache read price | — | No | Per million tokens read from the provider’s cache. Empty or 0 means the input price. |
small_price_cache_writeSmall model: cache write price | — | No | Per million tokens written to the provider’s cache. Empty or 0 means the input price. |
strong_price_inputStrong model: input price | — | No | As for the small model. Without it, a run that climbs to the strong model stops there. |
strong_price_outputStrong model: output price | — | No | Minor units per million output tokens. |
strong_price_cache_readStrong model: cache read price | — | No | Empty or 0 means the input price. |
strong_price_cache_writeStrong model: cache write price | — | No | Empty or 0 means the input price. |
share_catalogueShare the catalogue | — | No | On by default. Product titles, descriptions, attributes and prices may be sent. |
share_order_linesShare order lines | — | No | On by default. What was bought, how many and the totals — never names or addresses. |
share_contact_detailsShare contact details | — | No | Off by default. Customers’ names, emails, phone numbers and addresses. |
share_message_bodiesShare message bodies | — | No | Off by default. The text of customers’ messages, which review summaries need. |
share_documentsShare documents | — | No | PDFs and images, sent to the provider as files. On by default when the install has a key of its own, so Create from photos works as it is; off otherwise. |
CallTimeout | — | No | Bounds one call to a provider; 60 seconds when zero. Go only. |
PollInterval | — | No | How often the job runner looks for due work; five seconds when zero. Go only. |
Client | — | No | Replaces the HTTP client, which tests do to answer in a provider’s place. The provider hosts stay constants either way. Go only. |
The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own main() you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.
Setting it up
- Install the moduleRun the reference binary with -ai-gateway, or with -photo-products or -catalog-ai, which bring it; or pass aigateway.New to gocommerce.New in your own main(), as below. The site’s backend + admin quick start does not install it.
- The install’s key, or each store’sGive the engine an Anthropic key in ANTHROPIC_API_KEY and every store with no key of its own runs on it; a store outside US dollars needs its currency in AI_PLATFORM_USD_RATES. Without an install key, each store sets a key, a monthly cap and each model’s prices under Settings › Plugins › AI gateway.
- AI creditEach store starts with a free trial allowance. The install’s operator tops a store up, or changes its free trial, on the AI usage screen with the install’s admin token. A store cannot buy credit itself.
- Give it workCreate from photos, Improve with AI and review summaries run through it, and so does the Amazon importer’s rewrite. A module of your own registers a task and runs it now, or queues it in the transaction that caused it.
main.go
import (
"os"
"github.com/itswadesh/gocommerce/core"
aigateway "github.com/itswadesh/gocommerce/ext/ai-gateway"
catalogai "github.com/itswadesh/gocommerce/ext/catalog-ai"
photoproducts "github.com/itswadesh/gocommerce/ext/photo-products"
"github.com/itswadesh/gocommerce/ext/reviews"
)
// With no install key it starts idle: nothing is called until a store sets a key, a cap and prices.
gw := aigateway.New(aigateway.Config{PlatformAnthropicKey: os.Getenv("ANTHROPIC_API_KEY")})
app, err := gocommerce.New(cfg, gw,
photoproducts.New(photoproducts.Config{Gateway: gw}),
catalogai.New(catalogai.Config{Gateway: gw}),
reviews.New(reviews.Config{Gateway: gw}),
) Wired as the reference binary wires it in cmd/gocommerce/main.go; cfg is your gocommerce.Config. Hand the gateway to the Amazon importer the same way, amazon.Config{Gateway: gw}, to move its rewrite onto it. Import path github.com/itswadesh/gocommerce/ext/ai-gateway.
How it works
-
One run, one record
A run tries the task’s deterministic step, then the cache, then each model on its ladder. An answer is checked against the task’s schema with unknown fields refused, then by the task’s own check; one that fails moves up the ladder with the reason written down.
-
Reserved before the call
The most a call could cost, every input token at the dearest input-side price plus every output token, is held with one conditional UPDATE against the store’s AI credit on the install’s key, and against the month’s cap, so runs racing for the last of the money cannot both have it. Afterwards it is settled to what the provider reported.
-
Cost in integers
Prices are minor units per million tokens, so a call costs tokens times price in millionths of a minor unit, exact with no division. The install’s dollar prices become the store’s currency at its rate, rounded up. A call that left and reported nothing back is charged at its ceiling and marked as an estimate.
-
The install’s key stays the install’s
A store never sees the install’s key. When Anthropic refuses a call on it, the store sees the status and the kind of failure, and the operator’s log has Anthropic’s words. A store’s own key that will not open is not quietly swapped for the install’s.
-
Only what the owner allows leaves
A task tags what it sends by class, and a class the owner has not allowed is dropped before sending. With contact details off, an email address or an international phone number found elsewhere is replaced. What is sent is fenced in <data> blocks the model is told to treat as data.
-
Retries only where waiting helps
Queued work is claimed with FOR UPDATE SKIP LOCKED, stores taking turns. A timeout, a rate limit or a provider outage is retried with backoff, up to 12 attempts; a refusal, an answer that fails on the strong model, a spent cap or credit, or a missing price goes straight to failed, for a person.
-
Approval runs what was seen
A proposal waits seven days. Its preview is recomputed when opened and again on approval; if the store moved in between, nothing runs. Only a person signed in to the panel decides — not an API key or the admin token — holding ai.approve and the action’s own right.
What it does not do
Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.
- Anthropic and OpenAI onlyTwo providers, each at a fixed host: Anthropic’s Messages API and OpenAI’s chat completions, and the install’s own key is Anthropic’s. There is no custom address, so a self-hosted or other model cannot be reached through the gateway, and a provider that redirects is not followed.
- No credit, no callsOn the install’s key, a store with no AI credit left is refused before any model is called, and a store cannot buy credit itself: the install’s operator tops it up with the admin token. On a store’s own key, a missing key, cap or price stops the call, and a model priced at 0 is never called.
- A currency needs a rateThe install’s key is priced in US dollars. A store in another currency can use it only when the install gives that currency a rate; otherwise the store is told so and nothing is sent.
- The approval queue has no actions yetThe queue, its rules and its screen are built, but no module registers an action, so nothing can be proposed into it today. Agent keys only read for the same reason.
- Nothing queues work yetEvery task today, from photos to review summaries, runs directly rather than through the job queue, so the Jobs screen stays empty until a module queues work.
- No embeddingsAn Embedder interface is declared and nothing implements it. There is no vector or semantic search.
- Not in the quick startThe site’s backend + admin quick start does not install the AI gateway. It is a module you install when you run GoCommerce yourself, and this page describes the module, not any hosted panel.
- Not tried against a live providerThe tests run against PostgreSQL, with each provider answered by a recorded response from a local test server; none calls Anthropic’s or OpenAI’s real API.
FAQ
Questions about the AI gateway module
Does a store need its own key?
Not on an install with an Anthropic key of its own: the plugin is on for every store, pictures may be sent, and a store with no key runs on the install’s, paid from its AI credit. Without an install key, a store sets its own key, a monthly cap and each model’s prices before anything is called.
Which models can it use?
On the install’s key, the models the install names: Claude Haiku 5.5 and Claude Sonnet 5.5 unless AI_PLATFORM_SMALL_MODEL and AI_PLATFORM_STRONG_MODEL say otherwise. On a store’s own key, whatever that key reaches, named in the Small model and Strong model settings: claude-haiku-5-5 and claude-sonnet-5-5 by default on Anthropic, or OpenAI’s models by name. Check connection on the AI usage screen says whether the provider offers each name.
Who pays for the calls?
On the install’s key, the store pays per use from its AI credit, starting with a free trial allowance. Only a model call draws credit: a cached answer, an answer worked out without a model and every feature that is not AI draw none. On its own key, the store pays its provider and draws no credit; the gateway works out each call’s cost from the prices typed in and stops at the monthly cap, and the provider’s bill is the one that counts.
Does customer data reach the model?
Only the kinds the owner allows. The catalogue and order lines are allowed by default, and documents too on an install with its own key; contact details and message bodies are off until switched on. With contact details off, an email address or an international phone number that slipped into other data is replaced before sending, and each run’s record keeps the policy it ran under.
Is this an Anthropic or OpenAI partnership?
No. The module calls their public APIs with the install’s key or one the store supplies. Neither company endorses GoCommerce, and no store is known to run this module in production.
Source
Everything on this page is read from ext/ai-gateway in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.Anthropic, Claude and OpenAI are trademarks of their owners; this module calls their public APIs with the install’s key or one the store supplies, and implies no endorsement by either company. See trademarks.
Try it against a store of your own
The backend + admin quick start runs GoCommerce’s API and admin on your own machine, without a storefront. Add this module to it and try it on test orders before a real one depends on it.