-
Notifications
You must be signed in to change notification settings - Fork 2.3k
[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
base: main
Are you sure you want to change the base?
[draft] async text mode #4337
Conversation
| result = await session.run(user_input=ctx.text) | ||
|
|
||
| await ctx.send_result(result) | ||
| await ctx.save_session(session) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: how do you feel about automatically saving with a context manager?
async with ctx.resume(session=session, session_data=session_data, agent=...):
...
so users don't have to call ctx.save_session explicitly?
| result = await session.run(user_input=ctx.text) | ||
|
|
||
| await ctx.send_result(result) | ||
| await ctx.save_session(session) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for rtc_session, we have operations at the session level:
- session.generate_reply
- session.say
- session.run
It feels out of sync to me if we have to use ctx to send_result. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree it’s a bit odd to have this “out of sync” issue. I think the agent code shouldn’t be sending SMS outside the sms_handler tho. Just for separation of concerns.
| await sms_handler(text_context) | ||
|
|
||
| # serialize the state of the session | ||
| if text_context.session_data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QQ: how about we handle this inside ctx.save_session?
| self._greet_on_enter = greet_on_enter | ||
|
|
||
| async def on_enter(self): | ||
| if self._greet_on_enter: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to add a function called on_rehydrate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically going to be the default Python def __setstate__ method.
| async def aclose(self) -> None: | ||
| await self._aclose_impl(reason=CloseReason.USER_INITIATED) | ||
|
|
||
| def get_state(self) -> dict[str, Any]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we standardize this with __setstate__ and __getstate__ functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw, for the AgentSession, I think this method should stay private
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't use __setstate__ and __getstate__ because we cannot load the AgentSession using pickle.loads(data) directly if it's required to create the AgentSession in user's code.
| tool_ctx = llm.ToolContext(self.tools) | ||
| return { | ||
| "tools": list(tool_ctx.function_tools.keys()), | ||
| "chat_ctx": self._chat_ctx.to_dict( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the AgentSession, we should name it history
| "chat_ctx": self._chat_ctx.to_dict( | |
| "history": self._chat_ctx.to_dict( |
|
|
||
| return self._activity | ||
|
|
||
| def __getstate__(self) -> dict[str, Any]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should it looks like from the user perspective when they add their own states, should they override this function and call super().__getstate__?
| async def sms_handler(ctx: TextMessageContext): | ||
| logger.info(f"SMS received: {ctx.text}") | ||
|
|
||
| session = AgentSession(llm="openai/gpt-4.1-mini") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we let user to setup some config for sms handler here?
Something like that:
- `conversation_id` (required) — unique identifier for the conversation partner (Default to ctx.participant_number?)
- `retention_hours` (optional, default 168 = 7 days) — how long to store session
- `max_tokens` (optional) — limit on loaded context size
- `encryption_key` (optional) — for E2E encryption
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And maybe:
auto_save — almost always True. False only if developer wants conditional saving (e.g., don't save if user asked to "forget" instantly)
to test it