17
17
Any ,
18
18
Dict ,
19
19
List ,
20
- Literal ,
21
20
Optional ,
22
21
Tuple ,
23
22
Type ,
28
27
29
28
import jsonpatch
30
29
from botocore .config import Config
31
- from PIL import Image , ImageEnhance , ImageOps
30
+ from PIL import Image
32
31
from pydantic import BaseModel , Field
33
32
from strands import Agent , tool
34
33
from strands .models .bedrock import BedrockModel
@@ -215,81 +214,6 @@ def apply_json_patches(
215
214
return extraction_tool , apply_json_patches
216
215
217
216
218
- @tool
219
- def load_image (image_index : int , agent : Agent ) -> Image .Image :
220
- """
221
- Load an image from state as a PIL Image for viewing and analysis.
222
-
223
- Args:
224
- image_index: Index of the image to load (0-based)
225
-
226
- Returns:
227
- PIL Image object
228
- """
229
- images = agent .state .get ("images" )
230
- if not images or str (image_index ) not in images :
231
- raise ValueError (f"Image index { image_index } does not exist" )
232
-
233
- image_data = images [str (image_index )]
234
- if isinstance (image_data , str ):
235
- # Convert binary string back to PIL Image
236
- import base64
237
-
238
- img_bytes = base64 .b64decode (image_data )
239
- return Image .open (io .BytesIO (img_bytes ))
240
- else :
241
- # Legacy support for direct PIL images
242
- return image_data
243
-
244
-
245
- @tool
246
- def enhance_image (
247
- image_index : int ,
248
- enhancement_type : Literal ["brightness" , "contrast" , "sharpen" , "grayscale" ],
249
- agent : Agent ,
250
- factor : float = 1.5 ,
251
- ) -> str :
252
- """
253
- Apply image enhancement for better extraction accuracy.
254
-
255
- Args:
256
- image_index: Index of the image to enhance (0-based)
257
- enhancement_type: Type of enhancement (brightness, contrast, sharpen, grayscale)
258
- factor: Enhancement factor (for brightness/contrast)
259
- """
260
- try :
261
- # Load the image
262
- image = load_image (image_index , agent )
263
-
264
- # Apply enhancement
265
- if enhancement_type == "brightness" :
266
- enhancer = ImageEnhance .Brightness (image )
267
- enhanced = enhancer .enhance (factor )
268
- elif enhancement_type == "contrast" :
269
- enhancer = ImageEnhance .Contrast (image )
270
- enhanced = enhancer .enhance (factor )
271
- elif enhancement_type == "sharpen" :
272
- enhancer = ImageEnhance .Sharpness (image )
273
- enhanced = enhancer .enhance (factor )
274
- elif enhancement_type == "grayscale" :
275
- enhanced = ImageOps .grayscale (image )
276
-
277
- # Convert enhanced image back to binary string and store
278
- img_buffer = io .BytesIO ()
279
- enhanced .save (img_buffer , format = "PNG" )
280
-
281
- img_binary = base64 .b64encode (img_buffer .getvalue ()).decode ("utf-8" )
282
-
283
- images = agent .state .get ("images" )
284
- images [str (image_index )] = img_binary
285
- agent .state .set (key = "images" , value = images )
286
-
287
- return f"Applied { enhancement_type } to image { image_index } "
288
-
289
- except Exception as e :
290
- return f"Error enhancing image { image_index } : { str (e )} "
291
-
292
-
293
217
SYSTEM_PROMPT = """
294
218
You are a useful assistant that helps turn unstructured data into structured data using the provided tools.
295
219
@@ -317,7 +241,6 @@ def enhance_image(
317
241
4. Verify that all characters and formatting are preserved exactly as they appear
318
242
5. When fixing errors, use JSON patches to target specific problems
319
243
320
- Use load_image tool to view images when needed for better accuracy.
321
244
322
245
FINAL REVIEW (CRITICAL):
323
246
After successfully using the extraction tool, you MUST:
@@ -334,7 +257,6 @@ async def structured_output_async(
334
257
model_id : str ,
335
258
data_format : Type [TargetModel ],
336
259
prompt : Union [str , Message , Image .Image ],
337
- enable_image_tools : bool = True ,
338
260
existing_data : Optional [BaseModel ] = None ,
339
261
system_prompt : str | None = None ,
340
262
custom_instruction : str | None = None ,
@@ -425,9 +347,7 @@ async def structured_output_async(
425
347
)
426
348
427
349
# Prepare tools list
428
- tools = [extraction_tool , apply_json_patches , load_image ]
429
- if enable_image_tools :
430
- tools .append (enhance_image )
350
+ tools = [extraction_tool , apply_json_patches ]
431
351
432
352
# Create agent with system prompt and tools
433
353
schema_json = json .dumps (data_format .model_json_schema (), indent = 2 )
@@ -654,7 +574,6 @@ def structured_output(
654
574
model_id : str ,
655
575
data_format : Type [BaseModel ],
656
576
prompt : Union [str , Message , Image .Image ],
657
- enable_image_tools : bool = True ,
658
577
existing_data : Optional [BaseModel ] = None ,
659
578
system_prompt : str | None = None ,
660
579
custom_instruction : str | None = None ,
@@ -682,7 +601,6 @@ def structured_output(
682
601
model_id: Model identifier (e.g., "us.anthropic.claude-sonnet-4-20250514-v1:0")
683
602
data_format: Pydantic model class defining the expected structure
684
603
prompt: Input content (text, image, or content blocks)
685
- enable_image_tools: Whether to enable image enhancement tools (default: True)
686
604
existing_data: Optional existing data to update via patches
687
605
system_prompt: **DISCOURAGED** - Custom system prompt. Only use if the default
688
606
SYSTEM_PROMPT is completely unsuitable for your use case.
@@ -738,7 +656,6 @@ def run_in_new_loop():
738
656
model_id = model_id ,
739
657
data_format = data_format ,
740
658
prompt = prompt ,
741
- enable_image_tools = enable_image_tools ,
742
659
existing_data = existing_data ,
743
660
system_prompt = system_prompt ,
744
661
custom_instruction = custom_instruction ,
@@ -770,7 +687,6 @@ def run_in_new_loop():
770
687
model_id = model_id ,
771
688
data_format = data_format ,
772
689
prompt = prompt ,
773
- enable_image_tools = enable_image_tools ,
774
690
existing_data = existing_data ,
775
691
system_prompt = system_prompt ,
776
692
custom_instruction = custom_instruction ,
0 commit comments