deepagents-cli 0.0.3__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of deepagents-cli might be problematic. Click here for more details.

Files changed (41) hide show
  1. deepagents_cli/__init__.py +5 -0
  2. deepagents_cli/__main__.py +6 -0
  3. deepagents_cli/agent.py +267 -0
  4. deepagents_cli/cli.py +13 -0
  5. deepagents_cli/commands.py +86 -0
  6. deepagents_cli/config.py +138 -0
  7. deepagents_cli/execution.py +644 -0
  8. deepagents_cli/file_ops.py +347 -0
  9. deepagents_cli/input.py +249 -0
  10. deepagents_cli/main.py +217 -0
  11. deepagents_cli/py.typed +0 -0
  12. deepagents_cli/tools.py +140 -0
  13. deepagents_cli/ui.py +455 -0
  14. deepagents_cli-0.0.4.dist-info/METADATA +18 -0
  15. deepagents_cli-0.0.4.dist-info/RECORD +18 -0
  16. deepagents_cli-0.0.4.dist-info/entry_points.txt +3 -0
  17. deepagents_cli-0.0.4.dist-info/top_level.txt +1 -0
  18. deepagents/__init__.py +0 -7
  19. deepagents/cli.py +0 -567
  20. deepagents/default_agent_prompt.md +0 -64
  21. deepagents/graph.py +0 -144
  22. deepagents/memory/__init__.py +0 -17
  23. deepagents/memory/backends/__init__.py +0 -15
  24. deepagents/memory/backends/composite.py +0 -250
  25. deepagents/memory/backends/filesystem.py +0 -330
  26. deepagents/memory/backends/state.py +0 -206
  27. deepagents/memory/backends/store.py +0 -351
  28. deepagents/memory/backends/utils.py +0 -319
  29. deepagents/memory/protocol.py +0 -164
  30. deepagents/middleware/__init__.py +0 -13
  31. deepagents/middleware/agent_memory.py +0 -207
  32. deepagents/middleware/filesystem.py +0 -615
  33. deepagents/middleware/patch_tool_calls.py +0 -44
  34. deepagents/middleware/subagents.py +0 -481
  35. deepagents/pretty_cli.py +0 -289
  36. deepagents_cli-0.0.3.dist-info/METADATA +0 -551
  37. deepagents_cli-0.0.3.dist-info/RECORD +0 -24
  38. deepagents_cli-0.0.3.dist-info/entry_points.txt +0 -2
  39. deepagents_cli-0.0.3.dist-info/licenses/LICENSE +0 -21
  40. deepagents_cli-0.0.3.dist-info/top_level.txt +0 -1
  41. {deepagents_cli-0.0.3.dist-info → deepagents_cli-0.0.4.dist-info}/WHEEL +0 -0
