@chatpanel/events 0.362.0 → 0.371.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/answer-grounding.js +8 -5
- package/attached-paths.js +16 -16
- package/capability-endpoints.js +1 -1
- package/context-attachments.js +4 -4
- package/digest.js +5 -5
- package/document-context.js +7 -0
- package/engine-pacer.js +1 -1
- package/event.js +1 -1
- package/extract-capability.js +4 -4
- package/index.js +1 -1
- package/kb-capability.js +1 -0
- package/kb-chunk.js +14 -0
- package/kb-graph.js +3 -0
- package/kb-index.js +1 -0
- package/kb-research.js +5 -0
- package/kb-tool.js +9 -0
- package/package.json +17 -1
- package/page-context.js +5 -0
- package/prefetch.js +4 -2
- package/retrieval-plan.js +2 -2
- package/rrf.js +1 -1
- package/search-modes.js +4 -4
- package/settings-registry.js +1 -1
- package/shim.js +2 -2
- package/site-pages.js +1 -1
- package/stitch.js +13 -12
- package/text-index.js +1 -1
- package/tool-dispatch.js +4 -4
- package/tool-hub.js +10 -10
- package/turn-gather.js +1 -1
- package/turn-intent.js +3 -3
- package/turn-pipeline.js +3 -3
- package/web-search-tool.js +8 -8
- package/web-search.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/events",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.371.1",
|
|
4
4
|
"description": "The canonical ChatPanel event-log and capability contracts — typed durable facts, clock-free deterministic linearization, schema upcasting, and the invariants the replay harness asserts. Pure, dependency-free ESM shared by the ChatPanel extension, gateway and bridge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -189,6 +189,14 @@
|
|
|
189
189
|
"./skill-files.js": "./skill-files.js",
|
|
190
190
|
"./attached-paths.js": "./attached-paths.js",
|
|
191
191
|
"./extract-capability.js": "./extract-capability.js",
|
|
192
|
+
"./kb-chunk.js": "./kb-chunk.js",
|
|
193
|
+
"./kb-graph.js": "./kb-graph.js",
|
|
194
|
+
"./kb-index.js": "./kb-index.js",
|
|
195
|
+
"./kb-research.js": "./kb-research.js",
|
|
196
|
+
"./document-context.js": "./document-context.js",
|
|
197
|
+
"./page-context.js": "./page-context.js",
|
|
198
|
+
"./kb-tool.js": "./kb-tool.js",
|
|
199
|
+
"./kb-capability.js": "./kb-capability.js",
|
|
192
200
|
"./skill-scan.js": "./skill-scan.js",
|
|
193
201
|
"./skill-sources.js": "./skill-sources.js",
|
|
194
202
|
"./skill-vars.js": "./skill-vars.js",
|
|
@@ -524,6 +532,14 @@
|
|
|
524
532
|
"skill-files.js",
|
|
525
533
|
"attached-paths.js",
|
|
526
534
|
"extract-capability.js",
|
|
535
|
+
"kb-chunk.js",
|
|
536
|
+
"kb-graph.js",
|
|
537
|
+
"kb-index.js",
|
|
538
|
+
"kb-research.js",
|
|
539
|
+
"document-context.js",
|
|
540
|
+
"page-context.js",
|
|
541
|
+
"kb-tool.js",
|
|
542
|
+
"kb-capability.js",
|
|
527
543
|
"skill-scan.js",
|
|
528
544
|
"skill-sources.js",
|
|
529
545
|
"skill-vars.js",
|
package/page-context.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{createKb as z,addDocument as D,searchKb as A,shortHash as y,chunkById as S}from"./kb-index.js";import{needsWhole as B}from"./digest.js";const j=Object.freeze({maxChars:4e5});function C(l,t){return`${String(l||"").replace(/#.*$/,"")}|${y(String(t||""))}`}function v({max:l=6}={}){const t=new Map;return{get(c){if(!t.has(c))return null;const i=t.get(c);return t.delete(c),t.set(c,i),i},set(c,i){for(t.delete(c),t.set(c,i);t.size>l;)t.delete(t.keys().next().value)},get size(){return t.size}}}function M({url:l="",title:t="",text:c="",cache:i=null,now:h=()=>Date.now()}={}){const a=C(l,c),f=i?.get?.(a);if(f)return{kb:f.kb,docId:f.docId,chunks:f.chunks,reused:!0,ms:0};const u=h(),n=z({name:t||l||"page",now:h,embed:"off"}),o=`page-${y(a)}`,{chunks:p}=D(n,{id:o,title:t,pages:[String(c||"")],source:l?{url:l}:{},now:h,markdownHeadings:!0}),s={kb:n,docId:o,chunks:p.length};return i?.set?.(a,s),{...s,reused:!1,ms:Math.max(0,h()-u)}}async function P({url:l="",title:t="",text:c="",question:i="",queries:h=[],budgetChars:a=6e3,cache:f=null,rerank:u=null,now:n=()=>Date.now()}={}){const o=String(c||"");if(o.length<=a)return{text:o,whole:!0,chunks:0,picked:[],sections:[],reused:!1,ms:0};const p=n(),s=M({url:l,title:t,text:o,cache:f,now:n}),x=await A(s.kb,i,{limit:12,queries:h.filter(Boolean),rerank:u,now:n}).catch(()=>({results:[]})),d=new Map;let g=0;const k=e=>e.chars+2+(e.section?e.section.length+5:0),r=e=>!e||d.has(e.n)||g+k(e)>a?!1:(d.set(e.n,e),g+=k(e),!0),E=.4;for(let e=1;e<=s.chunks;e++){const $=S(s.kb,`${s.docId}#${e}`);if(!$||g+k($)>a*E)break;r($)}const m=d.size;for(const e of x.results||[])r(S(s.kb,e.id));if(d.size<=m)for(let e=2;e<=s.chunks&&g<a;e++)r(S(s.kb,`${s.docId}#${e}`));const b=[...d.values()].sort((e,$)=>e.n-$.n),N=[];let O=null;for(const e of b)e.section&&e.section!==O&&N.push(`## ${e.section}`),O=e.section,N.push(e.text);const I=(x.results||[]).map(e=>S(s.kb,e.id)).filter(e=>e&&d.has(e.n)&&e.n>m),_=[...new Set(I.map(e=>e.section).filter(Boolean))];return{text:N.join(`
|
|
2
|
+
|
|
3
|
+
`),whole:!1,chunks:s.chunks,picked:b.map(e=>e.n),sections:_,reused:s.reused,ms:Math.max(0,n()-p)}}const w=`⟦WEB_CONTENT⟧
|
|
4
|
+
`,R=`
|
|
5
|
+
⟦/WEB_CONTENT⟧`;async function H(l,{question:t="",queries:c=[],budgetChars:i=6e3,cache:h=null,rerank:a=null,now:f=()=>Date.now()}={}){const u=String(l??"");if(B(t))return{text:u,note:"",context:null};let n=null;if(u.startsWith("{"))try{n=JSON.parse(u)}catch{n=null}const o=typeof n?.text=="string"?n.text:n?null:u;if(o==null||o.length<=i)return{text:u,note:"",context:null};const p=o.indexOf(w),s=o.lastIndexOf(R),x=p>=0&&s>p,d=x?o.slice(0,p+w.length):"",g=x?o.slice(p+w.length,s):o,k=x?o.slice(s):"",r=await P({url:n?.url||"",title:n?.title||"",text:g,question:t,queries:c,budgetChars:Math.max(800,i-d.length-k.length),cache:h,rerank:a,now:f}),E=`${d}${r.text}${k}`,m=r.sections.slice(0,2).join("; "),b=r.whole?"":`${r.picked.length} of ${r.chunks} passages${m?` — ${m}`:""}${r.reused?" · index reused":""}`;return{text:n?JSON.stringify({...n,text:E,chars:n.chars??o.length,passages:r.picked.length,of:r.chunks}):E,note:b,context:r}}export{j as PAGE_READ_ARGS,v as createPageIndexCache,M as indexPage,P as pageContext,C as pageKey,H as shapePageRead};
|
package/prefetch.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import{researchAsk as O,runResearch as Z}from"./web-research.js";import{frontPagesAskedAbout as ee}from"./site-pages.js";import{weatherFromSearch as te}from"./weather-tool.js";const R=/(\bhow(?:'s| is| was|s) (?:the )?(?:weather|forecast|temperature)\b|\bwhat(?:'s| is|s) (?:the )?(?:weather|forecast|temperature)\b|\b(?:weather|forecast|temperature) (?:in|for|at|around|near)\b|\bis it (?:raining|snowing|hot|cold|warm|sunny|cloudy|windy)\b|\b(?:will|does) it (?:rain|snow)\b|\bhow (?:hot|cold|warm|humid|windy) is it\b|^\s*(?:weather|forecast)\b|\b(?:weather|forecast)\s*\??\s*$)/i,ne=/\b(right now|now|today|tonight|this (?:morning|afternoon|evening|weekend|week)|tomorrow|currently|at the moment|these days|later)\b/gi,se=new Set(["here","there","home","outside","my location","my area","my city","where i am","it","that"]),N=8,E="(?:page|tab|article|post|thread|discussion|story|site|website|doc|document|comments?|content|piece|blog(?: post)?|paper|video|readme|pdf)",oe=new RegExp(`\\b(?:this|current|the current|the open|open|that)\\s+${E}\\b`,"i"),re=new RegExp(`^\\s*(?:(?:can you |could you |please )?(?:summari[sz]e|tl;?\\s?dr|recap|give me the gist|what are the key (?:points|takeaways))(?:\\s+(?:it|this|that|here|(?:the|this)\\s+${E}(?:\\s+and\\s+(?:the\\s+)?${E})?))?|what(?:'s| is| are)? (?:people|they|folks|commenters) (?:saying|think(?:ing)?)(?: here| about (?:it|this))?)\\s*[?.!]*\\s*$`,"i"),ae=/\b(?:my|our|your|the|this|that|last|today'?s|yesterday'?s)\s+(?:meeting|chat|conversation|call|standup|notes?|email|inbox|calendar|day|week|transcript|thread with)\b|https?:\/\//i,ie=/^\s*(?:(?:please|pls|can you|could you|just|ok,?|no,?|then|so|now)\s+)*(?:use (?:the )?(?:web|internet)(?: search)?|use web ?search|(?:do|run|perform|make|start|try)(?: an?| the)? (?:(?:web|internet|online|google) ?)?search|search for (?:it|that|this)|search (?:the )?(?:web|internet|online)|web ?search(?: it)?|google(?: it| that)?|look (?:it |that )?up(?: online| on the web)?|check (?:the web|online)|try (?:the )?(?:web|internet|a web search|web search)|search (?:it|that|again|online))\b(?:\s+(?:for|about)\s+(.+?))?(?:,?\s+(?:please|pls|thanks|instead|now|then))*\s*[?.!]*\s*$/i;function ce(e){const t=ie.exec(String(e||""));if(!t)return null;const n=String(t[1]||"").trim();return n?{query:n}:{}}const he=/\b(?:weather|forecast|temperature|rain|snow)\b/i,le=/\b(?:rest of (?:the|this) (?:week|weekend|month)|(?:this|next|coming) (?:week|weekend)|(?:the|this) weekend|week ahead|the week|next (?:few|several|couple of) days|coming days|(?:5|7|10|14)[- ]?days?|extended|long[- ]range|two[- ]weeks?)\b/i,ue=/\b(?:i|we) (?:asked|said|wrote|told|searched|talked|discussed|mentioned|looked up|checked)\b|\b(?:did|have|had) (?:i|we)\b|\bhow (?:many|often) (?:times )?(?:i|we|did|have)\b|\bhow many times\b|\bmy (?:chats?|notes?|history|meetings?|conversations?|questions?|searches)\b|\blast time (?:i|we)\b/i,pe=/\b(?:find out more|find (?:out )?more|more (?:info|information|details)|look into (?:it|that|this)|dig (?:deeper|into (?:it|that))|get more details?|find (?:it|that) out|check (?:on )?(?:it|that) (?:again|online)|search (?:for )?more|look (?:it|that) up|find (?:the )?(?:rest|full|whole)(?: of it| forecast)?)\b/i,de=/^\s*(?:yes|yeah|yep|yup|sure|ok(?:ay)?|k|please(?: do)?|go ahead|go for it|do it|yes please|sure thing|absolutely|of course|ok look|look|search|please search|search it)(?:[\s,.!]+(?:please|thanks|thank you|go ahead|do it|look|search|yes))*[\s.!]*$/i,we=/\b(?:search the web|web search|search online|search for|look (?:it|that|this) up|look up|check online|find (?:it|that|out|more))\b/i,fe=/(?:web search for|search the web for|search (?:online )?for|look up|look for)\s+(?:the\s+)?(.{3,160}?)(?:\s*[?.!]|$)/i;function ge(e){const t=String(e||"").split(/\n+/).map(s=>s.trim()).filter(Boolean).slice(-3).join(" ");if(we.test(t)&&/\?/.test(t)){const s=(fe.exec(t)?.[1]||"").replace(/\s+for me$/i,"").trim();if(s)return s}const n=/\b(?:searching(?: the web| online)? for|looking up|checking(?: the web| online)? for)\s+(?:the\s+)?(.{3,160}?)(?:\.\.\.|…|[.!?]|$)/i.exec(t);return n?n[1].trim():""}const A=/^\s*(?:(?:no|nope|actually|but|well|sorry)\b[,.!]?\s*)?(?:i|we) (?:asked|said|meant|wanted)\b/i,x=/\b(?:did|when|how (?:many|often)|earlier|before|yesterday|last (?:time|week|month)|ago|previously|other day)\b/i;function be(e){const t=String(e||"");if(!A.test(t)||x.test(t))return"";const n=t.replace(A,"").replace(/^\s*(?:for|about)\s+/i,"").replace(/[.;]\s+(?:and|also)\s+/gi," and ").replace(/,?\s+not\s+[^.?!]*/i,"").trim();return/^(?:the\s+)?(?:weather|forecast|temperature)\b/i.test(n)?`what is ${/^the\s/i.test(n)?"":"the "}${n}`:""}function ke(e){const t=String(e||"");return A.test(t)&&!x.test(t)?!1:ue.test(t)}const me=/^\s*(?:and|what about|how about|now|no,?|ok,?|same for)\b[^?.!]{0,30}[?.!]*\s*$/i;function C(e){const t=String(e||"").trim();return!t||t.length>300||ae.test(t)?null:oe.test(t)||re.test(t)?{}:null}function w(e){return String(e||"").replace(ne," ").replace(/[?!.,;:]+$/g,"").replace(/^\s*(the|in|at|for|around|near|of)\s+/i,"").replace(/\s+/g," ").trim()}const P=/\b(how|what|what's|whats|is|are|was|will|do|does|can|should|why|when|the|a|an|tell|me|there|here|it|like|about)\b/i;function y(e){const t=e.toLowerCase();return t.length>=2&&t.length<=60&&!se.has(t)&&!P.test(t)&&!/^(weather|forecast|temperature)$/.test(t)&&/^[\p{L}]/u.test(t)&&t.split(/\s+/).length<=5}function T(e){const t=String(e||"").trim();return!R.test(t)||$(t)||/\b(?:love|like|hate|enjoy|miss|prefer)\s+(?:this|the|that|such|today's)?\s*(?:weather|forecast)\b/i.test(t)||/\b(?:api|app|apps|service|widget|feature|code|bug|model|tool|component|test|tests|data|endpoint|sdk|library|module|page|screen)\b/i.test(t)?!1:t.split(/\s+/).length<=12}const ye=/\s+(?:for|over|during|through|in|this|next|and)?\s*(?:the\s+)?(?:rest of (?:the|this) (?:week|weekend|day|month)|next (?:few|several|couple of|\d+) days|(?:this|next|coming) (?:week|weekend|month|few days)|the (?:weekend|week(?: ahead)?|coming days)|week ahead|\d+[- ]days?(?: forecast)?)\b/gi;function $(e){const t=String(e||"").trim();if(!R.test(t))return"";const n=t.replace(ye,"").trim();let s=/\b(?:in|at|for|around|near)\s+([^?!.;]+?)(?:\s+(?:right now|now|today|tonight|tomorrow|currently|this \w+))*\s*[?!.]*$/i.exec(n);if(s){const o=w(s[1].split(/\s+(?:and|&|vs\.?|versus|compared (?:to|with)|then|,)\s+/i)[0]);if(y(o))return o;if(y(w(s[1])))return w(s[1])}return s=/^(?:what(?:'s| is) the\s+)?([\p{L}][\p{L}\s,.'-]{1,60}?)\s+(?:weather|forecast|temperature)\b/iu.exec(n),s&&y(w(s[1]))&&!L.test(w(s[1]))||(s=/\b(?:weather|forecast|temperature)\s*[:\-]?\s+([\p{L}][\p{L}\s,.'-]{1,60}?)\s*[?!.]*$/iu.exec(n),s&&y(w(s[1])))?w(s[1]):""}const L=/\b(summari[sz]e|explain|try|again|retry|do|make|write|show|tell|open|read|find|search|help|stop|continue|go|list|give|send|run|check|fix|get|fetch|pull|grab|look ?up|display|compare|bring|thanks|thank|yes|no|please|this|that|my|page|note|file|meeting|chat|sounds?|good|great|nice|cool|fine|perfect|awesome|sure|nothing|else|ok|okay|yeah|yep|nope|bye|hello|hi|hey|time|traffic|news|story|joke|stock|price|you|yourself|him|her|them|us)\b/i,$e=/^(?:(?:okay|ok|alright|all right|great|cool|thanks|thank you|fine|good|and|also|then|so|now|actually|well|um+|uh+|hmm+|oh|no|wait)(?:[\s,.!—-]+|$))+/i,Se=/^(?:(?:i(?: want| wanted| would like|'d like) to know|i'm wondering|i wonder|(?:can|could) you (?:tell|check) (?:me)?|tell me)\s+)/i,W=/^(?:(?:how|what) about|(?:how|what)(?:'s| is|s) it(?: like)?(?: in| at| for| around| near)?|(?:in|at|for|around|near))\b[\s,]*/i;function F(e,t){if(!t||t.kind!=="weather")return"";const n=String(e||"").trim().replace(/[?!.]+$/,"").trim(),s=n.replace($e,"").trim().replace(Se,"").trim();if(!s||s.split(/\s+/).length>N)return"";const o=W.test(s)||s!==n&&/^(?:and|also)\b/i.test(n),r=w(s.replace(W,"").replace(/^(?:like\s+)?(?:in|at|for|around|near)\s+/i,""));return!r||/\d/.test(r)||!o&&r.split(/\s+/).length>2||!y(r)||L.test(r)?"":r}const k="([\\p{L}$][\\p{L}\\p{N}.&'-]*(?:\\s+[\\p{L}][\\p{L}\\p{N}.&'-]*){0,3})",_e=[new RegExp(`\\b(?:share price|stock price|stock quote|ticker)\\s+(?:of|for)\\s+${k}`,"iu"),{question:!0,re:new RegExp(`\\b(?:stock|stocks|shares?)\\s+(?:of|for|in)\\s+${k}`,"iu")},new RegExp(`\\b${k}(?:'s)?\\s+(?:stock|shares)\\s+(?:price|doing|trading|today|now|performance|performing|up|down|quote)\\b`,"iu"),new RegExp(`\\b${k}(?:'s)?\\s+(?:share price|stock price|stock quote)\\b`,"iu"),new RegExp(`^\\s*${k}(?:'s)?\\s+(?:stock|shares)\\s*\\??\\s*$`,"iu"),new RegExp(`\\b(?:how|where)(?:'s| is| are)\\s+${k}\\s+(?:stock\\s+|shares\\s+)?trading\\b`,"iu"),new RegExp(`\\bwhat(?:'s| is| are)\\s+${k}\\s+trading at\\b`,"iu"),/\$([A-Z]{1,5})\b/u],Ee=/^(?:the|a|an|my|our|your|this|that|it|its|their|market|stock market|markets|price|prices|today|now|company|companies|how|what|is|are|doing|of|for|in|weather|forecast|news|time|date|temperature|rain|you|me|us|them|those|these)$/i,Ae=/^(?:how|what|what's|whats|where|is|are|was|the|a|an|can|could|you|tell|me|about|of|for|in|and|also|so|now|then|please|check|show|give|get)$/i,Le=/\s+(?:stock|stocks|shares?|price|prices|doing|trading|today|now|right now|currently|at the moment|this (?:morning|afternoon|week)|lately|so far)\b.*$/i;function D(e){const t=e.toLowerCase();return t.length>=1&&t.length<=40&&!Ee.test(t)&&!P.test(t)&&/^[\p{L}]/u.test(t)&&t.split(/\s+/).length<=4}function je(e){const t=e.split(/\s+/).filter(Boolean);for(;t.length>1&&Ae.test(t[0]);)t.shift();return t.join(" ")}function q(e){return String(e||"").replace(/[?!.,;:]+$/g,"").replace(Le,"").replace(/(?:\s+(?:at|on|up|down|for me|please))+$/i,"").replace(/^\s*(?:the|shares? of|stock of)\s+/i,"").replace(/'s$/i,"").replace(/\s+(?:corp(?:oration)?|inc|co|company|ltd)\.?$/i,t=>t).replace(/\s+/g," ").trim()}function v(e){const t=String(e||"").trim(),n=/\?\s*$/.test(t)||/^\s*(?:(?:hey|hi|ok|okay|so|and|now)[\s,]+)*(?:how|what|where|is|are|can|could|would|will|tell|check|show|give|get|find|look up|please)\b/i.test(t);for(const s of _e){const o=s instanceof RegExp?s:s.re;if(s.question&&!n)continue;const r=o.exec(t);if(!r)continue;const l=je(q(r[1]));if(D(l))return l}return""}function B(e,t){if(!t||t.kind!=="stock")return"";let n=String(e||"").trim().replace(/[?!.]+$/,"").trim();if(!n||n.split(/\s+/).length>N)return"";n=n.replace(/^(?:(?:okay|ok|fine|good|great|thanks|thank you|cool|alright|all right|that'?s (?:fine|good|great|ok|okay))[\s,.!—-]*)+/i,"").trim();const s=/^(?:(?:and|also|then|so|now)[\s,]+)*(?:how about|what about)\b/i.test(n)||/^(?:and|also)[\s,]+/i.test(n);n=n.replace(/^(?:(?:and|also|then|so|now)[\s,]+)*(?:(?:how|what) about\b)?[\s,]*/i,"").trim();const o=q(n);return!o||!s&&(o.split(/\s+/).length>2||!/[?]\s*$/.test(String(e))&&o.split(/\s+/).length>1)||!D(o)||L.test(o)?"":o}const M=new RegExp("(?<![\\p{L}\\p{N}'])\\p{L}(?:[ \\t.,\\-–]{1,3}\\p{L}(?![\\p{L}\\p{N}'])){2,}","gu");function U(e){return String(e||"").replace(M,t=>t.replace(/[^\p{L}]/gu,"").toLowerCase())}function Oe(e){return[...String(e||"").matchAll(M)].map(t=>t[0].replace(/[^\p{L}]/gu,"").toLowerCase())}const Re=/\b(?:tell me (?:more |everything |all |something )?about|what do you know about|do you know (?:anything )?about|who(?:'s| is| was| are)|look up|lookup|search (?:the web |online |the internet |google )?for|search up|google|find (?:out )?(?:info(?:rmation)?|details|more|anything|something|everything) (?:on|about)|(?:info|information|background|details) (?:on|about)|research)\s+(.+)$/i,Ne=/[.?!;:,()](?=\s|$)|\s(?:uh|um|umm|er|erm|hmm|like|actually|i mean|sorry|the (?:first |last |sur|family )?name|his|her|their|its|it's|it is|spelled|spelt|and (?:tell|give|find|show|let|search|look)|then|please|for me|on the web|online|on google|from the web|if you can|thanks|thank you)\b/i,xe=/^(?:it|this|that|these|those|him|her|them|me|you|yourself|us|he|she|they|we|i|my|our|your|his|their|here|there|on|in|at|to|for|with|from|going|coming|speaking|talking|calling|joining|what|how|why|when|where|which|the weather|weather)\b/i,Ce=/^(?:my|our|your|this|that|today'?s|yesterday'?s|last|next|latest|recent)\b/i,Pe=/^(?:the|a|an)\b/i,Te=6;function I(e){const n=(String(e||"").split(Ne)[0]||"").replace(/\s+/g," ").replace(/^["'“‘]+|["'”’]+$/g,"").trim(),s=n.split(" ").filter(Boolean);return!s.length||s.length>Te||!new RegExp("\\p{L}","u").test(n)||xe.test(n)?"":n}function We(e){const t=Re.exec(U(e));return t?I(t[1]):""}const Fe=[[/\b(?:last|sur|family|second) ?name\b|\bsurname\b/i,e=>e.length-1],[/\bfirst name\b|\bgiven name\b/i,()=>0]],De=/\b(?:it(?:'s| is)|spelled|spelt|should be|is actually|actually|but|name is)\s+["'“‘]?([\p{L}][\p{L}'-]{1,40})["'”’]?\s*[.!?]*\s*$/iu,qe=/\b(?:no|nope|not|wrong|incorrect|misspel\w*|spell\w*|typo|name|actually|i meant|i mean)\b/i;function ve(e,t){const n=e.toLowerCase(),s=t.toLowerCase(),o=Array.from({length:s.length+1},(r,l)=>l);for(let r=1;r<=n.length;r++){let l=o[0];o[0]=r;for(let c=1;c<=s.length;c++){const u=o[c];o[c]=Math.min(o[c]+1,o[c-1]+1,l+(n[r-1]===s[c-1]?0:1)),l=u}}return o[s.length]}function Be(e,t){return new RegExp("^\\p{Lu}","u").test(t)?e.charAt(0).toUpperCase()+e.slice(1):e}function H(e,t){const n=String(t||"").trim();if(!n)return null;const s=String(e||""),o=Oe(s),r=U(s);let l=o.at(-1)||"";if(!l&&qe.test(r)&&(l=De.exec(r)?.[1]||""),!l||l.length<2)return null;const c=n.split(/\s+/);let u=-1;for(const[a,d]of Fe)if(a.test(r)){u=d(c);break}if(u<0){let a=1/0;c.forEach((d,f)=>{const g=ve(d,l)/Math.max(d.length,l.length);g<a&&(a=g,u=f)}),a>.6&&(u=c.length===1?0:-1)}if(u<0)return null;const i=c[u];return i.toLowerCase()===l.toLowerCase()?{subject:n,replaced:""}:(c[u]=Be(l,c.find(a=>new RegExp("^\\p{Lu}","u").test(a))||i),{subject:c.join(" "),replaced:i})}const Me=/\b(?:search|look|google|check|find|try)\b[^.?!]{0,30}\b(?:web|online|internet|google|up|again|it|him|her|them)\b|\blook(?:ing)? (?:it|that|him|her|them)? ?up\b/i,G=/\b(?:web|online|internet|google)\b/i;function Ue(e,t){if(!t||t.kind!=="lookup"||!t.subject)return null;const n=H(e,t.subject),s=/\b(?:not|wrong|isn'?t|incorrect|nope)\b/i.test(e);return!n&&!s&&!Me.test(e)?null:{subject:n?.subject||t.subject,replaced:n?.replaced||"",corrected:!!n||s,web:G.test(e)}}function J(e,t){const n=We(e);if(n){const o=H(e.slice(e.toLowerCase().indexOf(n.toLowerCase())+n.length),n);return{kind:"lookup",subject:o?.subject||n,replaced:o?.replaced||"",corrected:!!o?.replaced,web:G.test(e)}}const s=Ue(e,t);return s?{kind:"lookup",...s}:null}function K(e){return Ce.test(e)||/@|\d{5,}/.test(e)||!new RegExp("\\p{L}{2,}","u").test(e)?!1:!Pe.test(e)||new RegExp("\\s\\p{Lu}","u").test(e)}const Ie=/\b(?:news|headlines|stories)\s+(?:on|about|from|in|for|regarding|around)\s+(.+)$/i,He=/\bwhat(?:'s| is| are)\s+(?:new|happening|going on|the latest|the news)\s+(?:with|in|on|at|around|from)\s+(.+)$/i,Ge=/^(?:(?:can|could) you (?:tell|give) me |tell me |give me |show me )?(?:the |any |some )?(?:latest |recent |top |today'?s |breaking )?(.{2,60}?)\s+news(?:\s+(?:today|this (?:morning|week|evening)|right now|lately|these days))?\s*[?.!]*$/i,Je=/^(?:(?:can|could) you (?:tell|give) me |tell me |give me |show me |what(?:'s| is| are) )?(?:the |any )?(?:latest |top |today'?s |breaking )?(?:news|headlines)(?:\s+(?:today|this (?:morning|week|evening)|right now))?\s*[?.!]*$/i,Y=/\s+(?:today|tonight|this (?:morning|week|evening|year)|right now|lately|these days|recently|now)$/i;function Ke(e){const t=String(e||"").trim();if(!t||ee(t).length)return null;if(Je.test(t))return{subject:""};const n=Ie.exec(t)||Ge.exec(t),s=n?null:He.exec(t),o=n||s;if(!o)return null;const r=I(o[1].replace(/[?.!]+$/,"").replace(Y,"")).replace(Y,"");return s&&r.split(/\s+/).length>4||!r||!K(r)||/^(?:the )?(?:weather|stock|stocks|market)$/i.test(r)?null:{subject:r}}function nt(e){return/^\s*No (?:history matches|web results)\b/.test(String(e||""))}const z=Object.freeze({page:15e3,web:12e3,lookup:12e3}),Ye=6e3;function st(e){return Object.hasOwn(z,e?.kind)?z[e.kind]:Ye}const ze=/^\s*(?:(?:and|also|ok(?:ay)?|so|then)[,\s]+)?(?:(?:what|how) about|how(?:'s|’s| is| will| does)?(?: it| the weather| things)?(?: be| look(?:ing)?)?|is it|and|for)?\s*(?:(?:right )?now|currently|today|tonight|tomorrow(?: morning| afternoon| evening| night)?|(?:a |the )?day after tomorrow|later(?: today| tonight)?|(?:this|next|the) (?:morning|afternoon|evening|night|weekend|week)|(?:the )?rest of (?:the|this) week|(?:on |this |next )?(?:mon|tues|wednes|thurs|fri|satur|sun)day|outside|out there)\s*[?!.]*\s*$/i;function X(e,t){return!t||t.kind!=="weather"?"":ze.test(String(e||""))?String(t.subject||"here"):""}function Xe(e,t){const n=$(e)||X(e,t)||F(e,t);if(n)return{kind:"weather",subject:n};if(T(e))return{kind:"weather",subject:"here"};const s=v(e)||B(e,t);if(s)return{kind:"stock",subject:s};const o=J(String(e||""),t);if(o)return o;const r=O(e,{previous:t});return r?{kind:"research",subject:r.subject,research:r}:null}function ot(e){const t=(Array.isArray(e)?e:[]).filter(o=>o&&!o.pending&&(o.role==="user"||o.role==="assistant")),n=[];for(let o=0;o<t.length;o++)t[o].role==="user"&&n.push(o);if(n.length<2)return null;let s=null;for(let o=0;o<n.length-1;o++){const r=t[n[o]],l=t[n[o]+1]?.role==="assistant"?t[n[o]+1]:null,c=(r.attachments||[]).find(a=>a?.kind==="prefetch"),u=typeof r.content=="string"?r.content:"";s=Xe(u,s)||(c?{kind:c.prefetch,...c.research?{research:c.research}:{}}:null)||((l?.steps||[]).some(a=>a?.input?.action==="weather"||a?.tool==="weather")?{kind:"weather"}:null)}return s}function rt({text:e="",previous:t=null,previousText:n="",previousAnswer:s="",reach:o=new Set,lookup:r=!1,research:l=!1,page:c=!1,now:u=Date.now()}={}){const i=o instanceof Set?o:new Set(Array.isArray(o)?o:[]),a=[];if(ke(e))return r?Q(e,t,i):[];const d=de.test(String(e||""))?ge(s):"",f=String(e||"").trim().split(/\s+/).length,g=ce(e)||(d?{query:d}:null)||(pe.test(String(e||""))&&f<=14?{}:null);if(g&&(i.has("find:web_search")||i.has("web_search"))){const h=g.query||String(n||"").trim();if(h){const p=i.has("find:web_search"),m=!g.query;return[{kind:"web",tool:p?"find":"web_search",input:p?{action:"web_search",args:{query:h}}:{query:h},label:`Web — ${h.slice(0,60)}`,subject:h,...he.test(h)?{weather:!0}:{},...m?{borrowed:!0}:{}}]}}if(c&&(i.has("page:read_page")||i.has("read_page"))&&C(e)){const h=i.has("page:read_page"),p=me.test(e)&&C(n)?String(n).trim():"";return[{kind:"page",tool:h?"page":"read_page",input:h?{action:"read_page",args:{}}:{},label:"This page",...p?{ask:p}:{}}]}const S=i.has("find:weather"),V=i.has("weather");if(S||V){e=be(e)||e;const h=$(e)?"":X(e,t),p=$(e)||(h?h!=="here"?h:"":F(e,t)),m=p||(T(e)||h?"here":"");if(m&&(a.push({kind:"weather",tool:S?"find":"weather",input:S?{action:"weather",args:{location:m}}:{location:m},label:p?`Weather — ${p}`:"Weather — near you"}),p&&le.test(String(e||""))&&(i.has("find:web_search")||i.has("web_search")))){const _=`${p} 10 day weather forecast`,j=i.has("find:web_search");a.push({kind:"web",tool:j?"find":"web_search",input:j?{action:"web_search",args:{query:_}}:{query:_},label:`Web — ${p} extended forecast`,subject:_,weather:!0})}}const b=i.has("find:web_search");if(!a.length&&(b||i.has("web_search"))){const h=v(e)||B(e,t);if(h){const p=`${h} stock price today`;a.push({kind:"stock",tool:b?"find":"web_search",input:b?{action:"web_search",args:{query:p}}:{query:p},label:`Stock — ${h}`})}}if(!a.length&&(b||i.has("web_search"))){const h=Ke(e);if(h){const p=h.subject?`${h.subject} news today`:"top news today";a.push({kind:"news",tool:b?"find":"web_search",input:b?{action:"web_search",args:{query:p}}:{query:p},label:h.subject?`News — ${h.subject}`:"News — today",subject:h.subject})}}if(l&&!a.length&&(b||i.has("web_search"))){const h=O(e,{previous:t,now:u});if(h){const p=b?"find":"web_search";a.push({kind:"research",tool:p,input:p==="find"?{action:"web_search",args:{query:h.queries[0]}}:{query:h.queries[0]},label:`Research — ${h.subject}`,subject:h.subject,research:h})}}return r&&!a.length&&a.push(...Q(e,t,i)),a}function Q(e,t,n){const s=J(String(e||""),t);if(!s)return[];const{subject:o}=s,r=s.corrected?`The user corrected the name: it is "${o}"${s.replaced?`, not "${s.replaced}"`:""} — use this spelling; earlier answers in this chat were about the wrong name.`:"",l=a=>n.has(`find:${a}`)?{tool:"find",input:d=>({action:a,args:d})}:n.has(a)?{tool:a,input:d=>d}:null,c=[],u=l("history_search"),i=l("web_search");return u&&!s.web&&c.push({kind:"lookup",tool:u.tool,input:u.input({query:o}),label:`Library — ${o}`,subject:o,note:r}),i&&(s.web||K(o))&&c.push({kind:"lookup",tool:i.tool,input:i.input({query:o}),label:`Web — ${o}`,subject:o,note:r,fallback:c.length>0}),c}function at(e=[]){const t=Array.isArray(e)?e:[];for(let n=t.length-1;n>=0;n--)if(t[n]?.role==="user")return(t[n].attachments||[]).some(s=>s?.kind==="prefetch"&&String(s.text||"").trim());return!1}function it(e){const t=typeof e=="string"?e:e&&typeof e.text=="string"?e.text:JSON.stringify(e??""),n=e&&typeof e=="object"&&typeof e.note=="string"?e.note:"";return{text:t,note:n}}function Qe(e,t=""){const n=String(t||"").replace(/^ChatPanel\s*·\s*/u,"").trim();return n&&n!=="ChatPanel"?`${e?.label||""} · ${n}`:e?.label||""}function Ve(e,t,{now:n=Date.now(),note:s=""}={}){if(e.kind==="web"&&e.weather&&(t=te(t)||t),e.kind==="research"){const u=String(t||""),{question:i,domain:a,subject:d,slots:f}=e.research||{};return{id:`prefetch_research_${n}`,kind:"prefetch",prefetch:"research",subject:e.subject||d||"",research:{question:i,domain:a,subject:d,slots:f},title:e.label,text:u,chars:u.length}}const o=e.kind==="page"?"this is the page they mean.":e.kind==="web"?`these are web results for "${String(e.subject||"").slice(0,80)}" — answer from them; search again only with different words.`:e.kind==="stock"?`do not call ${e.tool} or any search tool again for the same company. Say the price and change it gives; if it gives none, say you could not find a current price — never estimate one.`:e.kind==="lookup"?`if it is about someone or something else, or found nothing, search again with DIFFERENT words (another spelling, the other source — library or web) — never the same query.${e.note?` ${e.note}`:""}`:`do not call ${e.tool} or any weather/search tool again for the same place.`,r=e.kind==="lookup"||e.kind==="web"?`SEARCHED for "${e.subject}"`:e.kind==="page"?"READ the page the user has open":"FETCHED",l=e.kind==="page"&&e.ask?`
|
|
1
|
+
import{researchAsk as O,runResearch as ee}from"./web-research.js";import{frontPagesAskedAbout as te}from"./site-pages.js";import{weatherFromSearch as ne}from"./weather-tool.js";import{PAGE_READ_ARGS as R}from"./page-context.js";const N=/(\bhow(?:'s| is| was|s) (?:the )?(?:weather|forecast|temperature)\b|\bwhat(?:'s| is|s) (?:the )?(?:weather|forecast|temperature)\b|\b(?:weather|forecast|temperature) (?:in|for|at|around|near)\b|\bis it (?:raining|snowing|hot|cold|warm|sunny|cloudy|windy)\b|\b(?:will|does) it (?:rain|snow)\b|\bhow (?:hot|cold|warm|humid|windy) is it\b|^\s*(?:weather|forecast)\b|\b(?:weather|forecast)\s*\??\s*$)/i,se=/\b(right now|now|today|tonight|this (?:morning|afternoon|evening|weekend|week)|tomorrow|currently|at the moment|these days|later)\b/gi,oe=new Set(["here","there","home","outside","my location","my area","my city","where i am","it","that"]),x=8,E="(?:page|tab|article|post|thread|discussion|story|site|website|doc|document|comments?|content|piece|blog(?: post)?|paper|video|readme|pdf)",re=new RegExp(`\\b(?:this|current|the current|the open|open|that)\\s+${E}\\b`,"i"),ae=new RegExp(`^\\s*(?:(?:can you |could you |please )?(?:summari[sz]e|tl;?\\s?dr|recap|give me the gist|what are the key (?:points|takeaways))(?:\\s+(?:it|this|that|here|(?:the|this)\\s+${E}(?:\\s+and\\s+(?:the\\s+)?${E})?))?|what(?:'s| is| are)? (?:people|they|folks|commenters) (?:saying|think(?:ing)?)(?: here| about (?:it|this))?)\\s*[?.!]*\\s*$`,"i"),ie=/\b(?:my|our|your|the|this|that|last|today'?s|yesterday'?s)\s+(?:meeting|chat|conversation|call|standup|notes?|email|inbox|calendar|day|week|transcript|thread with)\b|https?:\/\//i,ce=/^\s*(?:(?:please|pls|can you|could you|just|ok,?|no,?|then|so|now)\s+)*(?:use (?:the )?(?:web|internet)(?: search)?|use web ?search|(?:do|run|perform|make|start|try)(?: an?| the)? (?:(?:web|internet|online|google) ?)?search|search for (?:it|that|this)|search (?:the )?(?:web|internet|online)|web ?search(?: it)?|google(?: it| that)?|look (?:it |that )?up(?: online| on the web)?|check (?:the web|online)|try (?:the )?(?:web|internet|a web search|web search)|search (?:it|that|again|online))\b(?:\s+(?:for|about)\s+(.+?))?(?:,?\s+(?:please|pls|thanks|instead|now|then))*\s*[?.!]*\s*$/i;function he(e){const t=ce.exec(String(e||""));if(!t)return null;const n=String(t[1]||"").trim();return n?{query:n}:{}}const le=/\b(?:weather|forecast|temperature|rain|snow)\b/i,ue=/\b(?:rest of (?:the|this) (?:week|weekend|month)|(?:this|next|coming) (?:week|weekend)|(?:the|this) weekend|week ahead|the week|next (?:few|several|couple of) days|coming days|(?:5|7|10|14)[- ]?days?|extended|long[- ]range|two[- ]weeks?)\b/i,pe=/\b(?:i|we) (?:asked|said|wrote|told|searched|talked|discussed|mentioned|looked up|checked)\b|\b(?:did|have|had) (?:i|we)\b|\bhow (?:many|often) (?:times )?(?:i|we|did|have)\b|\bhow many times\b|\bmy (?:chats?|notes?|history|meetings?|conversations?|questions?|searches)\b|\blast time (?:i|we)\b/i,fe=/\b(?:find out more|find (?:out )?more|more (?:info|information|details)|look into (?:it|that|this)|dig (?:deeper|into (?:it|that))|get more details?|find (?:it|that) out|check (?:on )?(?:it|that) (?:again|online)|search (?:for )?more|look (?:it|that) up|find (?:the )?(?:rest|full|whole)(?: of it| forecast)?)\b/i,de=/^\s*(?:yes|yeah|yep|yup|sure|ok(?:ay)?|k|please(?: do)?|go ahead|go for it|do it|yes please|sure thing|absolutely|of course|ok look|look|search|please search|search it)(?:[\s,.!]+(?:please|thanks|thank you|go ahead|do it|look|search|yes))*[\s.!]*$/i,we=/\b(?:search the web|web search|search online|search for|look (?:it|that|this) up|look up|check online|find (?:it|that|out|more))\b/i,ge=/(?:web search for|search the web for|search (?:online )?for|look up|look for)\s+(?:the\s+)?(.{3,160}?)(?:\s*[?.!]|$)/i;function be(e){const t=String(e||"").split(/\n+/).map(s=>s.trim()).filter(Boolean).slice(-3).join(" ");if(we.test(t)&&/\?/.test(t)){const s=(ge.exec(t)?.[1]||"").replace(/\s+for me$/i,"").trim();if(s)return s}const n=/\b(?:searching(?: the web| online)? for|looking up|checking(?: the web| online)? for)\s+(?:the\s+)?(.{3,160}?)(?:\.\.\.|…|[.!?]|$)/i.exec(t);return n?n[1].trim():""}const A=/^\s*(?:(?:no|nope|actually|but|well|sorry)\b[,.!]?\s*)?(?:i|we) (?:asked|said|meant|wanted)\b/i,T=/\b(?:did|when|how (?:many|often)|earlier|before|yesterday|last (?:time|week|month)|ago|previously|other day)\b/i;function ke(e){const t=String(e||"");if(!A.test(t)||T.test(t))return"";const n=t.replace(A,"").replace(/^\s*(?:for|about)\s+/i,"").replace(/[.;]\s+(?:and|also)\s+/gi," and ").replace(/,?\s+not\s+[^.?!]*/i,"").trim();return/^(?:the\s+)?(?:weather|forecast|temperature)\b/i.test(n)?`what is ${/^the\s/i.test(n)?"":"the "}${n}`:""}function me(e){const t=String(e||"");return A.test(t)&&!T.test(t)?!1:pe.test(t)}const ye=/^\s*(?:and|what about|how about|now|no,?|ok,?|same for)\b[^?.!]{0,30}[?.!]*\s*$/i;function C(e){const t=String(e||"").trim();return!t||t.length>300||ie.test(t)?null:re.test(t)||ae.test(t)?{}:null}function d(e){return String(e||"").replace(se," ").replace(/[?!.,;:]+$/g,"").replace(/^\s*(the|in|at|for|around|near|of)\s+/i,"").replace(/\s+/g," ").trim()}const P=/\b(how|what|what's|whats|is|are|was|will|do|does|can|should|why|when|the|a|an|tell|me|there|here|it|like|about)\b/i;function y(e){const t=e.toLowerCase();return t.length>=2&&t.length<=60&&!oe.has(t)&&!P.test(t)&&!/^(weather|forecast|temperature)$/.test(t)&&/^[\p{L}]/u.test(t)&&t.split(/\s+/).length<=5}function W(e){const t=String(e||"").trim();return!N.test(t)||$(t)||/\b(?:love|like|hate|enjoy|miss|prefer)\s+(?:this|the|that|such|today's)?\s*(?:weather|forecast)\b/i.test(t)||/\b(?:api|app|apps|service|widget|feature|code|bug|model|tool|component|test|tests|data|endpoint|sdk|library|module|page|screen)\b/i.test(t)?!1:t.split(/\s+/).length<=12}const $e=/\s+(?:for|over|during|through|in|this|next|and)?\s*(?:the\s+)?(?:rest of (?:the|this) (?:week|weekend|day|month)|next (?:few|several|couple of|\d+) days|(?:this|next|coming) (?:week|weekend|month|few days)|the (?:weekend|week(?: ahead)?|coming days)|week ahead|\d+[- ]days?(?: forecast)?)\b/gi;function $(e){const t=String(e||"").trim();if(!N.test(t))return"";const n=t.replace($e,"").trim();let s=/\b(?:in|at|for|around|near)\s+([^?!.;]+?)(?:\s+(?:right now|now|today|tonight|tomorrow|currently|this \w+))*\s*[?!.]*$/i.exec(n);if(s){const o=d(s[1].split(/\s+(?:and|&|vs\.?|versus|compared (?:to|with)|then|,)\s+/i)[0]);if(y(o))return o;if(y(d(s[1])))return d(s[1])}return s=/^(?:what(?:'s| is) the\s+)?([\p{L}][\p{L}\s,.'-]{1,60}?)\s+(?:weather|forecast|temperature)\b/iu.exec(n),s&&y(d(s[1]))&&!L.test(d(s[1]))||(s=/\b(?:weather|forecast|temperature)\s*[:\-]?\s+([\p{L}][\p{L}\s,.'-]{1,60}?)\s*[?!.]*$/iu.exec(n),s&&y(d(s[1])))?d(s[1]):""}const L=/\b(summari[sz]e|explain|try|again|retry|do|make|write|show|tell|open|read|find|search|help|stop|continue|go|list|give|send|run|check|fix|get|fetch|pull|grab|look ?up|display|compare|bring|thanks|thank|yes|no|please|this|that|my|page|note|file|meeting|chat|sounds?|good|great|nice|cool|fine|perfect|awesome|sure|nothing|else|ok|okay|yeah|yep|nope|bye|hello|hi|hey|time|traffic|news|story|joke|stock|price|you|yourself|him|her|them|us)\b/i,Se=/^(?:(?:okay|ok|alright|all right|great|cool|thanks|thank you|fine|good|and|also|then|so|now|actually|well|um+|uh+|hmm+|oh|no|wait)(?:[\s,.!—-]+|$))+/i,_e=/^(?:(?:i(?: want| wanted| would like|'d like) to know|i'm wondering|i wonder|(?:can|could) you (?:tell|check) (?:me)?|tell me)\s+)/i,D=/^(?:(?:how|what) about|(?:how|what)(?:'s| is|s) it(?: like)?(?: in| at| for| around| near)?|(?:in|at|for|around|near))\b[\s,]*/i;function F(e,t){if(!t||t.kind!=="weather")return"";const n=String(e||"").trim().replace(/[?!.]+$/,"").trim(),s=n.replace(Se,"").trim().replace(_e,"").trim();if(!s||s.split(/\s+/).length>x)return"";const o=D.test(s)||s!==n&&/^(?:and|also)\b/i.test(n),r=d(s.replace(D,"").replace(/^(?:like\s+)?(?:in|at|for|around|near)\s+/i,""));return!r||/\d/.test(r)||!o&&r.split(/\s+/).length>2||!y(r)||L.test(r)?"":r}const k="([\\p{L}$][\\p{L}\\p{N}.&'-]*(?:\\s+[\\p{L}][\\p{L}\\p{N}.&'-]*){0,3})",Ee=[new RegExp(`\\b(?:share price|stock price|stock quote|ticker)\\s+(?:of|for)\\s+${k}`,"iu"),{question:!0,re:new RegExp(`\\b(?:stock|stocks|shares?)\\s+(?:of|for|in)\\s+${k}`,"iu")},new RegExp(`\\b${k}(?:'s)?\\s+(?:stock|shares)\\s+(?:price|doing|trading|today|now|performance|performing|up|down|quote)\\b`,"iu"),new RegExp(`\\b${k}(?:'s)?\\s+(?:share price|stock price|stock quote)\\b`,"iu"),new RegExp(`^\\s*${k}(?:'s)?\\s+(?:stock|shares)\\s*\\??\\s*$`,"iu"),new RegExp(`\\b(?:how|where)(?:'s| is| are)\\s+${k}\\s+(?:stock\\s+|shares\\s+)?trading\\b`,"iu"),new RegExp(`\\bwhat(?:'s| is| are)\\s+${k}\\s+trading at\\b`,"iu"),/\$([A-Z]{1,5})\b/u],Ae=/^(?:the|a|an|my|our|your|this|that|it|its|their|market|stock market|markets|price|prices|today|now|company|companies|how|what|is|are|doing|of|for|in|weather|forecast|news|time|date|temperature|rain|you|me|us|them|those|these)$/i,Le=/^(?:how|what|what's|whats|where|is|are|was|the|a|an|can|could|you|tell|me|about|of|for|in|and|also|so|now|then|please|check|show|give|get)$/i,je=/\s+(?:stock|stocks|shares?|price|prices|doing|trading|today|now|right now|currently|at the moment|this (?:morning|afternoon|week)|lately|so far)\b.*$/i;function q(e){const t=e.toLowerCase();return t.length>=1&&t.length<=40&&!Ae.test(t)&&!P.test(t)&&/^[\p{L}]/u.test(t)&&t.split(/\s+/).length<=4}function Oe(e){const t=e.split(/\s+/).filter(Boolean);for(;t.length>1&&Le.test(t[0]);)t.shift();return t.join(" ")}function v(e){return String(e||"").replace(/[?!.,;:]+$/g,"").replace(je,"").replace(/(?:\s+(?:at|on|up|down|for me|please))+$/i,"").replace(/^\s*(?:the|shares? of|stock of)\s+/i,"").replace(/'s$/i,"").replace(/\s+(?:corp(?:oration)?|inc|co|company|ltd)\.?$/i,t=>t).replace(/\s+/g," ").trim()}function B(e){const t=String(e||"").trim(),n=/\?\s*$/.test(t)||/^\s*(?:(?:hey|hi|ok|okay|so|and|now)[\s,]+)*(?:how|what|where|is|are|can|could|would|will|tell|check|show|give|get|find|look up|please)\b/i.test(t);for(const s of Ee){const o=s instanceof RegExp?s:s.re;if(s.question&&!n)continue;const r=o.exec(t);if(!r)continue;const l=Oe(v(r[1]));if(q(l))return l}return""}function M(e,t){if(!t||t.kind!=="stock")return"";let n=String(e||"").trim().replace(/[?!.]+$/,"").trim();if(!n||n.split(/\s+/).length>x)return"";n=n.replace(/^(?:(?:okay|ok|fine|good|great|thanks|thank you|cool|alright|all right|that'?s (?:fine|good|great|ok|okay))[\s,.!—-]*)+/i,"").trim();const s=/^(?:(?:and|also|then|so|now)[\s,]+)*(?:how about|what about)\b/i.test(n)||/^(?:and|also)[\s,]+/i.test(n);n=n.replace(/^(?:(?:and|also|then|so|now)[\s,]+)*(?:(?:how|what) about\b)?[\s,]*/i,"").trim();const o=v(n);return!o||!s&&(o.split(/\s+/).length>2||!/[?]\s*$/.test(String(e))&&o.split(/\s+/).length>1)||!q(o)||L.test(o)?"":o}const U=new RegExp("(?<![\\p{L}\\p{N}'])\\p{L}(?:[ \\t.,\\-–]{1,3}\\p{L}(?![\\p{L}\\p{N}'])){2,}","gu");function I(e){return String(e||"").replace(U,t=>t.replace(/[^\p{L}]/gu,"").toLowerCase())}function Re(e){return[...String(e||"").matchAll(U)].map(t=>t[0].replace(/[^\p{L}]/gu,"").toLowerCase())}const Ne=/\b(?:tell me (?:more |everything |all |something )?about|what do you know about|do you know (?:anything )?about|who(?:'s| is| was| are)|look up|lookup|search (?:the web |online |the internet |google )?for|search up|google|find (?:out )?(?:info(?:rmation)?|details|more|anything|something|everything) (?:on|about)|(?:info|information|background|details) (?:on|about)|research)\s+(.+)$/i,xe=/[.?!;:,()](?=\s|$)|\s(?:uh|um|umm|er|erm|hmm|like|actually|i mean|sorry|the (?:first |last |sur|family )?name|his|her|their|its|it's|it is|spelled|spelt|and (?:tell|give|find|show|let|search|look)|then|please|for me|on the web|online|on google|from the web|if you can|thanks|thank you)\b/i,Te=/^(?:it|this|that|these|those|him|her|them|me|you|yourself|us|he|she|they|we|i|my|our|your|his|their|here|there|on|in|at|to|for|with|from|going|coming|speaking|talking|calling|joining|what|how|why|when|where|which|the weather|weather)\b/i,Ce=/^(?:my|our|your|this|that|today'?s|yesterday'?s|last|next|latest|recent)\b/i,Pe=/^(?:the|a|an)\b/i,We=6;function G(e){const n=(String(e||"").split(xe)[0]||"").replace(/\s+/g," ").replace(/^["'“‘]+|["'”’]+$/g,"").trim(),s=n.split(" ").filter(Boolean);return!s.length||s.length>We||!new RegExp("\\p{L}","u").test(n)||Te.test(n)?"":n}function De(e){const t=Ne.exec(I(e));return t?G(t[1]):""}const Fe=[[/\b(?:last|sur|family|second) ?name\b|\bsurname\b/i,e=>e.length-1],[/\bfirst name\b|\bgiven name\b/i,()=>0]],qe=/\b(?:it(?:'s| is)|spelled|spelt|should be|is actually|actually|but|name is)\s+["'“‘]?([\p{L}][\p{L}'-]{1,40})["'”’]?\s*[.!?]*\s*$/iu,ve=/\b(?:no|nope|not|wrong|incorrect|misspel\w*|spell\w*|typo|name|actually|i meant|i mean)\b/i;function Be(e,t){const n=e.toLowerCase(),s=t.toLowerCase(),o=Array.from({length:s.length+1},(r,l)=>l);for(let r=1;r<=n.length;r++){let l=o[0];o[0]=r;for(let c=1;c<=s.length;c++){const u=o[c];o[c]=Math.min(o[c]+1,o[c-1]+1,l+(n[r-1]===s[c-1]?0:1)),l=u}}return o[s.length]}function Me(e,t){return new RegExp("^\\p{Lu}","u").test(t)?e.charAt(0).toUpperCase()+e.slice(1):e}function H(e,t){const n=String(t||"").trim();if(!n)return null;const s=String(e||""),o=Re(s),r=I(s);let l=o.at(-1)||"";if(!l&&ve.test(r)&&(l=qe.exec(r)?.[1]||""),!l||l.length<2)return null;const c=n.split(/\s+/);let u=-1;for(const[a,f]of Fe)if(a.test(r)){u=f(c);break}if(u<0){let a=1/0;c.forEach((f,w)=>{const g=Be(f,l)/Math.max(f.length,l.length);g<a&&(a=g,u=w)}),a>.6&&(u=c.length===1?0:-1)}if(u<0)return null;const i=c[u];return i.toLowerCase()===l.toLowerCase()?{subject:n,replaced:""}:(c[u]=Me(l,c.find(a=>new RegExp("^\\p{Lu}","u").test(a))||i),{subject:c.join(" "),replaced:i})}const Ue=/\b(?:search|look|google|check|find|try)\b[^.?!]{0,30}\b(?:web|online|internet|google|up|again|it|him|her|them)\b|\blook(?:ing)? (?:it|that|him|her|them)? ?up\b/i,J=/\b(?:web|online|internet|google)\b/i;function Ie(e,t){if(!t||t.kind!=="lookup"||!t.subject)return null;const n=H(e,t.subject),s=/\b(?:not|wrong|isn'?t|incorrect|nope)\b/i.test(e);return!n&&!s&&!Ue.test(e)?null:{subject:n?.subject||t.subject,replaced:n?.replaced||"",corrected:!!n||s,web:J.test(e)}}function K(e,t){const n=De(e);if(n){const o=H(e.slice(e.toLowerCase().indexOf(n.toLowerCase())+n.length),n);return{kind:"lookup",subject:o?.subject||n,replaced:o?.replaced||"",corrected:!!o?.replaced,web:J.test(e)}}const s=Ie(e,t);return s?{kind:"lookup",...s}:null}function Y(e){return Ce.test(e)||/@|\d{5,}/.test(e)||!new RegExp("\\p{L}{2,}","u").test(e)?!1:!Pe.test(e)||new RegExp("\\s\\p{Lu}","u").test(e)}const Ge=/\b(?:news|headlines|stories)\s+(?:on|about|from|in|for|regarding|around)\s+(.+)$/i,He=/\bwhat(?:'s| is| are)\s+(?:new|happening|going on|the latest|the news)\s+(?:with|in|on|at|around|from)\s+(.+)$/i,Je=/^(?:(?:can|could) you (?:tell|give) me |tell me |give me |show me )?(?:the |any |some )?(?:latest |recent |top |today'?s |breaking )?(.{2,60}?)\s+news(?:\s+(?:today|this (?:morning|week|evening)|right now|lately|these days))?\s*[?.!]*$/i,Ke=/^(?:(?:can|could) you (?:tell|give) me |tell me |give me |show me |what(?:'s| is| are) )?(?:the |any )?(?:latest |top |today'?s |breaking )?(?:news|headlines)(?:\s+(?:today|this (?:morning|week|evening)|right now))?\s*[?.!]*$/i,z=/\s+(?:today|tonight|this (?:morning|week|evening|year)|right now|lately|these days|recently|now)$/i;function Ye(e){const t=String(e||"").trim();if(!t||te(t).length)return null;if(Ke.test(t))return{subject:""};const n=Ge.exec(t)||Je.exec(t),s=n?null:He.exec(t),o=n||s;if(!o)return null;const r=G(o[1].replace(/[?.!]+$/,"").replace(z,"")).replace(z,"");return s&&r.split(/\s+/).length>4||!r||!Y(r)||/^(?:the )?(?:weather|stock|stocks|market)$/i.test(r)?null:{subject:r}}function rt(e){return/^\s*No (?:history matches|web results)\b/.test(String(e||""))}const X=Object.freeze({page:15e3,web:12e3,lookup:12e3}),ze=6e3;function at(e){return Object.hasOwn(X,e?.kind)?X[e.kind]:ze}const Xe=/^\s*(?:(?:and|also|ok(?:ay)?|so|then)[,\s]+)?(?:(?:what|how) about|how(?:'s|’s| is| will| does)?(?: it| the weather| things)?(?: be| look(?:ing)?)?|is it|and|for)?\s*(?:(?:right )?now|currently|today|tonight|tomorrow(?: morning| afternoon| evening| night)?|(?:a |the )?day after tomorrow|later(?: today| tonight)?|(?:this|next|the) (?:morning|afternoon|evening|night|weekend|week)|(?:the )?rest of (?:the|this) week|(?:on |this |next )?(?:mon|tues|wednes|thurs|fri|satur|sun)day|outside|out there)\s*[?!.]*\s*$/i;function Q(e,t){return!t||t.kind!=="weather"?"":Xe.test(String(e||""))?String(t.subject||"here"):""}function Qe(e,t){const n=$(e)||Q(e,t)||F(e,t);if(n)return{kind:"weather",subject:n};if(W(e))return{kind:"weather",subject:"here"};const s=B(e)||M(e,t);if(s)return{kind:"stock",subject:s};const o=K(String(e||""),t);if(o)return o;const r=O(e,{previous:t});return r?{kind:"research",subject:r.subject,research:r}:null}function it(e){const t=(Array.isArray(e)?e:[]).filter(o=>o&&!o.pending&&(o.role==="user"||o.role==="assistant")),n=[];for(let o=0;o<t.length;o++)t[o].role==="user"&&n.push(o);if(n.length<2)return null;let s=null;for(let o=0;o<n.length-1;o++){const r=t[n[o]],l=t[n[o]+1]?.role==="assistant"?t[n[o]+1]:null,c=(r.attachments||[]).find(a=>a?.kind==="prefetch"),u=typeof r.content=="string"?r.content:"";s=Qe(u,s)||(c?{kind:c.prefetch,...c.research?{research:c.research}:{}}:null)||((l?.steps||[]).some(a=>a?.input?.action==="weather"||a?.tool==="weather")?{kind:"weather"}:null)}return s}function ct({text:e="",previous:t=null,previousText:n="",previousAnswer:s="",reach:o=new Set,lookup:r=!1,research:l=!1,page:c=!1,now:u=Date.now()}={}){const i=o instanceof Set?o:new Set(Array.isArray(o)?o:[]),a=[];if(me(e))return r?V(e,t,i):[];const f=de.test(String(e||""))?be(s):"",w=String(e||"").trim().split(/\s+/).length,g=he(e)||(f?{query:f}:null)||(fe.test(String(e||""))&&w<=14?{}:null);if(g&&(i.has("find:web_search")||i.has("web_search"))){const h=g.query||String(n||"").trim();if(h){const p=i.has("find:web_search"),m=!g.query;return[{kind:"web",tool:p?"find":"web_search",input:p?{action:"web_search",args:{query:h}}:{query:h},label:`Web — ${h.slice(0,60)}`,subject:h,...le.test(h)?{weather:!0}:{},...m?{borrowed:!0}:{}}]}}if(c&&(i.has("page:read_page")||i.has("read_page"))&&C(e)){const h=i.has("page:read_page"),p=ye.test(e)&&C(n)?String(n).trim():"";return[{kind:"page",tool:h?"page":"read_page",input:h?{action:"read_page",args:{...R}}:{...R},label:"This page",...p?{ask:p}:{}}]}const S=i.has("find:weather"),Z=i.has("weather");if(S||Z){e=ke(e)||e;const h=$(e)?"":Q(e,t),p=$(e)||(h?h!=="here"?h:"":F(e,t)),m=p||(W(e)||h?"here":"");if(m&&(a.push({kind:"weather",tool:S?"find":"weather",input:S?{action:"weather",args:{location:m}}:{location:m},label:p?`Weather — ${p}`:"Weather — near you"}),p&&ue.test(String(e||""))&&(i.has("find:web_search")||i.has("web_search")))){const _=`${p} 10 day weather forecast`,j=i.has("find:web_search");a.push({kind:"web",tool:j?"find":"web_search",input:j?{action:"web_search",args:{query:_}}:{query:_},label:`Web — ${p} extended forecast`,subject:_,weather:!0})}}const b=i.has("find:web_search");if(!a.length&&(b||i.has("web_search"))){const h=B(e)||M(e,t);if(h){const p=`${h} stock price today`;a.push({kind:"stock",tool:b?"find":"web_search",input:b?{action:"web_search",args:{query:p}}:{query:p},label:`Stock — ${h}`})}}if(!a.length&&(b||i.has("web_search"))){const h=Ye(e);if(h){const p=h.subject?`${h.subject} news today`:"top news today";a.push({kind:"news",tool:b?"find":"web_search",input:b?{action:"web_search",args:{query:p}}:{query:p},label:h.subject?`News — ${h.subject}`:"News — today",subject:h.subject})}}if(l&&!a.length&&(b||i.has("web_search"))){const h=O(e,{previous:t,now:u});if(h){const p=b?"find":"web_search";a.push({kind:"research",tool:p,input:p==="find"?{action:"web_search",args:{query:h.queries[0]}}:{query:h.queries[0]},label:`Research — ${h.subject}`,subject:h.subject,research:h})}}return r&&!a.length&&a.push(...V(e,t,i)),a}function V(e,t,n){const s=K(String(e||""),t);if(!s)return[];const{subject:o}=s,r=s.corrected?`The user corrected the name: it is "${o}"${s.replaced?`, not "${s.replaced}"`:""} — use this spelling; earlier answers in this chat were about the wrong name.`:"",l=a=>n.has(`find:${a}`)?{tool:"find",input:f=>({action:a,args:f})}:n.has(a)?{tool:a,input:f=>f}:null,c=[],u=l("history_search"),i=l("web_search");return u&&!s.web&&c.push({kind:"lookup",tool:u.tool,input:u.input({query:o}),label:`Library — ${o}`,subject:o,note:r}),i&&(s.web||Y(o))&&c.push({kind:"lookup",tool:i.tool,input:i.input({query:o}),label:`Web — ${o}`,subject:o,note:r,fallback:c.length>0}),c}function ht(e=[]){const t=Array.isArray(e)?e:[];for(let n=t.length-1;n>=0;n--)if(t[n]?.role==="user")return(t[n].attachments||[]).some(s=>s?.kind==="prefetch"&&String(s.text||"").trim());return!1}function lt(e){const t=typeof e=="string"?e:e&&typeof e.text=="string"?e.text:JSON.stringify(e??""),n=e&&typeof e=="object"&&typeof e.note=="string"?e.note:"";return{text:t,note:n}}function Ve(e,t=""){const n=String(t||"").replace(/^ChatPanel\s*·\s*/u,"").trim();return n&&n!=="ChatPanel"?`${e?.label||""} · ${n}`:e?.label||""}function Ze(e){const t=String(e||"");if(!t.startsWith("{"))return t;try{const n=JSON.parse(t);return typeof n?.text!="string"?t:[typeof n.note=="string"?n.note:"",n.text,n.truncated?"(The page continues past what was read.)":""].filter(Boolean).join(`
|
|
2
|
+
|
|
3
|
+
`)}catch{return t}}function et(e,t,{now:n=Date.now(),note:s=""}={}){if(e.kind==="web"&&e.weather&&(t=ne(t)||t),e.kind==="page"&&(t=Ze(t)),e.kind==="research"){const u=String(t||""),{question:i,domain:a,subject:f,slots:w}=e.research||{};return{id:`prefetch_research_${n}`,kind:"prefetch",prefetch:"research",subject:e.subject||f||"",research:{question:i,domain:a,subject:f,slots:w},title:e.label,text:u,chars:u.length}}const o=e.kind==="page"?"this is the page they mean.":e.kind==="web"?`these are web results for "${String(e.subject||"").slice(0,80)}" — answer from them; search again only with different words.`:e.kind==="stock"?`do not call ${e.tool} or any search tool again for the same company. Say the price and change it gives; if it gives none, say you could not find a current price — never estimate one.`:e.kind==="lookup"?`if it is about someone or something else, or found nothing, search again with DIFFERENT words (another spelling, the other source — library or web) — never the same query.${e.note?` ${e.note}`:""}`:`do not call ${e.tool} or any weather/search tool again for the same place.`,r=e.kind==="lookup"||e.kind==="web"?`SEARCHED for "${e.subject}"`:e.kind==="page"?"READ the page the user has open":"FETCHED",l=e.kind==="page"&&e.ask?`
|
|
2
4
|
|
|
3
5
|
The question about this page: ${e.ask.slice(0,200)}`:"",c=`(ALREADY ${r} for the question below, with ${e.tool}. Answer from this; ${o})
|
|
4
6
|
|
|
5
|
-
${String(t||"")}${l}`;return{id:`prefetch_${e.kind}${e.kind==="lookup"?`_${e.input?.action||e.tool}`:""}_${n}`,kind:"prefetch",prefetch:e.kind,...e.subject?{subject:e.subject}:{},title:
|
|
7
|
+
${String(t||"")}${l}`;return{id:`prefetch_${e.kind}${e.kind==="lookup"?`_${e.input?.action||e.tool}`:""}_${n}`,kind:"prefetch",prefetch:e.kind,...e.subject?{subject:e.subject}:{},title:Ve(e,s),text:c,chars:c.length}}async function ut(e,{execute:t,until:n=null,now:s=()=>Date.now(),onActivity:o=()=>{},read:r=null,rerank:l=null}={}){const c=s(),u=i=>{try{o({type:"tool",name:"research",prefetched:!0,...i})}catch{}};u({phase:"start",input:e.input,summary:e.label});try{const{text:i,result:a}=await ee(e,{execute:t,until:n,now:s,read:r,rerank:l,onProgress:g=>u({phase:"progress",summary:`${e.label} — ${g.label}`})});if(!i)return u({phase:"done",status:"skipped",summary:e.label,ms:s()-c}),{attachment:null,text:"",result:a,note:"",status:"skipped"};const f=a.stats,w=`${f.searches} search${f.searches===1?"":"es"} · ${f.sites} site${f.sites===1?"":"s"} · ${(f.ms/1e3).toFixed(1)} s`;return u({phase:"done",status:"ok",summary:`${e.label} — ${w}`,ms:s()-c}),{attachment:et(e,i,{now:s()}),text:i,result:a,note:w,status:"ok"}}catch(i){const a=`error: ${String(i?.message||i).slice(0,80)}`;return u({phase:"done",status:a,summary:e.label,ms:s()-c}),{attachment:null,text:"",result:null,note:"",status:a}}}export{me as aboutOwnPast,ht as answeredByPrefetch,H as correctedSubject,I as joinSpelled,Ie as lookupFollowup,Ve as lookupLabel,lt as lookupResult,De as lookupSubject,Ye as newsAsk,be as offeredSearch,C as pageAsk,et as prefetchAttachment,at as prefetchBudgetMs,rt as prefetchMissed,ct as prefetchPlan,it as previousAsk,ke as restatedWeather,ut as runResearchItem,M as stockFollowupSubject,B as stockSubject,F as weatherFollowupPlace,Q as weatherFollowupWhen,W as weatherHere,$ as weatherPlace,he as webRedoAsk};
|
package/retrieval-plan.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{needsWhole as E}from"./digest.js";import{lookupSubject as
|
|
2
|
-
${String(o.text||"")}`})):
|
|
1
|
+
import{needsWhole as E,noteShape as C}from"./digest.js";import{lookupSubject as P,prefetchPlan as q,answeredByPrefetch as _}from"./prefetch.js";import{partChars as D,STITCH_LIMITS as W}from"./stitch.js";import{isSmallWindow as g,FIT_HEADROOM as F,SMALL_WINDOW_ROUNDS as y}from"./context-window.js";import{isPleasantry as L}from"./tool-need.js";const j=4,H={device:3,api:2,agent:8};function ee({question:r="",sources:t=[],fixedTokens:n=0,target:o={}}={}){const a=o.kind||"api",s=Number(o.window)||0,i=g(s),d=E(r),k=Math.max(1,Number(o.concurrency)||(a==="device"?1:4)),x=Number(o.secondsPerCall)||H[a]||2,h=(Array.isArray(t)?t:[]).filter(Boolean).map(e=>({...e,chars:Math.max(0,Number(e.chars)||0)})),m=s?Math.floor(s*F)-(Number(o.reserve)||1024)-(Number(n)||0):1/0,b=Number.isFinite(m)?Math.max(0,m)*j:1/0,f=new Map,c=new Set;let u=b;for(let e=!0;e;){e=!1;const l=h.filter(w=>!c.has(w.id)),p=l.length?u/l.length:0;for(const w of l)w.chars<=p&&(c.add(w.id),u-=w.chars,e=!0)}const T=h.filter(e=>!c.has(e.id)).reduce((e,l)=>e+l.chars,0);for(const e of h)f.set(e.id,c.has(e.id)?e.chars:Math.floor(u*e.chars/(T||1)));const S=D({windowTokens:s,reserveTokens:C(r).tokens})||0,M=h.map(e=>{const l={id:e.id,kind:e.kind,title:e.title||"",chars:e.chars,share:f.get(e.id)};if(a==="agent")return{...l,how:"agent",calls:0,why:"an agent reads it itself — handed the material, not a digest"};if(c.has(e.id)||!Number.isFinite(b))return{...l,how:"whole",calls:0,why:"it fits"};if(!i)return{...l,how:"merge",calls:Math.ceil(e.chars/Math.max(1,l.share)),why:"a large window: what does not fit is merged by the model"};if(d&&S>0){const p=Math.min(W.parts,Math.ceil(e.chars/S)),w=Math.ceil(e.chars/S),R=Math.max(1,Math.ceil(p/4));return{...l,how:"digest",parts:p,calls:p+R,unread:Math.max(0,w-p),why:"the question needs all of it, and it does not fit: read in parts, the notes combined"}}return{...l,how:"cut",calls:0,why:d?"no room to read it in parts: the parts that bear on the question":"a focused question: the parts that bear on it, by relevance"}}),I=h.some(e=>e.prefetched),O=a==="agent"?{offer:!0,rounds:null,why:"an agent keeps its own tools"}:i&&I?{offer:!1,rounds:1,why:"a small window, and a prefetch already answered"}:i?{offer:!0,rounds:y,why:"a small window: one tool round, then the answer"}:{offer:!0,rounds:null,why:""},A=M.reduce((e,l)=>e+(l.calls||0),0),$=Math.round((Math.ceil(A/k)+1)*x);return{sources:M,tools:O,estimate:{calls:A+1,seconds:$},say:B(M,$)}}function B(r,t){const n=r.filter(i=>i.how==="digest");if(!n.length)return"";const o=n.length===1?`"${n[0].title||"what is attached"}"`:`${n.length} attachments`,a=n.reduce((i,d)=>i+d.parts,0),s=n.reduce((i,d)=>i+(d.unread||0),0);return`Reading all of ${o} in ${a} part${a===1?"":"s"} first, so the answer covers the whole of it${s?` (the last ${s} part${s===1?"":"s"} will not fit)`:""} — about ${t} s.`}const N=/\b(?:schedule|reschedule|remind(?:er)?|calendar|invite|e-?mail|inbox|send|reply|draft|create|add|save|write (?:a |an )?note|open|click|fill|book|order|cancel|delete|rename|move|upload|download|run|execute|deploy|commit|share|post)\b/i,U=/\b(?:find out|find more|more (?:info|information|details)|look into|latest|current(?:ly)?|today|tonight|tomorrow|right now|this (?:week|weekend|month|year)|price|prices|cost|stock|shares?|score|news|headlines?|weather|forecast|hours|near me|nearby|directions|traffic|flight|look (?:it |that )?up|search|google|website|link|url|https?:\/\/|who(?:'s| is| was| are)|where(?:'s| is| are)|when(?:'s| is| does| do))\b/i,K=/\b(?:my|mine|our|ours|we|us|did i|have i|i (?:said|asked|wrote|told|had|was)|remember|last time|earlier today|meetings?|notes?|transcripts?|conversations?|chats?)\b/i;function Y(r){const t=String(r||"").trim();return t?N.test(t)||U.test(t)||K.test(t)||!!P(t):!1}const v=new Set(["weather","stock","news","page","web","research"]);function te(r=[]){return(Array.isArray(r)?r:[]).some(t=>t?.kind==="prefetch"&&v.has(t.prefetch)&&String(t.text||"").trim())}function re(r=[]){return(Array.isArray(r)?r:[]).some(t=>t&&v.has(t.kind))}function z({window:r=0,question:t="",answered:n=!1,decided:o="",reference:a=!1}={}){return g(r)?a?{offer:!0,rounds:y,why:"a small window, and a document attached by reference that was not read ahead — the files tool stays"}:n?{offer:!1,rounds:1,why:"a small window, and a prefetch already answered"}:o==="none"?N.test(String(t||""))?{offer:!0,rounds:y,why:"a small window: nothing to look up, and something to do"}:{offer:!1,rounds:1,why:"a small window, and the decider found nothing to look up"}:o?{offer:!0,rounds:y,why:`a small window, the decider asked for ${o}, and the fetch found nothing`}:Y(t)?{offer:!0,rounds:y,why:"a small window: one tool round, then the answer"}:{offer:!1,rounds:1,why:"a small window, and a question that needs no tools"}:{offer:!0,rounds:null,why:""}}function ne({window:r=0,question:t="",answered:n=!1}={}){if(!g(r))return{history:"all",memories:"all",before:!1,why:""};const o=L(t);return{history:n?"none":"all",memories:o?"none":n?"pinned":"matched",before:!0,why:[n?"a small window a fetch answered: the evidence, the question and pinned memories":"",o?"a greeting: no memories":n?"":"a small window: only the memories that bear on it"].filter(Boolean).join("; ")}}const G="From the user's own history. It may have nothing to do with the question: use it only if it answers it, otherwise answer from your own knowledge.";function oe(r=[],t={}){const n=(Array.isArray(r)?r:[]).filter(o=>o&&typeof o=="object");return t?.before?n.map(o=>({...o,before:!0,text:`${G}
|
|
2
|
+
${String(o.text||"")}`})):n}function ae(r=[],t=""){const n=String(t||"").trim();if(!n)return r;const o=/^(?:here|near me|nearby|my (?:location|area|city))$/i;return(Array.isArray(r)?r:[]).map(a=>{const s=a?.input?.args||a?.input;if(!s)return a;if(a.kind==="weather"&&o.test(String(s.location||"").trim())){const i={...s,location:n};return{...a,input:a.input.args?{...a.input,args:i}:i,label:`Weather — ${n}`}}if(typeof s.query=="string"&&/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i.test(s.query)){const i=s.query.replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${n}`);return{...a,input:a.input.args?{...a.input,args:{...s,query:i}}:{...s,query:i},subject:i,label:String(a.label||"").replace(/\bnear (?:me|here)\b|\bnearby\b|\baround here\b/i,`near ${n}`)}}return a})}function se({question:r="",previousText:t="",previousAnswer:n="",previous:o=null,reach:a=new Set,window:s=0,personal:i=!1,lookup:d=null,now:k=Date.now()}={}){const x=g(s),h=q({text:r,previous:o,previousText:t,previousAnswer:n,reach:a,research:!0,page:!0,lookup:d??x,now:k}),m=h.some(u=>["weather","stock","news","page","web","research"].includes(u.kind)),b=!!i&&!m,f=[];h.length&&f.push(`fetch first: ${h.map(u=>u.label||u.kind).join(", ")}`),i&&m&&f.push("a world fact — the person's history is not searched for it");const c=z({window:s,question:r,answered:h.length>0});return c.why&&f.push(c.why),{prefetch:h,world:m,research:b,tools:c,why:f}}export{G as HISTORY_NOTE,_ as answeredByPrefetch,ne as contextPlan,oe as historyContext,ae as placeItems,ee as planRetrieval,se as planTurn,z as toolPlan,Y as toolsWanted,te as worldAnswered,re as worldPlanned};
|
package/rrf.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function l(
|
|
1
|
+
function l(c,{k:u=60,limit:h=0,weights:a=null}={}){const r=new Map;(c||[]).forEach((e,o)=>{if(!Array.isArray(e))return;const s=Array.isArray(a)&&Number.isFinite(a[o])?a[o]:1;e.forEach((t,i)=>{t!=null&&r.set(t,(r.get(t)||0)+s/(u+i))})});const n=[...r.entries()].map(([e,o])=>({id:e,score:o})).sort((e,o)=>o.score-e.score);return h>0?n.slice(0,h):n}const w=new Set("a an and are as at be been but by can could did do does for from had has have how i if in into is it its me my of on or our ought shall should so than that the their them then there these they this those to um was we were what when where which who whom why will with would you your about tell show give find get please could-you was-there did-we".split(/\s+/));function d(c,{extra:u=[],max:h=4}={}){const a=String(c||"").trim(),r=[],n=new Set,e=t=>{const i=String(t||"").trim().replace(/\s+/g," "),f=i.toLowerCase();i&&!n.has(f)&&(n.add(f),r.push(i))};e(a);for(const t of u)e(t);const s=(a.toLowerCase().match(/[a-z0-9][a-z0-9'’_+-]*/g)||[]).filter(t=>!w.has(t)&&t.length>2);return s.length>=2&&e(s.join(" ")),s.length>3&&e([...s].sort((t,i)=>i.length-t.length).slice(0,3).join(" ")),r.slice(0,Math.max(1,h))}async function p(c,u,{limit:h=10,k:a=60}={}){const r=[],n=new Map,e=new Map;for(const o of c||[]){let s=[];try{s=await u(o)||[]}catch{s=[]}r.push(s.map(t=>t.id));for(const t of s)(!n.has(t.id)||!n.get(t.id).snippet&&t.snippet)&&n.set(t.id,t),e.has(t.id)||e.set(t.id,[]),e.get(t.id).push(o)}return l(r,{k:a,limit:h}).map(({id:o,score:s})=>({...n.get(o),id:o,score:s,foundBy:e.get(o)||[]}))}export{l as fuseRRF,p as multiSearch,d as planQueries};
|
package/search-modes.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{fuseRRF as Y}from"./rrf.js";import{lexicalPlan as H}from"./recall.js";import{recall as Q}from"./memory.js";const T=Object.freeze(["memory","keyword","graph","hybrid"]),
|
|
2
|
-
`),y={};t.forEach((a,d)=>{y[`p${d+1}`]={type:"score",instructions:`How well does passage [${d+1}] answer the question? A passage that only repeats the question, or says it cannot tell, does NOT answer it.`,options:["no","partly","answers it"]}}),y.answer={type:"choice",instructions:'Which passage gives the answer itself (a name, a fact, a date)? "none" if none does.',options:[...t.map((a,d)=>String(d+1)),"none"]};let c=null;try{c=await n({state:h,questions:y})}catch{c=null}const m=c?.answers;if(!m)return{reranked:i,decision:{verdict:"unknown"}};const u=t.map((a,d)=>({...a,relevance:Number(m[`p${d+1}`]?.value??0),at:d})).sort((a,d)=>d.relevance-a.relevance||a.at-d.at).map(({at:a,...d})=>d),b=String(m.answer?.value??"none"),S=b==="none"?null:t[Number(b)-1];return{reranked:[...u,...i.slice(r)],decision:S?{verdict:"found",id:S.id,title:S.title,by:c.model||"model",calibrated:c.calibrated!==!1}:{verdict:"not-found",by:c.model||"model",calibrated:c.calibrated!==!1}}}async function
|
|
1
|
+
import{fuseRRF as Y}from"./rrf.js";import{lexicalPlan as H}from"./recall.js";import{recall as Q}from"./memory.js";import{pageAsk as W}from"./prefetch.js";const T=Object.freeze(["memory","keyword","graph","hybrid"]),X=new Set("i im ive id ill the a an this that these those what who whom whose which when where why how is are was were do does did can could will would should my your our their his her its we you he she they it me him them us yes no ok okay hi hello hey thanks please sure also and but or so if then monday tuesday wednesday thursday friday saturday sunday january february march april may june july august september october november december today tomorrow yesterday chap chapel chatpanel gemini nano claude codex speaker note notes chat chats meeting meetings summary topics action items met meet saw see called call asked ask told tell emailed email texted text messaged pinged ping spoke talked thanks thank dear cc per via with from here there now sorry great sure maybe perhaps still just only even also yet here's there's let please compare".split(/\s+/)),J=new Set("ceo cfo cto coo ai api usa us uk eu faq pdf ok".split(" ")),K=/(?<![\w'])((?:[A-Z][a-z][A-Za-z'-]+|[A-Z]{2,}[A-Za-z]*|[a-z][A-Z][A-Za-z]+)(?:\s+(?:[A-Z][A-Za-z'-]*|\d{1,4}[A-Za-z]{0,3})(?![\w'])){0,3})/g,U=/\b([A-Z][a-z][A-Za-z'-]+(?:\s+[A-Z][a-z][A-Za-z'-]+){0,2})\b/g;function M(o,{max:i=12,midSentence:n=!1,exclude:r=[],things:t=!1}={}){const h=new Map,y=new Set(r.map(u=>String(u).toLowerCase()).filter(Boolean)),c=new RegExp((t?K:U).source,"g"),m=String(o||"");for(const u of m.matchAll(c)){if(n&&/(^|[.!?:|\n"“]\s*)$/.test(m.slice(Math.max(0,u.index-3),u.index)))continue;const b=u[1].split(/\s+/).filter(d=>!X.has(d.toLowerCase().replace(/'s$/,"")));if(!b.length)continue;const S=b.join(" ").replace(/'s?$/,"");if(S.length<3||/^[\d\s]+$/.test(S)||t&&J.has(S.toLowerCase()))continue;const a=S.toLowerCase();if(![...y].some(d=>a===d||a.split(" ").some(E=>d.split(" ").includes(E)))&&(h.set(a,h.get(a)||{name:S,count:0}),h.get(a).count+=1,h.size>=i*2))break}return[...h.values()].sort((u,b)=>b.count-u.count).slice(0,i).map(u=>u.name)}function I(o,{plan:i=null}={}){const n=(i?.terms?.length?i.terms:H(o).terms).map(t=>String(t).toLowerCase().replace(/[^a-z0-9]/g,"")).filter(t=>t.length>=2),r=new Set(n);for(const t of n)t.length>=7&&r.add(t.slice(0,5));return[...r].slice(0,12)}const q=o=>o?.sinceAt||0;function B(o,i){const n=I(o).filter(t=>t.length>=4);if(n.length<2)return!1;const r=String(i||"").toLowerCase();return n.filter(t=>r.includes(t)).length/n.length>=.8}const V=500;function L(o){const i=(n,r)=>[...new Set((Array.isArray(n)?n:[]).map(r).filter(Boolean))].slice(-V);return{notNames:i(o?.notNames,n=>String(n||"").replace(/\s+/g," ").trim().toLowerCase().slice(0,80)),hidden:i(o?.hidden,n=>String(n||"").trim().slice(0,200))}}function ae(o,{op:i,value:n}){const r=L(o),t=String(n||"").trim();return t?i==="not-a-name"?L({...r,notNames:[...r.notNames,t]}):i==="undo-name"?{...r,notNames:r.notNames.filter(h=>h!==t.toLowerCase())}:i==="hide"?L({...r,hidden:[...r.hidden,t]}):i==="unhide"?{...r,hidden:r.hidden.filter(h=>h!==t)}:r:r}async function ee(o,i,{decide:n,k:r=6}={}){const t=i.slice(0,r);if(!n||!t.length)return{reranked:i,decision:{verdict:"unknown"}};const h=[`Question: ${String(o).slice(0,400)}`,"",...t.map((a,d)=>`[${d+1}] ${a.title}: ${String(a.snippet||"").replace(/\s+/g," ").slice(0,280)}`)].join(`
|
|
2
|
+
`),y={};t.forEach((a,d)=>{y[`p${d+1}`]={type:"score",instructions:`How well does passage [${d+1}] answer the question? A passage that only repeats the question, or says it cannot tell, does NOT answer it.`,options:["no","partly","answers it"]}}),y.answer={type:"choice",instructions:'Which passage gives the answer itself (a name, a fact, a date)? "none" if none does.',options:[...t.map((a,d)=>String(d+1)),"none"]};let c=null;try{c=await n({state:h,questions:y})}catch{c=null}const m=c?.answers;if(!m)return{reranked:i,decision:{verdict:"unknown"}};const u=t.map((a,d)=>({...a,relevance:Number(m[`p${d+1}`]?.value??0),at:d})).sort((a,d)=>d.relevance-a.relevance||a.at-d.at).map(({at:a,...d})=>d),b=String(m.answer?.value??"none"),S=b==="none"?null:t[Number(b)-1];return{reranked:[...u,...i.slice(r)],decision:S?{verdict:"found",id:S.id,title:S.title,by:c.model||"model",calibrated:c.calibrated!==!1}:{verdict:"not-found",by:c.model||"model",calibrated:c.calibrated!==!1}}}async function ce(o,{lexical:i,decide:n=null,corrections:r=null,memories:t=[],self:h="",excludeId:y=null,plan:c=null,limit:m=10,modes:u=T,hops:b=5,now:S=()=>Date.now()}={}){const a=new Set(u),d=L(r),E=new Set(d.hidden),Z=async s=>(await i(s)||[]).filter(p=>!E.has(p.id)),x=c||H(o),O={chats:"chat",notes:"note",meetings:"meeting"}[x.scope]||"",f={plan:{terms:I(o,{plan:x}),scope:x.scope,since:x.since||""},modes:{},ms:{},errors:{}},C=async(s,p)=>{const k=S();try{f.modes[s]=await p()}catch($){f.modes[s]=[],f.errors[s]=String($?.message||$)}return f.ms[s]=S()-k,f.modes[s]},F=await C("memory",async()=>a.has("memory")||a.has("graph")||a.has("hybrid")?Q(t,{text:o,includeAmbient:!1,limit:m}).map((s,p)=>({id:`memory:${s.id}`,kind:"memory",title:s.text,date:s.updatedAt||0,snippet:s.text,score:1/(1+p)})).filter(s=>!E.has(s.id)):[]),N=await C("keyword",async()=>a.has("keyword")||a.has("graph")||a.has("hybrid")?(await Z({terms:f.plan.terms,kind:O,sinceAt:q(x),limit:Math.max(m,20)+5})||[]).filter(s=>s.id!==y).map((s,p)=>({...s,echo:B(o,`${s.title}
|
|
3
3
|
${s.snippet||""}`),rank:p})).sort((s,p)=>Number(s.echo)-Number(p.echo)||s.rank-p.rank).map(({rank:s,...p},k)=>({...p,score:1/(1+k),...p.echo?{via:"an earlier time you asked"}:{}})):[]);await C("graph",async()=>{if(!a.has("graph")&&!a.has("hybrid"))return[];const s=new Map,p=(e,l,g)=>{const A=e.toLowerCase();if($.has(A))return;const D=s.get(A)||{name:e,weight:0,from:g};D.weight+=l,s.set(A,D)},k=h?[h]:[],$=new Set(d.notNames),w=new Set(N.filter(e=>e.echo).map(e=>e.id));for(const e of M(o,{exclude:k}))p(e,2,"question");F.slice(0,3).forEach((e,l)=>M(e.snippet,{exclude:k}).forEach(g=>p(g,1.5/(1+l),"memory"))),N.filter(e=>!e.echo).slice(0,8).forEach((e,l)=>[...e.names||[],...M(`${e.title}
|
|
4
4
|
${e.snippet||""}`,{midSentence:!0,exclude:k})].forEach(g=>p(g,1/(2+l),e.id)));const v=e=>N.slice(0,8).filter(l=>`${l.title} ${l.snippet||""} ${(l.names||[]).join(" ")}`.toLowerCase().includes(e)).length,R=Math.min(8,N.length),G=[...s.values()].some(e=>e.from==="question"||e.from==="memory"),j=[...s.entries()].filter(([e,l])=>l.from==="question"||l.from==="memory"||(!G||v(e)>=2)&&(R<4||v(e)<=R/2)).map(([e,l])=>({...l,key:e,weight:l.weight/(1+Math.max(0,v(e)-2))})).sort((e,l)=>l.weight-e.weight).slice(0,b),z=new Map,_=(e,l,g)=>{const A=z.get(e.id)||{...e,score:0,via:[]};A.score+=l,g&&!A.via.includes(g)&&A.via.push(g),z.set(e.id,A)};N.forEach((e,l)=>_(e,(e.echo?.05:.5)/(1+l),null));for(const e of j)(await Z({terms:[e.name.toLowerCase()],phrase:!0,kind:O,sinceAt:q(x),limit:10})||[]).filter(g=>g.id!==y&&!w.has(g.id)&&!B(o,`${g.title}
|
|
5
|
-
${g.snippet||""}`)).forEach((g,A)=>_(g,e.weight/(1+A),e.name));return f.plan.names=j.map(e=>e.name),[...z.values()].sort((e,l)=>l.score-e.score).slice(0,m).map(e=>({...e,via:e.via.length?e.via.join(", "):void 0}))}),await C("hybrid",async()=>{if(!a.has("hybrid"))return[];const s=(f.modes.graph||[]).filter(w=>w.via),p=[f.modes.memory,f.modes.keyword,s].map(w=>(w||[]).map(v=>v.id)),k=new Map;for(const w of["graph","keyword","memory"])for(const v of f.modes[w]||[])k.has(v.id)||k.set(v.id,{...v,from:[]});for(const w of["memory","keyword","graph"])for(const v of f.modes[w]||[])k.get(v.id)?.from.push(w);const $=Y(p,{limit:m+5}).map(({id:w,score:v})=>({...k.get(w),score:v,from:k.get(w).from.join("+")}));return[...$.filter(w=>!w.echo),...$.filter(w=>w.echo)].slice(0,m)}),n&&a.has("hybrid")&&await C("reranked",async()=>{const s=await
|
|
5
|
+
${g.snippet||""}`)).forEach((g,A)=>_(g,e.weight/(1+A),e.name));return f.plan.names=j.map(e=>e.name),[...z.values()].sort((e,l)=>l.score-e.score).slice(0,m).map(e=>({...e,via:e.via.length?e.via.join(", "):void 0}))}),await C("hybrid",async()=>{if(!a.has("hybrid"))return[];const s=(f.modes.graph||[]).filter(w=>w.via),p=[f.modes.memory,f.modes.keyword,s].map(w=>(w||[]).map(v=>v.id)),k=new Map;for(const w of["graph","keyword","memory"])for(const v of f.modes[w]||[])k.has(v.id)||k.set(v.id,{...v,from:[]});for(const w of["memory","keyword","graph"])for(const v of f.modes[w]||[])k.get(v.id)?.from.push(w);const $=Y(p,{limit:m+5}).map(({id:w,score:v})=>({...k.get(w),score:v,from:k.get(w).from.join("+")}));return[...$.filter(w=>!w.echo),...$.filter(w=>w.echo)].slice(0,m)}),n&&a.has("hybrid")&&await C("reranked",async()=>{const s=await ee(o,f.modes.hybrid||[],{decide:n});return f.decision=s.decision,s.reranked});for(const s of T)a.has(s)||delete f.modes[s];return a.has("keyword")&&(f.modes.keyword=N.slice(0,m)),f}const te=[/\bmy\s+(?:friends?|family|wife|husband|partner|mom|mum|dad|mother|father|son|daughter|kids?|brother|sister|boss|manager|colleagues?|team|doctor|neighbou?rs?|contacts?|notes?|meetings?|chats?|trip|plans?|tasks?|reminders?|flight|hotel|appointment|address|car|house|home)\b/i,/\b(?:did|have|had)\s+(?:i|we)\b/i,/\bwhat\s+did\s+(?:i|we|\w+)\s+(?:say|decide|agree|discuss|mention|write|note)\b/i,/\b(?:when|where|who|what)\s+(?:was|were|is|are)\s+(?:my|our)\b/i,/\b(?:i|we)\s+(?:told you|mentioned|said|talked about|discussed)\b/i,/\bremind me\b/i,/\b(?:was|were|am|are)\s+(?:i|we)\s+(?:planning|going|supposed|meant|thinking|hoping|booked|scheduled)\b/i,/\b(?:i|we)\s+(?:was|were)\s+(?:planning|going to|supposed to|meant to|thinking of|hoping to)\b/i,/\b(?:i|we)\s+(?:planned|booked|scheduled|decided)\b/i,/\bwho\s+(?:do|did|have)\s+i\s+(?:meet|met|talk|speak|spoke|chat)/i,/\b(?:meetings?|calls?|chats?|notes?)\s+(?:per|by|each|every|a)\s+(?:month|week|day)\b/i],se=/^\s*(?:(?:ok(?:ay)?|hey|so|and|also|please)[\s,]+)*(?:remember|note|keep in mind|don'?t forget|never forget|forget|call me|save (?:that|this))\b/i;function P(o,{names:i=[]}={}){const n=String(o||"");if(n.trim().length<6||se.test(n)||W(n)&&!/\b(?:i|we|my|our)\b/i.test(n))return!1;if(te.some(t=>t.test(n))||/\b(meetings?|calls?|chats?|notes?|conversations?)\b/i.test(n)&&M(n).length)return!0;const r=n.toLowerCase();return i.some(t=>t&&new RegExp(`\\b${String(t).toLowerCase().replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\b`).test(r))}function le(o,{names:i=[],home:n="",world:r=!1}={}){if(P(o))return!0;if(r)return!1;const t=c=>String(c||"").toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean),h=t(n),y=c=>{const m=t(c);return m.length>0&&h.length>0&&(m.every(u=>h.includes(u))||h.every((u,b)=>m[b]===u))};return P(o,{names:(Array.isArray(i)?i:[]).filter(c=>!y(c))})}function de(o,{max:i=5,now:n=Date.now()}={}){const r=(o?.modes?.reranked||o?.modes?.hybrid||[]).filter(c=>!c.echo).slice(0,i);if(!r.length)return null;const t=r.map((c,m)=>{const u=c.kind==="memory"?"memory":`${c.id}${c.title?` “${String(c.title).slice(0,80)}”`:""}`,b=String(c.snippet||c.title||"").replace(/\s+/g," ").trim().slice(0,300);return`${m+1}. [${u}] ${b}`}),h=o?.decision?.verdict==="found"?`
|
|
6
6
|
Most likely answered by: ${o.decision.title}`:"",y=`(ALREADY SEARCHED the person's own chats, notes, meetings and memory for the question below. Answer from this; cite the [id] you used. If the answer is not here, say you could not find it in their data — never guess, and never say you have no access to their data.)
|
|
7
7
|
|
|
8
8
|
${t.join(`
|
|
9
|
-
`)}${h}`;return{id:`prefetch_personal_${n}`,kind:"prefetch",prefetch:"personal",title:"Searched your own data",text:y,chars:y.length}}export{
|
|
9
|
+
`)}${h}`;return{id:`prefetch_personal_${n}`,kind:"prefetch",prefetch:"personal",title:"Searched your own data",text:y,chars:y.length}}export{V as MAX_CORRECTIONS,T as SEARCH_MODES,ae as correct,de as evidenceAttachment,B as isEcho,I as keywordTerms,M as namesIn,L as normalizeCorrections,P as personalAsk,le as personalFirst,ee as rerankAndDecide,ce as runSearchModes};
|