fix(types): preserve array-buffer response bodies (#9092)

Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates: typecheck/complexity/cognitive/changelog/vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-222248-suite.log
This commit is contained in:
backryun
2026-08-06 10:29:49 +09:00
committed by GitHub
parent 22d0e60d4a
commit da87422d9e
4 changed files with 9 additions and 16 deletions

View File

@@ -1,3 +1,4 @@
import { Buffer } from "node:buffer";
import { generateKeyPairSync, randomUUID } from "node:crypto";
import vm from "node:vm";
import { solveDuckDuckGoChallenge, makeDuckDuckGoFeSignals } from "./duckduckgo-web/challenge.ts";
@@ -499,7 +500,7 @@ export class DuckDuckGoWebExecutor extends BaseExecutor {
// Wrap the captured body as a Response so processResponse
// (already a streaming/non-streaming transformer) can be
// reused unchanged.
const upstreamResp = new Response(result.body, {
const upstreamResp = new Response(Buffer.from(result.body), {
status: result.status,
headers: {
"Content-Type": result.contentType || "text/event-stream",

View File

@@ -58,7 +58,7 @@ export interface EdgeTtsSynthInput {
}
export interface EdgeTtsSynthResult {
audio: Buffer;
audio: Buffer<ArrayBuffer>;
contentType: string;
}
@@ -189,9 +189,7 @@ export function isTurnEndMessage(message: string): boolean {
* ASCII headers, then the remaining bytes are audio data. Returns `null`
* for a frame too short to contain a valid header-length prefix.
*/
export function demuxAudioChunk(
frame: Buffer
): { headers: string; audio: Buffer } | null {
export function demuxAudioChunk(frame: Buffer): { headers: string; audio: Buffer } | null {
if (!Buffer.isBuffer(frame) || frame.length < 2) return null;
const headerLength = frame.readUInt16BE(0);
if (2 + headerLength > frame.length) return null;

View File

@@ -168,7 +168,7 @@ function encodeVarint(value: number): Uint8Array {
return new Uint8Array(bytes);
}
function concatBytes(arrays: Uint8Array[]): Uint8Array {
function concatBytes(arrays: Uint8Array[]): Uint8Array<ArrayBuffer> {
const total = arrays.reduce((n, a) => n + a.length, 0);
const out = new Uint8Array(total);
let off = 0;
@@ -626,7 +626,8 @@ export class WindsurfExecutor extends BaseExecutor {
const { done, value } = await reader.read();
if (done) break;
if (!value) continue;
pending = pending.length === 0 ? value : concatBytes([pending, value]);
pending =
pending.length === 0 ? Uint8Array.from(value) : concatBytes([pending, value]);
drainFrames();
}
} finally {

View File

@@ -148,7 +148,7 @@ async function readResponseText(response: Response, maxBytes: number) {
function normalizeBody(body: unknown, headers?: Record<string, string>) {
if (body === undefined || body === null) return undefined;
if (typeof body === "string") return body;
if (body instanceof Uint8Array) return body;
if (body instanceof Uint8Array) return new Uint8Array(body);
if (typeof body === "object") {
if (headers && !Object.keys(headers).some((key) => key.toLowerCase() === "content-type")) {
headers["Content-Type"] = "application/json";
@@ -388,14 +388,7 @@ export const builtinSkills: Record<string, SkillHandler> = {
},
web_fetch: async (input, context) => {
const {
url,
format,
depth,
wait_for_selector,
include_metadata,
provider,
} = input as {
const { url, format, depth, wait_for_selector, include_metadata, provider } = input as {
url: string;
format?: "markdown" | "html" | "links" | "screenshot";
depth?: 0 | 1 | 2;