@victor-software-house/pi-openai-proxy 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +4256 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# pi-openai-proxy
|
|
2
|
+
|
|
3
|
+
A local OpenAI-compatible HTTP proxy built on [pi](https://github.com/badlogic/pi-mono)'s SDK. Routes requests through pi's multi-provider model registry and credential management, exposing a single `http://localhost:<port>/v1/...` endpoint that any OpenAI-compatible client can connect to.
|
|
4
|
+
|
|
5
|
+
## Project docs
|
|
6
|
+
|
|
7
|
+
- `README.md` -- project overview and API surface
|
|
8
|
+
- `ROADMAP.md` -- short phase summary and delivery order
|
|
9
|
+
- `PLAN.md` -- detailed implementation contract (internal)
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
- **Single gateway** to 20+ LLM providers (Anthropic, OpenAI, Google, Bedrock, Mistral, xAI, Groq, OpenRouter, Vertex, etc.) via one OpenAI-compatible API
|
|
14
|
+
- **No duplicate config** -- reuses pi's `~/.pi/agent/auth.json` and `models.json` for credentials and model definitions
|
|
15
|
+
- **Self-hosted** -- runs locally, no third-party proxy services
|
|
16
|
+
- **Streaming** -- full SSE streaming with token usage and cost tracking
|
|
17
|
+
- **Agentic mode** (planned) -- expose pi's full agent loop (tools, sessions, compaction) behind a separate experimental endpoint
|
|
18
|
+
|
|
19
|
+
## Supported Endpoints
|
|
20
|
+
|
|
21
|
+
| Endpoint | Status | Description |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `GET /v1/models` | Implemented | List all available models from pi's ModelRegistry |
|
|
24
|
+
| `GET /v1/models/{model}` | Implemented | Model details for a canonical model ID (supports URL-encoded IDs with `/`) |
|
|
25
|
+
| `POST /v1/chat/completions` | Implemented | Chat completions (streaming and non-streaming) |
|
|
26
|
+
|
|
27
|
+
## Supported Chat Completions Features
|
|
28
|
+
|
|
29
|
+
| Feature | Status | Notes |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `model` | Implemented | Resolved via `ModelRegistry.find()`, canonical or shorthand |
|
|
32
|
+
| `messages` (text) | Implemented | System, developer, user, assistant, tool messages |
|
|
33
|
+
| `messages` (base64 images) | Implemented | Base64 data URI image content parts |
|
|
34
|
+
| `messages` (remote images) | Rejected | Disabled by default; returns clear error |
|
|
35
|
+
| `stream` | Implemented | SSE with `text_delta` / `toolcall_delta` mapping |
|
|
36
|
+
| `temperature` | Implemented | Direct passthrough to `StreamOptions` |
|
|
37
|
+
| `max_tokens` / `max_completion_tokens` | Implemented | Normalized to `StreamOptions.maxTokens` |
|
|
38
|
+
| `stop` sequences | Implemented | Via `onPayload` passthrough |
|
|
39
|
+
| `user` | Implemented | Via `onPayload` passthrough |
|
|
40
|
+
| `stream_options.include_usage` | Implemented | Final usage chunk in SSE stream |
|
|
41
|
+
| `tools` / `tool_choice` | Implemented | JSON Schema -> TypeBox conversion (supported subset) |
|
|
42
|
+
| `tool_calls` in messages | Implemented | Assistant tool call + tool result roundtrip |
|
|
43
|
+
| `reasoning_effort` | Implemented | Maps to pi's `ThinkingLevel` (`low`, `medium`, `high`) |
|
|
44
|
+
| `response_format` | Implemented | `text` and `json_object` via `onPayload` passthrough |
|
|
45
|
+
| `top_p` | Implemented | Via `onPayload` passthrough |
|
|
46
|
+
| `frequency_penalty` | Implemented | Via `onPayload` passthrough |
|
|
47
|
+
| `presence_penalty` | Implemented | Via `onPayload` passthrough |
|
|
48
|
+
| `seed` | Implemented | Via `onPayload` passthrough |
|
|
49
|
+
| `n > 1` | Not planned | Pi streams one completion at a time |
|
|
50
|
+
| `logprobs` | Not planned | Not in pi-ai's abstraction layer |
|
|
51
|
+
|
|
52
|
+
## Architecture
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
HTTP Client pi-openai-proxy
|
|
56
|
+
(curl, Aider, Continue, +--------------------------+
|
|
57
|
+
LiteLLM, Open WebUI, etc.) | |
|
|
58
|
+
| | Hono HTTP Server |
|
|
59
|
+
| POST /v1/chat/ | +-- Request parser |
|
|
60
|
+
+--completions------>| +-- Message converter |
|
|
61
|
+
| | +-- Model resolver |
|
|
62
|
+
| GET /v1/models | +-- Tool converter |
|
|
63
|
+
+------------------>| +-- SSE encoder |
|
|
64
|
+
| | |
|
|
65
|
+
| | Pi SDK |
|
|
66
|
+
| SSE / JSON | +-- ModelRegistry |
|
|
67
|
+
|<------------------+ +-- AuthStorage |
|
|
68
|
+
| +-- streamSimple() |
|
|
69
|
+
| +-- AgentSession (P4) |
|
|
70
|
+
+--------------------------+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Pi SDK Layers Used
|
|
74
|
+
|
|
75
|
+
- **`@mariozechner/pi-ai`** -- `streamSimple()`, `completeSimple()`, `Model`, `Usage`, `AssistantMessageEvent`
|
|
76
|
+
- **`@mariozechner/pi-coding-agent`** -- `ModelRegistry`, `AuthStorage`
|
|
77
|
+
|
|
78
|
+
## Model Naming
|
|
79
|
+
|
|
80
|
+
Models are addressed as `provider/model-id`, matching pi's registry:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
anthropic/claude-sonnet-4-20250514
|
|
84
|
+
openai/gpt-4o
|
|
85
|
+
google/gemini-2.5-pro
|
|
86
|
+
xai/grok-3
|
|
87
|
+
openrouter/anthropic/claude-sonnet-4-20250514
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Shorthand (bare model ID) is resolved by scanning all providers for a unique match. Ambiguous shorthand requests fail with a clear error listing the matching canonical IDs.
|
|
91
|
+
|
|
92
|
+
## Configuration
|
|
93
|
+
|
|
94
|
+
Uses pi's existing configuration:
|
|
95
|
+
|
|
96
|
+
- **API keys**: `~/.pi/agent/auth.json` (managed by `pi /login`)
|
|
97
|
+
- **Custom models**: `~/.pi/agent/models.json`
|
|
98
|
+
- **Per-request override**: `X-Pi-Upstream-Api-Key` header overrides the registry-resolved API key for a single request, keeping `Authorization` available for proxy authentication
|
|
99
|
+
|
|
100
|
+
### Environment Variables
|
|
101
|
+
|
|
102
|
+
| Variable | Default | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `PI_PROXY_HOST` | `127.0.0.1` | Bind address |
|
|
105
|
+
| `PI_PROXY_PORT` | `4141` | Listen port |
|
|
106
|
+
| `PI_PROXY_AUTH_TOKEN` | (disabled) | Bearer token for proxy authentication |
|
|
107
|
+
| `PI_PROXY_AGENTIC` | `false` | Enable experimental agentic mode |
|
|
108
|
+
| `PI_PROXY_REMOTE_IMAGES` | `false` | Enable remote image URL fetching |
|
|
109
|
+
| `PI_PROXY_MAX_BODY_SIZE` | `52428800` (50 MB) | Maximum request body size in bytes |
|
|
110
|
+
| `PI_PROXY_UPSTREAM_TIMEOUT_MS` | `120000` (120s) | Upstream request timeout in milliseconds |
|
|
111
|
+
|
|
112
|
+
## Dev Workflow
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
bun install # Install dependencies
|
|
116
|
+
bun run dev # Run in development
|
|
117
|
+
bun run build # Build for npm (tsdown)
|
|
118
|
+
bun run typecheck # TypeScript strict check
|
|
119
|
+
bun run lint # Biome + oxlint (strict)
|
|
120
|
+
bun test # Run all tests
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Tooling
|
|
124
|
+
|
|
125
|
+
- **Bun** -- runtime, test runner, package manager
|
|
126
|
+
- **tsdown** -- npm build (ESM + .d.ts)
|
|
127
|
+
- **Biome** -- format + lint
|
|
128
|
+
- **oxlint** -- type-aware lint with strict rules (`.oxlintrc.json`)
|
|
129
|
+
- **lefthook** -- pre-commit hooks (format, lint, typecheck), pre-push hooks (test)
|
|
130
|
+
- **commitlint** -- conventional commits
|
|
131
|
+
- **semantic-release** -- automated versioning and npm publish
|
|
132
|
+
- **mise** -- tool version management (node, bun)
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* pi-openai-proxy entry point.
|
|
5
|
+
*
|
|
6
|
+
* Initializes the pi model registry, creates the Hono app, and starts serving.
|
|
7
|
+
* Implements graceful shutdown on SIGTERM/SIGINT.
|
|
8
|
+
*/
|
|
9
|
+
declare const server: Bun.Server<undefined>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { server as default };
|