feat: surface codex runtime status

This commit is contained in:
AI Bot
2026-05-31 03:59:53 +08:00
parent cee1e7938e
commit 591638f35f
12 changed files with 544 additions and 6 deletions

View File

@@ -1353,6 +1353,83 @@ public final class BossUi {
}
}
JSONObject modelRoute = progress == null ? null : progress.optJSONObject("modelRoute");
JSONObject tokenUsage = progress == null ? null : progress.optJSONObject("tokenUsage");
JSONArray mcpServers = progress == null ? null : progress.optJSONArray("mcpServers");
JSONObject remoteControl = progress == null ? null : progress.optJSONObject("remoteControl");
boolean hasRuntimeStatus = modelRoute != null || tokenUsage != null ||
(mcpServers != null && mcpServers.length() > 0) || remoteControl != null;
if (hasRuntimeStatus) {
card.addView(divider(context));
card.addView(sectionTitle(context, "运行状态"));
if (modelRoute != null) {
String fromModel = modelRoute.optString("fromModel", "").trim();
String toModel = modelRoute.optString("toModel", "").trim();
String reason = modelRoute.optString("reason", "").trim();
if (!TextUtils.isEmpty(fromModel) && !TextUtils.isEmpty(toModel)) {
card.addView(detailRow(
context,
"",
"模型 " + fromModel + "" + toModel,
reason,
false
));
}
}
if (tokenUsage != null) {
int totalTokens = tokenUsage.optInt("totalTokens", 0);
int modelContextWindow = tokenUsage.optInt("modelContextWindow", 0);
int contextPercent = tokenUsage.optInt("contextPercent", 0);
if (totalTokens > 0) {
StringBuilder usage = new StringBuilder();
usage.append("上下文 ").append(String.format(Locale.US, "%,d", totalTokens));
if (modelContextWindow > 0) {
usage.append(" / ").append(String.format(Locale.US, "%,d", modelContextWindow));
}
if (contextPercent > 0) {
usage.append(" · ").append(contextPercent).append("%");
}
card.addView(detailRow(context, "", usage.toString(), "", false));
}
}
if (mcpServers != null) {
int shown = 0;
for (int i = 0; i < mcpServers.length(); i += 1) {
JSONObject server = mcpServers.optJSONObject(i);
String name = server == null ? "" : server.optString("name", "").trim();
if (TextUtils.isEmpty(name)) {
continue;
}
String status = server.optString("status", "").trim();
String error = server.optString("error", "").trim();
card.addView(detailRow(
context,
"M",
TextUtils.isEmpty(status) ? "MCP " + name : "MCP " + name + " · " + status,
error,
"failed".equals(status)
));
shown += 1;
if (shown >= 3) {
break;
}
}
}
if (remoteControl != null) {
String status = remoteControl.optString("status", "").trim();
String serverName = remoteControl.optString("serverName", "").trim();
if (!TextUtils.isEmpty(status)) {
card.addView(detailRow(
context,
"",
TextUtils.isEmpty(serverName) ? "远控 " + status : "远控 " + status + " · " + serverName,
"",
"errored".equals(status)
));
}
}
}
JSONArray warnings = progress == null ? null : progress.optJSONArray("warnings");
if (warnings != null && warnings.length() > 0) {
card.addView(divider(context));