copilotagent 0.1.6__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.
- copilotagent/__init__.py +35 -0
- copilotagent/cloud_subagents.py +220 -0
- copilotagent/graph.py +192 -0
- copilotagent/middleware/__init__.py +15 -0
- copilotagent/middleware/filesystem.py +1135 -0
- copilotagent/middleware/initial_message.py +88 -0
- copilotagent/middleware/patch_tool_calls.py +44 -0
- copilotagent/middleware/planner_prompts/drawdoc_awm.md +44 -0
- copilotagent/middleware/planner_prompts/itp_princeton.md +61 -0
- copilotagent/middleware/planner_prompts/research.md +51 -0
- copilotagent/middleware/planning.py +304 -0
- copilotagent/middleware/subagents.py +589 -0
- copilotagent/py.typed +2 -0
- copilotagent-0.1.6.dist-info/METADATA +616 -0
- copilotagent-0.1.6.dist-info/RECORD +18 -0
- copilotagent-0.1.6.dist-info/WHEEL +5 -0
- copilotagent-0.1.6.dist-info/licenses/LICENSE +21 -0
- copilotagent-0.1.6.dist-info/top_level.txt +1 -0
copilotagent/__init__.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""CopilotAgent package."""
|
|
2
|
+
|
|
3
|
+
__author__ = """Harrison Chase"""
|
|
4
|
+
__email__ = "harrison@langchain.dev"
|
|
5
|
+
__version__ = "0.1.6"
|
|
6
|
+
|
|
7
|
+
from copilotagent.cloud_subagents import (
|
|
8
|
+
get_cute_finish_itp_subagent,
|
|
9
|
+
get_cute_linear_subagent,
|
|
10
|
+
)
|
|
11
|
+
from copilotagent.graph import (
|
|
12
|
+
create_deep_agent,
|
|
13
|
+
DEFAULT_AGENT_TYPE,
|
|
14
|
+
DEFAULT_STARTING_MESSAGES,
|
|
15
|
+
get_default_starting_message,
|
|
16
|
+
)
|
|
17
|
+
from copilotagent.middleware.filesystem import FilesystemMiddleware
|
|
18
|
+
from copilotagent.middleware.initial_message import InitialMessageMiddleware
|
|
19
|
+
from copilotagent.middleware.planning import PlanningMiddleware
|
|
20
|
+
from copilotagent.middleware.subagents import CompiledSubAgent, SubAgent, SubAgentMiddleware
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"CompiledSubAgent",
|
|
24
|
+
"DEFAULT_AGENT_TYPE",
|
|
25
|
+
"DEFAULT_STARTING_MESSAGES",
|
|
26
|
+
"FilesystemMiddleware",
|
|
27
|
+
"InitialMessageMiddleware",
|
|
28
|
+
"PlanningMiddleware",
|
|
29
|
+
"SubAgent",
|
|
30
|
+
"SubAgentMiddleware",
|
|
31
|
+
"create_deep_agent",
|
|
32
|
+
"get_cute_finish_itp_subagent",
|
|
33
|
+
"get_cute_linear_subagent",
|
|
34
|
+
"get_default_starting_message",
|
|
35
|
+
]
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Cloud subagents using LangGraph Cloud deployed services.
|
|
2
|
+
|
|
3
|
+
This module provides factory functions for creating CompiledSubAgent instances
|
|
4
|
+
that connect to deployed LangGraph Cloud services via LangGraph SDK client.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any, TypedDict
|
|
11
|
+
|
|
12
|
+
from dotenv import load_dotenv
|
|
13
|
+
from langchain_core.runnables import Runnable
|
|
14
|
+
from langgraph_sdk import get_client
|
|
15
|
+
|
|
16
|
+
# Set up logging
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
# Try to load .env from multiple possible locations
|
|
20
|
+
env_locations = [
|
|
21
|
+
Path.cwd() / ".env", # Current working directory
|
|
22
|
+
Path(__file__).parent.parent.parent.parent / ".env", # copilot/.env
|
|
23
|
+
Path(__file__).parent.parent.parent.parent / "agents" / "ITP-Princeton" / ".env", # ITP-Princeton/.env
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
for env_path in env_locations:
|
|
27
|
+
if env_path.exists():
|
|
28
|
+
logger.info(f"Loading .env from: {env_path}")
|
|
29
|
+
load_dotenv(env_path)
|
|
30
|
+
break
|
|
31
|
+
else:
|
|
32
|
+
logger.warning(f"No .env file found in any of these locations: {env_locations}")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RemoteGraphRunnable(Runnable):
|
|
36
|
+
"""Wrapper to make LangGraph SDK client work as a Runnable.
|
|
37
|
+
|
|
38
|
+
This adapter allows the new LangGraph SDK client API to work with
|
|
39
|
+
the existing Runnable interface expected by SubAgentMiddleware.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, url: str, api_key: str, graph_id: str):
|
|
43
|
+
"""Initialize the remote graph runnable.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
url: The URL of the deployed LangGraph service
|
|
47
|
+
api_key: The API key for authentication
|
|
48
|
+
graph_id: The graph ID to use (assistant_id)
|
|
49
|
+
"""
|
|
50
|
+
self.url = url
|
|
51
|
+
self.api_key = api_key
|
|
52
|
+
self.graph_id = graph_id
|
|
53
|
+
self._client = None
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def client(self):
|
|
57
|
+
"""Lazy initialization of the client."""
|
|
58
|
+
if self._client is None:
|
|
59
|
+
self._client = get_client(url=self.url, api_key=self.api_key)
|
|
60
|
+
return self._client
|
|
61
|
+
|
|
62
|
+
def invoke(self, input: dict[str, Any], config: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
63
|
+
"""Synchronously invoke the remote graph.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
input: The input state dictionary
|
|
67
|
+
config: Optional configuration
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
The final state from the remote graph execution
|
|
71
|
+
"""
|
|
72
|
+
import asyncio
|
|
73
|
+
return asyncio.run(self.ainvoke(input, config))
|
|
74
|
+
|
|
75
|
+
async def ainvoke(self, input: dict[str, Any], config: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
76
|
+
"""Asynchronously invoke the remote graph.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
input: The input state dictionary
|
|
80
|
+
config: Optional configuration
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The final state from the remote graph execution
|
|
84
|
+
"""
|
|
85
|
+
# Use the runs.wait method to execute and wait for completion
|
|
86
|
+
result = await self.client.runs.wait(
|
|
87
|
+
thread_id=None, # Create a new thread for each invocation
|
|
88
|
+
assistant_id=self.graph_id,
|
|
89
|
+
input=input,
|
|
90
|
+
)
|
|
91
|
+
# Return the final state from the result
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class CompiledSubAgent(TypedDict):
|
|
96
|
+
"""A pre-compiled agent spec."""
|
|
97
|
+
|
|
98
|
+
name: str
|
|
99
|
+
"""The name of the agent."""
|
|
100
|
+
|
|
101
|
+
description: str
|
|
102
|
+
"""The description of the agent."""
|
|
103
|
+
|
|
104
|
+
runnable: Runnable
|
|
105
|
+
"""The Runnable to use for the agent."""
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_cute_linear_subagent() -> CompiledSubAgent:
|
|
109
|
+
"""Get cuteLinear cloud subagent for GUI data extraction.
|
|
110
|
+
|
|
111
|
+
This agent performs automated GUI data extraction including:
|
|
112
|
+
- Multi-step GUI navigation
|
|
113
|
+
- Screenshot capture
|
|
114
|
+
- OCR via AWS Textract
|
|
115
|
+
- AI-powered name normalization
|
|
116
|
+
- Human-in-the-loop review
|
|
117
|
+
- SharedState reporting
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
CompiledSubAgent dictionary with RemoteGraph runnable.
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
ValueError: If API key environment variable is not set.
|
|
124
|
+
"""
|
|
125
|
+
# Try multiple environment variable names (LangChain uses different names in different contexts)
|
|
126
|
+
api_key = (
|
|
127
|
+
os.getenv("LANGCHAIN_API_KEY") or
|
|
128
|
+
os.getenv("LANGSMITH_API_KEY") or
|
|
129
|
+
os.getenv("LANGGRAPH_API_KEY")
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Log environment variable status for debugging
|
|
133
|
+
logger.info(f"LANGCHAIN_API_KEY present: {bool(os.getenv('LANGCHAIN_API_KEY'))}")
|
|
134
|
+
logger.info(f"LANGSMITH_API_KEY present: {bool(os.getenv('LANGSMITH_API_KEY'))}")
|
|
135
|
+
logger.info(f"LANGGRAPH_API_KEY present: {bool(os.getenv('LANGGRAPH_API_KEY'))}")
|
|
136
|
+
logger.info(f"Current working directory: {Path.cwd()}")
|
|
137
|
+
logger.info(f"All env vars with 'LANG': {[k for k in os.environ.keys() if 'LANG' in k]}")
|
|
138
|
+
|
|
139
|
+
if not api_key:
|
|
140
|
+
msg = (
|
|
141
|
+
"API key environment variable is required for cloud subagents. "
|
|
142
|
+
"Please ensure .env file exists with one of: LANGCHAIN_API_KEY, LANGSMITH_API_KEY, or LANGGRAPH_API_KEY. "
|
|
143
|
+
f"Checked locations: {env_locations}"
|
|
144
|
+
)
|
|
145
|
+
logger.error(msg)
|
|
146
|
+
raise ValueError(msg)
|
|
147
|
+
|
|
148
|
+
logger.info(f"Creating RemoteGraphRunnable for cute-linear with API key: {api_key[:10]}...")
|
|
149
|
+
client = RemoteGraphRunnable(
|
|
150
|
+
url="https://cutelineargraph-ef1ae523c24e51ef94e330929a65833b.us.langgraph.app",
|
|
151
|
+
api_key=api_key,
|
|
152
|
+
graph_id="cuteLinearGraph",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
"name": "cute-linear",
|
|
157
|
+
"description": (
|
|
158
|
+
"Coordinated Data Extraction Agent - Performs automated GUI data extraction "
|
|
159
|
+
"including navigation, OCR via AWS Textract, and AI-powered name normalization. "
|
|
160
|
+
"Extracts borrower names from GUI interface, sends for human review, and reports "
|
|
161
|
+
"results back. Use this agent when you need to extract borrower names from the "
|
|
162
|
+
"GUI system."
|
|
163
|
+
),
|
|
164
|
+
"runnable": client,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def get_cute_finish_itp_subagent() -> CompiledSubAgent:
|
|
169
|
+
"""Get cuteFinishITP cloud subagent for GUI automation.
|
|
170
|
+
|
|
171
|
+
This agent executes a 25-step workflow for ITP document processing including:
|
|
172
|
+
- Popup detection and handling
|
|
173
|
+
- Form field navigation and filling
|
|
174
|
+
- Document verification
|
|
175
|
+
- Final document submission
|
|
176
|
+
- Screenshot capture for verification
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
CompiledSubAgent dictionary with RemoteGraph runnable.
|
|
180
|
+
|
|
181
|
+
Raises:
|
|
182
|
+
ValueError: If API key environment variable is not set.
|
|
183
|
+
"""
|
|
184
|
+
# Try multiple environment variable names (LangChain uses different names in different contexts)
|
|
185
|
+
api_key = (
|
|
186
|
+
os.getenv("LANGCHAIN_API_KEY") or
|
|
187
|
+
os.getenv("LANGSMITH_API_KEY") or
|
|
188
|
+
os.getenv("LANGGRAPH_API_KEY")
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Log environment variable status for debugging
|
|
192
|
+
logger.info(f"API key present: {bool(api_key)}")
|
|
193
|
+
|
|
194
|
+
if not api_key:
|
|
195
|
+
msg = (
|
|
196
|
+
"API key environment variable is required for cloud subagents. "
|
|
197
|
+
"Please ensure .env file exists with one of: LANGCHAIN_API_KEY, LANGSMITH_API_KEY, or LANGGRAPH_API_KEY. "
|
|
198
|
+
f"Checked locations: {env_locations}"
|
|
199
|
+
)
|
|
200
|
+
logger.error(msg)
|
|
201
|
+
raise ValueError(msg)
|
|
202
|
+
|
|
203
|
+
logger.info(f"Creating RemoteGraphRunnable for cute-finish-itp with API key: {api_key[:10]}...")
|
|
204
|
+
client = RemoteGraphRunnable(
|
|
205
|
+
url="https://cutefinishitp-2d3fcf81a7e55dd09a66354c5c2b567c.us.langgraph.app",
|
|
206
|
+
api_key=api_key,
|
|
207
|
+
graph_id="cuteFinishITP",
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
"name": "cute-finish-itp",
|
|
212
|
+
"description": (
|
|
213
|
+
"Encompass GUI Automation Agent - Executes a 25-step workflow for ITP document "
|
|
214
|
+
"processing including popup detection, form filling, document verification, and "
|
|
215
|
+
"final submission. Use this agent when you need to complete the ITP document "
|
|
216
|
+
"processing workflow in the Encompass GUI system."
|
|
217
|
+
),
|
|
218
|
+
"runnable": client,
|
|
219
|
+
}
|
|
220
|
+
|
copilotagent/graph.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Deepagents come with planning, filesystem, and subagents."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
4
|
+
from typing import Any, Literal
|
|
5
|
+
|
|
6
|
+
from langchain.agents import create_agent
|
|
7
|
+
from langchain.agents.middleware import HumanInTheLoopMiddleware, InterruptOnConfig
|
|
8
|
+
from langchain.agents.middleware.summarization import SummarizationMiddleware
|
|
9
|
+
from langchain.agents.middleware.types import AgentMiddleware
|
|
10
|
+
from langchain.agents.structured_output import ResponseFormat
|
|
11
|
+
from langchain_anthropic import ChatAnthropic
|
|
12
|
+
from langchain_anthropic.middleware import AnthropicPromptCachingMiddleware
|
|
13
|
+
from langchain_core.language_models import BaseChatModel
|
|
14
|
+
from langchain_core.tools import BaseTool
|
|
15
|
+
from langgraph.cache.base import BaseCache
|
|
16
|
+
from langgraph.graph.state import CompiledStateGraph
|
|
17
|
+
from langgraph.store.base import BaseStore
|
|
18
|
+
from langgraph.types import Checkpointer
|
|
19
|
+
|
|
20
|
+
from copilotagent.middleware.filesystem import FilesystemMiddleware
|
|
21
|
+
from copilotagent.middleware.initial_message import InitialMessageMiddleware
|
|
22
|
+
from copilotagent.middleware.patch_tool_calls import PatchToolCallsMiddleware
|
|
23
|
+
from copilotagent.middleware.planning import PlanningMiddleware
|
|
24
|
+
from copilotagent.middleware.subagents import CompiledSubAgent, SubAgent, SubAgentMiddleware
|
|
25
|
+
|
|
26
|
+
# Global default agent type for planning middleware
|
|
27
|
+
DEFAULT_AGENT_TYPE: Literal["ITP-Princeton", "DrawDoc-AWM", "research"] = "ITP-Princeton"
|
|
28
|
+
|
|
29
|
+
BASE_AGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools."
|
|
30
|
+
|
|
31
|
+
# Default starting messages for different agent types
|
|
32
|
+
DEFAULT_STARTING_MESSAGES = {
|
|
33
|
+
"ITP-Princeton": "Let's review and approve Intent to Proceed for Princeton mortgage",
|
|
34
|
+
"DrawDoc-AWM": "Let's draw the docs for AWM",
|
|
35
|
+
"research": None, # Research agents still get human input
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_default_model() -> ChatAnthropic:
|
|
40
|
+
"""Get the default model for deep agents.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
ChatAnthropic instance configured with Claude Sonnet 4.
|
|
44
|
+
"""
|
|
45
|
+
return ChatAnthropic(
|
|
46
|
+
model_name="claude-sonnet-4-5-20250929",
|
|
47
|
+
max_tokens=20000,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_default_starting_message(
|
|
52
|
+
agent_type: Literal["ITP-Princeton", "DrawDoc-AWM", "research"]
|
|
53
|
+
) -> str | None:
|
|
54
|
+
"""Get the default starting message for an agent type.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
agent_type: The type of agent.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Default starting message for the agent type, or None if no default.
|
|
61
|
+
"""
|
|
62
|
+
return DEFAULT_STARTING_MESSAGES.get(agent_type)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def create_deep_agent(
|
|
66
|
+
model: str | BaseChatModel | None = None,
|
|
67
|
+
tools: Sequence[BaseTool | Callable | dict[str, Any]] | None = None,
|
|
68
|
+
*,
|
|
69
|
+
system_prompt: str | None = None,
|
|
70
|
+
middleware: Sequence[AgentMiddleware] = (),
|
|
71
|
+
subagents: list[SubAgent | CompiledSubAgent] | None = None,
|
|
72
|
+
response_format: ResponseFormat | None = None,
|
|
73
|
+
context_schema: type[Any] | None = None,
|
|
74
|
+
checkpointer: Checkpointer | None = None,
|
|
75
|
+
store: BaseStore | None = None,
|
|
76
|
+
use_longterm_memory: bool = False,
|
|
77
|
+
interrupt_on: dict[str, bool | InterruptOnConfig] | None = None,
|
|
78
|
+
agent_type: Literal["ITP-Princeton", "DrawDoc-AWM", "research"] | None = None,
|
|
79
|
+
debug: bool = False,
|
|
80
|
+
name: str | None = None,
|
|
81
|
+
cache: BaseCache | None = None,
|
|
82
|
+
) -> CompiledStateGraph:
|
|
83
|
+
"""Create a deep agent.
|
|
84
|
+
|
|
85
|
+
This agent will by default have access to a tool to write todos (write_todos),
|
|
86
|
+
four file editing tools: write_file, ls, read_file, edit_file, and a tool to call
|
|
87
|
+
subagents.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
tools: The tools the agent should have access to.
|
|
91
|
+
system_prompt: The additional instructions the agent should have. Will go in
|
|
92
|
+
the system prompt.
|
|
93
|
+
middleware: Additional middleware to apply after standard middleware.
|
|
94
|
+
model: The model to use.
|
|
95
|
+
subagents: The subagents to use. Each subagent should be a dictionary with the
|
|
96
|
+
following keys:
|
|
97
|
+
- `name`
|
|
98
|
+
- `description` (used by the main agent to decide whether to call the
|
|
99
|
+
sub agent)
|
|
100
|
+
- `prompt` (used as the system prompt in the subagent)
|
|
101
|
+
- (optional) `tools`
|
|
102
|
+
- (optional) `model` (either a LanguageModelLike instance or dict
|
|
103
|
+
settings)
|
|
104
|
+
- (optional) `middleware` (list of AgentMiddleware)
|
|
105
|
+
response_format: A structured output response format to use for the agent.
|
|
106
|
+
context_schema: The schema of the deep agent.
|
|
107
|
+
checkpointer: Optional checkpointer for persisting agent state between runs.
|
|
108
|
+
store: Optional store for persisting longterm memories.
|
|
109
|
+
use_longterm_memory: Whether to use longterm memory - you must provide a store
|
|
110
|
+
in order to use longterm memory.
|
|
111
|
+
interrupt_on: Optional Dict[str, bool | InterruptOnConfig] mapping tool names to
|
|
112
|
+
interrupt configs.
|
|
113
|
+
agent_type: Type of agent for planning prompts. Options: "ITP-Princeton",
|
|
114
|
+
"DrawDoc-AWM", "research". Defaults to the global DEFAULT_AGENT_TYPE.
|
|
115
|
+
debug: Whether to enable debug mode. Passed through to create_agent.
|
|
116
|
+
name: The name of the agent. Passed through to create_agent.
|
|
117
|
+
cache: The cache to use for the agent. Passed through to create_agent.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
A configured deep agent.
|
|
121
|
+
"""
|
|
122
|
+
if model is None:
|
|
123
|
+
model = get_default_model()
|
|
124
|
+
|
|
125
|
+
# Use the provided agent_type or fall back to the global default
|
|
126
|
+
if agent_type is None:
|
|
127
|
+
agent_type = DEFAULT_AGENT_TYPE
|
|
128
|
+
|
|
129
|
+
# Get the default starting message for this agent type
|
|
130
|
+
default_starting_message = get_default_starting_message(agent_type)
|
|
131
|
+
|
|
132
|
+
deepagent_middleware = [
|
|
133
|
+
# Add initial message middleware first, so it can present default message
|
|
134
|
+
# before any other processing happens
|
|
135
|
+
InitialMessageMiddleware(
|
|
136
|
+
agent_type=agent_type,
|
|
137
|
+
default_message=default_starting_message,
|
|
138
|
+
),
|
|
139
|
+
PlanningMiddleware(
|
|
140
|
+
agent_type=agent_type,
|
|
141
|
+
),
|
|
142
|
+
FilesystemMiddleware(
|
|
143
|
+
long_term_memory=use_longterm_memory,
|
|
144
|
+
),
|
|
145
|
+
SubAgentMiddleware(
|
|
146
|
+
default_model=model,
|
|
147
|
+
default_tools=tools,
|
|
148
|
+
subagents=subagents if subagents is not None else [],
|
|
149
|
+
default_middleware=[
|
|
150
|
+
PlanningMiddleware(
|
|
151
|
+
agent_type=agent_type,
|
|
152
|
+
),
|
|
153
|
+
FilesystemMiddleware(
|
|
154
|
+
long_term_memory=use_longterm_memory,
|
|
155
|
+
),
|
|
156
|
+
SummarizationMiddleware(
|
|
157
|
+
model=model,
|
|
158
|
+
max_tokens_before_summary=170000,
|
|
159
|
+
messages_to_keep=6,
|
|
160
|
+
),
|
|
161
|
+
AnthropicPromptCachingMiddleware(unsupported_model_behavior="ignore"),
|
|
162
|
+
PatchToolCallsMiddleware(),
|
|
163
|
+
],
|
|
164
|
+
default_interrupt_on=interrupt_on,
|
|
165
|
+
general_purpose_agent=True,
|
|
166
|
+
),
|
|
167
|
+
SummarizationMiddleware(
|
|
168
|
+
model=model,
|
|
169
|
+
max_tokens_before_summary=170000,
|
|
170
|
+
messages_to_keep=6,
|
|
171
|
+
),
|
|
172
|
+
AnthropicPromptCachingMiddleware(unsupported_model_behavior="ignore"),
|
|
173
|
+
PatchToolCallsMiddleware(),
|
|
174
|
+
]
|
|
175
|
+
if interrupt_on is not None:
|
|
176
|
+
deepagent_middleware.append(HumanInTheLoopMiddleware(interrupt_on=interrupt_on))
|
|
177
|
+
if middleware is not None:
|
|
178
|
+
deepagent_middleware.extend(middleware)
|
|
179
|
+
|
|
180
|
+
return create_agent(
|
|
181
|
+
model,
|
|
182
|
+
system_prompt=system_prompt + "\n\n" + BASE_AGENT_PROMPT if system_prompt else BASE_AGENT_PROMPT,
|
|
183
|
+
tools=tools,
|
|
184
|
+
middleware=deepagent_middleware,
|
|
185
|
+
response_format=response_format,
|
|
186
|
+
context_schema=context_schema,
|
|
187
|
+
checkpointer=checkpointer,
|
|
188
|
+
store=store,
|
|
189
|
+
debug=debug,
|
|
190
|
+
name=name,
|
|
191
|
+
cache=cache,
|
|
192
|
+
).with_config({"recursion_limit": 1000})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Middleware for the CopilotAgent."""
|
|
2
|
+
|
|
3
|
+
from copilotagent.middleware.filesystem import FilesystemMiddleware
|
|
4
|
+
from copilotagent.middleware.initial_message import InitialMessageMiddleware
|
|
5
|
+
from copilotagent.middleware.planning import PlanningMiddleware
|
|
6
|
+
from copilotagent.middleware.subagents import CompiledSubAgent, SubAgent, SubAgentMiddleware
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"CompiledSubAgent",
|
|
10
|
+
"FilesystemMiddleware",
|
|
11
|
+
"InitialMessageMiddleware",
|
|
12
|
+
"PlanningMiddleware",
|
|
13
|
+
"SubAgent",
|
|
14
|
+
"SubAgentMiddleware",
|
|
15
|
+
]
|