Agent skill

Output Dev Cost Hooks

by growthxai in growthxai/output

Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system.

Apache-2.0Auto-check passedDevOps & Cloud

Install Output Dev Cost Hooks

skills CLI
$ npx skills add growthxai/output --skill output-dev-cost-hooks -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install growthxai/output output-dev-cost-hooks --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/growthxai/output.git skills-src && mkdir -p .claude/skills && cp -r skills-src/coding_assistants/claude/plugins/outputai/skills/output-dev-cost-hooks .claude/skills/output-dev-cost-hooks && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
output-dev-cost-hooks
GitHub stars
442
Token cost
~2.7k tokens
SKILL.md length
748 words
Files
1
Skills in repo
50
Repo updated
First seen
Licence
Apache-2.0

At a glance

Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system.

  • Works in 2 steps: Create a hook file → Register the file
  • Adding cost/spend logging
  • SKILL.md covers Overview, When to Use This Skill, Setup and Events You Can Subscribe To, plus 5 more sections
  • Calls npm; reaches docs.output.ai

What it does

Output Dev Cost Hooks is an agent skill from growthxai/output. Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system. Use when adding cost/spend logging, building a cost observability integration, or forwarding per-request cost data to an external system.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in DevOps & Cloud, covering Observability and Payments and billing. The repository describes itself as: The open-source TypeScript framework for building AI workflows and agents. Designed for Claude Code describe what you want, Claude builds it, with all the best practices already… The licence is Apache-2.0.

When your agent uses it

  • Adding cost/spend logging
  • Building a cost observability integration
  • Forwarding per-request cost data to an external system

Example prompts

  • “/output-dev-cost-hooks”

Requirements

  • Pre-approved tools (allowed-tools): Read, Write, Edit, Glob

Workflow steps

2 steps, taken from the step headings in SKILL.md.

  1. Create a hook file
  2. Register the file

What it can do on your machine

Read from SKILL.md and the folder at commit 99ee298. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit
    • Glob

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • docs.output.ai

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Output Dev Cost Hooks loads about 2.7k tokens when it runs. Until then it costs about 73 tokens; SKILL.md has 748 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~73
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from growthxai/output at commit 99ee298, republished under its Apache-2.0 licence (© growthxai). 748 words, ~2,666 tokens.

