feat(stats): make ST4TS model price table operator-tunable
The hive-wide cost estimate on the dashboard's ST4TS tab used a
hard-coded model->price table in hive_stats.rs. Anthropic list pricing
drifts, so move the table to a nix option operators can keep current
without a code change.
- New `services.hyperhive.modelPrices` option: attrset of model-family
short name -> { input, output, cache_read, cache_write } USD per
million tokens. Passed to `hive-c0re serve --model-prices <json>`.
- hive_stats: `Prices` is now public + Deserialize; add `PriceTable`
type and `resolve_prices` (longest case-insensitive substring key
wins) with the old hard-coded table preserved as `builtin_prices`
fallback for any model not covered.
- Coordinator holds the parsed table (hive-c0re-local, not injected
into containers, so not part of HiveEnv); `/api/stats-hive` reads it.
- Docs: dashboard.md ST4TS cost note updated; option self-documents
via nixosOptionsDoc.
Closes #1434
This commit is contained in:
parent
f5d9f325c6
commit
cc8f58fb24
6 changed files with 172 additions and 23 deletions
|
|
@ -423,6 +423,75 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
modelPrices = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
input = lib.mkOption {
|
||||
type = lib.types.float;
|
||||
description = "USD per million input tokens.";
|
||||
};
|
||||
output = lib.mkOption {
|
||||
type = lib.types.float;
|
||||
description = "USD per million output tokens.";
|
||||
};
|
||||
cache_read = lib.mkOption {
|
||||
type = lib.types.float;
|
||||
description = "USD per million cache-read tokens.";
|
||||
};
|
||||
cache_write = lib.mkOption {
|
||||
type = lib.types.float;
|
||||
description = "USD per million cache-creation (write) tokens.";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
default = {
|
||||
opus = {
|
||||
input = 15.0;
|
||||
output = 75.0;
|
||||
cache_read = 1.5;
|
||||
cache_write = 18.75;
|
||||
};
|
||||
sonnet = {
|
||||
input = 3.0;
|
||||
output = 15.0;
|
||||
cache_read = 0.3;
|
||||
cache_write = 3.75;
|
||||
};
|
||||
haiku = {
|
||||
input = 0.8;
|
||||
output = 4.0;
|
||||
cache_read = 0.08;
|
||||
cache_write = 1.0;
|
||||
};
|
||||
};
|
||||
example = {
|
||||
sonnet = {
|
||||
input = 3.0;
|
||||
output = 15.0;
|
||||
cache_read = 0.3;
|
||||
cache_write = 3.75;
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Per-model USD prices (per **million** tokens) used for the
|
||||
hive-wide cost *estimate* on the dashboard's ST4TS tab. Each key
|
||||
is a model-family short name matched case-insensitively as a
|
||||
substring of the active model id at runtime (e.g. `"sonnet"`
|
||||
matches `"claude-sonnet-4-5"`); the longest matching key wins, so
|
||||
a specific entry beats a generic family name. Any model not
|
||||
covered by this table falls back to hive-c0re's built-in
|
||||
estimate.
|
||||
|
||||
The defaults track Anthropic list pricing at the time of
|
||||
writing — override them here to keep the estimate current
|
||||
without a code change. Passed to `hive-c0re serve` as JSON via
|
||||
`--model-prices`; read only by hive-c0re itself (not injected
|
||||
into containers). Changes apply on the next host rebuild.
|
||||
'';
|
||||
};
|
||||
|
||||
agentCpuQuota = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "200%";
|
||||
|
|
@ -662,7 +731,7 @@ in
|
|||
);
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --nixpkgs-flake ${cfg.nixpkgsFlake} --nixpkgs-unstable-flake ${cfg.nixpkgsUnstableFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)} --agent-cpu-quota ${lib.escapeShellArg cfg.agentCpuQuota} --agent-memory-max ${lib.escapeShellArg cfg.agentMemoryMax}";
|
||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --nixpkgs-flake ${cfg.nixpkgsFlake} --nixpkgs-unstable-flake ${cfg.nixpkgsUnstableFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)} --agent-cpu-quota ${lib.escapeShellArg cfg.agentCpuQuota} --agent-memory-max ${lib.escapeShellArg cfg.agentMemoryMax} --model-prices ${lib.escapeShellArg (builtins.toJSON cfg.modelPrices)}";
|
||||
# Migrate hive-c0re's *own* state to the service user after an
|
||||
# upgrade from a root-run install (systemd's StateDirectory only
|
||||
# chowns the top-level dir, not pre-existing files inside it). The
|
||||
|
|
|
|||
Loading…
Reference in a new issue