openvibers/openvibe.actor Commits

The chat's sidebar is the network's one sidebar, with Actor's places as rows (#258)

OP OpenVibers committed 11 days ago · 7322b2d866 · 5 files, +16 −12

* The chat draws with the network's conversation UI (openvibe-shared/thread, L55 C4)

* Merge remote-tracking branch 'origin/main' into design/chat-on-thread-kit

* openvibe-shared v4.96.0 (was v4.95.0): the conversation UI

* The chats are the network's one sidebar, with Actor's places as rows (kit.sidebar via thread 4.97.0)

* Merge remote-tracking branch 'origin/main' into design/chat-kit-sidebar

# Conflicts:
#	server/http/chat-pages.js

* openvibe-shared v4.97.0 (was v4.96.0): the network's one sidebar in the chat

Changes

ddiff --git a/STATUS.json b/STATUS.json
iindex 55ec318..fa2fe78 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -9,11 +9,11 @@
"domain": "openvibe.actor",
"contracts": "openvibe-contracts v0.269.0",
"sdk": "openvibe-sdk v0.81.0",
-- "shared": "openvibe-shared v4.96.0",
++ "shared": "openvibe-shared v4.97.0",
"packages": [
"openvibe-contracts v0.269.0",
"openvibe-sdk v0.81.0",
-- "openvibe-shared v4.96.0"
++ "openvibe-shared v4.97.0"
],
"summary": "Public at https://openvibe.actor (sudo ovhost deploy actor; unit openvibe-actor on 127.0.0.1:4950). A task in plain words is classified, routed by openvibe-sdk/placement to the agent system that can do it (the OpenVibe runtime acting through OpenVibe.Search and OpenVibe.Tools, OpenAI's web agent, an open model on OpenVibe's server for private mode), run with its steps streamed live, checked by a model of another family, and delivered as platform.task@1 with its cost to a fraction of a cent and the explanation; a failed agent or check hands it to the next agent. Free tier per person with an operator ceiling.",
"works": [
ddiff --git a/package-lock.json b/package-lock.json
iindex 2de61c4..6e86e26 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -17,7 +17,7 @@
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.269.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.81.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.96.0",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.97.0",
"pg": "^8.23.0"
},
"devDependencies": {
@@@ -1190,9 +1190,9 @@
}
},
"node_modules/openvibe-shared": {
-- "version": "4.96.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.96.0",
-- "integrity": "sha512-4+9RNAqu66FTRxYlWndmOVy7ZLFCXnQIJXiTO6n8LeUmX0eoL+y/70hKVbz7XmmX/3khqkehJYAn9Tq8mVmmVQ==",
++ "version": "4.97.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.97.0",
++ "integrity": "sha512-1Lzemh84BvVaAV1oQNkMnOu6rtx/txsHedksKA1Xu/x24+Jtz43akAR/Yd/qpS2FFkQtc4+6nB79+iC05ny1Og==",
"license": "MIT",
"dependencies": {
"jsonwebtoken": "^9.0.0",
ddiff --git a/package.json b/package.json
iindex e37a3ce..c87cd1e 100644
---- a/package.json
++++ b/package.json
@@@ -30,7 +30,7 @@
"iovalkey": "^0.4.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.269.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.81.0",
-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.96.0",
++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.97.0",
"pg": "^8.23.0"
},
"engines": {
ddiff --git a/server/http/chat-pages.js b/server/http/chat-pages.js
iindex 33c50cd..4d1088f 100644
---- a/server/http/chat-pages.js
++++ b/server/http/chat-pages.js
@@@ -272,7 +272,9 @@ ${acting ? '' : html`<form method="post" action="/tasks/${row.id}/answer" class=
name: g.name,
items: g.items.map((c) => ({ href: `/chat/${c.id}`, title: c.title, current: c.id === currentId, live: c.open })),
})),
-- foot: [{ href: '/console', label: 'Console' }, { href: '/me/agents', label: 'Your agents' }, { href: '/memory', label: 'Memory' }],
++ findAction: '/chat',
++ // Actor's places as the network sidebar's rows, as Codes' are (kit.sidebar, plan L35).
++ nav: [{ href: '/console', label: 'Console', icon: 'grid' }, { href: '/me/agents', label: 'Your agents', icon: 'robot' }, { href: '/memory', label: 'Memory', icon: 'book' }],
}));
}
@@@ -343,7 +345,8 @@ ${modelChip(model)}
const title = first ? clip(first.task, 60) : 'New chat';
return send(res, status, {
viewer: req.viewer, config, path: req.originalUrl, title, app: true, noReferrer: true,
-- css: ['css/chat.css'], scripts: ['js/chat.js'], styles: ['thread.css'], sharedScripts: ['ov-thread.js'],
++ // The network's sidebar (kit.css, kit-web.js) and its conversation UI (thread.css, ov-thread.js).
++ css: ['css/chat.css'], scripts: ['js/chat.js'], styles: ['kit.css', 'thread.css'], sharedScripts: ['kit-web.js', 'ov-thread.js'],
body: html`${busy ? raw('<noscript><meta http-equiv="refresh" content="5"></noscript>') : ''}
<div class="chat" data-chat="${first ? first.id : ''}">${raw(thread.page({
sidebar: String(sidebar(chats, first ? first.id : null)),
ddiff --git a/test/chat.test.js b/test/chat.test.js
iindex 3a27801..cfa8394 100644
---- a/test/chat.test.js
++++ b/test/chat.test.js
@@@ -60,7 +60,8 @@ const LOC = /^\/chat\/(tsk_[0-9A-HJKMNP-TV-Z]{26})#t-\1$/;
assert.match(page.text, new RegExp(`<a class="ovt-act" href="/tasks/${first}\\?view=details">`), 'Details is the full task page');
assert.match(page.text, /<div class="ovt-meta"><span>Balanced/);
assert.match(page.text, new RegExp(`<input type="hidden" name="parent" value="${first}">`), 'the composer replies to the last turn');
-- assert.match(page.text, new RegExp(`<a href="/chat/${first}" aria-current="page"`), 'the chat is in the list, marked as the one open');
++ assert.match(page.text, new RegExp(`<a class="ovk-sidebar-item is-here" href="/chat/${first}" aria-current="page"`), 'the chat is in the list (the network\'s sidebar), marked as the one open');
++ assert.match(page.text, /<nav class="ovk-sidebar-nav"[^>]*>[\s\S]*Console[\s\S]*Your agents[\s\S]*Memory/, 'Actor\'s places as rows, as Codes\' are');
});
await check('a reply continues the chat: both turns, in order, one chat in the list, with the turn before in mind', async () => {
@@@ -74,8 +75,8 @@ const LOC = /^\/chat\/(tsk_[0-9A-HJKMNP-TV-Z]{26})#t-\1$/;
const page = await t.get(`/chat/${at}`, { as: kim });
const a = page.text.indexOf(`id="t-${first}"`), b = page.text.indexOf(`id="t-${second}"`);
assert.ok(a > 0 && b > a, `the chat through ${at} shows both turns, oldest first`);
-- assert.strictEqual((page.text.match(/<a href="\/chat\/tsk_/g) || []).length, 1, 'one chat in the list');
-- assert.match(page.text, new RegExp(`<a href="/chat/${first}" aria-current="page"`), 'the list names a chat by its first turn');
++ assert.strictEqual((page.text.match(/<a class="ovk-sidebar-item[^"]*" href="\/chat\/tsk_/g) || []).length, 1, 'one chat in the list');
++ assert.match(page.text, new RegExp(`<a class="ovk-sidebar-item is-here" href="/chat/${first}" aria-current="page"`), 'the list names a chat by its first turn');
}
});