Skip to main content

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-codex credential in ~/.pi/agent/auth.json, or sign in with codex-login
  • For Claude Code: the Claude Code CLI logged in once (~/.claude/.credentials.json)
  • For paid OpenCode models: OPENCODE_API_KEY or an explicit api_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", "nemotron-3.5-lightning-free")
go = create_chat("opencode-go", "minimax-m3", 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 models: gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-6-astra, gpt-5.5, gpt-5.3-codex-spark. As of 2026-09 the ChatGPT account only serves these; older GPT-5.x ids return 400 not supported when using Codex with a ChatGPT account. calculate_cost follows models.dev pricing, including the long-context tier that bills the whole request at the higher rate once the prompt exceeds 272k tokens. Ids outside the catalog are still sent to the API, but calculate_cost prices them as unknown and returns 0.

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.5").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.5").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("nemotron-3.5-lightning-free")
paid = ChatOpencode("minimax-m3", api_key="...")
go = ChatOpencode("minimax-m3", tier="go", api_key="...")

Free models include nemotron-3.5-lightning-free, big-pickle, and mimo-v2.5-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). On macOS it reads the login keychain item Claude Code-credentials first and falls back to ~/.claude/.credentials.json, writing the refreshed token back to whichever source it read. An explicit creds_path always wins and uses only that file.

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-1, 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.

tool_choice is forwarded to the Messages API unchanged. claude-fable-5-1 rejects a forced tool choice - "any" or a named tool - with a 400, so use tool_choice="auto" with that model.

Using a subscription OAuth session from a third-party app may violate Anthropic's terms and risk your account. See the pi-claude-code-auth README before relying on this.

License

MIT

Metadata

Release files for open-langchain 0.8.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for open-langchain 0.8.1
File Size Uploaded
open_langchain-0.8.1.tar.gz 272.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for open-langchain 0.8.1
File Interpreter ABI Platform
open_langchain-0.8.1-py3-none-any.whl Python 3 none any Details

Total release size: 307.3 kB

Release files / open_langchain-0.8.1.tar.gz

Download URL open_langchain-0.8.1.tar.gz
Size 272.2 kB
Tags Source
SHA-256 checksum
How to use checksums
b225aa952096581c86ab21a1d34f3ff461fc5893a9829f35235efa231bb23c8c
BLAKE2b-256 checksum
How to use checksums
0f2bab6f9d6405c99693f9a258e4933172997316128b6c9a420586f237e759c3
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / open_langchain-0.8.1-py3-none-any.whl

Download URL open_langchain-0.8.1-py3-none-any.whl
Size 35.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
929b445a431885b2e3275f62a55c329b91baf26b0951bc2422d37e9f783a984d
BLAKE2b-256 checksum
How to use checksums
f8a3bc628feee88d73833bbddcf7b5133f996dfa32216c87459ec7bfa0fc4075
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release history Release notifications | RSS feed

This release

0.8.1 This release

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page