Skip to content

Commit b4f7f75

Browse files
committed
finetuned system1
1 parent 4ba6c53 commit b4f7f75

22 files changed

+251
-132
lines changed

agent_stream/schedule_agent.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44

55
from restack_ai import Restack
6+
from restack_ai.event import AgentEvent
67
from src.agents.agent import AgentStream
78

89

@@ -11,7 +12,12 @@ async def main() -> None:
1112

1213
agent_id = f"{int(time.time() * 1000)}-{AgentStream.__name__}"
1314
run_id = await client.schedule_agent(
14-
agent_name=AgentStream.__name__, agent_id=agent_id
15+
agent_name=AgentStream.__name__,
16+
agent_id=agent_id,
17+
event=AgentEvent(
18+
name="messages",
19+
input={"messages": [{"role": "user", "content": "Tell me a joke"}]},
20+
),
1521
)
1622

1723
await client.get_agent_result(agent_id=agent_id, run_id=run_id)

agent_video/pipecat/agent/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dependencies = [
1010
"python-dotenv>=1.0.1",
1111
"pydantic>=2.10.6",
1212
"watchfiles>=1.0.4",
13-
"restack-ai>=0.0.85",]
13+
"restack-ai>=0.0.87",]
1414

1515
[project.scripts]
1616
dev = "src.services:watch_services"

agent_video/pipecat/agent/src/agents/agent.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,26 @@
44
from pydantic import BaseModel
55
from restack_ai.agent import (
66
NonRetryableError,
7+
RetryPolicy,
78
agent,
89
import_functions,
910
log,
10-
RetryPolicy,
11-
uuid
11+
uuid,
1212
)
1313

14-
1514
from src.workflows.logic import LogicWorkflow, LogicWorkflowInput
1615

1716
with import_functions():
1817
from src.functions.context_docs import context_docs
18+
from src.functions.daily_send_data import (
19+
DailySendDataInput,
20+
daily_send_data,
21+
)
1922
from src.functions.llm_chat import (
2023
LlmChatInput,
2124
Message,
2225
llm_chat,
2326
)
24-
from src.functions.daily_send_data import daily_send_data, DailySendDataInput
2527
from src.functions.llm_talk import LlmTalkInput, llm_talk
2628

2729

@@ -32,15 +34,18 @@ class MessagesEvent(BaseModel):
3234
class EndEvent(BaseModel):
3335
end: bool
3436

37+
3538
class AgentInput(BaseModel):
3639
room_url: str
37-
model: Literal['restack', 'gpt-4o-mini', 'gpt-4o'] = 'restack'
40+
model: Literal["restack", "gpt-4o-mini", "gpt-4o"] = "restack"
3841
interactive_prompt: str | None = None
3942
reasoning_prompt: str | None = None
4043

44+
4145
class ContextEvent(BaseModel):
4246
context: str
4347

48+
4449
class DailyMessageEvent(BaseModel):
4550
message: str
4651
recipient: str | None = None
@@ -52,7 +57,9 @@ def __init__(self) -> None:
5257
self.end = False
5358
self.messages: list[Message] = []
5459
self.room_url = ""
55-
self.model: Literal['restack', 'gpt-4o-mini', 'gpt-4o'] = "restack"
60+
self.model: Literal[
61+
"restack", "gpt-4o-mini", "gpt-4o"
62+
] = "restack"
5663
self.interactive_prompt = ""
5764
self.reasoning_prompt = ""
5865
self.context = ""
@@ -84,7 +91,7 @@ async def messages(
8491
messages=self.messages[-3:],
8592
context=str(self.context),
8693
mode="default",
87-
model='gpt-4o-mini',
94+
model="ft:gpt-4o-mini-2024-07-18:restack::BJymdMm8",
8895
interactive_prompt=self.interactive_prompt,
8996
),
9097
start_to_close_timeout=timedelta(seconds=3),
@@ -104,7 +111,7 @@ async def messages(
104111
),
105112
start_to_close_timeout=timedelta(seconds=120),
106113
)
107-
114+
108115
except Exception as e:
109116
error_message = f"llm_chat function failed: {e}"
110117
raise NonRetryableError(error_message) from e
@@ -122,21 +129,26 @@ async def end(self, end: EndEvent) -> EndEvent:
122129
log.info("Received end")
123130
self.end = True
124131
return end
125-
132+
126133
@agent.event
127134
async def context(self, context: ContextEvent) -> str:
128135
log.info("Received context")
129136
self.context = context.context
130137
return self.context
131138

