Skip to content

Commit 7729655

Browse files
committed
Fix pill
1 parent c96731e commit 7729655

File tree

2 files changed

+56
-170
lines changed

2 files changed

+56
-170
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,60 @@
11
'use client'
22

3+
import { Plus } from 'lucide-react'
34
import { memo } from 'react'
45
import { cn } from '@/lib/utils'
56

67
interface ContextUsagePillProps {
78
percentage: number
89
className?: string
10+
onCreateNewChat?: () => void
911
}
1012

11-
export const ContextUsagePill = memo(({ percentage, className }: ContextUsagePillProps) => {
12-
// Don't render if invalid (but DO render if 0 or very small)
13-
if (percentage === null || percentage === undefined || Number.isNaN(percentage)) return null
13+
export const ContextUsagePill = memo(
14+
({ percentage, className, onCreateNewChat }: ContextUsagePillProps) => {
15+
// Don't render if invalid (but DO render if 0 or very small)
16+
if (percentage === null || percentage === undefined || Number.isNaN(percentage)) return null
1417

15-
// Determine color based on percentage (similar to Cursor IDE)
16-
const getColorClass = () => {
17-
if (percentage >= 90) return 'bg-red-500/10 text-red-600 dark:text-red-400'
18-
if (percentage >= 75) return 'bg-orange-500/10 text-orange-600 dark:text-orange-400'
19-
if (percentage >= 50) return 'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400'
20-
return 'bg-gray-500/10 text-gray-600 dark:text-gray-400'
21-
}
18+
const isHighUsage = percentage >= 75
19+
20+
// Determine color based on percentage (similar to Cursor IDE)
21+
const getColorClass = () => {
22+
if (percentage >= 90) return 'bg-red-500/10 text-red-600 dark:text-red-400'
23+
if (percentage >= 75) return 'bg-orange-500/10 text-orange-600 dark:text-orange-400'
24+
if (percentage >= 50) return 'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400'
25+
return 'bg-gray-500/10 text-gray-600 dark:text-gray-400'
26+
}
2227

23-
// Format: show 1 decimal for <1%, 0 decimals for >=1%
24-
const formattedPercentage = percentage < 1 ? percentage.toFixed(1) : percentage.toFixed(0)
25-
26-
return (
27-
<div
28-
className={cn(
29-
'inline-flex items-center justify-center rounded-full px-2 py-0.5 font-medium text-[11px] tabular-nums transition-colors',
30-
getColorClass(),
31-
className
32-
)}
33-
title={`Context: ${percentage.toFixed(2)}%`}
34-
>
35-
{formattedPercentage}%
36-
</div>
37-
)
38-
})
28+
// Format: show 1 decimal for <1%, 0 decimals for >=1%
29+
const formattedPercentage = percentage < 1 ? percentage.toFixed(1) : percentage.toFixed(0)
30+
31+
return (
32+
<div
33+
className={cn(
34+
'inline-flex items-center gap-1 rounded-full px-2 py-0.5 font-medium text-[11px] tabular-nums transition-colors',
35+
getColorClass(),
36+
isHighUsage && 'border border-red-500/50',
37+
className
38+
)}
39+
title={`Context used in this chat: ${percentage.toFixed(2)}%`}
40+
>
41+
<span>{formattedPercentage}%</span>
42+
{isHighUsage && onCreateNewChat && (
43+
<button
44+
onClick={(e) => {
45+
e.stopPropagation()
46+
onCreateNewChat()
47+
}}
48+
className="inline-flex items-center justify-center hover:opacity-70 transition-opacity"
49+
title="Recommended: Start a new chat for better quality"
50+
type="button"
51+
>
52+
<Plus className="h-3 w-3" />
53+
</button>
54+
)}
55+
</div>
56+
)
57+
}
58+
)
3959

4060
ContextUsagePill.displayName = 'ContextUsagePill'

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/user-input.tsx

Lines changed: 10 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -183,19 +183,10 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
183183
const [isLoadingLogs, setIsLoadingLogs] = useState(false)
184184

