@cursor/july 0.1.16 → 0.1.18
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/README.md +9 -4
- package/dist/bin/agent-serve.js +60 -2
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +13 -3
- package/dist/channels/slack/auth.d.ts +7 -1
- package/dist/channels/slack/auth.d.ts.map +1 -1
- package/dist/channels/slack/auth.js +14 -0
- package/dist/channels/slack/blocks.d.ts +61 -0
- package/dist/channels/slack/blocks.d.ts.map +1 -0
- package/dist/channels/slack/blocks.js +90 -0
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +1 -1
- package/dist/channels/slack/defaults.d.ts +2 -0
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +29 -3
- package/dist/channels/slack/dispatch.d.ts +3 -17
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +4 -1
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +6 -1
- package/dist/channels/slack/index.d.ts +2 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +2 -0
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +4 -1
- package/dist/channels/slack/interactive.d.ts +39 -3
- package/dist/channels/slack/interactive.d.ts.map +1 -1
- package/dist/channels/slack/interactive.js +153 -7
- package/dist/channels/slack/manifest.d.ts +13 -0
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +36 -14
- package/dist/channels/slack/message-body.d.ts +13 -0
- package/dist/channels/slack/message-body.d.ts.map +1 -0
- package/dist/channels/slack/message-body.js +82 -0
- package/dist/channels/slack/setup.d.ts +4 -1
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +16 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +24 -3
- package/dist/channels/slack/thread-context.d.ts +0 -2
- package/dist/channels/slack/thread-context.d.ts.map +1 -1
- package/dist/channels/slack/thread-context.js +1 -65
- package/dist/channels/slack/types.d.ts +93 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/connections.d.ts +4 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +4 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.DjHC-Ggf.js → app.BR5EdVSq.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BOzkeUi8.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.DwviwmIq.js → VPLocalSearchBox.CNCzfUKC.js} +1 -1
- package/dist/docs/assets/chunks/{theme.BIpeYSon.js → theme.CwKvMSWv.js} +2 -2
- package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.js → example-agents_security-reviewer.md.Dhj_m7_B.js} +1 -1
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.js → guides_mcp-oauth.md.Dd8EgSem.js} +3 -2
- package/dist/docs/assets/{guides_mcp-oauth.md.DqmEOQY1.lean.js → guides_mcp-oauth.md.Dd8EgSem.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.FWale6Ip.js → guides_slack.md.D_xFKlnF.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.js → reference_connections.md.B9Q3TOve.js} +12 -5
- package/dist/docs/assets/{reference_connections.md.CsSr3rDz.lean.js → reference_connections.md.B9Q3TOve.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 +5 -5
- 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 +6 -5
- package/dist/docs/guides/slack.html +5 -5
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +3 -3
- package/dist/docs/reference/connections.html +14 -7
- 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/evals/assertions.d.ts +190 -0
- package/dist/evals/assertions.d.ts.map +1 -0
- package/dist/evals/assertions.js +461 -0
- package/dist/evals/expect.d.ts +95 -0
- package/dist/evals/expect.d.ts.map +1 -0
- package/dist/evals/expect.js +194 -0
- package/dist/evals/judge.d.ts +133 -0
- package/dist/evals/judge.d.ts.map +1 -0
- package/dist/evals/judge.js +228 -0
- package/dist/evals/loaders.d.ts +51 -0
- package/dist/evals/loaders.d.ts.map +1 -0
- package/dist/evals/loaders.js +124 -0
- package/dist/evals/matchers.d.ts +95 -0
- package/dist/evals/matchers.d.ts.map +1 -0
- package/dist/evals/matchers.js +145 -0
- package/dist/evals/reporters.d.ts +70 -0
- package/dist/evals/reporters.d.ts.map +1 -0
- package/dist/evals/reporters.js +221 -0
- package/dist/evals/results.d.ts +103 -0
- package/dist/evals/results.d.ts.map +1 -0
- package/dist/evals/results.js +28 -0
- package/dist/evals/run-facts.d.ts +77 -0
- package/dist/evals/run-facts.d.ts.map +1 -0
- package/dist/evals/run-facts.js +187 -0
- package/dist/evals.d.ts +118 -31
- package/dist/evals.d.ts.map +1 -1
- package/dist/evals.js +46 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/builtin-tools/index.d.ts +10 -0
- package/dist/internal/builtin-tools/index.d.ts.map +1 -0
- package/dist/internal/builtin-tools/index.js +27 -0
- package/dist/internal/builtin-tools/reminders.d.ts +9 -0
- package/dist/internal/builtin-tools/reminders.d.ts.map +1 -0
- package/dist/internal/builtin-tools/reminders.js +138 -0
- package/dist/internal/cli-ax.d.ts +27 -0
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +90 -12
- package/dist/internal/cli-mcp.d.ts +8 -0
- package/dist/internal/cli-mcp.d.ts.map +1 -1
- package/dist/internal/cli-mcp.js +98 -0
- package/dist/internal/cli-slack.d.ts +29 -1
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +799 -13
- package/dist/internal/cursor-event-relay.d.ts +30 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +37 -0
- package/dist/internal/deploy-client.d.ts +7 -0
- package/dist/internal/deploy-client.d.ts.map +1 -1
- package/dist/internal/deploy-client.js +9 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +70 -9
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +2 -0
- package/dist/internal/eval-judge-model.d.ts +59 -0
- package/dist/internal/eval-judge-model.d.ts.map +1 -0
- package/dist/internal/eval-judge-model.js +131 -0
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +12 -20
- package/dist/internal/eval-runner.d.ts +31 -25
- package/dist/internal/eval-runner.d.ts.map +1 -1
- package/dist/internal/eval-runner.js +329 -126
- package/dist/internal/evals-client.d.ts.map +1 -1
- package/dist/internal/evals-client.js +4 -1
- package/dist/internal/local-env.d.ts +8 -0
- package/dist/internal/local-env.d.ts.map +1 -0
- package/dist/internal/local-env.js +47 -0
- package/dist/internal/playground/static.d.ts +3 -0
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +3 -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 +21 -0
- package/dist/internal/run-client.d.ts +15 -0
- package/dist/internal/run-client.d.ts.map +1 -1
- package/dist/internal/run-client.js +3 -2
- package/dist/internal/sdk-runner.d.ts +51 -1
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +176 -36
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +11 -1
- package/dist/internal/session-engine.d.ts +18 -5
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +81 -19
- package/dist/internal/slack-provision-client.d.ts +133 -0
- package/dist/internal/slack-provision-client.d.ts.map +1 -0
- package/dist/internal/slack-provision-client.js +286 -0
- package/dist/playground/assets/cursor-icons-16-f_W_ogc-.woff2 +0 -0
- package/dist/playground/assets/index-DRjS5klQ.js +85 -0
- package/dist/playground/assets/index-TCDs-UhZ.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +98 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -0
- package/docs/example-agents/security-reviewer.md +1 -1
- package/docs/guides/mcp-oauth.md +10 -5
- package/docs/guides/slack.md +3 -2
- package/docs/reference/connections.md +28 -18
- package/package.json +20 -2
- package/skills/create-agent/SKILL.md +15 -7
- package/skills/debug/SKILL.md +3 -1
- package/skills/mcp-auth/SKILL.md +1 -1
- package/skills/setup-slack/SKILL.md +177 -11
- package/src/bin/agent-serve.ts +63 -2
- package/src/channels/slack/api.ts +16 -3
- package/src/channels/slack/auth.ts +16 -1
- package/src/channels/slack/blocks.ts +139 -0
- package/src/channels/slack/cursor-account.ts +1 -0
- package/src/channels/slack/defaults.ts +32 -4
- package/src/channels/slack/dispatch.ts +6 -19
- package/src/channels/slack/inbound.ts +6 -1
- package/src/channels/slack/index.ts +2 -0
- package/src/channels/slack/init.ts +3 -0
- package/src/channels/slack/interactive.ts +184 -19
- package/src/channels/slack/manifest.ts +37 -6
- package/src/channels/slack/message-body.ts +90 -0
- package/src/channels/slack/setup.ts +16 -2
- package/src/channels/slack/slack-channel.ts +37 -6
- package/src/channels/slack/thread-context.ts +1 -69
- package/src/channels/slack/types.ts +105 -1
- package/src/connections.ts +4 -1
- package/src/evals/assertions.ts +704 -0
- package/src/evals/expect.ts +272 -0
- package/src/evals/judge.ts +346 -0
- package/src/evals/loaders.ts +113 -0
- package/src/evals/matchers.ts +246 -0
- package/src/evals/reporters.ts +274 -0
- package/src/evals/results.ts +132 -0
- package/src/evals/run-facts.ts +274 -0
- package/src/evals.ts +205 -42
- package/src/index.ts +2 -0
- package/src/internal/builtin-tools/index.ts +40 -0
- package/src/internal/builtin-tools/reminders.ts +158 -0
- package/src/internal/cli-ax.ts +134 -15
- package/src/internal/cli-mcp.ts +118 -5
- package/src/internal/cli-slack.ts +1017 -15
- package/src/internal/cursor-event-relay.ts +67 -0
- package/src/internal/deploy-client.ts +10 -0
- package/src/internal/discovery.ts +83 -5
- package/src/internal/distribution.ts +2 -0
- package/src/internal/eval-judge-model.ts +148 -0
- package/src/internal/eval-run-store.ts +10 -14
- package/src/internal/eval-runner.ts +460 -214
- package/src/internal/evals-client.ts +5 -0
- package/src/internal/local-env.ts +53 -0
- package/src/internal/playground/static.ts +3 -0
- package/src/internal/reminder-runner.ts +30 -0
- package/src/internal/run-client.ts +17 -1
- package/src/internal/sdk-runner.ts +234 -35
- package/src/internal/server.ts +12 -0
- package/src/internal/session-engine.ts +103 -21
- package/src/internal/slack-provision-client.ts +442 -0
- package/src/types.ts +125 -4
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DZtu0ZIc.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/cursor-icons-16-CQ50JpfO.woff2 +0 -0
- package/dist/playground/assets/index-Bwl4Onx4.js +0 -85
- package/dist/playground/assets/index-ByV4nfch.css +0 -1
- /package/dist/docs/assets/{example-agents_security-reviewer.md.BZSNycMf.lean.js → example-agents_security-reviewer.md.Dhj_m7_B.lean.js} +0 -0
- /package/dist/docs/assets/{guides_slack.md.FWale6Ip.lean.js → guides_slack.md.D_xFKlnF.lean.js} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads an agent directory's `.env.local` (and each immediate child's,
|
|
3
|
+
* for multi-agent hosts) into process.env. Real env always wins —
|
|
4
|
+
* `process.loadEnvFile` never overrides. Values a previous call loaded are
|
|
5
|
+
* refreshed, so a reload picks up edits made since.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
// Not real env, so a reload has to clear them first: loadEnvFile skips
|
|
10
|
+
// anything already in process.env, which would pin the first-boot values.
|
|
11
|
+
let fileLoadedKeys = new Set();
|
|
12
|
+
export function loadAgentLocalEnv(dir) {
|
|
13
|
+
for (const key of fileLoadedKeys) {
|
|
14
|
+
delete process.env[key];
|
|
15
|
+
}
|
|
16
|
+
const realKeys = new Set(Object.keys(process.env));
|
|
17
|
+
const loaded = [];
|
|
18
|
+
const tryLoad = (path) => {
|
|
19
|
+
if (!existsSync(path)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
process.loadEnvFile(path);
|
|
23
|
+
loaded.push(path);
|
|
24
|
+
};
|
|
25
|
+
const trackLoadedKeys = () => {
|
|
26
|
+
fileLoadedKeys = new Set(Object.keys(process.env).filter((key) => !realKeys.has(key)));
|
|
27
|
+
};
|
|
28
|
+
tryLoad(join(dir, ".env.local"));
|
|
29
|
+
let children;
|
|
30
|
+
try {
|
|
31
|
+
children = readdirSync(dir, { withFileTypes: true })
|
|
32
|
+
.filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
|
|
33
|
+
.map((entry) => entry.name);
|
|
34
|
+
}
|
|
35
|
+
catch (_a) {
|
|
36
|
+
trackLoadedKeys();
|
|
37
|
+
return loaded;
|
|
38
|
+
}
|
|
39
|
+
for (const child of children) {
|
|
40
|
+
if (child === "node_modules") {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
tryLoad(join(dir, child, ".env.local"));
|
|
44
|
+
}
|
|
45
|
+
trackLoadedKeys();
|
|
46
|
+
return loaded;
|
|
47
|
+
}
|
|
@@ -18,6 +18,9 @@ export declare function playgroundBundleExists(): boolean;
|
|
|
18
18
|
* The SPA `index.html` with a `<base href>` injected so its relative asset
|
|
19
19
|
* URLs resolve under the mount point (`/playground/` or `/<slug>/playground/`).
|
|
20
20
|
* Falls back to a helpful placeholder page when the bundle is missing.
|
|
21
|
+
* The hosted alias performs the same injection for its central copy
|
|
22
|
+
* (`backend/server/src/agentServe/aliasPlaygroundShell.ts`) — keep them
|
|
23
|
+
* behaviorally aligned.
|
|
21
24
|
*/
|
|
22
25
|
export declare function renderPlaygroundIndexHtml(baseHref: string): string;
|
|
23
26
|
/** Serve one built asset from `dist/playground/assets/` by filename. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../../src/internal/playground/static.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiBvD,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED
|
|
1
|
+
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../../src/internal/playground/static.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiBvD,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUlE;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAsB5D;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAiBvE"}
|
|
@@ -45,6 +45,9 @@ export function playgroundBundleExists() {
|
|
|
45
45
|
* The SPA `index.html` with a `<base href>` injected so its relative asset
|
|
46
46
|
* URLs resolve under the mount point (`/playground/` or `/<slug>/playground/`).
|
|
47
47
|
* Falls back to a helpful placeholder page when the bundle is missing.
|
|
48
|
+
* The hosted alias performs the same injection for its central copy
|
|
49
|
+
* (`backend/server/src/agentServe/aliasPlaygroundShell.ts`) — keep them
|
|
50
|
+
* behaviorally aligned.
|
|
48
51
|
*/
|
|
49
52
|
export function renderPlaygroundIndexHtml(baseHref) {
|
|
50
53
|
if (!playgroundBundleExists()) {
|
|
@@ -42,6 +42,13 @@ export declare class ReminderRunner {
|
|
|
42
42
|
cancel(id: string, reason?: string): Promise<ReminderInfo | undefined>;
|
|
43
43
|
/** Cancel all armed reminders matching a continuation token (e.g. PR closed). */
|
|
44
44
|
cancelForContinuation(continuationToken: string, reason: string): Promise<number>;
|
|
45
|
+
/**
|
|
46
|
+
* Re-key armed reminders when a channel rotates a session's continuation
|
|
47
|
+
* token (the built-in HTTP channel rotates after every follow-up). Without
|
|
48
|
+
* this, a reminder armed before the rotation misses its session at fire
|
|
49
|
+
* time and disarms as `session_gone`.
|
|
50
|
+
*/
|
|
51
|
+
rekeyContinuation(channelId: string, oldToken: string, newToken: string): Promise<number>;
|
|
45
52
|
/** Fire one reminder immediately (dev / hillclimb). */
|
|
46
53
|
dispatch(reminderId: string): Promise<{
|
|
47
54
|
reminderId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reminder-runner.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAEV,mBAAmB,EAGnB,YAAY,EAEb,MAAM,aAAa,CAAC;AASrB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE;IAFzC,YACE,UAAU,EAAE,MAAM,EACT,oBAAoB,EAAE,MAAM,EAAE,EAIxC;CACF;AAyDD,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,OAAO,CAAS;IAExB,YACmB,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAe,EAG3D;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B3B;IAED;;;OAGG;YACW,kBAAkB;IA6BhC,8EAA8E;YAChE,OAAO;IAKrB,IAAI,IAAI,IAAI,CAOX;IAEK,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8D9D;IAEK,IAAI,CAAC,MAAM,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA4B1B;IAEK,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,SAAoB,GACzB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAkBnC;IAED,iFAAiF;IAC3E,qBAAqB,CACzB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAUjB;IAED,uDAAuD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAQD;IAED,OAAO,CAAC,QAAQ;IA4ChB,OAAO,CAAC,UAAU;YAQJ,IAAI;YA6GJ,aAAa;IAY3B,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;YACW,mBAAmB;YAcnB,aAAa;YAcb,YAAY;IA0C1B,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,iBAAiB;YAeX,MAAM;YAYN,SAAS;CAoFxB;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"reminder-runner.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAEV,mBAAmB,EAGnB,YAAY,EAEb,MAAM,aAAa,CAAC;AASrB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE;IAFzC,YACE,UAAU,EAAE,MAAM,EACT,oBAAoB,EAAE,MAAM,EAAE,EAIxC;CACF;AAyDD,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,OAAO,CAAS;IAExB,YACmB,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAe,EAG3D;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B3B;IAED;;;OAGG;YACW,kBAAkB;IA6BhC,8EAA8E;YAChE,OAAO;IAKrB,IAAI,IAAI,IAAI,CAOX;IAEK,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8D9D;IAEK,IAAI,CAAC,MAAM,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA4B1B;IAEK,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,SAAoB,GACzB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAkBnC;IAED,iFAAiF;IAC3E,qBAAqB,CACzB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAUjB;IAED;;;;;OAKG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAkBjB;IAED,uDAAuD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAQD;IAED,OAAO,CAAC,QAAQ;IA4ChB,OAAO,CAAC,UAAU;YAQJ,IAAI;YA6GJ,aAAa;IAY3B,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;YACW,mBAAmB;YAcnB,aAAa;YAcb,YAAY;IA0C1B,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,iBAAiB;YAeX,MAAM;YAYN,SAAS;CAoFxB;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -279,6 +279,27 @@ export class ReminderRunner {
|
|
|
279
279
|
return n;
|
|
280
280
|
});
|
|
281
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Re-key armed reminders when a channel rotates a session's continuation
|
|
284
|
+
* token (the built-in HTTP channel rotates after every follow-up). Without
|
|
285
|
+
* this, a reminder armed before the rotation misses its session at fire
|
|
286
|
+
* time and disarms as `session_gone`.
|
|
287
|
+
*/
|
|
288
|
+
rekeyContinuation(channelId, oldToken, newToken) {
|
|
289
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
290
|
+
const armed = yield this.store.listArmed();
|
|
291
|
+
let n = 0;
|
|
292
|
+
for (const record of armed) {
|
|
293
|
+
if (record.channelId !== channelId ||
|
|
294
|
+
record.continuationToken !== oldToken) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
yield this.persist(Object.assign(Object.assign({}, record), { continuationToken: newToken, updatedAt: new Date().toISOString() }));
|
|
298
|
+
n += 1;
|
|
299
|
+
}
|
|
300
|
+
return n;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
282
303
|
/** Fire one reminder immediately (dev / hillclimb). */
|
|
283
304
|
dispatch(reminderId) {
|
|
284
305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -34,6 +34,11 @@ export interface RunSessionResult {
|
|
|
34
34
|
events: SessionEvent[];
|
|
35
35
|
trajectory: Trajectory;
|
|
36
36
|
ok: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Index to pass as `startIndex` on the next call for this session. Undefined
|
|
39
|
+
* when the turn streamed nothing, in which case reuse the previous value.
|
|
40
|
+
*/
|
|
41
|
+
nextEventIndex?: number;
|
|
37
42
|
}
|
|
38
43
|
/**
|
|
39
44
|
* Run one or more messages against a live agent-serve base URL
|
|
@@ -43,6 +48,16 @@ export declare function runSession(options: RunClientOptions & {
|
|
|
43
48
|
messages: string[];
|
|
44
49
|
sessionId?: string;
|
|
45
50
|
continuationToken?: string;
|
|
51
|
+
/**
|
|
52
|
+
* First event index to read when resuming an existing session.
|
|
53
|
+
*
|
|
54
|
+
* The stream replays from `startIndex` and this client stops at the first
|
|
55
|
+
* terminal event, so a caller that sends several turns across separate
|
|
56
|
+
* `runSession` calls **must** pass the index after its last consumed event
|
|
57
|
+
* (see {@link RunSessionResult.nextEventIndex}). Omitting it replays the
|
|
58
|
+
* earlier turn and returns those stale events instead of the new turn's.
|
|
59
|
+
*/
|
|
60
|
+
startIndex?: number;
|
|
46
61
|
/** Applied only when creating a new session (first message). */
|
|
47
62
|
workspaceDir?: string;
|
|
48
63
|
/** Applied only when creating a new session (first message). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-client.d.ts","sourceRoot":"","sources":["../../src/internal/run-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,6EAA6E;AAC7E,qBAAa,sBAAuB,SAAQ,KAAK;IAG7C,QAAQ,CAAC,SAAS,EAAE,MAAM;IAF5B,YACE,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,MAAM,EAI3B;CACF;AACD,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,EAAE,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"run-client.d.ts","sourceRoot":"","sources":["../../src/internal/run-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,6EAA6E;AAC7E,qBAAa,sBAAuB,SAAQ,KAAK;IAG7C,QAAQ,CAAC,SAAS,EAAE,MAAM;IAF5B,YACE,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,MAAM,EAI3B;CACF;AACD,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAQD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,gBAAgB,GAAG;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,gEAAgE;IAChE,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B,GACA,OAAO,CAAC,gBAAgB,CAAC,CA0D3B"}
|
|
@@ -35,6 +35,7 @@ const TERMINAL_TYPES = new Set([
|
|
|
35
35
|
*/
|
|
36
36
|
export function runSession(options) {
|
|
37
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
var _a;
|
|
38
39
|
if (options.messages.length === 0) {
|
|
39
40
|
throw new Error("runSession requires at least one message");
|
|
40
41
|
}
|
|
@@ -42,7 +43,7 @@ export function runSession(options) {
|
|
|
42
43
|
let sessionId = options.sessionId;
|
|
43
44
|
let continuationToken = options.continuationToken;
|
|
44
45
|
const allEvents = [];
|
|
45
|
-
let nextEventIndex = 0;
|
|
46
|
+
let nextEventIndex = (_a = options.startIndex) !== null && _a !== void 0 ? _a : 0;
|
|
46
47
|
const auth = {
|
|
47
48
|
bearerToken: options.bearerToken,
|
|
48
49
|
headers: options.headers,
|
|
@@ -78,7 +79,7 @@ export function runSession(options) {
|
|
|
78
79
|
throw new Error("server did not return a session id");
|
|
79
80
|
}
|
|
80
81
|
const trajectory = buildTrajectory(allEvents);
|
|
81
|
-
return Object.assign(Object.assign({ sessionId }, (continuationToken === undefined ? {} : { continuationToken })), { baseUrl, events: allEvents, trajectory, ok: trajectory.ok });
|
|
82
|
+
return Object.assign(Object.assign({ sessionId }, (continuationToken === undefined ? {} : { continuationToken })), { baseUrl, events: allEvents, trajectory, ok: trajectory.ok, nextEventIndex: allEvents.length === 0 ? undefined : nextEventIndex });
|
|
82
83
|
});
|
|
83
84
|
}
|
|
84
85
|
function runOneTurn(args) {
|
|
@@ -5,13 +5,33 @@
|
|
|
5
5
|
* settings; cloud agents use Cursor cloud (`bc-…` ids) with optional
|
|
6
6
|
* `cloud` options from `defineAgent`.
|
|
7
7
|
*/
|
|
8
|
-
import { type LocalAgentStore, type ModelSelection } from "@cursor/sdk";
|
|
8
|
+
import { type LocalAgentStore, type ModelSelection, type RunResult } from "@cursor/sdk";
|
|
9
9
|
import { type ModelSetting, type RunnerTurnRequest, type TurnOutcome } from "../types.js";
|
|
10
10
|
/** Internal seam between the session engine and the Cursor SDK harness. */
|
|
11
11
|
export interface AgentRunner {
|
|
12
12
|
runTurn(request: RunnerTurnRequest): Promise<TurnOutcome>;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a local workspace before any session needs it, so the first turn
|
|
15
|
+
* is not the one that pays for it. Best effort, hence the reported outcome:
|
|
16
|
+
* a runner that cannot warm must say so rather than let a caller log
|
|
17
|
+
* success over a workspace that was never touched.
|
|
18
|
+
*/
|
|
19
|
+
prewarm?(request: RunnerPrewarmRequest): Promise<PrewarmOutcome>;
|
|
13
20
|
dispose?(): Promise<void>;
|
|
14
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* The parts of a turn that decide which local executor it runs on. Must stay
|
|
24
|
+
* a subset of {@link RunnerTurnRequest} — anything that disagrees warms an
|
|
25
|
+
* executor no turn will ask for.
|
|
26
|
+
*/
|
|
27
|
+
export type RunnerPrewarmRequest = Pick<RunnerTurnRequest, "workspaceDir" | "runnerStateDir" | "sandbox" | "mcpServers" | "subagents" | "model">;
|
|
28
|
+
/** Whether a workspace was actually resolved, and why not when it wasn't. */
|
|
29
|
+
export type PrewarmOutcome = {
|
|
30
|
+
readonly warmed: true;
|
|
31
|
+
} | {
|
|
32
|
+
readonly warmed: false;
|
|
33
|
+
readonly reason: string;
|
|
34
|
+
};
|
|
15
35
|
export interface CursorSdkRunnerOptions {
|
|
16
36
|
/** Cursor API key. Defaults to the `CURSOR_API_KEY` environment variable. */
|
|
17
37
|
apiKey?: string;
|
|
@@ -24,14 +44,43 @@ export interface CursorSdkRunnerOptions {
|
|
|
24
44
|
/** Diagnostics for degraded paths (resume-miss fallback). */
|
|
25
45
|
logger?: (line: string) => void;
|
|
26
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* The backend's `NotLoggedIn` copy ("Authentication error" title, "try
|
|
49
|
+
* logging out and back in." detail) as it surfaces through SDK RunResults.
|
|
50
|
+
* Deliberately narrow: this gates a one-shot in-place retry, and matching
|
|
51
|
+
* broader error text would retry turns that a fresh transport cannot fix.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isAuthErrorMessage(message: string | undefined): boolean;
|
|
27
54
|
export declare class CursorSdkRunner implements AgentRunner {
|
|
28
55
|
private readonly options;
|
|
29
56
|
private readonly agents;
|
|
30
57
|
private readonly stores;
|
|
58
|
+
private readonly prewarmReleases;
|
|
31
59
|
constructor(options?: CursorSdkRunnerOptions);
|
|
32
60
|
runTurn(request: RunnerTurnRequest): Promise<TurnOutcome>;
|
|
61
|
+
private runTurnAttempt;
|
|
62
|
+
/**
|
|
63
|
+
* Build the local executor for a workspace before any session asks for it.
|
|
64
|
+
* The warmed executor is reference counted, so the lease is held until
|
|
65
|
+
* {@link dispose}; dropping it early would tear the workspace back down.
|
|
66
|
+
*/
|
|
67
|
+
prewarm(request: RunnerPrewarmRequest): Promise<PrewarmOutcome>;
|
|
33
68
|
dispose(): Promise<void>;
|
|
34
69
|
private getAgent;
|
|
70
|
+
/**
|
|
71
|
+
* Drop a cached handle and close it best-effort to release its transport
|
|
72
|
+
* and executor lease. Identity-checked so a turn that lost a race with a
|
|
73
|
+
* newer open cannot evict the replacement handle.
|
|
74
|
+
*/
|
|
75
|
+
private evictAgent;
|
|
76
|
+
private log;
|
|
77
|
+
private requireApiKey;
|
|
78
|
+
private buildSharedOptions;
|
|
79
|
+
/**
|
|
80
|
+
* The options that decide which local executor a turn runs on. Prewarming
|
|
81
|
+
* goes through here too, so a warmed workspace is the one turns land on.
|
|
82
|
+
*/
|
|
83
|
+
private buildLocalOptions;
|
|
35
84
|
private openAgent;
|
|
36
85
|
private openLocalAgent;
|
|
37
86
|
private openCloudAgent;
|
|
@@ -47,4 +96,5 @@ export declare function isServerMintedCloudAgentId(id: string): boolean;
|
|
|
47
96
|
*/
|
|
48
97
|
export declare function isLocalAgentNotFoundError(error: unknown, agentId: string): boolean;
|
|
49
98
|
export declare function toModelSelection(model: ModelSetting): ModelSelection;
|
|
99
|
+
export declare function runErrorMessage(result: Pick<RunResult, "error">): string;
|
|
50
100
|
//# sourceMappingURL=sdk-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-runner.d.ts","sourceRoot":"","sources":["../../src/internal/sdk-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,
|
|
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;AAErB,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;IAyE5B;;;;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;IAqC5B,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;AAmED,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,MAAM,CAExE"}
|
|
@@ -15,18 +15,80 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
import { mkdir } from "node:fs/promises";
|
|
18
|
-
import { Agent, JsonlLocalAgentStore, } from "@cursor/sdk";
|
|
18
|
+
import { Agent, createAgentPlatform, JsonlLocalAgentStore, } from "@cursor/sdk";
|
|
19
19
|
import { DEFAULT_MODEL, } from "../types.js";
|
|
20
|
+
/**
|
|
21
|
+
* How long one SDK agent handle (and the Connect transport inside it) may be
|
|
22
|
+
* reused before the runner retires it.
|
|
23
|
+
*
|
|
24
|
+
* The transport exchanges the account API key for a short-lived access token
|
|
25
|
+
* (`SessionType.API_KEY_TOKEN`, 60 minutes) once per handle, and has no
|
|
26
|
+
* reliable refresh: an Unauthenticated rejection on the agent's streaming RPC
|
|
27
|
+
* surfaces while the stream is being read — outside the transport's
|
|
28
|
+
* request-time 401 retry — so an expired token gets replayed on every
|
|
29
|
+
* subsequent turn until the handle is rebuilt. Long-lived sessions (watch
|
|
30
|
+
* wakes, crons) hit this at the ~60 minute mark and then fail forever.
|
|
31
|
+
* Retiring the handle comfortably before the token can expire keeps them
|
|
32
|
+
* healthy: `Agent.resume` rehydrates the same conversation from the runner
|
|
33
|
+
* store on a fresh transport, so recycling costs only transport warmth.
|
|
34
|
+
*/
|
|
35
|
+
const MAX_AGENT_HANDLE_AGE_MS = 45 * 60 * 1000;
|
|
36
|
+
/**
|
|
37
|
+
* The backend's `NotLoggedIn` copy ("Authentication error" title, "try
|
|
38
|
+
* logging out and back in." detail) as it surfaces through SDK RunResults.
|
|
39
|
+
* Deliberately narrow: this gates a one-shot in-place retry, and matching
|
|
40
|
+
* broader error text would retry turns that a fresh transport cannot fix.
|
|
41
|
+
*/
|
|
42
|
+
export function isAuthErrorMessage(message) {
|
|
43
|
+
if (message === undefined) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return /authentication error|try logging out and back in/i.test(message);
|
|
47
|
+
}
|
|
20
48
|
export class CursorSdkRunner {
|
|
21
49
|
constructor(options = {}) {
|
|
22
50
|
this.options = options;
|
|
23
51
|
this.agents = new Map();
|
|
24
52
|
this.stores = new Map();
|
|
53
|
+
this.prewarmReleases = [];
|
|
25
54
|
}
|
|
26
55
|
runTurn(request) {
|
|
27
56
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
var _a;
|
|
58
|
+
let sawUpdate = false;
|
|
59
|
+
const tracked = Object.assign(Object.assign({}, request), { onUpdate: (update) => {
|
|
60
|
+
sawUpdate = true;
|
|
61
|
+
return request.onUpdate(update);
|
|
62
|
+
} });
|
|
63
|
+
const outcome = yield this.runTurnAttempt(tracked);
|
|
64
|
+
if (outcome.status !== "error" ||
|
|
65
|
+
!isAuthErrorMessage(outcome.errorMessage) ||
|
|
66
|
+
sawUpdate ||
|
|
67
|
+
request.isFirstTurn ||
|
|
68
|
+
((_a = request.signal) === null || _a === void 0 ? void 0 : _a.aborted) === true) {
|
|
69
|
+
return outcome;
|
|
70
|
+
}
|
|
71
|
+
// The turn died on an authentication failure before producing any output
|
|
72
|
+
// — the signature of a handle whose exchanged access token expired (the
|
|
73
|
+
// failed attempt already evicted it). Retrying once on a fresh handle is
|
|
74
|
+
// safe here because nothing streamed and no tool ran. First turns are
|
|
75
|
+
// excluded: their token was exchanged moments ago, so the credential
|
|
76
|
+
// itself is the problem and a retry cannot succeed.
|
|
77
|
+
this.log(`[agentkit] session ${request.sessionId}: retrying the turn on a fresh SDK agent handle after an authentication failure`);
|
|
28
78
|
try {
|
|
29
|
-
|
|
79
|
+
return yield this.runTurnAttempt(tracked);
|
|
80
|
+
}
|
|
81
|
+
catch (_b) {
|
|
82
|
+
// The retry was best effort; report the original failure.
|
|
83
|
+
return outcome;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
runTurnAttempt(request) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const agentPromise = this.getAgent(request);
|
|
90
|
+
try {
|
|
91
|
+
const agent = yield agentPromise;
|
|
30
92
|
const run = yield agent.send(request.prompt, Object.assign({ onDelta: (_a) => __awaiter(this, [_a], void 0, function* ({ update }) {
|
|
31
93
|
try {
|
|
32
94
|
yield request.onUpdate(update);
|
|
@@ -65,7 +127,17 @@ export class CursorSdkRunner {
|
|
|
65
127
|
}
|
|
66
128
|
try {
|
|
67
129
|
const result = yield run.wait();
|
|
68
|
-
|
|
130
|
+
const outcome = toTurnOutcome(result);
|
|
131
|
+
if (outcome.status === "error") {
|
|
132
|
+
// An error result usually means the handle's transport is poisoned
|
|
133
|
+
// — most often a cached access token that aged past its 60-minute
|
|
134
|
+
// lifetime and gets replayed on every request (stream failures
|
|
135
|
+
// bypass the transport's 401 retry). Retire the handle so the next
|
|
136
|
+
// attempt resumes the conversation from the store on a fresh
|
|
137
|
+
// transport instead of failing every turn until a restart.
|
|
138
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
139
|
+
}
|
|
140
|
+
return outcome;
|
|
69
141
|
}
|
|
70
142
|
finally {
|
|
71
143
|
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
@@ -74,14 +146,36 @@ export class CursorSdkRunner {
|
|
|
74
146
|
catch (error) {
|
|
75
147
|
// Drop the cached agent so a dead Connect/HTTP2 session cannot poison
|
|
76
148
|
// the next turn (terminal/shell overflow often kills the transport).
|
|
77
|
-
this.
|
|
149
|
+
this.evictAgent(request.sessionId, agentPromise);
|
|
78
150
|
throw error;
|
|
79
151
|
}
|
|
80
152
|
});
|
|
81
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Build the local executor for a workspace before any session asks for it.
|
|
156
|
+
* The warmed executor is reference counted, so the lease is held until
|
|
157
|
+
* {@link dispose}; dropping it early would tear the workspace back down.
|
|
158
|
+
*/
|
|
159
|
+
prewarm(request) {
|
|
160
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
161
|
+
const platform = (yield createAgentPlatform());
|
|
162
|
+
if (typeof platform.prewarmLocalWorkspace !== "function") {
|
|
163
|
+
// Older @cursor/sdk. Turns still work; they just pay on the first one.
|
|
164
|
+
return {
|
|
165
|
+
warmed: false,
|
|
166
|
+
reason: "the installed @cursor/sdk has no prewarmLocalWorkspace; upgrade it to warm the workspace before the first turn",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const release = yield platform.prewarmLocalWorkspace(yield this.buildLocalOptions(request));
|
|
170
|
+
this.prewarmReleases.push(release);
|
|
171
|
+
return { warmed: true };
|
|
172
|
+
});
|
|
173
|
+
}
|
|
82
174
|
dispose() {
|
|
83
175
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
const
|
|
176
|
+
const releases = this.prewarmReleases.splice(0);
|
|
177
|
+
yield Promise.allSettled(releases.map((release) => release()));
|
|
178
|
+
const agents = yield Promise.allSettled([...this.agents.values()].map((handle) => handle.agent));
|
|
85
179
|
this.agents.clear();
|
|
86
180
|
for (const settled of agents) {
|
|
87
181
|
if (settled.status === "fulfilled") {
|
|
@@ -91,47 +185,89 @@ export class CursorSdkRunner {
|
|
|
91
185
|
});
|
|
92
186
|
}
|
|
93
187
|
getAgent(request) {
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
this
|
|
188
|
+
const cached = this.agents.get(request.sessionId);
|
|
189
|
+
if (cached !== undefined) {
|
|
190
|
+
const ageMs = Date.now() - cached.openedAtMs;
|
|
191
|
+
if (ageMs < MAX_AGENT_HANDLE_AGE_MS) {
|
|
192
|
+
return cached.agent;
|
|
193
|
+
}
|
|
194
|
+
// Past this age the handle's exchanged access token could expire
|
|
195
|
+
// mid-turn. Retire it and reopen below on a fresh transport.
|
|
196
|
+
this.log(`[agentkit] session ${request.sessionId}: recycling the SDK agent handle after ${Math.round(ageMs / 60000)} min so the turn runs on a fresh access token`);
|
|
197
|
+
this.evictAgent(request.sessionId, cached.agent);
|
|
101
198
|
}
|
|
199
|
+
const agentPromise = this.openAgent(request).catch((error) => {
|
|
200
|
+
// Nothing opened, so there is no handle to close — just free the slot.
|
|
201
|
+
this.agents.delete(request.sessionId);
|
|
202
|
+
throw error;
|
|
203
|
+
});
|
|
204
|
+
this.agents.set(request.sessionId, {
|
|
205
|
+
agent: agentPromise,
|
|
206
|
+
openedAtMs: Date.now(),
|
|
207
|
+
});
|
|
102
208
|
return agentPromise;
|
|
103
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Drop a cached handle and close it best-effort to release its transport
|
|
212
|
+
* and executor lease. Identity-checked so a turn that lost a race with a
|
|
213
|
+
* newer open cannot evict the replacement handle.
|
|
214
|
+
*/
|
|
215
|
+
evictAgent(sessionId, agent) {
|
|
216
|
+
const cached = this.agents.get(sessionId);
|
|
217
|
+
if (cached === undefined || cached.agent !== agent) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
this.agents.delete(sessionId);
|
|
221
|
+
void cached.agent.then((sdkAgent) => sdkAgent.close()).catch(() => { });
|
|
222
|
+
}
|
|
223
|
+
log(line) {
|
|
224
|
+
var _a;
|
|
225
|
+
((_a = this.options.logger) !== null && _a !== void 0 ? _a : (() => { }))(line);
|
|
226
|
+
}
|
|
227
|
+
requireApiKey() {
|
|
228
|
+
var _a;
|
|
229
|
+
const apiKey = (_a = this.options.apiKey) !== null && _a !== void 0 ? _a : process.env.CURSOR_API_KEY;
|
|
230
|
+
if (apiKey === undefined || apiKey.trim() === "") {
|
|
231
|
+
throw new Error("The Cursor SDK runner requires a Cursor credential: run `agent-serve login`, set CURSOR_API_KEY, or pass serve({ apiKey }).");
|
|
232
|
+
}
|
|
233
|
+
return apiKey;
|
|
234
|
+
}
|
|
235
|
+
buildSharedOptions(request) {
|
|
236
|
+
var _a;
|
|
237
|
+
const subagents = toAgentDefinitions(request.subagents);
|
|
238
|
+
return Object.assign(Object.assign({ model: toModelSelection((_a = request.model) !== null && _a !== void 0 ? _a : DEFAULT_MODEL), apiKey: this.requireApiKey() }, (Object.keys(request.mcpServers).length > 0
|
|
239
|
+
? { mcpServers: request.mcpServers }
|
|
240
|
+
: {})), (subagents === undefined ? {} : { agents: subagents }));
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The options that decide which local executor a turn runs on. Prewarming
|
|
244
|
+
* goes through here too, so a warmed workspace is the one turns land on.
|
|
245
|
+
*/
|
|
246
|
+
buildLocalOptions(request) {
|
|
247
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
248
|
+
var _a;
|
|
249
|
+
const store = (_a = this.options.store) !== null && _a !== void 0 ? _a : (yield this.getStore(request.runnerStateDir));
|
|
250
|
+
return Object.assign(Object.assign({}, this.buildSharedOptions(request)), { local: Object.assign({ cwd: request.workspaceDir, settingSources: ["project"], store }, (request.sandbox === true
|
|
251
|
+
? { sandboxOptions: { enabled: true } }
|
|
252
|
+
: {})) });
|
|
253
|
+
});
|
|
254
|
+
}
|
|
104
255
|
openAgent(request) {
|
|
105
256
|
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
-
var _a, _b;
|
|
107
|
-
const apiKey = (_a = this.options.apiKey) !== null && _a !== void 0 ? _a : process.env.CURSOR_API_KEY;
|
|
108
|
-
if (apiKey === undefined || apiKey.trim() === "") {
|
|
109
|
-
throw new Error("The Cursor SDK runner requires a Cursor credential: run `agent-serve login`, set CURSOR_API_KEY, or pass serve({ apiKey }).");
|
|
110
|
-
}
|
|
111
|
-
const model = (_b = request.model) !== null && _b !== void 0 ? _b : DEFAULT_MODEL;
|
|
112
|
-
const subagents = toAgentDefinitions(request.subagents);
|
|
113
|
-
const shared = Object.assign(Object.assign({ model: toModelSelection(model), apiKey }, (Object.keys(request.mcpServers).length > 0
|
|
114
|
-
? { mcpServers: request.mcpServers }
|
|
115
|
-
: {})), (subagents === undefined ? {} : { agents: subagents }));
|
|
116
257
|
if (request.runtime === "cloud") {
|
|
117
|
-
return this.openCloudAgent(request,
|
|
258
|
+
return this.openCloudAgent(request, this.buildSharedOptions(request));
|
|
118
259
|
}
|
|
119
|
-
return this.openLocalAgent(request
|
|
260
|
+
return this.openLocalAgent(request);
|
|
120
261
|
});
|
|
121
262
|
}
|
|
122
|
-
openLocalAgent(request
|
|
263
|
+
openLocalAgent(request) {
|
|
123
264
|
return __awaiter(this, void 0, void 0, function* () {
|
|
124
|
-
var _a, _b
|
|
125
|
-
const
|
|
126
|
-
const options = Object.assign(Object.assign({}, shared), { local: {
|
|
127
|
-
cwd: request.workspaceDir,
|
|
128
|
-
settingSources: ["project"],
|
|
129
|
-
store,
|
|
130
|
-
} });
|
|
265
|
+
var _a, _b;
|
|
266
|
+
const options = yield this.buildLocalOptions(request);
|
|
131
267
|
if (request.isFirstTurn || request.sdkAgentId === undefined) {
|
|
132
|
-
return Agent.create(Object.assign(Object.assign({}, options), { agentId: (
|
|
268
|
+
return Agent.create(Object.assign(Object.assign({}, options), { agentId: (_a = request.sdkAgentId) !== null && _a !== void 0 ? _a : request.sessionId }));
|
|
133
269
|
}
|
|
134
|
-
const agentId = (
|
|
270
|
+
const agentId = (_b = request.sdkAgentId) !== null && _b !== void 0 ? _b : request.sessionId;
|
|
135
271
|
try {
|
|
136
272
|
return yield Agent.resume(agentId, options);
|
|
137
273
|
}
|
|
@@ -144,7 +280,7 @@ export class CursorSdkRunner {
|
|
|
144
280
|
// conversation under the same id beats failing this thread's turns
|
|
145
281
|
// forever ("Agent … not found" on every follow-up). The channel's
|
|
146
282
|
// warm-turn prompt context re-hydrates the thread history.
|
|
147
|
-
|
|
283
|
+
this.log(`[agentkit] no stored conversation for ${agentId} on this host; starting a fresh one`);
|
|
148
284
|
return Agent.create(Object.assign(Object.assign({}, options), { agentId }));
|
|
149
285
|
}
|
|
150
286
|
});
|
|
@@ -242,6 +378,10 @@ function toTurnOutcome(result) {
|
|
|
242
378
|
? {}
|
|
243
379
|
: { reasoningTokens: result.usage.reasoningTokens }));
|
|
244
380
|
return Object.assign(Object.assign(Object.assign({ status: result.status }, (result.result === undefined ? {} : { result: result.result })), (result.status === "error"
|
|
245
|
-
? { errorMessage:
|
|
381
|
+
? { errorMessage: runErrorMessage(result) }
|
|
246
382
|
: {})), (usage === undefined ? {} : { usage }));
|
|
247
383
|
}
|
|
384
|
+
export function runErrorMessage(result) {
|
|
385
|
+
var _a, _b;
|
|
386
|
+
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";
|
|
387
|
+
}
|
|
@@ -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;AAqFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,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,
|
|
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;AAqFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,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,CA2pB3B"}
|
package/dist/internal/server.js
CHANGED
|
@@ -241,6 +241,11 @@ export function startServer(mounts_1) {
|
|
|
241
241
|
// Rehydrate sessions from the authored storage sink before any
|
|
242
242
|
// channel or route can address them (continuation tokens must resolve).
|
|
243
243
|
yield engine.restoreStoredSessions();
|
|
244
|
+
// Resolve a shared harness workspace in the background: on a large repo
|
|
245
|
+
// that takes seconds, and a deployment coming online should absorb it
|
|
246
|
+
// rather than whoever sends the first message. No-op unless the agent
|
|
247
|
+
// pins `local.workspaceDir`.
|
|
248
|
+
void engine.prewarmSharedWorkspace();
|
|
244
249
|
if (!githubAuthWarmed) {
|
|
245
250
|
// Soft ambient GitHub auth check before channel onStart (which may call
|
|
246
251
|
// host.github). Missing auth is a warning only — serve still starts.
|
|
@@ -263,6 +268,7 @@ export function startServer(mounts_1) {
|
|
|
263
268
|
list: (filter) => reminderRunner.list(filter),
|
|
264
269
|
cancel: (id, reason) => reminderRunner.cancel(id, reason),
|
|
265
270
|
cancelForContinuation: (token, reason) => reminderRunner.cancelForContinuation(token, reason),
|
|
271
|
+
rekeyContinuation: (channelId, oldToken, newToken) => reminderRunner.rekeyContinuation(channelId, oldToken, newToken),
|
|
266
272
|
dispatch: (id) => reminderRunner.dispatch(id),
|
|
267
273
|
});
|
|
268
274
|
engine.setEvals({
|
|
@@ -687,7 +693,11 @@ function mountAgentRoutes(router, runtime, args) {
|
|
|
687
693
|
method: "GET",
|
|
688
694
|
pattern: `${base}/v1/meta`,
|
|
689
695
|
auth: "none",
|
|
690
|
-
handler: () => jsonResponse(Object.assign({ name: project.name, dev, basePath: base
|
|
696
|
+
handler: () => jsonResponse(Object.assign({ name: project.name, dev, basePath: base,
|
|
697
|
+
// Framework version, for SPA/engine skew observability now that the
|
|
698
|
+
// hosted playground shell is served centrally (backend deploys)
|
|
699
|
+
// while engines stay on their install-time version.
|
|
700
|
+
version: packageVersion() }, (multi ? { indexPath: "/" } : {}))),
|
|
691
701
|
});
|
|
692
702
|
router.add({
|
|
693
703
|
method: "GET",
|
|
@@ -227,15 +227,28 @@ export declare class SessionEngine {
|
|
|
227
227
|
getContinuationLastBotMessageTs(channelId: string, continuationToken: string): Promise<string | undefined>;
|
|
228
228
|
interruptContinuation(channelId: string, continuationToken: string): Promise<boolean>;
|
|
229
229
|
/**
|
|
230
|
-
* Local harness cwd for a session: per-send override, else
|
|
231
|
-
* `<agent.local.cwd>/<sessionId>`, else
|
|
230
|
+
* Local harness cwd for a session: per-send override, else the shared
|
|
231
|
+
* `agent.local.workspaceDir`, else `<agent.local.cwd>/<sessionId>`, else
|
|
232
|
+
* the durable session workspace.
|
|
232
233
|
*/
|
|
233
234
|
harnessCwd(record: SessionRecord): string;
|
|
234
235
|
/**
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
236
|
+
* True when the harness cwd is a directory the session does not own — a
|
|
237
|
+
* per-send override (e.g. a PR worktree) or a workspace shared by every
|
|
238
|
+
* session. Agent scaffold has to stay out of those, so it lands in the
|
|
239
|
+
* durable session workspace and the instructions travel inline instead.
|
|
238
240
|
*/
|
|
241
|
+
private hasBorrowedWorkspace;
|
|
242
|
+
/**
|
|
243
|
+
* Resolve the shared harness workspace during startup, so the first session
|
|
244
|
+
* is not the one that waits for it. Only possible with
|
|
245
|
+
* `local.workspaceDir`: every other layout gives a session its own cwd,
|
|
246
|
+
* which is unknowable until that session exists.
|
|
247
|
+
*
|
|
248
|
+
* Best effort — warming is an optimization, and a turn rebuilds on its own.
|
|
249
|
+
*/
|
|
250
|
+
prewarmSharedWorkspace(): Promise<void>;
|
|
251
|
+
/** Directory that receives AGENTS.md / skills / agent tools. */
|
|
239
252
|
private scaffoldDir;
|
|
240
253
|
private executeTurn;
|
|
241
254
|
private buildTurnRequest;
|