Skip to content

Commit f7981e3

Browse files
committed
refactor(events): update event store implementations and health config
- Update Postgres and MongoDB event stores to support array filters for aggregate IDs and event types - Rename time-related fields in event criteria (FromTime/ToTime -> StartTime/EndTime) - Simplify AI service wrapper by removing direct AI manager start - Enhance health config with additional options and intervals - Add delete operations to MemoryEventStore - Update Redis broker to handle connection stats type conversions - Remove unused binary file and update go.mod dependencies
1 parent 2e87a10 commit f7981e3

17 files changed

Lines changed: 275 additions & 178 deletions

File tree

examples/ai-agents-demo/main.go

Lines changed: 63 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/xraph/forge"
1010
"github.com/xraph/forge/extensions/ai"
11+
"github.com/xraph/forge/extensions/ai/agents"
1112
"github.com/xraph/forge/extensions/ai/stores"
1213

1314
_ "github.com/mattn/go-sqlite3"
@@ -16,15 +17,6 @@ import (
1617
func main() {
1718
fmt.Println("=== Forge v2: AI Agent Storage & API Demo ===\n")
1819

19-
// Create app
20-
app, err := forge.NewApp(forge.AppConfig{
21-
Name: "ai-agents-demo",
22-
Version: "1.0.0",
23-
})
24-
if err != nil {
25-
log.Fatal(err)
26-
}
27-
2820
// Option 1: Use in-memory store (default, no database)
2921
memoryStore := stores.NewMemoryAgentStore()
3022

@@ -35,50 +27,58 @@ func main() {
3527
}
3628
defer db.Close()
3729

38-
// Get logger from app
39-
var logger forge.Logger
40-
if l, err := app.Container().Resolve("logger"); err == nil {
41-
if loggerImpl, ok := l.(forge.Logger); ok {
42-
logger = loggerImpl
43-
}
44-
}
45-
46-
sqlStore := stores.NewSQLAgentStore(db, "agents", logger)
47-
48-
// Create table
49-
if err := sqlStore.CreateTable(context.Background()); err != nil {
50-
log.Printf("Warning: failed to create agents table: %v", err)
51-
}
52-
5330
// Choose which store to use
5431
var agentStore ai.AgentStore
5532
useSQL := true // Set to true to use SQL store, false for memory store
5633

5734
if useSQL {
35+
// Get logger from temporary app to create SQL store
36+
tempApp := forge.NewApp(forge.AppConfig{
37+
Name: "temp",
38+
Version: "1.0.0",
39+
})
40+
var logger forge.Logger
41+
if l, err := tempApp.Container().Resolve("logger"); err == nil {
42+
if loggerImpl, ok := l.(forge.Logger); ok {
43+
logger = loggerImpl
44+
}
45+
}
46+
47+
sqlStore := stores.NewSQLAgentStore(db, "agents", logger)
48+
49+
// Create table
50+
if err := sqlStore.CreateTable(context.Background()); err != nil {
51+
log.Printf("Warning: failed to create agents table: %v", err)
52+
}
53+
5854
agentStore = sqlStore
5955
fmt.Println("✓ Using SQL store (persistent)")
6056
} else {
6157
agentStore = memoryStore
6258
fmt.Println("✓ Using memory store (ephemeral)")
6359
}
6460

65-
// Register agent store in DI
66-
if err := app.Container().Register("agentStore", func(c forge.Container) (any, error) {
67-
return agentStore, nil
68-
}); err != nil {
69-
log.Fatal(err)
70-
}
71-
7261
// Configure AI extension
7362
config := ai.DefaultConfig()
7463
config.EnableLLM = true
7564
config.EnableAgents = true
7665
config.EnableInference = false
7766
config.EnableCoordination = true
7867

79-
// Register AI extension
68+
// Create AI extension
8069
ext := ai.NewExtensionWithConfig(config)
81-
if err := app.RegisterExtension(ext); err != nil {
70+
71+
// Create app with AI extension
72+
app := forge.NewApp(forge.AppConfig{
73+
Name: "ai-agents-demo",
74+
Version: "1.0.0",
75+
Extensions: []forge.Extension{ext},
76+
})
77+
78+
// Register agent store in DI
79+
if err := app.Container().Register("agentStore", func(c forge.Container) (any, error) {
80+
return agentStore, nil
81+
}); err != nil {
8282
log.Fatal(err)
8383
}
8484

@@ -92,7 +92,7 @@ func main() {
9292
}
9393
}()
9494

95-
ctx := context.Background()
95+
9696

9797
// Get AI manager
9898
var aiManager ai.AI
@@ -105,77 +105,47 @@ func main() {
105105
// Demo: Create agents dynamically
106106
fmt.Println("\n→ Creating Agents:")
107107

108-
agent1Def := &ai.AgentDefinition{
109-
ID: "code-reviewer-001",
110-
Name: "Go Code Reviewer",
111-
Type: "code_reviewer",
112-
SystemPrompt: "You are an expert Go developer. Review code for best practices, security, and performance.",
113-
Model: "gpt-4",
114-
Provider: "openai",
115-
}
116-
117-
fmt.Printf(" Creating agent: %s\n", agent1Def.Name)
118-
if manager, ok := aiManager.(*ai.managerImpl); ok {
119-
if _, err := manager.CreateAgent(ctx, agent1Def); err != nil {
120-
log.Printf(" Error creating agent: %v", err)
121-
} else {
122-
fmt.Printf(" ✓ Agent created: %s\n", agent1Def.ID)
123-
}
124-
}
125-
126-
agent2Def := &ai.AgentDefinition{
127-
ID: "code-generator-001",
128-
Name: "Code Generator",
129-
Type: "code_generator",
130-
SystemPrompt: "You are a helpful code generation assistant. Write clean, well-documented code.",
131-
Model: "gpt-3.5-turbo",
132-
Provider: "openai",
108+
// Create optimization agent
109+
optimizationAgent := agents.NewOptimizationAgent("optimization-001", "Performance Optimizer")
110+
fmt.Printf(" Creating agent: %s\n", optimizationAgent.Name())
111+
if err := aiManager.RegisterAgent(optimizationAgent); err != nil {
112+
log.Printf(" Error registering agent: %v", err)
113+
} else {
114+
fmt.Printf(" ✓ Agent registered: %s\n", optimizationAgent.ID())
133115
}
134116

135-
fmt.Printf(" Creating agent: %s\n", agent2Def.Name)
136-
if manager, ok := aiManager.(*ai.managerImpl); ok {
137-
if _, err := manager.CreateAgent(ctx, agent2Def); err != nil {
138-
log.Printf(" Error creating agent: %v", err)
139-
} else {
140-
fmt.Printf(" ✓ Agent created: %s\n", agent2Def.ID)
141-
}
117+
// Create anomaly detection agent
118+
anomalyAgent := agents.NewAnomalyDetectionAgent("anomaly-001", "Anomaly Detector")
119+
fmt.Printf(" Creating agent: %s\n", anomalyAgent.Name())
120+
if err := aiManager.RegisterAgent(anomalyAgent); err != nil {
121+
log.Printf(" Error registering agent: %v", err)
122+
} else {
123+
fmt.Printf(" ✓ Agent registered: %s\n", anomalyAgent.ID())
142124
}
143125

144126
// Demo: List agents
145127
fmt.Println("\n→ Listing Agents:")
146-
if manager, ok := aiManager.(*ai.managerImpl); ok {
147-
agents, err := manager.ListAgentsWithFilter(ctx, ai.AgentFilter{})
148-
if err != nil {
149-
log.Printf(" Error listing agents: %v", err)
150-
} else {
151-
fmt.Printf(" Found %d agents:\n", len(agents))
152-
for _, agent := range agents {
153-
fmt.Printf(" - %s (%s): %s\n", agent.ID, agent.Type, agent.Name)
154-
}
155-
}
128+
agents := aiManager.ListAgents()
129+
fmt.Printf(" Found %d agents:\n", len(agents))
130+
for _, agent := range agents {
131+
fmt.Printf(" - %s (%s): %s\n", agent.ID(), agent.Type(), agent.Name())
156132
}
157133

158134
// Demo: Create a team
159135
fmt.Println("\n→ Creating Agent Team:")
160-
team := ai.NewAgentTeam("dev-team-001", "Development Team", logger)
136+
team := ai.NewAgentTeam("dev-team-001", "Development Team", app.Logger())
161137

162138
// Add agents to team
163-
if manager, ok := aiManager.(*ai.managerImpl); ok {
164-
agent1, err1 := manager.GetAgent("code-reviewer-001")
165-
agent2, err2 := manager.GetAgent("code-generator-001")
166-
167-
if err1 == nil && err2 == nil {
168-
team.AddAgent(agent1)
169-
team.AddAgent(agent2)
170-
fmt.Printf(" ✓ Team created with %d agents\n", len(team.Agents()))
171-
172-
// Register team
173-
if err := manager.RegisterTeam(team); err != nil {
174-
log.Printf(" Error registering team: %v", err)
175-
} else {
176-
fmt.Println(" ✓ Team registered")
177-
}
178-
}
139+
agent1, err1 := aiManager.GetAgent("optimization-001")
140+
agent2, err2 := aiManager.GetAgent("anomaly-001")
141+
142+
if err1 == nil && err2 == nil {
143+
team.AddAgent(agent1)
144+
team.AddAgent(agent2)
145+
fmt.Printf(" ✓ Team created with %d agents\n", len(team.Agents()))
146+
fmt.Println(" ✓ Team configured (teams are managed separately from individual agents)")
147+
} else {
148+
log.Printf(" Error getting agents for team: %v, %v", err1, err2)
179149
}
180150

181151
// Demo: Persistence test (restart simulation)

examples/cache-demo/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ func main() {
150150
Namespace: "cache_demo",
151151
},
152152
HealthConfig: forge.HealthConfig{
153-
Enabled: true,
154-
HealthPath: "/_/health",
153+
Enabled: true,
155154
},
156155
})
157156

examples/config-example/main.go

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"context"
54
"fmt"
65
"log"
76
"net/http"
@@ -36,7 +35,7 @@ func example1() {
3635
configManager := forge.NewManager(forge.ManagerConfig{})
3736

3837
source, err := sources.NewFileSource("./config.yaml", sources.FileSourceOptions{
39-
Logger: forge.NewLogger(logger.LoggerConfig{
38+
Logger: forge.NewLogger(forge.LoggingConfig{
4039
Level: "info",
4140
}),
4241
})
@@ -45,18 +44,15 @@ func example1() {
4544
}
4645

4746
if err := configManager.LoadFrom(source); err != nil {
48-
log.Fatalf("Failed to add config source: %v", err)
47+
log.Fatalf("Failed to load config from source: %v", err)
4948
}
5049

51-
if err := configManager.Load(context.Background()); err != nil {
52-
log.Fatalf("Failed to load config: %v", err)
53-
}
54-
55-
// Create app with extensions
56-
// Extensions will automatically load their config from ConfigManager
50+
// Create app with extensions and provide the ConfigManager
51+
// Extensions will automatically load their config from the provided ConfigManager
5752
app := forge.NewApp(forge.AppConfig{
58-
Name: "config-example",
59-
Version: "1.0.0",
53+
Name: "config-example",
54+
Version: "1.0.0",
55+
ConfigManager: configManager, // Provide the pre-loaded ConfigManager
6056
Extensions: []forge.Extension{
6157
// Load config from "extensions.cache" or "cache" key
6258
cache.NewExtension(),
@@ -66,13 +62,6 @@ func example1() {
6662
},
6763
})
6864

69-
// Register ConfigManager with DI so extensions can use it
70-
if err := forge.RegisterSingleton(app.Container(), forge.ConfigKey, func(c forge.Container) (forge.ConfigManager, error) {
71-
return configManager, nil
72-
}); err != nil {
73-
log.Fatalf("Failed to register ConfigManager: %v", err)
74-
}
75-
7665
// Register a simple test route
7766
app.Router().GET("/test", func(ctx forge.Context) error {
7867
return ctx.JSON(http.StatusOK, map[string]string{
@@ -88,7 +77,7 @@ func example1() {
8877
fmt.Println("Visit: http://localhost:8080/_/mcp/info")
8978
fmt.Println()
9079

91-
if err := app.Run(context.Background()); err != nil {
80+
if err := app.Run(); err != nil {
9281
log.Fatalf("App failed: %v", err)
9382
}
9483
}
@@ -98,20 +87,20 @@ func example2() {
9887
fmt.Println("Example 2: Programmatic config overrides")
9988
fmt.Println("----------------------------------------")
10089

101-
// Create config manager
90+
// Create config manager and load config file
10291
configManager := forge.NewManager(forge.ManagerConfig{})
103-
if err := configManager.AddSource("file", forge.SourceConfig{
104-
Type: "file",
105-
Config: map[string]interface{}{
106-
"path": "./config.yaml",
107-
"format": "yaml",
108-
},
109-
}); err != nil {
110-
log.Fatalf("Failed to add config source: %v", err)
92+
93+
source, err := sources.NewFileSource("./config.yaml", sources.FileSourceOptions{
94+
Logger: forge.NewLogger(forge.LoggingConfig{
95+
Level: "info",
96+
}),
97+
})
98+
if err != nil {
99+
log.Fatalf("Failed to create file source: %v", err)
111100
}
112101

113-
if err := configManager.Load(context.Background()); err != nil {
114-
log.Fatalf("Failed to load config: %v", err)
102+
if err := configManager.LoadFrom(source); err != nil {
103+
log.Fatalf("Failed to load config from source: %v", err)
115104
}
116105

117106
// Create app with programmatic overrides
@@ -144,7 +133,7 @@ func example2() {
144133
fmt.Println("MCP base path: /api/mcp (overrides /_/mcp from config)")
145134
fmt.Println()
146135

147-
if err := app.Run(context.Background()); err != nil {
136+
if err := app.Run(); err != nil {
148137
log.Fatalf("App failed: %v", err)
149138
}
150139
}
@@ -171,7 +160,7 @@ func example3() {
171160
fmt.Println("This will fail because cache requires config")
172161
fmt.Println()
173162

174-
if err := app.Run(context.Background()); err != nil {
163+
if err := app.Run(); err != nil {
175164
fmt.Printf("Expected error: %v\n", err)
176165
fmt.Println("\nThis demonstrates the RequireConfig flag working correctly.")
177166
}

examples/mcp-basic/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func main() {
8181
fmt.Println("\n")
8282

8383
// Run HTTP server
84-
if err := app.Run(ctx, ":8080"); err != nil {
84+
if err := app.Run(); err != nil {
8585
fmt.Printf("Server error: %v\n", err)
8686
os.Exit(1)
8787
}

0 commit comments

Comments
 (0)