Skip to content

Commit

Permalink
Fix Serve
Browse files Browse the repository at this point in the history
  • Loading branch information
ashpreetbedi committed Sep 18, 2024
1 parent 0343bd3 commit 3980e9c
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 51 deletions.
2 changes: 1 addition & 1 deletion cookbook/agents/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
storage=PgAgentStorage(table_name="agent_sessions", db_url="postgresql+psycopg://ai:ai@localhost:5532/ai"),
)

run1: RunResponse = agent.run("What is the stock price of NVDA")
run1: RunResponse = agent.run("What is the stock price of NVDA") # type: ignore
# run2: RunResponse = agent.run({"text": "What is the stock price of NVDA", "image": "https://example.com/image.jpg"})
pprint(run1)
# print("------------*******************------------")
Expand Down
2 changes: 1 addition & 1 deletion cookbook/providers/openai/basic_stream_off.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
model=OpenAIChat(model="gpt-4o"),
)

run: RunResponse = agent.run("Share a healthy breakfast recipe")
run: RunResponse = agent.run("Share a healthy breakfast recipe") # type: ignore

print(run.content)
57 changes: 34 additions & 23 deletions phi/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,37 @@ def get_delegation_prompt(self) -> str:
return delegation_prompt
return ""

def get_tools(self) -> Optional[List[Union[Tool, Toolkit, Callable, Dict, Function]]]:
tools: List[Union[Tool, Toolkit, Callable, Dict, Function]] = []

# Add provided tools
if self.tools is not None:
for tool in self.tools:
tools.append(tool)

# Add tools for accessing memory
if self.memory is not None:
if self.read_chat_history:
tools.append(self.get_chat_history)
if self.read_tool_call_history:
tools.append(self.get_tool_call_history)
if self.create_memories:
tools.append(self.update_memory)

# Add tools for accessing knowledge
if self.knowledge is not None:
if self.search_knowledge:
tools.append(self.search_knowledge_base)
if self.update_knowledge:
tools.append(self.add_to_knowledge)

# Add delegation tools
if self.team is not None and len(self.team) > 0:
for agent_index, agent in enumerate(self.team):
tools.append(self.get_delegation_function(agent, agent_index))

return tools

def update_model(self) -> None:
if self.model is None:
try:
Expand All @@ -286,32 +317,12 @@ def update_model(self) -> None:
if self.output_model is not None and self.model.response_format is None:
self.model.response_format = {"type": "json_object"}

# Add tools for accessing memory
if self.memory is not None:
if self.read_chat_history:
self.model.add_tool(self.get_chat_history)
if self.read_tool_call_history:
self.model.add_tool(self.get_tool_call_history)
if self.create_memories:
self.model.add_tool(self.update_memory)

# Add tools for accessing knowledge
if self.knowledge is not None:
if self.search_knowledge:
self.model.add_tool(self.search_knowledge_base)
if self.update_knowledge:
self.model.add_tool(self.add_to_knowledge)

# Add tools to the Model
if self.tools is not None:
for tool in self.tools:
agent_tools = self.get_tools()
if agent_tools is not None:
for tool in agent_tools:
self.model.add_tool(tool)

# Add delegation tools to the Model
if self.team is not None and len(self.team) > 0:
for agent_index, agent in enumerate(self.team):
self.model.add_tool(self.get_delegation_function(agent, agent_index))

# Set show_tool_calls if it is not set on the Model
if self.model.show_tool_calls is None and self.show_tool_calls is not None:
self.model.show_tool_calls = self.show_tool_calls
Expand Down
90 changes: 64 additions & 26 deletions phi/playground/playground.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
from typing import List, Optional, Generator, Iterator
from typing import List, Optional, Generator, Any, Dict, cast

from fastapi import FastAPI, HTTPException
from fastapi.routing import APIRouter
from fastapi.responses import StreamingResponse

from pydantic import BaseModel
from phi.agent.agent import Agent, RunResponse
from phi.agent.agent import Agent, RunResponse, Tool, Toolkit, Function
from phi.playground.settings import PlaygroundSettings
from phi.utils.log import logger


class AgentLLM(BaseModel):
class AgentModel(BaseModel):
name: Optional[str] = None
model: Optional[str] = None
provider: Optional[str] = None


class AgentGetResponse(BaseModel):
agent_id: str
llm: Optional[AgentLLM] = None
name: Optional[str] = None
model: Optional[AgentModel] = None
enable_rag: Optional[bool] = None
tools: Optional[List[Dict[str, Any]]] = None
storage: Optional[Dict[str, Any]] = None
knowledge: Optional[Dict[str, Any]] = None
details: Optional[Dict[str, Any]] = None


