Skip to content

Commit fa4086d

Browse files
aksOpsclaude
andcommitted
build: regenerate dist bundles after Wave 3 examples strip
Bundles shrink (-81 lines net) reflecting the deleted per-app config.py, __main__.py, __init__.py, and code_review/ui.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 20ad4f5 commit fa4086d

4 files changed

Lines changed: 256 additions & 337 deletions

File tree

dist/app.py

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,25 @@ class AppConfig(BaseModel):
12851285
orchestrator: OrchestratorConfig = Field(default_factory=OrchestratorConfig)
12861286
runtime: RuntimeConfig = Field(default_factory=RuntimeConfig)
12871287
ui: UIConfig = Field(default_factory=UIConfig)
1288+
# Cross-cutting framework knobs (confidence threshold, escalation
1289+
# roster, severity aliases, dedup prompt, intake tuning) read by
1290+
# the runtime directly off the loaded ``AppConfig`` — no
1291+
# app-specific provider callable required. Apps configure these
1292+
# under the ``framework:`` block of their YAML; tests build them
1293+
# in code via ``FrameworkAppConfig(...)``. Defaults are framework-
1294+
# neutral so unconfigured apps still validate cleanly.
1295+
framework: FrameworkAppConfig = Field(default_factory=FrameworkAppConfig)
1296+
# Two-stage dedup pipeline shape. Typed as ``Any`` because
1297+
# ``DedupConfig`` lives in ``runtime.dedup`` and importing it here
1298+
# would introduce a circular import (``runtime.dedup`` ->
1299+
# ``runtime.config``). The ``_coerce_dedup`` validator below
1300+
# promotes a raw dict (the YAML shape) to a real ``DedupConfig``;
1301+
# callers reading ``cfg.dedup`` get the typed object.
1302+
dedup: Any | None = None
1303+
# App-specific environments roster surfaced on the UI's
1304+
# ``GET /environments`` endpoint and the env selector. Empty list
1305+
# means "this app doesn't expose environments".
1306+
environments: list[str] = Field(default_factory=list)
12881307
# Declarative trigger registry. Each entry is one transport-flavoured
12891308
# ``TriggerConfig`` (api/webhook/schedule/plugin). Typed as
12901309
# ``list[Any]`` because Pydantic v2's discriminated-union binding
@@ -1293,6 +1312,23 @@ class AppConfig(BaseModel):
12931312
# promotes raw dicts to the proper TriggerConfig variants.
12941313
triggers: list[Any] = Field(default_factory=list)
12951314

1315+
@model_validator(mode="after")
1316+
def _coerce_dedup(self) -> "AppConfig":
1317+
# Lazy import to avoid the circular dep with ``runtime.dedup``
1318+
# (which imports things that re-import ``runtime.config``).
1319+
1320+
if self.dedup is None:
1321+
return self
1322+
if isinstance(self.dedup, DedupConfig):
1323+
return self
1324+
if isinstance(self.dedup, dict):
1325+
self.__dict__["dedup"] = DedupConfig(**self.dedup)
1326+
return self
1327+
raise ValueError(
1328+
f"app.dedup must be a DedupConfig or dict; got "
1329+
f"{type(self.dedup).__name__}"
1330+
)
1331+
12961332
@model_validator(mode="after")
12971333
def _coerce_triggers(self) -> "AppConfig":
12981334
# Lazy import inside the validator to avoid a circular import:
@@ -4360,9 +4396,15 @@ async def build_graph(*, cfg: AppConfig, skills: dict, store: SessionStore,
43604396
f"(known: {sorted(skills.keys())})"
43614397
)
43624398
if framework_cfg is None:
4363-
framework_cfg = resolve_framework_app_config(
4364-
getattr(cfg.runtime, "framework_app_config_path", None),
4365-
)
4399+
# Prefer the YAML-driven ``AppConfig.framework`` field; fall
4400+
# back to the legacy provider-callable path for backward
4401+
# compatibility with deployments that still wire it.
4402+
if getattr(cfg.runtime, "framework_app_config_path", None) is not None:
4403+
framework_cfg = resolve_framework_app_config(
4404+
cfg.runtime.framework_app_config_path,
4405+
)
4406+
else:
4407+
framework_cfg = getattr(cfg, "framework", None) or resolve_framework_app_config(None)
43664408
gated_edges = _collect_gated_edges(skills)
43674409

