Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ Workflow: `.github/workflows/sync-agent-sdk-openapi.yml`
- Use Mintlify components (`<Note>`, `<Warning>`, `<Tabs>`, etc.) where appropriate.
- When linking internally, prefer **absolute** doc paths (e.g. `/overview/quickstart`).

## LLM API Key Options

The SDK documentation maintains three ways for users to obtain LLM access:

1. **Direct Provider** - Bring your own API key from providers like Anthropic, OpenAI, etc.
2. **OpenHands Cloud** - Use OpenHands Cloud API keys (recommended for verified models)
3. **Third-party Subscription Login** - Authenticate with existing subscriptions (e.g., ChatGPT Plus/Pro via `LLM.subscription_login()`)

When documenting LLM setup or examples, ensure all three options are mentioned where appropriate:
- `sdk/getting-started.mdx` - Main getting started page with AccordionGroup
- `sdk/shared-snippets/how-to-run-example.mdx` - Shared snippet for running examples
- `sdk/guides/llm-subscriptions.mdx` - Dedicated guide for subscription login

## Validation

### LLM pricing table validation
Expand Down
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
{
"group": "LLM Features",
"pages": [
"sdk/guides/llm-subscriptions",
"sdk/guides/llm-registry",
"sdk/guides/llm-routing",
"sdk/guides/llm-reasoning",
Expand Down
12 changes: 12 additions & 0 deletions sdk/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ The SDK requires an LLM API key from any [LiteLLM-supported provider](https://do

[Learn more →](/openhands/usage/llms/openhands-llms)
</Accordion>

<Accordion title="Option 3: ChatGPT Subscription" icon="message">
If you have a ChatGPT Plus or Pro subscription, you can use `LLM.subscription_login()` to authenticate with your ChatGPT account and access Codex models without consuming API credits.

```python
from openhands.sdk import LLM

llm = LLM.subscription_login(vendor="openai", model="gpt-5.2-codex")
```

[Learn more →](/sdk/guides/llm-subscriptions)
</Accordion>
</AccordionGroup>

> Tip: Model name prefixes depend on your provider
Expand Down
165 changes: 165 additions & 0 deletions sdk/guides/llm-subscriptions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
---
title: LLM Subscriptions
description: Use your ChatGPT Plus/Pro subscription to access Codex models without consuming API credits.
---

import RunExampleCode from "/sdk/shared-snippets/how-to-run-example.mdx";

<Info>
OpenAI subscription is the first provider we support. More subscription providers will be added in future releases.
</Info>

> A ready-to-run example is available [here](#ready-to-run-example)!

Use your existing ChatGPT Plus or Pro subscription to access OpenAI's Codex models without consuming API credits. The SDK handles OAuth authentication, credential caching, and automatic token refresh.

## How It Works

<Steps>
<Step>
### Call subscription_login()

The `LLM.subscription_login()` class method handles the entire authentication flow:

```python icon="python"
from openhands.sdk import LLM

llm = LLM.subscription_login(vendor="openai", model="gpt-5.2-codex")
```

On first run, this opens your browser for OAuth authentication with OpenAI. After successful login, credentials are cached locally in `~/.openhands/auth/` for future use.
</Step>
<Step>
### Use the LLM

Once authenticated, use the LLM with your agent as usual. The SDK automatically refreshes tokens when they expire.
</Step>
</Steps>

## Supported Models

The following models are available via ChatGPT subscription:

| Model | Description |
|-------|-------------|
| `gpt-5.2-codex` | Latest Codex model (default) |
| `gpt-5.2` | GPT-5.2 base model |
| `gpt-5.1-codex-max` | High-capacity Codex model |
| `gpt-5.1-codex-mini` | Lightweight Codex model |

## Configuration Options

### Force Fresh Login

If your cached credentials become stale or you want to switch accounts:

```python icon="python"
llm = LLM.subscription_login(
vendor="openai",
model="gpt-5.2-codex",
force_login=True, # Always perform fresh OAuth login
)
```

### Disable Browser Auto-Open

For headless environments or when you prefer to manually open the URL:

```python icon="python"
llm = LLM.subscription_login(
vendor="openai",
model="gpt-5.2-codex",
open_browser=False, # Prints URL to console instead
)
```

### Check Subscription Mode

Verify that the LLM is using subscription-based authentication:

```python icon="python"
llm = LLM.subscription_login(vendor="openai", model="gpt-5.2-codex")
print(f"Using subscription: {llm.is_subscription}") # True
```

## Credential Storage

Credentials are stored securely in `~/.openhands/auth/`. To clear cached credentials and force a fresh login, delete the files in this directory.

## Ready-to-run Example

<Note>
This example is available on GitHub: [examples/01_standalone_sdk/35_subscription_login.py](https://github.com/OpenHands/software-agent-sdk/blob/main/examples/01_standalone_sdk/35_subscription_login.py)
</Note>

```python icon="python" expandable examples/01_standalone_sdk/35_subscription_login.py
"""Example: Using ChatGPT subscription for Codex models.

This example demonstrates how to use your ChatGPT Plus/Pro subscription
to access OpenAI's Codex models without consuming API credits.

The subscription_login() method handles:
- OAuth PKCE authentication flow
- Credential caching (~/.openhands/auth/)
- Automatic token refresh

Supported models:
- gpt-5.2-codex
- gpt-5.2
- gpt-5.1-codex-max
- gpt-5.1-codex-mini

Requirements:
- Active ChatGPT Plus or Pro subscription
- Browser access for initial OAuth login
"""

import os

from openhands.sdk import LLM, Agent, Conversation, Tool
from openhands.tools.file_editor import FileEditorTool
from openhands.tools.terminal import TerminalTool


# First time: Opens browser for OAuth login
# Subsequent calls: Reuses cached credentials (auto-refreshes if expired)
llm = LLM.subscription_login(
vendor="openai",
model="gpt-5.2-codex", # or "gpt-5.2", "gpt-5.1-codex-max", "gpt-5.1-codex-mini"
)

# Alternative: Force a fresh login (useful if credentials are stale)
# llm = LLM.subscription_login(vendor="openai", model="gpt-5.2-codex", force_login=True)

# Alternative: Disable auto-opening browser (prints URL to console instead)
# llm = LLM.subscription_login(
# vendor="openai", model="gpt-5.2-codex", open_browser=False
# )

# Verify subscription mode is active
print(f"Using subscription mode: {llm.is_subscription}")

# Use the LLM with an agent as usual
agent = Agent(
llm=llm,
tools=[
Tool(name=TerminalTool.name),
Tool(name=FileEditorTool.name),
],
)

cwd = os.getcwd()
conversation = Conversation(agent=agent, workspace=cwd)

conversation.send_message("List the files in the current directory.")
conversation.run()
print("Done!")
```

<RunExampleCode path_to_script="examples/01_standalone_sdk/35_subscription_login.py"/>

## Next Steps

- **[LLM Registry](/sdk/guides/llm-registry)** - Manage multiple LLM configurations
- **[LLM Streaming](/sdk/guides/llm-streaming)** - Stream responses token-by-token
- **[LLM Reasoning](/sdk/guides/llm-reasoning)** - Access model reasoning traces
8 changes: 6 additions & 2 deletions sdk/shared-snippets/how-to-run-example.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{/*
This snippet describe on how to run an example using your own API-key or the Openhands Cloud
This snippet describe on how to run an example using your own API-key, the Openhands Cloud, or ChatGPT subscription
*/}
You can run the example code as-is.

Expand All @@ -15,4 +15,8 @@ You can run the example code as-is.
<CodeBlock language="bash" filename="OpenHands Cloud" icon="terminal" wrap>
{`# https://app.all-hands.dev/settings/api-keys\nexport LLM_API_KEY="your-openhands-api-key"\nexport LLM_MODEL="openhands/claude-sonnet-4-5-20250929"\ncd software-agent-sdk\nuv run python ${path_to_script}`}
</CodeBlock>
</CodeGroup>
</CodeGroup>

<Tip>
**ChatGPT Plus/Pro subscribers**: You can use `LLM.subscription_login()` to authenticate with your ChatGPT account and access Codex models without consuming API credits. See the [LLM Subscriptions guide](/sdk/guides/llm-subscriptions) for details.
</Tip>