pi-cursor-sdk 0.1.62 → 0.3.6
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/CHANGELOG.md +85 -0
- package/README.md +57 -53
- package/dist/bundled-context-windows.js +39 -0
- package/dist/context-window-cache.js +92 -0
- package/dist/context.js +338 -0
- package/dist/cursor-active-tools.js +3 -0
- package/dist/cursor-agent-message-web-tools.js +165 -0
- package/dist/cursor-agents-context-registration.js +17 -0
- package/dist/cursor-agents-context.js +113 -0
- package/dist/cursor-api-key.js +34 -0
- package/dist/cursor-bridge-contract.js +27 -0
- package/dist/cursor-cloud-lifecycle.js +650 -0
- package/dist/cursor-cloud-local-state.js +460 -0
- package/dist/cursor-cloud-options.js +145 -0
- package/dist/cursor-cloud-reporting.js +222 -0
- package/dist/cursor-compact-tool-summary.js +75 -0
- package/dist/cursor-config.js +613 -0
- package/dist/cursor-context-tools.js +4 -0
- package/dist/cursor-display-only-trace.js +11 -0
- package/dist/cursor-display-text.js +18 -0
- package/dist/cursor-durable-fs.js +53 -0
- package/dist/cursor-edit-diff.js +13 -0
- package/dist/cursor-env-boolean.js +19 -0
- package/dist/cursor-fallback-models.generated.js +7760 -0
- package/dist/cursor-fallback-warning.js +15 -0
- package/dist/cursor-http1.js +45 -0
- package/dist/cursor-incomplete-tool-visibility.js +83 -0
- package/dist/cursor-live-run-accounting.js +55 -0
- package/dist/cursor-live-run-coordinator.js +406 -0
- package/dist/cursor-mcp-timeout-override.js +116 -0
- package/dist/cursor-model-lifecycle.js +32 -0
- package/dist/cursor-model.js +5 -0
- package/dist/cursor-native-replay-routing.js +35 -0
- package/dist/cursor-native-replay-trace.js +28 -0
- package/dist/cursor-native-tool-display-registration.js +102 -0
- package/dist/cursor-native-tool-display-replay.js +428 -0
- package/dist/cursor-native-tool-display-state.js +70 -0
- package/dist/cursor-native-tool-display-tools.js +123 -0
- package/dist/cursor-native-tool-names.js +11 -0
- package/dist/cursor-partial-content-emitter.js +118 -0
- package/dist/cursor-pi-tool-bridge-abort.js +114 -0
- package/dist/cursor-pi-tool-bridge-constants.js +6 -0
- package/dist/cursor-pi-tool-bridge-diagnostics.js +125 -0
- package/dist/cursor-pi-tool-bridge-env.js +18 -0
- package/dist/cursor-pi-tool-bridge-mcp.js +100 -0
- package/dist/cursor-pi-tool-bridge-run.js +355 -0
- package/dist/cursor-pi-tool-bridge-server.js +163 -0
- package/dist/cursor-pi-tool-bridge-snapshot.js +63 -0
- package/dist/cursor-pi-tool-bridge-types.js +1 -0
- package/dist/cursor-pi-tool-bridge.js +123 -0
- package/dist/cursor-provider-errors.js +311 -0
- package/dist/cursor-provider-lazy.js +39 -0
- package/dist/cursor-provider-live-run-drain.js +412 -0
- package/dist/cursor-provider-overflow.js +90 -0
- package/dist/cursor-provider-run-finalizer.js +176 -0
- package/dist/cursor-provider-run-outcome.js +76 -0
- package/dist/cursor-provider-turn-coordinator.js +275 -0
- package/dist/cursor-provider-turn-display-router.js +158 -0
- package/dist/cursor-provider-turn-emit.js +35 -0
- package/dist/cursor-provider-turn-finalize.js +154 -0
- package/dist/cursor-provider-turn-lifecycle-emitter.js +126 -0
- package/dist/cursor-provider-turn-prepare.js +374 -0
- package/dist/cursor-provider-turn-runner.js +146 -0
- package/dist/cursor-provider-turn-sdk-normalizer.js +74 -0
- package/dist/cursor-provider-turn-send.js +138 -0
- package/dist/cursor-provider-turn-shell-output.js +117 -0
- package/dist/cursor-provider-turn-tool-ledger.js +99 -0
- package/dist/cursor-provider-turn-types.js +1 -0
- package/dist/cursor-provider.js +72 -0
- package/dist/cursor-question-tool.js +194 -0
- package/dist/cursor-record-utils.js +61 -0
- package/dist/cursor-replay-activity-builders.js +114 -0
- package/dist/cursor-replay-source-names.js +27 -0
- package/dist/cursor-replay-summary-args.js +105 -0
- package/dist/cursor-replay-tool-details.js +167 -0
- package/dist/cursor-ripgrep-path.js +27 -0
- package/dist/cursor-run-final-text.js +63 -0
- package/dist/cursor-runtime-state.js +380 -0
- package/dist/cursor-sdk-billed-usage.js +86 -0
- package/dist/cursor-sdk-event-debug-constants.js +33 -0
- package/dist/cursor-sdk-event-debug-session.js +107 -0
- package/dist/cursor-sdk-event-debug.js +461 -0
- package/dist/cursor-sdk-output-filter.js +1 -0
- package/dist/cursor-sdk-process-error-guard.js +221 -0
- package/dist/cursor-sdk-runtime.js +3 -0
- package/dist/cursor-sensitive-text.js +23 -0
- package/dist/cursor-session-agent-cleanup.js +311 -0
- package/dist/cursor-session-agent-lifecycle.js +32 -0
- package/dist/cursor-session-agent-lineage.js +103 -0
- package/dist/cursor-session-agent-resume.js +417 -0
- package/dist/cursor-session-agent.js +507 -0
- package/dist/cursor-session-compaction-prep.js +21 -0
- package/dist/cursor-session-scope.js +113 -0
- package/dist/cursor-session-send-policy.js +18 -0
- package/dist/cursor-session-store.js +105 -0
- package/dist/cursor-session-turn-queue.js +50 -0
- package/dist/cursor-setting-sources.js +15 -0
- package/dist/cursor-skill-tool.js +230 -0
- package/dist/cursor-state.js +519 -0
- package/dist/cursor-task-presentation.js +59 -0
- package/dist/cursor-tool-lifecycle.js +94 -0
- package/dist/cursor-tool-manifest.js +34 -0
- package/dist/cursor-tool-presentation-registry.js +305 -0
- package/dist/cursor-tool-result-display-readers.js +158 -0
- package/dist/cursor-tool-transcript.js +32 -0
- package/dist/cursor-tool-visibility.js +28 -0
- package/dist/cursor-transcript-tool-formatters.js +618 -0
- package/dist/cursor-transcript-tool-specs.js +284 -0
- package/dist/cursor-transcript-utils.js +170 -0
- package/dist/cursor-usage-accounting.js +166 -0
- package/dist/cursor-web-tool-activity.js +23 -0
- package/dist/cursor-web-tool-args.js +12 -0
- package/dist/index.js +82 -0
- package/dist/model-discovery.js +305 -0
- package/dist/model-list-cache.js +156 -0
- package/docs/cursor-dogfood-checklist.md +2 -1
- package/docs/cursor-live-smoke-checklist.md +15 -14
- package/docs/cursor-model-ux-spec.md +29 -8
- package/docs/cursor-native-tool-replay.md +13 -13
- package/docs/cursor-native-tool-visual-audit.md +6 -3
- package/docs/cursor-testing-lessons.md +7 -7
- package/docs/cursor-tool-surfaces.md +5 -5
- package/docs/platform-smoke.md +6 -6
- package/node_modules/fast-uri/index.js +37 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +136 -0
- package/node_modules/hono/dist/cjs/context.js +28 -13
- package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/cjs/hono-base.js +3 -2
- package/node_modules/hono/dist/cjs/jsx/base.js +27 -23
- package/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +7 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/cjs/router.js +1 -1
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/cookie.js +3 -2
- package/node_modules/hono/dist/cjs/utils/url.js +8 -8
- package/node_modules/hono/dist/context.js +28 -13
- package/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/hono-base.js +3 -2
- package/node_modules/hono/dist/jsx/base.js +27 -23
- package/node_modules/hono/dist/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -10
- package/node_modules/hono/dist/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/router.js +1 -1
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/client/types.d.ts +1 -1
- package/node_modules/hono/dist/types/hono-base.d.ts +4 -3
- package/node_modules/hono/dist/types/jsx/base.d.ts +4 -2
- package/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
- package/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
- package/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
- package/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
- package/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
- package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +1 -1
- package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
- package/node_modules/hono/dist/types/router.d.ts +1 -1
- package/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/cookie.js +4 -3
- package/node_modules/hono/dist/utils/url.js +6 -7
- package/node_modules/hono/package.json +10 -3
- package/node_modules/ip-address/README.md +146 -126
- package/node_modules/ip-address/dist/common.d.ts +29 -0
- package/node_modules/ip-address/dist/common.js +44 -5
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +8 -1
- package/node_modules/ip-address/dist/ipv4.js +24 -20
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +68 -3
- package/node_modules/ip-address/dist/ipv6.js +180 -53
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.js +5 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +3 -2
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +6 -4
- package/package.json +23 -11
- package/platform-smoke.config.mjs +1 -1
- package/scripts/build.mjs +126 -0
- package/scripts/cloud-runtime-smoke.mjs +3 -1
- package/scripts/debug-provider-events.mjs +3 -1
- package/scripts/debug-sdk-events.mjs +1 -1
- package/scripts/isolated-cursor-smoke.sh +5 -4
- package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +1 -1
- package/scripts/lib/cursor-visual-render.mjs +1 -1
- package/scripts/lib/ensure-built.mjs +16 -0
- package/scripts/lib/local-resume-smoke-harness.mjs +1 -1
- package/scripts/local-resume-smoke.mjs +3 -1
- package/scripts/platform-smoke/card-detect.mjs +1 -1
- package/scripts/platform-smoke/live-suite-runner.mjs +16 -40
- package/scripts/platform-smoke/platform-build-windows.ps1 +1 -1
- package/scripts/platform-smoke/render-ansi.mjs +1 -1
- package/scripts/platform-smoke/scenarios.mjs +1 -1
- package/scripts/platform-smoke/targets.mjs +2 -2
- package/scripts/platform-smoke.mjs +5 -5
- package/scripts/prepare.mjs +102 -0
- package/scripts/refresh-cursor-model-snapshots.mjs +16 -7
- package/scripts/steering-rpc-smoke.mjs +4 -2
- package/scripts/tmux-live-smoke.sh +11 -11
- package/scripts/visual-tui-smoke-self-test.mjs +4 -1
- package/scripts/visual-tui-smoke.mjs +51 -7
- package/shared/cursor-model-selection-identities.d.mts +21 -0
- package/shared/cursor-model-selection-identities.mjs +95 -0
- package/src/bundled-context-windows.ts +21 -12
- package/src/context.ts +1 -1
- package/src/cursor-agents-context-registration.ts +2 -2
- package/src/cursor-agents-context.ts +0 -2
- package/src/cursor-api-key.ts +5 -4
- package/src/cursor-cloud-reporting.ts +23 -2
- package/src/cursor-context-tools.ts +1 -1
- package/src/cursor-display-only-trace.ts +1 -1
- package/src/cursor-fallback-models.generated.ts +1726 -824
- package/src/cursor-live-run-accounting.ts +1 -1
- package/src/cursor-live-run-coordinator.ts +2 -1
- package/src/cursor-native-replay-routing.ts +1 -1
- package/src/cursor-native-tool-display-registration.ts +10 -11
- package/src/cursor-partial-content-emitter.ts +1 -1
- package/src/cursor-pi-tool-bridge-mcp.ts +1 -1
- package/src/cursor-pi-tool-bridge-run.ts +1 -1
- package/src/cursor-pi-tool-bridge-types.ts +1 -1
- package/src/cursor-provider-errors.ts +1 -1
- package/src/cursor-provider-lazy.ts +6 -5
- package/src/cursor-provider-live-run-drain.ts +2 -1
- package/src/cursor-provider-overflow.ts +1 -1
- package/src/cursor-provider-run-finalizer.ts +2 -1
- package/src/cursor-provider-turn-coordinator.ts +1 -1
- package/src/cursor-provider-turn-finalize.ts +12 -0
- package/src/cursor-provider-turn-lifecycle-emitter.ts +1 -1
- package/src/cursor-provider-turn-prepare.ts +1 -1
- package/src/cursor-provider-turn-types.ts +3 -1
- package/src/cursor-provider.ts +1 -1
- package/src/cursor-run-final-text.ts +1 -1
- package/src/cursor-sdk-billed-usage.ts +107 -0
- package/src/cursor-sdk-event-debug.ts +1 -1
- package/src/cursor-sdk-process-error-guard.ts +6 -4
- package/src/cursor-session-agent-lifecycle.ts +8 -9
- package/src/cursor-session-agent-resume.ts +23 -0
- package/src/cursor-session-agent.ts +1 -1
- package/src/cursor-session-compaction-prep.ts +4 -0
- package/src/cursor-session-send-policy.ts +1 -1
- package/src/cursor-tool-manifest.ts +1 -1
- package/src/cursor-usage-accounting.ts +71 -10
- package/src/index.ts +1 -1
- package/src/model-discovery.ts +32 -89
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +16 -0
- package/node_modules/cross-spawn/node_modules/which/CHANGELOG.md +0 -166
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Api, AssistantMessage, Context, Model } from "@earendil-works/pi-ai
|
|
1
|
+
import type { Api, AssistantMessage, Context, Model } from "@earendil-works/pi-ai";
|
|
2
2
|
import {
|
|
3
3
|
CURSOR_APPROX_CHARS_PER_TOKEN,
|
|
4
4
|
CURSOR_IMAGE_TOKEN_ESTIMATE,
|
|
@@ -91,18 +91,30 @@ function getCursorSdkUncachedInputTokens(turnUsage: CursorSdkTurnUsage): number
|
|
|
91
91
|
return turnUsage.inputTokens - turnUsage.cacheReadTokens - turnUsage.cacheWriteTokens;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
export function
|
|
94
|
+
export function isCursorSdkUsagePartitionSafe(turnUsage: CursorSdkTurnUsage, model: Model<Api>): boolean {
|
|
95
95
|
const counts = [turnUsage.inputTokens, turnUsage.outputTokens, turnUsage.cacheReadTokens, turnUsage.cacheWriteTokens];
|
|
96
96
|
const uncachedInput = getCursorSdkUncachedInputTokens(turnUsage);
|
|
97
97
|
return (
|
|
98
98
|
counts.every((count) => Number.isFinite(count) && count >= 0) &&
|
|
99
99
|
Number.isFinite(uncachedInput) &&
|
|
100
100
|
uncachedInput >= 0 &&
|
|
101
|
-
turnUsage.outputTokens <= model.maxTokens
|
|
101
|
+
turnUsage.outputTokens <= model.maxTokens
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function isCursorSdkUsageSafeForPiMessage(turnUsage: CursorSdkTurnUsage, model: Model<Api>): boolean {
|
|
106
|
+
return (
|
|
107
|
+
isCursorSdkUsagePartitionSafe(turnUsage, model) &&
|
|
102
108
|
turnUsage.inputTokens + turnUsage.outputTokens <= model.contextWindow
|
|
103
109
|
);
|
|
104
110
|
}
|
|
105
111
|
|
|
112
|
+
export interface CursorSdkUsageApplyOptions {
|
|
113
|
+
runtime: CursorRuntime;
|
|
114
|
+
turn?: CursorSdkTurnUsage;
|
|
115
|
+
billed?: CursorSdkTurnUsage;
|
|
116
|
+
}
|
|
117
|
+
|
|
106
118
|
export function applyCursorSdkUsage(partial: AssistantMessage, turnUsage: CursorSdkTurnUsage): void {
|
|
107
119
|
// Pi treats input/cacheRead/cacheWrite as disjoint additive prompt components.
|
|
108
120
|
partial.usage.input = getCursorSdkUncachedInputTokens(turnUsage);
|
|
@@ -117,8 +129,23 @@ function isCompatibleCursorAssistantMeasurement(assistant: AssistantMessage, mod
|
|
|
117
129
|
return assistant.api === model.api && assistant.provider === model.provider && assistant.model === model.id;
|
|
118
130
|
}
|
|
119
131
|
|
|
132
|
+
function getLatestCompactionBoundary(context: Context): { index: number; tokensBefore?: number } | undefined {
|
|
133
|
+
for (let index = context.messages.length - 1; index >= 0; index -= 1) {
|
|
134
|
+
const message = context.messages[index] as { role?: string; tokensBefore?: number };
|
|
135
|
+
if (message.role !== "compactionSummary") continue;
|
|
136
|
+
const tokensBefore = message.tokensBefore;
|
|
137
|
+
return {
|
|
138
|
+
index,
|
|
139
|
+
tokensBefore: Number.isFinite(tokensBefore) && tokensBefore !== undefined && tokensBefore > 0 ? Math.floor(tokensBefore) : undefined,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
|
|
120
145
|
function getLastAcceptedContextOccupancy(context: Context, model: Model<Api>): number {
|
|
146
|
+
const boundary = getLatestCompactionBoundary(context);
|
|
121
147
|
for (let index = context.messages.length - 1; index >= 0; index -= 1) {
|
|
148
|
+
if (boundary && index < boundary.index) break;
|
|
122
149
|
const message = context.messages[index];
|
|
123
150
|
if (message.role !== "assistant" || !("usage" in message)) continue;
|
|
124
151
|
const assistant = message as AssistantMessage;
|
|
@@ -127,7 +154,9 @@ function getLastAcceptedContextOccupancy(context: Context, model: Model<Api>): n
|
|
|
127
154
|
const { usage } = assistant;
|
|
128
155
|
const total =
|
|
129
156
|
usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
130
|
-
if (Number.isFinite(total)
|
|
157
|
+
if (!Number.isFinite(total) || total <= 0 || total > model.contextWindow) continue;
|
|
158
|
+
if (boundary?.tokensBefore !== undefined && total >= boundary.tokensBefore) continue;
|
|
159
|
+
return total;
|
|
131
160
|
}
|
|
132
161
|
return 0;
|
|
133
162
|
}
|
|
@@ -146,18 +175,50 @@ export function applyCursorApproximateUsage(partial: AssistantMessage, model: Mo
|
|
|
146
175
|
);
|
|
147
176
|
}
|
|
148
177
|
|
|
178
|
+
function applyCursorOccupancyEstimate(partial: AssistantMessage, model: Model<Api>, context: Context): void {
|
|
179
|
+
partial.usage.totalTokens = Math.max(
|
|
180
|
+
estimateCursorContextTotalTokens(partial, model, context),
|
|
181
|
+
getLastAcceptedContextOccupancy(context, model),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function isCurrentLocalOccupancy(turn: CursorSdkTurnUsage, model: Model<Api>, context: Context): boolean {
|
|
186
|
+
if (!isCursorSdkUsageSafeForPiMessage(turn, model)) return false;
|
|
187
|
+
const tokensBefore = getLatestCompactionBoundary(context)?.tokensBefore;
|
|
188
|
+
return tokensBefore === undefined || turn.inputTokens + turn.outputTokens < tokensBefore;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function applyResolvedCursorOccupancy(
|
|
192
|
+
partial: AssistantMessage,
|
|
193
|
+
model: Model<Api>,
|
|
194
|
+
context: Context,
|
|
195
|
+
localTurn: CursorSdkTurnUsage | undefined,
|
|
196
|
+
): void {
|
|
197
|
+
if (localTurn && isCurrentLocalOccupancy(localTurn, model, context)) {
|
|
198
|
+
partial.usage.totalTokens = localTurn.inputTokens + localTurn.outputTokens;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
applyCursorOccupancyEstimate(partial, model, context);
|
|
202
|
+
}
|
|
203
|
+
|
|
149
204
|
export function applyCursorUsage(
|
|
150
205
|
partial: AssistantMessage,
|
|
151
206
|
model: Model<Api>,
|
|
152
207
|
context: Context,
|
|
153
208
|
sessionInputTokens: number,
|
|
154
|
-
sdkUsage?:
|
|
209
|
+
sdkUsage?: CursorSdkUsageApplyOptions,
|
|
155
210
|
): void {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
211
|
+
const billed = sdkUsage?.billed;
|
|
212
|
+
const localTurn = sdkUsage?.runtime === "local" ? sdkUsage.turn : undefined;
|
|
213
|
+
if (billed && isCursorSdkUsagePartitionSafe(billed, model)) {
|
|
214
|
+
applyCursorSdkUsage(partial, billed);
|
|
215
|
+
applyResolvedCursorOccupancy(partial, model, context, localTurn);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
// Only local raw turn-ended usage has a captured full-prompt/cache-partition occupancy contract.
|
|
219
|
+
if (localTurn && isCursorSdkUsageSafeForPiMessage(localTurn, model)) {
|
|
220
|
+
applyCursorSdkUsage(partial, localTurn);
|
|
221
|
+
applyResolvedCursorOccupancy(partial, model, context, localTurn);
|
|
161
222
|
return;
|
|
162
223
|
}
|
|
163
224
|
applyCursorApproximateUsage(partial, model, context, sessionInputTokens);
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { registerCursorFallbackIssueWarning } from "./cursor-fallback-warning.js
|
|
|
15
15
|
import { registerCursorAgentsContextDedup } from "./cursor-agents-context-registration.js";
|
|
16
16
|
import { registerCursorOverflowNormalization } from "./cursor-provider-overflow.js";
|
|
17
17
|
import { registerCursorSdkSessionProcessErrorGuard } from "./cursor-sdk-process-error-guard.js";
|
|
18
|
+
import { prepareCursorSessionForCompaction } from "./cursor-session-compaction-prep.js";
|
|
18
19
|
|
|
19
20
|
type CursorExtensionApi =
|
|
20
21
|
& Pick<ExtensionAPI, "registerProvider" | "registerCommand" | "on">
|
|
@@ -54,7 +55,6 @@ export default async function (pi: CursorExtensionApi) {
|
|
|
54
55
|
registerCursorSessionAgentLifecycle(pi);
|
|
55
56
|
registerCursorSessionAgentResume(pi);
|
|
56
57
|
pi.on("session_before_compact", async () => {
|
|
57
|
-
const { prepareCursorSessionForCompaction } = await import("./cursor-session-compaction-prep.js");
|
|
58
58
|
await prepareCursorSessionForCompaction();
|
|
59
59
|
});
|
|
60
60
|
registerCursorRuntimeControls(pi);
|
package/src/model-discovery.ts
CHANGED
|
@@ -5,7 +5,8 @@ import type {
|
|
|
5
5
|
ModelSelection,
|
|
6
6
|
} from "@cursor/sdk";
|
|
7
7
|
import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
8
|
-
import type { ModelThinkingLevel, ThinkingLevelMap } from "@earendil-works/pi-ai
|
|
8
|
+
import type { ModelThinkingLevel, ThinkingLevelMap } from "@earendil-works/pi-ai";
|
|
9
|
+
import { getCursorModelSelectionIdentities } from "../shared/cursor-model-selection-identities.mjs";
|
|
9
10
|
import { loadContextWindowCache } from "./context-window-cache.js";
|
|
10
11
|
import { loadCursorSdk } from "./cursor-sdk-runtime.js";
|
|
11
12
|
import { resolveCursorApiKey, resolveCursorRuntimeApiKey } from "./cursor-api-key.js";
|
|
@@ -176,13 +177,6 @@ function getParamValue(params: ModelParameterValue[], id: string): string | unde
|
|
|
176
177
|
return params.find((param) => param.id === id)?.value;
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
function encodePiModelId(modelId: string, context?: string, fastOverride?: boolean): string {
|
|
180
|
-
const contextQualified = context ? `${modelId}@${context}` : modelId;
|
|
181
|
-
if (fastOverride === true) return `${contextQualified}:fast`;
|
|
182
|
-
if (fastOverride === false) return `${contextQualified}:slow`;
|
|
183
|
-
return contextQualified;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
180
|
function getModelName(item: ModelListItem, context?: string, alias?: string, fastOverride?: boolean): string {
|
|
187
181
|
const displayName = item.displayName || item.id;
|
|
188
182
|
const qualifiers: string[] = [];
|
|
@@ -193,18 +187,17 @@ function getModelName(item: ModelListItem, context?: string, alias?: string, fas
|
|
|
193
187
|
return context ? `${baseName} @ ${context}` : baseName;
|
|
194
188
|
}
|
|
195
189
|
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
contextWindowCache.get(
|
|
204
|
-
(
|
|
205
|
-
|
|
190
|
+
function getContextWindow(
|
|
191
|
+
contextWindowCache: Map<string, number>,
|
|
192
|
+
selectionKeys: readonly string[],
|
|
193
|
+
context?: string,
|
|
194
|
+
baseModelId?: string,
|
|
195
|
+
): number {
|
|
196
|
+
for (const key of new Set(selectionKeys)) {
|
|
197
|
+
const contextWindow = contextWindowCache.get(key);
|
|
198
|
+
if (contextWindow !== undefined) return contextWindow;
|
|
199
|
+
}
|
|
206
200
|
return (
|
|
207
|
-
contextWindowOverride ??
|
|
208
201
|
(context ? parseContextWindow(context) : undefined) ??
|
|
209
202
|
(baseModelId ? contextWindowCache.get(baseModelId) : undefined) ??
|
|
210
203
|
contextWindowCache.get("default") ??
|
|
@@ -219,6 +212,7 @@ function toMetadata(
|
|
|
219
212
|
defaultParams: ModelParameterValue[],
|
|
220
213
|
context: string | undefined,
|
|
221
214
|
contextWindowCache: Map<string, number>,
|
|
215
|
+
contextWindowKeys: readonly string[],
|
|
222
216
|
fastOverride?: boolean,
|
|
223
217
|
): CursorModelMetadata {
|
|
224
218
|
const thinkingLevelMap = getThinkingLevelMap(item);
|
|
@@ -230,7 +224,7 @@ function toMetadata(
|
|
|
230
224
|
displayName: item.displayName || item.id,
|
|
231
225
|
defaultParams: cloneParams(defaultParams),
|
|
232
226
|
...(context ? { context } : {}),
|
|
233
|
-
contextWindow: getContextWindow(contextWindowCache,
|
|
227
|
+
contextWindow: getContextWindow(contextWindowCache, contextWindowKeys, context, item.id),
|
|
234
228
|
supportsFast: getParameter(item, "fast") !== undefined,
|
|
235
229
|
defaultFast: fastValue === "true",
|
|
236
230
|
...(fastOverride !== undefined ? { fastOverride } : {}),
|
|
@@ -259,78 +253,27 @@ function toModelConfig(metadata: CursorModelMetadata, name: string): ProviderMod
|
|
|
259
253
|
};
|
|
260
254
|
}
|
|
261
255
|
|
|
262
|
-
function getContextValues(item: ModelListItem): string[] {
|
|
263
|
-
return getParameter(item, "context")?.values.map((value) => value.value) ?? [];
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function getAmbiguousAliases(items: ModelListItem[]): Set<string> {
|
|
267
|
-
const aliasOwners = new Map<string, Set<string>>();
|
|
268
|
-
for (const item of items) {
|
|
269
|
-
for (const rawAlias of item.aliases ?? []) {
|
|
270
|
-
const alias = rawAlias.trim();
|
|
271
|
-
if (!alias || alias === item.id) continue;
|
|
272
|
-
const owners = aliasOwners.get(alias) ?? new Set<string>();
|
|
273
|
-
owners.add(item.id);
|
|
274
|
-
aliasOwners.set(alias, owners);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return new Set([...aliasOwners.entries()].filter(([, owners]) => owners.size > 1).map(([alias]) => alias));
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function getModelIds(item: ModelListItem, reservedBaseModelIds: Set<string>, ambiguousAliases: Set<string>): string[] {
|
|
281
|
-
const ids = [item.id];
|
|
282
|
-
for (const rawAlias of item.aliases ?? []) {
|
|
283
|
-
const alias = rawAlias.trim();
|
|
284
|
-
if (!alias || alias === item.id || ids.includes(alias) || reservedBaseModelIds.has(alias) || ambiguousAliases.has(alias)) continue;
|
|
285
|
-
ids.push(alias);
|
|
286
|
-
}
|
|
287
|
-
return ids;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function toModelConfigs(
|
|
291
|
-
item: ModelListItem,
|
|
292
|
-
usedPiModelIds: Set<string>,
|
|
293
|
-
reservedBaseModelIds: Set<string>,
|
|
294
|
-
ambiguousAliases: Set<string>,
|
|
295
|
-
contextWindowCache: Map<string, number>,
|
|
296
|
-
): ProviderModelConfig[] {
|
|
297
|
-
const defaultParams = getDefaultParams(item);
|
|
298
|
-
const contextValues = getContextValues(item);
|
|
299
|
-
const contexts = contextValues.length > 0 ? contextValues : [undefined];
|
|
300
|
-
const configs: ProviderModelConfig[] = [];
|
|
301
|
-
|
|
302
|
-
const fastOverrides = getParameter(item, "fast") === undefined ? [undefined] : [undefined, true, false];
|
|
303
|
-
|
|
304
|
-
for (const selectionModelId of getModelIds(item, reservedBaseModelIds, ambiguousAliases)) {
|
|
305
|
-
const alias = selectionModelId === item.id ? undefined : selectionModelId;
|
|
306
|
-
for (const context of contexts) {
|
|
307
|
-
const contextParams = context ? replaceParam(defaultParams, "context", context) : defaultParams;
|
|
308
|
-
for (const fastOverride of fastOverrides) {
|
|
309
|
-
const params = fastOverride === undefined ? contextParams : replaceParam(contextParams, "fast", fastOverride ? "true" : "false");
|
|
310
|
-
const piModelId = encodePiModelId(selectionModelId, context, fastOverride);
|
|
311
|
-
if (usedPiModelIds.has(piModelId)) continue;
|
|
312
|
-
usedPiModelIds.add(piModelId);
|
|
313
|
-
const metadata = toMetadata(item, piModelId, selectionModelId, params, context, contextWindowCache, fastOverride);
|
|
314
|
-
metadataByPiModelId.set(piModelId, metadata);
|
|
315
|
-
configs.push(toModelConfig(metadata, getModelName(item, context, alias, fastOverride)));
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return configs;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function sortModelsByBaseId(items: ModelListItem[]): ModelListItem[] {
|
|
324
|
-
return [...items].sort((a, b) => a.id.localeCompare(b.id));
|
|
325
|
-
}
|
|
326
|
-
|
|
327
256
|
function registerModelItems(items: ModelListItem[]): ProviderModelConfig[] {
|
|
328
257
|
metadataByPiModelId.clear();
|
|
329
|
-
const usedPiModelIds = new Set<string>();
|
|
330
|
-
const reservedBaseModelIds = new Set(items.map((item) => item.id));
|
|
331
|
-
const ambiguousAliases = getAmbiguousAliases(items);
|
|
332
258
|
const contextWindowCache = loadContextWindowCache();
|
|
333
|
-
return
|
|
259
|
+
return getCursorModelSelectionIdentities(items).map(({ model: item, selectionModelId, context, fastOverride, piModelId, contextWindowKey, baseContextWindowKey }) => {
|
|
260
|
+
const defaultParams = getDefaultParams(item);
|
|
261
|
+
const contextParams = context ? replaceParam(defaultParams, "context", context) : defaultParams;
|
|
262
|
+
const params = fastOverride === undefined ? contextParams : replaceParam(contextParams, "fast", fastOverride ? "true" : "false");
|
|
263
|
+
const metadata = toMetadata(
|
|
264
|
+
item,
|
|
265
|
+
piModelId,
|
|
266
|
+
selectionModelId,
|
|
267
|
+
params,
|
|
268
|
+
context,
|
|
269
|
+
contextWindowCache,
|
|
270
|
+
[piModelId, contextWindowKey, baseContextWindowKey],
|
|
271
|
+
fastOverride,
|
|
272
|
+
);
|
|
273
|
+
metadataByPiModelId.set(piModelId, metadata);
|
|
274
|
+
const alias = selectionModelId === item.id ? undefined : selectionModelId;
|
|
275
|
+
return toModelConfig(metadata, getModelName(item, context, alias, fastOverride));
|
|
276
|
+
});
|
|
334
277
|
}
|
|
335
278
|
|
|
336
279
|
export function getCursorModelMetadata(modelId: string): CursorModelMetadata | undefined {
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"rootDir": "src",
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"noEmit": true
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"],
|
|
15
|
+
"exclude": ["node_modules", "dist"]
|
|
16
|
+
}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
# Changes
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
## 2.0.2
|
|
5
|
-
|
|
6
|
-
* Rename bin to `node-which`
|
|
7
|
-
|
|
8
|
-
## 2.0.1
|
|
9
|
-
|
|
10
|
-
* generate changelog and publish on version bump
|
|
11
|
-
* enforce 100% test coverage
|
|
12
|
-
* Promise interface
|
|
13
|
-
|
|
14
|
-
## 2.0.0
|
|
15
|
-
|
|
16
|
-
* Parallel tests, modern JavaScript, and drop support for node < 8
|
|
17
|
-
|
|
18
|
-
## 1.3.1
|
|
19
|
-
|
|
20
|
-
* update deps
|
|
21
|
-
* update travis
|
|
22
|
-
|
|
23
|
-
## v1.3.0
|
|
24
|
-
|
|
25
|
-
* Add nothrow option to which.sync
|
|
26
|
-
* update tap
|
|
27
|
-
|
|
28
|
-
## v1.2.14
|
|
29
|
-
|
|
30
|
-
* appveyor: drop node 5 and 0.x
|
|
31
|
-
* travis-ci: add node 6, drop 0.x
|
|
32
|
-
|
|
33
|
-
## v1.2.13
|
|
34
|
-
|
|
35
|
-
* test: Pass missing option to pass on windows
|
|
36
|
-
* update tap
|
|
37
|
-
* update isexe to 2.0.0
|
|
38
|
-
* neveragain.tech pledge request
|
|
39
|
-
|
|
40
|
-
## v1.2.12
|
|
41
|
-
|
|
42
|
-
* Removed unused require
|
|
43
|
-
|
|
44
|
-
## v1.2.11
|
|
45
|
-
|
|
46
|
-
* Prevent changelog script from being included in package
|
|
47
|
-
|
|
48
|
-
## v1.2.10
|
|
49
|
-
|
|
50
|
-
* Use env.PATH only, not env.Path
|
|
51
|
-
|
|
52
|
-
## v1.2.9
|
|
53
|
-
|
|
54
|
-
* fix for paths starting with ../
|
|
55
|
-
* Remove unused `is-absolute` module
|
|
56
|
-
|
|
57
|
-
## v1.2.8
|
|
58
|
-
|
|
59
|
-
* bullet items in changelog that contain (but don't start with) #
|
|
60
|
-
|
|
61
|
-
## v1.2.7
|
|
62
|
-
|
|
63
|
-
* strip 'update changelog' changelog entries out of changelog
|
|
64
|
-
|
|
65
|
-
## v1.2.6
|
|
66
|
-
|
|
67
|
-
* make the changelog bulleted
|
|
68
|
-
|
|
69
|
-
## v1.2.5
|
|
70
|
-
|
|
71
|
-
* make a changelog, and keep it up to date
|
|
72
|
-
* don't include tests in package
|
|
73
|
-
* Properly handle relative-path executables
|
|
74
|
-
* appveyor
|
|
75
|
-
* Attach error code to Not Found error
|
|
76
|
-
* Make tests pass on Windows
|
|
77
|
-
|
|
78
|
-
## v1.2.4
|
|
79
|
-
|
|
80
|
-
* Fix typo
|
|
81
|
-
|
|
82
|
-
## v1.2.3
|
|
83
|
-
|
|
84
|
-
* update isexe, fix regression in pathExt handling
|
|
85
|
-
|
|
86
|
-
## v1.2.2
|
|
87
|
-
|
|
88
|
-
* update deps, use isexe module, test windows
|
|
89
|
-
|
|
90
|
-
## v1.2.1
|
|
91
|
-
|
|
92
|
-
* Sometimes windows PATH entries are quoted
|
|
93
|
-
* Fixed a bug in the check for group and user mode bits. This bug was introduced during refactoring for supporting strict mode.
|
|
94
|
-
* doc cli
|
|
95
|
-
|
|
96
|
-
## v1.2.0
|
|
97
|
-
|
|
98
|
-
* Add support for opt.all and -as cli flags
|
|
99
|
-
* test the bin
|
|
100
|
-
* update travis
|
|
101
|
-
* Allow checking for multiple programs in bin/which
|
|
102
|
-
* tap 2
|
|
103
|
-
|
|
104
|
-
## v1.1.2
|
|
105
|
-
|
|
106
|
-
* travis
|
|
107
|
-
* Refactored and fixed undefined error on Windows
|
|
108
|
-
* Support strict mode
|
|
109
|
-
|
|
110
|
-
## v1.1.1
|
|
111
|
-
|
|
112
|
-
* test +g exes against secondary groups, if available
|
|
113
|
-
* Use windows exe semantics on cygwin & msys
|
|
114
|
-
* cwd should be first in path on win32, not last
|
|
115
|
-
* Handle lower-case 'env.Path' on Windows
|
|
116
|
-
* Update docs
|
|
117
|
-
* use single-quotes
|
|
118
|
-
|
|
119
|
-
## v1.1.0
|
|
120
|
-
|
|
121
|
-
* Add tests, depend on is-absolute
|
|
122
|
-
|
|
123
|
-
## v1.0.9
|
|
124
|
-
|
|
125
|
-
* which.js: root is allowed to execute files owned by anyone
|
|
126
|
-
|
|
127
|
-
## v1.0.8
|
|
128
|
-
|
|
129
|
-
* don't use graceful-fs
|
|
130
|
-
|
|
131
|
-
## v1.0.7
|
|
132
|
-
|
|
133
|
-
* add license to package.json
|
|
134
|
-
|
|
135
|
-
## v1.0.6
|
|
136
|
-
|
|
137
|
-
* isc license
|
|
138
|
-
|
|
139
|
-
## 1.0.5
|
|
140
|
-
|
|
141
|
-
* Awful typo
|
|
142
|
-
|
|
143
|
-
## 1.0.4
|
|
144
|
-
|
|
145
|
-
* Test for path absoluteness properly
|
|
146
|
-
* win: Allow '' as a pathext if cmd has a . in it
|
|
147
|
-
|
|
148
|
-
## 1.0.3
|
|
149
|
-
|
|
150
|
-
* Remove references to execPath
|
|
151
|
-
* Make `which.sync()` work on Windows by honoring the PATHEXT variable.
|
|
152
|
-
* Make `isExe()` always return true on Windows.
|
|
153
|
-
* MIT
|
|
154
|
-
|
|
155
|
-
## 1.0.2
|
|
156
|
-
|
|
157
|
-
* Only files can be exes
|
|
158
|
-
|
|
159
|
-
## 1.0.1
|
|
160
|
-
|
|
161
|
-
* Respect the PATHEXT env for win32 support
|
|
162
|
-
* should 0755 the bin
|
|
163
|
-
* binary
|
|
164
|
-
* guts
|
|
165
|
-
* package
|
|
166
|
-
* 1st
|