ucp
This commit is contained in:
+43
-1
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"git.k6n.net/mats/go-cart-actor/pkg/cart"
|
||||
messages "git.k6n.net/mats/go-cart-actor/proto/cart"
|
||||
@@ -26,6 +27,12 @@ func (s *Server) callTool(req *rpcRequest) *rpcResponse {
|
||||
if err := json.Unmarshal(req.Params, &p); err != nil {
|
||||
return errorResponse(req.ID, codeInvalidParams, "invalid params")
|
||||
}
|
||||
|
||||
// Extract UCP meta from arguments (UCP-Agent profile advertisement).
|
||||
// Per the UCP spec, meta is a sibling key inside arguments:
|
||||
// "arguments": { "meta": { "ucp-agent": { "profile": "..." } }, ... }
|
||||
args := extractUCPAgentMeta(&p.Arguments)
|
||||
|
||||
var t *tool
|
||||
for i := range s.tools {
|
||||
if s.tools[i].Name == p.Name {
|
||||
@@ -36,13 +43,48 @@ func (s *Server) callTool(req *rpcRequest) *rpcResponse {
|
||||
if t == nil {
|
||||
return errorResponse(req.ID, codeInvalidParams, "unknown tool: "+p.Name)
|
||||
}
|
||||
out, err := t.invoke(p.Arguments)
|
||||
out, err := t.invoke(args)
|
||||
if err != nil {
|
||||
return result(req.ID, toolError(err))
|
||||
}
|
||||
return result(req.ID, toolText(out))
|
||||
}
|
||||
|
||||
// extractUCPAgentMeta checks if the JSON arguments contain a "meta" key with
|
||||
// a nested "ucp-agent.profile" field. If found, it logs the profile (for
|
||||
// observability) and strips the "meta" key before returning the cleaned
|
||||
// arguments to the tool handler, so the meta object does not leak into the
|
||||
// tool's argument namespace.
|
||||
func extractUCPAgentMeta(arguments *json.RawMessage) json.RawMessage {
|
||||
if arguments == nil || len(*arguments) == 0 {
|
||||
return *arguments
|
||||
}
|
||||
var obj map[string]json.RawMessage
|
||||
if err := json.Unmarshal(*arguments, &obj); err != nil {
|
||||
return *arguments
|
||||
}
|
||||
metaRaw, hasMeta := obj["meta"]
|
||||
if !hasMeta {
|
||||
return *arguments
|
||||
}
|
||||
// Try to extract the profile for observability.
|
||||
var meta struct {
|
||||
UCPAgent *struct {
|
||||
Profile string `json:"profile"`
|
||||
} `json:"ucp-agent"`
|
||||
}
|
||||
if err := json.Unmarshal(metaRaw, &meta); err == nil && meta.UCPAgent != nil && meta.UCPAgent.Profile != "" {
|
||||
log.Printf("ucp-agent: profile=%s", meta.UCPAgent.Profile)
|
||||
}
|
||||
// Strip meta from arguments before passing to the tool handler.
|
||||
delete(obj, "meta")
|
||||
cleaned, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return *arguments
|
||||
}
|
||||
return cleaned
|
||||
}
|
||||
|
||||
func (s *Server) buildTools() []tool {
|
||||
return []tool{
|
||||
{
|
||||
|
||||
+43
-1
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"git.k6n.net/mats/go-cart-actor/pkg/order"
|
||||
@@ -27,6 +28,12 @@ func (s *Server) callTool(req *rpcRequest) *rpcResponse {
|
||||
if err := json.Unmarshal(req.Params, &p); err != nil {
|
||||
return errorResponse(req.ID, codeInvalidParams, "invalid params")
|
||||
}
|
||||
|
||||
// Extract UCP meta from arguments (UCP-Agent profile advertisement).
|
||||
// Per the UCP spec, meta is a sibling key inside arguments:
|
||||
// "arguments": { "meta": { "ucp-agent": { "profile": "..." } }, ... }
|
||||
args := extractUCPAgentMeta(&p.Arguments)
|
||||
|
||||
var t *tool
|
||||
for i := range s.tools {
|
||||
if s.tools[i].Name == p.Name {
|
||||
@@ -37,13 +44,48 @@ func (s *Server) callTool(req *rpcRequest) *rpcResponse {
|
||||
if t == nil {
|
||||
return errorResponse(req.ID, codeInvalidParams, "unknown tool: "+p.Name)
|
||||
}
|
||||
out, err := t.invoke(p.Arguments)
|
||||
out, err := t.invoke(args)
|
||||
if err != nil {
|
||||
return result(req.ID, toolError(err))
|
||||
}
|
||||
return result(req.ID, toolText(out))
|
||||
}
|
||||
|
||||
// extractUCPAgentMeta checks if the JSON arguments contain a "meta" key with
|
||||
// a nested "ucp-agent.profile" field. If found, it logs the profile (for
|
||||
// observability) and strips the "meta" key before returning the cleaned
|
||||
// arguments to the tool handler, so the meta object does not leak into the
|
||||
// tool's argument namespace.
|
||||
func extractUCPAgentMeta(arguments *json.RawMessage) json.RawMessage {
|
||||
if arguments == nil || len(*arguments) == 0 {
|
||||
return *arguments
|
||||
}
|
||||
var obj map[string]json.RawMessage
|
||||
if err := json.Unmarshal(*arguments, &obj); err != nil {
|
||||
return *arguments
|
||||
}
|
||||
metaRaw, hasMeta := obj["meta"]
|
||||
if !hasMeta {
|
||||
return *arguments
|
||||
}
|
||||
// Try to extract the profile for observability.
|
||||
var meta struct {
|
||||
UCPAgent *struct {
|
||||
Profile string `json:"profile"`
|
||||
} `json:"ucp-agent"`
|
||||
}
|
||||
if err := json.Unmarshal(metaRaw, &meta); err == nil && meta.UCPAgent != nil && meta.UCPAgent.Profile != "" {
|
||||
log.Printf("ucp-agent: profile=%s", meta.UCPAgent.Profile)
|
||||
}
|
||||
// Strip meta from arguments before passing to the tool handler.
|
||||
delete(obj, "meta")
|
||||
cleaned, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return *arguments
|
||||
}
|
||||
return cleaned
|
||||
}
|
||||
|
||||
func (s *Server) buildTools() []tool {
|
||||
return []tool{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user