claude-cognitive 0.1.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 (196) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/bin/claude-cognitive.js +9 -0
  4. package/dist/agents/context.d.ts +40 -0
  5. package/dist/agents/context.d.ts.map +1 -0
  6. package/dist/agents/context.js +144 -0
  7. package/dist/agents/context.js.map +1 -0
  8. package/dist/agents/index.d.ts +9 -0
  9. package/dist/agents/index.d.ts.map +1 -0
  10. package/dist/agents/index.js +11 -0
  11. package/dist/agents/index.js.map +1 -0
  12. package/dist/agents/loader.d.ts +48 -0
  13. package/dist/agents/loader.d.ts.map +1 -0
  14. package/dist/agents/loader.js +157 -0
  15. package/dist/agents/loader.js.map +1 -0
  16. package/dist/agents/templates.d.ts +51 -0
  17. package/dist/agents/templates.d.ts.map +1 -0
  18. package/dist/agents/templates.js +186 -0
  19. package/dist/agents/templates.js.map +1 -0
  20. package/dist/agents/types.d.ts +52 -0
  21. package/dist/agents/types.d.ts.map +1 -0
  22. package/dist/agents/types.js +6 -0
  23. package/dist/agents/types.js.map +1 -0
  24. package/dist/cli/commands/config.d.ts +10 -0
  25. package/dist/cli/commands/config.d.ts.map +1 -0
  26. package/dist/cli/commands/config.js +22 -0
  27. package/dist/cli/commands/config.js.map +1 -0
  28. package/dist/cli/commands/index.d.ts +17 -0
  29. package/dist/cli/commands/index.d.ts.map +1 -0
  30. package/dist/cli/commands/index.js +17 -0
  31. package/dist/cli/commands/index.js.map +1 -0
  32. package/dist/cli/commands/init.d.ts +10 -0
  33. package/dist/cli/commands/init.d.ts.map +1 -0
  34. package/dist/cli/commands/init.js +109 -0
  35. package/dist/cli/commands/init.js.map +1 -0
  36. package/dist/cli/commands/install.d.ts +10 -0
  37. package/dist/cli/commands/install.d.ts.map +1 -0
  38. package/dist/cli/commands/install.js +440 -0
  39. package/dist/cli/commands/install.js.map +1 -0
  40. package/dist/cli/commands/learn.d.ts +10 -0
  41. package/dist/cli/commands/learn.d.ts.map +1 -0
  42. package/dist/cli/commands/learn.js +33 -0
  43. package/dist/cli/commands/learn.js.map +1 -0
  44. package/dist/cli/commands/recall.d.ts +10 -0
  45. package/dist/cli/commands/recall.d.ts.map +1 -0
  46. package/dist/cli/commands/recall.js +52 -0
  47. package/dist/cli/commands/recall.js.map +1 -0
  48. package/dist/cli/commands/reflect.d.ts +10 -0
  49. package/dist/cli/commands/reflect.d.ts.map +1 -0
  50. package/dist/cli/commands/reflect.js +48 -0
  51. package/dist/cli/commands/reflect.js.map +1 -0
  52. package/dist/cli/commands/semantic.d.ts +10 -0
  53. package/dist/cli/commands/semantic.d.ts.map +1 -0
  54. package/dist/cli/commands/semantic.js +67 -0
  55. package/dist/cli/commands/semantic.js.map +1 -0
  56. package/dist/cli/commands/serve.d.ts +10 -0
  57. package/dist/cli/commands/serve.d.ts.map +1 -0
  58. package/dist/cli/commands/serve.js +61 -0
  59. package/dist/cli/commands/serve.js.map +1 -0
  60. package/dist/cli/commands/status.d.ts +10 -0
  61. package/dist/cli/commands/status.d.ts.map +1 -0
  62. package/dist/cli/commands/status.js +44 -0
  63. package/dist/cli/commands/status.js.map +1 -0
  64. package/dist/cli/commands/sync.d.ts +10 -0
  65. package/dist/cli/commands/sync.d.ts.map +1 -0
  66. package/dist/cli/commands/sync.js +260 -0
  67. package/dist/cli/commands/sync.js.map +1 -0
  68. package/dist/cli/commands/uninstall.d.ts +10 -0
  69. package/dist/cli/commands/uninstall.d.ts.map +1 -0
  70. package/dist/cli/commands/uninstall.js +205 -0
  71. package/dist/cli/commands/uninstall.js.map +1 -0
  72. package/dist/cli/commands/update-bank.d.ts +10 -0
  73. package/dist/cli/commands/update-bank.d.ts.map +1 -0
  74. package/dist/cli/commands/update-bank.js +129 -0
  75. package/dist/cli/commands/update-bank.js.map +1 -0
  76. package/dist/cli/index.d.ts +6 -0
  77. package/dist/cli/index.d.ts.map +1 -0
  78. package/dist/cli/index.js +56 -0
  79. package/dist/cli/index.js.map +1 -0
  80. package/dist/cli/utils/errors.d.ts +42 -0
  81. package/dist/cli/utils/errors.d.ts.map +1 -0
  82. package/dist/cli/utils/errors.js +78 -0
  83. package/dist/cli/utils/errors.js.map +1 -0
  84. package/dist/cli/utils/index.d.ts +9 -0
  85. package/dist/cli/utils/index.d.ts.map +1 -0
  86. package/dist/cli/utils/index.js +7 -0
  87. package/dist/cli/utils/index.js.map +1 -0
  88. package/dist/cli/utils/output.d.ts +90 -0
  89. package/dist/cli/utils/output.d.ts.map +1 -0
  90. package/dist/cli/utils/output.js +164 -0
  91. package/dist/cli/utils/output.js.map +1 -0
  92. package/dist/client.d.ts +200 -0
  93. package/dist/client.d.ts.map +1 -0
  94. package/dist/client.js +447 -0
  95. package/dist/client.js.map +1 -0
  96. package/dist/config.d.ts +44 -0
  97. package/dist/config.d.ts.map +1 -0
  98. package/dist/config.js +264 -0
  99. package/dist/config.js.map +1 -0
  100. package/dist/errors.d.ts +72 -0
  101. package/dist/errors.d.ts.map +1 -0
  102. package/dist/errors.js +188 -0
  103. package/dist/errors.js.map +1 -0
  104. package/dist/events.d.ts +148 -0
  105. package/dist/events.d.ts.map +1 -0
  106. package/dist/events.js +115 -0
  107. package/dist/events.js.map +1 -0
  108. package/dist/hooks/index.d.ts +7 -0
  109. package/dist/hooks/index.d.ts.map +1 -0
  110. package/dist/hooks/index.js +7 -0
  111. package/dist/hooks/index.js.map +1 -0
  112. package/dist/hooks/inject-context.d.ts +18 -0
  113. package/dist/hooks/inject-context.d.ts.map +1 -0
  114. package/dist/hooks/inject-context.js +57 -0
  115. package/dist/hooks/inject-context.js.map +1 -0
  116. package/dist/hooks/process-session.d.ts +18 -0
  117. package/dist/hooks/process-session.d.ts.map +1 -0
  118. package/dist/hooks/process-session.js +119 -0
  119. package/dist/hooks/process-session.js.map +1 -0
  120. package/dist/index.d.ts +63 -0
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +59 -0
  123. package/dist/index.js.map +1 -0
  124. package/dist/learn/analyzers/git.d.ts +62 -0
  125. package/dist/learn/analyzers/git.d.ts.map +1 -0
  126. package/dist/learn/analyzers/git.js +183 -0
  127. package/dist/learn/analyzers/git.js.map +1 -0
  128. package/dist/learn/analyzers/index.d.ts +15 -0
  129. package/dist/learn/analyzers/index.d.ts.map +1 -0
  130. package/dist/learn/analyzers/index.js +10 -0
  131. package/dist/learn/analyzers/index.js.map +1 -0
  132. package/dist/learn/analyzers/package.d.ts +57 -0
  133. package/dist/learn/analyzers/package.d.ts.map +1 -0
  134. package/dist/learn/analyzers/package.js +245 -0
  135. package/dist/learn/analyzers/package.js.map +1 -0
  136. package/dist/learn/analyzers/readme.d.ts +27 -0
  137. package/dist/learn/analyzers/readme.d.ts.map +1 -0
  138. package/dist/learn/analyzers/readme.js +163 -0
  139. package/dist/learn/analyzers/readme.js.map +1 -0
  140. package/dist/learn/analyzers/source.d.ts +70 -0
  141. package/dist/learn/analyzers/source.d.ts.map +1 -0
  142. package/dist/learn/analyzers/source.js +231 -0
  143. package/dist/learn/analyzers/source.js.map +1 -0
  144. package/dist/learn/analyzers/structure.d.ts +39 -0
  145. package/dist/learn/analyzers/structure.d.ts.map +1 -0
  146. package/dist/learn/analyzers/structure.js +172 -0
  147. package/dist/learn/analyzers/structure.js.map +1 -0
  148. package/dist/learn/extractor.d.ts +76 -0
  149. package/dist/learn/extractor.d.ts.map +1 -0
  150. package/dist/learn/extractor.js +302 -0
  151. package/dist/learn/extractor.js.map +1 -0
  152. package/dist/learn/index.d.ts +31 -0
  153. package/dist/learn/index.d.ts.map +1 -0
  154. package/dist/learn/index.js +165 -0
  155. package/dist/learn/index.js.map +1 -0
  156. package/dist/mcp/handlers.d.ts +23 -0
  157. package/dist/mcp/handlers.d.ts.map +1 -0
  158. package/dist/mcp/handlers.js +124 -0
  159. package/dist/mcp/handlers.js.map +1 -0
  160. package/dist/mcp/index.d.ts +32 -0
  161. package/dist/mcp/index.d.ts.map +1 -0
  162. package/dist/mcp/index.js +40 -0
  163. package/dist/mcp/index.js.map +1 -0
  164. package/dist/mcp/server.d.ts +79 -0
  165. package/dist/mcp/server.d.ts.map +1 -0
  166. package/dist/mcp/server.js +277 -0
  167. package/dist/mcp/server.js.map +1 -0
  168. package/dist/mcp/tools.d.ts +59 -0
  169. package/dist/mcp/tools.d.ts.map +1 -0
  170. package/dist/mcp/tools.js +43 -0
  171. package/dist/mcp/tools.js.map +1 -0
  172. package/dist/mcp/types.d.ts +65 -0
  173. package/dist/mcp/types.d.ts.map +1 -0
  174. package/dist/mcp/types.js +6 -0
  175. package/dist/mcp/types.js.map +1 -0
  176. package/dist/mind.d.ts +250 -0
  177. package/dist/mind.d.ts.map +1 -0
  178. package/dist/mind.js +637 -0
  179. package/dist/mind.js.map +1 -0
  180. package/dist/promotion.d.ts +112 -0
  181. package/dist/promotion.d.ts.map +1 -0
  182. package/dist/promotion.js +196 -0
  183. package/dist/promotion.js.map +1 -0
  184. package/dist/retry.d.ts +70 -0
  185. package/dist/retry.d.ts.map +1 -0
  186. package/dist/retry.js +122 -0
  187. package/dist/retry.js.map +1 -0
  188. package/dist/semantic.d.ts +202 -0
  189. package/dist/semantic.d.ts.map +1 -0
  190. package/dist/semantic.js +424 -0
  191. package/dist/semantic.js.map +1 -0
  192. package/dist/types.d.ts +363 -0
  193. package/dist/types.d.ts.map +1 -0
  194. package/dist/types.js +30 -0
  195. package/dist/types.js.map +1 -0
  196. package/package.json +70 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Observation promotion logic for claude-cognitive.