185185
const { data: session } = useSession()
186-
const { currentChat, workflowId, enabledModels, setEnabledModels, contextUsage } =
186+
const { currentChat, workflowId, enabledModels, setEnabledModels, contextUsage, createNewChat } =
187187
useCopilotStore()
188188
const params = useParams()
189189
const workspaceId = params.workspaceId as string
190-
// Track per-chat preference for auto-adding workflow context
191-
const [workflowAutoAddDisabledMap, setWorkflowAutoAddDisabledMap] = useState<
192-
Record<string, boolean>
193-
>({})
194-
// Also track for new chats (no ID yet)
195-
const [newChatWorkflowDisabled, setNewChatWorkflowDisabled] = useState(false)
196-
const workflowAutoAddDisabled = currentChat?.id
197-
? workflowAutoAddDisabledMap[currentChat.id] || false
198-
: newChatWorkflowDisabled
199190

200191
// Determine placeholder based on mode
201192
const effectivePlaceholder =
@@ -253,97 +244,6 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
253244
}
254245
}, [enabledModels, setEnabledModels])
255246

256-
// Track the last chat ID we've seen to detect chat changes
257-
const [lastChatId, setLastChatId] = useState<string | undefined>(undefined)
258-
// Track if we just sent a message to avoid re-adding context after submit
259-
const [justSentMessage, setJustSentMessage] = useState(false)
260-
261-
// Reset states when switching to a truly new chat
262-
useEffect(() => {
263-
const currentChatId = currentChat?.id
264-
265-
// Detect when we're switching to a different chat
266-
if (lastChatId !== currentChatId) {
267-
// If switching to a new chat (undefined ID) from a different state
268-
// reset the disabled flag so each new chat starts fresh
269-
if (!currentChatId && lastChatId !== undefined) {
270-
setNewChatWorkflowDisabled(false)
271-
}
272-
273-
// If a new chat just got an ID assigned, transfer the disabled state
274-
if (currentChatId && !lastChatId && newChatWorkflowDisabled) {
275-
setWorkflowAutoAddDisabledMap((prev) => ({
276-
...prev,
277-
[currentChatId]: true,
278-
}))
279-
// Keep newChatWorkflowDisabled as false for the next new chat
280-
setNewChatWorkflowDisabled(false)
281-
}
282-
283-
// Reset the "just sent" flag when switching chats
284-
setJustSentMessage(false)
285-
286-
setLastChatId(currentChatId)
287-
}
288-
}, [currentChat?.id, lastChatId, newChatWorkflowDisabled])
289-
290-
// Auto-add workflow context when message is empty and not disabled
291-
useEffect(() => {
292-
// Don't auto-add if disabled or no workflow
293-
if (!workflowId || workflowAutoAddDisabled) return
294-
295-
// Don't auto-add right after sending a message
296-
if (justSentMessage) return
297-
298-
// Only add when message is empty (new message being composed)
299-
if (message && message.trim().length > 0) return
300-
301-
// Check if current_workflow context already exists
302-
const hasCurrentWorkflowContext = selectedContexts.some(
303-
(ctx) => ctx.kind === 'current_workflow' && (ctx as any).workflowId === workflowId
304-
)
305-
if (hasCurrentWorkflowContext) {
306-
return
307-
}
308-
309-
const addWorkflowContext = async () => {
310-
// Double-check disabled state right before adding
311-
if (workflowAutoAddDisabled) return
312-
313-
// Get workflow name
314-
let workflowName = 'Current Workflow'
315-
316-
// Try loaded workflows first
317-
const existingWorkflow = workflows.find((w) => w.id === workflowId)
318-
if (existingWorkflow) {
319-
workflowName = existingWorkflow.name
320-
} else if (workflows.length === 0) {
321-
// If workflows not loaded yet, try to fetch this specific one
322-
try {
323-
const resp = await fetch(`/api/workflows/${workflowId}`)
324-
if (resp.ok) {
325-
const data = await resp.json()
326-
workflowName = data?.data?.name || 'Current Workflow'
327-
}
328-
} catch {}
329-
}
330-
331-
// Add current_workflow context using functional update to prevent duplicates
332-
setSelectedContexts((prev) => {
333-
const alreadyHasCurrentWorkflow = prev.some(
334-
(ctx) => ctx.kind === 'current_workflow' && (ctx as any).workflowId === workflowId
335-
)
336-
if (alreadyHasCurrentWorkflow) return prev
337-
338-
return [
339-
...prev,
340-
{ kind: 'current_workflow', workflowId, label: workflowName } as ChatContext,
341-
]
342-
})
343-
}
344-
345-
addWorkflowContext()
346-
}, [workflowId, workflowAutoAddDisabled, workflows.length, message, justSentMessage]) // Re-run when message changes
347247

348248
// Auto-resize textarea and toggle vertical scroll when exceeding max height
349249
useEffect(() => {
@@ -712,16 +612,8 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
712612
size: f.size,
713613
}))
714614

