Skip to main content

Drop-in ChatOpenAI replacement for LangChain/LangGraph using Codex ChatGPT OAuth subscription.

Project description

AlgoceanCodexOAuth

LangChain / LangGraph에서 ChatOpenAI 자리에 그대로 꽂는 Codex ChatGPT OAuth LLM 래퍼입니다.

API key 과금 경로는 코드에서 차단하고, 로컬 codex login으로 저장된 ChatGPT OAuth 구독 한도만 사용합니다.

LangGraph / LangChain
  → AlgoceanCodexOAuth
  → codex exec
  → 로컬 ChatGPT OAuth 세션
  → Codex 구독 한도 / 크레딧

설치

1. Codex CLI + ChatGPT OAuth (1회)

npm install -g @openai/codex

unset OPENAI_API_KEY
unset CODEX_API_KEY
codex logout
codex login
codex login status

공식 인증 문서: Codex Authentication

2. Python 패키지

pip install algocean-codex-oauth

LangGraph 프로젝트:

pip install algocean-codex-oauth langgraph langchain-core

Quick Start

ChatOpenAI → AlgoceanCodexOAuth (1:1 교체)

Before (API key)

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model="gpt-4o")
response = llm.invoke([HumanMessage(content="FastAPI Depends를 짧게 설명해줘.")])
print(response.content)

After (Codex OAuth)

from algocean_codex_oauth import AlgoceanCodexOAuth
from langchain_core.messages import HumanMessage

llm = AlgoceanCodexOAuth(model="gpt-5.5")
response = llm.invoke([HumanMessage(content="FastAPI Depends를 짧게 설명해줘.")])
print(response.content)

LangGraph

단일 노드

from langchain_core.messages import HumanMessage, SystemMessage
from langgraph.graph import StateGraph, END
from typing_extensions import TypedDict

from algocean_codex_oauth import AlgoceanCodexOAuth

class State(TypedDict):
    user_input: str
    answer: str

llm = AlgoceanCodexOAuth(model="gpt-5.5")

async def assistant_node(state: State) -> State:
    messages = [
        SystemMessage(content="간결한 개인 비서."),
        HumanMessage(content=state["user_input"]),
    ]
    ai = await llm.ainvoke(messages)
    return {"answer": ai.content}

graph = StateGraph(State)
graph.add_node("assistant", assistant_node)
graph.set_entry_point("assistant")
graph.add_edge("assistant", END)
app = graph.compile()

ReAct Agent

from langgraph.prebuilt import create_react_agent
from langchain_core.messages import HumanMessage
from algocean_codex_oauth import AlgoceanCodexOAuth

llm = AlgoceanCodexOAuth(model="gpt-5.5")
agent = create_react_agent(llm, tools=[])
result = agent.invoke({"messages": [HumanMessage(content="hello")]})

Structured Output (LangGraph state merge)

from pydantic import BaseModel, Field
from langchain_core.messages import HumanMessage
from algocean_codex_oauth import AlgoceanCodexOAuth

class Analysis(BaseModel):
    summary: str = Field(description="요약")
    risk_level: str = Field(description="low | medium | high")

llm = AlgoceanCodexOAuth(model="gpt-5.5")
structured = llm.with_structured_output(Analysis)
result = structured.invoke([HumanMessage(content="위험도를 평가해줘.")])
print(result.summary, result.risk_level)

내부적으로 Codex CLI --output-schema를 사용합니다.
문서: Codex non-interactive mode

ChatOpenAI 기능 대응

ChatOpenAI (API key) AlgoceanCodexOAuth
llm.invoke(messages) 동일
await llm.ainvoke(messages) 동일
llm.astream(messages) 동일
llm.with_structured_output(schema) 동일
LangGraph state["messages"] 멀티턴 thread_mode="messages" (기본)
대화 세션 유지 thread_mode="codex_resume" + ephemeral=False
새 대화 시작 llm.reset_thread()
response.response_metadata["usage"] 동일

생성자

AlgoceanCodexOAuth(
    model: str = "gpt-5.5",
    *,
    timeout: int = 180,
    sandbox: str = "read-only",
    workdir: str | None = None,
    ephemeral: bool = True,
    thread_mode: str = "messages",     # messages | codex_resume
    codex_bin: str = "codex",
    require_chatgpt_login: bool = True,
)

Preset

