Ai Core/Debug Logging logo

Ai Core/Debug Logging

OrganizationPopular
TanStack
ai-core/debug-logging

Pluggable, category-toggleable debug logging for TanStack AI activities. Toggle with `debug: true | false | DebugConfig` on chat(), summarize(), generateImage(), generateSpeech(), generateTranscription(), generateVideo(). Categories: request, provider, output, middleware, tools, agentLoop, config, errors. Pipe into pino/winston/etc via `debug: { logger }`. Errors log by default even when `debug` is omitted; silence with `debug: false`.

Overview

PublisherTanStack
Repositoryai
Skill nameai-core/debug-logging
Stars
3.1K
Forks
330
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by TanStack on GitHub. Read the source before you install it.

Installation

Install the Ai Core/Debug Logging AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/TanStack/ai.git /tmp/ai
mkdir -p .claude/skills
cp -r /tmp/ai/packages/ai/skills/ai-core/debug-logging .claude/skills/tanstack-ai-core-debug-logging
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Ai Core/Debug Logging in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Ai Core/Debug Logging on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Ai Core/Debug Logging is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Debug Logging

Dependency note: This skill builds on ai-core. Read it first for critical rules.

Use this skill when you need to turn debug logging on or off, narrow what's printed, or pipe logs into a custom logger (pino, winston, etc.). The same debug option works on every activity — chat(), summarize(), generateImage(), generateSpeech(), generateTranscription(), generateVideo().

Turn it on

typescript
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const messages = [{ role: 'user' as const, content: 'Hello' }]

const stream = chat({
  adapter: openaiText('gpt-5.5'),
  messages,
  debug: true, // all categories on, prints to console
})

Each log line is prefixed with an emoji and [tanstack-ai:<category>]:

📤 [tanstack-ai:request] 📤 activity=chat provider=openai model=gpt-5.2 messages=1 tools=0 stream=true
🔁 [tanstack-ai:agentLoop] 🔁 run started
📥 [tanstack-ai:provider] 📥 provider=openai type=response.output_text.delta
📨 [tanstack-ai:output] 📨 type=TEXT_MESSAGE_CONTENT

Turn it off

typescript
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const messages = [{ role: 'user' as const, content: 'Hello' }]

chat({
  adapter: openaiText('gpt-5.5'),
  messages,
  debug: false, // silence everything, including errors
})

Omitting debug is not the same as debug: false. When omitted, the errors category is still on (errors are cheap and important). Use debug: false or debug: { errors: false } for true silence.

DebugOption — the accepted shapes

typescript
import type { Logger } from '@tanstack/ai'

// As exported by '@tanstack/ai'
type DebugOption = boolean | DebugConfig

interface DebugConfig {
  // Per-category flags. Any flag omitted from a DebugConfig defaults to true.
  request?: boolean
  provider?: boolean
  output?: boolean
  middleware?: boolean
  tools?: boolean
  agentLoop?: boolean
  config?: boolean
  errors?: boolean
  // Optional custom logger. Defaults to ConsoleLogger.
  logger?: Logger
}

Resolution rules for the debug?: DebugOption field on every activity:

debug valueEffect
omitted (undefined)Only errors is active; default ConsoleLogger.
trueAll categories on; default ConsoleLogger.
falseAll categories off (including errors); default ConsoleLogger.
DebugConfig objectEach unspecified flag defaults to true; logger replaces ConsoleLogger.

Narrow what's printed

Pass a DebugConfig object. Unspecified categories default to true, so it's easiest to toggle by setting specific flags to false:

typescript
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const messages = [{ role: 'user' as const, content: 'Hello' }]

chat({
  adapter: openaiText('gpt-5.5'),
  messages,
  debug: { middleware: false }, // everything except middleware
})

To print only a specific set, set the rest to false explicitly:

typescript
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const messages = [{ role: 'user' as const, content: 'Hello' }]

chat({
  adapter: openaiText('gpt-5.5'),
  messages,
  debug: {
    provider: true,
    output: true,
    middleware: false,
    tools: false,
    agentLoop: false,
    config: false,
    errors: true, // keep errors on — they're cheap and important
    request: false,
  },
})

Pipe into your own logger

typescript
import { chat, type Logger } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import pino from 'pino'

const pinoLogger = pino()
const logger: Logger = {
  debug: (msg, meta) => pinoLogger.debug(meta, msg),
  info: (msg, meta) => pinoLogger.info(meta, msg),
  warn: (msg, meta) => pinoLogger.warn(meta, msg),
  error: (msg, meta) => pinoLogger.error(meta, msg),
}

const messages = [{ role: 'user' as const, content: 'Hello' }]

chat({
  adapter: openaiText('gpt-5.5'),
  messages,
  debug: { logger }, // all categories on, piped to pino
})

The default console logger is exported as ConsoleLogger if you want to wrap it:

typescript
import { ConsoleLogger } from '@tanstack/ai'

Categories

CategoryLogsApplies to
requestOutgoing call to a provider (model, message count, tool count)All activities
providerEvery raw chunk/frame received from a provider SDKStreaming activities (chat, realtime)
outputEvery chunk or result yielded to the callerAll activities
middlewareInputs and outputs around every middleware hookchat() only
toolsBefore/after tool call executionchat() only
agentLoopAgent-loop iterations and phase transitionschat() only
configConfig transforms returned by middleware onConfig hookschat() only
errorsEvery caught error anywhere in the pipelineAll activities

Chat-only categories simply never fire for non-chat activities — those concepts don't exist in their pipelines.

Non-chat activities

Same debug option everywhere:

typescript
import {
  summarize,
  generateImage,
  generateSpeech,
  generateTranscription,
  generateVideo,
} from '@tanstack/ai'
import {
  openaiSummarize,
  openaiImage,
  openaiSpeech,
  openaiTranscription,
  openaiVideo,
} from '@tanstack/ai-openai'
import { logger } from './logger'
import { audio } from './recording'

summarize({
  adapter: openaiSummarize('gpt-5.5'),
  text: 'Long article…',
  debug: true,
})
generateImage({
  adapter: openaiImage('gpt-image-2'),
  prompt: 'a cat',
  debug: { logger },
})
generateSpeech({
  adapter: openaiSpeech('tts-1-hd'),
  text: 'Hello',
  debug: { request: true },
})
generateTranscription({
  adapter: openaiTranscription('gpt-4o-transcribe'),
  audio,
  debug: false,
})
generateVideo({
  adapter: openaiVideo('sora-2'),
  prompt: 'a wave',
  debug: { output: true },
})

Realtime session adapters in provider packages (e.g. openaiRealtime, elevenlabsRealtime) accept the same debug?: DebugOption on their session options. They emit request, provider, and errors lines; the chat-only categories don't apply.

Common Mistakes

a. HIGH: Treating omitted debug as silent

typescript
import { chat } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const adapter = openaiText('gpt-5.5')
const messages = [{ role: 'user' as const, content: 'Hello' }]

// WRONG — expecting this to be completely silent
chat({ adapter, messages })
// Errors still print via [tanstack-ai:errors] ... on failure.

// CORRECT — explicit silence
chat({ adapter, messages, debug: false })
chat({ adapter, messages, debug: { errors: false } })

debug undefined means "only errors"; debug: false means "nothing at all".

Source: docs/advanced/debug-logging.md

b. MEDIUM: Reaching for middleware when debug would do

typescript
import { chat, type ChatMiddleware } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

const adapter = openaiText('gpt-5.5')
const messages = [{ role: 'user' as const, content: 'Hello' }]

// WRONG — writing logging middleware to see chunks flow
const chunkLogger: ChatMiddleware = {
  name: 'chunk-logger',
  onChunk: (ctx, chunk) => {
    console.log(chunk.type, chunk)
  },
}
chat({ adapter, messages, middleware: [chunkLogger] })

// CORRECT — just turn on the relevant categories
chat({
  adapter,
  messages,
  debug: { provider: true, output: true },
})

For observing the built-in pipeline, the debug option is strictly faster than writing logging middleware. Reach for middleware when you need to transform chunks, not just see them.

Source: docs/advanced/debug-logging.md

c. LOW: Logger implementation that can throw

A user-supplied Logger that throws will have its exception swallowed by the SDK so it never masks the real error that triggered the log call. Still, prefer implementations that don't throw — silenced exceptions are harder to debug than loud ones.

typescript
import type { Logger } from '@tanstack/ai'

// WRONG — a logger that can throw on serialization
const fragile: Logger = {
  debug: (msg, meta) => console.debug(msg, JSON.stringify(meta)), // cyclic meta → throws
  info: (msg, meta) => console.info(msg, JSON.stringify(meta)),
  warn: (msg, meta) => console.warn(msg, JSON.stringify(meta)),
  error: (msg, meta) => console.error(msg, JSON.stringify(meta)),
}

// CORRECT — guard serialization in the logger itself
const guarded =
  (log: (...args: Array<unknown>) => void): Logger['debug'] =>
  (msg, meta) => {
    try {
      log(msg, JSON.stringify(meta))
    } catch {
      log(msg) // fall back to the bare message rather than throw
    }
  }

const safe: Logger = {
  debug: guarded(console.debug),
  info: guarded(console.info),
  warn: guarded(console.warn),
  error: guarded(console.error),
}

Source: packages/ai/src/logger/internal-logger.ts

Cross-References

  • See also: ai-core/middleware/SKILL.md — if you need to transform chunks/config, not just observe them.
  • See also: Observability (docs/advanced/observability.md) — the programmatic event client for a richer, structured feed beyond log lines.

Frequently asked questions

What does the Ai Core/Debug Logging AI skill do?

Pluggable, category-toggleable debug logging for TanStack AI activities. Toggle with `debug: true | false | DebugConfig` on chat(), summarize(), generateImage(), generateSpeech(), generateTranscription(), generateVideo(). Categories: request, provider, output, middleware, tools, agentLoop, config, errors. Pipe into pino/winston/etc via `debug: { logger }`. Errors log by default even when `debug` is omitted; silence with `debug: false`.

Why use Ai Core/Debug Logging on TypingMind?

Because you install it once and use it with any model. Ai Core/Debug Logging is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Ai Core/Debug Logging in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/TanStack/ai/tree/main/packages/ai/skills/ai-core/debug-logging. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Ai Core/Debug Logging?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Ai Core/Debug Logging?

As many as you like. As long as a model supports skills, you can use Ai Core/Debug Logging with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Ai Core/Debug Logging AI skill free?

Yes. It is published on GitHub by TanStack under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