From 30854527cddd7cffddf3b97791ffc1acd72dda94 Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Tue, 12 Nov 2024 12:53:07 +0100 Subject: [PATCH] wip --- .../example_agent/workspace/index.html | 39 ------ .../example_agent/workspace/reset.css | 1 - .../example_agent/workspace/styles.css | 1 - agentpress/response_processor.py | 4 +- agentpress/thread_manager.py | 124 +++++++++++------- state.json | 12 +- 6 files changed, 76 insertions(+), 105 deletions(-) delete mode 100644 agentpress/examples/example_agent/workspace/index.html delete mode 100644 agentpress/examples/example_agent/workspace/reset.css delete mode 100644 agentpress/examples/example_agent/workspace/styles.css diff --git a/agentpress/examples/example_agent/workspace/index.html b/agentpress/examples/example_agent/workspace/index.html deleted file mode 100644 index 68a4ef6e..00000000 --- a/agentpress/examples/example_agent/workspace/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - Modern Landing Page - - - - -
- - -
- -
-
-
-

Transform Your Digital Experience

-

Innovative solutions for modern challenges. Simplify, streamline, and succeed.

- Get Started -
-
-
- - - - \ No newline at end of file diff --git a/agentpress/examples/example_agent/workspace/reset.css b/agentpress/examples/example_agent/workspace/reset.css deleted file mode 100644 index a41bb483..00000000 --- a/agentpress/examples/example_agent/workspace/reset.css +++ /dev/null @@ -1 +0,0 @@ -*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}body{line-height:1.6;font-family:'-apple-system','BlinkMacSystemFont','Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Open Sans','Helvetica Neue',sans-serif}img{max-width:100%;height:auto}a{text-decoration:none;color:inherit} \ No newline at end of file diff --git a/agentpress/examples/example_agent/workspace/styles.css b/agentpress/examples/example_agent/workspace/styles.css deleted file mode 100644 index e2a480bd..00000000 --- a/agentpress/examples/example_agent/workspace/styles.css +++ /dev/null @@ -1 +0,0 @@ -:root{--primary-color:#3498db;--secondary-color:#2ecc71;--text-color:#333;--background-color:#f4f4f4}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;color:var(--text-color);background-color:var(--background-color)}.container{max-width:1200px;margin:0 auto;padding:0 15px}.header{display:flex;justify-content:space-between;align-items:center;padding:20px 0;background-color:white;box-shadow:0 2px 4px rgba(0,0,0,0.1)}.header-logo{font-size:24px;font-weight:bold;color:var(--primary-color)}.nav-links{display:flex;list-style:none;gap:20px}.nav-links a{color:var(--text-color);transition:color 0.3s ease}.nav-links a:hover{color:var(--primary-color)}.hero{display:flex;align-items:center;min-height:70vh;background:linear-gradient(135deg,var(--primary-color),var(--secondary-color));color:white;text-align:center}.hero-content{max-width:800px;margin:0 auto;padding:40px 20px}.hero-title{font-size:48px;margin-bottom:20px;font-weight:bold}.hero-subtitle{font-size:24px;margin-bottom:30px;opacity:0.9}.cta-button{display:inline-block;background-color:white;color:var(--primary-color);padding:12px 30px;border-radius:5px;font-weight:bold;transition:transform 0.3s ease}.cta-button:hover{transform:scale(1.05)}.footer{background-color:#333;color:white;text-align:center;padding:20px;margin-top:40px}.footer-content{max-width:800px;margin:0 auto}@media screen and (max-width:768px){.header{flex-direction:column;text-align:center}.nav-links{margin-top:15px}.hero{text-align:center}.hero-title{font-size:36px}.hero-subtitle{font-size:20px}} \ No newline at end of file diff --git a/agentpress/response_processor.py b/agentpress/response_processor.py index 2b9dae85..85113b89 100644 --- a/agentpress/response_processor.py +++ b/agentpress/response_processor.py @@ -1,5 +1,5 @@ +import logging from typing import Dict, Any, AsyncGenerator, Callable -import json from agentpress.tool_executor import ToolExecutor from agentpress.tool_parser import ToolParser @@ -50,7 +50,7 @@ class LLMResponseProcessor: self, response_stream: AsyncGenerator, execute_tools: bool = True, - immediate_execution: bool = True # Renamed from execute_tools_immediately + immediate_execution: bool = True ) -> AsyncGenerator: """ Process streaming LLM response and handle tool execution. diff --git a/agentpress/thread_manager.py b/agentpress/thread_manager.py index 6c570a0b..e985fc95 100644 --- a/agentpress/thread_manager.py +++ b/agentpress/thread_manager.py @@ -350,73 +350,95 @@ if __name__ == "__main__": from agentpress.examples.example_agent.tools.files_tool import FilesTool async def main(): - manager = ThreadManager() - manager.add_tool(FilesTool, ['create_file']) - thread_id = await manager.create_thread() + # Initialize managers + thread_manager = ThreadManager() + + # Register available tools + thread_manager.add_tool(FilesTool) + + # Create a new thread + thread_id = await thread_manager.create_thread() # Add a test message - await manager.add_message(thread_id, { + await thread_manager.add_message(thread_id, { "role": "user", "content": "Please create 10x files – Each should be a chapter of a book about an Introduction to Robotics.." }) + # Define system message system_message = { "role": "system", "content": "You are a helpful assistant that can create, read, update, and delete files." } - model_name = "anthropic/claude-3-5-haiku-latest" - # model_name = "gpt-4o-mini" - - # Test with tools (non-streaming) - print("\n🤖 Testing non-streaming response with tools:") - response = await manager.run_thread( + + # Test with streaming response and tool execution + print("\n🤖 Testing streaming response with tools:") + response = await thread_manager.run_thread( thread_id=thread_id, system_message=system_message, - model_name=model_name, + model_name="anthropic/claude-3-5-haiku-latest", temperature=0.7, - stream=False, + max_tokens=4096, + stream=True, use_tools=True, - execute_tool_calls=True + execute_tools=True, + immediate_tool_execution=True, + parallel_tool_execution=False ) - - # Print the non-streaming response - if "error" in response: - print(f"Error: {response['message']}") + + # Handle streaming response + if isinstance(response, AsyncGenerator): + print("\nAssistant is responding:") + content_buffer = "" + try: + async for chunk in response: + if hasattr(chunk.choices[0], 'delta'): + delta = chunk.choices[0].delta + + # Handle content streaming + if hasattr(delta, 'content') and delta.content is not None: + content_buffer += delta.content + if delta.content.endswith((' ', '\n')): + print(content_buffer, end='', flush=True) + content_buffer = "" + + # Handle tool calls + if hasattr(delta, 'tool_calls') and delta.tool_calls: + for tool_call in delta.tool_calls: + # Print tool name when it first appears + if tool_call.function and tool_call.function.name: + print(f"\n🛠️ Tool Call: {tool_call.function.name}", flush=True) + + # Print arguments as they stream in + if tool_call.function and tool_call.function.arguments: + print(f" {tool_call.function.arguments}", end='', flush=True) + + # Print any remaining content + if content_buffer: + print(content_buffer, flush=True) + print("\n✨ Response completed\n") + + except Exception as e: + print(f"\n❌ Error processing stream: {e}") else: - print(response["llm_response"].choices[0].message.content) - print("\n✨ Response completed.\n") + # Handle non-streaming response + print("\nAssistant response:") + if hasattr(response.choices[0], 'message'): + message = response.choices[0].message + if message.content: + print(message.content) + if hasattr(message, 'tool_calls') and message.tool_calls: + for tool_call in message.tool_calls: + print(f"\n🛠️ Tool Call: {tool_call.function.name}") + print(f" Arguments: {tool_call.function.arguments}") + print("\n✨ Response completed\n") - # Test streaming - print("\n🤖 Testing streaming response:") - stream_response = await manager.run_thread( - thread_id=thread_id, - system_message=system_message, - model_name=model_name, - temperature=0.7, - stream=True, - use_tools=True, - execute_tool_calls=True, - execute_tools_on_stream=True - ) - - buffer = "" - async for chunk in stream_response: - if isinstance(chunk, dict) and 'choices' in chunk: - content = chunk['choices'][0]['delta'].get('content', '') - else: - # For non-dict responses (like ModelResponse objects) - content = chunk.choices[0].delta.content - - if content: - buffer += content - # Print complete words/sentences when we hit whitespace - if content[-1].isspace(): - print(buffer, end='', flush=True) - buffer = "" - - # Print any remaining content - if buffer: - print(buffer, flush=True) - print("\n✨ Stream completed.\n") + # Display final thread state + messages = await thread_manager.list_messages(thread_id) + print("\n📝 Final Thread State:") + for msg in messages: + role = msg.get('role', 'unknown') + content = msg.get('content', '') + print(f"\n{role.upper()}: {content[:100]}...") asyncio.run(main()) diff --git a/state.json b/state.json index 1a7c1001..5cc232f0 100644 --- a/state.json +++ b/state.json @@ -1,13 +1,3 @@ { - "files": { - "index.html": { - "content": "\n\n\n \n \n Modern Landing Page\n \n \n\n\n
\n
YourBrand
\n \n
\n\n
\n
\n
\n

Transform Your Digital Experience

\n

Innovative solutions for modern challenges. Simplify, streamline, and succeed.

\n Get Started\n
\n
\n
\n\n \n\n" - }, - "reset.css": { - "content": "*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}body{line-height:1.6;font-family:'-apple-system','BlinkMacSystemFont','Segoe UI','Roboto','Oxygen','Ubuntu','Cantarell','Open Sans','Helvetica Neue',sans-serif}img{max-width:100%;height:auto}a{text-decoration:none;color:inherit}" - }, - "styles.css": { - "content": ":root{--primary-color:#3498db;--secondary-color:#2ecc71;--text-color:#333;--background-color:#f4f4f4}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;color:var(--text-color);background-color:var(--background-color)}.container{max-width:1200px;margin:0 auto;padding:0 15px}.header{display:flex;justify-content:space-between;align-items:center;padding:20px 0;background-color:white;box-shadow:0 2px 4px rgba(0,0,0,0.1)}.header-logo{font-size:24px;font-weight:bold;color:var(--primary-color)}.nav-links{display:flex;list-style:none;gap:20px}.nav-links a{color:var(--text-color);transition:color 0.3s ease}.nav-links a:hover{color:var(--primary-color)}.hero{display:flex;align-items:center;min-height:70vh;background:linear-gradient(135deg,var(--primary-color),var(--secondary-color));color:white;text-align:center}.hero-content{max-width:800px;margin:0 auto;padding:40px 20px}.hero-title{font-size:48px;margin-bottom:20px;font-weight:bold}.hero-subtitle{font-size:24px;margin-bottom:30px;opacity:0.9}.cta-button{display:inline-block;background-color:white;color:var(--primary-color);padding:12px 30px;border-radius:5px;font-weight:bold;transition:transform 0.3s ease}.cta-button:hover{transform:scale(1.05)}.footer{background-color:#333;color:white;text-align:center;padding:20px;margin-top:40px}.footer-content{max-width:800px;margin:0 auto}@media screen and (max-width:768px){.header{flex-direction:column;text-align:center}.nav-links{margin-top:15px}.hero{text-align:center}.hero-title{font-size:36px}.hero-subtitle{font-size:20px}}" - } - } + "files": {} } \ No newline at end of file