v0.8.13: tool cards paired by call id, markdown rendered while it streams
Two things the window got wrong once a real turn ran through it, plus the switch that was invisible on a dark theme. Tool cards (app/src/core/AgentCore.*, app/qml/Main.qml, ToolCard.qml): - A turn that called the same tool twice left the first card on "running" forever and gave its result to the second card: both were paired by name. cst_agent_hooks_t hands the call (ctl_tool_call_t) to every callback, so the id travels with the signals now (toolEvent(phase, id, name, detail), toolResult(id, name, exitCode, output)) and findTool() matches on it, in the same way AgentCore::history() fills it from tool_call_id / tool_calls_json for a replayed session. Only a call without an id -- an old text-protocol session -- still falls back to the name. - Nothing may keep spinning after a turn: closeAllRows() runs when the turn ends and settles every open row; a call that never came back shows "no result" (state "unfinished") and no longer claims an exit code. Streaming text (app/qml/Main.qml, ChatView.qml): - The answer was plain text while it streamed and turned into markdown only when the turn ended. A 120 ms timer now re-renders the open answer with the engine's own renderer (AgentCore::renderMarkdown -> cst_web_md_html), so a list, a table or a code fence fills in formatted as it arrives. A row keeps its own "html" field; a replayed session renders once, where its rows are built. QML details: - the Plan mode Switch got a drawn indicator: the Basic style's pill is a dark pill with a dark knob on this theme, which made the control look disabled. - Every engine signal handler is a plain window function now (engineToolEvent, engineToolResult, engineTurnFinished, engineAssistant, ...), which is also what lets --uitest drive the exact path; rowJson(i) returns a transcript row as JSON for it (an object would not survive QMetaObject::invokeMethod). Tests: 6 more checks -- a call opens a card, two calls of one tool are two cards, the result lands on the card of its own call, the other card is untouched, the turn end settles an open call, a delta opens a streaming answer and markdown is rendered while it still streams. 52/52 pass, --selftest, ctest cst-app-selftest. Version 0.8.13.
This commit is contained in:
@@ -273,6 +273,30 @@ Rectangle {
|
||||
checked: side.planMode
|
||||
implicitHeight: Theme.touchTarget
|
||||
onClicked: side.planModeRequested(checked)
|
||||
/* The Basic style's indicator is a dark pill with a dark
|
||||
* knob here, so it is drawn: thumb-sized, accent when
|
||||
* on, clearly off when not. */
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 44
|
||||
implicitHeight: 22
|
||||
x: planSwitch.leftPadding
|
||||
y: parent.height / 2 - height / 2
|
||||
radius: 11
|
||||
color: planSwitch.checked ? Theme.accentDim : Theme.surfaceAlt
|
||||
border.width: 1
|
||||
border.color: planSwitch.checked ? Theme.accent : Theme.border
|
||||
Rectangle {
|
||||
width: 16
|
||||
height: 16
|
||||
y: 2
|
||||
x: planSwitch.checked ? parent.width - width - 3 : 3
|
||||
radius: 8
|
||||
color: planSwitch.checked ? Theme.text : Theme.textDim
|
||||
Behavior on x {
|
||||
NumberAnimation { duration: 120; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: "Plan mode"
|
||||
|
||||
Reference in New Issue
Block a user