openvibers/openvibe.shared Commits

4.24.3: agent-session's web steps read as lookups (web_search and web_fetch before file searches) (#153)

OP OpenVibers committed 16 days ago · f64dde1ec7 · 6 files, +18 −6

Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex aa1cf1f..cd32367 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -6,6 +6,12 @@ A release is the git tag `vX.Y.Z`; consumers pin the tag's tarball (see README).
## Unreleased
++## 4.24.3 — 2026-10-28
++
++- **`agent-session.js`: web steps read as lookups.** A tool whose name speaks of the web (`web_search`, `web_fetch`) is
++ a web step before a file search, and a query given as its description reads "Looked up …". An address reads
++ "Opened …". OpenVibe.Actor's web searches showed as "Listed …".
++
## 4.24.2 — 2026-10-28
- **`agent-session.js` takes `link(url)`**, which decides which https addresses in an agent's text become links; the
ddiff --git a/README.md b/README.md
iindex b25b5fb..85630a0 100644
---- a/README.md
++++ b/README.md
@@@ -2,7 +2,7 @@
> Versioned UI, the OpenVibe Frame (the navbar, footer and "shipped" views every site sits in), SEO, legal and release-client packages every OpenVibe site renders.
--**Status:** alpha, v4.24.2 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
++**Status:** alpha, v4.24.3 (every release is a tag; see [CHANGELOG.md](CHANGELOG.md)). Every deployed
consumer installs a tagged release and none keeps a vendored copy
([docs/migration-plan.md](docs/migration-plan.md) is done); each repository's `package.json` names
the tag it pins.
ddiff --git a/STATUS.json b/STATUS.json
iindex a6e308a..f855143 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -4,7 +4,7 @@
"code": true,
"wave": "W2",
"package": "openvibe-shared",
-- "version": "4.24.2",
++ "version": "4.24.3",
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"deployed": false,
"deployment": "none of its own: a package released as git tags; OpenVibe.Network serves /shared/* from its pinned tag, and a site can serve its own pinned copy (openvibe-shared/serve)",
ddiff --git a/agent-session.js b/agent-session.js
iindex 622a9ca..fe2e305 100644
---- a/agent-session.js
++++ b/agent-session.js
@@@ -55,8 +55,9 @@
if (KIND[name]) return KIND[name];
const w = new Set(String(name || '').replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase().split(/[^a-z]+/).filter(Boolean));
const any = (...xs) => xs.some((x) => w.has(x));
-- return any('bash', 'shell', 'command', 'exec', 'run', 'terminal') ? 'command' : any('edit', 'patch', 'replace') ? 'edit' : any('write', 'create') ? 'write'
-- : any('read', 'cat', 'view', 'open') ? 'read' : any('grep', 'glob', 'find', 'search', 'list', 'ls') ? 'search' : any('web', 'fetch', 'http', 'browse', 'url') ? 'web' : 'tool';
++ // The web first: web_search and web_fetch are looking things up, not searching files.
++ return any('web', 'fetch', 'http', 'browse', 'url', 'internet') ? 'web' : any('bash', 'shell', 'command', 'exec', 'run', 'terminal') ? 'command' : any('edit', 'patch', 'replace') ? 'edit'
++ : any('write', 'create') ? 'write' : any('read', 'cat', 'view', 'open') ? 'read' : any('grep', 'glob', 'find', 'search', 'list', 'ls') ? 'search' : 'tool';
}
const NOUN = { command: ['command', 'commands'], read: ['read', 'reads'], search: ['search', 'searches'], edit: ['edit', 'edits'], write: ['new file', 'new files'], web: ['lookup', 'lookups'], agent: ['helper', 'helpers'], plan: ['plan', 'plan'], tool: ['tool', 'tools'] };
const VERB = {
@@@ -208,7 +209,11 @@
if (edits.length) { out.diff = []; edits.forEach((e, n) => { if (n) out.diff.push(['@', '…']); out.diff.push(...diffLines(e.old_string, e.new_string)); }); }
else if (typeof i.content === 'string') { out.preview = i.content; out.diff = i.content.split('\n').map((l) => ['+', l]); }
if (out.diff) out.diff.forEach(([op]) => { if (op === '+') out.added++; else if (op === '-') out.removed++; });
-- } else if (k === 'web') { out.title = i.query ? `Looked up ${i.query}` : `Opened ${String(i.url || step.what || '').replace(/^https?:\/\//, '').slice(0, 60)}`; out.sub = String(i.url || ''); }
++ } else if (k === 'web') {
++ const asked = i.query || (!i.url && !/^https?:\/\//.test(String(i.description || step.what || '')) ? i.description || step.what : '');
++ const url = i.url || (/^https?:\/\//.test(String(i.description || step.what || '')) ? i.description || step.what : '');
++ out.title = asked ? `Looked up ${asked}` : `Opened ${String(url).replace(/^https?:\/\//, '').slice(0, 60)}`; out.sub = asked ? '' : String(url);
++ }
else if (k === 'agent') { out.title = String(i.description || 'A helper agent'); out.sub = i.subagent_type ? `${i.subagent_type} helper` : 'helper'; out.preview = String(i.prompt || ''); }
else if (k === 'plan') { out.title = 'Updated the plan'; }
else { out.title = String(step.name || 'Tool'); out.sub = String(step.what || ''); }
ddiff --git a/package.json b/package.json
iindex 2e54a03..32251f5 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-shared",
-- "version": "4.24.2",
++ "version": "4.24.3",
"description": "Shared navbar, footer, themes, icons, legal pages, SEO, auth and analytics for every OpenVibe site",
"main": "index.js",
"bin": {
ddiff --git a/test/agent-session.test.js b/test/agent-session.test.js
iindex c7d51b0..c500dd3 100644
---- a/test/agent-session.test.js
++++ b/test/agent-session.test.js
@@@ -21,6 +21,7 @@ assert.deepStrictEqual(['Bash', 'run_command', 'Read', 'Grep', 'Edit', 'write_fi
['command', 'command', 'read', 'search', 'edit', 'write', 'web', 'agent', 'plan', 'command', 'tool'], 'every agent\'s tools map to the same kinds');
assert.deepStrictEqual(as.diffLines('a\nb\nc', 'a\nB\nc'), [['=', 'a'], ['-', 'b'], ['+', 'B'], ['=', 'c']], 'a changed line is a removal and an addition');
assert.deepStrictEqual(as.diffLines('', 'x'), [['-', ''], ['+', 'x']]);
++assert.deepStrictEqual(['web_search', 'web_fetch', 'search_files'].map(as.kindOf), ['web', 'web', 'search'], 'the web before files (4.24.3)');
// OpenVibe.Actor's task events (actor.task-event@1) read like the rest (4.24.1).
assert.deepStrictEqual(as.normalize({ kind: 'state', state: 'running', seq: 2 }), [{ t: 'state', state: 'running' }]);
assert.deepStrictEqual(as.normalize({ kind: 'output', step: 'plan', agent: 'deepseek', text: 'DeepSeek takes it' }), [{ t: 'step', text: 'DeepSeek takes it', agent: 'deepseek' }]);