fix(s31): close 1 review BLOCKER — EmbedderConfig registry + --embedder-config, never an import path
This commit is contained in:
parent
cabe05acf3
commit
b9dd91cdbe
4 changed files with 240 additions and 1 deletions
|
|
@ -52,8 +52,11 @@ from portfolio_optimiser.validator import Rejection, ValidatedProposal
|
|||
from portfolio_optimiser import okf, outbox
|
||||
from portfolio_optimiser.semretrieval import (
|
||||
SEMANTIC_WEIGHT_DEFAULT,
|
||||
Embedder,
|
||||
FakeEmbedder,
|
||||
HybridRanker,
|
||||
build_embedder,
|
||||
load_embedder_config,
|
||||
)
|
||||
from portfolio_optimiser.verdicts import (
|
||||
ExpeLContextProvider,
|
||||
|
|
@ -258,6 +261,7 @@ async def run_project(
|
|||
meter: TokenMeter | None = None,
|
||||
live_dry_run: bool = False,
|
||||
semantic_retrieval: bool = False,
|
||||
embedder: Embedder | None = None,
|
||||
) -> RunResult | DryRunReport:
|
||||
"""Run the vertical slice for ONE project. ``client_factory`` is the test-injection seam
|
||||
(defaults to the real backend). ``verdict_input`` carries the expert decision/rationale
|
||||
|
|
@ -395,7 +399,11 @@ async def run_project(
|
|||
# of that object — including a subsequent run with the flag OFF. Flag off => ranker stays None
|
||||
# => ``retrieve`` falls through to the StructuralRetriever default.
|
||||
ranker = (
|
||||
HybridRanker(FakeEmbedder(), similarity, SEMANTIC_WEIGHT_DEFAULT)
|
||||
HybridRanker(
|
||||
embedder if embedder is not None else FakeEmbedder(),
|
||||
similarity,
|
||||
SEMANTIC_WEIGHT_DEFAULT,
|
||||
)
|
||||
if semantic_retrieval
|
||||
else None
|
||||
)
|
||||
|
|
@ -553,6 +561,7 @@ async def run_portfolio(
|
|||
top_k: int = 3,
|
||||
meter_factory: Callable[[], TokenMeter] | None = None,
|
||||
semantic_retrieval: bool = False,
|
||||
embedder: Embedder | None = None,
|
||||
) -> PortfolioResult:
|
||||
"""Fan out over a portfolio of independent projects SEQUENTIALLY, composing ``run_project``
|
||||
as-is (every project's execution state — meter, debate, retrieval context — is built fresh
|
||||
|
|
@ -632,6 +641,7 @@ async def run_portfolio(
|
|||
max_tokens=max_tokens,
|
||||
top_k=top_k,
|
||||
semantic_retrieval=semantic_retrieval,
|
||||
embedder=embedder,
|
||||
meter=meter_factory() if meter_factory is not None else None,
|
||||
),
|
||||
)
|
||||
|
|
@ -671,6 +681,13 @@ def main(argv: list[str] | None = None) -> int:
|
|||
help="fail-fast dimension scope config (JSON): scopes the run to one cost axis; a "
|
||||
"missing or malformed file refuses the run (authoritative startup config, not a RAW inbox)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--embedder-config",
|
||||
default=None,
|
||||
help='fail-fast embedder config (JSON, e.g. {"type": "fake"}): selects the embedder '
|
||||
"used by --semantic-retrieval from a CLOSED registry. Not an import path — a config file "
|
||||
"can never name arbitrary code to load (a new embedder is added as a registry branch)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--outbox-dir",
|
||||
default=None,
|
||||
|
|
@ -761,6 +778,7 @@ def main(argv: list[str] | None = None) -> int:
|
|||
"--run-id": args.run_id is not None,
|
||||
"--dimension-config": args.dimension_config is not None,
|
||||
"--semantic-retrieval": args.semantic_retrieval,
|
||||
"--embedder-config": args.embedder_config is not None,
|
||||
}
|
||||
if any(report_forbidden.values()):
|
||||
print(
|
||||
|
|
@ -824,12 +842,18 @@ def main(argv: list[str] | None = None) -> int:
|
|||
goals = load_goal_config(args.goals) if args.goals else None
|
||||
ledger = SavingsLedger.load(args.ledger) if args.ledger else None
|
||||
dimension = load_dimension(args.dimension_config) if args.dimension_config else None
|
||||
embedder = (
|
||||
build_embedder(load_embedder_config(args.embedder_config))
|
||||
if args.embedder_config
|
||||
else None
|
||||
)
|
||||
project_ids = (args.project_id,) if args.project_id is not None else None
|
||||
portfolio_result = asyncio.run(
|
||||
run_portfolio(
|
||||
project_ids,
|
||||
args.profile,
|
||||
dimension=dimension,
|
||||
embedder=embedder,
|
||||
ledger=ledger,
|
||||
goals=goals,
|
||||
semantic_retrieval=args.semantic_retrieval,
|
||||
|
|
@ -902,6 +926,11 @@ def main(argv: list[str] | None = None) -> int:
|
|||
dimension=(
|
||||
load_dimension(args.dimension_config) if args.dimension_config else None
|
||||
),
|
||||
embedder=(
|
||||
build_embedder(load_embedder_config(args.embedder_config))
|
||||
if args.embedder_config
|
||||
else None
|
||||
),
|
||||
outbox_dir=args.outbox_dir,
|
||||
run_id=args.run_id,
|
||||
verdict_input={"decision": args.decision, "rationale": args.rationale},
|
||||
|
|
@ -943,6 +972,11 @@ def main(argv: list[str] | None = None) -> int:
|
|||
dimension=(
|
||||
load_dimension(args.dimension_config) if args.dimension_config else None
|
||||
),
|
||||
embedder=(
|
||||
build_embedder(load_embedder_config(args.embedder_config))
|
||||
if args.embedder_config
|
||||
else None
|
||||
),
|
||||
outbox_dir=args.outbox_dir,
|
||||
run_id=args.run_id,
|
||||
verdict_input={"decision": args.decision, "rationale": args.rationale},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue