CMDCGateway.Meter (cmdc_gateway v0.4.1)

Copy Markdown View Source

Usage Metering — per api_key 用量统计。

v0.2 起在 init/1 中通过 CMDC.EventBus.subscribe_all/0 真正订阅 所有 session 的事件流,自动响应:

  • {:agent_end, _messages, %CMDC.TokenUsage{}} → 累计三类 token + cost + cached
  • {:agent_end, _messages, raw_map} → 同上(兼容老 Provider 未归一化的 raw)

注意:prompt_count 在 Router 的 POST /v1/sessions/:id/prompt 端点同步 +1, 不通过 EventBus 监听 :prompt_received(避免 Router 手动计数 + 自动监听双重计数)。

api_key 通过 CMDCGateway.SessionStore.get/1 反查。

统计指标

  • :prompt_count — 总 prompt 请求数
  • :total_prompt_tokens — 累计输入 token 数
  • :total_completion_tokens — 累计输出 token 数
  • :total_tokens — 累计总 token 数
  • :total_cost_usd — 累计美元成本(v0.2 新增)
  • :cached_tokens — 累计 prompt cache 命中 token 数(v0.2 新增)
  • :last_activity_at — 最后活跃时间戳(毫秒)

查询

CMDCGateway.Meter.get_usage("my-api-key")
# => %{prompt_count: 42, total_tokens: 128_000, ...}

Summary

Functions

获取所有 api_key 的用量汇总。

Returns a specification to start this module under a supervisor.

获取某个 api_key 的累计用量。

记录一次 prompt 请求。

手动记录一次 token 用量(兼容老调用)。

重置某个 api_key 的用量。

重置所有用量数据。

Types

usage()

@type usage() :: %{
  prompt_count: non_neg_integer(),
  total_prompt_tokens: non_neg_integer(),
  total_completion_tokens: non_neg_integer(),
  total_tokens: non_neg_integer(),
  total_cost_usd: float(),
  cached_tokens: non_neg_integer(),
  last_activity_at: integer()
}

Functions

all_usage()

@spec all_usage() :: [{String.t(), usage()}]

获取所有 api_key 的用量汇总。

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_usage(api_key)

@spec get_usage(String.t()) :: usage()

获取某个 api_key 的累计用量。

record_prompt(api_key)

@spec record_prompt(String.t()) :: :ok

记录一次 prompt 请求。

v0.2 起 Meter 已自动通过 EventBus 监听 :prompt_received 事件;保留本函数 仅用于 Router HTTP 层的同步计数(请求被接收即增加,不必等 Agent 真正开始处理)。

record_tokens(api_key, usage)

@spec record_tokens(String.t(), map() | CMDC.TokenUsage.t()) :: :ok

手动记录一次 token 用量(兼容老调用)。

v0.2 起 Meter 已自动通过 EventBus 监听 :agent_end,本函数保留为外部 自定义场景使用。

reset(api_key)

@spec reset(String.t()) :: :ok

重置某个 api_key 的用量。

reset_all()

@spec reset_all() :: :ok

重置所有用量数据。

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()