symfonic.capabilities.extensions.legacy_prompts¶
legacy_prompts ¶
Reading a legacy plugin's prompt hook (T4.2.2).
Split from the bridge because it is the only asynchronous, per-turn, failure- prone part of reading a plugin: identity, tool refusal, policy, and lifecycle are all settled once at construction, and this runs on every render.
The containment envelope is inherited deliberately from the pre-refactor dispatcher — a misbehaving plugin is skipped, never propagated, because a plugin's bug must not become the agent's outage. What changes is that each skip now emits a value. Previously the dispatcher logged at DEBUG and returned an empty list, so "this plugin had nothing to say" and "this plugin raised" were the same reading of a turn. Here they differ by a diagnostic.
Severity is what makes that value reach an operator. Anything that costs a
fragment its place in the turn — a hook that raised, a hook that answered a
non-list, a position outside the vocabulary, a position='kernel' claim on the
layer AS-INT-3 reserves — is recorded at Severity.ERROR, because
:attr:~.composition.ComposedExtensions.refusals is the ERROR-severity subset
and that is the tuple ExtensionsCapability.contribute's handler logs at
WARNING. A diagnostic recorded below ERROR is a value nobody is told about; the
truncation note is deliberately one of those, because the fragment still lands.
Two mappings are performed and both are recorded rather than assumed:
position→layer.cached → l1,volatile → l2,kernel → l1with a diagnostic. The kernel remap matches the legacy dispatcher's, and is still correct for a different reason: L0 is the kernel's instruction layer and no extension may write it (AS-INT-3).- everything → the
profiletier. A plugin's output is untrusted input (AS-INT-1); it used to render into the cached prefix beside operator instructions with no tier at all.
LegacyPromptReader ¶
Calls one plugin's prompt hook and maps what it answered.
Source code in src/symfonic/capabilities/extensions/legacy_prompts.py
read
async
¶
Harvest this turn's fragments, resetting the diagnostics first.