lastriko 0.1.4 → 0.1.7
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 +1 -1
- package/dist/__tests__/integration/ws-flow.integration.test.js +38 -140
- package/dist/__tests__/integration/ws-flow.integration.test.js.map +1 -1
- package/dist/client/events.js +91 -63
- package/dist/client/events.js.map +1 -1
- package/dist/client/swap.d.ts +14 -1
- package/dist/client/swap.js +185 -7
- package/dist/client/swap.js.map +1 -1
- package/dist/client/ws.d.ts +1 -0
- package/dist/client/ws.js +127 -40
- package/dist/client/ws.js.map +1 -1
- package/dist/client/ws.test.js +5 -309
- package/dist/client/ws.test.js.map +1 -1
- package/dist/components/context.d.ts +13 -1
- package/dist/components/context.js +312 -1
- package/dist/components/context.js.map +1 -1
- package/dist/components/context.test.js +73 -116
- package/dist/components/context.test.js.map +1 -1
- package/dist/components/registry.d.ts +2 -2
- package/dist/components/registry.js +52 -4
- package/dist/components/registry.js.map +1 -1
- package/dist/components/types.d.ts +175 -3
- package/dist/engine/executor.js +11 -0
- package/dist/engine/executor.js.map +1 -1
- package/dist/engine/executor.test.js +19 -10
- package/dist/engine/executor.test.js.map +1 -1
- package/dist/engine/messages.d.ts +9 -1
- package/dist/engine/messages.js.map +1 -1
- package/dist/engine/messages.test.d.ts +1 -0
- package/dist/engine/messages.test.js +39 -0
- package/dist/engine/messages.test.js.map +1 -0
- package/dist/engine/renderer.js +211 -7
- package/dist/engine/renderer.js.map +1 -1
- package/dist/engine/renderer.test.js +218 -234
- package/dist/engine/renderer.test.js.map +1 -1
- package/dist/engine/server.d.ts +1 -0
- package/dist/engine/server.js +41 -5
- package/dist/engine/server.js.map +1 -1
- package/dist/engine/server.test.js +62 -4
- package/dist/engine/server.test.js.map +1 -1
- package/dist/engine/watcher.d.ts +17 -1
- package/dist/engine/watcher.js +42 -5
- package/dist/engine/watcher.js.map +1 -1
- package/dist/engine/watcher.test.d.ts +1 -0
- package/dist/engine/watcher.test.js +62 -0
- package/dist/engine/watcher.test.js.map +1 -0
- package/dist/engine/websocket.hub.test.js +24 -0
- package/dist/engine/websocket.hub.test.js.map +1 -1
- package/dist/engine/websocket.js +0 -1
- package/dist/engine/websocket.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,130 +1,87 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { UIContext } from './context';
|
|
3
3
|
import { createConnectionScope } from './registry';
|
|
4
|
-
describe('uiContext', () => {
|
|
5
|
-
it('creates
|
|
6
|
-
const scope = createConnectionScope('
|
|
4
|
+
describe('uiContext Phase 3', () => {
|
|
5
|
+
it('creates and updates phase 3 input handles', () => {
|
|
6
|
+
const scope = createConnectionScope('p3-ctx-inputs');
|
|
7
7
|
const ui = new UIContext(scope);
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
expect(
|
|
13
|
-
expect(
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
const multi = ui.multiSelect('Tags', ['a', 'b', 'c'], { defaults: ['a', 'c'], maxSelections: 2 });
|
|
9
|
+
const color = ui.colorPicker('Color', { default: '#112233' });
|
|
10
|
+
const date = ui.dateInput('Date', { default: '2026-04-08' });
|
|
11
|
+
expect(multi.value).toEqual(['a', 'c']);
|
|
12
|
+
expect(color.value).toBe('#112233');
|
|
13
|
+
expect(date.value).toBe('2026-04-08');
|
|
14
|
+
multi.update({ value: ['b', 'c', 'a'] });
|
|
15
|
+
color.update({ value: '#abcdef' });
|
|
16
|
+
date.update({ value: '2026-05-01' });
|
|
17
|
+
expect(multi.value).toEqual(['b', 'c']);
|
|
18
|
+
expect(color.value).toBe('#abcdef');
|
|
19
|
+
expect(date.value).toBe('2026-05-01');
|
|
16
20
|
});
|
|
17
|
-
it('
|
|
18
|
-
const scope = createConnectionScope('
|
|
21
|
+
it('creates advanced passive components', () => {
|
|
22
|
+
const scope = createConnectionScope('p3-ctx-passive');
|
|
19
23
|
const ui = new UIContext(scope);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
ui.video('https://example.com/a.mp4', { src: 'https://example.com/a.mp4', autoplay: true });
|
|
25
|
+
ui.audio('https://example.com/a.mp3', { src: 'https://example.com/a.mp3', label: 'Audio demo' });
|
|
26
|
+
ui.diff('a\nb', 'a\nc');
|
|
27
|
+
ui.accordion([{ label: 'S1', defaultOpen: true, content: (s) => s.text('one') }]);
|
|
28
|
+
ui.filmStrip(['https://example.com/1.png']);
|
|
29
|
+
ui.beforeAfter('https://example.com/b.png', 'https://example.com/a.png');
|
|
30
|
+
const types = new Set(scope.listHandles().map((h) => h.type));
|
|
31
|
+
expect(types.has('video')).toBe(true);
|
|
32
|
+
expect(types.has('audio')).toBe(true);
|
|
33
|
+
expect(types.has('diff')).toBe(true);
|
|
34
|
+
expect(types.has('accordion')).toBe(true);
|
|
35
|
+
expect(types.has('filmStrip')).toBe(true);
|
|
36
|
+
expect(types.has('beforeAfter')).toBe(true);
|
|
25
37
|
});
|
|
26
|
-
it('
|
|
27
|
-
const scope = createConnectionScope('
|
|
38
|
+
it('supports fullscreen and modelCompare state updates', () => {
|
|
39
|
+
const scope = createConnectionScope('p3-ctx-stateful');
|
|
28
40
|
const ui = new UIContext(scope);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
expect(
|
|
34
|
-
|
|
35
|
-
expect(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
expect(
|
|
47
|
-
expect((chunks[1]?.payload).chunk).toBe(' world');
|
|
48
|
-
expect((chunks[2]?.payload).done).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
it('chatUI stores and clears connection-scoped message history', () => {
|
|
51
|
-
const scope = createConnectionScope('c5');
|
|
52
|
-
const ui = new UIContext(scope);
|
|
53
|
-
const chat = ui.chatUI();
|
|
54
|
-
chat.addMessage('user', 'hi');
|
|
55
|
-
chat.addMessage('assistant', 'hello');
|
|
56
|
-
expect(chat.value).toHaveLength(2);
|
|
57
|
-
expect(chat.lastMessage?.content).toBe('hello');
|
|
58
|
-
chat.clear();
|
|
59
|
-
expect(chat.value).toHaveLength(0);
|
|
60
|
-
});
|
|
61
|
-
it('promptEditor interpolate replaces template variables', () => {
|
|
62
|
-
const scope = createConnectionScope('c6');
|
|
63
|
-
const ui = new UIContext(scope);
|
|
64
|
-
const prompt = ui.promptEditor({ default: 'Write a {{tone}} note about {{topic}}.' });
|
|
65
|
-
const finalText = prompt.interpolate({ tone: 'formal', topic: 'safety' });
|
|
66
|
-
expect(finalText).toBe('Write a formal note about safety.');
|
|
67
|
-
});
|
|
68
|
-
it('tabs handle supports setActive for enabled tabs only', () => {
|
|
69
|
-
const scope = createConnectionScope('c7');
|
|
70
|
-
const ui = new UIContext(scope);
|
|
71
|
-
const tabs = ui.tabs([
|
|
72
|
-
{ label: 'One', content: (t) => t.text('first') },
|
|
73
|
-
{ label: 'Two', content: (t) => t.text('second'), disabled: true },
|
|
74
|
-
], { defaultTab: 'One' });
|
|
75
|
-
expect(tabs.value).toBe('One');
|
|
76
|
-
tabs.setActive('Two');
|
|
77
|
-
expect(tabs.value).toBe('One');
|
|
78
|
-
tabs.setActive('One');
|
|
79
|
-
expect(tabs.value).toBe('One');
|
|
80
|
-
expect(scope.outbox.filter((message) => message.type === 'FRAGMENT').length).toBeGreaterThan(0);
|
|
41
|
+
const fullscreen = ui.fullscreen((f) => {
|
|
42
|
+
f.text('full');
|
|
43
|
+
}, { trigger: 'manual' });
|
|
44
|
+
const model = ui.modelCompare([{ label: 'M1', model: 'x', provider: 'p' }], { prompt: 'hello' });
|
|
45
|
+
expect(model.value.results.M1).toBe('');
|
|
46
|
+
fullscreen.open();
|
|
47
|
+
expect(fullscreen.value).toBe(true);
|
|
48
|
+
fullscreen.close();
|
|
49
|
+
expect(fullscreen.value).toBe(false);
|
|
50
|
+
model.update({
|
|
51
|
+
value: {
|
|
52
|
+
results: { M1: 'ok' },
|
|
53
|
+
isStreaming: { M1: false },
|
|
54
|
+
errors: { M1: null },
|
|
55
|
+
latencies: { M1: 12 },
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
expect(model.results.M1).toBe('ok');
|
|
81
59
|
});
|
|
82
|
-
it('
|
|
83
|
-
const scope = createConnectionScope('
|
|
60
|
+
it('parameterPanel maps schema to child controls', () => {
|
|
61
|
+
const scope = createConnectionScope('p3-ctx-params');
|
|
84
62
|
const ui = new UIContext(scope);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
63
|
+
const params = ui.parameterPanel({
|
|
64
|
+
temperature: { type: 'number', min: 0, max: 2, default: 0.7 },
|
|
65
|
+
stream: { type: 'boolean', default: true },
|
|
66
|
+
model: { type: 'select', options: ['a', 'b'], default: 'a' },
|
|
67
|
+
note: { type: 'string', default: 'x' },
|
|
68
|
+
}, { title: 'Params', collapsible: true });
|
|
69
|
+
expect(params.value.temperature).toBe(0.7);
|
|
70
|
+
expect(params.value.stream).toBe(true);
|
|
71
|
+
expect(params.value.model).toBe('a');
|
|
72
|
+
expect(params.value.note).toBe('x');
|
|
73
|
+
params.update({
|
|
74
|
+
value: {
|
|
75
|
+
temperature: 1.1,
|
|
76
|
+
stream: false,
|
|
77
|
+
model: 'b',
|
|
78
|
+
note: 'updated',
|
|
95
79
|
},
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
},
|
|
102
|
-
(g2) => {
|
|
103
|
-
g2.alert('info');
|
|
104
|
-
g2.loading('loading');
|
|
105
|
-
},
|
|
106
|
-
], { cols: 2, gap: 8 });
|
|
107
|
-
m.card('card', (c) => {
|
|
108
|
-
c.divider({ label: 'sep' });
|
|
109
|
-
c.spacer('sm');
|
|
110
|
-
});
|
|
111
|
-
},
|
|
112
|
-
footer: (f) => {
|
|
113
|
-
f.text('footer');
|
|
114
|
-
},
|
|
115
|
-
}, { sidebarPosition: 'right', sidebarWidth: '300px' });
|
|
116
|
-
const handles = scope.listHandles();
|
|
117
|
-
expect(handles.some((h) => h.type === 'shell')).toBe(true);
|
|
118
|
-
expect(handles.some((h) => h.type === 'grid')).toBe(true);
|
|
119
|
-
expect(handles.some((h) => h.type === 'code')).toBe(true);
|
|
120
|
-
expect(handles.some((h) => h.type === 'json')).toBe(true);
|
|
121
|
-
expect(handles.some((h) => h.type === 'card')).toBe(true);
|
|
122
|
-
expect(handles.some((h) => h.type === 'divider')).toBe(true);
|
|
123
|
-
expect(handles.some((h) => h.type === 'spacer')).toBe(true);
|
|
124
|
-
expect(handles.some((h) => h.type === 'alert')).toBe(true);
|
|
125
|
-
expect(handles.some((h) => h.type === 'loading')).toBe(true);
|
|
126
|
-
scope.destroy();
|
|
127
|
-
expect(disconnected).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
expect(params.value.temperature).toBe(1.1);
|
|
82
|
+
expect(params.value.stream).toBe(false);
|
|
83
|
+
expect(params.value.model).toBe('b');
|
|
84
|
+
expect(params.value.note).toBe('updated');
|
|
128
85
|
});
|
|
129
86
|
});
|
|
130
87
|
//# sourceMappingURL=context.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.test.js","sourceRoot":"","sources":["../../src/components/context.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"context.test.js","sourceRoot":"","sources":["../../src/components/context.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { ConnectionScope } from './types';
|
|
2
|
-
export declare function createConnectionScope(id?: string, transport?:
|
|
1
|
+
import type { ConnectionScope, ServerConnection } from './types';
|
|
2
|
+
export declare function createConnectionScope(id?: string, transport?: ServerConnection): ConnectionScope;
|
|
@@ -10,6 +10,45 @@ export function createConnectionScope(id, transport = { send: () => { } }) {
|
|
|
10
10
|
const roots = [];
|
|
11
11
|
const cleanupFns = [];
|
|
12
12
|
const outbox = [];
|
|
13
|
+
const batch = { timer: null, messages: [] };
|
|
14
|
+
const sendNow = (message) => {
|
|
15
|
+
outbox.push(message);
|
|
16
|
+
transport.send(message);
|
|
17
|
+
};
|
|
18
|
+
const flushBatch = () => {
|
|
19
|
+
if (batch.messages.length === 0) {
|
|
20
|
+
batch.timer = null;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const payload = { messages: batch.messages.splice(0) };
|
|
24
|
+
batch.timer = null;
|
|
25
|
+
sendNow({ type: 'BATCH', payload });
|
|
26
|
+
};
|
|
27
|
+
const scheduleBatchFlush = () => {
|
|
28
|
+
if (batch.timer) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
batch.timer = setTimeout(() => {
|
|
32
|
+
flushBatch();
|
|
33
|
+
}, 16);
|
|
34
|
+
};
|
|
35
|
+
const enqueueBatchEntry = (entry) => {
|
|
36
|
+
const isFragment = entry.type === 'FRAGMENT';
|
|
37
|
+
if (isFragment) {
|
|
38
|
+
const fragmentId = entry.payload.id;
|
|
39
|
+
const existing = batch.messages.findIndex((item) => item.type === 'FRAGMENT' && item.payload.id === fragmentId);
|
|
40
|
+
if (existing >= 0) {
|
|
41
|
+
batch.messages[existing] = entry;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
batch.messages.push(entry);
|
|
45
|
+
}
|
|
46
|
+
scheduleBatchFlush();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
batch.messages.push(entry);
|
|
50
|
+
scheduleBatchFlush();
|
|
51
|
+
};
|
|
13
52
|
return {
|
|
14
53
|
id: scopeId,
|
|
15
54
|
connection: transport,
|
|
@@ -52,19 +91,28 @@ export function createConnectionScope(id, transport = { send: () => { } }) {
|
|
|
52
91
|
}
|
|
53
92
|
},
|
|
54
93
|
send(message) {
|
|
55
|
-
|
|
56
|
-
|
|
94
|
+
if (message.type === 'FRAGMENT' || message.type === 'STREAM_CHUNK') {
|
|
95
|
+
enqueueBatchEntry(message);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
sendNow(message);
|
|
57
99
|
},
|
|
58
100
|
pushFragment(handle) {
|
|
59
|
-
|
|
101
|
+
const fragment = {
|
|
60
102
|
type: 'FRAGMENT',
|
|
61
103
|
payload: { id: handle.id, html: renderComponent(handle) },
|
|
62
|
-
}
|
|
104
|
+
};
|
|
105
|
+
this.send(fragment);
|
|
63
106
|
},
|
|
64
107
|
onCleanup(fn) {
|
|
65
108
|
cleanupFns.push(fn);
|
|
66
109
|
},
|
|
67
110
|
clearTransientState() {
|
|
111
|
+
if (batch.timer) {
|
|
112
|
+
clearTimeout(batch.timer);
|
|
113
|
+
batch.timer = null;
|
|
114
|
+
}
|
|
115
|
+
batch.messages.length = 0;
|
|
68
116
|
atoms.clear();
|
|
69
117
|
handles.clear();
|
|
70
118
|
counters.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAqB,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/components/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { WritableAtom } from 'nanostores';
|
|
2
2
|
import type { ServerToClientMessage, ThemeMode } from '../engine/messages';
|
|
3
|
-
export type ComponentType = 'text' | 'button' | 'textInput' | 'numberInput' | 'slider' | 'toggle' | 'select' | 'fileUpload' | 'markdown' | 'image' | 'imageGrid' | 'code' | 'json' | 'table' | 'metric' | 'progress' | 'shell' | 'grid' | 'tabs' | 'card' | 'divider' | 'spacer' | 'alert' | 'loading' | 'streamText' | 'chatUI' | 'promptEditor';
|
|
3
|
+
export type ComponentType = 'text' | 'button' | 'textInput' | 'numberInput' | 'slider' | 'toggle' | 'select' | 'multiSelect' | 'colorPicker' | 'dateInput' | 'fileUpload' | 'markdown' | 'image' | 'imageGrid' | 'video' | 'audio' | 'code' | 'json' | 'diff' | 'table' | 'metric' | 'progress' | 'shell' | 'grid' | 'tabs' | 'accordion' | 'fullscreen' | 'card' | 'divider' | 'spacer' | 'alert' | 'loading' | 'streamText' | 'chatUI' | 'promptEditor' | 'modelCompare' | 'parameterPanel' | 'filmStrip' | 'beforeAfter';
|
|
4
4
|
export type TableRow = Record<string, unknown>;
|
|
5
5
|
export interface ComponentHandle<TProps, TValue = void> {
|
|
6
6
|
readonly id: string;
|
|
@@ -74,12 +74,32 @@ export interface FileUploadOpts {
|
|
|
74
74
|
helperText?: string;
|
|
75
75
|
dragDrop?: boolean;
|
|
76
76
|
}
|
|
77
|
+
export interface MultiSelectOpts {
|
|
78
|
+
defaults?: string[];
|
|
79
|
+
disabled?: boolean;
|
|
80
|
+
helperText?: string;
|
|
81
|
+
maxSelections?: number;
|
|
82
|
+
}
|
|
83
|
+
export interface ColorPickerOpts {
|
|
84
|
+
default?: string;
|
|
85
|
+
format?: 'hex' | 'rgb' | 'hsl';
|
|
86
|
+
disabled?: boolean;
|
|
87
|
+
helperText?: string;
|
|
88
|
+
swatches?: string[];
|
|
89
|
+
}
|
|
90
|
+
export interface DateInputOpts {
|
|
91
|
+
default?: string;
|
|
92
|
+
min?: string;
|
|
93
|
+
max?: string;
|
|
94
|
+
disabled?: boolean;
|
|
95
|
+
helperText?: string;
|
|
96
|
+
type?: 'date' | 'datetime-local' | 'time' | 'month';
|
|
97
|
+
}
|
|
77
98
|
export interface UploadedFile {
|
|
78
99
|
name: string;
|
|
79
100
|
path: string;
|
|
80
101
|
size: number;
|
|
81
102
|
type: string;
|
|
82
|
-
lastModified: number;
|
|
83
103
|
}
|
|
84
104
|
export interface TextProps {
|
|
85
105
|
content: string;
|
|
@@ -118,6 +138,23 @@ export interface FileUploadProps extends FileUploadOpts {
|
|
|
118
138
|
label: string;
|
|
119
139
|
value: UploadedFile | UploadedFile[] | null;
|
|
120
140
|
}
|
|
141
|
+
export interface MultiSelectProps extends MultiSelectOpts {
|
|
142
|
+
label: string;
|
|
143
|
+
options: Array<{
|
|
144
|
+
label: string;
|
|
145
|
+
value: string;
|
|
146
|
+
disabled?: boolean;
|
|
147
|
+
}>;
|
|
148
|
+
value: string[];
|
|
149
|
+
}
|
|
150
|
+
export interface ColorPickerProps extends ColorPickerOpts {
|
|
151
|
+
label: string;
|
|
152
|
+
value: string;
|
|
153
|
+
}
|
|
154
|
+
export interface DateInputProps extends DateInputOpts {
|
|
155
|
+
label: string;
|
|
156
|
+
value: string;
|
|
157
|
+
}
|
|
121
158
|
export interface MarkdownProps {
|
|
122
159
|
content: string;
|
|
123
160
|
}
|
|
@@ -138,6 +175,23 @@ export interface ImageGridProps {
|
|
|
138
175
|
gap?: number;
|
|
139
176
|
minWidth?: number;
|
|
140
177
|
}
|
|
178
|
+
export interface VideoProps {
|
|
179
|
+
src: string;
|
|
180
|
+
controls?: boolean;
|
|
181
|
+
autoplay?: boolean;
|
|
182
|
+
muted?: boolean;
|
|
183
|
+
loop?: boolean;
|
|
184
|
+
poster?: string;
|
|
185
|
+
width?: string;
|
|
186
|
+
caption?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface AudioProps {
|
|
189
|
+
src: string;
|
|
190
|
+
controls?: boolean;
|
|
191
|
+
autoplay?: boolean;
|
|
192
|
+
loop?: boolean;
|
|
193
|
+
label?: string;
|
|
194
|
+
}
|
|
141
195
|
export interface CodeProps {
|
|
142
196
|
content: string;
|
|
143
197
|
lang?: string;
|
|
@@ -146,6 +200,15 @@ export interface JsonProps {
|
|
|
146
200
|
label?: string;
|
|
147
201
|
data: unknown;
|
|
148
202
|
}
|
|
203
|
+
export interface DiffProps {
|
|
204
|
+
before: string;
|
|
205
|
+
after: string;
|
|
206
|
+
mode?: 'split' | 'unified';
|
|
207
|
+
beforeLabel?: string;
|
|
208
|
+
afterLabel?: string;
|
|
209
|
+
lang?: string;
|
|
210
|
+
context?: number;
|
|
211
|
+
}
|
|
149
212
|
export interface TableProps {
|
|
150
213
|
columns: string[];
|
|
151
214
|
rows: Array<{
|
|
@@ -189,6 +252,19 @@ export interface GridOpts {
|
|
|
189
252
|
export interface TabsOpts {
|
|
190
253
|
defaultTab?: string;
|
|
191
254
|
}
|
|
255
|
+
export interface AccordionSection {
|
|
256
|
+
label: string;
|
|
257
|
+
content: (ctx: UIContext) => void;
|
|
258
|
+
defaultOpen?: boolean;
|
|
259
|
+
}
|
|
260
|
+
export interface AccordionOpts {
|
|
261
|
+
allowMultiple?: boolean;
|
|
262
|
+
}
|
|
263
|
+
export interface FullscreenOpts {
|
|
264
|
+
trigger?: 'button' | 'manual';
|
|
265
|
+
label?: string;
|
|
266
|
+
defaultOpen?: boolean;
|
|
267
|
+
}
|
|
192
268
|
export interface ToastOpts {
|
|
193
269
|
type?: 'info' | 'success' | 'warning' | 'error';
|
|
194
270
|
duration?: number;
|
|
@@ -224,6 +300,74 @@ export interface ChatUIOptions {
|
|
|
224
300
|
export interface ChatUIProps extends ChatUIOptions {
|
|
225
301
|
messages: ChatMessage[];
|
|
226
302
|
}
|
|
303
|
+
export interface ModelSpec {
|
|
304
|
+
label: string;
|
|
305
|
+
model: string;
|
|
306
|
+
provider: string;
|
|
307
|
+
color?: string;
|
|
308
|
+
}
|
|
309
|
+
export interface ModelCompareOpts {
|
|
310
|
+
prompt: string;
|
|
311
|
+
systemPrompt?: string;
|
|
312
|
+
temperature?: number;
|
|
313
|
+
maxTokens?: number;
|
|
314
|
+
streaming?: boolean;
|
|
315
|
+
}
|
|
316
|
+
export interface ModelCompareResults {
|
|
317
|
+
results: Record<string, string>;
|
|
318
|
+
isStreaming: Record<string, boolean>;
|
|
319
|
+
errors: Record<string, string | null>;
|
|
320
|
+
latencies: Record<string, number>;
|
|
321
|
+
}
|
|
322
|
+
export interface ModelCompareProps extends ModelCompareOpts {
|
|
323
|
+
models: ModelSpec[];
|
|
324
|
+
value: ModelCompareResults;
|
|
325
|
+
}
|
|
326
|
+
export type ParameterSchema = Record<string, ParameterDef>;
|
|
327
|
+
export interface ParameterDef {
|
|
328
|
+
type: 'number' | 'string' | 'boolean' | 'select';
|
|
329
|
+
label?: string;
|
|
330
|
+
default?: unknown;
|
|
331
|
+
min?: number;
|
|
332
|
+
max?: number;
|
|
333
|
+
step?: number;
|
|
334
|
+
options?: string[];
|
|
335
|
+
description?: string;
|
|
336
|
+
}
|
|
337
|
+
export interface ParameterPanelOpts {
|
|
338
|
+
title?: string;
|
|
339
|
+
collapsible?: boolean;
|
|
340
|
+
}
|
|
341
|
+
export interface ParameterPanelProps extends ParameterPanelOpts {
|
|
342
|
+
schema: ParameterSchema;
|
|
343
|
+
ids: string[];
|
|
344
|
+
value: Record<string, unknown>;
|
|
345
|
+
}
|
|
346
|
+
export interface FilmStripItem {
|
|
347
|
+
src: string;
|
|
348
|
+
alt?: string;
|
|
349
|
+
caption?: string;
|
|
350
|
+
thumbnail?: string;
|
|
351
|
+
}
|
|
352
|
+
export interface FilmStripOpts {
|
|
353
|
+
height?: number;
|
|
354
|
+
zoom?: boolean;
|
|
355
|
+
showCaptions?: boolean;
|
|
356
|
+
selectedIndex?: number;
|
|
357
|
+
}
|
|
358
|
+
export interface FilmStripProps extends FilmStripOpts {
|
|
359
|
+
images: FilmStripItem[];
|
|
360
|
+
}
|
|
361
|
+
export interface BeforeAfterOpts {
|
|
362
|
+
beforeLabel?: string;
|
|
363
|
+
afterLabel?: string;
|
|
364
|
+
initialPosition?: number;
|
|
365
|
+
orientation?: 'horizontal' | 'vertical';
|
|
366
|
+
}
|
|
367
|
+
export interface BeforeAfterProps extends BeforeAfterOpts {
|
|
368
|
+
before: string;
|
|
369
|
+
after: string;
|
|
370
|
+
}
|
|
227
371
|
export interface PromptEditorOpts extends TextInputOpts {
|
|
228
372
|
label?: string;
|
|
229
373
|
variables?: string[];
|
|
@@ -246,6 +390,9 @@ export type SliderHandle = InputHandle<number, SliderProps>;
|
|
|
246
390
|
export type ToggleHandle = InputHandle<boolean, ToggleProps>;
|
|
247
391
|
export type SelectHandle = InputHandle<string, SelectProps>;
|
|
248
392
|
export type FileUploadHandle = InputHandle<UploadedFile | UploadedFile[] | null, FileUploadProps>;
|
|
393
|
+
export type MultiSelectHandle = InputHandle<string[], MultiSelectProps>;
|
|
394
|
+
export type ColorPickerHandle = InputHandle<string, ColorPickerProps>;
|
|
395
|
+
export type DateInputHandle = InputHandle<string, DateInputProps>;
|
|
249
396
|
export interface TableRowHandle {
|
|
250
397
|
id: string;
|
|
251
398
|
update(data: Partial<TableRow>): void;
|
|
@@ -271,6 +418,11 @@ export interface TabsHandle extends ComponentHandle<Record<string, unknown>, str
|
|
|
271
418
|
readonly type: 'tabs';
|
|
272
419
|
setActive(label: string): void;
|
|
273
420
|
}
|
|
421
|
+
export interface FullscreenHandle extends ComponentHandle<Record<string, unknown>, boolean> {
|
|
422
|
+
readonly type: 'fullscreen';
|
|
423
|
+
open(): void;
|
|
424
|
+
close(): void;
|
|
425
|
+
}
|
|
274
426
|
export interface StreamHandle extends Omit<ComponentHandle<StreamTextProps, string>, 'update'> {
|
|
275
427
|
readonly type: 'streamText';
|
|
276
428
|
readonly text: string;
|
|
@@ -291,7 +443,15 @@ export interface PromptEditorHandle extends InputHandle<string, PromptEditorProp
|
|
|
291
443
|
readonly type: 'promptEditor';
|
|
292
444
|
interpolate(vars: Record<string, string>): string;
|
|
293
445
|
}
|
|
294
|
-
export
|
|
446
|
+
export interface ModelCompareHandle extends ComponentHandle<ModelCompareProps, ModelCompareResults> {
|
|
447
|
+
readonly type: 'modelCompare';
|
|
448
|
+
readonly results: Record<string, string>;
|
|
449
|
+
readonly isStreaming: Record<string, boolean>;
|
|
450
|
+
readonly errors: Record<string, string | null>;
|
|
451
|
+
readonly latencies: Record<string, number>;
|
|
452
|
+
}
|
|
453
|
+
export type ParameterPanelHandle = InputHandle<Record<string, unknown>, ParameterPanelProps>;
|
|
454
|
+
export type AnyComponentHandle = TextHandle | ButtonHandle | TextInputHandle | NumberInputHandle | SliderHandle | ToggleHandle | SelectHandle | MultiSelectHandle | ColorPickerHandle | DateInputHandle | FileUploadHandle | TableHandle | MetricHandle | ProgressHandle | TabsHandle | FullscreenHandle | StreamHandle | ChatHandle | PromptEditorHandle | ModelCompareHandle | ParameterPanelHandle | ComponentHandle<MarkdownProps> | ComponentHandle<ImageProps> | ComponentHandle<ImageGridProps> | ComponentHandle<VideoProps> | ComponentHandle<AudioProps> | ComponentHandle<CodeProps> | ComponentHandle<JsonProps> | ComponentHandle<DiffProps> | ComponentHandle<FilmStripProps> | ComponentHandle<BeforeAfterProps> | ComponentHandle<Record<string, unknown>, unknown>;
|
|
295
455
|
export interface RenderNode {
|
|
296
456
|
id: string;
|
|
297
457
|
}
|
|
@@ -362,10 +522,18 @@ export interface UIContext {
|
|
|
362
522
|
slider(label: string, opts: SliderOpts): SliderHandle;
|
|
363
523
|
toggle(label: string, opts?: ToggleOpts): ToggleHandle;
|
|
364
524
|
select(label: string, options: SelectOption[], opts?: SelectOpts): SelectHandle;
|
|
525
|
+
multiSelect(label: string, options: SelectOption[], opts?: MultiSelectOpts): MultiSelectHandle;
|
|
526
|
+
colorPicker(label: string, opts?: ColorPickerOpts): ColorPickerHandle;
|
|
527
|
+
dateInput(label: string, opts?: DateInputOpts): DateInputHandle;
|
|
365
528
|
fileUpload(label: string, opts?: FileUploadOpts): FileUploadHandle;
|
|
529
|
+
video(src: string, opts?: VideoProps): void;
|
|
530
|
+
audio(src: string, opts?: AudioProps): void;
|
|
531
|
+
diff(before: string, after: string, opts?: Partial<DiffProps>): void;
|
|
366
532
|
shell(regions: ShellRegions, opts?: ShellOpts): void;
|
|
367
533
|
grid(areas: Array<(ctx: UIContext) => void>, opts?: GridOpts): void;
|
|
368
534
|
tabs(tabs: TabDef[], opts?: TabsOpts): TabsHandle;
|
|
535
|
+
accordion(sections: AccordionSection[], opts?: AccordionOpts): void;
|
|
536
|
+
fullscreen(content: (ctx: UIContext) => void, opts?: FullscreenOpts): FullscreenHandle;
|
|
369
537
|
card(titleOrContent: string | ((ctx: UIContext) => void), contentOrNothing?: (ctx: UIContext) => void): void;
|
|
370
538
|
divider(opts?: {
|
|
371
539
|
label?: string;
|
|
@@ -377,6 +545,10 @@ export interface UIContext {
|
|
|
377
545
|
streamText(opts?: StreamTextOpts): StreamHandle;
|
|
378
546
|
chatUI(opts?: ChatUIOptions): ChatHandle;
|
|
379
547
|
promptEditor(opts?: PromptEditorOpts): PromptEditorHandle;
|
|
548
|
+
modelCompare(models: ModelSpec[], opts: ModelCompareOpts): ModelCompareHandle;
|
|
549
|
+
parameterPanel(schema: ParameterSchema, opts?: ParameterPanelOpts): ParameterPanelHandle;
|
|
550
|
+
filmStrip(images: Array<string | FilmStripItem>, opts?: FilmStripOpts): void;
|
|
551
|
+
beforeAfter(before: string, after: string, opts?: BeforeAfterOpts): void;
|
|
380
552
|
onDisconnect(fn: () => void): void;
|
|
381
553
|
}
|
|
382
554
|
export interface ShellRegions {
|
package/dist/engine/executor.js
CHANGED
|
@@ -25,6 +25,11 @@ export function handleClientEvent(scope, payload) {
|
|
|
25
25
|
handle.update({ value: target });
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
+
if (handle.type === 'parameterPanel') {
|
|
29
|
+
const panel = handle;
|
|
30
|
+
panel.update({});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
28
33
|
scope.pushFragment(handle);
|
|
29
34
|
return;
|
|
30
35
|
}
|
|
@@ -49,6 +54,12 @@ export function handleClientEvent(scope, payload) {
|
|
|
49
54
|
});
|
|
50
55
|
return;
|
|
51
56
|
}
|
|
57
|
+
if (handle.type === 'fullscreen') {
|
|
58
|
+
const fullscreen = handle;
|
|
59
|
+
const current = fullscreen.value;
|
|
60
|
+
fullscreen.update({ value: !current });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
52
63
|
if (handle.type === 'table' && typeof payload.value === 'string') {
|
|
53
64
|
const tableHandle = handle;
|
|
54
65
|
const row = tableHandle.props.rows.find((entry) => entry.id === payload.value);
|