Introduction¶
The DSH route is “everything is a plugin,” and an agent’s capabilities are pieced together by plugins in the profile. The conventional approach is to load tools and context into every session, but once the session ends, the question of “who this agent is” disappears—switching windows means a fresh, unfamiliar start. If you want an agent to reside on a machine permanently, remember what was said continuously, and distinguish between “what was actually done” and “what wasn’t,” then the plugin introduced below is worth a look.
life-innovation (repository Leon-dbh/life-innovation) is a DSH plugin under the “Memory” category on the community directory SkillHub. The maintainer is Leon-dbh, currently with 1 star on GitHub, package version 0.2.2 (from package.json), and license MIT. It puts memory, life timeline, rhythm, and a few limited tools into a single package without generating a persona, only providing a “room.”
What is it?¶
One-sentence positioning: An agent room installed in a DSH profile, providing cross-session memory, daily life timeline, nightly archiving and dreaming, and a read-only “home” page.
It solves three things:
- Cross-session memory: Original text precipitates into a five-layer structure and is loaded into every round of system prompts;
- Evidence-based life timeline: Life blocks are only aggregated from truly spoken words and truly called tools; periods without evidence are recorded as “gaps” without fabricating activities;
- Autonomous idle time: When no one is speaking, the agent enters different states based on the clock, quietly writing diaries, flipping through memories, reading a book, or dreaming.
Four Things in One Package¶
The README explicitly states that one package brings four things:
- Room:
life-innovationpreset, facts only, no persona; - Memory: Original text → Summary → Key points → Portrait + Relations, cross-session;
- Days: Life line aggregated only from real actions, with evidence, rhythm, and archiving;
- Her home:
/homeread-only page, and the “Home” entry in the session header bar.
It is worth noting that the plugin does not hardcode the agent name in the code. The name has only one source: agentName in the plugin config. If agentName is not set, the prompt says “You have no preset name; whatever others call you is up to them,” and the page title is “Home”; if set, the prompt adds “You are called
Memory: Five-Layer Structure and Lifecycle¶
The memory database is <home>/state/life-innovation.sqlite (configurable via config.dbPath), with a five-layer structure: raw_turns original text → summaries summaries → assertions key points → profiles portraits + relations relationships.
During every round of assembling the system prompt, ctx.systemPrompt.context currently calculates a “what you remember” segment, defaulting to ≤1200 characters. Rule extraction is deterministic, covering names, cities, work, age, birthdays, pets, likes/dislikes, plans, without calling the model for this; if there is a new description of the same thing, the old description is replaced by superseded_by. Three things explicitly not done: no session isolation, no importing old project libraries, no writing “You are a [persona]”.
The memory pack is not calculated every round. lib/packCache.js uses a set of fingerprints (date, max id of live assertions/actions/summaries, max update time/count of profiles, max id of new raw turns today) to decide whether to rebuild; when fingerprints remain unchanged, the entire segment is reused, the system prompt prefix is stable, and the provider cache hits.
Regarding lifecycle, three designs are worth noting:
- Dual Half-life: Normal memory weight drops by half in 30 days, emotional memory drops by half in 7 days; this only affects sorting and does not delete original text;
- Archive: Original text older than 90 days is moved to
raw_archive, ID remains, evidenceraw:Nremains valid; - Trash:
store.recycleRaw(id)removes original text from recall and reading; the payload stays in therecycletable, restore it withnode tools/restore.mjs --list/--id N.
When the memory pack is full, it truncates by whole lines, not splitting words in half.
Days and Rhythm¶
The life line is aggregated from real actions, without writing an activity pool: raw_turns (spoken words) + actions (called tools) → life_blocks. If there is no action between blocks for more than 45 minutes, it is recorded as a “gap” with empty evidence—do not fill it with “she is reading/staring/thinking.”
The tick checks every 60 seconds: if it satisfies 8–23 o’clock, quiet ≥20 minutes, and no diary has been written in the last 30 minutes, it writes today into <home>/diary/YYYY-MM-DD.md and leaves a write_diary entry in actions. Every diary entry carries an evidence id (raw:1–30 / act:7); days without actions are not forcibly written. Plan items carry due_at, and valid_to records after expiration, no longer appearing in the memory pack.
When no one is speaking, there are only five states, all derived from the clock and real events:
| State | When | What she does |
|---|---|---|
Awake awake |
Someone spoke in the last 10 minutes | Normal chat |
Quiet quiet |
8–23, quiet ≥20 minutes | Write diary, flip memories, read book; max 1 quiet action per 3 hours |
Night night |
23–8 | Don’t seek others; archive/dream only |
Closed closed |
After cross-day catch-up | Freeze that day, don’t rewrite diary |
Offline offline |
Host shutdown/restart | Only record a gap, don’t fill in any activities |
Archiving enters the “Night” state after 23:00, waiting for the day to finish and quiet conditions to be met before closing, writing diary/YYYY-MM-DD.md and leaving a close_day action (successful only once). Dreams take materials from the last 3 days of real original text and real actions, marked non_factual=1, evidence is raw:N / act:N; dreams do not enter life blocks or facts. The next day, the agent can use note_write with dream_date to write the dream to notes/<date>-dream.md, marking the body as “Dreams are not real things.”
State injection is life:rhythm (order 850), name injection is life:name (order 810).
Home Page and Read-Back Tools¶
The fixed entry http://127.0.0.1:60080/home is a read-only dashboard: what was done today, things remembered about you, relations, summaries, dreams (dreams marked “not real”). When there are no dreams for the day, the page shows yesterday’s and marks it “Last night’s dream · Date,” avoiding false reports like “No dream yet.” The page reads from the same SQLite via a read-only connection, does not write to the database, does not call the model, and does not speak for the agent; text is escaped, auto-refreshes every 90 seconds.
On the right side of the session header is a “Home” button, registered by client.js to conversation.session.header.actions. It opens the DSH same-origin address /life-innovation/home, which remains valid even if the fixed entry port changes.
On the agent side, there are four read-back tools, all querying only their own database, registered in apply using ctx.tools.register, and released on unloading:
| Tool | Behavior |
|---|---|
memory_find(query, limit≤8) |
Find original text deterministically sorted by word bigram + IDF + freshness + emotion weight; max 8 results, ≤200 chars, returns ref, score, why |
memory_read(ref) |
raw:<id> reads original text (≤2000 chars), act:<id> reads a real action; archived old original text is also readable |
life_status() |
Counts of original text/archive/assertions/actions/trash, what was done today, last injection count, last recall query, relationship last updated |
life_days({days:1..7}) |
Time segments, real activities (with evidence), gaps, action ledger, dreams |
Six Hands: Bounded and Quota-Based¶
Besides speaking and recalling, the agent has six other things it can do, all with boundaries, quotas, and logged in the action ledger:
| Tool | Purpose | Boundaries |
|---|---|---|
room_list / room_read |
View/read diary, notes, books at home | room_list lists diary/, notes/, books/, backups/; room_read is read-only for the first three; path cage rejects .., drive letters, symlink escape |
note_write |
Write notes to notes/; can take dream_date to record last night’s dream |
Max 3 per day, 2000 chars each; no overwriting same name; one dream per note |
book_next |
Read a segment from Project Gutenberg | Fixed 4 public domain books; 4 segments per day; read-only locally after first download |
lookup |
Check Wikipedia summary | Max 3 times per day; only traverses Wikipedia domain; returns “not found” if cannot check |
notify |
Pop a Windows notification | Max 1 per day, 120 chars; only for interactive desktop sessions |
When quiet, tick performs one real action in the order “read a local book -> flip yesterday’s diary -> flip memories,” recording it in actions. The README also specifically warns: if the local network is unreachable to zh.wikipedia.org, lookup will truthfully return “not connected” rather than using model memory to impersonate query results.
Regarding active speaking, the preset hooks @deepseek-ai/dsh-tool-schedule, allowing the agent to set its own alarms (schedule_create/list/update/delete). When the time comes, the Host delivers a message with source.kind='schedule' to wake the agent. Tasks and delivery records are kept in $DSH_HOME/storages/schedule.json, surviving restarts; only the most recent expired one is replenished.
There is an lib/outbox.js ledger for outgoing notifications, a four-state unidirectional state machine: pending / sent / uncertain / failed. If confirmation is not received, it is always uncertain. When integrating a channel, only call recordDelivery(), do not use boolean values to judge “sent or not.”
Installation and Activation¶
Prerequisites: Windows, Node.js 22+, npm; pnpm is optional (will be auto-installed if missing); DEEPSEEK_API_KEY must be in the user environment variables.
The recommended practice on GitHub is to run the official installation script:
# 1) Clone to any directory
git clone https://github.com/Leon-dbh/life-innovation.git D:/tools/life-innovation
# 2) Install (default profile=life-innovation, data dir=D:\life-innovation-home)
powershell -ExecutionPolicy Bypass -File D:/tools/life-innovation/install/install.ps1
# To name the agent, add -AgentName (only affects prompt and page, not plugin code)
powershell -ExecutionPolicy Bypass -File D:/tools/life-innovation/install/install.ps1 -AgentName '鲸鲸'
# 3) Open the fixed entry
start http://127.0.0.1:60080/
Alternatively, let DSH install directly from git:
dsh plugin --profile life-innovation add github:Leon-dbh/life-innovation
Or download the offline package from the Release: https://github.com/Leon-dbh/life-innovation/releases/latest. Note that the repository root directory is the plugin package, no sub-packages.
The installation script does five things idempotently: checks node/npm/pnpm and API key; creates D:\life-innovation-home\{state,diary,logs,backups}; writes package.json and cordis.patch.yml in %DSH_HOME%\profiles\life-innovation (default preset life-innovation); dsh plugin --profile life-innovation add <this plugin>; registers scheduled task LifeInnovationDailyBackup (at 03:30 daily, keeping 14 copies).
Common parameters:
-DataHome E:\my-agent-home # Change data directory
-AgentName '名字' # Name the agent; if blank, no preset name
-Profile my-agent # Change DSH profile name
-EntryPort 60080 # Fixed entry port
-DryRun # Only show what will happen
-Force # Rewrite existing profile files after backup
Startup method:
$env:DSH_HOME='D:\dsh-home'
dsh --profile life-innovation --port 60081 --no-open
The line dsh web: http://127.0.0.1:60081/?token=… in the log is the actual entry; accessing / directly returns 401. After entering, select the life-innovation-home workspace and create a new session; the first sentence can be “What is your name?”
Manual installation without running the script: dsh plugin --profile life-innovation add D:/workspace_1/plugins/life-innovation.
Typical Usage¶
All data is in the home directory; moving to another machine only requires moving this directory:
state/life-innovation.sqlite: memory + actions + life line + outbound ledger;diary/YYYY-MM-DD.md: diary entries;backups/export-*: archives (auto-cleaning old copies).
Use home: D:/life-innovation-home in the plugin config; changing the directory only requires changing this one place, or setting the environment variable LIFE_INNOVATION_HOME (the old JINGJING_HOME is still a fallback). If a new library does not exist during an upgrade but the old state/jingjing.sqlite exists in the same directory, it will automatically read the old library without losing memory; to explicitly specify, use config.dbPath or LIFE_INNOVATION_DB.
Export and import:
node tools/export.mjs --db D:/life-innovation-home/state/life-innovation.sqlite --data D:/life-innovation-home --out D:/life-innovation-home/backups/export-manual
node tools/import.mjs --from <export directory> --db <new machine>/state/life-innovation.sqlite --data <new machine>
Importing defaults to not overwriting existing libraries (add --force to overwrite, which first leaves a .bak-<timestamp>); diary files are merged by filename; after import, a recount is performed, and an error is reported if the numbers do not match, rather than pretending success. Archives use node tools/backup.mjs --db … --data … --keep 14, which is what the scheduled task runs.
When merging memory from another machine, stop the running web first, then merge:
node tools\merge.mjs --target D:\life-innovation-home\state\life-innovation.sqlite `
--source D:\backup\export-2026-11-05\life-innovation.sqlite `
--data D:\life-innovation-home
Merging is append-only: duplicate original text is deduplicated by “time + who said it + original text,” and only one action per call_id is kept; since the self-incrementing IDs differ on both sides, assertions.source and life_blocks.evidence will be re-pointed to the merged IDs; evidence that cannot be pointed to is not moved. Trash is not moved during merge.
Applicable Scenarios and Notes¶
Who is it for: Someone who wants to run a resident agent on a Windows machine and is willing to give it its own memory and rhythm, rather than starting from zero every round. The memory layer, life line, and archiving all revolve around “things that actually happened,” leaving gaps without evidence, which aligns with scenarios requiring strict factual standards.
Points to note before use:
- The plugin runs with the current DSH process permissions; check the source code and license (MIT) before installing and do not directly stack load it in an unknown profile;
- Currently a single-database design; memory and diary are in the same home directory; the web must be stopped before merging across machines to avoid write conflicts during the process;
- Known limitations: original text with low IDs recovered from the trash can still be read and participate in recall, but will not enter new automatic summaries;
lookupwill only truthfully report an error if the network is unreachable; - Star count is currently low (1 star), it is an early project, and the functional boundaries follow the repository README.
Ecosystem background note: DSH’s philosophy is “everything is a plugin,” SkillHub is an independent community directory site with no official affiliation to DeepSeek/Xuanfuan, do not treat it as an official app store.
Conclusion¶
The value of life-innovation lies not in “giving the agent a persona,” but in packaging cross-session memory, evidence-based life lines, and idle rhythms into a single package, while maintaining restraint on what is factual and what lacks evidence. If you are building a resident desktop agent, you can start with the step dsh plugin --profile life-innovation add github:Leon-dbh/life-innovation.
Directory page: https://www.skillhub.cn/plugins/Leon-dbh/life-innovation
Repository: https://github.com/Leon-dbh/life-innovation