codebuddy-agent-sdk 0.1.27__py3-none-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of codebuddy-agent-sdk might be problematic. Click here for more details.
- codebuddy_agent_sdk/__init__.py +126 -0
- codebuddy_agent_sdk/_binary.py +150 -0
- codebuddy_agent_sdk/_errors.py +54 -0
- codebuddy_agent_sdk/_message_parser.py +122 -0
- codebuddy_agent_sdk/_version.py +3 -0
- codebuddy_agent_sdk/bin/codebuddy +0 -0
- codebuddy_agent_sdk/client.py +311 -0
- codebuddy_agent_sdk/mcp/__init__.py +35 -0
- codebuddy_agent_sdk/mcp/create_sdk_mcp_server.py +154 -0
- codebuddy_agent_sdk/mcp/sdk_control_server_transport.py +95 -0
- codebuddy_agent_sdk/mcp/types.py +300 -0
- codebuddy_agent_sdk/py.typed +0 -0
- codebuddy_agent_sdk/query.py +535 -0
- codebuddy_agent_sdk/transport/__init__.py +6 -0
- codebuddy_agent_sdk/transport/base.py +26 -0
- codebuddy_agent_sdk/transport/subprocess.py +171 -0
- codebuddy_agent_sdk/types.py +330 -0
- codebuddy_agent_sdk-0.1.27.dist-info/METADATA +89 -0
- codebuddy_agent_sdk-0.1.27.dist-info/RECORD +20 -0
- codebuddy_agent_sdk-0.1.27.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Subprocess transport for CLI communication."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from collections.abc import AsyncIterable, AsyncIterator
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from .._binary import get_cli_path
|
|
12
|
+
from ..types import AppendSystemPrompt, CodeBuddyAgentOptions
|
|
13
|
+
from .base import Transport
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SubprocessTransport(Transport):
|
|
17
|
+
"""Transport that communicates with CLI via subprocess."""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
options: CodeBuddyAgentOptions,
|
|
22
|
+
prompt: str | AsyncIterable[dict[str, Any]] | None = None,
|
|
23
|
+
):
|
|
24
|
+
self.options = options
|
|
25
|
+
self.prompt = prompt
|
|
26
|
+
self._process: asyncio.subprocess.Process | None = None
|
|
27
|
+
self._closed = False
|
|
28
|
+
|
|
29
|
+
def _get_cli_path(self) -> str:
|
|
30
|
+
"""Get the path to CLI executable."""
|
|
31
|
+
# User-specified path takes highest precedence
|
|
32
|
+
if self.options.codebuddy_code_path:
|
|
33
|
+
return str(self.options.codebuddy_code_path)
|
|
34
|
+
|
|
35
|
+
# Use the binary resolver (env var -> package binary -> monorepo)
|
|
36
|
+
return get_cli_path()
|
|
37
|
+
|
|
38
|
+
def _build_args(self) -> list[str]:
|
|
39
|
+
"""Build CLI arguments from options."""
|
|
40
|
+
args = [
|
|
41
|
+
"--input-format",
|
|
42
|
+
"stream-json",
|
|
43
|
+
"--verbose",
|
|
44
|
+
"--output-format",
|
|
45
|
+
"stream-json",
|
|
46
|
+
]
|
|
47
|
+
opts = self.options
|
|
48
|
+
|
|
49
|
+
# Model options
|
|
50
|
+
if opts.model:
|
|
51
|
+
args.extend(["--model", opts.model])
|
|
52
|
+
if opts.fallback_model:
|
|
53
|
+
args.extend(["--fallback-model", opts.fallback_model])
|
|
54
|
+
|
|
55
|
+
# Permission options
|
|
56
|
+
if opts.permission_mode:
|
|
57
|
+
args.extend(["--permission-mode", opts.permission_mode])
|
|
58
|
+
|
|
59
|
+
# Turn limits
|
|
60
|
+
if opts.max_turns:
|
|
61
|
+
args.extend(["--max-turns", str(opts.max_turns)])
|
|
62
|
+
|
|
63
|
+
# Session options
|
|
64
|
+
if opts.continue_conversation:
|
|
65
|
+
args.append("--continue")
|
|
66
|
+
if opts.resume:
|
|
67
|
+
args.extend(["--resume", opts.resume])
|
|
68
|
+
if opts.fork_session:
|
|
69
|
+
args.append("--fork-session")
|
|
70
|
+
|
|
71
|
+
# Tool options
|
|
72
|
+
if opts.allowed_tools:
|
|
73
|
+
args.extend(["--allowedTools", ",".join(opts.allowed_tools)])
|
|
74
|
+
if opts.disallowed_tools:
|
|
75
|
+
args.extend(["--disallowedTools", ",".join(opts.disallowed_tools)])
|
|
76
|
+
|
|
77
|
+
# MCP options
|
|
78
|
+
if opts.mcp_servers and isinstance(opts.mcp_servers, dict):
|
|
79
|
+
args.extend(["--mcp-config", json.dumps({"mcpServers": opts.mcp_servers})])
|
|
80
|
+
|
|
81
|
+
# Settings
|
|
82
|
+
# SDK default: don't load any filesystem settings for clean environment isolation
|
|
83
|
+
# When setting_sources is explicitly provided (including empty list), use it
|
|
84
|
+
# When not provided (None), default to 'none' for SDK isolation
|
|
85
|
+
if opts.setting_sources is not None:
|
|
86
|
+
setting_value = (
|
|
87
|
+
"none" if len(opts.setting_sources) == 0 else ",".join(opts.setting_sources)
|
|
88
|
+
)
|
|
89
|
+
args.extend(["--setting-sources", setting_value])
|
|
90
|
+
else:
|
|
91
|
+
# SDK default behavior: no filesystem settings loaded
|
|
92
|
+
args.extend(["--setting-sources", "none"])
|
|
93
|
+
|
|
94
|
+
# Output options
|
|
95
|
+
if opts.include_partial_messages:
|
|
96
|
+
args.append("--include-partial-messages")
|
|
97
|
+
|
|
98
|
+
# System prompt options
|
|
99
|
+
if opts.system_prompt is not None:
|
|
100
|
+
if isinstance(opts.system_prompt, str):
|
|
101
|
+
args.extend(["--system-prompt", opts.system_prompt])
|
|
102
|
+
elif isinstance(opts.system_prompt, AppendSystemPrompt):
|
|
103
|
+
args.extend(["--append-system-prompt", opts.system_prompt.append])
|
|
104
|
+
|
|
105
|
+
# Extra args (custom flags)
|
|
106
|
+
for flag, value in opts.extra_args.items():
|
|
107
|
+
if value is None:
|
|
108
|
+
args.append(f"--{flag}")
|
|
109
|
+
else:
|
|
110
|
+
args.extend([f"--{flag}", value])
|
|
111
|
+
|
|
112
|
+
return args
|
|
113
|
+
|
|
114
|
+
async def connect(self) -> None:
|
|
115
|
+
"""Start the subprocess."""
|
|
116
|
+
cli_path = self._get_cli_path()
|
|
117
|
+
args = self._build_args()
|
|
118
|
+
cwd = str(self.options.cwd) if self.options.cwd else os.getcwd()
|
|
119
|
+
|
|
120
|
+
env = {
|
|
121
|
+
**os.environ,
|
|
122
|
+
**self.options.env,
|
|
123
|
+
"CODEBUDDY_CODE_ENTRYPOINT": "sdk-py",
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
self._process = await asyncio.create_subprocess_exec(
|
|
127
|
+
cli_path,
|
|
128
|
+
*args,
|
|
129
|
+
stdin=asyncio.subprocess.PIPE,
|
|
130
|
+
stdout=asyncio.subprocess.PIPE,
|
|
131
|
+
stderr=asyncio.subprocess.PIPE,
|
|
132
|
+
cwd=cwd,
|
|
133
|
+
env=env,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Start stderr reader if callback provided
|
|
137
|
+
if self.options.stderr and self._process.stderr:
|
|
138
|
+
asyncio.create_task(self._read_stderr())
|
|
139
|
+
|
|
140
|
+
async def _read_stderr(self) -> None:
|
|
141
|
+
"""Read stderr and call callback."""
|
|
142
|
+
if self._process and self._process.stderr and self.options.stderr:
|
|
143
|
+
async for line in self._process.stderr:
|
|
144
|
+
self.options.stderr(line.decode())
|
|
145
|
+
|
|
146
|
+
async def read(self) -> AsyncIterator[str]:
|
|
147
|
+
"""Read lines from stdout."""
|
|
148
|
+
if not self._process or not self._process.stdout:
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
async for line in self._process.stdout:
|
|
152
|
+
if self._closed:
|
|
153
|
+
break
|
|
154
|
+
yield line.decode().strip()
|
|
155
|
+
|
|
156
|
+
async def write(self, data: str) -> None:
|
|
157
|
+
"""Write data to stdin."""
|
|
158
|
+
if self._process and self._process.stdin:
|
|
159
|
+
self._process.stdin.write((data + "\n").encode())
|
|
160
|
+
await self._process.stdin.drain()
|
|
161
|
+
|
|
162
|
+
async def close(self) -> None:
|
|
163
|
+
"""Close the subprocess."""
|
|
164
|
+
if self._closed:
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
self._closed = True
|
|
168
|
+
|
|
169
|
+
if self._process:
|
|
170
|
+
self._process.kill()
|
|
171
|
+
await self._process.wait()
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
"""Type definitions for CodeBuddy Agent SDK."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Awaitable, Callable
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .mcp.types import SdkMcpServer
|
|
12
|
+
|
|
13
|
+
# ============= AskUserQuestion Types =============
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class AskUserQuestionOption:
|
|
18
|
+
"""Option for AskUserQuestion tool."""
|
|
19
|
+
|
|
20
|
+
label: str
|
|
21
|
+
description: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class AskUserQuestionQuestion:
|
|
26
|
+
"""Question for AskUserQuestion tool."""
|
|
27
|
+
|
|
28
|
+
question: str
|
|
29
|
+
header: str
|
|
30
|
+
options: list[AskUserQuestionOption]
|
|
31
|
+
multi_select: bool
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class AskUserQuestionInput:
|
|
36
|
+
"""Input for AskUserQuestion tool."""
|
|
37
|
+
|
|
38
|
+
questions: list[AskUserQuestionQuestion]
|
|
39
|
+
answers: dict[str, str] | None = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# ============= Permission Types =============
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class CanUseToolOptions:
|
|
47
|
+
"""Options passed to canUseTool callback."""
|
|
48
|
+
|
|
49
|
+
tool_use_id: str
|
|
50
|
+
signal: Any | None = None
|
|
51
|
+
agent_id: str | None = None
|
|
52
|
+
suggestions: list[dict[str, Any]] | None = None
|
|
53
|
+
blocked_path: str | None = None
|
|
54
|
+
decision_reason: str | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class PermissionResultAllow:
|
|
59
|
+
"""Allow permission result."""
|
|
60
|
+
|
|
61
|
+
updated_input: dict[str, Any]
|
|
62
|
+
behavior: Literal["allow"] = "allow"
|
|
63
|
+
updated_permissions: list[dict[str, Any]] | None = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class PermissionResultDeny:
|
|
68
|
+
"""Deny permission result."""
|
|
69
|
+
|
|
70
|
+
message: str
|
|
71
|
+
behavior: Literal["deny"] = "deny"
|
|
72
|
+
interrupt: bool = False
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
PermissionResult = PermissionResultAllow | PermissionResultDeny
|
|
76
|
+
|
|
77
|
+
# CanUseTool callback type
|
|
78
|
+
CanUseTool = Callable[
|
|
79
|
+
[str, dict[str, Any], CanUseToolOptions],
|
|
80
|
+
Awaitable[PermissionResult],
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Permission modes
|
|
85
|
+
PermissionMode = Literal["default", "acceptEdits", "plan", "bypassPermissions"]
|
|
86
|
+
|
|
87
|
+
# Hook events
|
|
88
|
+
HookEvent = (
|
|
89
|
+
Literal["PreToolUse"]
|
|
90
|
+
| Literal["PostToolUse"]
|
|
91
|
+
| Literal["UserPromptSubmit"]
|
|
92
|
+
| Literal["Stop"]
|
|
93
|
+
| Literal["SubagentStop"]
|
|
94
|
+
| Literal["PreCompact"]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Setting sources
|
|
98
|
+
SettingSource = Literal["user", "project", "local"]
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Agent definition
|
|
102
|
+
@dataclass
|
|
103
|
+
class AgentDefinition:
|
|
104
|
+
"""Agent definition configuration."""
|
|
105
|
+
|
|
106
|
+
description: str
|
|
107
|
+
prompt: str
|
|
108
|
+
tools: list[str] | None = None
|
|
109
|
+
disallowed_tools: list[str] | None = None
|
|
110
|
+
model: str | None = None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# Content block types
|
|
114
|
+
@dataclass
|
|
115
|
+
class TextBlock:
|
|
116
|
+
"""Text content block."""
|
|
117
|
+
|
|
118
|
+
text: str
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass
|
|
122
|
+
class ThinkingBlock:
|
|
123
|
+
"""Thinking content block."""
|
|
124
|
+
|
|
125
|
+
thinking: str
|
|
126
|
+
signature: str
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@dataclass
|
|
130
|
+
class ToolUseBlock:
|
|
131
|
+
"""Tool use content block."""
|
|
132
|
+
|
|
133
|
+
id: str
|
|
134
|
+
name: str
|
|
135
|
+
input: dict[str, Any]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@dataclass
|
|
139
|
+
class ToolResultBlock:
|
|
140
|
+
"""Tool result content block."""
|
|
141
|
+
|
|
142
|
+
tool_use_id: str
|
|
143
|
+
content: str | list[dict[str, Any]] | None = None
|
|
144
|
+
is_error: bool | None = None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# Message types
|
|
151
|
+
@dataclass
|
|
152
|
+
class UserMessage:
|
|
153
|
+
"""User message."""
|
|
154
|
+
|
|
155
|
+
content: str | list[ContentBlock]
|
|
156
|
+
uuid: str | None = None
|
|
157
|
+
parent_tool_use_id: str | None = None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@dataclass
|
|
161
|
+
class AssistantMessage:
|
|
162
|
+
"""Assistant message with content blocks."""
|
|
163
|
+
|
|
164
|
+
content: list[ContentBlock]
|
|
165
|
+
model: str
|
|
166
|
+
parent_tool_use_id: str | None = None
|
|
167
|
+
error: str | None = None
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@dataclass
|
|
171
|
+
class SystemMessage:
|
|
172
|
+
"""System message with metadata."""
|
|
173
|
+
|
|
174
|
+
subtype: str
|
|
175
|
+
data: dict[str, Any]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@dataclass
|
|
179
|
+
class ResultMessage:
|
|
180
|
+
"""Result message with cost and usage information."""
|
|
181
|
+
|
|
182
|
+
subtype: str
|
|
183
|
+
duration_ms: int
|
|
184
|
+
duration_api_ms: int
|
|
185
|
+
is_error: bool
|
|
186
|
+
num_turns: int
|
|
187
|
+
session_id: str
|
|
188
|
+
total_cost_usd: float | None = None
|
|
189
|
+
usage: dict[str, Any] | None = None
|
|
190
|
+
result: str | None = None
|
|
191
|
+
errors: list[str] | None = None
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@dataclass
|
|
195
|
+
class StreamEvent:
|
|
196
|
+
"""Stream event for partial message updates during streaming."""
|
|
197
|
+
|
|
198
|
+
uuid: str
|
|
199
|
+
session_id: str
|
|
200
|
+
event: dict[str, Any]
|
|
201
|
+
parent_tool_use_id: str | None = None
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@dataclass
|
|
205
|
+
class ErrorMessage:
|
|
206
|
+
"""Error message from CLI."""
|
|
207
|
+
|
|
208
|
+
error: str
|
|
209
|
+
session_id: str | None = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
Message = (
|
|
213
|
+
UserMessage | AssistantMessage | SystemMessage | ResultMessage | StreamEvent | ErrorMessage
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# Hook types
|
|
218
|
+
class HookContext(TypedDict):
|
|
219
|
+
"""Context information for hook callbacks."""
|
|
220
|
+
|
|
221
|
+
signal: Any | None
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class SyncHookJSONOutput(TypedDict):
|
|
225
|
+
"""Synchronous hook output with control and decision fields."""
|
|
226
|
+
|
|
227
|
+
continue_: NotRequired[bool]
|
|
228
|
+
suppressOutput: NotRequired[bool]
|
|
229
|
+
stopReason: NotRequired[str]
|
|
230
|
+
decision: NotRequired[Literal["block"]]
|
|
231
|
+
reason: NotRequired[str]
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
HookJSONOutput = SyncHookJSONOutput
|
|
235
|
+
|
|
236
|
+
HookCallback = Callable[
|
|
237
|
+
[Any, str | None, HookContext],
|
|
238
|
+
Awaitable[HookJSONOutput],
|
|
239
|
+
]
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@dataclass
|
|
243
|
+
class HookMatcher:
|
|
244
|
+
"""Hook matcher configuration."""
|
|
245
|
+
|
|
246
|
+
matcher: str | None = None
|
|
247
|
+
hooks: list[HookCallback] = field(default_factory=list)
|
|
248
|
+
timeout: float | None = None
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# MCP Server config
|
|
252
|
+
class McpStdioServerConfig(TypedDict):
|
|
253
|
+
"""MCP stdio server configuration."""
|
|
254
|
+
|
|
255
|
+
type: NotRequired[Literal["stdio"]]
|
|
256
|
+
command: str
|
|
257
|
+
args: NotRequired[list[str]]
|
|
258
|
+
env: NotRequired[dict[str, str]]
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class McpSdkServerConfig(TypedDict):
|
|
262
|
+
"""
|
|
263
|
+
SDK MCP Server configuration - for servers running within the SDK process.
|
|
264
|
+
Created via create_sdk_mcp_server().
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
type: Literal["sdk"]
|
|
268
|
+
name: str
|
|
269
|
+
server: SdkMcpServer
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
McpServerConfig = McpStdioServerConfig | McpSdkServerConfig
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# System prompt configuration
|
|
276
|
+
@dataclass
|
|
277
|
+
class AppendSystemPrompt:
|
|
278
|
+
"""Append to the default system prompt."""
|
|
279
|
+
|
|
280
|
+
append: str
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
# Main configuration
|
|
284
|
+
@dataclass
|
|
285
|
+
class CodeBuddyAgentOptions:
|
|
286
|
+
"""Query options for CodeBuddy Agent SDK."""
|
|
287
|
+
|
|
288
|
+
allowed_tools: list[str] = field(default_factory=list)
|
|
289
|
+
"""
|
|
290
|
+
List of tool names that are auto-allowed without prompting for permission.
|
|
291
|
+
These tools will execute automatically without asking the user for approval.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
disallowed_tools: list[str] = field(default_factory=list)
|
|
295
|
+
"""
|
|
296
|
+
List of tool names that are disallowed. When the model attempts to use
|
|
297
|
+
these tools, the request will be denied. MCP tools matching this list
|
|
298
|
+
are also filtered from the model's context.
|
|
299
|
+
"""
|
|
300
|
+
|
|
301
|
+
system_prompt: str | AppendSystemPrompt | None = None
|
|
302
|
+
"""
|
|
303
|
+
System prompt configuration.
|
|
304
|
+
|
|
305
|
+
- `str`: Override the entire system prompt
|
|
306
|
+
- `AppendSystemPrompt`: Append to the default system prompt
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
mcp_servers: dict[str, McpServerConfig] | str | Path = field(default_factory=dict)
|
|
310
|
+
permission_mode: PermissionMode | None = None
|
|
311
|
+
continue_conversation: bool = False
|
|
312
|
+
resume: str | None = None
|
|
313
|
+
max_turns: int | None = None
|
|
314
|
+
model: str | None = None
|
|
315
|
+
fallback_model: str | None = None
|
|
316
|
+
cwd: str | Path | None = None
|
|
317
|
+
codebuddy_code_path: str | Path | None = None
|
|
318
|
+
env: dict[str, str] = field(default_factory=dict)
|
|
319
|
+
extra_args: dict[str, str | None] = field(default_factory=dict)
|
|
320
|
+
stderr: Callable[[str], None] | None = None
|
|
321
|
+
hooks: dict[HookEvent, list[HookMatcher]] | None = None
|
|
322
|
+
include_partial_messages: bool = False
|
|
323
|
+
fork_session: bool = False
|
|
324
|
+
agents: dict[str, AgentDefinition] | None = None
|
|
325
|
+
setting_sources: list[SettingSource] | None = None
|
|
326
|
+
can_use_tool: CanUseTool | None = None
|
|
327
|
+
"""
|
|
328
|
+
Custom permission handler callback.
|
|
329
|
+
Called when a tool requires permission approval.
|
|
330
|
+
"""
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codebuddy-agent-sdk
|
|
3
|
+
Version: 0.1.27
|
|
4
|
+
Summary: CodeBuddy Code SDK for Python
|
|
5
|
+
Author-email: ninoyi <ninoyi@tencent.com>
|
|
6
|
+
Keywords: agent,ai,codebuddy,sdk
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# CodeBuddy Agent SDK for Python
|
|
24
|
+
|
|
25
|
+
SDK for building AI agents with CodeBuddy Code's capabilities. Programmatically interact with AI to build autonomous agents that can understand codebases, edit files, and execute workflows.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Using uv (recommended)
|
|
31
|
+
uv add codebuddy-agent-sdk
|
|
32
|
+
|
|
33
|
+
# Using pip
|
|
34
|
+
pip install codebuddy-agent-sdk
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
from codebuddy_agent_sdk import query
|
|
42
|
+
|
|
43
|
+
async def main():
|
|
44
|
+
async for message in query(
|
|
45
|
+
prompt="What files are in this directory?",
|
|
46
|
+
permission_mode="bypassPermissions",
|
|
47
|
+
):
|
|
48
|
+
if message.type == "assistant":
|
|
49
|
+
for block in message.content:
|
|
50
|
+
if hasattr(block, "text"):
|
|
51
|
+
print(block.text)
|
|
52
|
+
|
|
53
|
+
asyncio.run(main())
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API Reference
|
|
57
|
+
|
|
58
|
+
### `query(prompt, **options)`
|
|
59
|
+
|
|
60
|
+
Create a query to interact with the agent.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
async for message in query(
|
|
64
|
+
prompt="Your prompt here",
|
|
65
|
+
model="sonnet", # Model to use
|
|
66
|
+
permission_mode="bypassPermissions", # Permission mode
|
|
67
|
+
max_turns=10, # Maximum conversation turns
|
|
68
|
+
cwd="/path/to/project", # Working directory
|
|
69
|
+
):
|
|
70
|
+
# Handle message
|
|
71
|
+
pass
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Message Types
|
|
75
|
+
|
|
76
|
+
- `system` - Session initialization info
|
|
77
|
+
- `assistant` - Agent responses (text, tool calls)
|
|
78
|
+
- `result` - Query completion status
|
|
79
|
+
|
|
80
|
+
## Related Links
|
|
81
|
+
|
|
82
|
+
- [CodeBuddy Code CLI](https://www.npmjs.com/package/@tencent-ai/codebuddy-code)
|
|
83
|
+
- [Documentation](https://cnb.cool/codebuddy/codebuddy-code/-/blob/main/docs)
|
|
84
|
+
- [Issues](https://cnb.cool/codebuddy/codebuddy-code/-/issues)
|
|
85
|
+
|
|
86
|
+
## Feedback
|
|
87
|
+
|
|
88
|
+
- Submit issues at [Issues](https://cnb.cool/codebuddy/codebuddy-code/-/issues)
|
|
89
|
+
- Contact: codebuddy@tencent.com
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
codebuddy_agent_sdk/__init__.py,sha256=GKrVvH2KKyuA9ht-7uMVHJJn7eWBKOi0_DKc2Ef5RCU,2690
|
|
2
|
+
codebuddy_agent_sdk/_binary.py,sha256=rQFj2B__X7zHMxFazp_0vgXQFsqPi578f8g4jSkLUBc,4338
|
|
3
|
+
codebuddy_agent_sdk/_errors.py,sha256=bLmyebUowNlbUomXyuS1L6J6ZbwHohvzqH_1GmN4_oM,1248
|
|
4
|
+
codebuddy_agent_sdk/_message_parser.py,sha256=vtyeuwIFdl9Wz1WrWEg7G6E3OECDZT4G6bvpH15Q3VY,3504
|
|
5
|
+
codebuddy_agent_sdk/_version.py,sha256=PuGt-TG_y-epKt7rwV96SbTWUkhFlvkyVOJnLXXGVW8,75
|
|
6
|
+
codebuddy_agent_sdk/client.py,sha256=JfdA0wq4KOOrP4mZXfVuF4uwdrEbVHGIUrzpt4Bt_ZM,10803
|
|
7
|
+
codebuddy_agent_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
codebuddy_agent_sdk/query.py,sha256=tCfFomCNGS1Sygbk0U9j25JLsF2azWa-3AuckThYaII,17341
|
|
9
|
+
codebuddy_agent_sdk/types.py,sha256=rw5jrIg8LWtZN1Km_7TzY7SP_wFRJwKNGwPxgRcQ47A,7473
|
|
10
|
+
codebuddy_agent_sdk/bin/codebuddy,sha256=u0t0idfxMHpMFBhg8-w6Xyc1eleqz_VlMxTDP8Pz7yU,77940417
|
|
11
|
+
codebuddy_agent_sdk/mcp/__init__.py,sha256=0aCmHN0MnMCCUU0bdTWBRlxAblnxA-vR5Og0y3BA480,764
|
|
12
|
+
codebuddy_agent_sdk/mcp/create_sdk_mcp_server.py,sha256=ig0b0ghf0T8GGjltFBRSmQSTFsaJ6fBI8S1Pjupqhps,4959
|
|
13
|
+
codebuddy_agent_sdk/mcp/sdk_control_server_transport.py,sha256=CIG3h5gULubGcQPHPVd-GG9cLswwVDfgDlLba6ZPQbs,2944
|
|
14
|
+
codebuddy_agent_sdk/mcp/types.py,sha256=CPEBUW5vCt93cBgu3HvAacXMsa5FdRWwWxPeicQ0PWw,8578
|
|
15
|
+
codebuddy_agent_sdk/transport/__init__.py,sha256=zv_8OJHgnWjCInqOiu3GOFby4XVGvDwICHpOsymOlko,166
|
|
16
|
+
codebuddy_agent_sdk/transport/base.py,sha256=XtLquCmt4yzPhTBHcVU0XFb016uG0E-12ETc-N9tzIk,662
|
|
17
|
+
codebuddy_agent_sdk/transport/subprocess.py,sha256=VHoGXoP0qm597bhIE_mTV9xyIDUM-nMk7fwZwntx94c,5701
|
|
18
|
+
codebuddy_agent_sdk-0.1.27.dist-info/METADATA,sha256=7I6H0xtclNvPAkqs79en6VZFVEQgzoFPia6Me2z0C8c,2539
|
|
19
|
+
codebuddy_agent_sdk-0.1.27.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
20
|
+
codebuddy_agent_sdk-0.1.27.dist-info/RECORD,,
|