715-
// Build contexts to send: hide current_workflow in UI but always include it in payload
716-
const uiContexts = selectedContexts.filter((c) => (c as any).kind !== 'current_workflow')
717-
const finalContexts: any[] = [...uiContexts]
718-
719-
if (workflowId) {
720-
// Include current_workflow for the agent; label not shown in UI
721-
finalContexts.push({ kind: 'current_workflow', workflowId, label: 'Current Workflow' })
722-
}
723-
724-
onSubmit(trimmedMessage, fileAttachments, finalContexts as any)
615+
// Send only the explicitly selected contexts
616+
onSubmit(trimmedMessage, fileAttachments, selectedContexts as any)
725617

726618
// Clean up preview URLs before clearing
727619
attachedFiles.forEach((f) => {
@@ -738,17 +630,8 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
738630
}
739631
setAttachedFiles([])
740632

741-
// Clear @mention contexts after submission, but preserve current_workflow if not disabled
742-
setSelectedContexts((prev) => {
743-
// Keep current_workflow context if it's not disabled
744-
const currentWorkflowCtx = prev.find(
745-
(ctx) => ctx.kind === 'current_workflow' && !workflowAutoAddDisabled
746-
)
747-
return currentWorkflowCtx ? [currentWorkflowCtx] : []
748-
})
749-
750-
// Mark that we just sent a message to prevent auto-add
751-
setJustSentMessage(true)
633+
// Clear @mention contexts after submission
634+
setSelectedContexts([])
752635

753636
setOpenSubmenuFor(null)
754637
setShowMentionMenu(false)
@@ -1442,11 +1325,6 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
14421325
setInternalMessage(newValue)
14431326
}
14441327

1445-
// Reset the "just sent" flag when user starts typing
1446-
if (justSentMessage && newValue.length > 0) {
1447-
setJustSentMessage(false)
1448-
}
1449-
14501328
const caret = e.target.selectionStart ?? newValue.length
14511329
const active = getActiveMentionQueryAtPosition(caret, newValue)
14521330
if (active) {
@@ -1716,34 +1594,22 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
17161594
// Keep selected contexts in sync with inline @label tokens so deleting inline tokens updates pills
17171595
useEffect(() => {
17181596
if (!message) {
1719-
// When message is empty, preserve current_workflow if not disabled
1720-
// Clear other contexts
1721-
setSelectedContexts((prev) => {
1722-
const currentWorkflowCtx = prev.find(
1723-
(ctx) => ctx.kind === 'current_workflow' && !workflowAutoAddDisabled
1724-
)
1725-
return currentWorkflowCtx ? [currentWorkflowCtx] : []
1726-
})
1597+
// When message is empty, clear all contexts
1598+
setSelectedContexts([])
17271599
return
17281600
}
17291601
const presentLabels = new Set<string>()
17301602
const ranges = computeMentionRanges()
17311603
for (const r of ranges) presentLabels.add(r.label)
17321604
setSelectedContexts((prev) => {
1733-
// Keep contexts that are mentioned in text OR are current_workflow (unless disabled)
1605+
// Keep only contexts that are mentioned in text
17341606
const filteredContexts = prev.filter((c) => {
1735-
// Always preserve current_workflow context if it's not disabled
1736-
// It should only be removable via the X button
1737-
if (c.kind === 'current_workflow' && !workflowAutoAddDisabled) {
1738-
return true
1739-
}
1740-
// For other contexts, check if they're mentioned in text
17411607
return !!c.label && presentLabels.has(c.label!)
17421608
})
17431609

17441610
return filteredContexts
17451611
})
1746-
}, [message, workflowAutoAddDisabled])
1612+
}, [message])
17471613

17481614
// Manage aggregate mode and preloading when needed
17491615
useEffect(() => {
@@ -2064,7 +1930,7 @@ const UserInput = forwardRef<UserInputRef, UserInputProps>(
20641930
{/* Context Usage Pill - Top Right */}
20651931
{contextUsage && contextUsage.percentage > 0 && (
20661932
<div className='absolute top-2 right-2 z-10'>
2067-
<ContextUsagePill percentage={contextUsage.percentage} />
1933+
<ContextUsagePill percentage={contextUsage.percentage} onCreateNewChat={createNewChat} />
20681934
</div>
20691935
)}
20701936
{/* Attached Files Display with Thumbnails */}

0 commit comments

Comments
 (0)