vision-agent 0.2.199__py3-none-any.whl → 0.2.201__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.
@@ -0,0 +1,46 @@
1
+ CONVERSATION = """
2
+ **Role**: You are a help agent that assists users with their vision-related questions.
3
+
4
+ **Actions**:
5
+ `generate_or_edit_vision_code` - This action will generate code for the user to solve a vision task. It will also edit vision code for the user, this is useful if the user wants to modify vision-related aspects of the code such as changing the vision model or the image pre-processing steps.
6
+
7
+ `edit_code` - If the user already has code for a vision task, from a previous call to `generate_or_edit_vision_code` and wants to quickly modify the code, you can use this action to edit the code. This is good for non-vision related changes such as formatting the response as a json or removing print statements.
8
+
9
+ **Exampels**:
10
+ Here is an example of how you can interact with a user and Actions:
11
+ --- START EXAMPLES ---
12
+ USER: Can you help me write code to detect dogs in this image? Media name images/dogs.jpg
13
+
14
+ AGENT: <response>Yes, I can help you with that. I will write the code to detect dogs in the image.</response><action>generate_or_edit_vision_code</action>
15
+
16
+ OBSERVATION:
17
+ <final_code>
18
+ from vision_agent.tools import load_image, owl_v2_image
19
+ def detect_dogs(image_path: str):
20
+ image = load_image(image_path)
21
+ dogs = owl_v2_image(image)
22
+ return dogs
23
+ </final_code>
24
+ <final_test>
25
+ def test_detect_dogs():
26
+ dogs = detect_dogs("images/dogs.jpg")
27
+ assert len(dogs) > 0
28
+ </final_test>
29
+
30
+ AGENT: <response>Here is the code to detect dogs in the image.</response>
31
+
32
+ --- END EXAMPLES ---
33
+
34
+ **Conversation**:
35
+ Here is the current conversation so far:
36
+ --- START CONVERSATION ---
37
+ {conversation}
38
+ --- END CONVERSATION ---
39
+
40
+ **Instructions**:
41
+ 1. Only respond with a single <response> tag and a single <action> tag.
42
+ 2. Respond in the following format, the <action> tag is optional and can be excluded if you do not want to take any action:
43
+
44
+ <response>Your response to the user's message</response>
45
+ <action>The action you want to take from **Actions**</action>
46
+ """
@@ -0,0 +1,215 @@
1
+ import copy
2
+ from pathlib import Path
3
+ from typing import Any, Callable, Dict, List, Optional, Union, cast
4
+
5
+ from vision_agent.agent import Agent, AgentCoder, VisionAgentCoderV2
6
+ from vision_agent.agent.agent_utils import (
7
+ add_media_to_chat,
8
+ convert_message_to_agentmessage,
9
+ extract_tag,
10
+ )
11
+ from vision_agent.agent.types import AgentMessage, PlanContext
12
+ from vision_agent.agent.vision_agent_coder_v2 import format_code_context
13
+ from vision_agent.agent.vision_agent_prompts_v2 import CONVERSATION
14
+ from vision_agent.lmm import LMM, AnthropicLMM
15
+ from vision_agent.lmm.types import Message
16
+ from vision_agent.utils.execute import CodeInterpreter, CodeInterpreterFactory
17
+
18
+
19
+ def format_conversation(chat: List[AgentMessage]) -> str:
20
+ chat = copy.deepcopy(chat)
21
+ prompt = ""
22
+ for chat_i in chat:
23
+ if chat_i.role == "user":
24
+ prompt += f"USER: {chat_i.content}\n\n"
25
+ elif chat_i.role == "observation" or chat_i.role == "coder":
26
+ prompt += f"OBSERVATION: {chat_i.content}\n\n"
27
+ elif chat_i.role == "conversation":
28
+ prompt += f"AGENT: {chat_i.content}\n\n"
29
+ return prompt
30
+
31
+
32
+ def run_conversation(agent: LMM, chat: List[AgentMessage]) -> str:
33
+ # only keep last 10 messages
34
+ conv = format_conversation(chat[-10:])
35
+ prompt = CONVERSATION.format(
36
+ conversation=conv,
37
+ )
38
+ response = agent([{"role": "user", "content": prompt}], stream=False)
39
+ return cast(str, response)
40
+
41
+
42
+ def extract_conversation_for_generate_code(
43
+ chat: List[AgentMessage],
44
+ ) -> List[AgentMessage]:
45
+ chat = copy.deepcopy(chat)
46
+ extracted_chat = []
47
+ for chat_i in chat:
48
+ if chat_i.role == "user":
49
+ extracted_chat.append(chat_i)
50
+ elif chat_i.role == "coder":
51
+ if "<final_code>" in chat_i.content and "<final_test>" in chat_i.content:
52
+ extracted_chat.append(chat_i)
53
+
54
+ return extracted_chat
55
+
56
+
57
+ def maybe_run_action(
58
+ coder: AgentCoder,
59
+ action: Optional[str],
60
+ chat: List[AgentMessage],
61
+ code_interpreter: Optional[CodeInterpreter] = None,
62
+ ) -> Optional[List[AgentMessage]]:
63
+ if action == "generate_or_edit_vision_code":
64
+ extracted_chat = extract_conversation_for_generate_code(chat)
65
+ # there's an issue here because coder.generate_code will send it's code_context
66
+ # to the outside user via it's update_callback, but we don't necessarily have
67
+ # access to that update_callback here, so we re-create the message using
68
+ # format_code_context.
69
+ code_context = coder.generate_code(
70
+ extracted_chat, code_interpreter=code_interpreter
71
+ )
72
+ return [
73
+ AgentMessage(role="coder", content=format_code_context(code_context)),
74
+ AgentMessage(role="observation", content=code_context.test_result.text()),
75
+ ]
76
+ elif action == "edit_code":
77
+ extracted_chat = extract_conversation_for_generate_code(chat)
78
+ plan_context = PlanContext(
79
+ plan="Edit the latest code observed in the fewest steps possible according to the user's feedback.",
80
+ instructions=[],
81
+ code="",
82
+ )
83
+ code_context = coder.generate_code_from_plan(
84
+ extracted_chat, plan_context, code_interpreter=code_interpreter
85
+ )
86
+ return [
87
+ AgentMessage(role="coder", content=format_code_context(code_context)),
88
+ AgentMessage(role="observation", content=code_context.test_result.text()),
89
+ ]
90
+ elif action == "view_image":
91
+ pass
92
+
93
+ return None
94
+
95
+
96
+ class VisionAgentV2(Agent):
97
+ """VisionAgentV2 is a conversational agent that allows you to more easily use a
98
+ coder agent such as VisionAgentCoderV2 to write vision code for you.
99
+ """
100
+
101
+ def __init__(
102
+ self,
103
+ agent: Optional[LMM] = None,
104
+ coder: Optional[AgentCoder] = None,
105
+ verbose: bool = False,
106
+ code_sandbox_runtime: Optional[str] = None,
107
+ update_callback: Callable[[Dict[str, Any]], None] = lambda x: None,
108
+ ) -> None:
109
+ """Initialize the VisionAgentV2.
110
+
111
+ Parameters:
112
+ agent (Optional[LMM]): The language model to use for the agent. If None, a
113
+ default AnthropicLMM will be used.
114
+ coder (Optional[AgentCoder]): The coder agent to use for generating vision
115
+ code. If None, a default VisionAgentCoderV2 will be used.
116
+ verbose (bool): Whether to print out debug information.
117
+ code_sandbox_runtime (Optional[str]): The code sandbox runtime to use, can
118
+ be one of: None, "local" or "e2b". If None, it will read from the
119
+ environment variable CODE_SANDBOX_RUNTIME.
120
+ update_callback (Callable[[Dict[str, Any]], None]): The callback function
121
+ that will send back intermediate conversation messages.
122
+ """
123
+
124
+ self.agent = (
125
+ agent
126
+ if agent is not None
127
+ else AnthropicLMM(
128
+ model_name="claude-3-5-sonnet-20241022",
129
+ temperature=0.0,
130
+ )
131
+ )
132
+ self.coder = (
133
+ coder
134
+ if coder is not None
135
+ else VisionAgentCoderV2(verbose=verbose, update_callback=update_callback)
136
+ )
137
+
138
+ self.verbose = verbose
139
+ self.code_sandbox_runtime = code_sandbox_runtime
140
+ self.update_callback = update_callback
141
+
142
+ # force coder to use the same update_callback
143
+ if hasattr(self.coder, "update_callback"):
144
+ self.coder.update_callback = update_callback
145
+
146
+ def __call__(
147
+ self,
148
+ input: Union[str, List[Message]],
149
+ media: Optional[Union[str, Path]] = None,
150
+ ) -> str:
151
+ """Conversational interface to the agent. This is the main method to use to
152
+ interact with the agent. It takes in a string or list of messages and returns
153
+ the agent's response as a string.
154
+
155
+ Parameters:
156
+ input (Union[str, List[Message]]): The input to the agent. This can be a
157
+ string or a list of messages in the format of [{"role": "user",
158
+ "content": "describe your task here..."}, ...].
159
+ media (Optional[Union[str, Path]]): The path to the media file to use with
160
+ the input. This can be an image or video file.
161
+
162
+ Returns:
163
+ str: The agent's response as a string.
164
+ """
165
+
166
+ input_msg = convert_message_to_agentmessage(input, media)
167
+ return self.chat(input_msg)[-1].content
168
+
169
+ def chat(
170
+ self,
171
+ chat: List[AgentMessage],
172
+ ) -> List[AgentMessage]:
173
+ """Conversational interface to the agent. This is the main method to use to
174
+ interact with the agent. It takes in a list of messages and returns the agent's
175
+ response as a list of messages.
176
+
177
+ Parameters:
178
+ chat (List[AgentMessage]): The input to the agent. This should be a list of
179
+ AgentMessage objects.
180
+
181
+ Returns:
182
+ List[AgentMessage]: The agent's response as a list of AgentMessage objects.
183
+ """
184
+
185
+ return_chat = []
186
+ with CodeInterpreterFactory.new_instance(
187
+ self.code_sandbox_runtime
188
+ ) as code_interpreter:
189
+ int_chat, _, _ = add_media_to_chat(chat, code_interpreter)
190
+ response_context = run_conversation(self.agent, int_chat)
191
+ return_chat.append(
192
+ AgentMessage(role="conversation", content=response_context)
193
+ )
194
+ self.update_callback(return_chat[-1].model_dump())
195
+
196
+ action = extract_tag(response_context, "action")
197
+
198
+ updated_chat = maybe_run_action(
199
+ self.coder, action, int_chat, code_interpreter=code_interpreter
200
+ )
201
+ if updated_chat is not None:
202
+ # do not append updated_chat to return_chat becuase the observation
203
+ # from running the action will have already been added via the callbacks
204
+ obs_response_context = run_conversation(
205
+ self.agent, return_chat + updated_chat
206
+ )
207
+ return_chat.append(
208
+ AgentMessage(role="conversation", content=obs_response_context)
209
+ )
210
+ self.update_callback(return_chat[-1].model_dump())
211
+
212
+ return return_chat
213
+
214
+ def log_progress(self, data: Dict[str, Any]) -> None:
215
+ pass
@@ -1,7 +1,6 @@
1
1
  import difflib
