Skip to content

Commit

Permalink
premature parsing of json in a blob
Browse files Browse the repository at this point in the history
  • Loading branch information
kfarr committed Dec 31, 2024
1 parent 558b7bd commit a2cc5fc
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 2 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-json-pretty": "^2.2.0",
"react-select": "^5.4.0",
"stripe": "^15.8.0",
"three": "0.145.0",
Expand Down Expand Up @@ -123,4 +124,4 @@
"prettier --write"
]
}
}
}
68 changes: 67 additions & 1 deletion src/editor/components/widgets/AIChatPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,71 @@ import { useState, useEffect, useRef } from 'react';
import { vertexAI } from '../../services/firebase.js';
import { getGenerativeModel } from 'firebase/vertexai';
import Collapsible from '../Collapsible';
import JSONPretty from 'react-json-pretty';
import 'react-json-pretty/themes/monikai.css';

// Helper component to render message content with JSON formatting
const MessageContent = ({ content }) => {
const formatContent = (text) => {
const parts = [];
let currentIndex = 0;
const jsonBlockRegex = /```(?:json)?\s*(\{[\s\S]*?\})\s*```/g;

let match;
while ((match = jsonBlockRegex.exec(text)) !== null) {
// Add text before the JSON block
if (match.index > currentIndex) {
parts.push({
type: 'text',
content: text.slice(currentIndex, match.index)
});
}

try {
// Try to parse the JSON
const jsonContent = JSON.parse(match[1]);
parts.push({
type: 'json',
content: jsonContent
});
} catch (e) {
// If parsing fails, treat as regular text
parts.push({
type: 'text',
content: match[0]
});
}

currentIndex = match.index + match[0].length;
}

// Add any remaining text
if (currentIndex < text.length) {
parts.push({
type: 'text',
content: text.slice(currentIndex)
});
}

return parts;
};

const parts = formatContent(content);

return (
<>
{parts.map((part, index) => (
<div key={index} className={part.type === 'json' ? 'json-block' : ''}>
{part.type === 'json' ? (
<JSONPretty data={part.content} />
) : (
<span>{part.content}</span>
)}
</div>
))}
</>
);
};

const AIChatPanel = ({ scene }) => {
const [messages, setMessages] = useState([]);
Expand Down Expand Up @@ -76,6 +141,7 @@ const AIChatPanel = ({ scene }) => {
chatContainerRef.current.scrollHeight;
}
}, [messages]);

return (
<div className="chat-panel-container">
<Collapsible defaultCollapsed={false}>
Expand All @@ -84,7 +150,7 @@ const AIChatPanel = ({ scene }) => {
<div ref={chatContainerRef} className="chat-messages">
{messages.map((message, index) => (
<div key={index} className={`chat-message ${message.role}`}>
{message.content}
<MessageContent content={message.content} />
</div>
))}
{isLoading && <div className="loading-indicator">Thinking...</div>}
Expand Down
40 changes: 40 additions & 0 deletions src/editor/style/chat-panel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@
&.assistant {
align-self: flex-start;
background-color: variables.$darkgray-500;

// Ensure JSON blocks expand properly within assistant messages
.json-block {
width: 100%;
margin: 0.5em 0;
}

// Override react-json-pretty default styles
.json-pretty {
width: 100% !important;
max-width: none !important;
font-family: 'Fira Code', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono',
monospace !important;
font-size: 13px !important;
line-height: 1.4 !important;
background-color: variables.$darkgray-900 !important;
padding: 8px !important;
border-radius: 6px !important;
overflow-x: auto !important;

// Style JSON keys
.__json-key__ {
color: variables.$purple-100 !important;
}

// Style JSON strings
.__json-string__ {
color: variables.$green-100 !important;
}

// Style JSON values (numbers, booleans)
.__json-value__ {
color: variables.$blue-100 !important;
}

// Style JSON punctuation
.__json-punctuation__ {
color: variables.$gray-300 !important;
}
}
}
}

Expand Down

0 comments on commit a2cc5fc

Please sign in to comment.