Reasoning Serialization Tests
tailcallhq/forgecode
Checks that ReasoningConfig fields are serialized into the right provider-specific JSON for OpenRouter, Anthropic, GitHub Copilot and Codex requests.
Adds a new LLM provider implementing LLMProvider interface with call() and stream() methods.
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install caliber-ai-org/ai-setup llm-provider --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/llm-provider .claude/skills/llm-provider && rm -rf skills-srcUse ~/.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/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .claude/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-providerType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install caliber-ai-org/ai-setup llm-provider --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/llm-provider .agents/skills/llm-provider && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .agents/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install caliber-ai-org/ai-setup llm-provider --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/llm-provider .cursor/skills/llm-provider && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .cursor/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/caliber-ai-org/ai-setup.git --path skills/llm-provider--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install caliber-ai-org/ai-setup llm-provider --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/llm-provider .gemini/skills/llm-provider && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .gemini/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install caliber-ai-org/ai-setup llm-providerInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/llm-provider .github/skills/llm-provider && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .github/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add caliber-ai-org/ai-setup --skill llm-provider -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install caliber-ai-org/ai-setup llm-provider --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/caliber-ai-org/ai-setup.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/llm-provider .opencode/skills/llm-provider && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "llm-provider" agent skill from https://github.com/caliber-ai-org/ai-setup/tree/master/skills/llm-provider into .opencode/skills/llm-provider/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "llm-provider", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
llm-providerAdds a new LLM provider implementing LLMProvider interface with call() and stream() methods.
LLM Provider is an agent skill from caliber-ai-org/ai-setup. Adds a new LLM provider implementing LLMProvider interface with call() and stream() methods. Integrates with provider factory in src/llm/index.ts, config detection in src/llm/config.ts, and error handling via tracking and recovery. Use when adding a new model backend, integrating a third-party LLM API, or extending LLM platform support. Do NOT use for fixing bugs in existing providers, modifying existing provider behavior, or changing the LLMProvider interface.
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 Testing & QA, covering LLM API integration and Error handling. It works with OpenAI. The repository describes itself as: Continuously sync your AI setups with one command. Codebase tailor suited agent skills, MCPs and config files for Claude Code, Cursor, and Codex. The licence is MIT.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f5dbc00. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npmnpxFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use npm and npx, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
LLM Provider loads about 2.7k tokens when it runs. Until then it costs about 120 tokens; SKILL.md has 670 words of instructions outside code blocks.
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.
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.
The full file from caliber-ai-org/ai-setup at commit f5dbc00, republished under its MIT licence (© caliber-ai-org). 670 words, ~2,711 tokens.
.claude/skills/llm-provider/SKILL.md (or your agent's skills folder).All providers MUST implement the LLMProvider interface from src/llm/types.ts with three methods:
<string> — single non-streaming call returning text<void> — streaming call invoking callbacksInitialize client in constructor and store defaultModel from config. Example: this.client = new YourSDK({ apiKey: config.apiKey }). Never lazy-initialize on first call — providers are instantiated once and cached in src/llm/index.ts.
For EVERY response in call() and stream(), invoke trackUsage(model, usage) from src/llm/usage.js before returning/ending. This is mandatory — it captures token metrics for CLI telemetry and cost analysis. If the API doesn't return usage data, estimate via estimateTokens(text), which assumes ~4 chars per token.
Both call() and stream() must respect the model parameter using pattern: options.model || this.defaultModel. Never hardcode model names. Callers supply model overrides via LLMCallOptions.model.
Error handling: catch all errors, preserve error messages unchanged. The retry logic in src/llm/index.ts handles transient errors (ECONNRESET, socket hang up, 529 overload). For seat-based providers (Cursor, Claude CLI), wrap stderr via parseSeatBasedError() for user-friendly messages.
Always update ProviderType union (Step 2), DEFAULT_MODELS (Step 4), and createProvider() switch case (Step 5) in lock-step. Missing any one breaks the build or causes runtime Unknown provider error.
Verify directory exists: ls -la src/llm/. Create src/llm/your-provider.ts. Match existing provider patterns (src/llm/anthropic.ts, src/llm/openai-compat.ts).
Minimal structure:
import type { LLMProvider, LLMCallOptions, LLMStreamOptions, LLMStreamCallbacks, LLMConfig, TokenUsage } from './types.js';
import { trackUsage } from './usage.js';
import { estimateTokens } from './utils.js';
export class YourProviderProvider implements LLMProvider {
private client: YourSDKType;
private defaultModel: string;
constructor(config: LLMConfig) {
if (!config.apiKey) throw new Error('API key required');
this.client = new YourSDK({ apiKey: config.apiKey, ...(config.baseUrl && { baseURL: config.baseUrl }) });
this.defaultModel = config.model;
}
async call(options: LLMCallOptions): Promise<string> {
const model = options.model || this.defaultModel;
const response = await this.client.messages.create({ model, max_tokens: options.maxTokens || 4096, system: options.system, messages: [{ role: 'user', content: options.prompt }] });
trackUsage(model, { inputTokens: response.usage?.input_tokens || 0, outputTokens: response.usage?.output_tokens || 0 });
return response.content?.[0]?.text || '';
}
async stream(options: LLMStreamOptions, callbacks: LLMStreamCallbacks): Promise<void> {
const model = options.model || this.defaultModel;
const messages = [...(options.messages || []), { role: 'user' as const, content: options.prompt }];
try {
const stream = await this.client.stream({ model, max_tokens: options.maxTokens || 10240, system: options.system, messages });
let stopReason: string | undefined, usage: TokenUsage | undefined;
for await (const chunk of stream) {
if (chunk.delta?.text) callbacks.onText(chunk.delta.text);
if (chunk.delta?.stop_reason) stopReason = chunk.delta.stop_reason;
if (chunk.usage) usage = { inputTokens: chunk.usage.input_tokens, outputTokens: chunk.usage.output_tokens };
}
if (usage) trackUsage(model, usage);
callbacks.onEnd({ stopReason, usage });
} catch (error) { callbacks.onError(error instanceof Error ? error : new Error(String(error))); }
}
}Verify: File exports the class; imports match existing providers.
Edit src/llm/types.ts line 1. Add your provider in kebab-case:
export type ProviderType = 'anthropic' | 'vertex' | 'openai' | 'cursor' | 'claude-cli' | 'your-provider';Verify: npx tsc --noEmit shows no ProviderType errors.
If your provider needs fields beyond apiKey, model, baseUrl, extend LLMConfig in src/llm/types.ts:
export interface LLMConfig {
provider: ProviderType;
model: string;
fastModel?: string;
apiKey?: string;
baseUrl?: string;
yourProviderSecret?: string;
}Edit src/llm/config.ts:
Line 9: Add to DEFAULT_MODELS:
export const DEFAULT_MODELS: Record<ProviderType, string> = {
anthropic: 'claude-sonnet-4-6',
vertex: 'claude-sonnet-4-6',
openai: 'gpt-5.4-mini',
cursor: 'sonnet-4.6',
'claude-cli': 'default',
'your-provider': 'your-provider/default-model',
};Line 17: Add to MODEL_CONTEXT_WINDOWS if known:
export const MODEL_CONTEXT_WINDOWS: Record<string, number> = {
'your-provider/model-name': 128_000,
};Line 59: In resolveFromEnv(), add env detection before final return null:
if (process.env.YOUR_PROVIDER_API_KEY) {
return {
provider: 'your-provider',
apiKey: process.env.YOUR_PROVIDER_API_KEY,
model: process.env.CALIBER_MODEL || DEFAULT_MODELS['your-provider'],
baseUrl: process.env.YOUR_PROVIDER_BASE_URL,
};
}Line 115: In readConfigFile() validation, add 'your-provider' to includes list.
Verify: npm run test -- src/llm/__tests__/ -t config confirms env var detection works.
Edit src/llm/index.ts. Add import (line ~4):
import { YourProviderProvider } from './your-provider.js';In createProvider() switch (line ~24), add before default case:
case 'your-provider':
return new YourProviderProvider(config);Verify: npx tsc --noEmit passes; no type errors on switch cases.
Create src/llm/__tests__/your-provider.test.ts:
import { describe, it, expect, beforeEach } from 'vitest';
import { YourProviderProvider } from '../your-provider.js';
describe('YourProviderProvider', () => {
let provider: YourProviderProvider;
beforeEach(() => {
provider = new YourProviderProvider({ provider: 'your-provider', model: 'test', apiKey: 'test' });
});
it('implements LLMProvider interface', () => {
expect(typeof provider.call).toBe('function');
expect(typeof provider.stream).toBe('function');
});
it('call() returns string', async () => {
const result = await provider.call({ system: 'helpful', prompt: 'hi' });
expect(typeof result).toBe('string');
});
it('stream() invokes callbacks', async () => {
const texts: string[] = [];
let ended = false;
await provider.stream({ system: 'helpful', prompt: 'hi' }, {
onText: (t) => texts.push(t),
onEnd: () => { ended = true; },
onError: () => {},
});
expect(ended).toBe(true);
});
});Verify: npm run test -- src/llm/__tests__/your-provider.test.ts passes.
Run factory tests with your provider env var:
YOUR_PROVIDER_API_KEY=test npm run test -- src/llm/__tests__/index.test.tsVerify: getProvider() instantiates your provider; llmCall() dispatches correctly.
User says: "I need caliber to use my local LM Studio instance."
Actions: Create src/llm/lm-studio.ts extending OpenAICompatProvider. Add 'lm-studio' to ProviderType. In config.ts:
if (process.env.LM_STUDIO_BASE_URL) {
return { provider: 'lm-studio', apiKey: '', model: 'local', baseUrl: process.env.LM_STUDIO_BASE_URL };
}Register in createProvider() case. User: export LM_STUDIO_BASE_URL=http://localhost:8000/v1. Result: caliber uses local LM Studio; tokens estimated via estimateTokens().
User says: "Ollama is auto-detected; no API key needed."
Actions: Create src/llm/ollama.ts extending OpenAICompatProvider. Add 'ollama' to ProviderType and SEAT_BASED_PROVIDERS. In config.ts:
if (process.env.OLLAMA_HOST) {
return { provider: 'ollama', model: 'mistral', baseUrl: process.env.OLLAMA_HOST || 'http://localhost:11434/v1' };
}Result: Offline per-machine LLM without API keys.
Unknown provider: your-provider
Cannot find module './your-provider.js'
API key is required for YourProvider
YOUR_PROVIDER_API_KEY=test npm run test -- src/llm/__tests__/index.test.ts.LLM response did not include usage tokens
trackUsage(model, { inputTokens: estimateTokens(options.system + options.prompt), outputTokens: estimateTokens(response.text) });Stream callbacks never fire; onEnd not called
for await (const chunk of stream) { } callbacks.onEnd({ stopReason, usage });My model parameter is ignored
options.model || this.defaultModel.const model = options.model || this.defaultModel; const response = await this.client.create({ model, ... });trackUsage() is never called
trackUsage(model, { inputTokens: ..., outputTokens: ... });Type error: Provider doesn't implement LLMProvider
© caliber-ai-org, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/llm-provider of caliber-ai-org/ai-setup.
Open the folder on GitHubat commit f5dbc00
LLM Provider 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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| LLM Provider this skillcaliber-ai-org/ai-setup | 1.3k | — | ~2.7k | Automated safety check: Pass | MIT | |
| Reasoning Serialization Teststailcallhq/forgecode | 7.6k | — | ~1k | Automated safety check: Pass | Apache-2.0 | |
| Visual QARandallLiuXin/GodotMaker | 550 | — | ~1.8k | Automated safety check: Pass | Custom licence | |
| ModLens Image Vision Bridgeliustack/modlens | 4.2k | — | ~1.3k | Automated safety check: Notes | MIT | |
| 9Router AI Gateway Setupdecolua/9router | 31k | — | ~744 | Automated safety check: Pass | MIT | |
| Mem0 Provider for Vercel AI SDKmem0ai/mem0 | 67k | — | ~2.3k | Automated safety check: Pass | Apache-2.0 |
tailcallhq/forgecode
Checks that ReasoningConfig fields are serialized into the right provider-specific JSON for OpenRouter, Anthropic, GitHub Copilot and Codex requests.
RandallLiuXin/GodotMaker
Visual quality assurance: analyze game screenshots for defects, compare against reference, check motion in frame sequences.
liustack/modlens
Gives text-only models sight by running the modlens CLI on an image path or URL and returning structured JSON evidence with transcribed text, layout and semantics.
decolua/9router
Sets up access to the 9Router AI gateway, an OpenAI-compatible REST endpoint for chat, images, speech, embeddings, web search and web fetch, and indexes its capability skills.
mem0ai/mem0
Adds persistent memory to Vercel AI SDK apps with the Mem0 provider, using a wrapped model or standalone retrieve and store utilities.
decolua/9router
Sends chat and code-generation requests through a 9Router gateway using OpenAI or Anthropic message formats, with streaming and auto-fallback combos.
caliber-ai-org/ai-setup
Creates a new CLI command following the Commander.js pattern in src/commands/.
caliber-ai-org/ai-setup
Writes Vitest tests following project patterns: tests/ directories, vi.mock() for module mocking with vi.hoisted() for test-time factories, global LLM mock from src/test/setup.ts, environment…
caliber-ai-org/ai-setup
Discovers and installs community skills from the public registry.
caliber-ai-org/ai-setup
Saves user instructions as persistent learnings for future sessions.
caliber-ai-org/ai-setup
Add a new deterministic scoring check in src/scoring/checks/ that evaluates config quality.
caliber-ai-org/ai-setup
Sets up Caliber for automatic AI agent context sync. An agent skill from caliber-ai-org/ai-setup.
Works with
Categories
Adds a new LLM provider implementing LLMProvider interface with call() and stream() methods. LLM Provider is an agent skill from caliber-ai-org/ai-setup. Adds a new LLM provider implementing LLMProvider interface with call() and stream() methods.
LLM Provider fits situations like: adding a new model backend; integrating a third-party LLM API; extending LLM platform support; fixing bugs in existing providers.
Run `npx skills add caliber-ai-org/ai-setup --skill llm-provider -a claude-code`. Or copy the skill folder (skills/llm-provider in caliber-ai-org/ai-setup) into .claude/skills/llm-provider in your project. Claude Code loads it when a task matches its description.
Run `npx skills add caliber-ai-org/ai-setup --skill llm-provider -a codex`. Or copy the skill folder (skills/llm-provider in caliber-ai-org/ai-setup) into .agents/skills/llm-provider in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add caliber-ai-org/ai-setup --skill llm-provider -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/llm-provider, .gemini/skills/llm-provider, .github/skills/llm-provider and .opencode/skills/llm-provider in your project.
Going by SKILL.md and its folder, LLM Provider needs the command-line tools its instructions call (npm and npx). Our summary lists: Node.js; A credential in YOUR_PROVIDER_API_KEY.
SKILL.md contains no URLs. Its commands use npm and npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
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.
LLM Provider is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
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.
Skills that share tags, products or a category with LLM Provider: Reasoning Serialization Tests (tailcallhq/forgecode, 7.6k stars), Visual QA (RandallLiuXin/GodotMaker, 550 stars), ModLens Image Vision Bridge (liustack/modlens, 4.2k stars) and 9Router AI Gateway Setup (decolua/9router, 31k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
caliber-ai-org (a GitHub organization) maintains it in caliber-ai-org/ai-setup, which has 1,302 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 24, 2026.
Source: caliber-ai-org/ai-setup on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.