agent no. from backend
3clyp50 committed
Dec 30, 2025 at 04:45 UTC
ced8f87e8ea4e899d79235d8f5b9a1b3173091f1
3 files changed
+20
-20
python/helpers/log.py
+7
@@ -136,10 +136,16 @@ class LogItem:
136
duration_ms: Optional[int] = None # Duration until next step (set by Log.log)
137
tokens_in: int = 0 # Input tokens consumed
138
tokens_out: int = 0 # Output tokens generated
139
+ agent_number: int = 0 # Agent number (0 = main agent, 1+ = subordinate agents)
140
141
def __post_init__(self):
142
self.guid = self.log.guid
143
self.timestamp = time.time() # Record creation time
144
+ # Capture agent number from context if available
145
+ if self.log.context and self.log.context.streaming_agent:
146
+ self.agent_number = self.log.context.streaming_agent.number
147
+ else:
148
+ self.agent_number = 0 # Default to main agent
149
150
def update(
151
self,
@@ -202,6 +208,7 @@ class LogItem:
208
"duration_ms": self.duration_ms, # Duration until next step
209
"tokens_in": self.tokens_in, # Input tokens
210
"tokens_out": self.tokens_out, # Output tokens
211
+ "agent_number": self.agent_number, # Agent number for identifying main/subordinate agents
212
}
213
214
webui/index.js
+4
-3
@@ -185,8 +185,8 @@ async function updateUserTime() {
185
updateUserTime();
186
setInterval(updateUserTime, 1000);
187
188
-function setMessage(id, type, heading, content, temp, kvps = null, timestamp = null, durationMs = null, tokensIn = 0, tokensOut = 0) {
189
- const result = msgs.setMessage(id, type, heading, content, temp, kvps, timestamp, durationMs, tokensIn, tokensOut);
188
+function setMessage(id, type, heading, content, temp, kvps = null, timestamp = null, durationMs = null, tokensIn = 0, tokensOut = 0, agentNumber = 0) {
189
+ const result = msgs.setMessage(id, type, heading, content, temp, kvps, timestamp, durationMs, tokensIn, tokensOut, agentNumber);
190
const chatHistoryEl = document.getElementById("chat-history");
191
if (preferencesStore.autoScroll && chatHistoryEl) {
192
chatHistoryEl.scrollTop = chatHistoryEl.scrollHeight;
@@ -314,7 +314,8 @@ export async function poll() {
314
log.timestamp,
315
log.duration_ms,
316
log.tokens_in,
317
- log.tokens_out
317
+ log.tokens_out,
318
+ log.agent_number || 0 // Agent number for identifying main/subordinate agents
319
);
320
}
321
afterMessagesUpdate(response.logs);
webui/js/messages.js
+9
-17
@@ -17,19 +17,7 @@ const PROCESS_TYPES = ['agent', 'tool', 'code_exe', 'browser', 'info', 'hint', '
17
// Main types that should always be visible (not collapsed)
18
const MAIN_TYPES = ['user', 'response', 'error', 'rate_limit'];
19
20
-/**
21
- * Check if a response is from the main agent (A0)
22
- * Subordinate agents (A1, A2, ...) responses should be treated as process steps
23
- */
24
-function isMainAgentResponse(heading) {
25
- if (!heading) return true; // Default to main agent
26
- // Check for subordinate agent patterns like "A1:", "A2:", etc.
27
- const match = heading.match(/\bA(\d+):/);
28
- if (!match) return true; // No agent marker = main agent
29
- return match[1] === "0"; // Only A0 is the main agent
30
-}
31
-
32
-export function setMessage(id, type, heading, content, temp, kvps = null, timestamp = null, durationMs = null, tokensIn = 0, tokensOut = 0) {
20
+export function setMessage(id, type, heading, content, temp, kvps = null, timestamp = null, durationMs = null, tokensIn = 0, tokensOut = 0, agentNumber = 0) {
21
// Check if this is a process type message
22
const isProcessType = PROCESS_TYPES.includes(type);
23
const isMainType = MAIN_TYPES.includes(type);
@@ -64,7 +52,8 @@ export function setMessage(id, type, heading, content, temp, kvps = null, timest
52
}
53
54
// For subordinate agent responses (A1, A2, ...), treat as a process step instead of main response
67
- if (type === "response" && !isMainAgentResponse(heading)) {
55
+ // agentNumber: 0 = main agent, 1+ = subordinate agents
56
+ if (type === "response" && agentNumber !== 0) {
57
if (processStepElement) {
58
updateProcessStep(processStepElement, id, "agent", heading, content, kvps, durationMs, tokensIn, tokensOut);
59
return processStepElement;
@@ -1118,8 +1107,11 @@ function createProcessGroup(id) {
1107
group.classList.add("process-group");
1108
group.setAttribute("data-group-id", groupId);
1109
1121
- // Default to collapsed state - don't add 'expanded' class
1122
- // (Users can expand manually by clicking)
1110
+ // Check initial expansion state from store (respects user preference)
1111
+ const initiallyExpanded = processGroupStore.isGroupExpanded(groupId);
1112
+ if (initiallyExpanded) {
1113
+ group.classList.add('expanded');
1114
+ }
1115
1116
// Create header
1117
const header = document.createElement("div");
@@ -1724,7 +1716,7 @@ function markProcessGroupComplete(group, responseTitle) {
1716
const statusEl = group.querySelector(".group-status");
1717
if (statusEl) {
1718
statusEl.innerHTML = '<span class="badge-icon material-symbols-outlined">check_circle</span>END';
1727
- statusEl.className = "status-badge status-response group-status"; // No status-active
1719
+ statusEl.className = "status-badge status-end group-status"; // No status-active
1720
}
1721
1722
// Remove status-active from all step badges (stop spinners)