Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ class MockAgentService {
public stepsSubject = new BehaviorSubject<ReActStep[]>([]);
public headIdSubject = new BehaviorSubject<string | null>(null);
public workflowSubject = new BehaviorSubject<Workflow | null>(null);
public scrollToStepSubject = new Subject<{ agentId: string; messageId: string; stepId: number }>();
public scrollToStep$ = this.scrollToStepSubject.asObservable();

public ensureWorkflowPolling = vi.fn();
public getAgentState = vi.fn((): Observable<AgentState> => of(this.stateSubject.getValue()));
Expand Down Expand Up @@ -722,33 +720,6 @@ describe("AgentChatComponent", () => {
});
});

describe("scroll-to-step requests", () => {
it("scrolls to and highlights the requested step of this agent", () => {
createComponent();
const s0 = makeStep({ messageId: "m1", stepId: 0 });
const s1 = makeStep({ messageId: "m1", stepId: 1 });
agentService.stepsSubject.next([s0, s1]);
fixture.detectChanges();
agentService.setHoveredMessage.mockClear();

agentService.scrollToStepSubject.next({ agentId: AGENT_ID, messageId: "m1", stepId: 0 });

expect(scrollIntoViewMock).toHaveBeenCalledWith({ behavior: "smooth", block: "center" });
expect(component.hoveredMessageIndex).toBe(0);
expect(agentService.setHoveredMessage).toHaveBeenCalledWith(AGENT_ID, s0);
});

it("ignores scroll requests addressed to other agents", () => {
createComponent();
agentService.stepsSubject.next([makeStep()]);
fixture.detectChanges();

agentService.scrollToStepSubject.next({ agentId: "someone-else", messageId: "m1", stepId: 0 });

expect(scrollIntoViewMock).not.toHaveBeenCalled();
});
});

describe("template rendering", () => {
it("renders user and agent message bubbles with roles, content and tool summary", async () => {
createComponent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,6 @@ export class AgentChatComponent implements OnInit, AfterViewChecked, OnDestroy,
if (this.isActive) {
this.startWorkflowSubscription();
}

// Subscribe to scroll-to-step requests
this.agentService.scrollToStep$.pipe(untilDestroyed(this)).subscribe(({ agentId, messageId, stepId }) => {
if (agentId === this.agentInfo.id) {
this.scrollToStep(messageId, stepId);
}
});
}

ngOnChanges(changes: SimpleChanges): void {
Expand Down Expand Up @@ -741,18 +734,4 @@ export class AgentChatComponent implements OnInit, AfterViewChecked, OnDestroy,
error: () => {},
});
}

/**
* Scroll to a specific step in the chat by messageId and stepId.
*/
private scrollToStep(messageId: string, stepId: number): void {
// Find the step index in visibleSteps
const stepIndex = this.visibleSteps.findIndex(step => step.messageId === messageId && step.stepId === stepId);

if (stepIndex >= 0) {
this.scrollToMessage(stepIndex);
// Highlight the message briefly
this.setHoveredMessage(stepIndex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -702,9 +702,6 @@ describe("AgentPanelComponent", () => {
* children resolve the same AgentService token.
*/
class FullMockAgentService extends MockAgentService {
public scrollToStepSubject = new Subject<{ agentId: string; messageId: string; stepId: number }>();
public scrollToStep$ = this.scrollToStepSubject.asObservable();

// agent-chat
public ensureWorkflowPolling = vi.fn();
public getAgentState = vi.fn((): Observable<AgentState> => of(AgentState.AVAILABLE));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1223,15 +1223,6 @@ describe("AgentService", () => {
expect(seen).toEqual([true, false]);
expect(service.getShowPortShapes()).toBe(false);
});

it("requestScrollToStep broadcasts the scroll target", () => {
let target: { agentId: string; messageId: string; stepId: number } | undefined;
service.scrollToStep$.subscribe(t => (target = t));

service.requestScrollToStep("agent-1", "m1", 4);

expect(target).toEqual({ agentId: "agent-1", messageId: "m1", stepId: 4 });
});
});

// ---------------------------------------------------------------------------
Expand Down
13 changes: 1 addition & 12 deletions frontend/src/app/workspace/service/agent/agent.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,13 @@ export class AgentService {
private modelTypes$: Observable<ModelType[]> | null = null;

// ============================================================================
// Canvas annotation state (port shapes, step badges, scroll-to-step)
// Canvas annotation state (port shapes, step badges)
// ============================================================================

/** Whether to show output port shapes (rows, columns) on operators */
private showPortShapesSubject = new BehaviorSubject<boolean>(true);
public showPortShapes$ = this.showPortShapesSubject.asObservable();

/** Subject emitting scroll-to-step requests */
private scrollToStepSubject = new Subject<{ agentId: string; messageId: string; stepId: number }>();
public scrollToStep$ = this.scrollToStepSubject.asObservable();

constructor(
private http: HttpClient,
private notificationService: NotificationService,
Expand Down Expand Up @@ -1224,13 +1220,6 @@ export class AgentService {
return this.showPortShapesSubject.getValue();
}

/**
* Request scrolling to a specific step in the agent chat.
*/
public requestScrollToStep(agentId: string, messageId: string, stepId: number): void {
this.scrollToStepSubject.next({ agentId, messageId, stepId });
}

// ============================================================================
// Operator Result Annotation Methods
// ============================================================================
Expand Down
Loading