@ours.network/fleet 1.2.0-nightly.64 → 1.2.0-nightly.66

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.
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Durable, private, single-writer state for one agent's self-reminders.
3
+ *
4
+ * The runner that supervises the agent is the only writer: the agent's MCP
5
+ * tools, the dispatch timer and the session's release guard all run in that
6
+ * one process, and every mutation here is synchronous, so each method call is
7
+ * its own linearization point. Asynchronous callers (a queue receipt, a turn
8
+ * completion) never carry state across an `await`; they re-read the current
9
+ * record and apply only forward transitions, so a late receipt can never undo
10
+ * an acknowledgement, update or cancellation that happened meanwhile.
11
+ *
12
+ * Event lifecycle — the boundary that matters is `dispatched`:
13
+ *
14
+ * pending ──admit──▶ admitting ──release guard──▶ dispatched ──ack──▶ acknowledged
15
+ * ▲ │ │
16
+ * └── not released ───┘ └─ restart ─▶ uncertain (held)
17
+ *
18
+ * `dispatched` is written durably by the session's release guard immediately
19
+ * before the prompt is handed to the model. An event found `admitting` after a
20
+ * restart therefore provably never reached the model (reminder prompt bodies
21
+ * are not retained, so session recovery cannot replay them) and is retried
22
+ * under the same event id. An event found `dispatched` may or may not have been
23
+ * seen, so it is held as `uncertain` and never automatically re-admitted.
24
+ */
25
+ export declare const SELF_REMINDERS_FILE = ".self-reminders.json";
26
+ export declare const MAX_OPEN_REMINDERS = 100;
27
+ export declare const MAX_RETAINED_CLOSED = 200;
28
+ export declare const DEFAULT_LATE_WINDOW_SECONDS = 3600;
29
+ export declare const MAX_LATE_WINDOW_SECONDS: number;
30
+ export declare const MIN_LATE_WINDOW_SECONDS = 60;
31
+ export type ReminderState = 'active' | 'delivered' | 'acknowledged' | 'cancelled' | 'expired';
32
+ export type ReminderEventState = 'pending' | 'admitting' | 'dispatched' | 'uncertain' | 'acknowledged' | 'invalidated' | 'expired';
33
+ /**
34
+ * Who a store belongs to. The fields that must match depend on lifetime,
35
+ * because that is what each lifetime keeps stable across its ordinary
36
+ * stop/start:
37
+ *
38
+ * - `permanent`: an orderly stop releases the managed runtime, and the next
39
+ * start provisions a new runtime instance and action for the SAME identity
40
+ * and state directory. Ownership is the role plus its identity CID. A
41
+ * removed agent's state directory is deleted, so a later same-named agent
42
+ * starts without this store; a replaced identity has a different CID.
43
+ * - `temporary` (including task members): suspend/resume keeps the runtime
44
+ * instance and action, and retirement archives the directory with this store
45
+ * removed. Ownership is role, CID, instance and action.
46
+ */
47
+ export interface ReminderOwner {
48
+ role: string;
49
+ lifetime: 'permanent' | 'temporary';
50
+ /** Logical managed-runtime instance. */
51
+ instance: string;
52
+ cid: string;
53
+ /** Creation action of that runtime instance. */
54
+ action: string;
55
+ }
56
+ export interface ReminderRecord {
57
+ id: string;
58
+ requestKey: string;
59
+ requestDigest: string;
60
+ revision: number;
61
+ state: ReminderState;
62
+ title: string;
63
+ note: string;
64
+ localTime: string;
65
+ timeZone: string;
66
+ fold?: 0 | 1;
67
+ dueAt: string;
68
+ lateWindowSeconds: number;
69
+ expiresAt: string;
70
+ createdAt: string;
71
+ updatedAt: string;
72
+ closedReason?: string;
73
+ }
74
+ export interface ReminderEvent {
75
+ id: string;
76
+ reminderId: string;
77
+ revision: number;
78
+ state: ReminderEventState;
79
+ createdAt: string;
80
+ attempts: number;
81
+ retryAt?: string;
82
+ promptId?: string;
83
+ admittedAt?: string;
84
+ dispatchedAt?: string;
85
+ closedAt?: string;
86
+ reason?: string;
87
+ }
88
+ export declare class ReminderError extends Error {
89
+ readonly code: string;
90
+ constructor(code: string, message: string);
91
+ }
92
+ export interface ReminderWriter {
93
+ (path: string, contents: string): void;
94
+ }
95
+ export interface ScheduleInput {
96
+ title?: unknown;
97
+ note?: unknown;
98
+ local_time?: unknown;
99
+ time_zone?: unknown;
100
+ fold?: unknown;
101
+ late_window_seconds?: unknown;
102
+ }
103
+ export interface ReminderView {
104
+ id: string;
105
+ /** The caller's own idempotency key, so a retried or interrupted run can find its work. */
106
+ request_key: string;
107
+ revision: number;
108
+ state: ReminderState;
109
+ title: string;
110
+ note: string;
111
+ local_time: string;
112
+ time_zone: string;
113
+ fold?: 0 | 1;
114
+ due_at: string;
115
+ late_window_seconds: number;
116
+ expires_at: string;
117
+ created_at: string;
118
+ updated_at: string;
119
+ closed_reason?: string;
120
+ /** The current revision's wake, if one exists. */
121
+ event?: {
122
+ id: string;
123
+ state: ReminderEventState;
124
+ revision: number;
125
+ };
126
+ }
127
+ export declare class ReminderStore {
128
+ readonly owner: ReminderOwner;
129
+ private readonly now;
130
+ private readonly log;
131
+ private readonly write;
132
+ readonly path: string;
133
+ private state;
134
+ /**
135
+ * Load or create the store for exactly this owner (see `ReminderOwner`). A
136
+ * store written for anyone else is never adopted: it is moved aside and
137
+ * nothing in it is delivered, so a same-named successor or a replaced
138
+ * identity cannot inherit a predecessor's wakes.
139
+ */
140
+ constructor(stateDir: string, owner: ReminderOwner, now: () => number, log?: (line: string) => void, write?: ReminderWriter);
141
+ /** Restart recovery. Never re-admits anything that may have reached the model. */
142
+ private recover;
143
+ private persist;
144
+ /**
145
+ * Apply a mutation and persist it as one step. If the write fails the
146
+ * in-memory state is restored, so memory never claims what disk does not.
147
+ */
148
+ private commit;
149
+ private reminder;
150
+ private event;
151
+ private schedule;
152
+ private openCount;
153
+ create(requestKey: unknown, input: ScheduleInput): {
154
+ reminder: ReminderView;
155
+ created: boolean;
156
+ };
157
+ update(id: unknown, expectedRevision: unknown, input: ScheduleInput): ReminderView;
158
+ cancel(id: unknown, expectedRevision: unknown): ReminderView;
159
+ list(filter?: {
160
+ state?: unknown;
161
+ limit?: unknown;
162
+ after?: unknown;
163
+ }): {
164
+ uncertain_events: number;
165
+ after?: string | undefined;
166
+ reminders: ReminderView[];
167
+ more: boolean;
168
+ };
169
+ inspect(eventId: unknown): {
170
+ event: {
171
+ reason?: string | undefined;
172
+ closed_at?: string | undefined;
173
+ dispatched_at?: string | undefined;
174
+ id: string;
175
+ reminder_id: string;
176
+ revision: number;
177
+ state: ReminderEventState;
178
+ created_at: string;
179
+ };
180
+ reminder: ReminderView | undefined;
181
+ current: boolean;
182
+ eligible: boolean;
183
+ late_by_ms: number | undefined;
184
+ };
185
+ ack(eventId: unknown, expectedRevision: unknown): {
186
+ event: {
187
+ reason?: string | undefined;
188
+ closed_at?: string | undefined;
189
+ dispatched_at?: string | undefined;
190
+ id: string;
191
+ reminder_id: string;
192
+ revision: number;
193
+ state: ReminderEventState;
194
+ created_at: string;
195
+ };
196
+ acknowledged: boolean;
197
+ duplicate: boolean;
198
+ };
199
+ /**
200
+ * Earliest instant the dispatcher has work, or undefined when idle.
201
+ * `live` names admissions still owned by a queued prompt in this process:
202
+ * their own completion re-arms the dispatcher, so they are not work here.
203
+ */
204
+ nextWorkAt(live?: ReadonlySet<string>): number | undefined;
205
+ private openEvent;
206
+ /**
207
+ * Expire what is past its window and create a pending event for each due
208
+ * reminder. Returns the events ready to admit now, earliest due first.
209
+ */
210
+ sweep(live?: ReadonlySet<string>): ReminderEvent[];
211
+ /** Durable claim made before the prompt is queued. False: do not queue. */
212
+ markAdmitting(eventId: string): boolean;
213
+ /** Record the session's queue receipt; never moves an event backwards. */
214
+ recordReceipt(eventId: string, promptId: string): void;
215
+ /**
216
+ * The release guard: called synchronously by the session at the moment the
217
+ * prompt would be handed to the model. It returns true only after
218
+ * `dispatched` is durably on disk; any doubt refuses the dispatch.
219
+ */
220
+ claimDispatch(eventId: string, stopping: boolean): {
221
+ dispatch: boolean;
222
+ reason?: string;
223
+ };
224
+ /**
225
+ * An admission that ended without the release guard dispatching it (queue
226
+ * refused, session died, release refused while stopping) goes back to
227
+ * pending. Anything already past `admitting` is left exactly as it is.
228
+ */
229
+ releaseUndispatched(eventId: string, retryAt: number): void;
230
+ eventSummary(eventId: string): {
231
+ event: ReminderEvent;
232
+ reminder: ReminderRecord;
233
+ } | undefined;
234
+ private supersedeEvents;
235
+ /** Bound retained history; open reminders and their events are never dropped. */
236
+ private prune;
237
+ private view;
238
+ private eventView;
239
+ }
240
+ /** Remove a retired agent's reminder store and any quarantined copies. */
241
+ export declare function removeReminderState(stateDir: string): void;