ai-progress-controls 0.1.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +823 -0
  3. package/dist/ai-progress-controls.es.js +7191 -0
  4. package/dist/ai-progress-controls.es.js.map +1 -0
  5. package/dist/ai-progress-controls.umd.js +2 -0
  6. package/dist/ai-progress-controls.umd.js.map +1 -0
  7. package/dist/index.d.ts +2212 -0
  8. package/package.json +105 -0
  9. package/src/__tests__/setup.ts +93 -0
  10. package/src/core/base/AIControl.ts +230 -0
  11. package/src/core/base/index.ts +3 -0
  12. package/src/core/base/types.ts +77 -0
  13. package/src/core/base/utils.ts +168 -0
  14. package/src/core/batch-progress/BatchProgress.test.ts +458 -0
  15. package/src/core/batch-progress/BatchProgress.ts +760 -0
  16. package/src/core/batch-progress/index.ts +14 -0
  17. package/src/core/batch-progress/styles.ts +480 -0
  18. package/src/core/batch-progress/types.ts +169 -0
  19. package/src/core/model-loader/ModelLoader.test.ts +311 -0
  20. package/src/core/model-loader/ModelLoader.ts +673 -0
  21. package/src/core/model-loader/index.ts +2 -0
  22. package/src/core/model-loader/styles.ts +496 -0
  23. package/src/core/model-loader/types.ts +127 -0
  24. package/src/core/parameter-panel/ParameterPanel.test.ts +856 -0
  25. package/src/core/parameter-panel/ParameterPanel.ts +877 -0
  26. package/src/core/parameter-panel/index.ts +14 -0
  27. package/src/core/parameter-panel/styles.ts +323 -0
  28. package/src/core/parameter-panel/types.ts +278 -0
  29. package/src/core/parameter-slider/ParameterSlider.test.ts +299 -0
  30. package/src/core/parameter-slider/ParameterSlider.ts +653 -0
  31. package/src/core/parameter-slider/index.ts +8 -0
  32. package/src/core/parameter-slider/styles.ts +493 -0
  33. package/src/core/parameter-slider/types.ts +107 -0
  34. package/src/core/queue-progress/QueueProgress.test.ts +344 -0
  35. package/src/core/queue-progress/QueueProgress.ts +563 -0
  36. package/src/core/queue-progress/index.ts +5 -0
  37. package/src/core/queue-progress/styles.ts +469 -0
  38. package/src/core/queue-progress/types.ts +130 -0
  39. package/src/core/retry-progress/RetryProgress.test.ts +397 -0
  40. package/src/core/retry-progress/RetryProgress.ts +957 -0
  41. package/src/core/retry-progress/index.ts +6 -0
  42. package/src/core/retry-progress/styles.ts +530 -0
  43. package/src/core/retry-progress/types.ts +176 -0
  44. package/src/core/stream-progress/StreamProgress.test.ts +531 -0
  45. package/src/core/stream-progress/StreamProgress.ts +517 -0
  46. package/src/core/stream-progress/index.ts +2 -0
  47. package/src/core/stream-progress/styles.ts +349 -0
  48. package/src/core/stream-progress/types.ts +82 -0
  49. package/src/index.ts +19 -0
