Files
OmniRoute/tests/unit/conductor-delegate.test.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

72 lines
3.2 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { createConductorTask } from "../../src/lib/conductor/hubProxy.ts";
function fakeHub(body: unknown, status = 201) {
const calls: { url: string; method: string; auth: string | null; body: unknown }[] = [];
const impl = (async (url: string | URL | Request, init?: RequestInit) => {
calls.push({
url: String(url),
method: init?.method ?? "GET",
auth: (init?.headers as Record<string, string> | undefined)?.authorization ?? null,
body: JSON.parse(String(init?.body ?? "{}")),
});
return new Response(JSON.stringify(body), { status });
}) as typeof fetch;
return { impl, calls };
}
test.beforeEach(() => {
process.env.CONDUCTOR_HUB_URL = "http://hub.test:7910";
process.env.CONDUCTOR_HUB_TOKEN = "tok-hub";
delete process.env.CONDUCTOR_ORCHESTRATOR_TOKEN;
});
test.after(() => {
delete process.env.CONDUCTOR_HUB_URL;
delete process.env.CONDUCTOR_HUB_TOKEN;
delete process.env.CONDUCTOR_ORCHESTRATOR_TOKEN;
});
test("traduz a delegação A2A no POST /v1/tasks do hub (shape exato do contrato)", async () => {
const { impl, calls } = fakeHub({ id: "t_novo", status: "submitted" });
const r = await createConductorTask(
{ repoUrl: "https://git.x/repo", baseRef: "dev", prompt: "adicione um README", mode: "council-3", cli: "claude", model: "cc/claude-sonnet-5" },
{ fetchImpl: impl }
);
assert.deepEqual(r, { ok: true, status: 201, task_id: "t_novo" });
assert.equal(calls[0].url, "http://hub.test:7910/v1/tasks");
assert.equal(calls[0].method, "POST");
assert.deepEqual(calls[0].body, {
repo: { url: "https://git.x/repo", base_ref: "dev" },
spec: { prompt: "adicione um README" },
mode: "council-3",
requirements: { cli: "claude", model: "cc/claude-sonnet-5" },
});
});
test("defaults: base_ref main, mode solo, sem requirements quando cli/model ausentes", async () => {
const { impl, calls } = fakeHub({ id: "t_d", status: "submitted" });
await createConductorTask({ repoUrl: "https://git.x/r", prompt: "p" }, { fetchImpl: impl });
assert.deepEqual(calls[0].body, { repo: { url: "https://git.x/r", base_ref: "main" }, spec: { prompt: "p" }, mode: "solo" });
});
test("credencial: prefere CONDUCTOR_ORCHESTRATOR_TOKEN; fallback é o token do hub", async () => {
const a = fakeHub({ id: "t_1" });
await createConductorTask({ repoUrl: "https://x/r", prompt: "p" }, { fetchImpl: a.impl });
assert.equal(a.calls[0].auth, "Bearer tok-hub");
process.env.CONDUCTOR_ORCHESTRATOR_TOKEN = "tok-orch";
const b = fakeHub({ id: "t_2" });
await createConductorTask({ repoUrl: "https://x/r", prompt: "p" }, { fetchImpl: b.impl });
assert.equal(b.calls[0].auth, "Bearer tok-orch");
});
test("recusa do hub → {ok:false, status} sem lançar nem vazar corpo; env ausente → 503", async () => {
const { impl } = fakeHub({ error: "segredo do hub" }, 422);
const r = await createConductorTask({ repoUrl: "https://x/r", prompt: "p" }, { fetchImpl: impl });
assert.deepEqual(r, { ok: false, status: 422 });
delete process.env.CONDUCTOR_HUB_URL;
assert.deepEqual(await createConductorTask({ repoUrl: "https://x/r", prompt: "p" }, {}), { ok: false, status: 503 });
});