@symerian/symi 3.0.17 → 3.0.19

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.
Files changed (259) hide show
  1. package/dist/{audio-preflight-CBDFctZN.js → audio-preflight-BfmZbg4Y.js} +4 -4
  2. package/dist/{audio-preflight-gsZSpG-6.js → audio-preflight-DcuC-liM.js} +4 -4
  3. package/dist/build-info.json +3 -3
  4. package/dist/bundled/boot-md/handler.js +8 -8
  5. package/dist/bundled/session-memory/handler.js +7 -7
  6. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  7. package/dist/{chrome-nPMY1XTJ.js → chrome-Bo7cbvFK.js} +5 -5
  8. package/dist/{chrome-BjVab8gM.js → chrome-DYp18Q0t.js} +5 -5
  9. package/dist/{deliver-D-QFqm31.js → deliver-ChSIbiMM.js} +1 -1
  10. package/dist/{deliver-B4-bcot9.js → deliver-DEgRQM4J.js} +1 -1
  11. package/dist/extensionAPI.js +7 -7
  12. package/dist/{image-CDwtQjmt.js → image-Bx-hvoNJ.js} +1 -1
  13. package/dist/{image-CcS-vzTA.js → image-CQl_mjWk.js} +1 -1
  14. package/dist/llm-slug-generator.js +7 -7
  15. package/dist/{manager-BnEdHzmO.js → manager-D_pn0urG.js} +1 -1
  16. package/dist/{manager-09r0qPze.js → manager-YQxK2t0C.js} +1 -1
  17. package/dist/{pi-embedded-CWsY69-4.js → pi-embedded-CLw_ZzEZ.js} +16 -16
  18. package/dist/{pi-embedded-helpers-BBMy-lqr.js → pi-embedded-helpers-B5I53aw6.js} +4 -4
  19. package/dist/{pi-embedded-helpers-ChEYbgVj.js → pi-embedded-helpers-sUAEIC9X.js} +4 -4
  20. package/dist/plugin-sdk/{accounts-BfyWsC_i.js → accounts-CWFytwbR.js} +3 -3
  21. package/dist/plugin-sdk/{active-listener-DcJW7xAT.js → active-listener-BkZ4jHrL.js} +2 -2
  22. package/dist/plugin-sdk/{agent-scope-ChbGV6of.js → agent-scope-C9gfY_Gk.js} +2 -2
  23. package/dist/plugin-sdk/{audio-preflight-D3GtNLqW.js → audio-preflight-HKbdzXLZ.js} +21 -21
  24. package/dist/plugin-sdk/{bindings-CN2Qmefj.js → bindings-BaKIqPPy.js} +2 -2
  25. package/dist/plugin-sdk/{channel-web-DTyqujjA.js → channel-web-D5nWiTH1.js} +18 -18
  26. package/dist/plugin-sdk/{chrome-BKzAKr3K.js → chrome-klTSnz-9.js} +3 -3
  27. package/dist/plugin-sdk/{chunk-DhDkBujV.js → chunk-BbrYSny_.js} +1 -1
  28. package/dist/plugin-sdk/{command-format-CVrYFyZS.js → command-format-BN6tyZt6.js} +1 -1
  29. package/dist/plugin-sdk/{commands-registry-17yfZkHZ.js → commands-registry-CTzKKtY6.js} +4 -4
  30. package/dist/plugin-sdk/{config-7wk65zKC.js → config-Crv2qEdJ.js} +9 -9
  31. package/dist/plugin-sdk/{consolidate-exbAW0ml.js → consolidate-DT1QH65Q.js} +2 -2
  32. package/dist/plugin-sdk/{deliver-TxAcw7J5.js → deliver-7rOvAlrc.js} +12 -12
  33. package/dist/plugin-sdk/{diagnostic-Debx4frd.js → diagnostic-0nsxhWp7.js} +1 -1
  34. package/dist/plugin-sdk/{fs-safe-wBYbAkJF.js → fs-safe-DfWYBeWF.js} +1 -1
  35. package/dist/plugin-sdk/{gemini-auth-7U2pm2Ky.js → gemini-auth-C0N0_u49.js} +1 -1
  36. package/dist/plugin-sdk/{image-BtDVmYA5.js → image-WOSl2apK.js} +4 -4
  37. package/dist/plugin-sdk/index.js +43 -43
  38. package/dist/plugin-sdk/{ir-CKMvRrGW.js → ir-9J84MTls.js} +4 -4
  39. package/dist/plugin-sdk/{local-roots-c_gaPs01.js → local-roots-OLRDbvyY.js} +3 -3
  40. package/dist/plugin-sdk/{login-DUym1Jy0.js → login-C7x4q0i2.js} +7 -7
  41. package/dist/plugin-sdk/{login-qr-B-WBdvrX.js → login-qr-Dv5_MoAW.js} +9 -9
  42. package/dist/plugin-sdk/{manager-B71SCzos.js → manager-C83tK17x.js} +8 -8
  43. package/dist/plugin-sdk/{manifest-registry-Dnic6Chh.js → manifest-registry-CJMV-PI7.js} +1 -1
  44. package/dist/plugin-sdk/{markdown-tables-Dur7OTlM.js → markdown-tables-DXNKz5y_.js} +1 -1
  45. package/dist/plugin-sdk/{message-channel-BrAhJJV_.js → message-channel-aGy1HbQQ.js} +1 -1
  46. package/dist/plugin-sdk/{model-selection-B9qaVQSJ.js → model-selection-C-3-tpe7.js} +4 -4
  47. package/dist/plugin-sdk/{outbound-DB1wDM8b.js → outbound-DquCeSy5.js} +6 -6
  48. package/dist/plugin-sdk/{pi-auth-json-ZO118hoy.js → pi-auth-json-D9PDCXGn.js} +1 -1
  49. package/dist/plugin-sdk/{pi-embedded-helpers-s_U0Un7j.js → pi-embedded-helpers-D3ygfH7l.js} +16 -16
  50. package/dist/plugin-sdk/{plugins-DF81oSaI.js → plugins-DOwnSg9D.js} +4 -4
  51. package/dist/plugin-sdk/{pw-ai-CTwP02uv.js → pw-ai-rlengLjb.js} +8 -8
  52. package/dist/plugin-sdk/{qmd-manager-CBaSGant.js → qmd-manager-BzxFjRFa.js} +4 -4
  53. package/dist/plugin-sdk/{registry-CZVURNhF.js → registry-5iFfixlB.js} +2 -2
  54. package/dist/plugin-sdk/{replies-hwRbkU3z.js → replies-BXOzO_H5.js} +7 -7
  55. package/dist/plugin-sdk/{reply-prefix-CaXmzZlx.js → reply-prefix-INAKTqCU.js} +1 -1
  56. package/dist/plugin-sdk/{resolve-outbound-target-fxVSOBmk.js → resolve-outbound-target-DvbxHtqp.js} +2 -2
  57. package/dist/plugin-sdk/{resolve-route-ClCyiOeu.js → resolve-route-URXlY3AK.js} +3 -3
  58. package/dist/plugin-sdk/{runner-Cq5jvwQ7.js → runner-Bv0_DWoH.js} +9 -9
  59. package/dist/plugin-sdk/{session-B_TkB65Y.js → session-C3r8l7ou.js} +4 -4
  60. package/dist/plugin-sdk/{skill-commands-0LF9HTGr.js → skill-commands-KjLUGIdZ.js} +5 -5
  61. package/dist/plugin-sdk/{skills-BIT_O7J0.js → skills-BrsD4L5c.js} +7 -7
  62. package/dist/plugin-sdk/{sqlite-Bx5Y5U5X.js → sqlite-CjW7ME1H.js} +1 -1
  63. package/dist/plugin-sdk/{subsystem-CXqYeDy-.js → subsystem-DcOg1xJr.js} +1 -1
  64. package/dist/plugin-sdk/{synthesis-DtsYAj1E.js → synthesis-CY7YAasV.js} +38 -38
  65. package/dist/plugin-sdk/{target-errors-B8mokOeH.js → target-errors-BVWJGWFq.js} +2 -2
  66. package/dist/plugin-sdk/{thinking-Ca0DhqzO.js → thinking-CtsTDPOi.js} +3 -3
  67. package/dist/plugin-sdk/{tokens-CvlONEqh.js → tokens-8lqOTZCB.js} +1 -1
  68. package/dist/plugin-sdk/{tool-images-DpBaWEHT.js → tool-images-Cl_rGIUZ.js} +2 -2
  69. package/dist/plugin-sdk/{tool-loop-detection-BOvUFa0f.js → tool-loop-detection-Da4WUT_P.js} +2 -2
  70. package/dist/plugin-sdk/{unified-runner-CnM7lyNd.js → unified-runner-nwMnsZyj.js} +60 -60
  71. package/dist/plugin-sdk/web-BlweOZDp.js +54 -0
  72. package/dist/plugin-sdk/{whatsapp-actions-CvnfsFJm.js → whatsapp-actions-DpfaGYs7.js} +21 -21
  73. package/dist/{pw-ai-BW8_KeDf.js → pw-ai-BqxJG-Wh.js} +1 -1
  74. package/dist/{pw-ai-j9IE1K0-.js → pw-ai-C-NSGye0.js} +1 -1
  75. package/dist/{runner-8ALr2UII.js → runner-COGFTeDw.js} +1 -1
  76. package/dist/{runner-C4-9kFdR.js → runner-DhCi2lT1.js} +1 -1
  77. package/dist/{synthesis-Cph3LhA1.js → synthesis-CXZu24Vx.js} +7 -7
  78. package/dist/{synthesis-Cus0A2dL.js → synthesis-DrPxcMlQ.js} +7 -7
  79. package/dist/{unified-runner-CX80YMTk.js → unified-runner-iByUazvW.js} +16 -16
  80. package/dist/{web-ChozvJ7I.js → web-EsMQBIYf.js} +7 -7
  81. package/dist/{web-DFlsbXmQ.js → web-PPg5y6xI.js} +7 -7
  82. package/package.json +1 -1
  83. package/dist/plugin-sdk/web-CIPJBHAU.js +0 -54
  84. package/extensions/copilot-proxy/README.md +0 -24
  85. package/extensions/copilot-proxy/index.ts +0 -154
  86. package/extensions/copilot-proxy/node_modules/.bin/symi +0 -21
  87. package/extensions/copilot-proxy/package.json +0 -15
  88. package/extensions/copilot-proxy/symi.plugin.json +0 -9
  89. package/extensions/device-pair/index.ts +0 -642
  90. package/extensions/device-pair/symi.plugin.json +0 -20
  91. package/extensions/diagnostics-otel/index.ts +0 -15
  92. package/extensions/diagnostics-otel/node_modules/.bin/acorn +0 -21
  93. package/extensions/diagnostics-otel/node_modules/.bin/symi +0 -21
  94. package/extensions/diagnostics-otel/package.json +0 -27
  95. package/extensions/diagnostics-otel/src/service.test.ts +0 -290
  96. package/extensions/diagnostics-otel/src/service.ts +0 -666
  97. package/extensions/diagnostics-otel/symi.plugin.json +0 -8
  98. package/extensions/google-antigravity-auth/README.md +0 -24
  99. package/extensions/google-antigravity-auth/index.ts +0 -424
  100. package/extensions/google-antigravity-auth/node_modules/.bin/symi +0 -21
  101. package/extensions/google-antigravity-auth/package.json +0 -15
  102. package/extensions/google-antigravity-auth/symi.plugin.json +0 -9
  103. package/extensions/google-gemini-cli-auth/README.md +0 -35
  104. package/extensions/google-gemini-cli-auth/index.ts +0 -75
  105. package/extensions/google-gemini-cli-auth/node_modules/.bin/symi +0 -21
  106. package/extensions/google-gemini-cli-auth/oauth.test.ts +0 -162
  107. package/extensions/google-gemini-cli-auth/oauth.ts +0 -636
  108. package/extensions/google-gemini-cli-auth/package.json +0 -15
  109. package/extensions/google-gemini-cli-auth/symi.plugin.json +0 -9
  110. package/extensions/learning-loop/index.ts +0 -159
  111. package/extensions/learning-loop/node_modules/.bin/symi +0 -21
  112. package/extensions/learning-loop/package.json +0 -18
  113. package/extensions/learning-loop/src/analytics/gateway-methods.ts +0 -230
  114. package/extensions/learning-loop/src/analytics/metrics-aggregator.ts +0 -153
  115. package/extensions/learning-loop/src/capture/run-tracker.ts +0 -181
  116. package/extensions/learning-loop/src/capture/serializer.ts +0 -74
  117. package/extensions/learning-loop/src/db.ts +0 -583
  118. package/extensions/learning-loop/src/feedback/explicit-feedback.ts +0 -58
  119. package/extensions/learning-loop/src/feedback/implicit-signals.ts +0 -89
  120. package/extensions/learning-loop/src/graph/edge-inference.ts +0 -189
  121. package/extensions/learning-loop/src/graph/graph-retrieval.ts +0 -144
  122. package/extensions/learning-loop/src/graph/graph-store.ts +0 -183
  123. package/extensions/learning-loop/src/hooks.ts +0 -244
  124. package/extensions/learning-loop/src/injection/cache.ts +0 -73
  125. package/extensions/learning-loop/src/injection/context-injector.ts +0 -104
  126. package/extensions/learning-loop/src/injection/prompt-builder.ts +0 -43
  127. package/extensions/learning-loop/src/learning/embedding-bridge.ts +0 -54
  128. package/extensions/learning-loop/src/learning/learning-extractor.ts +0 -217
  129. package/extensions/learning-loop/src/learning/learning-store.ts +0 -158
  130. package/extensions/learning-loop/src/learning/retrieval.ts +0 -87
  131. package/extensions/learning-loop/src/math/confidence-intervals.ts +0 -62
  132. package/extensions/learning-loop/src/math/ewma.ts +0 -51
  133. package/extensions/learning-loop/src/math/weighted-scorer.ts +0 -42
  134. package/extensions/learning-loop/src/schema.ts +0 -176
  135. package/extensions/learning-loop/src/scoring/normalization.ts +0 -32
  136. package/extensions/learning-loop/src/scoring/quality-engine.ts +0 -78
  137. package/extensions/learning-loop/src/scoring/signal-extractors.ts +0 -155
  138. package/extensions/learning-loop/src/test/context-injector.test.ts +0 -142
  139. package/extensions/learning-loop/src/test/fixes.test.ts +0 -1286
  140. package/extensions/learning-loop/src/test/graph.test.ts +0 -711
  141. package/extensions/learning-loop/src/test/integration.test.ts +0 -312
  142. package/extensions/learning-loop/src/test/learning-store.test.ts +0 -191
  143. package/extensions/learning-loop/src/test/math.test.ts +0 -148
  144. package/extensions/learning-loop/src/test/quality-engine.test.ts +0 -231
  145. package/extensions/learning-loop/src/test/run-tracker.test.ts +0 -143
  146. package/extensions/learning-loop/src/types.ts +0 -281
  147. package/extensions/learning-loop/symi.plugin.json +0 -46
  148. package/extensions/llm-task/README.md +0 -97
  149. package/extensions/llm-task/index.ts +0 -6
  150. package/extensions/llm-task/package.json +0 -12
  151. package/extensions/llm-task/src/llm-task-tool.test.ts +0 -138
  152. package/extensions/llm-task/src/llm-task-tool.ts +0 -249
  153. package/extensions/llm-task/symi.plugin.json +0 -21
  154. package/extensions/memory-lancedb/config.ts +0 -161
  155. package/extensions/memory-lancedb/index.test.ts +0 -330
  156. package/extensions/memory-lancedb/index.ts +0 -670
  157. package/extensions/memory-lancedb/node_modules/.bin/arrow2csv +0 -21
  158. package/extensions/memory-lancedb/node_modules/.bin/openai +0 -21
  159. package/extensions/memory-lancedb/node_modules/.bin/symi +0 -21
  160. package/extensions/memory-lancedb/package.json +0 -20
  161. package/extensions/memory-lancedb/symi.plugin.json +0 -71
  162. package/extensions/minimax-portal-auth/README.md +0 -33
  163. package/extensions/minimax-portal-auth/index.ts +0 -161
  164. package/extensions/minimax-portal-auth/node_modules/.bin/symi +0 -21
  165. package/extensions/minimax-portal-auth/oauth.ts +0 -247
  166. package/extensions/minimax-portal-auth/package.json +0 -15
  167. package/extensions/minimax-portal-auth/symi.plugin.json +0 -9
  168. package/extensions/model-equalizer/index.ts +0 -80
  169. package/extensions/model-equalizer/skills/model-equalizer/SKILL.md +0 -58
  170. package/extensions/model-equalizer/src/detection.ts +0 -62
  171. package/extensions/model-equalizer/src/enhancer.ts +0 -63
  172. package/extensions/model-equalizer/src/test/detection.test.ts +0 -218
  173. package/extensions/model-equalizer/src/test/enhancer.test.ts +0 -137
  174. package/extensions/model-equalizer/src/test/integration.test.ts +0 -185
  175. package/extensions/model-equalizer/src/types.ts +0 -24
  176. package/extensions/model-equalizer/symi.plugin.json +0 -12
  177. package/extensions/phone-control/index.ts +0 -421
  178. package/extensions/phone-control/symi.plugin.json +0 -10
  179. package/extensions/pipeline/README.md +0 -75
  180. package/extensions/pipeline/SKILL.md +0 -97
  181. package/extensions/pipeline/index.ts +0 -18
  182. package/extensions/pipeline/package.json +0 -11
  183. package/extensions/pipeline/src/pipeline-tool.test.ts +0 -345
  184. package/extensions/pipeline/src/pipeline-tool.ts +0 -266
  185. package/extensions/pipeline/src/windows-spawn.test.ts +0 -148
  186. package/extensions/pipeline/src/windows-spawn.ts +0 -193
  187. package/extensions/pipeline/symi.plugin.json +0 -10
  188. package/extensions/qwen-portal-auth/README.md +0 -24
  189. package/extensions/qwen-portal-auth/index.ts +0 -134
  190. package/extensions/qwen-portal-auth/oauth.ts +0 -190
  191. package/extensions/qwen-portal-auth/symi.plugin.json +0 -9
  192. package/extensions/talk-voice/index.ts +0 -150
  193. package/extensions/talk-voice/symi.plugin.json +0 -10
  194. package/extensions/thread-ownership/index.test.ts +0 -180
  195. package/extensions/thread-ownership/index.ts +0 -133
  196. package/extensions/thread-ownership/symi.plugin.json +0 -28
  197. package/skills/1password/SKILL.md +0 -71
  198. package/skills/1password/references/cli-examples.md +0 -29
  199. package/skills/1password/references/get-started.md +0 -17
  200. package/skills/apple-notes/SKILL.md +0 -78
  201. package/skills/apple-reminders/SKILL.md +0 -119
  202. package/skills/bear-notes/SKILL.md +0 -108
  203. package/skills/blogwatcher/SKILL.md +0 -70
  204. package/skills/blucli/SKILL.md +0 -48
  205. package/skills/bluebubbles/SKILL.md +0 -132
  206. package/skills/camsnap/SKILL.md +0 -46
  207. package/skills/canvas/SKILL.md +0 -204
  208. package/skills/connect-email/SKILL.md +0 -142
  209. package/skills/document-generation/SKILL.md +0 -83
  210. package/skills/eightctl/SKILL.md +0 -51
  211. package/skills/food-order/SKILL.md +0 -49
  212. package/skills/gemini/SKILL.md +0 -44
  213. package/skills/gh-issues/SKILL.md +0 -865
  214. package/skills/gifgrep/SKILL.md +0 -80
  215. package/skills/github/SKILL.md +0 -164
  216. package/skills/gog/SKILL.md +0 -117
  217. package/skills/goplaces/SKILL.md +0 -53
  218. package/skills/healthcheck/SKILL.md +0 -246
  219. package/skills/himalaya/SKILL.md +0 -258
  220. package/skills/himalaya/references/configuration.md +0 -184
  221. package/skills/himalaya/references/message-composition.md +0 -199
  222. package/skills/imsg/SKILL.md +0 -122
  223. package/skills/long-task/SKILL.md +0 -58
  224. package/skills/long-task/scripts/detach-task.sh +0 -187
  225. package/skills/nano-banana-pro/SKILL.md +0 -59
  226. package/skills/nano-banana-pro/scripts/generate_image.py +0 -184
  227. package/skills/nano-pdf/SKILL.md +0 -39
  228. package/skills/notion/SKILL.md +0 -173
  229. package/skills/obsidian/SKILL.md +0 -82
  230. package/skills/openai-image-gen/SKILL.md +0 -90
  231. package/skills/openai-image-gen/scripts/gen.py +0 -240
  232. package/skills/openai-whisper/SKILL.md +0 -39
  233. package/skills/openai-whisper-api/SKILL.md +0 -53
  234. package/skills/openai-whisper-api/scripts/transcribe.sh +0 -85
  235. package/skills/openhue/SKILL.md +0 -113
  236. package/skills/oracle/SKILL.md +0 -126
  237. package/skills/ordercli/SKILL.md +0 -79
  238. package/skills/peekaboo/SKILL.md +0 -191
  239. package/skills/reactions-extensive/SKILL.md +0 -30
  240. package/skills/reactions-minimal/SKILL.md +0 -31
  241. package/skills/safe-edit/SKILL.md +0 -51
  242. package/skills/sag/SKILL.md +0 -88
  243. package/skills/sherpa-onnx-tts/SKILL.md +0 -104
  244. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +0 -178
  245. package/skills/songsee/SKILL.md +0 -50
  246. package/skills/sonoscli/SKILL.md +0 -66
  247. package/skills/spotify-player/SKILL.md +0 -65
  248. package/skills/symihub/SKILL.md +0 -78
  249. package/skills/things-mac/SKILL.md +0 -87
  250. package/skills/tmux/SKILL.md +0 -153
  251. package/skills/tmux/scripts/find-sessions.sh +0 -112
  252. package/skills/tmux/scripts/wait-for-text.sh +0 -83
  253. package/skills/trello/SKILL.md +0 -96
  254. package/skills/video-frames/SKILL.md +0 -47
  255. package/skills/video-frames/scripts/frame.sh +0 -81
  256. package/skills/voice-call/SKILL.md +0 -46
  257. package/skills/wacli/SKILL.md +0 -73
  258. package/skills/weather/SKILL.md +0 -113
  259. package/skills/xurl/SKILL.md +0 -462
