@turns/dev 0.0.18 → 0.0.19
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/dist/agent-anchor.js +44 -5
- package/package.json +1 -1
package/dist/agent-anchor.js
CHANGED
|
@@ -198,11 +198,21 @@ class LineTransport {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* How long a background notification's `result` is held before it is taken as
|
|
203
|
+
* the end of the prompt's turn. Claude answers a task notification with a turn
|
|
204
|
+
* of its own, stamped `origin.kind: "task-notification"`; when a prompt is
|
|
205
|
+
* waiting behind it, that turn's `result` arrives first and the prompt's turn
|
|
206
|
+
* starts right after it. If Claude instead folded the prompt into the
|
|
207
|
+
* notification's turn, nothing follows, and the held result is the prompt's.
|
|
208
|
+
*/
|
|
209
|
+
const CLAUDE_NOTIFICATION_RESULT_GRACE_MS = 2_000;
|
|
201
210
|
class ClaudeTransport extends LineTransport {
|
|
202
211
|
sessionId;
|
|
203
212
|
permissionMode;
|
|
204
213
|
turnWaiter;
|
|
205
214
|
control;
|
|
215
|
+
heldResult = null;
|
|
206
216
|
constructor(anchor, createSession) {
|
|
207
217
|
const profile = { command: 'claude' };
|
|
208
218
|
const nativePermissionMode = anchor.permissionMode === 'default' ? 'manual' : anchor.permissionMode;
|
|
@@ -238,6 +248,13 @@ class ClaudeTransport extends LineTransport {
|
|
|
238
248
|
onFrame(frame) {
|
|
239
249
|
if (!frame || typeof frame !== 'object')
|
|
240
250
|
return;
|
|
251
|
+
// Another turn starting means a held notification result was not the
|
|
252
|
+
// prompt's: keep waiting for the result of the turn now running.
|
|
253
|
+
if (this.heldResult &&
|
|
254
|
+
((frame.type === 'system' && frame.subtype === 'init') || frame.type === 'stream_event' || frame.type === 'assistant')) {
|
|
255
|
+
clearTimeout(this.heldResult.timer);
|
|
256
|
+
this.heldResult = null;
|
|
257
|
+
}
|
|
241
258
|
if (frame.type === 'system' && frame.subtype === 'init' && frame.session_id) {
|
|
242
259
|
this.sessionId = String(frame.session_id);
|
|
243
260
|
if (this.sessionId !== this.anchor.agentSessionId)
|
|
@@ -245,11 +262,20 @@ class ClaudeTransport extends LineTransport {
|
|
|
245
262
|
return;
|
|
246
263
|
}
|
|
247
264
|
if (frame.type === 'result' && this.turnWaiter) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
265
|
+
if (frame.origin?.kind === 'task-notification') {
|
|
266
|
+
if (this.heldResult)
|
|
267
|
+
clearTimeout(this.heldResult.timer);
|
|
268
|
+
const timer = setTimeout(() => {
|
|
269
|
+
if (this.heldResult?.frame !== frame)
|
|
270
|
+
return;
|
|
271
|
+
this.heldResult = null;
|
|
272
|
+
this.settleTurn(frame);
|
|
273
|
+
}, CLAUDE_NOTIFICATION_RESULT_GRACE_MS);
|
|
274
|
+
timer.unref?.();
|
|
275
|
+
this.heldResult = { frame, timer };
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
this.settleTurn(frame);
|
|
253
279
|
return;
|
|
254
280
|
}
|
|
255
281
|
if (frame.type === 'control_response') {
|
|
@@ -266,7 +292,20 @@ class ClaudeTransport extends LineTransport {
|
|
|
266
292
|
if (frame.type === 'control_request')
|
|
267
293
|
void this.answerReverse(frame);
|
|
268
294
|
}
|
|
295
|
+
settleTurn(frame) {
|
|
296
|
+
const waiter = this.turnWaiter;
|
|
297
|
+
if (!waiter)
|
|
298
|
+
return;
|
|
299
|
+
this.turnWaiter = null;
|
|
300
|
+
frame.is_error
|
|
301
|
+
? waiter.reject(new Error(frame.result || frame.subtype || 'Claude turn failed.'))
|
|
302
|
+
: waiter.resolve(frame);
|
|
303
|
+
}
|
|
269
304
|
onClose(error) {
|
|
305
|
+
if (this.heldResult) {
|
|
306
|
+
clearTimeout(this.heldResult.timer);
|
|
307
|
+
this.heldResult = null;
|
|
308
|
+
}
|
|
270
309
|
if (this.turnWaiter) {
|
|
271
310
|
this.turnWaiter.reject(error);
|
|
272
311
|
this.turnWaiter = null;
|