Files
llmgw/internal/cli/memory.go
T
2026-09-24 04:04:03 +03:00

63 lines
2.0 KiB
Go

package cli
import (
"fmt"
"github.com/spf13/cobra"
)
// newMemoryCmd turns note storage on for a project, or off.
//
// A command rather than a configuration key for the same reason threads are:
// keeping what an agent decided to remember is a decision about data, not about
// deployment, and it should look like an act rather than a default nobody read.
func newMemoryCmd(open opener) *cobra.Command {
var (
project string
hours int
off bool
)
cmd := &cobra.Command{
Use: "memory",
Short: "Keep notes an agent writes for itself, across conversations",
Long: "With this on, an agent can save and search notes through /v1/memory or the\n" +
"MCP tools at /mcp (remember, recall, forget), and find them again in later\n" +
"conversations.\n\n" +
"Off for every project until this is run. The retention is required: notes\n" +
"expire that many hours after they were last written, so a store nobody\n" +
"chose a number for does not keep everything forever.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
if !off && hours <= 0 {
return fmt.Errorf("--retain-hours is required: say how long notes are kept, or pass --off")
}
s, err := open(cmd.Context())
if err != nil {
return err
}
defer s.Close()
keep := hours
if off {
keep = 0
}
if err := s.SetMemoryRetention(cmd.Context(), project, keep); err != nil {
return err
}
if keep == 0 {
fmt.Fprintf(cmd.OutOrStdout(),
"%s keeps no notes. Existing ones are removed at the next prune.\n", project)
return nil
}
fmt.Fprintf(cmd.OutOrStdout(),
"%s keeps notes for %d hours after they were last written.\n", project, keep)
return nil
},
}
cmd.Flags().StringVar(&project, "project", "default", "project id")
cmd.Flags().IntVar(&hours, "retain-hours", 0, "how long a note is kept after it was last written")
cmd.Flags().BoolVar(&off, "off", false, "stop keeping notes for this project")
return cmd
}