From 33b5b8c8f4aa5d6bbaf5e0e02ee69e040b23d83e Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sat, 15 Mar 2025 23:25:03 +0100 Subject: [PATCH] feat(agent): add MCP integration (#50) * feat(agent): add MCP integration Signed-off-by: mudler * Update core/agent/mcp.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Hook MCP Server configuration to creation and setting mask * Allow to specify a bearer token * Small fixups --------- Signed-off-by: mudler Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- core/agent/actions.go | 18 ++--- core/agent/agent.go | 10 ++- core/agent/mcp.go | 160 ++++++++++++++++++++++++++++++++++++++ core/agent/options.go | 9 +++ core/state/config.go | 1 + core/state/pool.go | 1 + go.mod | 24 ++++++ go.sum | 85 +++++++++++++++++++- webui/views/create.html | 46 +++++++++++ webui/views/settings.html | 82 ++++++++++++++++++- 10 files changed, 422 insertions(+), 14 deletions(-) create mode 100644 core/agent/mcp.go diff --git a/core/agent/actions.go b/core/agent/actions.go index 7c4024d..a01bf5e 100644 --- a/core/agent/actions.go +++ b/core/agent/actions.go @@ -174,7 +174,7 @@ func (m Messages) IsLastMessageFromRole(role string) bool { func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act Action, c []openai.ChatCompletionMessage, reasoning string) (*decisionResult, error) { - stateHUD, err := renderTemplate(pickTemplate, a.prepareHUD(), a.systemInternalActions(), reasoning) + stateHUD, err := renderTemplate(pickTemplate, a.prepareHUD(), a.availableActions(), reasoning) if err != nil { return nil, err } @@ -203,7 +203,7 @@ func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act return a.decision(ctx, cc, - a.systemInternalActions().ToTools(), + a.availableActions().ToTools(), openai.ToolChoice{ Type: openai.ToolTypeFunction, Function: openai.ToolFunction{Name: act.Definition().Name.String()}, @@ -211,9 +211,9 @@ func (a *Agent) generateParameters(ctx context.Context, pickTemplate string, act ) } -func (a *Agent) systemInternalActions() Actions { +func (a *Agent) availableActions() Actions { // defaultActions := append(a.options.userActions, action.NewReply()) - defaultActions := a.options.userActions + defaultActions := append(a.mcpActions, a.options.userActions...) if a.options.initiateConversations && a.selfEvaluationInProgress { // && self-evaluation.. acts := append(defaultActions, action.NewConversation()) @@ -264,7 +264,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. // and then use the reply to get the action thought, err := a.decision(ctx, messages, - a.systemInternalActions().ToTools(), + a.availableActions().ToTools(), nil) if err != nil { return nil, nil, "", err @@ -274,7 +274,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. xlog.Debug(fmt.Sprintf("thought message: %v", thought.message)) // Find the action - chosenAction := a.systemInternalActions().Find(thought.actioName) + chosenAction := a.availableActions().Find(thought.actioName) if chosenAction == nil || thought.actioName == "" { xlog.Debug("no answer") @@ -286,7 +286,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. return chosenAction, thought.actionParams, thought.message, nil } - prompt, err := renderTemplate(templ, a.prepareHUD(), a.systemInternalActions(), "") + prompt, err := renderTemplate(templ, a.prepareHUD(), a.availableActions(), "") if err != nil { return nil, nil, "", err } @@ -325,7 +325,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. // From the thought, get the action call // Get all the available actions IDs actionsID := []string{} - for _, m := range a.systemInternalActions() { + for _, m := range a.availableActions() { actionsID = append(actionsID, m.Definition().Name.String()) } intentionsTools := action.NewIntention(actionsID...) @@ -358,7 +358,7 @@ func (a *Agent) pickAction(ctx context.Context, templ string, messages []openai. } // Find the action - chosenAction := a.systemInternalActions().Find(actionChoice.Tool) + chosenAction := a.availableActions().Find(actionChoice.Tool) if chosenAction == nil { return nil, nil, "", fmt.Errorf("no action found for intent:" + actionChoice.Tool) } diff --git a/core/agent/agent.go b/core/agent/agent.go index fe88af5..6677e99 100644 --- a/core/agent/agent.go +++ b/core/agent/agent.go @@ -39,6 +39,8 @@ type Agent struct { pause bool newConversations chan openai.ChatCompletionMessage + + mcpActions Actions } type RAGDB interface { @@ -84,6 +86,10 @@ func New(opts ...Option) (*Agent, error) { // xlog = xlog.New(h) //programLevel.Set(a.options.logLevel) + xlog.Info("Populating actions from MCP Servers (if any)") + a.initMCPActions() + xlog.Info("Done populating actions from MCP Servers") + xlog.Info( "Agent created", "agent", a.Character.Name, @@ -214,7 +220,7 @@ func (a *Agent) Memory() RAGDB { } func (a *Agent) runAction(chosenAction Action, params action.ActionParams) (result action.ActionResult, err error) { - for _, act := range a.systemInternalActions() { + for _, act := range a.availableActions() { if act.Definition().Name == chosenAction.Definition().Name { res, err := act.Run(a.actionContext, params) if err != nil { @@ -708,7 +714,7 @@ func (a *Agent) consumeJob(job *Job, role string) { // If we have a hud, display it when answering normally if a.options.enableHUD { - prompt, err := renderTemplate(hudTemplate, a.prepareHUD(), a.systemInternalActions(), reasoning) + prompt, err := renderTemplate(hudTemplate, a.prepareHUD(), a.availableActions(), reasoning) if err != nil { job.Result.Conversation = a.currentConversation job.Result.Finish(fmt.Errorf("error renderTemplate: %w", err)) diff --git a/core/agent/mcp.go b/core/agent/mcp.go new file mode 100644 index 0000000..d933283 --- /dev/null +++ b/core/agent/mcp.go @@ -0,0 +1,160 @@ +package agent + +import ( + "context" + "encoding/json" + "errors" + + mcp "github.com/metoro-io/mcp-golang" + "github.com/metoro-io/mcp-golang/transport/http" + "github.com/mudler/LocalAgent/core/action" + "github.com/mudler/LocalAgent/pkg/xlog" + "github.com/sashabaranov/go-openai/jsonschema" +) + +var _ Action = &mcpAction{} + +type MCPServer struct { + URL string `json:"url"` + Token string `json:"token"` +} + +type mcpAction struct { + mcpClient *mcp.Client + inputSchema ToolInputSchema + toolName string + toolDescription string +} + +func (m *mcpAction) Run(ctx context.Context, params action.ActionParams) (action.ActionResult, error) { + resp, err := m.mcpClient.CallTool(ctx, m.toolName, params) + if err != nil { + xlog.Error("Failed to call tool", "error", err.Error()) + return action.ActionResult{}, err + } + + xlog.Debug("MCP response", "response", resp) + + textResult := "" + for _, c := range resp.Content { + switch c.Type { + case mcp.ContentTypeText: + textResult += c.TextContent.Text + "\n" + case mcp.ContentTypeImage: + xlog.Error("Image content not supported yet") + case mcp.ContentTypeEmbeddedResource: + xlog.Error("Embedded resource content not supported yet") + } + } + + return action.ActionResult{ + Result: textResult, + }, nil +} + +func (m *mcpAction) Definition() action.ActionDefinition { + props := map[string]jsonschema.Definition{} + dat, err := json.Marshal(m.inputSchema.Properties) + if err != nil { + xlog.Error("Failed to marshal input schema", "error", err.Error()) + } + json.Unmarshal(dat, &props) + + return action.ActionDefinition{ + Name: action.ActionDefinitionName(m.toolName), + Description: m.toolDescription, + Required: m.inputSchema.Required, + //Properties: , + Properties: props, + } +} + +type ToolInputSchema struct { + Type string `json:"type"` + Properties map[string]interface{} `json:"properties,omitempty"` + Required []string `json:"required,omitempty"` +} + +func (a *Agent) initMCPActions() error { + + a.mcpActions = nil + var err error + + generatedActions := Actions{} + + for _, mcpServer := range a.options.mcpServers { + transport := http.NewHTTPClientTransport("/mcp") + transport.WithBaseURL(mcpServer.URL) + if mcpServer.Token != "" { + transport.WithHeader("Authorization", "Bearer "+mcpServer.Token) + } + + // Create a new client + client := mcp.NewClient(transport) + + xlog.Debug("Initializing client", "server", mcpServer.URL) + // Initialize the client + response, e := client.Initialize(a.context) + if e != nil { + xlog.Error("Failed to initialize client", "error", e.Error(), "server", mcpServer) + if err == nil { + err = e + } else { + err = errors.Join(err, e) + } + continue + } + + xlog.Debug("Client initialized: %v", response.Instructions) + + var cursor *string + for { + tools, err := client.ListTools(a.context, cursor) + if err != nil { + xlog.Error("Failed to list tools", "error", err.Error()) + return err + } + + for _, t := range tools.Tools { + desc := "" + if t.Description != nil { + desc = *t.Description + } + + xlog.Debug("Tool", "mcpServer", mcpServer, "name", t.Name, "description", desc) + + dat, err := json.Marshal(t.InputSchema) + if err != nil { + xlog.Error("Failed to marshal input schema", "error", err.Error()) + } + + xlog.Debug("Input schema", "mcpServer", mcpServer, "tool", t.Name, "schema", string(dat)) + + // XXX: This is a wild guess, to verify (data types might be incompatible) + var inputSchema ToolInputSchema + err = json.Unmarshal(dat, &inputSchema) + if err != nil { + xlog.Error("Failed to unmarshal input schema", "error", err.Error()) + } + + // Create a new action with Client + tool + generatedActions = append(generatedActions, &mcpAction{ + mcpClient: client, + toolName: t.Name, + inputSchema: inputSchema, + toolDescription: desc, + }) + } + + if tools.NextCursor == nil { + break // No more pages + } + cursor = tools.NextCursor + } + + } + + a.mcpActions = generatedActions + + return err +} diff --git a/core/agent/options.go b/core/agent/options.go index 60b325a..2dbe551 100644 --- a/core/agent/options.go +++ b/core/agent/options.go @@ -44,6 +44,8 @@ type options struct { resultCallback func(ActionState) conversationsPath string + + mcpServers []MCPServer } func (o *options) SeparatedMultimodalModel() bool { @@ -161,6 +163,13 @@ func WithSystemPrompt(prompt string) Option { } } +func WithMCPServers(servers ...MCPServer) Option { + return func(o *options) error { + o.mcpServers = servers + return nil + } +} + func WithLLMAPIURL(url string) Option { return func(o *options) error { o.LLMAPI.APIURL = url diff --git a/core/state/config.go b/core/state/config.go index 732d6ae..1101346 100644 --- a/core/state/config.go +++ b/core/state/config.go @@ -31,6 +31,7 @@ type AgentConfig struct { Connector []ConnectorConfig `json:"connectors" form:"connectors" ` Actions []ActionsConfig `json:"actions" form:"actions"` PromptBlocks []PromptBlocksConfig `json:"promptblocks" form:"promptblocks"` + MCPServers []agent.MCPServer `json:"mcp_servers" form:"mcp_servers"` // This is what needs to be part of ActionsConfig Model string `json:"model" form:"model"` diff --git a/core/state/pool.go b/core/state/pool.go index 9adfd6e..7a34a45 100644 --- a/core/state/pool.go +++ b/core/state/pool.go @@ -212,6 +212,7 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error WithModel(model), WithLLMAPIURL(a.apiURL), WithContext(ctx), + WithMCPServers(config.MCPServers...), WithPeriodicRuns(config.PeriodicRuns), WithPermanentGoal(config.PermanentGoal), WithPrompts(promptBlocks...), diff --git a/go.mod b/go.mod index 33ff7e1..e094396 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/gofiber/fiber/v2 v2.52.4 github.com/gofiber/template/html/v2 v2.1.1 github.com/google/go-github/v69 v69.2.0 + github.com/metoro-io/mcp-golang v0.8.0 github.com/onsi/ginkgo/v2 v2.15.0 github.com/onsi/gomega v1.31.1 github.com/philippgille/chromem-go v0.5.0 @@ -34,10 +35,18 @@ require ( github.com/antchfx/htmlquery v1.3.0 // indirect github.com/antchfx/xmlquery v1.3.17 // indirect github.com/antchfx/xpath v1.2.4 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.8.1 // indirect github.com/go-logr/logr v1.3.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.9.7 // indirect github.com/gocolly/colly v1.2.0 // indirect github.com/gofiber/template v1.8.3 // indirect github.com/gofiber/utils v1.1.0 // indirect @@ -48,19 +57,33 @@ require ( github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/kennygrant/sanitize v1.2.4 // indirect github.com/klauspost/compress v1.17.7 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.9 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pkoukk/tiktoken-go v0.1.6 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/temoto/robotstxt v1.1.2 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect go.starlark.net v0.0.0-20230302034142-4b1e35fe2254 // indirect golang.org/x/crypto v0.30.0 // indirect golang.org/x/net v0.32.0 // indirect @@ -69,5 +92,6 @@ require ( golang.org/x/tools v0.28.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3374d46..a9d6e15 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,10 @@ github.com/antchfx/xmlquery v1.3.17/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7T github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY= github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwmarrin/discordgo v0.28.1 h1:gXsuo2GBO7NbR6uqmrrBDplPUx2T3nzu775q/Rd1aG4= github.com/bwmarrin/discordgo v0.28.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -23,6 +27,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2 h1:flLYmnQFZNo04x2NPehMbf30m7Pli57xwZ0NFqR/hb0= github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2/go.mod h1:NtWqRzAp/1tw+twkW8uuBenEVVYndEAZACWU3F3xdoQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -36,8 +41,20 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/eritikass/githubmarkdownconvertergo v0.1.10 h1:mL93ADvYMOeT15DcGtK9AaFFc+RcWcy6kQBC6yS/5f4= github.com/eritikass/githubmarkdownconvertergo v0.1.10/go.mod h1:BdpHs6imOtzE5KorbUtKa6bZ0ZBh1yFcrTTAL8FwDKY= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-telegram/bot v1.2.1 h1:FkrixLCtMtPUQAN4plXdNElbhkdXkx2p68YPXKBruDg= @@ -46,6 +63,8 @@ github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI= github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA= github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM= @@ -87,6 +106,7 @@ github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzea github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -94,10 +114,28 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o= github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -106,14 +144,26 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/metoro-io/mcp-golang v0.8.0 h1:DkigHa3w7WwMFomcEz5wiMDX94DsvVm/3mCV3d1obnc= +github.com/metoro-io/mcp-golang v0.8.0/go.mod h1:ifLP9ZzKpN1UqFWNTpAHOqSvNkMK6b7d1FSZ5Lu0lN0= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philippgille/chromem-go v0.5.0 h1:bryX0F3N6jnN/21iBd8i2/k9EzPTZn3nyiqAti19si8= github.com/philippgille/chromem-go v0.5.0/go.mod h1:hTd+wGEm/fFPQl7ilfCwQXkgEUxceYh86iIdoKMolPo= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw= github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -121,6 +171,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM= +github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY= github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA= github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/sashabaranov/go-openai v1.18.3 h1:dspFGkmZbhjg1059KhqLYSV2GaCiRIn+bOu50TlXUq8= @@ -130,30 +184,52 @@ github.com/slack-go/slack v0.12.5/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQ github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg= github.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo= github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64 h1:l/T7dYuJEQZOwVOpjIXr1180aM9PZL/d1MnMVIxefX4= github.com/thoj/go-ircevent v0.0.0-20210723090443-73e444401d64/go.mod h1:Q1NAJOuRdQCqN/VIWdnaaEhV8LpeO2rtlBP7/iDJNII= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tmc/langchaingo v0.1.8 h1:nrImgh0aWdu3stJTHz80N60WGwPWY8HXCK10gQny7bA= github.com/tmc/langchaingo v0.1.8/go.mod h1:iNBfS9e6jxBKsJSPWnlqNhoVWgdA3D1g5cdFJjbIZNQ= github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E= github.com/traefik/yaegi v0.16.1/go.mod h1:4eVhbPb3LnD2VigQjhYbEJ69vDRFdT2HQNrXx8eEwUY= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.starlark.net v0.0.0-20230302034142-4b1e35fe2254 h1:Ss6D3hLXTM0KobyBYEAygXzFfGcjnmfEJOBgSbemCtg= go.starlark.net v0.0.0-20230302034142-4b1e35fe2254/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= @@ -190,6 +266,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -251,9 +328,15 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/webui/views/create.html b/webui/views/create.html index c9d8ae3..0a7beca 100644 --- a/webui/views/create.html +++ b/webui/views/create.html @@ -35,6 +35,15 @@ Add Action + +
+
+ +
+ +
@@ -247,6 +256,27 @@ actionsSection.insertAdjacentHTML('beforeend', newActionHTML); }); + // Add MCP functionality + document.getElementById('addMCPButton').addEventListener('click', function() { + const mcpSection = document.getElementById('mcpSection'); + const newMCPIndex = mcpSection.getElementsByClassName('mcp_server').length; + const newMCPHTML = ` +
+

MCP Server ${newMCPIndex + 1}

+
+ + +
+
+ + +
+
+ `; + + mcpSection.insertAdjacentHTML('beforeend', newMCPHTML); + }); + // Add dynamic prompt functionality document.getElementById('dynamic_button').addEventListener('click', function() { const promptsSection = document.getElementById('dynamic_box'); @@ -354,6 +384,22 @@ } } jsonData.connectors = connectors; + + // MCP Servers + const mcpServers = []; + const mcpServerElements = document.getElementsByClassName('mcp_server'); + for (let i = 0; i < mcpServerElements.length; i++) { + const urlField = document.getElementById(`mcpURL${i}`); + const tokenField = document.getElementById(`mcpToken${i}`); + + if (urlField && urlField.value.trim()) { + mcpServers.push({ + url: urlField.value.trim(), + token: tokenField ? tokenField.value.trim() : '' + }); + } + } + jsonData.mcp_servers = mcpServers; // Process actions - KEEP CONFIG AS STRING const actions = []; diff --git a/webui/views/settings.html b/webui/views/settings.html index d89b122..c721307 100644 --- a/webui/views/settings.html +++ b/webui/views/settings.html @@ -59,6 +59,17 @@ Add Action
+ +
+ +
+ +
+ +
+
@@ -343,6 +354,28 @@ connectorsSection.insertAdjacentHTML('beforeend', newConnectorHTML); }); + // Add MCP functionality + document.getElementById('addMCPButton').addEventListener('click', function() { + const mcpSection = document.getElementById('mcpSection'); + const newMCPIndex = mcpSection.getElementsByClassName('mcp_server').length; + const newMCPHTML = ` +
+

