thoth-plugin 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -1
- package/defaults/skill/cal-grid/SKILL.md +168 -0
- package/defaults/skill/cal-grid/cal-grid-template.md +106 -0
- package/defaults/skill/context-discovery/SKILL.md +253 -0
- package/defaults/skill/context-discovery/discovery.prose +143 -0
- package/defaults/skill/context-onboarding/SKILL.md +370 -0
- package/{dist/defaults/skill/_legacy/email-draft/skill.md → defaults/skill/email-draft/SKILL.md} +33 -30
- package/defaults/skill/evening-close/SKILL.md +93 -61
- package/defaults/skill/evening-close/evening-close-template.md +42 -0
- package/{dist/defaults/skill/_legacy → defaults/skill}/gardener/SKILL.md +3 -3
- package/{dist/defaults/skill/_legacy → defaults/skill}/google-chat-scan/SKILL.md +7 -0
- package/{dist/defaults/skill/_legacy → defaults/skill}/leadership-coach/SKILL.md +9 -8
- package/defaults/skill/mail-triage/SKILL.md +272 -15
- package/defaults/skill/mail-triage/mail-triage-template.md +90 -0
- package/defaults/skill/morning-boot/SKILL.md +214 -25
- package/defaults/skill/morning-boot/daily-log-template.md +98 -0
- package/defaults/skill/morning-boot/morning-boot.prose +98 -0
- package/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
- package/defaults/skill/open-prose/SKILL.md +373 -0
- package/defaults/skill/open-prose/antipatterns.md +852 -0
- package/defaults/skill/open-prose/docs.md +2676 -0
- package/defaults/skill/open-prose/patterns.md +610 -0
- package/defaults/skill/open-prose/prose.md +950 -0
- package/{dist/defaults/skill/_legacy → defaults/skill}/post-meeting-drill/SKILL.md +90 -95
- package/defaults/skill/post-meeting-drill/examples.md +130 -0
- package/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
- package/defaults/skill/skill-generator/SKILL.md +217 -0
- package/defaults/skill/skill-generator/skill-template.md +163 -0
- package/defaults/skill/slack-pulse/SKILL.md +211 -14
- package/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
- package/defaults/skill/slack-write/skill.md +184 -0
- package/defaults/skill/thought-router/SKILL.md +7 -8
- package/dist/cli.js +137 -3
- package/dist/config/schema.d.ts +0 -2
- package/dist/defaults/skill/cal-grid/SKILL.md +168 -0
- package/dist/defaults/skill/cal-grid/cal-grid-template.md +106 -0
- package/dist/defaults/skill/context-discovery/SKILL.md +253 -0
- package/dist/defaults/skill/context-discovery/discovery.prose +143 -0
- package/dist/defaults/skill/context-onboarding/SKILL.md +370 -0
- package/{defaults/skill/_legacy/email-draft/skill.md → dist/defaults/skill/email-draft/SKILL.md} +33 -30
- package/dist/defaults/skill/evening-close/SKILL.md +93 -61
- package/dist/defaults/skill/evening-close/evening-close-template.md +42 -0
- package/{defaults/skill/_legacy → dist/defaults/skill}/gardener/SKILL.md +3 -3
- package/{defaults/skill/_legacy → dist/defaults/skill}/google-chat-scan/SKILL.md +7 -0
- package/{defaults/skill/_legacy → dist/defaults/skill}/leadership-coach/SKILL.md +9 -8
- package/dist/defaults/skill/mail-triage/SKILL.md +272 -15
- package/dist/defaults/skill/mail-triage/mail-triage-template.md +90 -0
- package/dist/defaults/skill/morning-boot/SKILL.md +214 -25
- package/dist/defaults/skill/morning-boot/daily-log-template.md +98 -0
- package/dist/defaults/skill/morning-boot/morning-boot.prose +98 -0
- package/dist/defaults/skill/{_legacy/onboarding → onboarding}/SKILL.md +7 -6
- package/dist/defaults/skill/open-prose/SKILL.md +373 -0
- package/dist/defaults/skill/open-prose/antipatterns.md +852 -0
- package/dist/defaults/skill/open-prose/docs.md +2676 -0
- package/dist/defaults/skill/open-prose/patterns.md +610 -0
- package/dist/defaults/skill/open-prose/prose.md +950 -0
- package/{defaults/skill/_legacy → dist/defaults/skill}/post-meeting-drill/SKILL.md +90 -95
- package/dist/defaults/skill/post-meeting-drill/examples.md +130 -0
- package/dist/defaults/skill/post-meeting-drill/post-meeting-drill-template.md +111 -0
- package/dist/defaults/skill/skill-generator/SKILL.md +217 -0
- package/dist/defaults/skill/skill-generator/skill-template.md +163 -0
- package/dist/defaults/skill/slack-pulse/SKILL.md +211 -14
- package/dist/defaults/skill/slack-pulse/slack-pulse-template.md +98 -0
- package/dist/defaults/skill/slack-write/skill.md +184 -0
- package/dist/defaults/skill/thought-router/SKILL.md +7 -8
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +26 -189
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/sentinel-service.d.ts +0 -1
- package/dist/sdk/test-harness.d.ts +90 -0
- package/dist/sdk/thoth-client.d.ts +1 -0
- package/dist/shared/index.d.ts +0 -1
- package/dist/specialization/prompt-sections.d.ts +1 -1
- package/package.json +1 -1
- package/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
- package/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
- package/dist/defaults/skill/_legacy/cal-grid/SKILL.md +0 -16
- package/dist/defaults/skill/_legacy/skill-generator/SKILL.md +0 -362
- package/dist/hooks/temporal-awareness.d.ts +0 -31
- package/dist/hooks/temporal-awareness.test.d.ts +0 -1
- /package/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
- /package/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
- /package/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
- /package/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
- /package/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/capsule-init → capsule-init}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/cross-linker → cross-linker}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/gardener → gardener}/confidence-tiers.md +0 -0
- /package/dist/defaults/skill/{_legacy/gardener → gardener}/repair-workflow.md +0 -0
- /package/dist/defaults/skill/{_legacy/handover → handover}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/interview-prep → interview-prep}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/link-retrofit → link-retrofit}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/restore-environment → restore-environment}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/scorecard-synthesis → scorecard-synthesis}/SKILL.md +0 -0
- /package/dist/defaults/skill/{_legacy/skill-generator → skill-generator}/testing-protocol.md +0 -0
- /package/dist/defaults/skill/{_legacy/system-init → system-init}/SKILL.md +0 -0
|
@@ -0,0 +1,2676 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: language-specification
|
|
3
|
+
summary: |
|
|
4
|
+
Complete syntax grammar, validation rules, and compilation semantics for OpenProse.
|
|
5
|
+
Read this file when compiling, validating, or resolving ambiguous syntax. Assumes
|
|
6
|
+
prose.md is already in context for execution semantics.
|
|
7
|
+
see-also:
|
|
8
|
+
- SKILL.md: Activation triggers, onboarding, telemetry
|
|
9
|
+
- prose.md: Execution semantics, how to run programs
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OpenProse Language Reference
|
|
13
|
+
|
|
14
|
+
OpenProse is a programming language for AI sessions. An AI session is a Turing-complete computer; this document provides complete documentation for the language syntax, semantics, and execution model.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Document Purpose: Compiler + Validator
|
|
19
|
+
|
|
20
|
+
This document serves a dual role:
|
|
21
|
+
|
|
22
|
+
### As Compiler
|
|
23
|
+
|
|
24
|
+
When asked to "compile" a `.prose` file, use this specification to:
|
|
25
|
+
|
|
26
|
+
1. **Parse** the program according to the syntax grammar
|
|
27
|
+
2. **Validate** that the program is well-formed and semantically valid
|
|
28
|
+
3. **Transform** the program into "best practice" canonical form:
|
|
29
|
+
- Expand syntax sugar where appropriate
|
|
30
|
+
- Normalize formatting and structure
|
|
31
|
+
- Apply optimizations (e.g., hoisting block definitions)
|
|
32
|
+
|
|
33
|
+
### As Validator
|
|
34
|
+
|
|
35
|
+
The validation criterion: **Would a blank agent with only `prose.md` understand this program as self-evident?**
|
|
36
|
+
|
|
37
|
+
When validating, check:
|
|
38
|
+
|
|
39
|
+
- Syntax correctness (all constructs match grammar)
|
|
40
|
+
- Semantic validity (references resolve, types match)
|
|
41
|
+
- Self-evidence (program is clear without this full spec)
|
|
42
|
+
|
|
43
|
+
If a construct is ambiguous or non-obvious, it should be flagged or transformed into a clearer form.
|
|
44
|
+
|
|
45
|
+
### When to Read This Document
|
|
46
|
+
|
|
47
|
+
- **Compilation requested**: Read fully to apply all rules
|
|
48
|
+
- **Validation requested**: Read fully to check all constraints
|
|
49
|
+
- **Ambiguous syntax encountered**: Reference specific sections
|
|
50
|
+
- **Interpretation only**: Use `prose.md` instead (smaller, faster)
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Table of Contents
|
|
55
|
+
|
|
56
|
+
1. [Overview](#overview)
|
|
57
|
+
2. [File Format](#file-format)
|
|
58
|
+
3. [Comments](#comments)
|
|
59
|
+
4. [String Literals](#string-literals)
|
|
60
|
+
5. [Import Statements](#import-statements)
|
|
61
|
+
6. [Agent Definitions](#agent-definitions)
|
|
62
|
+
7. [Session Statement](#session-statement)
|
|
63
|
+
8. [Variables & Context](#variables--context)
|
|
64
|
+
9. [Composition Blocks](#composition-blocks)
|
|
65
|
+
10. [Parallel Blocks](#parallel-blocks)
|
|
66
|
+
11. [Fixed Loops](#fixed-loops)
|
|
67
|
+
12. [Unbounded Loops](#unbounded-loops)
|
|
68
|
+
13. [Pipeline Operations](#pipeline-operations)
|
|
69
|
+
14. [Error Handling](#error-handling)
|
|
70
|
+
15. [Choice Blocks](#choice-blocks)
|
|
71
|
+
16. [Conditional Statements](#conditional-statements)
|
|
72
|
+
17. [Execution Model](#execution-model)
|
|
73
|
+
18. [Validation Rules](#validation-rules)
|
|
74
|
+
19. [Examples](#examples)
|
|
75
|
+
20. [Future Features](#future-features)
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Overview
|
|
80
|
+
|
|
81
|
+
OpenProse provides a declarative syntax for defining multi-agent workflows. Programs consist of statements that are executed sequentially, with each `session` statement spawning a subagent to complete a task.
|
|
82
|
+
|
|
83
|
+
### Design Principles
|
|
84
|
+
|
|
85
|
+
- **Pattern over framework**: The simplest solution is barely anything at all—just structure for English
|
|
86
|
+
- **Self-evident**: Programs should be understandable with minimal documentation
|
|
87
|
+
- **The OpenProse VM is intelligent**: Design for understanding, not parsing
|
|
88
|
+
- **Framework-agnostic**: Works with Claude Code, OpenCode, and any future agent framework
|
|
89
|
+
- **Files are artifacts**: `.prose` is the portable unit of work
|
|
90
|
+
|
|
91
|
+
### Current Implementation Status
|
|
92
|
+
|
|
93
|
+
The following features are implemented:
|
|
94
|
+
|
|
95
|
+
| Feature | Status | Description |
|
|
96
|
+
| ---------------------- | ----------- | ---------------------------------------------- |
|
|
97
|
+
| Comments | Implemented | `# comment` syntax |
|
|
98
|
+
| Single-line strings | Implemented | `"string"` with escapes |
|
|
99
|
+
| Simple session | Implemented | `session "prompt"` |
|
|
100
|
+
| Agent definitions | Implemented | `agent name:` with model/prompt properties |
|
|
101
|
+
| Session with agent | Implemented | `session: agent` with property overrides |
|
|
102
|
+
| Import statements | Implemented | `import "skill" from "source"` |
|
|
103
|
+
| Agent skills | Implemented | `skills: ["skill1", "skill2"]` |
|
|
104
|
+
| Agent permissions | Implemented | `permissions:` block with rules |
|
|
105
|
+
| Let binding | Implemented | `let name = session "..."` |
|
|
106
|
+
| Const binding | Implemented | `const name = session "..."` |
|
|
107
|
+
| Variable reassignment | Implemented | `name = session "..."` (for let only) |
|
|
108
|
+
| Context property | Implemented | `context: var` or `context: [a, b, c]` |
|
|
109
|
+
| do: blocks | Implemented | Explicit sequential blocks |
|
|
110
|
+
| Inline sequence | Implemented | `session "A" -> session "B"` |
|
|
111
|
+
| Named blocks | Implemented | `block name:` with `do name` invocation |
|
|
112
|
+
| Parallel blocks | Implemented | `parallel:` for concurrent execution |
|
|
113
|
+
| Named parallel results | Implemented | `x = session "..."` inside parallel |
|
|
114
|
+
| Object context | Implemented | `context: { a, b, c }` shorthand |
|
|
115
|
+
| Join strategies | Implemented | `parallel ("first"):` or `parallel ("any"):` |
|
|
116
|
+
| Failure policies | Implemented | `parallel (on-fail: "continue"):` |
|
|
117
|
+
| Repeat blocks | Implemented | `repeat N:` fixed iterations |
|
|
118
|
+
| Repeat with index | Implemented | `repeat N as i:` with index variable |
|
|
119
|
+
| For-each blocks | Implemented | `for item in items:` iteration |
|
|
120
|
+
| For-each with index | Implemented | `for item, i in items:` with index |
|
|
121
|
+
| Parallel for-each | Implemented | `parallel for item in items:` fan-out |
|
|
122
|
+
| Unbounded loop | Implemented | `loop:` with optional max iterations |
|
|
123
|
+
| Loop until | Implemented | `loop until **condition**:` AI-evaluated |
|
|
124
|
+
| Loop while | Implemented | `loop while **condition**:` AI-evaluated |
|
|
125
|
+
| Loop with index | Implemented | `loop as i:` or `loop until ... as i:` |
|
|
126
|
+
| Map pipeline | Implemented | `items \| map:` transform each item |
|
|
127
|
+
| Filter pipeline | Implemented | `items \| filter:` keep matching items |
|
|
128
|
+
| Reduce pipeline | Implemented | `items \| reduce(acc, item):` accumulate |
|
|
129
|
+
| Parallel map | Implemented | `items \| pmap:` concurrent transform |
|
|
130
|
+
| Pipeline chaining | Implemented | `\| filter: ... \| map: ...` |
|
|
131
|
+
| Try/catch blocks | Implemented | `try:` with `catch:` for error handling |
|
|
132
|
+
| Try/catch/finally | Implemented | `finally:` for cleanup |
|
|
133
|
+
| Error variable | Implemented | `catch as err:` access error context |
|
|
134
|
+
| Throw statement | Implemented | `throw` or `throw "message"` |
|
|
135
|
+
| Retry property | Implemented | `retry: 3` automatic retry on failure |
|
|
136
|
+
| Backoff strategy | Implemented | `backoff: "exponential"` delay between retries |
|
|
137
|
+
| Multi-line strings | Implemented | `"""..."""` preserving whitespace |
|
|
138
|
+
| String interpolation | Implemented | `"Hello {name}"` variable substitution |
|
|
139
|
+
| Block parameters | Implemented | `block name(param):` with parameters |
|
|
140
|
+
| Block invocation args | Implemented | `do name(arg)` passing arguments |
|
|
141
|
+
| Choice blocks | Implemented | `choice **criteria**: option "label":` |
|
|
142
|
+
| If/elif/else | Implemented | `if **condition**:` conditional branching |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## File Format
|
|
147
|
+
|
|
148
|
+
| Property | Value |
|
|
149
|
+
| ---------------- | -------------------- |
|
|
150
|
+
| Extension | `.prose` |
|
|
151
|
+
| Encoding | UTF-8 |
|
|
152
|
+
| Case sensitivity | Case-sensitive |
|
|
153
|
+
| Indentation | Spaces (Python-like) |
|
|
154
|
+
| Line endings | LF or CRLF |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Comments
|
|
159
|
+
|
|
160
|
+
Comments provide documentation within programs and are ignored during execution.
|
|
161
|
+
|
|
162
|
+
### Syntax
|
|
163
|
+
|
|
164
|
+
```prose
|
|
165
|
+
# This is a standalone comment
|
|
166
|
+
|
|
167
|
+
session "Hello" # This is an inline comment
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Rules
|
|
171
|
+
|
|
172
|
+
1. Comments begin with `#` and extend to end of line
|
|
173
|
+
2. Comments can appear on their own line or after a statement
|
|
174
|
+
3. Empty comments are valid: `#`
|
|
175
|
+
4. The `#` character inside string literals is NOT a comment
|
|
176
|
+
|
|
177
|
+
### Examples
|
|
178
|
+
|
|
179
|
+
```prose
|
|
180
|
+
# Program header comment
|
|
181
|
+
# Author: Example
|
|
182
|
+
|
|
183
|
+
session "Do something" # Explain what this does
|
|
184
|
+
|
|
185
|
+
# This comment is between statements
|
|
186
|
+
session "Do another thing"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Compilation Behavior
|
|
190
|
+
|
|
191
|
+
Comments are **stripped during compilation**. The OpenProse VM never sees them. They have no effect on execution and exist purely for human documentation.
|
|
192
|
+
|
|
193
|
+
### Important Notes
|
|
194
|
+
|
|
195
|
+
- **Comments inside strings are NOT comments**:
|
|
196
|
+
|
|
197
|
+
```prose
|
|
198
|
+
session "Say hello # this is part of the string"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The `#` inside the string literal is part of the prompt, not a comment.
|
|
202
|
+
|
|
203
|
+
- **Comments inside indented blocks are allowed**:
|
|
204
|
+
```prose
|
|
205
|
+
agent researcher:
|
|
206
|
+
# This comment is inside the block
|
|
207
|
+
model: sonnet
|
|
208
|
+
# This comment is outside the block
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## String Literals
|
|
214
|
+
|
|
215
|
+
String literals represent text values, primarily used for session prompts.
|
|
216
|
+
|
|
217
|
+
### Syntax
|
|
218
|
+
|
|
219
|
+
Strings are enclosed in double quotes:
|
|
220
|
+
|
|
221
|
+
```prose
|
|
222
|
+
"This is a string"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Escape Sequences
|
|
226
|
+
|
|
227
|
+
The following escape sequences are supported:
|
|
228
|
+
|
|
229
|
+
| Sequence | Meaning |
|
|
230
|
+
| -------- | ------------ |
|
|
231
|
+
| `\\` | Backslash |
|
|
232
|
+
| `\"` | Double quote |
|
|
233
|
+
| `\n` | Newline |
|
|
234
|
+
| `\t` | Tab |
|
|
235
|
+
|
|
236
|
+
### Examples
|
|
237
|
+
|
|
238
|
+
```prose
|
|
239
|
+
session "Hello world"
|
|
240
|
+
session "Line one\nLine two"
|
|
241
|
+
session "She said \"hello\""
|
|
242
|
+
session "Path: C:\\Users\\name"
|
|
243
|
+
session "Column1\tColumn2"
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Rules
|
|
247
|
+
|
|
248
|
+
1. Single-line strings must be properly terminated with a closing `"`
|
|
249
|
+
2. Unknown escape sequences are errors
|
|
250
|
+
3. Empty strings `""` are valid but generate a warning when used as prompts
|
|
251
|
+
|
|
252
|
+
### Multi-line Strings
|
|
253
|
+
|
|
254
|
+
Multi-line strings use triple double-quotes (`"""`) and preserve internal whitespace and newlines:
|
|
255
|
+
|
|
256
|
+
```prose
|
|
257
|
+
session """
|
|
258
|
+
This is a multi-line prompt.
|
|
259
|
+
It preserves:
|
|
260
|
+
- Indentation
|
|
261
|
+
- Line breaks
|
|
262
|
+
- All internal whitespace
|
|
263
|
+
"""
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### Multi-line String Rules
|
|
267
|
+
|
|
268
|
+
1. Opening `"""` must be followed by a newline
|
|
269
|
+
2. Content continues until closing `"""`
|
|
270
|
+
3. Escape sequences work the same as single-line strings
|
|
271
|
+
4. Leading/trailing whitespace inside the delimiters is preserved
|
|
272
|
+
|
|
273
|
+
### String Interpolation
|
|
274
|
+
|
|
275
|
+
Strings can embed variable references using `{varname}` syntax:
|
|
276
|
+
|
|
277
|
+
```prose
|
|
278
|
+
let name = session "Get the user's name"
|
|
279
|
+
|
|
280
|
+
session "Hello {name}, welcome to the system!"
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### Interpolation Syntax
|
|
284
|
+
|
|
285
|
+
- Variables are referenced by wrapping the variable name in curly braces: `{varname}`
|
|
286
|
+
- Works in both single-line and multi-line strings
|
|
287
|
+
- Empty braces `{}` are treated as literal text, not interpolation
|
|
288
|
+
- Nested braces are not supported
|
|
289
|
+
|
|
290
|
+
#### Examples
|
|
291
|
+
|
|
292
|
+
```prose
|
|
293
|
+
let research = session "Research the topic"
|
|
294
|
+
let analysis = session "Analyze findings"
|
|
295
|
+
|
|
296
|
+
# Single variable interpolation
|
|
297
|
+
session "Based on {research}, provide recommendations"
|
|
298
|
+
|
|
299
|
+
# Multiple interpolations
|
|
300
|
+
session "Combining {research} with {analysis}, synthesize insights"
|
|
301
|
+
|
|
302
|
+
# Multi-line with interpolation
|
|
303
|
+
session """
|
|
304
|
+
Review Summary:
|
|
305
|
+
- Research: {research}
|
|
306
|
+
- Analysis: {analysis}
|
|
307
|
+
Please provide final recommendations.
|
|
308
|
+
"""
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### Interpolation Rules
|
|
312
|
+
|
|
313
|
+
1. Variable names must be valid identifiers
|
|
314
|
+
2. Referenced variables must be in scope
|
|
315
|
+
3. Empty braces `{}` are literal text
|
|
316
|
+
4. Backslash can escape braces: `\{` produces literal `{`
|
|
317
|
+
|
|
318
|
+
### Validation
|
|
319
|
+
|
|
320
|
+
| Check | Result |
|
|
321
|
+
| -------------------------------- | ------- |
|
|
322
|
+
| Unterminated string | Error |
|
|
323
|
+
| Unknown escape sequence | Error |
|
|
324
|
+
| Empty string as prompt | Warning |
|
|
325
|
+
| Undefined interpolation variable | Error |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Import Statements
|
|
330
|
+
|
|
331
|
+
Import statements load external skills that can be assigned to agents.
|
|
332
|
+
|
|
333
|
+
### Syntax
|
|
334
|
+
|
|
335
|
+
```prose
|
|
336
|
+
import "skill-name" from "source"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Source Types
|
|
340
|
+
|
|
341
|
+
| Source Type | Format | Example |
|
|
342
|
+
| ----------- | --------------------- | ------------------------- |
|
|
343
|
+
| GitHub | `github:user/repo` | `github:anthropic/skills` |
|
|
344
|
+
| NPM | `npm:package` | `npm:@org/analyzer` |
|
|
345
|
+
| Local path | `./path` or `../path` | `./local-skills/my-skill` |
|
|
346
|
+
|
|
347
|
+
### Examples
|
|
348
|
+
|
|
349
|
+
```prose
|
|
350
|
+
# Import from GitHub
|
|
351
|
+
import "web-search" from "github:anthropic/skills"
|
|
352
|
+
|
|
353
|
+
# Import from npm
|
|
354
|
+
import "code-analyzer" from "npm:@company/analyzer"
|
|
355
|
+
|
|
356
|
+
# Import from local path
|
|
357
|
+
import "custom-tool" from "./skills/custom-tool"
|
|
358
|
+
import "shared-skill" from "../common/skills"
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Validation Rules
|
|
362
|
+
|
|
363
|
+
| Check | Severity | Message |
|
|
364
|
+
| --------------------- | -------- | -------------------------------------- |
|
|
365
|
+
| Empty skill name | Error | Import skill name cannot be empty |
|
|
366
|
+
| Empty source | Error | Import source cannot be empty |
|
|
367
|
+
| Duplicate import | Error | Skill already imported |
|
|
368
|
+
| Unknown source format | Warning | Should start with github:, npm:, or ./ |
|
|
369
|
+
|
|
370
|
+
### Execution Semantics
|
|
371
|
+
|
|
372
|
+
Import statements are processed before any agent definitions or sessions. The OpenProse VM:
|
|
373
|
+
|
|
374
|
+
1. Validates all imports at the start of execution
|
|
375
|
+
2. Loads skill definitions from the specified sources
|
|
376
|
+
3. Makes skills available for agent assignment
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Agent Definitions
|
|
381
|
+
|
|
382
|
+
Agents are reusable templates that configure subagent behavior. Once defined, agents can be referenced in session statements.
|
|
383
|
+
|
|
384
|
+
### Syntax
|
|
385
|
+
|
|
386
|
+
```prose
|
|
387
|
+
agent name:
|
|
388
|
+
model: sonnet
|
|
389
|
+
prompt: "System prompt for this agent"
|
|
390
|
+
skills: ["skill1", "skill2"]
|
|
391
|
+
permissions:
|
|
392
|
+
read: ["*.md"]
|
|
393
|
+
bash: deny
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Properties
|
|
397
|
+
|
|
398
|
+
| Property | Type | Values | Description |
|
|
399
|
+
| ------------- | ---------- | ------------------------- | ----------------------------------- |
|
|
400
|
+
| `model` | identifier | `sonnet`, `opus`, `haiku` | The Claude model to use |
|
|
401
|
+
| `prompt` | string | Any string | System prompt/context for the agent |
|
|
402
|
+
| `skills` | array | String array | Skills assigned to this agent |
|
|
403
|
+
| `permissions` | block | Permission rules | Access control for the agent |
|
|
404
|
+
|
|
405
|
+
### Skills Property
|
|
406
|
+
|
|
407
|
+
The `skills` property assigns imported skills to an agent:
|
|
408
|
+
|
|
409
|
+
```prose
|
|
410
|
+
import "web-search" from "github:anthropic/skills"
|
|
411
|
+
import "summarizer" from "./local-skills"
|
|
412
|
+
|
|
413
|
+
agent researcher:
|
|
414
|
+
skills: ["web-search", "summarizer"]
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Skills must be imported before they can be assigned. Referencing an unimported skill generates a warning.
|
|
418
|
+
|
|
419
|
+
### Permissions Property
|
|
420
|
+
|
|
421
|
+
The `permissions` property controls agent access:
|
|
422
|
+
|
|
423
|
+
```prose
|
|
424
|
+
agent secure-agent:
|
|
425
|
+
permissions:
|
|
426
|
+
read: ["*.md", "*.txt"]
|
|
427
|
+
write: ["output/"]
|
|
428
|
+
bash: deny
|
|
429
|
+
network: allow
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### Permission Types
|
|
433
|
+
|
|
434
|
+
| Type | Description |
|
|
435
|
+
| --------- | -------------------------------------------- |
|
|
436
|
+
| `read` | Files the agent can read (glob patterns) |
|
|
437
|
+
| `write` | Files the agent can write (glob patterns) |
|
|
438
|
+
| `execute` | Files the agent can execute (glob patterns) |
|
|
439
|
+
| `bash` | Shell access: `allow`, `deny`, or `prompt` |
|
|
440
|
+
| `network` | Network access: `allow`, `deny`, or `prompt` |
|
|
441
|
+
|
|
442
|
+
#### Permission Values
|
|
443
|
+
|
|
444
|
+
| Value | Description |
|
|
445
|
+
| -------- | ------------------------------------------------- |
|
|
446
|
+
| `allow` | Permission granted |
|
|
447
|
+
| `deny` | Permission denied |
|
|
448
|
+
| `prompt` | Ask user for permission |
|
|
449
|
+
| Array | List of allowed patterns (for read/write/execute) |
|
|
450
|
+
|
|
451
|
+
### Examples
|
|
452
|
+
|
|
453
|
+
```prose
|
|
454
|
+
# Define a research agent
|
|
455
|
+
agent researcher:
|
|
456
|
+
model: sonnet
|
|
457
|
+
prompt: "You are a research assistant skilled at finding and synthesizing information"
|
|
458
|
+
|
|
459
|
+
# Define a writing agent
|
|
460
|
+
agent writer:
|
|
461
|
+
model: opus
|
|
462
|
+
prompt: "You are a technical writer who creates clear, concise documentation"
|
|
463
|
+
|
|
464
|
+
# Agent with only model
|
|
465
|
+
agent quick:
|
|
466
|
+
model: haiku
|
|
467
|
+
|
|
468
|
+
# Agent with only prompt
|
|
469
|
+
agent expert:
|
|
470
|
+
prompt: "You are a domain expert"
|
|
471
|
+
|
|
472
|
+
# Agent with skills
|
|
473
|
+
agent web-researcher:
|
|
474
|
+
model: sonnet
|
|
475
|
+
skills: ["web-search", "summarizer"]
|
|
476
|
+
|
|
477
|
+
# Agent with permissions
|
|
478
|
+
agent file-handler:
|
|
479
|
+
permissions:
|
|
480
|
+
read: ["*.md", "*.txt"]
|
|
481
|
+
write: ["output/"]
|
|
482
|
+
bash: deny
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Model Selection
|
|
486
|
+
|
|
487
|
+
| Model | Use Case |
|
|
488
|
+
| -------- | ------------------------------------- |
|
|
489
|
+
| `haiku` | Fast, simple tasks; quick responses |
|
|
490
|
+
| `sonnet` | Balanced performance; general purpose |
|
|
491
|
+
| `opus` | Complex reasoning; detailed analysis |
|
|
492
|
+
|
|
493
|
+
### Execution Semantics
|
|
494
|
+
|
|
495
|
+
When a session references an agent:
|
|
496
|
+
|
|
497
|
+
1. The agent's `model` property determines which Claude model is used
|
|
498
|
+
2. The agent's `prompt` property is included as system context
|
|
499
|
+
3. Session properties can override agent defaults
|
|
500
|
+
|
|
501
|
+
### Validation Rules
|
|
502
|
+
|
|
503
|
+
| Check | Severity | Message |
|
|
504
|
+
| --------------------- | -------- | ------------------------------ |
|
|
505
|
+
| Duplicate agent name | Error | Agent already defined |
|
|
506
|
+
| Invalid model value | Error | Must be sonnet, opus, or haiku |
|
|
507
|
+
| Empty prompt property | Warning | Consider providing a prompt |
|
|
508
|
+
| Duplicate property | Error | Property already specified |
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Session Statement
|
|
513
|
+
|
|
514
|
+
The session statement is the primary executable construct in OpenProse. It spawns a subagent to complete a task.
|
|
515
|
+
|
|
516
|
+
### Syntax Variants
|
|
517
|
+
|
|
518
|
+
#### Simple Session (with inline prompt)
|
|
519
|
+
|
|
520
|
+
```prose
|
|
521
|
+
session "prompt text"
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### Session with Agent Reference
|
|
525
|
+
|
|
526
|
+
```prose
|
|
527
|
+
session: agentName
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
#### Named Session with Agent
|
|
531
|
+
|
|
532
|
+
```prose
|
|
533
|
+
session sessionName: agentName
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
#### Session with Properties
|
|
537
|
+
|
|
538
|
+
```prose
|
|
539
|
+
session: agentName
|
|
540
|
+
prompt: "Override the agent's default prompt"
|
|
541
|
+
model: opus # Override the agent's model
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Property Overrides
|
|
545
|
+
|
|
546
|
+
When a session references an agent, it can override the agent's properties:
|
|
547
|
+
|
|
548
|
+
```prose
|
|
549
|
+
agent researcher:
|
|
550
|
+
model: sonnet
|
|
551
|
+
prompt: "You are a research assistant"
|
|
552
|
+
|
|
553
|
+
# Use researcher with different model
|
|
554
|
+
session: researcher
|
|
555
|
+
model: opus
|
|
556
|
+
|
|
557
|
+
# Use researcher with different prompt
|
|
558
|
+
session: researcher
|
|
559
|
+
prompt: "Research this specific topic in depth"
|
|
560
|
+
|
|
561
|
+
# Override both
|
|
562
|
+
session: researcher
|
|
563
|
+
model: opus
|
|
564
|
+
prompt: "Specialized research task"
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Execution Semantics
|
|
568
|
+
|
|
569
|
+
When the OpenProse VM encounters a `session` statement:
|
|
570
|
+
|
|
571
|
+
1. **Resolve Configuration**: Merge agent defaults with session overrides
|
|
572
|
+
2. **Spawn a Subagent**: Create a new Claude subagent with the resolved configuration
|
|
573
|
+
3. **Send the Prompt**: Pass the prompt string to the subagent
|
|
574
|
+
4. **Wait for Completion**: Block until the subagent finishes
|
|
575
|
+
5. **Continue**: Proceed to the next statement
|
|
576
|
+
|
|
577
|
+
### Execution Flow Diagram
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
OpenProse VM Subagent
|
|
581
|
+
| |
|
|
582
|
+
| spawn session |
|
|
583
|
+
|----------------------------->|
|
|
584
|
+
| |
|
|
585
|
+
| send prompt |
|
|
586
|
+
|----------------------------->|
|
|
587
|
+
| |
|
|
588
|
+
| [processing...] |
|
|
589
|
+
| |
|
|
590
|
+
| session complete |
|
|
591
|
+
|<-----------------------------|
|
|
592
|
+
| |
|
|
593
|
+
| continue to next statement |
|
|
594
|
+
v v
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Sequential Execution
|
|
598
|
+
|
|
599
|
+
Multiple sessions execute sequentially:
|
|
600
|
+
|
|
601
|
+
```prose
|
|
602
|
+
session "First task"
|
|
603
|
+
session "Second task"
|
|
604
|
+
session "Third task"
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Each session waits for the previous one to complete before starting.
|
|
608
|
+
|
|
609
|
+
### Using Claude Code's Task Tool
|
|
610
|
+
|
|
611
|
+
To execute a session, use the Task tool:
|
|
612
|
+
|
|
613
|
+
```typescript
|
|
614
|
+
// Simple session
|
|
615
|
+
Task({
|
|
616
|
+
description: "OpenProse session",
|
|
617
|
+
prompt: "The prompt from the session statement",
|
|
618
|
+
subagent_type: "general-purpose",
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// Session with agent configuration
|
|
622
|
+
Task({
|
|
623
|
+
description: "OpenProse session",
|
|
624
|
+
prompt: "The session prompt",
|
|
625
|
+
subagent_type: "general-purpose",
|
|
626
|
+
model: "opus", // From agent or override
|
|
627
|
+
});
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Validation Rules
|
|
631
|
+
|
|
632
|
+
| Check | Severity | Message |
|
|
633
|
+
| ------------------------- | -------- | -------------------------------------------- |
|
|
634
|
+
| Missing prompt and agent | Error | Session requires a prompt or agent reference |
|
|
635
|
+
| Undefined agent reference | Error | Agent not defined |
|
|
636
|
+
| Empty prompt `""` | Warning | Session has empty prompt |
|
|
637
|
+
| Whitespace-only prompt | Warning | Session prompt contains only whitespace |
|
|
638
|
+
| Prompt > 10,000 chars | Warning | Consider breaking into smaller tasks |
|
|
639
|
+
| Duplicate property | Error | Property already specified |
|
|
640
|
+
|
|
641
|
+
### Examples
|
|
642
|
+
|
|
643
|
+
```prose
|
|
644
|
+
# Simple session
|
|
645
|
+
session "Hello world"
|
|
646
|
+
|
|
647
|
+
# Session with agent
|
|
648
|
+
agent researcher:
|
|
649
|
+
model: sonnet
|
|
650
|
+
prompt: "You research topics thoroughly"
|
|
651
|
+
|
|
652
|
+
session: researcher
|
|
653
|
+
prompt: "Research quantum computing applications"
|
|
654
|
+
|
|
655
|
+
# Named session
|
|
656
|
+
session analysis: researcher
|
|
657
|
+
prompt: "Analyze the competitive landscape"
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Canonical Form
|
|
661
|
+
|
|
662
|
+
The compiled output preserves the structure:
|
|
663
|
+
|
|
664
|
+
```
|
|
665
|
+
Input:
|
|
666
|
+
agent researcher:
|
|
667
|
+
model: sonnet
|
|
668
|
+
|
|
669
|
+
session: researcher
|
|
670
|
+
prompt: "Do research"
|
|
671
|
+
|
|
672
|
+
Output:
|
|
673
|
+
agent researcher:
|
|
674
|
+
model: sonnet
|
|
675
|
+
session: researcher
|
|
676
|
+
prompt: "Do research"
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
## Variables & Context
|
|
682
|
+
|
|
683
|
+
Variables allow you to capture the results of sessions and pass them as context to subsequent sessions.
|
|
684
|
+
|
|
685
|
+
### Let Binding
|
|
686
|
+
|
|
687
|
+
The `let` keyword creates a mutable variable bound to a session result:
|
|
688
|
+
|
|
689
|
+
```prose
|
|
690
|
+
let research = session "Research the topic thoroughly"
|
|
691
|
+
|
|
692
|
+
# research now holds the output of that session
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
Variables can be reassigned:
|
|
696
|
+
|
|
697
|
+
```prose
|
|
698
|
+
let draft = session "Write initial draft"
|
|
699
|
+
|
|
700
|
+
# Revise the draft
|
|
701
|
+
draft = session "Improve the draft"
|
|
702
|
+
context: draft
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### Const Binding
|
|
706
|
+
|
|
707
|
+
The `const` keyword creates an immutable variable:
|
|
708
|
+
|
|
709
|
+
```prose
|
|
710
|
+
const config = session "Get configuration settings"
|
|
711
|
+
|
|
712
|
+
# This would be an error:
|
|
713
|
+
# config = session "Try to change"
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Context Property
|
|
717
|
+
|
|
718
|
+
The `context` property passes previous session outputs to a new session:
|
|
719
|
+
|
|
720
|
+
#### Single Context
|
|
721
|
+
|
|
722
|
+
```prose
|
|
723
|
+
let research = session "Research quantum computing"
|
|
724
|
+
|
|
725
|
+
session "Write summary"
|
|
726
|
+
context: research
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
#### Multiple Contexts
|
|
730
|
+
|
|
731
|
+
```prose
|
|
732
|
+
let research = session "Research the topic"
|
|
733
|
+
let analysis = session "Analyze the findings"
|
|
734
|
+
|
|
735
|
+
session "Write final report"
|
|
736
|
+
context: [research, analysis]
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
#### Empty Context (Fresh Start)
|
|
740
|
+
|
|
741
|
+
Use an empty array to start a session without inherited context:
|
|
742
|
+
|
|
743
|
+
```prose
|
|
744
|
+
session "Independent task"
|
|
745
|
+
context: []
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
#### Object Context Shorthand
|
|
749
|
+
|
|
750
|
+
For passing multiple named results (especially from parallel blocks), use object shorthand:
|
|
751
|
+
|
|
752
|
+
```prose
|
|
753
|
+
parallel:
|
|
754
|
+
a = session "Task A"
|
|
755
|
+
b = session "Task B"
|
|
756
|
+
|
|
757
|
+
session "Combine results"
|
|
758
|
+
context: { a, b }
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
This is equivalent to passing an object where each property is a variable reference.
|
|
762
|
+
|
|
763
|
+
### Complete Example
|
|
764
|
+
|
|
765
|
+
```prose
|
|
766
|
+
agent researcher:
|
|
767
|
+
model: sonnet
|
|
768
|
+
prompt: "You are a research assistant"
|
|
769
|
+
|
|
770
|
+
agent writer:
|
|
771
|
+
model: opus
|
|
772
|
+
prompt: "You are a technical writer"
|
|
773
|
+
|
|
774
|
+
# Gather research
|
|
775
|
+
let research = session: researcher
|
|
776
|
+
prompt: "Research quantum computing developments"
|
|
777
|
+
|
|
778
|
+
# Analyze findings
|
|
779
|
+
let analysis = session: researcher
|
|
780
|
+
prompt: "Analyze the key findings"
|
|
781
|
+
context: research
|
|
782
|
+
|
|
783
|
+
# Write the final report using both contexts
|
|
784
|
+
const report = session: writer
|
|
785
|
+
prompt: "Write a comprehensive report"
|
|
786
|
+
context: [research, analysis]
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
### Validation Rules
|
|
790
|
+
|
|
791
|
+
| Check | Severity | Message |
|
|
792
|
+
| ------------------------------- | -------- | -------------------------------------------------- |
|
|
793
|
+
| Duplicate variable name | Error | Variable already defined |
|
|
794
|
+
| Const reassignment | Error | Cannot reassign const variable |
|
|
795
|
+
| Undefined variable reference | Error | Undefined variable |
|
|
796
|
+
| Variable conflicts with agent | Error | Variable name conflicts with agent name |
|
|
797
|
+
| Undefined context variable | Error | Undefined variable in context |
|
|
798
|
+
| Non-identifier in context array | Error | Context array elements must be variable references |
|
|
799
|
+
|
|
800
|
+
---
|
|
801
|
+
|
|
802
|
+
## Composition Blocks
|
|
803
|
+
|
|
804
|
+
Composition blocks allow you to structure programs into reusable, named units and express sequences of operations inline.
|
|
805
|
+
|
|
806
|
+
### do: Block (Anonymous Sequential Block)
|
|
807
|
+
|
|
808
|
+
The `do:` keyword creates an explicit sequential block. All statements in the block execute in order.
|
|
809
|
+
|
|
810
|
+
#### Syntax
|
|
811
|
+
|
|
812
|
+
```prose
|
|
813
|
+
do:
|
|
814
|
+
statement1
|
|
815
|
+
statement2
|
|
816
|
+
...
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
#### Examples
|
|
820
|
+
|
|
821
|
+
```prose
|
|
822
|
+
# Explicit sequential block
|
|
823
|
+
do:
|
|
824
|
+
session "Research the topic"
|
|
825
|
+
session "Analyze findings"
|
|
826
|
+
session "Write summary"
|
|
827
|
+
|
|
828
|
+
# Assign result to a variable
|
|
829
|
+
let result = do:
|
|
830
|
+
session "Gather data"
|
|
831
|
+
session "Process data"
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
### Block Definitions
|
|
835
|
+
|
|
836
|
+
Named blocks create reusable workflow components. Define once, invoke multiple times.
|
|
837
|
+
|
|
838
|
+
#### Syntax
|
|
839
|
+
|
|
840
|
+
```prose
|
|
841
|
+
block name:
|
|
842
|
+
statement1
|
|
843
|
+
statement2
|
|
844
|
+
...
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
#### Invoking Blocks
|
|
848
|
+
|
|
849
|
+
Use `do` followed by the block name to invoke a defined block:
|
|
850
|
+
|
|
851
|
+
```prose
|
|
852
|
+
do blockname
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
#### Examples
|
|
856
|
+
|
|
857
|
+
```prose
|
|
858
|
+
# Define a review pipeline
|
|
859
|
+
block review-pipeline:
|
|
860
|
+
session "Security review"
|
|
861
|
+
session "Performance review"
|
|
862
|
+
session "Synthesize reviews"
|
|
863
|
+
|
|
864
|
+
# Define another block
|
|
865
|
+
block final-check:
|
|
866
|
+
session "Final verification"
|
|
867
|
+
session "Sign off"
|
|
868
|
+
|
|
869
|
+
# Use the blocks
|
|
870
|
+
do review-pipeline
|
|
871
|
+
session "Make fixes based on review"
|
|
872
|
+
do final-check
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
### Block Parameters
|
|
876
|
+
|
|
877
|
+
Blocks can accept parameters to make them more flexible and reusable.
|
|
878
|
+
|
|
879
|
+
#### Syntax
|
|
880
|
+
|
|
881
|
+
```prose
|
|
882
|
+
block name(param1, param2):
|
|
883
|
+
# param1 and param2 are available here
|
|
884
|
+
statement1
|
|
885
|
+
statement2
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
#### Invoking with Arguments
|
|
889
|
+
|
|
890
|
+
Pass arguments when invoking a parameterized block:
|
|
891
|
+
|
|
892
|
+
```prose
|
|
893
|
+
do name(arg1, arg2)
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
#### Examples
|
|
897
|
+
|
|
898
|
+
```prose
|
|
899
|
+
# Define a parameterized block
|
|
900
|
+
block review(topic):
|
|
901
|
+
session "Research {topic} thoroughly"
|
|
902
|
+
session "Analyze key findings about {topic}"
|
|
903
|
+
session "Summarize {topic} analysis"
|
|
904
|
+
|
|
905
|
+
# Invoke with different arguments
|
|
906
|
+
do review("quantum computing")
|
|
907
|
+
do review("machine learning")
|
|
908
|
+
do review("blockchain")
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
#### Multiple Parameters
|
|
912
|
+
|
|
913
|
+
```prose
|
|
914
|
+
block process-item(item, mode):
|
|
915
|
+
session "Process {item} using {mode} mode"
|
|
916
|
+
session "Verify {item} processing"
|
|
917
|
+
|
|
918
|
+
do process-item("data.csv", "strict")
|
|
919
|
+
do process-item("config.json", "lenient")
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
#### Parameter Scope
|
|
923
|
+
|
|
924
|
+
- Parameters are scoped to the block body
|
|
925
|
+
- Parameters shadow outer variables of the same name (with warning)
|
|
926
|
+
- Parameters are implicitly `const` within the block
|
|
927
|
+
|
|
928
|
+
#### Validation Rules
|
|
929
|
+
|
|
930
|
+
| Check | Severity | Message |
|
|
931
|
+
| ----------------------- | -------- | ---------------------------------------------- |
|
|
932
|
+
| Argument count mismatch | Warning | Block expects N parameters but got M arguments |
|
|
933
|
+
| Parameter shadows outer | Warning | Parameter shadows outer variable |
|
|
934
|
+
|
|
935
|
+
### Inline Sequence (Arrow Operator)
|
|
936
|
+
|
|
937
|
+
The `->` operator chains sessions into a sequence on a single line. This is syntactic sugar for sequential execution.
|
|
938
|
+
|
|
939
|
+
#### Syntax
|
|
940
|
+
|
|
941
|
+
```prose
|
|
942
|
+
session "A" -> session "B" -> session "C"
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
This is equivalent to:
|
|
946
|
+
|
|
947
|
+
```prose
|
|
948
|
+
session "A"
|
|
949
|
+
session "B"
|
|
950
|
+
session "C"
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
#### Examples
|
|
954
|
+
|
|
955
|
+
```prose
|
|
956
|
+
# Quick pipeline
|
|
957
|
+
session "Plan" -> session "Execute" -> session "Review"
|
|
958
|
+
|
|
959
|
+
# Assign result
|
|
960
|
+
let workflow = session "Draft" -> session "Edit" -> session "Finalize"
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
### Block Hoisting
|
|
964
|
+
|
|
965
|
+
Block definitions are hoisted - you can use a block before it's defined in the source:
|
|
966
|
+
|
|
967
|
+
```prose
|
|
968
|
+
# Use before definition
|
|
969
|
+
do validation-checks
|
|
970
|
+
|
|
971
|
+
# Definition comes later
|
|
972
|
+
block validation-checks:
|
|
973
|
+
session "Check syntax"
|
|
974
|
+
session "Check semantics"
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
### Nested Composition
|
|
978
|
+
|
|
979
|
+
Blocks and do: blocks can be nested:
|
|
980
|
+
|
|
981
|
+
```prose
|
|
982
|
+
block outer-workflow:
|
|
983
|
+
session "Start"
|
|
984
|
+
do:
|
|
985
|
+
session "Sub-task 1"
|
|
986
|
+
session "Sub-task 2"
|
|
987
|
+
session "End"
|
|
988
|
+
|
|
989
|
+
do:
|
|
990
|
+
do outer-workflow
|
|
991
|
+
session "Final step"
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
### Context with Blocks
|
|
995
|
+
|
|
996
|
+
Blocks work with the context system:
|
|
997
|
+
|
|
998
|
+
```prose
|
|
999
|
+
# Capture do block result
|
|
1000
|
+
let research = do:
|
|
1001
|
+
session "Gather information"
|
|
1002
|
+
session "Analyze patterns"
|
|
1003
|
+
|
|
1004
|
+
# Use in subsequent session
|
|
1005
|
+
session "Write report"
|
|
1006
|
+
context: research
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### Validation Rules
|
|
1010
|
+
|
|
1011
|
+
| Check | Severity | Message |
|
|
1012
|
+
| ------------------------------- | -------- | ------------------------------------ |
|
|
1013
|
+
| Undefined block reference | Error | Block not defined |
|
|
1014
|
+
| Duplicate block definition | Error | Block already defined |
|
|
1015
|
+
| Block name conflicts with agent | Error | Block name conflicts with agent name |
|
|
1016
|
+
| Empty block name | Error | Block definition must have a name |
|
|
1017
|
+
|
|
1018
|
+
---
|
|
1019
|
+
|
|
1020
|
+
## Parallel Blocks
|
|
1021
|
+
|
|
1022
|
+
Parallel blocks allow multiple sessions to run concurrently. All branches execute simultaneously, and the block waits for all to complete before continuing.
|
|
1023
|
+
|
|
1024
|
+
### Basic Syntax
|
|
1025
|
+
|
|
1026
|
+
```prose
|
|
1027
|
+
parallel:
|
|
1028
|
+
session "Security review"
|
|
1029
|
+
session "Performance review"
|
|
1030
|
+
session "Style review"
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
All three sessions start at the same time and run concurrently. The program waits for all of them to complete before proceeding.
|
|
1034
|
+
|
|
1035
|
+
### Named Parallel Results
|
|
1036
|
+
|
|
1037
|
+
Capture the results of parallel branches into variables:
|
|
1038
|
+
|
|
1039
|
+
```prose
|
|
1040
|
+
parallel:
|
|
1041
|
+
security = session "Security review"
|
|
1042
|
+
perf = session "Performance review"
|
|
1043
|
+
style = session "Style review"
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
These variables can then be used in subsequent sessions.
|
|
1047
|
+
|
|
1048
|
+
### Object Context Shorthand
|
|
1049
|
+
|
|
1050
|
+
Pass multiple parallel results to a session using object shorthand:
|
|
1051
|
+
|
|
1052
|
+
```prose
|
|
1053
|
+
parallel:
|
|
1054
|
+
security = session "Security review"
|
|
1055
|
+
perf = session "Performance review"
|
|
1056
|
+
style = session "Style review"
|
|
1057
|
+
|
|
1058
|
+
session "Synthesize all reviews"
|
|
1059
|
+
context: { security, perf, style }
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
The object shorthand `{ a, b, c }` is equivalent to passing an object with properties `a`, `b`, and `c` where each property's value is the corresponding variable.
|
|
1063
|
+
|
|
1064
|
+
### Mixed Composition
|
|
1065
|
+
|
|
1066
|
+
#### Parallel Inside Sequential
|
|
1067
|
+
|
|
1068
|
+
```prose
|
|
1069
|
+
do:
|
|
1070
|
+
session "Setup"
|
|
1071
|
+
parallel:
|
|
1072
|
+
session "Task A"
|
|
1073
|
+
session "Task B"
|
|
1074
|
+
session "Cleanup"
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
The setup runs first, then Task A and Task B run in parallel, and finally cleanup runs.
|
|
1078
|
+
|
|
1079
|
+
#### Sequential Inside Parallel
|
|
1080
|
+
|
|
1081
|
+
```prose
|
|
1082
|
+
parallel:
|
|
1083
|
+
do:
|
|
1084
|
+
session "Multi-step task 1a"
|
|
1085
|
+
session "Multi-step task 1b"
|
|
1086
|
+
do:
|
|
1087
|
+
session "Multi-step task 2a"
|
|
1088
|
+
session "Multi-step task 2b"
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
Each parallel branch contains a sequential workflow. The two workflows run concurrently.
|
|
1092
|
+
|
|
1093
|
+
### Assigning Parallel Blocks to Variables
|
|
1094
|
+
|
|
1095
|
+
```prose
|
|
1096
|
+
let results = parallel:
|
|
1097
|
+
session "Task A"
|
|
1098
|
+
session "Task B"
|
|
1099
|
+
```
|
|
1100
|
+
|
|
1101
|
+
### Complete Example
|
|
1102
|
+
|
|
1103
|
+
```prose
|
|
1104
|
+
agent reviewer:
|
|
1105
|
+
model: sonnet
|
|
1106
|
+
|
|
1107
|
+
# Run parallel reviews
|
|
1108
|
+
parallel:
|
|
1109
|
+
sec = session: reviewer
|
|
1110
|
+
prompt: "Review for security issues"
|
|
1111
|
+
perf = session: reviewer
|
|
1112
|
+
prompt: "Review for performance issues"
|
|
1113
|
+
style = session: reviewer
|
|
1114
|
+
prompt: "Review for style issues"
|
|
1115
|
+
|
|
1116
|
+
# Combine all reviews
|
|
1117
|
+
session "Create unified review report"
|
|
1118
|
+
context: { sec, perf, style }
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
### Join Strategies
|
|
1122
|
+
|
|
1123
|
+
By default, parallel blocks wait for all branches to complete. You can specify alternative join strategies:
|
|
1124
|
+
|
|
1125
|
+
#### First (Race)
|
|
1126
|
+
|
|
1127
|
+
Return as soon as the first branch completes, cancel others:
|
|
1128
|
+
|
|
1129
|
+
```prose
|
|
1130
|
+
parallel ("first"):
|
|
1131
|
+
session "Try approach A"
|
|
1132
|
+
session "Try approach B"
|
|
1133
|
+
session "Try approach C"
|
|
1134
|
+
```
|
|
1135
|
+
|
|
1136
|
+
The first successful result wins. Other branches are cancelled.
|
|
1137
|
+
|
|
1138
|
+
#### Any (N of M)
|
|
1139
|
+
|
|
1140
|
+
Return when any N branches complete successfully:
|
|
1141
|
+
|
|
1142
|
+
```prose
|
|
1143
|
+
# Default: any 1 success
|
|
1144
|
+
parallel ("any"):
|
|
1145
|
+
session "Attempt 1"
|
|
1146
|
+
session "Attempt 2"
|
|
1147
|
+
|
|
1148
|
+
# Specific count: wait for 2 successes
|
|
1149
|
+
parallel ("any", count: 2):
|
|
1150
|
+
session "Attempt 1"
|
|
1151
|
+
session "Attempt 2"
|
|
1152
|
+
session "Attempt 3"
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
#### All (Default)
|
|
1156
|
+
|
|
1157
|
+
Wait for all branches to complete:
|
|
1158
|
+
|
|
1159
|
+
```prose
|
|
1160
|
+
# Implicit - this is the default
|
|
1161
|
+
parallel:
|
|
1162
|
+
session "Task A"
|
|
1163
|
+
session "Task B"
|
|
1164
|
+
|
|
1165
|
+
# Explicit
|
|
1166
|
+
parallel ("all"):
|
|
1167
|
+
session "Task A"
|
|
1168
|
+
session "Task B"
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
### Failure Policies
|
|
1172
|
+
|
|
1173
|
+
Control how the parallel block handles branch failures:
|
|
1174
|
+
|
|
1175
|
+
#### Fail-Fast (Default)
|
|
1176
|
+
|
|
1177
|
+
If any branch fails, fail immediately and cancel other branches:
|
|
1178
|
+
|
|
1179
|
+
```prose
|
|
1180
|
+
parallel: # Implicit fail-fast
|
|
1181
|
+
session "Critical task 1"
|
|
1182
|
+
session "Critical task 2"
|
|
1183
|
+
|
|
1184
|
+
# Explicit
|
|
1185
|
+
parallel (on-fail: "fail-fast"):
|
|
1186
|
+
session "Critical task 1"
|
|
1187
|
+
session "Critical task 2"
|
|
1188
|
+
```
|
|
1189
|
+
|
|
1190
|
+
#### Continue
|
|
1191
|
+
|
|
1192
|
+
Let all branches complete, then report all failures:
|
|
1193
|
+
|
|
1194
|
+
```prose
|
|
1195
|
+
parallel (on-fail: "continue"):
|
|
1196
|
+
session "Task 1"
|
|
1197
|
+
session "Task 2"
|
|
1198
|
+
session "Task 3"
|
|
1199
|
+
|
|
1200
|
+
# Continue regardless of which branches failed
|
|
1201
|
+
session "Process results, including failures"
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
#### Ignore
|
|
1205
|
+
|
|
1206
|
+
Ignore all failures, always succeed:
|
|
1207
|
+
|
|
1208
|
+
```prose
|
|
1209
|
+
parallel (on-fail: "ignore"):
|
|
1210
|
+
session "Optional enrichment 1"
|
|
1211
|
+
session "Optional enrichment 2"
|
|
1212
|
+
|
|
1213
|
+
# This always runs, even if all branches failed
|
|
1214
|
+
session "Continue regardless"
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
### Combining Modifiers
|
|
1218
|
+
|
|
1219
|
+
Join strategies and failure policies can be combined:
|
|
1220
|
+
|
|
1221
|
+
```prose
|
|
1222
|
+
# Race with resilience
|
|
1223
|
+
parallel ("first", on-fail: "continue"):
|
|
1224
|
+
session "Fast but unreliable"
|
|
1225
|
+
session "Slow but reliable"
|
|
1226
|
+
|
|
1227
|
+
# Get any 2 results, ignoring failures
|
|
1228
|
+
parallel ("any", count: 2, on-fail: "ignore"):
|
|
1229
|
+
session "Approach 1"
|
|
1230
|
+
session "Approach 2"
|
|
1231
|
+
session "Approach 3"
|
|
1232
|
+
session "Approach 4"
|
|
1233
|
+
```
|
|
1234
|
+
|
|
1235
|
+
### Execution Semantics
|
|
1236
|
+
|
|
1237
|
+
When the OpenProse VM encounters a `parallel:` block:
|
|
1238
|
+
|
|
1239
|
+
1. **Fork**: Start all branches concurrently
|
|
1240
|
+
2. **Execute**: Each branch runs independently
|
|
1241
|
+
3. **Join**: Wait according to join strategy:
|
|
1242
|
+
- `"all"` (default): Wait for all branches
|
|
1243
|
+
- `"first"`: Return on first completion
|
|
1244
|
+
- `"any"`: Return on first success (or N successes with `count`)
|
|
1245
|
+
4. **Handle failures**: According to on-fail policy:
|
|
1246
|
+
- `"fail-fast"` (default): Cancel remaining and fail immediately
|
|
1247
|
+
- `"continue"`: Wait for all, then report failures
|
|
1248
|
+
- `"ignore"`: Treat failures as successes
|
|
1249
|
+
5. **Continue**: Proceed to the next statement with available results
|
|
1250
|
+
|
|
1251
|
+
### Validation Rules
|
|
1252
|
+
|
|
1253
|
+
| Check | Severity | Message |
|
|
1254
|
+
| ------------------------------------ | -------- | -------------------------------------------- |
|
|
1255
|
+
| Invalid join strategy | Error | Must be "all", "first", or "any" |
|
|
1256
|
+
| Invalid on-fail policy | Error | Must be "fail-fast", "continue", or "ignore" |
|
|
1257
|
+
| Count without "any" | Error | Count is only valid with "any" strategy |
|
|
1258
|
+
| Count less than 1 | Error | Count must be at least 1 |
|
|
1259
|
+
| Count exceeds branches | Warning | Count exceeds number of parallel branches |
|
|
1260
|
+
| Duplicate variable in parallel | Error | Variable already defined |
|
|
1261
|
+
| Variable conflicts with agent | Error | Variable name conflicts with agent name |
|
|
1262
|
+
| Undefined variable in object context | Error | Undefined variable in context |
|
|
1263
|
+
|
|
1264
|
+
---
|
|
1265
|
+
|
|
1266
|
+
## Fixed Loops
|
|
1267
|
+
|
|
1268
|
+
Fixed loops provide bounded iteration over a set number of times or over a collection.
|
|
1269
|
+
|
|
1270
|
+
### Repeat Block
|
|
1271
|
+
|
|
1272
|
+
The `repeat` block executes its body a fixed number of times.
|
|
1273
|
+
|
|
1274
|
+
#### Basic Syntax
|
|
1275
|
+
|
|
1276
|
+
```prose
|
|
1277
|
+
repeat 3:
|
|
1278
|
+
session "Generate a creative idea"
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
#### With Index Variable
|
|
1282
|
+
|
|
1283
|
+
Access the current iteration index using `as`:
|
|
1284
|
+
|
|
1285
|
+
```prose
|
|
1286
|
+
repeat 5 as i:
|
|
1287
|
+
session "Process item"
|
|
1288
|
+
context: i
|
|
1289
|
+
```
|
|
1290
|
+
|
|
1291
|
+
The index variable `i` is scoped to the loop body and starts at 0.
|
|
1292
|
+
|
|
1293
|
+
### For-Each Block
|
|
1294
|
+
|
|
1295
|
+
The `for` block iterates over a collection.
|
|
1296
|
+
|
|
1297
|
+
#### Basic Syntax
|
|
1298
|
+
|
|
1299
|
+
```prose
|
|
1300
|
+
let fruits = ["apple", "banana", "cherry"]
|
|
1301
|
+
for fruit in fruits:
|
|
1302
|
+
session "Describe this fruit"
|
|
1303
|
+
context: fruit
|
|
1304
|
+
```
|
|
1305
|
+
|
|
1306
|
+
#### With Inline Array
|
|
1307
|
+
|
|
1308
|
+
```prose
|
|
1309
|
+
for topic in ["AI", "climate", "space"]:
|
|
1310
|
+
session "Research this topic"
|
|
1311
|
+
context: topic
|
|
1312
|
+
```
|
|
1313
|
+
|
|
1314
|
+
#### With Index Variable
|
|
1315
|
+
|
|
1316
|
+
Access both the item and its index:
|
|
1317
|
+
|
|
1318
|
+
```prose
|
|
1319
|
+
let items = ["a", "b", "c"]
|
|
1320
|
+
for item, i in items:
|
|
1321
|
+
session "Process item with index"
|
|
1322
|
+
context: [item, i]
|
|
1323
|
+
```
|
|
1324
|
+
|
|
1325
|
+
### Parallel For-Each
|
|
1326
|
+
|
|
1327
|
+
The `parallel for` block runs all iterations concurrently (fan-out pattern):
|
|
1328
|
+
|
|
1329
|
+
```prose
|
|
1330
|
+
let topics = ["AI", "climate", "space"]
|
|
1331
|
+
parallel for topic in topics:
|
|
1332
|
+
session "Research this topic"
|
|
1333
|
+
context: topic
|
|
1334
|
+
|
|
1335
|
+
session "Combine all research"
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
This is equivalent to:
|
|
1339
|
+
|
|
1340
|
+
```prose
|
|
1341
|
+
parallel:
|
|
1342
|
+
session "Research AI" context: "AI"
|
|
1343
|
+
session "Research climate" context: "climate"
|
|
1344
|
+
session "Research space" context: "space"
|
|
1345
|
+
```
|
|
1346
|
+
|
|
1347
|
+
But more concise and dynamic.
|
|
1348
|
+
|
|
1349
|
+
### Variable Scoping
|
|
1350
|
+
|
|
1351
|
+
Loop variables are scoped to the loop body:
|
|
1352
|
+
|
|
1353
|
+
- They are implicitly `const` within each iteration
|
|
1354
|
+
- They shadow outer variables of the same name (with a warning)
|
|
1355
|
+
- They are not accessible outside the loop
|
|
1356
|
+
|
|
1357
|
+
```prose
|
|
1358
|
+
let item = session "outer"
|
|
1359
|
+
for item in ["a", "b"]:
|
|
1360
|
+
# 'item' here is the loop variable
|
|
1361
|
+
session "process loop item"
|
|
1362
|
+
context: item
|
|
1363
|
+
# 'item' here refers to the outer variable again
|
|
1364
|
+
session "use outer item"
|
|
1365
|
+
context: item
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
### Nesting
|
|
1369
|
+
|
|
1370
|
+
Loops can be nested:
|
|
1371
|
+
|
|
1372
|
+
```prose
|
|
1373
|
+
repeat 2:
|
|
1374
|
+
repeat 3:
|
|
1375
|
+
session "Inner task"
|
|
1376
|
+
```
|
|
1377
|
+
|
|
1378
|
+
Different loop types can be combined:
|
|
1379
|
+
|
|
1380
|
+
```prose
|
|
1381
|
+
let items = ["a", "b"]
|
|
1382
|
+
repeat 2:
|
|
1383
|
+
for item in items:
|
|
1384
|
+
session "Process item"
|
|
1385
|
+
context: item
|
|
1386
|
+
```
|
|
1387
|
+
|
|
1388
|
+
### Complete Example
|
|
1389
|
+
|
|
1390
|
+
```prose
|
|
1391
|
+
# Generate multiple variations of ideas
|
|
1392
|
+
repeat 3:
|
|
1393
|
+
session "Generate a creative startup idea"
|
|
1394
|
+
|
|
1395
|
+
session "Select the best idea from the options above"
|
|
1396
|
+
|
|
1397
|
+
# Research the selected idea from multiple angles
|
|
1398
|
+
let angles = ["market", "technology", "competition"]
|
|
1399
|
+
parallel for angle in angles:
|
|
1400
|
+
session "Research this angle of the startup idea"
|
|
1401
|
+
context: angle
|
|
1402
|
+
|
|
1403
|
+
session "Synthesize all research into a business plan"
|
|
1404
|
+
```
|
|
1405
|
+
|
|
1406
|
+
### Validation Rules
|
|
1407
|
+
|
|
1408
|
+
| Check | Severity | Message |
|
|
1409
|
+
| ----------------------------- | -------- | ------------------------------------ |
|
|
1410
|
+
| Repeat count must be positive | Error | Repeat count must be positive |
|
|
1411
|
+
| Repeat count must be integer | Error | Repeat count must be an integer |
|
|
1412
|
+
| Undefined collection variable | Error | Undefined collection variable |
|
|
1413
|
+
| Loop variable shadows outer | Warning | Loop variable shadows outer variable |
|
|
1414
|
+
|
|
1415
|
+
---
|
|
1416
|
+
|
|
1417
|
+
## Unbounded Loops
|
|
1418
|
+
|
|
1419
|
+
Unbounded loops provide iteration with AI-evaluated termination conditions. Unlike fixed loops, the iteration count is not known ahead of time - the OpenProse VM evaluates conditions at runtime using its intelligence to determine when to stop.
|
|
1420
|
+
|
|
1421
|
+
### Discretion Markers
|
|
1422
|
+
|
|
1423
|
+
Unbounded loops use **discretion markers** (`**...**`) to wrap AI-evaluated conditions. These markers signal that the enclosed text should be interpreted intelligently by the OpenProse VM at runtime, not as a literal boolean expression.
|
|
1424
|
+
|
|
1425
|
+
```prose
|
|
1426
|
+
# The text inside **...** is evaluated by the AI
|
|
1427
|
+
loop until **the poem has vivid imagery and flows smoothly**:
|
|
1428
|
+
session "Review and improve the poem"
|
|
1429
|
+
```
|
|
1430
|
+
|
|
1431
|
+
For multi-line conditions, use triple-asterisks:
|
|
1432
|
+
|
|
1433
|
+
```prose
|
|
1434
|
+
loop until ***
|
|
1435
|
+
the document is complete
|
|
1436
|
+
all sections have been reviewed
|
|
1437
|
+
and formatting is consistent
|
|
1438
|
+
***:
|
|
1439
|
+
session "Continue working on the document"
|
|
1440
|
+
```
|
|
1441
|
+
|
|
1442
|
+
### Basic Loop
|
|
1443
|
+
|
|
1444
|
+
The simplest unbounded loop runs indefinitely until explicitly limited:
|
|
1445
|
+
|
|
1446
|
+
```prose
|
|
1447
|
+
loop:
|
|
1448
|
+
session "Process next item"
|
|
1449
|
+
```
|
|
1450
|
+
|
|
1451
|
+
**Warning**: Loops without termination conditions or max iterations generate a warning. Always include a safety limit:
|
|
1452
|
+
|
|
1453
|
+
```prose
|
|
1454
|
+
loop (max: 50):
|
|
1455
|
+
session "Process next item"
|
|
1456
|
+
```
|
|
1457
|
+
|
|
1458
|
+
### Loop Until
|
|
1459
|
+
|
|
1460
|
+
The `loop until` variant runs until a condition becomes true:
|
|
1461
|
+
|
|
1462
|
+
```prose
|
|
1463
|
+
loop until **the task is complete**:
|
|
1464
|
+
session "Continue working on the task"
|
|
1465
|
+
```
|
|
1466
|
+
|
|
1467
|
+
The OpenProse VM evaluates the discretion condition after each iteration and exits when it determines the condition is satisfied.
|
|
1468
|
+
|
|
1469
|
+
### Loop While
|
|
1470
|
+
|
|
1471
|
+
The `loop while` variant runs while a condition remains true:
|
|
1472
|
+
|
|
1473
|
+
```prose
|
|
1474
|
+
loop while **there are still items to process**:
|
|
1475
|
+
session "Process the next item"
|
|
1476
|
+
```
|
|
1477
|
+
|
|
1478
|
+
Semantically, `loop while **X**` is equivalent to `loop until **not X**`.
|
|
1479
|
+
|
|
1480
|
+
### Iteration Variable
|
|
1481
|
+
|
|
1482
|
+
Track the current iteration number using `as`:
|
|
1483
|
+
|
|
1484
|
+
```prose
|
|
1485
|
+
loop until **done** as attempt:
|
|
1486
|
+
session "Try approach"
|
|
1487
|
+
context: attempt
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
The iteration variable:
|
|
1491
|
+
|
|
1492
|
+
- Starts at 0
|
|
1493
|
+
- Increments by 1 each iteration
|
|
1494
|
+
- Is scoped to the loop body
|
|
1495
|
+
- Is implicitly `const` within each iteration
|
|
1496
|
+
|
|
1497
|
+
### Safety Limits
|
|
1498
|
+
|
|
1499
|
+
Specify maximum iterations with `(max: N)`:
|
|
1500
|
+
|
|
1501
|
+
```prose
|
|
1502
|
+
# Stop after 10 iterations even if condition not met
|
|
1503
|
+
loop until **all bugs fixed** (max: 10):
|
|
1504
|
+
session "Find and fix a bug"
|
|
1505
|
+
```
|
|
1506
|
+
|
|
1507
|
+
The loop exits when:
|
|
1508
|
+
|
|
1509
|
+
1. The condition is satisfied (for `until`/`while` variants), OR
|
|
1510
|
+
2. The maximum iteration count is reached
|
|
1511
|
+
|
|
1512
|
+
### Complete Syntax
|
|
1513
|
+
|
|
1514
|
+
All options can be combined:
|
|
1515
|
+
|
|
1516
|
+
```prose
|
|
1517
|
+
loop until **condition** (max: N) as i:
|
|
1518
|
+
body...
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
Order matters: condition comes before modifiers, modifiers before `as`.
|
|
1522
|
+
|
|
1523
|
+
### Examples
|
|
1524
|
+
|
|
1525
|
+
#### Iterative Improvement
|
|
1526
|
+
|
|
1527
|
+
```prose
|
|
1528
|
+
session "Write an initial draft"
|
|
1529
|
+
|
|
1530
|
+
loop until **the draft is polished and ready for review** (max: 5):
|
|
1531
|
+
session "Review the current draft and identify issues"
|
|
1532
|
+
session "Revise the draft to address the issues"
|
|
1533
|
+
|
|
1534
|
+
session "Present the final draft"
|
|
1535
|
+
```
|
|
1536
|
+
|
|
1537
|
+
#### Debugging Workflow
|
|
1538
|
+
|
|
1539
|
+
```prose
|
|
1540
|
+
session "Run tests to identify failures"
|
|
1541
|
+
|
|
1542
|
+
loop until **all tests pass** (max: 20) as attempt:
|
|
1543
|
+
session "Identify the failing test"
|
|
1544
|
+
session "Fix the bug causing the failure"
|
|
1545
|
+
session "Run tests again"
|
|
1546
|
+
|
|
1547
|
+
session "Confirm all tests pass and summarize fixes"
|
|
1548
|
+
```
|
|
1549
|
+
|
|
1550
|
+
#### Consensus Building
|
|
1551
|
+
|
|
1552
|
+
```prose
|
|
1553
|
+
parallel:
|
|
1554
|
+
opinion1 = session "Get first expert opinion"
|
|
1555
|
+
opinion2 = session "Get second expert opinion"
|
|
1556
|
+
|
|
1557
|
+
loop until **experts have reached consensus** (max: 5):
|
|
1558
|
+
session "Identify points of disagreement"
|
|
1559
|
+
context: { opinion1, opinion2 }
|
|
1560
|
+
session "Facilitate discussion to resolve differences"
|
|
1561
|
+
|
|
1562
|
+
session "Document the final consensus"
|
|
1563
|
+
```
|
|
1564
|
+
|
|
1565
|
+
#### Quality Threshold
|
|
1566
|
+
|
|
1567
|
+
```prose
|
|
1568
|
+
let draft = session "Create initial document"
|
|
1569
|
+
|
|
1570
|
+
loop while **quality score is below threshold** (max: 10):
|
|
1571
|
+
draft = session "Review and improve the document"
|
|
1572
|
+
context: draft
|
|
1573
|
+
session "Calculate new quality score"
|
|
1574
|
+
|
|
1575
|
+
session "Finalize the document"
|
|
1576
|
+
context: draft
|
|
1577
|
+
```
|
|
1578
|
+
|
|
1579
|
+
### Execution Semantics
|
|
1580
|
+
|
|
1581
|
+
When the OpenProse VM encounters an unbounded loop:
|
|
1582
|
+
|
|
1583
|
+
1. **Initialize**: Set iteration counter to 0
|
|
1584
|
+
2. **Check Condition** (for `until`/`while`):
|
|
1585
|
+
- For `until`: Exit if condition is satisfied
|
|
1586
|
+
- For `while`: Exit if condition is NOT satisfied
|
|
1587
|
+
3. **Check Limit**: Exit if iteration count >= max iterations
|
|
1588
|
+
4. **Execute Body**: Run all statements in the loop body
|
|
1589
|
+
5. **Increment**: Increase iteration counter
|
|
1590
|
+
6. **Repeat**: Go to step 2
|
|
1591
|
+
|
|
1592
|
+
For basic `loop:` without conditions:
|
|
1593
|
+
|
|
1594
|
+
- Only the max iteration limit can cause exit
|
|
1595
|
+
- Without max, the loop runs indefinitely (warning issued)
|
|
1596
|
+
|
|
1597
|
+
### Condition Evaluation
|
|
1598
|
+
|
|
1599
|
+
The OpenProse VM uses its intelligence to evaluate discretion conditions:
|
|
1600
|
+
|
|
1601
|
+
1. **Context Awareness**: The condition is evaluated in the context of what has happened so far in the session
|
|
1602
|
+
2. **Semantic Understanding**: The condition text is interpreted semantically, not literally
|
|
1603
|
+
3. **Uncertainty Handling**: When uncertain, the OpenProse VM may:
|
|
1604
|
+
- Continue iterating if progress is being made
|
|
1605
|
+
- Exit early if diminishing returns are detected
|
|
1606
|
+
- Use heuristics based on the condition's semantics
|
|
1607
|
+
|
|
1608
|
+
### Nesting
|
|
1609
|
+
|
|
1610
|
+
Unbounded loops can be nested with other loop types:
|
|
1611
|
+
|
|
1612
|
+
```prose
|
|
1613
|
+
# Unbounded inside fixed
|
|
1614
|
+
repeat 3:
|
|
1615
|
+
loop until **sub-task complete** (max: 10):
|
|
1616
|
+
session "Work on sub-task"
|
|
1617
|
+
|
|
1618
|
+
# Fixed inside unbounded
|
|
1619
|
+
loop until **all batches processed** (max: 5):
|
|
1620
|
+
repeat 3:
|
|
1621
|
+
session "Process batch item"
|
|
1622
|
+
|
|
1623
|
+
# Multiple unbounded
|
|
1624
|
+
loop until **outer condition** (max: 5):
|
|
1625
|
+
loop until **inner condition** (max: 10):
|
|
1626
|
+
session "Deep iteration"
|
|
1627
|
+
```
|
|
1628
|
+
|
|
1629
|
+
### Variable Scoping
|
|
1630
|
+
|
|
1631
|
+
Loop variables follow the same scoping rules as fixed loops:
|
|
1632
|
+
|
|
1633
|
+
```prose
|
|
1634
|
+
let i = session "outer"
|
|
1635
|
+
loop until **done** as i:
|
|
1636
|
+
# 'i' here is the loop variable (shadows outer)
|
|
1637
|
+
session "use loop i"
|
|
1638
|
+
context: i
|
|
1639
|
+
# 'i' here refers to the outer variable again
|
|
1640
|
+
session "use outer i"
|
|
1641
|
+
context: i
|
|
1642
|
+
```
|
|
1643
|
+
|
|
1644
|
+
### Validation Rules
|
|
1645
|
+
|
|
1646
|
+
| Check | Severity | Message |
|
|
1647
|
+
| ----------------------------- | -------- | ------------------------------------- |
|
|
1648
|
+
| Loop without max or condition | Warning | Unbounded loop without max iterations |
|
|
1649
|
+
| Max iterations <= 0 | Error | Max iterations must be positive |
|
|
1650
|
+
| Max iterations not integer | Error | Max iterations must be an integer |
|
|
1651
|
+
| Empty discretion condition | Error | Discretion condition cannot be empty |
|
|
1652
|
+
| Very short condition | Warning | Discretion condition may be ambiguous |
|
|
1653
|
+
| Loop variable shadows outer | Warning | Loop variable shadows outer variable |
|
|
1654
|
+
|
|
1655
|
+
---
|
|
1656
|
+
|
|
1657
|
+
## Pipeline Operations
|
|
1658
|
+
|
|
1659
|
+
Pipeline operations provide functional-style collection transformations. They allow you to chain operations like map, filter, and reduce using the pipe operator (`|`).
|
|
1660
|
+
|
|
1661
|
+
### Pipe Operator
|
|
1662
|
+
|
|
1663
|
+
The pipe operator (`|`) passes a collection to a transformation operation:
|
|
1664
|
+
|
|
1665
|
+
```prose
|
|
1666
|
+
let items = ["a", "b", "c"]
|
|
1667
|
+
let results = items | map:
|
|
1668
|
+
session "Process this item"
|
|
1669
|
+
context: item
|
|
1670
|
+
```
|
|
1671
|
+
|
|
1672
|
+
### Map
|
|
1673
|
+
|
|
1674
|
+
The `map` operation transforms each element in a collection:
|
|
1675
|
+
|
|
1676
|
+
```prose
|
|
1677
|
+
let articles = ["article1", "article2", "article3"]
|
|
1678
|
+
|
|
1679
|
+
let summaries = articles | map:
|
|
1680
|
+
session "Summarize this article in one sentence"
|
|
1681
|
+
context: item
|
|
1682
|
+
```
|
|
1683
|
+
|
|
1684
|
+
Inside a map body, the implicit variable `item` refers to the current element being processed.
|
|
1685
|
+
|
|
1686
|
+
### Filter
|
|
1687
|
+
|
|
1688
|
+
The `filter` operation keeps elements that match a condition:
|
|
1689
|
+
|
|
1690
|
+
```prose
|
|
1691
|
+
let items = ["one", "two", "three", "four", "five"]
|
|
1692
|
+
|
|
1693
|
+
let short = items | filter:
|
|
1694
|
+
session "Does this word have 4 or fewer letters? Answer yes or no."
|
|
1695
|
+
context: item
|
|
1696
|
+
```
|
|
1697
|
+
|
|
1698
|
+
The session in a filter body should return something the OpenProse VM can interpret as truthy/falsy (like "yes"/"no").
|
|
1699
|
+
|
|
1700
|
+
### Reduce
|
|
1701
|
+
|
|
1702
|
+
The `reduce` operation accumulates elements into a single result:
|
|
1703
|
+
|
|
1704
|
+
```prose
|
|
1705
|
+
let ideas = ["AI assistant", "smart home", "health tracker"]
|
|
1706
|
+
|
|
1707
|
+
let combined = ideas | reduce(summary, idea):
|
|
1708
|
+
session "Add this idea to the summary, creating a cohesive concept"
|
|
1709
|
+
context: [summary, idea]
|
|
1710
|
+
```
|
|
1711
|
+
|
|
1712
|
+
The reduce operation requires explicit variable names:
|
|
1713
|
+
|
|
1714
|
+
- First variable (`summary`): the accumulator
|
|
1715
|
+
- Second variable (`idea`): the current item
|
|
1716
|
+
|
|
1717
|
+
The first item in the collection becomes the initial accumulator value.
|
|
1718
|
+
|
|
1719
|
+
### Parallel Map (pmap)
|
|
1720
|
+
|
|
1721
|
+
The `pmap` operation is like `map` but runs all transformations concurrently:
|
|
1722
|
+
|
|
1723
|
+
```prose
|
|
1724
|
+
let tasks = ["task1", "task2", "task3"]
|
|
1725
|
+
|
|
1726
|
+
let results = tasks | pmap:
|
|
1727
|
+
session "Process this task in parallel"
|
|
1728
|
+
context: item
|
|
1729
|
+
|
|
1730
|
+
session "Aggregate all results"
|
|
1731
|
+
context: results
|
|
1732
|
+
```
|
|
1733
|
+
|
|
1734
|
+
This is similar to `parallel for`, but in pipeline syntax.
|
|
1735
|
+
|
|
1736
|
+
### Chaining
|
|
1737
|
+
|
|
1738
|
+
Pipeline operations can be chained to compose complex transformations:
|
|
1739
|
+
|
|
1740
|
+
```prose
|
|
1741
|
+
let topics = ["quantum computing", "blockchain", "machine learning", "IoT"]
|
|
1742
|
+
|
|
1743
|
+
let result = topics
|
|
1744
|
+
| filter:
|
|
1745
|
+
session "Is this topic trending? Answer yes or no."
|
|
1746
|
+
context: item
|
|
1747
|
+
| map:
|
|
1748
|
+
session "Write a one-line startup pitch for this topic"
|
|
1749
|
+
context: item
|
|
1750
|
+
|
|
1751
|
+
session "Present the startup pitches"
|
|
1752
|
+
context: result
|
|
1753
|
+
```
|
|
1754
|
+
|
|
1755
|
+
Operations execute left-to-right: first filter, then map.
|
|
1756
|
+
|
|
1757
|
+
### Complete Example
|
|
1758
|
+
|
|
1759
|
+
```prose
|
|
1760
|
+
# Define a collection
|
|
1761
|
+
let articles = ["AI breakthroughs", "Climate solutions", "Space exploration"]
|
|
1762
|
+
|
|
1763
|
+
# Process with chained operations
|
|
1764
|
+
let summaries = articles
|
|
1765
|
+
| filter:
|
|
1766
|
+
session "Is this topic relevant to technology? Answer yes or no."
|
|
1767
|
+
context: item
|
|
1768
|
+
| map:
|
|
1769
|
+
session "Write a compelling one-paragraph summary"
|
|
1770
|
+
context: item
|
|
1771
|
+
| reduce(combined, summary):
|
|
1772
|
+
session "Merge this summary into the combined document"
|
|
1773
|
+
context: [combined, summary]
|
|
1774
|
+
|
|
1775
|
+
# Present the final result
|
|
1776
|
+
session "Format and present the combined summaries"
|
|
1777
|
+
context: summaries
|
|
1778
|
+
```
|
|
1779
|
+
|
|
1780
|
+
### Implicit Variables
|
|
1781
|
+
|
|
1782
|
+
| Operation | Available Variables |
|
|
1783
|
+
| --------- | -------------------------------------------- |
|
|
1784
|
+
| `map` | `item` - current element |
|
|
1785
|
+
| `filter` | `item` - current element |
|
|
1786
|
+
| `pmap` | `item` - current element |
|
|
1787
|
+
| `reduce` | Named explicitly: `reduce(accVar, itemVar):` |
|
|
1788
|
+
|
|
1789
|
+
### Execution Semantics
|
|
1790
|
+
|
|
1791
|
+
When the OpenProse VM encounters a pipeline:
|
|
1792
|
+
|
|
1793
|
+
1. **Input**: Start with the input collection
|
|
1794
|
+
2. **For each operation**:
|
|
1795
|
+
- **map**: Transform each element, producing a new collection
|
|
1796
|
+
- **filter**: Keep elements where the session returns truthy
|
|
1797
|
+
- **reduce**: Accumulate elements into a single value
|
|
1798
|
+
- **pmap**: Transform all elements concurrently
|
|
1799
|
+
3. **Output**: Return the final transformed collection/value
|
|
1800
|
+
|
|
1801
|
+
### Variable Scoping
|
|
1802
|
+
|
|
1803
|
+
Pipeline variables are scoped to their operation body:
|
|
1804
|
+
|
|
1805
|
+
```prose
|
|
1806
|
+
let item = "outer"
|
|
1807
|
+
let items = ["a", "b"]
|
|
1808
|
+
|
|
1809
|
+
let results = items | map:
|
|
1810
|
+
# 'item' here is the pipeline variable (shadows outer)
|
|
1811
|
+
session "process"
|
|
1812
|
+
context: item
|
|
1813
|
+
|
|
1814
|
+
# 'item' here refers to the outer variable again
|
|
1815
|
+
session "use outer"
|
|
1816
|
+
context: item
|
|
1817
|
+
```
|
|
1818
|
+
|
|
1819
|
+
### Validation Rules
|
|
1820
|
+
|
|
1821
|
+
| Check | Severity | Message |
|
|
1822
|
+
| ------------------------------- | -------- | -------------------------------------------------- |
|
|
1823
|
+
| Undefined input collection | Error | Undefined collection variable |
|
|
1824
|
+
| Invalid pipe operator | Error | Expected pipe operator (map, filter, reduce, pmap) |
|
|
1825
|
+
| Reduce without variables | Error | Expected accumulator and item variables |
|
|
1826
|
+
| Pipeline variable shadows outer | Warning | Implicit/explicit variable shadows outer variable |
|
|
1827
|
+
|
|
1828
|
+
---
|
|
1829
|
+
|
|
1830
|
+
## Error Handling
|
|
1831
|
+
|
|
1832
|
+
OpenProse provides structured error handling with try/catch/finally blocks, throw statements, and retry mechanisms for resilient workflows.
|
|
1833
|
+
|
|
1834
|
+
### Try/Catch Blocks
|
|
1835
|
+
|
|
1836
|
+
The `try:` block wraps operations that might fail. The `catch:` block handles errors.
|
|
1837
|
+
|
|
1838
|
+
```prose
|
|
1839
|
+
try:
|
|
1840
|
+
session "Attempt risky operation"
|
|
1841
|
+
catch:
|
|
1842
|
+
session "Handle the error gracefully"
|
|
1843
|
+
```
|
|
1844
|
+
|
|
1845
|
+
#### Error Variable Access
|
|
1846
|
+
|
|
1847
|
+
Use `catch as err:` to capture error context for the error handler:
|
|
1848
|
+
|
|
1849
|
+
```prose
|
|
1850
|
+
try:
|
|
1851
|
+
session "Call external API"
|
|
1852
|
+
catch as err:
|
|
1853
|
+
session "Log and handle the error"
|
|
1854
|
+
context: err
|
|
1855
|
+
```
|
|
1856
|
+
|
|
1857
|
+
The error variable (`err`) contains contextual information about what went wrong and is only accessible within the catch block.
|
|
1858
|
+
|
|
1859
|
+
### Try/Catch/Finally
|
|
1860
|
+
|
|
1861
|
+
The `finally:` block always executes, whether the try block succeeds or fails:
|
|
1862
|
+
|
|
1863
|
+
```prose
|
|
1864
|
+
try:
|
|
1865
|
+
session "Acquire and use resource"
|
|
1866
|
+
catch:
|
|
1867
|
+
session "Handle any errors"
|
|
1868
|
+
finally:
|
|
1869
|
+
session "Always clean up resource"
|
|
1870
|
+
```
|
|
1871
|
+
|
|
1872
|
+
#### Execution Order
|
|
1873
|
+
|
|
1874
|
+
1. **Try succeeds**: try body → finally body
|
|
1875
|
+
2. **Try fails**: try body (until failure) → catch body → finally body
|
|
1876
|
+
|
|
1877
|
+
### Try/Finally (No Catch)
|
|
1878
|
+
|
|
1879
|
+
For cleanup without error handling, use try/finally:
|
|
1880
|
+
|
|
1881
|
+
```prose
|
|
1882
|
+
try:
|
|
1883
|
+
session "Open connection and do work"
|
|
1884
|
+
finally:
|
|
1885
|
+
session "Close connection"
|
|
1886
|
+
```
|
|
1887
|
+
|
|
1888
|
+
### Throw Statement
|
|
1889
|
+
|
|
1890
|
+
The `throw` statement raises or re-raises errors.
|
|
1891
|
+
|
|
1892
|
+
#### Rethrow
|
|
1893
|
+
|
|
1894
|
+
Inside a catch block, `throw` without arguments re-raises the caught error to outer handlers:
|
|
1895
|
+
|
|
1896
|
+
```prose
|
|
1897
|
+
try:
|
|
1898
|
+
try:
|
|
1899
|
+
session "Inner operation"
|
|
1900
|
+
catch:
|
|
1901
|
+
session "Partial handling"
|
|
1902
|
+
throw # Re-raise to outer handler
|
|
1903
|
+
catch:
|
|
1904
|
+
session "Handle re-raised error"
|
|
1905
|
+
```
|
|
1906
|
+
|
|
1907
|
+
#### Throw with Message
|
|
1908
|
+
|
|
1909
|
+
Throw a new error with a custom message:
|
|
1910
|
+
|
|
1911
|
+
```prose
|
|
1912
|
+
session "Check preconditions"
|
|
1913
|
+
throw "Precondition not met"
|
|
1914
|
+
```
|
|
1915
|
+
|
|
1916
|
+
### Nested Error Handling
|
|
1917
|
+
|
|
1918
|
+
Try blocks can be nested. Inner catch blocks don't trigger outer handlers unless they rethrow:
|
|
1919
|
+
|
|
1920
|
+
```prose
|
|
1921
|
+
try:
|
|
1922
|
+
session "Outer operation"
|
|
1923
|
+
try:
|
|
1924
|
+
session "Inner risky operation"
|
|
1925
|
+
catch:
|
|
1926
|
+
session "Handle inner error" # Outer catch won't run
|
|
1927
|
+
session "Continue outer operation"
|
|
1928
|
+
catch:
|
|
1929
|
+
session "Handle outer error only"
|
|
1930
|
+
```
|
|
1931
|
+
|
|
1932
|
+
### Error Handling in Parallel
|
|
1933
|
+
|
|
1934
|
+
Each parallel branch can have its own error handling:
|
|
1935
|
+
|
|
1936
|
+
```prose
|
|
1937
|
+
parallel:
|
|
1938
|
+
try:
|
|
1939
|
+
session "Branch A might fail"
|
|
1940
|
+
catch:
|
|
1941
|
+
session "Recover branch A"
|
|
1942
|
+
try:
|
|
1943
|
+
session "Branch B might fail"
|
|
1944
|
+
catch:
|
|
1945
|
+
session "Recover branch B"
|
|
1946
|
+
|
|
1947
|
+
session "Continue with recovered results"
|
|
1948
|
+
```
|
|
1949
|
+
|
|
1950
|
+
This differs from the `on-fail:` policy which controls behavior when unhandled errors occur.
|
|
1951
|
+
|
|
1952
|
+
### Retry Property
|
|
1953
|
+
|
|
1954
|
+
The `retry:` property makes a session automatically retry on failure:
|
|
1955
|
+
|
|
1956
|
+
```prose
|
|
1957
|
+
session "Call flaky API"
|
|
1958
|
+
retry: 3
|
|
1959
|
+
```
|
|
1960
|
+
|
|
1961
|
+
#### Retry with Backoff
|
|
1962
|
+
|
|
1963
|
+
Add `backoff:` to control delay between retries:
|
|
1964
|
+
|
|
1965
|
+
```prose
|
|
1966
|
+
session "Rate-limited API"
|
|
1967
|
+
retry: 5
|
|
1968
|
+
backoff: "exponential"
|
|
1969
|
+
```
|
|
1970
|
+
|
|
1971
|
+
**Backoff Strategies:**
|
|
1972
|
+
|
|
1973
|
+
| Strategy | Behavior |
|
|
1974
|
+
| --------------- | ---------------------------------- |
|
|
1975
|
+
| `"none"` | Immediate retry (default) |
|
|
1976
|
+
| `"linear"` | Fixed delay between retries |
|
|
1977
|
+
| `"exponential"` | Doubling delay (1s, 2s, 4s, 8s...) |
|
|
1978
|
+
|
|
1979
|
+
#### Retry with Context
|
|
1980
|
+
|
|
1981
|
+
Retry works with other session properties:
|
|
1982
|
+
|
|
1983
|
+
```prose
|
|
1984
|
+
let data = session "Get input"
|
|
1985
|
+
session "Process data"
|
|
1986
|
+
context: data
|
|
1987
|
+
retry: 3
|
|
1988
|
+
backoff: "linear"
|
|
1989
|
+
```
|
|
1990
|
+
|
|
1991
|
+
### Combining Patterns
|
|
1992
|
+
|
|
1993
|
+
Retry and try/catch work together for maximum resilience:
|
|
1994
|
+
|
|
1995
|
+
```prose
|
|
1996
|
+
try:
|
|
1997
|
+
session "Call external service"
|
|
1998
|
+
retry: 3
|
|
1999
|
+
backoff: "exponential"
|
|
2000
|
+
catch:
|
|
2001
|
+
session "All retries failed, use fallback"
|
|
2002
|
+
```
|
|
2003
|
+
|
|
2004
|
+
### Validation Rules
|
|
2005
|
+
|
|
2006
|
+
| Check | Severity | Message |
|
|
2007
|
+
| ---------------------------- | -------- | --------------------------------------------------- |
|
|
2008
|
+
| Try without catch or finally | Error | Try block must have at least "catch:" or "finally:" |
|
|
2009
|
+
| Error variable shadows outer | Warning | Error variable shadows outer variable |
|
|
2010
|
+
| Empty throw message | Warning | Throw message is empty |
|
|
2011
|
+
| Non-positive retry count | Error | Retry count must be positive |
|
|
2012
|
+
| Non-integer retry count | Error | Retry count must be an integer |
|
|
2013
|
+
| High retry count (>10) | Warning | Retry count is unusually high |
|
|
2014
|
+
| Invalid backoff strategy | Error | Must be "none", "linear", or "exponential" |
|
|
2015
|
+
| Retry on agent definition | Warning | Retry property is only valid in session statements |
|
|
2016
|
+
|
|
2017
|
+
### Syntax Reference
|
|
2018
|
+
|
|
2019
|
+
```
|
|
2020
|
+
try_block ::= "try" ":" NEWLINE INDENT statement+ DEDENT
|
|
2021
|
+
[catch_block]
|
|
2022
|
+
[finally_block]
|
|
2023
|
+
|
|
2024
|
+
catch_block ::= "catch" ["as" identifier] ":" NEWLINE INDENT statement+ DEDENT
|
|
2025
|
+
|
|
2026
|
+
finally_block ::= "finally" ":" NEWLINE INDENT statement+ DEDENT
|
|
2027
|
+
|
|
2028
|
+
throw_statement ::= "throw" [string_literal]
|
|
2029
|
+
|
|
2030
|
+
retry_property ::= "retry" ":" number_literal
|
|
2031
|
+
|
|
2032
|
+
backoff_property ::= "backoff" ":" string_literal
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
---
|
|
2036
|
+
|
|
2037
|
+
## Choice Blocks
|
|
2038
|
+
|
|
2039
|
+
Choice blocks allow the OpenProse VM to select from multiple labeled options based on criteria. This is useful for branching workflows where the best path depends on runtime analysis.
|
|
2040
|
+
|
|
2041
|
+
### Syntax
|
|
2042
|
+
|
|
2043
|
+
```prose
|
|
2044
|
+
choice **criteria**:
|
|
2045
|
+
option "Label A":
|
|
2046
|
+
statements...
|
|
2047
|
+
option "Label B":
|
|
2048
|
+
statements...
|
|
2049
|
+
```
|
|
2050
|
+
|
|
2051
|
+
### Criteria
|
|
2052
|
+
|
|
2053
|
+
The criteria is wrapped in discretion markers (`**...**`) and is evaluated by the OpenProse VM to select which option to execute:
|
|
2054
|
+
|
|
2055
|
+
```prose
|
|
2056
|
+
choice **the best approach for the current situation**:
|
|
2057
|
+
option "Quick fix":
|
|
2058
|
+
session "Apply a quick temporary fix"
|
|
2059
|
+
option "Full refactor":
|
|
2060
|
+
session "Perform a complete code refactor"
|
|
2061
|
+
```
|
|
2062
|
+
|
|
2063
|
+
### Multi-line Criteria
|
|
2064
|
+
|
|
2065
|
+
For complex criteria, use triple-asterisks:
|
|
2066
|
+
|
|
2067
|
+
```prose
|
|
2068
|
+
choice ***
|
|
2069
|
+
which strategy is most appropriate
|
|
2070
|
+
given the current project constraints
|
|
2071
|
+
and timeline requirements
|
|
2072
|
+
***:
|
|
2073
|
+
option "MVP approach":
|
|
2074
|
+
session "Build minimum viable product"
|
|
2075
|
+
option "Full feature set":
|
|
2076
|
+
session "Build complete feature set"
|
|
2077
|
+
```
|
|
2078
|
+
|
|
2079
|
+
### Examples
|
|
2080
|
+
|
|
2081
|
+
#### Simple Choice
|
|
2082
|
+
|
|
2083
|
+
```prose
|
|
2084
|
+
let analysis = session "Analyze the code quality"
|
|
2085
|
+
|
|
2086
|
+
choice **the severity of issues found in the analysis**:
|
|
2087
|
+
option "Critical":
|
|
2088
|
+
session "Stop deployment and fix critical issues"
|
|
2089
|
+
context: analysis
|
|
2090
|
+
option "Minor":
|
|
2091
|
+
session "Log issues for later and proceed"
|
|
2092
|
+
context: analysis
|
|
2093
|
+
option "None":
|
|
2094
|
+
session "Proceed with deployment"
|
|
2095
|
+
```
|
|
2096
|
+
|
|
2097
|
+
#### Choice with Multiple Statements per Option
|
|
2098
|
+
|
|
2099
|
+
```prose
|
|
2100
|
+
choice **the user's experience level**:
|
|
2101
|
+
option "Beginner":
|
|
2102
|
+
session "Explain basic concepts first"
|
|
2103
|
+
session "Provide step-by-step guidance"
|
|
2104
|
+
session "Include helpful tips and warnings"
|
|
2105
|
+
option "Expert":
|
|
2106
|
+
session "Provide concise technical summary"
|
|
2107
|
+
session "Include advanced configuration options"
|
|
2108
|
+
```
|
|
2109
|
+
|
|
2110
|
+
#### Nested Choices
|
|
2111
|
+
|
|
2112
|
+
```prose
|
|
2113
|
+
choice **the type of request**:
|
|
2114
|
+
option "Bug report":
|
|
2115
|
+
choice **the bug severity**:
|
|
2116
|
+
option "Critical":
|
|
2117
|
+
session "Escalate immediately"
|
|
2118
|
+
option "Normal":
|
|
2119
|
+
session "Add to sprint backlog"
|
|
2120
|
+
option "Feature request":
|
|
2121
|
+
session "Add to feature backlog"
|
|
2122
|
+
```
|
|
2123
|
+
|
|
2124
|
+
### Execution Semantics
|
|
2125
|
+
|
|
2126
|
+
When the OpenProse VM encounters a `choice` block:
|
|
2127
|
+
|
|
2128
|
+
1. **Evaluate Criteria**: Interpret the discretion criteria in current context
|
|
2129
|
+
2. **Select Option**: Choose the most appropriate labeled option
|
|
2130
|
+
3. **Execute**: Run all statements in the selected option's body
|
|
2131
|
+
4. **Continue**: Proceed to the next statement after the choice block
|
|
2132
|
+
|
|
2133
|
+
Only one option is executed per choice block.
|
|
2134
|
+
|
|
2135
|
+
### Validation Rules
|
|
2136
|
+
|
|
2137
|
+
| Check | Severity | Message |
|
|
2138
|
+
| ----------------------- | -------- | ------------------------------------------ |
|
|
2139
|
+
| Choice without options | Error | Choice block must have at least one option |
|
|
2140
|
+
| Empty criteria | Error | Choice criteria cannot be empty |
|
|
2141
|
+
| Duplicate option labels | Warning | Duplicate option label |
|
|
2142
|
+
| Empty option body | Warning | Option has empty body |
|
|
2143
|
+
|
|
2144
|
+
### Syntax Reference
|
|
2145
|
+
|
|
2146
|
+
```
|
|
2147
|
+
choice_block ::= "choice" discretion ":" NEWLINE INDENT option+ DEDENT
|
|
2148
|
+
|
|
2149
|
+
option ::= "option" string ":" NEWLINE INDENT statement+ DEDENT
|
|
2150
|
+
|
|
2151
|
+
discretion ::= "**" text "**" | "***" text "***"
|
|
2152
|
+
```
|
|
2153
|
+
|
|
2154
|
+
---
|
|
2155
|
+
|
|
2156
|
+
## Conditional Statements
|
|
2157
|
+
|
|
2158
|
+
If/elif/else statements provide conditional branching based on AI-evaluated conditions using discretion markers.
|
|
2159
|
+
|
|
2160
|
+
### If Statement
|
|
2161
|
+
|
|
2162
|
+
```prose
|
|
2163
|
+
if **condition**:
|
|
2164
|
+
statements...
|
|
2165
|
+
```
|
|
2166
|
+
|
|
2167
|
+
### If/Else
|
|
2168
|
+
|
|
2169
|
+
```prose
|
|
2170
|
+
if **condition**:
|
|
2171
|
+
statements...
|
|
2172
|
+
else:
|
|
2173
|
+
statements...
|
|
2174
|
+
```
|
|
2175
|
+
|
|
2176
|
+
### If/Elif/Else
|
|
2177
|
+
|
|
2178
|
+
```prose
|
|
2179
|
+
if **first condition**:
|
|
2180
|
+
statements...
|
|
2181
|
+
elif **second condition**:
|
|
2182
|
+
statements...
|
|
2183
|
+
elif **third condition**:
|
|
2184
|
+
statements...
|
|
2185
|
+
else:
|
|
2186
|
+
statements...
|
|
2187
|
+
```
|
|
2188
|
+
|
|
2189
|
+
### Discretion Conditions
|
|
2190
|
+
|
|
2191
|
+
Conditions are wrapped in discretion markers (`**...**`) for AI evaluation:
|
|
2192
|
+
|
|
2193
|
+
```prose
|
|
2194
|
+
let analysis = session "Analyze the codebase"
|
|
2195
|
+
|
|
2196
|
+
if **the code has security vulnerabilities**:
|
|
2197
|
+
session "Fix security issues immediately"
|
|
2198
|
+
context: analysis
|
|
2199
|
+
elif **the code has performance issues**:
|
|
2200
|
+
session "Optimize performance bottlenecks"
|
|
2201
|
+
context: analysis
|
|
2202
|
+
else:
|
|
2203
|
+
session "Proceed with normal review"
|
|
2204
|
+
context: analysis
|
|
2205
|
+
```
|
|
2206
|
+
|
|
2207
|
+
### Multi-line Conditions
|
|
2208
|
+
|
|
2209
|
+
Use triple-asterisks for complex conditions:
|
|
2210
|
+
|
|
2211
|
+
```prose
|
|
2212
|
+
if ***
|
|
2213
|
+
the test suite passes
|
|
2214
|
+
and the code coverage is above 80%
|
|
2215
|
+
and there are no linting errors
|
|
2216
|
+
***:
|
|
2217
|
+
session "Deploy to production"
|
|
2218
|
+
else:
|
|
2219
|
+
session "Fix issues before deploying"
|
|
2220
|
+
```
|
|
2221
|
+
|
|
2222
|
+
### Examples
|
|
2223
|
+
|
|
2224
|
+
#### Simple If
|
|
2225
|
+
|
|
2226
|
+
```prose
|
|
2227
|
+
session "Check system health"
|
|
2228
|
+
|
|
2229
|
+
if **the system is healthy**:
|
|
2230
|
+
session "Continue with normal operations"
|
|
2231
|
+
```
|
|
2232
|
+
|
|
2233
|
+
#### If/Else
|
|
2234
|
+
|
|
2235
|
+
```prose
|
|
2236
|
+
let review = session "Review the pull request"
|
|
2237
|
+
|
|
2238
|
+
if **the code changes are safe and well-tested**:
|
|
2239
|
+
session "Approve and merge the PR"
|
|
2240
|
+
context: review
|
|
2241
|
+
else:
|
|
2242
|
+
session "Request changes"
|
|
2243
|
+
context: review
|
|
2244
|
+
```
|
|
2245
|
+
|
|
2246
|
+
#### Multiple Elif
|
|
2247
|
+
|
|
2248
|
+
```prose
|
|
2249
|
+
let status = session "Check project status"
|
|
2250
|
+
|
|
2251
|
+
if **the project is on track**:
|
|
2252
|
+
session "Continue as planned"
|
|
2253
|
+
elif **the project is slightly delayed**:
|
|
2254
|
+
session "Adjust timeline and communicate"
|
|
2255
|
+
elif **the project is significantly delayed**:
|
|
2256
|
+
session "Escalate to management"
|
|
2257
|
+
session "Create recovery plan"
|
|
2258
|
+
else:
|
|
2259
|
+
session "Assess project viability"
|
|
2260
|
+
```
|
|
2261
|
+
|
|
2262
|
+
#### Nested Conditionals
|
|
2263
|
+
|
|
2264
|
+
```prose
|
|
2265
|
+
if **the request is authenticated**:
|
|
2266
|
+
if **the user has admin privileges**:
|
|
2267
|
+
session "Process admin request"
|
|
2268
|
+
else:
|
|
2269
|
+
session "Process standard user request"
|
|
2270
|
+
else:
|
|
2271
|
+
session "Return authentication error"
|
|
2272
|
+
```
|
|
2273
|
+
|
|
2274
|
+
### Combining with Other Constructs
|
|
2275
|
+
|
|
2276
|
+
#### With Try/Catch
|
|
2277
|
+
|
|
2278
|
+
```prose
|
|
2279
|
+
try:
|
|
2280
|
+
session "Attempt operation"
|
|
2281
|
+
if **operation succeeded partially**:
|
|
2282
|
+
session "Complete remaining steps"
|
|
2283
|
+
catch as err:
|
|
2284
|
+
if **error is recoverable**:
|
|
2285
|
+
session "Apply recovery procedure"
|
|
2286
|
+
context: err
|
|
2287
|
+
else:
|
|
2288
|
+
throw "Unrecoverable error"
|
|
2289
|
+
```
|
|
2290
|
+
|
|
2291
|
+
#### With Loops
|
|
2292
|
+
|
|
2293
|
+
```prose
|
|
2294
|
+
loop until **task complete** (max: 10):
|
|
2295
|
+
session "Work on task"
|
|
2296
|
+
if **encountered blocker**:
|
|
2297
|
+
session "Resolve blocker"
|
|
2298
|
+
```
|
|
2299
|
+
|
|
2300
|
+
### Execution Semantics
|
|
2301
|
+
|
|
2302
|
+
When the OpenProse VM encounters an `if` statement:
|
|
2303
|
+
|
|
2304
|
+
1. **Evaluate Condition**: Interpret the first discretion condition
|
|
2305
|
+
2. **If True**: Execute the then-body and skip remaining clauses
|
|
2306
|
+
3. **If False**: Check each `elif` condition in order
|
|
2307
|
+
4. **Elif Match**: Execute that elif's body and skip remaining
|
|
2308
|
+
5. **No Match**: Execute the `else` body (if present)
|
|
2309
|
+
6. **Continue**: Proceed to the next statement
|
|
2310
|
+
|
|
2311
|
+
### Validation Rules
|
|
2312
|
+
|
|
2313
|
+
| Check | Severity | Message |
|
|
2314
|
+
| --------------- | -------- | --------------------------------- |
|
|
2315
|
+
| Empty condition | Error | If/elif condition cannot be empty |
|
|
2316
|
+
| Elif without if | Error | Elif must follow if |
|
|
2317
|
+
| Else without if | Error | Else must follow if or elif |
|
|
2318
|
+
| Multiple else | Error | Only one else clause allowed |
|
|
2319
|
+
| Empty body | Warning | Condition has empty body |
|
|
2320
|
+
|
|
2321
|
+
### Syntax Reference
|
|
2322
|
+
|
|
2323
|
+
```
|
|
2324
|
+
if_statement ::= "if" discretion ":" NEWLINE INDENT statement+ DEDENT
|
|
2325
|
+
elif_clause*
|
|
2326
|
+
[else_clause]
|
|
2327
|
+
|
|
2328
|
+
elif_clause ::= "elif" discretion ":" NEWLINE INDENT statement+ DEDENT
|
|
2329
|
+
|
|
2330
|
+
else_clause ::= "else" ":" NEWLINE INDENT statement+ DEDENT
|
|
2331
|
+
|
|
2332
|
+
discretion ::= "**" text "**" | "***" text "***"
|
|
2333
|
+
```
|
|
2334
|
+
|
|
2335
|
+
---
|
|
2336
|
+
|
|
2337
|
+
## Execution Model
|
|
2338
|
+
|
|
2339
|
+
OpenProse uses a two-phase execution model.
|
|
2340
|
+
|
|
2341
|
+
### Phase 1: Compilation (Static)
|
|
2342
|
+
|
|
2343
|
+
The compile phase handles deterministic preprocessing:
|
|
2344
|
+
|
|
2345
|
+
1. **Parse**: Convert source code to AST
|
|
2346
|
+
2. **Validate**: Check for syntax and semantic errors
|
|
2347
|
+
3. **Expand**: Normalize syntax sugar (when implemented)
|
|
2348
|
+
4. **Output**: Generate canonical program
|
|
2349
|
+
|
|
2350
|
+
### Phase 2: Runtime (Intelligent)
|
|
2351
|
+
|
|
2352
|
+
The OpenProse VM executes the compiled program:
|
|
2353
|
+
|
|
2354
|
+
1. **Load**: Receive the compiled program
|
|
2355
|
+
2. **Collect Agents**: Register all agent definitions
|
|
2356
|
+
3. **Execute**: Process each statement in order
|
|
2357
|
+
4. **Spawn**: Create subagents with resolved configurations
|
|
2358
|
+
5. **Coordinate**: Manage context passing between sessions
|
|
2359
|
+
|
|
2360
|
+
### OpenProse VM Behavior
|
|
2361
|
+
|
|
2362
|
+
| Aspect | Behavior |
|
|
2363
|
+
| -------------------- | ----------------------------------------------- |
|
|
2364
|
+
| Execution order | Strict - follows program exactly |
|
|
2365
|
+
| Session creation | Strict - creates what program specifies |
|
|
2366
|
+
| Agent resolution | Strict - merge properties deterministically |
|
|
2367
|
+
| Context passing | Intelligent - summarizes/transforms as needed |
|
|
2368
|
+
| Completion detection | Intelligent - determines when session is "done" |
|
|
2369
|
+
|
|
2370
|
+
### State Management
|
|
2371
|
+
|
|
2372
|
+
For the current implementation, state is tracked in-context (conversation history):
|
|
2373
|
+
|
|
2374
|
+
| State Type | Tracking Approach |
|
|
2375
|
+
| ------------------- | --------------------------------------------------- |
|
|
2376
|
+
| Agent definitions | Collected at program start |
|
|
2377
|
+
| Execution flow | Implicit reasoning ("completed X, now executing Y") |
|
|
2378
|
+
| Session outputs | Held in conversation history |
|
|
2379
|
+
| Position in program | Tracked by OpenProse VM |
|
|
2380
|
+
|
|
2381
|
+
---
|
|
2382
|
+
|
|
2383
|
+
## Validation Rules
|
|
2384
|
+
|
|
2385
|
+
The validator checks programs for errors and warnings before execution.
|
|
2386
|
+
|
|
2387
|
+
### Errors (Block Execution)
|
|
2388
|
+
|
|
2389
|
+
| Code | Description |
|
|
2390
|
+
| ---- | ----------------------------------- |
|
|
2391
|
+
| E001 | Unterminated string literal |
|
|
2392
|
+
| E002 | Unknown escape sequence in string |
|
|
2393
|
+
| E003 | Session missing prompt or agent |
|
|
2394
|
+
| E004 | Unexpected token |
|
|
2395
|
+
| E005 | Invalid syntax |
|
|
2396
|
+
| E006 | Duplicate agent definition |
|
|
2397
|
+
| E007 | Undefined agent reference |
|
|
2398
|
+
| E008 | Invalid model value |
|
|
2399
|
+
| E009 | Duplicate property |
|
|
2400
|
+
| E010 | Duplicate import |
|
|
2401
|
+
| E011 | Empty import skill name |
|
|
2402
|
+
| E012 | Empty import source |
|
|
2403
|
+
| E013 | Skills must be an array |
|
|
2404
|
+
| E014 | Skill name must be a string |
|
|
2405
|
+
| E015 | Permissions must be a block |
|
|
2406
|
+
| E016 | Permission pattern must be a string |
|
|
2407
|
+
|
|
2408
|
+
### Warnings (Non-blocking)
|
|
2409
|
+
|
|
2410
|
+
| Code | Description |
|
|
2411
|
+
| ---- | ---------------------------------------- |
|
|
2412
|
+
| W001 | Empty session prompt |
|
|
2413
|
+
| W002 | Whitespace-only session prompt |
|
|
2414
|
+
| W003 | Session prompt exceeds 10,000 characters |
|
|
2415
|
+
| W004 | Empty prompt property |
|
|
2416
|
+
| W005 | Unknown property name |
|
|
2417
|
+
| W006 | Unknown import source format |
|
|
2418
|
+
| W007 | Skill not imported |
|
|
2419
|
+
| W008 | Unknown permission type |
|
|
2420
|
+
| W009 | Unknown permission value |
|
|
2421
|
+
| W010 | Empty skills array |
|
|
2422
|
+
|
|
2423
|
+
### Error Message Format
|
|
2424
|
+
|
|
2425
|
+
Errors include location information:
|
|
2426
|
+
|
|
2427
|
+
```
|
|
2428
|
+
Error at line 5, column 12: Unterminated string literal
|
|
2429
|
+
session "Hello
|
|
2430
|
+
^
|
|
2431
|
+
```
|
|
2432
|
+
|
|
2433
|
+
---
|
|
2434
|
+
|
|
2435
|
+
## Examples
|
|
2436
|
+
|
|
2437
|
+
### Minimal Program
|
|
2438
|
+
|
|
2439
|
+
```prose
|
|
2440
|
+
session "Hello world"
|
|
2441
|
+
```
|
|
2442
|
+
|
|
2443
|
+
### Research Pipeline with Agents
|
|
2444
|
+
|
|
2445
|
+
```prose
|
|
2446
|
+
# Define specialized agents
|
|
2447
|
+
agent researcher:
|
|
2448
|
+
model: sonnet
|
|
2449
|
+
prompt: "You are a research assistant"
|
|
2450
|
+
|
|
2451
|
+
agent writer:
|
|
2452
|
+
model: opus
|
|
2453
|
+
prompt: "You are a technical writer"
|
|
2454
|
+
|
|
2455
|
+
# Execute workflow
|
|
2456
|
+
session: researcher
|
|
2457
|
+
prompt: "Research recent developments in quantum computing"
|
|
2458
|
+
|
|
2459
|
+
session: writer
|
|
2460
|
+
prompt: "Write a summary of the research findings"
|
|
2461
|
+
```
|
|
2462
|
+
|
|
2463
|
+
### Code Review Workflow
|
|
2464
|
+
|
|
2465
|
+
```prose
|
|
2466
|
+
agent reviewer:
|
|
2467
|
+
model: sonnet
|
|
2468
|
+
prompt: "You are an expert code reviewer"
|
|
2469
|
+
|
|
2470
|
+
session: reviewer
|
|
2471
|
+
prompt: "Read the code in src/ and identify potential bugs"
|
|
2472
|
+
|
|
2473
|
+
session: reviewer
|
|
2474
|
+
prompt: "Suggest fixes for each bug found"
|
|
2475
|
+
|
|
2476
|
+
session: reviewer
|
|
2477
|
+
prompt: "Create a summary of all changes needed"
|
|
2478
|
+
```
|
|
2479
|
+
|
|
2480
|
+
### Multi-step Task with Model Override
|
|
2481
|
+
|
|
2482
|
+
```prose
|
|
2483
|
+
agent analyst:
|
|
2484
|
+
model: haiku
|
|
2485
|
+
prompt: "You analyze data quickly"
|
|
2486
|
+
|
|
2487
|
+
# Quick initial analysis
|
|
2488
|
+
session: analyst
|
|
2489
|
+
prompt: "Scan the data for obvious patterns"
|
|
2490
|
+
|
|
2491
|
+
# Detailed analysis with more powerful model
|
|
2492
|
+
session: analyst
|
|
2493
|
+
model: opus
|
|
2494
|
+
prompt: "Perform deep analysis on the patterns found"
|
|
2495
|
+
```
|
|
2496
|
+
|
|
2497
|
+
### Comments for Documentation
|
|
2498
|
+
|
|
2499
|
+
```prose
|
|
2500
|
+
# Project: Quarterly Report Generator
|
|
2501
|
+
# Author: Team Lead
|
|
2502
|
+
# Date: 2024-01-01
|
|
2503
|
+
|
|
2504
|
+
agent data-collector:
|
|
2505
|
+
model: sonnet
|
|
2506
|
+
prompt: "You gather and organize data"
|
|
2507
|
+
|
|
2508
|
+
agent analyst:
|
|
2509
|
+
model: opus
|
|
2510
|
+
prompt: "You analyze data and create insights"
|
|
2511
|
+
|
|
2512
|
+
# Step 1: Gather data
|
|
2513
|
+
session: data-collector
|
|
2514
|
+
prompt: "Collect all sales data from the past quarter"
|
|
2515
|
+
|
|
2516
|
+
# Step 2: Analysis
|
|
2517
|
+
session: analyst
|
|
2518
|
+
prompt: "Perform trend analysis on the collected data"
|
|
2519
|
+
|
|
2520
|
+
# Step 3: Report generation
|
|
2521
|
+
session: analyst
|
|
2522
|
+
prompt: "Generate a formatted quarterly report with charts"
|
|
2523
|
+
```
|
|
2524
|
+
|
|
2525
|
+
### Workflow with Skills and Permissions
|
|
2526
|
+
|
|
2527
|
+
```prose
|
|
2528
|
+
# Import external skills
|
|
2529
|
+
import "web-search" from "github:anthropic/skills"
|
|
2530
|
+
import "file-writer" from "./local-skills"
|
|
2531
|
+
|
|
2532
|
+
# Define a secure research agent
|
|
2533
|
+
agent researcher:
|
|
2534
|
+
model: sonnet
|
|
2535
|
+
prompt: "You are a research assistant"
|
|
2536
|
+
skills: ["web-search"]
|
|
2537
|
+
permissions:
|
|
2538
|
+
read: ["*.md", "*.txt"]
|
|
2539
|
+
bash: deny
|
|
2540
|
+
|
|
2541
|
+
# Define a writer agent
|
|
2542
|
+
agent writer:
|
|
2543
|
+
model: opus
|
|
2544
|
+
prompt: "You create documentation"
|
|
2545
|
+
skills: ["file-writer"]
|
|
2546
|
+
permissions:
|
|
2547
|
+
write: ["docs/"]
|
|
2548
|
+
bash: deny
|
|
2549
|
+
|
|
2550
|
+
# Execute workflow
|
|
2551
|
+
session: researcher
|
|
2552
|
+
prompt: "Research AI safety topics"
|
|
2553
|
+
|
|
2554
|
+
session: writer
|
|
2555
|
+
prompt: "Write a summary document"
|
|
2556
|
+
```
|
|
2557
|
+
|
|
2558
|
+
---
|
|
2559
|
+
|
|
2560
|
+
## Future Features
|
|
2561
|
+
|
|
2562
|
+
All core features through Tier 12 have been implemented. Potential future enhancements:
|
|
2563
|
+
|
|
2564
|
+
### Tier 13: Extended Features
|
|
2565
|
+
|
|
2566
|
+
- Custom functions with return values
|
|
2567
|
+
- Module system for code organization
|
|
2568
|
+
- Type annotations for validation
|
|
2569
|
+
- Async/await patterns for advanced concurrency
|
|
2570
|
+
|
|
2571
|
+
### Tier 14: Tooling
|
|
2572
|
+
|
|
2573
|
+
- Language server protocol (LSP) support
|
|
2574
|
+
- VS Code extension
|
|
2575
|
+
- Interactive debugger
|
|
2576
|
+
- Performance profiling
|
|
2577
|
+
|
|
2578
|
+
---
|
|
2579
|
+
|
|
2580
|
+
## Syntax Grammar (Implemented)
|
|
2581
|
+
|
|
2582
|
+
```
|
|
2583
|
+
program → statement* EOF
|
|
2584
|
+
statement → agentDef | blockDef | parallelBlock | repeatBlock | forEachBlock
|
|
2585
|
+
| loopBlock | tryBlock | choiceBlock | ifStatement | session
|
|
2586
|
+
| doBlock | arrowExpr | letBinding | constBinding | assignment
|
|
2587
|
+
| throwStatement | comment
|
|
2588
|
+
|
|
2589
|
+
# Definitions
|
|
2590
|
+
agentDef → "agent" IDENTIFIER ":" NEWLINE INDENT property* DEDENT
|
|
2591
|
+
blockDef → "block" IDENTIFIER params? ":" NEWLINE INDENT statement* DEDENT
|
|
2592
|
+
params → "(" IDENTIFIER ( "," IDENTIFIER )* ")"
|
|
2593
|
+
|
|
2594
|
+
# Control Flow
|
|
2595
|
+
parallelBlock → "parallel" parallelMods? ":" NEWLINE INDENT parallelBranch* DEDENT
|
|
2596
|
+
parallelMods → "(" ( joinStrategy | onFail | countMod ) ( "," ( joinStrategy | onFail | countMod ) )* ")"
|
|
2597
|
+
joinStrategy → string # "all" | "first" | "any"
|
|
2598
|
+
onFail → "on-fail" ":" string # "fail-fast" | "continue" | "ignore"
|
|
2599
|
+
countMod → "count" ":" NUMBER # only valid with "any"
|
|
2600
|
+
parallelBranch → ( IDENTIFIER "=" )? statement
|
|
2601
|
+
|
|
2602
|
+
# Loops
|
|
2603
|
+
repeatBlock → "repeat" NUMBER ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement* DEDENT
|
|
2604
|
+
forEachBlock → "parallel"? "for" IDENTIFIER ( "," IDENTIFIER )? "in" collection ":" NEWLINE INDENT statement* DEDENT
|
|
2605
|
+
loopBlock → "loop" ( ( "until" | "while" ) discretion )? loopMods? ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement* DEDENT
|
|
2606
|
+
loopMods → "(" "max" ":" NUMBER ")"
|
|
2607
|
+
|
|
2608
|
+
# Error Handling
|
|
2609
|
+
tryBlock → "try" ":" NEWLINE INDENT statement+ DEDENT catchBlock? finallyBlock?
|
|
2610
|
+
catchBlock → "catch" ( "as" IDENTIFIER )? ":" NEWLINE INDENT statement+ DEDENT
|
|
2611
|
+
finallyBlock → "finally" ":" NEWLINE INDENT statement+ DEDENT
|
|
2612
|
+
throwStatement → "throw" string?
|
|
2613
|
+
|
|
2614
|
+
# Conditionals
|
|
2615
|
+
choiceBlock → "choice" discretion ":" NEWLINE INDENT choiceOption+ DEDENT
|
|
2616
|
+
choiceOption → "option" string ":" NEWLINE INDENT statement+ DEDENT
|
|
2617
|
+
ifStatement → "if" discretion ":" NEWLINE INDENT statement+ DEDENT elifClause* elseClause?
|
|
2618
|
+
elifClause → "elif" discretion ":" NEWLINE INDENT statement+ DEDENT
|
|
2619
|
+
elseClause → "else" ":" NEWLINE INDENT statement+ DEDENT
|
|
2620
|
+
|
|
2621
|
+
# Blocks and Sequences
|
|
2622
|
+
doBlock → "do" ( ":" NEWLINE INDENT statement* DEDENT | IDENTIFIER args? )
|
|
2623
|
+
args → "(" expression ( "," expression )* ")"
|
|
2624
|
+
arrowExpr → session "->" session ( "->" session )*
|
|
2625
|
+
|
|
2626
|
+
# Sessions
|
|
2627
|
+
session → "session" ( string | ":" IDENTIFIER | IDENTIFIER ":" IDENTIFIER )
|
|
2628
|
+
( NEWLINE INDENT property* DEDENT )?
|
|
2629
|
+
|
|
2630
|
+
# Bindings
|
|
2631
|
+
letBinding → "let" IDENTIFIER "=" expression
|
|
2632
|
+
constBinding → "const" IDENTIFIER "=" expression
|
|
2633
|
+
assignment → IDENTIFIER "=" expression
|
|
2634
|
+
|
|
2635
|
+
# Expressions
|
|
2636
|
+
expression → session | doBlock | parallelBlock | repeatBlock | forEachBlock
|
|
2637
|
+
| loopBlock | arrowExpr | pipeExpr | string | IDENTIFIER | array | objectContext
|
|
2638
|
+
|
|
2639
|
+
# Pipelines
|
|
2640
|
+
pipeExpr → ( IDENTIFIER | array ) ( "|" pipeOp )+
|
|
2641
|
+
pipeOp → ( "map" | "filter" | "pmap" ) ":" NEWLINE INDENT statement* DEDENT
|
|
2642
|
+
| "reduce" "(" IDENTIFIER "," IDENTIFIER ")" ":" NEWLINE INDENT statement* DEDENT
|
|
2643
|
+
|
|
2644
|
+
# Properties
|
|
2645
|
+
property → ( "model" | "prompt" | "context" | "retry" | "backoff" | IDENTIFIER )
|
|
2646
|
+
":" ( IDENTIFIER | string | array | objectContext | NUMBER )
|
|
2647
|
+
|
|
2648
|
+
# Primitives
|
|
2649
|
+
discretion → "**" text "**" | "***" text "***"
|
|
2650
|
+
collection → IDENTIFIER | array
|
|
2651
|
+
array → "[" ( expression ( "," expression )* )? "]"
|
|
2652
|
+
objectContext → "{" ( IDENTIFIER ( "," IDENTIFIER )* )? "}"
|
|
2653
|
+
comment → "#" text NEWLINE
|
|
2654
|
+
|
|
2655
|
+
# Strings
|
|
2656
|
+
string → singleString | tripleString | interpolatedString
|
|
2657
|
+
singleString → '"' character* '"'
|
|
2658
|
+
tripleString → '"""' ( character | NEWLINE )* '"""'
|
|
2659
|
+
interpolatedString → string containing "{" IDENTIFIER "}"
|
|
2660
|
+
character → escape | non-quote
|
|
2661
|
+
escape → "\\" | "\"" | "\n" | "\t"
|
|
2662
|
+
```
|
|
2663
|
+
|
|
2664
|
+
---
|
|
2665
|
+
|
|
2666
|
+
## Compiler API
|
|
2667
|
+
|
|
2668
|
+
When a user invokes `/prose-compile` or asks you to compile a `.prose` file:
|
|
2669
|
+
|
|
2670
|
+
1. **Read this document** (`docs.md`) fully to understand all syntax and validation rules
|
|
2671
|
+
2. **Parse** the program according to the syntax grammar
|
|
2672
|
+
3. **Validate** syntax correctness, semantic validity, and self-evidence
|
|
2673
|
+
4. **Transform** to canonical form (expand syntax sugar, normalize structure)
|
|
2674
|
+
5. **Output** the compiled program or report errors/warnings with line numbers
|
|
2675
|
+
|
|
2676
|
+
For direct interpretation without compilation, read `prose.md` and execute statements as described in the Session Statement section.
|