llm = AlgoceanCodexOAuth.chat(model="gpt-5.5")                  # messages 멀티턴
llm = AlgoceanCodexOAuth.repo_read(workdir="/path/to/repo")
llm = AlgoceanCodexOAuth.repo_write(workdir="/path/to/repo")    # codex_resume
Preset thread_mode 멀티턴 방식
chat() messages ChatOpenAI처럼 messages 히스토리 전달
repo_read(path) messages messages 히스토리
repo_write(path) codex_resume Codex exec resume (에이전트)

멀티턴 — ChatOpenAI와 동일하게

방식 1: messages (기본, LangGraph 표준)

messages = [HumanMessage(content="코드네임은 ALPHA7")]
ai1 = await llm.ainvoke(messages)
messages += [ai1, HumanMessage(content="코드네임이 뭐야?")]
ai2 = await llm.ainvoke(messages)

LangGraph state["messages"] 패턴과 1:1 동일합니다.

방식 2: codex_resume (Codex thread 유지)

llm = AlgoceanCodexOAuth(
    model="gpt-5.5",
    workdir="/path/to/repo",
    sandbox="read-only",
    ephemeral=False,
    thread_mode="codex_resume",
)

await llm.ainvoke([HumanMessage(content="첫 질문")])
await llm.ainvoke([HumanMessage(content="이어서")])  # exec resume
llm.reset_thread()  # 새 대화

Streaming

async for chunk in llm.astream([HumanMessage(content="hello")]):
    print(chunk.content, end="", flush=True)

Provider 스위치 (미니 Codex)

def get_llm(use_codex_oauth: bool):
    if use_codex_oauth:
        from algocean_codex_oauth import AlgoceanCodexOAuth
        return AlgoceanCodexOAuth(model="gpt-5.5")
    from langchain_openai import ChatOpenAI
    return ChatOpenAI(model="gpt-4o")

그래프 코드는 동일하고 import / 클래스만 바꾸면 됩니다.

OAuth 정책

라이브러리는 호출마다 아래를 강제합니다.

  • OPENAI_API_KEY, CODEX_API_KEY 환경 변수 제거
  • require_chatgpt_login=Truecodex login status로 ChatGPT OAuth 확인
  • API key 인증 감지 시 AlgoceanCodexOAuthError 발생

아키텍처

algocean_codex_oauth/
├── chat_model.py    # AlgoceanCodexOAuth (BaseChatModel) — public API
├── client.py        # codex exec / exec resume
├── auth.py          # OAuth 검증, API key 차단
├── config.py        # AlgoceanCodexConfig
├── messages.py      # LangChain messages → prompt
├── session.py       # 멀티턴 thread resume (고급)
└── errors.py

멀티턴 (Session 래퍼)

AlgoceanCodexSessionthread_mode="codex_resume" 편의 래퍼입니다.
직접 AlgoceanCodexOAuth(..., thread_mode="codex_resume") 를 써도 동일합니다.

제한

  • 개인 로컬 / 개인 구독 용도입니다. SaaS 서버에서 외부 사용자에게 AI를 제공하는 용도에는 맞지 않습니다.
  • Codex CLI(codex)가 PATH에 있어야 합니다.
  • danger-full-access sandbox는 격리 환경에서만 사용하세요.

개발

git clone https://github.com/algocean1204/AlgoceanCodexOAuth.git
cd AlgoceanCodexOAuth
pip install -e ".[dev]"
pytest

PyPI

pip install algocean-codex-oauth

License

MIT

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

algocean_codex_oauth-0.1.0.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

algocean_codex_oauth-0.1.0-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file algocean_codex_oauth-0.1.0.tar.gz.

File metadata

  • Download URL: algocean_codex_oauth-0.1.0.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for algocean_codex_oauth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 101f73ee9bf9c5f7b581a5e2b44420b4876dc72e6fb8562b2b0838b51f8042c3
MD5 f691a0768e635c1e28fefaddd320c3c0
BLAKE2b-256 ecb2baa3f9fdb3738f44eb2bab6cd07f03e09874f8d89903c9cc687e0babfbfc

See more details on using hashes here.

File details

Details for the file algocean_codex_oauth-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for algocean_codex_oauth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2dda47950c62a8c99d6e9a0a9aae485d5b853e2bb55eab21e964e0dd98ff3c5d
MD5 4bc22d2f85985288279d5ca07e7be553
BLAKE2b-256 c0196a71a6771ff52b819bb8fa86c0bbe09938c600f152f38ce3ab4cc8ee66d5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page