clavarium 0.2.369-next.1 → 0.2.370-next.1
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/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/server/apikeys.mjs +3 -2
- package/server/rooms.mjs +14 -5
- package/server/settingswords.mjs +2 -0
- package/web/app.js +7 -1
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clavarium",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.370-next.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "clavarium",
|
|
9
|
-
"version": "0.2.
|
|
9
|
+
"version": "0.2.370-next.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@xterm/addon-fit": "^0.11.0",
|
package/package.json
CHANGED
package/server/apikeys.mjs
CHANGED
|
@@ -559,8 +559,9 @@ export async function handleExternal(request, response, { keys, status, chats =
|
|
|
559
559
|
if (typeof text !== 'string' || !text.trim()) throw new Refusal(400, 'Say something: text.');
|
|
560
560
|
if (text.length > SAY_MAX) throw new Refusal(400, `${SAY_MAX} characters at most.`);
|
|
561
561
|
if (to !== undefined && to !== null && (!Array.isArray(to) || to.length > 20 || to.some((x) => typeof x !== 'string'))) throw new Refusal(400, 'to: the names of AIs of this room.');
|
|
562
|
-
await rooms.say(room, text, { as: keys.roomSignature(id), to: Array.isArray(to) ? to : [] });
|
|
563
|
-
|
|
562
|
+
const done = await rooms.say(room, text, { as: keys.roomSignature(id), to: Array.isArray(to) ? to : [] });
|
|
563
|
+
/* Posted; an AI it could not reach (its chat off) said by name. */
|
|
564
|
+
return done?.missed?.length ? { ok: true, notReached: done.missed.map((m) => m.name) } : { ok: true };
|
|
564
565
|
};
|
|
565
566
|
const boxesListed = (id) => {
|
|
566
567
|
const there = new Map((boxes?.list() ?? []).map((b) => [b.id, b]));
|
package/server/rooms.mjs
CHANGED
|
@@ -272,16 +272,25 @@ export class Rooms {
|
|
|
272
272
|
const said = now.messages.at(-1);
|
|
273
273
|
const named = (Array.isArray(to) ? to : []).map((x) => members.find((m) => m.id === x && m.kind === 'ai')).filter(Boolean);
|
|
274
274
|
const host = members.find((m) => m.id === room.host);
|
|
275
|
+
/* Kept in the room whatever happens next: an AI that cannot be reached (its chat off) is said back by name,
|
|
276
|
+
never as a failure of what was already posted (07-11). */
|
|
277
|
+
const missed = [];
|
|
275
278
|
for (const ai of named.length ? named : host ? [host] : []) {
|
|
276
279
|
this.#think(room.id, ai.id, true);
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
280
|
+
try {
|
|
281
|
+
/* Its own copy of each file, in its chat's files: as if attached there (a fresh read of the room's file). */
|
|
282
|
+
const copies = [];
|
|
283
|
+
for (const f of attached) { const stream = createReadStream(f.file); stream.headers = { 'content-length': String(f.size) }; copies.push((await this.#attach(ai.ref, f.name, stream)).path); }
|
|
284
|
+
await this.#say(ai.ref, text, { by: { id: who.id, name: who.name, kind: who.kind, look: who.look }, room: { id: room.id, name: room.name, message: said.id } }, ...(copies.length ? [copies] : []));
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (!(error instanceof Refusal)) throw error;
|
|
287
|
+
this.#think(room.id, ai.id, false);
|
|
288
|
+
missed.push({ name: ai.name, why: error.message });
|
|
289
|
+
}
|
|
281
290
|
}
|
|
282
291
|
/* Handed to its AIs: read, as a conversation's agent would say it (06-11: the clock stayed on every message). */
|
|
283
292
|
try { t.seen?.(); } catch { /* an older Parley */ }
|
|
284
|
-
return this.read(id);
|
|
293
|
+
return missed.length ? { ...this.read(id), missed } : this.read(id);
|
|
285
294
|
}
|
|
286
295
|
|
|
287
296
|
/* AN AI ANSWERS IN A ROOM (what its own folder says, entry.room): only to a room it is in; signed by where it
|
package/server/settingswords.mjs
CHANGED
|
@@ -24,6 +24,8 @@ export const SETTINGS_WORDS_FR = {
|
|
|
24
24
|
'set-free-of': '{free} libres sur {total}', 'set-left-of': '{free} restants sur {total}', 'set-highest': 'au plus {n} % en 1 h',
|
|
25
25
|
'set-core': '1 cœur', 'set-cores': '{n} cœurs',
|
|
26
26
|
'set-update-out': '{v} est sortie', 'set-up-to-date': 'À jour · {v}', 'set-wifi-on': 'Wi-Fi · {name}', 'set-wifi-off': 'Wi-Fi non utilisé', 'set-cable': 'Câble',
|
|
27
|
+
/* A room message an AI could not get (its chat off): rooms.mjs say, missed. */
|
|
28
|
+
'set-room-missed': '{names} ne l\'a pas reçu : discussion coupée',
|
|
27
29
|
/* A box's learning session (boxcollect.mjs): the radio, its false wakes kept. */
|
|
28
30
|
'set-collect': 'Séance d\'apprentissage (radio)', 'set-collect-from': 'de', 'set-collect-to': 'à',
|
|
29
31
|
'set-collect-go': 'Programmer', 'set-collect-stop': 'Arrêter', 'set-collect-scheduled': 'Programmée de {from} à {to}',
|
package/web/app.js
CHANGED
|
@@ -5613,7 +5613,13 @@
|
|
|
5613
5613
|
if (known && JSON.stringify(thinkingOf(known)) !== JSON.stringify(who)) { known.thinking = who; paint(); }
|
|
5614
5614
|
return d;
|
|
5615
5615
|
}),
|
|
5616
|
-
|
|
5616
|
+
/* Kept in the room even when an AI of it could not get it (its chat off, 07-11): said for a moment, by name. */
|
|
5617
|
+
send: async (text, answers, files) => {
|
|
5618
|
+
const d = await post(`${API}/rooms/${id}/talk`, { text, ...(files?.length ? { files: files.map((f) => f.path) } : {}) });
|
|
5619
|
+
const missed = Array.isArray(d?.missed) ? d.missed.map((m) => String(m?.name ?? '')).filter(Boolean) : [];
|
|
5620
|
+
if (missed.length) flash(uiSaid('set-room-missed', '{names} did not get it: chat off', { names: missed.join(', ') }));
|
|
5621
|
+
return d;
|
|
5622
|
+
},
|
|
5617
5623
|
/* A file attached in a room (06-11): as in a conversation's chat; kept in the room, a copy to each AI the message goes to. */
|
|
5618
5624
|
attach: { upload: async (file) => { const x = await fetch(`${API}/rooms/${id}/talk/file?${new URLSearchParams({ name: file.name })}`, { method: 'POST', headers: { 'content-type': 'application/octet-stream' }, body: file }); const j = await x.json().catch(() => ({})); if (!x.ok) throw new Error(j.error || 'The file could not be sent.'); return j; } },
|
|
5619
5625
|
/* A file an AI of the room showed or cited (ai:<member>:work:a.png): read from its own conversation, in the same viewer as in its chat. */
|