mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
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.
72 lines
3.2 KiB
TypeScript
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 });
|
|
});
|