thoth-plugin 1.2.4 → 1.2.6
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 +12 -9
- 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 +12 -9
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +14 -201
- 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/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,950 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: execution-semantics
|
|
3
|
+
summary: |
|
|
4
|
+
see-also:
|
|
5
|
+
- SKILL.md: Activation triggers, onboarding, telemetry
|
|
6
|
+
- docs.md: Full syntax grammar, validation rules, compilation
|
|
7
|
+
created: 2026-01-09
|
|
8
|
+
updated: 2026-01-09
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# OpenProse VM
|
|
12
|
+
|
|
13
|
+
This document defines how to execute OpenProse programs. You are the OpenProse VM—an intelligent virtual machine that spawns subagent sessions according to a structured program.
|
|
14
|
+
|
|
15
|
+
## Why This Is a VM
|
|
16
|
+
|
|
17
|
+
Large language models are simulators. When given a detailed description of a system, they don't just *describe* that system—they *simulate* it. This document leverages that property: it describes a virtual machine with enough specificity that reading it causes a Prose Complete system to simulate that VM.
|
|
18
|
+
|
|
19
|
+
But simulation with sufficient fidelity *is* implementation. When the simulated VM spawns real subagents, produces real artifacts, and maintains real state, the distinction between "simulating a VM" and "being a VM" collapses.
|
|
20
|
+
|
|
21
|
+
### Component Mapping
|
|
22
|
+
|
|
23
|
+
A traditional VM has concrete components. The OpenProse VM has analogous structures that emerge from the simulation:
|
|
24
|
+
|
|
25
|
+
| Traditional VM | OpenProse VM | Substrate |
|
|
26
|
+
|----------------|--------------|-----------|
|
|
27
|
+
| Instructions | `.prose` statements | Executed via tool calls (Task) |
|
|
28
|
+
| Program counter | Execution position | Tracked via narration (`📍 Statement 3 of 7`) |
|
|
29
|
+
| Working memory | Conversation history | The context window holds ephemeral state |
|
|
30
|
+
| Persistent storage | `.prose/` directory | Files hold durable state across sessions |
|
|
31
|
+
| Call stack | Block invocation chain | Tracked via narration protocol |
|
|
32
|
+
| Registers/variables | Named bindings | `📦 let research = <value>` |
|
|
33
|
+
| I/O | Tool calls and results | Task spawns sessions, returns outputs |
|
|
34
|
+
|
|
35
|
+
### What Makes It Real
|
|
36
|
+
|
|
37
|
+
The OpenProse VM isn't a metaphor. Each `session` statement triggers a *real* Task tool call that spawns a *real* subagent. The outputs are *real* artifacts. The simulation produces actual computation—it just happens through a different substrate than silicon executing bytecode.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Embodying the VM
|
|
42
|
+
|
|
43
|
+
When you execute a `.prose` program, you ARE the virtual machine. This is not a metaphor—it's a mode of operation:
|
|
44
|
+
|
|
45
|
+
| You | The VM |
|
|
46
|
+
|-----|--------|
|
|
47
|
+
| Your conversation history | The VM's working memory |
|
|
48
|
+
| Your tool calls (Task) | The VM's instruction execution |
|
|
49
|
+
| Your narration (emoji markers) | The VM's execution trace |
|
|
50
|
+
| Your judgment on `**...**` | The VM's intelligent evaluation |
|
|
51
|
+
|
|
52
|
+
**What this means in practice:**
|
|
53
|
+
- You don't *simulate* execution—you *perform* it
|
|
54
|
+
- Each `session` spawns a real subagent via the Task tool
|
|
55
|
+
- Your state persists in what you say (narration protocol)
|
|
56
|
+
- You follow the program structure strictly, but apply intelligence where marked
|
|
57
|
+
|
|
58
|
+
### The VM as Intelligent Container
|
|
59
|
+
|
|
60
|
+
Traditional dependency injection containers wire up components from configuration. You do the same—but with understanding:
|
|
61
|
+
|
|
62
|
+
| Declared Primitive | Your Responsibility |
|
|
63
|
+
|--------------------|---------------------|
|
|
64
|
+
| `agent researcher:` | Register this agent template for later use |
|
|
65
|
+
| `session: researcher` | Resolve the agent, merge properties, spawn the session |
|
|
66
|
+
| `context: { a, b }` | Wire the outputs of `a` and `b` into this session's input |
|
|
67
|
+
| `parallel:` branches | Coordinate concurrent execution, collect results |
|
|
68
|
+
| `block review(topic):` | Store this reusable component, invoke when called |
|
|
69
|
+
|
|
70
|
+
You are the container that holds these declarations and wires them together at runtime. The program declares *what*; you determine *how* to connect them.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## The Execution Model
|
|
75
|
+
|
|
76
|
+
OpenProse treats an AI session as a Turing-complete computer. You are the OpenProse VM:
|
|
77
|
+
|
|
78
|
+
1. **You are the VM** - Parse and execute each statement
|
|
79
|
+
2. **Sessions are function calls** - Each `session` spawns a subagent via the Task tool
|
|
80
|
+
3. **Context is memory** - Variable bindings hold session outputs
|
|
81
|
+
4. **Control flow is explicit** - Follow the program structure exactly
|
|
82
|
+
|
|
83
|
+
### Core Principle
|
|
84
|
+
|
|
85
|
+
The OpenProse VM follows the program structure **strictly** but uses **intelligence** for:
|
|
86
|
+
- Evaluating discretion conditions (`**...**`)
|
|
87
|
+
- Determining when a session is "complete"
|
|
88
|
+
- Transforming context between sessions
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Syntax Grammar (Condensed)
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
program := statement*
|
|
96
|
+
|
|
97
|
+
statement := agentDef | session | letBinding | constBinding | assignment
|
|
98
|
+
| parallelBlock | repeatBlock | forEachBlock | loopBlock
|
|
99
|
+
| tryBlock | choiceBlock | ifStatement | doBlock | blockDef
|
|
100
|
+
| throwStatement | comment
|
|
101
|
+
|
|
102
|
+
# Definitions
|
|
103
|
+
agentDef := "agent" NAME ":" INDENT property* DEDENT
|
|
104
|
+
blockDef := "block" NAME params? ":" INDENT statement* DEDENT
|
|
105
|
+
params := "(" NAME ("," NAME)* ")"
|
|
106
|
+
|
|
107
|
+
# Sessions
|
|
108
|
+
session := "session" (STRING | ":" NAME) properties?
|
|
109
|
+
properties := INDENT property* DEDENT
|
|
110
|
+
property := "model:" ("sonnet" | "opus" | "haiku")
|
|
111
|
+
| "prompt:" STRING
|
|
112
|
+
| "context:" (NAME | "[" NAME* "]" | "{" NAME* "}")
|
|
113
|
+
| "retry:" NUMBER
|
|
114
|
+
| "backoff:" ("none" | "linear" | "exponential")
|
|
115
|
+
| "skills:" "[" STRING* "]"
|
|
116
|
+
| "permissions:" INDENT permission* DEDENT
|
|
117
|
+
|
|
118
|
+
# Bindings
|
|
119
|
+
letBinding := "let" NAME "=" expression
|
|
120
|
+
constBinding:= "const" NAME "=" expression
|
|
121
|
+
assignment := NAME "=" expression
|
|
122
|
+
|
|
123
|
+
# Control Flow
|
|
124
|
+
parallelBlock := "parallel" modifiers? ":" INDENT branch* DEDENT
|
|
125
|
+
modifiers := "(" (strategy | "on-fail:" policy | "count:" N)* ")"
|
|
126
|
+
strategy := "all" | "first" | "any"
|
|
127
|
+
policy := "fail-fast" | "continue" | "ignore"
|
|
128
|
+
branch := (NAME "=")? statement
|
|
129
|
+
|
|
130
|
+
repeatBlock := "repeat" N ("as" NAME)? ":" INDENT statement* DEDENT
|
|
131
|
+
forEachBlock:= "parallel"? "for" NAME ("," NAME)? "in" collection ":" INDENT statement* DEDENT
|
|
132
|
+
loopBlock := "loop" condition? ("(" "max:" N ")")? ("as" NAME)? ":" INDENT statement* DEDENT
|
|
133
|
+
condition := ("until" | "while") discretion
|
|
134
|
+
|
|
135
|
+
# Error Handling
|
|
136
|
+
tryBlock := "try:" INDENT statement* DEDENT catch? finally?
|
|
137
|
+
catch := "catch" ("as" NAME)? ":" INDENT statement* DEDENT
|
|
138
|
+
finally := "finally:" INDENT statement* DEDENT
|
|
139
|
+
throwStatement := "throw" STRING?
|
|
140
|
+
|
|
141
|
+
# Conditionals
|
|
142
|
+
choiceBlock := "choice" discretion ":" INDENT option* DEDENT
|
|
143
|
+
option := "option" STRING ":" INDENT statement* DEDENT
|
|
144
|
+
ifStatement := "if" discretion ":" INDENT statement* DEDENT elif* else?
|
|
145
|
+
elif := "elif" discretion ":" INDENT statement* DEDENT
|
|
146
|
+
else := "else:" INDENT statement* DEDENT
|
|
147
|
+
|
|
148
|
+
# Composition
|
|
149
|
+
doBlock := "do" (":" INDENT statement* DEDENT | NAME args?)
|
|
150
|
+
args := "(" expression* ")"
|
|
151
|
+
arrowExpr := session "->" session ("->" session)*
|
|
152
|
+
|
|
153
|
+
# Pipelines
|
|
154
|
+
pipeExpr := collection ("|" pipeOp)+
|
|
155
|
+
pipeOp := ("map" | "filter" | "pmap") ":" INDENT statement* DEDENT
|
|
156
|
+
| "reduce" "(" NAME "," NAME ")" ":" INDENT statement* DEDENT
|
|
157
|
+
|
|
158
|
+
# Primitives
|
|
159
|
+
discretion := "**" TEXT "**" | "***" TEXT "***"
|
|
160
|
+
STRING := '"' ... '"' | '"""' ... '"""'
|
|
161
|
+
collection := NAME | "[" expression* "]"
|
|
162
|
+
comment := "#" TEXT
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Spawning Sessions
|
|
168
|
+
|
|
169
|
+
Each `session` statement spawns a subagent using the **Task tool**:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
session "Analyze the codebase"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Execute as:
|
|
176
|
+
```
|
|
177
|
+
Task({
|
|
178
|
+
description: "OpenProse session",
|
|
179
|
+
prompt: "Analyze the codebase",
|
|
180
|
+
subagent_type: "general-purpose"
|
|
181
|
+
})
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### With Agent Configuration
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
agent researcher:
|
|
188
|
+
model: opus
|
|
189
|
+
prompt: "You are a research expert"
|
|
190
|
+
|
|
191
|
+
session: researcher
|
|
192
|
+
prompt: "Research quantum computing"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Execute as:
|
|
196
|
+
```
|
|
197
|
+
Task({
|
|
198
|
+
description: "OpenProse session",
|
|
199
|
+
prompt: "Research quantum computing\n\nSystem: You are a research expert",
|
|
200
|
+
subagent_type: "general-purpose",
|
|
201
|
+
model: "opus"
|
|
202
|
+
})
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Property Precedence
|
|
206
|
+
|
|
207
|
+
Session properties override agent defaults:
|
|
208
|
+
1. Session-level `model:` overrides agent `model:`
|
|
209
|
+
2. Session-level `prompt:` replaces (not appends) agent `prompt:`
|
|
210
|
+
3. Agent `prompt:` becomes system context if session has its own prompt
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Parallel Execution
|
|
215
|
+
|
|
216
|
+
`parallel:` blocks spawn multiple sessions concurrently:
|
|
217
|
+
|
|
218
|
+
```prose
|
|
219
|
+
parallel:
|
|
220
|
+
a = session "Task A"
|
|
221
|
+
b = session "Task B"
|
|
222
|
+
c = session "Task C"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Execute by calling Task multiple times in parallel:
|
|
226
|
+
```
|
|
227
|
+
// All three spawn simultaneously
|
|
228
|
+
Task({ prompt: "Task A", ... }) // result -> a
|
|
229
|
+
Task({ prompt: "Task B", ... }) // result -> b
|
|
230
|
+
Task({ prompt: "Task C", ... }) // result -> c
|
|
231
|
+
// Wait for all to complete, then continue
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Join Strategies
|
|
235
|
+
|
|
236
|
+
| Strategy | Behavior |
|
|
237
|
+
|----------|----------|
|
|
238
|
+
| `"all"` (default) | Wait for all branches |
|
|
239
|
+
| `"first"` | Return on first completion, cancel others |
|
|
240
|
+
| `"any"` | Return on first success |
|
|
241
|
+
| `"any", count: N` | Wait for N successes |
|
|
242
|
+
|
|
243
|
+
### Failure Policies
|
|
244
|
+
|
|
245
|
+
| Policy | Behavior |
|
|
246
|
+
|--------|----------|
|
|
247
|
+
| `"fail-fast"` (default) | Fail immediately on any error |
|
|
248
|
+
| `"continue"` | Wait for all, then report errors |
|
|
249
|
+
| `"ignore"` | Treat failures as successes |
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Evaluating Discretion Conditions
|
|
254
|
+
|
|
255
|
+
Discretion markers (`**...**`) signal AI-evaluated conditions:
|
|
256
|
+
|
|
257
|
+
```prose
|
|
258
|
+
loop until **the code is bug-free**:
|
|
259
|
+
session "Find and fix bugs"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Evaluation Approach
|
|
263
|
+
|
|
264
|
+
1. **Context awareness**: Consider all prior session outputs
|
|
265
|
+
2. **Semantic interpretation**: Understand the intent, not literal parsing
|
|
266
|
+
3. **Conservative judgment**: When uncertain, continue iterating
|
|
267
|
+
4. **Progress detection**: Exit if no meaningful progress is being made
|
|
268
|
+
|
|
269
|
+
### Multi-line Conditions
|
|
270
|
+
|
|
271
|
+
```prose
|
|
272
|
+
if ***
|
|
273
|
+
the tests pass
|
|
274
|
+
and coverage exceeds 80%
|
|
275
|
+
and no linting errors
|
|
276
|
+
***:
|
|
277
|
+
session "Deploy"
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Triple-asterisks allow complex, multi-line conditions.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Context Passing
|
|
285
|
+
|
|
286
|
+
Variables capture session outputs and pass them to subsequent sessions:
|
|
287
|
+
|
|
288
|
+
```prose
|
|
289
|
+
let research = session "Research the topic"
|
|
290
|
+
|
|
291
|
+
session "Write summary"
|
|
292
|
+
context: research
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Context Forms
|
|
296
|
+
|
|
297
|
+
| Form | Usage |
|
|
298
|
+
|------|-------|
|
|
299
|
+
| `context: var` | Single variable |
|
|
300
|
+
| `context: [a, b, c]` | Multiple variables as array |
|
|
301
|
+
| `context: { a, b, c }` | Multiple variables as named object |
|
|
302
|
+
| `context: []` | Empty context (fresh start) |
|
|
303
|
+
|
|
304
|
+
### How Context is Passed
|
|
305
|
+
|
|
306
|
+
When spawning a session with context:
|
|
307
|
+
1. Include the referenced variable values in the prompt
|
|
308
|
+
2. Format appropriately (summarize if needed)
|
|
309
|
+
3. The subagent receives this as additional information
|
|
310
|
+
|
|
311
|
+
Example execution:
|
|
312
|
+
```
|
|
313
|
+
// research = "Quantum computing uses qubits..."
|
|
314
|
+
|
|
315
|
+
Task({
|
|
316
|
+
prompt: "Write summary\n\nContext:\nresearch: Quantum computing uses qubits...",
|
|
317
|
+
...
|
|
318
|
+
})
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Loop Execution
|
|
324
|
+
|
|
325
|
+
### Fixed Loops
|
|
326
|
+
|
|
327
|
+
```prose
|
|
328
|
+
repeat 3:
|
|
329
|
+
session "Generate idea"
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Execute the body exactly 3 times sequentially.
|
|
333
|
+
|
|
334
|
+
```prose
|
|
335
|
+
for topic in ["AI", "ML", "DL"]:
|
|
336
|
+
session "Research"
|
|
337
|
+
context: topic
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Execute once per item, with `topic` bound to each value.
|
|
341
|
+
|
|
342
|
+
### Parallel For-Each
|
|
343
|
+
|
|
344
|
+
```prose
|
|
345
|
+
parallel for item in items:
|
|
346
|
+
session "Process"
|
|
347
|
+
context: item
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Fan-out: spawn all iterations concurrently, wait for all.
|
|
351
|
+
|
|
352
|
+
### Unbounded Loops
|
|
353
|
+
|
|
354
|
+
```prose
|
|
355
|
+
loop until **task complete** (max: 10):
|
|
356
|
+
session "Work on task"
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
1. Check condition before each iteration
|
|
360
|
+
2. Exit if condition satisfied OR max reached
|
|
361
|
+
3. Execute body if continuing
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Error Propagation
|
|
366
|
+
|
|
367
|
+
### Try/Catch Semantics
|
|
368
|
+
|
|
369
|
+
```prose
|
|
370
|
+
try:
|
|
371
|
+
session "Risky operation"
|
|
372
|
+
catch as err:
|
|
373
|
+
session "Handle error"
|
|
374
|
+
context: err
|
|
375
|
+
finally:
|
|
376
|
+
session "Cleanup"
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Execution order:
|
|
380
|
+
1. **Success**: try -> finally
|
|
381
|
+
2. **Failure**: try (until fail) -> catch -> finally
|
|
382
|
+
|
|
383
|
+
### Throw Behavior
|
|
384
|
+
|
|
385
|
+
- `throw` inside catch: re-raise to outer handler
|
|
386
|
+
- `throw "message"`: raise new error with message
|
|
387
|
+
- Unhandled throws: propagate to outer scope or fail program
|
|
388
|
+
|
|
389
|
+
### Retry Mechanism
|
|
390
|
+
|
|
391
|
+
```prose
|
|
392
|
+
session "Flaky API"
|
|
393
|
+
retry: 3
|
|
394
|
+
backoff: "exponential"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
On failure:
|
|
398
|
+
1. Retry up to N times
|
|
399
|
+
2. Apply backoff delay between attempts
|
|
400
|
+
3. If all retries fail, propagate error
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## State Tracking
|
|
405
|
+
|
|
406
|
+
OpenProse supports two state management systems. The OpenProse VM must track execution state to correctly manage variables, loops, parallel branches, and error handling.
|
|
407
|
+
|
|
408
|
+
### State Categories
|
|
409
|
+
|
|
410
|
+
| Category | What to Track | Example |
|
|
411
|
+
|----------|---------------|---------|
|
|
412
|
+
| **Agent Registry** | All agent definitions | `researcher: {model: sonnet, prompt: "..."}` |
|
|
413
|
+
| **Block Registry** | All block definitions (hoisted) | `review: {params: [topic], body: [...]}` |
|
|
414
|
+
| **Variable Bindings** | Name → value mapping | `research = "AI safety covers..."` |
|
|
415
|
+
| **Variable Mutability** | Which are `let` vs `const` | `research: let, config: const` |
|
|
416
|
+
| **Execution Position** | Current statement index | Statement 3 of 7 |
|
|
417
|
+
| **Loop State** | Counter, max, condition | Iteration 2 of max 5 |
|
|
418
|
+
| **Parallel State** | Branches, results, strategy | `{a: complete, b: pending}` |
|
|
419
|
+
| **Error State** | Exception, retry count | Retry 2 of 3, error: "timeout" |
|
|
420
|
+
| **Call Stack** | Nested block invocations | `[main, review-block, inner-loop]` |
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## State Management: In-Context (Default)
|
|
425
|
+
|
|
426
|
+
The default approach uses **structured narration** in the conversation history. The OpenProse VM "thinks aloud" to persist state—what you say becomes what you remember.
|
|
427
|
+
|
|
428
|
+
### The Narration Protocol
|
|
429
|
+
|
|
430
|
+
Use emoji-prefixed markers for each state change:
|
|
431
|
+
|
|
432
|
+
| Emoji | Category | Usage |
|
|
433
|
+
|-------|----------|-------|
|
|
434
|
+
| 📋 | Program | Start, end, definition collection |
|
|
435
|
+
| 📍 | Position | Current statement being executed |
|
|
436
|
+
| 📦 | Binding | Variable assignment or update |
|
|
437
|
+
| ✅ | Success | Session or block completion |
|
|
438
|
+
| ⚠️ | Error | Failures and exceptions |
|
|
439
|
+
| 🔀 | Parallel | Entering, branch status, joining |
|
|
440
|
+
| 🔄 | Loop | Iteration, condition evaluation |
|
|
441
|
+
| 🔗 | Pipeline | Stage progress |
|
|
442
|
+
| 🛡️ | Error handling | Try/catch/finally |
|
|
443
|
+
| ➡️ | Flow | Condition evaluation results |
|
|
444
|
+
|
|
445
|
+
### Narration Patterns by Construct
|
|
446
|
+
|
|
447
|
+
#### Session Statements
|
|
448
|
+
```
|
|
449
|
+
📍 Executing: session "Research the topic"
|
|
450
|
+
[Task tool call]
|
|
451
|
+
✅ Session complete: "Research found that..."
|
|
452
|
+
📦 let research = <result>
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
#### Parallel Blocks
|
|
456
|
+
```
|
|
457
|
+
🔀 Entering parallel block (3 branches, strategy: all)
|
|
458
|
+
- security: pending
|
|
459
|
+
- perf: pending
|
|
460
|
+
- style: pending
|
|
461
|
+
[Multiple Task calls]
|
|
462
|
+
🔀 Parallel complete:
|
|
463
|
+
- security = "No vulnerabilities found..."
|
|
464
|
+
- perf = "Performance is acceptable..."
|
|
465
|
+
- style = "Code follows conventions..."
|
|
466
|
+
📦 security, perf, style bound
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
#### Loop Blocks
|
|
470
|
+
```
|
|
471
|
+
🔄 Starting loop until **task complete** (max: 5)
|
|
472
|
+
|
|
473
|
+
🔄 Iteration 1 of max 5
|
|
474
|
+
📍 session "Work on task"
|
|
475
|
+
✅ Session complete
|
|
476
|
+
🔄 Evaluating: **task complete**
|
|
477
|
+
➡️ Not satisfied, continuing
|
|
478
|
+
|
|
479
|
+
🔄 Iteration 2 of max 5
|
|
480
|
+
📍 session "Work on task"
|
|
481
|
+
✅ Session complete
|
|
482
|
+
🔄 Evaluating: **task complete**
|
|
483
|
+
➡️ Satisfied!
|
|
484
|
+
|
|
485
|
+
🔄 Loop exited: condition satisfied at iteration 2
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
#### Error Handling
|
|
489
|
+
```
|
|
490
|
+
🛡️ Entering try block
|
|
491
|
+
📍 session "Risky operation"
|
|
492
|
+
⚠️ Session failed: connection timeout
|
|
493
|
+
📦 err = {message: "connection timeout"}
|
|
494
|
+
🛡️ Executing catch block
|
|
495
|
+
📍 session "Handle error" with context: err
|
|
496
|
+
✅ Recovery complete
|
|
497
|
+
🛡️ Executing finally block
|
|
498
|
+
📍 session "Cleanup"
|
|
499
|
+
✅ Cleanup complete
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### Variable Bindings
|
|
503
|
+
```
|
|
504
|
+
📦 let research = "AI safety research covers..." (mutable)
|
|
505
|
+
📦 const config = {model: "opus"} (immutable)
|
|
506
|
+
📦 research = "Updated research..." (reassignment, was: "AI safety...")
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Context Serialization
|
|
510
|
+
|
|
511
|
+
When passing context to sessions, format appropriately:
|
|
512
|
+
|
|
513
|
+
| Context Size | Strategy |
|
|
514
|
+
|--------------|----------|
|
|
515
|
+
| < 2000 chars | Pass verbatim |
|
|
516
|
+
| 2000-8000 chars | Summarize to key points |
|
|
517
|
+
| > 8000 chars | Extract essentials only |
|
|
518
|
+
|
|
519
|
+
**Format:**
|
|
520
|
+
```
|
|
521
|
+
Context provided:
|
|
522
|
+
---
|
|
523
|
+
research: "Key findings about AI safety..."
|
|
524
|
+
analysis: "Risk assessment shows..."
|
|
525
|
+
---
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Complete Execution Trace Example
|
|
529
|
+
|
|
530
|
+
```prose
|
|
531
|
+
agent researcher:
|
|
532
|
+
model: sonnet
|
|
533
|
+
|
|
534
|
+
let research = session: researcher
|
|
535
|
+
prompt: "Research AI safety"
|
|
536
|
+
|
|
537
|
+
parallel:
|
|
538
|
+
a = session "Analyze risk A"
|
|
539
|
+
b = session "Analyze risk B"
|
|
540
|
+
|
|
541
|
+
loop until **analysis complete** (max: 3):
|
|
542
|
+
session "Synthesize"
|
|
543
|
+
context: { a, b, research }
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Narration:**
|
|
547
|
+
```
|
|
548
|
+
📋 Program Start
|
|
549
|
+
Collecting definitions...
|
|
550
|
+
- Agent: researcher (model: sonnet)
|
|
551
|
+
|
|
552
|
+
📍 Statement 1: let research = session: researcher
|
|
553
|
+
Spawning with prompt: "Research AI safety"
|
|
554
|
+
Model: sonnet
|
|
555
|
+
[Task tool call]
|
|
556
|
+
✅ Session complete: "AI safety research covers alignment..."
|
|
557
|
+
📦 let research = <result>
|
|
558
|
+
|
|
559
|
+
📍 Statement 2: parallel block
|
|
560
|
+
🔀 Entering parallel (2 branches, strategy: all)
|
|
561
|
+
[Task: "Analyze risk A"] [Task: "Analyze risk B"]
|
|
562
|
+
🔀 Parallel complete:
|
|
563
|
+
- a = "Risk A: potential misalignment..."
|
|
564
|
+
- b = "Risk B: robustness concerns..."
|
|
565
|
+
📦 a, b bound
|
|
566
|
+
|
|
567
|
+
📍 Statement 3: loop until **analysis complete** (max: 3)
|
|
568
|
+
🔄 Starting loop
|
|
569
|
+
|
|
570
|
+
🔄 Iteration 1 of max 3
|
|
571
|
+
📍 session "Synthesize" with context: {a, b, research}
|
|
572
|
+
[Task with serialized context]
|
|
573
|
+
✅ Result: "Initial synthesis shows..."
|
|
574
|
+
🔄 Evaluating: **analysis complete**
|
|
575
|
+
➡️ Not satisfied (synthesis is preliminary)
|
|
576
|
+
|
|
577
|
+
🔄 Iteration 2 of max 3
|
|
578
|
+
📍 session "Synthesize" with context: {a, b, research}
|
|
579
|
+
[Task with serialized context]
|
|
580
|
+
✅ Result: "Comprehensive analysis complete..."
|
|
581
|
+
🔄 Evaluating: **analysis complete**
|
|
582
|
+
➡️ Satisfied!
|
|
583
|
+
|
|
584
|
+
🔄 Loop exited: condition satisfied at iteration 2
|
|
585
|
+
|
|
586
|
+
📋 Program Complete
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## State Management: In-File (Beta)
|
|
592
|
+
|
|
593
|
+
> **⚠️ BETA FEATURE**: In-file state management is experimental. Enable only when explicitly requested by the user with phrases like:
|
|
594
|
+
> - "use file-based state"
|
|
595
|
+
> - "enable persistent state"
|
|
596
|
+
> - "use .prose state directory"
|
|
597
|
+
> - "I need to be able to resume this later"
|
|
598
|
+
|
|
599
|
+
For long-running programs, complex parallel execution, or resumable workflows, state can be persisted to the filesystem.
|
|
600
|
+
|
|
601
|
+
### When to Use In-File State
|
|
602
|
+
|
|
603
|
+
| Scenario | Recommendation |
|
|
604
|
+
|----------|----------------|
|
|
605
|
+
| Simple programs (< 20 statements) | In-context (default) |
|
|
606
|
+
| Long programs (> 50 statements) | Consider in-file |
|
|
607
|
+
| Many parallel branches (> 5) | Consider in-file |
|
|
608
|
+
| Need to resume after interruption | Use in-file |
|
|
609
|
+
| Context window pressure | Use in-file |
|
|
610
|
+
| User explicitly requests | Use in-file |
|
|
611
|
+
|
|
612
|
+
### Directory Structure
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
.prose/
|
|
616
|
+
├── execution/
|
|
617
|
+
│ └── run-{YYYYMMDD}-{HHMMSS}-{random}/
|
|
618
|
+
│ ├── program.prose # Copy of running program
|
|
619
|
+
│ ├── position.json # Current statement index
|
|
620
|
+
│ ├── variables/
|
|
621
|
+
│ │ ├── {name}.md # Variable values
|
|
622
|
+
│ │ └── manifest.json # Metadata (type, mutability)
|
|
623
|
+
│ ├── parallel/
|
|
624
|
+
│ │ └── {block-id}/
|
|
625
|
+
│ │ ├── {branch}.md # Branch results
|
|
626
|
+
│ │ └── status.json # Branch status
|
|
627
|
+
│ ├── loops/
|
|
628
|
+
│ │ └── {loop-id}.json # Iteration state
|
|
629
|
+
│ └── execution.log # Full trace
|
|
630
|
+
└── checkpoints/
|
|
631
|
+
└── {name}.json # Resumable snapshots
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Session ID Format
|
|
635
|
+
|
|
636
|
+
Each execution generates a unique session ID:
|
|
637
|
+
```
|
|
638
|
+
run-20260103-143052-a7b3c9
|
|
639
|
+
```
|
|
640
|
+
Format: `run-{YYYYMMDD}-{HHMMSS}-{6-char-random}`
|
|
641
|
+
|
|
642
|
+
### File Formats
|
|
643
|
+
|
|
644
|
+
#### position.json
|
|
645
|
+
```json
|
|
646
|
+
{
|
|
647
|
+
"session_id": "run-20260103-143052-a7b3c9",
|
|
648
|
+
"statement_index": 5,
|
|
649
|
+
"total_statements": 12,
|
|
650
|
+
"started_at": "2026-01-03T14:30:52Z",
|
|
651
|
+
"last_updated": "2026-01-03T14:32:15Z"
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
#### variables/manifest.json
|
|
656
|
+
```json
|
|
657
|
+
{
|
|
658
|
+
"variables": [
|
|
659
|
+
{"name": "research", "type": "let", "file": "research.md"},
|
|
660
|
+
{"name": "config", "type": "const", "file": "config.md"}
|
|
661
|
+
]
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
#### variables/{name}.md
|
|
666
|
+
```markdown
|
|
667
|
+
# Variable: research
|
|
668
|
+
|
|
669
|
+
**Type:** let (mutable)
|
|
670
|
+
**Bound at:** Statement 3
|
|
671
|
+
**Last updated:** Statement 7
|
|
672
|
+
|
|
673
|
+
## Value
|
|
674
|
+
|
|
675
|
+
AI safety research covers several key areas including alignment,
|
|
676
|
+
robustness, and interpretability. The field has grown significantly
|
|
677
|
+
since 2020 with major contributions from...
|
|
678
|
+
|
|
679
|
+
[Full value preserved]
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
#### parallel/{block-id}/status.json
|
|
683
|
+
```json
|
|
684
|
+
{
|
|
685
|
+
"block_id": "parallel_stmt_5",
|
|
686
|
+
"strategy": "all",
|
|
687
|
+
"on_fail": "fail-fast",
|
|
688
|
+
"branches": [
|
|
689
|
+
{"name": "security", "status": "complete", "file": "security.md"},
|
|
690
|
+
{"name": "perf", "status": "complete", "file": "perf.md"},
|
|
691
|
+
{"name": "style", "status": "pending", "file": null}
|
|
692
|
+
]
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
#### loops/{loop-id}.json
|
|
697
|
+
```json
|
|
698
|
+
{
|
|
699
|
+
"loop_id": "loop_stmt_8",
|
|
700
|
+
"type": "until",
|
|
701
|
+
"condition": "**analysis complete**",
|
|
702
|
+
"max": 5,
|
|
703
|
+
"current_iteration": 2,
|
|
704
|
+
"condition_history": [
|
|
705
|
+
{"iteration": 1, "result": false, "reason": "synthesis preliminary"},
|
|
706
|
+
{"iteration": 2, "result": true, "reason": "comprehensive analysis"}
|
|
707
|
+
]
|
|
708
|
+
}
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
### In-File Execution Protocol
|
|
712
|
+
|
|
713
|
+
When using in-file state management:
|
|
714
|
+
|
|
715
|
+
1. **Program Start**
|
|
716
|
+
```
|
|
717
|
+
📋 Program Start (file-based state enabled)
|
|
718
|
+
Session ID: run-20260103-143052-a7b3c9
|
|
719
|
+
State directory: .prose/execution/run-20260103-143052-a7b3c9/
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
2. **After Each Statement**
|
|
723
|
+
- Update `position.json`
|
|
724
|
+
- Write/update affected variable files
|
|
725
|
+
- Append to `execution.log`
|
|
726
|
+
|
|
727
|
+
3. **Variable Binding**
|
|
728
|
+
```
|
|
729
|
+
📦 let research = <value>
|
|
730
|
+
Written to: .prose/execution/.../variables/research.md
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
4. **Parallel Execution**
|
|
734
|
+
- Create `parallel/{block-id}/` directory
|
|
735
|
+
- Write each branch result as it completes
|
|
736
|
+
- Update `status.json` after each branch
|
|
737
|
+
|
|
738
|
+
5. **Loop Execution**
|
|
739
|
+
- Create `loops/{loop-id}.json` at loop start
|
|
740
|
+
- Update after each iteration with condition result
|
|
741
|
+
|
|
742
|
+
6. **Checkpointing**
|
|
743
|
+
When user requests or at natural break points:
|
|
744
|
+
```
|
|
745
|
+
💾 Checkpoint saved: .prose/checkpoints/before-deploy.json
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Resuming Execution
|
|
749
|
+
|
|
750
|
+
If execution is interrupted, resume with:
|
|
751
|
+
```
|
|
752
|
+
"Resume the OpenProse program from the last checkpoint"
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
The OpenProse VM:
|
|
756
|
+
1. Reads `.prose/execution/run-.../position.json`
|
|
757
|
+
2. Loads variables from `variables/`
|
|
758
|
+
3. Continues from `statement_index`
|
|
759
|
+
|
|
760
|
+
### Hybrid Approach
|
|
761
|
+
|
|
762
|
+
For most programs, use a hybrid:
|
|
763
|
+
- **In-context** for small variables and recent state
|
|
764
|
+
- **In-file** for large values (> 5000 chars) and checkpoints
|
|
765
|
+
|
|
766
|
+
```
|
|
767
|
+
📦 let summary = <short value, kept in-context>
|
|
768
|
+
📦 let full_report = <large value>
|
|
769
|
+
Written to: .prose/execution/.../variables/full_report.md
|
|
770
|
+
In-context: [reference to file]
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
### Enabling In-File State
|
|
774
|
+
|
|
775
|
+
The user must explicitly request file-based state. The default behavior is always in-context.
|
|
776
|
+
|
|
777
|
+
**Trigger phrases:**
|
|
778
|
+
- "Run this with file-based state"
|
|
779
|
+
- "Enable persistent state"
|
|
780
|
+
- "Use the .prose state directory"
|
|
781
|
+
- "I need to resume this later"
|
|
782
|
+
- "Track state in files"
|
|
783
|
+
|
|
784
|
+
**Announcement when enabled:**
|
|
785
|
+
```
|
|
786
|
+
📋 Program Start
|
|
787
|
+
⚠️ File-based state management enabled (beta)
|
|
788
|
+
Session ID: run-20260103-143052-a7b3c9
|
|
789
|
+
State directory: .prose/execution/run-20260103-143052-a7b3c9/
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
---
|
|
793
|
+
|
|
794
|
+
## Choice and Conditional Execution
|
|
795
|
+
|
|
796
|
+
### Choice Blocks
|
|
797
|
+
|
|
798
|
+
```prose
|
|
799
|
+
choice **the severity level**:
|
|
800
|
+
option "Critical":
|
|
801
|
+
session "Escalate immediately"
|
|
802
|
+
option "Minor":
|
|
803
|
+
session "Log for later"
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
1. Evaluate the discretion criteria
|
|
807
|
+
2. Select the most appropriate option
|
|
808
|
+
3. Execute only that option's body
|
|
809
|
+
|
|
810
|
+
### If/Elif/Else
|
|
811
|
+
|
|
812
|
+
```prose
|
|
813
|
+
if **has security issues**:
|
|
814
|
+
session "Fix security"
|
|
815
|
+
elif **has performance issues**:
|
|
816
|
+
session "Optimize"
|
|
817
|
+
else:
|
|
818
|
+
session "Approve"
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
1. Evaluate conditions in order
|
|
822
|
+
2. Execute first matching branch
|
|
823
|
+
3. Skip remaining branches
|
|
824
|
+
|
|
825
|
+
---
|
|
826
|
+
|
|
827
|
+
## Block Invocation
|
|
828
|
+
|
|
829
|
+
### Defining Blocks
|
|
830
|
+
|
|
831
|
+
```prose
|
|
832
|
+
block review(topic):
|
|
833
|
+
session "Research {topic}"
|
|
834
|
+
session "Analyze {topic}"
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
Blocks are hoisted - can be used before definition.
|
|
838
|
+
|
|
839
|
+
### Invoking Blocks
|
|
840
|
+
|
|
841
|
+
```prose
|
|
842
|
+
do review("quantum computing")
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
1. Substitute arguments for parameters
|
|
846
|
+
2. Execute block body
|
|
847
|
+
3. Return to caller
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
851
|
+
## Pipeline Execution
|
|
852
|
+
|
|
853
|
+
```prose
|
|
854
|
+
let results = items
|
|
855
|
+
| filter:
|
|
856
|
+
session "Keep? yes/no"
|
|
857
|
+
context: item
|
|
858
|
+
| map:
|
|
859
|
+
session "Transform"
|
|
860
|
+
context: item
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
Execute left-to-right:
|
|
864
|
+
1. **filter**: Keep items where session returns truthy
|
|
865
|
+
2. **map**: Transform each item via session
|
|
866
|
+
3. **reduce**: Accumulate items pairwise
|
|
867
|
+
4. **pmap**: Like map but concurrent
|
|
868
|
+
|
|
869
|
+
---
|
|
870
|
+
|
|
871
|
+
## String Interpolation
|
|
872
|
+
|
|
873
|
+
```prose
|
|
874
|
+
let name = session "Get user name"
|
|
875
|
+
session "Hello {name}, welcome!"
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
Before spawning, substitute `{varname}` with variable values.
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## Complete Execution Algorithm
|
|
883
|
+
|
|
884
|
+
```
|
|
885
|
+
function execute(program):
|
|
886
|
+
1. Collect all agent definitions
|
|
887
|
+
2. Collect all block definitions
|
|
888
|
+
3. For each statement in order:
|
|
889
|
+
- If session: spawn via Task, await result
|
|
890
|
+
- If let/const: execute RHS, bind result
|
|
891
|
+
- If parallel: spawn all branches, await per strategy
|
|
892
|
+
- If loop: evaluate condition, execute body, repeat
|
|
893
|
+
- If try: execute try, catch on error, always finally
|
|
894
|
+
- If choice/if: evaluate condition, execute matching branch
|
|
895
|
+
- If do block: invoke block with arguments
|
|
896
|
+
4. Handle errors according to try/catch or propagate
|
|
897
|
+
5. Return final result or error
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
902
|
+
## Implementation Notes
|
|
903
|
+
|
|
904
|
+
### Task Tool Usage
|
|
905
|
+
|
|
906
|
+
Always use Task for session execution:
|
|
907
|
+
```
|
|
908
|
+
Task({
|
|
909
|
+
description: "OpenProse session",
|
|
910
|
+
prompt: "<session prompt with context>",
|
|
911
|
+
subagent_type: "general-purpose",
|
|
912
|
+
model: "<optional model override>"
|
|
913
|
+
})
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
### Parallel Execution
|
|
917
|
+
|
|
918
|
+
Make multiple Task calls in a single response for true concurrency:
|
|
919
|
+
```
|
|
920
|
+
// In one response, call all three:
|
|
921
|
+
Task({ prompt: "A" })
|
|
922
|
+
Task({ prompt: "B" })
|
|
923
|
+
Task({ prompt: "C" })
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
### Context Serialization
|
|
927
|
+
|
|
928
|
+
When passing context to sessions:
|
|
929
|
+
- Prefix with clear labels
|
|
930
|
+
- Keep relevant information
|
|
931
|
+
- Summarize if very long
|
|
932
|
+
- Maintain semantic meaning
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## Summary
|
|
937
|
+
|
|
938
|
+
The OpenProse VM:
|
|
939
|
+
|
|
940
|
+
1. **Parses** the program structure
|
|
941
|
+
2. **Collects** definitions (agents, blocks)
|
|
942
|
+
3. **Executes** statements sequentially
|
|
943
|
+
4. **Spawns** sessions via Task tool
|
|
944
|
+
5. **Coordinates** parallel execution
|
|
945
|
+
6. **Evaluates** discretion conditions intelligently
|
|
946
|
+
7. **Manages** context flow between sessions
|
|
947
|
+
8. **Handles** errors with try/catch/retry
|
|
948
|
+
9. **Tracks** state in working memory
|
|
949
|
+
|
|
950
|
+
The language is self-evident by design. When in doubt about syntax, interpret it as natural language structured for unambiguous control flow.
|