internal/mcp: implement logging
Provide a ServerSession method that directly implements the spec method. Also provide a custom slog.Handler that writes a notification on each log call. It uses a slog.JSONHandler to format the message as JSON, then adds the additional fields of LoggingMessageParams. I decided that the direct method should handle levels, since that is in the spec, but that rate-limiting is an extra feature, so is only provided in the slog handler. Change-Id: I1190ca124e992e61fb633ac52ee3492c8e6d99c9 Reviewed-on: https://go-review.googlesource.com/c/tools/+/674498 Auto-Submit: Jonathan Amsterdam <jba@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Sam Thanawalla <samthanawalla@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
bd2af6e0b1
commit
edda031578
1 changed files with 416 additions and 42 deletions
|
|
@ -19,6 +19,7 @@ import (
|
|||
"go/format"
|
||||
"io"
|
||||
"log"
|
||||
"maps"
|
||||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
|
|
@ -110,7 +111,18 @@ var declarations = config{
|
|||
Name: "-",
|
||||
Fields: config{"Params": {Name: "ListToolsParams"}},
|
||||
},
|
||||
"ListToolsResult": {},
|
||||
"ListToolsResult": {},
|
||||
"loggingCapabilities": {Substitute: "struct{}"},
|
||||
"LoggingLevel": {},
|
||||
"LoggingMessageNotification": {
|
||||
Name: "-",
|
||||
Fields: config{
|
||||
"Params": {
|
||||
Name: "LoggingMessageParams",
|
||||
Fields: config{"Data": {Substitute: "any"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ModelHint": {},
|
||||
"ModelPreferences": {},
|
||||
"PingRequest": {
|
||||
|
|
@ -153,8 +165,13 @@ var declarations = config{
|
|||
"Prompts": {Name: "promptCapabilities"},
|
||||
"Resources": {Name: "resourceCapabilities"},
|
||||
"Tools": {Name: "toolCapabilities"},
|
||||
"Logging": {Name: "loggingCapabilities"},
|
||||
},
|
||||
},
|
||||
"SetLevelRequest": {
|
||||
Name: "-",
|
||||
Fields: config{"Params": {Name: "SetLevelParams"}},
|
||||
},
|
||||
"Tool": {
|
||||
Fields: config{"InputSchema": {Substitute: "*jsonschema.Schema"}},
|
||||
},
|
||||
|
|
@ -220,7 +237,7 @@ import (
|
|||
}
|
||||
// Write out method names.
|
||||
fmt.Fprintln(buf, `const (`)
|
||||
for name, s := range schema.Definitions {
|
||||
for _, name := range slices.Sorted(maps.Keys(schema.Definitions)) {
|
||||
prefix := "method"
|
||||
method, found := strings.CutSuffix(name, "Request")
|
||||
if !found {
|
||||
|
|
@ -228,7 +245,7 @@ import (
|
|||
method, found = strings.CutSuffix(name, "Notification")
|
||||
}
|
||||
if found {
|
||||
if ms, ok := s.Properties["method"]; ok {
|
||||
if ms, ok := schema.Definitions[name].Properties["method"]; ok {
|
||||
if c := ms.Const; c != nil {
|
||||
fmt.Fprintf(buf, "%s%s = %q\n", prefix, method, *c)
|
||||
}
|
||||
|
|
@ -395,9 +412,9 @@ func writeType(w io.Writer, config *typeConfig, def *jsonschema.Schema, named ma
|
|||
fieldTypeSchema = rs
|
||||
}
|
||||
needPointer := isStruct(fieldTypeSchema)
|
||||
// Special case: there are no sampling capabilities defined, but
|
||||
// we want it to be a struct for future expansion.
|
||||
if !needPointer && name == "sampling" {
|
||||
// Special case: there are no sampling or logging capabilities defined,
|
||||
// but we want them to be structs for future expansion.
|
||||
if !needPointer && (name == "sampling" || name == "logging") {
|
||||
needPointer = true
|
||||
}
|
||||
if config != nil && config.Fields[export] != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue