Skip to content

initSquadTelemetry() should auto-wire EventBus, CostTracker, and token metrics #281

Closed

Description

@bradygaster

Problem

Currently, getting full telemetry from the Squad SDK requires ~30 lines of manual wiring per app:

  1. Import RuntimeEventBus, CostTracker, recordTokenUsage separately
  2. Create an EventBus instance and pass it to initSquadTelemetry({ eventBus })
  3. Create a CostTracker and call costTracker.wireToEventBus(eventBus)
  4. Subscribe to the session's usage event and manually forward it to the EventBus as a session:message event
  5. Call recordTokenUsage() yourself to populate the OTel metric counters (squad.tokens.input, squad.tokens.output, squad.tokens.cost)
  6. Print costTracker.formatSummary() at shutdown

Without all of this, users only see squad.sessions.active and squad.sessions.created in their Aspire/OTel dashboard — no token counts, no cost data, no per-agent breakdowns.

Additionally, the SDK's client.js puts token data as span attributes (tokens.input, tokens.output) on the squad.session.stream span, but never calls recordTokenUsage() to fire the metric counters. So even with a properly configured OTel endpoint, the squad.tokens.* metrics never appear.

Discovery

Found while wiring telemetry across the Squad IRL samples. All 19 samples needed identical boilerplate. The pattern works, but it shouldn't require this much ceremony.

What users have to do today

import { initSquadTelemetry, RuntimeEventBus as EventBus, CostTracker, recordTokenUsage } from '@bradygaster/squad-sdk';

const eventBus = new EventBus();
const telemetry = initSquadTelemetry({ eventBus });
const costTracker = new CostTracker();
costTracker.wireToEventBus(eventBus);

// ... after creating session ...
session.on('usage', (event) => {
  const inputTokens = event.inputTokens ?? 0;
  const outputTokens = event.outputTokens ?? 0;
  const model = event.model ?? 'unknown';
  const cost = estimateCost(model, inputTokens, outputTokens); // user must provide pricing!

  recordTokenUsage({ type: 'usage', sessionId: session.sessionId, model, inputTokens, outputTokens, estimatedCost: cost, timestamp: new Date() });
  eventBus.emit({ type: 'session:message', sessionId: session.sessionId, payload: { inputTokens, outputTokens, model, estimatedCost: cost }, timestamp: new Date() });
});

Proposed Solution

initSquadTelemetry() should handle all of this internally. Ideal API:

const telemetry = initSquadTelemetry();
// That's it. Everything lights up.

Specifically:

  1. Auto-create EventBus internally if none is provided
  2. Auto-wire CostTracker to the internal EventBus
  3. Have client.js call recordTokenUsage() in sendMessage() and sendAndWait() — not just set span attributes
  4. Auto-forward session usage events to the EventBus when sessions are created via SquadClient
  5. Include model pricing in the SDK so users don't have to maintain their own pricing table
  6. Expose the CostTracker on the returned handle: telemetry.costTracker.formatSummary()

Bonus: SquadClient integration

If SquadClient accepted an optional eventBus parameter, it could auto-wire session events internally:

const client = new SquadClient({ cwd: process.cwd(), eventBus: telemetry.eventBus });

Impact

  • Every SDK consumer currently gets incomplete telemetry unless they know the internal architecture
  • The squad.tokens.* OTel metrics are defined but never populated through normal usage paths
  • Cost reporting requires users to maintain their own model pricing table

Current Workaround

See commit 63bf0b1 in Squad IRL for the full pattern applied across 19 samples.

Activity

  1. github-actions commented on Mar 9, 2026

    @github-actions
    Contributor

    📋 Assigned to Telemetry (Aspire & Observability)

    Issue: #281 — initSquadTelemetry() should auto-wire EventBus, CostTracker, and token metrics

    Telemetry will pick this up in the next Copilot session.

    For Copilot coding agent: If enabled, this issue will be worked automatically.
    Otherwise, start a Copilot session and say:
    Telemetry, work on issue #281

  2. github-actions commented on Mar 13, 2026

    @github-actions
    Contributor

    📋 Assigned to Telemetry (Aspire & Observability)

    Issue: #281 — initSquadTelemetry() should auto-wire EventBus, CostTracker, and token metrics

    Telemetry will pick this up in the next Copilot session.

    For Copilot coding agent: If enabled, this issue will be worked automatically.
    Otherwise, start a Copilot session and say:
    Telemetry, work on issue #281

  3. deleted a comment from github-actions on Mar 18, 2026
  4. added
    squadSquad triage inbox — Lead will assign to a member
    on Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or improvementnext-upPriority queue — next issues to workpriority:p2Next sprintsquadSquad triage inbox — Lead will assign to a memberstatus:doneWork completed and shippedtype:featureNew capability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions