Skip to content

Commit

Permalink
Merge pull request #722 from Mirascope/add-partial-tool-streaming-docs
Browse files Browse the repository at this point in the history
docs: streaming partial tools with examples
  • Loading branch information
willbakst authored Nov 28, 2024
2 parents 78ec14a + d4daee1 commit d8c9381
Show file tree
Hide file tree
Showing 84 changed files with 2,963 additions and 0 deletions.
28 changes: 28 additions & 0 deletions docs/learn/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,34 @@ Mirascope supports streaming responses with tools, which is useful for long-runn

If you think we're missing any, let us know!

### Streaming Partial Tools

You can also stream intermediate partial tools and their deltas (rather than just the fully constructed tool) by setting `stream={"partial_tools": True}`:

!!! mira ""

{% for tool_method, tool_method_title in tool_methods %}
=== "{{ tool_method_title }}"

{% for method, method_title in zip(prompt_writing_methods, prompt_writing_method_titles) %}
=== "{{ method_title }}"

{% for provider in supported_llm_providers %}
=== "{{ provider }}"

{% if tool_method == "function" %}
```python hl_lines="21 30"
{% else %}
```python hl_lines="22 31"
{% endif %}
--8<-- "examples/learn/tools/partial_tool_streams/{{ provider | provider_dir }}/{{ tool_method }}/{{ method }}.py"
```
{% endfor %}

{% endfor %}

{% endfor %}

## Tool Message Parameters

!!! mira ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from mirascope.core import BaseMessageParam, BaseTool, anthropic
from pydantic import Field


class GetBookAuthor(BaseTool):
"""Returns the author of the book with the given title."""

title: str = Field(..., description="The title of the book.")

def call(self) -> str:
if self.title == "The Name of the Wind":
return "Patrick Rothfuss"
elif self.title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[GetBookAuthor],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> list[BaseMessageParam]:
return [BaseMessageParam(role="user", content=f"Who wrote {books}?")]


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from mirascope.core import BaseTool, Messages, anthropic
from pydantic import Field


class GetBookAuthor(BaseTool):
"""Returns the author of the book with the given title."""

title: str = Field(..., description="The title of the book.")

def call(self) -> str:
if self.title == "The Name of the Wind":
return "Patrick Rothfuss"
elif self.title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[GetBookAuthor],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> Messages.Type:
return Messages.User(f"Who wrote {books}?")


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from mirascope.core import BaseTool, anthropic
from pydantic import Field


class GetBookAuthor(BaseTool):
"""Returns the author of the book with the given title."""

title: str = Field(..., description="The title of the book.")

def call(self) -> str:
if self.title == "The Name of the Wind":
return "Patrick Rothfuss"
elif self.title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[GetBookAuthor],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> str:
return f"Who wrote {books}?"


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from mirascope.core import BaseTool, anthropic, prompt_template
from pydantic import Field


class GetBookAuthor(BaseTool):
"""Returns the author of the book with the given title."""

title: str = Field(..., description="The title of the book.")

def call(self) -> str:
if self.title == "The Name of the Wind":
return "Patrick Rothfuss"
elif self.title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[GetBookAuthor],
stream={"partial_tools": True},
)
@prompt_template("Who wrote {book}?")
def identify_authors(books: list[str]): ...


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from mirascope.core import BaseMessageParam, anthropic


def get_book_author(title: str) -> str:
"""Returns the author of the book with the given title
Args:
title: The title of the book.
"""
if title == "The Name of the Wind":
return "Patrick Rothfuss"
elif title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[get_book_author],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> list[BaseMessageParam]:
return [BaseMessageParam(role="user", content=f"Who wrote {books}?")]


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from mirascope.core import Messages, anthropic


def get_book_author(title: str) -> str:
"""Returns the author of the book with the given title
Args:
title: The title of the book.
"""
if title == "The Name of the Wind":
return "Patrick Rothfuss"
elif title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[get_book_author],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> Messages.Type:
return Messages.User(f"Who wrote {books}?")


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from mirascope.core import anthropic


def get_book_author(title: str) -> str:
"""Returns the author of the book with the given title
Args:
title: The title of the book.
"""
if title == "The Name of the Wind":
return "Patrick Rothfuss"
elif title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[get_book_author],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> str:
return f"Who wrote {books}?"


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from mirascope.core import anthropic, prompt_template


def get_book_author(title: str) -> str:
"""Returns the author of the book with the given title
Args:
title: The title of the book.
"""
if title == "The Name of the Wind":
return "Patrick Rothfuss"
elif title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@anthropic.call(
"claude-3-5-sonnet-20240620",
tools=[get_book_author],
stream={"partial_tools": True},
)
@prompt_template("Who wrote {book}?")
def identify_authors(books: list[str]): ...


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from mirascope.core import BaseMessageParam, BaseTool, azure
from pydantic import Field


class GetBookAuthor(BaseTool):
"""Returns the author of the book with the given title."""

title: str = Field(..., description="The title of the book.")

def call(self) -> str:
if self.title == "The Name of the Wind":
return "Patrick Rothfuss"
elif self.title == "Mistborn: The Final Empire":
return "Brandon Sanderson"
else:
return "Unknown"


@azure.call(
"gpt-4o-mini",
tools=[GetBookAuthor],
stream={"partial_tools": True},
)
def identify_authors(books: list[str]) -> list[BaseMessageParam]:
return [BaseMessageParam(role="user", content=f"Who wrote {books}?")]


stream = identify_authors(["The Name of the Wind", "Mistborn: The Final Empire"])
for chunk, tool in stream:
if tool:
if tool.delta is not None: # partial tool
print(tool.delta)
else:
print(tool.call())
else:
print(chunk.content, end="", flush=True)
Loading

0 comments on commit d8c9381

Please sign in to comment.