3
+ * Handles auto-promotion of high-confidence observations to semantic memory.
4
+ * @module promotion
5
+ */
6
+ import type { Observation, TypedEventEmitter } from "./events.js";
7
+ import type { SemanticMemory } from "./semantic.js";
8
+ import type { Opinion } from "./types.js";
9
+ /** Default confidence threshold for auto-promotion */
10
+ export declare const DEFAULT_PROMOTION_THRESHOLD = 0.9;
11
+ /** Options for the PromotionManager */
12
+ export interface PromotionOptions {
13
+ /** Confidence threshold for auto-promotion (default: 0.9) */
14
+ threshold?: number;
15
+ /** Whether to deduplicate similar observations (default: true) */
16
+ deduplicate?: boolean;
17
+ /** Similarity threshold for deduplication (0-1, default: 0.8) */
18
+ similarityThreshold?: number;
19
+ }
20
+ /** Result of a promotion attempt */
21
+ export interface PromotionResult {
22
+ /** Whether the observation was promoted */
23
+ promoted: boolean;
24
+ /** Reason if not promoted */
25
+ reason?: "below_threshold" | "duplicate" | "error";
26
+ /** Error message if promotion failed */
27
+ error?: string;
28
+ }
29
+ /**
30
+ * Manages observation promotion to semantic memory.
31
+ *
32
+ * Listens for opinion:formed events and auto-promotes observations
33
+ * that meet the confidence threshold.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const manager = new PromotionManager(semanticMemory, mind, {
38
+ * threshold: 0.9
39
+ * });
40
+ *
41
+ * // Manager automatically listens to mind events
42
+ * // Or promote manually:
43
+ * await manager.promote({
44
+ * text: "Auth changes need nav updates",
45
+ * confidence: 0.95,
46
+ * source: "reflect"
47
+ * });
48
+ * ```
49
+ */
50
+ export declare class PromotionManager {
51
+ private readonly semantic;
52
+ private readonly emitter;
53
+ private readonly options;
54
+ /** Track promoted texts to prevent duplicates within session */
55
+ private promotedTexts;
56
+ /** Bound handler for cleanup */
57
+ private boundHandleOpinion;
58
+ constructor(semantic: SemanticMemory, emitter: TypedEventEmitter, options?: PromotionOptions);
59
+ /**
60
+ * Start listening for opinion events and auto-promote.
61
+ *
62
+ * Call this after Mind initialization to enable auto-promotion.
63
+ */
64
+ startListening(): void;
65
+ /**
66
+ * Stop listening for opinion events.
67
+ */
68
+ stopListening(): void;
69
+ /**
70
+ * Manually promote an observation.
71
+ *
72
+ * @param observation - Observation to promote
73
+ * @returns Result of promotion attempt
74
+ */
75
+ promote(observation: Observation): Promise<PromotionResult>;
76
+ /**
77
+ * Get the current promotion threshold.
78
+ */
79
+ getThreshold(): number;
80
+ /**
81
+ * Handle an opinion event and potentially promote it.
82
+ * @internal
83
+ */
84
+ private handleOpinion;
85
+ /**
86
+ * Normalize text for comparison.
87
+ * @internal
88
+ */
89
+ private normalizeText;
90
+ /**
91
+ * Check if text is similar to existing content.
92
+ * Uses simple word overlap for efficiency.
93
+ * @internal
94
+ */
95
+ private isSimilar;
96
+ /**
97
+ * Clear the session's promoted texts cache.
98
+ * Call this at session end if needed.
99
+ */
100
+ clearCache(): void;
101
+ }
102
+ /**
103
+ * Create an Observation from an Opinion.
104
+ *
105
+ * Convenience function for converting between types.
106
+ */
107
+ export declare function opinionToObservation(opinion: Opinion, source?: string): Observation;
108
+ /**
109
+ * Check if an opinion meets the promotion threshold.
110
+ */
111
+ export declare function shouldPromote(opinion: Opinion, threshold?: number): boolean;
112
+ //# sourceMappingURL=promotion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion.d.ts","sourceRoot":"","sources":["../src/promotion.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAM1C,sDAAsD;AACtD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAM/C,uCAAuC;AACvC,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iEAAiE;IACjE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,GAAG,OAAO,CAAC;IACnD,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IAErD,gEAAgE;IAChE,OAAO,CAAC,aAAa,CAA0B;IAE/C,gCAAgC;IAChC,OAAO,CAAC,kBAAkB,CAAsC;gBAG9D,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,gBAAqB;IAchC;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAItB;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;;;;OAKG;IACG,OAAO,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAmDjE;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;;OAGG;YACW,aAAa;IAU3B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAmBjB;;;OAGG;IACH,UAAU,IAAI,IAAI;CAGnB;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,MAAM,GAAE,MAAkB,GACzB,WAAW,CAMb;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,SAAS,GAAE,MAAoC,GAC9C,OAAO,CAET"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Observation promotion logic for claude-cognitive.
3
+ * Handles auto-promotion of high-confidence observations to semantic memory.
4
+ * @module promotion
5
+ */
6
+ // ============================================
7
+ // Constants
8
+ // ============================================
9
+ /** Default confidence threshold for auto-promotion */
10
+ export const DEFAULT_PROMOTION_THRESHOLD = 0.9;
11
+ // ============================================
12
+ // PromotionManager Class
13
+ // ============================================
14
+ /**
15
+ * Manages observation promotion to semantic memory.
16
+ *
17
+ * Listens for opinion:formed events and auto-promotes observations
18
+ * that meet the confidence threshold.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const manager = new PromotionManager(semanticMemory, mind, {
23
+ * threshold: 0.9
24
+ * });
25
+ *
26
+ * // Manager automatically listens to mind events
27
+ * // Or promote manually:
28
+ * await manager.promote({
29
+ * text: "Auth changes need nav updates",
30
+ * confidence: 0.95,
31
+ * source: "reflect"
32
+ * });
33
+ * ```
34
+ */
35
+ export class PromotionManager {
36
+ semantic;
37
+ emitter;
38
+ options;
39
+ /** Track promoted texts to prevent duplicates within session */
40
+ promotedTexts = new Set();
41
+ /** Bound handler for cleanup */
42
+ boundHandleOpinion;
43
+ constructor(semantic, emitter, options = {}) {
44
+ this.semantic = semantic;
45
+ this.emitter = emitter;
46
+ this.options = {
47
+ threshold: options.threshold ?? DEFAULT_PROMOTION_THRESHOLD,
48
+ deduplicate: options.deduplicate ?? true,
49
+ similarityThreshold: options.similarityThreshold ?? 0.8,
50
+ };
51
+ // Bind handler once for proper removal
52
+ this.boundHandleOpinion = this.handleOpinion.bind(this);
53
+ }
54
+ /**
55
+ * Start listening for opinion events and auto-promote.
56
+ *
57
+ * Call this after Mind initialization to enable auto-promotion.
58
+ */
59
+ startListening() {
60
+ this.emitter.on("opinion:formed", this.boundHandleOpinion);
61
+ }
62
+ /**
63
+ * Stop listening for opinion events.
64
+ */
65
+ stopListening() {
66
+ this.emitter.off("opinion:formed", this.boundHandleOpinion);
67
+ }
68
+ /**
69
+ * Manually promote an observation.
70
+ *
71
+ * @param observation - Observation to promote
72
+ * @returns Result of promotion attempt
73
+ */
74
+ async promote(observation) {
75
+ // Check threshold
76
+ if (observation.confidence < this.options.threshold) {
77
+ return {
78
+ promoted: false,
79
+ reason: "below_threshold",
80
+ };
81
+ }
82
+ // Check for duplicates
83
+ if (this.options.deduplicate) {
84
+ const normalized = this.normalizeText(observation.text);
85
+ if (this.promotedTexts.has(normalized)) {
86
+ return {
87
+ promoted: false,
88
+ reason: "duplicate",
89
+ };
90
+ }
91
+ // Check existing observations in semantic memory
92
+ if (this.semantic.isLoaded()) {
93
+ const existing = this.semantic.get("Observations") ?? "";
94
+ if (this.isSimilar(observation.text, existing)) {
95
+ return {
96
+ promoted: false,
97
+ reason: "duplicate",
98
+ };
99
+ }
100
+ }
101
+ }
102
+ // Perform promotion
103
+ try {
104
+ await this.semantic.promoteObservation(observation);
105
+ this.promotedTexts.add(this.normalizeText(observation.text));
106
+ // Emit event
107
+ this.emitter.emit("observation:promoted", observation);
108
+ return { promoted: true };
109
+ }
110
+ catch (error) {
111
+ const msg = error instanceof Error ? error.message : String(error);
112
+ return {
113
+ promoted: false,
114
+ reason: "error",
115
+ error: msg,
116
+ };
117
+ }
118
+ }
119
+ /**
120
+ * Get the current promotion threshold.
121
+ */
122
+ getThreshold() {
123
+ return this.options.threshold;
124
+ }
125
+ /**
126
+ * Handle an opinion event and potentially promote it.
127
+ * @internal
128
+ */
129
+ async handleOpinion(opinion) {
130
+ const observation = {
131
+ text: opinion.opinion,
132
+ confidence: opinion.confidence,
133
+ source: "reflect",
134
+ };
135
+ await this.promote(observation);
136
+ }
137
+ /**
138
+ * Normalize text for comparison.
139
+ * @internal
140
+ */
141
+ normalizeText(text) {
142
+ return text
143
+ .toLowerCase()
144
+ .replace(/[^\w\s]/g, "")
145
+ .replace(/\s+/g, " ")
146
+ .trim();
147
+ }
148
+ /**
149
+ * Check if text is similar to existing content.
150
+ * Uses simple word overlap for efficiency.
151
+ * @internal
152
+ */
153
+ isSimilar(newText, existingContent) {
154
+ const newWords = new Set(this.normalizeText(newText).split(" "));
155
+ const existingWords = new Set(this.normalizeText(existingContent).split(" "));
156
+ if (newWords.size === 0)
157
+ return false;
158
+ let overlap = 0;
159
+ for (const word of newWords) {
160
+ if (existingWords.has(word)) {
161
+ overlap++;
162
+ }
163
+ }
164
+ const similarity = overlap / newWords.size;
165
+ return similarity >= this.options.similarityThreshold;
166
+ }
167
+ /**
168
+ * Clear the session's promoted texts cache.
169
+ * Call this at session end if needed.
170
+ */
171
+ clearCache() {
172
+ this.promotedTexts.clear();
173
+ }
174
+ }
175
+ // ============================================
176
+ // Utility Functions
177
+ // ============================================
178
+ /**
179
+ * Create an Observation from an Opinion.
180
+ *
181
+ * Convenience function for converting between types.
182
+ */
183
+ export function opinionToObservation(opinion, source = "reflect") {
184
+ return {
185
+ text: opinion.opinion,
186
+ confidence: opinion.confidence,
187
+ source,
188
+ };
189
+ }
190
+ /**
191
+ * Check if an opinion meets the promotion threshold.
192
+ */
193
+ export function shouldPromote(opinion, threshold = DEFAULT_PROMOTION_THRESHOLD) {
194
+ return opinion.confidence >= threshold;
195
+ }
196
+ //# sourceMappingURL=promotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotion.js","sourceRoot":"","sources":["../src/promotion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Retry logic with exponential backoff for claude-cognitive.
3
+ * @module retry
4
+ */
5
+ /**
6
+ * Options for retry behavior.
7
+ */
8
+ export interface RetryOptions {
9
+ /** Maximum number of retry attempts (default: 3) */
10
+ maxAttempts: number;
11
+ /** Initial delay in milliseconds (default: 100) */
12
+ initialDelayMs: number;
13
+ /** Maximum delay in milliseconds (default: 5000) */
14
+ maxDelayMs: number;
15
+ /** Exponential backoff multiplier (default: 2) */
16
+ backoffMultiplier: number;
17
+ /** Add random jitter to prevent thundering herd (default: true) */
18
+ jitter: boolean;
19
+ /**
20
+ * Custom function to determine if error is retryable.
21
+ * If not provided, uses HindsightError.isRetryable or defaults to false.
22
+ */
23
+ shouldRetry?: (error: Error, attempt: number) => boolean;
24
+ /**
25
+ * Callback invoked before each retry attempt.
26
+ * Useful for logging or metrics.
27
+ */
28
+ onRetry?: (error: Error, attempt: number, delayMs: number) => void;
29
+ }
30
+ /**
31
+ * Execute a function with retry logic and exponential backoff.
32
+ *
33
+ * Retries are attempted when:
34
+ * 1. The error has `isRetryable: true` (for HindsightError)
35
+ * 2. The custom `shouldRetry` function returns true
36
+ * 3. The error is a TimeoutError
37
+ *
38
+ * @param fn - The async function to execute
39
+ * @param options - Retry configuration options
40
+ * @returns The result of the function
41
+ * @throws The last error if all retries are exhausted
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const result = await withRetry(
46
+ * () => client.recall(bankId, query),
47
+ * { maxAttempts: 3 }
48
+ * );
49
+ * ```
50
+ */
51
+ export declare function withRetry<T>(fn: () => Promise<T>, options?: Partial<RetryOptions>): Promise<T>;
52
+ /**
53
+ * Create a retryable version of an async function.
54
+ *
55
+ * @param fn - The async function to wrap
56
+ * @param options - Retry configuration options
57
+ * @returns A wrapped function that automatically retries on failure
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const retryableRecall = createRetryable(
62
+ * (query: string) => client.recall(bankId, query),
63
+ * { maxAttempts: 3 }
64
+ * );
65
+ *
66
+ * const result = await retryableRecall('authentication flow');
67
+ * ```
68
+ */
69
+ export declare function createRetryable<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, options?: Partial<RetryOptions>): (...args: TArgs) => Promise<TResult>;
70
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACzD;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpE;AA0DD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,OAAO,CAAC,YAAY,CAAM,GAClC,OAAO,CAAC,CAAC,CAAC,CAkCZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EAC9D,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,EACxC,OAAO,GAAE,OAAO,CAAC,YAAY,CAAM,GAClC,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAEtC"}
package/dist/retry.js ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Retry logic with exponential backoff for claude-cognitive.
3
+ * @module retry
4
+ */
5
+ import { HindsightError } from "./errors.js";
6
+ const DEFAULT_RETRY_OPTIONS = {
7
+ maxAttempts: 3,
8
+ initialDelayMs: 100,
9
+ maxDelayMs: 5000,
10
+ backoffMultiplier: 2,
11
+ jitter: true,
12
+ };
13
+ /**
14
+ * Sleep for a given number of milliseconds.
15
+ * @internal
16
+ */
17
+ function sleep(ms) {
18
+ return new Promise((resolve) => setTimeout(resolve, ms));
19
+ }
20
+ /**
21
+ * Check if an error is retryable using default logic.
22
+ * @internal
23
+ */
24
+ function isDefaultRetryable(error) {
25
+ // Check for HindsightError.isRetryable
26
+ if (HindsightError.isHindsightError(error)) {
27
+ return error.isRetryable;
28
+ }
29
+ // Retry on timeout errors
30
+ if (error.name === "TimeoutError") {
31
+ return true;
32
+ }
33
+ // Don't retry unknown errors by default
34
+ return false;
35
+ }
36
+ /**
37
+ * Calculate delay for a given attempt with exponential backoff.
38
+ * @internal
39
+ */
40
+ function calculateDelay(attempt, opts) {
41
+ // Exponential: initialDelay * multiplier^(attempt-1)
42
+ const exponentialDelay = opts.initialDelayMs * Math.pow(opts.backoffMultiplier, attempt - 1);
43
+ // Cap at maxDelay
44
+ const cappedDelay = Math.min(exponentialDelay, opts.maxDelayMs);
45
+ // Add jitter (0-50% of delay) to prevent thundering herd
46
+ if (opts.jitter) {
47
+ const jitterRange = cappedDelay * 0.5;
48
+ return Math.floor(cappedDelay + Math.random() * jitterRange);
49
+ }
50
+ return cappedDelay;
51
+ }
52
+ /**
53
+ * Execute a function with retry logic and exponential backoff.
54
+ *
55
+ * Retries are attempted when:
56
+ * 1. The error has `isRetryable: true` (for HindsightError)
57
+ * 2. The custom `shouldRetry` function returns true
58
+ * 3. The error is a TimeoutError
59
+ *
60
+ * @param fn - The async function to execute
61
+ * @param options - Retry configuration options
62
+ * @returns The result of the function
63
+ * @throws The last error if all retries are exhausted
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const result = await withRetry(
68
+ * () => client.recall(bankId, query),
69
+ * { maxAttempts: 3 }
70
+ * );
71
+ * ```
72
+ */
73
+ export async function withRetry(fn, options = {}) {
74
+ const opts = { ...DEFAULT_RETRY_OPTIONS, ...options };
75
+ let lastError;
76
+ for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
77
+ try {
78
+ return await fn();
79
+ }
80
+ catch (error) {
81
+ lastError = error instanceof Error ? error : new Error(String(error));
82
+ // Check if we should retry
83
+ const isRetryable = opts.shouldRetry
84
+ ? opts.shouldRetry(lastError, attempt)
85
+ : isDefaultRetryable(lastError);
86
+ // If not retryable or last attempt, throw immediately
87
+ if (!isRetryable || attempt === opts.maxAttempts) {
88
+ throw lastError;
89
+ }
90
+ // Calculate delay with exponential backoff
91
+ const delay = calculateDelay(attempt, opts);
92
+ // Invoke onRetry callback if provided
93
+ if (opts.onRetry) {
94
+ opts.onRetry(lastError, attempt, delay);
95
+ }
96
+ await sleep(delay);
97
+ }
98
+ }
99
+ // Should never reach here, but TypeScript needs this
100
+ throw lastError ?? new Error("Retry failed");
101
+ }
102
+ /**
103
+ * Create a retryable version of an async function.
104
+ *
105
+ * @param fn - The async function to wrap
106
+ * @param options - Retry configuration options
107
+ * @returns A wrapped function that automatically retries on failure
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const retryableRecall = createRetryable(
112
+ * (query: string) => client.recall(bankId, query),
113
+ * { maxAttempts: 3 }
114
+ * );
115
+ *
116
+ * const result = await retryableRecall('authentication flow');
117
+ * ```
118
+ */
119
+ export function createRetryable(fn, options = {}) {
120
+ return (...args) => withRetry(() => fn(...args), options);
121
+ }
122
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}