def __init__(self, signature, tools: list[Callable], max_iters=5):
"""
`tools` is either a list of functions, callable classes, or `dspy.Tool` instances.
"""
self.signature = signature = ensure_signature(signature)
self.max_iters = max_iters
tools = [t if isinstance(t, Tool) else Tool(t) for t in tools]
tools = {tool.name: tool for tool in tools}
inputs = ", ".join([f"`{k}`" for k in signature.input_fields.keys()])
outputs = ", ".join([f"`{k}`" for k in signature.output_fields.keys()])
instr = [f"{signature.instructions}\n"] if signature.instructions else []
instr.extend(
[
f"You will be given {inputs} and your goal is to finish with {outputs}.\n",
"To do this, you will interleave Thought, Tool Name, and Tool Args, and receive a resulting Observation.\n",
"Thought can reason about the current situation, and Tool Name can be the following types:\n",
]
)
finish_desc = (
f"Signals that the final outputs, i.e. {outputs}, are now available and marks the task as complete."
)
finish_args = {} # k: v.annotation for k, v in signature.output_fields.items()}
tools["finish"] = Tool(
func=lambda **kwargs: "Completed.",
name="finish",
desc=finish_desc,
args=finish_args,
)
for idx, tool in enumerate(tools.values()):
args = getattr(tool, "args")
desc = (f", whose description is <desc>{tool.desc}</desc>." if tool.desc else ".").replace("\n", " ")
desc += f" It takes arguments {args} in JSON format."
instr.append(f"({idx+1}) {tool.name}{desc}")
react_signature = (
dspy.Signature({**signature.input_fields}, "\n".join(instr))
.append("trajectory", dspy.InputField(), type_=str)
.append("next_thought", dspy.OutputField(), type_=str)
.append("next_tool_name", dspy.OutputField(), type_=Literal[tuple(tools.keys())])
.append("next_tool_args", dspy.OutputField(), type_=dict[str, Any])
)
fallback_signature = dspy.Signature(
{**signature.input_fields, **signature.output_fields},
signature.instructions,
).append("trajectory", dspy.InputField(), type_=str)
self.tools = tools
self.react = dspy.Predict(react_signature)
self.extract = dspy.ChainOfThought(fallback_signature)