symfonic.capabilities.memory.phases.procedural_llm¶
procedural_llm ¶
Phase 12's other extractor: ask a model which procedures repeat.
Split from :mod:.procedural because that module crossed its 300-line budget
on the way into this package, and this is the split the code already draws --
one extractor reads patterns with a regex, the other asks a model, and they
share only the draft-writing tail.
v7.6 adopter Ask 9 Option A: either-or dispatch. When an extractor is supplied it runs instead of the regex one; the eval rejected merged streams.
run_llm_extractor
async
¶
run_llm_extractor(llm_extractor: Any, procedural_layer: ProceduralLayer, scope: TenantScope, *, recent_episodes: list[MemoryEntry], max_drafts_per_run: int, model_name: str, promote_assistant_content: bool = False, gate: DurabilityGate | None = None) -> int
Run the LLM-backed procedural extractor and write its drafts.
Mirrors the regex extractor's tail (existing-skill snapshot ->
store_skill loop -> dedup-collision count -> summary log line)
so SRE telemetry can compare the two paths apples-to-apples and
consumers can flip phase_12_use_llm_extractor without changing
their log parsers.
The Phase 12 LLM summary log line carries:
Phase 12 LLM: tenant=<id> drafts_emitted=K drafts_kept=K' \
drafts_rejected_by_dedup=K'' max_drafts=N model=<name> \
cost_usd=<calc-or-0>
cost_usd is best-effort: when the extractor returns 0 drafts on
a failed model call the helper still emits a summary line so
consumers can distinguish "no signal" from "extractor crashed
silently" (matches the v7.4.8 rationale on the regex extractor).
Source code in src/symfonic/capabilities/memory/phases/procedural_llm.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |