@probelabs/probe 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 +583 -0
- package/bin/.gitkeep +0 -0
- package/bin/probe +158 -0
- package/bin/probe-binary +0 -0
- package/build/agent/ProbeAgent.d.ts +199 -0
- package/build/agent/ProbeAgent.js +1486 -0
- package/build/agent/acp/README.md +347 -0
- package/build/agent/acp/connection.js +237 -0
- package/build/agent/acp/connection.test.js +311 -0
- package/build/agent/acp/examples/simple-client.js +212 -0
- package/build/agent/acp/examples/tool-lifecycle.js +230 -0
- package/build/agent/acp/final-test.js +173 -0
- package/build/agent/acp/index.js +5 -0
- package/build/agent/acp/integration.test.js +385 -0
- package/build/agent/acp/manual-test.js +410 -0
- package/build/agent/acp/protocol-test.js +190 -0
- package/build/agent/acp/server.js +448 -0
- package/build/agent/acp/server.test.js +371 -0
- package/build/agent/acp/test-runner.js +216 -0
- package/build/agent/acp/test-utils/README.md +315 -0
- package/build/agent/acp/test-utils/acp-tester.js +484 -0
- package/build/agent/acp/test-utils/mock-acp-client.js +434 -0
- package/build/agent/acp/tools.js +368 -0
- package/build/agent/acp/tools.test.js +334 -0
- package/build/agent/acp/types.js +218 -0
- package/build/agent/acp/types.test.js +327 -0
- package/build/agent/appTracer.js +360 -0
- package/build/agent/fileSpanExporter.js +169 -0
- package/build/agent/index.js +7426 -0
- package/build/agent/mcp/client.js +338 -0
- package/build/agent/mcp/config.js +313 -0
- package/build/agent/mcp/index.js +64 -0
- package/build/agent/mcp/xmlBridge.js +371 -0
- package/build/agent/mockProvider.js +53 -0
- package/build/agent/probeTool.js +257 -0
- package/build/agent/schemaUtils.js +1726 -0
- package/build/agent/simpleTelemetry.js +267 -0
- package/build/agent/telemetry.js +225 -0
- package/build/agent/tokenCounter.js +395 -0
- package/build/agent/tools.js +163 -0
- package/build/cli.js +49 -0
- package/build/delegate.js +267 -0
- package/build/directory-resolver.js +237 -0
- package/build/downloader.js +750 -0
- package/build/extract.js +149 -0
- package/build/index.js +70 -0
- package/build/mcp/index.js +514 -0
- package/build/mcp/index.ts +608 -0
- package/build/query.js +116 -0
- package/build/search.js +247 -0
- package/build/tools/common.js +410 -0
- package/build/tools/index.js +40 -0
- package/build/tools/langchain.js +88 -0
- package/build/tools/system-message.js +121 -0
- package/build/tools/vercel.js +271 -0
- package/build/utils/file-lister.js +193 -0
- package/build/utils.js +128 -0
- package/cjs/agent/ProbeAgent.cjs +5829 -0
- package/cjs/index.cjs +6217 -0
- package/cjs/package.json +3 -0
- package/index.d.ts +401 -0
- package/package.json +114 -0
- package/scripts/postinstall.js +172 -0
- package/src/agent/ProbeAgent.d.ts +199 -0
- package/src/agent/ProbeAgent.js +1486 -0
- package/src/agent/acp/README.md +347 -0
- package/src/agent/acp/connection.js +237 -0
- package/src/agent/acp/connection.test.js +311 -0
- package/src/agent/acp/examples/simple-client.js +212 -0
- package/src/agent/acp/examples/tool-lifecycle.js +230 -0
- package/src/agent/acp/final-test.js +173 -0
- package/src/agent/acp/index.js +5 -0
- package/src/agent/acp/integration.test.js +385 -0
- package/src/agent/acp/manual-test.js +410 -0
- package/src/agent/acp/protocol-test.js +190 -0
- package/src/agent/acp/server.js +448 -0
- package/src/agent/acp/server.test.js +371 -0
- package/src/agent/acp/test-runner.js +216 -0
- package/src/agent/acp/test-utils/README.md +315 -0
- package/src/agent/acp/test-utils/acp-tester.js +484 -0
- package/src/agent/acp/test-utils/mock-acp-client.js +434 -0
- package/src/agent/acp/tools.js +368 -0
- package/src/agent/acp/tools.test.js +334 -0
- package/src/agent/acp/types.js +218 -0
- package/src/agent/acp/types.test.js +327 -0
- package/src/agent/appTracer.js +360 -0
- package/src/agent/fileSpanExporter.js +169 -0
- package/src/agent/index.js +813 -0
- package/src/agent/mcp/client.js +338 -0
- package/src/agent/mcp/config.js +313 -0
- package/src/agent/mcp/index.js +64 -0
- package/src/agent/mcp/xmlBridge.js +371 -0
- package/src/agent/mockProvider.js +53 -0
- package/src/agent/probeTool.js +257 -0
- package/src/agent/schemaUtils.js +1726 -0
- package/src/agent/simpleTelemetry.js +267 -0
- package/src/agent/telemetry.js +225 -0
- package/src/agent/tokenCounter.js +395 -0
- package/src/agent/tools.js +163 -0
- package/src/cli.js +49 -0
- package/src/delegate.js +267 -0
- package/src/directory-resolver.js +237 -0
- package/src/downloader.js +750 -0
- package/src/extract.js +149 -0
- package/src/index.js +70 -0
- package/src/mcp/index.ts +608 -0
- package/src/query.js +116 -0
- package/src/search.js +247 -0
- package/src/tools/common.js +410 -0
- package/src/tools/index.js +40 -0
- package/src/tools/langchain.js +88 -0
- package/src/tools/system-message.js +121 -0
- package/src/tools/vercel.js +271 -0
- package/src/utils/file-lister.js +193 -0
- package/src/utils.js +128 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// Agent Client Protocol (ACP) type definitions
|
|
2
|
+
// Based on the ACP specification from Zed Industries
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ACP Protocol Version
|
|
6
|
+
*/
|
|
7
|
+
export const ACP_PROTOCOL_VERSION = "1";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* JSON-RPC 2.0 message types
|
|
11
|
+
*/
|
|
12
|
+
export const MessageType = {
|
|
13
|
+
REQUEST: 'request',
|
|
14
|
+
RESPONSE: 'response',
|
|
15
|
+
NOTIFICATION: 'notification'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ACP Request method names
|
|
20
|
+
*/
|
|
21
|
+
export const RequestMethod = {
|
|
22
|
+
INITIALIZE: 'initialize',
|
|
23
|
+
NEW_SESSION: 'newSession',
|
|
24
|
+
LOAD_SESSION: 'loadSession',
|
|
25
|
+
SET_SESSION_MODE: 'setSessionMode',
|
|
26
|
+
PROMPT: 'prompt',
|
|
27
|
+
CANCEL: 'cancel',
|
|
28
|
+
|
|
29
|
+
// Client requests (that the agent can make to the client)
|
|
30
|
+
WRITE_TEXT_FILE: 'writeTextFile',
|
|
31
|
+
READ_TEXT_FILE: 'readTextFile',
|
|
32
|
+
REQUEST_PERMISSION: 'requestPermission',
|
|
33
|
+
CREATE_TERMINAL: 'createTerminal'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* ACP Notification method names
|
|
38
|
+
*/
|
|
39
|
+
export const NotificationMethod = {
|
|
40
|
+
SESSION_UPDATED: 'sessionUpdated',
|
|
41
|
+
TOOL_CALL_PROGRESS: 'toolCallProgress',
|
|
42
|
+
MESSAGE_CHUNK: 'messageChunk',
|
|
43
|
+
PLAN_UPDATED: 'planUpdated',
|
|
44
|
+
AVAILABLE_COMMANDS: 'availableCommands'
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Tool call status types
|
|
49
|
+
*/
|
|
50
|
+
export const ToolCallStatus = {
|
|
51
|
+
PENDING: 'pending',
|
|
52
|
+
IN_PROGRESS: 'in_progress',
|
|
53
|
+
COMPLETED: 'completed',
|
|
54
|
+
FAILED: 'failed'
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Tool call kinds
|
|
59
|
+
*/
|
|
60
|
+
export const ToolCallKind = {
|
|
61
|
+
READ: 'read',
|
|
62
|
+
edit: 'edit',
|
|
63
|
+
delete: 'delete',
|
|
64
|
+
execute: 'execute',
|
|
65
|
+
search: 'search',
|
|
66
|
+
query: 'query',
|
|
67
|
+
extract: 'extract'
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Content block types
|
|
72
|
+
*/
|
|
73
|
+
export const ContentType = {
|
|
74
|
+
TEXT: 'text',
|
|
75
|
+
IMAGE: 'image',
|
|
76
|
+
AUDIO: 'audio',
|
|
77
|
+
RESOURCE: 'resource',
|
|
78
|
+
EMBEDDED_RESOURCE: 'embedded_resource'
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Error codes (following JSON-RPC 2.0 spec)
|
|
83
|
+
*/
|
|
84
|
+
export const ErrorCode = {
|
|
85
|
+
PARSE_ERROR: -32700,
|
|
86
|
+
INVALID_REQUEST: -32600,
|
|
87
|
+
METHOD_NOT_FOUND: -32601,
|
|
88
|
+
INVALID_PARAMS: -32602,
|
|
89
|
+
INTERNAL_ERROR: -32603,
|
|
90
|
+
|
|
91
|
+
// ACP-specific errors
|
|
92
|
+
UNSUPPORTED_PROTOCOL_VERSION: -32001,
|
|
93
|
+
SESSION_NOT_FOUND: -32002,
|
|
94
|
+
PERMISSION_DENIED: -32003,
|
|
95
|
+
TOOL_EXECUTION_FAILED: -32004
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Session modes
|
|
100
|
+
*/
|
|
101
|
+
export const SessionMode = {
|
|
102
|
+
NORMAL: 'normal',
|
|
103
|
+
PLANNING: 'planning'
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create a JSON-RPC 2.0 message
|
|
108
|
+
*/
|
|
109
|
+
export function createMessage(method, params = null, id = null) {
|
|
110
|
+
const message = {
|
|
111
|
+
jsonrpc: '2.0',
|
|
112
|
+
method
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (params !== null) {
|
|
116
|
+
message.params = params;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (id !== null) {
|
|
120
|
+
message.id = id;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return message;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Create a JSON-RPC 2.0 response
|
|
128
|
+
*/
|
|
129
|
+
export function createResponse(id, result = null, error = null) {
|
|
130
|
+
const response = {
|
|
131
|
+
jsonrpc: '2.0',
|
|
132
|
+
id
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
if (error) {
|
|
136
|
+
response.error = error;
|
|
137
|
+
} else {
|
|
138
|
+
response.result = result;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return response;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Create an error object
|
|
146
|
+
*/
|
|
147
|
+
export function createError(code, message, data = null) {
|
|
148
|
+
const error = {
|
|
149
|
+
code,
|
|
150
|
+
message
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
if (data !== null) {
|
|
154
|
+
error.data = data;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return error;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Create a content block
|
|
162
|
+
*/
|
|
163
|
+
export function createContentBlock(type, content, metadata = {}) {
|
|
164
|
+
return {
|
|
165
|
+
type,
|
|
166
|
+
...content,
|
|
167
|
+
...metadata
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Create a text content block
|
|
173
|
+
*/
|
|
174
|
+
export function createTextContent(text) {
|
|
175
|
+
return createContentBlock(ContentType.TEXT, { text });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Create a tool call progress notification
|
|
180
|
+
*/
|
|
181
|
+
export function createToolCallProgress(toolCallId, status, result = null, error = null) {
|
|
182
|
+
const progress = {
|
|
183
|
+
toolCallId,
|
|
184
|
+
status
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
if (result !== null) {
|
|
188
|
+
progress.result = result;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (error !== null) {
|
|
192
|
+
progress.error = error;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return progress;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Validate JSON-RPC 2.0 message format
|
|
200
|
+
*/
|
|
201
|
+
export function validateMessage(message) {
|
|
202
|
+
if (!message || typeof message !== 'object') {
|
|
203
|
+
return { valid: false, error: 'Message must be an object' };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (message.jsonrpc !== '2.0') {
|
|
207
|
+
return { valid: false, error: 'Invalid or missing jsonrpc version' };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Request validation
|
|
211
|
+
if (message.id !== undefined) {
|
|
212
|
+
if (!message.method && !message.result && !message.error) {
|
|
213
|
+
return { valid: false, error: 'Request must have method or response must have result/error' };
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return { valid: true };
|
|
218
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
// Tests for ACP Types and Utilities
|
|
2
|
+
import {
|
|
3
|
+
ACP_PROTOCOL_VERSION,
|
|
4
|
+
MessageType,
|
|
5
|
+
RequestMethod,
|
|
6
|
+
NotificationMethod,
|
|
7
|
+
ToolCallStatus,
|
|
8
|
+
ToolCallKind,
|
|
9
|
+
ContentType,
|
|
10
|
+
ErrorCode,
|
|
11
|
+
SessionMode,
|
|
12
|
+
createMessage,
|
|
13
|
+
createResponse,
|
|
14
|
+
createError,
|
|
15
|
+
createContentBlock,
|
|
16
|
+
createTextContent,
|
|
17
|
+
createToolCallProgress,
|
|
18
|
+
validateMessage
|
|
19
|
+
} from './types.js';
|
|
20
|
+
|
|
21
|
+
describe('ACP Types', () => {
|
|
22
|
+
describe('constants', () => {
|
|
23
|
+
test('should have correct protocol version', () => {
|
|
24
|
+
expect(ACP_PROTOCOL_VERSION).toBe("1");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('should have message types', () => {
|
|
28
|
+
expect(MessageType.REQUEST).toBe('request');
|
|
29
|
+
expect(MessageType.RESPONSE).toBe('response');
|
|
30
|
+
expect(MessageType.NOTIFICATION).toBe('notification');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('should have request methods', () => {
|
|
34
|
+
expect(RequestMethod.INITIALIZE).toBe('initialize');
|
|
35
|
+
expect(RequestMethod.NEW_SESSION).toBe('newSession');
|
|
36
|
+
expect(RequestMethod.PROMPT).toBe('prompt');
|
|
37
|
+
expect(RequestMethod.CANCEL).toBe('cancel');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('should have notification methods', () => {
|
|
41
|
+
expect(NotificationMethod.SESSION_UPDATED).toBe('sessionUpdated');
|
|
42
|
+
expect(NotificationMethod.TOOL_CALL_PROGRESS).toBe('toolCallProgress');
|
|
43
|
+
expect(NotificationMethod.MESSAGE_CHUNK).toBe('messageChunk');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('should have tool call statuses', () => {
|
|
47
|
+
expect(ToolCallStatus.PENDING).toBe('pending');
|
|
48
|
+
expect(ToolCallStatus.IN_PROGRESS).toBe('in_progress');
|
|
49
|
+
expect(ToolCallStatus.COMPLETED).toBe('completed');
|
|
50
|
+
expect(ToolCallStatus.FAILED).toBe('failed');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('should have tool call kinds', () => {
|
|
54
|
+
expect(ToolCallKind.READ).toBe('read');
|
|
55
|
+
expect(ToolCallKind.edit).toBe('edit');
|
|
56
|
+
expect(ToolCallKind.search).toBe('search');
|
|
57
|
+
expect(ToolCallKind.query).toBe('query');
|
|
58
|
+
expect(ToolCallKind.extract).toBe('extract');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('should have content types', () => {
|
|
62
|
+
expect(ContentType.TEXT).toBe('text');
|
|
63
|
+
expect(ContentType.IMAGE).toBe('image');
|
|
64
|
+
expect(ContentType.RESOURCE).toBe('resource');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should have error codes', () => {
|
|
68
|
+
expect(ErrorCode.PARSE_ERROR).toBe(-32700);
|
|
69
|
+
expect(ErrorCode.INVALID_REQUEST).toBe(-32600);
|
|
70
|
+
expect(ErrorCode.METHOD_NOT_FOUND).toBe(-32601);
|
|
71
|
+
expect(ErrorCode.INVALID_PARAMS).toBe(-32602);
|
|
72
|
+
expect(ErrorCode.INTERNAL_ERROR).toBe(-32603);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('should have session modes', () => {
|
|
76
|
+
expect(SessionMode.NORMAL).toBe('normal');
|
|
77
|
+
expect(SessionMode.PLANNING).toBe('planning');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('createMessage', () => {
|
|
82
|
+
test('should create basic message', () => {
|
|
83
|
+
const message = createMessage('testMethod');
|
|
84
|
+
|
|
85
|
+
expect(message).toEqual({
|
|
86
|
+
jsonrpc: '2.0',
|
|
87
|
+
method: 'testMethod'
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('should create message with params', () => {
|
|
92
|
+
const params = { test: 'value' };
|
|
93
|
+
const message = createMessage('testMethod', params);
|
|
94
|
+
|
|
95
|
+
expect(message).toEqual({
|
|
96
|
+
jsonrpc: '2.0',
|
|
97
|
+
method: 'testMethod',
|
|
98
|
+
params
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('should create message with ID', () => {
|
|
103
|
+
const message = createMessage('testMethod', null, 123);
|
|
104
|
+
|
|
105
|
+
expect(message).toEqual({
|
|
106
|
+
jsonrpc: '2.0',
|
|
107
|
+
method: 'testMethod',
|
|
108
|
+
id: 123
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('should create message with params and ID', () => {
|
|
113
|
+
const params = { test: 'value' };
|
|
114
|
+
const message = createMessage('testMethod', params, 456);
|
|
115
|
+
|
|
116
|
+
expect(message).toEqual({
|
|
117
|
+
jsonrpc: '2.0',
|
|
118
|
+
method: 'testMethod',
|
|
119
|
+
params,
|
|
120
|
+
id: 456
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('createResponse', () => {
|
|
126
|
+
test('should create success response', () => {
|
|
127
|
+
const result = { success: true };
|
|
128
|
+
const response = createResponse(123, result);
|
|
129
|
+
|
|
130
|
+
expect(response).toEqual({
|
|
131
|
+
jsonrpc: '2.0',
|
|
132
|
+
id: 123,
|
|
133
|
+
result
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('should create error response', () => {
|
|
138
|
+
const error = { code: -32601, message: 'Method not found' };
|
|
139
|
+
const response = createResponse(456, null, error);
|
|
140
|
+
|
|
141
|
+
expect(response).toEqual({
|
|
142
|
+
jsonrpc: '2.0',
|
|
143
|
+
id: 456,
|
|
144
|
+
error
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test('should create response with null result', () => {
|
|
149
|
+
const response = createResponse(789);
|
|
150
|
+
|
|
151
|
+
expect(response).toEqual({
|
|
152
|
+
jsonrpc: '2.0',
|
|
153
|
+
id: 789,
|
|
154
|
+
result: null
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe('createError', () => {
|
|
160
|
+
test('should create basic error', () => {
|
|
161
|
+
const error = createError(ErrorCode.INTERNAL_ERROR, 'Something went wrong');
|
|
162
|
+
|
|
163
|
+
expect(error).toEqual({
|
|
164
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
165
|
+
message: 'Something went wrong'
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('should create error with data', () => {
|
|
170
|
+
const data = { details: 'More info' };
|
|
171
|
+
const error = createError(ErrorCode.INVALID_PARAMS, 'Invalid parameters', data);
|
|
172
|
+
|
|
173
|
+
expect(error).toEqual({
|
|
174
|
+
code: ErrorCode.INVALID_PARAMS,
|
|
175
|
+
message: 'Invalid parameters',
|
|
176
|
+
data
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('createContentBlock', () => {
|
|
182
|
+
test('should create basic content block', () => {
|
|
183
|
+
const content = { text: 'Hello world' };
|
|
184
|
+
const block = createContentBlock(ContentType.TEXT, content);
|
|
185
|
+
|
|
186
|
+
expect(block).toEqual({
|
|
187
|
+
type: ContentType.TEXT,
|
|
188
|
+
text: 'Hello world'
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('should create content block with metadata', () => {
|
|
193
|
+
const content = { uri: 'file://test.txt' };
|
|
194
|
+
const metadata = { size: 1024, encoding: 'utf-8' };
|
|
195
|
+
const block = createContentBlock(ContentType.RESOURCE, content, metadata);
|
|
196
|
+
|
|
197
|
+
expect(block).toEqual({
|
|
198
|
+
type: ContentType.RESOURCE,
|
|
199
|
+
uri: 'file://test.txt',
|
|
200
|
+
size: 1024,
|
|
201
|
+
encoding: 'utf-8'
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('createTextContent', () => {
|
|
207
|
+
test('should create text content block', () => {
|
|
208
|
+
const block = createTextContent('Hello world');
|
|
209
|
+
|
|
210
|
+
expect(block).toEqual({
|
|
211
|
+
type: ContentType.TEXT,
|
|
212
|
+
text: 'Hello world'
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('createToolCallProgress', () => {
|
|
218
|
+
test('should create basic progress', () => {
|
|
219
|
+
const progress = createToolCallProgress('tool-123', ToolCallStatus.IN_PROGRESS);
|
|
220
|
+
|
|
221
|
+
expect(progress).toEqual({
|
|
222
|
+
toolCallId: 'tool-123',
|
|
223
|
+
status: ToolCallStatus.IN_PROGRESS
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('should create progress with result', () => {
|
|
228
|
+
const result = { found: 5 };
|
|
229
|
+
const progress = createToolCallProgress('tool-456', ToolCallStatus.COMPLETED, result);
|
|
230
|
+
|
|
231
|
+
expect(progress).toEqual({
|
|
232
|
+
toolCallId: 'tool-456',
|
|
233
|
+
status: ToolCallStatus.COMPLETED,
|
|
234
|
+
result
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test('should create progress with error', () => {
|
|
239
|
+
const error = 'Tool failed';
|
|
240
|
+
const progress = createToolCallProgress('tool-789', ToolCallStatus.FAILED, null, error);
|
|
241
|
+
|
|
242
|
+
expect(progress).toEqual({
|
|
243
|
+
toolCallId: 'tool-789',
|
|
244
|
+
status: ToolCallStatus.FAILED,
|
|
245
|
+
error
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
describe('validateMessage', () => {
|
|
251
|
+
test('should validate correct request message', () => {
|
|
252
|
+
const message = {
|
|
253
|
+
jsonrpc: '2.0',
|
|
254
|
+
method: 'test',
|
|
255
|
+
id: 1
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const result = validateMessage(message);
|
|
259
|
+
expect(result.valid).toBe(true);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test('should validate correct notification message', () => {
|
|
263
|
+
const message = {
|
|
264
|
+
jsonrpc: '2.0',
|
|
265
|
+
method: 'test'
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const result = validateMessage(message);
|
|
269
|
+
expect(result.valid).toBe(true);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test('should validate correct response message', () => {
|
|
273
|
+
const message = {
|
|
274
|
+
jsonrpc: '2.0',
|
|
275
|
+
id: 1,
|
|
276
|
+
result: { success: true }
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const result = validateMessage(message);
|
|
280
|
+
expect(result.valid).toBe(true);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('should validate correct error response message', () => {
|
|
284
|
+
const message = {
|
|
285
|
+
jsonrpc: '2.0',
|
|
286
|
+
id: 1,
|
|
287
|
+
error: { code: -32601, message: 'Method not found' }
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const result = validateMessage(message);
|
|
291
|
+
expect(result.valid).toBe(true);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test('should reject null/undefined message', () => {
|
|
295
|
+
expect(validateMessage(null).valid).toBe(false);
|
|
296
|
+
expect(validateMessage(undefined).valid).toBe(false);
|
|
297
|
+
expect(validateMessage(null).error).toBe('Message must be an object');
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test('should reject non-object message', () => {
|
|
301
|
+
const result = validateMessage('not an object');
|
|
302
|
+
expect(result.valid).toBe(false);
|
|
303
|
+
expect(result.error).toBe('Message must be an object');
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
test('should reject missing jsonrpc', () => {
|
|
307
|
+
const message = { method: 'test', id: 1 };
|
|
308
|
+
const result = validateMessage(message);
|
|
309
|
+
expect(result.valid).toBe(false);
|
|
310
|
+
expect(result.error).toBe('Invalid or missing jsonrpc version');
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test('should reject wrong jsonrpc version', () => {
|
|
314
|
+
const message = { jsonrpc: '1.0', method: 'test', id: 1 };
|
|
315
|
+
const result = validateMessage(message);
|
|
316
|
+
expect(result.valid).toBe(false);
|
|
317
|
+
expect(result.error).toBe('Invalid or missing jsonrpc version');
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test('should reject invalid request/response structure', () => {
|
|
321
|
+
const message = { jsonrpc: '2.0', id: 1 }; // No method, result, or error
|
|
322
|
+
const result = validateMessage(message);
|
|
323
|
+
expect(result.valid).toBe(false);
|
|
324
|
+
expect(result.error).toBe('Request must have method or response must have result/error');
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
});
|