5
5
"bytes"
6
6
"context"
7
7
"encoding/json"
8
- "fmt"
9
8
"io"
10
9
"net/http"
10
+ "strconv"
11
11
"strings"
12
12
13
13
"golang.org/x/exp/jsonrpc2"
@@ -297,7 +297,12 @@ func handleLoggingMethod(paramsMap map[string]interface{}) (string, map[string]i
297
297
return "" , nil
298
298
}
299
299
300
- // handleCompletionMethod extracts resource ID for completion requests
300
+ // handleCompletionMethod extracts resource ID for completion requests.
301
+ // For PromptReference: extracts the prompt name
302
+ // For ResourceTemplateReference: extracts the template URI
303
+ // For legacy string ref: returns the string value
304
+ // Always returns paramsMap as arguments since completion requests need the full context
305
+ // including the argument being completed and any context from previous completions.
301
306
func handleCompletionMethod (paramsMap map [string ]interface {}) (string , map [string ]interface {}) {
302
307
// Check if ref is a map (PromptReference or ResourceTemplateReference)
303
308
if ref , ok := paramsMap ["ref" ].(map [string ]interface {}); ok {
@@ -326,16 +331,29 @@ func handleElicitationMethod(paramsMap map[string]interface{}) (string, map[stri
326
331
return "" , paramsMap
327
332
}
328
333
329
- // handleSamplingMethod extracts resource ID for sampling/createMessage requests
334
+ // handleSamplingMethod extracts resource ID for sampling/createMessage requests.
335
+ // Returns the model name from modelPreferences if available, otherwise returns a
336
+ // truncated version of the systemPrompt. The 50-character truncation provides a
337
+ // reasonable balance between uniqueness and readability for authorization and audit logs.
330
338
func handleSamplingMethod (paramsMap map [string ]interface {}) (string , map [string ]interface {}) {
331
339
// Use model preferences or system prompt as identifier if available
332
- if modelPrefs , ok := paramsMap ["modelPreferences" ].(map [string ]interface {}); ok {
333
- if name , ok := modelPrefs ["name" ].(string ); ok {
340
+ if modelPrefs , ok := paramsMap ["modelPreferences" ].(map [string ]interface {}); ok && modelPrefs != nil {
341
+ // Try direct name field first (simplified structure)
342
+ if name , ok := modelPrefs ["name" ].(string ); ok && name != "" {
334
343
return name , paramsMap
335
344
}
345
+ // Try to get model name from hints array (full spec structure)
346
+ if hints , ok := modelPrefs ["hints" ].([]interface {}); ok && len (hints ) > 0 {
347
+ if hint , ok := hints [0 ].(map [string ]interface {}); ok {
348
+ if name , ok := hint ["name" ].(string ); ok && name != "" {
349
+ return name , paramsMap
350
+ }
351
+ }
352
+ }
336
353
}
337
354
if systemPrompt , ok := paramsMap ["systemPrompt" ].(string ); ok && systemPrompt != "" {
338
355
// Use first 50 chars of system prompt as identifier
356
+ // This provides a reasonable balance between uniqueness and readability
339
357
if len (systemPrompt ) > 50 {
340
358
return systemPrompt [:50 ], paramsMap
341
359
}
@@ -360,27 +378,29 @@ func handleResourceUnsubscribeMethod(paramsMap map[string]interface{}) (string,
360
378
return "" , nil
361
379
}
362
380
363
- // handleProgressNotificationMethod extracts resource ID for progress notifications
381
+ // handleProgressNotificationMethod extracts resource ID for progress notifications.
382
+ // Extracts the progressToken which can be either a string or numeric value.
364
383
func handleProgressNotificationMethod (paramsMap map [string ]interface {}) (string , map [string ]interface {}) {
365
384
if token , ok := paramsMap ["progressToken" ].(string ); ok {
366
385
return token , paramsMap
367
386
}
368
387
// Also handle numeric progress tokens
369
388
if token , ok := paramsMap ["progressToken" ].(float64 ); ok {
370
- return fmt . Sprintf ( "%.0f" , token ), paramsMap
389
+ return strconv . FormatFloat ( token , 'f' , 0 , 64 ), paramsMap
371
390
}
372
391
return "" , paramsMap
373
392
}
374
393
375
- // handleCancelledNotificationMethod extracts resource ID for cancelled notifications
394
+ // handleCancelledNotificationMethod extracts resource ID for cancelled notifications.
395
+ // Extracts the requestId which can be either a string or numeric value.
376
396
func handleCancelledNotificationMethod (paramsMap map [string ]interface {}) (string , map [string ]interface {}) {
377
397
// Extract request ID as the resource identifier
378
398
if requestId , ok := paramsMap ["requestId" ].(string ); ok {
379
399
return requestId , paramsMap
380
400
}
381
401
// Handle numeric request IDs
382
402
if requestId , ok := paramsMap ["requestId" ].(float64 ); ok {
383
- return fmt . Sprintf ( "%.0f" , requestId ), paramsMap
403
+ return strconv . FormatFloat ( requestId , 'f' , 0 , 64 ), paramsMap
384
404
}
385
405
return "" , paramsMap
386
406
}
0 commit comments