@corenel/harness 0.2.0 → 0.4.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/dist/acp/agentMap.d.ts +34 -0
- package/dist/acp/agentMap.d.ts.map +1 -0
- package/dist/acp/agentMap.js +110 -0
- package/dist/acp/agentMap.js.map +1 -0
- package/dist/acp/index.d.ts +4 -0
- package/dist/acp/index.d.ts.map +1 -0
- package/dist/acp/index.js +6 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/acp/policyMap.d.ts +55 -0
- package/dist/acp/policyMap.d.ts.map +1 -0
- package/dist/acp/policyMap.js +121 -0
- package/dist/acp/policyMap.js.map +1 -0
- package/dist/acp/types.d.ts +41 -0
- package/dist/acp/types.d.ts.map +1 -0
- package/dist/acp/types.js +14 -0
- package/dist/acp/types.js.map +1 -0
- package/dist/api/backend.d.ts +39 -0
- package/dist/api/backend.d.ts.map +1 -0
- package/dist/api/backend.js +126 -0
- package/dist/api/backend.js.map +1 -0
- package/dist/api/client.d.ts +95 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +212 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/fileMirrorSource.d.ts +24 -0
- package/dist/api/fileMirrorSource.d.ts.map +1 -0
- package/dist/api/fileMirrorSource.js +59 -0
- package/dist/api/fileMirrorSource.js.map +1 -0
- package/dist/api/mirror.d.ts +102 -0
- package/dist/api/mirror.d.ts.map +1 -0
- package/dist/api/mirror.js +204 -0
- package/dist/api/mirror.js.map +1 -0
- package/dist/api/mirrorScheduler.d.ts +56 -0
- package/dist/api/mirrorScheduler.d.ts.map +1 -0
- package/dist/api/mirrorScheduler.js +167 -0
- package/dist/api/mirrorScheduler.js.map +1 -0
- package/dist/compression.d.ts +15 -1
- package/dist/compression.d.ts.map +1 -1
- package/dist/compression.js +32 -1
- package/dist/compression.js.map +1 -1
- package/dist/core/loop.d.ts +12 -0
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +138 -14
- package/dist/core/loop.js.map +1 -1
- package/dist/core/spawn.d.ts +54 -0
- package/dist/core/spawn.d.ts.map +1 -0
- package/dist/core/spawn.js +58 -0
- package/dist/core/spawn.js.map +1 -0
- package/dist/dag/executeNode.js +2 -2
- package/dist/fileSchema.js +1 -1
- package/dist/guardrail/guardrail.js +1 -1
- package/dist/guardrail/index.js +7 -7
- package/dist/guardrail/permission-service.js +1 -1
- package/dist/guardrail/serialize.js +1 -1
- package/dist/guardrail/store.js +2 -2
- package/dist/install/lockfile.d.ts +79 -0
- package/dist/install/lockfile.d.ts.map +1 -0
- package/dist/install/lockfile.js +155 -0
- package/dist/install/lockfile.js.map +1 -0
- package/dist/install/store.d.ts +13 -0
- package/dist/install/store.d.ts.map +1 -0
- package/dist/install/store.js +38 -0
- package/dist/install/store.js.map +1 -0
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +6 -1
- package/dist/log.js.map +1 -1
- package/dist/prompts/config.js +2 -2
- package/dist/prompts/host.d.ts +4 -0
- package/dist/prompts/host.d.ts.map +1 -1
- package/dist/prompts/host.js.map +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +13 -6
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/library/defaults.generated.js +2 -2
- package/dist/prompts/library/defaults.generated.js.map +1 -1
- package/dist/prompts/library/index.js +1 -1
- package/dist/providers/contextWindow.d.ts +19 -0
- package/dist/providers/contextWindow.d.ts.map +1 -0
- package/dist/providers/contextWindow.js +68 -0
- package/dist/providers/contextWindow.js.map +1 -0
- package/dist/providers/gateway.d.ts +3 -0
- package/dist/providers/gateway.d.ts.map +1 -1
- package/dist/providers/gateway.js +4 -1
- package/dist/providers/gateway.js.map +1 -1
- package/dist/sessions/apiLeaseStore.d.ts +10 -0
- package/dist/sessions/apiLeaseStore.d.ts.map +1 -0
- package/dist/sessions/apiLeaseStore.js +41 -0
- package/dist/sessions/apiLeaseStore.js.map +1 -0
- package/dist/sessions/blobGc.d.ts +62 -0
- package/dist/sessions/blobGc.d.ts.map +1 -0
- package/dist/sessions/blobGc.js +154 -0
- package/dist/sessions/blobGc.js.map +1 -0
- package/dist/sessions/fileRecallStore.js +1 -1
- package/dist/sessions/fileSessionStore.js +1 -1
- package/dist/sessions/head.d.ts +90 -0
- package/dist/sessions/head.d.ts.map +1 -0
- package/dist/sessions/head.js +82 -0
- package/dist/sessions/head.js.map +1 -0
- package/dist/sessions/inflight.d.ts +58 -0
- package/dist/sessions/inflight.d.ts.map +1 -0
- package/dist/sessions/inflight.js +0 -0
- package/dist/sessions/inflight.js.map +1 -0
- package/dist/sessions/lease.d.ts +59 -0
- package/dist/sessions/lease.d.ts.map +1 -0
- package/dist/sessions/lease.js +115 -0
- package/dist/sessions/lease.js.map +1 -0
- package/dist/sessions/leaseStore.d.ts +46 -0
- package/dist/sessions/leaseStore.d.ts.map +1 -0
- package/dist/sessions/leaseStore.js +58 -0
- package/dist/sessions/leaseStore.js.map +1 -0
- package/dist/sessions/timeline.d.ts +134 -0
- package/dist/sessions/timeline.d.ts.map +1 -0
- package/dist/sessions/timeline.js +127 -0
- package/dist/sessions/timeline.js.map +1 -0
- package/dist/sidecar/host.d.ts +241 -5
- package/dist/sidecar/host.d.ts.map +1 -1
- package/dist/sidecar/host.js +630 -5
- package/dist/sidecar/host.js.map +1 -1
- package/dist/sidecar/server.d.ts +124 -2
- package/dist/sidecar/server.d.ts.map +1 -1
- package/dist/sidecar/server.js +620 -9
- package/dist/sidecar/server.js.map +1 -1
- package/dist/sidecar/wsChannel.d.ts +4 -0
- package/dist/sidecar/wsChannel.d.ts.map +1 -0
- package/dist/sidecar/wsChannel.js +62 -0
- package/dist/sidecar/wsChannel.js.map +1 -0
- package/dist/skills.js +2 -2
- package/dist/snapshot/effects.d.ts +69 -0
- package/dist/snapshot/effects.d.ts.map +1 -0
- package/dist/snapshot/effects.js +67 -0
- package/dist/snapshot/effects.js.map +1 -0
- package/dist/snapshot/manifest.d.ts +73 -0
- package/dist/snapshot/manifest.d.ts.map +1 -0
- package/dist/snapshot/manifest.js +141 -0
- package/dist/snapshot/manifest.js.map +1 -0
- package/dist/snapshot/tree.d.ts +62 -0
- package/dist/snapshot/tree.d.ts.map +1 -0
- package/dist/snapshot/tree.js +147 -0
- package/dist/snapshot/tree.js.map +1 -0
- package/dist/tools/builtins.d.ts.map +1 -1
- package/dist/tools/builtins.js +67 -8
- package/dist/tools/builtins.js.map +1 -1
- package/dist/tools/callAgent.d.ts +16 -0
- package/dist/tools/callAgent.d.ts.map +1 -0
- package/dist/tools/callAgent.js +53 -0
- package/dist/tools/callAgent.js.map +1 -0
- package/dist/tools/files.d.ts +10 -0
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +159 -8
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/http.js +1 -1
- package/dist/tools/namespaces.d.ts +1 -1
- package/dist/tools/namespaces.d.ts.map +1 -1
- package/dist/tools/namespaces.js +40 -2
- package/dist/tools/namespaces.js.map +1 -1
- package/dist/tools/procs.d.ts +18 -0
- package/dist/tools/procs.d.ts.map +1 -0
- package/dist/tools/procs.js +281 -0
- package/dist/tools/procs.js.map +1 -0
- package/dist/tools/todo.d.ts.map +1 -1
- package/dist/tools/todo.js +12 -0
- package/dist/tools/todo.js.map +1 -1
- package/package.json +18 -7
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { LeaseConflict } from './client.js';
|
|
2
|
+
const blank = () => ({
|
|
3
|
+
pushedIndex: 0, lastPushedAt: 0, lastError: '', authoritative: false, epoch: 0,
|
|
4
|
+
});
|
|
5
|
+
export class SessionMirror {
|
|
6
|
+
constructor(deps) {
|
|
7
|
+
Object.defineProperty(this, "deps", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: deps
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "state", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: new Map()
|
|
18
|
+
});
|
|
19
|
+
/** local session id -> the id this backend knows it by. Two namespaces, and
|
|
20
|
+
* assuming they are one is a silent 404 on every push. */
|
|
21
|
+
Object.defineProperty(this, "remoteIds", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: new Map()
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(this, "now", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: void 0
|
|
32
|
+
});
|
|
33
|
+
this.now = deps.now ?? Date.now;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The backend's id for a local session, creating the record if this is the
|
|
37
|
+
* first time it has been mentioned.
|
|
38
|
+
*
|
|
39
|
+
* Idempotent on the server, so a reconnect finds the session it was already
|
|
40
|
+
* pushing to rather than opening a second one beside it and splitting the log.
|
|
41
|
+
*/
|
|
42
|
+
async remoteId(sessionId) {
|
|
43
|
+
const known = this.remoteIds.get(sessionId);
|
|
44
|
+
if (known)
|
|
45
|
+
return known;
|
|
46
|
+
const found = await this.deps.client.findByLocalId(sessionId);
|
|
47
|
+
if (found) {
|
|
48
|
+
this.remoteIds.set(sessionId, found._id);
|
|
49
|
+
return found._id;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const created = await this.deps.client.createSession({ localId: sessionId, location: 'local' });
|
|
53
|
+
this.remoteIds.set(sessionId, created._id);
|
|
54
|
+
return created._id;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
// A SANDBOX credential cannot create sessions, on purpose: the user
|
|
58
|
+
// provisions the session and the credential together, and the machine
|
|
59
|
+
// finds them. Saying that plainly beats reporting the raw 401, which reads
|
|
60
|
+
// like a broken credential rather than a missing session.
|
|
61
|
+
const status = err.status;
|
|
62
|
+
if (status === 401 || status === 403) {
|
|
63
|
+
throw new Error(`no session on the backend for "${sessionId}", and this credential may not create one — `
|
|
64
|
+
+ 'provision the session first, or use a user credential');
|
|
65
|
+
}
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
status(sessionId) {
|
|
70
|
+
return { ...(this.state.get(sessionId) ?? blank()) };
|
|
71
|
+
}
|
|
72
|
+
set(sessionId, patch) {
|
|
73
|
+
const next = { ...(this.state.get(sessionId) ?? blank()), ...patch };
|
|
74
|
+
this.state.set(sessionId, next);
|
|
75
|
+
return { ...next };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Claim authority for this machine.
|
|
79
|
+
*
|
|
80
|
+
* Reads the current epoch and takes the next one. Losing the race is a normal
|
|
81
|
+
* answer, not an error: another machine holds the session, and what this one
|
|
82
|
+
* does about that is a decision for the caller (usually: stop, and offer the
|
|
83
|
+
* user a demote).
|
|
84
|
+
*/
|
|
85
|
+
async claim(sessionId) {
|
|
86
|
+
try {
|
|
87
|
+
const remote = await this.remoteId(sessionId);
|
|
88
|
+
const current = await this.deps.client.getSession(remote);
|
|
89
|
+
const lease = await this.deps.client.acquireLease(remote, current.epoch, this.deps.holder);
|
|
90
|
+
this.deps.log?.(`mirror: took authority for ${sessionId} at epoch ${lease.epoch}`);
|
|
91
|
+
return { ok: true, status: this.set(sessionId, { authoritative: true, epoch: lease.epoch, lastError: '' }) };
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const lost = err instanceof LeaseConflict;
|
|
95
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
96
|
+
this.deps.log?.(`mirror: could not take authority for ${sessionId}: ${message}`);
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
status: this.set(sessionId, {
|
|
100
|
+
authoritative: false,
|
|
101
|
+
...(lost ? { epoch: err.currentEpoch } : {}),
|
|
102
|
+
lastError: message,
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Give authority up, so another machine can take it without waiting for an
|
|
108
|
+
* expiry that does not exist. Best-effort like everything else here. */
|
|
109
|
+
async release(sessionId) {
|
|
110
|
+
const s = this.status(sessionId);
|
|
111
|
+
if (!s.authoritative)
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
const epoch = await this.deps.client.releaseLease(await this.remoteId(sessionId), s.epoch);
|
|
115
|
+
this.set(sessionId, { authoritative: false, epoch });
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
// A failed release is not worth surfacing: the next holder's acquire will
|
|
119
|
+
// supersede this epoch anyway. That is the whole point of a monotonic
|
|
120
|
+
// counter over a flag.
|
|
121
|
+
this.set(sessionId, { authoritative: false, lastError: err instanceof Error ? err.message : String(err) });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Push everything the mirror has not seen.
|
|
126
|
+
*
|
|
127
|
+
* Resumes from the recorded cursor, so an interrupted push costs a retry rather
|
|
128
|
+
* than a re-upload of the whole log. Resolves either way — a caller in the
|
|
129
|
+
* middle of an agent turn must never have to handle this throwing.
|
|
130
|
+
*/
|
|
131
|
+
async push(sessionId) {
|
|
132
|
+
const before = this.status(sessionId);
|
|
133
|
+
if (!before.authoritative) {
|
|
134
|
+
// Pushing without authority would overwrite whichever machine is actually
|
|
135
|
+
// running the session. Refusing is the correct behaviour, not a limitation.
|
|
136
|
+
return { ok: false, pushed: 0, status: this.set(sessionId, { lastError: 'not the authoritative holder' }) };
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const remote = await this.remoteId(sessionId);
|
|
140
|
+
const { entries, nextIndex } = await this.deps.local.entriesSince(sessionId, before.pushedIndex);
|
|
141
|
+
if (entries.length) {
|
|
142
|
+
await this.deps.client.appendTimeline(remote, before.epoch, entries);
|
|
143
|
+
}
|
|
144
|
+
const head = await this.deps.local.head(sessionId);
|
|
145
|
+
if (head)
|
|
146
|
+
await this.deps.client.putHead(remote, before.epoch, head);
|
|
147
|
+
return {
|
|
148
|
+
ok: true,
|
|
149
|
+
pushed: entries.length,
|
|
150
|
+
status: this.set(sessionId, {
|
|
151
|
+
pushedIndex: Math.max(before.pushedIndex, nextIndex),
|
|
152
|
+
lastPushedAt: this.now(),
|
|
153
|
+
lastError: '',
|
|
154
|
+
}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
159
|
+
const lostAuthority = err instanceof LeaseConflict;
|
|
160
|
+
if (lostAuthority) {
|
|
161
|
+
// Someone else took the session. This machine's copy is a stale branch
|
|
162
|
+
// now, and continuing to push would be fighting over a session it no
|
|
163
|
+
// longer holds. Stop, and let the caller decide what to tell the user.
|
|
164
|
+
this.deps.log?.(`mirror: lost authority for ${sessionId}; stopping`);
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
pushed: 0,
|
|
168
|
+
lostAuthority: true,
|
|
169
|
+
status: this.set(sessionId, {
|
|
170
|
+
authoritative: false,
|
|
171
|
+
epoch: err.currentEpoch,
|
|
172
|
+
lastError: 'another machine took this session',
|
|
173
|
+
}),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
this.deps.log?.(`mirror: push failed for ${sessionId}: ${message}`);
|
|
177
|
+
return { ok: false, pushed: 0, status: this.set(sessionId, { lastError: message }) };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Read the mirror.
|
|
182
|
+
*
|
|
183
|
+
* RETURNS the remote state; it does not write anything locally. What to do with
|
|
184
|
+
* a remote copy — restore it, merge it, show it read-only — belongs to whoever
|
|
185
|
+
* owns the local store, and a mirror that silently overwrote local state would
|
|
186
|
+
* have made itself the original.
|
|
187
|
+
*/
|
|
188
|
+
async pull(sessionId, since = 0) {
|
|
189
|
+
try {
|
|
190
|
+
const { entries, nextIndex } = await this.deps.client.readTimeline(await this.remoteId(sessionId), since);
|
|
191
|
+
return { ok: true, entries, nextIndex, error: '' };
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
return { ok: false, entries: [], nextIndex: 0, error: err instanceof Error ? err.message : String(err) };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** Forget local bookkeeping for a session — after a destroy, or when this
|
|
198
|
+
* machine stops caring about it. Does not touch the remote copy. */
|
|
199
|
+
forget(sessionId) {
|
|
200
|
+
this.state.delete(sessionId);
|
|
201
|
+
this.remoteIds.delete(sessionId);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=mirror.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../api/mirror.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA4CzC,MAAM,KAAK,GAAG,GAAiB,EAAE,CAAC,CAAC;IACjC,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;CAC/E,CAAC,CAAC;AAEH,MAAM,OAAO,aAAa;IAOxB,YAA6B,IAAuB;QAAxC;;;;mBAAiB,IAAI;WAAmB;QANnC;;;;mBAAQ,IAAI,GAAG,EAAwB;WAAC;QACzD;kEAC0D;QACzC;;;;mBAAY,IAAI,GAAG,EAAkB;WAAC;QACtC;;;;;WAAkB;QAGjC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,QAAQ,CAAC,SAAiB;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QAExB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO,KAAK,CAAC,GAAG,CAAC;QACnB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAChG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3C,OAAO,OAAO,CAAC,GAAG,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oEAAoE;YACpE,sEAAsE;YACtE,2EAA2E;YAC3E,0DAA0D;YAC1D,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,kCAAkC,SAAS,8CAA8C;sBACvF,uDAAuD,CAC1D,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAiB;QACtB,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAEO,GAAG,CAAC,SAAiB,EAAE,KAA4B;QACzD,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAChC,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC3F,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,8BAA8B,SAAS,aAAa,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QAC/G,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,GAAG,YAAY,aAAa,CAAC;YAC1C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,wCAAwC,SAAS,KAAK,OAAO,EAAE,CAAC,CAAC;YACjF,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE;oBAC1B,aAAa,EAAE,KAAK;oBACpB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAG,GAAqB,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC/D,SAAS,EAAE,OAAO;iBACnB,CAAC;aACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;4EACwE;IACxE,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,CAAC,aAAa;YAAE,OAAO;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3F,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0EAA0E;YAC1E,sEAAsE;YACtE,uBAAuB;YACvB,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,SAAiB;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC1B,0EAA0E;YAC1E,4EAA4E;YAC5E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,8BAA8B,EAAE,CAAC,EAAE,CAAC;QAC9G,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC9C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YACjG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,IAAI;gBAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAErE,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE;oBAC1B,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC;oBACpD,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;oBACxB,SAAS,EAAE,EAAE;iBACd,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,aAAa,GAAG,GAAG,YAAY,aAAa,CAAC;YACnD,IAAI,aAAa,EAAE,CAAC;gBAClB,uEAAuE;gBACvE,qEAAqE;gBACrE,uEAAuE;gBACvE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,8BAA8B,SAAS,YAAY,CAAC,CAAC;gBACrE,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,CAAC;oBACT,aAAa,EAAE,IAAI;oBACnB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE;wBAC1B,aAAa,EAAE,KAAK;wBACpB,KAAK,EAAG,GAAqB,CAAC,YAAY;wBAC1C,SAAS,EAAE,mCAAmC;qBAC/C,CAAC;iBACH,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,2BAA2B,SAAS,KAAK,OAAO,EAAE,CAAC,CAAC;YACpE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACvF,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,KAAK,GAAG,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1G,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3G,CAAC;IACH,CAAC;IAED;wEACoE;IACpE,MAAM,CAAC,SAAiB;QACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { PushResult } from './mirror';
|
|
2
|
+
/** Just enough of SessionMirror to schedule against — so a test needs no client. */
|
|
3
|
+
export interface SchedulableMirror {
|
|
4
|
+
push(sessionId: string): Promise<PushResult>;
|
|
5
|
+
}
|
|
6
|
+
export interface MirrorSchedulerDeps {
|
|
7
|
+
mirror: SchedulableMirror;
|
|
8
|
+
/** Quiet period after the last write before pushing. */
|
|
9
|
+
debounceMs?: number;
|
|
10
|
+
/** How far behind the mirror may fall while writes keep coming. */
|
|
11
|
+
maxWaitMs?: number;
|
|
12
|
+
/** Wait after a failed push before trying again. Doubles, to a cap. */
|
|
13
|
+
retryMs?: number;
|
|
14
|
+
maxRetryMs?: number;
|
|
15
|
+
setTimer?: (fn: () => void, ms: number) => unknown;
|
|
16
|
+
clearTimer?: (handle: unknown) => void;
|
|
17
|
+
now?: () => number;
|
|
18
|
+
log?: (line: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare class MirrorScheduler {
|
|
21
|
+
private readonly deps;
|
|
22
|
+
private readonly pending;
|
|
23
|
+
private readonly cfg;
|
|
24
|
+
private readonly setTimer;
|
|
25
|
+
private readonly clearTimer;
|
|
26
|
+
private readonly now;
|
|
27
|
+
constructor(deps: MirrorSchedulerDeps);
|
|
28
|
+
private slot;
|
|
29
|
+
private disarm;
|
|
30
|
+
/**
|
|
31
|
+
* Work happened; push soon.
|
|
32
|
+
*
|
|
33
|
+
* Cheap and synchronous — this is called from the write path, and the write
|
|
34
|
+
* path must never wait on the mirror.
|
|
35
|
+
*/
|
|
36
|
+
touch(sessionId: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Push now and wait for the result.
|
|
39
|
+
*
|
|
40
|
+
* For pause, handoff and shutdown — the moments where "shortly" is not good
|
|
41
|
+
* enough because the machine may be about to stop being the one that has the
|
|
42
|
+
* session.
|
|
43
|
+
*/
|
|
44
|
+
flush(sessionId: string): Promise<PushResult>;
|
|
45
|
+
/** Flush every session with work outstanding — shutdown, or a demote of the
|
|
46
|
+
* whole machine. Runs them together; one failure does not stop the others. */
|
|
47
|
+
flushAll(): Promise<Record<string, PushResult>>;
|
|
48
|
+
private run;
|
|
49
|
+
/** Whether a push is scheduled or in flight. */
|
|
50
|
+
pending_(sessionId: string): boolean;
|
|
51
|
+
/** Stop scheduling for a session and forget it — a destroy, or a handoff that
|
|
52
|
+
* has already flushed. */
|
|
53
|
+
stop(sessionId: string): void;
|
|
54
|
+
dispose(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=mirrorScheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirrorScheduler.d.ts","sourceRoot":"","sources":["../../api/mirrorScheduler.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,oFAAoF;AACpF,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAgBD,qBAAa,eAAe;IAOd,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEN,IAAI,EAAE,mBAAmB;IAYtD,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,MAAM;IAOd;;;;;OAKG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAqB9B;;;;;;OAMG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAMnD;kFAC8E;IACxE,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAMvC,GAAG;IA2CjB,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAKpC;8BAC0B;IAC1B,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO7B,OAAO,IAAI,IAAI;CAIhB"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const DEFAULTS = { debounceMs: 2000, maxWaitMs: 15000, retryMs: 5000, maxRetryMs: 60000 };
|
|
2
|
+
export class MirrorScheduler {
|
|
3
|
+
constructor(deps) {
|
|
4
|
+
Object.defineProperty(this, "deps", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: deps
|
|
9
|
+
});
|
|
10
|
+
Object.defineProperty(this, "pending", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true,
|
|
14
|
+
value: new Map()
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(this, "cfg", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: void 0
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(this, "setTimer", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
writable: true,
|
|
26
|
+
value: void 0
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(this, "clearTimer", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: void 0
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(this, "now", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true,
|
|
38
|
+
value: void 0
|
|
39
|
+
});
|
|
40
|
+
this.cfg = {
|
|
41
|
+
debounceMs: deps.debounceMs ?? DEFAULTS.debounceMs,
|
|
42
|
+
maxWaitMs: deps.maxWaitMs ?? DEFAULTS.maxWaitMs,
|
|
43
|
+
retryMs: deps.retryMs ?? DEFAULTS.retryMs,
|
|
44
|
+
maxRetryMs: deps.maxRetryMs ?? DEFAULTS.maxRetryMs,
|
|
45
|
+
};
|
|
46
|
+
this.setTimer = deps.setTimer ?? ((fn, ms) => setTimeout(fn, ms));
|
|
47
|
+
this.clearTimer = deps.clearTimer ?? ((h) => clearTimeout(h));
|
|
48
|
+
this.now = deps.now ?? Date.now;
|
|
49
|
+
}
|
|
50
|
+
slot(sessionId) {
|
|
51
|
+
let p = this.pending.get(sessionId);
|
|
52
|
+
if (!p) {
|
|
53
|
+
p = { handle: null, firstDirtyAt: 0, running: false, dirtyAgain: false, retryMs: this.cfg.retryMs, stopped: false };
|
|
54
|
+
this.pending.set(sessionId, p);
|
|
55
|
+
}
|
|
56
|
+
return p;
|
|
57
|
+
}
|
|
58
|
+
disarm(p) {
|
|
59
|
+
if (p.handle !== null) {
|
|
60
|
+
this.clearTimer(p.handle);
|
|
61
|
+
p.handle = null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Work happened; push soon.
|
|
66
|
+
*
|
|
67
|
+
* Cheap and synchronous — this is called from the write path, and the write
|
|
68
|
+
* path must never wait on the mirror.
|
|
69
|
+
*/
|
|
70
|
+
touch(sessionId) {
|
|
71
|
+
const p = this.slot(sessionId);
|
|
72
|
+
if (p.stopped)
|
|
73
|
+
return;
|
|
74
|
+
if (p.running) {
|
|
75
|
+
// Do not overlap pushes for one session: the second would race the first's
|
|
76
|
+
// cursor advance and could re-send or skip entries.
|
|
77
|
+
p.dirtyAgain = true;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!p.firstDirtyAt)
|
|
81
|
+
p.firstDirtyAt = this.now();
|
|
82
|
+
this.disarm(p);
|
|
83
|
+
// The ceiling wins over the quiet period: a busy session must not defer its
|
|
84
|
+
// push forever just because it never goes quiet.
|
|
85
|
+
const elapsed = this.now() - p.firstDirtyAt;
|
|
86
|
+
const wait = Math.max(0, Math.min(this.cfg.debounceMs, this.cfg.maxWaitMs - elapsed));
|
|
87
|
+
p.handle = this.setTimer(() => { void this.run(sessionId); }, wait);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Push now and wait for the result.
|
|
91
|
+
*
|
|
92
|
+
* For pause, handoff and shutdown — the moments where "shortly" is not good
|
|
93
|
+
* enough because the machine may be about to stop being the one that has the
|
|
94
|
+
* session.
|
|
95
|
+
*/
|
|
96
|
+
async flush(sessionId) {
|
|
97
|
+
const p = this.slot(sessionId);
|
|
98
|
+
this.disarm(p);
|
|
99
|
+
return this.run(sessionId, { force: true });
|
|
100
|
+
}
|
|
101
|
+
/** Flush every session with work outstanding — shutdown, or a demote of the
|
|
102
|
+
* whole machine. Runs them together; one failure does not stop the others. */
|
|
103
|
+
async flushAll() {
|
|
104
|
+
const ids = [...this.pending.keys()];
|
|
105
|
+
const results = await Promise.all(ids.map(async (id) => [id, await this.flush(id)]));
|
|
106
|
+
return Object.fromEntries(results);
|
|
107
|
+
}
|
|
108
|
+
async run(sessionId, opts = {}) {
|
|
109
|
+
const p = this.slot(sessionId);
|
|
110
|
+
if (p.stopped && !opts.force) {
|
|
111
|
+
return { ok: false, pushed: 0, status: { pushedIndex: 0, lastPushedAt: 0, lastError: 'stopped', authoritative: false, epoch: 0 } };
|
|
112
|
+
}
|
|
113
|
+
p.running = true;
|
|
114
|
+
this.disarm(p);
|
|
115
|
+
try {
|
|
116
|
+
const result = await this.deps.mirror.push(sessionId);
|
|
117
|
+
if (result.lostAuthority) {
|
|
118
|
+
// Another machine has the session. Stop — do not retry, do not re-arm.
|
|
119
|
+
this.deps.log?.(`mirror: authority lost for ${sessionId}; scheduler stopped`);
|
|
120
|
+
p.stopped = true;
|
|
121
|
+
p.dirtyAgain = false;
|
|
122
|
+
p.firstDirtyAt = 0;
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
if (result.ok) {
|
|
126
|
+
p.retryMs = this.cfg.retryMs;
|
|
127
|
+
p.firstDirtyAt = 0;
|
|
128
|
+
// Work that arrived mid-push has not been sent; schedule another round.
|
|
129
|
+
if (p.dirtyAgain) {
|
|
130
|
+
p.dirtyAgain = false;
|
|
131
|
+
p.running = false;
|
|
132
|
+
this.touch(sessionId);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
// A transient failure. Back off rather than hammering a server that is
|
|
138
|
+
// already unhappy, and keep the dirty state so nothing is dropped.
|
|
139
|
+
p.handle = this.setTimer(() => { void this.run(sessionId); }, p.retryMs);
|
|
140
|
+
p.retryMs = Math.min(p.retryMs * 2, this.cfg.maxRetryMs);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
p.running = false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Whether a push is scheduled or in flight. */
|
|
148
|
+
pending_(sessionId) {
|
|
149
|
+
const p = this.pending.get(sessionId);
|
|
150
|
+
return !!p && (p.handle !== null || p.running || p.dirtyAgain);
|
|
151
|
+
}
|
|
152
|
+
/** Stop scheduling for a session and forget it — a destroy, or a handoff that
|
|
153
|
+
* has already flushed. */
|
|
154
|
+
stop(sessionId) {
|
|
155
|
+
const p = this.pending.get(sessionId);
|
|
156
|
+
if (!p)
|
|
157
|
+
return;
|
|
158
|
+
this.disarm(p);
|
|
159
|
+
this.pending.delete(sessionId);
|
|
160
|
+
}
|
|
161
|
+
dispose() {
|
|
162
|
+
for (const [, p] of this.pending)
|
|
163
|
+
this.disarm(p);
|
|
164
|
+
this.pending.clear();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=mirrorScheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirrorScheduler.js","sourceRoot":"","sources":["../../api/mirrorScheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/compression.d.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import type { CompressionMode, OffloadRef } from '@corenel/protocol';
|
|
2
|
-
export type { CompressionMode, CompressionConfig, OffloadRef } from '@corenel/protocol';
|
|
2
|
+
export type { CompressionMode, CompressionConfig, CompressionStrategy, OffloadRef } from '@corenel/protocol';
|
|
3
3
|
/** How much of an offloaded output to keep inline as a preview. */
|
|
4
4
|
export declare const PREVIEW_BYTES = 800;
|
|
5
5
|
/** Threshold for a given fill ratio (0–1). As the window fills, offload sooner. */
|
|
6
6
|
export declare function effectiveThreshold(mode: CompressionMode, fill?: number): number;
|
|
7
|
+
export declare const OFFLOAD_MARKER_PREFIX = "[offloaded tool result \u00B7 ";
|
|
8
|
+
/** True if `content` is already a formatOffloadRef() pointer — i.e. this
|
|
9
|
+
* result was already offloaded and must not be recorded/rewritten again. */
|
|
10
|
+
export declare function isOffloadPointer(content: string): boolean;
|
|
11
|
+
/** The blob id (and recorded byte count) a formatOffloadRef() pointer carries,
|
|
12
|
+
* for a caller that needs to read the real content back — e.g. a restored
|
|
13
|
+
* transcript row recognizing a persisted pointer as still-offloaded (see
|
|
14
|
+
* @corenel/term's persist.ts). Returns `null` for anything that isn't a
|
|
15
|
+
* pointer, or a pointer whose tail doesn't parse (never thrown on — this can
|
|
16
|
+
* be read back out of a session log written by an older/different format). */
|
|
17
|
+
export declare function parseOffloadPointer(content: string): {
|
|
18
|
+
id: string;
|
|
19
|
+
bytes: number;
|
|
20
|
+
} | null;
|
|
7
21
|
/** The self-describing reference that replaces a large output in the history.
|
|
8
22
|
* Carries enough (tool, size, preview, recall instruction) for the model to
|
|
9
23
|
* decide whether to pull the full content back. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE7G,mEAAmE;AACnE,eAAO,MAAM,aAAa,MAAM,CAAC;AAOjC,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,SAAI,GAAG,MAAM,CAI1E;AAQD,eAAO,MAAM,qBAAqB,mCAA8B,CAAC;AAEjE;4EAC4E;AAC5E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAOD;;;;;8EAK8E;AAC9E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMzF;AAED;;mDAEmD;AACnD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAGxD"}
|
package/dist/compression.js
CHANGED
|
@@ -17,11 +17,42 @@ export function effectiveThreshold(mode, fill = 0) {
|
|
|
17
17
|
const factor = fill < 0.5 ? 1 : fill < 0.7 ? 0.7 : fill < 0.85 ? 0.5 : 0.35;
|
|
18
18
|
return Math.max(FLOOR[mode], Math.round(BASE[mode] * factor));
|
|
19
19
|
}
|
|
20
|
+
// The stable, load-bearing prefix every formatOffloadRef() output starts with.
|
|
21
|
+
// Exported (not just used internally) so any pass that needs to recognize an
|
|
22
|
+
// ALREADY-offloaded message — the deferred strategy's history-compaction pass
|
|
23
|
+
// in loop.ts is the first caller — checks this instead of re-deriving it or
|
|
24
|
+
// loose-matching a substring that could coincidentally appear in real tool
|
|
25
|
+
// output. Keep formatOffloadRef's head in sync with this if either changes.
|
|
26
|
+
export const OFFLOAD_MARKER_PREFIX = '[offloaded tool result · ';
|
|
27
|
+
/** True if `content` is already a formatOffloadRef() pointer — i.e. this
|
|
28
|
+
* result was already offloaded and must not be recorded/rewritten again. */
|
|
29
|
+
export function isOffloadPointer(content) {
|
|
30
|
+
return content.startsWith(OFFLOAD_MARKER_PREFIX);
|
|
31
|
+
}
|
|
32
|
+
// Matches the `{bytes} bytes · recall the full content with recall_result({ id: "{id}" })`
|
|
33
|
+
// tail formatOffloadRef() writes. Kept beside it so there is exactly one place
|
|
34
|
+
// that knows both directions of the pointer format.
|
|
35
|
+
const POINTER_TAIL_RE = /· ([\d,]+) bytes · recall the full content with recall_result\(\{ id: "([^"]+)" \}\)/;
|
|
36
|
+
/** The blob id (and recorded byte count) a formatOffloadRef() pointer carries,
|
|
37
|
+
* for a caller that needs to read the real content back — e.g. a restored
|
|
38
|
+
* transcript row recognizing a persisted pointer as still-offloaded (see
|
|
39
|
+
* @corenel/term's persist.ts). Returns `null` for anything that isn't a
|
|
40
|
+
* pointer, or a pointer whose tail doesn't parse (never thrown on — this can
|
|
41
|
+
* be read back out of a session log written by an older/different format). */
|
|
42
|
+
export function parseOffloadPointer(content) {
|
|
43
|
+
if (!isOffloadPointer(content))
|
|
44
|
+
return null;
|
|
45
|
+
const m = POINTER_TAIL_RE.exec(content);
|
|
46
|
+
if (!m)
|
|
47
|
+
return null;
|
|
48
|
+
const bytes = Number(m[1].replace(/,/g, ''));
|
|
49
|
+
return { id: m[2], bytes: Number.isFinite(bytes) ? bytes : 0 };
|
|
50
|
+
}
|
|
20
51
|
/** The self-describing reference that replaces a large output in the history.
|
|
21
52
|
* Carries enough (tool, size, preview, recall instruction) for the model to
|
|
22
53
|
* decide whether to pull the full content back. */
|
|
23
54
|
export function formatOffloadRef(ref) {
|
|
24
|
-
const head =
|
|
55
|
+
const head = `${OFFLOAD_MARKER_PREFIX}${ref.toolName} · ${ref.bytes.toLocaleString()} bytes · recall the full content with recall_result({ id: "${ref.id}" })]`;
|
|
25
56
|
return ref.preview ? `${head}\n--- preview ---\n${ref.preview}${ref.bytes > ref.preview.length ? '\n…(truncated)' : ''}` : head;
|
|
26
57
|
}
|
|
27
58
|
//# sourceMappingURL=compression.js.map
|
package/dist/compression.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AAAA;;;;;yFAKyF;AAOzF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC,+EAA+E;AAC/E,8BAA8B;AAC9B,MAAM,IAAI,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAM,EAAE,QAAQ,EAAE,KAAM,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAC3H,MAAM,KAAK,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAK,EAAE,QAAQ,EAAE,IAAK,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAE1H,mFAAmF;AACnF,MAAM,UAAU,kBAAkB,CAAC,IAAqB,EAAE,IAAI,GAAG,CAAC;IAChE,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;mDAEmD;AACnD,MAAM,UAAU,gBAAgB,CAAC,GAAe;IAC9C,MAAM,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"compression.js","sourceRoot":"","sources":["../compression.ts"],"names":[],"mappings":"AAAA;;;;;yFAKyF;AAOzF,mEAAmE;AACnE,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC,+EAA+E;AAC/E,8BAA8B;AAC9B,MAAM,IAAI,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAM,EAAE,QAAQ,EAAE,KAAM,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAC3H,MAAM,KAAK,GAAoC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAK,EAAE,QAAQ,EAAE,IAAK,EAAE,UAAU,EAAE,IAAK,EAAE,CAAC;AAE1H,mFAAmF;AACnF,MAAM,UAAU,kBAAkB,CAAC,IAAqB,EAAE,IAAI,GAAG,CAAC;IAChE,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,QAAQ,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,+EAA+E;AAC/E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG,2BAA2B,CAAC;AAEjE;4EAC4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;AACnD,CAAC;AAED,2FAA2F;AAC3F,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,eAAe,GAAG,sFAAsF,CAAC;AAE/G;;;;;8EAK8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;mDAEmD;AACnD,MAAM,UAAU,gBAAgB,CAAC,GAAe;IAC9C,MAAM,IAAI,GAAG,GAAG,qBAAqB,GAAG,GAAG,CAAC,QAAQ,MAAM,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,8DAA8D,GAAG,CAAC,EAAE,OAAO,CAAC;IAChK,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,sBAAsB,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClI,CAAC"}
|
package/dist/core/loop.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface RunAgentArgs {
|
|
|
20
20
|
policy?: Policy;
|
|
21
21
|
/** Per-tool permission resolver. When omitted, tools run without an approval gate. */
|
|
22
22
|
permission?: PermissionService;
|
|
23
|
+
/** Customize the tool-result text a refused tool call gets. The kernel is
|
|
24
|
+
* host-agnostic and cannot know WHY a decision came back "deny" — a real
|
|
25
|
+
* person declining an interactive prompt, and a non-interactive host that
|
|
26
|
+
* has nobody to ask, are both just "deny" by the time they reach here. The
|
|
27
|
+
* default wording ("denied by the user") is only honest for the former;
|
|
28
|
+
* a host that fails closed with no prompt at all (see `run`/`run-agent` in
|
|
29
|
+
* @corenel/cli) should supply this so the model — and whoever reads the
|
|
30
|
+
* transcript — hears the actual cause and the actual remedy, not a claim
|
|
31
|
+
* that a person was asked and said no when nobody was asked anything. */
|
|
32
|
+
describePermissionDenial?: (toolName: string) => string;
|
|
23
33
|
/** Context-compression config (rung-1 offload). Omit to disable. */
|
|
24
34
|
compression?: CompressionConfig;
|
|
25
35
|
/** Intra-run self-healing budget (stream-retry + tool-steer). Omit for defaults. */
|
|
@@ -27,6 +37,8 @@ export interface RunAgentArgs {
|
|
|
27
37
|
/** Optional output-token ceiling forwarded to the model on every turn (reasoning
|
|
28
38
|
* + visible output combined for reasoning models). Omit to leave output unbounded. */
|
|
29
39
|
maxCompletionTokens?: number;
|
|
40
|
+
/** Sampling temperature, already vetted by the caller for model support. */
|
|
41
|
+
temperature?: number;
|
|
30
42
|
signal?: AbortSignal;
|
|
31
43
|
onEvent?: (e: AgentEvent) => void;
|
|
32
44
|
}
|
package/dist/core/loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAA4B,MAAM,mBAAmB,CAAC;AAE7G,OAAO,EACY,KAAK,cAAc,EAErC,MAAM,YAAY,CAAC;AAMpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAA0D,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGhH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;kDAC8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;;;6EAQyE;IACzE,wBAAwB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,oEAAoE;IACpE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,oFAAoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC;0FACsF;IACtF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CA2U1E"}
|