|
7 | 7 | from framework.graph.checkpoint_config import CheckpointConfig |
8 | 8 | from framework.llm import LiteLLMProvider |
9 | 9 | from framework.runner.tool_registry import ToolRegistry |
10 | | -from framework.runtime.agent_runtime import AgentRuntime, create_agent_runtime |
| 10 | +from framework.runtime.agent_runtime import create_agent_runtime |
11 | 11 | from framework.runtime.execution_stream import EntryPointSpec |
12 | 12 |
|
13 | 13 | from .config import default_config, metadata |
|
18 | 18 | name="Local Business Extraction", |
19 | 19 | description="Find local businesses on Maps, extract contacts, and sync to Google Sheets.", |
20 | 20 | success_criteria=[ |
21 | | - SuccessCriterion(id="sc-1", description="Extract business details from Maps", metric="count", target="5", weight=0.5), |
22 | | - SuccessCriterion(id="sc-2", description="Sync data to Google Sheets", metric="success_rate", target="1.0", weight=0.5), |
| 21 | + SuccessCriterion( |
| 22 | + id="sc-1", |
| 23 | + description="Extract business details from Maps", |
| 24 | + metric="count", |
| 25 | + target="5", |
| 26 | + weight=0.5, |
| 27 | + ), |
| 28 | + SuccessCriterion( |
| 29 | + id="sc-2", |
| 30 | + description="Sync data to Google Sheets", |
| 31 | + metric="success_rate", |
| 32 | + target="1.0", |
| 33 | + weight=0.5, |
| 34 | + ), |
23 | 35 | ], |
24 | 36 | constraints=[ |
25 | | - Constraint(id="c-1", description="Must verify website presence before scraping", constraint_type="hard", category="quality"), |
| 37 | + Constraint( |
| 38 | + id="c-1", |
| 39 | + description="Must verify website presence before scraping", |
| 40 | + constraint_type="hard", |
| 41 | + category="quality", |
| 42 | + ), |
26 | 43 | ], |
27 | 44 | ) |
28 | 45 |
|
29 | 46 | nodes = [map_search_gcu, extract_contacts_node, sheets_sync_node] |
30 | 47 |
|
31 | 48 | edges = [ |
32 | | - EdgeSpec(id="extract-to-sheets", source="extract-contacts", target="sheets-sync", |
33 | | - condition=EdgeCondition.ON_SUCCESS, priority=1), |
| 49 | + EdgeSpec( |
| 50 | + id="extract-to-sheets", |
| 51 | + source="extract-contacts", |
| 52 | + target="sheets-sync", |
| 53 | + condition=EdgeCondition.ON_SUCCESS, |
| 54 | + priority=1, |
| 55 | + ), |
34 | 56 | # Loop back for new tasks |
35 | | - EdgeSpec(id="sheets-to-extract", source="sheets-sync", target="extract-contacts", |
36 | | - condition=EdgeCondition.ALWAYS, priority=1), |
| 57 | + EdgeSpec( |
| 58 | + id="sheets-to-extract", |
| 59 | + source="sheets-sync", |
| 60 | + target="extract-contacts", |
| 61 | + condition=EdgeCondition.ALWAYS, |
| 62 | + priority=1, |
| 63 | + ), |
37 | 64 | ] |
38 | 65 |
|
39 | 66 | entry_node = "extract-contacts" |
|
43 | 70 |
|
44 | 71 | conversation_mode = "continuous" |
45 | 72 | identity_prompt = "You are a lead generation specialist focused on local businesses." |
46 | | -loop_config = {"max_iterations": 100, "max_tool_calls_per_turn": 30, "max_history_tokens": 32000} |
| 73 | +loop_config = { |
| 74 | + "max_iterations": 100, |
| 75 | + "max_tool_calls_per_turn": 30, |
| 76 | + "max_history_tokens": 32000, |
| 77 | +} |
| 78 | + |
47 | 79 |
|
48 | 80 | class LocalBusinessExtractor: |
49 | 81 | def __init__(self, config=None): |
@@ -79,36 +111,60 @@ def _build_graph(self): |
79 | 111 | ) |
80 | 112 |
|
81 | 113 | def _setup(self): |
82 | | - self._storage_path = Path.home() / ".hive" / "agents" / "local_business_extractor" |
| 114 | + self._storage_path = ( |
| 115 | + Path.home() / ".hive" / "agents" / "local_business_extractor" |
| 116 | + ) |
83 | 117 | self._storage_path.mkdir(parents=True, exist_ok=True) |
84 | 118 | self._tool_registry = ToolRegistry() |
85 | 119 | mcp_config = Path(__file__).parent / "mcp_servers.json" |
86 | 120 | if mcp_config.exists(): |
87 | 121 | self._tool_registry.load_mcp_config(mcp_config) |
88 | | - llm = LiteLLMProvider(model=self.config.model, api_key=self.config.api_key, api_base=self.config.api_base) |
| 122 | + llm = LiteLLMProvider( |
| 123 | + model=self.config.model, |
| 124 | + api_key=self.config.api_key, |
| 125 | + api_base=self.config.api_base, |
| 126 | + ) |
89 | 127 | tools = list(self._tool_registry.get_tools().values()) |
90 | 128 | tool_executor = self._tool_registry.get_executor() |
91 | 129 | self._graph = self._build_graph() |
92 | 130 | self._agent_runtime = create_agent_runtime( |
93 | | - graph=self._graph, goal=self.goal, storage_path=self._storage_path, |
94 | | - entry_points=[EntryPointSpec(id="default", name="Default", entry_node=self.entry_node, |
95 | | - trigger_type="manual", isolation_level="shared")], |
96 | | - llm=llm, tools=tools, tool_executor=tool_executor, |
97 | | - checkpoint_config=CheckpointConfig(enabled=True, checkpoint_on_node_complete=True), |
| 131 | + graph=self._graph, |
| 132 | + goal=self.goal, |
| 133 | + storage_path=self._storage_path, |
| 134 | + entry_points=[ |
| 135 | + EntryPointSpec( |
| 136 | + id="default", |
| 137 | + name="Default", |
| 138 | + entry_node=self.entry_node, |
| 139 | + trigger_type="manual", |
| 140 | + isolation_level="shared", |
| 141 | + ) |
| 142 | + ], |
| 143 | + llm=llm, |
| 144 | + tools=tools, |
| 145 | + tool_executor=tool_executor, |
| 146 | + checkpoint_config=CheckpointConfig( |
| 147 | + enabled=True, checkpoint_on_node_complete=True |
| 148 | + ), |
98 | 149 | ) |
99 | 150 |
|
100 | 151 | async def start(self): |
101 | | - if self._agent_runtime is None: self._setup() |
102 | | - if not self._agent_runtime.is_running: await self._agent_runtime.start() |
| 152 | + if self._agent_runtime is None: |
| 153 | + self._setup() |
| 154 | + if not self._agent_runtime.is_running: |
| 155 | + await self._agent_runtime.start() |
103 | 156 |
|
104 | 157 | async def stop(self): |
105 | | - if self._agent_runtime and self._agent_runtime.is_running: await self._agent_runtime.stop() |
| 158 | + if self._agent_runtime and self._agent_runtime.is_running: |
| 159 | + await self._agent_runtime.stop() |
106 | 160 | self._agent_runtime = None |
107 | 161 |
|
108 | 162 | async def run(self, context, session_state=None): |
109 | 163 | await self.start() |
110 | 164 | try: |
111 | | - result = await self._agent_runtime.trigger_and_wait("default", context, session_state=session_state) |
| 165 | + result = await self._agent_runtime.trigger_and_wait( |
| 166 | + "default", context, session_state=session_state |
| 167 | + ) |
112 | 168 | return result or ExecutionResult(success=False, error="Execution timeout") |
113 | 169 | finally: |
114 | 170 | await self.stop() |
|
0 commit comments