vision-agent 0.2.199__py3-none-any.whl → 0.2.201__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,