LibreChat/api/server/controllers/agents
Danny Avila 4ee68d5240
💸 feat: Per-Agent Endpoint Token Config in Multi-Endpoint Billing (#13738)
* 💸 feat: Per-Agent Endpoint Token Config in Multi-Endpoint Billing

Price each collected/emitted usage item with the producing agent's resolved
endpoint token config, instead of the primary agent's for the whole graph.

Previously AgentClient.recordCollectedUsage and the subagent usage emitter used
a single this.options.endpointTokenConfig (the primary's) for every usage item.
A connected agent or subagent on a different custom endpoint that shares a model
id with an entry in the primary's tokenConfig was therefore mis-priced (a model
absent from it already fell back to the built-in rate map — no regression).

- Tag each usage with its producing agent: ModelEndHandler stamps
  usage.agentId = agentContext.agentId; createSubagentUsageSink stamps the
  child's subagentAgentId (UsageMetadata gains an optional agentId).
- buildAgentToolContext retains endpointTokenConfig so initialize.js can build
  an agentId -> endpointTokenConfig map from agentToolContexts (the one map that
  holds every agent, including pure subagents pruned from agentConfigs).
- AgentClient.resolveAgentEndpointTokenConfig(usage) looks up that map by
  agentId, falling back to the primary config; used by both the billing path
  (new optional resolveEndpointTokenConfig on recordCollectedUsage) and the
  subagent cost emitter.
- recordCollectedUsage's resolver is optional and falls back to the batch
  endpointTokenConfig, so the shared responses.js/openai.js call sites are
  unchanged.
- Tests: two-endpoint graph with a colliding model id prices per-agent; resolver
  nullish falls back to batch; subagent sink tags the child agent id.

* fix: Align emit-path cost with per-agent billing; honor known-agent built-in pricing

Addresses Codex review on the per-agent endpoint token config:
- Emit path (callbacks.js) now prices each on_token_usage event with the
  producing agent's config (resolved via usageCost.resolveEndpointTokenConfig),
  so streamed/persisted metadata.usage.cost matches the per-agent balance
  transaction. The agentId tag is resolved server-side and stripped from the
  emitted/persisted payload.
- Resolver (resolveAgentTokenConfig) now treats a known agent's config as
  authoritative, including undefined → built-in pricing, so a known non-custom
  agent in a custom-primary graph is no longer charged the primary's rates.
  Only untagged/unknown usage falls back to the primary config.
- endpointTokenConfigByAgentId records every known agent (value may be
  undefined) so the resolver distinguishes known-no-rates from unknown.
2026-06-14 12:00:32 -04:00
..
__tests__ 💸 feat: Per-Agent Endpoint Token Config in Multi-Endpoint Billing (#13738) 2026-06-14 12:00:32 -04:00
callbacks.js 💸 feat: Per-Agent Endpoint Token Config in Multi-Endpoint Billing (#13738) 2026-06-14 12:00:32 -04:00
client.js 💸 feat: Per-Agent Endpoint Token Config in Multi-Endpoint Billing (#13738) 2026-06-14 12:00:32 -04:00
client.test.js 🧠 fix: Bound Memory Agent Input (#13606) 2026-06-09 14:38:21 -04:00
errors.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
filterAuthorizedTools.spec.js 🧠 refactor: Memoize MCP Permission Checks Per Request (#13419) 2026-05-30 18:32:06 -04:00
openai.js 🧾 fix: Bill Subagent Child-Run Model Usage in Parent Transactions (#13683) 2026-06-13 14:55:48 -04:00
recordCollectedUsage.spec.js 🪢 chore: Consolidate Pricing and Tx Imports After tx.js Module Removal (#12086) 2026-03-21 14:28:53 -04:00
request.js 🧵 fix: Reject Preliminary Parent Follow-Ups (#13619) 2026-06-09 12:06:51 -04:00
responses.js 🧾 fix: Bill Subagent Child-Run Model Usage in Parent Transactions (#13683) 2026-06-13 14:55:48 -04:00
v1.js 🧭 fix: Restore Empty Skill Allowlist Catalog (#13526) 2026-06-05 12:30:48 -04:00
v1.spec.js 🧭 fix: Restore Empty Skill Allowlist Catalog (#13526) 2026-06-05 12:30:48 -04:00