skydeckai-code 0.1.34__py3-none-any.whl → 0.1.36__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.
@@ -17,31 +17,43 @@ from .state import state
17
17
  def read_file_tool():
18
18
  return {
19
19
  "name": "read_file",
20
- "description": "Read the contents of a file from the file system. "
21
- "WHEN TO USE: When you need to examine the actual content of a single file, view source code, check configuration files, or analyze text data. "
20
+ "description": "Read the contents of one or more files from the file system. "
21
+ "WHEN TO USE: When you need to examine the actual content of one or more files, view source code, check configuration files, or analyze text data. "
22
22
  "This is the primary tool for accessing file contents directly. "
23
23
  "WHEN NOT TO USE: When you only need file metadata like size or modification date (use get_file_info instead), when you need to list directory contents "
24
- "(use directory_listing instead), or when you need to read multiple files at once (use read_multiple_files instead). "
25
- "RETURNS: The complete text content of the specified file or the requested portion if offset/limit are specified. Binary files or files with unknown encodings will return an error message. "
26
- "Handles various text encodings and provides detailed error messages if the file cannot be read. Only works within the allowed directory. "
27
- "Example: Enter 'src/main.py' to read a Python file, or add offset/limit to read specific line ranges.",
24
+ "(use directory_listing instead). "
25
+ "RETURNS: The complete text content of the specified file(s) or the requested portion if offset/limit are specified. Binary files or files with unknown encodings will return an error message. "
26
+ "Each file's content is preceded by a header showing the file path (==> path/to/file <==). "
27
+ "Handles various text encodings and provides detailed error messages if a file cannot be read. Only works within the allowed directory. "
28
+ "Example: Use 'files: [{\"path\": \"src/main.py\"}]' to read a Python file, or add offset/limit to read specific line ranges. "
29
+ "For multiple files, use 'files: [{\"path\": \"file1.txt\"}, {\"path\": \"file2.txt\"}]' with optional offset/limit for each file.",
28
30
  "inputSchema": {
29
31
  "type": "object",
30
32
  "properties": {
31
- "path": {
32
- "type": "string",
33
- "description": "Path to the file to read. This must be a path to a file, not a directory. Examples: 'README.md', 'src/main.py', 'config.json'. Both absolute and relative paths are supported, but must be within the allowed workspace."
34
- },
35
- "offset": {
36
- "type": "integer",
37
- "description": "Line number to start reading from (1-indexed). If specified, the file will be read starting from this line. Default is to start from the beginning of the file.",
38
- },
39
- "limit": {
40
- "type": "integer",
41
- "description": "Maximum number of lines to read after the offset. If specified along with offset, only this many lines will be read. Default is to read to the end of the file.",
33
+ "files": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "properties": {
38
+ "path": {
39
+ "type": "string",
40
+ "description": "Path to the file to read. This must be a path to a file, not a directory. Examples: 'README.md', 'src/main.py', 'config.json'. Both absolute and relative paths are supported, but must be within the allowed workspace."
41
+ },
42
+ "offset": {
43
+ "type": "integer",
44
+ "description": "Line number to start reading from (1-indexed). If specified, the file will be read starting from this line. Default is to start from the beginning of the file."
45
+ },
46
+ "limit": {
47
+ "type": "integer",
48
+ "description": "Maximum number of lines to read after the offset. If specified along with offset, only this many lines will be read. Default is to read to the end of the file."
49
+ }
50
+ },
51
+ "required": ["path"]
52
+ },
53
+ "description": "List of files to read with optional offset and limit for each file."
42
54
  }
43
55
  },
44
- "required": ["path"]
56
+ "required": ["files"]
45
57
  },
46
58
  }
47
59
 
@@ -214,31 +226,6 @@ def delete_file_tool():
214
226
  },
215
227
  }
216
228
 
