(agent_id, session_key, row, now_ms)
| 130 | |
| 131 | |
| 132 | def build_task(agent_id, session_key, row, now_ms): |
| 133 | session_id = row.get('sessionId') or session_key |
| 134 | updated_at = row.get('updatedAt') or 0 |
| 135 | age_ms = max(0, now_ms - updated_at) if updated_at else 99 * 24 * 3600 * 1000 |
| 136 | aborted = bool(row.get('abortedLastRun')) |
| 137 | state = state_from_session(age_ms, aborted) |
| 138 | |
| 139 | official, org = detect_official(agent_id) |
| 140 | channel = row.get('lastChannel') or (row.get('origin') or {}).get('channel') or '-' |
| 141 | session_file = row.get('sessionFile', '') |
| 142 | |
| 143 | # 尝试从 activity 获取更有意义的当前状态描述 |
| 144 | latest_act = '等待指令' |
| 145 | acts = load_activity(session_file, limit=5) |
| 146 | |
| 147 | # If the absolute latest is a tool result, look for the preceding assistant thought |
| 148 | # because that explains *why* the tool was called. |
| 149 | if acts: |
| 150 | first_act = acts[0] |
| 151 | if first_act['kind'] == 'tool' and len(acts) > 1: |
| 152 | # Look for next assistant message (which is actually previous in time) |
| 153 | for next_act in acts[1:]: |
| 154 | if next_act['kind'] == 'assistant': |
| 155 | latest_act = f"正在执行: {next_act['text'][:80]}" |
| 156 | break |
| 157 | else: |
| 158 | latest_act = first_act['text'][:60] |
| 159 | elif first_act['kind'] == 'assistant': |
| 160 | latest_act = f"思考中: {first_act['text'][:80]}" |
| 161 | else: |
| 162 | latest_act = acts[0]['text'][:60] |
| 163 | |
| 164 | title_label = (row.get('origin') or {}).get('label') or session_key |
| 165 | # 清洗会话标题:agent:xxx:cron:uuid → 定时任务, agent:xxx:subagent:uuid → 子任务 |
| 166 | import re |
| 167 | if re.match(r'agent:\w+:cron:', title_label): |
| 168 | title = f"{org}定时任务" |
| 169 | elif re.match(r'agent:\w+:subagent:', title_label): |
| 170 | title = f"{org}子任务" |
| 171 | elif title_label == session_key or len(title_label) > 40: |
| 172 | title = f"{org}会话" |
| 173 | else: |
| 174 | title = f"{title_label}" |
| 175 | |
| 176 | return { |
| 177 | 'id': f"OC-{agent_id}-{str(session_id)[:8]}", |
| 178 | 'title': title, |
| 179 | 'official': official, |
| 180 | 'org': org, |
| 181 | 'state': state, |
| 182 | 'now': latest_act, |
| 183 | 'eta': ms_to_str(updated_at), |
| 184 | 'block': '上次运行中断' if aborted else '无', |
| 185 | 'output': session_file, |
| 186 | 'flow': { |
| 187 | 'draft': f"agent={agent_id}", |
| 188 | 'review': f"updatedAt={ms_to_str(updated_at)}", |
| 189 | 'dispatch': f"sessionKey={session_key}", |
no test coverage detected