Skip to content

Commit 9ab9e1d

Browse files
committed
fix issues with edit code
1 parent b2bcc9f commit 9ab9e1d

File tree

1 file changed

+68
-48
lines changed

1 file changed

+68
-48
lines changed

vision_agent/tools/meta_tools.py

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ def view_lines(
176176
f"[Artifact: {name} ({total_lines} lines total)]\n"
177177
+ format_lines(lines[start:end], start)
178178
+ (
179-
"[End of artifact]"
179+
"\n[End of artifact]"
180180
if end == len(lines)
181-
else f"[{len(lines) - end} more lines]"
181+
else f"\n[{len(lines) - end} more lines]"
182182
)
183183
)
184184

@@ -258,8 +258,10 @@ def edit_code_artifact(
258258
Parameters:
259259
artifacts (Artifacts): The artifacts object to edit the artifact from.
260260
name (str): The name of the artifact to edit.
261-
start (int): The line number to start the edit.
262-
end (int): The line number to end the edit.
261+
start (int): The line number to start the edit, can be in [-1, total_lines]
262+
where -1 represents the end of the file.
263+
end (int): The line number to end the edit, can be in [-1, total_lines] where
264+
-1 represents the end of the file.
263265
content (str): The content to insert.
264266
"""
265267
# just make the artifact if it doesn't exist instead of forcing agent to call
@@ -268,17 +270,21 @@ def edit_code_artifact(
268270
artifacts[name] = ""
269271

270272
total_lines = len(artifacts[name].splitlines())
271-
if start < 0 or end < 0 or start > end or end > total_lines:
273+
if start < -1 or end < -1 or start > end or end > total_lines:
272274
print("[Invalid line range]")
273275
return "[Invalid line range]"
274-
if start == end:
275-
end += 1
276+
277+
if start == -1:
278+
start = total_lines
279+
if end == -1:
280+
end = total_lines
276281

277282
new_content_lines = content.splitlines(keepends=True)
278283
new_content_lines = [
279284
line if line.endswith("\n") else line + "\n" for line in new_content_lines
280285
]
281286
lines = artifacts[name].splitlines(keepends=True)
287+
lines = [line if line.endswith("\n") else line + "\n" for line in lines]
282288
edited_lines = lines[:start] + new_content_lines + lines[end:]
283289

284290
cur_line = start + len(content.split("\n")) // 2
@@ -760,6 +766,51 @@ def use_object_detection_fine_tuning(
760766
return diff
761767

762768

769+
def _find_name(file: Path, names: List[str]) -> str:
770+
if not str(file) in names:
771+
return str(file)
772+
name = file.name
773+
suffix = file.suffix
774+
# test basic names first
775+
for i in range(100):
776+
new_name = f"{name}_output_{i}{suffix}"
777+
if new_name not in names:
778+
return new_name
779+
return f"{name}_output_{str(uuid.uuid4())}{suffix}"
780+
781+
782+
def _extract_file_names(
783+
code: str, obs: str, file_counts: Dict[str, int], existing_names: List[str]
784+
) -> Dict[str, List[str]]:
785+
try:
786+
response = extract_json(
787+
AnthropicLMM()( # type: ignore
788+
f"""You are a helpful AI assistant. You are given a number of files for certain file types, your job is to look at the code and the output of running that code and assign each file a file name. Below is the code snippet:
789+
790+
```python
791+
{code}
792+
```
793+
794+
```output
795+
{obs}
796+
```
797+
798+
Here's the number of files that need file names:
799+
{json.dumps({k: v for k, v in file_counts.items()})}
800+
801+
The name cannot conflict with any of these existing names:
802+
{str(existing_names)}
803+
804+
Return the file paths in the following JSON format:
805+
{{"png": ["image_name1.png", "other_image_name.png"], "mp4": ["video_name.mp4"]}}"""
806+
)
807+
)
808+
except json.JSONDecodeError:
809+
response = {}
810+
811+
return response
812+
813+
763814
def extract_and_save_files_to_artifacts(
764815
artifacts: Artifacts, code: str, obs: str, result: Execution
765816
) -> None:
@@ -775,8 +826,8 @@ def extract_and_save_files_to_artifacts(
775826
# file system.
776827
files = {}
777828
for res in result.results:
778-
if len(res.formats()) == 1 and res.formats()[0] in ["png", "jpeg", "mp4"]:
779-
format = res.formats()[0]
829+
if len(res.formats()) == 1 and res.formats()[0] in ["png", "jpeg", "mp4"]: # type: ignore
830+
format = res.formats()[0] # type: ignore
780831
if format == "png":
781832
data = base64.b64decode(res.png) if res.png is not None else None
782833
elif format == "jpeg":
@@ -791,50 +842,19 @@ def extract_and_save_files_to_artifacts(
791842
else:
792843
files[format].append(data)
793844

794-
try:
795-
response = extract_json(
796-
AnthropicLMM()( # type: ignore
797-
f"""You are a helpful AI assistant. You are given a number of files for certain file types, your job is to look at the code and the output of running that code and assign each file a file name. Below is the code snippet:
798-
799-
```python
800-
{code}
801-
```
802-
803-
```output
804-
{obs}
805-
```
806-
807-
Here's the number of files that need file names:
808-
{json.dumps({k: len(v) for k, v in files.items()})}
809-
810-
The name cannot conflict with any of these existing names:
811-
{json.dumps(list(artifacts.artifacts.keys()))}
812-
813-
Return the file paths in the following JSON format:
814-
{{"png": ["image_name1.png", "other_image_name.png"], "mp4": ["video_name.mp4"]}}"""
815-
)
816-
)
817-
except json.JSONDecodeError:
818-
response = {}
819-
820-
def find_name(file: Path, names: List[str]) -> str:
821-
if not str(file) in names:
822-
return str(file)
823-
name = file.name
824-
suffix = file.suffix
825-
# test basic names first
826-
for i in range(100):
827-
new_name = f"{name}_output_{i}{suffix}"
828-
if new_name not in names:
829-
return new_name
830-
return f"{name}_output_{str(uuid.uuid4())}{suffix}"
845+
response = _extract_file_names(
846+
code,
847+
obs,
848+
{k: len(v) for k, v in files.items()},
849+
list(artifacts.artifacts.keys()),
850+
)
831851

832852
for format in files.keys():
833853
i = 0
834854
if format in response:
835855
for file in response[format]:
836856
if i < len(files[format]) and files[format][i] is not None:
837-
new_name = find_name(
857+
new_name = _find_name(
838858
Path(file).with_suffix("." + format),
839859
list(artifacts.artifacts.keys()),
840860
)
@@ -844,7 +864,7 @@ def find_name(file: Path, names: List[str]) -> str:
844864
for j in range(i, len(files[format])):
845865
name = "image" if format in ["png", "jpeg"] else "video"
846866
if files[format][j] is not None:
847-
new_name = find_name(
867+
new_name = _find_name(
848868
Path(f"{name}").with_suffix("." + format),
849869
list(artifacts.artifacts.keys()),
850870
)

0 commit comments

Comments
 (0)