fix: a turned-off loaded module is not called gone; route and probe provider failures said by provider, once, truthfully; expansion note names shortcuts (attacker round 22)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-15 23:46:54 +03:00
co-authored by Claude Sonnet 5.5
parent a931d59d93
commit a577ff0af3
6 changed files with 34 additions and 9 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ export async function buildInputs({ project, scene, slots, expand, frames, hooks
if (!(body && typeof body.text === "string")) failedExpand = true;
}
// Features that add inputs of their own (a Chat comment for the enhancer, say) say so through a hook: { inputs: {slot: {name: value}}, notes: [text] }.
const notes = failedExpand ? ["The prompt could not be expanded ($variables, anchor, postfix): the text was sent as typed."] : [];
const notes = failedExpand ? ["The prompt could not be expanded (shortcuts, $variables, anchor, postfix): the text was sent as typed."] : [];
for (const hook of hooks) {
let out;
try { out = (await hook({ project, scene, slots })) || {}; } catch (err) { notes.push(`An add-on's input could not be added to this run: ${err.message}`); continue; }
+2 -1
View File
@@ -204,7 +204,8 @@ def partition(specs: Iterable, settings) -> Tuple[List, List[str]]:
"""(kept, notes): `specs` without the ones the project turned off or that are quarantined."""
specs = list(specs)
off, everything = off_by_project(settings), all_off(settings)
known = {s.id for s in specs}
from . import registry
known = {s.id for s in specs} | set(registry.current().specs) # the list passed in is filtered (traits, capability); "loaded" is the registry
for gone in sorted(off - known): # a saved "turn this module off" for a module that is no longer loaded
log.once(f"stale_off:{gone}", log.WARNING, "FunPack modules",
f"{gone!r} is turned off in this project's settings, but no module with that id is loaded: ignored")
+2 -2
View File
@@ -111,7 +111,7 @@ def detect(path: Path, registry=None) -> dict:
matched = claims(keyset)
except Exception as exc: # noqa: BLE001
from . import log
log.failed(f"{spec.id}.detect", exc)
log.once(f"provider:{spec.id}.detect:{type(exc).__name__}", log.WARNING, f"{spec.id}.detect", f"failed while answering -- {type(exc).__name__}: {exc}")
continue
if matched:
traits = None # unknown, not empty: a module that never says hides nothing
@@ -121,7 +121,7 @@ def detect(path: Path, registry=None) -> dict:
traits = list(probe_traits(keyset))
except Exception as exc: # noqa: BLE001
from . import log
log.failed(f"{spec.id}.probe_traits", exc)
log.once(f"provider:{spec.id}.probe_traits:{type(exc).__name__}", log.WARNING, f"{spec.id}.probe_traits", f"failed while answering -- {type(exc).__name__}: {exc}")
return {"module": spec.id, "title": spec.title, "detected": True,
"reason": f"{p.name}: {spec.title}", "traits": traits}
return {"module": None, "title": None, "detected": False,
+6 -5
View File
@@ -116,9 +116,10 @@ def modules(rescan=False):
return registry_mod.current(rescan)
def _provider_failed(what, exc):
def _provider_failed(what, exc, spec=None):
"""A provider raised while answering: said once per provider and kind of error, then skipped."""
log.once(f"provider:{what}:{type(exc).__name__}", log.WARNING, what, f"failed while answering -- {type(exc).__name__}: {exc}")
who = f"{what} ({spec.id})" if spec is not None else what
log.once(f"provider:{who}:{type(exc).__name__}", log.WARNING, who, f"failed while answering -- {type(exc).__name__}: {exc}")
def settings_sinks():
@@ -128,7 +129,7 @@ def settings_sinks():
try:
sink = make()
except Exception as exc: # noqa: BLE001
_provider_failed("settings_sink", exc)
_provider_failed("settings_sink", exc, _spec)
continue
if isinstance(sink, dict) and sink.get("node") and sink.get("input"):
found.append({"node": sink["node"], "input": sink["input"]})
@@ -268,7 +269,7 @@ def register(routes, prefix=None):
try:
offered = make()
except Exception as exc: # noqa: BLE001
_provider_failed("pipeline_presets", exc)
_provider_failed("pipeline_presets", exc, spec)
continue
for preset in (offered or []):
if isinstance(preset, dict) and preset.get("id") and preset.get("slots"):
@@ -306,7 +307,7 @@ def register(routes, prefix=None):
try:
presets += list(make() or [])
except Exception as exc: # noqa: BLE001
_provider_failed("pipeline_presets", exc)
_provider_failed("pipeline_presets", exc, _spec)
reg = modules()
rows = readiness.machine(sysinfo.collect().get("disk", {}).get("free_gb"))
rows += readiness.models(counts)
+12
View File
@@ -139,3 +139,15 @@ def test_a_saved_turn_off_for_a_module_that_is_gone_is_said_once():
control.partition([spec("b")], {"_off": {"modules": ["gone"]}})
said = [r for r in log.history() if "'gone'" in r["message"]]
assert len(said) == 1 and "ignored" in said[0]["message"]
def test_a_turned_off_module_that_is_loaded_but_not_in_the_filtered_list_is_not_called_gone(monkeypatch):
"""Callers pass a filtered list (by capability, by the model's traits); "gone" means absent from the registry."""
from core import log, registry
log._reset()
reg = registry.Registry()
reg.specs["sharpen"] = spec("sharpen")
monkeypatch.setattr(registry, "current", lambda rescan=False: reg)
control.partition([spec("other")], {"_off": {"modules": ["sharpen"]}})
control.partition([spec("other")], {"_off": {"all": True}})
assert not [r for r in log.history() if "no module with that id" in r["message"]]
+11
View File
@@ -300,3 +300,14 @@ def test_a_duplicate_id_is_said_in_the_log_not_only_in_settings():
reg.add(validate({"id": "dup", "title": "A", "mount": "m"}, source="one"))
reg.add(validate({"id": "dup", "title": "B", "mount": "m"}, source="two"))
assert any("duplicate id" in r["message"] for r in log.history())
def test_route_providers_that_raise_are_said_by_name_once_each():
from core import log, routes
log._reset()
a = type("S", (), {"id": "mod_a"})()
b = type("S", (), {"id": "mod_b"})()
for s in (a, b, a, b):
routes._provider_failed("settings_sink", KeyError("x"), s)
said = [r for r in log.history() if "failed while answering" in r["message"]]
assert sorted(r["source"] for r in said) == ["settings_sink (mod_a)", "settings_sink (mod_b)"]