mirror of
https://github.com/mudler/LocalAGI.git
synced 2026-08-04 16:06:08 -04:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 419a4363c3 | |||
| 292d0c9c19 | |||
| 1147e02844 | |||
| c8e83dc4b9 | |||
| 8b5188c35b | |||
| 55b631bc51 | |||
| c1e2eeb8af | |||
| 50f168f322 | |||
| b5dacb0e4f |
@@ -148,10 +148,34 @@ func (a *Agent) saveCurrentConversation(conv Messages) {
|
||||
xlog.Error("Error storing into memory", "error", err)
|
||||
}
|
||||
} else {
|
||||
for _, message := range conv {
|
||||
if message.Role == "user" {
|
||||
if err := a.options.ragdb.Store(message.Content); err != nil {
|
||||
xlog.Error("Error storing into memory", "error", err)
|
||||
// Use the conversation storage mode to determine what to store
|
||||
switch a.options.conversationStorageMode {
|
||||
case StoreWholeConversation:
|
||||
// Store the entire conversation as a single block
|
||||
if len(conv) > 0 {
|
||||
convStr := Messages(conv).String()
|
||||
if err := a.options.ragdb.Store(convStr); err != nil {
|
||||
xlog.Error("Error storing whole conversation into memory", "error", err)
|
||||
}
|
||||
}
|
||||
case StoreUserAndAssistant:
|
||||
// Store user and assistant messages separately
|
||||
for _, message := range conv {
|
||||
if message.Role == "user" || message.Role == "assistant" {
|
||||
if err := a.options.ragdb.Store(message.Content); err != nil {
|
||||
xlog.Error("Error storing message into memory", "error", err, "role", message.Role)
|
||||
}
|
||||
}
|
||||
}
|
||||
case StoreUserOnly:
|
||||
fallthrough
|
||||
default:
|
||||
// Store only user messages (default behavior)
|
||||
for _, message := range conv {
|
||||
if message.Role == "user" {
|
||||
if err := a.options.ragdb.Store(message.Content); err != nil {
|
||||
xlog.Error("Error storing into memory", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-39
@@ -10,6 +10,18 @@ import (
|
||||
|
||||
type Option func(*options) error
|
||||
|
||||
// ConversationStorageMode defines how conversations are stored in the knowledge base
|
||||
type ConversationStorageMode string
|
||||
|
||||
const (
|
||||
// StoreUserOnly stores only user messages (default)
|
||||
StoreUserOnly ConversationStorageMode = "user_only"
|
||||
// StoreUserAndAssistant stores both user and assistant messages separately
|
||||
StoreUserAndAssistant ConversationStorageMode = "user_and_assistant"
|
||||
// StoreWholeConversation stores the entire conversation as a single block
|
||||
StoreWholeConversation ConversationStorageMode = "whole_conversation"
|
||||
)
|
||||
|
||||
type llmOptions struct {
|
||||
APIURL string
|
||||
APIKey string
|
||||
@@ -31,6 +43,7 @@ type options struct {
|
||||
enableHUD, standaloneJob, showCharacter, enableKB, enableSummaryMemory, enableLongTermMemory bool
|
||||
stripThinkingTags bool
|
||||
kbAutoSearch bool
|
||||
conversationStorageMode ConversationStorageMode
|
||||
|
||||
canStopItself bool
|
||||
initiateConversations bool
|
||||
@@ -49,11 +62,6 @@ type options struct {
|
||||
kbResults int
|
||||
ragdb RAGDB
|
||||
|
||||
// KB compaction (when enableKB is true)
|
||||
enableKBCompaction bool
|
||||
kbCompactionInterval string // "daily", "weekly", "monthly"
|
||||
kbCompactionSummarize bool
|
||||
|
||||
// Evaluation settings
|
||||
maxEvaluationLoops int
|
||||
enableEvaluation bool
|
||||
@@ -85,12 +93,13 @@ func (o *options) SeparatedMultimodalModel() bool {
|
||||
|
||||
func defaultOptions() *options {
|
||||
return &options{
|
||||
parallelJobs: 1,
|
||||
periodicRuns: 15 * time.Minute,
|
||||
schedulerPollInterval: 30 * time.Second,
|
||||
maxEvaluationLoops: 2,
|
||||
enableEvaluation: false,
|
||||
kbAutoSearch: true, // Default to true to maintain backward compatibility
|
||||
parallelJobs: 1,
|
||||
periodicRuns: 15 * time.Minute,
|
||||
schedulerPollInterval: 30 * time.Second,
|
||||
maxEvaluationLoops: 2,
|
||||
enableEvaluation: false,
|
||||
kbAutoSearch: true, // Default to true to maintain backward compatibility
|
||||
conversationStorageMode: StoreUserOnly, // Default to user-only for backward compatibility
|
||||
LLMAPI: llmOptions{
|
||||
APIURL: "http://localhost:8080",
|
||||
Model: "gpt-4",
|
||||
@@ -166,33 +175,6 @@ func EnableKnowledgeBaseWithResults(results int) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// EnableKBCompaction enables periodic KB compaction (group by date, optionally summarize, store, delete originals).
|
||||
var EnableKBCompaction = func(o *options) error {
|
||||
o.enableKBCompaction = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithKBCompactionInterval sets the compaction window: "daily", "weekly", or "monthly".
|
||||
func WithKBCompactionInterval(interval string) Option {
|
||||
return func(o *options) error {
|
||||
switch interval {
|
||||
case "daily", "weekly", "monthly":
|
||||
o.kbCompactionInterval = interval
|
||||
default:
|
||||
o.kbCompactionInterval = "daily"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithKBCompactionSummarize sets whether compaction uses LLM to summarize (true) or just concatenates (false).
|
||||
func WithKBCompactionSummarize(summarize bool) Option {
|
||||
return func(o *options) error {
|
||||
o.kbCompactionSummarize = summarize
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithLastMessageDuration(duration string) Option {
|
||||
return func(o *options) error {
|
||||
d, err := time.ParseDuration(duration)
|
||||
@@ -269,6 +251,19 @@ func WithRAGDB(db RAGDB) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithConversationStorageMode sets how conversations are stored in the knowledge base
|
||||
func WithConversationStorageMode(mode ConversationStorageMode) Option {
|
||||
return func(o *options) error {
|
||||
switch mode {
|
||||
case StoreUserOnly, StoreUserAndAssistant, StoreWholeConversation:
|
||||
o.conversationStorageMode = mode
|
||||
default:
|
||||
o.conversationStorageMode = StoreUserOnly
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithSystemPrompt(prompt string) Option {
|
||||
return func(o *options) error {
|
||||
o.systemPrompt = prompt
|
||||
@@ -445,7 +440,7 @@ func WithRandomIdentity(guidance ...string) Option {
|
||||
|
||||
func WithActions(actions ...types.Action) Option {
|
||||
return func(o *options) error {
|
||||
o.userActions = actions
|
||||
o.userActions = append(o.userActions, actions...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +183,11 @@ func RunCompaction(ctx context.Context, client *localrag.WrappedClient, period s
|
||||
|
||||
// runCompactionTicker runs compaction on a schedule (daily/weekly/monthly). It stops when ctx is done.
|
||||
func runCompactionTicker(ctx context.Context, client *localrag.WrappedClient, config *AgentConfig, apiURL, apiKey, model string) {
|
||||
// Run first compaction immediately on startup
|
||||
if err := RunCompaction(ctx, client, config.KBCompactionInterval, config.KBCompactionSummarize, apiURL, apiKey, model); err != nil {
|
||||
xlog.Warn("compaction ticker initial run failed", "collection", client.Collection(), "error", err)
|
||||
}
|
||||
|
||||
interval := 24 * time.Hour
|
||||
switch config.KBCompactionInterval {
|
||||
case "weekly":
|
||||
|
||||
+17
-3
@@ -97,9 +97,10 @@ type AgentConfig struct {
|
||||
KnowledgeBaseResults int `json:"kb_results" form:"kb_results"`
|
||||
CanStopItself bool `json:"can_stop_itself" form:"can_stop_itself"`
|
||||
SystemPrompt string `json:"system_prompt" form:"system_prompt"`
|
||||
LongTermMemory bool `json:"long_term_memory" form:"long_term_memory"`
|
||||
SummaryLongTermMemory bool `json:"summary_long_term_memory" form:"summary_long_term_memory"`
|
||||
ParallelJobs int `json:"parallel_jobs" form:"parallel_jobs"`
|
||||
LongTermMemory bool `json:"long_term_memory" form:"long_term_memory"`
|
||||
SummaryLongTermMemory bool `json:"summary_long_term_memory" form:"summary_long_term_memory"`
|
||||
ConversationStorageMode string `json:"conversation_storage_mode" form:"conversation_storage_mode"`
|
||||
ParallelJobs int `json:"parallel_jobs" form:"parallel_jobs"`
|
||||
StripThinkingTags bool `json:"strip_thinking_tags" form:"strip_thinking_tags"`
|
||||
EnableEvaluation bool `json:"enable_evaluation" form:"enable_evaluation"`
|
||||
MaxEvaluationLoops int `json:"max_evaluation_loops" form:"max_evaluation_loops"`
|
||||
@@ -299,6 +300,19 @@ func NewAgentConfigMeta(
|
||||
HelpText: "Inject knowledge base search and add actions as tools, allowing the agent to access its memory without manual configuration",
|
||||
Tags: config.Tags{Section: "MemorySettings"},
|
||||
},
|
||||
{
|
||||
Name: "conversation_storage_mode",
|
||||
Label: "Conversation Storage Mode",
|
||||
Type: "select",
|
||||
DefaultValue: "user_only",
|
||||
Options: []config.FieldOption{
|
||||
{Value: "user_only", Label: "User Messages Only"},
|
||||
{Value: "user_and_assistant", Label: "User and Assistant Messages"},
|
||||
{Value: "whole_conversation", Label: "Whole Conversation as Block"},
|
||||
},
|
||||
HelpText: "Controls what gets stored in the knowledge base: only user messages, user and assistant messages separately, or the entire conversation as a single block",
|
||||
Tags: config.Tags{Section: "MemorySettings"},
|
||||
},
|
||||
{
|
||||
Name: "system_prompt",
|
||||
Label: "System Prompt",
|
||||
|
||||
+4
-8
@@ -447,6 +447,10 @@ func (a *AgentPool) startAgentWithConfig(name, pooldir string, config *AgentConf
|
||||
opts = append(opts, EnableSummaryMemory)
|
||||
}
|
||||
|
||||
if config.ConversationStorageMode != "" {
|
||||
opts = append(opts, WithConversationStorageMode(ConversationStorageMode(config.ConversationStorageMode)))
|
||||
}
|
||||
|
||||
if config.CanStopItself {
|
||||
opts = append(opts, CanStopItself)
|
||||
}
|
||||
@@ -479,14 +483,6 @@ func (a *AgentPool) startAgentWithConfig(name, pooldir string, config *AgentConf
|
||||
if config.EnableKnowledgeBase {
|
||||
ragClient = localrag.NewWrappedClient(a.localRAGAPI, a.localRAGKey, name)
|
||||
opts = append(opts, WithRAGDB(ragClient), EnableKnowledgeBase)
|
||||
if config.EnableKBCompaction {
|
||||
interval := config.KBCompactionInterval
|
||||
if interval == "" {
|
||||
interval = "daily"
|
||||
}
|
||||
summarize := config.KBCompactionSummarize
|
||||
opts = append(opts, EnableKBCompaction, WithKBCompactionInterval(interval), WithKBCompactionSummarize(summarize))
|
||||
}
|
||||
// Set KB auto search option (defaults to true for backward compatibility)
|
||||
// For backward compatibility: if both new KB fields are false (zero values),
|
||||
// assume this is an old config and default KBAutoSearch to true
|
||||
|
||||
@@ -16,7 +16,7 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/jung-kurt/gofpdf v1.16.2
|
||||
github.com/modelcontextprotocol/go-sdk v1.1.0
|
||||
github.com/mudler/cogito v0.8.2-0.20260214201734-da0d4ceb2b44
|
||||
github.com/mudler/cogito v0.9.1-0.20260216182842-e9820e6bf7b9
|
||||
github.com/mudler/xlog v0.0.1
|
||||
github.com/onsi/ginkgo/v2 v2.25.3
|
||||
github.com/onsi/gomega v1.38.2
|
||||
|
||||
@@ -234,6 +234,16 @@ github.com/mudler/cogito v0.8.2-0.20260206153401-a5346975d42b h1:LXHovZzNgP0n/oY
|
||||
github.com/mudler/cogito v0.8.2-0.20260206153401-a5346975d42b/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.8.2-0.20260214201734-da0d4ceb2b44 h1:joGszpItINnZdoL/0p2077Wz2xnxMGRSRgYN5mS7I4c=
|
||||
github.com/mudler/cogito v0.8.2-0.20260214201734-da0d4ceb2b44/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.8.2-0.20260215213413-af34921ff561 h1:qA7dGJhF5GjgGKHh0lOITZjl9q2jehjKqxxCnaUR1yg=
|
||||
github.com/mudler/cogito v0.8.2-0.20260215213413-af34921ff561/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.8.2-0.20260215230740-d1c0dc9bd9dc h1:tBAGwQq5kOSIh+vfLffVr5Th2ajFwrTj0usLgyGM2CQ=
|
||||
github.com/mudler/cogito v0.8.2-0.20260215230740-d1c0dc9bd9dc/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216144443-c96e8ddc1157 h1:M2Yx84QtKQrhMWlB+K99RKJ+x5s8HoRumegObaLuQlI=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216144443-c96e8ddc1157/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216163119-07b624cc772f h1:LkCJD11Mlx8ZyHoNRbpxbrw1Znl9GiFKjZbcXYwAKwk=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216163119-07b624cc772f/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216182842-e9820e6bf7b9 h1:Ek+fAIUt9v5tqBgPZ89QTgGXwOSZcCiElD37NkbdmSk=
|
||||
github.com/mudler/cogito v0.9.1-0.20260216182842-e9820e6bf7b9/go.mod h1:6sfja3lcu2nWRzEc0wwqGNu/eCG3EWgij+8s7xyUeQ4=
|
||||
github.com/mudler/xlog v0.0.1 h1:yR3/wszd3ZM6u1n96YITJZ4yUcDgqHSwvQmzUJa+8vg=
|
||||
github.com/mudler/xlog v0.0.1/go.mod h1:39f5vcd05Qd6GWKM8IjyHNQ7AmOx3ZM0YfhfIGhC18U=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@types/react": "^19.2.13",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.4",
|
||||
"eslint": "^10.0.0",
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.13", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ=="],
|
||||
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||
|
||||
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@types/react": "^19.2.13",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.4",
|
||||
"eslint": "^10.0.0",
|
||||
|
||||
Reference in New Issue
Block a user