Initialize the task, with an optional message to start the conversation. Initializes `self.pending_message` and `self.pending_sender`. Args: msg (str|ChatDocument): optional message to start the conversation. Returns: (ChatDocument|None): the
(self, msg: None | str | ChatDocument = None)
| 608 | self.non_human_responders_async.append(cast(Responder, task)) |
| 609 | |
| 610 | def init(self, msg: None | str | ChatDocument = None) -> ChatDocument | None: |
| 611 | """ |
| 612 | Initialize the task, with an optional message to start the conversation. |
| 613 | Initializes `self.pending_message` and `self.pending_sender`. |
| 614 | Args: |
| 615 | msg (str|ChatDocument): optional message to start the conversation. |
| 616 | |
| 617 | Returns: |
| 618 | (ChatDocument|None): the initialized `self.pending_message`. |
| 619 | Currently not used in the code, but provided for convenience. |
| 620 | """ |
| 621 | self.pending_sender = Entity.USER |
| 622 | if isinstance(msg, str): |
| 623 | self.pending_message = ChatDocument( |
| 624 | content=msg, |
| 625 | metadata=ChatDocMetaData( |
| 626 | sender=Entity.USER, |
| 627 | # external user input -> untrusted (#1035) |
| 628 | tainted=True, |
| 629 | ), |
| 630 | ) |
| 631 | elif msg is None and len(self.agent.message_history) > 1: |
| 632 | # if agent has a history beyond system msg, set the |
| 633 | # pending message to the ChatDocument linked from |
| 634 | # last message in the history |
| 635 | last_agent_msg = self.agent.message_history[-1] |
| 636 | self.pending_message = ChatDocument.from_id(last_agent_msg.chat_document_id) |
| 637 | if self.pending_message is not None: |
| 638 | self.pending_sender = self.pending_message.metadata.sender |
| 639 | else: |
| 640 | if isinstance(msg, ChatDocument): |
| 641 | # carefully deep-copy: fresh metadata.id, register |
| 642 | # as new obj in registry |
| 643 | original_parent_id = msg.metadata.parent_id |
| 644 | self.pending_message = ChatDocument.deepcopy(msg) |
| 645 | # Preserve the parent pointer from the original message |
| 646 | self.pending_message.metadata.parent_id = original_parent_id |
| 647 | # A USER-origin ChatDocument handed to a ROOT task (caller is |
| 648 | # None) is external untrusted input (e.g. Task.run(ChatDocument( |
| 649 | # sender=USER, ...))) that bypassed the tainting constructors -- |
| 650 | # taint it. Sub-task inputs (caller is not None, relabeled to |
| 651 | # USER just below) keep their propagated taint; we only set. #1035 |
| 652 | if ( |
| 653 | self.caller is None |
| 654 | and self.pending_message.metadata.sender == Entity.USER |
| 655 | ): |
| 656 | self.pending_message.metadata.tainted = True |
| 657 | if self.pending_message is not None and self.caller is not None: |
| 658 | # msg may have come from `caller`, so we pretend this is from |
| 659 | # the CURRENT task's USER entity |
| 660 | self.pending_message.metadata.sender = Entity.USER |
| 661 | # update parent, child, agent pointers |
| 662 | if msg is not None: |
| 663 | msg.metadata.child_id = self.pending_message.metadata.id |
| 664 | # Only override parent_id if it wasn't already set in the |
| 665 | # original message. This preserves parent chains from TaskTool |
| 666 | if not msg.metadata.parent_id: |
| 667 | self.pending_message.metadata.parent_id = msg.metadata.id |