@equinor/fusion-framework-cli-plugin-ai-chat 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,57 @@
1
+ # @equinor/fusion-framework-cli-plugin-ai-chat
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`e2d2a76`](https://github.com/equinor/fusion-framework/commit/e2d2a76d08b86c3a9d8783fed1606551df9d5633) Thanks [@odinr](https://github.com/odinr)! - Add new AI chat plugin package for interactive chat with AI models.
8
+
9
+ This plugin extends the Fusion Framework CLI with interactive chat capabilities using vector store context retrieval for enhanced, context-aware responses.
10
+
11
+ **Features:**
12
+
13
+ - Interactive conversation mode with readline interface
14
+ - Real-time streaming responses from AI models
15
+ - Intelligent message history compression using AI summarization
16
+ - Automatic vector store context retrieval for enhanced responses
17
+ - Configurable context and history limits
18
+
19
+ **Quick Usage:**
20
+
21
+ 1. Install the plugin:
22
+
23
+ ```sh
24
+ pnpm add -D @equinor/fusion-framework-cli-plugin-ai-chat
25
+ ```
26
+
27
+ 2. Configure in `fusion-cli.config.ts`:
28
+
29
+ ```typescript
30
+ import { defineFusionCli } from "@equinor/fusion-framework-cli";
31
+
32
+ export default defineFusionCli(() => ({
33
+ plugins: ["@equinor/fusion-framework-cli-plugin-ai-chat"],
34
+ }));
35
+ ```
36
+
37
+ 3. Use the chat command:
38
+
39
+ ```sh
40
+ # Start interactive chat
41
+ ffc ai chat
42
+
43
+ # With custom context limit
44
+ ffc ai chat --context-limit 10
45
+
46
+ # With verbose output
47
+ ffc ai chat --verbose
48
+ ```
49
+
50
+ The plugin supports Azure OpenAI and Azure Cognitive Search configuration via command-line options or environment variables.
51
+
52
+ ### Patch Changes
53
+
54
+ - Updated dependencies [[`e2d2a76`](https://github.com/equinor/fusion-framework/commit/e2d2a76d08b86c3a9d8783fed1606551df9d5633), [`e2d2a76`](https://github.com/equinor/fusion-framework/commit/e2d2a76d08b86c3a9d8783fed1606551df9d5633), [`e2d2a76`](https://github.com/equinor/fusion-framework/commit/e2d2a76d08b86c3a9d8783fed1606551df9d5633)]:
55
+ - @equinor/fusion-framework-cli-plugin-ai-base@1.0.0
56
+ - @equinor/fusion-framework-cli@13.0.0
57
+ - @equinor/fusion-framework-module-ai@2.0.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Equinor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # @equinor/fusion-framework-cli-plugin-ai-chat
2
+
3
+ AI chat plugin for Fusion Framework CLI providing interactive chat with AI models.
4
+
5
+ > [!WARNING]
6
+ > **WORK IN PROGRESS - CRUDE VERSION FOR TESTING**
7
+ >
8
+ > This plugin is currently a work-in-progress, crude version intended for testing the search index functionality. It is not production-ready and may have bugs, incomplete features, or breaking changes.
9
+ >
10
+ > - Use at your own risk
11
+ > - API and behavior may change without notice
12
+ > - Not recommended for production use
13
+ > - Primarily for internal testing of vector store search capabilities
14
+
15
+ ## Installation
16
+
17
+ ```sh
18
+ pnpm add -D @equinor/fusion-framework-cli-plugin-ai-chat
19
+ ```
20
+
21
+ ## Configuration
22
+
23
+ After installing the plugin, create a `fusion-cli.config.ts` file in your project root:
24
+
25
+ ```typescript
26
+ import { defineFusionCli } from '@equinor/fusion-framework-cli';
27
+
28
+ export default defineFusionCli(() => ({
29
+ plugins: [
30
+ '@equinor/fusion-framework-cli-plugin-ai-chat',
31
+ ],
32
+ }));
33
+ ```
34
+
35
+ The CLI will automatically discover and load plugins listed in this configuration file. The config file can be `.ts`, `.js`, or `.json`. The `defineFusionCli` helper provides type safety and IntelliSense support.
36
+
37
+ ## Features
38
+
39
+ This plugin extends the Fusion Framework CLI with AI chat capabilities:
40
+
41
+ - **Interactive chat** with AI models
42
+ - Real-time streaming responses
43
+ - Intelligent message history compression
44
+ - Vector store context retrieval for enhanced responses
45
+
46
+ ## Usage
47
+
48
+ Once installed, the chat command is automatically available:
49
+
50
+ ```sh
51
+ # Interactive chat with AI models
52
+ ffc ai chat
53
+ ```
54
+
55
+ ## Commands
56
+
57
+ ### `ai chat`
58
+
59
+ Interactive chat with Large Language Models using readline for a smooth CLI experience. Enhanced with vector store context retrieval for more accurate and relevant responses.
60
+
61
+ **Features:**
62
+ - Interactive conversation mode
63
+ - Real-time streaming responses from AI models
64
+ - Intelligent message history compression using AI summarization
65
+ - Automatic vector store context retrieval for enhanced responses
66
+ - Special commands: clear (clear conversation history)
67
+ - Support for Azure OpenAI models and Azure Cognitive Search
68
+ - Live typing effect for AI responses
69
+ - Configurable context retrieval limits
70
+
71
+ **Options:**
72
+ - `--openai-api-key <key>` - API key for Azure OpenAI
73
+ - `--openai-api-version <version>` - API version (default: 2024-02-15-preview)
74
+ - `--openai-instance <name>` - Azure OpenAI instance name
75
+ - `--openai-chat-deployment <name>` - Azure OpenAI chat deployment name (required)
76
+ - `--openai-embedding-deployment <name>` - Azure OpenAI embedding deployment name
77
+ - `--azure-search-endpoint <url>` - Azure Search endpoint URL (required)
78
+ - `--azure-search-api-key <key>` - Azure Search API key (required)
79
+ - `--azure-search-index-name <name>` - Azure Search index name (required)
80
+ - `--context-limit <number>` - Max context documents to retrieve (default: 5)
81
+ - `--history-limit <number>` - Max messages to keep in conversation history (default: 20, auto-compresses at 10)
82
+ - `--verbose` - Enable verbose output
83
+
84
+ **Environment Variables:**
85
+ All options can be provided via environment variables:
86
+ - `AZURE_OPENAI_API_KEY` - API key for Azure OpenAI
87
+ - `AZURE_OPENAI_API_VERSION` - API version
88
+ - `AZURE_OPENAI_INSTANCE_NAME` - Instance name
89
+ - `AZURE_OPENAI_CHAT_DEPLOYMENT_NAME` - Chat deployment name
90
+ - `AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME` - Embedding deployment name
91
+ - `AZURE_SEARCH_ENDPOINT` - Azure Search endpoint
92
+ - `AZURE_SEARCH_API_KEY` - Azure Search API key
93
+ - `AZURE_SEARCH_INDEX_NAME` - Azure Search index name
94
+
95
+ **Interactive Commands:**
96
+ - `clear` - Clear conversation history
97
+ - `Ctrl+C` - Exit immediately
98
+
99
+ **Examples:**
100
+ ```sh
101
+ $ ffc ai chat
102
+ $ ffc ai chat --context-limit 10
103
+ $ ffc ai chat --history-limit 100
104
+ $ ffc ai chat --verbose --azure-search-endpoint https://my-search.search.windows.net
105
+ ```
106
+
107
+ ## Configuration
108
+
109
+ The plugin requires Azure OpenAI and Azure Cognitive Search configuration. See the main CLI documentation for details on setting up API keys and endpoints.
110
+
111
+ ## License
112
+
113
+ ISC
@@ -0,0 +1,294 @@
1
+ import { createCommand, createOption } from 'commander';
2
+ import { from } from 'rxjs';
3
+ import { withOptions as withAiOptions, } from '@equinor/fusion-framework-cli-plugin-ai-base/command-options';
4
+ import { createInterface } from 'node:readline';
5
+ import { setupFramework } from '@equinor/fusion-framework-cli-plugin-ai-base';
6
+ import { createSystemMessage } from './system-message-template.js';
7
+ import { RunnablePassthrough, RunnableSequence, } from '@langchain/core/runnables';
8
+ import { StringOutputParser } from '@langchain/core/output_parsers';
9
+ const _command = createCommand('chat')
10
+ .description('Interactive chat with Large Language Models')
11
+ .addOption(createOption('--verbose', 'Enable verbose output').default(false))
12
+ .addOption(createOption('--context-limit <number>', 'Maximum number of context documents to retrieve')
13
+ .default(5)
14
+ .argParser(parseInt))
15
+ .addOption(createOption('--history-limit <number>', 'Maximum number of messages to keep in conversation history')
16
+ .default(20)
17
+ .argParser(parseInt))
18
+ .action(async (options) => {
19
+ // Initialize the framework
20
+ const framework = await setupFramework(options);
21
+ // Get the AI provider
22
+ const aiProvider = framework.ai;
23
+ if (options.verbose) {
24
+ console.log('โœ… Framework initialized successfully');
25
+ console.log('๐Ÿ’ฌ Starting interactive chat...');
26
+ console.log('๐Ÿ” Context retrieval enabled');
27
+ console.log(`๐Ÿ“ Message history limit: ${options.historyLimit || 20} messages`);
28
+ if (options.azureSearchEndpoint) {
29
+ console.log(`๐Ÿ“š Using vector store: ${options.azureSearchIndexName}`);
30
+ }
31
+ else {
32
+ console.log('โš ๏ธ No vector store configured - context retrieval will be skipped');
33
+ }
34
+ console.log('๐Ÿ” Using model:', options.openaiChatDeployment);
35
+ console.log('Type "exit" or "quit" to end the conversation');
36
+ console.log('Type "clear" to clear the conversation history');
37
+ console.log('Press Ctrl+C to exit immediately');
38
+ console.log('');
39
+ }
40
+ // Start interactive chat
41
+ if (!options.openaiChatDeployment) {
42
+ throw new Error('Chat deployment name is required');
43
+ }
44
+ if (!options.azureSearchIndexName) {
45
+ throw new Error('Azure Search index name is required');
46
+ }
47
+ const chatService = framework.ai.getService('chat', options.openaiChatDeployment);
48
+ const vectorStoreService = aiProvider.getService('search', options.azureSearchIndexName);
49
+ if (options.verbose) {
50
+ console.log('๐Ÿ”ง Configuring retriever with options:', {
51
+ k: options.contextLimit || 5,
52
+ searchType: 'similarity',
53
+ });
54
+ }
55
+ // Configure retriever with similarity search (not MMR) for more predictable results
56
+ // MMR (Maximum Marginal Relevance) can sometimes cause issues with Azure Search
57
+ const retriever = vectorStoreService.asRetriever({
58
+ k: options.contextLimit || 5,
59
+ searchType: 'similarity',
60
+ });
61
+ /**
62
+ * Retrieves relevant context documents from the vector store for a given query
63
+ * @param input - The user's query string
64
+ * @returns Promise resolving to formatted context string or error message
65
+ */
66
+ const retrieveContext = async (input) => {
67
+ try {
68
+ if (options.verbose) {
69
+ console.log('๐Ÿ” Retrieving context for query:', input);
70
+ }
71
+ const docs = await retriever.invoke(input);
72
+ console.log('๐Ÿ“„ Retrieved documents:', docs?.length || 0);
73
+ if (options.verbose) {
74
+ for (const doc of docs) {
75
+ console.log('๐Ÿ“„ Document:', {
76
+ pageContent: `${doc.pageContent.substring(0, 100)}...`,
77
+ metadata: doc.metadata,
78
+ });
79
+ }
80
+ }
81
+ if (!docs || docs.length === 0) {
82
+ return 'No relevant context found.';
83
+ }
84
+ return docs.map((doc) => doc.pageContent).join('\n');
85
+ }
86
+ catch (error) {
87
+ console.error('โŒ Error retrieving context:', error);
88
+ if (options.verbose) {
89
+ console.error('Full error details:', error);
90
+ }
91
+ return 'Error retrieving context.';
92
+ }
93
+ };
94
+ // Create a custom runnable that formats the prompt as ChatMessage[]
95
+ // This chain step retrieves context and formats it into a proper message array
96
+ const formatPromptAsMessages = new RunnablePassthrough().pipe(async (input) => {
97
+ // Retrieve relevant context from vector store based on user's message
98
+ const context = await retrieveContext(input.userMessage);
99
+ // Build system message with retrieved context for RAG (Retrieval-Augmented Generation)
100
+ // Emphasizes using FUSION framework knowledge from the provided context
101
+ const systemMessage = createSystemMessage(context);
102
+ // Build the complete message array with system message, history, and current user message
103
+ // Order: system message (with context) -> conversation history -> current user message
104
+ const messages = [
105
+ { role: 'system', content: systemMessage },
106
+ ...input.messageHistory,
107
+ { role: 'user', content: input.userMessage },
108
+ ];
109
+ return messages;
110
+ });
111
+ // Create the chatbot chain using LangChain's RunnableSequence
112
+ // Chain flow: format messages -> invoke chat model -> parse string output
113
+ // Note: Type assertion needed because IModel extends RunnableInterface but TypeScript
114
+ // doesn't recognize the compatibility without explicit casting
115
+ const chain = RunnableSequence.from([
116
+ formatPromptAsMessages,
117
+ chatService,
118
+ new StringOutputParser(),
119
+ ]);
120
+ const messageHistory = [];
121
+ /**
122
+ * Summarizes the oldest messages in the conversation history using AI
123
+ * This helps compress long conversation histories while preserving important context
124
+ * @param messages - Array of messages to summarize
125
+ * @returns Promise resolving to a summary message that can replace the original messages
126
+ */
127
+ const summarizeOldMessages = async (messages) => {
128
+ // Convert messages to a text format for summarization
129
+ const conversationText = messages.map((msg) => `${msg.role}: ${msg.content}`).join('\n');
130
+ const summaryPrompt = `Please provide a concise summary of the following conversation history. Focus on key topics, decisions, and important context that should be remembered for the ongoing conversation:
131
+
132
+ ${conversationText}
133
+
134
+ Summary:`;
135
+ try {
136
+ // Use the chat service to generate a summary of the conversation
137
+ const summaryResponse = await chatService.invoke([
138
+ { role: 'user', content: summaryPrompt },
139
+ ]);
140
+ return {
141
+ role: 'assistant',
142
+ content: `[Previous conversation summary: ${summaryResponse}]`,
143
+ };
144
+ }
145
+ catch (error) {
146
+ console.error('โŒ Error summarizing conversation:', error);
147
+ // Fallback to a simple summary if AI summarization fails
148
+ // This ensures the conversation can continue even if summarization fails
149
+ return {
150
+ role: 'assistant',
151
+ content: `[Previous conversation summary: ${messages.length} messages about various topics]`,
152
+ };
153
+ }
154
+ };
155
+ /**
156
+ * Manages message history with intelligent compression using AI summarization
157
+ * Implements a two-stage compression strategy:
158
+ * 1. When history reaches 10 messages, summarize oldest 5 messages using AI
159
+ * 2. If history still exceeds limit after compression, remove oldest non-summary messages
160
+ * @param history - Current message history array (will be mutated)
161
+ * @param newMessage - New message to add to history
162
+ * @param limit - Maximum number of messages to keep in history
163
+ * @returns Updated message history with compression applied
164
+ */
165
+ const addMessageToHistory = async (history, newMessage, limit) => {
166
+ history.push(newMessage);
167
+ // Stage 1: AI-based compression when history reaches 10 messages
168
+ // Summarize the oldest 5 messages and replace them with a single summary message
169
+ // This preserves important context while reducing token usage
170
+ let hasSummary = false;
171
+ if (history.length >= 10) {
172
+ if (options.verbose) {
173
+ console.log('๐Ÿ”„ Compressing conversation history with AI summarization...');
174
+ }
175
+ // Remove oldest 5 messages and summarize them
176
+ const oldestMessages = history.splice(0, 5);
177
+ const summary = await summarizeOldMessages(oldestMessages);
178
+ // Insert the summary at the beginning to maintain chronological order
179
+ history.unshift(summary);
180
+ hasSummary = true;
181
+ if (options.verbose) {
182
+ console.log(`๐Ÿ“ Compressed 5 messages into 1 summary. History now has ${history.length} messages.`);
183
+ }
184
+ }
185
+ // Stage 2: Hard limit enforcement if history still exceeds limit after compression
186
+ // If we just created a summary, start removing from position 1 to preserve it
187
+ // Otherwise, remove from position 0 as usual
188
+ if (history.length > limit) {
189
+ const messagesToRemove = history.length - limit;
190
+ const startIndex = hasSummary ? 1 : 0;
191
+ // Ensure we don't remove more messages than available (keeping summary if it exists)
192
+ const maxRemovable = hasSummary ? history.length - 2 : history.length - 1;
193
+ const actualRemoval = Math.min(messagesToRemove, Math.max(0, maxRemovable));
194
+ if (actualRemoval > 0) {
195
+ history.splice(startIndex, actualRemoval);
196
+ if (options.verbose) {
197
+ console.log(`๐Ÿ—‘๏ธ Removed ${actualRemoval} messages. History now has ${history.length} messages.`);
198
+ }
199
+ }
200
+ }
201
+ return history;
202
+ };
203
+ console.log('๐Ÿ’ฌ Chat ready! Start typing your message...\n');
204
+ console.log('๐Ÿ’ก Press Ctrl+C to exit at any time\n');
205
+ // Create readline interface for better Ctrl+C handling
206
+ // This provides better control over input/output and signal handling
207
+ const rl = createInterface({
208
+ input: process.stdin,
209
+ output: process.stdout,
210
+ });
211
+ // Handle Ctrl+C gracefully to prevent abrupt termination
212
+ const handleExit = () => {
213
+ console.log('\n\n๐Ÿ‘‹ Goodbye!');
214
+ rl.close();
215
+ process.exit(0);
216
+ };
217
+ process.on('SIGINT', handleExit);
218
+ process.on('SIGTERM', handleExit);
219
+ // Interactive chat loop - continues until user exits
220
+ while (true) {
221
+ try {
222
+ // Prompt user for input using readline
223
+ const userMessage = await new Promise((resolve) => {
224
+ rl.question('You: ', (answer) => {
225
+ resolve(answer.trim());
226
+ });
227
+ });
228
+ // Skip empty messages
229
+ if (!userMessage) {
230
+ console.log('Please enter a message\n');
231
+ continue;
232
+ }
233
+ // Handle special commands
234
+ if (userMessage.toLowerCase() === 'clear') {
235
+ messageHistory.length = 0;
236
+ console.log('\n๐Ÿงน Conversation history cleared!\n');
237
+ continue;
238
+ }
239
+ // Add user message to history (with automatic compression if needed)
240
+ await addMessageToHistory(messageHistory, { role: 'user', content: userMessage }, options.historyLimit || 20);
241
+ // Show typing indicator
242
+ console.log('\n๐Ÿค– AI Response:');
243
+ // Use LangChain runnable chain for RAG (Retrieval-Augmented Generation)
244
+ try {
245
+ if (options.verbose) {
246
+ console.log('๐Ÿ” Using LangChain chain with context retrieval...');
247
+ console.log(`๐Ÿ“ Message history contains ${messageHistory.length} messages`);
248
+ }
249
+ // Stream the response from the chain for real-time output
250
+ const responseStream = await chain.stream({ userMessage, messageHistory });
251
+ // Collect the full response while streaming chunks to stdout
252
+ // This allows users to see the response as it's generated
253
+ const fullResponse = await new Promise((resolve, reject) => {
254
+ let fullResponse = '';
255
+ from(responseStream).subscribe({
256
+ next: (chunk) => {
257
+ // Write each chunk immediately for streaming effect
258
+ process.stdout.write(String(chunk));
259
+ fullResponse += chunk;
260
+ },
261
+ error: (error) => {
262
+ reject(error);
263
+ },
264
+ complete: () => {
265
+ resolve(fullResponse);
266
+ },
267
+ });
268
+ });
269
+ // Add AI response to history for context in future messages
270
+ await addMessageToHistory(messageHistory, { role: 'assistant', content: fullResponse }, options.historyLimit || 20);
271
+ }
272
+ catch (error) {
273
+ console.error('\nโŒ Chain error:', error);
274
+ console.log('Falling back to basic chat...');
275
+ }
276
+ console.log('');
277
+ }
278
+ catch (error) {
279
+ console.error('\nโŒ Error during chat:', error);
280
+ console.log('');
281
+ }
282
+ }
283
+ });
284
+ /**
285
+ * CLI command for interactive chat with AI models.
286
+ * Enhanced with AI options including chat, embedding, and search capabilities.
287
+ */
288
+ export const command = withAiOptions(_command, {
289
+ includeChat: true,
290
+ includeEmbedding: true,
291
+ includeSearch: true,
292
+ });
293
+ export default command;
294
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { registerAiPlugin } from '@equinor/fusion-framework-cli-plugin-ai-base';
2
+ import { command as chatCommand } from './chat.js';
3
+ /**
4
+ * Registers the AI chat plugin command with the CLI program
5
+ * @param program - The Commander program instance to register commands with
6
+ */
7
+ export function registerChatPlugin(program) {
8
+ registerAiPlugin(program, chatCommand);
9
+ }
10
+ export default registerChatPlugin;
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AAEnD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACzC,CAAC;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * System message template for FUSION framework chat assistant
3
+ *
4
+ * This template emphasizes using FUSION knowledge from the provided context
5
+ * to provide accurate and comprehensive answers about the FUSION framework.
6
+ *
7
+ * @param context - The retrieved context from the vector store containing FUSION knowledge
8
+ * @returns Formatted system message string for the AI chat assistant
9
+ */
10
+ export function createSystemMessage(context) {
11
+ return `You are a helpful assistant specialized in the FUSION framework. Your primary goal is to use FUSION knowledge from the provided context to answer questions accurately and comprehensively.
12
+
13
+ **Priority Guidelines:**
14
+ 1. **Always prioritize FUSION-specific information** from the context below when answering questions
15
+ 2. Use FUSION framework patterns, APIs, conventions, and best practices from the context
16
+ 3. Reference specific FUSION modules, packages, or components mentioned in the context when relevant
17
+ 4. If the context contains FUSION documentation, code examples, or implementation details, use them as the basis for your response
18
+ 5. Only provide general answers if the context doesn't contain relevant FUSION information, and clearly state when you're doing so
19
+
20
+ **Context (FUSION Knowledge Base):**
21
+ ${context}
22
+
23
+ Remember: Your expertise comes from the FUSION context provided above. Use it as extensively as possible to provide accurate, framework-specific guidance.`;
24
+ }
25
+ //# sourceMappingURL=system-message-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-message-template.js","sourceRoot":"","sources":["../../src/system-message-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO;;;;;;;;;;EAUP,OAAO;;2JAEkJ,CAAC;AAC5J,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Generated by genversion.
2
+ export const version = '1.0.0';
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}