Skip to content

Commit fa27d43

Browse files
authored
feat(managed_agents): add Claude Managed Agents cookbooks (#508)
* feat(managed_agents): add Claude Managed Agents cookbooks Adds the managed_agents/ directory with 9 notebooks covering the Claude Managed Agents API, ported from cookbooks-private PRs #41, #43, #49, #52. Applied cookbooks: - data_analyst_agent.ipynb (charmaine, jyan-anthropic) - slack_data_bot.ipynb (charmaine) - sre_incident_responder.ipynb (gaganb-ant) Guided tutorials (CMA_*): - iterate_fix_failing_tests (pauly-ant) — entry-point walkthrough - orchestrate_issue_to_pr (pauly-ant) — multi-turn issue-to-PR flow - explore_unfamiliar_codebase (pauly-ant) — grounding in a codebase - gate_human_in_the_loop (pauly-ant) — custom-tool HITL approval - prompt_versioning_and_rollback (markn-ant) — server-side prompt versioning - operate_in_production (pauly-ant) — vaults, MCP, status_idled webhooks Includes example_data/ fixtures, a managed_agents/pyproject.toml pinning anthropic>=0.91.0, shared utilities.py, plus registry.yaml and authors.yaml entries for the 6 registered notebooks. * Update registry.yaml
1 parent 89e3293 commit fa27d43

40 files changed

Lines changed: 4889 additions & 0 deletions

authors.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,17 @@ benlehrburger-ant:
2121
Briiick:
2222
name: Alexander Bricken
2323
avatar: https://avatars.githubusercontent.com/u/44481408?v=4
24+
charmaine:
25+
name: Charmaine Lee
26+
website: https://github.com/charmaine
27+
avatar: https://avatars.githubusercontent.com/u/16736130?v=4
2428
davidhershey:
2529
name: David Hershey
2630
website: https://github.com/davidhershey
2731
avatar: https://avatars.githubusercontent.com/u/11651858?v=4
32+
gaganb-ant:
33+
name: Gagan Bhat
34+
avatar: https://avatars.githubusercontent.com/u/235440171?v=4
2835
GarvanD:
2936
name: Garvan Doyle
3037
website: https://garvandoyle.com
@@ -55,13 +62,25 @@ jsham042:
5562
name: Joe Shamon
5663
website: https://github.com/jsham042
5764
avatar: https://github.com/jsham042.png
65+
jyan-anthropic:
66+
name: Jess Yan
67+
website: https://github.com/jyan-anthropic
68+
avatar: https://avatars.githubusercontent.com/u/235391680?v=4
5869
maheshmurag:
5970
name: Mahesh Murag
6071
website: https://github.com/maheshmurag
6172
avatar: https://avatars.githubusercontent.com/u/5667029?v=4
73+
markn-ant:
74+
name: Mark Nowicki
75+
website: https://github.com/markn-ant
76+
avatar: https://avatars.githubusercontent.com/markn-ant
6277
nadine-anthropic:
6378
name: Nadine Yasser
6479
avatar: https://avatars.githubusercontent.com/u/238355370?v=4
80+
pauly-ant:
81+
name: Paul Yang
82+
website: https://github.com/pauly-ant
83+
avatar: https://avatars.githubusercontent.com/u/269031447?v=4
6584
PedramNavid:
6685
name: Pedram Navid
6786
website: http://x.com/pdrmnvd

managed_agents/.env.example

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
ANTHROPIC_API_KEY=sk-ant-...
2+
3+
# Populated from data_analyst_agent.ipynb output; consumed by slack_data_bot.ipynb
4+
ANALYST_ENV_ID=env_...
5+
ANALYST_AGENT_ID=agent_...
6+
ANALYST_AGENT_VERSION=...
7+
8+
# For slack_data_bot.ipynb
9+
SLACK_BOT_TOKEN=xoxb-...
10+
SLACK_APP_TOKEN=xapp-...
11+
12+
# Required for the GitHub MCP sidebar in CMA_orchestrate_issue_to_pr.ipynb
13+
# and the vault-backed MCP credentials in CMA_operate_in_production.ipynb
14+
GITHUB_TOKEN=ghp_...
15+
16+
# Optional — override the default model used by the CMA_ tutorials
17+
COOKBOOK_MODEL=claude-sonnet-4-6
18+
19+
# For sre_incident_responder.ipynb (production wiring only)
20+
DD_API_KEY=
21+
DD_APP_KEY=

managed_agents/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
report.html
2+
__pycache__/
3+
*.pyc
4+
.env
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "1ff5d825",
6+
"metadata": {},
7+
"source": [
8+
"# Explore: grounding in an unfamiliar codebase\n",
9+
"\n",
10+
"This notebook drops the agent into a repository it's never seen\n",
11+
"before and asks it to figure out the real architecture. The\n",
12+
"filesystem is the agent's only workspace, and only the files it\n",
13+
"chooses to read end up in its context window, so exploration with\n",
14+
"`ls`, `grep`, and `read` is how it builds up a mental model.\n",
15+
"\n",
16+
"The interesting part is a trap we've planted in the fixture.\n",
17+
"`ARCHITECTURE.md` describes a layout that the code no longer\n",
18+
"follows, so an agent that trusts the docs without checking the\n",
19+
"code will confidently give the wrong answer. Grounding, in this\n",
20+
"context, means verifying what you read against what's actually\n",
21+
"there rather than treating documentation as authoritative.\n",
22+
"\n",
23+
"What this teaches beyond the iterate notebook:\n",
24+
"\n",
25+
"- **Exploration before action.** A good agent reads enough of the\n",
26+
" tree to understand it, then answers, not the other way around.\n",
27+
"- **Adding resources mid-session.** The sidebar at the end shows\n",
28+
" how to push more files into a running session via\n",
29+
" `sessions.resources.add` rather than re-creating the session.\n",
30+
" Useful when exploration uncovers something the agent should\n",
31+
" look at next."
32+
]
33+
},
34+
{
35+
"cell_type": "code",
36+
"execution_count": null,
37+
"id": "b36209d4",
38+
"metadata": {},
39+
"outputs": [],
40+
"source": [
41+
"import io\n",
42+
"import os\n",
43+
"\n",
44+
"from anthropic import Anthropic\n",
45+
"from utilities import (\n",
46+
" make_unfamiliar_repo_zip,\n",
47+
" stream_until_end_turn,\n",
48+
" wait_for_idle_status,\n",
49+
")\n",
50+
"\n",
51+
"MODEL = os.environ.get(\"COOKBOOK_MODEL\", \"claude-sonnet-4-6\")\n",
52+
"\n",
53+
"client = Anthropic()"
54+
]
55+
},
56+
{
57+
"cell_type": "markdown",
58+
"id": "98ab21e5",
59+
"metadata": {},
60+
"source": [
61+
"## 1. Generate the repo fixture\n",
62+
"\n",
63+
"The repo is small enough that we build it in memory with a helper\n",
64+
"rather than keeping a disk fixture alongside the notebook. The\n",
65+
"helper plants a `services/` microservices layout and a stale\n",
66+
"`ARCHITECTURE.md` that still describes the old monolithic layout."
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": null,
72+
"id": "108bd220",
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"buf = make_unfamiliar_repo_zip()\n",
77+
"fixture_zip = client.beta.files.upload(file=(\"repo.zip\", buf, \"application/zip\"))\n",
78+
"print(f\"fixture: {fixture_zip.id}\")"
79+
]
80+
},
81+
{
82+
"cell_type": "markdown",
83+
"id": "1c2ba40f",
84+
"metadata": {},
85+
"source": [
86+
"## 2. Agent + environment + session"
87+
]
88+
},
89+
{
90+
"cell_type": "code",
91+
"execution_count": null,
92+
"id": "faf4808b",
93+
"metadata": {},
94+
"outputs": [],
95+
"source": [
96+
"agent = client.beta.agents.create(\n",
97+
" name=\"cookbook-explore\",\n",
98+
" model=MODEL,\n",
99+
" system=(\n",
100+
" \"You are onboarding to an unfamiliar codebase. Explore before \"\n",
101+
" \"answering, docs can be stale. Verify what you read against \"\n",
102+
" \"actual code structure. Write notes to /tmp/NOTES.md as you go.\"\n",
103+
" ),\n",
104+
" tools=[\n",
105+
" {\n",
106+
" \"type\": \"agent_toolset_20260401\",\n",
107+
" \"default_config\": {\n",
108+
" \"enabled\": True,\n",
109+
" \"permission_policy\": {\"type\": \"always_allow\"},\n",
110+
" },\n",
111+
" }\n",
112+
" ],\n",
113+
")\n",
114+
"\n",
115+
"env = client.beta.environments.create(\n",
116+
" name=\"cookbook-explore-env\",\n",
117+
" config={\"type\": \"cloud\", \"networking\": {\"type\": \"limited\"}},\n",
118+
")\n",
119+
"\n",
120+
"session = client.beta.sessions.create(\n",
121+
" environment_id=env.id,\n",
122+
" agent={\"type\": \"agent\", \"id\": agent.id, \"version\": agent.version},\n",
123+
" resources=[{\"type\": \"file\", \"file_id\": fixture_zip.id, \"mount_path\": \"repo.zip\"}],\n",
124+
" title=\"Onboard to repo\",\n",
125+
")\n",
126+
"print(f\"session: {session.id}\")"
127+
]
128+
},
129+
{
130+
"cell_type": "markdown",
131+
"id": "2710d8a0",
132+
"metadata": {},
133+
"source": [
134+
"## 3. Explore and watch for the stale-doc trap\n",
135+
"\n",
136+
"A grounded answer mentions the real `services/` layout and flags\n",
137+
"`ARCHITECTURE.md` as out of date. An ungrounded answer parrots\n",
138+
"the monolith layout the stale doc describes."
139+
]
140+
},
141+
{
142+
"cell_type": "code",
143+
"execution_count": null,
144+
"id": "a8acee26",
145+
"metadata": {},
146+
"outputs": [],
147+
"source": [
148+
"client.beta.sessions.events.send(\n",
149+
" session_id=session.id,\n",
150+
" events=[\n",
151+
" {\n",
152+
" \"type\": \"user.message\",\n",
153+
" \"content\": [\n",
154+
" {\n",
155+
" \"type\": \"text\",\n",
156+
" \"text\": (\n",
157+
" \"Unzip /mnt/session/uploads/repo.zip to /tmp/repo/. \"\n",
158+
" \"Then: what is the actual architecture of this \"\n",
159+
" \"codebase? Be specific about directory structure. \"\n",
160+
" \"Check if the docs are accurate.\"\n",
161+
" ),\n",
162+
" }\n",
163+
" ],\n",
164+
" }\n",
165+
" ],\n",
166+
")\n",
167+
"\n",
168+
"print(\"=== exploration ===\")\n",
169+
"stream_until_end_turn(client, session.id)"
170+
]
171+
},
172+
{
173+
"cell_type": "markdown",
174+
"id": "28aea9a1",
175+
"metadata": {},
176+
"source": [
177+
"## 4. Read back the agent's notes\n",
178+
"\n",
179+
"The agent was told to keep notes in `/tmp/NOTES.md` as it worked.\n",
180+
"Printing that file is a useful way to see how its understanding\n",
181+
"of the codebase developed during exploration."
182+
]
183+
},
184+
{
185+
"cell_type": "code",
186+
"execution_count": null,
187+
"id": "90943a95",
188+
"metadata": {},
189+
"outputs": [],
190+
"source": [
191+
"client.beta.sessions.events.send(\n",
192+
" session_id=session.id,\n",
193+
" events=[\n",
194+
" {\n",
195+
" \"type\": \"user.message\",\n",
196+
" \"content\": [{\"type\": \"text\", \"text\": \"cat /tmp/NOTES.md\"}],\n",
197+
" }\n",
198+
" ],\n",
199+
")\n",
200+
"stream_until_end_turn(client, session.id)"
201+
]
202+
},
203+
{
204+
"cell_type": "markdown",
205+
"id": "31d28889",
206+
"metadata": {},
207+
"source": [
208+
"## Sidebar: adding more context to a running session\n",
209+
"\n",
210+
"The `resources=` argument on `sessions.create` is the most common\n",
211+
"way to mount files, but the API also exposes a\n",
212+
"`/v1/sessions/<id>/resources` sub-resource for managing mounts on\n",
213+
"an existing session. This is useful here: if exploration uncovers\n",
214+
"a question that needs additional context (a config file, a\n",
215+
"changelog, an external schema), you can drop it in without\n",
216+
"tearing down the session.\n",
217+
"\n",
218+
"The pattern is the same upload-then-attach loop you already know,\n",
219+
"just split across two calls instead of one:"
220+
]
221+
},
222+
{
223+
"cell_type": "code",
224+
"execution_count": null,
225+
"id": "eeec2815",
226+
"metadata": {},
227+
"outputs": [],
228+
"source": [
229+
"hints = b\"# DEPLOY HISTORY\\n2026-03-01: monolith -> microservices migration complete\\n\"\n",
230+
"hints_file = client.beta.files.upload(\n",
231+
" file=(\"DEPLOY_HISTORY.md\", io.BytesIO(hints), \"text/markdown\")\n",
232+
")\n",
233+
"\n",
234+
"added = client.beta.sessions.resources.add(\n",
235+
" session_id=session.id,\n",
236+
" type=\"file\",\n",
237+
" file_id=hints_file.id,\n",
238+
" mount_path=\"DEPLOY_HISTORY.md\",\n",
239+
")\n",
240+
"print(f\"added resource {added.id} to session {session.id}\")\n",
241+
"\n",
242+
"attached = client.beta.sessions.resources.list(session_id=session.id)\n",
243+
"print(f\"{len(attached.data)} resources attached now\")\n",
244+
"\n",
245+
"client.beta.sessions.events.send(\n",
246+
" session_id=session.id,\n",
247+
" events=[\n",
248+
" {\n",
249+
" \"type\": \"user.message\",\n",
250+
" \"content\": [\n",
251+
" {\n",
252+
" \"type\": \"text\",\n",
253+
" \"text\": (\n",
254+
" \"There's a DEPLOY_HISTORY.md in your workspace now. \"\n",
255+
" \"Read it and tell me whether it changes anything in \"\n",
256+
" \"your earlier answer.\"\n",
257+
" ),\n",
258+
" }\n",
259+
" ],\n",
260+
" }\n",
261+
" ],\n",
262+
")\n",
263+
"print(\"\\n--- follow-up with deploy history ---\")\n",
264+
"stream_until_end_turn(client, session.id)\n",
265+
"\n",
266+
"# Detach the file now that the agent is done with it. `delete` here\n",
267+
"# is the resource-detach verb, not the cookbook-wide archive.\n",
268+
"client.beta.sessions.resources.delete(session_id=session.id, resource_id=added.id)\n",
269+
"print(\"detached follow-up resource\")"
270+
]
271+
},
272+
{
273+
"cell_type": "markdown",
274+
"id": "50363d78",
275+
"metadata": {},
276+
"source": [
277+
"## Cleanup"
278+
]
279+
},
280+
{
281+
"cell_type": "code",
282+
"execution_count": null,
283+
"id": "358e0a02",
284+
"metadata": {},
285+
"outputs": [],
286+
"source": [
287+
"wait_for_idle_status(client, session.id)\n",
288+
"client.beta.sessions.archive(session.id)\n",
289+
"client.beta.environments.archive(env.id)\n",
290+
"client.beta.agents.archive(agent.id)\n",
291+
"print(\"archived\")"
292+
]
293+
}
294+
],
295+
"metadata": {
296+
"jupytext": {
297+
"cell_metadata_filter": "-all",
298+
"main_language": "python",
299+
"notebook_metadata_filter": "-all"
300+
}
301+
},
302+
"nbformat": 4,
303+
"nbformat_minor": 5
304+
}

0 commit comments

Comments
 (0)