@@ -1,481 +0,0 @@
1
- """Middleware for providing subagents to an agent via a `task` tool."""
2
-
3
- from collections.abc import Awaitable, Callable, Sequence
4
- from typing import Any, TypedDict, cast
5
- from typing_extensions import NotRequired
6
-
7
- from langchain.agents import create_agent
8
- from langchain.agents.middleware import HumanInTheLoopMiddleware, InterruptOnConfig
9
- from langchain.agents.middleware.types import AgentMiddleware, ModelRequest, ModelResponse
10
- from langchain.tools import BaseTool, ToolRuntime
11
- from langchain_core.language_models import BaseChatModel
12
- from langchain_core.messages import HumanMessage, ToolMessage
13
- from langchain_core.runnables import Runnable
14
- from langchain_core.tools import StructuredTool
15
- from langgraph.types import Command
16
-
17
-
18
- class SubAgent(TypedDict):
19
- """Specification for an agent.
20
-
21
- When specifying custom agents, the `default_middleware` from `SubAgentMiddleware`
22
- will be applied first, followed by any `middleware` specified in this spec.
23
- To use only custom middleware without the defaults, pass `default_middleware=[]`
24
- to `SubAgentMiddleware`.
25
- """
26
-
27
- name: str
28
- """The name of the agent."""
29
-
30
- description: str
31
- """The description of the agent."""
32
-
33
- system_prompt: str
34
- """The system prompt to use for the agent."""
35
-
36
- tools: Sequence[BaseTool | Callable | dict[str, Any]]
37
- """The tools to use for the agent."""
38
-
39
- model: NotRequired[str | BaseChatModel]
40
- """The model for the agent. Defaults to `default_model`."""
41
-
42
- middleware: NotRequired[list[AgentMiddleware]]
43
- """Additional middleware to append after `default_middleware`."""
44
-
45
- interrupt_on: NotRequired[dict[str, bool | InterruptOnConfig]]
46
- """The tool configs to use for the agent."""
47
-
48
-
49
- class CompiledSubAgent(TypedDict):
50
- """A pre-compiled agent spec."""
51
-
52
- name: str
53
- """The name of the agent."""
54
-
55
- description: str
56
- """The description of the agent."""
57
-
58
- runnable: Runnable
59
- """The Runnable to use for the agent."""
60
-
61
-
62
- DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools."
63
-
64
- # State keys that should be excluded when passing state to subagents
65
- _EXCLUDED_STATE_KEYS = ("messages", "todos")
66
-
67
- TASK_TOOL_DESCRIPTION = """Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.
68
-
69
- Available agent types and the tools they have access to:
70
- {available_agents}
71
-
72
- When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
73
-
74
- ## Usage notes:
75
- 1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
76
- 2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
77
- 3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
78
- 4. The agent's outputs should generally be trusted
79
- 5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
80
- 6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
81
- 7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.
82
-
83
- ### Example usage of the general-purpose agent:
84
-
85
- <example_agent_descriptions>
86
- "general-purpose": use this agent for general purpose tasks, it has access to all tools as the main agent.
87
- </example_agent_descriptions>
88
-
89
- <example>
90
- User: "I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them."
91
- Assistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*
92
- Assistant: *Synthesizes the results of the three isolated research tasks and responds to the User*
93
- <commentary>
94
- Research is a complex, multi-step task in it of itself.
95
- The research of each individual player is not dependent on the research of the other players.
96
- The assistant uses the task tool to break down the complex objective into three isolated tasks.
97
- Each research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.
98
- This means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.
99
- </commentary>
100
- </example>
101
-
102
- <example>
103
- User: "Analyze a single large code repository for security vulnerabilities and generate a report."
104
- Assistant: *Launches a single `task` subagent for the repository analysis*
105
- Assistant: *Receives report and integrates results into final summary*
106
- <commentary>
107
- Subagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.
108
- If the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.
109
- </commentary>
110
- </example>
111
-
112
- <example>
113
- User: "Schedule two meetings for me and prepare agendas for each."
114
- Assistant: *Calls the task tool in parallel to launch two `task` subagents (one per meeting) to prepare agendas*
115
- Assistant: *Returns final schedules and agendas*
116
- <commentary>
117
- Tasks are simple individually, but subagents help silo agenda preparation.
118
- Each subagent only needs to worry about the agenda for one meeting.
119
- </commentary>
120
- </example>
121
-
122
- <example>
123
- User: "I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway."
124
- Assistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*
125
- <commentary>
126
- The assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.
127
- It is better to just complete the task directly and NOT use the `task`tool.
128
- </commentary>
129
- </example>
130
-
131
- ### Example usage with custom agents:
132
-
133
- <example_agent_descriptions>
134
- "content-reviewer": use this agent after you are done creating significant content or documents
135
- "greeting-responder": use this agent when to respond to user greetings with a friendly joke
136
- "research-analyst": use this agent to conduct thorough research on complex topics
137
- </example_agent_description>
138
-
139
- <example>
140
- user: "Please write a function that checks if a number is prime"
141
- assistant: Sure let me write a function that checks if a number is prime
142
- assistant: First let me use the Write tool to write a function that checks if a number is prime
143
- assistant: I'm going to use the Write tool to write the following code:
144
- <code>
145
- function isPrime(n) {{
146
- if (n <= 1) return false
147
- for (let i = 2; i * i <= n; i++) {{
148
- if (n % i === 0) return false
149
- }}
150
- return true
151
- }}
152
- </code>
153
- <commentary>
154
- Since significant content was created and the task was completed, now use the content-reviewer agent to review the work
155
- </commentary>
156
- assistant: Now let me use the content-reviewer agent to review the code
157
- assistant: Uses the Task tool to launch with the content-reviewer agent
158
- </example>
159
-
160
- <example>
161
- user: "Can you help me research the environmental impact of different renewable energy sources and create a comprehensive report?"
162
- <commentary>
163
- This is a complex research task that would benefit from using the research-analyst agent to conduct thorough analysis
164
- </commentary>
165
- assistant: I'll help you research the environmental impact of renewable energy sources. Let me use the research-analyst agent to conduct comprehensive research on this topic.
166
- assistant: Uses the Task tool to launch with the research-analyst agent, providing detailed instructions about what research to conduct and what format the report should take
167
- </example>
168
-
169
- <example>
170
- user: "Hello"
171
- <commentary>
172
- Since the user is greeting, use the greeting-responder agent to respond with a friendly joke
173
- </commentary>
174
- assistant: "I'm going to use the Task tool to launch with the greeting-responder agent"
175
- </example>""" # noqa: E501
176
-
177
- TASK_SYSTEM_PROMPT = """## `task` (subagent spawner)
178
-
179
- You have access to a `task` tool to launch short-lived subagents that handle isolated tasks. These agents are ephemeral — they live only for the duration of the task and return a single result.
180
-
181
- When to use the task tool:
182
- - When a task is complex and multi-step, and can be fully delegated in isolation
183
- - When a task is independent of other tasks and can run in parallel
184
- - When a task requires focused reasoning or heavy token/context usage that would bloat the orchestrator thread
185
- - When sandboxing improves reliability (e.g. code execution, structured searches, data formatting)
186
- - When you only care about the output of the subagent, and not the intermediate steps (ex. performing a lot of research and then returned a synthesized report, performing a series of computations or lookups to achieve a concise, relevant answer.)
187
-
188
- Subagent lifecycle:
189
- 1. **Spawn** → Provide clear role, instructions, and expected output
190
- 2. **Run** → The subagent completes the task autonomously
191
- 3. **Return** → The subagent provides a single structured result
192
- 4. **Reconcile** → Incorporate or synthesize the result into the main thread
193
-
194
- When NOT to use the task tool:
195
- - If you need to see the intermediate reasoning or steps after the subagent has completed (the task tool hides them)
196
- - If the task is trivial (a few tool calls or simple lookup)
197
- - If delegating does not reduce token usage, complexity, or context switching
198
- - If splitting would add latency without benefit
199
-
200
- ## Important Task Tool Usage Notes to Remember
201
- - Whenever possible, parallelize the work that you do. This is true for both tool_calls, and for tasks. Whenever you have independent steps to complete - make tool_calls, or kick off tasks (subagents) in parallel to accomplish them faster. This saves time for the user, which is incredibly important.
202
- - Remember to use the `task` tool to silo independent tasks within a multi-part objective.
203
- - You should use the `task` tool whenever you have a complex task that will take multiple steps, and is independent from other tasks that the agent needs to complete. These agents are highly competent and efficient.""" # noqa: E501
204
-
205
-
206
- DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent." # noqa: E501
207
-
208
-
209
- def _get_subagents(
210
- *,
211
- default_model: str | BaseChatModel,
212
- default_tools: Sequence[BaseTool | Callable | dict[str, Any]],
213
- default_middleware: list[AgentMiddleware] | None,
214
- default_interrupt_on: dict[str, bool | InterruptOnConfig] | None,
215
- subagents: list[SubAgent | CompiledSubAgent],
216
- general_purpose_agent: bool,
217
- ) -> tuple[dict[str, Any], list[str]]:
218
- """Create subagent instances from specifications.
219
-
220
- Args:
221
- default_model: Default model for subagents that don't specify one.
222
- default_tools: Default tools for subagents that don't specify tools.
223
- default_middleware: Middleware to apply to all subagents. If `None`,
224
- no default middleware is applied.
225
- default_interrupt_on: The tool configs to use for the default general-purpose subagent. These
226
- are also the fallback for any subagents that don't specify their own tool configs.
227
- subagents: List of agent specifications or pre-compiled agents.
228
- general_purpose_agent: Whether to include a general-purpose subagent.
229
-
230
- Returns:
231
- Tuple of (agent_dict, description_list) where agent_dict maps agent names
232
- to runnable instances and description_list contains formatted descriptions.
233
- """
234
- # Use empty list if None (no default middleware)
235
- default_subagent_middleware = default_middleware or []
236
-
237
- agents: dict[str, Any] = {}
238
- subagent_descriptions = []
239
-
240
- # Create general-purpose agent if enabled
241
- if general_purpose_agent:
242
- general_purpose_middleware = [*default_subagent_middleware]
243
- if default_interrupt_on:
244
- general_purpose_middleware.append(HumanInTheLoopMiddleware(interrupt_on=default_interrupt_on))
245
- general_purpose_subagent = create_agent(
246
- default_model,
247
- system_prompt=DEFAULT_SUBAGENT_PROMPT,
248
- tools=default_tools,
249
- middleware=general_purpose_middleware,
250
- )
251
- agents["general-purpose"] = general_purpose_subagent
252
- subagent_descriptions.append(f"- general-purpose: {DEFAULT_GENERAL_PURPOSE_DESCRIPTION}")
253
-
254
- # Process custom subagents
255
- for agent_ in subagents:
256
- subagent_descriptions.append(f"- {agent_['name']}: {agent_['description']}")
257
- if "runnable" in agent_:
258
- custom_agent = cast("CompiledSubAgent", agent_)
259
- agents[custom_agent["name"]] = custom_agent["runnable"]
260
- continue
261
- _tools = agent_.get("tools", list(default_tools))
262
-
263
- subagent_model = agent_.get("model", default_model)
264
-
265
- _middleware = [*default_subagent_middleware, *agent_["middleware"]] if "middleware" in agent_ else [*default_subagent_middleware]
266
-
267
- interrupt_on = agent_.get("interrupt_on", default_interrupt_on)
268
- if interrupt_on:
269
- _middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))
270
-
271
- agents[agent_["name"]] = create_agent(
272
- subagent_model,
273
- system_prompt=agent_["system_prompt"],
274
- tools=_tools,
275
- middleware=_middleware,
276
- checkpointer=False,
277
- )
278
- return agents, subagent_descriptions
279
-
280
-
281
- def _create_task_tool(
282
- *,
283
- default_model: str | BaseChatModel,
284
- default_tools: Sequence[BaseTool | Callable | dict[str, Any]],
285
- default_middleware: list[AgentMiddleware] | None,
286
- default_interrupt_on: dict[str, bool | InterruptOnConfig] | None,
287
- subagents: list[SubAgent | CompiledSubAgent],
288
- general_purpose_agent: bool,
289
- task_description: str | None = None,
290
- ) -> BaseTool:
291
- """Create a task tool for invoking subagents.
292
-
293
- Args:
294
- default_model: Default model for subagents.
295
- default_tools: Default tools for subagents.
296
- default_middleware: Middleware to apply to all subagents.
297
- default_interrupt_on: The tool configs to use for the default general-purpose subagent. These
298
- are also the fallback for any subagents that don't specify their own tool configs.
299
- subagents: List of subagent specifications.
300
- general_purpose_agent: Whether to include general-purpose agent.
301
- task_description: Custom description for the task tool. If `None`,
302
- uses default template. Supports `{available_agents}` placeholder.
303
-
304
- Returns:
305
- A StructuredTool that can invoke subagents by type.
306
- """
307
- subagent_graphs, subagent_descriptions = _get_subagents(
308
- default_model=default_model,
309
- default_tools=default_tools,
310
- default_middleware=default_middleware,
311
- default_interrupt_on=default_interrupt_on,
312
- subagents=subagents,
313
- general_purpose_agent=general_purpose_agent,
314
- )
315
- subagent_description_str = "\n".join(subagent_descriptions)
316
-
317
- def _return_command_with_state_update(result: dict, tool_call_id: str) -> Command:
318
- state_update = {k: v for k, v in result.items() if k not in _EXCLUDED_STATE_KEYS}
319
- return Command(
320
- update={
321
- **state_update,
322
- "messages": [ToolMessage(result["messages"][-1].content, tool_call_id=tool_call_id)],
323
- }
324
- )
325
-
326
- def _validate_and_prepare_state(subagent_type: str, description: str, runtime: ToolRuntime) -> tuple[Runnable, dict]:
327
- """Validate subagent type and prepare state for invocation."""
328
- if subagent_type not in subagent_graphs:
329
- msg = f"Error: invoked agent of type {subagent_type}, the only allowed types are {[f'`{k}`' for k in subagent_graphs]}"
330
- raise ValueError(msg)
331
- subagent = subagent_graphs[subagent_type]
332
- # Create a new state dict to avoid mutating the original
333
- subagent_state = {k: v for k, v in runtime.state.items() if k not in _EXCLUDED_STATE_KEYS}
334
- subagent_state["messages"] = [HumanMessage(content=description)]
335
- return subagent, subagent_state
336
-
337
- # Use custom description if provided, otherwise use default template
338
- if task_description is None:
339
- task_description = TASK_TOOL_DESCRIPTION.format(available_agents=subagent_description_str)
340
- elif "{available_agents}" in task_description:
341
- # If custom description has placeholder, format with agent descriptions
342
- task_description = task_description.format(available_agents=subagent_description_str)
343
-
344
- def task(
345
- description: str,
346
- subagent_type: str,
347
- runtime: ToolRuntime,
348
- ) -> str | Command:
349
- subagent, subagent_state = _validate_and_prepare_state(subagent_type, description, runtime)
350
- result = subagent.invoke(subagent_state)
351
- if not runtime.tool_call_id:
352
- value_error_msg = "Tool call ID is required for subagent invocation"
353
- raise ValueError(value_error_msg)
354
- return _return_command_with_state_update(result, runtime.tool_call_id)
355
-
356
- async def atask(
357
- description: str,
358
- subagent_type: str,
359
- runtime: ToolRuntime,
360
- ) -> str | Command:
361
- subagent, subagent_state = _validate_and_prepare_state(subagent_type, description, runtime)
362
- result = await subagent.ainvoke(subagent_state)
363
- if not runtime.tool_call_id:
364
- value_error_msg = "Tool call ID is required for subagent invocation"
365
- raise ValueError(value_error_msg)
366
- return _return_command_with_state_update(result, runtime.tool_call_id)
367
-
368
- return StructuredTool.from_function(
369
- name="task",
370
- func=task,
371
- coroutine=atask,
372
- description=task_description,
373
- )
374
-
375
-
376
- class SubAgentMiddleware(AgentMiddleware):
377
- """Middleware for providing subagents to an agent via a `task` tool.
378
-
379
- This middleware adds a `task` tool to the agent that can be used to invoke subagents.
380
- Subagents are useful for handling complex tasks that require multiple steps, or tasks
381
- that require a lot of context to resolve.
382
-
383
- A chief benefit of subagents is that they can handle multi-step tasks, and then return
384
- a clean, concise response to the main agent.
385
-
386
- Subagents are also great for different domains of expertise that require a narrower
387
- subset of tools and focus.
388
-
389
- This middleware comes with a default general-purpose subagent that can be used to
390
- handle the same tasks as the main agent, but with isolated context.
391
-
392
- Args:
393
- default_model: The model to use for subagents.
394
- Can be a LanguageModelLike or a dict for init_chat_model.
395
- default_tools: The tools to use for the default general-purpose subagent.
396
- default_middleware: Default middleware to apply to all subagents. If `None` (default),
397
- no default middleware is applied. Pass a list to specify custom middleware.
398
- default_interrupt_on: The tool configs to use for the default general-purpose subagent. These
399
- are also the fallback for any subagents that don't specify their own tool configs.
400
- subagents: A list of additional subagents to provide to the agent.
401
- system_prompt: Full system prompt override. When provided, completely replaces
402
- the agent's system prompt.
403
- general_purpose_agent: Whether to include the general-purpose agent. Defaults to `True`.
404
- task_description: Custom description for the task tool. If `None`, uses the
405
- default description template.
406
-
407
- Example:
408
- ```python
409
- from langchain.agents.middleware.subagents import SubAgentMiddleware
410
- from langchain.agents import create_agent
411
-
412
- # Basic usage with defaults (no default middleware)
413
- agent = create_agent(
414
- "openai:gpt-4o",
415
- middleware=[
416
- SubAgentMiddleware(
417
- default_model="openai:gpt-4o",
418
- subagents=[],
419
- )
420
- ],
421
- )
422
-
423
- # Add custom middleware to subagents
424
- agent = create_agent(
425
- "openai:gpt-4o",
426
- middleware=[
427
- SubAgentMiddleware(
428
- default_model="openai:gpt-4o",
429
- default_middleware=[TodoListMiddleware()],
430
- subagents=[],
431
- )
432
- ],
433
- )
434
- ```
435
- """
436
-
437
- def __init__(
438
- self,
439
- *,
440
- default_model: str | BaseChatModel,
441
- default_tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
442
- default_middleware: list[AgentMiddleware] | None = None,
443
- default_interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
444
- subagents: list[SubAgent | CompiledSubAgent] | None = None,
445
- system_prompt: str | None = TASK_SYSTEM_PROMPT,
446
- general_purpose_agent: bool = True,
447
- task_description: str | None = None,
448
- ) -> None:
449
- """Initialize the SubAgentMiddleware."""
450
- super().__init__()
451
- self.system_prompt = system_prompt
452
- task_tool = _create_task_tool(
453
- default_model=default_model,
454
- default_tools=default_tools or [],
455
- default_middleware=default_middleware,
456
- default_interrupt_on=default_interrupt_on,
457
- subagents=subagents or [],
458
- general_purpose_agent=general_purpose_agent,
459
- task_description=task_description,
460
- )
461
- self.tools = [task_tool]
462
-
463
- def wrap_model_call(
464
- self,
465
- request: ModelRequest,
466
- handler: Callable[[ModelRequest], ModelResponse],
467
- ) -> ModelResponse:
468
- """Update the system prompt to include instructions on using subagents."""
469
- if self.system_prompt is not None:
470
- request.system_prompt = request.system_prompt + "\n\n" + self.system_prompt if request.system_prompt else self.system_prompt
471
- return handler(request)
472
-
473
- async def awrap_model_call(
474
- self,
475
- request: ModelRequest,
476
- handler: Callable[[ModelRequest], Awaitable[ModelResponse]],
477
- ) -> ModelResponse:
478
- """(async) Update the system prompt to include instructions on using subagents."""
479
- if self.system_prompt is not None:
480
- request.system_prompt = request.system_prompt + "\n\n" + self.system_prompt if request.system_prompt else self.system_prompt
481
- return await handler(request)