| 25 | |
| 26 | |
| 27 | class EventHandler(AsyncAssistantEventHandler): |
| 28 | def __init__(self, assistant_name: str) -> None: |
| 29 | super().__init__() |
| 30 | self.current_message: cl.Message = None |
| 31 | self.current_step: cl.Step = None |
| 32 | self.current_tool_call = None |
| 33 | self.assistant_name = assistant_name |
| 34 | previous_steps = local_steps.get() or [] |
| 35 | parent_step = previous_steps[-1] if previous_steps else None |
| 36 | if parent_step: |
| 37 | self.parent_id = parent_step.id |
| 38 | |
| 39 | async def on_run_step_created(self, run_step: RunStep) -> None: |
| 40 | cl.user_session.set("run_step", run_step) |
| 41 | |
| 42 | async def on_text_created(self, text) -> None: |
| 43 | self.current_message = await cl.Message( |
| 44 | author=self.assistant_name, content="" |
| 45 | ).send() |
| 46 | |
| 47 | async def on_text_delta(self, delta, snapshot): |
| 48 | if delta.value: |
| 49 | await self.current_message.stream_token(delta.value) |
| 50 | |
| 51 | async def on_text_done(self, text): |
| 52 | await self.current_message.update() |
| 53 | if text.annotations: |
| 54 | for annotation in text.annotations: |
| 55 | if annotation.type == "file_path": |
| 56 | response = ( |
| 57 | await async_openai_client.files.with_raw_response.content( |
| 58 | annotation.file_path.file_id |
| 59 | ) |
| 60 | ) |
| 61 | file_name = annotation.text.split("/")[-1] |
| 62 | try: |
| 63 | fig = plotly.io.from_json(response.content) |
| 64 | element = cl.Plotly(name=file_name, figure=fig) |
| 65 | await cl.Message(content="", elements=[element]).send() |
| 66 | except Exception as e: |
| 67 | element = cl.File(content=response.content, name=file_name) |
| 68 | await cl.Message(content="", elements=[element]).send() |
| 69 | # Hack to fix links |
| 70 | if ( |
| 71 | annotation.text in self.current_message.content |
| 72 | and element.chainlit_key |
| 73 | ): |
| 74 | self.current_message.content = self.current_message.content.replace( |
| 75 | annotation.text, |
| 76 | f"/project/file/{element.chainlit_key}?session_id={cl.context.session.id}", |
| 77 | ) |
| 78 | await self.current_message.update() |
| 79 | |
| 80 | async def on_tool_call_created(self, tool_call): |
| 81 | self.current_tool_call = tool_call.id |
| 82 | self.current_step = cl.Step( |
| 83 | name=tool_call.type, type="tool", parent_id=self.parent_id |
| 84 | ) |