fix: adding tools, changing init, general cleanup
This commit is contained in:
parent
74c199aae5
commit
c3dd0baabb
|
|
@ -1,14 +1,16 @@
|
|||
"""
|
||||
Multi-Peer Honcho + Agno Example
|
||||
|
||||
A realistic multi-agent scenario using Agno's patterns:
|
||||
- A coordinator agent routes questions to specialists
|
||||
- Each specialist has its own HonchoTools (identity)
|
||||
- All share the same session for conversation continuity
|
||||
- The coordinator uses specialists as tools
|
||||
A three-way conversation between:
|
||||
- User: asking questions about life, work, and meaning
|
||||
- Tech Bro Advisor: startup culture, hustle, optimization mindset
|
||||
- Philosophy Guru: mindfulness, ancient wisdom, inner peace
|
||||
|
||||
All three peers observe each other and build representations on each other,
|
||||
creating a rich understanding of each participant's perspective over time.
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY or LLM_OPENAI_API_KEY: OpenAI API key
|
||||
LLM_OPENAI_API_KEY: OpenAI API key (matches honcho .env)
|
||||
HONCHO_API_KEY: Required for Honcho API access
|
||||
"""
|
||||
|
||||
|
|
@ -19,155 +21,110 @@ from dotenv import load_dotenv
|
|||
|
||||
from agno.agent import Agent
|
||||
from agno.models.openai import OpenAIChat
|
||||
from agno.tools import tool
|
||||
|
||||
from honcho import Honcho
|
||||
from honcho.session import SessionPeerConfig
|
||||
from honcho_agno import HonchoTools
|
||||
|
||||
load_dotenv()
|
||||
|
||||
if not os.getenv("OPENAI_API_KEY") and (llm_key := os.getenv("LLM_OPENAI_API_KEY")):
|
||||
# Use LLM_OPENAI_API_KEY from honcho .env
|
||||
if llm_key := os.getenv("LLM_OPENAI_API_KEY"):
|
||||
os.environ["OPENAI_API_KEY"] = llm_key
|
||||
|
||||
|
||||
def create_advisor_system(session_id: str):
|
||||
def create_advisory_session(session_id: str):
|
||||
"""
|
||||
Creates a multi-agent advisory system where:
|
||||
- Each specialist agent has its own identity (HonchoTools)
|
||||
- A coordinator routes to specialists and synthesizes responses
|
||||
- All agents share the same conversation session
|
||||
Creates a three-peer advisory system where:
|
||||
- User asks questions
|
||||
- Tech Bro gives startup/optimization perspective
|
||||
- Philosophy Guru gives mindfulness/wisdom perspective
|
||||
- All three observe each other and build representations
|
||||
"""
|
||||
model_id = os.getenv("OPENAI_MODEL", "gpt-4o")
|
||||
|
||||
# Shared Honcho client and session
|
||||
honcho = Honcho(workspace_id="advisory-system")
|
||||
session = honcho.session(session_id)
|
||||
# Shared Honcho client
|
||||
honcho = Honcho(workspace_id="advisory-trio")
|
||||
|
||||
# === TECH BRO ADVISOR ===
|
||||
tech_bro_tools = HonchoTools(
|
||||
app_id="advisory-trio",
|
||||
peer_id="tech-bro",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
tech_bro_agent = Agent(
|
||||
name="Tech Bro Advisor",
|
||||
model=OpenAIChat(id=model_id),
|
||||
tools=[tech_bro_tools],
|
||||
description="Startup founder vibes, optimization mindset, hustle culture perspective.",
|
||||
instructions=[
|
||||
"You're a successful tech entrepreneur who's been through YC and raised Series B.",
|
||||
"Everything is an opportunity to optimize, scale, or disrupt.",
|
||||
"Use the chat tool to understand what the user is dealing with and what they care about.",
|
||||
"Give advice through the lens of productivity, systems thinking, and growth hacking.",
|
||||
"Reference things like morning routines, cold plunges, biohacking, and 10x thinking.",
|
||||
"Be enthusiastic but genuine - you really believe this stuff works.",
|
||||
"Keep responses conversational and punchy.",
|
||||
],
|
||||
)
|
||||
|
||||
# === PHILOSOPHY MEDITATION GURU ===
|
||||
guru_tools = HonchoTools(
|
||||
app_id="advisory-trio",
|
||||
peer_id="philosophy-guru",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
guru_agent = Agent(
|
||||
name="Philosophy Guru",
|
||||
model=OpenAIChat(id=model_id),
|
||||
tools=[guru_tools],
|
||||
description="Meditation teacher, draws on Stoicism, Buddhism, and Taoism.",
|
||||
instructions=[
|
||||
"You're a calm, wise meditation teacher who's spent years studying ancient philosophy.",
|
||||
"Draw on Stoicism, Buddhism, Taoism, and other contemplative traditions.",
|
||||
"Use the chat tool to understand the user's inner state and what they truly seek.",
|
||||
"Gently guide toward presence, acceptance, and inner peace.",
|
||||
"Reference concepts like impermanence, the present moment, letting go, and wu wei.",
|
||||
"Offer a counterbalance to hustle culture - not everything needs to be optimized.",
|
||||
"Speak slowly and thoughtfully. Use metaphors from nature.",
|
||||
],
|
||||
)
|
||||
|
||||
# Create user peer and configure session observation
|
||||
user_peer = honcho.peer("user")
|
||||
session = tech_bro_tools.session # Use session from toolkit
|
||||
|
||||
# === SPECIALIST AGENTS ===
|
||||
# Each has its own identity via HonchoTools
|
||||
# Add all peers to session and configure observation
|
||||
session.add_peers([user_peer, tech_bro_tools.peer, guru_tools.peer])
|
||||
|
||||
tech_tools = HonchoTools(
|
||||
app_id="advisory-system",
|
||||
peer_id="tech-specialist",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
full_observation = SessionPeerConfig(
|
||||
observe_me=True,
|
||||
observe_others=True
|
||||
)
|
||||
session.set_peer_config(user_peer, full_observation)
|
||||
session.set_peer_config(tech_bro_tools.peer, full_observation)
|
||||
session.set_peer_config(guru_tools.peer, full_observation)
|
||||
|
||||
tech_agent = Agent(
|
||||
name="Tech Specialist",
|
||||
model=OpenAIChat(id=model_id),
|
||||
tools=[tech_tools],
|
||||
description="Technical advisor for architecture, implementation, and technology choices.",
|
||||
instructions=[
|
||||
"Focus on technical feasibility and implementation details.",
|
||||
"Use get_context to understand what's been discussed.",
|
||||
"Save key technical recommendations with add_message.",
|
||||
"Be concise - you're part of a team.",
|
||||
],
|
||||
)
|
||||
|
||||
business_tools = HonchoTools(
|
||||
app_id="advisory-system",
|
||||
peer_id="business-specialist",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
business_agent = Agent(
|
||||
name="Business Specialist",
|
||||
model=OpenAIChat(id=model_id),
|
||||
tools=[business_tools],
|
||||
description="Business advisor for strategy, market fit, and ROI.",
|
||||
instructions=[
|
||||
"Focus on business viability and market considerations.",
|
||||
"Use get_context to understand what's been discussed.",
|
||||
"Save key business insights with add_message.",
|
||||
"Be concise - you're part of a team.",
|
||||
],
|
||||
)
|
||||
|
||||
# === COORDINATOR TOOLS ===
|
||||
# Wrap specialists as tools the coordinator can invoke
|
||||
|
||||
@tool
|
||||
def consult_tech_specialist(question: str) -> str:
|
||||
"""
|
||||
Consult the technical specialist for architecture, implementation,
|
||||
or technology-related questions.
|
||||
|
||||
Args:
|
||||
question: The technical question to ask.
|
||||
|
||||
Returns:
|
||||
Technical specialist's response.
|
||||
"""
|
||||
response = tech_agent.run(question)
|
||||
return str(response.content) if response.content else ""
|
||||
|
||||
@tool
|
||||
def consult_business_specialist(question: str) -> str:
|
||||
"""
|
||||
Consult the business specialist for strategy, market fit,
|
||||
or ROI-related questions.
|
||||
|
||||
Args:
|
||||
question: The business question to ask.
|
||||
|
||||
Returns:
|
||||
Business specialist's response.
|
||||
"""
|
||||
response = business_agent.run(question)
|
||||
return str(response.content) if response.content else ""
|
||||
|
||||
# Coordinator has its own identity too
|
||||
coordinator_tools = HonchoTools(
|
||||
app_id="advisory-system",
|
||||
peer_id="coordinator",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
coordinator = Agent(
|
||||
name="Advisory Coordinator",
|
||||
model=OpenAIChat(id=model_id),
|
||||
tools=[coordinator_tools, consult_tech_specialist, consult_business_specialist],
|
||||
description="Coordinates between specialists to provide comprehensive advice.",
|
||||
instructions=[
|
||||
"Use get_context to understand the full conversation history.",
|
||||
"Route technical questions to the tech specialist.",
|
||||
"Route business questions to the business specialist.",
|
||||
"Synthesize specialist inputs into actionable recommendations.",
|
||||
"Save your final synthesis with add_message.",
|
||||
],
|
||||
)
|
||||
|
||||
return coordinator, session, user_peer
|
||||
return session, user_peer, tech_bro_tools, guru_tools, tech_bro_agent, guru_agent
|
||||
|
||||
|
||||
def main(test_mode: bool = False):
|
||||
session_id = f"advisory-{uuid.uuid4().hex[:8]}"
|
||||
def main():
|
||||
session_id = f"trio-{uuid.uuid4().hex[:8]}"
|
||||
|
||||
print(f"Session: {session_id}")
|
||||
print("=" * 60)
|
||||
|
||||
coordinator, session, user_peer = create_advisor_system(session_id)
|
||||
session, user_peer, tech_bro_tools, guru_tools, tech_bro_agent, guru_agent = (
|
||||
create_advisory_session(session_id)
|
||||
)
|
||||
|
||||
if test_mode:
|
||||
# Non-interactive test
|
||||
test_question = "I want to build a SaaS product for small businesses. What should I consider?"
|
||||
print(f"\n[TEST MODE] User: {test_question}\n")
|
||||
|
||||
session.add_messages([user_peer.message(test_question)])
|
||||
response = coordinator.run(test_question)
|
||||
print(f"Advisor: {response.content}\n")
|
||||
print("=" * 60)
|
||||
print("Test completed successfully!")
|
||||
return
|
||||
|
||||
# Interactive chat loop
|
||||
print("\nAdvisory System Ready")
|
||||
print("Ask questions about building a product. Type 'quit' to exit.\n")
|
||||
print("\nAdvisory Trio Ready")
|
||||
print("Ask about life, work, meaning - get two very different perspectives.")
|
||||
print("Type 'quit' to exit.\n")
|
||||
|
||||
while True:
|
||||
user_input = input("You: ").strip()
|
||||
|
|
@ -176,15 +133,24 @@ def main(test_mode: bool = False):
|
|||
if user_input.lower() in ("quit", "exit", "q"):
|
||||
break
|
||||
|
||||
# Save user message to session
|
||||
# Save user message
|
||||
session.add_messages([user_peer.message(user_input)])
|
||||
|
||||
# Coordinator handles routing and synthesis
|
||||
response = coordinator.run(user_input)
|
||||
print(f"\nAdvisor: {response.content}\n")
|
||||
# Tech Bro responds
|
||||
print()
|
||||
print("-" * 40)
|
||||
tech_response = tech_bro_agent.run(user_input)
|
||||
tech_content = str(tech_response.content) if tech_response.content else ""
|
||||
session.add_messages([tech_bro_tools.peer.message(tech_content)])
|
||||
print(f"🚀 Tech Bro: {tech_content}\n")
|
||||
|
||||
# Guru responds
|
||||
print("-" * 40)
|
||||
guru_response = guru_agent.run(user_input)
|
||||
guru_content = str(guru_response.content) if guru_response.content else ""
|
||||
session.add_messages([guru_tools.peer.message(guru_content)])
|
||||
print(f"🧘 Guru: {guru_content}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
test_mode = "--test" in sys.argv
|
||||
main(test_mode=test_mode)
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
"""
|
||||
Honcho Multi-Tool Example
|
||||
|
||||
Demonstrates using all Honcho tools with an Agno agent:
|
||||
- add_message: Store agent responses (attributed to the toolkit's peer)
|
||||
- get_context: Retrieve session context
|
||||
- search_messages: Semantic search
|
||||
- query_peer: Dialectic API queries about any peer
|
||||
Demonstrates using Honcho tools with an Agno agent:
|
||||
- chat: Ask questions about the conversation (recommended)
|
||||
- get_context: Retrieve raw session context
|
||||
- search_messages: Semantic search through messages
|
||||
|
||||
Pattern: toolkit = agent identity
|
||||
- HonchoTools represents the assistant's identity
|
||||
- User messages are added via Honcho directly
|
||||
- The agent uses tools to query context and save its responses
|
||||
The chat tool is the recommended way to understand users
|
||||
It reasons over conversation context and provides synthesized insights.
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY or LLM_OPENAI_API_KEY: OpenAI API key
|
||||
OPENAI_MODEL: Model to use (default: gpt-4o)
|
||||
LLM_OPENAI_API_KEY: OpenAI API key (matches honcho .env)
|
||||
OPENAI_MODEL: Model to use
|
||||
HONCHO_API_KEY: Required for Honcho API access
|
||||
"""
|
||||
|
||||
|
|
@ -30,8 +27,8 @@ from honcho_agno import HonchoTools
|
|||
|
||||
load_dotenv()
|
||||
|
||||
# Support both OPENAI_API_KEY and LLM_OPENAI_API_KEY
|
||||
if not os.getenv("OPENAI_API_KEY") and (llm_key := os.getenv("LLM_OPENAI_API_KEY")):
|
||||
# Use LLM_OPENAI_API_KEY from honcho .env
|
||||
if llm_key := os.getenv("LLM_OPENAI_API_KEY"):
|
||||
os.environ["OPENAI_API_KEY"] = llm_key
|
||||
|
||||
|
||||
|
|
@ -40,20 +37,21 @@ def main():
|
|||
print("HONCHO TOOLS + AGNO EXAMPLE")
|
||||
print("=" * 70 + "\n")
|
||||
|
||||
# Initialize Honcho for managing the session and user peer
|
||||
# Initialize Honcho client
|
||||
honcho = Honcho(workspace_id="travel-app")
|
||||
session = honcho.session("trip-planning-session")
|
||||
user_peer = honcho.peer("traveler-42")
|
||||
|
||||
# Setup Honcho tools - this IS the assistant's identity
|
||||
# Setup Honcho tools - creates peer and session internally
|
||||
honcho_tools = HonchoTools(
|
||||
app_id="travel-app",
|
||||
peer_id="travel-assistant", # The toolkit speaks as "travel-assistant"
|
||||
peer_id="travel-assistant",
|
||||
session_id="trip-planning-session",
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
# Pre-populate with user's travel preferences (via Honcho directly)
|
||||
# Create user peer (the toolkit's peer is "travel-assistant")
|
||||
user_peer = honcho.peer("traveler-42")
|
||||
|
||||
# Pre-populate with user's travel preferences
|
||||
print("Adding user's travel preferences to memory...")
|
||||
messages = [
|
||||
"I'm planning a trip to Japan in March",
|
||||
|
|
@ -64,7 +62,7 @@ def main():
|
|||
]
|
||||
|
||||
for msg in messages:
|
||||
session.add_messages([user_peer.message(msg)])
|
||||
honcho_tools.session.add_messages([user_peer.message(msg)])
|
||||
print(f" [traveler-42]: {msg[:50]}...")
|
||||
|
||||
print("\n" + "-" * 70 + "\n")
|
||||
|
|
@ -75,42 +73,54 @@ def main():
|
|||
model=OpenAIChat(id=os.getenv("OPENAI_MODEL", "gpt-4o")),
|
||||
tools=[honcho_tools],
|
||||
description=(
|
||||
"A travel planning expert with access to memory tools. "
|
||||
"Use get_context for recent conversation, search_messages to find "
|
||||
"specific preferences, and query_peer to understand the traveler."
|
||||
"A travel planning expert with access to Honcho memory tools. "
|
||||
"Use chat to understand the traveler's preferences and travel style."
|
||||
),
|
||||
instructions=[
|
||||
"Always retrieve relevant context before making recommendations",
|
||||
"Use search to find specific preferences mentioned",
|
||||
"Use query_peer with target_peer_id='traveler-42' to understand their travel style",
|
||||
"Use the chat tool to understand the user's preferences and travel style",
|
||||
"Ask both broad and specific questions like 'What is their travel style?' or 'What is their budget?'",
|
||||
"Only use get_context or search_messages if you need raw message history",
|
||||
"Be specific and actionable in your recommendations",
|
||||
"Use add_message to save your recommendations to the conversation",
|
||||
],
|
||||
)
|
||||
|
||||
# Run the agent with a planning request
|
||||
print("Asking agent to create a personalized itinerary...\n")
|
||||
response = agent.run(
|
||||
"Create a 3-day Tokyo itinerary for me. First, use the memory tools to "
|
||||
"understand my preferences (budget, accommodation style, interests), "
|
||||
"then create a personalized plan that matches what I've told you."
|
||||
"Create a 3-day Tokyo itinerary for me. Use the chat tool to ask about "
|
||||
"my budget, accommodation preferences, and interests, then create "
|
||||
"a personalized plan that matches my travel style."
|
||||
)
|
||||
|
||||
# Save the assistant's response to Honcho (using toolkit's peer and session)
|
||||
assistant_response = str(response.content) if response.content else ""
|
||||
if assistant_response:
|
||||
honcho_tools.session.add_messages([honcho_tools.peer.message(assistant_response)])
|
||||
|
||||
print("=" * 70)
|
||||
print("RESPONSE")
|
||||
print("=" * 70)
|
||||
print(response.content)
|
||||
|
||||
# Demonstrate chat (recommended)
|
||||
print("\n" + "=" * 70)
|
||||
print("DIRECT TOOL USAGE: chat (recommended)")
|
||||
print("=" * 70)
|
||||
chat_result = honcho_tools.chat(
|
||||
"What are the traveler's key preferences and constraints?"
|
||||
)
|
||||
print(chat_result)
|
||||
|
||||
# Demonstrate search capability
|
||||
print("\n" + "=" * 70)
|
||||
print("DIRECT TOOL USAGE: Searching for budget info...")
|
||||
print("DIRECT TOOL USAGE: search_messages")
|
||||
print("=" * 70)
|
||||
search_result = honcho_tools.search_messages("budget money cost", limit=5)
|
||||
print(search_result)
|
||||
|
||||
# Show full conversation context
|
||||
print("\n" + "=" * 70)
|
||||
print("FULL SESSION CONTEXT")
|
||||
print("DIRECT TOOL USAGE: get_context")
|
||||
print("=" * 70)
|
||||
print(honcho_tools.get_context())
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Simple Honcho + Agno Example
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY or LLM_OPENAI_API_KEY: OpenAI API key
|
||||
LLM_OPENAI_API_KEY: OpenAI API key (matches honcho .env)
|
||||
HONCHO_API_KEY: Required for Honcho API access
|
||||
"""
|
||||
|
||||
|
|
@ -19,28 +19,28 @@ from honcho_agno import HonchoTools
|
|||
|
||||
load_dotenv()
|
||||
|
||||
# Support both OPENAI_API_KEY and LLM_OPENAI_API_KEY
|
||||
if not os.getenv("OPENAI_API_KEY") and (llm_key := os.getenv("LLM_OPENAI_API_KEY")):
|
||||
# Use LLM_OPENAI_API_KEY from honcho .env
|
||||
if llm_key := os.getenv("LLM_OPENAI_API_KEY"):
|
||||
os.environ["OPENAI_API_KEY"] = llm_key
|
||||
|
||||
|
||||
def main():
|
||||
# Create shared session
|
||||
session_id = f"simple-{uuid.uuid4().hex[:8]}"
|
||||
|
||||
# Initialize Honcho directly for managing user messages
|
||||
# Initialize Honcho client
|
||||
honcho = Honcho(workspace_id="agno-demo")
|
||||
session = honcho.session(session_id)
|
||||
user_peer = honcho.peer("user")
|
||||
|
||||
# Initialize HonchoTools - this IS the assistant's identity
|
||||
# Initialize HonchoTools - creates peer and session internally
|
||||
honcho_tools = HonchoTools(
|
||||
app_id="agno-demo",
|
||||
peer_id="assistant", # The toolkit speaks as "assistant"
|
||||
session_id=session_id, # Same session as user
|
||||
honcho_client=honcho, # Reuse client
|
||||
peer_id="assistant",
|
||||
session_id=session_id,
|
||||
honcho_client=honcho,
|
||||
)
|
||||
|
||||
# Create user peer (toolkit's peer is "assistant")
|
||||
user_peer = honcho.peer("user")
|
||||
|
||||
# Create an agent with memory tools
|
||||
agent = Agent(
|
||||
name="Programming Mentor",
|
||||
|
|
@ -48,15 +48,14 @@ def main():
|
|||
tools=[honcho_tools],
|
||||
description="A programming mentor that remembers user interests and progress.",
|
||||
instructions=[
|
||||
"Use get_context to understand the conversation history",
|
||||
"Use query_peer to ask about the user's preferences",
|
||||
"Use add_message to save your responses to the conversation",
|
||||
"Use the chat tool to understand the user's preferences and interests",
|
||||
"Use get_context if you need raw conversation history",
|
||||
],
|
||||
)
|
||||
|
||||
# Add user messages via Honcho directly
|
||||
# Add user messages
|
||||
print("Adding user messages to conversation...")
|
||||
session.add_messages([
|
||||
honcho_tools.session.add_messages([
|
||||
user_peer.message("I'm learning Python programming"),
|
||||
user_peer.message("I'm also interested in web development with FastAPI"),
|
||||
])
|
||||
|
|
@ -65,9 +64,14 @@ def main():
|
|||
print("\nAsking the agent for recommendations...")
|
||||
response = agent.run(
|
||||
"Based on what you know about the user, what should they learn next? "
|
||||
"Use get_context to see the conversation history first."
|
||||
"Use the chat tool to understand their interests first."
|
||||
)
|
||||
|
||||
# Save the assistant's response to Honcho
|
||||
assistant_response = str(response.content) if response.content else ""
|
||||
if assistant_response:
|
||||
honcho_tools.session.add_messages([honcho_tools.peer.message(assistant_response)])
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("RESPONSE")
|
||||
print("=" * 60)
|
||||
|
|
|
|||
|
|
@ -2,17 +2,16 @@
|
|||
Honcho Tools for Agno
|
||||
|
||||
This module provides a Toolkit that allows Agno agents to interact with Honcho's
|
||||
memory system, including session context, semantic search, and dialectic API.
|
||||
memory system, including session context, semantic search, and chat.
|
||||
|
||||
Each HonchoTools instance represents ONE agent identity (peer). The toolkit
|
||||
speaks as that peer when adding messages or querying the dialectic. For
|
||||
multi-peer conversations, create separate toolkit instances or use Honcho
|
||||
directly to manage other peers.
|
||||
provides read access to Honcho for querying conversation context.
|
||||
Orchestration code will handle saving messages to avoid duplicates.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from agno.tools import Toolkit
|
||||
from honcho import Honcho
|
||||
|
|
@ -28,14 +27,12 @@ class HonchoTools(Toolkit):
|
|||
"""
|
||||
Honcho toolkit for Agno agents.
|
||||
|
||||
Each toolkit instance represents ONE agent identity. The peer_id parameter
|
||||
defines who this toolkit "speaks as" - all messages added through this
|
||||
toolkit are attributed to that peer.
|
||||
Each toolkit instance is for ONE agent identity.
|
||||
|
||||
For multi-peer conversations:
|
||||
- Create one HonchoTools per agent, each with a different peer_id
|
||||
- Share the same session_id across toolkits
|
||||
- Use Honcho directly for peers not represented by an agent
|
||||
- Messages are saved to Honcho by the orchestration code, not the toolkit
|
||||
|
||||
Example:
|
||||
```python
|
||||
|
|
@ -43,7 +40,6 @@ class HonchoTools(Toolkit):
|
|||
from agno.models.openai import OpenAIChat
|
||||
from honcho_agno import HonchoTools
|
||||
|
||||
# This toolkit IS the assistant - it speaks as "assistant"
|
||||
honcho_tools = HonchoTools(
|
||||
app_id="my-app",
|
||||
peer_id="assistant",
|
||||
|
|
@ -62,8 +58,6 @@ class HonchoTools(Toolkit):
|
|||
app_id: str = "default",
|
||||
peer_id: str = "assistant",
|
||||
session_id: str | None = None,
|
||||
api_key: str | None = None,
|
||||
base_url: str | None = None,
|
||||
honcho_client: Honcho | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
|
|
@ -72,31 +66,21 @@ class HonchoTools(Toolkit):
|
|||
Args:
|
||||
app_id: Application/workspace ID for scoping operations.
|
||||
Maps to Honcho's workspace_id.
|
||||
peer_id: The identity this toolkit represents. All messages
|
||||
added through this toolkit are attributed to this peer.
|
||||
This is who the agent "is" in the conversation.
|
||||
peer_id: The identity this toolkit represents. This is who
|
||||
the agent "is" when querying peer knowledge.
|
||||
session_id: Optional session ID. If not provided, a new UUID
|
||||
will be generated. Share this across toolkits for multi-peer
|
||||
conversations.
|
||||
api_key: Optional API key for Honcho. If not provided, will
|
||||
attempt to read from HONCHO_API_KEY environment variable.
|
||||
base_url: Optional base URL for the Honcho API.
|
||||
honcho_client: Optional pre-configured Honcho client instance.
|
||||
If provided, other connection parameters are ignored.
|
||||
If provided, app_id is ignored.
|
||||
"""
|
||||
super().__init__(name="honcho")
|
||||
|
||||
# Initialize Honcho client
|
||||
self.honcho: Honcho
|
||||
if honcho_client is not None:
|
||||
self.honcho = honcho_client
|
||||
else:
|
||||
client_kwargs: dict[str, Any] = {"workspace_id": app_id}
|
||||
if api_key is not None:
|
||||
client_kwargs["api_key"] = api_key
|
||||
if base_url is not None:
|
||||
client_kwargs["base_url"] = base_url
|
||||
self.honcho = Honcho(**client_kwargs)
|
||||
self.honcho = Honcho(workspace_id=app_id)
|
||||
|
||||
# Store identifiers
|
||||
self.app_id: str = app_id
|
||||
|
|
@ -104,38 +88,15 @@ class HonchoTools(Toolkit):
|
|||
self.session_id: str = session_id or str(uuid.uuid4())
|
||||
|
||||
# Create the peer this toolkit represents
|
||||
# This is THE identity of this toolkit - one toolkit = one voice
|
||||
self.peer: Peer = self.honcho.peer(peer_id)
|
||||
|
||||
# Create or get session
|
||||
self.session: Session = self.honcho.session(self.session_id)
|
||||
|
||||
# Register tools
|
||||
self.register(self.add_message)
|
||||
self.register(self.get_context)
|
||||
self.register(self.search_messages)
|
||||
self.register(self.query_peer)
|
||||
|
||||
def add_message(self, content: str) -> str:
|
||||
"""
|
||||
Store a message in the current session as this agent.
|
||||
|
||||
Use this tool to save your responses or important information
|
||||
to the conversation history. The message is attributed to this
|
||||
toolkit's peer identity.
|
||||
|
||||
Args:
|
||||
content: The message content to store.
|
||||
|
||||
Returns:
|
||||
Confirmation message indicating the memory was saved.
|
||||
"""
|
||||
try:
|
||||
self.session.add_messages([self.peer.message(content)])
|
||||
return f"Message saved as '{self.peer_id}' to session {self.session_id}"
|
||||
except Exception as e:
|
||||
logger.exception("Error saving message")
|
||||
return f"Error saving message: {e!s}"
|
||||
self.register(self.chat)
|
||||
|
||||
def get_context(
|
||||
self,
|
||||
|
|
@ -145,9 +106,6 @@ class HonchoTools(Toolkit):
|
|||
"""
|
||||
Retrieve recent conversation context within token limits.
|
||||
|
||||
Use this tool to get optimized context from the current session,
|
||||
including messages and optional summary, that fits within token budgets.
|
||||
|
||||
Args:
|
||||
tokens: Maximum number of tokens to include. If not specified,
|
||||
returns all available context.
|
||||
|
|
@ -161,35 +119,7 @@ class HonchoTools(Toolkit):
|
|||
summary=include_summary,
|
||||
tokens=tokens,
|
||||
)
|
||||
|
||||
result: list[str] = []
|
||||
|
||||
# Add summary if present
|
||||
if context.summary:
|
||||
result.append("=== Session Summary ===")
|
||||
result.append(context.summary.content)
|
||||
result.append("")
|
||||
|
||||
# Add peer representation if present
|
||||
if context.peer_representation:
|
||||
result.append("=== Peer Representation ===")
|
||||
result.append(context.peer_representation)
|
||||
result.append("")
|
||||
|
||||
# Add peer card if present
|
||||
if context.peer_card:
|
||||
result.append("=== Peer Card ===")
|
||||
result.extend(context.peer_card)
|
||||
result.append("")
|
||||
|
||||
# Add messages
|
||||
if context.messages:
|
||||
result.append(f"=== Messages ({len(context.messages)}) ===")
|
||||
for msg in context.messages:
|
||||
result.append(f"{msg.peer_id}: {msg.content}")
|
||||
|
||||
return "\n".join(result) if result else "No context available"
|
||||
|
||||
return str(context)
|
||||
except Exception as e:
|
||||
logger.exception("Error retrieving context")
|
||||
return f"Error retrieving context: {e!s}"
|
||||
|
|
@ -230,31 +160,24 @@ class HonchoTools(Toolkit):
|
|||
logger.exception("Error searching messages")
|
||||
return f"Error searching messages: {e!s}"
|
||||
|
||||
def query_peer(self, query: str, target_peer_id: str | None = None) -> str:
|
||||
def chat(self, query: str) -> str:
|
||||
"""
|
||||
Query the system's knowledge about a peer in the conversation.
|
||||
Ask a question about what was discussed in this conversation.
|
||||
|
||||
Use this tool to ask questions about any participant's preferences,
|
||||
interests, or past interactions. The system uses dialectic reasoning
|
||||
to provide insights based on the peer's long-term representation.
|
||||
Use this tool to query session-specific context and facts.
|
||||
The system uses Honcho reasoning to provide synthesized
|
||||
insights based on the conversation history.
|
||||
|
||||
Args:
|
||||
query: Natural language question about the peer.
|
||||
Examples: "What does the user like?", "What are their preferences?"
|
||||
target_peer_id: Optional peer ID to query about. If not provided,
|
||||
queries about this toolkit's own peer identity.
|
||||
query: Natural language question about the conversation.
|
||||
Examples: "What did we discuss?", "What preferences should I be aware of?",
|
||||
"What topics came up?"
|
||||
|
||||
Returns:
|
||||
Response from the dialectic API with insights about the peer.
|
||||
Synthesized response based on the session context.
|
||||
"""
|
||||
try:
|
||||
# Query about a specific peer, or self if not specified
|
||||
if target_peer_id:
|
||||
target = self.honcho.peer(target_peer_id)
|
||||
else:
|
||||
target = self.peer
|
||||
|
||||
response = target.chat(
|
||||
response = self.peer.chat(
|
||||
query=query,
|
||||
stream=False,
|
||||
session=self.session_id,
|
||||
|
|
@ -263,8 +186,8 @@ class HonchoTools(Toolkit):
|
|||
return str(response) if response else "No relevant information found."
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Error querying peer knowledge")
|
||||
return f"Error querying peer knowledge: {e!s}"
|
||||
logger.exception("Error querying conversation")
|
||||
return f"Error querying conversation: {e!s}"
|
||||
|
||||
def reset_session(self) -> str:
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue