@graphrefly/graphrefly 0.47.1 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base/composition/index.cjs +28 -19
- package/dist/base/composition/index.cjs.map +1 -1
- package/dist/base/composition/index.d.cts +14 -5
- package/dist/base/composition/index.d.ts +14 -5
- package/dist/base/composition/index.js +9 -9
- package/dist/base/index.cjs +294 -164
- package/dist/base/index.cjs.map +1 -1
- package/dist/base/index.d.cts +2 -2
- package/dist/base/index.d.ts +2 -2
- package/dist/base/index.js +77 -72
- package/dist/base/io/index.cjs +145 -85
- package/dist/base/io/index.cjs.map +1 -1
- package/dist/base/io/index.d.cts +32 -5
- package/dist/base/io/index.d.ts +32 -5
- package/dist/base/io/index.js +5 -5
- package/dist/base/mutation/index.cjs +21 -0
- package/dist/base/mutation/index.cjs.map +1 -1
- package/dist/base/mutation/index.d.cts +23 -1
- package/dist/base/mutation/index.d.ts +23 -1
- package/dist/base/mutation/index.js +3 -1
- package/dist/base/sources/browser/index.cjs +18 -12
- package/dist/base/sources/browser/index.cjs.map +1 -1
- package/dist/base/sources/browser/index.d.cts +20 -2
- package/dist/base/sources/browser/index.d.ts +20 -2
- package/dist/base/sources/browser/index.js +18 -12
- package/dist/base/sources/browser/index.js.map +1 -1
- package/dist/base/sources/event/index.cjs +29 -1
- package/dist/base/sources/event/index.cjs.map +1 -1
- package/dist/base/sources/event/index.d.cts +67 -3
- package/dist/base/sources/event/index.d.ts +67 -3
- package/dist/base/sources/event/index.js +5 -2
- package/dist/base/sources/index.cjs +96 -50
- package/dist/base/sources/index.cjs.map +1 -1
- package/dist/base/sources/index.d.cts +1 -1
- package/dist/base/sources/index.d.ts +1 -1
- package/dist/base/sources/index.js +7 -4
- package/dist/base/sources/node/index.cjs +43 -37
- package/dist/base/sources/node/index.cjs.map +1 -1
- package/dist/base/sources/node/index.js +43 -37
- package/dist/base/sources/node/index.js.map +1 -1
- package/dist/{chunk-J5WFUEO4.js → chunk-23MAWVOJ.js} +3 -3
- package/dist/{chunk-YXCPV26R.js → chunk-3REMCHSS.js} +39 -27
- package/dist/chunk-3REMCHSS.js.map +1 -0
- package/dist/{chunk-CEVNQ74M.js → chunk-3YGXPUHW.js} +2 -2
- package/dist/{chunk-CEVNQ74M.js.map → chunk-3YGXPUHW.js.map} +1 -1
- package/dist/{chunk-EVYY4X5A.js → chunk-46X2EFQH.js} +16 -5
- package/dist/chunk-46X2EFQH.js.map +1 -0
- package/dist/{chunk-NY2PYHNC.js → chunk-5UY3PNFY.js} +12 -5
- package/dist/chunk-5UY3PNFY.js.map +1 -0
- package/dist/{chunk-RGMTUZCL.js → chunk-65OM4XLQ.js} +50 -4
- package/dist/chunk-65OM4XLQ.js.map +1 -0
- package/dist/{chunk-3PSLNJDU.js → chunk-6DQYBIHW.js} +314 -49
- package/dist/chunk-6DQYBIHW.js.map +1 -0
- package/dist/{chunk-LDCSZ72P.js → chunk-6YBER5UP.js} +3 -3
- package/dist/{chunk-LDCSZ72P.js.map → chunk-6YBER5UP.js.map} +1 -1
- package/dist/{chunk-7EGRP2VX.js → chunk-7BULJTL6.js} +2 -2
- package/dist/{chunk-7EGRP2VX.js.map → chunk-7BULJTL6.js.map} +1 -1
- package/dist/{chunk-VLAGJZSL.js → chunk-7T7WLEPM.js} +25 -4
- package/dist/chunk-7T7WLEPM.js.map +1 -0
- package/dist/{chunk-PKPO3JTZ.js → chunk-AQAKDE7F.js} +29 -11
- package/dist/chunk-AQAKDE7F.js.map +1 -0
- package/dist/{chunk-2OB3CEJS.js → chunk-B5Y5GPD5.js} +2 -2
- package/dist/{chunk-BXGZFGZ4.js → chunk-C5QD5DQX.js} +22 -1
- package/dist/chunk-C5QD5DQX.js.map +1 -0
- package/dist/{chunk-4XCHZRUJ.js → chunk-D5YGR4TP.js} +58 -7
- package/dist/chunk-D5YGR4TP.js.map +1 -0
- package/dist/{chunk-NPRP3MCV.js → chunk-DHDCOOJU.js} +2 -2
- package/dist/chunk-DHDCOOJU.js.map +1 -0
- package/dist/{chunk-MTTRCEJT.js → chunk-DVTDF5OI.js} +2 -2
- package/dist/{chunk-SOOKUYVM.js → chunk-F7EKHR32.js} +13 -9
- package/dist/chunk-F7EKHR32.js.map +1 -0
- package/dist/{chunk-A7KV5UK4.js → chunk-G7H6PN7P.js} +2 -2
- package/dist/{chunk-OCUDSN63.js → chunk-GGKHHG5Y.js} +110 -64
- package/dist/chunk-GGKHHG5Y.js.map +1 -0
- package/dist/{chunk-RAGGHLCV.js → chunk-GUNIRPEJ.js} +8 -6
- package/dist/{chunk-RAGGHLCV.js.map → chunk-GUNIRPEJ.js.map} +1 -1
- package/dist/{chunk-YJ4U2D2C.js → chunk-J5TBZFBD.js} +9 -7
- package/dist/chunk-J5TBZFBD.js.map +1 -0
- package/dist/{chunk-Y52CS6YA.js → chunk-JA67ZQG2.js} +2 -2
- package/dist/{chunk-Y52CS6YA.js.map → chunk-JA67ZQG2.js.map} +1 -1
- package/dist/{chunk-U225SKB4.js → chunk-K4ZYJ4EM.js} +569 -424
- package/dist/chunk-K4ZYJ4EM.js.map +1 -0
- package/dist/{chunk-Z4YXAUDN.js → chunk-KUFXLAEY.js} +11 -7
- package/dist/{chunk-Z4YXAUDN.js.map → chunk-KUFXLAEY.js.map} +1 -1
- package/dist/{chunk-IHTWQEDR.js → chunk-LTSI7ULC.js} +3 -3
- package/dist/{chunk-IHTWQEDR.js.map → chunk-LTSI7ULC.js.map} +1 -1
- package/dist/{chunk-DKNHAICT.js → chunk-MMHGYX44.js} +25 -9
- package/dist/chunk-MMHGYX44.js.map +1 -0
- package/dist/{chunk-K7PDZYQE.js → chunk-MQMTRKY3.js} +129 -50
- package/dist/chunk-MQMTRKY3.js.map +1 -0
- package/dist/{chunk-42FQ27MQ.js → chunk-MTODGQBR.js} +44 -179
- package/dist/chunk-MTODGQBR.js.map +1 -0
- package/dist/{chunk-O3MT7DYI.js → chunk-N6MNJNHB.js} +2 -2
- package/dist/{chunk-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
- package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
- package/dist/{chunk-DM4OMPWK.js → chunk-NSA5K5G2.js} +2 -2
- package/dist/{chunk-MLTPJMH6.js → chunk-QQYULEZL.js} +2 -2
- package/dist/chunk-QSW4DFKE.js +31 -0
- package/dist/chunk-QSW4DFKE.js.map +1 -0
- package/dist/{chunk-PZWISPIQ.js → chunk-S7HN5FHL.js} +17 -11
- package/dist/chunk-S7HN5FHL.js.map +1 -0
- package/dist/{chunk-4S53H2KR.js → chunk-SUNCHMML.js} +2 -2
- package/dist/{chunk-4GYMCUDZ.js → chunk-T2U6N3FV.js} +7 -7
- package/dist/{chunk-RJOG4IJU.js → chunk-T5URUIIY.js} +50 -35
- package/dist/chunk-T5URUIIY.js.map +1 -0
- package/dist/{chunk-B4AKFXGE.js → chunk-TPTZZV25.js} +6 -6
- package/dist/chunk-TPTZZV25.js.map +1 -0
- package/dist/{chunk-BU3SEFA5.js → chunk-V46JWFGV.js} +7 -6
- package/dist/chunk-V46JWFGV.js.map +1 -0
- package/dist/{chunk-IJRR6YAI.js → chunk-VLDRAMP7.js} +18 -12
- package/dist/chunk-VLDRAMP7.js.map +1 -0
- package/dist/{chunk-6XZYT4SW.js → chunk-X6ESZDR6.js} +8 -9
- package/dist/chunk-X6ESZDR6.js.map +1 -0
- package/dist/{chunk-E5OZPDIW.js → chunk-X7BA5PWG.js} +7 -5
- package/dist/chunk-X7BA5PWG.js.map +1 -0
- package/dist/{chunk-CXANAIZU.js → chunk-XEWV254I.js} +3 -3
- package/dist/{chunk-CXANAIZU.js.map → chunk-XEWV254I.js.map} +1 -1
- package/dist/{chunk-V4Y3TM7U.js → chunk-YBJVKMTM.js} +38 -16
- package/dist/chunk-YBJVKMTM.js.map +1 -0
- package/dist/{chunk-7ADWWI2T.js → chunk-ZW32BPXV.js} +17 -6
- package/dist/chunk-ZW32BPXV.js.map +1 -0
- package/dist/compat/index.cjs +52 -5
- package/dist/compat/index.cjs.map +1 -1
- package/dist/compat/index.d.cts +1 -1
- package/dist/compat/index.d.ts +1 -1
- package/dist/compat/index.js +7 -7
- package/dist/compat/nestjs/index.cjs +52 -5
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +1 -1
- package/dist/compat/nestjs/index.d.ts +1 -1
- package/dist/compat/nestjs/index.js +4 -4
- package/dist/{fallback-Bx46zqky.d.cts → fallback-BROR6ZhO.d.cts} +1 -1
- package/dist/{fallback-pIWW8A2d.d.ts → fallback-DO80aM_3.d.ts} +1 -1
- package/dist/{index-B_p8tnvf.d.cts → index-D1z3XcF9.d.cts} +1 -0
- package/dist/{index-_HDSmPyp.d.ts → index-DZ6yua0Q.d.ts} +1 -0
- package/dist/index.cjs +2387 -1707
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +173 -150
- package/dist/index.js.map +1 -1
- package/dist/presets/ai/index.cjs +88 -26
- package/dist/presets/ai/index.cjs.map +1 -1
- package/dist/presets/ai/index.js +14 -14
- package/dist/presets/harness/index.cjs +183 -51
- package/dist/presets/harness/index.cjs.map +1 -1
- package/dist/presets/harness/index.d.cts +15 -5
- package/dist/presets/harness/index.d.ts +15 -5
- package/dist/presets/harness/index.js +26 -26
- package/dist/presets/index.cjs +298 -101
- package/dist/presets/index.cjs.map +1 -1
- package/dist/presets/index.d.cts +2 -2
- package/dist/presets/index.d.ts +2 -2
- package/dist/presets/index.js +49 -49
- package/dist/presets/inspect/index.cjs +63 -14
- package/dist/presets/inspect/index.cjs.map +1 -1
- package/dist/presets/inspect/index.d.cts +1 -1
- package/dist/presets/inspect/index.d.ts +1 -1
- package/dist/presets/inspect/index.js +6 -6
- package/dist/presets/resilience/index.cjs +64 -44
- package/dist/presets/resilience/index.cjs.map +1 -1
- package/dist/presets/resilience/index.d.cts +12 -8
- package/dist/presets/resilience/index.d.ts +12 -8
- package/dist/presets/resilience/index.js +6 -6
- package/dist/{rate-limiter-DpVbSYdH.d.cts → rate-limiter-DC26FM8J.d.cts} +10 -1
- package/dist/{rate-limiter-CEALq4N1.d.ts → rate-limiter-DyWpwpQP.d.ts} +10 -1
- package/dist/{reactive-layout-fswlBUvX.d.ts → reactive-layout-BBBWH0V_.d.cts} +85 -4
- package/dist/{reactive-layout-fswlBUvX.d.cts → reactive-layout-BBBWH0V_.d.ts} +85 -4
- package/dist/solutions/index.cjs +239 -92
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +2 -2
- package/dist/solutions/index.d.ts +2 -2
- package/dist/solutions/index.js +32 -32
- package/dist/{spawnable-5mDY501F.d.cts → spawnable-B2IlW60f.d.cts} +23 -2
- package/dist/{spawnable-D3lR0oQu.d.ts → spawnable-tttFz2Nh.d.ts} +23 -2
- package/dist/testing/index.cjs +94 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +59 -0
- package/dist/testing/index.d.ts +59 -0
- package/dist/testing/index.js +73 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/{timeout-U5O4ESK3.js → timeout-BEABACRP.js} +2 -2
- package/dist/utils/ai/browser.cjs.map +1 -1
- package/dist/utils/ai/browser.d.cts +2 -2
- package/dist/utils/ai/browser.d.ts +2 -2
- package/dist/utils/ai/browser.js +10 -10
- package/dist/utils/ai/browser.js.map +1 -1
- package/dist/utils/ai/index.cjs +291 -191
- package/dist/utils/ai/index.cjs.map +1 -1
- package/dist/utils/ai/index.d.cts +108 -12
- package/dist/utils/ai/index.d.ts +108 -12
- package/dist/utils/ai/index.js +23 -21
- package/dist/utils/ai/node.cjs.map +1 -1
- package/dist/utils/ai/node.d.cts +5 -5
- package/dist/utils/ai/node.d.ts +5 -5
- package/dist/utils/ai/node.js +3 -3
- package/dist/utils/ai/node.js.map +1 -1
- package/dist/utils/cqrs/index.cjs +29 -3
- package/dist/utils/cqrs/index.cjs.map +1 -1
- package/dist/utils/cqrs/index.d.cts +12 -7
- package/dist/utils/cqrs/index.d.ts +12 -7
- package/dist/utils/cqrs/index.js +2 -2
- package/dist/utils/demo-shell/index.cjs +45 -19
- package/dist/utils/demo-shell/index.cjs.map +1 -1
- package/dist/utils/demo-shell/index.d.cts +1 -1
- package/dist/utils/demo-shell/index.d.ts +1 -1
- package/dist/utils/demo-shell/index.js +2 -2
- package/dist/utils/domain-templates/index.cjs +1 -1
- package/dist/utils/domain-templates/index.cjs.map +1 -1
- package/dist/utils/domain-templates/index.js +3 -3
- package/dist/utils/graphspec/index.cjs +1 -1
- package/dist/utils/graphspec/index.cjs.map +1 -1
- package/dist/utils/graphspec/index.js +3 -3
- package/dist/utils/harness/index.cjs +16 -10
- package/dist/utils/harness/index.cjs.map +1 -1
- package/dist/utils/harness/index.js +1 -1
- package/dist/utils/index.cjs +1692 -1192
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +7 -7
- package/dist/utils/index.d.ts +7 -7
- package/dist/utils/index.js +77 -59
- package/dist/utils/inspect/index.cjs +52 -4
- package/dist/utils/inspect/index.cjs.map +1 -1
- package/dist/utils/inspect/index.d.cts +32 -3
- package/dist/utils/inspect/index.d.ts +32 -3
- package/dist/utils/inspect/index.js +4 -4
- package/dist/utils/job-queue/index.cjs +46 -9
- package/dist/utils/job-queue/index.cjs.map +1 -1
- package/dist/utils/job-queue/index.d.cts +33 -3
- package/dist/utils/job-queue/index.d.ts +33 -3
- package/dist/utils/job-queue/index.js +2 -2
- package/dist/utils/memory/index.cjs +570 -425
- package/dist/utils/memory/index.cjs.map +1 -1
- package/dist/utils/memory/index.d.cts +261 -33
- package/dist/utils/memory/index.d.ts +261 -33
- package/dist/utils/memory/index.js +10 -2
- package/dist/utils/messaging/index.cjs.map +1 -1
- package/dist/utils/messaging/index.d.cts +4 -3
- package/dist/utils/messaging/index.d.ts +4 -3
- package/dist/utils/messaging/index.js +2 -2
- package/dist/utils/orchestration/index.cjs +14 -3
- package/dist/utils/orchestration/index.cjs.map +1 -1
- package/dist/utils/orchestration/index.js +3 -3
- package/dist/utils/process/index.cjs +32 -2
- package/dist/utils/process/index.cjs.map +1 -1
- package/dist/utils/process/index.d.cts +4 -3
- package/dist/utils/process/index.d.ts +4 -3
- package/dist/utils/process/index.js +3 -3
- package/dist/utils/reactive-layout/index.cjs +184 -55
- package/dist/utils/reactive-layout/index.cjs.map +1 -1
- package/dist/utils/reactive-layout/index.d.cts +128 -3
- package/dist/utils/reactive-layout/index.d.ts +128 -3
- package/dist/utils/reactive-layout/index.js +16 -8
- package/dist/utils/reduction/index.cjs +1 -1
- package/dist/utils/reduction/index.cjs.map +1 -1
- package/dist/utils/reduction/index.js +2 -2
- package/dist/utils/resilience/index.cjs +64 -43
- package/dist/utils/resilience/index.cjs.map +1 -1
- package/dist/utils/resilience/index.d.cts +1 -1
- package/dist/utils/resilience/index.d.ts +1 -1
- package/dist/utils/resilience/index.js +5 -5
- package/dist/utils/surface/index.cjs +1 -1
- package/dist/utils/surface/index.cjs.map +1 -1
- package/dist/utils/surface/index.js +4 -4
- package/package.json +15 -3
- package/dist/chunk-3PSLNJDU.js.map +0 -1
- package/dist/chunk-42FQ27MQ.js.map +0 -1
- package/dist/chunk-4XCHZRUJ.js.map +0 -1
- package/dist/chunk-6XZYT4SW.js.map +0 -1
- package/dist/chunk-7ADWWI2T.js.map +0 -1
- package/dist/chunk-B4AKFXGE.js.map +0 -1
- package/dist/chunk-BU3SEFA5.js.map +0 -1
- package/dist/chunk-BXGZFGZ4.js.map +0 -1
- package/dist/chunk-DKNHAICT.js.map +0 -1
- package/dist/chunk-E5OZPDIW.js.map +0 -1
- package/dist/chunk-EVYY4X5A.js.map +0 -1
- package/dist/chunk-IJRR6YAI.js.map +0 -1
- package/dist/chunk-K7PDZYQE.js.map +0 -1
- package/dist/chunk-NPRP3MCV.js.map +0 -1
- package/dist/chunk-NY2PYHNC.js.map +0 -1
- package/dist/chunk-OCUDSN63.js.map +0 -1
- package/dist/chunk-PKPO3JTZ.js.map +0 -1
- package/dist/chunk-PZWISPIQ.js.map +0 -1
- package/dist/chunk-RGMTUZCL.js.map +0 -1
- package/dist/chunk-RJOG4IJU.js.map +0 -1
- package/dist/chunk-SOOKUYVM.js.map +0 -1
- package/dist/chunk-U225SKB4.js.map +0 -1
- package/dist/chunk-V4Y3TM7U.js.map +0 -1
- package/dist/chunk-VLAGJZSL.js.map +0 -1
- package/dist/chunk-W2BOPXTI.js +0 -1
- package/dist/chunk-YJ4U2D2C.js.map +0 -1
- package/dist/chunk-YXCPV26R.js.map +0 -1
- package/dist/timeout-U5O4ESK3.js.map +0 -1
- /package/dist/{chunk-J5WFUEO4.js.map → chunk-23MAWVOJ.js.map} +0 -0
- /package/dist/{chunk-2OB3CEJS.js.map → chunk-B5Y5GPD5.js.map} +0 -0
- /package/dist/{chunk-MTTRCEJT.js.map → chunk-DVTDF5OI.js.map} +0 -0
- /package/dist/{chunk-A7KV5UK4.js.map → chunk-G7H6PN7P.js.map} +0 -0
- /package/dist/{chunk-O3MT7DYI.js.map → chunk-N6MNJNHB.js.map} +0 -0
- /package/dist/{chunk-DM4OMPWK.js.map → chunk-NSA5K5G2.js.map} +0 -0
- /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
- /package/dist/{chunk-4S53H2KR.js.map → chunk-SUNCHMML.js.map} +0 -0
- /package/dist/{chunk-4GYMCUDZ.js.map → chunk-T2U6N3FV.js.map} +0 -0
- /package/dist/{chunk-W2BOPXTI.js.map → timeout-BEABACRP.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/ai/agents/chat-stream.ts","../src/utils/ai/_internal.ts","../src/utils/ai/agents/tool-execution.ts","../src/utils/ai/agents/tool-registry.ts","../src/utils/ai/memory/memory-composers.ts","../src/utils/ai/prompts/prompt-node.ts","../src/utils/ai/prompts/prompt-call.ts"],"sourcesContent":["import { type Node, node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../_internal.js\";\nimport type { ChatMessage } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// chatStream\n// ---------------------------------------------------------------------------\n\nexport type ChatStreamOptions = {\n\tgraph?: GraphOptions;\n\tmaxMessages?: number;\n};\n\nexport class ChatStreamGraph extends Graph {\n\tprivate readonly _log: ReactiveLogBundle<ChatMessage>;\n\treadonly messages: Node<readonly ChatMessage[]>;\n\t/**\n\t * Most recently appended message. Stays in the protocol SENTINEL state\n\t * (`cache === undefined`, no DATA emitted) until the first append, then\n\t * tracks the latest entry. Per COMPOSITION-GUIDE §1a, the SENTINEL is\n\t * the canonical \"no value yet\" signal — consumers detect empty via\n\t * `data[i] === undefined` inside reactive fns or `latest.cache === undefined`\n\t * outside. No `T | null` placeholder, no `hasLatest` companion.\n\t */\n\treadonly latest: Node<ChatMessage>;\n\treadonly messageCount: Node<number>;\n\n\tconstructor(name: string, opts: ChatStreamOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._log = reactiveLog<ChatMessage>([], {\n\t\t\tname: \"messages\",\n\t\t\tmaxSize: opts.maxMessages,\n\t\t});\n\t\tthis.messages = this._log.entries;\n\t\tthis.add(this.messages, { name: \"messages\" });\n\n\t\t// SENTINEL on empty (COMPOSITION-GUIDE §1a): return `[]` for\n\t\t// RESOLVED-only on empty stream, `[T]` to emit DATA. `latest.cache`\n\t\t// stays `undefined` until the first append.\n\t\tthis.latest = node<ChatMessage>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst entries = data[0] as readonly ChatMessage[];\n\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(entries[entries.length - 1] as ChatMessage);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"latest\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_latest\"),\n\t\t\t},\n\t\t);\n\t\tthis.add(this.latest, { name: \"latest\" });\n\t\tthis.addDisposer(keepalive(this.latest));\n\n\t\tthis.messageCount = node<number>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly ChatMessage[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"messageCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_message_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.messageCount, { name: \"messageCount\" });\n\t\tthis.addDisposer(keepalive(this.messageCount));\n\t}\n\n\tappend(role: ChatMessage[\"role\"], content: string, extra?: Partial<ChatMessage>): void {\n\t\tthis._log.append({ role, content, ...extra });\n\t}\n\n\tappendToolResult(callId: string, content: string): void {\n\t\tthis._log.append({ role: \"tool\", content, toolCallId: callId });\n\t}\n\n\tclear(): void {\n\t\tthis._log.clear();\n\t}\n\n\tallMessages(): readonly ChatMessage[] {\n\t\treturn this.messages.cache as readonly ChatMessage[];\n\t}\n}\n\nexport function chatStream(name: string, opts?: ChatStreamOptions): ChatStreamGraph {\n\treturn new ChatStreamGraph(name, opts);\n}\n","/**\n * @internal — shared helpers for the AI pattern modules.\n *\n * NOT part of the public API. Consumers reach public symbols through\n * `@graphrefly/graphrefly/patterns/ai` (the barrel).\n *\n * @module\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n} from \"./adapters/core/types.js\";\n\nexport function aiMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"ai\", kind, extra);\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isNodeLike(x: unknown): x is Node<unknown> {\n\treturn (\n\t\ttypeof x === \"object\" &&\n\t\tx !== null &&\n\t\t\"subscribe\" in x &&\n\t\ttypeof (x as Node<unknown>).subscribe === \"function\" &&\n\t\t\"cache\" in x\n\t);\n}\n\nexport function isAsyncIterableLike(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\tSymbol.asyncIterator in x &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** First settled `DATA` from a `Node` (do not pass plain strings — `fromAny` would iterate chars). */\nexport function firstDataFromNode(\n\tresolved: Node<unknown>,\n\topts?: { timeoutMs?: number },\n): Promise<unknown> {\n\tif ((resolved as { status?: string }).status === \"settled\") {\n\t\tconst immediate = resolved.cache;\n\t\tif (immediate !== undefined) {\n\t\t\treturn Promise.resolve(immediate);\n\t\t}\n\t}\n\tconst timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = new ResettableTimer();\n\t\tconst unsub = resolved.subscribe((messages) => {\n\t\t\tfor (const msg of messages) {\n\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\tresolve(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === ERROR) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === COMPLETE) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(new Error(\"firstDataFromNode: completed without producing a value\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\ttimer.start(timeoutMs, () => {\n\t\t\tunsub();\n\t\t\treject(new Error(`firstDataFromNode: timed out after ${timeoutMs}ms`));\n\t\t});\n\t});\n}\n\n/** Await Promise-likes, then resolve `Node` / async-iterable inputs via `fromAny` + first `DATA`. */\nexport async function resolveToolHandlerResult(value: unknown): Promise<unknown> {\n\tif (isPromiseLike(value)) {\n\t\treturn resolveToolHandlerResult(await value);\n\t}\n\tif (isNodeLike(value)) {\n\t\treturn firstDataFromNode(value);\n\t}\n\tif (isAsyncIterableLike(value)) {\n\t\treturn firstDataFromNode(fromAny(value as NodeInput<unknown>));\n\t}\n\treturn value;\n}\n\n/** Strip markdown code fences, handling trailing commentary after closing fence. */\nexport function stripFences(text: string): string {\n\tconst match = text.match(/^```(?:json)?\\s*([\\s\\S]*?)\\s*```[\\s\\S]*$/);\n\treturn match ? match[1]! : text;\n}\n\n/**\n * Bridge-layer failure kind reported to {@link OneShotLlmCallConfig.onFailure}.\n *\n * - `\"throw\"` — synchronous throw from `adapter.invoke()`.\n * - `\"error\"` — `[ERROR, value]` message on the bridged Node.\n * - `\"complete\"` — the bridged Node closed without emitting DATA.\n * - `\"onSuccess-threw\"` — `onSuccess(resp)` itself threw (uncaught parse /\n * builder error). Caller's `onFailure` decides the failure-payload shape.\n */\nexport type OneShotLlmFailureKind = \"throw\" | \"error\" | \"complete\" | \"onSuccess-threw\";\n\n/** Configuration for {@link _oneShotLlmCall}. */\nexport interface OneShotLlmCallConfig<T> {\n\t/**\n\t * Build the success payload from the adapter's first DATA message.\n\t * MAY throw — the helper catches and routes through `onFailure(kind:\n\t * \"onSuccess-threw\", err)` so callers don't need their own try/catch.\n\t */\n\tonSuccess: (resp: LLMResponse) => T;\n\t/**\n\t * Build a failure payload when the bridge layer reports any of the\n\t * {@link OneShotLlmFailureKind} categories. Caller chooses the detail\n\t * string format and any error-class metadata.\n\t */\n\tonFailure: (kind: OneShotLlmFailureKind, err: unknown) => T;\n\t/**\n\t * Forwarded to `adapter.invoke(messages, opts)` — `signal` is set\n\t * by the helper from the producer's AbortController and CANNOT be\n\t * overridden here (cancellation is a hard contract of this helper).\n\t */\n\tinvokeOpts?: Omit<LLMInvokeOptions, \"signal\">;\n\t/**\n\t * Optional parent abort signal (e.g. JobFlow pump's per-claim signal).\n\t * When the parent aborts, the helper aborts its inner AbortController —\n\t * so `adapter.invoke({ signal })` and `fromAny({ signal })` see the\n\t * cascade and cancel in-flight work. Pump-driven harness teardown\n\t * (`harness.destroy()`) propagates through this hook (Tier 6.5 2.5b).\n\t */\n\tparentSignal?: AbortSignal;\n}\n\n/**\n * Internal — one-shot bridge from `adapter.invoke()` (a `NodeInput<LLMResponse>`)\n * into a producer that emits exactly one DATA + COMPLETE.\n *\n * **Why this exists.** The harness's `defaultLlmExecutor` and\n * `defaultLlmVerifier` (Tier 6.5 C2) both call `adapter.invoke()` once\n * per claimed JobFlow job and need to:\n * 1. Subscribe to the bridged Node, capture the first DATA, parse, emit\n * a domain payload.\n * 2. Map adapter throws / ERROR / COMPLETE-without-DATA to a domain\n * failure payload (rather than nack the JobFlow claim).\n * 3. Thread `signal: ac.signal` into BOTH `adapter.invoke()` (via\n * `LLMInvokeOptions.signal`) and `fromAny()` (covers Node-shaped\n * invokeResults) so teardown actually aborts in-flight HTTP work.\n * 4. Tear down the inner subscription cleanly when DATA captures or\n * when the producer is unsubscribed.\n *\n * Pre-extraction this body was duplicated ~80 LOC across the two default\n * bridges; symmetric fixes had to land twice (qa F1 / F2 / F5). This\n * helper centralizes the producer body so future bridge-layer fixes apply\n * once.\n *\n * **Not part of the public API.** Callers in `patterns/ai/_internal.ts`'s\n * import surface (the harness defaults today) use this; user code should\n * use `promptNode` for cross-wave reactive transforms or call\n * `adapter.invoke()` directly.\n */\nexport function _oneShotLlmCall<T>(\n\tadapter: LLMAdapter,\n\tmessages: readonly ChatMessage[],\n\tconfig: OneShotLlmCallConfig<T>,\n): NodeInput<T> {\n\treturn node<T>(\n\t\t(_data, actions) => {\n\t\t\tconst ac = new AbortController();\n\t\t\t// Link parent signal (e.g. pump per-claim signal) so cascading\n\t\t\t// teardown propagates: parent abort → inner ac.abort → adapter +\n\t\t\t// fromAny cancel.\n\t\t\tconst parentSignal = config.parentSignal;\n\t\t\tlet unlinkParent: () => void = () => undefined;\n\t\t\tif (parentSignal) {\n\t\t\t\tif (parentSignal.aborted) {\n\t\t\t\t\tac.abort();\n\t\t\t\t} else {\n\t\t\t\t\tconst onParentAbort = (): void => ac.abort();\n\t\t\t\t\tparentSignal.addEventListener(\"abort\", onParentAbort, { once: true });\n\t\t\t\t\tunlinkParent = () => parentSignal.removeEventListener(\"abort\", onParentAbort);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet captured = false;\n\t\t\tlet unsub: (() => void) | null = null;\n\t\t\tconst emitOnce = (value: T): void => {\n\t\t\t\tif (captured) return;\n\t\t\t\tcaptured = true;\n\t\t\t\tactions.down([[DATA, value], [COMPLETE]] satisfies Messages);\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = null;\n\t\t\t};\n\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\ttry {\n\t\t\t\tinvokeResult = adapter.invoke(messages, { ...config.invokeOpts, signal: ac.signal });\n\t\t\t} catch (err) {\n\t\t\t\temitOnce(config.onFailure(\"throw\", err));\n\t\t\t\treturn () => {\n\t\t\t\t\tunlinkParent();\n\t\t\t\t\tac.abort();\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst callNode = fromAny<LLMResponse>(invokeResult, { signal: ac.signal });\n\t\t\tunsub = callNode.subscribe((batch) => {\n\t\t\t\tfor (const m of batch) {\n\t\t\t\t\tif (captured) return;\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\temitOnce(config.onSuccess(m[1] as LLMResponse));\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\temitOnce(config.onFailure(\"onSuccess-threw\", err));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\temitOnce(config.onFailure(\"error\", m[1]));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\t// COMPLETE without prior DATA — without this arm the JobFlow\n\t\t\t\t\t\t// pump's claim would stall (qa F1 regression). Helper handles\n\t\t\t\t\t\t// for ALL callers; defaults can't regress.\n\t\t\t\t\t\temitOnce(config.onFailure(\"complete\", undefined));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t// Sync DATA delivery (cached state / `fromAny` over a sync value):\n\t\t\t// the callback ran reentrantly before `unsub` was assigned, so the\n\t\t\t// `unsub?.()` call inside `emitOnce` was a no-op. Drop the upstream\n\t\t\t// subscription now that we have the handle.\n\t\t\tif (captured && unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = null;\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tunlinkParent();\n\t\t\t\tac.abort();\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = null;\n\t\t\t};\n\t\t},\n\t\t{ describeKind: \"producer\" },\n\t);\n}\n","/**\n * `toolExecution` — reactive per-tool-call executor with retry + rescue.\n *\n * Lifted from the inlined `executeToolReactively` helper inside `agent-loop.ts`\n * so it can be consumed standalone by any caller with a reactive `toolCalls`\n * batch — not just `agentLoop`. The shape is: one input `Node<readonly\n * ToolCall[]>` + a `ToolRegistryGraph` → one output `Node<readonly\n * ToolResult[]>`. Each call maps to a per-call `retrySource(executeReactive)`\n * → optional `rescue` chain that emits the handler result on success, or a\n * JSON-wrapped `{ error }` payload on terminal failure so the LLM can see the\n * error as tool output and decide whether to try again via another tool call.\n *\n * **Cancellation.** `executeReactive` mints a per-call `AbortController` and\n * threads its signal into the handler call. When `switchMap` supersedes the\n * inner (a fresh `toolCalls` batch arrives) or the outer graph tears down,\n * the per-call node unsubscribes and `ac.abort()` fires. Signal-aware\n * handlers (`fetch(url, {signal})`, child-process kill, DB cancel) actually\n * stop in-flight work; handlers that ignore the signal still complete to\n * their original termination, but their result is discarded.\n *\n * @module\n */\n\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { rescue, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { retry } from \"../../../base/resilience/retry.js\";\nimport type { ToolCall } from \"../adapters/core/types.js\";\nimport type { ToolRegistryGraph } from \"./tool-registry.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single tool execution outcome: `{id, content}` where content is a JSON string. */\nexport interface ToolResult {\n\treadonly id: string;\n\treadonly content: string;\n}\n\nexport type ToolExecutionOptions = {\n\t/**\n\t * Reactive tool-call batch. Each non-empty emission triggers a fresh\n\t * per-call execution fan-out; superseding emissions cancel the prior fan.\n\t */\n\ttoolCalls: Node<readonly ToolCall[]>;\n\t/** Registry that resolves tool name → handler. */\n\ttools: ToolRegistryGraph;\n\t/**\n\t * Retry count per individual tool call. `retrySource({count: N})` retries\n\t * up to N times on error (N retries = N+1 total attempts). Default: 1.\n\t */\n\tretryCount?: number;\n\t/**\n\t * How to surface a terminal error after retries are exhausted.\n\t * - `\"rescue\"` (default): emit `{id, content: JSON.stringify({error})}`\n\t * so the LLM sees the failure as structured tool output and can decide\n\t * how to react. Sibling calls in the same batch continue to their own\n\t * completion; one call's failure does not affect the others.\n\t * - `\"propagate\"`: let the ERROR propagate downstream. **Blast radius:**\n\t * the per-batch `derived` join auto-errors when any per-call node\n\t * terminates with ERROR, so one call's failure discards every sibling's\n\t * DATA (even ones that already settled with a valid ToolResult). Use\n\t * `\"propagate\"` only when a single tool failure should be fatal for the\n\t * whole batch; prefer `\"rescue\"` when you want the LLM to see partial\n\t * results plus per-call error markers.\n\t */\n\tonError?: \"rescue\" | \"propagate\";\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Reactive executor for a batch of LLM tool calls.\n *\n * Each DATA emission on `toolCalls` dispatches a fresh per-call fan-out: for\n * every call in the batch, construct a `retrySource(fromAny(tools.execute(\n * name, args)))` node, optionally `rescue` it into a JSON error shape, and\n * join the results via a `derived` whose first-run gate waits for every call\n * to settle before emitting the batch. Empty batches (`calls.length === 0`)\n * are a caller-side invariant violation (the upstream gate should emit\n * RESOLVED for empty batches, not DATA) and trigger a loud error — callers\n * that want to accept empty batches should upstream-filter them first.\n *\n * Reference-equality + content-equality dedup is applied to the output batch\n * so duplicate re-emissions from a completing retrySource don't propagate.\n *\n * @param opts - `{ toolCalls, tools, retryCount?, onError? }`.\n * @returns `Node<readonly ToolResult[]>` — one ToolResult per input ToolCall.\n */\nexport function toolExecution(opts: ToolExecutionOptions): Node<readonly ToolResult[]> {\n\tconst { toolCalls, tools } = opts;\n\tconst retryCount = opts.retryCount ?? 1;\n\tconst onError = opts.onError ?? \"rescue\";\n\n\tconst batchEquals = (a: readonly ToolResult[], b: readonly ToolResult[]): boolean => {\n\t\tif (a === b) return true;\n\t\tif (a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tconst ai = a[i];\n\t\t\tconst bi = b[i];\n\t\t\tif (ai?.id !== bi?.id) return false;\n\t\t\tif (ai?.content !== bi?.content) return false;\n\t\t}\n\t\treturn true;\n\t};\n\n\treturn switchMap<readonly ToolCall[], readonly ToolResult[]>(toolCalls, (calls) => {\n\t\tif (calls == null || calls.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"toolExecution: received an empty tool-call batch as DATA — callers must upstream-filter empty batches (emit RESOLVED) so switchMap is only dispatched for non-empty batches.\",\n\t\t\t);\n\t\t}\n\t\tconst perCall = calls.map((call) => executeOne(call, tools, retryCount, onError));\n\t\t// `executeOne` returns `Node<ToolResult>` in both \"rescue\" and\n\t\t// \"propagate\" modes (the rescue handler builds a `ToolResult`\n\t\t// shape; the success `derived` builds one directly). The join\n\t\t// just forwards the per-call values — no shape coercion needed.\n\t\treturn node(\n\t\t\tperCall,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(data as readonly ToolResult[]);\n\t\t\t},\n\t\t\t{ describeKind: \"derived\", name: \"toolExecution::batch\", equals: batchEquals },\n\t\t);\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Per-call reactive executor. `retrySource` re-invokes the factory on ERROR\n * (each attempt mints a fresh `executeReactive` node, which in turn mints a\n * fresh `AbortController` and handler invocation). `executeReactive` itself\n * handles synchronous handler throws — they surface as `[[ERROR, err]]`\n * inside the producer, so `retrySource`'s reactive ERROR path fires\n * consistently regardless of handler shape. No `Promise.resolve().then(...)`\n * thunk needed — the reactive path is end-to-end.\n *\n * Handlers that return a plain string are surfaced as-is; anything else is\n * `JSON.stringify`'d so LLMs that parse tool results can roundtrip\n * structured data without surprise quoting.\n */\nfunction executeOne(\n\tcall: ToolCall,\n\ttools: ToolRegistryGraph,\n\tretryCount: number,\n\tonError: \"rescue\" | \"propagate\",\n): Node<ToolResult> {\n\tconst attempted: Node<unknown> = retry(() => tools.executeReactive(call.name, call.arguments), {\n\t\tcount: retryCount,\n\t}).node;\n\tconst onSuccess = node<ToolResult>(\n\t\t[attempted],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst val = data[0];\n\t\t\tactions.emit({\n\t\t\t\tid: call.id,\n\t\t\t\tcontent: typeof val === \"string\" ? val : JSON.stringify(val),\n\t\t\t});\n\t\t},\n\t\t{ describeKind: \"derived\" },\n\t);\n\tif (onError === \"propagate\") return onSuccess;\n\treturn rescue(onSuccess, (err) => ({\n\t\tid: call.id,\n\t\tcontent: JSON.stringify({ error: String(err) }),\n\t}));\n}\n","import { ERROR, type Messages, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAsyncIter, fromPromise, keepalive, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta, isNodeLike } from \"../_internal.js\";\nimport type { ToolDefinition } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// toolRegistry\n// ---------------------------------------------------------------------------\n\nexport type ToolRegistryOptions = {\n\tgraph?: GraphOptions;\n};\n\n/**\n * `ToolRegistryGraph` — name-keyed registry of {@link ToolDefinition}s.\n *\n * **Reactive-only execution.** The only execution path is\n * {@link executeReactive}, which returns a `Node<unknown>` for the handler\n * result. Composing factories (`toolExecution`, `agentLoop`) consume it\n * directly inside `retrySource` / `switchMap` chains. There is intentionally\n * no imperative `execute()` Promise method — the registry was originally a\n * dual-boundary class (imperative + reactive) and the imperative path was\n * the only thing in the codebase bridging through `Promise.resolve().then()`\n * to feed `fromAny`. Removing it left every consumer on a single\n * reactive-all-the-way path with real abort propagation.\n *\n * For non-reactive callers (debug scripts, one-shot tests), bridge with\n * `awaitSettled(toolRegistry.executeReactive(name, args))`.\n *\n * **Wave A Unit 6 refactor:** internal storage migrated from `state<Map>`\n * (O(N) Map-copy per mutation) to `ReactiveMapBundle<string, ToolDefinition>`\n * (O(1) mutations + version counter).\n */\nexport class ToolRegistryGraph extends Graph {\n\treadonly definitions: Node<ReadonlyMap<string, ToolDefinition>>;\n\treadonly schemas: Node<readonly ToolDefinition[]>;\n\tprivate readonly _bundle: ReturnType<typeof reactiveMap<string, ToolDefinition>>;\n\n\tconstructor(name: string, opts: ToolRegistryOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._bundle = reactiveMap<string, ToolDefinition>({\n\t\t\tname: \"definitions\",\n\t\t});\n\t\tthis.definitions = this._bundle.entries;\n\t\tthis.add(this.definitions, { name: \"definitions\" });\n\n\t\tthis.schemas = node<readonly ToolDefinition[]>(\n\t\t\t[this.definitions],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst defs = data[0];\n\t\t\t\tactions.emit([...((defs ?? new Map()) as ReadonlyMap<string, ToolDefinition>).values()]);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"schemas\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"tool_schemas\"),\n\t\t\t\tinitial: [],\n\t\t\t},\n\t\t);\n\t\tthis.add(this.schemas, { name: \"schemas\" });\n\t\tthis.addDisposer(keepalive(this.schemas));\n\t}\n\n\tregister(tool: ToolDefinition): void {\n\t\tthis._bundle.set(tool.name, tool);\n\t}\n\n\tunregister(name: string): void {\n\t\tthis._bundle.delete(name);\n\t}\n\n\t/**\n\t * Reactive execution — returns a `Node<unknown>` that emits the handler\n\t * result. The returned node is a `producer` that:\n\t *\n\t * 1. Mints a per-call `AbortController` whose `signal` is threaded into\n\t * the handler call AND into `fromAny` (so a `fromPromise` /\n\t * `fromAsyncIter` inner abandons cleanly when the consumer\n\t * unsubscribes).\n\t * 2. Runs `tool.handler(args, {signal})` inside a try/catch — a\n\t * synchronous throw surfaces as `[[ERROR, err]]` downstream instead\n\t * of escaping the producer.\n\t * 3. Forwards every message from the inner `fromAny` chain to the\n\t * producer's outputs.\n\t * 4. On teardown (subscriber count drops to zero, e.g. `switchMap`\n\t * supersede) calls `ac.abort()` and unsubscribes the inner.\n\t * Signal-aware handlers (e.g. `fetch(url, {signal})`) actually stop.\n\t *\n\t * Each call mints a fresh node tied to a fresh `handler(args, ...)`\n\t * invocation — call `executeReactive` again for repeated invocations.\n\t *\n\t * @throws `Error` synchronously when `name` is not registered (no node is\n\t * constructed — the caller gets a pre-wiring failure rather than a\n\t * silent ERROR wave on an empty graph).\n\t */\n\texecuteReactive(name: string, args: Record<string, unknown>): Node<unknown> {\n\t\tconst tool = this._bundle.get(name);\n\t\tif (!tool) throw new Error(`toolRegistry: unknown tool \"${name}\"`);\n\t\treturn node<unknown>(\n\t\t\t[],\n\t\t\t(_data, actions) => {\n\t\t\t\tconst ac = new AbortController();\n\t\t\t\tlet inner: Node<unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = tool.handler(args, { signal: ac.signal });\n\t\t\t\t\tinner = handlerResultToNode(raw, ac.signal);\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// Synchronous throw from handler → ERROR. Producer cleanup\n\t\t\t\t\t// still aborts the controller for symmetry (no-op if no\n\t\t\t\t\t// signal listeners attached).\n\t\t\t\t\tactions.down([[ERROR, err]] satisfies Messages);\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tac.abort();\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst unsub = inner.subscribe((batch) => {\n\t\t\t\t\tactions.down(batch as Messages);\n\t\t\t\t});\n\t\t\t\treturn () => {\n\t\t\t\t\tac.abort();\n\t\t\t\t\tunsub();\n\t\t\t\t};\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: `executeReactive::${name}`,\n\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\tmeta: aiMeta(\"tool_execute_reactive\"),\n\t\t\t},\n\t\t);\n\t}\n\n\tgetDefinition(name: string): ToolDefinition | undefined {\n\t\t// Pure read via the snapshot cache — avoids the bundle's\n\t\t// `wrapMutation` path (which would run the version-bump check and\n\t\t// any configured retention eviction on every lookup). Safe because\n\t\t// `getDefinition` is a boundary API, not a reactive fn body.\n\t\treturn this._bundle.entries.cache?.get(name);\n\t}\n}\n\nexport function toolRegistry(name: string, opts?: ToolRegistryOptions): ToolRegistryGraph {\n\treturn new ToolRegistryGraph(name, opts);\n}\n\n/**\n * Coerce a tool handler return value into a `Node<unknown>`.\n *\n * Differs from `fromAny` by treating **strings, arrays, plain iterables, and\n * scalar objects as single DATA values** rather than iterating them. A tool\n * handler that returns `\"hello world\"` should surface as one `DATA(\"hello\n * world\")`, not 11 `DATA` events of single characters; an array `[1, 2, 3]`\n * should surface as `DATA([1, 2, 3])`, not three separate emissions.\n *\n * Reactive shapes (Node, Promise, AsyncIterable) are unwrapped as expected.\n *\n * @internal\n */\nfunction handlerResultToNode(raw: unknown, signal: AbortSignal): Node<unknown> {\n\tif (isNodeLike(raw)) {\n\t\treturn raw as Node<unknown>;\n\t}\n\tif (raw != null && typeof (raw as PromiseLike<unknown>).then === \"function\") {\n\t\treturn fromPromise(raw as PromiseLike<unknown>, { signal });\n\t}\n\tif (raw != null && typeof raw === \"object\" && Symbol.asyncIterator in (raw as object)) {\n\t\treturn fromAsyncIter(raw as AsyncIterable<unknown>, { signal });\n\t}\n\t// String, number, boolean, null, undefined, plain object, array,\n\t// sync iterable — treat as a single DATA value via a resolved Promise so\n\t// `fromPromise`'s scalar-DATA-emit + COMPLETE semantics match the\n\t// pre-refactor `tools.execute` behavior (which always wrapped via async).\n\treturn fromPromise(Promise.resolve(raw), { signal });\n}\n","// ---------------------------------------------------------------------------\n// memory composers — Unit 7 C-factoring (2026-04-23 doc decision).\n//\n// Each composer attaches one capability (vectors, KG, tiers, retrieval) to a\n// `DistillBundle`. `agentMemory` continues to ship as the ergonomic sugar\n// over the full pipeline; power users who want a subset call these factories\n// directly.\n//\n// Class B audit (2026-04-30): the composers were migrated from\n// bundle-returning factories to **Graph subclasses** so they participate in\n// `describe()` / `destroy()` like every other Phase 4+ Graph (mirrors\n// `AuditTrailGraph`, `PolicyGateGraph`, `CqrsGraph`). The factory functions\n// remain as ergonomic constructors (`memoryWithVectors(opts) → MemoryWithVectorsGraph`).\n//\n// Tier 4.1 B + 4.3 B (2026-04-29): `memoryWithTiers` is the construction site\n// for the distill bundle when tiers are configured (`reactiveMap.retention`\n// wired at construction eliminates the §7 feedback cycle the prior\n// `tierClassifier` effect carried). `permanentKeys` and `entryCreatedAtNs`\n// are reactive maps mounted on the graph (not closure state) so\n// `describe()`/`explain()` can walk to the inputs that fed an archival\n// decision.\n// ---------------------------------------------------------------------------\n\nimport { batch, DATA, monotonicNs, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport type { StorageHandle } from \"@graphrefly/pure-ts/extra\";\nimport {\n\tfromAny,\n\tkeepalive,\n\ttype NodeInput,\n\ttype ReactiveMapBundle,\n\ttype ReactiveMapRetention,\n\treactiveMap,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype DistillBundle,\n\ttype DistillOptions,\n\tdistill,\n\ttype Extraction,\n} from \"../../../base/composition/distill.js\";\nimport { decay } from \"../../../base/utils/decay.js\";\nimport {\n\tcollection,\n\tcosineSimilarity,\n\ttype KnowledgeEdge,\n\ttype KnowledgeGraph,\n\tknowledgeGraph,\n\ttype VectorIndexGraph,\n\ttype VectorRecord,\n\ttype VectorSearchResult,\n\tvectorIndex,\n} from \"../../memory/index.js\";\nimport { aiMeta } from \"../_internal.js\";\nimport type { RetrievalEntry, RetrievalQuery, RetrievalTrace } from \"./retrieval.js\";\nimport {\n\tDEFAULT_DECAY_RATE,\n\ttype MemoryTier,\n\ttype MemoryTiersBundle,\n\ttype MemoryTiersOptions,\n} from \"./tiers.js\";\n\n// Tier 4.7 (Wave AM Unit 5 carry): the pre-rebuild defensive `extractStoreMap`\n// helper (runtime `instanceof Map` check before casting) was deleted in favor\n// of a typed `as` cast at each callsite. The upstream `ReactiveMapBundle`\n// always emits a real Map on the live emit path; non-Map snapshots only\n// surface on `Graph.restore` from a codec that round-tripped Map → JSON →\n// plain object (handled in `extra/composite.ts:mapFromSnapshot` for distill\n// internals). Empty map is the canonical \"no entries yet\" value —\n// `node([], { initial: undefined })` would stall a derived/effect's first-run gate.\n//\n// qa F3 (deferred): the typed cast lies if upstream contract ever breaks\n// (e.g. `entries` emits a non-Map non-undefined value). Failure mode is a\n// TypeError at iteration instead of a silent empty-map fallback —\n// deliberate trade-off, surfacing real upstream-contract violations beats\n// hiding them. Upstream-narrowing follow-up filed in `docs/optimizations.md`\n// under \"Tier 4.7 follow-up — narrow `ReactiveMapBundle.entries` callback typing\".\n\n// ---------------------------------------------------------------------------\n// memoryWithVectors\n// ---------------------------------------------------------------------------\n\nexport interface MemoryWithVectorsOptions<TMem> {\n\t/** Optional Graph identity — passed through to the underlying `Graph` ctor. */\n\tgraph?: GraphOptions;\n\t/** Subgraph name. Default: `\"memory-vectors\"`. */\n\tname?: string;\n\t/** The substrate distill store to index. */\n\tstore: DistillBundle<TMem>;\n\t/** Embedding dimension. Must match the `embedFn` output length. */\n\tdimension: number;\n\t/** Extract an embedding vector for a memory entry. */\n\tembedFn: (mem: TMem) => readonly number[] | undefined;\n}\n\n/**\n * Graph subclass that attaches a vector index to a `DistillBundle`. The inner\n * `VectorIndexGraph` is mounted at `\"vectorIndex\"`; an internal effect\n * subscribes to the substrate store and re-indexes on every change.\n *\n * Mirrors `AuditTrailGraph` / `PolicyGateGraph` shape — fully self-contained,\n * teardown via the Graph's `destroy()` cascade.\n */\nexport class MemoryWithVectorsGraph<TMem> extends Graph {\n\treadonly vectors: VectorIndexGraph<TMem>;\n\n\tconstructor(opts: MemoryWithVectorsOptions<TMem>) {\n\t\tsuper(opts.name ?? \"memory-vectors\", opts.graph);\n\t\tthis.vectors = vectorIndex<TMem>({ dimension: opts.dimension });\n\t\tthis.mount(\"vectorIndex\", this.vectors);\n\n\t\tconst embedFn = opts.embedFn;\n\t\tconst vectorsRef = this.vectors;\n\n\t\t// Indexer effect — subscribes to the substrate's store entries, upserts\n\t\t// vectors. Pure side-effect; restricted `effect` fn (no emit/down).\n\t\t// Cross-graph dep on `opts.store.store.entries` is fine — the substrate\n\t\t// is the upstream wired in by the parent factory.\n\t\tconst indexer = node(\n\t\t\t[opts.store.store.entries],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst storeMap =\n\t\t\t\t\t(data[0] as ReadonlyMap<string, TMem> | undefined) ?? new Map<string, TMem>();\n\t\t\t\tfor (const [key, mem] of storeMap) {\n\t\t\t\t\tconst vec = embedFn(mem);\n\t\t\t\t\tif (vec) vectorsRef.upsert(key, vec, mem);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"indexer\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(indexer, { name: \"indexer\" });\n\t\tthis.addDisposer(keepalive(indexer));\n\t}\n}\n\n/**\n * Attach a vector index to a `DistillBundle`. Indexes every entry in the\n * store as it changes. Returns the `MemoryWithVectorsGraph` whose `vectors`\n * field exposes the underlying `VectorIndexGraph`.\n *\n * Teardown is handled by `Graph.destroy()` — typically inherited via\n * mounting the result on a parent graph (see `agentMemory`).\n */\nexport function memoryWithVectors<TMem>(\n\topts: MemoryWithVectorsOptions<TMem>,\n): MemoryWithVectorsGraph<TMem> {\n\treturn new MemoryWithVectorsGraph<TMem>(opts);\n}\n\n// ---------------------------------------------------------------------------\n// memoryWithKG\n// ---------------------------------------------------------------------------\n\nexport interface MemoryWithKGOptions<TMem> {\n\t/** Optional Graph identity. */\n\tgraph?: GraphOptions;\n\t/** Subgraph name. Default: `\"memory-kg\"`. */\n\tname?: string;\n\t/** The substrate distill store to index. */\n\tstore: DistillBundle<TMem>;\n\t/** Inner KnowledgeGraph name. Default: `${name}-kg`. */\n\tkgName?: string;\n\t/**\n\t * Mount path within this Graph for the KnowledgeGraph. Default:\n\t * `\"knowledge-kg\"` (B5c — symmetric with the outer `knowledge` mount so\n\t * describe paths render `knowledge::knowledge-kg::*`).\n\t */\n\tmountPath?: string;\n\t/**\n\t * Extract entities + relations for a memory entry. Omit to mount an empty\n\t * KG without an indexer effect — caller upserts entities / relations\n\t * directly on the `kg` field.\n\t */\n\tentityFn?: (\n\t\tkey: string,\n\t\tmem: TMem,\n\t) =>\n\t\t| {\n\t\t\t\tentities?: Array<{ id: string; value: unknown }>;\n\t\t\t\trelations?: Array<{ from: string; to: string; relation: string; weight?: number }>;\n\t\t }\n\t\t| undefined;\n}\n\n/**\n * Graph subclass that attaches a knowledge graph alongside a `DistillBundle`.\n * Mounts the inner `KnowledgeGraph` at `mountPath` (default `\"knowledge-kg\"`); when\n * `entityFn` is provided, an indexer effect populates entities/relations on\n * every store change.\n */\nexport class MemoryWithKGGraph<TMem> extends Graph {\n\treadonly kg: KnowledgeGraph<unknown, string>;\n\n\tconstructor(opts: MemoryWithKGOptions<TMem>) {\n\t\tconst name = opts.name ?? \"memory-kg\";\n\t\tsuper(name, opts.graph);\n\t\tconst kgName = opts.kgName ?? `${name}-kg`;\n\t\tconst mountPath = opts.mountPath ?? \"knowledge-kg\";\n\t\tthis.kg = knowledgeGraph<unknown, string>(kgName);\n\t\tthis.mount(mountPath, this.kg);\n\n\t\tif (!opts.entityFn) return;\n\t\tconst entityFn = opts.entityFn;\n\t\tconst kgRef = this.kg;\n\t\tconst indexer = node(\n\t\t\t[opts.store.store.entries],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst storeMap =\n\t\t\t\t\t(data[0] as ReadonlyMap<string, TMem> | undefined) ?? new Map<string, TMem>();\n\t\t\t\tfor (const [key, mem] of storeMap) {\n\t\t\t\t\tconst extracted = entityFn(key, mem);\n\t\t\t\t\tif (!extracted) continue;\n\t\t\t\t\tfor (const ent of extracted.entities ?? []) {\n\t\t\t\t\t\tkgRef.upsertEntity(ent.id, ent.value);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const rel of extracted.relations ?? []) {\n\t\t\t\t\t\tkgRef.link(rel.from, rel.to, rel.relation, rel.weight);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"indexer\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(indexer, { name: \"indexer\" });\n\t\tthis.addDisposer(keepalive(indexer));\n\t}\n}\n\n/**\n * Attach a knowledge graph alongside a `DistillBundle`. Returns the\n * `MemoryWithKGGraph` whose `kg` field exposes the inner `KnowledgeGraph`.\n */\nexport function memoryWithKG<TMem>(opts: MemoryWithKGOptions<TMem>): MemoryWithKGGraph<TMem> {\n\treturn new MemoryWithKGGraph<TMem>(opts);\n}\n\n// ---------------------------------------------------------------------------\n// memoryWithTiers\n// ---------------------------------------------------------------------------\n\n/**\n * Full options for {@link memoryWithTiers} (Tier 4.1 B + 4.3 B refactor,\n * 2026-04-29). Combines tier-policy options with the distill-side options\n * needed to construct the underlying store — `memoryWithTiers` is the\n * **construction site** for the distill bundle so it can wire\n * `reactiveMap.retention` into the store at construction (eliminating the\n * §7 feedback cycle the previous `tierClassifier` effect carried).\n */\nexport type MemoryWithTiersOptions<TRaw, TMem> = MemoryTiersOptions<TMem> &\n\tOmit<DistillOptions<TMem>, \"mapOptions\" | \"score\" | \"context\"> & {\n\t\t/** Optional Graph identity. */\n\t\tgraph?: GraphOptions;\n\t\t/** Subgraph name. Default: `\"memory-tiers\"`. */\n\t\tname?: string;\n\t\t/** Raw source feeding distill. */\n\t\tsource: NodeInput<TRaw>;\n\t\t/** Reactive extraction wiring (same shape as `distill`). */\n\t\textractFn: (\n\t\t\traw: Node<TRaw>,\n\t\t\texisting: Node<ReadonlyMap<string, TMem>>,\n\t\t) => NodeInput<Extraction<TMem>>;\n\t\t/** Score function — same signature as `agentMemory.score`. */\n\t\tscore: (mem: TMem, context: unknown) => number;\n\t\t/** Optional reactive context node (passed to `score`). */\n\t\tcontext?: NodeInput<unknown>;\n\t};\n\n/**\n * Graph subclass attaching 3-tier storage (active / archived / permanent) to\n * a fresh distill store, wiring `reactiveMap.retention` at construction so\n * archival happens synchronously inside the substrate's mutation pipeline\n * (no §7 feedback cycle). Promotes `permanentKeys` and `entryCreatedAtNs` to\n * reactive maps registered on this graph (Tier 4.3 B — Unit 7 Q3) so\n * `describe()` / `explain()` can walk to \"why was X archived?\".\n *\n * Public-face fields:\n * - `store` — the distill bundle (construction site, exposed for downstream\n * composers).\n * - `tiers` — tier classification + permanent promotion handles.\n * - `compact`, `size` — alias for `store.compact` / `store.size` (registered\n * under their canonical names so `describe()` keys match `agentMemory`'s\n * pre-migration layout).\n */\nexport class MemoryWithTiersGraph<TRaw, TMem> extends Graph {\n\treadonly store: DistillBundle<TMem>;\n\treadonly tiers: MemoryTiersBundle<TMem>;\n\treadonly compact: Node<Array<{ key: string; value: TMem; score: number }>>;\n\treadonly size: Node<number>;\n\treadonly permanent: ReturnType<typeof collection<TMem>>;\n\treadonly permanentKeys: ReactiveMapBundle<string, true>;\n\treadonly entryCreatedAtNs: ReactiveMapBundle<string, number>;\n\n\tconstructor(opts: MemoryWithTiersOptions<TRaw, TMem>) {\n\t\tsuper(opts.name ?? \"memory-tiers\", opts.graph);\n\n\t\tconst decayRate = opts.decayRate ?? DEFAULT_DECAY_RATE;\n\t\tconst maxActive = opts.maxActive ?? 1000;\n\t\tconst archiveThreshold = opts.archiveThreshold ?? 0.1;\n\t\tconst permanentFilter = opts.permanentFilter ?? (() => false);\n\n\t\t// Tier 2.3 fold: `lightCollection` was merged into\n\t\t// `collection({ranked: false})`. The unified factory returns a Graph (not\n\t\t// a detached bundle), so it's mounted as a subgraph for `describe()`.\n\t\tthis.permanent = collection<TMem>(\"permanent\", { ranked: false });\n\t\tthis.mount(\"permanent\", this.permanent);\n\n\t\t// 4.3 B (Unit 7 Q3, 2026-04-29): closure-state promotion. `permanentKeys`\n\t\t// and `entryCreatedAtNs` are reactive maps registered on this graph so\n\t\t// `describe()` can walk to them and `explain()` can trace the inputs\n\t\t// that fed an archival decision.\n\t\tthis.permanentKeys = reactiveMap<string, true>({ name: \"permanentKeys\" });\n\t\tthis.add(this.permanentKeys.entries, { name: \"permanentKeys\" });\n\t\tthis.entryCreatedAtNs = reactiveMap<string, number>({ name: \"entryCreatedAtNs\" });\n\t\tthis.add(this.entryCreatedAtNs.entries, { name: \"entryCreatedAtNs\" });\n\n\t\t// Closure-mirror for ctx (§28 factory-time seed). `score(mem, ctx)` runs\n\t\t// inside `retention.score` which is invoked synchronously from store\n\t\t// mutations — no reactive dep on contextNode there. The mirror keeps\n\t\t// `latestCtx` current via subscribe.\n\t\t//\n\t\t// Topology visibility: the local-default branch registers the context\n\t\t// state node so it appears in `describe()`. The user-supplied-Node\n\t\t// branch deliberately leaves the node unregistered — `fromAny` returns\n\t\t// the caller's owned Node, which is owned by their graph; mounting it\n\t\t// here would corrupt cross-graph ownership.\n\t\tlet contextNode: Node<unknown>;\n\t\tif (opts.context) {\n\t\t\tcontextNode = fromAny(opts.context);\n\t\t} else {\n\t\t\tcontextNode = node<unknown>([], { initial: null });\n\t\t\tthis.add(contextNode, { name: \"context\" });\n\t\t}\n\t\tlet latestCtx: unknown = contextNode.cache;\n\t\tconst ctxUnsub = contextNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestCtx = m[1];\n\t\t});\n\t\tthis.addDisposer(ctxUnsub);\n\n\t\tconst permanentKeysRef = this.permanentKeys;\n\t\tconst entryCreatedAtNsRef = this.entryCreatedAtNs;\n\t\tconst score = opts.score;\n\n\t\t// Build retention. `score` runs synchronously inside store mutations.\n\t\t// Permanent matches return Infinity to bypass eviction.\n\t\t//\n\t\t// DS-13.5.F (2026-05-01): `score` is read-only against\n\t\t// `entryCreatedAtNs` — the first-write side-effect was extracted into\n\t\t// the `entryCreatedAtNs/sync` effect below. Race window for the very\n\t\t// first call on a new key is mitigated by the `?? nowNs` fallback\n\t\t// (yields ageSeconds = 0, i.e. fresh-decay), and the sync effect\n\t\t// populates the map after the wave settles so subsequent score calls\n\t\t// see the persisted timestamp.\n\t\tconst retention: ReactiveMapRetention<string, TMem> = {\n\t\t\tscore: (key, value) => {\n\t\t\t\tif (permanentFilter(key, value)) return Number.POSITIVE_INFINITY;\n\t\t\t\tif (permanentKeysRef.has(key)) return Number.POSITIVE_INFINITY;\n\t\t\t\tconst nowNs = monotonicNs();\n\t\t\t\tconst createdNs = entryCreatedAtNsRef.get(key) ?? nowNs;\n\t\t\t\tconst ageSeconds = Number(nowNs - createdNs) / 1e9;\n\t\t\t\treturn decay(score(value, latestCtx), ageSeconds, decayRate);\n\t\t\t},\n\t\t\tarchiveThreshold,\n\t\t\tmaxSize: maxActive,\n\t\t};\n\n\t\t// Construct distill with retention wired into mapOptions.\n\t\tthis.store = distill<TRaw, TMem>(opts.source, opts.extractFn, {\n\t\t\tscore: opts.score,\n\t\t\tcost: opts.cost,\n\t\t\t...(opts.budget !== undefined ? { budget: opts.budget } : {}),\n\t\t\t...(opts.evict !== undefined ? { evict: opts.evict } : {}),\n\t\t\t...(opts.consolidate !== undefined ? { consolidate: opts.consolidate } : {}),\n\t\t\t...(opts.consolidateTrigger !== undefined\n\t\t\t\t? { consolidateTrigger: opts.consolidateTrigger }\n\t\t\t\t: {}),\n\t\t\t...(opts.context !== undefined ? { context: opts.context } : {}),\n\t\t\tmapOptions: { retention },\n\t\t});\n\n\t\t// Register the distill bundle's exposed nodes under their canonical\n\t\t// names so consumers (and `describe()`) see the same shape as the\n\t\t// pre-migration top-level surface on `agentMemory`.\n\t\tthis.add(this.store.store.entries, { name: \"store\" });\n\t\tthis.compact = this.store.compact;\n\t\tthis.add(this.compact, { name: \"compact\" });\n\t\tthis.size = this.store.size;\n\t\tthis.add(this.size, { name: \"size\" });\n\n\t\tconst storeRef = this.store;\n\t\tconst tierOf = (key: string): MemoryTier => {\n\t\t\tif (permanentKeysRef.has(key)) return \"permanent\";\n\t\t\tconst m =\n\t\t\t\t(storeRef.store.entries.cache as ReadonlyMap<string, TMem> | undefined) ??\n\t\t\t\tnew Map<string, TMem>();\n\t\t\tif (m.has(key)) return \"active\";\n\t\t\treturn \"archived\";\n\t\t};\n\t\tconst permanentRef = this.permanent;\n\t\tconst markPermanent = (key: string, value: TMem): void => {\n\t\t\tpermanentKeysRef.set(key, true);\n\t\t\tpermanentRef.upsert(key, value);\n\t\t};\n\n\t\t// DS-13.5.F (2026-05-01): first-write of `entryCreatedAtNs[key]` runs\n\t\t// here (extracted from `retention.score` to keep score pure). Reads\n\t\t// `store.store.entries`, writes `entryCreatedAtNs` — distinct nodes,\n\t\t// no §7 feedback cycle. Idempotent: re-emissions for already-tracked\n\t\t// keys skip via `entryCreatedAtNsRef.has(key)`.\n\t\tconst syncCreatedAt = node(\n\t\t\t[this.store.store.entries],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst map = (data[0] as ReadonlyMap<string, TMem> | undefined) ?? new Map<string, TMem>();\n\t\t\t\tconst nowNs = monotonicNs();\n\t\t\t\tconst toAdd: string[] = [];\n\t\t\t\tfor (const key of map.keys()) {\n\t\t\t\t\tif (!entryCreatedAtNsRef.has(key)) toAdd.push(key);\n\t\t\t\t}\n\t\t\t\tif (toAdd.length > 0) {\n\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\tfor (const key of toAdd) entryCreatedAtNsRef.set(key, nowNs);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"entryCreatedAtNs/sync\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(syncCreatedAt, { name: \"entryCreatedAtNs/sync\" });\n\t\tthis.addDisposer(keepalive(syncCreatedAt));\n\n\t\t// GC entryCreatedAtNs entries that no longer exist in the active store.\n\t\t// (Adds happen via the syncCreatedAt effect above; removals piggyback\n\t\t// on the store-snapshot subscriber here so the map stays in sync.)\n\t\tconst entriesUnsub = this.store.store.entries.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst map = m[1] as ReadonlyMap<string, TMem>;\n\t\t\t\tconst created = entryCreatedAtNsRef.entries.cache as\n\t\t\t\t\t| ReadonlyMap<string, number>\n\t\t\t\t\t| undefined;\n\t\t\t\tif (created == null) continue;\n\t\t\t\tconst toDelete: string[] = [];\n\t\t\t\tfor (const key of created.keys()) {\n\t\t\t\t\tif (!map.has(key)) toDelete.push(key);\n\t\t\t\t}\n\t\t\t\tif (toDelete.length > 0) {\n\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\tfor (const key of toDelete) entryCreatedAtNsRef.delete(key);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(entriesUnsub);\n\n\t\t// Permanent-promotion effect. Writes to `permanent` collection +\n\t\t// `permanentKeys` (NOT to the active store), so no §7 cycle: the effect's\n\t\t// dep is `store.store.entries`, but it doesn't write back to that node.\n\t\tconst promoter = node(\n\t\t\t[this.store.store.entries],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst map = (data[0] as ReadonlyMap<string, TMem> | undefined) ?? new Map<string, TMem>();\n\t\t\t\tfor (const [key, mem] of map) {\n\t\t\t\t\tif (permanentKeysRef.has(key)) continue;\n\t\t\t\t\tif (permanentFilter(key, mem)) {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tmarkPermanent(key, mem);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"promoter\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(promoter, { name: \"promoter\" });\n\t\tthis.addDisposer(keepalive(promoter));\n\n\t\tlet archiveHandle: StorageHandle | null = null;\n\t\tif (opts.archiveTier) {\n\t\t\tarchiveHandle = this.attachSnapshotStorage(\n\t\t\t\t[{ snapshot: opts.archiveTier }],\n\t\t\t\topts.archiveStorageOptions ?? {},\n\t\t\t);\n\t\t\tthis.addDisposer(() => archiveHandle?.dispose());\n\t\t}\n\n\t\tthis.tiers = {\n\t\t\tpermanent: this.permanent,\n\t\t\tactiveEntries: this.store.store.entries,\n\t\t\tarchiveHandle,\n\t\t\ttierOf,\n\t\t\tmarkPermanent,\n\t\t};\n\t}\n}\n\n/**\n * Attach 3-tier storage (active / archived / permanent) over a fresh distill\n * store. Returns a `MemoryWithTiersGraph` whose `store` and `tiers` fields\n * mirror the previous bundle shape.\n *\n * **API shape** (Class B audit, 2026-04-30 — breaking change vs.\n * pre-migration): the factory takes a single opts bag including `source`\n * and `extractFn`. The bundle is exposed as `result.store` for downstream\n * composers (vectors / KG / retrieval).\n *\n * - `permanentFilter`-matching entries score `Infinity` in retention →\n * never archived. Independent permanent-promotion effect upserts them\n * into the `permanent` collection.\n * - Below-threshold entries → retention archives synchronously.\n * - Over-`maxActive` entries → retention's `maxSize` evicts lowest-scored.\n */\nexport function memoryWithTiers<TRaw, TMem>(\n\topts: MemoryWithTiersOptions<TRaw, TMem>,\n): MemoryWithTiersGraph<TRaw, TMem> {\n\treturn new MemoryWithTiersGraph<TRaw, TMem>(opts);\n}\n\n// ---------------------------------------------------------------------------\n// memoryRetrieval\n// ---------------------------------------------------------------------------\n\nexport interface MemoryRetrievalOptions<TMem> {\n\t/** Optional Graph identity. */\n\tgraph?: GraphOptions;\n\t/** Subgraph name. Default: `\"memory-retrieval\"`. */\n\tname?: string;\n\t/** The substrate distill store. */\n\tstore: DistillBundle<TMem>;\n\t/** Optional vector index for similarity search. */\n\tvectors?: VectorIndexGraph<TMem> | null;\n\t/** Optional knowledge graph for entity-relation expansion. */\n\tkg?: KnowledgeGraph<unknown, string> | null;\n\t/** Score function (same shape as `agentMemory.score`). */\n\tscore: (mem: TMem, context: unknown) => number;\n\t/** Cost function for budget packing. */\n\tcost: (mem: TMem) => number;\n\t/** Token / cost budget. Default 2000. */\n\tbudget?: number;\n\t/** Top-K vector candidates. Default 20. */\n\ttopK?: number;\n\t/** KG expansion depth in hops. Default 1. */\n\tgraphDepth?: number;\n\t/** Hierarchical-context boost weight. Default 0. */\n\tcontextWeight?: number;\n\t/** Hierarchical-context accessor for entries. */\n\tcontextOf?: (mem: TMem) => readonly string[] | undefined;\n\t/** Optional reactive context node (passed to `score`). */\n\tcontext?: NodeInput<unknown>;\n}\n\nfunction sharedPrefixDepth(\n\tq: readonly string[] | undefined,\n\te: readonly string[] | undefined,\n): number {\n\tif (!q || !e) return 0;\n\tconst n = Math.min(q.length, e.length);\n\tlet i = 0;\n\twhile (i < n && q[i] === e[i]) i++;\n\treturn i;\n}\n\n// QA-fix: element-wise reference-equality dedup so subscribers don't wake\n// up when an identical packed array lands (runRetrieval allocates a new\n// outer array reference every call).\nconst packedEquals = <T>(a: readonly T[], b: readonly T[]): boolean => {\n\tif (a === b) return true;\n\tif (a.length !== b.length) return false;\n\tfor (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n\treturn true;\n};\n\n/**\n * Graph subclass that builds the retrieval pipeline (vector + KG + budget\n * packing) over a `DistillBundle` and optional vectors / kg substrates.\n *\n * **C1 rework (2026-04-30):** retrieval is reactive-only. Each\n * `retrieveReactive(input)` call constructs its own per-input subgraph\n * mounted at `retrieve_${id}` with named nodes `context`, `result`, and\n * `projection`. Subgraphs register their own scoped disposers so teardown\n * is local to the per-call mount.\n *\n * **QA F-9 (2026-04-30):** the shared `retrieval` / `retrievalTrace`\n * state-node mirrors are dropped — they were last-writer-wins under\n * concurrent `retrieveReactive(...)` calls. Consumers must subscribe to\n * the per-call `projection` node directly. One-shot consumers use\n * `awaitSettled(retrieveReactive(input))`.\n *\n * **QA F-6 (2026-04-30):** the per-call `result` derived declares\n * `vectors.entries` / `kg.adjacencyOut` / `kg.adjacencyIn` as deps when\n * configured, so a vector upsert / KG mutation re-runs retrieval even\n * when the query / context / store-snapshot are unchanged. Resolves the\n * §28 closure-mirror gap where these `.cache` reads were undeclared.\n */\nexport class MemoryRetrievalGraph<TMem> extends Graph {\n\tprivate readonly _store: DistillBundle<TMem>;\n\tprivate readonly _vectors: VectorIndexGraph<TMem> | null;\n\tprivate readonly _kg: KnowledgeGraph<unknown, string> | null;\n\tprivate readonly _opts: MemoryRetrievalOptions<TMem>;\n\tprivate readonly _contextNode: Node<unknown>;\n\tprivate readonly _topK: number;\n\tprivate readonly _graphDepth: number;\n\tprivate readonly _budget: number;\n\tprivate readonly _contextWeight: number;\n\tprivate _retrieveSeq = 0;\n\n\tconstructor(opts: MemoryRetrievalOptions<TMem>) {\n\t\tsuper(opts.name ?? \"memory-retrieval\", opts.graph);\n\n\t\tthis._store = opts.store;\n\t\tthis._vectors = opts.vectors ?? null;\n\t\tthis._kg = opts.kg ?? null;\n\t\tthis._opts = opts;\n\t\tthis._topK = opts.topK ?? 20;\n\t\tthis._graphDepth = opts.graphDepth ?? 1;\n\t\tthis._budget = opts.budget ?? 2000;\n\t\tthis._contextWeight = opts.contextWeight ?? 0;\n\t\t// DS-13.5.C: synthesized branch (no `opts.context` supplied) registers\n\t\t// on this graph as `_context` so describe()/explain() can walk to it.\n\t\t// User-supplied branch stays unregistered — `fromAny` returns the\n\t\t// caller's owned Node, which is owned by their graph; mounting it\n\t\t// here would corrupt cross-graph ownership (mirrors MemoryWithTiers's\n\t\t// context-branch policy).\n\t\tif (opts.context) {\n\t\t\tthis._contextNode = fromAny(opts.context);\n\t\t} else {\n\t\t\tthis._contextNode = this.state<unknown>(\"_context\", null);\n\t\t}\n\t}\n\n\tprivate _runRetrieval(\n\t\tstoreMap: ReadonlyMap<string, TMem>,\n\t\tctx: unknown,\n\t\tquery: RetrievalQuery,\n\t): { packed: RetrievalEntry<TMem>[]; trace: RetrievalTrace<TMem> } {\n\t\tconst opts = this._opts;\n\t\tconst candidateMap = new Map<\n\t\t\tstring,\n\t\t\t{ value: TMem; sources: Set<\"vector\" | \"graph\" | \"store\"> }\n\t\t>();\n\n\t\tlet vectorCandidates: VectorSearchResult<TMem>[] = [];\n\t\tif (this._vectors && query.vector) {\n\t\t\t// Wave A migrated `vectorIndex` to a reactive-only read API\n\t\t\t// (`searchNode`); inline the equivalent flat-cosine snapshot scan\n\t\t\t// here since `_runRetrieval` is sync and `searchNode` is async-shaped.\n\t\t\t// `patterns/ai/memory/` is queued for its own audit per the Wave A\n\t\t\t// session doc § D.1.\n\t\t\tconst q = query.vector;\n\t\t\tconst snapshot = this._vectors.entries.cache as\n\t\t\t\t| ReadonlyMap<string, VectorRecord<TMem>>\n\t\t\t\t| undefined;\n\t\t\tif (snapshot && snapshot.size > 0 && this._topK > 0) {\n\t\t\t\tconst scored = [...snapshot.values()]\n\t\t\t\t\t.map(\n\t\t\t\t\t\t(row): VectorSearchResult<TMem> => ({\n\t\t\t\t\t\t\tid: row.id,\n\t\t\t\t\t\t\tscore: cosineSimilarity(q, row.vector),\n\t\t\t\t\t\t\t...(row.meta !== undefined ? { meta: row.meta } : {}),\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t\t.sort((a, b) => b.score - a.score)\n\t\t\t\t\t.slice(0, this._topK);\n\t\t\t\tvectorCandidates = scored;\n\t\t\t\tfor (const vc of vectorCandidates) {\n\t\t\t\t\tconst mem = storeMap.get(vc.id);\n\t\t\t\t\tif (mem) candidateMap.set(vc.id, { value: mem, sources: new Set([\"vector\"]) });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst graphExpanded: string[] = [];\n\t\tif (this._kg) {\n\t\t\t// Wave A migrated `knowledgeGraph` to a reactive-only `relatedNode`\n\t\t\t// API; inline the equivalent adjacency-snapshot scan here for the\n\t\t\t// sync expansion. `adjacencyOut` / `adjacencyIn` are kept warm by\n\t\t\t// the kg's own internal keepalive disposers, so `.cache` is always\n\t\t\t// populated post-construction.\n\t\t\tconst adjOut = this._kg.adjacencyOut.cache as\n\t\t\t\t| ReadonlyMap<string, readonly KnowledgeEdge<string>[]>\n\t\t\t\t| undefined;\n\t\t\tconst adjIn = this._kg.adjacencyIn.cache as\n\t\t\t\t| ReadonlyMap<string, readonly KnowledgeEdge<string>[]>\n\t\t\t\t| undefined;\n\t\t\tconst seedIds = [...(query.entityIds ?? []), ...[...candidateMap.keys()]];\n\t\t\tconst visited = new Set<string>();\n\t\t\tlet frontier = seedIds;\n\t\t\tfor (let depth = 0; depth < this._graphDepth; depth++) {\n\t\t\t\tconst nextFrontier: string[] = [];\n\t\t\t\tfor (const id of frontier) {\n\t\t\t\t\tif (visited.has(id)) continue;\n\t\t\t\t\tvisited.add(id);\n\t\t\t\t\tconst outEdges = adjOut?.get(id) ?? [];\n\t\t\t\t\tconst inEdges = adjIn?.get(id) ?? [];\n\t\t\t\t\tfor (const edge of outEdges) {\n\t\t\t\t\t\tconst targetId = edge.to;\n\t\t\t\t\t\tif (!visited.has(targetId)) {\n\t\t\t\t\t\t\tnextFrontier.push(targetId);\n\t\t\t\t\t\t\tconst mem = storeMap.get(targetId);\n\t\t\t\t\t\t\tif (mem) {\n\t\t\t\t\t\t\t\tconst existing = candidateMap.get(targetId);\n\t\t\t\t\t\t\t\tif (existing) existing.sources.add(\"graph\");\n\t\t\t\t\t\t\t\telse candidateMap.set(targetId, { value: mem, sources: new Set([\"graph\"]) });\n\t\t\t\t\t\t\t\tgraphExpanded.push(targetId);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Inbound edges: traverse to the `from` side. Match the\n\t\t\t\t\t// previous `kg.related(id)` semantics, which returned both\n\t\t\t\t\t// `from === id` and `to === id` matches.\n\t\t\t\t\tfor (const edge of inEdges) {\n\t\t\t\t\t\tconst targetId = edge.from;\n\t\t\t\t\t\tif (!visited.has(targetId)) {\n\t\t\t\t\t\t\tnextFrontier.push(targetId);\n\t\t\t\t\t\t\tconst mem = storeMap.get(targetId);\n\t\t\t\t\t\t\tif (mem) {\n\t\t\t\t\t\t\t\tconst existing = candidateMap.get(targetId);\n\t\t\t\t\t\t\t\tif (existing) existing.sources.add(\"graph\");\n\t\t\t\t\t\t\t\telse candidateMap.set(targetId, { value: mem, sources: new Set([\"graph\"]) });\n\t\t\t\t\t\t\t\tgraphExpanded.push(targetId);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfrontier = nextFrontier;\n\t\t\t}\n\t\t}\n\t\tfor (const [key, mem] of storeMap) {\n\t\t\tif (!candidateMap.has(key)) {\n\t\t\t\tcandidateMap.set(key, { value: mem, sources: new Set([\"store\"]) });\n\t\t\t}\n\t\t}\n\n\t\tconst qDepth = query.context?.length ?? 0;\n\t\tconst ranked: RetrievalEntry<TMem>[] = [];\n\t\tfor (const [key, { value, sources }] of candidateMap) {\n\t\t\tconst entryContext = opts.contextOf ? opts.contextOf(value) : undefined;\n\t\t\tlet score = opts.score(value, ctx);\n\t\t\tif (this._contextWeight > 0 && qDepth > 0) {\n\t\t\t\tconst shared = sharedPrefixDepth(query.context, entryContext);\n\t\t\t\tif (shared > 0) score = score * (1 + (this._contextWeight * shared) / qDepth);\n\t\t\t}\n\t\t\tconst entry: RetrievalEntry<TMem> = entryContext\n\t\t\t\t? { key, value, score, sources: [...sources], context: entryContext }\n\t\t\t\t: { key, value, score, sources: [...sources] };\n\t\t\tranked.push(entry);\n\t\t}\n\t\tranked.sort((a, b) => b.score - a.score);\n\n\t\tconst packed: RetrievalEntry<TMem>[] = [];\n\t\tlet usedBudget = 0;\n\t\tfor (const entry of ranked) {\n\t\t\tconst c = opts.cost(entry.value);\n\t\t\tif (usedBudget + c > this._budget && packed.length > 0) break;\n\t\t\tpacked.push(entry);\n\t\t\tusedBudget += c;\n\t\t}\n\n\t\treturn { packed, trace: { vectorCandidates, graphExpanded, ranked, packed } };\n\t}\n\n\t/**\n\t * Reactive consumer API — chain into the graph.\n\t *\n\t * Each call constructs its own per-input subgraph mounted at\n\t * `retrieve_${id}` (auto-incrementing within this MemoryRetrievalGraph\n\t * instance) with named nodes:\n\t *\n\t * - `context` — `fromAny(queryInput)` projection (so the input node is\n\t * visible to `describe()` even when callers pass a raw value).\n\t * - `result` — pure derived `{ packed, trace }`.\n\t * - `projection` — the packed-array node returned to the caller.\n\t *\n\t * `result` declares the substrate's `store.entries`, the optional\n\t * `context` Node, the local `context` projection, and (when configured)\n\t * `vectors.entries` / `kg.adjacencyOut` / `kg.adjacencyIn` as deps —\n\t * so vector upserts and KG mutations re-trigger retrieval even when\n\t * the input is unchanged.\n\t *\n\t * **Lifecycle contract (DS-13.5.C, 2026-05-01).** The per-call subgraph\n\t * stays mounted while the returned `projection` has at least one\n\t * subscriber. When the last subscriber unsubscribes, projection's\n\t * `deactivate` cleanup hook fires (canonical \"last unsubscribe\" signal\n\t * via the existing `NodeFnCleanup.onDeactivation` protocol), which calls\n\t * `parent.remove(retrieve_${id})` and tears the per-call topology\n\t * down via TEARDOWN cascade (post-DS-13.5.A Q16, COMPLETE auto-precedes).\n\t *\n\t * **Single-shot lifecycle.** This auto-unmount is keyed to the FIRST\n\t * last-unsubscribe event — projection is non-resubscribable from the\n\t * caller's perspective. Callers who need to subscribe / unsubscribe /\n\t * re-subscribe should hold a long-lived subscription externally (e.g.\n\t * `keepalive(projection)`) or call `retrieveReactive(...)` again to\n\t * mount a fresh per-call subgraph.\n\t *\n\t * **Caller obligation.** Either subscribe to `projection` (and\n\t * eventually unsubscribe to trigger cleanup) OR drop the returned\n\t * reference without subscribing — in the no-subscribe case the\n\t * subgraph is dormant (no compute fires) and a parent `destroy()`\n\t * cascade reclaims it. Holding `projection` without subscribing AND\n\t * without ever destroying the parent is the leak case the JSDoc above\n\t * the C1 rework covers.\n\t *\n\t * One-shot callers use `awaitSettled(retrieveReactive(input))`.\n\t */\n\tretrieveReactive(\n\t\tqueryInput: NodeInput<RetrievalQuery | null>,\n\t): Node<ReadonlyArray<RetrievalEntry<TMem>>> {\n\t\tconst id = ++this._retrieveSeq;\n\t\tconst segment = `retrieve_${id}`;\n\n\t\t// Per-call subgraph — owns the wiring, the keepalive, and the\n\t\t// teardown. Mounted on `this` so it's visible in `describe()` and\n\t\t// reachable via `${parent}::retrieve_${id}::result` etc.\n\t\tconst sub = new Graph(segment);\n\n\t\t// Wrap the input as a local pass-through so the per-call subgraph\n\t\t// shows the query source in `describe()` regardless of where the\n\t\t// caller's node lives in the broader topology. `fromAny` returns\n\t\t// the original Node when given a Node, otherwise wraps a\n\t\t// value/promise into a producer.\n\t\t//\n\t\t// DS-13.5.C: registered via `sub.derived(...)` (Graph helper) for\n\t\t// equals plumbing + automatic registration; replaces the prior raw\n\t\t// `node([inputNode], fn) + sub.add(...)` shape.\n\t\tconst inputNode = fromAny(queryInput);\n\t\tconst localContext = sub.derived<RetrievalQuery | null>(\n\t\t\t\"context\",\n\t\t\t[inputNode],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\treturn [(data[0] as RetrievalQuery | null) ?? null];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: aiMeta(\"retrieval_query_input\"),\n\t\t\t\tinitial: null,\n\t\t\t},\n\t\t);\n\n\t\t// /qa F-6 (2026-04-30): declare vectors / kg substrate Node refs as\n\t\t// deps so vector upserts / KG mutations re-trigger retrieval even\n\t\t// when query / context / store snapshots are unchanged. The\n\t\t// `_runRetrieval` body reads `.cache` from these substrates; before\n\t\t// this fix those reads were undeclared §28 closure-mirrors.\n\t\tconst resultDeps: (string | Node<unknown>)[] = [\n\t\t\tthis._store.store.entries,\n\t\t\tthis._contextNode,\n\t\t\tlocalContext,\n\t\t];\n\t\tif (this._vectors) resultDeps.push(this._vectors.entries as Node<unknown>);\n\t\tif (this._kg) {\n\t\t\tresultDeps.push(this._kg.adjacencyOut as Node<unknown>);\n\t\t\tresultDeps.push(this._kg.adjacencyIn as Node<unknown>);\n\t\t}\n\n\t\t// DS-13.5.C: migrated to `sub.derived(...)` for equals plumbing +\n\t\t// automatic registration.\n\t\tconst result = sub.derived<{\n\t\t\tpacked: ReadonlyArray<RetrievalEntry<TMem>>;\n\t\t\ttrace: RetrievalTrace<TMem> | null;\n\t\t}>(\n\t\t\t\"result\",\n\t\t\tresultDeps,\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst query = data[2];\n\t\t\t\tif (query == null) {\n\t\t\t\t\treturn [{ packed: [] as ReadonlyArray<RetrievalEntry<TMem>>, trace: null }];\n\t\t\t\t}\n\t\t\t\tconst storeMap =\n\t\t\t\t\t(data[0] as ReadonlyMap<string, TMem> | undefined) ?? new Map<string, TMem>();\n\t\t\t\tconst { packed, trace } = this._runRetrieval(storeMap, data[1], query as RetrievalQuery);\n\t\t\t\treturn [{ packed, trace }];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: aiMeta(\"retrieval_reactive_result\"),\n\t\t\t\tinitial: { packed: [] as ReadonlyArray<RetrievalEntry<TMem>>, trace: null },\n\t\t\t},\n\t\t);\n\n\t\t// DS-13.5.C: projection stays as raw `node()` (not `sub.derived`)\n\t\t// because the keepalive disposer is wired via the fn's\n\t\t// `NodeFnCleanup.onDeactivation` hook — projection's cleanup-on-last-\n\t\t// unsubscribe is what drives `parent.remove(segment)`. The Graph\n\t\t// `.derived()` helper drops the cleanup return, so the raw form\n\t\t// is required here. `equals: packedEquals` is preserved verbatim.\n\t\tconst projection = node<ReadonlyArray<RetrievalEntry<TMem>>>(\n\t\t\t[result],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((b, i) =>\n\t\t\t\t\tb != null && b.length > 0 ? b.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as { packed: ReadonlyArray<RetrievalEntry<TMem>> }).packed);\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t// Auto-unmount on last unsubscribe (DS-13.5.C).\n\t\t\t\t\t\t// Idempotent: try/catch covers the case where the\n\t\t\t\t\t\t// segment was already removed (e.g. parent destroy\n\t\t\t\t\t\t// cascade ran first, or the caller called remove()\n\t\t\t\t\t\t// manually).\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tthis.remove(segment);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* best-effort cleanup */\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"projection\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"retrieval_reactive\"),\n\t\t\t\tinitial: [] as ReadonlyArray<RetrievalEntry<TMem>>,\n\t\t\t\tequals: packedEquals,\n\t\t\t},\n\t\t);\n\t\tsub.add(projection, { name: \"projection\" });\n\n\t\tthis.mount(segment, sub);\n\t\treturn projection;\n\t}\n}\n\n/**\n * Build the retrieval pipeline (vector + KG + budget packing) over a\n * `DistillBundle` and optional `vectors` / `kg` substrates. Returns a\n * `MemoryRetrievalGraph` exposing `retrieval` / `retrievalTrace` reactive\n * state and the `retrieveReactive(input)` consumer method.\n */\nexport function memoryRetrieval<TMem>(\n\topts: MemoryRetrievalOptions<TMem>,\n): MemoryRetrievalGraph<TMem> {\n\treturn new MemoryRetrievalGraph<TMem>(opts);\n}\n","/**\n * `promptNode` — universal LLM transform as a reactive derived node.\n *\n * The shape: `deps → messagesNode (derived) → switchMap → response (producer) → output`.\n * Each upstream wave is one LLM call; superseding waves cancel the in-flight\n * call via the abort signal threaded through `nodeSignal(opts.abort)`.\n *\n * The producer-shape on the inner is load-bearing: it emits exactly one DATA\n * + COMPLETE per wave, so the outer switchMap sees one DATA per wave (matches\n * the `HarnessExecutor` contract). A `node([response], (batchData, actions, ctx) => {\n * const data = ...; actions.emit(parse(data[0]));\n * }, { describeKind: \"derived\" })` would have its\n * own first-run / push-on-subscribe semantics that can leak a transient null\n * before the real response arrives — observed and reverted in an earlier\n * attempt; see SESSION-ai-harness-module-review.md line 3654 for context.\n * Locked as path (b) producer-based by Session C (2026-04-27); inner-node\n * naming aligned to `prompt_node::response` per the C+D widening (2026-04-30).\n *\n * **Retry / replay-cache.** Stack middleware on the adapter:\n *\n * ```ts\n * import { withRetry, withReplayCache } from \"@graphrefly/graphrefly/patterns/ai\";\n *\n * const adapter = withRetry(\n * withReplayCache(baseAdapter, { keyFn: (ctx) => ctx.messages[0].content }),\n * { count: 3, backoff: 200 },\n * );\n * const result = promptNode(adapter, [input], (q) => q);\n * ```\n *\n * `promptNode` no longer ships `retries` / `cache` options — they duplicated\n * middleware already at the adapter layer.\n *\n * **Cross-wave cache (COMPOSITION-GUIDE §32).** The switchMap output cache\n * survives across new outer DATAs — `promptNode`'s cached value persists\n * until the next wave fully resolves. Consumers that need to distinguish\n * \"fresh value for THIS session\" from \"stale cache from a prior session\"\n * (e.g. `agentLoop` resetting on new `run()`) must add a `node([])` mirror\n * at their session boundary and depend on the mirror, not the `promptNode`\n * output directly. `promptNode` itself stays primitive — it does not\n * embed a state-mirror.\n *\n * @module\n */\n\nimport { COMPLETE, DATA, ERROR, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { nodeSignal } from \"../../../base/sources/settled.js\";\nimport { aiMeta, stripFences } from \"../_internal.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tToolDefinition,\n} from \"../adapters/core/types.js\";\n\nexport type PromptNodeOptions = {\n\tname?: string;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Output format:\n\t * - `\"text\"` (default) — emit the response content as a string.\n\t * - `\"json\"` — `JSON.parse` the content (markdown fences stripped).\n\t * - `\"raw\"` — emit the full {@link LLMResponse} object (subsumes the\n\t * pre-Tier-2.3 `fromLLM` shape; use this when you need `usage` /\n\t * `toolCalls` / `finishReason` alongside `content`).\n\t */\n\tformat?: \"text\" | \"json\" | \"raw\";\n\t/**\n\t * Reactive tool definitions forwarded to the adapter. Pair with\n\t * `format: \"raw\"` (or read `toolCalls` from a downstream parser) when\n\t * tool-calling is in scope.\n\t *\n\t * **Reactive declared edge** (DF12, Tier 7): `tools` is a `Node` so the\n\t * tools list participates in `describe()` topology and `explain()` causal\n\t * chains. The tools Node is added to `messagesNode`'s declared deps —\n\t * tools changes re-invoke the LLM (treated as a new call envelope).\n\t * Wrap with `distinctUntilChanged` upstream if your tool selector emits\n\t * noisy duplicates that would otherwise spam the adapter. See\n\t * COMPOSITION-GUIDE §31 (Dynamic tool selection) for the canonical\n\t * `toolSelector` pattern that produces this Node.\n\t *\n\t * **Activation note:** since `tools` is a real declared dep, `messagesNode`\n\t * waits for the tools Node to DATA at least once before firing\n\t * (push-on-subscribe SENTINEL gate). Pass a `node<ToolDefinition[]>([], { initial: [] })`\n\t * if you want immediate activation with no tools, or the latest published\n\t * `toolSelector.tools` Node.\n\t */\n\ttools?: Node<readonly ToolDefinition[]>;\n\t/**\n\t * Optional system prompt. Forwarded via `opts.systemPrompt` to the adapter\n\t * only — never pushed as a `{role:\"system\"}` message (avoiding the\n\t * double-send class of bug where adapters that normalize both shapes end\n\t * up with two system entries).\n\t */\n\tsystemPrompt?: string;\n\t/**\n\t * Optional reactive abort signal. When the node emits `true`, the in-flight\n\t * `adapter.invoke()` call is cancelled via `AbortController.abort()`.\n\t * Threaded through `nodeSignal(abort)` — a one-shot bridge. Useful inside\n\t * agent state machines where a separate `aborted` state should cancel the\n\t * current LLM call without superseding via switchMap.\n\t */\n\tabort?: Node<boolean>;\n\tmeta?: Record<string, unknown>;\n};\n\n/** Extract text content from an LLM response, handling various response shapes. */\nfunction extractContent(resp: unknown): string {\n\tif (resp != null && typeof resp === \"object\" && \"content\" in resp) {\n\t\treturn String((resp as LLMResponse).content);\n\t}\n\tif (typeof resp === \"string\") return resp;\n\treturn String(resp);\n}\n\nfunction previewContent(text: string, max = 200): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, max)}…`;\n}\n\n/**\n * Universal LLM transform: wraps a prompt template + model adapter into a reactive derived node.\n * Re-invokes the LLM whenever any dep changes. Suitable for triage, QA, hypothesis, parity, etc.\n *\n * **Topology** (visible in `describe()`):\n * ```\n * <deps...>, [tools?] → <name>::messages (derived, meta.ai = prompt_node::messages)\n * <name>::messages → <name>::output (switchMap product, meta.ai = prompt_node::output)\n * per-wave inner: <name>::response (producer, meta.ai = prompt_node::response)\n * ```\n * When `opts.tools` is supplied, the tools `Node` is appended to\n * `messagesNode`'s declared deps so it appears as a real edge in `describe()`\n * / `explain()` (DF12, Tier 7).\n *\n * **No-input semantics** (matches the codebase-wide SENTINEL convention):\n * - **Initial no-input** (no real input has ever arrived) — emits nothing.\n * Outer cache stays `undefined`; `subscribe` consumers see no DATA event.\n * Use this to keep downstream gating clean: a `withLatestFrom`-paired\n * trigger won't fire until the LLM has actually produced something.\n * - **Mid-flow no-input** (input dropped to nullish after at least one\n * real LLM call) — emits `null` as a domain \"input went away\" signal.\n * Downstream consumers can distinguish \"haven't started\" from \"input\n * gone.\"\n *\n * **Retries / caching:** stack `withRetry` / `withReplayCache` middleware on the\n * `adapter` argument — `promptNode` no longer ships its own duplicated retry /\n * cache loops (pre-1.0 cleanup, see review session 1).\n *\n * @param adapter - LLM adapter (provider-agnostic). Wrap with `withRetry` /\n * `withReplayCache` middleware for transient-error tolerance\n * or replay caching.\n * @param deps - Input nodes whose values feed the prompt.\n * @param prompt - Static string or template function receiving dep values.\n * @param opts - Optional configuration.\n * @returns `Node` emitting LLM responses (string or parsed JSON).\n */\n// Overload 1: `format: \"raw\"` constrains the emit type to `LLMResponse | null`\n// (the full adapter response, with `usage` / `toolCalls` / `finishReason`).\n// Subsumes the pre-Tier-2.3 `fromLLM` shape.\nexport function promptNode(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts: PromptNodeOptions & { format: \"raw\" },\n): Node<LLMResponse | null>;\n// Overload 2: `format: \"text\" | \"json\"` (default text) — emit-type is the\n// caller's `T` (defaults to `string`). For `\"json\"` callers typically pass\n// the parsed shape (e.g. `promptNode<MyShape>(...)`).\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: Omit<PromptNodeOptions, \"format\"> & { format?: \"text\" | \"json\" },\n): Node<T | null>;\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: PromptNodeOptions,\n): Node<T | null> {\n\tconst format = opts?.format ?? \"text\";\n\tconst baseName = opts?.name ?? \"prompt_node\";\n\n\t// qa A8: tools without `format: \"raw\"` is a footgun — adapter receives\n\t// the tool definitions and may produce `toolCalls`, but the emit path\n\t// only extracts `content`. Warn at construction; downstream parsers\n\t// reading `toolCalls` from a custom `format: \"raw\"` consumer pattern\n\t// can ignore by setting `format: \"raw\"` (intent now matches behavior).\n\tif (opts?.tools !== undefined && format !== \"raw\") {\n\t\tconsole.warn(\n\t\t\t\"promptNode: `tools` is set but `format !== 'raw'`. \" +\n\t\t\t\t\"Tool calls in the response will be silently dropped — set \" +\n\t\t\t\t\"`format: 'raw'` to receive the full LLMResponse with `toolCalls`.\",\n\t\t);\n\t}\n\n\t// SENTINEL semantics rely on the universal first-run gate + standard\n\t// prevData semantics (undefined = SENTINEL, any other value = DATA seen):\n\t// - **Initial no-input** (no dep has ever DATA'd, so prevData is\n\t// undefined across the board): the `derived`'s first-run gate blocks\n\t// `messagesNode`'s fn entirely. It never emits, switchMap never\n\t// fires, outer cache stays `undefined`.\n\t// - **Mid-flow no-input** (deps previously DATA'd then went nullish):\n\t// fn runs, returns `[]`, switchMap dispatches the `node([], { initial: null })`\n\t// branch → outer emits `null` as the domain \"input went away\" signal.\n\t// No `initial: []` and no closure flag — `prevData === undefined` is\n\t// already the sentinel marker, and the gate already enforces \"don't fire\n\t// fn until every dep has DATA'd at least once.\"\n\t//\n\t// DF12: when `opts.tools` is a Node, it's appended to `messagesNode`'s\n\t// declared deps. The fn slices values into user-deps + tools, and emits\n\t// an envelope `{ messages, tools }` so switchMap's per-wave inner can\n\t// read the latest tools via the reactive edge instead of a closure.\n\ttype Envelope = {\n\t\tmessages: readonly ChatMessage[];\n\t\ttools: readonly ToolDefinition[] | undefined;\n\t};\n\tconst userDepsLength = deps.length;\n\tconst allDeps: readonly Node<unknown>[] =\n\t\topts?.tools !== undefined ? [...deps, opts.tools as Node<unknown>] : deps;\n\tconst messagesNode = node<Envelope>(\n\t\tallDeps as Node<unknown>[],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst userValues = data.slice(0, userDepsLength);\n\t\t\tconst toolsValue =\n\t\t\t\topts?.tools !== undefined\n\t\t\t\t\t? (data[userDepsLength] as readonly ToolDefinition[] | undefined)\n\t\t\t\t\t: undefined;\n\t\t\t// Dep-level null guard (composition guide §8): if any USER dep is\n\t\t\t// nullish, emit empty messages → switchMap emits null (mid-flow\n\t\t\t// drop-out). The tools dep can legitimately be empty `[]`; only\n\t\t\t// user deps gate the call.\n\t\t\tif (userValues.some((v) => v == null)) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst text = typeof prompt === \"string\" ? prompt : prompt(...userValues);\n\t\t\tif (!text) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// systemPrompt forwarded through invoke opts only (no double-send).\n\t\t\tactions.emit({\n\t\t\t\tmessages: [{ role: \"user\" as const, content: text }],\n\t\t\t\ttools: toolsValue,\n\t\t\t});\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::messages`,\n\t\t\tmeta: aiMeta(\"prompt_node::messages\"),\n\t\t},\n\t);\n\n\tconst result = switchMap<Envelope, T | null>(\n\t\tmessagesNode,\n\t\t(envelope) => {\n\t\t\tconst { messages: msgs, tools } = envelope;\n\t\t\tif (!msgs || msgs.length === 0) {\n\t\t\t\treturn node<T | null>([], { initial: null }) as NodeInput<T | null>;\n\t\t\t}\n\n\t\t\t// Producer ensures exactly one DATA + COMPLETE per wave; switchMap\n\t\t\t// sees one DATA, the harness's \"one emission per wave\" contract is\n\t\t\t// honored. Earlier attempts using a derived node leaked\n\t\t\t// transient nulls via the derived's first-run gate.\n\t\t\treturn node<T | null>(\n\t\t\t\t(_data, actions) => {\n\t\t\t\t\tlet done = false;\n\t\t\t\t\tlet cancelled = false;\n\t\t\t\t\tlet abortDispose: (() => void) | undefined;\n\n\t\t\t\t\tconst invokeOpts: LLMInvokeOptions = {\n\t\t\t\t\t\tmodel: opts?.model,\n\t\t\t\t\t\ttemperature: opts?.temperature,\n\t\t\t\t\t\tmaxTokens: opts?.maxTokens,\n\t\t\t\t\t\tsystemPrompt: opts?.systemPrompt,\n\t\t\t\t\t\t...(tools !== undefined ? { tools } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tif (opts?.abort) {\n\t\t\t\t\t\tconst sig = nodeSignal(opts.abort);\n\t\t\t\t\t\tinvokeOpts.signal = sig.signal;\n\t\t\t\t\t\tabortDispose = sig.dispose;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinvokeResult = adapter.invoke(msgs, invokeOpts);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\t\treturn () => {\n\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callNode = fromAny(invokeResult);\n\n\t\t\t\t\tconst sub = callNode.subscribe((batch) => {\n\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\tfor (const msg of batch) {\n\t\t\t\t\t\t\t// F-11: re-check `cancelled` (and `done`) at the top of\n\t\t\t\t\t\t\t// each per-message iteration so a teardown / abort that\n\t\t\t\t\t\t\t// fires synchronously between messages stops processing\n\t\t\t\t\t\t\t// further batched messages immediately.\n\t\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\t\t\t\tconst resp = msg[1] as LLMResponse;\n\t\t\t\t\t\t\t\t// `format: \"raw\"` bypasses parsing — emit the full\n\t\t\t\t\t\t\t\t// LLMResponse object (subsumes the pre-Tier-2.3 `fromLLM`\n\t\t\t\t\t\t\t\t// output shape).\n\t\t\t\t\t\t\t\tif (format === \"raw\") {\n\t\t\t\t\t\t\t\t\tactions.emit(resp as unknown as T);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// F-12: cache the extracted content once on the\n\t\t\t\t\t\t\t\t\t// parse-failure path so we don't call\n\t\t\t\t\t\t\t\t\t// `extractContent(resp)` twice (once for parsing,\n\t\t\t\t\t\t\t\t\t// once for the error-message preview).\n\t\t\t\t\t\t\t\t\tlet content: string;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tcontent = extractContent(resp);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t// extractContent itself failed — propagate as\n\t\t\t\t\t\t\t\t\t\t// an ERROR with a generic raw-extraction message.\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to extract content from LLM response: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal-error\n\t\t\t\t\t\t\t\t\t\t// branches so we don't retain the AbortController\n\t\t\t\t\t\t\t\t\t\t// after the wave terminates. Idempotent.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst parsed: T =\n\t\t\t\t\t\t\t\t\t\t\tformat === \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t? (JSON.parse(stripFences(content)) as T)\n\t\t\t\t\t\t\t\t\t\t\t\t: (content as unknown as T);\n\t\t\t\t\t\t\t\t\t\tactions.emit(parsed);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to parse LLM response as JSON: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}\\n Raw content (first 200 chars): ${previewContent(content)}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on parse-error\n\t\t\t\t\t\t\t\t\t\t// terminal branch.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (msg[0] === ERROR) {\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal ERROR branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[ERROR, msg[1]]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else if (msg[0] === COMPLETE) {\n\t\t\t\t\t\t\t\t// Adapter completed — propagate. emit() above already\n\t\t\t\t\t\t\t\t// queued the parsed value so the wave carries DATA + COMPLETE.\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal COMPLETE branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Spec §1.3.6 forward-unknown — DIRTY/RESOLVED/INVALIDATE/\n\t\t\t\t\t\t\t\t// PAUSE/RESUME etc. should propagate so downstream caches /\n\t\t\t\t\t\t\t\t// flow-control hooks aren't starved. Re-typed `as never`\n\t\t\t\t\t\t\t\t// because the call's NodeInput<LLMResponse> message tuple\n\t\t\t\t\t\t\t\t// is wider than the unbound `T` projection.\n\t\t\t\t\t\t\t\tactions.down([msg as never]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\tsub();\n\t\t\t\t\t\t// F-7: cleanup callback's abortDispose call is idempotent —\n\t\t\t\t\t\t// the terminal-branch dispose above sets `abortDispose =\n\t\t\t\t\t\t// undefined` so this is a no-op when terminal-fired.\n\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\t\tname: `${baseName}::response`,\n\t\t\t\t\tmeta: aiMeta(\"prompt_node::response\"),\n\t\t\t\t},\n\t\t\t) as NodeInput<T | null>;\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::output`,\n\t\t\tmeta: opts?.meta\n\t\t\t\t? { ...aiMeta(\"prompt_node::output\"), ...opts.meta }\n\t\t\t\t: aiMeta(\"prompt_node::output\"),\n\t\t},\n\t);\n\n\treturn result;\n}\n","// ---------------------------------------------------------------------------\n// promptCall — public single-shot LLM JSON helper (Tier 4.6 Wave AM Unit 4\n// promotion from the previously-internal `llmJsonCall` in\n// `patterns/ai/memory/llm-memory.ts`).\n//\n// Wraps {@link promptNode} for the common \"one-shot LLM JSON call per input\"\n// shape: a per-call `node([], { initial: input })` is wrapped, the prompt builder runs against\n// it, and the returned `NodeInput<TOut>` slots into reactive callbacks like\n// `distill`'s `extractFn` / `consolidateFn`. Inherits markdown-fence stripping\n// and content-preview parse errors from `promptNode({format: \"json\"})`.\n//\n// `llmExtractor` / `llmConsolidator` are now thin wrappers over `promptCall`.\n// ---------------------------------------------------------------------------\n\nimport { node } from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport type { Extraction } from \"../../../base/composition/distill.js\";\nimport type { LLMAdapter } from \"../adapters/core/types.js\";\nimport { promptNode } from \"./prompt-node.js\";\n\n/** Options accepted by {@link promptCall}, {@link llmExtractor}, and {@link llmConsolidator}. */\nexport type PromptCallOptions = {\n\tadapter: LLMAdapter;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Optional name forwarded to the underlying `promptNode` (used as the\n\t * `<name>::messages` / `<name>::response` / `<name>::output` path prefix).\n\t * Defaults differ per call site so multiple `promptCall`s wired into the\n\t * same graph don't collide on `prompt_node::output`.\n\t */\n\tname?: string;\n};\n\n/**\n * Build a one-shot LLM JSON-call factory: each invocation wraps `input` in a\n * fresh `node([], { initial: input })`, delegates to `promptNode({format: \"json\"})`, and\n * returns a `NodeInput<TOut>` that the caller plugs into `distill` /\n * `agentLoop` / any reactive composition that accepts `NodeInput`.\n *\n * **Per-call lifecycle.** The returned `NodeInput<TOut>` is a producer that\n * emits exactly one `DATA` per upstream input (per Tier 1.2 Session C lock —\n * `promptNode` guarantees one DATA per wave). When the consumer's switchMap\n * supersedes it, the per-call `node([], { initial: input })` and the inner `prompt_node::response`\n * tear down together.\n *\n * @param systemPrompt - System message sent on every call.\n * @param buildUserContent - Per-input user-content builder (must be JSON-stringifiable).\n * @param opts - Adapter + model/temperature/maxTokens + optional name prefix.\n * @param defaultName - Path-prefix fallback when `opts.name` is omitted.\n * @returns Factory `(input: TIn) => NodeInput<TOut>`.\n *\n * @category patterns\n */\nexport function promptCall<TIn, TOut>(\n\tsystemPrompt: string,\n\tbuildUserContent: (input: TIn) => string,\n\topts: PromptCallOptions,\n\tdefaultName: string,\n): (input: TIn) => NodeInput<TOut> {\n\tconst name = opts.name ?? defaultName;\n\treturn (input: TIn) => {\n\t\t// One-shot node([], { initial: input }) per call — switchMap teardown inside the\n\t\t// consumer (e.g. distill) reclaims the node when the next upstream\n\t\t// arrives or the bundle disposes.\n\t\tconst inputState = node<TIn>([], { initial: input });\n\t\treturn promptNode<TOut>(\n\t\t\topts.adapter,\n\t\t\t[inputState as never],\n\t\t\t(value: unknown) => buildUserContent(value as TIn),\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tformat: \"json\",\n\t\t\t\tsystemPrompt,\n\t\t\t\tmodel: opts.model,\n\t\t\t\ttemperature: opts.temperature ?? 0,\n\t\t\t\tmaxTokens: opts.maxTokens,\n\t\t\t},\n\t\t) as NodeInput<TOut>;\n\t};\n}\n\n/** Options accepted by {@link llmExtractor} and {@link llmConsolidator}. */\nexport type LLMExtractorOptions = PromptCallOptions & {\n\t/**\n\t * Cap the dedup-hint slice of `existingKeys` passed to the LLM. Larger\n\t * stores ship more keys (better dedup recall) at the cost of prompt size.\n\t * Default 100. Set to `Infinity` to forward every key.\n\t */\n\tmaxExistingKeys?: number;\n};\n\n/** Alias for backward compatibility. */\nexport type LLMConsolidatorOptions = LLMExtractorOptions;\n\n/**\n * Returns an `extractFn` callback for `distill()` that invokes an LLM to\n * extract structured memories from raw input.\n *\n * The system prompt should instruct the LLM to return JSON matching\n * `Extraction<TMem>` shape: `{ upsert: [{ key, value }], remove?: [key] }`.\n *\n * Built on `promptNode({format: \"json\"})` — inherits markdown-fence stripping\n * and content-preview parse errors. Stack `withRetry` on the adapter for\n * transient-error tolerance (see `patterns/ai/adapters/middleware/retry.ts`).\n */\nexport function llmExtractor<TRaw, TMem>(\n\tsystemPrompt: string,\n\topts: LLMExtractorOptions,\n): (raw: TRaw, existing: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>> {\n\tconst cap = opts.maxExistingKeys ?? 100;\n\tconst call = promptCall<{ raw: TRaw; existingKeys: string[] }, Extraction<TMem>>(\n\t\tsystemPrompt,\n\t\t(input) => JSON.stringify({ input: input.raw, existingKeys: input.existingKeys }),\n\t\topts,\n\t\t\"llmExtractor\",\n\t);\n\treturn (raw: TRaw, existing: ReadonlyMap<string, TMem>) => {\n\t\tconst existingKeys =\n\t\t\tcap === Number.POSITIVE_INFINITY ? [...existing.keys()] : [...existing.keys()].slice(0, cap);\n\t\treturn call({ raw, existingKeys });\n\t};\n}\n\n/**\n * Returns a `consolidateFn` callback for `distill()` that invokes an LLM to\n * cluster and merge related memories.\n */\nexport function llmConsolidator<TMem>(\n\tsystemPrompt: string,\n\topts: LLMConsolidatorOptions,\n): (entries: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>> {\n\tconst call = promptCall<readonly { key: string; value: TMem }[], Extraction<TMem>>(\n\t\tsystemPrompt,\n\t\t(memories) => JSON.stringify({ memories }),\n\t\topts,\n\t\t\"llmConsolidator\",\n\t);\n\treturn (entries: ReadonlyMap<string, TMem>) => {\n\t\tconst memories = [...entries.entries()].map(([key, value]) => ({ key, value }));\n\t\treturn call(memories);\n\t};\n}\n"],"mappings":"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","names":["node","batch","node","batch","node","node","batch","ERROR","node","keepalive","Graph","Graph","node","batch","keepalive","ERROR","DATA","node","fromAny","keepalive","reactiveMap","Graph","Graph","node","keepalive","reactiveMap","fromAny","DATA","COMPLETE","DATA","ERROR","node","fromAny","switchMap","node","batch","switchMap","ERROR","fromAny","DATA","COMPLETE","node","node"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|