anentrypoint-design 0.0.460 → 0.0.462
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/dist/247420.js +20 -20
- package/package.json +1 -1
- package/src/components/freddie/pages-chat.js +31 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.462",
|
|
4
4
|
"description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/247420.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
import * as webjsx from '../../../vendor/webjsx/index.js';
|
|
19
19
|
import { makePage, api, loadingState, emptyState } from './runtime.js';
|
|
20
|
-
import { Table, PageHeader } from '../content.js';
|
|
20
|
+
import { Table, PageHeader, Select } from '../content.js';
|
|
21
21
|
import { Chip } from '../shell.js';
|
|
22
22
|
import { formatTime } from '../../locale.js';
|
|
23
23
|
import { queueMessage, watchReconnect, isOnline } from '../../idb-outbox.js';
|
|
@@ -57,6 +57,8 @@ function applyEnvelope(msgs, env, sendApprove) {
|
|
|
57
57
|
}
|
|
58
58
|
} else if (event === 'steer.append') {
|
|
59
59
|
if (!isDupUser(data.text)) msgs.push({ id: 'u' + msgs.length + env.ts, role: 'user', content: data.text || '', time: formatTime(ts) });
|
|
60
|
+
} else if (event === 'queue.append') {
|
|
61
|
+
if (!isDupUser(data.text)) msgs.push({ id: 'u' + msgs.length + env.ts, role: 'user', content: data.text || '', time: formatTime(ts) });
|
|
60
62
|
} else if (event === 'assistant.delta') {
|
|
61
63
|
// Progressive text mid-turn: accumulate into the live bubble; the
|
|
62
64
|
// settled message.append at turn end overwrites with the authoritative
|
|
@@ -84,7 +86,20 @@ function applyEnvelope(msgs, env, sendApprove) {
|
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
export const chat = makePage((ctx) => {
|
|
87
|
-
Object.assign(ctx.state, { loading: false, messages: [], draft: '', busy: false, error: null, sessionId: null, ws: null, conn: 'closed' });
|
|
89
|
+
Object.assign(ctx.state, { loading: false, messages: [], draft: '', busy: false, error: null, sessionId: null, ws: null, conn: 'closed', sessions: [] });
|
|
90
|
+
|
|
91
|
+
// Session picker (kimi web's sessions sidebar, compact form): recent
|
|
92
|
+
// conversations from /api/sessions, needsInput badges included. Picking
|
|
93
|
+
// one reconnects the WS under that id and rebuilds from server replay.
|
|
94
|
+
api('/api/sessions').then(rows => { ctx.state.sessions = Array.isArray(rows) ? rows : []; ctx.rerender(); }).catch(() => { /* swallow: picker degrades to new-chat-only */ });
|
|
95
|
+
|
|
96
|
+
function switchSession(id) {
|
|
97
|
+
const st = ctx.state;
|
|
98
|
+
if (!id || id === st.sessionId) return;
|
|
99
|
+
try { st.ws && st.ws.close(); } catch { /* already closed */ }
|
|
100
|
+
ctx.set({ sessionId: id, messages: [], ws: null, conn: 'closed', busy: false, error: null });
|
|
101
|
+
ensureWs();
|
|
102
|
+
}
|
|
88
103
|
|
|
89
104
|
// Offline outbox: a prompt sent while genuinely offline queues to
|
|
90
105
|
// IndexedDB and auto-flushes on the real 'online' event via the legacy
|
|
@@ -142,6 +157,8 @@ export const chat = makePage((ctx) => {
|
|
|
142
157
|
if (f.error && !c.error) c.error = f.error;
|
|
143
158
|
}
|
|
144
159
|
ctx.set({ busy: false });
|
|
160
|
+
// New turns can create/rename sessions — refresh the picker.
|
|
161
|
+
api('/api/sessions').then(rows => { ctx.state.sessions = Array.isArray(rows) ? rows : []; ctx.rerender(); }).catch(() => { /* swallow: picker refresh is best-effort */ });
|
|
145
162
|
} else if (f.type === 'error') {
|
|
146
163
|
const c = cur();
|
|
147
164
|
if (c && c.role === 'assistant') c.error = f.error;
|
|
@@ -166,10 +183,10 @@ export const chat = makePage((ctx) => {
|
|
|
166
183
|
const t = (typeof text === 'string' ? text : s().draft || '').trim();
|
|
167
184
|
if (!t) return;
|
|
168
185
|
|
|
169
|
-
// Mid-turn send =
|
|
170
|
-
//
|
|
186
|
+
// Mid-turn send = QUEUE for after the turn (kimi 1.31's Enter channel);
|
|
187
|
+
// injection mid-turn is /steer in the REPL or a wire steer frame.
|
|
171
188
|
if (s().busy) {
|
|
172
|
-
if (sendFrame({ type: '
|
|
189
|
+
if (sendFrame({ type: 'queue', text: t })) {
|
|
173
190
|
s().messages = [...s().messages, { id: 'u' + Date.now(), role: 'user', content: t, time: formatTime(Date.now()) }];
|
|
174
191
|
ctx.set({ draft: '' });
|
|
175
192
|
}
|
|
@@ -206,13 +223,21 @@ export const chat = makePage((ctx) => {
|
|
|
206
223
|
return () => {
|
|
207
224
|
const st = s();
|
|
208
225
|
return h('div', { class: 'fd-chat' },
|
|
226
|
+
st.sessions.length ? h('div', { class: 'fd-chat-picker' },
|
|
227
|
+
Select({
|
|
228
|
+
value: st.sessionId || '',
|
|
229
|
+
placeholder: 'new conversation',
|
|
230
|
+
'aria-label': 'switch conversation',
|
|
231
|
+
options: st.sessions.map(row => ({ value: row.id, label: (row.title || '(untitled)').slice(0, 60) + (row.needsInput ? ' — needs input' : '') })),
|
|
232
|
+
onChange: switchSession,
|
|
233
|
+
})) : null,
|
|
209
234
|
AgentChat({
|
|
210
235
|
messages: st.messages,
|
|
211
236
|
busy: st.busy,
|
|
212
237
|
draft: st.draft,
|
|
213
238
|
status: st.busy ? 'streaming…' : (st.conn === 'open' ? 'ready' : 'connecting…'),
|
|
214
239
|
agentName: 'freddie',
|
|
215
|
-
placeholder: st.busy ? '
|
|
240
|
+
placeholder: st.busy ? 'queue a follow-up… (or stop)' : 'message…',
|
|
216
241
|
showMinimap: true,
|
|
217
242
|
banners: st.error ? [noteAlert({ kind: 'error', msg: st.error })] : [],
|
|
218
243
|
onInput: (v) => { st.draft = v; },
|