Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix lint
  • Loading branch information
Theodore Li committed Mar 13, 2026
commit 604fd9a590a32de94af75171c79b66bcd8e0b6a2
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,7 @@ export function ResourceContent({ workspaceId, resource, previewMode }: Resource

case 'workflow':
return (
<EmbeddedWorkflow
key={resource.id}
workspaceId={workspaceId}
workflowId={resource.id}
/>
<EmbeddedWorkflow key={resource.id} workspaceId={workspaceId} workflowId={resource.id} />
)

case 'knowledgebase':
Expand Down Expand Up @@ -240,8 +236,7 @@ function EmbeddedWorkflow({ workspaceId, workflowId }: EmbeddedWorkflowProps) {
const hydrationPhase = useWorkflowRegistry((state) => state.hydration.phase)
const hydrationWorkflowId = useWorkflowRegistry((state) => state.hydration.workflowId)
const isMetadataLoaded = hydrationPhase !== 'idle' && hydrationPhase !== 'metadata-loading'
const hasLoadError =
hydrationPhase === 'error' && hydrationWorkflowId === workflowId
const hasLoadError = hydrationPhase === 'error' && hydrationWorkflowId === workflowId

if (!isMetadataLoaded) return LOADING_SKELETON

Expand All @@ -250,7 +245,7 @@ function EmbeddedWorkflow({ workspaceId, workflowId }: EmbeddedWorkflowProps) {
<div className='flex h-full flex-col items-center justify-center gap-[12px]'>
<WorkflowX className='h-[32px] w-[32px] text-[var(--text-muted)]' />
<div className='flex flex-col items-center gap-[4px]'>
<h2 className='text-[20px] font-medium text-[var(--text-secondary)]'>
<h2 className='font-medium text-[20px] text-[var(--text-secondary)]'>
Workflow not found
</h2>
<p className='text-[13px] text-[var(--text-muted)]'>
Expand Down Expand Up @@ -285,7 +280,7 @@ function EmbeddedFile({ workspaceId, fileId, previewMode }: EmbeddedFileProps) {
<div className='flex h-full flex-col items-center justify-center gap-[12px]'>
<FileX className='h-[32px] w-[32px] text-[var(--text-muted)]' />
<div className='flex flex-col items-center gap-[4px]'>
<h2 className='text-[20px] font-medium text-[var(--text-secondary)]'>File not found</h2>
<h2 className='font-medium text-[20px] text-[var(--text-secondary)]'>File not found</h2>
<p className='text-[13px] text-[var(--text-muted)]'>
This file may have been deleted or moved
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,9 @@ function getContextIcon(ctx: ChatContext) {
switch (ctx.kind) {
case 'workflow':
case 'current_workflow':
return (
<WorkflowPillIcon
workflowId={ctx.workflowId}
className='mr-[4px] h-[10px] w-[10px]'
/>
)
return <WorkflowPillIcon workflowId={ctx.workflowId} className='mr-[4px] h-[10px] w-[10px]' />
case 'workflow_block':
return (
<WorkflowPillIcon
workflowId={ctx.workflowId}
className='mr-[4px] h-[10px] w-[10px]'
/>
)
return <WorkflowPillIcon workflowId={ctx.workflowId} className='mr-[4px] h-[10px] w-[10px]' />
case 'knowledge':
return <Database className='mr-[4px] h-[10px] w-[10px] text-[var(--text-icon)]' />
case 'templates':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,17 @@ type WindowWithSpeech = Window & {
}

import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ArrowUp, AtSign, ChevronRight, Folder, Loader2, Mic, Paperclip, Plus, X } from 'lucide-react'
import {
ArrowUp,
AtSign,
ChevronRight,
Folder,
Loader2,
Mic,
Paperclip,
Plus,
X,
} from 'lucide-react'
import { useParams } from 'next/navigation'
import { createPortal } from 'react-dom'
import {
Expand Down Expand Up @@ -66,7 +76,15 @@ import {
import { useSession } from '@/lib/auth/auth-client'
import { cn } from '@/lib/core/utils/cn'
import { CHAT_ACCEPT_ATTRIBUTE } from '@/lib/uploads/utils/validation'
import { ContextPills } from './components'
import {
type AvailableItem,
useAvailableResources,
} from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown'
import { getResourceConfig } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry'
import type {
MothershipResource,
MothershipResourceType,
} from '@/app/workspace/[workspaceId]/home/types'
import {
useCaretViewport,
useContextManagement,
Expand All @@ -78,17 +96,12 @@ import {
computeMentionHighlightRanges,
extractContextTokens,
} from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/utils'
import type { ChatContext } from '@/stores/panel'
import {
useAvailableResources,
type AvailableItem,
} from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/add-resource-dropdown'
import { getResourceConfig } from '@/app/workspace/[workspaceId]/home/components/mothership-view/components/resource-registry'
import type { MothershipResource, MothershipResourceType } from '@/app/workspace/[workspaceId]/home/types'
import { useFolders } from '@/hooks/queries/folders'
import { useFolderStore } from '@/stores/folders/store'
import type { FolderTreeNode } from '@/stores/folders/types'
import type { ChatContext } from '@/stores/panel'
import { useAnimatedPlaceholder } from '../../hooks'
import { ContextPills } from './components'

const TEXTAREA_BASE_CLASSES = cn(
'm-0 box-border h-auto min-h-[24px] w-full resize-none',
Expand Down Expand Up @@ -184,9 +197,7 @@ function ResourceMentionMenu({
)
}
// When no query, show all items flat
return availableResources.flatMap(({ type, items }) =>
items.map((item) => ({ type, item }))
)
return availableResources.flatMap(({ type, items }) => items.map((item) => ({ type, item })))
}, [availableResources, query])

// Reset active index when query changes
Expand Down Expand Up @@ -263,7 +274,9 @@ function ResourceMentionMenu({
onClick={() => handleSelect({ type, id: item.id, title: item.name })}
className={cn(
'flex cursor-pointer items-center gap-[8px] px-[8px] py-[6px] text-[13px]',
index === activeIndex ? 'bg-[var(--surface-active)]' : 'hover:bg-[var(--surface-active)]'
index === activeIndex
? 'bg-[var(--surface-active)]'
: 'hover:bg-[var(--surface-active)]'
)}
>
{config.renderDropdownItem({ item })}
Expand Down Expand Up @@ -292,7 +305,13 @@ interface ResourceTypeFolderProps {
onSelect: (resource: MothershipResource) => void
}

function ResourceTypeFolder({ type, items, config, workspaceId, onSelect }: ResourceTypeFolderProps) {
function ResourceTypeFolder({
type,
items,
config,
workspaceId,
onSelect,
}: ResourceTypeFolderProps) {
const [expanded, setExpanded] = useState(false)
const Icon = config.icon

Expand Down Expand Up @@ -578,7 +597,11 @@ export interface FileAttachmentForApi {

interface UserInputProps {
defaultValue?: string
onSubmit: (text: string, fileAttachments?: FileAttachmentForApi[], contexts?: ChatContext[]) => void
onSubmit: (
text: string,
fileAttachments?: FileAttachmentForApi[],
contexts?: ChatContext[]
) => void
isSending: boolean
onStopGeneration: () => void
isInitialView?: boolean
Expand Down Expand Up @@ -608,10 +631,13 @@ export function UserInput({
const animatedPlaceholder = useAnimatedPlaceholder(isInitialView)
const placeholder = isInitialView ? animatedPlaceholder : 'Send message to Sim'

const files = useFileAttachments({ userId: userId || session?.user?.id, disabled: false, isLoading: isSending })
const files = useFileAttachments({
userId: userId || session?.user?.id,
disabled: false,
isLoading: isSending,
})
const hasFiles = files.attachedFiles.some((f) => !f.uploading && f.key)


const contextManagement = useContextManagement({ message: value })

const handleContextAdd = useCallback(
Expand Down Expand Up @@ -741,10 +767,13 @@ export function UserInput({
}
}, [isInitialView, textareaRef])

const handleContainerClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
if ((e.target as HTMLElement).closest('button')) return
textareaRef.current?.focus()
}, [textareaRef])
const handleContainerClick = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
if ((e.target as HTMLElement).closest('button')) return
textareaRef.current?.focus()
},
[textareaRef]
)

const handleSubmit = useCallback(() => {
const fileAttachmentsForApi: FileAttachmentForApi[] = files.attachedFiles
Expand Down Expand Up @@ -898,7 +927,6 @@ export function UserInput({
[isInitialView]
)


const toggleListening = useCallback(() => {
if (isListening) {
recognitionRef.current?.stop()
Expand Down Expand Up @@ -1122,7 +1150,9 @@ export function UserInput({
onClose={() => {
mentionMenu.closeMentionMenu()
}}
query={mentionMenu.getActiveMentionQueryAtPosition(mentionMenu.getCaretPos())?.query ?? ''}
query={
mentionMenu.getActiveMentionQueryAtPosition(mentionMenu.getCaretPos())?.query ?? ''
}
/>,
document.body
)}
Expand Down Expand Up @@ -1243,7 +1273,6 @@ export function UserInput({
</div>
</div>
)}

</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use client'

import { cn } from '@/lib/core/utils/cn'
import type { ChatMessageContext } from '../types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import type { ChatMessageContext } from '../types'

interface UserMessageContentProps {
content: string
Expand Down Expand Up @@ -48,15 +47,10 @@ function MentionHighlight({ context, token }: { context: ChatMessageContext; tok
return null
})

const bgColor = workflowColor
? `${workflowColor}40`
: 'rgba(50, 189, 126, 0.4)'
const bgColor = workflowColor ? `${workflowColor}40` : 'rgba(50, 189, 126, 0.4)'

return (
<span
className='rounded-[4px] py-[1px] px-[2px]'
style={{ backgroundColor: bgColor }}
>
<span className='rounded-[4px] px-[2px] py-[1px]' style={{ backgroundColor: bgColor }}>
{token}
</span>
)
Expand Down
14 changes: 10 additions & 4 deletions apps/sim/app/workspace/[workspaceId]/home/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ import {
} from '@/lib/core/utils/browser-storage'
import { persistImportedWorkflow } from '@/lib/workflows/operations/import-export'
import { useChatHistory, useMarkTaskRead } from '@/hooks/queries/tasks'
import { MessageContent, MothershipView, TemplatePrompts, UserInput, UserMessageContent } from './components'
import type { FileAttachmentForApi } from './components/user-input/user-input'
import type { ChatContext } from '@/stores/panel'
import type { MothershipResource, MothershipResourceType } from './types'
import {
MessageContent,
MothershipView,
TemplatePrompts,
UserInput,
UserMessageContent,
} from './components'
import type { FileAttachmentForApi } from './components/user-input/user-input'
import { useAutoScroll, useChat } from './hooks'
import type { MothershipResource, MothershipResourceType } from './types'

const logger = createLogger('Home')

Expand Down Expand Up @@ -245,7 +251,7 @@ export function Home({ chatId }: HomeProps = {}) {
(context: ChatContext) => {
let resourceType: MothershipResourceType | null = null
let resourceId: string | null = null
let resourceTitle: string = context.label
const resourceTitle: string = context.label

switch (context.kind) {
case 'workflow':
Expand Down
15 changes: 12 additions & 3 deletions apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import {
taskKeys,
useChatHistory,
} from '@/hooks/queries/tasks'
import type { ChatContext } from '@/stores/panel'
import { getTopInsertionSortOrder } from '@/hooks/queries/utils/top-insertion-sort-order'
import { useExecutionStream } from '@/hooks/use-execution-stream'
import { useExecutionStore } from '@/stores/execution/store'
import { useFolderStore } from '@/stores/folders/store'
import type { ChatContext } from '@/stores/panel'
import { useTerminalConsoleStore } from '@/stores/terminal'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { invalidateResourceQueries } from '../components/mothership-view/components/resource-registry'
Expand All @@ -46,7 +46,11 @@ export interface UseChatReturn {
isSending: boolean
error: string | null
resolvedChatId: string | undefined
sendMessage: (message: string, fileAttachments?: FileAttachmentForApi[], contexts?: ChatContext[]) => Promise<void>
sendMessage: (
message: string,
fileAttachments?: FileAttachmentForApi[],
contexts?: ChatContext[]
) => Promise<void>
stopGeneration: () => Promise<void>
resources: MothershipResource[]
activeResourceId: string | null
Expand Down Expand Up @@ -580,7 +584,12 @@ export function useChat(
const resource = parsed.resource
if (resource?.type && resource?.id) {
removeResource(resource.type as MothershipResourceType, resource.id)
invalidateResourceQueries(queryClient, workspaceId, resource.type as MothershipResourceType, resource.id)
invalidateResourceQueries(
queryClient,
workspaceId,
resource.type as MothershipResourceType,
resource.id
)
onResourceEventRef.current?.()
}
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ export function KnowledgeBase({
<div className='flex h-full flex-col items-center justify-center gap-[12px]'>
<DatabaseX className='h-[32px] w-[32px] text-[var(--text-muted)]' />
<div className='flex flex-col items-center gap-[4px]'>
<h2 className='text-[20px] font-medium text-[var(--text-secondary)]'>
<h2 className='font-medium text-[20px] text-[var(--text-secondary)]'>
Knowledge base not found
</h2>
<p className='text-[13px] text-[var(--text-muted)]'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ export function Table({
<div className='flex h-full flex-col items-center justify-center gap-[12px]'>
<TableX className='h-[32px] w-[32px] text-[var(--text-muted)]' />
<div className='flex flex-col items-center gap-[4px]'>
<h2 className='text-[20px] font-medium text-[var(--text-secondary)]'>Table not found</h2>
<h2 className='font-medium text-[20px] text-[var(--text-secondary)]'>Table not found</h2>
<p className='text-[13px] text-[var(--text-muted)]'>
This table may have been deleted or moved
</p>
Expand Down
9 changes: 4 additions & 5 deletions apps/sim/lib/copilot/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ export function extractDeletedResourcesFromToolResult(
if (operation !== 'delete') return []
const kbId = (data.id as string) ?? (args.knowledgeBaseId as string)
if (kbId) {
return [{ type: 'knowledgebase', id: kbId, title: (data.name as string) || 'Knowledge Base' }]
return [
{ type: 'knowledgebase', id: kbId, title: (data.name as string) || 'Knowledge Base' },
]
}
return []
}
Expand Down Expand Up @@ -286,10 +288,7 @@ export async function persistChatResources(
/**
* Removes resources from a chat's JSONB resources column by type+id.
*/
export async function removeChatResources(
chatId: string,
toRemove: ChatResource[]
): Promise<void> {
export async function removeChatResources(chatId: string, toRemove: ChatResource[]): Promise<void> {
if (toRemove.length === 0) return

try {
Expand Down