Show runtime guidance in transcript

This commit is contained in:
wuyang6
2026-06-12 18:37:04 +08:00
parent 5bcc22622e
commit cdf27e5bd2
3 changed files with 124 additions and 1 deletions
+47
View File
@@ -71,6 +71,7 @@ from src.run_state_store import ACTIVE_RUN_STATUSES, RunStateStore
from src.session_store import ( from src.session_store import (
DEFAULT_AGENT_SESSION_DIR, DEFAULT_AGENT_SESSION_DIR,
StoredAgentSession, StoredAgentSession,
append_agent_display_message,
agent_session_delta, agent_session_delta,
cancel_session_input_queue, cancel_session_input_queue,
consume_session_guidance, consume_session_guidance,
@@ -1834,6 +1835,12 @@ def create_app(state: AgentState) -> FastAPI:
content=content, content=content,
metadata=payload.metadata, metadata=payload.metadata,
) )
if item.get('kind') == 'guidance':
_append_guidance_display_message(
safe_id,
directory=directory,
item=item,
)
return {'session_id': safe_id, 'item': item} return {'session_id': safe_id, 'item': item}
@app.patch('/api/sessions/{session_id}/input-queue/{item_id}') @app.patch('/api/sessions/{session_id}/input-queue/{item_id}')
@@ -1857,6 +1864,12 @@ def create_app(state: AgentState) -> FastAPI:
) )
if item is None: if item is None:
raise HTTPException(status_code=404, detail='Queue item not found') raise HTTPException(status_code=404, detail='Queue item not found')
if item.get('kind') == 'guidance' and item.get('status') == 'pending':
_append_guidance_display_message(
safe_id,
directory=directory,
item=item,
)
return {'session_id': safe_id, 'item': item} return {'session_id': safe_id, 'item': item}
@app.delete('/api/sessions/{session_id}/input-queue/{item_id}') @app.delete('/api/sessions/{session_id}/input-queue/{item_id}')
@@ -3050,6 +3063,40 @@ def _normalize_transcript_entry(entry: dict[str, Any]) -> dict[str, Any]:
return out return out
def _append_guidance_display_message(
session_id: str,
*,
directory: Path,
item: dict[str, Any],
) -> None:
content = str(item.get('content') or '').strip()
item_id = item.get('id')
if (
not content
or not isinstance(item_id, int)
or isinstance(item_id, bool)
):
return
message_id = f'user_guidance_{item_id}'
append_agent_display_message(
session_id,
{
'role': 'user',
'content': content,
'state': 'final',
'message_id': message_id,
'metadata': {
'kind': 'runtime_guidance_display',
'queue_item_id': item_id,
'lineage_id': message_id,
'run_id': str(item.get('run_id') or ''),
'created_at': float(item.get('created_at') or time.time()),
},
},
directory=directory,
)
def _truncate_api_text(text: str, limit: int) -> str: def _truncate_api_text(text: str, limit: int) -> str:
if len(text) <= limit: if len(text) <= limit:
return text return text
@@ -985,7 +985,10 @@ const ComposerPendingInputQueue: FC<{ sessionId: string | null }> = ({
status: "pending", status: "pending",
}) })
.catch(() => undefined) .catch(() => undefined)
.finally(dispatchInputQueueChanged); .finally(() => {
dispatchInputQueueChanged();
window.dispatchEvent(new Event("claw-sessions-changed"));
});
}} }}
> >
+73
View File
@@ -213,6 +213,79 @@ def agent_session_delta(
} }
def append_agent_display_message(
session_id: str,
message: JSONDict,
directory: Path | None = None,
) -> dict[str, Any] | None:
target_dir = directory or DEFAULT_AGENT_SESSION_DIR
if not isinstance(message, dict):
return None
message_key = _display_message_key(message)
message_json = json.dumps(message, ensure_ascii=False, sort_keys=True)
now = time.time()
with _connect_agent_session_db(target_dir) as conn:
existing = conn.execute(
"""
select seq, message_json
from agent_display_messages
where session_id = ? and message_key = ?
order by seq asc
limit 1
""",
(session_id, message_key),
).fetchone()
if existing is not None:
if existing['message_json'] != message_json:
conn.execute(
"""
update agent_display_messages
set role = ?,
updated_at = ?,
message_json = ?
where session_id = ? and seq = ?
""",
(
str(message.get('role') or ''),
now,
message_json,
session_id,
int(existing['seq']),
),
)
return {
'seq': int(existing['seq']),
'updated_at': now,
'message': message,
}
latest = conn.execute(
"""
select max(seq) as latest_seq
from agent_display_messages
where session_id = ?
""",
(session_id,),
).fetchone()
seq = int(latest['latest_seq'] or 0) + 1 if latest is not None else 1
conn.execute(
"""
insert into agent_display_messages (
session_id, seq, message_key, role, updated_at, message_json
)
values (?, ?, ?, ?, ?, ?)
""",
(
session_id,
seq,
message_key,
str(message.get('role') or ''),
now,
message_json,
),
)
return {'seq': seq, 'updated_at': now, 'message': message}
def enqueue_session_input( def enqueue_session_input(
session_id: str, session_id: str,
*, *,