@noorm/marie-cli 0.1.15 → 0.1.16

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 (93) hide show
  1. package/.marie_visual_verify_1771225696548/progress_bar_check.txt +1 -0
  2. package/SENTINEL.md +33 -0
  3. package/dist/domain/DomainEntity.js +7 -0
  4. package/dist/domain/DomainEntity.js.map +1 -0
  5. package/dist/extension.cjs +149 -147
  6. package/dist/extension.js +459 -0
  7. package/dist/extension.js.map +1 -0
  8. package/dist/infrastructure/BaseAdapter.js +3 -0
  9. package/dist/infrastructure/BaseAdapter.js.map +1 -0
  10. package/dist/monolith/cli/CliFileSystemPort.js +16 -8
  11. package/dist/monolith/cli/CliFileSystemPort.js.map +1 -1
  12. package/dist/monolith/cli/MarieToolDefinitionsCLI.js +9 -6
  13. package/dist/monolith/cli/MarieToolDefinitionsCLI.js.map +1 -1
  14. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js +1 -1
  15. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js.map +1 -1
  16. package/dist/monolith/infrastructure/ai/core/MarieEngine.js +29 -10
  17. package/dist/monolith/infrastructure/ai/core/MarieEngine.js.map +1 -1
  18. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js +19 -13
  19. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js.map +1 -1
  20. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js +8 -8
  21. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js.map +1 -1
  22. package/dist/monolith/infrastructure/config/ConfigService.js +2 -22
  23. package/dist/monolith/infrastructure/config/ConfigService.js.map +1 -1
  24. package/dist/monolith/infrastructure/joy/JoyTools.js +535 -0
  25. package/dist/monolith/infrastructure/joy/JoyTools.js.map +1 -0
  26. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js +14 -13
  27. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js.map +1 -1
  28. package/dist/monolith/plumbing/analysis/TestService.js +2 -1
  29. package/dist/monolith/plumbing/analysis/TestService.js.map +1 -1
  30. package/dist/monolith/plumbing/filesystem/FileService.js +22 -10
  31. package/dist/monolith/plumbing/filesystem/FileService.js.map +1 -1
  32. package/dist/monolith/plumbing/utils/EnvironmentUtils.js +59 -0
  33. package/dist/monolith/plumbing/utils/EnvironmentUtils.js.map +1 -0
  34. package/dist/monolith/plumbing/utils/MutexUtils.js +86 -0
  35. package/dist/monolith/plumbing/utils/MutexUtils.js.map +1 -0
  36. package/dist/monolith/runtime/MarieRuntime.js +250 -136
  37. package/dist/monolith/runtime/MarieRuntime.js.map +1 -1
  38. package/dist/monolith/runtime/RuntimeAdapterBase.js +6 -0
  39. package/dist/monolith/runtime/RuntimeAdapterBase.js.map +1 -1
  40. package/dist/monolith/services/JoyAutomationService.js +1 -1
  41. package/dist/monolith/services/JoyAutomationService.js.map +1 -1
  42. package/dist/monolith/services/JoyService.js +1 -1
  43. package/dist/monolith/services/JoyService.js.map +1 -1
  44. package/dist/plumbing/BaseTool.js +7 -0
  45. package/dist/plumbing/BaseTool.js.map +1 -0
  46. package/dist/prompts.js +85 -0
  47. package/dist/prompts.js.map +1 -0
  48. package/dist/test_agent_stream_control_plane.js +170 -0
  49. package/dist/test_agent_stream_control_plane.js.map +1 -0
  50. package/dist/test_content_buffer_cap.js +67 -0
  51. package/dist/test_content_buffer_cap.js.map +1 -0
  52. package/dist/test_prefix_tree.js +120 -0
  53. package/dist/test_prefix_tree.js.map +1 -0
  54. package/dist/test_retry_utils.js +169 -0
  55. package/dist/test_retry_utils.js.map +1 -0
  56. package/dist/test_strategy_integration.js +114 -0
  57. package/dist/test_strategy_integration.js.map +1 -0
  58. package/dist/test_streaming_fragility.js +191 -0
  59. package/dist/test_streaming_fragility.js.map +1 -0
  60. package/dist/webview-ui/App.js +16 -0
  61. package/dist/webview-ui/App.js.map +1 -0
  62. package/dist/webview-ui/Providers.js +6 -0
  63. package/dist/webview-ui/Providers.js.map +1 -0
  64. package/dist/webview-ui/components/ApprovalPanel.js +8 -0
  65. package/dist/webview-ui/components/ApprovalPanel.js.map +1 -0
  66. package/dist/webview-ui/components/ChatPanel.js +19 -0
  67. package/dist/webview-ui/components/ChatPanel.js.map +1 -0
  68. package/dist/webview-ui/components/Composer.js +19 -0
  69. package/dist/webview-ui/components/Composer.js.map +1 -0
  70. package/dist/webview-ui/components/HeaderBar.js +5 -0
  71. package/dist/webview-ui/components/HeaderBar.js.map +1 -0
  72. package/dist/webview-ui/components/SessionList.js +14 -0
  73. package/dist/webview-ui/components/SessionList.js.map +1 -0
  74. package/dist/webview-ui/context/WebviewStateContext.js +146 -0
  75. package/dist/webview-ui/context/WebviewStateContext.js.map +1 -0
  76. package/dist/webview-ui/main.css +1 -0
  77. package/dist/webview-ui/main.js +108 -0
  78. package/dist/webview-ui/main.js.map +1 -0
  79. package/dist/webview-ui/types.js +2 -0
  80. package/dist/webview-ui/types.js.map +1 -0
  81. package/dist/webview-ui/vscode.js +4 -0
  82. package/dist/webview-ui/vscode.js.map +1 -0
  83. package/lint_output.txt +705 -0
  84. package/lint_output_v2.txt +711 -0
  85. package/marie-coder-0.1.16.vsix +0 -0
  86. package/package.json +3 -10
  87. package/JOY_ZONING.md +0 -200
  88. package/dist/monolith/tests/FileAppendVerifyTest.js +0 -28
  89. package/dist/monolith/tests/FileAppendVerifyTest.js.map +0 -1
  90. package/dist/monolith/tests/StreamingVerifyTest.js +0 -100
  91. package/dist/monolith/tests/StreamingVerifyTest.js.map +0 -1
  92. package/dist/monolith/tests/VisualProgressTest.js +0 -86
  93. package/dist/monolith/tests/VisualProgressTest.js.map +0 -1
