@tanstack/ai-svelte 0.19.3 → 0.20.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/chat-ui/create-chat-hook.d.ts +27 -0
- package/dist/chat-ui/create-chat-hook.js +26 -0
- package/dist/chat-ui/create-ui.d.ts +131 -0
- package/dist/chat-ui/create-ui.js +100 -0
- package/dist/chat-ui/selected-part.svelte +45 -0
- package/dist/chat-ui/selected-part.svelte.d.ts +9 -0
- package/dist/chat-ui/ui-chat.svelte +42 -0
- package/dist/chat-ui/ui-chat.svelte.d.ts +9 -0
- package/dist/chat-ui/ui-interrupt.svelte +30 -0
- package/dist/chat-ui/ui-interrupt.svelte.d.ts +9 -0
- package/dist/chat-ui/ui-interrupts.svelte +30 -0
- package/dist/chat-ui/ui-interrupts.svelte.d.ts +9 -0
- package/dist/chat-ui/ui-message.svelte +45 -0
- package/dist/chat-ui/ui-message.svelte.d.ts +12 -0
- package/dist/chat-ui/ui-messages.svelte +31 -0
- package/dist/chat-ui/ui-messages.svelte.d.ts +10 -0
- package/dist/chat-ui/ui-part.svelte +30 -0
- package/dist/chat-ui/ui-part.svelte.d.ts +9 -0
- package/dist/chat-ui/ui-provider.svelte +29 -0
- package/dist/chat-ui/ui-provider.svelte.d.ts +10 -0
- package/dist/chat-ui/ui-queue.svelte +21 -0
- package/dist/chat-ui/ui-queue.svelte.d.ts +7 -0
- package/dist/create-chat-hook.d.ts +35 -0
- package/dist/create-chat-hook.js +31 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ui.d.ts +11 -0
- package/dist/ui.js +11 -0
- package/package.json +9 -4
- package/src/chat-ui/create-chat-hook.ts +62 -0
- package/src/chat-ui/create-ui.ts +310 -0
- package/src/chat-ui/selected-part.svelte +45 -0
- package/src/chat-ui/ui-chat.svelte +42 -0
- package/src/chat-ui/ui-interrupt.svelte +30 -0
- package/src/chat-ui/ui-interrupts.svelte +30 -0
- package/src/chat-ui/ui-message.svelte +45 -0
- package/src/chat-ui/ui-messages.svelte +31 -0
- package/src/chat-ui/ui-part.svelte +30 -0
- package/src/chat-ui/ui-provider.svelte +29 -0
- package/src/chat-ui/ui-queue.svelte +21 -0
- package/src/create-chat-hook.ts +67 -0
- package/src/index.ts +1 -0
- package/src/ui.ts +25 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getChatContext,
|
|
4
|
+
getComponentsContext,
|
|
5
|
+
listInterrupts,
|
|
6
|
+
type UIDescriptor,
|
|
7
|
+
} from './create-ui'
|
|
8
|
+
import UIInterrupt from './ui-interrupt.svelte'
|
|
9
|
+
import type { ChatUIInterrupt } from '@tanstack/ai-client/ui'
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
ui,
|
|
13
|
+
children,
|
|
14
|
+
}: {
|
|
15
|
+
ui: UIDescriptor
|
|
16
|
+
children?: import('svelte').Snippet<[Array<ChatUIInterrupt>]>
|
|
17
|
+
} = $props()
|
|
18
|
+
|
|
19
|
+
const chat = $derived(getChatContext(ui))
|
|
20
|
+
const comps = $derived(getComponentsContext(ui))
|
|
21
|
+
const interrupts = $derived(listInterrupts(chat, comps.inlineToolNames))
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
{#if children}
|
|
25
|
+
{@render children(interrupts)}
|
|
26
|
+
{:else}
|
|
27
|
+
{#each interrupts as interrupt (interrupt.id)}
|
|
28
|
+
<UIInterrupt {ui} {interrupt} />
|
|
29
|
+
{/each}
|
|
30
|
+
{/if}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getChatContext,
|
|
4
|
+
getComponentsContext,
|
|
5
|
+
messageParts,
|
|
6
|
+
readInterrupts,
|
|
7
|
+
type UIDescriptor,
|
|
8
|
+
} from './create-ui'
|
|
9
|
+
import SelectedPart from './selected-part.svelte'
|
|
10
|
+
import type { ChatUIInterrupt } from '@tanstack/ai-client/ui'
|
|
11
|
+
import type { UIMessage } from '@tanstack/ai-client'
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
ui,
|
|
15
|
+
message,
|
|
16
|
+
interrupts,
|
|
17
|
+
children,
|
|
18
|
+
}: {
|
|
19
|
+
ui: UIDescriptor
|
|
20
|
+
message: UIMessage
|
|
21
|
+
interrupts?: ReadonlyArray<ChatUIInterrupt>
|
|
22
|
+
children?: import('svelte').Snippet<[unknown]>
|
|
23
|
+
} = $props()
|
|
24
|
+
|
|
25
|
+
const comps = $derived(getComponentsContext(ui))
|
|
26
|
+
const resolvedInterrupts = $derived(
|
|
27
|
+
interrupts ?? readInterrupts(getChatContext(ui)),
|
|
28
|
+
)
|
|
29
|
+
const selectedParts = $derived(
|
|
30
|
+
messageParts(message, resolvedInterrupts, comps.inlineToolNames),
|
|
31
|
+
)
|
|
32
|
+
const Message = $derived(comps.components.message as any)
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
{#if children}
|
|
36
|
+
{@render children(selectedParts)}
|
|
37
|
+
{:else}
|
|
38
|
+
<Message {message}>
|
|
39
|
+
{#snippet parts()}
|
|
40
|
+
{#each selectedParts as part, index (`${message.id}-${index}`)}
|
|
41
|
+
<SelectedPart {ui} selected={part} />
|
|
42
|
+
{/each}
|
|
43
|
+
{/snippet}
|
|
44
|
+
</Message>
|
|
45
|
+
{/if}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getChatContext,
|
|
4
|
+
readInterrupts,
|
|
5
|
+
readMessages,
|
|
6
|
+
type UIDescriptor,
|
|
7
|
+
} from './create-ui'
|
|
8
|
+
import UIMessage from './ui-message.svelte'
|
|
9
|
+
import type { Snippet } from 'svelte'
|
|
10
|
+
import type { UIMessage as UIMessageModel } from '@tanstack/ai-client'
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
ui,
|
|
14
|
+
children,
|
|
15
|
+
}: {
|
|
16
|
+
ui: UIDescriptor
|
|
17
|
+
children?: Snippet<[ReadonlyArray<UIMessageModel>]>
|
|
18
|
+
} = $props()
|
|
19
|
+
|
|
20
|
+
const chat = $derived(getChatContext(ui))
|
|
21
|
+
const messages = $derived(readMessages(chat))
|
|
22
|
+
const interrupts = $derived(readInterrupts(chat))
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
{#if children}
|
|
26
|
+
{@render children(messages)}
|
|
27
|
+
{:else}
|
|
28
|
+
{#each messages as message (message.id)}
|
|
29
|
+
<UIMessage {ui} {message} {interrupts} />
|
|
30
|
+
{/each}
|
|
31
|
+
{/if}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getChatContext,
|
|
4
|
+
readInterrupts,
|
|
5
|
+
type UIDescriptor,
|
|
6
|
+
} from './create-ui'
|
|
7
|
+
import { selectMessageUI } from '@tanstack/ai-client/ui'
|
|
8
|
+
import SelectedPart from './selected-part.svelte'
|
|
9
|
+
import type { MessagePart } from '@tanstack/ai-client'
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
ui,
|
|
13
|
+
part,
|
|
14
|
+
}: {
|
|
15
|
+
ui: UIDescriptor
|
|
16
|
+
part: MessagePart
|
|
17
|
+
} = $props()
|
|
18
|
+
|
|
19
|
+
const chat = $derived(getChatContext(ui))
|
|
20
|
+
const selected = $derived(
|
|
21
|
+
selectMessageUI(
|
|
22
|
+
{ id: 'part', role: 'assistant', parts: [part] },
|
|
23
|
+
{ interrupts: readInterrupts(chat), inlineToolNames: [] },
|
|
24
|
+
).parts[0],
|
|
25
|
+
)
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{#if selected}
|
|
29
|
+
<SelectedPart {ui} {selected} />
|
|
30
|
+
{/if}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
setUIContext,
|
|
4
|
+
type ChatUIComponents,
|
|
5
|
+
type UIDescriptor,
|
|
6
|
+
} from './create-ui'
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
ui,
|
|
10
|
+
chat,
|
|
11
|
+
components,
|
|
12
|
+
children,
|
|
13
|
+
}: {
|
|
14
|
+
ui: UIDescriptor
|
|
15
|
+
// ponytail: Svelte components are not generic, so ChatUIHost<TOptions> cannot
|
|
16
|
+
// accept a typed createChat() host with tool-approval interrupts.
|
|
17
|
+
chat: any
|
|
18
|
+
components?: ChatUIComponents<unknown>
|
|
19
|
+
children?: import('svelte').Snippet
|
|
20
|
+
} = $props()
|
|
21
|
+
|
|
22
|
+
setUIContext({
|
|
23
|
+
ui,
|
|
24
|
+
chat,
|
|
25
|
+
components: (components ?? ui.components) as never,
|
|
26
|
+
})
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
{@render children?.()}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
getChatContext,
|
|
4
|
+
getComponentsContext,
|
|
5
|
+
readQueue,
|
|
6
|
+
type UIDescriptor,
|
|
7
|
+
} from './create-ui'
|
|
8
|
+
|
|
9
|
+
let { ui }: { ui: UIDescriptor } = $props()
|
|
10
|
+
|
|
11
|
+
const chat = $derived(getChatContext(ui))
|
|
12
|
+
const comps = $derived(getComponentsContext(ui))
|
|
13
|
+
const items = $derived(readQueue(chat))
|
|
14
|
+
const QueueItem = $derived(comps.components.queue as any)
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#if QueueItem}
|
|
18
|
+
{#each items as item (item.id)}
|
|
19
|
+
<QueueItem {item} />
|
|
20
|
+
{/each}
|
|
21
|
+
{/if}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createChat as createUnboundChat } from './create-chat.svelte'
|
|
2
|
+
import type {
|
|
3
|
+
AnyClientTool,
|
|
4
|
+
InterruptDefinition,
|
|
5
|
+
SchemaInput,
|
|
6
|
+
} from '@tanstack/ai'
|
|
7
|
+
import type { InferredClientContext } from '@tanstack/ai-client'
|
|
8
|
+
import type { CreateChatOptions } from './types'
|
|
9
|
+
|
|
10
|
+
type ChatHookOverrides<
|
|
11
|
+
TTools extends ReadonlyArray<AnyClientTool>,
|
|
12
|
+
TSchema extends SchemaInput | undefined,
|
|
13
|
+
TContext,
|
|
14
|
+
TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,
|
|
15
|
+
> = {
|
|
16
|
+
threadId?: string
|
|
17
|
+
live?: boolean
|
|
18
|
+
forwardedProps?: Record<string, any>
|
|
19
|
+
body?: Record<string, any>
|
|
20
|
+
initialMessages?: CreateChatOptions<
|
|
21
|
+
TTools,
|
|
22
|
+
TSchema,
|
|
23
|
+
TContext,
|
|
24
|
+
TInterrupts
|
|
25
|
+
>['initialMessages']
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Bind chat options once at module scope. The returned `createChat`
|
|
30
|
+
* function creates a chat instance from those options.
|
|
31
|
+
*
|
|
32
|
+
* Pass per-call overrides for instance keys such as `threadId`,
|
|
33
|
+
* `initialMessages`, `live`, and `forwardedProps`. Do not change `tools`,
|
|
34
|
+
* `interrupts`, or `outputSchema` here. Those stay on the factory options.
|
|
35
|
+
*
|
|
36
|
+
* Rename the function at the call site if you already import `createChat` from
|
|
37
|
+
* `@tanstack/ai-svelte`: `const { createChat: createAppChat } = createChatHook(chatOptions)`.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```svelte
|
|
41
|
+
* <script>
|
|
42
|
+
* import { createChatHook } from '@tanstack/ai-svelte'
|
|
43
|
+
*
|
|
44
|
+
* const { createChat } = createChatHook(chatOptions)
|
|
45
|
+
* const chat = createChat({ threadId: 'support-1' })
|
|
46
|
+
* </script>
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function createChatHook<
|
|
50
|
+
const TTools extends ReadonlyArray<AnyClientTool> = any,
|
|
51
|
+
TSchema extends SchemaInput | undefined = undefined,
|
|
52
|
+
TContext = InferredClientContext<TTools>,
|
|
53
|
+
const TInterrupts extends ReadonlyArray<
|
|
54
|
+
InterruptDefinition<any, any, any, any>
|
|
55
|
+
> = readonly [],
|
|
56
|
+
>(options: CreateChatOptions<TTools, TSchema, TContext, TInterrupts>) {
|
|
57
|
+
function createChat(
|
|
58
|
+
overrides?: ChatHookOverrides<TTools, TSchema, TContext, TInterrupts>,
|
|
59
|
+
) {
|
|
60
|
+
if (!overrides) {
|
|
61
|
+
return createUnboundChat(options)
|
|
62
|
+
}
|
|
63
|
+
return createUnboundChat({ ...options, ...overrides })
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { createChat }
|
|
67
|
+
}
|
package/src/index.ts
CHANGED
package/src/ui.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Barrel entry for the `@tanstack/ai-svelte/ui` subpath.
|
|
2
|
+
export { createChatUI, getUIContext } from './chat-ui/create-ui'
|
|
3
|
+
export { createChatHook } from './chat-ui/create-chat-hook'
|
|
4
|
+
export type {
|
|
5
|
+
ChatUIComponents,
|
|
6
|
+
ChatUIFactoryConfig,
|
|
7
|
+
ChatUIHost,
|
|
8
|
+
ChatUIQueueItem,
|
|
9
|
+
InputProps,
|
|
10
|
+
InterruptProps,
|
|
11
|
+
LayoutProps,
|
|
12
|
+
MessageProps,
|
|
13
|
+
PartProps,
|
|
14
|
+
QueueProps,
|
|
15
|
+
ToolProps,
|
|
16
|
+
UIDescriptor,
|
|
17
|
+
} from './chat-ui/create-ui'
|
|
18
|
+
export { default as UIChat } from './chat-ui/ui-chat.svelte'
|
|
19
|
+
export { default as UIProvider } from './chat-ui/ui-provider.svelte'
|
|
20
|
+
export { default as UIMessages } from './chat-ui/ui-messages.svelte'
|
|
21
|
+
export { default as UIMessage } from './chat-ui/ui-message.svelte'
|
|
22
|
+
export { default as UIPart } from './chat-ui/ui-part.svelte'
|
|
23
|
+
export { default as UIInterrupts } from './chat-ui/ui-interrupts.svelte'
|
|
24
|
+
export { default as UIInterrupt } from './chat-ui/ui-interrupt.svelte'
|
|
25
|
+
export { default as UIQueue } from './chat-ui/ui-queue.svelte'
|