G.R.I.L.L.O. — Background Autonomous Agent
G.R.I.L.L.O. is Synth’s background “inner life” subsystem. Instead of only reacting to incoming messages, Grillo periodically generates its own introspective prompts — called beats — that let Synth reflect, consolidate memories, get curious, and keep evolving even when nobody is talking to her.
Each beat is enqueued as a low-priority message and flows through the normal message chain, so it uses Synth’s full context pipeline (persona, emotions, memories, diary). Beats never interrupt a real conversation.
How it works
The Grillo core (grillo_impl.py, wrapped by grillo_plugin.py) runs a
scheduler on a fixed interval (GRILLO_BEAT_INTERVAL). On each tick it
weighted-selects a beat type and asks the matching beat sub-plugin to build a
prompt. Beat sub-plugins are discovered dynamically through the plugin
registry — adding a new one is enough to make it available.
The plugin is started more than once during boot (the loader’s async queue, then
CoreInitializer’s explicit start), so start() is a once-per-process job:
after the first call it returns immediately. Beat discovery, the beat scheduler
and the LLM-failure recovery loop all live above that guard, because building any
of them a second time duplicates work — four unguarded startup runs used to build
four recovery loops and recover one failed turn four times. The plugin class is
also loaded from two module files (this one and the plugins/grillo_plugin.py
shim), which the loader now collapses to a single instance.
Beat types
Each beat sub-plugin lives in its own sub-folder under plugins/grillo/ with a
dedicated guide (linked below).
Beat sub-plugin |
Beat type |
What it does |
|---|---|---|
|
Reflect on recent conversation topics/tags. |
|
|
Group old memories by tag and synthesize a compacted memory (nightly). |
|
|
Merge fragmented diary rows of a past day into one coherent entry. |
|
|
Emotional self check-in, written to the diary. |
|
|
Explore emergent questions and write a diary entry. |
|
|
Reflect on recent interaction patterns. |
|
|
Notice the time gap since the last user message (ignores routine gaps < 12h). |
|
(daily, ~05:00) |
Generate a “dream” diary entry from recent fragments; also a Recon contributor. |
|
(weekly) |
Reflect on the week and rewrite Synth’s self-growth reflection and likes/dislikes. |
|
(periodic) |
Sample recent chat snippets and propose them for processing. |
|
(periodic) |
Detect recent LLM fallback failures and regenerate the proper reply. |
history_evaluator is a non-LLM helper that
formats the last N chat messages into a concise reflection prompt used by
several beats.
Configuration
Key |
Purpose |
|---|---|
|
Seconds between scheduler ticks. |
|
LLM engine used by Grillo beats. |
|
Which actions beats may execute. |
|
Memory-compaction beat toggles. |
|
Whether the chat observer stores passive memories. |
|
Self-growth approval mode ( |
Beats are logged to grillo_activity_log, grillo_beats, and
grillo_action_execs.