Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions bindings/python/examples/tool_calls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import asyncio
from typing import Annotated

from pydantic import BaseModel

from uzu import (
ChatConfig,
ChatMessage,
ChatReplyConfig,
Engine,
EngineConfig,
SamplingMethod,
SamplingPolicy,
uzu_tool_function,
)


class Coordinate(BaseModel):
"""A geographic coordinate."""

latitude: Annotated[float, "Latitude in decimal degrees."]
longitude: Annotated[float, "Longitude in decimal degrees."]


@uzu_tool_function(
name="get_location",
description="Return the current location in coordinates"
)
def get_current_location() -> Coordinate:
return Coordinate(latitude=51.5074, longitude=-0.1278)


@uzu_tool_function
def get_current_temperature(
latitude: Annotated[float, "Latitude in decimal degrees."],
longitude: Annotated[float, "Longitude in decimal degrees."],
) -> float:
"""Return the temperature at the provided coordinates."""
_ = latitude, longitude
return 25.0


async def main() -> None:
engine = await Engine.create(EngineConfig.create())
model = await engine.model("mlx-community/Qwen3.5-9B-MLX-8bit")
if model is None:
raise RuntimeError("Model not found")

async for update in (await engine.download(model)).iterator():
print(f"Download progress: {update.progress}")

session = await engine.chat(model, ChatConfig.create())
await session.add_tool(get_current_location)
await session.add_tool(get_current_temperature)

messages = [
ChatMessage.system().with_text("You are a helpful assistant"),
ChatMessage.user().with_text("What temperature is it now at my location?"),
]
config = ChatReplyConfig.create().with_sampling_policy(
SamplingPolicy.Custom(method=SamplingMethod.Greedy())
)
replies = await session.reply(messages, config)
if replies:
message = replies[-1].message
print(f"Reasoning: {message.reasoning or ''}")
print(f"Text: {message.text or ''}")


if __name__ == "__main__":
asyncio.run(main())
2 changes: 1 addition & 1 deletion bindings/python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ classifiers = [
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
dynamic = ["version"]
dependencies = ["pydantic>=2.13.3"]

[project.urls]
Homepage = "https://trymirai.com"
Expand All @@ -35,7 +36,6 @@ Issues = "https://github.com/trymirai/uzu/issues"

[project.optional-dependencies]
dev = ["pytest>=8.3.4", "ruff>=0.14.0"]
examples = ["pydantic>=2.13.3"]

[tool.maturin]
features = ["bindings-pyo3"]
Expand Down
1 change: 1 addition & 0 deletions bindings/python/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading
Loading