@eventcatalog/core 2.34.7 → 2.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +2 -1
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +1 -1
  5. package/dist/analytics/log-build.js +3 -3
  6. package/dist/{chunk-RHCB6E6X.js → chunk-DGRAYXHN.js} +1 -1
  7. package/dist/{chunk-ZPWE3CVX.js → chunk-HDG7YSFG.js} +9 -0
  8. package/dist/{chunk-F22TOAQN.js → chunk-J4VCEL32.js} +1 -1
  9. package/dist/{chunk-Y6K4D4LS.js → chunk-LP6AXVOF.js} +1 -1
  10. package/dist/constants.cjs +1 -1
  11. package/dist/constants.js +1 -1
  12. package/dist/eventcatalog.cjs +21 -2
  13. package/dist/eventcatalog.config.d.cts +1 -0
  14. package/dist/eventcatalog.config.d.ts +1 -0
  15. package/dist/eventcatalog.js +22 -6
  16. package/dist/features.cjs +44 -2
  17. package/dist/features.d.cts +2 -1
  18. package/dist/features.d.ts +2 -1
  19. package/dist/features.js +6 -3
  20. package/eventcatalog/astro.config.mjs +8 -2
  21. package/eventcatalog/src/components/Lists/ProtocolList.tsx +1 -1
  22. package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +3 -3
  23. package/eventcatalog/src/components/SideBars/DomainSideBar.astro +1 -1
  24. package/eventcatalog/src/components/SideBars/FlowSideBar.astro +2 -2
  25. package/eventcatalog/src/components/SideBars/MessageSideBar.astro +5 -5
  26. package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +2 -2
  27. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +1 -2
  28. package/eventcatalog/src/content.config.ts +13 -2
  29. package/eventcatalog/src/enterprise/collections/chat-prompts.ts +32 -0
  30. package/eventcatalog/src/enterprise/collections/custom-pages.ts +12 -15
  31. package/eventcatalog/src/enterprise/collections/index.ts +2 -0
  32. package/eventcatalog/src/enterprise/custom-documentation/collection.ts +1 -1
  33. package/eventcatalog/src/enterprise/eventcatalog-chat/EventCatalogVectorStore.ts +50 -0
  34. package/eventcatalog/src/enterprise/eventcatalog-chat/components/Chat.tsx +50 -0
  35. package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatMessage.tsx +231 -0
  36. package/eventcatalog/src/enterprise/eventcatalog-chat/components/InputModal.tsx +233 -0
  37. package/eventcatalog/src/enterprise/eventcatalog-chat/components/MentionInput.tsx +211 -0
  38. package/eventcatalog/src/enterprise/eventcatalog-chat/components/WelcomePromptArea.tsx +88 -0
  39. package/eventcatalog/src/enterprise/{ai-assistant/components/ChatWindow.tsx → eventcatalog-chat/components/windows/ChatWindow.client.tsx} +3 -5
  40. package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx +499 -0
  41. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/api/ai/chat.ts +56 -0
  42. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/api/ai/resources.ts +42 -0
  43. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +189 -0
  44. package/eventcatalog/src/enterprise/eventcatalog-chat/utils/ai.ts +151 -0
  45. package/eventcatalog/src/enterprise/eventcatalog-chat/utils/chat-prompts.ts +50 -0
  46. package/eventcatalog/src/pages/chat/index.astro +2 -168
  47. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +1 -0
  48. package/package.json +8 -1
  49. package/eventcatalog/src/enterprise/ai-assistant/components/Chat.tsx +0 -16
  50. /package/eventcatalog/src/{shared-collections.ts → content.config-shared-collections.ts} +0 -0
  51. /package/eventcatalog/src/enterprise/{ai-assistant → eventcatalog-chat}/components/ChatSidebar.tsx +0 -0
  52. /package/eventcatalog/src/enterprise/{ai-assistant → eventcatalog-chat}/components/hooks/ChatProvider.tsx +0 -0
  53. /package/eventcatalog/src/enterprise/{ai-assistant → eventcatalog-chat}/components/workers/document-importer.ts +0 -0
  54. /package/eventcatalog/src/enterprise/{ai-assistant → eventcatalog-chat}/components/workers/engine.ts +0 -0