MCP Server ${newMCPIndex + 1}

+
+ + +
+
+ + +
+
+ `; + + mcpSection.insertAdjacentHTML('beforeend', newMCPHTML); + }); + + // Add action functionality document.getElementById('action_button').addEventListener('click', function() { const actionsSection = document.getElementById('action_box'); @@ -472,7 +505,23 @@ } } jsonData.connectors = connectors; - + + // MCP Servers - updated to handle URL and token + const mcpServers = []; + const mcpServerElements = document.getElementsByClassName('mcp_server'); + for (let i = 0; i < mcpServerElements.length; i++) { + const urlField = document.getElementById(`mcpURL${i}`); + const tokenField = document.getElementById(`mcpToken${i}`); + + if (urlField && urlField.value.trim()) { + mcpServers.push({ + url: urlField.value.trim(), + token: tokenField ? tokenField.value.trim() : '' + }); + } + } + jsonData.mcp_servers = mcpServers; + // Process actions - KEEP CONFIG AS STRING const actions = []; const actionElements = document.getElementsByClassName('action'); @@ -649,9 +698,10 @@ } - function populateFormWithConfig(config) { + function populateFormWithConfig(config) { // Clear existing dynamic sections document.getElementById('connectorsSection').innerHTML = ''; + document.getElementById('mcpSection').innerHTML = ''; document.getElementById('action_box').innerHTML = ''; document.getElementById('dynamic_box').innerHTML = ''; @@ -695,6 +745,34 @@ }); } + // Populate MCP servers + if (config.mcp_servers && Array.isArray(config.mcp_servers)) { + config.mcp_servers.forEach((server, index) => { + // Add MCP server section + document.getElementById('addMCPButton').click(); + + // Find the added MCP server elements + const mcpURL = document.getElementById(`mcpURL${index}`); + const mcpToken = document.getElementById(`mcpToken${index}`); + + // Set values + if (mcpURL) { + // If server is a string (old format), use it as URL + if (typeof server === 'string') { + mcpURL.value = server; + } + // If server is an object (new format), extract URL + else if (typeof server === 'object' && server !== null) { + mcpURL.value = server.url || ''; + + if (mcpToken && server.token) { + mcpToken.value = server.token; + } + } + } + }); + } + // Populate actions if (config.actions && Array.isArray(config.actions)) { config.actions.forEach((action, index) => {