@@ -0,0 +1,14 @@
1
+ export { ParameterPanel } from './ParameterPanel';
2
+ export type {
3
+ ParameterDefinition,
4
+ PresetConfiguration,
5
+ ParameterPanelConfig,
6
+ ParameterPanelState,
7
+ PanelChangeEvent,
8
+ PresetLoadEvent,
9
+ ConfigExportEvent,
10
+ ConfigImportEvent,
11
+ PanelResetEvent,
12
+ ValidationErrorEvent,
13
+ ExportedConfig,
14
+ } from './types';
@@ -0,0 +1,323 @@
1
+ export const styles = `
2
+ :host {
3
+ display: block;
4
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
5
+ --panel-bg: #ffffff;
6
+ --panel-border: #e5e7eb;
7
+ --panel-text: #1f2937;
8
+ --panel-text-secondary: #6b7280;
9
+ --panel-header-bg: #f9fafb;
10
+ --panel-primary: #2563eb;
11
+ --panel-primary-hover: #1d4ed8;
12
+ --panel-danger: #dc2626;
13
+ --panel-danger-hover: #b91c1c;
14
+ --panel-success: #16a34a;
15
+ --panel-radius: 12px;
16
+ --panel-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
17
+ }
18
+
19
+ .container {
20
+ background: var(--panel-bg);
21
+ border: 1px solid var(--panel-border);
22
+ border-radius: var(--panel-radius);
23
+ box-shadow: var(--panel-shadow);
24
+ overflow: hidden;
25
+ }
26
+
27
+ .header {
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ padding: 16px 20px;
32
+ background: var(--panel-header-bg);
33
+ border-bottom: 1px solid var(--panel-border);
34
+ }
35
+
36
+ .header.collapsible {
37
+ cursor: pointer;
38
+ user-select: none;
39
+ }
40
+
41
+ .header.collapsible:hover {
42
+ background: #f3f4f6;
43
+ }
44
+
45
+ .title-section {
46
+ display: flex;
47
+ align-items: center;
48
+ gap: 12px;
49
+ flex: 1;
50
+ }
51
+
52
+ .title {
53
+ font-size: 18px;
54
+ font-weight: 600;
55
+ color: var(--panel-text);
56
+ margin: 0;
57
+ }
58
+
59
+ .dirty-indicator {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ width: 8px;
64
+ height: 8px;
65
+ background: var(--panel-primary);
66
+ border-radius: 50%;
67
+ opacity: 0;
68
+ transition: opacity 0.2s;
69
+ }
70
+
71
+ .dirty-indicator.show {
72
+ opacity: 1;
73
+ }
74
+
75
+ .collapse-icon {
76
+ font-size: 20px;
77
+ color: var(--panel-text-secondary);
78
+ transition: transform 0.2s;
79
+ }
80
+
81
+ .collapse-icon.collapsed {
82
+ transform: rotate(-90deg);
83
+ }
84
+
85
+ .content {
86
+ max-height: 2000px;
87
+ overflow: hidden;
88
+ transition: max-height 0.3s ease-out, padding 0.3s ease-out;
89
+ }
90
+
91
+ .content.collapsed {
92
+ max-height: 0;
93
+ padding: 0 !important;
94
+ }
95
+
96
+ .presets-section {
97
+ padding: 16px 20px;
98
+ border-bottom: 1px solid var(--panel-border);
99
+ background: var(--panel-header-bg);
100
+ }
101
+
102
+ .presets-label {
103
+ font-size: 12px;
104
+ font-weight: 600;
105
+ text-transform: uppercase;
106
+ letter-spacing: 0.05em;
107
+ color: var(--panel-text-secondary);
108
+ margin-bottom: 10px;
109
+ }
110
+
111
+ .presets-buttons {
112
+ display: flex;
113
+ flex-wrap: wrap;
114
+ gap: 8px;
115
+ }
116
+
117
+ .preset-btn {
118
+ padding: 8px 16px;
119
+ background: white;
120
+ border: 1px solid var(--panel-border);
121
+ border-radius: 6px;
122
+ font-size: 14px;
123
+ font-weight: 500;
124
+ color: var(--panel-text);
125
+ cursor: pointer;
126
+ transition: all 0.2s;
127
+ display: flex;
128
+ align-items: center;
129
+ gap: 6px;
130
+ }
131
+
132
+ .preset-btn:hover {
133
+ border-color: var(--panel-primary);
134
+ background: #eff6ff;
135
+ }
136
+
137
+ .preset-btn.active {
138
+ background: var(--panel-primary);
139
+ color: white;
140
+ border-color: var(--panel-primary);
141
+ }
142
+
143
+ .preset-btn .icon {
144
+ font-size: 16px;
145
+ }
146
+
147
+ .preset-btn:disabled {
148
+ opacity: 0.5;
149
+ cursor: not-allowed;
150
+ }
151
+
152
+ .parameters-section {
153
+ padding: 20px;
154
+ }
155
+
156
+ .parameters-grid {
157
+ display: grid;
158
+ gap: 20px;
159
+ }
160
+
161
+ .parameters-grid.layout-grid {
162
+ grid-template-columns: repeat(var(--grid-columns, 2), 1fr);
163
+ }
164
+
165
+ .parameters-grid.layout-vertical {
166
+ grid-template-columns: 1fr;
167
+ }
168
+
169
+ @media (max-width: 768px) {
170
+ .parameters-grid.layout-grid {
171
+ grid-template-columns: 1fr;
172
+ }
173
+ }
174
+
175
+ .parameter-wrapper {
176
+ display: block;
177
+ }
178
+
179
+ .actions-section {
180
+ padding: 16px 20px;
181
+ border-top: 1px solid var(--panel-border);
182
+ background: var(--panel-header-bg);
183
+ display: flex;
184
+ align-items: center;
185
+ justify-content: space-between;
186
+ flex-wrap: wrap;
187
+ gap: 12px;
188
+ }
189
+
190
+ .actions-left,
191
+ .actions-right {
192
+ display: flex;
193
+ gap: 8px;
194
+ flex-wrap: wrap;
195
+ }
196
+
197
+ .action-btn {
198
+ padding: 8px 16px;
199
+ background: white;
200
+ border: 1px solid var(--panel-border);
201
+ border-radius: 6px;
202
+ font-size: 14px;
203
+ font-weight: 500;
204
+ color: var(--panel-text);
205
+ cursor: pointer;
206
+ transition: all 0.2s;
207
+ display: flex;
208
+ align-items: center;
209
+ gap: 6px;
210
+ }
211
+
212
+ .action-btn:hover {
213
+ background: #f9fafb;
214
+ border-color: var(--panel-primary);
215
+ }
216
+
217
+ .action-btn.primary {
218
+ background: var(--panel-primary);
219
+ color: white;
220
+ border-color: var(--panel-primary);
221
+ }
222
+
223
+ .action-btn.primary:hover {
224
+ background: var(--panel-primary-hover);
225
+ }
226
+
227
+ .action-btn.danger {
228
+ color: var(--panel-danger);
229
+ }
230
+
231
+ .action-btn.danger:hover {
232
+ background: #fef2f2;
233
+ border-color: var(--panel-danger);
234
+ }
235
+
236
+ .action-btn:disabled {
237
+ opacity: 0.5;
238
+ cursor: not-allowed;
239
+ }
240
+
241
+ .validation-errors {
242
+ padding: 12px 20px;
243
+ background: #fef2f2;
244
+ border-bottom: 1px solid #fecaca;
245
+ display: none;
246
+ }
247
+
248
+ .validation-errors.show {
249
+ display: block;
250
+ }
251
+
252
+ .error-item {
253
+ display: flex;
254
+ align-items: center;
255
+ gap: 8px;
256
+ color: var(--panel-danger);
257
+ font-size: 13px;
258
+ margin: 4px 0;
259
+ }
260
+
261
+ .error-icon {
262
+ font-size: 16px;
263
+ }
264
+
265
+ .empty-state {
266
+ padding: 40px 20px;
267
+ text-align: center;
268
+ color: var(--panel-text-secondary);
269
+ }
270
+
271
+ .empty-state-icon {
272
+ font-size: 48px;
273
+ margin-bottom: 12px;
274
+ opacity: 0.5;
275
+ }
276
+
277
+ .empty-state-text {
278
+ font-size: 14px;
279
+ }
280
+
281
+ /* Dark mode support */
282
+ :host([theme="dark"]) {
283
+ --panel-bg: #1f2937;
284
+ --panel-border: #374151;
285
+ --panel-text: #f9fafb;
286
+ --panel-text-secondary: #9ca3af;
287
+ --panel-header-bg: #111827;
288
+ --panel-primary: #3b82f6;
289
+ --panel-primary-hover: #2563eb;
290
+ --panel-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
291
+ }
292
+
293
+ /* Loading state */
294
+ .loading {
295
+ position: relative;
296
+ pointer-events: none;
297
+ opacity: 0.6;
298
+ }
299
+
300
+ .loading::after {
301
+ content: '';
302
+ position: absolute;
303
+ top: 50%;
304
+ left: 50%;
305
+ width: 24px;
306
+ height: 24px;
307
+ margin: -12px 0 0 -12px;
308
+ border: 3px solid var(--panel-border);
309
+ border-top-color: var(--panel-primary);
310
+ border-radius: 50%;
311
+ animation: spin 0.6s linear infinite;
312
+ }
313
+
314
+ @keyframes spin {
315
+ to { transform: rotate(360deg); }
316
+ }
317
+
318
+ /* Disabled state */
319
+ :host([disabled]) .container {
320
+ opacity: 0.6;
321
+ pointer-events: none;
322
+ }
323
+ `;
@@ -0,0 +1,278 @@
1
+ import type { PresetValue } from '../parameter-slider/types';
2
+
3
+ /**
4
+ * Parameter definition for a single slider in the panel
5
+ */
6
+ export interface ParameterDefinition {
7
+ /** Unique parameter ID */
8
+ id: string;
9
+
10
+ /** Display label */
11
+ label: string;
12
+
13
+ /** Minimum value */
14
+ min: number;
15
+
16
+ /** Maximum value */
17
+ max: number;
18
+
19
+ /** Current/default value */
20
+ value: number;
21
+
22
+ /** Step size for slider */
23
+ step?: number;
24
+
25
+ /** Number of decimal places to display */
26
+ decimals?: number;
27
+
28
+ /** Parameter description/help text */
29
+ description?: string;
30
+
31
+ /** Unit suffix (e.g., '%', 'tokens') */
32
+ unit?: string;
33
+
34
+ /** Preset values for this parameter */
35
+ presets?: PresetValue[];
36
+
37
+ /** Show manual input field */
38
+ showInput?: boolean;
39
+
40
+ /** Show reset button */
41
+ showReset?: boolean;
42
+
43
+ /** Disabled state */
44
+ disabled?: boolean;
45
+
46
+ /** Validation function */
47
+ validate?: (value: number, allValues: Record<string, number>) => boolean | string;
48
+ }
49
+
50
+ /**
51
+ * Preset configuration containing values for all parameters
52
+ */
53
+ export interface PresetConfiguration {
54
+ /** Preset name (display) */
55
+ name: string;
56
+
57
+ /** Preset description */
58
+ description?: string;
59
+
60
+ /** Parameter values */
61
+ values: Record<string, number>;
62
+
63
+ /** Optional icon/emoji */
64
+ icon?: string;
65
+
66
+ /** Is this a built-in preset? */
67
+ isBuiltIn?: boolean;
68
+ }
69
+
70
+ /**
71
+ * Configuration options for ParameterPanel
72
+ */
73
+ export interface ParameterPanelConfig {
74
+ /** Array of parameter definitions */
75
+ parameters: ParameterDefinition[];
76
+
77
+ /** Built-in and custom presets */
78
+ presets?: Record<string, PresetConfiguration>;
79
+
80
+ /** Default preset to load on initialization */
81
+ defaultPreset?: string;
82
+
83
+ /** Layout style: grid or vertical */
84
+ layout?: 'grid' | 'vertical';
85
+
86
+ /** Number of columns for grid layout */
87
+ columns?: number;
88
+
89
+ /** Panel title */
90
+ title?: string;
91
+
92
+ /** Show preset selector buttons */
93
+ showPresets?: boolean;
94
+
95
+ /** Show reset all button */
96
+ showResetAll?: boolean;
97
+
98
+ /** Show export/import buttons */
99
+ showExportImport?: boolean;
100
+
101
+ /** Enable value persistence to localStorage */
102
+ persistValues?: boolean;
103
+
104
+ /** Enable preset persistence to localStorage */
105
+ persistPresets?: boolean;
106
+
107
+ /** LocalStorage key for persistence */
108
+ storageKey?: string;
109
+
110
+ /** Make panel collapsible */
111
+ collapsible?: boolean;
112
+
113
+ /** Start collapsed */
114
+ startCollapsed?: boolean;
115
+
116
+ /** Validate parameters on change */
117
+ validateOnChange?: boolean;
118
+
119
+ /** Emit change events */
120
+ emitChangeEvents?: boolean;
121
+
122
+ /** Disabled state for entire panel */
123
+ disabled?: boolean;
124
+
125
+ /** Enable debug logging */
126
+ debug?: boolean;
127
+
128
+ /** Additional CSS class */
129
+ className?: string;
130
+
131
+ /** ARIA label for accessibility */
132
+ ariaLabel?: string;
133
+ }
134
+
135
+ /**
136
+ * Internal state of the ParameterPanel
137
+ */
138
+ export interface ParameterPanelState {
139
+ /** Current values for all parameters */
140
+ values: Record<string, number>;
141
+
142
+ /** Currently active preset name */
143
+ activePreset: string | null;
144
+
145
+ /** Is panel collapsed */
146
+ isCollapsed: boolean;
147
+
148
+ /** Validation errors by parameter ID */
149
+ errors: Record<string, string>;
150
+
151
+ /** Are any parameters being modified */
152
+ isDirty: boolean;
153
+ }
154
+
155
+ /**
156
+ * Event detail when any parameter changes
157
+ */
158
+ export interface PanelChangeEvent {
159
+ /** Changed parameter ID */
160
+ parameterId: string;
161
+
162
+ /** New value */
163
+ value: number;
164
+
165
+ /** Previous value */
166
+ previousValue: number;
167
+
168
+ /** All current values */
169
+ allValues: Record<string, number>;
170
+
171
+ /** Source of change */
172
+ source: 'slider' | 'input' | 'preset' | 'reset' | 'import';
173
+
174
+ /** Timestamp */
175
+ timestamp: number;
176
+ }
177
+
178
+ /**
179
+ * Event detail when preset is loaded
180
+ */
181
+ export interface PresetLoadEvent {
182
+ /** Preset name/ID */
183
+ presetId: string;
184
+
185
+ /** Preset configuration */
186
+ preset: PresetConfiguration;
187
+
188
+ /** Previous values before preset load */
189
+ previousValues: Record<string, number>;
190
+
191
+ /** Timestamp */
192
+ timestamp: number;
193
+ }
194
+
195
+ /**
196
+ * Event detail when configuration is exported
197
+ */
198
+ export interface ConfigExportEvent {
199
+ /** Exported configuration */
200
+ config: ExportedConfig;
201
+
202
+ /** Export format */
203
+ format: 'json' | 'url';
204
+
205
+ /** Timestamp */
206
+ timestamp: number;
207
+ }
208
+
209
+ /**
210
+ * Event detail when configuration is imported
211
+ */
212
+ export interface ConfigImportEvent {
213
+ /** Imported configuration */
214
+ config: ExportedConfig;
215
+
216
+ /** Previous values */
217
+ previousValues: Record<string, number>;
218
+
219
+ /** Timestamp */
220
+ timestamp: number;
221
+ }
222
+
223
+ /**
224
+ * Event detail when panel is reset
225
+ */
226
+ export interface PanelResetEvent {
227
+ /** Previous values before reset */
228
+ previousValues: Record<string, number>;
229
+
230
+ /** New values after reset */
231
+ newValues: Record<string, number>;
232
+
233
+ /** Timestamp */
234
+ timestamp: number;
235
+ }
236
+
237
+ /**
238
+ * Event detail when validation fails
239
+ */
240
+ export interface ValidationErrorEvent {
241
+ /** Parameter ID with error */
242
+ parameterId: string;
243
+
244
+ /** Error message */
245
+ error: string;
246
+
247
+ /** Current value */
248
+ value: number;
249
+
250
+ /** Timestamp */
251
+ timestamp: number;
252
+ }
253
+
254
+ /**
255
+ * Exported configuration format
256
+ */
257
+ export interface ExportedConfig {
258
+ /** Format version */
259
+ version: string;
260
+
261
+ /** Preset name if applicable */
262
+ preset?: string;
263
+
264
+ /** Parameter values */
265
+ parameters: Record<string, number>;
266
+
267
+ /** Metadata */
268
+ metadata?: {
269
+ /** Creation timestamp */
270
+ created: string;
271
+
272
+ /** Configuration name */
273
+ name?: string;
274
+
275
+ /** Description */
276
+ description?: string;
277
+ };
278
+ }