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:
@@ -2,7 +2,7 @@ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
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 { AgentEvent, AgentTool, AgentToolContext } from "@oh-my-pi/pi-agent-core";
|
||||
import { type BlockState, handleServerMessage, type ToolCallState } from "@oh-my-pi/pi-ai/providers/cursor";
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
McpArgsSchema,
|
||||
ReadArgsSchema,
|
||||
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 { CursorExecHandlers } from "@oh-my-pi/pi-coding-agent/cursor";
|
||||
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 () => {
|
||||
for (const testCase of commonJsCases) {
|
||||
const actual = await loadCommonJsCase(testCase);
|
||||
|
||||
@@ -364,6 +364,36 @@ describe("StatusLineComponent context breakdown", () => {
|
||||
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 () => {
|
||||
const { session } = makeSession({
|
||||
messages: [userMessage("hi"), assistantMessage("done")],
|
||||
|
||||
@@ -11,6 +11,11 @@ let tempDir: string;
|
||||
let testSettings: Settings;
|
||||
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 () => {
|
||||
resetSettingsForTest();
|
||||
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);
|
||||
});
|
||||
|
||||
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 () => {
|
||||
const filePath = path.join(tempDir, "normal.ts");
|
||||
await Bun.write(filePath, "// Regular source file\nexport const foo = 1;");
|
||||
|
||||
Reference in New Issue
Block a user