Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tool docstring cannot be longer than 1024 characters in v1 but can be longer in v0 #772

Closed
off6atomic opened this issue Jan 18, 2025 · 1 comment · Fixed by #778
Closed
Assignees
Labels
bug Something isn't working mirascope

Comments

@off6atomic
Copy link
Contributor

off6atomic commented Jan 18, 2025

Description

This is the code for Mirascope v0:

from dotenv import load_dotenv
from mirascope.openai import OpenAICall, OpenAICallParams

load_dotenv()


def list_design_option_values_sorted_by_sales_metric(
    design_option: str,
    time_range_start: str,
    time_range_end: str,
    sales_metric: str = "TotalUnitsSold",
    asc: bool = False,
):
    """
    Lists pattern design option values sorted by their sales metric in ascending or descending order.
    Top 5 design option values fetched from the Postgres database will be returned along with
    their sales metric.

    Less than 5 design option values will be returned if there are less than 5 values.
    Do not call this function again with the same arguments if you receive less than 5 values.

    Args:
        design_option: The design option to query. MUST be one of the following values:
            - "shoulderSeam"
            - "necklineStyle"
            - "necklineStyle.crewNeck.crewNeckWidth"
            - "necklineStyle.crewNeck.neckFinish"
            - "productLength"
            - "productLength.hip.level"
            - "frontHem"
            - "frontHem.straight.hemFoldBack"
            - "backHem"
            - "backHem.straight.hemFoldBack"
            - "slitDepth"
            - "pocket"
            - "sleeveLength"
            - "sleeveFabric"
            - "sleeveHem"
            - "sleeveHem.regular.sleeveHemFoldBack"
            - "bodyFit"
            - "shoulderFit"
            - "silhouette"
            - "sleeveFit"
        time_range_start: The start of the time range to filter sales by e.g., "2023-01-01 00:00:00+00".
        time_range_end: The end of the time range to filter sales by e.g., "2024-01-01 00:00:00+00".
        sales_metric: Sales metric to sort by. Can be "UnitsSoldFullPrice", "RevenueFullPrice", "UnitsSoldDiscounted", "RevenueDiscounted", "TotalUnitsSold", or "TotalRevenue". Default is "TotalUnitsSold".
        asc: Whether to sort the results in ascending order. Default is False (descending order).

    Raises:
        ValueError: If invalid design_option or sales_metric is provided.
    """
    print(
        "The values are:",
        design_option,
        time_range_start,
        time_range_end,
        sales_metric,
        asc,
    )


class LLM(OpenAICall):
    prompt: str
    prompt_template = "{prompt}"
    call_params = OpenAICallParams(
        model="gpt-4o",
        tools=[list_design_option_values_sorted_by_sales_metric],
        temperature=0.0,
    )


llm = LLM(prompt="call the list tool with random parameter values. don't ask me anything.")
response = llm.call()
if tool := response.tool:
    print(tool.args)
    tool.call()
else:
    print(response.content)

You will notice that the code runs successfully. Here's the output:

{'design_option': 'necklineStyle', 'time_range_start': '2023-01-01 00:00:00+00', 'time_range_end': '2023-12-31 23:59:59+00', 'sales_metric': 'TotalRevenue', 'asc': True}
The values are: necklineStyle 2023-01-01 00:00:00+00 2023-12-31 23:59:59+00 TotalRevenue True

This is the code for Mirascope v1:

from dotenv import load_dotenv
from mirascope.core import openai

load_dotenv()


def list_design_option_values_sorted_by_sales_metric(
    design_option: str,
    time_range_start: str,
    time_range_end: str,
    sales_metric: str = "TotalUnitsSold",
    asc: bool = False,
):
    """
    Lists pattern design option values sorted by their sales metric in ascending or descending order.
    Top 5 design option values fetched from the Postgres database will be returned along with
    their sales metric.

    Less than 5 design option values will be returned if there are less than 5 values.
    Do not call this function again with the same arguments if you receive less than 5 values.

    Args:
        design_option: The design option to query. MUST be one of the following values:
            - "shoulderSeam"
            - "necklineStyle"
            - "necklineStyle.crewNeck.crewNeckWidth"
            - "necklineStyle.crewNeck.neckFinish"
            - "productLength"
            - "productLength.hip.level"
            - "frontHem"
            - "frontHem.straight.hemFoldBack"
            - "backHem"
            - "backHem.straight.hemFoldBack"
            - "slitDepth"
            - "pocket"
            - "sleeveLength"
            - "sleeveFabric"
            - "sleeveHem"
            - "sleeveHem.regular.sleeveHemFoldBack"
            - "bodyFit"
            - "shoulderFit"
            - "silhouette"
            - "sleeveFit"
        time_range_start: The start of the time range to filter sales by e.g., "2023-01-01 00:00:00+00".
        time_range_end: The end of the time range to filter sales by e.g., "2024-01-01 00:00:00+00".
        sales_metric: Sales metric to sort by. Can be "UnitsSoldFullPrice", "RevenueFullPrice", "UnitsSoldDiscounted", "RevenueDiscounted", "TotalUnitsSold", or "TotalRevenue". Default is "TotalUnitsSold".
        asc: Whether to sort the results in ascending order. Default is False (descending order).

    Raises:
        ValueError: If invalid design_option or sales_metric is provided.
    """
    print(
        "The values are:",
        design_option,
        time_range_start,
        time_range_end,
        sales_metric,
        asc,
    )


@openai.call(
    "gpt-4o",
    tools=[list_design_option_values_sorted_by_sales_metric],
    call_params={"temperature": 0},
)
def llm(prompt: str):
    return prompt


response = llm("call the tool with random parameter values. don't ask me anything.")
if tool := response.tool:
    print(tool.args)
    tool.call()
else:
    print(response.content)

Running the code will result in this error:

openai.BadRequestError: Error code: 400 - {'error': {'message': "Invalid 'tools[0].function.description': string too long. Expected a string with maximum length 1024, but got a string with length 1628 instead.", 'type': 'invalid_request_error', 'param': 'tools[0].function.description', 'code': 'string_above_max_length'}}

Python, Mirascope & OS Versions, related packages (not required)

Requirements for v0:

openai==1.34.0
pydantic==2.7.1
pydantic-core==2.18.2
mirascope==0.18.2

Requirements for v1:

openai==1.59.7
pydantic==2.10.5
pydantic-core==2.27.2
mirascope==1.15.0
@off6atomic off6atomic added the bug Something isn't working label Jan 18, 2025
@willbakst willbakst self-assigned this Jan 21, 2025
willbakst pushed a commit that referenced this issue Jan 24, 2025
@willbakst willbakst mentioned this issue Jan 24, 2025
@willbakst
Copy link
Contributor

The 1024 limit is imposed by OpenAI. The reason this worked in v0 and doesn't work in v1 is that in v0 we only used the short/long description and dropped everything else (but in v1 we just use the original docstring).

I've implemented a fix for this that drops args/examples from the tool description so that they don't count against that limit.

The fix is released in v1.16.1!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mirascope
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants