This repository has been archived by the owner on Mar 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Wolfram Alhpa tooling * Add basic implementation, hold optional parameters * Add enums and error handling * Improvements * Type checking fixes * Add types-requests * Add catchall return * Update type error in run_update_tool_eval --> This was on main * Add env var to .env.example
- Loading branch information
Showing
11 changed files
with
595 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
# sourcery skip: docstrings-for-packages | ||
from automata.config.prompt.agentified_search import AGENTIFIED_SEARCH_TEMPLATE | ||
from automata.config.prompt.doc_generation import DOC_GENERATION_TEMPLATE | ||
from automata.config.prompt.wolfram_alpha import WOLFRAM_ALPHA_TEMPLATE | ||
|
||
__all__ = ["AGENTIFIED_SEARCH_TEMPLATE", "DOC_GENERATION_TEMPLATE"] | ||
__all__ = [ | ||
"AGENTIFIED_SEARCH_TEMPLATE", | ||
"DOC_GENERATION_TEMPLATE", | ||
"WOLFRAM_ALPHA_TEMPLATE", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
"""Defines the Wolfram Alpha prompt template.""" | ||
import textwrap | ||
|
||
WOLFRAM_ALPHA_TEMPLATE = textwrap.dedent( | ||
""" | ||
When using the Wolfram Alpha Oracle, you must call the query method with an `input_str` argument. Optional arguments, such as maxchars can also be passed in. | ||
Here are a few examples of how to use the Wolfram Alpha API through the Wolfram Alpha Oracle tool: | ||
Example 1 | ||
---------- | ||
input_str: 10 densest metals | ||
- Observed Results - | ||
Input interpretation: | ||
10 densest metallic elements | by mass density | ||
Result: | ||
1 | hassium | 41 g/cm^3 | | ||
2 | meitnerium | 37.4 g/cm^3 | | ||
3 | bohrium | 37.1 g/cm^3 | | ||
4 | seaborgium | 35.3 g/cm^3 | | ||
5 | darmstadtium | 34.8 g/cm^3 | | ||
6 | dubnium | 29.3 g/cm^3 | | ||
7 | roentgenium | 28.7 g/cm^3 | | ||
8 | rutherfordium | 23.2 g/cm^3 | | ||
9 | osmium | 22.59 g/cm^3 | | ||
10 | iridium | 22.56 g/cm^3 | | ||
Periodic table location: | ||
image: https://www6b3.wolframalpha.com/Calculate/MSP/MSP231019ge21d317638ic9000064icf9g3h4g5idge?MSPStoreType=image/png&s=18 | ||
Images: | ||
image: https://www6b3.wolframalpha.com/Calculate/MSP/MSP231119ge21d317638ic900005b65dgd6f55c7h34?MSPStoreType=image/png&s=18 | ||
Wolfram Language code: Dataset[EntityValue[{Entity["Element", "Hassium"], Entity["Element", "Meitnerium"], Entity["Element", "Bohrium"], Entity["Element", "Seaborgium"], Entity["Element", "Darmstadtium"], Entity["Element", "Dubnium"], Entity["Element", "Roentgenium"], Entity["Element", "Rutherfordium"], Entity["Element", "Osmium"], Entity["Element", "Iridium"]}, EntityProperty["Element", "Image"], "EntityAssociation"]] | ||
Basic elemental properties: | ||
atomic symbol | all | Bh | Db | Ds | Hs | Ir | Mt | Os | Rf | Rg | Sg | ||
atomic number | median | 106.5 | ||
| highest | 111 (roentgenium) | ||
| lowest | 76 (osmium) | ||
| distribution | | ||
atomic mass | median | 269 u | ||
| highest | 282 u (roentgenium) | ||
| lowest | 190.23 u (osmium) | ||
| distribution | | ||
half-life | median | 78 min | ||
| highest | 13 h (rutherfordium) | ||
| lowest | 4 min (darmstadtium) | ||
| distribution | | ||
Thermodynamic properties: | ||
phase at STP | all | solid | ||
(properties at standard conditions) | ||
Material properties: | ||
mass density | median | 32.1 g/cm^3 | ||
| highest | 41 g/cm^3 (hassium) | ||
| lowest | 22.56 g/cm^3 (iridium) | ||
| distribution | | ||
(properties at standard conditions) | ||
Reactivity: | ||
valence | median | 6 | ||
| highest | 7 (bohrium) | ||
| lowest | 4 (rutherfordium) | ||
| distribution | | ||
Atomic properties: | ||
term symbol | all | ^2S_(1/2) | ^3D_3 | ^3F_2 | ^4F_(3/2) | ^4F_(9/2) | ^5D_0 | ^5D_4 | ^6S_(5/2) | ||
(electronic ground state properties) | ||
Abundances: | ||
crust abundance | median | 0 mass% | ||
| highest | 1.8×10^-7 mass% (osmium) | ||
| lowest | 0 mass% (8 elements) | ||
human abundance | median | 0 mass% | ||
| highest | 0 mass% (8 elements) | ||
| lowest | 0 mass% (8 elements) | ||
Nuclear properties: | ||
half-life | median | 78 min | ||
| highest | 13 h (rutherfordium) | ||
| lowest | 4 min (darmstadtium) | ||
| distribution | | ||
specific radioactivity | highest | 6.123×10^6 TBq/g (darmstadtium) | ||
| lowest | 33169 TBq/g (rutherfordium) | ||
| median | 366018 TBq/g | ||
| distribution | | ||
Wolfram|Alpha website result for "10 densest metals": | ||
https://www6b3.wolframalpha.com/input?i=10+densest+metals | ||
""" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
automata/experimental/tools/builders/wolfram_alpha_oracle_builder.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
"""Implementation of a toolkit builder for the Wolfram Alpha API.""" | ||
|
||
import logging | ||
import logging.config | ||
from typing import List | ||
|
||
from automata.agent import AgentToolkitNames, OpenAIAgentToolkitBuilder | ||
from automata.config.config_base import LLMProvider | ||
from automata.core.utils import get_logging_config | ||
from automata.experimental.tools.wolfram_alpha_oracle import WolframAlphaOracle | ||
from automata.llm import OpenAITool | ||
from automata.singletons.toolkit_registry import ( | ||
OpenAIAutomataAgentToolkitRegistry, | ||
) | ||
from automata.tools.tool_base import Tool | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.config.dictConfig(get_logging_config()) | ||
|
||
|
||
class WolframAlphaToolkitBuilder: | ||
"""Builder for setting up the Wolfram Alpha Tool.""" | ||
|
||
def build(self) -> List[Tool]: | ||
"""Build and return a list containing an instance of the Wolfram Alpha Tool wrapped in a Tool object.""" | ||
return [ | ||
Tool( | ||
name="wolfram-alpha-oracle", | ||
function=self.query_wolfram_alpha, | ||
description="A tool to query the Wolfram Alpha API and retrieve results.", | ||
) | ||
] | ||
|
||
def query_wolfram_alpha(self, input_str: str, **kwargs) -> str: | ||
"""A wrapper function to query the Wolfram Alpha API.""" | ||
oracle = WolframAlphaOracle() | ||
if result := oracle.query(input_str, **kwargs): | ||
return result | ||
return "Failed to get data from Wolfram Alpha." | ||
|
||
|
||
@OpenAIAutomataAgentToolkitRegistry.register_tool_manager | ||
class WolframAlphaOpenAIToolkitBuilder( | ||
WolframAlphaToolkitBuilder, OpenAIAgentToolkitBuilder | ||
): | ||
TOOL_NAME = AgentToolkitNames.WOLFRAM_ALPHA_ORACLE | ||
LLM_PROVIDER = LLMProvider.OPENAI | ||
|
||
def __init__(self, **kwargs): | ||
super().__init__() | ||
|
||
def build_for_open_ai(self) -> List[OpenAITool]: | ||
"""Builds the tools associated with the Wolfram Alpha oracle for the OpenAI API.""" | ||
tools = super().build() | ||
|
||
properties = { | ||
"query": { | ||
"type": "string", | ||
"description": "The query string to send to Wolfram Alpha.", | ||
}, | ||
} | ||
required = ["query"] | ||
|
||
openai_tools = [] | ||
for tool in tools: | ||
openai_tool = OpenAITool( | ||
function=tool.function, | ||
name=tool.name, | ||
description=tool.description, | ||
properties=properties, | ||
required=required, | ||
) | ||
openai_tools.append(openai_tool) | ||
|
||
return openai_tools |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
""" | ||
Module to interface with the Wolfram Alpha API. | ||
Provides a set of enumerations for various query parameters and a class to | ||
handle querying the API and processing responses. | ||
""" | ||
|
||
import logging | ||
import logging.config | ||
import os | ||
import random | ||
import time | ||
from enum import Enum | ||
from typing import Optional | ||
|
||
import dotenv | ||
import requests | ||
|
||
from automata.core.utils import get_logging_config | ||
|
||
logger = logging.getLogger(__name__) | ||
logging.config.dictConfig(get_logging_config()) | ||
dotenv.load_dotenv() | ||
|
||
|
||
class BasicParameters(Enum): | ||
"""An enum for the basic parameters of the Wolfram Alpha API.""" | ||
|
||
INPUT = "input" | ||
APPID = "appid" | ||
FORMAT = "format" | ||
OUTPUT = "output" | ||
|
||
|
||
class PodSelection(Enum): | ||
"""An enum for the pod selection parameters of the Wolfram Alpha API.""" | ||
|
||
INCLUDEPODID = "includepodid" | ||
EXCLUDEPODID = "excludepodid" | ||
PODTITLE = "podtitle" | ||
PODINDEX = "podindex" | ||
SCANNER = "scanner" | ||
|
||
|
||
class Location(Enum): | ||
"""An enum for the location parameters of the Wolfram Alpha API.""" | ||
|
||
IP = "ip" | ||
LATLONG = "latlong" | ||
LOCATION = "location" | ||
|
||
|
||
class Size(Enum): | ||
"""An enum for the size parameters of the Wolfram Alpha API.""" | ||
|
||
WIDTH = "width" | ||
MAXWIDTH = "maxwidth" | ||
PLOTWIDTH = "plotwidth" | ||
MAG = "mag" | ||
|
||
|
||
class TimeoutsAsync(Enum): | ||
"""An enum for the timeouts and async parameters of the Wolfram Alpha API.""" | ||
|
||
SCANTIMEOUT = "scantimeout" | ||
PODTIMEOUT = "podtimeout" | ||
FORMATTIMEOUT = "formattimeout" | ||
PARSETIMEOUT = "parsetimeout" | ||
TOTALTIMEOUT = "totaltimeout" | ||
ASYNC = "async" | ||
|
||
|
||
class Misc(Enum): | ||
"""An enum for the miscellaneous parameters of the Wolfram Alpha API.""" | ||
|
||
REINTERPRET = "reinterpret" | ||
TRANSLATION = "translation" | ||
IGNORECASE = "ignorecase" | ||
SIG = "sig" | ||
ASSUMPTION = "assumption" | ||
PODSTATE = "podstate" | ||
UNITS = "units" | ||
|
||
|
||
class WolframAlphaOracle: | ||
"""Interface for querying the Wolfram Alpha API.""" | ||
|
||
BASE_URL = "https://www.wolframalpha.com/api/v1/llm-api" | ||
MAX_RETRIES = 3 | ||
BASE_DELAY = 1 | ||
MAX_DELAY = 10 | ||
|
||
@classmethod | ||
def query(cls, input_str: str, **kwargs) -> Optional[str]: | ||
"""Sends a query to the Wolfram Alpha API.""" | ||
|
||
app_id = os.environ.get("WOLFRAM_APP_ID") | ||
if not app_id: | ||
raise ValueError("WOLFRAM_APP_ID environment variable is not set.") | ||
|
||
params = { | ||
BasicParameters.INPUT.value: input_str, | ||
BasicParameters.APPID.value: app_id, | ||
} | ||
|
||
for key, value in kwargs.items(): | ||
params[key] = value.value if isinstance(value, Enum) else value | ||
|
||
retries = 0 | ||
delay = cls.BASE_DELAY | ||
|
||
# Uses exponential backoff with jitter to retry requests as the Wolfram Alpha API does not support retries. | ||
while retries < cls.MAX_RETRIES: | ||
try: | ||
response = requests.get(cls.BASE_URL, params=params) | ||
response.raise_for_status() | ||
return response.text | ||
except ( | ||
requests.ConnectionError, | ||
requests.Timeout, | ||
requests.RequestException, | ||
) as e: | ||
if retries < cls.MAX_RETRIES - 1: | ||
jitter = random.uniform(0, 0.1 * delay) | ||
time_to_wait = delay + jitter | ||
logger.warning( | ||
f"Error occurred: {e}. Retrying in {time_to_wait:.2f} seconds..." | ||
) | ||
time.sleep(time_to_wait) | ||
delay = min(2 * delay, cls.MAX_DELAY) | ||
retries += 1 | ||
elif isinstance(e, requests.ConnectionError): | ||
raise ConnectionError( | ||
f"Failed to connect to Wolfram Alpha API: {e}" | ||
) from e | ||
elif isinstance(e, requests.Timeout): | ||
raise TimeoutError( | ||
f"Request to Wolfram Alpha API timed out: {e}" | ||
) from e | ||
else: | ||
raise RuntimeError( | ||
f"An error occurred while querying the Wolfram Alpha API: {e}" | ||
) from e | ||
return None | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.