.claude/skills/flow-skill-ai-skel-ts/SKILL.md
Scaffold a complete AI agent application skeleton with LLM integration, tool calling, observability, cost tracking, session management, and content fetching. Use when the user asks to create an AI agent, add LLM integration, scaffold an AI application, or mentions "ai-skel", "agent skeleton", or "AI scaffold". Works with any programming language.
npx skillsauth add korchasa/ai-skel-ts flow-skill-ai-skel-tsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generates a production-grade AI agent skeleton directly in the target project. The scaffold follows battle-tested patterns from the ai-skel-ts reference implementation.
The skeleton consists of 10 modules organized into 4 layers:
┌─────────────────────────────────────────────────┐
│ Agent Layer │
│ Agent (stateful conversation + tool dispatch) │
├──────────────┬──────────────┬───────────────────┤
│ LLM Layer │ Tools Layer │ Session Layer │
│ LLM Request │ MCP Client │ History Compact │
│ (retry, │ (protocol │ (trim or │
│ validate, │ bridge, │ summarize, │
│ observe) │ namespace) │ tool-pair │
│ │ │ consistency) │
├──────────────┴──────────────┴───────────────────┤
│ Observability Layer │
│ Logger │ Cost Tracker │ Run Context │ Debug I/O │
├─────────────────────────────────────────────────┤
│ Content Layer │
│ Local Fetcher │ Brave Search │ Jina Scraper │
└─────────────────────────────────────────────────┘
When generating the scaffold, follow these steps:
ai package)openai, anthropic, google-generativeai, or litellmgithub.com/sashabaranov/go-openai or provider SDKsasync-openai or provider SDKsGenerate modules in this order (each depends only on previously generated ones):
For each module, generate at minimum:
Create a main entry point (mod.ts / main.py / main.go / etc.) that re-exports public API.
Each module below includes: purpose, key interfaces, algorithm, and critical implementation details. For full reference implementations in TypeScript, see the reference files.
Purpose: Structured logging with levels, context, and timestamps.
Interface:
(context: string, logLevel: "debug"|"info"|"warn"|"error")debug(msg, meta?), info(msg, meta?), warn(msg, meta?), error(msg, error?)createFromLevelString(context, levelString) — validates level, warns and falls back to "debug"Algorithm: Compare numeric level values (debug=0, info=1, warn=2, error=3). Log only if message level >= configured level.
Key detail: Error objects need special serialization (JSON.stringify(Error) returns "{}"). Extract name, message, stack explicitly.
Reference: reference-observability.md
Purpose: Accumulate LLM token usage and costs across requests.
Interface:
addCost(cost: number) — adds USD cost, increments request counteraddTokens(inputTokens, outputTokens) — accumulates token countsgetReport() → {totalCost, totalInputTokens, totalOutputTokens, totalTokens, requestCount}getFormattedReport() → human-readable stringreset() — zeroes all countersPattern: Singleton (for global tracking) OR instance (for per-run tracking). Provide both options.
Reference: reference-observability.md
Purpose: Immutable execution context with unique run ID and debug artifact management.
Interface:
RunContext { runId, debugDir, logger, startTime, saveDebugFile() }createRunContext(logger, debugDir, runId?) — auto-generates reverse-sortable ID if not providedgetSubDebugDir(ctx, stageDir) — returns subdirectory path for a stagesafeSanitize(obj) — recursively handles Error, Buffer, circular refs for serializationCritical algorithm — Reverse-sortable Run ID:
maxMs = Date.UTC(9999, 11, 31, 23, 59, 59, 999)
reversedMs = maxMs - Date.now()
runId = toISO(reversedMs) + microSequence
This makes newest runs sort first in file listings.
Reference: reference-core.md
Purpose: Provider-agnostic LLM interface with retry, validation, self-correction, and observability.
This is the most complex module. Read reference-core.md carefully.
Interface:
ModelURI — parses protocol://provider/model?params (e.g., chat://openai/gpt-4o?timeout=60000)createLlmRequester(modelUri, logger, costTracker, ctx) → requester function(messages, identifier, schema?, tools?, maxSteps?, stageName, settings?) → GenerateResultGenerateResult { result, text, toolCalls, toolResults, newMessages, steps, estimatedCost, inputTokens, outputTokens, validationError?, rawResponse? }Core algorithm (retry loop with self-correction):
parse URI → create provider instance → return requester function
requester(messages, schema, tools, ...):
write initial YAML log file
for attempt = 1..MAX_RETRIES(3):
set timeout via AbortController
call LLM SDK (generateText / chat completion)
on success:
track cost/tokens
aggregate newMessages from steps
update YAML log
return result
on validation error (schema mismatch):
append assistant message (raw response)
append user message (error description) ← SELF-CORRECTION
update YAML log
retry
on fatal API error (401/403/400):
return error immediately (no retry)
on transient error:
exponential backoff: delay = 1000ms * 2^(attempt-1) + jitter(20%)
retry
Key details:
{PROVIDER}_API_KEY)Reference: reference-core.md
Purpose: Manage conversation context window by trimming or summarizing history.
Interface:
HistoryCompactor { compact(messages) → messages, estimateSymbols(message) → number }SimpleHistoryCompactor(maxSymbols) — trims oldest messagesSummarizingHistoryCompactor(maxSymbols, summaryTokenThreshold, summaryGenerator) — LLM-poweredAlgorithm (SimpleHistoryCompactor):
trimBySymbolLimit:
iterate messages from newest to oldest
accumulate symbol weight (JSON.stringify length)
stop when budget exceeded
ensureToolConsistency:
collect all tool-call IDs and tool-result IDs
remove messages with orphaned tool-calls (no matching result)
remove messages with orphaned tool-results (no matching call)
Algorithm (SummarizingHistoryCompactor):
estimate token count (symbols / 4)
if under threshold → delegate to SimpleHistoryCompactor
if over threshold:
split: messages[0..splitPoint] → summarize, messages[splitPoint..] → keep
splitPoint = index before last assistant message
call SummaryGenerator.generateSummary(toSummarize) → summary message
ensure proper message alternation (add dummy user message if needed)
apply tool consistency check
on error → fallback to SimpleHistoryCompactor
Reference: reference-session.md
Purpose: Bridge between Model Context Protocol servers and the LLM tool interface.
Interface:
McpClientWrapper(config, logger, name) — config is either {type:"stdio", command, args} or {type:"sse", url}connect() / disconnect() — lifecycle managementgetTools() → Record<string, Tool> — discovers and converts toolsKey details:
serverName__toolName) to prevent collisionsjsonSchema() helper if available)tools/call, extract text content from response partsReference: reference-session.md
Purpose: Stateful conversation runner with tool integration and history management.
Interface:
Agent(llm, mcpClients?, ctx, systemPrompt?, compactor?, tools?)init() — connects MCP clients, aggregates all toolsrun(input) → GenerateResult — full access to resultschat(input) → string — convenience wrappergetHistory() → messages arrayAlgorithm:
constructor:
store params
if systemPrompt: push system message to history
init:
for each mcpClient:
connect()
getTools() → merge into this.tools
run(input):
push user message to history
if compactor: compact history
call llm(messages, tools, maxSteps=10, ...)
if error: throw
append all newMessages to history
return result
chat(input):
return run(input).text
Reference: reference-core.md
Three content acquisition strategies. Add only what the project needs.
Local Fetcher: HTML → clean text + metadata via Readability algorithm Brave Search: REST API client with 429 retry and rate-limited batch search Jina Scraper: Dual-endpoint (search + reader) API client with rich options
Reference: reference-fetchers.md
When adapting patterns to a target language:
| Concept | TypeScript | Python | Go | Rust |
|---------|-----------|--------|-----|------|
| Interfaces | interface / type | Protocol / ABC | interface | trait |
| Generics | <T> | Generic[T] | [T any] | <T> |
| Async | async/await | async/await | goroutines/channels | async/await |
| Error handling | try/catch + types | try/except + types | error return | Result<T, E> |
| Dependency injection | constructor params | constructor / __init__ | struct fields | struct fields |
| Singleton | static instance | module-level / __new__ | sync.Once | once_cell::Lazy |
| Schema validation | Zod | Pydantic | struct tags + validator | serde + validator |
| URI parsing | URL class | urllib.parse | net/url | url crate |
Adapt to the project's conventions. Suggested structure:
{src_dir}/
├── agent/
│ ├── agent.{ext}
│ └── agent_test.{ext}
├── llm/
│ ├── requester.{ext}
│ ├── model_uri.{ext}
│ └── requester_test.{ext}
├── run_context/
│ ├── context.{ext}
│ └── context_test.{ext}
├── cost_tracker/
│ ├── tracker.{ext}
│ └── tracker_test.{ext}
├── logger/
│ ├── logger.{ext}
│ └── logger_test.{ext}
├── session/
│ ├── compactor.{ext}
│ ├── summary_generator.{ext}
│ └── compactor_test.{ext}
├── mcp/ # optional
│ └── client.{ext}
├── fetchers/ # optional
│ ├── local/
│ ├── brave/
│ └── jina/
└── mod.{ext} # public API entry point
delay = baseDelay * 2^(attempt-1) + jitterprotocol://provider/model?paramsAfter generating the scaffold, verify:
tools
Scaffold a complete AI agent application skeleton with LLM integration, tool calling, observability, cost tracking, session management, and content fetching using @korchasa/ai-skel-ts. Use when the user asks to create an AI agent, add LLM integration, scaffold an AI application, or mentions "ai-skel", "agent skeleton", or "AI scaffold". Works with any programming language.
testing
Create structured specification for large features using phased decomposition. Produces documents/spec-{name}.md with dependency-ordered phases, atomic tasks, explicit boundaries, and per-phase status tracking.
documentation
Guidelines for writing comprehensive Product Requirements Documents (PRD)
development
How to write in informational style