zero-agent 0.1.0__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.
- agentz/agent/base.py +262 -0
- agentz/artifacts/__init__.py +5 -0
- agentz/artifacts/artifact_writer.py +538 -0
- agentz/artifacts/reporter.py +235 -0
- agentz/artifacts/terminal_writer.py +100 -0
- agentz/context/__init__.py +6 -0
- agentz/context/context.py +91 -0
- agentz/context/conversation.py +205 -0
- agentz/context/data_store.py +208 -0
- agentz/llm/llm_setup.py +156 -0
- agentz/mcp/manager.py +142 -0
- agentz/mcp/patches.py +88 -0
- agentz/mcp/servers/chrome_devtools/server.py +14 -0
- agentz/profiles/base.py +108 -0
- agentz/profiles/data/data_analysis.py +38 -0
- agentz/profiles/data/data_loader.py +35 -0
- agentz/profiles/data/evaluation.py +43 -0
- agentz/profiles/data/model_training.py +47 -0
- agentz/profiles/data/preprocessing.py +47 -0
- agentz/profiles/data/visualization.py +47 -0
- agentz/profiles/manager/evaluate.py +51 -0
- agentz/profiles/manager/memory.py +62 -0
- agentz/profiles/manager/observe.py +48 -0
- agentz/profiles/manager/routing.py +66 -0
- agentz/profiles/manager/writer.py +51 -0
- agentz/profiles/mcp/browser.py +21 -0
- agentz/profiles/mcp/chrome.py +21 -0
- agentz/profiles/mcp/notion.py +21 -0
- agentz/runner/__init__.py +74 -0
- agentz/runner/base.py +28 -0
- agentz/runner/executor.py +320 -0
- agentz/runner/hooks.py +110 -0
- agentz/runner/iteration.py +142 -0
- agentz/runner/patterns.py +215 -0
- agentz/runner/tracker.py +188 -0
- agentz/runner/utils.py +45 -0
- agentz/runner/workflow.py +250 -0
- agentz/tools/__init__.py +20 -0
- agentz/tools/data_tools/__init__.py +17 -0
- agentz/tools/data_tools/data_analysis.py +152 -0
- agentz/tools/data_tools/data_loading.py +92 -0
- agentz/tools/data_tools/evaluation.py +175 -0
- agentz/tools/data_tools/helpers.py +120 -0
- agentz/tools/data_tools/model_training.py +192 -0
- agentz/tools/data_tools/preprocessing.py +229 -0
- agentz/tools/data_tools/visualization.py +281 -0
- agentz/utils/__init__.py +69 -0
- agentz/utils/config.py +708 -0
- agentz/utils/helpers.py +10 -0
- agentz/utils/parsers.py +142 -0
- agentz/utils/printer.py +539 -0
- pipelines/base.py +972 -0
- pipelines/data_scientist.py +97 -0
- pipelines/data_scientist_memory.py +151 -0
- pipelines/experience_learner.py +0 -0
- pipelines/prompt_generator.py +0 -0
- pipelines/simple.py +78 -0
- pipelines/simple_browser.py +145 -0
- pipelines/simple_chrome.py +75 -0
- pipelines/simple_notion.py +103 -0
- pipelines/tool_builder.py +0 -0
- zero_agent-0.1.0.dist-info/METADATA +269 -0
- zero_agent-0.1.0.dist-info/RECORD +66 -0
- zero_agent-0.1.0.dist-info/WHEEL +5 -0
- zero_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
- zero_agent-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
6
|
+
|
7
|
+
from agentz.agent.base import ContextAgent
|
8
|
+
from agentz.context.context import Context
|
9
|
+
from pipelines.base import BasePipeline
|
10
|
+
|
11
|
+
|
12
|
+
class DataScienceQuery(BaseModel):
|
13
|
+
"""Query model for data science tasks."""
|
14
|
+
prompt: str
|
15
|
+
data_path: str
|
16
|
+
|
17
|
+
def format(self) -> str:
|
18
|
+
"""Format data science query."""
|
19
|
+
return (
|
20
|
+
f"Task: {self.prompt}\n"
|
21
|
+
f"Dataset path: {self.data_path}\n"
|
22
|
+
"Provide a comprehensive data science workflow"
|
23
|
+
)
|
24
|
+
|
25
|
+
|
26
|
+
class DataScientistPipeline(BasePipeline):
|
27
|
+
"""Data science pipeline using manager-tool pattern.
|
28
|
+
|
29
|
+
This pipeline demonstrates the minimal implementation needed:
|
30
|
+
- __init__: Setup agents
|
31
|
+
- execute: Implement the workflow logic
|
32
|
+
- DataScienceQuery.format(): Format query (handled automatically by BasePipeline)
|
33
|
+
|
34
|
+
All other logic (iteration, tool execution, memory save) is handled by BasePipeline.
|
35
|
+
"""
|
36
|
+
|
37
|
+
def __init__(self, config):
|
38
|
+
"""Initialize pipeline with explicit manager agents and tool agent dictionary."""
|
39
|
+
super().__init__(config)
|
40
|
+
|
41
|
+
# Initialize context and profiles
|
42
|
+
self.context = Context(["profiles", "states"])
|
43
|
+
llm = self.config.llm.main_model
|
44
|
+
|
45
|
+
# Create manager agents - automatically bound to pipeline with role
|
46
|
+
self.observe_agent = ContextAgent.from_profile(self, "observe", llm)
|
47
|
+
self.evaluate_agent = ContextAgent.from_profile(self, "evaluate", llm)
|
48
|
+
self.routing_agent = ContextAgent.from_profile(self, "routing", llm)
|
49
|
+
self.writer_agent = ContextAgent.from_profile(self, "writer", llm)
|
50
|
+
|
51
|
+
# Create tool agents as dictionary - automatically bound to pipeline
|
52
|
+
tool_names = [
|
53
|
+
"data_loader",
|
54
|
+
"data_analysis",
|
55
|
+
"preprocessing",
|
56
|
+
"model_training",
|
57
|
+
"evaluation",
|
58
|
+
"visualization",
|
59
|
+
]
|
60
|
+
self.tool_agents = {
|
61
|
+
f"{name}_agent": ContextAgent.from_profile(self, name, llm)
|
62
|
+
for name in tool_names
|
63
|
+
}
|
64
|
+
|
65
|
+
async def execute(self) -> Any:
|
66
|
+
"""Execute data science workflow - full implementation in one function."""
|
67
|
+
self.update_printer("research", "Executing research workflow...")
|
68
|
+
|
69
|
+
# Iterative loop: observe → evaluate → route → tools
|
70
|
+
while self.iteration < self.max_iterations and not self.context.state.complete:
|
71
|
+
# Begin iteration with its group
|
72
|
+
_, group_id = self.begin_iteration()
|
73
|
+
|
74
|
+
query = self.context.state.query
|
75
|
+
|
76
|
+
# Observe → Evaluate → Route → Tools
|
77
|
+
observe_output = await self.observe_agent(query, group_id=group_id)
|
78
|
+
evaluate_output = await self.evaluate_agent(observe_output, group_id=group_id)
|
79
|
+
|
80
|
+
if not self.context.state.complete:
|
81
|
+
routing_output = await self.routing_agent(self._serialize_output(evaluate_output), group_id=group_id)
|
82
|
+
await self._execute_tools(routing_output, self.tool_agents, group_id)
|
83
|
+
|
84
|
+
# End iteration with its group
|
85
|
+
self.end_iteration(group_id)
|
86
|
+
|
87
|
+
if self.context.state.complete:
|
88
|
+
break
|
89
|
+
|
90
|
+
# Final report
|
91
|
+
final_group = self.begin_final_report()
|
92
|
+
self.update_printer("research", "Research workflow complete", is_done=True)
|
93
|
+
|
94
|
+
findings = self.context.state.findings_text()
|
95
|
+
await self.writer_agent(findings, group_id=final_group)
|
96
|
+
|
97
|
+
self.end_final_report(final_group)
|
@@ -0,0 +1,151 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any, Dict, Optional
|
4
|
+
|
5
|
+
from agentz.agent.base import ContextAgent
|
6
|
+
from agentz.context.conversation import create_conversation_state
|
7
|
+
from agentz.context.context import Context
|
8
|
+
from agentz.profiles.manager.memory import MemoryAgentOutput
|
9
|
+
from agentz.profiles.manager.evaluate import EvaluateOutput
|
10
|
+
from agentz.profiles.manager.routing import AgentSelectionPlan
|
11
|
+
from agentz.profiles.base import load_all_profiles
|
12
|
+
from pipelines.data_scientist import DataScientistPipeline
|
13
|
+
|
14
|
+
|
15
|
+
class DataScientistMemoryPipeline(DataScientistPipeline):
|
16
|
+
"""Data scientist pipeline variant that maintains iterative memory compression."""
|
17
|
+
|
18
|
+
def __init__(self, config):
|
19
|
+
# Don't call super().__init__ yet - we need to customize
|
20
|
+
# Call BasePipeline.__init__ directly
|
21
|
+
from pipelines.base import BasePipeline
|
22
|
+
BasePipeline.__init__(self, config)
|
23
|
+
|
24
|
+
profiles = load_all_profiles()
|
25
|
+
state = create_conversation_state(profiles=profiles)
|
26
|
+
llm = self.config.llm.main_model
|
27
|
+
|
28
|
+
# Centralized context engine with state and behaviors (including memory)
|
29
|
+
self.context = Context(
|
30
|
+
state=state,
|
31
|
+
behaviors=["observe", "evaluate", "route", "writer", "memory"],
|
32
|
+
config=config,
|
33
|
+
)
|
34
|
+
|
35
|
+
# Manager agents with memory support
|
36
|
+
self.observe_agent = ContextAgent.from_profile(profiles["observe"], llm)
|
37
|
+
self.evaluate_agent = ContextAgent.from_profile(profiles["evaluate"], llm)
|
38
|
+
self.routing_agent = ContextAgent.from_profile(profiles["routing"], llm)
|
39
|
+
self.writer_agent = ContextAgent.from_profile(profiles["writer"], llm)
|
40
|
+
self.memory_agent = ContextAgent.from_profile(profiles["memory"], llm)
|
41
|
+
|
42
|
+
# Tool agents for specialized tasks
|
43
|
+
self.tool_agents: Dict[str, Any] = {
|
44
|
+
f"{name}_agent": ContextAgent.from_profile(profiles[name], llm)
|
45
|
+
for name in ["data_loader", "data_analysis", "preprocessing",
|
46
|
+
"model_training", "evaluation", "visualization"]
|
47
|
+
}
|
48
|
+
|
49
|
+
# Optional report configuration
|
50
|
+
self.report_length: Optional[str] = None
|
51
|
+
self.report_instructions: Optional[str] = None
|
52
|
+
|
53
|
+
async def execute(self) -> Any:
|
54
|
+
"""Execute data science workflow with memory compression.
|
55
|
+
|
56
|
+
This shows the full workflow:
|
57
|
+
1. Iterative loop with observe → evaluate → route → execute tools → memory compression
|
58
|
+
2. Final report generation with writer agent
|
59
|
+
"""
|
60
|
+
self.update_printer("research", "Executing research workflow...")
|
61
|
+
|
62
|
+
return await self.run_iterative_loop(
|
63
|
+
iteration_body=self._iteration_step,
|
64
|
+
final_body=self._final_step
|
65
|
+
)
|
66
|
+
|
67
|
+
async def _iteration_step(self, iteration, group_id: str):
|
68
|
+
"""Execute one iteration: observe → evaluate → route → tools → memory."""
|
69
|
+
# Step 1: Observe using behavior rendering
|
70
|
+
observe_instructions = self.context.render_behavior("observe", self.context.snapshot("observe"))
|
71
|
+
observe_result = await self.agent_step(
|
72
|
+
agent=self.observe_agent,
|
73
|
+
instructions=observe_instructions,
|
74
|
+
span_name="observe",
|
75
|
+
span_type="agent",
|
76
|
+
printer_key="observe",
|
77
|
+
printer_title="Observing",
|
78
|
+
printer_group_id=group_id,
|
79
|
+
)
|
80
|
+
observe_output = observe_result.final_output if hasattr(observe_result, 'final_output') else observe_result
|
81
|
+
self.context.apply_output("observe", observe_output)
|
82
|
+
iteration.observation = self._serialize_output(observe_output)
|
83
|
+
self._record_structured_payload(observe_output, context_label="observe")
|
84
|
+
|
85
|
+
# Step 2: Evaluate using behavior rendering
|
86
|
+
evaluate_instructions = self.context.render_behavior("evaluate", self.context.snapshot("evaluate"))
|
87
|
+
evaluate_result = await self.agent_step(
|
88
|
+
agent=self.evaluate_agent,
|
89
|
+
instructions=evaluate_instructions,
|
90
|
+
span_name="evaluate",
|
91
|
+
span_type="agent",
|
92
|
+
output_model=EvaluateOutput,
|
93
|
+
printer_key="evaluate",
|
94
|
+
printer_title="Evaluating",
|
95
|
+
printer_group_id=group_id,
|
96
|
+
)
|
97
|
+
evaluate_output = evaluate_result.final_output if hasattr(evaluate_result, 'final_output') else evaluate_result
|
98
|
+
self.context.apply_output("evaluate", evaluate_output)
|
99
|
+
self._record_structured_payload(evaluate_output, context_label="evaluate")
|
100
|
+
|
101
|
+
# Step 3: Route to appropriate tools if not complete
|
102
|
+
if not self.state.complete:
|
103
|
+
routing_instructions = self.context.render_behavior("route", self.context.snapshot("route"))
|
104
|
+
routing_result = await self.agent_step(
|
105
|
+
agent=self.routing_agent,
|
106
|
+
instructions=routing_instructions,
|
107
|
+
span_name="routing",
|
108
|
+
span_type="agent",
|
109
|
+
output_model=AgentSelectionPlan,
|
110
|
+
printer_key="routing",
|
111
|
+
printer_title="Routing",
|
112
|
+
printer_group_id=group_id,
|
113
|
+
)
|
114
|
+
routing_output = routing_result.final_output if hasattr(routing_result, 'final_output') else routing_result
|
115
|
+
self.context.apply_output("route", routing_output)
|
116
|
+
self._record_structured_payload(routing_output, context_label="routing")
|
117
|
+
|
118
|
+
# Step 4: Execute selected tools in parallel
|
119
|
+
await self._execute_tools(routing_output, self.tool_agents, group_id)
|
120
|
+
|
121
|
+
# Step 5: Memory compression (if needed)
|
122
|
+
if not self.state.complete and bool(self.state.unsummarized_history()):
|
123
|
+
memory_instructions = self.context.render_behavior("memory", self.context.snapshot("memory"))
|
124
|
+
memory_result = await self.agent_step(
|
125
|
+
agent=self.memory_agent,
|
126
|
+
instructions=memory_instructions,
|
127
|
+
span_name="memory",
|
128
|
+
span_type="agent",
|
129
|
+
output_model=MemoryAgentOutput,
|
130
|
+
printer_key="memory",
|
131
|
+
printer_title="Memory Compression",
|
132
|
+
printer_group_id=group_id,
|
133
|
+
)
|
134
|
+
memory_output = memory_result.final_output if hasattr(memory_result, 'final_output') else memory_result
|
135
|
+
self.context.apply_output("memory", memory_output)
|
136
|
+
self._record_structured_payload(memory_output, context_label="memory")
|
137
|
+
|
138
|
+
async def _final_step(self, final_group: str):
|
139
|
+
"""Generate final report using writer agent."""
|
140
|
+
self.update_printer("research", "Research workflow complete", is_done=True)
|
141
|
+
|
142
|
+
writer_instructions = self.context.render_behavior("writer", self.context.snapshot("writer"))
|
143
|
+
await self.agent_step(
|
144
|
+
agent=self.writer_agent,
|
145
|
+
instructions=writer_instructions,
|
146
|
+
span_name="writer",
|
147
|
+
span_type="agent",
|
148
|
+
printer_key="writer",
|
149
|
+
printer_title="Writing Report",
|
150
|
+
printer_group_id=final_group,
|
151
|
+
)
|
File without changes
|
File without changes
|
pipelines/simple.py
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
from agentz.agent.base import ContextAgent
|
6
|
+
from agentz.profiles.base import load_all_profiles
|
7
|
+
from pipelines.base import BasePipeline
|
8
|
+
|
9
|
+
|
10
|
+
class SimplePipeline(BasePipeline):
|
11
|
+
"""Simple two-agent pipeline: routing agent + single tool agent."""
|
12
|
+
|
13
|
+
def __init__(self, config):
|
14
|
+
super().__init__(config)
|
15
|
+
|
16
|
+
# Load profiles for template rendering
|
17
|
+
self.profiles = load_all_profiles()
|
18
|
+
llm = self.config.llm.main_model
|
19
|
+
|
20
|
+
# Setup routing agent
|
21
|
+
self.routing_agent = ContextAgent.from_profile(self.profiles["routing"], llm)
|
22
|
+
|
23
|
+
# Setup single tool agent
|
24
|
+
self.tool_agent = ContextAgent.from_profile(self.profiles["data_analysis"], llm)
|
25
|
+
|
26
|
+
async def run(self):
|
27
|
+
"""Run the simple pipeline with single-pass execution."""
|
28
|
+
logger.info(f"Data path: {self.config.data_path}")
|
29
|
+
logger.info(f"User prompt: {self.config.prompt}")
|
30
|
+
|
31
|
+
# Prepare query
|
32
|
+
query = self.prepare_query(
|
33
|
+
content=f"Task: {self.config.prompt}\n"
|
34
|
+
f"Dataset path: {self.config.data_path}\n"
|
35
|
+
"Analyze the data and provide insights"
|
36
|
+
)
|
37
|
+
|
38
|
+
# Route the task
|
39
|
+
# self.update_printer("route", "Routing task to agent...")
|
40
|
+
routing_instructions = self.profiles["routing"].render(
|
41
|
+
QUERY=query,
|
42
|
+
GAP="Route the query to the data_analysis_agent",
|
43
|
+
HISTORY=""
|
44
|
+
)
|
45
|
+
selection_plan = await self.agent_step(
|
46
|
+
agent=self.routing_agent,
|
47
|
+
instructions=routing_instructions,
|
48
|
+
span_name="route_task",
|
49
|
+
span_type="agent",
|
50
|
+
output_model=self.routing_agent.output_type,
|
51
|
+
printer_key="route",
|
52
|
+
printer_title="Routing",
|
53
|
+
)
|
54
|
+
# self.update_printer("route", "Task routed", is_done=True)
|
55
|
+
|
56
|
+
# Execute the tool agent
|
57
|
+
task = selection_plan.tasks[0]
|
58
|
+
# self.update_printer("tool", f"Executing {task.agent}...")
|
59
|
+
|
60
|
+
# import ipdb
|
61
|
+
# ipdb.set_trace()
|
62
|
+
|
63
|
+
result = await self.agent_step(
|
64
|
+
agent=self.tool_agent,
|
65
|
+
instructions=task.model_dump_json(),
|
66
|
+
span_name=task.agent,
|
67
|
+
span_type="tool",
|
68
|
+
printer_key="tool",
|
69
|
+
printer_title=f"Tool: {task.agent}",
|
70
|
+
)
|
71
|
+
# import ipdb
|
72
|
+
# ipdb.set_trace()
|
73
|
+
|
74
|
+
# self.update_printer("tool", f"Completed {task.agent}", is_done=True)
|
75
|
+
|
76
|
+
logger.info("Simple pipeline completed")
|
77
|
+
return result
|
78
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
from agentz.agent.base import ContextAgent as Agent
|
6
|
+
from agentz.profiles.base import load_all_profiles
|
7
|
+
from pipelines.base import BasePipeline
|
8
|
+
from agentz.mcp.manager import MCPManager, MCPServerSpec
|
9
|
+
from agentz.mcp.patches import apply_browsermcp_close_patch
|
10
|
+
|
11
|
+
|
12
|
+
class NullReporter:
|
13
|
+
"""No-op reporter to disable report generation for this pipeline."""
|
14
|
+
|
15
|
+
def start(self, *_args, **_kwargs): # noqa: D401 - intentionally blank
|
16
|
+
return None
|
17
|
+
|
18
|
+
def set_final_result(self, _result): # noqa: D401 - intentionally blank
|
19
|
+
return None
|
20
|
+
|
21
|
+
def finalize(self): # noqa: D401 - intentionally blank
|
22
|
+
return None
|
23
|
+
|
24
|
+
def print_terminal_report(self): # noqa: D401 - intentionally blank
|
25
|
+
return None
|
26
|
+
|
27
|
+
def record_status_update(self, **_kwargs): # noqa: D401 - intentionally blank
|
28
|
+
return None
|
29
|
+
|
30
|
+
def record_panel(self, **_kwargs): # noqa: D401 - intentionally blank
|
31
|
+
return None
|
32
|
+
|
33
|
+
def record_group_start(self, **_kwargs): # noqa: D401 - intentionally blank
|
34
|
+
return None
|
35
|
+
|
36
|
+
def record_group_end(self, **_kwargs): # noqa: D401 - intentionally blank
|
37
|
+
return None
|
38
|
+
|
39
|
+
def record_agent_step_start(self, **_kwargs): # noqa: D401 - intentionally blank
|
40
|
+
return None
|
41
|
+
|
42
|
+
def record_agent_step_end(self, **_kwargs): # noqa: D401 - intentionally blank
|
43
|
+
return None
|
44
|
+
|
45
|
+
|
46
|
+
class SimpleBrowserPipeline(BasePipeline):
|
47
|
+
"""Simple two-agent pipeline: routing agent + single tool agent."""
|
48
|
+
|
49
|
+
def __init__(self, config):
|
50
|
+
super().__init__(config)
|
51
|
+
|
52
|
+
# Ensure Browser MCP stdio server has patched close handler to avoid recursion errors.
|
53
|
+
apply_browsermcp_close_patch()
|
54
|
+
|
55
|
+
# Disable report generation for this pipeline
|
56
|
+
self.reporter = NullReporter()
|
57
|
+
|
58
|
+
# Load profiles for template rendering
|
59
|
+
self.profiles = load_all_profiles()
|
60
|
+
llm = self.config.llm.main_model
|
61
|
+
|
62
|
+
# Setup routing agent
|
63
|
+
self.routing_agent = Agent.from_profile(self.profiles["routing"], llm)
|
64
|
+
|
65
|
+
# Setup single tool agent
|
66
|
+
self.tool_agent = None
|
67
|
+
mcp_config = getattr(self.config, "mcp", None)
|
68
|
+
self.mcp_manager = MCPManager.from_config(mcp_config)
|
69
|
+
self.mcp_manager.ensure_server(
|
70
|
+
"browser",
|
71
|
+
MCPServerSpec(
|
72
|
+
type="stdio",
|
73
|
+
options={
|
74
|
+
"name": "Browser",
|
75
|
+
"params": {"command": "npx", "args": ["-y", "@browsermcp/mcp@latest"]},
|
76
|
+
},
|
77
|
+
),
|
78
|
+
)
|
79
|
+
|
80
|
+
async def run(self):
|
81
|
+
"""Run the simple pipeline with single-pass execution to validate the browser agent."""
|
82
|
+
logger.info(f"User prompt: {self.config.prompt}")
|
83
|
+
|
84
|
+
async with self.mcp_manager.session() as mcp_session:
|
85
|
+
server = await mcp_session.get_server("browser")
|
86
|
+
self.tool_agent = Agent(
|
87
|
+
name="Browser",
|
88
|
+
instructions=f"""
|
89
|
+
You are a browser agent. Your task is to interact with the browser following the instructions provided.
|
90
|
+
""",
|
91
|
+
mcp_servers=[server],
|
92
|
+
model=self.config.llm.main_model,
|
93
|
+
# output_type=ToolAgentOutput if model_supports_json_and_tool_calls(self.config.llm.main_model) else None,
|
94
|
+
# output_parser=create_type_parser(ToolAgentOutput) if not model_supports_json_and_tool_calls(self.config.llm.main_model) else None
|
95
|
+
)
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
# Prepare query
|
100
|
+
query = self.prepare_query(
|
101
|
+
content=f"Task: {self.config.prompt}\n"
|
102
|
+
)
|
103
|
+
|
104
|
+
# Route the task
|
105
|
+
# self.update_printer("route", "Routing task to agent...")
|
106
|
+
routing_instructions = self.profiles["routing"].render(
|
107
|
+
QUERY=query,
|
108
|
+
GAP="Route the query to the browser_agent",
|
109
|
+
HISTORY=""
|
110
|
+
)
|
111
|
+
selection_plan = await self.agent_step(
|
112
|
+
agent=self.routing_agent,
|
113
|
+
instructions=routing_instructions,
|
114
|
+
span_name="route_task",
|
115
|
+
span_type="agent",
|
116
|
+
output_model=self.routing_agent.output_type,
|
117
|
+
printer_key="route",
|
118
|
+
printer_title="Routing",
|
119
|
+
)
|
120
|
+
# self.update_printer("route", "Task routed", is_done=True)
|
121
|
+
|
122
|
+
# Execute the tool agent
|
123
|
+
task = selection_plan.tasks[0]
|
124
|
+
print(task)
|
125
|
+
# self.update_printer("tool", f"Executing {task.agent}...")
|
126
|
+
|
127
|
+
# import ipdb
|
128
|
+
# ipdb.set_trace()
|
129
|
+
|
130
|
+
result = await self.agent_step(
|
131
|
+
agent=self.tool_agent,
|
132
|
+
instructions=task.model_dump_json(),
|
133
|
+
span_name=task.agent,
|
134
|
+
span_type="tool",
|
135
|
+
printer_key="tool",
|
136
|
+
printer_title=f"Tool: {task.agent}",
|
137
|
+
)
|
138
|
+
# import ipdb
|
139
|
+
# ipdb.set_trace()
|
140
|
+
|
141
|
+
# self.update_printer("tool", f"Completed {task.agent}", is_done=True)
|
142
|
+
|
143
|
+
logger.info("Simple browser pipeline completed")
|
144
|
+
return result
|
145
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
from agentz.agent.base import ContextAgent
|
6
|
+
from agentz.profiles.base import load_all_profiles
|
7
|
+
from pipelines.base import BasePipeline
|
8
|
+
|
9
|
+
|
10
|
+
class SimpleChromePipeline(BasePipeline):
|
11
|
+
"""Simple two-agent pipeline: routing agent + single tool agent."""
|
12
|
+
|
13
|
+
def __init__(self, config):
|
14
|
+
super().__init__(config)
|
15
|
+
|
16
|
+
# Load profiles for template rendering
|
17
|
+
self.profiles = load_all_profiles()
|
18
|
+
llm = self.config.llm.main_model
|
19
|
+
|
20
|
+
# Setup routing agent
|
21
|
+
self.routing_agent = ContextAgent.from_profile(self.profiles["routing"], llm)
|
22
|
+
|
23
|
+
# Setup single tool agent
|
24
|
+
self.tool_agent = ContextAgent.from_profile(self.profiles["chrome"], llm)
|
25
|
+
|
26
|
+
async def run(self):
|
27
|
+
"""Run the simple pipeline with single-pass execution to validate the chrome agent."""
|
28
|
+
logger.info(f"User prompt: {self.config.prompt}")
|
29
|
+
|
30
|
+
# Prepare query
|
31
|
+
query = self.prepare_query(
|
32
|
+
content=f"Task: {self.config.prompt}\n"
|
33
|
+
)
|
34
|
+
|
35
|
+
# Route the task
|
36
|
+
# self.update_printer("route", "Routing task to agent...")
|
37
|
+
routing_instructions = self.profiles["routing"].render(
|
38
|
+
QUERY=query,
|
39
|
+
GAP="Route the query to the chrome_agent",
|
40
|
+
HISTORY=""
|
41
|
+
)
|
42
|
+
selection_plan = await self.agent_step(
|
43
|
+
agent=self.routing_agent,
|
44
|
+
instructions=routing_instructions,
|
45
|
+
span_name="route_task",
|
46
|
+
span_type="agent",
|
47
|
+
output_model=self.routing_agent.output_type,
|
48
|
+
printer_key="route",
|
49
|
+
printer_title="Routing",
|
50
|
+
)
|
51
|
+
# self.update_printer("route", "Task routed", is_done=True)
|
52
|
+
|
53
|
+
# Execute the tool agent
|
54
|
+
task = selection_plan.tasks[0]
|
55
|
+
# self.update_printer("tool", f"Executing {task.agent}...")
|
56
|
+
|
57
|
+
# import ipdb
|
58
|
+
# ipdb.set_trace()
|
59
|
+
|
60
|
+
result = await self.agent_step(
|
61
|
+
agent=self.tool_agent,
|
62
|
+
instructions=task.model_dump_json(),
|
63
|
+
span_name=task.agent,
|
64
|
+
span_type="tool",
|
65
|
+
printer_key="tool",
|
66
|
+
printer_title=f"Tool: {task.agent}",
|
67
|
+
)
|
68
|
+
# import ipdb
|
69
|
+
# ipdb.set_trace()
|
70
|
+
|
71
|
+
# self.update_printer("tool", f"Completed {task.agent}", is_done=True)
|
72
|
+
|
73
|
+
logger.info("Simple chrome pipeline completed")
|
74
|
+
return result
|
75
|
+
|
@@ -0,0 +1,103 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
from agentz.agent.base import ContextAgent as Agent
|
6
|
+
from agentz.profiles.base import load_all_profiles
|
7
|
+
from pipelines.base import BasePipeline
|
8
|
+
from agentz.profiles.base import ToolAgentOutput
|
9
|
+
from agentz.utils.config import BaseConfig
|
10
|
+
from agentz.llm.llm_setup import model_supports_json_and_tool_calls
|
11
|
+
from agentz.utils import create_type_parser
|
12
|
+
from agents.mcp import MCPServer, MCPServerStdio, MCPServerSse
|
13
|
+
|
14
|
+
|
15
|
+
async def get_notion_server():
|
16
|
+
async with MCPServerSse(
|
17
|
+
name = "Notion",
|
18
|
+
params = {
|
19
|
+
"url": "https://mcp.notion.com/mcp"
|
20
|
+
}
|
21
|
+
) as server:
|
22
|
+
return server
|
23
|
+
|
24
|
+
class SimpleNotionPipeline(BasePipeline):
|
25
|
+
"""Simple two-agent pipeline: routing agent + single tool agent."""
|
26
|
+
|
27
|
+
def __init__(self, config):
|
28
|
+
super().__init__(config)
|
29
|
+
|
30
|
+
# Load profiles for template rendering
|
31
|
+
self.profiles = load_all_profiles()
|
32
|
+
llm = self.config.llm.main_model
|
33
|
+
|
34
|
+
# Setup routing agent
|
35
|
+
self.routing_agent = Agent.from_profile(self.profiles["routing"], llm)
|
36
|
+
|
37
|
+
# Setup single tool agent
|
38
|
+
self.tool_agent = None
|
39
|
+
|
40
|
+
async def run(self):
|
41
|
+
"""Run the simple pipeline with single-pass execution to validate the notion agent."""
|
42
|
+
logger.info(f"User prompt: {self.config.prompt}")
|
43
|
+
|
44
|
+
|
45
|
+
self.tool_agent = Agent(
|
46
|
+
name="Notion",
|
47
|
+
instructions=f"""
|
48
|
+
You are a notion agent. Your task is to interact with the notion following the instructions provided.
|
49
|
+
""",
|
50
|
+
mcp_servers=[await get_notion_server()],
|
51
|
+
model=self.config.llm.main_model,
|
52
|
+
output_type=ToolAgentOutput if model_supports_json_and_tool_calls(self.config.llm.main_model) else None,
|
53
|
+
output_parser=create_type_parser(ToolAgentOutput) if not model_supports_json_and_tool_calls(self.config.llm.main_model) else None
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
# Prepare query
|
59
|
+
query = self.prepare_query(
|
60
|
+
content=f"Task: {self.config.prompt}\n"
|
61
|
+
)
|
62
|
+
|
63
|
+
# Route the task
|
64
|
+
# self.update_printer("route", "Routing task to agent...")
|
65
|
+
routing_instructions = self.profiles["routing"].render(
|
66
|
+
QUERY=query,
|
67
|
+
GAP="Route the query to the notion_agent",
|
68
|
+
HISTORY=""
|
69
|
+
)
|
70
|
+
selection_plan = await self.agent_step(
|
71
|
+
agent=self.routing_agent,
|
72
|
+
instructions=routing_instructions,
|
73
|
+
span_name="route_task",
|
74
|
+
span_type="agent",
|
75
|
+
output_model=self.routing_agent.output_type,
|
76
|
+
printer_key="route",
|
77
|
+
printer_title="Routing",
|
78
|
+
)
|
79
|
+
# self.update_printer("route", "Task routed", is_done=True)
|
80
|
+
|
81
|
+
# Execute the tool agent
|
82
|
+
task = selection_plan.tasks[0]
|
83
|
+
# self.update_printer("tool", f"Executing {task.agent}...")
|
84
|
+
|
85
|
+
# import ipdb
|
86
|
+
# ipdb.set_trace()
|
87
|
+
|
88
|
+
result = await self.agent_step(
|
89
|
+
agent=self.tool_agent,
|
90
|
+
instructions=task.model_dump_json(),
|
91
|
+
span_name=task.agent,
|
92
|
+
span_type="tool",
|
93
|
+
printer_key="tool",
|
94
|
+
printer_title=f"Tool: {task.agent}",
|
95
|
+
)
|
96
|
+
# import ipdb
|
97
|
+
# ipdb.set_trace()
|
98
|
+
|
99
|
+
# self.update_printer("tool", f"Completed {task.agent}", is_done=True)
|
100
|
+
|
101
|
+
logger.info("Simple notion pipeline completed")
|
102
|
+
return result
|
103
|
+
|
File without changes
|