Skip to content

Commit 0633f9e

Browse files
nunocoracaoclaude
andcommitted
Add search, update, categories, and default path to memory tool
- Add search_memories tool (keyword search with AND logic, optional category filter) - Add update_memory tool (edit existing memories by ID) - Add optional category field to memories for organization - Default memory path to ~/.cagent/memory/<config-name>/memory.db (per-user, per-agent-config) - Make path optional in config validation (was required, now defaults) - Add configName parameter to ToolsetCreator for per-config-file identity - SQLite migration adds category column transparently to existing databases - Expand tool instructions with guidance on search vs get_all, update vs create Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 26f794c commit 0633f9e

File tree

19 files changed

+520
-75
lines changed

19 files changed

+520
-75
lines changed

docs/configuration/tools/index.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,29 @@ toolsets:
101101

102102
### Memory
103103

104-
Persistent key-value storage backed by SQLite. Data survives across sessions, letting agents remember context, user preferences, and past decisions.
104+
Persistent key-value storage backed by SQLite. Data survives across sessions, letting agents remember context, user preferences, and past decisions. Memories can be organized with categories and searched by keyword.
105+
106+
Each agent gets its own database at `~/.cagent/memory/<agent-name>/memory.db` by default.
105107

106108
```yaml
107109
toolsets:
108110
- type: memory
109-
path: ./agent_memory.db # optional: custom database path
111+
path: ./agent_memory.db # optional: override the default location
110112
```
111113

112-
| Property | Type | Default | Description |
113-
| -------- | ------ | --------- | ---------------------------------------------------------------------- |
114-
| `path` | string | automatic | Path to the SQLite database file. If omitted, uses a default location. |
114+
| Property | Type | Default | Description |
115+
| -------- | ------ | -------------------------------------------- | ------------------------------------ |
116+
| `path` | string | `~/.cagent/memory/<agent-name>/memory.db` | Path to the SQLite database file |
117+
118+
| Operation | Description |
119+
| ------------------ | ------------------------------------------------------------------- |
120+
| `add_memory` | Store a new memory with optional category |
121+
| `get_memories` | Retrieve all stored memories |
122+
| `delete_memory` | Delete a specific memory by ID |
123+
| `search_memories` | Search memories by keywords and/or category (more efficient than get_all) |
124+
| `update_memory` | Update an existing memory's content and/or category by ID |
125+
126+
Memories support an optional `category` field (e.g., `preference`, `fact`, `project`, `decision`) for organization and filtering.
115127

116128
### Fetch
117129

pkg/acp/registry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
func createToolsetRegistry(agent *Agent) *teamloader.ToolsetRegistry {
1515
registry := teamloader.NewDefaultToolsetRegistry()
1616

17-
registry.Register("filesystem", func(ctx context.Context, toolset latest.Toolset, parentDir string, runConfig *config.RuntimeConfig) (tools.ToolSet, error) {
17+
registry.Register("filesystem", func(ctx context.Context, toolset latest.Toolset, parentDir string, runConfig *config.RuntimeConfig, _ string) (tools.ToolSet, error) {
1818
wd := runConfig.WorkingDir
1919
if wd == "" {
2020
var err error

pkg/config/latest/validate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,7 @@ func (t *Toolset) validate() error {
116116
case "shell":
117117
// no additional validation needed
118118
case "memory":
119-
if t.Path == "" {
120-
return errors.New("memory toolset requires a path to be set")
121-
}
119+
// path is optional; defaults to ~/.cagent/memory/<agent-name>/memory.db
122120
case "tasks":
123121
// path defaults to ./tasks.json if not set
124122
case "mcp":

pkg/config/v2/validate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ func (t *Toolset) validate() error {
6666

6767
switch t.Type {
6868
case "memory":
69-
if t.Path == "" {
70-
return errors.New("memory toolset requires a path to be set")
71-
}
69+
// path is optional; defaults to ~/.cagent/memory/<agent-name>/memory.db
7270
case "mcp":
7371
count := 0
7472
if t.Command != "" {

pkg/config/v3/validate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ func (t *Toolset) validate() error {
8787
return errors.New("sandbox requires at least one path to be set")
8888
}
8989
case "memory":
90-
if t.Path == "" {
91-
return errors.New("memory toolset requires a path to be set")
92-
}
90+
// path is optional; defaults to ~/.cagent/memory/<agent-name>/memory.db
9391
case "mcp":
9492
count := 0
9593
if t.Command != "" {

pkg/config/v4/validate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,7 @@ func (t *Toolset) validate() error {
110110
return errors.New("sandbox requires at least one path to be set")
111111
}
112112
case "memory":
113-
if t.Path == "" {
114-
return errors.New("memory toolset requires a path to be set")
115-
}
113+
// path is optional; defaults to ~/.cagent/memory/<agent-name>/memory.db
116114
case "mcp":
117115
count := 0
118116
if t.Command != "" {

pkg/config/v5/validate.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ func (t *Toolset) validate() error {
113113
return errors.New("sandbox requires at least one path to be set")
114114
}
115115
case "memory":
116-
if t.Path == "" {
117-
return errors.New("memory toolset requires a path to be set")
118-
}
116+
// path is optional; defaults to ~/.cagent/memory/<agent-name>/memory.db
119117
case "tasks":
120118
// path defaults to ./tasks.json if not set
121119
case "mcp":

pkg/config/validation_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ func TestValidationErrors(t *testing.T) {
3636
name string
3737
path string
3838
}{
39-
{
40-
name: "memory toolset missing path",
41-
path: "missing_memory_path_v2.yaml",
42-
},
4339
{
4440
name: "path in non memory toolset",
4541
path: "invalid_path_v2.yaml",

pkg/creator/agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func createToolsetRegistry(workingDir string) *teamloader.ToolsetRegistry {
120120
}
121121

122122
registry := teamloader.NewDefaultToolsetRegistry()
123-
registry.Register("filesystem", func(context.Context, latest.Toolset, string, *config.RuntimeConfig) (tools.ToolSet, error) {
123+
registry.Register("filesystem", func(context.Context, latest.Toolset, string, *config.RuntimeConfig, string) (tools.ToolSet, error) {
124124
return tracker, nil
125125
})
126126

pkg/creator/agent_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func TestFileWriteTracker(t *testing.T) {
158158
require.NotNil(t, registry)
159159

160160
// Create the toolset through the registry
161-
toolset, err := registry.CreateTool(ctx, latest.Toolset{Type: "filesystem"}, runConfig.WorkingDir, runConfig)
161+
toolset, err := registry.CreateTool(ctx, latest.Toolset{Type: "filesystem"}, runConfig.WorkingDir, runConfig, "test-agent")
162162
require.NoError(t, err)
163163
require.NotNil(t, toolset)
164164

0 commit comments

Comments
 (0)