2026-03-16 11:10:33 +00:00
// SPDX-License-Identifier: EUPL-1.2
package brain
import (
"context"
"time"
2026-03-22 03:41:07 +00:00
core "dappco.re/go/core"
2026-03-29 20:15:58 +00:00
"forge.lthn.ai/core/mcp/pkg/mcp/ide"
2026-03-16 11:10:33 +00:00
"github.com/modelcontextprotocol/go-sdk/mcp"
)
2026-03-22 13:02:37 +00:00
// input := brain.RememberInput{
2026-03-30 22:54:19 +00:00
// Content: "Use core.Env for system paths.",
// Type: "convention",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type RememberInput struct {
Content string ` json:"content" `
Type string ` json:"type" `
Tags [ ] string ` json:"tags,omitempty" `
Project string ` json:"project,omitempty" `
Confidence float64 ` json:"confidence,omitempty" `
Supersedes string ` json:"supersedes,omitempty" `
ExpiresIn int ` json:"expires_in,omitempty" `
}
2026-03-22 13:02:37 +00:00
// output := brain.RememberOutput{
2026-03-30 22:54:19 +00:00
// Success: true,
// MemoryID: "mem_123",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type RememberOutput struct {
Success bool ` json:"success" `
2026-04-02 08:49:22 +00:00
MemoryID string ` json:"memory_id,omitempty" `
2026-03-16 11:10:33 +00:00
Timestamp time . Time ` json:"timestamp" `
}
2026-03-22 13:02:37 +00:00
// input := brain.RecallInput{
2026-03-30 22:54:19 +00:00
// Query: "core.Env conventions",
// TopK: 5,
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type RecallInput struct {
2026-03-20 19:31:45 +00:00
Query string ` json:"query" `
TopK int ` json:"top_k,omitempty" `
2026-03-16 11:10:33 +00:00
Filter RecallFilter ` json:"filter,omitempty" `
}
2026-03-22 13:02:37 +00:00
// filter := brain.RecallFilter{
2026-03-30 22:54:19 +00:00
// Project: "agent",
// Type: "convention",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type RecallFilter struct {
2026-03-20 19:31:45 +00:00
Project string ` json:"project,omitempty" `
Type any ` json:"type,omitempty" `
AgentID string ` json:"agent_id,omitempty" `
MinConfidence float64 ` json:"min_confidence,omitempty" `
2026-03-16 11:10:33 +00:00
}
2026-03-22 13:02:37 +00:00
// output := brain.RecallOutput{
2026-03-30 22:54:19 +00:00
// Success: true,
// Count: 1,
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type RecallOutput struct {
Success bool ` json:"success" `
Count int ` json:"count" `
Memories [ ] Memory ` json:"memories" `
}
2026-03-22 13:02:37 +00:00
// memory := brain.Memory{
2026-03-30 22:54:19 +00:00
// ID: "mem_123",
// Type: "convention",
// Content: "Use core.Env for system paths.",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type Memory struct {
2026-04-02 02:39:59 +00:00
ID string ` json:"id" `
2026-04-02 08:26:02 +00:00
WorkspaceID string ` json:"workspace_id,omitempty" `
2026-04-02 02:39:59 +00:00
AgentID string ` json:"agent_id" `
Type string ` json:"type" `
Content string ` json:"content" `
Tags [ ] string ` json:"tags,omitempty" `
Project string ` json:"project,omitempty" `
Source string ` json:"source,omitempty" `
Confidence float64 ` json:"confidence" `
SupersedesID string ` json:"supersedes_id,omitempty" `
SupersedesCount int ` json:"supersedes_count,omitempty" `
ExpiresAt string ` json:"expires_at,omitempty" `
2026-04-02 05:11:48 +00:00
DeletedAt string ` json:"deleted_at,omitempty" `
2026-04-02 02:39:59 +00:00
CreatedAt string ` json:"created_at" `
UpdatedAt string ` json:"updated_at" `
2026-03-16 11:10:33 +00:00
}
2026-04-02 09:07:12 +00:00
// memory := brain.BrainMemory{ID: "mem_123", Type: "convention", Content: "Use core.Trim for clean input."}
2026-04-02 00:53:11 +00:00
type BrainMemory = Memory
2026-03-22 13:02:37 +00:00
// input := brain.ForgetInput{
2026-03-30 22:54:19 +00:00
// ID: "mem_123",
// Reason: "superseded",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type ForgetInput struct {
ID string ` json:"id" `
Reason string ` json:"reason,omitempty" `
}
2026-03-22 13:02:37 +00:00
// output := brain.ForgetOutput{
2026-03-30 22:54:19 +00:00
// Success: true,
// Forgotten: "mem_123",
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type ForgetOutput struct {
Success bool ` json:"success" `
Forgotten string ` json:"forgotten" `
Timestamp time . Time ` json:"timestamp" `
}
2026-03-22 13:02:37 +00:00
// input := brain.ListInput{
2026-03-30 22:54:19 +00:00
// Project: "agent",
// Limit: 20,
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type ListInput struct {
Project string ` json:"project,omitempty" `
Type string ` json:"type,omitempty" `
AgentID string ` json:"agent_id,omitempty" `
Limit int ` json:"limit,omitempty" `
}
2026-03-22 13:02:37 +00:00
// output := brain.ListOutput{
2026-03-30 22:54:19 +00:00
// Success: true,
// Count: 2,
2026-03-22 13:02:37 +00:00
// }
2026-03-16 11:10:33 +00:00
type ListOutput struct {
Success bool ` json:"success" `
Count int ` json:"count" `
Memories [ ] Memory ` json:"memories" `
}
func ( s * Subsystem ) registerBrainTools ( server * mcp . Server ) {
mcp . AddTool ( server , & mcp . Tool {
Name : "brain_remember" ,
Description : "Store a memory in the shared OpenBrain knowledge store. Persists decisions, observations, conventions, research, plans, bugs, or architecture knowledge for other agents." ,
} , s . brainRemember )
mcp . AddTool ( server , & mcp . Tool {
Name : "brain_recall" ,
Description : "Semantic search across the shared OpenBrain knowledge store. Returns memories ranked by similarity to your query, with optional filtering." ,
} , s . brainRecall )
mcp . AddTool ( server , & mcp . Tool {
Name : "brain_forget" ,
Description : "Remove a memory from the shared OpenBrain knowledge store. Permanently deletes from both database and vector index." ,
} , s . brainForget )
mcp . AddTool ( server , & mcp . Tool {
Name : "brain_list" ,
Description : "List memories in the shared OpenBrain knowledge store. Supports filtering by project, type, and agent. No vector search -- use brain_recall for semantic queries." ,
} , s . brainList )
}
func ( s * Subsystem ) brainRemember ( _ context . Context , _ * mcp . CallToolRequest , input RememberInput ) ( * mcp . CallToolResult , RememberOutput , error ) {
if s . bridge == nil {
return nil , RememberOutput { } , errBridgeNotAvailable
}
err := s . bridge . Send ( ide . BridgeMessage {
Type : "brain_remember" ,
Data : map [ string ] any {
"content" : input . Content ,
"type" : input . Type ,
"tags" : input . Tags ,
"project" : input . Project ,
"confidence" : input . Confidence ,
"supersedes" : input . Supersedes ,
"expires_in" : input . ExpiresIn ,
} ,
} )
if err != nil {
2026-03-22 03:41:07 +00:00
return nil , RememberOutput { } , core . E ( "brain.remember" , "failed to send brain_remember" , err )
2026-03-16 11:10:33 +00:00
}
return nil , RememberOutput {
Success : true ,
Timestamp : time . Now ( ) ,
} , nil
}
func ( s * Subsystem ) brainRecall ( _ context . Context , _ * mcp . CallToolRequest , input RecallInput ) ( * mcp . CallToolResult , RecallOutput , error ) {
if s . bridge == nil {
return nil , RecallOutput { } , errBridgeNotAvailable
}
err := s . bridge . Send ( ide . BridgeMessage {
Type : "brain_recall" ,
Data : map [ string ] any {
"query" : input . Query ,
"top_k" : input . TopK ,
"filter" : input . Filter ,
} ,
} )
if err != nil {
2026-03-22 03:41:07 +00:00
return nil , RecallOutput { } , core . E ( "brain.recall" , "failed to send brain_recall" , err )
2026-03-16 11:10:33 +00:00
}
return nil , RecallOutput {
Success : true ,
Memories : [ ] Memory { } ,
} , nil
}
func ( s * Subsystem ) brainForget ( _ context . Context , _ * mcp . CallToolRequest , input ForgetInput ) ( * mcp . CallToolResult , ForgetOutput , error ) {
if s . bridge == nil {
return nil , ForgetOutput { } , errBridgeNotAvailable
}
err := s . bridge . Send ( ide . BridgeMessage {
Type : "brain_forget" ,
Data : map [ string ] any {
"id" : input . ID ,
"reason" : input . Reason ,
} ,
} )
if err != nil {
2026-03-22 03:41:07 +00:00
return nil , ForgetOutput { } , core . E ( "brain.forget" , "failed to send brain_forget" , err )
2026-03-16 11:10:33 +00:00
}
return nil , ForgetOutput {
Success : true ,
Forgotten : input . ID ,
Timestamp : time . Now ( ) ,
} , nil
}
func ( s * Subsystem ) brainList ( _ context . Context , _ * mcp . CallToolRequest , input ListInput ) ( * mcp . CallToolResult , ListOutput , error ) {
if s . bridge == nil {
return nil , ListOutput { } , errBridgeNotAvailable
}
err := s . bridge . Send ( ide . BridgeMessage {
Type : "brain_list" ,
Data : map [ string ] any {
"project" : input . Project ,
"type" : input . Type ,
"agent_id" : input . AgentID ,
"limit" : input . Limit ,
} ,
} )
if err != nil {
2026-03-22 03:41:07 +00:00
return nil , ListOutput { } , core . E ( "brain.list" , "failed to send brain_list" , err )
2026-03-16 11:10:33 +00:00
}
return nil , ListOutput {
Success : true ,
Memories : [ ] Memory { } ,
} , nil
}