mnfst 0.5.270 → 0.5.271
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/lib/manifest.chat.js
CHANGED
|
@@ -1009,8 +1009,8 @@
|
|
|
1009
1009
|
/* Manifest Chat — optional LLM (Claude) adapter
|
|
1010
1010
|
* By Andrew Matlock under MIT license · https://manifestx.dev
|
|
1011
1011
|
*
|
|
1012
|
-
* Reference `claude` adapter: replies stream from
|
|
1013
|
-
*
|
|
1012
|
+
* Reference `claude` adapter: replies stream from the same-origin /_ai/chat relay,
|
|
1013
|
+
* served by mnfst-run locally and by Manifest hosting once published. $chat
|
|
1014
1014
|
* never calls the LLM — this adapter does, behind the same contract. Optional, loaded separately from the bundle.
|
|
1015
1015
|
* Attachments ride draft.body.media[] as base64 → image/document blocks.
|
|
1016
1016
|
*/
|
|
@@ -1030,7 +1030,7 @@
|
|
|
1030
1030
|
|
|
1031
1031
|
function claudeAdapter(opts) {
|
|
1032
1032
|
opts = opts || {};
|
|
1033
|
-
// Same-origin relay
|
|
1033
|
+
// Same-origin relay for an `ai` block; override via
|
|
1034
1034
|
// opts.endpoint / window.CHAT_LLM_ENDPOINT.
|
|
1035
1035
|
const endpoint = opts.endpoint || window.CHAT_LLM_ENDPOINT || '/_ai/chat';
|
|
1036
1036
|
// only when set — the relay's ai block (system + grounding) is the default
|
|
@@ -1044,7 +1044,9 @@
|
|
|
1044
1044
|
function loadStore(cid) { try { return JSON.parse(localStorage.getItem(lsKey(cid)) || '[]'); } catch { return []; } }
|
|
1045
1045
|
function saveMsg(cid, m) {
|
|
1046
1046
|
const all = loadStore(cid);
|
|
1047
|
-
|
|
1047
|
+
const r = { id: m.id, role: m.author.kind === 'agent' ? 'assistant' : 'user', text: m.body.text, ts: m.ts };
|
|
1048
|
+
if (m.error) r.error = true;
|
|
1049
|
+
all.push(r);
|
|
1048
1050
|
try { localStorage.setItem(lsKey(cid), JSON.stringify(all.slice(-200))); } catch { }
|
|
1049
1051
|
}
|
|
1050
1052
|
const toMsg = (r) => ({ id: r.id, conversationId: null, author: r.role === 'assistant' ? BOT : USER, body: { text: r.text }, ts: r.ts, status: 'delivered' });
|
|
@@ -1053,14 +1055,19 @@
|
|
|
1053
1055
|
// Only what the API accepts is forwarded (images + PDFs with data);
|
|
1054
1056
|
// audio/video/voice render locally but don't reach the model.
|
|
1055
1057
|
function apiMessages(cid, draft) {
|
|
1056
|
-
const
|
|
1058
|
+
const text = (draft.body && draft.body.text) || draft.text || '';
|
|
1059
|
+
const stored = loadStore(cid);
|
|
1060
|
+
const prev = stored[stored.length - 1];
|
|
1061
|
+
if (prev && prev.role === 'user' && prev.text === text) stored.pop(); // send() already saved this turn
|
|
1062
|
+
// relays accept up to 100 messages, starting on a user turn
|
|
1063
|
+
const hist = stored.filter(r => !r.error && r.text && r.text.trim()).slice(-99).map(r => ({ role: r.role, content: r.text }));
|
|
1064
|
+
while (hist.length && hist[0].role !== 'user') hist.shift();
|
|
1057
1065
|
const media = ((draft.body && draft.body.media) || []).filter(a =>
|
|
1058
1066
|
a.data && (a.kind === 'image' || a.mediaType === 'application/pdf'));
|
|
1059
1067
|
const blocks = media.map(a => a.kind === 'image'
|
|
1060
1068
|
? { type: 'image', source: { type: 'base64', media_type: a.mediaType, data: a.data } }
|
|
1061
1069
|
: { type: 'document', source: { type: 'base64', media_type: 'application/pdf', data: a.data } });
|
|
1062
|
-
const
|
|
1063
|
-
const last = blocks.length ? { role: 'user', content: [...blocks, { type: 'text', text }] } : { role: 'user', content: text };
|
|
1070
|
+
const last = blocks.length ? { role: 'user', content: text.trim() ? [...blocks, { type: 'text', text }] : blocks } : { role: 'user', content: text };
|
|
1064
1071
|
return [...hist, last];
|
|
1065
1072
|
}
|
|
1066
1073
|
|
|
@@ -1069,10 +1076,19 @@
|
|
|
1069
1076
|
const messages = streamReply._pending; streamReply._pending = null;
|
|
1070
1077
|
const mid = id('m');
|
|
1071
1078
|
h.onMessage && h.onMessage({ id: mid, conversationId: cid, author: BOT, body: { text: '' }, ts: Date.now(), status: 'streaming', meta: { model: opts.model } });
|
|
1072
|
-
let full = '';
|
|
1079
|
+
let full = '', reply = '';
|
|
1073
1080
|
try {
|
|
1074
1081
|
const resp = await fetch(endpoint, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ system, model: opts.model, messages }) });
|
|
1075
|
-
if (!resp.ok)
|
|
1082
|
+
if (!resp.ok) {
|
|
1083
|
+
let body = '', msg = '';
|
|
1084
|
+
try { body = await resp.text(); } catch { }
|
|
1085
|
+
try { const j = JSON.parse(body); msg = (j && (j.message || j.error)) || ''; } catch { }
|
|
1086
|
+
if (!msg) {
|
|
1087
|
+
const line = body.split('\n').find(l => l.startsWith('data:'));
|
|
1088
|
+
try { const evt = line && JSON.parse(line.slice(5).trim()); msg = (evt && evt.error && evt.error.message) || ''; } catch { }
|
|
1089
|
+
}
|
|
1090
|
+
const err = new Error('HTTP ' + resp.status); err.relayMessage = typeof msg === 'string' ? msg : ''; throw err;
|
|
1091
|
+
}
|
|
1076
1092
|
const reader = resp.body.getReader(); const dec = new TextDecoder(); let buf = '';
|
|
1077
1093
|
for (; ;) {
|
|
1078
1094
|
const { done, value } = await reader.read(); if (done) break;
|
|
@@ -1083,16 +1099,20 @@
|
|
|
1083
1099
|
const line = frame.split('\n').find(l => l.startsWith('data:')); if (!line) continue;
|
|
1084
1100
|
let evt; try { evt = JSON.parse(line.slice(5).trim()); } catch { continue; }
|
|
1085
1101
|
if (evt.type === 'content_block_delta' && evt.delta && evt.delta.type === 'text_delta') {
|
|
1086
|
-
full += evt.delta.text; h.onMessagePart && h.onMessagePart(mid, { text: evt.delta.text });
|
|
1102
|
+
full += evt.delta.text; reply += evt.delta.text; h.onMessagePart && h.onMessagePart(mid, { text: evt.delta.text });
|
|
1087
1103
|
} else if (evt.type === 'error') { full += '\n\n_(error: ' + (evt.error && evt.error.message) + ')_'; h.onMessagePart && h.onMessagePart(mid, { text: '\n\n_(error)_' }); }
|
|
1088
1104
|
}
|
|
1089
1105
|
}
|
|
1090
1106
|
} catch (e) {
|
|
1091
|
-
const note =
|
|
1107
|
+
const note = e && e.relayMessage
|
|
1108
|
+
? '\n\n(' + e.relayMessage + ')'
|
|
1109
|
+
: '\n\n(AI chat unavailable at `' + endpoint + '`' + (e && /^HTTP /.test(e.message) ? ': ' + e.message : '') + ')';
|
|
1092
1110
|
h.onMessagePart && h.onMessagePart(mid, { text: note }); full += note;
|
|
1093
1111
|
}
|
|
1094
1112
|
h.onMessagePart && h.onMessagePart(mid, { text: '', done: true });
|
|
1095
|
-
|
|
1113
|
+
// error notes show in the UI but never reach the model: keep partial text, else flag the entry
|
|
1114
|
+
if (reply.trim()) saveMsg(cid, { id: mid, author: BOT, body: { text: reply }, ts: Date.now() });
|
|
1115
|
+
else saveMsg(cid, { id: mid, author: BOT, body: { text: full }, ts: Date.now(), error: true });
|
|
1096
1116
|
}
|
|
1097
1117
|
|
|
1098
1118
|
return {
|
package/lib/manifest.data.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest.appwrite.auth.js": "sha384-gWLSeVPqCLMiUZB8MU7GqMg3x2yULFUsp8nTTZrPp/9Dlkix42rBn9yIimvwrHqZ",
|
|
3
|
-
"manifest.appwrite.data.js": "sha384-
|
|
3
|
+
"manifest.appwrite.data.js": "sha384-go0Kp+qGs1e5uIrBUXfDH1J1WUegEtsf0ZVHS5wEQiJXkU2f/M8eSCPXlJtU6CJR",
|
|
4
4
|
"manifest.appwrite.presences.js": "sha384-LINPhIPTCK+rA8zd+HPUzMSEgH6Sl2vQMEyItT97bnEE2FYGYKqjXX+CWdt6nl9z",
|
|
5
5
|
"manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
|
|
6
6
|
"manifest.charts.js": "sha384-AFbP7mQnigy7DU1s+YE30yKTeQAKfgNazhbfSNbfd9ZpLgeulZKaPi/fAq3gJHDO",
|
|
7
|
-
"manifest.chat.js": "sha384-
|
|
7
|
+
"manifest.chat.js": "sha384-8kxS2HImRVeRiarqaGiNFlCTqB7inp/y7Hn0kIPNzADl130s4JgnmJ7uCmW0Mmvt",
|
|
8
8
|
"manifest.code.js": "sha384-WGPlZE5Sp9GygUzJSmCdpLyYQTgvmEKc9BQS9Hmq1VTQwkqYJzPSWibHvPekcres",
|
|
9
9
|
"manifest.color.js": "sha384-6Rv3LxyTcZNjrhtayQfqRdCx0uSZ4BiEbgEI98I62eTvp8Aw7LBIoNJ0Je1oktwL",
|
|
10
10
|
"manifest.colorpicker.js": "sha384-P+Zx0QzhMGfku8s3yEskTte4/iXCGVX3zdhu42IGNfFcSmhOW+nqVK7w+uczWRGY",
|
|
11
11
|
"manifest.combobox.js": "sha384-/lJo6vaxKjgnBSRs/dzkhK1dzGk3GBw8FISoNJZB70mwAVwu1k5veZyBXjOb4keS",
|
|
12
12
|
"manifest.components.js": "sha384-BUFA8h+G5Plr82sV7bKzO42pPoiRZwRQcKj1lt2ROFiKjjlkayU/vmkAFqEsdBA+",
|
|
13
13
|
"manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
|
|
14
|
-
"manifest.data.js": "sha384-
|
|
14
|
+
"manifest.data.js": "sha384-HNnAhuzs+a3HkWH2WgL5cE/iCTbZmMMkYH++Q9oJMhAyYGchPkwbeSnL89yF3qnT",
|
|
15
15
|
"manifest.datepicker.js": "sha384-EzlMwvIxlla/0BuyhAEqxN0M8TGcWIWgEIg840V0akKQQK1uY648wPWMkobvtq/o",
|
|
16
16
|
"manifest.defer.js": "sha384-PRp7+dCZHnnl55rX2xrHutLrQnszHo7o5o9Tq28M/yjLZPuXDzcwQNxCdvbtCYSz",
|
|
17
17
|
"manifest.device.js": "sha384-YeQaS56L8IILqrQNBSeAOLwIh5DuAOrE60cYLK1+46qJtUrXlAvqGe2j5mbV4Vq7",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
|
|
29
29
|
"manifest.status.js": "sha384-ofu7nBnVIGZ1U1o2R9d2H3V8aEMPUCVbl5FO3gIToXqi0oa36fTviEdh5UU7Kitw",
|
|
30
30
|
"manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
|
|
31
|
-
"manifest.sw.js": "sha384-
|
|
31
|
+
"manifest.sw.js": "sha384-WjwI0K3kGBDGcQgkUTf8WQjKN2tiQxwkucPsrFWcNAMAy9IMSXFyqz43ERGIY9eO",
|
|
32
32
|
"manifest.tabs.js": "sha384-otU09H7jnawVKQdLAYpMCd3jx00tgyPVr42D2hLIBzN5dG4se505YesavdnMqEi1",
|
|
33
33
|
"manifest.tailwind.js": "sha384-yuP3LEvWU+QVjxjkZ0YhErtC9RrGmhOmHjjFjhS9obqZbp5/KTIEnSR0CXDvHE0B",
|
|
34
34
|
"manifest.toasts.js": "sha384-UpOz9fAdGeGUhL0NamBg5iPepEfIy73p9HYdcxfOQC5b7CVsl7Our0skdZzaLNcC",
|
package/lib/manifest.sw.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
// Build stamps the published version here; unstamped (dev) falls back to the
|
|
18
18
|
// registration URL's `v`, then 'dev'.
|
|
19
|
-
const BUILD_VERSION = '0.5.
|
|
19
|
+
const BUILD_VERSION = '0.5.271';
|
|
20
20
|
const CACHE_PREFIX = 'mnfst-sw:';
|
|
21
21
|
const META_CACHE = CACHE_PREFIX + 'meta';
|
|
22
22
|
// Sized to hold a full precache.json warm-up (PRECACHE_MAX_ENTRIES server-side)
|