mirror of
https://github.com/anthropics/claude-agent-sdk-python.git
synced 2025-10-06 01:00:03 +03:00
174 lines
5.5 KiB
Python
174 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Example demonstrating setting sources control.
|
|
|
|
This example shows how to use the setting_sources option to control which
|
|
settings are loaded, including custom slash commands, agents, and other
|
|
configurations.
|
|
|
|
Setting sources determine where Claude Code loads configurations from:
|
|
- "user": Global user settings (~/.claude/)
|
|
- "project": Project-level settings (.claude/ in project)
|
|
- "local": Local gitignored settings (.claude-local/)
|
|
|
|
IMPORTANT: When setting_sources is not provided (None), NO settings are loaded
|
|
by default. This creates an isolated environment. To load settings, explicitly
|
|
specify which sources to use.
|
|
|
|
By controlling which sources are loaded, you can:
|
|
- Create isolated environments with no custom settings (default)
|
|
- Load only user settings, excluding project-specific configurations
|
|
- Combine multiple sources as needed
|
|
|
|
Usage:
|
|
./examples/setting_sources.py - List the examples
|
|
./examples/setting_sources.py all - Run all examples
|
|
./examples/setting_sources.py default - Run a specific example
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from claude_agent_sdk import (
|
|
ClaudeAgentOptions,
|
|
ClaudeSDKClient,
|
|
SystemMessage,
|
|
)
|
|
|
|
|
|
def extract_slash_commands(msg: SystemMessage) -> list[str]:
|
|
"""Extract slash command names from system message."""
|
|
if msg.subtype == "init":
|
|
commands = msg.data.get("slash_commands", [])
|
|
return commands
|
|
return []
|
|
|
|
|
|
async def example_default():
|
|
"""Default behavior - no settings loaded."""
|
|
print("=== Default Behavior Example ===")
|
|
print("Setting sources: None (default)")
|
|
print("Expected: No custom slash commands will be available\n")
|
|
|
|
sdk_dir = Path(__file__).parent.parent
|
|
|
|
options = ClaudeAgentOptions(
|
|
cwd=sdk_dir,
|
|
)
|
|
|
|
async with ClaudeSDKClient(options=options) as client:
|
|
await client.query("What is 2 + 2?")
|
|
|
|
async for msg in client.receive_response():
|
|
if isinstance(msg, SystemMessage) and msg.subtype == "init":
|
|
commands = extract_slash_commands(msg)
|
|
print(f"Available slash commands: {commands}")
|
|
if "commit" in commands:
|
|
print("❌ /commit is available (unexpected)")
|
|
else:
|
|
print("✓ /commit is NOT available (expected - no settings loaded)")
|
|
break
|
|
|
|
print()
|
|
|
|
|
|
async def example_user_only():
|
|
"""Load only user-level settings, excluding project settings."""
|
|
print("=== User Settings Only Example ===")
|
|
print("Setting sources: ['user']")
|
|
print("Expected: Project slash commands (like /commit) will NOT be available\n")
|
|
|
|
# Use the SDK repo directory which has .claude/commands/commit.md
|
|
sdk_dir = Path(__file__).parent.parent
|
|
|
|
options = ClaudeAgentOptions(
|
|
setting_sources=["user"],
|
|
cwd=sdk_dir,
|
|
)
|
|
|
|
async with ClaudeSDKClient(options=options) as client:
|
|
# Send a simple query
|
|
await client.query("What is 2 + 2?")
|
|
|
|
# Check the initialize message for available commands
|
|
async for msg in client.receive_response():
|
|
if isinstance(msg, SystemMessage) and msg.subtype == "init":
|
|
commands = extract_slash_commands(msg)
|
|
print(f"Available slash commands: {commands}")
|
|
if "commit" in commands:
|
|
print("❌ /commit is available (unexpected)")
|
|
else:
|
|
print("✓ /commit is NOT available (expected)")
|
|
break
|
|
|
|
print()
|
|
|
|
|
|
async def example_project_and_user():
|
|
"""Load both project and user settings."""
|
|
print("=== Project + User Settings Example ===")
|
|
print("Setting sources: ['user', 'project']")
|
|
print("Expected: Project slash commands (like /commit) WILL be available\n")
|
|
|
|
sdk_dir = Path(__file__).parent.parent
|
|
|
|
options = ClaudeAgentOptions(
|
|
setting_sources=["user", "project"],
|
|
cwd=sdk_dir,
|
|
)
|
|
|
|
async with ClaudeSDKClient(options=options) as client:
|
|
await client.query("What is 2 + 2?")
|
|
|
|
async for msg in client.receive_response():
|
|
if isinstance(msg, SystemMessage) and msg.subtype == "init":
|
|
commands = extract_slash_commands(msg)
|
|
print(f"Available slash commands: {commands}")
|
|
if "commit" in commands:
|
|
print("✓ /commit is available (expected)")
|
|
else:
|
|
print("❌ /commit is NOT available (unexpected)")
|
|
break
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
async def main():
|
|
"""Run all examples or a specific example based on command line argument."""
|
|
examples = {
|
|
"default": example_default,
|
|
"user_only": example_user_only,
|
|
"project_and_user": example_project_and_user,
|
|
}
|
|
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python setting_sources.py <example_name>")
|
|
print("\nAvailable examples:")
|
|
print(" all - Run all examples")
|
|
for name in examples:
|
|
print(f" {name}")
|
|
sys.exit(0)
|
|
|
|
example_name = sys.argv[1]
|
|
|
|
if example_name == "all":
|
|
for example in examples.values():
|
|
await example()
|
|
print("-" * 50 + "\n")
|
|
elif example_name in examples:
|
|
await examples[example_name]()
|
|
else:
|
|
print(f"Error: Unknown example '{example_name}'")
|
|
print("\nAvailable examples:")
|
|
print(" all - Run all examples")
|
|
for name in examples:
|
|
print(f" {name}")
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("Starting Claude SDK Setting Sources Examples...")
|
|
print("=" * 50 + "\n")
|
|
asyncio.run(main()) |