132139
@agent.event
133-
async def daily_message(self, daily_message: DailyMessageEvent) -> bool:
140+
async def daily_message(
141+
self, daily_message: DailyMessageEvent
142+
) -> bool:
134143
log.info("Received message", daily_message=daily_message)
135144
await agent.step(
136145
function=daily_send_data,
137146
function_input=DailySendDataInput(
138147
room_url=self.room_url,
139-
data={"text": daily_message.message, "author": "agent"},
148+
data={
149+
"text": daily_message.message,
150+
"author": "agent",
151+
},
140152
recipient=daily_message.recipient,
141153
),
142154
)
@@ -147,15 +159,17 @@ async def run(self, agent_input: AgentInput) -> None:
147159
try:
148160
self.room_url = agent_input.room_url
149161
self.model = agent_input.model
150-
self.interactive_prompt = agent_input.interactive_prompt
162+
self.interactive_prompt = (
163+
agent_input.interactive_prompt
164+
)
151165
self.reasoning_prompt = agent_input.reasoning_prompt
152166
docs = await agent.step(function=context_docs)
153167
except Exception as e:
154168
error_message = f"context_docs function failed: {e}"
155169
raise NonRetryableError(error_message) from e
156170
else:
157171
system_prompt = f"""
158-
You can answer questions about the following documentation:
172+
You are an AI assistant for Restack. You can answer questions about the following documentation:
159173
{docs}
160174
{self.interactive_prompt}
161175
"""

