Skip to content

Commit d6c0120

Browse files
committed
Merge branch 'main' into pdl-aggregators
2 parents 5718045 + 4d1e9dd commit d6c0120

File tree

202 files changed

+5079
-4653
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+5079
-4653
lines changed

.github/workflows/mkdocs-gh-pages.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ jobs:
3333
steps:
3434
- name: Checkout
3535
uses: actions/checkout@v4
36+
# Schema
37+
- name: Copy schema
38+
run: |
39+
mkdir -p ./docs/dist
40+
cp ./src/pdl/pdl-schema.json ./docs/dist/pdl-schema.json
3641
# Docs
3742
- name: Setup Pages
3843
uses: actions/configure-pages@v5

.github/workflows/tauri-cli.yml

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,53 @@ jobs:
2525
with:
2626
node-version: 22
2727
- name: Install dependencies
28+
# sleep 2 to wait for ollama to be running... hack warning
2829
run: |
2930
npm ci & sudo apt update && \
3031
sudo apt install -y libgtk-3-dev libwebkit2gtk-4.1-dev librsvg2-dev patchelf at-spi2-core && \
31-
(curl -fsSL https://ollama.com/install.sh | sudo -E sh && sleep 2 && ollama pull granite3.2:2b)
32+
(curl -fsSL https://ollama.com/install.sh | sudo -E sh && sleep 2)
3233
wait
3334
- name: Test production build
3435
run: npm run tauri build -- --bundles deb # Skip testing appimage, is this dangerous? It's slow...
3536
- name: Setup xvfb for screen 0
3637
run: Xvfb :1 -screen 0 1600x1200x24 &
3738

38-
- name: Run production build
39+
- name: Test beeai compiler
3940
env:
4041
DISPLAY: :1
4142
run: |
4243
PATH=./src-tauri/target/release/:$PATH
44+
45+
for i in ./demos/beeai/*.py
46+
do pdl compile beeai $i -g -o /tmp/z.json && jq .description /tmp/z.json
47+
done
4348
44-
# 1. `run` subcommand works without any arguments
45-
pdl run | grep Usage
49+
- name: Test pdl run against production build
50+
env:
51+
DISPLAY: :1
52+
run: |
53+
PATH=./src-tauri/target/release/:$PATH
54+
55+
# 1a. `run` subcommand errors due to missing required positional parameter
56+
pdl run && (echo "This should have failed" && exit 1) || (echo "Great, expected failure received" && exit 0)
57+
58+
# 1b.`run` subcommand works without any arguments to print Usage
59+
pdl run 2>&1 | grep Usage
4660
47-
# 2. `run` subcommand works with demo1.pdl
61+
# 1c.`run` subcommand works with -h to print Usage
62+
pdl run -h 2>&1 | grep Usage
63+
64+
# 2. `run` subcommand works with UI demos (yaml source)
4865
pdl run ./demos/demo1.pdl | grep 'write a hello'
4966
67+
# 3. `run` subcommand works with UI demos (json source)
68+
# demo4 depends on user input
69+
# demo5,demo6 each depend on an external file, and the interpreter does not currently capture this in the trace
70+
# demo8 currently requires building a model which the interpreter does not directly support
71+
# demo9 takes forever, so... for now skip it
72+
for i in ./src/demos/*.json
73+
do if [[ $(basename $i) != "demo4.json" ]] && [[ $(basename $i) != "demo5.json" ]] && [[ $(basename $i) != "demo6.json" ]] && [[ $(basename $i) != "demo8.json" ]] && [[ $(basename $i) != "demo9.json" ]]; then pdl run $i; fi
74+
done
75+
5076
- name: Tear down xvfb
51-
run: killall Xvfb
77+
run: killall Xvfb || true

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ We can pass initial data to the interpreter to populate variables used in a PDL
106106
pdl --data <JSON-or-YAML-data> <my-example>
107107
```
108108

109+
For an example, see [file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/free_variables.pdl).
110+
109111
This can also be done by passing a JSON or YAML file:
110112

111113
```

docs/assets/pdl-ui-3.png

46.6 KB
Loading

docs/tutorial.md

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Using the `input` field, we can also give a directly an array of messages (`role
7272
--8<-- "./examples/tutorial/calling_llm_with_input_messages.pdl"
7373
```
7474

75-
This has the same output as the previous program.
75+
This has the same output as the previous program. An alternative way of writing this is [this](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/calling_llm_with_input_messages_var.pdl) program.
7676

7777
### Parameter defaults for watsonx Granite models
7878

@@ -104,7 +104,7 @@ Consider the following example ([file](https://github.com/IBM/prompt-declaration
104104
```
105105

106106
Here we assign the output of the model to variable `GEN` using the `def` field. The last line of the program prints out the value of `GEN`. Notice the notation `${ }` for accessing the value of a variable. Any [Jinja](https://jinja.palletsprojects.com/en/3.1.x/) expression is allowed to be used inside these braces. These expressions
107-
are also used to specify conditions for loops and conditionals. See for example this [file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/conditionals_loops.pdl).
107+
are also used to specify conditions for loops and conditionals. See for example this [file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/chatbot.pdl).
108108

109109
When we execute this program, we obtain:
110110
```
@@ -115,10 +115,10 @@ GEN is equal to: Hello
115115

116116
## Model Chaining
117117

118-
In PDL, we can declaratively chain models together as in the following example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/model_chaining.pdl)):
118+
In PDL, we can declaratively chain models together as in the following example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/calling_llm_chaining.pdl)):
119119

120120
```yaml
121-
--8<-- "./examples/tutorial/model_chaining.pdl"
121+
--8<-- "./examples/tutorial/calling_llm_chaining.pdl"
122122
```
123123

124124
In this program, the first call is to a Granite model with the prompt `"Hello\n"`. The following block in the program prints out the sentence: `"\nDid you just say Hello?\n"`. The final line of the program takes the entire context produced so far and passes it as input to the Granite model. Notice that the input passed to this model is the context up to that point, represented as a conversation. This makes it easy to chain models together and continue building on previous interactions. Notice how the conversational context is accumulated implicitly without requiring the user to explicitly manage messages.
@@ -159,12 +159,18 @@ To reset the context when calling a function, we can pass the special argument:
159159

160160
Notice that the arguments of function calls are expressions and cannot be arbitrary PDL blocks.
161161

162+
A function name can be aliased (see [example](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/function_alias.pdl)).
163+
164+
The context inherited by a function can be reset at the call site (see [example](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/function_empty_context.pdl)).
165+
166+
Functions can be declared with optional parameters (see [example](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/function_optional_params.pdl)).
167+
162168
## Grouping Variable Definitions in Defs
163169

164-
In PDL, the above program can be written more neatly by grouping certain variable definitions into a `defs` section, as follows ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/grouping_definitions.pdl)):
170+
In PDL, the above program can be written more neatly by grouping certain variable definitions into a `defs` section, as follows ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/defs.pdl)):
165171

166172
```yaml
167-
--8<-- "./examples/tutorial/grouping_definitions.pdl"
173+
--8<-- "./examples/tutorial/defs.pdl"
168174
```
169175

170176

@@ -173,7 +179,7 @@ This program has the same output has the one from the previous section.
173179
Any block can have a `defs` field defining variables used in that block. Notice it's different than the `def` field which stores the
174180
result of the block after execution.
175181

176-
182+
For another example, see [file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/defs-hello.pdl).
177183

178184
## Muting Block Output with contribute
179185

@@ -310,9 +316,15 @@ Other possible values for `parser` are `yaml`, `jsonl`, or `regex`.
310316

311317
The following example extracts using a regular expression parser the code between triple backtick generated by a model:
312318
```yaml
319+
--8<-- "./examples/tutorial/parser_regex_code.pdl"
320+
```
321+
322+
Here is another example using a regular expression:
323+
```yaml
313324
--8<-- "./examples/tutorial/parser_regex.pdl"
314325
```
315326

327+
316328
We support the following operations with the`regex` parser (indicated with the `mode` field):
317329

318330
- `fullmatch` (default)
@@ -334,40 +346,43 @@ See [here](https://docs.python.org/3/library/re.html) for more information on ho
334346

335347
## Calling code
336348

337-
The following script shows how to execute python code ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/calling_code.pdl)). The python code is executed locally (or in a containerized way if using `pdl --sandbox`). In principle, PDL is agnostic of any specific programming language, but we currently only support Python, Jinja, and shell commands. Variables defined in PDL are copied into the global scope of the Python code, so those variables can be used directly in the code. However, mutating variables in Python has no effect on the variables in the PDL program. The result of the code must be assigned to the variable `result` internally to be propagated to the result of the block. A variable `def` on the code block will then be set to this result.
349+
The following script shows how to execute python code ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/code_python.pdl)). The python code is executed locally (or in a containerized way if using `pdl --sandbox`). In principle, PDL is agnostic of any specific programming language, but we currently only support Python, Jinja, and shell commands. Variables defined in PDL are copied into the global scope of the Python code, so those variables can be used directly in the code. However, mutating variables in Python has no effect on the variables in the PDL program. The result of the code must be assigned to the variable `result` internally to be propagated to the result of the block. A variable `def` on the code block will then be set to this result.
338350

339351
In order to define variables that are carried over to the next Python code block, a special variable `PDL_SESSION` can be used, and
340352
variables assigned to it as fields.
341-
See for example: ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/rag/tfidf_rag.pdl)).
353+
See for example: ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/tfidf_rag.pdl)).
342354

343355
```yaml
344-
--8<-- "./examples/tutorial/calling_code.pdl"
356+
--8<-- "./examples/tutorial/code_python.pdl"
345357
```
346358

347359
This results in the following output (for example):
348360
```
349361
Hello, r!
350362
```
351363

352-
PDL also supports Jinja code blocks, as well as PDL code blocks for meta-cycle programming.
364+
PDL also supports Jinja code blocks, shell commands, as well as PDL code blocks for meta-cycle programming. For more examples, see
365+
([Jinja code](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/code_jinja.pdl)),
366+
([shell command](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/code_command.pdl)),
367+
([PDL code](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/code_pdl.pdl)).
353368

354369
## Calling REST APIs
355370

356-
PDL programs can contain calls to REST APIs with Python code. Consider a simple weather app ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/calling_apis.pdl)):
371+
PDL programs can contain calls to REST APIs with Python code. Consider a simple weather app ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/weather.pdl)):
357372

358373
```yaml
359-
--8<-- "./examples/tutorial/calling_apis.pdl"
374+
--8<-- "./examples/tutorial/programs/weather.pdl"
360375
```
361376

362377
In this program, we first define a query about the weather in some location (assigned to variable `QUERY`). The next block is a call to a Granite model with few-shot examples to extract the location, which we assign to variable `LOCATION`. The next block makes an API call with Python (mocked in this example). Here the `LOCATION` is appended to the `url`. The result is a JSON object, which may be hard to interpret for a human user. So we make a final call to an LLM to interpret the JSON in terms of weather. Notice that many blocks have `contribute` set to `[]` to hide intermediate results.
363378

364379

365380
## Data Block
366381

367-
PDL offers the ability to create JSON data as illustrated by the following example (described in detail in the [Overview](https://ibm.github.io/prompt-declaration-language/#overview) section). The `data` block can gather previously defined variables into a JSON structure. This feature is useful for data generation. Programs such as this one can be generalized to read jsonl files to generate data en masse by piping into another jsonl file ([file](https://github.com/IBM/prompt-declaration-language/blob/main/examples/tutorial/data_block.pdl)).
382+
PDL offers the ability to create JSON data as illustrated by the following example (described in detail in the [Overview](https://ibm.github.io/prompt-declaration-language/#overview) section). The `data` block can gather previously defined variables into a JSON structure. This feature is useful for data generation. Programs such as this one can be generalized to read jsonl files to generate data en masse by piping into another jsonl file ([file](https://github.com/IBM/prompt-declaration-language/blob/main/examples/tutorial/programs/code-json.pdl)).
368383

369384
```yaml
370-
--8<-- "./examples/tutorial/data_block.pdl"
385+
--8<-- "./examples/tutorial/programs/code-json.pdl"
371386
```
372387

373388
Notice that in the `data` block the values are interpreted as Jinja expressions. If values need to be PDL programs to be interpreted, then you need to use
@@ -409,11 +424,11 @@ The `import` block means that the PDL code at that file is executed and its scop
409424

410425
## Conditionals and Loops
411426

412-
PDL supports conditionals and loops as illustrated in the following example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/conditionals_loops.pdl)), which implements a chatbot.
427+
PDL supports conditionals and loops as illustrated in the following example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/chatbot.pdl)), which implements a chatbot.
413428

414429

415430
```yaml
416-
--8<-- "./examples/tutorial/conditionals_loops.pdl"
431+
--8<-- "./examples/tutorial/programs/chatbot.pdl"
417432
```
418433

419434
The first block prompts the user for a query, and this is contributed to the background context. The next
@@ -432,6 +447,8 @@ Notice that the `repeat` and `then` blocks are followed by `text`. This is becau
432447
The way that the result of each iteration is collated with other iterations can be customized in PDL using
433448
the `join` feature (see the following section).
434449

450+
Another simple example of using an `if` statement is [this](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/if.pdl).
451+
435452
### For Loops
436453

437454
PDL also offers `for` loops over lists.
@@ -536,7 +553,7 @@ as soon as one of the exit conditions is satisfied:
536553
### Match block
537554

538555
PDL provides a match block for convenience.
539-
Consider the [example](https://github.com/IBM/prompt-declaration-language//blob/main/examples/intrinsics/demo-hallucination.pdl). This shows retrieved RAG documents
556+
Consider the [example](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/demo-hallucination.pdl). This shows retrieved RAG documents
540557
that are then submitted with a query to a RAG Granite model.
541558
The output contains an answer to the query together with hallucination
542559
score and possibly a citation.
@@ -565,7 +582,7 @@ The `match` field indicates an expression to match on. The cases follow the `wit
565582

566583
## Roles and Chat Templates
567584

568-
Consider again the chatbot example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/conditionals_loops.pdl)). By default blocks have role `user`, except for model call blocks, which have role `assistant`.
585+
Consider again the chatbot example ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/programs/chatbot.pdl)). By default blocks have role `user`, except for model call blocks, which have role `assistant`.
569586
If we write roles explicitly for the chatbot, we obtain:
570587

571588

@@ -624,12 +641,12 @@ parameters:
624641

625642
## Type Checking
626643

627-
Consider the following PDL program ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/gen-data.pdl)). It first reads the data
628-
found [here](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/gen-data.yaml) to form few-shot examples. These demonstrations show how to create
644+
Consider the following PDL program ([file](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/type_checking.pdl)). It first reads the data
645+
found [here](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/type_checking_data.yaml) to form few-shot examples. These demonstrations show how to create
629646
some JSON data.
630647

631648
```yaml
632-
--8<-- "./examples/tutorial/gen-data.pdl"
649+
--8<-- "./examples/tutorial/type_checking.pdl"
633650
```
634651

635652
Upon reading the data we use a parser to parse it into a YAML. The `spec` field indicates the expected type for the
@@ -641,9 +658,9 @@ Similarly, the output of the model call is parsed as YAML, and the `spec` indica
641658

642659
When we run this program, we obtain the output:
643660
```
644-
gen-data.pdl:8 - Type errors during spec checking:
645-
gen-data.pdl:8 - 30 should be of type <class 'int'>
646661
{'name': 'John', 'age': '30'}
662+
type_checking.pdl:9 - Type errors during spec checking:
663+
type_checking.pdl:9 - twentyfive should be of type <class 'int'>
647664
```
648665

649666
Notice that since we asked the age to be produced in letters, we got a string back and this causes a type error indicated above.
@@ -670,9 +687,24 @@ the examples below:
670687
- `[{question: str, answer: str}]`: same as above
671688
- `{enum: [red, green, blue]}`: an enumeration
672689

690+
Another example of type checking a list can be found [here](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/type_list.pdl).
691+
673692
## Structured Decoding
674693

675-
When a type is specified in a PDL block, it is used for structured decoding with models that support it. The fields `guided_json` and `response_format` are added automatically by the interpreter with a JSON Schema value obtained from the type. Models that support structured decoding will then use this to generate JSON of the correct format.
694+
When a type is specified in a PDL block, it is used for structured decoding with models that support it. The fields `guided_json` and `response_format` are added automatically by the interpreter with a JSON Schema value obtained from the type. Models on platforms that support structured decoding will then use this to generate JSON of the correct format.
695+
696+
The following [program](https://github.com/IBM/prompt-declaration-language//blob/main/examples/tutorial/structured-decoding.pdl):
697+
698+
```yaml
699+
--8<-- "./examples/tutorial/structured_decoding.pdl"
700+
```
701+
702+
produces the output:
703+
```
704+
705+
What is the color of the sky?
706+
{'color': 'blue'}
707+
```
676708

677709
## Python SDK
678710

examples/code/code-json.pdl

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ defs:
55
parser: yaml
66
TRUTH:
77
read: ./ground_truth.txt
8-
text:
8+
lastOf:
99
- model: ollama_chat/granite3.2:2b
1010
def: EXPLANATION
11-
contribute: []
1211
input:
1312
|
1413
Here is some info about the location of the function in the repo.
@@ -21,10 +20,7 @@ text:
2120
Explain the following code:
2221
```
2322
${ CODE.source_code }```
24-
parameters:
25-
temperature: 0
2623
- def: EVAL
27-
contribute: []
2824
lang: python
2925
code:
3026
|
@@ -35,7 +31,6 @@ text:
3531
truth = """
3632
${ TRUTH }
3733
"""
38-
# (In PDL, set `result` to the output you wish for your code block.)
3934
result = textdistance.levenshtein.normalized_similarity(expl, truth)
4035
- data:
4136
input: ${ CODE }

0 commit comments

Comments
 (0)