feat(embeddings): add embedding model support and related changes
* Introduced EmbeddingModel method in Client and Provider interfaces * Updated InsertThought and SearchThoughts methods to handle embedding models * Created embeddings table and updated match_thoughts function for model filtering * Removed embedding column from thoughts table * Adjusted permissions for new embeddings table
This commit is contained in:
47
internal/mcpserver/schema.go
Normal file
47
internal/mcpserver/schema.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package mcpserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
"github.com/google/uuid"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
var toolSchemaOptions = &jsonschema.ForOptions{
|
||||
TypeSchemas: map[reflect.Type]*jsonschema.Schema{
|
||||
reflect.TypeFor[uuid.UUID](): {
|
||||
Type: "string",
|
||||
Format: "uuid",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func addTool[In any, Out any](server *mcp.Server, tool *mcp.Tool, handler func(context.Context, *mcp.CallToolRequest, In) (*mcp.CallToolResult, Out, error)) {
|
||||
if err := setToolSchemas[In, Out](tool); err != nil {
|
||||
panic(fmt.Sprintf("configure MCP tool %q schemas: %v", tool.Name, err))
|
||||
}
|
||||
mcp.AddTool(server, tool, handler)
|
||||
}
|
||||
|
||||
func setToolSchemas[In any, Out any](tool *mcp.Tool) error {
|
||||
if tool.InputSchema == nil {
|
||||
inputSchema, err := jsonschema.For[In](toolSchemaOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("infer input schema: %w", err)
|
||||
}
|
||||
tool.InputSchema = inputSchema
|
||||
}
|
||||
|
||||
if tool.OutputSchema == nil {
|
||||
outputSchema, err := jsonschema.For[Out](toolSchemaOptions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("infer output schema: %w", err)
|
||||
}
|
||||
tool.OutputSchema = outputSchema
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
42
internal/mcpserver/schema_test.go
Normal file
42
internal/mcpserver/schema_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package mcpserver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
|
||||
"git.warky.dev/wdevs/amcs/internal/tools"
|
||||
)
|
||||
|
||||
func TestSetToolSchemasUsesStringUUIDsInListOutput(t *testing.T) {
|
||||
tool := &mcp.Tool{Name: "list_thoughts"}
|
||||
|
||||
if err := setToolSchemas[tools.ListInput, tools.ListOutput](tool); err != nil {
|
||||
t.Fatalf("set tool schemas: %v", err)
|
||||
}
|
||||
|
||||
schema, ok := tool.OutputSchema.(*jsonschema.Schema)
|
||||
if !ok {
|
||||
t.Fatalf("output schema type = %T, want *jsonschema.Schema", tool.OutputSchema)
|
||||
}
|
||||
|
||||
thoughtsSchema := schema.Properties["thoughts"]
|
||||
if thoughtsSchema == nil {
|
||||
t.Fatal("missing thoughts schema")
|
||||
}
|
||||
if thoughtsSchema.Items == nil {
|
||||
t.Fatal("missing thoughts item schema")
|
||||
}
|
||||
|
||||
idSchema := thoughtsSchema.Items.Properties["id"]
|
||||
if idSchema == nil {
|
||||
t.Fatal("missing id schema")
|
||||
}
|
||||
if idSchema.Type != "string" {
|
||||
t.Fatalf("id schema type = %q, want %q", idSchema.Type, "string")
|
||||
}
|
||||
if idSchema.Format != "uuid" {
|
||||
t.Fatalf("id schema format = %q, want %q", idSchema.Format, "uuid")
|
||||
}
|
||||
}
|
||||
@@ -32,87 +32,87 @@ func New(cfg config.MCPConfig, toolSet ToolSet) http.Handler {
|
||||
Version: cfg.Version,
|
||||
}, nil)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "capture_thought",
|
||||
Description: "Store a thought with generated embeddings and extracted metadata.",
|
||||
}, toolSet.Capture.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "search_thoughts",
|
||||
Description: "Search stored thoughts by semantic similarity.",
|
||||
}, toolSet.Search.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "list_thoughts",
|
||||
Description: "List recent thoughts with optional metadata filters.",
|
||||
}, toolSet.List.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "thought_stats",
|
||||
Description: "Get counts and top metadata buckets across stored thoughts.",
|
||||
}, toolSet.Stats.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "get_thought",
|
||||
Description: "Retrieve a full thought by id.",
|
||||
}, toolSet.Get.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "update_thought",
|
||||
Description: "Update thought content or merge metadata.",
|
||||
}, toolSet.Update.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "delete_thought",
|
||||
Description: "Hard-delete a thought by id.",
|
||||
}, toolSet.Delete.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "archive_thought",
|
||||
Description: "Archive a thought so it is hidden from default search and listing.",
|
||||
}, toolSet.Archive.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "create_project",
|
||||
Description: "Create a named project container for thoughts.",
|
||||
}, toolSet.Projects.Create)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "list_projects",
|
||||
Description: "List projects and their current thought counts.",
|
||||
}, toolSet.Projects.List)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "set_active_project",
|
||||
Description: "Set the active project for the current MCP session.",
|
||||
}, toolSet.Projects.SetActive)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "get_active_project",
|
||||
Description: "Return the active project for the current MCP session.",
|
||||
}, toolSet.Projects.GetActive)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "get_project_context",
|
||||
Description: "Get recent and semantic context for a project.",
|
||||
}, toolSet.Context.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "recall_context",
|
||||
Description: "Recall semantically relevant and recent context.",
|
||||
}, toolSet.Recall.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "summarize_thoughts",
|
||||
Description: "Summarize a filtered or searched set of thoughts.",
|
||||
}, toolSet.Summarize.Handle)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "link_thoughts",
|
||||
Description: "Create a typed relationship between two thoughts.",
|
||||
}, toolSet.Links.Link)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
addTool(server, &mcp.Tool{
|
||||
Name: "related_thoughts",
|
||||
Description: "Retrieve explicit links and semantic neighbors for a thought.",
|
||||
}, toolSet.Links.Related)
|
||||
|
||||
Reference in New Issue
Block a user