Skip to content

Commit 5cc58fb

Browse files
committed
docs(context): record the port fallback notice and version reporting
1 parent 1c91aa5 commit 5cc58fb

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

CLAUDE.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This is a Rust workspace with three main components:
2929
- Core streaming library for LLM interactions
3030
- Provider-agnostic API that supports multiple LLM services
3131
- Uses Server-Sent Events (SSE) via a custom eventsource-client fork
32-
- Providers: OpenAI, Anthropic, Google, Mistral, Ollama, Groq, Jina, DeepSeek
32+
- Providers: OpenAI, Anthropic, Google, Mistral, Ollama, Groq, Jina, DeepSeek, and ChatGPT (subscription)
3333
- Simple, synchronous-style API that abstracts away complex async operations
3434

3535
### CLI (`crates/llm_stream/`)
@@ -38,6 +38,8 @@ This is a Rust workspace with three main components:
3838
- Features: conversation history, templates, presets, external editor support
3939
- Syntax highlighting using syntect with Tokyo Night themes
4040
- Streaming output with spinners and colored terminal output
41+
- ChatGPT subscription sign-in (`--login`, `--login-status`, `--logout`), stored at `<config_dir>/auth.json` with mode `0600`
42+
- Reasoning controls for the `chatgpt` provider: `--reasoning-effort`, `--reasoning-summary`, `--models`
4143

4244
### Build Tools (`xtask/`)
4345
- Custom build automation following the cargo-xtask pattern
@@ -53,6 +55,19 @@ Each LLM provider has a dedicated module (e.g., `anthropic.rs`, `openai.rs`) tha
5355
- Streaming delta processing
5456
- Provider-specific error handling
5557

58+
### The ChatGPT Provider
59+
Unlike every other provider, `--api chatgpt` authenticates with a ChatGPT subscription's
60+
OAuth credentials rather than an API key, over an undocumented endpoint internal to
61+
OpenAI's Codex CLI. Two rules are load-bearing and easy to break by accident:
62+
63+
- **Never send a `version` header** to that endpoint — it gates model access, and any value
64+
we send is compared against Codex's own release train. The guard comment lives at
65+
`lib/llm_stream/src/chatgpt.rs:337`.
66+
- **Never print raw access or refresh tokens**, in logs, errors, or debug output.
67+
68+
There is deliberately no local model allowlist: `--model` passes through verbatim and the
69+
server's own refusal reaches the operator. `--models` probes the server for the answer.
70+
5671
### Configuration System
5772
- TOML-based configuration in `~/.config/llm-stream/config.toml`
5873
- Supports templates for prompt engineering
@@ -71,9 +86,33 @@ Each LLM provider has a dedicated module (e.g., `anthropic.rs`, `openai.rs`) tha
7186

7287
## Testing
7388

74-
Run tests with appropriate environment variables for API keys:
89+
```bash
90+
cargo test # aborts at the first failing target — see below
91+
cargo test -p llm-stream --bin llm-stream # CLI unit tests
92+
cargo test -p llm_stream --lib # library unit tests
93+
cargo test -p llm-stream --test cli # offline CLI integration tests
94+
```
95+
96+
`prelude::tests::test_preset_system_over_config_system` is a known, pre-existing failure. It
97+
makes a bare `cargo test` stop before reaching `crates/llm_stream/tests/`, so name the
98+
target explicitly.
99+
100+
Some providers' unit tests read API keys from the environment:
101+
75102
```bash
76103
OPENAI_API_KEY=sk-... cargo test
77104
```
78105

106+
### The live ChatGPT smoke test
107+
108+
`crates/llm_stream/tests/live_chatgpt.rs` performs one real round trip against a ChatGPT
109+
subscription. It skips unless opted in, because every run spends the operator's quota:
110+
111+
```bash
112+
LLM_STREAM_LIVE_TEST=1 cargo test -p llm-stream --test live_chatgpt -- --nocapture
113+
```
114+
115+
It requires a completed `llm-stream --login`. **Never make it unconditional and never wire
116+
it into CI.**
117+
79118
Examples are available in `lib/llm_stream/examples/` for each provider.

CONTEXT.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Running `llm-stream --login` authenticates the operator against a ChatGPT subscr
3232
- **WHEN** the loopback callback's `state` parameter is missing or does not match the value generated at the start of `--login`
3333
- **THEN** the sign-in fails and no credentials are stored
3434

35+
#### Scenario: The preferred loopback port is occupied
36+
- **WHEN** the operator runs `llm-stream --login` while another process holds port 1455
37+
- **THEN** the CLI prints a warning to stderr naming port 1455, the port it fell back to, and what to close
38+
- **AND** the sign-in continues on the fallback port
39+
3540
### Requirement: Credential storage permissions
3641
Stored ChatGPT credentials are only ever readable and writable by the file's owner.
3742

@@ -161,3 +166,10 @@ The config file's top-level `base_url`, `env`, `key`, `version`, and `model` def
161166
#### Scenario: Config file matches the selected provider
162167
- **WHEN** the operator runs `llm-stream --api <provider> "<prompt>"` and the config file's top-level `api` matches `<provider>`, or omits `--api` entirely
163168
- **THEN** `base_url`, `env`, `key`, `version`, and `model` are inherited from the config file as before
169+
170+
### Requirement: Version reporting
171+
Running `llm-stream --version` identifies the binary and the version actually installed.
172+
173+
#### Scenario: Reporting the installed version
174+
- **WHEN** the operator runs `llm-stream --version`
175+
- **THEN** the CLI prints `llm-stream <version>`, where `<version>` is the version of the installed `llm-stream` package

0 commit comments

Comments
 (0)