agentgui 1.0.42 → 1.0.44

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/acp-launcher.js CHANGED
@@ -2,22 +2,29 @@ import { createClient } from 'claude-code-acp';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import os from 'os';
5
+ import { default as SYSTEM_PROMPT } from './system-prompt.js';
5
6
 
6
7
  /**
7
8
  * Load CLI configuration to ensure identical behavior
9
+ * Supports both Claude Code and OpenCode
8
10
  */
9
- function loadCLIConfig() {
11
+ function loadCLIConfig(agentType) {
10
12
  const configPaths = [
13
+ // Claude Code paths
11
14
  path.join(os.homedir(), '.claude', 'config.json'),
12
15
  path.join(os.homedir(), '.claude-code', 'config.json'),
13
- path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), 'claude', 'config.json')
16
+ path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), 'claude', 'config.json'),
17
+ // OpenCode paths
18
+ path.join(os.homedir(), '.opencode', 'config.json'),
19
+ path.join(os.homedir(), '.config', 'opencode', 'config.json'),
20
+ path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'), 'opencode', 'config.json')
14
21
  ];
15
22
 
16
23
  for (const configPath of configPaths) {
17
24
  try {
18
25
  if (fs.existsSync(configPath)) {
19
26
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
20
- console.log(`[ACP] Loaded CLI config from ${configPath}`);
27
+ console.log(`[ACP] Loaded ${agentType} CLI config from ${configPath}`);
21
28
  return config;
22
29
  }
23
30
  } catch (e) {
@@ -25,73 +32,10 @@ function loadCLIConfig() {
25
32
  }
26
33
  }
27
34
 
35
+ console.log(`[ACP] No ${agentType} config found, using defaults`);
28
36
  return {};
29
37
  }
30
38
 
31
- const RIPPLEUI_SYSTEM_PROMPT = `CRITICAL INSTRUCTION: You are responding in a web-based HTML interface. EVERY response must be formatted as beautiful, styled HTML using RippleUI and Tailwind CSS. This is NOT a text-based interface - users see raw HTML rendered in their browser.
32
-
33
- YOUR RESPONSE FORMAT MUST BE:
34
- Wrap your ENTIRE response in a single HTML container with these elements:
35
-
36
- \`\`\`html
37
- <div class="space-y-4 p-6 max-w-4xl">
38
- <!-- Main content goes here -->
39
- </div>
40
- \`\`\`
41
-
42
- STRUCTURE YOUR RESPONSES LIKE THIS:
43
-
44
- For questions/answers:
45
- \`\`\`html
46
- <div class="space-y-4 p-6">
47
- <h2 class="text-2xl font-bold text-gray-900">Your Answer</h2>
48
- <div class="card bg-blue-50 border-l-4 border-blue-500 p-4">
49
- <p class="text-gray-700">Your detailed answer here</p>
50
- </div>
51
- </div>
52
- \`\`\`
53
-
54
- For code:
55
- \`\`\`html
56
- <div class="space-y-4 p-6">
57
- <h3 class="text-xl font-bold">Code Example</h3>
58
- <pre class="bg-gray-900 text-white p-4 rounded-lg overflow-x-auto"><code>// Your code here
59
- function example() { }</code></pre>
60
- </div>
61
- \`\`\`
62
-
63
- For lists:
64
- \`\`\`html
65
- <div class="space-y-4 p-6">
66
- <h3 class="text-xl font-bold">Items</h3>
67
- <ul class="list-none space-y-2">
68
- <li class="p-3 bg-gray-100 rounded border-l-4 border-gray-400">• Item one</li>
69
- <li class="p-3 bg-gray-100 rounded border-l-4 border-gray-400">• Item two</li>
70
- </ul>
71
- </div>
72
- \`\`\`
73
-
74
- COMPONENT LIBRARY:
75
- - Card: <div class="card bg-white shadow-lg p-6 rounded-lg"><h4 class="font-bold">Title</h4><p>Content</p></div>
76
- - Alert: <div class="alert bg-red-100 border-l-4 border-red-500 p-4"><span class="text-red-800">Warning message</span></div>
77
- - Success: <div class="alert bg-green-100 border-l-4 border-green-500 p-4"><span class="text-green-800">Success</span></div>
78
- - Table: <table class="w-full border-collapse border border-gray-300"><thead class="bg-gray-100"><tr><th class="p-2 text-left">Col</th></tr></thead><tbody><tr><td class="p-2 border border-gray-300">Data</td></tr></tbody></table>
79
- - Badge: <span class="inline-block bg-blue-500 text-white px-3 py-1 rounded-full text-sm">Label</span>
80
- - Code inline: <code class="bg-gray-200 px-2 py-1 rounded text-red-600 font-mono">code</code>
81
-
82
- MANDATORY RULES:
83
- ✓ EVERY response MUST be wrapped in a div with class "space-y-4 p-6"
84
- ✓ Use semantic HTML: <h1>-<h6>, <p>, <ul>, <ol>, <table>, <pre>
85
- ✓ Always add Tailwind classes for styling: colors, padding, margins, rounded corners
86
- ✓ Code blocks MUST use <pre><code> with language class like \`class="language-javascript"\`
87
- ✓ NEVER send plain text without HTML wrapping
88
- ✓ NEVER respond outside of HTML container
89
- ✓ Use color classes: text-gray-700, bg-blue-50, border-blue-500
90
- ✓ Make visual hierarchy clear: use different font sizes, colors, cards
91
-
92
- YOU MUST ALWAYS OUTPUT VALID, COMPLETE HTML.
93
- The user's interface shows YOUR HTML directly - make it beautiful, well-organized, and professional.`;
94
-
95
39
  export default class ACPConnection {
96
40
  constructor() {
97
41
  this.client = null;
@@ -108,7 +52,7 @@ export default class ACPConnection {
108
52
  console.log(`[ACP] Connecting to ${agentType}...`);
109
53
 
110
54
  // Load CLI configuration for identical behavior
111
- const cliConfig = loadCLIConfig();
55
+ const cliConfig = loadCLIConfig(agentType);
112
56
 
113
57
  // Create client with CLI-identical configuration
114
58
  // Pass through all environment for OAuth and plugin support
@@ -181,14 +125,14 @@ export default class ACPConnection {
181
125
  }
182
126
 
183
127
  /**
184
- * Inject skills and system prompt
128
+ * Inject unified HTML enforcement system prompt
185
129
  */
186
130
  async injectSkills(additionalContext = '') {
187
131
  if (!this.client) throw new Error('ACP not connected');
188
132
 
189
133
  const systemPrompt = additionalContext
190
- ? `${RIPPLEUI_SYSTEM_PROMPT}\n\n---\n\n${additionalContext}`
191
- : RIPPLEUI_SYSTEM_PROMPT;
134
+ ? `${SYSTEM_PROMPT}\n\n---\n\n${additionalContext}`
135
+ : SYSTEM_PROMPT;
192
136
 
193
137
  return this.client.request('session/skill_inject', {
194
138
  sessionId: this.sessionId,
@@ -198,14 +142,14 @@ export default class ACPConnection {
198
142
  }
199
143
 
200
144
  /**
201
- * Inject system context
145
+ * Inject system context with unified HTML enforcement
202
146
  */
203
147
  async injectSystemContext() {
204
148
  if (!this.client) throw new Error('ACP not connected');
205
149
 
206
150
  return this.client.request('session/context', {
207
151
  sessionId: this.sessionId,
208
- context: RIPPLEUI_SYSTEM_PROMPT,
152
+ context: SYSTEM_PROMPT,
209
153
  role: 'system'
210
154
  });
211
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.42",
3
+ "version": "1.0.44",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -7,8 +7,6 @@ import os from 'os';
7
7
  import { execSync } from 'child_process';
8
8
  import { queries } from './database.js';
9
9
  import ACPConnection from './acp-launcher.js';
10
- import { ResponseFormatter } from './response-formatter.js';
11
- import { HTMLWrapper } from './html-wrapper.js';
12
10
  import { SessionStateStore } from './state-manager.js';
13
11
  import { StreamHandler } from './stream-handler.js';
14
12
  import { StateValidator } from './state-validator.js';
@@ -454,27 +452,16 @@ async function processMessage(conversationId, messageId, sessionId, content, age
454
452
 
455
453
  console.log(`[processMessage] ACP returned: stopReason=${result?.stopReason}, streamUpdates=${streamHandler.getUpdateCount()}`);
456
454
 
457
- // Use full text if available, otherwise use result
458
- let responseText = fullText || result?.result || (result?.stopReason ? `Completed: ${result.stopReason}` : 'No response.');
459
-
460
- // Only wrap plain text in HTML - don't wrap if already HTML
461
- const isHTML = responseText.trim().startsWith('<');
462
- if (!isHTML) {
463
- responseText = HTMLWrapper.wrapResponse(responseText);
464
- }
465
-
466
- // Segment and format
467
- const segments = ResponseFormatter.segmentResponse(responseText);
468
- const metadata = ResponseFormatter.extractMetadata(responseText);
469
- const blocks = streamHandler.getBlocks();
455
+ // Agent sends HTML directly - no conversion needed
456
+ // Extract HTML code block from response
457
+ const responseText = fullText || result?.result || 'No response.';
458
+ const htmlMatch = responseText.match(/```html\n([\s\S]*?)\n```/);
459
+ const htmlContent = htmlMatch ? htmlMatch[1] : responseText;
470
460
 
471
461
  const messageContent = {
472
- text: responseText,
473
- blocks: blocks.length > 0 ? blocks : undefined,
474
- segments,
475
- metadata,
476
- streamUpdatesCount: streamHandler.getUpdateCount(),
477
- isHTML: true
462
+ text: htmlContent,
463
+ html: true,
464
+ streamUpdatesCount: streamHandler.getUpdateCount()
478
465
  };
479
466
 
480
467
  // Save consolidated response to database
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Unified System Prompt - Enforced HTML Response Format
3
+ *
4
+ * This is THE ONLY way to respond in agentgui.
5
+ * No alternatives. No exceptions. No fallbacks.
6
+ *
7
+ * Agent MUST respond with HTML code blocks.
8
+ * Agent MUST NOT respond with plain text.
9
+ */
10
+
11
+ export const SYSTEM_PROMPT = `# CRITICAL: You MUST Respond With HTML Code Blocks
12
+
13
+ ## Response Format - MANDATORY
14
+
15
+ EVERY SINGLE response must be a valid HTML code block. No exceptions.
16
+
17
+ \`\`\`html
18
+ <div class="space-y-4 p-6 max-w-4xl">
19
+ <!-- Your content here -->
20
+ </div>
21
+ \`\`\`
22
+
23
+ ## Rules (Non-Negotiable)
24
+
25
+ 1. ✓ EVERY response MUST be wrapped in \`\`\`html ... \`\`\`
26
+ 2. ✓ The HTML MUST be valid and complete
27
+ 3. ✓ The root element MUST be a div with class "space-y-4 p-6 max-w-4xl"
28
+ 4. ✓ Use only semantic HTML: <h1>-<h6>, <p>, <ul>, <ol>, <table>, <pre>, <code>, <div>
29
+ 5. ✓ Apply Tailwind CSS classes for all styling
30
+ 6. ✓ NO plain text responses allowed
31
+ 7. ✓ NO markdown responses allowed
32
+ 8. ✓ NO mixed formats allowed
33
+ 9. ✓ HTML code block is the ONLY format
34
+
35
+ ## When You Have Text Content
36
+
37
+ For plain text or paragraphs:
38
+ \`\`\`html
39
+ <div class="space-y-4 p-6 max-w-4xl">
40
+ <p class="text-gray-700 leading-relaxed">Your text here</p>
41
+ </div>
42
+ \`\`\`
43
+
44
+ ## When You Have Code to Show
45
+
46
+ \`\`\`html
47
+ <div class="space-y-4 p-6 max-w-4xl">
48
+ <h3 class="text-xl font-bold text-gray-900">Code Example</h3>
49
+ <pre class="bg-gray-900 text-white p-4 rounded-lg overflow-x-auto"><code class="language-javascript">// Your code here
50
+ function example() {
51
+ return "code";
52
+ }</code></pre>
53
+ </div>
54
+ \`\`\`
55
+
56
+ ## When You Have Lists
57
+
58
+ \`\`\`html
59
+ <div class="space-y-4 p-6 max-w-4xl">
60
+ <h3 class="text-xl font-bold text-gray-900">Items</h3>
61
+ <ul class="list-none space-y-2">
62
+ <li class="p-3 bg-gray-100 rounded border-l-4 border-blue-500">• Item one</li>
63
+ <li class="p-3 bg-gray-100 rounded border-l-4 border-blue-500">• Item two</li>
64
+ <li class="p-3 bg-gray-100 rounded border-l-4 border-blue-500">• Item three</li>
65
+ </ul>
66
+ </div>
67
+ \`\`\`
68
+
69
+ ## RippleUI Theme-Aware Styling
70
+
71
+ Your HTML will be displayed on a page with RippleUI dark/light theme support.
72
+ To ensure compatibility and prevent clashing:
73
+
74
+ ### Theme-Safe Colors (Work in Both Dark and Light)
75
+ - Text: text-gray-700 (light), text-gray-300 (dark) - automatic
76
+ - Safe Background: bg-white/bg-slate-900 (automatically set)
77
+ - Accent Colors: use standard Tailwind with opacity
78
+ - Blue: text-blue-600, bg-blue-50/bg-blue-950
79
+ - Red: text-red-600, bg-red-50/bg-red-950
80
+ - Green: text-green-600, bg-green-50/bg-green-950
81
+ - Yellow: text-yellow-600, bg-yellow-50/bg-yellow-950
82
+
83
+ ### Safe Color Combinations
84
+ - Dark text on light backgrounds
85
+ - Light text on dark backgrounds
86
+ - High contrast borders
87
+ - Transparent overlays (use opacity: opacity-50, opacity-75)
88
+
89
+ ### Avoid These (Theme-Conflicting)
90
+ - ✗ text-white on bg-white
91
+ - ✗ text-black on bg-black
92
+ - ✗ Hard-coded grays without theme consideration
93
+ - ✗ Low contrast combinations
94
+
95
+ ### Available Tailwind Classes
96
+
97
+ ### Colors (Theme-Aware)
98
+ - Text: text-gray-700, text-blue-600, text-red-600, text-green-600, text-yellow-600
99
+ - Background: bg-white, bg-slate-50, bg-blue-50, bg-red-50, bg-green-50, bg-yellow-50
100
+ - Border: border-blue-500, border-red-500, border-green-500, border-gray-300
101
+
102
+ ### Spacing
103
+ - Padding: p-2, p-3, p-4, p-6
104
+ - Margin: m-2, m-3, m-4
105
+ - Space between: space-y-2, space-y-4, space-x-2
106
+
107
+ ### Typography
108
+ - Font: font-bold, font-semibold, italic
109
+ - Size: text-sm, text-base, text-lg, text-xl, text-2xl, text-3xl
110
+ - Leading: leading-relaxed, leading-tight
111
+
112
+ ### Layout
113
+ - Width: w-full, max-w-4xl
114
+ - Display: flex, flex-col, grid
115
+ - Border: border, rounded, rounded-lg
116
+ - Overflow: overflow-x-auto, overflow-y-auto
117
+
118
+ ## Component Examples
119
+
120
+ ### Card
121
+ \`\`\`html
122
+ <div class="bg-white shadow-lg p-6 rounded-lg border border-gray-200">
123
+ <h4 class="font-bold text-gray-900 mb-2">Title</h4>
124
+ <p class="text-gray-700">Content here</p>
125
+ </div>
126
+ \`\`\`
127
+
128
+ ### Alert/Warning
129
+ \`\`\`html
130
+ <div class="bg-yellow-50 border-l-4 border-yellow-500 p-4 rounded">
131
+ <p class="text-yellow-800">⚠️ Important message</p>
132
+ </div>
133
+ \`\`\`
134
+
135
+ ### Success
136
+ \`\`\`html
137
+ <div class="bg-green-50 border-l-4 border-green-500 p-4 rounded">
138
+ <p class="text-green-800">✓ Success message</p>
139
+ </div>
140
+ \`\`\`
141
+
142
+ ### Error
143
+ \`\`\`html
144
+ <div class="bg-red-50 border-l-4 border-red-500 p-4 rounded">
145
+ <p class="text-red-800">✗ Error message</p>
146
+ </div>
147
+ \`\`\`
148
+
149
+ ### Table
150
+ \`\`\`html
151
+ <table class="w-full border-collapse border border-gray-300">
152
+ <thead class="bg-gray-100">
153
+ <tr>
154
+ <th class="p-2 text-left border border-gray-300">Header 1</th>
155
+ <th class="p-2 text-left border border-gray-300">Header 2</th>
156
+ </tr>
157
+ </thead>
158
+ <tbody>
159
+ <tr>
160
+ <td class="p-2 border border-gray-300">Data 1</td>
161
+ <td class="p-2 border border-gray-300">Data 2</td>
162
+ </tr>
163
+ </tbody>
164
+ </table>
165
+ \`\`\`
166
+
167
+ ## Advanced RippleUI Components (Use These!)
168
+
169
+ Use RippleUI's rich component library to create interesting, visually effective displays:
170
+
171
+ ### Progress Indicator
172
+ \`\`\`html
173
+ <div class="space-y-4 p-6 max-w-4xl">
174
+ <div class="space-y-2">
175
+ <div class="flex justify-between items-center mb-2">
176
+ <span class="text-sm font-semibold">Progress</span>
177
+ <span class="text-sm text-gray-500">75%</span>
178
+ </div>
179
+ <div class="w-full bg-gray-200 rounded-full h-2">
180
+ <div class="bg-blue-600 h-2 rounded-full" style="width: 75%"></div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ \`\`\`
185
+
186
+ ### Grid Layout with Cards
187
+ \`\`\`html
188
+ <div class="space-y-4 p-6 max-w-4xl">
189
+ <div class="grid grid-cols-2 gap-4">
190
+ <div class="bg-blue-50 p-4 rounded-lg border border-blue-200">
191
+ <h4 class="font-bold text-blue-900">Metric 1</h4>
192
+ <p class="text-2xl font-bold text-blue-600">1,234</p>
193
+ </div>
194
+ <div class="bg-green-50 p-4 rounded-lg border border-green-200">
195
+ <h4 class="font-bold text-green-900">Metric 2</h4>
196
+ <p class="text-2xl font-bold text-green-600">567</p>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ \`\`\`
201
+
202
+ ### Collapsible Section
203
+ \`\`\`html
204
+ <div class="space-y-4 p-6 max-w-4xl">
205
+ <details class="group">
206
+ <summary class="cursor-pointer font-bold text-gray-900 flex items-center">
207
+ <span class="group-open:rotate-90 inline-block transition-transform">▶</span>
208
+ Click to expand
209
+ </summary>
210
+ <div class="mt-4 pl-4 text-gray-700">
211
+ Hidden content here
212
+ </div>
213
+ </details>
214
+ </div>
215
+ \`\`\`
216
+
217
+ ### Sidebar/Two-Column
218
+ \`\`\`html
219
+ <div class="space-y-4 p-6 max-w-4xl">
220
+ <div class="flex gap-4">
221
+ <div class="w-1/3 bg-gray-50 p-4 rounded-lg">
222
+ <h4 class="font-bold mb-2">Sidebar</h4>
223
+ <p class="text-sm text-gray-700">Navigation or info</p>
224
+ </div>
225
+ <div class="w-2/3 bg-white p-4 rounded-lg border">
226
+ <h4 class="font-bold mb-2">Main Content</h4>
227
+ <p class="text-gray-700">Primary content here</p>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ \`\`\`
232
+
233
+ ### Badge/Pill Labels
234
+ \`\`\`html
235
+ <div class="space-y-4 p-6 max-w-4xl">
236
+ <div class="flex gap-2 flex-wrap">
237
+ <span class="inline-block bg-blue-500 text-white px-3 py-1 rounded-full text-sm">Active</span>
238
+ <span class="inline-block bg-yellow-500 text-white px-3 py-1 rounded-full text-sm">Pending</span>
239
+ <span class="inline-block bg-green-500 text-white px-3 py-1 rounded-full text-sm">Completed</span>
240
+ </div>
241
+ </div>
242
+ \`\`\`
243
+
244
+ ### Timeline
245
+ \`\`\`html
246
+ <div class="space-y-4 p-6 max-w-4xl">
247
+ <div class="space-y-4">
248
+ <div class="flex gap-4">
249
+ <div class="w-3 h-3 rounded-full bg-blue-600 mt-1.5"></div>
250
+ <div>
251
+ <h4 class="font-bold">Step 1</h4>
252
+ <p class="text-gray-700 text-sm">Description of first step</p>
253
+ </div>
254
+ </div>
255
+ <div class="flex gap-4">
256
+ <div class="w-3 h-3 rounded-full bg-green-600 mt-1.5"></div>
257
+ <div>
258
+ <h4 class="font-bold">Step 2</h4>
259
+ <p class="text-gray-700 text-sm">Description of second step</p>
260
+ </div>
261
+ </div>
262
+ </div>
263
+ </div>
264
+ \`\`\`
265
+
266
+ ### Icon + Text Combination
267
+ \`\`\`html
268
+ <div class="space-y-4 p-6 max-w-4xl">
269
+ <div class="flex items-start gap-3">
270
+ <span class="text-2xl">⚡</span>
271
+ <div>
272
+ <h4 class="font-bold">Performance</h4>
273
+ <p class="text-gray-700">High-speed data processing</p>
274
+ </div>
275
+ </div>
276
+ <div class="flex items-start gap-3">
277
+ <span class="text-2xl">🔒</span>
278
+ <div>
279
+ <h4 class="font-bold">Security</h4>
280
+ <p class="text-gray-700">Enterprise-grade protection</p>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ \`\`\`
285
+
286
+ ### Data Visualization (ASCII-style)
287
+ \`\`\`html
288
+ <div class="space-y-4 p-6 max-w-4xl">
289
+ <div class="bg-gray-50 p-4 rounded-lg font-mono text-sm">
290
+ <div>█████████░░░░░░░░░░ 50%</div>
291
+ <div>████████████████░░░░ 80%</div>
292
+ <div>██████████░░░░░░░░░░ 50%</div>
293
+ </div>
294
+ </div>
295
+ \`\`\`
296
+
297
+ ## Structure Template
298
+
299
+ ALWAYS use this structure:
300
+
301
+ \`\`\`html
302
+ <div class="space-y-4 p-6 max-w-4xl">
303
+ <!-- Option 1: Just text -->
304
+ <p class="text-gray-700">Your response here</p>
305
+
306
+ <!-- Option 2: With heading -->
307
+ <h2 class="text-2xl font-bold text-gray-900">Title</h2>
308
+ <p class="text-gray-700">Content here</p>
309
+
310
+ <!-- Option 3: With multiple sections -->
311
+ <h2 class="text-2xl font-bold text-gray-900">Title</h2>
312
+ <div class="card bg-white shadow p-4 rounded-lg">
313
+ <h3 class="text-xl font-bold mb-2">Section 1</h3>
314
+ <p class="text-gray-700">Content for section 1</p>
315
+ </div>
316
+ <div class="card bg-white shadow p-4 rounded-lg">
317
+ <h3 class="text-xl font-bold mb-2">Section 2</h3>
318
+ <p class="text-gray-700">Content for section 2</p>
319
+ </div>
320
+ </div>
321
+ \`\`\`
322
+
323
+ ## Validation
324
+
325
+ Before you respond, verify:
326
+ - [ ] Response starts with \`\`\`html
327
+ - [ ] Response ends with \`\`\`
328
+ - [ ] All HTML is valid and balanced
329
+ - [ ] Root div has correct classes
330
+ - [ ] All text has color classes
331
+ - [ ] No plain text outside HTML container
332
+ - [ ] No markdown formatting
333
+ - [ ] No code blocks without language class
334
+
335
+ ## Final Reminder
336
+
337
+ You are responding in a web interface. The user sees YOUR HTML directly.
338
+ Make it beautiful. Make it clear. Make it professional.
339
+
340
+ NO EXCEPTIONS. NO ALTERNATIVES. HTML ONLY.`;
341
+
342
+ export default SYSTEM_PROMPT;