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:
can1357
2026-08-20 07:18:19 +02:00
parent d820cf75bb
commit df0bb6e31a
90 changed files with 198107 additions and 92186 deletions
-2
View File
@@ -37,14 +37,12 @@
"fmt": "biome format --write ."
},
"dependencies": {
"@bufbuild/protobuf": "catalog:",
"@oh-my-pi/omptype": "catalog:",
"@oh-my-pi/pi-catalog": "catalog:",
"@oh-my-pi/pi-utils": "catalog:",
"@oh-my-pi/pi-wire": "catalog:"
},
"devDependencies": {
"@bufbuild/protoc-gen-es": "catalog:",
"@types/bun": "catalog:"
},
"engines": {
+1 -1
View File
@@ -1,6 +1,6 @@
#!/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.
Usage: python proto-extractor.py <bundled-js-file> <output-dir>
+1 -1
View File
@@ -9,7 +9,7 @@
*
* Kept apart from `cursor/exec-modern.ts` on purpose: these are pure
* 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
* nested path would drag the whole exec implementation in with it — and
* `./providers/*` is a single-segment wildcard export that cannot serve a
+18 -17
View File
@@ -1,9 +1,7 @@
import { createHash } from "node:crypto";
import * as fs from "node:fs/promises";
import http2 from "node:http2";
import { create, fromBinary, fromJson, type JsonValue, toBinary, toJson } from "@bufbuild/protobuf";
import { ValueSchema } from "@bufbuild/protobuf/wkt";
import type { ConversationStep, McpToolDefinition } from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
import type { ConversationStep, McpToolDefinition } from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
import {
AgentClientMessageSchema,
AgentConversationTurnStructureSchema,
@@ -139,11 +137,21 @@ import {
WriteShellStdinErrorSchema,
WriteShellStdinResultSchema,
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 { calculateCost } from "@oh-my-pi/pi-catalog/models";
import {
$env,
isRecord,
logger,
parseJsonWithRepair,
parseStreamingJson,
@@ -3099,8 +3107,7 @@ function parseToolArgsJson(text: string): unknown {
function decodeMcpArgValue(value: Uint8Array): unknown {
try {
const parsedValue = fromBinary(ValueSchema, value);
const jsonValue = toJson(ValueSchema, parsedValue) as JsonValue;
const jsonValue = decodeJsonValue(value);
if (typeof jsonValue === "string") {
return parseToolArgsJson(jsonValue);
}
@@ -4212,10 +4219,10 @@ export function buildMcpToolDefinitions(tools: Tool[] | undefined): McpToolDefin
return forwarded.map(tool => {
const jsonSchema = toolWireSchema(tool);
const schemaValue: JsonValue =
jsonSchema && typeof jsonSchema === "object"
? (jsonSchema as JsonValue)
jsonSchema !== null && !Array.isArray(jsonSchema) && isJsonValue(jsonSchema)
? jsonSchema
: { type: "object", properties: {}, required: [] };
const inputSchema = toBinary(ValueSchema, fromJson(ValueSchema, schemaValue));
const inputSchema = encodeJsonValue(schemaValue);
return create(McpToolDefinitionSchema, {
name: tool.name,
description: tool.description || "",
@@ -4463,17 +4470,11 @@ function buildRootPromptMessagesJson(
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 {
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
if (typeof value === "number") return Number.isFinite(value);
if (Array.isArray(value)) return value.every(isJsonValue);
if (!isPlainRecord(value)) return false;
if (!isRecord(value)) return false;
for (const key in value) {
if (!isJsonValue(value[key])) return false;
}
@@ -4488,7 +4489,7 @@ function encodeCursorMcpArguments(toolCall: ToolCall): Record<string, Uint8Array
if (!isJsonValue(value)) {
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;
}
@@ -10,7 +10,7 @@
* 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 {
AfterAgentResponseRequestResponseSchema,
AfterAgentThoughtRequestResponseSchema,
@@ -64,7 +64,7 @@ import {
StopRequestResponseSchema,
SubagentStartRequestResponseSchema,
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";
/**
@@ -1,5 +1,5 @@
import type http2 from "node:http2";
import { create, toBinary } from "@bufbuild/protobuf";
import { create, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
import {
AgentClientMessageSchema,
AskQuestionInteractionResponseSchema,
@@ -21,7 +21,7 @@ import {
WebFetchRequestResponseSchema,
WebSearchRequestResponse_ApprovedSchema,
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";
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
+10 -16
View File
@@ -1,32 +1,26 @@
import { gunzipSync, gzipSync } from "node:zlib";
import { create, fromBinary, toBinary } from "@bufbuild/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 { create, fromBinary, toBinary } from "@oh-my-pi/pi-catalog/discovery/protobuf";
import {
CacheControlType,
type ChatMessagePrompt,
ChatMessagePromptSchema,
ChatToolChoiceSchema,
ChatToolDefinitionSchema,
PromptCacheOptionsSchema,
} from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/chat_pb/chat_pb";
import {
ChatMessageRequestType,
ChatMessageSource,
type ChatToolCall,
ChatToolCallSchema,
ChatToolChoiceSchema,
ChatToolDefinitionSchema,
CompletionConfigurationSchema,
ConversationalPlannerMode,
GetChatMessageRequestSchema,
GetChatMessageResponseSchema,
GetUserJwtRequestSchema,
GetUserJwtResponseSchema,
ImageDataSchema,
MetadataSchema,
PromptCacheOptionsSchema,
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 { logger, parseStreamingJson, parseStreamingJsonThrottled } from "@oh-my-pi/pi-utils";
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
+1 -1
View File
@@ -40,7 +40,7 @@ import type { OpenAICompletionsOptions } from "./providers/openai-completions";
import { streamPiNative } from "./providers/pi-native-client";
// Heavy provider stream functions are imported lazily via register-builtins,
// 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
// gitlab-duo / kimi / synthetic providers stay eager because their modules
// export routing predicates (isGitLabDuoModel, isKimiModel, isSyntheticModel)
+1 -1
View File
@@ -32,7 +32,7 @@ import type {
ShellResult,
WriteArgs,
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 { 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";
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it } from "bun:test";
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 type { Context, Model } from "@oh-my-pi/pi-ai/types";
import { buildModel } from "@oh-my-pi/pi-catalog/build";
@@ -9,7 +9,7 @@ import {
InteractionUpdateSchema,
TextDeltaUpdateSchema,
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
// 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 * 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 type { Context, Model } from "@oh-my-pi/pi-ai/types";
import { buildModel } from "@oh-my-pi/pi-catalog/build";
@@ -10,7 +10,7 @@ import {
InteractionUpdateSchema,
TextDeltaUpdateSchema,
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,
// 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 { create } from "@bufbuild/protobuf";
import { create } from "@oh-my-pi/pi-catalog/discovery/protobuf";
import {
type BlockState,
buildCursorHistoryForTest,
@@ -16,7 +16,7 @@ import type { AssistantMessage, Context, CursorExecHandlers, Model, ToolResultMe
import { kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
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 {
type AgentRunRequest,
AgentServerMessageSchema,
@@ -31,7 +31,7 @@ import {
ReadRejectedSchema,
ReadResultSchema,
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";
afterEach(() => {
+2 -2
View File
@@ -1,5 +1,5 @@
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,
CURSOR_CLIENT_VERSION,
@@ -64,7 +64,7 @@ import {
SubagentAwaitArgsSchema,
ToolCallSchema,
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
@@ -1,5 +1,5 @@
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 { AssistantMessage } from "@oh-my-pi/pi-ai/types";
import { AssistantMessageEventStream } from "@oh-my-pi/pi-ai/utils/event-stream";
@@ -16,7 +16,7 @@ import {
SetupVmEnvironmentArgsSchema,
SwitchModeRequestQuerySchema,
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 ProtoUnknownBag = { $unknown?: ProtoUnknownField[] };
+2 -2
View File
@@ -5,11 +5,11 @@
// buildGrpcRequest is exercised directly (the transport is HTTP/2), and the
// serialized run request is decoded back from the wire bytes.
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 type { Context, Model } from "@oh-my-pi/pi-ai/types";
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({
id: "cursor-composer-2.5",
@@ -1,6 +1,6 @@
import { afterEach, describe, expect, it } from "bun:test";
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 type { Context, CursorToolResultHandler, Model, ToolResultMessage } from "@oh-my-pi/pi-ai/types";
import { buildModel } from "@oh-my-pi/pi-catalog/build";
@@ -15,7 +15,7 @@ import {
TurnEndedUpdateSchema,
UpdateTodosArgsSchema,
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;
+2 -2
View File
@@ -1,5 +1,5 @@
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,
processInteractionUpdate,
@@ -29,7 +29,7 @@ import {
UpdateTodosResultSchema,
UpdateTodosSuccessSchema,
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. */
interface SyncCall {
@@ -1,9 +1,9 @@
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 { AssistantMessage } from "@oh-my-pi/pi-ai/types";
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 {
type AgentClientMessage,
AgentClientMessageSchema,
@@ -20,7 +20,7 @@ import {
WebFetchRequestQuerySchema,
WebSearchArgsSchema,
WebSearchRequestQuerySchema,
} from "@oh-my-pi/pi-catalog/discovery/cursor-gen/agent_pb";
} from "@oh-my-pi/pi-catalog/discovery/cursor-proto";
function cursorAssistantMessage(): AssistantMessage {
return {
+2 -2
View File
@@ -1,9 +1,9 @@
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 type { Context, Model } from "@oh-my-pi/pi-ai/types";
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
+2 -3
View File
@@ -1,11 +1,10 @@
import { describe, expect, it } from "bun:test";
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 type { AssistantMessage, Context, Model } from "@oh-my-pi/pi-ai/types";
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 { GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-gen/exa/auth_pb/auth_pb";
import { GetChatMessageRequestSchema, GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-proto";
const devinModel: Model<"devin-agent"> = buildModel({
id: "devin-test",
@@ -1,11 +1,10 @@
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 { streamDevin } from "@oh-my-pi/pi-ai/providers/devin";
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
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 { GetChatMessageResponseSchema, GetUserJwtResponseSchema } from "@oh-my-pi/pi-catalog/discovery/devin-proto";
const CONNECT_END_STREAM_FLAG = 0x02;
const LARGE_TOOL_RESULT_BYTES = 160 * 1024;
@@ -1,14 +1,14 @@
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 type { Context, Model, ToolCall } from "@oh-my-pi/pi-ai/types";
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 {
ChatToolCallSchema,
GetChatMessageResponseSchema,
GetUserJwtResponseSchema,
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 {
const out = new Uint8Array(5 + payload.length);
+4 -4
View File
@@ -1,14 +1,14 @@
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 type { Context, Model } from "@oh-my-pi/pi-ai/types";
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 {
GetChatMessageResponseSchema,
GetUserJwtResponseSchema,
ModelUsageStatsSchema,
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 {
const out = new Uint8Array(5 + payload.length);