Repository navigation
feat: add litellm.agent() to run claude code, codex, opencode and deep agents through the ai gateway - #43885
Conversation
…e_code/api_error.jsonl
…e_code/max_turns.jsonl
…e_code/resume_turn.jsonl
…e_code/structured_output.jsonl
|
@Veria please re-review at 8e8f811. Both open issues (OpenCode repo plugins, Deep Agents symlink escape) are fixed with regression tests; details in the earlier comment. @greptileai please re-review the latest commits. |
| post_routes = tuple( | ||
| Route( | ||
| f"{prefix}/{route}", | ||
| self._handle, | ||
| methods=["POST"], # mutable-ok: Starlette Route takes a methods list | ||
| ) | ||
| for prefix, route in itertools.product(ROUTE_PREFIXES, POST_ROUTES) |
There was a problem hiding this comment.
Custom HTTP handler violates requirement
This endpoint registers its own Starlette routes and uses its own handler to parse and dispatch model requests. The repository requires new HTTP handlers to reuse LiteLLM’s existing HTTP-handler infrastructure instead of implementing a custom handler.
Rule Used: What: Block any PR which writes it's own custom http handler instead of reusing litellm's existing http handlers. (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…dbox_backend_symlinks.py
|
@greptileai thanks, addressed in d31d713:
Please re-review. |
litellm.agent() (BerriAI/litellm#43885, merged 2026-10-01) runs Claude Code, Codex, opencode and Deep Agents through the gateway with a per-session token. It overlaps with Ploeg's Run execution; Ploeg already meters through LiteLLM. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
## [unfold-v0.4.0-rc.46](https://forgejo.webgrip.dev/webgrip/unfold/compare/unfold-v0.4.0-rc.45...unfold-v0.4.0-rc.46) (2026-10-08) ### Added * **unfold:** answer VS Code's getNetworkDiagnosticsInfo on the AHP host ([b4009da](https://forgejo.webgrip.dev/webgrip/unfold/commit/b4009da67d51e5a79e79978cb3ef95236e0b393f)) * **unfold:** keep AHP read and archive state per person ([d91f8db](https://forgejo.webgrip.dev/webgrip/unfold/commit/d91f8db0a1bde5fb911a5b275e071a5bc026fa38)) * **unfold:** let an AHP client accept a candidate, and drop the dead operation ([288c2bb](https://forgejo.webgrip.dev/webgrip/unfold/commit/288c2bb23e07bb1492cf01f26c794cddd2483223)) * **unfold:** resume a known AHP client with reconnect on a new connection ([68e3da7](https://forgejo.webgrip.dev/webgrip/unfold/commit/68e3da765bac19cd0e0d4072511a018d640865ee)) ### Fixed * **unfold:** accept GHE.com API roots for GitHub task sources ([39a7e75](https://forgejo.webgrip.dev/webgrip/unfold/commit/39a7e7574fda64a5c01d706b9e05f0c78f09e6bb)) * **unfold:** advertise the AHP candidate as a session changeset on the chat ([c2ee2f6](https://forgejo.webgrip.dev/webgrip/unfold/commit/c2ee2f6699059c58c5a1e1dc977b7825f5b24cdd)) * **unfold:** announce AHP chat activity with chat/activityChanged ([2ad38a0](https://forgejo.webgrip.dev/webgrip/unfold/commit/2ad38a0cca2c4bfd8dfbcd1d6fd76592befd9cd3)) * **unfold:** clear finished AHP activity with null in summary changes ([e1ed1dc](https://forgejo.webgrip.dev/webgrip/unfold/commit/e1ed1dc0f16f4dde3c8601c362db6b97eafb469e)) * **unfold:** echo every accepted AHP client action in server order ([a921c21](https://forgejo.webgrip.dev/webgrip/unfold/commit/a921c2189cb39c446f6df170ccbbf25629294626)) * **unfold:** honour createSession.activeClient on the AHP host ([18f908e](https://forgejo.webgrip.dev/webgrip/unfold/commit/18f908e51c25326370a29dbd6c62d85da367f3b3)) * **unfold:** keep a dropped AHP active client through its reconnect ([b614313](https://forgejo.webgrip.dev/webgrip/unfold/commit/b614313b3ac10f20f98c92d96a7bef8631182fa2)) * **unfold:** keep a resumed AHP client's session spelling ([2ee4ce5](https://forgejo.webgrip.dev/webgrip/unfold/commit/2ee4ce5a300b6c2dbfa20cfd9ae0a5644ea760ba)) * **unfold:** keep every AHP input request inside a turn the client holds ([fd334a6](https://forgejo.webgrip.dev/webgrip/unfold/commit/fd334a68b23ece7bdd5e98d2ed5914b373fedc62)) * **unfold:** keep GHE.com enterprises apart when matching checkout remotes ([1039e00](https://forgejo.webgrip.dev/webgrip/unfold/commit/1039e00e1ebd6b8dfe538060bc2deffcbc19c899)) * **unfold:** negotiate the AHP protocol version by the 1.0 rule ([748ddf5](https://forgejo.webgrip.dev/webgrip/unfold/commit/748ddf5c3eff6dad0ee495a2d15b6c2be67b2875)) * **unfold:** send AHP questions with a message, their choices and a real answer path ([3334a9e](https://forgejo.webgrip.dev/webgrip/unfold/commit/3334a9e0d1b11e5a355d60d9989889def62977ac)) * **unfold:** send root/activeSessionsChanged to each AHP viewer ([eaf46e4](https://forgejo.webgrip.dev/webgrip/unfold/commit/eaf46e4c1130fa2ea029fb807387e4ef747de3a5)) * **unfold:** serve each AHP candidate file whole on both sides ([78d9951](https://forgejo.webgrip.dev/webgrip/unfold/commit/78d995166e2e33c14e98da531c43d91244f4ac39)) * **unfold:** spell AHP session URIs by VS Code's own host rule ([f087609](https://forgejo.webgrip.dev/webgrip/unfold/commit/f0876092b6467000a6f70fbe8252da71cfd282b1)) * **unfold:** spell AHP session URIs the way each client asked ([f71edfb](https://forgejo.webgrip.dev/webgrip/unfold/commit/f71edfb512c6e74094f45149d04c85496a25f185)) * **unfold:** stop doubling the first chunk of every streamed AHP markdown part ([a97a9ec](https://forgejo.webgrip.dev/webgrip/unfold/commit/a97a9ececc9983a9a3a1f2329e5e55fe21a0bb5b)) ### Docs * add LiteLLM agent() to the market landscape ([b6ddb52](https://forgejo.webgrip.dev/webgrip/unfold/commit/b6ddb527dbffa49e54ad6233827613b1b2c970da)), references [BerriAI/litellm#43885](https://forgejo.webgrip.dev/BerriAI/litellm/issues/43885) * record the VS Code 1.141 fit, AHP 1.0 and the two 1.142 host breaks ([1d0fef3](https://forgejo.webgrip.dev/webgrip/unfold/commit/1d0fef3e5271e60c3a66e3ea36b320584a2c1a01)) * **unfold:** record the AHP host fixes and correct the Open VSX risk ([c9ec4f0](https://forgejo.webgrip.dev/webgrip/unfold/commit/c9ec4f0fb2f4df58bf287cecc32921c1ff55c4b3)) * **unfold:** record the final AHP end-to-end run and reconnect fixes ([62d0e65](https://forgejo.webgrip.dev/webgrip/unfold/commit/62d0e6555692cce85e8984db79ee4a067548ed23)) ### Tests * **unfold:** replay VS Code main and 1.141 against the AHP host ([9b884ec](https://forgejo.webgrip.dev/webgrip/unfold/commit/9b884ecbb6191e0373a90c9880fb34f9c2fea708))
TLDR
Problem this solves:
How it solves it:
litellm.agent()/litellm.aagent(), plusagent_session,agent_resume,agent_capabilitiesHarnessis a typed enum; passing a string raisesTypeErrormodel="litellm_proxy/<group>"sends every agent model call through the AI GatewayBaseHarnessConfig(litellm/llms/<harness>/harness/transformation.py); one generic handler does the I/OlitellmWhat you get
With
stream=Trueyou get typed events as they happen. Real output from all four harnesses on the same task, each routed through the gateway (metadata={"run": "pr-proof"}shows up in spend logs, taggedharness,<name>):Sessions keep the runtime's own conversation across turns and can be saved and resumed in another process:
User Flow
Before: a developer who wants Codex to fix a repo on their team's Bedrock models has no LiteLLM path
~/.codex/config.tomlto point it at their LiteLLM gatewayAfter: the same developer runs Codex from Python through the gateway with one call
pip install litellm starlette uvicorn, havecodexon PATH, and setLITELLM_PROXY_API_BASE/LITELLM_PROXY_API_KEYlitellm.agent(Harness.CODEX, "fix the flaky test", sandbox=sandbox.local("./repo"), model="litellm_proxy/coder")result.costharness,codexPre-Submission checklist
Screenshots / Proof of Fix
Real runs against
https://gateway.litellm-sandbox.ai, real model calls, no mocks, realclaude,codexandopencodeCLIs and realdeepagents.Before (82d8b37)
All harnesses
python -c "import litellm; litellm.agent"AttributeError: module 'litellm' has no attribute 'agent'After (f76c2ac)
One task on each harness
python .claude/harness-docs/demo.py(the script behind the output under "What you get")hello.py: Claude Code $0.00233, Codex $0.05512, OpenCode $0.03474, Deep Agents $0.01527E2E suite, all four harnesses
LITELLM_PROXY_API_BASE=... LITELLM_PROXY_API_KEY=... pytest tests/harness_e2e -v26 passed. For each harness: creates a file and reports cost, streams events withDonelast, returns validated structured output, remembers an earlier turn, detaches and resumes, read-only blocks writes. Plus a string harness is rejected and an unsupported option fails before the runtime startsUnit tests
pytest tests/unit/harness tests/unit/llms/{base_llm/harness,claude_code,codex,opencode,deepagents}285 passed, 1 skipped(the skip is a live test that needs gateway env)Type
🆕 New Feature
✅ Test
Caveats (if any)
Medium
claude/codex/opencodemust be on PATHpermissions="ask"(interactive approval) only on Deep Agents for now~/.cache/litellm-harnessso resume workstests/harness_e2eis allowlisted out of CI (needs live CLIs and a gateway); run it manuallyLow
urllib3/pyjwt/nextlockfile versions; also red onmainsince 18:57 today, not from this PRDocs: BerriAI/litellm-docs#1945