@cursor/july 0.1.27 → 0.1.29
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/bin/agent-serve.js +32 -5
- package/dist/channels/slack/auth.d.ts +13 -13
- package/dist/channels/slack/auth.d.ts.map +1 -1
- package/dist/channels/slack/auth.js +19 -10
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +3 -1
- package/dist/channels/slack/defaults.d.ts +7 -4
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +14 -4
- package/dist/channels/slack/dispatch.d.ts +6 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +59 -21
- package/dist/channels/slack/external-policy.d.ts +27 -0
- package/dist/channels/slack/external-policy.d.ts.map +1 -0
- package/dist/channels/slack/external-policy.js +53 -0
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/interactive.d.ts +6 -0
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +42 -15
- package/dist/channels/slack/slack-channel.d.ts +19 -1
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +48 -6
- package/dist/channels/slack/types.d.ts +10 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.BICLoJYF.js → app.QdunVQKg.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DGe61XHA.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.wN4Ko9dT.js → VPLocalSearchBox.B6EpUXYf.js} +1 -1
- package/dist/docs/assets/chunks/{theme.dnnTE-Co.js → theme.BOTJVqh7.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.D_xFKlnF.js → guides_slack.md.CjmJSvZS.js} +8 -4
- package/dist/docs/assets/guides_slack.md.CjmJSvZS.lean.js +1 -0
- package/dist/docs/assets/guides_webhooks.md.wSOYas3X.js +183 -0
- package/dist/docs/assets/{guides_webhooks.md.B1EswtUu.lean.js → guides_webhooks.md.wSOYas3X.lean.js} +1 -1
- package/dist/docs/assets/{index.md.Dfv5ic9t.js → index.md.CH_s5uZe.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.DdmiKgqf.js → reference_channels.md.CDhTRfUz.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.DdmiKgqf.lean.js → reference_channels.md.CDhTRfUz.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +3 -3
- package/dist/docs/evals.html +3 -3
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/slack.html +11 -7
- package/dist/docs/guides/webhooks.html +138 -5
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +5 -5
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +5 -5
- package/dist/docs/reference/cli.html +3 -3
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +3 -3
- package/dist/docs/troubleshooting.html +3 -3
- package/dist/internal/cli-ax.d.ts +8 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +116 -57
- package/dist/internal/cloud-turn-cost.d.ts +34 -0
- package/dist/internal/cloud-turn-cost.d.ts.map +1 -0
- package/dist/internal/cloud-turn-cost.js +106 -0
- package/dist/internal/cursor-slack-relay.d.ts +2 -0
- package/dist/internal/cursor-slack-relay.d.ts.map +1 -1
- package/dist/internal/cursor-slack-relay.js +1 -0
- package/dist/internal/deploy-client.d.ts +2 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +1 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +9 -2
- package/dist/internal/event-log.d.ts +6 -0
- package/dist/internal/event-log.d.ts.map +1 -1
- package/dist/internal/event-log.js +16 -0
- package/dist/internal/host-platforms.d.ts +13 -0
- package/dist/internal/host-platforms.d.ts.map +1 -1
- package/dist/internal/host-platforms.js +25 -16
- package/dist/internal/http-channel.d.ts.map +1 -1
- package/dist/internal/http-channel.js +3 -1
- package/dist/internal/local-control-plane.d.ts +25 -0
- package/dist/internal/local-control-plane.d.ts.map +1 -0
- package/dist/internal/local-control-plane.js +172 -0
- package/dist/internal/platform-schedule-sync.d.ts +17 -0
- package/dist/internal/platform-schedule-sync.d.ts.map +1 -0
- package/dist/internal/platform-schedule-sync.js +72 -0
- package/dist/internal/platform-timers.d.ts +28 -0
- package/dist/internal/platform-timers.d.ts.map +1 -0
- package/dist/internal/platform-timers.js +120 -0
- package/dist/internal/reminder-runner.d.ts +16 -12
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +112 -61
- package/dist/internal/reminder-store.d.ts +5 -4
- package/dist/internal/reminder-store.d.ts.map +1 -1
- package/dist/internal/reminder-store.js +5 -4
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +44 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +115 -16
- package/dist/internal/session-engine.d.ts +22 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +110 -4
- package/dist/internal/storage-coordinator.d.ts +4 -15
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +4 -30
- package/dist/playground/assets/index-CquRB-l0.js +85 -0
- package/dist/playground/assets/{index-Bul1WfrB.css → index-Dj0bWpkn.css} +1 -1
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +0 -3
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +0 -3
- package/dist/types.d.ts +11 -2
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +1 -0
- package/docs/guides/slack.md +32 -7
- package/docs/guides/webhooks.md +183 -0
- package/docs/reference/channels.md +2 -1
- package/package.json +1 -1
- package/skills/setup-slack/SKILL.md +3 -0
- package/src/bin/agent-serve.ts +33 -5
- package/src/channels/slack/auth.ts +29 -22
- package/src/channels/slack/cursor-account.ts +2 -0
- package/src/channels/slack/defaults.ts +24 -4
- package/src/channels/slack/dispatch.ts +42 -1
- package/src/channels/slack/external-policy.ts +62 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/interactive.ts +42 -10
- package/src/channels/slack/slack-channel.ts +66 -3
- package/src/channels/slack/types.ts +12 -0
- package/src/internal/cli-ax.ts +110 -34
- package/src/internal/cloud-turn-cost.ts +158 -0
- package/src/internal/cursor-slack-relay.ts +3 -0
- package/src/internal/deploy-client.ts +3 -0
- package/src/internal/discovery.ts +9 -1
- package/src/internal/event-log.ts +17 -0
- package/src/internal/host-platforms.ts +40 -18
- package/src/internal/http-channel.ts +3 -1
- package/src/internal/local-control-plane.ts +188 -0
- package/src/internal/platform-schedule-sync.ts +81 -0
- package/src/internal/platform-timers.ts +173 -0
- package/src/internal/reminder-runner.ts +131 -67
- package/src/internal/reminder-store.ts +5 -4
- package/src/internal/sdk-runner.ts +49 -1
- package/src/internal/server.ts +130 -11
- package/src/internal/session-engine.ts +138 -3
- package/src/internal/storage-coordinator.ts +4 -41
- package/src/storage.ts +0 -5
- package/src/types.ts +11 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.CQJytDwU.js +0 -1
- package/dist/docs/assets/guides_slack.md.D_xFKlnF.lean.js +0 -1
- package/dist/docs/assets/guides_webhooks.md.B1EswtUu.js +0 -50
- package/dist/playground/assets/index-BDCeW4uc.js +0 -86
- /package/dist/docs/assets/{index.md.Dfv5ic9t.lean.js → index.md.CH_s5uZe.lean.js} +0 -0
|
@@ -13,10 +13,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
13
13
|
});
|
|
14
14
|
};
|
|
15
15
|
import { randomBytes } from "node:crypto";
|
|
16
|
-
import { join } from "node:path";
|
|
17
16
|
import { parseDuration } from "./duration.js";
|
|
18
17
|
import { defaultBusyPolicy, MAX_TIMER_MS, nextCronFireMs, ReminderValidationError, resolveSchedule, } from "./reminder-schedule.js";
|
|
19
|
-
import { ReminderStore, } from "./reminder-store.js";
|
|
20
18
|
import { APP_AUTH } from "./schedule-runner.js";
|
|
21
19
|
import { SessionBusyError } from "./session-engine.js";
|
|
22
20
|
export { ReminderValidationError } from "./reminder-schedule.js";
|
|
@@ -71,35 +69,72 @@ function buildFirePrompt(record) {
|
|
|
71
69
|
return lines.join("\n");
|
|
72
70
|
}
|
|
73
71
|
export class ReminderRunner {
|
|
74
|
-
constructor(engine, logger = () => { }) {
|
|
72
|
+
constructor(engine, logger = () => { }, platformTimers) {
|
|
75
73
|
this.engine = engine;
|
|
76
74
|
this.logger = logger;
|
|
75
|
+
this.platformTimers = platformTimers;
|
|
76
|
+
this.records = new Map();
|
|
77
77
|
this.handlers = new Map();
|
|
78
78
|
this.timers = new Map();
|
|
79
79
|
this.firing = new Set();
|
|
80
80
|
/** Single-flight idle gates keyed by `channelId:continuationToken`. */
|
|
81
81
|
this.idleGates = new Map();
|
|
82
82
|
this.started = false;
|
|
83
|
-
this.store = new ReminderStore(join(engine.stateRoot, "reminders"));
|
|
84
83
|
}
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Load reminder documents from the control plane into memory. Does not
|
|
86
|
+
* arm in-process timers — the CP owns clocks.
|
|
87
|
+
*/
|
|
88
|
+
hydrate() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
if (this.platformTimers === undefined) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
let remote = [];
|
|
94
|
+
try {
|
|
95
|
+
remote = yield this.platformTimers.listReminders();
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
this.logger(`[agentkit] reminders: control-plane list failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this.records.clear();
|
|
102
|
+
for (const record of remote) {
|
|
103
|
+
this.records.set(record.id, record);
|
|
104
|
+
}
|
|
105
|
+
let disarmedOrphan = 0;
|
|
106
|
+
for (const record of [...this.records.values()]) {
|
|
107
|
+
if (record.status !== "armed") {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if ((record.hasRunHandler === true || record.hasUntilFn === true) &&
|
|
111
|
+
this.handlers.get(record.id) === undefined) {
|
|
112
|
+
yield this.disarm(record, "handler_lost_on_restart");
|
|
113
|
+
disarmedOrphan += 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (remote.length > 0 || disarmedOrphan > 0) {
|
|
117
|
+
this.logger(`[agentkit] reminders: hydrated ${remote.length} reminder(s) from control plane` +
|
|
118
|
+
(disarmedOrphan > 0
|
|
119
|
+
? `; disarmed ${disarmedOrphan} without live handlers`
|
|
120
|
+
: ""));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
87
123
|
}
|
|
88
|
-
/** Start deadline timers for armed reminders (
|
|
124
|
+
/** Start deadline timers for armed reminders (tests / no control plane). */
|
|
89
125
|
start() {
|
|
90
126
|
return __awaiter(this, void 0, void 0, function* () {
|
|
91
127
|
if (this.started)
|
|
92
128
|
return;
|
|
93
129
|
this.started = true;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
yield this.hydrate();
|
|
131
|
+
if (this.platformTimers !== undefined) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const armed = [...this.records.values()].filter((r) => r.status === "armed");
|
|
98
135
|
let restored = 0;
|
|
99
136
|
let disarmedOrphan = 0;
|
|
100
137
|
for (const record of armed) {
|
|
101
|
-
// Run / function-until handlers are in-memory only. After restart they
|
|
102
|
-
// are gone — disarm rather than falling back to a generic prompt fire.
|
|
103
138
|
if ((record.hasRunHandler === true || record.hasUntilFn === true) &&
|
|
104
139
|
this.handlers.get(record.id) === undefined) {
|
|
105
140
|
yield this.disarm(record, "handler_lost_on_restart");
|
|
@@ -117,45 +152,49 @@ export class ReminderRunner {
|
|
|
117
152
|
}
|
|
118
153
|
});
|
|
119
154
|
}
|
|
120
|
-
|
|
121
|
-
* Pull reminder records from `defineStorage` into `<stateRoot>/reminders`
|
|
122
|
-
* when local disk is empty for that id. Failures are logged and skipped.
|
|
123
|
-
*/
|
|
124
|
-
hydrateFromStorage() {
|
|
155
|
+
persist(record) {
|
|
125
156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return;
|
|
157
|
+
if (this.platformTimers !== undefined) {
|
|
158
|
+
yield this.platformTimers.putReminder(record);
|
|
129
159
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
160
|
+
this.records.set(record.id, record);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
getRecord(id) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
if (this.platformTimers !== undefined) {
|
|
166
|
+
try {
|
|
167
|
+
const remote = yield this.platformTimers.getReminder(id);
|
|
168
|
+
if (remote === undefined) {
|
|
169
|
+
this.records.delete(id);
|
|
170
|
+
return undefined;
|
|
137
171
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
172
|
+
this.records.set(id, remote);
|
|
173
|
+
return remote;
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
this.logger(`[agentkit] reminders: control-plane get failed for ${id}: ${error instanceof Error ? error.message : String(error)}`);
|
|
177
|
+
return this.records.get(id);
|
|
141
178
|
}
|
|
142
179
|
}
|
|
143
|
-
|
|
144
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
145
|
-
this.logger(`[agentkit] reminders: storage hydrate failed: ${message}`);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (hydrated > 0) {
|
|
149
|
-
this.logger(`[agentkit] reminders: hydrated ${hydrated} reminder(s) from storage`);
|
|
150
|
-
}
|
|
180
|
+
return this.records.get(id);
|
|
151
181
|
});
|
|
152
182
|
}
|
|
153
|
-
|
|
154
|
-
persist(record) {
|
|
183
|
+
allRecords() {
|
|
155
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
185
|
+
if (this.platformTimers !== undefined) {
|
|
186
|
+
try {
|
|
187
|
+
const remote = yield this.platformTimers.listReminders();
|
|
188
|
+
this.records.clear();
|
|
189
|
+
for (const record of remote) {
|
|
190
|
+
this.records.set(record.id, record);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
this.logger(`[agentkit] reminders: control-plane list failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return [...this.records.values()];
|
|
159
198
|
});
|
|
160
199
|
}
|
|
161
200
|
stop() {
|
|
@@ -217,7 +256,7 @@ export class ReminderRunner {
|
|
|
217
256
|
run: input.run,
|
|
218
257
|
untilFn,
|
|
219
258
|
});
|
|
220
|
-
if (this.started) {
|
|
259
|
+
if (this.started && this.platformTimers === undefined) {
|
|
221
260
|
this.armTimer(record);
|
|
222
261
|
}
|
|
223
262
|
return toInfo(record);
|
|
@@ -225,7 +264,7 @@ export class ReminderRunner {
|
|
|
225
264
|
}
|
|
226
265
|
list(filter) {
|
|
227
266
|
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
-
const all = yield this.
|
|
267
|
+
const all = yield this.allRecords();
|
|
229
268
|
return all
|
|
230
269
|
.filter((r) => {
|
|
231
270
|
if ((filter === null || filter === void 0 ? void 0 : filter.status) !== undefined && r.status !== filter.status) {
|
|
@@ -251,7 +290,7 @@ export class ReminderRunner {
|
|
|
251
290
|
}
|
|
252
291
|
cancel(id_1) {
|
|
253
292
|
return __awaiter(this, arguments, void 0, function* (id, reason = "explicit_cancel") {
|
|
254
|
-
const record = yield this.
|
|
293
|
+
const record = yield this.getRecord(id);
|
|
255
294
|
if (record === undefined) {
|
|
256
295
|
return undefined;
|
|
257
296
|
}
|
|
@@ -268,7 +307,7 @@ export class ReminderRunner {
|
|
|
268
307
|
/** Cancel all armed reminders matching a continuation token (e.g. PR closed). */
|
|
269
308
|
cancelForContinuation(continuationToken, reason) {
|
|
270
309
|
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
-
const armed = yield this.
|
|
310
|
+
const armed = (yield this.allRecords()).filter((r) => r.status === "armed");
|
|
272
311
|
let n = 0;
|
|
273
312
|
for (const record of armed) {
|
|
274
313
|
if (record.continuationToken === continuationToken) {
|
|
@@ -287,7 +326,7 @@ export class ReminderRunner {
|
|
|
287
326
|
*/
|
|
288
327
|
rekeyContinuation(channelId, oldToken, newToken) {
|
|
289
328
|
return __awaiter(this, void 0, void 0, function* () {
|
|
290
|
-
const armed = yield this.
|
|
329
|
+
const armed = (yield this.allRecords()).filter((r) => r.status === "armed");
|
|
291
330
|
let n = 0;
|
|
292
331
|
for (const record of armed) {
|
|
293
332
|
if (record.channelId !== channelId ||
|
|
@@ -300,14 +339,22 @@ export class ReminderRunner {
|
|
|
300
339
|
return n;
|
|
301
340
|
});
|
|
302
341
|
}
|
|
303
|
-
/** Fire one reminder immediately (dev / hillclimb). */
|
|
304
|
-
dispatch(
|
|
305
|
-
return __awaiter(this,
|
|
306
|
-
const record = yield this.
|
|
342
|
+
/** Fire one reminder immediately (dev / hillclimb / control plane). */
|
|
343
|
+
dispatch(reminderId_1) {
|
|
344
|
+
return __awaiter(this, arguments, void 0, function* (reminderId, opts = {}) {
|
|
345
|
+
const record = yield this.getRecord(reminderId);
|
|
307
346
|
if (record === undefined) {
|
|
308
|
-
const ids = (yield this.
|
|
347
|
+
const ids = (yield this.allRecords()).map((r) => r.id);
|
|
309
348
|
throw new UnknownReminderError(reminderId, ids);
|
|
310
349
|
}
|
|
350
|
+
if (opts.expectedFireCount !== undefined &&
|
|
351
|
+
record.fireCount !== opts.expectedFireCount) {
|
|
352
|
+
return {
|
|
353
|
+
reminderId,
|
|
354
|
+
outcome: "noop",
|
|
355
|
+
reason: "stale_fire_count",
|
|
356
|
+
};
|
|
357
|
+
}
|
|
311
358
|
const result = yield this.fire(record.id, { force: true });
|
|
312
359
|
return Object.assign({ reminderId }, result);
|
|
313
360
|
});
|
|
@@ -327,7 +374,7 @@ export class ReminderRunner {
|
|
|
327
374
|
// Keep recurring reminders alive after unexpected throws.
|
|
328
375
|
// One-shots stay armed so a failed wake can be retried / dispatched.
|
|
329
376
|
try {
|
|
330
|
-
const current = yield this.
|
|
377
|
+
const current = yield this.getRecord(record.id);
|
|
331
378
|
if (current === undefined || current.status !== "armed")
|
|
332
379
|
return;
|
|
333
380
|
const oneShot = current.scheduleKind === "delay" || current.scheduleKind === "at";
|
|
@@ -362,7 +409,7 @@ export class ReminderRunner {
|
|
|
362
409
|
}
|
|
363
410
|
this.firing.add(id);
|
|
364
411
|
try {
|
|
365
|
-
const record = yield this.
|
|
412
|
+
const record = yield this.getRecord(id);
|
|
366
413
|
if (record === undefined || record.status !== "armed") {
|
|
367
414
|
this.clearTimer(id);
|
|
368
415
|
return { outcome: "noop", reason: "not_armed" };
|
|
@@ -399,7 +446,7 @@ export class ReminderRunner {
|
|
|
399
446
|
return { outcome: "fired", reason: "skipped_busy" };
|
|
400
447
|
}
|
|
401
448
|
yield this.whenSessionIdle(record.channelId, record.continuationToken);
|
|
402
|
-
const still = yield this.
|
|
449
|
+
const still = yield this.getRecord(id);
|
|
403
450
|
if (still === undefined || still.status !== "armed") {
|
|
404
451
|
return { outcome: "noop", reason: "disarmed_while_waiting" };
|
|
405
452
|
}
|
|
@@ -417,7 +464,7 @@ export class ReminderRunner {
|
|
|
417
464
|
return { outcome: "noop", reason: "missing_handler" };
|
|
418
465
|
}
|
|
419
466
|
// Cancel / disarm during the handler must win over reschedule.
|
|
420
|
-
const latest = yield this.
|
|
467
|
+
const latest = yield this.getRecord(id);
|
|
421
468
|
if (result.action === "stop") {
|
|
422
469
|
if (latest !== undefined && latest.status === "armed") {
|
|
423
470
|
yield this.disarm(latest, "run_stop");
|
|
@@ -590,7 +637,7 @@ export class ReminderRunner {
|
|
|
590
637
|
}
|
|
591
638
|
afterFire(record, _outcome, reschedule) {
|
|
592
639
|
return __awaiter(this, void 0, void 0, function* () {
|
|
593
|
-
const current = yield this.
|
|
640
|
+
const current = yield this.getRecord(record.id);
|
|
594
641
|
if (current === undefined || current.status !== "armed") {
|
|
595
642
|
return;
|
|
596
643
|
}
|
|
@@ -619,7 +666,9 @@ export class ReminderRunner {
|
|
|
619
666
|
? String(reschedule.delay)
|
|
620
667
|
: String(reschedule.at), updatedAt: new Date().toISOString() });
|
|
621
668
|
yield this.persist(updated);
|
|
622
|
-
this.
|
|
669
|
+
if (this.platformTimers === undefined) {
|
|
670
|
+
this.armTimer(updated);
|
|
671
|
+
}
|
|
623
672
|
return;
|
|
624
673
|
}
|
|
625
674
|
if (oneShot) {
|
|
@@ -642,7 +691,9 @@ export class ReminderRunner {
|
|
|
642
691
|
}
|
|
643
692
|
const updated = Object.assign(Object.assign({}, current), { fireCount: current.fireCount + 1, nextFireAtMs, updatedAt: new Date().toISOString() });
|
|
644
693
|
yield this.persist(updated);
|
|
645
|
-
this.
|
|
694
|
+
if (this.platformTimers === undefined) {
|
|
695
|
+
this.armTimer(updated);
|
|
696
|
+
}
|
|
646
697
|
});
|
|
647
698
|
}
|
|
648
699
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Reminder document store used by the local control plane
|
|
3
|
+
* (`<stateRoot>/control-plane/reminders/`).
|
|
3
4
|
*
|
|
4
5
|
* Handlers (`run` / function `until`) are not serializable — they live only
|
|
5
|
-
* in the in-memory {@link ReminderRunner} registry.
|
|
6
|
-
* prompt, target, and status so
|
|
7
|
-
*
|
|
6
|
+
* in the in-memory {@link ReminderRunner} registry. The control plane holds
|
|
7
|
+
* schedule, prompt, target, and status so prompt-form reminders survive
|
|
8
|
+
* restart.
|
|
8
9
|
*/
|
|
9
10
|
import type { ReminderBusyPolicy, ReminderScheduleKind, ReminderStatus } from "../types.js";
|
|
10
11
|
export declare const REMINDER_SNAPSHOT_VERSION: 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reminder-store.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-store.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reminder-store.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,yBAAyB,EAAG,CAAU,CAAC;AAEpD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,yBAAyB,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,oBAAoB,CAAC;IACnC,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAkBxE;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,MAAM,EAAI;IAEhD,OAAO,CAAC,QAAQ;IAIV,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhC;IAEK,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAiBtC;IAEK,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3C;IAEK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAsBzD;IAEK,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhD;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtC;CACF"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Reminder document store used by the local control plane
|
|
3
|
+
* (`<stateRoot>/control-plane/reminders/`).
|
|
3
4
|
*
|
|
4
5
|
* Handlers (`run` / function `until`) are not serializable — they live only
|
|
5
|
-
* in the in-memory {@link ReminderRunner} registry.
|
|
6
|
-
* prompt, target, and status so
|
|
7
|
-
*
|
|
6
|
+
* in the in-memory {@link ReminderRunner} registry. The control plane holds
|
|
7
|
+
* schedule, prompt, target, and status so prompt-form reminders survive
|
|
8
|
+
* restart.
|
|
8
9
|
*/
|
|
9
10
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
10
11
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAOL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAOL,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAEjB,MAAM,aAAa,CAAC;AAGrB,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D;;;;;OAKG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACjE,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,iBAAiB,EACf,cAAc,GACd,gBAAgB,GAChB,SAAS,GACT,YAAY,GACZ,WAAW,GACX,OAAO,CACV,CAAC;AAEF,6EAA6E;AAC7E,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAcxD,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAwBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKvE;AAED,qBAAa,eAAgB,YAAW,WAAW;IAKrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+C;IACtE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkC;IAElE,YAA6B,OAAO,GAAE,sBAA2B,EAAI;IAE/D,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkC9D;YAEa,cAAc;IAmF5B;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAepE;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAY7B;IAED,OAAO,CAAC,QAAQ;IA0BhB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,kBAAkB;IAc1B;;;OAGG;YACW,iBAAiB;YAkBjB,SAAS;YAOT,cAAc;YA6Bd,cAAc;IA6C5B,OAAO,CAAC,QAAQ;CAUjB;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAMT;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,cAAc,CAQpE;AAwGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,MAAM,CAExE"}
|
|
@@ -17,6 +17,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
17
17
|
import { mkdir } from "node:fs/promises";
|
|
18
18
|
import { Agent, createAgentPlatform, JsonlLocalAgentStore, } from "@cursor/sdk";
|
|
19
19
|
import { DEFAULT_MODEL, } from "../types.js";
|
|
20
|
+
import { mapSdkTokenUsage, usageTokenSum } from "./cloud-turn-cost.js";
|
|
20
21
|
/**
|
|
21
22
|
* How long one SDK agent handle (and the Connect transport inside it) may be
|
|
22
23
|
* reused before the runner retires it.
|
|
@@ -127,7 +128,7 @@ export class CursorSdkRunner {
|
|
|
127
128
|
}
|
|
128
129
|
try {
|
|
129
130
|
const result = yield run.wait();
|
|
130
|
-
|
|
131
|
+
let outcome = toTurnOutcome(result);
|
|
131
132
|
if (outcome.status === "error") {
|
|
132
133
|
// An error result usually means the handle's transport is poisoned
|
|
133
134
|
// — most often a cached access token that aged past its 60-minute
|
|
@@ -137,6 +138,15 @@ export class CursorSdkRunner {
|
|
|
137
138
|
// transport instead of failing every turn until a restart.
|
|
138
139
|
this.evictAgent(request.sessionId, agentPromise);
|
|
139
140
|
}
|
|
141
|
+
else if (request.runtime === "cloud" &&
|
|
142
|
+
outcome.status === "finished" &&
|
|
143
|
+
usageTokenSum(outcome.usage) <= 0 &&
|
|
144
|
+
result.id !== "") {
|
|
145
|
+
// Cloud `wait()` drops usage after stream reconnect / getRun replay,
|
|
146
|
+
// or returns an all-zero stub. `getUsage` still has the run's tokens
|
|
147
|
+
// (eventually); without them traces/ABs never record an estimated cost.
|
|
148
|
+
outcome = yield fillMissingCloudUsage(agent, result.id, outcome);
|
|
149
|
+
}
|
|
140
150
|
return outcome;
|
|
141
151
|
}
|
|
142
152
|
finally {
|
|
@@ -389,6 +399,39 @@ function toTurnOutcome(result) {
|
|
|
389
399
|
? { errorMessage: runErrorMessage(result) }
|
|
390
400
|
: {})), (usage === undefined ? {} : { usage }));
|
|
391
401
|
}
|
|
402
|
+
/** Billing can lag briefly after `wait()`; retry before giving up on cost. */
|
|
403
|
+
const CLOUD_USAGE_RETRY_DELAYS_MS = [0, 400, 1200];
|
|
404
|
+
/**
|
|
405
|
+
* Cloud `wait()` often omits usage after a stream drop. Pull the run's
|
|
406
|
+
* tokens from the usage API so the engine can still estimate cost.
|
|
407
|
+
* Failures are ignored: a missing estimate is better than failing the turn.
|
|
408
|
+
*/
|
|
409
|
+
function fillMissingCloudUsage(agent, runId, outcome) {
|
|
410
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
411
|
+
for (const delayMs of CLOUD_USAGE_RETRY_DELAYS_MS) {
|
|
412
|
+
if (delayMs > 0) {
|
|
413
|
+
yield sleep(delayMs);
|
|
414
|
+
}
|
|
415
|
+
try {
|
|
416
|
+
const billed = yield agent.getUsage({ runId });
|
|
417
|
+
const mapped = mapSdkTokenUsage(billed.usage);
|
|
418
|
+
if (usageTokenSum(mapped) <= 0) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
return Object.assign(Object.assign({}, outcome), { usage: mapped });
|
|
422
|
+
}
|
|
423
|
+
catch (_a) {
|
|
424
|
+
// Transient usage-API failures should still burn the retry budget.
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return outcome;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
function sleep(ms) {
|
|
431
|
+
return new Promise((resolve) => {
|
|
432
|
+
setTimeout(resolve, ms);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
392
435
|
export function runErrorMessage(result) {
|
|
393
436
|
var _a, _b;
|
|
394
437
|
return ((_b = (_a = result.error) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.trim()) || "The Cursor agent run failed";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AA8FrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAiBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAsrB3B"}
|