| 37 | class Delegation(Tool): |
| 38 | |
| 39 | async def execute(self, message="", reset="", **kwargs): |
| 40 | requested_profile = _validate_subordinate_profile( |
| 41 | self.agent, kwargs.get("profile", kwargs.get("agent_profile", "")) |
| 42 | ) |
| 43 | existing_subordinate = self.agent.get_data(Agent.DATA_NAME_SUBORDINATE) |
| 44 | reset_requested = str(reset).lower().strip() == "true" |
| 45 | |
| 46 | if existing_subordinate and requested_profile and not reset_requested: |
| 47 | current_profile = str( |
| 48 | getattr(getattr(existing_subordinate, "config", None), "profile", "") |
| 49 | or "" |
| 50 | ) |
| 51 | if current_profile != requested_profile: |
| 52 | raise RepairableException( |
| 53 | f"Subordinate already uses profile '{current_profile or 'default'}'. " |
| 54 | f"Set reset=true to switch to '{requested_profile}'." |
| 55 | ) |
| 56 | |
| 57 | # create subordinate agent using the data object on this agent and set superior agent to his data object |
| 58 | if ( |
| 59 | existing_subordinate is None |
| 60 | or reset_requested |
| 61 | ): |
| 62 | # set subordinate prompt profile if provided, otherwise use the default profile |
| 63 | override_settings = ( |
| 64 | {"agent_profile": requested_profile} if requested_profile else None |
| 65 | ) |
| 66 | config = initialize_agent(override_settings=override_settings) |
| 67 | |
| 68 | # create agent |
| 69 | sub = Agent(self.agent.number + 1, config, self.agent.context) |
| 70 | # register superior/subordinate |
| 71 | sub.set_data(Agent.DATA_NAME_SUPERIOR, self.agent) |
| 72 | self.agent.set_data(Agent.DATA_NAME_SUBORDINATE, sub) |
| 73 | |
| 74 | # add user message to subordinate agent |
| 75 | subordinate: Agent = self.agent.get_data(Agent.DATA_NAME_SUBORDINATE) # type: ignore |
| 76 | subordinate.hist_add_user_message(UserMessage(message=message, attachments=[])) |
| 77 | |
| 78 | # run subordinate monologue |
| 79 | result = await subordinate.monologue() |
| 80 | |
| 81 | # seal the subordinate's current topic so messages move to `topics` for compression |
| 82 | subordinate.history.new_topic() |
| 83 | |
| 84 | # hint to use includes for long responses |
| 85 | additional = None |
| 86 | if len(result) >= save_tool_call_file.LEN_MIN: |
| 87 | hint = self.agent.read_prompt("fw.hint.call_sub.md") |
| 88 | if hint: |
| 89 | additional = {"hint": hint} |
| 90 | |
| 91 | # result |
| 92 | return Response(message=result, break_loop=False, additional=additional) |
| 93 | |
| 94 | def get_log_object(self): |
| 95 | return self.agent.context.log.log( |