@swizzy_ai/kit 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/README.md +717 -0
- package/dist/core/wizard/bungee/builder.d.ts +27 -0
- package/dist/core/wizard/bungee/builder.d.ts.map +1 -0
- package/dist/core/wizard/bungee/types.d.ts +12 -0
- package/dist/core/wizard/bungee/types.d.ts.map +1 -0
- package/dist/core/wizard/index.d.ts +7 -0
- package/dist/core/wizard/index.d.ts.map +1 -0
- package/dist/core/wizard/steps/base.d.ts +48 -0
- package/dist/core/wizard/steps/base.d.ts.map +1 -0
- package/dist/core/wizard/steps/compute.d.ts +16 -0
- package/dist/core/wizard/steps/compute.d.ts.map +1 -0
- package/dist/core/wizard/steps/text.d.ts +16 -0
- package/dist/core/wizard/steps/text.d.ts.map +1 -0
- package/dist/core/wizard/wizard.d.ts +110 -0
- package/dist/core/wizard/wizard.d.ts.map +1 -0
- package/dist/index.d.ts +309 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1451 -0
- package/dist/index.js.map +1 -0
- package/dist/services/client/index.d.ts +34 -0
- package/dist/services/client/index.d.ts.map +1 -0
- package/dist/services/client/models.d.ts +17 -0
- package/dist/services/client/models.d.ts.map +1 -0
- package/dist/services/client/providers.d.ts +29 -0
- package/dist/services/client/providers.d.ts.map +1 -0
- package/dist/services/client/registry.d.ts +11 -0
- package/dist/services/client/registry.d.ts.map +1 -0
- package/dist/ui/wizard-script.js +242 -0
- package/dist/ui/wizard-styles.css +96 -0
- package/dist/ui/wizard-visualizer.html +481 -0
- package/package.json +53 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Wizard Visualizer | Production</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--background: #000000;
|
|
13
|
+
--foreground: #ffffff;
|
|
14
|
+
--accent-primary: #e43de7;
|
|
15
|
+
--accent-primary-rgb: 228, 61, 231;
|
|
16
|
+
--accent-secondary: #00dfd8;
|
|
17
|
+
--border: #333333;
|
|
18
|
+
--surface: #111111;
|
|
19
|
+
--success: #e43de7;
|
|
20
|
+
--warning: #f5a623;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
body {
|
|
24
|
+
background-color: var(--background);
|
|
25
|
+
color: var(--foreground);
|
|
26
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Custom Scrollbar */
|
|
31
|
+
::-webkit-scrollbar { width: 4px; height: 4px; }
|
|
32
|
+
::-webkit-scrollbar-track { background: transparent; }
|
|
33
|
+
::-webkit-scrollbar-thumb { background: #333; border-radius: 10px; }
|
|
34
|
+
::-webkit-scrollbar-thumb:hover { background: #444; }
|
|
35
|
+
|
|
36
|
+
.glass-header {
|
|
37
|
+
background: rgba(0, 0, 0, 0.8);
|
|
38
|
+
backdrop-filter: blur(12px);
|
|
39
|
+
border-bottom: 1px solid var(--border);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sidebar-border { border-right: 1px solid var(--border); }
|
|
43
|
+
.right-sidebar-border { border-left: 1px solid var(--border); }
|
|
44
|
+
|
|
45
|
+
.step-card {
|
|
46
|
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
47
|
+
border: 1px solid var(--border);
|
|
48
|
+
background: #0a0a0a;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.step-card.active {
|
|
52
|
+
border-color: var(--accent-primary);
|
|
53
|
+
box-shadow: 0 0 20px rgba(0, 112, 243, 0.1);
|
|
54
|
+
transform: scale(1.01);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.step-card.completed {
|
|
58
|
+
border-color: rgba(0, 112, 243, 0.3);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.pulse {
|
|
62
|
+
animation: pulse 2s infinite;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes pulse {
|
|
66
|
+
0% { opacity: 1; }
|
|
67
|
+
50% { opacity: 0.5; }
|
|
68
|
+
100% { opacity: 1; }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.terminal-line {
|
|
72
|
+
border-left: 2px solid var(--accent-primary);
|
|
73
|
+
padding-left: 12px;
|
|
74
|
+
margin-bottom: 8px;
|
|
75
|
+
animation: slideIn 0.3s ease-out;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@keyframes slideIn {
|
|
79
|
+
from { opacity: 0; transform: translateX(-10px); }
|
|
80
|
+
to { opacity: 1; transform: translateX(0); }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.badge {
|
|
84
|
+
font-size: 10px;
|
|
85
|
+
text-transform: uppercase;
|
|
86
|
+
letter-spacing: 0.05em;
|
|
87
|
+
padding: 2px 6px;
|
|
88
|
+
border-radius: 4px;
|
|
89
|
+
font-weight: 600;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.badge-blue { background: rgba(0, 112, 243, 0.1); color: #0070f3; border: 1px solid rgba(0, 112, 243, 0.2); }
|
|
93
|
+
.badge-green { background: rgba(0, 223, 216, 0.1); color: #00dfd8; border: 1px solid rgba(0, 223, 216, 0.2); }
|
|
94
|
+
|
|
95
|
+
.instruction-panel {
|
|
96
|
+
background: #050505;
|
|
97
|
+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.loader {
|
|
101
|
+
width: 14px;
|
|
102
|
+
height: 14px;
|
|
103
|
+
border: 2px solid rgba(255, 255, 255, 0.1);
|
|
104
|
+
border-top-color: var(--accent-primary);
|
|
105
|
+
border-radius: 50%;
|
|
106
|
+
animation: spin 0.8s linear infinite;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@keyframes spin {
|
|
110
|
+
to { transform: rotate(360deg); }
|
|
111
|
+
}
|
|
112
|
+
</style>
|
|
113
|
+
</head>
|
|
114
|
+
<body class="h-screen flex flex-col">
|
|
115
|
+
|
|
116
|
+
<!-- Header -->
|
|
117
|
+
<header class="glass-header h-14 flex items-center justify-between px-6 z-50">
|
|
118
|
+
<div class="flex items-center gap-4">
|
|
119
|
+
<div class="flex items-center gap-2">
|
|
120
|
+
<div class="w-6 h-6 bg-white rounded flex items-center justify-center">
|
|
121
|
+
<div class="w-3 h-3 bg-black transform rotate-45"></div>
|
|
122
|
+
</div>
|
|
123
|
+
<span class="font-bold text-sm tracking-tight">WIZARD_CORE</span>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="h-4 w-[1px] bg-neutral-800 mx-2"></div>
|
|
126
|
+
<div class="flex gap-6 text-[11px] font-medium text-neutral-400">
|
|
127
|
+
<div class="flex flex-col">
|
|
128
|
+
<span class="text-[9px] text-neutral-600 uppercase">Tokens</span>
|
|
129
|
+
<span class="text-white" id="total-tokens">0</span>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="flex flex-col">
|
|
132
|
+
<span class="text-[9px] text-neutral-600 uppercase">Rate</span>
|
|
133
|
+
<span class="text-white" id="token-rate">0/s</span>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="flex items-center gap-4">
|
|
139
|
+
<div id="status-badge" class="badge badge-blue flex items-center gap-2">
|
|
140
|
+
<div class="w-1.5 h-1.5 rounded-full bg-current"></div>
|
|
141
|
+
<span id="status-text">Ready</span>
|
|
142
|
+
</div>
|
|
143
|
+
<div class="h-8 w-8 rounded-full bg-neutral-900 border border-neutral-800 flex items-center justify-center overflow-hidden">
|
|
144
|
+
<img src="/placeholder.svg?height=32&width=32" alt="user" />
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</header>
|
|
148
|
+
|
|
149
|
+
<div class="flex-1 flex overflow-hidden">
|
|
150
|
+
<!-- Left Sidebar: Context -->
|
|
151
|
+
<aside class="w-72 sidebar-border flex flex-col bg-[#050505]">
|
|
152
|
+
<div class="p-4 border-bottom border-neutral-900 flex items-center justify-between">
|
|
153
|
+
<span class="text-[10px] uppercase font-bold text-neutral-500 tracking-widest">Context Data</span>
|
|
154
|
+
<i class="fas fa-database text-[10px] text-neutral-600"></i>
|
|
155
|
+
</div>
|
|
156
|
+
<div id="context-list" class="flex-1 overflow-y-auto p-4 space-y-3">
|
|
157
|
+
<!-- Context Items -->
|
|
158
|
+
</div>
|
|
159
|
+
</aside>
|
|
160
|
+
|
|
161
|
+
<!-- Main Content: Step Flow -->
|
|
162
|
+
<main class="flex-1 overflow-y-auto bg-black scroll-smooth">
|
|
163
|
+
<div class="max-w-3xl mx-auto py-12 px-6">
|
|
164
|
+
<div class="flex flex-col gap-8 relative" id="steps-container">
|
|
165
|
+
<!-- Timeline Line -->
|
|
166
|
+
<div class="absolute left-6 top-8 bottom-8 w-[1px] bg-neutral-800 -z-10"></div>
|
|
167
|
+
|
|
168
|
+
<!-- Steps dynamic -->
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</main>
|
|
172
|
+
|
|
173
|
+
<!-- Right Sidebar: Instructions & Live Feed -->
|
|
174
|
+
<aside class="w-80 right-sidebar-border flex flex-col instruction-panel">
|
|
175
|
+
<div class="p-4 border-b border-neutral-900 flex items-center justify-between">
|
|
176
|
+
<span class="text-[10px] uppercase font-bold text-neutral-500 tracking-widest">Execution Log</span>
|
|
177
|
+
<div class="flex gap-2">
|
|
178
|
+
<div class="w-2 h-2 rounded-full bg-neutral-800"></div>
|
|
179
|
+
<div class="w-2 h-2 rounded-full bg-neutral-800"></div>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
<div id="instruction-feed" class="flex-1 p-4 overflow-y-auto text-[12px] leading-relaxed text-neutral-300">
|
|
183
|
+
<div class="terminal-line text-neutral-500">System initialized. Waiting for command...</div>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<!-- Controls -->
|
|
187
|
+
<div class="p-6 border-t border-neutral-900 bg-black">
|
|
188
|
+
<div class="flex gap-2">
|
|
189
|
+
<button id="start-btn" class="flex-1 h-10 bg-white text-black text-[12px] font-bold rounded flex items-center justify-center gap-2 hover:bg-neutral-200 transition-colors">
|
|
190
|
+
<i class="fas fa-play text-[10px]"></i> START
|
|
191
|
+
</button>
|
|
192
|
+
<button id="pause-btn" class="hidden flex-1 h-10 bg-neutral-900 text-white text-[12px] font-bold rounded border border-neutral-800 flex items-center justify-center gap-2 hover:bg-neutral-800 transition-colors">
|
|
193
|
+
<i class="fas fa-pause text-[10px]"></i> PAUSE
|
|
194
|
+
</button>
|
|
195
|
+
<button id="stop-btn" class="w-10 h-10 bg-neutral-900 text-red-500 text-[12px] rounded border border-neutral-800 flex items-center justify-center hover:bg-red-500/10 transition-colors">
|
|
196
|
+
<i class="fas fa-stop"></i>
|
|
197
|
+
</button>
|
|
198
|
+
<button id="replay-btn" class="w-10 h-10 bg-neutral-900 text-neutral-400 text-[12px] rounded border border-neutral-800 flex items-center justify-center hover:bg-neutral-800 transition-colors">
|
|
199
|
+
<i class="fas fa-redo"></i>
|
|
200
|
+
</button>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</aside>
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
<script>
|
|
207
|
+
class WizardEngine {
|
|
208
|
+
constructor() {
|
|
209
|
+
this.ws = null;
|
|
210
|
+
this.steps = new Map();
|
|
211
|
+
this.context = new Map();
|
|
212
|
+
this.state = {
|
|
213
|
+
isRunning: false,
|
|
214
|
+
isPaused: false,
|
|
215
|
+
totalTokens: 0,
|
|
216
|
+
currentStepId: null
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
this.init();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
init() {
|
|
223
|
+
this.setupWebSocket();
|
|
224
|
+
this.setupListeners();
|
|
225
|
+
this.log("Wizard Engine V4.0 ready for deployment.");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
setupWebSocket() {
|
|
229
|
+
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
230
|
+
const wsUrl = `${protocol}//${location.host}`;
|
|
231
|
+
|
|
232
|
+
this.ws = new WebSocket(wsUrl);
|
|
233
|
+
|
|
234
|
+
this.ws.onopen = () => {
|
|
235
|
+
this.log("Connection established with production node.");
|
|
236
|
+
this.updateConnectionUI(true);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
this.ws.onmessage = (e) => {
|
|
240
|
+
const data = JSON.parse(e.data);
|
|
241
|
+
this.handleMessage(data);
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
this.ws.onclose = () => {
|
|
245
|
+
this.log("Connection lost. Retrying in 5s...", "error");
|
|
246
|
+
this.updateConnectionUI(false);
|
|
247
|
+
setTimeout(() => this.setupWebSocket(), 5000);
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
handleMessage(data) {
|
|
252
|
+
if (data.type === 'batch') {
|
|
253
|
+
data.messages.forEach(m => this.handleMessage(m));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
switch(data.type) {
|
|
258
|
+
case 'wizard_start': this.initSteps(data.steps); break;
|
|
259
|
+
case 'step_update': this.updateStep(data); break;
|
|
260
|
+
case 'token_update': this.updateTokens(data); break;
|
|
261
|
+
case 'context_update': this.updateContext(data); break;
|
|
262
|
+
case 'status_update': this.updateStatus(data.status); break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
initSteps(steps) {
|
|
267
|
+
const container = document.getElementById('steps-container');
|
|
268
|
+
container.innerHTML = '<div class="absolute left-6 top-8 bottom-8 w-[1px] bg-neutral-800 -z-10"></div>';
|
|
269
|
+
this.steps.clear();
|
|
270
|
+
|
|
271
|
+
const flatSteps = Array.isArray(steps[0]) ? steps[0] : steps;
|
|
272
|
+
|
|
273
|
+
flatSteps.forEach(step => {
|
|
274
|
+
const el = this.createStepElement(step);
|
|
275
|
+
container.appendChild(el);
|
|
276
|
+
this.steps.set(step.id, { el, data: step });
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
createStepElement(step) {
|
|
281
|
+
const div = document.createElement('div');
|
|
282
|
+
div.id = `step-${step.id}`;
|
|
283
|
+
div.className = `step-card p-6 rounded-xl flex gap-6 relative transition-all duration-500 opacity-40`;
|
|
284
|
+
div.innerHTML = `
|
|
285
|
+
<div class="flex-shrink-0 w-12 h-12 rounded-full border-2 border-neutral-800 bg-black flex items-center justify-center z-10 step-icon-container">
|
|
286
|
+
<span class="text-neutral-500 font-mono text-xs">${step.id.split('-').pop() || '01'}</span>
|
|
287
|
+
</div>
|
|
288
|
+
<div class="flex-1">
|
|
289
|
+
<div class="flex items-center justify-between mb-2">
|
|
290
|
+
<h3 class="text-sm font-bold text-white">${step.id}</h3>
|
|
291
|
+
<div class="flex items-center">
|
|
292
|
+
<span class="text-[10px] text-neutral-600 font-mono uppercase status-label">Waiting</span>
|
|
293
|
+
<button class="replay-btn hidden text-neutral-500 hover:text-white text-xs ml-2" onclick="engine.sendMessage({ type: 'goto', stepId: '${step.id}' })"><i class="fas fa-redo"></i></button>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
<p class="text-[12px] text-neutral-500 leading-relaxed mb-4">${step.instruction || 'Processing...'}</p>
|
|
297
|
+
<div class="step-content hidden border-t border-neutral-900 pt-4 mt-4">
|
|
298
|
+
<!-- Dynamic form fields -->
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
`;
|
|
302
|
+
return div;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
updateStep(data) {
|
|
306
|
+
const step = this.steps.get(data.stepId);
|
|
307
|
+
if (!step) return;
|
|
308
|
+
|
|
309
|
+
const { el } = step;
|
|
310
|
+
el.className = `step-card p-6 rounded-xl flex gap-6 relative transition-all duration-500 ${data.status}`;
|
|
311
|
+
|
|
312
|
+
const iconContainer = el.querySelector('.step-icon-container');
|
|
313
|
+
const statusLabel = el.querySelector('.status-label');
|
|
314
|
+
const content = el.querySelector('.step-content');
|
|
315
|
+
|
|
316
|
+
if (data.status === 'current') {
|
|
317
|
+
el.classList.add('active', 'opacity-100');
|
|
318
|
+
iconContainer.innerHTML = '<div class="loader"></div>';
|
|
319
|
+
iconContainer.style.borderColor = 'var(--accent-primary)';
|
|
320
|
+
statusLabel.textContent = 'Running';
|
|
321
|
+
statusLabel.className = 'text-[10px] font-mono uppercase status-label pulse';
|
|
322
|
+
statusLabel.style.color = 'var(--accent-primary)';
|
|
323
|
+
el.querySelector('.replay-btn').classList.add('hidden');
|
|
324
|
+
this.log(`Executing: ${data.stepId} - ${data.instruction || 'Processing...'}`);
|
|
325
|
+
|
|
326
|
+
if (data.fields && data.fields.length > 0) {
|
|
327
|
+
this.createStepForm(content, data.stepId, data.fields);
|
|
328
|
+
content.classList.remove('hidden');
|
|
329
|
+
} else if (data.instruction) {
|
|
330
|
+
const instEl = document.createElement('div');
|
|
331
|
+
instEl.className = 'text-[11px] text-neutral-400 bg-neutral-900/50 p-3 rounded mt-2 border border-neutral-800';
|
|
332
|
+
instEl.innerHTML = marked.parse(data.instruction);
|
|
333
|
+
content.innerHTML = '';
|
|
334
|
+
content.appendChild(instEl);
|
|
335
|
+
content.classList.remove('hidden');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
339
|
+
} else if (data.status === 'completed') {
|
|
340
|
+
el.classList.add('completed', 'opacity-100');
|
|
341
|
+
el.classList.remove('active');
|
|
342
|
+
iconContainer.innerHTML = '<i class="fas fa-check text-[12px]"></i>';
|
|
343
|
+
iconContainer.style.borderColor = 'rgba(var(--accent-primary-rgb), 0.3)';
|
|
344
|
+
iconContainer.querySelector('i').style.color = 'var(--accent-primary)';
|
|
345
|
+
statusLabel.textContent = 'Done';
|
|
346
|
+
statusLabel.className = 'text-[10px] text-neutral-500 font-mono uppercase status-label';
|
|
347
|
+
el.querySelector('.replay-btn').classList.remove('hidden');
|
|
348
|
+
|
|
349
|
+
if (data.data) {
|
|
350
|
+
const outputEl = document.createElement('div');
|
|
351
|
+
outputEl.className = 'text-[11px] text-neutral-300 bg-neutral-900/50 p-3 rounded mt-2 border border-neutral-800 font-mono relative';
|
|
352
|
+
const preEl = document.createElement('pre');
|
|
353
|
+
preEl.className = 'whitespace-pre-wrap break-words max-h-64 overflow-y-auto';
|
|
354
|
+
preEl.textContent = typeof data.data === 'string' ? data.data : JSON.stringify(data.data, null, 2);
|
|
355
|
+
const copyBtn = document.createElement('button');
|
|
356
|
+
copyBtn.className = 'absolute top-2 right-2 text-neutral-500 hover:text-white text-xs';
|
|
357
|
+
copyBtn.innerHTML = '<i class="fas fa-copy"></i>';
|
|
358
|
+
copyBtn.onclick = () => {
|
|
359
|
+
navigator.clipboard.writeText(preEl.textContent);
|
|
360
|
+
copyBtn.innerHTML = '<i class="fas fa-check"></i>';
|
|
361
|
+
setTimeout(() => copyBtn.innerHTML = '<i class="fas fa-copy"></i>', 1000);
|
|
362
|
+
};
|
|
363
|
+
outputEl.appendChild(preEl);
|
|
364
|
+
outputEl.appendChild(copyBtn);
|
|
365
|
+
content.innerHTML = '';
|
|
366
|
+
content.appendChild(outputEl);
|
|
367
|
+
content.classList.remove('hidden');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
updateContext(data) {
|
|
373
|
+
this.context.clear();
|
|
374
|
+
Object.entries(data.context).forEach(([key, value]) => {
|
|
375
|
+
this.context.set(key, value);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const list = document.getElementById('context-list');
|
|
379
|
+
list.innerHTML = '';
|
|
380
|
+
|
|
381
|
+
Object.entries(data.context).forEach(([key, value]) => {
|
|
382
|
+
const item = document.createElement('div');
|
|
383
|
+
item.className = 'p-3 bg-neutral-900 border border-neutral-800 rounded-lg group cursor-pointer hover:border-neutral-700 transition-all';
|
|
384
|
+
|
|
385
|
+
const type = Array.isArray(value) ? 'ARRAY' : typeof value;
|
|
386
|
+
const displayContent = typeof value === 'string' ? value :
|
|
387
|
+
Array.isArray(value) ? JSON.stringify(value, null, 2) :
|
|
388
|
+
JSON.stringify(value, null, 2);
|
|
389
|
+
|
|
390
|
+
item.innerHTML = `
|
|
391
|
+
<div class="flex items-center justify-between mb-1">
|
|
392
|
+
<span class="text-[11px] font-bold text-neutral-300">${key}</span>
|
|
393
|
+
<div class="flex items-center gap-1">
|
|
394
|
+
<span class="text-[9px] text-neutral-600 uppercase font-mono">${type.toUpperCase()}</span>
|
|
395
|
+
<button class="text-neutral-500 hover:text-white text-xs copy-btn" data-key="${key}">
|
|
396
|
+
<i class="fas fa-copy"></i>
|
|
397
|
+
</button>
|
|
398
|
+
</div>
|
|
399
|
+
</div>
|
|
400
|
+
<pre class="text-[10px] text-neutral-500 whitespace-pre-wrap break-words max-h-32 overflow-y-auto">${displayContent}</pre>
|
|
401
|
+
`;
|
|
402
|
+
|
|
403
|
+
item.querySelector('.copy-btn').onclick = (e) => {
|
|
404
|
+
e.stopPropagation();
|
|
405
|
+
const btn = e.target.closest('.copy-btn');
|
|
406
|
+
const key = btn.dataset.key;
|
|
407
|
+
const value = this.context.get(key);
|
|
408
|
+
const copyText = typeof value === 'string' ? value : JSON.stringify(value, null, 2);
|
|
409
|
+
navigator.clipboard.writeText(copyText);
|
|
410
|
+
btn.innerHTML = '<i class="fas fa-check"></i>';
|
|
411
|
+
setTimeout(() => btn.innerHTML = '<i class="fas fa-copy"></i>', 1000);
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
list.appendChild(item);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
updateStatus(status) {
|
|
419
|
+
this.state = { ...this.state, ...status };
|
|
420
|
+
const startBtn = document.getElementById('start-btn');
|
|
421
|
+
const pauseBtn = document.getElementById('pause-btn');
|
|
422
|
+
const statusBadge = document.getElementById('status-badge');
|
|
423
|
+
const statusText = document.getElementById('status-text');
|
|
424
|
+
|
|
425
|
+
if (status.isRunning && !status.isPaused) {
|
|
426
|
+
startBtn.classList.add('hidden');
|
|
427
|
+
pauseBtn.classList.remove('hidden');
|
|
428
|
+
statusBadge.className = 'badge badge-green flex items-center gap-2';
|
|
429
|
+
statusText.textContent = 'Running';
|
|
430
|
+
} else if (status.isPaused) {
|
|
431
|
+
if (status.isStepMode) {
|
|
432
|
+
pauseBtn.innerHTML = '<i class="fas fa-step-forward text-[10px]"></i> NEXT STEP';
|
|
433
|
+
pauseBtn.onclick = () => this.sendMessage({ type: 'step_forward' });
|
|
434
|
+
} else {
|
|
435
|
+
pauseBtn.innerHTML = '<i class="fas fa-play text-[10px]"></i> RESUME';
|
|
436
|
+
pauseBtn.onclick = () => this.sendMessage({ type: 'resume' });
|
|
437
|
+
}
|
|
438
|
+
statusText.textContent = 'Paused';
|
|
439
|
+
} else {
|
|
440
|
+
startBtn.classList.remove('hidden');
|
|
441
|
+
pauseBtn.classList.add('hidden');
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
log(msg, type = "info") {
|
|
446
|
+
const feed = document.getElementById('instruction-feed');
|
|
447
|
+
const line = document.createElement('div');
|
|
448
|
+
line.className = `terminal-line ${type === 'error' ? 'text-red-500 border-red-500' : 'text-neutral-300'}`;
|
|
449
|
+
line.innerHTML = `<span class="text-neutral-600 mr-2">[${new Date().toLocaleTimeString([], {hour12: false})}]</span> ${msg}`;
|
|
450
|
+
feed.appendChild(line);
|
|
451
|
+
feed.scrollTop = feed.scrollHeight;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
setupListeners() {
|
|
455
|
+
document.getElementById('start-btn').onclick = () => this.sendMessage({ type: 'run' });
|
|
456
|
+
document.getElementById('pause-btn').onclick = () => this.sendMessage({ type: 'pause' });
|
|
457
|
+
document.getElementById('stop-btn').onclick = () => this.sendMessage({ type: 'stop' });
|
|
458
|
+
document.getElementById('replay-btn').onclick = () => this.sendMessage({ type: 'resume' });
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
sendMessage(message) {
|
|
462
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
463
|
+
this.ws.send(JSON.stringify(message));
|
|
464
|
+
this.log(`Manual trigger: ${message.type.toUpperCase()}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
updateConnectionUI(connected) {
|
|
469
|
+
const badge = document.getElementById('status-badge');
|
|
470
|
+
badge.classList.toggle('opacity-50', !connected);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
updateTokens(data) {
|
|
474
|
+
document.getElementById('total-tokens').textContent = data.totalTokens.toLocaleString();
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const engine = new WizardEngine();
|
|
479
|
+
</script>
|
|
480
|
+
</body>
|
|
481
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@swizzy_ai/kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A TypeScript library for building wizard-like workflows with LLM integration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rollup -c",
|
|
9
|
+
"build:tsc": "tsc",
|
|
10
|
+
"clean": "rm -rf dist",
|
|
11
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"wizard",
|
|
15
|
+
"llm",
|
|
16
|
+
"workflow",
|
|
17
|
+
"typescript"
|
|
18
|
+
],
|
|
19
|
+
"author": "Olufemi Oluwatobi <tobilobaolufemi001@gmail.com>",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/swizzy-ai/swizzy-kit.git"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/swizzy-ai/swizzy-kit#readme",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/swizzy-ai/swizzy-kit/issues"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@ai-sdk/anthropic": "^1.0.0",
|
|
31
|
+
"@ai-sdk/google": "^1.0.0",
|
|
32
|
+
"@ai-sdk/openai": "^1.0.0",
|
|
33
|
+
"@ai-sdk/xai": "^1.0.0",
|
|
34
|
+
"ai": "^4.0.0",
|
|
35
|
+
"ws": "^8.14.2",
|
|
36
|
+
"zod": "^3.22.4"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
40
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
41
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
42
|
+
"@types/node": "^20.10.5",
|
|
43
|
+
"@types/ws": "^8.5.8",
|
|
44
|
+
"rollup": "^4.9.6",
|
|
45
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
46
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
47
|
+
"tslib": "^2.6.2",
|
|
48
|
+
"typescript": "^5.3.3"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist"
|
|
52
|
+
]
|
|
53
|
+
}
|