@noorm/marie-cli 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 (193) hide show
  1. package/JOY_ZONING.md +200 -0
  2. package/LICENSE.md +190 -0
  3. package/README.md +94 -0
  4. package/dist/cli-new/components/App.js +138 -0
  5. package/dist/cli-new/components/App.js.map +1 -0
  6. package/dist/cli-new/components/ApprovalDialog.js +31 -0
  7. package/dist/cli-new/components/ApprovalDialog.js.map +1 -0
  8. package/dist/cli-new/components/Banner.js +23 -0
  9. package/dist/cli-new/components/Banner.js.map +1 -0
  10. package/dist/cli-new/components/ChatArea.js +49 -0
  11. package/dist/cli-new/components/ChatArea.js.map +1 -0
  12. package/dist/cli-new/components/Header.js +20 -0
  13. package/dist/cli-new/components/Header.js.map +1 -0
  14. package/dist/cli-new/components/InputArea.js +97 -0
  15. package/dist/cli-new/components/InputArea.js.map +1 -0
  16. package/dist/cli-new/components/MessageBubble.js +114 -0
  17. package/dist/cli-new/components/MessageBubble.js.map +1 -0
  18. package/dist/cli-new/components/SessionSwitcher.js +46 -0
  19. package/dist/cli-new/components/SessionSwitcher.js.map +1 -0
  20. package/dist/cli-new/components/SetupWizard.js +283 -0
  21. package/dist/cli-new/components/SetupWizard.js.map +1 -0
  22. package/dist/cli-new/components/ToolCallDisplay.js +45 -0
  23. package/dist/cli-new/components/ToolCallDisplay.js.map +1 -0
  24. package/dist/cli-new/hooks/useGit.js +99 -0
  25. package/dist/cli-new/hooks/useGit.js.map +1 -0
  26. package/dist/cli-new/hooks/useMarie.js +249 -0
  27. package/dist/cli-new/hooks/useMarie.js.map +1 -0
  28. package/dist/cli-new/hooks/useSessions.js +75 -0
  29. package/dist/cli-new/hooks/useSessions.js.map +1 -0
  30. package/dist/cli-new/index.js +52 -0
  31. package/dist/cli-new/index.js.map +1 -0
  32. package/dist/cli-new/styles/theme.js +68 -0
  33. package/dist/cli-new/styles/theme.js.map +1 -0
  34. package/dist/cli-new/types/cli.js +2 -0
  35. package/dist/cli-new/types/cli.js.map +1 -0
  36. package/dist/extension.cjs +655 -0
  37. package/dist/monolith/adapters/CliMarieAdapter.js +72 -0
  38. package/dist/monolith/adapters/CliMarieAdapter.js.map +1 -0
  39. package/dist/monolith/adapters/VscodeMarieAdapter.js +81 -0
  40. package/dist/monolith/adapters/VscodeMarieAdapter.js.map +1 -0
  41. package/dist/monolith/cli/CliFileSystemPort.js +83 -0
  42. package/dist/monolith/cli/CliFileSystemPort.js.map +1 -0
  43. package/dist/monolith/cli/MarieToolDefinitionsCLI.js +438 -0
  44. package/dist/monolith/cli/MarieToolDefinitionsCLI.js.map +1 -0
  45. package/dist/monolith/cli/index.js +272 -0
  46. package/dist/monolith/cli/index.js.map +1 -0
  47. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js +80 -0
  48. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js.map +1 -0
  49. package/dist/monolith/cli/services/JoyServiceCLI.js +63 -0
  50. package/dist/monolith/cli/services/JoyServiceCLI.js.map +1 -0
  51. package/dist/monolith/cli/storage.js +119 -0
  52. package/dist/monolith/cli/storage.js.map +1 -0
  53. package/dist/monolith/domain/joy/JoyTools.js +513 -0
  54. package/dist/monolith/domain/joy/JoyTools.js.map +1 -0
  55. package/dist/monolith/domain/joy/RitualService.js +51 -0
  56. package/dist/monolith/domain/joy/RitualService.js.map +1 -0
  57. package/dist/monolith/domain/marie/MarieTypes.js +2 -0
  58. package/dist/monolith/domain/marie/MarieTypes.js.map +1 -0
  59. package/dist/monolith/infrastructure/ai/agents/MarieAscendant.js +230 -0
  60. package/dist/monolith/infrastructure/ai/agents/MarieAscendant.js.map +1 -0
  61. package/dist/monolith/infrastructure/ai/agents/MarieYOLO.js +207 -0
  62. package/dist/monolith/infrastructure/ai/agents/MarieYOLO.js.map +1 -0
  63. package/dist/monolith/infrastructure/ai/context/ContextArchiveService.js +129 -0
  64. package/dist/monolith/infrastructure/ai/context/ContextArchiveService.js.map +1 -0
  65. package/dist/monolith/infrastructure/ai/context/ContextManager.js +118 -0
  66. package/dist/monolith/infrastructure/ai/context/ContextManager.js.map +1 -0
  67. package/dist/monolith/infrastructure/ai/core/FileSystemPort.js +2 -0
  68. package/dist/monolith/infrastructure/ai/core/FileSystemPort.js.map +1 -0
  69. package/dist/monolith/infrastructure/ai/core/GhostPort.js +2 -0
  70. package/dist/monolith/infrastructure/ai/core/GhostPort.js.map +1 -0
  71. package/dist/monolith/infrastructure/ai/core/MarieAscensionTypes.js +2 -0
  72. package/dist/monolith/infrastructure/ai/core/MarieAscensionTypes.js.map +1 -0
  73. package/dist/monolith/infrastructure/ai/core/MarieEngine.js +590 -0
  74. package/dist/monolith/infrastructure/ai/core/MarieEngine.js.map +1 -0
  75. package/dist/monolith/infrastructure/ai/core/MarieEventDispatcher.js +161 -0
  76. package/dist/monolith/infrastructure/ai/core/MarieEventDispatcher.js.map +1 -0
  77. package/dist/monolith/infrastructure/ai/core/MarieLockManager.js +121 -0
  78. package/dist/monolith/infrastructure/ai/core/MarieLockManager.js.map +1 -0
  79. package/dist/monolith/infrastructure/ai/core/MarieProgressTracker.js +256 -0
  80. package/dist/monolith/infrastructure/ai/core/MarieProgressTracker.js.map +1 -0
  81. package/dist/monolith/infrastructure/ai/core/MariePulseService.js +67 -0
  82. package/dist/monolith/infrastructure/ai/core/MariePulseService.js.map +1 -0
  83. package/dist/monolith/infrastructure/ai/core/MarieResponse.js +101 -0
  84. package/dist/monolith/infrastructure/ai/core/MarieResponse.js.map +1 -0
  85. package/dist/monolith/infrastructure/ai/core/MarieSanitizer.js +86 -0
  86. package/dist/monolith/infrastructure/ai/core/MarieSanitizer.js.map +1 -0
  87. package/dist/monolith/infrastructure/ai/core/MarieSession.js +202 -0
  88. package/dist/monolith/infrastructure/ai/core/MarieSession.js.map +1 -0
  89. package/dist/monolith/infrastructure/ai/core/MarieStabilityMonitor.js +58 -0
  90. package/dist/monolith/infrastructure/ai/core/MarieStabilityMonitor.js.map +1 -0
  91. package/dist/monolith/infrastructure/ai/core/MarieToolMender.js +127 -0
  92. package/dist/monolith/infrastructure/ai/core/MarieToolMender.js.map +1 -0
  93. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js +548 -0
  94. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js.map +1 -0
  95. package/dist/monolith/infrastructure/ai/core/MarieYOLOTypes.js +2 -0
  96. package/dist/monolith/infrastructure/ai/core/MarieYOLOTypes.js.map +1 -0
  97. package/dist/monolith/infrastructure/ai/core/ReasoningBudget.js +125 -0
  98. package/dist/monolith/infrastructure/ai/core/ReasoningBudget.js.map +1 -0
  99. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js +30 -0
  100. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js.map +1 -0
  101. package/dist/monolith/infrastructure/ai/providers/AIProvider.js +2 -0
  102. package/dist/monolith/infrastructure/ai/providers/AIProvider.js.map +1 -0
  103. package/dist/monolith/infrastructure/ai/providers/AnthropicProvider.js +148 -0
  104. package/dist/monolith/infrastructure/ai/providers/AnthropicProvider.js.map +1 -0
  105. package/dist/monolith/infrastructure/ai/providers/CerebrasProvider.js +208 -0
  106. package/dist/monolith/infrastructure/ai/providers/CerebrasProvider.js.map +1 -0
  107. package/dist/monolith/infrastructure/ai/providers/OpenRouterProvider.js +404 -0
  108. package/dist/monolith/infrastructure/ai/providers/OpenRouterProvider.js.map +1 -0
  109. package/dist/monolith/infrastructure/ai/providers/OpenRouterStreamParser.js +283 -0
  110. package/dist/monolith/infrastructure/ai/providers/OpenRouterStreamParser.js.map +1 -0
  111. package/dist/monolith/infrastructure/config/ConfigService.js +398 -0
  112. package/dist/monolith/infrastructure/config/ConfigService.js.map +1 -0
  113. package/dist/monolith/infrastructure/services/MarieMemoryStore.js +140 -0
  114. package/dist/monolith/infrastructure/services/MarieMemoryStore.js.map +1 -0
  115. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js +1568 -0
  116. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js.map +1 -0
  117. package/dist/monolith/infrastructure/tools/PureStreamParser.js +147 -0
  118. package/dist/monolith/infrastructure/tools/PureStreamParser.js.map +1 -0
  119. package/dist/monolith/infrastructure/tools/SharedToolDefinitions.js +223 -0
  120. package/dist/monolith/infrastructure/tools/SharedToolDefinitions.js.map +1 -0
  121. package/dist/monolith/infrastructure/tools/ToolRegistry.js +29 -0
  122. package/dist/monolith/infrastructure/tools/ToolRegistry.js.map +1 -0
  123. package/dist/monolith/infrastructure/tools/ToolUtils.js +59 -0
  124. package/dist/monolith/infrastructure/tools/ToolUtils.js.map +1 -0
  125. package/dist/monolith/plumbing/analysis/CodeHealthService.js +146 -0
  126. package/dist/monolith/plumbing/analysis/CodeHealthService.js.map +1 -0
  127. package/dist/monolith/plumbing/analysis/ComplexityService.js +43 -0
  128. package/dist/monolith/plumbing/analysis/ComplexityService.js.map +1 -0
  129. package/dist/monolith/plumbing/analysis/DependencyService.js +51 -0
  130. package/dist/monolith/plumbing/analysis/DependencyService.js.map +1 -0
  131. package/dist/monolith/plumbing/analysis/DiscoveryService.js +49 -0
  132. package/dist/monolith/plumbing/analysis/DiscoveryService.js.map +1 -0
  133. package/dist/monolith/plumbing/analysis/JoyMapService.js +66 -0
  134. package/dist/monolith/plumbing/analysis/JoyMapService.js.map +1 -0
  135. package/dist/monolith/plumbing/analysis/LintService.js +132 -0
  136. package/dist/monolith/plumbing/analysis/LintService.js.map +1 -0
  137. package/dist/monolith/plumbing/analysis/MarieSentinelService.js +276 -0
  138. package/dist/monolith/plumbing/analysis/MarieSentinelService.js.map +1 -0
  139. package/dist/monolith/plumbing/analysis/QualityGuardrailService.js +119 -0
  140. package/dist/monolith/plumbing/analysis/QualityGuardrailService.js.map +1 -0
  141. package/dist/monolith/plumbing/analysis/SurgicalMender.js +70 -0
  142. package/dist/monolith/plumbing/analysis/SurgicalMender.js.map +1 -0
  143. package/dist/monolith/plumbing/analysis/TestService.js +104 -0
  144. package/dist/monolith/plumbing/analysis/TestService.js.map +1 -0
  145. package/dist/monolith/plumbing/filesystem/FileService.js +406 -0
  146. package/dist/monolith/plumbing/filesystem/FileService.js.map +1 -0
  147. package/dist/monolith/plumbing/filesystem/PathResolver.js +26 -0
  148. package/dist/monolith/plumbing/filesystem/PathResolver.js.map +1 -0
  149. package/dist/monolith/plumbing/git/GitService.js +71 -0
  150. package/dist/monolith/plumbing/git/GitService.js.map +1 -0
  151. package/dist/monolith/plumbing/lsp/SymbolService.js +36 -0
  152. package/dist/monolith/plumbing/lsp/SymbolService.js.map +1 -0
  153. package/dist/monolith/plumbing/terminal/ProcessRegistry.js +31 -0
  154. package/dist/monolith/plumbing/terminal/ProcessRegistry.js.map +1 -0
  155. package/dist/monolith/plumbing/terminal/TerminalService.js +180 -0
  156. package/dist/monolith/plumbing/terminal/TerminalService.js.map +1 -0
  157. package/dist/monolith/plumbing/ui/DecorationService.js +54 -0
  158. package/dist/monolith/plumbing/ui/DecorationService.js.map +1 -0
  159. package/dist/monolith/plumbing/utils/ErrorUtils.js +11 -0
  160. package/dist/monolith/plumbing/utils/ErrorUtils.js.map +1 -0
  161. package/dist/monolith/plumbing/utils/JsonUtils.js +360 -0
  162. package/dist/monolith/plumbing/utils/JsonUtils.js.map +1 -0
  163. package/dist/monolith/plumbing/utils/PrefixTree.js +153 -0
  164. package/dist/monolith/plumbing/utils/PrefixTree.js.map +1 -0
  165. package/dist/monolith/plumbing/utils/RetryUtils.js +141 -0
  166. package/dist/monolith/plumbing/utils/RetryUtils.js.map +1 -0
  167. package/dist/monolith/plumbing/utils/StreamTagDetector.js +128 -0
  168. package/dist/monolith/plumbing/utils/StreamTagDetector.js.map +1 -0
  169. package/dist/monolith/plumbing/utils/StringUtils.js +97 -0
  170. package/dist/monolith/plumbing/utils/StringUtils.js.map +1 -0
  171. package/dist/monolith/plumbing/utils/TimeoutUtils.js +21 -0
  172. package/dist/monolith/plumbing/utils/TimeoutUtils.js.map +1 -0
  173. package/dist/monolith/runtime/MarieRuntime.js +354 -0
  174. package/dist/monolith/runtime/MarieRuntime.js.map +1 -0
  175. package/dist/monolith/runtime/RuntimeAdapterBase.js +59 -0
  176. package/dist/monolith/runtime/RuntimeAdapterBase.js.map +1 -0
  177. package/dist/monolith/runtime/providerFactory.js +11 -0
  178. package/dist/monolith/runtime/providerFactory.js.map +1 -0
  179. package/dist/monolith/runtime/types.js +2 -0
  180. package/dist/monolith/runtime/types.js.map +1 -0
  181. package/dist/monolith/services/HealthService.js +38 -0
  182. package/dist/monolith/services/HealthService.js.map +1 -0
  183. package/dist/monolith/services/JoyAutomationService.js +131 -0
  184. package/dist/monolith/services/JoyAutomationService.js.map +1 -0
  185. package/dist/monolith/services/JoyLogService.js +48 -0
  186. package/dist/monolith/services/JoyLogService.js.map +1 -0
  187. package/dist/monolith/services/JoyService.js +190 -0
  188. package/dist/monolith/services/JoyService.js.map +1 -0
  189. package/dist/monolith/services/MarieGhostService.js +168 -0
  190. package/dist/monolith/services/MarieGhostService.js.map +1 -0
  191. package/dist/monolith/services/MarieSCMProvider.js +41 -0
  192. package/dist/monolith/services/MarieSCMProvider.js.map +1 -0
  193. package/package.json +168 -0
