diff --git a/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.scss b/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.scss index 2738c91f7..2be2b310a 100644 --- a/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.scss +++ b/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.scss @@ -176,6 +176,14 @@ font-size: 11px; } +.th-create-panel__tool-tooltip { + .bitfun-tooltip__content { + width: max-content; + max-width: min(520px, calc(100vw - 32px)); + white-space: pre-wrap; + } +} + @container (max-width: 480px) { .th__list-body { padding: $size-gap-4; diff --git a/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.tsx b/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.tsx index f679f7df3..8a90f3499 100644 --- a/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.tsx +++ b/src/web-ui/src/app/scenes/agents/components/CreateAgentPage.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect, useCallback } from 'react'; import { ArrowLeft } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { Input, Textarea, Switch, Button } from '@/component-library'; +import { Input, Textarea, Switch, Button, Tooltip } from '@/component-library'; import { SubagentAPI } from '@/infrastructure/api/service-api/SubagentAPI'; import type { SubagentLevel } from '@/infrastructure/api/service-api/SubagentAPI'; import { toolAPI } from '@/infrastructure/api/service-api/ToolAPI'; @@ -48,6 +48,7 @@ const CreateAgentPage: React.FC = () => { if (!name) return null; return { name, + description: typeof tool?.description === 'string' ? tool.description : '', isReadonly: Boolean(tool?.is_readonly), }; }) @@ -329,16 +330,28 @@ const CreateAgentPage: React.FC = () => {
- {selectableTools.map((tool) => ( - - ))} + {selectableTools.map((tool) => { + const tooltipContent = tool.description.trim() || tool.name; + + return ( + + + + ); + })}
)} diff --git a/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.test.ts b/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.test.ts index 29307c7e9..c0d8acb42 100644 --- a/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.test.ts +++ b/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.test.ts @@ -7,13 +7,13 @@ import { } from './subagentEditorUtils'; const tools: SubagentEditorToolInfo[] = [ - { name: 'GetFileDiff', isReadonly: true }, - { name: 'Read', isReadonly: true }, - { name: 'Grep', isReadonly: true }, - { name: 'Glob', isReadonly: true }, - { name: 'LS', isReadonly: true }, - { name: 'Write', isReadonly: false }, - { name: 'Bash', isReadonly: false }, + { name: 'GetFileDiff', description: 'Show file changes.', isReadonly: true }, + { name: 'Read', description: 'Read file contents.', isReadonly: true }, + { name: 'Grep', description: 'Search file contents.', isReadonly: true }, + { name: 'Glob', description: 'Find files by pattern.', isReadonly: true }, + { name: 'LS', description: 'List directory contents.', isReadonly: true }, + { name: 'Write', description: 'Write file contents.', isReadonly: false }, + { name: 'Bash', description: 'Run shell commands.', isReadonly: false }, ]; describe('subagentEditorUtils', () => { diff --git a/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.ts b/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.ts index 07c906d69..1d57a3041 100644 --- a/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.ts +++ b/src/web-ui/src/app/scenes/agents/components/subagentEditorUtils.ts @@ -1,5 +1,6 @@ export interface SubagentEditorToolInfo { name: string; + description: string; isReadonly: boolean; } diff --git a/src/web-ui/src/component-library/components/Tooltip/Tooltip.scss b/src/web-ui/src/component-library/components/Tooltip/Tooltip.scss index aa70e6e55..57e37767a 100644 --- a/src/web-ui/src/component-library/components/Tooltip/Tooltip.scss +++ b/src/web-ui/src/component-library/components/Tooltip/Tooltip.scss @@ -44,8 +44,24 @@ box-shadow: var(--shadow-sm); max-width: 280px; + max-height: min(320px, calc(100vh - 24px)); + overflow-y: auto; + overscroll-behavior: contain; word-wrap: break-word; user-select: text; + + &::-webkit-scrollbar { + width: 4px; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + + &::-webkit-scrollbar-thumb { + background: var(--border-medium); + border-radius: 2px; + } } &--top.bitfun-tooltip--visible { diff --git a/src/web-ui/src/component-library/components/Tooltip/Tooltip.tsx b/src/web-ui/src/component-library/components/Tooltip/Tooltip.tsx index ac5ed8f96..5d483db4e 100644 --- a/src/web-ui/src/component-library/components/Tooltip/Tooltip.tsx +++ b/src/web-ui/src/component-library/components/Tooltip/Tooltip.tsx @@ -4,6 +4,7 @@ import './Tooltip.scss'; export type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right'; const DEFAULT_TOOLTIP_DELAY = 450; +const INTERACTIVE_TOOLTIP_HIDE_DELAY = 400; export interface TooltipProps { content: React.ReactNode; @@ -255,7 +256,7 @@ export const Tooltip: React.FC = ({ hideTimeoutRef.current = setTimeout(() => { hideTimeoutRef.current = null; hideTooltip(); - }, 150); + }, INTERACTIVE_TOOLTIP_HIDE_DELAY); }, [hideTooltip, interactive]); const handleMouseMove = useCallback(