Skip to content

Commit

Permalink
Add docs for optional variable assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
klntsky committed Nov 20, 2024
1 parent 0c866a9 commit 9bb23f0
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 22 deletions.
1 change: 0 additions & 1 deletion docs/modules.md

This file was deleted.

44 changes: 23 additions & 21 deletions docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@ will be expanded to the same string, because it does not contain any MetaPrompt

# Variables

```metaprompt
Here's a variable: [:variable_name].
Variables should be referenced using this sintax: `[:variable_name]`. Variable names should match `[a-zA-Z_][a-zA-Z0-9_]*`.

If a variable is used before first assignment, it is treated as a required
prompt parameter automatically.
The syntax for assignments is `[:variable_name=any expression]`.

[:variable_name=it can be reassigned to any value, however]
[:variable_name=Including a value containing its old value: [:variable_name]]
```
Optional assignments use `?=` instead of `=` - they update the value only if a variable is unset.

# Comments

Expand Down Expand Up @@ -96,16 +92,32 @@ Normally, you would not need escaping, e.g. `[:foo` will evaluate to `[:foo` as

# Modules

Every `.metaprompt` file is a function.
Every `.metaprompt` file is a module. Conceptually, a module is a function that accepts a number of arguments, runs the executable parts, and returns text.

## Passing parameters

Unbound variables used in a module are its parameters, that must be provided when calling the module.

Unbound variables used in a file are its parameters, that must be provided.
**Example**

Consider a file named [`hello.metaprompt`](../examples/hello.metaprompt):

```metaprompt
Hello, [:what]! [# `what` is a parameter ]
[:who=you] [# `who` is NOT a parameter, because it is assigned before first use]
Hello, [:what]! [# `what` is a required parameter ]
[:who?=you]
[# ^ `who` is NOT a required parameter, because it is assigned
before first use. However, optional assignment is used, so
the default value can be overridden from the caller module
]
How are [:who] feeling today?
```

The `hello` module can be used like this from [another module](../examples/module-demo.metaprompt):

```
[:use ./hello :what=world :who=we]
```

## File imports

The following expression will include `./relative-import.metaprompt` file (relative to the directory of the file, NOT to the current working dir):
Expand All @@ -118,16 +130,6 @@ The following expression will include `./relative-import.metaprompt` file (relat

**NOT IMPLEMENTED**

## Passing parameters

```
[:use ./relative-import
:someParameter= arbitrary value, potentially using
any other MetaPrompt constructs
:otherParameter= another value
]
```

## Special variables

- `MODEL` - used to determine active LLM id.
Expand Down
7 changes: 7 additions & 0 deletions examples/hello.metaprompt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Hello, [:what]! [# `what` is a required parameter ]
[:who?=you]
[# ^ `who` is NOT a required parameter, because it is assigned
before first use. However, optional assignment is used, so
the default value can be overridden from the caller module
]
How are [:who] feeling today?
1 change: 1 addition & 0 deletions examples/module-demo.metaprompt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[:use ./hello :what=world :who=we]
2 changes: 2 additions & 0 deletions python/src/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ async def _eval_ast(ast):
yield chunk
elif ast["type"] == "text":
yield ast["text"]
elif ast["type"] == "comment":
return
elif ast["type"] == "metaprompt":
async for chunk in _eval_exprs(ast["exprs"]):
yield chunk
Expand Down
2 changes: 2 additions & 0 deletions python/src/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ def extract_parameter_set(ast):
elif ast["type"] == "exprs":
for expr in ast["exprs"]:
extract_parameter_set(expr, assigned)
elif ast["type"] == "comment":
pass
elif ast["type"] == "if_then_else":
res = res.then(extract_parameter_set(ast["condition"])).then(
extract_parameter_set(ast["then"]).alternative(
Expand Down

0 comments on commit 9bb23f0

Please sign in to comment.