agent_video/pipecat/agent/src/functions/daily_create_room.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ async def daily_create_room(
3232
function_input: DailyRoomInput,
3333
) -> DailyRoomOutput:
3434
try:
35-
3635
api_key = os.getenv("DAILYCO_API_KEY")
3736
if not api_key:
3837
raise ValueError(

agent_video/pipecat/agent/src/functions/daily_send_data.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,35 @@
1111

1212
load_dotenv()
1313

14-
async def send_data_to_room(room_name: str, data: dict, recipient: str | None = "*") -> bool:
14+
15+
async def send_data_to_room(
16+
room_name: str, data: dict, recipient: str | None = "*"
17+
) -> bool:
1518
"""Send a message to a Daily room."""
1619
api_key = os.getenv("DAILYCO_API_KEY")
1720
if not api_key:
18-
raise ValueError("DAILYCO_API_KEY not set in environment.")
21+
raise ValueError(
22+
"DAILYCO_API_KEY not set in environment."
23+
)
1924

2025
headers = {
2126
"Authorization": f"Bearer {api_key}",
22-
"Content-Type": "application/json"
27+
"Content-Type": "application/json",
2328
}
2429

2530
url = f"https://api.daily.co/v1/rooms/{room_name}/send-app-message"
2631
recipient = recipient or "*"
27-
data = {
28-
"data": data,
29-
"recipient": recipient
30-
}
32+
data = {"data": data, "recipient": recipient}
3133

3234
async with aiohttp.ClientSession() as session:
33-
async with session.post(url, headers=headers, json=data) as response:
35+
async with session.post(
36+
url, headers=headers, json=data
37+
) as response:
3438
if response.status != 200:
3539
text = await response.text()
36-
raise Exception(f"Failed to send message (status: {response.status}): {text}")
40+
raise Exception(
41+
f"Failed to send message (status: {response.status}): {text}"
42+
)
3743

3844
return True
3945

@@ -43,15 +49,16 @@ class DailySendDataInput(BaseModel):
4349
data: dict
4450
recipient: str | None = "*"
4551

52+
4653
@function.defn(name="daily_send_data")
4754
async def daily_send_data(
4855
function_input: DailySendDataInput,
4956
) -> bool:
5057
try:
5158
return await send_data_to_room(
52-
room_name=function_input.room_url.split('/')[-1],
59+
room_name=function_input.room_url.split("/")[-1],
5360
data=function_input.data,
54-
recipient=function_input.recipient
61+
recipient=function_input.recipient,
5562
)
5663
except Exception as e:
5764
log.error("Error sending message to daily room", error=e)

agent_video/pipecat/agent/src/functions/llm_chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Message(BaseModel):
2525

2626
class LlmChatInput(BaseModel):
2727
system_content: str | None = None
28-
model: Literal['gpt-4o-mini', 'gpt-4o']
28+
model: Literal["gpt-4o-mini", "gpt-4o"]
2929
messages: list[Message] = Field(default_factory=list)
3030
stream: bool = True
3131

agent_video/pipecat/agent/src/functions/llm_logic.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import os
22
from typing import Literal
33

4-
from openai import OpenAI
4+
from openai import AsyncOpenAI
55
from pydantic import BaseModel
66
from restack_ai.function import NonRetryableError, function
7+
78
from src.functions.llm_chat import Message
89

10+
911
class LlmLogicResponse(BaseModel):
1012
"""Structured AI decision output used to interrupt conversations."""
1113

@@ -25,8 +27,9 @@ async def llm_logic(
2527
function_input: LlmLogicInput,
2628
) -> LlmLogicResponse:
2729
try:
28-
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
29-
30+
client = AsyncOpenAI(
31+
api_key=os.environ.get("OPENAI_API_KEY")
32+
)
3033

3134
if function_input.reasoning_prompt:
3235
system_prompt = (
@@ -36,12 +39,13 @@ async def llm_logic(
3639
else:
3740
system_prompt = (
3841
"Analyze the developer's questions and determine if an interruption is needed. "
42+
"For example, to ask a follow up question and keep the conversation going. "
3943
"Use the Restack documentation for accurate answers. "
4044
"Track what the developer has learned and update their belief state."
4145
f"Restack Documentation: {function_input.documentation}"
4246
)
4347

44-
response = client.beta.chat.completions.parse(
48+
response = await client.beta.chat.completions.parse(
4549
model="gpt-4o",
4650
messages=[
4751
{

agent_video/pipecat/agent/src/functions/llm_talk.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@
1212
from src.client import api_address
1313
from src.functions.llm_chat import Message
1414

15+
1516
class LlmTalkInput(BaseModel):
1617
messages: list[Message] = Field(default_factory=list)
1718
context: str | None = None # Updated context from Slow AI
1819
mode: Literal["default", "interrupt"]
1920
stream: bool = True
20-
model: Literal['gpt-4o-mini', 'gpt-4o']
21+
model: Literal[
22+
"gpt-4o-mini",
23+
"gpt-4o",
24+
"ft:gpt-4o-mini-2024-07-18:restack::BJymdMm8",
25+
]
2126
interactive_prompt: str | None = None
2227

28+
2329
@function.defn()
2430
async def llm_talk(function_input: LlmTalkInput) -> str:
2531
"""Fast AI generates responses while checking for memory updates."""
@@ -31,12 +37,13 @@ async def llm_talk(function_input: LlmTalkInput) -> str:
3137
if interactive_prompt:
3238
system_prompt = (
3339
interactive_prompt
34-
+ "Current context: " + function_input.context
40+
+ "Current context: "
41+
+ function_input.context
3542
)
3643

3744
else:
3845
common_prompt = (
39-
"Your are an AI assistant helping developers build with restack: the backend framework for accurate & reliable AI agents."
46+
"Your are an AI assistant helping developers build with restack: the backend framework for accurate & reliable AI agents."
4047
"Your interface with users will be voice. Be friendly, helpful and avoid usage of unpronouncable punctuation."
4148
"Always try to bring back the conversation to restack if the user is talking about something else. "
4249
"Current context: " + function_input.context

agent_video/pipecat/agent/src/functions/tavus_create_room.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
class TavusRoomOutput(BaseModel):
1717
room_url: str
1818

19+
1920
@function.defn(name="tavus_create_room")
2021
async def tavus_create_room() -> TavusRoomOutput:
2122
try:
@@ -28,13 +29,18 @@ async def tavus_create_room() -> TavusRoomOutput:
2829

2930
async with aiohttp.ClientSession() as session:
3031
url = "https://tavusapi.com/v2/conversations"
31-
headers = {"Content-Type": "application/json", "x-api-key": api_key}
32+
headers = {
33+
"Content-Type": "application/json",
34+
"x-api-key": api_key,
35+
}
3236
payload = {
3337
"replica_id": replica_id,
3438
"persona_id": "pipecat0",
3539
}
3640

37-
async with session.post(url, headers=headers, json=payload) as r:
41+
async with session.post(
42+
url, headers=headers, json=payload
43+
) as r:
3844
r.raise_for_status()
3945
response_json = await r.json()
4046

@@ -47,4 +53,4 @@ async def tavus_create_room() -> TavusRoomOutput:
4753
log.error("Error creating Tavus room", error=e)
4854
raise NonRetryableError(
4955
f"Error creating Tavus room: {e}",
50-
) from e
56+
) from e

agent_video/pipecat/agent/src/services.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
import webbrowser
44
from pathlib import Path
55

6+
from restack_ai.restack import ServiceOptions
67
from watchfiles import run_process
78

89
from src.agents.agent import AgentVideo
910
from src.client import client
1011
from src.functions.context_docs import context_docs
11-
from src.functions.llm_chat import llm_chat
12-
from src.workflows.room import RoomWorkflow
13-
from restack_ai.restack import ServiceOptions
1412
from src.functions.daily_create_room import daily_create_room
15-
from src.functions.tavus_create_room import tavus_create_room
1613
from src.functions.daily_send_data import daily_send_data
14+
from src.functions.llm_chat import llm_chat
15+
from src.functions.llm_logic import llm_logic
16+
from src.functions.llm_talk import llm_talk
1717
from src.functions.send_agent_event import send_agent_event
18+
from src.functions.tavus_create_room import tavus_create_room
1819
from src.workflows.logic import LogicWorkflow
19-
from src.functions.llm_talk import llm_talk
20-
from src.functions.llm_logic import llm_logic
20+
from src.workflows.room import RoomWorkflow
21+
2122

2223
async def main() -> None:
2324
await client.start_service(

0 commit comments

Comments
 (0)