mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 08:50:43 +00:00
refactor: centralize provider stream fallback ownership
This commit is contained in:
@@ -3,6 +3,7 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
buildCopilotDynamicHeaders,
|
||||
createHtmlEntityToolCallArgumentDecodingWrapper,
|
||||
createPayloadPatchStreamWrapper,
|
||||
defaultToolStreamExtraParams,
|
||||
decodeHtmlEntitiesInObject,
|
||||
hasCopilotVisionInput,
|
||||
@@ -182,3 +183,47 @@ describe("createHtmlEntityToolCallArgumentDecodingWrapper", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("createPayloadPatchStreamWrapper", () => {
|
||||
it("passes stream call options to payload patches", () => {
|
||||
let captured: Record<string, unknown> = {};
|
||||
const baseStreamFn: StreamFn = (_model, _context, options) => {
|
||||
const payload: Record<string, unknown> = {};
|
||||
options?.onPayload?.(payload, _model);
|
||||
captured = payload;
|
||||
return {} as ReturnType<StreamFn>;
|
||||
};
|
||||
|
||||
const wrapped = createPayloadPatchStreamWrapper(baseStreamFn, ({ payload, options }) => {
|
||||
payload.reasoning = (options as { reasoning?: unknown } | undefined)?.reasoning;
|
||||
});
|
||||
void wrapped(
|
||||
{ id: "model" } as never,
|
||||
{ messages: [] } as never,
|
||||
{
|
||||
reasoning: "medium",
|
||||
} as never,
|
||||
);
|
||||
|
||||
expect(captured).toEqual({ reasoning: "medium" });
|
||||
});
|
||||
|
||||
it("calls the underlying stream directly when shouldPatch rejects the model", () => {
|
||||
let onPayloadWasInstalled = false;
|
||||
const baseStreamFn: StreamFn = (_model, _context, options) => {
|
||||
onPayloadWasInstalled = typeof options?.onPayload === "function";
|
||||
return {} as ReturnType<StreamFn>;
|
||||
};
|
||||
|
||||
const wrapped = createPayloadPatchStreamWrapper(
|
||||
baseStreamFn,
|
||||
({ payload }) => {
|
||||
payload.unexpected = true;
|
||||
},
|
||||
{ shouldPatch: () => false },
|
||||
);
|
||||
void wrapped({ id: "model" } as never, { messages: [] } as never, {});
|
||||
|
||||
expect(onPayloadWasInstalled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -132,13 +132,26 @@ export function createPayloadPatchStreamWrapper(
|
||||
patchPayload: (params: {
|
||||
payload: Record<string, unknown>;
|
||||
model: Parameters<StreamFn>[0];
|
||||
context: Parameters<StreamFn>[1];
|
||||
options: Parameters<StreamFn>[2];
|
||||
}) => void,
|
||||
wrapperOptions?: {
|
||||
shouldPatch?: (params: {
|
||||
model: Parameters<StreamFn>[0];
|
||||
context: Parameters<StreamFn>[1];
|
||||
options: Parameters<StreamFn>[2];
|
||||
}) => boolean;
|
||||
},
|
||||
): StreamFn {
|
||||
const underlying = baseStreamFn ?? streamSimple;
|
||||
return (model, context, options) =>
|
||||
streamWithPayloadPatch(underlying, model, context, options, (payload) =>
|
||||
patchPayload({ payload, model }),
|
||||
return (model, context, options) => {
|
||||
if (wrapperOptions?.shouldPatch && !wrapperOptions.shouldPatch({ model, context, options })) {
|
||||
return underlying(model, context, options);
|
||||
}
|
||||
return streamWithPayloadPatch(underlying, model, context, options, (payload) =>
|
||||
patchPayload({ payload, model, context, options }),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export type DeepSeekV4ThinkingLevel = ProviderWrapStreamFnContext["thinkingLevel"];
|
||||
|
||||
Reference in New Issue
Block a user