hmgill commited on
Commit
13f99ed
Β·
verified Β·
1 Parent(s): 931b3fb

Update agents/agent.py

Browse files
Files changed (1) hide show
  1. agents/agent.py +46 -29
agents/agent.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- CellposeAgent with optimized image attachment - only attaches when visual inspection is needed
3
  """
4
  import torch
5
  import json
@@ -23,8 +23,8 @@ class CellposeAgent:
23
  @staticmethod
24
  def attach_images_callback(step_log: ActionStep, agent: ToolCallingAgent) -> None:
25
  """
26
- OPTIMIZED: Only attach images for visual refinement step to save tokens.
27
- For all other steps, skip image attachment - images are accessible via file paths.
28
  """
29
  if not isinstance(step_log, ActionStep):
30
  return
@@ -72,19 +72,44 @@ class CellposeAgent:
72
  try:
73
  obs_data = json.loads(step_log.observations)
74
 
75
- # ONLY attach images for visual refinement step
76
- if obs_data.get("status") == "ready_for_visual_analysis":
77
- segmented = obs_data.get("image_paths", {}).get("segmented")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  if segmented:
80
- print(f"[Callback] Attaching segmented image for visual analysis: {segmented}")
81
  try:
82
  seg_img = Image.open(segmented)
83
 
84
  # Compress the segmented image
85
  compressed_seg = resize_and_compress_image(seg_img, max_size=512, quality=75)
86
 
87
- # Attach the segmented image
88
  step_log.observations_images = [compressed_seg]
89
 
90
  obs_data["images_info"] = {
@@ -98,10 +123,6 @@ class CellposeAgent:
98
  print(f"[Callback] βœ“ Attached compressed segmented image for VLM inspection")
99
  except Exception as e:
100
  print(f"[Callback] Error attaching segmented image: {e}")
101
- else:
102
- # For all other steps, explicitly skip image attachment to save tokens
103
- step_log.observations_images = []
104
- print(f"[Callback] Skipped image attachment (not a refinement step) to save tokens")
105
 
106
  except json.JSONDecodeError:
107
  pass
@@ -112,20 +133,18 @@ class CellposeAgent:
112
  @staticmethod
113
  def manage_image_memory(step_log: ActionStep, agent: ToolCallingAgent) -> None:
114
  """
115
- Aggressive memory management: clear ALL images from ALL previous steps.
116
- Use empty list instead of None for more reliable cleanup.
117
  """
118
  if not isinstance(step_log, ActionStep):
119
  return
120
 
121
- # Clear images from ALL previous steps (more aggressive)
122
  for previous_step in agent.memory.steps:
123
  if isinstance(previous_step, ActionStep):
124
- if previous_step.observations_images is not None and len(previous_step.observations_images) > 0:
125
  print(f" [Memory] Clearing images from step {previous_step.step_number}")
126
- previous_step.observations_images = [] # Empty list, not None
127
-
128
- # Try to clear any cached references (defensive)
129
  if hasattr(previous_step, '_observations_images'):
130
  previous_step._observations_images = []
131
 
@@ -138,9 +157,8 @@ class CellposeAgent:
138
  When a user provides an image:
139
  1. use appropriate tools to review which cellpose-sam parameters are available.
140
  2. use the tool: `get_segmentation_parameters`
141
- - **IMPORTANT**: You will receive image metadata (dimensions, properties, statistics)
142
- - The actual image file is accessible via the file path in the response
143
- - Use the metadata to reason about appropriate parameter values
144
  3. carefully analyze the image metadata and matched parameters:
145
  - consider cell density based on image dimensions
146
  - compare matched parameter values to image characteristics
@@ -149,9 +167,8 @@ class CellposeAgent:
149
  5. Provide your final parameter recommendations in a clear, structured format
150
  6. Use the parameters to run cellpose_sam through the tool: run_cellpose_sam
151
  7. after run_cellpose_sam, call the tool: refine_cellpose_sam_segmentation
152
- - **IMPORTANT**: After this tool runs, you WILL SEE the SEGMENTED image (colored masks overlay)
153
- - This is the ONLY step where you can visually inspect the actual image
154
- - Visually assess the segmentation quality - are cells properly detected and separated?
155
  - Use the visual analysis checklist provided in the tool output
156
  8. Based on visual analysis of the segmented image:
157
  - Assess if cell boundaries are accurate
@@ -162,10 +179,10 @@ class CellposeAgent:
162
  - Decide which parameters to adjust based on what you observe
163
  - Re-run run_cellpose_sam with adjusted parameters
164
 
165
- **CRITICAL: Call refine_cellpose_sam_segmentation AT MOST 2 TIMES total**
166
  - First call: Check initial segmentation quality
167
  - Second call (if needed): Verify refinement improved results
168
- - NEVER call it a third time - always stop after 2 refinement checks
169
 
170
  ## DOCUMENTATION QUERY WORKFLOW ##
171
  - "What is X": use `search_documentation_vector`
@@ -177,7 +194,7 @@ class CellposeAgent:
177
  - Be concise and actionable
178
  - Always explain your reasoning when adjusting parameters
179
  - If keeping original matched parameters, briefly confirm why it's appropriate
180
- - Base your decisions on visual observation of the segmented output (when available in refinement step)
181
 
182
  **CRITICAL - Final Response Format:**
183
  When segmentation is complete, you MUST provide a comprehensive text summary that includes:
@@ -213,7 +230,7 @@ class CellposeAgent:
213
  return InferenceClientModel(
214
  model_id=settings.AGENT_MODEL_ID,
215
  token=settings.HF_TOKEN,
216
- timeout=180 # 3 minutes timeout for API calls
217
  )
218
 
219
 
 
1
  """
