GitHub - Vlad1mir-D/atuin-ai-proxy · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
Vlad1mir-D
atuin-ai-proxy
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
master
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>17 Commits<br>17 Commits
atuin_ai_proxy
atuin_ai_proxy
tests
tests
.dockerignore
.dockerignore
.env.example
.env.example
.gitignore
.gitignore
Dockerfile
Dockerfile
README.md
README.md
docker-compose.yaml.example
docker-compose.yaml.example
pyproject.toml
pyproject.toml
View all files
Repository files navigation
Atuin AI Proxy
Python 3 proxy that exposes the Atuin Hub AI endpoint expected by Atuin and forwards requests to OpenAI-compatible Chat Completions or Responses backends.
Atuin config
Point Atuin at the proxy:
[ai]<br>enabled = true<br>endpoint = "http://localhost:8000"<br>api_token = "change-me"
Set api_token to the same value as ATUIN_PROXY_TOKEN. If ATUIN_PROXY_TOKEN is unset, the proxy accepts local requests without bearer auth.
Run with Docker Compose
cp .env.example .env<br># edit .env<br>docker compose up --build
Backends:
# OpenAI-compatible API<br>BACKEND=openai<br>OPENAI_API_KEY=sk-...<br>OPENAI_API=auto<br>MODEL=...
# Codex access token or personal access token<br>BACKEND=codex-token<br>CODEX_ACCESS_TOKEN=at-...<br>CODEX_ACCOUNT_ID=...<br>MODEL=...
# Codex OAuth auth.json<br>BACKEND=codex-oauth<br>CODEX_HOME=/data/codex<br>MODEL=...
Server binding:
HOST=0.0.0.0<br>PORT=8000
OPENAI_API applies only to BACKEND=openai and accepts auto, responses,<br>or chat_completions. The default auto mode tries Chat Completions first and<br>falls back to Responses when the Chat Completions request is rejected as<br>unsupported.
The codex-token and codex-oauth backends support only the Responses API. If<br>OPENAI_API=chat_completions is configured with either Codex backend, the proxy<br>logs a startup warning and uses the Responses API.
For Codex OAuth device login:
docker compose run --rm atuin-ai-proxy atuin-ai-proxy auth login --device-code<br>docker compose up
To use an existing Codex CLI auth file, mount it as /data/codex/auth.json or set CODEX_AUTH_FILE to the mounted path.<br>CODEX_CLIENT_ID can override the bundled Codex OAuth client id when needed.
Local development
The implementation uses only the Python standard library at runtime.
python3 -m unittest discover -s tests<br>python3 -m atuin_ai_proxy serve
Debugging
The proxy includes a request id in every HTTP response and in stream errors. When<br>Atuin reports SSE request failed (...), copy the request_id from the JSON<br>body and search for it in the proxy logs.
Logging levels:
# Normal operational logs<br>LOG_LEVEL=INFO
# Startup warnings and errors only<br>LOG_LEVEL=WARNING
# Request/backend diagnostics: model source, upstream status, tool names, timings<br>LOG_LEVEL=DEBUG
# DEBUG plus sanitized request, backend, and SSE payload excerpts<br>LOG_LEVEL=TRACE<br>TRACE_PAYLOAD_BYTES=4096
For local runs, the serve command can override LOG_LEVEL with any level the<br>proxy emits: TRACE, DEBUG, INFO, WARNING, or ERROR.
python3 -m atuin_ai_proxy serve --log-level DEBUG
TRACE output is sanitized and bounded, but it can still include shell history,<br>prompts, paths, and command output. Use it only while diagnosing a problem.
Common failures:
400 missing_model: set MODEL=... or configure Atuin to send a model.
400 invalid_json / 400 invalid_request: Atuin sent a body the proxy could<br>not parse or convert.
401 unauthorized: Atuin [ai].api_token does not match ATUIN_PROXY_TOKEN.
502 auth_error: backend auth is missing or invalid.
502 upstream_http_error: the selected backend rejected the converted<br>upstream request; the error body includes a sanitized upstream excerpt.
504 upstream_timeout: the backend did not respond before<br>REQUEST_TIMEOUT_SECONDS.
Protocol notes
The proxy accepts POST /api/cli/chat, returns text/event-stream, sets x-atuin-ai-session-id, and translates upstream stream events into Atuin stream events:
response.output_text.delta -> text
Chat Completions choices[].delta.content -> text
completed function_call items ->...