mirror of
https://github.com/run-llama/chat-ui.git
synced 2026-07-22 11:45:34 -04:00
feat: render annotation inline (#101)
* feat: render annotation inline * clean up * demo inline * update comment * wait longer for annotaton * add doc * refactor: add annotationsRenderer * fix: format * change contract * fix build * defaultAnnotationRenderers * use zod * separate advanced example * have isInline props for easily custom renderer * fix: lint * fix fomat * introduce: readonly for artifact * add editable example * treat inline artifact as normal artifact * still need outside artifact * fix: duplicate artifact * fix annotations reset * extract artifacts from markdown * update inline artifacts * remove readonly * update example page * fix import * update example * update comment * update advanced example * update wiki inline example * able to custom show inline or not * Create grumpy-geckos-drive.md * fix: format * fix format * fix lint * fix build * chore: clear inline parser * remove useless config * simplify example * remove zod * remove artifact in message annotations * use tryParse to safe extract inline annotations * update demo canvas * remove unused props * update changese * fix: comment --------- Co-authored-by: Marcus Schiesser <mail@marcusschiesser.de>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@llamaindex/chat-ui': minor
|
||||
---
|
||||
|
||||
feat: support inline rendering of annotations and use it for artifacts
|
||||
@@ -46,7 +46,20 @@ const initialMessages: Message[] = [
|
||||
id: 'Yqc9VoIR3ANyzTj3',
|
||||
role: 'assistant',
|
||||
content:
|
||||
'The artifact is a Python implementation of the binary search algorithm, which efficiently searches for a target value in a sorted list.',
|
||||
'The artifact is a Python implementation of the binary search algorithm, which efficiently searches for a target value in a sorted list.' +
|
||||
`\n\`\`\`annotation\n${JSON.stringify({
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'binary_search.py',
|
||||
code: 'def binary_search(arr, target):\n left, right = 0, len(arr) - 1\n while left <= right:\n mid = left + (right - left) // 2\n if arr[mid] == target:\n return mid\n elif arr[mid] < target:\n left = mid + 1\n else:\n right = mid - 1\n return -1\n\n# Example usage:\n# sorted_list = [1, 2, 3, 4, 5]\n# target = 3\n# result = binary_search(sorted_list, target)\n# print(result) # Output: 2',
|
||||
language: 'python',
|
||||
},
|
||||
created_at: 1745480281756,
|
||||
},
|
||||
})}
|
||||
\n\`\`\`\n`,
|
||||
annotations: [
|
||||
{
|
||||
userInput: 'Write binary search algorithm in python',
|
||||
@@ -198,18 +211,6 @@ const initialMessages: Message[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'binary_search.py',
|
||||
code: 'def binary_search(arr, target):\n left, right = 0, len(arr) - 1\n while left <= right:\n mid = left + (right - left) // 2\n if arr[mid] == target:\n return mid\n elif arr[mid] < target:\n left = mid + 1\n else:\n right = mid - 1\n return -1\n\n# Example usage:\n# sorted_list = [1, 2, 3, 4, 5]\n# target = 3\n# result = binary_search(sorted_list, target)\n# print(result) # Output: 2',
|
||||
language: 'python',
|
||||
},
|
||||
created_at: 1745480281756,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: [
|
||||
{
|
||||
@@ -275,7 +276,20 @@ const initialMessages: Message[] = [
|
||||
id: 'yWQHYXgn6WT0oE7J',
|
||||
role: 'assistant',
|
||||
content:
|
||||
'The artifact is a Python implementation of the binary search algorithm that includes logging statements to track the values of the left, right, and mid indices during each step of the search process.',
|
||||
'The artifact is a Python implementation of the binary search algorithm that includes logging statements to track the values of the left, right, and mid indices during each step of the search process.' +
|
||||
`\n\`\`\`annotation\n${JSON.stringify({
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'binary_search.py',
|
||||
code: "import logging\n\nlogging.basicConfig(level=logging.INFO)\n\ndef binary_search(arr, target):\n left, right = 0, len(arr) - 1\n while left <= right:\n mid = left + (right - left) // 2\n logging.info(f'Left: {left}, Right: {right}, Mid: {mid}, Mid Value: {arr[mid]}')\n if arr[mid] == target:\n return mid\n elif arr[mid] < target:\n left = mid + 1\n else:\n right = mid - 1\n return -1\n\n# Example usage\nif __name__ == '__main__':\n arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n target = 7\n result = binary_search(arr, target)\n if result != -1:\n logging.info(f'Target found at index: {result}')\n else:\n logging.info('Target not found')",
|
||||
language: 'python',
|
||||
},
|
||||
created_at: 1745480319651,
|
||||
},
|
||||
})}
|
||||
\n\`\`\`\n`,
|
||||
annotations: [
|
||||
{
|
||||
userInput: 'Add some logs to the code',
|
||||
@@ -455,18 +469,6 @@ const initialMessages: Message[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'binary_search.py',
|
||||
code: "import logging\n\nlogging.basicConfig(level=logging.INFO)\n\ndef binary_search(arr, target):\n left, right = 0, len(arr) - 1\n while left <= right:\n mid = left + (right - left) // 2\n logging.info(f'Left: {left}, Right: {right}, Mid: {mid}, Mid Value: {arr[mid]}')\n if arr[mid] == target:\n return mid\n elif arr[mid] < target:\n left = mid + 1\n else:\n right = mid - 1\n return -1\n\n# Example usage\nif __name__ == '__main__':\n arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n target = 7\n result = binary_search(arr, target)\n if result != -1:\n logging.info(f'Target found at index: {result}')\n else:\n logging.info('Target not found')",
|
||||
language: 'python',
|
||||
},
|
||||
created_at: 1745480319651,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: [
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ Artifacts are interactive, editable content that appears in the chat canvas. The
|
||||
|
||||
The artifact system consists of:
|
||||
|
||||
- **Artifact Annotations** - Data structure for artifact content
|
||||
- **ChatCanvas** - Side panel for displaying artifacts
|
||||
- **Artifact Viewers** - Components for rendering different artifact types
|
||||
- **Version Management** - Track changes and revisions
|
||||
@@ -119,7 +118,11 @@ export async function POST(request: Request) {
|
||||
},
|
||||
}
|
||||
|
||||
controller.enqueue(encoder.encode(`8:${JSON.stringify([artifact])}\\n`))
|
||||
// wrap the annotation in a code block with the language key is 'annotation'
|
||||
const codeBlock = `\n\`\`\`annotation\n${JSON.stringify(codeArtifact)}\n\`\`\`\n`
|
||||
|
||||
// send the artifact with the 0: prefix to make it inline
|
||||
controller.enqueue(encoder.encode(`0:${JSON.stringify(codeBlock)}\\n`))
|
||||
|
||||
// Send follow-up text
|
||||
controller.enqueue(
|
||||
@@ -392,7 +395,6 @@ The canvas automatically appears when artifacts are present:
|
||||
<ChatMessage message={messageWithArtifact}>
|
||||
<ChatMessage.Content>
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.Artifact /> {/* Triggers canvas display */}
|
||||
</ChatMessage.Content>
|
||||
</ChatMessage>
|
||||
```
|
||||
|
||||
@@ -148,7 +148,6 @@ function CustomMessage({ message, isLast }) {
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content>
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.Artifact />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
@@ -189,7 +188,6 @@ Main content area with annotation support:
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.Image />
|
||||
<ChatMessage.Content.Artifact />
|
||||
<ChatMessage.Content.Source />
|
||||
<ChatMessage.Content.Event />
|
||||
<ChatMessage.Content.AgentEvent />
|
||||
|
||||
@@ -87,7 +87,6 @@ function CustomChatMessages() {
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.Artifact />
|
||||
<ChatMessage.Content.Source />
|
||||
<CustomWeatherAnnotation />
|
||||
</ChatMessage.Content>
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/**
|
||||
* Advanced Chat API Route Example
|
||||
*
|
||||
* This example demonstrates advanced streaming features:
|
||||
* - Text streaming with token-by-token delivery
|
||||
* - Both standard annotations (sent after text) and inline annotations (embedded in text)
|
||||
* - Inline annotations are embedded as special code blocks within the markdown stream
|
||||
* - Multiple annotation types: sources, artifacts, and custom components (wiki)
|
||||
*
|
||||
* Use this example to understand how to mix regular content with interactive
|
||||
* components that appear at specific positions in the chat stream.
|
||||
*/
|
||||
|
||||
import { NextResponse, type NextRequest } from 'next/server'
|
||||
|
||||
const TOKEN_DELAY = 30 // 30ms delay between tokens
|
||||
const TEXT_PREFIX = '0:' // vercel ai text prefix
|
||||
const ANNOTATION_PREFIX = '8:' // vercel ai annotation prefix
|
||||
const INLINE_ANNOTATION_KEY = 'annotation' // the language key to detect inline annotation code in markdown
|
||||
const ANNOTATION_DELAY = 1000 // 1 second delay between annotations
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const { messages } = await request.json()
|
||||
const lastMessage = messages[messages.length - 1]
|
||||
|
||||
const stream = fakeChatStream(`User query: "${lastMessage.content}".\n`)
|
||||
|
||||
return new Response(stream, {
|
||||
headers: {
|
||||
'Content-Type': 'text/plain; charset=utf-8',
|
||||
'X-Vercel-AI-Data-Stream': 'v1',
|
||||
Connection: 'keep-alive',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
const detail = (error as Error).message
|
||||
return NextResponse.json({ detail }, { status: 500 })
|
||||
}
|
||||
}
|
||||
|
||||
const SAMPLE_TEXT = [
|
||||
`
|
||||
Welcome to the demo of @llamaindex/chat-ui. Let me show you the different types of components that can be triggered from the server.
|
||||
|
||||
### Markdown with code block
|
||||
|
||||
\`\`\`js
|
||||
const a = 1
|
||||
const b = 2
|
||||
const c = a + b
|
||||
console.log(c)
|
||||
\`\`\`
|
||||
|
||||
`,
|
||||
'\n ### Demo inline annotations \n',
|
||||
'Here are some steps to create a simple wiki app: \n',
|
||||
'1. Create package.json file:',
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
created_at: 1717334400000,
|
||||
inline: true, // this artifact will be only displayed inline in the message
|
||||
data: {
|
||||
file_name: 'package.json',
|
||||
language: 'json',
|
||||
code: `{
|
||||
"name": "wiki-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Wiki application",
|
||||
"main": "wiki.js",
|
||||
"dependencies": {
|
||||
"axios": "^1.0.0",
|
||||
"wiki-api": "^2.1.0"
|
||||
}
|
||||
}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
'2. Check the wiki fetching script:',
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
created_at: 1717334500000,
|
||||
inline: true, // this artifact will be only displayed inline in the message
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'wiki.js',
|
||||
language: 'javascript',
|
||||
code: `async function getWiki(search) {
|
||||
const response = await fetch("/api/wiki?search=" + search);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
}
|
||||
getWiki("What is LlamaIndex?");`,
|
||||
},
|
||||
},
|
||||
},
|
||||
'3. Check the current wiki:',
|
||||
{
|
||||
type: 'wiki',
|
||||
data: {
|
||||
title: 'LlamaIndex',
|
||||
summary: 'LlamaIndex is a framework for building AI applications.',
|
||||
url: 'https://www.llamaindex.ai',
|
||||
category: 'AI',
|
||||
lastUpdated: '2025-06-02',
|
||||
},
|
||||
},
|
||||
'#### 🎯 Demo generating a document artifact',
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
inline: true, // this artifact will be only displayed inline in the message
|
||||
type: 'document',
|
||||
data: {
|
||||
title: 'Sample document',
|
||||
content: `# Getting Started Guide
|
||||
|
||||
## Introduction
|
||||
This comprehensive guide will walk you through everything you need to know to get started with our platform. Whether you're a beginner or an experienced user, you'll find valuable information here.
|
||||
|
||||
## Key Features
|
||||
- **Easy Setup**: Get running in minutes
|
||||
- **Powerful Tools**: Access advanced capabilities
|
||||
- **Great Documentation**: Find answers quickly
|
||||
- **Active Community**: Get help when needed
|
||||
|
||||
## Setup Process
|
||||
1. Install Dependencies
|
||||
First, ensure you have all required dependencies installed on your system.
|
||||
|
||||
2. Configuration
|
||||
Update your configuration files with the necessary settings:
|
||||
- API keys
|
||||
- Environment variables
|
||||
- User preferences
|
||||
|
||||
3. First Steps
|
||||
Begin with basic operations to familiarize yourself with the platform.
|
||||
|
||||
## Best Practices
|
||||
- Always backup your data
|
||||
- Follow security guidelines
|
||||
- Keep your dependencies updated
|
||||
- Document your changes
|
||||
|
||||
## Troubleshooting
|
||||
If you encounter issues, try these steps:
|
||||
1. Check logs for errors
|
||||
2. Verify configurations
|
||||
3. Update to latest version
|
||||
4. Contact support if needed
|
||||
|
||||
## Additional Resources
|
||||
- [Documentation](https://docs.example.com)
|
||||
- [API Reference](https://api.example.com)
|
||||
- [Community Forums](https://community.example.com)
|
||||
|
||||
Feel free to explore and reach out if you need assistance!`,
|
||||
type: 'markdown',
|
||||
},
|
||||
},
|
||||
},
|
||||
'\n\n Please feel free to open the document in the canvas and edit it. The document will be saved as a new version',
|
||||
]
|
||||
|
||||
const SAMPLE_SOURCES = [
|
||||
{
|
||||
type: 'sources',
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: '1', url: '/sample.pdf' },
|
||||
{ id: '2', url: '/sample.pdf' },
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const fakeChatStream = (query: string): ReadableStream => {
|
||||
return new ReadableStream({
|
||||
async start(controller) {
|
||||
const encoder = new TextEncoder()
|
||||
controller.enqueue(
|
||||
encoder.encode(`${TEXT_PREFIX}${JSON.stringify(query)}\n`)
|
||||
)
|
||||
|
||||
// insert inline annotations
|
||||
for (const item of SAMPLE_TEXT) {
|
||||
if (typeof item === 'string') {
|
||||
for (const token of item.split(' ')) {
|
||||
await new Promise(resolve => setTimeout(resolve, TOKEN_DELAY))
|
||||
controller.enqueue(
|
||||
encoder.encode(`${TEXT_PREFIX}${JSON.stringify(`${token} `)}\n`)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
await new Promise(resolve => setTimeout(resolve, ANNOTATION_DELAY))
|
||||
// append inline annotation with 0: prefix
|
||||
const annotationCode = toInlineAnnotationCode(item)
|
||||
controller.enqueue(
|
||||
encoder.encode(`${TEXT_PREFIX}${JSON.stringify(annotationCode)}\n`)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// insert sources in fixed positions
|
||||
for (const item of SAMPLE_SOURCES) {
|
||||
controller.enqueue(
|
||||
encoder.encode(`${ANNOTATION_PREFIX}${JSON.stringify([item])}\n`)
|
||||
)
|
||||
}
|
||||
|
||||
controller.close()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* To append inline annotations to the stream, we need to wrap the annotation in a code block with the language key.
|
||||
* The language key is `annotation` and the code block is wrapped in backticks.
|
||||
* The prefix `0:` ensures it will be treated as inline markdown. Example:
|
||||
*
|
||||
* 0:\`\`\`annotation
|
||||
* \{
|
||||
* "type": "artifact",
|
||||
* "data": \{...\}
|
||||
* \}
|
||||
* \`\`\`
|
||||
*/
|
||||
function toInlineAnnotationCode(item: any) {
|
||||
return `\n\`\`\`${INLINE_ANNOTATION_KEY}\n${JSON.stringify(item)}\n\`\`\`\n`
|
||||
}
|
||||
@@ -1,3 +1,15 @@
|
||||
/**
|
||||
* Basic Chat API Route Example
|
||||
*
|
||||
* This is a simple example demonstrating:
|
||||
* - Text streaming with token-by-token delivery
|
||||
* - Basic markdown content with code blocks
|
||||
* - Custom annotations (weather) sent after text completion
|
||||
* - Standard annotations (sources) sent after text completion
|
||||
*
|
||||
* Use this example as a starting point for implementing basic chat functionality
|
||||
* with \@llamaindex/chat-ui components.
|
||||
*/
|
||||
import { NextResponse, type NextRequest } from 'next/server'
|
||||
|
||||
const TOKEN_DELAY = 30 // 30ms delay between tokens
|
||||
@@ -40,26 +52,6 @@ console.log(c)
|
||||
|
||||
`
|
||||
const SAMPLE_ANNOTATIONS = [
|
||||
{
|
||||
type: 'sources',
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: '1', url: '/sample.pdf' },
|
||||
{ id: '2', url: '/sample.pdf' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'artifact',
|
||||
data: {
|
||||
type: 'code',
|
||||
data: {
|
||||
file_name: 'sample.ts',
|
||||
language: 'typescript',
|
||||
code: 'console.log("Hello, world!");',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'weather',
|
||||
data: {
|
||||
@@ -70,6 +62,15 @@ const SAMPLE_ANNOTATIONS = [
|
||||
windSpeed: 12,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'sources',
|
||||
data: {
|
||||
nodes: [
|
||||
{ id: '1', url: '/sample.pdf' },
|
||||
{ id: '2', url: '/sample.pdf' },
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const fakeChatStream = (query: string): ReadableStream => {
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
useChatUI,
|
||||
} from '@llamaindex/chat-ui'
|
||||
import { Message, useChat } from 'ai/react'
|
||||
import { CustomWeatherAnnotation } from '../components/custom-weather-annotation'
|
||||
import { WeatherAnnotation } from '../components/custom-weather'
|
||||
import { WikiCard } from '@/components/custom-wiki'
|
||||
|
||||
const initialMessages: Message[] = [
|
||||
{
|
||||
@@ -39,7 +40,9 @@ export default function Page(): JSX.Element {
|
||||
|
||||
function ChatExample() {
|
||||
const handler = useChat({
|
||||
api: '/api/chat',
|
||||
// api: '/api/chat',
|
||||
// uncomment this to try advanced example in app/api/chat/advanced/route.ts
|
||||
api: '/api/chat/advanced',
|
||||
initialMessages,
|
||||
})
|
||||
|
||||
@@ -86,10 +89,17 @@ function CustomChatMessages() {
|
||||
</div>
|
||||
</ChatMessage.Avatar>
|
||||
<ChatMessage.Content isLoading={isLoading} append={append}>
|
||||
<ChatMessage.Content.Markdown />
|
||||
<ChatMessage.Content.Artifact />
|
||||
<ChatMessage.Content.Markdown
|
||||
annotationRenderers={{
|
||||
// these annotations are rendered inline with the Markdown text
|
||||
artifact: ChatCanvas.Artifact,
|
||||
wiki: WikiCard,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* annotation components under the Markdown text */}
|
||||
<WeatherAnnotation />
|
||||
<ChatMessage.Content.Source />
|
||||
<CustomWeatherAnnotation />
|
||||
</ChatMessage.Content>
|
||||
<ChatMessage.Actions />
|
||||
</ChatMessage>
|
||||
|
||||
+17
-19
@@ -10,20 +10,32 @@ interface WeatherData {
|
||||
windSpeed: number
|
||||
}
|
||||
|
||||
export function CustomWeatherAnnotation() {
|
||||
// A custom annotation component that is used to display weather information in a chat message
|
||||
// The weather data is extracted from annotations in the message that has type 'weather'
|
||||
export function WeatherAnnotation() {
|
||||
const { message } = useChatMessage()
|
||||
|
||||
const weatherData = getAnnotationData<WeatherData>(message, 'weather')
|
||||
|
||||
if (weatherData.length === 0) return null
|
||||
return <WeatherCard data={weatherData[0]} />
|
||||
}
|
||||
|
||||
const data = weatherData[0]
|
||||
function WeatherCard({ data }: { data: WeatherData }) {
|
||||
const iconMap: Record<string, string> = {
|
||||
sunny: '☀️',
|
||||
cloudy: '☁️',
|
||||
rainy: '🌧️',
|
||||
snowy: '❄️',
|
||||
stormy: '⛈️',
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="my-4 rounded-lg border border-blue-200 bg-blue-50 p-4">
|
||||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-blue-100">
|
||||
<WeatherIcon condition={data.condition} />
|
||||
<span className="text-2xl">
|
||||
{iconMap[data.condition.toLowerCase()] || '🌤️'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold text-blue-900">{data.location}</h3>
|
||||
@@ -46,17 +58,3 @@ export function CustomWeatherAnnotation() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function WeatherIcon({ condition }: { condition: string }) {
|
||||
const iconMap: Record<string, string> = {
|
||||
sunny: '☀️',
|
||||
cloudy: '☁️',
|
||||
rainy: '🌧️',
|
||||
snowy: '❄️',
|
||||
stormy: '⛈️',
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="text-2xl">{iconMap[condition.toLowerCase()] || '🌤️'}</span>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
'use client'
|
||||
|
||||
interface WikiData {
|
||||
title: string
|
||||
summary: string
|
||||
url: string
|
||||
category: string
|
||||
lastUpdated: string
|
||||
}
|
||||
|
||||
// A UI widget that displays wiki information, it can be used inline with markdown text
|
||||
export function WikiCard({ data }: { data: WikiData }) {
|
||||
const iconMap: Record<string, string> = {
|
||||
science: '🧪',
|
||||
history: '📜',
|
||||
technology: '💻',
|
||||
biology: '🧬',
|
||||
geography: '🌍',
|
||||
literature: '📚',
|
||||
art: '🎨',
|
||||
music: '🎵',
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="my-4 rounded-lg border border-green-200 bg-green-50 p-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
|
||||
<span className="text-2xl">
|
||||
{iconMap[data.category.toLowerCase()] || '📖'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="my-0! font-semibold text-green-900">{data.title}</h3>
|
||||
<div className="text-sm text-green-700">
|
||||
<p className="mt-1 whitespace-pre-wrap">{data.summary}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 grid grid-cols-2 gap-4 text-sm text-green-600">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>📂 Category:</span>
|
||||
<span className="font-medium">{data.category}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>📅 Updated:</span>
|
||||
<span className="font-medium">{data.lastUpdated}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<a
|
||||
href={data.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1 text-sm text-green-700 underline hover:text-green-900"
|
||||
>
|
||||
📖 Read full article
|
||||
<span>↗</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -81,10 +81,12 @@
|
||||
"prosemirror-view": "^1.39.2",
|
||||
"react-markdown": "^8.0.7",
|
||||
"rehype-katex": "^7.0.0",
|
||||
"remark": "^14.0.3",
|
||||
"remark": "^15.0.1",
|
||||
"remark-code-import": "^1.2.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
"remark-parse": "^11.0.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"tailwind-merge": "^2.1.0",
|
||||
"vaul": "^0.9.1"
|
||||
},
|
||||
|
||||
@@ -1,37 +1,28 @@
|
||||
import { Message } from '../chat.interface'
|
||||
|
||||
// TODO: add different methods to retrieve annotations from a message - e.g. by parsing its content for inline annotations
|
||||
|
||||
export type MessageAnnotation<T = unknown> = {
|
||||
type: string
|
||||
data: T
|
||||
}
|
||||
import { getInlineAnnotations } from './inline'
|
||||
import { isMessageAnnotation, MessageAnnotation } from './types'
|
||||
import { getVercelAnnotations } from './vercel'
|
||||
|
||||
/**
|
||||
* Gets annotation data directly from a message by type
|
||||
* Type for annotation parser functions
|
||||
*/
|
||||
type AnnotationParser = (message: Message) => unknown[]
|
||||
|
||||
/**
|
||||
* Gets all annotation data from a message by type, combining results from multiple parsers
|
||||
* @param message - The message to extract annotations from
|
||||
* @param type - The annotation type to filter by (can be standard or custom)
|
||||
* @returns Array of data from annotations of the specified type, or null if none found
|
||||
* @param parsers - Array of parser functions to use (defaults to Vercel and inline parsers)
|
||||
* @returns Array of data from annotations of the specified type from all parsers
|
||||
*/
|
||||
|
||||
export function getAnnotationData<T = unknown>(
|
||||
message: Message,
|
||||
type: string
|
||||
type: string,
|
||||
parsers: AnnotationParser[] = [getVercelAnnotations, getInlineAnnotations]
|
||||
): T[] {
|
||||
const annotations = message.annotations
|
||||
if (!annotations) return []
|
||||
const allAnnotations = parsers
|
||||
.flatMap(parser => parser(message))
|
||||
.filter(a => isMessageAnnotation(a)) as MessageAnnotation<T>[]
|
||||
|
||||
const matchingAnnotations = annotations
|
||||
.filter(
|
||||
a =>
|
||||
a &&
|
||||
typeof a === 'object' &&
|
||||
a !== null &&
|
||||
'type' in a &&
|
||||
a.type === type &&
|
||||
'data' in a
|
||||
)
|
||||
.map(a => (a as { data: T }).data)
|
||||
|
||||
return matchingAnnotations
|
||||
return allAnnotations.filter(a => a.type === type).map(a => a.data) as T[]
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
export enum MessageAnnotationType {
|
||||
IMAGE = 'image',
|
||||
DOCUMENT_FILE = 'document_file',
|
||||
SOURCES = 'sources',
|
||||
EVENTS = 'events',
|
||||
SUGGESTED_QUESTIONS = 'suggested_questions',
|
||||
AGENT_EVENTS = 'agent',
|
||||
ARTIFACT = 'artifact',
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './annotations'
|
||||
export * from './data'
|
||||
export * from './types'
|
||||
export * from './inline'
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { remark } from 'remark'
|
||||
import remarkParse from 'remark-parse'
|
||||
import { visit } from 'unist-util-visit'
|
||||
import { Message } from '../chat.interface'
|
||||
import { isMessageAnnotation, MessageAnnotation } from './types'
|
||||
|
||||
const INLINE_ANNOTATION_KEY = 'annotation'
|
||||
|
||||
// parse Markdown and extract code blocks
|
||||
function parseMarkdownCodeBlocks(markdown: string) {
|
||||
const markdownCodeBlocks: {
|
||||
language: string | null
|
||||
code: string
|
||||
}[] = []
|
||||
|
||||
// Parse Markdown to AST using remark
|
||||
const processor = remark().use(remarkParse)
|
||||
const ast = processor.parse(markdown)
|
||||
|
||||
// Visit all code nodes in the AST
|
||||
visit(ast, 'code', (node: any) => {
|
||||
markdownCodeBlocks.push({
|
||||
language: node.lang || null, // Language is stored in node.lang
|
||||
code: node.value, // Code content is stored in node.value
|
||||
})
|
||||
})
|
||||
|
||||
return markdownCodeBlocks
|
||||
}
|
||||
|
||||
// extract all inline annotations from markdown
|
||||
export function getInlineAnnotations(message: Message): unknown[] {
|
||||
const codeBlocks = parseMarkdownCodeBlocks(message.content)
|
||||
return codeBlocks
|
||||
.filter(block => block.language === INLINE_ANNOTATION_KEY)
|
||||
.map(block => tryParse(block.code))
|
||||
.filter(Boolean) // filter out null values
|
||||
}
|
||||
|
||||
// convert annotation to inline markdown
|
||||
export function toInlineAnnotation(annotation: MessageAnnotation) {
|
||||
return `\`\`\`${INLINE_ANNOTATION_KEY}\n${JSON.stringify(annotation)}\n\`\`\``
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and validates an inline annotation from a code block
|
||||
* @param language - The language identifier from the markdown code block
|
||||
* @param codeValue - The raw code content from a markdown code block
|
||||
* @returns The parsed annotation if valid, null if not an annotation or invalid
|
||||
*/
|
||||
export function parseInlineAnnotation(
|
||||
language: string,
|
||||
codeValue: string
|
||||
): MessageAnnotation | null {
|
||||
// Check if this is an inline annotation code block
|
||||
if (language !== INLINE_ANNOTATION_KEY) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
const annotation = tryParse(codeValue)
|
||||
|
||||
if (annotation === null || !isMessageAnnotation(annotation)) {
|
||||
console.warn(
|
||||
`Invalid inline annotation: ${codeValue}, expected an object`
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
return annotation
|
||||
} catch (error) {
|
||||
console.warn(`Failed to parse inline annotation: ${codeValue}`, error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// try to parse the code value as a JSON object and return null if it fails
|
||||
function tryParse(codeValue: string) {
|
||||
try {
|
||||
return JSON.parse(codeValue)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
export enum MessageAnnotationType {
|
||||
IMAGE = 'image',
|
||||
DOCUMENT_FILE = 'document_file',
|
||||
SOURCES = 'sources',
|
||||
EVENTS = 'events',
|
||||
SUGGESTED_QUESTIONS = 'suggested_questions',
|
||||
AGENT_EVENTS = 'agent',
|
||||
ARTIFACT = 'artifact',
|
||||
}
|
||||
|
||||
export type MessageAnnotation<T = unknown> = {
|
||||
type: string
|
||||
data: T
|
||||
}
|
||||
|
||||
export function isMessageAnnotation(
|
||||
annotation: unknown
|
||||
): annotation is MessageAnnotation {
|
||||
return (
|
||||
annotation !== null &&
|
||||
typeof annotation === 'object' &&
|
||||
'type' in annotation &&
|
||||
'data' in annotation &&
|
||||
typeof (annotation as any).type === 'string'
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Message } from '../chat.interface'
|
||||
|
||||
/**
|
||||
* Gets annotation data directly from a message by type
|
||||
* @param message - The message to extract annotations from
|
||||
* @param type - The annotation type to filter by (can be standard or custom)
|
||||
* @returns Array of data from annotations of the specified type, or null if none found
|
||||
*/
|
||||
export function getVercelAnnotations(message: Message): unknown[] {
|
||||
return message.annotations ?? []
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Message } from '../chat.interface'
|
||||
import { MessageAnnotationType } from '../annotations/data'
|
||||
import { getAnnotationData } from '../annotations/annotations'
|
||||
import { MessageAnnotationType, getAnnotationData } from '../annotations'
|
||||
import { getInlineAnnotations } from '../annotations/inline'
|
||||
|
||||
// check if two artifacts are equal by comparing their type and created time
|
||||
export function isEqualArtifact(a: Artifact, b: Artifact) {
|
||||
@@ -15,7 +15,9 @@ export function extractArtifactsFromAllMessages(messages: Message[]) {
|
||||
}
|
||||
|
||||
export function extractArtifactsFromMessage(message: Message): Artifact[] {
|
||||
return getAnnotationData<Artifact>(message, MessageAnnotationType.ARTIFACT)
|
||||
return getAnnotationData<Artifact>(message, MessageAnnotationType.ARTIFACT, [
|
||||
getInlineAnnotations, // only extract artifacts from inline annotations
|
||||
])
|
||||
}
|
||||
|
||||
export type CodeArtifactError = {
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
} from './artifacts'
|
||||
import { Message } from '../chat.interface'
|
||||
import { useChatUI } from '../chat.context'
|
||||
import { toInlineAnnotation } from '../annotations'
|
||||
|
||||
interface ChatCanvasContextType {
|
||||
allArtifacts: Artifact[]
|
||||
@@ -110,13 +111,7 @@ export function ChatCanvasProvider({ children }: { children: ReactNode }) {
|
||||
{
|
||||
id: `restore-success-${Date.now()}`,
|
||||
role: 'assistant',
|
||||
content: `Successfully restored to ${artifact.type} version ${getArtifactVersion(artifact).versionNumber}`,
|
||||
annotations: [
|
||||
{
|
||||
type: 'artifact',
|
||||
data: newArtifact,
|
||||
},
|
||||
],
|
||||
content: `Successfully restored to ${artifact.type} version ${getArtifactVersion(artifact).versionNumber}\n${toInlineAnnotation({ type: 'artifact', data: newArtifact })}`,
|
||||
},
|
||||
] as (Message & { id: string })[]
|
||||
|
||||
@@ -164,8 +159,7 @@ export function ChatCanvasProvider({ children }: { children: ReactNode }) {
|
||||
},
|
||||
{
|
||||
role: 'assistant',
|
||||
content: `Updated content for ${artifact.type} artifact version ${getArtifactVersion(artifact).versionNumber}`,
|
||||
annotations: [{ type: 'artifact', data: newArtifact }],
|
||||
content: `Updated content for ${artifact.type} artifact version ${getArtifactVersion(artifact).versionNumber}\n${toInlineAnnotation({ type: 'artifact', data: newArtifact })}`,
|
||||
},
|
||||
] as (Message & { id: string })[]
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ChatCanvasActions } from './actions'
|
||||
import { CodeArtifactViewer } from './artifacts/code'
|
||||
import { useChatCanvas } from './context'
|
||||
import { DocumentArtifactViewer } from './artifacts/document'
|
||||
import { ArtifactCard } from './artifact-card'
|
||||
|
||||
interface ChatCanvasProps {
|
||||
children?: React.ReactNode
|
||||
@@ -40,6 +41,7 @@ function ChatCanvas({ children, className }: ChatCanvasProps) {
|
||||
|
||||
ChatCanvas.CodeArtifact = CodeArtifactViewer
|
||||
ChatCanvas.DocumentArtifact = DocumentArtifactViewer
|
||||
ChatCanvas.Artifact = ArtifactCard
|
||||
ChatCanvas.Actions = ChatCanvasActions
|
||||
|
||||
export default ChatCanvas
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from 'react'
|
||||
import { ComponentType } from 'react'
|
||||
import {
|
||||
ChatAgentEvents,
|
||||
ChatEvents,
|
||||
@@ -14,13 +14,12 @@ import {
|
||||
SourceData,
|
||||
SourceNode,
|
||||
} from '../widgets/index.js' // this import needs the file extension as it's importing the widget bundle
|
||||
import { MessageAnnotationType } from './annotations/data.js'
|
||||
import { MessageAnnotationType } from './annotations/types.js'
|
||||
import { getAnnotationData } from './annotations/annotations.js'
|
||||
import { extractArtifactsFromMessage } from './canvas/artifacts.js'
|
||||
import { useChatMessage } from './chat-message.context.js'
|
||||
import { useChatUI } from './chat.context.js'
|
||||
import { ArtifactCard } from './canvas/artifact-card.js'
|
||||
import { Message } from './chat.interface.js'
|
||||
import ChatCanvas from './canvas/index.js'
|
||||
|
||||
export function EventAnnotations() {
|
||||
const { message, isLast, isLoading } = useChatMessage()
|
||||
@@ -122,19 +121,9 @@ export function SuggestedQuestionsAnnotations() {
|
||||
)
|
||||
}
|
||||
|
||||
export function ArtifactAnnotations() {
|
||||
const { message } = useChatMessage()
|
||||
const artifacts = useMemo(
|
||||
() => extractArtifactsFromMessage(message),
|
||||
[message]
|
||||
)
|
||||
if (!artifacts?.length) return null
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
{artifacts.map((artifact, index) => (
|
||||
<ArtifactCard key={index} data={artifact} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
export const defaultAnnotationRenderers: Record<
|
||||
string,
|
||||
ComponentType<{ data: any }>
|
||||
> = {
|
||||
artifact: ChatCanvas.Artifact,
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '../widgets/index.js'
|
||||
import {
|
||||
AgentEventAnnotations,
|
||||
ArtifactAnnotations,
|
||||
defaultAnnotationRenderers,
|
||||
DocumentFileAnnotations,
|
||||
EventAnnotations,
|
||||
ImageAnnotations,
|
||||
@@ -69,6 +69,7 @@ interface ChatMarkdownProps extends React.PropsWithChildren {
|
||||
citationComponent?: ComponentType<CitationComponentProps>
|
||||
className?: string
|
||||
languageRenderers?: Record<string, ComponentType<LanguageRendererProps>>
|
||||
annotationRenderers?: Record<string, ComponentType<{ data: any }>>
|
||||
}
|
||||
|
||||
function ChatMessage(props: ChatMessageProps) {
|
||||
@@ -125,7 +126,6 @@ function ChatMessageContent(props: ChatMessageContentProps) {
|
||||
<DocumentFileAnnotations />
|
||||
<SourceAnnotations />
|
||||
<SuggestedQuestionsAnnotations />
|
||||
<ArtifactAnnotations />
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -147,6 +147,9 @@ function ChatMarkdown(props: ChatMarkdownProps) {
|
||||
sources={{ nodes }}
|
||||
citationComponent={props.citationComponent}
|
||||
languageRenderers={props.languageRenderers}
|
||||
annotationRenderers={
|
||||
props.annotationRenderers ?? defaultAnnotationRenderers
|
||||
}
|
||||
className={cn(
|
||||
{
|
||||
'bg-primary text-primary-foreground ml-auto w-fit max-w-[80%] rounded-xl px-3 py-2':
|
||||
@@ -211,7 +214,6 @@ type ComposibleChatMessageContent = typeof ChatMessageContent & {
|
||||
DocumentFile: typeof DocumentFileAnnotations
|
||||
Source: typeof SourceAnnotations
|
||||
SuggestedQuestions: typeof SuggestedQuestionsAnnotations
|
||||
Artifact: typeof ArtifactAnnotations
|
||||
}
|
||||
|
||||
type ComposibleChatMessage = typeof ChatMessage & {
|
||||
@@ -238,7 +240,6 @@ PrimiviteChatMessage.Content.Markdown = ChatMarkdown
|
||||
PrimiviteChatMessage.Content.DocumentFile = DocumentFileAnnotations
|
||||
PrimiviteChatMessage.Content.Source = SourceAnnotations
|
||||
PrimiviteChatMessage.Content.SuggestedQuestions = SuggestedQuestionsAnnotations
|
||||
PrimiviteChatMessage.Content.Artifact = ArtifactAnnotations
|
||||
|
||||
PrimiviteChatMessage.Avatar = ChatMessageAvatar
|
||||
PrimiviteChatMessage.Actions = ChatMessageActions
|
||||
|
||||
@@ -7,6 +7,7 @@ export { default as ChatCanvas } from './chat/canvas'
|
||||
export { default as ChatInput } from './chat/chat-input'
|
||||
export { default as ChatMessages } from './chat/chat-messages'
|
||||
export { default as ChatMessage, ContentPosition } from './chat/chat-message'
|
||||
export { defaultAnnotationRenderers } from './chat/chat-annotations'
|
||||
|
||||
// Context Provider Hooks
|
||||
export { useChatUI } from './chat/chat.context'
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { SourceData } from './chat-sources'
|
||||
import { Citation, CitationComponentProps } from './citation'
|
||||
import { cn } from '../lib/utils'
|
||||
import { parseInlineAnnotation } from '../chat/annotations/inline'
|
||||
|
||||
const MemoizedReactMarkdown: FC<Options> = memo(
|
||||
ReactMarkdown,
|
||||
@@ -85,6 +86,7 @@ export function Markdown({
|
||||
citationComponent: CitationComponent,
|
||||
className: customClassName,
|
||||
languageRenderers,
|
||||
annotationRenderers,
|
||||
}: {
|
||||
content: string
|
||||
sources?: SourceData
|
||||
@@ -92,6 +94,7 @@ export function Markdown({
|
||||
citationComponent?: ComponentType<CitationComponentProps>
|
||||
className?: string
|
||||
languageRenderers?: Record<string, ComponentType<LanguageRendererProps>>
|
||||
annotationRenderers?: Record<string, ComponentType<{ data: any }>>
|
||||
}) {
|
||||
const processedContent = preprocessContent(content)
|
||||
|
||||
@@ -123,6 +126,30 @@ export function Markdown({
|
||||
const language = (match && match[1]) || ''
|
||||
const codeValue = String(children).replace(/\n$/, '')
|
||||
|
||||
const annotation = parseInlineAnnotation(language, codeValue)
|
||||
|
||||
if (annotation) {
|
||||
// Check if we have a specific renderer for it
|
||||
if (annotationRenderers?.[annotation.type]) {
|
||||
const CustomRenderer = annotationRenderers[annotation.type]
|
||||
return (
|
||||
<div className="my-4">
|
||||
<CustomRenderer data={annotation.data} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// If no custom renderer found, render an error message
|
||||
return (
|
||||
<div className="mb-2 max-w-full overflow-hidden rounded-md border border-red-200 bg-red-50 p-3 dark:border-red-800 dark:bg-red-900/20">
|
||||
<div className="overflow-wrap-anywhere whitespace-pre-wrap break-words text-sm text-red-800 dark:text-red-200">
|
||||
<strong>Annotation Render Error:</strong> No renderer found
|
||||
for annotation type “{annotation.type}”.
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (inline) {
|
||||
return (
|
||||
<code className={className} {...props}>
|
||||
|
||||
Generated
+316
-72
@@ -43,7 +43,7 @@ importers:
|
||||
version: 1.1.11(@types/react-dom@18.3.7)(@types/react@18.3.21)(react-dom@18.3.1)(react@18.3.1)
|
||||
ai:
|
||||
specifier: 4.0.0
|
||||
version: 4.0.0(react@18.3.1)(zod@3.25.32)
|
||||
version: 4.0.0(react@18.3.1)(zod@3.25.42)
|
||||
class-variance-authority:
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.1
|
||||
@@ -58,7 +58,7 @@ importers:
|
||||
version: 11.11.1
|
||||
llamaindex:
|
||||
specifier: 0.9.3
|
||||
version: 0.9.3(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(zod@3.25.32)
|
||||
version: 0.9.3(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(zod@3.25.42)
|
||||
lucide-react:
|
||||
specifier: ^0.453.0
|
||||
version: 0.453.0(react@18.3.1)
|
||||
@@ -121,7 +121,7 @@ importers:
|
||||
version: link:../../../packages/chat-ui
|
||||
ai:
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.16(react@19.1.0)(zod@3.25.32)
|
||||
version: 4.3.16(react@19.1.0)(zod@3.25.42)
|
||||
next:
|
||||
specifier: ^15.3.2
|
||||
version: 15.3.2(react-dom@19.1.0)(react@19.1.0)
|
||||
@@ -170,7 +170,7 @@ importers:
|
||||
version: link:../../packages/chat-ui
|
||||
ai:
|
||||
specifier: ^4.3.16
|
||||
version: 4.3.16(react@19.1.0)(zod@3.25.32)
|
||||
version: 4.3.16(react@19.1.0)(zod@3.25.42)
|
||||
next:
|
||||
specifier: ^15.3.2
|
||||
version: 15.3.2(react-dom@19.1.0)(react@19.1.0)
|
||||
@@ -311,8 +311,8 @@ importers:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.1
|
||||
remark:
|
||||
specifier: ^14.0.3
|
||||
version: 14.0.3
|
||||
specifier: ^15.0.1
|
||||
version: 15.0.1
|
||||
remark-code-import:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0
|
||||
@@ -322,9 +322,15 @@ importers:
|
||||
remark-math:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
remark-parse:
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0
|
||||
tailwind-merge:
|
||||
specifier: ^2.1.0
|
||||
version: 2.6.0
|
||||
unist-util-visit:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
vaul:
|
||||
specifier: ^0.9.1
|
||||
version: 0.9.9(@types/react@18.3.21)(react-dom@18.3.1)(react@18.3.1)
|
||||
@@ -370,7 +376,7 @@ importers:
|
||||
|
||||
packages:
|
||||
|
||||
/@ai-sdk/provider-utils@2.0.0(zod@3.25.32):
|
||||
/@ai-sdk/provider-utils@2.0.0(zod@3.25.42):
|
||||
resolution: {integrity: sha512-uITgVJByhtzuQU2ZW+2CidWRmQqTUTp6KADevy+4aRnmILZxY2LCt+UZ/ZtjJqq0MffwkuQPPY21ExmFAQ6kKA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -383,10 +389,10 @@ packages:
|
||||
eventsource-parser: 3.0.1
|
||||
nanoid: 5.1.5
|
||||
secure-json-parse: 2.7.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/provider-utils@2.2.8(zod@3.25.32):
|
||||
/@ai-sdk/provider-utils@2.2.8(zod@3.25.42):
|
||||
resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -395,7 +401,7 @@ packages:
|
||||
'@ai-sdk/provider': 1.1.3
|
||||
nanoid: 3.3.11
|
||||
secure-json-parse: 2.7.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/provider@1.0.0:
|
||||
@@ -412,7 +418,7 @@ packages:
|
||||
json-schema: 0.4.0
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/react@1.0.0(react@18.3.1)(zod@3.25.32):
|
||||
/@ai-sdk/react@1.0.0(react@18.3.1)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-BDrZqQA07Btg64JCuhFvBgYV+tt2B8cXINzEqWknGoxqcwgdE8wSLG2gkXoLzyC2Rnj7oj0HHpOhLUxDCmoKZg==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -424,15 +430,15 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.32)
|
||||
'@ai-sdk/ui-utils': 1.0.0(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.42)
|
||||
'@ai-sdk/ui-utils': 1.0.0(zod@3.25.42)
|
||||
react: 18.3.1
|
||||
swr: 2.3.3(react@18.3.1)
|
||||
throttleit: 2.1.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/react@1.2.12(react@19.1.0)(zod@3.25.32):
|
||||
/@ai-sdk/react@1.2.12(react@19.1.0)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-jK1IZZ22evPZoQW3vlkZ7wvjYGYF+tRBKXtrcolduIkQ/m/sOAVcVeVDUDvh1T91xCnWCdUGCPZg2avZ90mv3g==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -442,15 +448,15 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.32)
|
||||
'@ai-sdk/ui-utils': 1.2.11(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.42)
|
||||
'@ai-sdk/ui-utils': 1.2.11(zod@3.25.42)
|
||||
react: 19.1.0
|
||||
swr: 2.3.3(react@19.1.0)
|
||||
throttleit: 2.1.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/ui-utils@1.0.0(zod@3.25.32):
|
||||
/@ai-sdk/ui-utils@1.0.0(zod@3.25.42):
|
||||
resolution: {integrity: sha512-oXBDIM/0niWeTWyw77RVl505dNxBUDLLple7bTsqo2d3i1UKwGlzBUX8XqZsh7GbY7I6V05nlG0Y8iGlWxv1Aw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -460,21 +466,21 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.0.0
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.32)
|
||||
zod: 3.25.32
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.42)
|
||||
zod: 3.25.42
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.42)
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/ui-utils@1.2.11(zod@3.25.32):
|
||||
/@ai-sdk/ui-utils@1.2.11(zod@3.25.42):
|
||||
resolution: {integrity: sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.23.8
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.1.3
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.32)
|
||||
zod: 3.25.32
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.42)
|
||||
zod: 3.25.42
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.42)
|
||||
dev: false
|
||||
|
||||
/@alloc/quick-lru@5.2.0:
|
||||
@@ -1616,8 +1622,8 @@ packages:
|
||||
'@llamaindex/env': 0.1.28(gpt-tokenizer@2.9.0)
|
||||
'@types/node': 22.15.23
|
||||
magic-bytes.js: 1.12.1
|
||||
zod: 3.24.4
|
||||
zod-to-json-schema: 3.24.5(zod@3.24.4)
|
||||
zod: 3.25.42
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.42)
|
||||
transitivePeerDependencies:
|
||||
- '@aws-crypto/sha256-js'
|
||||
- '@huggingface/transformers'
|
||||
@@ -1666,12 +1672,12 @@ packages:
|
||||
web-tree-sitter: 0.24.7
|
||||
dev: false
|
||||
|
||||
/@llamaindex/openai@0.1.54(gpt-tokenizer@2.9.0)(zod@3.25.32):
|
||||
/@llamaindex/openai@0.1.54(gpt-tokenizer@2.9.0)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-C1r5PleKcIihiDQ9mCCVVBwmub/hT4o8Yi97U9KNR2u0oSOVXfuYWuxx9ViYiiYG4GnnwO5DqmEGzlC32TR5oA==}
|
||||
dependencies:
|
||||
'@llamaindex/core': 0.5.2(gpt-tokenizer@2.9.0)
|
||||
'@llamaindex/env': 0.1.28(gpt-tokenizer@2.9.0)
|
||||
openai: 4.98.0(zod@3.25.32)
|
||||
openai: 4.98.0(zod@3.25.42)
|
||||
transitivePeerDependencies:
|
||||
- '@aws-crypto/sha256-js'
|
||||
- '@huggingface/transformers'
|
||||
@@ -3411,6 +3417,12 @@ packages:
|
||||
'@types/unist': 2.0.11
|
||||
dev: false
|
||||
|
||||
/@types/mdast@4.0.4:
|
||||
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
dev: false
|
||||
|
||||
/@types/mdurl@2.0.0:
|
||||
resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
|
||||
dev: false
|
||||
@@ -3983,7 +3995,7 @@ packages:
|
||||
humanize-ms: 1.2.1
|
||||
dev: false
|
||||
|
||||
/ai@4.0.0(react@18.3.1)(zod@3.25.32):
|
||||
/ai@4.0.0(react@18.3.1)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-cqf2GCaXnOPhUU+Ccq6i+5I0jDjnFkzfq7t6mc0SUSibSa1wDPn5J4p8+Joh2fDGDYZOJ44rpTW9hSs40rXNAw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -3996,17 +4008,17 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.0.0
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.32)
|
||||
'@ai-sdk/react': 1.0.0(react@18.3.1)(zod@3.25.32)
|
||||
'@ai-sdk/ui-utils': 1.0.0(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.0.0(zod@3.25.42)
|
||||
'@ai-sdk/react': 1.0.0(react@18.3.1)(zod@3.25.42)
|
||||
'@ai-sdk/ui-utils': 1.0.0(zod@3.25.42)
|
||||
'@opentelemetry/api': 1.9.0
|
||||
jsondiffpatch: 0.6.0
|
||||
react: 18.3.1
|
||||
zod: 3.25.32
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.32)
|
||||
zod: 3.25.42
|
||||
zod-to-json-schema: 3.24.5(zod@3.25.42)
|
||||
dev: false
|
||||
|
||||
/ai@4.3.16(react@19.1.0)(zod@3.25.32):
|
||||
/ai@4.3.16(react@19.1.0)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-KUDwlThJ5tr2Vw0A1ZkbDKNME3wzWhuVfAOwIvFUzl1TPVDFAXDFTXio3p+jaKneB+dKNCvFFlolYmmgHttG1g==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
@@ -4017,13 +4029,13 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 1.1.3
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.32)
|
||||
'@ai-sdk/react': 1.2.12(react@19.1.0)(zod@3.25.32)
|
||||
'@ai-sdk/ui-utils': 1.2.11(zod@3.25.32)
|
||||
'@ai-sdk/provider-utils': 2.2.8(zod@3.25.42)
|
||||
'@ai-sdk/react': 1.2.12(react@19.1.0)(zod@3.25.42)
|
||||
'@ai-sdk/ui-utils': 1.2.11(zod@3.25.42)
|
||||
'@opentelemetry/api': 1.9.0
|
||||
jsondiffpatch: 0.6.0
|
||||
react: 19.1.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/ajv@6.12.6:
|
||||
@@ -7087,7 +7099,7 @@ packages:
|
||||
wrap-ansi: 9.0.0
|
||||
dev: true
|
||||
|
||||
/llamaindex@0.9.3(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(zod@3.25.32):
|
||||
/llamaindex@0.9.3(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)(zod@3.25.42):
|
||||
resolution: {integrity: sha512-NgMD2eddBxwvrhGsHsma7XxfEda015u4IMzWzUCq94ZnlVfXaRNMe/hWUOkief+huvUV3EkTTSWpSrXhZyiriQ==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
dependencies:
|
||||
@@ -7095,7 +7107,7 @@ packages:
|
||||
'@llamaindex/core': 0.5.2(gpt-tokenizer@2.9.0)
|
||||
'@llamaindex/env': 0.1.28(gpt-tokenizer@2.9.0)
|
||||
'@llamaindex/node-parser': 1.0.2(@llamaindex/core@0.5.2)(@llamaindex/env@0.1.28)(tree-sitter@0.22.4)(web-tree-sitter@0.24.7)
|
||||
'@llamaindex/openai': 0.1.54(gpt-tokenizer@2.9.0)(zod@3.25.32)
|
||||
'@llamaindex/openai': 0.1.54(gpt-tokenizer@2.9.0)(zod@3.25.42)
|
||||
'@types/lodash': 4.17.16
|
||||
'@types/node': 22.15.17
|
||||
ajv: 8.17.1
|
||||
@@ -7284,6 +7296,25 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/mdast-util-from-markdown@2.0.2:
|
||||
resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/unist': 3.0.3
|
||||
decode-named-character-reference: 1.1.0
|
||||
devlop: 1.1.0
|
||||
mdast-util-to-string: 4.0.0
|
||||
micromark: 4.0.2
|
||||
micromark-util-decode-numeric-character-reference: 2.0.2
|
||||
micromark-util-decode-string: 2.0.1
|
||||
micromark-util-normalize-identifier: 2.0.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
unist-util-stringify-position: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/mdast-util-gfm-autolink-literal@1.0.3:
|
||||
resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==}
|
||||
dependencies:
|
||||
@@ -7355,6 +7386,13 @@ packages:
|
||||
unist-util-is: 5.2.1
|
||||
dev: false
|
||||
|
||||
/mdast-util-phrasing@4.1.0:
|
||||
resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
unist-util-is: 6.0.0
|
||||
dev: false
|
||||
|
||||
/mdast-util-to-hast@12.3.0:
|
||||
resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==}
|
||||
dependencies:
|
||||
@@ -7381,12 +7419,32 @@ packages:
|
||||
zwitch: 2.0.4
|
||||
dev: false
|
||||
|
||||
/mdast-util-to-markdown@2.1.2:
|
||||
resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/unist': 3.0.3
|
||||
longest-streak: 3.1.0
|
||||
mdast-util-phrasing: 4.1.0
|
||||
mdast-util-to-string: 4.0.0
|
||||
micromark-util-classify-character: 2.0.1
|
||||
micromark-util-decode-string: 2.0.1
|
||||
unist-util-visit: 5.0.0
|
||||
zwitch: 2.0.4
|
||||
dev: false
|
||||
|
||||
/mdast-util-to-string@3.2.0:
|
||||
resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==}
|
||||
dependencies:
|
||||
'@types/mdast': 3.0.15
|
||||
dev: false
|
||||
|
||||
/mdast-util-to-string@4.0.0:
|
||||
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
dev: false
|
||||
|
||||
/mdurl@2.0.0:
|
||||
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
||||
dev: false
|
||||
@@ -7459,6 +7517,27 @@ packages:
|
||||
uvu: 0.5.6
|
||||
dev: false
|
||||
|
||||
/micromark-core-commonmark@2.0.3:
|
||||
resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
|
||||
dependencies:
|
||||
decode-named-character-reference: 1.1.0
|
||||
devlop: 1.1.0
|
||||
micromark-factory-destination: 2.0.1
|
||||
micromark-factory-label: 2.0.1
|
||||
micromark-factory-space: 2.0.1
|
||||
micromark-factory-title: 2.0.1
|
||||
micromark-factory-whitespace: 2.0.1
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-chunked: 2.0.1
|
||||
micromark-util-classify-character: 2.0.1
|
||||
micromark-util-html-tag-name: 2.0.1
|
||||
micromark-util-normalize-identifier: 2.0.1
|
||||
micromark-util-resolve-all: 2.0.1
|
||||
micromark-util-subtokenize: 2.1.0
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-extension-gfm-autolink-literal@1.0.5:
|
||||
resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==}
|
||||
dependencies:
|
||||
@@ -7551,6 +7630,14 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-factory-destination@2.0.1:
|
||||
resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
|
||||
dependencies:
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-factory-label@1.1.0:
|
||||
resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==}
|
||||
dependencies:
|
||||
@@ -7560,6 +7647,15 @@ packages:
|
||||
uvu: 0.5.6
|
||||
dev: false
|
||||
|
||||
/micromark-factory-label@2.0.1:
|
||||
resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
|
||||
dependencies:
|
||||
devlop: 1.1.0
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-factory-space@1.1.0:
|
||||
resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==}
|
||||
dependencies:
|
||||
@@ -7567,6 +7663,13 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-factory-space@2.0.1:
|
||||
resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
|
||||
dependencies:
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-factory-title@1.1.0:
|
||||
resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==}
|
||||
dependencies:
|
||||
@@ -7576,6 +7679,15 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-factory-title@2.0.1:
|
||||
resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
|
||||
dependencies:
|
||||
micromark-factory-space: 2.0.1
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-factory-whitespace@1.1.0:
|
||||
resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==}
|
||||
dependencies:
|
||||
@@ -7585,6 +7697,15 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-factory-whitespace@2.0.1:
|
||||
resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
|
||||
dependencies:
|
||||
micromark-factory-space: 2.0.1
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-character@1.2.0:
|
||||
resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==}
|
||||
dependencies:
|
||||
@@ -7592,12 +7713,25 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-character@2.1.1:
|
||||
resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-chunked@1.1.0:
|
||||
resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-chunked@2.0.1:
|
||||
resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 2.0.1
|
||||
dev: false
|
||||
|
||||
/micromark-util-classify-character@1.1.0:
|
||||
resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==}
|
||||
dependencies:
|
||||
@@ -7606,6 +7740,14 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-classify-character@2.0.1:
|
||||
resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
|
||||
dependencies:
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-combine-extensions@1.1.0:
|
||||
resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==}
|
||||
dependencies:
|
||||
@@ -7613,12 +7755,25 @@ packages:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-combine-extensions@2.0.1:
|
||||
resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
|
||||
dependencies:
|
||||
micromark-util-chunked: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-decode-numeric-character-reference@1.1.0:
|
||||
resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-decode-numeric-character-reference@2.0.2:
|
||||
resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 2.0.1
|
||||
dev: false
|
||||
|
||||
/micromark-util-decode-string@1.1.0:
|
||||
resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==}
|
||||
dependencies:
|
||||
@@ -7628,26 +7783,55 @@ packages:
|
||||
micromark-util-symbol: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-decode-string@2.0.1:
|
||||
resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
|
||||
dependencies:
|
||||
decode-named-character-reference: 1.1.0
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-decode-numeric-character-reference: 2.0.2
|
||||
micromark-util-symbol: 2.0.1
|
||||
dev: false
|
||||
|
||||
/micromark-util-encode@1.1.0:
|
||||
resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-encode@2.0.1:
|
||||
resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-html-tag-name@1.2.0:
|
||||
resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-html-tag-name@2.0.1:
|
||||
resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-normalize-identifier@1.1.0:
|
||||
resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-normalize-identifier@2.0.1:
|
||||
resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
|
||||
dependencies:
|
||||
micromark-util-symbol: 2.0.1
|
||||
dev: false
|
||||
|
||||
/micromark-util-resolve-all@1.1.0:
|
||||
resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==}
|
||||
dependencies:
|
||||
micromark-util-types: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-resolve-all@2.0.1:
|
||||
resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
|
||||
dependencies:
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-sanitize-uri@1.2.0:
|
||||
resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==}
|
||||
dependencies:
|
||||
@@ -7656,6 +7840,14 @@ packages:
|
||||
micromark-util-symbol: 1.1.0
|
||||
dev: false
|
||||
|
||||
/micromark-util-sanitize-uri@2.0.1:
|
||||
resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
|
||||
dependencies:
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-encode: 2.0.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
dev: false
|
||||
|
||||
/micromark-util-subtokenize@1.1.0:
|
||||
resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==}
|
||||
dependencies:
|
||||
@@ -7665,14 +7857,31 @@ packages:
|
||||
uvu: 0.5.6
|
||||
dev: false
|
||||
|
||||
/micromark-util-subtokenize@2.1.0:
|
||||
resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
|
||||
dependencies:
|
||||
devlop: 1.1.0
|
||||
micromark-util-chunked: 2.0.1
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
dev: false
|
||||
|
||||
/micromark-util-symbol@1.1.0:
|
||||
resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-symbol@2.0.1:
|
||||
resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-types@1.1.0:
|
||||
resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==}
|
||||
dev: false
|
||||
|
||||
/micromark-util-types@2.0.2:
|
||||
resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
|
||||
dev: false
|
||||
|
||||
/micromark@3.2.0:
|
||||
resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==}
|
||||
dependencies:
|
||||
@@ -7697,6 +7906,30 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/micromark@4.0.2:
|
||||
resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
|
||||
dependencies:
|
||||
'@types/debug': 4.1.12
|
||||
debug: 4.4.1
|
||||
decode-named-character-reference: 1.1.0
|
||||
devlop: 1.1.0
|
||||
micromark-core-commonmark: 2.0.3
|
||||
micromark-factory-space: 2.0.1
|
||||
micromark-util-character: 2.1.1
|
||||
micromark-util-chunked: 2.0.1
|
||||
micromark-util-combine-extensions: 2.0.1
|
||||
micromark-util-decode-numeric-character-reference: 2.0.2
|
||||
micromark-util-encode: 2.0.1
|
||||
micromark-util-normalize-identifier: 2.0.1
|
||||
micromark-util-resolve-all: 2.0.1
|
||||
micromark-util-sanitize-uri: 2.0.1
|
||||
micromark-util-subtokenize: 2.1.0
|
||||
micromark-util-symbol: 2.0.1
|
||||
micromark-util-types: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/micromatch@4.0.8:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
|
||||
engines: {node: '>=8.6'}
|
||||
@@ -8054,7 +8287,7 @@ packages:
|
||||
mimic-function: 5.0.1
|
||||
dev: true
|
||||
|
||||
/openai@4.98.0(zod@3.25.32):
|
||||
/openai@4.98.0(zod@3.25.42):
|
||||
resolution: {integrity: sha512-TmDKur1WjxxMPQAtLG5sgBSCJmX7ynTsGmewKzoDwl1fRxtbLOsiR0FA/AOAAtYUmP6azal+MYQuOENfdU+7yg==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -8073,7 +8306,7 @@ packages:
|
||||
form-data-encoder: 1.7.2
|
||||
formdata-node: 4.4.1
|
||||
node-fetch: 2.7.0
|
||||
zod: 3.25.32
|
||||
zod: 3.25.42
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
dev: false
|
||||
@@ -8959,6 +9192,17 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/remark-parse@11.0.0:
|
||||
resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
|
||||
dependencies:
|
||||
'@types/mdast': 4.0.4
|
||||
mdast-util-from-markdown: 2.0.2
|
||||
micromark-util-types: 2.0.2
|
||||
unified: 11.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/remark-rehype@10.1.0:
|
||||
resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==}
|
||||
dependencies:
|
||||
@@ -8968,21 +9212,21 @@ packages:
|
||||
unified: 10.1.2
|
||||
dev: false
|
||||
|
||||
/remark-stringify@10.0.3:
|
||||
resolution: {integrity: sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==}
|
||||
/remark-stringify@11.0.0:
|
||||
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
||||
dependencies:
|
||||
'@types/mdast': 3.0.15
|
||||
mdast-util-to-markdown: 1.5.0
|
||||
unified: 10.1.2
|
||||
'@types/mdast': 4.0.4
|
||||
mdast-util-to-markdown: 2.1.2
|
||||
unified: 11.0.5
|
||||
dev: false
|
||||
|
||||
/remark@14.0.3:
|
||||
resolution: {integrity: sha512-bfmJW1dmR2LvaMJuAnE88pZP9DktIFYXazkTfOIKZzi3Knk9lT0roItIA24ydOucI3bV/g/tXBA6hzqq3FV9Ew==}
|
||||
/remark@15.0.1:
|
||||
resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==}
|
||||
dependencies:
|
||||
'@types/mdast': 3.0.15
|
||||
remark-parse: 10.0.2
|
||||
remark-stringify: 10.0.3
|
||||
unified: 10.1.2
|
||||
'@types/mdast': 4.0.4
|
||||
remark-parse: 11.0.0
|
||||
remark-stringify: 11.0.0
|
||||
unified: 11.0.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
@@ -10107,6 +10351,18 @@ packages:
|
||||
vfile: 5.3.7
|
||||
dev: false
|
||||
|
||||
/unified@11.0.5:
|
||||
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
|
||||
dependencies:
|
||||
'@types/unist': 3.0.3
|
||||
bail: 2.0.2
|
||||
devlop: 1.1.0
|
||||
extend: 3.0.2
|
||||
is-plain-obj: 4.1.0
|
||||
trough: 2.2.0
|
||||
vfile: 6.0.3
|
||||
dev: false
|
||||
|
||||
/unist-util-find-after@5.0.0:
|
||||
resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
|
||||
dependencies:
|
||||
@@ -10592,28 +10848,16 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zod-to-json-schema@3.24.5(zod@3.24.4):
|
||||
/zod-to-json-schema@3.24.5(zod@3.25.42):
|
||||
resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==}
|
||||
peerDependencies:
|
||||
zod: ^3.24.1
|
||||
dependencies:
|
||||
zod: 3.24.4
|
||||
zod: 3.25.42
|
||||
dev: false
|
||||
|
||||
/zod-to-json-schema@3.24.5(zod@3.25.32):
|
||||
resolution: {integrity: sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==}
|
||||
peerDependencies:
|
||||
zod: ^3.24.1
|
||||
dependencies:
|
||||
zod: 3.25.32
|
||||
dev: false
|
||||
|
||||
/zod@3.24.4:
|
||||
resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==}
|
||||
dev: false
|
||||
|
||||
/zod@3.25.32:
|
||||
resolution: {integrity: sha512-OSm2xTIRfW8CV5/QKgngwmQW/8aPfGdaQFlrGoErlgg/Epm7cjb6K6VEyExfe65a3VybUOnu381edLb0dfJl0g==}
|
||||
/zod@3.25.42:
|
||||
resolution: {integrity: sha512-PcALTLskaucbeHc41tU/xfjfhcz8z0GdhhDcSgrCTmSazUuqnYqiXO63M0QUBVwpBlsLsNVn5qHSC5Dw3KZvaQ==}
|
||||
dev: false
|
||||
|
||||
/zwitch@2.0.4:
|
||||
|
||||
Reference in New Issue
Block a user