From 35bd41d7a6734695c64c919089ca26d02317b5e9 Mon Sep 17 00:00:00 2001 From: Sarmad Qadri Date: Wed, 3 Jan 2024 19:46:50 -0500 Subject: [PATCH] [Cookbook] Simple Function calling example with Mixtral-8x7B Along with some fixes to function calling using OpenAI and Anyscale modelparsers --- .../Function_Calling_with_Mixtral.ipynb | 485 ++++++++++++++++++ cookbooks/Anyscale/README.md | 1 + cookbooks/Anyscale/recommender.aiconfig.json | 91 ++++ cookbooks/Anyscale/updated.aiconfig.json | 116 +++++ .../default_parsers/anyscale_endpoint.py | 31 +- python/src/aiconfig/default_parsers/openai.py | 37 +- python/src/aiconfig/schema.py | 8 +- 7 files changed, 732 insertions(+), 37 deletions(-) create mode 100644 cookbooks/Anyscale/Function_Calling_with_Mixtral.ipynb create mode 100644 cookbooks/Anyscale/recommender.aiconfig.json create mode 100644 cookbooks/Anyscale/updated.aiconfig.json diff --git a/cookbooks/Anyscale/Function_Calling_with_Mixtral.ipynb b/cookbooks/Anyscale/Function_Calling_with_Mixtral.ipynb new file mode 100644 index 000000000..11c27cb4c --- /dev/null +++ b/cookbooks/Anyscale/Function_Calling_with_Mixtral.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "_KIVLBz840Bi" + }, + "source": [ + "# Function Calling with Anyscale Endpoints & AIConfig\n", + "\n", + "This notebook serves as a practical guide for leveraging AIConfig and function calling with Anyscale Endpoints. We start with a mock database of books and functions to list, search, and retrieve books. Function calling is enabled so the LLM can interpret a user's question, determine the appropriate function to call, and execute the function. \n", + "\n", + "This guide shows how to achieve the [OpenAI function calling demo](https://github.com/openai/openai-node/blob/v4/examples/function-call-stream.ts) using Anyscale Endpoints instead (and using Mixtral-8x7B instead of GPT-4).\n", + "\n", + "Read more about [Function Calling with Anyscale Endpoints](https://docs.endpoints.anyscale.com/guides/function-calling) and [AIConfig for prompt and model management](https://github.com/lastmile-ai/aiconfig)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Install AIConfig package\n", + "%pip install python-aiconfig" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Obtaining file:///Users/saqadri/lm/aiconfig/python\n", + " Installing build dependencies ... \u001b[?25ldone\n", + "\u001b[?25h Checking if build backend supports build_editable ... \u001b[?25ldone\n", + "\u001b[?25h Getting requirements to build editable ... \u001b[?25ldone\n", + "\u001b[?25h Preparing editable metadata (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25hRequirement already satisfied: black in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (23.11.0)\n", + "Requirement already satisfied: flake8 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (6.1.0)\n", + "Requirement already satisfied: flask-cors in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (4.0.0)\n", + "Requirement already satisfied: flask[async] in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (3.0.0)\n", + "Requirement already satisfied: google-generativeai in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.3.2)\n", + "Requirement already satisfied: huggingface-hub in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.20.1)\n", + "Requirement already satisfied: hypothesis==6.91.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (6.91.0)\n", + "Requirement already satisfied: lastmile-utils==0.0.14 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.0.14)\n", + "Requirement already satisfied: mock in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (5.1.0)\n", + "Requirement already satisfied: nest-asyncio in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (1.5.8)\n", + "Requirement already satisfied: nltk in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (3.8.1)\n", + "Requirement already satisfied: openai<1.5,>=1.0.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (1.4.0)\n", + "Requirement already satisfied: prompt-toolkit in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (3.0.42)\n", + "Requirement already satisfied: pybars3 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.9.7)\n", + "Requirement already satisfied: pydantic>=2.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (2.4.2)\n", + "Requirement already satisfied: pylint in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (3.0.2)\n", + "Requirement already satisfied: pytest in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (7.4.3)\n", + "Requirement already satisfied: pytest-asyncio in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.23.3)\n", + "Requirement already satisfied: python-dotenv in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (1.0.0)\n", + "Requirement already satisfied: pyyaml in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (6.0.1)\n", + "Requirement already satisfied: requests in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (2.31.0)\n", + "Requirement already satisfied: result in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-aiconfig==1.1.8) (0.15.0)\n", + "Requirement already satisfied: attrs>=19.2.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from hypothesis==6.91.0->python-aiconfig==1.1.8) (23.2.0)\n", + "Requirement already satisfied: sortedcontainers<3.0.0,>=2.1.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from hypothesis==6.91.0->python-aiconfig==1.1.8) (2.4.0)\n", + "Requirement already satisfied: chardet==5.2.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (5.2.0)\n", + "Requirement already satisfied: isort==5.12.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (5.12.0)\n", + "Requirement already satisfied: jsoncomment==0.4.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (0.4.2)\n", + "Requirement already satisfied: pandas==2.1.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (2.1.2)\n", + "Requirement already satisfied: pyright==1.1.335 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (1.1.335)\n", + "Requirement already satisfied: autoflake==2.2.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from lastmile-utils==0.0.14->python-aiconfig==1.1.8) (2.2.1)\n", + "Requirement already satisfied: click>=8.0.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from black->python-aiconfig==1.1.8) (8.1.7)\n", + "Requirement already satisfied: mypy-extensions>=0.4.3 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from black->python-aiconfig==1.1.8) (1.0.0)\n", + "Requirement already satisfied: packaging>=22.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from black->python-aiconfig==1.1.8) (23.2)\n", + "Requirement already satisfied: pathspec>=0.9.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from black->python-aiconfig==1.1.8) (0.12.1)\n", + "Requirement already satisfied: platformdirs>=2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from black->python-aiconfig==1.1.8) (4.1.0)\n", + "Requirement already satisfied: mccabe<0.8.0,>=0.7.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flake8->python-aiconfig==1.1.8) (0.7.0)\n", + "Requirement already satisfied: pycodestyle<2.12.0,>=2.11.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flake8->python-aiconfig==1.1.8) (2.11.1)\n", + "Requirement already satisfied: pyflakes<3.2.0,>=3.1.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flake8->python-aiconfig==1.1.8) (3.1.0)\n", + "Requirement already satisfied: annotated-types>=0.4.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pydantic>=2.1->python-aiconfig==1.1.8) (0.6.0)\n", + "Requirement already satisfied: pydantic-core==2.10.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pydantic>=2.1->python-aiconfig==1.1.8) (2.10.1)\n", + "Requirement already satisfied: typing-extensions>=4.6.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pydantic>=2.1->python-aiconfig==1.1.8) (4.9.0)\n", + "Requirement already satisfied: astroid<=3.1.0-dev0,>=3.0.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pylint->python-aiconfig==1.1.8) (3.0.2)\n", + "Requirement already satisfied: tomlkit>=0.10.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pylint->python-aiconfig==1.1.8) (0.12.3)\n", + "Requirement already satisfied: dill>=0.3.6 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pylint->python-aiconfig==1.1.8) (0.3.7)\n", + "Requirement already satisfied: iniconfig in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pytest->python-aiconfig==1.1.8) (2.0.0)\n", + "Requirement already satisfied: pluggy<2.0,>=0.12 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pytest->python-aiconfig==1.1.8) (1.3.0)\n", + "Requirement already satisfied: json-spec in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from jsoncomment==0.4.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (0.11.0)\n", + "Requirement already satisfied: numpy<2,>=1.26.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pandas==2.1.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (1.26.3)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pandas==2.1.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pandas==2.1.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (2023.3.post1)\n", + "Requirement already satisfied: tzdata>=2022.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pandas==2.1.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (2023.4)\n", + "Requirement already satisfied: nodeenv>=1.6.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pyright==1.1.335->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (1.8.0)\n", + "Requirement already satisfied: anyio<5,>=3.5.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (4.2.0)\n", + "Requirement already satisfied: distro<2,>=1.7.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (1.9.0)\n", + "Requirement already satisfied: httpx<1,>=0.23.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (0.26.0)\n", + "Requirement already satisfied: sniffio in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (1.3.0)\n", + "Requirement already satisfied: tqdm>4 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (4.66.1)\n", + "Requirement already satisfied: Werkzeug>=3.0.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flask[async]->python-aiconfig==1.1.8) (3.0.1)\n", + "Requirement already satisfied: Jinja2>=3.1.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flask[async]->python-aiconfig==1.1.8) (3.1.2)\n", + "Requirement already satisfied: itsdangerous>=2.1.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flask[async]->python-aiconfig==1.1.8) (2.1.2)\n", + "Requirement already satisfied: blinker>=1.6.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flask[async]->python-aiconfig==1.1.8) (1.7.0)\n", + "Requirement already satisfied: asgiref>=3.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from flask[async]->python-aiconfig==1.1.8) (3.7.2)\n", + "Requirement already satisfied: google-ai-generativelanguage==0.4.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-generativeai->python-aiconfig==1.1.8) (0.4.0)\n", + "Requirement already satisfied: google-auth in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-generativeai->python-aiconfig==1.1.8) (2.26.0)\n", + "Requirement already satisfied: google-api-core in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-generativeai->python-aiconfig==1.1.8) (2.15.0)\n", + "Requirement already satisfied: protobuf in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-generativeai->python-aiconfig==1.1.8) (4.25.1)\n", + "Requirement already satisfied: proto-plus<2.0.0dev,>=1.22.3 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-ai-generativelanguage==0.4.0->google-generativeai->python-aiconfig==1.1.8) (1.23.0)\n", + "Requirement already satisfied: filelock in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from huggingface-hub->python-aiconfig==1.1.8) (3.13.1)\n", + "Requirement already satisfied: fsspec>=2023.5.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from huggingface-hub->python-aiconfig==1.1.8) (2023.12.2)\n", + "Requirement already satisfied: joblib in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from nltk->python-aiconfig==1.1.8) (1.3.2)\n", + "Requirement already satisfied: regex>=2021.8.3 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from nltk->python-aiconfig==1.1.8) (2023.12.25)\n", + "Requirement already satisfied: wcwidth in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from prompt-toolkit->python-aiconfig==1.1.8) (0.2.12)\n", + "Requirement already satisfied: PyMeta3>=0.5.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pybars3->python-aiconfig==1.1.8) (0.5.1)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from requests->python-aiconfig==1.1.8) (3.3.2)\n", + "Requirement already satisfied: idna<4,>=2.5 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from requests->python-aiconfig==1.1.8) (3.6)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from requests->python-aiconfig==1.1.8) (2.1.0)\n", + "Requirement already satisfied: certifi>=2017.4.17 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from requests->python-aiconfig==1.1.8) (2023.11.17)\n", + "Requirement already satisfied: googleapis-common-protos<2.0.dev0,>=1.56.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-api-core->google-generativeai->python-aiconfig==1.1.8) (1.62.0)\n", + "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-auth->google-generativeai->python-aiconfig==1.1.8) (5.3.2)\n", + "Requirement already satisfied: pyasn1-modules>=0.2.1 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-auth->google-generativeai->python-aiconfig==1.1.8) (0.3.0)\n", + "Requirement already satisfied: rsa<5,>=3.1.4 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-auth->google-generativeai->python-aiconfig==1.1.8) (4.9)\n", + "Requirement already satisfied: httpcore==1.* in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (1.0.2)\n", + "Requirement already satisfied: h11<0.15,>=0.13 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai<1.5,>=1.0.0->python-aiconfig==1.1.8) (0.14.0)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from Jinja2>=3.1.2->flask[async]->python-aiconfig==1.1.8) (2.1.3)\n", + "Requirement already satisfied: grpcio<2.0dev,>=1.33.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0->google-ai-generativelanguage==0.4.0->google-generativeai->python-aiconfig==1.1.8) (1.60.0)\n", + "Requirement already satisfied: grpcio-status<2.0.dev0,>=1.33.2 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.0->google-ai-generativelanguage==0.4.0->google-generativeai->python-aiconfig==1.1.8) (1.60.0)\n", + "Requirement already satisfied: setuptools in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from nodeenv>=1.6.0->pyright==1.1.335->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (69.0.3)\n", + "Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from pyasn1-modules>=0.2.1->google-auth->google-generativeai->python-aiconfig==1.1.8) (0.5.1)\n", + "Requirement already satisfied: six>=1.5 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas==2.1.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (1.16.0)\n", + "Requirement already satisfied: importlib-metadata<6.0.0,>=5.0.0 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from json-spec->jsoncomment==0.4.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (5.2.0)\n", + "Requirement already satisfied: zipp>=0.5 in /opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages (from importlib-metadata<6.0.0,>=5.0.0->json-spec->jsoncomment==0.4.2->lastmile-utils==0.0.14->python-aiconfig==1.1.8) (3.17.0)\n", + "Building wheels for collected packages: python-aiconfig\n", + " Building editable for python-aiconfig (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25h Created wheel for python-aiconfig: filename=python_aiconfig-1.1.8-0.editable-py3-none-any.whl size=9971 sha256=18699068804b023ee12eb07d94efe96e40c05e54dfa9e4d971e6fbcf933645da\n", + " Stored in directory: /private/var/folders/mk/5l10lyqs1c73_pj2grj9f9vw0000gn/T/pip-ephem-wheel-cache-8467usz2/wheels/e7/fd/a2/adfd3d754fa5bcf2040054afef13bbf40a8e091249b821d62d\n", + "Successfully built python-aiconfig\n", + "Installing collected packages: python-aiconfig\n", + " Attempting uninstall: python-aiconfig\n", + " Found existing installation: python-aiconfig 1.1.8\n", + " Uninstalling python-aiconfig-1.1.8:\n", + " Successfully uninstalled python-aiconfig-1.1.8\n", + "Successfully installed python-aiconfig-1.1.8\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install -e /Users/saqadri/lm/aiconfig/python" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "51w-3OZC_Z97" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Create .env file at aiconfig/.env containing the following line: \n", + "# ANYSCALE_ENDPOINT_API_KEY=\n", + "# You can get your key from https://app.endpoints.anyscale.com/credentials\n", + "import dotenv\n", + "dotenv.load_dotenv()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "rXJJiDO6gbOK" + }, + "source": [ + "## Set up the books DB" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "KP-CTNZBKN_J" + }, + "outputs": [], + "source": [ + "# Define db of books\n", + "db = [\n", + " {\n", + " 'id': 'a1',\n", + " 'name': 'To Kill a Mockingbird',\n", + " 'genre': 'historical',\n", + " 'description': ('Compassionate, dramatic, and deeply moving, \"To Kill A Mockingbird\" takes readers to the roots of human behavior - to innocence and experience, kindness and cruelty, love and hatred, humor and pathos. Now with over 18 million copies in print and translated into forty languages, this regional story by a young Alabama woman claims universal appeal. Harper Lee always considered her book to be a simple love story. Today it is regarded as a masterpiece of American literature.'),\n", + " },\n", + " {\n", + " 'id': 'a2',\n", + " 'name': 'All the Light We Cannot See',\n", + " 'genre': 'historical',\n", + " 'description': ('In a mining town in Germany, Werner Pfennig, an orphan, grows up with his younger sister, enchanted by a crude radio they find that brings them news and stories from places they have never seen or imagined. Werner becomes an expert at building and fixing these crucial new instruments and is enlisted to use his talent to track down the resistance. Deftly interweaving the lives of Marie-Laure and Werner, Doerr illuminates the ways, against all odds, people try to be good to one another.'),\n", + " },\n", + " {\n", + " 'id': 'a3',\n", + " 'name': 'Where the Crawdads Sing',\n", + " 'genre': 'historical',\n", + " 'description': ('For years, rumors of the “Marsh Girl” haunted Barkley Cove, a quiet fishing village. Kya Clark is barefoot and wild; unfit for polite society. So in late 1969, when the popular Chase Andrews is found dead, locals immediately suspect her.\\n\\n'\n", + " 'But Kya is not what they say. A born naturalist with just one day of school, she takes life\\'s lessons from the land, learning the real ways of the world from the dishonest signals of fireflies. But while she has the skills to live in solitude forever, the time comes when she yearns to be touched and loved. Drawn to two young men from town, who are each intrigued by her wild beauty, Kya opens herself to a new and startling world—until the unthinkable happens.'),\n", + " },\n", + "]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "dCiJurzKgnqB" + }, + "source": [ + "## Define functions (to interact with DB)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "nbolW2mVDeZD" + }, + "outputs": [], + "source": [ + "# Define the functions: list, search, get\n", + "\n", + "# The 'list' function returns a list of books in a specified genre.\n", + "def list(genre):\n", + " return [item for item in db if item['genre'] == genre]\n", + "\n", + "# The 'search' function returns a list of books that match the provided name.\n", + "def search(name):\n", + " return [item for item in db if name in item['name']]\n", + "\n", + "# The 'get' function returns detailed information about a book based on its ID.\n", + "# Note: This function accepts only IDs, not names. Use the 'search' function to find a book's ID.\n", + "def get(id):\n", + " for item in db:\n", + " if item['id'] == id:\n", + " return item\n", + " return None" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "ni_umLSdjAAT" + }, + "source": [ + "## Get recommendations using function calls" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "o7eJfimvLa3X" + }, + "outputs": [], + "source": [ + "# Use helper function to executes the function specified by the LLM's output for 'function_call'.\n", + "# It handles 'list', 'search', or 'get' functions, and raises a ValueError for unknown functions.\n", + "import json\n", + "\n", + "def call_function(function_call):\n", + " args = json.loads(function_call.arguments)\n", + " name = function_call.name\n", + "\n", + " if name == 'list':\n", + " print(f\"genre={args['genre']}, args={args}\")\n", + " return list(args['genre'])\n", + " elif name == 'search':\n", + " return search(args['name'])\n", + " elif name == 'get':\n", + " return get(args['id'])\n", + " else:\n", + " raise ValueError('No function found')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages/pydantic/_internal/_fields.py:128: UserWarning: Field \"model_parsers\" has conflict with protected namespace \"model_\".\n", + "\n", + "You may be able to resolve this warning by setting `model_config['protected_namespaces'] = ()`.\n", + " warnings.warn(\n", + "/opt/homebrew/Caskroom/miniconda/base/envs/aiconfig/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + } + ], + "source": [ + "from aiconfig import AIConfigRuntime, InferenceOptions\n", + "\n", + "config = AIConfigRuntime.load(\"recommender.aiconfig.json\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "id": "jD9S3q5mMtqd" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ExecuteResult(output_type='execute_result', execution_count=0, data=OutputDataWithToolCallsValue(kind='tool_calls', value=[ToolCallData(id='call_2f1aca9308454db1bf39030212fe3c4f', function=FunctionCallData(arguments='{\"name\": \"Where the Crawdads Sing\"}', name='search'), type='function')]), mime_type=None, metadata={'raw_response': {'role': 'assistant', 'tool_calls': [{'id': 'call_2f1aca9308454db1bf39030212fe3c4f', 'function': {'arguments': '{\"name\": \"Where the Crawdads Sing\"}', 'name': 'search'}, 'type': 'function'}]}, 'id': 'mistralai/Mixtral-8x7B-Instruct-v0.1-UL3yG8uqvO7QFPsRp1dUMfNDVL3vo27sZPxqrbECoKc', 'created': 1704329124, 'model': 'mistralai/Mixtral-8x7B-Instruct-v0.1', 'object': 'text_completion', 'usage': {'completion_tokens': 62, 'prompt_tokens': 651, 'total_tokens': 713}, 'finish_reason': 'tool_calls', 'role': 'assistant'})]\n" + ] + } + ], + "source": [ + "# Run recommendBook prompt with gpt-3.5 and determine right function to call based on user question\n", + "params = {\"book\":\"Where the Crawdads Sing\"}\n", + "inference_options = InferenceOptions(stream=False)\n", + "\n", + "completion = await config.run(\"recommend_book\", params, options=inference_options)\n", + "print(completion)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "kind='tool_calls' value=[ToolCallData(id='call_2f1aca9308454db1bf39030212fe3c4f', function=FunctionCallData(arguments='{\"name\": \"Where the Crawdads Sing\"}', name='search'), type='function')]\n" + ] + } + ], + "source": [ + "output_data = completion[0].data\n", + "print(output_data)\n", + "\n", + "assert output_data.kind == \"tool_calls\"" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "id": "CZ_NhrvrTCu8" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "id='call_2f1aca9308454db1bf39030212fe3c4f' function=FunctionCallData(arguments='{\"name\": \"Where the Crawdads Sing\"}', name='search') type='function'\n", + "[\n", + " {\n", + " \"id\": \"a3\",\n", + " \"name\": \"Where the Crawdads Sing\",\n", + " \"genre\": \"historical\",\n", + " \"description\": \"For years, rumors of the \\u201cMarsh Girl\\u201d haunted Barkley Cove, a quiet fishing village. Kya Clark is barefoot and wild; unfit for polite society. So in late 1969, when the popular Chase Andrews is found dead, locals immediately suspect her.\\n\\nBut Kya is not what they say. A born naturalist with just one day of school, she takes life's lessons from the land, learning the real ways of the world from the dishonest signals of fireflies. But while she has the skills to live in solitude forever, the time comes when she yearns to be touched and loved. Drawn to two young men from town, who are each intrigued by her wild beauty, Kya opens herself to a new and startling world\\u2014until the unthinkable happens.\"\n", + " }\n", + "]\n" + ] + } + ], + "source": [ + "# Run call_function to execute the LLM-specified function (list, search, get)\n", + "\n", + "result = None\n", + "for func_call in output_data.value:\n", + " print(func_call)\n", + " function = func_call.function\n", + " result = call_function(function)\n", + " print(json.dumps(result, indent=4))\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": { + "id": "MKEf1idOjkvk" + }, + "source": [ + "## Using LLaMA-7B to generate a user-friendly response" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "id": "0QZHtalIVGQB" + }, + "outputs": [], + "source": [ + "model=\"mistralai/Mistral-7B-Instruct-v0.1\"\n", + "data = {\n", + " \"model\": model,\n", + " \"messages\": [\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"Here is some data about a book from a books DB - please write a short description about the book as if you're a librarian. Data: {{book_info}}\"\n", + " }\n", + " ]\n", + "}\n", + "\n", + "new_prompts = await config.serialize(model, data, prompt_name=\"gen_summary\")\n", + "config.add_prompt(prompt_name=\"gen_summary\", prompt_data=new_prompts[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "id": "Xd-4rg5lj8lp" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " \"Where the Crawdads Sing\" is a captivating historical novel by Delia Owens that explores the life of Kya Clark, a self-sufficient naturalist who lives in the marshes of North Carolina. With vivid descriptions of the natural world and Kya's relationship with it, the novel highlights the resilience of the human spirit and the power of love and community. It is a poignant story that explores complex themes such as isolation, grief and the search for connection while also examining the prejudices and biases of society. With its stunning prose and compelling plot, \"Where the Crawdads Sing\" is a must-read for anyone interested in a beautifully written, thought-provoking novel." + ] + } + ], + "source": [ + "inference_options = InferenceOptions(stream=True)\n", + "completion = await config.run(\"gen_summary\", params={\"book_info\": result}, options=inference_options)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "4l-buJXglaLw" + }, + "outputs": [], + "source": [ + "config.save(\"recommender.aiconfig.json\", include_outputs=True)" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/cookbooks/Anyscale/README.md b/cookbooks/Anyscale/README.md index 6ae242632..989270c73 100644 --- a/cookbooks/Anyscale/README.md +++ b/cookbooks/Anyscale/README.md @@ -10,6 +10,7 @@ We cover: - Inference using Anyscale Endpoints - Prompt chains with multiple models +- Function calling with Anyscale Endpoints & AIConfig Read more about [AIConfig for prompt and model management](https://github.com/lastmile-ai/aiconfig). diff --git a/cookbooks/Anyscale/recommender.aiconfig.json b/cookbooks/Anyscale/recommender.aiconfig.json new file mode 100644 index 000000000..e45296852 --- /dev/null +++ b/cookbooks/Anyscale/recommender.aiconfig.json @@ -0,0 +1,91 @@ +{ + "name": "Book Finder", + "schema_version": "latest", + "metadata": { + "parameters": {}, + "models": {}, + "model_parsers": { + "mistralai/Mistral-7B-Instruct-v0.1": "AnyscaleEndpoint", + "mistralai/Mixtral-8x7B-Instruct-v0.1": "AnyscaleEndpoint" + } + }, + "description": "Use Mixtral-8x7B function calling with Anyscale Endpoints to help recommend books", + "prompts": [ + { + "name": "recommend_book", + "input": "I really enjoyed reading {{book}}, could you recommend me a book that is similar and tell me why?", + "metadata": { + "model": { + "name": "mistralai/Mixtral-8x7B-Instruct-v0.1", + "settings": { + "model": "mistralai/Mixtral-8x7B-Instruct-v0.1", + "tools": [ + { + "type": "function", + "function": { + "name": "list", + "description": "list queries books by genre, and returns a list of names of books", + "parameters": { + "type": "object", + "properties": { + "genre": { + "type": "string", + "enum": [ + "mystery", + "nonfiction", + "memoir", + "romance", + "historical" + ] + } + } + } + } + }, + { + "type": "function", + "function": { + "name": "search", + "description": "search queries books by their name and returns a list of book names and their ids", + "parameters": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } + }, + { + "type": "function", + "function": { + "name": "get", + "description": "get returns a book's detailed information based on the id of the book. Note that this does not accept names, and only IDs, which you can get by using search.", + "parameters": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + } + } + } + } + ], + "system_prompt": { + "role": "system", + "content": "Please use our book database, which you can access using functions to answer the following questions." + } + } + }, + "parameters": { + "book": "To Kill a Mockingbird" + }, + "remember_chat_context": true + }, + "outputs": [] + } + ], + "$schema": "https://json.schemastore.org/aiconfig-1.0" +} diff --git a/cookbooks/Anyscale/updated.aiconfig.json b/cookbooks/Anyscale/updated.aiconfig.json new file mode 100644 index 000000000..770952a71 --- /dev/null +++ b/cookbooks/Anyscale/updated.aiconfig.json @@ -0,0 +1,116 @@ +{ + "name": "NYC Trip Planner", + "schema_version": "latest", + "metadata": { + "parameters": {}, + "models": { + "meta-llama/Llama-2-7b-chat-hf": { + "model": "meta-llama/Llama-2-7b-chat-hf", + "top_p": 1, + "temperature": 1 + }, + "meta-llama/Llama-2-70b-chat-hf": { + "model": "meta-llama/Llama-2-70b-chat-hf", + "max_tokens": 3000, + "system_prompt": "You are an expert travel coordinator with exquisite taste." + } + }, + "default_model": "meta-llama/Llama-2-7b-chat-hf", + "model_parsers": { + "meta-llama/Llama-2-7b-chat-hf": "AnyscaleEndpoint", + "meta-llama/Llama-2-13b-chat-hf": "AnyscaleEndpoint", + "Meta-Llama/Llama-Guard-7b": "AnyscaleEndpoint", + "meta-llama/Llama-2-70b-chat-hf": "AnyscaleEndpoint", + "Open-Orca/Mistral-7B-OpenOrca": "AnyscaleEndpoint", + "codellama/CodeLlama-34b-Instruct-hf": "AnyscaleEndpoint", + "HuggingFaceH4/zephyr-7b-beta": "AnyscaleEndpoint", + "mistralai/Mistral-7B-Instruct-v0.1": "AnyscaleEndpoint", + "mistralai/Mixtral-8x7B-Instruct-v0.1": "AnyscaleEndpoint", + "thenlper/gte-large": "AnyscaleEndpoint" + } + }, + "description": "Intrepid explorer with ChatGPT and AIConfig", + "prompts": [ + { + "name": "get_activities", + "input": "Tell me 10 fun attractions to do in NYC.", + "outputs": [ + { + "output_type": "execute_result", + "execution_count": 0, + "data": { + "role": "assistant", + "content": " Sure! Here are 10 fun attractions to do in New York City:\n\n1. Visit the Statue of Liberty and Ellis Island: Take a ferry to Liberty Island to see the iconic Statue of Liberty up close and learn about its history at the nearby Ellis Island Immigration Museum.\n2. Explore the Metropolitan Museum of Art: With over 2 million works of art spanning 5,000 years of history, the Met is one of the world's largest and most comprehensive art museums.\n3. Walk across the Brooklyn Bridge: Take a stroll across this iconic bridge for spectacular views of the Manhattan skyline, the East River, and Brooklyn.\n4. See a Broadway show: New York City is home to dozens of world-class theaters and performances, including Tony-award winning shows like Hamilton, Wicked, and The Lion King.\n5. Visit Central Park: This 843-acre green oasis in the middle of Manhattan offers a peaceful escape from the hustle and bustle of the city, with plenty of walking paths, lakes, and monuments to explore.\n6. Go shopping on Fifth Avenue: From high-end designer boutiques to exclusive department stores, Fifth Avenue is the ultimate shopping destination in NYC.\n7. Visit the 9/11 Memorial & Museum: A poignant tribute to the victims of the 9/11 attacks, the memorial features two reflecting pools surrounded by the names of those who were killed, as well as a museum with artifacts and stories from that fateful day.\n8. Take a food tour: New York City is a food lover's paradise, with a diverse array of cuisines and dining options. Take a guided tour to sample some of the city's best foods, from classic pizza to artisanal doughnuts.\n9. Visit the Museum of Modern Art (MoMA): With a collection of over 200,000 works of art, MoMA is one of the world's premier modern art museums, featuring pieces by artists like Picasso, Warhol, and Pollock.\n10. Take a helicopter tour of NYC: For a unique perspective on the city, take a helicopter tour of New York City's iconic skyline and landmarks. You'll soar over the Hudson River and get a bird's-eye view of Manhattan's towering skyscrapers, bridges, and parks.\n\nThese are just a few of the many fun attractions to explore in New York City. Depending on your interests, there are countless other activities and experiences to enjoy in the city that never sleeps!" + }, + "metadata": { + "finish_reason": "stop" + } + } + ] + }, + { + "name": "gen_itinerary", + "input": "Generate an itinerary ordered by {{order_by}} for these activities: {{get_activities.output}}.", + "metadata": { + "model": { + "name": "AnyscaleEndpoint", + "settings": { + "model": "mistralai/Mixtral-8x7B-Instruct-v0.1", + "max_tokens": 3000, + "system_prompt": "You are an expert travel coordinator with exquisite taste." + } + }, + "parameters": { + "order_by": "geographic location" + } + }, + "outputs": [ + { + "output_type": "execute_result", + "execution_count": 0, + "data": { + "role": "assistant", + "content": " 1. Private guided tour of the Louvre Museum (2-3 hours)\nBegin your journey with a private guided tour of the Louvre Museum, the world's largest art museum and a historic monument in Paris. This tour will allow you to explore the museum's most famous works, including the Mona Lisa, the Winged Victory of Samothrace, and the Venus de Milo, with a knowledgeable guide who can provide context and insight into the artwork.\n\n2. Champagne tasting at a prestigious champagne house in Reims (2 hours)\nNext, head to Reims, a city in the Champagne region of France, for a private champagne tasting at a prestigious champagne house such as Taittinger, Veuve Clicquot, or Ruinart. You'll learn about the history and production methods of champagne, as well as have the opportunity to taste a selection of their finest bubbly.\n\n3. Lunch at a Michelin-starred restaurant in Reims (1.5-2 hours)\nTreat yourself to lunch at one of Reims' Michelin-starred restaurants, such as Le Foch, where you can sample local specialties such as Jambon de Reims, or Reims ham, and indulge in expertly prepared dishes made with fresh, seasonal ingredients.\n\n4. Private guided tour of the Palace of Versailles (3-4 hours)\nNo trip to France would be complete without a visit to the Palace of Versailles, the opulent palace and gardens of the French monarchy. A private guided tour will allow you to explore the palace's grand halls, ornate apartments, and incomparable art collections, as well as stroll through the meticulously manicured gardens and fountains.\n\n5. Seine River dinner cruise (2-3 hours)\nEnd your day with a romantic Seine River dinner cruise, where you'll float past some of Paris' most iconic landmarks, including the Eiffel Tower, Notre-Dame Cathedral, and the Louvre Museum, all while enjoying a delicious meal and live music.\n\n6. Private guided tour of Montmartre and Sacr\u00e9-Coeur Basilica (2-3 hours)\nBegin your second day with a private guided tour of Montmartre, the historic and artistic neighborhood atop a hill in Paris. This tour will take you through the charming streets of Montmartre, past the Moulin Rouge and the Place du Tertre, to the iconic white-domed Basilica of Sacr\u00e9-Coeur.\n\n7. Cooking class at a professional cooking school in Paris (3-4 hours)\nNext, immerse yourself in French culinary traditions with a private cooking class at a professional cooking school. You'll learn how to prepare classic French dishes such as coq au vin, ratatouille, or tarte tatin, and have the opportunity to enjoy the fruits of your labor for lunch.\n\n8. Private guided tour of the Mus\u00e9e d'Orsay (2-3 hours)\nEnd your trip with a private guided tour of the Mus\u00e9e d'Orsay, a museum located in a former railway station, which houses a vast collection of Impressionist and Post-Impressionist art. This tour will allow you to see works by artists such as Monet, Renoir, Degas, and Van Gogh, and gain a deeper understanding of the artistic movements that defined this period." + }, + "metadata": { + "finish_reason": "stop" + } + } + ] + }, + { + "name": "gen_packing_list", + "input": "What should I bring to {{location}}?", + "metadata": { + "model": { + "name": "gpt-3.5-turbo", + "settings": { + "model": "gpt-3.5-turbo", + "system_prompt": { + "role": "system", + "content": "You provide a bulleted list of items to pack for a week long trip." + } + } + }, + "parameters": { + "location": "nyc" + }, + "remember_chat_context": true + }, + "outputs": [ + { + "output_type": "execute_result", + "execution_count": 0, + "data": { + "content": "- Clothes for a week, including underwear, socks, and sleepwear\n- Outerwear appropriate for the weather (jacket, coat, or sweater)\n- Comfortable shoes for walking\n- Toiletries (toothbrush, toothpaste, shampoo, conditioner, soap, etc.)\n- Medications, if needed\n- Phone charger and other electronic accessories\n- Personal identification and travel documents (ID, passport, visa, etc.)\n- Wallet with cash and/or credit cards\n- Travel-sized umbrella or raincoat, depending on the weather forecast\n- Snacks and water bottle for the journey\n- Any necessary electronics or gadgets (camera, laptop, etc.)\n- Entertainment options (books, magazines, headphones, etc.)\n- Travel adapter, if necessary\n- Maps or guidebook of NYC\n- Sunscreen and sunglasses, if visiting during summer or sunny weather\n- Light backpack or day bag for touring around the city\n- Any special items specific to your needs or interests (art supplies, workout gear, etc.)", + "role": "assistant" + }, + "metadata": { + "finish_reason": "stop" + } + } + ] + } + ], + "$schema": "https://json.schemastore.org/aiconfig-1.0" +} \ No newline at end of file diff --git a/python/src/aiconfig/default_parsers/anyscale_endpoint.py b/python/src/aiconfig/default_parsers/anyscale_endpoint.py index 3cf9af18a..eab7d2510 100644 --- a/python/src/aiconfig/default_parsers/anyscale_endpoint.py +++ b/python/src/aiconfig/default_parsers/anyscale_endpoint.py @@ -15,7 +15,6 @@ Prompt, ToolCallData, ) -from aiconfig.util.config_utils import get_api_key_from_environment from .openai import OpenAIInference @@ -244,21 +243,23 @@ def build_output_data( if message.get("content") is not None: output_data = message.get("content") # string elif message.get("tool_calls") is not None: - tool_calls = [ - ToolCallData( - id=item.id, - function=FunctionCallData( - arguments=item.function.arguments, - name=item.function.name, - ), - type="function", + tool_calls = [] + for item in message.get("tool_calls"): + function = item.get("function") + if function is None: + continue + + tool_calls.append( + ToolCallData( + id=item.get("id"), + function=FunctionCallData( + arguments=function.get("arguments"), + name=function.get("name"), + ), + type=item.get("type") if not None else "function", + ) ) - for item in message.get("tool_calls") - # It's possible that ChatCompletionMessageToolCall may - # support more than just function calls in the future - # so filter out other types - if item.type == "function" - ] + output_data = OutputDataWithToolCallsValue( kind="tool_calls", value=tool_calls, diff --git a/python/src/aiconfig/default_parsers/openai.py b/python/src/aiconfig/default_parsers/openai.py index ec1afc621..6495cdc9f 100644 --- a/python/src/aiconfig/default_parsers/openai.py +++ b/python/src/aiconfig/default_parsers/openai.py @@ -345,8 +345,7 @@ def get_output_text( if isinstance(output_data.value, str): return output_data.value # If we get here that means it must be of kind tool_calls - return json.dumps(output_data.value, indent=2) - + return output_data.model_dump_json(exclude_none=True, indent=2) # Doing this to be backwards-compatible with old output format # where we used to save the ChatCompletionMessage in output.data if isinstance(output_data, ChatCompletionMessage): @@ -435,6 +434,8 @@ def refine_chat_completion_params(model_settings): "stop", "stream", "temperature", + "tools", + "tool_choice", "top_p", "user", } @@ -539,21 +540,25 @@ def build_output_data( if message.get("content") is not None: output_data = message.get("content") # string elif message.get("tool_calls") is not None: - tool_calls = [ - ToolCallData( - id=item.id, - function=FunctionCallData( - arguments=item.function.arguments, - name=item.function.name, - ), - type="function", + tool_calls = [] + for item in message.get("tool_calls"): + function = item.get("function") + if function is None: + # It's possible that ChatCompletionMessageToolCall may + # support more than just function calls in the future + # so filter out other types of tool calls for now + continue + + tool_calls.append( + ToolCallData( + id=item.get("id"), + function=FunctionCallData( + arguments=function.get("arguments"), + name=function.get("name"), + ), + type=item.get("type") if not None else "function", + ) ) - for item in message.get("tool_calls") - # It's possible that ChatCompletionMessageToolCall may - # support more than just function calls in the future - # so filter out other types - if item.type == "function" - ] output_data = OutputDataWithToolCallsValue( kind="tool_calls", value=tool_calls, diff --git a/python/src/aiconfig/schema.py b/python/src/aiconfig/schema.py index 77156c0c4..72dbe57ba 100644 --- a/python/src/aiconfig/schema.py +++ b/python/src/aiconfig/schema.py @@ -853,13 +853,9 @@ def add_outputs(self, prompt_name: str, outputs: List[Output], overwrite: bool = """ prompt = self.get_prompt(prompt_name) if not prompt: - raise IndexError( - f"Cannot add outputs. Prompt '{prompt_name}' not found in config." - ) + raise IndexError(f"Cannot add outputs. Prompt '{prompt_name}' not found in config.") if not outputs: - raise ValueError( - f"Cannot add outputs. No outputs provided for prompt '{prompt_name}'." - ) + raise ValueError(f"Cannot add outputs. No outputs provided for prompt '{prompt_name}'.") if overwrite: prompt.outputs = outputs else: