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:
co-authored by
Claude Sonnet 5.5
parent
a931d59d93
commit
a577ff0af3
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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"]]
|
||||
|
||||
@@ -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)"]
|
||||
|
||||
Reference in New Issue
Block a user