Request to address this comment before merging: https://github.com/ComposioHQ/hermes/pull/9861/#discussion_r3236035984
Meters every matched customer-facing trigger delivery and ships connected_account_id on each event so Metronome can derive active_connections server-side via SQL COUNT(DISTINCT) over tool_calls + triggers. No Apollo cron, no daily summarizer.
Metering pipeline:
metering/entities/triggers.ts — new metered entity, connected_account_id required (rejected as empty string in schemas.ts superRefine)events/types/trigger_delivery_usage.ts — new context event composio.usage.trigger_delivery, wired into the PlatformEvent discriminated unionevents/handlers/usage_metered/handler.ts — new arm builds the canonical triggers payload + Stripe customer enrichmenttriggers/handleTriggerInstances.ts — emits the context event from sendTriggerUpdatesToCustomer after fan-out kick-off; fire-and-forget (void emitEvent(...).catch(...)) matching the precedent set by the tool_call_usage and tool_router_session_usage emit sitespages/api/v3/internal/trigger/resend_log.ts — passes skipMetering: true so operator resends don't double-bill (each resend mints a fresh log id)triggers/dbUtils/types.ts + 7 Prisma include sites — extends TriggerInstanceWithAuthConfigToolkitProject to load project.org (need org.nanoId at the emit site)metering/constants.ts — adds metering_trigger_type + metering_delivery_status enums (replaces inline magic strings)metering/webhooks/billable_metric_ids.ts — real Metronome metric UUIDs for staging (d68c118f-...) and prod (2202c6a5-...); follows the existing SESSIONS_* / TOOL_CALLS_* hardcoded-by-design pattern (file's own header comment justifies)Usage API support:
metering/usage_breakdown/types.ts — triggers entry added to BREAKDOWN_GROUP_BY_KEYS (group_by axes: trigger_slug, toolkit_slug, connected_account_id, trigger_type, auth_config_id, user_id, project_id; default trigger_slug). Tightened to as const satisfies Record<MeteredEntityType, BreakdownConfig> so adding a new entity to metering_entity_type is a compile error at the literal if breakdown config is missing — replaces a runtime check with type-level enforcementmetering/usage_breakdown/validation.ts — drops the now-redundant isBreakdownEntityType runtime branch (BreakdownEntityType === MeteredEntityType by construction)pages/api/v3.1/{org,project}/usage/[entity_type].ts + metering/usage_api/breakdown_http_schemas.ts — OpenAPI descriptions mention triggers as a valid entity type and the default group_by⚠️ Deploy steps:
triggers to Doppler METRONOME_ENABLED_ENTITIES (staging → prod) — gates Metronome billing only; ClickHouse + v3.1 usage APIs are live on mergeNotes:
env-var-check CI failure is a known false positive on the hardcoded metric UUIDs — same pattern as existing SESSIONS_* / TOOL_CALLS_* entries in mastersendTriggerUpdatesToCustomer (TRIGGER_MESSAGE + trigger_delivery_usage) into one event with two consumers per @lingalarahul7's review feedback. Current dual-event design matches the precedent from tool_calls / sessions; out of scope for this PRpnpm with-env vitest run src/lib/metering src/lib/events src/lib/triggers/handleTriggerInstances.test.ts → 212/212 passing, 8 skipped (live-CH gated)connected_account_id rejection), 3 handler arm tests, 3 emit tests on sendTriggerUpdatesToCustomer (payload, skipMetering honored, ordering regression guard via mock.invocationCallOrder), 1 integration test exercising emitEvent → handler → deliver, 3 breakdown contract tests (triggers accepted, default group_by = trigger_slug, unsupported group_by rejected), 2 live-CH round-trips (direct write + handler-driven emit, both extracting connected_account_id via JSONExtractString — same SQL Metronome's Active Accounts metric runs)APOLLO_LIVE_CLICKHOUSE_METERING=true against local CH → 3/3 pass (sessions, tool_calls, triggers in both deliver_direct_metering_event_live.test.ts and usage_metered_platform_event_live.test.ts)pnpm format:check / pnpm check-types / pnpm lint clean (1 unrelated pre-existing warning)Request to address this comment before merging: https://github.com/ComposioHQ/hermes/pull/9861/#discussion_r3236035984
Add the lowest-priority metered entities after the main billing surfaces are live.
active_connections events and aggregate them3-5 engineering days
| May 21, 2026 5:16am |
Based on git blame analysis of 27 file(s):
| Contributor | Contribution | Files |
|---|---|---|
| haxzie | 61% | 18 |
| shams haroon | 17% | 26 |
| anshugarg15 | 11% | 7 |
| lingalarahul7 | 7% | 13 |
| Zen | 1% | 3 |
🤖 Based on git blame with recency weighting (recent edits count more).
:x: Patch coverage is 92.34043% with 18 lines in your changes missing coverage. Please review.
| Flag | Coverage Δ | |
|---|---|---|
| e2e-tests | 6.17% <72.64%> (+0.11%) | :arrow_up: |
| self-hosted-tests | 5.57% <0.42%> (-0.04%) | :arrow_down: |
| thermos-unit-tests | ? | |
| unit-tests | 58.87% <68.80%> (+0.13%) | :arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
| Files with missing lines | Coverage Δ | |
|---|---|---|
| ...pps/apollo/src/lib/events/types/trigger_message.ts | 100.00% <100.00%> (ø) | |
| apps/apollo/src/lib/metering/constants.ts | 100.00% <100.00%> (ø) | |
| apps/apollo/src/lib/metering/entities/index.ts | 100.00% <100.00%> (ø) | |
| apps/apollo/src/lib/metering/entities/triggers.ts | 100.00% <100.00%> (ø) | |
| apps/apollo/src/lib/metering/schemas.ts | 90.29% <100.00%> (+1.04%) | :arrow_up: |
| ...s/apollo/src/lib/metering/usage_breakdown/types.ts |
... and 328 files with indirect coverage changes
100.00% <100.00%> (ø) |
| ...llo/src/lib/metering/usage_breakdown/validation.ts | 100.00% <ø> (+13.15%) | :arrow_up: |
| apps/apollo/src/lib/triggers/dbUtils/types.ts | 100.00% <ø> (ø) |
| .../apollo/src/lib/triggers/handleTriggerInstances.ts | 93.75% <100.00%> (+0.18%) | :arrow_up: |
| ...c/lib/metering/usage_api/breakdown_http_schemas.ts | 0.00% <0.00%> (ø) |
| ... and 9 more |