@cursor/july 0.1.9 → 0.1.11
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 +1 -0
- package/dist/bin/agent-serve.js +26 -3
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +2 -1
- package/dist/channels/github/types.d.ts +4 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +13 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +36 -11
- package/dist/channels/slack/eval-directive.d.ts +63 -0
- package/dist/channels/slack/eval-directive.d.ts.map +1 -0
- package/dist/channels/slack/eval-directive.js +283 -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/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +4 -2
- package/dist/channels/slack/types.d.ts +7 -0
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +10 -5
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +10 -5
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +4 -4
- package/dist/docs/assets/{app.Ciosf24M.js → app.BcXUGca7.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BIbvK8M1.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BcRDly7n.js → VPLocalSearchBox.CWur6XGZ.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CMpbjdfx.js → theme.BnvulOX2.js} +2 -2
- package/dist/docs/assets/{deployment.md.DC5-ImcM.js → deployment.md.TecHo0_2.js} +3 -3
- package/dist/docs/assets/{deployment.md.DC5-ImcM.lean.js → deployment.md.TecHo0_2.lean.js} +1 -1
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.js +29 -0
- package/dist/docs/assets/guides_mcp-oauth.md.DqmEOQY1.lean.js +1 -0
- package/dist/docs/assets/{index.md.COiu-1jL.js → index.md.t0TM2Qzz.js} +3 -3
- package/dist/docs/assets/{index.md.COiu-1jL.lean.js → index.md.t0TM2Qzz.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.D189RBCH.js → reference_cli.md.B74NrVzb.js} +5 -4
- package/dist/docs/assets/{reference_cli.md.D189RBCH.lean.js → reference_cli.md.B74NrVzb.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.js → reference_connections.md.CsSr3rDz.js} +9 -4
- package/dist/docs/assets/{reference_connections.md.zaEYCLHT.lean.js → reference_connections.md.CsSr3rDz.lean.js} +1 -1
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.js +1 -0
- package/dist/docs/assets/reference_prompt.md.BaiweQxE.lean.js +1 -0
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.js → reference_tools.md.BRSDnTbN.js} +16 -3
- package/dist/docs/assets/{reference_tools.md.CqgJroI0.lean.js → reference_tools.md.BRSDnTbN.lean.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.js → troubleshooting.md.CmQkmnzC.js} +1 -1
- package/dist/docs/assets/{troubleshooting.md.DkovjS7h.lean.js → troubleshooting.md.CmQkmnzC.lean.js} +1 -1
- 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 +4 -4
- package/dist/docs/example-agents/approval-buddy.html +4 -4
- package/dist/docs/example-agents/benny.html +4 -4
- package/dist/docs/example-agents/bugbot.html +4 -4
- package/dist/docs/example-agents/codebase-wiki.html +4 -4
- package/dist/docs/example-agents/codeowners-review.html +4 -4
- package/dist/docs/example-agents/concierge.html +4 -4
- package/dist/docs/example-agents/fsd.html +4 -4
- package/dist/docs/example-agents/index.html +4 -4
- package/dist/docs/example-agents/knowledge-base.html +4 -4
- package/dist/docs/example-agents/oncall.html +4 -4
- package/dist/docs/example-agents/security-reviewer.html +4 -4
- package/dist/docs/example-agents/slack-agent.html +4 -4
- package/dist/docs/example-agents/weather-agent.html +4 -4
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/cloud-runtime.html +4 -4
- package/dist/docs/guides/github.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +53 -0
- package/dist/docs/guides/slack.html +4 -4
- package/dist/docs/guides/webhooks.html +4 -4
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +4 -4
- package/dist/docs/index.html +6 -6
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/channels.html +4 -4
- package/dist/docs/reference/cli.html +8 -7
- package/dist/docs/reference/connections.html +13 -8
- package/dist/docs/reference/hooks.html +4 -4
- package/dist/docs/reference/http-api.html +4 -4
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/prompt.html +33 -0
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +5 -5
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +20 -7
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/storage.html +4 -4
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/evals.d.ts +39 -0
- package/dist/evals.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +7 -4
- package/dist/internal/cli-mcp-oauth.d.ts +16 -0
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -0
- package/dist/internal/cli-mcp-oauth.js +194 -0
- package/dist/internal/cli-mcp.d.ts +4 -1
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +19 -1
- package/dist/internal/corp-ca.d.ts +9 -0
- package/dist/internal/corp-ca.d.ts.map +1 -0
- package/dist/internal/corp-ca.js +44 -0
- package/dist/internal/cursor/account-mcp.d.ts +17 -4
- package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
- package/dist/internal/cursor/account-mcp.js +105 -17
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +64 -10
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/logs-client.js +1 -1
- package/dist/internal/mcp-host.d.ts.map +1 -1
- package/dist/internal/mcp-host.js +49 -26
- package/dist/internal/mcp-oauth.d.ts +88 -0
- package/dist/internal/mcp-oauth.d.ts.map +1 -0
- package/dist/internal/mcp-oauth.js +385 -0
- package/dist/internal/resolved-connections.d.ts +6 -0
- package/dist/internal/resolved-connections.d.ts.map +1 -1
- package/dist/internal/resolved-connections.js +10 -3
- package/dist/internal/sdk-runner.d.ts +9 -0
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +28 -2
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +24 -6
- package/dist/internal/session-engine.d.ts +30 -10
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +166 -74
- package/dist/internal/sessions-client.d.ts +16 -2
- package/dist/internal/sessions-client.d.ts.map +1 -1
- package/dist/internal/sessions-client.js +30 -13
- package/dist/internal/storage-coordinator.d.ts +11 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +30 -0
- package/dist/internal/stream-progress.d.ts.map +1 -1
- package/dist/internal/stream-progress.js +8 -4
- package/dist/internal/turn-governor.d.ts +54 -0
- package/dist/internal/turn-governor.d.ts.map +1 -0
- package/dist/internal/turn-governor.js +111 -0
- package/dist/playground/assets/{index-C0-QEG4O.js → index-BIGLubwK.js} +46 -46
- package/dist/playground/assets/{index-z3JY9O2x.css → index-C17ZQKDG.css} +1 -1
- package/dist/playground/index.html +2 -2
- package/dist/prompt.d.ts +39 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +70 -0
- package/dist/storage-backends/cursor-hosted.d.ts +10 -0
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +14 -0
- package/dist/types.d.ts +93 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -0
- package/docs/README.md +4 -0
- package/docs/deployment.md +6 -1
- package/docs/guides/mcp-oauth.md +157 -0
- package/docs/reference/cli.md +30 -0
- package/docs/reference/connections.md +32 -2
- package/docs/reference/prompt.md +47 -0
- package/docs/reference/tools.md +21 -0
- package/docs/troubleshooting.md +11 -0
- package/package.json +9 -2
- package/skills/create-agent/SKILL.md +7 -3
- package/skills/framework-map/SKILL.md +1 -0
- package/skills/mcp-auth/SKILL.md +138 -0
- package/src/bin/agent-serve.ts +30 -3
- package/src/channels/github/github-channel.ts +2 -0
- package/src/channels/github/types.ts +4 -0
- package/src/channels/slack/cursor-account.ts +2 -0
- package/src/channels/slack/dispatch.ts +49 -0
- package/src/channels/slack/eval-directive.ts +348 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/slack-channel.ts +3 -0
- package/src/channels/slack/types.ts +7 -0
- package/src/connections.ts +10 -5
- package/src/evals.ts +43 -0
- package/src/index.ts +3 -0
- package/src/internal/cli-ax.ts +10 -4
- package/src/internal/cli-mcp-oauth.ts +254 -0
- package/src/internal/cli-mcp.ts +25 -2
- package/src/internal/cursor/account-mcp.ts +153 -41
- package/src/internal/discovery.ts +70 -8
- package/src/internal/distribution.ts +1 -0
- package/src/internal/logs-client.ts +1 -1
- package/src/internal/mcp-host.ts +33 -9
- package/src/internal/mcp-oauth.ts +496 -0
- package/src/internal/resolved-connections.ts +20 -5
- package/src/internal/sdk-runner.ts +37 -1
- package/src/internal/server.ts +28 -6
- package/src/internal/session-engine.ts +192 -76
- package/src/internal/sessions-client.ts +51 -15
- package/src/internal/storage-coordinator.ts +36 -0
- package/src/internal/stream-progress.ts +8 -0
- package/src/internal/turn-governor.ts +145 -0
- package/src/prompt.ts +83 -0
- package/src/storage-backends/cursor-hosted.ts +21 -0
- package/src/types.ts +92 -6
- package/dist/docs/assets/chunks/@localSearchIndexroot.D154Detj.js +0 -1
|
@@ -24,6 +24,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
import { resolveStoragePolicy, storageKeys, } from "../storage.js";
|
|
27
|
+
import { isCursorHostedStorage } from "../storage-backends/cursor-hosted.js";
|
|
27
28
|
import { describeError } from "./describe-error.js";
|
|
28
29
|
import { isReminderRecord } from "./reminder-store.js";
|
|
29
30
|
/** Event types that close a unit of work — flush point for turn-end batching. */
|
|
@@ -190,6 +191,13 @@ export class StorageCoordinator {
|
|
|
190
191
|
get canBulkRestore() {
|
|
191
192
|
return this.definition.list !== undefined;
|
|
192
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* True when the authored sink is `cursorHostedStorage` (Bugbot via the
|
|
196
|
+
* control-plane proxy). `GET /v1/sessions` prefers this durable list.
|
|
197
|
+
*/
|
|
198
|
+
get isCursorHosted() {
|
|
199
|
+
return isCursorHostedStorage(this.definition);
|
|
200
|
+
}
|
|
193
201
|
/**
|
|
194
202
|
* Saved session records for this agent (startup restore). Errors are
|
|
195
203
|
* logged and read as "nothing saved" — a broken store must never block
|
|
@@ -203,6 +211,28 @@ export class StorageCoordinator {
|
|
|
203
211
|
.filter((record) => record != null);
|
|
204
212
|
});
|
|
205
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Session records from the sink for the sessions API. Unlike
|
|
216
|
+
* {@link listSessions}, missing `list` or a thrown sink error **propagates**
|
|
217
|
+
* so the caller can fall back to the local session store.
|
|
218
|
+
*/
|
|
219
|
+
listSessionsFromSink() {
|
|
220
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
const list = this.definition.list;
|
|
222
|
+
if (list === undefined) {
|
|
223
|
+
throw new Error("storage sink has no list");
|
|
224
|
+
}
|
|
225
|
+
const entries = yield list(storageKeys.sessionPrefix(this.agentName), this.context("restore"));
|
|
226
|
+
if (!Array.isArray(entries)) {
|
|
227
|
+
throw new Error("storage list returned a non-array");
|
|
228
|
+
}
|
|
229
|
+
return entries
|
|
230
|
+
.map((entry) => entry.value)
|
|
231
|
+
.filter((record) => record != null &&
|
|
232
|
+
typeof record.sessionId === "string" &&
|
|
233
|
+
record.sessionId !== "");
|
|
234
|
+
});
|
|
235
|
+
}
|
|
206
236
|
/**
|
|
207
237
|
* Saved event stream for one session: chunk values concatenated in key
|
|
208
238
|
* order (chunks are keyed by their first event's index, zero-padded, so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-progress.d.ts","sourceRoot":"","sources":["../../src/internal/stream-progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"stream-progress.d.ts","sourceRoot":"","sources":["../../src/internal/stream-progress.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE;IAC7C,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,cAAc,CA6NjB"}
|
|
@@ -21,7 +21,7 @@ export function createStreamProgress(options) {
|
|
|
21
21
|
const elapsed = (since) => `${Date.now() - since}ms`;
|
|
22
22
|
return {
|
|
23
23
|
onEvent(event) {
|
|
24
|
-
var _a, _b, _c;
|
|
24
|
+
var _a, _b, _c, _d;
|
|
25
25
|
switch (event.type) {
|
|
26
26
|
case "session.started": {
|
|
27
27
|
write(c.dim(`session ${event.sessionId}\n`));
|
|
@@ -35,12 +35,16 @@ export function createStreamProgress(options) {
|
|
|
35
35
|
}
|
|
36
36
|
break;
|
|
37
37
|
}
|
|
38
|
+
case "turn.queued": {
|
|
39
|
+
write(c.dim(` turn ${(_a = event.turnId) !== null && _a !== void 0 ? _a : "?"} queued (position ${event.data.position}, max ${event.data.maxRunningTurns} running)\n`));
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
38
42
|
case "turn.started": {
|
|
39
43
|
turnClock = Date.now();
|
|
40
44
|
if (event.turnId !== undefined) {
|
|
41
45
|
turnStartedAt.set(event.turnId, turnClock);
|
|
42
46
|
}
|
|
43
|
-
write(c.dim(` turn ${(
|
|
47
|
+
write(c.dim(` turn ${(_b = event.turnId) !== null && _b !== void 0 ? _b : "?"} started\n`));
|
|
44
48
|
break;
|
|
45
49
|
}
|
|
46
50
|
case "message.received": {
|
|
@@ -131,11 +135,11 @@ export function createStreamProgress(options) {
|
|
|
131
135
|
const detail = event.data.description
|
|
132
136
|
? ` — ${truncate(event.data.description, 60)}`
|
|
133
137
|
: "";
|
|
134
|
-
write(` ${c.magenta("task")} ${c.bold((
|
|
138
|
+
write(` ${c.magenta("task")} ${c.bold((_c = event.data.name) !== null && _c !== void 0 ? _c : "subagent")}${c.dim(detail)}\n`);
|
|
135
139
|
break;
|
|
136
140
|
}
|
|
137
141
|
case "subagent.completed": {
|
|
138
|
-
write(` ${c.magenta("✓")} ${c.bold((
|
|
142
|
+
write(` ${c.magenta("✓")} ${c.bold((_d = event.data.name) !== null && _d !== void 0 ? _d : "subagent")} ${c.dim("done")}\n`);
|
|
139
143
|
break;
|
|
140
144
|
}
|
|
141
145
|
case "turn.completed": {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FIFO admission of model turns under `concurrency.maxRunningTurns`
|
|
3
|
+
* (see {@link AgentConcurrencyOptions}). One governor per session engine:
|
|
4
|
+
* every turn acquires a slot before its SDK run starts and releases it when
|
|
5
|
+
* the run settles, so at most `maxRunningTurns` turns execute at once and
|
|
6
|
+
* the rest wait in arrival order instead of failing.
|
|
7
|
+
*
|
|
8
|
+
* Waiting is cancellable: the engine passes the turn's abort signal, so a
|
|
9
|
+
* follow-up that preempts a queued turn (or an explicit `interrupt()`)
|
|
10
|
+
* removes the waiter without ever running it.
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentConcurrencyOptions } from "../types.js";
|
|
13
|
+
export interface TurnPermit {
|
|
14
|
+
/** Return the slot. Idempotent; wakes the oldest waiter, if any. */
|
|
15
|
+
release(): void;
|
|
16
|
+
}
|
|
17
|
+
export interface AcquireTurnSlotArgs {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
/** Abort waiting (preemption / interrupt). Ignored once a slot is held. */
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
/**
|
|
22
|
+
* Called synchronously when the turn must wait, with its 1-based
|
|
23
|
+
* position among waiting turns at enqueue time.
|
|
24
|
+
*/
|
|
25
|
+
onQueued?: (position: number) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare class TurnGovernor {
|
|
28
|
+
/** The configured ceiling, or undefined for unlimited. */
|
|
29
|
+
readonly maxRunningTurns: number | undefined;
|
|
30
|
+
private running;
|
|
31
|
+
private readonly waiters;
|
|
32
|
+
/** Sessions currently waiting for a slot (at most one turn per session). */
|
|
33
|
+
private readonly queuedSessions;
|
|
34
|
+
constructor(concurrency: AgentConcurrencyOptions | undefined);
|
|
35
|
+
/** True when a `maxRunningTurns` ceiling is configured. */
|
|
36
|
+
get limited(): boolean;
|
|
37
|
+
/** True while `sessionId` has a turn waiting for a slot. */
|
|
38
|
+
isQueued(sessionId: string): boolean;
|
|
39
|
+
/** Turns currently waiting for a slot. */
|
|
40
|
+
get queuedCount(): number;
|
|
41
|
+
/** Turns currently holding a slot. */
|
|
42
|
+
get runningCount(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Acquire a turn slot. Resolves with a permit once a slot is free (FIFO
|
|
45
|
+
* behind earlier waiters), or with `undefined` when the abort signal
|
|
46
|
+
* fires while waiting — the turn must then settle as cancelled without
|
|
47
|
+
* running. Unlimited governors grant immediately.
|
|
48
|
+
*/
|
|
49
|
+
acquire(args: AcquireTurnSlotArgs): Promise<TurnPermit | undefined>;
|
|
50
|
+
/** Take a slot and build its (idempotent) release handle. */
|
|
51
|
+
private grantSlot;
|
|
52
|
+
private wakeNextWaiter;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=turn-governor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn-governor.d.ts","sourceRoot":"","sources":["../../src/internal/turn-governor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AASD,qBAAa,YAAY;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IAEpD,YAAY,WAAW,EAAE,uBAAuB,GAAG,SAAS,EAE3D;IAED,2DAA2D;IAC3D,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnC;IAED,0CAA0C;IAC1C,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,sCAAsC;IACtC,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAoClE;IAED,6DAA6D;IAC7D,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,cAAc;CAYvB"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FIFO admission of model turns under `concurrency.maxRunningTurns`
|
|
3
|
+
* (see {@link AgentConcurrencyOptions}). One governor per session engine:
|
|
4
|
+
* every turn acquires a slot before its SDK run starts and releases it when
|
|
5
|
+
* the run settles, so at most `maxRunningTurns` turns execute at once and
|
|
6
|
+
* the rest wait in arrival order instead of failing.
|
|
7
|
+
*
|
|
8
|
+
* Waiting is cancellable: the engine passes the turn's abort signal, so a
|
|
9
|
+
* follow-up that preempts a queued turn (or an explicit `interrupt()`)
|
|
10
|
+
* removes the waiter without ever running it.
|
|
11
|
+
*/
|
|
12
|
+
export class TurnGovernor {
|
|
13
|
+
constructor(concurrency) {
|
|
14
|
+
this.running = 0;
|
|
15
|
+
this.waiters = [];
|
|
16
|
+
/** Sessions currently waiting for a slot (at most one turn per session). */
|
|
17
|
+
this.queuedSessions = new Set();
|
|
18
|
+
this.maxRunningTurns = concurrency === null || concurrency === void 0 ? void 0 : concurrency.maxRunningTurns;
|
|
19
|
+
}
|
|
20
|
+
/** True when a `maxRunningTurns` ceiling is configured. */
|
|
21
|
+
get limited() {
|
|
22
|
+
return this.maxRunningTurns !== undefined;
|
|
23
|
+
}
|
|
24
|
+
/** True while `sessionId` has a turn waiting for a slot. */
|
|
25
|
+
isQueued(sessionId) {
|
|
26
|
+
return this.queuedSessions.has(sessionId);
|
|
27
|
+
}
|
|
28
|
+
/** Turns currently waiting for a slot. */
|
|
29
|
+
get queuedCount() {
|
|
30
|
+
return this.waiters.length;
|
|
31
|
+
}
|
|
32
|
+
/** Turns currently holding a slot. */
|
|
33
|
+
get runningCount() {
|
|
34
|
+
return this.running;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Acquire a turn slot. Resolves with a permit once a slot is free (FIFO
|
|
38
|
+
* behind earlier waiters), or with `undefined` when the abort signal
|
|
39
|
+
* fires while waiting — the turn must then settle as cancelled without
|
|
40
|
+
* running. Unlimited governors grant immediately.
|
|
41
|
+
*/
|
|
42
|
+
acquire(args) {
|
|
43
|
+
var _a;
|
|
44
|
+
const limit = this.maxRunningTurns;
|
|
45
|
+
if (limit === undefined) {
|
|
46
|
+
return Promise.resolve(NO_OP_PERMIT);
|
|
47
|
+
}
|
|
48
|
+
if (this.running < limit && this.waiters.length === 0) {
|
|
49
|
+
return Promise.resolve(this.grantSlot());
|
|
50
|
+
}
|
|
51
|
+
// Saturated. A turn that is already preempted never enqueues.
|
|
52
|
+
if (((_a = args.signal) === null || _a === void 0 ? void 0 : _a.aborted) === true) {
|
|
53
|
+
return Promise.resolve(undefined);
|
|
54
|
+
}
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
const waiter = {
|
|
58
|
+
sessionId: args.sessionId,
|
|
59
|
+
grant: (permit) => resolve(permit),
|
|
60
|
+
cancel: () => resolve(undefined),
|
|
61
|
+
cleanup: () => {
|
|
62
|
+
var _a;
|
|
63
|
+
this.queuedSessions.delete(args.sessionId);
|
|
64
|
+
(_a = args.signal) === null || _a === void 0 ? void 0 : _a.removeEventListener("abort", onAbort);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
const onAbort = () => {
|
|
68
|
+
const index = this.waiters.indexOf(waiter);
|
|
69
|
+
if (index === -1) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.waiters.splice(index, 1);
|
|
73
|
+
waiter.cleanup();
|
|
74
|
+
waiter.cancel();
|
|
75
|
+
};
|
|
76
|
+
this.waiters.push(waiter);
|
|
77
|
+
this.queuedSessions.add(args.sessionId);
|
|
78
|
+
(_a = args.signal) === null || _a === void 0 ? void 0 : _a.addEventListener("abort", onAbort, { once: true });
|
|
79
|
+
(_b = args.onQueued) === null || _b === void 0 ? void 0 : _b.call(args, this.waiters.length);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Take a slot and build its (idempotent) release handle. */
|
|
83
|
+
grantSlot() {
|
|
84
|
+
this.running += 1;
|
|
85
|
+
let released = false;
|
|
86
|
+
return {
|
|
87
|
+
release: () => {
|
|
88
|
+
if (released) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
released = true;
|
|
92
|
+
this.running -= 1;
|
|
93
|
+
this.wakeNextWaiter();
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
wakeNextWaiter() {
|
|
98
|
+
const limit = this.maxRunningTurns;
|
|
99
|
+
if (limit === undefined || this.running >= limit) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const waiter = this.waiters.shift();
|
|
103
|
+
if (waiter === undefined) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
waiter.cleanup();
|
|
107
|
+
waiter.grant(this.grantSlot());
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Permit handed out by unlimited governors. */
|
|
111
|
+
const NO_OP_PERMIT = { release: () => { } };
|