::nx::Object ::nx::Object ::nsmcp::QuestionBackend ::nsmcp::QuestionBackend → reportingInstructions canonicalResult describe run toolCallResult ::nsmcp::QuestionBackend->::nx::Object ::nsmcp::ChatCompletionsBackend ::nsmcp::ChatCompletionsBackend describe init run streamClose streamData streamDrain streamHeaders streamOpen ::nsmcp::ChatCompletionsBackend->::nsmcp::QuestionBackend ::nsmcp::CodexQuestionBackend ::nsmcp::CodexQuestionBackend describe run ::nsmcp::CodexQuestionBackend->::nsmcp::QuestionBackend

Class ::nsmcp::QuestionBackend

::nsmcp::QuestionBackend[i] create ...

Shared reporting rules for Codex and direct API backends.
Defined in /usr/local/ns/tcl/nsmcp/question-backend.tcl

Class Relations

  • class: ::nx::Class[i]
  • superclass: ::nx::Object[i]
  • subclass: ::nsmcp::ChatCompletionsBackend[i], ::nsmcp::CodexQuestionBackend[i]
::nx::Class create ::nsmcp::QuestionBackend \
     -superclass ::nx::Object

Methods (to be applied on the object)

  • reportingInstructions (scripted, public)

     nsmcp::QuestionBackend[i] reportingInstructions base
    Parameters:
    base (required)

    Testcases:
    No testcase defined.
    append base " For system-log warning analysis use log_error_summary with severities [list {["Warning"]}]; the default selects Error/Fatal/Bug only. Mixed warning/error analysis can select all four. To inspect individual warning records use log_errors with severity Warning. Failure to request a severity is not evidence that it is absent or disabled. Treat severity as the emitter's classification and assess operational significance from the actual message, counts and context."
    append base " For mutex diagnostics, use coverage.mutexTraceGroups and mutexTraceUngroupedRecords for full-scan categorization, never extrapolate the first five examples. Expected ns:sched unlock/hold traces are omitted. Report wait versus hold durations separately and their scanned-file scope; untimestamped traces cannot be assigned to today's time window. Long durations alone do not establish contention or an incident; retain thread/offset evidence and distinguish observations from interpretation."
    return "$base For scheduler warnings, call server_runtime and inspect scheduler.available and scheduler.counters. These are process-lifetime counters observed at scheduler.observedAt, not totals for the requested warning window or sampled interval. Compare repeated observations from the same process before claiming ongoing problems; do not subtract maxima or compare counters across restarts. waitReturnLateness includes condition-wait mutex reacquisition and cannot isolate OS wake-up latency. mutexAcquisition measures only explicit acquisitions by the main scheduler thread, not worker locks. nonThreadedCallbacks records callback execution; threaded jobs named by late-dispatch warnings may be victims rather than causes. dispatchLateness is dequeue lateness, not worker execution-start delay. over100ms uses 100ms; slow callback warnings use schedlogminduration, normally 2s. Warnings are rate limited and suppression counters do not mean observations were lost. lastId and maxId may refer to completed one-shot or cancelled jobs; a missing live entry does not invalidate the measurement. Timing context in a warning gives the last callback, which need not be the blocking one. Do not infer causality from proximity alone or advise changing the exam-minute alignment ns_after callback merely because of a one-time startup observation. Use one timezone consistently for window bounds, group occurrence times and commentary: honor the requested timezone, otherwise use the supplied browser timezone context, otherwise UTC. Convert epoch timestamps rather than copying local timestamps from log examples. For error or warning summaries, report every returned group (count and description), severityTotals and ungroupedRecords; also report omittedGroups, omittedGroupRecords and groupingComplete. Distinguish classified but unreturned records from records exceeding the grouping capacity. Deduplication markers inherit the original severity, are physical log records rather than independent incidents, and reported suppressed occurrences cannot be assigned wholesale to the requested window. Inspect deduplication accounting and its attribution limits. For duplicate-parameter warnings inspect accessCorrelation: it is bounded sample evidence from retained cached access records, not a distribution of all warnings. Missing or ambiguous correlations, legacy missing User-Agents, ingestion lag and retention are unknown evidence, not proof of no bot activity. Browser-like User-Agents do not establish human traffic; duplicate parameters do not by themselves prove bots or a URL-generation defect. do not silently omit groups. Groups count log records, not unique incidents. Correlate records only with supporting request/thread identifiers and timing; separately timestamped Error records are not continuation lines merely because their messages match. Report coverage.logBounds as observed file times, never as a rotation time or proof of a complete day. Distinguish configured rotation settings from verified rotation; unknown schedule or lastVerifiedAt remains unknown. Do not assume the current file covers the UTC day, even with local midnight rotation. Untimestamped/inferred diagnostics remain separate from windowed severity totals. For address-free source diversity and User-Agent rankings, use access_bot_routing mode scan with aggregateTraffic true, includePeerAddresses false and the exact path when requested. Aggregates count all selected scanned records before evidence truncation; inspect observed completeness, unknown fields, cardinality limits and time-window coverage separately. Do not request address disclosure just to measure source counts or concentration. Deliberate fast-pool overrides such as /robots.txt are not evidence of failed bot isolation; inspect effective mappings. Before recommending admission or concurrency controls, establish what controls already exist from user-provided facts and configuration. Registered filters alone do not reveal their implementation. Do not propose an existing two-concurrent-anonymous-request limit again; assess its effect using authenticationStates counts, 503 counts and successful handler time, and identify unmeasured enforcement details. High 503 counts can indicate successful protection, not worker overload. Logged authentication state is not a verified session identity; old cached rows may be unknown. Inspect process.cpuCapacity: effectiveCores is the minimum visible CPU ceiling, constraintsComplete and incompleteReasons qualify it. Compare sampled core consumption with that ceiling; inspect cgroup throttling deltas across the same interval. Cgroup counters include other processes and ancestors may include siblings; do not sum ancestor counters or attribute all throttling to NaviServer. Hidden limits, shares and host contention can reduce actual availability. Do not call CPU capacity unknown when a usable qualified value is reported. When duplicate-parameter requestSamples include userAgentSource system-log, use that User-Agent directly even if accessCorrelation is unavailable; it takes precedence over cached User-Agent. Access correlation still supplies status, pool and timing. A truncated User-Agent is incomplete evidence. For performance advice, inspect server_request_routing and access_bot_routing before claiming bot isolation failed or proposing new filters. Filter registrations do not establish filter purpose or implementation. Use slow_requests to investigate slow access records; do not infer individual SQL plans or query timings from access timing data. In explicit manual page mode follow diagnostic nextArguments and report page-local counts and unknown rule semantics. access_bot_routing.lookupMode distinguishes native-context precedence resolution from fallback-rule-membership; expectedPool describes current routing only, and contextComplete=false means insufficient logged inputs. Do not interpret fallback membership candidates or bot-like heuristics as verified historical routing failures. To inspect routing candidates, use access_bot_routing category for the exact reported category and obey limit maximum 100. Distinguish filteredOutRecords from omittedRecords and use omittedCategoryTotals to identify missing candidate evidence. If includePeerAddresses is denied, retry without it and provide authorized redacted evidence rather than abandoning the investigation. A rescan is a new observation, not recovered retained evidence. omittedRecords and omittedCategoryTotals count log records, not groups. Choose the category appropriate to the current lookupMode, especially after a core upgrade. access_bot_routing defaults to a background scan: wait for the completed job result and use its aggregate counts. Do not request mode page or manually paginate unless the user explicitly wants byte-page inspection. Timeout preserves the jobHandle for log_results; do not start a duplicate scan. For server_history, use the default page size of 100 (maximum 100); do not choose small pages unless explicitly requested. Follow nextArguments unchanged until history.more=false, preserving the window and cursor; do not restart the same history query. For broad performance investigations start with a bounded recent window, normally 10 completed minutes; expand only when evidence or the user requires it. Budget history pages against the 32-call question limit and reserve calls for other diagnostics and a final answer. If the requested window cannot fit the remaining call budget, report partial coverage and the exact continuation arguments rather than silently shortening the requested window, claiming complete coverage, or exhausting the tool-call limit."

