acontext 0.1.4__tar.gz → 0.1.5__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.
- {acontext-0.1.4 → acontext-0.1.5}/PKG-INFO +1 -1
- {acontext-0.1.4 → acontext-0.1.5}/pyproject.toml +1 -1
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/prompts.py +4 -1
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/sandbox.py +25 -10
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/text_editor.py +17 -4
- {acontext-0.1.4 → acontext-0.1.5}/README.md +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/__init__.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/_constants.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/_utils.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/__init__.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/base.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/disk.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/agent/skill.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/async_client.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/client.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/client_types.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/errors.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/messages.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/py.typed +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/__init__.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_disks.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_sandboxes.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_sessions.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_skills.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_tools.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/async_users.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/disks.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/sandboxes.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/sessions.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/skills.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/tools.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/resources/users.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/__init__.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/common.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/disk.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/sandbox.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/session.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/skill.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/tool.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/types/user.py +0 -0
- {acontext-0.1.4 → acontext-0.1.5}/src/acontext/uploads.py +0 -0
|
@@ -92,5 +92,8 @@ Container environment:
|
|
|
92
92
|
- Standard Unix utilities available (grep, sed, awk, etc.)
|
|
93
93
|
- Archive tools: tar, unzip, zip
|
|
94
94
|
- Additional tools: ripgrep, fd, sqlite3, jq, imagemagick
|
|
95
|
-
-
|
|
95
|
+
- You can install new packages with pip if needed (internet access is available)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
Remember to always export your artifacts at the end of your task so that the user can view them.
|
|
96
99
|
"""
|
|
@@ -10,6 +10,15 @@ from .prompts import SANDBOX_TEXT_EDITOR_REMINDER, SANDBOX_BASH_REMINDER, SKILL_
|
|
|
10
10
|
from ..client import AcontextClient
|
|
11
11
|
from ..async_client import AcontextAsyncClient
|
|
12
12
|
|
|
13
|
+
MAX_OUTPUT_CHARS = 20000
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def truncate_output(text: str, max_chars: int = MAX_OUTPUT_CHARS) -> str:
|
|
17
|
+
"""Truncate text to max_chars, appending a truncation flag if needed."""
|
|
18
|
+
if len(text) > max_chars:
|
|
19
|
+
return text[:max_chars] + "...[truncated]"
|
|
20
|
+
return text
|
|
21
|
+
|
|
13
22
|
|
|
14
23
|
class MountedSkill(TypedDict):
|
|
15
24
|
name: str
|
|
@@ -191,8 +200,8 @@ class BashTool(BaseTool):
|
|
|
191
200
|
|
|
192
201
|
return json.dumps(
|
|
193
202
|
{
|
|
194
|
-
"stdout": result.stdout,
|
|
195
|
-
"stderr": result.stderr,
|
|
203
|
+
"stdout": truncate_output(result.stdout),
|
|
204
|
+
"stderr": truncate_output(result.stderr),
|
|
196
205
|
"exit_code": result.exit_code,
|
|
197
206
|
}
|
|
198
207
|
)
|
|
@@ -213,8 +222,8 @@ class BashTool(BaseTool):
|
|
|
213
222
|
|
|
214
223
|
return json.dumps(
|
|
215
224
|
{
|
|
216
|
-
"stdout": result.stdout,
|
|
217
|
-
"stderr": result.stderr,
|
|
225
|
+
"stdout": truncate_output(result.stdout),
|
|
226
|
+
"stderr": truncate_output(result.stderr),
|
|
218
227
|
"exit_code": result.exit_code,
|
|
219
228
|
}
|
|
220
229
|
)
|
|
@@ -248,27 +257,33 @@ class TextEditorTool(BaseTool):
|
|
|
248
257
|
"command": {
|
|
249
258
|
"type": "string",
|
|
250
259
|
"enum": ["view", "create", "str_replace"],
|
|
251
|
-
"description":
|
|
260
|
+
"description": (
|
|
261
|
+
"Perform only text operations: 'view', 'create', or 'str_replace'. "
|
|
262
|
+
"Required parameters per command: "
|
|
263
|
+
"'view' requires path (view_range is optional); "
|
|
264
|
+
"'create' requires path and file_text; "
|
|
265
|
+
"'str_replace' requires path, old_str, and new_str."
|
|
266
|
+
),
|
|
252
267
|
},
|
|
253
268
|
"path": {
|
|
254
269
|
"type": "string",
|
|
255
|
-
"description": "The file path in the sandbox (e.g., '/workspace/script.py')",
|
|
270
|
+
"description": "Required for all commands. The file path in the sandbox (e.g., '/workspace/script.py')",
|
|
256
271
|
},
|
|
257
272
|
"file_text": {
|
|
258
273
|
"type": ["string", "null"],
|
|
259
|
-
"description": "
|
|
274
|
+
"description": "Required for 'create' command. The content to write to the file.",
|
|
260
275
|
},
|
|
261
276
|
"old_str": {
|
|
262
277
|
"type": ["string", "null"],
|
|
263
|
-
"description": "
|
|
278
|
+
"description": "Required for 'str_replace' command. The exact string to find and replace.",
|
|
264
279
|
},
|
|
265
280
|
"new_str": {
|
|
266
281
|
"type": ["string", "null"],
|
|
267
|
-
"description": "
|
|
282
|
+
"description": "Required for 'str_replace' command. The string to replace old_str with.",
|
|
268
283
|
},
|
|
269
284
|
"view_range": {
|
|
270
285
|
"type": ["array", "null"],
|
|
271
|
-
"description": "
|
|
286
|
+
"description": "Optional for 'view' command. An array [start_line, end_line] to view specific lines. If not provided, shows the first 200 lines.",
|
|
272
287
|
},
|
|
273
288
|
}
|
|
274
289
|
|
|
@@ -6,6 +6,15 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from .sandbox import AsyncSandboxContext, SandboxContext
|
|
8
8
|
|
|
9
|
+
MAX_CONTENT_CHARS = 20000
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def truncate_content(text: str, max_chars: int = MAX_CONTENT_CHARS) -> str:
|
|
13
|
+
"""Truncate text to max_chars, appending a truncation flag if needed."""
|
|
14
|
+
if len(text) > max_chars:
|
|
15
|
+
return text[:max_chars] + "...[truncated]"
|
|
16
|
+
return text
|
|
17
|
+
|
|
9
18
|
|
|
10
19
|
def escape_for_shell(s: str) -> str:
|
|
11
20
|
"""Escape a string for safe use in shell commands."""
|
|
@@ -53,7 +62,9 @@ def view_file(
|
|
|
53
62
|
start_line, end_line = view_range
|
|
54
63
|
cmd = f"sed -n '{start_line},{end_line}p' {escape_for_shell(path)} | nl -ba -v {start_line}"
|
|
55
64
|
else:
|
|
56
|
-
|
|
65
|
+
# Default to first 200 lines if no range specified
|
|
66
|
+
max_lines = 200
|
|
67
|
+
cmd = f"head -n {max_lines} {escape_for_shell(path)} | nl -ba"
|
|
57
68
|
start_line = 1
|
|
58
69
|
|
|
59
70
|
result = ctx.client.sandboxes.exec_command(
|
|
@@ -76,7 +87,7 @@ def view_file(
|
|
|
76
87
|
|
|
77
88
|
return {
|
|
78
89
|
"file_type": "text",
|
|
79
|
-
"content": result.stdout,
|
|
90
|
+
"content": truncate_content(result.stdout),
|
|
80
91
|
"numLines": num_lines,
|
|
81
92
|
"startLine": start_line if view_range else 1,
|
|
82
93
|
"totalLines": total_lines + 1, # wc -l doesn't count last line without newline
|
|
@@ -270,7 +281,9 @@ async def async_view_file(
|
|
|
270
281
|
start_line, end_line = view_range
|
|
271
282
|
cmd = f"sed -n '{start_line},{end_line}p' {escape_for_shell(path)} | nl -ba -v {start_line}"
|
|
272
283
|
else:
|
|
273
|
-
|
|
284
|
+
# Default to first 200 lines if no range specified
|
|
285
|
+
max_lines = 200
|
|
286
|
+
cmd = f"head -n {max_lines} {escape_for_shell(path)} | nl -ba"
|
|
274
287
|
start_line = 1
|
|
275
288
|
|
|
276
289
|
result = await ctx.client.sandboxes.exec_command(
|
|
@@ -292,7 +305,7 @@ async def async_view_file(
|
|
|
292
305
|
|
|
293
306
|
return {
|
|
294
307
|
"file_type": "text",
|
|
295
|
-
"content": result.stdout,
|
|
308
|
+
"content": truncate_content(result.stdout),
|
|
296
309
|
"numLines": num_lines,
|
|
297
310
|
"startLine": start_line if view_range else 1,
|
|
298
311
|
"totalLines": total_lines + 1,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|