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.
Files changed (66) hide show
  1. agentz/agent/base.py +262 -0
  2. agentz/artifacts/__init__.py +5 -0
  3. agentz/artifacts/artifact_writer.py +538 -0
  4. agentz/artifacts/reporter.py +235 -0
  5. agentz/artifacts/terminal_writer.py +100 -0
  6. agentz/context/__init__.py +6 -0
  7. agentz/context/context.py +91 -0
  8. agentz/context/conversation.py +205 -0
  9. agentz/context/data_store.py +208 -0
  10. agentz/llm/llm_setup.py +156 -0
  11. agentz/mcp/manager.py +142 -0
  12. agentz/mcp/patches.py +88 -0
  13. agentz/mcp/servers/chrome_devtools/server.py +14 -0
  14. agentz/profiles/base.py +108 -0
  15. agentz/profiles/data/data_analysis.py +38 -0
  16. agentz/profiles/data/data_loader.py +35 -0
  17. agentz/profiles/data/evaluation.py +43 -0
  18. agentz/profiles/data/model_training.py +47 -0
  19. agentz/profiles/data/preprocessing.py +47 -0
  20. agentz/profiles/data/visualization.py +47 -0
  21. agentz/profiles/manager/evaluate.py +51 -0
  22. agentz/profiles/manager/memory.py +62 -0
  23. agentz/profiles/manager/observe.py +48 -0
  24. agentz/profiles/manager/routing.py +66 -0
  25. agentz/profiles/manager/writer.py +51 -0
  26. agentz/profiles/mcp/browser.py +21 -0
  27. agentz/profiles/mcp/chrome.py +21 -0
  28. agentz/profiles/mcp/notion.py +21 -0
  29. agentz/runner/__init__.py +74 -0
  30. agentz/runner/base.py +28 -0
  31. agentz/runner/executor.py +320 -0
  32. agentz/runner/hooks.py +110 -0
  33. agentz/runner/iteration.py +142 -0
  34. agentz/runner/patterns.py +215 -0
  35. agentz/runner/tracker.py +188 -0
  36. agentz/runner/utils.py +45 -0
  37. agentz/runner/workflow.py +250 -0
  38. agentz/tools/__init__.py +20 -0
  39. agentz/tools/data_tools/__init__.py +17 -0
  40. agentz/tools/data_tools/data_analysis.py +152 -0
  41. agentz/tools/data_tools/data_loading.py +92 -0
  42. agentz/tools/data_tools/evaluation.py +175 -0
  43. agentz/tools/data_tools/helpers.py +120 -0
  44. agentz/tools/data_tools/model_training.py +192 -0
  45. agentz/tools/data_tools/preprocessing.py +229 -0
  46. agentz/tools/data_tools/visualization.py +281 -0
  47. agentz/utils/__init__.py +69 -0
  48. agentz/utils/config.py +708 -0
  49. agentz/utils/helpers.py +10 -0
  50. agentz/utils/parsers.py +142 -0
  51. agentz/utils/printer.py +539 -0
  52. pipelines/base.py +972 -0
  53. pipelines/data_scientist.py +97 -0
  54. pipelines/data_scientist_memory.py +151 -0
  55. pipelines/experience_learner.py +0 -0
  56. pipelines/prompt_generator.py +0 -0
  57. pipelines/simple.py +78 -0
  58. pipelines/simple_browser.py +145 -0
  59. pipelines/simple_chrome.py +75 -0
  60. pipelines/simple_notion.py +103 -0
  61. pipelines/tool_builder.py +0 -0
  62. zero_agent-0.1.0.dist-info/METADATA +269 -0
  63. zero_agent-0.1.0.dist-info/RECORD +66 -0
  64. zero_agent-0.1.0.dist-info/WHEEL +5 -0
  65. zero_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
  66. 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