217
- def read_multiple_files_tool():
218
- return {
219
- "name": "read_multiple_files",
220
- "description": "Read the contents of multiple files simultaneously. "
221
- "WHEN TO USE: When you need to examine or compare multiple files at once, analyze related files together, or gather content from several files efficiently. "
222
- "Useful for understanding code across multiple files, comparing configuration files, or collecting information from related documents. "
223
- "WHEN NOT TO USE: When you only need to read a single file (use read_file instead), when you need to read binary files or images (use read_image_file instead), "
224
- "or when you need metadata about files rather than their contents (use get_file_info instead). "
225
- "RETURNS: The contents of all specified files, with each file's content preceded by a header showing its path (==> path/to/file <==). "
226
- "If an individual file cannot be read, an error message is included in its place, but the operation continues for other files. "
227
- "Failed reads for individual files won't stop the entire operation. Only works within the allowed directory. "
228
- "Example: Enter ['src/main.py', 'README.md'] to read both files.",
229
- "inputSchema": {
230
- "type": "object",
231
- "properties": {
232
- "paths": {
233
- "type": "array",
234
- "items": {"type": "string"},
235
- "description": "List of file paths to read. Must contain at least one path. Each path should point to a text file. Examples: ['README.md', 'package.json'], ['src/main.py', 'src/utils.py', 'config.ini']. Both absolute and relative paths are supported, but must be within the allowed workspace.",
236
- }
237
- },
238
- "required": ["paths"]
239
- },
240
- }
241
-
242
229
  def edit_file_tool():
243
230
  return {
244
231
  "name": "edit_file",
@@ -395,41 +382,43 @@ async def handle_write_file(arguments: dict):
395
382
  raise ValueError(f"Error writing file: {str(e)}")
396
383
 
397
384
  async def handle_read_file(arguments: dict):
398
- path = arguments.get("path")
399
- if not path:
400
- raise ValueError("path must be provided")
401
-
402
- # Get the line range parameters
403
- offset = arguments.get("offset")
404
- limit = arguments.get("limit")
405
-
406
- return await _read_single_file(path, offset, limit)
407
-
408
- async def handle_read_multiple_files(arguments: dict):
409
- paths = arguments.get("paths", [])
410
- if not isinstance(paths, list):
411
- raise ValueError("paths must be a list of strings")
412
- if not all(isinstance(p, str) for p in paths):
413
- raise ValueError("all paths must be strings")
414
- if not paths:
415
- raise ValueError("paths list cannot be empty")
416
-
385
+ files = arguments.get("files")
386
+ if not files:
387
+ raise ValueError("files must be provided")
388
+ if not isinstance(files, list):
389
+ raise ValueError("files must be an array")
390
+ if not files:
391
+ raise ValueError("files array cannot be empty")
392
+
393
+ # Validate each file entry
394
+ for file_entry in files:
395
+ if not isinstance(file_entry, dict):
396
+ raise ValueError("each file entry must be an object")
397
+ if "path" not in file_entry:
398
+ raise ValueError("each file entry must have a path property")
399
+
400
+ # Read each file with its own offset/limit
417
401
  results = []
418
- for path in paths:
402
+ for file_entry in files:
403
+ path = file_entry.get("path")
404
+ offset = file_entry.get("offset")
405
+ limit = file_entry.get("limit")
406
+
419
407
  try:
420
408
  # Add file path header first
421
409
  results.append(TextContent(
422
410
  type="text",
423
411
  text=f"\n==> {path} <==\n"
424
412
  ))
425
- # Then add file contents
426
- file_contents = await _read_single_file(path)
413
+ # Then add file contents with specific offset/limit
414
+ file_contents = await _read_single_file(path, offset, limit)
427
415
  results.extend(file_contents)
428
416
  except Exception as e:
429
417
  results.append(TextContent(
430
418
  type="text",
431
419
  text=f"Error: {str(e)}\n"
432
420
  ))
421
+
433
422
  return results
434
423
 
435
424
  async def handle_move_file(arguments: dict):