Skip to content

Commit

Permalink
chore: reasoning block (#4551)
Browse files Browse the repository at this point in the history
* chore: reasoning text block

* chore: update interface support all theme

* chore: update failed test

* chore: update state collapsed based on message index

* fix: use reserve_id instead of message index

* chore: clean up

* chore: fix loading indicator

---------

Co-authored-by: Louis <[email protected]>
  • Loading branch information
urmauur and louis-menlo authored Feb 1, 2025
1 parent f2bb9c9 commit 043284f
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 62 deletions.
24 changes: 12 additions & 12 deletions extensions/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -509,61 +509,61 @@ __metadata:

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension":
version: 0.1.10
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=546b6d&locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=af6a7b&locator=%40janhq%2Fmonitoring-extension%40workspace%3Amonitoring-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/abb0aeb570396ef5d2fe482410a178f422ced7da132fa28f92b930eba191439a6a9b3567641c283eb6bf6413ace2950669393fc8f1e415d442e22d7107c23a44
checksum: 10c0/482f1f5363ca64f48a40c3d2937ac07dcf42a6d2dd6c82356359cec986e9312611f84ca8cdaed4ef338d978cd163909a2708d75f8e957aa51b09447aae83eca0
languageName: node
linkType: hard

Expand Down
8 changes: 7 additions & 1 deletion web/containers/Providers/ModelHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,13 @@ export default function ModelHandler() {
.catch(() => undefined)
if (updatedMessage) {
deleteMessage(message.id)
addNewMessage(updatedMessage)
addNewMessage({
...updatedMessage,
metadata: {
...updatedMessage.metadata,
reserve_id: message.id,
},
})
setTokenSpeed((prev) =>
prev ? { ...prev, message: updatedMessage.id } : undefined
)
Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"slate-react": "0.110.3",
"swr": "^2.2.5",
"tailwind-merge": "^2.0.0",
"tailwindcss": "3.3.5",
"tailwindcss": "3.4.17",
"ulidx": "^2.3.0",
"use-debounce": "^10.0.0",
"uuid": "^9.0.1",
Expand Down
7 changes: 6 additions & 1 deletion web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ const ChatBody = memo(
>
{items.map((virtualRow) => (
<div
key={messages[virtualRow.index]?.id}
key={
(messages[virtualRow.index]?.metadata
?.reserve_id as string) ??
messages[virtualRow.index]?.id ??
virtualRow.index
}
data-index={virtualRow.index}
ref={virtualizer.measureElement}
>
Expand Down
59 changes: 59 additions & 0 deletions web/screens/Thread/ThreadCenterPanel/TextMessage/ThinkingBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react'

import { atom, useAtom } from 'jotai'
import { ChevronDown, ChevronUp, Loader } from 'lucide-react'

interface Props {
text: string
status: string
id: string
}

const thinkingBlockStateAtom = atom<{ [id: string]: boolean }>({})

const ThinkingBlock = ({ id, text, status }: Props) => {
const [thinkingState, setThinkingState] = useAtom(thinkingBlockStateAtom)

const isExpanded = thinkingState[id] ?? false

const loading = !text.includes('</think>') && status === 'pending'

const handleClick = () => {
setThinkingState((prev) => ({ ...prev, [id]: !isExpanded }))
}

if (!text.replace(/<\/?think>/g, '').trim()) return null

return (
<div className="mx-auto w-full">
<div className="mb-4 rounded-lg border border-dashed border-[hsla(var(--app-border))] p-2">
<div
className="flex cursor-pointer items-center gap-3"
onClick={handleClick}
>
{loading && (
<Loader className="h-4 w-4 animate-spin text-[hsla(var(--primary-bg))]" />
)}
<button className="flex items-center gap-2 focus:outline-none">
{isExpanded ? (
<ChevronUp className="h-4 w-4" />
) : (
<ChevronDown className="h-4 w-4" />
)}
<span className="font-medium">
{loading ? 'Thinking...' : 'Thought'}
</span>
</button>
</div>

{isExpanded && (
<div className="mt-2 pl-6 text-[hsla(var(--text-secondary))]">
{text.replace(/<\/?think>/g, '').trim()}
</div>
)}
</div>
</div>
)
}

export default ThinkingBlock
25 changes: 24 additions & 1 deletion web/screens/Thread/ThreadCenterPanel/TextMessage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import MessageToolbar from '../MessageToolbar'
import DocMessage from './DocMessage'
import ImageMessage from './ImageMessage'
import { MarkdownTextMessage } from './MarkdownTextMessage'
import ThinkingBlock from './ThinkingBlock'

import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom'
import {
Expand All @@ -41,6 +42,21 @@ const MessageContainer: React.FC<
[props.content]
)

const { reasoningSegment, textSegment } = useMemo(() => {
const isThinking = text.includes('<think>') && !text.includes('</think>')
if (isThinking) return { reasoningSegment: text, textSegment: '' }

const match = text.match(/<think>([\s\S]*?)<\/think>/)
if (match?.index === undefined)
return { reasoningSegment: undefined, textSegment: text }

const splitIndex = match.index + match[0].length
return {
reasoningSegment: text.slice(0, splitIndex),
textSegment: text.slice(splitIndex),
}
}, [text])

const image = useMemo(
() =>
props.content.find((e) => e.type === ContentType.Image)?.image_url?.url,
Expand Down Expand Up @@ -144,9 +160,16 @@ const MessageContainer: React.FC<
)}
dir="ltr"
>
{reasoningSegment && (
<ThinkingBlock
id={(props.metadata?.reserve_id as string) ?? props.id}
text={reasoningSegment}
status={props.status}
/>
)}
<MarkdownTextMessage
id={props.id}
text={text}
text={textSegment}
isUser={isUser}
/>
</div>
Expand Down
5 changes: 5 additions & 0 deletions web/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
'slide-in': 'slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)',
'leave': 'leave 150ms ease-in forwards',
'bounce-right': 'bounce-right 3s infinite',
'spin': 'spin 2s linear infinite',
},
keyframes: {
'wave': {
Expand Down Expand Up @@ -47,6 +48,10 @@ module.exports = {
'40%': { transform: 'translateX(-8px)' },
'60%': { transform: 'translateX(-4px)' },
},
'spin': {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
},
extend: {
fontFamily: {
Expand Down
59 changes: 13 additions & 46 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,7 @@ __metadata:
slate-react: "npm:0.110.3"
swr: "npm:^2.2.5"
tailwind-merge: "npm:^2.0.0"
tailwindcss: "npm:3.3.5"
tailwindcss: "npm:3.4.17"
ts-jest: "npm:^29.2.5"
typescript: "npm:^5.3.3"
ulidx: "npm:^2.3.0"
Expand Down Expand Up @@ -6141,7 +6141,7 @@ __metadata:
languageName: node
linkType: hard

"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0":
"chokidar@npm:^3.6.0":
version: 3.6.0
resolution: "chokidar@npm:3.6.0"
dependencies:
Expand Down Expand Up @@ -8451,7 +8451,7 @@ __metadata:
languageName: node
linkType: hard

"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2":
"fast-glob@npm:^3.0.3, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2":
version: 3.3.2
resolution: "fast-glob@npm:3.3.2"
dependencies:
Expand Down Expand Up @@ -11483,7 +11483,7 @@ __metadata:
languageName: node
linkType: hard

"jiti@npm:^1.19.1, jiti@npm:^1.21.6":
"jiti@npm:^1.21.6":
version: 1.21.7
resolution: "jiti@npm:1.21.7"
bin:
Expand Down Expand Up @@ -11946,7 +11946,7 @@ __metadata:
languageName: node
linkType: hard

"lilconfig@npm:^2.0.3, lilconfig@npm:^2.0.5, lilconfig@npm:^2.1.0":
"lilconfig@npm:^2.0.3, lilconfig@npm:^2.0.5":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
checksum: 10c0/64645641aa8d274c99338e130554abd6a0190533c0d9eb2ce7ebfaf2e05c7d9961f3ffe2bfa39efd3b60c521ba3dd24fa236fe2775fc38501bf82bf49d4678b8
Expand Down Expand Up @@ -14609,7 +14609,7 @@ __metadata:
languageName: node
linkType: hard

"postcss-load-config@npm:^4.0.1, postcss-load-config@npm:^4.0.2":
"postcss-load-config@npm:^4.0.2":
version: 4.0.2
resolution: "postcss-load-config@npm:4.0.2"
dependencies:
Expand Down Expand Up @@ -14763,7 +14763,7 @@ __metadata:
languageName: node
linkType: hard

"postcss-nested@npm:^6.0.1, postcss-nested@npm:^6.2.0":
"postcss-nested@npm:^6.2.0":
version: 6.2.0
resolution: "postcss-nested@npm:6.2.0"
dependencies:
Expand Down Expand Up @@ -14908,7 +14908,7 @@ __metadata:
languageName: node
linkType: hard

"postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9, postcss-selector-parser@npm:^6.1.1, postcss-selector-parser@npm:^6.1.2":
"postcss-selector-parser@npm:^6.0.10, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9, postcss-selector-parser@npm:^6.1.1, postcss-selector-parser@npm:^6.1.2":
version: 6.1.2
resolution: "postcss-selector-parser@npm:6.1.2"
dependencies:
Expand Down Expand Up @@ -14983,7 +14983,7 @@ __metadata:
languageName: node
linkType: hard

"postcss@npm:^8.4.23, postcss@npm:^8.4.47":
"postcss@npm:^8.4.47":
version: 8.4.49
resolution: "postcss@npm:8.4.49"
dependencies:
Expand Down Expand Up @@ -15959,7 +15959,7 @@ __metadata:
languageName: node
linkType: hard

"resolve@npm:^1.1.7, resolve@npm:^1.11.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.2, resolve@npm:^1.22.4, resolve@npm:^1.22.8":
"resolve@npm:^1.1.7, resolve@npm:^1.11.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8":
version: 1.22.10
resolution: "resolve@npm:1.22.10"
dependencies:
Expand All @@ -15985,7 +15985,7 @@ __metadata:
languageName: node
linkType: hard

"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.11.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>":
"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.11.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>":
version: 1.22.10
resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin<compat/resolve>::version=1.22.10&hash=c3c19d"
dependencies:
Expand Down Expand Up @@ -17449,7 +17449,7 @@ __metadata:
languageName: node
linkType: hard

"sucrase@npm:^3.32.0, sucrase@npm:^3.35.0":
"sucrase@npm:^3.35.0":
version: 3.35.0
resolution: "sucrase@npm:3.35.0"
dependencies:
Expand Down Expand Up @@ -17561,40 +17561,7 @@ __metadata:
languageName: node
linkType: hard

"tailwindcss@npm:3.3.5":
version: 3.3.5
resolution: "tailwindcss@npm:3.3.5"
dependencies:
"@alloc/quick-lru": "npm:^5.2.0"
arg: "npm:^5.0.2"
chokidar: "npm:^3.5.3"
didyoumean: "npm:^1.2.2"
dlv: "npm:^1.1.3"
fast-glob: "npm:^3.3.0"
glob-parent: "npm:^6.0.2"
is-glob: "npm:^4.0.3"
jiti: "npm:^1.19.1"
lilconfig: "npm:^2.1.0"
micromatch: "npm:^4.0.5"
normalize-path: "npm:^3.0.0"
object-hash: "npm:^3.0.0"
picocolors: "npm:^1.0.0"
postcss: "npm:^8.4.23"
postcss-import: "npm:^15.1.0"
postcss-js: "npm:^4.0.1"
postcss-load-config: "npm:^4.0.1"
postcss-nested: "npm:^6.0.1"
postcss-selector-parser: "npm:^6.0.11"
resolve: "npm:^1.22.2"
sucrase: "npm:^3.32.0"
bin:
tailwind: lib/cli.js
tailwindcss: lib/cli.js
checksum: 10c0/a57c0a9cdba9db19097e34e25b7e4690fab43f31ba200afc3bb9635a03036ca93e9884a17b616fb8a2486d57d2ecc9a06862ce4685b3ace57f7a67436e7594a0
languageName: node
linkType: hard

"tailwindcss@npm:^3.4.1":
"tailwindcss@npm:3.4.17, tailwindcss@npm:^3.4.1":
version: 3.4.17
resolution: "tailwindcss@npm:3.4.17"
dependencies:
Expand Down

0 comments on commit 043284f

Please sign in to comment.