44 "context"
55 "encoding/json"
66 "fmt"
7+ "strings"
78 "sync"
9+ "time"
810
911 "github.com/voocel/mas/llm"
1012)
@@ -20,7 +22,13 @@ type agent struct {
2022 state map [string ]interface {}
2123 provider llm.Provider
2224 eventBus EventBus
23- mu sync.RWMutex
25+
26+ // Cognitive ability
27+ skillLibrary SkillLibrary
28+ cognitiveState * CognitiveState
29+ cognitiveMode CognitiveMode
30+
31+ mu sync.RWMutex
2432}
2533
2634func NewAgent (model , apiKey string ) Agent {
@@ -30,13 +38,22 @@ func NewAgent(model, apiKey string) Agent {
3038 }
3139
3240 return & agent {
33- name : "assistant" ,
34- model : model ,
35- temperature : 0.7 ,
36- maxTokens : 2000 ,
37- tools : make ([]Tool , 0 ),
38- state : make (map [string ]interface {}),
39- provider : provider ,
41+ name : "assistant" ,
42+ model : model ,
43+ temperature : 0.7 ,
44+ maxTokens : 2000 ,
45+ tools : make ([]Tool , 0 ),
46+ state : make (map [string ]interface {}),
47+ provider : provider ,
48+ skillLibrary : NewSkillLibrary (),
49+ cognitiveState : & CognitiveState {
50+ CurrentLayer : CortexLayer ,
51+ Mode : AutomaticMode ,
52+ LoadedSkills : make ([]string , 0 ),
53+ RecentDecisions : make ([]* Decision , 0 ),
54+ LastUpdate : time .Now (),
55+ },
56+ cognitiveMode : AutomaticMode ,
4057 }
4158}
4259
@@ -525,3 +542,321 @@ func (a *agent) convertToolsToLLMFormat() []llm.ToolDefinition {
525542
526543 return tools
527544}
545+
546+ // Cognitive capabilities implementation
547+
548+ func (a * agent ) Plan (ctx context.Context , goal string ) (* Plan , error ) {
549+ a .mu .Lock ()
550+ defer a .mu .Unlock ()
551+
552+ // Emit planning event
553+ if err := a .PublishEvent (ctx , EventType ("agent.plan.start" ), EventData (
554+ "goal" , goal ,
555+ "agent_name" , a .name ,
556+ )); err != nil {
557+ fmt .Printf ("Failed to publish plan start event: %v\n " , err )
558+ }
559+
560+ // Use LLM to generate plan
561+ planPrompt := fmt .Sprintf (`Create a step-by-step plan to achieve this goal: %s
562+
563+ Please respond with a structured plan including:
564+ 1. Break down into logical steps
565+ 2. Identify which cognitive layer each step should use:
566+ - reflex: immediate responses
567+ - cerebellum: learned skills
568+ - cortex: reasoning and analysis
569+ - meta: high-level planning
570+
571+ Goal: %s` , goal , goal )
572+
573+ response , err := a .Chat (ctx , planPrompt )
574+ if err != nil {
575+ return nil , fmt .Errorf ("failed to generate plan: %w" , err )
576+ }
577+
578+ plan := NewPlan (goal )
579+ plan .Context ["llm_response" ] = response
580+
581+ // Update cognitive state
582+ a .cognitiveState .ActivePlan = plan
583+ a .cognitiveState .CurrentLayer = MetaLayer
584+ a .cognitiveState .LastUpdate = time .Now ()
585+
586+ // Emit planning completion event
587+ if err := a .PublishEvent (ctx , EventType ("agent.plan.complete" ), EventData (
588+ "plan_id" , plan .ID ,
589+ "goal" , goal ,
590+ "agent_name" , a .name ,
591+ )); err != nil {
592+ fmt .Printf ("Failed to publish plan complete event: %v\n " , err )
593+ }
594+
595+ return plan , nil
596+ }
597+
598+ func (a * agent ) Reason (ctx context.Context , situation * Situation ) (* Decision , error ) {
599+ a .mu .Lock ()
600+ defer a .mu .Unlock ()
601+
602+ // Emit reasoning event
603+ if err := a .PublishEvent (ctx , EventType ("agent.reason.start" ), EventData (
604+ "situation" , situation ,
605+ "agent_name" , a .name ,
606+ )); err != nil {
607+ fmt .Printf ("Failed to publish reason start event: %v\n " , err )
608+ }
609+
610+ // Create reasoning prompt
611+ reasoningPrompt := fmt .Sprintf (`Analyze this situation and make a decision:
612+
613+ Context: %v
614+ Inputs: %v
615+ Constraints: %v
616+ Goals: %v
617+
618+ Please provide:
619+ 1. Your analysis of the situation
620+ 2. Recommended action
621+ 3. Confidence level (0-1)
622+ 4. Which cognitive layer to use for execution` ,
623+ situation .Context , situation .Inputs , situation .Constraints , situation .Goals )
624+
625+ response , err := a .Chat (ctx , reasoningPrompt )
626+ if err != nil {
627+ return nil , fmt .Errorf ("failed to reason about situation: %w" , err )
628+ }
629+
630+ // Create decision
631+ decision := & Decision {
632+ Action : extractAction (response ),
633+ Layer : CortexLayer ,
634+ Confidence : extractConfidence (response ),
635+ Reasoning : response ,
636+ Parameters : make (map [string ]interface {}),
637+ Timestamp : time .Now (),
638+ }
639+
640+ // Update cognitive state
641+ a .cognitiveState .RecentDecisions = append (a .cognitiveState .RecentDecisions , decision )
642+ if len (a .cognitiveState .RecentDecisions ) > 10 {
643+ a .cognitiveState .RecentDecisions = a .cognitiveState .RecentDecisions [1 :]
644+ }
645+ a .cognitiveState .CurrentLayer = CortexLayer
646+ a .cognitiveState .LastUpdate = time .Now ()
647+
648+ // Emit reasoning completion event
649+ if err := a .PublishEvent (ctx , EventType ("agent.reason.complete" ), EventData (
650+ "decision" , decision ,
651+ "agent_name" , a .name ,
652+ )); err != nil {
653+ fmt .Printf ("Failed to publish reason complete event: %v\n " , err )
654+ }
655+
656+ return decision , nil
657+ }
658+
659+ func (a * agent ) ExecuteSkill (ctx context.Context , skillName string , params map [string ]interface {}) (interface {}, error ) {
660+ a .mu .RLock ()
661+ skill , err := a .skillLibrary .GetSkill (skillName )
662+ a .mu .RUnlock ()
663+
664+ if err != nil {
665+ return nil , fmt .Errorf ("skill not found: %w" , err )
666+ }
667+
668+ // Emit skill execution event
669+ if err := a .PublishEvent (ctx , EventType ("agent.skill.start" ), EventData (
670+ "skill_name" , skillName ,
671+ "parameters" , params ,
672+ "agent_name" , a .name ,
673+ )); err != nil {
674+ fmt .Printf ("Failed to publish skill start event: %v\n " , err )
675+ }
676+
677+ // Execute skill
678+ result , err := skill .Execute (ctx , params )
679+
680+ // Update cognitive state
681+ a .mu .Lock ()
682+ a .cognitiveState .CurrentLayer = skill .Layer ()
683+ a .cognitiveState .LastUpdate = time .Now ()
684+ a .mu .Unlock ()
685+
686+ // Emit skill completion event
687+ eventType := EventType ("agent.skill.complete" )
688+ eventData := EventData (
689+ "skill_name" , skillName ,
690+ "parameters" , params ,
691+ "agent_name" , a .name ,
692+ "success" , err == nil ,
693+ )
694+
695+ if err != nil {
696+ eventType = EventType ("agent.skill.error" )
697+ eventData ["error" ] = err .Error ()
698+ } else {
699+ eventData ["result" ] = result
700+ }
701+
702+ if publishErr := a .PublishEvent (ctx , eventType , eventData ); publishErr != nil {
703+ fmt .Printf ("Failed to publish skill event: %v\n " , publishErr )
704+ }
705+
706+ return result , err
707+ }
708+
709+ func (a * agent ) React (ctx context.Context , stimulus * Stimulus ) (* Action , error ) {
710+ a .mu .Lock ()
711+ defer a .mu .Unlock ()
712+
713+ // Emit reaction event
714+ if err := a .PublishEvent (ctx , EventType ("agent.react.start" ), EventData (
715+ "stimulus" , stimulus ,
716+ "agent_name" , a .name ,
717+ )); err != nil {
718+ fmt .Printf ("Failed to publish react start event: %v\n " , err )
719+ }
720+
721+ // Quick reactive response based on stimulus urgency
722+ var action * Action
723+
724+ if stimulus .Urgency > 0.8 {
725+ // High urgency - immediate reflex response
726+ action = & Action {
727+ Type : "immediate_response" ,
728+ Layer : ReflexLayer ,
729+ Parameters : stimulus .Data ,
730+ Priority : int (stimulus .Urgency * 100 ),
731+ Timestamp : time .Now (),
732+ }
733+ } else {
734+ // Lower urgency - deliberate response
735+ action = & Action {
736+ Type : "deliberate_response" ,
737+ Layer : CortexLayer ,
738+ Parameters : stimulus .Data ,
739+ Priority : int (stimulus .Urgency * 100 ),
740+ Timestamp : time .Now (),
741+ }
742+ }
743+
744+ // Update cognitive state
745+ a .cognitiveState .CurrentLayer = action .Layer
746+ a .cognitiveState .LastUpdate = time .Now ()
747+
748+ // Emit reaction completion event
749+ if err := a .PublishEvent (ctx , EventType ("agent.react.complete" ), EventData (
750+ "action" , action ,
751+ "agent_name" , a .name ,
752+ )); err != nil {
753+ fmt .Printf ("Failed to publish react complete event: %v\n " , err )
754+ }
755+
756+ return action , nil
757+ }
758+
759+ func (a * agent ) GetSkillLibrary () SkillLibrary {
760+ a .mu .RLock ()
761+ defer a .mu .RUnlock ()
762+ return a .skillLibrary
763+ }
764+
765+ func (a * agent ) WithSkills (skills ... Skill ) Agent {
766+ newAgent := & agent {
767+ name : a .name ,
768+ model : a .model ,
769+ systemPrompt : a .systemPrompt ,
770+ temperature : a .temperature ,
771+ maxTokens : a .maxTokens ,
772+ tools : a .tools ,
773+ memory : a .memory ,
774+ state : a .state ,
775+ provider : a .provider ,
776+ eventBus : a .eventBus ,
777+ skillLibrary : NewSkillLibrary (),
778+ cognitiveState : & CognitiveState {
779+ CurrentLayer : a .cognitiveState .CurrentLayer ,
780+ Mode : a .cognitiveState .Mode ,
781+ ActivePlan : a .cognitiveState .ActivePlan ,
782+ LoadedSkills : make ([]string , 0 ),
783+ RecentDecisions : make ([]* Decision , 0 ),
784+ LastUpdate : time .Now (),
785+ },
786+ cognitiveMode : a .cognitiveMode ,
787+ }
788+
789+ // Copy existing skills
790+ for _ , skill := range a .skillLibrary .ListSkills () {
791+ newAgent .skillLibrary .RegisterSkill (skill )
792+ }
793+
794+ // Add new skills
795+ for _ , skill := range skills {
796+ newAgent .skillLibrary .RegisterSkill (skill )
797+ newAgent .cognitiveState .LoadedSkills = append (newAgent .cognitiveState .LoadedSkills , skill .Name ())
798+ }
799+
800+ return newAgent
801+ }
802+
803+ func (a * agent ) GetCognitiveState () * CognitiveState {
804+ a .mu .RLock ()
805+ defer a .mu .RUnlock ()
806+
807+ // Return a copy to prevent external modification
808+ state := * a .cognitiveState
809+ return & state
810+ }
811+
812+ func (a * agent ) SetCognitiveMode (mode CognitiveMode ) Agent {
813+ newAgent := & agent {
814+ name : a .name ,
815+ model : a .model ,
816+ systemPrompt : a .systemPrompt ,
817+ temperature : a .temperature ,
818+ maxTokens : a .maxTokens ,
819+ tools : a .tools ,
820+ memory : a .memory ,
821+ state : a .state ,
822+ provider : a .provider ,
823+ eventBus : a .eventBus ,
824+ skillLibrary : a .skillLibrary ,
825+ cognitiveState : & CognitiveState {
826+ CurrentLayer : a .cognitiveState .CurrentLayer ,
827+ Mode : mode ,
828+ ActivePlan : a .cognitiveState .ActivePlan ,
829+ LoadedSkills : a .cognitiveState .LoadedSkills ,
830+ RecentDecisions : a .cognitiveState .RecentDecisions ,
831+ LastUpdate : time .Now (),
832+ },
833+ cognitiveMode : mode ,
834+ }
835+
836+ return newAgent
837+ }
838+
839+ // Helper functions for cognitive processing
840+
841+ func extractAction (response string ) string {
842+ // Simple extraction logic - in production you might use more sophisticated parsing
843+ lines := strings .Split (response , "\n " )
844+ for _ , line := range lines {
845+ if strings .Contains (strings .ToLower (line ), "action" ) || strings .Contains (strings .ToLower (line ), "recommend" ) {
846+ return strings .TrimSpace (line )
847+ }
848+ }
849+ return "continue"
850+ }
851+
852+ func extractConfidence (response string ) float64 {
853+ // Simple confidence extraction - in production you might use regex or LLM structured output
854+ if strings .Contains (strings .ToLower (response ), "high confidence" ) || strings .Contains (strings .ToLower (response ), "very confident" ) {
855+ return 0.9
856+ } else if strings .Contains (strings .ToLower (response ), "medium confidence" ) || strings .Contains (strings .ToLower (response ), "somewhat confident" ) {
857+ return 0.7
858+ } else if strings .Contains (strings .ToLower (response ), "low confidence" ) || strings .Contains (strings .ToLower (response ), "uncertain" ) {
859+ return 0.4
860+ }
861+ return 0.6 // default
862+ }
0 commit comments