• exec/chat_llm.js

    From Rob Swindell (on Debian Linux)@VERT to Git commit to main/sbbs/master on Mon Aug 10 03:17:45 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/a7718428415a389396c1ec21
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: treat a repeated question as a failed answer

    Reply-text similarity cannot detect a stuck conversation. A user asked
    the same question three times running and got three answers that meant
    the same thing but scored only 0.33-0.58 against each other, because
    the model rewords itself at this temperature. Genuinely new answers on
    a single topic score 0.42-0.62, so the ranges overlap and no threshold separates them.

    The question itself is the reliable signal: someone retyping what they
    just asked is telling you the previous answer did not land, whatever
    its wording. When the incoming question matches one of that speaker's
    own recent questions, the previous answer is treated as a repeat
    outright, bypassing the similarity test, and the existing regenerate- then-deflect path runs.

    Only the speaker's own turns are compared -- the bot restating a
    question back is not the user asking twice. Similarity still governs
    whether the REGENERATED answer counts as another repeat, at a looser
    threshold, since the strict one would essentially never fire there.

    ---
    þ 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 Mon Aug 10 03:17:45 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/e77a8de7278d146a717e0fcf
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: police gitlab.synchro.net URLs against fabrication

    The fabrication filter covered the wiki and the curated archive domains
    but not GitLab, so invented commit links passed straight through. A
    user was handed a commit URL for a SHA that does not exist, said the
    link was broken, and was handed a second invented one. A plausible
    commit URL is precisely the kind of thing someone clicks and trusts.

    gitlab.synchro.net now sits alongside the other policed domains, and
    the notion of a valid URL is generalised rather than special-cased:
    a URL may be cited if it appeared in the retrieved context, in the
    transcript the model was handed, in a tool result, or in the curated
    archive index.

    Tool results are the source that matters here -- an issue lookup
    returns a real issue URL, and nothing downstream could previously tell
    that apart from a URL the model composed. Both tool-execution paths
    record what they returned.

    Retrieved-context URLs are now collected from the injected text rather
    than only from wiki-prefixed provenance, so enabling a crawler whose
    chunks carry GitLab links cannot have the filter strip the very URLs
    retrieval just supplied.

    ---
    þ 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 Oct 16 21:19:03 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/2a48d15a6f3e497f8af7b03a
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: reject a provider/endpoint mismatch at config load

    Ollama serves both its native /api/chat and an OpenAI-compatible /v1/chat/completions on the same port, so pairing the wrong provider with
    an endpoint doesn't fail at the HTTP level. provider=openai against
    /api/chat failed only after the full generation, with "no choices in
    response: <raw JSON>"; a sysop (Keyop) hit exactly that in #synchronet
    while following the advice to switch endpoints.

    load_config() now compares the endpoint's path with the provider
    (/api/chat = ollama, .../chat/completions = openai) for both endpoint and endpoint_fallback, and throws an error naming the fix, before any
    request. For URLs whose path doesn't say (e.g. behind a proxy), the
    response parsers also recognize the other API's reply shape and say so
    instead of dumping the raw JSON.

    Tested against Ollama: both mismatches fail at once (0.0s) with the new messages; both correct pairings still reply; the live config still
    loads; chat_openai() aimed at /api/chat reports the native shape.

    Co-Authored-By: Claude Opus 5.5 <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 Oct 16 21:19:03 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/87062103db874c07c2048efb
    Modified Files:
    exec/chat_llm.js
    Log Message:
    chat_llm: honor "= false" for boolean chat_llm.ini keys

    iniGetObject() already converts true/false values to booleans, but load_config() and its callers compared these keys against the STRING
    'false', which never matched. So setting any of memory_persist,
    reply_dedup, memory_summary_in_prompt, stream or simulate_typos to false
    was silently ignored. memory_persist = false, the documented setting for
    bots in public channels that shouldn't retain anything about strangers,
    still wrote per-speaker memory files.

    New cfg_bool() normalizes all five in load_config() (booleans, numbers,
    and false/no/off/0 strings; unset keeps the default of true), and the
    use sites test the booleans.

    Tested: an ini with the five keys off yields false for each, unset
    yields true, and a chat turn with memory_persist = false leaves the
    speaker's memory file untouched.

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

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