@@ -0,0 +1,120 @@
1
+ import { PrefixTree } from "./monolith/plumbing/utils/PrefixTree.js";
2
+ console.log("Starting PrefixTree Tests...\n");
3
+ // Test Suite 1: Basic Tag Detection
4
+ function testBasicDetection() {
5
+ console.log("Suite 1: Basic Tag Detection");
6
+ const tree = new PrefixTree(["<tool>", "</tool>", "<|start|>", "<|end|>"]);
7
+ // Test 1: Empty text
8
+ const result1 = tree.findEarliestTag("");
9
+ console.log(`Test: Empty text - ${result1 === null ? "PASS" : "FAIL"}`);
10
+ // Test 2: Single tag
11
+ const result2 = tree.findEarliestTag("Hello <tool> world");
12
+ console.log(`Test: Single tag - ${result2?.tag === "<tool>" && result2?.index === 6 ? "PASS" : "FAIL"}`);
13
+ // Test 3: Multiple tags (earliest wins)
14
+ const result3 = tree.findEarliestTag("Text </tool> more <tool> stuff");
15
+ console.log(`Test: Multiple tags (earliest) - ${result3?.tag === "</tool>" && result3?.index === 5 ? "PASS" : "FAIL"}`);
16
+ // Test 4: Overlapping tags
17
+ const result4 = tree.findEarliestTag("<<tool>>");
18
+ console.log(`Test: Overlapping tags - ${result4?.tag === "<tool>" && result4?.index === 1 ? "PASS" : "FAIL"}`);
19
+ // Test 5: No tags
20
+ const result5 = tree.findEarliestTag("Just plain text here");
21
+ console.log(`Test: No tags - ${result5 === null ? "PASS" : "FAIL"}`);
22
+ }
23
+ // Test Suite 2: Partial Tag Detection
24
+ function testPartialDetection() {
25
+ console.log("\nSuite 2: Partial Tag Detection");
26
+ const tree = new PrefixTree(["<tool>", "<|start|>", "<|end|>"]);
27
+ // Test 1: Complete partial at end
28
+ const result1 = tree.findLongestPartialAtEnd("Text <too");
29
+ console.log(`Test: Partial '<too' - ${result1 === 4 ? "PASS" : "FAIL (got " + result1 + ")"}`);
30
+ // Test 2: Longer partial
31
+ const result2 = tree.findLongestPartialAtEnd("Text <|star");
32
+ console.log(`Test: Partial '<|star' - ${result2 === 6 ? "PASS" : "FAIL (got " + result2 + ")"}`);
33
+ // Test 3: No partial
34
+ const result3 = tree.findLongestPartialAtEnd("No partial here");
35
+ console.log(`Test: No partial - ${result3 === 0 ? "PASS" : "FAIL"}`);
36
+ // Test 4: Complete tag (not a partial)
37
+ const result4 = tree.findLongestPartialAtEnd("Complete <tool>");
38
+ console.log(`Test: Complete tag (not partial) - ${result4 === 0 ? "PASS" : "FAIL"}`);
39
+ // Test 5: Single char partial
40
+ const result5 = tree.findLongestPartialAtEnd("End with <");
41
+ console.log(`Test: Single char partial '<' - ${result5 === 1 ? "PASS" : "FAIL (got " + result5 + ")"}`);
42
+ }
43
+ // Test Suite 3: Fuzzy Matching
44
+ function testFuzzyMatching() {
45
+ console.log("\nSuite 3: Fuzzy Matching");
46
+ const tree = new PrefixTree([
47
+ "<|tool_call_begin|>",
48
+ "<|tool_call_end|>",
49
+ "<tool>",
50
+ ]);
51
+ // Test 1: Exact match (distance 0)
52
+ const result1 = tree.findSimilarTags("<tool>", 2);
53
+ console.log(`Test: Exact match - ${result1.includes("<tool>") && result1.length === 1 ? "PASS" : "FAIL"}`);
54
+ // Test 2: Distance 1 (one char off)
55
+ const result2 = tree.findSimilarTags("<tol>", 2);
56
+ console.log(`Test: Distance 1 - ${result2.includes("<tool>") ? "PASS" : "FAIL"}`);
57
+ // Test 3: Distance 2 (two chars off)
58
+ const result3 = tree.findSimilarTags("<|tool_call_begi|>", 2);
59
+ console.log(`Test: Distance 2 - ${result3.includes("<|tool_call_begin|>") ? "PASS" : "FAIL"}`);
60
+ // Test 4: Too far (distance > 2)
61
+ const result4 = tree.findSimilarTags("<toolz>", 1);
62
+ console.log(`Test: Distance > max - ${result4.length === 0 ? "PASS" : "FAIL"}`);
63
+ // Test 5: Multiple matches
64
+ const result5 = tree.findSimilarTags("<|tool_call_en|>", 2);
65
+ console.log(`Test: Multiple fuzzy matches - ${result5.length >= 1 ? "PASS" : "FAIL"}`);
66
+ }
67
+ // Test Suite 4: Performance with Large Tag Sets
68
+ function testPerformance() {
69
+ console.log("\nSuite 4: Performance");
70
+ // Create a large tag set
71
+ const tags = [];
72
+ for (let i = 0; i < 100; i++) {
73
+ tags.push(`<tag_${i}>`);
74
+ tags.push(`<|llama_tag_${i}|>`);
75
+ }
76
+ const tree = new PrefixTree(tags);
77
+ const text = "Some text content ".repeat(10) + "<tag_50>" + " more text".repeat(10);
78
+ const startTime = Date.now();
79
+ const result = tree.findEarliestTag(text);
80
+ const duration = Date.now() - startTime;
81
+ console.log(`Test: Large tag set (200 tags) - ${result?.tag === "<tag_50>" && duration < 50 ? "PASS" : "FAIL"} (${duration}ms)`);
82
+ // Test partial detection performance
83
+ const partialText = "x".repeat(1000) + "<tag_9";
84
+ const startTime2 = Date.now();
85
+ const partial = tree.findLongestPartialAtEnd(partialText);
86
+ const duration2 = Date.now() - startTime2;
87
+ console.log(`Test: Partial detection perf - ${partial === 7 && duration2 < 100 ? "PASS" : "FAIL"} (${duration2}ms)`);
88
+ }
89
+ // Test Suite 5: Edge Cases
90
+ function testEdgeCases() {
91
+ console.log("\nSuite 5: Edge Cases");
92
+ const tree = new PrefixTree(["<a>", "<ab>", "<abc>"]);
93
+ // Test 1: Nested overlapping tags
94
+ const result1 = tree.findEarliestTag("<a<ab>>");
95
+ console.log(`Test: Nested tags - ${result1?.tag === "<a>" && result1?.index === 0 ? "PASS" : "FAIL"}`);
96
+ // Test 2: Tag prefix of another
97
+ const result2 = tree.findEarliestTag("Text <abc> end");
98
+ console.log(`Test: Tag prefix - ${result2?.tag === "<a>" && result2?.index === 5 ? "PASS" : "FAIL"}`);
99
+ // Test 3: Special characters
100
+ const tree2 = new PrefixTree(["<|tag|>", "<tag\\n>"]);
101
+ const result3 = tree2.findEarliestTag("Start <|tag|> end");
102
+ console.log(`Test: Special chars - ${result3?.tag === "<|tag|>" ? "PASS" : "FAIL"}`);
103
+ // Test 4: Very long tag
104
+ const longTag = "<" + "x".repeat(100) + ">";
105
+ const tree3 = new PrefixTree([longTag]);
106
+ const result4 = tree3.findEarliestTag("Text " + longTag + " end");
107
+ console.log(`Test: Long tag (102 chars) - ${result4?.tag === longTag ? "PASS" : "FAIL"}`);
108
+ // Test 5: Unicode characters
109
+ const tree4 = new PrefixTree(["<🔧>", "<emoji>"]);
110
+ const result5 = tree4.findEarliestTag("Start <🔧> end");
111
+ console.log(`Test: Unicode - ${result5?.tag === "<🔧>" ? "PASS" : "FAIL"}`);
112
+ }
113
+ // Run all tests
114
+ testBasicDetection();
115
+ testPartialDetection();
116
+ testFuzzyMatching();
117
+ testPerformance();
118
+ testEdgeCases();
119
+ console.log("\nAll PrefixTree tests completed!");
120
+ //# sourceMappingURL=test_prefix_tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_prefix_tree.js","sourceRoot":"","sources":["../src/test_prefix_tree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ import { withRetry, RetryConfig, } from "./monolith/plumbing/utils/RetryUtils.js";
2
+ console.log("Starting RetryUtils Tests...\n");
3
+ // Helper to simulate async operations
4
+ async function sleep(ms) {
5
+ return new Promise((resolve) => setTimeout(resolve, ms));
6
+ }
7
+ // Test Suite 1: Successful Execution
8
+ async function testSuccessfulExecution() {
9
+ console.log("Suite 1: Successful Execution");
10
+ // Test 1: No retry needed
11
+ let callCount = 0;
12
+ const config = new RetryConfig();
13
+ try {
14
+ const result = await withRetry(async () => {
15
+ callCount++;
16
+ return "success";
17
+ }, config, "Test1");
18
+ console.log(`Test: No retry needed - ${result === "success" && callCount === 1 ? "PASS" : "FAIL"}`);
19
+ }
20
+ catch (e) {
21
+ console.log(`Test: No retry needed - FAIL (threw error)`);
22
+ }
23
+ }
24
+ // Test Suite 2: Retryable Errors
25
+ async function testRetryableErrors() {
26
+ console.log("\nSuite 2: Retryable Errors");
27
+ // Test 1: Success on 2nd attempt
28
+ let attempt1 = 0;
29
+ const config1 = new RetryConfig();
30
+ try {
31
+ const result = await withRetry(async () => {
32
+ attempt1++;
33
+ if (attempt1 === 1) {
34
+ throw new Error("ETIMEDOUT: Connection timeout");
35
+ }
36
+ return "success";
37
+ }, config1, "Test2.1");
38
+ console.log(`Test: Success on 2nd attempt - ${result === "success" && attempt1 === 2 ? "PASS" : "FAIL (attempts: " + attempt1 + ")"}`);
39
+ }
40
+ catch (e) {
41
+ console.log(`Test: Success on 2nd attempt - FAIL (threw error)`);
42
+ }
43
+ // Test 2: Success on 3rd attempt
44
+ let attempt2 = 0;
45
+ const config2 = new RetryConfig();
46
+ try {
47
+ const result = await withRetry(async () => {
48
+ attempt2++;
49
+ if (attempt2 < 3) {
50
+ throw new Error("Rate limit exceeded");
51
+ }
52
+ return "success";
53
+ }, config2, "Test2.2");
54
+ console.log(`Test: Success on 3rd attempt - ${result === "success" && attempt2 === 3 ? "PASS" : "FAIL (attempts: " + attempt2 + ")"}`);
55
+ }
56
+ catch (e) {
57
+ console.log(`Test: Success on 3rd attempt - FAIL (threw error)`);
58
+ }
59
+ }
60
+ // Test Suite 3: Non-Retryable Errors
61
+ async function testNonRetryableErrors() {
62
+ console.log("\nSuite 3: Non-Retryable Errors");
63
+ // Test 1: Validation error (immediate failure)
64
+ let attempt1 = 0;
65
+ const config1 = new RetryConfig();
66
+ try {
67
+ await withRetry(async () => {
68
+ attempt1++;
69
+ throw new Error("Invalid input: missing required field");
70
+ }, config1, "Test3.1");
71
+ console.log(`Test: Non-retryable error - FAIL (should have thrown)`);
72
+ }
73
+ catch (e) {
74
+ console.log(`Test: Non-retryable error - ${attempt1 === 1 ? "PASS" : "FAIL (attempts: " + attempt1 + ")"}`);
75
+ }
76
+ // Test 2: Permission error
77
+ let attempt2 = 0;
78
+ const config2 = new RetryConfig();
79
+ try {
80
+ await withRetry(async () => {
81
+ attempt2++;
82
+ throw new Error("Permission denied");
83
+ }, config2, "Test3.2");
84
+ console.log(`Test: Permission error - FAIL (should have thrown)`);
85
+ }
86
+ catch (e) {
87
+ console.log(`Test: Permission error - ${attempt2 === 1 ? "PASS" : "FAIL (attempts: " + attempt2 + ")"}`);
88
+ }
89
+ }
90
+ // Test Suite 4: Exhausted Retries
91
+ async function testExhaustedRetries() {
92
+ console.log("\nSuite 4: Exhausted Retries");
93
+ // Test 1: Max retries exceeded
94
+ let attempt = 0;
95
+ const config = new RetryConfig();
96
+ config.maxRetries = 3;
97
+ try {
98
+ await withRetry(async () => {
99
+ attempt++;
100
+ throw new Error("ETIMEDOUT: persistent timeout");
101
+ }, config, "Test4.1");
102
+ console.log(`Test: Max retries - FAIL (should have thrown)`);
103
+ }
104
+ catch (e) {
105
+ // Should attempt 1 initial + 3 retries = 4 total
106
+ console.log(`Test: Max retries - ${attempt === 4 ? "PASS" : "FAIL (attempts: " + attempt + ", expected 4)"}`);
107
+ }
108
+ }
109
+ // Test Suite 5: Exponential Backoff
110
+ async function testExponentialBackoff() {
111
+ console.log("\nSuite 5: Exponential Backoff");
112
+ const config = new RetryConfig();
113
+ config.baseDelayMs = 100;
114
+ config.maxDelayMs = 5000;
115
+ // Test 1: First retry delay
116
+ const delay1 = config.getBackoffDelay(0);
117
+ console.log(`Test: First retry delay - ${delay1 >= 100 && delay1 <= 200 ? "PASS" : "FAIL (got " + delay1 + "ms)"}`);
118
+ // Test 2: Second retry delay
119
+ const delay2 = config.getBackoffDelay(1);
120
+ console.log(`Test: Second retry delay - ${delay2 >= 200 && delay2 <= 350 ? "PASS" : "FAIL (got " + delay2 + "ms)"}`);
121
+ // Test 3: Max delay cap
122
+ const delay10 = config.getBackoffDelay(10);
123
+ console.log(`Test: Max delay cap - ${delay10 <= 5000 ? "PASS" : "FAIL (got " + delay10 + "ms)"}`);
124
+ // Test 4: Actual timing (2 retries)
125
+ let attempt = 0;
126
+ const startTime = Date.now();
127
+ try {
128
+ await withRetry(async () => {
129
+ attempt++;
130
+ if (attempt < 3) {
131
+ throw new Error("TIMEOUT: retry me");
132
+ }
133
+ return "success";
134
+ }, config, "Test5.4");
135
+ const duration = Date.now() - startTime;
136
+ // Should take ~100ms + ~200ms = ~300ms (with some variance for jitter)
137
+ console.log(`Test: Actual timing - ${duration >= 250 && duration <= 600 ? "PASS" : "FAIL (took " + duration + "ms)"}`);
138
+ }
139
+ catch (e) {
140
+ console.log(`Test: Actual timing - FAIL (threw error)`);
141
+ }
142
+ }
143
+ // Test Suite 6: Error Detection
144
+ function testErrorDetection() {
145
+ console.log("\nSuite 6: Error Detection");
146
+ const config = new RetryConfig();
147
+ // Test retryable errors
148
+ console.log(`Test: ETIMEDOUT - ${config.isRetryable("ETIMEDOUT: connection timeout") ? "PASS" : "FAIL"}`);
149
+ console.log(`Test: ECONNRESET - ${config.isRetryable("Error: ECONNRESET") ? "PASS" : "FAIL"}`);
150
+ console.log(`Test: Rate limit - ${config.isRetryable("Rate limit exceeded") ? "PASS" : "FAIL"}`);
151
+ console.log(`Test: Throttle - ${config.isRetryable("Request throttled") ? "PASS" : "FAIL"}`);
152
+ // Test non-retryable errors
153
+ console.log(`Test: Invalid input - ${!config.isRetryable("Invalid input") ? "PASS" : "FAIL"}`);
154
+ console.log(`Test: Permission - ${!config.isRetryable("Permission denied") ? "PASS" : "FAIL"}`);
155
+ }
156
+ // Run all tests
157
+ async function runAllTests() {
158
+ await testSuccessfulExecution();
159
+ await testRetryableErrors();
160
+ await testNonRetryableErrors();
161
+ await testExhaustedRetries();
162
+ await testExponentialBackoff();
163
+ testErrorDetection();
164
+ console.log("\nAll RetryUtils tests completed!");
165
+ }
166
+ runAllTests().catch((err) => {
167
+ console.error("Test error:", err);
168
+ });
169
+ //# sourceMappingURL=test_retry_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_retry_utils.js","sourceRoot":"","sources":["../src/test_retry_utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,WAAW,GACZ,MAAM,yCAAyC,CAAC;AAEjD,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAE9C,sCAAsC;AACtC,KAAK,UAAU,KAAK,CAAC,EAAU;IAC7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,qCAAqC;AACrC,KAAK,UAAU,uBAAuB;IACpC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,0BAA0B;IAC1B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,KAAK,IAAI,EAAE;YACT,SAAS,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,MAAM,EACN,OAAO,CACR,CAAC;QACF,OAAO,CAAC,GAAG,CACT,2BAA2B,MAAM,KAAK,SAAS,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CACvF,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,iCAAiC;AACjC,KAAK,UAAU,mBAAmB;IAChC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,iCAAiC;IACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,KAAK,IAAI,EAAE;YACT,QAAQ,EAAE,CAAC;YACX,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,OAAO,EACP,SAAS,CACV,CAAC;QACF,OAAO,CAAC,GAAG,CACT,kCAAkC,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,GAAG,QAAQ,GAAG,GAAG,EAAE,CAC1H,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;IAED,iCAAiC;IACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAC5B,KAAK,IAAI,EAAE;YACT,QAAQ,EAAE,CAAC;YACX,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,OAAO,EACP,SAAS,CACV,CAAC;QACF,OAAO,CAAC,GAAG,CACT,kCAAkC,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,GAAG,QAAQ,GAAG,GAAG,EAAE,CAC1H,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,KAAK,UAAU,sBAAsB;IACnC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,+CAA+C;IAC/C,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,SAAS,CACb,KAAK,IAAI,EAAE;YACT,QAAQ,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC,EACD,OAAO,EACP,SAAS,CACV,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,+BAA+B,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,GAAG,QAAQ,GAAG,GAAG,EAAE,CAC/F,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,SAAS,CACb,KAAK,IAAI,EAAE;YACT,QAAQ,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC,EACD,OAAO,EACP,SAAS,CACV,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,4BAA4B,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,GAAG,QAAQ,GAAG,GAAG,EAAE,CAC5F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,kCAAkC;AAClC,KAAK,UAAU,oBAAoB;IACjC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAE5C,+BAA+B;IAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IACjC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,SAAS,CACb,KAAK,IAAI,EAAE;YACT,OAAO,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC,EACD,MAAM,EACN,SAAS,CACV,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,iDAAiD;QACjD,OAAO,CAAC,GAAG,CACT,uBAAuB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,GAAG,OAAO,GAAG,eAAe,EAAE,CACjG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,oCAAoC;AACpC,KAAK,UAAU,sBAAsB;IACnC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IACjC,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC;IACzB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IAEzB,4BAA4B;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CACT,6BAA6B,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,MAAM,GAAG,KAAK,EAAE,CACvG,CAAC;IAEF,6BAA6B;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CACT,8BAA8B,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,MAAM,GAAG,KAAK,EAAE,CACxG,CAAC;IAEF,wBAAwB;IACxB,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CACT,yBAAyB,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,OAAO,GAAG,KAAK,EAAE,CACrF,CAAC;IAEF,oCAAoC;IACpC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,SAAS,CACb,KAAK,IAAI,EAAE;YACT,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC,EACD,MAAM,EACN,SAAS,CACV,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACxC,uEAAuE;QACvE,OAAO,CAAC,GAAG,CACT,yBAAyB,QAAQ,IAAI,GAAG,IAAI,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,GAAG,QAAQ,GAAG,KAAK,EAAE,CAC1G,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,gCAAgC;AAChC,SAAS,kBAAkB;IACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAEjC,wBAAwB;IACxB,OAAO,CAAC,GAAG,CACT,qBAAqB,MAAM,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAC7F,CAAC;IACF,OAAO,CAAC,GAAG,CACT,sBAAsB,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAClF,CAAC;IACF,OAAO,CAAC,GAAG,CACT,sBAAsB,MAAM,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CACpF,CAAC;IACF,OAAO,CAAC,GAAG,CACT,oBAAoB,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAChF,CAAC;IAEF,4BAA4B;IAC5B,OAAO,CAAC,GAAG,CACT,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAClF,CAAC;IACF,OAAO,CAAC,GAAG,CACT,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CACnF,CAAC;AACJ,CAAC;AAED,gBAAgB;AAChB,KAAK,UAAU,WAAW;IACxB,MAAM,uBAAuB,EAAE,CAAC;IAChC,MAAM,mBAAmB,EAAE,CAAC;IAC5B,MAAM,sBAAsB,EAAE,CAAC;IAC/B,MAAM,oBAAoB,EAAE,CAAC;IAC7B,MAAM,sBAAsB,EAAE,CAAC;IAC/B,kBAAkB,EAAE,CAAC;IAErB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AACnD,CAAC;AAED,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,114 @@
1
+ import { MarieEngine } from "./monolith/infrastructure/ai/core/MarieEngine.js";
2
+ import { ToolRegistry } from "./monolith/infrastructure/tools/ToolRegistry.js";
3
+ import { MarieProgressTracker } from "./monolith/infrastructure/ai/core/MarieProgressTracker.js";
4
+ // --- MOCKS ---
5
+ class MockAIProvider {
6
+ async createMessage() {
7
+ return { role: "assistant", content: "Thought" };
8
+ }
9
+ callCount = 0;
10
+ async createMessageStream(params, onUpdate) {
11
+ this.callCount++;
12
+ if (this.callCount > 1) {
13
+ onUpdate({ type: "content_delta", text: "Done. " });
14
+ return { role: "assistant", content: "Done." };
15
+ }
16
+ onUpdate({ type: "content_delta", text: "I will create a file. " });
17
+ onUpdate({
18
+ type: "tool_call_delta",
19
+ index: 0,
20
+ id: "call_123",
21
+ name: "write_to_file"
22
+ });
23
+ onUpdate({
24
+ type: "tool_call_delta",
25
+ index: 0,
26
+ id: "call_123",
27
+ argumentsDelta: '{"path": "test.txt", "content": "hello"}'
28
+ });
29
+ onUpdate({ type: "usage", usage: { totalTokens: 100 } });
30
+ return {
31
+ role: "assistant",
32
+ content: "I will create a file.",
33
+ tool_uses: [{ id: "call_123", name: "write_to_file", input: { path: "test.txt", content: "hello" } }]
34
+ };
35
+ }
36
+ estimateTokens() { return 0; }
37
+ async listModels() { return []; }
38
+ }
39
+ class MockFileSystemPort {
40
+ async readFile() { return ""; }
41
+ async writeFile(p, c) {
42
+ console.log(`[MockFS] Writing to ${p}: ${c}`);
43
+ }
44
+ async deleteFile() { }
45
+ async backupFile() { }
46
+ async restoreFile() { }
47
+ async rollbackAll() { }
48
+ clearBackups() { }
49
+ }
50
+ // --- TEST RUNNER ---
51
+ async function runStrategyTest() {
52
+ console.log("🚀 Starting Strategy Integration Test...");
53
+ const toolRegistry = new ToolRegistry();
54
+ toolRegistry.register({
55
+ name: "write_to_file",
56
+ description: "Write content",
57
+ input_schema: { type: "object", properties: { path: { type: "string" }, content: { type: "string" } } },
58
+ execute: async (args) => {
59
+ console.log("[Tool] write_to_file executed");
60
+ return "Success";
61
+ }
62
+ });
63
+ const run = {
64
+ runId: "test_run",
65
+ startedAt: Date.now(),
66
+ steps: 0,
67
+ tools: 0,
68
+ objectives: [
69
+ { id: 'understand_request', label: 'Understand', status: 'in_progress' },
70
+ { id: 'execute_plan', label: 'Execute', status: 'pending' },
71
+ { id: 'deliver_result', label: 'Deliver', status: 'pending' }
72
+ ],
73
+ activeObjectiveId: 'understand_request',
74
+ achieved: []
75
+ };
76
+ const events = [];
77
+ const tracker = new MarieProgressTracker({
78
+ onEvent: (e) => {
79
+ events.push(e);
80
+ console.log(`[Event Capture] Captured event: ${e.type}`);
81
+ if (e.type === 'progress_update') {
82
+ console.log(`[Tracker] Progress: ${e.activeObjectiveId} -> ${e.context}`);
83
+ }
84
+ },
85
+ onStream: (c) => console.log(`[Stream] ${c}`)
86
+ }, run);
87
+ const provider = new MockAIProvider();
88
+ const fs = new MockFileSystemPort();
89
+ // We mock VscodeFileSystemPort by name to test environment detection in MarieEngine
90
+ Object.defineProperty(fs.constructor, 'name', { value: 'CliFileSystemPort' });
91
+ const engine = new MarieEngine(provider, toolRegistry, async () => true, // Auto-approve
92
+ undefined, fs);
93
+ console.log("\n--- Executing chatLoop ---");
94
+ await engine.chatLoop([{ role: "user", content: "create a file" }], tracker, async () => { });
95
+ // Wait for throttle timers in dispatcher
96
+ await new Promise(resolve => setTimeout(resolve, 200));
97
+ console.log("\n--- Verification ---");
98
+ console.log("Event types seen:", events.map(e => e.type).join(', '));
99
+ // 1. Verify environment detection
100
+ const state = engine.state;
101
+ console.log(`Test: Environment detected as CLI - ${state.environment === 'cli' ? 'PASS' : 'FAIL'}`);
102
+ // 2. Verify objective transition
103
+ const finalObjective = run.activeObjectiveId;
104
+ console.log(`Test: Objective transitioned to execute_plan - ${finalObjective === 'execute_plan' ? 'PASS' : 'FAIL'}`);
105
+ // 3. Verify event routing (content_delta should be in events)
106
+ const hasContentDelta = events.some(e => e.type === 'content_delta');
107
+ console.log(`Test: MarieEventDispatcher routed content_delta - ${hasContentDelta ? 'PASS' : 'FAIL'}`);
108
+ // 4. Verify tool delta routing
109
+ const hasToolDelta = events.some(e => e.type === 'tool_delta');
110
+ console.log(`Test: MarieEventDispatcher routed tool_delta - ${hasToolDelta ? 'PASS' : 'FAIL'}`);
111
+ console.log("\nStrategy Integration Test Completed!");
112
+ }
113
+ runStrategyTest().catch(console.error);
114
+ //# sourceMappingURL=test_strategy_integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_strategy_integration.js","sourceRoot":"","sources":["../src/test_strategy_integration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,191 @@
1
+ import { StreamTagDetector } from "./monolith/plumbing/utils/StreamTagDetector.js";
2
+ import { OpenRouterStreamParser } from "./monolith/infrastructure/ai/providers/OpenRouterStreamParser.js";
3
+ async function runTests() {
4
+ console.log("Starting Streaming Tests...\n");
5
+ // --- Suite 1: StreamTagDetector ---
6
+ console.log("Suite 1: StreamTagDetector (Component Level)");
7
+ const tests = [
8
+ {
9
+ name: "Normal Content (No Tags)",
10
+ chunks: ["Hello ", "world", "!"],
11
+ expectedTags: []
12
+ },
13
+ {
14
+ name: "Complete Tag in One Chunk",
15
+ chunks: ["Hello <tool>"],
16
+ expectedTags: ["<tool>"]
17
+ },
18
+ {
19
+ name: "Split Tag (<t + ool>)",
20
+ chunks: ["Hello <t", "ool>"],
21
+ expectedTags: ["<tool>"]
22
+ },
23
+ {
24
+ name: "Llama 3 Split Tag",
25
+ chunks: ["Start <|tool_", "call_", "begin|> End"],
26
+ expectedTags: ["<|tool_call_begin|>"]
27
+ }
28
+ ];
29
+ let passed = 0;
30
+ for (const test of tests) {
31
+ console.log(`Test: ${test.name}`);
32
+ const detector = new StreamTagDetector();
33
+ const detectedTags = [];
34
+ let outputText = "";
35
+ for (const chunk of test.chunks) {
36
+ const result = detector.process(chunk);
37
+ if (result.type === 'tag')
38
+ detectedTags.push(result.tag);
39
+ if (result.text)
40
+ outputText += result.text;
41
+ }
42
+ // Verification
43
+ const expected = test.expectedTags;
44
+ const actual = detectedTags;
45
+ let p = true;
46
+ if (expected.length !== actual.length)
47
+ p = false;
48
+ else {
49
+ for (let i = 0; i < expected.length; i++) {
50
+ if (expected[i] !== actual[i])
51
+ p = false;
52
+ }
53
+ }
54
+ if (p) {
55
+ console.log(" PASS");
56
+ passed++;
57
+ }
58
+ else {
59
+ console.log(` FAIL. Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
60
+ }
61
+ }
62
+ console.log(`Suite 1 Results: ${passed}/${tests.length} Passed\n`);
63
+ // --- Suite 2: OpenRouterStreamParser ---
64
+ console.log("Suite 2: OpenRouterStreamParser (Integration Level)");
65
+ // Test Llama 3 Tool Call Parsing
66
+ // Llama 3 format: <|tool_call_begin|> function_name <|tool_call_argument_begin|> {args} <|tool_call_end|>
67
+ const parserTests = [
68
+ {
69
+ name: "Llama 3 Full Tool Call",
70
+ chunks: [
71
+ "Some text ",
72
+ "<|tool_call_begin|> functions.weather_lookup <|tool_call_argument_begin|> ",
73
+ "{\"city\": \"Paris\"}",
74
+ " <|tool_call_end|>"
75
+ ],
76
+ expectTool: "weather_lookup"
77
+ },
78
+ {
79
+ name: "Llama 3 Split Across Chunks",
80
+ chunks: [
81
+ "Text <|tool_call_", "begin|> functions.calculator ",
82
+ "<|tool_call_argument_", "begin|> {\"expression\": \"2+", "2\"} <|tool_call_end|>"
83
+ ],
84
+ expectTool: "calculator"
85
+ },
86
+ {
87
+ name: "Multiple Tags in One Chunk",
88
+ chunks: [
89
+ "<|tool_call_begin|> tool1 <|tool_call_argument_begin|> {} <|tool_call_end|><|tool_call_begin|> tool2 <|tool_call_argument_begin|> {} <|tool_call_end|>"
90
+ ],
91
+ expectTool: "tool2" // The test loop picks the last one or we can check count
92
+ },
93
+ {
94
+ name: "Messy Llama 3 (Plural & Missing Argument Tag)",
95
+ chunks: [
96
+ "<|tool_call_begin|> functions.test_tool <|tool_call_arguments_begin|> {\"key\": \"value\"} <|tool_call_end|>",
97
+ "<|tool_call_begin|> direct_tool {\"foo\": \"bar\"} <|tool_call_end|>"
98
+ ],
99
+ expectTool: "direct_tool"
100
+ },
101
+ {
102
+ name: "Standard Content (No Tools)",
103
+ chunks: ["Just text"],
104
+ expectTool: null
105
+ },
106
+ {
107
+ name: "Markdown JSON (No Tags) - REPRODUCTION",
108
+ chunks: [
109
+ "I will read the file.\n",
110
+ "```json\n",
111
+ "{\"name\": \"read_file\", \"input\": {\"path\": \"foo.ts\"}}\n",
112
+ "```"
113
+ ],
114
+ expectTool: "read_file"
115
+ },
116
+ {
117
+ name: "Non-tool tags shouldn't be swallowed",
118
+ chunks: ["I have a plan:\n", "<Plan>\n", "1. Search\n", "2. Replace\n", "</Plan>\n", "Proceeding now."],
119
+ expectText: "I have a plan:\n<Plan>\n1. Search\n2. Replace\n</Plan>\nProceeding now."
120
+ },
121
+ {
122
+ name: "Truncated buffer should flush as text",
123
+ chunks: ["Starting tool...\n", "<tool>\n", "{\"name\": \"incomplete\""],
124
+ expectText: "Starting tool...\n<tool>\n{\"name\": \"incomplete\""
125
+ }
126
+ ];
127
+ passed = 0;
128
+ for (const test of parserTests) {
129
+ console.log(`Test: ${test.name}`);
130
+ const parser = new OpenRouterStreamParser();
131
+ let foundTools = [];
132
+ let emittedText = "";
133
+ let fullContent = "";
134
+ for (const chunk of test.chunks) {
135
+ fullContent += chunk;
136
+ const events = parser.processContent(chunk);
137
+ for (const event of events) {
138
+ if (event.type === 'tool_call_delta') {
139
+ if (event.name && !foundTools.includes(event.name)) {
140
+ foundTools.push(event.name);
141
+ }
142
+ }
143
+ if (event.type === 'content_delta') {
144
+ emittedText += event.text;
145
+ }
146
+ }
147
+ }
148
+ // Finalize parser
149
+ const finalEvents = parser.finalize(fullContent);
150
+ for (const event of finalEvents) {
151
+ if (event.type === 'tool_call_delta') {
152
+ if (event.name && !foundTools.includes(event.name)) {
153
+ foundTools.push(event.name);
154
+ }
155
+ }
156
+ if (event.type === 'content_delta') {
157
+ emittedText += event.text;
158
+ }
159
+ }
160
+ if (test.expectTool) {
161
+ if (foundTools.includes(test.expectTool)) {
162
+ console.log(` PASS: Detected tool '${test.expectTool}'`);
163
+ passed++;
164
+ }
165
+ else {
166
+ console.log(` FAIL: Expected '${test.expectTool}', found [${foundTools.join(', ')}]`);
167
+ }
168
+ }
169
+ else if (test.expectText) {
170
+ if (emittedText.trim() === test.expectText.trim()) {
171
+ console.log(" PASS: Text emitted correctly");
172
+ passed++;
173
+ }
174
+ else {
175
+ console.log(` FAIL: Text mismatch.\n Expected: [${test.expectText.trim()}]\n Got: [${emittedText.trim()}]`);
176
+ }
177
+ }
178
+ else {
179
+ if (foundTools.length === 0) {
180
+ console.log(" PASS: No tool detected");
181
+ passed++;
182
+ }
183
+ else {
184
+ console.log(` FAIL: Unexpected tool(s) found: [${foundTools.join(', ')}]`);
185
+ }
186
+ }
187
+ }
188
+ console.log(`Suite 2 Results: ${passed}/${parserTests.length} Passed\n`);
189
+ }
190
+ runTests();
191
+ //# sourceMappingURL=test_streaming_fragility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_streaming_fragility.js","sourceRoot":"","sources":["../src/test_streaming_fragility.ts"],"names":[],"mappings":"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"}