@tinycloud/courier 0.2.0-beta.38 → 0.2.0-beta.40
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 +51 -13
- package/dist/a2a.d.ts +1 -1
- package/dist/a2a.js +1 -1
- package/dist/a2a.js.map +1 -1
- package/dist/notify.d.ts +6 -2
- package/dist/notify.js +11 -7
- package/dist/notify.js.map +1 -1
- package/dist/pause.d.ts +8 -2
- package/dist/pause.js +27 -15
- package/dist/pause.js.map +1 -1
- package/dist/watch-cmd.js +1 -1
- package/dist/watch-cmd.js.map +1 -1
- package/dist/watch.d.ts +73 -9
- package/dist/watch.js +473 -70
- package/dist/watch.js.map +1 -1
- package/package.json +3 -3
- package/skills/courier/SKILL.md +26 -1
package/dist/watch.d.ts
CHANGED
|
@@ -13,6 +13,38 @@ export interface PendingWake {
|
|
|
13
13
|
firstSeenAt: number;
|
|
14
14
|
lastSeenAt: number;
|
|
15
15
|
}
|
|
16
|
+
interface NoticeRetry {
|
|
17
|
+
/** Six digits while dispatching, otherwise six dashes; independent of the display count. */
|
|
18
|
+
dispatchArrivals: string;
|
|
19
|
+
tries: number;
|
|
20
|
+
nextAttemptAt: number;
|
|
21
|
+
logged: boolean;
|
|
22
|
+
}
|
|
23
|
+
type NeedsKind = 'message' | 'approval';
|
|
24
|
+
interface NeedsSlot extends NoticeRetry {
|
|
25
|
+
threadId: string;
|
|
26
|
+
eventId: string;
|
|
27
|
+
count: string;
|
|
28
|
+
firstSeenAt: string;
|
|
29
|
+
arrivalFirstSeenAt: string;
|
|
30
|
+
}
|
|
31
|
+
interface PauseEpisode extends NoticeRetry {
|
|
32
|
+
kind: '' | 'paused' | 'peer-paused';
|
|
33
|
+
eventId: string;
|
|
34
|
+
/** Fixed-width saturating count of additional transitions represented by this slot. */
|
|
35
|
+
repeats: string;
|
|
36
|
+
}
|
|
37
|
+
/** Allocated only from our own thread/wake/pause records, never from incoming notice ids. */
|
|
38
|
+
interface ThreadNoticeState {
|
|
39
|
+
ourPaused: boolean;
|
|
40
|
+
peerPaused: boolean;
|
|
41
|
+
lastPeerNoticeId: string;
|
|
42
|
+
lastNoticeSentAt: string;
|
|
43
|
+
ourMarkerId: string;
|
|
44
|
+
episodes: [PauseEpisode, PauseEpisode];
|
|
45
|
+
informPending: boolean;
|
|
46
|
+
informText: string;
|
|
47
|
+
}
|
|
16
48
|
export interface WatchState {
|
|
17
49
|
v: 1;
|
|
18
50
|
/** Keyed `<peer>/<threadId>`. */
|
|
@@ -24,21 +56,34 @@ export interface WatchState {
|
|
|
24
56
|
wakes: Record<string, number[]>;
|
|
25
57
|
/** Threads this watcher has seen paused; a marker that vanishes from this list means the human resumed it. */
|
|
26
58
|
paused: string[];
|
|
59
|
+
/** Failed wake count and completion-based backoff, retained across watcher restarts. */
|
|
60
|
+
wakeRetries: Record<string, {
|
|
61
|
+
failures: number;
|
|
62
|
+
nextAttemptAt: number;
|
|
63
|
+
}>;
|
|
64
|
+
approvalRetries: Record<string, {
|
|
65
|
+
failures: number;
|
|
66
|
+
nextAttemptAt: number;
|
|
67
|
+
}>;
|
|
27
68
|
/** Posts and notifications that must happen exactly-ish once and survive a restart (retried until they succeed). */
|
|
28
69
|
outbox: OutboxItem[];
|
|
29
70
|
held: Record<string, HeldBacklog>;
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
/**
|
|
71
|
+
/** One fixed record per locally known thread. Peer ids are values, never keys. */
|
|
72
|
+
threadNotices: Record<string, ThreadNoticeState>;
|
|
73
|
+
/** Two coalescing needs-you slots per locally paired peer, allocated only from local configuration. */
|
|
74
|
+
peerNotices: Record<string, Record<NeedsKind, NeedsSlot>>;
|
|
75
|
+
noticeGlobalLog: number[];
|
|
76
|
+
/** Every dispatch attempt, success or failure, per peer for the shared rolling-hour cap. */
|
|
33
77
|
noticeLog: Record<string, number[]>;
|
|
34
78
|
}
|
|
35
|
-
/** `tries
|
|
79
|
+
/** `tries`: notification dispatch attempts (max 3), or failed inform attempts (max 8). */
|
|
36
80
|
export type OutboxItem = {
|
|
37
81
|
id: string;
|
|
38
82
|
kind: 'inform';
|
|
39
83
|
peer: string;
|
|
40
84
|
threadId: string;
|
|
41
85
|
text: string;
|
|
86
|
+
pauseId?: string;
|
|
42
87
|
tries?: number;
|
|
43
88
|
nextAttemptAt?: number;
|
|
44
89
|
} | {
|
|
@@ -87,12 +132,12 @@ export interface WatchDeps {
|
|
|
87
132
|
wake: Waker;
|
|
88
133
|
log: WatchLog;
|
|
89
134
|
/** Posts the `thread-paused` inform to a peer (own space, `to/<peer>/threads/<id>/msg/`). Default: nothing. */
|
|
90
|
-
postInform?(peer: string, threadId: string, text: string): Promise<void>;
|
|
135
|
+
postInform?(peer: string, threadId: string, text: string, pauseId?: string): Promise<void>;
|
|
91
136
|
/** Tells this side's human without a model (desktop notification or operator command). Default: log only. */
|
|
92
137
|
notify?: Notifier;
|
|
93
138
|
/** Local bounded notification log; omitted by library callers that want no disk output. */
|
|
94
139
|
notificationHome?: string;
|
|
95
|
-
/** D mode
|
|
140
|
+
/** D mode mirrors and receipts, then notifies without invoking a wake adapter. */
|
|
96
141
|
notifyOnly?: boolean;
|
|
97
142
|
/**
|
|
98
143
|
* Who this watcher is, for wake claims. `profileId` is stable for this profile on this machine (a restart keeps it,
|
|
@@ -121,7 +166,6 @@ export declare class Watcher {
|
|
|
121
166
|
private pausedKeys;
|
|
122
167
|
/** Serialises everything that reads or writes pause markers, so a stale listing cannot drop a pause just written. */
|
|
123
168
|
private pausedLock;
|
|
124
|
-
private readonly wakeFailures;
|
|
125
169
|
private readonly outboxBusy;
|
|
126
170
|
private approvalsAgain;
|
|
127
171
|
/** Unique to this run: a claim with this id is this process's own. */
|
|
@@ -172,6 +216,8 @@ export declare class Watcher {
|
|
|
172
216
|
/** Serialises syncs per peer; a request that arrives mid-sync reruns once after it. */
|
|
173
217
|
sync(peer: StoredPeer, via: Via): Promise<void>;
|
|
174
218
|
private syncPeer;
|
|
219
|
+
/** Only locally authored meta/messages/tasks, or a local wake/pause witness, establish a known thread. */
|
|
220
|
+
private syncKnownThreads;
|
|
175
221
|
private mirrorCreate;
|
|
176
222
|
/**
|
|
177
223
|
* meta.json is immutable (create-only); tasks are mutable, so copy the latest until they are terminal. Runs after
|
|
@@ -197,8 +243,26 @@ export declare class Watcher {
|
|
|
197
243
|
private exclusive;
|
|
198
244
|
/** Called inside `mutate`: parks a message that arrived while its thread is paused (bounded). */
|
|
199
245
|
private hold;
|
|
200
|
-
/**
|
|
246
|
+
/** Two episode values per known thread. Additional transitions coalesce, without allocating another slot. */
|
|
247
|
+
private queueEpisode;
|
|
248
|
+
/** Only the paired handles in our local configuration allocate needs-you state. */
|
|
249
|
+
private syncNoticePeers;
|
|
250
|
+
/** Bounded values only: a later delivery updates the same paired-peer slot. Called inside mutate. */
|
|
251
|
+
private queueNeeds;
|
|
252
|
+
private noticeSlot;
|
|
253
|
+
private rememberNotice;
|
|
254
|
+
/** Earliest rolling-hour retry under the global allowance and each paired peer's share. */
|
|
255
|
+
private noticeRateDeadline;
|
|
256
|
+
/** -1 appends; a nonnegative index yields that place; undefined leaves the pending slot alone. */
|
|
257
|
+
private admissionIndex;
|
|
258
|
+
/** Queue places can yield; the two fixed episode records retain all retry metadata. */
|
|
201
259
|
private enqueue;
|
|
260
|
+
private outboxCandidates;
|
|
261
|
+
/** Admit local work first, allowing eligible peers to pass deferred entries in a full queue. */
|
|
262
|
+
private fillOutbox;
|
|
263
|
+
private fairOutbox;
|
|
264
|
+
/** Completion matches both the fixed slot and episode ULID; another queued episode is independent. */
|
|
265
|
+
private finishOutbox;
|
|
202
266
|
/**
|
|
203
267
|
* Markers under me/state/paused/ are the truth. A marker that disappeared means the human resumed: the budget starts
|
|
204
268
|
* over and what arrived meanwhile wakes the agent once. Serialised, so overlapping calls never apply a stale listing.
|
|
@@ -206,7 +270,7 @@ export declare class Watcher {
|
|
|
206
270
|
syncPaused(): Promise<void>;
|
|
207
271
|
/** State that only matters for a day or an hour is dropped, so it cannot grow without bound. */
|
|
208
272
|
private pruneState;
|
|
209
|
-
/** Informs and notifications queued in state; failures back off (1, 2, 4 ... 15 minutes) and give up after
|
|
273
|
+
/** Informs and notifications queued in state; failures back off (1, 2, 4 ... 15 minutes) and give up after 3 notification attempts or 8 inform failures. */
|
|
210
274
|
private runOutbox;
|
|
211
275
|
pollOnce(via: Via): Promise<void>;
|
|
212
276
|
/**
|