Skip to content

Commit c8ec434

Browse files
authored
167/show ai tools (#427)
* Fix issue for new user * Tools selection * Added styles * Added styles
1 parent 4248920 commit c8ec434

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+602
-5617
lines changed

src/app/app/virtual-lab/(free)/explore/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { sectionAtom } from '@/state/application';
1010

1111
import styles from './layout.module.css';
1212

13-
const LiteratureSuggestions = dynamic(() => import('@/components/literature-suggestions'));
13+
const LiteratureSuggestions = dynamic(() => import('@/components/ai-assistant'));
1414

1515
type GenericLayoutProps = {
1616
children: ReactNode;

src/app/app/virtual-lab/lab/[virtualLabId]/project/[projectId]/explore/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { sectionAtom } from '@/state/application';
1010

1111
import styles from './layout.module.css';
1212

13-
const LiteratureSuggestions = dynamic(() => import('@/components/literature-suggestions'));
13+
const LiteratureSuggestions = dynamic(() => import('@/components/ai-assistant'));
1414

1515
type GenericLayoutProps = {
1616
children: ReactNode;

src/components/literature-suggestions/literature-suggestions.module.css renamed to src/components/ai-assistant/ai-assistant.module.css

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
width: max(320px, 25vw);
2222
height: 100%;
23-
background-color: var(--color-neutral-9);
23+
background-color: var(--color-neutral-7);
2424
color: var(--color-primary-1);
2525
padding: 1em;
2626
display: grid;
@@ -77,18 +77,28 @@
7777

7878
.literatureSuggestions button.actionButton {
7979
font: inherit;
80-
border: 2px solid var(--color-primary-2);
81-
border-radius: 4px;
80+
border: 2px solid #f0f0f0;
81+
background: #fff;
82+
border-radius: 999vmax;
83+
box-shadow:
84+
0 0.5em 1em #0005,
85+
0 -0.5em 1em #fff;
8286
line-height: 2;
8387
padding: 0 1em;
8488
cursor: pointer;
89+
display: flex;
90+
flex-wrap: nowrap;
91+
flex-direction: row;
92+
justify-content: flex-start;
93+
align-items: center;
94+
gap: 1em;
8595
}
8696

8797
.footerButtons {
8898
display: flex;
8999
flex-wrap: nowrap;
90100
flex-direction: row;
91-
justify-content: flex-end;
101+
justify-content: flex-start;
92102
align-items: center;
93103
gap: 1em;
94104
margin: 1em 0;
@@ -132,8 +142,10 @@ button.cancelButton:active {
132142
margin-top: 2em;
133143
font-size: 120%;
134144
padding: 1em;
135-
box-shadow: rgba(0, 0, 0, 0.12) 0px 6px 16px;
145+
box-shadow: rgba(0, 0, 0, 0.12) 0 6px 16px;
136146
border-radius: 1em;
147+
border: 2px solid var(--color-neutral-9);
148+
background-color: var(--color-neutral-8);
137149
}
138150

139151
.welcome > div > p {

src/components/literature-suggestions/literature-suggestions.tsx renamed to src/components/ai-assistant/ai-assistant.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,25 @@ import Prompt from './prompt';
99
import { Spinner } from './spinner';
1010
import SuggestedQuestions from './suggested-questions';
1111
import { useCollapsedPanel } from './hooks';
12+
import { IconClear } from './icons/clear';
1213
import { classNames } from '@/util/utils';
1314
import { useServiceAiAgentChat, useServiceAiAgentThread } from '@/services/ai-agent';
1415

15-
import styles from './literature-suggestions.module.css';
16+
import { useAITools } from '@/services/ai-agent/tools/tools';
17+
import styles from './ai-assistant.module.css';
1618

1719
export interface LiteratureSuggestionsProps {
1820
className?: string;
1921
}
2022

21-
export default function LiteratureSuggestions({ className }: LiteratureSuggestionsProps) {
23+
export default function ArtificialIntelligenceAssistant({ className }: LiteratureSuggestionsProps) {
24+
const tools = useAITools();
2225
const [collapsedPanel, setCollapsedPanel] = useCollapsedPanel();
2326
const refChatBottom = React.useRef<HTMLDivElement | null>(null);
2427
const [threadId, recreateThreadId] = useServiceAiAgentThread();
2528
const [prompt, setPrompt] = React.useState('');
2629
const { messages, clear, status, append, error, stop } = useServiceAiAgentChat(threadId ?? '');
2730

28-
// TODO: for future improvement, to disable the spinner for user has not virtual lab
29-
// const userStats = useAtomValue(userStatsAtom);
30-
// const userHasVirtualLab = Boolean(userStats?.data?.owned_labs_count);
31-
3231
const handleQuery = React.useCallback(
3332
(content: string) => {
3433
append({
@@ -77,7 +76,7 @@ export default function LiteratureSuggestions({ className }: LiteratureSuggestio
7776
</div>
7877
</div>
7978
)}
80-
{threadId ? (
79+
{threadId && tools ? (
8180
<>
8281
<div className={styles.articles}>
8382
{messages.map((item, messageIndex) => (
@@ -90,7 +89,8 @@ export default function LiteratureSuggestions({ className }: LiteratureSuggestio
9089
{status === 'ready' && messages.length > 0 && (
9190
<div className={styles.footerButtons}>
9291
<button type="button" className={styles.actionButton} onClick={handleClearChat}>
93-
Clear the Chat
92+
<IconClear />
93+
<div>Clear chat</div>
9494
</button>
9595
</div>
9696
)}
@@ -110,7 +110,7 @@ export default function LiteratureSuggestions({ className }: LiteratureSuggestio
110110
/>
111111
)}
112112
{(status === 'ready' || status === 'error') && (
113-
<Prompt value={prompt} onChange={setPrompt} onClick={handleQuery} />
113+
<Prompt value={prompt} tools={tools} onChange={setPrompt} onClick={handleQuery} />
114114
)}
115115
{status !== 'ready' && status !== 'error' && (
116116
<div className={styles.spinnerContainer}>

src/components/literature-suggestions/error/error.module.css renamed to src/components/ai-assistant/error/error.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
}
99

1010
.error pre {
11-
white-space: prewrap;
11+
white-space: pre-wrap;
1212
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export function IconClear() {
2+
return (
3+
<svg
4+
width="1em"
5+
height="1em"
6+
viewBox="0 0 13 13"
7+
fill="none"
8+
xmlns="http://www.w3.org/2000/svg"
9+
>
10+
<path
11+
d="M12.9999 6.6258L12.9948 5.30653C12.9898 4.42915 12.2957 3.72064 11.4397 3.71827H11.4341L9.80397 3.72405L9.83444 0.598611V0.599189C9.83726 0.275303 9.5839 0.0104052 9.26792 0.00694055L8.50449 0H8.49828C8.18511 0 7.93008 0.258531 7.9267 0.580107L7.89623 3.7322L6.2108 3.73856C5.35314 3.74377 4.66087 4.45863 4.66188 5.33778L4.6664 6.65705C4.6664 6.72182 4.68953 6.78486 4.73072 6.8346C4.54 8.13476 3.86911 9.31064 2.85578 10.118L2.8507 10.1221C2.74011 10.2111 2.71584 10.3731 2.7954 10.4922C2.86763 10.6015 2.94267 10.7068 3.01716 10.8051C3.92505 12.0018 5.26232 12.7767 6.73108 12.9566C6.95959 12.9855 7.18981 13 7.42002 13C8.52765 12.9971 9.60986 12.6559 10.528 12.0208C11.446 11.3852 12.1587 10.4835 12.5757 9.43151C12.9075 8.58767 13.0389 7.67564 12.9599 6.7698C12.9865 6.72642 12.9999 6.67669 12.9999 6.6258ZM8.46279 0.584713C8.46336 0.56447 8.47916 0.548276 8.49891 0.547698L9.26291 0.555216V0.555795C9.28266 0.556373 9.29846 0.572567 9.29902 0.59281L9.26855 3.7258L8.43232 3.72927L8.46279 0.584713ZM5.49423 4.59749V4.59691C5.68382 4.3997 5.94226 4.28807 6.21253 4.28749L11.4364 4.26783L11.4398 4.26725C12.0006 4.26956 12.4548 4.73399 12.4594 5.30831L12.4633 6.35284L5.20087 6.38118L5.19692 5.33665C5.19523 5.05961 5.30244 4.79298 5.49372 4.59749L5.49423 4.59749ZM10.5115 11.3546C9.95008 11.8052 9.30231 12.1279 8.60999 12.3008C9.18101 11.7016 9.61604 10.9798 9.88294 10.1875C9.92357 10.047 9.84908 9.89892 9.71366 9.85091C9.57881 9.80291 9.43041 9.87231 9.37737 10.0082C9.06026 10.9475 8.48416 11.7722 7.71954 12.3836C7.69866 12.3998 7.6806 12.4194 7.66537 12.4414C7.04638 12.4732 6.42684 12.3882 5.83781 12.191C6.31177 11.7433 6.70506 11.2135 7.00073 10.6266C7.06393 10.4924 7.01145 10.331 6.88224 10.2628C6.75359 10.1945 6.59447 10.2443 6.52506 10.375C6.21754 10.9852 5.79323 11.5259 5.2775 11.9649C4.55751 11.6219 3.92724 11.1083 3.43867 10.4663C3.41949 10.4403 3.39974 10.4143 3.37999 10.3871V10.3877C4.39169 9.50393 5.05863 8.27602 5.2584 6.9291L12.4334 6.90191C12.5655 8.62373 11.8426 10.2968 10.5115 11.3546ZM7.33133 9.82423L7.32343 9.84795C7.30086 9.91793 7.25233 9.97519 7.18857 10.0076C7.12425 10.0405 7.05033 10.0457 6.98262 10.022C6.91491 9.99832 6.85961 9.948 6.82802 9.88207C6.79698 9.81613 6.79303 9.74037 6.81617 9.67154L6.82294 9.65129V9.65072C6.86977 9.5067 7.02156 9.4292 7.16206 9.4772C7.30199 9.52521 7.37816 9.68079 7.33133 9.82423ZM3.76692 6.54599C3.91475 6.54599 4.03494 6.42338 4.03494 6.27184C4.03494 6.12031 3.91476 5.99711 3.76692 5.99711C2.94875 5.99653 2.28575 5.31694 2.28517 4.47829V4.47713C2.28404 4.32618 2.16442 4.20413 2.01714 4.20413C1.86931 4.20413 1.74968 4.32675 1.74968 4.47829C1.74855 5.31518 1.08838 5.99355 0.271975 5.99711H0.267461C0.119632 5.99711 0 6.1203 0 6.27184C0 6.42336 0.119621 6.54599 0.267461 6.54599C1.0828 6.54714 1.74517 7.22268 1.74979 8.05844V8.06538C1.7481 8.13883 1.77518 8.21055 1.82596 8.26318C1.87618 8.31639 1.94502 8.34588 2.01724 8.34588C2.08946 8.34588 2.15831 8.31639 2.20908 8.26318C2.2593 8.21055 2.28695 8.13883 2.28526 8.06538C2.28582 7.22849 2.94599 6.54952 3.76253 6.54597L3.76692 6.54599ZM2.01722 7.03645C1.83835 6.71835 1.58105 6.45461 1.27071 6.27184C1.58048 6.08849 1.83778 5.82476 2.01665 5.50665C2.19552 5.82475 2.45281 6.08849 2.76316 6.27184C2.45283 6.45518 2.19609 6.71891 2.01722 7.03645Z"
12+
fill="currentColor"
13+
/>
14+
</svg>
15+
);
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export function IconGear({ className }: { className?: string }) {
2+
return (
3+
<svg
4+
className={className}
5+
xmlns="http://www.w3.org/2000/svg"
6+
viewBox="0 0 24 24"
7+
width="1.5em"
8+
height="1.5em"
9+
>
10+
<title>Tools</title>
11+
<path
12+
fill="currentColor"
13+
d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"
14+
/>
15+
</svg>
16+
);
17+
}

src/components/ai-assistant/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './ai-assistant';

src/components/literature-suggestions/message-item/message-item.module.css renamed to src/components/ai-assistant/message-item/message-item.module.css

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
.user {
66
display: flex;
77
flex-wrap: nowrap;
8-
flex-direction: row;
8+
flex-direction: column;
99
justify-content: flex-start;
1010
align-items: stretch;
1111
gap: 0;
1212
color: var(--color-on-primary);
1313
margin: 8px 0;
14+
margin-bottom: 32px;
15+
}
16+
17+
.timestamp {
18+
color: #000b;
1419
}
1520

1621
.userAvatar {
@@ -38,6 +43,7 @@
3843
}
3944

4045
.userContent {
46+
position: relative;
4147
flex: 1 1 auto;
4248
padding: 8px;
4349
border-radius: 6px;
@@ -50,10 +56,34 @@
5056
min-height: 64px;
5157
}
5258

59+
.userContent::after {
60+
content: '';
61+
position: absolute;
62+
right: 16px;
63+
bottom: -24px;
64+
width: 32px;
65+
height: 24px;
66+
background-color: var(--color-primary-5);
67+
border-radius: 0;
68+
z-index: 1;
69+
clip-path: path('M0,0h24L32,24,0,0z');
70+
}
71+
5372
.userContent > div {
5473
padding: 0 1em;
5574
}
5675

76+
.markdown {
77+
border-radius: 1em;
78+
border: 2px solid var(--color-neutral-9);
79+
background-color: #f8f8f8;
80+
padding: 1em;
81+
margin: 1em 0;
82+
box-shadow: 0 0.5em 1em #0005;
83+
clip-path: none;
84+
z-index: 1;
85+
}
86+
5787
.markdown ul {
5888
list-style: disc;
5989
}

src/components/literature-suggestions/message-item/message-item.tsx renamed to src/components/ai-assistant/message-item/message-item.tsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import Link from 'next/link';
55
import { ToolInvocation, UIMessage } from '@ai-sdk/ui-utils';
66
import ReactMarkdown from 'react-markdown';
77

8-
import ToolArticles from './tools/articles/tool-articles';
9-
import ToolMorphologies from './tools/morphologies/tool-morphologies';
8+
import ToolArticles from '../../../services/ai-agent/tools/articles/tool-articles';
9+
import ToolMorphologies from '../../../services/ai-agent/tools/morphologies/tool-morphologies';
10+
import ToolsProgress from './tools-progress';
1011
import { classNames } from '@/util/utils';
1112

1213
import styles from './message-item.module.css';
@@ -31,23 +32,26 @@ function renderMessage(value: UIMessage, hideTools: boolean, debug: boolean): Re
3132
case 'user':
3233
return (
3334
<div className={styles.user}>
34-
{/* <div className={styles.userAvatar}><ChevronRight fill="currentColor" /></div> */}
3535
<div className={styles.userContent}>
3636
<div>{value.content}</div>
3737
</div>
38+
<div className={styles.timestamp}>{value.createdAt && formatDate(value.createdAt)}</div>
3839
</div>
3940
);
4041
case 'assistant': {
4142
return (
4243
<>
43-
<ReactMarkdown
44-
className={styles.markdown}
45-
components={{
46-
a: LinkWithExternalTarget,
47-
}}
48-
>
49-
{value.content}
50-
</ReactMarkdown>
44+
<ToolsProgress message={value} />
45+
{value.content.trim().length > 0 && (
46+
<ReactMarkdown
47+
className={styles.markdown}
48+
components={{
49+
a: LinkWithExternalTarget,
50+
}}
51+
>
52+
{value.content}
53+
</ReactMarkdown>
54+
)}
5155
{!hideTools && (
5256
<>
5357
<ToolArticles message={value} />
@@ -108,3 +112,11 @@ function LinkWithExternalTarget({ href, children }: AnchorHTMLAttributes<HTMLAnc
108112
</Link>
109113
);
110114
}
115+
116+
function formatDate(d: Date): string {
117+
const formatter = new Intl.DateTimeFormat(undefined, {
118+
dateStyle: 'short',
119+
timeStyle: 'short',
120+
});
121+
return formatter.format(d);
122+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './tools-progress';
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.toolState {
2+
color: #000e;
3+
border: 1px solid #0003;
4+
display: inline-flex;
5+
flex-wrap: nowrap;
6+
flex-direction: row;
7+
justify-content: space-between;
8+
align-items: center;
9+
gap: 0.5em;
10+
padding: 0.25em 0.5em;
11+
margin: 0.5em;
12+
}
13+
14+
.toolState > * {
15+
flex: 0 0 auto;
16+
}
17+
18+
.toolState > .name {
19+
flex: 1 1 auto;
20+
}
21+
22+
.spin {
23+
animation: 1s infinite linear animation-spin;
24+
}
25+
26+
@keyframes animation-spin {
27+
from {
28+
transform: rotate(0);
29+
}
30+
to {
31+
transform: rotate(360deg);
32+
}
33+
}

0 commit comments

Comments
 (0)