@@ -1,159 +0,0 @@
1
- import path from "node:path";
2
- import { resolveMemorySearchConfig } from "../../src/agents/memory-search.js";
3
- import { createEmbeddingProvider } from "../../src/memory/embeddings.js";
4
- import type { SymiPluginApi } from "../../src/plugins/types.js";
5
- import { registerGatewayMethods } from "./src/analytics/gateway-methods.js";
6
- import { createMetricsAggregator } from "./src/analytics/metrics-aggregator.js";
7
- import { createRunTracker } from "./src/capture/run-tracker.js";
8
- import { createDatabaseManager } from "./src/db.js";
9
- import { createImplicitSignals } from "./src/feedback/implicit-signals.js";
10
- import { createEdgeInference } from "./src/graph/edge-inference.js";
11
- import { createGraphRetrieval } from "./src/graph/graph-retrieval.js";
12
- import { createGraphStore } from "./src/graph/graph-store.js";
13
- import { registerHooks } from "./src/hooks.js";
14
- import { createContextInjector } from "./src/injection/context-injector.js";
15
- import { createEmbeddingBridge, type EmbeddingBridge } from "./src/learning/embedding-bridge.js";
16
- import { createLearningExtractor } from "./src/learning/learning-extractor.js";
17
- import { createLearningStore } from "./src/learning/learning-store.js";
18
- import { createQualityEngine } from "./src/scoring/quality-engine.js";
19
- import { resolveConfig } from "./src/types.js";
20
-
21
- const plugin = {
22
- id: "learning-loop",
23
- name: "Learning Loop",
24
- description:
25
- "Closed-loop learning with deterministic quality scoring, pattern extraction, and context injection",
26
-
27
- register(api: SymiPluginApi) {
28
- const config = resolveConfig(api.pluginConfig);
29
- const logger = api.logger;
30
- const rootStateDir = api.runtime.state.resolveStateDir();
31
- const stateDir = path.join(rootStateDir, "learning-loop");
32
-
33
- const db = createDatabaseManager({ stateDir, config, logger });
34
- const tracker = createRunTracker();
35
- const qualityEngine = createQualityEngine({ config, db });
36
- const graphStore = createGraphStore({ db });
37
- const learningStore = createLearningStore({ db, graphStore });
38
- const edgeInference = createEdgeInference({ graphStore, learningStore });
39
- const graphRetrieval = createGraphRetrieval({ graphStore, learningStore, config });
40
-
41
- // Lazy embedding bridge: initializes on first use, avoids blocking sync register()
42
- let bridgePromise: Promise<EmbeddingBridge> | null = null;
43
- let bridgeResolved = false;
44
- let bridgeHasProvider = false;
45
-
46
- async function initBridge(): Promise<EmbeddingBridge> {
47
- try {
48
- const memCfg = resolveMemorySearchConfig(api.config, "main");
49
- const result = await createEmbeddingProvider({
50
- config: api.config,
51
- provider: memCfg?.provider ?? "auto",
52
- model: memCfg?.model ?? "",
53
- fallback: memCfg?.fallback ?? "none",
54
- local: memCfg?.local,
55
- remote: memCfg?.remote,
56
- });
57
- return createEmbeddingBridge({ provider: result.provider, logger });
58
- } catch (err) {
59
- logger.warn(`[learning-loop] embedding bridge init failed: ${String(err)}`);
60
- return createEmbeddingBridge({ provider: null, logger });
61
- }
62
- }
63
-
64
- async function initAndTrack(): Promise<EmbeddingBridge> {
65
- const bridge = await initBridge();
66
- bridgeResolved = true;
67
- bridgeHasProvider = bridge.available();
68
- return bridge;
69
- }
70
-
71
- const lazyBridge: EmbeddingBridge = {
72
- async embed(text) {
73
- if (!bridgePromise) bridgePromise = initAndTrack();
74
- return (await bridgePromise).embed(text);
75
- },
76
- async embedBatch(texts) {
77
- if (!bridgePromise) bridgePromise = initAndTrack();
78
- return (await bridgePromise).embedBatch(texts);
79
- },
80
- available: () => (bridgeResolved ? bridgeHasProvider : true),
81
- };
82
-
83
- const extractor = createLearningExtractor({
84
- db,
85
- learningStore,
86
- config,
87
- edgeInference,
88
- embeddingBridge: lazyBridge,
89
- });
90
- const injector = createContextInjector({
91
- db,
92
- learningStore,
93
- config,
94
- embeddingBridge: lazyBridge,
95
- graphRetrieval,
96
- });
97
- const metrics = createMetricsAggregator({ db });
98
- const implicit = createImplicitSignals({ db, config });
99
-
100
- registerHooks(api, {
101
- config,
102
- logger,
103
- db,
104
- tracker,
105
- qualityEngine,
106
- learningStore,
107
- extractor,
108
- injector,
109
- metrics,
110
- implicit,
111
- edgeInference,
112
- });
113
-
114
- registerGatewayMethods(api, {
115
- db,
116
- learningStore,
117
- metrics,
118
- injector,
119
- qualityEngine,
120
- graphStore,
121
- });
122
-
123
- // One-time async backfill: embed historical learnings that have no embeddings
124
- async function backfillEmbeddings(): Promise<void> {
125
- const BATCH_SIZE = 50;
126
- let totalBackfilled = 0;
127
-
128
- // eslint-disable-next-line no-constant-condition
129
- while (true) {
130
- const rows = db.getLearningsWithoutEmbeddings(BATCH_SIZE);
131
- if (rows.length === 0) break;
132
-
133
- const texts = rows.map((r) => r.content);
134
- const embeddings = await lazyBridge.embedBatch(texts);
135
-
136
- for (let i = 0; i < rows.length; i++) {
137
- const emb = embeddings[i];
138
- if (emb) {
139
- db.updateLearningEmbedding(rows[i]!.id, emb);
140
- totalBackfilled++;
141
- }
142
- }
143
-
144
- if (rows.length < BATCH_SIZE) break;
145
- }
146
-
147
- if (totalBackfilled > 0) {
148
- logger.debug?.(`[learning-loop] backfilled embeddings for ${totalBackfilled} learnings`);
149
- }
150
- }
151
-
152
- // Fire-and-forget: backfill after bridge is ready
153
- backfillEmbeddings().catch((err) => {
154
- logger.warn(`[learning-loop] embedding backfill failed: ${String(err)}`);
155
- });
156
- },
157
- };
158
-
159
- export default plugin;
@@ -1,21 +0,0 @@
1
- #!/bin/sh
2
- basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3
-
4
- case `uname` in
5
- *CYGWIN*|*MINGW*|*MSYS*)
6
- if command -v cygpath > /dev/null 2>&1; then
7
- basedir=`cygpath -w "$basedir"`
8
- fi
9
- ;;
10
- esac
11
-
12
- if [ -z "$NODE_PATH" ]; then
13
- export NODE_PATH="/home/symi/projects/symi/node_modules:/home/symi/projects/node_modules:/home/symi/node_modules:/home/node_modules:/node_modules:/home/symi/projects/symi/node_modules/.pnpm/node_modules"
14
- else
15
- export NODE_PATH="/home/symi/projects/symi/node_modules:/home/symi/projects/node_modules:/home/symi/node_modules:/home/node_modules:/node_modules:/home/symi/projects/symi/node_modules/.pnpm/node_modules:$NODE_PATH"
16
- fi
17
- if [ -x "$basedir/node" ]; then
18
- exec "$basedir/node" "$basedir/../@symerian/symi/symi.mjs" "$@"
19
- else
20
- exec node "$basedir/../@symerian/symi/symi.mjs" "$@"
21
- fi
@@ -1,18 +0,0 @@
1
- {
2
- "name": "@symi/learning-loop",
3
- "version": "3.0.9",
4
- "private": true,
5
- "description": "Closed-loop learning extension with deterministic quality scoring and vector-indexed learning storage",
6
- "type": "module",
7
- "devDependencies": {
8
- "@symerian/symi": "workspace:*"
9
- },
10
- "peerDependencies": {
11
- "@symerian/symi": ">=2026.1.26"
12
- },
13
- "symi": {
14
- "extensions": [
15
- "./index.ts"
16
- ]
17
- }
18
- }
@@ -1,230 +0,0 @@
1
- /**
2
- * Gateway RPC methods for the Glass UI.
3
- */
4
-
5
- import type { SymiPluginApi } from "../../../../src/plugins/types.js";
6
- import type { DatabaseManager } from "../db.js";
7
- import { createExplicitFeedbackHandler } from "../feedback/explicit-feedback.js";
8
- import type { GraphStore } from "../graph/graph-store.js";
9
- import type { ContextInjector } from "../injection/context-injector.js";
10
- import type { LearningStore } from "../learning/learning-store.js";
11
- import type { QualityEngine } from "../scoring/quality-engine.js";
12
- import type { LearningCategory, EdgeType } from "../types.js";
13
- import type { MetricsAggregator } from "./metrics-aggregator.js";
14
-
15
- export function registerGatewayMethods(
16
- api: SymiPluginApi,
17
- deps: {
18
- db: DatabaseManager;
19
- learningStore: LearningStore;
20
- metrics: MetricsAggregator;
21
- injector: ContextInjector;
22
- qualityEngine?: QualityEngine;
23
- graphStore?: GraphStore;
24
- },
25
- ) {
26
- const { db, learningStore, metrics, injector, qualityEngine, graphStore } = deps;
27
- const feedbackHandler = createExplicitFeedbackHandler({ db, qualityEngine });
28
-
29
- // learning.metrics.models
30
- api.registerGatewayMethod("learning.metrics.models", (opts) => {
31
- try {
32
- const params = opts.params as { provider?: string; model?: string };
33
- const result = metrics.getModelMetrics(params.provider, params.model);
34
- opts.respond(true, result);
35
- } catch (err) {
36
- opts.respond(false, undefined, { code: 500, message: String(err) });
37
- }
38
- });
39
-
40
- // learning.metrics.timeseries
41
- api.registerGatewayMethod("learning.metrics.timeseries", (opts) => {
42
- try {
43
- const params = opts.params as {
44
- provider?: string;
45
- model?: string;
46
- fromHour?: string;
47
- toHour?: string;
48
- };
49
- const result = metrics.getTimeseries(params);
50
- opts.respond(true, result);
51
- } catch (err) {
52
- opts.respond(false, undefined, { code: 500, message: String(err) });
53
- }
54
- });
55
-
56
- // learning.metrics.leaderboard
57
- api.registerGatewayMethod("learning.metrics.leaderboard", (opts) => {
58
- try {
59
- const result = metrics.getLeaderboard();
60
- opts.respond(true, result);
61
- } catch (err) {
62
- opts.respond(false, undefined, { code: 500, message: String(err) });
63
- }
64
- });
65
-
66
- // learning.learnings.list
67
- api.registerGatewayMethod("learning.learnings.list", (opts) => {
68
- try {
69
- const params = opts.params as { category?: string; limit?: number };
70
- const result = learningStore.listLearnings({
71
- category: params.category as LearningCategory | undefined,
72
- limit: params.limit,
73
- });
74
- opts.respond(true, result);
75
- } catch (err) {
76
- opts.respond(false, undefined, { code: 500, message: String(err) });
77
- }
78
- });
79
-
80
- // learning.learnings.search
81
- api.registerGatewayMethod("learning.learnings.search", (opts) => {
82
- try {
83
- const params = opts.params as { query: string; limit?: number };
84
- if (!params.query) {
85
- opts.respond(false, undefined, { code: 400, message: "query is required" });
86
- return;
87
- }
88
- const result = learningStore.searchByText(params.query, params.limit ?? 20);
89
- opts.respond(true, result);
90
- } catch (err) {
91
- opts.respond(false, undefined, { code: 500, message: String(err) });
92
- }
93
- });
94
-
95
- // learning.feedback.submit
96
- api.registerGatewayMethod("learning.feedback.submit", (opts) => {
97
- try {
98
- const params = opts.params as { runId: string; score: number };
99
- if (!params.runId || params.score == null) {
100
- opts.respond(false, undefined, {
101
- code: 400,
102
- message: "runId and score (1-5) are required",
103
- });
104
- return;
105
- }
106
- const result = feedbackHandler.submitFeedback(params.runId, params.score);
107
- if (!result) {
108
- opts.respond(false, undefined, { code: 404, message: "Run not found" });
109
- return;
110
- }
111
- opts.respond(true, result);
112
- } catch (err) {
113
- opts.respond(false, undefined, { code: 500, message: String(err) });
114
- }
115
- });
116
-
117
- // learning.status
118
- api.registerGatewayMethod("learning.status", (opts) => {
119
- try {
120
- const stats = db.getStats();
121
- const cacheStats = injector.getCacheStats();
122
- opts.respond(true, {
123
- ...stats,
124
- cache: cacheStats,
125
- });
126
- } catch (err) {
127
- opts.respond(false, undefined, { code: 500, message: String(err) });
128
- }
129
- });
130
-
131
- // --- Graph methods ---
132
-
133
- if (graphStore) {
134
- // learning.graph.edges
135
- api.registerGatewayMethod("learning.graph.edges", (opts) => {
136
- try {
137
- const params = opts.params as { learningId: string; typeFilter?: EdgeType[] };
138
- if (!params.learningId) {
139
- opts.respond(false, undefined, { code: 400, message: "learningId is required" });
140
- return;
141
- }
142
- const edges = graphStore.getEdges(params.learningId, {
143
- typeFilter: params.typeFilter,
144
- });
145
- opts.respond(true, edges);
146
- } catch (err) {
147
- opts.respond(false, undefined, { code: 500, message: String(err) });
148
- }
149
- });
150
-
151
- // learning.graph.neighbors
152
- api.registerGatewayMethod("learning.graph.neighbors", (opts) => {
153
- try {
154
- const params = opts.params as {
155
- learningId: string;
156
- hops?: number;
157
- typeFilter?: EdgeType[];
158
- };
159
- if (!params.learningId) {
160
- opts.respond(false, undefined, { code: 400, message: "learningId is required" });
161
- return;
162
- }
163
- const neighbors = graphStore.getNeighbors(
164
- params.learningId,
165
- params.hops ?? 1,
166
- params.typeFilter,
167
- );
168
- // Convert Map to serializable object
169
- const result: Array<{ id: string; weight: number }> = [];
170
- for (const [id, weight] of neighbors) {
171
- result.push({ id, weight });
172
- }
173
- opts.respond(true, result);
174
- } catch (err) {
175
- opts.respond(false, undefined, { code: 500, message: String(err) });
176
- }
177
- });
178
-
179
- // learning.graph.contradictions
180
- api.registerGatewayMethod("learning.graph.contradictions", (opts) => {
181
- try {
182
- const params = opts.params as { learningId?: string } | undefined;
183
- const contradictions = graphStore.getContradictions(params?.learningId);
184
- opts.respond(true, contradictions);
185
- } catch (err) {
186
- opts.respond(false, undefined, { code: 500, message: String(err) });
187
- }
188
- });
189
-
190
- // learning.graph.stats
191
- api.registerGatewayMethod("learning.graph.stats", (opts) => {
192
- try {
193
- const edgeTypes: EdgeType[] = ["T", "S", "C", "U", "X", "R"];
194
- const countsByType: Record<string, number> = {};
195
- let totalEdges = 0;
196
- for (const t of edgeTypes) {
197
- const edges = db.getEdgesByType(t);
198
- countsByType[t] = edges.length;
199
- totalEdges += edges.length;
200
- }
201
-
202
- const learnings = db.getAllLearnings(10000);
203
- let centralitySum = 0;
204
- let centralityCount = 0;
205
- for (const l of learnings) {
206
- const score = db.getCentralityScore(l.id);
207
- if (score > 0) {
208
- centralitySum += score;
209
- centralityCount++;
210
- }
211
- }
212
-
213
- const avgCentrality = centralityCount > 0 ? centralitySum / centralityCount : 0;
214
- const nodeCount = learnings.length;
215
- const maxEdges = nodeCount > 1 ? (nodeCount * (nodeCount - 1)) / 2 : 0;
216
- const density = maxEdges > 0 ? totalEdges / maxEdges : 0;
217
-
218
- opts.respond(true, {
219
- totalEdges,
220
- countsByType,
221
- avgCentrality,
222
- nodeCount,
223
- density,
224
- });
225
- } catch (err) {
226
- opts.respond(false, undefined, { code: 500, message: String(err) });
227
- }
228
- });
229
- }
230
- }
@@ -1,153 +0,0 @@
1
- /**
2
- * Pre-aggregated time bucket metrics.
3
- *
4
- * Uses O(1) upsert per run via SQLite's ON CONFLICT UPDATE.
5
- * Variance computed via: var = sum_sq/n - (sum/n)^2
6
- */
7
-
8
- import type { DatabaseManager } from "../db.js";
9
- import { wilsonScoreLowerBound } from "../math/confidence-intervals.js";
10
- import type { CompletedRun, QualityScore, MetricsBucketRow } from "../types.js";
11
-
12
- export type MetricsAggregator = ReturnType<typeof createMetricsAggregator>;
13
-
14
- export function createMetricsAggregator(params: { db: DatabaseManager }) {
15
- const { db } = params;
16
-
17
- /**
18
- * Record a completed run in the metrics buckets. O(1) upsert.
19
- */
20
- function recordRun(run: CompletedRun, score: QualityScore): void {
21
- db.upsertMetricsBucket(
22
- run.provider,
23
- run.model,
24
- run.completedAt,
25
- score.score,
26
- run.durationMs,
27
- run.success,
28
- run.usage.input ?? 0,
29
- run.usage.output ?? 0,
30
- );
31
- }
32
-
33
- /**
34
- * Get per-model quality, success rate, latency, and token efficiency.
35
- */
36
- function getModelMetrics(
37
- provider?: string,
38
- model?: string,
39
- ): Array<{
40
- provider: string;
41
- model: string;
42
- runCount: number;
43
- successRate: number;
44
- successRateLowerBound: number;
45
- avgQuality: number;
46
- qualityVariance: number;
47
- avgLatency: number;
48
- latencyVariance: number;
49
- avgTokenInput: number;
50
- avgTokenOutput: number;
51
- }> {
52
- const buckets = db.getMetricsBuckets(provider, model);
53
- const grouped = new Map<string, MetricsBucketRow[]>();
54
-
55
- for (const b of buckets) {
56
- const key = `${b.provider}:${b.model}`;
57
- const group = grouped.get(key) ?? [];
58
- group.push(b);
59
- grouped.set(key, group);
60
- }
61
-
62
- const results: Array<{
63
- provider: string;
64
- model: string;
65
- runCount: number;
66
- successRate: number;
67
- successRateLowerBound: number;
68
- avgQuality: number;
69
- qualityVariance: number;
70
- avgLatency: number;
71
- latencyVariance: number;
72
- avgTokenInput: number;
73
- avgTokenOutput: number;
74
- }> = [];
75
-
76
- for (const [, group] of grouped) {
77
- const totalRuns = group.reduce((s, b) => s + b.run_count, 0);
78
- if (totalRuns === 0) continue;
79
-
80
- const totalSuccess = group.reduce((s, b) => s + b.success_count, 0);
81
- const qualitySum = group.reduce((s, b) => s + b.quality_sum, 0);
82
- const qualitySumSq = group.reduce((s, b) => s + b.quality_sum_sq, 0);
83
- const latencySum = group.reduce((s, b) => s + b.latency_sum, 0);
84
- const latencySumSq = group.reduce((s, b) => s + b.latency_sum_sq, 0);
85
- const tokenInputSum = group.reduce((s, b) => s + b.token_input_sum, 0);
86
- const tokenOutputSum = group.reduce((s, b) => s + b.token_output_sum, 0);
87
-
88
- const avgQuality = qualitySum / totalRuns;
89
- const avgLatency = latencySum / totalRuns;
90
- const successRate = totalSuccess / totalRuns;
91
-
92
- results.push({
93
- provider: group[0]!.provider,
94
- model: group[0]!.model,
95
- runCount: totalRuns,
96
- successRate,
97
- successRateLowerBound: wilsonScoreLowerBound(totalSuccess, totalRuns),
98
- avgQuality,
99
- qualityVariance: Math.max(0, qualitySumSq / totalRuns - avgQuality ** 2),
100
- avgLatency,
101
- latencyVariance: Math.max(0, latencySumSq / totalRuns - avgLatency ** 2),
102
- avgTokenInput: tokenInputSum / totalRuns,
103
- avgTokenOutput: tokenOutputSum / totalRuns,
104
- });
105
- }
106
-
107
- return results.sort((a, b) => b.avgQuality - a.avgQuality);
108
- }
109
-
110
- /**
111
- * Get time-bucketed quality trends.
112
- */
113
- function getTimeseries(params?: {
114
- provider?: string;
115
- model?: string;
116
- fromHour?: string;
117
- toHour?: string;
118
- }): Array<{
119
- bucketHour: string;
120
- provider: string;
121
- model: string;
122
- runCount: number;
123
- avgQuality: number;
124
- successRate: number;
125
- avgLatency: number;
126
- }> {
127
- const buckets = db.getMetricsBuckets(
128
- params?.provider,
129
- params?.model,
130
- params?.fromHour,
131
- params?.toHour,
132
- );
133
-
134
- return buckets.map((b) => ({
135
- bucketHour: b.bucket_hour,
136
- provider: b.provider,
137
- model: b.model,
138
- runCount: b.run_count,
139
- avgQuality: b.run_count > 0 ? b.quality_sum / b.run_count : 0,
140
- successRate: b.run_count > 0 ? b.success_count / b.run_count : 0,
141
- avgLatency: b.run_count > 0 ? b.latency_sum / b.run_count : 0,
142
- }));
143
- }
144
-
145
- /**
146
- * Get model comparison leaderboard.
147
- */
148
- function getLeaderboard() {
149
- return db.getModelLeaderboard();
150
- }
151
-
152
- return { recordRun, getModelMetrics, getTimeseries, getLeaderboard };
153
- }