@probelabs/probe-chat 0.6.0-rc100
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.
- package/README.md +338 -0
- package/TRACING.md +226 -0
- package/appTracer.js +947 -0
- package/auth.js +76 -0
- package/bin/probe-chat.js +13 -0
- package/cancelRequest.js +84 -0
- package/fileSpanExporter.js +183 -0
- package/implement/README.md +228 -0
- package/implement/backends/AiderBackend.js +750 -0
- package/implement/backends/BaseBackend.js +276 -0
- package/implement/backends/ClaudeCodeBackend.js +767 -0
- package/implement/backends/MockBackend.js +237 -0
- package/implement/backends/registry.js +85 -0
- package/implement/core/BackendManager.js +567 -0
- package/implement/core/ImplementTool.js +354 -0
- package/implement/core/config.js +428 -0
- package/implement/core/timeouts.js +58 -0
- package/implement/core/utils.js +496 -0
- package/implement/types/BackendTypes.js +126 -0
- package/index.html +3751 -0
- package/index.js +582 -0
- package/logo.png +0 -0
- package/package.json +101 -0
- package/probeChat.js +269 -0
- package/probeTool.js +714 -0
- package/storage/JsonChatStorage.js +476 -0
- package/telemetry.js +287 -0
- package/test/integration/chatFlows.test.js +320 -0
- package/test/integration/toolCalling.test.js +471 -0
- package/test/mocks/mockLLMProvider.js +269 -0
- package/test/test-backends.js +90 -0
- package/test/testUtils.js +530 -0
- package/test/unit/backendTimeout.test.js +161 -0
- package/test/verify-tests.js +118 -0
- package/tokenCounter.js +419 -0
- package/tokenUsageDisplay.js +134 -0
- package/tools.js +186 -0
- package/webServer.js +1103 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import BaseBackend from './BaseBackend.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Mock backend for testing the implement tool functionality
|
|
5
|
+
*/
|
|
6
|
+
class MockBackend extends BaseBackend {
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.name = 'mock';
|
|
10
|
+
this.displayName = 'Mock Backend';
|
|
11
|
+
this.description = 'A mock backend for testing purposes';
|
|
12
|
+
this.supportedLanguages = ['javascript', 'typescript', 'python', 'rust', 'go', 'java', 'cpp', 'csharp', 'ruby', 'php', 'swift'];
|
|
13
|
+
this.supportedFeatures = {
|
|
14
|
+
streaming: true,
|
|
15
|
+
rollback: true,
|
|
16
|
+
directFileEdit: true,
|
|
17
|
+
gitIntegration: true,
|
|
18
|
+
webSearch: true,
|
|
19
|
+
multiFile: true,
|
|
20
|
+
planning: true,
|
|
21
|
+
testing: true
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Test configuration
|
|
25
|
+
this.responses = [];
|
|
26
|
+
this.currentResponseIndex = 0;
|
|
27
|
+
this.simulateErrors = false;
|
|
28
|
+
this.simulateTimeout = false;
|
|
29
|
+
this.responseDelay = 100; // ms
|
|
30
|
+
this.capturedRequests = [];
|
|
31
|
+
this.sessionCounter = 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Test helpers
|
|
35
|
+
reset() {
|
|
36
|
+
this.responses = [];
|
|
37
|
+
this.currentResponseIndex = 0;
|
|
38
|
+
this.simulateErrors = false;
|
|
39
|
+
this.simulateTimeout = false;
|
|
40
|
+
this.capturedRequests = [];
|
|
41
|
+
this.sessionCounter = 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
addResponse(response) {
|
|
45
|
+
this.responses.push(response);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setResponses(responses) {
|
|
49
|
+
this.responses = responses;
|
|
50
|
+
this.currentResponseIndex = 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getNextResponse() {
|
|
54
|
+
if (this.responses.length === 0) {
|
|
55
|
+
return this.generateDefaultResponse();
|
|
56
|
+
}
|
|
57
|
+
const response = this.responses[this.currentResponseIndex];
|
|
58
|
+
this.currentResponseIndex = (this.currentResponseIndex + 1) % this.responses.length;
|
|
59
|
+
return response;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
generateDefaultResponse() {
|
|
63
|
+
return {
|
|
64
|
+
type: 'progress',
|
|
65
|
+
message: 'Mock backend processing request',
|
|
66
|
+
details: {
|
|
67
|
+
status: 'complete',
|
|
68
|
+
filesModified: ['mock-file.js'],
|
|
69
|
+
summary: 'Successfully processed mock request'
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async checkAvailability() {
|
|
75
|
+
// Always available unless configured otherwise
|
|
76
|
+
if (this.simulateErrors) {
|
|
77
|
+
return {
|
|
78
|
+
available: false,
|
|
79
|
+
reason: 'Mock backend configured to simulate unavailability'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
available: true,
|
|
84
|
+
version: '1.0.0-mock'
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async checkHealth() {
|
|
89
|
+
if (this.simulateErrors) {
|
|
90
|
+
return {
|
|
91
|
+
healthy: false,
|
|
92
|
+
status: 'error',
|
|
93
|
+
message: 'Mock backend configured to simulate unhealthy state'
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
healthy: true,
|
|
98
|
+
status: 'ready',
|
|
99
|
+
details: {
|
|
100
|
+
mockSessions: this.sessionCounter,
|
|
101
|
+
capturedRequests: this.capturedRequests.length
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
validateRequest(request) {
|
|
107
|
+
const errors = [];
|
|
108
|
+
|
|
109
|
+
if (!request.request || typeof request.request !== 'string') {
|
|
110
|
+
errors.push('Request must include a "request" field with the implementation request');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (this.simulateErrors && request.request && request.request.includes('error')) {
|
|
114
|
+
errors.push('Mock backend configured to reject requests containing "error"');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return errors;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async implement(request, options = {}) {
|
|
121
|
+
this.capturedRequests.push({ request, options, timestamp: Date.now() });
|
|
122
|
+
|
|
123
|
+
// Simulate timeout
|
|
124
|
+
if (this.simulateTimeout) {
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 60000));
|
|
126
|
+
throw new Error('Mock backend timeout');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Simulate errors
|
|
130
|
+
if (this.simulateErrors) {
|
|
131
|
+
throw new Error('Mock backend configured to simulate error');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const sessionId = `mock-session-${++this.sessionCounter}`;
|
|
135
|
+
const response = this.getNextResponse();
|
|
136
|
+
|
|
137
|
+
// Handle dry run
|
|
138
|
+
if (options.dryRun) {
|
|
139
|
+
return {
|
|
140
|
+
sessionId,
|
|
141
|
+
status: 'dry-run',
|
|
142
|
+
plan: response.plan || 'Mock implementation plan:\n1. Analyze request\n2. Generate code\n3. Apply changes',
|
|
143
|
+
estimatedFiles: response.estimatedFiles || ['mock-file.js'],
|
|
144
|
+
estimatedComplexity: response.estimatedComplexity || 'low'
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Simulate streaming responses
|
|
149
|
+
if (options.onProgress && response.stream) {
|
|
150
|
+
for (const chunk of response.stream) {
|
|
151
|
+
await new Promise(resolve => setTimeout(resolve, this.responseDelay));
|
|
152
|
+
options.onProgress(chunk);
|
|
153
|
+
}
|
|
154
|
+
} else if (options.onProgress) {
|
|
155
|
+
// Default streaming behavior
|
|
156
|
+
await new Promise(resolve => setTimeout(resolve, this.responseDelay));
|
|
157
|
+
options.onProgress({
|
|
158
|
+
type: 'start',
|
|
159
|
+
message: 'Mock backend starting implementation'
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
await new Promise(resolve => setTimeout(resolve, this.responseDelay));
|
|
163
|
+
options.onProgress({
|
|
164
|
+
type: 'progress',
|
|
165
|
+
message: 'Analyzing request and generating code'
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await new Promise(resolve => setTimeout(resolve, this.responseDelay));
|
|
169
|
+
options.onProgress({
|
|
170
|
+
type: 'file_update',
|
|
171
|
+
file: response.file || 'mock-file.js',
|
|
172
|
+
action: 'modified',
|
|
173
|
+
content: response.content || '// Mock generated code\nconsole.log("Hello from mock backend!");'
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await new Promise(resolve => setTimeout(resolve, this.responseDelay));
|
|
177
|
+
options.onProgress({
|
|
178
|
+
type: 'complete',
|
|
179
|
+
message: 'Implementation complete'
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Return final result
|
|
184
|
+
return {
|
|
185
|
+
sessionId,
|
|
186
|
+
status: 'success',
|
|
187
|
+
filesModified: response.filesModified || ['mock-file.js'],
|
|
188
|
+
summary: response.summary || 'Mock implementation completed successfully',
|
|
189
|
+
details: response.details || {
|
|
190
|
+
linesAdded: 10,
|
|
191
|
+
linesRemoved: 2,
|
|
192
|
+
filesCreated: 0,
|
|
193
|
+
filesModified: 1
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async cancelSession(sessionId) {
|
|
199
|
+
return {
|
|
200
|
+
sessionId,
|
|
201
|
+
status: 'cancelled',
|
|
202
|
+
message: 'Mock session cancelled'
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async getSessionStatus(sessionId) {
|
|
207
|
+
return {
|
|
208
|
+
sessionId,
|
|
209
|
+
status: 'completed',
|
|
210
|
+
progress: 100,
|
|
211
|
+
message: 'Mock session completed'
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Test-specific methods
|
|
216
|
+
getLastRequest() {
|
|
217
|
+
return this.capturedRequests[this.capturedRequests.length - 1];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
getAllRequests() {
|
|
221
|
+
return this.capturedRequests;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
setErrorMode(enabled) {
|
|
225
|
+
this.simulateErrors = enabled;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
setTimeoutMode(enabled) {
|
|
229
|
+
this.simulateTimeout = enabled;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
setResponseDelay(delay) {
|
|
233
|
+
this.responseDelay = delay;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export default MockBackend;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend registry for automatic discovery and registration
|
|
3
|
+
* @module registry
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import AiderBackend from './AiderBackend.js';
|
|
7
|
+
import ClaudeCodeBackend from './ClaudeCodeBackend.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Available backend classes
|
|
11
|
+
*/
|
|
12
|
+
const AVAILABLE_BACKENDS = {
|
|
13
|
+
aider: AiderBackend,
|
|
14
|
+
'claude-code': ClaudeCodeBackend
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get all available backend classes
|
|
19
|
+
* @returns {Object<string, typeof BaseBackend>}
|
|
20
|
+
*/
|
|
21
|
+
function getAvailableBackends() {
|
|
22
|
+
return { ...AVAILABLE_BACKENDS };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Create a backend instance by name
|
|
27
|
+
* @param {string} name - Backend name
|
|
28
|
+
* @returns {BaseBackend|null}
|
|
29
|
+
*/
|
|
30
|
+
function createBackend(name) {
|
|
31
|
+
const BackendClass = AVAILABLE_BACKENDS[name];
|
|
32
|
+
if (!BackendClass) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return new BackendClass();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Register a custom backend class
|
|
41
|
+
* @param {string} name - Backend name
|
|
42
|
+
* @param {typeof BaseBackend} BackendClass - Backend class
|
|
43
|
+
*/
|
|
44
|
+
function registerBackend(name, BackendClass) {
|
|
45
|
+
AVAILABLE_BACKENDS[name] = BackendClass;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get backend metadata
|
|
50
|
+
* @param {string} name - Backend name
|
|
51
|
+
* @returns {Object|null}
|
|
52
|
+
*/
|
|
53
|
+
function getBackendMetadata(name) {
|
|
54
|
+
const backend = createBackend(name);
|
|
55
|
+
if (!backend) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
name: backend.name,
|
|
61
|
+
version: backend.version,
|
|
62
|
+
description: backend.getDescription(),
|
|
63
|
+
capabilities: backend.getCapabilities(),
|
|
64
|
+
dependencies: backend.getRequiredDependencies()
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* List all registered backend names
|
|
70
|
+
* @returns {string[]}
|
|
71
|
+
*/
|
|
72
|
+
function listBackendNames() {
|
|
73
|
+
return Object.keys(AVAILABLE_BACKENDS);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
getAvailableBackends,
|
|
78
|
+
createBackend,
|
|
79
|
+
registerBackend,
|
|
80
|
+
getBackendMetadata,
|
|
81
|
+
listBackendNames,
|
|
82
|
+
// Export backend classes for direct use
|
|
83
|
+
AiderBackend,
|
|
84
|
+
ClaudeCodeBackend
|
|
85
|
+
};
|