Python SDK Reference
Version Requirement: This document is for CodeBuddy Agent SDK v0.1.0 and above.
This document provides a complete API reference for the Python SDK. For quick start and usage examples, please refer to SDK Overview.
Table of Contents
Requirements
| Dependency | Version Requirement |
|---|---|
| Python | >= 3.10 |
| CodeBuddy CLI | Installed |
Async Runtime: The SDK is based on asyncio, all APIs are asynchronous.
Installation
Recommended to use uv for dependency management:
bash
uv add codebuddy-agent-sdkOr using pip:
bash
pip install codebuddy-agent-sdkEnvironment Variables
| Variable Name | Description | Required |
|---|---|---|
CODEBUDDY_CODE_PATH | CodeBuddy CLI executable path | Optional |
If not set, the SDK will look for CLI in the following order:
- Environment variable
CODEBUDDY_CODE_PATH - Built-in binary within SDK package
- Development environment monorepo path
Authentication Configuration
The SDK supports authentication using existing login credentials, API Key, or OAuth Client Credentials. See SDK Overview - Authentication Configuration for details.
Functions
query()
Main API entry point, creates a query and returns an async iterator of messages.
python
async def query(
*,
prompt: str | AsyncIterable[dict[str, Any]],
options: CodeBuddyAgentOptions | None = None,
transport: Transport | None = None,
) -> AsyncIterator[Message]:Parameters:
| Parameter | Type | Description |
|---|---|---|
prompt | str | AsyncIterable[dict] | Query prompt or user message stream |
options | CodeBuddyAgentOptions | Configuration options (optional) |
transport | Transport | Custom transport layer (optional) |
Returns: AsyncIterator[Message] - Async iterator of messages
Example:
python
from codebuddy_agent_sdk import query, AssistantMessage, TextBlock
async for message in query(prompt="What is 2+2?"):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)Client Class
CodeBuddySDKClient
Client class for bidirectional interactive conversations. Supports multi-turn dialogues, interruptions, and dynamic control.
python
class CodeBuddySDKClient:
def __init__(
self,
options: CodeBuddyAgentOptions | None = None,
transport: Transport | None = None,
): ...Methods:
connect()
Connect to CodeBuddy.
python
async def connect(
self,
prompt: str | AsyncIterable[dict[str, Any]] | None = None
) -> None:query()
Send user message.
python
async def query(
self,
prompt: str | AsyncIterable[dict[str, Any]],
session_id: str = "default",
) -> None:receive_response()
Receive messages until a ResultMessage is received.
python
async def receive_response(self) -> AsyncIterator[Message]:receive_messages()
Receive all messages (does not auto-stop).
python
async def receive_messages(self) -> AsyncIterator[Message]:disconnect()
Disconnect.
python
async def disconnect(self) -> None:Context Manager Support:
python
async with CodeBuddySDKClient() as client:
await client.query("Hello!")
async for msg in client.receive_response():
print(msg)Unstable API
Warning: The following APIs are experimental and may change in future versions.
interrupt()
Send interrupt signal.
python
async def interrupt(self) -> None:set_permission_mode()
Dynamically modify permission mode.
python
async def set_permission_mode(self, mode: str) -> None:set_model()
Dynamically modify model.
python
async def set_model(self, model: str | None = None) -> None:Types
CodeBuddyAgentOptions
Complete configuration options:
python
@dataclass
class CodeBuddyAgentOptions:
allowed_tools: list[str] = field(default_factory=list)
disallowed_tools: list[str] = field(default_factory=list)
system_prompt: str | AppendSystemPrompt | None = None
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
permission_mode: PermissionMode | None = None
continue_conversation: bool = False
resume: str | None = None
max_turns: int | None = None
model: str | None = None
fallback_model: str | None = None
cwd: str | Path | None = None
codebuddy_code_path: str | Path | None = None
env: dict[str, str] = field(default_factory=dict)
extra_args: dict[str, str | None] = field(default_factory=dict)
stderr: Callable[[str], None] | None = None
hooks: dict[HookEvent, list[HookMatcher]] | None = None
include_partial_messages: bool = False
fork_session: bool = False
agents: dict[str, AgentDefinition] | None = None
setting_sources: list[SettingSource] | None = None
can_use_tool: CanUseTool | None = None| Field | Type | Description |
|---|---|---|
allowed_tools | list[str] | Tool whitelist to auto-allow |
disallowed_tools | list[str] | Tool blacklist to disallow |
system_prompt | str | AppendSystemPrompt | System prompt configuration |
mcp_servers | dict[str, McpServerConfig] | MCP server configuration |
permission_mode | PermissionMode | Permission mode |
continue_conversation | bool | Continue recent session |
resume | str | Session ID to resume |
max_turns | int | Maximum conversation turns |
model | str | Specify model |
fallback_model | str | Fallback model |
cwd | str | Path | Working directory |
codebuddy_code_path | str | Path | CLI executable path |
env | dict[str, str] | Environment variables |
extra_args | dict[str, str | None] | Extra CLI arguments |
stderr | Callable[[str], None] | stderr callback |
hooks | dict[HookEvent, list[HookMatcher]] | Hook configuration |
include_partial_messages | bool | Include partial messages |
fork_session | bool | Fork session |
agents | dict[str, AgentDefinition] | Custom agents |
setting_sources | list[SettingSource] | Setting sources |
can_use_tool | CanUseTool | Permission callback function |
PermissionMode
python
PermissionMode = Literal["default", "acceptEdits", "plan", "bypassPermissions"]| Value | Description |
|---|---|
"default" | Default mode, all operations require confirmation |
"acceptEdits" | Auto-approve file edits |
"plan" | Planning mode, only allow reads |
"bypassPermissions" | Skip all permission checks |
PermissionResult
python
PermissionResult = PermissionResultAllow | PermissionResultDeny
@dataclass
class PermissionResultAllow:
updated_input: dict[str, Any]
behavior: Literal["allow"] = "allow"
updated_permissions: list[dict[str, Any]] | None = None
@dataclass
class PermissionResultDeny:
message: str
behavior: Literal["deny"] = "deny"
interrupt: bool = FalseCanUseTool
python
CanUseTool = Callable[
[str, dict[str, Any], CanUseToolOptions],
Awaitable[PermissionResult],
]
@dataclass
class CanUseToolOptions:
tool_use_id: str
signal: Any | None = None
agent_id: str | None = None
suggestions: list[dict[str, Any]] | None = None
blocked_path: str | None = None
decision_reason: str | None = NoneAgentDefinition
python
@dataclass
class AgentDefinition:
description: str # Agent description
prompt: str # System prompt
tools: list[str] | None = None # Allowed tools
disallowed_tools: list[str] | None = None # Disallowed tools
model: str | None = None # Model to useMcpServerConfig
python
class McpStdioServerConfig(TypedDict):
type: NotRequired[Literal["stdio"]]
command: str
args: NotRequired[list[str]]
env: NotRequired[dict[str, str]]
McpServerConfig = McpStdioServerConfigHookEvent
python
HookEvent = (
Literal["PreToolUse"]
| Literal["PostToolUse"]
| Literal["UserPromptSubmit"]
| Literal["Stop"]
| Literal["SubagentStop"]
| Literal["PreCompact"]
)HookMatcher
python
@dataclass
class HookMatcher:
matcher: str | None = None # Match pattern (supports regex)
hooks: list[HookCallback] = field(default_factory=list)
timeout: float | None = None # Timeout in secondsHookCallback
python
HookCallback = Callable[
[Any, str | None, HookContext],
Awaitable[HookJSONOutput],
]
class HookContext(TypedDict):
signal: Any | None
class SyncHookJSONOutput(TypedDict):
continue_: NotRequired[bool]
suppressOutput: NotRequired[bool]
stopReason: NotRequired[str]
decision: NotRequired[Literal["block"]]
reason: NotRequired[str]SettingSource
Controls which filesystem locations the SDK loads configuration from.
python
SettingSource = Literal["user", "project", "local"]| Value | Description | Location |
|---|---|---|
"user" | Global user settings | ~/.codebuddy/settings.json |
"project" | Project shared settings | .codebuddy/settings.json |
"local" | Project local settings | .codebuddy/settings.local.json |
Default Behavior: When setting_sources is not specified, the SDK does not load any filesystem configuration. This provides a completely clean runtime environment.
python
# Default: no configuration loaded (clean environment)
async for msg in query(prompt="..."):
pass
# Load project configuration
options = CodeBuddyAgentOptions(setting_sources=["project"])
# Load all configurations (similar to CLI behavior)
options = CodeBuddyAgentOptions(setting_sources=["user", "project", "local"])AppendSystemPrompt
python
@dataclass
class AppendSystemPrompt:
append: str # Content to append to default system promptMessage Types
Message
Union of all message types:
python
Message = UserMessage | AssistantMessage | SystemMessage | ResultMessage | StreamEventSystemMessage
python
@dataclass
class SystemMessage:
subtype: str
data: dict[str, Any]UserMessage
python
@dataclass
class UserMessage:
content: str | list[ContentBlock]
uuid: str | None = None
parent_tool_use_id: str | None = NoneAssistantMessage
python
@dataclass
class AssistantMessage:
content: list[ContentBlock]
model: str
parent_tool_use_id: str | None = None
error: str | None = NoneResultMessage
python
@dataclass
class ResultMessage:
subtype: str
duration_ms: int
duration_api_ms: int
is_error: bool
num_turns: int
session_id: str
total_cost_usd: float | None = None
usage: dict[str, Any] | None = None
result: str | None = NoneStreamEvent
python
@dataclass
class StreamEvent:
uuid: str
session_id: str
event: dict[str, Any]
parent_tool_use_id: str | None = NoneContentBlock
python
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock
@dataclass
class TextBlock:
text: str
@dataclass
class ThinkingBlock:
thinking: str
signature: str
@dataclass
class ToolUseBlock:
id: str
name: str
input: dict[str, Any]
@dataclass
class ToolResultBlock:
tool_use_id: str
content: str | list[dict[str, Any]] | None = None
is_error: bool | None = NoneInput Types
AskUserQuestionInput
python
@dataclass
class AskUserQuestionInput:
questions: list[AskUserQuestionQuestion]
answers: dict[str, str] | None = NoneAskUserQuestionQuestion
python
@dataclass
class AskUserQuestionQuestion:
question: str # Complete question text (should end with ?)
header: str # Short label (max 12 characters)
options: list[AskUserQuestionOption]
multi_select: bool # Whether to allow multiple selectionsAskUserQuestionOption
python
@dataclass
class AskUserQuestionOption:
label: str # Display text (1-5 words)
description: str # Option descriptionErrors
All exceptions inherit from CodeBuddySDKError.
CodeBuddySDKError
python
class CodeBuddySDKError(Exception):
"""Base exception for CodeBuddy SDK errors."""
passCLIConnectionError
Thrown when connection to CLI fails or no connection is established.
python
class CLIConnectionError(CodeBuddySDKError):
passCLINotFoundError
Thrown when CLI executable is not found.
python
class CLINotFoundError(CodeBuddySDKError):
def __init__(
self,
message: str,
platform: str | None = None,
arch: str | None = None,
): ...Attributes:
| Attribute | Type | Description |
|---|---|---|
platform | str | None | Current platform |
arch | str | None | Current architecture |
CLIJSONDecodeError
Thrown when JSON decoding of CLI output fails.
python
class CLIJSONDecodeError(CodeBuddySDKError):
passProcessError
Thrown when CLI process encounters an error.
python
class ProcessError(CodeBuddySDKError):
passRelated Documentation
- SDK Overview - Quick start and usage examples
- TypeScript SDK Reference - TypeScript version API
- Hook Reference Guide - Detailed Hook configuration instructions
- MCP Integration - MCP server configuration guide