feat: implemented provider wire codecs and optimized telemetry and parsing
- Added internal protobuf wire codecs, message builders, and protocol definitions for Cursor and Devin providers. - Deferred loading of OTel SDK and OTLP exporters and added bounded caches to optimize startup and lookup performance. - Added SQLite-backed parse caching for legacy extension source analysis and streaming file chunk parsing for changelogs. - Added support for rendering context usage overflow above 100% in the status line component.
This commit is contained in:
@@ -65,6 +65,8 @@
|
|||||||
"!**/test-sessions.ts",
|
"!**/test-sessions.ts",
|
||||||
"!**/agent_pb.ts",
|
"!**/agent_pb.ts",
|
||||||
"!**/devin-gen/**/*",
|
"!**/devin-gen/**/*",
|
||||||
|
"!packages/catalog/src/discovery/cursor-proto.ts",
|
||||||
|
"!packages/catalog/src/discovery/devin-proto.ts",
|
||||||
"!.worktrees/**/*",
|
"!.worktrees/**/*",
|
||||||
"!.wt/**/*"
|
"!.wt/**/*"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -42,14 +42,12 @@
|
|||||||
"name": "@oh-my-pi/pi-ai",
|
"name": "@oh-my-pi/pi-ai",
|
||||||
"version": "17.3.8",
|
"version": "17.3.8",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bufbuild/protobuf": "catalog:",
|
|
||||||
"@oh-my-pi/omptype": "catalog:",
|
"@oh-my-pi/omptype": "catalog:",
|
||||||
"@oh-my-pi/pi-catalog": "catalog:",
|
"@oh-my-pi/pi-catalog": "catalog:",
|
||||||
"@oh-my-pi/pi-utils": "catalog:",
|
"@oh-my-pi/pi-utils": "catalog:",
|
||||||
"@oh-my-pi/pi-wire": "catalog:",
|
"@oh-my-pi/pi-wire": "catalog:",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@bufbuild/protoc-gen-es": "catalog:",
|
|
||||||
"@types/bun": "catalog:",
|
"@types/bun": "catalog:",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -65,7 +63,6 @@
|
|||||||
"name": "@oh-my-pi/pi-catalog",
|
"name": "@oh-my-pi/pi-catalog",
|
||||||
"version": "17.3.8",
|
"version": "17.3.8",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bufbuild/protobuf": "catalog:",
|
|
||||||
"@oh-my-pi/omptype": "catalog:",
|
"@oh-my-pi/omptype": "catalog:",
|
||||||
"@oh-my-pi/pi-utils": "catalog:",
|
"@oh-my-pi/pi-utils": "catalog:",
|
||||||
},
|
},
|
||||||
@@ -350,8 +347,6 @@
|
|||||||
"@babel/traverse": "^7.29.7",
|
"@babel/traverse": "^7.29.7",
|
||||||
"@babel/types": "^7.29.7",
|
"@babel/types": "^7.29.7",
|
||||||
"@biomejs/biome": "^2.5.3",
|
"@biomejs/biome": "^2.5.3",
|
||||||
"@bufbuild/protobuf": "^2.12.1",
|
|
||||||
"@bufbuild/protoc-gen-es": "^2.12.1",
|
|
||||||
"@huggingface/transformers": "^4.2.0",
|
"@huggingface/transformers": "^4.2.0",
|
||||||
"@napi-rs/cli": "3.7.2",
|
"@napi-rs/cli": "3.7.2",
|
||||||
"@oh-my-pi/hashline": "17.3.8",
|
"@oh-my-pi/hashline": "17.3.8",
|
||||||
@@ -478,12 +473,6 @@
|
|||||||
|
|
||||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.8", "", { "os": "win32", "cpu": "x64" }, "sha512-I2czzXTY61f3nFJxXoMDq80t7MivxDEnCjE+8sDKoFfcKMaoQdkqhIFQ3KyY0XLzeSpUBYeNAXgD+iOV/BU0VA=="],
|
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.8", "", { "os": "win32", "cpu": "x64" }, "sha512-I2czzXTY61f3nFJxXoMDq80t7MivxDEnCjE+8sDKoFfcKMaoQdkqhIFQ3KyY0XLzeSpUBYeNAXgD+iOV/BU0VA=="],
|
||||||
|
|
||||||
"@bufbuild/protobuf": ["@bufbuild/protobuf@2.14.0", "", {}, "sha512-C3UGsiCwSprE2NKIIFA3hCDlpXTMCAXRZuEVp88L1GY36Y41+rYL5fryE+nOFhp4p4JPQvdV8PQ4DWgHgeTE+w=="],
|
|
||||||
|
|
||||||
"@bufbuild/protoc-gen-es": ["@bufbuild/protoc-gen-es@2.14.0", "", { "dependencies": { "@bufbuild/protobuf": "2.14.0", "@bufbuild/protoplugin": "2.14.0" }, "bin": { "protoc-gen-es": "bin/protoc-gen-es" } }, "sha512-/Rrui0BJWSRONiKGYzqWq9ivGN3+cYkmc47QWITufr7K6yDb8HfssuJUSQZeptyg/rHbHrfDzCUjzoJ2pwuafg=="],
|
|
||||||
|
|
||||||
"@bufbuild/protoplugin": ["@bufbuild/protoplugin@2.14.0", "", { "dependencies": { "@bufbuild/protobuf": "2.14.0", "@typescript/vfs": "^1.6.2", "typescript": "5.4.5" } }, "sha512-S0TvZhVtTEkZQRj2JsXBCXiib/b0+bLQtJCcn+hj9O/usgbcgxHn4D+ii22Ao3qj0/kKxVYeo7BtAI2dMk+iig=="],
|
|
||||||
|
|
||||||
"@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
"@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="],
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
"@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||||
@@ -1414,10 +1403,6 @@
|
|||||||
|
|
||||||
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"@bufbuild/protoplugin/@typescript/vfs": ["@typescript/vfs@1.6.4", "", { "dependencies": { "debug": "^4.4.3" }, "peerDependencies": { "typescript": "*" } }, "sha512-PJFXFS4ZJKiJ9Qiuix6Dz/OwEIqHD7Dme1UwZhTK11vR+5dqW2ACbdndWQexBzCx+CPuMe5WBYQWCsFyGlQLlQ=="],
|
|
||||||
|
|
||||||
"@bufbuild/protoplugin/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="],
|
|
||||||
|
|
||||||
"@huggingface/transformers/onnxruntime-node": ["onnxruntime-node@1.24.3", "", { "dependencies": { "adm-zip": "^0.5.16", "global-agent": "^3.0.0", "onnxruntime-common": "1.24.3" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg=="],
|
"@huggingface/transformers/onnxruntime-node": ["onnxruntime-node@1.24.3", "", { "dependencies": { "adm-zip": "^0.5.16", "global-agent": "^3.0.0", "onnxruntime-common": "1.24.3" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg=="],
|
||||||
|
|
||||||
"@isaacs/fs-minipass/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
|
"@isaacs/fs-minipass/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ The Ollama integration consists of two distinct provider definitions in `package
|
|||||||
Cursor's integration in `packages/ai` operates over an HTTP/2 Connect RPC transport (`/agent.v1.AgentService/Run`) sending length-prefixed binary Protobuf messages (`AgentClientMessage` and `AgentServerMessage`). Key implementation entry points include `packages/ai/src/providers/cursor.ts` for connection lifecycle, Connect message streaming, and frame dispatching; `packages/ai/src/providers/cursor-pi-args.ts` for pure argument and path transformations; `packages/ai/src/providers/cursor/exec-modern.ts` for local tool result frame builders; `packages/ai/src/registry/cursor.ts` and `packages/ai/src/registry/oauth/cursor.ts` for PKCE browser authentication and token refresh; `packages/ai/src/usage/cursor.ts` for multi-endpoint quota tracking; and `packages/catalog/src/discovery/cursor.ts` for Connect RPC model discovery.
|
Cursor's integration in `packages/ai` operates over an HTTP/2 Connect RPC transport (`/agent.v1.AgentService/Run`) sending length-prefixed binary Protobuf messages (`AgentClientMessage` and `AgentServerMessage`). Key implementation entry points include `packages/ai/src/providers/cursor.ts` for connection lifecycle, Connect message streaming, and frame dispatching; `packages/ai/src/providers/cursor-pi-args.ts` for pure argument and path transformations; `packages/ai/src/providers/cursor/exec-modern.ts` for local tool result frame builders; `packages/ai/src/registry/cursor.ts` and `packages/ai/src/registry/oauth/cursor.ts` for PKCE browser authentication and token refresh; `packages/ai/src/usage/cursor.ts` for multi-endpoint quota tracking; and `packages/catalog/src/discovery/cursor.ts` for Connect RPC model discovery.
|
||||||
|
|
||||||
### Special casings
|
### Special casings
|
||||||
- **Pure Argument Translation (`cursor-pi-args.ts`)**: Path and argument formatting functions (`piReadPath`, `piReadPathHasRange`, `piReadDisplayPath`, `piGrepSkip`, `piJoinPath`, `piLsPath`, `piEscapeRegexLiteral`, `piLimit`, `piTimeout`) are kept strictly independent of Protobuf imports so legacy shims can share them without bundling `@bufbuild/protobuf` into virtual registries.
|
- **Pure Argument Translation (`cursor-pi-args.ts`)**: Path and argument formatting functions (`piReadPath`, `piReadPathHasRange`, `piReadDisplayPath`, `piGrepSkip`, `piJoinPath`, `piLsPath`, `piEscapeRegexLiteral`, `piLimit`, `piTimeout`) are kept strictly independent of Protobuf imports so legacy shims can share them without bundling protobuf schemas into virtual registries.
|
||||||
- **Empty Grep Pattern Rejection**: `grepArgs` frames with an empty `pattern` and non-empty `glob` are rejected up front (`emptyGrepPatternRejection`) with a descriptive error, forcing the model to retry or switch tools rather than triggering local tool failure after block persistence.
|
- **Empty Grep Pattern Rejection**: `grepArgs` frames with an empty `pattern` and non-empty `glob` are rejected up front (`emptyGrepPatternRejection`) with a descriptive error, forcing the model to retry or switch tools rather than triggering local tool failure after block persistence.
|
||||||
- **Native Tools & `SoftToolRequirement` Interplay**:
|
- **Native Tools & `SoftToolRequirement` Interplay**:
|
||||||
- Native tools (`CURSOR_NATIVE_TOOL_NAMES`: `bash`, `read`, `write`, `delete`, `ls`, `grep`, `todo`) are omitted when building `requestContext` MCP tool definitions.
|
- Native tools (`CURSOR_NATIVE_TOOL_NAMES`: `bash`, `read`, `write`, `delete`, `ls`, `grep`, `todo`) are omitted when building `requestContext` MCP tool definitions.
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
"@babel/traverse": "^7.29.7",
|
"@babel/traverse": "^7.29.7",
|
||||||
"@babel/types": "^7.29.7",
|
"@babel/types": "^7.29.7",
|
||||||
"@biomejs/biome": "^2.5.3",
|
"@biomejs/biome": "^2.5.3",
|
||||||
"@bufbuild/protobuf": "^2.12.1",
|
|
||||||
"@bufbuild/protoc-gen-es": "^2.12.1",
|
|
||||||
"@huggingface/transformers": "^4.2.0",
|
"@huggingface/transformers": "^4.2.0",
|
||||||
"@napi-rs/cli": "3.7.2",
|
"@napi-rs/cli": "3.7.2",
|
||||||
"@oh-my-pi/hashline": "17.3.8",
|
"@oh-my-pi/hashline": "17.3.8",
|
||||||
|
|||||||
@@ -37,14 +37,12 @@
|
|||||||
"fmt": "biome format --write ."
|
"fmt": "biome format --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bufbuild/protobuf": "catalog:",
|
|
||||||
"@oh-my-pi/omptype": "catalog:",
|
"@oh-my-pi/omptype": "catalog:",
|
||||||
"@oh-my-pi/pi-catalog": "catalog:",
|
"@oh-my-pi/pi-catalog": "catalog:",
|
||||||
"@oh-my-pi/pi-utils": "catalog:",
|
"@oh-my-pi/pi-utils": "catalog:",
|
||||||
"@oh-my-pi/pi-wire": "catalog:"
|
"@oh-my-pi/pi-wire": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@bufbuild/protoc-gen-es": "catalog:",
|
|
||||||
"@types/bun": "catalog:"
|
"@types/bun": "catalog:"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Extracts protobuf definitions from bundled JavaScript generated by @bufbuild/protobuf.
|
Extracts protobuf definitions from bundled JavaScript.
|
||||||
Reconstructs .proto files with comments preserved.
|
Reconstructs .proto files with comments preserved.
|
||||||
|
|
||||||
Usage: python proto-extractor.py <bundled-js-file> <output-dir>
|
Usage: python proto-extractor.py <bundled-js-file> <output-dir>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
* Kept apart from `cursor/exec-modern.ts` on purpose: these are pure
|
* Kept apart from `cursor/exec-modern.ts` on purpose: these are pure
|
||||||
* string/path functions with no protobuf coupling, while that module pulls in
|
* string/path functions with no protobuf coupling, while that module pulls in
|
||||||
* `@bufbuild/protobuf` and the generated `agent_pb` graph. The legacy shim is
|
* the generated cursor protobuf graph. The legacy shim is
|
||||||
* compiled into the bundled virtual module registry, so importing it from a
|
* compiled into the bundled virtual module registry, so importing it from a
|
||||||
* nested path would drag the whole exec implementation in with it — and
|
* nested path would drag the whole exec implementation in with it — and
|
||||||
* `./providers/*` is a single-segment wildcard export that cannot serve a
|
* `./providers/*` is a single-segment wildcard export that cannot serve a
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { createHash } from "node:crypto";
|
import { createHash } from "node:crypto";
|
||||||
import * as fs from "node:fs/promises";
|
import * as fs from "node:fs/promises";
|
||||||
import http2 from "node:http2";
|
import http2 from "node:http2";
|
||||||
import { create, fromBinary, fromJson, type JsonValue, toBinary, toJson } from "@bufbuild/protobuf";
|
import type { ConversationStep, McpToolDefinition } from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import { ValueSchema } from "@bufbuild/protobuf/wkt";
|
|
||||||
import type { ConversationStep, McpToolDefinition } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
|
||||||
import {
|
import {
|
||||||
AgentClientMessageSchema,
|
AgentClientMessageSchema,
|
||||||
AgentConversationTurnStructureSchema,
|
AgentConversationTurnStructureSchema,
|
||||||
@@ -139,11 +137,21 @@ import {
|
|||||||
WriteShellStdinErrorSchema,
|
WriteShellStdinErrorSchema,
|
||||||
WriteShellStdinResultSchema,
|
WriteShellStdinResultSchema,
|
||||||
WriteSuccessSchema,
|
WriteSuccessSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
import {
|
||||||
|
create,
|
||||||
|
decodeJsonValue,
|
||||||
|
encodeJsonValue,
|
||||||
|
fromBinary,
|
||||||
|
type JsonValue,
|
||||||
|
toBinary,
|
||||||
|
toJson,
|
||||||
|
} from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { isKimiK3ModelId } from "@oh-my-pi/pi-catalog/identity";
|
import { isKimiK3ModelId } from "@oh-my-pi/pi-catalog/identity";
|
||||||
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
||||||
import {
|
import {
|
||||||
$env,
|
$env,
|
||||||
|
isRecord,
|
||||||
logger,
|
logger,
|
||||||
parseJsonWithRepair,
|
parseJsonWithRepair,
|
||||||
parseStreamingJson,
|
parseStreamingJson,
|
||||||
@@ -3099,8 +3107,7 @@ function parseToolArgsJson(text: string): unknown {
|
|||||||
|
|
||||||
function decodeMcpArgValue(value: Uint8Array): unknown {
|
function decodeMcpArgValue(value: Uint8Array): unknown {
|
||||||
try {
|
try {
|
||||||
const parsedValue = fromBinary(ValueSchema, value);
|
const jsonValue = decodeJsonValue(value);
|
||||||
const jsonValue = toJson(ValueSchema, parsedValue) as JsonValue;
|
|
||||||
if (typeof jsonValue === "string") {
|
if (typeof jsonValue === "string") {
|
||||||
return parseToolArgsJson(jsonValue);
|
return parseToolArgsJson(jsonValue);
|
||||||
}
|
}
|
||||||
@@ -4212,10 +4219,10 @@ export function buildMcpToolDefinitions(tools: Tool[] | undefined): McpToolDefin
|
|||||||
return forwarded.map(tool => {
|
return forwarded.map(tool => {
|
||||||
const jsonSchema = toolWireSchema(tool);
|
const jsonSchema = toolWireSchema(tool);
|
||||||
const schemaValue: JsonValue =
|
const schemaValue: JsonValue =
|
||||||
jsonSchema && typeof jsonSchema === "object"
|
jsonSchema !== null && !Array.isArray(jsonSchema) && isJsonValue(jsonSchema)
|
||||||
? (jsonSchema as JsonValue)
|
? jsonSchema
|
||||||
: { type: "object", properties: {}, required: [] };
|
: { type: "object", properties: {}, required: [] };
|
||||||
const inputSchema = toBinary(ValueSchema, fromJson(ValueSchema, schemaValue));
|
const inputSchema = encodeJsonValue(schemaValue);
|
||||||
return create(McpToolDefinitionSchema, {
|
return create(McpToolDefinitionSchema, {
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
description: tool.description || "",
|
description: tool.description || "",
|
||||||
@@ -4463,17 +4470,11 @@ function buildRootPromptMessagesJson(
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPlainRecord(value: unknown): value is Record<string, unknown> {
|
|
||||||
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
||||||
const prototype = Object.getPrototypeOf(value);
|
|
||||||
return prototype === Object.prototype || prototype === null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isJsonValue(value: unknown): value is JsonValue {
|
function isJsonValue(value: unknown): value is JsonValue {
|
||||||
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
||||||
if (typeof value === "number") return Number.isFinite(value);
|
if (typeof value === "number") return Number.isFinite(value);
|
||||||
if (Array.isArray(value)) return value.every(isJsonValue);
|
if (Array.isArray(value)) return value.every(isJsonValue);
|
||||||
if (!isPlainRecord(value)) return false;
|
if (!isRecord(value)) return false;
|
||||||
for (const key in value) {
|
for (const key in value) {
|
||||||
if (!isJsonValue(value[key])) return false;
|
if (!isJsonValue(value[key])) return false;
|
||||||
}
|
}
|
||||||
@@ -4488,7 +4489,7 @@ function encodeCursorMcpArguments(toolCall: ToolCall): Record<string, Uint8Array
|
|||||||
if (!isJsonValue(value)) {
|
if (!isJsonValue(value)) {
|
||||||
throw new AIError.ValidationError(`Cursor tool argument ${toolCall.name}.${name} is not JSON-serializable`);
|
throw new AIError.ValidationError(`Cursor tool argument ${toolCall.name}.${name} is not JSON-serializable`);
|
||||||
}
|
}
|
||||||
encoded[name] = toBinary(ValueSchema, fromJson(ValueSchema, value));
|
encoded[name] = encodeJsonValue(value);
|
||||||
}
|
}
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* the server reads as "the tool ran and produced nothing".
|
* the server reads as "the tool ran and produced nothing".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { create } from "@bufbuild/protobuf";
|
import { create } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
import {
|
||||||
AfterAgentResponseRequestResponseSchema,
|
AfterAgentResponseRequestResponseSchema,
|
||||||
AfterAgentThoughtRequestResponseSchema,
|
AfterAgentThoughtRequestResponseSchema,
|
||||||
@@ -64,7 +64,7 @@ import {
|
|||||||
StopRequestResponseSchema,
|
StopRequestResponseSchema,
|
||||||
SubagentStartRequestResponseSchema,
|
SubagentStartRequestResponseSchema,
|
||||||
SubagentStopRequestResponseSchema,
|
SubagentStopRequestResponseSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import type { ToolResultMessage } from "../../types";
|
import type { ToolResultMessage } from "../../types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type http2 from "node:http2";
|
import type http2 from "node:http2";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
import {
|
||||||
AgentClientMessageSchema,
|
AgentClientMessageSchema,
|
||||||
AskQuestionInteractionResponseSchema,
|
AskQuestionInteractionResponseSchema,
|
||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
WebFetchRequestResponseSchema,
|
WebFetchRequestResponseSchema,
|
||||||
WebSearchRequestResponse_ApprovedSchema,
|
WebSearchRequestResponse_ApprovedSchema,
|
||||||
WebSearchRequestResponseSchema,
|
WebSearchRequestResponseSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import { $env } from "@oh-my-pi/pi-utils";
|
import { $env } from "@oh-my-pi/pi-utils";
|
||||||
|
|
||||||
const NOT_IMPLEMENTED_SUFFIX = "not implemented by this client";
|
const NOT_IMPLEMENTED_SUFFIX = "not implemented by this client";
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
version: v2
|
|
||||||
plugins:
|
|
||||||
- local: /work/pi/node_modules/.bin/protoc-gen-es
|
|
||||||
out: ../gen
|
|
||||||
opt:
|
|
||||||
- target=ts
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
version: v2
|
|
||||||
modules:
|
|
||||||
- path: .
|
|
||||||
lint:
|
|
||||||
use:
|
|
||||||
- STANDARD
|
|
||||||
except:
|
|
||||||
- COMMENT_FIELD
|
|
||||||
- COMMENT_MESSAGE
|
|
||||||
- COMMENT_ENUM
|
|
||||||
- COMMENT_ENUM_VALUE
|
|
||||||
- COMMENT_RPC
|
|
||||||
- COMMENT_SERVICE
|
|
||||||
- COMMENT_ONEOF
|
|
||||||
breaking:
|
|
||||||
use:
|
|
||||||
- FILE
|
|
||||||
@@ -1,32 +1,26 @@
|
|||||||
import { gunzipSync, gzipSync } from "node:zlib";
|
import { gunzipSync, gzipSync } from "node:zlib";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
|
||||||
ChatMessageRequestType,
|
|
||||||
GetChatMessageRequestSchema,
|
|
||||||
GetChatMessageResponseSchema,
|
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/api_server_pb/api_server_pb";
|
|
||||||
import {
|
|
||||||
GetUserJwtRequestSchema,
|
|
||||||
GetUserJwtResponseSchema,
|
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
|
||||||
import {
|
import {
|
||||||
CacheControlType,
|
CacheControlType,
|
||||||
type ChatMessagePrompt,
|
type ChatMessagePrompt,
|
||||||
ChatMessagePromptSchema,
|
ChatMessagePromptSchema,
|
||||||
ChatToolChoiceSchema,
|
ChatMessageRequestType,
|
||||||
ChatToolDefinitionSchema,
|
|
||||||
PromptCacheOptionsSchema,
|
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/chat_pb/chat_pb";
|
|
||||||
import {
|
|
||||||
ChatMessageSource,
|
ChatMessageSource,
|
||||||
type ChatToolCall,
|
type ChatToolCall,
|
||||||
ChatToolCallSchema,
|
ChatToolCallSchema,
|
||||||
|
ChatToolChoiceSchema,
|
||||||
|
ChatToolDefinitionSchema,
|
||||||
CompletionConfigurationSchema,
|
CompletionConfigurationSchema,
|
||||||
ConversationalPlannerMode,
|
ConversationalPlannerMode,
|
||||||
|
GetChatMessageRequestSchema,
|
||||||
|
GetChatMessageResponseSchema,
|
||||||
|
GetUserJwtRequestSchema,
|
||||||
|
GetUserJwtResponseSchema,
|
||||||
ImageDataSchema,
|
ImageDataSchema,
|
||||||
MetadataSchema,
|
MetadataSchema,
|
||||||
|
PromptCacheOptionsSchema,
|
||||||
StopReason,
|
StopReason,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
import { calculateCost } from "@oh-my-pi/pi-catalog/models";
|
||||||
import { logger, parseStreamingJson, parseStreamingJsonThrottled } from "@oh-my-pi/pi-utils";
|
import { logger, parseStreamingJson, parseStreamingJsonThrottled } from "@oh-my-pi/pi-utils";
|
||||||
import * as AIError from "../error";
|
import * as AIError from "../error";
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
version: v2
|
|
||||||
# Codegen is scoped to the api_server.proto transitive closure (the RPCs the
|
|
||||||
# devin provider actually uses). The rest of the reverse-engineered Codeium
|
|
||||||
# corpus is kept in this directory for reference/maintenance but is NOT
|
|
||||||
# generated. Vendored google/* WKTs are intentionally absent — buf bundles them.
|
|
||||||
inputs:
|
|
||||||
- directory: .
|
|
||||||
paths:
|
|
||||||
- buf/validate/validate.proto
|
|
||||||
- exa/analytics_pb/analytics.proto
|
|
||||||
- exa/api_server_pb/api_server.proto
|
|
||||||
- exa/auth_pb/auth.proto
|
|
||||||
- exa/auto_cascade_common_pb/auto_cascade_common.proto
|
|
||||||
- exa/bug_checker_pb/bug_checker.proto
|
|
||||||
- exa/cascade_plugins_pb/cascade_plugins.proto
|
|
||||||
- exa/chat_pb/chat.proto
|
|
||||||
- exa/code_edit/code_edit_pb/code_edit.proto
|
|
||||||
- exa/codeium_common_pb/codeium_common.proto
|
|
||||||
- exa/context_module_pb/context_module.proto
|
|
||||||
- exa/cortex_pb/cortex.proto
|
|
||||||
- exa/diff_action_pb/diff_action.proto
|
|
||||||
- exa/index_pb/index.proto
|
|
||||||
- exa/knowledge_base_pb/knowledge_base.proto
|
|
||||||
- exa/language_server_pb/language_server.proto
|
|
||||||
- exa/opensearch_clients_pb/opensearch_clients.proto
|
|
||||||
- exa/prompt_pb/prompt.proto
|
|
||||||
- exa/reactive_component_pb/reactive_component.proto
|
|
||||||
- exa/trust_pb/trust.proto
|
|
||||||
plugins:
|
|
||||||
- local: ../../../../../../node_modules/.bin/protoc-gen-es
|
|
||||||
out: ../../../../../catalog/src/discovery/devin-gen
|
|
||||||
opt:
|
|
||||||
- target=ts
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
version: v2
|
|
||||||
modules:
|
|
||||||
- path: .
|
|
||||||
lint:
|
|
||||||
use:
|
|
||||||
- STANDARD
|
|
||||||
except:
|
|
||||||
- COMMENT_FIELD
|
|
||||||
- COMMENT_MESSAGE
|
|
||||||
- COMMENT_ENUM
|
|
||||||
- COMMENT_ENUM_VALUE
|
|
||||||
- COMMENT_RPC
|
|
||||||
- COMMENT_SERVICE
|
|
||||||
- COMMENT_ONEOF
|
|
||||||
breaking:
|
|
||||||
use:
|
|
||||||
- FILE
|
|
||||||
@@ -40,7 +40,7 @@ import type { OpenAICompletionsOptions } from "./providers/openai-completions";
|
|||||||
import { streamPiNative } from "./providers/pi-native-client";
|
import { streamPiNative } from "./providers/pi-native-client";
|
||||||
// Heavy provider stream functions are imported lazily via register-builtins,
|
// Heavy provider stream functions are imported lazily via register-builtins,
|
||||||
// which wraps each provider module in a dynamic import. This keeps the
|
// which wraps each provider module in a dynamic import. This keeps the
|
||||||
// AWS SDK, google-auth-library, @google/genai, @bufbuild/protobuf, and
|
// AWS SDK, google-auth-library, @google/genai, and
|
||||||
// other provider SDKs out of the CLI startup parse graph. The
|
// other provider SDKs out of the CLI startup parse graph. The
|
||||||
// gitlab-duo / kimi / synthetic providers stay eager because their modules
|
// gitlab-duo / kimi / synthetic providers stay eager because their modules
|
||||||
// export routing predicates (isGitLabDuoModel, isKimiModel, isSyntheticModel)
|
// export routing predicates (isGitLabDuoModel, isKimiModel, isSyntheticModel)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import type {
|
|||||||
ShellResult,
|
ShellResult,
|
||||||
WriteArgs,
|
WriteArgs,
|
||||||
WriteResult,
|
WriteResult,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
||||||
import { isOpenAIModelId } from "@oh-my-pi/pi-catalog/identity/family";
|
import { isOpenAIModelId } from "@oh-my-pi/pi-catalog/identity/family";
|
||||||
import type { Api, FetchImpl, KnownApi, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
|
import type { Api, FetchImpl, KnownApi, Model, Provider, ThinkingBudgets, Usage } from "@oh-my-pi/pi-catalog/types";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "bun:test";
|
import { afterEach, describe, expect, it } from "bun:test";
|
||||||
import * as http2 from "node:http2";
|
import * as http2 from "node:http2";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
InteractionUpdateSchema,
|
InteractionUpdateSchema,
|
||||||
TextDeltaUpdateSchema,
|
TextDeltaUpdateSchema,
|
||||||
TurnEndedUpdateSchema,
|
TurnEndedUpdateSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
// Cursor forwards caller headers (including `before_provider_headers` extension
|
// Cursor forwards caller headers (including `before_provider_headers` extension
|
||||||
// edits), and it speaks HTTP/2. These assert the TRANSPORT contract against a
|
// edits), and it speaks HTTP/2. These assert the TRANSPORT contract against a
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "bun:test";
|
import { afterEach, describe, expect, it } from "bun:test";
|
||||||
import * as http2 from "node:http2";
|
import * as http2 from "node:http2";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
InteractionUpdateSchema,
|
InteractionUpdateSchema,
|
||||||
TextDeltaUpdateSchema,
|
TextDeltaUpdateSchema,
|
||||||
TurnEndedUpdateSchema,
|
TurnEndedUpdateSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
// #8345: a server-side per-conversation rejection (bare resource_exhausted,
|
// #8345: a server-side per-conversation rejection (bare resource_exhausted,
|
||||||
// zero tokens) poisons the wire conversationId; the next attempt must rotate
|
// zero tokens) poisons the wire conversationId; the next attempt must rotate
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { afterEach, describe, expect, it, vi } from "bun:test";
|
import { afterEach, describe, expect, it, vi } from "bun:test";
|
||||||
import { create } from "@bufbuild/protobuf";
|
import { create } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
import {
|
||||||
type BlockState,
|
type BlockState,
|
||||||
buildCursorHistoryForTest,
|
buildCursorHistoryForTest,
|
||||||
@@ -16,7 +16,7 @@ import type { AssistantMessage, Context, CursorExecHandlers, Model, ToolResultMe
|
|||||||
import { kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
|
import { kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
|
||||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import type { McpResult, ReadResult } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
import type { McpResult, ReadResult } from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import {
|
import {
|
||||||
type AgentRunRequest,
|
type AgentRunRequest,
|
||||||
AgentServerMessageSchema,
|
AgentServerMessageSchema,
|
||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
ReadRejectedSchema,
|
ReadRejectedSchema,
|
||||||
ReadResultSchema,
|
ReadResultSchema,
|
||||||
ReadSuccessSchema,
|
ReadSuccessSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import { logger } from "@oh-my-pi/pi-utils";
|
import { logger } from "@oh-my-pi/pi-utils";
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
import {
|
||||||
type BlockState,
|
type BlockState,
|
||||||
CURSOR_CLIENT_VERSION,
|
CURSOR_CLIENT_VERSION,
|
||||||
@@ -64,7 +64,7 @@ import {
|
|||||||
SubagentAwaitArgsSchema,
|
SubagentAwaitArgsSchema,
|
||||||
ToolCallSchema,
|
ToolCallSchema,
|
||||||
WebFetchAllowlistPrecheckArgsSchema,
|
WebFetchAllowlistPrecheckArgsSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drive one `ExecServerMessage` through the real dispatcher and decode every
|
* Drive one `ExecServerMessage` through the real dispatcher and decode every
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, fromBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { AssistantMessage } from "@oh-my-pi/pi-ai/types";
|
import type { AssistantMessage } from "@oh-my-pi/pi-ai/types";
|
||||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
SetupVmEnvironmentArgsSchema,
|
SetupVmEnvironmentArgsSchema,
|
||||||
SwitchModeRequestQuerySchema,
|
SwitchModeRequestQuerySchema,
|
||||||
WebSearchRequestQuerySchema,
|
WebSearchRequestQuerySchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
type ProtoUnknownField = { no: number; wireType: number; data: Uint8Array };
|
type ProtoUnknownField = { no: number; wireType: number; data: Uint8Array };
|
||||||
type ProtoUnknownBag = { $unknown?: ProtoUnknownField[] };
|
type ProtoUnknownBag = { $unknown?: ProtoUnknownField[] };
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
// buildGrpcRequest is exercised directly (the transport is HTTP/2), and the
|
// buildGrpcRequest is exercised directly (the transport is HTTP/2), and the
|
||||||
// serialized run request is decoded back from the wire bytes.
|
// serialized run request is decoded back from the wire bytes.
|
||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { fromBinary } from "@bufbuild/protobuf";
|
import { fromBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { buildGrpcRequest } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { buildGrpcRequest } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { AgentClientMessageSchema } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
import { AgentClientMessageSchema } from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
const model: Model<"cursor-agent"> = buildModel({
|
const model: Model<"cursor-agent"> = buildModel({
|
||||||
id: "cursor-composer-2.5",
|
id: "cursor-composer-2.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { afterEach, describe, expect, it } from "bun:test";
|
import { afterEach, describe, expect, it } from "bun:test";
|
||||||
import * as http2 from "node:http2";
|
import * as http2 from "node:http2";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { streamCursor } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { Context, CursorToolResultHandler, Model, ToolResultMessage } from "@oh-my-pi/pi-ai/types";
|
import type { Context, CursorToolResultHandler, Model, ToolResultMessage } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
TurnEndedUpdateSchema,
|
TurnEndedUpdateSchema,
|
||||||
UpdateTodosArgsSchema,
|
UpdateTodosArgsSchema,
|
||||||
UpdateTodosToolCallSchema,
|
UpdateTodosToolCallSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
const CONNECT_END_STREAM_FLAG = 0b00000010;
|
const CONNECT_END_STREAM_FLAG = 0b00000010;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import {
|
import {
|
||||||
type BlockState,
|
type BlockState,
|
||||||
processInteractionUpdate,
|
processInteractionUpdate,
|
||||||
@@ -29,7 +29,7 @@ import {
|
|||||||
UpdateTodosResultSchema,
|
UpdateTodosResultSchema,
|
||||||
UpdateTodosSuccessSchema,
|
UpdateTodosSuccessSchema,
|
||||||
UpdateTodosToolCallSchema,
|
UpdateTodosToolCallSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
/** One `todoSync` invocation, recorded verbatim. */
|
/** One `todoSync` invocation, recorded verbatim. */
|
||||||
interface SyncCall {
|
interface SyncCall {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
import type { AssistantMessage } from "@oh-my-pi/pi-ai/types";
|
import type { AssistantMessage } from "@oh-my-pi/pi-ai/types";
|
||||||
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
|
||||||
import type { InteractionQuery, InteractionResponse } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
import type { InteractionQuery, InteractionResponse } from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import {
|
import {
|
||||||
type AgentClientMessage,
|
type AgentClientMessage,
|
||||||
AgentClientMessageSchema,
|
AgentClientMessageSchema,
|
||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
WebFetchRequestQuerySchema,
|
WebFetchRequestQuerySchema,
|
||||||
WebSearchArgsSchema,
|
WebSearchArgsSchema,
|
||||||
WebSearchRequestQuerySchema,
|
WebSearchRequestQuerySchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
|
|
||||||
function cursorAssistantMessage(): AssistantMessage {
|
function cursorAssistantMessage(): AssistantMessage {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regression for #4228: a Devin Connect frame header advertising an outsized
|
* Regression for #4228: a Devin Connect frame header advertising an outsized
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { gunzipSync } from "node:zlib";
|
import { gunzipSync } from "node:zlib";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
||||||
import type { AssistantMessage, Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { AssistantMessage, Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { GetChatMessageRequestSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/api_server_pb/api_server_pb";
|
import { GetChatMessageRequestSchema, GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
|
||||||
|
|
||||||
const devinModel: Model<"devin-agent"> = buildModel({
|
const devinModel: Model<"devin-agent"> = buildModel({
|
||||||
id: "devin-test",
|
id: "devin-test",
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import * as AIError from "@oh-my-pi/pi-ai/error";
|
import * as AIError from "@oh-my-pi/pi-ai/error";
|
||||||
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { GetChatMessageResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/api_server_pb/api_server_pb";
|
import { GetChatMessageResponseSchema, GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
|
||||||
|
|
||||||
const CONNECT_END_STREAM_FLAG = 0x02;
|
const CONNECT_END_STREAM_FLAG = 0x02;
|
||||||
const LARGE_TOOL_RESULT_BYTES = 160 * 1024;
|
const LARGE_TOOL_RESULT_BYTES = 160 * 1024;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
||||||
import type { Context, Model, ToolCall } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model, ToolCall } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { GetChatMessageResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/api_server_pb/api_server_pb";
|
|
||||||
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
|
||||||
import {
|
import {
|
||||||
ChatToolCallSchema,
|
ChatToolCallSchema,
|
||||||
|
GetChatMessageResponseSchema,
|
||||||
|
GetUserJwtResponseSchema,
|
||||||
StopReason,
|
StopReason,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
|
|
||||||
function frameConnectMessage(payload: Uint8Array): Uint8Array {
|
function frameConnectMessage(payload: Uint8Array): Uint8Array {
|
||||||
const out = new Uint8Array(5 + payload.length);
|
const out = new Uint8Array(5 + payload.length);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { describe, expect, it } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
import { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
|
||||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||||
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
||||||
import { GetChatMessageResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/api_server_pb/api_server_pb";
|
|
||||||
import { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
|
|
||||||
import {
|
import {
|
||||||
|
GetChatMessageResponseSchema,
|
||||||
|
GetUserJwtResponseSchema,
|
||||||
ModelUsageStatsSchema,
|
ModelUsageStatsSchema,
|
||||||
StopReason,
|
StopReason,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/devin-proto";
|
||||||
|
|
||||||
function frameConnectMessage(payload: Uint8Array): Uint8Array {
|
function frameConnectMessage(payload: Uint8Array): Uint8Array {
|
||||||
const out = new Uint8Array(5 + payload.length);
|
const out = new Uint8Array(5 + payload.length);
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
- Models now include an optional `tokenizer` family field across bundled, discovered, and custom models (supporting Claude, Qwen, DeepSeek, Kimi, and GLM families), with support for explicit overrides in model configuration.
|
- Models now include an optional `tokenizer` family field across bundled, discovered, and custom models (supporting Claude, Qwen, DeepSeek, Kimi, and GLM families), with support for explicit overrides in model configuration.
|
||||||
- Added long-context cost tiers (`cost.longContext`) to subscription Codex GPT-5.6 models (Sol, Terra, Luna) matching first-party API pricing above 272K input tokens.
|
- Added long-context cost tiers (`cost.longContext`) to subscription Codex GPT-5.6 models (Sol, Terra, Luna) matching first-party API pricing above 272K input tokens.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Bundled model metadata is prebuilt during generation, reducing catalog startup work.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed tool-call turn failures for `opencode-go/muse-spark-1.2` and related variants by ensuring API transport pins apply to live discovery and automatically inferring response routes for gateway-first OpenCode models ([#8957](https://github.com/can1357/oh-my-pi/issues/8957)).
|
- Fixed tool-call turn failures for `opencode-go/muse-spark-1.2` and related variants by ensuring API transport pins apply to live discovery and automatically inferring response routes for gateway-first OpenCode models ([#8957](https://github.com/can1357/oh-my-pi/issues/8957)).
|
||||||
|
|||||||
@@ -31,10 +31,9 @@
|
|||||||
"fix": "biome check --write --unsafe .",
|
"fix": "biome check --write --unsafe .",
|
||||||
"fmt": "biome format --write .",
|
"fmt": "biome format --write .",
|
||||||
"gen:models": "bun scripts/generate-models.ts",
|
"gen:models": "bun scripts/generate-models.ts",
|
||||||
"gen:cursor-proto": "protoc --plugin=protoc-gen-es=../../node_modules/.bin/protoc-gen-es --es_out=src/discovery/cursor-gen --es_opt=target=ts -I ../ai/src/providers/cursor/proto ../ai/src/providers/cursor/proto/agent.proto"
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bufbuild/protobuf": "catalog:",
|
|
||||||
"@oh-my-pi/omptype": "catalog:",
|
"@oh-my-pi/omptype": "catalog:",
|
||||||
"@oh-my-pi/pi-utils": "catalog:"
|
"@oh-my-pi/pi-utils": "catalog:"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import type { OAuthProvider } from "@oh-my-pi/pi-ai/oauth/types";
|
|||||||
import { getGitLabDuoModels } from "@oh-my-pi/pi-ai/providers/gitlab-duo";
|
import { getGitLabDuoModels } from "@oh-my-pi/pi-ai/providers/gitlab-duo";
|
||||||
import { getProviderDefinition } from "@oh-my-pi/pi-ai/registry";
|
import { getProviderDefinition } from "@oh-my-pi/pi-ai/registry";
|
||||||
import { $env } from "@oh-my-pi/pi-utils";
|
import { $env } from "@oh-my-pi/pi-utils";
|
||||||
|
import { buildModel } from "../src/build";
|
||||||
import { ANTIGRAVITY_PRIMARY_ENDPOINT, fetchAntigravityDiscoveryModels } from "../src/discovery/antigravity";
|
import { ANTIGRAVITY_PRIMARY_ENDPOINT, fetchAntigravityDiscoveryModels } from "../src/discovery/antigravity";
|
||||||
import { buildGitLabDuoWorkflowFallbackModel } from "../src/discovery/gitlab-duo-workflow";
|
import { buildGitLabDuoWorkflowFallbackModel } from "../src/discovery/gitlab-duo-workflow";
|
||||||
import { createModelManager } from "../src/model-manager";
|
import { createModelManager } from "../src/model-manager";
|
||||||
@@ -52,7 +53,7 @@ import {
|
|||||||
stripFireworksDeepSeekThinkingToggle,
|
stripFireworksDeepSeekThinkingToggle,
|
||||||
} from "../src/provider-models/openai-compat";
|
} from "../src/provider-models/openai-compat";
|
||||||
import { type OpenAICodexAccount, openaiCodexModelManagerOptions } from "../src/provider-models/special";
|
import { type OpenAICodexAccount, openaiCodexModelManagerOptions } from "../src/provider-models/special";
|
||||||
import type { Api, ModelSpec } from "../src/types";
|
import type { Api, Model, ModelSpec } from "../src/types";
|
||||||
import { cleanModelName } from "../src/utils";
|
import { cleanModelName } from "../src/utils";
|
||||||
import { collapseEffortVariantsAcrossProviders } from "../src/variant-collapse";
|
import { collapseEffortVariantsAcrossProviders } from "../src/variant-collapse";
|
||||||
import {
|
import {
|
||||||
@@ -156,7 +157,7 @@ async function fetchProviderModelsFromCatalog(
|
|||||||
return { models: [], succeeded: true };
|
return { models: [], succeeded: true };
|
||||||
}
|
}
|
||||||
console.log(`Fetched ${models.length} models from ${descriptor.catalogDiscovery.label} model manager`);
|
console.log(`Fetched ${models.length} models from ${descriptor.catalogDiscovery.label} model manager`);
|
||||||
// The manager returns built models; models.json stores specs (sparse compat).
|
// Keep discovery rows as specs until policies finish; the final bundle is fully materialized below.
|
||||||
return { models: models.map(model => toModelSpec(model)), succeeded: true };
|
return { models: models.map(model => toModelSpec(model)), succeeded: true };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to fetch ${descriptor.catalogDiscovery.label} models:`, error);
|
console.error(`Failed to fetch ${descriptor.catalogDiscovery.label} models:`, error);
|
||||||
@@ -657,8 +658,9 @@ async function generateModels() {
|
|||||||
// Previous-snapshot entries may carry an older ThinkingConfig vocabulary;
|
// Previous-snapshot entries may carry an older ThinkingConfig vocabulary;
|
||||||
// applyGeneratedModelPolicies re-bakes `thinking` for every model, so the
|
// applyGeneratedModelPolicies re-bakes `thinking` for every model, so the
|
||||||
// inbound shape is irrelevant beyond identity/pricing/compat fields.
|
// inbound shape is irrelevant beyond identity/pricing/compat fields.
|
||||||
for (const models of Object.values(prevModelsJson as unknown as Record<string, Record<string, ModelSpec>>)) {
|
for (const models of Object.values(prevModelsJson as unknown as Record<string, Record<string, Model<Api>>>)) {
|
||||||
for (const model of Object.values(models)) {
|
for (const bundledModel of Object.values(models)) {
|
||||||
|
const model = toModelSpec(bundledModel);
|
||||||
if (
|
if (
|
||||||
!fetchedKeys.has(`${model.provider}/${model.id}`) &&
|
!fetchedKeys.has(`${model.provider}/${model.id}`) &&
|
||||||
!DISCOVERY_ONLY_PROVIDERS.has(model.provider) &&
|
!DISCOVERY_ONLY_PROVIDERS.has(model.provider) &&
|
||||||
@@ -744,9 +746,12 @@ async function generateModels() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const MODELS: Record<string, Record<string, ModelSpec>> = sortObj(providers);
|
const modelSpecs: Record<string, Record<string, ModelSpec>> = sortObj(providers);
|
||||||
for (const key in MODELS) {
|
const MODELS: Record<string, Record<string, Model<Api>>> = {};
|
||||||
MODELS[key] = sortObj(MODELS[key]);
|
for (const [provider, models] of Object.entries(modelSpecs)) {
|
||||||
|
MODELS[provider] = Object.fromEntries(
|
||||||
|
Object.entries(sortObj(models)).map(([id, model]) => [id, buildModel(model)]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate JSON file
|
// Generate JSON file
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
import * as path from "node:path";
|
||||||
|
import { generateProtoTs, ProtoContext, parseProto } from "./proto-parser";
|
||||||
|
|
||||||
|
const PACKAGES_DIR = path.resolve(import.meta.dir, "../..");
|
||||||
|
const CURSOR_PROTO = path.join(PACKAGES_DIR, "ai/src/providers/cursor/proto/agent.proto");
|
||||||
|
const DEVIN_PROTO_DIR = path.join(PACKAGES_DIR, "ai/src/providers/devin/proto");
|
||||||
|
const DISCOVERY_DIR = path.resolve(import.meta.dir, "../src/discovery");
|
||||||
|
|
||||||
|
const CURSOR_CONSUMER_DIRS = [
|
||||||
|
path.join(PACKAGES_DIR, "ai/src"),
|
||||||
|
path.join(PACKAGES_DIR, "ai/test"),
|
||||||
|
path.join(PACKAGES_DIR, "catalog/src"),
|
||||||
|
path.join(PACKAGES_DIR, "catalog/test"),
|
||||||
|
path.join(PACKAGES_DIR, "coding-agent/test"),
|
||||||
|
];
|
||||||
|
|
||||||
|
const CURSOR_ENUMS = ["ForceBackgroundShellStatus", "ForceBackgroundSubagentStatus"];
|
||||||
|
const DEVIN_MESSAGES = [
|
||||||
|
"exa.chat_pb.ChatMessagePrompt",
|
||||||
|
"exa.codeium_common_pb.ChatToolCall",
|
||||||
|
"exa.chat_pb.ChatToolChoice",
|
||||||
|
"exa.chat_pb.ChatToolDefinition",
|
||||||
|
"exa.codeium_common_pb.ClientModelConfig",
|
||||||
|
"exa.codeium_common_pb.CompletionConfiguration",
|
||||||
|
"exa.api_server_pb.GetChatMessageRequest",
|
||||||
|
"exa.api_server_pb.GetChatMessageResponse",
|
||||||
|
"exa.api_server_pb.GetCliModelConfigsRequest",
|
||||||
|
"exa.api_server_pb.GetCliModelConfigsResponse",
|
||||||
|
"exa.auth_pb.GetUserJwtRequest",
|
||||||
|
"exa.auth_pb.GetUserJwtResponse",
|
||||||
|
"exa.codeium_common_pb.ImageData",
|
||||||
|
"exa.codeium_common_pb.Metadata",
|
||||||
|
"exa.codeium_common_pb.ModelUsageStats",
|
||||||
|
"exa.chat_pb.PromptCacheOptions",
|
||||||
|
"exa.codeium_common_pb.ModelInfo",
|
||||||
|
"exa.codeium_common_pb.ModelFeatures",
|
||||||
|
];
|
||||||
|
const DEVIN_ENUMS = [
|
||||||
|
"CacheControlType",
|
||||||
|
"ChatMessageRequestType",
|
||||||
|
"ChatMessageSource",
|
||||||
|
"ConversationalPlannerMode",
|
||||||
|
"StopReason",
|
||||||
|
];
|
||||||
|
|
||||||
|
async function collectCursorMessages(): Promise<string[]> {
|
||||||
|
const symbols = new Set<string>();
|
||||||
|
const importPattern = /import(?:\s+type)?\s*\{([^}]*)\}\s*from\s*["']([^"']+)["'];/g;
|
||||||
|
const sourceFiles = await collectTypeScriptFiles(CURSOR_CONSUMER_DIRS);
|
||||||
|
|
||||||
|
for (const sourceFile of sourceFiles) {
|
||||||
|
const source = await Bun.file(sourceFile).text();
|
||||||
|
for (const match of source.matchAll(importPattern)) {
|
||||||
|
const modulePath = match[2];
|
||||||
|
if (!modulePath.endsWith("cursor-proto")) continue;
|
||||||
|
for (const specifier of match[1].split(",")) {
|
||||||
|
const symbol = specifier
|
||||||
|
.trim()
|
||||||
|
.replace(/^type\s+/, "")
|
||||||
|
.replace(/\s+as\s+.+$/, "");
|
||||||
|
if (!symbol) continue;
|
||||||
|
symbols.add(symbol.endsWith("Schema") ? symbol.slice(0, -6) : symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const enumName of CURSOR_ENUMS) symbols.delete(enumName);
|
||||||
|
if (symbols.size === 0) throw new Error("No Cursor protocol consumers found");
|
||||||
|
return [...symbols].sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function collectTypeScriptFiles(directories: string[]): Promise<string[]> {
|
||||||
|
const files: string[] = [];
|
||||||
|
const glob = new Bun.Glob("**/*.ts");
|
||||||
|
for (const directory of directories) {
|
||||||
|
for await (const relativePath of glob.scan({ cwd: directory, onlyFiles: true })) {
|
||||||
|
files.push(path.join(directory, relativePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files.sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parseProtoDirectory(directory: string): Promise<ProtoContext> {
|
||||||
|
const context = new ProtoContext();
|
||||||
|
const paths: string[] = [];
|
||||||
|
const glob = new Bun.Glob("**/*.proto");
|
||||||
|
for await (const relativePath of glob.scan({ cwd: directory, onlyFiles: true })) paths.push(relativePath);
|
||||||
|
|
||||||
|
for (const relativePath of paths.sort()) {
|
||||||
|
const source = await Bun.file(path.join(directory, relativePath)).text();
|
||||||
|
context.addFile(parseProto(source, relativePath));
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateProtocols(): Promise<void> {
|
||||||
|
const cursorSource = await Bun.file(CURSOR_PROTO).text();
|
||||||
|
const cursorContext = new ProtoContext();
|
||||||
|
cursorContext.addFile(parseProto(cursorSource, "agent.proto"));
|
||||||
|
|
||||||
|
const cursor = generateProtoTs(cursorContext, {
|
||||||
|
includeMessages: await collectCursorMessages(),
|
||||||
|
includeEnums: CURSOR_ENUMS,
|
||||||
|
includeDependencies: true,
|
||||||
|
packagePrefix: "Cursor agent",
|
||||||
|
protobufImportPath: "./protobuf",
|
||||||
|
});
|
||||||
|
const devin = generateProtoTs(await parseProtoDirectory(DEVIN_PROTO_DIR), {
|
||||||
|
includeMessages: DEVIN_MESSAGES,
|
||||||
|
includeEnums: DEVIN_ENUMS,
|
||||||
|
includeDependencies: true,
|
||||||
|
packagePrefix: "Devin",
|
||||||
|
protobufImportPath: "./protobuf",
|
||||||
|
});
|
||||||
|
|
||||||
|
await Bun.write(path.join(DISCOVERY_DIR, "cursor-proto.ts"), `${cursor}\n`);
|
||||||
|
await Bun.write(path.join(DISCOVERY_DIR, "devin-proto.ts"), `${devin}\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
await generateProtocols();
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -59,6 +59,11 @@ function supportsOpenAIGAComputerUse(spec: ModelSpec<Api>, explicitSupport: bool
|
|||||||
return parsed !== null && semverGte(parsed.version, "5.4");
|
return parsed !== null && semverGte(parsed.version, "5.4");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build one model from an authored spec. Bundled models.json rows are fully
|
||||||
|
* materialized by the generator and consumed directly (see `models.ts`), so
|
||||||
|
* this only runs for discovered/custom/override specs.
|
||||||
|
*/
|
||||||
export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi> {
|
export function buildModel<TApi extends Api>(spec: ModelSpec<TApi>): Model<TApi> {
|
||||||
const compat = buildCompat(spec) as CompatOf<TApi>;
|
const compat = buildCompat(spec) as CompatOf<TApi>;
|
||||||
const supportsComputerUseConfig = explicitComputerUseConfig(spec);
|
const supportsComputerUseConfig = explicitComputerUseConfig(spec);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,12 @@
|
|||||||
import * as http2 from "node:http2";
|
import * as http2 from "node:http2";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "./protobuf";
|
||||||
import { type } from "@oh-my-pi/omptype";
|
import { type } from "@oh-my-pi/omptype";
|
||||||
import { isKimiK3ModelId } from "../identity";
|
import { isKimiK3ModelId } from "../identity";
|
||||||
import { bareModelId, parseGlmModel, semverGte } from "../identity/classify";
|
import { bareModelId, parseGlmModel, semverGte } from "../identity/classify";
|
||||||
import { getBundledModels } from "../models";
|
import { getBundledModels } from "../models";
|
||||||
import { toModelSpec } from "../provider-models/bundled-references";
|
import { toModelSpec } from "../provider-models/bundled-references";
|
||||||
import type { Model, ModelSpec } from "../types";
|
import type { Model, ModelSpec } from "../types";
|
||||||
import { GetUsableModelsRequestSchema, GetUsableModelsResponseSchema } from "./cursor-gen/agent_pb";
|
import { GetUsableModelsRequestSchema, GetUsableModelsResponseSchema } from "./cursor-proto";
|
||||||
|
|
||||||
const CURSOR_DEFAULT_BASE_URL = "https://api2.cursor.sh";
|
const CURSOR_DEFAULT_BASE_URL = "https://api2.cursor.sh";
|
||||||
const CURSOR_DEFAULT_CLIENT_VERSION = "cli-2026.02.13-41ac335";
|
const CURSOR_DEFAULT_CLIENT_VERSION = "cli-2026.02.13-41ac335";
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,71 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/auth_pb/auth.proto (package exa.auth_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { file_buf_validate_validate } from "../../buf/validate/validate_pb";
|
|
||||||
import type { Metadata } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import { file_exa_codeium_common_pb_codeium_common } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/auth_pb/auth.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_auth_pb_auth: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("ChZleGEvYXV0aF9wYi9hdXRoLnByb3RvEgtleGEuYXV0aF9wYiJGChFHZXRVc2VySnd0UmVxdWVzdBIxCghtZXRhZGF0YRgBIAEoCzIfLmV4YS5jb2RlaXVtX2NvbW1vbl9wYi5NZXRhZGF0YSJFChJHZXRVc2VySnd0UmVzcG9uc2USEAoIdXNlcl9qd3QYASABKAkSHQoVY3VzdG9tX2FwaV9zZXJ2ZXJfdXJsGAIgASgJMlwKC0F1dGhTZXJ2aWNlEk0KCkdldFVzZXJKd3QSHi5leGEuYXV0aF9wYi5HZXRVc2VySnd0UmVxdWVzdBofLmV4YS5hdXRoX3BiLkdldFVzZXJKd3RSZXNwb25zZWIGcHJvdG8z", [file_buf_validate_validate, file_exa_codeium_common_pb_codeium_common]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auth_pb.GetUserJwtRequest
|
|
||||||
*/
|
|
||||||
export type GetUserJwtRequest = Message<"exa.auth_pb.GetUserJwtRequest"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.Metadata metadata = 1;
|
|
||||||
*/
|
|
||||||
metadata?: Metadata | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auth_pb.GetUserJwtRequest.
|
|
||||||
* Use `create(GetUserJwtRequestSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const GetUserJwtRequestSchema: GenMessage<GetUserJwtRequest> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auth_pb_auth, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auth_pb.GetUserJwtResponse
|
|
||||||
*/
|
|
||||||
export type GetUserJwtResponse = Message<"exa.auth_pb.GetUserJwtResponse"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string user_jwt = 1;
|
|
||||||
*/
|
|
||||||
userJwt: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string custom_api_server_url = 2;
|
|
||||||
*/
|
|
||||||
customApiServerUrl: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auth_pb.GetUserJwtResponse.
|
|
||||||
* Use `create(GetUserJwtResponseSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const GetUserJwtResponseSchema: GenMessage<GetUserJwtResponse> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auth_pb_auth, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from service exa.auth_pb.AuthService
|
|
||||||
*/
|
|
||||||
export const AuthService: GenService<{
|
|
||||||
/**
|
|
||||||
* @generated from rpc exa.auth_pb.AuthService.GetUserJwt
|
|
||||||
*/
|
|
||||||
getUserJwt: {
|
|
||||||
methodKind: "unary";
|
|
||||||
input: typeof GetUserJwtRequestSchema;
|
|
||||||
output: typeof GetUserJwtResponseSchema;
|
|
||||||
},
|
|
||||||
}> = /*@__PURE__*/
|
|
||||||
serviceDesc(file_exa_auth_pb_auth, 0);
|
|
||||||
|
|
||||||
-348
@@ -1,348 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/auto_cascade_common_pb/auto_cascade_common.proto (package exa.auto_cascade_common_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { file_buf_validate_validate } from "../../buf/validate/validate_pb";
|
|
||||||
import type { CascadeRunStatus, CortexTrajectory } from "../cortex_pb/cortex_pb";
|
|
||||||
import { file_exa_cortex_pb_cortex } from "../cortex_pb/cortex_pb";
|
|
||||||
import type { Timestamp } from "@bufbuild/protobuf/wkt";
|
|
||||||
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/auto_cascade_common_pb/auto_cascade_common.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_auto_cascade_common_pb_auto_cascade_common: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("CjRleGEvYXV0b19jYXNjYWRlX2NvbW1vbl9wYi9hdXRvX2Nhc2NhZGVfY29tbW9uLnByb3RvEhpleGEuYXV0b19jYXNjYWRlX2NvbW1vbl9wYiJQCgtHaXRSZXBvSW5mbxIRCglyZXBvX25hbWUYASABKAkSDgoGYnJhbmNoGAIgASgJEg4KBmNvbW1pdBgDIAEoCRIOCgZwcl91cmwYBCABKAki7wIKC1Nlc3Npb25JbmZvEhIKCnNlc3Npb25faWQYASABKAkSEwoLZXhwbGFuYXRpb24YAiABKAkSDwoHc3NoX3VybBgDIAEoCRIvCgZzdGF0dXMYBCABKA4yHy5leGEuY29ydGV4X3BiLkNhc2NhZGVSdW5TdGF0dXMSDwoHc3VtbWFyeRgFIAEoCRIzCgp0cmFqZWN0b3J5GAYgASgLMh8uZXhhLmNvcnRleF9wYi5Db3J0ZXhUcmFqZWN0b3J5EhMKC3Nlc3Npb25fa2V5GAcgASgJEi4KCmNyZWF0ZWRfYXQYCCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjoKCWdpdF9yZXBvcxgJIAMoCzInLmV4YS5hdXRvX2Nhc2NhZGVfY29tbW9uX3BiLkdpdFJlcG9JbmZvEi4KCnVwZGF0ZWRfYXQYCiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIrIBCgxTZXNzaW9uSW5mb3MSSAoIc2Vzc2lvbnMYASADKAsyNi5leGEuYXV0b19jYXNjYWRlX2NvbW1vbl9wYi5TZXNzaW9uSW5mb3MuU2Vzc2lvbnNFbnRyeRpYCg1TZXNzaW9uc0VudHJ5EgsKA2tleRgBIAEoCRI2CgV2YWx1ZRgCIAEoCzInLmV4YS5hdXRvX2Nhc2NhZGVfY29tbW9uX3BiLlNlc3Npb25JbmZvOgI4ASKmAgoVR2l0aHViUHVsbFJlcXVlc3RJbmZvEgsKA3VybBgBIAEoCRINCgVvd25lchgCIAEoCRIMCgRyZXBvGAMgASgJEg0KBXRpdGxlGAQgASgJEg4KBm51bWJlchgFIAEoCRJCCgljaV9zdGF0dXMYBiABKA4yLy5leGEuYXV0b19jYXNjYWRlX2NvbW1vbl9wYi5HaXRodWJDSUNoZWNrU3RhdHVzElAKDWJyYW5jaF9zdGF0dXMYByABKA4yOS5leGEuYXV0b19jYXNjYWRlX2NvbW1vbl9wYi5HaXRodWJQdWxsUmVxdWVzdEJyYW5jaFN0YXR1cxIuCgp1cGRhdGVkX2F0GAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJMChZHaXRodWJJbnN0YWxsYXRpb25JbmZvEhcKD2luc3RhbGxhdGlvbl9pZBgBIAEoCRIZChFvcmdhbml6YXRpb25fbmFtZRgCIAEoCSq9AQoMQnJhbmNoU3RhdHVzEh0KGUJSQU5DSF9TVEFUVVNfVU5TUEVDSUZJRUQQABIXChNCUkFOQ0hfU1RBVFVTX05PX1BSEAESGQoVQlJBTkNIX1NUQVRVU19QUl9PUEVOEAISGwoXQlJBTkNIX1NUQVRVU19QUl9DTE9TRUQQAxIbChdCUkFOQ0hfU1RBVFVTX1BSX01FUkdFRBAEEiAKHEJSQU5DSF9TVEFUVVNfSEFTX1NVR0dFU1RJT04QBSqpAQoLQ29tbWVudFR5cGUSHAoYQ09NTUVOVF9UWVBFX1VOU1BFQ0lGSUVEEAASJgoiQ09NTUVOVF9UWVBFX01BTlVBTF9SRVZJRVdfVFJJR0dFUhABEhUKEUNPTU1FTlRfVFlQRV9MR1RNEAISHAoYQ09NTUVOVF9UWVBFX1JFVklFV19CT0RZEAMSHwobQ09NTUVOVF9UWVBFX1JFVklFV19DT01NRU5UEAQqqAEKE0dpdGh1YkNJQ2hlY2tTdGF0dXMSJgoiR0lUSFVCX0NJX0NIRUNLX1NUQVRVU19VTlNQRUNJRklFRBAAEiIKHkdJVEhVQl9DSV9DSEVDS19TVEFUVVNfU1VDQ0VTUxABEiEKHUdJVEhVQl9DSV9DSEVDS19TVEFUVVNfRkFJTEVEEAISIgoeR0lUSFVCX0NJX0NIRUNLX1NUQVRVU19QRU5ESU5HEAMqhwIKHUdpdGh1YlB1bGxSZXF1ZXN0QnJhbmNoU3RhdHVzEjEKLUdJVEhVQl9QVUxMX1JFUVVFU1RfQlJBTkNIX1NUQVRVU19VTlNQRUNJRklFRBAAEioKJkdJVEhVQl9QVUxMX1JFUVVFU1RfQlJBTkNIX1NUQVRVU19PUEVOEAESLAooR0lUSFVCX1BVTExfUkVRVUVTVF9CUkFOQ0hfU1RBVFVTX0NMT1NFRBACEisKJ0dJVEhVQl9QVUxMX1JFUVVFU1RfQlJBTkNIX1NUQVRVU19EUkFGVBADEiwKKEdJVEhVQl9QVUxMX1JFUVVFU1RfQlJBTkNIX1NUQVRVU19NRVJHRUQQBGIGcHJvdG8z", [file_buf_validate_validate, file_exa_cortex_pb_cortex, file_google_protobuf_timestamp]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auto_cascade_common_pb.GitRepoInfo
|
|
||||||
*/
|
|
||||||
export type GitRepoInfo = Message<"exa.auto_cascade_common_pb.GitRepoInfo"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string repo_name = 1;
|
|
||||||
*/
|
|
||||||
repoName: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string branch = 2;
|
|
||||||
*/
|
|
||||||
branch: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string commit = 3;
|
|
||||||
*/
|
|
||||||
commit: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string pr_url = 4;
|
|
||||||
*/
|
|
||||||
prUrl: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auto_cascade_common_pb.GitRepoInfo.
|
|
||||||
* Use `create(GitRepoInfoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const GitRepoInfoSchema: GenMessage<GitRepoInfo> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auto_cascade_common_pb.SessionInfo
|
|
||||||
*/
|
|
||||||
export type SessionInfo = Message<"exa.auto_cascade_common_pb.SessionInfo"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string session_id = 1;
|
|
||||||
*/
|
|
||||||
sessionId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string explanation = 2;
|
|
||||||
*/
|
|
||||||
explanation: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string ssh_url = 3;
|
|
||||||
*/
|
|
||||||
sshUrl: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.cortex_pb.CascadeRunStatus status = 4;
|
|
||||||
*/
|
|
||||||
status: CascadeRunStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string summary = 5;
|
|
||||||
*/
|
|
||||||
summary: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.cortex_pb.CortexTrajectory trajectory = 6;
|
|
||||||
*/
|
|
||||||
trajectory?: CortexTrajectory | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string session_key = 7;
|
|
||||||
*/
|
|
||||||
sessionKey: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: google.protobuf.Timestamp created_at = 8;
|
|
||||||
*/
|
|
||||||
createdAt?: Timestamp | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.auto_cascade_common_pb.GitRepoInfo git_repos = 9;
|
|
||||||
*/
|
|
||||||
gitRepos: GitRepoInfo[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: google.protobuf.Timestamp updated_at = 10;
|
|
||||||
*/
|
|
||||||
updatedAt?: Timestamp | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auto_cascade_common_pb.SessionInfo.
|
|
||||||
* Use `create(SessionInfoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SessionInfoSchema: GenMessage<SessionInfo> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auto_cascade_common_pb.SessionInfos
|
|
||||||
*/
|
|
||||||
export type SessionInfos = Message<"exa.auto_cascade_common_pb.SessionInfos"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: map<string, exa.auto_cascade_common_pb.SessionInfo> sessions = 1;
|
|
||||||
*/
|
|
||||||
sessions: { [key: string]: SessionInfo };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auto_cascade_common_pb.SessionInfos.
|
|
||||||
* Use `create(SessionInfosSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SessionInfosSchema: GenMessage<SessionInfos> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auto_cascade_common_pb.GithubPullRequestInfo
|
|
||||||
*/
|
|
||||||
export type GithubPullRequestInfo = Message<"exa.auto_cascade_common_pb.GithubPullRequestInfo"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string url = 1;
|
|
||||||
*/
|
|
||||||
url: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string owner = 2;
|
|
||||||
*/
|
|
||||||
owner: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string repo = 3;
|
|
||||||
*/
|
|
||||||
repo: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string title = 4;
|
|
||||||
*/
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string number = 5;
|
|
||||||
*/
|
|
||||||
number: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.auto_cascade_common_pb.GithubCICheckStatus ci_status = 6;
|
|
||||||
*/
|
|
||||||
ciStatus: GithubCICheckStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.auto_cascade_common_pb.GithubPullRequestBranchStatus branch_status = 7;
|
|
||||||
*/
|
|
||||||
branchStatus: GithubPullRequestBranchStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: google.protobuf.Timestamp updated_at = 8;
|
|
||||||
*/
|
|
||||||
updatedAt?: Timestamp | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auto_cascade_common_pb.GithubPullRequestInfo.
|
|
||||||
* Use `create(GithubPullRequestInfoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const GithubPullRequestInfoSchema: GenMessage<GithubPullRequestInfo> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.auto_cascade_common_pb.GithubInstallationInfo
|
|
||||||
*/
|
|
||||||
export type GithubInstallationInfo = Message<"exa.auto_cascade_common_pb.GithubInstallationInfo"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string installation_id = 1;
|
|
||||||
*/
|
|
||||||
installationId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string organization_name = 2;
|
|
||||||
*/
|
|
||||||
organizationName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.auto_cascade_common_pb.GithubInstallationInfo.
|
|
||||||
* Use `create(GithubInstallationInfoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const GithubInstallationInfoSchema: GenMessage<GithubInstallationInfo> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.auto_cascade_common_pb.BranchStatus
|
|
||||||
*/
|
|
||||||
export enum BranchStatus {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_NO_PR = 1;
|
|
||||||
*/
|
|
||||||
NO_PR = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_PR_OPEN = 2;
|
|
||||||
*/
|
|
||||||
PR_OPEN = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_PR_CLOSED = 3;
|
|
||||||
*/
|
|
||||||
PR_CLOSED = 3,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_PR_MERGED = 4;
|
|
||||||
*/
|
|
||||||
PR_MERGED = 4,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: BRANCH_STATUS_HAS_SUGGESTION = 5;
|
|
||||||
*/
|
|
||||||
HAS_SUGGESTION = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.auto_cascade_common_pb.BranchStatus.
|
|
||||||
*/
|
|
||||||
export const BranchStatusSchema: GenEnum<BranchStatus> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.auto_cascade_common_pb.CommentType
|
|
||||||
*/
|
|
||||||
export enum CommentType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: COMMENT_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: COMMENT_TYPE_MANUAL_REVIEW_TRIGGER = 1;
|
|
||||||
*/
|
|
||||||
MANUAL_REVIEW_TRIGGER = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: COMMENT_TYPE_LGTM = 2;
|
|
||||||
*/
|
|
||||||
LGTM = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: COMMENT_TYPE_REVIEW_BODY = 3;
|
|
||||||
*/
|
|
||||||
REVIEW_BODY = 3,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: COMMENT_TYPE_REVIEW_COMMENT = 4;
|
|
||||||
*/
|
|
||||||
REVIEW_COMMENT = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.auto_cascade_common_pb.CommentType.
|
|
||||||
*/
|
|
||||||
export const CommentTypeSchema: GenEnum<CommentType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.auto_cascade_common_pb.GithubCICheckStatus
|
|
||||||
*/
|
|
||||||
export enum GithubCICheckStatus {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_CI_CHECK_STATUS_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
GITHUB_CI_CHECK_STATUS_UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_CI_CHECK_STATUS_SUCCESS = 1;
|
|
||||||
*/
|
|
||||||
GITHUB_CI_CHECK_STATUS_SUCCESS = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_CI_CHECK_STATUS_FAILED = 2;
|
|
||||||
*/
|
|
||||||
GITHUB_CI_CHECK_STATUS_FAILED = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_CI_CHECK_STATUS_PENDING = 3;
|
|
||||||
*/
|
|
||||||
GITHUB_CI_CHECK_STATUS_PENDING = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.auto_cascade_common_pb.GithubCICheckStatus.
|
|
||||||
*/
|
|
||||||
export const GithubCICheckStatusSchema: GenEnum<GithubCICheckStatus> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.auto_cascade_common_pb.GithubPullRequestBranchStatus
|
|
||||||
*/
|
|
||||||
export enum GithubPullRequestBranchStatus {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_PULL_REQUEST_BRANCH_STATUS_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_PULL_REQUEST_BRANCH_STATUS_OPEN = 1;
|
|
||||||
*/
|
|
||||||
OPEN = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_PULL_REQUEST_BRANCH_STATUS_CLOSED = 2;
|
|
||||||
*/
|
|
||||||
CLOSED = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_PULL_REQUEST_BRANCH_STATUS_DRAFT = 3;
|
|
||||||
*/
|
|
||||||
DRAFT = 3,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: GITHUB_PULL_REQUEST_BRANCH_STATUS_MERGED = 4;
|
|
||||||
*/
|
|
||||||
MERGED = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.auto_cascade_common_pb.GithubPullRequestBranchStatus.
|
|
||||||
*/
|
|
||||||
export const GithubPullRequestBranchStatusSchema: GenEnum<GithubPullRequestBranchStatus> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_auto_cascade_common_pb_auto_cascade_common, 3);
|
|
||||||
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/bug_checker_pb/bug_checker.proto (package exa.bug_checker_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/bug_checker_pb/bug_checker.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_bug_checker_pb_bug_checker: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("CiRleGEvYnVnX2NoZWNrZXJfcGIvYnVnX2NoZWNrZXIucHJvdG8SEmV4YS5idWdfY2hlY2tlcl9wYiInCgNGaXgSDwoHb2xkX3N0chgBIAEoCRIPCgduZXdfc3RyGAIgASgJItMBCgNCdWcSCgoCaWQYASABKAkSDAoEZmlsZRgCIAEoCRINCgVzdGFydBgDIAEoBRILCgNlbmQYBCABKAUSDQoFdGl0bGUYBSABKAkSEwoLZGVzY3JpcHRpb24YBiABKAkSEAoIc2V2ZXJpdHkYByABKAkSEgoKcmVzb2x1dGlvbhgIIAEoCRISCgpjb25maWRlbmNlGAkgASgBEhIKCmNhdGVnb3JpZXMYCiADKAkSJAoDZml4GAsgASgLMhcuZXhhLmJ1Z19jaGVja2VyX3BiLkZpeGIGcHJvdG8z");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.bug_checker_pb.Fix
|
|
||||||
*/
|
|
||||||
export type Fix = Message<"exa.bug_checker_pb.Fix"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string old_str = 1;
|
|
||||||
*/
|
|
||||||
oldStr: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string new_str = 2;
|
|
||||||
*/
|
|
||||||
newStr: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.bug_checker_pb.Fix.
|
|
||||||
* Use `create(FixSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const FixSchema: GenMessage<Fix> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_bug_checker_pb_bug_checker, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.bug_checker_pb.Bug
|
|
||||||
*/
|
|
||||||
export type Bug = Message<"exa.bug_checker_pb.Bug"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string id = 1;
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string file = 2;
|
|
||||||
*/
|
|
||||||
file: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 start = 3;
|
|
||||||
*/
|
|
||||||
start: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 end = 4;
|
|
||||||
*/
|
|
||||||
end: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string title = 5;
|
|
||||||
*/
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string description = 6;
|
|
||||||
*/
|
|
||||||
description: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string severity = 7;
|
|
||||||
*/
|
|
||||||
severity: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string resolution = 8;
|
|
||||||
*/
|
|
||||||
resolution: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: double confidence = 9;
|
|
||||||
*/
|
|
||||||
confidence: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated string categories = 10;
|
|
||||||
*/
|
|
||||||
categories: string[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.bug_checker_pb.Fix fix = 11;
|
|
||||||
*/
|
|
||||||
fix?: Fix | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.bug_checker_pb.Bug.
|
|
||||||
* Use `create(BugSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const BugSchema: GenMessage<Bug> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_bug_checker_pb_bug_checker, 1);
|
|
||||||
|
|
||||||
-1198
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-18354
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,312 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/diff_action_pb/diff_action.proto (package exa.diff_action_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import type { Language } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import { file_exa_codeium_common_pb_codeium_common } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/diff_action_pb/diff_action.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_diff_action_pb_diff_action: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("CiRleGEvZGlmZl9hY3Rpb25fcGIvZGlmZl9hY3Rpb24ucHJvdG8SEmV4YS5kaWZmX2FjdGlvbl9wYiKlAQoLVW5pZmllZERpZmYSPgoFbGluZXMYAyADKAsyLy5leGEuZGlmZl9hY3Rpb25fcGIuVW5pZmllZERpZmYuVW5pZmllZERpZmZMaW5lGlYKD1VuaWZpZWREaWZmTGluZRIMCgR0ZXh0GAEgASgJEjUKBHR5cGUYAiABKA4yJy5leGEuZGlmZl9hY3Rpb25fcGIuVW5pZmllZERpZmZMaW5lVHlwZSLWAQoJRGlmZkJsb2NrEhIKCnN0YXJ0X2xpbmUYASABKAUSEAoIZW5kX2xpbmUYAiABKAUSNQoMdW5pZmllZF9kaWZmGAMgASgLMh8uZXhhLmRpZmZfYWN0aW9uX3BiLlVuaWZpZWREaWZmEjYKDWZyb21fbGFuZ3VhZ2UYBCABKA4yHy5leGEuY29kZWl1bV9jb21tb25fcGIuTGFuZ3VhZ2USNAoLdG9fbGFuZ3VhZ2UYBSABKA4yHy5leGEuY29kZWl1bV9jb21tb25fcGIuTGFuZ3VhZ2UiVQoTQ2hhcmFjdGVyRGlmZkNoYW5nZRIMCgR0ZXh0GAEgASgJEjAKBHR5cGUYAiABKA4yIi5leGEuZGlmZl9hY3Rpb25fcGIuRGlmZkNoYW5nZVR5cGUiSQoNQ2hhcmFjdGVyRGlmZhI4CgdjaGFuZ2VzGAEgAygLMicuZXhhLmRpZmZfYWN0aW9uX3BiLkNoYXJhY3RlckRpZmZDaGFuZ2UiigEKDUNvbWJvRGlmZkxpbmUSDAoEdGV4dBgBIAEoCRIwCgR0eXBlGAIgASgOMiIuZXhhLmRpZmZfYWN0aW9uX3BiLkRpZmZDaGFuZ2VUeXBlEjkKDmNoYXJhY3Rlcl9kaWZmGAMgASgLMiEuZXhhLmRpZmZfYWN0aW9uX3BiLkNoYXJhY3RlckRpZmYiPQoJQ29tYm9EaWZmEjAKBWxpbmVzGAEgAygLMiEuZXhhLmRpZmZfYWN0aW9uX3BiLkNvbWJvRGlmZkxpbmUirgEKB0RpZmZTZXQSNQoMdW5pZmllZF9kaWZmGAEgASgLMh8uZXhhLmRpZmZfYWN0aW9uX3BiLlVuaWZpZWREaWZmEjkKDmNoYXJhY3Rlcl9kaWZmGAIgASgLMiEuZXhhLmRpZmZfYWN0aW9uX3BiLkNoYXJhY3RlckRpZmYSMQoKY29tYm9fZGlmZhgDIAEoCzIdLmV4YS5kaWZmX2FjdGlvbl9wYi5Db21ib0RpZmYiOAoIRGlmZkxpc3QSLAoFZGlmZnMYAiADKAsyHS5leGEuZGlmZl9hY3Rpb25fcGIuRGlmZkJsb2NrKqkBChNVbmlmaWVkRGlmZkxpbmVUeXBlEiYKIlVOSUZJRURfRElGRl9MSU5FX1RZUEVfVU5TUEVDSUZJRUQQABIhCh1VTklGSUVEX0RJRkZfTElORV9UWVBFX0lOU0VSVBABEiEKHVVOSUZJRURfRElGRl9MSU5FX1RZUEVfREVMRVRFEAISJAogVU5JRklFRF9ESUZGX0xJTkVfVFlQRV9VTkNIQU5HRUQQAyqMAQoORGlmZkNoYW5nZVR5cGUSIAocRElGRl9DSEFOR0VfVFlQRV9VTlNQRUNJRklFRBAAEhsKF0RJRkZfQ0hBTkdFX1RZUEVfSU5TRVJUEAESGwoXRElGRl9DSEFOR0VfVFlQRV9ERUxFVEUQAhIeChpESUZGX0NIQU5HRV9UWVBFX1VOQ0hBTkdFRBADKnYKCERpZmZUeXBlEhkKFURJRkZfVFlQRV9VTlNQRUNJRklFRBAAEhUKEURJRkZfVFlQRV9VTklGSUVEEAESFwoTRElGRl9UWVBFX0NIQVJBQ1RFUhACEhMKD0RJRkZfVFlQRV9DT01CTxADIgQIBBAEIgQIBRAFYgZwcm90bzM", [file_exa_codeium_common_pb_codeium_common]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.UnifiedDiff
|
|
||||||
*/
|
|
||||||
export type UnifiedDiff = Message<"exa.diff_action_pb.UnifiedDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.diff_action_pb.UnifiedDiff.UnifiedDiffLine lines = 3;
|
|
||||||
*/
|
|
||||||
lines: UnifiedDiff_UnifiedDiffLine[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.UnifiedDiff.
|
|
||||||
* Use `create(UnifiedDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const UnifiedDiffSchema: GenMessage<UnifiedDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.UnifiedDiff.UnifiedDiffLine
|
|
||||||
*/
|
|
||||||
export type UnifiedDiff_UnifiedDiffLine = Message<"exa.diff_action_pb.UnifiedDiff.UnifiedDiffLine"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string text = 1;
|
|
||||||
*/
|
|
||||||
text: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.UnifiedDiffLineType type = 2;
|
|
||||||
*/
|
|
||||||
type: UnifiedDiffLineType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.UnifiedDiff.UnifiedDiffLine.
|
|
||||||
* Use `create(UnifiedDiff_UnifiedDiffLineSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const UnifiedDiff_UnifiedDiffLineSchema: GenMessage<UnifiedDiff_UnifiedDiffLine> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 0, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.DiffBlock
|
|
||||||
*/
|
|
||||||
export type DiffBlock = Message<"exa.diff_action_pb.DiffBlock"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 start_line = 1;
|
|
||||||
*/
|
|
||||||
startLine: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 end_line = 2;
|
|
||||||
*/
|
|
||||||
endLine: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.UnifiedDiff unified_diff = 3;
|
|
||||||
*/
|
|
||||||
unifiedDiff?: UnifiedDiff | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.Language from_language = 4;
|
|
||||||
*/
|
|
||||||
fromLanguage: Language;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.Language to_language = 5;
|
|
||||||
*/
|
|
||||||
toLanguage: Language;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.DiffBlock.
|
|
||||||
* Use `create(DiffBlockSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const DiffBlockSchema: GenMessage<DiffBlock> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.CharacterDiffChange
|
|
||||||
*/
|
|
||||||
export type CharacterDiffChange = Message<"exa.diff_action_pb.CharacterDiffChange"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string text = 1;
|
|
||||||
*/
|
|
||||||
text: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.DiffChangeType type = 2;
|
|
||||||
*/
|
|
||||||
type: DiffChangeType;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.CharacterDiffChange.
|
|
||||||
* Use `create(CharacterDiffChangeSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CharacterDiffChangeSchema: GenMessage<CharacterDiffChange> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.CharacterDiff
|
|
||||||
*/
|
|
||||||
export type CharacterDiff = Message<"exa.diff_action_pb.CharacterDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.diff_action_pb.CharacterDiffChange changes = 1;
|
|
||||||
*/
|
|
||||||
changes: CharacterDiffChange[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.CharacterDiff.
|
|
||||||
* Use `create(CharacterDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CharacterDiffSchema: GenMessage<CharacterDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.ComboDiffLine
|
|
||||||
*/
|
|
||||||
export type ComboDiffLine = Message<"exa.diff_action_pb.ComboDiffLine"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string text = 1;
|
|
||||||
*/
|
|
||||||
text: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.DiffChangeType type = 2;
|
|
||||||
*/
|
|
||||||
type: DiffChangeType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.CharacterDiff character_diff = 3;
|
|
||||||
*/
|
|
||||||
characterDiff?: CharacterDiff | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.ComboDiffLine.
|
|
||||||
* Use `create(ComboDiffLineSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const ComboDiffLineSchema: GenMessage<ComboDiffLine> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.ComboDiff
|
|
||||||
*/
|
|
||||||
export type ComboDiff = Message<"exa.diff_action_pb.ComboDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.diff_action_pb.ComboDiffLine lines = 1;
|
|
||||||
*/
|
|
||||||
lines: ComboDiffLine[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.ComboDiff.
|
|
||||||
* Use `create(ComboDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const ComboDiffSchema: GenMessage<ComboDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 5);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.DiffSet
|
|
||||||
*/
|
|
||||||
export type DiffSet = Message<"exa.diff_action_pb.DiffSet"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.UnifiedDiff unified_diff = 1;
|
|
||||||
*/
|
|
||||||
unifiedDiff?: UnifiedDiff | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.CharacterDiff character_diff = 2;
|
|
||||||
*/
|
|
||||||
characterDiff?: CharacterDiff | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.diff_action_pb.ComboDiff combo_diff = 3;
|
|
||||||
*/
|
|
||||||
comboDiff?: ComboDiff | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.DiffSet.
|
|
||||||
* Use `create(DiffSetSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const DiffSetSchema: GenMessage<DiffSet> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 6);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.diff_action_pb.DiffList
|
|
||||||
*/
|
|
||||||
export type DiffList = Message<"exa.diff_action_pb.DiffList"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.diff_action_pb.DiffBlock diffs = 2;
|
|
||||||
*/
|
|
||||||
diffs: DiffBlock[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.diff_action_pb.DiffList.
|
|
||||||
* Use `create(DiffListSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const DiffListSchema: GenMessage<DiffList> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_diff_action_pb_diff_action, 7);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.diff_action_pb.UnifiedDiffLineType
|
|
||||||
*/
|
|
||||||
export enum UnifiedDiffLineType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: UNIFIED_DIFF_LINE_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: UNIFIED_DIFF_LINE_TYPE_INSERT = 1;
|
|
||||||
*/
|
|
||||||
INSERT = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: UNIFIED_DIFF_LINE_TYPE_DELETE = 2;
|
|
||||||
*/
|
|
||||||
DELETE = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: UNIFIED_DIFF_LINE_TYPE_UNCHANGED = 3;
|
|
||||||
*/
|
|
||||||
UNCHANGED = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.diff_action_pb.UnifiedDiffLineType.
|
|
||||||
*/
|
|
||||||
export const UnifiedDiffLineTypeSchema: GenEnum<UnifiedDiffLineType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_diff_action_pb_diff_action, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.diff_action_pb.DiffChangeType
|
|
||||||
*/
|
|
||||||
export enum DiffChangeType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_CHANGE_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_CHANGE_TYPE_INSERT = 1;
|
|
||||||
*/
|
|
||||||
INSERT = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_CHANGE_TYPE_DELETE = 2;
|
|
||||||
*/
|
|
||||||
DELETE = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_CHANGE_TYPE_UNCHANGED = 3;
|
|
||||||
*/
|
|
||||||
UNCHANGED = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.diff_action_pb.DiffChangeType.
|
|
||||||
*/
|
|
||||||
export const DiffChangeTypeSchema: GenEnum<DiffChangeType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_diff_action_pb_diff_action, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.diff_action_pb.DiffType
|
|
||||||
*/
|
|
||||||
export enum DiffType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_TYPE_UNIFIED = 1;
|
|
||||||
*/
|
|
||||||
UNIFIED = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_TYPE_CHARACTER = 2;
|
|
||||||
*/
|
|
||||||
CHARACTER = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: DIFF_TYPE_COMBO = 3;
|
|
||||||
*/
|
|
||||||
COMBO = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.diff_action_pb.DiffType.
|
|
||||||
*/
|
|
||||||
export const DiffTypeSchema: GenEnum<DiffType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_diff_action_pb_diff_action, 2);
|
|
||||||
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-10918
File diff suppressed because one or more lines are too long
-2125
File diff suppressed because one or more lines are too long
@@ -1,361 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/prompt_pb/prompt.proto (package exa.prompt_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import type { ChatMessage, DeepWikiContext, DeepWikiSymbolContext } from "../chat_pb/chat_pb";
|
|
||||||
import { file_exa_chat_pb_chat } from "../chat_pb/chat_pb";
|
|
||||||
import type { CodeDiagnostic, CommandRequestSource, Document, IntellisenseSuggestion, TerminalCommandData, TerminalShellCommand } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import { file_exa_codeium_common_pb_codeium_common } from "../codeium_common_pb/codeium_common_pb";
|
|
||||||
import type { ContextModuleResult } from "../context_module_pb/context_module_pb";
|
|
||||||
import { file_exa_context_module_pb_context_module } from "../context_module_pb/context_module_pb";
|
|
||||||
import type { CortexStepType, CortexTrajectory } from "../cortex_pb/cortex_pb";
|
|
||||||
import { file_exa_cortex_pb_cortex } from "../cortex_pb/cortex_pb";
|
|
||||||
import type { HandleStreamingTabV2Response_Diff, HandleStreamingTabV2Response_TabJump } from "../language_server_pb/language_server_pb";
|
|
||||||
import { file_exa_language_server_pb_language_server } from "../language_server_pb/language_server_pb";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/prompt_pb/prompt.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_prompt_pb_prompt: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("ChpleGEvcHJvbXB0X3BiL3Byb21wdC5wcm90bxINZXhhLnByb21wdF9wYiI5Cg5QZW5kaW5nQ29tbWFuZBITCgtpbnN0cnVjdGlvbhgBIAEoCRISCgpjb21wbGV0aW9uGAIgASgJIs4EChFDb21tYW5kSW50ZW50SW5mbxIRCglzZWxlY3Rpb24YASABKAkSEwoLaW5zdHJ1Y3Rpb24YAiABKAkSNwoOaW5wdXRfZG9jdW1lbnQYAyABKAsyHy5leGEuY29kZWl1bV9jb21tb25fcGIuRG9jdW1lbnQSHAoUc2VsZWN0aW9uX3N0YXJ0X2xpbmUYBCABKAQSGgoSc2VsZWN0aW9uX2VuZF9saW5lGAUgASgEEkkKFXRlcm1pbmFsX2NvbW1hbmRfZGF0YRgGIAEoCzIqLmV4YS5jb2RlaXVtX2NvbW1vbl9wYi5UZXJtaW5hbENvbW1hbmREYXRhEkYKEXByZXZpb3VzX2NvbW1hbmRzGAcgAygLMisuZXhhLmNvZGVpdW1fY29tbW9uX3BiLlRlcm1pbmFsU2hlbGxDb21tYW5kEjcKEHBlbmRpbmdfY29tbWFuZHMYCCADKAsyHS5leGEucHJvbXB0X3BiLlBlbmRpbmdDb21tYW5kEkMKDnJlcXVlc3Rfc291cmNlGAkgASgOMisuZXhhLmNvZGVpdW1fY29tbW9uX3BiLkNvbW1hbmRSZXF1ZXN0U291cmNlEkoKE2ludGVsbGlzZW5zZV9wcm9tcHQYCiADKAsyLS5leGEuY29kZWl1bV9jb21tb25fcGIuSW50ZWxsaXNlbnNlU3VnZ2VzdGlvbhJBChJkaWFnbm9zdGljc19wcm9tcHQYCyADKAsyJS5leGEuY29kZWl1bV9jb21tb25fcGIuQ29kZURpYWdub3N0aWMioAIKFVN1cGVyY29tcGxldGVGZWVkYmFjaxIQCghhY2NlcHRlZBgBIAEoCBIaChJpbnRlbnRpb25hbF9yZWplY3QYAiABKAgSFQoNY29tcGxldGlvbl9pZBgDIAEoCRIUCgx0aW1lc3RhbXBfbXMYBCABKAMSUgoPZGlmZl9zdWdnZXN0aW9uGAUgASgLMjkuZXhhLmxhbmd1YWdlX3NlcnZlcl9wYi5IYW5kbGVTdHJlYW1pbmdUYWJWMlJlc3BvbnNlLkRpZmYSWAoSdGFianVtcF9zdWdnZXN0aW9uGAYgASgLMjwuZXhhLmxhbmd1YWdlX3NlcnZlcl9wYi5IYW5kbGVTdHJlYW1pbmdUYWJWMlJlc3BvbnNlLlRhYkp1bXAiVgocU3VwZXJjb21wbGV0ZUZlZWRiYWNrQ29udGV4dBI2CghmZWVkYmFjaxgBIAMoCzIkLmV4YS5wcm9tcHRfcGIuU3VwZXJjb21wbGV0ZUZlZWRiYWNrIrUFChdVbmlmaWVkUHJvbXB0Q29tcG9uZW50cxJJChVjb250ZXh0X21vZHVsZV9yZXN1bHQYAiABKAsyKi5leGEuY29udGV4dF9tb2R1bGVfcGIuQ29udGV4dE1vZHVsZVJlc3VsdBI6ChFjb3J0ZXhfdHJhamVjdG9yeRgDIAEoCzIfLmV4YS5jb3J0ZXhfcGIuQ29ydGV4VHJhamVjdG9yeRI9ChNjb21tYW5kX2ludGVudF9pbmZvGAQgASgLMiAuZXhhLnByb21wdF9wYi5Db21tYW5kSW50ZW50SW5mbxIvCg1jaGF0X21lc3NhZ2VzGAEgAygLMhguZXhhLmNoYXRfcGIuQ2hhdE1lc3NhZ2USPwoQY29kZV9kaWFnbm9zdGljcxgFIAMoCzIlLmV4YS5jb2RlaXVtX2NvbW1vbl9wYi5Db2RlRGlhZ25vc3RpYxI4Cg9vdGhlcl9kb2N1bWVudHMYCSADKAsyHy5leGEuY29kZWl1bV9jb21tb25fcGIuRG9jdW1lbnQSQQoRZGVlcF93aWtpX2NvbnRleHQYCiABKAsyIi5leGEuY2hhdF9wYi5EZWVwV2lraVN5bWJvbENvbnRleHRCAhgBEjoKFGRlZXBfd2lraV9jb250ZXh0X3YyGAsgASgLMhwuZXhhLmNoYXRfcGIuRGVlcFdpa2lDb250ZXh0ElMKHnN1cGVyY29tcGxldGVfZmVlZGJhY2tfY29udGV4dBgMIAEoCzIrLmV4YS5wcm9tcHRfcGIuU3VwZXJjb21wbGV0ZUZlZWRiYWNrQ29udGV4dEoECAYQB0oECAcQCEoECAgQCVIVa25vd2xlZGdlX2Jhc2VfcmVzdWx0UhRrbm93bGVkZ2VfYmFzZV9pdGVtc1IVa25vd2xlZGdlX2Jhc2VfZ3JvdXBzIjsKHlN5c3RlbVByb21wdENvbnN0cnVjdGlvbkNvbmZpZxIZChFlbGVtZW50X3NlcGFyYXRvchgBIAEoCSJUChhDb21tYW5kUHJvbXB0Q2FjaGVDb25maWcSGQoRbWF4X3RyYWNrZWRfZmlsZXMYASABKAMSHQoVbWF4X2NhY2hlX2FnZV9zZWNvbmRzGAIgASgDItYHChZDdW11bGF0aXZlUHJvbXB0Q29uZmlnEiUKHXBlcnNpc3RlbnRfY29udGV4dF9tdWx0aXBsaWVyGAcgASgCEi0KJXBlcnNpc3RlbnRfYWN0aXZlX2RvY3VtZW50X211bHRpcGxpZXIYCiABKAISJwofcGVyc2lzdGVudF9vcGVuX2RvY3NfbXVsdGlwbGllchgLIAEoAhIqCiJwZXJzaXN0ZW50X21heF90b2tlbnNfcGVyX29wZW5fZG9jGBEgASgDEiYKHnBlcnNpc3RlbnRfbWF4X2NjaXNfY29uc2lkZXJlZBgMIAEoAxInCh9wZXJzaXN0ZW50X2RvY3VtZW50X3N1ZmZpeF9mcmFjGBQgASgCEiUKHXRyYWplY3RvcnlfY29udGV4dF9tdWx0aXBsaWVyGAIgASgCEi8KJ3RyYWplY3RvcnlfcmVmcmVzaF90aHJlc2hvbGRfbXVsdGlwbGllchgPIAEoAhIoCiB0cmFqZWN0b3J5X3RydW5jYXRpb25fbXVsdGlwbGllchgQIAEoAhIkChxlcGhlbWVyYWxfY29udGV4dF9tdWx0aXBsaWVyGAkgASgCEiEKGWludGVudF9yZXNlcnZhdGlvbl90b2tlbnMYBiABKAMSLAokZXBoZW1lcmFsX2FjdGl2ZV9kb2N1bWVudF9tdWx0aXBsaWVyGA0gASgCEiUKHWVwaGVtZXJhbF9tYXhfY2Npc19jb25zaWRlcmVkGA4gASgDEiYKHmVwaGVtZXJhbF9kb2N1bWVudF9zdWZmaXhfZnJhYxgVIAEoAhJBChphbGxvd2VkX2Nhc2NhZGVfc3RlcF90eXBlcxgSIAMoDjIdLmV4YS5jb3J0ZXhfcGIuQ29ydGV4U3RlcFR5cGUSaAobYWxsb3dlZF9pbXBsaWNpdF9zdGVwX3R5cGVzGBYgAygLMkMuZXhhLnByb21wdF9wYi5DdW11bGF0aXZlUHJvbXB0Q29uZmlnLkFsbG93ZWRJbXBsaWNpdFN0ZXBUeXBlc0VudHJ5Gj8KHUFsbG93ZWRJbXBsaWNpdFN0ZXBUeXBlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCDoCOAFKBAgBEAJKBAgDEARKBAgEEAVKBAgFEAZSImFjdGl2ZV9kb2N1bWVudF9jb250ZXh0X211bHRpcGxpZXJSH2NvbnRleHRfaXRlbV9jb250ZXh0X211bHRpcGxpZXJSGGNhY2hlX2NvbnRleHRfbXVsdGlwbGllclITbWF4X2NjaXNfY29uc2lkZXJlZGIGcHJvdG8z", [file_exa_chat_pb_chat, file_exa_codeium_common_pb_codeium_common, file_exa_context_module_pb_context_module, file_exa_cortex_pb_cortex, file_exa_language_server_pb_language_server]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.PendingCommand
|
|
||||||
*/
|
|
||||||
export type PendingCommand = Message<"exa.prompt_pb.PendingCommand"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string instruction = 1;
|
|
||||||
*/
|
|
||||||
instruction: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string completion = 2;
|
|
||||||
*/
|
|
||||||
completion: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.PendingCommand.
|
|
||||||
* Use `create(PendingCommandSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const PendingCommandSchema: GenMessage<PendingCommand> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.CommandIntentInfo
|
|
||||||
*/
|
|
||||||
export type CommandIntentInfo = Message<"exa.prompt_pb.CommandIntentInfo"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string selection = 1;
|
|
||||||
*/
|
|
||||||
selection: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string instruction = 2;
|
|
||||||
*/
|
|
||||||
instruction: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.Document input_document = 3;
|
|
||||||
*/
|
|
||||||
inputDocument?: Document | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: uint64 selection_start_line = 4;
|
|
||||||
*/
|
|
||||||
selectionStartLine: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: uint64 selection_end_line = 5;
|
|
||||||
*/
|
|
||||||
selectionEndLine: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.TerminalCommandData terminal_command_data = 6;
|
|
||||||
*/
|
|
||||||
terminalCommandData?: TerminalCommandData | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.codeium_common_pb.TerminalShellCommand previous_commands = 7;
|
|
||||||
*/
|
|
||||||
previousCommands: TerminalShellCommand[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.prompt_pb.PendingCommand pending_commands = 8;
|
|
||||||
*/
|
|
||||||
pendingCommands: PendingCommand[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.codeium_common_pb.CommandRequestSource request_source = 9;
|
|
||||||
*/
|
|
||||||
requestSource: CommandRequestSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.codeium_common_pb.IntellisenseSuggestion intellisense_prompt = 10;
|
|
||||||
*/
|
|
||||||
intellisensePrompt: IntellisenseSuggestion[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.codeium_common_pb.CodeDiagnostic diagnostics_prompt = 11;
|
|
||||||
*/
|
|
||||||
diagnosticsPrompt: CodeDiagnostic[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.CommandIntentInfo.
|
|
||||||
* Use `create(CommandIntentInfoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CommandIntentInfoSchema: GenMessage<CommandIntentInfo> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.SupercompleteFeedback
|
|
||||||
*/
|
|
||||||
export type SupercompleteFeedback = Message<"exa.prompt_pb.SupercompleteFeedback"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: bool accepted = 1;
|
|
||||||
*/
|
|
||||||
accepted: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool intentional_reject = 2;
|
|
||||||
*/
|
|
||||||
intentionalReject: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string completion_id = 3;
|
|
||||||
*/
|
|
||||||
completionId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 timestamp_ms = 4;
|
|
||||||
*/
|
|
||||||
timestampMs: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.language_server_pb.HandleStreamingTabV2Response.Diff diff_suggestion = 5;
|
|
||||||
*/
|
|
||||||
diffSuggestion?: HandleStreamingTabV2Response_Diff | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.language_server_pb.HandleStreamingTabV2Response.TabJump tabjump_suggestion = 6;
|
|
||||||
*/
|
|
||||||
tabjumpSuggestion?: HandleStreamingTabV2Response_TabJump | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.SupercompleteFeedback.
|
|
||||||
* Use `create(SupercompleteFeedbackSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SupercompleteFeedbackSchema: GenMessage<SupercompleteFeedback> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.SupercompleteFeedbackContext
|
|
||||||
*/
|
|
||||||
export type SupercompleteFeedbackContext = Message<"exa.prompt_pb.SupercompleteFeedbackContext"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.prompt_pb.SupercompleteFeedback feedback = 1;
|
|
||||||
*/
|
|
||||||
feedback: SupercompleteFeedback[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.SupercompleteFeedbackContext.
|
|
||||||
* Use `create(SupercompleteFeedbackContextSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SupercompleteFeedbackContextSchema: GenMessage<SupercompleteFeedbackContext> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.UnifiedPromptComponents
|
|
||||||
*/
|
|
||||||
export type UnifiedPromptComponents = Message<"exa.prompt_pb.UnifiedPromptComponents"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.context_module_pb.ContextModuleResult context_module_result = 2;
|
|
||||||
*/
|
|
||||||
contextModuleResult?: ContextModuleResult | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.cortex_pb.CortexTrajectory cortex_trajectory = 3;
|
|
||||||
*/
|
|
||||||
cortexTrajectory?: CortexTrajectory | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.prompt_pb.CommandIntentInfo command_intent_info = 4;
|
|
||||||
*/
|
|
||||||
commandIntentInfo?: CommandIntentInfo | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.chat_pb.ChatMessage chat_messages = 1;
|
|
||||||
*/
|
|
||||||
chatMessages: ChatMessage[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.codeium_common_pb.CodeDiagnostic code_diagnostics = 5;
|
|
||||||
*/
|
|
||||||
codeDiagnostics: CodeDiagnostic[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.codeium_common_pb.Document other_documents = 9;
|
|
||||||
*/
|
|
||||||
otherDocuments: Document[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.chat_pb.DeepWikiSymbolContext deep_wiki_context = 10 [deprecated = true];
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
deepWikiContext?: DeepWikiSymbolContext | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.chat_pb.DeepWikiContext deep_wiki_context_v2 = 11;
|
|
||||||
*/
|
|
||||||
deepWikiContextV2?: DeepWikiContext | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.prompt_pb.SupercompleteFeedbackContext supercomplete_feedback_context = 12;
|
|
||||||
*/
|
|
||||||
supercompleteFeedbackContext?: SupercompleteFeedbackContext | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.UnifiedPromptComponents.
|
|
||||||
* Use `create(UnifiedPromptComponentsSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const UnifiedPromptComponentsSchema: GenMessage<UnifiedPromptComponents> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.SystemPromptConstructionConfig
|
|
||||||
*/
|
|
||||||
export type SystemPromptConstructionConfig = Message<"exa.prompt_pb.SystemPromptConstructionConfig"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string element_separator = 1;
|
|
||||||
*/
|
|
||||||
elementSeparator: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.SystemPromptConstructionConfig.
|
|
||||||
* Use `create(SystemPromptConstructionConfigSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SystemPromptConstructionConfigSchema: GenMessage<SystemPromptConstructionConfig> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 5);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.CommandPromptCacheConfig
|
|
||||||
*/
|
|
||||||
export type CommandPromptCacheConfig = Message<"exa.prompt_pb.CommandPromptCacheConfig"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 max_tracked_files = 1;
|
|
||||||
*/
|
|
||||||
maxTrackedFiles: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 max_cache_age_seconds = 2;
|
|
||||||
*/
|
|
||||||
maxCacheAgeSeconds: bigint;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.CommandPromptCacheConfig.
|
|
||||||
* Use `create(CommandPromptCacheConfigSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CommandPromptCacheConfigSchema: GenMessage<CommandPromptCacheConfig> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 6);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.prompt_pb.CumulativePromptConfig
|
|
||||||
*/
|
|
||||||
export type CumulativePromptConfig = Message<"exa.prompt_pb.CumulativePromptConfig"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: float persistent_context_multiplier = 7;
|
|
||||||
*/
|
|
||||||
persistentContextMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float persistent_active_document_multiplier = 10;
|
|
||||||
*/
|
|
||||||
persistentActiveDocumentMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float persistent_open_docs_multiplier = 11;
|
|
||||||
*/
|
|
||||||
persistentOpenDocsMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 persistent_max_tokens_per_open_doc = 17;
|
|
||||||
*/
|
|
||||||
persistentMaxTokensPerOpenDoc: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 persistent_max_ccis_considered = 12;
|
|
||||||
*/
|
|
||||||
persistentMaxCcisConsidered: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float persistent_document_suffix_frac = 20;
|
|
||||||
*/
|
|
||||||
persistentDocumentSuffixFrac: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float trajectory_context_multiplier = 2;
|
|
||||||
*/
|
|
||||||
trajectoryContextMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float trajectory_refresh_threshold_multiplier = 15;
|
|
||||||
*/
|
|
||||||
trajectoryRefreshThresholdMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float trajectory_truncation_multiplier = 16;
|
|
||||||
*/
|
|
||||||
trajectoryTruncationMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float ephemeral_context_multiplier = 9;
|
|
||||||
*/
|
|
||||||
ephemeralContextMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 intent_reservation_tokens = 6;
|
|
||||||
*/
|
|
||||||
intentReservationTokens: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float ephemeral_active_document_multiplier = 13;
|
|
||||||
*/
|
|
||||||
ephemeralActiveDocumentMultiplier: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 ephemeral_max_ccis_considered = 14;
|
|
||||||
*/
|
|
||||||
ephemeralMaxCcisConsidered: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: float ephemeral_document_suffix_frac = 21;
|
|
||||||
*/
|
|
||||||
ephemeralDocumentSuffixFrac: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.cortex_pb.CortexStepType allowed_cascade_step_types = 18;
|
|
||||||
*/
|
|
||||||
allowedCascadeStepTypes: CortexStepType[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: map<string, bool> allowed_implicit_step_types = 22;
|
|
||||||
*/
|
|
||||||
allowedImplicitStepTypes: { [key: string]: boolean };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.prompt_pb.CumulativePromptConfig.
|
|
||||||
* Use `create(CumulativePromptConfigSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CumulativePromptConfigSchema: GenMessage<CumulativePromptConfig> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_prompt_pb_prompt, 7);
|
|
||||||
|
|
||||||
-450
@@ -1,450 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/reactive_component_pb/reactive_component.proto (package exa.reactive_component_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/reactive_component_pb/reactive_component.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_reactive_component_pb_reactive_component: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("CjJleGEvcmVhY3RpdmVfY29tcG9uZW50X3BiL3JlYWN0aXZlX2NvbXBvbmVudC5wcm90bxIZZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYiJEChxTdHJlYW1SZWFjdGl2ZVVwZGF0ZXNSZXF1ZXN0EhgKEHByb3RvY29sX3ZlcnNpb24YASABKA0SCgoCaWQYAiABKAkiegodU3RyZWFtUmVhY3RpdmVVcGRhdGVzUmVzcG9uc2USDwoHdmVyc2lvbhgBIAEoBBI0CgRkaWZmGAIgASgLMiYuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5NZXNzYWdlRGlmZhISCgpmdWxsX3N0YXRlGAMgASgMIqEBCglUZXN0UHJvdG8SDwoHY291bnRlchgBIAEoBRIOCgZ2YWx1ZXMYAiADKAUSNAoGbmVzdGVkGAMgASgLMiQuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5UZXN0UHJvdG8SPQoPbmVzdGVkX3JlcGVhdGVkGAQgAygLMiQuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5UZXN0UHJvdG8iSAoLTWVzc2FnZURpZmYSOQoLZmllbGRfZGlmZnMYASADKAsyJC5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLkZpZWxkRGlmZiL9AQoJRmllbGREaWZmEhQKDGZpZWxkX251bWJlchgBIAEoDRJDCg91cGRhdGVfc2luZ3VsYXIYAiABKAsyKC5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLlNpbmd1bGFyVmFsdWVIABJCCg91cGRhdGVfcmVwZWF0ZWQYAyABKAsyJy5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLlJlcGVhdGVkRGlmZkgAEjgKCnVwZGF0ZV9tYXAYBCABKAsyIi5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLk1hcERpZmZIABIPCgVjbGVhchgFIAEoCEgAQgYKBGRpZmYiewoMUmVwZWF0ZWREaWZmEhIKCm5ld19sZW5ndGgYASABKA0SPwoNdXBkYXRlX3ZhbHVlcxgCIAMoCzIoLmV4YS5yZWFjdGl2ZV9jb21wb25lbnRfcGIuU2luZ3VsYXJWYWx1ZRIWCg51cGRhdGVfaW5kaWNlcxgDIAMoDSJHCgdNYXBEaWZmEjwKDW1hcF9rZXlfZGlmZnMYASADKAsyJS5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLk1hcEtleURpZmYipQEKCk1hcEtleURpZmYSOQoHbWFwX2tleRgBIAEoCzIoLmV4YS5yZWFjdGl2ZV9jb21wb25lbnRfcGIuU2luZ3VsYXJWYWx1ZRJDCg91cGRhdGVfc2luZ3VsYXIYAiABKAsyKC5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLlNpbmd1bGFyVmFsdWVIABIPCgVjbGVhchgDIAEoCEgAQgYKBGRpZmYi1wMKDVNpbmd1bGFyVmFsdWUSFgoMZG91YmxlX3ZhbHVlGAEgASgBSAASFQoLZmxvYXRfdmFsdWUYAiABKAJIABIVCgtpbnQzMl92YWx1ZRgDIAEoBUgAEhUKC2ludDY0X3ZhbHVlGAQgASgDSAASFgoMdWludDMyX3ZhbHVlGAUgASgNSAASFgoMdWludDY0X3ZhbHVlGAYgASgESAASFgoMc2ludDMyX3ZhbHVlGAcgASgRSAASFgoMc2ludDY0X3ZhbHVlGAggASgSSAASFwoNZml4ZWQzMl92YWx1ZRgJIAEoB0gAEhcKDWZpeGVkNjRfdmFsdWUYCiABKAZIABIYCg5zZml4ZWQzMl92YWx1ZRgLIAEoD0gAEhgKDnNmaXhlZDY0X3ZhbHVlGAwgASgQSAASFAoKYm9vbF92YWx1ZRgNIAEoCEgAEhQKCmVudW1fdmFsdWUYDiABKA1IABIWCgxzdHJpbmdfdmFsdWUYDyABKAlIABIVCgtieXRlc192YWx1ZRgQIAEoDEgAEj8KDW1lc3NhZ2VfdmFsdWUYESABKAsyJi5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLk1lc3NhZ2VEaWZmSABCBwoFdmFsdWUiiAYKDVRlc3REaWZmUHJvdG8SHQoVc2luZ3VsYXJfc2NhbGFyX3ZhbHVlGAEgASgBEkQKFnNpbmd1bGFyX21lc3NhZ2VfdmFsdWUYAiABKAsyJC5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLlRlc3RQcm90bxIiChVvcHRpb25hbF9zY2FsYXJfdmFsdWUYCiABKAFIAYgBARIdChVyZXBlYXRlZF9zY2FsYXJfdmFsdWUYAyADKAESRAoWcmVwZWF0ZWRfbWVzc2FnZV92YWx1ZRgEIAMoCzIkLmV4YS5yZWFjdGl2ZV9jb21wb25lbnRfcGIuVGVzdFByb3RvElYKEG1hcF9zY2FsYXJfdmFsdWUYBSADKAsyPC5leGEucmVhY3RpdmVfY29tcG9uZW50X3BiLlRlc3REaWZmUHJvdG8uTWFwU2NhbGFyVmFsdWVFbnRyeRJYChFtYXBfbWVzc2FnZV92YWx1ZRgGIAMoCzI9LmV4YS5yZWFjdGl2ZV9jb21wb25lbnRfcGIuVGVzdERpZmZQcm90by5NYXBNZXNzYWdlVmFsdWVFbnRyeRIcChJvbmVvZl9zY2FsYXJfdmFsdWUYByABKAFIABJDChNvbmVvZl9tZXNzYWdlX3ZhbHVlGAggASgLMiQuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5UZXN0UHJvdG9IABI3CgplbnVtX3ZhbHVlGAkgASgOMiMuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5UZXN0RW51bRo1ChNNYXBTY2FsYXJWYWx1ZUVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaXAoUTWFwTWVzc2FnZVZhbHVlRW50cnkSCwoDa2V5GAEgASgJEjMKBXZhbHVlGAIgASgLMiQuZXhhLnJlYWN0aXZlX2NvbXBvbmVudF9wYi5UZXN0UHJvdG86AjgBQgwKCm9uZW9mX3Rlc3RCGAoWX29wdGlvbmFsX3NjYWxhcl92YWx1ZSpLCghUZXN0RW51bRIZChVURVNUX0VOVU1fVU5TUEVDSUZJRUQQABIRCg1URVNUX0VOVU1fT05FEAESEQoNVEVTVF9FTlVNX1RXTxACYgZwcm90bzM");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.StreamReactiveUpdatesRequest
|
|
||||||
*/
|
|
||||||
export type StreamReactiveUpdatesRequest = Message<"exa.reactive_component_pb.StreamReactiveUpdatesRequest"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint32 protocol_version = 1;
|
|
||||||
*/
|
|
||||||
protocolVersion: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string id = 2;
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.StreamReactiveUpdatesRequest.
|
|
||||||
* Use `create(StreamReactiveUpdatesRequestSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const StreamReactiveUpdatesRequestSchema: GenMessage<StreamReactiveUpdatesRequest> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.StreamReactiveUpdatesResponse
|
|
||||||
*/
|
|
||||||
export type StreamReactiveUpdatesResponse = Message<"exa.reactive_component_pb.StreamReactiveUpdatesResponse"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint64 version = 1;
|
|
||||||
*/
|
|
||||||
version: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.MessageDiff diff = 2;
|
|
||||||
*/
|
|
||||||
diff?: MessageDiff | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bytes full_state = 3;
|
|
||||||
*/
|
|
||||||
fullState: Uint8Array;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.StreamReactiveUpdatesResponse.
|
|
||||||
* Use `create(StreamReactiveUpdatesResponseSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const StreamReactiveUpdatesResponseSchema: GenMessage<StreamReactiveUpdatesResponse> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.TestProto
|
|
||||||
*/
|
|
||||||
export type TestProto = Message<"exa.reactive_component_pb.TestProto"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 counter = 1;
|
|
||||||
*/
|
|
||||||
counter: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated int32 values = 2;
|
|
||||||
*/
|
|
||||||
values: number[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.TestProto nested = 3;
|
|
||||||
*/
|
|
||||||
nested?: TestProto | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.reactive_component_pb.TestProto nested_repeated = 4;
|
|
||||||
*/
|
|
||||||
nestedRepeated: TestProto[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.TestProto.
|
|
||||||
* Use `create(TestProtoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const TestProtoSchema: GenMessage<TestProto> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.MessageDiff
|
|
||||||
*/
|
|
||||||
export type MessageDiff = Message<"exa.reactive_component_pb.MessageDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.reactive_component_pb.FieldDiff field_diffs = 1;
|
|
||||||
*/
|
|
||||||
fieldDiffs: FieldDiff[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.MessageDiff.
|
|
||||||
* Use `create(MessageDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const MessageDiffSchema: GenMessage<MessageDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.FieldDiff
|
|
||||||
*/
|
|
||||||
export type FieldDiff = Message<"exa.reactive_component_pb.FieldDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint32 field_number = 1;
|
|
||||||
*/
|
|
||||||
fieldNumber: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from oneof exa.reactive_component_pb.FieldDiff.diff
|
|
||||||
*/
|
|
||||||
diff: {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.SingularValue update_singular = 2;
|
|
||||||
*/
|
|
||||||
value: SingularValue;
|
|
||||||
case: "updateSingular";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.RepeatedDiff update_repeated = 3;
|
|
||||||
*/
|
|
||||||
value: RepeatedDiff;
|
|
||||||
case: "updateRepeated";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.MapDiff update_map = 4;
|
|
||||||
*/
|
|
||||||
value: MapDiff;
|
|
||||||
case: "updateMap";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: bool clear = 5;
|
|
||||||
*/
|
|
||||||
value: boolean;
|
|
||||||
case: "clear";
|
|
||||||
} | { case: undefined; value?: undefined };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.FieldDiff.
|
|
||||||
* Use `create(FieldDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const FieldDiffSchema: GenMessage<FieldDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.RepeatedDiff
|
|
||||||
*/
|
|
||||||
export type RepeatedDiff = Message<"exa.reactive_component_pb.RepeatedDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint32 new_length = 1;
|
|
||||||
*/
|
|
||||||
newLength: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.reactive_component_pb.SingularValue update_values = 2;
|
|
||||||
*/
|
|
||||||
updateValues: SingularValue[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated uint32 update_indices = 3;
|
|
||||||
*/
|
|
||||||
updateIndices: number[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.RepeatedDiff.
|
|
||||||
* Use `create(RepeatedDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const RepeatedDiffSchema: GenMessage<RepeatedDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 5);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.MapDiff
|
|
||||||
*/
|
|
||||||
export type MapDiff = Message<"exa.reactive_component_pb.MapDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.reactive_component_pb.MapKeyDiff map_key_diffs = 1;
|
|
||||||
*/
|
|
||||||
mapKeyDiffs: MapKeyDiff[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.MapDiff.
|
|
||||||
* Use `create(MapDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const MapDiffSchema: GenMessage<MapDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 6);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.MapKeyDiff
|
|
||||||
*/
|
|
||||||
export type MapKeyDiff = Message<"exa.reactive_component_pb.MapKeyDiff"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.SingularValue map_key = 1;
|
|
||||||
*/
|
|
||||||
mapKey?: SingularValue | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from oneof exa.reactive_component_pb.MapKeyDiff.diff
|
|
||||||
*/
|
|
||||||
diff: {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.SingularValue update_singular = 2;
|
|
||||||
*/
|
|
||||||
value: SingularValue;
|
|
||||||
case: "updateSingular";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: bool clear = 3;
|
|
||||||
*/
|
|
||||||
value: boolean;
|
|
||||||
case: "clear";
|
|
||||||
} | { case: undefined; value?: undefined };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.MapKeyDiff.
|
|
||||||
* Use `create(MapKeyDiffSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const MapKeyDiffSchema: GenMessage<MapKeyDiff> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 7);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.SingularValue
|
|
||||||
*/
|
|
||||||
export type SingularValue = Message<"exa.reactive_component_pb.SingularValue"> & {
|
|
||||||
/**
|
|
||||||
* @generated from oneof exa.reactive_component_pb.SingularValue.value
|
|
||||||
*/
|
|
||||||
value: {
|
|
||||||
/**
|
|
||||||
* @generated from field: double double_value = 1;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "doubleValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: float float_value = 2;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "floatValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 int32_value = 3;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "int32Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 int64_value = 4;
|
|
||||||
*/
|
|
||||||
value: bigint;
|
|
||||||
case: "int64Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint32 uint32_value = 5;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "uint32Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint64 uint64_value = 6;
|
|
||||||
*/
|
|
||||||
value: bigint;
|
|
||||||
case: "uint64Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: sint32 sint32_value = 7;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "sint32Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: sint64 sint64_value = 8;
|
|
||||||
*/
|
|
||||||
value: bigint;
|
|
||||||
case: "sint64Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: fixed32 fixed32_value = 9;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "fixed32Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: fixed64 fixed64_value = 10;
|
|
||||||
*/
|
|
||||||
value: bigint;
|
|
||||||
case: "fixed64Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: sfixed32 sfixed32_value = 11;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "sfixed32Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: sfixed64 sfixed64_value = 12;
|
|
||||||
*/
|
|
||||||
value: bigint;
|
|
||||||
case: "sfixed64Value";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: bool bool_value = 13;
|
|
||||||
*/
|
|
||||||
value: boolean;
|
|
||||||
case: "boolValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: uint32 enum_value = 14;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "enumValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: string string_value = 15;
|
|
||||||
*/
|
|
||||||
value: string;
|
|
||||||
case: "stringValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: bytes bytes_value = 16;
|
|
||||||
*/
|
|
||||||
value: Uint8Array;
|
|
||||||
case: "bytesValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.MessageDiff message_value = 17;
|
|
||||||
*/
|
|
||||||
value: MessageDiff;
|
|
||||||
case: "messageValue";
|
|
||||||
} | { case: undefined; value?: undefined };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.SingularValue.
|
|
||||||
* Use `create(SingularValueSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SingularValueSchema: GenMessage<SingularValue> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 8);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.reactive_component_pb.TestDiffProto
|
|
||||||
*/
|
|
||||||
export type TestDiffProto = Message<"exa.reactive_component_pb.TestDiffProto"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: double singular_scalar_value = 1;
|
|
||||||
*/
|
|
||||||
singularScalarValue: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.TestProto singular_message_value = 2;
|
|
||||||
*/
|
|
||||||
singularMessageValue?: TestProto | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: optional double optional_scalar_value = 10;
|
|
||||||
*/
|
|
||||||
optionalScalarValue?: number | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated double repeated_scalar_value = 3;
|
|
||||||
*/
|
|
||||||
repeatedScalarValue: number[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.reactive_component_pb.TestProto repeated_message_value = 4;
|
|
||||||
*/
|
|
||||||
repeatedMessageValue: TestProto[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: map<int32, double> map_scalar_value = 5;
|
|
||||||
*/
|
|
||||||
mapScalarValue: { [key: number]: number };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: map<string, exa.reactive_component_pb.TestProto> map_message_value = 6;
|
|
||||||
*/
|
|
||||||
mapMessageValue: { [key: string]: TestProto };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from oneof exa.reactive_component_pb.TestDiffProto.oneof_test
|
|
||||||
*/
|
|
||||||
oneofTest: {
|
|
||||||
/**
|
|
||||||
* @generated from field: double oneof_scalar_value = 7;
|
|
||||||
*/
|
|
||||||
value: number;
|
|
||||||
case: "oneofScalarValue";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.TestProto oneof_message_value = 8;
|
|
||||||
*/
|
|
||||||
value: TestProto;
|
|
||||||
case: "oneofMessageValue";
|
|
||||||
} | { case: undefined; value?: undefined };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.reactive_component_pb.TestEnum enum_value = 9;
|
|
||||||
*/
|
|
||||||
enumValue: TestEnum;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.reactive_component_pb.TestDiffProto.
|
|
||||||
* Use `create(TestDiffProtoSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const TestDiffProtoSchema: GenMessage<TestDiffProto> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_reactive_component_pb_reactive_component, 9);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.reactive_component_pb.TestEnum
|
|
||||||
*/
|
|
||||||
export enum TestEnum {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TEST_ENUM_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TEST_ENUM_ONE = 1;
|
|
||||||
*/
|
|
||||||
ONE = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TEST_ENUM_TWO = 2;
|
|
||||||
*/
|
|
||||||
TWO = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.reactive_component_pb.TestEnum.
|
|
||||||
*/
|
|
||||||
export const TestEnumSchema: GenEnum<TestEnum> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_reactive_component_pb_reactive_component, 0);
|
|
||||||
|
|
||||||
@@ -1,712 +0,0 @@
|
|||||||
// @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
|
|
||||||
// @generated from file exa/trust_pb/trust.proto (package exa.trust_pb, syntax proto3)
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
|
||||||
import type { Timestamp } from "@bufbuild/protobuf/wkt";
|
|
||||||
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
|
|
||||||
import type { Message } from "@bufbuild/protobuf";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the file exa/trust_pb/trust.proto.
|
|
||||||
*/
|
|
||||||
export const file_exa_trust_pb_trust: GenFile = /*@__PURE__*/
|
|
||||||
fileDesc("ChhleGEvdHJ1c3RfcGIvdHJ1c3QucHJvdG8SDGV4YS50cnVzdF9wYiJhCg9UcnVzdElkZW50aWZpZXISOgoPaWRlbnRpZmllcl90eXBlGAEgASgOMiEuZXhhLnRydXN0X3BiLlRydXN0SWRlbnRpZmllclR5cGUSEgoKaWRlbnRpZmllchgCIAEoCSJPCg1UcnVzdFF1ZXJ5S2V5EjEKCGtleV90eXBlGAEgASgOMh8uZXhhLnRydXN0X3BiLlRydXN0UXVlcnlLZXlUeXBlEgsKA2tleRgCIAEoCSKPBwoKVHJ1c3RFdmVudBIvCgtvYnNlcnZlZF9hdBgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoGc291cmNlGAMgASgOMh4uZXhhLnRydXN0X3BiLlRydXN0RXZlbnRTb3VyY2USFwoPaWRlbXBvdGVuY3lfa2V5GAQgASgJEi4KB3Vua25vd24YBSABKAsyGy5leGEudHJ1c3RfcGIuVW5rbm93blNpZ25hbEgAEkUKE3Byb3ZpZGVyc19leGhhdXN0ZWQYBiABKAsyJi5leGEudHJ1c3RfcGIuUHJvdmlkZXJzRXhoYXVzdGVkU2lnbmFsSAASSQoWY3Jvc3NfbW9kZWxfcmF0ZV9saW1pdBgHIAEoCzInLmV4YS50cnVzdF9wYi5Dcm9zc01vZGVsUmF0ZUxpbWl0U2lnbmFsSAASOwoOYWNjb3VudF9mYW5vdXQYCCABKAsyIS5leGEudHJ1c3RfcGIuQWNjb3VudEZhbm91dFNpZ25hbEgAEkQKE211bHRpX2lwX3RyYWplY3RvcnkYCSABKAsyJS5leGEudHJ1c3RfcGIuTXVsdGlJcFRyYWplY3RvcnlTaWduYWxIABI0CgtjeWJlcl9hYnVzZRgKIAEoCzIdLmV4YS50cnVzdF9wYi5DeWJlckFidXNlRXZlbnRIABJDChNvcGVuYWlfYmxvY2tlZF91c2VyGAsgASgLMiQuZXhhLnRydXN0X3BiLk9wZW5BSUJsb2NrZWRVc2VyRXZlbnRIABJIChVzdXNwaWNpb3VzX3VzZXJfYWdlbnQYDCABKAsyJy5leGEudHJ1c3RfcGIuU3VzcGljaW91c1VzZXJBZ2VudFNpZ25hbEgAEjcKDG1hbnVhbF90cnVzdBgOIAEoCzIfLmV4YS50cnVzdF9wYi5NYW51YWxUcnVzdFNpZ25hbEgAElAKGWh1bnRlcl9lbWFpbF92ZXJpZmljYXRpb24YESABKAsyKy5leGEudHJ1c3RfcGIuSHVudGVyRW1haWxWZXJpZmljYXRpb25TaWduYWxIABIyCgtpZGVudGlmaWVycxgNIAMoCzIdLmV4YS50cnVzdF9wYi5UcnVzdElkZW50aWZpZXISLgoJcXVlcnlfa2V5GA8gASgLMhsuZXhhLnRydXN0X3BiLlRydXN0UXVlcnlLZXlCCAoGc2lnbmFsSgQIAhADIg8KDVVua25vd25TaWduYWwiswEKGFByb3ZpZGVyc0V4aGF1c3RlZFNpZ25hbBIRCgltb2RlbF91aWQYASABKAkSDAoEdGllchgCIAEoCRIWCg50b3RhbF9hdHRlbXB0cxgDIAEoBRIXCg9sYXN0X2Vycm9yX2NvZGUYBCABKAkSGgoSbGFzdF9lcnJvcl9tZXNzYWdlGAUgASgJEhcKD3Byb3ZpZGVyc190cmllZBgGIAEoBRIQCghhdXRoX3VpZBgHIAEoCSKcAQoZQ3Jvc3NNb2RlbFJhdGVMaW1pdFNpZ25hbBIRCgltb2RlbF91aWQYASABKAkSDAoEdGllchgCIAEoCRINCgVjb3VudBgDIAEoAxINCgVsaW1pdBgEIAEoAxIWCg5wZXJpb2Rfc2Vjb25kcxgFIAEoBRIWCg5lbWFpbF9taXNtYXRjaBgGIAEoCBIQCghhdXRoX3VpZBgHIAEoCSJfChNBY2NvdW50RmFub3V0U2lnbmFsEhAKCGF1dGhfdWlkGAEgASgJEhAKCGlkZW50aXR5GAIgASgJEhIKCmFjY291bnRfaWQYAyABKAkSEAoIaXNfdHJpYWwYBCABKAgilwEKF011bHRpSXBUcmFqZWN0b3J5U2lnbmFsEhAKCGF1dGhfdWlkGAEgASgJEhAKCGlwX2NvdW50GAIgASgDEhEKCXRocmVzaG9sZBgDIAEoAxIWCg53aW5kb3dfc2Vjb25kcxgEIAEoBRIMCgR0aWVyGAUgASgJEg0KBWVtYWlsGAYgASgJEhAKCGVuZm9yY2VkGAcgASgIImoKD0N5YmVyQWJ1c2VFdmVudBIQCghhdXRoX3VpZBgBIAEoCRIQCghwcm92aWRlchgCIAEoCRISCgpldmVudF90eXBlGAMgASgJEhEKCW1vZGVsX3VpZBgEIAEoCRIMCgR0aWVyGAUgASgJIl0KFk9wZW5BSUJsb2NrZWRVc2VyRXZlbnQSEAoIYXV0aF91aWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSEQoJbW9kZWxfdWlkGAMgASgJEgwKBHRpZXIYBCABKAkiWQoZU3VzcGljaW91c1VzZXJBZ2VudFNpZ25hbBIQCghhdXRoX3VpZBgBIAEoCRISCgp1c2VyX2FnZW50GAIgASgJEhYKDm1hdGNoZWRfcHJlZml4GAMgASgJIo0BChFNYW51YWxUcnVzdFNpZ25hbBIQCghhdXRoX3VpZBgBIAEoCRIxCgd2ZXJkaWN0GAIgASgOMiAuZXhhLnRydXN0X3BiLk1hbnVhbFRydXN0VmVyZGljdBIPCgdwZXJjZW50GAMgASgFEg4KBnJlYXNvbhgEIAEoCRISCgpmbGFnZ2VkX2J5GAUgASgJIpwCCh1IdW50ZXJFbWFpbFZlcmlmaWNhdGlvblNpZ25hbBINCgVlbWFpbBgBIAEoCRIOCgZyZXN1bHQYAiABKAkSDgoGc3RhdHVzGAMgASgJEg0KBXNjb3JlGAQgASgFEg4KBnJlZ2V4cBgFIAEoCBIRCglnaWJiZXJpc2gYBiABKAgSEgoKZGlzcG9zYWJsZRgHIAEoCBIPCgd3ZWJtYWlsGAggASgIEhIKCm14X3JlY29yZHMYCSABKAgSEwoLc210cF9zZXJ2ZXIYCiABKAgSEgoKc210cF9jaGVjaxgLIAEoCBISCgphY2NlcHRfYWxsGAwgASgIEg0KBWJsb2NrGA0gASgIEhUKDXNvdXJjZXNfY291bnQYDiABKAUiRAoYUmVjb3JkVHJ1c3RFdmVudHNSZXF1ZXN0EigKBmV2ZW50cxgBIAMoCzIYLmV4YS50cnVzdF9wYi5UcnVzdEV2ZW50IhsKGVJlY29yZFRydXN0RXZlbnRzUmVzcG9uc2UqqwEKEFRydXN0RXZlbnRTb3VyY2USIgoeVFJVU1RfRVZFTlRfU09VUkNFX1VOU1BFQ0lGSUVEEAASIQodVFJVU1RfRVZFTlRfU09VUkNFX0FQSV9TRVJWRVIQARImCiJUUlVTVF9FVkVOVF9TT1VSQ0VfREVWSU5fV0VCU0VSVkVSEAISKAokVFJVU1RfRVZFTlRfU09VUkNFX0lOVEVSTkFMX0RFVEVDVE9SEAMqsgEKE1RydXN0SWRlbnRpZmllclR5cGUSJQohVFJVU1RfSURFTlRJRklFUl9UWVBFX1VOU1BFQ0lGSUVEEAASHwobVFJVU1RfSURFTlRJRklFUl9UWVBFX0VNQUlMEAESJwojVFJVU1RfSURFTlRJRklFUl9UWVBFX0RFVklOX1VTRVJfSUQQAhIqCiZUUlVTVF9JREVOVElGSUVSX1RZUEVfREVWSU5fQUNDT1VOVF9JRBADKq8BChFUcnVzdFF1ZXJ5S2V5VHlwZRIkCiBUUlVTVF9RVUVSWV9LRVlfVFlQRV9VTlNQRUNJRklFRBAAEiEKHVRSVVNUX1FVRVJZX0tFWV9UWVBFX0FVVEhfVUlEEAESJgoiVFJVU1RfUVVFUllfS0VZX1RZUEVfREVWSU5fVVNFUl9JRBACEikKJVRSVVNUX1FVRVJZX0tFWV9UWVBFX0RFVklOX0FDQ09VTlRfSUQQAyp9ChJNYW51YWxUcnVzdFZlcmRpY3QSJAogTUFOVUFMX1RSVVNUX1ZFUkRJQ1RfVU5TUEVDSUZJRUQQABIeChpNQU5VQUxfVFJVU1RfVkVSRElDVF9UUlVTVBABEiEKHU1BTlVBTF9UUlVTVF9WRVJESUNUX0RJU1RSVVNUEAJiBnByb3RvMw", [file_google_protobuf_timestamp]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.TrustIdentifier
|
|
||||||
*/
|
|
||||||
export type TrustIdentifier = Message<"exa.trust_pb.TrustIdentifier"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.TrustIdentifierType identifier_type = 1;
|
|
||||||
*/
|
|
||||||
identifierType: TrustIdentifierType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string identifier = 2;
|
|
||||||
*/
|
|
||||||
identifier: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.TrustIdentifier.
|
|
||||||
* Use `create(TrustIdentifierSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const TrustIdentifierSchema: GenMessage<TrustIdentifier> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.TrustQueryKey
|
|
||||||
*/
|
|
||||||
export type TrustQueryKey = Message<"exa.trust_pb.TrustQueryKey"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.TrustQueryKeyType key_type = 1;
|
|
||||||
*/
|
|
||||||
keyType: TrustQueryKeyType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string key = 2;
|
|
||||||
*/
|
|
||||||
key: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.TrustQueryKey.
|
|
||||||
* Use `create(TrustQueryKeySchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const TrustQueryKeySchema: GenMessage<TrustQueryKey> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.TrustEvent
|
|
||||||
*/
|
|
||||||
export type TrustEvent = Message<"exa.trust_pb.TrustEvent"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: google.protobuf.Timestamp observed_at = 1;
|
|
||||||
*/
|
|
||||||
observedAt?: Timestamp | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.TrustEventSource source = 3;
|
|
||||||
*/
|
|
||||||
source: TrustEventSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string idempotency_key = 4;
|
|
||||||
*/
|
|
||||||
idempotencyKey: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from oneof exa.trust_pb.TrustEvent.signal
|
|
||||||
*/
|
|
||||||
signal: {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.UnknownSignal unknown = 5;
|
|
||||||
*/
|
|
||||||
value: UnknownSignal;
|
|
||||||
case: "unknown";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.ProvidersExhaustedSignal providers_exhausted = 6;
|
|
||||||
*/
|
|
||||||
value: ProvidersExhaustedSignal;
|
|
||||||
case: "providersExhausted";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.CrossModelRateLimitSignal cross_model_rate_limit = 7;
|
|
||||||
*/
|
|
||||||
value: CrossModelRateLimitSignal;
|
|
||||||
case: "crossModelRateLimit";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.AccountFanoutSignal account_fanout = 8;
|
|
||||||
*/
|
|
||||||
value: AccountFanoutSignal;
|
|
||||||
case: "accountFanout";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.MultiIpTrajectorySignal multi_ip_trajectory = 9;
|
|
||||||
*/
|
|
||||||
value: MultiIpTrajectorySignal;
|
|
||||||
case: "multiIpTrajectory";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.CyberAbuseEvent cyber_abuse = 10;
|
|
||||||
*/
|
|
||||||
value: CyberAbuseEvent;
|
|
||||||
case: "cyberAbuse";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.OpenAIBlockedUserEvent openai_blocked_user = 11;
|
|
||||||
*/
|
|
||||||
value: OpenAIBlockedUserEvent;
|
|
||||||
case: "openaiBlockedUser";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.SuspiciousUserAgentSignal suspicious_user_agent = 12;
|
|
||||||
*/
|
|
||||||
value: SuspiciousUserAgentSignal;
|
|
||||||
case: "suspiciousUserAgent";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.ManualTrustSignal manual_trust = 14;
|
|
||||||
*/
|
|
||||||
value: ManualTrustSignal;
|
|
||||||
case: "manualTrust";
|
|
||||||
} | {
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.HunterEmailVerificationSignal hunter_email_verification = 17;
|
|
||||||
*/
|
|
||||||
value: HunterEmailVerificationSignal;
|
|
||||||
case: "hunterEmailVerification";
|
|
||||||
} | { case: undefined; value?: undefined };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.trust_pb.TrustIdentifier identifiers = 13;
|
|
||||||
*/
|
|
||||||
identifiers: TrustIdentifier[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.TrustQueryKey query_key = 15;
|
|
||||||
*/
|
|
||||||
queryKey?: TrustQueryKey | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.TrustEvent.
|
|
||||||
* Use `create(TrustEventSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const TrustEventSchema: GenMessage<TrustEvent> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.UnknownSignal
|
|
||||||
*/
|
|
||||||
export type UnknownSignal = Message<"exa.trust_pb.UnknownSignal"> & {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.UnknownSignal.
|
|
||||||
* Use `create(UnknownSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const UnknownSignalSchema: GenMessage<UnknownSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 3);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.ProvidersExhaustedSignal
|
|
||||||
*/
|
|
||||||
export type ProvidersExhaustedSignal = Message<"exa.trust_pb.ProvidersExhaustedSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string model_uid = 1;
|
|
||||||
*/
|
|
||||||
modelUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string tier = 2;
|
|
||||||
*/
|
|
||||||
tier: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 total_attempts = 3;
|
|
||||||
*/
|
|
||||||
totalAttempts: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string last_error_code = 4;
|
|
||||||
*/
|
|
||||||
lastErrorCode: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string last_error_message = 5;
|
|
||||||
*/
|
|
||||||
lastErrorMessage: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 providers_tried = 6;
|
|
||||||
*/
|
|
||||||
providersTried: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 7;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.ProvidersExhaustedSignal.
|
|
||||||
* Use `create(ProvidersExhaustedSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const ProvidersExhaustedSignalSchema: GenMessage<ProvidersExhaustedSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.CrossModelRateLimitSignal
|
|
||||||
*/
|
|
||||||
export type CrossModelRateLimitSignal = Message<"exa.trust_pb.CrossModelRateLimitSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string model_uid = 1;
|
|
||||||
*/
|
|
||||||
modelUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string tier = 2;
|
|
||||||
*/
|
|
||||||
tier: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 count = 3;
|
|
||||||
*/
|
|
||||||
count: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 limit = 4;
|
|
||||||
*/
|
|
||||||
limit: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 period_seconds = 5;
|
|
||||||
*/
|
|
||||||
periodSeconds: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool email_mismatch = 6;
|
|
||||||
*/
|
|
||||||
emailMismatch: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 7;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.CrossModelRateLimitSignal.
|
|
||||||
* Use `create(CrossModelRateLimitSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CrossModelRateLimitSignalSchema: GenMessage<CrossModelRateLimitSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 5);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.AccountFanoutSignal
|
|
||||||
*/
|
|
||||||
export type AccountFanoutSignal = Message<"exa.trust_pb.AccountFanoutSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string identity = 2;
|
|
||||||
*/
|
|
||||||
identity: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string account_id = 3;
|
|
||||||
*/
|
|
||||||
accountId: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool is_trial = 4;
|
|
||||||
*/
|
|
||||||
isTrial: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.AccountFanoutSignal.
|
|
||||||
* Use `create(AccountFanoutSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const AccountFanoutSignalSchema: GenMessage<AccountFanoutSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 6);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.MultiIpTrajectorySignal
|
|
||||||
*/
|
|
||||||
export type MultiIpTrajectorySignal = Message<"exa.trust_pb.MultiIpTrajectorySignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 ip_count = 2;
|
|
||||||
*/
|
|
||||||
ipCount: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int64 threshold = 3;
|
|
||||||
*/
|
|
||||||
threshold: bigint;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 window_seconds = 4;
|
|
||||||
*/
|
|
||||||
windowSeconds: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string tier = 5;
|
|
||||||
*/
|
|
||||||
tier: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string email = 6;
|
|
||||||
*/
|
|
||||||
email: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool enforced = 7;
|
|
||||||
*/
|
|
||||||
enforced: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.MultiIpTrajectorySignal.
|
|
||||||
* Use `create(MultiIpTrajectorySignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const MultiIpTrajectorySignalSchema: GenMessage<MultiIpTrajectorySignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 7);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.CyberAbuseEvent
|
|
||||||
*/
|
|
||||||
export type CyberAbuseEvent = Message<"exa.trust_pb.CyberAbuseEvent"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string provider = 2;
|
|
||||||
*/
|
|
||||||
provider: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string event_type = 3;
|
|
||||||
*/
|
|
||||||
eventType: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string model_uid = 4;
|
|
||||||
*/
|
|
||||||
modelUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string tier = 5;
|
|
||||||
*/
|
|
||||||
tier: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.CyberAbuseEvent.
|
|
||||||
* Use `create(CyberAbuseEventSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const CyberAbuseEventSchema: GenMessage<CyberAbuseEvent> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 8);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.OpenAIBlockedUserEvent
|
|
||||||
*/
|
|
||||||
export type OpenAIBlockedUserEvent = Message<"exa.trust_pb.OpenAIBlockedUserEvent"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string provider = 2;
|
|
||||||
*/
|
|
||||||
provider: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string model_uid = 3;
|
|
||||||
*/
|
|
||||||
modelUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string tier = 4;
|
|
||||||
*/
|
|
||||||
tier: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.OpenAIBlockedUserEvent.
|
|
||||||
* Use `create(OpenAIBlockedUserEventSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const OpenAIBlockedUserEventSchema: GenMessage<OpenAIBlockedUserEvent> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 9);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.SuspiciousUserAgentSignal
|
|
||||||
*/
|
|
||||||
export type SuspiciousUserAgentSignal = Message<"exa.trust_pb.SuspiciousUserAgentSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string user_agent = 2;
|
|
||||||
*/
|
|
||||||
userAgent: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string matched_prefix = 3;
|
|
||||||
*/
|
|
||||||
matchedPrefix: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.SuspiciousUserAgentSignal.
|
|
||||||
* Use `create(SuspiciousUserAgentSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const SuspiciousUserAgentSignalSchema: GenMessage<SuspiciousUserAgentSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 10);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.ManualTrustSignal
|
|
||||||
*/
|
|
||||||
export type ManualTrustSignal = Message<"exa.trust_pb.ManualTrustSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string auth_uid = 1;
|
|
||||||
*/
|
|
||||||
authUid: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: exa.trust_pb.ManualTrustVerdict verdict = 2;
|
|
||||||
*/
|
|
||||||
verdict: ManualTrustVerdict;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 percent = 3;
|
|
||||||
*/
|
|
||||||
percent: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string reason = 4;
|
|
||||||
*/
|
|
||||||
reason: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string flagged_by = 5;
|
|
||||||
*/
|
|
||||||
flaggedBy: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.ManualTrustSignal.
|
|
||||||
* Use `create(ManualTrustSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const ManualTrustSignalSchema: GenMessage<ManualTrustSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 11);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.HunterEmailVerificationSignal
|
|
||||||
*/
|
|
||||||
export type HunterEmailVerificationSignal = Message<"exa.trust_pb.HunterEmailVerificationSignal"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: string email = 1;
|
|
||||||
*/
|
|
||||||
email: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string result = 2;
|
|
||||||
*/
|
|
||||||
result: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: string status = 3;
|
|
||||||
*/
|
|
||||||
status: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 score = 4;
|
|
||||||
*/
|
|
||||||
score: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool regexp = 5;
|
|
||||||
*/
|
|
||||||
regexp: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool gibberish = 6;
|
|
||||||
*/
|
|
||||||
gibberish: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool disposable = 7;
|
|
||||||
*/
|
|
||||||
disposable: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool webmail = 8;
|
|
||||||
*/
|
|
||||||
webmail: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool mx_records = 9;
|
|
||||||
*/
|
|
||||||
mxRecords: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool smtp_server = 10;
|
|
||||||
*/
|
|
||||||
smtpServer: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool smtp_check = 11;
|
|
||||||
*/
|
|
||||||
smtpCheck: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool accept_all = 12;
|
|
||||||
*/
|
|
||||||
acceptAll: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: bool block = 13;
|
|
||||||
*/
|
|
||||||
block: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from field: int32 sources_count = 14;
|
|
||||||
*/
|
|
||||||
sourcesCount: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.HunterEmailVerificationSignal.
|
|
||||||
* Use `create(HunterEmailVerificationSignalSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const HunterEmailVerificationSignalSchema: GenMessage<HunterEmailVerificationSignal> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 12);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.RecordTrustEventsRequest
|
|
||||||
*/
|
|
||||||
export type RecordTrustEventsRequest = Message<"exa.trust_pb.RecordTrustEventsRequest"> & {
|
|
||||||
/**
|
|
||||||
* @generated from field: repeated exa.trust_pb.TrustEvent events = 1;
|
|
||||||
*/
|
|
||||||
events: TrustEvent[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.RecordTrustEventsRequest.
|
|
||||||
* Use `create(RecordTrustEventsRequestSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const RecordTrustEventsRequestSchema: GenMessage<RecordTrustEventsRequest> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 13);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from message exa.trust_pb.RecordTrustEventsResponse
|
|
||||||
*/
|
|
||||||
export type RecordTrustEventsResponse = Message<"exa.trust_pb.RecordTrustEventsResponse"> & {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the message exa.trust_pb.RecordTrustEventsResponse.
|
|
||||||
* Use `create(RecordTrustEventsResponseSchema)` to create a new message.
|
|
||||||
*/
|
|
||||||
export const RecordTrustEventsResponseSchema: GenMessage<RecordTrustEventsResponse> = /*@__PURE__*/
|
|
||||||
messageDesc(file_exa_trust_pb_trust, 14);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.trust_pb.TrustEventSource
|
|
||||||
*/
|
|
||||||
export enum TrustEventSource {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_EVENT_SOURCE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_EVENT_SOURCE_API_SERVER = 1;
|
|
||||||
*/
|
|
||||||
API_SERVER = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_EVENT_SOURCE_DEVIN_WEBSERVER = 2;
|
|
||||||
*/
|
|
||||||
DEVIN_WEBSERVER = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_EVENT_SOURCE_INTERNAL_DETECTOR = 3;
|
|
||||||
*/
|
|
||||||
INTERNAL_DETECTOR = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.trust_pb.TrustEventSource.
|
|
||||||
*/
|
|
||||||
export const TrustEventSourceSchema: GenEnum<TrustEventSource> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_trust_pb_trust, 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.trust_pb.TrustIdentifierType
|
|
||||||
*/
|
|
||||||
export enum TrustIdentifierType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_IDENTIFIER_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_IDENTIFIER_TYPE_EMAIL = 1;
|
|
||||||
*/
|
|
||||||
EMAIL = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_IDENTIFIER_TYPE_DEVIN_USER_ID = 2;
|
|
||||||
*/
|
|
||||||
DEVIN_USER_ID = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_IDENTIFIER_TYPE_DEVIN_ACCOUNT_ID = 3;
|
|
||||||
*/
|
|
||||||
DEVIN_ACCOUNT_ID = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.trust_pb.TrustIdentifierType.
|
|
||||||
*/
|
|
||||||
export const TrustIdentifierTypeSchema: GenEnum<TrustIdentifierType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_trust_pb_trust, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.trust_pb.TrustQueryKeyType
|
|
||||||
*/
|
|
||||||
export enum TrustQueryKeyType {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_QUERY_KEY_TYPE_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_QUERY_KEY_TYPE_AUTH_UID = 1;
|
|
||||||
*/
|
|
||||||
AUTH_UID = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_QUERY_KEY_TYPE_DEVIN_USER_ID = 2;
|
|
||||||
*/
|
|
||||||
DEVIN_USER_ID = 2,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: TRUST_QUERY_KEY_TYPE_DEVIN_ACCOUNT_ID = 3;
|
|
||||||
*/
|
|
||||||
DEVIN_ACCOUNT_ID = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.trust_pb.TrustQueryKeyType.
|
|
||||||
*/
|
|
||||||
export const TrustQueryKeyTypeSchema: GenEnum<TrustQueryKeyType> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_trust_pb_trust, 2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum exa.trust_pb.ManualTrustVerdict
|
|
||||||
*/
|
|
||||||
export enum ManualTrustVerdict {
|
|
||||||
/**
|
|
||||||
* @generated from enum value: MANUAL_TRUST_VERDICT_UNSPECIFIED = 0;
|
|
||||||
*/
|
|
||||||
UNSPECIFIED = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: MANUAL_TRUST_VERDICT_TRUST = 1;
|
|
||||||
*/
|
|
||||||
TRUST = 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @generated from enum value: MANUAL_TRUST_VERDICT_DISTRUST = 2;
|
|
||||||
*/
|
|
||||||
DISTRUST = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the enum exa.trust_pb.ManualTrustVerdict.
|
|
||||||
*/
|
|
||||||
export const ManualTrustVerdictSchema: GenEnum<ManualTrustVerdict> = /*@__PURE__*/
|
|
||||||
enumDesc(file_exa_trust_pb_trust, 3);
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,13 @@
|
|||||||
import { gunzipSync } from "node:zlib";
|
import { gunzipSync } from "node:zlib";
|
||||||
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary, toBinary } from "./protobuf";
|
||||||
import type { FetchImpl, ModelSpec } from "../types";
|
import type { FetchImpl, ModelSpec } from "../types";
|
||||||
import { discoveryFetch } from "../utils";
|
import { discoveryFetch } from "../utils";
|
||||||
import {
|
import {
|
||||||
|
type ClientModelConfig,
|
||||||
GetCliModelConfigsRequestSchema,
|
GetCliModelConfigsRequestSchema,
|
||||||
GetCliModelConfigsResponseSchema,
|
GetCliModelConfigsResponseSchema,
|
||||||
} from "./devin-gen/exa/api_server_pb/api_server_pb";
|
MetadataSchema,
|
||||||
import { type ClientModelConfig, MetadataSchema } from "./devin-gen/exa/codeium_common_pb/codeium_common_pb";
|
} from "./devin-proto";
|
||||||
|
|
||||||
const DEVIN_DEFAULT_BASE_URL = "https://server.codeium.com";
|
const DEVIN_DEFAULT_BASE_URL = "https://server.codeium.com";
|
||||||
const DEVIN_GET_CLI_MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs";
|
const DEVIN_GET_CLI_MODEL_CONFIGS_PATH = "/exa.api_server_pb.ApiServerService/GetCliModelConfigs";
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ export * from "./codex";
|
|||||||
export * from "./gemini";
|
export * from "./gemini";
|
||||||
export * from "./gitlab-duo-workflow";
|
export * from "./gitlab-duo-workflow";
|
||||||
export * from "./openai-compatible";
|
export * from "./openai-compatible";
|
||||||
|
export * from "./protobuf";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -72,13 +72,34 @@ export const KNOWN_HOSTS = {
|
|||||||
|
|
||||||
export type KnownHost = keyof typeof KNOWN_HOSTS;
|
export type KnownHost = keyof typeof KNOWN_HOSTS;
|
||||||
|
|
||||||
|
// Host checks fan out across every compatibility field for a model. Bound the
|
||||||
|
// cache because custom providers may contribute arbitrary endpoints at runtime.
|
||||||
|
const MAX_URL_HOST_MATCHES = 512;
|
||||||
|
const urlHostMatches = new Map<string, Map<KnownHost, boolean>>();
|
||||||
|
|
||||||
|
function getUrlHostMatches(baseUrl: string): Map<KnownHost, boolean> {
|
||||||
|
let matches = urlHostMatches.get(baseUrl);
|
||||||
|
if (matches !== undefined) return matches;
|
||||||
|
if (urlHostMatches.size === MAX_URL_HOST_MATCHES) urlHostMatches.clear();
|
||||||
|
matches = new Map<KnownHost, boolean>();
|
||||||
|
urlHostMatches.set(baseUrl, matches);
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
/** URL-only host check (for call sites that have no provider id, e.g. raw env config). */
|
/** URL-only host check (for call sites that have no provider id, e.g. raw env config). */
|
||||||
export function hostMatchesUrl(baseUrl: string | undefined, host: KnownHost): boolean {
|
export function hostMatchesUrl(baseUrl: string | undefined, host: KnownHost): boolean {
|
||||||
if (!baseUrl) return false;
|
if (!baseUrl) return false;
|
||||||
|
const matches = getUrlHostMatches(baseUrl);
|
||||||
|
const cached = matches.get(host);
|
||||||
|
if (cached !== undefined) return cached;
|
||||||
const spec: HostClassSpec = KNOWN_HOSTS[host];
|
const spec: HostClassSpec = KNOWN_HOSTS[host];
|
||||||
for (const marker of spec.urlMarkers) {
|
for (const marker of spec.urlMarkers) {
|
||||||
if (includesAsciiCaseInsensitive(baseUrl, marker)) return true;
|
if (includesAsciiCaseInsensitive(baseUrl, marker)) {
|
||||||
|
matches.set(host, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
matches.set(host, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ const KIMI_K2_ALIASES: Record<string, true> = {
|
|||||||
"kimi-for-coding-highspeed": true,
|
"kimi-for-coding-highspeed": true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Resolution is pure and catalog ids recur across providers and aliases.
|
||||||
|
const MAX_TOKENIZER_CACHE_ENTRIES = 2_048;
|
||||||
|
const modelTokenizerCache = new Map<string, ModelTokenizer | null>();
|
||||||
|
|
||||||
function claudeTokenizer(modelId: string): ModelTokenizer | undefined {
|
function claudeTokenizer(modelId: string): ModelTokenizer | undefined {
|
||||||
const parsed = parseAnthropicModel(modelId);
|
const parsed = parseAnthropicModel(modelId);
|
||||||
if (parsed) {
|
if (parsed) {
|
||||||
@@ -56,12 +60,16 @@ function glmTokenizer(modelId: string): ModelTokenizer | undefined {
|
|||||||
* materializes the result as `Model.tokenizer`; consumers read that property.
|
* materializes the result as `Model.tokenizer`; consumers read that property.
|
||||||
*/
|
*/
|
||||||
export function resolveModelTokenizer(modelId: string): ModelTokenizer | undefined {
|
export function resolveModelTokenizer(modelId: string): ModelTokenizer | undefined {
|
||||||
|
const cached = modelTokenizerCache.get(modelId);
|
||||||
|
if (cached !== undefined) return cached ?? undefined;
|
||||||
const bare = bareModelId(modelId);
|
const bare = bareModelId(modelId);
|
||||||
return (
|
const tokenizer =
|
||||||
claudeTokenizer(bare) ??
|
claudeTokenizer(bare) ??
|
||||||
qwenTokenizer(bare) ??
|
qwenTokenizer(bare) ??
|
||||||
deepSeekTokenizer(bare) ??
|
deepSeekTokenizer(bare) ??
|
||||||
kimiTokenizer(bare) ??
|
kimiTokenizer(bare) ??
|
||||||
glmTokenizer(bare)
|
glmTokenizer(bare);
|
||||||
);
|
if (modelTokenizerCache.size === MAX_TOKENIZER_CACHE_ENTRIES) modelTokenizerCache.clear();
|
||||||
|
modelTokenizerCache.set(modelId, tokenizer ?? null);
|
||||||
|
return tokenizer;
|
||||||
}
|
}
|
||||||
|
|||||||
+183610
-2414
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,5 @@
|
|||||||
import { buildModel } from "./build";
|
|
||||||
import MODELS from "./models.json" with { type: "json" };
|
import MODELS from "./models.json" with { type: "json" };
|
||||||
import type { Api, KnownProvider, Model, ModelSpec, TokenCost, Usage } from "./types";
|
import type { Api, KnownProvider, Model, TokenCost, Usage } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static bundled model registry loaded from `models.json`.
|
* Static bundled model registry loaded from `models.json`.
|
||||||
@@ -12,7 +11,7 @@ import type { Api, KnownProvider, Model, ModelSpec, TokenCost, Usage } from "./t
|
|||||||
*/
|
*/
|
||||||
const modelRegistry = new Map<string, Map<string, Model<Api>>>();
|
const modelRegistry = new Map<string, Map<string, Model<Api>>>();
|
||||||
|
|
||||||
/** Build (once) and return one provider's enriched bundled models. */
|
/** Return one provider's bundled models, materialized by the generator. */
|
||||||
function getProviderModels(provider: string): Map<string, Model<Api>> | undefined {
|
function getProviderModels(provider: string): Map<string, Model<Api>> | undefined {
|
||||||
const cachedModels = modelRegistry.get(provider);
|
const cachedModels = modelRegistry.get(provider);
|
||||||
if (cachedModels !== undefined) return cachedModels;
|
if (cachedModels !== undefined) return cachedModels;
|
||||||
@@ -20,8 +19,10 @@ function getProviderModels(provider: string): Map<string, Model<Api>> | undefine
|
|||||||
|
|
||||||
const providerModels = new Map<string, Model<Api>>();
|
const providerModels = new Map<string, Model<Api>>();
|
||||||
const rawModels = MODELS[provider as keyof typeof MODELS];
|
const rawModels = MODELS[provider as keyof typeof MODELS];
|
||||||
for (const [id, model] of Object.entries(rawModels)) {
|
for (const id in rawModels) {
|
||||||
providerModels.set(id, buildModel(model as ModelSpec<Api>));
|
// models.json rows are complete Models emitted by generate-models.ts;
|
||||||
|
// consuming them verbatim keeps startup allocation-free.
|
||||||
|
providerModels.set(id, rawModels[id as keyof typeof rawModels] as unknown as Model<Api>);
|
||||||
}
|
}
|
||||||
modelRegistry.set(provider, providerModels);
|
modelRegistry.set(provider, providerModels);
|
||||||
return providerModels;
|
return providerModels;
|
||||||
|
|||||||
@@ -9,8 +9,18 @@ import type { Api, Model, ModelSpec } from "../types";
|
|||||||
* manager, which rebuilds via `buildModel`.
|
* manager, which rebuilds via `buildModel`.
|
||||||
*/
|
*/
|
||||||
export function toModelSpec<TApi extends Api>(model: Model<TApi>): ModelSpec<TApi> {
|
export function toModelSpec<TApi extends Api>(model: Model<TApi>): ModelSpec<TApi> {
|
||||||
const { compat: _compat, compatConfig, ...rest } = model;
|
const {
|
||||||
return { ...rest, compat: compatConfig } as ModelSpec<TApi>;
|
compat: _compat,
|
||||||
|
compatConfig,
|
||||||
|
supportsComputerUse: _derivedComputerUse,
|
||||||
|
supportsComputerUseConfig,
|
||||||
|
...rest
|
||||||
|
} = model;
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
...(supportsComputerUseConfig !== undefined ? { supportsComputerUse: supportsComputerUseConfig } : {}),
|
||||||
|
compat: compatConfig,
|
||||||
|
} as ModelSpec<TApi>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createBundledReferenceMap<TApi extends Api>(
|
export function createBundledReferenceMap<TApi extends Api>(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { readModelCache, writeModelCache } from "@oh-my-pi/pi-catalog/model-cach
|
|||||||
import { resolveProviderModels } from "@oh-my-pi/pi-catalog/model-manager";
|
import { resolveProviderModels } from "@oh-my-pi/pi-catalog/model-manager";
|
||||||
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
import { getBundledModel } from "@oh-my-pi/pi-catalog/models";
|
||||||
import { openrouterModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
|
import { openrouterModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat";
|
||||||
import type { Model, ModelSpec } from "@oh-my-pi/pi-catalog/types";
|
import type { Api, Model, ModelSpec } from "@oh-my-pi/pi-catalog/types";
|
||||||
|
|
||||||
function completionsSpec(overrides: Partial<ModelSpec<"openai-completions">> = {}): ModelSpec<"openai-completions"> {
|
function completionsSpec(overrides: Partial<ModelSpec<"openai-completions">> = {}): ModelSpec<"openai-completions"> {
|
||||||
return {
|
return {
|
||||||
@@ -58,6 +58,16 @@ describe("buildModel", () => {
|
|||||||
expect(model.compatConfig).toBeUndefined();
|
expect(model.compatConfig).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("built models survive a JSON roundtrip, so generator-materialized rows need no rebuild", () => {
|
||||||
|
// models.ts consumes models.json rows verbatim as complete Models; this
|
||||||
|
// holds only if buildModel output is pure JSON (no functions, no
|
||||||
|
// undefined-valued fields that JSON would drop).
|
||||||
|
const generated = [buildModel(completionsSpec({ reasoning: true })), buildModel(openrouterSpec())];
|
||||||
|
for (const model of generated) {
|
||||||
|
expect(JSON.parse(JSON.stringify(model)) as Model<Api>).toEqual(model);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("lets sparse overrides win over detection and keeps the verbatim config", () => {
|
it("lets sparse overrides win over detection and keeps the verbatim config", () => {
|
||||||
const sparse = { supportsDeveloperRole: true } as const;
|
const sparse = { supportsDeveloperRole: true } as const;
|
||||||
const model = buildModel(
|
const model = buildModel(
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
|
||||||
import { createReferenceResolver } from "../src/provider-models/bundled-references";
|
|
||||||
import type { ModelSpec } from "../src/types";
|
|
||||||
|
|
||||||
const FIXTURE = `${import.meta.dir}/fixtures/bundled-reference-laziness.ts`;
|
|
||||||
|
|
||||||
function runFixture(fixture: string): string {
|
|
||||||
const result = Bun.spawnSync({
|
|
||||||
cmd: [process.execPath, fixture],
|
|
||||||
env: process.env,
|
|
||||||
stdout: "pipe",
|
|
||||||
stderr: "pipe",
|
|
||||||
});
|
|
||||||
expect(result.exitCode, result.stderr.toString()).toBe(0);
|
|
||||||
return result.stdout.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("bundled model laziness", () => {
|
|
||||||
test("provider options and the bundled registry stay lazy", () => {
|
|
||||||
const { retainedRssBytes } = JSON.parse(runFixture(FIXTURE)) as { retainedRssBytes: number };
|
|
||||||
expect(retainedRssBytes).toBeLessThan(8 * 1024 * 1024);
|
|
||||||
}, 60_000);
|
|
||||||
test("a lazy provider-reference factory initializes on first resolution and only once", () => {
|
|
||||||
const reference = {
|
|
||||||
id: "fixture-model",
|
|
||||||
name: "Fixture Model",
|
|
||||||
api: "openai-completions",
|
|
||||||
provider: "fixture",
|
|
||||||
baseUrl: "https://example.test/v1",
|
|
||||||
reasoning: false,
|
|
||||||
input: ["text"],
|
|
||||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
||||||
contextWindow: 8192,
|
|
||||||
maxTokens: 1024,
|
|
||||||
} satisfies ModelSpec<"openai-completions">;
|
|
||||||
let factoryCalls = 0;
|
|
||||||
const resolveReference = createReferenceResolver(() => {
|
|
||||||
factoryCalls++;
|
|
||||||
return new Map([[reference.id, reference]]);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(factoryCalls).toBe(0);
|
|
||||||
expect(resolveReference(reference.id)).toBe(reference);
|
|
||||||
expect(resolveReference(reference.id)).toBe(reference);
|
|
||||||
expect(factoryCalls).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -4,11 +4,11 @@ import * as http2 from "node:http2";
|
|||||||
import type * as net from "node:net";
|
import type * as net from "node:net";
|
||||||
import * as os from "node:os";
|
import * as os from "node:os";
|
||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import { create, toBinary } from "@bufbuild/protobuf";
|
import { create, toBinary } from "../src/discovery/protobuf";
|
||||||
// Import from source, not the package specifier: the workspace `node_modules`
|
// Import from source, not the package specifier: the workspace `node_modules`
|
||||||
// copy resolves to the primary checkout, not this worktree.
|
// copy resolves to the primary checkout, not this worktree.
|
||||||
import { fetchCursorUsableModels } from "../src/discovery/cursor";
|
import { fetchCursorUsableModels } from "../src/discovery/cursor";
|
||||||
import { GetUsableModelsResponseSchema, ModelDetailsSchema } from "../src/discovery/cursor-gen/agent_pb";
|
import { GetUsableModelsResponseSchema, ModelDetailsSchema } from "../src/discovery/cursor-proto";
|
||||||
import { resolveProviderModels } from "../src/model-manager";
|
import { resolveProviderModels } from "../src/model-manager";
|
||||||
import { cursorModelManagerOptions } from "../src/provider-models/special";
|
import { cursorModelManagerOptions } from "../src/provider-models/special";
|
||||||
import type { ModelSpec } from "../src/types";
|
import type { ModelSpec } from "../src/types";
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
import { expect, spyOn } from "bun:test";
|
|
||||||
import * as buildModule from "../../src/build";
|
|
||||||
import type { GeneratedProvider } from "../../src/models";
|
|
||||||
import { ollamaCloudModelManagerOptions } from "../../src/provider-models/ollama";
|
|
||||||
import { nanoGptModelManagerOptions } from "../../src/provider-models/openai-compat";
|
|
||||||
|
|
||||||
Bun.gc(true);
|
|
||||||
const rssBefore = process.memoryUsage().rss;
|
|
||||||
nanoGptModelManagerOptions();
|
|
||||||
ollamaCloudModelManagerOptions();
|
|
||||||
Bun.gc(true);
|
|
||||||
const retainedRssBytes = process.memoryUsage().rss - rssBefore;
|
|
||||||
|
|
||||||
process.stdout.write(JSON.stringify({ retainedRssBytes }));
|
|
||||||
|
|
||||||
// Keep the model-registry import below the RSS assertion setup: importing it
|
|
||||||
// eagerly loads models.json and would invalidate the provider-option laziness
|
|
||||||
// measurement above. This same isolated process can then verify the registry's
|
|
||||||
// own lazy, per-provider enrichment without paying for a second Bun startup.
|
|
||||||
const { getBundledModel, getBundledModels, getBundledProviders } = await import("../../src/models");
|
|
||||||
const { default: MODELS } = await import("../../src/models.json", { with: { type: "json" } });
|
|
||||||
const buildSpy = spyOn(buildModule, "buildModel");
|
|
||||||
const rawProviders = Object.keys(MODELS);
|
|
||||||
const firstProviders = getBundledProviders();
|
|
||||||
const secondProviders = getBundledProviders();
|
|
||||||
|
|
||||||
expect(buildSpy).toHaveBeenCalledTimes(0);
|
|
||||||
expect(firstProviders as string[]).toEqual(rawProviders);
|
|
||||||
expect(secondProviders as string[]).toEqual(rawProviders);
|
|
||||||
expect(secondProviders).not.toBe(firstProviders);
|
|
||||||
|
|
||||||
const provider = "sakana" satisfies GeneratedProvider;
|
|
||||||
const rawModelIds = Object.keys(MODELS[provider]);
|
|
||||||
const firstModels = getBundledModels(provider);
|
|
||||||
|
|
||||||
expect(buildSpy).toHaveBeenCalledTimes(rawModelIds.length);
|
|
||||||
expect(firstModels.map(model => model.id)).toEqual(rawModelIds);
|
|
||||||
|
|
||||||
const secondModels = getBundledModels(provider);
|
|
||||||
expect(secondModels).not.toBe(firstModels);
|
|
||||||
expect(secondModels).toHaveLength(firstModels.length);
|
|
||||||
for (let index = 0; index < firstModels.length; index++) {
|
|
||||||
expect(secondModels[index]).toBe(firstModels[index]);
|
|
||||||
}
|
|
||||||
expect(buildSpy).toHaveBeenCalledTimes(rawModelIds.length);
|
|
||||||
|
|
||||||
const firstModelId = rawModelIds[0];
|
|
||||||
if (firstModelId === undefined) throw new Error(`${provider} must have a bundled model`);
|
|
||||||
expect(getBundledModel(provider, firstModelId)).toBe(firstModels[0]);
|
|
||||||
expect(getBundledModel(provider, firstModelId)).toBe(firstModels[0]);
|
|
||||||
expect(buildSpy).toHaveBeenCalledTimes(rawModelIds.length);
|
|
||||||
|
|
||||||
const unknownProvider = "not-a-bundled-provider" as GeneratedProvider;
|
|
||||||
expect(getBundledModels(unknownProvider)).toEqual([]);
|
|
||||||
expect(getBundledModel(unknownProvider, "missing-model")).toBeUndefined();
|
|
||||||
expect(buildSpy).toHaveBeenCalledTimes(rawModelIds.length);
|
|
||||||
|
|
||||||
buildSpy.mockRestore();
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { expect, it } from "bun:test";
|
||||||
|
import { generateProtoTs, parseProto } from "../scripts/proto-parser";
|
||||||
|
|
||||||
|
it("emits a requested message's transitive schema and enum dependencies", () => {
|
||||||
|
const output = generateProtoTs(
|
||||||
|
parseProto(`
|
||||||
|
syntax = "proto3";
|
||||||
|
package example;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
STATE_UNSPECIFIED = 0;
|
||||||
|
STATE_READY = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Child {
|
||||||
|
string text = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Root {
|
||||||
|
optional bool enabled = 1;
|
||||||
|
Child child = 2;
|
||||||
|
State state = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Unused {
|
||||||
|
string ignored = 1;
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
{ includeMessages: ["example.Root"] },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(output).toContain("export interface Root");
|
||||||
|
expect(output).toContain("export interface Child");
|
||||||
|
expect(output).toContain("export enum State");
|
||||||
|
expect(output).toContain('name: "enabled", kind: "bool", optional: true');
|
||||||
|
expect(output).not.toContain("export interface Unused");
|
||||||
|
});
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { expect, it } from "bun:test";
|
||||||
|
import {
|
||||||
|
decodeJsonValue,
|
||||||
|
encodeJsonValue,
|
||||||
|
type JsonValue,
|
||||||
|
type MessageCodec,
|
||||||
|
type ProtoMessage,
|
||||||
|
pb,
|
||||||
|
} from "../src/discovery/protobuf";
|
||||||
|
|
||||||
|
interface Envelope extends ProtoMessage {
|
||||||
|
enabled?: boolean;
|
||||||
|
choice: { case: undefined; value?: undefined } | { case: "text"; value: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
const EnvelopeSchema = pb<Envelope>("test.Envelope", [
|
||||||
|
{ no: 1, name: "enabled", kind: "bool", optional: true },
|
||||||
|
{
|
||||||
|
kind: "oneof",
|
||||||
|
name: "choice",
|
||||||
|
variants: [{ no: 2, name: "text", kind: "string" }],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
interface Counter extends ProtoMessage {
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CounterSchema = pb<Counter>("test.Counter", [{ no: 1, name: "value", kind: "int32" }]);
|
||||||
|
|
||||||
|
interface Node extends ProtoMessage {
|
||||||
|
label: string;
|
||||||
|
child?: Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NodeSchema: MessageCodec<Node> = pb<Node>("test.Node", [
|
||||||
|
{ no: 1, name: "label", kind: "string" },
|
||||||
|
{ no: 2, name: "child", kind: "message", T: () => NodeSchema },
|
||||||
|
]);
|
||||||
|
|
||||||
|
it("preserves selected oneofs and explicit optional defaults", () => {
|
||||||
|
const decoded = EnvelopeSchema.decode(
|
||||||
|
EnvelopeSchema.encode({ enabled: false, choice: { case: "text", value: "hello" } }),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(decoded).toMatchObject({ enabled: false, choice: { case: "text", value: "hello" } });
|
||||||
|
expect(EnvelopeSchema.toJson(decoded)).toEqual({ enabled: false, text: "hello" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("retains unknown wire fields while re-encoding a message", () => {
|
||||||
|
const input = new Uint8Array([0x08, 0x2a, 0x10, 0x07]);
|
||||||
|
|
||||||
|
expect(CounterSchema.encode(CounterSchema.decode(input))).toEqual(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("round-trips JSON values with empty struct keys", () => {
|
||||||
|
const value: JsonValue = { "": ["kept", { nested: true }], count: 1 };
|
||||||
|
|
||||||
|
expect(decodeJsonValue(encodeJsonValue(value))).toEqual(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resolves recursive static message descriptors on demand", () => {
|
||||||
|
const decoded = NodeSchema.decode(
|
||||||
|
NodeSchema.encode({ label: "root", child: { label: "child", child: { label: "leaf" } } }),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(decoded.child?.child?.label).toBe("leaf");
|
||||||
|
});
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
- Compaction method priorities — `compaction.methodOrder` takes an ordered preference list (e.g. `[remote, snap]` uses remote compaction where the provider supports it, such as OpenAI, and snap everywhere else), replacing `compaction.strategy`/`compaction.remoteEnabled`.
|
- Compaction method priorities — `compaction.methodOrder` takes an ordered preference list (e.g. `[remote, snap]` uses remote compaction where the provider supports it, such as OpenAI, and snap everywhere else), replacing `compaction.strategy`/`compaction.remoteEnabled`.
|
||||||
- Unified inline overlays and selectors (model picker, settings, `/cleanse`) into one titled rounded-box panel style.
|
- Unified inline overlays and selectors (model picker, settings, `/cleanse`) into one titled rounded-box panel style.
|
||||||
- Risk badges and warnings on `/settings` rows, starting with External Thinking.
|
- Risk badges and warnings on `/settings` rows, starting with External Thinking.
|
||||||
|
- Faster CLI Startup
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { memoryFixtures } from "./memory";
|
|||||||
import { miscFixtures } from "./misc";
|
import { miscFixtures } from "./misc";
|
||||||
import { searchFixtures } from "./search";
|
import { searchFixtures } from "./search";
|
||||||
import { shellFixtures } from "./shell";
|
import { shellFixtures } from "./shell";
|
||||||
|
import { statusLineFixtures } from "./status-line";
|
||||||
import { webFixtures } from "./web";
|
import { webFixtures } from "./web";
|
||||||
|
|
||||||
export * from "./types";
|
export * from "./types";
|
||||||
@@ -36,5 +37,6 @@ export const galleryFixtures = {
|
|||||||
...memoryFixtures,
|
...memoryFixtures,
|
||||||
...webFixtures,
|
...webFixtures,
|
||||||
...codeintelFixtures,
|
...codeintelFixtures,
|
||||||
|
...statusLineFixtures,
|
||||||
...miscFixtures,
|
...miscFixtures,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Gallery fixture for the status-line context gauge — the box top border that
|
||||||
|
* bridges the segment groups. Renders the real `StatusLineComponent` against a
|
||||||
|
* fake session at four usage levels, mapping the gallery lifecycle states to
|
||||||
|
* fill levels; `error` shows the >100% overflow case (usage anchored to a
|
||||||
|
* larger window than the active model's, e.g. after switching to a smaller
|
||||||
|
* model mid-session), where the gauge clamps to full while the context_pct
|
||||||
|
* segment reports the raw percent.
|
||||||
|
*/
|
||||||
|
import { StatusLineComponent } from "../../modes/components/status-line";
|
||||||
|
import { theme } from "../../modes/theme/theme";
|
||||||
|
import type { AgentSession } from "../../session/agent-session";
|
||||||
|
import type { GalleryFixture, GalleryFixtureState } from "./types";
|
||||||
|
|
||||||
|
const GAUGE_WINDOW = 200_000;
|
||||||
|
|
||||||
|
/** Simulated usage per gallery lifecycle state, against {@link GAUGE_WINDOW}. */
|
||||||
|
const GAUGE_CASES: Record<GalleryFixtureState, { tokens: number; note: string }> = {
|
||||||
|
streaming: { tokens: 6_000, note: "3% used — fresh session" },
|
||||||
|
progress: { tokens: 124_000, note: "62% used — warning zone" },
|
||||||
|
success: { tokens: 194_000, note: "97% used — past compaction threshold" },
|
||||||
|
error: { tokens: 240_000, note: "120% used — overflow: percent breaks past the window label in red" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Minimal session double satisfying every query `getTopBorder` makes. */
|
||||||
|
function fakeGaugeSession(tokens: number): AgentSession {
|
||||||
|
const model = { id: "test-model", contextWindow: GAUGE_WINDOW };
|
||||||
|
const messages = [{ role: "user", content: "hi" }];
|
||||||
|
return {
|
||||||
|
messages,
|
||||||
|
systemPrompt: [],
|
||||||
|
agent: { state: { tools: [] } },
|
||||||
|
skills: [],
|
||||||
|
model,
|
||||||
|
modelRegistry: { isUsingOAuth: () => false },
|
||||||
|
state: { messages, model },
|
||||||
|
settings: undefined,
|
||||||
|
sessionManager: {
|
||||||
|
getUsageStatistics: () => ({
|
||||||
|
input: 0,
|
||||||
|
output: 0,
|
||||||
|
cacheRead: 0,
|
||||||
|
cacheWrite: 0,
|
||||||
|
totalTokens: 0,
|
||||||
|
orchestrationInput: 0,
|
||||||
|
orchestrationOutput: 0,
|
||||||
|
orchestrationCacheRead: 0,
|
||||||
|
premiumRequests: 0,
|
||||||
|
cost: 0,
|
||||||
|
}),
|
||||||
|
getSessionName: () => "gallery",
|
||||||
|
},
|
||||||
|
getAsyncJobSnapshot: () => ({ running: [] }),
|
||||||
|
isFastModeActive: () => false,
|
||||||
|
getContextUsage: () => ({ tokens, contextWindow: GAUGE_WINDOW, percent: (tokens / GAUGE_WINDOW) * 100 }),
|
||||||
|
contextUsageRevision: 0,
|
||||||
|
} as unknown as AgentSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Render one contextLine variant of the top border for the given usage. */
|
||||||
|
function renderGaugeVariant(tokens: number, contextLine: "annotated" | "embedded", width: number): string {
|
||||||
|
const component = new StatusLineComponent(fakeGaugeSession(tokens));
|
||||||
|
component.updateSettings({
|
||||||
|
preset: "custom",
|
||||||
|
leftSegments: contextLine === "embedded" ? ["model", "context_pct"] : ["model"],
|
||||||
|
rightSegments: contextLine === "embedded" ? ["session_name"] : ["context_pct"],
|
||||||
|
separator: "powerline-thin",
|
||||||
|
sessionAccent: false,
|
||||||
|
contextLine,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
return component.getTopBorder(width).content;
|
||||||
|
} finally {
|
||||||
|
component.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderContextGaugeState(state: GalleryFixtureState, width: number): readonly string[] {
|
||||||
|
const { tokens, note } = GAUGE_CASES[state];
|
||||||
|
return [
|
||||||
|
theme.fg("dim", ` ${note}`),
|
||||||
|
renderGaugeVariant(tokens, "annotated", width),
|
||||||
|
renderGaugeVariant(tokens, "embedded", width),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const statusLineFixtures: Record<string, GalleryFixture> = {
|
||||||
|
context_gauge: {
|
||||||
|
label: "Context Gauge",
|
||||||
|
renderState: renderContextGaugeState,
|
||||||
|
args: { note: "status-line context gauge preview" },
|
||||||
|
result: { content: [{ type: "text", text: "Rendered annotated and embedded context gauges." }] },
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -164,15 +164,6 @@ export function mergeProviderRemoteCompactionConfig(
|
|||||||
return mergeRemoteCompactionConfig(providerConfig, modelConfig);
|
return mergeRemoteCompactionConfig(providerConfig, modelConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Project a built model back to spec shape for the model-manager/cache
|
|
||||||
* boundary: sparse compat comes from `compatConfig`, never from the resolved
|
|
||||||
* record.
|
|
||||||
*/
|
|
||||||
export function toModelSpec<TApi extends Api>(model: Model<TApi>): ModelSpec<TApi> {
|
|
||||||
return { ...model, compat: model.compatConfig } as ModelSpec<TApi>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The patchable subset of `Model` fields shared by `modelOverrides` entries,
|
* The patchable subset of `Model` fields shared by `modelOverrides` entries,
|
||||||
* custom model definitions, and parsed custom-model overlays. `undefined`
|
* custom model definitions, and parsed custom-model overlays. `undefined`
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import {
|
|||||||
resolveModelCacheProviderId,
|
resolveModelCacheProviderId,
|
||||||
resolveOllamaModelCacheProviderId,
|
resolveOllamaModelCacheProviderId,
|
||||||
} from "@oh-my-pi/pi-catalog/provider-models";
|
} from "@oh-my-pi/pi-catalog/provider-models";
|
||||||
|
import { toModelSpec } from "@oh-my-pi/pi-catalog/provider-models/bundled-references";
|
||||||
import { collapseBuiltModelVariants } from "@oh-my-pi/pi-catalog/variant-collapse";
|
import { collapseBuiltModelVariants } from "@oh-my-pi/pi-catalog/variant-collapse";
|
||||||
import { getAgentDir, isBunTestRuntime, logger, wrapFetchForExtraCa } from "@oh-my-pi/pi-utils";
|
import { getAgentDir, isBunTestRuntime, logger, wrapFetchForExtraCa } from "@oh-my-pi/pi-utils";
|
||||||
import { resolveProviderModelReference } from "../config/model-resolver";
|
import { resolveProviderModelReference } from "../config/model-resolver";
|
||||||
@@ -80,7 +81,6 @@ import {
|
|||||||
mergeRemoteCompactionConfig,
|
mergeRemoteCompactionConfig,
|
||||||
type ProviderOverride,
|
type ProviderOverride,
|
||||||
providersWithAuthoritativeProjectCatalog,
|
providersWithAuthoritativeProjectCatalog,
|
||||||
toModelSpec,
|
|
||||||
} from "./model-patch";
|
} from "./model-patch";
|
||||||
import {
|
import {
|
||||||
BUILT_IN_DISCOVERY_CACHE_TTL_MS,
|
BUILT_IN_DISCOVERY_CACHE_TTL_MS,
|
||||||
@@ -646,7 +646,7 @@ export class ModelRegistry {
|
|||||||
|
|
||||||
return models.map(m => {
|
return models.map(m => {
|
||||||
if (!providerOverride) return m;
|
if (!providerOverride) return m;
|
||||||
const withTransportOverride = this.#applyProviderTransportOverride(m, providerOverride);
|
const withTransportOverride = this.#applyProviderTransportOverride(toModelSpec(m), providerOverride);
|
||||||
return buildModel({
|
return buildModel({
|
||||||
...withTransportOverride,
|
...withTransportOverride,
|
||||||
compat: mergeCompat(m.compatConfig, providerOverride.compat),
|
compat: mergeCompat(m.compatConfig, providerOverride.compat),
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
/// <reference path="./legacy-pi-virtual-modules.d.ts" />
|
/// <reference path="./legacy-pi-virtual-modules.d.ts" />
|
||||||
|
|
||||||
|
import { Database } from "bun:sqlite";
|
||||||
import * as fs from "node:fs";
|
import * as fs from "node:fs";
|
||||||
import { createRequire, isBuiltin } from "node:module";
|
import { createRequire, isBuiltin } from "node:module";
|
||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import * as url from "node:url";
|
import * as url from "node:url";
|
||||||
import type { ParseResult, ParserPlugin } from "@babel/parser";
|
import type { ParseResult, ParserPlugin } from "@babel/parser";
|
||||||
import { parse as parseBabel } from "@babel/parser";
|
import { parse as parseBabel } from "@babel/parser";
|
||||||
import { isCompiledBinary, stripWindowsExtendedLengthPathPrefix } from "@oh-my-pi/pi-utils";
|
import {
|
||||||
|
getLegacyPiExtensionCacheDbPath,
|
||||||
|
isCompiledBinary,
|
||||||
|
logger,
|
||||||
|
stripWindowsExtendedLengthPathPrefix,
|
||||||
|
} from "@oh-my-pi/pi-utils";
|
||||||
import { registerPluginCacheInvalidator } from "../../discovery/helpers";
|
import { registerPluginCacheInvalidator } from "../../discovery/helpers";
|
||||||
|
|
||||||
const IS_COMPILED_BINARY = isCompiledBinary();
|
const IS_COMPILED_BINARY = isCompiledBinary();
|
||||||
@@ -537,6 +543,159 @@ function collectExtensionSpecifierReferences(
|
|||||||
return references;
|
return references;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EXTENSION_PARSE_CACHE_SCHEMA_VERSION = 1;
|
||||||
|
const EXTENSION_PARSE_CACHE_MAX_BYTES = 8 * 1024 * 1024;
|
||||||
|
const EXTENSION_PARSE_CACHE_MAX_ENTRIES = 10_000;
|
||||||
|
|
||||||
|
interface ExtensionSourceAnalysis {
|
||||||
|
readonly sourceType: "script" | "module";
|
||||||
|
readonly references: readonly ExtensionSpecifierReference[];
|
||||||
|
readonly commonJsNamedExports: readonly string[];
|
||||||
|
readonly commonJsReexportSpecifiers: readonly string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ExtensionParseCacheRow {
|
||||||
|
source_type: "script" | "module";
|
||||||
|
references: string;
|
||||||
|
commonjs_named_exports: string;
|
||||||
|
commonjs_reexport_specifiers: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let extensionParseCacheDb: Database | null | undefined;
|
||||||
|
const extensionSourceAnalysisCache = new Map<string, ExtensionSourceAnalysis>();
|
||||||
|
|
||||||
|
function extensionParseCacheKey(source: string, importerPath: string): string {
|
||||||
|
return `${EXTENSION_PARSE_CACHE_SCHEMA_VERSION}:${path.extname(importerPath).toLowerCase()}:${Bun.hash(source).toString(16)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExtensionParseCacheDb(): Database | null {
|
||||||
|
if (extensionParseCacheDb !== undefined) return extensionParseCacheDb;
|
||||||
|
try {
|
||||||
|
const cachePath = getLegacyPiExtensionCacheDbPath();
|
||||||
|
try {
|
||||||
|
if (fs.statSync(cachePath).size > EXTENSION_PARSE_CACHE_MAX_BYTES) {
|
||||||
|
fs.rmSync(cachePath, { force: true });
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// A missing or unreadable cache is a cold cache.
|
||||||
|
}
|
||||||
|
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
||||||
|
const db = new Database(cachePath, { create: true });
|
||||||
|
db.run("PRAGMA busy_timeout = 50");
|
||||||
|
db.run(
|
||||||
|
"CREATE TABLE IF NOT EXISTS extension_parse_cache (cache_key TEXT PRIMARY KEY, source_type TEXT NOT NULL, references TEXT NOT NULL, commonjs_named_exports TEXT NOT NULL, commonjs_reexport_specifiers TEXT NOT NULL)",
|
||||||
|
);
|
||||||
|
extensionParseCacheDb = db;
|
||||||
|
return db;
|
||||||
|
} catch (error) {
|
||||||
|
logger.debug("legacy Pi extension parse cache unavailable", {
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
});
|
||||||
|
extensionParseCacheDb = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCachedAnalysis(row: ExtensionParseCacheRow): ExtensionSourceAnalysis | null {
|
||||||
|
try {
|
||||||
|
if (row.source_type !== "script" && row.source_type !== "module") return null;
|
||||||
|
const references = JSON.parse(row.references) as unknown;
|
||||||
|
const commonJsNamedExports = JSON.parse(row.commonjs_named_exports) as unknown;
|
||||||
|
const commonJsReexportSpecifiers = JSON.parse(row.commonjs_reexport_specifiers) as unknown;
|
||||||
|
if (
|
||||||
|
!Array.isArray(references) ||
|
||||||
|
!references.every(
|
||||||
|
reference =>
|
||||||
|
reference &&
|
||||||
|
typeof reference === "object" &&
|
||||||
|
(reference.kind === "import" || reference.kind === "require") &&
|
||||||
|
typeof reference.specifier === "string" &&
|
||||||
|
typeof reference.start === "number" &&
|
||||||
|
typeof reference.end === "number",
|
||||||
|
) ||
|
||||||
|
!Array.isArray(commonJsNamedExports) ||
|
||||||
|
!commonJsNamedExports.every(name => typeof name === "string") ||
|
||||||
|
!Array.isArray(commonJsReexportSpecifiers) ||
|
||||||
|
!commonJsReexportSpecifiers.every(specifier => typeof specifier === "string")
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
sourceType: row.source_type,
|
||||||
|
references: references as ExtensionSpecifierReference[],
|
||||||
|
commonJsNamedExports,
|
||||||
|
commonJsReexportSpecifiers,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeExtensionSourceAnalysis(cacheKey: string, analysis: ExtensionSourceAnalysis): void {
|
||||||
|
void Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
const db = getExtensionParseCacheDb();
|
||||||
|
if (!db) return;
|
||||||
|
db.run(
|
||||||
|
"INSERT OR REPLACE INTO extension_parse_cache (cache_key, source_type, references, commonjs_named_exports, commonjs_reexport_specifiers) VALUES (?, ?, ?, ?, ?)",
|
||||||
|
[
|
||||||
|
cacheKey,
|
||||||
|
analysis.sourceType,
|
||||||
|
JSON.stringify(analysis.references),
|
||||||
|
JSON.stringify(analysis.commonJsNamedExports),
|
||||||
|
JSON.stringify(analysis.commonJsReexportSpecifiers),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
const count =
|
||||||
|
db.query<{ count: number }, []>("SELECT count(*) AS count FROM extension_parse_cache").get()?.count ?? 0;
|
||||||
|
if (count > EXTENSION_PARSE_CACHE_MAX_ENTRIES) {
|
||||||
|
db.run("DELETE FROM extension_parse_cache");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
logger.debug("legacy Pi extension parse cache write failed", {
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExtensionSourceAnalysis(source: string, importerPath: string): ExtensionSourceAnalysis {
|
||||||
|
const cacheKey = extensionParseCacheKey(source, importerPath);
|
||||||
|
const memoryCached = extensionSourceAnalysisCache.get(cacheKey);
|
||||||
|
if (memoryCached) return memoryCached;
|
||||||
|
|
||||||
|
const db = getExtensionParseCacheDb();
|
||||||
|
try {
|
||||||
|
const row = db
|
||||||
|
?.query<ExtensionParseCacheRow, [string]>(
|
||||||
|
"SELECT source_type, references, commonjs_named_exports, commonjs_reexport_specifiers FROM extension_parse_cache WHERE cache_key = ?",
|
||||||
|
)
|
||||||
|
.get(cacheKey);
|
||||||
|
if (row) {
|
||||||
|
const cached = parseCachedAnalysis(row);
|
||||||
|
if (cached) {
|
||||||
|
extensionSourceAnalysisCache.set(cacheKey, cached);
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.debug("legacy Pi extension parse cache read failed", {
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ast = parseExtensionSource(source, importerPath);
|
||||||
|
const commonJs = collectCommonJsExportAnalysis(ast);
|
||||||
|
const analysis: ExtensionSourceAnalysis = {
|
||||||
|
sourceType: ast.program.sourceType,
|
||||||
|
references: collectExtensionSpecifierReferences(source, importerPath, ast),
|
||||||
|
...commonJs,
|
||||||
|
};
|
||||||
|
extensionSourceAnalysisCache.set(cacheKey, analysis);
|
||||||
|
writeExtensionSourceAnalysis(cacheKey, analysis);
|
||||||
|
return analysis;
|
||||||
|
}
|
||||||
|
|
||||||
function applySpecifierReplacements(
|
function applySpecifierReplacements(
|
||||||
source: string,
|
source: string,
|
||||||
replacements: ReadonlyArray<ExtensionSpecifierReference & { readonly replacement: string }>,
|
replacements: ReadonlyArray<ExtensionSpecifierReference & { readonly replacement: string }>,
|
||||||
@@ -1003,7 +1162,7 @@ async function rewriteLegacyExtensionSource(
|
|||||||
// Compiled mode completes the override map from the build-supplied module
|
// Compiled mode completes the override map from the build-supplied module
|
||||||
// keys on first use; every rewrite path must see the full map.
|
// keys on first use; every rewrite path must see the full map.
|
||||||
await ensureLegacyPiOverridesReady();
|
await ensureLegacyPiOverridesReady();
|
||||||
const references = collectExtensionSpecifierReferences(source, importerPath);
|
const references = getExtensionSourceAnalysis(source, importerPath).references;
|
||||||
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
||||||
for (const reference of references) {
|
for (const reference of references) {
|
||||||
if (reference.kind !== "import") continue;
|
if (reference.kind !== "import") continue;
|
||||||
@@ -1448,7 +1607,7 @@ async function isCommonJsModulePath(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const parsedSourceType =
|
const parsedSourceType =
|
||||||
sourceType ?? parseExtensionSource(await Bun.file(modulePath).text(), modulePath).program.sourceType;
|
sourceType ?? getExtensionSourceAnalysis(await Bun.file(modulePath).text(), modulePath).sourceType;
|
||||||
if (parsedSourceType === "module") {
|
if (parsedSourceType === "module") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1776,7 +1935,7 @@ async function rewriteExtensionSpecifiers(
|
|||||||
importerPath: string,
|
importerPath: string,
|
||||||
rewriteImports = false,
|
rewriteImports = false,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const references = collectExtensionSpecifierReferences(source, importerPath);
|
const references = getExtensionSourceAnalysis(source, importerPath).references;
|
||||||
const resolvedSpecifierTargets = new Map<string, string>();
|
const resolvedSpecifierTargets = new Map<string, string>();
|
||||||
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
||||||
for (const reference of references) {
|
for (const reference of references) {
|
||||||
@@ -1808,7 +1967,7 @@ function rewriteExtensionSpecifiersFromCache(source: string, importerPath: strin
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
const replacements: Array<ExtensionSpecifierReference & { replacement: string }> = [];
|
||||||
for (const reference of collectExtensionSpecifierReferences(source, importerPath)) {
|
for (const reference of getExtensionSourceAnalysis(source, importerPath).references) {
|
||||||
const replacement = resolvedSpecifierTargets.get(`${reference.kind}\0${reference.specifier}`);
|
const replacement = resolvedSpecifierTargets.get(`${reference.kind}\0${reference.specifier}`);
|
||||||
if (replacement) {
|
if (replacement) {
|
||||||
replacements.push({ ...reference, replacement });
|
replacements.push({ ...reference, replacement });
|
||||||
@@ -1839,7 +1998,7 @@ async function moduleRequiresNativeAddonUncached(modulePath: string): Promise<bo
|
|||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (const reference of collectExtensionSpecifierReferences(source, modulePath)) {
|
for (const reference of getExtensionSourceAnalysis(source, modulePath).references) {
|
||||||
if (reference.kind === "require" && (await resolveExtensionNativeAddon(reference.specifier, modulePath))) {
|
if (reference.kind === "require" && (await resolveExtensionNativeAddon(reference.specifier, modulePath))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2040,18 +2199,18 @@ async function collectExtensionModules(entryRealPath: string): Promise<Extension
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
modules.set(file, source);
|
modules.set(file, source);
|
||||||
const ast = parseExtensionSource(source, file);
|
const analysis = getExtensionSourceAnalysis(source, file);
|
||||||
const sourceIsCommonJs = await isGraphOwnedCommonJsModule(
|
const sourceIsCommonJs = await isGraphOwnedCommonJsModule(
|
||||||
file,
|
file,
|
||||||
entryRealPath,
|
entryRealPath,
|
||||||
ast.program.sourceType,
|
analysis.sourceType,
|
||||||
inheritedModuleKind,
|
inheritedModuleKind,
|
||||||
);
|
);
|
||||||
if (sourceIsCommonJs) {
|
if (sourceIsCommonJs) {
|
||||||
commonJsPaths.add(file);
|
commonJsPaths.add(file);
|
||||||
}
|
}
|
||||||
const dir = path.dirname(file);
|
const dir = path.dirname(file);
|
||||||
const references = collectExtensionSpecifierReferences(source, file, ast);
|
const references = analysis.references;
|
||||||
for (const reference of references) {
|
for (const reference of references) {
|
||||||
const specifier = reference.specifier;
|
const specifier = reference.specifier;
|
||||||
try {
|
try {
|
||||||
@@ -2233,22 +2392,11 @@ export async function __collectLegacyPiExtensionSourcesForTests(
|
|||||||
*/
|
*/
|
||||||
const COMMONJS_NAMED_EXPORT_IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
const COMMONJS_NAMED_EXPORT_IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
||||||
|
|
||||||
function collectCommonJsNamedExports(source: string, modulePath: string, visited = new Set<string>()): string[] {
|
function collectCommonJsExportAnalysis(
|
||||||
let realModulePath = modulePath;
|
ast: ParseResult,
|
||||||
try {
|
): Pick<ExtensionSourceAnalysis, "commonJsNamedExports" | "commonJsReexportSpecifiers"> {
|
||||||
realModulePath = fs.realpathSync(modulePath);
|
|
||||||
} catch {
|
|
||||||
// The caller's path remains the stable cycle key when realpath fails.
|
|
||||||
}
|
|
||||||
if (visited.has(realModulePath)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
visited.add(realModulePath);
|
|
||||||
|
|
||||||
const names = new Set<string>();
|
const names = new Set<string>();
|
||||||
|
|
||||||
const reexportSpecifiers = new Set<string>();
|
const reexportSpecifiers = new Set<string>();
|
||||||
const ast = parseExtensionSource(source, modulePath);
|
|
||||||
for (const { node, scope } of collectScopedAstNodes(
|
for (const { node, scope } of collectScopedAstNodes(
|
||||||
ast,
|
ast,
|
||||||
candidate => candidate.type === "CallExpression" || candidate.type === "AssignmentExpression",
|
candidate => candidate.type === "CallExpression" || candidate.type === "AssignmentExpression",
|
||||||
@@ -2284,17 +2432,13 @@ function collectCommonJsNamedExports(source: string, modulePath: string, visited
|
|||||||
if (node.type !== "AssignmentExpression" || node.operator !== "=") continue;
|
if (node.type !== "AssignmentExpression" || node.operator !== "=") continue;
|
||||||
const left = asAstNode(node.left);
|
const left = asAstNode(node.left);
|
||||||
if (left?.type !== "MemberExpression") continue;
|
if (left?.type !== "MemberExpression") continue;
|
||||||
|
|
||||||
const propertyName = staticMemberPropertyName(left);
|
const propertyName = staticMemberPropertyName(left);
|
||||||
const object = asAstNode(left.object);
|
const object = asAstNode(left.object);
|
||||||
if (propertyName !== null && isUnshadowedExportsTarget(object, scope)) {
|
if (propertyName !== null && isUnshadowedExportsTarget(object, scope)) {
|
||||||
if (propertyName !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(propertyName)) {
|
if (propertyName !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(propertyName)) names.add(propertyName);
|
||||||
names.add(propertyName);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!isUncomputedMember(left, "module", "exports") || scopeHasBinding(scope, MODULE_BINDING)) continue;
|
if (!isUncomputedMember(left, "module", "exports") || scopeHasBinding(scope, MODULE_BINDING)) continue;
|
||||||
|
|
||||||
const right = asAstNode(node.right);
|
const right = asAstNode(node.right);
|
||||||
if (right?.type === "ObjectExpression") {
|
if (right?.type === "ObjectExpression") {
|
||||||
const properties = nodeArray(right, "properties");
|
const properties = nodeArray(right, "properties");
|
||||||
@@ -2303,28 +2447,37 @@ function collectCommonJsNamedExports(source: string, modulePath: string, visited
|
|||||||
const property = asAstNode(value);
|
const property = asAstNode(value);
|
||||||
if (!property || (property.type !== "ObjectProperty" && property.type !== "ObjectMethod")) continue;
|
if (!property || (property.type !== "ObjectProperty" && property.type !== "ObjectMethod")) continue;
|
||||||
const name = staticObjectPropertyName(property);
|
const name = staticObjectPropertyName(property);
|
||||||
if (name && name !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(name)) {
|
if (name && name !== "default" && COMMONJS_NAMED_EXPORT_IDENTIFIER.test(name)) names.add(name);
|
||||||
names.add(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isGlobalRequireCall(right, scope)) {
|
if (isGlobalRequireCall(right, scope)) {
|
||||||
const argument = nodeArgument(right, 0);
|
const argument = nodeArgument(right, 0);
|
||||||
if (argument?.type === "StringLiteral" && typeof argument.value === "string") {
|
if (argument?.type === "StringLiteral" && typeof argument.value === "string")
|
||||||
reexportSpecifiers.add(argument.value);
|
reexportSpecifiers.add(argument.value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return { commonJsNamedExports: [...names], commonJsReexportSpecifiers: [...reexportSpecifiers] };
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectCommonJsNamedExports(source: string, modulePath: string, visited = new Set<string>()): string[] {
|
||||||
|
let realModulePath = modulePath;
|
||||||
|
try {
|
||||||
|
realModulePath = fs.realpathSync(modulePath);
|
||||||
|
} catch {
|
||||||
|
// The caller's path remains the stable cycle key when realpath fails.
|
||||||
|
}
|
||||||
|
if (visited.has(realModulePath)) return [];
|
||||||
|
visited.add(realModulePath);
|
||||||
|
const analysis = getExtensionSourceAnalysis(source, modulePath);
|
||||||
|
const names = new Set(analysis.commonJsNamedExports);
|
||||||
const nativeRequire = createRequire(modulePath);
|
const nativeRequire = createRequire(modulePath);
|
||||||
for (const specifier of reexportSpecifiers) {
|
for (const specifier of analysis.commonJsReexportSpecifiers) {
|
||||||
try {
|
try {
|
||||||
const resolved = fs.realpathSync(nativeRequire.resolve(specifier));
|
const resolved = fs.realpathSync(nativeRequire.resolve(specifier));
|
||||||
const reexportedSource = rewriteExtensionSpecifiersFromCache(fs.readFileSync(resolved, "utf8"), resolved);
|
const reexportedSource = rewriteExtensionSpecifiersFromCache(fs.readFileSync(resolved, "utf8"), resolved);
|
||||||
for (const name of collectCommonJsNamedExports(reexportedSource, resolved, visited)) {
|
for (const name of collectCommonJsNamedExports(reexportedSource, resolved, visited)) names.add(name);
|
||||||
names.add(name);
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
// Native modules and non-source re-exports do not expose analyzable names.
|
// Native modules and non-source re-exports do not expose analyzable names.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2021,13 +2021,22 @@ export class StatusLineComponent implements Component {
|
|||||||
let percentStart = -1;
|
let percentStart = -1;
|
||||||
let windowStart = -1;
|
let windowStart = -1;
|
||||||
let scaleWidth = gapWidth;
|
let scaleWidth = gapWidth;
|
||||||
|
// >100%: usage anchored past the active window (e.g. model switch to a
|
||||||
|
// smaller window). The bar clamps full, but the embedded label breaks
|
||||||
|
// past the window label — `──200K─120%` with the percent in error color.
|
||||||
|
const percentOverflow = pct > 100;
|
||||||
if (embedContext) {
|
if (embedContext) {
|
||||||
const candidatePercent = formatEmbeddedContextPercent(clampedPct);
|
const candidatePercent = formatEmbeddedContextPercent(percentOverflow ? pct : clampedPct);
|
||||||
const candidateWindow = formatNumber(ctx.contextWindow);
|
const candidateWindow = formatNumber(ctx.contextWindow);
|
||||||
if (gapWidth >= candidatePercent.length + candidateWindow.length + 4) {
|
if (gapWidth >= candidatePercent.length + candidateWindow.length + 4) {
|
||||||
percentLabel = candidatePercent;
|
percentLabel = candidatePercent;
|
||||||
windowLabel = candidateWindow;
|
windowLabel = candidateWindow;
|
||||||
windowStart = gapWidth - windowLabel.length - 1;
|
if (percentOverflow) {
|
||||||
|
percentStart = gapWidth - percentLabel.length;
|
||||||
|
windowStart = percentStart - 1 - windowLabel.length;
|
||||||
|
} else {
|
||||||
|
windowStart = gapWidth - windowLabel.length - 1;
|
||||||
|
}
|
||||||
scaleWidth = windowStart;
|
scaleWidth = windowStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2054,7 +2063,7 @@ export class StatusLineComponent implements Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (percentLabel) {
|
if (percentLabel && percentStart < 0) {
|
||||||
const maxStart = scaleWidth - percentLabel.length - 1;
|
const maxStart = scaleWidth - percentLabel.length - 1;
|
||||||
const preferredStart = Math.min(maxStart, Math.max(1, usedCount));
|
const preferredStart = Math.min(maxStart, Math.max(1, usedCount));
|
||||||
const overlapsBoundary = (start: number): boolean => {
|
const overlapsBoundary = (start: number): boolean => {
|
||||||
@@ -2079,6 +2088,7 @@ export class StatusLineComponent implements Component {
|
|||||||
const speculationGlyph = theme.symbol("context.speculation");
|
const speculationGlyph = theme.symbol("context.speculation");
|
||||||
const thresholdGlyph = theme.symbol("context.compaction");
|
const thresholdGlyph = theme.symbol("context.compaction");
|
||||||
const speculationColor = theme.getFgAnsi("muted");
|
const speculationColor = theme.getFgAnsi("muted");
|
||||||
|
const overflowColor = theme.getFgAnsi("error");
|
||||||
const rawAccentHex = accentHex ?? theme.getColorHex("borderAccent");
|
const rawAccentHex = accentHex ?? theme.getColorHex("borderAccent");
|
||||||
const dimmedAccentHex = adjustHsv(rawAccentHex, { s: 0.7, v: 0.75 });
|
const dimmedAccentHex = adjustHsv(rawAccentHex, { s: 0.7, v: 0.75 });
|
||||||
const thresholdColor = getSessionAccentAnsi(dimmedAccentHex) ?? usedColor;
|
const thresholdColor = getSessionAccentAnsi(dimmedAccentHex) ?? usedColor;
|
||||||
@@ -2089,7 +2099,7 @@ export class StatusLineComponent implements Component {
|
|||||||
let color = i < usedCount ? usedColor : unusedColor;
|
let color = i < usedCount ? usedColor : unusedColor;
|
||||||
let glyph = horizontal;
|
let glyph = horizontal;
|
||||||
if (percentStart >= 0 && i >= percentStart && i < percentStart + percentLabel.length) {
|
if (percentStart >= 0 && i >= percentStart && i < percentStart + percentLabel.length) {
|
||||||
color = usedColor;
|
color = percentOverflow ? overflowColor : usedColor;
|
||||||
glyph = percentLabel.charAt(i - percentStart);
|
glyph = percentLabel.charAt(i - percentStart);
|
||||||
} else if (i === thresholdIdx) {
|
} else if (i === thresholdIdx) {
|
||||||
color = thresholdColor;
|
color = thresholdColor;
|
||||||
|
|||||||
@@ -0,0 +1,421 @@
|
|||||||
|
/**
|
||||||
|
* OTLP provider registration and signal recording for telemetry export.
|
||||||
|
*
|
||||||
|
* Loaded on demand by `./telemetry-export` only when an `OTEL_*` endpoint is
|
||||||
|
* configured — the OTel SDK + OTLP exporter graph costs ~100ms of module
|
||||||
|
* evaluation, so it must stay out of default CLI startup.
|
||||||
|
*
|
||||||
|
* Only the `http/protobuf` transport is supported — an
|
||||||
|
* `OTEL_EXPORTER_OTLP*_PROTOCOL` of `grpc` or `http/json` declines rather than
|
||||||
|
* misrouting protobuf payloads. The exporter line is pinned to the 0.218/2.7
|
||||||
|
* family validated under Bun; the 1.x OTLP line deadlocks when its
|
||||||
|
* `req.on("close")` handler fires after a successful export.
|
||||||
|
*/
|
||||||
|
import type {
|
||||||
|
AgentRunCoverage,
|
||||||
|
AgentRunSummary,
|
||||||
|
AgentTelemetryConfig,
|
||||||
|
AgentTelemetryWarning,
|
||||||
|
ChatUsageEvent,
|
||||||
|
ToolStatus,
|
||||||
|
} from "@oh-my-pi/pi-agent-core";
|
||||||
|
import { logger, postmortem } from "@oh-my-pi/pi-utils";
|
||||||
|
import {
|
||||||
|
type Attributes,
|
||||||
|
type AttributeValue,
|
||||||
|
type Counter,
|
||||||
|
context,
|
||||||
|
type Histogram,
|
||||||
|
type Meter,
|
||||||
|
metrics,
|
||||||
|
} from "@opentelemetry/api";
|
||||||
|
import { type LogAttributes, logs, type Logger as OtelLogger, SeverityNumber } from "@opentelemetry/api-logs";
|
||||||
|
import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
|
||||||
|
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
|
||||||
|
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
|
||||||
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
||||||
|
import { detectResources, envDetector, resourceFromAttributes } from "@opentelemetry/resources";
|
||||||
|
import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
||||||
|
import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
||||||
|
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
||||||
|
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
||||||
|
import type { TelemetrySignalConfig } from "./telemetry-export";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Periodic flush interval. A long-lived `omp` process (the ACP server is
|
||||||
|
* spawned once and reused across many turns) would otherwise hold finished
|
||||||
|
* telemetry until a batch window elapses or the process exits.
|
||||||
|
*/
|
||||||
|
const FLUSH_INTERVAL_MS = 30_000;
|
||||||
|
|
||||||
|
const SERVICE_NAME = "oh-my-pi";
|
||||||
|
|
||||||
|
type OtelLogLevel = "none" | logger.LogLevel;
|
||||||
|
|
||||||
|
const LOG_SEVERITY: Record<logger.LogLevel, SeverityNumber> = {
|
||||||
|
error: SeverityNumber.ERROR,
|
||||||
|
warn: SeverityNumber.WARN,
|
||||||
|
info: SeverityNumber.INFO,
|
||||||
|
debug: SeverityNumber.DEBUG,
|
||||||
|
};
|
||||||
|
|
||||||
|
const LOG_LEVEL_WEIGHT: Record<logger.LogLevel, number> = {
|
||||||
|
error: 0,
|
||||||
|
warn: 1,
|
||||||
|
info: 2,
|
||||||
|
debug: 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TOOL_STATUSES = ["ok", "error", "skipped", "blocked", "timeout", "aborted"] satisfies readonly ToolStatus[];
|
||||||
|
|
||||||
|
let traceProvider: NodeTracerProvider | undefined;
|
||||||
|
let logProvider: LoggerProvider | undefined;
|
||||||
|
let meterProvider: MeterProvider | undefined;
|
||||||
|
let metricRecorder: AgentMetricRecorder | undefined;
|
||||||
|
let otelLogger: OtelLogger | undefined;
|
||||||
|
let unregisterLogSink: (() => void) | undefined;
|
||||||
|
|
||||||
|
/** Whether {@link registerProviders} registered any real OTLP signal provider. */
|
||||||
|
export function isTelemetryExportEnabled(): boolean {
|
||||||
|
if (traceProvider) return true;
|
||||||
|
if (logProvider) return true;
|
||||||
|
if (meterProvider) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge OTLP metrics/log hooks into an existing agent telemetry config.
|
||||||
|
*
|
||||||
|
* The caller still owns content-capture policy, cost estimation, and custom
|
||||||
|
* attributes. This only appends host-level metrics/log forwarding for the
|
||||||
|
* providers registered by {@link registerProviders}.
|
||||||
|
*/
|
||||||
|
export function createTelemetryExportConfig(
|
||||||
|
config: AgentTelemetryConfig | undefined,
|
||||||
|
): AgentTelemetryConfig | undefined {
|
||||||
|
if (!isTelemetryExportEnabled()) return config;
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
onChatUsage: async event => {
|
||||||
|
await config?.onChatUsage?.(event);
|
||||||
|
metricRecorder?.recordChatUsage(event);
|
||||||
|
},
|
||||||
|
onRunEnd: (summary, coverage) => {
|
||||||
|
config?.onRunEnd?.(summary, coverage);
|
||||||
|
metricRecorder?.recordRun(summary, coverage);
|
||||||
|
emitRunSummaryLog(summary, coverage);
|
||||||
|
},
|
||||||
|
onTelemetryWarning: warning => {
|
||||||
|
config?.onTelemetryWarning?.(warning);
|
||||||
|
emitTelemetryWarningLog(warning);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Register global trace/log/meter providers for the enabled signals. */
|
||||||
|
export async function registerProviders(signalConfig: TelemetrySignalConfig): Promise<void> {
|
||||||
|
// `envDetector` parses OTEL_RESOURCE_ATTRIBUTES (percent-decoded, per spec) and
|
||||||
|
// OTEL_SERVICE_NAME; merged last so both take precedence over the fallback
|
||||||
|
// service.name — with OTEL_SERVICE_NAME still winning service.name inside the
|
||||||
|
// detector itself.
|
||||||
|
const resource = resourceFromAttributes({ "service.name": SERVICE_NAME }).merge(
|
||||||
|
detectResources({ detectors: [envDetector] }),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (signalConfig.trace) {
|
||||||
|
const exporter = new OTLPTraceExporter();
|
||||||
|
traceProvider = new NodeTracerProvider({
|
||||||
|
resource,
|
||||||
|
spanProcessors: [new BatchSpanProcessor(exporter)],
|
||||||
|
});
|
||||||
|
traceProvider.register({ contextManager: new AsyncLocalStorageContextManager().enable() });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signalConfig.metric) {
|
||||||
|
const exporter = new OTLPMetricExporter();
|
||||||
|
meterProvider = new MeterProvider({
|
||||||
|
resource,
|
||||||
|
readers: [new PeriodicExportingMetricReader({ exporter })],
|
||||||
|
});
|
||||||
|
metrics.setGlobalMeterProvider(meterProvider);
|
||||||
|
metricRecorder = new AgentMetricRecorder(metrics.getMeter("@oh-my-pi/pi-coding-agent"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signalConfig.log) {
|
||||||
|
const exporter = new OTLPLogExporter();
|
||||||
|
logProvider = new LoggerProvider({
|
||||||
|
resource,
|
||||||
|
processors: [new BatchLogRecordProcessor({ exporter })],
|
||||||
|
});
|
||||||
|
logs.setGlobalLoggerProvider(logProvider);
|
||||||
|
otelLogger = logProvider.getLogger("@oh-my-pi/pi-coding-agent");
|
||||||
|
unregisterLogSink = logger.registerLogSink(event => {
|
||||||
|
emitOtelLog(
|
||||||
|
event.level,
|
||||||
|
event.message,
|
||||||
|
logAttributesFromContext(event.context),
|
||||||
|
"pi.omp.log",
|
||||||
|
event.timestamp,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const flushTimer = setInterval(() => {
|
||||||
|
flushTelemetryExport().catch(() => {});
|
||||||
|
}, FLUSH_INTERVAL_MS);
|
||||||
|
flushTimer.unref();
|
||||||
|
|
||||||
|
postmortem.register("otel-export", async () => {
|
||||||
|
clearInterval(flushTimer);
|
||||||
|
unregisterLogSink?.();
|
||||||
|
unregisterLogSink = undefined;
|
||||||
|
const shutdowns: Promise<void>[] = [];
|
||||||
|
if (traceProvider) shutdowns.push(traceProvider.shutdown());
|
||||||
|
if (logProvider) shutdowns.push(logProvider.shutdown());
|
||||||
|
if (meterProvider) shutdowns.push(meterProvider.shutdown());
|
||||||
|
await Promise.all(shutdowns);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class AgentMetricRecorder {
|
||||||
|
readonly #tokenUsage: Histogram<Attributes>;
|
||||||
|
readonly #chatCostUsd: Counter<Attributes>;
|
||||||
|
readonly #runs: Counter<Attributes>;
|
||||||
|
readonly #steps: Counter<Attributes>;
|
||||||
|
readonly #chatCalls: Counter<Attributes>;
|
||||||
|
readonly #chatDurationMs: Histogram<Attributes>;
|
||||||
|
readonly #toolCalls: Counter<Attributes>;
|
||||||
|
readonly #toolDurationMs: Histogram<Attributes>;
|
||||||
|
readonly #errors: Counter<Attributes>;
|
||||||
|
|
||||||
|
constructor(meter: Meter) {
|
||||||
|
this.#tokenUsage = meter.createHistogram("gen_ai.client.token.usage", {
|
||||||
|
description: "Token usage reported by GenAI chat calls.",
|
||||||
|
unit: "{token}",
|
||||||
|
});
|
||||||
|
this.#chatCostUsd = meter.createCounter("pi.omp.agent.chat.cost.estimated_usd", {
|
||||||
|
description: "Estimated USD cost for completed chat calls.",
|
||||||
|
unit: "USD",
|
||||||
|
});
|
||||||
|
this.#runs = meter.createCounter("pi.omp.agent.runs", {
|
||||||
|
description: "Completed agent runs.",
|
||||||
|
unit: "{run}",
|
||||||
|
});
|
||||||
|
this.#steps = meter.createCounter("pi.omp.agent.steps", {
|
||||||
|
description: "Agent loop steps completed inside a run.",
|
||||||
|
unit: "{step}",
|
||||||
|
});
|
||||||
|
this.#chatCalls = meter.createCounter("pi.omp.agent.chat.calls", {
|
||||||
|
description: "Chat calls completed inside agent runs.",
|
||||||
|
unit: "{call}",
|
||||||
|
});
|
||||||
|
this.#chatDurationMs = meter.createHistogram("pi.omp.agent.chat.duration", {
|
||||||
|
description: "Total chat latency observed in an agent run.",
|
||||||
|
unit: "ms",
|
||||||
|
});
|
||||||
|
this.#toolCalls = meter.createCounter("pi.omp.agent.tool.calls", {
|
||||||
|
description: "Tool calls completed inside agent runs.",
|
||||||
|
unit: "{call}",
|
||||||
|
});
|
||||||
|
this.#toolDurationMs = meter.createHistogram("pi.omp.agent.tool.duration", {
|
||||||
|
description: "Total tool latency observed in an agent run.",
|
||||||
|
unit: "ms",
|
||||||
|
});
|
||||||
|
this.#errors = meter.createCounter("pi.omp.agent.errors", {
|
||||||
|
description: "Errors observed in chat and tool execution.",
|
||||||
|
unit: "{error}",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
recordChatUsage(event: ChatUsageEvent): void {
|
||||||
|
const baseAttrs = metricAttributes({
|
||||||
|
"gen_ai.operation.name": "chat",
|
||||||
|
"gen_ai.provider.name": event.provider,
|
||||||
|
"gen_ai.request.model": event.model,
|
||||||
|
"gen_ai.response.service_tier": event.serviceTier,
|
||||||
|
"pi.gen_ai.agent.id": event.agent?.id,
|
||||||
|
"pi.gen_ai.agent.name": event.agent?.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#recordToken(event.usage.inputTokens, baseAttrs, "input");
|
||||||
|
this.#recordToken(event.usage.outputTokens, baseAttrs, "output");
|
||||||
|
this.#recordToken(event.usage.totalTokens, baseAttrs, "total");
|
||||||
|
this.#recordToken(event.usage.cachedInputTokens, baseAttrs, "cache_read_input");
|
||||||
|
this.#recordToken(event.usage.cacheWriteTokens, baseAttrs, "cache_write_input");
|
||||||
|
this.#recordToken(event.usage.reasoningOutputTokens, baseAttrs, "reasoning_output");
|
||||||
|
|
||||||
|
if (event.cost && "usd" in event.cost && event.cost.usd > 0) {
|
||||||
|
this.#chatCostUsd.add(event.cost.usd, baseAttrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
recordRun(summary: AgentRunSummary, coverage: AgentRunCoverage): void {
|
||||||
|
const runAttrs = metricAttributes({
|
||||||
|
"pi.omp.agent.models_used.count": coverage.modelsUsed.length,
|
||||||
|
"pi.omp.agent.providers_used.count": coverage.providersUsed.length,
|
||||||
|
"pi.omp.agent.tools_available.count": coverage.toolsAvailable.length,
|
||||||
|
"pi.omp.agent.tools_invoked.count": coverage.toolsInvoked.length,
|
||||||
|
"pi.omp.agent.tools_unused.count": coverage.toolsUnused.length,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#runs.add(1, runAttrs);
|
||||||
|
if (summary.stepCount > 0) this.#steps.add(summary.stepCount, runAttrs);
|
||||||
|
if (summary.chats.totalLatencyMs > 0) this.#chatDurationMs.record(summary.chats.totalLatencyMs, runAttrs);
|
||||||
|
|
||||||
|
for (const reason in summary.chats.byStopReason) {
|
||||||
|
const count = summary.chats.byStopReason[reason];
|
||||||
|
if (count > 0)
|
||||||
|
this.#chatCalls.add(count, metricAttributes({ ...runAttrs, "gen_ai.response.finish_reason": reason }));
|
||||||
|
}
|
||||||
|
for (const toolName in summary.tools.byName) {
|
||||||
|
const counters = summary.tools.byName[toolName];
|
||||||
|
const toolAttrs = metricAttributes({ ...runAttrs, "gen_ai.tool.name": toolName });
|
||||||
|
if (counters.totalLatencyMs > 0) this.#toolDurationMs.record(counters.totalLatencyMs, toolAttrs);
|
||||||
|
for (const status of TOOL_STATUSES) {
|
||||||
|
const count = counters[status];
|
||||||
|
if (count > 0) this.#toolCalls.add(count, metricAttributes({ ...toolAttrs, "pi.omp.tool.status": status }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const errorType in summary.errors.byType) {
|
||||||
|
const count = summary.errors.byType[errorType];
|
||||||
|
if (count > 0) this.#errors.add(count, metricAttributes({ ...runAttrs, "error.type": errorType }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#recordToken(value: number | undefined, baseAttrs: Attributes, tokenType: string): void {
|
||||||
|
if (!value || value <= 0) return;
|
||||||
|
this.#tokenUsage.record(value, metricAttributes({ ...baseAttrs, "gen_ai.token.type": tokenType }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function metricAttributes(fields: Readonly<Record<string, unknown>>): Attributes {
|
||||||
|
const out: Attributes = {};
|
||||||
|
for (const key in fields) {
|
||||||
|
const value = fields[key];
|
||||||
|
if (value === undefined || value === null) continue;
|
||||||
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
||||||
|
out[key] = value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const text = String(value);
|
||||||
|
if (text.length > 0) out[key] = text;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitRunSummaryLog(summary: AgentRunSummary, coverage: AgentRunCoverage): void {
|
||||||
|
emitOtelLog(
|
||||||
|
"info",
|
||||||
|
"agent run completed",
|
||||||
|
{
|
||||||
|
"pi.omp.agent.step_count": summary.stepCount,
|
||||||
|
"pi.omp.agent.chats.total": summary.chats.total,
|
||||||
|
"pi.omp.agent.chats.total_latency_ms": summary.chats.totalLatencyMs,
|
||||||
|
"pi.omp.agent.tools.total": summary.tools.total,
|
||||||
|
"pi.omp.agent.tools.ok": summary.tools.ok,
|
||||||
|
"pi.omp.agent.tools.error": summary.tools.error,
|
||||||
|
"pi.omp.agent.tools.skipped": summary.tools.skipped,
|
||||||
|
"pi.omp.agent.tools.blocked": summary.tools.blocked,
|
||||||
|
"pi.omp.agent.tools.timeout": summary.tools.timeout,
|
||||||
|
"pi.omp.agent.tools.aborted": summary.tools.aborted,
|
||||||
|
"pi.omp.agent.tools.total_latency_ms": summary.tools.totalLatencyMs,
|
||||||
|
"pi.omp.agent.usage.input_tokens": summary.usage.inputTokens,
|
||||||
|
"pi.omp.agent.usage.output_tokens": summary.usage.outputTokens,
|
||||||
|
"pi.omp.agent.usage.cached_input_tokens": summary.usage.cachedInputTokens,
|
||||||
|
"pi.omp.agent.usage.cache_write_tokens": summary.usage.cacheWriteTokens,
|
||||||
|
"pi.omp.agent.usage.reasoning_output_tokens": summary.usage.reasoningOutputTokens,
|
||||||
|
"pi.omp.agent.usage.total_tokens": summary.usage.totalTokens,
|
||||||
|
"pi.omp.agent.cost.estimated_usd": summary.cost.estimatedUsd,
|
||||||
|
"pi.omp.agent.cost.unavailable_reasons": summary.cost.unavailableReasons.join(","),
|
||||||
|
"pi.omp.agent.errors.total": summary.errors.total,
|
||||||
|
"pi.omp.agent.coverage.tools_available": coverage.toolsAvailable.join(","),
|
||||||
|
"pi.omp.agent.coverage.tools_invoked": coverage.toolsInvoked.join(","),
|
||||||
|
"pi.omp.agent.coverage.tools_unused": coverage.toolsUnused.join(","),
|
||||||
|
"pi.omp.agent.coverage.models_used": coverage.modelsUsed.join(","),
|
||||||
|
"pi.omp.agent.coverage.providers_used": coverage.providersUsed.join(","),
|
||||||
|
},
|
||||||
|
"pi.omp.agent.run.completed",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitTelemetryWarningLog(warning: AgentTelemetryWarning): void {
|
||||||
|
const attrs = logAttributesFromContext({
|
||||||
|
code: warning.code,
|
||||||
|
error: warning.error,
|
||||||
|
});
|
||||||
|
emitOtelLog("warn", warning.message, attrs, "pi.omp.telemetry.warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitOtelLog(
|
||||||
|
level: logger.LogLevel,
|
||||||
|
body: string,
|
||||||
|
attributes: LogAttributes,
|
||||||
|
eventName: string,
|
||||||
|
timestamp = new Date(),
|
||||||
|
): void {
|
||||||
|
if (!otelLogger) return;
|
||||||
|
const minLevel = parseOtelLogLevel(process.env.OTEL_LOG_LEVEL);
|
||||||
|
if (minLevel === "none") return;
|
||||||
|
if (LOG_LEVEL_WEIGHT[level] > LOG_LEVEL_WEIGHT[minLevel]) return;
|
||||||
|
otelLogger.emit({
|
||||||
|
eventName,
|
||||||
|
timestamp,
|
||||||
|
observedTimestamp: new Date(),
|
||||||
|
severityNumber: LOG_SEVERITY[level],
|
||||||
|
severityText: level.toUpperCase(),
|
||||||
|
body,
|
||||||
|
attributes,
|
||||||
|
context: context.active(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseOtelLogLevel(raw: string | undefined): OtelLogLevel {
|
||||||
|
if (!raw) return "info";
|
||||||
|
switch (raw.trim().toLowerCase()) {
|
||||||
|
case "none":
|
||||||
|
return "none";
|
||||||
|
case "error":
|
||||||
|
return "error";
|
||||||
|
case "warn":
|
||||||
|
case "warning":
|
||||||
|
return "warn";
|
||||||
|
case "debug":
|
||||||
|
return "debug";
|
||||||
|
default:
|
||||||
|
return "info";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function logAttributesFromContext(input: Record<string, unknown> | undefined): LogAttributes {
|
||||||
|
const out: LogAttributes = { "process.pid": process.pid };
|
||||||
|
if (!input) return out;
|
||||||
|
for (const key in input) {
|
||||||
|
const attr = logAttributeValue(input[key]);
|
||||||
|
if (attr !== undefined) out[key] = attr;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logAttributeValue(value: unknown): AttributeValue | undefined {
|
||||||
|
if (value === undefined || value === null) return undefined;
|
||||||
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
||||||
|
if (value instanceof Error) {
|
||||||
|
return `${value.name}: ${value.message}`;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const text = JSON.stringify(value);
|
||||||
|
if (text && text.length > 0) return text;
|
||||||
|
} catch {
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Flush buffered spans, log records, and metrics across all registered providers. */
|
||||||
|
export async function flushTelemetryExport(): Promise<void> {
|
||||||
|
const flushes: Promise<void>[] = [];
|
||||||
|
if (traceProvider) flushes.push(traceProvider.forceFlush());
|
||||||
|
if (logProvider) flushes.push(logProvider.forceFlush());
|
||||||
|
if (meterProvider) flushes.push(meterProvider.forceFlush());
|
||||||
|
await Promise.all(flushes);
|
||||||
|
}
|
||||||
@@ -3,86 +3,37 @@
|
|||||||
*
|
*
|
||||||
* oh-my-pi's agent core (`@oh-my-pi/pi-agent-core`) emits OpenTelemetry GenAI
|
* oh-my-pi's agent core (`@oh-my-pi/pi-agent-core`) emits OpenTelemetry GenAI
|
||||||
* spans through the global `@opentelemetry/api` tracer, and exposes run-level
|
* spans through the global `@opentelemetry/api` tracer, and exposes run-level
|
||||||
* callbacks for metrics/log pipelines. This module registers the OTLP/proto
|
* callbacks for metrics/log pipelines. This module resolves the standard
|
||||||
* trace, log, and metric SDK providers when the standard `OTEL_*` endpoint env
|
* `OTEL_*` env contract (endpoint, exporter selection, protocol,
|
||||||
* vars are set so `omp` can be observed by any OTLP collector without vendor
|
* `OTEL_SDK_DISABLED`) and, only when at least one signal has an OTLP endpoint,
|
||||||
* coupling.
|
* loads `./telemetry-export-otlp` to register the trace/log/metric providers —
|
||||||
|
* keeping the OTel SDK + exporter module graph (~100ms) out of default startup.
|
||||||
*
|
*
|
||||||
* Only the `http/protobuf` transport is supported — an
|
* Only the `http/protobuf` transport is supported — an
|
||||||
* `OTEL_EXPORTER_OTLP*_PROTOCOL` of `grpc` or `http/json` declines rather than
|
* `OTEL_EXPORTER_OTLP*_PROTOCOL` of `grpc` or `http/json` declines rather than
|
||||||
* misrouting protobuf payloads. The exporter line is pinned to the 0.218/2.7
|
* misrouting protobuf payloads.
|
||||||
* family validated under Bun; the 1.x OTLP line deadlocks when its
|
|
||||||
* `req.on("close")` handler fires after a successful export.
|
|
||||||
*/
|
*/
|
||||||
import type {
|
import type { AgentTelemetryConfig } from "@oh-my-pi/pi-agent-core";
|
||||||
AgentRunCoverage,
|
import { logger } from "@oh-my-pi/pi-utils";
|
||||||
AgentRunSummary,
|
|
||||||
AgentTelemetryConfig,
|
|
||||||
AgentTelemetryWarning,
|
|
||||||
ChatUsageEvent,
|
|
||||||
ToolStatus,
|
|
||||||
} from "@oh-my-pi/pi-agent-core";
|
|
||||||
import { logger, postmortem } from "@oh-my-pi/pi-utils";
|
|
||||||
import {
|
|
||||||
type Attributes,
|
|
||||||
type AttributeValue,
|
|
||||||
type Counter,
|
|
||||||
context,
|
|
||||||
type Histogram,
|
|
||||||
type Meter,
|
|
||||||
metrics,
|
|
||||||
} from "@opentelemetry/api";
|
|
||||||
import { type LogAttributes, logs, type Logger as OtelLogger, SeverityNumber } from "@opentelemetry/api-logs";
|
|
||||||
import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
|
|
||||||
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-proto";
|
|
||||||
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
|
|
||||||
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
||||||
import { detectResources, envDetector, resourceFromAttributes } from "@opentelemetry/resources";
|
|
||||||
import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
||||||
import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
||||||
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
||||||
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
||||||
|
|
||||||
/**
|
/** Per-signal OTLP export toggles resolved from the `OTEL_*` env contract. */
|
||||||
* Periodic flush interval. A long-lived `omp` process (the ACP server is
|
export interface TelemetrySignalConfig {
|
||||||
* spawned once and reused across many turns) would otherwise hold finished
|
|
||||||
* telemetry until a batch window elapses or the process exits.
|
|
||||||
*/
|
|
||||||
const FLUSH_INTERVAL_MS = 30_000;
|
|
||||||
|
|
||||||
const SERVICE_NAME = "oh-my-pi";
|
|
||||||
|
|
||||||
type TelemetrySignal = "trace" | "log" | "metric";
|
|
||||||
type OtelLogLevel = "none" | logger.LogLevel;
|
|
||||||
|
|
||||||
interface SignalConfig {
|
|
||||||
readonly trace: boolean;
|
readonly trace: boolean;
|
||||||
readonly log: boolean;
|
readonly log: boolean;
|
||||||
readonly metric: boolean;
|
readonly metric: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LOG_SEVERITY: Record<logger.LogLevel, SeverityNumber> = {
|
type TelemetrySignal = "trace" | "log" | "metric";
|
||||||
error: SeverityNumber.ERROR,
|
|
||||||
warn: SeverityNumber.WARN,
|
|
||||||
info: SeverityNumber.INFO,
|
|
||||||
debug: SeverityNumber.DEBUG,
|
|
||||||
};
|
|
||||||
|
|
||||||
const LOG_LEVEL_WEIGHT: Record<logger.LogLevel, number> = {
|
/** Loaded OTLP implementation module; `undefined` until a signal registers. */
|
||||||
error: 0,
|
interface OtlpExportModule {
|
||||||
warn: 1,
|
registerProviders(signalConfig: TelemetrySignalConfig): Promise<void>;
|
||||||
info: 2,
|
isTelemetryExportEnabled(): boolean;
|
||||||
debug: 3,
|
createTelemetryExportConfig(config: AgentTelemetryConfig | undefined): AgentTelemetryConfig | undefined;
|
||||||
};
|
flushTelemetryExport(): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
const TOOL_STATUSES = ["ok", "error", "skipped", "blocked", "timeout", "aborted"] satisfies readonly ToolStatus[];
|
let otlp: OtlpExportModule | undefined;
|
||||||
|
|
||||||
let traceProvider: NodeTracerProvider | undefined;
|
|
||||||
let logProvider: LoggerProvider | undefined;
|
|
||||||
let meterProvider: MeterProvider | undefined;
|
|
||||||
let metricRecorder: AgentMetricRecorder | undefined;
|
|
||||||
let otelLogger: OtelLogger | undefined;
|
|
||||||
let unregisterLogSink: (() => void) | undefined;
|
|
||||||
let initPromise: Promise<void> | undefined;
|
let initPromise: Promise<void> | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,10 +43,7 @@ let initPromise: Promise<void> | undefined;
|
|||||||
* disabled.
|
* disabled.
|
||||||
*/
|
*/
|
||||||
export function isTelemetryExportEnabled(): boolean {
|
export function isTelemetryExportEnabled(): boolean {
|
||||||
if (traceProvider) return true;
|
return otlp?.isTelemetryExportEnabled() ?? false;
|
||||||
if (logProvider) return true;
|
|
||||||
if (meterProvider) return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,28 +51,13 @@ export function isTelemetryExportEnabled(): boolean {
|
|||||||
*
|
*
|
||||||
* The caller still owns content-capture policy, cost estimation, and custom
|
* The caller still owns content-capture policy, cost estimation, and custom
|
||||||
* attributes. This only appends host-level metrics/log forwarding for the
|
* attributes. This only appends host-level metrics/log forwarding for the
|
||||||
* providers registered by {@link initTelemetryExport}.
|
* providers registered by {@link initTelemetryExport}; a passthrough when
|
||||||
|
* export is disabled.
|
||||||
*/
|
*/
|
||||||
export function createTelemetryExportConfig(
|
export function createTelemetryExportConfig(
|
||||||
config: AgentTelemetryConfig | undefined,
|
config: AgentTelemetryConfig | undefined,
|
||||||
): AgentTelemetryConfig | undefined {
|
): AgentTelemetryConfig | undefined {
|
||||||
if (!isTelemetryExportEnabled()) return config;
|
return otlp ? otlp.createTelemetryExportConfig(config) : config;
|
||||||
return {
|
|
||||||
...config,
|
|
||||||
onChatUsage: async event => {
|
|
||||||
await config?.onChatUsage?.(event);
|
|
||||||
metricRecorder?.recordChatUsage(event);
|
|
||||||
},
|
|
||||||
onRunEnd: (summary, coverage) => {
|
|
||||||
config?.onRunEnd?.(summary, coverage);
|
|
||||||
metricRecorder?.recordRun(summary, coverage);
|
|
||||||
emitRunSummaryLog(summary, coverage);
|
|
||||||
},
|
|
||||||
onTelemetryWarning: warning => {
|
|
||||||
config?.onTelemetryWarning?.(warning);
|
|
||||||
emitTelemetryWarningLog(warning);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,7 +66,6 @@ export function createTelemetryExportConfig(
|
|||||||
* the OTEL kill-switches are engaged), so startup can call it unconditionally.
|
* the OTEL kill-switches are engaged), so startup can call it unconditionally.
|
||||||
*/
|
*/
|
||||||
export async function initTelemetryExport(): Promise<void> {
|
export async function initTelemetryExport(): Promise<void> {
|
||||||
if (isTelemetryExportEnabled()) return;
|
|
||||||
if (initPromise) return initPromise;
|
if (initPromise) return initPromise;
|
||||||
|
|
||||||
if (process.env.OTEL_SDK_DISABLED?.trim().toLowerCase() === "true") return;
|
if (process.env.OTEL_SDK_DISABLED?.trim().toLowerCase() === "true") return;
|
||||||
@@ -141,76 +73,26 @@ export async function initTelemetryExport(): Promise<void> {
|
|||||||
const signalConfig = resolveSignalConfig();
|
const signalConfig = resolveSignalConfig();
|
||||||
if (!signalConfig.trace && !signalConfig.log && !signalConfig.metric) return;
|
if (!signalConfig.trace && !signalConfig.log && !signalConfig.metric) return;
|
||||||
|
|
||||||
initPromise = registerProviders(signalConfig);
|
initPromise = (async () => {
|
||||||
|
// Branch-only: the OTel SDK + OTLP exporter graph loads only when an endpoint is configured.
|
||||||
|
const impl: OtlpExportModule = await import("./telemetry-export-otlp");
|
||||||
|
await impl.registerProviders(signalConfig);
|
||||||
|
otlp = impl;
|
||||||
|
})();
|
||||||
return initPromise;
|
return initPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function registerProviders(signalConfig: SignalConfig): Promise<void> {
|
/**
|
||||||
// `envDetector` parses OTEL_RESOURCE_ATTRIBUTES (percent-decoded, per spec) and
|
* Flush buffered spans, log records, and metrics. No-op when export is disabled.
|
||||||
// OTEL_SERVICE_NAME; merged last so both take precedence over the fallback
|
* Hosts embedding the agent can call this at natural boundaries (e.g. the end
|
||||||
// service.name — with OTEL_SERVICE_NAME still winning service.name inside the
|
* of a turn) so telemetry surfaces promptly rather than on the batch interval.
|
||||||
// detector itself.
|
*/
|
||||||
const resource = resourceFromAttributes({ "service.name": SERVICE_NAME }).merge(
|
export async function flushTelemetryExport(): Promise<void> {
|
||||||
detectResources({ detectors: [envDetector] }),
|
if (otlp) await otlp.flushTelemetryExport();
|
||||||
);
|
|
||||||
|
|
||||||
if (signalConfig.trace) {
|
|
||||||
const exporter = new OTLPTraceExporter();
|
|
||||||
traceProvider = new NodeTracerProvider({
|
|
||||||
resource,
|
|
||||||
spanProcessors: [new BatchSpanProcessor(exporter)],
|
|
||||||
});
|
|
||||||
traceProvider.register({ contextManager: new AsyncLocalStorageContextManager().enable() });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signalConfig.metric) {
|
|
||||||
const exporter = new OTLPMetricExporter();
|
|
||||||
meterProvider = new MeterProvider({
|
|
||||||
resource,
|
|
||||||
readers: [new PeriodicExportingMetricReader({ exporter })],
|
|
||||||
});
|
|
||||||
metrics.setGlobalMeterProvider(meterProvider);
|
|
||||||
metricRecorder = new AgentMetricRecorder(metrics.getMeter("@oh-my-pi/pi-coding-agent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signalConfig.log) {
|
|
||||||
const exporter = new OTLPLogExporter();
|
|
||||||
logProvider = new LoggerProvider({
|
|
||||||
resource,
|
|
||||||
processors: [new BatchLogRecordProcessor({ exporter })],
|
|
||||||
});
|
|
||||||
logs.setGlobalLoggerProvider(logProvider);
|
|
||||||
otelLogger = logProvider.getLogger("@oh-my-pi/pi-coding-agent");
|
|
||||||
unregisterLogSink = logger.registerLogSink(event => {
|
|
||||||
emitOtelLog(
|
|
||||||
event.level,
|
|
||||||
event.message,
|
|
||||||
logAttributesFromContext(event.context),
|
|
||||||
"pi.omp.log",
|
|
||||||
event.timestamp,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const flushTimer = setInterval(() => {
|
|
||||||
flushTelemetryExport().catch(() => {});
|
|
||||||
}, FLUSH_INTERVAL_MS);
|
|
||||||
flushTimer.unref();
|
|
||||||
|
|
||||||
postmortem.register("otel-export", async () => {
|
|
||||||
clearInterval(flushTimer);
|
|
||||||
unregisterLogSink?.();
|
|
||||||
unregisterLogSink = undefined;
|
|
||||||
const shutdowns: Promise<void>[] = [];
|
|
||||||
if (traceProvider) shutdowns.push(traceProvider.shutdown());
|
|
||||||
if (logProvider) shutdowns.push(logProvider.shutdown());
|
|
||||||
if (meterProvider) shutdowns.push(meterProvider.shutdown());
|
|
||||||
await Promise.all(shutdowns);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveSignalConfig(): SignalConfig {
|
function resolveSignalConfig(): TelemetrySignalConfig {
|
||||||
const signalConfig: SignalConfig = {
|
return {
|
||||||
trace: signalEnabled(
|
trace: signalEnabled(
|
||||||
"trace",
|
"trace",
|
||||||
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ?? process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
||||||
@@ -230,7 +112,6 @@ function resolveSignalConfig(): SignalConfig {
|
|||||||
process.env.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL ?? process.env.OTEL_EXPORTER_OTLP_PROTOCOL,
|
process.env.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL ?? process.env.OTEL_EXPORTER_OTLP_PROTOCOL,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
return signalConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function signalEnabled(
|
function signalEnabled(
|
||||||
@@ -255,250 +136,3 @@ function signalEnabled(
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AgentMetricRecorder {
|
|
||||||
readonly #tokenUsage: Histogram<Attributes>;
|
|
||||||
readonly #chatCostUsd: Counter<Attributes>;
|
|
||||||
readonly #runs: Counter<Attributes>;
|
|
||||||
readonly #steps: Counter<Attributes>;
|
|
||||||
readonly #chatCalls: Counter<Attributes>;
|
|
||||||
readonly #chatDurationMs: Histogram<Attributes>;
|
|
||||||
readonly #toolCalls: Counter<Attributes>;
|
|
||||||
readonly #toolDurationMs: Histogram<Attributes>;
|
|
||||||
readonly #errors: Counter<Attributes>;
|
|
||||||
|
|
||||||
constructor(meter: Meter) {
|
|
||||||
this.#tokenUsage = meter.createHistogram("gen_ai.client.token.usage", {
|
|
||||||
description: "Token usage reported by GenAI chat calls.",
|
|
||||||
unit: "{token}",
|
|
||||||
});
|
|
||||||
this.#chatCostUsd = meter.createCounter("pi.omp.agent.chat.cost.estimated_usd", {
|
|
||||||
description: "Estimated USD cost for completed chat calls.",
|
|
||||||
unit: "USD",
|
|
||||||
});
|
|
||||||
this.#runs = meter.createCounter("pi.omp.agent.runs", {
|
|
||||||
description: "Completed agent runs.",
|
|
||||||
unit: "{run}",
|
|
||||||
});
|
|
||||||
this.#steps = meter.createCounter("pi.omp.agent.steps", {
|
|
||||||
description: "Agent loop steps completed inside a run.",
|
|
||||||
unit: "{step}",
|
|
||||||
});
|
|
||||||
this.#chatCalls = meter.createCounter("pi.omp.agent.chat.calls", {
|
|
||||||
description: "Chat calls completed inside agent runs.",
|
|
||||||
unit: "{call}",
|
|
||||||
});
|
|
||||||
this.#chatDurationMs = meter.createHistogram("pi.omp.agent.chat.duration", {
|
|
||||||
description: "Total chat latency observed in an agent run.",
|
|
||||||
unit: "ms",
|
|
||||||
});
|
|
||||||
this.#toolCalls = meter.createCounter("pi.omp.agent.tool.calls", {
|
|
||||||
description: "Tool calls completed inside agent runs.",
|
|
||||||
unit: "{call}",
|
|
||||||
});
|
|
||||||
this.#toolDurationMs = meter.createHistogram("pi.omp.agent.tool.duration", {
|
|
||||||
description: "Total tool latency observed in an agent run.",
|
|
||||||
unit: "ms",
|
|
||||||
});
|
|
||||||
this.#errors = meter.createCounter("pi.omp.agent.errors", {
|
|
||||||
description: "Errors observed in chat and tool execution.",
|
|
||||||
unit: "{error}",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
recordChatUsage(event: ChatUsageEvent): void {
|
|
||||||
const baseAttrs = metricAttributes({
|
|
||||||
"gen_ai.operation.name": "chat",
|
|
||||||
"gen_ai.provider.name": event.provider,
|
|
||||||
"gen_ai.request.model": event.model,
|
|
||||||
"gen_ai.response.service_tier": event.serviceTier,
|
|
||||||
"pi.gen_ai.agent.id": event.agent?.id,
|
|
||||||
"pi.gen_ai.agent.name": event.agent?.name,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.#recordToken(event.usage.inputTokens, baseAttrs, "input");
|
|
||||||
this.#recordToken(event.usage.outputTokens, baseAttrs, "output");
|
|
||||||
this.#recordToken(event.usage.totalTokens, baseAttrs, "total");
|
|
||||||
this.#recordToken(event.usage.cachedInputTokens, baseAttrs, "cache_read_input");
|
|
||||||
this.#recordToken(event.usage.cacheWriteTokens, baseAttrs, "cache_write_input");
|
|
||||||
this.#recordToken(event.usage.reasoningOutputTokens, baseAttrs, "reasoning_output");
|
|
||||||
|
|
||||||
if (event.cost && "usd" in event.cost && event.cost.usd > 0) {
|
|
||||||
this.#chatCostUsd.add(event.cost.usd, baseAttrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
recordRun(summary: AgentRunSummary, coverage: AgentRunCoverage): void {
|
|
||||||
const runAttrs = metricAttributes({
|
|
||||||
"pi.omp.agent.models_used.count": coverage.modelsUsed.length,
|
|
||||||
"pi.omp.agent.providers_used.count": coverage.providersUsed.length,
|
|
||||||
"pi.omp.agent.tools_available.count": coverage.toolsAvailable.length,
|
|
||||||
"pi.omp.agent.tools_invoked.count": coverage.toolsInvoked.length,
|
|
||||||
"pi.omp.agent.tools_unused.count": coverage.toolsUnused.length,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.#runs.add(1, runAttrs);
|
|
||||||
if (summary.stepCount > 0) this.#steps.add(summary.stepCount, runAttrs);
|
|
||||||
if (summary.chats.totalLatencyMs > 0) this.#chatDurationMs.record(summary.chats.totalLatencyMs, runAttrs);
|
|
||||||
|
|
||||||
for (const reason in summary.chats.byStopReason) {
|
|
||||||
const count = summary.chats.byStopReason[reason];
|
|
||||||
if (count > 0)
|
|
||||||
this.#chatCalls.add(count, metricAttributes({ ...runAttrs, "gen_ai.response.finish_reason": reason }));
|
|
||||||
}
|
|
||||||
for (const toolName in summary.tools.byName) {
|
|
||||||
const counters = summary.tools.byName[toolName];
|
|
||||||
const toolAttrs = metricAttributes({ ...runAttrs, "gen_ai.tool.name": toolName });
|
|
||||||
if (counters.totalLatencyMs > 0) this.#toolDurationMs.record(counters.totalLatencyMs, toolAttrs);
|
|
||||||
for (const status of TOOL_STATUSES) {
|
|
||||||
const count = counters[status];
|
|
||||||
if (count > 0) this.#toolCalls.add(count, metricAttributes({ ...toolAttrs, "pi.omp.tool.status": status }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const errorType in summary.errors.byType) {
|
|
||||||
const count = summary.errors.byType[errorType];
|
|
||||||
if (count > 0) this.#errors.add(count, metricAttributes({ ...runAttrs, "error.type": errorType }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#recordToken(value: number | undefined, baseAttrs: Attributes, tokenType: string): void {
|
|
||||||
if (!value || value <= 0) return;
|
|
||||||
this.#tokenUsage.record(value, metricAttributes({ ...baseAttrs, "gen_ai.token.type": tokenType }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function metricAttributes(fields: Readonly<Record<string, unknown>>): Attributes {
|
|
||||||
const out: Attributes = {};
|
|
||||||
for (const key in fields) {
|
|
||||||
const value = fields[key];
|
|
||||||
if (value === undefined || value === null) continue;
|
|
||||||
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
||||||
out[key] = value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const text = String(value);
|
|
||||||
if (text.length > 0) out[key] = text;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitRunSummaryLog(summary: AgentRunSummary, coverage: AgentRunCoverage): void {
|
|
||||||
emitOtelLog(
|
|
||||||
"info",
|
|
||||||
"agent run completed",
|
|
||||||
{
|
|
||||||
"pi.omp.agent.step_count": summary.stepCount,
|
|
||||||
"pi.omp.agent.chats.total": summary.chats.total,
|
|
||||||
"pi.omp.agent.chats.total_latency_ms": summary.chats.totalLatencyMs,
|
|
||||||
"pi.omp.agent.tools.total": summary.tools.total,
|
|
||||||
"pi.omp.agent.tools.ok": summary.tools.ok,
|
|
||||||
"pi.omp.agent.tools.error": summary.tools.error,
|
|
||||||
"pi.omp.agent.tools.skipped": summary.tools.skipped,
|
|
||||||
"pi.omp.agent.tools.blocked": summary.tools.blocked,
|
|
||||||
"pi.omp.agent.tools.timeout": summary.tools.timeout,
|
|
||||||
"pi.omp.agent.tools.aborted": summary.tools.aborted,
|
|
||||||
"pi.omp.agent.tools.total_latency_ms": summary.tools.totalLatencyMs,
|
|
||||||
"pi.omp.agent.usage.input_tokens": summary.usage.inputTokens,
|
|
||||||
"pi.omp.agent.usage.output_tokens": summary.usage.outputTokens,
|
|
||||||
"pi.omp.agent.usage.cached_input_tokens": summary.usage.cachedInputTokens,
|
|
||||||
"pi.omp.agent.usage.cache_write_tokens": summary.usage.cacheWriteTokens,
|
|
||||||
"pi.omp.agent.usage.reasoning_output_tokens": summary.usage.reasoningOutputTokens,
|
|
||||||
"pi.omp.agent.usage.total_tokens": summary.usage.totalTokens,
|
|
||||||
"pi.omp.agent.cost.estimated_usd": summary.cost.estimatedUsd,
|
|
||||||
"pi.omp.agent.cost.unavailable_reasons": summary.cost.unavailableReasons.join(","),
|
|
||||||
"pi.omp.agent.errors.total": summary.errors.total,
|
|
||||||
"pi.omp.agent.coverage.tools_available": coverage.toolsAvailable.join(","),
|
|
||||||
"pi.omp.agent.coverage.tools_invoked": coverage.toolsInvoked.join(","),
|
|
||||||
"pi.omp.agent.coverage.tools_unused": coverage.toolsUnused.join(","),
|
|
||||||
"pi.omp.agent.coverage.models_used": coverage.modelsUsed.join(","),
|
|
||||||
"pi.omp.agent.coverage.providers_used": coverage.providersUsed.join(","),
|
|
||||||
},
|
|
||||||
"pi.omp.agent.run.completed",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitTelemetryWarningLog(warning: AgentTelemetryWarning): void {
|
|
||||||
const attrs = logAttributesFromContext({
|
|
||||||
code: warning.code,
|
|
||||||
error: warning.error,
|
|
||||||
});
|
|
||||||
emitOtelLog("warn", warning.message, attrs, "pi.omp.telemetry.warning");
|
|
||||||
}
|
|
||||||
|
|
||||||
function emitOtelLog(
|
|
||||||
level: logger.LogLevel,
|
|
||||||
body: string,
|
|
||||||
attributes: LogAttributes,
|
|
||||||
eventName: string,
|
|
||||||
timestamp = new Date(),
|
|
||||||
): void {
|
|
||||||
if (!otelLogger) return;
|
|
||||||
const minLevel = parseOtelLogLevel(process.env.OTEL_LOG_LEVEL);
|
|
||||||
if (minLevel === "none") return;
|
|
||||||
if (LOG_LEVEL_WEIGHT[level] > LOG_LEVEL_WEIGHT[minLevel]) return;
|
|
||||||
otelLogger.emit({
|
|
||||||
eventName,
|
|
||||||
timestamp,
|
|
||||||
observedTimestamp: new Date(),
|
|
||||||
severityNumber: LOG_SEVERITY[level],
|
|
||||||
severityText: level.toUpperCase(),
|
|
||||||
body,
|
|
||||||
attributes,
|
|
||||||
context: context.active(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseOtelLogLevel(raw: string | undefined): OtelLogLevel {
|
|
||||||
if (!raw) return "info";
|
|
||||||
switch (raw.trim().toLowerCase()) {
|
|
||||||
case "none":
|
|
||||||
return "none";
|
|
||||||
case "error":
|
|
||||||
return "error";
|
|
||||||
case "warn":
|
|
||||||
case "warning":
|
|
||||||
return "warn";
|
|
||||||
case "debug":
|
|
||||||
return "debug";
|
|
||||||
default:
|
|
||||||
return "info";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function logAttributesFromContext(input: Record<string, unknown> | undefined): LogAttributes {
|
|
||||||
const out: LogAttributes = { "process.pid": process.pid };
|
|
||||||
if (!input) return out;
|
|
||||||
for (const key in input) {
|
|
||||||
const attr = logAttributeValue(input[key]);
|
|
||||||
if (attr !== undefined) out[key] = attr;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function logAttributeValue(value: unknown): AttributeValue | undefined {
|
|
||||||
if (value === undefined || value === null) return undefined;
|
|
||||||
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
|
||||||
if (value instanceof Error) {
|
|
||||||
return `${value.name}: ${value.message}`;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const text = JSON.stringify(value);
|
|
||||||
if (text && text.length > 0) return text;
|
|
||||||
} catch {
|
|
||||||
return String(value);
|
|
||||||
}
|
|
||||||
return String(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush buffered spans, log records, and metrics. No-op when export is disabled.
|
|
||||||
* Hosts embedding the agent can call this at natural boundaries (e.g. the end
|
|
||||||
* of a turn) so telemetry surfaces promptly rather than on the batch interval.
|
|
||||||
*/
|
|
||||||
export async function flushTelemetryExport(): Promise<void> {
|
|
||||||
const flushes: Promise<void>[] = [];
|
|
||||||
if (traceProvider) flushes.push(traceProvider.forceFlush());
|
|
||||||
if (logProvider) flushes.push(logProvider.forceFlush());
|
|
||||||
if (meterProvider) flushes.push(meterProvider.forceFlush());
|
|
||||||
await Promise.all(flushes);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import { getLastChangelogVersionPath, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
import { getLastChangelogVersionPath, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
||||||
|
import type { BunFile } from "bun";
|
||||||
import bundledChangelogPath from "../../CHANGELOG.md" with { type: "file" };
|
import bundledChangelogPath from "../../CHANGELOG.md" with { type: "file" };
|
||||||
import type { SettingValue } from "../config/settings";
|
import type { SettingValue } from "../config/settings";
|
||||||
|
|
||||||
@@ -197,6 +198,88 @@ function parseChangelogContent(content: string): ChangelogEntry[] {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function parseStartupChangelog(
|
||||||
|
changelogPath: string | undefined,
|
||||||
|
lastVersion: ChangelogEntry,
|
||||||
|
): Promise<{ entries: ChangelogEntry[]; totalUnseenEntries: number }> {
|
||||||
|
if (changelogPath) {
|
||||||
|
try {
|
||||||
|
return await parseStartupChangelogFile(Bun.file(changelogPath), lastVersion);
|
||||||
|
} catch (error) {
|
||||||
|
if (!isEnoent(error)) {
|
||||||
|
logger.error(`Warning: Could not parse changelog: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseStartupChangelogFile(
|
||||||
|
Bun.file(resolveBundledChangelogPath(bundledChangelogPath, import.meta.url)),
|
||||||
|
lastVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parseStartupChangelogFile(
|
||||||
|
file: BunFile,
|
||||||
|
lastVersion: ChangelogEntry,
|
||||||
|
): Promise<{ entries: ChangelogEntry[]; totalUnseenEntries: number }> {
|
||||||
|
const entries: ChangelogEntry[] = [];
|
||||||
|
let currentVersion: ChangelogEntry | undefined;
|
||||||
|
let currentLines: string[] | undefined;
|
||||||
|
let totalUnseenEntries = 0;
|
||||||
|
|
||||||
|
const finishCurrentEntry = () => {
|
||||||
|
if (currentVersion && currentLines) {
|
||||||
|
entries.push({ ...currentVersion, content: currentLines.join("\n").trim() });
|
||||||
|
}
|
||||||
|
currentVersion = undefined;
|
||||||
|
currentLines = undefined;
|
||||||
|
};
|
||||||
|
const processLine = (line: string): boolean => {
|
||||||
|
if (!line.startsWith("## ")) {
|
||||||
|
currentLines?.push(line);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
finishCurrentEntry();
|
||||||
|
const versionMatch = line.match(/##\s+\[?(\d+)\.(\d+)\.(\d+)\]?/);
|
||||||
|
if (!versionMatch) return false;
|
||||||
|
|
||||||
|
const version = {
|
||||||
|
major: Number.parseInt(versionMatch[1], 10),
|
||||||
|
minor: Number.parseInt(versionMatch[2], 10),
|
||||||
|
patch: Number.parseInt(versionMatch[3], 10),
|
||||||
|
content: "",
|
||||||
|
};
|
||||||
|
if (compareChangelogEntries(version, lastVersion) <= 0) return true;
|
||||||
|
|
||||||
|
totalUnseenEntries++;
|
||||||
|
if (entries.length < RECENT_CHANGELOG_ENTRY_LIMIT) {
|
||||||
|
currentVersion = version;
|
||||||
|
currentLines = [line];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
let pending = "";
|
||||||
|
const chunkSize = 32 * 1024;
|
||||||
|
for (let start = 0; start < file.size; start += chunkSize) {
|
||||||
|
const end = Math.min(start + chunkSize, file.size);
|
||||||
|
pending += decoder.decode(await file.slice(start, end).arrayBuffer(), { stream: end < file.size });
|
||||||
|
let newlineIndex = pending.indexOf("\n");
|
||||||
|
while (newlineIndex !== -1) {
|
||||||
|
if (processLine(pending.slice(0, newlineIndex))) {
|
||||||
|
return { entries, totalUnseenEntries };
|
||||||
|
}
|
||||||
|
pending = pending.slice(newlineIndex + 1);
|
||||||
|
newlineIndex = pending.indexOf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pending && !processLine(pending + decoder.decode())) {
|
||||||
|
finishCurrentEntry();
|
||||||
|
}
|
||||||
|
return { entries, totalUnseenEntries };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare changelog entries by their parsed version parts.
|
* Compare changelog entries by their parsed version parts.
|
||||||
* Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
* Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
||||||
@@ -264,6 +347,32 @@ export function renderChangelogEntries(
|
|||||||
return { markdown: markdown.slice(0, low) + suffix, truncated: true };
|
return { markdown: markdown.slice(0, low) + suffix, truncated: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectStartupChangelogEntries(
|
||||||
|
newEntries: ChangelogEntry[],
|
||||||
|
totalUnseenEntries: number,
|
||||||
|
): StartupChangelogSelection {
|
||||||
|
if (newEntries.length === 0) {
|
||||||
|
return emptyStartupSelection(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rendered = renderChangelogEntries(newEntries, {
|
||||||
|
maxBytes: STARTUP_CHANGELOG_MAX_BYTES,
|
||||||
|
truncationHint: STARTUP_CHANGELOG_FULL_HINT,
|
||||||
|
oldestFirst: false,
|
||||||
|
});
|
||||||
|
const summary = summarizeChangelogEntries(newEntries);
|
||||||
|
const latestEntry = newEntries[0];
|
||||||
|
return {
|
||||||
|
markdown: rendered.markdown,
|
||||||
|
persistCurrentVersion: true,
|
||||||
|
truncated: rendered.truncated,
|
||||||
|
selectedEntries: newEntries.length,
|
||||||
|
totalUnseenEntries,
|
||||||
|
latestVersion: latestEntry ? `${latestEntry.major}.${latestEntry.minor}.${latestEntry.patch}` : undefined,
|
||||||
|
...summary,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select bounded release notes for interactive startup.
|
* Select bounded release notes for interactive startup.
|
||||||
*/
|
*/
|
||||||
@@ -282,27 +391,7 @@ export function selectStartupChangelog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const allNewEntries = getNewEntries(entries, markerVersion);
|
const allNewEntries = getNewEntries(entries, markerVersion);
|
||||||
const newEntries = allNewEntries.slice(0, RECENT_CHANGELOG_ENTRY_LIMIT);
|
return selectStartupChangelogEntries(allNewEntries.slice(0, RECENT_CHANGELOG_ENTRY_LIMIT), allNewEntries.length);
|
||||||
if (newEntries.length === 0) {
|
|
||||||
return emptyStartupSelection(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const rendered = renderChangelogEntries(newEntries, {
|
|
||||||
maxBytes: STARTUP_CHANGELOG_MAX_BYTES,
|
|
||||||
truncationHint: STARTUP_CHANGELOG_FULL_HINT,
|
|
||||||
oldestFirst: false,
|
|
||||||
});
|
|
||||||
const summary = summarizeChangelogEntries(newEntries);
|
|
||||||
const latestEntry = newEntries[0];
|
|
||||||
return {
|
|
||||||
markdown: rendered.markdown,
|
|
||||||
persistCurrentVersion: true,
|
|
||||||
truncated: rendered.truncated,
|
|
||||||
selectedEntries: newEntries.length,
|
|
||||||
totalUnseenEntries: allNewEntries.length,
|
|
||||||
latestVersion: latestEntry ? `${latestEntry.major}.${latestEntry.minor}.${latestEntry.patch}` : undefined,
|
|
||||||
...summary,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -334,9 +423,8 @@ export async function resolveStartupChangelogForDisplay(options: {
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const { entries, totalUnseenEntries } = await parseStartupChangelog(options.changelogPath, parsedLastVersion);
|
||||||
const entries = await parseChangelog(options.changelogPath);
|
const startupChangelog = selectStartupChangelogEntries(entries, totalUnseenEntries);
|
||||||
const startupChangelog = selectStartupChangelog(entries, lastVersion, options.currentVersion);
|
|
||||||
if (startupChangelog.persistCurrentVersion) {
|
if (startupChangelog.persistCurrentVersion) {
|
||||||
await writeLastChangelogVersion(options.currentVersion, options.agentDir);
|
await writeLastChangelogVersion(options.currentVersion, options.agentDir);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|||||||
import * as fs from "node:fs/promises";
|
import * as fs from "node:fs/promises";
|
||||||
import * as os from "node:os";
|
import * as os from "node:os";
|
||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import { create, fromBinary } from "@bufbuild/protobuf";
|
import { create, fromBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
|
||||||
import { type } from "@oh-my-pi/omptype";
|
import { type } from "@oh-my-pi/omptype";
|
||||||
import type { AgentEvent, AgentTool, AgentToolContext } from "@oh-my-pi/pi-agent-core";
|
import type { AgentEvent, AgentTool, AgentToolContext } from "@oh-my-pi/pi-agent-core";
|
||||||
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
McpArgsSchema,
|
McpArgsSchema,
|
||||||
ReadArgsSchema,
|
ReadArgsSchema,
|
||||||
ShellArgsSchema,
|
ShellArgsSchema,
|
||||||
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
|
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
|
||||||
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
||||||
import { CursorExecHandlers } from "@oh-my-pi/pi-coding-agent/cursor";
|
import { CursorExecHandlers } from "@oh-my-pi/pi-coding-agent/cursor";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -401,6 +401,32 @@ describe("legacy Pi Babel AST behavior baseline", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("keeps mixed import and require rewrites byte-identical after a cached analysis", async () => {
|
||||||
|
const source = [
|
||||||
|
'import value from "tracked-dep";',
|
||||||
|
'export { value as named } from "tracked-dep";',
|
||||||
|
'const required = require("tracked-dep");',
|
||||||
|
].join("\n");
|
||||||
|
const expected = [
|
||||||
|
`import value from ${JSON.stringify(importTarget)};`,
|
||||||
|
`export { value as named } from ${JSON.stringify(importTarget)};`,
|
||||||
|
`const required = require(${JSON.stringify(requireTarget)});`,
|
||||||
|
].join("\n");
|
||||||
|
expect(await __rewriteLegacyExtensionSourceForTests(source, rewriteImporter)).toBe(expected);
|
||||||
|
expect(await __rewriteLegacyExtensionSourceForTests(source, rewriteImporter)).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("uses a fresh analysis when extension source content changes", async () => {
|
||||||
|
const original = 'import value from "tracked-dep";';
|
||||||
|
const changed = 'const value = require("tracked-dep");';
|
||||||
|
expect(await __rewriteLegacyExtensionSourceForTests(original, rewriteImporter)).toBe(
|
||||||
|
`import value from ${JSON.stringify(importTarget)};`,
|
||||||
|
);
|
||||||
|
expect(await __rewriteLegacyExtensionSourceForTests(changed, rewriteImporter)).toBe(
|
||||||
|
`const value = require(${JSON.stringify(requireTarget)});`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("discovers exact CommonJS named exports with Babel binding semantics", async () => {
|
test("discovers exact CommonJS named exports with Babel binding semantics", async () => {
|
||||||
for (const testCase of commonJsCases) {
|
for (const testCase of commonJsCases) {
|
||||||
const actual = await loadCommonJsCase(testCase);
|
const actual = await loadCommonJsCase(testCase);
|
||||||
|
|||||||
@@ -364,6 +364,36 @@ describe("StatusLineComponent context breakdown", () => {
|
|||||||
settings.clearOverride("statusLine.preset");
|
settings.clearOverride("statusLine.preset");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("embedded overflow (>100%) breaks the raw percent past the window label in error color", () => {
|
||||||
|
const { session } = makeSession({
|
||||||
|
messages: [userMessage("hi"), assistantMessage("done")],
|
||||||
|
contextWindow: 200_000,
|
||||||
|
usage: { tokens: 240_000, contextWindow: 200_000, percent: 120 },
|
||||||
|
});
|
||||||
|
settings.override("statusLine.preset", "custom");
|
||||||
|
settings.override("statusLine.leftSegments", ["pi", "context_pct"]);
|
||||||
|
settings.override("statusLine.rightSegments", ["context_total", "session_name"]);
|
||||||
|
settings.override("statusLine.contextLine", "embedded");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const comp = new StatusLineComponent(session);
|
||||||
|
const border = comp.getTopBorder(120);
|
||||||
|
const plain = border.content.replaceAll(/\x1b\[[0-9;]*m/g, "");
|
||||||
|
const windowIndex = plain.indexOf("200K");
|
||||||
|
const percentIndex = plain.indexOf("120%");
|
||||||
|
expect(border.width).toBe(120);
|
||||||
|
expect(windowIndex).toBeGreaterThanOrEqual(0);
|
||||||
|
expect(percentIndex).toBeGreaterThan(windowIndex);
|
||||||
|
// The clamped label must not render alongside the overflow one.
|
||||||
|
expect(plain).not.toContain("100%");
|
||||||
|
expect(border.content).toContain(`${theme.getFgAnsi("error")}120%`);
|
||||||
|
} finally {
|
||||||
|
settings.clearOverride("statusLine.contextLine");
|
||||||
|
settings.clearOverride("statusLine.rightSegments");
|
||||||
|
settings.clearOverride("statusLine.leftSegments");
|
||||||
|
settings.clearOverride("statusLine.preset");
|
||||||
|
}
|
||||||
|
});
|
||||||
it("uses semantic Nerd Font markers for async speculation and compaction boundaries", async () => {
|
it("uses semantic Nerd Font markers for async speculation and compaction boundaries", async () => {
|
||||||
const { session } = makeSession({
|
const { session } = makeSession({
|
||||||
messages: [userMessage("hi"), assistantMessage("done")],
|
messages: [userMessage("hi"), assistantMessage("done")],
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ let tempDir: string;
|
|||||||
let testSettings: Settings;
|
let testSettings: Settings;
|
||||||
const GENERATED_TYPESCRIPT = "// Code generated by sqlc. DO NOT EDIT.\n\nexport const foo = 1;";
|
const GENERATED_TYPESCRIPT = "// Code generated by sqlc. DO NOT EDIT.\n\nexport const foo = 1;";
|
||||||
|
|
||||||
|
const CATALOG_PROTOCOL_DECLARATIONS = [
|
||||||
|
path.resolve(import.meta.dir, "../../../catalog/src/discovery/cursor-proto.ts"),
|
||||||
|
path.resolve(import.meta.dir, "../../../catalog/src/discovery/devin-proto.ts"),
|
||||||
|
];
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
resetSettingsForTest();
|
resetSettingsForTest();
|
||||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "auto-gen-guard-"));
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "auto-gen-guard-"));
|
||||||
@@ -80,6 +85,12 @@ describe("assertEditableFile", () => {
|
|||||||
await expect(assertEditableFile(filePath, undefined, testSettings)).rejects.toBeInstanceOf(ToolError);
|
await expect(assertEditableFile(filePath, undefined, testSettings)).rejects.toBeInstanceOf(ToolError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("blocks generated catalog protocol declarations", async () => {
|
||||||
|
for (const filePath of CATALOG_PROTOCOL_DECLARATIONS) {
|
||||||
|
await expect(assertEditableFile(filePath, undefined, testSettings)).rejects.toBeInstanceOf(ToolError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("allows normal files", async () => {
|
it("allows normal files", async () => {
|
||||||
const filePath = path.join(tempDir, "normal.ts");
|
const filePath = path.join(tempDir, "normal.ts");
|
||||||
await Bun.write(filePath, "// Regular source file\nexport const foo = 1;");
|
await Bun.write(filePath, "// Regular source file\nexport const foo = 1;");
|
||||||
|
|||||||
@@ -678,6 +678,11 @@ export function getGithubCacheDbPath(): string {
|
|||||||
return dirs.rootSubdir(path.join("cache", "github-cache.db"), "cache");
|
return dirs.rootSubdir(path.join("cache", "github-cache.db"), "cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the legacy Pi extension parse cache database path. */
|
||||||
|
export function getLegacyPiExtensionCacheDbPath(): string {
|
||||||
|
return dirs.rootSubdir(path.join("cache", "legacy-pi-extension-cache.db"), "cache");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the encrypted auth-broker snapshot cache path (~/.omp/cache/auth-broker-snapshot.enc).
|
* Get the encrypted auth-broker snapshot cache path (~/.omp/cache/auth-broker-snapshot.enc).
|
||||||
* Honors the `OMP_AUTH_BROKER_SNAPSHOT_CACHE` env var when set so tests and
|
* Honors the `OMP_AUTH_BROKER_SNAPSHOT_CACHE` env var when set so tests and
|
||||||
|
|||||||
Reference in New Issue
Block a user