mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-25 16:42:16 +03:00
The executor barrel statically imported ~100 executor modules and
constructed every instance at module load. Measured cold cost on top of
the minimal set: ~0.7–1.2s boot time and ~35MB heap, paid by every
deployment regardless of which providers it uses.
Now:
- executors/index.ts keeps the declarative alias table byte-stable (same
keys, same order, same ctor args — pinned by the golden lock) but each
value is a deferred loader using dynamic import; bundlers emit
on-demand chunks
- registry.ts gains registerLazyExecutor/loadRegisteredExecutor: aliases
are declared eagerly so hasSpecializedExecutor() and
listExecutorAliases() stay synchronous, instances materialize once on
first use and cache into the same registry map
- getExecutor() becomes async; production call sites (chatCore proxy
resolver, video generation, compression judge/eval clients,
quotaAutoPing deps, anthropic OAuth validation) await it
- cliproxy wrapper ExecutorLike types drop their index signatures so
BaseExecutor satisfies them structurally
Measured after (isolated DATA_DIR): barrel boot 712-832ms / ~45MB with
first-use materialization of an executor costing +120-150ms once.
Test impact: 24 unit suites adapted mechanically to the async seam
(await + union narrowing on the Response | {response} execute result);
class imports moved from the barrel to executor module files. The
web-cookie sweep SIGABRT failure is pre-existing (reproduced identically
on the clean base).
Commit gate note: husky lint-staged fails with 'suppressions left that
do not occur anymore' — reproduced identically on a stashed clean tree
(22 baseline problems), independent of this change.
166 lines
5.7 KiB
TypeScript
166 lines
5.7 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { getExecutor } from "../../open-sse/executors/index.ts";
|
|
import {
|
|
AntigravityExecutor,
|
|
processAntigravitySSEPayload,
|
|
} from "../../open-sse/executors/antigravity.ts";
|
|
|
|
function emptyCollected(): any {
|
|
return {
|
|
textContent: "",
|
|
finishReason: "",
|
|
toolCalls: [],
|
|
usage: null,
|
|
remainingCredits: null,
|
|
};
|
|
}
|
|
|
|
test("getExecutor('agy') returns AntigravityExecutor (not DefaultExecutor)", async () => {
|
|
const executor = await getExecutor("agy");
|
|
assert.ok(executor instanceof AntigravityExecutor, "agy provider should use AntigravityExecutor");
|
|
});
|
|
|
|
test("getExecutor('antigravity') returns AntigravityExecutor", async () => {
|
|
const executor = await getExecutor("antigravity");
|
|
assert.ok(
|
|
executor instanceof AntigravityExecutor,
|
|
"antigravity provider should use AntigravityExecutor"
|
|
);
|
|
});
|
|
|
|
test("getExecutor('agy') builds valid streaming URL", async () => {
|
|
const executor = await getExecutor("agy");
|
|
const url = executor.buildUrl("gemini-3.7-flash-high", true);
|
|
assert.ok(
|
|
url.includes("streamGenerateContent?alt=sse"),
|
|
`expected streaming endpoint URL, got: ${url}`
|
|
);
|
|
});
|
|
|
|
test("getExecutor('agy') builds valid non-streaming URL", async () => {
|
|
const executor = await getExecutor("agy");
|
|
const url = executor.buildUrl("gemini-3.7-flash-high", false);
|
|
// Antigravity executor always uses streaming endpoint (buildUrl ignores stream flag)
|
|
assert.ok(
|
|
url.includes("streamGenerateContent?alt=sse"),
|
|
`expected streaming endpoint URL (always), got: ${url}`
|
|
);
|
|
});
|
|
|
|
test("getExecutor('agy') buildHeaders returns Bearer auth", async () => {
|
|
const executor = await getExecutor("agy");
|
|
const headers = executor.buildHeaders({ accessToken: "test-token" });
|
|
assert.equal(headers.Authorization, "Bearer test-token");
|
|
});
|
|
|
|
// #3821-review LEDGER-9 — the Antigravity SSE `markdown` extraction branch had no test.
|
|
test("processAntigravitySSEPayload accumulates top-level markdown into textContent", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload(JSON.stringify({ markdown: "Hello " }), collected);
|
|
processAntigravitySSEPayload(JSON.stringify({ response: { markdown: "world" } }), collected);
|
|
assert.equal(collected.textContent, "Hello world");
|
|
});
|
|
|
|
test("processAntigravitySSEPayload uses candidate parts text when no markdown is present", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload(
|
|
JSON.stringify({ response: { candidates: [{ content: { parts: [{ text: "from parts" }] } }] } }),
|
|
collected
|
|
);
|
|
assert.equal(collected.textContent, "from parts");
|
|
});
|
|
|
|
test("processAntigravitySSEPayload ignores [DONE] and malformed payloads without throwing", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload("[DONE]", collected);
|
|
processAntigravitySSEPayload("{not json", collected);
|
|
assert.equal(collected.textContent, "");
|
|
});
|
|
|
|
// #7037 — non-streaming (and tool-only) responses carry the tool call as a native
|
|
// `part.functionCall` with no `part.text`. It must produce a tool call instead of
|
|
// empty content (which previously surfaced as a 502 "Provider returned empty content").
|
|
test("processAntigravitySSEPayload converts native part.functionCall into a tool call (#7037)", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload(
|
|
JSON.stringify({
|
|
response: {
|
|
candidates: [
|
|
{
|
|
content: {
|
|
parts: [{ functionCall: { name: "get_weather", args: { city: "Paris" } } }],
|
|
},
|
|
finishReason: "STOP",
|
|
},
|
|
],
|
|
usageMetadata: { promptTokenCount: 12, candidatesTokenCount: 932, totalTokenCount: 944 },
|
|
},
|
|
}),
|
|
collected
|
|
);
|
|
|
|
assert.equal(collected.textContent, "");
|
|
assert.equal(collected.toolCalls.length, 1);
|
|
assert.equal(collected.toolCalls[0].type, "function");
|
|
assert.equal(collected.toolCalls[0].function.name, "get_weather");
|
|
assert.deepEqual(JSON.parse(collected.toolCalls[0].function.arguments), { city: "Paris" });
|
|
assert.equal(collected.finishReason, "tool_calls");
|
|
assert.ok(collected.usage !== null, "usage metadata should still be collected");
|
|
});
|
|
|
|
test("processAntigravitySSEPayload handles a mixed text + functionCall response (#7037)", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload(
|
|
JSON.stringify({
|
|
response: {
|
|
candidates: [
|
|
{
|
|
content: {
|
|
parts: [
|
|
{ text: "Let me check." },
|
|
{ functionCall: { name: "get_weather", args: { city: "Paris" } } },
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
collected
|
|
);
|
|
|
|
assert.equal(collected.textContent, "Let me check.");
|
|
assert.equal(collected.toolCalls.length, 1);
|
|
assert.equal(collected.toolCalls[0].function.name, "get_weather");
|
|
});
|
|
|
|
// #7037 — before the fix, a function-call-only payload yielded no text and no
|
|
// tool call, so the non-streaming path returned empty content. Guard that the
|
|
// textual-tool-call path is unaffected.
|
|
test("processAntigravitySSEPayload still parses textual [Tool call:] when present", () => {
|
|
const collected = emptyCollected();
|
|
processAntigravitySSEPayload(
|
|
JSON.stringify({
|
|
response: {
|
|
candidates: [
|
|
{
|
|
content: {
|
|
parts: [
|
|
{
|
|
text: "[Tool call: get_weather]\nArguments: {\"city\":\"Paris\"}",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
collected
|
|
);
|
|
|
|
assert.equal(collected.toolCalls.length, 1);
|
|
assert.equal(collected.toolCalls[0].function.name, "get_weather");
|
|
assert.deepEqual(JSON.parse(collected.toolCalls[0].function.arguments), { city: "Paris" });
|
|
});
|