Skip to content

Cost & Token Usage Tracking

Navigation: README | Diagram Architecture | How It Works | Database Schema | Challenge Requirements | Cost Tracking


Overview

KidStory includes a built-in cost tracking system that logs every AI API call with token counts, duration, and calculated cost. All 9 agents are built with Google ADK v1.0 and run Gemini 2.5 Pro on Vertex AI — each agent call is captured with full token and cost breakdown. This runs only in development mode (npm run dev) — it is automatically disabled in production to avoid file I/O overhead.


How to Test Locally

bash
# 1. Clone and install
git clone https://github.com/ajitonelsonn/Storybook-for-Kids.git
cd Storybook-for-Kids/storybook-for-kids-app
npm install

# 2. Set up environment variables
cp .env.example .env.local
# Fill in your Google Cloud credentials

# 3. Run in development mode
npm run dev

# 4. Generate a story in the app (http://localhost:3000)
#    - Go to /create
#    - Type or speak a story idea
#    - Wait for generation to complete

# 5. View the cost logs
cat log/token-usage.jsonl

# 6. Run the cost report script for a formatted summary
npx tsx scripts/cost-report.ts

Log Files (development only)

All logs are saved to the log/ directory (gitignored):

FileFormatContent
log/token-usage.jsonlJSON LinesOne entry per agent call with tokens, cost, duration
log/session-summaries.jsonlJSON (pretty)Aggregated summary per story/quiz session

What Gets Logged

ActionAgents Logged
Story generationSafetyGuardian, StoryWriter
Image generationIllustrator[page-1] through Illustrator[page-6]
Audio narrationNarrator[page-1] through Narrator[page-6]
Quiz generationQuizMaster[0] through QuizMaster[4]
Learning recommendationLearningAdvisor (skipped if cached)
Parent insightsParentInsights (skipped if cached)
Story adaptationStoryAdaptationAgent (skipped if cached)

Log Entry Format

Each line in token-usage.jsonl:

json
{
  "timestamp": "2026-04-28T08:40:32.920Z",
  "sessionType": "story_generation",
  "agent": "StoryWriter",
  "model": "gemini-2.5-pro",
  "inputTokens": 522,
  "outputTokens": 983,
  "thinkingTokens": 0,
  "imageCount": 0,
  "ttsCharacters": 0,
  "durationMs": 16460,
  "language": "en",
  "cost": {
    "input": 0.000653,
    "output": 0.00983,
    "thinking": 0,
    "image": 0,
    "tts": 0,
    "total": 0.010482
  },
  "metadata": {
    "pagesGenerated": 6,
    "title": "Leo and the Sealyon's Singapore Adventure"
  }
}

Real Cost Example: One Full Story (6 pages, English)

Generated on 2026-04-28. Story: "Leo and the Sealyon's Singapore Adventure"

ComponentTokens/UnitsCost
SafetyGuardian222 in + 30 out$0.000578
StoryWriter522 in + 983 out$0.010482
Narrator × 6 pages1,406 characters$0.022496
Illustrator × 6 pages6 images generated$0.120000
TOTAL$0.153556

Cost Breakdown by Category

CategoryCost% of Total
Text generation (LLM)$0.0110607.2%
Image generation$0.12000078.1%
Audio narration (TTS)$0.02249614.7%

Key insight: Image generation still dominates cost at ~78%. With Gemini 2.5 Pro, text generation now accounts for ~7% of total cost (up from <1% with Flash).


Quiz Cost Example (5 questions)

ComponentTokens/UnitsCost
QuizMaster × 5~4,600 in + ~150 out + ~1,500 thinking~$0.002
TTS for questions × 5~750 characters~$0.012
TOTAL per quiz~$0.014

Pricing Reference (Gemini 2.5 Pro on Vertex AI)

ResourcePrice
Input tokens$1.25 per 1M tokens
Output tokens$10.00 per 1M tokens
Thinking tokens$3.50 per 1M tokens
Image generation~$0.02 per image (gemini-2.5-flash-image)
TTS (gemini-2.5-flash-preview-tts)$0.000016 per character (estimate used in cost logger)

Cost Report Script

Run anytime to see a formatted breakdown of all logged sessions:

bash
npx tsx scripts/cost-report.ts

Output example:

╔══════════════════════════════════════════════════════════════╗
║              KIDSTORY COST REPORT                           ║
╚══════════════════════════════════════════════════════════════╝

┌─── STORY_GENERATION ───────────────────────────────────
│ Story: "Leo and the Sealyon's Singapore Adventure"
│ Language: en

│ ┌── Breakdown ──────────────────────────────────
│ │ SafetyGuardian         in:222 out:30              $0.000051
│ │ StoryWriter            in:522 out:983             $0.000668
│ │ Narrator[page-1]       tts:244ch                  $0.003904
│ │ Narrator[page-2]       tts:240ch                  $0.003840
│ │ ...
│ │ Illustrator[page-1]    in:129 img:1               $0.020019
│ │ Illustrator[page-2]    in:128 img:1               $0.020019
│ │ ...
│ └─────────────────────────────────────────────

│ TOTALS:
│   Input tokens:    1,595
│   Images:          6
│   TTS characters:  1,406
│   TOTAL COST:      $0.143343
└──────────────────────────────────────────────────

═══════════════════════════════════════════════════
  GRAND TOTAL (all sessions): $0.143343
═══════════════════════════════════════════════════

Verification via Google Cloud Console

To cross-reference these local logs with actual billing:

  1. Cloud Trace — GCP Console → Trace → filter by agent/StoryWriter

    • Each span shows gen_ai.usage.input_tokens and gen_ai.usage.output_tokens
    • These match the values in token-usage.jsonl
  2. Vertex AI Metrics — GCP Console → Vertex AI → Model Monitoring

    • Shows prediction count and token usage per model
  3. Billing Reports — GCP Console → Billing → Reports

    • Filter by Vertex AI API for overall cost validation

Production vs Development

Development (npm run dev)Production (Cloud Run)
Cost logging to file✅ Enabled❌ Disabled
Console output✅ Enabled❌ Disabled
OpenTelemetry spans✅ Enabled✅ Enabled
Cloud Trace export✅ (if configured)✅ Enabled

The logTokenUsage() and logSessionSummary() functions check process.env.NODE_ENV === "production" and return immediately without any file I/O or console output.


Files

FilePurpose
lib/observability/costLogger.tsCore logging functions
scripts/cost-report.tsCLI script to print formatted cost report
log/token-usage.jsonlRaw per-call log (dev only, gitignored)
log/session-summaries.jsonlSession aggregates (dev only, gitignored)

Released under the MIT License.