nsmcp::QuestionService method event (public)
<instance of nsmcp::QuestionService> event handle turn event
Defined in /usr/local/ns/tcl/nsmcp/question-service.tcl
Record a backend event for a specific retained turn. Serialize updates and discard events for expired or superseded turns.
- Parameters:
- handle (required)
- Retained job or conversation handle; ownership and expiry checks still apply.
- turn (required)
- Retained turn identifier, used to reject superseded callbacks.
- event (required)
- Backend event dictionary for the retained question turn.
- Returns:
- Whether the event was accepted for the active turn.
- Testcases:
- No testcase defined.
Source code: ns_mutex lock ${:mutex} try { if {![nsv_exists ${:store} $handle]} { return false } set record [nsv_get ${:store} $handle] if {[dict get $record current] ne $turn} { return false } set continue [expr {[dict get $record status] ne "cancelling"}] if {[dict get $event type] eq "check"} { return $continue } set last [lindex [dict get $record turns] end] switch -- [dict get $event type] { model { dict set last model [string range [dict get $event model] 0 255] } questionUsage { set raw [dict get $event usage] set usage [::nsmcp::questionUsageCounters $raw { inputTokens inputTokens outputTokens outputTokens totalTokens totalTokens cachedInputTokens cachedInputTokens cacheWriteInputTokens cacheWriteInputTokens reasoningOutputTokens reasoningOutputTokens }] foreach key {scope source reason} { if {[dict exists $raw $key]} { dict set usage $key [string range [dict get $raw $key] 0 63] } } dict set usage available [expr {[dict exists $raw available] && [string is boolean -strict [dict get $raw available]] && [dict get $raw available]}] dict set last questionUsage $usage } usage { # Only the adapter-neutral allowlist reaches logs/storage. set raw [dict get $event usage] set usage [::nsmcp::questionUsageCounters $raw { inputTokens inputTokens outputTokens outputTokens totalTokens totalTokens cachedInputTokens cachedInputTokens uncachedInputTokens uncachedInputTokens cacheWriteInputTokens cacheWriteInputTokens reasoningOutputTokens reasoningOutputTokens apiRequests apiRequests requestsWithUsage requestsWithUsage }] foreach key {scope source} { if {[dict exists $raw $key]} { dict set usage $key [string range [dict get $raw $key] 0 63] } } if {[dict exists $raw complete] && [string is boolean -strict [dict get $raw complete]]} { dict set usage complete [expr {!![dict get $raw complete]}] } dict set last usage $usage } text { dict append last answer [dict get $event text] } job { set key [dict get $event jobHandle] if {![dict exists $last jobs $key] && [dict exists $last jobs] && [dict size [dict get $last jobs]]>=128} { error "Question background job limit reached" } dict set last jobs $key $event } tool { dict lappend last tools [:toolEvidence $handle $event] } state { set state [dict get $event state] if {[string bytelength $state]>${:maxBytes}} { error "Question continuation size limit reached; start a new conversation" } dict set record state [zlib compress [encoding convertto utf-8 $state]] dict set record stateEncoding zlib-tcl-v1 } } dict set record turns [lreplace [dict get $record turns] end end $last] if {[string bytelength $record] > ${:maxBytes}} { error "Conversation size limit reached (${:maxBytes} bytes); start a new conversation" } nsv_set ${:store} $handle $record return $continue } finally { ns_mutex unlock ${:mutex} }XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)