render typed tool cards and live session status from stream-json
The conversation pane now exploits the structured stream instead of dumping tool input as JSON. ConversationController indexes tool_use by id so a tool_result pairs back to its call and renders the Edit/Write diff or is_error failure in place; per-tool bodies (Bash command+output, Read/Grep file/query) reuse the shared renderers factored out of the permission card. SessionStatus gains cost + contextWindow + rate-limit, read straight off the init/result/rate_limit_event events, so the in-pane status line reflects live state without the config probe. Partial-message streaming is wired behind --include-partial-messages but its event shape is unverified against the live binary and degrades to a no-op if it differs — see T-184. T-168. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -388,10 +388,17 @@ class TranscriptReader {
|
||||
}
|
||||
|
||||
/// Live per-session status surfaced for the status strip / sidebar
|
||||
/// (T-145). All fields nullable — a chunk only carries what it saw, and
|
||||
/// the reader [merge]s deltas into a running status.
|
||||
/// (T-145, T-168). All fields nullable — a chunk only carries what it saw,
|
||||
/// and the reader [merge]s deltas into a running status.
|
||||
class SessionStatus {
|
||||
const SessionStatus({this.model, this.permissionMode, this.contextTokens});
|
||||
const SessionStatus({
|
||||
this.model,
|
||||
this.permissionMode,
|
||||
this.contextTokens,
|
||||
this.cost,
|
||||
this.contextWindow,
|
||||
this.rateLimitInfo,
|
||||
});
|
||||
|
||||
/// Assistant `message.model`, e.g. `claude-opus-4-7`.
|
||||
final String? model;
|
||||
@@ -404,21 +411,42 @@ class SessionStatus {
|
||||
/// the transcript doesn't carry the model's context limit.
|
||||
final int? contextTokens;
|
||||
|
||||
bool get isEmpty => model == null && permissionMode == null && contextTokens == null;
|
||||
/// Cumulative cost in USD from the `result` event's `total_cost_usd`
|
||||
/// field (T-168). Null until the first result event arrives.
|
||||
final double? cost;
|
||||
|
||||
/// The model's context-window size in tokens from the `result` event's
|
||||
/// `modelUsage.<model>.contextWindow` (T-168). Null until first result.
|
||||
final int? contextWindow;
|
||||
|
||||
/// Latest rate-limit info string from `rate_limit_event`, e.g.
|
||||
/// `"rate limited — resets 14:32"` (T-168). Null when not rate-limited.
|
||||
final String? rateLimitInfo;
|
||||
|
||||
bool get isEmpty => model == null && permissionMode == null && contextTokens == null && cost == null && contextWindow == null && rateLimitInfo == null;
|
||||
|
||||
/// Overlay [other]'s non-null fields onto this one.
|
||||
SessionStatus merge(SessionStatus other) => SessionStatus(
|
||||
model: other.model ?? model,
|
||||
permissionMode: other.permissionMode ?? permissionMode,
|
||||
contextTokens: other.contextTokens ?? contextTokens,
|
||||
cost: other.cost ?? cost,
|
||||
contextWindow: other.contextWindow ?? contextWindow,
|
||||
rateLimitInfo: other.rateLimitInfo ?? rateLimitInfo,
|
||||
);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is SessionStatus && other.model == model && other.permissionMode == permissionMode && other.contextTokens == contextTokens;
|
||||
other is SessionStatus &&
|
||||
other.model == model &&
|
||||
other.permissionMode == permissionMode &&
|
||||
other.contextTokens == contextTokens &&
|
||||
other.cost == cost &&
|
||||
other.contextWindow == contextWindow &&
|
||||
other.rateLimitInfo == rateLimitInfo;
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(model, permissionMode, contextTokens);
|
||||
int get hashCode => Object.hash(model, permissionMode, contextTokens, cost, contextWindow, rateLimitInfo);
|
||||
}
|
||||
|
||||
/// Result of [parseTranscriptChunk]: items, version-drift warnings, and
|
||||
@@ -429,7 +457,17 @@ class _StatusAcc {
|
||||
String? model;
|
||||
String? permissionMode;
|
||||
int? contextTokens;
|
||||
SessionStatus toStatus() => SessionStatus(model: model, permissionMode: permissionMode, contextTokens: contextTokens);
|
||||
double? cost;
|
||||
int? contextWindow;
|
||||
String? rateLimitInfo;
|
||||
SessionStatus toStatus() => SessionStatus(
|
||||
model: model,
|
||||
permissionMode: permissionMode,
|
||||
contextTokens: contextTokens,
|
||||
cost: cost,
|
||||
contextWindow: contextWindow,
|
||||
rateLimitInfo: rateLimitInfo,
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user