2121"""
2222
2323import asyncio
24+ import base64
25+ import os
2426from typing import List
2527from dotenv import load_dotenv
2628
@@ -160,7 +162,7 @@ class NeoFSAgentDemo:
160162 "test_scenarios" : {
161163 "existing_containers" : [
162164 {
163- "id" : "xxxxxx " ,
165+ "id" : "GuZWKoBFg8GYCWdgHxZwVdBfdHTvNPJhvY1EHFQTCoXV " ,
164166 "name" : "demo-public-storage" ,
165167 "type" : "public" ,
166168 "acl" : "public-read-write"
@@ -249,6 +251,8 @@ def load_test_data(self):
249251
250252 def create_agent (self , name : str , tools : List , description : str ) -> ToolCallAgent :
251253 """Create a specialized agent with specific tools"""
254+ # Capture variables for closure to avoid issues with lambda
255+ agent_tools_list = tools
252256
253257 class NeoFSSpecializedAgent (ToolCallAgent ):
254258 agent_name : str = name
@@ -295,13 +299,14 @@ class NeoFSSpecializedAgent(ToolCallAgent):
295299 Explain each step clearly.
296300 """
297301 max_steps : int = 20
298- available_tools : ToolManager = Field (default_factory = lambda : ToolManager (tools ))
302+ available_tools : ToolManager = Field (default_factory = lambda : ToolManager (agent_tools_list ))
299303
300304 agent = NeoFSSpecializedAgent (
301305 llm = ChatBot (
302306 llm_provider = "openrouter" ,
303307 model_name = "openai/gpt-4o"
304- )
308+ ),
309+ available_tools = ToolManager (agent_tools_list )
305310 )
306311 return agent
307312
@@ -483,7 +488,7 @@ async def demo_public_container_workflow(self):
483488 self .print_section_header ("3. PUBLIC Container Complete Workflow" )
484489
485490 # Use PUBLIC container ID
486- public_container_id = "xxxxxxxxx "
491+ public_container_id = "xxxxxxxxxxxxxxx "
487492
488493 # Use persistent agent to remember object_id
489494 agent = self .agents ['object' ]
@@ -537,7 +542,7 @@ async def demo_eacl_container_workflow(self):
537542 self .print_section_header ("4. eACL Container Complete Workflow" )
538543
539544 # Use existing eACL container
540- eacl_container_id = "xxxxxxxxx "
545+ eacl_container_id = "xxxxxxxxxxxxxxx "
541546
542547 # Use persistent agent
543548 agent = self .agents ['access' ]
@@ -662,8 +667,8 @@ async def demo_advanced_scenarios(self):
662667 self .print_section_header ("6. Advanced Object Operations" )
663668
664669 # User-provided container IDs
665- public_container_id = "xxxxxxxxx "
666- eacl_container_id = "xxxxxxxxx "
670+ public_container_id = "xxxxxxxxxxxxxxx "
671+ eacl_container_id = "xxxxxxxxxxxxxxx "
667672
668673 # Use persistent agent
669674 agent = self .agents ['object' ]
@@ -863,6 +868,54 @@ async def demo_advanced_scenarios(self):
863868No bearer token needed for delete operation.""" )
864869 print (f"✅ Response: { response11 } " )
865870
871+ async def demo_upload_to_specific_container (self , image_path : str = None , file_name : str = None , attributes : dict = None ):
872+ """Upload image to a specific public container using agent
873+
874+ Args:
875+ image_path: Path to image file. If None, uses sample image data.
876+ file_name: File name. If None, uses default or basename of image_path.
877+ attributes: File attributes dict. If None, uses default.
878+ """
879+ self .print_section_header ("7. Upload Image to Specific Public Container" )
880+
881+ # Fixed container ID
882+ # Original: "754iyTDY8xUtZJZfheSYLUn7jvCkxr79RcbjMt81QykC" (does not exist - confirmed by tests)
883+ # Using one of your public containers instead for testing:
884+ TARGET_CONTAINER_ID = "xxxxxxxxxxxxxxx" # agent-demo-public-1760869880 (ACL: 1fbfbfff = public-read-write)
885+
886+ # Use object storage agent
887+ agent = self .agents ['object' ]
888+
889+ # Prepare image data
890+ if image_path and os .path .exists (image_path ):
891+ # Read image file and encode to base64
892+ with open (image_path , 'rb' ) as f :
893+ image_bytes = f .read ()
894+ image_base64 = base64 .b64encode (image_bytes ).decode ('utf-8' )
895+ if file_name is None :
896+ file_name = os .path .basename (image_path )
897+ ext = os .path .splitext (file_name )[1 ][1 :].lower ()
898+ content_type = f"image/{ ext } " if ext in ['png' , 'jpg' , 'jpeg' , 'gif' , 'webp' ] else "image/png"
899+ else :
900+ # Use sample image (1x1 pixel red PNG)
901+ image_base64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
902+ file_name = file_name or "demo-image.png"
903+ content_type = "image/png"
904+
905+ print (f"\n { '-' * 60 } " )
906+ print (f" Agent: { agent .agent_name } " )
907+ print (f" Scenario: Upload Image to Public Container" )
908+ print (f" Container ID: { TARGET_CONTAINER_ID } " )
909+ print (f" Image: { file_name } " )
910+ print (f" Content Type: { content_type } " )
911+ print (f"{ '-' * 60 } " )
912+
913+ # Simplified natural language prompt - let agent handle details
914+ response = await agent .run (f"""Upload an image file named "{ file_name } " ({ content_type } ) to container { TARGET_CONTAINER_ID } .
915+ The image data is: { image_base64 } .
916+ This is a public container.""" )
917+ print (f"✅ Response: { response } " )
918+
866919 async def run_comprehensive_demo (self ):
867920 """Run the complete agent-based demonstration"""
868921 print ("🚀 NeoFS Storage - AI Agent Comprehensive Demonstration" )
@@ -883,12 +936,19 @@ async def run_comprehensive_demo(self):
883936 print (f"✅ Created { len (self .agents )} specialized agents" )
884937
885938 # Run comprehensive demonstrations
886- # await self.demo_network_status()
887- # await self.demo_container_operations()
888- # await self.demo_public_container_workflow()
889- # await self.demo_eacl_container_workflow()
890- # await self.demo_access_control()
939+ await self .demo_network_status ()
940+ await self .demo_container_operations ()
941+ await self .demo_public_container_workflow ()
942+ await self .demo_eacl_container_workflow ()
943+ await self .demo_access_control ()
891944 await self .demo_advanced_scenarios ()
945+ # Test with sample image
946+ await self .demo_upload_to_specific_container ()
947+
948+ # Test with real image file if exists
949+ test_image_path = "examples/test_image.png"
950+ if os .path .exists (test_image_path ):
951+ await self .demo_upload_to_specific_container (image_path = test_image_path )
892952
893953 # Final summary
894954 self .print_section_header ("Demo Completed Successfully" )
0 commit comments