class AgentChatRequest(BaseModel):
class AgentRunRequest(BaseModel):
message: str
agent_id: str
stream: bool = True
Expand All @@ -36,14 +41,16 @@ def __init__(
agents: List[Agent],
settings: Optional[PlaygroundSettings] = None,
api_app: Optional[FastAPI] = None,
api_router: Optional[APIRouter] = None,
router: Optional[APIRouter] = None,
):
self.agents: List[Agent] = agents
self.settings: PlaygroundSettings = settings or PlaygroundSettings()
self.api_app: Optional[FastAPI] = api_app
self.api_router: Optional[APIRouter] = api_router
self.router: Optional[APIRouter] = router

def get_api_router(self):
self.agent_list: Optional[List[AgentGetResponse]] = None

def get_router(self):
playground_routes = APIRouter(prefix="/playground", tags=["Playground"])

@playground_routes.get("/status")
Expand All @@ -52,31 +59,61 @@ def playground_status():

@playground_routes.get("/agent/get", response_model=List[AgentGetResponse])
def agent_get():
agent_list: List[AgentGetResponse] = []
if self.agent_list is not None:
return self.agent_list

self.agent_list = []
for agent in self.agents:
agent_list.append(
agent_tools = agent.get_tools()
formatted_tools = []
if agent_tools is not None:
for tool in agent_tools:
if isinstance(tool, dict):
formatted_tools.append(tool)
elif isinstance(tool, Tool):
formatted_tools.append(tool.to_dict())
elif isinstance(tool, Toolkit):
for f_name, f in tool.functions.items():
formatted_tools.append(f.to_dict())
elif isinstance(tool, Function):
formatted_tools.append(tool.to_dict())
elif callable(tool):
func = Function.from_callable(tool)
formatted_tools.append(func.to_dict())
else:
logger.warning(f"Unknown tool type: {type(tool)}")

self.agent_list.append(
AgentGetResponse(
llm=AgentLLM(
agent_id=agent.agent_id,
name=agent.name,
model=AgentModel(
provider=agent.model.provider or agent.model.__class__.__name__ if agent.model else None,
name=agent.model.name or agent.model.__class__.__name__ if agent.model else None,
model=agent.model.model if agent.model else None,
),
name=agent.name,
agent_id=agent.agent_id,
enable_rag=agent.enable_rag,
tools=formatted_tools,
storage={"name": agent.storage.__class__.__name__} if agent.storage else None,
knowledge={agent.knowledge.__class__.__name__} if agent.knowledge else None,
details={
"description": agent.description,
"instructions": agent.instructions,
},
)
)

return agent_list
return self.agent_list

def chat_response_streamer(agent: Agent, message: str) -> Generator:
logger.info(f"ChatRequest: {message} for Agent: {agent.agent_id}")
run_response: Iterator[RunResponse] = agent.run(message, stream=True)
run_response = agent.run(message, stream=True)
for run_response_chunk in run_response:
yield run_response_chunk.content
run_response_chunk = cast(RunResponse, run_response_chunk)
yield run_response_chunk.model_dump_json()

@playground_routes.post("/agent/chat")
def agent_chat(body: AgentChatRequest):
logger.debug(f"ChatRequest: {body}")
@playground_routes.post("/agent/run")
def agent_chat(body: AgentRunRequest):
logger.debug(f"AgentRunRequest: {body}")
agent: Optional[Agent] = None
for _agent in self.agents:
if _agent.agent_id == body.agent_id:
Expand All @@ -91,7 +128,8 @@ def agent_chat(body: AgentChatRequest):
media_type="text/event-stream",
)
else:
return agent.run(body.message, stream=False)
run_response = cast(RunResponse, agent.run(body.message, stream=False))
return run_response.model_dump_json()

return playground_routes

Expand All @@ -116,14 +154,14 @@ def get_api_app(self) -> FastAPI:
raise Exception("API App could not be created.")

# Create an API Router if not provided
if not self.api_router:
self.api_router = APIRouter(prefix="/v1")
if not self.router:
self.router = APIRouter(prefix="/v1")

if not self.api_router:
if not self.router:
raise Exception("API Router could not be created.")

self.api_router.include_router(self.get_api_router())
self.api_app.include_router(self.api_router)
self.router.include_router(self.get_router())
self.api_app.include_router(self.router)

# Add Middlewares
self.api_app.add_middleware(
Expand Down

0 comments on commit 3980e9c

Please sign in to comment.