An agent with a task-creating tool re-creates the same reminder on
every run. One deployment reached 6,399 tasks for a single agent, and
4,734 of them (74%) were byte-identical in both prompt and schedule.
CreateTask now returns the task that is scheduled, which is the
existing one when an equivalent task is already set. The caller sees a
success either way. An error would invite the model to retry with
different wording, and that agent already held seven phrasings of one
reminder.
Tasks match on agent, schedule type, schedule value and a normalised
prompt: lowercased, with whitespace collapsed and punctuation dropped.
Reworded prompts stay distinct. Merging prompts that differ in their
words risks dropping a task somebody meant to schedule, so a per-agent
ceiling bounds that case instead. At the ceiling, creation fails with a
message naming list_tasks and remove_task so the agent can free room
itself. A duplicate consumes no room and is never refused.
Dedupe is on by default with a ceiling of 100 tasks per agent.
LOCALAGI_SCHEDULER_DEDUPE_TASKS and
LOCALAGI_SCHEDULER_MAX_TASKS_PER_AGENT tune them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KZaoEXfGsjmkhXtVxtvPp4
Both on-disk histories grew without limit. One deployment reached
91,849 conversation files (2.7 GB) and a 684 MB scheduler store holding
71,580 task runs.
Conversation dumps have no reader. conversationsPath appears five times
in the tree: the option, its setter, and the three lines that write. A
new Prune sweeps the directory by age and by a per-agent count, taking
the timestamp from the filename so a sweep is one ReadDir with no stat
per file. Files that do not match the naming scheme are left alone. The
count limit matters as much as the age limit: one agent wrote 40,670
dumps in a single month, and an age window alone keeps all of them. A
"decision-" prefixed dump buckets separately from the agent's own, so
those rounds cannot evict the history worth keeping.
The scheduler store re-marshals its whole file on every task run, so an
unbounded run list makes each execution more expensive than the last.
JSONStore now caps runs per task and by age, and drops runs whose task
is gone. It prunes at load as well, so a store that has already grown
shrinks without waiting for the next execution.
Retention is on by default: 30 days and 200 dumps per agent, 20 runs
per task and 30 days of runs. Five LOCALAGI_ variables tune it, and 0
disables any single limit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KZaoEXfGsjmkhXtVxtvPp4
* Merge origin/main and resolve conflicts: keep all features including auto-compaction and evaluation
* fix: resolve merge conflict syntax errors in config.go
* feat: wire auto-compaction options to cogito
Wire enableAutoCompaction and autoCompactionThreshold options to
cogito.WithCompactionThreshold() when starting the agent.
---------
Co-authored-by: Team Coding Agent 1 <team-coding-agent-1@local>
* feat: add scheduler task template and template-based skills prompt
- Add WithSchedulerTaskTemplate option for recurring tasks run by scheduler
- Expose scheduler_task_template in core/state/config.go for user configuration
- Add WithSkillPromptTemplate option for custom skill prompt templates
- Use {{.Skills}} slice in templates to iterate over Skill.Name, Skill.Description
- Default template mimics current XML behavior with <available_skills> format
- Rename customIntro to customTemplate in services/skills for consistency
* cleanups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Update core/state/config.go
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@localai.io>
Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This allows to configure specifically how the Knowledge base should be
accessible to the agent.
- Auto search: When enabled, every message will trigger a search to the
knowledge base. This is useful mostly if you mean to give immediate
context to the agent. Particularly suited for search agents.
- As tools: it will inject search and add tools to the knowledge base so
the agent can handle these autonomously.
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* WIP
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Drop old webui
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Almost there
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* It builds
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Make it build
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fixups, still doesn't work
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* unused now
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Send result before closing
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Fix observability
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Drop MCP code and wire-up in cogito
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Drop some templates
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Keep reporting into conv
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* tests fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* tests fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Do not complete observable during thought process
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Update cogito
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Drop unneded option now
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Fixups
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Better handling of user tools
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* TEST
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Add flake attempts
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Revert "TEST"
This reverts commit 8b12a9fd03.
* tKeep indexing MCP actions
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Split CI jobs to improve speed
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* CI optimizations
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Bump timeout
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Bump cogito
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fix: always commit last progress
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* chore: better management of observables
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
---------
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* feat: switch to official MCP SDK
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* Drop MCP Box
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
---------
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
* fix(core): Add recursive loop detection and move loop detection
Signed-off-by: Richard Palethorpe <io@richiejp.com>
* fix(ci): Free up space after installation to avoid out of space error
Signed-off-by: Richard Palethorpe <io@richiejp.com>
---------
Signed-off-by: Richard Palethorpe <io@richiejp.com>
* refactor(ui): Make message status SSE name more specific
Signed-off-by: Richard Palethorpe <io@richiejp.com>
* feat(ui): Add structured observability events
Signed-off-by: Richard Palethorpe <io@richiejp.com>
---------
Signed-off-by: Richard Palethorpe <io@richiejp.com>
* switch to observer pattern
Signed-off-by: mudler <mudler@localai.io>
* keep conversation history in telegram and slack
* generalize with conversation tracker
---------
Signed-off-by: mudler <mudler@localai.io>