@noorm/marie-cli 0.1.15 → 0.1.17

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 (103) hide show
  1. package/.marie_visual_verify_1771225696548/progress_bar_check.txt +1 -0
  2. package/SENTINEL.md +33 -0
  3. package/dist/cli-new/components/App.js +3 -1
  4. package/dist/cli-new/components/App.js.map +1 -1
  5. package/dist/cli-new/components/Banner.js +5 -5
  6. package/dist/cli-new/components/Banner.js.map +1 -1
  7. package/dist/cli-new/hooks/useUpdateCheck.js +17 -0
  8. package/dist/cli-new/hooks/useUpdateCheck.js.map +1 -0
  9. package/dist/domain/DomainEntity.js +7 -0
  10. package/dist/domain/DomainEntity.js.map +1 -0
  11. package/dist/extension.cjs +164 -154
  12. package/dist/extension.js +473 -0
  13. package/dist/extension.js.map +1 -0
  14. package/dist/infrastructure/BaseAdapter.js +3 -0
  15. package/dist/infrastructure/BaseAdapter.js.map +1 -0
  16. package/dist/monolith/cli/CliFileSystemPort.js +16 -8
  17. package/dist/monolith/cli/CliFileSystemPort.js.map +1 -1
  18. package/dist/monolith/cli/MarieToolDefinitionsCLI.js +9 -6
  19. package/dist/monolith/cli/MarieToolDefinitionsCLI.js.map +1 -1
  20. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js +1 -1
  21. package/dist/monolith/cli/services/JoyAutomationServiceCLI.js.map +1 -1
  22. package/dist/monolith/infrastructure/ai/core/MarieEngine.js +29 -10
  23. package/dist/monolith/infrastructure/ai/core/MarieEngine.js.map +1 -1
  24. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js +19 -13
  25. package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js.map +1 -1
  26. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js +8 -8
  27. package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js.map +1 -1
  28. package/dist/monolith/infrastructure/config/ConfigService.js +2 -22
  29. package/dist/monolith/infrastructure/config/ConfigService.js.map +1 -1
  30. package/dist/monolith/infrastructure/joy/JoyTools.js +535 -0
  31. package/dist/monolith/infrastructure/joy/JoyTools.js.map +1 -0
  32. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js +14 -13
  33. package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js.map +1 -1
  34. package/dist/monolith/plumbing/analysis/MarieSentinelService.js +23 -3
  35. package/dist/monolith/plumbing/analysis/MarieSentinelService.js.map +1 -1
  36. package/dist/monolith/plumbing/analysis/TestService.js +2 -1
  37. package/dist/monolith/plumbing/analysis/TestService.js.map +1 -1
  38. package/dist/monolith/plumbing/filesystem/FileService.js +22 -10
  39. package/dist/monolith/plumbing/filesystem/FileService.js.map +1 -1
  40. package/dist/monolith/plumbing/utils/EnvironmentUtils.js +59 -0
  41. package/dist/monolith/plumbing/utils/EnvironmentUtils.js.map +1 -0
  42. package/dist/monolith/plumbing/utils/MutexUtils.js +86 -0
  43. package/dist/monolith/plumbing/utils/MutexUtils.js.map +1 -0
  44. package/dist/monolith/runtime/MarieRuntime.js +250 -136
  45. package/dist/monolith/runtime/MarieRuntime.js.map +1 -1
  46. package/dist/monolith/runtime/RuntimeAdapterBase.js +6 -0
  47. package/dist/monolith/runtime/RuntimeAdapterBase.js.map +1 -1
  48. package/dist/monolith/services/JoyAutomationService.js +1 -1
  49. package/dist/monolith/services/JoyAutomationService.js.map +1 -1
  50. package/dist/monolith/services/JoyService.js +1 -1
  51. package/dist/monolith/services/JoyService.js.map +1 -1
  52. package/dist/monolith/services/UpdateService.js +61 -0
  53. package/dist/monolith/services/UpdateService.js.map +1 -0
  54. package/dist/plumbing/BaseTool.js +7 -0
  55. package/dist/plumbing/BaseTool.js.map +1 -0
  56. package/dist/prompts.js +90 -0
  57. package/dist/prompts.js.map +1 -0
  58. package/dist/test_agent_stream_control_plane.js +170 -0
  59. package/dist/test_agent_stream_control_plane.js.map +1 -0
  60. package/dist/test_content_buffer_cap.js +67 -0
  61. package/dist/test_content_buffer_cap.js.map +1 -0
  62. package/dist/test_prefix_tree.js +120 -0
  63. package/dist/test_prefix_tree.js.map +1 -0
  64. package/dist/test_retry_utils.js +169 -0
  65. package/dist/test_retry_utils.js.map +1 -0
  66. package/dist/test_strategy_integration.js +114 -0
  67. package/dist/test_strategy_integration.js.map +1 -0
  68. package/dist/test_streaming_fragility.js +191 -0
  69. package/dist/test_streaming_fragility.js.map +1 -0
  70. package/dist/webview-ui/App.js +16 -0
  71. package/dist/webview-ui/App.js.map +1 -0
  72. package/dist/webview-ui/Providers.js +6 -0
  73. package/dist/webview-ui/Providers.js.map +1 -0
  74. package/dist/webview-ui/components/ApprovalPanel.js +8 -0
  75. package/dist/webview-ui/components/ApprovalPanel.js.map +1 -0
  76. package/dist/webview-ui/components/ChatPanel.js +19 -0
  77. package/dist/webview-ui/components/ChatPanel.js.map +1 -0
  78. package/dist/webview-ui/components/Composer.js +19 -0
  79. package/dist/webview-ui/components/Composer.js.map +1 -0
  80. package/dist/webview-ui/components/HeaderBar.js +5 -0
  81. package/dist/webview-ui/components/HeaderBar.js.map +1 -0
  82. package/dist/webview-ui/components/SessionList.js +14 -0
  83. package/dist/webview-ui/components/SessionList.js.map +1 -0
  84. package/dist/webview-ui/context/WebviewStateContext.js +146 -0
  85. package/dist/webview-ui/context/WebviewStateContext.js.map +1 -0
  86. package/dist/webview-ui/main.css +1 -0
  87. package/dist/webview-ui/main.js +108 -0
  88. package/dist/webview-ui/main.js.map +1 -0
  89. package/dist/webview-ui/types.js +2 -0
  90. package/dist/webview-ui/types.js.map +1 -0
  91. package/dist/webview-ui/vscode.js +4 -0
  92. package/dist/webview-ui/vscode.js.map +1 -0
  93. package/lint_output.txt +705 -0
  94. package/lint_output_v2.txt +711 -0
  95. package/marie-coder-0.1.16.vsix +0 -0
  96. package/package.json +3 -10
  97. package/JOY_ZONING.md +0 -200
  98. package/dist/monolith/tests/FileAppendVerifyTest.js +0 -28
  99. package/dist/monolith/tests/FileAppendVerifyTest.js.map +0 -1
  100. package/dist/monolith/tests/StreamingVerifyTest.js +0 -100
  101. package/dist/monolith/tests/StreamingVerifyTest.js.map +0 -1
  102. package/dist/monolith/tests/VisualProgressTest.js +0 -86
  103. package/dist/monolith/tests/VisualProgressTest.js.map +0 -1
