fix(code-mode): report UTF-8 API file byte counts (#104244)

* fix(code-mode): report UTF-8 API file byte counts

* fix(code-mode): report UTF-8 API file byte counts

* chore(changelog): keep release notes release-owned

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
qingminlong
2026-07-11 05:10:46 -07:00
committed by GitHub
co-authored by Peter Steinberger
parent b2a6408964
commit 08da0d3861
3 changed files with 25 additions and 11 deletions
+7 -2
View File
@@ -574,6 +574,7 @@ export type CodeModeApiVirtualFile = {
path: string;
description?: string;
content: string;
bytes: number;
};
function buildMcpParamDocs(schema: unknown): McpApiParamDoc[] {
@@ -872,18 +873,22 @@ export function createCodeModeApiVirtualFiles(
if (!model) {
return [];
}
const rootContent = renderMcpRootFile(model.docs);
const files: CodeModeApiVirtualFile[] = [
{
path: "mcp/index.d.ts",
description: "Root MCP namespace declaration and server list.",
content: renderMcpRootFile(model.docs),
content: rootContent,
bytes: Buffer.byteLength(rootContent, "utf8"),
},
];
for (const server of model.docs) {
const content = renderMcpServerHeader(server, server.tools);
files.push({
path: `mcp/${server.identifier}.d.ts`,
description: `MCP server declaration for ${server.serverName}.`,
content: renderMcpServerHeader(server, server.tools),
content,
bytes: Buffer.byteLength(content, "utf8"),
});
}
return files;
+16 -2
View File
@@ -886,7 +886,7 @@ describe("Code Mode", () => {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string", description: "Repository name" },
repo: { type: "string", description: "Repository 名称" },
title: { type: "string", description: "Issue title\nShown in tracker" },
body: { type: "string", default: "" },
},
@@ -939,6 +939,9 @@ describe("Code Mode", () => {
return {
apiHeader: api.header,
apiFilePaths: apiFiles.files.map((file) => file.path),
listedServerFileBytes: apiFiles.files.find((file) => file.path === "mcp/github.d.ts").bytes,
serverFileBytes: serverFile.bytes,
serverFileContent: serverFile.content,
rootFileHasReference: rootFile.content.includes('./github.d.ts'),
serverFileHasCreateIssue: serverFile.content.includes('function createIssue('),
serverFileHasTitleDoc: serverFile.content.includes('@param title Issue title Shown in tracker'),
@@ -987,12 +990,23 @@ describe("Code Mode", () => {
apiSchemaTitle: "object",
apiHeader: expect.stringContaining("function createIssue("),
apiFilePaths: ["mcp/index.d.ts", "mcp/github.d.ts"],
listedServerFileBytes: expect.any(Number),
serverFileBytes: expect.any(Number),
serverFileContent: expect.stringContaining("Repository 名称"),
rootFileHasReference: true,
serverFileHasCreateIssue: true,
serverFileHasTitleDoc: true,
rootServers: [{ identifier: "github", serverName: "github", toolCount: 1 }],
});
const value = details.value as { apiHeader: string };
const value = details.value as {
apiHeader: string;
listedServerFileBytes: number;
serverFileBytes: number;
serverFileContent: string;
};
expect(value.listedServerFileBytes).toBe(value.serverFileBytes);
expect(value.serverFileBytes).toBe(Buffer.byteLength(value.serverFileContent, "utf8"));
expect(value.serverFileBytes).toBeGreaterThan(value.serverFileContent.length);
expect(value.apiHeader).toContain("@param title Issue title Shown in tracker");
expect(value.apiHeader).not.toContain("@param title Issue title\n");
expect(value.apiHeader).toContain("title: string;");
+2 -7
View File
@@ -7,6 +7,7 @@ import { createRequire } from "node:module";
import { parentPort, workerData } from "node:worker_threads";
import { isRecord } from "@openclaw/normalization-core/record-coerce";
import { EvalFlags, Intrinsics, JSException, QuickJS, type JSValueHandle } from "quickjs-wasi";
import type { CodeModeApiVirtualFile } from "./code-mode-namespaces.js";
const require = createRequire(import.meta.url);
const QUICKJS_WASM_PATH = require.resolve("quickjs-wasi/quickjs.wasm");
let quickJsWasmModulePromise: Promise<WebAssembly.Module> | undefined;
@@ -46,12 +47,6 @@ type CodeModeNamespaceDescriptor = {
scope: SerializedCodeModeNamespaceValue;
};
type CodeModeApiVirtualFile = {
path: string;
description?: string;
content: string;
};
type CodeModeWorkerInput =
| {
kind: "exec";
@@ -312,7 +307,7 @@ const CONTROLLER_SOURCE = String.raw`
path,
content,
description: typeof file.description === "string" ? file.description : undefined,
bytes: content.length,
bytes: file.bytes,
}));
}
const api = Object.freeze({