Skip to content

Commit

Permalink
update aptos assistant
Browse files Browse the repository at this point in the history
  • Loading branch information
daoauth committed Dec 2, 2024
1 parent 9edf9d9 commit 1ecee2d
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 62 deletions.
18 changes: 14 additions & 4 deletions src/utilities/aptosAssistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ const getContent = (str: string) => {
return choices[0]?.delta?.content || '';
};

export interface AuditCodeRequest {
let isLoading: boolean = false;
let history: {
user: string;
bot: string;
}
}[] = [];

export const aptosAssistant = async (
requests: AuditCodeRequest[],
request: string,
onData: (data: string) => void,
onEnd: () => void,
): Promise<void> => {
if (isLoading) {
return;
}
isLoading = true;
history.push({ user: request, bot: '' });
try {
const response = await fetch(
'https://assistant.aptosfoundation.org/api/assistant/chat',
Expand All @@ -30,7 +36,7 @@ export const aptosAssistant = async (
top: 3,
suggest_followup_questions: false,
},
history: requests,
history,
}),
},
);
Expand Down Expand Up @@ -80,11 +86,15 @@ export const aptosAssistant = async (
}

if (onEnd) {
isLoading = false;
history[history.length - 1].bot = resultText;
onEnd();
}
} catch (error) {
history.slice(0, -1);
vscode.window.showErrorMessage(`Unknown error: ${error}`);
if (onEnd) {
isLoading = false;
onEnd();
}
}
Expand Down
122 changes: 81 additions & 41 deletions src/webview/panel/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,43 @@
import React, { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { VSCodeTextField } from '@vscode/webview-ui-toolkit/react';
import { marked } from 'marked';

import './App.css';

import { COMMENDS } from './utilities/commends';
import { vscode } from './utilities/vscode';
import { User } from './components/User';
import { Bot } from './components/Bot';

function App() {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [input, setInput] = useState<string>('');
const [html, setHtml] = useState<string>('');
const [htmlHistory, setHtmlHistory] = useState<
{ isBot: boolean; content: string }[]
>([]);
const messagesEndRef = useRef<HTMLDivElement>(null);

useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [htmlHistory]);

useEffect(() => {
const initInfo = async () => {
const info =
'This window is for testing the [```Aptos Assistant```](https://assistant.aptosfoundation.org). Try using the ```Aptos Assistant (beta) context menu``` in the Explorer or Editor window.';
const renderedHtml = await marked.parse(info);
setHtml(() => renderedHtml);
};
const handleMessage = async (event: any) => {
const message = event.data;
switch (message.command) {
case 'aptos-extension.assistant.file':
case 'aptos-extension.assistant.folder':
setIsLoading(() => true);
setHtmlHistory((old) => [
...old,
{ isBot: false, content: message.data },
{ isBot: true, content: '' },
]);
break;
case COMMENDS.AptosAssistantStream:
const renderedHtml = await marked.parse(message.data);
setHtml(() => renderedHtml);
setHtmlHistory((old) => [
...old.slice(0, -1),
{ isBot: true, content: message.data },
]);
break;
case COMMENDS.AptosAssistantStreamEnd:
setIsLoading(() => false);
Expand All @@ -38,11 +47,6 @@ function App() {
}
};
window.addEventListener('message', handleMessage);

initInfo();
return () => {
window.removeEventListener('message', handleMessage);
};
}, []);

return (
Expand All @@ -51,34 +55,70 @@ function App() {
style={{
flex: 1,
overflowY: 'auto',
color: 'var(--vscode-foreground)',
borderBottom: '1px solid var(--vscode-editorGroup-border)',
}}
dangerouslySetInnerHTML={{ __html: html }}
/>
<VSCodeTextField
>
{htmlHistory.length === 0 ? (
<div
style={{
flex: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
color: 'var(--vscode-foreground)',
fontSize: '1.2rem',
textAlign: 'center',
height: '100%',
}}
>
No messages yet. Start a conversation!
</div>
) : (
htmlHistory.map((item, key) =>
item.isBot ? (
<Bot key={key} data={item.content} />
) : (
<User key={key} data={item.content} />
),
)
)}
<div ref={messagesEndRef} />
</div>
<div
style={{
backgroundColor: 'var(--vscode-editor-background)',
color: 'var(--vscode-input-foreground)',
}}
disabled={isLoading}
value={input}
placeholder="Message..."
onChange={(event) => {
setInput((event.target as any)?.value || '');
}}
onKeyDown={(event) => {
const value = (event.target as any)?.value || '';
if (event.key === 'Enter' && value) {
vscode.postMessage({
command: COMMENDS.AptosAssistantQuestion,
data: value,
});
setInput('');
setIsLoading(() => true);
}
position: 'sticky',
bottom: 0,
paddingBottom: '1rem',
}}
/>
>
<VSCodeTextField
style={{
width: '100%',
color: 'var(--vscode-input-foreground)',
}}
disabled={isLoading}
value={input}
placeholder="Message..."
onChange={(event) => {
!isLoading && setInput((event.target as any)?.value || '');
}}
onKeyDown={(event) => {
const value = (event.target as any)?.value || '';
if (event.key === 'Enter' && value && !isLoading) {
vscode.postMessage({
command: COMMENDS.AptosAssistantQuestion,
data: value,
});
setInput('');
setIsLoading(() => true);
setHtmlHistory((old) => [
...old,
{ isBot: false, content: value },
{ isBot: true, content: '' },
]);
}
}}
/>
</div>
</div>
);
}
Expand Down
21 changes: 21 additions & 0 deletions src/webview/panel/src/components/Bot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect, useState } from 'react';
import { marked } from 'marked';

export const Bot = ({ data }: { data: string }) => {
const [html, setHtml] = useState<string>('');
useEffect(() => {
const renderedHtml = marked.parse(data, { async: false });
setHtml(() => renderedHtml);
}, [data]);
return (
<div
style={{
width: '80%',
color: 'var(--vscode-foreground)',
textAlign: 'left',
marginBottom: '1rem',
}}
dangerouslySetInnerHTML={{ __html: html }}
/>
);
};
40 changes: 40 additions & 0 deletions src/webview/panel/src/components/User.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export const User = ({ data }: { data: string }) => {
return (
<div
style={{
display: 'flex',
justifyContent: 'flex-end',
marginBottom: '1rem',
}}
>
<div
style={{
maxWidth: '80%',
backgroundColor: 'var(--vscode-input-background)',
color: 'var(--vscode-foreground)',
padding: '10px 15px',
borderRadius: '15px',
textAlign: 'left',
position: 'relative',
boxShadow: '0px 2px 5px rgba(0, 0, 0, 0.2)',
}}
>
{data}
<div
style={{
content: '""',
position: 'absolute',
bottom: '10px',
right: '-10px',
width: '0',
height: '0',
borderTop: '10px solid var(--vscode-input-background)',
borderLeft: '10px solid transparent',
borderRight: 'none',
borderBottom: 'none',
}}
/>
</div>
</div>
);
};
27 changes: 10 additions & 17 deletions src/webview/panelProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,11 @@ class PanelProvider implements vscode.WebviewViewProvider {
switch (command) {
case COMMENDS.AptosAssistantQuestion:
aptosAssistant(
[
{
user: data,
bot: '',
},
],
(data) => {
data,
(stream) => {
this._view?.webview.postMessage({
command: COMMENDS.AptosAssistantStream,
data,
data: stream,
});
},
() => {
Expand Down Expand Up @@ -89,18 +84,16 @@ class PanelProvider implements vscode.WebviewViewProvider {
switch (message.command) {
case 'aptos-extension.assistant.file':
case 'aptos-extension.assistant.folder':
this._view?.webview.postMessage({ command: message.command });
this._view?.webview.postMessage({
command: message.command,
data: 'Code Analysis...',
});
aptosAssistant(
[
{
user: message.data,
bot: '',
},
],
(data) => {
message.data,
(stream) => {
this._view?.webview.postMessage({
command: COMMENDS.AptosAssistantStream,
data,
data: stream,
});
},
() => {
Expand Down

0 comments on commit 1ecee2d

Please sign in to comment.