Skip to content

Commit

Permalink
Merge pull request #5 from vatsalsaglani/develop
Browse files Browse the repository at this point in the history
Readme and version updates along with print removal
  • Loading branch information
vatsalsaglani authored Mar 9, 2024
2 parents 46cd878 + f5bcdcf commit 483872d
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ jobs:
python setup.py sdist bdist_wheel
twine check dist/*
- name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
uses: pypa/gh-action-pypi-publish@release/v2
with:
password: ${{ secrets.PYPI_API_TOKEN }}
184 changes: 183 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
@@ -1 +1,183 @@
# Claudetools
# Claudetools

**Claudetools** is a Python library that provides a convenient way to use Claude 3 family's structured data generation capabilities for function calling. The function calling capabilities are similar to ones available with OpenAI models.

With `claudetools` one can now use any model from the **Claude 3** family of models for function calling.

## Key Features

- **Function Calling**: Define and call custom functions within your prompts, leveraging the advanced capabilities of Claude 3 models.
- **Synchronous and Asynchronous Clients**: Choose between synchronous or asynchronous interaction modes depending on your use case.
- **Flexible Tool Definition**: Specify function names, descriptions, and parameters using the Pydantic library for type safety and validation.
- **Multiple Tools Support**: Opt to call multiple tools within a single prompt, enabling more complex interactions.
- **Customizable System Prompts**: Attach custom system prompts to your conversations for better context and control.


## Installation

You can install `claudetools` from PyPI or directly from the source:

### From PyPi

```bash
pip install caludetools
```

### Install from source

```bash
pip install git+https://github.com/vatsalsaglani/claudetools
```

## Usage

Here's a basic example of how to use `claudetools` for function calling with the Claude 3 model:

```py
import asyncio
from claudetools.tools.tool import Tool
from pydantic import BaseModel, Field
from typing import List, Dict
import json

# create a tool instance with your Anthropic API Key
tool = Tool(ANTHROPIC_API_KEY)

# define your function parameters
class AddTodo(BaseModel):
text: str = Field(..., description="Text to add for the TODO to remember.")

class MarkCompleted(BaseModel):
text: str = Field(..., description="Text of the completed TODO.")


class ReOpen(BaseModel):
text: str = Field(..., description="Text of the TODO to reopen.")


# specify the functions you want to use
functions = [{
"name": "AddTodo",
"description": "Add a TODO with text to remember.",
"parameters": AddTodo.model_json_schema()
}, {
"name": "MarkCompleted",
"description": "Get text of the todo mark it complete",
"parameters": MarkCompleted.model_json_schema()
}, {
"name": "ReOpen",
"description": "Get text of the todo reopen it.",
"parameters": ReOpen.model_json_schema()
}]

# set up the user messages
user_messages = [{
"role":
"user",
"content":
"""I have to pick up my daughter from school. After which I've to do the laundary. And now I need to cook lunch."""
}]

# dependency prompt to attach to the main system prompt
DEPENDENCY_PROMPT = """You are a helpful assistant that helps a user with their tasks and todos. The user can add a todos, mark todos as completed, or reopen certain todos.
The user can provide multiple actions at once so you've to break those down and call the appropriate functions in the correct sequence."""


# call the tool with the required parameters
output = tool(model="claude-3-sonnet-20240229",
messages=user_messages,
tools=functions,
tool_choice=None,
multiple_tools=True,
attach_system=DEPENDENCY_PROMPT,
max_tokens=3000)

if output:
print(json.dumps(output, indent=4))
else:
print("Unable to find a function!")
```

> No default value of `max_tokens` is assumed hence, please provide `max_tokens` to avoid getting an error from the Claude APIs.
_The parameter explanation is provided below._

- `model`: The name of the model from the Claude 3 family.
- `messages`: Messages transferred between the user and the assistant.
- `tools`: Set of function specification to use.
- `tool_choice`: User a particular function. By default the value is `None`. The model will figure out the function to call and provide the related parameters. If a specific function needs to be called provide `{"name": "function name"}` in the `tool_choice` argument.
- `multiple_tools`: Defaults to `False`. Can be set to `True` to get multiple function calls.
- `attach_system`: Defaults to `None`. Can also accept string which will be attached as part of the system prompt.
- `max_tokens`: As mentioned above, no default value of `max_tokens` is assumed. Hence, please provide `max_tokens` to avoid getting an error.


### Asynchronous Interaction

Just import `AsyncTool` instead of `Tool` to and use `await` with each call.

```py
import asyncio
from claudetools.tools.tool import AsyncTool
from pydantic import BaseModel, Field
from typing import List, Dict
import json

tool = AsyncTool(ANTHROPIC_API_KEY)

class AddTodo(BaseModel):
text: str = Field(..., description="Text to add for the TODO to remember.")


functions = [{
"name": "AddTodo",
"description": "Add a TODO with text to remember.",
"parameters": AddTodo.model_json_schema()
}, {
"name": "MarkCompleted",
"description": "Get text of the todo mark it complete",
"parameters": MarkCompleted.model_json_schema()
}, {
"name": "ReOpen",
"description": "Get text of the todo reopen it.",
"parameters": ReOpen.model_json_schema()
}]

user_messages = [{
"role":
"user",
"content":
"""I have to pick up my daughter from school. After which I've to do the laundary. And now I need to cook lunch."""
}]

async def main():

output = await tool(model="claude-3-sonnet-20240229",
messages=user_messages,
tools=functions,
tool_choice=None,
multiple_tools=True,
attach_system=None,
max_tokens=3000)
if output:
print(json.dumps(output, indent=4))
else:
print("Unable to find a function!")

if __name__ == "__main__":
asyncio.run(main())
```

## Requirements

Python 3.7 or higher.

## TODOs

- [ ] Add examples notebook.
- [ ] Enable logging.
- [ ] Add support for AWS Bedrock.
- [ ] Validate outputs in `tool_choice`.

## Contributing

Contributions to `claudetools` are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on this GitHub repository.
2 changes: 1 addition & 1 deletion claudetools/completion/async_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ async def __call__(self, model: str, messages: List[Dict], **kwargs):
headers=self.headers)
response.raise_for_status()
output = response.json()
print("MODEL OUTPUT\n", output)
# print("MODEL OUTPUT\n", output)
return output.get("content")[0].get("text")
2 changes: 1 addition & 1 deletion claudetools/completion/complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ def __call__(self, model: str, messages: List[Dict], **kwargs):
output = self.client.messages.create(model=model,
messages=messages,
**kwargs)
print("MODEL OUTPUT\n", output)
# print("MODEL OUTPUT\n", output)
return output.content[0].text
2 changes: 1 addition & 1 deletion claudetools/tools/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async def tool_call(self,
if tool_choice:
ToolChoice.model_validate(tool_choice)
tool_name = tool_choice.get("name")
print(tool_choice, type(tool_choice))
# print(tool_choice, type(tool_choice))
system = SINGLE_FUNCTION_SPECIFIC_CALL.format(
functions=tools, function_name=tool_name)
else:
Expand Down
7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

setup(
name="claudetools",
version="0.2.0",
version="0.4.0",
author="Vatsal J. Saglani",
author_email="[email protected]",
description="Function calling using the Claude 3 family.",
description=
"Claudetools is a Python library that enables function calling with the Claude 3 family of language models from Anthropic.",
long_description=open("Readme.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/vatsalsaglani/claudetools",
packages=find_packages(),
install_requires=["httpx==0.25.0", "anthropic==0.19.1", "pydantic==2.4.2"],
python_requires=">=3.9")
python_requires=">=3.7")

0 comments on commit 483872d

Please sign in to comment.