@@ -0,0 +1,189 @@
1
+ ---
2
+ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
+ import Chat from '@enterprise/eventcatalog-chat/components/Chat';
4
+ import { getChatPromptsGroupedByCategory } from '@enterprise/eventcatalog-chat/utils/chat-prompts';
5
+ import config from '@config';
6
+ import path from 'node:path';
7
+ import fs from 'node:fs';
8
+ import { isEventCatalogChatEnabled } from '@utils/feature';
9
+ import { Code } from 'astro-expressive-code/components';
10
+ import { getDomains } from '@utils/collections/domains';
11
+ import { getEvents } from '@utils/events';
12
+ import { getCommands } from '@utils/commands';
13
+ import { getServices } from '@utils/collections/services';
14
+
15
+ const isEnabled = config.chat?.enabled || false;
16
+ const chatConfig = config.chat || {};
17
+
18
+ const PROJECT_DIR = path.resolve(process.env.PROJECT_DIR || process.cwd());
19
+ const GENERATED_AI_DIR = path.resolve(PROJECT_DIR, 'public/ai');
20
+
21
+ const directoryExists = fs.existsSync(GENERATED_AI_DIR);
22
+
23
+ // Get all information for the mention input
24
+ const [events, commands, services, domains] = await Promise.all([
25
+ getEvents({ getAllVersions: false }),
26
+ getCommands({ getAllVersions: false }),
27
+ getServices({ getAllVersions: false }),
28
+ getDomains({ getAllVersions: false }),
29
+ ]);
30
+ const allItems = [...events, ...commands, ...services, ...domains];
31
+
32
+ const chatPrompts = await getChatPromptsGroupedByCategory();
33
+
34
+ const resources = allItems.map((item) => ({ id: item.data.id, type: item.collection, name: item.data.name }));
35
+
36
+ const generatorConfig = `
37
+ generators: [
38
+ [
39
+ "@eventcatalog/generator-ai", {
40
+ // If you want to chunk files into smaller chunks, set this to true
41
+ splitMarkdownFiles: true
42
+ }
43
+ ],
44
+ ],
45
+ `;
46
+
47
+ if (!isEventCatalogChatEnabled()) {
48
+ return Astro.redirect(buildUrl('/chat/feature'));
49
+ }
50
+ ---
51
+
52
+ <VerticalSideBarLayout title="AI Chat">
53
+ <div class="flex h-[calc(100vh-60px)] bg-white">
54
+ {
55
+ isEnabled ? (
56
+ directoryExists ? (
57
+ <>
58
+ <div id="browserWarning" class="flex items-center justify-center w-full p-4 sm:p-8" style="display: none;">
59
+ <div class="max-w-2xl text-center bg-yellow-100 text-yellow-800 px-8 py-6 rounded-lg shadow-md">
60
+ <h2 class="text-2xl font-bold mb-4">Unsupported Browser</h2>
61
+ <p>
62
+ EventCatalog AI Assistant uses LLM models in the browser which is{' '}
63
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/GPU" class="text-blue-500 hover:underline">
64
+ only supported in Chrome and Edge browsers
65
+ </a>
66
+ . <br />
67
+ Please switch to a supported browser for the best experience.
68
+ </p>
69
+ </div>
70
+ </div>
71
+ <div id="chatContainer" class="w-full">
72
+ <Chat client:only="react" chatConfig={chatConfig} resources={resources} chatPrompts={chatPrompts} />
73
+ </div>
74
+ </>
75
+ ) : (
76
+ <div class="flex items-center justify-center w-full p-4 sm:p-8">
77
+ <div class="max-w-2xl text-center">
78
+ <h2 class="text-2xl font-bold text-gray-900 mb-4">EventCatalog AI Assistant Setup Required</h2>
79
+ <p class="text-gray-600 mb-6">
80
+ To use the AI Assistant, you need to generate the AI data first.
81
+ <br />
82
+ Please install the plugin and run the generator command to generate the AI data.
83
+ </p>
84
+
85
+ <div class="text-left space-y-4">
86
+ <div class="space-y-2">
87
+ <h2 class="text-lg font-semibold text-left">1. Install the generator</h2>
88
+ <Code code={`npm i @eventcatalog/generator-ai`} lang="bash" frame="terminal" />
89
+ </div>
90
+
91
+ <div class="space-y-2">
92
+ <h2 class="text-lg font-semibold text-left">2. Configure the generator</h2>
93
+ <Code code={generatorConfig} lang="javascript" frame="terminal" title="eventcatalog.config.js" />
94
+ </div>
95
+
96
+ <div class="space-y-2">
97
+ <h2 class="text-lg font-semibold text-left">3. Generate the AI data</h2>
98
+ <Code code={`npm run generate`} lang="bash" frame="none" />
99
+ </div>
100
+ <p class="text-gray-600 text-sm mt-2">
101
+ After running the generator, a new folder called <code class="bg-gray-100 p-1 rounded-md">generated-ai</code>{' '}
102
+ will be created in your project.
103
+ </p>
104
+
105
+ <p class="text-gray-600 text-sm mt-2">Once done, refresh this page.</p>
106
+ </div>
107
+ </div>
108
+ </div>
109
+ )
110
+ ) : (
111
+ <div class="flex items-center justify-center w-full p-4 sm:p-8">
112
+ <div class="max-w-6xl flex flex-col md:flex-row gap-8 md:gap-12 items-center">
113
+ {/* Left side - Illustration */}
114
+ <div class="flex-1">
115
+ <img
116
+ src="/images/ai-placeholder.png"
117
+ alt="AI Assistant Illustration"
118
+ class="w-full max-w-sm md:max-w-md mx-auto rounded-lg shadow-lg"
119
+ />
120
+ </div>
121
+
122
+ {/* Right side - Content */}
123
+ <div class="flex-1">
124
+ <h2 class="text-2xl md:text-3xl font-bold text-gray-900 mb-4">EventCatalog AI Assistant</h2>
125
+ <p class="text-gray-600 mb-6 text-base md:text-lg">
126
+ Chat with your catalog to quickly find information, understand relationships, and get instant answers about your
127
+ architecture. Our AI-powered assistant makes exploring your event catalog faster and more intuitive than ever.
128
+ </p>
129
+
130
+ <div class="bg-gray-700 rounded-lg p-4 md:p-6 mb-4">
131
+ <h3 class="text-lg text-white font-semibold mb-3">Quick Setup</h3>
132
+ <Code code={`npm install @eventcatalog/generator-ai`} lang="bash" frame="none" />
133
+ <a
134
+ href="https://www.eventcatalog.dev/features/ai-assistant"
135
+ class="inline-flex items-center text-sm text-white mt-4"
136
+ >
137
+ Learn more about setup →
138
+ </a>
139
+ </div>
140
+ <p class="text-gray-600 mb-6 text-sm">
141
+ Your data stays private and secure - all processing happens locally on your machine.
142
+ </p>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ )
147
+ }
148
+ </div>
149
+ </VerticalSideBarLayout>
150
+
151
+ <script>
152
+ function checkBrowser() {
153
+ const userAgent = navigator.userAgent.toLowerCase();
154
+ const isChrome = /chrome/.test(userAgent) && !/edg/.test(userAgent);
155
+ const isEdge = /edg/.test(userAgent);
156
+
157
+ const warningElement = document.getElementById('browserWarning') as HTMLElement;
158
+ const chatContainer = document.getElementById('chatContainer') as HTMLElement;
159
+
160
+ if (warningElement && chatContainer) {
161
+ if (!isChrome && !isEdge) {
162
+ warningElement.style.display = 'flex';
163
+ chatContainer.style.display = 'none';
164
+ } else {
165
+ warningElement.style.display = 'none';
166
+ chatContainer.style.display = 'block';
167
+ }
168
+ }
169
+ }
170
+
171
+ // Run check when DOM is loaded
172
+ document.addEventListener('DOMContentLoaded', checkBrowser);
173
+ </script>
174
+
175
+ <style>
176
+ .loading-status.ready {
177
+ background-color: rgb(240 253 244); /* light green bg */
178
+ color: rgb(22 163 74); /* green text */
179
+ }
180
+
181
+ .loading-status.hidden {
182
+ display: none;
183
+ }
184
+
185
+ /* Add smooth scrolling behavior */
186
+ .scroll-smooth {
187
+ scroll-behavior: smooth;
188
+ }
189
+ </style>
@@ -0,0 +1,151 @@
1
+ import { streamText, type CoreMessage, type Message } from 'ai';
2
+ import { openai } from '@ai-sdk/openai';
3
+ import { EventCatalogVectorStore, type Resource } from '@enterprise/eventcatalog-chat/EventCatalogVectorStore';
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import config from '@config';
7
+
8
+ const AI_EMBEDDINGS_PATH = path.join(process.env.PROJECT_DIR || process.cwd(), 'public/ai');
9
+
10
+ const documents = JSON.parse(fs.readFileSync(path.join(AI_EMBEDDINGS_PATH, 'documents.json'), 'utf8'));
11
+ const embeddings = JSON.parse(fs.readFileSync(path.join(AI_EMBEDDINGS_PATH, 'embeddings.json'), 'utf8'));
12
+
13
+ const OpenAIChatModelIds = [
14
+ 'o1',
15
+ 'o1-2024-12-17',
16
+ 'o1-mini',
17
+ 'o1-mini-2024-09-12',
18
+ 'o1-preview',
19
+ 'o1-preview-2024-09-12',
20
+ 'o3-mini',
21
+ 'o3-mini-2025-01-31',
22
+ 'o3',
23
+ 'o3-2025-04-16',
24
+ 'o4-mini',
25
+ 'o4-mini-2025-04-16',
26
+ 'gpt-4.1',
27
+ 'gpt-4.1-2025-04-14',
28
+ 'gpt-4.1-mini',
29
+ 'gpt-4.1-mini-2025-04-14',
30
+ 'gpt-4.1-nano',
31
+ 'gpt-4.1-nano-2025-04-14',
32
+ 'gpt-4o',
33
+ 'gpt-4o-2024-05-13',
34
+ 'gpt-4o-2024-08-06',
35
+ 'gpt-4o-2024-11-20',
36
+ 'gpt-4o-audio-preview',
37
+ 'gpt-4o-audio-preview-2024-10-01',
38
+ 'gpt-4o-audio-preview-2024-12-17',
39
+ 'gpt-4o-search-preview',
40
+ 'gpt-4o-search-preview-2025-03-11',
41
+ 'gpt-4o-mini-search-preview',
42
+ 'gpt-4o-mini-search-preview-2025-03-11',
43
+ 'gpt-4o-mini',
44
+ 'gpt-4o-mini-2024-07-18',
45
+ 'gpt-4-turbo',
46
+ 'gpt-4-turbo-2024-04-09',
47
+ 'gpt-4-turbo-preview',
48
+ 'gpt-4-0125-preview',
49
+ 'gpt-4-1106-preview',
50
+ 'gpt-4',
51
+ 'gpt-4-0613',
52
+ 'gpt-4.5-preview',
53
+ 'gpt-4.5-preview-2025-02-27',
54
+ 'gpt-3.5-turbo-0125',
55
+ 'gpt-3.5-turbo',
56
+ 'gpt-3.5-turbo-1106',
57
+ 'chatgpt-4o-latest',
58
+ ];
59
+
60
+ export const getResources = async (question: string) => {
61
+ const vectorStore = await EventCatalogVectorStore.create(documents, embeddings);
62
+ const resources = await vectorStore.getEventCatalogResources(question);
63
+ return resources;
64
+ };
65
+
66
+ export async function askQuestion(
67
+ question: string = 'Tell me more about the Payment domain',
68
+ historicMessages: Message[] = [],
69
+ systemPromptOverride?: string
70
+ ) {
71
+ const resources = await getResources(question);
72
+
73
+ const baseSystemPrompt = `You are an expert in event-driven architecture and domain-driven design, specializing in documentation for EventCatalog.
74
+
75
+ You assist developers, architects, and business stakeholders who need information about their event-driven system catalog. You help with questions about:
76
+ - Events (asynchronous messages that notify about something that has happened)
77
+ - Commands (requests to perform an action)
78
+ - Queries (requests for information)
79
+ - Services (bounded contexts or applications that produce/consume events)
80
+ - Domains (business capabilities or functional areas)
81
+
82
+ Your primary goal is to help users understand their event-driven system through accurate documentation interpretation.
83
+
84
+ IMPORTANT RULES:
85
+ 1. Resources will be provided to you in <resource> tags. ONLY use these resources to answer questions.
86
+ 2. NEVER include ANY <resource> tags in your responses. This is a strict requirement.
87
+ 3. ALWAYS refer to resources by their name/ID/title attributes only.
88
+ 4. If asked about specific resource types (e.g., "What domains do we have?"), simply list their names without elaboration.
89
+ 5. NEVER invent or make up resources that aren't provided to you.
90
+ 6. When you return code examples, make sure you always return them in markdown code blocks.
91
+
92
+ RESPONSE FORMAT EXAMPLES:
93
+ ✓ CORRECT: "The SubscriptionService produces the UserSubscribed event."
94
+ ✗ INCORRECT: "<resource id="SubscriptionService">...</resource> produces events."
95
+
96
+ When responding:
97
+ 1. Use only information from the provided resources.
98
+ 2. Explain connections between resources when relevant.
99
+ 3. Use appropriate technical terminology.
100
+ 4. Use clear formatting with headings and bullet points when helpful.
101
+ 5. State clearly when information is missing rather than making assumptions.
102
+ 6. Don't provide code examples unless specifically requested.
103
+
104
+ Your primary goal is to help users understand their event-driven system through accurate documentation interpretation.
105
+
106
+ If you have additional context, use it to answer the question.`;
107
+
108
+ const resourceStrings = resources.map((resource: Resource) => {
109
+ const attributes = Object.entries(resource)
110
+ .filter(([key, value]) => key !== 'markdown' && key !== 'loc' && value !== undefined && value !== null)
111
+ .map(([key, value]) => `${key}="${String(value).replace(/"/g, '&quot;')}"`) // Escape quotes in values
112
+ .join(' ');
113
+ return `<resource ${attributes} />`;
114
+ });
115
+
116
+ const resourceContext = `==========
117
+ ${resourceStrings.join('\n')}
118
+ ==========`;
119
+
120
+ let systemPrompt = systemPromptOverride ? systemPromptOverride : baseSystemPrompt;
121
+ systemPrompt += `\n\n${resourceContext}`;
122
+
123
+ // add 1 more rule
124
+ systemPrompt += `\n\n1. When you return code examples, make sure you always return them in markdown code blocks.`;
125
+ const messages = [
126
+ {
127
+ role: 'system',
128
+ content: systemPrompt, // Fixed: Was qaPrompt
129
+ },
130
+ ...historicMessages,
131
+ {
132
+ role: 'user',
133
+ content: question,
134
+ },
135
+ ] as CoreMessage[];
136
+
137
+ const model = config?.chat?.model || 'o4-mini';
138
+
139
+ if (!OpenAIChatModelIds.includes(model)) {
140
+ throw new Error(`Invalid model: ${model}, please use one of the following models: ${OpenAIChatModelIds.join(', ')}`);
141
+ }
142
+
143
+ return await streamText({
144
+ model: openai(model),
145
+ messages: messages,
146
+ temperature: 0.2,
147
+ topP: 1,
148
+ frequencyPenalty: 0,
149
+ presencePenalty: 0,
150
+ });
151
+ }
@@ -0,0 +1,50 @@
1
+ import { getCollection } from 'astro:content';
2
+ import type { CollectionEntry } from 'astro:content';
3
+
4
+ export type ChatPrompt = CollectionEntry<'chatPrompts'>;
5
+
6
+ // Update cache to store both versions
7
+ let cachedChatPrompts: Record<string, ChatPrompt[]> = {
8
+ allVersions: [],
9
+ currentVersions: [],
10
+ };
11
+
12
+ export const getChatPrompts = async (): Promise<ChatPrompt[]> => {
13
+ const cacheKey = 'allVersions';
14
+
15
+ // Check if we have cached domains for this specific getAllVersions value
16
+ if (cachedChatPrompts[cacheKey].length > 0) {
17
+ return cachedChatPrompts[cacheKey];
18
+ }
19
+
20
+ const prompts = await getCollection('chatPrompts');
21
+
22
+ return prompts;
23
+ };
24
+
25
+ export type ChatPromptCategoryGroup = {
26
+ label: string;
27
+ icon?: string;
28
+ items: ChatPrompt[];
29
+ };
30
+
31
+ export const getChatPromptsGroupedByCategory = async (): Promise<ChatPromptCategoryGroup[]> => {
32
+ const prompts = await getChatPrompts();
33
+
34
+ const grouped = prompts.reduce(
35
+ (acc, prompt) => {
36
+ const { id, label, icon } = prompt.data.category;
37
+
38
+ if (!acc[id]) {
39
+ acc[id] = { label, icon, items: [] };
40
+ }
41
+
42
+ acc[id].items.push(prompt);
43
+ return acc;
44
+ },
45
+ {} as Record<string, { label: string; icon?: string; items: ChatPrompt[] }>
46
+ );
47
+
48
+ // Convert the grouped object into the desired array format
49
+ return Object.values(grouped);
50
+ };
@@ -1,171 +1,5 @@
1
1
  ---
