Skip to content
Open
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Accordion,
AccordionItem,
AgentLoadingIcon,
Code,
Flex,
getLastStringChild,
Expand Down Expand Up @@ -92,15 +93,21 @@ export function SimpleToolCall({
const toolName = attributes?.tool?.name ?? ''
const args = attributes?.tool?.arguments
const kind = resolveToolCallKind(toolName, args)
const title = customTitle ?? toolCallDisplayTitle(kind, toolName, args)
const title =
customTitle ?? toolCallDisplayTitle(kind, toolName, args, isPending)
const subtitle = toolCallDisplaySubtitle(kind, toolName, args, content)
const label = customLabel ?? (
<ToolCallLineLabel
title={title}
subtitle={subtitle}
runtime={toolRuntime}
isPending={isPending}
leadingIcon={leadingIcon}
leadingIcon={
leadingIcon ??
(isPending && kind === 'subagent' ? (
<AgentLoadingIcon size={12} />
) : undefined)
}
/>
)
const accordionProps = {
Expand Down Expand Up @@ -474,7 +481,7 @@ const AccordionLabelSC = styled.span(({ theme }) => ({

const ToolCallLineSC = styled.span(({ theme }) => ({
display: 'flex',
alignItems: 'baseline',
alignItems: 'center',
gap: theme.spacing.xsmall,
minWidth: 0,
maxWidth: '100%',
Expand Down
15 changes: 14 additions & 1 deletion js/console/src/components/ai/chatbot/toolCallDisplay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ describe('toolCallDisplayTitle', () => {
expect(toolCallDisplayTitle('subagent', 'workbench_subagent')).toBe(
'subagent'
)
expect(
toolCallDisplayTitle('subagent', 'workbench_subagent', {
subagent: 'coding',
})
).toBe('subagent')
expect(
toolCallDisplayTitle(
'subagent',
'workbench_subagent',
{ subagent: 'coding' },
true
)
).toBe('Coding subagent')
expect(toolCallDisplayTitle('read', 'Read')).toBe('read')
expect(toolCallDisplayTitle('python_sandbox', 'python_sandbox')).toBe(
'python sandbox'
Expand All @@ -55,7 +68,7 @@ describe('toolCallDisplaySubtitle', () => {
subagent: 'infrastructure',
prompt: 'Find CrashLoopBackOff pods in production',
})
).toBe('Infrastructure · Find CrashLoopBackOff pods in production')
).toBe('Find CrashLoopBackOff pods in production')
})

it('prefers path and query over the raw tool name', () => {
Expand Down
14 changes: 9 additions & 5 deletions js/console/src/components/ai/chatbot/toolCallDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ export function toolCallGroupHeader(
export function toolCallDisplayTitle(
kind: ToolCallKind,
toolName: string,
args?: ToolArguments
args?: ToolArguments,
isPending?: boolean
): string {
switch (kind) {
case 'command_execution':
Expand All @@ -211,7 +212,7 @@ export function toolCallDisplayTitle(
case 'grep':
return 'grep'
case 'subagent':
return 'subagent'
return isPending ? formatSubagentTitle(args) : 'subagent'
case 'subagent_result':
return 'result'
case 'enable_tools':
Expand Down Expand Up @@ -292,10 +293,13 @@ export function getSubagentPrompt(args?: ToolArguments): string {
return typeof args.prompt === 'string' ? args.prompt : ''
}

function formatSubagentSubtitle(args?: ToolArguments): string {
export function formatSubagentTitle(args?: ToolArguments): string {
const role = startCase(getSubagentRole(args).replace(/[_-]+/g, ' '))
const prompt = getSubagentPrompt(args)
return [role, prompt].filter(Boolean).join(' · ')
return role ? `${role} subagent` : 'Subagent'
}

function formatSubagentSubtitle(args?: ToolArguments): string {
return getSubagentPrompt(args)
}

export function getCommand(toolName: string, args?: ToolArguments): string {
Expand Down
14 changes: 3 additions & 11 deletions js/console/src/components/utils/AILoadingText.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Flex, FlexProps, LoaderIcon } from '@pluralsh/design-system'
import { AgentLoadingIcon, Flex, FlexProps } from '@pluralsh/design-system'
import { Body2P } from 'components/utils/typography/Text'
import {
useWorkbenchJobActivityWhimseyTextQuery,
Expand Down Expand Up @@ -42,17 +42,9 @@ export function AILoadingText({
gap="xsmall"
{...props}
>
<LoaderIcon
<AgentLoadingIcon
color="icon-xlight"
size={16}
css={{
animation: 'workbench-loader-pulse 1.2s ease-in-out infinite',
'@keyframes workbench-loader-pulse': {
'0%': { opacity: 1, transform: 'scale(1) rotate(0deg)' },
'50%': { opacity: 0.5, transform: 'scale(1.18) rotate(90deg)' },
'100%': { opacity: 1, transform: 'scale(1) rotate(180deg)' },
},
}}
size={12}
/>
<EaseIn currentKey={whimseyText}>
<Body2P
Expand Down
3 changes: 3 additions & 0 deletions js/console/src/components/utils/typography/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,8 @@ const sharedTextStyles = ({
backgroundClip: 'text',
color: 'transparent',
animation: `shimmer-text ${SHIMMER_DURATION} linear infinite`,
'@media (prefers-reduced-motion: reduce)': {
animationDuration: '6s',
},
}),
})
Loading
Loading