-
Notifications
You must be signed in to change notification settings - Fork 2.9k
[draft] async text mode #4337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
longcw
wants to merge
59
commits into
main
Choose a base branch
from
longc/text-mode
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,430
−301
Draft
[draft] async text mode #4337
Changes from all commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
1c7b33e
wip
longcw 8eba4e9
add logs
longcw de63ced
add sms-console
longcw fedadd3
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw e0f387b
fix types
longcw 4e2b715
fix agent handoff
longcw d8bf768
fix wrapped entrypoint
longcw 5d05117
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw a092a42
save session after the text handler
longcw d6c7065
add multiple responses
longcw 4f22115
add e2e encryption
longcw 30f9711
add get_init_kwargs
longcw 6084764
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw fcc3b92
serialize old_agent for AgentTask
longcw 03ac592
add Agent.configure
longcw 7bdae50
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 1eff439
hand text message request from lk server (#4553)
longcw 12c6b88
durable scheduler WIP
theomonnom 685e7b8
contextvars already handled
theomonnom 8495cea
export session state as db and compute delta for sync (#4604)
longcw 52f1eb2
durable functions integration (#4647)
longcw 4db5018
update sms cli
longcw cb731e4
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 214f5f7
clean and update session store versions
longcw 09a2026
fix types
longcw 29f13e4
save init kwargs as blob
longcw 363d168
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw c763a96
store chat ctx as text
longcw 128ceb8
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw acad0a7
ignore config update
longcw 9a1e67e
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 54fc75a
add http server for text mode (#4718)
longcw b4f9246
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 2a18d4e
fix cli
longcw c854820
fix cli
longcw ba69121
fix drain messages in buffer before close
longcw 970976c
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 2511a47
fix SpeechHandle creation
longcw 9c10af2
update endpoint and fix http server close
longcw b7782f5
update session store and cache
longcw 5ca2442
rename durable and http sever modules
longcw 0bfbd27
add error code to types
longcw c45f6f6
update protocol for http api
longcw 207b6f2
fix import
longcw 5f7dca2
update to response proto
longcw e46bd74
handle durable unpickle error
longcw fbc978f
fix typo
longcw b3590c9
handle durable function failure
longcw c5c7f70
fix durable function resume
longcw 9d9179f
remove session started event
longcw 93ab71b
fix _resume_durable_function
longcw e4683b2
fix types
longcw 19d781a
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 6d3979d
fix durable scheduler shutdown and text mode session cleanup
longcw e346db6
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw fcbeda8
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 3d7ebea
Merge remote-tracking branch 'origin/main' into longc/text-mode
longcw 58ee25a
use Instructions in example
longcw 8f90a86
add setup_fnc for Agent
longcw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| import logging | ||
| import os | ||
|
|
||
| import aiohttp | ||
| from dotenv import load_dotenv | ||
|
|
||
| from livekit.agents import ( | ||
| Agent, | ||
| AgentServer, | ||
| AgentSession, | ||
| EffectCall, | ||
| JobContext, | ||
| JobExecutorType, | ||
| RunContext, | ||
| TextMessageContext, | ||
| cli, | ||
| ) | ||
| from livekit.agents.beta.workflows import GetEmailTask | ||
| from livekit.agents.llm import Instructions, ToolFlag, function_tool | ||
| from livekit.plugins import silero | ||
| from livekit.plugins.turn_detector.multilingual import MultilingualModel | ||
|
|
||
| logger = logging.getLogger("basic-agent") | ||
|
|
||
| load_dotenv() | ||
|
|
||
| PORT = int(os.getenv("PORT", 8081)) | ||
|
|
||
|
|
||
| class MyAgent(Agent): | ||
| BASE_INSTRUCTIONS = ( | ||
| "Your name is Kelly. You would interact with users via {modality}. " | ||
| "with that in mind keep your responses concise and to the point. " | ||
| "{modality_specific}" | ||
| "You are curious and friendly, and have a sense of humor. " | ||
| "When user want to register for the weather event, call the `register_for_weather` function. " | ||
| ) | ||
|
|
||
| def __init__(self) -> None: | ||
| super().__init__( | ||
| instructions=Instructions( | ||
| audio=self.BASE_INSTRUCTIONS.format( | ||
| modality="voice", | ||
| modality_specific="do not use emojis, asterisks, markdown, or other special characters in your responses.", | ||
| ), | ||
| text=self.BASE_INSTRUCTIONS.format( | ||
| modality="text", | ||
| modality_specific="you can use emojis to make your responses more engaging.", | ||
| ), | ||
| ), | ||
| ) | ||
|
|
||
| @function_tool | ||
| async def get_weather( | ||
| self, | ||
| latitude: str, | ||
| longitude: str, | ||
| ): | ||
| """Called when the user asks about the weather. This function will return the weather for | ||
| the given location. When given a location, please estimate the latitude and longitude of the | ||
| location and do not ask the user for them. | ||
|
|
||
| Args: | ||
| latitude: The latitude of the location | ||
| longitude: The longitude of the location | ||
| """ | ||
|
|
||
| logger.info(f"getting weather for {latitude}, {longitude}") | ||
| self.session.say("I'm getting the weather for you...") | ||
|
|
||
| url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m" | ||
| weather_data = {} | ||
| async with aiohttp.ClientSession() as session: | ||
| async with session.get(url) as response: | ||
| if response.status == 200: | ||
| data = await response.json() | ||
| # response from the function call is returned to the LLM | ||
| weather_data = { | ||
| "temperature": data["current"]["temperature_2m"], | ||
| "temperature_unit": "Celsius", | ||
| } | ||
| else: | ||
| raise Exception(f"Failed to get weather data, status code: {response.status}") | ||
|
|
||
| return weather_data | ||
|
|
||
| @function_tool(flags=ToolFlag.DURABLE) | ||
| async def register_for_weather(self, context: RunContext): | ||
| """Called when the user wants to register for the weather event.""" | ||
| logger.info("register_for_weather called") | ||
|
|
||
| chat_ctx = self.chat_ctx.copy( | ||
| exclude_function_call=True, exclude_instructions=True, exclude_config_update=True | ||
| ) | ||
| email_result = await EffectCall( | ||
| GetEmailTask( | ||
| chat_ctx=chat_ctx, | ||
| setup_fnc=lambda agent: agent.configure(llm="openai/gpt-4.1"), | ||
| ) | ||
| ) | ||
| email_address = email_result.email_address | ||
|
|
||
| logger.info(f"User's email address: {email_address}") | ||
|
|
||
| return "You are now registered for the weather event." | ||
| # context.session.say("You are now registered for the weather event.") | ||
|
|
||
|
|
||
| server = AgentServer(port=PORT, job_executor_type=JobExecutorType.THREAD) | ||
|
|
||
|
|
||
| @server.text_handler(endpoint="weather") | ||
| async def text_handler(ctx: TextMessageContext): | ||
| logger.info(f"text message received: {ctx.text}") | ||
|
|
||
| session = AgentSession( | ||
| llm="openai/gpt-4.1-mini", | ||
| # state_passphrase="my-secret-passphrase", | ||
| ) | ||
|
|
||
| start_result = await session.start( | ||
| agent=ctx.session_state if ctx.session_state else MyAgent(), | ||
| capture_run=True, | ||
| wait_run_state=False, | ||
| ) | ||
| async for ev in start_result: | ||
| await ctx.send_response(ev) | ||
|
|
||
| logger.info(f"running session with text input: {ctx.text}") | ||
| async for ev in session.run(user_input=ctx.text): | ||
| await ctx.send_response(ev) | ||
|
|
||
|
|
||
| @server.rtc_session() | ||
| async def entrypoint(ctx: JobContext): | ||
| session = AgentSession( | ||
| stt="deepgram/nova-3", | ||
| llm="openai/gpt-4.1-mini", | ||
| tts="cartesia/sonic-2:9626c31c-bec5-4cca-baa8-f8ba9e84c8bc", | ||
| turn_detection=MultilingualModel(), | ||
| vad=silero.VAD.load(), | ||
| preemptive_generation=True, | ||
| ) | ||
|
|
||
| await session.start(agent=MyAgent(), room=ctx.room) | ||
|
|
||
| session.generate_reply(instructions="greeting the user", input_modality="audio") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| cli.run_app(server) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.