Skip to content

Commit e4c95c7

Browse files
committed
fixed ruff format --check
1 parent bfb1a81 commit e4c95c7

6 files changed

Lines changed: 165 additions & 47 deletions

File tree

.claude/skills/building-agents-construction/examples/online_research_agent/__main__.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,10 @@ async def _interactive_shell(verbose=False):
108108
try:
109109
while True:
110110
try:
111-
topic = await asyncio.get_event_loop().run_in_executor(None, input, "Topic> ")
112-
if topic.lower() in ['quit', 'exit', 'q']:
111+
topic = await asyncio.get_event_loop().run_in_executor(
112+
None, input, "Topic> "
113+
)
114+
if topic.lower() in ["quit", "exit", "q"]:
113115
click.echo("Goodbye!")
114116
break
115117

@@ -130,7 +132,11 @@ async def _interactive_shell(verbose=False):
130132
click.echo(f"\nReport saved to: {output['file_path']}\n")
131133
if "final_report" in output:
132134
click.echo("\n--- Report Preview ---\n")
133-
preview = output["final_report"][:500] + "..." if len(output.get("final_report", "")) > 500 else output.get("final_report", "")
135+
preview = (
136+
output["final_report"][:500] + "..."
137+
if len(output.get("final_report", "")) > 500
138+
else output.get("final_report", "")
139+
)
134140
click.echo(preview)
135141
click.echo("\n")
136142
else:
@@ -142,6 +148,7 @@ async def _interactive_shell(verbose=False):
142148
except Exception as e:
143149
click.echo(f"Error: {e}", err=True)
144150
import traceback
151+
145152
traceback.print_exc()
146153
finally:
147154
await agent.stop()

.claude/skills/building-agents-construction/examples/online_research_agent/agent.py

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Agent graph construction for Online Research Agent."""
2+
23
from framework.graph import EdgeSpec, EdgeCondition, Goal, SuccessCriterion, Constraint
34
from framework.graph.edge import GraphSpec
45
from framework.graph.executor import ExecutionResult
@@ -194,13 +195,15 @@ def _build_entry_point_specs(self) -> list[EntryPointSpec]:
194195
trigger_type = "manual"
195196
name = ep_id.replace("-", " ").title()
196197

197-
specs.append(EntryPointSpec(
198-
id=ep_id,
199-
name=name,
200-
entry_node=node_id,
201-
trigger_type=trigger_type,
202-
isolation_level="shared",
203-
))
198+
specs.append(
199+
EntryPointSpec(
200+
id=ep_id,
201+
name=name,
202+
entry_node=node_id,
203+
trigger_type=trigger_type,
204+
isolation_level="shared",
205+
)
206+
)
204207
return specs
205208

206209
def _create_runtime(self, mock_mode=False) -> AgentRuntime:
@@ -225,7 +228,10 @@ def _create_runtime(self, mock_mode=False) -> AgentRuntime:
225228
for server_name, server_config in mcp_servers.items():
226229
server_config["name"] = server_name
227230
# Resolve relative cwd paths
228-
if "cwd" in server_config and not Path(server_config["cwd"]).is_absolute():
231+
if (
232+
"cwd" in server_config
233+
and not Path(server_config["cwd"]).is_absolute()
234+
):
229235
server_config["cwd"] = str(agent_dir / server_config["cwd"])
230236
tool_registry.register_mcp_server(server_config)
231237

@@ -297,7 +303,9 @@ async def trigger(
297303
"""
298304
if self._runtime is None or not self._runtime.is_running:
299305
raise RuntimeError("Agent runtime not started. Call start() first.")
300-
return await self._runtime.trigger(entry_point, input_data, correlation_id, session_state=session_state)
306+
return await self._runtime.trigger(
307+
entry_point, input_data, correlation_id, session_state=session_state
308+
)
301309

