Compare commits

...

2 Commits

Author SHA1 Message Date
Marcus Schiesser 9aeea6f1ea feat: use ink to render workflow 2025-05-19 13:36:08 +07:00
Marcus Schiesser a882bbf9c8 chore: copied doc-workflow example from CL 2025-05-19 12:40:45 +07:00
5 changed files with 754 additions and 37 deletions
+332
View File
@@ -0,0 +1,332 @@
import { ChatMemoryBuffer, ChatMessage, LLM, MessageContent } from "llamaindex";
import {
agentStreamEvent,
createStatefulMiddleware,
createWorkflow,
startAgentEvent,
stopAgentEvent,
workflowEvent,
} from "@llamaindex/workflow";
import { z } from "zod";
export const DocumentRequirementSchema = z.object({
type: z.enum(["markdown", "html"]),
title: z.string(),
requirement: z.string(),
});
export type DocumentRequirement = z.infer<typeof DocumentRequirementSchema>;
export const UIEventSchema = z.object({
type: z.literal("ui_event"),
data: z.object({
state: z
.enum(["plan", "generate", "completed"])
.describe(
"The current state of the workflow: 'plan', 'generate', or 'completed'.",
),
requirement: z
.string()
.optional()
.describe(
"An optional requirement creating or updating a document, if applicable.",
),
}),
});
export type UIEvent = z.infer<typeof UIEventSchema>;
export const uiEvent = workflowEvent<UIEvent>();
const planEvent = workflowEvent<{
userInput: MessageContent;
context?: string | undefined;
}>();
const generateArtifactEvent = workflowEvent<{
requirement: DocumentRequirement;
}>();
const synthesizeAnswerEvent = workflowEvent<{
requirement: DocumentRequirement;
generatedArtifact: string;
}>();
const ArtifactSchema = z.object({
type: z.literal("artifact"),
data: z.object({
type: z.literal("document"),
data: z.object({
title: z.string(),
content: z.string(),
type: z.string(),
}),
created_at: z.number(),
}),
});
export type Artifact = z.infer<typeof ArtifactSchema>;
export const artifactEvent = workflowEvent<Artifact>();
export function createDocumentArtifactWorkflow(
llm: LLM,
chatHistory: ChatMessage[],
lastArtifact: Artifact | undefined,
) {
const { withState, getContext } = createStatefulMiddleware(() => {
return {
memory: new ChatMemoryBuffer({
llm,
chatHistory: chatHistory,
}),
lastArtifact: lastArtifact,
};
});
const workflow = withState(createWorkflow());
workflow.handle([startAgentEvent], async ({ data: { userInput } }) => {
// Prepare chat history
const { state } = getContext();
// Put user input to the memory
if (!userInput) {
throw new Error("Missing user input to start the workflow");
}
state.memory.put({
role: "user",
content: userInput,
});
return planEvent.with({
userInput,
context: state.lastArtifact
? JSON.stringify(state.lastArtifact)
: undefined,
});
});
workflow.handle([planEvent], async ({ data: planData }) => {
const { sendEvent } = getContext();
const { state } = getContext();
sendEvent(
uiEvent.with({
type: "ui_event",
data: {
state: "plan",
},
}),
);
const user_msg = planData.userInput;
const context = planData.context
? `## The context is: \n${planData.context}\n`
: "";
const prompt = `
You are a documentation analyst responsible for analyzing the user's request and providing requirements for document generation or update.
Follow these instructions:
1. Carefully analyze the conversation history and the user's request to determine what has been done and what the next step should be.
2. From the user's request, provide requirements for the next step of the document generation or update.
3. Do not be verbose; only return the requirements for the next step of the document generation or update.
4. Only the following document types are allowed: "markdown", "html".
5. The requirement should be in the following format:
\`\`\`json
{
"type": "markdown" | "html",
"title": string,
"requirement": string
}
\`\`\`
## Example:
User request: Create a project guideline document.
You should return:
\`\`\`json
{
"type": "markdown",
"title": "Project Guideline",
"requirement": "Generate a Markdown document that outlines the project goals, deliverables, and timeline. Include sections for introduction, objectives, deliverables, and timeline."
}
\`\`\`
User request: Add a troubleshooting section to the guideline.
You should return:
\`\`\`json
{
"type": "markdown",
"title": "Project Guideline",
"requirement": "Add a 'Troubleshooting' section at the end of the document with common issues and solutions."
}
\`\`\`
${context}
Now, please plan for the user's request:
${user_msg}
`;
const response = await llm.complete({
prompt,
});
// Parse the response to DocumentRequirement
const jsonBlock = response.text.match(/```json\s*([\s\S]*?)\s*```/);
if (!jsonBlock) {
throw new Error("No JSON block found in the response.");
}
const requirement = DocumentRequirementSchema.parse(
JSON.parse(jsonBlock[1]),
);
state.memory.put({
role: "assistant",
content: `Planning for the document generation: \n${response.text}`,
});
return generateArtifactEvent.with({
requirement,
});
});
workflow.handle(
[generateArtifactEvent],
async ({ data: { requirement } }) => {
const { sendEvent } = getContext();
const { state } = getContext();
sendEvent(
uiEvent.with({
type: "ui_event",
data: {
state: "generate",
requirement: requirement.requirement,
},
}),
);
const previousArtifact = state.lastArtifact
? JSON.stringify(state.lastArtifact)
: "";
const requirementStr = JSON.stringify(requirement);
const prompt = `
You are a skilled technical writer who can help users with documentation.
You are given a task to generate or update a document for a given requirement.
## Follow these instructions:
**1. Carefully read the user's requirements.**
If any details are ambiguous or missing, make reasonable assumptions and clearly reflect those in your output.
If the previous document is provided:
+ Carefully analyze the document with the request to make the right changes.
+ Avoid making unnecessary changes from the previous document if the request is not to rewrite it from scratch.
**2. For document requests:**
- If the user does not specify a type, default to Markdown.
- Ensure the document is clear, well-structured, and grammatically correct.
- Only generate content relevant to the user's request—do not add extra boilerplate.
**3. Do not be verbose in your response.**
- No other text or comments; only return the document content wrapped by the appropriate code block (\`\`\`markdown or \`\`\`html).
- If the user's request is to update the document, only return the updated document.
**4. Only the following types are allowed: "markdown", "html".**
**5. If there is no change to the document, return the reason without any code block.**
## Example:
\`\`\`markdown
# Project Guideline
## Introduction
...
\`\`\`
The previous content is:
${previousArtifact}
Now, please generate the document for the following requirement:
${requirementStr}
`;
const response = await llm.complete({
prompt,
});
// Extract the document from the response
const docMatch = response.text.match(/```(markdown|html)([\s\S]*)```/);
const generatedContent = response.text;
if (docMatch) {
const content = docMatch[2].trim();
const docType = docMatch[1] as "markdown" | "html";
// Put the generated document to the memory
state.memory.put({
role: "assistant",
content: `Generated document: \n${response.text}`,
});
// To show the Canvas panel for the artifact
sendEvent(
artifactEvent.with({
type: "artifact",
data: {
type: "document",
created_at: Date.now(),
data: {
title: requirement.title,
content: content,
type: docType,
},
},
}),
);
}
return synthesizeAnswerEvent.with({
requirement,
generatedArtifact: generatedContent,
});
},
);
workflow.handle([synthesizeAnswerEvent], async ({ data }) => {
const { sendEvent } = getContext();
const { state } = getContext();
const chatHistory = await state.memory.getMessages();
const messages = [
...chatHistory,
{
role: "system" as const,
content: `
Your responsibility is to explain the work to the user.
If there is no document to update, explain the reason.
If the document is updated, just summarize what changed. Don't need to include the whole document again in the response.
`,
},
];
const responseStream = await llm.chat({
messages,
stream: true,
});
sendEvent(
uiEvent.with({
type: "ui_event",
data: {
state: "completed",
requirement: data.requirement.requirement,
},
}),
);
let response = "";
for await (const chunk of responseStream) {
response += chunk.delta;
sendEvent(
agentStreamEvent.with({
delta: chunk.delta,
response: "",
currentAgentName: "assistant",
raw: chunk,
}),
);
}
return stopAgentEvent.with({
result: response,
});
});
return workflow;
}
+162
View File
@@ -0,0 +1,162 @@
import { openai } from "@llamaindex/openai";
import { Box, render, Text } from "ink";
import React from "react";
import {
agentStreamEvent,
startAgentEvent,
stopAgentEvent,
} from "@llamaindex/workflow";
import {
artifactEvent,
createDocumentArtifactWorkflow,
uiEvent,
UIEvent,
} from "./doc-workflow";
// Import Artifact type (assuming it's exported from doc-workflow.ts)
// If not exported, we'd define a simplified version here or use 'any' temporarily.
// Based on the read file, Artifact is a Zod schema inference.
// We can either import it or define a similar structure for props.
// For now, let's assume it's available from './doc-workflow'.
import type { Artifact } from "./doc-workflow"; // Assuming Artifact is exported
const llm = openai({ model: "gpt-4.1-mini" });
// Define the props for our UI component
interface WorkflowUIProps {
uiEvent: UIEvent;
}
// React component to render the UI using Ink
const WorkflowUI: React.FC<WorkflowUIProps> = ({ uiEvent }) => {
const contentWidth = 60;
const stateColorMap: { [key: string]: string } = {
plan: "yellow",
generate: "blue",
completed: "green",
};
const state = uiEvent.data.state;
const coloredStateText = (
<Text color={stateColorMap[state] || "white"}>{state.toUpperCase()}</Text>
);
const title = "💡 Workflow Event";
const requirementLabel = "Requirement: ";
return (
<Box
borderStyle="round"
borderColor="gray"
flexDirection="column"
paddingX={1}
width={contentWidth + 2 + 2}
>
<Box justifyContent="center" paddingTop={0} paddingBottom={0}>
<Text>{title}</Text>
</Box>
<Box borderStyle="single" borderColor="gray" height={1} marginY={1} />
<Box flexDirection="column">
<Box>
<Text>State: </Text>
{coloredStateText}
</Box>
{uiEvent.data.requirement !== undefined && (
<Box flexDirection="row" marginTop={1}>
<Text>{requirementLabel}</Text>
<Box flexGrow={1} flexShrink={1} marginLeft={1}>
<Text>{uiEvent.data.requirement}</Text>
</Box>
</Box>
)}
</Box>
</Box>
);
};
// --- BEGIN NEW ARTIFACT UI COMPONENT ---
interface ArtifactUIProps {
artifact: Artifact; // Use the imported Artifact type
}
const ArtifactUI: React.FC<ArtifactUIProps> = ({ artifact }) => {
const artifactData = artifact.data.data; // Access nested data
const contentWidth = 80; // Allow more width for artifact content
return (
<Box
borderStyle="round"
borderColor="cyan"
flexDirection="column"
padding={1}
width={contentWidth + 2 + 2} // Account for padding and border
>
<Box justifyContent="center" paddingBottom={1}>
<Text bold color="cyan">
📄 Artifact Generated: {artifactData.title}
</Text>
</Box>
<Box borderStyle="single" borderColor="gray" marginY={1} />
<Box flexDirection="column" gap={1}>
<Box>
<Text bold>Title: </Text>
<Text>{artifactData.title}</Text>
</Box>
<Box>
<Text bold>Type: </Text>
<Text>{artifactData.type}</Text>
</Box>
<Box flexDirection="column">
<Text bold>Content:</Text>
{/* Add a Box for content to allow it to take up space and wrap */}
<Box borderStyle="round" borderColor="gray" padding={1} marginTop={1}>
<Text>{artifactData.content}</Text>
</Box>
</Box>
<Box marginTop={1}>
<Text dimColor>
Created At: {new Date(artifact.data.created_at).toLocaleString()}
</Text>
</Box>
</Box>
</Box>
);
};
async function main() {
const workflow = createDocumentArtifactWorkflow(llm, [], undefined);
const { stream, sendEvent } = workflow.createContext();
const { rerender, unmount, clear } = render(
<Text>Waiting for workflow to start...</Text>,
);
sendEvent(
startAgentEvent.with({ userInput: "Create a project guideline document." }),
);
for await (const event of stream.until(stopAgentEvent)) {
if (agentStreamEvent.include(event)) {
process.stdout.write(event.data.delta);
} else if (uiEvent.include(event)) {
if (event.data.data.state !== "completed") {
rerender(<WorkflowUI uiEvent={event.data} />);
}
} else if (artifactEvent.include(event)) {
rerender(<ArtifactUI artifact={event.data} />);
}
}
unmount();
console.log("\nWorkflow finished.");
}
main().catch(console.error);
+4
View File
@@ -2,6 +2,7 @@
"name": "@llamaindex/examples",
"version": "0.3.16",
"private": true,
"type": "module",
"scripts": {
"lint": "eslint .",
"start": "tsx ./starter.ts"
@@ -63,15 +64,18 @@
"ajv": "^8.17.1",
"commander": "^12.1.0",
"dotenv": "^16.4.5",
"ink": "^5.2.1",
"js-tiktoken": "^1.0.14",
"llamaindex": "^0.11.0",
"mongodb": "6.7.0",
"postgres": "^3.4.4",
"react": "^18.3.1",
"wikipedia": "^2.1.2",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^22.9.0",
"@types/react": "^18.3.21",
"tsx": "^4.19.3",
"typescript": "^5.7.3"
},
+3 -8
View File
@@ -10,13 +10,8 @@
"outDir": "./lib",
"tsBuildInfoFile": "./lib/.tsbuildinfo",
"incremental": true,
"composite": true
"composite": true,
"jsx": "react-jsx"
},
"ts-node": {
"files": true,
"compilerOptions": {
"module": "commonjs"
}
},
"include": ["./**/*.ts"]
"include": ["./**/*.ts", "./**/*.tsx"]
}
+253 -29
View File
@@ -754,7 +754,7 @@ importers:
version: 0.10.0
ai:
specifier: ^4.0.0
version: 4.3.7(react@19.1.0)(zod@3.24.2)
version: 4.3.7(react@18.3.1)(zod@3.24.2)
ajv:
specifier: ^8.17.1
version: 8.17.1
@@ -764,6 +764,9 @@ importers:
dotenv:
specifier: ^16.4.5
version: 16.5.0
ink:
specifier: ^5.2.1
version: 5.2.1(@types/react@18.3.21)(bufferutil@4.0.9)(react@18.3.1)
js-tiktoken:
specifier: ^1.0.14
version: 1.0.19
@@ -776,6 +779,9 @@ importers:
postgres:
specifier: ^3.4.4
version: 3.4.5
react:
specifier: ^18.3.1
version: 18.3.1
wikipedia:
specifier: ^2.1.2
version: 2.1.2
@@ -786,6 +792,9 @@ importers:
'@types/node':
specifier: ^22.9.0
version: 22.9.0
'@types/react':
specifier: ^18.3.21
version: 18.3.21
tsx:
specifier: ^4.19.3
version: 4.19.3
@@ -830,7 +839,7 @@ importers:
version: 1.11.21(@swc/helpers@0.5.17)
jotai:
specifier: 2.10.2
version: 2.10.2(@types/react@19.1.2)(react@19.1.0)
version: 2.10.2(@types/react@19.1.4)(react@19.1.0)
openai:
specifier: ^4
version: 4.94.0(ws@8.18.1(bufferutil@4.0.9))(zod@3.24.4)
@@ -1991,6 +2000,10 @@ packages:
vue:
optional: true
'@alcalzone/ansi-tokenize@0.1.3':
resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==}
engines: {node: '>=14.13.1'}
'@alloc/quick-lru@5.2.0':
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@@ -5923,11 +5936,14 @@ packages:
peerDependencies:
'@types/react': ^19.0.0
'@types/react@18.3.21':
resolution: {integrity: sha512-gXLBtmlcRJeT09/sI4PxVwyrku6SaNUj/6cMubjE6T6XdY1fDmBL7r0nX0jbSZPU/Xr0KuwLLZh6aOYY5d91Xw==}
'@types/react@19.0.10':
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
'@types/react@19.1.2':
resolution: {integrity: sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==}
'@types/react@19.1.4':
resolution: {integrity: sha512-EB1yiiYdvySuIITtD5lhW4yPyJ31RkJkkDw794LaQYrxCSaQV/47y5o1FMC4zF9ZyjUjzJMZwbovEnT5yHTW6g==}
'@types/readable-stream@4.0.18':
resolution: {integrity: sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA==}
@@ -6664,6 +6680,10 @@ packages:
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
auto-bind@5.0.1:
resolution: {integrity: sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
autoprefixer@10.4.21:
resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
engines: {node: ^10 || ^12 || >=14}
@@ -7025,10 +7045,18 @@ packages:
resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==}
engines: {node: '>= 10.0'}
cli-boxes@3.0.0:
resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
engines: {node: '>=10'}
cli-cursor@3.1.0:
resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==}
engines: {node: '>=8'}
cli-cursor@4.0.0:
resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
cli-cursor@5.0.0:
resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
engines: {node: '>=18'}
@@ -7067,6 +7095,10 @@ packages:
code-block-writer@13.0.3:
resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==}
code-excerpt@4.0.0:
resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
codemirror@6.0.1:
resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
@@ -7200,6 +7232,10 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
convert-to-spaces@2.0.1:
resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
convict@6.2.4:
resolution: {integrity: sha512-qN60BAwdMVdofckX7AlohVJ2x9UvjTNoKVXCL2LxFk1l7757EJqf1nySdMkPQer0bt8kQ5lQiyZ9/2NvrFBuwQ==}
engines: {node: '>=6'}
@@ -7635,6 +7671,9 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
es-toolkit@1.38.0:
resolution: {integrity: sha512-OT3AxczYYd3W50bCj4V0hKoOAfqIy9tof0leNQYekEDxVKir3RTVTJOLij7VAe6fsCNsGhC0JqIkURpMXTCSEA==}
es6-error@4.1.1:
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
@@ -7666,6 +7705,10 @@ packages:
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
escape-string-regexp@2.0.0:
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
engines: {node: '>=8'}
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
@@ -8773,6 +8816,10 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
indent-string@5.0.0:
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
engines: {node: '>=12'}
inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
@@ -8786,6 +8833,19 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
ink@5.2.1:
resolution: {integrity: sha512-BqcUyWrG9zq5HIwW6JcfFHsIYebJkWWb4fczNah1goUO0vv5vneIlfwuS85twyJ5hYR/y18FlAYUxrO9ChIWVg==}
engines: {node: '>=18'}
peerDependencies:
'@types/react': '>=18.0.0'
react: '>=18.0.0'
react-devtools-core: ^4.19.1
peerDependenciesMeta:
'@types/react':
optional: true
react-devtools-core:
optional: true
inline-style-parser@0.1.1:
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
@@ -8906,6 +8966,11 @@ packages:
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
is-in-ci@1.0.0:
resolution: {integrity: sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg==}
engines: {node: '>=18'}
hasBin: true
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
@@ -10656,6 +10721,10 @@ packages:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
patch-console@2.0.0:
resolution: {integrity: sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
@@ -11206,6 +11275,12 @@ packages:
'@types/react':
optional: true
react-reconciler@0.29.2:
resolution: {integrity: sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==}
engines: {node: '>=0.10.0'}
peerDependencies:
react: ^18.3.1
react-refresh@0.14.2:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
@@ -11264,6 +11339,10 @@ packages:
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
@@ -11465,6 +11544,10 @@ packages:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
restore-cursor@5.1.0:
resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
engines: {node: '>=18'}
@@ -11600,6 +11683,9 @@ packages:
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
scheduler@0.25.0:
resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
@@ -11890,6 +11976,10 @@ packages:
stack-trace@0.0.10:
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
stack-utils@2.0.6:
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
engines: {node: '>=10'}
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -13145,6 +13235,10 @@ packages:
wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
widest-line@5.0.0:
resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==}
engines: {node: '>=18'}
wikipedia@2.1.2:
resolution: {integrity: sha512-RAYaMpXC9/E873RaSEtlEa8dXK4e0p5k98GKOd210MtkE5emm6fcnwD+N6ZA4cuffjDWagvhaQKtp/mGp2BOVQ==}
engines: {node: '>=10'}
@@ -13323,6 +13417,9 @@ packages:
resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
engines: {node: '>=18'}
yoga-layout@3.2.1:
resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==}
youch@3.3.4:
resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==}
@@ -13401,6 +13498,16 @@ snapshots:
react: 19.1.0
zod: 3.24.2
'@ai-sdk/react@1.2.9(react@18.3.1)(zod@3.24.2)':
dependencies:
'@ai-sdk/provider-utils': 2.2.7(zod@3.24.2)
'@ai-sdk/ui-utils': 1.2.8(zod@3.24.2)
react: 18.3.1
swr: 2.3.3(react@18.3.1)
throttleit: 2.1.0
optionalDependencies:
zod: 3.24.2
'@ai-sdk/react@1.2.9(react@19.0.0)(zod@3.24.4)':
dependencies:
'@ai-sdk/provider-utils': 2.2.7(zod@3.24.4)
@@ -13472,6 +13579,11 @@ snapshots:
transitivePeerDependencies:
- zod
'@alcalzone/ansi-tokenize@0.1.3':
dependencies:
ansi-styles: 6.2.1
is-fullwidth-code-point: 4.0.0
'@alloc/quick-lru@5.2.0': {}
'@ampproject/remapping@2.3.0':
@@ -18711,14 +18823,18 @@ snapshots:
dependencies:
'@types/react': 19.0.10
'@types/react@18.3.21':
dependencies:
'@types/prop-types': 15.7.14
csstype: 3.1.3
'@types/react@19.0.10':
dependencies:
csstype: 3.1.3
'@types/react@19.1.2':
'@types/react@19.1.4':
dependencies:
csstype: 3.1.3
optional: true
'@types/readable-stream@4.0.18':
dependencies:
@@ -19319,7 +19435,7 @@ snapshots:
'@wojtekmaj/react-hooks@1.17.2(react@19.1.0)':
dependencies:
'@types/react': 19.0.10
'@types/react': 19.1.4
react: 19.1.0
'@xhmikosr/archive-type@7.0.0':
@@ -19477,6 +19593,18 @@ snapshots:
- solid-js
- vue
ai@4.3.7(react@18.3.1)(zod@3.24.2):
dependencies:
'@ai-sdk/provider': 1.1.3
'@ai-sdk/provider-utils': 2.2.7(zod@3.24.2)
'@ai-sdk/react': 1.2.9(react@18.3.1)(zod@3.24.2)
'@ai-sdk/ui-utils': 1.2.8(zod@3.24.2)
'@opentelemetry/api': 1.9.0
jsondiffpatch: 0.6.0
zod: 3.24.2
optionalDependencies:
react: 18.3.1
ai@4.3.7(react@19.0.0)(zod@3.24.4):
dependencies:
'@ai-sdk/provider': 1.1.3
@@ -19721,6 +19849,8 @@ snapshots:
asynckit@0.4.0: {}
auto-bind@5.0.1: {}
autoprefixer@10.4.21(postcss@8.5.3):
dependencies:
browserslist: 4.24.4
@@ -20132,10 +20262,16 @@ snapshots:
dependencies:
source-map: 0.6.1
cli-boxes@3.0.0: {}
cli-cursor@3.1.0:
dependencies:
restore-cursor: 3.1.0
cli-cursor@4.0.0:
dependencies:
restore-cursor: 4.0.0
cli-cursor@5.0.0:
dependencies:
restore-cursor: 5.1.0
@@ -20165,6 +20301,10 @@ snapshots:
code-block-writer@13.0.3: {}
code-excerpt@4.0.0:
dependencies:
convert-to-spaces: 2.0.1
codemirror@6.0.1:
dependencies:
'@codemirror/autocomplete': 6.18.6
@@ -20327,6 +20467,8 @@ snapshots:
convert-source-map@2.0.0: {}
convert-to-spaces@2.0.1: {}
convict@6.2.4:
dependencies:
lodash.clonedeep: 4.5.0
@@ -20790,6 +20932,8 @@ snapshots:
is-date-object: 1.1.0
is-symbol: 1.1.1
es-toolkit@1.38.0: {}
es6-error@4.1.1: {}
esast-util-from-estree@2.0.0:
@@ -20889,6 +21033,8 @@ snapshots:
escape-html@1.0.3: {}
escape-string-regexp@2.0.0: {}
escape-string-regexp@4.0.0: {}
escape-string-regexp@5.0.0: {}
@@ -20938,7 +21084,7 @@ snapshots:
'@typescript-eslint/parser': 8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3)
eslint: 9.22.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2))
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-react: 7.37.2(eslint@9.22.0(jiti@2.4.2))
@@ -20968,22 +21114,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.0
enhanced-resolve: 5.18.1
eslint: 9.22.0(jiti@2.4.2)
fast-glob: 3.3.3
get-tsconfig: 4.10.0
is-bun-module: 1.3.0
is-glob: 4.0.3
stable-hash: 0.0.4
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
@@ -21000,6 +21130,22 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.0
enhanced-resolve: 5.18.1
eslint: 9.22.0(jiti@2.4.2)
fast-glob: 3.3.3
get-tsconfig: 4.10.0
is-bun-module: 1.3.0
is-glob: 4.0.3
stable-hash: 0.0.4
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)):
dependencies:
debug: 3.2.7
@@ -21011,14 +21157,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)):
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3)
eslint: 9.22.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2))
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
@@ -21062,7 +21208,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.22.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2)))(eslint@9.22.0(jiti@2.4.2))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -22591,6 +22737,8 @@ snapshots:
imurmurhash@0.1.4: {}
indent-string@5.0.0: {}
inflight@1.0.6:
dependencies:
once: 1.4.0
@@ -22604,6 +22752,39 @@ snapshots:
ini@1.3.8: {}
ink@5.2.1(@types/react@18.3.21)(bufferutil@4.0.9)(react@18.3.1):
dependencies:
'@alcalzone/ansi-tokenize': 0.1.3
ansi-escapes: 7.0.0
ansi-styles: 6.2.1
auto-bind: 5.0.1
chalk: 5.4.1
cli-boxes: 3.0.0
cli-cursor: 4.0.0
cli-truncate: 4.0.0
code-excerpt: 4.0.0
es-toolkit: 1.38.0
indent-string: 5.0.0
is-in-ci: 1.0.0
patch-console: 2.0.0
react: 18.3.1
react-reconciler: 0.29.2(react@18.3.1)
scheduler: 0.23.2
signal-exit: 3.0.7
slice-ansi: 7.1.0
stack-utils: 2.0.6
string-width: 7.2.0
type-fest: 4.40.0
widest-line: 5.0.0
wrap-ansi: 9.0.0
ws: 8.18.1(bufferutil@4.0.9)
yoga-layout: 3.2.1
optionalDependencies:
'@types/react': 18.3.21
transitivePeerDependencies:
- bufferutil
- utf-8-validate
inline-style-parser@0.1.1: {}
inline-style-parser@0.2.4: {}
@@ -22720,6 +22901,8 @@ snapshots:
is-hexadecimal@2.0.1: {}
is-in-ci@1.0.0: {}
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
@@ -22872,9 +23055,9 @@ snapshots:
jiti@2.4.2: {}
jotai@2.10.2(@types/react@19.1.2)(react@19.1.0):
jotai@2.10.2(@types/react@19.1.4)(react@19.1.0):
optionalDependencies:
'@types/react': 19.1.2
'@types/react': 19.1.4
react: 19.1.0
js-base64@3.7.2: {}
@@ -25068,6 +25251,8 @@ snapshots:
parseurl@1.3.3: {}
patch-console@2.0.0: {}
path-browserify@1.0.1: {}
path-exists@4.0.0: {}
@@ -25613,6 +25798,12 @@ snapshots:
optionalDependencies:
'@types/react': 19.0.10
react-reconciler@0.29.2(react@18.3.1):
dependencies:
loose-envify: 1.4.0
react: 18.3.1
scheduler: 0.23.2
react-refresh@0.14.2: {}
react-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.1.0):
@@ -25664,6 +25855,10 @@ snapshots:
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
react@18.3.1:
dependencies:
loose-envify: 1.4.0
react@19.0.0: {}
react@19.1.0: {}
@@ -26004,6 +26199,11 @@ snapshots:
onetime: 5.1.2
signal-exit: 3.0.7
restore-cursor@4.0.0:
dependencies:
onetime: 5.1.2
signal-exit: 3.0.7
restore-cursor@5.1.0:
dependencies:
onetime: 7.0.0
@@ -26221,6 +26421,10 @@ snapshots:
sax@1.4.1: {}
scheduler@0.23.2:
dependencies:
loose-envify: 1.4.0
scheduler@0.25.0: {}
scheduler@0.26.0: {}
@@ -26596,6 +26800,10 @@ snapshots:
stack-trace@0.0.10: {}
stack-utils@2.0.6:
dependencies:
escape-string-regexp: 2.0.0
stackback@0.0.2: {}
stacktracey@2.1.8:
@@ -26849,6 +27057,12 @@ snapshots:
magic-string: 0.30.17
zimmerframe: 1.1.2
swr@2.3.3(react@18.3.1):
dependencies:
dequal: 2.0.3
react: 18.3.1
use-sync-external-store: 1.4.0(react@18.3.1)
swr@2.3.3(react@19.0.0):
dependencies:
dequal: 2.0.3
@@ -27477,6 +27691,10 @@ snapshots:
dependencies:
react: 19.1.0
use-sync-external-store@1.4.0(react@18.3.1):
dependencies:
react: 18.3.1
use-sync-external-store@1.4.0(react@19.0.0):
dependencies:
react: 19.0.0
@@ -28222,6 +28440,10 @@ snapshots:
string-width: 4.2.3
optional: true
widest-line@5.0.0:
dependencies:
string-width: 7.2.0
wikipedia@2.1.2:
dependencies:
axios: 1.8.4
@@ -28409,6 +28631,8 @@ snapshots:
yoctocolors-cjs@2.1.2: {}
yoga-layout@3.2.1: {}
youch@3.3.4:
dependencies:
cookie: 0.7.2