Copy
Ask AI
import asyncio
import json
from dedalus_labs import AsyncDedalus, DedalusRunner
from dedalus_labs.utils.streaming import stream_async
from dotenv import load_dotenv
from dedalus_labs.utils.streaming import stream_async
load_dotenv()
def on_tool(evt: dict) -> None:
print("[policy tool evt]", json.dumps(evt))
def calculate_ship_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
"""Calculate nautical distance between two coordinates."""
print(f"[tool:calculate_distance] from ({lat1}, {lon1}) to ({lat2}, {lon2})")
# Simplified distance calculation
lat_diff = abs(lat2 - lat1)
lon_diff = abs(lon2 - lon1)
distance = ((lat_diff ** 2 + lon_diff ** 2) ** 0.5) * 60 # Rough nautical miles
return round(distance, 2)
def estimate_sailing_time(distance: float, wind_speed: int = 15) -> dict:
"""Estimate sailing time based on distance and wind conditions."""
print(f"[tool:estimate_time] distance={distance} nautical miles, wind={wind_speed} knots")
# Assume average sailing speed based on wind
if wind_speed < 10:
sailing_speed = 4 # knots
conditions = "light winds"
elif wind_speed < 20:
sailing_speed = 7 # knots
conditions = "moderate winds"
else:
sailing_speed = 10 # knots
conditions = "strong winds"
hours = distance / sailing_speed
days = hours / 24
return {
"hours": round(hours, 1),
"days": round(days, 1),
"conditions": conditions,
"sailing_speed": sailing_speed
}
def check_treasure_coordinates(lat: float, lon: float) -> str:
"""Check if coordinates match any famous treasure locations."""
print(f"[tool:check_treasure] checking ({lat}, {lon})")
famous_locations = {
(25.7, -80.3): "Near the Florida Keys - known pirate waters!",
(18.2, -77.3): "Jamaica - Port Royal, the old pirate haven!",
(12.1, -68.9): "Aruba - Caribbean treasure waters!",
(32.3, -64.7): "Bermuda - mysterious triangle territory!"
}
# Check if close to any famous location
for (treasure_lat, treasure_lon), description in famous_locations.items():
if abs(lat - treasure_lat) < 2 and abs(lon - treasure_lon) < 2:
return description
return "Open seas - chart yer own course, matey!"
def policy(ctx: dict) -> dict:
step = ctx.get("step", 1)
print(f"[policy] step={step}")
pol: dict = {}
if step == 3:
pol.update({"message_prepend": [{"role": "system", "content": "You must speak like a pirate."}]})
# Cap total steps for safety
pol.setdefault("max_steps", 4)
return pol
async def main() -> None:
client = AsyncDedalus()
runner = DedalusRunner(client)
prompt = (
"Step 1) Calculate the sailing distance from Miami (25.7617, -80.1918) to Nassau, Bahamas (25.0443, -77.3504). "
"Step 2) Estimate how long it would take to sail there with 18-knot winds. "
"Step 3) Check if Nassau coordinates are near any famous treasure locations and search for historical pirate activity in the Bahamas. "
)
result = runner.run(
input=prompt,
model="openai/gpt-5",
tools=[calculate_ship_distance, estimate_sailing_time, check_treasure_coordinates],
mcp_servers=["tsion/brave-search-mcp"],
stream=True,
on_tool_event=on_tool,
policy=policy
)
await stream_async(result)
if __name__ == "__main__":
asyncio.run(main())