@0xmaxma/claude-gateway 1.6.8 → 1.7.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.
Files changed (223) hide show
  1. package/README.md +149 -20
  2. package/config.template.json +59 -1
  3. package/dist/agent/dreaming/accept.d.ts +43 -0
  4. package/dist/agent/dreaming/accept.d.ts.map +1 -0
  5. package/dist/agent/dreaming/accept.js +230 -0
  6. package/dist/agent/dreaming/accept.js.map +1 -0
  7. package/dist/agent/dreaming/applier.d.ts +77 -0
  8. package/dist/agent/dreaming/applier.d.ts.map +1 -0
  9. package/dist/agent/dreaming/applier.js +406 -0
  10. package/dist/agent/dreaming/applier.js.map +1 -0
  11. package/dist/agent/dreaming/audit.d.ts +27 -0
  12. package/dist/agent/dreaming/audit.d.ts.map +1 -0
  13. package/dist/agent/dreaming/audit.js +100 -0
  14. package/dist/agent/dreaming/audit.js.map +1 -0
  15. package/dist/agent/dreaming/compactor.d.ts +66 -0
  16. package/dist/agent/dreaming/compactor.d.ts.map +1 -0
  17. package/dist/agent/dreaming/compactor.js +306 -0
  18. package/dist/agent/dreaming/compactor.js.map +1 -0
  19. package/dist/agent/dreaming/config.d.ts +19 -0
  20. package/dist/agent/dreaming/config.d.ts.map +1 -0
  21. package/dist/agent/dreaming/config.js +107 -0
  22. package/dist/agent/dreaming/config.js.map +1 -0
  23. package/dist/agent/dreaming/episodic.d.ts +42 -0
  24. package/dist/agent/dreaming/episodic.d.ts.map +1 -0
  25. package/dist/agent/dreaming/episodic.js +116 -0
  26. package/dist/agent/dreaming/episodic.js.map +1 -0
  27. package/dist/agent/dreaming/gather.d.ts +31 -0
  28. package/dist/agent/dreaming/gather.d.ts.map +1 -0
  29. package/dist/agent/dreaming/gather.js +55 -0
  30. package/dist/agent/dreaming/gather.js.map +1 -0
  31. package/dist/agent/dreaming/index.d.ts +87 -0
  32. package/dist/agent/dreaming/index.d.ts.map +1 -0
  33. package/dist/agent/dreaming/index.js +377 -0
  34. package/dist/agent/dreaming/index.js.map +1 -0
  35. package/dist/agent/dreaming/migrate-cli.d.ts +17 -0
  36. package/dist/agent/dreaming/migrate-cli.d.ts.map +1 -0
  37. package/dist/agent/dreaming/migrate-cli.js +42 -0
  38. package/dist/agent/dreaming/migrate-cli.js.map +1 -0
  39. package/dist/agent/dreaming/migrate.d.ts +72 -0
  40. package/dist/agent/dreaming/migrate.d.ts.map +1 -0
  41. package/dist/agent/dreaming/migrate.js +374 -0
  42. package/dist/agent/dreaming/migrate.js.map +1 -0
  43. package/dist/agent/dreaming/report.d.ts +39 -0
  44. package/dist/agent/dreaming/report.d.ts.map +1 -0
  45. package/dist/agent/dreaming/report.js +121 -0
  46. package/dist/agent/dreaming/report.js.map +1 -0
  47. package/dist/agent/dreaming/reviewer.d.ts +43 -0
  48. package/dist/agent/dreaming/reviewer.d.ts.map +1 -0
  49. package/dist/agent/dreaming/reviewer.js +249 -0
  50. package/dist/agent/dreaming/reviewer.js.map +1 -0
  51. package/dist/agent/dreaming/staleness.d.ts +68 -0
  52. package/dist/agent/dreaming/staleness.d.ts.map +1 -0
  53. package/dist/agent/dreaming/staleness.js +281 -0
  54. package/dist/agent/dreaming/staleness.js.map +1 -0
  55. package/dist/agent/dreaming/types.d.ts +130 -0
  56. package/dist/agent/dreaming/types.d.ts.map +1 -0
  57. package/dist/agent/dreaming/types.js +10 -0
  58. package/dist/agent/dreaming/types.js.map +1 -0
  59. package/dist/agent/knowledge/archive-db.d.ts +114 -0
  60. package/dist/agent/knowledge/archive-db.d.ts.map +1 -0
  61. package/dist/agent/knowledge/archive-db.js +474 -0
  62. package/dist/agent/knowledge/archive-db.js.map +1 -0
  63. package/dist/agent/knowledge/chunk.d.ts +21 -0
  64. package/dist/agent/knowledge/chunk.d.ts.map +1 -0
  65. package/dist/agent/knowledge/chunk.js +67 -0
  66. package/dist/agent/knowledge/chunk.js.map +1 -0
  67. package/dist/agent/knowledge/config.d.ts +20 -0
  68. package/dist/agent/knowledge/config.d.ts.map +1 -0
  69. package/dist/agent/knowledge/config.js +143 -0
  70. package/dist/agent/knowledge/config.js.map +1 -0
  71. package/dist/agent/knowledge/graph-demo.d.ts +25 -0
  72. package/dist/agent/knowledge/graph-demo.d.ts.map +1 -0
  73. package/dist/agent/knowledge/graph-demo.js +132 -0
  74. package/dist/agent/knowledge/graph-demo.js.map +1 -0
  75. package/dist/agent/knowledge/index.d.ts +24 -0
  76. package/dist/agent/knowledge/index.d.ts.map +1 -0
  77. package/dist/agent/knowledge/index.js +50 -0
  78. package/dist/agent/knowledge/index.js.map +1 -0
  79. package/dist/agent/knowledge/indexer.d.ts +34 -0
  80. package/dist/agent/knowledge/indexer.d.ts.map +1 -0
  81. package/dist/agent/knowledge/indexer.js +271 -0
  82. package/dist/agent/knowledge/indexer.js.map +1 -0
  83. package/dist/agent/knowledge/lifecycle.d.ts +91 -0
  84. package/dist/agent/knowledge/lifecycle.d.ts.map +1 -0
  85. package/dist/agent/knowledge/lifecycle.js +205 -0
  86. package/dist/agent/knowledge/lifecycle.js.map +1 -0
  87. package/dist/agent/knowledge/provenance.d.ts +15 -0
  88. package/dist/agent/knowledge/provenance.d.ts.map +1 -0
  89. package/dist/agent/knowledge/provenance.js +37 -0
  90. package/dist/agent/knowledge/provenance.js.map +1 -0
  91. package/dist/agent/knowledge/reindex-cli.d.ts +13 -0
  92. package/dist/agent/knowledge/reindex-cli.d.ts.map +1 -0
  93. package/dist/agent/knowledge/reindex-cli.js +53 -0
  94. package/dist/agent/knowledge/reindex-cli.js.map +1 -0
  95. package/dist/agent/knowledge/reindex-spawn.d.ts +30 -0
  96. package/dist/agent/knowledge/reindex-spawn.d.ts.map +1 -0
  97. package/dist/agent/knowledge/reindex-spawn.js +97 -0
  98. package/dist/agent/knowledge/reindex-spawn.js.map +1 -0
  99. package/dist/agent/knowledge/shared-promote.d.ts +18 -0
  100. package/dist/agent/knowledge/shared-promote.d.ts.map +1 -0
  101. package/dist/agent/knowledge/shared-promote.js +29 -0
  102. package/dist/agent/knowledge/shared-promote.js.map +1 -0
  103. package/dist/agent/knowledge/shared-writer.d.ts +24 -0
  104. package/dist/agent/knowledge/shared-writer.d.ts.map +1 -0
  105. package/dist/agent/knowledge/shared-writer.js +97 -0
  106. package/dist/agent/knowledge/shared-writer.js.map +1 -0
  107. package/dist/agent/knowledge/types.d.ts +83 -0
  108. package/dist/agent/knowledge/types.d.ts.map +1 -0
  109. package/dist/agent/knowledge/types.js +12 -0
  110. package/dist/agent/knowledge/types.js.map +1 -0
  111. package/dist/agent/knowledge/wiki.d.ts +107 -0
  112. package/dist/agent/knowledge/wiki.d.ts.map +1 -0
  113. package/dist/agent/knowledge/wiki.js +415 -0
  114. package/dist/agent/knowledge/wiki.js.map +1 -0
  115. package/dist/agent/memory-metrics.d.ts +48 -0
  116. package/dist/agent/memory-metrics.d.ts.map +1 -0
  117. package/dist/agent/memory-metrics.js +156 -0
  118. package/dist/agent/memory-metrics.js.map +1 -0
  119. package/dist/agent/runner.d.ts +24 -1
  120. package/dist/agent/runner.d.ts.map +1 -1
  121. package/dist/agent/runner.js +82 -6
  122. package/dist/agent/runner.js.map +1 -1
  123. package/dist/agent/skill-learning/config.d.ts +18 -0
  124. package/dist/agent/skill-learning/config.d.ts.map +1 -0
  125. package/dist/agent/skill-learning/config.js +71 -0
  126. package/dist/agent/skill-learning/config.js.map +1 -0
  127. package/dist/agent/skill-learning/curator.d.ts +45 -0
  128. package/dist/agent/skill-learning/curator.d.ts.map +1 -0
  129. package/dist/agent/skill-learning/curator.js +171 -0
  130. package/dist/agent/skill-learning/curator.js.map +1 -0
  131. package/dist/agent/skill-learning/index.d.ts +79 -0
  132. package/dist/agent/skill-learning/index.d.ts.map +1 -0
  133. package/dist/agent/skill-learning/index.js +308 -0
  134. package/dist/agent/skill-learning/index.js.map +1 -0
  135. package/dist/agent/skill-learning/metrics.d.ts +13 -0
  136. package/dist/agent/skill-learning/metrics.d.ts.map +1 -0
  137. package/dist/agent/skill-learning/metrics.js +109 -0
  138. package/dist/agent/skill-learning/metrics.js.map +1 -0
  139. package/dist/agent/skill-learning/notifier.d.ts +111 -0
  140. package/dist/agent/skill-learning/notifier.d.ts.map +1 -0
  141. package/dist/agent/skill-learning/notifier.js +398 -0
  142. package/dist/agent/skill-learning/notifier.js.map +1 -0
  143. package/dist/agent/skill-learning/reviewer.d.ts +61 -0
  144. package/dist/agent/skill-learning/reviewer.d.ts.map +1 -0
  145. package/dist/agent/skill-learning/reviewer.js +271 -0
  146. package/dist/agent/skill-learning/reviewer.js.map +1 -0
  147. package/dist/agent/skill-learning/telemetry.d.ts +22 -0
  148. package/dist/agent/skill-learning/telemetry.d.ts.map +1 -0
  149. package/dist/agent/skill-learning/telemetry.js +90 -0
  150. package/dist/agent/skill-learning/telemetry.js.map +1 -0
  151. package/dist/agent/skill-learning/trigger.d.ts +23 -0
  152. package/dist/agent/skill-learning/trigger.d.ts.map +1 -0
  153. package/dist/agent/skill-learning/trigger.js +44 -0
  154. package/dist/agent/skill-learning/trigger.js.map +1 -0
  155. package/dist/agent/skill-learning/types.d.ts +165 -0
  156. package/dist/agent/skill-learning/types.d.ts.map +1 -0
  157. package/dist/agent/skill-learning/types.js +11 -0
  158. package/dist/agent/skill-learning/types.js.map +1 -0
  159. package/dist/agent/skill-learning/writer.d.ts +37 -0
  160. package/dist/agent/skill-learning/writer.d.ts.map +1 -0
  161. package/dist/agent/skill-learning/writer.js +223 -0
  162. package/dist/agent/skill-learning/writer.js.map +1 -0
  163. package/dist/agent/workspace-loader.d.ts +83 -6
  164. package/dist/agent/workspace-loader.d.ts.map +1 -1
  165. package/dist/agent/workspace-loader.js +207 -14
  166. package/dist/agent/workspace-loader.js.map +1 -1
  167. package/dist/api/gateway-router.d.ts +2 -0
  168. package/dist/api/gateway-router.d.ts.map +1 -1
  169. package/dist/api/gateway-router.js +293 -6
  170. package/dist/api/gateway-router.js.map +1 -1
  171. package/dist/api/share-router.d.ts.map +1 -1
  172. package/dist/api/share-router.js +27 -1
  173. package/dist/api/share-router.js.map +1 -1
  174. package/dist/api/skills-router.d.ts +2 -2
  175. package/dist/api/skills-router.d.ts.map +1 -1
  176. package/dist/api/skills-router.js +61 -1
  177. package/dist/api/skills-router.js.map +1 -1
  178. package/dist/apps/agent-manager.d.ts +7 -0
  179. package/dist/apps/agent-manager.d.ts.map +1 -1
  180. package/dist/apps/agent-manager.js +13 -1
  181. package/dist/apps/agent-manager.js.map +1 -1
  182. package/dist/config/migrator.d.ts +2 -0
  183. package/dist/config/migrator.d.ts.map +1 -1
  184. package/dist/config/migrator.js +72 -1
  185. package/dist/config/migrator.js.map +1 -1
  186. package/dist/history/cleanup.d.ts +7 -0
  187. package/dist/history/cleanup.d.ts.map +1 -1
  188. package/dist/history/cleanup.js +27 -0
  189. package/dist/history/cleanup.js.map +1 -1
  190. package/dist/history/db.d.ts +65 -0
  191. package/dist/history/db.d.ts.map +1 -1
  192. package/dist/history/db.js +261 -0
  193. package/dist/history/db.js.map +1 -1
  194. package/dist/index.js +122 -20
  195. package/dist/index.js.map +1 -1
  196. package/dist/session/process.d.ts +10 -0
  197. package/dist/session/process.d.ts.map +1 -1
  198. package/dist/session/process.js +86 -1
  199. package/dist/session/process.js.map +1 -1
  200. package/dist/share/share-store.d.ts +11 -0
  201. package/dist/share/share-store.d.ts.map +1 -1
  202. package/dist/share/share-store.js +3 -1
  203. package/dist/share/share-store.js.map +1 -1
  204. package/dist/skills/loader.d.ts +8 -0
  205. package/dist/skills/loader.d.ts.map +1 -1
  206. package/dist/skills/loader.js +29 -1
  207. package/dist/skills/loader.js.map +1 -1
  208. package/dist/types.d.ts +116 -0
  209. package/dist/types.d.ts.map +1 -1
  210. package/dist/ui/web-ui.d.ts.map +1 -1
  211. package/dist/ui/web-ui.js +1126 -3
  212. package/dist/ui/web-ui.js.map +1 -1
  213. package/mcp/package.json +2 -1
  214. package/mcp/server.ts +2 -0
  215. package/mcp/tools/image/module.ts +114 -9
  216. package/mcp/tools/memory/archive-reader.test.ts +212 -0
  217. package/mcp/tools/memory/archive-reader.ts +253 -0
  218. package/mcp/tools/memory/module.ts +152 -0
  219. package/mcp/tools/memory/retrieval-recorder.ts +66 -0
  220. package/mcp/tools/shared/share-client.ts +20 -1
  221. package/mcp/tools/skills/module.ts +28 -0
  222. package/package.json +1 -1
  223. package/resource/claude_gateway.svg +1038 -112
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ /**
3
+ * SkillLearningManager — the only export the runner/index wire to.
4
+ *
5
+ * Owns the closed loop: cheap per-turn telemetry capture (always-on), a
6
+ * debounced session-idle review trigger, the print-only reviewer, the
7
+ * provenance-guarded writer, and the daily curator. All turn-lifecycle methods
8
+ * are best-effort and MUST never throw into the runner's hot path.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.SkillLearningManager = exports.REVIEW_IDLE_DEBOUNCE_MS = void 0;
12
+ const loader_1 = require("../../skills/loader");
13
+ const parser_1 = require("../../skills/parser");
14
+ const config_1 = require("./config");
15
+ const telemetry_1 = require("./telemetry");
16
+ const trigger_1 = require("./trigger");
17
+ const reviewer_1 = require("./reviewer");
18
+ const writer_1 = require("./writer");
19
+ const curator_1 = require("./curator");
20
+ const metrics_1 = require("./metrics");
21
+ const notifier_1 = require("./notifier");
22
+ /** Debounce: fire the review this long after the last turn ends (session-idle proxy). */
23
+ exports.REVIEW_IDLE_DEBOUNCE_MS = 20000;
24
+ /** Heuristic: a user message that reads like a correction of the agent's last action. */
25
+ const CORRECTION_RE = /^\s*(no\b|not\b|wrong\b|that'?s not|nope\b|ไม่ใช่|ผิด|บ่ใช่)/i;
26
+ class SkillLearningManager {
27
+ constructor(opts) {
28
+ this.accum = new Map();
29
+ this.reviewInFlight = new Set();
30
+ this.idleTimers = new Map();
31
+ this.db = opts.db;
32
+ this.agentId = opts.agentId;
33
+ this.workspaceDir = opts.workspaceDir;
34
+ this.mcpToolsDir = opts.mcpToolsDir;
35
+ this.sharedSkillsDir = opts.sharedSkillsDir;
36
+ this.logger = opts.logger;
37
+ this.reviewSpawn = opts.reviewSpawn;
38
+ this.now = opts.now ?? Date.now;
39
+ this.cfg = (0, config_1.resolveSkillLearningConfig)(opts.agentCfg, opts.globalCfg);
40
+ this.notifier =
41
+ opts.notifier ??
42
+ new notifier_1.SkillNotifier({
43
+ workspaceDir: this.workspaceDir,
44
+ notify: this.cfg.notify,
45
+ send: (0, notifier_1.buildChannelSend)(this.workspaceDir, opts.channels ?? {}, opts.logger),
46
+ logger: opts.logger,
47
+ });
48
+ }
49
+ isEnabled() {
50
+ return this.cfg.enabled;
51
+ }
52
+ // ---- Turn lifecycle (called by the runner; all best-effort) ----------------
53
+ /** A user turn begins. `invokedSkills` = skills detected in the incoming message. */
54
+ onTurnStart(mapKey, sessionId, firstUserMessage, invokedSkills = []) {
55
+ try {
56
+ let a = this.accum.get(mapKey);
57
+ if (!a || a.sessionId !== sessionId) {
58
+ a = this.freshAccum(sessionId);
59
+ }
60
+ else {
61
+ a.turnIdx += 1;
62
+ }
63
+ a.startedAt = this.now();
64
+ a.toolUseIds.clear();
65
+ a.toolCalls = 0;
66
+ a.tokensIn = 0;
67
+ a.tokensOut = 0;
68
+ a.recoveryFired = false;
69
+ a.skillsLoaded = new Set(invokedSkills.filter(Boolean));
70
+ a.firstUserMsg = firstUserMessage ?? '';
71
+ if (CORRECTION_RE.test(a.firstUserMsg))
72
+ a.sigCorrection = true;
73
+ this.accum.set(mapKey, a);
74
+ }
75
+ catch {
76
+ /* never break the turn */
77
+ }
78
+ }
79
+ /** A tool_use block streamed by. Deduped by block id (cumulative snapshots). */
80
+ onToolUse(mapKey, toolUseId) {
81
+ const a = this.accum.get(mapKey);
82
+ if (!a)
83
+ return;
84
+ if (toolUseId) {
85
+ if (a.toolUseIds.has(toolUseId))
86
+ return;
87
+ a.toolUseIds.add(toolUseId);
88
+ }
89
+ a.toolCalls += 1;
90
+ }
91
+ onTokenUsage(mapKey, inputTokens, totalTokens) {
92
+ const a = this.accum.get(mapKey);
93
+ if (!a)
94
+ return;
95
+ if (inputTokens > a.tokensIn)
96
+ a.tokensIn = inputTokens; // peak context
97
+ a.tokensOut += Math.max(0, totalTokens); // accumulated work
98
+ }
99
+ onRecoveryFired(mapKey) {
100
+ const a = this.accum.get(mapKey);
101
+ if (!a)
102
+ return;
103
+ a.recoveryFired = true;
104
+ a.sigRecovery = true;
105
+ }
106
+ /** A user turn ended. Persist the metric row + arm the idle-review debounce. */
107
+ onTurnEnd(mapKey, sessionId) {
108
+ try {
109
+ const a = this.accum.get(mapKey);
110
+ if (!a || a.sessionId !== sessionId)
111
+ return;
112
+ const ts = this.now();
113
+ const skills = [...a.skillsLoaded];
114
+ this.db.insertTurnMetric({
115
+ sessionId,
116
+ turnIdx: a.turnIdx,
117
+ ts,
118
+ toolCalls: a.toolCalls,
119
+ durationMs: Math.max(0, ts - a.startedAt),
120
+ tokensIn: a.tokensIn,
121
+ tokensOut: a.tokensOut,
122
+ recoveryFired: a.recoveryFired ? 1 : 0,
123
+ skillsLoaded: skills.length ? JSON.stringify(skills) : null,
124
+ intentHash: (0, telemetry_1.intentHash)(a.firstUserMsg),
125
+ enabled: this.cfg.enabled ? 1 : 0,
126
+ });
127
+ for (const name of skills)
128
+ this.db.bumpSkillLoaded(name, ts);
129
+ a.sigMaxToolCalls = Math.max(a.sigMaxToolCalls, a.toolCalls);
130
+ this.scheduleIdleReview(mapKey, sessionId);
131
+ }
132
+ catch {
133
+ /* best-effort */
134
+ }
135
+ }
136
+ // ---- Review path -----------------------------------------------------------
137
+ scheduleIdleReview(mapKey, sessionId) {
138
+ if (!this.cfg.enabled)
139
+ return; // capture still ran above; review is the gated part
140
+ const existing = this.idleTimers.get(mapKey);
141
+ if (existing)
142
+ clearTimeout(existing);
143
+ const t = setTimeout(() => {
144
+ this.idleTimers.delete(mapKey);
145
+ void this.runReviewNow(mapKey, sessionId);
146
+ }, exports.REVIEW_IDLE_DEBOUNCE_MS);
147
+ if (typeof t.unref === 'function')
148
+ t.unref();
149
+ this.idleTimers.set(mapKey, t);
150
+ }
151
+ /**
152
+ * The gated review entry (also the direct test seam). Reads session signals,
153
+ * checks the daily budget, and — if the gate passes — runs the reviewer and
154
+ * applies the proposal. Never throws.
155
+ */
156
+ async runReviewNow(mapKey, sessionId) {
157
+ if (!this.cfg.enabled)
158
+ return;
159
+ if (this.reviewInFlight.has(sessionId))
160
+ return;
161
+ const a = this.accum.get(mapKey);
162
+ if (!a || a.sessionId !== sessionId)
163
+ return;
164
+ const signals = {
165
+ toolCalls: a.sigMaxToolCalls,
166
+ recoveryFired: a.sigRecovery,
167
+ userCorrection: a.sigCorrection,
168
+ };
169
+ const dayStart = (0, telemetry_1.startOfDayMs)(this.now(), this.cfg.pruneTimezone);
170
+ const spent = this.db.countReviewRunsSince(dayStart);
171
+ const decision = (0, trigger_1.shouldReview)(signals, this.cfg, { spent, cap: this.cfg.maxReviewsPerDay });
172
+ if (!decision.review)
173
+ return;
174
+ this.reviewInFlight.add(sessionId);
175
+ try {
176
+ const transcript = this.gatherTranscript(sessionId);
177
+ if (!transcript.trim())
178
+ return;
179
+ const existing = this.loadExistingSkills();
180
+ const { proposal, tokensSpent } = await (0, reviewer_1.runReviewer)({ transcript, existingSkills: existing.map((s) => ({ name: s.name, description: s.description })) }, this.cfg, this.reviewSpawn);
181
+ const outcome = (0, writer_1.applyProposal)(proposal, {
182
+ workspaceDir: this.workspaceDir,
183
+ sessionId,
184
+ now: this.now(),
185
+ mode: this.cfg.mode,
186
+ existing,
187
+ });
188
+ // Record provenance only on a genuine create — an edit's skill_stats row
189
+ // already exists (from the original create), so re-recording would reset
190
+ // its created_at (age clock) and usage counters.
191
+ if (outcome.written && !outcome.queued && outcome.action === 'create' && outcome.name) {
192
+ this.db.recordSkillCreated({
193
+ name: outcome.name,
194
+ origin: 'auto',
195
+ createdAt: this.now(),
196
+ createdFromSession: sessionId,
197
+ pinned: 0,
198
+ });
199
+ }
200
+ this.db.insertReviewRun({
201
+ sessionId,
202
+ ts: this.now(),
203
+ triggerReason: decision.reason,
204
+ outcome: outcome.written ? outcome.action : proposal.action === 'none' ? 'none' : 'error',
205
+ tokensSpent,
206
+ });
207
+ // Tell the operator a skill changed — diary (always) + throttled channel
208
+ // push. Only for a genuine live write (not the propose review queue).
209
+ if (outcome.written && !outcome.queued && outcome.name &&
210
+ (outcome.action === 'create' || outcome.action === 'edit')) {
211
+ this.notifier.onSkillWritten({
212
+ name: outcome.name,
213
+ action: outcome.action,
214
+ sessionId,
215
+ now: this.now(),
216
+ });
217
+ }
218
+ this.logger?.info(`[skill-learning:${this.agentId}] review (${decision.reason}) → ${outcome.written ? `${outcome.action}:${outcome.name}${outcome.queued ? ' (queued)' : ''}` : `no-write (${outcome.reason ?? proposal.action})`} tokens=${tokensSpent}`);
219
+ }
220
+ catch (err) {
221
+ this.logger?.warn?.(`[skill-learning:${this.agentId}] review failed: ${err.message}`);
222
+ }
223
+ finally {
224
+ this.reviewInFlight.delete(sessionId);
225
+ // Reset session signals so the next batch of turns re-qualifies from scratch.
226
+ a.sigMaxToolCalls = 0;
227
+ a.sigRecovery = false;
228
+ a.sigCorrection = false;
229
+ }
230
+ }
231
+ // ---- Curator ---------------------------------------------------------------
232
+ /** Start the daily curator scheduler. Returns a canceller. */
233
+ startCurator() {
234
+ return (0, curator_1.startCurator)(() => ({
235
+ db: this.db,
236
+ workspaceDir: this.workspaceDir,
237
+ agentId: this.agentId,
238
+ cfg: this.cfg,
239
+ logger: this.logger,
240
+ }), this.cfg);
241
+ }
242
+ /** Run one curation sweep immediately (test/ops seam). */
243
+ curateNow() {
244
+ return (0, curator_1.curateOnce)({
245
+ db: this.db,
246
+ workspaceDir: this.workspaceDir,
247
+ agentId: this.agentId,
248
+ cfg: this.cfg,
249
+ now: this.now(),
250
+ logger: this.logger,
251
+ });
252
+ }
253
+ /** The effectiveness rollup (REST/MCP read side). */
254
+ rollup() {
255
+ return (0, metrics_1.computeRollup)(this.db, this.agentId, this.now());
256
+ }
257
+ // ---- Internals -------------------------------------------------------------
258
+ freshAccum(sessionId) {
259
+ return {
260
+ sessionId,
261
+ turnIdx: 0,
262
+ startedAt: this.now(),
263
+ toolUseIds: new Set(),
264
+ toolCalls: 0,
265
+ tokensIn: 0,
266
+ tokensOut: 0,
267
+ recoveryFired: false,
268
+ skillsLoaded: new Set(),
269
+ firstUserMsg: '',
270
+ sigMaxToolCalls: 0,
271
+ sigRecovery: false,
272
+ sigCorrection: false,
273
+ };
274
+ }
275
+ gatherTranscript(sessionId) {
276
+ const rows = this.db.getSessionTranscript(sessionId, 200);
277
+ return rows
278
+ .map((r) => `${r.role === 'assistant' ? 'assistant' : 'user'}: ${r.content}`)
279
+ .join('\n')
280
+ .slice(-20000); // bound the reviewer prompt
281
+ }
282
+ /** All loaded skills with resolved provenance + path (for dedup + guards). */
283
+ loadExistingSkills() {
284
+ try {
285
+ const registry = (0, loader_1.loadSkills)({
286
+ workspaceDir: this.workspaceDir,
287
+ mcpToolsDir: this.mcpToolsDir,
288
+ sharedSkillsDir: this.sharedSkillsDir,
289
+ });
290
+ const out = [];
291
+ for (const skill of registry.skills.values()) {
292
+ let origin = 'user';
293
+ // Only workspace skills can ever be origin:auto; trust the on-disk FM.
294
+ if (skill.source === 'workspace') {
295
+ const fm = (0, parser_1.extractFrontmatter)(skill.content)?.frontmatter;
296
+ origin = fm && fm['origin'] === 'auto' ? 'auto' : (0, writer_1.readSkillOrigin)(skill.filePath);
297
+ }
298
+ out.push({ name: skill.name, description: skill.description, origin, filePath: skill.filePath });
299
+ }
300
+ return out;
301
+ }
302
+ catch {
303
+ return [];
304
+ }
305
+ }
306
+ }
307
+ exports.SkillLearningManager = SkillLearningManager;
308
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agent/skill-learning/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Metrics (read side) — the 5 effectiveness measures, all derived from
3
+ * turn_metrics + skill_stats + skill_review_runs. This is the concrete
4
+ * "measurable effectiveness" surface (planning-62 §Measurement).
5
+ *
6
+ * All measures are directional/heuristic by design; the causal signal is the
7
+ * `enabled` on/off cohort (measure 4) and the net-token ledger (measure 5).
8
+ */
9
+ import type { HistoryDB } from '../../history/db';
10
+ import type { SkillMetricsRollup } from './types';
11
+ /** Compute the full effectiveness rollup for an agent. */
12
+ export declare function computeRollup(db: HistoryDB, agentId: string, now: number): SkillMetricsRollup;
13
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/agent/skill-learning/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA4BlD,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAqD7F"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * Metrics (read side) — the 5 effectiveness measures, all derived from
4
+ * turn_metrics + skill_stats + skill_review_runs. This is the concrete
5
+ * "measurable effectiveness" surface (planning-62 §Measurement).
6
+ *
7
+ * All measures are directional/heuristic by design; the causal signal is the
8
+ * `enabled` on/off cohort (measure 4) and the net-token ledger (measure 5).
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.computeRollup = computeRollup;
12
+ function median(values) {
13
+ if (values.length === 0)
14
+ return 0;
15
+ const s = values.slice().sort((a, b) => a - b);
16
+ const mid = Math.floor(s.length / 2);
17
+ return s.length % 2 ? s[mid] : Math.round((s[mid - 1] + s[mid]) / 2);
18
+ }
19
+ /** Median for display, or `null` when there is no data (distinct from a real 0). */
20
+ function medianOrNull(values) {
21
+ return values.length === 0 ? null : median(values);
22
+ }
23
+ function turnTokens(r) {
24
+ return r.tokensIn + r.tokensOut;
25
+ }
26
+ function hasSkill(r) {
27
+ if (!r.skillsLoaded)
28
+ return false;
29
+ try {
30
+ const arr = JSON.parse(r.skillsLoaded);
31
+ return Array.isArray(arr) && arr.length > 0;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ /** Compute the full effectiveness rollup for an agent. */
38
+ function computeRollup(db, agentId, now) {
39
+ const stats = db.listSkillStats();
40
+ const autoStats = stats.filter((s) => s.origin === 'auto');
41
+ const turns = db.listTurnMetrics(0);
42
+ const reviews = db.listReviewRuns(0);
43
+ // ---- Measure 1: adoption funnel ----
44
+ const autoSkills = autoStats.length;
45
+ const loadedAtLeast1 = autoStats.filter((s) => s.timesLoaded >= 1).length;
46
+ const loadedAtLeast3 = autoStats.filter((s) => s.timesLoaded >= 3).length;
47
+ const stickyPct = autoSkills > 0 ? (loadedAtLeast3 / autoSkills) * 100 : 0;
48
+ // ---- Measure 2: cost-to-complete delta (skill-loaded turns vs not) ----
49
+ const before = turns.filter((t) => !hasSkill(t));
50
+ const after = turns.filter((t) => hasSkill(t));
51
+ const clusters = new Set(turns.map((t) => t.intentHash ?? 'misc')).size;
52
+ // ---- Measure 3: recovery-rate trend (earlier half vs recent half by ts) ----
53
+ const byTs = turns.slice().sort((a, b) => a.ts - b.ts);
54
+ const half = Math.floor(byTs.length / 2);
55
+ const earlier = byTs.slice(0, half);
56
+ const recent = byTs.slice(half);
57
+ const rate = (rows) => rows.length ? (rows.filter((r) => r.recoveryFired).length / rows.length) * 100 : 0;
58
+ // ---- Measure 4: cohort A/B by the `enabled` column ----
59
+ const enabledTurns = turns.filter((t) => t.enabled === 1);
60
+ const disabledTurns = turns.filter((t) => t.enabled === 0);
61
+ // ---- Measure 5: net token economics ----
62
+ const spentReviewing = reviews.reduce((n, r) => n + r.tokensSpent, 0);
63
+ const savedByReuse = estimateSaved(turns);
64
+ return {
65
+ agentId,
66
+ generatedAt: now,
67
+ adoption: { autoSkills, loadedAtLeast1, loadedAtLeast3, stickyPct },
68
+ costDelta: {
69
+ clusters,
70
+ medianToolCallsBefore: medianOrNull(before.map((t) => t.toolCalls)),
71
+ medianToolCallsAfter: medianOrNull(after.map((t) => t.toolCalls)),
72
+ medianTokensBefore: medianOrNull(before.map(turnTokens)),
73
+ medianTokensAfter: medianOrNull(after.map(turnTokens)),
74
+ },
75
+ recovery: { ratePctRecent: rate(recent), ratePctEarlier: rate(earlier) },
76
+ cohort: {
77
+ enabledTurns: enabledTurns.length,
78
+ disabledTurns: disabledTurns.length,
79
+ enabledMedianToolCalls: medianOrNull(enabledTurns.map((t) => t.toolCalls)),
80
+ disabledMedianToolCalls: medianOrNull(disabledTurns.map((t) => t.toolCalls)),
81
+ },
82
+ netTokens: { savedByReuse, spentReviewing, net: savedByReuse - spentReviewing },
83
+ };
84
+ }
85
+ /**
86
+ * Estimate tokens saved by reuse: per intent cluster, take the median token cost
87
+ * of "before" (no-skill) turns as the counterfactual, and credit each "after"
88
+ * (skill-loaded) turn the positive difference. Sum across clusters.
89
+ */
90
+ function estimateSaved(turns) {
91
+ const byCluster = new Map();
92
+ for (const t of turns) {
93
+ const k = t.intentHash ?? 'misc';
94
+ (byCluster.get(k) ?? byCluster.set(k, []).get(k)).push(t);
95
+ }
96
+ let saved = 0;
97
+ for (const rows of byCluster.values()) {
98
+ const before = rows.filter((r) => !hasSkill(r));
99
+ const after = rows.filter((r) => hasSkill(r));
100
+ if (!before.length || !after.length)
101
+ continue;
102
+ const baseline = median(before.map(turnTokens));
103
+ for (const a of after) {
104
+ saved += Math.max(0, baseline - turnTokens(a));
105
+ }
106
+ }
107
+ return saved;
108
+ }
109
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/agent/skill-learning/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Skill notifier — tells the operator when the closed loop writes a skill.
3
+ *
4
+ * Two independent surfaces (per user request, 2026-08-17):
5
+ * 1. **Diary** (`SKILLS_LEARNED.md` in the workspace) — ALWAYS appended, an
6
+ * immutable audit log of every auto-write. Cheap, offline, never throttled.
7
+ * 2. **Channel push** (Telegram) — a short "learned a skill" ping, gated by
8
+ * `cfg.notify`. Throttled: up to NOTIFY_THROTTLE_MAX immediate pings per
9
+ * rolling window, then further writes coalesce into one digest so a burst
10
+ * cannot spam the chat.
11
+ *
12
+ * Everything here is best-effort and MUST NOT throw into the review path.
13
+ * The channel transport (`send`) is injected — the manager builds the real
14
+ * Telegram sender; tests pass a capturing stub. Diary + throttle logic are
15
+ * transport-agnostic and fully unit-testable with an injected clock.
16
+ */
17
+ export declare const DIARY_FILENAME = "SKILLS_LEARNED.md";
18
+ /** Rolling window for the burst throttle. */
19
+ export declare const NOTIFY_THROTTLE_WINDOW_MS: number;
20
+ /** Immediate pings allowed per window before writes coalesce into a digest. */
21
+ export declare const NOTIFY_THROTTLE_MAX = 3;
22
+ /** A channel transport: deliver one plain-text message. Never expected to throw. */
23
+ export type SendFn = (text: string) => void | Promise<void>;
24
+ export interface SkillWriteEvent {
25
+ name: string;
26
+ action: 'create' | 'edit';
27
+ sessionId: string;
28
+ /** Timestamp (ms) — injected clock so tests are deterministic. */
29
+ now: number;
30
+ }
31
+ export interface SkillNotifierOpts {
32
+ workspaceDir: string;
33
+ /** Channel push on/off. The diary is written regardless. */
34
+ notify: boolean;
35
+ /** Channel transport. `undefined` ⇒ no channel wired (diary-only). */
36
+ send?: SendFn;
37
+ logger?: {
38
+ info: (msg: string) => void;
39
+ warn?: (msg: string) => void;
40
+ };
41
+ }
42
+ /**
43
+ * Read the Telegram allowlist for a workspace — the chat_ids authorized to talk
44
+ * to this agent, which are exactly the right recipients for its notifications
45
+ * (Telegram DM chat_id == user_id). Best-effort: any error ⇒ no recipients.
46
+ */
47
+ export declare function readTelegramRecipients(workspaceDir: string): string[];
48
+ /** POST a Telegram sendMessage. Throws on HTTP failure so the caller can log it. */
49
+ export declare function pushTelegram(botToken: string, chatId: string, text: string): Promise<void>;
50
+ /**
51
+ * Build the channel `send` transport for an agent from its Telegram bot token.
52
+ * Returns `undefined` when no token is configured (diary-only). The returned fn
53
+ * resolves recipients fresh on each call (allowlist may change at runtime) and
54
+ * fans out best-effort — one failed recipient never blocks the others.
55
+ */
56
+ export declare function buildTelegramSend(workspaceDir: string, botToken: string | undefined, logger?: SkillNotifierOpts['logger']): SendFn | undefined;
57
+ /** Per-agent channel credentials available at gateway boot (from AgentConfig). */
58
+ export interface ChannelTokens {
59
+ telegramBotToken?: string;
60
+ discordBotToken?: string;
61
+ /** LINE channel access token. Present ⇒ the LINE transport self-activates. */
62
+ lineAccessToken?: string;
63
+ }
64
+ /** Discord recipients: user_ids from `.discord-state/access.json` `allowFrom`. */
65
+ export declare function readDiscordRecipients(workspaceDir: string): string[];
66
+ /** DM a Discord user (open DM channel, then post chunked). Throws on HTTP failure. */
67
+ export declare function pushDiscordDM(botToken: string, userId: string, text: string): Promise<void>;
68
+ /** Build the Discord `send` transport. undefined when no bot token is configured. */
69
+ export declare function buildDiscordSend(workspaceDir: string, botToken: string | undefined, logger?: SkillNotifierOpts['logger']): SendFn | undefined;
70
+ /** LINE recipients: user_ids from `.line-state/access.json` `allowFrom`. */
71
+ export declare function readLineRecipients(workspaceDir: string): string[];
72
+ /** Push a LINE text message to a user. Throws on HTTP failure so the caller can log it. */
73
+ export declare function pushLine(accessToken: string, to: string, text: string): Promise<void>;
74
+ /**
75
+ * Build the LINE `send` transport. undefined when no channel access token is
76
+ * configured — so LINE stays dormant until an agent has LINE set up, at which
77
+ * point it self-activates with no code change ("just open it": the token flows
78
+ * in from AgentConfig.line.channelAccessToken at boot).
79
+ */
80
+ export declare function buildLineSend(workspaceDir: string, accessToken: string | undefined, logger?: SkillNotifierOpts['logger']): SendFn | undefined;
81
+ /**
82
+ * Build a single fan-out `send` across every configured channel transport.
83
+ * Returns undefined when the agent has no push channel wired (diary-only).
84
+ * Fan-out is best-effort and concurrent — one channel failing never blocks the
85
+ * others, and no rejection escapes into the review path.
86
+ */
87
+ export declare function buildChannelSend(workspaceDir: string, tokens: ChannelTokens, logger?: SkillNotifierOpts['logger']): SendFn | undefined;
88
+ export declare class SkillNotifier {
89
+ private readonly workspaceDir;
90
+ private readonly notify;
91
+ private readonly send?;
92
+ private readonly logger?;
93
+ /** Timestamps of immediate pings still inside the current window. */
94
+ private recent;
95
+ /** Coalesced writes awaiting a digest flush. */
96
+ private buffer;
97
+ private flushTimer?;
98
+ constructor(opts: SkillNotifierOpts);
99
+ /**
100
+ * Record a live skill write. Appends the diary (always) and, if channel push
101
+ * is on, either pings immediately or buffers for a digest. Never throws.
102
+ */
103
+ onSkillWritten(ev: SkillWriteEvent): void;
104
+ /** Emit any buffered digest now (shutdown / test seam / timer callback). */
105
+ flushPending(): void;
106
+ private pushThrottled;
107
+ private armFlush;
108
+ private safeSend;
109
+ private appendDiary;
110
+ }
111
+ //# sourceMappingURL=notifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../../src/agent/skill-learning/notifier.ts"],"names":[],"mappings":"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"}