WIP: Save agent roles integration work before CHORUS rebrand

- Agent roles and coordination features
- Chat API integration testing
- New configuration and workspace management

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-08-01 02:21:11 +10:00
parent 81b473d48f
commit 5978a0b8f5
3713 changed files with 1103925 additions and 59 deletions

View File

@@ -23,10 +23,12 @@ type PubSub struct {
// Topic subscriptions
bzzzTopic *pubsub.Topic
antennaeTopic *pubsub.Topic
contextTopic *pubsub.Topic
// Message subscriptions
bzzzSub *pubsub.Subscription
antennaeSub *pubsub.Subscription
contextSub *pubsub.Subscription
// Dynamic topic management
dynamicTopics map[string]*pubsub.Topic
@@ -37,9 +39,22 @@ type PubSub struct {
// Configuration
bzzzTopicName string
antennaeTopicName string
contextTopicName string
// External message handler for Antennae messages
AntennaeMessageHandler func(msg Message, from peer.ID)
// External message handler for Context Feedback messages
ContextFeedbackHandler func(msg Message, from peer.ID)
// Hypercore-style logging
hypercoreLog HypercoreLogger
}
// HypercoreLogger interface for dependency injection
type HypercoreLogger interface {
AppendString(logType string, data map[string]interface{}) error
GetStats() map[string]interface{}
}
// MessageType represents different types of messages
@@ -74,6 +89,13 @@ const (
MentorshipResponse MessageType = "mentorship_response" // Senior role providing mentorship
ProjectUpdate MessageType = "project_update" // Project-level status updates
DeliverableReady MessageType = "deliverable_ready" // Notification that deliverable is complete
// RL Context Curator feedback messages
FeedbackEvent MessageType = "feedback_event" // Context feedback for RL learning
ContextRequest MessageType = "context_request" // Request context from HCFS
ContextResponse MessageType = "context_response" // Response with context data
ContextUsage MessageType = "context_usage" // Report context usage patterns
ContextRelevance MessageType = "context_relevance" // Report context relevance scoring
)
// Message represents a Bzzz/Antennae message
@@ -95,12 +117,18 @@ type Message struct {
// NewPubSub creates a new PubSub instance for Bzzz coordination and Antennae meta-discussion
func NewPubSub(ctx context.Context, h host.Host, bzzzTopic, antennaeTopic string) (*PubSub, error) {
return NewPubSubWithLogger(ctx, h, bzzzTopic, antennaeTopic, nil)
}
// NewPubSubWithLogger creates a new PubSub instance with hypercore logging
func NewPubSubWithLogger(ctx context.Context, h host.Host, bzzzTopic, antennaeTopic string, logger HypercoreLogger) (*PubSub, error) {
if bzzzTopic == "" {
bzzzTopic = "bzzz/coordination/v1"
}
if antennaeTopic == "" {
antennaeTopic = "antennae/meta-discussion/v1"
}
contextTopic := "bzzz/context-feedback/v1"
pubsubCtx, cancel := context.WithCancel(ctx)
@@ -123,8 +151,10 @@ func NewPubSub(ctx context.Context, h host.Host, bzzzTopic, antennaeTopic string
cancel: cancel,
bzzzTopicName: bzzzTopic,
antennaeTopicName: antennaeTopic,
contextTopicName: contextTopic,
dynamicTopics: make(map[string]*pubsub.Topic),
dynamicSubs: make(map[string]*pubsub.Subscription),
hypercoreLog: logger,
}
// Join static topics
@@ -136,8 +166,9 @@ func NewPubSub(ctx context.Context, h host.Host, bzzzTopic, antennaeTopic string
// Start message handlers
go p.handleBzzzMessages()
go p.handleAntennaeMessages()
go p.handleContextFeedbackMessages()
fmt.Printf("📡 PubSub initialized - Bzzz: %s, Antennae: %s\n", bzzzTopic, antennaeTopic)
fmt.Printf("📡 PubSub initialized - Bzzz: %s, Antennae: %s, Context: %s\n", bzzzTopic, antennaeTopic, contextTopic)
return p, nil
}
@@ -146,7 +177,12 @@ func (p *PubSub) SetAntennaeMessageHandler(handler func(msg Message, from peer.I
p.AntennaeMessageHandler = handler
}
// joinStaticTopics joins the main Bzzz and Antennae topics
// SetContextFeedbackHandler sets the handler for incoming context feedback messages.
func (p *PubSub) SetContextFeedbackHandler(handler func(msg Message, from peer.ID)) {
p.ContextFeedbackHandler = handler
}
// joinStaticTopics joins the main Bzzz, Antennae, and Context Feedback topics
func (p *PubSub) joinStaticTopics() error {
// Join Bzzz coordination topic
bzzzTopic, err := p.ps.Join(p.bzzzTopicName)
@@ -174,6 +210,19 @@ func (p *PubSub) joinStaticTopics() error {
}
p.antennaeSub = antennaeSub
// Join Context Feedback topic
contextTopic, err := p.ps.Join(p.contextTopicName)
if err != nil {
return fmt.Errorf("failed to join Context Feedback topic: %w", err)
}
p.contextTopic = contextTopic
contextSub, err := contextTopic.Subscribe()
if err != nil {
return fmt.Errorf("failed to subscribe to Context Feedback topic: %w", err)
}
p.contextSub = contextSub
return nil
}
@@ -332,6 +381,23 @@ func (p *PubSub) PublishAntennaeMessage(msgType MessageType, data map[string]int
return p.antennaeTopic.Publish(p.ctx, msgBytes)
}
// PublishContextFeedbackMessage publishes a message to the Context Feedback topic
func (p *PubSub) PublishContextFeedbackMessage(msgType MessageType, data map[string]interface{}) error {
msg := Message{
Type: msgType,
From: p.host.ID().String(),
Timestamp: time.Now(),
Data: data,
}
msgBytes, err := json.Marshal(msg)
if err != nil {
return fmt.Errorf("failed to marshal context feedback message: %w", err)
}
return p.contextTopic.Publish(p.ctx, msgBytes)
}
// PublishRoleBasedMessage publishes a role-based collaboration message
func (p *PubSub) PublishRoleBasedMessage(msgType MessageType, data map[string]interface{}, opts MessageOptions) error {
msg := Message{
@@ -366,6 +432,11 @@ func (p *PubSub) PublishRoleBasedMessage(msgType MessageType, data map[string]in
return topic.Publish(p.ctx, msgBytes)
}
// GetHypercoreLog returns the hypercore logger for external access
func (p *PubSub) GetHypercoreLog() HypercoreLogger {
return p.hypercoreLog
}
// MessageOptions holds options for role-based messages
type MessageOptions struct {
FromRole string
@@ -432,6 +503,36 @@ func (p *PubSub) handleAntennaeMessages() {
}
}
// handleContextFeedbackMessages processes incoming context feedback messages
func (p *PubSub) handleContextFeedbackMessages() {
for {
msg, err := p.contextSub.Next(p.ctx)
if err != nil {
if p.ctx.Err() != nil {
return // Context cancelled
}
fmt.Printf("❌ Error receiving Context Feedback message: %v\n", err)
continue
}
if msg.ReceivedFrom == p.host.ID() {
continue
}
var contextMsg Message
if err := json.Unmarshal(msg.Data, &contextMsg); err != nil {
fmt.Printf("❌ Failed to unmarshal Context Feedback message: %v\n", err)
continue
}
if p.ContextFeedbackHandler != nil {
p.ContextFeedbackHandler(contextMsg, msg.ReceivedFrom)
} else {
p.processContextFeedbackMessage(contextMsg, msg.ReceivedFrom)
}
}
}
// handleDynamicMessages processes messages from a dynamic topic subscription
func (p *PubSub) handleDynamicMessages(sub *pubsub.Subscription) {
for {
@@ -464,12 +565,132 @@ func (p *PubSub) handleDynamicMessages(sub *pubsub.Subscription) {
// processBzzzMessage handles different types of Bzzz coordination messages
func (p *PubSub) processBzzzMessage(msg Message, from peer.ID) {
fmt.Printf("🐝 Bzzz [%s] from %s: %v\n", msg.Type, from.ShortString(), msg.Data)
// Log to hypercore if logger is available
if p.hypercoreLog != nil {
logData := map[string]interface{}{
"message_type": string(msg.Type),
"from_peer": from.String(),
"from_short": from.ShortString(),
"timestamp": msg.Timestamp,
"data": msg.Data,
"topic": "bzzz",
}
// Map pubsub message types to hypercore log types
var logType string
switch msg.Type {
case TaskAnnouncement:
logType = "task_announced"
case TaskClaim:
logType = "task_claimed"
case TaskProgress:
logType = "task_progress"
case TaskComplete:
logType = "task_completed"
case CapabilityBcast:
logType = "capability_broadcast"
case AvailabilityBcast:
logType = "network_event"
default:
logType = "network_event"
}
if err := p.hypercoreLog.AppendString(logType, logData); err != nil {
fmt.Printf("❌ Failed to log Bzzz message to hypercore: %v\n", err)
}
}
}
// processAntennaeMessage provides default handling for Antennae messages if no external handler is set
func (p *PubSub) processAntennaeMessage(msg Message, from peer.ID) {
fmt.Printf("🎯 Default Antennae Handler [%s] from %s: %v\n",
msg.Type, from.ShortString(), msg.Data)
// Log to hypercore if logger is available
if p.hypercoreLog != nil {
logData := map[string]interface{}{
"message_type": string(msg.Type),
"from_peer": from.String(),
"from_short": from.ShortString(),
"timestamp": msg.Timestamp,
"data": msg.Data,
"topic": "antennae",
"from_role": msg.FromRole,
"to_roles": msg.ToRoles,
"required_expertise": msg.RequiredExpertise,
"project_id": msg.ProjectID,
"priority": msg.Priority,
"thread_id": msg.ThreadID,
}
// Map pubsub message types to hypercore log types
var logType string
switch msg.Type {
case MetaDiscussion, TaskHelpRequest, TaskHelpResponse:
logType = "collaboration"
case CoordinationRequest, CoordinationComplete:
logType = "collaboration"
case DependencyAlert:
logType = "collaboration"
case EscalationTrigger:
logType = "escalation"
case RoleAnnouncement, ExpertiseRequest, ExpertiseResponse:
logType = "collaboration"
case StatusUpdate, WorkAllocation, RoleCollaboration:
logType = "collaboration"
case MentorshipRequest, MentorshipResponse:
logType = "collaboration"
case ProjectUpdate, DeliverableReady:
logType = "collaboration"
default:
logType = "collaboration"
}
if err := p.hypercoreLog.AppendString(logType, logData); err != nil {
fmt.Printf("❌ Failed to log Antennae message to hypercore: %v\n", err)
}
}
}
// processContextFeedbackMessage provides default handling for context feedback messages if no external handler is set
func (p *PubSub) processContextFeedbackMessage(msg Message, from peer.ID) {
fmt.Printf("🧠 Context Feedback [%s] from %s: %v\n",
msg.Type, from.ShortString(), msg.Data)
// Log to hypercore if logger is available
if p.hypercoreLog != nil {
logData := map[string]interface{}{
"message_type": string(msg.Type),
"from_peer": from.String(),
"from_short": from.ShortString(),
"timestamp": msg.Timestamp,
"data": msg.Data,
"topic": "context_feedback",
"from_role": msg.FromRole,
"to_roles": msg.ToRoles,
"project_id": msg.ProjectID,
"priority": msg.Priority,
"thread_id": msg.ThreadID,
}
// Map context feedback message types to hypercore log types
var logType string
switch msg.Type {
case FeedbackEvent:
logType = "context_feedback"
case ContextRequest, ContextResponse:
logType = "context_request"
case ContextUsage, ContextRelevance:
logType = "context_usage"
default:
logType = "context_feedback"
}
if err := p.hypercoreLog.AppendString(logType, logData); err != nil {
fmt.Printf("❌ Failed to log Context Feedback message to hypercore: %v\n", err)
}
}
}
// Close shuts down the PubSub instance
@@ -482,6 +703,9 @@ func (p *PubSub) Close() error {
if p.antennaeSub != nil {
p.antennaeSub.Cancel()
}
if p.contextSub != nil {
p.contextSub.Cancel()
}
if p.bzzzTopic != nil {
p.bzzzTopic.Close()
@@ -489,6 +713,9 @@ func (p *PubSub) Close() error {
if p.antennaeTopic != nil {
p.antennaeTopic.Close()
}
if p.contextTopic != nil {
p.contextTopic.Close()
}
p.dynamicTopicsMux.Lock()
for _, topic := range p.dynamicTopics {