Skip to content

Commit e4ad8e7

Browse files
committed
fix(chat): keep an activity's completed title off runs while it still waits on the user
Every run of a main-lane activity segment received the segment-wide activity, including its completedTitle. A finished multi-call run before a pending approval or terminal handoff (which splits the segment into runs) therefore read the past-tense completed title while the activity was still unfinished. Runs now receive the completed title only once every call in the segment has finished; until then they keep the activity's in-progress title and summarize their own calls. Fully finished activities render exactly as before.
1 parent 7107ca4 commit e4ad8e7

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

‎apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group.test.ts‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,50 @@ describe('AgentGroup inline main activity', () => {
481481
expect(container.textContent).not.toContain('Built API')
482482
})
483483

484+
function renderBuildActivity(lastStatus: ToolCallStatus) {
485+
const read = (id: string): AgentGroupItem => ({
486+
type: 'tool',
487+
data: { id, toolName: 'read', displayTitle: `Read ${id}`, status: 'success' },
488+
})
489+
act(() =>
490+
root.render(
491+
createElement(AgentGroupView, {
492+
agentName: 'mothership',
493+
agentLabel: 'Sim',
494+
activity: { id: 'build', title: 'Building API', completedTitle: 'Built API' },
495+
items: [
496+
read('config'),
497+
read('schema'),
498+
{
499+
type: 'tool',
500+
data: {
501+
id: 'create',
502+
toolName: 'create',
503+
displayTitle: 'Create route',
504+
status: lastStatus,
505+
},
506+
},
507+
],
508+
ToolCallComponent: ({ displayTitle, renderStatus }: ToolCallItemProps) =>
509+
renderStatus
510+
? renderStatus({ label: displayTitle, activeLabel: displayTitle, isActive: false })
511+
: createElement('div', { 'data-pending': 'true' }, displayTitle),
512+
})
513+
)
514+
)
515+
}
516+
517+
it('keeps the completed title off a finished multi-call run while its activity awaits approval', () => {
518+
renderBuildActivity('awaiting_approval')
519+
expect(container.textContent).not.toContain('Built API')
520+
expect(container.querySelector('[data-pending]')?.textContent).toBe('Create route')
521+
})
522+
523+
it('shows the completed title on a multi-call run once its activity has finished', () => {
524+
renderBuildActivity('success')
525+
expect(container.querySelector('[role="status"]')?.textContent).toBe('Built API')
526+
})
527+
484528
it.each([
485529
[
486530
'approval',

‎apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/main-agent-activity.tsx‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { type ComponentType, Fragment, type ReactNode } from 'react'
2+
import { omit } from '@sim/utils/object'
23
import type { ToolActivity } from '@/lib/mothership/generated/protocol'
4+
import { isAgentGroupResolved } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-content'
35
import type { AgentGroupItem } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view'
46
import { splitMainLane } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/lane-activity'
57
import { ToolActivityGroup } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group'
@@ -18,6 +20,9 @@ interface MainAgentActivityProps {
1820
/**
1921
* The main lane's runs and interaction cards;
2022
* which run is live is decided by the lane, never by a run's position.
23+
* A run reads the activity's completed title only once every call of the
24+
* activity has finished, so a finished run before a pending approval or
25+
* handoff never claims the whole activity is done.
2126
*/
2227
export function MainAgentActivity({
2328
activity: groupActivity,
@@ -28,6 +33,10 @@ export function MainAgentActivity({
2833
liveToolId,
2934
}: MainAgentActivityProps) {
3035
const entries = splitMainLane(items)
36+
const runActivity =
37+
groupActivity && !isAgentGroupResolved(items)
38+
? omit(groupActivity, ['completedTitle'])
39+
: groupActivity
3140
const activity = entries.map((entry) => {
3241
if (entry.type === 'item') {
3342
return (
@@ -41,7 +50,7 @@ export function MainAgentActivity({
4150
<ToolActivityGroup
4251
key={tools[0].id}
4352
tools={tools}
44-
activity={groupActivity}
53+
activity={runActivity}
4554
isLive={tools.some((tool) => tool.id === liveToolId)}
4655
ToolCallComponent={ToolCallComponent}
4756
autoScrollActivity={autoScrollActivity}

0 commit comments

Comments
 (0)