-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[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
Changes from 2 commits
1c7b33e
8eba4e9
de63ced
fedadd3
e0f387b
4e2b715
d8bf768
5d05117
a092a42
d6c7065
4f22115
30f9711
6084764
fcc3b92
03ac592
7bdae50
1eff439
12c6b88
685e7b8
8495cea
52f1eb2
4db5018
cb731e4
214f5f7
09a2026
29f13e4
363d168
c763a96
128ceb8
acad0a7
9a1e67e
54fc75a
b4f9246
2a18d4e
c854820
ba69121
970976c
2511a47
9c10af2
b7782f5
5ca2442
0bfbd27
c45f6f6
207b6f2
5f7dca2
e46bd74
fbc978f
b3590c9
c5c7f70
9d9179f
93ab71b
e4683b2
19d781a
6d3979d
e346db6
fcbeda8
3d7ebea
58ee25a
8f90a86
73c22ef
f93f61f
8e85966
227b906
3e962cf
c853dbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,6 +93,7 @@ def __init__( | |
|
|
||
| self._mcp_servers = mcp_servers | ||
| self._activity: AgentActivity | None = None | ||
| self._rehydrated = False | ||
|
|
||
| @property | ||
| def id(self) -> str: | ||
|
|
@@ -359,6 +360,35 @@ def _get_activity_or_raise(self) -> AgentActivity: | |
|
|
||
| return self._activity | ||
|
|
||
| def __getstate__(self) -> dict[str, Any]: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| tool_ctx = llm.ToolContext(self.tools) | ||
| return { | ||
| "tools": list(tool_ctx.function_tools.keys()), | ||
| "chat_ctx": self.chat_ctx.to_dict(), | ||
| } | ||
|
|
||
| def __setstate__(self, state: dict[str, Any]) -> None: | ||
| try: | ||
| self.__init__() | ||
| except TypeError as e: | ||
| logger.error("Agent rehydration requires a zero-argument constructor") | ||
| raise e | ||
|
|
||
| tool_ctx = llm.ToolContext(self.tools) | ||
| valid_tools: list[llm.FunctionTool | llm.RawFunctionTool] = [] | ||
| for name in state["tools"]: | ||
| if name in tool_ctx.function_tools: | ||
| valid_tools.append(tool_ctx.function_tools[name]) | ||
| else: | ||
| logger.warning("tool not found when unpickling", extra={"missing_tool": name}) | ||
|
|
||
| # TODO: serialize the ongoing speech tasks? | ||
| # TODO: support AgentTask | ||
|
|
||
| self._tools = valid_tools | ||
| self._chat_ctx = llm.ChatContext.from_dict(state["chat_ctx"]) | ||
| self._rehydrated = True # skip on_enter when rehydrating | ||
|
|
||
| class default: | ||
| @staticmethod | ||
| async def stt_node( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ | |
| from types import TracebackType | ||
| from typing import ( | ||
| TYPE_CHECKING, | ||
| Any, | ||
| Generic, | ||
| Literal, | ||
| Optional, | ||
|
|
@@ -838,6 +839,32 @@ async def _aclose_impl( | |
| async def aclose(self) -> None: | ||
| await self._aclose_impl(reason=CloseReason.USER_INITIATED) | ||
|
|
||
| def get_state(self) -> dict[str, Any]: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we standardize this with
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fwiw, for the AgentSession, I think this method should stay private
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't use |
||
| tool_ctx = llm.ToolContext(self.tools) | ||
| return { | ||
| "tools": list(tool_ctx.function_tools.keys()), | ||
| "chat_ctx": self._chat_ctx.to_dict(), | ||
| "agent": self._agent, | ||
| } | ||
|
|
||
| async def rehydrate(self, state: dict[str, Any]) -> None: | ||
| tool_ctx = llm.ToolContext(self.tools) | ||
| valid_tools: list[llm.FunctionTool | llm.RawFunctionTool] = [] | ||
| for name in state["tools"]: | ||
| if name in tool_ctx.function_tools: | ||
| valid_tools.append(tool_ctx.function_tools[name]) | ||
| else: | ||
| logger.warning("tool not found when unpickling", extra={"missing_tool": name}) | ||
|
|
||
| self._tools = valid_tools | ||
| self._chat_ctx = llm.ChatContext.from_dict(state["chat_ctx"]) | ||
|
|
||
| if self._started: | ||
| # only allow rehydrate session that not started yet? | ||
| await self._update_activity(state["agent"]) | ||
| else: | ||
| await self.start(agent=state["agent"]) | ||
|
|
||
| def update_options( | ||
| self, | ||
| *, | ||
|
|
@@ -1076,8 +1103,7 @@ async def _update_activity( | |
| await self._activity.resume() | ||
|
|
||
| # move it outside the lock to allow calling _update_activity in on_enter of a new agent | ||
| if wait_on_enter: | ||
| assert self._activity._on_enter_task is not None | ||
| if wait_on_enter and self._activity._on_enter_task: | ||
| await asyncio.shield(self._activity._on_enter_task) | ||
|
|
||
| @utils.log_exceptions(logger=logger) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.