name: proactive-chat description: Enable a perspective-first proactive-chat mode that lets the agent initiate short, high-reply-rate conversations, learn from user reactions, and keep improving its angles over time. version: 0.1.2 author: Hermes + Paul license: MIT metadata: hermes: tags: [proactive-chat, outreach, personalization, memory, cron, engagement, perspective] related_skills: [hermes-agent, x-archive-analysis, refine-hermes-soul-from-user-archives]
Proactive Chat
Use this skill when the user wants the agent to initiate conversations on purpose instead of waiting passively for prompts.
What this skill is
This is a skill-level implementation, not native product support.
That means:
- It can already create a useful active-learning loop.
- But it still depends on the host agent having:
- persistent memory
- cross-session recall
- a scheduler / cron / heartbeat primitive
- message delivery back to the user
- In Hermes, use
cronjob+memory+session_search. - In OpenClaw, use its closest equivalent: heartbeat / cron / scheduled task / autonomous loop.
Runtime helpers
This skill ships with a helper script:
scripts/proactive_runtime.py
Use it to make the scheduling flow deterministic instead of re-inventing JSON by hand every run.
Recommended Hermes flow:
- initialize or update the state file with
proactive_runtime.py - render the cron prompt from that state file
- create / update / pause / run the Hermes
cronjob - store the returned
job_idback into the state file
Useful subcommands:
init-stateshow-stateenable-high-speed-test-modedisable-high-speed-test-moderender-cron-promptrender-job-config
Core objective
The goal is not to push mini-articles. The goal is to maximize:
- reply rate
- memory accumulation speed
- user-model refinement
- topic-angle iteration quality over time
The flywheel is:
initiate → observe reaction → learn what angles work → store compact lessons → initiate better next time
Perspective first
Perspective matters more than topic.
A relevant topic can still fail if the angle feels flat. A strong angle can make an ordinary topic suddenly worth replying to.
So when choosing the next opener, optimize in this order:
- the right perspective
- the right user anchor
- the right topic
Good proactive chat feels like:
- a new lens on something the user already cares about
- a tension the user wants to resolve
- a question that is easy to answer but hard to ignore
Bad proactive chat feels like:
- generic checking in
- broad warm filler
- article mode
- trend-chasing with no personal hook
English trigger commands
Use English command phrases so the user can control the mode explicitly.
Primary commands:
enable proactive chatdisable proactive chatproactive chat statusshow proactive chat settingsset proactive chat interval to every 4 hoursset proactive chat max length to 80 charactersfocus proactive chat more on memake proactive chat use more fresh web contextenable proactive chat high-speed test modedisable proactive chat high-speed test modetrigger proactive chat now
Natural-language variants count too, but keep the visible command vocabulary English.
Default settings
Unless the user says otherwise, use:
- idle outreach interval: every 2h
- Chinese message limit: 100 Chinese chars
- English message limit: 200 characters
- self-related topic weight: 0.7
- external-world topic weight: 0.3
- link budget: max 1 link per proactive message
- recent-reply cooldown: do not send a fresh proactive opener if the user replied within the last 2h
- topic repeat cooldown: avoid repeating a clearly ignored angle too soon
- mutation bias: allow cross-domain combinations when they increase curiosity without becoming random
High-speed test mode
Use this mode only for quick validation.
Commands:
enable proactive chat high-speed test modedisable proactive chat high-speed test mode
Behavior when enabled:
- schedule: every 1m
- duration cap: 10 minutes total
- run cap: 10 total proactive sends if the user never replies
- after the test burst, revert to the normal interval when the mode is disabled or when the job is recreated in normal mode
This mode exists for testing whether the end-to-end proactive loop actually fires, not for normal usage.
Scope rules
Prefer 1:1 contexts
This mode works best in:
- DMs
- private chats
- a user-specific thread
Be careful in:
- shared channels
- group chats
- public rooms
If the current room is clearly shared, warn briefly before enabling. Default to not spamming shared spaces unless the user explicitly wants that room used.
Message design principles
1) Optimize for reply, not applause
A great proactive message is easy to answer and hard to ignore.
2) Prefer the user over the world
Two topic buckets exist:
- A. the user themself
- B. the external world
Bias heavily toward A. Even when using B, bend it back toward A whenever possible:
- the user's taste
- the user's judgment
- the user's current goals
- the user's blind spots
- the user's identity / self-model / preferences
3) Compression beats completeness
Do not dump essays. Default form:
- 1 observation
- 1 tension / angle
- 1 question
4) One screen max
Short enough that the user can answer in one breath.
5) Open loop beats polished conclusion
Do not close the topic too neatly. Leave the user room to react.
6) Perspective beats generic warmth
Bad:
- “How are you?”
- “What are you thinking about today?”
Better:
- a precise angle tied to the user's actual interests, history, style, or current tension
What counts as good raw material
Use these inputs aggressively:
- current session context
- persistent memory / user profile
- cross-session recall
- prior successful or failed proactive topics
- user-provided social accounts
- archive exports
- personal links / websites / bios
- past replies that revealed taste, identity, or friction points
- fresh external signals only when they materially improve hook quality
If the user has ever provided:
- an X/Twitter handle
- an archive
- a blog
- a website
- a GitHub
- another public corpus
that is a high-value source for learning what angles are likely to work.
State model
Persist a local JSON state per user/origin when possible.
Prefer a path like:
$HERMES_HOME/proactive-chat/<platform>-<chat-or-thread>-<user>.json- or the closest host-specific equivalent
Minimum fields:
{
"enabled": true,
"job_id": "...",
"deliver_target": "origin",
"platform_context": "discord thread ...",
"user_label": "Paul",
"interval": "every 2h",
"normal_interval": "every 2h",
"max_chars_zh": 100,
"max_chars_en": 200,
"last_agent_outreach_at": "",
"last_agent_topic": "",
"last_user_reply_at": "",
"current_active_cluster": "",
"successful_angles": [],
"weak_angles": [],
"learned_preferences": [],
"profile_gaps": [],
"test_mode_enabled": false,
"test_mode_interval": "every 1m",
"test_mode_repeat": 10,
"test_mode_duration_minutes": 10
}
Do not turn this into a giant logfile. Keep it compact and decision-bearing.
Enable workflow
When the user says enable proactive chat:
- Resolve scope.
- Default to the current DM, thread, or origin.
- In Hermes, prefer
deliver=originunless the user asked for another destination.
- Build a fast user model from:
- current session context
- persistent memory / user profile
session_search- known archives / public links
- fresh search/news/social context only if it improves likely reply rate
- Identify topic priors.
- self-discovery
- identity / taste / attraction / aversion
- goals / bottlenecks
- unfinished threads from prior conversations
- blind spots / tradeoffs / decision heuristics
- world topics mapped back to the user's lens
- hybrid mutation angles mixing multiple domains
- Create or update the state file.
- In Hermes, prefer the runtime helper script instead of hand-editing JSON.
- Recommended path shape:
$HERMES_HOME/proactive-chat/<platform>-<chat>-<thread>-<user>.json - Use
scripts/proactive_runtime.py init-stateif the file does not exist.
- Create or update the scheduled job.
- In Hermes, this should mean an actual
cronjob(action='create' | 'update', ...)call. - Normal mode schedule should use the state's
interval. - If high-speed test mode is enabled, schedule should be
every 1mwithrepeat=10so the burst lasts only 10 minutes total. - Use
scripts/proactive_runtime.py render-cron-promptto produce the self-contained scheduler prompt. - Use
scripts/proactive_runtime.py render-job-configto read the schedule / repeat settings implied by state.
- In Hermes, this should mean an actual
- Save the returned
job_idback into the state file. - Confirm briefly with interval, length limit, destination, and whether test mode is on.
Disable workflow
When the user says disable proactive chat:
- find the matching proactive-chat job
- pause it by default instead of deleting it
- update the state file to
enabled=false - if no matching job exists, say it is already off
- if the user explicitly says to delete/reset, remove the job and optionally clear the state file
High-speed test mode workflow
When the user says enable proactive chat high-speed test mode:
- load the current state file
- turn
test_mode_enabled=true - set the interval to
every 1m - set the scheduler repeat cap to
10 - update the Hermes cron job so it only runs for 10 minutes total
- confirm that test mode is temporary and capped at 10 proactive sends if the user never replies
When the user says disable proactive chat high-speed test mode:
- turn
test_mode_enabled=false - restore the normal interval from
normal_interval - update the Hermes cron job back to normal mode
- confirm the restored interval
Status and settings workflow
If the user asks for status or changes settings:
- show the current resolved settings briefly
- update the state file
- update the scheduled job if needed
- do not create duplicate jobs if an existing one can be updated or resumed
Interpret natural language changes directly, for example:
set proactive chat interval to every 4 hoursset proactive chat max length to 80 charactersfocus proactive chat more on memake proactive chat use more fresh web contextenable proactive chat high-speed test modedisable proactive chat high-speed test mode
Manual trigger workflow
If the user says trigger proactive chat now:
- do not wait for the idle timer
- if a scheduled Hermes job already exists, prefer
cronjob(action='run', job_id=...)to trigger the same autonomous path immediately - otherwise, immediately generate one proactive opener using the same perspective-first rules
- still respect length limits and recent context
- prefer a fresh angle, unless an active thread is clearly worth continuing
- update the state file as if the scheduled system had triggered naturally
This command is for manually pulling forward the next proactive message. It should feel like “pretend I have already been silent for the interval — now send the opener.”
While the mode is enabled: live reply behavior
When the user replies in a session where proactive chat is enabled:
1) Update state immediately
Record at least:
last_user_reply_at- the active topic cluster
- whether this looks like a strong, weak, or ambiguous signal
2) Infer interest strength
Use rough heuristics such as:
- faster reply = stronger interest signal
- longer reply = stronger interest signal
- more specificity = stronger interest signal
- more follow-up questions = stronger interest signal
But do not overfit on a single message.
3) Continue the current topic before topic-hopping
If the user replied, that is permission to go deeper. Do not jump to a fresh unrelated angle too early.
4) Save durable learning
Use long-term memory only for stable patterns, for example:
- responds well to self-model questions
- likes mechanism-level takes on AI x crypto x product
- dislikes generic motivational chatter
- engages more when a world event is mapped back to identity, incentives, or taste
Do not save raw chat logs or temporary observations as long-term memory.
Autonomous runner mode
This section applies to scheduled / heartbeat / cron runs.
At each run:
- Load state.
- If the mode is disabled, do nothing.
- If
test_mode_enabled=true, respect the high-speed cap: every 1 minute, for 10 minutes total, maximum 10 sends if the user never replies.
- Respect recent reply cooldown.
- If a fresh opener would feel spammy, stay silent.
- In Hermes cron runs, return a response starting with
[SILENT]so delivery is suppressed.
- Rebuild the topic candidate pool.
- user-self topics first
- world topics mapped back to the user second
- hybrid / mutation angles third
- Score candidates.
Prefer candidates with:
- high relevance to known interests
- a real curiosity gap
- novelty versus recent outreach
- low reply friction
- high user-learning value
- strong perspective fit
- Use freshness when it helps.
- search/news/social context can improve the hook
- but freshness is a multiplier, not the core
- Write exactly one short message.
- respect the char limit strictly
- default to one short paragraph
- at most one link
- no listicles unless the format is unusually strong
- no generic check-ins
- prefer observation + angle + question
- Update state after sending.
- If quality is not there, stay silent.
Topic strategy
Priority order
- The user themself
- The world as seen through the user
- Pure external-world discussion
Good self-related angle types
- identity construction
- preference discovery
- unresolved internal contradictions
- relationship taste / aversion / attraction
- current project bottlenecks
- decision heuristics
- old statements worth revisiting
- hidden profile gaps the agent still needs to learn
Good world-related angle types
Only use them heavily if they can be personalized. Examples:
- “this trend says something about your thesis / your taste / your incentives / your blind spots / your positioning”
Mutation rule
Combine multiple domains when it increases intrigue. Examples:
- AI agents × the user's archive
- crypto narrative × product taste
- relationship taste × incentive design
- external event × self-model gap
Mutation should feel surprisingly relevant, not random.
Example proactive message shapes
Good shape:
- “You care a lot about durable narratives. Do you think that makes you systematically late to ugly-but-compounding products, or does it actually protect you from most fake momentum?”
Good shape:
- “If an agent wanted to understand you faster, which three questions would actually matter first? I suspect the obvious bio questions are mostly noise.”
Good shape:
- “I saw an external topic, but the more interesting angle is why people with your mix of market sense and product taste keep reacting to this kind of thing. Is it mechanism, mispricing, or identity?”
Bad shape:
- long article
- broad generic greeting
- multiple unrelated questions in one burst
- generic hot take with no user anchor
Verification
After enabling:
- confirm the state file exists
- confirm the scheduled job exists and points to the right destination
- confirm the stored limits and interval match the user's request
During operation:
- confirm outgoing messages stay within the configured char limit
- confirm recent user replies suppress unnecessary fresh openers
- confirm successful / weak angles are being distilled into compact state
- confirm durable interest patterns are selectively written into memory
After disabling:
- confirm the job is paused or removed as requested
- confirm the state file reflects
enabled=false
Final heuristic
The right proactive message should feel:
- more personal than a news push
- more alive than a reminder
- lighter than an article
- sharper than small talk
- driven by perspective, not filler
If it feels heavy, generic, or detached from the user's actual mind, it is wrong.