File size: 2,741 Bytes
39c930a 8d7fe7c 39c930a d4ec913 5ddb3df 39c930a f92d1a2 39c930a f92d1a2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
from dataclasses import dataclass
import jsonschema
from dataclasses_json import DataClassJsonMixin
import backoff
import logging
from typing import Callable
PromptType = str | dict | list
FunctionCallType = dict
OutputType = str | FunctionCallType
logger = logging.getLogger("aide")
@backoff.on_predicate(
wait_gen=backoff.expo,
max_value=60,
factor=1.5,
)
def backoff_create(
create_fn: Callable, retry_exceptions: list[Exception], *args, **kwargs
):
try:
return create_fn(*args, **kwargs)
except retry_exceptions as e:
logger.info(f"Backoff exception: {e}")
return False
def opt_messages_to_list(
system_message: str | None, user_message: str | None
) -> list[dict[str, str]]:
messages = []
if system_message:
messages.append({"role": "system", "content": system_message})
if user_message:
messages.append({"role": "user", "content": user_message})
return messages
def compile_prompt_to_md(prompt: PromptType, _header_depth: int = 1) -> str:
if isinstance(prompt, str):
return prompt.strip() + "\n"
elif isinstance(prompt, list):
return "\n".join([f"- {s.strip()}" for s in prompt] + ["\n"])
out = []
header_prefix = "#" * _header_depth
for k, v in prompt.items():
out.append(f"{header_prefix} {k}\n")
out.append(compile_prompt_to_md(v, _header_depth=_header_depth + 1))
return "\n".join(out)
@dataclass
class FunctionSpec(DataClassJsonMixin):
name: str
json_schema: dict # JSON schema
description: str
def __post_init__(self):
# validate the schema
jsonschema.Draft7Validator.check_schema(self.json_schema)
@property
def as_openai_tool_dict(self):
"""Convert to OpenAI's function format."""
return {
"type": "function",
"function": {
"name": self.name,
"description": self.description,
"parameters": self.json_schema,
},
}
@property
def openai_tool_choice_dict(self):
return {
"type": "function",
"function": {"name": self.name},
}
@property
def as_anthropic_tool_dict(self):
"""Convert to Anthropic's tool format."""
return {
"name": self.name,
"description": self.description,
"input_schema": self.json_schema, # Anthropic uses input_schema instead of parameters
}
@property
def anthropic_tool_choice_dict(self):
"""Convert to Anthropic's tool choice format."""
return {
"type": "tool", # Anthropic uses "tool" instead of "function"
"name": self.name,
}
|