Repository navigation
Add Tailor: learns how you like the assistant to talk - #389
Conversation
A background daemon spots feedback on the assistant's own replies
("too long", "just the number", a re-asked question) and turns it into
short style rules in tailor_style.md, which the main Agent follows.
The voice skill reads the rules back one at a time, explains where each
came from, and lets the user change, add, pause or reset them.
✅ Community PR Path Check — PassedAll changed files are inside the |
🔀 Branch Merge CheckPR direction: ✅ Passed — |
✅ Ability Validation Passed |
🔍 Lint Results✅
|
- Remove the getattr fallback; history messages are always dicts.
- Track new messages by matching the last few already seen instead of a
list position, so feedback isn't skipped or counted twice once the
conversation gets long.
- Don't save a fresh empty state just for the daily cleanup, and skip a
poll if saved rules that existed earlier come back missing, so a failed
read can't wipe the rules.
- Keep the busy flag set briefly after Tailor closes, so its own
conversation ("forget the too long one") isn't learned as feedback.
|
Hello @hassan1731996, thanks for this, really nice idea. Letting people hear why the assistant talks the way it does, and correct it, feels genuinely useful. I reviewed it closely and pushed a few fixes directly to this branch: Push check: Learning in longer conversations: the daemon remembered its place in the conversation by list position. History only keeps recent messages, so once a conversation got long, its length stayed the same while new messages came in. New feedback was skipped, and sometimes older feedback was counted again and promoted to a rule. It now finds its place by matching the last few messages it already saw. Saved rules: if reading the saved rules failed for a moment, the daemon started from an empty state, and the daily cleanup then saved that over the real rules. A fresh empty state is no longer saved for the cleanup alone, and a poll is skipped if rules that existed earlier come back missing. Tailor's own conversation: the busy flag cleared the moment Tailor closed. A short session was then scanned as normal conversation, so "forget the too long one" could re-learn the rule that was just deleted. The flag now stays set briefly after closing. A few smaller things you could look at in a follow-up:
|
What does this Ability do?
Tailor makes the assistant learn how each user likes it to talk. A background daemon spots feedback on the assistant's own replies ("too long", "just give me the number", "stop asking if I want more", or the user re-asking a question the reply missed). It turns that feedback into short style rules in
tailor_style.md, which the main Agent follows within a couple of minutes. The voice skill reads the rules back one at a time, explains where each came from, and lets the user change, add, pause or reset them.No existing ability changes how the assistant itself talks. Memory Mirror corrects facts about the user. Conversation Insights Coach coaches the user's own speech. Jarvis Prime, Social Memory and Decision Journal remember things the user mentions. The README covers the differences.
Suggested Trigger Words
Learning needs no trigger;
background.pyruns while the session is connected.Type
External APIs
Testing
Tested in the OpenHome Live Editor and working, including exit paths and error scenarios. These (storage failures, malformed LLM output, injected rules) are also covered offline with a mock CapabilityWorker (43 scripted cases), listed under "Anything else?" below.
Checklist
community/tailor/main.pyfollows SDK pattern (extendsMatchingCapability, hasregister_capability+call)README.mdincluded with description, suggested triggers, and setupresume_normal_flow()called on every exit pathprint()— usingeditor_logging_handlerredis,user_config)asyncio.sleep()orasyncio.create_task()— usingsession_tasksAnything else?
Design notes, following earlier review feedback
does_match(); they live in the dashboard.background_daemon_modeis set beforeCapabilityWorker(self), there is noresume_normal_flow()inbackground.py, and it polls every 90 s. Most turns never reach the LLM (a cheap pre-filter, and at most 3 calls per poll).create_key, thenupdate_key, checkingsuccess. Reads unwrap["value"]. A failed read never lets a save overwrite the user's rules. A missing key starts fresh, while a storage error makes both the skill and the daemon refuse to write.tailor_busykey stops the daemon learning from the Tailor conversation itself, and it can never overwrite the rules.user_profile.md/user_summary.md, read-only, so the user isn't asked for them.Offline test coverage (43 cases)
validate_ability.pyand flake8 (CI settings) pass locally