diff --git a/pkg/agentic/actions.go b/pkg/agentic/actions.go index 9981fc3..c89a5fa 100644 --- a/pkg/agentic/actions.go +++ b/pkg/agentic/actions.go @@ -11,6 +11,7 @@ import ( "dappco.re/go/agent/pkg/lib" "dappco.re/go/agent/pkg/messages" core "dappco.re/go/core" + "github.com/modelcontextprotocol/go-sdk/mcp" ) // result := c.Action("agentic.dispatch").Run(ctx, core.NewOptions( @@ -154,6 +155,33 @@ func (s *PrepSubsystem) handleComplete(ctx context.Context, options core.Options return s.Core().Task("agent.completion").Run(ctx, s.Core(), options) } +// input := agentic.CompleteInput{Workspace: "/srv/.core/workspace/core/go-io/task-42"} +type CompleteInput struct { + Workspace string `json:"workspace"` +} + +// out := agentic.CompleteOutput{Success: true, Workspace: "core/go-io/task-42"} +type CompleteOutput struct { + Success bool `json:"success"` + Workspace string `json:"workspace"` +} + +func (s *PrepSubsystem) completeTool(ctx context.Context, _ *mcp.CallToolRequest, input CompleteInput) (*mcp.CallToolResult, CompleteOutput, error) { + if input.Workspace == "" { + return nil, CompleteOutput{}, core.E("agentic.complete", "workspace is required", nil) + } + + result := s.handleComplete(ctx, core.NewOptions(core.Option{Key: "workspace", Value: input.Workspace})) + if !result.OK { + return nil, CompleteOutput{}, resultErrorValue("agentic.complete", result) + } + + return nil, CompleteOutput{ + Success: true, + Workspace: input.Workspace, + }, nil +} + // result := c.Action("agentic.qa").Run(ctx, core.NewOptions( // // core.Option{Key: "workspace", Value: "/path/to/workspace"}, diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index 446a05e..7b10045 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -357,6 +357,10 @@ func (s *PrepSubsystem) RegisterTools(server *mcp.Server) { s.registerDispatchTool(server) s.registerStatusTool(server) s.registerResumeTool(server) + mcp.AddTool(server, &mcp.Tool{ + Name: "agentic_complete", + Description: "Run the completion pipeline (QA → PR → Verify → Ingest → Poke) in the background.", + }, s.completeTool) s.registerCreatePRTool(server) s.registerListPRsTool(server) s.registerClosePRTool(server) diff --git a/pkg/agentic/prep_test.go b/pkg/agentic/prep_test.go index f112025..01cea6a 100644 --- a/pkg/agentic/prep_test.go +++ b/pkg/agentic/prep_test.go @@ -12,6 +12,7 @@ import ( core "dappco.re/go/core" "dappco.re/go/core/forge" + mcpsdk "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -609,6 +610,38 @@ func TestPrep_OnStartup_Good_RegistersPlatformCommandAlias(t *testing.T) { assert.Contains(t, c.Commands(), "fleet/events") } +func TestPrep_RegisterTools_Good_RegistersCompletionTool(t *testing.T) { + server := mcpsdk.NewServer(&mcpsdk.Implementation{Name: "test", Version: "0.1.0"}, &mcpsdk.ServerOptions{ + Capabilities: &mcpsdk.ServerCapabilities{ + Tools: &mcpsdk.ToolCapabilities{ListChanged: true}, + }, + }) + + subsystem := &PrepSubsystem{} + subsystem.RegisterTools(server) + + client := mcpsdk.NewClient(&mcpsdk.Implementation{Name: "test", Version: "0.1.0"}, nil) + clientTransport, serverTransport := mcpsdk.NewInMemoryTransports() + + serverSession, err := server.Connect(context.Background(), serverTransport, nil) + require.NoError(t, err) + t.Cleanup(func() { _ = serverSession.Close() }) + + clientSession, err := client.Connect(context.Background(), clientTransport, nil) + require.NoError(t, err) + t.Cleanup(func() { _ = clientSession.Close() }) + + result, err := clientSession.ListTools(context.Background(), nil) + require.NoError(t, err) + + var toolNames []string + for _, tool := range result.Tools { + toolNames = append(toolNames, tool.Name) + } + + assert.Contains(t, toolNames, "agentic_complete") +} + func TestPrep_OnStartup_Good_RegistersGenerateCommand(t *testing.T) { t.Setenv("CORE_WORKSPACE", t.TempDir()) t.Setenv("CORE_AGENT_DISPATCH", "")