Methods (to be applied on instances)

  • canonicalResult (scripted, public)

     <instance of nsmcp::QuestionBackend[i]> canonicalResult json
    Parameters:
    json (required)

    Testcases:
    No testcase defined.
    if {[catch {ns_json parse -output triples -- $json} root] || [lindex $root 1] ne "object"} {return $json}
    if {[catch {ns_json triples gettype -path structuredContent -- $root}]} {return $json}
    set structured [list {} [ns_json triples gettype -path structuredContent -- $root] [ns_json triples getvalue -output triples -path structuredContent -- $root]]
    set duplicate [ns_json value -- $structured]
    set fields {}
    foreach {key type value} [lindex $root 2] {
        if {$key eq "content" && $type eq "array"} {
            set content {}
            set index 0
            foreach {i kind members} $value {
                set omit false
                if {$kind eq "object"} {
                    set item [ns_json parse [ns_json value -- [list {} object $members]]]
                    if {[dict exists $item type] && [dict get $item type] eq "text"
                        && [dict exists $item text] && [dict get $item text] eq $duplicate} {set omit true}
                }
                if {!$omit} {lappend content $index $kind $members; incr index}
            }
            set value $content
        }
        lappend fields $key $type $value
    }
    return [ns_json value -- [list {} object $fields]]
  • describe (scripted, public)

     <instance of nsmcp::QuestionBackend[i]> describe

    Testcases:
    No testcase defined.
    return {backend unknown}
  • run (scripted, public)

     <instance of nsmcp::QuestionBackend[i]> run question state emit
    Parameters:
    question (required)
    state (required)
    emit (required)

    Testcases:
    No testcase defined.
    error "abstract QuestionBackend.run"
  • toolCallResult (scripted, public)

     <instance of nsmcp::QuestionBackend[i]> toolCallResult item
    Parameters:
    item (required)

    Testcases:
    No testcase defined.
    if {![catch {ns_json triples gettype -path error -- $item} type] && $type ne "null"} {
        set error [ns_json triples getvalue -output triples -path error -- $item]
        return [ns_json value -- [list {} object [list isError boolean true error $type $error]]]
    }
    if {[catch {ns_json triples gettype -path result -- $item} type]} {return null}
    return [:canonicalResult [ns_json value -- [list {} $type [ns_json triples getvalue -output triples -path result -- $item]]]]