Skip to content

Commit 76c50bc

Browse files
committed
refactor(examples): consolidate 16 examples into 12
Merge narrow/related examples and remove developer-internals files: - 04_resources_and_retrieval.py: merge resource management + tool retrieval - 06_agent_identity.py: rename from 08 (content unchanged) - 07_skills.py: renumber from 10_skills - 08_human_in_the_loop.py: renumber from 07 - 09_async_and_streaming.py: merge arun()/gather and run_stream() with "Which method to use" preamble distinguishing the two patterns - 10_error_handling.py: renumber from 11 - 11_multi_agent.py: renumber from 13 - 12_persistence.py: renumber from 16 - Delete 09_repl_isolation.py and 10_extract_subgraph.py (internals) - Update README to document all 12 examples
1 parent 1bfab00 commit 76c50bc

15 files changed

Lines changed: 280 additions & 521 deletions

examples/04_resource_management.py

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""
2+
Resource Management and Tool Retrieval
3+
=======================================
4+
5+
BaseAgent exposes a ResourceManager that tracks data sources, libraries, and
6+
tools. You can register custom data and libraries so the agent can reference
7+
them when planning tasks, and optionally enable automatic tool selection.
8+
9+
DataLakeItem — a dataset the agent can read (CSV, Parquet, etc.)
10+
Library — a Python/R package or CLI tool the agent can use
11+
use_tool_retriever — when True, the agent embeds available tools and selects
12+
relevant ones by semantic similarity before each run,
13+
instead of passing the full tool list.
14+
"""
15+
16+
from BaseAgent import BaseAgent
17+
from BaseAgent.resources import DataLakeItem, Library
18+
19+
# ---------------------------------------------------------------------------
20+
# 1. Register data sources and libraries
21+
# ---------------------------------------------------------------------------
22+
agent = BaseAgent()
23+
24+
agent.resource_manager.add_data_item(
25+
DataLakeItem(
26+
filename="my_dataset.csv",
27+
description="Custom dataset for protein analysis",
28+
format="csv",
29+
category="research",
30+
path="/path/to/my_dataset.csv",
31+
)
32+
)
33+
34+
agent.resource_manager.add_data_item(
35+
DataLakeItem(
36+
filename="experiment_results.parquet",
37+
description="Results from experiment batch #42",
38+
format="parquet",
39+
category="experiments",
40+
size_mb=125.5,
41+
path="/path/to/experiment_results.parquet",
42+
)
43+
)
44+
45+
agent.resource_manager.add_library(
46+
Library(
47+
name="custom_analysis_lib",
48+
description="Custom library for advanced protein analysis",
49+
type="Python",
50+
version="2.1.0",
51+
category="analysis",
52+
installation_cmd="pip install custom-analysis-lib",
53+
)
54+
)
55+
56+
# Query the registered resources
57+
print("=== Available Data Sources ===")
58+
for data in agent.resource_manager.get_all_data():
59+
print(f"- {data.filename}: {data.description}")
60+
61+
print("\n=== Python Libraries ===")
62+
for lib in agent.resource_manager.filter_libraries_by_type("Python")[:5]:
63+
print(f"- {lib.name} ({lib.version}): {lib.description}")
64+
65+
summary = agent.resource_manager.get_summary()
66+
print(f"\n=== Resource Summary ===")
67+
print(f"Tools: {summary['tools']['total']}")
68+
print(f"Data Sources: {summary['data']['total']}")
69+
print(f"Libraries: {summary['libraries']['total']}")
70+
71+
_, result = agent.run("Analyse my_dataset.csv using custom_analysis_lib")
72+
print(f"\n=== Agent Result ===\n{result}")
73+
74+
# ---------------------------------------------------------------------------
75+
# 2. Automatic tool selection (tool retriever)
76+
# ---------------------------------------------------------------------------
77+
# With use_tool_retriever=True the agent ranks tools by semantic similarity
78+
# to the task and passes only the top matches to the LLM — useful when the
79+
# full tool list is large.
80+
retriever_agent = BaseAgent(
81+
llm="claude-sonnet-4-20250514",
82+
use_tool_retriever=True,
83+
)
84+
85+
_, result = retriever_agent.run(
86+
"Analyze protein sequences and calculate binding affinities."
87+
)
88+
print(result)
89+
90+
# You can also pin a specific tool subset for a single run.
91+
retriever_agent.resource_manager.select_tools_by_names(["run_python_repl"])
92+
_, result = retriever_agent.run("Run a quick Python calculation.")
93+
print(result)

examples/06_tool_retrieval.py

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
Single skill: full body always injected into the system prompt.
1616
Multiple skills: catalog mode (name + description only) shown initially;
1717
the retrieve node selects relevant skills per task and injects full bodies.
18+
19+
Run this script from the repo root::
20+
21+
python examples/07_skills.py
1822
"""
1923

