Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import { useMemo, useState } from 'react'
|
|
import Markdown from 'react-markdown'
|
|
import { AgentIcon } from '../../../shared/icons/AgentIcon'
|
|
import { ChevronDownIcon } from '../../../shared/icons/ChevronDownIcon'
|
|
import { ChevronRightIcon } from '../../../shared/icons/ChevronRightIcon'
|
|
import { AgentAction } from '../../../shared/types/AgentAction'
|
|
import { ChatHistoryActionItem } from '../../../shared/types/ChatHistoryItem'
|
|
import { Streaming } from '../../../shared/types/Streaming'
|
|
import { useAgent } from '../../agent/TldrawAgentAppProvider'
|
|
import { ChatHistoryGroup } from './ChatHistoryGroup'
|
|
import { getActionInfo } from './getActionInfo'
|
|
|
|
export function ChatHistoryGroupWithoutDiff({ group }: { group: ChatHistoryGroup }) {
|
|
const agent = useAgent()
|
|
const { items } = group
|
|
|
|
const nonEmptyItems = useMemo(() => {
|
|
return items.filter((item) => {
|
|
const { description } = getActionInfo(item.action, agent)
|
|
return description !== null
|
|
})
|
|
}, [items, agent])
|
|
|
|
const [collapsed, setCollapsed] = useState(true)
|
|
|
|
const complete = useMemo(() => {
|
|
return items.every((item) => item.action.complete)
|
|
}, [items])
|
|
|
|
const summary = useMemo(() => {
|
|
const time = Math.floor(items.reduce((acc, item) => acc + item.action.time, 0) / 1000)
|
|
if (time === 0) return 'Thought for less than a second'
|
|
if (time === 1) return 'Thought for 1 second'
|
|
return `Thought for ${time} seconds`
|
|
}, [items])
|
|
|
|
if (nonEmptyItems.length === 0) {
|
|
return null
|
|
}
|
|
|
|
if (nonEmptyItems.length < 2) {
|
|
return (
|
|
<div className="chat-history-group">
|
|
{nonEmptyItems.map((item, i) => {
|
|
return <ChatHistoryItem item={item} key={'action-' + i} />
|
|
})}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const showContent = !collapsed || !complete
|
|
|
|
return (
|
|
<div className="chat-history-group">
|
|
{complete && (
|
|
<button onClick={() => setCollapsed((v) => !v)}>
|
|
<span>{showContent ? <ChevronDownIcon /> : <ChevronRightIcon />}</span>
|
|
{summary}
|
|
</button>
|
|
)}
|
|
{showContent && (
|
|
<div className="agent-actions-container">
|
|
{nonEmptyItems.map((item, i) => {
|
|
return <ChatHistoryItemExpanded action={item.action} key={'action-' + i} />
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function ChatHistoryItem({ item }: { item: ChatHistoryActionItem }) {
|
|
const agent = useAgent()
|
|
const { action } = item
|
|
const { description, summary } = getActionInfo(action, agent)
|
|
const collapsible = summary !== null
|
|
const [collapsed, setCollapsed] = useState(collapsible)
|
|
|
|
if (!description) return null
|
|
|
|
return (
|
|
<div className="agent-actions-container">
|
|
{action.complete && collapsible && (
|
|
<button onClick={() => setCollapsed((v) => !v)}>
|
|
<span>{collapsed ? <ChevronRightIcon /> : <ChevronDownIcon />}</span>
|
|
{summary}
|
|
</button>
|
|
)}
|
|
|
|
{(!collapsed || !action.complete) && <ChatHistoryItemExpanded action={action} />}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function ChatHistoryItemExpanded({ action }: { action: Streaming<AgentAction> }) {
|
|
const agent = useAgent()
|
|
const { icon, description } = getActionInfo(action, agent)
|
|
|
|
return (
|
|
<div className={`agent-action agent-action-type-${action._type}`}>
|
|
{icon && (
|
|
<span>
|
|
<AgentIcon type={icon} />
|
|
</span>
|
|
)}
|
|
<span className="agent-action-description">
|
|
<Markdown>{description}</Markdown>
|
|
</span>
|
|
</div>
|
|
)
|
|
}
|