2
+ CellposeAgent with proper VLM configuration and JPEG compression for API payload optimization
3
  """
4
  import torch
5
  import json
 
23
  @staticmethod
24
  def attach_images_callback(step_log: ActionStep, agent: ToolCallingAgent) -> None:
25
  """
26
+ Callback to attach actual PIL images for VLM inspection.
27
+ Images are automatically resized and compressed to reduce token consumption.
28
  """
29
  if not isinstance(step_log, ActionStep):
30
  return
 
72
  try:
73
  obs_data = json.loads(step_log.observations)
74
 
75
+ # Pattern 1: Single image from get_segmentation_parameters
76
+ if obs_data.get("status") == "success" and "image_path" in obs_data:
77
+ image_path = obs_data["image_path"]
78
+ print(f"[Callback] Attaching image: {image_path}")
79
+
80
+ try:
81
+ img = Image.open(image_path)
82
+ compressed_img = resize_and_compress_image(img, max_size=512, quality=75)
83
+
84
+ # Attach compressed PIL Image
85
+ step_log.observations_images = [compressed_img]
86
+
87
+ # Keep metadata for context
88
+ obs_data["image_info"] = {
89
+ "original_dimensions": f"{img.size[0]}x{img.size[1]} pixels",
90
+ "processed_dimensions": f"{compressed_img.size[0]}x{compressed_img.size[1]} pixels",
91
+ "mode": compressed_img.mode,
92
+ "note": "Image compressed for API efficiency (JPEG quality=75)"
93
+ }
94
+ step_log.observations = json.dumps(obs_data, indent=2)
95
+ print(f"[Callback] βœ“ Attached compressed image for VLM inspection")
96
+ except Exception as e:
97
+ print(f"[Callback] Error attaching image: {e}")
98
+
99
+ # Pattern 2: Segmented image ONLY from refine_segmentation
100
+ elif obs_data.get("status") == "ready_for_visual_analysis":
101
+ paths = obs_data.get("image_paths", {})
102
+ segmented = paths.get("segmented")
103
 
104
  if segmented:
105
+ print(f"[Callback] Attaching segmented image only: {segmented}")
106
  try:
107
  seg_img = Image.open(segmented)
108
 
109
  # Compress the segmented image
110
  compressed_seg = resize_and_compress_image(seg_img, max_size=512, quality=75)
111
 
112
+ # Attach only the segmented image
113
  step_log.observations_images = [compressed_seg]
114
 
115
  obs_data["images_info"] = {
 
123
  print(f"[Callback] βœ“ Attached compressed segmented image for VLM inspection")
124
  except Exception as e:
125
  print(f"[Callback] Error attaching segmented image: {e}")
 
 
 
 
126
 
127
  except json.JSONDecodeError:
128
  pass
 
133
  @staticmethod
134
  def manage_image_memory(step_log: ActionStep, agent: ToolCallingAgent) -> None:
135
  """
136
+ Clear images from ALL previous steps at the START of each new step.
 
137
  """
138
  if not isinstance(step_log, ActionStep):
139
  return
140
 
141
+ # Clear ALL previous step images immediately
142
  for previous_step in agent.memory.steps:
143
  if isinstance(previous_step, ActionStep):
144
+ if previous_step.observations_images is not None:
145
  print(f" [Memory] Clearing images from step {previous_step.step_number}")
146
+ previous_step.observations_images = [] # Use empty list instead of None
147
+ # Also try to clear any cached references
 
148
  if hasattr(previous_step, '_observations_images'):
149
  previous_step._observations_images = []
150
 
 
157
  When a user provides an image:
158
  1. use appropriate tools to review which cellpose-sam parameters are available.
159
  2. use the tool: `get_segmentation_parameters`
160
+ - **IMPORTANT**: After this tool runs, you will receive image metadata (dimensions, properties)
161
+ - Use this information to reason about appropriate parameter values
 
162
  3. carefully analyze the image metadata and matched parameters:
163
  - consider cell density based on image dimensions
164
  - compare matched parameter values to image characteristics
 
167
  5. Provide your final parameter recommendations in a clear, structured format
168
  6. Use the parameters to run cellpose_sam through the tool: run_cellpose_sam
169
  7. after run_cellpose_sam, call the tool: refine_cellpose_sam_segmentation
170
+ - **IMPORTANT**: After this tool runs, you will see the SEGMENTED image (colored masks overlay)
171
+ - Visually inspect the segmentation quality - are cells properly detected and separated?
 
172
  - Use the visual analysis checklist provided in the tool output
173
  8. Based on visual analysis of the segmented image:
174
  - Assess if cell boundaries are accurate
 
179
  - Decide which parameters to adjust based on what you observe
180
  - Re-run run_cellpose_sam with adjusted parameters
181
 
182
+ **CRITICAL: Call refine_cellpose_sam_segmentation AT MOST 1 TIMES total**
183
  - First call: Check initial segmentation quality
184
  - Second call (if needed): Verify refinement improved results
185
+ - NEVER call it a second time - always stop after 1 refinement check
186
 
187
  ## DOCUMENTATION QUERY WORKFLOW ##
188
  - "What is X": use `search_documentation_vector`
 
194
  - Be concise and actionable
195
  - Always explain your reasoning when adjusting parameters
196
  - If keeping original matched parameters, briefly confirm why it's appropriate
197
+ - Base your decisions on visual observation of the segmented output
198
 
199
  **CRITICAL - Final Response Format:**
200
  When segmentation is complete, you MUST provide a comprehensive text summary that includes:
 
230
  return InferenceClientModel(
231
  model_id=settings.AGENT_MODEL_ID,
232
  token=settings.HF_TOKEN,
233
+ timeout=240 # 3 minutes timeout for API calls
234
  )
235
 
236