mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
fix(tui): include learning notes in turn completion
Carry learning events on the message completion payload so remembered/recalled notes flush deterministically after the assistant response even if standalone event timing is missed.
This commit is contained in:
@@ -1108,6 +1108,8 @@ def _on_tool_complete(sid: str, tool_call_id: str, name: str, args: dict, result
|
||||
|
||||
event = learning_event_from_tool(name, args, result)
|
||||
if event:
|
||||
if session is not None:
|
||||
session.setdefault("learning_events", []).append(event)
|
||||
_emit("learning.event", sid, event)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -2340,6 +2342,7 @@ def _(rid, params: dict) -> dict:
|
||||
if session.get("running"):
|
||||
return _err(rid, 4009, "session busy")
|
||||
session["running"] = True
|
||||
session["learning_events"] = []
|
||||
history = list(session["history"])
|
||||
history_version = int(session.get("history_version", 0))
|
||||
images = list(session.get("attached_images", []))
|
||||
@@ -2502,6 +2505,9 @@ def _(rid, params: dict) -> dict:
|
||||
payload["reasoning"] = last_reasoning
|
||||
if status_note:
|
||||
payload["warning"] = status_note
|
||||
learning_events = list(session.get("learning_events") or [])
|
||||
if learning_events:
|
||||
payload["learning_events"] = learning_events
|
||||
rendered = render_message(raw, cols)
|
||||
if rendered:
|
||||
payload["rendered"] = rendered
|
||||
|
||||
@@ -547,11 +547,21 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
||||
return
|
||||
case 'message.complete': {
|
||||
const { finalMessages, finalText, wasInterrupted } = turnController.recordMessageComplete(ev.payload ?? {})
|
||||
const completedLearning = (ev.payload?.learning_events ?? [])
|
||||
.map(e => {
|
||||
const title = String(e?.title ?? '').trim()
|
||||
const verb = String(e?.verb ?? e?.type ?? 'learned').trim()
|
||||
|
||||
return title ? `${verb}: ${title}` : ''
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
||||
if (!wasInterrupted) {
|
||||
const msgs: Msg[] = finalMessages.length ? finalMessages : [{ role: 'assistant', text: finalText }]
|
||||
const learningLines = [...completedLearning, ...pendingLearning].filter((text, i, xs) => xs.indexOf(text) === i)
|
||||
|
||||
msgs.forEach(appendMessage)
|
||||
pendingLearning.forEach(text => appendMessage({ kind: 'learning', role: 'system', text }))
|
||||
learningLines.forEach(text => appendMessage({ kind: 'learning', role: 'system', text }))
|
||||
pendingLearning = []
|
||||
|
||||
if (bellOnComplete && stdout?.isTTY) {
|
||||
|
||||
@@ -425,7 +425,13 @@ export type GatewayEvent =
|
||||
| { payload: SubagentEventPayload; session_id?: string; type: 'subagent.complete' }
|
||||
| { payload: { rendered?: string; text?: string }; session_id?: string; type: 'message.delta' }
|
||||
| {
|
||||
payload?: { reasoning?: string; rendered?: string; text?: string; usage?: Usage }
|
||||
payload?: {
|
||||
learning_events?: { source?: string; summary?: string; title?: string; type?: string; verb?: string; via?: string }[]
|
||||
reasoning?: string
|
||||
rendered?: string
|
||||
text?: string
|
||||
usage?: Usage
|
||||
}
|
||||
session_id?: string
|
||||
type: 'message.complete'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user