Back to skills
SKILL.md
Ai Skel Ts Usage
ASecurityScaffold 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.
- 3 stars
- 0 votes
- 0 copies
- 0 views
- Added September 2, 2026
Works with
Security analysis
100/100Pro scans all 5 files and shows the line behind each finding
npx -y skills add korchasa/flowai --skill ai-skel-ts-usage --agent claude-codeAre you the author of Ai Skel Ts Usage?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/korchasa-ai-skel-ts-usage)---
name: ai-skel-ts-usage
description: >
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.
license: MIT
compatibility: Requires Deno 2.x or Node.js 18+
metadata:
author: korchasa
version: "0.8.8"
---
# AI Agent Scaffold
Generates a production-grade AI agent skeleton directly in the target project. The scaffold follows battle-tested patterns from the [ai-skel-ts](https://github.com/korchasa/ai-skel-ts) reference implementation.
## When to Use
- User asks to create a new AI agent or AI-powered application
- User asks to add LLM integration to an existing project
- User mentions "scaffold", "skeleton", "ai-skel", or "agent framework"
## Architecture Overview
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 |
+---------------------------------------------------+
```
## Scaffold Workflow
When generating the scaffold, follow these steps:
### Step 1: Detect Project Context
1. Identify the target programming language and runtime
2. Identify the package manager and dependency management approach
3. Identify existing project structure conventions (src/, lib/, internal/, etc.)
4. Determine which LLM SDK is appropriate for the language:
- **TypeScript/JavaScript**: Vercel AI SDK (`ai` package)
- **Python**: `openai`, `anthropic`, `google-generativeai`, or `litellm`
- **Go**: `github.com/sashabaranov/go-openai` or provider SDKs
- **Rust**: `async-openai` or provider SDKs
- **Other**: use the provider's HTTP API directly
### Step 2: Generate Modules Bottom-Up
Generate modules in this order (each depends only on previously generated ones):
1. **Logger** — zero dependencies
2. **Cost Tracker** — depends on Logger
3. **Run Context** — depends on Logger
4. **LLM Requester** — depends on Logger, Cost Tracker, Run Context
5. **Session Compactor** — depends on Logger
6. **MCP Client** — depends on Logger (optional, skip if not needed)
7. **Agent** — depends on LLM Requester, Session Compactor, MCP Client, Run Context
8. **Fetchers** — depends on Run Context (optional, add as needed)
### Step 3: Add Tests
For each module, generate at minimum:
- Unit tests with mocked dependencies
- One integration-style test with real interfaces (but mocked HTTP/LLM)
### Step 4: Wire Entry Point
Create a main entry point (mod.ts / main.py / main.go / etc.) that re-exports public API.
## Module Specifications
Each module below includes: purpose, key interfaces, algorithm, and critical implementation details. For full reference implementations in TypeScript, see the reference files.
---
### 1. Logger
**Purpose**: Structured logging with levels, context, and timestamps.
**Interface**:
- Constructor: `(context: string, logLevel: "debug"|"info"|"warn"|"error")`
- Methods: `debug(msg, meta?)`, `info(msg, meta?)`, `warn(msg, meta?)`, `error(msg, error?)`
- Factory: `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](references/reference-observability.md)
---
### 2. Cost Tracker
**Purpose**: Accumulate LLM token usage and costs across requests.
**Interface**:
- `addCost(cost: number)` — adds USD cost, increments request counter
- `addTokens(inputTokens, outputTokens)` — accumulates token counts
- `getReport()` → `{totalCost, totalInputTokens, totalOutputTokens, totalTokens, requestCount}`
- `getFormattedReport()` → human-readable string
- `reset()` — zeroes all counters
**Pattern**: Singleton (for global tracking) OR instance (for per-run tracking). Provide both options.
Reference: [reference-observability.md](references/reference-observability.md)
---
### 3. Run Context
**Purpose**: Immutable execution context with unique run ID and debug artifact management.
**Interface**:
- `RunContext { runId, debugDir, logger, startTime, saveDebugFile() }`
- Factory: `createRunContext(logger, debugDir, runId?)` — auto-generates reverse-sortable ID if not provided
- `getSubDebugDir(ctx, stageDir)` — returns subdirectory path for a stage
- `safeSanitize(obj)` — recursively handles Error, Buffer, circular refs for serialization
**Critical 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](references/reference-core.md)
---
### 4. LLM Requester
**Purpose**: Provider-agnostic LLM interface with retry, validation, self-correction, and observability.
**This is the most complex module.** Read [reference-core.md](references/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
- Requester function: `(messages, identifier, schema?, tools?, maxSteps?, stageName, settings?) → GenerateResult`
- `GenerateResult { 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**:
- API key resolution: URI param > environment variable (`{PROVIDER}_API_KEY`)
- AbortController.abort() must be wrapped in try-catch (listeners can throw)
- Mask apiKey in URI toString() for logging
- Settings from URI are defaults; per-request settings override them
Reference: [reference-core.md](references/reference-core.md)
---
### 5. Session Compactor
**Purpose**: Manage conversation context window by trimming or summarizing history.
**Interface**:
- `HistoryCompactor { compact(messages) → messages, estimateSymbols(message) → number }`
- `SimpleHistoryCompactor(maxSymbols)` — trims oldest messages
- `SummarizingHistoryCompactor(maxSymbols, summaryTokenThreshold, summaryGenerator)` — LLM-powered
**Algorithm** (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](references/reference-session.md)
---
### 6. MCP Client (optional)
**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 management
- `getTools()` → `Record<string, Tool>` — discovers and converts tools
**Key details**:
- Tool namespacing: prefix tool names with server name (`serverName__toolName`) to prevent collisions
- Tool conversion: MCP JSON Schema → LLM SDK Tool format (use `jsonSchema()` helper if available)
- Execute: call MCP `tools/call`, extract text content from response parts
Reference: [reference-session.md](references/reference-session.md)
---
### 7. Agent
**Purpose**: Stateful conversation runner with tool integration and history management.
**Interface**:
- `Agent(llm, mcpClients?, ctx, systemPrompt?, compactor?, tools?)`
- `init()` — connects MCP clients, aggregates all tools
- `run(input)` → `GenerateResult` — full access to results
- `chat(input)` → `string` — convenience wrapper
- `getHistory()` → messages array
**Algorithm**:
```
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](references/reference-core.md)
---
### 8-10. Fetchers (optional)
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](references/reference-fetchers.md)
---
## Language Adaptation Guidelines
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 |
## File Organization
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
```
## Critical Rules
1. **No stubs**: Every function must have a real implementation
2. **Observability first**: Every LLM call writes a YAML debug artifact to debugDir
3. **Self-correction**: On schema validation failure, feed the error back to the LLM
4. **Tool-pair consistency**: Never leave orphaned tool-calls or tool-results in history
5. **Reverse-sortable IDs**: Run IDs sort newest-first in file listings
6. **Mask secrets**: API keys must never appear in logs or debug files
7. **Exponential backoff**: `delay = baseDelay * 2^(attempt-1) + jitter`
8. **Safe serialization**: Handle Error objects, Buffers, circular references before serializing
9. **URI-based config**: Model configuration via `protocol://provider/model?params`
10. **Graceful degradation**: Summarization fails → fall back to trimming; MCP fails → continue without tools
## Checklist
After generating the scaffold, verify:
- [ ] All modules compile/lint without errors
- [ ] Tests pass
- [ ] LLM Requester has retry loop with self-correction
- [ ] Agent preserves all intermediate tool-call messages in history
- [ ] Session Compactor maintains tool-call/tool-result pair consistency
- [ ] Run Context generates reverse-sortable IDs
- [ ] Logger handles Error serialization
- [ ] Cost Tracker accumulates across requests
- [ ] Debug artifacts written as YAML to structured directories
- [ ] API keys masked in all log output
Files in this skill
- SKILL.md
- references/reference-core.md
- references/reference-fetchers.md
- references/reference-observability.md
- references/reference-session.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.