Skip to content

Commit cb3ea50

Browse files
update sdk cookbooks to v0.1.6
- bump sdk from v0.0.20 to v0.1.6 - modernize code with sdk type abstractions - add session management and tool filtering - expand notebook 01 with more features - improve narrative flow and explanations - add utils for report tracking
1 parent fe63970 commit cb3ea50

File tree

12 files changed

+2143
-1770
lines changed

12 files changed

+2143
-1770
lines changed

claude_agent_sdk/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ uv.lock
2323
*.ipynb_checkpoints/
2424

2525
# macOS
26-
.DS_Store
26+
.DS_Store

claude_agent_sdk/00_The_one_liner_research_agent.ipynb

Lines changed: 287 additions & 607 deletions
Large diffs are not rendered by default.

claude_agent_sdk/01_The_chief_of_staff_agent.ipynb

Lines changed: 1066 additions & 668 deletions
Large diffs are not rendered by default.

claude_agent_sdk/02_The_observability_agent.ipynb

Lines changed: 636 additions & 447 deletions
Large diffs are not rendered by default.

claude_agent_sdk/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A tutorial series demonstrating how to build sophisticated general-purpose agentic systems using the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-python), progressing from simple research agents to multi-agent orchestration with external system integration.
44

5+
> **📌 Updated for SDK v0.1.6**: These notebooks use the latest Claude Agent SDK v0.1.6 features. Requires Claude Code 2.0.0+. See the [migration guide](https://docs.claude.com/en/api/agent-sdk/migrate-to-claude-agent-sdk) for details if you started developing with the Claude Code SDK.
6+
57
## Getting Started
68

79
#### 1. Install uv, [node](https://nodejs.org/en/download/), and the Claude Code CLI (if you haven't already)
@@ -42,11 +44,12 @@ This tutorial series takes you on a journey from basic agent implementation to s
4244
### What You'll Learn
4345

4446
Through this series, you'll be exposed to:
45-
- **Core SDK fundamentals** with `query()` and the `ClaudeSDKClient` & `ClaudeAgentOptions` interfaces in the Python SDK
47+
- **Core Claude Agent SDK fundamentals** with `query()` and the `ClaudeSDKClient` & `ClaudeAgentOptions` interfaces in the Python SDK
4648
- **Tool usage patterns** from basic WebSearch to complex MCP server integration
4749
- **Multi-agent orchestration** with specialized subagents and coordination
4850
- **Enterprise features** by leveraging hooks for compliance tracking and audit trails
4951
- **External system integration** via Model Context Protocol (MCP)
52+
- **Custom tool creation** with in-process SDK MCP servers
5053

5154
Note: This tutorial assumes you have some level of familiarity with Claude Code. Ideally, if you have been using Claude Code to supercharge your coding tasks and would like to leverage its raw agentic power for tasks beyond Software Engineering, this tutorial will help you get started.
5255

@@ -72,20 +75,21 @@ Build a comprehensive AI Chief of Staff for a startup CEO, showcasing advanced S
7275
- **Output Styles:** Tailored communication for different audiences
7376
- **Plan Mode:** Strategic planning without execution for complex tasks
7477
- **Custom Slash Commands:** User-friendly shortcuts for common operations
75-
- **Hooks:** Automated compliance tracking and audit trails
76-
- **Subagent Orchestration:** Coordinating specialized agents for domain expertise
78+
- **Hooks:** Automated compliance tracking and audit trails (PreToolUse & PostToolUse). Defined programmatically or via filesystem.
79+
- **Subagent Orchestration:** Coordinating specialized agents for domain expertise. Defined programmatically or via filesystem.
7780
- **Bash Tool Integration:** Python script execution for procedural knowledge and complex computations
81+
- **System Prompt Patterns:** Append to presets and custom replacements.
82+
- **Session Management:** Resume and fork conversations with session IDs for multi-day workflows
7883

7984
### [Notebook 02: The Observability Agent](02_The_observability_agent.ipynb)
8085

8186
Expand beyond local capabilities by connecting agents to external systems through the Model Context Protocol. Transform your agent from a passive observer into an active participant in DevOps workflows.
8287

83-
**Advanced Capabilities:**
88+
**Integration:**
8489
- **Git MCP Server:** 13+ tools for repository analysis and version control
8590
- **GitHub MCP Server:** 100+ tools for complete GitHub platform integration
91+
- **SDK MCP Servers:** Create custom in-process tools with `create_sdk_mcp_server()` and `@tool` decorator
8692
- **Real-time Monitoring:** CI/CD pipeline analysis and failure detection
87-
- **Intelligent Incident Response:** Automated root cause analysis
88-
- **Production Workflow Automation:** From monitoring to actionable insights
8993

9094
## Complete Agent Implementations
9195

claude_agent_sdk/chief_of_staff_agent/.claude/settings.local.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"hooks": [
3030
{
3131
"type": "command",
32-
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/report-tracker.py123"
32+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/report-tracker.py"
3333
}
3434
]
3535
}

claude_agent_sdk/chief_of_staff_agent/agent.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@
1010

1111
from dotenv import load_dotenv
1212

13-
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
13+
from claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, ClaudeSDKClient, ResultMessage, UserMessage
1414

1515
load_dotenv()
1616

1717

