-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
🚀 Describe the new functionality needed
Many other agentic frameworks make it easy to define tools by using decorators on a function. In looking at the existing mechanism for defining custom tools for local execution in a client, there is a lot of boilerplate code that would be repeated over and over again when you have a large number of tools.
For example, from the stack-apps repo:
class TickerDataTool(SingleMessageClientTool):
"""Tool to get finance data using yfinance apis"""
def get_name(self) -> str:
return "get_ticker_data"
def get_description(self) -> str:
return "Get yearly closing prices for a given ticker symbol"
def get_params_definition(self) -> Dict[str, Parameter]:
return {
"ticker_symbol": Parameter(
name="ticker_symbol",
parameter_type="str",
description="The ticker symbol for which to get the data. eg. '^GSPC'",
required=True,
),
"start": Parameter(
name="start",
parameter_type="str",
description="Start date, eg. '2021-01-01'",
required=True,
),
"end": Parameter(
name="end",
parameter_type="str",
description="End date, eg. '2024-12-31'",
required=True,
),
}
def run_impl(self, ticker_symbol: str, start: str, end: str):
data = yf.download(ticker_symbol, start=start, end=end)
data["Year"] = data.index.year
annual_close = data.groupby("Year")["Close"].last().reset_index()
annual_close_json = annual_close.to_json(orient="records", date_format="iso")
return annual_close_jsonComparing to something like Pydantic:
@routing_agent.tool
async def knowledge_tool(ctx: RunContext[str], original_query: str) -> str:
"""A tool for answering general OpenShift and Kubernetes knowledge
questions. Use for obtaining how-to, documentation, and similar answers.
Args:
original_query: the question to get an answer for
"""
logger.debug(ctx)
r = await knowledge_agent.run(original_query, usage=ctx.usage)
# pprint(r.all_messages)
return r.dataThere is a lot of prior art (codebase) from other frameworks for how to implement decorations like this, which make it trivial to define custom tools.
💡 Why is this needed? What if we don't build it?
Not having a decoration mechanism for more trivial tool definition use cases makes llama-stack much harder to use and requires a lot more boilerplate code to be re-used, which increases codebase sizes and also means that any future vulnerabilities that might be found would require a lot more touchpoints to fix.
Other thoughts
#234 is somewhat related, but not entirely.