openvibers/openvibe.chat Commits
Vibe: a guessed freshness window does not hide the Work listing (#261)
Changes
@@@ -119,6 +119,9 @@ const OWNERS = [[/\b(news|headlines?)\b/i, 'news'],];const ownerOf = (q) => (OWNERS.find(([re]) => re.test(String(q || ''))) || [])[1] || null;++// A query that names its own time ("posted recently", "today") keeps the freshness window on the retry; one that does++// not (the bare "remote video editing jobs") lets the retry look outside the window the model guessed (11-01).++const TEMPORAL = /\b(today|tonight|now|latest|recent|recently|new|posted|this\s+(week|month|year)|week|month|year|day)\b/i;/** The 2–3 key nouns of a request, or null when it is already that short ("video editor", "mechanical keyboard"). */function shortenQuery(q) {const words = String(q || '').toLowerCase().replace(/[^\p{L}\p{N}\s'-]+/gu, ' ').split(/\s+/).filter(Boolean);@@@ -153,10 +156,12 @@ async function searchOpenvibe(args, { fetchImpl = null, searchClient = null } =const short = shortenQuery(query);if (short) {const owner = wanted || ownerOf(query);-- const retryBody = await fabricSearch.query({ q: short, scopes: ['network'], limit, ...window, ...(owner ? { owner } : {}), signal: AbortSignal.timeout(8000) }, opts);++ const retryWindow = TEMPORAL.test(query) ? window : {};++ const dropped = freshness && !retryWindow.freshness ? freshness : null;++ const retryBody = await fabricSearch.query({ q: short, scopes: ['network'], limit, ...retryWindow, ...(owner ? { owner } : {}), signal: AbortSignal.timeout(8000) }, opts);const retried = (Array.isArray(retryBody.results) ? retryBody.results : []).slice(0, limit).map((r) => fabricSearch.resultOf(r));-- if (retried.length) return { query: short, original_query: query, retried_with: short, ...window, ...(owner ? { owner } : {}), citations: fabricSearch.citationsOf(retried), results: retried, note: `Nothing matched "${query}". A retry with "${short}" found ${retried.length}; answer from that, or say plainly if it is not what they asked for.` };-- return { query, original_query: query, retried_with: short, ...window, ...(owner ? { owner } : {}), citations: [], results: [], note: nothingNote(query, short) };++ if (retried.length) return { query: short, original_query: query, retried_with: short, ...retryWindow, ...(dropped ? { freshness_dropped: dropped } : {}), ...(owner ? { owner } : {}), citations: fabricSearch.citationsOf(retried), results: retried, note: `Nothing matched "${query}"${dropped ? ` in the last ${dropped}` : ''}. A retry with "${short}"${dropped ? ' without that window' : ''} found ${retried.length}; answer from that, or say plainly if it is not what they asked for.` };++ return { query, original_query: query, retried_with: short, ...retryWindow, ...(dropped ? { freshness_dropped: dropped } : {}), ...(owner ? { owner } : {}), citations: [], results: [], note: nothingNote(query, short) };}return { query, ...window, ...product, citations: [], results: [], note: nothingNote(query) };} catch (err) {@@@ -148,13 +148,12 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', aassert.match(none.note, /2–3 key nouns/, 'the one hint: a shorter query');assert.match(none.note, /video editor/, 'the job-title example the starter chip needs');// "remote video editing jobs" finds nothing: one automatic retry with the nouns, narrowed to Work, before the model spends a round.++ const job = { scope: 'network', kind: 'document', owner: 'work', type: 'job', title: 'Intern Video Editing & Support at Bettermile', snippet: 'Video editing, remote-friendly', url: 'https://openvibe.work/jobs/job_1', published_at: '2026-10-26T00:00:00Z' };const retrySeen = [];const retryFake = async (url) => {retrySeen.push(new URL(String(url)));const q = retrySeen[retrySeen.length - 1].searchParams.get('q');-- const results = q === 'video editing'-- ? [{ scope: 'network', kind: 'document', owner: 'work', type: 'job', title: 'Intern Video Editing & Support at Bettermile', snippet: 'Video editing, remote-friendly', url: 'https://openvibe.work/jobs/job_1', published_at: '2026-10-26T00:00:00Z' }]-- : [];++ const results = q === 'video editing' ? [job] : [];return new Response(JSON.stringify({ results }), { status: 200, headers: { 'content-type': 'application/json' } });};const retried = await aiTools._runners.search_openvibe({ query: 'Find remote video editing jobs posted recently', freshness: 'week' }, { fetchImpl: retryFake });@@@ -163,7 +162,13 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', aassert.deepStrictEqual([retrySeen[1].searchParams.get('q'), retrySeen[1].searchParams.get('owner'), retrySeen[1].searchParams.get('freshness')], ['video editing', 'work', 'week']);assert.deepStrictEqual([retried.query, retried.original_query, retried.results.length], ['video editing', 'Find remote video editing jobs posted recently', 1]);assert.match(retried.note, /retry with "video editing" found 1/);-- // ...and when the retry finds nothing either, the note says both queries and still gives the hint.++ // A bare query with no time words: a window the model guessed is dropped for the retry, so the Work job is found.++ const bareSeen = [];++ const bare = await aiTools._runners.search_openvibe({ query: 'remote video editing jobs', owner: 'work', freshness: 'day' }, { fetchImpl: async (url) => { bareSeen.push(new URL(String(url))); const q = bareSeen[bareSeen.length - 1].searchParams.get('q'); return new Response(JSON.stringify({ results: q === 'video editing' ? [job] : [] }), { status: 200, headers: { 'content-type': 'application/json' } }); } });++ assert.deepStrictEqual([bareSeen[0].searchParams.get('freshness'), bareSeen[1].searchParams.get('freshness')], ['day', null], 'no time word: the retry looks outside the guessed window');++ assert.deepStrictEqual([bare.freshness_dropped, bare.results.length], ['day', 1]);++ assert.match(bare.note, /in the last day/);++ // ...and when both find nothing, the note still gives the hint.const bothEmpty = await aiTools._runners.search_openvibe({ query: 'remote video editing jobs', freshness: 'day' }, { fetchImpl: async () => new Response(JSON.stringify({ results: [] }), { status: 200, headers: { 'content-type': 'application/json' } }) });assert.match(bothEmpty.note, /"remote video editing jobs" and a retry with "video editing" both found nothing/);assert.match(bothEmpty.note, /2–3 key nouns/);
@@ -119,6 +119,9 @@ const OWNERS = [
@@ -119,6 +119,9 @@ const OWNERS = [
[/\b(news|headlines?)\b/i, 'news'],
[/\b(news|headlines?)\b/i, 'news'],
];
];
const ownerOf = (q) => (OWNERS.find(([re]) => re.test(String(q || ''))) || [])[1] || null;
const ownerOf = (q) => (OWNERS.find(([re]) => re.test(String(q || ''))) || [])[1] || null;
+// A query that names its own time ("posted recently", "today") keeps the freshness window on the retry; one that does
+// not (the bare "remote video editing jobs") lets the retry look outside the window the model guessed (11-01).
+const TEMPORAL = /\b(today|tonight|now|latest|recent|recently|new|posted|this\s+(week|month|year)|week|month|year|day)\b/i;
/** The 2–3 key nouns of a request, or null when it is already that short ("video editor", "mechanical keyboard"). */
/** The 2–3 key nouns of a request, or null when it is already that short ("video editor", "mechanical keyboard"). */
function shortenQuery(q) {
function shortenQuery(q) {
const words = String(q || '').toLowerCase().replace(/[^\p{L}\p{N}\s'-]+/gu, ' ').split(/\s+/).filter(Boolean);
const words = String(q || '').toLowerCase().replace(/[^\p{L}\p{N}\s'-]+/gu, ' ').split(/\s+/).filter(Boolean);
@@ -153,10 +156,12 @@ async function searchOpenvibe(args, { fetchImpl = null, searchClient = null } =
@@ -153,10 +156,12 @@ async function searchOpenvibe(args, { fetchImpl = null, searchClient = null } =
const short = shortenQuery(query);
const short = shortenQuery(query);
if (short) {
if (short) {
const owner = wanted || ownerOf(query);
const owner = wanted || ownerOf(query);
- const retryBody = await fabricSearch.query({ q: short, scopes: ['network'], limit, ...window, ...(owner ? { owner } : {}), signal: AbortSignal.timeout(8000) }, opts);
+ const retryWindow = TEMPORAL.test(query) ? window : {};
+ const dropped = freshness && !retryWindow.freshness ? freshness : null;
+ const retryBody = await fabricSearch.query({ q: short, scopes: ['network'], limit, ...retryWindow, ...(owner ? { owner } : {}), signal: AbortSignal.timeout(8000) }, opts);
const retried = (Array.isArray(retryBody.results) ? retryBody.results : []).slice(0, limit).map((r) => fabricSearch.resultOf(r));
const retried = (Array.isArray(retryBody.results) ? retryBody.results : []).slice(0, limit).map((r) => fabricSearch.resultOf(r));
- if (retried.length) return { query: short, original_query: query, retried_with: short, ...window, ...(owner ? { owner } : {}), citations: fabricSearch.citationsOf(retried), results: retried, note: `Nothing matched "${query}". A retry with "${short}" found ${retried.length}; answer from that, or say plainly if it is not what they asked for.` };
- return { query, original_query: query, retried_with: short, ...window, ...(owner ? { owner } : {}), citations: [], results: [], note: nothingNote(query, short) };
+ if (retried.length) return { query: short, original_query: query, retried_with: short, ...retryWindow, ...(dropped ? { freshness_dropped: dropped } : {}), ...(owner ? { owner } : {}), citations: fabricSearch.citationsOf(retried), results: retried, note: `Nothing matched "${query}"${dropped ? ` in the last ${dropped}` : ''}. A retry with "${short}"${dropped ? ' without that window' : ''} found ${retried.length}; answer from that, or say plainly if it is not what they asked for.` };
+ return { query, original_query: query, retried_with: short, ...retryWindow, ...(dropped ? { freshness_dropped: dropped } : {}), ...(owner ? { owner } : {}), citations: [], results: [], note: nothingNote(query, short) };
}
}
return { query, ...window, ...product, citations: [], results: [], note: nothingNote(query) };
return { query, ...window, ...product, citations: [], results: [], note: nothingNote(query) };
} catch (err) {
} catch (err) {
@@ -148,13 +148,12 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', a
@@ -148,13 +148,12 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', a
assert.match(none.note, /2–3 key nouns/, 'the one hint: a shorter query');
assert.match(none.note, /2–3 key nouns/, 'the one hint: a shorter query');
assert.match(none.note, /video editor/, 'the job-title example the starter chip needs');
assert.match(none.note, /video editor/, 'the job-title example the starter chip needs');
// "remote video editing jobs" finds nothing: one automatic retry with the nouns, narrowed to Work, before the model spends a round.
// "remote video editing jobs" finds nothing: one automatic retry with the nouns, narrowed to Work, before the model spends a round.
+ const job = { scope: 'network', kind: 'document', owner: 'work', type: 'job', title: 'Intern Video Editing & Support at Bettermile', snippet: 'Video editing, remote-friendly', url: 'https://openvibe.work/jobs/job_1', published_at: '2026-10-26T00:00:00Z' };
const retrySeen = [];
const retrySeen = [];
const retryFake = async (url) => {
const retryFake = async (url) => {
retrySeen.push(new URL(String(url)));
retrySeen.push(new URL(String(url)));
const q = retrySeen[retrySeen.length - 1].searchParams.get('q');
const q = retrySeen[retrySeen.length - 1].searchParams.get('q');
- const results = q === 'video editing'
- ? [{ scope: 'network', kind: 'document', owner: 'work', type: 'job', title: 'Intern Video Editing & Support at Bettermile', snippet: 'Video editing, remote-friendly', url: 'https://openvibe.work/jobs/job_1', published_at: '2026-10-26T00:00:00Z' }]
- : [];
+ const results = q === 'video editing' ? [job] : [];
return new Response(JSON.stringify({ results }), { status: 200, headers: { 'content-type': 'application/json' } });
return new Response(JSON.stringify({ results }), { status: 200, headers: { 'content-type': 'application/json' } });
};
};
const retried = await aiTools._runners.search_openvibe({ query: 'Find remote video editing jobs posted recently', freshness: 'week' }, { fetchImpl: retryFake });
const retried = await aiTools._runners.search_openvibe({ query: 'Find remote video editing jobs posted recently', freshness: 'week' }, { fetchImpl: retryFake });
@@ -163,7 +162,13 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', a
@@ -163,7 +162,13 @@ t('the tool list and the runners: bounded, fair, refusing what is not theirs', a
assert.deepStrictEqual([retrySeen[1].searchParams.get('q'), retrySeen[1].searchParams.get('owner'), retrySeen[1].searchParams.get('freshness')], ['video editing', 'work', 'week']);
assert.deepStrictEqual([retrySeen[1].searchParams.get('q'), retrySeen[1].searchParams.get('owner'), retrySeen[1].searchParams.get('freshness')], ['video editing', 'work', 'week']);
assert.deepStrictEqual([retried.query, retried.original_query, retried.results.length], ['video editing', 'Find remote video editing jobs posted recently', 1]);
assert.deepStrictEqual([retried.query, retried.original_query, retried.results.length], ['video editing', 'Find remote video editing jobs posted recently', 1]);
assert.match(retried.note, /retry with "video editing" found 1/);
assert.match(retried.note, /retry with "video editing" found 1/);
- // ...and when the retry finds nothing either, the note says both queries and still gives the hint.
+ // A bare query with no time words: a window the model guessed is dropped for the retry, so the Work job is found.
+ const bareSeen = [];
+ const bare = await aiTools._runners.search_openvibe({ query: 'remote video editing jobs', owner: 'work', freshness: 'day' }, { fetchImpl: async (url) => { bareSeen.push(new URL(String(url))); const q = bareSeen[bareSeen.length - 1].searchParams.get('q'); return new Response(JSON.stringify({ results: q === 'video editing' ? [job] : [] }), { status: 200, headers: { 'content-type': 'application/json' } }); } });
+ assert.deepStrictEqual([bareSeen[0].searchParams.get('freshness'), bareSeen[1].searchParams.get('freshness')], ['day', null], 'no time word: the retry looks outside the guessed window');
+ assert.deepStrictEqual([bare.freshness_dropped, bare.results.length], ['day', 1]);
+ assert.match(bare.note, /in the last day/);
+ // ...and when both find nothing, the note still gives the hint.
const bothEmpty = await aiTools._runners.search_openvibe({ query: 'remote video editing jobs', freshness: 'day' }, { fetchImpl: async () => new Response(JSON.stringify({ results: [] }), { status: 200, headers: { 'content-type': 'application/json' } }) });
const bothEmpty = await aiTools._runners.search_openvibe({ query: 'remote video editing jobs', freshness: 'day' }, { fetchImpl: async () => new Response(JSON.stringify({ results: [] }), { status: 200, headers: { 'content-type': 'application/json' } }) });
assert.match(bothEmpty.note, /"remote video editing jobs" and a retry with "video editing" both found nothing/);
assert.match(bothEmpty.note, /"remote video editing jobs" and a retry with "video editing" both found nothing/);
assert.match(bothEmpty.note, /2–3 key nouns/);
assert.match(bothEmpty.note, /2–3 key nouns/);