Skip to content

Commit f976b97

Browse files
committed
Update ai-sdk to v5 #951
1 parent 706c874 commit f976b97

37 files changed

+1779
-2103
lines changed

browser/data-browser/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"name": "Joep Meindertsma"
66
},
77
"dependencies": {
8+
"@ai-sdk/react": "^2.0.29",
89
"@bugsnag/core": "^7.25.0",
910
"@bugsnag/js": "^7.25.0",
1011
"@bugsnag/plugin-react": "^7.25.0",
@@ -18,7 +19,7 @@
1819
"@emotion/is-prop-valid": "^1.3.1",
1920
"@modelcontextprotocol/sdk": "^1.13.3",
2021
"@oddbird/css-anchor-positioning": "^0.6.1",
21-
"@openrouter/ai-sdk-provider": "^0.4.3",
22+
"@openrouter/ai-sdk-provider": "^1.2.0",
2223
"@radix-ui/react-popover": "^1.1.2",
2324
"@radix-ui/react-scroll-area": "^1.2.0",
2425
"@radix-ui/react-tabs": "^1.1.1",
@@ -36,8 +37,8 @@
3637
"@tomic/react": "workspace:*",
3738
"@uiw/codemirror-theme-github": "^4.24.1",
3839
"@uiw/react-codemirror": "^4.24.1",
40+
"ai": "^5.0.29",
3941
"clsx": "^2.1.1",
40-
"ai": "^4.3.16",
4142
"downshift": "^9.0.9",
4243
"emoji-mart": "^5.6.0",
4344
"ollama-ai-provider": "^1.2.0",
@@ -60,11 +61,11 @@
6061
"react-window": "^1.8.10",
6162
"reactflow": "^11.11.4",
6263
"remark-gfm": "^4.0.0",
63-
"styled-components": "^6.1.13",
64+
"styled-components": "^6.1.19",
6465
"stylis": "4.3.0",
6566
"tippy.js": "^6.3.7",
6667
"tiptap-markdown": "^0.8.10",
67-
"zod": "^3.24.2"
68+
"zod": "^4.1.5"
6869
},
6970
"devDependencies": {
7071
"@tanstack/router-devtools": "^1.95.1",

browser/data-browser/src/components/AI/AIChatMessage.tsx

Lines changed: 9 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,34 @@
11
import styled from 'styled-components';
2-
import Markdown from '../datatypes/Markdown';
3-
import type { CoreAssistantMessage, CoreToolMessage } from 'ai';
4-
import { FaCircleExclamation, FaRetweet, FaTrash } from 'react-icons/fa6';
5-
import {
6-
isAIErrorMessage,
7-
isMessageWithContext,
8-
type AIChatDisplayMessage,
9-
} from './types';
10-
import { UserMessage, ToolResultMessage } from './AIChatMessageParts';
2+
import { FaRetweet, FaTrash } from 'react-icons/fa6';
3+
import { type AtomicUIMessage } from './types';
114
import { AssistantMessage } from './AIChatMessageParts/AssistantMessage';
125
import { IconButton } from '../IconButton/IconButton';
6+
import { UserMessage } from './AIChatMessageParts/UserMessage';
137

148
interface MessageProps {
15-
message: AIChatDisplayMessage;
16-
onDeleteMessage?: (message: AIChatDisplayMessage) => void;
17-
onRegenerateMessage?: (message: AIChatDisplayMessage) => void;
18-
}
19-
20-
function isToolMessage(
21-
message: AIChatDisplayMessage,
22-
): message is CoreToolMessage {
23-
return message.role === 'tool';
24-
}
25-
26-
function isAssistantMessage(
27-
message: AIChatDisplayMessage,
28-
): message is CoreAssistantMessage {
29-
return message.role === 'assistant';
9+
message: AtomicUIMessage;
10+
onDeleteMessage?: (message: AtomicUIMessage) => void;
11+
onRegenerateMessage?: (message: AtomicUIMessage) => void;
3012
}
3113

3214
export const AIChatMessage = ({
33-
message: messageIn,
15+
message,
3416
onDeleteMessage,
3517
onRegenerateMessage,
3618
}: MessageProps) => {
37-
const [message, context] = isMessageWithContext(messageIn)
38-
? [messageIn.message, messageIn.context]
39-
: [messageIn];
40-
4119
if (message.role === 'user') {
4220
return (
4321
<MessageActionWrapper
4422
message={message}
4523
onDeleteMessage={onDeleteMessage}
4624
onRegenerateMessage={onRegenerateMessage}
4725
>
48-
<UserMessage message={message} context={context} />
26+
<UserMessage message={message} />
4927
</MessageActionWrapper>
5028
);
5129
}
5230

53-
if (isAIErrorMessage(message)) {
54-
return (
55-
<ErrorMessageWrapper>
56-
<SenderName>
57-
<FaCircleExclamation />
58-
Error
59-
</SenderName>
60-
<Markdown text={message.content} maxLength={Infinity} />
61-
</ErrorMessageWrapper>
62-
);
63-
}
64-
65-
if (isToolMessage(message)) {
66-
return <ToolResultMessage message={message} />;
67-
}
68-
69-
if (isAssistantMessage(message)) {
31+
if (message.role === 'assistant') {
7032
return (
7133
<MessageActionWrapper message={message} onDeleteMessage={onDeleteMessage}>
7234
<AssistantMessage message={message} />
@@ -77,27 +39,6 @@ export const AIChatMessage = ({
7739
return <span>Unknown message type</span>;
7840
};
7941

80-
const ErrorMessageWrapper = styled.div`
81-
border-radius: ${p => p.theme.radius};
82-
width: 90%;
83-
padding: ${p => p.theme.size()};
84-
85-
background-color: ${p => (p.theme.darkMode ? '#440e0e' : '#f8dbdb')};
86-
`;
87-
88-
const SenderName = styled.span`
89-
display: inline-flex;
90-
align-items: center;
91-
gap: 1ch;
92-
font-weight: bold;
93-
font-size: 0.6rem;
94-
color: ${p => p.theme.colors.textLight};
95-
svg {
96-
font-size: 0.8rem;
97-
color: ${p => p.theme.colors.textLight};
98-
}
99-
`;
100-
10142
const FloatingActionRow = styled.div`
10243
position: absolute;
10344
top: 0;
Lines changed: 24 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,50 @@
11
import React from 'react';
2-
import { TOOL_NAMES } from '../useAtomicTools';
3-
import {
4-
AtomicEditToolMessage,
5-
AtomicFetchToolMessage,
6-
AtomicSearchToolMessage,
7-
BasicMessage,
8-
ImageContent,
9-
isImagePart,
10-
ReasoningMessage,
11-
} from './index';
12-
import type { CoreAssistantMessage, ToolCallPart } from 'ai';
13-
import styled from 'styled-components';
2+
import { isToolUIPart } from 'ai';
3+
import type { AtomicUIMessage } from '../types';
4+
import { FileContent } from './FileContent';
5+
import { MessageToolPart } from './MessageToolPart';
6+
import { SourceUrlPart } from './SourceUrlPart';
7+
import { BasicMessage } from './BasicMessage';
8+
import { ReasoningMessage } from './ReasoningMessage';
149

1510
interface AssistantMessageProps {
16-
message: CoreAssistantMessage;
11+
message: AtomicUIMessage;
1712
}
1813

1914
export const AssistantMessage: React.FC<AssistantMessageProps> = ({
2015
message,
2116
}) => {
22-
if (message.content.length === 0) {
23-
return null;
24-
}
25-
26-
if (typeof message.content === 'string') {
27-
return <BasicMessage text={message.content} />;
28-
}
29-
3017
return (
3118
<>
32-
{message.content.map((c, index) => {
33-
if (c.type === 'text') {
34-
if (c.text.length === 0) {
19+
{message.parts.map((part, index) => {
20+
if (part.type === 'text') {
21+
if (part.text.length === 0) {
3522
return null;
3623
}
3724

38-
return <BasicMessage key={`text-${index}`} text={c.text} />;
25+
return <BasicMessage key={index} text={part.text} />;
3926
}
4027

41-
if (isImagePart(c)) {
42-
return <ImageContent key={`image-${index}`} imagePart={c} />;
28+
if (part.type === 'file') {
29+
return <FileContent key={index} part={part} />;
4330
}
4431

45-
if (c.type === 'tool-call') {
46-
switch (c.toolName) {
47-
case TOOL_NAMES.SEARCH_RESOURCE:
48-
return (
49-
<AtomicSearchToolMessage key={c.toolCallId} toolCall={c} />
50-
);
51-
case TOOL_NAMES.GET_ATOMIC_RESOURCE:
52-
return <AtomicFetchToolMessage key={c.toolCallId} toolCall={c} />;
53-
case TOOL_NAMES.EDIT_ATOMIC_RESOURCE:
54-
return <AtomicEditToolMessage key={c.toolCallId} toolCall={c} />;
55-
case TOOL_NAMES.CREATE_RESOURCE:
56-
return (
57-
<BasicCustomToolUseMessage key={c.toolCallId} toolCall={c}>
58-
Creating Resource
59-
</BasicCustomToolUseMessage>
60-
);
61-
default:
62-
return (
63-
<ToolUseMessage key={c.toolCallId}>
64-
Using tool: <span>{c.toolName}</span>
65-
</ToolUseMessage>
66-
);
67-
}
32+
if (isToolUIPart(part)) {
33+
return <MessageToolPart key={index} part={part} />;
6834
}
6935

70-
if (c.type === 'reasoning') {
71-
return <ReasoningMessage key={c.text} text={c.text} />;
36+
if (part.type === 'reasoning') {
37+
return (
38+
<ReasoningMessage key={index} text={part.text} state={part.state} />
39+
);
40+
}
41+
42+
if (part.type === 'source-url') {
43+
return <SourceUrlPart key={index} part={part} />;
7244
}
7345

7446
return null;
7547
})}
7648
</>
7749
);
7850
};
79-
80-
interface ToolCallMessageProps {
81-
toolCall: ToolCallPart;
82-
}
83-
84-
const BasicCustomToolUseMessage = ({
85-
toolCall,
86-
children,
87-
}: React.PropsWithChildren<ToolCallMessageProps>) => {
88-
return (
89-
<ToolUseMessage key={toolCall.toolCallId}>
90-
<span>{children}</span>
91-
</ToolUseMessage>
92-
);
93-
};
94-
95-
const ToolUseMessage = styled.div`
96-
background-color: var(--mainSelectedBg);
97-
padding: 0.5em;
98-
border-radius: var(--radius);
99-
font-size: 0.7rem;
100-
width: fit-content;
101-
color: var(--textLight);
102-
`;

browser/data-browser/src/components/AI/AIChatMessageParts/AtomicEditToolMessage.tsx

Lines changed: 0 additions & 67 deletions
This file was deleted.

browser/data-browser/src/components/AI/AIChatMessageParts/AtomicFetchToolMessage.tsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)