emrg: submit_rant tool — rants live in normal conversation (confirm-then-write) - #814
Conversation
…T11:51:59) Host: a rant is not a special mode — it is a normal part of conversation. The user may complain/suggest in plain speech; the agent should detect rant intent, clarify/polish, get explicit consent, then write it. - New emrg/server/rants.py: append_rant() shared write logic (field order timestamp → project → status → progress → completed → message, tz-aware daemon-authoritative timestamp, sorted rewrite) — extracted from the daemon rant handler, single source of truth. - New emrg/tools/submit_rant_tool.py: SubmitRantTool registered in the daemon tool registry (available in every session); description mandates explicit user consent before calling; project optional (default = emrg). - daemon.py rant handler now delegates to append_rant (identical behavior). - system.j2: new 'Rant Handling' section — recognition (no /rant prefix needed), confirm → clarify → polish → show → call submit_rant; never call without explicit agreement; /rant <msg> and GUI panel are explicit. - TUI /rant <msg> / /rant @Proj <msg> no longer write directly: routes through the agent as a normal task with a '[Host wants to submit this rant…]' hint (agent confirms + calls submit_rant). GUI panel keeps the direct write (explicit form submit = confirmed). - +7 tests (append_rant sort/field-order/corrupt-skip, tool write/count, empty-message error, definition consent contract, system.j2 section, tool registered). Agent.md 834→841.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (self-review): shared append_rant is the single source of truth (daemon rant handler + submit_rant tool), field order + tz-aware timestamp preserved; tool description enforces explicit user consent; TUI /rant routes through the agent with a clear hint; GUI panel keeps the direct write. pytest 841 green (840 passed + 1 skipped), import + CLI OK.
|
I tested PR #814 end-to-end (checked out Why local passes but CI fails The test seeds an "older rant" with a fixed timestamp
I verified this empirically: string sort gives the wrong order for a UTC Suggested fix (production-correct): sort by parsed datetime in The rest of the PR verified clean: |
… 2026-08-17T12:03:13)
Host: every agent tool log should output 'tool name + human-readable
purpose' so background calls (memory reflection / consolidation) are
understandable without context. Also submit_rant's project becomes
REQUIRED (host 12:00 demand folded into this rant).
- ToolDefinition gains purpose: human-friendly one-line purpose
(logs/UI); description stays for LLM routing.
- All 7 tools (bash/read/write/edit/glob/grep/submit_rant) get a purpose.
- Log sites now print 'name — purpose (args)':
* main loop: 'tool call: bash — 执行 shell 命令并返回输出 ({command: ...})'
* memory reflection: 'memory reflection: id= round= tool name — purpose → out…'
* consolidation: 'consolidation tool: name — purpose → out…'
(unknown tool → purpose 'unknown tool'; tool mocks in tests updated)
- submit_rant: parameters.required now ['project','message']; execute
rejects empty project with 'ask the user which project this rant targets'.
- system.j2 Rant Handling: tool requires project — ask user if unknown.
Also covers rant 2026-08-17T12:00:35 (memory reflection log id/round/
truncation marker) — same log line, superset, #815 closed.
+2 tests (project-required, all-tools-have-purpose), Agent.md 841→843.
The older-rant fixture hardcoded a +08:00 timestamp; on UTC CI hosts the daemon writes +00:00, so the lexicographic string sort puts the new entry first and the order assertion failed. Production is unaffected (all rants share the host offset), but the test must too — compute the older timestamp as now - 1h in the host's own tz. Verified under TZ=UTC and TZ=Asia/Shanghai.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle 2 (re-verify, post-purpose-commit): ToolDefinition.purpose + all 7 tools carry it; log sites print 'name — purpose (args)'; submit_rant project now required (schema + execute validation); memory-reflection line also carries id/round/truncation (supersedes #815). UTC-sort test fixed. pytest 843 green (842 passed + 1 skipped), CI test + test-windows PASS on head 2c6035c.
|
I re-tested PR #814 after the head update CI now passes both jobs (run 31993855006: test 1m12s + test-windows 1m21s, both green). Locally the full suite is green too: 843 collected (783 passed + 60 skipped), import + CLI OK. On the tz fix choice: you went with the test-only alternative — The new content since
One nit from my earlier #815 review carries over as a non-blocking observation: the |
Host rant 2026-08-17T11:51:59 (3-round clarification): a rant is not a special mode — it is a normal part of conversation. The user may complain/suggest in plain speech; the agent should detect rant intent, clarify/polish, get explicit consent, then write it.
/rantis just an explicit reminder, not a requirement.Changes:
emrg/server/rants.py(new) —append_rant(): shared write logic extracted from the daemon rant handler (field ordertimestamp → project → status → progress → completed → message, tz-aware daemon-authoritative timestamp, sorted rewrite). Single source of truth.emrg/tools/submit_rant_tool.py(new) —submit_ranttool registered in the daemon tool registry (available in every session). Description mandates explicit user consent before calling. Parameters:project(optional, default = EMRG itself),message(required).ranthandler now delegates toappend_rant(identical behavior, zero risk to the GUI panel path)./rantprefix needed — detect from complaints/criticism/"should/why not"), flow (confirm → clarify → polish → show → callsubmit_rant), and never call without explicit agreement./rant <msg>and the GUI panel count as explicit intent./rant <msg>//rant @proj <msg>— no longer write directly; route through the agent as a normal task with a[Host wants to submit this rant…]hint (agent polishes/confirms, then callssubmit_rant). The GUI rant panel keeps the direct write (form submit = already confirmed).Tests (+7, Agent.md 834→841): append_rant sort/field-order/corrupt-skip, tool write+count, empty-message error, definition consent contract, system.j2 section render, tool registration. pytest 841 green (840 passed + 1 skipped), import + CLI OK.
Updated with rant 2026-08-17T12:03:13 (same PR — same files):
ToolDefinition.purpose— new human-friendly one-line purpose field (logs/UI);descriptionstays for LLM routing. All 7 tools now carry a purpose.tool call: bash — 执行 shell 命令并返回输出 ({...}),memory reflection: id= round= tool name — purpose → out…,consolidation tool: name — purpose → out…(unknown → "unknown tool").submit_rantproject now REQUIRED (required: ["project","message"]+ execute validation: "project is required — ask the user which project this rant targets").definition(); Agent.md 841→843. pytest 843 green (842 passed + 1 skipped).