43684410
sg = StateGraph(GraphState)
@@ -7028,14 +7070,19 @@ async def create(cls, cfg: AppConfig) -> "Orchestrator":
70287070
stack = AsyncExitStack()
70297071
await stack.__aenter__()
70307072
try:
7031-
# Cross-cutting framework knobs come from the dotted-path
7032-
# provider on RuntimeConfig.framework_app_config_path. When
7033-
# unset the runtime falls back to a bare FrameworkAppConfig()
7034-
# so unit tests that build an AppConfig without an app-side
7035-
# provider keep working.
7036-
framework_cfg = resolve_framework_app_config(
7037-
cfg.runtime.framework_app_config_path,
7038-
)
7073+
# Cross-cutting framework knobs read directly off
7074+
# ``AppConfig.framework`` — the YAML carries them under the
7075+
# ``framework:`` block, no app-specific provider callable.
7076+
# Falls back to the dotted-path provider for backward
7077+
# compatibility with deployments that still wire it (the
7078+
# provider, when set, wins over the YAML default since
7079+
# historical configs relied on it).
7080+
if cfg.runtime.framework_app_config_path is not None:
7081+
framework_cfg = resolve_framework_app_config(
7082+
cfg.runtime.framework_app_config_path,
7083+
)
7084+
else:
7085+
framework_cfg = cfg.framework
70397086
# Resolve the app state class once. ``None`` (default) keeps the
70407087
# framework-default ``Session`` shape; apps point this at e.g.
70417088
# ``examples.incident_management.state.IncidentState`` via YAML.
@@ -7146,13 +7193,18 @@ async def create(cls, cfg: AppConfig) -> "Orchestrator":
71467193
# about it. Production deployments with a real registry hit
71477194
# the strict validation path.
71487195
#
7149-
# The DedupConfig comes through a generic provider hook
7150-
# (``RuntimeConfig.dedup_config_path``) — the runtime never
7151-
# imports an app-specific config to discover dedup settings.
7196+
# DedupConfig is now a first-class field on ``AppConfig``
7197+
# (read from the YAML's top-level ``dedup:`` block). The
7198+
# legacy provider-callable path is honoured when set so
7199+
# existing deployments don't break, but the YAML wins for
7200+
# bare apps.
71527201
dedup_pipeline: DedupPipeline | None = None
7153-
dedup_cfg: DedupConfig | None = _resolve_dedup_config(
7154-
cfg.runtime.dedup_config_path,
7155-
)
7202+
if cfg.runtime.dedup_config_path is not None:
7203+
dedup_cfg: DedupConfig | None = _resolve_dedup_config(
7204+
cfg.runtime.dedup_config_path,
7205+
)
7206+
else:
7207+
dedup_cfg = cfg.dedup
71567208
if dedup_cfg is not None and dedup_cfg.enabled:
71577209
if dedup_cfg.stage2_model in cfg.llm.models:
71587210
_llm_cfg_capture = cfg.llm
@@ -7754,11 +7806,15 @@ async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
77547806
app.state.orchestrator = orch
77557807
# Environments roster is app-specific (incident-management has
77567808
# production/staging/dev/local; code-review doesn't expose one).
7757-
# Resolve via the generic provider hook so the runtime never
7758-
# imports an app config module.
7759-
app.state.environments = _resolve_environments(
7760-
getattr(cfg.runtime, "environments_provider_path", None),
7761-
)
7809+
# Read it from the YAML's top-level ``environments:`` block;
7810+
# fall back to the legacy ``environments_provider_path`` callable
7811+
# for deployments that still wire it.
7812+
if cfg.environments:
7813+
app.state.environments = list(cfg.environments)
7814+
else:
7815+
app.state.environments = _resolve_environments(
7816+
getattr(cfg.runtime, "environments_provider_path", None),
7817+
)
77627818

77637819
# ------------------------------------------------------------
77647820
# Build & start the trigger registry

0 commit comments

Comments
 (0)