feat: show sub-workflow agents and lifecycle in the Activity panel

Deep agent resolution in the sidecar now walks sub-workflow nodes so
nested agents carry subworkflowNodeId and subworkflowName on activity
events. New subworkflow-started / subworkflow-completed activity types
let the frontend track sub-workflow lifecycle.

The Activity panel groups nested agents under collapsible sub-workflow
cards with status badges, accent-colored left borders, and smooth
expand/collapse transitions. Cards auto-expand when a sub-workflow
starts running. Workflows without sub-workflow nodes render identically
to before.

Extracted AgentRow, SubWorkflowGroup, and shared accent constants to
a new components/activity/ feature directory. Added
resolveWorkflowAgentHierarchy and buildGroupedActivityRows for
hierarchical activity grouping with dynamic fallback for unresolved
sub-workflow agents.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-04-08 18:57:23 +02:00
co-authored by Copilot
parent fa8f6ef4b3
commit c70a5c6612
24 changed files with 2063 additions and 240 deletions
+3 -1
View File
@@ -2004,7 +2004,7 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
const session = this.requireSession(workspace, sessionId);
const activityType = event.activityType;
let nextRun: SessionRunRecord | undefined;
if (activityType !== 'completed') {
if (activityType === 'thinking' || activityType === 'tool-calling' || activityType === 'handoff') {
nextRun = this.updateSessionRun(session, requestId, (run) =>
appendRunActivityEvent(run, {
activityType,
@@ -2032,6 +2032,8 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
activityType: event.activityType,
agentId: event.agentId,
agentName: event.agentName,
subworkflowNodeId: event.subworkflowNodeId,
subworkflowName: event.subworkflowName,
sourceAgentId: event.sourceAgentId,
sourceAgentName: event.sourceAgentName,
toolName: event.toolName,
+3 -1
View File
@@ -675,7 +675,7 @@ export class SessionTurnExecutor {
const session = this.requireSession(workspace, sessionId);
const activityType = event.activityType;
let nextRun: SessionRunRecord | undefined;
if (activityType !== 'completed') {
if (activityType === 'thinking' || activityType === 'tool-calling' || activityType === 'handoff') {
nextRun = this.updateSessionRun(session, requestId, (run) =>
appendRunActivityEvent(run, {
activityType,
@@ -703,6 +703,8 @@ export class SessionTurnExecutor {
activityType: event.activityType,
agentId: event.agentId,
agentName: event.agentName,
subworkflowNodeId: event.subworkflowNodeId,
subworkflowName: event.subworkflowName,
sourceAgentId: event.sourceAgentId,
sourceAgentName: event.sourceAgentName,
toolName: event.toolName,