2024
from BaseAgent import BaseAgent, Skill
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
After agent.run() returns, check agent.is_interrupted:
1111
True → a code block is waiting for review; call resume() or reject(feedback)
1212
False → the agent finished normally; the second return value is the final answer
13+
14+
Run this script from the repo root::
15+
16+
python examples/08_human_in_the_loop.py
1317
"""
1418

1519
from BaseAgent import BaseAgent
@@ -55,4 +59,3 @@
5559
print("Final answer:", answer)
5660
else:
5761
print("Final answer:", payload2)
58-

examples/09_async_and_streaming.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
"""Example 9: Async API and streaming events.
2+
3+
Which method to use
4+
-------------------
5+
arun() — async equivalent of run(); returns (log, content) when the
6+
agent finishes. Use inside async orchestrators, web servers,
7+
or when running multiple agents concurrently with asyncio.gather().
8+
run_stream() — async generator that yields AgentEvent objects *during*
9+
execution. Use when you need real-time visibility into
10+
reasoning, code execution, and errors (e.g. feeding a UI or
11+
collecting a fine-grained trace).
12+
13+
Both require an async context (async def / asyncio.run()).
14+
15+
Run this script from the repo root::
16+
17+
python examples/09_async_and_streaming.py
18+
"""
19+
20+
from __future__ import annotations
21+
22+
import asyncio
23+
24+
from BaseAgent import BaseAgent, EventType
25+
26+
27+
# ===========================================================================
28+
# Part A — arun(), aresume(), areject()
29+
# ===========================================================================
30+
31+
async def basic_async_run():
32+
"""arun() returns (log, content) just like run()."""
33+
agent = BaseAgent(llm="claude-sonnet-4-20250514")
34+
log, answer = await agent.arun("What is 2 + 2?")
35+
print("Answer:", answer)
36+
print(f"Log entries: {len(log)}")
37+
38+
39+
async def async_hitl():
40+
"""HITL workflow using arun() / aresume() / areject()."""
41+
agent = BaseAgent(
42+
llm="claude-sonnet-4-20250514",
43+
require_approval="always",
44+
)
45+
46+
_, payload = await agent.arun("Compute the sum of 1 through 10 in Python.")
47+
48+
if agent.is_interrupted:
49+
print("Code pending approval:")
50+
if isinstance(payload, dict):
51+
print(payload.get("code", ""))
52+
53+
# --- Option A: approve ---
54+
_, answer = await agent.aresume()
55+
print("Approved. Final answer:", answer)
56+
57+
# --- Option B: reject with feedback (commented out) ---
58+
# _, payload2 = await agent.areject("Use a list comprehension instead.")
59+
# if not agent.is_interrupted:
60+
# print("After feedback:", payload2)
61+
else:
62+
print("Completed without interruption:", payload)
63+
64+
65+
async def concurrent_agents():
66+
"""Run two independent agents concurrently with asyncio.gather()."""
67+
agent_a = BaseAgent(llm="claude-sonnet-4-20250514")
68+
agent_b = BaseAgent(llm="claude-sonnet-4-20250514")
69+
70+
(_, ans_a), (_, ans_b) = await asyncio.gather(
71+
agent_a.arun("What is the capital of France?"),
72+
agent_b.arun("What is the capital of Germany?"),
73+
)
74+
print("Agent A:", ans_a)
75+
print("Agent B:", ans_b)
76+
77+
78+
# ===========================================================================
79+
# Part B — run_stream() and AgentEvent
80+
# ===========================================================================
81+
82+
async def stream_all_events():
83+
"""Print every event emitted during a run."""
84+
agent = BaseAgent(llm="claude-sonnet-4-20250514", require_approval="never")
85+
86+
print("=== All events ===")
87+
async for event in agent.run_stream("What is the GC content of the sequence ATCGATCG?"):
88+
print(f"[{event.event_type.value:20s}] {event.content[:120]}")
89+
90+
91+
async def stream_filtered_events():
92+
"""Receive only THINKING and FINAL_ANSWER events."""
93+
agent = BaseAgent(llm="claude-sonnet-4-20250514", require_approval="never")
94+
95+
print("\n=== Filtered: THINKING + FINAL_ANSWER only ===")
96+
async for event in agent.run_stream(
97+
"Summarise the role of BRCA1 in DNA repair.",
98+
event_types={EventType.THINKING, EventType.FINAL_ANSWER},
99+
):
100+
label = "Reasoning" if event.event_type == EventType.THINKING else "Answer"
101+
print(f"[{label}] {event.content[:200]}")
102+
103+
104+
async def stream_to_json():
105+
"""Serialise each event to JSON (useful for WebSocket / SSE payloads)."""
106+
agent = BaseAgent(llm="claude-sonnet-4-20250514", require_approval="never")
107+
108+
print("\n=== JSON payloads ===")
109+
async for event in agent.run_stream(
110+
"Name three model organisms used in genetics research.",
111+
event_types={EventType.FINAL_ANSWER},
112+
):
113+
print(event.to_json())
114+
115+
116+
if __name__ == "__main__":
117+
print("=== Basic async run ===")
118+
asyncio.run(basic_async_run())
119+
120+
print("\n=== Async HITL ===")
121+
asyncio.run(async_hitl())
122+
123+
print("\n=== Concurrent agents ===")
124+
asyncio.run(concurrent_agents())
125+
126+
print("\n=== Streaming: all events ===")
127+
asyncio.run(stream_all_events())
128+
129+
asyncio.run(stream_filtered_events())
130+
asyncio.run(stream_to_json())

0 commit comments

Comments
 (0)