ワンクリックで
ax-provider-development
Use as a step-by-step guide when adding a new provider implementation or an entirely new provider category to AX
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use as a step-by-step guide when adding a new provider implementation or an entirely new provider category to AX
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-development |
| description | Use as a step-by-step guide when adding a new provider implementation or an entirely new provider category to AX |
This is a walkthrough for adding providers to AX. Every provider follows the same contract pattern: a TypeScript interface, a create(config) export, a static allowlist entry, and co-located tests. Follow these steps in order.
Example: adding a redis implementation to the memory provider category.
Create src/providers/memory/redis.ts:
import type { Config } from '../../types.js';
import type { MemoryProvider, MemoryEntry } from './types.js';
import { safePath } from '../../utils/safe-path.js'; // if doing file ops
export function create(config: Config): MemoryProvider {
// Initialize provider state
return {
async write(entry) { /* ... */ },
async query(q) { /* ... */ },
async read(id) { /* ... */ },
async delete(id) { /* ... */ },
async list(scope, limit) { /* ... */ },
};
}
Rules:
create(config: Config) — this is the contracttypes.tssafePath() for ANY file path constructed from inputEdit src/host/provider-map.ts:
memory: {
file: '../providers/memory/file.js',
sqlite: '../providers/memory/sqlite.js',
memu: '../providers/memory/memu.js',
redis: '../providers/memory/redis.js', // ← Add this
},
SC-SEC-002: This is mandatory. Without it, the provider cannot be loaded.
Create tests/providers/memory/redis.test.ts:
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
import { create } from '../../../src/providers/memory/redis.js';
describe('MemoryProvider/redis', () => {
test('create returns valid provider', () => {
const provider = create(mockConfig);
expect(provider.write).toBeInstanceOf(Function);
expect(provider.query).toBeInstanceOf(Function);
// ... test all interface methods
});
test('write and query round-trip', async () => {
const provider = create(mockConfig);
await provider.write({ scope: 'test', content: 'hello' });
const results = await provider.query({ scope: 'test', query: 'hello' });
expect(results).toHaveLength(1);
});
});
Edit src/types.ts to add any new config fields the provider needs.
Example: adding a notifications provider category.
Create src/providers/notifications/types.ts:
export interface NotificationProvider {
send(opts: { channel: string; message: string }): Promise<void>;
list(channel: string): Promise<Notification[]>;
}
export interface Notification {
id: string;
channel: string;
message: string;
timestamp: number;
}
Create src/providers/notifications/console.ts:
import type { Config } from '../../types.js';
import type { NotificationProvider } from './types.js';
export function create(config: Config): NotificationProvider {
return {
async send(opts) { console.log(`[${opts.channel}] ${opts.message}`); },
async list() { return []; },
};
}
notifications: {
console: '../providers/notifications/console.js',
},
Edit src/types.ts:
// In Config.providers:
notifications: string;
// In ProviderRegistry:
notifications: NotificationProvider;
Edit src/host/registry.ts in loadProviders():
notifications: await loadProvider('notifications', config.providers.notifications, config),
src/ipc-schemas.ts with .strict()src/host/ipc-server.tssrc/agent/ipc-tools.ts (TypeBox schema)src/agent/mcp-server.ts (Zod v4 schema)tests/sandbox-isolation.test.tsPROFILE_DEFAULTS in src/onboarding/prompts.tsPROVIDER_CHOICES in prompts.tswizard.tsCreate tests/providers/notifications/console.test.ts.
Use this checklist every time you add a provider:
create(config: Config)safePath() for all file path construction from inputPROVIDER_MAP in provider-map.tstests/types.ts, Config + ProviderRegistry updatedsandbox-isolation.test.tsWhen developing a new provider, be aware of all existing categories in the provider map:
| Category | Implementations | Notes |
|---|---|---|
| llm | anthropic, openai, openrouter, groq, deepinfra, router, mock | Multi-model router available |
| image | openai, openrouter, groq, gemini, router, mock | |
| memory | cortex | Embedding-based with SummaryStore |
| scanner | patterns, guardian | Input/output security scanning |
| channel | slack | Session addressing |
| web | none, fetch, tavily | Proxied HTTP with taint tagging |
| browser | none, container | Sandboxed Playwright |
| credentials | plaintext, keychain | OS keychain for secure storage |
| skills | database | Git-backed proposals |
| audit | database | JSONL/DB audit logs |
| sandbox | subprocess, docker, apple, k8s | Agent isolation (see note below) |
| scheduler | none, plainjob | Cron/heartbeat |
| screener | static, none | Skill content screening |
| database | sqlite, postgresql | Shared connection factory |
| storage | database | Message queue, sessions, docs |
| eventbus | inprocess, nats | Pub/sub for completion events |
| workspace | none, local, gcs | Persistent file workspaces (recent addition) |
Sandbox providers: The sandbox category has been simplified. Old Linux-specific providers (seatbelt, nsjail, bwrap) have been removed. The current set is: subprocess (no isolation, dev use), docker (container isolation), apple (Apple Container on macOS), and k8s (Kubernetes pods with NATS IPC). In k8s mode, IPC runs over NATS instead of Unix sockets.
Workspace provider (src/providers/workspace/): A recent addition that manages persistent file workspaces for agent sessions. Three scopes (agent, user, session) with mount/commit/cleanup lifecycle. Backends: none (no-op), local (filesystem), gcs (Google Cloud Storage). Loaded in registry.ts as part of the standard provider chain.
provider-map.ts entry causes a runtime throw, not a compile error. Always add it.create() validated at runtime: registry.ts checks that the module exports a create function. Missing it silently fails until startup.types.ts. Don't put provider interfaces in the shared src/types.ts.config.providers.channels is string[], loaded as ChannelProvider[]. Other categories are single strings.ipc-tools.ts (TypeBox) AND mcp-server.ts (Zod). Missing one breaks that runner variant.Type.Object(...) from TypeBox. IPC schemas use z.strictObject(...) from Zod.safePath() is security-critical: Any file-based provider that skips safePath() is a path traversal vulnerability. This is enforced by code review.ax-testing skill for patterns.registry.ts alongside all other providers. If adding a new category, follow the same pattern (loaded after database, before the return statement).