acontext 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.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.
acontext/agent/sandbox.py CHANGED
@@ -283,6 +283,7 @@ class TextEditorTool(BaseTool):
283
283
  },
284
284
  "view_range": {
285
285
  "type": ["array", "null"],
286
+ "items": {"type": "integer"},
286
287
  "description": "Optional for 'view' command. An array [start_line, end_line] to view specific lines. If not provided, shows the first 200 lines.",
287
288
  },
288
289
  }
@@ -1,6 +1,7 @@
1
1
  """Text editor file operations for sandbox environments."""
2
2
 
3
3
  import base64
4
+ import posixpath
4
5
  from typing import TYPE_CHECKING
5
6
 
6
7
  if TYPE_CHECKING:
@@ -41,53 +42,53 @@ def view_file(
41
42
  Returns:
42
43
  A dict with file content and metadata, or error information.
43
44
  """
44
- # First check if file exists and get total lines
45
- check_cmd = f"wc -l < {escape_for_shell(path)} 2>/dev/null || echo 'FILE_NOT_FOUND'"
46
- result = ctx.client.sandboxes.exec_command(
47
- sandbox_id=ctx.sandbox_id,
48
- command=check_cmd,
49
- timeout=timeout,
50
- )
45
+ escaped_path = escape_for_shell(path)
51
46
 
52
- if "FILE_NOT_FOUND" in result.stdout or result.exit_code != 0:
53
- return {
54
- "error": f"File not found: {path}",
55
- "stderr": result.stderr,
56
- }
57
-
58
- total_lines = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 0
59
-
60
- # Build the view command with line numbers
47
+ # Build combined command: check existence, get total lines, and view content in one exec
61
48
  if view_range and len(view_range) == 2:
62
49
  start_line, end_line = view_range
63
- cmd = f"sed -n '{start_line},{end_line}p' {escape_for_shell(path)} | nl -ba -v {start_line}"
50
+ view_cmd = (
51
+ f"sed -n '{start_line},{end_line}p' {escaped_path} | nl -ba -v {start_line}"
52
+ )
64
53
  else:
65
- # Default to first 200 lines if no range specified
66
54
  max_lines = 200
67
- cmd = f"head -n {max_lines} {escape_for_shell(path)} | nl -ba"
55
+ view_cmd = f"head -n {max_lines} {escaped_path} | nl -ba"
68
56
  start_line = 1
69
57
 
58
+ # Single combined command: outputs "TOTAL:<n>" on first line, then file content
59
+ cmd = (
60
+ f"if [ ! -f {escaped_path} ]; then echo 'FILE_NOT_FOUND'; exit 1; fi; "
61
+ f'echo "TOTAL:$(wc -l < {escaped_path})"; {view_cmd}'
62
+ )
63
+
70
64
  result = ctx.client.sandboxes.exec_command(
71
65
  sandbox_id=ctx.sandbox_id,
72
66
  command=cmd,
73
67
  timeout=timeout,
74
68
  )
75
69
 
76
- if result.exit_code != 0:
70
+ if result.exit_code != 0 or "FILE_NOT_FOUND" in result.stdout:
77
71
  return {
78
- "error": f"Failed to view file: {path}",
72
+ "error": f"File not found: {path}",
79
73
  "stderr": result.stderr,
80
74
  }
81
75
 
82
- # Count lines in output
83
- content_lines = (
84
- result.stdout.rstrip("\n").split("\n") if result.stdout.strip() else []
85
- )
76
+ # Parse output: first line is "TOTAL:<n>", rest is content
77
+ lines = result.stdout.split("\n", 1)
78
+ total_lines = 0
79
+ content = ""
80
+
81
+ if lines and lines[0].startswith("TOTAL:"):
82
+ total_str = lines[0][6:].strip()
83
+ total_lines = int(total_str) if total_str.isdigit() else 0
84
+ content = lines[1] if len(lines) > 1 else ""
85
+
86
+ content_lines = content.rstrip("\n").split("\n") if content.strip() else []
86
87
  num_lines = len(content_lines)
87
88
 
88
89
  return {
89
90
  "file_type": "text",
90
- "content": truncate_content(result.stdout),
91
+ "content": truncate_content(content),
91
92
  "numLines": num_lines,
92
93
  "startLine": start_line if view_range else 1,
93
94
  "totalLines": total_lines + 1, # wc -l doesn't count last line without newline
@@ -108,41 +109,35 @@ def create_file(
108
109
  Returns:
109
110
  A dict with creation status or error information.
110
111
  """
111
- # Check if file already exists
112
- check_cmd = f"test -f {escape_for_shell(path)} && echo 'EXISTS' || echo 'NEW'"
113
- check_result = ctx.client.sandboxes.exec_command(
114
- sandbox_id=ctx.sandbox_id,
115
- command=check_cmd,
116
- timeout=timeout,
117
- )
118
- is_update = "EXISTS" in check_result.stdout
119
-
120
- # Create directory if needed
121
- dir_path = "/".join(path.split("/")[:-1])
122
- if dir_path:
123
- mkdir_cmd = f"mkdir -p {escape_for_shell(dir_path)}"
124
- ctx.client.sandboxes.exec_command(
125
- sandbox_id=ctx.sandbox_id,
126
- command=mkdir_cmd,
127
- timeout=timeout,
128
- )
129
-
130
- # Write file using base64 encoding to safely transfer content
112
+ escaped_path = escape_for_shell(path)
131
113
  encoded_content = base64.b64encode(file_text.encode()).decode()
132
- write_cmd = f"echo {escape_for_shell(encoded_content)} | base64 -d > {escape_for_shell(path)}"
114
+
115
+ # Get directory path for mkdir
116
+ dir_path = posixpath.dirname(path)
117
+ mkdir_part = f"mkdir -p {escape_for_shell(dir_path)} && " if dir_path else ""
118
+
119
+ # Single combined command: check existence, create dir, write file
120
+ cmd = (
121
+ f"is_update=$(test -f {escaped_path} && echo 1 || echo 0); "
122
+ f"{mkdir_part}"
123
+ f"echo {escape_for_shell(encoded_content)} | base64 -d > {escaped_path} && "
124
+ f'echo "STATUS:$is_update"'
125
+ )
133
126
 
134
127
  result = ctx.client.sandboxes.exec_command(
135
128
  sandbox_id=ctx.sandbox_id,
136
- command=write_cmd,
129
+ command=cmd,
137
130
  timeout=timeout,
138
131
  )
139
132
 
140
- if result.exit_code != 0:
133
+ if result.exit_code != 0 or "STATUS:" not in result.stdout:
141
134
  return {
142
135
  "error": f"Failed to create file: {path}",
143
136
  "stderr": result.stderr,
144
137
  }
145
138
 
139
+ is_update = "STATUS:1" in result.stdout
140
+
146
141
  return {
147
142
  "is_file_update": is_update,
148
143
  "message": f"File {'updated' if is_update else 'created'}: {path}",
@@ -154,6 +149,9 @@ def str_replace(
154
149
  ) -> dict:
155
150
  """Replace a string in a file.
156
151
 
152
+ Uses a Python script on the sandbox to avoid transferring the entire file.
153
+ Only the base64-encoded old_str and new_str are sent.
154
+
157
155
  Args:
158
156
  ctx: The sandbox context.
159
157
  path: The file path to modify.
@@ -162,85 +160,62 @@ def str_replace(
162
160
  timeout: Optional timeout for command execution.
163
161
 
164
162
  Returns:
165
- A dict with diff information or error details.
163
+ A dict with success message or error details.
166
164
  """
167
- # First read the file content
168
- read_cmd = f"cat {escape_for_shell(path)}"
165
+ old_b64 = base64.b64encode(old_str.encode()).decode()
166
+ new_b64 = base64.b64encode(new_str.encode()).decode()
167
+
168
+ # Write Python script to a temp file and execute it
169
+ # This avoids shell escaping issues with inline python -c
170
+ py_script = f'''import sys, base64, os
171
+ old = base64.b64decode("{old_b64}").decode()
172
+ new = base64.b64decode("{new_b64}").decode()
173
+ path = "{path}"
174
+ if not os.path.exists(path):
175
+ print("FILE_NOT_FOUND")
176
+ sys.exit(1)
177
+ with open(path, "r") as f:
178
+ content = f.read()
179
+ count = content.count(old)
180
+ if count == 0:
181
+ print("NOT_FOUND")
182
+ sys.exit(0)
183
+ if count > 1:
184
+ print(f"MULTIPLE:{{count}}")
185
+ sys.exit(0)
186
+ with open(path, "w") as f:
187
+ f.write(content.replace(old, new, 1))
188
+ print("SUCCESS")
189
+ '''
190
+ # Base64 encode the script itself to avoid any escaping issues
191
+ script_b64 = base64.b64encode(py_script.encode()).decode()
192
+ cmd = f"echo {escape_for_shell(script_b64)} | base64 -d | python3"
193
+
169
194
  result = ctx.client.sandboxes.exec_command(
170
195
  sandbox_id=ctx.sandbox_id,
171
- command=read_cmd,
196
+ command=cmd,
172
197
  timeout=timeout,
173
198
  )
174
199
 
175
- if result.exit_code != 0:
176
- return {
177
- "error": f"File not found: {path}",
178
- "stderr": result.stderr,
179
- }
180
-
181
- original_content = result.stdout
182
-
183
- # Check if old_str exists in the file
184
- if old_str not in original_content:
185
- return {
186
- "error": f"String not found in file: {old_str[:50]}...",
187
- }
188
-
189
- # Count occurrences
190
- occurrences = original_content.count(old_str)
191
- if occurrences > 1:
192
- return {
193
- "error": f"Multiple occurrences ({occurrences}) of the string found. Please provide more context to make the match unique.",
194
- }
195
-
196
- # Perform the replacement
197
- new_content = original_content.replace(old_str, new_str, 1)
198
-
199
- # Find the line numbers affected
200
- old_lines = original_content.split("\n")
201
- new_lines = new_content.split("\n")
200
+ output = result.stdout.strip()
202
201
 
203
- # Find where the change starts
204
- old_start = 1
205
- for i, (old_line, new_line) in enumerate(zip(old_lines, new_lines)):
206
- if old_line != new_line:
207
- old_start = i + 1
208
- break
202
+ if result.exit_code != 0 or output == "FILE_NOT_FOUND":
203
+ return {"error": f"File not found: {path}", "stderr": result.stderr}
209
204
 
210
- # Write the new content
211
- encoded_content = base64.b64encode(new_content.encode()).decode()
212
- write_cmd = f"echo {escape_for_shell(encoded_content)} | base64 -d > {escape_for_shell(path)}"
205
+ if output == "NOT_FOUND":
206
+ return {"error": f"String not found in file: {old_str[:50]}..."}
213
207
 
214
- result = ctx.client.sandboxes.exec_command(
215
- sandbox_id=ctx.sandbox_id,
216
- command=write_cmd,
217
- timeout=timeout,
218
- )
219
-
220
- if result.exit_code != 0:
208
+ if output.startswith("MULTIPLE:"):
209
+ count = output.split(":")[1]
221
210
  return {
222
- "error": f"Failed to write file: {path}",
223
- "stderr": result.stderr,
211
+ "error": f"Multiple occurrences ({count}) of the string found. "
212
+ "Please provide more context to make the match unique."
224
213
  }
225
214
 
226
- # Calculate diff info
227
- old_str_lines = old_str.count("\n") + 1
228
- new_str_lines = new_str.count("\n") + 1
215
+ if output == "SUCCESS":
216
+ return {"msg": "Successfully replaced text at exactly one location."}
229
217
 
230
- # Build diff lines
231
- diff_lines = []
232
- for line in old_str.split("\n"):
233
- diff_lines.append(f"-{line}")
234
- for line in new_str.split("\n"):
235
- diff_lines.append(f"+{line}")
236
-
237
- return {
238
- "oldStart": old_start,
239
- "oldLines": old_str_lines,
240
- "newStart": old_start,
241
- "newLines": new_str_lines,
242
- "lines": diff_lines,
243
- }
218
+ return {"error": f"Unexpected response: {output}", "stderr": result.stderr}
244
219
 
245
220
 
246
221
  # ============================================================================
@@ -249,7 +224,10 @@ def str_replace(
249
224
 
250
225
 
251
226
  async def async_view_file(
252
- ctx: "AsyncSandboxContext", path: str, view_range: list | None, timeout: float | None
227
+ ctx: "AsyncSandboxContext",
228
+ path: str,
229
+ view_range: list | None,
230
+ timeout: float | None,
253
231
  ) -> dict:
254
232
  """View file content with line numbers (async).
255
233
 
@@ -262,50 +240,53 @@ async def async_view_file(
262
240
  Returns:
263
241
  A dict with file content and metadata, or error information.
264
242
  """
265
- check_cmd = f"wc -l < {escape_for_shell(path)} 2>/dev/null || echo 'FILE_NOT_FOUND'"
266
- result = await ctx.client.sandboxes.exec_command(
267
- sandbox_id=ctx.sandbox_id,
268
- command=check_cmd,
269
- timeout=timeout,
270
- )
271
-
272
- if "FILE_NOT_FOUND" in result.stdout or result.exit_code != 0:
273
- return {
274
- "error": f"File not found: {path}",
275
- "stderr": result.stderr,
276
- }
277
-
278
- total_lines = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 0
243
+ escaped_path = escape_for_shell(path)
279
244
 
245
+ # Build combined command: check existence, get total lines, and view content in one exec
280
246
  if view_range and len(view_range) == 2:
281
247
  start_line, end_line = view_range
282
- cmd = f"sed -n '{start_line},{end_line}p' {escape_for_shell(path)} | nl -ba -v {start_line}"
248
+ view_cmd = (
249
+ f"sed -n '{start_line},{end_line}p' {escaped_path} | nl -ba -v {start_line}"
250
+ )
283
251
  else:
284
- # Default to first 200 lines if no range specified
285
252
  max_lines = 200
286
- cmd = f"head -n {max_lines} {escape_for_shell(path)} | nl -ba"
253
+ view_cmd = f"head -n {max_lines} {escaped_path} | nl -ba"
287
254
  start_line = 1
288
255
 
256
+ # Single combined command: outputs "TOTAL:<n>" on first line, then file content
257
+ cmd = (
258
+ f"if [ ! -f {escaped_path} ]; then echo 'FILE_NOT_FOUND'; exit 1; fi; "
259
+ f'echo "TOTAL:$(wc -l < {escaped_path})"; {view_cmd}'
260
+ )
261
+
289
262
  result = await ctx.client.sandboxes.exec_command(
290
263
  sandbox_id=ctx.sandbox_id,
291
264
  command=cmd,
292
265
  timeout=timeout,
293
266
  )
294
267
 
295
- if result.exit_code != 0:
268
+ if result.exit_code != 0 or "FILE_NOT_FOUND" in result.stdout:
296
269
  return {
297
- "error": f"Failed to view file: {path}",
270
+ "error": f"File not found: {path}",
298
271
  "stderr": result.stderr,
299
272
  }
300
273
 
301
- content_lines = (
302
- result.stdout.rstrip("\n").split("\n") if result.stdout.strip() else []
303
- )
274
+ # Parse output: first line is "TOTAL:<n>", rest is content
275
+ lines = result.stdout.split("\n", 1)
276
+ total_lines = 0
277
+ content = ""
278
+
279
+ if lines and lines[0].startswith("TOTAL:"):
280
+ total_str = lines[0][6:].strip()
281
+ total_lines = int(total_str) if total_str.isdigit() else 0
282
+ content = lines[1] if len(lines) > 1 else ""
283
+
284
+ content_lines = content.rstrip("\n").split("\n") if content.strip() else []
304
285
  num_lines = len(content_lines)
305
286
 
306
287
  return {
307
288
  "file_type": "text",
308
- "content": truncate_content(result.stdout),
289
+ "content": truncate_content(content),
309
290
  "numLines": num_lines,
310
291
  "startLine": start_line if view_range else 1,
311
292
  "totalLines": total_lines + 1,
@@ -326,38 +307,35 @@ async def async_create_file(
326
307
  Returns:
327
308
  A dict with creation status or error information.
328
309
  """
329
- check_cmd = f"test -f {escape_for_shell(path)} && echo 'EXISTS' || echo 'NEW'"
330
- check_result = await ctx.client.sandboxes.exec_command(
331
- sandbox_id=ctx.sandbox_id,
332
- command=check_cmd,
333
- timeout=timeout,
334
- )
335
- is_update = "EXISTS" in check_result.stdout
336
-
337
- dir_path = "/".join(path.split("/")[:-1])
338
- if dir_path:
339
- mkdir_cmd = f"mkdir -p {escape_for_shell(dir_path)}"
340
- await ctx.client.sandboxes.exec_command(
341
- sandbox_id=ctx.sandbox_id,
342
- command=mkdir_cmd,
343
- timeout=timeout,
344
- )
345
-
310
+ escaped_path = escape_for_shell(path)
346
311
  encoded_content = base64.b64encode(file_text.encode()).decode()
347
- write_cmd = f"echo {escape_for_shell(encoded_content)} | base64 -d > {escape_for_shell(path)}"
312
+
313
+ # Get directory path for mkdir
314
+ dir_path = posixpath.dirname(path)
315
+ mkdir_part = f"mkdir -p {escape_for_shell(dir_path)} && " if dir_path else ""
316
+
317
+ # Single combined command: check existence, create dir, write file
318
+ cmd = (
319
+ f"is_update=$(test -f {escaped_path} && echo 1 || echo 0); "
320
+ f"{mkdir_part}"
321
+ f"echo {escape_for_shell(encoded_content)} | base64 -d > {escaped_path} && "
322
+ f'echo "STATUS:$is_update"'
323
+ )
348
324
 
349
325
  result = await ctx.client.sandboxes.exec_command(
350
326
  sandbox_id=ctx.sandbox_id,
351
- command=write_cmd,
327
+ command=cmd,
352
328
  timeout=timeout,
353
329
  )
354
330
 
355
- if result.exit_code != 0:
331
+ if result.exit_code != 0 or "STATUS:" not in result.stdout:
356
332
  return {
357
333
  "error": f"Failed to create file: {path}",
358
334
  "stderr": result.stderr,
359
335
  }
360
336
 
337
+ is_update = "STATUS:1" in result.stdout
338
+
361
339
  return {
362
340
  "is_file_update": is_update,
363
341
  "message": f"File {'updated' if is_update else 'created'}: {path}",
@@ -365,10 +343,17 @@ async def async_create_file(
365
343
 
366
344
 
367
345
  async def async_str_replace(
368
- ctx: "AsyncSandboxContext", path: str, old_str: str, new_str: str, timeout: float | None
346
+ ctx: "AsyncSandboxContext",
347
+ path: str,
348
+ old_str: str,
349
+ new_str: str,
350
+ timeout: float | None,
369
351
  ) -> dict:
370
352
  """Replace a string in a file (async).
371
353
 
354
+ Uses a Python script on the sandbox to avoid transferring the entire file.
355
+ Only the base64-encoded old_str and new_str are sent.
356
+
372
357
  Args:
373
358
  ctx: The async sandbox context.
374
359
  path: The file path to modify.
@@ -377,73 +362,59 @@ async def async_str_replace(
377
362
  timeout: Optional timeout for command execution.
378
363
 
379
364
  Returns:
380
- A dict with diff information or error details.
365
+ A dict with success message or error details.
381
366
  """
382
- read_cmd = f"cat {escape_for_shell(path)}"
367
+ old_b64 = base64.b64encode(old_str.encode()).decode()
368
+ new_b64 = base64.b64encode(new_str.encode()).decode()
369
+
370
+ # Write Python script to a temp file and execute it
371
+ # This avoids shell escaping issues with inline python -c
372
+ py_script = f'''import sys, base64, os
373
+ old = base64.b64decode("{old_b64}").decode()
374
+ new = base64.b64decode("{new_b64}").decode()
375
+ path = "{path}"
376
+ if not os.path.exists(path):
377
+ print("FILE_NOT_FOUND")
378
+ sys.exit(1)
379
+ with open(path, "r") as f:
380
+ content = f.read()
381
+ count = content.count(old)
382
+ if count == 0:
383
+ print("NOT_FOUND")
384
+ sys.exit(0)
385
+ if count > 1:
386
+ print(f"MULTIPLE:{{count}}")
387
+ sys.exit(0)
388
+ with open(path, "w") as f:
389
+ f.write(content.replace(old, new, 1))
390
+ print("SUCCESS")
391
+ '''
392
+ # Base64 encode the script itself to avoid any escaping issues
393
+ script_b64 = base64.b64encode(py_script.encode()).decode()
394
+ cmd = f"echo {escape_for_shell(script_b64)} | base64 -d | python3"
395
+
383
396
  result = await ctx.client.sandboxes.exec_command(
384
397
  sandbox_id=ctx.sandbox_id,
385
- command=read_cmd,
398
+ command=cmd,
386
399
  timeout=timeout,
387
400
  )
388
401
 
389
- if result.exit_code != 0:
390
- return {
391
- "error": f"File not found: {path}",
392
- "stderr": result.stderr,
393
- }
394
-
395
- original_content = result.stdout
396
-
397
- if old_str not in original_content:
398
- return {
399
- "error": f"String not found in file: {old_str[:50]}...",
400
- }
401
-
402
- occurrences = original_content.count(old_str)
403
- if occurrences > 1:
404
- return {
405
- "error": f"Multiple occurrences ({occurrences}) of the string found. Please provide more context to make the match unique.",
406
- }
407
-
408
- new_content = original_content.replace(old_str, new_str, 1)
409
-
410
- old_lines = original_content.split("\n")
411
- new_lines = new_content.split("\n")
402
+ output = result.stdout.strip()
412
403
 
413
- old_start = 1
414
- for i, (old_line, new_line) in enumerate(zip(old_lines, new_lines)):
415
- if old_line != new_line:
416
- old_start = i + 1
417
- break
404
+ if result.exit_code != 0 or output == "FILE_NOT_FOUND":
405
+ return {"error": f"File not found: {path}", "stderr": result.stderr}
418
406
 
419
- encoded_content = base64.b64encode(new_content.encode()).decode()
420
- write_cmd = f"echo {escape_for_shell(encoded_content)} | base64 -d > {escape_for_shell(path)}"
407
+ if output == "NOT_FOUND":
408
+ return {"error": f"String not found in file: {old_str[:50]}..."}
421
409
 
422
- result = await ctx.client.sandboxes.exec_command(
423
- sandbox_id=ctx.sandbox_id,
424
- command=write_cmd,
425
- timeout=timeout,
426
- )
427
-
428
- if result.exit_code != 0:
410
+ if output.startswith("MULTIPLE:"):
411
+ count = output.split(":")[1]
429
412
  return {
430
- "error": f"Failed to write file: {path}",
431
- "stderr": result.stderr,
413
+ "error": f"Multiple occurrences ({count}) of the string found. "
414
+ "Please provide more context to make the match unique."
432
415
  }
433
416
 
434
- old_str_lines = old_str.count("\n") + 1
435
- new_str_lines = new_str.count("\n") + 1
417
+ if output == "SUCCESS":
418
+ return {"msg": "Successfully replaced text at exactly one location."}
436
419
 
437
- diff_lines = []
438
- for line in old_str.split("\n"):
439
- diff_lines.append(f"-{line}")
440
- for line in new_str.split("\n"):
441
- diff_lines.append(f"+{line}")
442
-
443
- return {
444
- "oldStart": old_start,
445
- "oldLines": old_str_lines,
446
- "newStart": old_start,
447
- "newLines": new_str_lines,
448
- "lines": diff_lines,
449
- }
420
+ return {"error": f"Unexpected response: {output}", "stderr": result.stderr}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: acontext
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: Python SDK for the Acontext API
5
5
  Keywords: acontext,sdk,client,api
6
6
  Requires-Dist: httpx>=0.28.1
@@ -5,9 +5,9 @@ acontext/agent/__init__.py,sha256=lx5HqeVDfIxkbGfAt0ju8hkk8EPsgFvKmMrQzjNXR8w,21
5
5
  acontext/agent/base.py,sha256=BDTqfqkPrPzvQIH_llOX6S_bkcDw3E30J5x9yd47Q6g,3526
6
6
  acontext/agent/disk.py,sha256=q-3DRkLcQLfdAXADJM3GPo6reWPzhKQrnyBiZdBZvIY,22775
7
7
  acontext/agent/prompts.py,sha256=awhYYClNAROnTAfzKKD8G5gHfTFs-1KqMUEWCEnlMMQ,4954
8
- acontext/agent/sandbox.py,sha256=cu51v6UanCG2BlgVJ9ee_YQHAsEzYUea2lbWd4EmHzM,18970
8
+ acontext/agent/sandbox.py,sha256=ziGGs2yqJaik_9o7S3f9G-CzcndmRs9fC3WDUi_UGbI,19016
9
9
  acontext/agent/skill.py,sha256=uB7teH7OAk4Cy6pOLRCJFBi5KZbyMMgZSLEt77TLB20,12880
10
- acontext/agent/text_editor.py,sha256=ysfMWjPuCrSG2p2Iu2rBlverxpGH_cOuvC7LK-vfIhU,13772
10
+ acontext/agent/text_editor.py,sha256=mrUtMfAtgpOOwYnh2xQpWRc0lCoE9u2_WMTVRuFiWRQ,13390
11
11
  acontext/async_client.py,sha256=WjqW7ruMtlYTBlk6PQ1-1yhjFSBBxGqI3oxrfEqqIpQ,8471
12
12
  acontext/client.py,sha256=XggELxXU9-8BcAcHOoiqQZypfPmkhe7SyJ3plHq-A9M,8217
13
13
  acontext/client_types.py,sha256=oR6lSDMjEERx0mIVOpKaTXbEu_lfoxe3fDpzA-ALE-8,1063
@@ -36,6 +36,6 @@ acontext/types/skill.py,sha256=v7OAvtkwTeZAkLG7NQMcwFoSJ4g-HDWjPZ4EoMyU3mk,2779
36
36
  acontext/types/tool.py,sha256=UlX6JIGRKd96vPayOkyi6pGwFi6w9GwWwAxr4BcqVts,670
37
37
  acontext/types/user.py,sha256=dBzHCqULSJ3Sqw7T8nA0U8Sctz76Pd0hm1qsHvtEIBQ,1264
38
38
  acontext/uploads.py,sha256=6twnqQOY_eerNuEjeSKsE_3S0IfJUiczXtAy4aXqDl8,1379
39
- acontext-0.1.5.dist-info/WHEEL,sha256=XV0cjMrO7zXhVAIyyc8aFf1VjZ33Fen4IiJk5zFlC3g,80
40
- acontext-0.1.5.dist-info/METADATA,sha256=7lm7p6PBr7kGaaDhyovfXm-_HECCrjP6MevRXCFa4E8,888
41
- acontext-0.1.5.dist-info/RECORD,,
39
+ acontext-0.1.6.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
40
+ acontext-0.1.6.dist-info/METADATA,sha256=xUgSw00x4t4EHQR7WLgfwlnjEgXJjD1LH2mk4t_KKSo,888
41
+ acontext-0.1.6.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.9.26
2
+ Generator: uv 0.9.27
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any