mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-13 17:09:07 +02:00
[management] Return default rates with each discovered model
The endpoint reported pricing_known and then made the operator find the price themselves. The dashboard has nothing to prefill a model row with, so a discovered model either arrived at zero — silently metering every request against it as free — or had to be priced by hand against a table NetBird already ships. Each model now carries the rates it would actually be billed at. Rates come from the live default pricing table rather than the compiled-in catalog, because that is the table the synthesiser ships to the proxy: an operator running a defaults_llm_pricing.yaml would otherwise be shown one price in the form and charged another. It is the same lookup the catalog endpoint prefills from, so a model reached by either route prices identically — pinned by TestDiscoveredRatesMatchTheCatalogEndpoint, since the two are separate call paths that would otherwise drift. pricing_known now derives from that same lookup instead of a second pass over the compiled catalog, so "we can price this" and "here is the price" can no longer disagree. input_per_1k and output_per_1k are required and sent even at zero: an unpriced model is offered at zero and flagged rather than withheld — the vendor says the credential can reach it, and hiding it would hide a model the operator genuinely has. The cache rates stay absent when unset, matching the catalog response, because a zero there reads as "free" rather than "not applicable".
This commit is contained in:
@@ -125,7 +125,20 @@ func (h *handler) discoverProviderModels(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
out := api.AgentNetworkModelDiscoveryResponse{Models: make([]api.AgentNetworkDiscoveredModel, 0, len(models))}
|
||||
for _, m := range models {
|
||||
entry := api.AgentNetworkDiscoveredModel{Id: m.ID, PricingKnown: m.PricingKnown}
|
||||
entry := api.AgentNetworkDiscoveredModel{
|
||||
Id: m.ID,
|
||||
PricingKnown: m.PricingKnown,
|
||||
// Sent even when zero: the form prefills every discovered model as
|
||||
// an editable row, and an unpriced one is shown at zero and flagged
|
||||
// rather than left out.
|
||||
InputPer1k: m.InputPer1k,
|
||||
OutputPer1k: m.OutputPer1k,
|
||||
// Cache rates stay absent when unset, matching the catalog
|
||||
// response — a zero would read as "free", not "not applicable".
|
||||
CachedInputPer1k: positiveRatePtr(m.CachedInputPer1k),
|
||||
CacheReadPer1k: positiveRatePtr(m.CacheReadPer1k),
|
||||
CacheCreationPer1k: positiveRatePtr(m.CacheCreationPer1k),
|
||||
}
|
||||
if m.Label != "" {
|
||||
label := m.Label
|
||||
entry.Label = &label
|
||||
|
||||
Reference in New Issue
Block a user