UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

90 lines • 6.63 kB
/** * Turning a natural-language question into full-text search terms, for the lexical leg of * `PgLexicalVectorStore`. * * With the `simple` text-search configuration (no stemming, no stop words; any language) a question * searched as is either matches nothing (every word required) or, as "any word", ranks chunks full * of "the / of / which / de / que" first. So the query side drops the stop words of the question's * language(s) and keeps the meaningful terms, which the store then ranks by how many of them a chunk * holds, rare terms weighing more (an IDF over the matching rows, BM25-style). */ const words = (s) => new Set(s.split(/\s+/).filter(Boolean)); /** * Postgres' Snowball stop word lists (`tsearch_data/{english,portuguese,spanish}.stop`), minus * one-letter words (never terms here) and words that carry meaning in a sibling language * ("estado", "sentido"). */ export const DEFAULT_STOP_WORDS = { english: words(` me my myself we our ours ourselves you your yours yourself yourselves he him his himself she her hers herself it its itself they them their theirs themselves what which who whom this that these those am is are was were be been being have has had having do does did doing an the and but if or because as until while of at by for with about against between into through during before after above below to from up down in out on off over under again further then once here there when where why how all any both each few more most other some such no nor not only own same so than too very can will just don should now`), portuguese: words(` de que do da em um para com não uma os no se na por mais as dos como mas ao ele das seu sua ou quando muito nos já eu também só pelo pela até isso ela entre depois sem mesmo aos seus quem nas me esse eles você essa num nem suas meu às minha numa pelos elas qual nós lhe deles essas esses pelas este dele tu te vocês vos lhes meus minhas teu tua teus tuas nosso nossa nossos nossas dela delas esta estes estas aquele aquela aqueles aquelas isto aquilo estou está estamos estão estive esteve estivemos estiveram estava estávamos estavam estivera estivéramos esteja estejamos estejam estivesse estivéssemos estivessem estiver estivermos estiverem hei há havemos hão houve houvemos houveram houvera houvéramos haja hajamos hajam houvesse houvéssemos houvessem houver houvermos houverem houverei houverá houveremos houverão houveria houveríamos houveriam sou somos são era éramos eram fui foi fomos foram fora fôramos seja sejamos sejam fosse fôssemos fossem for formos forem serei será seremos serão seria seríamos seriam tenho tem temos tém tinha tínhamos tinham tive teve tivemos tiveram tivera tivéramos tenha tenhamos tenham tivesse tivéssemos tivessem tiver tivermos tiverem terei terá teremos terão teria teríamos teriam`), spanish: words(` de la que el en los del se las por un para con no una su al lo como más pero sus le ya este sí porque esta entre cuando muy sin sobre también me hasta hay donde quien desde todo nos durante todos uno les ni contra otros ese eso ante ellos esto mí antes algunos qué unos yo otro otras otra él tanto esa estos mucho quienes nada muchos cual poco ella estar estas algunas algo nosotros mi mis tú te ti tu tus ellas nosotras vosotros vosotras os mío mía míos mías tuyo tuya tuyos tuyas suyo suya suyos suyas nuestro nuestra nuestros nuestras vuestro vuestra vuestros vuestras esos esas estoy estás está estamos estáis están esté estés estemos estéis estén estaré estarás estará estaremos estaréis estarán estaría estarías estaríamos estaríais estarían estaba estabas estábamos estabais estaban estuve estuviste estuvo estuvimos estuvisteis estuvieron estuviera estuvieras estuviéramos estuvierais estuvieran estuviese estuvieses estuviésemos estuvieseis estuviesen estando estad he has ha hemos habéis han haya hayas hayamos hayáis hayan habré habrás habrá habremos habréis habrán habría habrías habríamos habríais habrían había habías habíamos habíais habían hube hubiste hubo hubimos hubisteis hubieron hubiera hubieras hubiéramos hubierais hubieran hubiese hubieses hubiésemos hubieseis hubiesen habiendo habido habida habidos habidas soy eres es somos sois son sea seas seamos seáis sean seré serás será seremos seréis serán sería serías seríamos seríais serían era eras éramos erais eran fui fuiste fue fuimos fuisteis fueron fuera fueras fuéramos fuerais fueran fuese fueses fuésemos fueseis fuesen tengo tienes tiene tenemos tenéis tienen tenga tengas tengamos tengáis tengan tendré tendrás tendrá tendremos tendréis tendrán tendría tendrías tendríamos tendríais tendrían tenía tenías teníamos teníais tenían tuve tuviste tuvo tuvimos tuvisteis tuvieron tuviera tuvieras tuviéramos tuvierais tuvieran tuviese tuvieses tuviésemos tuvieseis tuviesen teniendo tenido tenida tenidos tenidas tened`), }; const TOKEN = /[\p{L}\p{N}]{2,}/gu; /** * The meaningful terms of a question, in order, deduplicated, at most `max`: the stop words of the * language(s) the question is written in are dropped (the language(s) with the most stop words in * it, so "sea"/"son" stay terms in an English question although they are Spanish stop words). A * question made only of stop words keeps them all (there is nothing else to search for). */ export function keywordTerms(query, max = 24, stopWords = DEFAULT_STOP_WORDS) { const tokens = [...new Set(query.toLowerCase().normalize('NFC').match(TOKEN) ?? [])]; const counts = Object.entries(stopWords).map(([, stop]) => [stop, tokens.filter((t) => stop.has(t)).length]); const best = Math.max(0, ...counts.map(([, n]) => n)); if (best === 0) return tokens.slice(0, max); const stop = counts.filter(([, n]) => n === best).map(([s]) => s); const terms = tokens.filter((t) => !stop.some((s) => s.has(t))); return (terms.length > 0 ? terms : tokens).slice(0, max); } /** Whether the user wrote search syntax (a quoted phrase, `-exclusion`) worth honoring as such. */ export function hasSearchSyntax(query) { return /"[^"]+"/.test(query) || /(^|\s)-[\p{L}\p{N}]/u.test(query); } /** `'a' | 'b' | …` for `to_tsquery` (terms are letter/digit runs, so quoting is enough). */ export function anyTermTsquery(terms) { return terms.map((t) => `'${t.replace(/'/g, '')}'`).join(' | '); } //# sourceMappingURL=lexical-query.js.map