@@ -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":"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"}
@@ -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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"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Providers } from "./Providers.js";
3
+ import { ApprovalPanel } from "./components/ApprovalPanel.js";
4
+ import { ChatPanel } from "./components/ChatPanel.js";
5
+ import { Composer } from "./components/Composer.js";
6
+ import { HeaderBar } from "./components/HeaderBar.js";
7
+ import { SessionList } from "./components/SessionList.js";
8
+ import { useWebviewState } from "./context/WebviewStateContext.js";
9
+ function AppContent() {
10
+ const { state, actions } = useWebviewState();
11
+ return (_jsxs("div", { className: "layout", children: [_jsx(SessionList, { sessions: state.sessions, currentSessionId: state.currentSessionId, onLoad: actions.loadSession, onCreate: actions.createSession, onRefresh: actions.refreshSessions }), _jsxs("main", { className: "right", children: [_jsx(HeaderBar, { config: state.config, isLoading: state.isLoading, onAutonomyMode: actions.setAutonomyMode, onClear: actions.clearSession, onStop: actions.stopGeneration, onSettings: actions.openSettings }), _jsx(ChatPanel, { messages: state.messages, streamingBuffer: state.streamingBuffer }), _jsx(ApprovalPanel, { pendingApproval: state.pendingApproval, onApprove: actions.approveTool }), _jsx(Composer, { isLoading: state.isLoading, onSend: actions.sendMessage, onModels: actions.getModels })] })] }));
12
+ }
13
+ export default function App() {
14
+ return (_jsx(Providers, { children: _jsx(AppContent, {}) }));
15
+ }
16
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/webview-ui/App.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA;AAElE,SAAS,UAAU;IACf,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,eAAe,EAAE,CAAA;IAE5C,OAAO,CACH,eAAK,SAAS,EAAC,QAAQ,aACnB,KAAC,WAAW,IACR,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EACxC,MAAM,EAAE,OAAO,CAAC,WAAW,EAC3B,QAAQ,EAAE,OAAO,CAAC,aAAa,EAC/B,SAAS,EAAE,OAAO,CAAC,eAAe,GACpC,EAEF,gBAAM,SAAS,EAAC,OAAO,aACnB,KAAC,SAAS,IACN,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,cAAc,EAAE,OAAO,CAAC,eAAe,EACvC,OAAO,EAAE,OAAO,CAAC,YAAY,EAC7B,MAAM,EAAE,OAAO,CAAC,cAAc,EAC9B,UAAU,EAAE,OAAO,CAAC,YAAY,GAClC,EAEF,KAAC,SAAS,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,GAAI,EAE/E,KAAC,aAAa,IAAC,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,GAAI,EAEzF,KAAC,QAAQ,IAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,GAAI,IAC/F,IACL,CACT,CAAA;AACL,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,GAAG;IACvB,OAAO,CACH,KAAC,SAAS,cACN,KAAC,UAAU,KAAG,GACN,CACf,CAAA;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { WebviewStateProvider } from "./context/WebviewStateContext.js";
3
+ export function Providers({ children }) {
4
+ return _jsx(WebviewStateProvider, { children: children });
5
+ }
6
+ //# sourceMappingURL=Providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Providers.js","sourceRoot":"","sources":["../../src/webview-ui/Providers.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAEvE,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAA2B;IAC3D,OAAO,KAAC,oBAAoB,cAAE,QAAQ,GAAwB,CAAA;AAClE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function ApprovalPanel({ pendingApproval, onApprove, }) {
3
+ if (!pendingApproval) {
4
+ return null;
5
+ }
6
+ return (_jsxs("div", { className: "approval", children: [_jsx("strong", { children: "Approval required" }), _jsxs("div", { children: ["Tool: ", _jsx("code", { children: pendingApproval.toolName })] }), _jsx("pre", { children: JSON.stringify(pendingApproval.toolInput, null, 2) }), _jsxs("div", { className: "row", children: [_jsx("button", { onClick: () => onApprove(true), children: "Approve" }), _jsx("button", { onClick: () => onApprove(false), children: "Deny" })] })] }));
7
+ }
8
+ //# sourceMappingURL=ApprovalPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApprovalPanel.js","sourceRoot":"","sources":["../../../src/webview-ui/components/ApprovalPanel.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,aAAa,CAAC,EAC1B,eAAe,EACf,SAAS,GAIZ;IACG,IAAI,CAAC,eAAe,EAAE,CAAC;QACnB,OAAO,IAAI,CAAA;IACf,CAAC;IAED,OAAO,CACH,eAAK,SAAS,EAAC,UAAU,aACrB,iDAAkC,EAClC,oCACU,yBAAO,eAAe,CAAC,QAAQ,GAAQ,IAC3C,EACN,wBAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAO,EAC/D,eAAK,SAAS,EAAC,KAAK,aAChB,iBAAQ,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,wBAAkB,EACxD,iBAAQ,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAe,IACpD,IACJ,CACT,CAAA;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from "react";
3
+ function roleLabel(role) {
4
+ if (role === "assistant")
5
+ return "Marie";
6
+ if (role === "user")
7
+ return "You";
8
+ return "System";
9
+ }
10
+ export function ChatPanel({ messages, streamingBuffer, }) {
11
+ const chatRef = useRef(null);
12
+ useEffect(() => {
13
+ if (chatRef.current) {
14
+ chatRef.current.scrollTop = chatRef.current.scrollHeight;
15
+ }
16
+ }, [messages, streamingBuffer]);
17
+ return (_jsxs("section", { className: "chat", ref: chatRef, children: [messages.map((message) => (_jsxs("div", { className: `msg ${message.role}`, children: [_jsx("div", { className: "role", children: roleLabel(message.role) }), _jsx("pre", { children: message.content })] }, message.id))), streamingBuffer && (_jsxs("div", { className: "msg assistant stream", children: [_jsx("div", { className: "role", children: "Marie" }), _jsx("pre", { children: streamingBuffer })] }))] }));
18
+ }
19
+ //# sourceMappingURL=ChatPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPanel.js","sourceRoot":"","sources":["../../../src/webview-ui/components/ChatPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAGzC,SAAS,SAAS,CAAC,IAAuB;IACtC,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,OAAO,CAAA;IACxC,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAA;IACjC,OAAO,QAAQ,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EACtB,QAAQ,EACR,eAAe,GAIlB;IACG,MAAM,OAAO,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAA;IAEnD,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAA;QAC5D,CAAC;IACL,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAA;IAE/B,OAAO,CACH,mBAAS,SAAS,EAAC,MAAM,EAAC,GAAG,EAAE,OAAO,aACjC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CACvB,eAAK,SAAS,EAAE,OAAO,OAAO,CAAC,IAAI,EAAE,aACjC,cAAK,SAAS,EAAC,MAAM,YAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAO,EACrD,wBAAM,OAAO,CAAC,OAAO,GAAO,KAFY,OAAO,CAAC,EAAE,CAGhD,CACT,CAAC,EACD,eAAe,IAAI,CAChB,eAAK,SAAS,EAAC,sBAAsB,aACjC,cAAK,SAAS,EAAC,MAAM,sBAAY,EACjC,wBAAM,eAAe,GAAO,IAC1B,CACT,IACK,CACb,CAAA;AACL,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ export function Composer({ isLoading, onSend, onModels, }) {
4
+ const [input, setInput] = useState("");
5
+ const submit = () => {
6
+ const text = input.trim();
7
+ if (!text)
8
+ return;
9
+ setInput("");
10
+ onSend(text);
11
+ };
12
+ return (_jsxs("footer", { className: "composer", children: [_jsx("textarea", { value: input, onChange: (e) => setInput(e.target.value), onKeyDown: (e) => {
13
+ if (e.key === "Enter" && !e.shiftKey) {
14
+ e.preventDefault();
15
+ submit();
16
+ }
17
+ }, placeholder: "Ask Marie\u2026" }), _jsxs("div", { className: "stack", children: [_jsx("button", { onClick: submit, disabled: isLoading, children: "Send" }), _jsx("button", { onClick: onModels, className: "secondary", children: "Models" })] })] }));
18
+ }
19
+ //# sourceMappingURL=Composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Composer.js","sourceRoot":"","sources":["../../../src/webview-ui/components/Composer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,MAAM,UAAU,QAAQ,CAAC,EACrB,SAAS,EACT,MAAM,EACN,QAAQ,GAKX;IACG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEtC,MAAM,MAAM,GAAG,GAAG,EAAE;QAChB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QACzB,IAAI,CAAC,IAAI;YAAE,OAAM;QACjB,QAAQ,CAAC,EAAE,CAAC,CAAA;QACZ,MAAM,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC,CAAA;IAED,OAAO,CACH,kBAAQ,SAAS,EAAC,UAAU,aACxB,mBACI,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;oBACb,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;wBACnC,CAAC,CAAC,cAAc,EAAE,CAAA;wBAClB,MAAM,EAAE,CAAA;oBACZ,CAAC;gBACL,CAAC,EACD,WAAW,EAAC,iBAAY,GAC1B,EACF,eAAK,SAAS,EAAC,OAAO,aAClB,iBAAQ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,qBAEnC,EACT,iBAAQ,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAC,WAAW,uBAEvC,IACP,IACD,CACZ,CAAA;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function HeaderBar({ config, isLoading, onAutonomyMode, onClear, onStop, onSettings, }) {
3
+ return (_jsxs("header", { className: "top", children: [_jsxs("div", { children: [_jsxs("div", { children: [_jsx("strong", { children: "Marie" }), " \u00B7 ", config.provider, " \u00B7 ", config.model] }), _jsxs("div", { className: "muted", children: ["Spirit Pressure: ", config.autonomyMode === 'ascension' ? 'ASCENDANT' : config.autonomyMode, isLoading ? " · Running…" : ""] })] }), _jsxs("div", { className: "row", children: [_jsxs("select", { value: config.autonomyMode, onChange: (e) => onAutonomyMode(e.target.value), children: [_jsx("option", { value: "balanced", children: "balanced" }), _jsx("option", { value: "high", children: "high" }), _jsx("option", { value: "ascension", children: "ascension" })] }), _jsx("button", { onClick: onClear, className: "secondary", children: "Clear" }), _jsx("button", { onClick: onStop, className: "secondary", children: "Stop" }), _jsx("button", { onClick: onSettings, className: "secondary", children: "Settings" })] })] }));
4
+ }
5
+ //# sourceMappingURL=HeaderBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeaderBar.js","sourceRoot":"","sources":["../../../src/webview-ui/components/HeaderBar.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,SAAS,CAAC,EACtB,MAAM,EACN,SAAS,EACT,cAAc,EACd,OAAO,EACP,MAAM,EACN,UAAU,GAQb;IACG,OAAO,CACH,kBAAQ,SAAS,EAAC,KAAK,aACnB,0BACI,0BACI,qCAAsB,cAAI,MAAM,CAAC,QAAQ,cAAK,MAAM,CAAC,KAAK,IACxD,EACN,eAAK,SAAS,EAAC,OAAO,kCAAmB,MAAM,CAAC,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,IAAO,IACrJ,EACN,eAAK,SAAS,EAAC,KAAK,aAChB,kBAAQ,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,aAC/E,iBAAQ,KAAK,EAAC,UAAU,yBAAkB,EAC1C,iBAAQ,KAAK,EAAC,MAAM,qBAAc,EAClC,iBAAQ,KAAK,EAAC,WAAW,0BAAmB,IACvC,EACT,iBAAQ,OAAO,EAAE,OAAO,EAAE,SAAS,EAAC,WAAW,sBAEtC,EACT,iBAAQ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAC,WAAW,qBAErC,EACT,iBAAQ,OAAO,EAAE,UAAU,EAAE,SAAS,EAAC,WAAW,yBAEzC,IACP,IACD,CACZ,CAAA;AACL,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ function formatSessionDate(timestamp) {
3
+ try {
4
+ return new Date(timestamp).toLocaleDateString();
5
+ }
6
+ catch {
7
+ return "";
8
+ }
9
+ }
10
+ export function SessionList({ sessions, currentSessionId, onLoad, onCreate, onRefresh, }) {
11
+ const sorted = [...sessions].sort((a, b) => Number(b.isPinned) - Number(a.isPinned) || b.lastModified - a.lastModified);
12
+ return (_jsxs("aside", { className: "left stack", children: [_jsxs("div", { className: "row", children: [_jsx("button", { onClick: onCreate, children: "New" }), _jsx("button", { onClick: onRefresh, className: "secondary", children: "Refresh" })] }), _jsx("div", { className: "muted", children: "Sessions" }), _jsxs("div", { className: "stack", children: [sorted.length === 0 && _jsx("div", { className: "muted", children: "No sessions" }), sorted.map((session) => (_jsxs("button", { onClick: () => onLoad(session.id), className: `session ${session.id === currentSessionId ? "active" : ""}`, children: [_jsxs("span", { children: [session.isPinned ? "📌 " : "", session.title || "New Session"] }), _jsx("span", { className: "muted", children: formatSessionDate(session.lastModified) })] }, session.id)))] })] }));
13
+ }
14
+ //# sourceMappingURL=SessionList.js.map