1818
def get_activity_text(msg) -> str | None:
1919
"""Extract activity text from a message"""
2020
try:
21-
if "Assistant" in msg.__class__.__name__:
21+
if isinstance(msg, AssistantMessage):
2222
if hasattr(msg, "content") and msg.content:
2323
first_content = msg.content[0] if isinstance(msg.content, list) else msg.content
2424
if hasattr(first_content, "name"):
2525
return f"🤖 Using: {first_content.name}()"
2626
return "🤖 Thinking..."
27-
elif "User" in msg.__class__.__name__:
27+
elif isinstance(msg, UserMessage):
2828
return "✓ Tool completed"
2929
except (AttributeError, IndexError):
3030
pass
@@ -44,6 +44,8 @@ async def send_query(
4444
permission_mode: Literal["default", "plan", "acceptEdits"] = "default",
4545
output_style: str | None = None,
4646
activity_handler: Callable[[Any], None | Any] = print_activity,
47+
resume: str | None = None,
48+
fork_session: bool = False,
4749
) -> tuple[str | None, list]:
4850
"""
4951
Send a query to the Chief of Staff agent with all features integrated.
@@ -54,6 +56,8 @@ async def send_query(
5456
continue_conversation: Continue the previous conversation if True
5557
permission_mode: "default" (execute), "plan" (think only), or "acceptEdits"
5658
output_style: Override output style (e.g., "executive", "technical", "board-report")
59+
resume: Session ID to resume (Feature 8: Session Management)
60+
fork_session: If True with resume, creates branch; if False, continues same session
5761
5862
Returns:
5963
Tuple of (result, messages) - result is the final text, messages is the full conversation
@@ -88,12 +92,19 @@ async def send_query(
8892
"Bash",
8993
"WebSearch",
9094
],
95+
"disallowed_tools": ["WebFetch"],
9196
"continue_conversation": continue_conversation,
9297
"system_prompt": system_prompt,
9398
"permission_mode": permission_mode,
9499
"cwd": os.path.dirname(os.path.abspath(__file__)),
100+
"setting_sources": ["project", "local"],
95101
}
96102

103+
# Add session management parameters if provided (Feature 8)
104+
if resume:
105+
options_dict["resume"] = resume
106+
options_dict["fork_session"] = fork_session
107+
97108
# add output style if specified
98109
if output_style:
99110
options_dict["settings"] = json.dumps({"outputStyle": output_style})
@@ -113,7 +124,7 @@ async def send_query(
113124
else:
114125
activity_handler(msg)
115126

116-
if hasattr(msg, "result"):
127+
if isinstance(msg, ResultMessage):
117128
result = msg.result
118129
except Exception as e:
119130
print(f"❌ Query error: {e}")

claude_agent_sdk/observability_agent/agent.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@
1010

1111
from dotenv import load_dotenv
1212

13-
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
13+
from claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, ClaudeSDKClient, ResultMessage, UserMessage
1414

1515
load_dotenv()
1616

1717

1818
def get_activity_text(msg) -> str | None:
1919
"""Extract activity text from a message"""
2020
try:
21-
if "Assistant" in msg.__class__.__name__:
21+
if isinstance(msg, AssistantMessage):
2222
if hasattr(msg, "content") and msg.content:
2323
first_content = msg.content[0] if isinstance(msg.content, list) else msg.content
2424
if hasattr(first_content, "name"):
2525
return f"🤖 Using: {first_content.name}()"
2626
return "🤖 Thinking..."
27-
elif "User" in msg.__class__.__name__:
27+
elif isinstance(msg, UserMessage):
2828
return "✓ Tool completed"
2929
except (AttributeError, IndexError):
3030
pass
@@ -102,7 +102,7 @@ async def send_query(
102102
else:
103103
activity_handler(msg)
104104

105-
if hasattr(msg, "result"):
105+
if isinstance(msg, ResultMessage):
106106
result = msg.result
107107
except Exception as e:
108108
print(f"❌ Query error: {e}")

claude_agent_sdk/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "Add your description here"
55
readme = "README.md"
66
requires-python = ">=3.11"
77
dependencies = [
8-
"claude-agent-sdk>=0.0.20",
8+
"claude-agent-sdk>=0.1.6",
99
"ipykernel>=6.29.5",
1010
"mcp-server-git>=2025.1.14",
1111
"python-dotenv>=1.1.1",

claude_agent_sdk/research_agent/agent.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88

99
from dotenv import load_dotenv
1010

11-
from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
11+
from claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, ClaudeSDKClient, ResultMessage, UserMessage
1212

1313
load_dotenv()
1414

1515

1616
def get_activity_text(msg) -> str | None:
1717
"""Extract activity text from a message"""
1818
try:
19-
if "Assistant" in msg.__class__.__name__:
19+
if isinstance(msg, AssistantMessage):
2020
# Check if content exists and has items
2121
if hasattr(msg, "content") and msg.content:
2222
first_content = msg.content[0] if isinstance(msg.content, list) else msg.content
2323
if hasattr(first_content, "name"):
2424
return f"🤖 Using: {first_content.name}()"
2525
return "🤖 Thinking..."
26-
elif "User" in msg.__class__.__name__:
26+
elif isinstance(msg, UserMessage):
2727
return "✓ Tool completed"
2828
except (AttributeError, IndexError):
2929
pass
@@ -78,7 +78,7 @@ async def send_query(
7878
else:
7979
activity_handler(msg)
8080

81-
if hasattr(msg, "result"):
81+
if isinstance(msg, ResultMessage):
8282
result = msg.result
8383
except Exception as e:
8484
print(f"❌ Query error: {e}")

0 commit comments

Comments
 (0)