Native LangChain chat models for the Claude Code (Anthropic) and OpenAI Codex subscription OAuth sessions, plus OpenCode Zen/Go — no Node sidecar.
Project description
open-langchain
Native LangChain chat models for OpenAI Codex (ChatGPT Plus/Pro subscription OAuth), Claude (Claude Code subscription OAuth), and OpenCode Zen/Go. No Pi runtime, no Node sidecar.
Requirements
- Python >= 3.9
- For Codex: an
openai-codexcredential in~/.pi/agent/auth.json, or sign in withcodex-login - For Claude Code: the Claude Code CLI logged in once (
~/.claude/.credentials.json) - For paid OpenCode models:
OPENCODE_API_KEYor an explicitapi_key
Install
pip install open-langchain
# or: uv add open-langchain
Usage
create_chat routes the supported native providers:
from open_langchain import create_chat
codex = create_chat("openai-codex", "gpt-5.3-codex-spark")
claude = create_chat("claude-code", "claude-sonnet-4-6")
free = create_chat("opencode", "deepseek-v4-flash-free")
go = create_chat("opencode-go", "glm-5", api_key="...")
Or construct Codex directly:
from open_langchain import ChatCodex
model = ChatCodex(
model="gpt-5.3-codex-spark",
reasoning="minimal",
system="You are a helpful assistant.",
)
print(model.invoke("Hello!").content)
Codex Auth
ChatCodex reads the same ~/.pi/agent/auth.json credential shape under
openai-codex, refreshes the OAuth token in place, and talks directly to
https://chatgpt.com/backend-api/codex/responses.
If no credential exists:
codex-login
codex-login --device
Tool Calling
from langchain_core.tools import tool
from open_langchain import ChatCodex
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"It is sunny in {city}, 24C."
model = ChatCodex(model="gpt-5.3-codex").bind_tools([get_weather])
msg = model.invoke("What's the weather in Paris?")
print(msg.tool_calls)
tool_choice is passed through to the Codex Responses API:
forced = ChatCodex(model="gpt-5.3-codex").bind_tools(
[get_weather],
tool_choice={"type": "function", "name": "get_weather"},
)
For agent loops, keep tool_choice="auto" unless every model turn should call the
same tool.
Streaming
for chunk in model.stream("Write a haiku."):
print(chunk.content, end="")
OpenCode
ChatOpencode uses OpenCode's OpenAI-compatible endpoints through
langchain-openai.
from open_langchain import ChatOpencode
free = ChatOpencode("deepseek-v4-flash-free")
paid = ChatOpencode("glm-5")
go = ChatOpencode("glm-5", tier="go")
Free models include deepseek-v4-flash-free, big-pickle, mimo-v2.5-free, and
nemotron-3-super-free.
Claude Code (Anthropic subscription)
ChatClaudeCode talks to the Anthropic Messages API authenticated with the
Claude Code OAuth session already on the machine (~/.claude/.credentials.json),
billing requests against your Claude Code subscription — no API key. It reads and
refreshes the token in place (with a claude CLI fallback).
from open_langchain import ChatClaudeCode, create_chat
chat = create_chat("claude-code", "claude-sonnet-4-6")
print(chat.invoke("Hello!").content)
# Or construct directly, with options:
opus = ChatClaudeCode(model="claude-opus-5", reasoning="medium")
Models: claude-opus-5, claude-fable-5, claude-opus-4-8, claude-opus-4-7,
claude-sonnet-5, claude-sonnet-4-6, claude-haiku-4-5. Reasoning uses
adaptive thinking on the Claude 5 family and Opus 4.8/4.7, and a token budget on
Sonnet 4.6 (Haiku has no reasoning). The Claude 5 models ship a 1M context
window by default; for the older models the 1M-context beta is opt-in via
long_context=True, since the subscription rejects long-context requests
without extra credits otherwise. Tool calling and streaming work as with
ChatCodex.
Using a subscription OAuth session from a third-party app may violate Anthropic's terms and risk your account. See the
pi-claude-code-authREADME before relying on this.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file open_langchain-0.7.0.tar.gz.
File metadata
- Download URL: open_langchain-0.7.0.tar.gz
- Upload date:
- Size: 267.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6e70510abd33d9410e46e4d4b7f9093b7422ca9fec9b4c0eb45118658687713
|
|
| MD5 |
ced06772131c31ccea8f740ff8dfee96
|
|
| BLAKE2b-256 |
77ff589f9aea2d775f05f1f9d703f7a3bcaca220790c819eac08b15cb3326543
|
File details
Details for the file open_langchain-0.7.0-py3-none-any.whl.
File metadata
- Download URL: open_langchain-0.7.0-py3-none-any.whl
- Upload date:
- Size: 33.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c53a0bfefda3fae9284dd0b038baee8e8cb4780394a840e392d5b3d76c66a10
|
|
| MD5 |
2fef82cc84a8da8cc386e69e7681b0ca
|
|
| BLAKE2b-256 |
783a7f575bed620b3a7b992c05745c628817bf9c3ee076b7551b2e2b9e7fee51
|