302310
async def trigger_and_wait(
303311
self,
@@ -320,9 +328,13 @@ async def trigger_and_wait(
320328
"""
321329
if self._runtime is None or not self._runtime.is_running:
322330
raise RuntimeError("Agent runtime not started. Call start() first.")
323-
return await self._runtime.trigger_and_wait(entry_point, input_data, timeout, session_state=session_state)
331+
return await self._runtime.trigger_and_wait(
332+
entry_point, input_data, timeout, session_state=session_state
333+
)
324334

325-
async def run(self, context: dict, mock_mode=False, session_state=None) -> ExecutionResult:
335+
async def run(
336+
self, context: dict, mock_mode=False, session_state=None
337+
) -> ExecutionResult:
326338
"""
327339
Run the agent (convenience method for simple single execution).
328340
@@ -341,7 +353,9 @@ async def run(self, context: dict, mock_mode=False, session_state=None) -> Execu
341353
else:
342354
entry_point = "start"
343355

344-
result = await self.trigger_and_wait(entry_point, context, session_state=session_state)
356+
result = await self.trigger_and_wait(
357+
entry_point, context, session_state=session_state
358+
)
345359
return result or ExecutionResult(success=False, error="Execution timeout")
346360
finally:
347361
await self.stop()
@@ -403,7 +417,9 @@ def validate(self):
403417
# Validate entry points
404418
for ep_id, node_id in self.entry_points.items():
405419
if node_id not in node_ids:
406-
errors.append(f"Entry point '{ep_id}' references unknown node '{node_id}'")
420+
errors.append(
421+
f"Entry point '{ep_id}' references unknown node '{node_id}'"
422+
)
407423

408424
return {
409425
"valid": len(errors) == 0,

.claude/skills/building-agents-construction/examples/online_research_agent/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Runtime configuration."""
2+
23
from dataclasses import dataclass
34

45

@@ -13,6 +14,7 @@ class RuntimeConfig:
1314

1415
default_config = RuntimeConfig()
1516

17+
1618
# Agent metadata
1719
@dataclass
1820
class AgentMetadata:

.claude/skills/building-agents-construction/examples/online_research_agent/nodes/__init__.py

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Node definitions for Online Research Agent."""
2+
23
from framework.graph import NodeSpec
34

45
# Node 1: Parse Query
@@ -10,9 +11,21 @@
1011
input_keys=["topic"],
1112
output_keys=["search_queries", "research_focus", "key_aspects"],
1213
output_schema={
13-
"research_focus": {"type": "string", "required": True, "description": "Brief statement of what we're researching"},
14-
"key_aspects": {"type": "array", "required": True, "description": "List of 3-5 key aspects to investigate"},
15-
"search_queries": {"type": "array", "required": True, "description": "List of 3-5 search queries"},
14+
"research_focus": {
15+
"type": "string",
16+
"required": True,
17+
"description": "Brief statement of what we're researching",
18+
},
19+
"key_aspects": {
20+
"type": "array",
21+
"required": True,
22+
"description": "List of 3-5 key aspects to investigate",
23+
},
24+
"search_queries": {
25+
"type": "array",
26+
"required": True,
27+
"description": "List of 3-5 search queries",
28+
},
1629
},
1730
system_prompt="""\
1831
You are a research query strategist. Given a research topic, analyze it and generate search queries.
@@ -50,8 +63,16 @@
5063
input_keys=["search_queries", "research_focus"],
5164
output_keys=["source_urls", "search_results_summary"],
5265
output_schema={
53-
"source_urls": {"type": "array", "required": True, "description": "List of source URLs found"},
54-
"search_results_summary": {"type": "string", "required": True, "description": "Brief summary of what was found"},
66+
"source_urls": {
67+
"type": "array",
68+
"required": True,
69+
"description": "List of source URLs found",
70+
},
71+
"search_results_summary": {
72+
"type": "string",
73+
"required": True,
74+
"description": "Brief summary of what was found",
75+
},
5576
},
5677
system_prompt="""\
5778
You are a research assistant executing web searches. Use the web_search tool to find sources.
@@ -80,8 +101,16 @@
80101
input_keys=["source_urls", "research_focus"],
81102
output_keys=["fetched_sources", "fetch_errors"],
82103
output_schema={
83-
"fetched_sources": {"type": "array", "required": True, "description": "List of fetched source objects with url, title, content"},
84-
"fetch_errors": {"type": "array", "required": True, "description": "List of URLs that failed to fetch"},
104+
"fetched_sources": {
105+
"type": "array",
106+
"required": True,
107+
"description": "List of fetched source objects with url, title, content",
108+
},
109+
"fetch_errors": {
110+
"type": "array",
111+
"required": True,
112+
"description": "List of URLs that failed to fetch",
113+
},
85114
},
86115
system_prompt="""\
87116
You are a content fetcher. Use web_scrape tool to retrieve content from URLs.
@@ -113,8 +142,16 @@
113142
input_keys=["fetched_sources", "research_focus", "key_aspects"],
114143
output_keys=["ranked_sources", "source_analysis"],
115144
output_schema={
116-
"ranked_sources": {"type": "array", "required": True, "description": "List of ranked sources with scores"},
117-
"source_analysis": {"type": "string", "required": True, "description": "Overview of source quality and coverage"},
145+
"ranked_sources": {
146+
"type": "array",
147+
"required": True,
148+
"description": "List of ranked sources with scores",
149+
},
150+
"source_analysis": {
151+
"type": "string",
152+
"required": True,
153+
"description": "Overview of source quality and coverage",
154+
},
118155
},
119156
system_prompt="""\
120157
You are a source evaluator. Assess each source for quality and relevance.
@@ -153,9 +190,21 @@
153190
input_keys=["ranked_sources", "research_focus", "key_aspects"],
154191
output_keys=["key_findings", "themes", "source_citations"],
155192
output_schema={
156-
"key_findings": {"type": "array", "required": True, "description": "List of key findings with sources and confidence"},
157-
"themes": {"type": "array", "required": True, "description": "List of themes with descriptions and supporting sources"},
158-
"source_citations": {"type": "object", "required": True, "description": "Map of facts to supporting URLs"},
193+
"key_findings": {
194+
"type": "array",
195+
"required": True,
196+
"description": "List of key findings with sources and confidence",
197+
},
198+
"themes": {
199+
"type": "array",
200+
"required": True,
201+
"description": "List of themes with descriptions and supporting sources",
202+
},
203+
"source_citations": {
204+
"type": "object",
205+
"required": True,
206+
"description": "Map of facts to supporting URLs",
207+
},
159208
},
160209
system_prompt="""\
161210
You are a research synthesizer. Analyze multiple sources to extract insights.
@@ -192,11 +241,25 @@
192241
name="Write Report",
193242
description="Generate a narrative report with proper citations",
194243
node_type="llm_generate",
195-
input_keys=["key_findings", "themes", "source_citations", "research_focus", "ranked_sources"],
244+
input_keys=[
245+
"key_findings",
246+
"themes",
247+
"source_citations",
248+
"research_focus",
249+
"ranked_sources",
250+
],
196251
output_keys=["report_content", "references"],
197252
output_schema={
198-
"report_content": {"type": "string", "required": True, "description": "Full markdown report text with citations"},
199-
"references": {"type": "array", "required": True, "description": "List of reference objects with number, url, title"},
253+
"report_content": {
254+
"type": "string",
255+
"required": True,
256+
"description": "Full markdown report text with citations",
257+
},
258+
"references": {
259+
"type": "array",
260+
"required": True,
261+
"description": "List of reference objects with number, url, title",
262+
},
200263
},
201264
system_prompt="""\
202265
You are a research report writer. Create a well-structured narrative report.
@@ -239,9 +302,21 @@
239302
input_keys=["report_content", "references", "source_citations"],
240303
output_keys=["quality_score", "issues", "final_report"],
241304
output_schema={
242-
"quality_score": {"type": "number", "required": True, "description": "Quality score 0-1"},
243-
"issues": {"type": "array", "required": True, "description": "List of issues found and fixed"},
244-
"final_report": {"type": "string", "required": True, "description": "Corrected full report"},
305+
"quality_score": {
306+
"type": "number",
307+
"required": True,
308+
"description": "Quality score 0-1",
309+
},
310+
"issues": {
311+
"type": "array",
312+
"required": True,
313+
"description": "List of issues found and fixed",
314+
},
315+
"final_report": {
316+
"type": "string",
317+
"required": True,
318+
"description": "Corrected full report",
319+
},
245320
},
246321
system_prompt="""\
247322
You are a quality assurance reviewer. Check the research report for issues.
@@ -278,8 +353,16 @@
278353
input_keys=["final_report", "references", "research_focus"],
279354
output_keys=["file_path", "save_status"],
280355
output_schema={
281-
"file_path": {"type": "string", "required": True, "description": "Path where report was saved"},
282-
"save_status": {"type": "string", "required": True, "description": "Status of save operation"},
356+
"file_path": {
357+
"type": "string",
358+
"required": True,
359+
"description": "Path where report was saved",
360+
},
361+
"save_status": {
362+
"type": "string",
363+
"required": True,
364+
"description": "Status of save operation",
365+
},
283366
},
284367
system_prompt="""\
285368
You are a file manager. Save the research report to disk.

core/framework/mcp/agent_builder_server.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,13 @@ def add_node(
524524
tools_list = json.loads(tools)
525525
routes_dict = json.loads(routes)
526526
except json.JSONDecodeError as e:
527-
return json.dumps({
528-
"valid": False,
529-
"errors": [f"Invalid JSON input: {e}"],
530-
"warnings": [],
531-
})
527+
return json.dumps(
528+
{
529+
"valid": False,
530+
"errors": [f"Invalid JSON input: {e}"],
531+
"warnings": [],
532+
}
533+
)
532534

533535
# Validate credentials for tools BEFORE adding the node
534536
cred_error = _validate_tool_credentials(tools_list)
@@ -717,11 +719,13 @@ def update_node(
717719
tools_list = json.loads(tools) if tools else None
718720
routes_dict = json.loads(routes) if routes else None
719721
except json.JSONDecodeError as e:
720-
return json.dumps({
721-
"valid": False,
722-
"errors": [f"Invalid JSON input: {e}"],
723-
"warnings": [],
724-
})
722+
return json.dumps(
723+
{
724+
"valid": False,
725+
"errors": [f"Invalid JSON input: {e}"],
726+
"warnings": [],
727+
}
728+
)
725729

726730
# Validate credentials for new tools BEFORE updating
727731
if tools_list:

core/tests/test_executor_max_retries.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
the max_retries field in NodeSpec and using a hardcoded value of 3.
66
"""
77

8-
from unittest.mock import MagicMock
8+
from unittest.mock import AsyncMock, MagicMock
99

1010
import pytest
1111

@@ -47,6 +47,12 @@ async def execute(self, ctx: NodeContext) -> NodeResult:
4747
return NodeResult(success=False, error=f"Permanent error (attempt {self.attempt_count})")
4848

4949

50+
@pytest.fixture(autouse=True)
51+
def fast_sleep(monkeypatch):
52+
"""Mock asyncio.sleep to avoid real delays from exponential backoff."""
53+
monkeypatch.setattr("asyncio.sleep", AsyncMock())
54+
55+
5056
@pytest.fixture
5157
def runtime():
5258
"""Create a mock Runtime for testing."""

0 commit comments

Comments
 (0)