Passing Functions as Tools#321
Conversation
6f8cd93 to
93c7a63
Compare
ab402d3 to
7148520
Compare
4e8bd4b to
4fcdf70
Compare
4fcdf70 to
8ec5123
Compare
|
|
23548ce to
1f089f7
Compare
efd3ee9 to
e7bb55f
Compare
65db34a to
ed3ba8a
Compare
| # Test missing required fields | ||
| incomplete_tool = { | ||
| 'type': 'function', | ||
| 'function': {'name': 'test'}, # missing description and parameters |
There was a problem hiding this comment.
So in the previous behavior - no.
But since the last Pydantic PR you have to provide Parameters. Tested out both the OpenAI Python SDK with Ollama and the current published version of ollama-python. I think it might be worthwhile to have the Tool class have optional on all params to make sure it is backwards compatible.
Seems like function calling still works with not a fully-fledged JSON (I'm sure it's flakey but not our job).
Proposed Tool def'n:
class Tool(SubscriptableBaseModel):
type: Optional[Literal['function']] = 'function'
class Function(SubscriptableBaseModel):
name: Optional[str] = None
description: Optional[str] = None
class Parameters(SubscriptableBaseModel):
type: Optional[Literal['object']] = 'object'
required: Optional[Sequence[str]] = None
class Property(SubscriptableBaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
type: Optional[str] = None
description: Optional[str] = None
properties: Optional[Mapping[str, Property]] = None
parameters: Optional[Parameters] = None
function: Optional[Function] = Nonee8a4950 to
6d9c156
Compare
3a994b2 to
c5c61a3
Compare
| # 1. A parenthetical expression like (integer) - captured in group 1 | ||
| # 2. A colon : | ||
| # Followed by optional whitespace. Only split on first occurrence. | ||
| parts = re.split(r'(?:\(([^)]*)\)|:)\s*', line, maxsplit=1) |
There was a problem hiding this comment.
I tend to avoid regexp when possible since it's hard to grok. In this scenario, a simpler solution would be to split on the mandatory : than parse the pre-colon and post-colon sections independently. Here's an example that passes your tests
for line in parsed_docstring['args'].splitlines():
pre, _, post = line.partition(':')
if not pre.strip():
continue
if not post.strip() and last_key:
parsed_docstring[last_key] += ' ' + pre
continue
arg_name, _, _ = pre.replace('(', ' ').partition(' ')
last_key = arg_name.strip()
parsed_docstring[last_key] = post.strip()| types = {t.get('type', 'string') for t in v.get('anyOf')} if 'anyOf' in v else {v.get('type', 'string')} | ||
| if 'null' in types: | ||
| schema['required'].remove(k) | ||
| types.discard('null') |
There was a problem hiding this comment.
If null is the only type (for some reason), this will be an empty string
There was a problem hiding this comment.
I think this is okay, IMO something like:
def (a:None, b:type(None)):
...is extremely unlikely
* Fix image serialization
|
I found that the ollama-Python/examples/tools.py script cannot specify an IP address. |
Features:
.chat(tools=[python_func,...])🥳Examples to come on follow up for both Pydantic and Functions as Tools