Skip to content

Commit

Permalink
Implement foreign function interface
Browse files Browse the repository at this point in the history
  • Loading branch information
klntsky committed Nov 23, 2024
1 parent 04bec7b commit f9d00a2
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 93 deletions.
18 changes: 18 additions & 0 deletions examples/foreign_functions.metaprompt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
false and true = [@and :with false :with true]
true and true = [@and :with true :with true]
true and false = [@and :with true :with false]
false and false = [@and :with false :with false]

false xor true = [@xor :with false :with true]
true xor true = [@xor :with true :with true]
true xor false = [@xor :with true :with false]
false xor false = [@xor :with false :with false]

[@cite :with
[@strip :with

autonomous AI agent
look inside
chatgpt prompt in a loop

]]
2 changes: 2 additions & 0 deletions grammar/MetaPrompt.g4
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ expr: LB expr1 RB
| OPTION_KW
| DEFAULT_KW
| IS_KW
| CALL
| WITH_KW
;

expr1
Expand Down
7 changes: 5 additions & 2 deletions python/src/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from provider_config import ProviderConfig
from typing import Dict
from prelude import prelude


class Config:
Expand All @@ -10,9 +11,11 @@ def __init__(
ProviderConfig | None
) = None, # TODO: add List[ProviderConfig] option
model: str | None = None,
parameters: Dict[str, str] = {},
parameters: Dict[str, str] = None,
foreign_functions=None,
):
self.providers = providers or ProviderConfig()
self.parameters = parameters
self.parameters = parameters or {}
self.model = model
self.foreign_functions = {**prelude, **(foreign_functions or {})}
# TODO: add logger
26 changes: 26 additions & 0 deletions python/src/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from loader import extract_parameter_set
from eval_utils.assignment import Assignment
from eval_utils.chat_history import serialize_chat_history
from eval_utils.arguments import Argument