Download SKILL.mdSave it as .claude/skills/output-dev-cost-hooks/SKILL.md (or your agent's skills folder).
name
output-dev-cost-hooks
description
Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system. Use when adding cost/spend logging, building a cost observability integration, or forwarding per-request cost data to an external system.
allowed-tools
Read, Write, Edit, Glob

Cost Observability Hooks

Overview

This skill documents how to subscribe to Output's cost events so every priced LLM call and every HTTP call with attached cost (via addRequestCost, see output-dev-http-client-create) can be forwarded to your own observability system — a webhook, a structured log pipeline, a metrics backend, etc. Handler errors are caught and logged by the framework; they never affect the workflow or the request that triggered them.

When to Use This Skill

  • Forwarding per-call spend to an external observability/webhook endpoint
  • Logging cost events as structured fields for a log platform
  • Building alerting or dashboards on top of workflow spend
  • Auditing which workflows/activities are driving cost, in real time rather than after the fact

This skill is about project-wide hook registration for cost data already emitted by the framework. To make an HTTP client emit cost in the first place, see output-dev-http-client-create.

Setup

1. Create a hook file
typescript
// src/cost_hooks.ts
import { on } from '@outputai/core/hooks';
import type { HttpRequestCostEvent } from '@outputai/http';
import type { LLMGenerationMeteringEvent } from '@outputai/llm';

on<HttpRequestCostEvent>('cost:http:request', async event => {
  // handle HTTP cost
});

on<LLMGenerationMeteringEvent>('llm:generation:metering', async event => {
  // handle LLM cost
});
2. Register the file

Add the file to outputai.hookFiles in package.json, alongside any existing hook files. Paths are relative to the package root and point at the built .js output — npm run output:worker:build compiles src/ to dist/ (per tsconfig.json's rootDir/outDir), so src/cost_hooks.ts is registered as dist/cost_hooks.js, not the .ts source itself. The worker loads these files at startup.

json
{
  "outputai": {
    "hookFiles": [
      "./dist/cost_hooks.js"
    ]
  }
}

If you'd rather skip the build step, a hook file can also be plain, uncompiled JavaScript registered directly at its src/ path ("./src/cost_hooks.js") — see https://docs.output.ai/operations/error-hooks for that variant. The rest of this skill uses TypeScript + the built-output path, since that's what the framework's own examples (and every other file in a scaffolded project) use.

Events You Can Subscribe To

EventType importWhen it firesPrefer for
llm:generation:meteringLLMGenerationMeteringEvent from @outputai/llmAfter every LLM generation (text, image, Agent, streaming) that reports usage — including failed calls that got at least partial usageNew LLM cost integrations
cost:llm:requestLLMUsageEvent from @outputai/llmLegacy/compatible LLM cost event, same completion pathExisting handlers only — do not use for new work
cost:http:requestHttpRequestCostEvent from @outputai/httpOnly when your code (or a client's afterResponse hook) calls addRequestCost(response, total)Non-LLM paid API calls

Every event carries the same envelope: eventId (UUID v4, stable idempotency key), eventDate (ms epoch), activityInfo and workflowDetails (present when emitted from within a step/evaluator), outputActivityKind, and payload (the event-specific data described above).

Pattern 1: Forward to an external endpoint

Use this when spend needs to reach an external observability system over HTTP. Forward the raw envelope plus payload; redact anything that might carry secrets (API keys or tokens embedded in query strings) before logging or sending the URL.

typescript
// src/cost_hooks.ts
import { on } from '@outputai/core/hooks';
import { credentials } from '@outputai/core/credentials';
import type { HttpRequestCostEvent } from '@outputai/http';
import type { LLMGenerationMeteringEvent } from '@outputai/llm';

// Use plain fetch here, not createKyClient/outputFetch. Handlers run inside
// the emitting step's async context, so a traced client would add its own
// HTTP trace event to that step's trace on every forwarded cost event.
//
// Read the credential lazily with `get`, not `require`, at module scope: a
// hook file is imported at worker startup by an unguarded `await import()`
// (there's no try/catch around it), so a `require()` that throws here takes
// the whole worker down. `get`/`require` also only see workflow-scoped
// credentials from inside an activity — at startup, outside any activity,
// they resolve the global credential set only, so keep this in a global
// (not per-workflow) credential file.
const getWebhookUrl = (): string | undefined => credentials.get('observability.webhook_url') as string | undefined;

const postEvent = async (json: Record<string, unknown>): Promise<void> => {
  const webhookUrl = getWebhookUrl();
  if (!webhookUrl) {
    return;
  }

  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 5000);
  try {
    await fetch(`${webhookUrl}/events`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(json),
      signal: controller.signal
    });
  } finally {
    clearTimeout(timeout);
  }
};

// Strip query strings — some APIs put API keys or tokens there.
const redactUrl = (url: string): string => {
  try {
    const parsed = new URL(url);
    return `${parsed.origin}${parsed.pathname}`;
  } catch {
    return '[unparseable-url]';
  }
};

on<HttpRequestCostEvent>('cost:http:request', async event => {
  if (!event.workflowDetails || !event.payload) {
    return;
  }

  // A caught failure here logs with this handler's own context; an
  // uncaught one is still caught and logged by the framework either way.
  try {
    await postEvent({
      eventId: event.eventId,
      eventDate: event.eventDate,
      workflowId: event.workflowDetails.workflowId,
      kind: 'http',
      url: redactUrl(event.payload.url),
      totalUsd: event.payload.total
    });
  } catch (error) {
    console.warn('cost_hooks: failed to forward HTTP cost event', error);
  }
});

on<LLMGenerationMeteringEvent>('llm:generation:metering', async event => {
  if (!event.workflowDetails || !event.payload) {
    return;
  }

  try {
    await postEvent({
      eventId: event.eventId,
      eventDate: event.eventDate,
      workflowId: event.workflowDetails.workflowId,
      kind: 'llm',
      providerId: event.payload.usage.providerId,
      modelId: event.payload.usage.modelId,
      totalUsd: event.payload.cost?.total ?? null
    });
  } catch (error) {
    console.warn('cost_hooks: failed to forward LLM cost event', error);
  }
});

Pattern 2: Structured logging

Use this when spend just needs to land in your log platform as structured facets, without a separate network call. Use the framework Logger so fields are emitted consistently with the rest of the worker's logs.

typescript
// src/cost_hooks.ts
import { on } from '@outputai/core/hooks';
import { Logger } from '@outputai/core';
import type { HttpRequestCostEvent } from '@outputai/http';
import type { LLMGenerationMeteringEvent } from '@outputai/llm';

const log = Logger.createLogger('CostObservability');

const redactUrl = (url: string): string => {
  try {
    const parsed = new URL(url);
    return `${parsed.origin}${parsed.pathname}`;
  } catch {
    return '[unparseable-url]';
  }
};

on<HttpRequestCostEvent>('cost:http:request', async event => {
  if (!event.workflowDetails || !event.payload) {
    return;
  }

  log.info('http_request_cost', {
    eventId: event.eventId,
    workflowId: event.workflowDetails.workflowId,
    url: redactUrl(event.payload.url),
    totalUsd: event.payload.total
  });
});

on<LLMGenerationMeteringEvent>('llm:generation:metering', async event => {
  if (!event.workflowDetails || !event.payload) {
    return;
  }

  log.info('llm_generation_cost', {
    eventId: event.eventId,
    workflowId: event.workflowDetails.workflowId,
    providerId: event.payload.usage.providerId,
    modelId: event.payload.usage.modelId,
    totalUsd: event.payload.cost?.total ?? null
  });
});
Show full SKILL.md (288 more words)Show less

Handler Safety Rules

  • Handlers are wrapped in try/catch by the framework. A thrown or rejected handler is caught and logged (e.g. <eventName> hook error) and never affects the workflow, the worker, or the request that triggered the event — the same guarantee onError handlers get. Adding your own try/catch is still worthwhile so a forwarding failure logs with context you control, but it's not required for safety.
  • Skip incomplete events. Guard on event.workflowDetails and event.payload before using them — they're only populated when the event was emitted from within a step/evaluator context; eventId and eventDate, by contrast, are always present.
  • Redact before logging or sending URLs. Some third-party APIs embed API keys or tokens in query strings. Strip the query string (and any path segments you know carry secrets) before it leaves the process.
  • Use eventId as an idempotency key when forwarding to a system that might receive the same event more than once (e.g. retried delivery).
  • Expect one event per attempt. A step or evaluator that retries emits one cost event per attempt — that's correct, since each attempt is a real billed call.
  • Prefer llm:generation:metering over cost:llm:request for new integrations; the legacy event's shape is frozen and misses newer cost types (e.g. tool/grounding charges).

Verification Checklist

  • Hook file registered in outputai.hookFiles in package.json, pointing at the built .js path (dist/...), not the .ts source
  • Hook file imports on from @outputai/core/hooks
  • Handlers guard on missing workflowDetails / payload
  • URLs are redacted (query string stripped) before logging or forwarding
  • llm:generation:metering used instead of legacy cost:llm:request for new work
  • output-dev-http-client-create - Attaching cost to a paid API client with addRequestCost
  • output-dev-workflow-cost - Post-hoc cost calculation for a single completed workflow run via the CLI
  • output-dev-credentials - Storing the observability endpoint URL/token as a credential

© growthxai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in coding_assistants/claude/plugins/outputai/skills/output-dev-cost-hooks of growthxai/output.

Open the folder on GitHubat commit 99ee298

Compare with similar skills

Output Dev Cost Hooks next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Output Dev Cost Hooks compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Output Dev Cost Hooks this skillgrowthxai/output442—~2.7kAutomated safety check: PassApache-2.0
Distributed Tracingwshobson/agents40k12 repos~527Automated safety check: PassMIT
Workers Best Practiceshodgef/apiker1276 repos~1.8kAutomated safety check: PassMIT
Backend DesignxenitV1/claude-code-maestro229—~2.1kAutomated safety check: NotesMIT
Add Metricmicrobus-io/fabric172—~1.5kAutomated safety check: PassApache-2.0
OmniRoute Health Monitoringdiegosouzapw/OmniRoute75k—~1.2kAutomated safety check: PassMIT

Similar skills

  • Distributed Tracing

    wshobson/agents

    Implement distributed tracing with Jaeger and Tempo to track requests across microservices and identify performance bottlenecks.

    40k GitHub starsUsed in 12 repos~527 tokens
    DevOps & CloudAuto-check passed
  • Reviews and authors Cloudflare Workers code against production best practices.

    127 GitHub starsUsed in 6 repos~1.8k tokens
    DevOps & CloudAuto-check passed
  • Backend Design

    xenitV1/claude-code-maestro

    Elite Tier Backend standards, including Vertical Slice Architecture, Zero Trust Security, and High-Performance API protocols.

    229 GitHub stars~2.1k tokensUpdated 8 mo ago
    DevOps & CloudAuto-check: notes
  • Add Metric

    microbus-io/fabric

    TRIGGER when user asks to add or modify a metric, counter, gauge, or histogram, or to track/measure an operation.

    172 GitHub stars~1.5k tokensUpdated 12 days ago
    DevOps & CloudAuto-check passed
  • OmniRoute Health Monitoring

    diegosouzapw/OmniRoute

    Checks the health of an OmniRoute gateway: provider circuit breakers, latency percentiles, budget guard alerts, connection cooldowns and model lockouts.

    75k GitHub stars~1.2k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Telemetry Integration

    rapidaai/voice-ai

    Add or modify telemetry instrumentation across assistant-api and integration-api while preserving metric schema compatibility and audit behavior.

    745 GitHub stars~690 tokensUpdated 4 days ago
    DevOps & CloudAuto-check passed

More from growthxai/output

All 50 skills in this repo
  • Output Build Workflow

    growthxai/output

    Implement an Output SDK workflow from a plan document. An agent skill from growthxai/output.

    442 GitHub stars~2.2k tokensUpdated yesterday
    Auto-check passed
  • Output Credentials Edit

    growthxai/output

    View, edit, and set encrypted credentials in an Output.ai project.

    442 GitHub stars~1.1k tokensUpdated yesterday
    Auto-check: notes
  • Wire encrypted credentials to environment variables using the credential: convention.

    442 GitHub stars~930 tokensUpdated yesterday
    Auto-check: notes
  • Output Credentials Init

    growthxai/output

    Initialize encrypted credentials for an Output.ai project. An agent skill from growthxai/output.

    442 GitHub stars~803 tokensUpdated yesterday
    Auto-check: notes
  • Output Debug Workflow

    growthxai/output

    Debug Output SDK workflow issues. An agent skill from growthxai/output.

    442 GitHub stars~1.5k tokensUpdated yesterday
    Auto-check passed
  • Output Dev Agent Class

    growthxai/output

    Use the Agent class for multi-step tool loops, conversation history, streaming progress, and reusable LLM agents.

    442 GitHub stars~2.6k tokensUpdated yesterday
    Auto-check passed

Questions about Output Dev Cost Hooks

What does Output Dev Cost Hooks do?

Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system. Output Dev Cost Hooks is an agent skill from growthxai/output. Subscribe to cost events (cost:http:request, llm:generation:metering) to forward LLM and API spend to your own observability system.

When should I use Output Dev Cost Hooks?

Output Dev Cost Hooks fits situations like: adding cost/spend logging; building a cost observability integration; forwarding per-request cost data to an external system.

How do I install Output Dev Cost Hooks in Claude Code?

Run `npx skills add growthxai/output --skill output-dev-cost-hooks -a claude-code`. Or copy the skill folder (coding_assistants/claude/plugins/outputai/skills/output-dev-cost-hooks in growthxai/output) into .claude/skills/output-dev-cost-hooks in your project. Claude Code loads it when a task matches its description.

How do I install Output Dev Cost Hooks in Codex?

Run `npx skills add growthxai/output --skill output-dev-cost-hooks -a codex`. Or copy the skill folder (coding_assistants/claude/plugins/outputai/skills/output-dev-cost-hooks in growthxai/output) into .agents/skills/output-dev-cost-hooks in your project. Codex loads it when a task matches its description.

Can I use Output Dev Cost Hooks in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add growthxai/output --skill output-dev-cost-hooks -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/output-dev-cost-hooks, .gemini/skills/output-dev-cost-hooks, .github/skills/output-dev-cost-hooks and .opencode/skills/output-dev-cost-hooks in your project.

What does Output Dev Cost Hooks need to run?

Going by SKILL.md and its folder, Output Dev Cost Hooks needs the command-line tools its instructions call (npm). Its frontmatter pre-approves these tools: Read, Write, Edit, Glob.

Does Output Dev Cost Hooks access the network?

SKILL.md names 1 domain. In commands or code: docs.output.ai; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is Output Dev Cost Hooks safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Output Dev Cost Hooks use?

Output Dev Cost Hooks is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Output Dev Cost Hooks use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Output Dev Cost Hooks?

Skills that share tags, products or a category with Output Dev Cost Hooks: Distributed Tracing (wshobson/agents, 40k stars), Workers Best Practices (hodgef/apiker, 127 stars), Backend Design (xenitV1/claude-code-maestro, 229 stars) and Add Metric (microbus-io/fabric, 172 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Output Dev Cost Hooks?

growthxai (a GitHub organization) maintains it in growthxai/output, which has 442 GitHub stars. The repository holds 50 skills in this directory. The repository was last updated on October 9, 2026.

Source: growthxai/output on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.