Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/20250215-AddingThinkFence #320

Merged
merged 5 commits into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion src/commands/scm/generateComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export default class GenerateCommentsCommand implements Command {

const diff = await getGitDifferences(gitService)
if (diff) {
const comments = await getComments(diff)
const s = await getComments(diff)
const comments = s.replace(/<\s*think\s*>(.*?)<\/think>/gs, '').trim()

createDebugNotification(
`GitService: diff(${diff.length}) ~ comments(${comments.length})`
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ export const onDidSaveMessages = async (
//Add summary to conversation
if (conversation.chatMessages.length % SUMMARY_THRESHOLD == 0) {
//Deep clone for summary
const summary = JSON.parse(JSON.stringify(conversation)) as IConversation
summary.embeddingId = undefined // ignore embedding for summary
const tempConversation = JSON.parse(
JSON.stringify(conversation)
) as IConversation
tempConversation.embeddingId = undefined // ignore embedding for summary
const chatCompletion: IChatCompletion = {
content: `Please summarise the content above. The summary must be less than ${SUMMARY_MAX_LENGTH} words. Only provide the facts within the content.`,
author: 'summary',
Expand All @@ -39,13 +41,16 @@ export const onDidSaveMessages = async (
promptTokens: 0,
totalTokens: 0,
}
summary.chatMessages.push(chatCompletion)
tempConversation.chatMessages.push(chatCompletion)

function messageCallback(_type: string, data: IChatCompletion): void {
if (!conversation) return

conversation.summary = data.content
.replace(/<\s*think\s*>(.*?)<\/think>/gs, '')
.trim()
}
createChatCompletionMessage(summary, cfg, messageCallback)
createChatCompletionMessage(tempConversation, cfg, messageCallback)
}
} catch (error) {
window.showErrorMessage(error as string)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FC, useState } from 'react'
import { Button } from '@fluentui/react-components'
import { CommentMultipleLinkRegular } from '@fluentui/react-icons'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

const ThinkSection: FC<{ content: string }> = ({ content }) => {
const [isOpen, setIsOpen] = useState(false)

return (
<div>
<Button
appearance="subtle"
size="small"
icon={<CommentMultipleLinkRegular />}
onClick={() => setIsOpen(!isOpen)}
>
{isOpen ? 'Collapse' : 'Expand'} reasoning
</Button>
{isOpen && (
<div>
<ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
</div>
)}
</div>
)
}

export default ThinkSection
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as CodeBlockMatched } from './CodeBlockMatched'
export { default as CodeBlockUnmatched } from './CodeBlockUnmatched'
export { default as MessageItemTokenInfo } from './MessageItemTokenInfo'
export { default as MessageItemToolbar } from './MessageItemToolbar'
export { default as ThinkSection } from './ThinkSection'
26 changes: 23 additions & 3 deletions webview/message/src/components/MessageItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CodeBlockMatched,
CodeBlockUnmatched,
MessageItemToolbar,
ThinkSection,
} from './components'

export const MessageItem: FC<IChatCompletionProps> = ({ chatCompletion }) => {
Expand All @@ -28,6 +29,24 @@ export const MessageItem: FC<IChatCompletionProps> = ({ chatCompletion }) => {
: configuration.assistantColor,
}

// Function to extract <think> content from chatCompletion.content
const extractThinkSections = (content: string) => {
const thinkSections: string[] = []
const regex = /<think>([\s\S]*?)<\/think>/g
let match

while ((match = regex.exec(content)) !== null) {
thinkSections.push(match[1])
}

const cleanedContent = content.replace(/<think>[\s\S]*?<\/think>/g, '')
return { cleanedContent, thinkSections }
}

const { cleanedContent, thinkSections } = extractThinkSections(
chatCompletion.content
)

return (
<div
className={MessageItemStyles.messageItem}
Expand All @@ -39,7 +58,6 @@ export const MessageItem: FC<IChatCompletionProps> = ({ chatCompletion }) => {
>
<div className={MessageItemStyles.messageWrapper}>
<div className={MessageItemStyles.messageHeader}>
{/* Conditionally render author if the message is not from the user */}
{chatCompletion.mine ? null : (
<span className={MessageItemStyles.author}>
{chatCompletion.author}
Expand All @@ -49,14 +67,13 @@ export const MessageItem: FC<IChatCompletionProps> = ({ chatCompletion }) => {
{' '}
Date: {chatCompletion.timestamp}
</span>
{/* Render MessageUtility component if totalTokens is greater than 0 */}
{chatCompletion.totalTokens > 0 && (
<MessageItemToolbar chatCompletion={chatCompletion} />
)}
</div>
</div>
<ReactMarkdown
children={chatCompletion.content.trim()}
children={cleanedContent.trim()}
remarkPlugins={[remarkGfm]}
components={{
code(props) {
Expand All @@ -73,6 +90,9 @@ export const MessageItem: FC<IChatCompletionProps> = ({ chatCompletion }) => {
},
}}
/>
{thinkSections.map((content, index) => (
<ThinkSection key={index} content={content} />
))}
</div>
)
}
Loading