@tanstack/ai-client 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/chat-client.d.ts +3 -0
- package/dist/esm/chat-client.js +33 -11
- package/dist/esm/chat-client.js.map +1 -1
- package/dist/esm/connection-adapters.js +2 -1
- package/dist/esm/connection-adapters.js.map +1 -1
- package/dist/esm/message-date-normalizer.d.ts +3 -0
- package/dist/esm/message-date-normalizer.js +35 -0
- package/dist/esm/message-date-normalizer.js.map +1 -0
- package/dist/esm/storage-adapters.js +13 -1
- package/dist/esm/storage-adapters.js.map +1 -1
- package/dist/esm/types.d.ts +5 -0
- package/dist/esm/types.js.map +1 -1
- package/package.json +3 -3
- package/src/chat-client.ts +70 -7
- package/src/connection-adapters.ts +5 -2
- package/src/message-date-normalizer.ts +29 -0
- package/src/storage-adapters.ts +13 -2
- package/src/types.ts +5 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { UIMessage } from './types'
|
|
2
|
+
|
|
3
|
+
function validDate(value: unknown): Date | undefined {
|
|
4
|
+
if (value instanceof Date)
|
|
5
|
+
return Number.isNaN(value.getTime()) ? undefined : value
|
|
6
|
+
if (typeof value !== 'string') return undefined
|
|
7
|
+
const date = new Date(value)
|
|
8
|
+
return Number.isNaN(date.getTime()) ? undefined : date
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function normalizeMessageDates(message: UIMessage): UIMessage {
|
|
12
|
+
const messageDate = validDate(message.createdAt)
|
|
13
|
+
const parts = message.parts.map((part) => {
|
|
14
|
+
if (part.type !== 'tool-result') return part
|
|
15
|
+
const date = validDate(part.createdAt)
|
|
16
|
+
const { createdAt: _ignored, ...rest } = part
|
|
17
|
+
return date ? { ...rest, createdAt: date } : rest
|
|
18
|
+
})
|
|
19
|
+
const { createdAt: _ignored, ...rest } = message
|
|
20
|
+
return messageDate
|
|
21
|
+
? { ...rest, parts, createdAt: messageDate }
|
|
22
|
+
: { ...rest, parts }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function normalizeMessagesDates(
|
|
26
|
+
messages: Array<UIMessage>,
|
|
27
|
+
): Array<UIMessage> {
|
|
28
|
+
return messages.map(normalizeMessageDates)
|
|
29
|
+
}
|
package/src/storage-adapters.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ChatPersistedState, ChatStorageAdapter } from './types'
|
|
1
|
+
import type { ChatPersistedState, ChatStorageAdapter, UIMessage } from './types'
|
|
2
|
+
import { normalizeMessagesDates } from './message-date-normalizer'
|
|
2
3
|
|
|
3
4
|
export interface WebStoragePersistenceOptions {
|
|
4
5
|
keyPrefix?: string
|
|
@@ -45,6 +46,16 @@ function stringifyJson(value: ChatPersistedState): string {
|
|
|
45
46
|
return serialized
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
function reviveMessageCreatedAt(message: UIMessage): UIMessage {
|
|
50
|
+
return normalizeMessagesDates([message]).at(0) ?? message
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function revivePersistedState(state: ChatPersistedState): ChatPersistedState {
|
|
54
|
+
if (state == null || typeof state !== 'object') return state
|
|
55
|
+
if (!Array.isArray(state.messages)) return state
|
|
56
|
+
return { ...state, messages: state.messages.map(reviveMessageCreatedAt) }
|
|
57
|
+
}
|
|
58
|
+
|
|
48
59
|
function createWebStoragePersistence(
|
|
49
60
|
storageName: 'localStorage' | 'sessionStorage',
|
|
50
61
|
options: WebStoragePersistenceOptions,
|
|
@@ -69,7 +80,7 @@ function createWebStoragePersistence(
|
|
|
69
80
|
return {
|
|
70
81
|
getItem(id) {
|
|
71
82
|
const item = getStorage().getItem(key(id))
|
|
72
|
-
return item === null ? null : deserialize(item)
|
|
83
|
+
return item === null ? null : revivePersistedState(deserialize(item))
|
|
73
84
|
},
|
|
74
85
|
setItem(id, value) {
|
|
75
86
|
getStorage().setItem(key(id), serialize(value))
|
package/src/types.ts
CHANGED
|
@@ -595,10 +595,14 @@ export type ToolCallPart<TTools extends ReadonlyArray<AnyClientTool> = any> =
|
|
|
595
595
|
|
|
596
596
|
export interface ToolResultPart {
|
|
597
597
|
type: 'tool-result'
|
|
598
|
+
id?: string
|
|
599
|
+
name?: string
|
|
598
600
|
toolCallId: string
|
|
599
601
|
content: string | Array<ContentPart>
|
|
600
602
|
state: ToolResultState
|
|
601
603
|
error?: string // Error message if state is "error"
|
|
604
|
+
metadata?: Record<string, unknown>
|
|
605
|
+
createdAt?: Date
|
|
602
606
|
}
|
|
603
607
|
|
|
604
608
|
export interface ThinkingPart {
|
|
@@ -639,6 +643,7 @@ export interface UIMessage<
|
|
|
639
643
|
> {
|
|
640
644
|
id: string
|
|
641
645
|
role: 'system' | 'user' | 'assistant'
|
|
646
|
+
name?: string
|
|
642
647
|
parts: Array<MessagePart<TTools, TData>>
|
|
643
648
|
createdAt?: Date
|
|
644
649
|
/**
|