mycode-sdk 0.12.0__tar.gz → 0.13.0__tar.gz
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.
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/PKG-INFO +40 -24
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/README.md +38 -22
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/pyproject.toml +1 -1
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/__init__.py +2 -11
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/agent.py +245 -81
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/compact.py +10 -1
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/hooks.py +2 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/messages.py +4 -5
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/models.py +57 -63
- mycode_sdk-0.13.0/src/mycode/models_catalog.json +11297 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/anthropic_like.py +13 -1
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/base.py +14 -8
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/gemini.py +27 -1
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/openai_chat.py +23 -7
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/openai_responses.py +35 -5
- mycode_sdk-0.13.0/src/mycode/tools.py +370 -0
- mycode_sdk-0.12.0/src/mycode/models_catalog.json +0 -8170
- mycode_sdk-0.12.0/src/mycode/tools.py +0 -1101
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/.gitignore +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/LICENSE +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/attachments.py +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/providers/__init__.py +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/py.typed +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/session.py +0 -0
- {mycode_sdk-0.12.0 → mycode_sdk-0.13.0}/src/mycode/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: mycode-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: Lightweight Python SDK for building AI agents.
|
|
5
5
|
Project-URL: Homepage, https://github.com/legibet/mycode
|
|
6
6
|
Project-URL: Repository, https://github.com/legibet/mycode
|
|
@@ -42,15 +42,27 @@ pip install mycode-sdk
|
|
|
42
42
|
|
|
43
43
|
```python
|
|
44
44
|
import asyncio
|
|
45
|
+
from pathlib import Path
|
|
46
|
+
|
|
47
|
+
from mycode import Agent, tool
|
|
45
48
|
|
|
46
|
-
|
|
49
|
+
|
|
50
|
+
@tool
|
|
51
|
+
def read_file(path: str) -> str:
|
|
52
|
+
"""Read a UTF-8 text file.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
path: File path, relative to the working directory.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
return Path(path).read_text(encoding="utf-8")
|
|
47
59
|
|
|
48
60
|
|
|
49
61
|
async def main() -> None:
|
|
50
62
|
agent = Agent(
|
|
51
63
|
model="claude-sonnet-4-6",
|
|
52
64
|
api_key="YOUR_API_KEY",
|
|
53
|
-
tools=[
|
|
65
|
+
tools=[read_file],
|
|
54
66
|
)
|
|
55
67
|
|
|
56
68
|
async for event in agent.achat("Read pyproject.toml and tell me the project name."):
|
|
@@ -142,15 +154,7 @@ agent = Agent(
|
|
|
142
154
|
|
|
143
155
|
Construct another `Agent` with the same `(session_dir, session_id)` to load the conversation history.
|
|
144
156
|
|
|
145
|
-
##
|
|
146
|
-
|
|
147
|
-
```python
|
|
148
|
-
from mycode import read_tool, write_tool, edit_tool, bash_tool
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Four tools for reading, writing, editing files, and running shell commands. Opt in by passing them to `tools=[...]`.
|
|
152
|
-
|
|
153
|
-
## Custom tools
|
|
157
|
+
## Tools
|
|
154
158
|
|
|
155
159
|
Decorate a typed function with `@tool`:
|
|
156
160
|
|
|
@@ -176,36 +180,48 @@ agent = Agent(
|
|
|
176
180
|
)
|
|
177
181
|
```
|
|
178
182
|
|
|
179
|
-
To call
|
|
183
|
+
To call another registered tool from inside a tool, type the first parameter as `ToolContext` and dispatch by name:
|
|
180
184
|
|
|
181
185
|
```python
|
|
182
186
|
from mycode import ToolContext, tool
|
|
183
187
|
|
|
184
188
|
|
|
185
189
|
@tool
|
|
186
|
-
def
|
|
187
|
-
"""
|
|
190
|
+
def greet_team(ctx: ToolContext, names: list[str]) -> str:
|
|
191
|
+
"""Greet several people at once."""
|
|
188
192
|
|
|
189
|
-
|
|
190
|
-
return result.output.splitlines()[0] if result.output else ""
|
|
193
|
+
return "\n".join(ctx.call("greet", {"name": name}).output for name in names)
|
|
191
194
|
```
|
|
192
195
|
|
|
193
|
-
Async tools use `await ctx.
|
|
196
|
+
Async tools use `await ctx.acall(name, args)` instead.
|
|
194
197
|
|
|
195
198
|
## Tool hooks
|
|
196
199
|
|
|
197
200
|
Inspect or replace tool calls before they run. Return `None` from `before_tool` to let the tool execute, or a `ToolExecutionResult` to skip it:
|
|
198
201
|
|
|
199
202
|
```python
|
|
200
|
-
|
|
203
|
+
import os
|
|
204
|
+
|
|
205
|
+
from mycode import Agent, Hooks, ToolExecutionResult, tool
|
|
201
206
|
|
|
202
207
|
hooks = Hooks()
|
|
203
208
|
|
|
204
209
|
|
|
210
|
+
@tool
|
|
211
|
+
def delete_file(path: str) -> str:
|
|
212
|
+
"""Delete a file.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
path: Path of the file to delete.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
os.remove(path)
|
|
219
|
+
return f"deleted {path}"
|
|
220
|
+
|
|
221
|
+
|
|
205
222
|
@hooks.before_tool
|
|
206
|
-
async def
|
|
207
|
-
|
|
208
|
-
if ctx.tool_name == "bash" and "rm -rf" in cmd:
|
|
223
|
+
async def protect_dotfiles(ctx):
|
|
224
|
+
if ctx.tool_name == "delete_file" and str(ctx.tool_input.get("path") or "").startswith("."):
|
|
209
225
|
return ToolExecutionResult(output="error: blocked", is_error=True)
|
|
210
226
|
return None
|
|
211
227
|
|
|
@@ -213,7 +229,7 @@ async def block_rm(ctx):
|
|
|
213
229
|
agent = Agent(
|
|
214
230
|
model="claude-sonnet-4-6",
|
|
215
231
|
api_key="...",
|
|
216
|
-
tools=[
|
|
232
|
+
tools=[delete_file],
|
|
217
233
|
hooks=hooks,
|
|
218
234
|
)
|
|
219
235
|
```
|
|
@@ -14,15 +14,27 @@ pip install mycode-sdk
|
|
|
14
14
|
|
|
15
15
|
```python
|
|
16
16
|
import asyncio
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from mycode import Agent, tool
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
|
|
22
|
+
@tool
|
|
23
|
+
def read_file(path: str) -> str:
|
|
24
|
+
"""Read a UTF-8 text file.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
path: File path, relative to the working directory.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
return Path(path).read_text(encoding="utf-8")
|
|
19
31
|
|
|
20
32
|
|
|
21
33
|
async def main() -> None:
|
|
22
34
|
agent = Agent(
|
|
23
35
|
model="claude-sonnet-4-6",
|
|
24
36
|
api_key="YOUR_API_KEY",
|
|
25
|
-
tools=[
|
|
37
|
+
tools=[read_file],
|
|
26
38
|
)
|
|
27
39
|
|
|
28
40
|
async for event in agent.achat("Read pyproject.toml and tell me the project name."):
|
|
@@ -114,15 +126,7 @@ agent = Agent(
|
|
|
114
126
|
|
|
115
127
|
Construct another `Agent` with the same `(session_dir, session_id)` to load the conversation history.
|
|
116
128
|
|
|
117
|
-
##
|
|
118
|
-
|
|
119
|
-
```python
|
|
120
|
-
from mycode import read_tool, write_tool, edit_tool, bash_tool
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Four tools for reading, writing, editing files, and running shell commands. Opt in by passing them to `tools=[...]`.
|
|
124
|
-
|
|
125
|
-
## Custom tools
|
|
129
|
+
## Tools
|
|
126
130
|
|
|
127
131
|
Decorate a typed function with `@tool`:
|
|
128
132
|
|
|
@@ -148,36 +152,48 @@ agent = Agent(
|
|
|
148
152
|
)
|
|
149
153
|
```
|
|
150
154
|
|
|
151
|
-
To call
|
|
155
|
+
To call another registered tool from inside a tool, type the first parameter as `ToolContext` and dispatch by name:
|
|
152
156
|
|
|
153
157
|
```python
|
|
154
158
|
from mycode import ToolContext, tool
|
|
155
159
|
|
|
156
160
|
|
|
157
161
|
@tool
|
|
158
|
-
def
|
|
159
|
-
"""
|
|
162
|
+
def greet_team(ctx: ToolContext, names: list[str]) -> str:
|
|
163
|
+
"""Greet several people at once."""
|
|
160
164
|
|
|
161
|
-
|
|
162
|
-
return result.output.splitlines()[0] if result.output else ""
|
|
165
|
+
return "\n".join(ctx.call("greet", {"name": name}).output for name in names)
|
|
163
166
|
```
|
|
164
167
|
|
|
165
|
-
Async tools use `await ctx.
|
|
168
|
+
Async tools use `await ctx.acall(name, args)` instead.
|
|
166
169
|
|
|
167
170
|
## Tool hooks
|
|
168
171
|
|
|
169
172
|
Inspect or replace tool calls before they run. Return `None` from `before_tool` to let the tool execute, or a `ToolExecutionResult` to skip it:
|
|
170
173
|
|
|
171
174
|
```python
|
|
172
|
-
|
|
175
|
+
import os
|
|
176
|
+
|
|
177
|
+
from mycode import Agent, Hooks, ToolExecutionResult, tool
|
|
173
178
|
|
|
174
179
|
hooks = Hooks()
|
|
175
180
|
|
|
176
181
|
|
|
182
|
+
@tool
|
|
183
|
+
def delete_file(path: str) -> str:
|
|
184
|
+
"""Delete a file.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
path: Path of the file to delete.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
os.remove(path)
|
|
191
|
+
return f"deleted {path}"
|
|
192
|
+
|
|
193
|
+
|
|
177
194
|
@hooks.before_tool
|
|
178
|
-
async def
|
|
179
|
-
|
|
180
|
-
if ctx.tool_name == "bash" and "rm -rf" in cmd:
|
|
195
|
+
async def protect_dotfiles(ctx):
|
|
196
|
+
if ctx.tool_name == "delete_file" and str(ctx.tool_input.get("path") or "").startswith("."):
|
|
181
197
|
return ToolExecutionResult(output="error: blocked", is_error=True)
|
|
182
198
|
return None
|
|
183
199
|
|
|
@@ -185,7 +201,7 @@ async def block_rm(ctx):
|
|
|
185
201
|
agent = Agent(
|
|
186
202
|
model="claude-sonnet-4-6",
|
|
187
203
|
api_key="...",
|
|
188
|
-
tools=[
|
|
204
|
+
tools=[delete_file],
|
|
189
205
|
hooks=hooks,
|
|
190
206
|
)
|
|
191
207
|
```
|
|
@@ -21,7 +21,7 @@ from mycode.messages import (
|
|
|
21
21
|
tool_use_block,
|
|
22
22
|
user_text_message,
|
|
23
23
|
)
|
|
24
|
-
from mycode.models import ModelMetadata, estimate_cost, resolve_model_metadata
|
|
24
|
+
from mycode.models import Cost, ModelMetadata, estimate_cost, resolve_model_metadata
|
|
25
25
|
from mycode.providers.base import ProviderError, StreamStartTimeoutError
|
|
26
26
|
from mycode.session import SessionStore
|
|
27
27
|
from mycode.tools import (
|
|
@@ -29,12 +29,7 @@ from mycode.tools import (
|
|
|
29
29
|
ToolExecutionResult,
|
|
30
30
|
ToolExecutor,
|
|
31
31
|
ToolSpec,
|
|
32
|
-
bash_tool,
|
|
33
|
-
cancel_all_tools,
|
|
34
|
-
edit_tool,
|
|
35
|
-
read_tool,
|
|
36
32
|
tool,
|
|
37
|
-
write_tool,
|
|
38
33
|
)
|
|
39
34
|
|
|
40
35
|
__version__ = metadata.version("mycode-sdk")
|
|
@@ -44,6 +39,7 @@ __all__ = [
|
|
|
44
39
|
"Attachment",
|
|
45
40
|
"ContentBlock",
|
|
46
41
|
"ConversationMessage",
|
|
42
|
+
"Cost",
|
|
47
43
|
"Event",
|
|
48
44
|
"AfterToolHook",
|
|
49
45
|
"BeforeToolHook",
|
|
@@ -63,16 +59,12 @@ __all__ = [
|
|
|
63
59
|
"ToolSpec",
|
|
64
60
|
"__version__",
|
|
65
61
|
"assistant_message",
|
|
66
|
-
"bash_tool",
|
|
67
62
|
"build_message",
|
|
68
63
|
"build_usage",
|
|
69
|
-
"cancel_all_tools",
|
|
70
64
|
"document_block",
|
|
71
|
-
"edit_tool",
|
|
72
65
|
"estimate_cost",
|
|
73
66
|
"flatten_message_text",
|
|
74
67
|
"image_block",
|
|
75
|
-
"read_tool",
|
|
76
68
|
"resolve_model_metadata",
|
|
77
69
|
"text_block",
|
|
78
70
|
"thinking_block",
|
|
@@ -80,5 +72,4 @@ __all__ = [
|
|
|
80
72
|
"tool_result_block",
|
|
81
73
|
"tool_use_block",
|
|
82
74
|
"user_text_message",
|
|
83
|
-
"write_tool",
|
|
84
75
|
]
|