2
- import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
- import Chat from '@enterprise/ai-assistant/components/Chat';
4
- import config from '@config';
5
- import path from 'node:path';
6
- import fs from 'node:fs';
7
- import { isEventCatalogChatEnabled } from '@utils/feature';
8
- import { Code } from 'astro-expressive-code/components';
9
- import { buildUrl } from '@utils/url-builder';
10
- const isEnabled = config.chat?.enabled || false;
11
- const chatConfig = config.chat || {};
12
-
13
- const PROJECT_DIR = path.resolve(process.env.PROJECT_DIR || process.cwd());
14
- const GENERATED_AI_DIR = path.resolve(PROJECT_DIR, 'public/ai');
15
-
16
- const directoryExists = fs.existsSync(GENERATED_AI_DIR);
17
-
18
- const generatorConfig = `
19
- generators: [
20
- [
21
- "@eventcatalog/generator-ai", {
22
- // If you want to chunk files into smaller chunks, set this to true
23
- splitMarkdownFiles: true
24
- }
25
- ],
26
- ],
27
- `;
28
-
29
- if (!isEventCatalogChatEnabled()) {
30
- return Astro.redirect(buildUrl('/chat/feature'));
31
- }
2
+ import ChatPage from '@enterprise/eventcatalog-chat/pages/chat/index.astro';
32
3
  ---
