feat(agentic): expose setup action surface
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
613e1fc58e
commit
7a034ccbe8
4 changed files with 83 additions and 4 deletions
|
|
@ -3,8 +3,11 @@
|
|||
package agentic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"dappco.re/go/agent/pkg/setup"
|
||||
core "dappco.re/go/core"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
func (s *PrepSubsystem) registerSetupCommands() {
|
||||
|
|
@ -14,17 +17,27 @@ func (s *PrepSubsystem) registerSetupCommands() {
|
|||
}
|
||||
|
||||
func (s *PrepSubsystem) cmdSetup(options core.Options) core.Result {
|
||||
return s.handleSetup(context.Background(), options)
|
||||
}
|
||||
|
||||
// result := c.Action("agentic.setup").Run(ctx, core.NewOptions(
|
||||
//
|
||||
// core.Option{Key: "path", Value: "."},
|
||||
// core.Option{Key: "template", Value: "auto"},
|
||||
//
|
||||
// ))
|
||||
func (s *PrepSubsystem) handleSetup(_ context.Context, options core.Options) core.Result {
|
||||
serviceResult := s.Core().Service("setup")
|
||||
if !serviceResult.OK {
|
||||
if serviceResult.Value != nil {
|
||||
return core.Result{Value: serviceResult.Value, OK: false}
|
||||
return core.Result{Value: core.E("agentic.setup", "setup service is required", nil), OK: false}
|
||||
}
|
||||
return core.Result{Value: core.E("agentic.cmdSetup", "setup service is required", nil), OK: false}
|
||||
return core.Result{Value: core.E("agentic.setup", "setup service is required", nil), OK: false}
|
||||
}
|
||||
|
||||
service, ok := serviceResult.Value.(*setup.Service)
|
||||
if !ok || service == nil {
|
||||
return core.Result{Value: core.E("agentic.cmdSetup", "setup service is required", nil), OK: false}
|
||||
return core.Result{Value: core.E("agentic.setup", "setup service is required", nil), OK: false}
|
||||
}
|
||||
|
||||
result := service.Run(setup.Options{
|
||||
|
|
@ -39,3 +52,44 @@ func (s *PrepSubsystem) cmdSetup(options core.Options) core.Result {
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) registerSetupTool(server *mcp.Server) {
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
Name: "agentic_setup",
|
||||
Description: "Scaffold a workspace with .core config files and optional templates.",
|
||||
}, s.setupTool)
|
||||
}
|
||||
|
||||
type SetupInput struct {
|
||||
Path string `json:"path,omitempty"`
|
||||
DryRun bool `json:"dry_run,omitempty"`
|
||||
Force bool `json:"force,omitempty"`
|
||||
Template string `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
type SetupOutput struct {
|
||||
Success bool `json:"success"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) setupTool(ctx context.Context, _ *mcp.CallToolRequest, input SetupInput) (*mcp.CallToolResult, SetupOutput, error) {
|
||||
result := s.handleSetup(ctx, core.NewOptions(
|
||||
core.Option{Key: "path", Value: input.Path},
|
||||
core.Option{Key: "dry_run", Value: input.DryRun},
|
||||
core.Option{Key: "force", Value: input.Force},
|
||||
core.Option{Key: "template", Value: input.Template},
|
||||
))
|
||||
if !result.OK {
|
||||
return nil, SetupOutput{}, resultErrorValue("agentic.setup", result)
|
||||
}
|
||||
|
||||
path, ok := result.Value.(string)
|
||||
if !ok {
|
||||
return nil, SetupOutput{}, core.E("agentic.setup", "invalid setup output", nil)
|
||||
}
|
||||
|
||||
return nil, SetupOutput{
|
||||
Success: true,
|
||||
Path: path,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
package agentic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -64,3 +65,23 @@ func TestCommandsSetup_CmdSetup_Ugly_DryRunDoesNotWrite(t *testing.T) {
|
|||
assert.False(t, fs.Exists(core.JoinPath(dir, ".core")))
|
||||
assert.False(t, fs.Exists(core.JoinPath(dir, "PROMPT.md")))
|
||||
}
|
||||
|
||||
func TestCommandsSetup_HandleSetup_Good_ActionAlias(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
require.True(t, fs.WriteMode(core.JoinPath(dir, "go.mod"), "module example.com/test\n", 0644).OK)
|
||||
|
||||
c := core.New(core.WithService(setup.Register))
|
||||
s := &PrepSubsystem{
|
||||
ServiceRuntime: core.NewServiceRuntime(c, AgentOptions{}),
|
||||
backoff: make(map[string]time.Time),
|
||||
failCount: make(map[string]int),
|
||||
}
|
||||
|
||||
result := s.handleSetup(context.Background(), core.NewOptions(core.Option{Key: "path", Value: dir}))
|
||||
require.True(t, result.OK)
|
||||
|
||||
createdPath, ok := result.Value.(string)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, dir, createdPath)
|
||||
assert.True(t, fs.Exists(core.JoinPath(dir, ".core", "build.yaml")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func (s *PrepSubsystem) OnStartup(ctx context.Context) core.Result {
|
|||
case "agentic.status", "agentic.scan", "agentic.watch",
|
||||
"agentic.issue.get", "agentic.issue.list", "agentic.issue.assign", "agentic.pr.get", "agentic.pr.list",
|
||||
"agentic.prompt", "agentic.task", "agentic.flow", "agentic.persona",
|
||||
"agentic.prompt.version",
|
||||
"agentic.prompt.version", "agentic.setup",
|
||||
"agentic.sync.status", "agentic.fleet.nodes", "agentic.fleet.stats", "agentic.fleet.events",
|
||||
"agentic.credits.balance", "agentic.credits.history",
|
||||
"agentic.subscription.detect", "agentic.subscription.budget",
|
||||
|
|
@ -184,6 +184,7 @@ func (s *PrepSubsystem) OnStartup(ctx context.Context) core.Result {
|
|||
c.Action("agentic.ingest", s.handleIngest).Description = "Create issues from agent findings"
|
||||
c.Action("agentic.poke", s.handlePoke).Description = "Drain next queued task from the queue"
|
||||
c.Action("agentic.mirror", s.handleMirror).Description = "Mirror agent branches to GitHub"
|
||||
c.Action("agentic.setup", s.handleSetup).Description = "Scaffold a workspace with .core config files and optional templates"
|
||||
|
||||
c.Action("agentic.issue.get", s.handleIssueGet).Description = "Get a Forge issue by number"
|
||||
c.Action("agentic.issue.list", s.handleIssueList).Description = "List Forge issues for a repo"
|
||||
|
|
@ -454,6 +455,7 @@ func (s *PrepSubsystem) RegisterTools(server *mcp.Server) {
|
|||
s.registerPRTools(server)
|
||||
s.registerContentTools(server)
|
||||
s.registerLanguageTools(server)
|
||||
s.registerSetupTool(server)
|
||||
|
||||
mcp.AddTool(server, &mcp.Tool{
|
||||
Name: "agentic_scan",
|
||||
|
|
|
|||
|
|
@ -712,6 +712,7 @@ func TestPrep_RegisterTools_Good_RegistersCompletionTool(t *testing.T) {
|
|||
assert.Contains(t, toolNames, "agentic_complete")
|
||||
assert.Contains(t, toolNames, "prompt_version")
|
||||
assert.Contains(t, toolNames, "agentic_prompt_version")
|
||||
assert.Contains(t, toolNames, "agentic_setup")
|
||||
assert.Contains(t, toolNames, "session_complete")
|
||||
assert.Contains(t, toolNames, "agentic_message_send")
|
||||
assert.Contains(t, toolNames, "agent_send")
|
||||
|
|
@ -738,6 +739,7 @@ func TestPrep_OnStartup_Good_RegistersGenerateCommand(t *testing.T) {
|
|||
assert.Contains(t, c.Commands(), "prep-workspace")
|
||||
assert.Contains(t, c.Commands(), "setup")
|
||||
assert.Contains(t, c.Commands(), "agentic:setup")
|
||||
assert.True(t, c.Action("agentic.setup").Exists())
|
||||
assert.Contains(t, c.Commands(), "watch")
|
||||
assert.Contains(t, c.Commands(), "workspace/watch")
|
||||
assert.Contains(t, c.Commands(), "agentic:watch")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue