diff --git a/cmd/core-agent/main.go b/cmd/core-agent/main.go index ce1fd1b..9ba1e55 100644 --- a/cmd/core-agent/main.go +++ b/cmd/core-agent/main.go @@ -18,9 +18,15 @@ import ( ) func main() { - c := core.New(core.Options{ - {Key: "name", Value: "core-agent"}, - }) + r := core.New( + core.WithOptions(core.Options{{Key: "name", Value: "core-agent"}}), + ) + if !r.OK { + core.Error("failed to create core", "err", r.Value) + os.Exit(1) + } + c := r.Value.(*core.Core) + // Version set at build time: go build -ldflags "-X main.version=0.15.0" if version != "" { c.App().Version = version @@ -312,7 +318,8 @@ func main() { prep.SetCore(c) mon.SetCore(c) - // IPC handlers registered automatically in SetCore() + // Register post-completion pipeline as IPC handlers + agentic.RegisterHandlers(c, prep) // Register as Core services with lifecycle hooks c.Service("agentic", core.Service{ @@ -509,9 +516,9 @@ func main() { }) // Run CLI — resolves os.Args to command path - r := c.Cli().Run() - if !r.OK { - if err, ok := r.Value.(error); ok { + result := c.Cli().Run() + if !result.OK { + if err, ok := result.Value.(error); ok { core.Error(err.Error()) } os.Exit(1) diff --git a/pkg/agentic/prep_test.go b/pkg/agentic/prep_test.go index 7205b92..84628f7 100644 --- a/pkg/agentic/prep_test.go +++ b/pkg/agentic/prep_test.go @@ -190,7 +190,7 @@ func TestSetCore_Good(t *testing.T) { s := &PrepSubsystem{} assert.Nil(t, s.core) - c := core.New(core.Options{{Key: "name", Value: "test"}}) + c := core.New(core.WithOptions(core.Options{{Key: "name", Value: "test"}})).Value.(*core.Core) s.SetCore(c) assert.NotNil(t, s.core) } diff --git a/pkg/agentic/register.go b/pkg/agentic/register.go new file mode 100644 index 0000000..6b36649 --- /dev/null +++ b/pkg/agentic/register.go @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: EUPL-1.2 + +package agentic + +import ( + core "dappco.re/go/core" +) + +// Register is the service factory for core.WithService. +// It creates the PrepSubsystem, wires Core, registers lifecycle hooks, +// and registers IPC handlers — all during Core construction. +// +// core.New( +// core.WithService(agentic.Register), +// ) +func Register(c *core.Core) core.Result { + prep := NewPrep() + prep.core = c + + c.Service("agentic", core.Service{ + OnStart: func() core.Result { + prep.StartRunner() + return core.Result{OK: true} + }, + OnStop: func() core.Result { + prep.frozen = true + return core.Result{OK: true} + }, + }) + + RegisterHandlers(c, prep) + + return core.Result{OK: true} +} diff --git a/pkg/brain/register.go b/pkg/brain/register.go new file mode 100644 index 0000000..34bfb5a --- /dev/null +++ b/pkg/brain/register.go @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: EUPL-1.2 + +package brain + +import ( + core "dappco.re/go/core" +) + +// Register is the service factory for core.WithService. +// Brain has no lifecycle hooks — it's a stateless API proxy. +// +// core.New( +// core.WithService(brain.Register), +// ) +func Register(c *core.Core) core.Result { + brn := NewDirect() + + c.Service("brain", core.Service{}) + + _ = brn // brain instance available for MCP tool registration + return core.Result{OK: true} +} diff --git a/pkg/monitor/register.go b/pkg/monitor/register.go new file mode 100644 index 0000000..027e075 --- /dev/null +++ b/pkg/monitor/register.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: EUPL-1.2 + +package monitor + +import ( + "dappco.re/go/agent/pkg/messages" + core "dappco.re/go/core" +) + +// Register is the service factory for core.WithService. +// It creates the monitor subsystem, wires Core for IPC, +// and registers lifecycle hooks. +// +// core.New( +// core.WithService(monitor.Register), +// ) +func Register(c *core.Core) core.Result { + mon := New() + mon.core = c + + c.Service("monitor", core.Service{ + OnStart: func() core.Result { + mon.Start(c.Context()) + return core.Result{OK: true} + }, + }) + + // Register IPC handler for agent lifecycle events + c.RegisterAction(func(c *core.Core, msg core.Message) core.Result { + switch ev := msg.(type) { + case messages.AgentCompleted: + mon.handleAgentCompleted(ev) + case messages.AgentStarted: + mon.handleAgentStarted(ev) + } + return core.Result{OK: true} + }) + + return core.Result{OK: true} +}