pi-harness-runtime 1.1.234 → 1.1.236
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/index.ts +64 -7
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/dist/continuation-controller.d.ts +6 -4
- package/packages/jev-judge/dist/continuation-controller.d.ts.map +1 -1
- package/packages/jev-judge/dist/continuation-controller.js +77 -88
- package/packages/jev-judge/dist/continuation-controller.js.map +1 -1
- package/packages/jev-judge/dist/typesafe-provider.js +2 -2
- package/packages/jev-judge/dist/typesafe-provider.js.map +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/jev-judge/src/continuation-controller.ts +87 -99
- package/packages/jev-judge/src/typesafe-provider.ts +2 -2
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -85,26 +85,31 @@ export class TodoContinuationController {
|
|
|
85
85
|
}
|
|
86
86
|
// 3. Get todo state (throws on branch read failure)
|
|
87
87
|
let inProgress;
|
|
88
|
-
let
|
|
88
|
+
let ready;
|
|
89
89
|
let blocked;
|
|
90
|
+
let allItems;
|
|
90
91
|
try {
|
|
91
92
|
inProgress = await this.todoProvider.getInProgress();
|
|
92
|
-
|
|
93
|
+
ready = await this.todoProvider.getReady();
|
|
93
94
|
blocked = await this.todoProvider.getBlocked();
|
|
95
|
+
const snapshot = await this.todoProvider.getSnapshot();
|
|
96
|
+
allItems = snapshot.items;
|
|
94
97
|
}
|
|
95
98
|
catch (err) {
|
|
96
99
|
const msg = err instanceof Error ? err.message : String(err);
|
|
97
100
|
debugLog("TodoContinuation", "Failed to read todos:", msg);
|
|
98
101
|
return { action: "stop", reason: `todo read failed: ${msg}` };
|
|
99
102
|
}
|
|
100
|
-
// 4.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
// 4. Filter in-progress for items without unfinished blockers
|
|
104
|
+
const unblockedInProgress = inProgress.filter((item) => {
|
|
105
|
+
if (!item.blockedBy?.length)
|
|
106
|
+
return true;
|
|
107
|
+
const blockerIds = new Set(item.blockedBy);
|
|
108
|
+
return !allItems.some((i) => blockerIds.has(i.id) && i.status !== "completed" && i.id !== item.id);
|
|
109
|
+
});
|
|
110
|
+
// 5. Continue unblocked in-progress work first
|
|
111
|
+
if (unblockedInProgress.length > 0) {
|
|
112
|
+
const item = unblockedInProgress[0];
|
|
108
113
|
// Reset counter if switching to a different task
|
|
109
114
|
if (this.state.lastItemContinued !== item.id) {
|
|
110
115
|
this.state.steerAttemptsForCurrentItem = 0;
|
|
@@ -116,9 +121,9 @@ export class TodoContinuationController {
|
|
|
116
121
|
}
|
|
117
122
|
return { action: "continue", nextItemId: item.id };
|
|
118
123
|
}
|
|
119
|
-
//
|
|
120
|
-
if (
|
|
121
|
-
const item =
|
|
124
|
+
// 5. Continue ready pending work (not blocked)
|
|
125
|
+
if (ready.length > 0) {
|
|
126
|
+
const item = ready[0];
|
|
122
127
|
// Reset counter if switching to a different task
|
|
123
128
|
if (this.state.lastItemContinued !== item.id) {
|
|
124
129
|
this.state.steerAttemptsForCurrentItem = 0;
|
|
@@ -130,66 +135,14 @@ export class TodoContinuationController {
|
|
|
130
135
|
}
|
|
131
136
|
return { action: "continue", nextItemId: item.id };
|
|
132
137
|
}
|
|
138
|
+
// 6. Only report blocked when nothing can proceed
|
|
139
|
+
if (blocked.length > 0) {
|
|
140
|
+
debugLog("TodoContinuation", "Tasks blocked:", blocked.length);
|
|
141
|
+
return { action: "blocked", question: `${blocked.length} task(s) blocked` };
|
|
142
|
+
}
|
|
133
143
|
// 7. No work remaining
|
|
134
144
|
return { action: "stop", reason: "No pending tasks" };
|
|
135
145
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Evaluate continuation decision and execute it
|
|
138
|
-
*/
|
|
139
|
-
async evaluateContinuation() {
|
|
140
|
-
// 1. Check user pause
|
|
141
|
-
if (this.state.userPaused) {
|
|
142
|
-
debugLog("TodoContinuation", "User paused, stopping");
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
// 2. Get current todo snapshot
|
|
146
|
-
const availability = await this.todoProvider.availability();
|
|
147
|
-
if (!availability.available) {
|
|
148
|
-
// No todo provider - don't auto-continue
|
|
149
|
-
debugLog("TodoContinuation", "Provider unavailable:", availability.error);
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
try {
|
|
153
|
-
// Get snapshot for state tracking
|
|
154
|
-
await this.todoProvider.getSnapshot();
|
|
155
|
-
// 3. Get in-progress and pending items
|
|
156
|
-
const inProgressItems = await this.todoProvider.getByStatus("in_progress");
|
|
157
|
-
const pendingItems = await this.todoProvider.getPending();
|
|
158
|
-
const completedItems = await this.todoProvider.getCompleted();
|
|
159
|
-
// 4. If there's work in progress, continue it
|
|
160
|
-
if (inProgressItems.length > 0) {
|
|
161
|
-
const item = inProgressItems[0];
|
|
162
|
-
debugLog("TodoContinuation", "In-progress item:", item.subject);
|
|
163
|
-
await this.continueItem(item);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
// 5. Determine action based on state
|
|
167
|
-
const totalItems = completedItems.length + pendingItems.length + inProgressItems.length;
|
|
168
|
-
const hasWork = pendingItems.length > 0 || inProgressItems.length > 0;
|
|
169
|
-
if (!hasWork && totalItems === 0) {
|
|
170
|
-
debugLog("TodoContinuation", "All items complete");
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (pendingItems.length > 0) {
|
|
174
|
-
// Check if items are blocked
|
|
175
|
-
const blockedItems = await this.todoProvider.getBlocked();
|
|
176
|
-
if (blockedItems.length === pendingItems.length) {
|
|
177
|
-
// All pending items are blocked - don't auto-continue
|
|
178
|
-
const blocker = blockedItems[0];
|
|
179
|
-
debugLog("TodoContinuation", "Items blocked:", blocker?.subject);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
// Continue the first non-blocked pending item
|
|
183
|
-
const readyItems = await this.todoProvider.getReady();
|
|
184
|
-
if (readyItems.length > 0) {
|
|
185
|
-
await this.continueItem(readyItems[0]);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
catch (err) {
|
|
190
|
-
debugLog("TodoContinuation", "Evaluation error:", err);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
146
|
/**
|
|
194
147
|
* Continue a specific todo item
|
|
195
148
|
*/
|
|
@@ -211,15 +164,61 @@ export class TodoContinuationController {
|
|
|
211
164
|
: `Continue task: ${item.subject}`;
|
|
212
165
|
this.state.lastSteerMessage = message;
|
|
213
166
|
debugLog("TodoContinuation", "Sending continuation:", item.subject);
|
|
214
|
-
// Send continuation message via
|
|
167
|
+
// Send continuation message via dispatch callback
|
|
215
168
|
try {
|
|
216
|
-
await this.
|
|
169
|
+
await this.config.dispatch(message);
|
|
217
170
|
}
|
|
218
171
|
catch (err) {
|
|
219
172
|
debugLog("TodoContinuation", "Failed to send continuation:", String(err));
|
|
220
173
|
this.state.continuationQueued = false;
|
|
221
174
|
}
|
|
222
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Guarded dispatch - checks all conditions before sending
|
|
178
|
+
*/
|
|
179
|
+
async guardedDispatch(itemId, message) {
|
|
180
|
+
// 1. Check if paused by user
|
|
181
|
+
if (this.state.userPaused) {
|
|
182
|
+
debugLog("TodoContinuation", "Guarded dispatch: user paused, skipping");
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
// 2. Check if session is still idle
|
|
186
|
+
if (this.ctx.isIdle?.() === false) {
|
|
187
|
+
debugLog("TodoContinuation", "Guarded dispatch: session not idle, skipping");
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
// 3. Check if continuation already queued (prevent duplicates)
|
|
191
|
+
if (this.state.continuationQueued) {
|
|
192
|
+
debugLog("TodoContinuation", "Guarded dispatch: already queued, skipping");
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
// 4. Verify item still needs work (not completed)
|
|
196
|
+
try {
|
|
197
|
+
const snapshot = await this.todoProvider.getSnapshot();
|
|
198
|
+
const item = snapshot.items.find((i) => i.id === itemId);
|
|
199
|
+
if (item?.status === "completed") {
|
|
200
|
+
debugLog("TodoContinuation", "Guarded dispatch: item completed, skipping");
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// If we can't read todos, skip dispatch
|
|
206
|
+
debugLog("TodoContinuation", "Guarded dispatch: failed to read todos, skipping");
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
// All checks passed - dispatch
|
|
210
|
+
this.state.continuationQueued = true;
|
|
211
|
+
this.state.lastSteerMessage = message;
|
|
212
|
+
try {
|
|
213
|
+
await this.config.dispatch(message);
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
debugLog("TodoContinuation", "Guarded dispatch failed:", String(err));
|
|
218
|
+
this.state.continuationQueued = false;
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
223
222
|
/**
|
|
224
223
|
* Steer to continue a todo item
|
|
225
224
|
*/
|
|
@@ -234,22 +233,12 @@ export class TodoContinuationController {
|
|
|
234
233
|
return;
|
|
235
234
|
}
|
|
236
235
|
this.state.steerAttemptsForCurrentItem++;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.state.lastSteerMessage = message;
|
|
244
|
-
this.state.todoRevision = snapshot.revision;
|
|
245
|
-
debugLog("TodoContinuation", "Steering to continue item", itemId);
|
|
246
|
-
// Send continuation message via Pi API
|
|
247
|
-
try {
|
|
248
|
-
await this.ctx.sendUserMessage?.(message, { deliverAs: "steer" });
|
|
249
|
-
}
|
|
250
|
-
catch (err) {
|
|
251
|
-
debugLog("TodoContinuation", "Failed to send steer:", String(err));
|
|
252
|
-
this.state.continuationQueued = false;
|
|
236
|
+
const message = `Continue todo item ID ${itemId}.`;
|
|
237
|
+
debugLog("TodoContinuation", "Attempting steer to continue item", itemId);
|
|
238
|
+
// Use guarded dispatch to verify all conditions
|
|
239
|
+
const sent = await this.guardedDispatch(itemId, message);
|
|
240
|
+
if (!sent) {
|
|
241
|
+
debugLog("TodoContinuation", "Steer blocked by guard conditions");
|
|
253
242
|
}
|
|
254
243
|
}
|
|
255
244
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuation-controller.js","sourceRoot":"","sources":["../src/continuation-controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,MAAM,cAAc,GAAG,2BAA2B,CAAC;AACnD,SAAS,QAAQ,CAAC,SAAiB,EAAE,GAAG,IAAe;IACtD,IAAI,CAAC;QACJ,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,SAAS,MAAM,SAAS,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QACpF,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE;YAC7C,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACR,gBAAgB;IACjB,CAAC;AACF,CAAC;
|
|
1
|
+
{"version":3,"file":"continuation-controller.js","sourceRoot":"","sources":["../src/continuation-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -79,9 +79,9 @@ export class TypeSafeJudge {
|
|
|
79
79
|
for (const [questionId, question] of Object.entries(questions)) {
|
|
80
80
|
const questionData = question;
|
|
81
81
|
const answer = data.answers?.[questionId];
|
|
82
|
+
// Reject missing required answers
|
|
82
83
|
if (!answer) {
|
|
83
|
-
|
|
84
|
-
continue;
|
|
84
|
+
throw new Error(`TypeSafe API: missing answer for required question "${questionId}"`);
|
|
85
85
|
}
|
|
86
86
|
const decision = this.buildDecision(questionId, questionData, answer);
|
|
87
87
|
decisions[questionId] = decision;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typesafe-provider.js","sourceRoot":"","sources":["../src/typesafe-provider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"typesafe-provider.js","sourceRoot":"","sources":["../src/typesafe-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,8 @@ function debugLog(component: string, ...args: unknown[]): void {
|
|
|
21
21
|
* Continuation configuration
|
|
22
22
|
*/
|
|
23
23
|
export interface ContinuationConfig {
|
|
24
|
+
/** Dispatch function to send messages to the agent (required) */
|
|
25
|
+
dispatch: (content: string) => Promise<void>;
|
|
24
26
|
/** Minimum wait before Jev fallback (ms) */
|
|
25
27
|
jevFallbackMinWaitMs?: number;
|
|
26
28
|
/** Threshold for routine continuation */
|
|
@@ -135,34 +137,40 @@ export class TodoContinuationController {
|
|
|
135
137
|
|
|
136
138
|
// 3. Get todo state (throws on branch read failure)
|
|
137
139
|
let inProgress: TodoItem[];
|
|
138
|
-
let
|
|
140
|
+
let ready: TodoItem[];
|
|
139
141
|
let blocked: TodoItem[];
|
|
142
|
+
let allItems: TodoItem[];
|
|
140
143
|
try {
|
|
141
144
|
inProgress = await this.todoProvider.getInProgress();
|
|
142
|
-
|
|
145
|
+
ready = await this.todoProvider.getReady();
|
|
143
146
|
blocked = await this.todoProvider.getBlocked();
|
|
147
|
+
const snapshot = await this.todoProvider.getSnapshot();
|
|
148
|
+
allItems = snapshot.items;
|
|
144
149
|
} catch (err) {
|
|
145
150
|
const msg = err instanceof Error ? err.message : String(err);
|
|
146
151
|
debugLog("TodoContinuation", "Failed to read todos:", msg);
|
|
147
152
|
return { action: "stop", reason: `todo read failed: ${msg}` };
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
// 4.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
// 4. Filter in-progress for items without unfinished blockers
|
|
156
|
+
const unblockedInProgress = inProgress.filter((item) => {
|
|
157
|
+
if (!item.blockedBy?.length) return true;
|
|
158
|
+
const blockerIds = new Set(item.blockedBy);
|
|
159
|
+
return !allItems.some(
|
|
160
|
+
(i) => blockerIds.has(i.id) && i.status !== "completed" && i.id !== item.id
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// 5. Continue unblocked in-progress work first
|
|
165
|
+
if (unblockedInProgress.length > 0) {
|
|
166
|
+
const item = unblockedInProgress[0];
|
|
155
167
|
|
|
156
|
-
// 5. Continue in-progress work if any
|
|
157
|
-
if (inProgress.length > 0) {
|
|
158
|
-
const item = inProgress[0];
|
|
159
|
-
|
|
160
168
|
// Reset counter if switching to a different task
|
|
161
169
|
if (this.state.lastItemContinued !== item.id) {
|
|
162
170
|
this.state.steerAttemptsForCurrentItem = 0;
|
|
163
171
|
this.state.lastItemContinued = item.id;
|
|
164
172
|
}
|
|
165
|
-
|
|
173
|
+
|
|
166
174
|
// Check per-task attempt limit
|
|
167
175
|
if (this.state.steerAttemptsForCurrentItem >= this.config.maxSteerAttempts) {
|
|
168
176
|
return { action: "stop", reason: `max attempts (${this.config.maxSteerAttempts}) reached for task ${item.id}` };
|
|
@@ -171,9 +179,9 @@ export class TodoContinuationController {
|
|
|
171
179
|
return { action: "continue", nextItemId: item.id };
|
|
172
180
|
}
|
|
173
181
|
|
|
174
|
-
//
|
|
175
|
-
if (
|
|
176
|
-
const item =
|
|
182
|
+
// 5. Continue ready pending work (not blocked)
|
|
183
|
+
if (ready.length > 0) {
|
|
184
|
+
const item = ready[0];
|
|
177
185
|
|
|
178
186
|
// Reset counter if switching to a different task
|
|
179
187
|
if (this.state.lastItemContinued !== item.id) {
|
|
@@ -189,73 +197,14 @@ export class TodoContinuationController {
|
|
|
189
197
|
return { action: "continue", nextItemId: item.id };
|
|
190
198
|
}
|
|
191
199
|
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Evaluate continuation decision and execute it
|
|
198
|
-
*/
|
|
199
|
-
private async evaluateContinuation(): Promise<void> {
|
|
200
|
-
// 1. Check user pause
|
|
201
|
-
if (this.state.userPaused) {
|
|
202
|
-
debugLog("TodoContinuation", "User paused, stopping");
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// 2. Get current todo snapshot
|
|
207
|
-
const availability = await this.todoProvider.availability();
|
|
208
|
-
if (!availability.available) {
|
|
209
|
-
// No todo provider - don't auto-continue
|
|
210
|
-
debugLog("TodoContinuation", "Provider unavailable:", availability.error);
|
|
211
|
-
return;
|
|
200
|
+
// 6. Only report blocked when nothing can proceed
|
|
201
|
+
if (blocked.length > 0) {
|
|
202
|
+
debugLog("TodoContinuation", "Tasks blocked:", blocked.length);
|
|
203
|
+
return { action: "blocked", question: `${blocked.length} task(s) blocked` };
|
|
212
204
|
}
|
|
213
205
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
await this.todoProvider.getSnapshot();
|
|
217
|
-
|
|
218
|
-
// 3. Get in-progress and pending items
|
|
219
|
-
const inProgressItems = await this.todoProvider.getByStatus("in_progress");
|
|
220
|
-
const pendingItems = await this.todoProvider.getPending();
|
|
221
|
-
const completedItems = await this.todoProvider.getCompleted();
|
|
222
|
-
|
|
223
|
-
// 4. If there's work in progress, continue it
|
|
224
|
-
if (inProgressItems.length > 0) {
|
|
225
|
-
const item = inProgressItems[0];
|
|
226
|
-
debugLog("TodoContinuation", "In-progress item:", item.subject);
|
|
227
|
-
await this.continueItem(item);
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// 5. Determine action based on state
|
|
232
|
-
const totalItems = completedItems.length + pendingItems.length + inProgressItems.length;
|
|
233
|
-
const hasWork = pendingItems.length > 0 || inProgressItems.length > 0;
|
|
234
|
-
|
|
235
|
-
if (!hasWork && totalItems === 0) {
|
|
236
|
-
debugLog("TodoContinuation", "All items complete");
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (pendingItems.length > 0) {
|
|
241
|
-
// Check if items are blocked
|
|
242
|
-
const blockedItems = await this.todoProvider.getBlocked();
|
|
243
|
-
if (blockedItems.length === pendingItems.length) {
|
|
244
|
-
// All pending items are blocked - don't auto-continue
|
|
245
|
-
const blocker = blockedItems[0];
|
|
246
|
-
debugLog("TodoContinuation", "Items blocked:", blocker?.subject);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Continue the first non-blocked pending item
|
|
251
|
-
const readyItems = await this.todoProvider.getReady();
|
|
252
|
-
if (readyItems.length > 0) {
|
|
253
|
-
await this.continueItem(readyItems[0]);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
} catch (err) {
|
|
257
|
-
debugLog("TodoContinuation", "Evaluation error:", err);
|
|
258
|
-
}
|
|
206
|
+
// 7. No work remaining
|
|
207
|
+
return { action: "stop", reason: "No pending tasks" };
|
|
259
208
|
}
|
|
260
209
|
|
|
261
210
|
/**
|
|
@@ -284,15 +233,65 @@ export class TodoContinuationController {
|
|
|
284
233
|
this.state.lastSteerMessage = message;
|
|
285
234
|
debugLog("TodoContinuation", "Sending continuation:", item.subject);
|
|
286
235
|
|
|
287
|
-
// Send continuation message via
|
|
236
|
+
// Send continuation message via dispatch callback
|
|
288
237
|
try {
|
|
289
|
-
await this.
|
|
238
|
+
await this.config.dispatch(message);
|
|
290
239
|
} catch (err) {
|
|
291
240
|
debugLog("TodoContinuation", "Failed to send continuation:", String(err));
|
|
292
241
|
this.state.continuationQueued = false;
|
|
293
242
|
}
|
|
294
243
|
}
|
|
295
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Guarded dispatch - checks all conditions before sending
|
|
247
|
+
*/
|
|
248
|
+
private async guardedDispatch(itemId: number, message: string): Promise<boolean> {
|
|
249
|
+
// 1. Check if paused by user
|
|
250
|
+
if (this.state.userPaused) {
|
|
251
|
+
debugLog("TodoContinuation", "Guarded dispatch: user paused, skipping");
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// 2. Check if session is still idle
|
|
256
|
+
if (this.ctx.isIdle?.() === false) {
|
|
257
|
+
debugLog("TodoContinuation", "Guarded dispatch: session not idle, skipping");
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// 3. Check if continuation already queued (prevent duplicates)
|
|
262
|
+
if (this.state.continuationQueued) {
|
|
263
|
+
debugLog("TodoContinuation", "Guarded dispatch: already queued, skipping");
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// 4. Verify item still needs work (not completed)
|
|
268
|
+
try {
|
|
269
|
+
const snapshot = await this.todoProvider.getSnapshot();
|
|
270
|
+
const item = snapshot.items.find((i) => i.id === itemId);
|
|
271
|
+
if (item?.status === "completed") {
|
|
272
|
+
debugLog("TodoContinuation", "Guarded dispatch: item completed, skipping");
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
} catch {
|
|
276
|
+
// If we can't read todos, skip dispatch
|
|
277
|
+
debugLog("TodoContinuation", "Guarded dispatch: failed to read todos, skipping");
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// All checks passed - dispatch
|
|
282
|
+
this.state.continuationQueued = true;
|
|
283
|
+
this.state.lastSteerMessage = message;
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
await this.config.dispatch(message);
|
|
287
|
+
return true;
|
|
288
|
+
} catch (err) {
|
|
289
|
+
debugLog("TodoContinuation", "Guarded dispatch failed:", String(err));
|
|
290
|
+
this.state.continuationQueued = false;
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
296
295
|
/**
|
|
297
296
|
* Steer to continue a todo item
|
|
298
297
|
*/
|
|
@@ -309,25 +308,14 @@ export class TodoContinuationController {
|
|
|
309
308
|
}
|
|
310
309
|
|
|
311
310
|
this.state.steerAttemptsForCurrentItem++;
|
|
312
|
-
this.state.continuationQueued = true;
|
|
313
|
-
|
|
314
|
-
const snapshot = await this.todoProvider.getSnapshot();
|
|
315
|
-
const item = snapshot.items.find((i) => i.id === itemId);
|
|
316
|
-
|
|
317
|
-
const message = item
|
|
318
|
-
? `Continue todo item: "${item.subject}". ${item.description ?? ""}`
|
|
319
|
-
: `Continue work on the next ready task.`;
|
|
320
311
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
debugLog("TodoContinuation", "Steering to continue item", itemId);
|
|
312
|
+
const message = `Continue todo item ID ${itemId}.`;
|
|
313
|
+
debugLog("TodoContinuation", "Attempting steer to continue item", itemId);
|
|
324
314
|
|
|
325
|
-
//
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
debugLog("TodoContinuation", "Failed to send steer:", String(err));
|
|
330
|
-
this.state.continuationQueued = false;
|
|
315
|
+
// Use guarded dispatch to verify all conditions
|
|
316
|
+
const sent = await this.guardedDispatch(itemId, message);
|
|
317
|
+
if (!sent) {
|
|
318
|
+
debugLog("TodoContinuation", "Steer blocked by guard conditions");
|
|
331
319
|
}
|
|
332
320
|
}
|
|
333
321
|
|
|
@@ -164,9 +164,9 @@ export class TypeSafeJudge {
|
|
|
164
164
|
const questionData = question as JevQuestion;
|
|
165
165
|
const answer = data.answers?.[questionId] as TypeSafeAnswer | undefined;
|
|
166
166
|
|
|
167
|
+
// Reject missing required answers
|
|
167
168
|
if (!answer) {
|
|
168
|
-
|
|
169
|
-
continue;
|
|
169
|
+
throw new Error(`TypeSafe API: missing answer for required question "${questionId}"`);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
const decision = this.buildDecision(
|