-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cd5bf7b
commit d482638
Showing
13 changed files
with
435 additions
and
62 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,5 @@ omit = | |
exclude_lines = | ||
pragma: no cover | ||
if __name__ == .__main__. | ||
\.\.\. | ||
show_missing = True |
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
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 |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import inspect | ||
import re | ||
import textwrap | ||
from typing import Callable, Union | ||
|
||
|
||
class FewShotExample: | ||
""" | ||
A question:answer representation for few-shot prompting | ||
""" | ||
|
||
def __init__(self, question: str, answer_expr: Union[str, Callable]) -> None: | ||
""" | ||
Args: | ||
question: sample question | ||
answer_expr: it can be either a stringified expression or a lambda for greater safety and code completions. | ||
Raises: | ||
ValueError: If answer_expr is not a correct type. | ||
""" | ||
self.question = question | ||
self.answer_expr = answer_expr | ||
|
||
if isinstance(self.answer_expr, str): | ||
self.answer = self.answer_expr | ||
elif callable(answer_expr): | ||
self.answer = self._parse_lambda(answer_expr) | ||
else: | ||
raise ValueError("Answer expression should be either a string or a lambda") | ||
|
||
def _parse_lambda(self, expr: Callable) -> str: | ||
""" | ||
Parses provided callable in order to extract the lambda code. | ||
All comments and references to variables like `self` etc will be removed | ||
to form a simple lambda representation. | ||
Args: | ||
expr: lambda expression to parse | ||
Returns: | ||
Parsed lambda in a form of cleaned up string | ||
""" | ||
# extract lambda from code | ||
expr_source = textwrap.dedent(inspect.getsource(expr)) | ||
expr_body = expr_source.replace("lambda:", "") | ||
|
||
# clean up by removing comments, new lines, free vars (self etc) | ||
parsed_expr = re.sub("\\#.*\n", "\n", expr_body, flags=re.MULTILINE) | ||
|
||
for m_name in expr.__code__.co_names: | ||
parsed_expr = parsed_expr.replace(f"{expr.__code__.co_freevars[0]}.{m_name}", m_name) | ||
|
||
# clean up any dangling commas or leading and trailing brackets | ||
parsed_expr = " ".join(parsed_expr.split()).strip().rstrip(",").replace("( ", "(").replace(" )", ")") | ||
if parsed_expr.startswith("("): | ||
parsed_expr = parsed_expr[1:-1] | ||
|
||
return parsed_expr | ||
|
||
def __str__(self) -> str: | ||
return self.answer |
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,119 @@ | ||
import copy | ||
from abc import ABCMeta, abstractmethod | ||
from typing import Dict, List, Tuple | ||
|
||
from dbally.prompts.elements import FewShotExample | ||
from dbally.prompts.prompt_template import PromptTemplate | ||
from dbally.views.exposed_functions import ExposedFunction | ||
|
||
|
||
def _promptify_filters( | ||
filters: List[ExposedFunction], | ||
) -> str: | ||
""" | ||
Formats filters for prompt | ||
Args: | ||
filters: list of filters exposed by the view | ||
Returns: | ||
filters formatted for prompt | ||
""" | ||
filters_for_prompt = "\n".join([str(filter) for filter in filters]) | ||
return filters_for_prompt | ||
|
||
|
||
class InputFormatter(metaclass=ABCMeta): | ||
""" | ||
Formats provided parameters to a form acceptable by IQL prompt | ||
""" | ||
|
||
@abstractmethod | ||
def __call__(self, conversation_template: PromptTemplate) -> Tuple[PromptTemplate, Dict[str, str]]: | ||
""" | ||
Runs the input formatting for provided prompt template. | ||
Args: | ||
conversation_template: a prompt template to use. | ||
Returns: | ||
A tuple with template and a dictionary with formatted inputs. | ||
""" | ||
|
||
|
||
class IQLInputFormatter(InputFormatter): | ||
""" | ||
Formats provided parameters to a form acceptable by default IQL prompt | ||
""" | ||
|
||
def __init__(self, filters: List[ExposedFunction], question: str) -> None: | ||
self.filters = filters | ||
self.question = question | ||
|
||
def __call__(self, conversation_template: PromptTemplate) -> Tuple[PromptTemplate, Dict[str, str]]: | ||
""" | ||
Runs the input formatting for provided prompt template. | ||
Args: | ||
conversation_template: a prompt template to use. | ||
Returns: | ||
A tuple with template and a dictionary with formatted filters and a question. | ||
""" | ||
return conversation_template, { | ||
"filters": _promptify_filters(self.filters), | ||
"question": self.question, | ||
} | ||
|
||
|
||
class IQLFewShotInputFormatter(InputFormatter): | ||
""" | ||
Formats provided parameters to a form acceptable by default IQL prompt. | ||
Calling it will inject `examples` before last message in a conversation. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
filters: List[ExposedFunction], | ||
examples: List[FewShotExample], | ||
question: str, | ||
) -> None: | ||
self.filters = filters | ||
self.question = question | ||
self.examples = examples | ||
|
||
def __call__(self, conversation_template: PromptTemplate) -> Tuple[PromptTemplate, Dict[str, str]]: | ||
""" | ||
Performs a deep copy of provided template and injects examples into chat history. | ||
Also prepares filters and question to be included within the prompt. | ||
Args: | ||
conversation_template: a prompt template to use to inject few-shot examples. | ||
Returns: | ||
A tuple with deeply-copied and enriched with examples template | ||
and a dictionary with formatted filters and a question. | ||
""" | ||
|
||
template_copy = copy.deepcopy(conversation_template) | ||
sys_msg = template_copy.chat[0] | ||
existing_msgs = [msg for msg in template_copy.chat[1:] if "is_example" not in msg] | ||
chat_examples = [ | ||
msg | ||
for example in self.examples | ||
for msg in [ | ||
{"role": "user", "content": example.question, "is_example": True}, | ||
{"role": "assistant", "content": example.answer, "is_example": True}, | ||
] | ||
] | ||
|
||
template_copy.chat = ( | ||
sys_msg, | ||
*chat_examples, | ||
*existing_msgs, | ||
) | ||
|
||
return template_copy, { | ||
"filters": _promptify_filters(self.filters), | ||
"question": self.question, | ||
} |
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.