mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-19 05:12:16 +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.
84 lines
3.0 KiB
TypeScript
84 lines
3.0 KiB
TypeScript
/**
|
|
* Fusion panel member extraction — resolves combo.models entries for the
|
|
* fusion strategy, including nested `combo-ref` steps (#6764).
|
|
*
|
|
* A combo-ref panel member is dispatched as ONE black-box panel voice (a full
|
|
* recursive handleComboChat call for the referenced combo, reusing the same
|
|
* executeComboRefUnit + cycle/depth guards every other combo-ref-consuming
|
|
* strategy already uses) — NOT a fan-out of the referenced combo's own
|
|
* targets. This keeps panel sizing and cost predictable and matches how a
|
|
* literal `auto/*` string panel member already behaves via the single-
|
|
* dispatch safety net in src/sse/handlers/chat.ts.
|
|
*/
|
|
import { getComboModelString, normalizeComboStep } from "../../../src/lib/combos/steps.ts";
|
|
import { executeComboRefUnit } from "./runtimeUnits.ts";
|
|
import type {
|
|
ComboCollectionLike,
|
|
ComboNestingContext,
|
|
HandleComboChatOptions,
|
|
HandleSingleModel,
|
|
ResolvedComboRefTarget,
|
|
} from "./types.ts";
|
|
|
|
export type FusionPanelSpec = {
|
|
/** Dispatch keys handed to fusion.ts's `models` — comboName for combo-ref members, plain model string otherwise. */
|
|
panel: string[];
|
|
/** comboName -> resolved combo-ref unit, consumed by buildFusionHandleSingleModel. */
|
|
comboRefUnits: Map<string, ResolvedComboRefTarget>;
|
|
};
|
|
|
|
export function extractFusionPanelSpec(
|
|
models: unknown[],
|
|
comboName: string,
|
|
allCombos: ComboCollectionLike
|
|
): FusionPanelSpec {
|
|
const panel: string[] = [];
|
|
const comboRefUnits = new Map<string, ResolvedComboRefTarget>();
|
|
models.forEach((entry, index) => {
|
|
const step = normalizeComboStep(entry, { comboName, index, allCombos });
|
|
if (!step) return;
|
|
if (step.kind === "combo-ref") {
|
|
if (!comboRefUnits.has(step.comboName)) {
|
|
comboRefUnits.set(step.comboName, {
|
|
kind: "combo-ref",
|
|
stepId: step.id,
|
|
executionKey: step.id,
|
|
comboName: step.comboName,
|
|
weight: step.weight,
|
|
label: step.label ?? null,
|
|
});
|
|
}
|
|
panel.push(step.comboName);
|
|
return;
|
|
}
|
|
// Provider-wildcard steps have no concrete model to dispatch — fusion is a
|
|
// fixed-size panel of literal models/combo-refs, not a wildcard-expanding
|
|
// strategy (see file header). Skip rather than push an undefined model.
|
|
const modelStr = getComboModelString(step);
|
|
if (modelStr) panel.push(modelStr);
|
|
});
|
|
return { panel, comboRefUnits };
|
|
}
|
|
|
|
export function buildFusionHandleSingleModel(args: {
|
|
handleSingleModel: HandleSingleModel;
|
|
comboRefUnits: Map<string, ResolvedComboRefTarget>;
|
|
allCombos: ComboCollectionLike;
|
|
nesting: ComboNestingContext;
|
|
baseOptions: HandleComboChatOptions;
|
|
runCombo: (options: HandleComboChatOptions) => Promise<Response>;
|
|
}): HandleSingleModel {
|
|
return (body, modelStr, target) => {
|
|
const unit = args.comboRefUnits.get(modelStr);
|
|
if (!unit) return args.handleSingleModel(body, modelStr, target);
|
|
return executeComboRefUnit({
|
|
body,
|
|
unit,
|
|
allCombos: args.allCombos,
|
|
runCombo: args.runCombo,
|
|
baseOptions: args.baseOptions,
|
|
nesting: args.nesting,
|
|
});
|
|
};
|
|
}
|