@iqai/adk 0.0.7 → 0.0.8
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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +43 -8
- package/dist/index.d.ts +43 -8
- package/dist/index.js +307 -163
- package/dist/index.mjs +168 -24
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2945,7 +2945,14 @@ init_logger();
|
|
|
2945
2945
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2946
2946
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
2947
2947
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
2948
|
-
import { CreateMessageRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
2948
|
+
import { CreateMessageRequestSchema as CreateMessageRequestSchema2 } from "@modelcontextprotocol/sdk/types.js";
|
|
2949
|
+
|
|
2950
|
+
// src/tools/mcp/sampling-handler.ts
|
|
2951
|
+
init_logger();
|
|
2952
|
+
import {
|
|
2953
|
+
CreateMessageRequestSchema,
|
|
2954
|
+
CreateMessageResultSchema
|
|
2955
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
2949
2956
|
|
|
2950
2957
|
// src/tools/mcp/types.ts
|
|
2951
2958
|
var McpErrorType = /* @__PURE__ */ ((McpErrorType2) => {
|
|
@@ -2969,6 +2976,154 @@ var McpError = class extends Error {
|
|
|
2969
2976
|
}
|
|
2970
2977
|
};
|
|
2971
2978
|
|
|
2979
|
+
// src/tools/mcp/sampling-handler.ts
|
|
2980
|
+
var McpSamplingHandler = class {
|
|
2981
|
+
logger = new Logger({ name: "McpSamplingHandler" });
|
|
2982
|
+
adkHandler;
|
|
2983
|
+
constructor(adkHandler) {
|
|
2984
|
+
this.adkHandler = adkHandler;
|
|
2985
|
+
}
|
|
2986
|
+
/**
|
|
2987
|
+
* Handle MCP sampling request and convert between formats
|
|
2988
|
+
*/
|
|
2989
|
+
async handleSamplingRequest(request) {
|
|
2990
|
+
try {
|
|
2991
|
+
const validationResult = CreateMessageRequestSchema.safeParse(request);
|
|
2992
|
+
if (!validationResult.success) {
|
|
2993
|
+
this.logger.error(
|
|
2994
|
+
"Invalid MCP sampling request:",
|
|
2995
|
+
validationResult.error
|
|
2996
|
+
);
|
|
2997
|
+
throw new McpError(
|
|
2998
|
+
`Invalid sampling request: ${validationResult.error.message}`,
|
|
2999
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3000
|
+
);
|
|
3001
|
+
}
|
|
3002
|
+
const mcpParams = request.params;
|
|
3003
|
+
if (!mcpParams.messages || !Array.isArray(mcpParams.messages)) {
|
|
3004
|
+
throw new McpError(
|
|
3005
|
+
"Invalid sampling request: messages array is required",
|
|
3006
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3007
|
+
);
|
|
3008
|
+
}
|
|
3009
|
+
if (!mcpParams.maxTokens || mcpParams.maxTokens <= 0) {
|
|
3010
|
+
throw new McpError(
|
|
3011
|
+
"Invalid sampling request: maxTokens must be a positive number",
|
|
3012
|
+
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3013
|
+
);
|
|
3014
|
+
}
|
|
3015
|
+
this.logger.debug("Converting MCP request to ADK format");
|
|
3016
|
+
const adkMessages = this.convertMcpMessagesToADK(mcpParams.messages);
|
|
3017
|
+
const adkRequest = {
|
|
3018
|
+
messages: adkMessages,
|
|
3019
|
+
systemPrompt: mcpParams.systemPrompt,
|
|
3020
|
+
modelPreferences: mcpParams.modelPreferences,
|
|
3021
|
+
includeContext: mcpParams.includeContext,
|
|
3022
|
+
temperature: mcpParams.temperature,
|
|
3023
|
+
maxTokens: mcpParams.maxTokens,
|
|
3024
|
+
stopSequences: mcpParams.stopSequences,
|
|
3025
|
+
metadata: mcpParams.metadata
|
|
3026
|
+
};
|
|
3027
|
+
this.logger.debug("Calling ADK sampling handler");
|
|
3028
|
+
const adkResponse = await this.adkHandler(adkRequest);
|
|
3029
|
+
this.logger.debug("Converting ADK response to MCP format");
|
|
3030
|
+
const mcpResponse = this.convertADKResponseToMcp(adkResponse);
|
|
3031
|
+
const responseValidation = CreateMessageResultSchema.safeParse(mcpResponse);
|
|
3032
|
+
if (!responseValidation.success) {
|
|
3033
|
+
this.logger.error(
|
|
3034
|
+
"Invalid MCP response generated:",
|
|
3035
|
+
responseValidation.error
|
|
3036
|
+
);
|
|
3037
|
+
throw new McpError(
|
|
3038
|
+
`Invalid response generated: ${responseValidation.error.message}`,
|
|
3039
|
+
"SAMPLING_ERROR" /* SAMPLING_ERROR */
|
|
3040
|
+
);
|
|
3041
|
+
}
|
|
3042
|
+
return mcpResponse;
|
|
3043
|
+
} catch (error) {
|
|
3044
|
+
this.logger.error("Error handling sampling request:", error);
|
|
3045
|
+
if (error instanceof McpError) {
|
|
3046
|
+
throw error;
|
|
3047
|
+
}
|
|
3048
|
+
throw new McpError(
|
|
3049
|
+
`Sampling request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
3050
|
+
"SAMPLING_ERROR" /* SAMPLING_ERROR */,
|
|
3051
|
+
error instanceof Error ? error : void 0
|
|
3052
|
+
);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Convert MCP messages to ADK message format
|
|
3057
|
+
*/
|
|
3058
|
+
convertMcpMessagesToADK(mcpMessages) {
|
|
3059
|
+
return mcpMessages.map((mcpMessage) => {
|
|
3060
|
+
const adkRole = mcpMessage.role === "assistant" ? "assistant" : "user";
|
|
3061
|
+
let adkContent;
|
|
3062
|
+
if (mcpMessage.content.type === "text") {
|
|
3063
|
+
adkContent = mcpMessage.content.text || "";
|
|
3064
|
+
} else if (mcpMessage.content.type === "image") {
|
|
3065
|
+
const contentParts = [];
|
|
3066
|
+
if (mcpMessage.content.text) {
|
|
3067
|
+
contentParts.push({
|
|
3068
|
+
type: "text",
|
|
3069
|
+
text: mcpMessage.content.text
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
if (mcpMessage.content.data) {
|
|
3073
|
+
const mimeType = mcpMessage.content.mimeType || "image/jpeg";
|
|
3074
|
+
const dataUrl = `data:${mimeType};base64,${mcpMessage.content.data}`;
|
|
3075
|
+
contentParts.push({
|
|
3076
|
+
type: "image",
|
|
3077
|
+
image_url: {
|
|
3078
|
+
url: dataUrl
|
|
3079
|
+
}
|
|
3080
|
+
});
|
|
3081
|
+
}
|
|
3082
|
+
adkContent = contentParts.length > 0 ? contentParts : "";
|
|
3083
|
+
} else {
|
|
3084
|
+
this.logger.warn(
|
|
3085
|
+
`Unknown MCP content type: ${mcpMessage.content.type}`
|
|
3086
|
+
);
|
|
3087
|
+
adkContent = mcpMessage.content.text || "";
|
|
3088
|
+
}
|
|
3089
|
+
const adkMessage = {
|
|
3090
|
+
role: adkRole,
|
|
3091
|
+
content: adkContent
|
|
3092
|
+
};
|
|
3093
|
+
this.logger.debug(
|
|
3094
|
+
`Converted MCP message - role: ${mcpMessage.role} -> ${adkRole}, content type: ${mcpMessage.content.type}`
|
|
3095
|
+
);
|
|
3096
|
+
return adkMessage;
|
|
3097
|
+
});
|
|
3098
|
+
}
|
|
3099
|
+
/**
|
|
3100
|
+
* Convert ADK response to MCP response format
|
|
3101
|
+
*/
|
|
3102
|
+
convertADKResponseToMcp(adkResponse) {
|
|
3103
|
+
const mcpResponse = {
|
|
3104
|
+
model: adkResponse.model,
|
|
3105
|
+
stopReason: adkResponse.stopReason,
|
|
3106
|
+
role: "assistant",
|
|
3107
|
+
// ADK responses are always from assistant
|
|
3108
|
+
content: {
|
|
3109
|
+
type: "text",
|
|
3110
|
+
text: adkResponse.content || ""
|
|
3111
|
+
}
|
|
3112
|
+
};
|
|
3113
|
+
this.logger.debug(
|
|
3114
|
+
`Converted ADK response - model: ${adkResponse.model}, content length: ${adkResponse.content?.length || 0}`
|
|
3115
|
+
);
|
|
3116
|
+
return mcpResponse;
|
|
3117
|
+
}
|
|
3118
|
+
/**
|
|
3119
|
+
* Update the ADK handler
|
|
3120
|
+
*/
|
|
3121
|
+
updateHandler(handler) {
|
|
3122
|
+
this.adkHandler = handler;
|
|
3123
|
+
this.logger.debug("ADK sampling handler updated");
|
|
3124
|
+
}
|
|
3125
|
+
};
|
|
3126
|
+
|
|
2972
3127
|
// src/tools/mcp/utils.ts
|
|
2973
3128
|
function withRetry(fn, instance, reinitMethod, maxRetries = 1) {
|
|
2974
3129
|
return async (...args) => {
|
|
@@ -3003,11 +3158,10 @@ var McpClientService = class {
|
|
|
3003
3158
|
client = null;
|
|
3004
3159
|
transport = null;
|
|
3005
3160
|
isClosing = false;
|
|
3006
|
-
|
|
3161
|
+
mcpSamplingHandler = null;
|
|
3007
3162
|
logger = new Logger({ name: "McpClientService" });
|
|
3008
3163
|
constructor(config) {
|
|
3009
3164
|
this.config = config;
|
|
3010
|
-
this.samplingHandler = config.samplingHandler || null;
|
|
3011
3165
|
}
|
|
3012
3166
|
/**
|
|
3013
3167
|
* Initializes and returns an MCP client based on configuration.
|
|
@@ -3209,7 +3363,7 @@ var McpClientService = class {
|
|
|
3209
3363
|
return !!this.client && !this.isClosing;
|
|
3210
3364
|
}
|
|
3211
3365
|
async setupSamplingHandler(client) {
|
|
3212
|
-
if (!this.
|
|
3366
|
+
if (!this.mcpSamplingHandler) {
|
|
3213
3367
|
if (this.config.debug) {
|
|
3214
3368
|
console.log(
|
|
3215
3369
|
"\u26A0\uFE0F No sampling handler provided - sampling requests will be rejected"
|
|
@@ -3217,26 +3371,10 @@ var McpClientService = class {
|
|
|
3217
3371
|
}
|
|
3218
3372
|
return;
|
|
3219
3373
|
}
|
|
3220
|
-
client.setRequestHandler(
|
|
3374
|
+
client.setRequestHandler(CreateMessageRequestSchema2, async (request) => {
|
|
3221
3375
|
try {
|
|
3222
3376
|
this.logger.debug("Received sampling request:", request);
|
|
3223
|
-
const
|
|
3224
|
-
if (!samplingRequest.messages || !Array.isArray(samplingRequest.messages)) {
|
|
3225
|
-
throw new McpError(
|
|
3226
|
-
"Invalid sampling request: messages array is required",
|
|
3227
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3228
|
-
);
|
|
3229
|
-
}
|
|
3230
|
-
if (!samplingRequest.maxTokens || samplingRequest.maxTokens <= 0) {
|
|
3231
|
-
throw new McpError(
|
|
3232
|
-
"Invalid sampling request: maxTokens must be a positive number",
|
|
3233
|
-
"INVALID_REQUEST_ERROR" /* INVALID_REQUEST_ERROR */
|
|
3234
|
-
);
|
|
3235
|
-
}
|
|
3236
|
-
const response = await this.samplingHandler({
|
|
3237
|
-
method: request.method,
|
|
3238
|
-
params: request.params
|
|
3239
|
-
});
|
|
3377
|
+
const response = await this.mcpSamplingHandler.handleSamplingRequest(request);
|
|
3240
3378
|
if (this.config.debug) {
|
|
3241
3379
|
console.log("\u2705 Sampling request completed successfully");
|
|
3242
3380
|
}
|
|
@@ -3257,16 +3395,22 @@ var McpClientService = class {
|
|
|
3257
3395
|
console.log("\u{1F3AF} Sampling handler registered successfully");
|
|
3258
3396
|
}
|
|
3259
3397
|
}
|
|
3398
|
+
/**
|
|
3399
|
+
* Set an ADK sampling handler
|
|
3400
|
+
*/
|
|
3260
3401
|
setSamplingHandler(handler) {
|
|
3261
|
-
this.
|
|
3402
|
+
this.mcpSamplingHandler = new McpSamplingHandler(handler);
|
|
3262
3403
|
if (this.client) {
|
|
3263
3404
|
this.setupSamplingHandler(this.client).catch((error) => {
|
|
3264
3405
|
console.error("Failed to update sampling handler:", error);
|
|
3265
3406
|
});
|
|
3266
3407
|
}
|
|
3267
3408
|
}
|
|
3409
|
+
/**
|
|
3410
|
+
* Remove the sampling handler
|
|
3411
|
+
*/
|
|
3268
3412
|
removeSamplingHandler() {
|
|
3269
|
-
this.
|
|
3413
|
+
this.mcpSamplingHandler = null;
|
|
3270
3414
|
if (this.client) {
|
|
3271
3415
|
try {
|
|
3272
3416
|
this.client.removeRequestHandler?.("sampling/createMessage");
|