2
2
  import json
3
3
  import os
4
- import pickle as pkl
5
4
  import re
6
5
  import subprocess
7
6
  import tempfile
@@ -73,95 +72,41 @@ class Artifacts:
73
72
  need to be in sync with the remote environment the VisionAgent is running in.
74
73
  """
75
74
 
76
- def __init__(
77
- self, remote_save_path: Union[str, Path], local_save_path: Union[str, Path]
78
- ) -> None:
75
+ def __init__(self, cwd: Union[str, Path]) -> None:
79
76
  """Initializes the Artifacts object with it's remote and local save paths.
80
77
 
81
78
  Parameters:
82
- remote_save_path (Union[str, Path]): The path to save the artifacts in the
83
- remote environment. For example "/home/user/artifacts.pkl".
84
- local_save_path (Union[str, Path]): The path to save the artifacts in the
85
- local environment. For example "/Users/my_user/workspace/artifacts.pkl".
79
+ cwd (Union[str, Path]): The path to save all the chat related files. For example "/home/user/chat_abc/".
86
80
  """
87
- self.remote_save_path = Path(remote_save_path)
88
- self.local_save_path = Path(local_save_path)
89
- self.artifacts: Dict[str, Any] = {}
81
+ self.cwd = Path(cwd)
90
82
 
91
- self.code_sandbox_runtime = None
92
-
93
- def load(
94
- self,
95
- artifacts_path: Union[str, Path],
96
- load_to_dir: Optional[Union[str, Path]] = None,
97
- ) -> None:
98
- """Loads are artifacts into the load_to_dir directory. If load_to_dir is None,
99
- it will load into remote_save_path directory. If an artifact value is None it
100
- will skip loading it.
101
-
102
- Parameters:
103
- artifacts_path (Union[str, Path]): The file path to load the artifacts from.
104
- If you are in the remote environment this would be remote_save_path, if
105
- you are in the local environment this would be local_save_path.
106
- load_to_dir (Optional[Union[str, Path]): The directory to load the artifacts
107
- into. If None, it will load into remote_save_path directory.
108
- """
109
- with open(artifacts_path, "rb") as f:
110
- self.artifacts = pkl.load(f)
111
-
112
- load_to_dir = (
113
- self.remote_save_path.parent if load_to_dir is None else Path(load_to_dir)
114
- )
115
-
116
- for k, v in self.artifacts.items():
117
- if v is not None:
118
- mode = "w" if isinstance(v, str) else "wb"
119
- with open(load_to_dir / k, mode) as f:
120
- f.write(v)
121
-
122
- def show(self, uploaded_file_dir: Optional[Union[str, Path]] = None) -> str:
123
- """Prints out the artifacts and the directory they have been loaded to. If you
124
- pass in upload_file_dir, it will show the artifacts have been loaded to the
125
- upload_file_dir directory. If you don't pass in upload_file_dir, it will show
126
- the artifacts have been loaded to the remote_save_path directory.
127
-
128
- Parameters:
129
- uploaded_file_dir (Optional[Union[str, Path]): The directory the artifacts
130
- have been loaded to.
131
- """
132
- loaded_path = (
133
- Path(uploaded_file_dir)
134
- if uploaded_file_dir is not None
135
- else self.remote_save_path.parent
136
- )
83
+ def show(self) -> str:
84
+ """Prints out all the files in the curret working directory"""
137
85
  output_str = "[Artifacts loaded]\n"
138
- for k in self.artifacts.keys():
139
- output_str += (
140
- f"Artifact name: {k}, loaded to path: {str(loaded_path / k)}\n"
141
- )
86
+ for k in self:
87
+ output_str += f"Artifact name: {k}, loaded to path: {str(self.cwd / k)}\n"
142
88
  output_str += "[End of artifacts]\n"
143
89
  print(output_str)
144
90
  return output_str
145
91
 
146
- def save(self, local_path: Optional[Union[str, Path]] = None) -> None:
147
- """Saves the artifacts to the local_save_path directory. If local_path is None,
148
- it will save to the local_save_path directory.
149
- """
150
- save_path = Path(local_path) if local_path is not None else self.local_save_path
151
- with open(save_path, "wb") as f:
152
- pkl.dump(self.artifacts, f)
153
-
154
92
  def __iter__(self) -> Any:
155
- return iter(self.artifacts)
93
+ return iter(os.listdir(self.cwd))
156
94
 
157
95
  def __getitem__(self, name: str) -> Any:
158
- return self.artifacts[name]
96
+ file_path = self.cwd / name
97
+ if file_path.exists():
98
+ with open(file_path, "r") as file:
99
+ return file.read()
100
+ else:
101
+ raise KeyError(f"File '{name}' not found in artifacts")
159
102
 
160
103
  def __setitem__(self, name: str, value: Any) -> None:
161
- self.artifacts[name] = value
104
+ file_path = self.cwd / name
105
+ with open(file_path, "w") as file:
106
+ file.write(value)
162
107
 
163
108
  def __contains__(self, name: str) -> bool:
164
- return name in self.artifacts
109
+ return name in os.listdir(self.cwd)
165
110
 
166
111
 
167
112
  def filter_file(file_name: Union[str, Path]) -> Tuple[bool, bool]:
@@ -175,27 +120,6 @@ def filter_file(file_name: Union[str, Path]) -> Tuple[bool, bool]:
175
120
  ), file_name_p.suffix in [".png", ".jpeg", ".jpg", ".mp4"]
176
121
 
177
122
 
178
- def capture_files_into_artifacts(artifacts: Artifacts) -> None:
179
- """This function is used to capture all files in the current directory into an
180
- artifact object. This is useful if you want to capture all files in the current
181
- directory and use them in a different environment where you don't have access to
182
- the file system.
183
-
184
- Parameters:
185
- artifact (Artifacts): The artifact object to save the files to.
186
- """
187
- for file in Path(".").glob("**/*"):
188
- usable_file, is_media = filter_file(file)
189
- mode = "rb" if is_media else "r"
190
- if usable_file:
191
- file_name = file.name
192
- if file_name.startswith(str(Path(artifacts.remote_save_path).parents)):
193
- idx = len(Path(artifacts.remote_save_path).parents)
194
- file_name = file_name[idx:]
195
- with open(file, mode) as f:
196
- artifacts[file_name] = f.read()
197
-
198
-
199
123
  # These tools are adapted from SWE-Agent https://github.com/princeton-nlp/SWE-agent
200
124
 
201
125
 
@@ -38,7 +38,7 @@ from vision_agent.utils.exceptions import (
38
38
 
39
39
  load_dotenv()
40
40
  _LOGGER = logging.getLogger(__name__)
41
- _SESSION_TIMEOUT = 600 # 10 minutes
41
+ _SESSION_TIMEOUT = 180 # 3 minutes
42
42
  WORKSPACE = Path(os.getenv("WORKSPACE", ""))
43
43
 
44
44
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vision-agent
3
- Version: 0.2.199
3
+ Version: 0.2.201
4
4
  Summary: Toolset for Vision Agent
5
5
  Author: Landing AI
6
6
  Author-email: dev@landing.ai
@@ -1,19 +1,22 @@
1
1
  vision_agent/.sim_tools/df.csv,sha256=0fmLwTDjnRTiqYwamTOdCPjruE6wZz0AVrONIPTHxZY,34086
2
2
  vision_agent/.sim_tools/embs.npy,sha256=xF8Cg7Xd09QCTySj831aL1O2_0kRNaaH8XRJIRjgWzQ,356480
3
3
  vision_agent/__init__.py,sha256=EAb4-f9iyuEYkBrX4ag1syM8Syx8118_t0R6_C34M9w,57
4
- vision_agent/agent/__init__.py,sha256=j4W3zHXKE96o93ZziY62ZBWgicLYEink1rIU3gPsfwM,548
5
- vision_agent/agent/agent.py,sha256=2cjIOxEuSJrqbfPXYoV0qER5ihXsPFCoEFJa4jpqan0,597
6
- vision_agent/agent/agent_utils.py,sha256=jDkvanBsT_ZH7MnPWP_Wa_ToPOy4hdy4kTw9FZytwwo,12765
7
- vision_agent/agent/vision_agent.py,sha256=rr1P9iTbr7OsjgMYWCeIxQYI4cLwPWia3NIMJNi-9Yo,26110
8
- vision_agent/agent/vision_agent_coder.py,sha256=waCmw_NTgsy9G-UqlRZFhsFJJVuWVrjxVnShe4Xp_lI,27743
4
+ vision_agent/agent/__init__.py,sha256=M8CffavdIh8Zh-skznLHIaQkYGCGK7vk4dq1FaVkbs4,617
5
+ vision_agent/agent/agent.py,sha256=sf8JcA3LNy_4GaS_gQb2Q-PXkl4dBuGh-7raI9KAtZo,1470
6
+ vision_agent/agent/agent_utils.py,sha256=NmrqjhSb6fpnrB8XGWtaywZjr9n89otusOZpcbWLf9k,13534
7
+ vision_agent/agent/types.py,sha256=aAd_ez1-NQh04k27cmywyOV2uA_vWWYE-Ok7zq_JoAk,1532
8
+ vision_agent/agent/vision_agent.py,sha256=I75bEU-os9Lf9OSICKfvQ_H_ftg-zOwgTwWnu41oIdo,23555
9
+ vision_agent/agent/vision_agent_coder.py,sha256=ANwUuCO4JpTYJs4s6ynSRFcdjZFUVuSoSfcqp8ZQDDQ,27451
9
10
  vision_agent/agent/vision_agent_coder_prompts.py,sha256=gPLVXQMNSzYnQYpNm0wlH_5FPkOTaFDV24bqzK3jQ40,12221
10
11
  vision_agent/agent/vision_agent_coder_prompts_v2.py,sha256=9v5HwbNidSzYUEFl6ZMniWWOmyLITM_moWLtKVaTen8,4845
11
- vision_agent/agent/vision_agent_coder_v2.py,sha256=LVV5Ij-2s03Cj27VJZI11dMKios8ALYZ4_mZTpeMDJU,10863
12
- vision_agent/agent/vision_agent_planner.py,sha256=F_5opnc0XmQmNH40rs2T7DFrai4CC6aDYe02Z8e93AM,18875
12
+ vision_agent/agent/vision_agent_coder_v2.py,sha256=SVIJC0N5TBgq9z-F99UebLimRuQuAe_HHvTFupBzVfo,14715
13
+ vision_agent/agent/vision_agent_planner.py,sha256=KWMA7XemcSmc_jn-MwdWz9wnKDtj-sYQ9tINi70_OoU,18583
13
14
  vision_agent/agent/vision_agent_planner_prompts.py,sha256=Y3jz9HRf8fz9NLUseN7cTgZqewP0RazxR7vw1sPhcn0,6691
14
- vision_agent/agent/vision_agent_planner_prompts_v2.py,sha256=PrihfrkxbeVQNzR2Vu3UwG_PRjFsjoC9IQko3WfUqPM,33143
15
- vision_agent/agent/vision_agent_planner_v2.py,sha256=11pCfaXXsivV9DKWI7nDcLf5dJV3IyHX0IR4Zn7UC9E,14288
16
- vision_agent/agent/vision_agent_prompts.py,sha256=4329ll0kqCznRALIMl-rlKWGjN92p3bcRrz8R-cO744,13748
15
+ vision_agent/agent/vision_agent_planner_prompts_v2.py,sha256=Tzon3h5iZdHJglesk8GVS-2myNf5-fhf7HUbkpZWHQk,33143
16
+ vision_agent/agent/vision_agent_planner_v2.py,sha256=mxQxD_B8sKYharh8e7W0uc1tN11YCztyLowc83seScc,17023
17
+ vision_agent/agent/vision_agent_prompts.py,sha256=PENFd8VM_vHKxeZPiotVM1RBVW9NrXimKbpvI1UteKI,13772
18
+ vision_agent/agent/vision_agent_prompts_v2.py,sha256=-vCWat-ARlCOOOeIDIFhg-kcwRRwjTXYEwsvvqPeaCs,1972
19
+ vision_agent/agent/vision_agent_v2.py,sha256=Cudp_ZZBI9rDwMjIYlvY4jzh_srsulYgfRWZLo4_2TQ,8366
17
20
  vision_agent/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
21
  vision_agent/clients/http.py,sha256=k883i6M_4nl7zwwHSI-yP5sAgQZIDPM1nrKD6YFJ3Xs,2009
19
22
  vision_agent/clients/landing_public_api.py,sha256=lU2ev6E8NICmR8DMUljuGcVFy5VNJQ4WQkWC8WnnJEc,1503
@@ -23,7 +26,7 @@ vision_agent/lmm/__init__.py,sha256=jyY1sJb_tYKg5-Wzs3p1lvwFkc-aUNZfMcLy3TOC4Zg,
23
26
  vision_agent/lmm/lmm.py,sha256=x_nIyDNDZwq4-pfjnJTmcyyJZ2_B7TjkA5jZp88YVO8,17103
24
27
  vision_agent/lmm/types.py,sha256=ZEXR_ptBL0ZwDMTDYkgxUCmSZFmBYPQd2jreNzr_8UY,221
25
28
  vision_agent/tools/__init__.py,sha256=xuNt5e4syQH28Vr6EdjLmO9ni9i00yav9yqcPMUx1oo,2878
26
- vision_agent/tools/meta_tools.py,sha256=by7TIbH7lsLIayX_Pe2mS1iw8aeLn2T8yqAo8SkB9Kg,32074
29
+ vision_agent/tools/meta_tools.py,sha256=TPeS7QWnc_PmmU_ndiDT03dXbQ5yDSP33E7U8cSj7Ls,28660
27
30
  vision_agent/tools/planner_tools.py,sha256=FROahw_6Taqvytv6pOjCHUEypOfjsi_f8Vo1c5vz6Mw,8823
28
31
  vision_agent/tools/prompts.py,sha256=V1z4YJLXZuUl_iZ5rY0M5hHc_2tmMEUKr0WocXKGt4E,1430
29
32
  vision_agent/tools/tool_utils.py,sha256=GDGOmBCo4UfYz-DJ-olREJHPsqs5mzHu0YXiAnpNE8E,10179
@@ -31,12 +34,12 @@ vision_agent/tools/tools.py,sha256=wXDs0m_Yb601FQVp5fPYYVtt4lHUeMnuqIbfDZhsE4Q,8
31
34
  vision_agent/tools/tools_types.py,sha256=8hYf2OZhI58gvf65KGaeGkt4EQ56nwLFqIQDPHioOBc,2339
32
35
  vision_agent/utils/__init__.py,sha256=7fMgbZiEwbNS0fBOS_hJI5PuEYBblw36zLi_UjUzvj4,244
33
36
  vision_agent/utils/exceptions.py,sha256=booSPSuoULF7OXRr_YbC4dtKt6gM_HyiFQHBuaW86C4,2052
34
- vision_agent/utils/execute.py,sha256=2sIQn45llOENMyrKu3TPINVRLLbOvvZ6SVHFCB9MQUo,28028
37
+ vision_agent/utils/execute.py,sha256=b3AA1G16Ixwlgd-kke13brKclxh5nJXQTrk25oj1W3o,28027
35
38
  vision_agent/utils/image_utils.py,sha256=rRWcxKggPXIRXIY_XT9rZt30ECDRq8zq7FDeXRDqQWs,11679
36
39
  vision_agent/utils/sim.py,sha256=NZc9QGD6BTY5O29NVbHH7oxDePL_QMnylT1lYcDUn1Y,7437
37
40
  vision_agent/utils/type_defs.py,sha256=BE12s3JNQy36QvauXHjwyeffVh5enfcvd4vTzSwvEZI,1384
38
41
  vision_agent/utils/video.py,sha256=tRcGp4vEnaDycigL1hBO9k0FBPtDH35fCQciVr9GqYI,6013
39
- vision_agent-0.2.199.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
40
- vision_agent-0.2.199.dist-info/METADATA,sha256=NbaPI49uOha3uZXbfOokpji32pilLujBz7DcmhaXW1M,19026
41
- vision_agent-0.2.199.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
42
- vision_agent-0.2.199.dist-info/RECORD,,
42
+ vision_agent-0.2.201.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
43
+ vision_agent-0.2.201.dist-info/METADATA,sha256=Vbdn9gqa9uz0RTRV9SMvNgPQbqLGmgQJKUtuEe1buI0,19026
44
+ vision_agent-0.2.201.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
45
+ vision_agent-0.2.201.dist-info/RECORD,,