一键导入
ax-provider-llm
Use when modifying LLM providers — Anthropic, OpenAI, multi-model router, traced wrapper, or mock provider in src/providers/llm/
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when modifying LLM providers — Anthropic, OpenAI, multi-model router, traced wrapper, or mock provider in src/providers/llm/
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when modifying logging, error handling, or diagnostic messages — logger setup, transports, error diagnosis patterns in src/logger.ts and src/errors.ts
Use when modifying the trusted host process — server orchestration, message routing, IPC handler, request lifecycle, event streaming, file handling, plugin loading, or agent delegation in src/host/
Use when modifying the sandboxed agent process — runner, IPC client, local/IPC tools, tool catalog, prompt building, or identity loading in src/agent/
Use when modifying agent sandbox isolation -- Docker, Apple Container (macOS), or k8s providers in src/providers/sandbox/
Use when modifying IPC protocol between host and agent — schemas, actions, length-prefix framing, or Zod validation in ipc-schemas.ts and ipc-server.ts
AX project architecture and coding skills - use sub-skills for specific subsystems (agent, host, cli, providers, etc.)
| name | ax-provider-llm |
| description | Use when modifying LLM providers — Anthropic, OpenAI, multi-model router, traced wrapper, or mock provider in src/providers/llm/ |
LLM providers implement streaming chat completions with tool use and advanced features (thinking/reasoning, vision) via the LLMProvider interface. Each provider exports a create(config: Config) factory and is registered in the static allowlist at src/host/provider-map.ts. Requests include optional task-type hints (default, fast, thinking, coding) for router-based model selection.
// src/providers/llm/types.ts
type ResolveImageFile = (fileId: string) => Promise<{ data: Buffer; mimeType: string } | null>;
interface ChatRequest {
model: string;
messages: Message[];
tools?: ToolDef[];
maxTokens?: number;
stream?: boolean;
taskType?: LLMTaskType; // Task type hint for router model selection
sessionId?: string; // Tracing backends (e.g. Langfuse session grouping)
resolveImageFile?: ResolveImageFile; // Resolves image fileId references to binary data
}
interface ChatChunk {
type: 'text' | 'thinking' | 'tool_use' | 'done';
content?: string;
toolCall?: { id: string; name: string; args: Record<string, unknown> };
usage?: { inputTokens: number; outputTokens: number };
}
interface LLMProvider {
name: string;
chat(req: ChatRequest): AsyncIterable<ChatChunk>;
models(): Promise<string[]>;
}
| Name | File | Description |
|---|---|---|
| Anthropic | src/providers/llm/anthropic.ts | Production provider using @anthropic-ai/sdk; OAuth-aware with proxy stub fallback; supports vision and thinking |
| OpenAI | src/providers/llm/openai.ts | OpenAI-compatible provider for OpenAI, Groq, OpenRouter, Fireworks, DeepInfra; supports reasoning/thinking and tool use |
| Router | src/providers/llm/router.ts | Multi-model router dispatching based on task type; per-provider cooldown and fallback chains |
| Traced | src/providers/llm/traced.ts | OpenTelemetry-instrumented wrapper; decorates any LLMProvider with span tracking |
| Mock | src/providers/llm/mock.ts | Canned responses for testing; keyword-matched replies, fixed usage stats |
ANTHROPIC_API_KEY and CLAUDE_CODE_OAUTH_TOKEN from env.client.messages.stream() (SSE). Yields text and thinking chunks on content_block_delta, tool_use chunks on content_block_stop, and a final done chunk with usage.type: 'image_data' (inline base64) or type: 'image' (file reference) are resolved via resolveImageFile callback and sent as base64 images to the API.{ type: 'thinking', content } chunks from thinking deltas.event.delta through unknown to extract both text and thinking properties safely.claude-sonnet-4-20250514. Default max tokens: 4096.OPENAI_API_KEY (or GROQ_API_KEY, OPENROUTER_API_KEY, FIREWORKS_API_KEY, DEEPINFRA_API_KEY for compatible providers).src/utils/openai-compat.ts (shared DEFAULT_BASE_URLS, envKey(), resolveBaseUrl() helpers).reasoning_content or reasoning from delta and yields as { type: 'thinking', content } chunks.unknown to safely access non-standard fields.src/providers/llm/router.ts'default', 'fast', 'thinking', 'coding' (from LLM_TASK_TYPES in src/types.ts).config.models keyed by task type; each value is an array of compound provider/model IDs.parseCompoundId() from src/providers/router-utils.ts to split on first /.req.taskType to candidate chain (or defaults to 'default').src/providers/llm/traced.tschat() call creates a gen_ai.chat span with attributes for model, max_tokens, session ID, and tool metadata.gen_ai.assistant.message and gen_ai.tool.call events.src/providers/router-utils.tsparseCompoundId(id: string): ModelCandidate -- splits compound IDs on first /.src/providers/shared-types.tshello, remember, default greeting).text, one done.src/providers/llm/<name>.ts exporting create(config: Config): Promise<LLMProvider>.chat() as an async * generator yielding ChatChunk objects (text -> thinking -> tool_use -> done).models() returning supported model IDs.src/host/provider-map.ts.tests/providers/llm/<name>.test.ts.safePath() if the provider reads any files from config-derived paths.resolveImageFile from ChatRequest. Check message.content for type: 'image' or type: 'image_data' blocks. Resolve file references via callback. Convert to provider-native format.thinking or reasoning_content properties. Cast delta through unknown first. Yield { type: 'thinking', content } chunks.chat() returns AsyncIterable<ChatChunk>, not a Promise. Always implement as async *chat().req.taskType is unset, router falls back to 'default'. Ensure config.models.default always exists.done chunk is required: Always yield a done chunk with usage as the last item.unknown when accessing thinking, reasoning_content, etc.