fix(ax): finish brain provider cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
de7844dcb9
commit
c77a9b93bc
2 changed files with 60 additions and 27 deletions
|
|
@ -434,6 +434,7 @@ func (s *PrepSubsystem) gitCmd(ctx context.Context, dir string, args ...string)
|
|||
|
||||
## Changelog
|
||||
|
||||
- 2026-03-26: WIP — net/http consolidated to transport.go (ONE file). net/url + io/fs eliminated. RFC-025 updated with 3 new quality gates (net/http, net/url, io/fs). 1:1 test + example test coverage. Array[T].Deduplicate replaces custom helpers. Remaining: remove dead `client` field from test literals, brain/provider.go Gin handler.
|
||||
- 2026-03-29: brain/provider.go no longer imports net/http for Gin handlers. Handler responses now use named status constants and shared response helpers. HTTP remains intentionally centralised in pkg/agentic/transport.go.
|
||||
- 2026-03-26: WIP — net/http consolidated to transport.go (ONE file). net/url + io/fs eliminated. RFC-025 updated with 3 new quality gates (net/http, net/url, io/fs). 1:1 test + example test coverage. Array[T].Deduplicate replaces custom helpers.
|
||||
- 2026-03-25: Quality gates pass. Zero disallowed imports (all 10). encoding/json→Core JSON. path/filepath→Core Path. os→Core Env/Fs. io→Core ReadAll/WriteAll. go-process fully Result-native. ServiceRuntime on all subsystems. 22 named Actions + Task pipeline. ChannelNotifier→IPC. Reference docs synced.
|
||||
- 2026-03-25: Initial spec — written with full core/go v0.8.0 domain context.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
package brain
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"dappco.re/go/core/api"
|
||||
|
|
@ -33,8 +32,17 @@ var (
|
|||
_ provider.Renderable = (*BrainProvider)(nil)
|
||||
)
|
||||
|
||||
// NewProvider creates a brain provider that proxies to Laravel via the IDE bridge.
|
||||
// The WS hub is used to emit brain events. Pass nil for hub if not needed.
|
||||
const (
|
||||
statusOK = 200
|
||||
statusBadRequest = 400
|
||||
statusInternalServerError = 500
|
||||
statusServiceUnavailable = 503
|
||||
)
|
||||
|
||||
// NewProvider creates a provider backed by the IDE bridge.
|
||||
//
|
||||
// p := brain.NewProvider(bridge, hub)
|
||||
// p.RegisterRoutes(router.Group("/api/brain"))
|
||||
func NewProvider(bridge *ide.Bridge, hub *ws.Hub) *BrainProvider {
|
||||
return &BrainProvider{
|
||||
bridge: bridge,
|
||||
|
|
@ -42,13 +50,19 @@ func NewProvider(bridge *ide.Bridge, hub *ws.Hub) *BrainProvider {
|
|||
}
|
||||
}
|
||||
|
||||
// Name implements api.RouteGroup.
|
||||
// Name returns the provider name used during API registration.
|
||||
//
|
||||
// name := p.Name()
|
||||
func (p *BrainProvider) Name() string { return "brain" }
|
||||
|
||||
// BasePath implements api.RouteGroup.
|
||||
// BasePath returns the HTTP base path for the provider routes.
|
||||
//
|
||||
// base := p.BasePath()
|
||||
func (p *BrainProvider) BasePath() string { return "/api/brain" }
|
||||
|
||||
// Channels implements provider.Streamable.
|
||||
// Channels returns the WS channels emitted by brain actions.
|
||||
//
|
||||
// channels := p.Channels()
|
||||
func (p *BrainProvider) Channels() []string {
|
||||
return []string{
|
||||
"brain.remember.complete",
|
||||
|
|
@ -57,7 +71,9 @@ func (p *BrainProvider) Channels() []string {
|
|||
}
|
||||
}
|
||||
|
||||
// Element implements provider.Renderable.
|
||||
// Element returns the UI element metadata for the provider panel.
|
||||
//
|
||||
// spec := p.Element()
|
||||
func (p *BrainProvider) Element() provider.ElementSpec {
|
||||
return provider.ElementSpec{
|
||||
Tag: "core-brain-panel",
|
||||
|
|
@ -65,7 +81,9 @@ func (p *BrainProvider) Element() provider.ElementSpec {
|
|||
}
|
||||
}
|
||||
|
||||
// RegisterRoutes implements api.RouteGroup.
|
||||
// RegisterRoutes binds the provider handlers onto a router group.
|
||||
//
|
||||
// p.RegisterRoutes(router.Group("/api/brain"))
|
||||
func (p *BrainProvider) RegisterRoutes(rg *gin.RouterGroup) {
|
||||
rg.POST("/remember", p.remember)
|
||||
rg.POST("/recall", p.recall)
|
||||
|
|
@ -74,7 +92,9 @@ func (p *BrainProvider) RegisterRoutes(rg *gin.RouterGroup) {
|
|||
rg.GET("/status", p.status)
|
||||
}
|
||||
|
||||
// Describe implements api.DescribableGroup.
|
||||
// Describe returns the OpenAPI route descriptions for the provider.
|
||||
//
|
||||
// routes := p.Describe()
|
||||
func (p *BrainProvider) Describe() []api.RouteDescription {
|
||||
return []api.RouteDescription{
|
||||
{
|
||||
|
|
@ -190,13 +210,13 @@ func (p *BrainProvider) Describe() []api.RouteDescription {
|
|||
|
||||
func (p *BrainProvider) remember(c *gin.Context) {
|
||||
if p.bridge == nil {
|
||||
c.JSON(http.StatusServiceUnavailable, api.Fail("bridge_unavailable", "brain bridge not available"))
|
||||
p.respondBridgeUnavailable(c)
|
||||
return
|
||||
}
|
||||
|
||||
var input RememberInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Fail("invalid_input", err.Error()))
|
||||
p.respondInvalidInput(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +233,7 @@ func (p *BrainProvider) remember(c *gin.Context) {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Fail("bridge_error", err.Error()))
|
||||
p.respondBridgeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -222,18 +242,18 @@ func (p *BrainProvider) remember(c *gin.Context) {
|
|||
"project": input.Project,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{"success": true}))
|
||||
c.JSON(statusOK, api.OK(map[string]any{"success": true}))
|
||||
}
|
||||
|
||||
func (p *BrainProvider) recall(c *gin.Context) {
|
||||
if p.bridge == nil {
|
||||
c.JSON(http.StatusServiceUnavailable, api.Fail("bridge_unavailable", "brain bridge not available"))
|
||||
p.respondBridgeUnavailable(c)
|
||||
return
|
||||
}
|
||||
|
||||
var input RecallInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Fail("invalid_input", err.Error()))
|
||||
p.respondInvalidInput(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +266,7 @@ func (p *BrainProvider) recall(c *gin.Context) {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Fail("bridge_error", err.Error()))
|
||||
p.respondBridgeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +274,7 @@ func (p *BrainProvider) recall(c *gin.Context) {
|
|||
"query": input.Query,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(RecallOutput{
|
||||
c.JSON(statusOK, api.OK(RecallOutput{
|
||||
Success: true,
|
||||
Memories: []Memory{},
|
||||
}))
|
||||
|
|
@ -262,13 +282,13 @@ func (p *BrainProvider) recall(c *gin.Context) {
|
|||
|
||||
func (p *BrainProvider) forget(c *gin.Context) {
|
||||
if p.bridge == nil {
|
||||
c.JSON(http.StatusServiceUnavailable, api.Fail("bridge_unavailable", "brain bridge not available"))
|
||||
p.respondBridgeUnavailable(c)
|
||||
return
|
||||
}
|
||||
|
||||
var input ForgetInput
|
||||
if err := c.ShouldBindJSON(&input); err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Fail("invalid_input", err.Error()))
|
||||
p.respondInvalidInput(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -280,7 +300,7 @@ func (p *BrainProvider) forget(c *gin.Context) {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Fail("bridge_error", err.Error()))
|
||||
p.respondBridgeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +308,7 @@ func (p *BrainProvider) forget(c *gin.Context) {
|
|||
"id": input.ID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{
|
||||
c.JSON(statusOK, api.OK(map[string]any{
|
||||
"success": true,
|
||||
"forgotten": input.ID,
|
||||
}))
|
||||
|
|
@ -296,7 +316,7 @@ func (p *BrainProvider) forget(c *gin.Context) {
|
|||
|
||||
func (p *BrainProvider) list(c *gin.Context) {
|
||||
if p.bridge == nil {
|
||||
c.JSON(http.StatusServiceUnavailable, api.Fail("bridge_unavailable", "brain bridge not available"))
|
||||
p.respondBridgeUnavailable(c)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +324,7 @@ func (p *BrainProvider) list(c *gin.Context) {
|
|||
if rawLimit := c.Query("limit"); rawLimit != "" {
|
||||
parsedLimit, err := strconv.Atoi(rawLimit)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, api.Fail("invalid_limit", "limit must be an integer"))
|
||||
c.JSON(statusBadRequest, api.Fail("invalid_limit", "limit must be an integer"))
|
||||
return
|
||||
}
|
||||
limit = parsedLimit
|
||||
|
|
@ -320,11 +340,11 @@ func (p *BrainProvider) list(c *gin.Context) {
|
|||
},
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, api.Fail("bridge_error", err.Error()))
|
||||
p.respondBridgeError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, api.OK(ListOutput{
|
||||
c.JSON(statusOK, api.OK(ListOutput{
|
||||
Success: true,
|
||||
Memories: []Memory{},
|
||||
}))
|
||||
|
|
@ -335,11 +355,23 @@ func (p *BrainProvider) status(c *gin.Context) {
|
|||
if p.bridge != nil {
|
||||
connected = p.bridge.Connected()
|
||||
}
|
||||
c.JSON(http.StatusOK, api.OK(map[string]any{
|
||||
c.JSON(statusOK, api.OK(map[string]any{
|
||||
"connected": connected,
|
||||
}))
|
||||
}
|
||||
|
||||
func (p *BrainProvider) respondBridgeUnavailable(c *gin.Context) {
|
||||
c.JSON(statusServiceUnavailable, api.Fail("bridge_unavailable", "brain bridge not available"))
|
||||
}
|
||||
|
||||
func (p *BrainProvider) respondInvalidInput(c *gin.Context, err error) {
|
||||
c.JSON(statusBadRequest, api.Fail("invalid_input", err.Error()))
|
||||
}
|
||||
|
||||
func (p *BrainProvider) respondBridgeError(c *gin.Context, err error) {
|
||||
c.JSON(statusInternalServerError, api.Fail("bridge_error", err.Error()))
|
||||
}
|
||||
|
||||
// emitEvent sends a WS event if the hub is available.
|
||||
func (p *BrainProvider) emitEvent(channel string, data any) {
|
||||
if p.hub == nil {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue