mandala-computer-mcp 0.1.1 → 0.3.0
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 +127 -16
- package/dist/api.d.ts +19 -6
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +261 -57
- package/dist/api.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +113 -8
- package/dist/cli.js.map +1 -1
- package/dist/errors.d.ts +74 -9
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +115 -25
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +36 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +223 -33
- package/dist/events.js.map +1 -1
- package/dist/format.d.ts +48 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +31 -1
- package/dist/format.js.map +1 -1
- package/dist/http-body.d.ts +17 -0
- package/dist/http-body.d.ts.map +1 -0
- package/dist/http-body.js +48 -0
- package/dist/http-body.js.map +1 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +177 -51
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/paths.d.ts +28 -18
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +85 -22
- package/dist/paths.js.map +1 -1
- package/dist/poll.d.ts +103 -0
- package/dist/poll.d.ts.map +1 -0
- package/dist/poll.js +129 -0
- package/dist/poll.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +14 -2
- package/dist/tools/agent.js.map +1 -1
- package/dist/tools/computers.d.ts.map +1 -1
- package/dist/tools/computers.js +346 -62
- package/dist/tools/computers.js.map +1 -1
- package/dist/tools/events.d.ts.map +1 -1
- package/dist/tools/events.js +295 -49
- package/dist/tools/events.js.map +1 -1
- package/dist/tools/guest.d.ts.map +1 -1
- package/dist/tools/guest.js +228 -32
- package/dist/tools/guest.js.map +1 -1
- package/dist/tools/input.d.ts.map +1 -1
- package/dist/tools/input.js +29 -3
- package/dist/tools/input.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +478 -20
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/templates.d.ts.map +1 -1
- package/dist/tools/templates.js +52 -13
- package/dist/tools/templates.js.map +1 -1
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +116 -17
- package/dist/tools/webhooks.js.map +1 -1
- package/package.json +3 -2
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,GAAG,cAAc,CAAC;CAChC;AAED,MAAM,OAAO,QAAS,SAAQ,YAAY;IAiB7B;IACA;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/events.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a computer is doing, held open on this side of the model.
|
|
3
3
|
*
|
|
4
|
-
* `GET computers/:id/events` (
|
|
4
|
+
* `GET computers/:id/events` (OPL-3785) is a websocket that says what
|
|
5
5
|
* a computer is doing without being asked, so that an agent stops paying for a
|
|
6
6
|
* screenshot to learn that nothing has changed. Every other client of that
|
|
7
7
|
* stream hands it to its caller as an iterator, because every other caller sits
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
* doorbell an addition to this file rather than a replacement for it, and one
|
|
26
26
|
* whose bell nothing on the other end rings yet.
|
|
27
27
|
*
|
|
28
|
-
* Written against the `events_url` entry in the platform's
|
|
29
|
-
* which is
|
|
28
|
+
* Written against the `events_url` entry in the platform's API reference,
|
|
29
|
+
* which is what this must not contradict.
|
|
30
30
|
*/
|
|
31
31
|
import type { Api } from './api.js';
|
|
32
32
|
/**
|
|
@@ -212,6 +212,9 @@ export declare class Subscription {
|
|
|
212
212
|
*/
|
|
213
213
|
get resumeCursor(): string | undefined;
|
|
214
214
|
get state(): SubscriptionState;
|
|
215
|
+
/** Cached capabilities survive a disconnect; this describes the current connection. */
|
|
216
|
+
get connected(): boolean;
|
|
217
|
+
get connectionVersion(): number;
|
|
215
218
|
get idleMs(): number;
|
|
216
219
|
/** What this computer can emit, as last stated. `undefined` before `hello`. */
|
|
217
220
|
get eventTypes(): string[] | undefined;
|
|
@@ -234,6 +237,10 @@ export declare class Subscription {
|
|
|
234
237
|
* that was looking for file paths.
|
|
235
238
|
*/
|
|
236
239
|
armGeneration(path: string): number;
|
|
240
|
+
/** Whether a completed re-arm still needs to be explained to this tree's caller. */
|
|
241
|
+
hasUndisclosedRearm(path: string): boolean;
|
|
242
|
+
/** Claim a re-arm for the response that is about to explain it. */
|
|
243
|
+
takeUndisclosedRearm(path: string): boolean;
|
|
237
244
|
/** The last thing this tree said it had lost, if it has said one since arming. */
|
|
238
245
|
lostFor(path: string): string | undefined;
|
|
239
246
|
/**
|
|
@@ -317,6 +324,19 @@ export declare class Subscription {
|
|
|
317
324
|
limit: number;
|
|
318
325
|
through?: number;
|
|
319
326
|
}): Delivery;
|
|
327
|
+
/**
|
|
328
|
+
* Whether this read needs the current computer state attached to its loss.
|
|
329
|
+
*
|
|
330
|
+
* Asked before {@link read}, because reconciliation awaits network reads and
|
|
331
|
+
* a caller can cancel during them. Consuming first would advance the shared
|
|
332
|
+
* cursor and clear the loss into a response that caller never receives. This
|
|
333
|
+
* preview may establish a loss for an unknown `since`, but consumes nothing.
|
|
334
|
+
*/
|
|
335
|
+
needsReconciliation(opts: {
|
|
336
|
+
since?: string;
|
|
337
|
+
limit: number;
|
|
338
|
+
through?: number;
|
|
339
|
+
}): boolean;
|
|
320
340
|
/**
|
|
321
341
|
* Where a read or a wait starts: the model's own place, or the cursor it named.
|
|
322
342
|
*
|
|
@@ -398,8 +418,20 @@ export declare class EventHub {
|
|
|
398
418
|
* resume — reaped for idleness, stopped on a computer somebody suspended —
|
|
399
419
|
* and one there is nothing left to resume: a deleted computer's cursor names
|
|
400
420
|
* a position in a stream that no longer exists.
|
|
421
|
+
*
|
|
422
|
+
* `expect` is the subscription the caller drained, and dropping BY IDENTITY
|
|
423
|
+
* rather than by id is what makes this safe under the concurrency these tools
|
|
424
|
+
* are designed for. Two calls on one computer overlap by design — a
|
|
425
|
+
* `wait_for_event` parked while a `poll_events` runs — and each holds its own
|
|
426
|
+
* handle. Without the check: A finds its stream stopped, drains it and drops
|
|
427
|
+
* it; the model's next call opens a fresh, healthy S2; B, still holding the
|
|
428
|
+
* stale S1, wakes, sees the status it recorded, drains an empty ring and
|
|
429
|
+
* drops — closing S2, a stream nothing was wrong with, out from under whoever
|
|
430
|
+
* had just opened it. Looked up by id, `drop` had no way to tell the two
|
|
431
|
+
* apart. A caller with no handle to name (the idle sweep passes the entry it
|
|
432
|
+
* is iterating) still drops whatever is there.
|
|
401
433
|
*/
|
|
402
|
-
drop(computerId: string, reason: string, remember?: boolean): void;
|
|
434
|
+
drop(computerId: string, reason: string, remember?: boolean, expect?: Subscription): void;
|
|
403
435
|
/** Close every socket. The session is over, or the process is going away. */
|
|
404
436
|
closeAll(): void;
|
|
405
437
|
}
|
package/dist/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
package/dist/events.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a computer is doing, held open on this side of the model.
|
|
3
3
|
*
|
|
4
|
-
* `GET computers/:id/events` (
|
|
4
|
+
* `GET computers/:id/events` (OPL-3785) is a websocket that says what
|
|
5
5
|
* a computer is doing without being asked, so that an agent stops paying for a
|
|
6
6
|
* screenshot to learn that nothing has changed. Every other client of that
|
|
7
7
|
* stream hands it to its caller as an iterator, because every other caller sits
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
* doorbell an addition to this file rather than a replacement for it, and one
|
|
26
26
|
* whose bell nothing on the other end rings yet.
|
|
27
27
|
*
|
|
28
|
-
* Written against the `events_url` entry in the platform's
|
|
29
|
-
* which is
|
|
28
|
+
* Written against the `events_url` entry in the platform's API reference,
|
|
29
|
+
* which is what this must not contradict.
|
|
30
30
|
*/
|
|
31
31
|
import { posix } from 'node:path';
|
|
32
32
|
import { WebSocket as UndiciWebSocket } from 'undici';
|
|
33
33
|
import { isTransientForPoll, MandalaError } from './errors.js';
|
|
34
|
-
import { unwrapComputer } from './format.js';
|
|
34
|
+
import { nothingAdmitted, unwrapComputer } from './format.js';
|
|
35
35
|
import * as P from './paths.js';
|
|
36
36
|
/**
|
|
37
37
|
* undici's `WebSocket`, not Node's global one.
|
|
@@ -196,6 +196,8 @@ export class Subscription {
|
|
|
196
196
|
/** The cursor after the last event actually handed to the model. */
|
|
197
197
|
#deliveredCursor;
|
|
198
198
|
#hello;
|
|
199
|
+
/** The buffer position after the greeting's cursor, retained across eviction. */
|
|
200
|
+
#helloFrom = 0;
|
|
199
201
|
#types;
|
|
200
202
|
/**
|
|
201
203
|
* The trees nominated on this stream, oldest nomination first.
|
|
@@ -238,6 +240,10 @@ export class Subscription {
|
|
|
238
240
|
* changed.
|
|
239
241
|
*/
|
|
240
242
|
#armGen = new Map();
|
|
243
|
+
/** Trees that have armed at least once in this subscription. */
|
|
244
|
+
#everArmed = new Set();
|
|
245
|
+
/** Re-arms a file-wait response has not explained yet. */
|
|
246
|
+
#undisclosedRearm = new Set();
|
|
241
247
|
/**
|
|
242
248
|
* The STANDING loss on each tree, cleared when it arms.
|
|
243
249
|
*
|
|
@@ -318,6 +324,8 @@ export class Subscription {
|
|
|
318
324
|
*/
|
|
319
325
|
#sent = [];
|
|
320
326
|
#greeted = false;
|
|
327
|
+
/** Monotonic so overlapping waits can each detect a connection interruption. */
|
|
328
|
+
#connectionVersion = 0;
|
|
321
329
|
/**
|
|
322
330
|
* Whether the socket now closing was closed by THIS side to re-nominate.
|
|
323
331
|
*
|
|
@@ -384,6 +392,13 @@ export class Subscription {
|
|
|
384
392
|
get state() {
|
|
385
393
|
return this.#state;
|
|
386
394
|
}
|
|
395
|
+
/** Cached capabilities survive a disconnect; this describes the current connection. */
|
|
396
|
+
get connected() {
|
|
397
|
+
return this.#greeted && this.#state.status === 'open';
|
|
398
|
+
}
|
|
399
|
+
get connectionVersion() {
|
|
400
|
+
return this.#connectionVersion;
|
|
401
|
+
}
|
|
387
402
|
get idleMs() {
|
|
388
403
|
return Date.now() - this.#lastUsed;
|
|
389
404
|
}
|
|
@@ -421,6 +436,14 @@ export class Subscription {
|
|
|
421
436
|
armGeneration(path) {
|
|
422
437
|
return this.#armGen.get(path) ?? 0;
|
|
423
438
|
}
|
|
439
|
+
/** Whether a completed re-arm still needs to be explained to this tree's caller. */
|
|
440
|
+
hasUndisclosedRearm(path) {
|
|
441
|
+
return this.#undisclosedRearm.has(path);
|
|
442
|
+
}
|
|
443
|
+
/** Claim a re-arm for the response that is about to explain it. */
|
|
444
|
+
takeUndisclosedRearm(path) {
|
|
445
|
+
return this.#undisclosedRearm.delete(path);
|
|
446
|
+
}
|
|
424
447
|
/** The last thing this tree said it had lost, if it has said one since arming. */
|
|
425
448
|
lostFor(path) {
|
|
426
449
|
return this.#watchLost.get(path);
|
|
@@ -508,7 +531,29 @@ export class Subscription {
|
|
|
508
531
|
// its tree limit, and the directory may since exist. "Call again" is the
|
|
509
532
|
// advice every one of those refusals gives, so calling again has to mean
|
|
510
533
|
// something.
|
|
511
|
-
|
|
534
|
+
// `unwatchable` belongs in this list and was the one condition missing from
|
|
535
|
+
// it. It is the only standing loss a nomination can lift — the guest decides
|
|
536
|
+
// watchability when it is ASKED, which is at nomination time, so a directory
|
|
537
|
+
// that has since been created is answered for only by asking again. Left
|
|
538
|
+
// out, the tree stayed in `#sent`, the early return below skipped the
|
|
539
|
+
// reopen, and the clearing on the next connection's `hello` was unreachable:
|
|
540
|
+
// `wait_for_file_change` refused every later call on a tree that was by then
|
|
541
|
+
// perfectly watchable, while its own refusal ended by promising that calling
|
|
542
|
+
// again would find it armed.
|
|
543
|
+
//
|
|
544
|
+
// Deleted here, exactly as `#watchRefused` is, and for the same reason: the
|
|
545
|
+
// reopen below IS the act of asking again, so the old answer must not still
|
|
546
|
+
// be standing while the new one is in flight. Left in place it reopens and
|
|
547
|
+
// then defeats itself — `armedWait` returns on a standing `unwatchable`
|
|
548
|
+
// before the new connection can greet, so the retry costs a round trip and
|
|
549
|
+
// changes nothing. Nothing is carried forward wrongly by dropping it: a
|
|
550
|
+
// guest whose directory is still missing answers `unwatchable` again on the
|
|
551
|
+
// connection this opens, and a reopen that never greets leaves the wait to
|
|
552
|
+
// end on its own deadline, which is what the refused retry beside it does.
|
|
553
|
+
const unwatchable = this.#watchLost.get(path) === 'unwatchable';
|
|
554
|
+
if (unwatchable)
|
|
555
|
+
this.#watchLost.delete(path);
|
|
556
|
+
const retrying = this.#watchRefused.delete(path) || this.#shedCandidate === path || unwatchable;
|
|
512
557
|
if (this.#shedCandidate === path)
|
|
513
558
|
this.#shedCandidate = undefined;
|
|
514
559
|
this.#upgradeFailures = 0;
|
|
@@ -525,8 +570,7 @@ export class Subscription {
|
|
|
525
570
|
// reopen for. A tree being retried is neither.
|
|
526
571
|
if (!retrying && this.#sent.includes(path))
|
|
527
572
|
return {};
|
|
528
|
-
this.#
|
|
529
|
-
this.#socket?.close();
|
|
573
|
+
this.#reopen();
|
|
530
574
|
this.#wakeAll();
|
|
531
575
|
return {};
|
|
532
576
|
}
|
|
@@ -539,6 +583,8 @@ export class Subscription {
|
|
|
539
583
|
this.#watchLost.delete(evicted);
|
|
540
584
|
this.#hostName.delete(evicted);
|
|
541
585
|
this.#interrupted.delete(evicted);
|
|
586
|
+
this.#everArmed.delete(evicted);
|
|
587
|
+
this.#undisclosedRearm.delete(evicted);
|
|
542
588
|
this.#watchRefused.delete(evicted);
|
|
543
589
|
// An experiment about a tree nobody nominates any more has nothing left
|
|
544
590
|
// to prove, and letting it finish would file a refusal against a path
|
|
@@ -554,14 +600,33 @@ export class Subscription {
|
|
|
554
600
|
// which is what `nominates` is for.
|
|
555
601
|
}
|
|
556
602
|
}
|
|
557
|
-
|
|
558
|
-
// reads `#watches` for the new connection. The flag is what keeps that turn
|
|
559
|
-
// from paying the reconnect floor for a reconnection this side chose.
|
|
560
|
-
this.#renominate = true;
|
|
561
|
-
this.#socket?.close();
|
|
603
|
+
this.#reopen();
|
|
562
604
|
this.#wakeAll();
|
|
563
605
|
return { evicted };
|
|
564
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* End the current connection so the next one carries the new watch set.
|
|
609
|
+
*
|
|
610
|
+
* Closed rather than aborted: `#loop` is still running and its next turn
|
|
611
|
+
* reads `#watches` for the new connection. `#renominate` is what keeps that
|
|
612
|
+
* turn from paying the reconnect floor for a reconnection this side chose.
|
|
613
|
+
*
|
|
614
|
+
* The flag is set ONLY when there is a socket to close, because that is what
|
|
615
|
+
* it claims: the connection now ending was ended by this side. Between
|
|
616
|
+
* connections there is none — `finish()` clears `#socket` the moment one
|
|
617
|
+
* ends, and the loop then spends a `GET /computers/:id` and a sleep before
|
|
618
|
+
* assigning the next — and a flag set in that window is consumed by the
|
|
619
|
+
* outcome of a connection this side did not cut short. That connection's
|
|
620
|
+
* failure to reach its opening frame is genuine evidence about the host, and
|
|
621
|
+
* swallowing it skips the backoff step, the `#blamed()` that would eventually
|
|
622
|
+
* shed the tree responsible, and the floor in front of the immediate retry.
|
|
623
|
+
*/
|
|
624
|
+
#reopen() {
|
|
625
|
+
if (!this.#socket)
|
|
626
|
+
return;
|
|
627
|
+
this.#renominate = true;
|
|
628
|
+
this.#socket.close();
|
|
629
|
+
}
|
|
565
630
|
/** Open the socket, if it is not already open. Returns at once. */
|
|
566
631
|
start() {
|
|
567
632
|
if (this.#running)
|
|
@@ -641,6 +706,28 @@ export class Subscription {
|
|
|
641
706
|
attached,
|
|
642
707
|
};
|
|
643
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* Whether this read needs the current computer state attached to its loss.
|
|
711
|
+
*
|
|
712
|
+
* Asked before {@link read}, because reconciliation awaits network reads and
|
|
713
|
+
* a caller can cancel during them. Consuming first would advance the shared
|
|
714
|
+
* cursor and clear the loss into a response that caller never receives. This
|
|
715
|
+
* preview may establish a loss for an unknown `since`, but consumes nothing.
|
|
716
|
+
*/
|
|
717
|
+
needsReconciliation(opts) {
|
|
718
|
+
const from = this.resolveFrom(opts.since);
|
|
719
|
+
if (this.#loss)
|
|
720
|
+
return true;
|
|
721
|
+
if (opts.through === undefined)
|
|
722
|
+
return false;
|
|
723
|
+
const end = opts.through + 1;
|
|
724
|
+
let count = 0;
|
|
725
|
+
for (const buffered of this.#ring) {
|
|
726
|
+
if (buffered.index >= from && buffered.index < end)
|
|
727
|
+
count++;
|
|
728
|
+
}
|
|
729
|
+
return count > opts.limit;
|
|
730
|
+
}
|
|
644
731
|
/**
|
|
645
732
|
* Where a read or a wait starts: the model's own place, or the cursor it named.
|
|
646
733
|
*
|
|
@@ -660,12 +747,21 @@ export class Subscription {
|
|
|
660
747
|
const at = this.#ring.findIndex((b) => b.event.cursor === since);
|
|
661
748
|
if (at >= 0)
|
|
662
749
|
return this.#ring[at].index + 1;
|
|
663
|
-
//
|
|
664
|
-
//
|
|
665
|
-
// deliberate rewind
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
750
|
+
// An opening cursor can outlive everything that followed it in the ring.
|
|
751
|
+
// Evicting already delivered events is harmless for implicit reads, but a
|
|
752
|
+
// deliberate rewind asks for those events again and must hear about the hole.
|
|
753
|
+
if (since === this.#hello?.cursor) {
|
|
754
|
+
const missing = Math.max(0, this.#oldest - this.#helloFrom);
|
|
755
|
+
if (missing && this.#loss?.events !== null) {
|
|
756
|
+
this.#loss = {
|
|
757
|
+
// Unread overflow and this rewind describe overlapping evicted
|
|
758
|
+
// prefixes. Count their union, rather than adding the same loss twice.
|
|
759
|
+
events: Math.max(missing, this.#loss?.events ?? 0),
|
|
760
|
+
reason: 'events requested from that opening cursor were dropped from this session’s buffer',
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
return Math.max(this.#helloFrom, this.#oldest);
|
|
764
|
+
}
|
|
669
765
|
// Otherwise: the unread frontier, NOT the oldest thing still in the ring.
|
|
670
766
|
// A delivered event stays in the ring until the cap evicts it, so answering
|
|
671
767
|
// an unplaceable cursor with `#oldest` re-sent events the model already
|
|
@@ -814,12 +910,38 @@ export class Subscription {
|
|
|
814
910
|
cancel?.addEventListener('abort', done, { once: true });
|
|
815
911
|
});
|
|
816
912
|
}
|
|
817
|
-
/**
|
|
913
|
+
/**
|
|
914
|
+
* The cursor for a position — WHERE THE CALLER IS, which is not always where
|
|
915
|
+
* the socket is.
|
|
916
|
+
*
|
|
917
|
+
* The last event handed over answers it whenever there was one. When there was
|
|
918
|
+
* not, the answer is still the model's own place and not `#resume`, which is
|
|
919
|
+
* after the last event this connection RECEIVED. The two are the same on an
|
|
920
|
+
* ordinary empty poll, and that is why the difference went unnoticed: no
|
|
921
|
+
* `through`, an empty window means the position has caught up with the ring.
|
|
922
|
+
*
|
|
923
|
+
* A `through` read is the case where they part. A wait resolves on an event
|
|
924
|
+
* and reads up to it, and by then another call on the same computer — which
|
|
925
|
+
* these tools are built to allow — may already have taken it: the window comes
|
|
926
|
+
* back empty while `more` is still positive. Answering `#resume` there hands
|
|
927
|
+
* back `more_waiting: N` beside a cursor that, passed in as `since`, resolves
|
|
928
|
+
* PAST those N events, with no loss to say they were skipped. So the position
|
|
929
|
+
* is read off the ring at `#delivered`, which is the one place that agrees
|
|
930
|
+
* with the `more` in the same answer.
|
|
931
|
+
*/
|
|
818
932
|
#position(last) {
|
|
819
933
|
const cursor = last?.event.cursor;
|
|
820
934
|
if (typeof cursor === 'string' && cursor)
|
|
821
935
|
return cursor;
|
|
822
|
-
|
|
936
|
+
const at = this.#ring.find((b) => b.index === this.#delivered - 1)?.event.cursor;
|
|
937
|
+
if (typeof at === 'string' && at)
|
|
938
|
+
return at;
|
|
939
|
+
// Nothing in the ring to place it by: either nothing has been delivered on
|
|
940
|
+
// this stream at all, or the event the position sits after has been evicted.
|
|
941
|
+
// The last cursor DELIVERED before `#resume`, for the reason
|
|
942
|
+
// {@link resumeCursor} gives — a position behind the truth is re-read, a
|
|
943
|
+
// position ahead of it is a hole nothing reports.
|
|
944
|
+
return this.#deliveredCursor ?? this.#resume ?? this.#hello?.cursor ?? '';
|
|
823
945
|
}
|
|
824
946
|
#wakeAll() {
|
|
825
947
|
for (const wake of [...this.#wake])
|
|
@@ -827,6 +949,10 @@ export class Subscription {
|
|
|
827
949
|
}
|
|
828
950
|
#push(event) {
|
|
829
951
|
this.#ring.push({ index: this.#nextIndex++, event });
|
|
952
|
+
// A resumed stream may replay the greeting's cursor after the greeting.
|
|
953
|
+
// Once that event arrives, its position is stronger than the initial frontier.
|
|
954
|
+
if (event.cursor === this.#hello?.cursor)
|
|
955
|
+
this.#helloFrom = this.#nextIndex;
|
|
830
956
|
if (this.#ring.length > MAX_BUFFERED) {
|
|
831
957
|
const evicted = this.#ring.splice(0, this.#ring.length - MAX_BUFFERED);
|
|
832
958
|
// Only what the model had not been handed is a loss. Dropping events it
|
|
@@ -966,22 +1092,55 @@ export class Subscription {
|
|
|
966
1092
|
throw err;
|
|
967
1093
|
}
|
|
968
1094
|
const status = c.status ?? 'unknown';
|
|
969
|
-
|
|
1095
|
+
// SETTLING IS FOREVER, so each of these has to be a state nobody is already
|
|
1096
|
+
// moving out of. `status` cannot say that on its own: it is read from the
|
|
1097
|
+
// guest process, and a start that has been ADMITTED has no process yet, so
|
|
1098
|
+
// it reads `stopped` through a cold boot and `suspended` through a resume —
|
|
1099
|
+
// whose session record is spent only on the way out of a start that worked.
|
|
1100
|
+
// A stream opened against a computer mid-resume used to die permanently and
|
|
1101
|
+
// name the resume as the reason (OPL-4631). nothingAdmitted is the
|
|
1102
|
+
// platform's own word for idle, and absence of the field is not that word.
|
|
1103
|
+
if (status === 'suspended' && nothingAdmitted(c)) {
|
|
970
1104
|
throw new SettledError(`${this.computerId} suspended, and the event stream is the one part of this API that does ` +
|
|
971
1105
|
'not resume a computer for you. Listening is not using, so a computer nobody touches ' +
|
|
972
1106
|
'suspends underneath its own stream. start_computer, then ask again.');
|
|
973
1107
|
}
|
|
974
|
-
|
|
975
|
-
|
|
1108
|
+
// Two terminal answers, and they are not the same answer. A disk that was
|
|
1109
|
+
// never finished is not started by anybody — the platform's own remedy is
|
|
1110
|
+
// "delete it and build it again" — so telling that caller to start_computer
|
|
1111
|
+
// sends them at a call that refuses them (Codex review).
|
|
1112
|
+
if (status === 'build-failed') {
|
|
1113
|
+
throw new SettledError(`${this.computerId}'s disk was never finished, so there is nothing to stream and nothing ` +
|
|
1114
|
+
'to start. Delete it and build it again.');
|
|
1115
|
+
}
|
|
1116
|
+
if (status === 'stopped' && nothingAdmitted(c)) {
|
|
1117
|
+
throw new SettledError(`${this.computerId} is stopped, and only a running computer has an event stream. ` +
|
|
976
1118
|
'start_computer, then ask again.');
|
|
977
1119
|
}
|
|
1120
|
+
// A computer whose disk was unlinked by a deletion that stopped partway
|
|
1121
|
+
// will never start again — the reference says so, and says deleting it
|
|
1122
|
+
// again is what clears it — so it belongs with the terminal states rather
|
|
1123
|
+
// than in the backoff below (Codex review).
|
|
1124
|
+
if (status === 'half-removed') {
|
|
1125
|
+
throw new SettledError(`${this.computerId} is half-removed: its disk is gone, it will never start again, and ` +
|
|
1126
|
+
'only deleting it again clears it. There is nothing to stream.');
|
|
1127
|
+
}
|
|
978
1128
|
if (status !== 'running') {
|
|
979
|
-
//
|
|
980
|
-
//
|
|
981
|
-
//
|
|
982
|
-
//
|
|
983
|
-
//
|
|
984
|
-
//
|
|
1129
|
+
// What is left is a state that MAY clear, which is a weaker claim than
|
|
1130
|
+
// the one this comment used to make and the honest one: `building`; a
|
|
1131
|
+
// `stopped` or `suspended` computer whose start has been admitted and is
|
|
1132
|
+
// loading; and the two readings that are not answers at all — a status
|
|
1133
|
+
// this client does not know, and a stopped or suspended computer whose
|
|
1134
|
+
// pool the host did not report. Retrying those is right for the same
|
|
1135
|
+
// reason waiting is: nothing here has said the machine will not come up.
|
|
1136
|
+
// What it is not is a promise that one will.
|
|
1137
|
+
//
|
|
1138
|
+
// That last pair is what this branch was FOR, and it could not reach it.
|
|
1139
|
+
// The comment here used to name `starting`, `moving` and `creating`; the
|
|
1140
|
+
// platform reports none of them — its statuses are `running`, `stopped`,
|
|
1141
|
+
// `suspended`, `building`, `build-failed` and `half-removed` — so the
|
|
1142
|
+
// flow it described, a create_computer followed at once by
|
|
1143
|
+
// wait_for_event("computer.ready"), met `stopped` and settled above.
|
|
985
1144
|
throw new MandalaError(`${this.computerId} is ${status}; waiting for it to be running`);
|
|
986
1145
|
}
|
|
987
1146
|
const vnc = c.vnc;
|
|
@@ -1100,6 +1259,8 @@ export class Subscription {
|
|
|
1100
1259
|
// A connection that has ended is not carrying anything, whatever it was
|
|
1101
1260
|
// greeted with. Without this the window between one connection ending
|
|
1102
1261
|
// and the next opening reads as a tree still on the wire.
|
|
1262
|
+
if (opened)
|
|
1263
|
+
this.#connectionVersion++;
|
|
1103
1264
|
this.#greeted = false;
|
|
1104
1265
|
if (this.#socket === socket)
|
|
1105
1266
|
this.#socket = undefined;
|
|
@@ -1166,6 +1327,13 @@ export class Subscription {
|
|
|
1166
1327
|
windows: Array.isArray(frame.windows) ? frame.windows : undefined,
|
|
1167
1328
|
watching: watched(frame.watching),
|
|
1168
1329
|
};
|
|
1330
|
+
const buffered = this.#ring.find((b) => b.event.cursor === hello.cursor);
|
|
1331
|
+
if (buffered)
|
|
1332
|
+
this.#helloFrom = buffered.index + 1;
|
|
1333
|
+
else if (hello.cursor !== this.#hello?.cursor)
|
|
1334
|
+
this.#helloFrom = this.#nextIndex;
|
|
1335
|
+
// The same greeting on a reconnect must retain its original frontier,
|
|
1336
|
+
// including any history that has since been evicted.
|
|
1169
1337
|
this.#hello = hello;
|
|
1170
1338
|
this.#types = hello.events;
|
|
1171
1339
|
this.#greeted = true;
|
|
@@ -1258,7 +1426,7 @@ export class Subscription {
|
|
|
1258
1426
|
// would drop a permanent condition that nothing puts back. `hello.watching`
|
|
1259
1427
|
// has no field for it, so the flag is the only record there is.
|
|
1260
1428
|
if (w.armed && !this.isArmed(nominated)) {
|
|
1261
|
-
this.#
|
|
1429
|
+
this.#armedTransition(nominated);
|
|
1262
1430
|
this.#watchLost.delete(nominated);
|
|
1263
1431
|
}
|
|
1264
1432
|
else if (this.#watchLost.get(nominated) === 'unwatchable') {
|
|
@@ -1333,6 +1501,14 @@ export class Subscription {
|
|
|
1333
1501
|
#bumpArm(path) {
|
|
1334
1502
|
this.#armGen.set(path, (this.#armGen.get(path) ?? 0) + 1);
|
|
1335
1503
|
}
|
|
1504
|
+
/** Record an arm, retaining later arms until a file wait explains their gap. */
|
|
1505
|
+
#armedTransition(path) {
|
|
1506
|
+
if (this.#everArmed.has(path))
|
|
1507
|
+
this.#undisclosedRearm.add(path);
|
|
1508
|
+
else
|
|
1509
|
+
this.#everArmed.add(path);
|
|
1510
|
+
this.#bumpArm(path);
|
|
1511
|
+
}
|
|
1336
1512
|
/**
|
|
1337
1513
|
* What a `file.changed` says about the TREE, as opposed to about a file.
|
|
1338
1514
|
*
|
|
@@ -1375,7 +1551,7 @@ export class Subscription {
|
|
|
1375
1551
|
// clears the flag when the link goes down — and the wait that should have
|
|
1376
1552
|
// said "re-read the tree" would have gone on waiting on a tree whose
|
|
1377
1553
|
// history had a hole in it.
|
|
1378
|
-
this.#
|
|
1554
|
+
this.#armedTransition(watch);
|
|
1379
1555
|
this.#armed.set(watch, true);
|
|
1380
1556
|
return;
|
|
1381
1557
|
}
|
|
@@ -1535,11 +1711,25 @@ export class EventHub {
|
|
|
1535
1711
|
* resume — reaped for idleness, stopped on a computer somebody suspended —
|
|
1536
1712
|
* and one there is nothing left to resume: a deleted computer's cursor names
|
|
1537
1713
|
* a position in a stream that no longer exists.
|
|
1714
|
+
*
|
|
1715
|
+
* `expect` is the subscription the caller drained, and dropping BY IDENTITY
|
|
1716
|
+
* rather than by id is what makes this safe under the concurrency these tools
|
|
1717
|
+
* are designed for. Two calls on one computer overlap by design — a
|
|
1718
|
+
* `wait_for_event` parked while a `poll_events` runs — and each holds its own
|
|
1719
|
+
* handle. Without the check: A finds its stream stopped, drains it and drops
|
|
1720
|
+
* it; the model's next call opens a fresh, healthy S2; B, still holding the
|
|
1721
|
+
* stale S1, wakes, sees the status it recorded, drains an empty ring and
|
|
1722
|
+
* drops — closing S2, a stream nothing was wrong with, out from under whoever
|
|
1723
|
+
* had just opened it. Looked up by id, `drop` had no way to tell the two
|
|
1724
|
+
* apart. A caller with no handle to name (the idle sweep passes the entry it
|
|
1725
|
+
* is iterating) still drops whatever is there.
|
|
1538
1726
|
*/
|
|
1539
|
-
drop(computerId, reason, remember = false) {
|
|
1727
|
+
drop(computerId, reason, remember = false, expect) {
|
|
1540
1728
|
const sub = this.#subs.get(computerId);
|
|
1541
1729
|
if (!sub)
|
|
1542
1730
|
return;
|
|
1731
|
+
if (expect !== undefined && sub !== expect)
|
|
1732
|
+
return;
|
|
1543
1733
|
const at = sub.resumeCursor;
|
|
1544
1734
|
const watches = sub.nominations;
|
|
1545
1735
|
sub.close(reason);
|
|
@@ -1580,7 +1770,7 @@ export class EventHub {
|
|
|
1580
1770
|
// be reported once. The idle window is what eventually takes it.
|
|
1581
1771
|
if (sub.idleMs < IDLE_REAP_MS)
|
|
1582
1772
|
continue;
|
|
1583
|
-
this.drop(id, 'nothing asked about this computer for five minutes', true);
|
|
1773
|
+
this.drop(id, 'nothing asked about this computer for five minutes', true, sub);
|
|
1584
1774
|
}
|
|
1585
1775
|
if (!this.#subs.size)
|
|
1586
1776
|
this.#stopSweep();
|