1"use strict";(globalThis.webpackChunkmy_website=globalThis.webpackChunkmy_website||[]).push([[1936],{75967(e,l,s){s.r(l),s.d(l,{assets:()=>o,contentTitle:()=>c,default:()=>g,frontMatter:()=>i,metadata:()=>n,toc:()=>a});let n=JSON.parse('{"id":"harness/deepagents","title":"Deep Agents","description":"Harness.DEEPAGENTS runs LangChain\'s Deep Agents in your Python process. It\'s the only harness here that\'s a Python library rather than a CLI, so there\'s no process to launch and nothing to install in the sandbox.","source":"@site/docs/harness/deepagents.md","sourceDirName":"harness","slug":"/harness/deepagents","permalink":"/docs/harness/deepagents","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Deep Agents","sidebar_label":"Deep Agents"},"sidebar":"tutorialSidebar","previous":{"title":"OpenCode","permalink":"/docs/harness/opencode"},"next":{"title":"Quickstart","permalink":"/docs/harness/quickstart"}}');var d=s(74848),t=s(28453);let i={title:"Deep Agents",sidebar_label:"Deep Agents",rawMarkdownB64:"LS0tCnRpdGxlOiBEZWVwIEFnZW50cwpzaWRlYmFyX2xhYmVsOiBEZWVwIEFnZW50cwotLS0KCiMgRGVlcCBBZ2VudHMKCmBIYXJuZXNzLkRFRVBBR0VOVFNgIHJ1bnMgTGFuZ0NoYWluJ3MgW0RlZXAgQWdlbnRzXShodHRwczovL2RvY3MubGFuZ2NoYWluLmNvbS9vc3MvcHl0aG9uL2RlZXBhZ2VudHMvb3ZlcnZpZXcpIGluIHlvdXIgUHl0aG9uIHByb2Nlc3MuIEl0J3MgdGhlIG9ubHkgaGFybmVzcyBoZXJlIHRoYXQncyBhIFB5dGhvbiBsaWJyYXJ5IHJhdGhlciB0aGFuIGEgQ0xJLCBzbyB0aGVyZSdzIG5vIHByb2Nlc3MgdG8gbGF1bmNoIGFuZCBub3RoaW5nIHRvIGluc3RhbGwgaW4gdGhlIHNhbmRib3guCgojIyBJbnN0YWxsCgpgYGBiYXNoCnBpcCBpbnN0YWxsIGxpdGVsbG0gZGVlcGFnZW50cyBsYW5nY2hhaW4tbGl0ZWxsbQpgYGAKCkRlZXAgQWdlbnRzIG5lZWRzIFB5dGhvbiAzLjExIG9yIG5ld2VyIGFuZCBkb2Vzbid0IG5lZWQgYHN0YXJsZXR0ZWAgb3IgYHV2aWNvcm5gLiBJZiBgZGVlcGFnZW50c2Agb3IgYGxhbmdjaGFpbi1saXRlbGxtYCBpcyBtaXNzaW5nLCB0aGUgY2FsbCByYWlzZXMgYEhhcm5lc3NJbnN0YWxsRmFpbGVkYCB3aXRoIHRoZSBpbnN0YWxsIGNvbW1hbmQuIHsvKiBrZWVwLXB5dGhvbi12ZXJzaW9uICovfQoKIyMgVXNhZ2UKCmBgYHB5dGhvbgppbXBvcnQgbGl0ZWxsbQpmcm9tIGxpdGVsbG0gaW1wb3J0IEhhcm5lc3MsIERlZXBBZ2VudHNPcHRpb25zLCBzYW5kYm94CgpkZWYgbG9va3VwX293bmVyKHBhdGg6IHN0cikgLT4gc3RyOgogICAgIiIiUmV0dXJuIHRoZSBDT0RFT1dORVJTIGVudHJ5IGZvciBhIGZpbGUgcGF0aC4iIiIKICAgIHJldHVybiBjb2Rlb3duZXJzLm1hdGNoKHBhdGgpCgpyZXN1bHQgPSBsaXRlbGxtLmFnZW50KAogICAgSGFybmVzcy5ERUVQQUdFTlRTLAogICAgIkZpbmQgdGhlIHRocmVlIGZsYWtpZXN0IHRlc3RzLCB3cml0ZSBOT1RFUy5tZCwgYW5kIG5hbW
1UgYW4gb3duZXIgZm9yIGVhY2guIiwKICAgIHNhbmRib3g9c2FuZGJveC5kb2NrZXIoInB5dGhvbjozLjEzIiwgbW91bnRzPXsiLi9yZXBvIjogIi93b3Jrc3BhY2UifSksCiAgICBtb2RlbD0ibGl0ZWxsbV9wcm94eS9jbGF1ZGUiLAogICAgdG9vbHM9W2xvb2t1cF9vd25lcl0sCiAgICBwZXJtaXNzaW9ucz0iZWRpdCIsCiAgICBvcHRpb25zPURlZXBBZ2VudHNPcHRpb25zKHJlY3Vyc2lvbl9saW1pdD0xMDApLAopCmBgYAoKIyMgVXNlIHdpdGggTGl0ZUxMTSBBSSBHYXRld2F5CgpEZWVwIEFnZW50cyB3b3JrcyB3aXRoIGFueSBtb2RlbCBncm91cCB0aGF0IHN1cHBvcnRzIHRvb2wgY2FsbGluZy4gQSBzdHJvbmcgbW9kZWwgcGF5cyBvZmYgZm9yIHRoZSBwbGFubmluZyBzdGVwLCBzbyBhIENsYXVkZSBvciBHUFQgZ3JvdXAgaXMgYSBnb29kIGRlZmF1bHQsIHdpdGggYSBjaGVhcGVyIGdyb3VwIGZvciBzdWJhZ2VudHMuCgpgYGB5YW1sIHRpdGxlPSJjb25maWcueWFtbCIKbW9kZWxfbGlzdDoKICAtIG1vZGVsX25hbWU6IGNsYXVkZQogICAgbGl0ZWxsbV9wYXJhbXM6CiAgICAgIG1vZGVsOiBhbnRocm9waWMvY2xhdWRlLXNvbm5ldC00LTUKICAgICAgYXBpX2tleTogb3MuZW52aXJvbi9BTlRIUk9QSUNfQVBJX0tFWQogIC0gbW9kZWxfbmFtZTogZ3B0LW1pbmkKICAgIGxpdGVsbG1fcGFyYW1zOgogICAgICBtb2RlbDogb3BlbmFpL2dwdC01LW1pbmkKICAgICAgYXBpX2tleTogb3MuZW52aXJvbi9PUEVOQUlfQVBJX0tFWQoKZ2VuZXJhbF9zZXR0aW5nczoKICBtYXN0ZXJfa2V5OiBvcy5lbnZpcm9uL0xJVEVMTE1fTUFTVEVSX0tFWQogIGRhdGFiYXNlX3VybDogb3MuZW52aXJvbi9EQVRBQkFTRV9VUkwKYGBgCgpDcmVhdGUgYSB2aXJ0dWFsIGtleSBzY29wZWQgdG8gdGhvc2UgZ3JvdXBzLgoKYGBgYmFzaApjdXJsIC1YIFBPU1QgaHR0cDovL2xvY2FsaG9zdDo0MDAwL2tleS9nZW5lcmF0ZSBcCiAgLUggIkF1dGhvcml6YXRpb246IEJlYXJlciAkTElURUxMTV9NQVNURVJfS0VZIiBcCiAgLUggIkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbiIgXAogIC1kICd7Im1vZGVscyI6IFsiY2xhdWRlIiwgImdwdC1taW5pIl0sICJrZXlfYWxpYXMiOiAiZGVlcGFnZW50cyJ9JwpgYGAKClRoZW4gcnVuIHdpdGggdGhlIGBsaXRlbGxtX3Byb3h5L2AgcHJlZml4LiBTZXQgdGhlIGdhdGV3YXkgaW4gdGhlIGVudmlyb25tZW50LCBvciBwYXNzIGl0IG9uIHRoZSBjYWxsLgoKYGBgcHl0aG9uCmltcG9ydCBsaXRlbGxtCmZyb20gbGl0ZWxsbSBpbXBvcnQgSGFybmVzcywgc2FuZGJveAoKcmVzdWx0ID0gbGl0ZWxsbS5hZ2VudCgKICAgIEhhcm5lc3MuREVFUEFHRU5UUywKICAgICJUcmlhZ2UgdGhlIGZhaWxpbmcgdGVzdCBhbmQgZmlsZSBhIHRpY2tldC4iLAogICAgc2FuZGJveD1zYW5kYm94LmxvY2FsKCIuL3JlcG8iKSwKICAgIG1vZGVsPSJsaXRlbGxtX3Byb3h5L2NsYXVkZSIsCiAgICBhcGlfYmFzZT0iaHR0cDovL2xvY2FsaG9zdDo0MDAwIiwgICMgb3IgTElURUxMTV9QUk9YWV9BUElfQkFTRQogICAgYXBpX2tleT0ic2stLi4uIiwgICAgICAgICAgICAgICAgICAjIG9yIExJVEVMTE1fUFJPWFlfQVBJX0tFWQogICAgdG9vbHM9W2xvb2t1cF9vd25lciwgb3Blbl90aWNrZXRdLAogICAgbWV0YWRhdGE9eyJ0aWNrZXQiOiAiRU5HLTQxMiJ9LAopCmBgYAoKRGVlcCBBZ2VudHMgY2FsbHMgYC92MS9jaGF0L2NvbXBsZXRpb25zYCB0aHJvdWdoIGEgYENoYXRMaXRlTExNYCBtb2RlbCB3aXRoIGBtb2RlbD0ibGl0ZWxsbV9wcm94eS9jbGF1ZGUiYC4gVGhlIGdhdGV3YXkgc2VlcyBlYWNoIHJlcXVlc3Qgd2l0aCBgbW9kZWxgIHNldCB0byBgY2xhdWRlYCwgdGhlIGhlYWRlciBgeC1saXRlbGxtLXRhZ3M6IGhhcm5lc3MsZGVlcGFnZW50c2AsIGFuZCB5b3VyIGBtZXRhZGF0YWAgYXMgYHgtbGl0ZWxsbS1zcGVuZC1sb2dzLW1ldGFkYXRhYCwgdGhlIHNhbWUgYXR0cmlidXRpb24gdGhlIENMSSBoYXJuZXNzZXMgZ2V0LgoKVW5saWtlIHRoZSBvdGhlciBoYXJuZXNzZXMsIERlZXAgQWdlbnRzIHJ1bnMgaW4geW91ciBQeXRob24gcHJvY2VzcyBhbmQgY2FsbHMgdGhlIGdhdGV3YXkgaXRzZWxmLiBUaGVyZSBpcyBubyBsb2NhbCBlbmRwb2ludCBhbmQgbm8gc2Vzc2lvbiB0b2tlbiwgc28gdGhlIHZpcnR1YWwga2V5IGxpdmVzIGluIHlvdXIgcHJvY2VzcywgYW5kIHlvdXIgcHJvY2VzcyBuZWVkcyBuZXR3b3JrIGFjY2VzcyB0byB0aGUgZ2F0ZXdheS4gSXRzIHBhY2thZ2VzLCBgcGlwIGluc3RhbGwgZGVlcGFnZW50cyBsYW5nY2hhaW4tbGl0ZWxsbWAsIGdvIG9uIHRoZSBtYWNoaW5lIHJ1bm5pbmcgeW91ciBjb2RlIHJhdGhlciB0aGFuIGluIHRoZSBzYW5kYm94LgoKIyMgT3B0aW9ucwoKYGBgcHl0aG9uCkBkYXRhY2xhc3MoZnJvemVuPVRydWUpCmNsYXNzIERlZXBBZ2VudHNPcHRpb25zOgogICAgc3ViYWdlbnRzOiBTZXF1ZW5jZVtTdWJBZ2VudF0gPSAoKSAgICMgZGVlcGFnZW50cyBTdWJBZ2VudCBkaWN0cywgcGFzc2VkIHRocm91Z2gKICAgIHJlY3Vyc2lvbl9saW1pdDogaW50IHwgTm9uZSA9IE5vbmUgICAjIExhbmdHcmFwaCByZWN1cnNpb24gbGltaXQgcGVyIHR1cm4KYGBgCgojIyBIb3cgaXQgbWFwcwoKVGhlIGFkYXB0ZXIgY2FsbHMgYGNyZWF0ZV9kZWVwX2FnZW50KClgIG9uY2UgcGVyIHNlc3Npb24uCgp8IGBsaXRlbGxtLmFnZW50KClgIHwgYGNyZWF0ZV9kZWVwX2FnZW50YCB8CnwtLS18LS0tfAp8IGBtb2RlbD0ibGl0ZWxsbV9wcm94eS9jbGF1ZGUiYCB8IGBtb2RlbD1DaGF0TGl0ZUxMTShtb2RlbD0ibGl0ZWxsbV9wcm94eS9jbGF1ZGUiLCBhcGlfYmFzZT0uLi4sIGFwaV9rZXk9Li4uKWAgfAp8IGBtb2RlbD0icHJvdmlkZXIvbW9kZWwiYCB8IGBtb2RlbD1DaGF0TGl0ZUxMTShtb2RlbD0icHJvdmlkZXIvbW9kZWwiKWAgfAp8IGBpbnN0cnVjdGlvbnM9YCB8IGBzeXN0ZW1fcHJvbXB0PWAgfAp8IGB0b29scz1gIHwgYHRvb2xzPWAgfAp8IGBvdXRwdXQ9YCB8IGByZXNwb25zZV9mb3JtYXQ9YCB8CnwgYHNhbmRib3g9YCB8IGBiYWNrZW5kPWAsIHdoaWNoIHJ1bnMgZmlsZSBhbmQgc2hlbGwgdG9vbHMgdGhyb3VnaCB0aGUgc2FuZGJveCB8Cnwgc2Vzc2lvbnMgfCBgY2hlY2twb2ludGVyPUluTWVtb3J5U2F2ZXIoKWAgd2l0aCBvbmUgdGhyZWFkIHBlciBzZXNzaW9uIHwKCiMjIE1vZGVscwoKVGhlIG1vZGVsIGlzIGEgYENoYXRMaXRlTExNYCBjaGF0IG1vZGVsLiBXaXRoIGEgYGxpdGVsbG1fcHJveHkvYCBtb2RlbCwgY2FsbHMgZ28gc3RyYWlnaHQgdG8gdGhlIGdhdGV3YXkgd2l0aCB5b3VyIHZpcnR1YWwga2V5IGFuZCBkb24ndCBuZWVkIHRoZSBsb2NhbCBlbmRwb2ludC4gQ29zdCBhbmQgdG9rZW5zIGNvbWUgZnJvbSBMYW5nQ2hhaW4ncyBgdXNhZ2VfbWV0YWRhdGFgLgoKIyMgU2FuZGJveAoKVGhlIGFnZW50IGxvb3AgcnVucyBpbiB5b3VyIHByb2Nlc3MsIGJ1dCBpdHMgZmlsZSB0b29scyBhbmQgaXRzIGBleGVjdXRlYCBzaGVsbCB0b29sIHJ1biBhZ2FpbnN0IHlvdXIgc2FuZGJveC4gV2l0aCBgc2FuZGJveC5sb2NhbChwYXRoKWAsIGZpbGUgYWNjZXNzIGlzIGxpbWl0ZWQgdG8gYHBhdGhgLgoKIyMgQnVpbHQtaW4gdG9vbHMKCmByZWFkX2ZpbGVgLCBgd3JpdG
1VfZmlsZWAsIGBlZGl0X2ZpbGVgLCBgbHNgLCBgZ2xvYmAsIGBncmVwYCBhbmQgYGV4ZWN1dGVgIGFwcGVhciBhcyBgcmVhZGAsIGB3cml0ZWAsIGBlZGl0YCwgYGxzYCwgYGdsb2JgLCBgZ3JlcGAgYW5kIGBiYXNoYC4gYHdyaXRlX3RvZG9zYCBhbmQgYHRhc2tgIGtlZXAgdGhlaXIgbmF0aXZlIG5hbWVzLiBgZGlzYWJsZV90b29scz1gIHJlbW92ZXMgdG9vbHMgYnkgdGhlaXIgbm9ybWFsaXplZCBuYW1lLgoKIyMgUGVybWlzc2lvbnMKCmAicmVhZC1vbmx5ImAsIGAiZWRpdCJgIGFuZCBgImZ1bGwiYCAodGhlIGRlZmF1bHQpIGFyZSBzdXBwb3J0ZWQuIGAicmVhZC1vbmx5ImAgcmVtb3ZlcyB0aGUgd3JpdGUsIGVkaXQgYW5kIGV4ZWN1dGUgdG9vbHMsIGFuZCBgImVkaXQiYCByZW1vdmVzIGBleGVjdXRlYC4KCiMjIFNlc3Npb25zIGFuZCBoaXN0b3J5CgpEZWVwIEFnZW50cyBpcyB0aGUgb25seSBoYXJuZXNzIHdpdGggY3VzdG9tIFB5dGhvbiB0b29scyBhbmQgaGlzdG9yeSBpbiB0aGlzIHJlbGVhc2UuIEEgc2Vzc2lvbiBrZWVwcyBhIExhbmdHcmFwaCBjaGVja3BvaW50ZXIgYW5kIGEgdGhyZWFkIGlkLCBhbmQgYHMuaGlzdG9yeSgpYCByZXR1cm5zIHRoZSB0aHJlYWQncyBtZXNzYWdlcyBpbiBPcGVuQUkgZm9ybWF0LgoKYGBgcHl0aG9uCndpdGggbGl0ZWxsbS5hZ2VudF9zZXNzaW9uKEhhcm5lc3MuREVFUEFHRU5UUywgc2FuZGJveD1ib3gsIG1vZGVsPSJsaXRlbGxtX3Byb3h5L2NsYXVkZSIpIGFzIHM6CiAgICBzLnJ1bigiUmVhZCB0aGUgUkVBRE1FIGFuZCBsaXN0IHRoZSBzZXR1cCBzdGVwcy4iKQogICAgcy5ydW4oIk5vdyBjaGVjayB3aGV0aGVyIHN0ZXAgMyBzdGlsbCB3b3Jrcy4iKQogICAgZm9yIG0gaW4gcy5oaXN0b3J5KCk6CiAgICAgICAgcHJpbnQobVsicm9sZSJdLCBtWyJjb250ZW50Il1bOjgwXSkKYGBgCg=="},c="Deep Agents",o={},a=[{value:"Install",id:"install",level:2},{value:"Usage",id:"usage",level:2},{value:"Use with LiteLLM AI Gateway",id:"use-with-litellm-ai-gateway",level:2},{value:"Options",id:"options",level:2},{value:"How it maps",id:"how-it-maps",level:2},{value:"Models",id:"models",level:2},{value:"Sandbox",id:"sandbox",level:2},{value:"Built-in tools",id:"built-in-tools",level:2},{value:"Permissions",id:"permissions",level:2},{value:"Sessions and history",id:"sessions-and-history",level:2}];function h(e){let l={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(l.header,{children:(0,d.jsx)(l.h1,{id:"deep-agents",children:"Deep Agents"})}),"\n",(0,d.jsxs)(l.p,{children:[(0,d.jsx)(l.code,{children:"Harness.DEEPAGENTS"})," runs LangChain's ",(0,d.jsx)(l.a,{href:"https://docs.langchain.com/oss/python/deepagents/overview",children:"Deep Agents"})," in your Python process. It's the only harness here that's a Python library rather than a CLI, so there's no process to launch and nothing to install in the sandbox."]}),"\n",(0,d.jsx)(l.h2,{id:"install",children:"Install"}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-bash",children:"pip install litellm deepagents langchain-litellm\n"})}),"\n",(0,d.jsxs)(l.p,{children:["Deep Agents needs Python 3.11 or newer and doesn't need ",(0,d.jsx)(l.code,{children:"starlette"})," or ",(0,d.jsx)(l.code,{children:"uvicorn"}),". If ",(0,d.jsx)(l.code,{children:"deepagents"})," or ",(0,d.jsx)(l.code,{children:"langchain-litellm"})," is missing, the call raises ",(0,d.jsx)(l.code,{children:"HarnessInstallFailed"})," with the install command. "]}),"\n",(0,d.jsx)(l.h2,{id:"usage",children:"Usage"}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-python",children:'import litellm\nfrom litellm import Harness, DeepAgentsOptions, sandbox\n\ndef lookup_owner(path: str) -> str:\n """Return the CODEOWNERS entry for a file path."""\n return codeowners.match(path)\n\nresult = litellm.agent(\n Harness.DEEPAGENTS,\n "Find the three flakiest tests, write NOTES.md, and name an owner for each.",\n sandbox=sandbox.docker("python:3.13", mounts={"./repo": "/workspace"}),\n model="litellm_proxy/claude",\n tools=[lookup_owner],\n permissions="edit",\n options=DeepAgentsOptions(recursion_limit=100),\n)\n'})}),"\n",(0,d.jsx)(l.h2,{id:"use-with-litellm-ai-gateway",children:"Use with LiteLLM AI Gateway"}),"\n",(0,d.jsx)(l.p,{children:"Deep Agents works with any model group that supports tool calling. A strong model pays off for the planning step, so a Claude or GPT group is a good default, with a cheaper group for subagents."}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-yaml",metastring:'title="config.yaml"',children:"model_list:\n - model_name: claude\n litellm_params:\n model: anthropic/claude-sonnet-4-5\n api_key: os.environ/ANTHROPIC_API_KEY\n - model_name: gpt-mini\n litellm_params:\n model: openai/gpt-5-mini\n api_key: os.environ/OPENAI_API_KEY\n\ngeneral_settings:\n master_key: os.environ/LITELLM_MASTER_KEY\n database_url: os.environ/DATABASE_URL\n"})}),"\n",(0,d.jsx)(l.p,{children:"Create a virtual key scoped to those groups."}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-bash",children:'curl -X POST http://localhost:4000/key/generate \\\n -H "Authorization: Bearer $LITELLM_MASTER_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{"models": ["claude", "gpt-mini"], "key_alias": "deepagents"}\'\n'})}),"\n",(0,d.jsxs)(l.p,{children:["Then run with the ",(0,d.jsx)(l.code,{children:"litellm_proxy/"})," prefix. Set the gateway in the environment, or pass it on the call."]}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-python",children:'import litellm\nfrom litellm import Harness, sandbox\n\nresult = litellm.agent(\n Harness.DEEPAGENTS,\n "Triage the failing test and file a t
1icket.",\n sandbox=sandbox.local("./repo"),\n model="litellm_proxy/claude",\n api_base="http://localhost:4000", # or LITELLM_PROXY_API_BASE\n api_key="sk-...", # or LITELLM_PROXY_API_KEY\n tools=[lookup_owner, open_ticket],\n metadata={"ticket": "ENG-412"},\n)\n'})}),"\n",(0,d.jsxs)(l.p,{children:["Deep Agents calls ",(0,d.jsx)(l.code,{children:"/v1/chat/completions"})," through a ",(0,d.jsx)(l.code,{children:"ChatLiteLLM"})," model with ",(0,d.jsx)(l.code,{children:'model="litellm_proxy/claude"'}),". The gateway sees each request with ",(0,d.jsx)(l.code,{children:"model"})," set to ",(0,d.jsx)(l.code,{children:"claude"}),", the header ",(0,d.jsx)(l.code,{children:"x-litellm-tags: harness,deepagents"}),", and your ",(0,d.jsx)(l.code,{children:"metadata"})," as ",(0,d.jsx)(l.code,{children:"x-litellm-spend-logs-metadata"}),", the same attribution the CLI harnesses get."]}),"\n",(0,d.jsxs)(l.p,{children:["Unlike the other harnesses, Deep Agents runs in your Python process and calls the gateway itself. There is no local endpoint and no session token, so the virtual key lives in your process, and your process needs network access to the gateway. Its packages, ",(0,d.jsx)(l.code,{children:"pip install deepagents langchain-litellm"}),", go on the machine running your code rather than in the sandbox."]}),"\n",(0,d.jsx)(l.h2,{id:"options",children:"Options"}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-python",children:"@dataclass(frozen=True)\nclass DeepAgentsOptions:\n subagents: Sequence[SubAgent] = () # deepagents SubAgent dicts, passed through\n recursion_limit: int | None = None # LangGraph recursion limit per turn\n"})}),"\n",(0,d.jsx)(l.h2,{id:"how-it-maps",children:"How it maps"}),"\n",(0,d.jsxs)(l.p,{children:["The adapter calls ",(0,d.jsx)(l.code,{children:"create_deep_agent()"})," once per session."]}),"\n",(0,d.jsxs)(l.table,{children:[(0,d.jsx)(l.thead,{children:(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.th,{children:(0,d.jsx)(l.code,{children:"litellm.agent()"})}),(0,d.jsx)(l.th,{children:(0,d.jsx)(l.code,{children:"create_deep_agent"})})]})}),(0,d.jsxs)(l.tbody,{children:[(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:'model="litellm_proxy/claude"'})}),(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:'model=ChatLiteLLM(model="litellm_proxy/claude", api_base=..., api_key=...)'})})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:'model="provider/model"'})}),(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:'model=ChatLiteLLM(model="provider/model")'})})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"instructions="})}),(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"system_prompt="})})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"tools="})}),(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"tools="})})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"output="})}),(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"response_format="})})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:(0,d.jsx)(l.code,{children:"sandbox="})}),(0,d.jsxs)(l.td,{children:[(0,d.jsx)(l.code,{children:"backend="}),", which runs file and shell tools through the sandbox"]})]}),(0,d.jsxs)(l.tr,{children:[(0,d.jsx)(l.td,{children:"sessions"}),(0,d.jsxs)(l.td,{children:[(0,d.jsx)(l.code,{children:"checkpointer=InMemorySaver()"})," with one thread per session"]})]})]})]}),"\n",(0,d.jsx)(l.h2,{id:"models",children:"Models"}),"\n",(0,d.jsxs)(l.p,{children:["The model is a ",(0,d.jsx)(l.code,{children:"ChatLiteLLM"})," chat model. With a ",(0,d.jsx)(l.code,{children:"litellm_proxy/"})," model, calls go straight to the gateway with your virtual key and don't need the local endpoint. Cost and tokens come from LangChain's ",(0,d.jsx)(l.code,{children:"usage_metadata"}),"."]}),"\n",(0,d.jsx)(l.h2,{id:"sandbox",children:"Sandbox"}),"\n",(0,d.jsxs)(l.p,{children:["The agent loop runs in your process, but its f
1ile tools and its ",(0,d.jsx)(l.code,{children:"execute"})," shell tool run against your sandbox. With ",(0,d.jsx)(l.code,{children:"sandbox.local(path)"}),", file access is limited to ",(0,d.jsx)(l.code,{children:"path"}),"."]}),"\n",(0,d.jsx)(l.h2,{id:"built-in-tools",children:"Built-in tools"}),"\n",(0,d.jsxs)(l.p,{children:[(0,d.jsx)(l.code,{children:"read_file"}),", ",(0,d.jsx)(l.code,{children:"write_file"}),", ",(0,d.jsx)(l.code,{children:"edit_file"}),", ",(0,d.jsx)(l.code,{children:"ls"}),", ",(0,d.jsx)(l.code,{children:"glob"}),", ",(0,d.jsx)(l.code,{children:"grep"})," and ",(0,d.jsx)(l.code,{children:"execute"})," appear as ",(0,d.jsx)(l.code,{children:"read"}),", ",(0,d.jsx)(l.code,{children:"write"}),", ",(0,d.jsx)(l.code,{children:"edit"}),", ",(0,d.jsx)(l.code,{children:"ls"}),", ",(0,d.jsx)(l.code,{children:"glob"}),", ",(0,d.jsx)(l.code,{children:"grep"})," and ",(0,d.jsx)(l.code,{children:"bash"}),". ",(0,d.jsx)(l.code,{children:"write_todos"})," and ",(0,d.jsx)(l.code,{children:"task"})," keep their native names. ",(0,d.jsx)(l.code,{children:"disable_tools="})," removes tools by their normalized name."]}),"\n",(0,d.jsx)(l.h2,{id:"permissions",children:"Permissions"}),"\n",(0,d.jsxs)(l.p,{children:[(0,d.jsx)(l.code,{children:'"read-only"'}),", ",(0,d.jsx)(l.code,{children:'"edit"'})," and ",(0,d.jsx)(l.code,{children:'"full"'})," (the default) are supported. ",(0,d.jsx)(l.code,{children:'"read-only"'})," removes the write, edit and execute tools, and ",(0,d.jsx)(l.code,{children:'"edit"'})," removes ",(0,d.jsx)(l.code,{children:"execute"}),"."]}),"\n",(0,d.jsx)(l.h2,{id:"sessions-and-history",children:"Sessions and history"}),"\n",(0,d.jsxs)(l.p,{children:["Deep Agents is the only harness with custom Python tools and history in this release. A session keeps a LangGraph checkpointer and a thread id, and ",(0,d.jsx)(l.code,{children:"s.history()"})," returns the thread's messages in OpenAI format."]}),"\n",(0,d.jsx)(l.pre,{children:(0,d.jsx)(l.code,{className:"language-python",children:'with litellm.agent_session(Harness.DEEPAGENTS, sandbox=box, model="litellm_proxy/claude") as s:\n s.run("Read the README and list the setup steps.")\n s.run("Now check whether step 3 still works.")\n for m in s.history():\n print(m["role"], m["content"][:80])\n'})})]})}function g(e={}){let{wrapper:l}={...(0,t.R)(),...e.components};return l?(0,d.jsx)(l,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453(e,l,s){s.d(l,{R:()=>i,x:()=>c});var n=s(96540);let d={},t=n.createContext(d);function i(e){let l=n.useContext(t);return n.useMemo(function(){return"function"==typeof e?e(l):{...l,...e}},[l,e])}function c(e){let l;return l=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:i(e.components),n.createElement(t.Provider,{value:l},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.