When Claude returns text + tool_use together, the bot was not sending the tool_result back, so no follow-up message reached the user. Now always sends tool_result to get a proper response. Also added Cal.com booking link to system prompt so bot offers consultation scheduling after capturing lead data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
import anthropic
|
|
import httpx
|
|
from config import settings
|
|
from knowledge import SYSTEM_PROMPT, TOOLS
|
|
|
|
client = anthropic.Anthropic(api_key=settings.anthropic_api_key)
|
|
|
|
|
|
async def get_ai_response(messages: list[dict]) -> tuple[str, dict | None]:
|
|
"""Get response from Claude. Returns (text_reply, lead_data_or_none)."""
|
|
response = client.messages.create(
|
|
model=settings.model,
|
|
max_tokens=settings.max_response_tokens,
|
|
system=SYSTEM_PROMPT,
|
|
tools=TOOLS,
|
|
messages=messages,
|
|
)
|
|
|
|
lead_data = None
|
|
tool_block = None
|
|
|
|
for block in response.content:
|
|
if block.type == "tool_use" and block.name == "capture_lead":
|
|
lead_data = block.input
|
|
tool_block = block
|
|
# Send lead to n8n webhook
|
|
try:
|
|
async with httpx.AsyncClient() as http:
|
|
await http.post(
|
|
f"{settings.n8n_webhook_url}/chatbot-lead",
|
|
json=lead_data,
|
|
timeout=10,
|
|
)
|
|
except Exception:
|
|
pass # Don't fail the chat if webhook fails
|
|
|
|
# If there was a tool use, always send tool result back to get a proper follow-up
|
|
if tool_block:
|
|
followup = client.messages.create(
|
|
model=settings.model,
|
|
max_tokens=settings.max_response_tokens,
|
|
system=SYSTEM_PROMPT,
|
|
tools=TOOLS,
|
|
messages=messages + [
|
|
{"role": "assistant", "content": response.content},
|
|
{
|
|
"role": "user",
|
|
"content": [
|
|
{
|
|
"type": "tool_result",
|
|
"tool_use_id": tool_block.id,
|
|
"content": "Lead captured successfully. Now confirm to the visitor and offer to book a free consultation at https://cal.ai-impress.com.",
|
|
}
|
|
],
|
|
},
|
|
],
|
|
)
|
|
text_parts = []
|
|
for block in followup.content:
|
|
if block.type == "text":
|
|
text_parts.append(block.text)
|
|
reply = " ".join(text_parts) if text_parts else "Thank you! I've noted your details. You can book a free consultation at https://cal.ai-impress.com — we'll be in touch shortly!"
|
|
else:
|
|
text_parts = []
|
|
for block in response.content:
|
|
if block.type == "text":
|
|
text_parts.append(block.text)
|
|
reply = " ".join(text_parts) if text_parts else "I'm sorry, could you rephrase that?"
|
|
|
|
return reply, lead_data
|