summaryrefslogtreecommitdiff
path: root/pi/agent/extensions/loop-scheduler/README.md
blob: 3e7ef37c5d03fadb811439f3bfc863db42761ecd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# Loop Scheduler

Session-scoped recurring and reactive prompts for Pi.

This extension adds two commands for interactive Pi sessions:

- `/loop` re-sends a prompt on an interval while the current Pi process stays open.
  The first run fires right after you create the loop; later runs use the interval.
- `/watch` posts a predefined prompt when the agent becomes idle or when an assistant response contains a substring.

## Commands

### `/loop`

- `/loop 10m <prompt>`
  Run a prompt every 10 minutes.
- `/loop <prompt>`
  Run a prompt every 10 minutes using the default interval.
- `/loop <prompt> every 2h`
  Alternative trailing interval form.
- `/loop list`
  Show the active loop jobs.
- `/loop cancel <id>`
  Cancel one loop job.
- `/loop cancel all`
  Cancel all loop jobs.

### `/watch`

- `/watch <prompt>`
  Run a prompt whenever the agent becomes idle.
- `/watch idle => <prompt>`
  Explicit idle watch form.
- `/watch contains <needle> => <prompt>`
  Post the prompt when an assistant response includes `<needle>`.
- `/watch list`
  Show the active watch jobs.
- `/watch cancel <id>`
  Cancel one watch job.
- `/watch cancel all`
  Cancel all watch jobs.

Supported units:

- `s`
- `m`
- `h`
- `d`

Examples:

- `5s`
- `10m`
- `2h`
- `1d`
- `every 2 hours`
- `hourly`
- `daily`

## Usage Flows

### Flow 1: Poll something on an interval

Start Pi in the repo, then run:

```text
/loop 10m check whether the deployment finished and summarize what changed
```

The first run happens almost immediately (then every 10 minutes) while the
session stays open.

### Flow 2: Loop another command

The scheduled prompt can itself be a slash command or workflow:

```text
/loop 20m /work-on-tasks highest-impact 1
```

or:

```text
/loop 30m /subagent Review the current working tree for concrete regressions only
```

### Flow 3: Check what is scheduled

```text
/loop list
```

This prints the current loop IDs, cadence, next due time, and prompt preview.

### Flow 4: Cancel a loop

Cancel one loop:

```text
/loop cancel ab12cd34
```

Cancel everything:

```text
/loop cancel all
```

### Flow 5: Trigger a prompt when the agent goes idle

```text
/watch idle => summarize what you just finished and suggest the next step
```

This prompt fires whenever the agent transitions from busy to idle.

### Flow 6: Trigger a prompt when a response contains text

```text
/watch contains error => inspect the error and report the concrete failure
```

The substring match is case-sensitive and is checked against assistant responses.

### Flow 7: Work from watch presets

Watch presets live in:

```text
~/.pi/agent/extensions/loop-scheduler/watch-presets.md
```

Preset lines use:

```text
* name: idle => prompt text
* name: contains needle => prompt text
```

## Busy-Agent Behavior

Loop jobs do not spam turns while Pi is busy.

- for **Gemma 4** models, loop/watch prompts use `deliverAs: "followUp"` so Pi queues them if the runtime is still finishing a turn (avoids “Agent is already processing” after long streams)
- if a job becomes due while the agent is running, it is marked pending
- when the current work finishes, the next pending loop fires once
- missed intervals do not stack into a catch-up storm

Watch jobs behave similarly:

- idle watches queue when the agent becomes idle
- substring watches queue when an assistant response matches the needle
- only one queued prompt is sent at a time, so watches do not overlap

## Session Model

This extension is session-scoped, not durable scheduling.

- loop jobs live only in the current Pi process
- watch jobs live only in the current Pi process
- closing Pi ends all loop jobs
- `/reload` or a restart drops the active schedules
- this is for active coding sessions, not unattended automation

## Good Uses

- poll build or deployment status
- re-run a review command every N minutes
- check Taskwarrior progress during a work session
- periodically ask for a summary while you are coding

## Bad Uses

- long-term unattended automation
- guaranteed exact-time scheduling
- anything that must survive terminal exit or Pi restart

## Notes

- `/loop` is intended for interactive or RPC sessions that remain open.
- It is not useful in one-shot `pi -p` mode because the process exits before
  later runs can fire.