IF_PROMPT = """Please determine if the following statement is true.
Do not write any other output, answer just "true" or "false".
Expand Down Expand Up @@ -186,6 +187,31 @@ def extract_choice_option(raw_response):

yield chosen_option

elif ast["type"] == "call":
name = ast["name"]
if name not in config.foreign_functions:
raise ValueError(f"Name {name} is not a foreign function")

fn = config.foreign_functions[name]

def capture(expr):
async def cb():
return await _collect_exprs(expr)

return cb

positional_args = [
Argument(capture(pos_arg), pos_arg)
for pos_arg in ast["positional_args"]
]

named_args = {
name: Argument(capture(expr), expr)
for name, expr in ast["named_args"].items()
}

yield await fn(*positional_args, **named_args)

elif ast["type"] == "use":
parameters = ast["parameters"]
module_name = ast["module_name"]
Expand Down
18 changes: 18 additions & 0 deletions python/src/eval_utils/arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Argument:
def __init__(self, compute, ast):
self._compute = compute
self._ast = ast
self._value = None
self._computed = False

async def compute(self):
if self._computed:
return self._value
res = await self._compute()
self._value = res
self._ast = None # allow gc to collect AST
self._computed = True
return res

async def get_ast(self):
return self._ast
35 changes: 35 additions & 0 deletions python/src/ffi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from functools import wraps
import inspect


def eager(fn):
@wraps(fn)
async def wrapper(*args, **kwargs):
args_computed = []
kwargs_computed = {}
for arg in args:
args_computed.append(await arg.compute())
for name, arg in kwargs.items():
kwargs_computed[name] = await arg.compute()
return await fn(*args_computed, **kwargs_computed)

return wrapper


def lazy(fn):
return fn


def foreign_function(eval_strategy=eager):
def wrap(fn):
@wraps(fn)
@eval_strategy
async def wrapper(*args, **kwargs):
if inspect.iscoroutinefunction(fn):
return await fn(*args, **kwargs)
else:
return fn(*args, **kwargs)

return wrapper

return wrap
2 changes: 2 additions & 0 deletions python/src/parse_metaprompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ def visitExpr(self, ctx: MetaPromptParser.ExprContext):
ctx.OPTION_KW(),
ctx.DEFAULT_KW(),
ctx.IS_KW(),
ctx.CALL(),
ctx.WITH_KW(),
]:
if part is not None:
exprs.append({"type": "text", "text": part.getText()})
Expand Down
2 changes: 1 addition & 1 deletion python/src/parser/MetaPrompt.interp
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ text


atn:
[4, 1, 17, 117, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 1, 0, 1, 0, 1, 1, 5, 1, 25, 8, 1, 10, 1, 12, 1, 28, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 45, 8, 2, 1, 3, 1, 3, 3, 3, 49, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 4, 66, 8, 4, 11, 4, 12, 4, 67, 1, 4, 3, 4, 71, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 87, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 5, 7, 99, 8, 7, 10, 7, 12, 7, 102, 9, 7, 1, 8, 1, 8, 1, 8, 5, 8, 107, 8, 8, 10, 8, 12, 8, 110, 9, 8, 1, 9, 4, 9, 113, 8, 9, 11, 9, 12, 9, 114, 1, 9, 1, 26, 0, 10, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 0, 132, 0, 20, 1, 0, 0, 0, 2, 26, 1, 0, 0, 0, 4, 44, 1, 0, 0, 0, 6, 48, 1, 0, 0, 0, 8, 86, 1, 0, 0, 0, 10, 88, 1, 0, 0, 0, 12, 93, 1, 0, 0, 0, 14, 100, 1, 0, 0, 0, 16, 108, 1, 0, 0, 0, 18, 112, 1, 0, 0, 0, 20, 21, 3, 2, 1, 0, 21, 22, 5, 0, 0, 1, 22, 1, 1, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 25, 28, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 26, 24, 1, 0, 0, 0, 27, 3, 1, 0, 0, 0, 28, 26, 1, 0, 0, 0, 29, 30, 5, 1, 0, 0, 30, 31, 3, 6, 3, 0, 31, 32, 5, 2, 0, 0, 32, 45, 1, 0, 0, 0, 33, 45, 3, 18, 9, 0, 34, 45, 5, 2, 0, 0, 35, 45, 5, 1, 0, 0, 36, 45, 5, 5, 0, 0, 37, 45, 5, 4, 0, 0, 38, 45, 5, 3, 0, 0, 39, 45, 5, 17, 0, 0, 40, 45, 5, 10, 0, 0, 41, 45, 5, 11, 0, 0, 42, 45, 5, 13, 0, 0, 43, 45, 5, 14, 0, 0, 44, 29, 1, 0, 0, 0, 44, 33, 1, 0, 0, 0, 44, 34, 1, 0, 0, 0, 44, 35, 1, 0, 0, 0, 44, 36, 1, 0, 0, 0, 44, 37, 1, 0, 0, 0, 44, 38, 1, 0, 0, 0, 44, 39, 1, 0, 0, 0, 44, 40, 1, 0, 0, 0, 44, 41, 1, 0, 0, 0, 44, 42, 1, 0, 0, 0, 44, 43, 1, 0, 0, 0, 45, 5, 1, 0, 0, 0, 46, 49, 3, 8, 4, 0, 47, 49, 3, 2, 1, 0, 48, 46, 1, 0, 0, 0, 48, 47, 1, 0, 0, 0, 49, 7, 1, 0, 0, 0, 50, 51, 5, 9, 0, 0, 51, 52, 3, 2, 1, 0, 52, 53, 5, 15, 0, 0, 53, 54, 3, 2, 1, 0, 54, 55, 5, 16, 0, 0, 55, 56, 3, 2, 1, 0, 56, 87, 1, 0, 0, 0, 57, 58, 5, 9, 0, 0, 58, 59, 3, 2, 1, 0, 59, 60, 5, 15, 0, 0, 60, 61, 3, 2, 1, 0, 61, 87, 1, 0, 0, 0, 62, 63, 5, 10, 0, 0, 63, 65, 3, 2, 1, 0, 64, 66, 3, 10, 5, 0, 65, 64, 1, 0, 0, 0, 66, 67, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 67, 68, 1, 0, 0, 0, 68, 70, 1, 0, 0, 0, 69, 71, 3, 12, 6, 0, 70, 69, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 87, 1, 0, 0, 0, 72, 73, 5, 7, 0, 0, 73, 87, 3, 16, 8, 0, 74, 75, 5, 4, 0, 0, 75, 87, 3, 2, 1, 0, 76, 77, 5, 5, 0, 0, 77, 87, 3, 2, 1, 0, 78, 79, 5, 17, 0, 0, 79, 80, 5, 3, 0, 0, 80, 87, 3, 2, 1, 0, 81, 87, 5, 17, 0, 0, 82, 83, 5, 8, 0, 0, 83, 84, 3, 14, 7, 0, 84, 85, 3, 16, 8, 0, 85, 87, 1, 0, 0, 0, 86, 50, 1, 0, 0, 0, 86, 57, 1, 0, 0, 0, 86, 62, 1, 0, 0, 0, 86, 72, 1, 0, 0, 0, 86, 74, 1, 0, 0, 0, 86, 76, 1, 0, 0, 0, 86, 78, 1, 0, 0, 0, 86, 81, 1, 0, 0, 0, 86, 82, 1, 0, 0, 0, 87, 9, 1, 0, 0, 0, 88, 89, 5, 11, 0, 0, 89, 90, 3, 2, 1, 0, 90, 91, 5, 14, 0, 0, 91, 92, 3, 2, 1, 0, 92, 11, 1, 0, 0, 0, 93, 94, 5, 13, 0, 0, 94, 95, 3, 2, 1, 0, 95, 13, 1, 0, 0, 0, 96, 97, 5, 12, 0, 0, 97, 99, 3, 2, 1, 0, 98, 96, 1, 0, 0, 0, 99, 102, 1, 0, 0, 0, 100, 98, 1, 0, 0, 0, 100, 101, 1, 0, 0, 0, 101, 15, 1, 0, 0, 0, 102, 100, 1, 0, 0, 0, 103, 104, 5, 17, 0, 0, 104, 105, 5, 3, 0, 0, 105, 107, 3, 2, 1, 0, 106, 103, 1, 0, 0, 0, 107, 110, 1, 0, 0, 0, 108, 106, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 17, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 111, 113, 5, 6, 0, 0, 112, 111, 1, 0, 0, 0, 113, 114, 1, 0, 0, 0, 114, 112, 1, 0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 19, 1, 0, 0, 0, 9, 26, 44, 48, 67, 70, 86, 100, 108, 114]
[4, 1, 17, 119, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 1, 0, 1, 0, 1, 0, 1, 1, 5, 1, 25, 8, 1, 10, 1, 12, 1, 28, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 47, 8, 2, 1, 3, 1, 3, 3, 3, 51, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 4, 68, 8, 4, 11, 4, 12, 4, 69, 1, 4, 3, 4, 73, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 89, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 5, 7, 101, 8, 7, 10, 7, 12, 7, 104, 9, 7, 1, 8, 1, 8, 1, 8, 5, 8, 109, 8, 8, 10, 8, 12, 8, 112, 9, 8, 1, 9, 4, 9, 115, 8, 9, 11, 9, 12, 9, 116, 1, 9, 1, 26, 0, 10, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 0, 0, 136, 0, 20, 1, 0, 0, 0, 2, 26, 1, 0, 0, 0, 4, 46, 1, 0, 0, 0, 6, 50, 1, 0, 0, 0, 8, 88, 1, 0, 0, 0, 10, 90, 1, 0, 0, 0, 12, 95, 1, 0, 0, 0, 14, 102, 1, 0, 0, 0, 16, 110, 1, 0, 0, 0, 18, 114, 1, 0, 0, 0, 20, 21, 3, 2, 1, 0, 21, 22, 5, 0, 0, 1, 22, 1, 1, 0, 0, 0, 23, 25, 3, 4, 2, 0, 24, 23, 1, 0, 0, 0, 25, 28, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 26, 24, 1, 0, 0, 0, 27, 3, 1, 0, 0, 0, 28, 26, 1, 0, 0, 0, 29, 30, 5, 1, 0, 0, 30, 31, 3, 6, 3, 0, 31, 32, 5, 2, 0, 0, 32, 47, 1, 0, 0, 0, 33, 47, 3, 18, 9, 0, 34, 47, 5, 2, 0, 0, 35, 47, 5, 1, 0, 0, 36, 47, 5, 5, 0, 0, 37, 47, 5, 4, 0, 0, 38, 47, 5, 3, 0, 0, 39, 47, 5, 17, 0, 0, 40, 47, 5, 10, 0, 0, 41, 47, 5, 11, 0, 0, 42, 47, 5, 13, 0, 0, 43, 47, 5, 14, 0, 0, 44, 47, 5, 8, 0, 0, 45, 47, 5, 12, 0, 0, 46, 29, 1, 0, 0, 0, 46, 33, 1, 0, 0, 0, 46, 34, 1, 0, 0, 0, 46, 35, 1, 0, 0, 0, 46, 36, 1, 0, 0, 0, 46, 37, 1, 0, 0, 0, 46, 38, 1, 0, 0, 0, 46, 39, 1, 0, 0, 0, 46, 40, 1, 0, 0, 0, 46, 41, 1, 0, 0, 0, 46, 42, 1, 0, 0, 0, 46, 43, 1, 0, 0, 0, 46, 44, 1, 0, 0, 0, 46, 45, 1, 0, 0, 0, 47, 5, 1, 0, 0, 0, 48, 51, 3, 8, 4, 0, 49, 51, 3, 2, 1, 0, 50, 48, 1, 0, 0, 0, 50, 49, 1, 0, 0, 0, 51, 7, 1, 0, 0, 0, 52, 53, 5, 9, 0, 0, 53, 54, 3, 2, 1, 0, 54, 55, 5, 15, 0, 0, 55, 56, 3, 2, 1, 0, 56, 57, 5, 16, 0, 0, 57, 58, 3, 2, 1, 0, 58, 89, 1, 0, 0, 0, 59, 60, 5, 9, 0, 0, 60, 61, 3, 2, 1, 0, 61, 62, 5, 15, 0, 0, 62, 63, 3, 2, 1, 0, 63, 89, 1, 0, 0, 0, 64, 65, 5, 10, 0, 0, 65, 67, 3, 2, 1, 0, 66, 68, 3, 10, 5, 0, 67, 66, 1, 0, 0, 0, 68, 69, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 73, 3, 12, 6, 0, 72, 71, 1, 0, 0, 0, 72, 73, 1, 0, 0, 0, 73, 89, 1, 0, 0, 0, 74, 75, 5, 7, 0, 0, 75, 89, 3, 16, 8, 0, 76, 77, 5, 4, 0, 0, 77, 89, 3, 2, 1, 0, 78, 79, 5, 5, 0, 0, 79, 89, 3, 2, 1, 0, 80, 81, 5, 17, 0, 0, 81, 82, 5, 3, 0, 0, 82, 89, 3, 2, 1, 0, 83, 89, 5, 17, 0, 0, 84, 85, 5, 8, 0, 0, 85, 86, 3, 14, 7, 0, 86, 87, 3, 16, 8, 0, 87, 89, 1, 0, 0, 0, 88, 52, 1, 0, 0, 0, 88, 59, 1, 0, 0, 0, 88, 64, 1, 0, 0, 0, 88, 74, 1, 0, 0, 0, 88, 76, 1, 0, 0, 0, 88, 78, 1, 0, 0, 0, 88, 80, 1, 0, 0, 0, 88, 83, 1, 0, 0, 0, 88, 84, 1, 0, 0, 0, 89, 9, 1, 0, 0, 0, 90, 91, 5, 11, 0, 0, 91, 92, 3, 2, 1, 0, 92, 93, 5, 14, 0, 0, 93, 94, 3, 2, 1, 0, 94, 11, 1, 0, 0, 0, 95, 96, 5, 13, 0, 0, 96, 97, 3, 2, 1, 0, 97, 13, 1, 0, 0, 0, 98, 99, 5, 12, 0, 0, 99, 101, 3, 2, 1, 0, 100, 98, 1, 0, 0, 0, 101, 104, 1, 0, 0, 0, 102, 100, 1, 0, 0, 0, 102, 103, 1, 0, 0, 0, 103, 15, 1, 0, 0, 0, 104, 102, 1, 0, 0, 0, 105, 106, 5, 17, 0, 0, 106, 107, 5, 3, 0, 0, 107, 109, 3, 2, 1, 0, 108, 105, 1, 0, 0, 0, 109, 112, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 17, 1, 0, 0, 0, 112, 110, 1, 0, 0, 0, 113, 115, 5, 6, 0, 0, 114, 113, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 114, 1, 0, 0, 0, 116, 117, 1, 0, 0, 0, 117, 19, 1, 0, 0, 0, 9, 26, 46, 50, 69, 72, 88, 102, 110, 116]
Loading

0 comments on commit f9d00a2

Please sign in to comment.