tools and skills, etc in the containers
This commit is contained in:
@@ -4,6 +4,30 @@ import rehypeRaw from 'rehype-raw';
|
||||
import type { ChatMessage } from '../types';
|
||||
import { ToolActivity } from './ToolActivity';
|
||||
import { QuestionActivity } from './QuestionActivity';
|
||||
import { getRawUrl } from '../../FileViewer/file-types';
|
||||
|
||||
// Matches absolute image file paths, e.g. /home/user/pic.png or /tmp/photo.jpg
|
||||
const IMAGE_PATH_RE = /(\/(?:home\/[^/\s]+\/)?[^\s`"'<>\n\r[\]()]+\.(?:png|jpg|jpeg|gif|webp|svg|bmp|ico))/gi;
|
||||
|
||||
function pathToImageUrl(filePath: string): string {
|
||||
// Strip /home/{username} prefix — the file browser root=home serves from the user's home dir
|
||||
const relative = filePath.replace(/^\/home\/[^/]+/, '') || '/';
|
||||
return getRawUrl(relative, 'home');
|
||||
}
|
||||
|
||||
function injectImages(text: string): string {
|
||||
// Split on fenced code blocks and inline code so we don't touch paths inside backticks
|
||||
const parts = text.split(/(```[\s\S]*?```|`[^`\n]+`)/g);
|
||||
return parts
|
||||
.map((part, i) => {
|
||||
if (i % 2 === 1) return part; // inside code — leave untouched
|
||||
return part.replace(IMAGE_PATH_RE, (match) => {
|
||||
const filename = match.split('/').pop() ?? 'image';
|
||||
return `})`;
|
||||
});
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
|
||||
const FRONTMATTER_RE = /^<frontmatter>([\s\S]*?)<\/frontmatter>\s*/;
|
||||
|
||||
@@ -56,7 +80,7 @@ export const MessageBubble = ({ message, onAnswer }: MessageBubbleProps) => {
|
||||
<div className="max-w-[85%] rounded-2xl rounded-tl-sm bg-muted/50 border border-border/50 px-4 py-2.5">
|
||||
<div className="chat-md">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
|
||||
{message.text}
|
||||
{injectImages(message.text)}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,7 +124,7 @@ export const StreamingBubble = ({ text }: StreamingBubbleProps) => {
|
||||
<div className="max-w-[85%] rounded-2xl rounded-tl-sm bg-muted/50 border border-border/50 px-4 py-2.5">
|
||||
<div className="chat-md">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
|
||||
{text}
|
||||
{injectImages(text)}
|
||||
</ReactMarkdown>
|
||||
<span className="inline-block w-2 h-4 bg-duck-teal/60 animate-pulse ml-0.5 align-middle" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user