• exec/chat_llm.js

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/1f72bd03d5d4bb38b1ea543a
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: skip RAG for identity/social queries

    inject_retrieval() fired on any query whose top BM25 hit cleared the
    score floor -- including self-referential questions like "what's your
    name?" (the token "name" scores well), injecting board/wiki chunks that
    the model then conflated with its own identity ("I'm Vertrauen BBS").
    Add _is_conversational_query() and gate inject_retrieval() on it:
    identity ("who/what are you", "your name", "are you a bot/sysop"),
    capability, and social-pleasantry queries now retrieve nothing and are
    answered from the system prompt's identity rules alone. Kept narrow so
    genuine knowledge questions (incl. "who is the sysop?") still retrieve.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/c356c273bcd6534a1e269d6f
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: decode HTML entities + don't archive-route Synchronet how-tos

    Two fixes surfaced while testing "pkzip" queries:

    1. final_reply_postprocess() now HTML-entity-decodes replies. The 7B
    model occasionally emits "&lt;http://...&gt;" (an autolinked URL in
    angle brackets) or "&amp;" inside a URL; plain-text IRC/terminal
    then showed the literal entities. Decode &lt;/&gt;/&quot;/&#39;/
    &apos; then &amp; (last, to avoid double-decoding) before the
    markdown-strip and URL-validation passes.

    2. classify_intent() no longer pre-routes to external_archives when the
    query is a Synchronet how-to/config question that merely NAMES a
    BBS-era topic. "how do I configure pkzip in sbbs?" was forced to
    external_archives and answered with SEA v. PKWARE lawsuit trivia;
    docstyle-shaped queries now skip the archive route and fall through
    to the model + wiki RAG. Pure-history phrasing ("how did the SJG
    raid happen", "tell me about pkzip") is not docstyle, so it still
    routes to the archive.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/9a7defa683da7dadc7fa263f
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: strip bare tool-name leaks from replies

    The model sometimes names an internal tool in user-facing prose without
    parens -- e.g. "...checking out the documents linked from
    external_archives: <url>" or "the this_bbs tool shows...". The leak-strip
    only handled the with-parens form (and didn't list external_archives at
    all). Add external_archives to that list and add a bare-name strip
    (optional lead-in preposition/article + tool name + optional "tool" +
    trailing colon). Leftover whitespace is collapsed by the existing
    cleanup pass; URLs in the sentence survive.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/0daf7f872fce4940a9bff35d
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: iterate HTML-entity decode for double-escaped replies

    The 7B model sometimes DOUBLE-escapes ("&amp;lt;...&amp;gt;"); the
    single-pass decode peeled only one layer and left "&lt;...&gt;" literal
    in the reply (seen in a live "who is Dr Seuss?" turn). Decode in a
    bounded loop (max 3 passes) until the string stops changing, so double-/triple-escaped entities fully resolve. Safe because a chat
    reply never legitimately contains a literal "&lt;".

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/61f06df8d086ff274293c425
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: strip dangling "check out this link: <name>" (no URL)

    The 7B model often appends a link reference that names a resource but
    never produces a URL ("...for more info, check out this link: BBS Documentaries"). strip_fake_urls() can't catch it -- there is no URL to
    strip. final_reply_postprocess() now removes the trailing clause, from a lead-in verb through "(this|the) link[:] <name>" to the end, but only
    when the clause carries no http(s) URL (callback check), so real
    citations survive.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/6d5c66b4112bf3e25069137c
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: rewrite mechanical empty-tool-result phrasing

    When a tool returns no hits, the model sometimes echoes a database-style
    "No results found for X" / "I couldn't find any info on X" -- which
    reads like an error, not the guru. final_reply_postprocess() now
    rewrites a whole-reply no-results admission into the guru's natural
    voice ("haven't come across anything on X"), preserving the topic.
    Anchored to the full trimmed reply so it only fires when the WHOLE
    reply is that admission, never on a sentence that merely says "found".

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/9e147fd2fa043804ece7f730
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: extend dangling-ref + deeper entity-decode + ".," cleanup

    Three postprocess hygiene fixes from live watching:
    - Dangling non-link strip now matches "this resource/page/article/
    guide/entry/write-up", not just "this link" (e.g. "...check out this
    resource: FidoNet Basics" with no URL).
    - Entity-decode loop cap raised 3 -> 6 passes: the 7B was seen
    QUADRUPLE-escaping a wiki URL ("&amp;amp;amp;lt;..."), which the
    3-pass cap left as "&lt;".
    - Collapse the "item., item" period-then-comma artifact (from the
    numbered-list -> inline conversion) into a single comma.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/12a8cf565d4f4f2433698081
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: mechanical-phrasing rewrite tolerates an adjective

    "No relevant hits found for X" slipped past the empty-result rewrite
    because an adjective ("relevant"/"matching"/"specific"/...) sat between
    "no" and the noun. Allow an optional adjective in both the "no <noun>"
    and "couldn't find any <noun>" branches.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/32dd5d66b972ff96a3d4589d
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: boost acronyms/glossary/facts for definitional queries

    acronym/ and syncfact/ docs don't get WIKI_BOOST (only dokuwiki/ does),
    so a short authoritative acronym definition lost to a wiki-boosted
    config page that merely mentions the term ("what does FOSSIL stand for"
    acronym/FOSSIL only #3). Add _is_definitional_query() ("what is X",
    "what does X stand for / mean", "define X", "what's a/an X") and, for
    those queries, boost acronym/, syncfact/, and dokuwiki/ref:* in
    bm25_search so the definition wins. Pairs with the new acronyms +
    syncfact index sources.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/2b3ae27c89a33ff148bfa86e
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: boost filebase for download / file-availability queries

    "is X available for download" / "where do I download X" pulled in wiki file-config pages (config:file_options, user:files) because "download"
    matches them with high frequency. Add _is_download_query() and, for
    those queries (excluding docstyle "how do I download X" so wiki how-tos
    stay), skip the wiki boost and boost filebase/ so the real files win
    (e.g. "where can I download syncterm" -> the SyncTERM files). A query
    term that matches no filename (e.g. "hyperterminal" vs htpe63.zip) still
    can't be surfaced by boosting -- that's a data limitation, noted inline.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/c336b3f9ff9a78301d1ad648
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: gate filebase boost on how-to, not all docstyle

    The download boost excluded any docstyle query, which wrongly caught
    "where can I download X" ("where" is a docstyle pattern) and denied it
    the filebase boost. Gate on howto_intent instead: "how do I download X"
    wiki, but "where can I download X" / "is X available" -> filebase.
    Fixes the regression case that slipped into eaf5c41ba.

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Fri May 29 23:59:57 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/4a869e667393a7414094194e
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: fix classify_intent under-routing for 3 query phrasings

    classify_intent pre-executes a tool to bypass qwen2.5:7b's unreliable tool-choice, but three natural phrasings fell through to the model,
    which then answered tool-less:

    - "how many BBSes are in the list?" -- no rule for an UNFILTERED total
    count (only filtered "how many <X> bbses" existed). Add a total-count
    rule AFTER the filtered ones so a network/software filter still wins;
    unfiltered list mode returns total = full directory size.
    - "what has been committed to Synchronet lately?" -- the recent-commits
    pattern's end-anchor rejected a "to <repo>" phrase before "lately".
    - "how many files were downloaded today?" -- the stats pattern didn't
    allow a passive-voice auxiliary ("were/was/has been") between noun
    and verb.

    Regression: count-sbbslist, git-commits-recent, host-bbs-stats-today
    now PASS; previously-matching forms still route (no regressions).

    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net