https://github.com/pppp606/cli-agent-openai-adapter
https://github.com/pppp606/cli-agent-openai-adapter
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/pppp606/cli-agent-openai-adapter
- Owner: pppp606
- License: mit
- Created: 2025-11-13T11:03:12.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-11-13T13:39:16.000Z (8 months ago)
- Last Synced: 2025-11-13T15:24:45.895Z (8 months ago)
- Size: 25.4 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cli-agent-openai-adapter
Convert CLI-based AI agents (Claude Code, etc.) to OpenAI ChatAPI endpoints.
## Overview
This adapter allows you to use local CLI tools like Claude Code as drop-in replacements for OpenAI's API in your development environment, while keeping the same code structure for production.
**Use Cases:**
- **Production**: Use OpenAI API (pay per token)
- **Development**: Use local Claude Code with Haiku model (reduce costs)
- **Same Code**: Switch between environments using the same API interface (e.g., LangChain's `ChatOpenAI`)
**Default Model:** This adapter uses Claude Haiku by default for cost efficiency during development. You can configure a different model (e.g., Sonnet, Opus) via the `MODEL` environment variable.
## Features
- ✅ OpenAI-compatible API endpoints (`/v1/chat/completions`)
- ✅ Support for conversation history
- ✅ Stateless execution (like OpenAI API)
- ✅ Chat-only mode (tools disabled for safety)
- ✅ TypeScript with full type definitions
- 🚧 Claude Code adapter (initial implementation)
- 🔜 Codex adapter (future)
- 🔜 Gemini CLI adapter (future)
## Demo
Try the adapter with the minimal, dependency-free web client:
```bash
# Start the adapter (project root)
npm ci
npm run build && npm start
# Open the client in your browser
# File path: examples/minimal-web-client/index.html
```
[→ Minimal Web Client README](examples/minimal-web-client/README.md)
## Installation
```bash
npm install -g cli-agent-openai-adapter
```
Or use directly with npx:
```bash
npx cli-agent-openai-adapter
```
## Prerequisites
- Node.js >= 20.0.0
- Claude Code CLI installed and accessible in PATH
To verify Claude Code is installed:
```bash
claude --version
```
## Usage
### Start the Server
```bash
cli-agent-openai-adapter
```
By default, the server starts at `http://localhost:8000`.
### Configuration
Configure using environment variables:
```bash
export ADAPTER_TYPE=claude-code # Adapter to use
export MODEL=haiku # Claude model to use (default: haiku)
export PORT=8000 # Server port
export HOST=localhost # Server host
export RUNTIME_DIR=./runtime # Runtime directory (optional)
export TIMEOUT=30000 # Timeout in milliseconds
export DEBUG=true # Enable debug mode
```
Or create a `.env` file (requires `dotenv`).
**Note:** This adapter uses **Haiku** as the default model to reduce costs during development. You can change the model by setting the `MODEL` environment variable to `sonnet` or `opus` if needed.
### Example with LangChain
```typescript
import { ChatOpenAI } from "@langchain/openai";
// Development environment: via cli-agent-openai-adapter
const llmDev = new ChatOpenAI({
configuration: {
baseURL: "http://localhost:8000/v1"
},
modelName: "claude-code",
apiKey: "dummy" // Not used but required by the SDK
});
// Production environment: OpenAI API directly
const llmProd = new ChatOpenAI({
openAIApiKey: process.env.OPENAI_API_KEY,
modelName: "gpt-4"
});
// Usage is identical
const response = await llmDev.invoke("Hello!");
console.log(response.content);
```
### Example with OpenAI SDK
```typescript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://localhost:8000/v1",
apiKey: "dummy" // Not used but required by the SDK
});
const response = await client.chat.completions.create({
model: "claude-code",
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello!" }
]
});
console.log(response.choices[0].message.content);
```
### Example with Direct HTTP Request
```bash
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-code",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
```
## API Endpoints
### POST /v1/chat/completions
OpenAI-compatible chat completions endpoint.
**Request:**
```json
{
"model": "claude-code",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello"}
],
"temperature": 0.7,
"max_tokens": 1000
}
```
**Response:**
```json
{
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1234567890,
"model": "claude-code",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you?"
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30
}
}
```
### GET /v1/models
List available models.
**Response:**
```json
{
"object": "list",
"data": [
{
"id": "claude-code",
"object": "model",
"created": 1234567890,
"owned_by": "cli-agent-openai-adapter"
}
]
}
```
### GET /health
Health check endpoint.
**Response:**
```json
{
"status": "ok",
"adapter": "claude-code"
}
```
## How It Works
### Architecture
1. **Stateless Execution**: Each request executes `claude code --system-prompt "..." -p "..."` independently
2. **Conversation History**: Managed by the client (like OpenAI API), sent in the `messages` array
3. **Chat Mode**: Tools are disabled via `.claude/settings.json` for chat-only behavior
4. **Output Cleaning**: ANSI codes and progress indicators are removed from CLI output
### Conversation History Handling
The adapter formats conversation history as JSON and includes it in the prompt:
```
System Prompt: [Your system message] + Context instruction
User Prompt:
Conversation history:
[
{"role": "user", "content": "My favorite color is blue"},
{"role": "assistant", "content": "That's nice!"}
]
Current user message: What is my favorite color?
```
This allows Claude to understand the full context while maintaining stateless execution.
## Error Handling
The adapter handles various error scenarios:
- **Timeout (30s default)**: Returns HTTP 504 with timeout error
- **CLI tool not found**: Fails at startup with clear error message
- **Invalid request**: Returns HTTP 400 with validation error
- **Execution error**: Returns HTTP 500 with error details
## Troubleshooting
### Claude Code not found
**Error:** `claude-code is not available`
**Solution:** Make sure Claude CLI is installed and accessible:
```bash
# Check if claude is in PATH
which claude
# Try running claude directly
claude --version
```
### Timeout errors
**Error:** `Claude Code execution timed out`
**Solution:** Increase timeout:
```bash
export TIMEOUT=60000 # 60 seconds
```
### Output contains noise
If responses contain ANSI codes or progress indicators, please report as an issue with examples.
## Development
### Setup
```bash
git clone https://github.com/pppp606/cli-agent-openai-adapter.git
cd cli-agent-openai-adapter
npm install
```
### Run in Development Mode
```bash
npm run dev
```
### Build
```bash
npm run build
```
### Run Tests
```bash
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
```
The project uses Jest for testing with full TypeScript support. All tests are located in `src/__tests__/` directory.
### Project Structure
```
cli-agent-openai-adapter/
├── src/
│ ├── adapters/
│ │ ├── base.ts # Abstract base class
│ │ ├── claude_code.ts # Claude Code implementation
│ │ └── factory.ts # Adapter factory
│ ├── bin/
│ │ └── cli.ts # CLI entry point
│ ├── server.ts # Express server
│ ├── config.ts # Configuration loader
│ ├── types.ts # TypeScript types
│ └── index.ts # Main exports
├── runtime/
│ └── claude-code/ # Claude Code runtime
│ └── .claude/
│ └── settings.json # Tool disable configuration
├── package.json
├── tsconfig.json
└── README.md
```
## Future Enhancements
- [ ] Support for streaming responses
- [ ] Support for Codex CLI adapter
- [ ] Support for Gemini CLI adapter
- [ ] Configuration file support (.adaprc)
- [ ] Better token estimation
- [ ] Conversation history truncation/summarization
- [ ] Logging and metrics
- [ ] Docker support
## License and Terms
This tool is provided under the MIT License.
**Important:** When using Claude Code through this adapter, you must comply with Anthropic's Terms of Service. Please use this tool in accordance with all applicable terms and conditions.
## Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
---
**Note:** This is an early implementation. The actual behavior of Claude Code CLI options may require adjustments. Please test in your environment and report any issues.