Introducing PromptScript(c)
There is a need to easily coordinate information flow/s between AI agents and/or deterministic applications to ensure reliable input/output between indeterministic systems (chaotic systems, such as AI agents or LLM outputs), and, deterministic systems such as traditional turing-style applications. As such, I have implemented a flow control language I call PromptScript(c).
# PromptScript Language Manual
## 1. Purpose
PromptScript is Ngaka’s workflow language. It allows the chatbot planner to convert a user request into a deterministic, executable sequence of module calls.
PromptScript combines:
* ordinary programming logic;
* semantic LLM-assisted conditions;
* typed module inputs and outputs;
* loops and counters;
* progress reporting;
* chatbot feedback;
* Task Manager integration.
The intended execution flow is:
```text
User prompt
→ chatbot planner
→ PromptScript
→ PromptScript interpreter
→ Ngaka modules
→ typed outputs
→ final chatbot response or artefact
```
---
# 2. Basic Syntax
Statements may end with a semicolon:
```text
$counter = 1;
```
Blocks use braces:
```text
if ($counter <= 20) {
$counter++;
}
```
Comments use:
```text
// This is a comment
```
Variables begin with `$`:
```text
$prompt
$image
$result
$counter
```
---
# 3. Built-in Variables
The interpreter provides standard variables.
```text
$prompt
```
The current user prompt.
```text
$conversation
```
Relevant conversation context.
```text
$file
```
The currently supplied file, where applicable.
```text
$files
```
A collection of supplied or selected files.
```text
$lastoutput
```
The output returned by the most recently executed module.
```text
$error
```
The most recent interpreter or module error.
---
# 4. Variable Assignment
```text
$counter = 1;
$name = "Report";
$complete = false;
```
Variables may contain:
* strings;
* numbers;
* booleans;
* JSON objects;
* arrays;
* file references;
* images;
* code;
* module results.
Example:
```text
$message = "Generating image " + $counter;
```
---
# 5. Deterministic Operators
These operators do not invoke an LLM.
```text
== exactly equal
!= not equal
< less than
<= less than or equal
> greater than
>= greater than or equal
&& logical AND
|| logical OR
! logical NOT
```
Example:
```text
if ($counter == 20) {
complete;
}
```
String comparison is exact:
```text
if ($language == "en") {
feedback("The prompt is already English.");
}
```
---
# 6. Semantic Operators
Semantic operators use a fast LLM to interpret meaning.
```text
~= means something like ; you can also say "like"
!~= does not mean something like
```
Example:
```text
if ($prompt ~= "create a picture of something") {
give $prompt to image_generator.mod as $image;
}
```
This does not require the user to say the exact words “create a picture”.
The following prompts may all match:
```text
Draw a cat.
Generate an image of Johannesburg.
Make me a poster.
Create an illustration of a courtroom.
```
By contrast:
```text
if ($prompt == "create a picture") {
```
matches only the exact string.
Semantic comparisons should be used only where ordinary deterministic comparisons are insufficient.
---
# 7. Conditional Logic
## 7.1 `if`
```text
if ($result.success == true) {
feedback("The operation succeeded.");
}
```
## 7.2 `else`
```text
if ($result.success == true) {
outputJson($result);
} else {
report $result.error;
}
```
## 7.3 Semantic conditions
```text
if ($prompt ~= "translate this into another language") {
give $prompt to translate.mod as $translation;
}
```
## 7.4 Combined conditions
```text
if ($prompt ~= "make an image" && $file == null) {
give $prompt to image_generator.mod as $image;
}
```
---
# 8. Module Execution
The core execution statement is:
```text
give INPUT to MODULE as VARIABLE;
```
Example:
```text
give $prompt to image_generator.mod as $image;
```
The module result is stored in `$image`.
A standard module result should provide:
```text
$image.success
$image.output
$image.error
$image.type
$image.metadata
```
Example:
```text
if ($image.success == true) {
give $image.output to chatbot_ngaka.mod;
} else {
report $image.error;
}
```
---
# 9. Module Offers
PromptScript executes registered Ngaka module offers.
An offer should describe:
```text
module
function
input type
output type
parameters
source
```
Typical output types include:
```text
text
json
image
file
document
code
map_link
coordinates
audio
video
html
```
Examples:
```text
image_generator.mod
input: text
output: image
```
```text
translate.mod
input: text
output: text
```
```text
latex.mod
input: text
output: image
```
```text
maps.mod
input: coordinates
output: map_link
```
```text
coding.mod
input: text
output: code
```
The interpreter must validate that one module’s output is compatible with the next module’s input.
---
# 10. Typed Input
PromptScript supports explicit input conversion.
## 10.1 JSON
```text
$data = takeInJson();
```
## 10.2 Text
```text
$text = takeInText();
```
## 10.3 Image
```text
$image = takeInImage();
```
## 10.4 File
```text
$file = takeInFile();
```
## 10.5 Binary data
```text
$data = takeInBinary();
```
The interpreter should reject incompatible input before running a workflow.
Example:
```text
$image = takeInImage();
give $image to translate.mod;
```
This should fail validation because a translator expects text rather than an image.
---
# 11. Typed Output
## 11.1 JSON
```text
outputJson($result);
```
## 11.2 Text
```text
outputText($translation);
```
## 11.3 Image
```text
outputImage($image);
```
## 11.4 File
```text
outputFile($document);
```
## 11.5 Binary data
```text
outputBinary($data);
```
The output command defines what the calling module or chatbot receives.
---
# 12. Loops
Loops are a required part of PromptScript.
## 12.1 `while`
```text
$counter = 1;
while ($counter <= 20) {
feedback("Processing item " + $counter);
$counter++;
}
```
## 12.2 `repeat`
```text
repeat 10 {
give $prompt to image_generator.mod as $image;
}
```
## 12.3 `foreach`
```text
foreach $file in $files {
give $file to unpack.mod as $text;
}
```
## 12.4 Increment and decrement
```text
$counter++;
$counter--;
```
## 12.5 `break`
Stops the current loop:
```text
if ($result.success == false) {
break;
}
```
## 12.6 `continue`
Skips to the next iteration:
```text
if ($file.type != "pdf") {
continue;
}
```
---
# 13. Example Loop
```text
$counter = 1;
startProgress();
while ($counter <= 20) {
updateprogress(
($counter / 20) * 100,
"Generating image " + $counter + " of 20"
);
give $prompt + " variation " + $counter
to image_generator.mod
as $image;
if ($image.success == false) {
endProgress(false);
report $image.error;
break;
}
$counter++;
}
endProgress(true);
complete;
```
The interpreter must check for cancellation before every module call and on every loop iteration.
---
# 14. Progress Functions
PromptScript uses Ngaka’s existing progress functions.
## 14.1 Start progress
```text
startProgress();
```
Starts progress polling and displays the progress window.
## 14.2 Update progress
```text
updateprogress(45, "Running OCR...");
```
Parameters:
```text
percentage
message
```
## 14.3 End successfully
```text
endProgress(true);
```
## 14.4 End unsuccessfully
```text
endProgress(false);
```
Example:
```text
startProgress();
updateprogress(10, "Reading files...");
updateprogress(50, "Summarising...");
updateprogress(90, "Creating document...");
endProgress(true);
```
---
# 15. Busy Indicator
For short-running operations, PromptScript may use the existing Ngaka busy indicator.
```text
busythrobber(on);
```
```text
busythrobber(off);
```
Example:
```text
busythrobber(on);
give $prompt to translate.mod as $translation;
busythrobber(off);
outputText($translation.output);
```
The interpreter should ensure the busy indicator is turned off when a workflow fails or terminates unexpectedly.
---
# 16. Chatbot Feedback
The `feedback()` command immediately sends a speech bubble to the main chatbot while the workflow continues.
```text
feedback("I am analysing the document.");
```
Example:
```text
feedback("I found five documents. I am summarising them now.");
foreach $file in $files {
give $file to summariser.mod as $summary;
}
```
This is useful when a full progress bar is unnecessary.
The programmer may use:
```text
feedback()
```
for conversational updates,
```text
busythrobber()
```
for short delays, or
```text
startProgress()
updateprogress()
endProgress()
```
for lengthy operations.
These may be combined.
---
# 17. Task Manager
PromptScript can open the Ngaka Task Manager:
```text
opentaskmanager;
```
or:
```text
opentaskmanager();
```
The interpreter should translate this into the existing Task Manager open function.
---
# 18. LLM Task Registration
Any module offer originating from an `<ai>` manifest offer is treated as an LLM-backed task.
Before executing an AI offer, the interpreter must:
1. register the process;
2. create or associate a progress file;
3. make the task visible in Task Manager;
4. provide the actual process ID;
5. periodically update its heartbeat;
6. remove or complete the task when finished.
The existing Ngaka functions include:
```php
ai_task_start()
ai_task_progress()
ai_task_touch()
ai_task_register_pid()
ai_task_finish()
ai_task_fail()
ai_task_cancelled()
ai_process_add()
ai_process_update()
ai_process_remove()
```
PromptScript programmers do not need to call these functions directly.
Example source:
```text
give $prompt to summariser.mod as $summary;
```
Interpreter behaviour:
```text
Detect that summariser.mod offer source is <ai>
→ register task
→ execute module
→ update task
→ finish or fail task
```
Non-AI offers do not need LLM task registration.
---
# 19. Cancellation
PromptScript must check whether cancellation has been requested:
* before each module call;
* before every loop iteration;
* after a long-running child process;
* before launching another AI task.
Conceptual behaviour:
```text
if task cancelled {
stop current child process;
mark task cancelled;
stop workflow;
}
```
A cancelled workflow must not call `endProgress(true)`.
---
# 20. Completion and Errors
## 20.1 `complete`
Ends the workflow successfully.
```text
complete;
```
## 20.2 `report`
Returns an error or explanatory message.
```text
report "No matching files were found.";
```
A variable may also be reported:
```text
report $result.error;
```
## 20.3 `return`
Returns a value to the caller:
```text
return $result;
```
## 20.4 Failure example
```text
if ($image.success == false) {
busythrobber(off);
endProgress(false);
report $image.error;
}
```
---
# 21. Accessing Result Properties
Module results use dot notation:
```text
$result.success
$result.output
$result.error
$result.type
$result.metadata
```
JSON fields may also be accessed with dot notation:
```text
$person.name
$document.pages
$document.entities[0].name
```
Example:
```text
$data = takeInJson();
if ($data.language == "af") {
give $data.text to translate.mod as $translation;
}
```
---
# 22. Strings
Strings use quotation marks:
```text
$message = "Generating document";
```
Concatenation uses `+`:
```text
$message = "Processing file " + $counter;
```
Example:
```text
feedback(
"Generating image " + $counter + " of " + $total
);
```
---
# 23. Arrays
Arrays may be created directly:
```text
$languages = ["en", "af", "zu"];
```
Access an item:
```text
$languages[0]
```
Iterate:
```text
foreach $language in $languages {
give $prompt to translate.mod as $translation
with language=$language;
}
```
Module outputs may also return arrays:
```text
$files = $search.output.files;
```
---
# 24. Module Parameters
Parameters may be supplied with `with`.
```text
give $prompt to translate.mod as $translation
with source="en", target="zu";
```
Another example:
```text
give $prompt to image_generator.mod as $image
with width=1024,
height=1024,
steps=20;
```
Parameters should be validated against the registered offer before execution.
---
# 25. Example: Generate an Image
```text
if ($prompt ~= "create a picture") {
busythrobber(on);
feedback("I am generating the image.");
give $prompt to image_generator.mod as $image;
busythrobber(off);
if ($image.success == true) {
outputImage($image.output);
complete;
} else {
report $image.error;
}
}
```
---
# 26. Example: Generate and Edit an Image
```text
if ($prompt ~= "create a dark image") {
startProgress();
updateprogress(10, "Generating the original image.");
give $prompt to image_generator.mod as $image;
if ($image.success == false) {
endProgress(false);
report $image.error;
}
updateprogress(60, "Darkening the image.");
give $image.output to image_editor.mod as $edited
with instruction="make the image darker";
if ($edited.success == false) {
endProgress(false);
report $edited.error;
}
updateprogress(100, "Image complete.");
endProgress(true);
outputImage($edited.output);
complete;
}
```
---
# 27. Example: Equation in a Word Document
```text
if ($prompt ~= "create a Word document containing an equation") {
startProgress();
updateprogress(20, "Rendering the equation.");
give $prompt to latex.mod as $equation;
if ($equation.success == false) {
endProgress(false);
report $equation.error;
}
updateprogress(60, "Creating the Word document.");
give $equation.output to document_generator.mod as $document
with format="docx";
if ($document.success == false) {
endProgress(false);
report $document.error;
}
endProgress(true);
outputFile($document.output);
complete;
}
```
---
# 28. Example: Translate Multiple Files
```text
$files = takeInJson();
$counter = 0;
$total = $files.length;
startProgress();
foreach $file in $files {
$counter++;
updateprogress(
($counter / $total) * 100,
"Translating " + $file.name
);
give $file to unpack.mod as $text;
if ($text.success == false) {
feedback("Unable to read " + $file.name);
continue;
}
give $text.output to translate.mod as $translation
with target="zu";
if ($translation.success == false) {
feedback("Unable to translate " + $file.name);
continue;
}
give $translation.output to file_writer.mod as $saved
with filename=$file.name + "-zu.txt";
}
endProgress(true);
complete;
```
---
# 29. Example: Map Request
```text
if ($prompt ~= "show a place on a map") {
give $prompt to geocoder.mod as $location;
if ($location.success == false) {
report "I could not determine the location.";
}
give $location.output to maps.mod as $map;
if ($map.success == true) {
outputJson({
"type": "map_link",
"url": $map.output
});
complete;
}
report $map.error;
}
```
---
# 30. Example: Generate Code
```text
if ($prompt ~= "write computer code") {
feedback("I am generating the code.");
give $prompt to coding.mod as $code;
if ($code.success == true) {
outputJson({
"type": "code",
"language": $code.metadata.language,
"content": $code.output
});
complete;
}
report $code.error;
}
```
The chatbot renderer may then place the returned code inside backticks.
---
# 31. Validation Rules
Before execution, the PromptScript interpreter should validate:
* syntax;
* matching braces;
* declared variables;
* valid operators;
* registered modules;
* registered module functions;
* required module parameters;
* input and output type compatibility;
* loop limits;
* unsupported commands;
* unavailable files;
* invalid JSON;
* forbidden direct system calls.
No workflow should start until validation succeeds.
---
# 32. Safety Limits
The interpreter should enforce configurable limits:
```text
maximum loop iterations
maximum module calls
maximum execution time
maximum nested block depth
maximum generated files
maximum AI calls
maximum output size
```
A `while` loop must not run forever.
Example:
```text
while ($counter <= 20) {
```
is valid.
An unbounded loop should be rejected or terminated:
```text
while (true) {
```
unless an administrator explicitly permits it and the loop contains a provable terminating condition.
---
# 33. Security Model
PromptScript must not directly execute:
* shell commands;
* arbitrary PHP;
* arbitrary JavaScript;
* SQL;
* filesystem paths outside the user’s permitted area;
* unregistered module functions.
All module execution must go through the Ngaka registry.
PromptScript should be an allow-listed interpreter, not an `eval()` wrapper.
---
# 34. Initial Reserved Words
```text
if
else
while
repeat
foreach
in
break
continue
give
to
as
with
return
report
complete
true
false
null
```
Built-in functions:
```text
takeInJson
takeInText
takeInImage
takeInFile
takeInBinary
outputJson
outputText
outputImage
outputFile
outputBinary
feedback
busythrobber
startProgress
updateprogress
endProgress
opentaskmanager
```
---
# 35. Initial Operator Set
```text
=
+
-
*
/
%
++
--
==
!=
<
<=
>
>=
&&
||
!
~=
!~=
```
---
# 36. Recommended Result Format
Every module call should return a standard object:
```json
{
"success": true,
"type": "image",
"output": "uploads/user/images/result.png",
"error": "",
"metadata": {
"width": 1024,
"height": 1024
}
}
```
Failure:
```json
{
"success": false,
"type": "error",
"output": null,
"error": "Image generation failed.",
"metadata": {}
}
```
This standard result format is central to reliable multi-stage workflows.
---
# 37. Status
PromptScript is currently a language design specification. The exact parser, interpreter, module adapter and planner-generation prompt still need to be implemented.
The first implementation should support:
```text
variables
if / else
while
repeat
foreach
break
continue
give ... to ... as ...
with parameters
==
!=
<
<=
>
>=
&&
||
~=
!~=
typed input/output
feedback
busythrobber
progress functions
Task Manager integration
complete
report
return
```
Later versions may add:
```text
parallel execution
functions
imports
saved workflows
scheduled workflows
events
transactions
retry policies
timeouts
user-defined types
```
PromptScript’s key design principle is:
> Use deterministic execution wherever possible, and invoke an LLM only where semantic judgement is explicitly requested.
```