@@ -0,0 +1,153 @@
1
+ import { StringUtils } from "./StringUtils.js";
2
+ /**
3
+ * Prefix Tree (Trie) for efficient tag detection.
4
+ * Provides O(k) complexity for finding tags where k = input length.
5
+ */
6
+ export class PrefixTree {
7
+ root = { children: new Map(), isEndOfTag: false };
8
+ tags = [];
9
+ constructor(tags) {
10
+ this.tags = tags;
11
+ for (const tag of tags) {
12
+ this.insert(tag);
13
+ }
14
+ }
15
+ /**
16
+ * Insert a tag into the trie.
17
+ */
18
+ insert(tag) {
19
+ let node = this.root;
20
+ for (const char of tag) {
21
+ if (!node.children.has(char)) {
22
+ node.children.set(char, { children: new Map(), isEndOfTag: false });
23
+ }
24
+ node = node.children.get(char);
25
+ }
26
+ node.isEndOfTag = true;
27
+ node.tag = tag;
28
+ }
29
+ /**
30
+ * Find the earliest complete tag in the text.
31
+ * Returns { index: number, tag: string } if found, null otherwise.
32
+ * Optimized with early-exit for O(k) performance.
33
+ */
34
+ findEarliestTag(text) {
35
+ let earliestIndex = Infinity;
36
+ let earliestTag = "";
37
+ // Try to match from each position in the text (with early-exit)
38
+ for (let startIdx = 0; startIdx < text.length; startIdx++) {
39
+ // Early-exit: if we already found a tag at an earlier position, stop
40
+ if (startIdx >= earliestIndex) {
41
+ break;
42
+ }
43
+ const result = this.matchFromPosition(text, startIdx);
44
+ if (result && result.index < earliestIndex) {
45
+ earliestIndex = result.index;
46
+ earliestTag = result.tag;
47
+ }
48
+ }
49
+ return earliestTag ? { index: earliestIndex, tag: earliestTag } : null;
50
+ }
51
+ /**
52
+ * Match a tag starting from a specific position.
53
+ * Returns the SHORTEST matching tag (to handle prefix overlaps correctly).
54
+ */
55
+ matchFromPosition(text, startIdx) {
56
+ let node = this.root;
57
+ let firstMatch = null;
58
+ for (let i = startIdx; i < text.length; i++) {
59
+ const char = text[i];
60
+ if (!node.children.has(char)) {
61
+ // Can't continue matching
62
+ break;
63
+ }
64
+ node = node.children.get(char);
65
+ if (node.isEndOfTag && !firstMatch) {
66
+ // Found first complete tag at this position
67
+ firstMatch = node.tag;
68
+ // Return immediately to get the shortest match
69
+ return { index: startIdx, tag: firstMatch };
70
+ }
71
+ }
72
+ return null;
73
+ }
74
+ /**
75
+ * Find the longest partial tag at the end of the text.
76
+ * Returns the length of the partial match (0 if none).
77
+ */
78
+ findLongestPartialAtEnd(text) {
79
+ let maxPartialLength = 0;
80
+ // Try matching from each position toward the end
81
+ for (let startIdx = 0; startIdx < text.length; startIdx++) {
82
+ const partialLength = this.matchPartialFromPosition(text, startIdx);
83
+ if (partialLength > 0 && startIdx + partialLength === text.length) {
84
+ maxPartialLength = Math.max(maxPartialLength, partialLength);
85
+ }
86
+ }
87
+ return maxPartialLength;
88
+ }
89
+ /**
90
+ * Match a partial tag from a position, returns length of match.
91
+ */
92
+ matchPartialFromPosition(text, startIdx) {
93
+ let node = this.root;
94
+ let matchLength = 0;
95
+ for (let i = startIdx; i < text.length; i++) {
96
+ const char = text[i];
97
+ if (!node.children.has(char)) {
98
+ return matchLength;
99
+ }
100
+ node = node.children.get(char);
101
+ matchLength++;
102
+ if (node.isEndOfTag) {
103
+ // This is a complete tag, not a partial
104
+ return 0;
105
+ }
106
+ }
107
+ // We matched up to the end of text without completing a tag
108
+ return matchLength;
109
+ }
110
+ editDistanceCache = new Map();
111
+ static MAX_CACHE_SIZE = 1000;
112
+ /**
113
+ * Find similar tags using edit distance (Levenshtein).
114
+ * Returns tags with edit distance <= maxDistance.
115
+ * Uses caching with eviction for improved performance.
116
+ */
117
+ findSimilarTags(input, maxDistance = 2) {
118
+ const similar = [];
119
+ for (const tag of this.tags) {
120
+ const cacheKey = `${input}:${tag}`;
121
+ let distance = this.editDistanceCache.get(cacheKey);
122
+ if (distance === undefined) {
123
+ distance = this.editDistance(input, tag);
124
+ // Evict oldest half when cache exceeds max size
125
+ if (this.editDistanceCache.size >= PrefixTree.MAX_CACHE_SIZE) {
126
+ const keysToDelete = Array.from(this.editDistanceCache.keys()).slice(0, PrefixTree.MAX_CACHE_SIZE / 2);
127
+ for (const key of keysToDelete) {
128
+ this.editDistanceCache.delete(key);
129
+ }
130
+ }
131
+ this.editDistanceCache.set(cacheKey, distance);
132
+ }
133
+ if (distance <= maxDistance) {
134
+ similar.push(tag);
135
+ }
136
+ }
137
+ return similar;
138
+ }
139
+ /**
140
+ * Calculate Levenshtein edit distance between two strings.
141
+ * Delegates to StringUtils for the optimized 2-row implementation.
142
+ */
143
+ editDistance(a, b) {
144
+ return StringUtils.levenshtein(a, b);
145
+ }
146
+ /**
147
+ * Clear the edit distance cache to free memory.
148
+ */
149
+ clearCache() {
150
+ this.editDistanceCache.clear();
151
+ }
152
+ }
153
+ //# sourceMappingURL=PrefixTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrefixTree.js","sourceRoot":"","sources":["../../../../src/monolith/plumbing/utils/PrefixTree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Error category classification for retry behavior.
3
+ */
4
+ export var ErrorCategory;
5
+ (function (ErrorCategory) {
6
+ ErrorCategory["TRANSIENT"] = "TRANSIENT";
7
+ ErrorCategory["PERMANENT"] = "PERMANENT";
8
+ ErrorCategory["UNKNOWN"] = "UNKNOWN";
9
+ })(ErrorCategory || (ErrorCategory = {}));
10
+ /**
11
+ * Retry configuration and utilities for handling transient errors.
12
+ */
13
+ export class RetryConfig {
14
+ maxRetries = 3;
15
+ baseDelayMs = 100;
16
+ maxDelayMs = 5000;
17
+ // Errors that are definitely retryable (transient)
18
+ transientErrors = [
19
+ "ECONNRESET",
20
+ "ETIMEDOUT",
21
+ "ENOTFOUND",
22
+ "ECONNREFUSED",
23
+ "timeout",
24
+ "throttle",
25
+ "rate limit",
26
+ "too many requests",
27
+ "429",
28
+ "503",
29
+ "504",
30
+ ];
31
+ // Errors that are definitely NOT retryable (permanent)
32
+ permanentErrors = [
33
+ "EACCES",
34
+ "EPERM",
35
+ "permission denied",
36
+ "unauthorized",
37
+ "forbidden",
38
+ "401",
39
+ "403",
40
+ "invalid",
41
+ "validation",
42
+ "not found",
43
+ "404",
44
+ ];
45
+ /**
46
+ * Categorize an error based on its message.
47
+ */
48
+ categorizeError(errorMessage) {
49
+ const lowerMessage = errorMessage.toLowerCase();
50
+ // Check if it's a known transient error
51
+ if (this.transientErrors.some((err) => lowerMessage.includes(err.toLowerCase()))) {
52
+ return ErrorCategory.TRANSIENT;
53
+ }
54
+ // Check if it's a known permanent error
55
+ if (this.permanentErrors.some((err) => lowerMessage.includes(err.toLowerCase()))) {
56
+ return ErrorCategory.PERMANENT;
57
+ }
58
+ return ErrorCategory.UNKNOWN;
59
+ }
60
+ /**
61
+ * Check if an error message indicates a retryable error.
62
+ */
63
+ isRetryable(errorMessage) {
64
+ const category = this.categorizeError(errorMessage);
65
+ // Only retry transient errors, not permanent or unknown
66
+ return category === ErrorCategory.TRANSIENT;
67
+ }
68
+ /**
69
+ * Calculate exponential backoff delay.
70
+ */
71
+ getBackoffDelay(attemptNumber) {
72
+ const delay = this.baseDelayMs * Math.pow(2, attemptNumber);
73
+ // Add jitter (randomness) to prevent thundering herd
74
+ const jitter = Math.random() * 0.3 * delay;
75
+ return Math.min(delay + jitter, this.maxDelayMs);
76
+ }
77
+ }
78
+ /**
79
+ * Execute a function with retry logic, respecting an AbortSignal.
80
+ */
81
+ export async function withRetry(fn, config, context, signal) {
82
+ let lastError = null;
83
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
84
+ if (signal?.aborted) {
85
+ throw new Error(`${context}: Aborted by user.`);
86
+ }
87
+ try {
88
+ return await fn();
89
+ }
90
+ catch (error) {
91
+ lastError = error;
92
+ const errorMessage = error?.message || String(error);
93
+ const category = config.categorizeError(errorMessage);
94
+ // Log error category for debugging
95
+ if (attempt === 0) {
96
+ console.log(`[Marie] ${context}: Error category: ${category}`);
97
+ }
98
+ // Don't retry if error is permanent
99
+ if (category === ErrorCategory.PERMANENT) {
100
+ console.log(`[Marie] ${context}: Permanent error, failing immediately.`);
101
+ throw error;
102
+ }
103
+ // Don't retry if error is unknown (conservative approach)
104
+ if (category === ErrorCategory.UNKNOWN) {
105
+ console.log(`[Marie] ${context}: Unknown error type, failing without retry.`);
106
+ throw error;
107
+ }
108
+ // Don't retry if we've exhausted attempts
109
+ if (attempt >= config.maxRetries) {
110
+ console.error(`[Marie] ${context}: Max retries (${config.maxRetries}) exceeded.`);
111
+ throw error;
112
+ }
113
+ // Calculate backoff and retry (only for TRANSIENT errors)
114
+ const delay = config.getBackoffDelay(attempt);
115
+ console.warn(`[Marie] ${context}: Attempt ${attempt + 1} failed (${category}), retrying in ${Math.round(delay)}ms... Error: ${errorMessage}`);
116
+ await sleep(delay, signal);
117
+ }
118
+ }
119
+ // Should never reach here, but TypeScript needs it
120
+ throw lastError || new Error(`${context}: Retry loop failed unexpectedly`);
121
+ }
122
+ /**
123
+ * Sleep for a specified number of milliseconds, optionally cancellable.
124
+ */
125
+ function sleep(ms, signal) {
126
+ return new Promise((resolve, reject) => {
127
+ const timeout = setTimeout(() => {
128
+ if (signal)
129
+ signal.removeEventListener("abort", abortHandler);
130
+ resolve();
131
+ }, ms);
132
+ const abortHandler = () => {
133
+ clearTimeout(timeout);
134
+ reject(new Error("Operation aborted."));
135
+ };
136
+ if (signal) {
137
+ signal.addEventListener("abort", abortHandler, { once: true });
138
+ }
139
+ });
140
+ }
141
+ //# sourceMappingURL=RetryUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryUtils.js","sourceRoot":"","sources":["../../../../src/monolith/plumbing/utils/RetryUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import { PrefixTree } from "./PrefixTree.js";
2
+ export class StreamTagDetector {
3
+ buffer = "";
4
+ static MAX_BUFFER_SIZE = 100000; // 100k chars safety limit
5
+ // Tags we want to detect.
6
+ // We strictly look for the start of a tool block or the end of one.
7
+ // Also includes Llama 3 variations and control tokens.
8
+ tags = [
9
+ "<|tool_call_begin|>",
10
+ "<|tool_call_end|>",
11
+ "<|tool_calls_section_begin|>", // Section begin marker
12
+ "<|tool_calls_section_end|>", // Section end marker
13
+ "<|tool_call_id|>", // Some models emit tool IDs separately
14
+ "<|tool_call_argument_begin|>",
15
+ "<|tool_call_arguments_begin|>", // Plural variant
16
+ "<tool>",
17
+ "</tool>",
18
+ "<function",
19
+ "</function>",
20
+ "<function_calls>",
21
+ "</function_calls>",
22
+ "<invoke",
23
+ "</invoke>",
24
+ "<thought>",
25
+ "</thought>",
26
+ "<tool_code>",
27
+ "</tool_code>",
28
+ "<tool_call>",
29
+ "</tool_call>",
30
+ "<|eot_id|>", // End of turn marker
31
+ "<|start_header_id|>", // Header start marker
32
+ "<|end_header_id|>", // Header end marker
33
+ ];
34
+ prefixTree;
35
+ constructor() {
36
+ this.prefixTree = new PrefixTree(this.tags);
37
+ }
38
+ /**
39
+ * Processes a chunk of text and returns a status indicating what happened.
40
+ *
41
+ * - 'tag': A full tag was found. The returned `text` is content BEFORE the tag. `tag` is the tag itself.
42
+ * The buffer will contain any remainder AFTER the tag for the next call.
43
+ * - 'incomplete': A partial tag was found at the end. `text` is the safe content before it.
44
+ * The buffer holds the partial tag.
45
+ * - 'content': No tags found. `text` Is the full content. Buffer is empty.
46
+ */
47
+ process(chunk) {
48
+ this.buffer += chunk;
49
+ // --- Buffer Growth Safety ---
50
+ if (this.buffer.length > StreamTagDetector.MAX_BUFFER_SIZE) {
51
+ console.error("[Marie] StreamTagDetector buffer exceeded safety limit. Flushing.");
52
+ const flushed = this.buffer;
53
+ this.buffer = "";
54
+ return { type: "content", text: flushed };
55
+ }
56
+ // 1. Check if we have any FULL tags using prefix tree (O(k) complexity)
57
+ const tagMatch = this.prefixTree.findEarliestTag(this.buffer);
58
+ if (tagMatch) {
59
+ // Found a tag!
60
+ // Emit content up to tag
61
+ const content = this.buffer.substring(0, tagMatch.index);
62
+ // Remove content + tag from buffer, keep remainder
63
+ this.buffer = this.buffer.substring(tagMatch.index + tagMatch.tag.length);
64
+ console.log(`[Marie] Tag detected: ${tagMatch.tag} at index ${tagMatch.index}`);
65
+ return { type: "tag", text: content, tag: tagMatch.tag };
66
+ }
67
+ // 2. Check for dynamic/malformed tags using regex
68
+ const lookbackLength = Math.min(200, this.buffer.length);
69
+ const recentBuffer = this.buffer.substring(this.buffer.length - lookbackLength);
70
+ // IMPORTANT: Keep this strict to avoid treating normal HTML/text tags
71
+ // (e.g. <script>, </button>) as tool tags.
72
+ // We only accept:
73
+ // - LLM control tags like <|tool_call_begin|>
74
+ // - compact call markers like call:0>
75
+ // - bracketed tool markers like [Tool Use: name]
76
+ const dynamicTagPattern = /<\|[\w_]{3,}(?:\|>|>)?|(?:^|[^a-zA-Z0-9_])(call:\d+>)|(?:^|[\s,])(\[Tool (?:Use|Result):[^\]]+\])/g;
77
+ const matches = Array.from(recentBuffer.matchAll(dynamicTagPattern));
78
+ if (matches.length > 0) {
79
+ const lastMatch = matches[matches.length - 1];
80
+ // If we have a capture group (index 1 or 2), use it, otherwise use the full match
81
+ const potentialTag = lastMatch[2] || lastMatch[1] || lastMatch[0];
82
+ // If it's a perfect match for a known tag or matches our dynamic pattern
83
+ // If we used a capture group, we need to adjust the index to point to that group specifically
84
+ const matchIndex = this.buffer.length -
85
+ lookbackLength +
86
+ lastMatch.index +
87
+ (lastMatch[0].length - potentialTag.length);
88
+ // Check if this is a definite tag (ends with > or ] or is a known tag)
89
+ if (potentialTag.endsWith(">") || potentialTag.endsWith("]") || this.tags.includes(potentialTag)) {
90
+ const content = this.buffer.substring(0, matchIndex);
91
+ this.buffer = this.buffer.substring(matchIndex + potentialTag.length);
92
+ console.log(`[Marie] Dynamic tag detected: ${potentialTag}`);
93
+ return { type: "tag", text: content, tag: potentialTag };
94
+ }
95
+ }
96
+ // 3. Check for partials (both prefix tree and dynamic)
97
+ const partialLength = this.prefixTree.findLongestPartialAtEnd(this.buffer);
98
+ // Dynamic partial check (strict): only hold potential control-tag prefixes,
99
+ // not generic trailing words/text.
100
+ const trailingControlTag = this.buffer.match(/<\|[\w_]*$/);
101
+ const trailingCallMarker = this.buffer.match(/call:\d*$/);
102
+ const dynamicPartialLength = Math.max(trailingControlTag ? trailingControlTag[0].length : 0, trailingCallMarker ? trailingCallMarker[0].length : 0);
103
+ const maxPartial = Math.max(partialLength, dynamicPartialLength);
104
+ if (maxPartial > 0) {
105
+ const unsafeStart = this.buffer.length - maxPartial;
106
+ const content = this.buffer.substring(0, unsafeStart);
107
+ this.buffer = this.buffer.substring(unsafeStart);
108
+ return { type: "incomplete", text: content };
109
+ }
110
+ // 4. No tags, no partials. Emit all.
111
+ const allContent = this.buffer;
112
+ this.buffer = "";
113
+ return { type: "content", text: allContent };
114
+ }
115
+ /**
116
+ * Resets the internal buffer. Useful for cleanup between sessions.
117
+ */
118
+ reset() {
119
+ this.buffer = "";
120
+ }
121
+ /**
122
+ * Returns the current buffer size for monitoring.
123
+ */
124
+ getBufferSize() {
125
+ return this.buffer.length;
126
+ }
127
+ }
128
+ //# sourceMappingURL=StreamTagDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StreamTagDetector.js","sourceRoot":"","sources":["../../../../src/monolith/plumbing/utils/StreamTagDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ export class StringUtils {
2
+ /**
3
+ * Calculates Levenshtein distance between two strings.
4
+ */
5
+ static levenshtein(a, b) {
6
+ // PERF: Prevent exhaustive comparison on massive strings (O(N^2) hazard)
7
+ const MAX_LEVEN_CHARS = 5000;
8
+ if (a.length > MAX_LEVEN_CHARS || b.length > MAX_LEVEN_CHARS) {
9
+ // Fallback to a fast length-based and prefix-based estimation for safety
10
+ const prefLen = this.getCommonPrefixLength(a, b);
11
+ const suffLen = this.getCommonSuffixLength(a, b);
12
+ const lenDiff = Math.abs(a.length - b.length);
13
+ return (lenDiff + (Math.max(a.length, b.length) - prefLen - suffLen - lenDiff));
14
+ }
15
+ // Ensure 'a' is the shorter string so we only allocate O(min(n,m)) space
16
+ if (a.length > b.length) {
17
+ const t = a;
18
+ a = b;
19
+ b = t;
20
+ }
21
+ const aLen = a.length;
22
+ const bLen = b.length;
23
+ if (aLen === 0)
24
+ return bLen;
25
+ let prev = new Array(aLen + 1);
26
+ let curr = new Array(aLen + 1);
27
+ for (let j = 0; j <= aLen; j++)
28
+ prev[j] = j;
29
+ for (let i = 1; i <= bLen; i++) {
30
+ curr[0] = i;
31
+ for (let j = 1; j <= aLen; j++) {
32
+ if (b[i - 1] === a[j - 1]) {
33
+ curr[j] = prev[j - 1];
34
+ }
35
+ else {
36
+ curr[j] = Math.min(prev[j - 1], curr[j - 1], prev[j]) + 1;
37
+ }
38
+ }
39
+ // Swap rows (reuse prev array on next iteration)
40
+ const tmp = prev;
41
+ prev = curr;
42
+ curr = tmp;
43
+ }
44
+ return prev[aLen];
45
+ }
46
+ /**
47
+ * Calculates similarity (0-1) between two strings using Levenshtein distance.
48
+ * Optimized with early exit for significantly different lengths.
49
+ */
50
+ static similarity(a, b) {
51
+ const maxLength = Math.max(a.length, b.length);
52
+ const minLength = Math.min(a.length, b.length);
53
+ if (maxLength === 0)
54
+ return 1.0;
55
+ // Early exit: if strings differ by > 50% in length, similarity will be low
56
+ // This avoids expensive Levenshtein calculation for obviously dissimilar strings
57
+ const lengthRatio = minLength / maxLength;
58
+ if (lengthRatio < 0.5) {
59
+ // Still compute, but we know it won't be high similarity
60
+ // Could return 0 here for even faster processing, but let's be accurate
61
+ }
62
+ return (maxLength - this.levenshtein(a, b)) / maxLength;
63
+ }
64
+ /**
65
+ * Safely extracts text from AI message content which can be a string or array of blocks.
66
+ */
67
+ static extractText(content) {
68
+ if (content === null || content === undefined)
69
+ return "";
70
+ if (typeof content === "string")
71
+ return content;
72
+ if (Array.isArray(content)) {
73
+ return content
74
+ .filter((block) => block && block.type === "text")
75
+ .map((block) => block.text || "")
76
+ .join(" ");
77
+ }
78
+ return "";
79
+ }
80
+ static getCommonPrefixLength(a, b) {
81
+ let i = 0;
82
+ const min = Math.min(a.length, b.length);
83
+ while (i < min && a[i] === b[i])
84
+ i++;
85
+ return i;
86
+ }
87
+ static getCommonSuffixLength(a, b) {
88
+ let i = 0;
89
+ const aLen = a.length;
90
+ const bLen = b.length;
91
+ const min = Math.min(aLen, bLen);
92
+ while (i < min && a[aLen - 1 - i] === b[bLen - 1 - i])
93
+ i++;
94
+ return i;
95
+ }
96
+ }
97
+ //# sourceMappingURL=StringUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StringUtils.js","sourceRoot":"","sources":["../../../../src/monolith/plumbing/utils/StringUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Executes a promise with a timeout.
3
+ */
4
+ export async function withTimeout(promise, ms, label) {
5
+ let timeoutId;
6
+ const timeoutPromise = new Promise((_, reject) => {
7
+ timeoutId = setTimeout(() => {
8
+ reject(new Error(`TimeoutError: ${label} timed out after ${ms}ms`));
9
+ }, ms);
10
+ });
11
+ try {
12
+ const result = await Promise.race([promise, timeoutPromise]);
13
+ clearTimeout(timeoutId);
14
+ return result;
15
+ }
16
+ catch (e) {
17
+ clearTimeout(timeoutId);
18
+ throw e;
19
+ }
20
+ }
21
+ //# sourceMappingURL=TimeoutUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeoutUtils.js","sourceRoot":"","sources":["../../../../src/monolith/plumbing/utils/TimeoutUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAmB,EACnB,EAAU,EACV,KAAa;IAEb,IAAI,SAAyB,CAAC;IAC9B,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QACtD,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,KAAK,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAAC;QACtE,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QAC7D,YAAY,CAAC,SAAU,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,YAAY,CAAC,SAAU,CAAC,CAAC;QACzB,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}