opencode-ext-connector 0.3.0
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 +39 -0
- package/LICENSE +29 -0
- package/README.md +207 -0
- package/THIRD_PARTY_NOTICES.md +201 -0
- package/dist/catalog/parse-ids.d.ts +2 -0
- package/dist/catalog/parse-ids.js +49 -0
- package/dist/core/adapter.d.ts +16 -0
- package/dist/core/adapter.js +20 -0
- package/dist/core/clock.d.ts +7 -0
- package/dist/core/clock.js +1 -0
- package/dist/core/deadline.d.ts +13 -0
- package/dist/core/deadline.js +54 -0
- package/dist/core/errors.d.ts +57 -0
- package/dist/core/errors.js +81 -0
- package/dist/core/health.d.ts +22 -0
- package/dist/core/health.js +30 -0
- package/dist/core/http.d.ts +28 -0
- package/dist/core/http.js +1 -0
- package/dist/core/ids.d.ts +7 -0
- package/dist/core/ids.js +23 -0
- package/dist/core/lifecycle.d.ts +4 -0
- package/dist/core/lifecycle.js +16 -0
- package/dist/core/logger.d.ts +21 -0
- package/dist/core/logger.js +61 -0
- package/dist/core/models.d.ts +41 -0
- package/dist/core/models.js +59 -0
- package/dist/core/options.d.ts +31 -0
- package/dist/core/options.js +62 -0
- package/dist/core/process.d.ts +20 -0
- package/dist/core/process.js +1 -0
- package/dist/http/fetch-transport.d.ts +2 -0
- package/dist/http/fetch-transport.js +75 -0
- package/dist/http/package-version.d.ts +7 -0
- package/dist/http/package-version.js +46 -0
- package/dist/http/read-body.d.ts +9 -0
- package/dist/http/read-body.js +22 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/logging/logger.d.ts +4 -0
- package/dist/logging/logger.js +11 -0
- package/dist/opencode/auth-store.d.ts +19 -0
- package/dist/opencode/auth-store.js +107 -0
- package/dist/opencode/beta-api.d.ts +3 -0
- package/dist/opencode/beta-api.js +1 -0
- package/dist/opencode/catalog-bridge.d.ts +3 -0
- package/dist/opencode/catalog-bridge.js +85 -0
- package/dist/opencode/health-refresh.d.ts +16 -0
- package/dist/opencode/health-refresh.js +49 -0
- package/dist/opencode/host-options.d.ts +2 -0
- package/dist/opencode/host-options.js +49 -0
- package/dist/opencode/language-factory.d.ts +13 -0
- package/dist/opencode/language-factory.js +37 -0
- package/dist/opencode/ollama-probe.d.ts +2 -0
- package/dist/opencode/ollama-probe.js +15 -0
- package/dist/opencode/ollama-production.d.ts +4 -0
- package/dist/opencode/ollama-production.js +10 -0
- package/dist/opencode/plugin.d.ts +33 -0
- package/dist/opencode/plugin.js +40 -0
- package/dist/opencode/process-exit.d.ts +4 -0
- package/dist/opencode/process-exit.js +22 -0
- package/dist/opencode/provider-entry.d.ts +25 -0
- package/dist/opencode/provider-entry.js +1 -0
- package/dist/opencode/providers.d.ts +16 -0
- package/dist/opencode/providers.js +140 -0
- package/dist/opencode/register-integrations.d.ts +3 -0
- package/dist/opencode/register-integrations.js +8 -0
- package/dist/opencode/reload.d.ts +9 -0
- package/dist/opencode/reload.js +30 -0
- package/dist/opencode/v1-anthropic-auth.d.ts +9 -0
- package/dist/opencode/v1-anthropic-auth.js +55 -0
- package/dist/opencode/v1-catalog.d.ts +13 -0
- package/dist/opencode/v1-catalog.js +80 -0
- package/dist/opencode/v1-language.d.ts +3 -0
- package/dist/opencode/v1-language.js +64 -0
- package/dist/opencode/v1-module.d.ts +23 -0
- package/dist/opencode/v1-module.js +74 -0
- package/dist/opencode/v1-session-auth.d.ts +5 -0
- package/dist/opencode/v1-session-auth.js +98 -0
- package/dist/providers/claude/adapter.d.ts +7 -0
- package/dist/providers/claude/adapter.js +37 -0
- package/dist/providers/claude/atomic-private-file.d.ts +13 -0
- package/dist/providers/claude/atomic-private-file.js +94 -0
- package/dist/providers/claude/auth-json.d.ts +2 -0
- package/dist/providers/claude/auth-json.js +14 -0
- package/dist/providers/claude/auth.d.ts +24 -0
- package/dist/providers/claude/auth.js +200 -0
- package/dist/providers/claude/cli-version.d.ts +10 -0
- package/dist/providers/claude/cli-version.js +36 -0
- package/dist/providers/claude/compat-betas.d.ts +5 -0
- package/dist/providers/claude/compat-betas.js +54 -0
- package/dist/providers/claude/compat-config.d.ts +8 -0
- package/dist/providers/claude/compat-config.js +31 -0
- package/dist/providers/claude/compat-request.d.ts +12 -0
- package/dist/providers/claude/compat-request.js +151 -0
- package/dist/providers/claude/compat-response.d.ts +1 -0
- package/dist/providers/claude/compat-response.js +54 -0
- package/dist/providers/claude/compat-signing.d.ts +9 -0
- package/dist/providers/claude/compat-signing.js +24 -0
- package/dist/providers/claude/compat-transform.d.ts +3 -0
- package/dist/providers/claude/compat-transform.js +224 -0
- package/dist/providers/claude/credentials.d.ts +7 -0
- package/dist/providers/claude/credentials.js +37 -0
- package/dist/providers/claude/emit-stream.d.ts +2 -0
- package/dist/providers/claude/emit-stream.js +62 -0
- package/dist/providers/claude/keychain-account.d.ts +1 -0
- package/dist/providers/claude/keychain-account.js +14 -0
- package/dist/providers/claude/language-model.d.ts +8 -0
- package/dist/providers/claude/language-model.js +109 -0
- package/dist/providers/claude/models.d.ts +9 -0
- package/dist/providers/claude/models.js +24 -0
- package/dist/providers/claude/prompt.d.ts +42 -0
- package/dist/providers/claude/prompt.js +134 -0
- package/dist/providers/claude/refresh.d.ts +19 -0
- package/dist/providers/claude/refresh.js +85 -0
- package/dist/providers/claude/sse-convert.d.ts +6 -0
- package/dist/providers/claude/sse-convert.js +74 -0
- package/dist/providers/claude/sse.d.ts +71 -0
- package/dist/providers/claude/sse.js +123 -0
- package/dist/providers/claude/transform.d.ts +32 -0
- package/dist/providers/claude/transform.js +52 -0
- package/dist/providers/claude/writeback.d.ts +18 -0
- package/dist/providers/claude/writeback.js +140 -0
- package/dist/providers/command-code/adapter.d.ts +7 -0
- package/dist/providers/command-code/adapter.js +37 -0
- package/dist/providers/command-code/auth.d.ts +5 -0
- package/dist/providers/command-code/auth.js +88 -0
- package/dist/providers/command-code/cli-version.d.ts +10 -0
- package/dist/providers/command-code/cli-version.js +36 -0
- package/dist/providers/command-code/emit-stream.d.ts +2 -0
- package/dist/providers/command-code/emit-stream.js +226 -0
- package/dist/providers/command-code/errors.d.ts +33 -0
- package/dist/providers/command-code/errors.js +105 -0
- package/dist/providers/command-code/language-model.d.ts +15 -0
- package/dist/providers/command-code/language-model.js +203 -0
- package/dist/providers/command-code/models.d.ts +3 -0
- package/dist/providers/command-code/models.js +18 -0
- package/dist/providers/command-code/record-stream.d.ts +1 -0
- package/dist/providers/command-code/record-stream.js +61 -0
- package/dist/providers/command-code/request-lifecycle.d.ts +8 -0
- package/dist/providers/command-code/request-lifecycle.js +33 -0
- package/dist/providers/command-code/request.d.ts +14 -0
- package/dist/providers/command-code/request.js +167 -0
- package/dist/providers/command-code/session.d.ts +5 -0
- package/dist/providers/command-code/session.js +9 -0
- package/dist/providers/cursor/adapter.d.ts +7 -0
- package/dist/providers/cursor/adapter.js +37 -0
- package/dist/providers/cursor/auth.d.ts +6 -0
- package/dist/providers/cursor/auth.js +56 -0
- package/dist/providers/cursor/blob-store.d.ts +26 -0
- package/dist/providers/cursor/blob-store.js +119 -0
- package/dist/providers/cursor/bridge-client.d.ts +33 -0
- package/dist/providers/cursor/bridge-client.js +200 -0
- package/dist/providers/cursor/bridge-event-sanitize.d.ts +3 -0
- package/dist/providers/cursor/bridge-event-sanitize.js +49 -0
- package/dist/providers/cursor/bridge-limits.d.ts +3 -0
- package/dist/providers/cursor/bridge-limits.js +10 -0
- package/dist/providers/cursor/bridge-process.d.ts +45 -0
- package/dist/providers/cursor/bridge-process.js +211 -0
- package/dist/providers/cursor/bridge-protocol.d.ts +68 -0
- package/dist/providers/cursor/bridge-protocol.js +49 -0
- package/dist/providers/cursor/bridge-serialize.d.ts +3 -0
- package/dist/providers/cursor/bridge-serialize.js +53 -0
- package/dist/providers/cursor/bridge-wire.d.ts +3 -0
- package/dist/providers/cursor/bridge-wire.js +163 -0
- package/dist/providers/cursor/checkpoint-store.d.ts +28 -0
- package/dist/providers/cursor/checkpoint-store.js +94 -0
- package/dist/providers/cursor/connect-frame-stream.d.ts +19 -0
- package/dist/providers/cursor/connect-frame-stream.js +160 -0
- package/dist/providers/cursor/connect-frame.d.ts +31 -0
- package/dist/providers/cursor/connect-frame.js +121 -0
- package/dist/providers/cursor/credentials.d.ts +5 -0
- package/dist/providers/cursor/credentials.js +22 -0
- package/dist/providers/cursor/direct-run-types.d.ts +33 -0
- package/dist/providers/cursor/direct-run-types.js +1 -0
- package/dist/providers/cursor/direct-run.d.ts +5 -0
- package/dist/providers/cursor/direct-run.js +213 -0
- package/dist/providers/cursor/direct-runtime.d.ts +23 -0
- package/dist/providers/cursor/direct-runtime.js +111 -0
- package/dist/providers/cursor/direct-stream.d.ts +28 -0
- package/dist/providers/cursor/direct-stream.js +190 -0
- package/dist/providers/cursor/exec-reply.d.ts +13 -0
- package/dist/providers/cursor/exec-reply.js +102 -0
- package/dist/providers/cursor/h2-bridge-response.d.ts +9 -0
- package/dist/providers/cursor/h2-bridge-response.js +51 -0
- package/dist/providers/cursor/h2-bridge-session.d.ts +24 -0
- package/dist/providers/cursor/h2-bridge-session.js +197 -0
- package/dist/providers/cursor/h2-bridge.d.ts +2 -0
- package/dist/providers/cursor/h2-bridge.js +12865 -0
- package/dist/providers/cursor/http2.d.ts +18 -0
- package/dist/providers/cursor/http2.js +144 -0
- package/dist/providers/cursor/interaction-reply.d.ts +6 -0
- package/dist/providers/cursor/interaction-reply.js +52 -0
- package/dist/providers/cursor/language-generate.d.ts +2 -0
- package/dist/providers/cursor/language-generate.js +35 -0
- package/dist/providers/cursor/language-model.d.ts +13 -0
- package/dist/providers/cursor/language-model.js +77 -0
- package/dist/providers/cursor/legacy-stream.d.ts +11 -0
- package/dist/providers/cursor/legacy-stream.js +115 -0
- package/dist/providers/cursor/mcp-tools.d.ts +7 -0
- package/dist/providers/cursor/mcp-tools.js +15 -0
- package/dist/providers/cursor/models.d.ts +14 -0
- package/dist/providers/cursor/models.js +116 -0
- package/dist/providers/cursor/ndjson.d.ts +3 -0
- package/dist/providers/cursor/ndjson.js +100 -0
- package/dist/providers/cursor/prompt.d.ts +4 -0
- package/dist/providers/cursor/prompt.js +142 -0
- package/dist/providers/cursor/proto/checkpoint.d.ts +35 -0
- package/dist/providers/cursor/proto/checkpoint.js +114 -0
- package/dist/providers/cursor/proto/context.d.ts +64 -0
- package/dist/providers/cursor/proto/context.js +178 -0
- package/dist/providers/cursor/proto/errors.d.ts +16 -0
- package/dist/providers/cursor/proto/errors.js +26 -0
- package/dist/providers/cursor/proto/exec-control.d.ts +20 -0
- package/dist/providers/cursor/proto/exec-control.js +54 -0
- package/dist/providers/cursor/proto/exec.d.ts +47 -0
- package/dist/providers/cursor/proto/exec.js +154 -0
- package/dist/providers/cursor/proto/fields.d.ts +22 -0
- package/dist/providers/cursor/proto/fields.js +97 -0
- package/dist/providers/cursor/proto/interaction-query.d.ts +15 -0
- package/dist/providers/cursor/proto/interaction-query.js +79 -0
- package/dist/providers/cursor/proto/interaction-tool-update.d.ts +10 -0
- package/dist/providers/cursor/proto/interaction-tool-update.js +58 -0
- package/dist/providers/cursor/proto/interaction-turn-ended.d.ts +6 -0
- package/dist/providers/cursor/proto/interaction-turn-ended.js +18 -0
- package/dist/providers/cursor/proto/interaction.d.ts +65 -0
- package/dist/providers/cursor/proto/interaction.js +185 -0
- package/dist/providers/cursor/proto/kv.d.ts +25 -0
- package/dist/providers/cursor/proto/kv.js +109 -0
- package/dist/providers/cursor/proto/mcp-result.d.ts +40 -0
- package/dist/providers/cursor/proto/mcp-result.js +150 -0
- package/dist/providers/cursor/proto/mcp.d.ts +19 -0
- package/dist/providers/cursor/proto/mcp.js +78 -0
- package/dist/providers/cursor/proto/model.d.ts +11 -0
- package/dist/providers/cursor/proto/model.js +36 -0
- package/dist/providers/cursor/proto/output-location.d.ts +7 -0
- package/dist/providers/cursor/proto/output-location.js +53 -0
- package/dist/providers/cursor/proto/prewarm.d.ts +16 -0
- package/dist/providers/cursor/proto/prewarm.js +68 -0
- package/dist/providers/cursor/proto/request-context.d.ts +16 -0
- package/dist/providers/cursor/proto/request-context.js +58 -0
- package/dist/providers/cursor/proto/request.d.ts +44 -0
- package/dist/providers/cursor/proto/request.js +111 -0
- package/dist/providers/cursor/proto/run-request.d.ts +19 -0
- package/dist/providers/cursor/proto/run-request.js +68 -0
- package/dist/providers/cursor/proto/server.d.ts +35 -0
- package/dist/providers/cursor/proto/server.js +93 -0
- package/dist/providers/cursor/proto/unknown-field.d.ts +1 -0
- package/dist/providers/cursor/proto/unknown-field.js +22 -0
- package/dist/providers/cursor/proto-value.d.ts +3 -0
- package/dist/providers/cursor/proto-value.js +170 -0
- package/dist/providers/cursor/proto-wire.d.ts +22 -0
- package/dist/providers/cursor/proto-wire.js +224 -0
- package/dist/providers/cursor/protocol-failure.d.ts +18 -0
- package/dist/providers/cursor/protocol-failure.js +45 -0
- package/dist/providers/cursor/recovery.d.ts +48 -0
- package/dist/providers/cursor/recovery.js +102 -0
- package/dist/providers/cursor/request-blob-ownership.d.ts +15 -0
- package/dist/providers/cursor/request-blob-ownership.js +39 -0
- package/dist/providers/cursor/request-build.d.ts +18 -0
- package/dist/providers/cursor/request-build.js +123 -0
- package/dist/providers/cursor/request-history.d.ts +32 -0
- package/dist/providers/cursor/request-history.js +163 -0
- package/dist/providers/cursor/request-input.d.ts +75 -0
- package/dist/providers/cursor/request-input.js +123 -0
- package/dist/providers/cursor/run-events.d.ts +15 -0
- package/dist/providers/cursor/run-events.js +43 -0
- package/dist/providers/cursor/run-session-expiry.d.ts +15 -0
- package/dist/providers/cursor/run-session-expiry.js +21 -0
- package/dist/providers/cursor/run-session.d.ts +50 -0
- package/dist/providers/cursor/run-session.js +205 -0
- package/dist/providers/cursor/run.d.ts +9 -0
- package/dist/providers/cursor/run.js +151 -0
- package/dist/providers/cursor/runner.d.ts +1 -0
- package/dist/providers/cursor/runner.js +55 -0
- package/dist/providers/cursor/server-dispatch-types.d.ts +83 -0
- package/dist/providers/cursor/server-dispatch-types.js +1 -0
- package/dist/providers/cursor/server-dispatch.d.ts +3 -0
- package/dist/providers/cursor/server-dispatch.js +178 -0
- package/dist/providers/cursor/session-state.d.ts +21 -0
- package/dist/providers/cursor/session-state.js +118 -0
- package/dist/providers/cursor/session.d.ts +1 -0
- package/dist/providers/cursor/session.js +26 -0
- package/dist/providers/cursor/settle-cleanup.d.ts +1 -0
- package/dist/providers/cursor/settle-cleanup.js +11 -0
- package/dist/providers/cursor/stream-adapter.d.ts +17 -0
- package/dist/providers/cursor/stream-adapter.js +99 -0
- package/dist/providers/cursor/tool-continuation.d.ts +14 -0
- package/dist/providers/cursor/tool-continuation.js +134 -0
- package/dist/providers/cursor/tool-stream.d.ts +2 -0
- package/dist/providers/cursor/tool-stream.js +220 -0
- package/dist/providers/cursor/usage.d.ts +3 -0
- package/dist/providers/cursor/usage.js +35 -0
- package/dist/providers/ollama/adapter.d.ts +8 -0
- package/dist/providers/ollama/adapter.js +65 -0
- package/dist/providers/ollama/catalog-state.d.ts +17 -0
- package/dist/providers/ollama/catalog-state.js +40 -0
- package/dist/providers/ollama/cloud-catalog.d.ts +3 -0
- package/dist/providers/ollama/cloud-catalog.js +82 -0
- package/dist/providers/ollama/errors.d.ts +14 -0
- package/dist/providers/ollama/errors.js +19 -0
- package/dist/providers/ollama/generate.d.ts +2 -0
- package/dist/providers/ollama/generate.js +49 -0
- package/dist/providers/ollama/html-links.d.ts +1 -0
- package/dist/providers/ollama/html-links.js +30 -0
- package/dist/providers/ollama/http.d.ts +12 -0
- package/dist/providers/ollama/http.js +67 -0
- package/dist/providers/ollama/index.d.ts +8 -0
- package/dist/providers/ollama/index.js +8 -0
- package/dist/providers/ollama/language-model.d.ts +11 -0
- package/dist/providers/ollama/language-model.js +62 -0
- package/dist/providers/ollama/local-catalog.d.ts +3 -0
- package/dist/providers/ollama/local-catalog.js +38 -0
- package/dist/providers/ollama/ndjson.d.ts +3 -0
- package/dist/providers/ollama/ndjson.js +51 -0
- package/dist/providers/ollama/prompt.d.ts +8 -0
- package/dist/providers/ollama/prompt.js +141 -0
- package/dist/providers/ollama/protocol.d.ts +56 -0
- package/dist/providers/ollama/protocol.js +26 -0
- package/dist/providers/ollama/runtime.d.ts +11 -0
- package/dist/providers/ollama/runtime.js +128 -0
- package/dist/providers/ollama/stream.d.ts +8 -0
- package/dist/providers/ollama/stream.js +110 -0
- package/dist/sdk/command-code.d.ts +5 -0
- package/dist/sdk/command-code.js +6 -0
- package/dist/sdk/cursor.d.ts +5 -0
- package/dist/sdk/cursor.js +6 -0
- package/dist/sdk/ollama.d.ts +5 -0
- package/dist/sdk/ollama.js +6 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +94 -0
- package/docs/README.ko.md +189 -0
- package/package.json +75 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Derived from Nomadcxx/opencode-cursor@8e14a26c1e080382f471a729436092ef72edf34e.
|
|
2
|
+
// Licensed under BSD-3-Clause. See THIRD_PARTY_NOTICES.md.
|
|
3
|
+
export function cursorTextFromUnknown(value) {
|
|
4
|
+
if (typeof value === "string" && value.length > 0) {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
if (typeof value !== "object" || value === null) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if ("text" in value && typeof value.text === "string") {
|
|
11
|
+
return value.text;
|
|
12
|
+
}
|
|
13
|
+
if ("delta" in value && typeof value.delta === "string") {
|
|
14
|
+
return value.delta;
|
|
15
|
+
}
|
|
16
|
+
if ("result" in value && typeof value.result === "string") {
|
|
17
|
+
return value.result;
|
|
18
|
+
}
|
|
19
|
+
if ("message" in value) {
|
|
20
|
+
return cursorTextFromUnknown(value.message);
|
|
21
|
+
}
|
|
22
|
+
if ("content" in value) {
|
|
23
|
+
const content = value.content;
|
|
24
|
+
if (typeof content === "string") {
|
|
25
|
+
return content;
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(content)) {
|
|
28
|
+
const parts = [];
|
|
29
|
+
for (const part of content) {
|
|
30
|
+
const text = cursorTextFromUnknown(part);
|
|
31
|
+
if (text !== null) {
|
|
32
|
+
parts.push(text);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return parts.length > 0 ? parts.join("") : null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
export function cursorResultError(value) {
|
|
41
|
+
const isError = "is_error" in value && value.is_error === true;
|
|
42
|
+
const subtype = "subtype" in value && typeof value.subtype === "string" ? value.subtype : "";
|
|
43
|
+
const exitCode = "exitCode" in value && typeof value.exitCode === "number"
|
|
44
|
+
? value.exitCode
|
|
45
|
+
: "exit_code" in value && typeof value.exit_code === "number"
|
|
46
|
+
? value.exit_code
|
|
47
|
+
: 0;
|
|
48
|
+
if (!isError && !subtype.includes("error") && exitCode === 0) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return new Error(cursorTextFromUnknown(value) ?? (subtype || `cursor-agent exited ${exitCode}`));
|
|
52
|
+
}
|
|
53
|
+
export function extractCursorNdjsonText(stream) {
|
|
54
|
+
const parts = [];
|
|
55
|
+
let assistantText = "";
|
|
56
|
+
let resultText = "";
|
|
57
|
+
for (const line of stream.split("\n")) {
|
|
58
|
+
const trimmed = line.trim();
|
|
59
|
+
if (trimmed.length === 0) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = JSON.parse(trimmed);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const type = "type" in parsed && typeof parsed.type === "string" ? parsed.type : "";
|
|
73
|
+
if (type === "thinking") {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (type !== "assistant" && type !== "text" && type !== "text-delta" && type !== "result") {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const text = cursorTextFromUnknown(parsed);
|
|
80
|
+
if (text !== null) {
|
|
81
|
+
if (type === "assistant") {
|
|
82
|
+
const delta = text.startsWith(assistantText) ? text.slice(assistantText.length) : text;
|
|
83
|
+
assistantText = text;
|
|
84
|
+
if (delta.length > 0) {
|
|
85
|
+
parts.push(delta);
|
|
86
|
+
}
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (type === "result") {
|
|
90
|
+
resultText = text;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
parts.push(text);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (assistantText.length === 0 && resultText.length > 0) {
|
|
97
|
+
parts.push(resultText);
|
|
98
|
+
}
|
|
99
|
+
return parts.join("");
|
|
100
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LanguageModelV3CallOptions } from "@ai-sdk/provider";
|
|
2
|
+
export declare function cursorSessionKey(call: LanguageModelV3CallOptions): string | null;
|
|
3
|
+
export declare function cursorIncrementalPrompt(call: LanguageModelV3CallOptions): string | null;
|
|
4
|
+
export declare function cursorPromptText(call: LanguageModelV3CallOptions): string;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
function toolResultBody(part) {
|
|
3
|
+
if (!("output" in part)) {
|
|
4
|
+
return "";
|
|
5
|
+
}
|
|
6
|
+
const output = Reflect.get(part, "output");
|
|
7
|
+
if (typeof output === "string") {
|
|
8
|
+
return output;
|
|
9
|
+
}
|
|
10
|
+
if (typeof output === "object" && output !== null && "value" in output) {
|
|
11
|
+
const value = Reflect.get(output, "value");
|
|
12
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
13
|
+
}
|
|
14
|
+
return JSON.stringify(output);
|
|
15
|
+
}
|
|
16
|
+
function textFromContentParts(parts) {
|
|
17
|
+
const texts = [];
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
if (part.type === "text" && "text" in part && typeof part.text === "string") {
|
|
20
|
+
texts.push(part.text);
|
|
21
|
+
}
|
|
22
|
+
if (part.type === "tool-call") {
|
|
23
|
+
const id = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "unknown";
|
|
24
|
+
const name = "toolName" in part && typeof part.toolName === "string" ? part.toolName : "unknown";
|
|
25
|
+
const input = "input" in part ? JSON.stringify(Reflect.get(part, "input")) : "{}";
|
|
26
|
+
texts.push(`tool_call(${name}, ${id}): ${input}`);
|
|
27
|
+
}
|
|
28
|
+
if (part.type === "tool-result") {
|
|
29
|
+
const id = "toolCallId" in part && typeof part.toolCallId === "string" ? part.toolCallId : "unknown";
|
|
30
|
+
const name = "toolName" in part && typeof part.toolName === "string" ? part.toolName : undefined;
|
|
31
|
+
const body = toolResultBody(part);
|
|
32
|
+
texts.push(name === undefined
|
|
33
|
+
? `TOOL_RESULT (call_id: ${id}): ${body}`
|
|
34
|
+
: `TOOL_RESULT (name: ${name}, call_id: ${id}): ${body}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return texts.join("");
|
|
38
|
+
}
|
|
39
|
+
function hash(value) {
|
|
40
|
+
return createHash("sha256").update(value).digest("hex").slice(0, 32);
|
|
41
|
+
}
|
|
42
|
+
function isMetaPrompt(text) {
|
|
43
|
+
const lower = text.toLowerCase();
|
|
44
|
+
return (lower.includes("title generator") ||
|
|
45
|
+
lower.includes("thread title") ||
|
|
46
|
+
lower.includes("generate a brief title"));
|
|
47
|
+
}
|
|
48
|
+
export function cursorSessionKey(call) {
|
|
49
|
+
const firstUser = call.prompt.find((message) => {
|
|
50
|
+
if (message.role !== "user") {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const text = textFromContentParts(message.content).trim();
|
|
54
|
+
return text.length > 0 && !isMetaPrompt(text);
|
|
55
|
+
});
|
|
56
|
+
if (firstUser === undefined || firstUser.role !== "user") {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const opener = textFromContentParts(firstUser.content).trim();
|
|
60
|
+
const tools = (call.tools ?? [])
|
|
61
|
+
.filter((tool) => tool.type === "function")
|
|
62
|
+
.map((tool) => ({
|
|
63
|
+
name: tool.name,
|
|
64
|
+
description: tool.description ?? "",
|
|
65
|
+
inputSchema: tool.inputSchema,
|
|
66
|
+
}));
|
|
67
|
+
return `${hash(opener)}\0${hash(JSON.stringify(tools))}`;
|
|
68
|
+
}
|
|
69
|
+
export function cursorIncrementalPrompt(call) {
|
|
70
|
+
const last = call.prompt.at(-1);
|
|
71
|
+
if (last?.role === "user") {
|
|
72
|
+
const text = textFromContentParts(last.content).trim();
|
|
73
|
+
return text.length > 0 ? text : null;
|
|
74
|
+
}
|
|
75
|
+
if (last?.role !== "tool") {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
let firstToolIndex = call.prompt.length - 1;
|
|
79
|
+
while (firstToolIndex > 0 && call.prompt[firstToolIndex - 1]?.role === "tool") {
|
|
80
|
+
firstToolIndex -= 1;
|
|
81
|
+
}
|
|
82
|
+
const parts = [];
|
|
83
|
+
const assistant = call.prompt[firstToolIndex - 1];
|
|
84
|
+
if (assistant?.role === "assistant") {
|
|
85
|
+
parts.push(`ASSISTANT: ${textFromContentParts(assistant.content)}`);
|
|
86
|
+
}
|
|
87
|
+
for (let index = firstToolIndex; index < call.prompt.length; index += 1) {
|
|
88
|
+
const message = call.prompt[index];
|
|
89
|
+
if (message?.role === "tool") {
|
|
90
|
+
parts.push(textFromContentParts(message.content));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
parts.push("The above tool calls have been executed. Continue your response based on these results.");
|
|
94
|
+
return parts.join("\n\n");
|
|
95
|
+
}
|
|
96
|
+
function toolDefinitions(call) {
|
|
97
|
+
const tools = (call.tools ?? []).filter((tool) => tool.type === "function");
|
|
98
|
+
if (tools.length === 0) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const definitions = tools
|
|
102
|
+
.map((tool) => {
|
|
103
|
+
const description = tool.description ?? "";
|
|
104
|
+
return `- ${tool.name}: ${description}\n Parameters: ${JSON.stringify(tool.inputSchema)}`;
|
|
105
|
+
})
|
|
106
|
+
.join("\n");
|
|
107
|
+
return [
|
|
108
|
+
"SYSTEM: You have access to the following tools. When you need to use one, respond with a tool_call in the standard OpenAI format.",
|
|
109
|
+
"Tool guidance: prefer write/edit for file changes; use bash mainly to run commands/tests.",
|
|
110
|
+
"",
|
|
111
|
+
`Available tools:\n${definitions}`,
|
|
112
|
+
].join("\n");
|
|
113
|
+
}
|
|
114
|
+
export function cursorPromptText(call) {
|
|
115
|
+
const parts = [];
|
|
116
|
+
const definitions = toolDefinitions(call);
|
|
117
|
+
if (definitions !== null) {
|
|
118
|
+
parts.push(definitions);
|
|
119
|
+
}
|
|
120
|
+
let hasToolResults = false;
|
|
121
|
+
for (const message of call.prompt) {
|
|
122
|
+
switch (message.role) {
|
|
123
|
+
case "system":
|
|
124
|
+
parts.push(`SYSTEM: ${message.content}`);
|
|
125
|
+
break;
|
|
126
|
+
case "user":
|
|
127
|
+
parts.push(`USER: ${textFromContentParts(message.content)}`);
|
|
128
|
+
break;
|
|
129
|
+
case "assistant":
|
|
130
|
+
parts.push(`ASSISTANT: ${textFromContentParts(message.content)}`);
|
|
131
|
+
break;
|
|
132
|
+
case "tool":
|
|
133
|
+
hasToolResults = true;
|
|
134
|
+
parts.push(textFromContentParts(message.content));
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (hasToolResults) {
|
|
139
|
+
parts.push("The above tool calls have been executed. Continue your response based on these results.");
|
|
140
|
+
}
|
|
141
|
+
return parts.join("\n");
|
|
142
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type CheckpointMapEntry = {
|
|
2
|
+
readonly key: string;
|
|
3
|
+
readonly value: Uint8Array;
|
|
4
|
+
};
|
|
5
|
+
export type ConversationTokenDetails = {
|
|
6
|
+
readonly usedTokens: number;
|
|
7
|
+
readonly maxTokens: number;
|
|
8
|
+
readonly breakdown?: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
export type ConversationCheckpoint = {
|
|
11
|
+
readonly rootPromptMessageBlobIds: readonly Uint8Array[];
|
|
12
|
+
readonly legacyTurnBlobIds: readonly Uint8Array[];
|
|
13
|
+
readonly todoBlobIds: readonly Uint8Array[];
|
|
14
|
+
readonly pendingToolCalls: readonly string[];
|
|
15
|
+
readonly tokenDetails?: ConversationTokenDetails;
|
|
16
|
+
readonly summaryBlob?: Uint8Array;
|
|
17
|
+
readonly planBlob?: Uint8Array;
|
|
18
|
+
readonly turnBlobIds: readonly Uint8Array[];
|
|
19
|
+
readonly previousWorkspaceUris: readonly string[];
|
|
20
|
+
readonly mode?: number;
|
|
21
|
+
readonly summaryArchiveBlob?: Uint8Array;
|
|
22
|
+
readonly fileStates: readonly CheckpointMapEntry[];
|
|
23
|
+
readonly summaryArchiveBlobIds: readonly Uint8Array[];
|
|
24
|
+
readonly turnTimingMessages: readonly Uint8Array[];
|
|
25
|
+
readonly fileStatesV2: readonly CheckpointMapEntry[];
|
|
26
|
+
readonly subagentStates: readonly CheckpointMapEntry[];
|
|
27
|
+
readonly selfSummaryCount?: number;
|
|
28
|
+
readonly readPaths: readonly string[];
|
|
29
|
+
readonly trackedGitRepoBranches: readonly Uint8Array[];
|
|
30
|
+
readonly clientName?: string;
|
|
31
|
+
readonly conversationStartedTimestampMs?: Uint8Array;
|
|
32
|
+
readonly conversationStartedTimeZone?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function decodeConversationCheckpoint(bytes: Uint8Array): ConversationCheckpoint;
|
|
35
|
+
export declare function encodeConversationCheckpoint(state: ConversationCheckpoint): Uint8Array;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Derived from Rahularya01/pi-cursor proto/agent.proto ConversationStateStructure. Licensed under MIT.
|
|
2
|
+
// See THIRD_PARTY_NOTICES.md.
|
|
3
|
+
import { concatBytes, decodeFieldsStrict, decodeUtf8Strict, encodeBytesField, encodeInt32Field, encodeStringField, } from "../proto-wire";
|
|
4
|
+
import { assertKnownFields, optionalField, optionalString, optionalUint32, repeatedFields, requiredField, requiredString, } from "./fields";
|
|
5
|
+
import { encodeUnknownField } from "./unknown-field";
|
|
6
|
+
function decodeTokenDetails(bytes) {
|
|
7
|
+
const context = "ConversationTokenDetails";
|
|
8
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
9
|
+
assertKnownFields(fields, [1, 2, 3], context);
|
|
10
|
+
const breakdown = optionalField(fields, { context, field: 3, wire: 2 });
|
|
11
|
+
return {
|
|
12
|
+
usedTokens: optionalUint32(fields, { context, field: 1, wire: 0 }) ?? 0,
|
|
13
|
+
maxTokens: optionalUint32(fields, { context, field: 2, wire: 0 }) ?? 0,
|
|
14
|
+
...(breakdown === undefined ? {} : { breakdown: breakdown.bytes }),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function encodeTokenDetails(details) {
|
|
18
|
+
return concatBytes([
|
|
19
|
+
...(details.usedTokens === 0 ? [] : [encodeInt32Field(1, details.usedTokens)]),
|
|
20
|
+
...(details.maxTokens === 0 ? [] : [encodeInt32Field(2, details.maxTokens)]),
|
|
21
|
+
...(details.breakdown === undefined ? [] : [encodeBytesField(3, details.breakdown)]),
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
function decodeMapEntry(bytes, context) {
|
|
25
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
26
|
+
assertKnownFields(fields, [1, 2], context);
|
|
27
|
+
return {
|
|
28
|
+
key: requiredString(fields, { context, field: 1, wire: 2 }),
|
|
29
|
+
value: requiredField(fields, { context, field: 2, wire: 2 }).bytes,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function encodeMapEntry(entry) {
|
|
33
|
+
return concatBytes([encodeStringField(1, entry.key), encodeBytesField(2, entry.value)]);
|
|
34
|
+
}
|
|
35
|
+
function repeatedBytes(fields, field, context) {
|
|
36
|
+
return repeatedFields(fields, { context, field, wire: 2 }).map((entry) => entry.bytes);
|
|
37
|
+
}
|
|
38
|
+
function repeatedStrings(fields, field, context) {
|
|
39
|
+
return repeatedFields(fields, { context, field, wire: 2 }).map((entry) => decodeUtf8Strict(entry.bytes, `${context} field ${field}`));
|
|
40
|
+
}
|
|
41
|
+
export function decodeConversationCheckpoint(bytes) {
|
|
42
|
+
const context = "ConversationStateStructure";
|
|
43
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
44
|
+
assertKnownFields(fields, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 26, 27], context);
|
|
45
|
+
const tokenDetails = optionalField(fields, { context, field: 5, wire: 2 });
|
|
46
|
+
const summaryBlob = optionalField(fields, { context, field: 6, wire: 2 });
|
|
47
|
+
const planBlob = optionalField(fields, { context, field: 7, wire: 2 });
|
|
48
|
+
const summaryArchiveBlob = optionalField(fields, { context, field: 11, wire: 2 });
|
|
49
|
+
const mode = optionalUint32(fields, { context, field: 10, wire: 0 });
|
|
50
|
+
const selfSummaryCount = optionalUint32(fields, { context, field: 17, wire: 0 });
|
|
51
|
+
const clientName = optionalString(fields, { context, field: 22, wire: 2 });
|
|
52
|
+
const conversationStartedTimestampMs = optionalField(fields, { context, field: 26, wire: 0 });
|
|
53
|
+
const conversationStartedTimeZone = optionalString(fields, { context, field: 27, wire: 2 });
|
|
54
|
+
return {
|
|
55
|
+
rootPromptMessageBlobIds: repeatedBytes(fields, 1, context),
|
|
56
|
+
legacyTurnBlobIds: repeatedBytes(fields, 2, context),
|
|
57
|
+
todoBlobIds: repeatedBytes(fields, 3, context),
|
|
58
|
+
pendingToolCalls: repeatedStrings(fields, 4, context),
|
|
59
|
+
...(tokenDetails === undefined ? {} : { tokenDetails: decodeTokenDetails(tokenDetails.bytes) }),
|
|
60
|
+
...(summaryBlob === undefined ? {} : { summaryBlob: summaryBlob.bytes }),
|
|
61
|
+
...(planBlob === undefined ? {} : { planBlob: planBlob.bytes }),
|
|
62
|
+
turnBlobIds: repeatedBytes(fields, 8, context),
|
|
63
|
+
previousWorkspaceUris: repeatedStrings(fields, 9, context),
|
|
64
|
+
...(mode === undefined ? {} : { mode }),
|
|
65
|
+
...(summaryArchiveBlob === undefined ? {} : { summaryArchiveBlob: summaryArchiveBlob.bytes }),
|
|
66
|
+
fileStates: repeatedBytes(fields, 12, context).map((entry) => decodeMapEntry(entry, "ConversationStateStructure.file_states")),
|
|
67
|
+
summaryArchiveBlobIds: repeatedBytes(fields, 13, context),
|
|
68
|
+
turnTimingMessages: repeatedBytes(fields, 14, context),
|
|
69
|
+
fileStatesV2: repeatedBytes(fields, 15, context).map((entry) => decodeMapEntry(entry, "ConversationStateStructure.file_states_v2")),
|
|
70
|
+
subagentStates: repeatedBytes(fields, 16, context).map((entry) => decodeMapEntry(entry, "ConversationStateStructure.subagent_states")),
|
|
71
|
+
...(selfSummaryCount === undefined ? {} : { selfSummaryCount }),
|
|
72
|
+
readPaths: repeatedStrings(fields, 18, context),
|
|
73
|
+
trackedGitRepoBranches: repeatedBytes(fields, 21, context),
|
|
74
|
+
...(clientName === undefined ? {} : { clientName }),
|
|
75
|
+
...(conversationStartedTimestampMs === undefined
|
|
76
|
+
? {}
|
|
77
|
+
: { conversationStartedTimestampMs: conversationStartedTimestampMs.bytes }),
|
|
78
|
+
...(conversationStartedTimeZone === undefined ? {} : { conversationStartedTimeZone }),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function encodeConversationCheckpoint(state) {
|
|
82
|
+
return concatBytes([
|
|
83
|
+
...state.rootPromptMessageBlobIds.map((value) => encodeBytesField(1, value)),
|
|
84
|
+
...state.legacyTurnBlobIds.map((value) => encodeBytesField(2, value)),
|
|
85
|
+
...state.todoBlobIds.map((value) => encodeBytesField(3, value)),
|
|
86
|
+
...state.pendingToolCalls.map((value) => encodeStringField(4, value)),
|
|
87
|
+
...(state.tokenDetails === undefined
|
|
88
|
+
? []
|
|
89
|
+
: [encodeBytesField(5, encodeTokenDetails(state.tokenDetails))]),
|
|
90
|
+
...(state.summaryBlob === undefined ? [] : [encodeBytesField(6, state.summaryBlob)]),
|
|
91
|
+
...(state.planBlob === undefined ? [] : [encodeBytesField(7, state.planBlob)]),
|
|
92
|
+
...state.turnBlobIds.map((value) => encodeBytesField(8, value)),
|
|
93
|
+
...state.previousWorkspaceUris.map((value) => encodeStringField(9, value)),
|
|
94
|
+
...(state.mode === undefined ? [] : [encodeInt32Field(10, state.mode)]),
|
|
95
|
+
...(state.summaryArchiveBlob === undefined
|
|
96
|
+
? []
|
|
97
|
+
: [encodeBytesField(11, state.summaryArchiveBlob)]),
|
|
98
|
+
...state.fileStates.map((entry) => encodeBytesField(12, encodeMapEntry(entry))),
|
|
99
|
+
...state.summaryArchiveBlobIds.map((value) => encodeBytesField(13, value)),
|
|
100
|
+
...state.turnTimingMessages.map((value) => encodeBytesField(14, value)),
|
|
101
|
+
...state.fileStatesV2.map((entry) => encodeBytesField(15, encodeMapEntry(entry))),
|
|
102
|
+
...state.subagentStates.map((entry) => encodeBytesField(16, encodeMapEntry(entry))),
|
|
103
|
+
...(state.selfSummaryCount === undefined ? [] : [encodeInt32Field(17, state.selfSummaryCount)]),
|
|
104
|
+
...state.readPaths.map((value) => encodeStringField(18, value)),
|
|
105
|
+
...state.trackedGitRepoBranches.map((value) => encodeBytesField(21, value)),
|
|
106
|
+
...(state.clientName === undefined ? [] : [encodeStringField(22, state.clientName)]),
|
|
107
|
+
...(state.conversationStartedTimestampMs === undefined
|
|
108
|
+
? []
|
|
109
|
+
: [encodeUnknownField(26, 0, state.conversationStartedTimestampMs)]),
|
|
110
|
+
...(state.conversationStartedTimeZone === undefined
|
|
111
|
+
? []
|
|
112
|
+
: [encodeStringField(27, state.conversationStartedTimeZone)]),
|
|
113
|
+
]);
|
|
114
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type SelectedImageData = {
|
|
2
|
+
readonly kind: "blob-id";
|
|
3
|
+
readonly bytes: Uint8Array;
|
|
4
|
+
} | {
|
|
5
|
+
readonly kind: "data";
|
|
6
|
+
readonly bytes: Uint8Array;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: "blob-id-with-data";
|
|
9
|
+
readonly blobId: Uint8Array;
|
|
10
|
+
readonly bytes: Uint8Array;
|
|
11
|
+
};
|
|
12
|
+
export type SelectedImage = {
|
|
13
|
+
readonly uuid: string;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly mimeType: string;
|
|
16
|
+
readonly data: SelectedImageData;
|
|
17
|
+
};
|
|
18
|
+
export type SelectedContext = {
|
|
19
|
+
readonly selectedImages: readonly SelectedImage[];
|
|
20
|
+
readonly extraContext: readonly string[];
|
|
21
|
+
};
|
|
22
|
+
export type UserMessage = {
|
|
23
|
+
readonly text: string;
|
|
24
|
+
readonly messageId: string;
|
|
25
|
+
readonly selectedContext?: SelectedContext;
|
|
26
|
+
readonly mode: number;
|
|
27
|
+
readonly isSimulatedMessage?: boolean;
|
|
28
|
+
readonly bestOfNGroupId?: string;
|
|
29
|
+
readonly tryUseBestOfNPromotion?: boolean;
|
|
30
|
+
readonly richText?: string;
|
|
31
|
+
readonly selectedContextBlob: Uint8Array;
|
|
32
|
+
readonly correlationId: string;
|
|
33
|
+
};
|
|
34
|
+
export type ConversationAction = {
|
|
35
|
+
readonly kind: "user-message";
|
|
36
|
+
readonly userMessage?: UserMessage;
|
|
37
|
+
readonly requestContextBytes?: Uint8Array;
|
|
38
|
+
readonly sendToInteractionListener?: boolean;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: "resume";
|
|
41
|
+
readonly payload: Uint8Array;
|
|
42
|
+
} | {
|
|
43
|
+
readonly kind: "cancel";
|
|
44
|
+
readonly payload: Uint8Array;
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: "summarize";
|
|
47
|
+
readonly payload: Uint8Array;
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: "shell-command";
|
|
50
|
+
readonly payload: Uint8Array;
|
|
51
|
+
} | {
|
|
52
|
+
readonly kind: "start-plan";
|
|
53
|
+
readonly payload: Uint8Array;
|
|
54
|
+
} | {
|
|
55
|
+
readonly kind: "execute-plan";
|
|
56
|
+
readonly payload: Uint8Array;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: "async-ask-question-completion";
|
|
59
|
+
readonly payload: Uint8Array;
|
|
60
|
+
};
|
|
61
|
+
export declare function decodeSelectedContext(bytes: Uint8Array): SelectedContext;
|
|
62
|
+
export declare function encodeSelectedContext(context: SelectedContext): Uint8Array;
|
|
63
|
+
export declare function decodeConversationAction(bytes: Uint8Array): ConversationAction;
|
|
64
|
+
export declare function encodeConversationAction(action: ConversationAction): Uint8Array;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// Derived from Rahularya01/pi-cursor proto/agent.proto conversation context fields. Licensed under MIT.
|
|
2
|
+
// See THIRD_PARTY_NOTICES.md.
|
|
3
|
+
import { concatBytes, decodeFieldsStrict, decodeUtf8Strict, encodeBoolField, encodeBytesField, encodeInt32Field, encodeStringField, } from "../proto-wire";
|
|
4
|
+
import { CursorProtocolError, unreachableVariant } from "./errors";
|
|
5
|
+
import { assertKnownFields, oneofField, optionalBool, optionalField, optionalString, repeatedFields, requiredField, requiredString, requiredUint32, } from "./fields";
|
|
6
|
+
function decodeImageData(bytes, field) {
|
|
7
|
+
switch (field) {
|
|
8
|
+
case 1:
|
|
9
|
+
return { kind: "blob-id", bytes };
|
|
10
|
+
case 8:
|
|
11
|
+
return { kind: "data", bytes };
|
|
12
|
+
case 9: {
|
|
13
|
+
const context = "SelectedImage.BlobIdWithData";
|
|
14
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
15
|
+
assertKnownFields(fields, [1, 2], context);
|
|
16
|
+
return {
|
|
17
|
+
kind: "blob-id-with-data",
|
|
18
|
+
blobId: requiredField(fields, { context, field: 1, wire: 2 }).bytes,
|
|
19
|
+
bytes: requiredField(fields, { context, field: 2, wire: 2 }).bytes,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
default:
|
|
23
|
+
throw new CursorProtocolError("malformed", "SelectedImage", "image data variant is absent");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function encodeImageData(data) {
|
|
27
|
+
switch (data.kind) {
|
|
28
|
+
case "blob-id":
|
|
29
|
+
return encodeBytesField(1, data.bytes);
|
|
30
|
+
case "data":
|
|
31
|
+
return encodeBytesField(8, data.bytes);
|
|
32
|
+
case "blob-id-with-data":
|
|
33
|
+
return encodeBytesField(9, concatBytes([encodeBytesField(1, data.blobId), encodeBytesField(2, data.bytes)]));
|
|
34
|
+
default:
|
|
35
|
+
return unreachableVariant(data, "SelectedImage.data");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function decodeSelectedImage(bytes) {
|
|
39
|
+
const context = "SelectedImage";
|
|
40
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
41
|
+
assertKnownFields(fields, [1, 2, 3, 7, 8, 9], context);
|
|
42
|
+
const data = oneofField(fields, [1, 8, 9], context);
|
|
43
|
+
return {
|
|
44
|
+
uuid: requiredString(fields, { context, field: 2, wire: 2 }),
|
|
45
|
+
path: optionalString(fields, { context, field: 3, wire: 2 }) ?? "",
|
|
46
|
+
mimeType: requiredString(fields, { context, field: 7, wire: 2 }),
|
|
47
|
+
data: decodeImageData(data.bytes, data.field),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function encodeSelectedImage(image) {
|
|
51
|
+
return concatBytes([
|
|
52
|
+
encodeImageData(image.data),
|
|
53
|
+
encodeStringField(2, image.uuid),
|
|
54
|
+
...(image.path === "" ? [] : [encodeStringField(3, image.path)]),
|
|
55
|
+
encodeStringField(7, image.mimeType),
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
export function decodeSelectedContext(bytes) {
|
|
59
|
+
const context = "SelectedContext";
|
|
60
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
61
|
+
assertKnownFields(fields, [1, 3], context);
|
|
62
|
+
return {
|
|
63
|
+
selectedImages: repeatedFields(fields, { context, field: 1, wire: 2 }).map((entry) => decodeSelectedImage(entry.bytes)),
|
|
64
|
+
extraContext: repeatedFields(fields, { context, field: 3, wire: 2 }).map((entry) => decodeUtf8Strict(entry.bytes, `${context} field 3`)),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function encodeSelectedContext(context) {
|
|
68
|
+
return concatBytes([
|
|
69
|
+
...context.selectedImages.map((image) => encodeBytesField(1, encodeSelectedImage(image))),
|
|
70
|
+
...context.extraContext.map((value) => encodeStringField(3, value)),
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
function decodeUserMessage(bytes) {
|
|
74
|
+
const context = "UserMessage";
|
|
75
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
76
|
+
assertKnownFields(fields, [1, 2, 3, 4, 5, 6, 7, 8, 10, 17], context);
|
|
77
|
+
const selectedContext = optionalField(fields, { context, field: 3, wire: 2 });
|
|
78
|
+
const isSimulatedMessage = optionalBool(fields, { context, field: 5, wire: 0 });
|
|
79
|
+
const bestOfNGroupId = optionalString(fields, { context, field: 6, wire: 2 });
|
|
80
|
+
const tryUseBestOfNPromotion = optionalBool(fields, { context, field: 7, wire: 0 });
|
|
81
|
+
const richText = optionalString(fields, { context, field: 8, wire: 2 });
|
|
82
|
+
const base = {
|
|
83
|
+
text: requiredString(fields, { context, field: 1, wire: 2 }),
|
|
84
|
+
messageId: requiredString(fields, { context, field: 2, wire: 2 }),
|
|
85
|
+
mode: requiredUint32(fields, { context, field: 4, wire: 0 }),
|
|
86
|
+
selectedContextBlob: requiredField(fields, { context, field: 10, wire: 2 }).bytes,
|
|
87
|
+
correlationId: requiredString(fields, { context, field: 17, wire: 2 }),
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
...base,
|
|
91
|
+
...(selectedContext === undefined
|
|
92
|
+
? {}
|
|
93
|
+
: { selectedContext: decodeSelectedContext(selectedContext.bytes) }),
|
|
94
|
+
...(isSimulatedMessage === undefined ? {} : { isSimulatedMessage }),
|
|
95
|
+
...(bestOfNGroupId === undefined ? {} : { bestOfNGroupId }),
|
|
96
|
+
...(tryUseBestOfNPromotion === undefined ? {} : { tryUseBestOfNPromotion }),
|
|
97
|
+
...(richText === undefined ? {} : { richText }),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function encodeUserMessage(message) {
|
|
101
|
+
return concatBytes([
|
|
102
|
+
encodeStringField(1, message.text),
|
|
103
|
+
encodeStringField(2, message.messageId),
|
|
104
|
+
...(message.selectedContext === undefined
|
|
105
|
+
? []
|
|
106
|
+
: [encodeBytesField(3, encodeSelectedContext(message.selectedContext))]),
|
|
107
|
+
encodeInt32Field(4, message.mode),
|
|
108
|
+
...(message.isSimulatedMessage === undefined
|
|
109
|
+
? []
|
|
110
|
+
: [encodeBoolField(5, message.isSimulatedMessage)]),
|
|
111
|
+
...(message.bestOfNGroupId === undefined ? [] : [encodeStringField(6, message.bestOfNGroupId)]),
|
|
112
|
+
...(message.tryUseBestOfNPromotion === undefined
|
|
113
|
+
? []
|
|
114
|
+
: [encodeBoolField(7, message.tryUseBestOfNPromotion)]),
|
|
115
|
+
...(message.richText === undefined ? [] : [encodeStringField(8, message.richText)]),
|
|
116
|
+
encodeBytesField(10, message.selectedContextBlob),
|
|
117
|
+
encodeStringField(17, message.correlationId),
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
export function decodeConversationAction(bytes) {
|
|
121
|
+
const context = "ConversationAction";
|
|
122
|
+
const fields = decodeFieldsStrict(bytes, { context });
|
|
123
|
+
assertKnownFields(fields, [1, 2, 3, 4, 5, 6, 7, 8], context);
|
|
124
|
+
const action = oneofField(fields, [1, 2, 3, 4, 5, 6, 7, 8], context);
|
|
125
|
+
if (action.field !== 1) {
|
|
126
|
+
const kinds = [
|
|
127
|
+
"resume",
|
|
128
|
+
"cancel",
|
|
129
|
+
"summarize",
|
|
130
|
+
"shell-command",
|
|
131
|
+
"start-plan",
|
|
132
|
+
"execute-plan",
|
|
133
|
+
"async-ask-question-completion",
|
|
134
|
+
];
|
|
135
|
+
const kind = kinds[action.field - 2];
|
|
136
|
+
if (kind === undefined) {
|
|
137
|
+
throw new CursorProtocolError("malformed", context, "action variant is absent");
|
|
138
|
+
}
|
|
139
|
+
return { kind, payload: action.bytes };
|
|
140
|
+
}
|
|
141
|
+
const actionContext = "UserMessageAction";
|
|
142
|
+
const actionFields = decodeFieldsStrict(action.bytes, { context: actionContext });
|
|
143
|
+
assertKnownFields(actionFields, [1, 2, 3], actionContext);
|
|
144
|
+
const userMessage = optionalField(actionFields, { context: actionContext, field: 1, wire: 2 });
|
|
145
|
+
const requestContext = optionalField(actionFields, { context: actionContext, field: 2, wire: 2 });
|
|
146
|
+
const listener = optionalBool(actionFields, { context: actionContext, field: 3, wire: 0 });
|
|
147
|
+
return {
|
|
148
|
+
kind: "user-message",
|
|
149
|
+
...(userMessage === undefined ? {} : { userMessage: decodeUserMessage(userMessage.bytes) }),
|
|
150
|
+
...(requestContext === undefined ? {} : { requestContextBytes: requestContext.bytes }),
|
|
151
|
+
...(listener === undefined ? {} : { sendToInteractionListener: listener }),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function encodeConversationAction(action) {
|
|
155
|
+
if (action.kind !== "user-message") {
|
|
156
|
+
const fields = {
|
|
157
|
+
resume: 2,
|
|
158
|
+
cancel: 3,
|
|
159
|
+
summarize: 4,
|
|
160
|
+
"shell-command": 5,
|
|
161
|
+
"start-plan": 6,
|
|
162
|
+
"execute-plan": 7,
|
|
163
|
+
"async-ask-question-completion": 8,
|
|
164
|
+
};
|
|
165
|
+
return encodeBytesField(fields[action.kind], action.payload);
|
|
166
|
+
}
|
|
167
|
+
return encodeBytesField(1, concatBytes([
|
|
168
|
+
...(action.userMessage === undefined
|
|
169
|
+
? []
|
|
170
|
+
: [encodeBytesField(1, encodeUserMessage(action.userMessage))]),
|
|
171
|
+
...(action.requestContextBytes === undefined
|
|
172
|
+
? []
|
|
173
|
+
: [encodeBytesField(2, action.requestContextBytes)]),
|
|
174
|
+
...(action.sendToInteractionListener === undefined
|
|
175
|
+
? []
|
|
176
|
+
: [encodeBoolField(3, action.sendToInteractionListener)]),
|
|
177
|
+
]));
|
|
178
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CursorProtocolReason = "malformed" | "truncated" | "wrong-wire" | "oversized" | "unsupported-flags";
|
|
2
|
+
export declare class CursorProtocolError extends Error {
|
|
3
|
+
readonly reason: CursorProtocolReason;
|
|
4
|
+
readonly context: string;
|
|
5
|
+
readonly name = "CursorProtocolError";
|
|
6
|
+
readonly code = "CURSOR_PROTOCOL_ERROR";
|
|
7
|
+
constructor(reason: CursorProtocolReason, context: string, detail: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class CursorProtocolDriftError extends Error {
|
|
10
|
+
readonly context: string;
|
|
11
|
+
readonly field: number;
|
|
12
|
+
readonly name = "CursorProtocolDriftError";
|
|
13
|
+
readonly code = "CURSOR_PROTOCOL_DRIFT";
|
|
14
|
+
constructor(context: string, field: number, detail?: string);
|
|
15
|
+
}
|
|
16
|
+
export declare function unreachableVariant(value: never, context: string): never;
|