mcp: use rand.Text and slog.DiscardHandler over internal implementation (#773)
Address TODOs in code requiring go 1.24 as minimum version mcp/logging.go: use slog.DiscardHandler, over local implementation mcp/util.go: use rand.Text, over local implementation Fixes #772
This commit is contained in:
parent
cf88bda0c5
commit
df4f0d56a4
7 changed files with 10 additions and 44 deletions
|
|
@ -234,7 +234,7 @@ func deepCopyThoughts(thoughts []*Thought) []*Thought {
|
|||
func StartThinking(ctx context.Context, _ *mcp.CallToolRequest, args StartThinkingArgs) (*mcp.CallToolResult, any, error) {
|
||||
sessionID := args.SessionID
|
||||
if sessionID == "" {
|
||||
sessionID = randText()
|
||||
sessionID = rand.Text()
|
||||
}
|
||||
|
||||
estimatedSteps := args.EstimatedSteps
|
||||
|
|
@ -480,20 +480,6 @@ func ThinkingHistory(ctx context.Context, req *mcp.ReadResourceRequest) (*mcp.Re
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Copied from crypto/rand.
|
||||
// TODO: once 1.24 is assured, just use crypto/rand.
|
||||
const base32alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
||||
|
||||
func randText() string {
|
||||
// ⌈log₃₂ 2¹²⁸⌉ = 26 chars
|
||||
src := make([]byte, 26)
|
||||
rand.Read(src)
|
||||
for i := range src {
|
||||
src[i] = base32alphabet[src[i]%32]
|
||||
}
|
||||
return string(src)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package mcp
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
|
@ -281,7 +282,7 @@ func BenchmarkMemoryEventStore(b *testing.B) {
|
|||
for i := range sessionIDs {
|
||||
sessionIDs[i] = fmt.Sprint(i)
|
||||
for j := range 3 {
|
||||
streamIDs[i][j] = randText()
|
||||
streamIDs[i][j] = rand.Text()
|
||||
}
|
||||
}
|
||||
payload := make([]byte, test.datasize)
|
||||
|
|
|
|||
|
|
@ -89,21 +89,12 @@ type LoggingHandler struct {
|
|||
handler slog.Handler
|
||||
}
|
||||
|
||||
// discardHandler is a slog.Handler that drops all logs.
|
||||
// TODO: use slog.DiscardHandler when we require Go 1.24+.
|
||||
type discardHandler struct{}
|
||||
|
||||
func (discardHandler) Enabled(context.Context, slog.Level) bool { return false }
|
||||
func (discardHandler) Handle(context.Context, slog.Record) error { return nil }
|
||||
func (discardHandler) WithAttrs([]slog.Attr) slog.Handler { return discardHandler{} }
|
||||
func (discardHandler) WithGroup(string) slog.Handler { return discardHandler{} }
|
||||
|
||||
// ensureLogger returns l if non-nil, otherwise a discard logger.
|
||||
func ensureLogger(l *slog.Logger) *slog.Logger {
|
||||
if l != nil {
|
||||
return l
|
||||
}
|
||||
return slog.New(discardHandler{})
|
||||
return slog.New(slog.DiscardHandler)
|
||||
}
|
||||
|
||||
// NewLoggingHandler creates a [LoggingHandler] that logs to the given [ServerSession] using a
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package mcp
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
|
|
@ -175,7 +176,7 @@ func NewServer(impl *Implementation, options *ServerOptions) *Server {
|
|||
}
|
||||
|
||||
if opts.GetSessionID == nil {
|
||||
opts.GetSessionID = randText
|
||||
opts.GetSessionID = rand.Text
|
||||
}
|
||||
|
||||
if opts.Logger == nil { // ensure we have a logger
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package mcp
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -216,7 +217,7 @@ func (h *SSEHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
|
||||
sessionID = randText()
|
||||
sessionID = rand.Text()
|
||||
endpoint, err := req.URL.Parse("?sessionid=" + sessionID)
|
||||
if err != nil {
|
||||
http.Error(w, "internal error: failed to create endpoint", http.StatusInternalServerError)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ package mcp
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
crand "crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -1140,7 +1141,7 @@ func (c *streamableServerConn) servePOST(w http.ResponseWriter, req *http.Reques
|
|||
// Important: don't publish the incoming messages until the stream is
|
||||
// registered, as the server may attempt to respond to imcoming messages as
|
||||
// soon as they're published.
|
||||
stream, err := c.newStream(req.Context(), calls, randText())
|
||||
stream, err := c.newStream(req.Context(), calls, crand.Text())
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("storing stream: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
|
|
|
|||
15
mcp/util.go
15
mcp/util.go
|
|
@ -5,7 +5,6 @@
|
|||
package mcp
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
|
|
@ -15,20 +14,6 @@ func assert(cond bool, msg string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Copied from crypto/rand.
|
||||
// TODO: once 1.24 is assured, just use crypto/rand.
|
||||
const base32alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
|
||||
|
||||
func randText() string {
|
||||
// ⌈log₃₂ 2¹²⁸⌉ = 26 chars
|
||||
src := make([]byte, 26)
|
||||
rand.Read(src)
|
||||
for i := range src {
|
||||
src[i] = base32alphabet[src[i]%32]
|
||||
}
|
||||
return string(src)
|
||||
}
|
||||
|
||||
// remarshal marshals from to JSON, and then unmarshals into to, which must be
|
||||
// a pointer type.
|
||||
func remarshal(from, to any) error {
|
||||
|
|
|
|||
Loading…
Reference in a new issue