@cursor/july 0.1.1 → 0.1.2
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/AGENTS.md +24 -2
- package/README.md +25 -15
- package/dist/bin/agent-serve.js +101 -12
- package/dist/channels/github/api.d.ts.map +1 -1
- package/dist/channels/github/api.js +31 -14
- package/dist/channels/github/cursor-account.d.ts +43 -0
- package/dist/channels/github/cursor-account.d.ts.map +1 -0
- package/dist/channels/github/cursor-account.js +95 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +46 -9
- package/dist/channels/github/index.d.ts +2 -2
- package/dist/channels/github/index.js +2 -2
- package/dist/channels/github/types.d.ts +17 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.d.ts +8 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +8 -0
- package/dist/channels/slack/types.d.ts +24 -3
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/types.js +15 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +8 -8
- package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
- package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
- package/dist/docs/assets/{app.DqfFEmJd.js → app.Oje4vhlk.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.H5XZ2zCB.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.CTR_TuaE.js} +2 -2
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
- package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
- package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
- package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
- package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
- package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
- package/dist/docs/assets/quickstart.md.CfU8_uTC.js +192 -0
- package/dist/docs/assets/quickstart.md.CfU8_uTC.lean.js +1 -0
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
- package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
- package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/evals.html +7 -7
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/cloud-runtime.html +5 -5
- package/dist/docs/guides/github.html +14 -7
- package/dist/docs/guides/human-in-the-loop.html +6 -6
- package/dist/docs/guides/slack.html +8 -8
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +5 -5
- package/dist/docs/index.html +7 -7
- package/dist/docs/quickstart.html +180 -23
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +8 -8
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +5 -5
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/instructions.html +13 -11
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/subagents.html +6 -6
- package/dist/docs/reference/tools.html +7 -7
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +41 -0
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/cli-deploy.d.ts +52 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -0
- package/dist/internal/cli-deploy.js +731 -0
- package/dist/internal/cursor/backend-client.d.ts +10 -1
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +79 -1
- package/dist/internal/cursor/github-credentials.d.ts +44 -0
- package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
- package/dist/internal/cursor/github-credentials.js +195 -0
- package/dist/internal/deploy-client.d.ts +176 -0
- package/dist/internal/deploy-client.d.ts.map +1 -0
- package/dist/internal/deploy-client.js +375 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +73 -5
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/eval-run-store.d.ts +22 -3
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +37 -19
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
- package/dist/internal/handleAgentServeTrigger.js +10 -12
- package/dist/internal/host-platforms.d.ts +7 -2
- package/dist/internal/host-platforms.d.ts.map +1 -1
- package/dist/internal/host-platforms.js +15 -10
- package/dist/internal/hosting.d.ts +37 -0
- package/dist/internal/hosting.d.ts.map +1 -0
- package/dist/internal/hosting.js +67 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +50 -6
- package/dist/internal/reminder-store.d.ts +2 -0
- package/dist/internal/reminder-store.d.ts.map +1 -1
- package/dist/internal/reminder-store.js +18 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +173 -42
- package/dist/internal/session-engine.d.ts +49 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +246 -17
- package/dist/internal/storage-coordinator.d.ts +139 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -0
- package/dist/internal/storage-coordinator.js +499 -0
- package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
- package/dist/playground/assets/index-B1Qc9h2u.css +1 -0
- package/dist/playground/assets/{index-FlWjhg3x.js → index-CpDYCj8W.js} +42 -42
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +204 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +153 -0
- package/dist/types.d.ts +44 -3
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +3 -2
- package/docs/guides/github.md +43 -8
- package/docs/guides/slack.md +1 -1
- package/docs/quickstart.md +329 -51
- package/docs/reference/instructions.md +8 -6
- package/docs/scaffolding-agents.md +1 -1
- package/docs/storage.md +98 -0
- package/package.json +8 -1
- package/skills/github/SKILL.md +9 -1
- package/src/bin/agent-serve.ts +139 -0
- package/src/channels/github/api.ts +42 -23
- package/src/channels/github/cursor-account.ts +165 -0
- package/src/channels/github/github-channel.ts +66 -6
- package/src/channels/github/index.ts +2 -2
- package/src/channels/github/types.ts +19 -0
- package/src/channels/slack/slack-channel.ts +17 -3
- package/src/channels/slack/types.ts +44 -3
- package/src/index.ts +13 -0
- package/src/internal/cli-deploy.ts +940 -0
- package/src/internal/cursor/backend-client.ts +103 -1
- package/src/internal/cursor/github-credentials.ts +248 -0
- package/src/internal/deploy-client.ts +591 -0
- package/src/internal/discovery.ts +88 -1
- package/src/internal/distribution.ts +1 -0
- package/src/internal/eval-run-store.ts +48 -19
- package/src/internal/handleAgentServeTrigger.ts +10 -12
- package/src/internal/host-platforms.ts +28 -11
- package/src/internal/hosting.ts +77 -0
- package/src/internal/reminder-runner.ts +50 -6
- package/src/internal/reminder-store.ts +21 -0
- package/src/internal/server.ts +213 -27
- package/src/internal/session-engine.ts +285 -7
- package/src/internal/storage-coordinator.ts +615 -0
- package/src/storage.ts +325 -0
- package/src/types.ts +40 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
- package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
- package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
- package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
- package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
- package/dist/playground/assets/index-1K-hG-7p.css +0 -1
- /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
|
@@ -26,8 +26,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
26
26
|
}
|
|
27
27
|
return t;
|
|
28
28
|
};
|
|
29
|
-
import { mkdir, rm } from "node:fs/promises";
|
|
30
|
-
import { join } from "node:path";
|
|
29
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
30
|
+
import { dirname, join } from "node:path";
|
|
31
31
|
import { mergeABInstructions, resolveABMaxPlaygroundSessions, resolveABSplit, } from "../ab.js";
|
|
32
32
|
import { slackThreadPermalink } from "../channels/slack/links.js";
|
|
33
33
|
import { DIRECT_TOOL_CALL_CHANNEL_ID, isSymbolicConnectionTransport, } from "../types.js";
|
|
@@ -45,6 +45,7 @@ import { validateToolInput } from "./json-schema.js";
|
|
|
45
45
|
import { McpHost } from "./mcp-host.js";
|
|
46
46
|
import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
|
|
47
47
|
import { SessionStore } from "./session-store.js";
|
|
48
|
+
import { StorageCoordinator } from "./storage-coordinator.js";
|
|
48
49
|
import { normalizeToolResult, toolCallErrorMessage } from "./tool-result.js";
|
|
49
50
|
import { buildAgentToolsCatalog, materializeWorkspace, writeWorkspaceFiles, } from "./workspace.js";
|
|
50
51
|
export const HTTP_CHANNEL_ID = "http";
|
|
@@ -106,8 +107,10 @@ export class ApprovalInterruptedError extends Error {
|
|
|
106
107
|
}
|
|
107
108
|
export class SessionEngine {
|
|
108
109
|
constructor(options) {
|
|
109
|
-
var _a;
|
|
110
|
-
var
|
|
110
|
+
var _a, _b;
|
|
111
|
+
var _c, _d, _e;
|
|
112
|
+
/** In-flight lazy restores, deduped per channel + continuation key. */
|
|
113
|
+
this.restoreInFlight = new Map();
|
|
111
114
|
this.channelsById = new Map();
|
|
112
115
|
/** Sessions with a turn being admitted (before the run promise exists). */
|
|
113
116
|
this.pendingTurns = new Set();
|
|
@@ -126,17 +129,29 @@ export class SessionEngine {
|
|
|
126
129
|
this.project = options.project;
|
|
127
130
|
this.stateRoot = options.stateRoot;
|
|
128
131
|
this.runner = options.runner;
|
|
129
|
-
this.logger = (
|
|
132
|
+
this.logger = (_c = options.logger) !== null && _c !== void 0 ? _c : (() => { });
|
|
130
133
|
this.sessions = new SessionStore(join(options.stateRoot, "sessions"));
|
|
131
134
|
this.logs = new EventLogStore((sessionId) => this.sessions.eventFilePath(sessionId), (sessionId, error) => this.logger(`[agent-serve] failed to persist events for ${sessionId}: ${describeError(error)}`));
|
|
132
|
-
this.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
+
this.storage =
|
|
136
|
+
options.project.storage === undefined
|
|
137
|
+
? undefined
|
|
138
|
+
: new StorageCoordinator({
|
|
139
|
+
definition: options.project.storage,
|
|
140
|
+
agentName: options.project.name,
|
|
141
|
+
projectRoot: options.project.rootDir,
|
|
142
|
+
logger: this.logger,
|
|
143
|
+
});
|
|
144
|
+
// Domain-specific hooks win; the defineStorage sink is the fallback.
|
|
145
|
+
const persistSamples = (_d = (_a = options.project.abConfig) === null || _a === void 0 ? void 0 : _a.persistSamples) !== null && _d !== void 0 ? _d : (_b = this.storage) === null || _b === void 0 ? void 0 : _b.asABSamplePersistence();
|
|
146
|
+
this.abCollector = new ABCollector(options.project.abs, this.logger, (sessionId) => __awaiter(this, void 0, void 0, function* () { return (yield this.logs.get(sessionId)).snapshot(0); }), {
|
|
147
|
+
projectRoot: options.project.rootDir,
|
|
148
|
+
persistSamples,
|
|
149
|
+
});
|
|
135
150
|
// Peer and Cursor-account transports are symbolic until the serve host
|
|
136
151
|
// resolves them; the host-side MCP registry starts with the concrete
|
|
137
152
|
// connections and gains the rest via setResolvedConnections.
|
|
138
153
|
this.mcpHost = new McpHost(options.project.agent.connections.filter((connection) => !isSymbolicConnectionTransport(connection.transport)));
|
|
139
|
-
this.platforms = createHostPlatforms();
|
|
154
|
+
this.platforms = (_e = options.platforms) !== null && _e !== void 0 ? _e : createHostPlatforms();
|
|
140
155
|
for (const channel of options.project.channels) {
|
|
141
156
|
this.channelsById.set(channel.id, channel.definition);
|
|
142
157
|
}
|
|
@@ -181,11 +196,17 @@ export class SessionEngine {
|
|
|
181
196
|
*/
|
|
182
197
|
send(channelId_1, message_1) {
|
|
183
198
|
return __awaiter(this, arguments, void 0, function* (channelId, message, options = {}) {
|
|
184
|
-
var _a
|
|
185
|
-
|
|
186
|
-
const
|
|
199
|
+
var _a;
|
|
200
|
+
var _b, _c, _d;
|
|
201
|
+
const auth = (_b = options.auth) !== null && _b !== void 0 ? _b : null;
|
|
202
|
+
let existing = options.continuationToken === undefined
|
|
187
203
|
? undefined
|
|
188
204
|
: yield this.sessions.findByContinuation(channelId, options.continuationToken);
|
|
205
|
+
if (existing === undefined && options.continuationToken !== undefined) {
|
|
206
|
+
// Local miss: the session may live only in the storage sink (it
|
|
207
|
+
// fell outside the startup restore window, or restore is lazy-only).
|
|
208
|
+
existing = yield this.restoreSessionByContinuation(channelId, options.continuationToken);
|
|
209
|
+
}
|
|
189
210
|
if (existing !== undefined) {
|
|
190
211
|
if (!samePrincipal(existing.auth, auth)) {
|
|
191
212
|
throw new SessionAuthError(existing.sessionId);
|
|
@@ -209,9 +230,9 @@ export class SessionEngine {
|
|
|
209
230
|
let record = {
|
|
210
231
|
sessionId: newSessionId(),
|
|
211
232
|
channelId,
|
|
212
|
-
mode: (
|
|
233
|
+
mode: (_c = options.mode) !== null && _c !== void 0 ? _c : "chat",
|
|
213
234
|
purpose,
|
|
214
|
-
continuationKey: (
|
|
235
|
+
continuationKey: (_d = options.continuationToken) !== null && _d !== void 0 ? _d : newContinuationKey(),
|
|
215
236
|
auth,
|
|
216
237
|
title: options.title,
|
|
217
238
|
channelState,
|
|
@@ -224,6 +245,7 @@ export class SessionEngine {
|
|
|
224
245
|
updatedAt: now,
|
|
225
246
|
};
|
|
226
247
|
yield this.sessions.save(record);
|
|
248
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.sessionRecord(record);
|
|
227
249
|
yield this.appendEvent(record.sessionId, {
|
|
228
250
|
type: "session.started",
|
|
229
251
|
data: { channelId },
|
|
@@ -996,11 +1018,22 @@ export class SessionEngine {
|
|
|
996
1018
|
}
|
|
997
1019
|
queueDispatch(sessionId, event) {
|
|
998
1020
|
var _a;
|
|
999
|
-
|
|
1021
|
+
var _b;
|
|
1022
|
+
// Single funnel for both append paths (appendEvent + the held-log emit),
|
|
1023
|
+
// so the storage sink sees every durable event exactly once.
|
|
1024
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.event(event);
|
|
1025
|
+
const chain = (_b = this.dispatchChains.get(sessionId)) !== null && _b !== void 0 ? _b : Promise.resolve();
|
|
1000
1026
|
const next = chain
|
|
1001
1027
|
.then(() => this.dispatchEvent(sessionId, event))
|
|
1002
1028
|
.catch((error) => {
|
|
1003
1029
|
this.logger(`[agent-serve] event dispatch failed for ${sessionId}: ${describeError(error)}`);
|
|
1030
|
+
})
|
|
1031
|
+
.then(() => {
|
|
1032
|
+
var _a;
|
|
1033
|
+
// Turn-end flush happens here — after the boundary event's handlers
|
|
1034
|
+
// and their record updates settled — so the persisted record carries
|
|
1035
|
+
// the turn's final channel state and continuation token.
|
|
1036
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.eventDispatched(event);
|
|
1004
1037
|
});
|
|
1005
1038
|
this.dispatchChains.set(sessionId, next);
|
|
1006
1039
|
}
|
|
@@ -1127,10 +1160,29 @@ export class SessionEngine {
|
|
|
1127
1160
|
*/
|
|
1128
1161
|
abSnapshot(caller, options) {
|
|
1129
1162
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1163
|
+
var _a;
|
|
1164
|
+
var _b;
|
|
1130
1165
|
const sessions = yield this.listSessions(caller, options);
|
|
1131
1166
|
const abConfig = this.project.abConfig;
|
|
1132
1167
|
const maxPlaygroundSessions = resolveABMaxPlaygroundSessions(abConfig === null || abConfig === void 0 ? void 0 : abConfig.maxPlaygroundSessions);
|
|
1133
1168
|
const foldedSessions = sessions.slice(0, maxPlaygroundSessions);
|
|
1169
|
+
// Backfill for a replacement host with nothing local to fold (e.g.
|
|
1170
|
+
// lazy-only restore before any session resumed): serve the persisted
|
|
1171
|
+
// aggregate instead of an empty surface. Gated on the host having no
|
|
1172
|
+
// sessions AT ALL — the persisted snapshot spans every principal, so a
|
|
1173
|
+
// caller who merely owns no sessions must not see it. Loaded once per
|
|
1174
|
+
// process (playground polls this route ~every 4s); skip the persist
|
|
1175
|
+
// side effect below — re-saving a restored snapshot would echo stale
|
|
1176
|
+
// data back into the store.
|
|
1177
|
+
if (foldedSessions.length === 0 &&
|
|
1178
|
+
this.storage !== undefined &&
|
|
1179
|
+
(yield this.sessions.list()).length === 0) {
|
|
1180
|
+
(_b = this.restoredAbSnapshot) !== null && _b !== void 0 ? _b : (this.restoredAbSnapshot = this.storage.getLatestAbSnapshot());
|
|
1181
|
+
const restoredSnapshot = yield this.restoredAbSnapshot;
|
|
1182
|
+
if (restoredSnapshot !== undefined) {
|
|
1183
|
+
return restoredSnapshot;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1134
1186
|
const snapshot = yield buildABSnapshot({
|
|
1135
1187
|
experiments: this.project.abs,
|
|
1136
1188
|
agentName: this.project.name,
|
|
@@ -1158,6 +1210,10 @@ export class SessionEngine {
|
|
|
1158
1210
|
this.logger(`[agent-serve] ab persistSnapshots.save threw: ${describeError(error)}`);
|
|
1159
1211
|
}
|
|
1160
1212
|
}
|
|
1213
|
+
else {
|
|
1214
|
+
// defineStorage fallback (throttled inside the coordinator).
|
|
1215
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.abSnapshot(snapshot);
|
|
1216
|
+
}
|
|
1161
1217
|
return snapshot;
|
|
1162
1218
|
});
|
|
1163
1219
|
}
|
|
@@ -1275,12 +1331,14 @@ export class SessionEngine {
|
|
|
1275
1331
|
var _a;
|
|
1276
1332
|
const chain = (_a = this.updateChains.get(sessionId)) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
1277
1333
|
const next = chain.then(() => __awaiter(this, void 0, void 0, function* () {
|
|
1334
|
+
var _a;
|
|
1278
1335
|
const current = yield this.sessions.get(sessionId);
|
|
1279
1336
|
if (current === undefined) {
|
|
1280
1337
|
throw new Error(`Session ${sessionId} not found`);
|
|
1281
1338
|
}
|
|
1282
1339
|
const updated = Object.assign(Object.assign({}, updater(current)), { updatedAt: new Date().toISOString() });
|
|
1283
1340
|
yield this.sessions.save(updated);
|
|
1341
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.sessionRecord(updated);
|
|
1284
1342
|
return updated;
|
|
1285
1343
|
}));
|
|
1286
1344
|
this.updateChains.set(sessionId, next.catch(() => { }));
|
|
@@ -1289,6 +1347,167 @@ export class SessionEngine {
|
|
|
1289
1347
|
// ==========================================================================
|
|
1290
1348
|
// Lifecycle
|
|
1291
1349
|
// ==========================================================================
|
|
1350
|
+
/**
|
|
1351
|
+
* Restore sessions from the authored storage sink. Called once at
|
|
1352
|
+
* serve start, before channels accept traffic: any persisted session
|
|
1353
|
+
* missing from the local `--state-root` is materialized there — events
|
|
1354
|
+
* as `events.ndjson`, record as `session.json` — after which every
|
|
1355
|
+
* existing read path (continuation lookup, event replay/streams, A/B
|
|
1356
|
+
* fold hydration) works unchanged. Local state always wins over the
|
|
1357
|
+
* sink, so restarts on the same host are no-ops.
|
|
1358
|
+
*
|
|
1359
|
+
* Failures are logged and skipped; a broken store (including rows that
|
|
1360
|
+
* violate the SessionRecord shape) never blocks serve start.
|
|
1361
|
+
*/
|
|
1362
|
+
restoreStoredSessions() {
|
|
1363
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1364
|
+
const storage = this.storage;
|
|
1365
|
+
if (storage === undefined || !storage.canBulkRestore) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
const policy = storage.policy.restore;
|
|
1369
|
+
if (policy === "off") {
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
try {
|
|
1373
|
+
yield this.runBulkRestore(storage, policy);
|
|
1374
|
+
}
|
|
1375
|
+
catch (error) {
|
|
1376
|
+
this.logger(`[agent-serve] session restore failed: ${describeError(error)}`);
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
runBulkRestore(storage, policy) {
|
|
1381
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1382
|
+
const loaded = yield storage.listSessions();
|
|
1383
|
+
// Guardrails on whatever the sink returned: drop invalid rows and
|
|
1384
|
+
// sessions older than the age window, then restore newest-first under
|
|
1385
|
+
// the count cap. Anything filtered out here stays reachable through
|
|
1386
|
+
// the lazy continuation-lookup path.
|
|
1387
|
+
const cutoff = Date.now() - policy.maxAgeMs;
|
|
1388
|
+
const candidates = loaded
|
|
1389
|
+
.map((record) => ({
|
|
1390
|
+
record,
|
|
1391
|
+
// Numeric timestamp for both the age filter and the sort; a
|
|
1392
|
+
// non-string updatedAt (e.g. a raw DB Date from an untyped sink)
|
|
1393
|
+
// parses to NaN and is dropped instead of crashing serve start.
|
|
1394
|
+
updatedAt: typeof (record === null || record === void 0 ? void 0 : record.updatedAt) === "string"
|
|
1395
|
+
? Date.parse(record.updatedAt)
|
|
1396
|
+
: Number.NaN,
|
|
1397
|
+
}))
|
|
1398
|
+
.filter(({ record, updatedAt }) => typeof (record === null || record === void 0 ? void 0 : record.sessionId) === "string" &&
|
|
1399
|
+
record.sessionId !== "" &&
|
|
1400
|
+
updatedAt >= cutoff)
|
|
1401
|
+
.sort((a, b) => b.updatedAt - a.updatedAt)
|
|
1402
|
+
.slice(0, policy.maxSessions)
|
|
1403
|
+
.map(({ record }) => record);
|
|
1404
|
+
let restored = 0;
|
|
1405
|
+
let budget = policy.maxTotalBytes;
|
|
1406
|
+
// Sink round trips dominate restore latency, so event streams are
|
|
1407
|
+
// fetched with bounded parallelism; writes stay sequential, newest
|
|
1408
|
+
// first, so the byte budget is enforced deterministically.
|
|
1409
|
+
outer: for (let i = 0; i < candidates.length; i += RESTORE_FETCH_CONCURRENCY) {
|
|
1410
|
+
const chunk = candidates.slice(i, i + RESTORE_FETCH_CONCURRENCY);
|
|
1411
|
+
const fetched = yield Promise.all(chunk.map((record) => __awaiter(this, void 0, void 0, function* () {
|
|
1412
|
+
try {
|
|
1413
|
+
// Local state always wins over the sink.
|
|
1414
|
+
if ((yield this.sessions.get(record.sessionId)) !== undefined) {
|
|
1415
|
+
return undefined;
|
|
1416
|
+
}
|
|
1417
|
+
const events = yield storage.listSessionEvents(record.sessionId);
|
|
1418
|
+
return { record, events };
|
|
1419
|
+
}
|
|
1420
|
+
catch (error) {
|
|
1421
|
+
this.logger(`[agent-serve] failed to restore session ${record.sessionId}: ${describeError(error)}`);
|
|
1422
|
+
return undefined;
|
|
1423
|
+
}
|
|
1424
|
+
})));
|
|
1425
|
+
for (const item of fetched) {
|
|
1426
|
+
if (item === undefined) {
|
|
1427
|
+
continue;
|
|
1428
|
+
}
|
|
1429
|
+
const ndjson = eventsNdjson(item.events);
|
|
1430
|
+
// Budget is checked BEFORE anything is written: one oversized
|
|
1431
|
+
// session cannot blow past maxTotalBytes on disk. Skipped sessions
|
|
1432
|
+
// stay reachable through the lazy path.
|
|
1433
|
+
const bytes = Buffer.byteLength(JSON.stringify(item.record), "utf8") +
|
|
1434
|
+
(ndjson === undefined ? 0 : Buffer.byteLength(ndjson, "utf8"));
|
|
1435
|
+
if (bytes > budget) {
|
|
1436
|
+
this.logger(`[agent-serve] session restore stopped at the ${policy.maxTotalBytes}-byte budget after ${restored} session(s); remaining sessions restore lazily on resume`);
|
|
1437
|
+
break outer;
|
|
1438
|
+
}
|
|
1439
|
+
try {
|
|
1440
|
+
yield this.materializeSession(item.record, ndjson);
|
|
1441
|
+
budget -= bytes;
|
|
1442
|
+
restored += 1;
|
|
1443
|
+
}
|
|
1444
|
+
catch (error) {
|
|
1445
|
+
this.logger(`[agent-serve] failed to restore session ${item.record.sessionId}: ${describeError(error)}`);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
if (restored > 0) {
|
|
1450
|
+
this.logger(`[agent-serve] restored ${restored} session(s) from storage`);
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Lazy restore: a continuation lookup missed locally, so ask the sink
|
|
1456
|
+
* for that one session and materialize it before resuming. Disk grows
|
|
1457
|
+
* with sessions that are actually resumed, not with history.
|
|
1458
|
+
*
|
|
1459
|
+
* Concurrent misses for the same key (webhook redeliveries, retries)
|
|
1460
|
+
* share one in-flight restore — a second materialization racing the
|
|
1461
|
+
* first resumed turn could truncate events the turn already appended.
|
|
1462
|
+
* Sink errors propagate and fail the send (see
|
|
1463
|
+
* {@link StorageCoordinator.getSessionByContinuation}).
|
|
1464
|
+
*/
|
|
1465
|
+
restoreSessionByContinuation(channelId, continuationKey) {
|
|
1466
|
+
const storage = this.storage;
|
|
1467
|
+
if (storage === undefined) {
|
|
1468
|
+
return Promise.resolve(undefined);
|
|
1469
|
+
}
|
|
1470
|
+
const key = `${channelId}\u0000${continuationKey}`;
|
|
1471
|
+
let pending = this.restoreInFlight.get(key);
|
|
1472
|
+
if (pending === undefined) {
|
|
1473
|
+
pending = this.loadAndMaterializeByContinuation(storage, channelId, continuationKey).finally(() => this.restoreInFlight.delete(key));
|
|
1474
|
+
this.restoreInFlight.set(key, pending);
|
|
1475
|
+
}
|
|
1476
|
+
return pending;
|
|
1477
|
+
}
|
|
1478
|
+
loadAndMaterializeByContinuation(storage, channelId, continuationKey) {
|
|
1479
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1480
|
+
const record = yield storage.getSessionByContinuation(channelId, continuationKey);
|
|
1481
|
+
if (record === undefined) {
|
|
1482
|
+
// Definitive miss: the caller starts a fresh session under this token.
|
|
1483
|
+
return undefined;
|
|
1484
|
+
}
|
|
1485
|
+
const local = yield this.sessions.get(record.sessionId);
|
|
1486
|
+
if (local !== undefined) {
|
|
1487
|
+
return local;
|
|
1488
|
+
}
|
|
1489
|
+
const events = yield storage.listSessionEvents(record.sessionId);
|
|
1490
|
+
yield this.materializeSession(record, eventsNdjson(events));
|
|
1491
|
+
this.logger(`[agent-serve] lazily restored session ${record.sessionId} from storage`);
|
|
1492
|
+
return record;
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
/**
|
|
1496
|
+
* Write one restored session to the local state root. Events land on
|
|
1497
|
+
* disk before the record: a session becomes visible (and addressable via
|
|
1498
|
+
* its continuation key) only with its full stream in place, and the
|
|
1499
|
+
* lazily opened event log hydrates from this file.
|
|
1500
|
+
*/
|
|
1501
|
+
materializeSession(record, eventsNdjson) {
|
|
1502
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1503
|
+
if (eventsNdjson !== undefined) {
|
|
1504
|
+
const filePath = this.sessions.eventFilePath(record.sessionId);
|
|
1505
|
+
yield mkdir(dirname(filePath), { recursive: true });
|
|
1506
|
+
yield writeFile(filePath, eventsNdjson, "utf8");
|
|
1507
|
+
}
|
|
1508
|
+
yield this.sessions.save(record);
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1292
1511
|
trackBackground(promise) {
|
|
1293
1512
|
this.backgroundWork.add(promise);
|
|
1294
1513
|
void promise
|
|
@@ -1300,18 +1519,28 @@ export class SessionEngine {
|
|
|
1300
1519
|
/** Drain running turns, dispatches, and pending writes, then dispose. */
|
|
1301
1520
|
close() {
|
|
1302
1521
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1303
|
-
var _a, _b;
|
|
1522
|
+
var _a, _b, _c;
|
|
1304
1523
|
this.approvals.cancelAll("deny");
|
|
1305
1524
|
yield Promise.allSettled([...this.activeTurns.values()]);
|
|
1306
1525
|
yield Promise.allSettled([...this.backgroundWork]);
|
|
1307
1526
|
yield Promise.allSettled([...this.dispatchChains.values()]);
|
|
1308
1527
|
yield Promise.allSettled([...this.updateChains.values()]);
|
|
1309
1528
|
yield this.logs.flushAll();
|
|
1529
|
+
yield (_a = this.storage) === null || _a === void 0 ? void 0 : _a.close();
|
|
1310
1530
|
yield this.mcpHost.close();
|
|
1311
|
-
yield (
|
|
1531
|
+
yield (_c = (_b = this.runner).dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
1312
1532
|
});
|
|
1313
1533
|
}
|
|
1314
1534
|
}
|
|
1535
|
+
/** Parallel event-stream loads during the startup bulk restore. */
|
|
1536
|
+
const RESTORE_FETCH_CONCURRENCY = 8;
|
|
1537
|
+
/** NDJSON payload for a restored event stream; undefined when empty. */
|
|
1538
|
+
function eventsNdjson(events) {
|
|
1539
|
+
if (events.length === 0) {
|
|
1540
|
+
return undefined;
|
|
1541
|
+
}
|
|
1542
|
+
return `${events.map((event) => JSON.stringify(event)).join("\n")}\n`;
|
|
1543
|
+
}
|
|
1315
1544
|
function subagentPrompt(subagent) {
|
|
1316
1545
|
var _a;
|
|
1317
1546
|
if (subagent.instructions !== undefined && subagent.instructions !== "") {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime for `defineStorage` (`agent/storage.ts`).
|
|
3
|
+
*
|
|
4
|
+
* The coordinator is the single funnel between the engine's hot paths and
|
|
5
|
+
* the author's key-value sink. The sink is four functions (`put` / `get` /
|
|
6
|
+
* `delete` / `list`); the coordinator owns everything else: it mints every
|
|
7
|
+
* key from the versioned scheme ({@link storageKeys}), coalesces
|
|
8
|
+
* session records and batches event chunks per turn (or debounce window),
|
|
9
|
+
* serializes delivery on one bounded queue per agent, and isolates
|
|
10
|
+
* failures — a throwing sink is logged and its write dropped; storage
|
|
11
|
+
* must never stall or fail a turn.
|
|
12
|
+
*
|
|
13
|
+
* Scaling shape: sessions, reminders, evals, and A/Bs all reduce to keyed
|
|
14
|
+
* puts on the same queue, so one author-owned sink covers every domain,
|
|
15
|
+
* and new domains are new key prefixes — not new config surface.
|
|
16
|
+
*/
|
|
17
|
+
import type { ABSamplePersistence } from "../ab.js";
|
|
18
|
+
import type { EvalRunPersistence } from "../evals.js";
|
|
19
|
+
import { type ResolvedStoragePolicy, type StorageContext, type StorageDefinition } from "../storage.js";
|
|
20
|
+
import type { SessionEvent, SessionRecord } from "../types.js";
|
|
21
|
+
import type { ABSnapshot } from "./ab-snapshot.js";
|
|
22
|
+
import { type ReminderRecord } from "./reminder-store.js";
|
|
23
|
+
export interface StorageCoordinatorOptions {
|
|
24
|
+
definition: StorageDefinition;
|
|
25
|
+
agentName: string;
|
|
26
|
+
projectRoot: string;
|
|
27
|
+
logger: (line: string) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare class StorageCoordinator {
|
|
30
|
+
readonly policy: ResolvedStoragePolicy;
|
|
31
|
+
private readonly definition;
|
|
32
|
+
private readonly agentName;
|
|
33
|
+
private readonly projectRoot;
|
|
34
|
+
private readonly logger;
|
|
35
|
+
/** Per-session pending state (events + coalesced record). */
|
|
36
|
+
private readonly buffers;
|
|
37
|
+
/**
|
|
38
|
+
* Last continuation key written to the sink per session, so a token
|
|
39
|
+
* change emits a delete for the stale index entry alongside the new put.
|
|
40
|
+
*/
|
|
41
|
+
private readonly continuationIndex;
|
|
42
|
+
/** Single delivery chain: writes reach the sink serialized, in order. */
|
|
43
|
+
private queue;
|
|
44
|
+
/** Ops on the queue not yet delivered (bounded by MAX_PENDING_OPS). */
|
|
45
|
+
private pending;
|
|
46
|
+
/** Ops dropped because the queue was full. */
|
|
47
|
+
private dropped;
|
|
48
|
+
private lastAbSnapshotAt;
|
|
49
|
+
private closed;
|
|
50
|
+
constructor(options: StorageCoordinatorOptions);
|
|
51
|
+
/** Durable session-record update (engine calls after every store save). */
|
|
52
|
+
sessionRecord(record: SessionRecord): void;
|
|
53
|
+
/** One appended session event (engine calls from its dispatch funnel). */
|
|
54
|
+
event(event: SessionEvent): void;
|
|
55
|
+
/**
|
|
56
|
+
* A boundary event's dispatch settled: channel/hook handlers ran and
|
|
57
|
+
* their record updates (channel state, continuation tokens) are
|
|
58
|
+
* buffered. This — not the append — is the turn-end flush point, so the
|
|
59
|
+
* persisted session record includes the boundary event's own handler
|
|
60
|
+
* mutations. Debounced batching intentionally ignores boundaries.
|
|
61
|
+
*/
|
|
62
|
+
eventDispatched(event: SessionEvent): void;
|
|
63
|
+
/** Flush everything buffered for one session (ordered: events, record). */
|
|
64
|
+
flushSession(sessionId: string, reason?: StorageContext["reason"]): void;
|
|
65
|
+
/**
|
|
66
|
+
* Index maintenance for `continuation/{channelId}/{token}` → sessionId:
|
|
67
|
+
* put the current token, delete the previous one when it changed.
|
|
68
|
+
*/
|
|
69
|
+
private continuationOps;
|
|
70
|
+
/** Whether the sink can serve the startup bulk restore (`list`). */
|
|
71
|
+
get canBulkRestore(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Saved session records for this agent (startup restore). Errors are
|
|
74
|
+
* logged and read as "nothing saved" — a broken store must never block
|
|
75
|
+
* serve start.
|
|
76
|
+
*/
|
|
77
|
+
listSessions(): Promise<SessionRecord[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Saved event stream for one session: chunk values concatenated in key
|
|
80
|
+
* order (chunks are keyed by their first event's index, zero-padded, so
|
|
81
|
+
* ascending key order is append order). Errors read as an empty stream.
|
|
82
|
+
*/
|
|
83
|
+
listSessionEvents(sessionId: string): Promise<SessionEvent[]>;
|
|
84
|
+
/**
|
|
85
|
+
* One saved session by channel continuation key (lazy restore). Unlike
|
|
86
|
+
* the startup reads, sink errors **propagate**: a failing store must
|
|
87
|
+
* fail the follow-up (which the caller can retry) rather than read as
|
|
88
|
+
* "unknown token" — that would mint a new session under the same
|
|
89
|
+
* continuation key and permanently shadow the real one on this host.
|
|
90
|
+
* A definitive miss (no index entry, or a write-only sink without
|
|
91
|
+
* `get`) resolves undefined.
|
|
92
|
+
*/
|
|
93
|
+
getSessionByContinuation(channelId: string, continuationKey: string): Promise<SessionRecord | undefined>;
|
|
94
|
+
/**
|
|
95
|
+
* Mirror one reminder record (create / fire / cancel / disarm). Local
|
|
96
|
+
* disk under `--state-root/reminders` remains the live source of truth;
|
|
97
|
+
* this is the durable copy for host replacement.
|
|
98
|
+
*/
|
|
99
|
+
reminder(record: ReminderRecord): void;
|
|
100
|
+
/**
|
|
101
|
+
* Saved reminder records for this agent (startup hydrate into local
|
|
102
|
+
* disk). Errors read as empty — same posture as session bulk restore.
|
|
103
|
+
*/
|
|
104
|
+
listReminders(): Promise<ReminderRecord[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Adapter for {@link EvalRunPersistence} so the playground eval store
|
|
107
|
+
* can fall back to this sink when `evals.config.ts` sets no
|
|
108
|
+
* `persistRuns`.
|
|
109
|
+
*/
|
|
110
|
+
asEvalRunPersistence(): EvalRunPersistence;
|
|
111
|
+
/**
|
|
112
|
+
* Adapter for {@link ABSamplePersistence} so the AB collector can fall
|
|
113
|
+
* back to this sink when `ab.config.ts` sets no `persistSamples`.
|
|
114
|
+
*/
|
|
115
|
+
asABSamplePersistence(): ABSamplePersistence;
|
|
116
|
+
/**
|
|
117
|
+
* Refresh the persisted aggregate A/B snapshot, throttled to once per
|
|
118
|
+
* {@link AB_SNAPSHOT_MIN_INTERVAL_MS} (the playground recomputes the
|
|
119
|
+
* fold on every `GET /v1/abs` poll).
|
|
120
|
+
*/
|
|
121
|
+
abSnapshot(snapshot: ABSnapshot): void;
|
|
122
|
+
/** Latest persisted aggregate A/B snapshot; errors read as absent. */
|
|
123
|
+
getLatestAbSnapshot(): Promise<ABSnapshot | undefined>;
|
|
124
|
+
/**
|
|
125
|
+
* Flush all buffers and drain the queue, giving the sink at most
|
|
126
|
+
* {@link CLOSE_DRAIN_TIMEOUT_MS} — a hung sink must not stall shutdown
|
|
127
|
+
* past the pod grace period. Called from engine close.
|
|
128
|
+
*/
|
|
129
|
+
close(): Promise<void>;
|
|
130
|
+
/** Pending deliveries (exposed for tests and drain instrumentation). */
|
|
131
|
+
whenIdle(): Promise<void>;
|
|
132
|
+
private buffer;
|
|
133
|
+
private armDebounce;
|
|
134
|
+
/** `list` wrapper for the startup reads: missing hook or throw ⇒ empty. */
|
|
135
|
+
private tryList;
|
|
136
|
+
private enqueue;
|
|
137
|
+
private context;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=storage-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-coordinator.d.ts","sourceRoot":"","sources":["../../src/internal/storage-coordinator.ts"],"names":[],"mappings":"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"}
|