Metadata-Version: 2.4
Name: abstract-gpt
Version: 0.1.0
Summary: Codex login and session management for the abstract toolserver
Author: jrputkey
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Provides-Extra: mcp
Requires-Dist: abstract-claude>=0.1.30; extra == "mcp"

# abstract-gpt

Codex login and session management, usable as a CLI and as the optional `/gpt/*`
category in `abstract_toolserver`. Requires Python 3.11+, Linux (for HTTP login
locking), and an installed Codex CLI.

```bash
pip install -e /srv/pyit/dev/abstract_gpt
abstract-gpt oauth-status
abstract-gpt login                    # device URL + code; approve in your browser
abstract-gpt launch --                # new interactive conversation
abstract-gpt exec -- "Explain this repository"  # ephemeral noninteractive session
```

`login --browser` uses normal browser login. `login --with-api-key` reads a key
from stdin via Codex itself. API key usage has separate API billing. No key is
required for the ChatGPT subscription login flow.

## Toolserver

Install in the toolserver's Python environment, then add alongside its Claude merge:

```python
_merge_optional_toolset("abstract_gpt.toolset:get_toolset")
```

Restart the service to register these routes. They use the toolserver's existing
authentication and execute as its OS user (`vm_mgr` on this host):

| Route | Purpose |
| --- | --- |
| `/gpt/state` | Wrapper configuration and local login status |
| `/gpt/oauth_status` | Local credential availability; not a live entitlement probe |
| `/gpt/oauth_solution` | Login instructions |
| `/gpt/login_start` | Start device login, or return an existing attempt |
| `/gpt/login_poll` | Poll state, verification URL and one-time code |
| `/gpt/save_template` | Save config.toml privately |
| `/gpt/restore` | Restore config only when missing |
| `/gpt/set_model` | Set `default_model`; null clears wrapper default |

Use POST for mutations. Device login runs in a detached subprocess with a
15-minute timeout; a file lock prevents duplicate flows across gunicorn workers.
Poll until `authenticated`, `failed`, `expired`, or `interrupted`. After service
restart, an interrupted attempt can be started again. Failed login output remains in the private `AG_ROOT/login-output.txt` for local
diagnostics, and is cleared at the next attempt. Raw login output and stored
credentials are never returned by the HTTP tools. The device code is sensitive:
use the existing authenticated toolserver connection.

## Storage and sessions

- `CODEX_HOME`: existing Codex home, default `~/.codex`. Login and launch use the
  same store so Codex manages token refresh. No credentials are copied between users.
- `AG_ROOT`: wrapper storage, default `~/.local/share/abstract_gpt`, private mode 0700.
- `AG_CODEX_BIN`: optional executable path. Otherwise `~/.local/bin/codex`, then PATH. The user-local binary takes priority
  to avoid selecting a Snap launcher inside a restricted systemd service.
- `abstract-gpt init`, `state`, `save-template`, `restore`, `set-model MODEL`,
  `login-start`, `login-poll`, and `oauth-solution` mirror their actions.
- `launch` starts a new conversation by default; explicit Codex resume flags still
  work. `exec` adds `--ephemeral`. Neither deletes existing sessions or changes
  sandbox/approval settings. Explicit model flags override the wrapper default.
- A config template can contain user-configured secrets; it stays private and is
  never returned through the API. It does not include auth.json or transcripts.

This package does not emulate Claude's durable token export, destructive reset,
or automatic quota fallback. Codex owns its cached authentication and renewal.
A service login applies to that service account; other OS users log in separately.

## Toolserver tools inside Codex

Optional `pip install 'abstract-gpt[mcp]'` reuses the existing protocol-neutral
`abstract_claude.mcp` bridge:

```bash
codex mcp add toolserver -- abstract-gpt mcp
```

The bridge honors `TOOLSERVER_URL` and the existing Hugpy operator credentials.

## Validation

```bash
PYTHONPATH=src python -m unittest discover -s tests -v
```

Tests use a fake Codex executable; they never consume model credits or change real
credentials. Authentication behavior follows the
[official Codex documentation](https://developers.openai.com/codex/auth/).
