mirror of https://github.com/kortix-ai/suna.git
wip
This commit is contained in:
parent
3c0634f6bc
commit
cfb3e561ed
|
@ -36,6 +36,9 @@ You have access to these tools through XML-based tool calling:
|
||||||
- idle: A special tool to indicate you have completed all tasks and are entering idle state
|
- idle: A special tool to indicate you have completed all tasks and are entering idle state
|
||||||
</available_tools>
|
</available_tools>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
RESPONSE_FORMAT = """
|
||||||
<response_format>
|
<response_format>
|
||||||
RESPONSE FORMAT – STRICTLY Output XML tags for tool calling
|
RESPONSE FORMAT – STRICTLY Output XML tags for tool calling
|
||||||
|
|
||||||
|
@ -79,4 +82,4 @@ def get_system_prompt():
|
||||||
'''
|
'''
|
||||||
Returns the system prompt with XML tool usage instructions.
|
Returns the system prompt with XML tool usage instructions.
|
||||||
'''
|
'''
|
||||||
return SYSTEM_PROMPT
|
return SYSTEM_PROMPT + RESPONSE_FORMAT
|
|
@ -1,331 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>My Portfolio</title>
|
|
||||||
<link rel="stylesheet" href="styles.css">
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<div class="container">
|
|
||||||
<h1 class="logo">My Portfolio</h1>
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#home">Home</a></li>
|
|
||||||
<li><a href="#about">About</a></li>
|
|
||||||
<li><a href="#skills">Skills</a></li>
|
|
||||||
<li><a href="#projects">Projects</a></li>
|
|
||||||
<li><a href="#contact">Contact</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
<div class="hamburger">
|
|
||||||
<div class="bar"></div>
|
|
||||||
<div class="bar"></div>
|
|
||||||
<div class="bar"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<section id="home" class="hero">
|
|
||||||
<div class="container">
|
|
||||||
<div class="hero-content">
|
|
||||||
<h1>Hello, I'm <span class="highlight">Your Name</span></h1>
|
|
||||||
<p class="tagline">Web Developer & Designer</p>
|
|
||||||
<div class="cta-buttons">
|
|
||||||
<a href="#projects" class="btn primary-btn">View My Work</a>
|
|
||||||
<a href="#contact" class="btn secondary-btn">Contact Me</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="about" class="about">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="section-title">About Me</h2>
|
|
||||||
<div class="about-content">
|
|
||||||
<div class="about-image">
|
|
||||||
<div class="image-placeholder">
|
|
||||||
<i class="fas fa-user"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="about-text">
|
|
||||||
<p>Hello! I'm a passionate web developer with a keen eye for design and a love for creating seamless user experiences. With a background in [Your Background], I bring a unique perspective to every project I work on.</p>
|
|
||||||
<p>I enjoy solving complex problems and turning ideas into reality through clean and efficient code. When I'm not coding, you can find me [Your Hobbies/Interests].</p>
|
|
||||||
<div class="about-details">
|
|
||||||
<div class="detail">
|
|
||||||
<i class="fas fa-graduation-cap"></i>
|
|
||||||
<span>Education: [Your Education]</span>
|
|
||||||
</div>
|
|
||||||
<div class="detail">
|
|
||||||
<i class="fas fa-briefcase"></i>
|
|
||||||
<span>Experience: [Years] years</span>
|
|
||||||
</div>
|
|
||||||
<div class="detail">
|
|
||||||
<i class="fas fa-map-marker-alt"></i>
|
|
||||||
<span>Location: [Your Location]</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="#" class="btn primary-btn">Download Resume</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="skills" class="skills">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="section-title">My Skills</h2>
|
|
||||||
<div class="skills-content">
|
|
||||||
<div class="skill-category">
|
|
||||||
<h3>Frontend Development</h3>
|
|
||||||
<div class="skills-grid">
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fab fa-html5"></i></div>
|
|
||||||
<h4>HTML5</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 90%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fab fa-css3-alt"></i></div>
|
|
||||||
<h4>CSS3</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 85%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fab fa-js"></i></div>
|
|
||||||
<h4>JavaScript</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 80%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fab fa-react"></i></div>
|
|
||||||
<h4>React</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 75%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skill-category">
|
|
||||||
<h3>Other Skills</h3>
|
|
||||||
<div class="skills-grid">
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fas fa-database"></i></div>
|
|
||||||
<h4>SQL</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 70%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fab fa-git-alt"></i></div>
|
|
||||||
<h4>Git</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 85%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fas fa-mobile-alt"></i></div>
|
|
||||||
<h4>Responsive Design</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 90%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="skill-item">
|
|
||||||
<div class="skill-icon"><i class="fas fa-paint-brush"></i></div>
|
|
||||||
<h4>UI/UX</h4>
|
|
||||||
<div class="skill-bar">
|
|
||||||
<div class="skill-level" style="width: 75%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="projects" class="projects">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="section-title">My Projects</h2>
|
|
||||||
<div class="project-filters">
|
|
||||||
<button class="filter-btn active" data-filter="all">All</button>
|
|
||||||
<button class="filter-btn" data-filter="web">Web Development</button>
|
|
||||||
<button class="filter-btn" data-filter="design">Design</button>
|
|
||||||
<button class="filter-btn" data-filter="other">Other</button>
|
|
||||||
</div>
|
|
||||||
<div class="projects-grid">
|
|
||||||
<div class="project-card" data-category="web">
|
|
||||||
<div class="project-image">
|
|
||||||
<div class="image-placeholder">
|
|
||||||
<i class="fas fa-laptop-code"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="project-info">
|
|
||||||
<h3>Project Title 1</h3>
|
|
||||||
<p>A brief description of the project and your role in it. Explain the technologies used and the problems solved.</p>
|
|
||||||
<div class="project-tags">
|
|
||||||
<span>HTML</span>
|
|
||||||
<span>CSS</span>
|
|
||||||
<span>JavaScript</span>
|
|
||||||
</div>
|
|
||||||
<div class="project-links">
|
|
||||||
<a href="#" class="btn small-btn"><i class="fas fa-eye"></i> Live Demo</a>
|
|
||||||
<a href="#" class="btn small-btn"><i class="fab fa-github"></i> Source Code</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="project-card" data-category="design">
|
|
||||||
<div class="project-image">
|
|
||||||
<div class="image-placeholder">
|
|
||||||
<i class="fas fa-paint-brush"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="project-info">
|
|
||||||
<h3>Project Title 2</h3>
|
|
||||||
<p>A brief description of the project and your role in it. Explain the technologies used and the problems solved.</p>
|
|
||||||
<div class="project-tags">
|
|
||||||
<span>Figma</span>
|
|
||||||
<span>UI/UX</span>
|
|
||||||
<span>Prototyping</span>
|
|
||||||
</div>
|
|
||||||
<div class="project-links">
|
|
||||||
<a href="#" class="btn small-btn"><i class="fas fa-eye"></i> Live Demo</a>
|
|
||||||
<a href="#" class="btn small-btn"><i class="fab fa-github"></i> Source Code</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="project-card" data-category="web">
|
|
||||||
<div class="project-image">
|
|
||||||
<div class="image-placeholder">
|
|
||||||
<i class="fas fa-mobile-alt"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="project-info">
|
|
||||||
<h3>Project Title 3</h3>
|
|
||||||
<p>A brief description of the project and your role in it. Explain the technologies used and the problems solved.</p>
|
|
||||||
<div class="project-tags">
|
|
||||||
<span>React</span>
|
|
||||||
<span>Node.js</span>
|
|
||||||
<span>MongoDB</span>
|
|
||||||
</div>
|
|
||||||
<div class="project-links">
|
|
||||||
<a href="#" class="btn small-btn"><i class="fas fa-eye"></i> Live Demo</a>
|
|
||||||
<a href="#" class="btn small-btn"><i class="fab fa-github"></i> Source Code</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="project-card" data-category="other">
|
|
||||||
<div class="project-image">
|
|
||||||
<div class="image-placeholder">
|
|
||||||
<i class="fas fa-cogs"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="project-info">
|
|
||||||
<h3>Project Title 4</h3>
|
|
||||||
<p>A brief description of the project and your role in it. Explain the technologies used and the problems solved.</p>
|
|
||||||
<div class="project-tags">
|
|
||||||
<span>Python</span>
|
|
||||||
<span>Data Analysis</span>
|
|
||||||
<span>Visualization</span>
|
|
||||||
</div>
|
|
||||||
<div class="project-links">
|
|
||||||
<a href="#" class="btn small-btn"><i class="fas fa-eye"></i> Live Demo</a>
|
|
||||||
<a href="#" class="btn small-btn"><i class="fab fa-github"></i> Source Code</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="contact" class="contact">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="section-title">Get In Touch</h2>
|
|
||||||
<div class="contact-content">
|
|
||||||
<div class="contact-info">
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon">
|
|
||||||
<i class="fas fa-envelope"></i>
|
|
||||||
</div>
|
|
||||||
<div class="contact-details">
|
|
||||||
<h3>Email</h3>
|
|
||||||
<p>your.email@example.com</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon">
|
|
||||||
<i class="fas fa-phone"></i>
|
|
||||||
</div>
|
|
||||||
<div class="contact-details">
|
|
||||||
<h3>Phone</h3>
|
|
||||||
<p>+1 (123) 456-7890</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-item">
|
|
||||||
<div class="contact-icon">
|
|
||||||
<i class="fas fa-map-marker-alt"></i>
|
|
||||||
</div>
|
|
||||||
<div class="contact-details">
|
|
||||||
<h3>Location</h3>
|
|
||||||
<p>City, Country</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="social-links">
|
|
||||||
<a href="#" class="social-link"><i class="fab fa-linkedin"></i></a>
|
|
||||||
<a href="#" class="social-link"><i class="fab fa-github"></i></a>
|
|
||||||
<a href="#" class="social-link"><i class="fab fa-twitter"></i></a>
|
|
||||||
<a href="#" class="social-link"><i class="fab fa-instagram"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="contact-form">
|
|
||||||
<form id="contactForm">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name">Name</label>
|
|
||||||
<input type="text" id="name" name="name" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email">Email</label>
|
|
||||||
<input type="email" id="email" name="email" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="subject">Subject</label>
|
|
||||||
<input type="text" id="subject" name="subject" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="message">Message</label>
|
|
||||||
<textarea id="message" name="message" rows="5" required></textarea>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn primary-btn">Send Message</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div class="container">
|
|
||||||
<p>© 2023 My Portfolio. All Rights Reserved.</p>
|
|
||||||
<div class="footer-links">
|
|
||||||
<a href="#home">Home</a>
|
|
||||||
<a href="#about">About</a>
|
|
||||||
<a href="#skills">Skills</a>
|
|
||||||
<a href="#projects">Projects</a>
|
|
||||||
<a href="#contact">Contact</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<div class="scroll-to-top">
|
|
||||||
<i class="fas fa-arrow-up"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="script.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
"""
|
||||||
|
Simple test script for LLM API with tool calling functionality.
|
||||||
|
|
||||||
|
This script tests basic tool calling with both streaming and non-streaming to verify functionality.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
from services.llm import make_llm_api_call
|
||||||
|
from utils.logger import logger
|
||||||
|
|
||||||
|
# Example tool schema from files_tool.py
|
||||||
|
CREATE_FILE_SCHEMA = {
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "create_file",
|
||||||
|
"description": "Create a new file with the provided contents at a given path in the workspace",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"file_path": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the file to be created"
|
||||||
|
},
|
||||||
|
"file_contents": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The content to write to the file"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["file_path", "file_contents"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async def test_simple_tool_call():
|
||||||
|
"""Test a simple non-streaming tool call to verify functionality."""
|
||||||
|
# Setup conversation
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "You are a helpful assistant with access to file management tools."},
|
||||||
|
{"role": "user", "content": "Create an HTML file named hello.html with a simple Hello World message."}
|
||||||
|
]
|
||||||
|
|
||||||
|
print("\n=== Testing non-streaming tool call ===\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Make API call with tool
|
||||||
|
response = await make_llm_api_call(
|
||||||
|
messages=messages,
|
||||||
|
model_name="gpt-4o",
|
||||||
|
temperature=0.0,
|
||||||
|
tools=[CREATE_FILE_SCHEMA],
|
||||||
|
tool_choice={"type": "function", "function": {"name": "create_file"}}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Print basic response info
|
||||||
|
print(f"Response model: {response.model}")
|
||||||
|
print(f"Response type: {type(response)}")
|
||||||
|
|
||||||
|
# Check if the response has tool calls
|
||||||
|
assistant_message = response.choices[0].message
|
||||||
|
print(f"\nAssistant message content: {assistant_message.content}")
|
||||||
|
|
||||||
|
if hasattr(assistant_message, 'tool_calls') and assistant_message.tool_calls:
|
||||||
|
print("\nTool calls detected:")
|
||||||
|
|
||||||
|
for i, tool_call in enumerate(assistant_message.tool_calls):
|
||||||
|
print(f"\nTool call {i+1}:")
|
||||||
|
print(f" ID: {tool_call.id}")
|
||||||
|
print(f" Type: {tool_call.type}")
|
||||||
|
print(f" Function: {tool_call.function.name}")
|
||||||
|
print(f" Arguments:")
|
||||||
|
|
||||||
|
try:
|
||||||
|
args = json.loads(tool_call.function.arguments)
|
||||||
|
print(json.dumps(args, indent=4))
|
||||||
|
|
||||||
|
# Access and print specific arguments
|
||||||
|
if tool_call.function.name == "create_file":
|
||||||
|
print(f"\nFile path: {args.get('file_path')}")
|
||||||
|
print(f"File contents length: {len(args.get('file_contents', ''))}")
|
||||||
|
print(f"File contents preview: {args.get('file_contents', '')[:100]}...")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing arguments: {e}")
|
||||||
|
else:
|
||||||
|
print("\nNo tool calls found in the response.")
|
||||||
|
print(f"Full response: {response}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error in test: {str(e)}", exc_info=True)
|
||||||
|
|
||||||
|
async def test_streaming_tool_call():
|
||||||
|
"""Test tool calling with streaming to observe behavior."""
|
||||||
|
# Setup conversation
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "You are a helpful assistant with access to file management tools."},
|
||||||
|
{"role": "user", "content": "Create an HTML file named hello.html with a simple Hello World message."}
|
||||||
|
]
|
||||||
|
|
||||||
|
print("\n=== Testing streaming tool call ===\n")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Make API call with tool in streaming mode
|
||||||
|
print("Sending streaming request...")
|
||||||
|
stream_response = await make_llm_api_call(
|
||||||
|
messages=messages,
|
||||||
|
model_name="gpt-4o",
|
||||||
|
temperature=0.0,
|
||||||
|
tools=[CREATE_FILE_SCHEMA],
|
||||||
|
tool_choice={"type": "function", "function": {"name": "create_file"}},
|
||||||
|
stream=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Process streaming response
|
||||||
|
print("\nResponse stream started. Processing chunks:\n")
|
||||||
|
|
||||||
|
# Stream statistics
|
||||||
|
chunk_count = 0
|
||||||
|
content_chunks = 0
|
||||||
|
tool_call_chunks = 0
|
||||||
|
accumulated_content = ""
|
||||||
|
|
||||||
|
# Storage for accumulated tool calls
|
||||||
|
tool_calls = []
|
||||||
|
|
||||||
|
# Process each chunk
|
||||||
|
async for chunk in stream_response:
|
||||||
|
chunk_count += 1
|
||||||
|
|
||||||
|
# Print chunk number and type
|
||||||
|
print(f"\n--- Chunk {chunk_count} ---")
|
||||||
|
print(f"Chunk type: {type(chunk)}")
|
||||||
|
|
||||||
|
if not hasattr(chunk, 'choices') or not chunk.choices:
|
||||||
|
print("No choices in chunk")
|
||||||
|
continue
|
||||||
|
|
||||||
|
delta = chunk.choices[0].delta
|
||||||
|
|
||||||
|
# Process content if present
|
||||||
|
if hasattr(delta, 'content') and delta.content is not None:
|
||||||
|
content_chunks += 1
|
||||||
|
accumulated_content += delta.content
|
||||||
|
print(f"Content: {delta.content}")
|
||||||
|
|
||||||
|
# Look for tool calls
|
||||||
|
if hasattr(delta, 'tool_calls') and delta.tool_calls:
|
||||||
|
tool_call_chunks += 1
|
||||||
|
print("Tool call detected in chunk!")
|
||||||
|
|
||||||
|
for tool_call in delta.tool_calls:
|
||||||
|
print(f"Tool call: {tool_call.model_dump()}")
|
||||||
|
|
||||||
|
# Track tool call parts
|
||||||
|
tool_call_index = tool_call.index if hasattr(tool_call, 'index') else 0
|
||||||
|
|
||||||
|
# Initialize tool call if new
|
||||||
|
while len(tool_calls) <= tool_call_index:
|
||||||
|
tool_calls.append({
|
||||||
|
"id": "",
|
||||||
|
"type": "function",
|
||||||
|
"function": {"name": "", "arguments": ""}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Update tool call ID if present
|
||||||
|
if hasattr(tool_call, 'id') and tool_call.id:
|
||||||
|
tool_calls[tool_call_index]["id"] = tool_call.id
|
||||||
|
|
||||||
|
# Update function name if present
|
||||||
|
if hasattr(tool_call, 'function'):
|
||||||
|
if hasattr(tool_call.function, 'name') and tool_call.function.name:
|
||||||
|
tool_calls[tool_call_index]["function"]["name"] = tool_call.function.name
|
||||||
|
|
||||||
|
# Update function arguments if present
|
||||||
|
if hasattr(tool_call.function, 'arguments') and tool_call.function.arguments:
|
||||||
|
tool_calls[tool_call_index]["function"]["arguments"] += tool_call.function.arguments
|
||||||
|
|
||||||
|
# Summary after all chunks processed
|
||||||
|
print("\n=== Streaming Summary ===")
|
||||||
|
print(f"Total chunks: {chunk_count}")
|
||||||
|
print(f"Content chunks: {content_chunks}")
|
||||||
|
print(f"Tool call chunks: {tool_call_chunks}")
|
||||||
|
|
||||||
|
if accumulated_content:
|
||||||
|
print(f"\nAccumulated content: {accumulated_content}")
|
||||||
|
|
||||||
|
if tool_calls:
|
||||||
|
print("\nAccumulated tool calls:")
|
||||||
|
for i, tool_call in enumerate(tool_calls):
|
||||||
|
print(f"\nTool call {i+1}:")
|
||||||
|
print(f" ID: {tool_call['id']}")
|
||||||
|
print(f" Type: {tool_call['type']}")
|
||||||
|
print(f" Function: {tool_call['function']['name']}")
|
||||||
|
print(f" Arguments: {tool_call['function']['arguments']}")
|
||||||
|
|
||||||
|
# Try to parse arguments
|
||||||
|
try:
|
||||||
|
args = json.loads(tool_call['function']['arguments'])
|
||||||
|
print("\nParsed arguments:")
|
||||||
|
print(json.dumps(args, indent=4))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing arguments: {str(e)}")
|
||||||
|
else:
|
||||||
|
print("\nNo tool calls accumulated from streaming response.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error in streaming test: {str(e)}", exc_info=True)
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
"""Run both tests for comparison."""
|
||||||
|
# await test_simple_tool_call()
|
||||||
|
await test_streaming_tool_call()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
Loading…
Reference in New Issue