| 1 | from helpers import persist_chat, tokens |
| 2 | from helpers import extract_tools |
| 3 | from helpers.extension import Extension |
| 4 | from agent import LoopData |
| 5 | import asyncio |
| 6 | from helpers.log import LogItem |
| 7 | from helpers import log |
| 8 | |
| 9 | |
| 10 | class LiveResponse(Extension): |
| 11 | |
| 12 | async def execute( |
| 13 | self, |
| 14 | loop_data: LoopData = LoopData(), |
| 15 | text: str = "", |
| 16 | parsed: dict = {}, |
| 17 | **kwargs, |
| 18 | ): |
| 19 | if not self.agent: |
| 20 | return |
| 21 | |
| 22 | try: |
| 23 | tool_name, tool_args = extract_tools.normalize_tool_request(parsed) |
| 24 | message = tool_args.get("text") |
| 25 | if not isinstance(message, str) or not message.strip(): |
| 26 | message = tool_args.get("message") |
| 27 | if ( |
| 28 | tool_name != "response" |
| 29 | or not isinstance(message, str) |
| 30 | or not message.strip() |
| 31 | ): |
| 32 | return # not a response |
| 33 | |
| 34 | # create log message and store it in loop data temporary params |
| 35 | if "log_item_response" not in loop_data.params_temporary: |
| 36 | # Share id with the agent log item so branching covers the response bubble |
| 37 | gen_item = loop_data.params_temporary.get("log_item_generating") |
| 38 | shared_id = gen_item.id if gen_item and gen_item.id else "" |
| 39 | loop_data.params_temporary["log_item_response"] = ( |
| 40 | self.agent.context.log.log( |
| 41 | type="response", |
| 42 | heading=f"icon://chat {self.agent.agent_name}: Responding", |
| 43 | id=shared_id, |
| 44 | ) |
| 45 | ) |
| 46 | |
| 47 | # update log message |
| 48 | log_item = loop_data.params_temporary["log_item_response"] |
| 49 | log_item.update(content=message) |
| 50 | except Exception as e: |
| 51 | pass |