33
4
 
34
- <VerticalSideBarLayout title="AI Chat">
35
- <div class="flex h-[calc(100vh-60px)] bg-white">
36
- {
37
- isEnabled ? (
38
- directoryExists ? (
39
- <>
40
- <div id="browserWarning" class="flex items-center justify-center w-full p-4 sm:p-8" style="display: none;">
41
- <div class="max-w-2xl text-center bg-yellow-100 text-yellow-800 px-8 py-6 rounded-lg shadow-md">
42
- <h2 class="text-2xl font-bold mb-4">Unsupported Browser</h2>
43
- <p>
44
- EventCatalog AI Assistant uses LLM models in the browser which is{' '}
45
- <a href="https://developer.mozilla.org/en-US/docs/Web/API/GPU" class="text-blue-500 hover:underline">
46
- only supported in Chrome and Edge browsers
47
- </a>
48
- . <br />
49
- Please switch to a supported browser for the best experience.
50
- </p>
51
- </div>
52
- </div>
53
- <div id="chatContainer" class="w-full">
54
- <Chat client:only="react" chatConfig={chatConfig} />
55
- </div>
56
- </>
57
- ) : (
58
- <div class="flex items-center justify-center w-full p-4 sm:p-8">
59
- <div class="max-w-2xl text-center">
60
- <h2 class="text-2xl font-bold text-gray-900 mb-4">EventCatalog AI Assistant Setup Required</h2>
61
- <p class="text-gray-600 mb-6">
62
- To use the AI Assistant, you need to generate the AI data first.
63
- <br />
64
- Please install the plugin and run the generator command to generate the AI data.
65
- </p>
66
-
67
- <div class="text-left space-y-4">
68
- <div class="space-y-2">
69
- <h2 class="text-lg font-semibold text-left">1. Install the generator</h2>
70
- <Code code={`npm i @eventcatalog/generator-ai`} lang="bash" frame="terminal" />
71
- </div>
72
-
73
- <div class="space-y-2">
74
- <h2 class="text-lg font-semibold text-left">2. Configure the generator</h2>
75
- <Code code={generatorConfig} lang="javascript" frame="terminal" title="eventcatalog.config.js" />
76
- </div>
77
-
78
- <div class="space-y-2">
79
- <h2 class="text-lg font-semibold text-left">3. Generate the AI data</h2>
80
- <Code code={`npm run generate`} lang="bash" frame="none" />
81
- </div>
82
- <p class="text-gray-600 text-sm mt-2">
83
- After running the generator, a new folder called <code class="bg-gray-100 p-1 rounded-md">generated-ai</code>{' '}
84
- will be created in your project.
85
- </p>
86
-
87
- <p class="text-gray-600 text-sm mt-2">Once done, refresh this page.</p>
88
- </div>
89
- </div>
90
- </div>
91
- )
92
- ) : (
93
- <div class="flex items-center justify-center w-full p-4 sm:p-8">
94
- <div class="max-w-6xl flex flex-col md:flex-row gap-8 md:gap-12 items-center">
95
- {/* Left side - Illustration */}
96
- <div class="flex-1">
97
- <img
98
- src="/images/ai-placeholder.png"
99
- alt="AI Assistant Illustration"
100
- class="w-full max-w-sm md:max-w-md mx-auto rounded-lg shadow-lg"
101
- />
102
- </div>
103
-
104
- {/* Right side - Content */}
105
- <div class="flex-1">
106
- <h2 class="text-2xl md:text-3xl font-bold text-gray-900 mb-4">EventCatalog AI Assistant</h2>
107
- <p class="text-gray-600 mb-6 text-base md:text-lg">
108
- Chat with your catalog to quickly find information, understand relationships, and get instant answers about your
109
- architecture. Our AI-powered assistant makes exploring your event catalog faster and more intuitive than ever.
110
- </p>
111
-
112
- <div class="bg-gray-700 rounded-lg p-4 md:p-6 mb-4">
113
- <h3 class="text-lg text-white font-semibold mb-3">Quick Setup</h3>
114
- <Code code={`npm install @eventcatalog/generator-ai`} lang="bash" frame="none" />
115
- <a
116
- href="https://www.eventcatalog.dev/features/ai-assistant"
117
- class="inline-flex items-center text-sm text-white mt-4"
118
- >
119
- Learn more about setup →
120
- </a>
121
- </div>
122
- <p class="text-gray-600 mb-6 text-sm">
123
- Your data stays private and secure - all processing happens locally on your machine.
124
- </p>
125
- </div>
126
- </div>
127
- </div>
128
- )
129
- }
130
- </div>
131
- </VerticalSideBarLayout>
132
-
133
- <script>
134
- function checkBrowser() {
135
- const userAgent = navigator.userAgent.toLowerCase();
136
- const isChrome = /chrome/.test(userAgent) && !/edg/.test(userAgent);
137
- const isEdge = /edg/.test(userAgent);
138
-
139
- const warningElement = document.getElementById('browserWarning') as HTMLElement;
140
- const chatContainer = document.getElementById('chatContainer') as HTMLElement;
141
-
142
- if (warningElement && chatContainer) {
143
- if (!isChrome && !isEdge) {
144
- warningElement.style.display = 'flex';
145
- chatContainer.style.display = 'none';
146
- } else {
147
- warningElement.style.display = 'none';
148
- chatContainer.style.display = 'block';
149
- }
150
- }
151
- }
152
-
153
- // Run check when DOM is loaded
154
- document.addEventListener('DOMContentLoaded', checkBrowser);
155
- </script>
156
-
157
- <style>
158
- .loading-status.ready {
159
- background-color: rgb(240 253 244); /* light green bg */
160
- color: rgb(22 163 74); /* green text */
161
- }
162
-
163
- .loading-status.hidden {
164
- display: none;
165
- }
166
-
167
- /* Add smooth scrolling behavior */
168
- .scroll-smooth {
169
- scroll-behavior: smooth;
170
- }
171
- </style>
5
+ <ChatPage />
@@ -0,0 +1 @@
1
+ declare module 'react-syntax-highlighter/dist/esm/styles/prism/material-light';
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "2.34.7",
9
+ "version": "2.35.1",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -21,8 +21,10 @@
21
21
  "default-files-for-collections/"
22
22
  ],
23
23
  "dependencies": {
24
+ "@ai-sdk/openai": "^1.3.16",
24
25
  "@astrojs/markdown-remark": "^6.3.1",
25
26
  "@astrojs/mdx": "^4.2.4",
27
+ "@astrojs/node": "^9.2.0",
26
28
  "@astrojs/react": "^4.2.4",
27
29
  "@astrojs/rss": "^4.0.11",
28
30
  "@astrojs/tailwind": "^6.0.2",
@@ -44,8 +46,10 @@
44
46
  "@radix-ui/react-tooltip": "^1.1.8",
45
47
  "@scalar/api-reference-react": "^0.4.37",
46
48
  "@tailwindcss/typography": "^0.5.13",
49
+ "@tanstack/react-query": "^5.74.3",
47
50
  "@tanstack/react-table": "^8.17.3",
48
51
  "@xyflow/react": "^12.3.6",
52
+ "ai": "^4.3.9",
49
53
  "astro": "^5.7.0",
50
54
  "astro-expressive-code": "^0.40.1",
51
55
  "astro-pagefind": "^1.6.0",
@@ -71,6 +75,8 @@
71
75
  "mermaid": "^11.4.1",
72
76
  "react": "^18.3.1",
73
77
  "react-dom": "^18.3.1",
78
+ "react-markdown": "^10.1.0",
79
+ "react-syntax-highlighter": "^15.6.1",
74
80
  "rehype-slug": "^6.0.0",
75
81
  "remark-comment": "^1.0.0",
76
82
  "remark-directive": "^3.0.0",
@@ -96,6 +102,7 @@
96
102
  "@types/node": "^20.14.2",
97
103
  "@types/react": "^18.3.3",
98
104
  "@types/react-dom": "^18.3.0",
105
+ "@types/react-syntax-highlighter": "^15.5.13",
99
106
  "@types/semver": "^7.5.8",
100
107
  "@types/shelljs": "^0.8.15",
101
108
  "@types/update-notifier": "^6.0.8",
@@ -1,16 +0,0 @@
1
- import Sidebar from './ChatSidebar';
2
- import { ChatProvider } from './hooks/ChatProvider';
3
- import ChatWindow from './ChatWindow';
4
-
5
- const Chat = ({ chatConfig }: { chatConfig: any }) => {
6
- return (
7
- <ChatProvider>
8
- <div className="flex overflow-hidden w-full">
9
- <Sidebar />
10
- <ChatWindow {...chatConfig} />
11
- </div>
12
- </ChatProvider>
13
- );
14
- };
15
-
16
- export default Chat;