poe-code 3.0.231 → 3.0.233
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/dist/agent.js +12 -7
- package/dist/agent.js.map +3 -3
- package/dist/index.js +536 -229
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -0
- package/dist/providers/poe-agent.js +424 -126
- package/dist/providers/poe-agent.js.map +4 -4
- package/package.json +6 -1
- package/packages/agent-skill-config/dist/index.d.ts +1 -0
- package/packages/agent-skill-config/dist/index.js +1 -0
- package/packages/memory/dist/explain.js +1 -1
- package/packages/memory/dist/index.js +315 -44
- package/packages/memory/dist/index.js.map +4 -4
- package/packages/memory/dist/query.js +1 -1
- package/packages/memory/dist/tokens.js +1 -1
- package/packages/superintendent/dist/mcp.js +41194 -151
- package/packages/superintendent/dist/mcp.js.map +7 -0
- package/packages/tiny-stdio-mcp-server/dist/index.d.ts +1 -1
- package/packages/tiny-stdio-mcp-server/dist/server.d.ts +12 -2
- package/packages/tiny-stdio-mcp-server/dist/server.js +310 -40
- package/packages/tiny-stdio-mcp-server/dist/types.d.ts +136 -9
- package/packages/tiny-stdio-mcp-server/dist/types.js +2 -1
|
@@ -5,5 +5,5 @@ export type { TypedSchema } from "./schema.js";
|
|
|
5
5
|
export { Image, Audio, File, toContentBlocks, fileTypeFromBuffer, } from "./content/index.js";
|
|
6
6
|
export type { ImageContent, AudioContent, EmbeddedResource, TextResourceContents, BlobResourceContents, ContentBlock, TextContent, FileTypeResult, } from "./content/index.js";
|
|
7
7
|
export type { ToolReturn } from "./content/index.js";
|
|
8
|
-
export type { ServerOptions, ToolHandler, ToolDefinition, Tool, CallToolResult, HandleResult, ContentItem, JSONSchema, JSONSchemaProperty, Transport, SDKTransport, JSONRPCRequest, JSONRPCResponse, JSONRPCError, JSONRPCMessage, JSONRPCNotification, InitializeResult, } from "./types.js";
|
|
8
|
+
export type { ServerOptions, ToolHandler, ToolDefinition, Tool, ToolAnnotations, ToolExecution, Icon, ContentAnnotations, ResourceLink, CallToolResult, PromptContentItem, PromptArgument, Prompt, PromptMessage, GetPromptResult, PromptHandler, PromptDefinition, Resource, ResourceTemplate, ResourceContents, ReadResourceResult, ResourceHandler, ResourceDefinition, ResourceTemplateDefinition, HandleResult, ContentItem, JSONSchema, JSONSchemaProperty, Transport, SDKTransport, JSONRPCRequest, JSONRPCResponse, JSONRPCError, JSONRPCMessage, JSONRPCNotification, InitializeResult, } from "./types.js";
|
|
9
9
|
export { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import type { ServerOptions, ToolHandler, HandleResult, Transport, SDKTransport, JSONRPCNotification } from "./types.js";
|
|
1
|
+
import type { ServerOptions, ToolDefinition, ToolHandler, HandleResult, Prompt, PromptHandler, Resource, ResourceHandler, ResourceTemplate, Transport, SDKTransport, JSONRPCNotification } from "./types.js";
|
|
2
2
|
import type { TypedSchema } from "./schema.js";
|
|
3
3
|
export interface Server {
|
|
4
4
|
tool<T>(name: string, description: string, inputSchema: TypedSchema<T>, handler: ToolHandler<T>): Server;
|
|
5
|
+
registerTool<T>(definition: Omit<ToolDefinition<T>, "handler">, handler: ToolHandler<T>): Server;
|
|
6
|
+
prompt(definition: Prompt, handler: PromptHandler): Server;
|
|
7
|
+
resource(definition: Resource, handler: ResourceHandler): Server;
|
|
8
|
+
resourceTemplate(definition: ResourceTemplate, handler: ResourceHandler): Server;
|
|
5
9
|
onNotification(listener: (notification: JSONRPCNotification) => void): () => void;
|
|
6
10
|
removeTool(name: string): boolean;
|
|
11
|
+
removePrompt(name: string): boolean;
|
|
12
|
+
removeResource(uri: string): boolean;
|
|
13
|
+
removeResourceTemplate(uriTemplate: string): boolean;
|
|
7
14
|
notifyToolsChanged(): Promise<void>;
|
|
8
|
-
|
|
15
|
+
notifyPromptsChanged(): Promise<void>;
|
|
16
|
+
notifyResourcesChanged(): Promise<void>;
|
|
17
|
+
notifyResourceUpdated(uri: string): Promise<void>;
|
|
18
|
+
createMessageSession(listener?: (notification: JSONRPCNotification) => void | Promise<void>): MessageSession;
|
|
9
19
|
handleMessage(method: string, params?: Record<string, unknown>): Promise<HandleResult>;
|
|
10
20
|
listen(): Promise<void>;
|
|
11
21
|
connect(transport: Transport): Promise<void>;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import * as readline from "readline";
|
|
2
|
+
import AjvModule from "ajv";
|
|
3
|
+
import uriTemplateParser from "uri-template";
|
|
4
|
+
import UriTemplate from "uri-template-lite";
|
|
2
5
|
import { JSON_RPC_ERROR_CODES, ToolError } from "./types.js";
|
|
3
6
|
import { parseMessage, formatSuccessResponse, formatErrorResponse, } from "./jsonrpc.js";
|
|
4
7
|
import { toContentBlocks } from "./content/convert.js";
|
|
@@ -9,12 +12,21 @@ const SUPPORTED_PROTOCOL_VERSIONS = new Set([
|
|
|
9
12
|
PROTOCOL_VERSION,
|
|
10
13
|
]);
|
|
11
14
|
export function createServer(options) {
|
|
15
|
+
const Ajv = "default" in AjvModule ? AjvModule.default : AjvModule;
|
|
16
|
+
const jsonSchemaValidator = new Ajv({ strict: false });
|
|
17
|
+
const supportNotifications = options.supportNotifications !== false;
|
|
18
|
+
const supportResourceSubscriptions = options.supportResourceSubscriptions !== false;
|
|
12
19
|
const tools = new Map();
|
|
20
|
+
const prompts = new Map();
|
|
21
|
+
const resources = new Map();
|
|
22
|
+
const resourceTemplates = new Map();
|
|
13
23
|
const notificationListeners = new Set();
|
|
14
24
|
const connectionNotificationListeners = new Map();
|
|
15
25
|
const defaultLifecycle = {
|
|
16
26
|
initialized: false,
|
|
17
27
|
initializeAccepted: false,
|
|
28
|
+
notificationReady: false,
|
|
29
|
+
resourceSubscriptions: new Set(),
|
|
18
30
|
};
|
|
19
31
|
const messageLifecycles = new Set([defaultLifecycle]);
|
|
20
32
|
const handleMessageWithLifecycle = async (method, lifecycle, params) => {
|
|
@@ -30,6 +42,7 @@ export function createServer(options) {
|
|
|
30
42
|
// still enforced by the separate lifecycle object given to each connection.
|
|
31
43
|
lifecycle.initializeAccepted = true;
|
|
32
44
|
lifecycle.initialized = true;
|
|
45
|
+
lifecycle.notificationReady = false;
|
|
33
46
|
const requestedProtocol = typeof params?.protocolVersion === "string"
|
|
34
47
|
? params.protocolVersion
|
|
35
48
|
: undefined;
|
|
@@ -39,7 +52,14 @@ export function createServer(options) {
|
|
|
39
52
|
: PROTOCOL_VERSION,
|
|
40
53
|
capabilities: {
|
|
41
54
|
tools: {
|
|
42
|
-
listChanged: true,
|
|
55
|
+
...(supportNotifications ? { listChanged: true } : {}),
|
|
56
|
+
},
|
|
57
|
+
prompts: {
|
|
58
|
+
...(supportNotifications ? { listChanged: true } : {}),
|
|
59
|
+
},
|
|
60
|
+
resources: {
|
|
61
|
+
...(supportNotifications ? { listChanged: true } : {}),
|
|
62
|
+
...(supportResourceSubscriptions ? { subscribe: true } : {}),
|
|
43
63
|
},
|
|
44
64
|
},
|
|
45
65
|
serverInfo: {
|
|
@@ -58,6 +78,7 @@ export function createServer(options) {
|
|
|
58
78
|
},
|
|
59
79
|
};
|
|
60
80
|
}
|
|
81
|
+
lifecycle.notificationReady = true;
|
|
61
82
|
return { result: undefined };
|
|
62
83
|
}
|
|
63
84
|
// All other methods require initialization
|
|
@@ -72,10 +93,10 @@ export function createServer(options) {
|
|
|
72
93
|
if (method === "tools/list") {
|
|
73
94
|
const toolList = [];
|
|
74
95
|
for (const tool of tools.values()) {
|
|
96
|
+
const descriptor = { ...tool };
|
|
97
|
+
delete descriptor.handler;
|
|
75
98
|
toolList.push({
|
|
76
|
-
|
|
77
|
-
description: tool.description,
|
|
78
|
-
inputSchema: tool.inputSchema,
|
|
99
|
+
...descriptor,
|
|
79
100
|
});
|
|
80
101
|
}
|
|
81
102
|
return { result: { tools: toolList } };
|
|
@@ -100,7 +121,7 @@ export function createServer(options) {
|
|
|
100
121
|
};
|
|
101
122
|
}
|
|
102
123
|
const toolArgs = (params?.arguments ?? {});
|
|
103
|
-
if (options.validateToolArguments !== false && !
|
|
124
|
+
if (options.validateToolArguments !== false && !jsonSchemaValidator.validate(tool.inputSchema, toolArgs)) {
|
|
104
125
|
return {
|
|
105
126
|
error: {
|
|
106
127
|
code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
|
|
@@ -116,6 +137,11 @@ export function createServer(options) {
|
|
|
116
137
|
const result = isCallToolResult(handlerResult)
|
|
117
138
|
? handlerResult
|
|
118
139
|
: { content: toContentBlocks(handlerResult) };
|
|
140
|
+
if (tool.outputSchema !== undefined
|
|
141
|
+
&& (result.structuredContent === undefined
|
|
142
|
+
|| !jsonSchemaValidator.validate(tool.outputSchema, result.structuredContent))) {
|
|
143
|
+
throw new Error("Invalid structured tool result");
|
|
144
|
+
}
|
|
119
145
|
return { result };
|
|
120
146
|
}
|
|
121
147
|
catch (err) {
|
|
@@ -135,6 +161,96 @@ export function createServer(options) {
|
|
|
135
161
|
return { result };
|
|
136
162
|
}
|
|
137
163
|
}
|
|
164
|
+
if (method === "prompts/list") {
|
|
165
|
+
return {
|
|
166
|
+
result: {
|
|
167
|
+
prompts: [...prompts.values()].map(({ handler: _handler, ...prompt }) => prompt),
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (method === "prompts/get") {
|
|
172
|
+
const promptName = typeof params?.name === "string" ? params.name : undefined;
|
|
173
|
+
if (promptName === undefined) {
|
|
174
|
+
return invalidParams("Prompt name required");
|
|
175
|
+
}
|
|
176
|
+
const prompt = prompts.get(promptName);
|
|
177
|
+
if (prompt === undefined) {
|
|
178
|
+
return invalidParams(`Prompt not found: ${promptName}`);
|
|
179
|
+
}
|
|
180
|
+
const args = toStringArguments(params?.arguments);
|
|
181
|
+
if (args === undefined || !hasRequiredPromptArguments(prompt, args)) {
|
|
182
|
+
return invalidParams("Invalid prompt arguments");
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const result = await prompt.handler(args);
|
|
186
|
+
if (!isGetPromptResult(result)) {
|
|
187
|
+
return internalError("Invalid prompt result");
|
|
188
|
+
}
|
|
189
|
+
return { result };
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
return internalError(toErrorMessage(error));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (method === "resources/list") {
|
|
196
|
+
return {
|
|
197
|
+
result: {
|
|
198
|
+
resources: [...resources.values()].map(({ handler: _handler, ...resource }) => resource),
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (method === "resources/templates/list") {
|
|
203
|
+
return {
|
|
204
|
+
result: {
|
|
205
|
+
resourceTemplates: [...resourceTemplates.values()].map(({ handler: _handler, ...resourceTemplate }) => resourceTemplate),
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (method === "resources/read") {
|
|
210
|
+
const uri = typeof params?.uri === "string" ? params.uri : undefined;
|
|
211
|
+
if (uri === undefined || !isValidUri(uri)) {
|
|
212
|
+
return invalidParams("Resource URI required");
|
|
213
|
+
}
|
|
214
|
+
const resource = findReadableResource(uri, resources, resourceTemplates);
|
|
215
|
+
if (resource === undefined) {
|
|
216
|
+
return resourceNotFound(uri);
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const result = await resource.handler(uri);
|
|
220
|
+
if (!isReadResourceResult(result)) {
|
|
221
|
+
return internalError("Invalid resource result");
|
|
222
|
+
}
|
|
223
|
+
return { result };
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
return internalError(toErrorMessage(error));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (method === "resources/subscribe" || method === "resources/unsubscribe") {
|
|
230
|
+
if (!supportResourceSubscriptions) {
|
|
231
|
+
return {
|
|
232
|
+
error: {
|
|
233
|
+
code: JSON_RPC_ERROR_CODES.METHOD_NOT_FOUND,
|
|
234
|
+
message: "Method not found",
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const uri = typeof params?.uri === "string" ? params.uri : undefined;
|
|
239
|
+
if (uri === undefined || !isValidUri(uri)) {
|
|
240
|
+
return invalidParams("Resource URI required");
|
|
241
|
+
}
|
|
242
|
+
if (method === "resources/subscribe"
|
|
243
|
+
&& findReadableResource(uri, resources, resourceTemplates) === undefined) {
|
|
244
|
+
return resourceNotFound(uri);
|
|
245
|
+
}
|
|
246
|
+
if (method === "resources/subscribe") {
|
|
247
|
+
lifecycle.resourceSubscriptions.add(uri);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
lifecycle.resourceSubscriptions.delete(uri);
|
|
251
|
+
}
|
|
252
|
+
return { result: {} };
|
|
253
|
+
}
|
|
138
254
|
return {
|
|
139
255
|
error: {
|
|
140
256
|
code: JSON_RPC_ERROR_CODES.METHOD_NOT_FOUND,
|
|
@@ -142,15 +258,23 @@ export function createServer(options) {
|
|
|
142
258
|
},
|
|
143
259
|
};
|
|
144
260
|
};
|
|
145
|
-
const createMessageSession = () => {
|
|
261
|
+
const createMessageSession = (listener) => {
|
|
146
262
|
const lifecycle = {
|
|
147
263
|
initialized: false,
|
|
148
264
|
initializeAccepted: false,
|
|
265
|
+
notificationReady: false,
|
|
266
|
+
resourceSubscriptions: new Set(),
|
|
149
267
|
};
|
|
150
268
|
messageLifecycles.add(lifecycle);
|
|
269
|
+
if (listener !== undefined) {
|
|
270
|
+
connectionNotificationListeners.set(listener, lifecycle);
|
|
271
|
+
}
|
|
151
272
|
return {
|
|
152
273
|
handleMessage: (method, params) => handleMessageWithLifecycle(method, lifecycle, params),
|
|
153
274
|
close: () => {
|
|
275
|
+
if (listener !== undefined) {
|
|
276
|
+
connectionNotificationListeners.delete(listener);
|
|
277
|
+
}
|
|
154
278
|
messageLifecycles.delete(lifecycle);
|
|
155
279
|
},
|
|
156
280
|
};
|
|
@@ -186,16 +310,17 @@ export function createServer(options) {
|
|
|
186
310
|
write(formatSuccessResponse(requestWithId.id, result) + "\n");
|
|
187
311
|
}
|
|
188
312
|
};
|
|
189
|
-
const broadcastNotification = async (method) => {
|
|
313
|
+
const broadcastNotification = async (method, params, canSend = () => true) => {
|
|
190
314
|
const notification = {
|
|
191
315
|
jsonrpc: "2.0",
|
|
192
316
|
method,
|
|
317
|
+
...(params === undefined ? {} : { params }),
|
|
193
318
|
};
|
|
194
319
|
for (const listener of notificationListeners) {
|
|
195
320
|
listener(notification);
|
|
196
321
|
}
|
|
197
322
|
await Promise.all([...connectionNotificationListeners].map(async ([listener, lifecycle]) => {
|
|
198
|
-
if (lifecycle.
|
|
323
|
+
if (lifecycle.notificationReady && canSend(lifecycle)) {
|
|
199
324
|
await listener(notification);
|
|
200
325
|
}
|
|
201
326
|
}));
|
|
@@ -210,6 +335,30 @@ export function createServer(options) {
|
|
|
210
335
|
});
|
|
211
336
|
return server;
|
|
212
337
|
},
|
|
338
|
+
registerTool(definition, handler) {
|
|
339
|
+
tools.set(definition.name, {
|
|
340
|
+
...definition,
|
|
341
|
+
handler: handler,
|
|
342
|
+
});
|
|
343
|
+
return server;
|
|
344
|
+
},
|
|
345
|
+
prompt(definition, handler) {
|
|
346
|
+
prompts.set(definition.name, { ...definition, handler });
|
|
347
|
+
return server;
|
|
348
|
+
},
|
|
349
|
+
resource(definition, handler) {
|
|
350
|
+
if (!isValidUri(definition.uri)) {
|
|
351
|
+
throw new Error(`Invalid resource URI: ${definition.uri}`);
|
|
352
|
+
}
|
|
353
|
+
resources.set(definition.uri, { ...definition, handler });
|
|
354
|
+
return server;
|
|
355
|
+
},
|
|
356
|
+
resourceTemplate(definition, handler) {
|
|
357
|
+
uriTemplateParser.parse(definition.uriTemplate);
|
|
358
|
+
new UriTemplate(definition.uriTemplate);
|
|
359
|
+
resourceTemplates.set(definition.uriTemplate, { ...definition, handler });
|
|
360
|
+
return server;
|
|
361
|
+
},
|
|
213
362
|
onNotification(listener) {
|
|
214
363
|
notificationListeners.add(listener);
|
|
215
364
|
return () => {
|
|
@@ -219,11 +368,36 @@ export function createServer(options) {
|
|
|
219
368
|
removeTool(name) {
|
|
220
369
|
return tools.delete(name);
|
|
221
370
|
},
|
|
371
|
+
removePrompt(name) {
|
|
372
|
+
return prompts.delete(name);
|
|
373
|
+
},
|
|
374
|
+
removeResource(uri) {
|
|
375
|
+
return resources.delete(uri);
|
|
376
|
+
},
|
|
377
|
+
removeResourceTemplate(uriTemplate) {
|
|
378
|
+
return resourceTemplates.delete(uriTemplate);
|
|
379
|
+
},
|
|
222
380
|
async notifyToolsChanged() {
|
|
223
|
-
if ([...messageLifecycles].some((lifecycle) => lifecycle.
|
|
381
|
+
if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
224
382
|
await broadcastNotification("notifications/tools/list_changed");
|
|
225
383
|
}
|
|
226
384
|
},
|
|
385
|
+
async notifyPromptsChanged() {
|
|
386
|
+
if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
387
|
+
await broadcastNotification("notifications/prompts/list_changed");
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
async notifyResourcesChanged() {
|
|
391
|
+
if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
|
|
392
|
+
await broadcastNotification("notifications/resources/list_changed");
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
async notifyResourceUpdated(uri) {
|
|
396
|
+
if (!supportResourceSubscriptions) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
await broadcastNotification("notifications/resources/updated", { uri }, (lifecycle) => lifecycle.resourceSubscriptions.has(uri));
|
|
400
|
+
},
|
|
227
401
|
createMessageSession,
|
|
228
402
|
handleMessage,
|
|
229
403
|
async listen() {
|
|
@@ -234,7 +408,7 @@ export function createServer(options) {
|
|
|
234
408
|
},
|
|
235
409
|
async connect(transport) {
|
|
236
410
|
return new Promise((resolve) => {
|
|
237
|
-
const lifecycle = { initialized: false, initializeAccepted: false };
|
|
411
|
+
const lifecycle = { initialized: false, initializeAccepted: false, notificationReady: false, resourceSubscriptions: new Set() };
|
|
238
412
|
const messageHandler = (method, params) => handleMessageWithLifecycle(method, lifecycle, params);
|
|
239
413
|
messageLifecycles.add(lifecycle);
|
|
240
414
|
const listener = (notification) => {
|
|
@@ -263,7 +437,7 @@ export function createServer(options) {
|
|
|
263
437
|
},
|
|
264
438
|
async connectSDK(transport) {
|
|
265
439
|
return new Promise((resolve, reject) => {
|
|
266
|
-
const lifecycle = { initialized: false, initializeAccepted: false };
|
|
440
|
+
const lifecycle = { initialized: false, initializeAccepted: false, notificationReady: false, resourceSubscriptions: new Set() };
|
|
267
441
|
const messageHandler = (method, params) => handleMessageWithLifecycle(method, lifecycle, params);
|
|
268
442
|
messageLifecycles.add(lifecycle);
|
|
269
443
|
const listener = (notification) => transport.send(notification);
|
|
@@ -326,39 +500,107 @@ export function createServer(options) {
|
|
|
326
500
|
};
|
|
327
501
|
return server;
|
|
328
502
|
}
|
|
329
|
-
function
|
|
330
|
-
return
|
|
503
|
+
function invalidParams(message) {
|
|
504
|
+
return {
|
|
505
|
+
error: {
|
|
506
|
+
code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
|
|
507
|
+
message,
|
|
508
|
+
},
|
|
509
|
+
};
|
|
331
510
|
}
|
|
332
|
-
function
|
|
333
|
-
return
|
|
334
|
-
|
|
511
|
+
function internalError(message) {
|
|
512
|
+
return {
|
|
513
|
+
error: {
|
|
514
|
+
code: JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
|
|
515
|
+
message,
|
|
516
|
+
},
|
|
517
|
+
};
|
|
335
518
|
}
|
|
336
|
-
function
|
|
337
|
-
|
|
519
|
+
function resourceNotFound(uri) {
|
|
520
|
+
return {
|
|
521
|
+
error: {
|
|
522
|
+
code: JSON_RPC_ERROR_CODES.RESOURCE_NOT_FOUND,
|
|
523
|
+
message: `Resource not found: ${uri}`,
|
|
524
|
+
},
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function toErrorMessage(error) {
|
|
528
|
+
return error instanceof Error ? error.message : String(error);
|
|
529
|
+
}
|
|
530
|
+
function isValidUri(uri) {
|
|
531
|
+
try {
|
|
532
|
+
new URL(uri);
|
|
533
|
+
return true;
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
338
536
|
return false;
|
|
339
537
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
538
|
+
}
|
|
539
|
+
function toStringArguments(value) {
|
|
540
|
+
if (value === undefined) {
|
|
541
|
+
return {};
|
|
345
542
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (argument
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
if ((property.type === "array" && !Array.isArray(argument))
|
|
355
|
-
|| (property.type === "object" && (typeof argument !== "object" || argument === null || Array.isArray(argument)))
|
|
356
|
-
|| (property.type === "integer" && (!Number.isInteger(argument)))
|
|
357
|
-
|| (property.type !== "array" && property.type !== "object" && property.type !== "integer" && typeof argument !== property.type)) {
|
|
358
|
-
return false;
|
|
543
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
544
|
+
return undefined;
|
|
545
|
+
}
|
|
546
|
+
const args = {};
|
|
547
|
+
for (const [name, argument] of Object.entries(value)) {
|
|
548
|
+
if (typeof argument !== "string") {
|
|
549
|
+
return undefined;
|
|
359
550
|
}
|
|
551
|
+
args[name] = argument;
|
|
552
|
+
}
|
|
553
|
+
return args;
|
|
554
|
+
}
|
|
555
|
+
function hasRequiredPromptArguments(prompt, args) {
|
|
556
|
+
return (prompt.arguments ?? []).every((argument) => argument.required !== true || args[argument.name] !== undefined);
|
|
557
|
+
}
|
|
558
|
+
function findReadableResource(uri, resources, resourceTemplates) {
|
|
559
|
+
const resource = resources.get(uri);
|
|
560
|
+
if (resource !== undefined) {
|
|
561
|
+
return resource;
|
|
360
562
|
}
|
|
361
|
-
return
|
|
563
|
+
return [...resourceTemplates.values()].find((template) => matchesUriTemplate(template.uriTemplate, uri));
|
|
564
|
+
}
|
|
565
|
+
function matchesUriTemplate(template, uri) {
|
|
566
|
+
try {
|
|
567
|
+
return new UriTemplate(template).match(uri) !== null;
|
|
568
|
+
}
|
|
569
|
+
catch {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function isCallToolResult(value) {
|
|
574
|
+
return hasContentArray(value) && value.content.every(isContentItem);
|
|
575
|
+
}
|
|
576
|
+
function isGetPromptResult(value) {
|
|
577
|
+
if (typeof value !== "object" || value === null || !("messages" in value)) {
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
return Array.isArray(value.messages)
|
|
581
|
+
&& value.messages.every((message) => typeof message === "object"
|
|
582
|
+
&& message !== null
|
|
583
|
+
&& "role" in message
|
|
584
|
+
&& (message.role === "user" || message.role === "assistant")
|
|
585
|
+
&& "content" in message
|
|
586
|
+
&& isPromptContentItem(message.content));
|
|
587
|
+
}
|
|
588
|
+
function isReadResourceResult(value) {
|
|
589
|
+
if (typeof value !== "object" || value === null || !("contents" in value)) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
return Array.isArray(value.contents)
|
|
593
|
+
&& value.contents.every((content) => typeof content === "object"
|
|
594
|
+
&& content !== null
|
|
595
|
+
&& "uri" in content
|
|
596
|
+
&& typeof content.uri === "string"
|
|
597
|
+
&& isValidUri(content.uri)
|
|
598
|
+
&& (("text" in content && typeof content.text === "string")
|
|
599
|
+
|| ("blob" in content && typeof content.blob === "string" && isBase64(content.blob))));
|
|
600
|
+
}
|
|
601
|
+
function hasContentArray(value) {
|
|
602
|
+
return typeof value === "object" && value !== null && "content" in value
|
|
603
|
+
&& Array.isArray(value.content);
|
|
362
604
|
}
|
|
363
605
|
function isContentItem(value) {
|
|
364
606
|
if (typeof value !== "object" || value === null || !("type" in value)) {
|
|
@@ -369,13 +611,41 @@ function isContentItem(value) {
|
|
|
369
611
|
return typeof block.text === "string";
|
|
370
612
|
}
|
|
371
613
|
if (block.type === "image" || block.type === "audio") {
|
|
372
|
-
return typeof block.data === "string" && typeof block.mimeType === "string";
|
|
614
|
+
return typeof block.data === "string" && isBase64(block.data) && typeof block.mimeType === "string";
|
|
615
|
+
}
|
|
616
|
+
if (block.type === "resource_link") {
|
|
617
|
+
return typeof block.uri === "string" && typeof block.name === "string";
|
|
373
618
|
}
|
|
374
619
|
if (block.type !== "resource" || typeof block.resource !== "object" || block.resource === null) {
|
|
375
620
|
return false;
|
|
376
621
|
}
|
|
377
622
|
const resource = block.resource;
|
|
378
623
|
return typeof resource.uri === "string"
|
|
379
|
-
&& typeof resource.mimeType === "string"
|
|
380
|
-
&& (typeof resource.text === "string" || typeof resource.blob === "string");
|
|
624
|
+
&& (resource.mimeType === undefined || typeof resource.mimeType === "string")
|
|
625
|
+
&& (typeof resource.text === "string" || (typeof resource.blob === "string" && isBase64(resource.blob)));
|
|
626
|
+
}
|
|
627
|
+
function isBase64(value) {
|
|
628
|
+
if (value.length === 0) {
|
|
629
|
+
return true;
|
|
630
|
+
}
|
|
631
|
+
if (value.length % 4 !== 0) {
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
634
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
635
|
+
const paddingStart = value.indexOf("=");
|
|
636
|
+
const encoded = paddingStart === -1 ? value : value.slice(0, paddingStart);
|
|
637
|
+
const padding = paddingStart === -1 ? "" : value.slice(paddingStart);
|
|
638
|
+
if (padding.length > 2 || [...padding].some((character) => character !== "=")) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
if ([...encoded].some((character) => !alphabet.includes(character))) {
|
|
642
|
+
return false;
|
|
643
|
+
}
|
|
644
|
+
return Buffer.from(value, "base64").toString("base64") === value;
|
|
645
|
+
}
|
|
646
|
+
function isPromptContentItem(value) {
|
|
647
|
+
if (!isContentItem(value)) {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
return !(typeof value === "object" && value !== null && "type" in value && value.type === "resource_link");
|
|
381
651
|
}
|