feat(bot): enhance topic processor logging for diagnosis

Added comprehensive logging to topic-processor.ts to capture API errors, parsing failures, and silent decisions. Also added result logging to purchase and payment ingestion handlers to trace the processor's output.
This commit is contained in:
2026-03-14 14:54:49 +04:00
parent 572c21f621
commit 8de8419028
3 changed files with 52 additions and 0 deletions

View File

@@ -635,6 +635,11 @@ export function registerConfiguredPaymentTopicIngestion(
engagementAssessment: conversationContext.engagement engagementAssessment: conversationContext.engagement
}) })
options.logger?.info(
{ event: 'payment.topic_processor_result', result: processorResult },
'Topic processor finished'
)
// Handle processor failure - only if explicitly mentioned // Handle processor failure - only if explicitly mentioned
if (!processorResult) { if (!processorResult) {
if (conversationContext.explicitMention) { if (conversationContext.explicitMention) {

View File

@@ -2476,6 +2476,11 @@ export function registerConfiguredPurchaseTopicIngestion(
engagementAssessment: conversationContext.engagement engagementAssessment: conversationContext.engagement
}) })
options.logger?.info(
{ event: 'purchase.topic_processor_result', result: processorResult },
'Topic processor finished'
)
// Handle processor failure - fun "bot sleeps" message only if explicitly mentioned // Handle processor failure - fun "bot sleeps" message only if explicitly mentioned
if (!processorResult) { if (!processorResult) {
if (conversationContext.explicitMention) { if (conversationContext.explicitMention) {

View File

@@ -390,6 +390,14 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
}) })
if (!response.ok) { if (!response.ok) {
logger?.error(
{
event: 'topic_processor.api_error',
status: response.status,
text: await response.text()
},
'Topic processor API error'
)
return null return null
} }
@@ -398,6 +406,10 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
const parsed = parseJsonFromResponseText<OpenAiStructuredResult>(text ?? '') const parsed = parseJsonFromResponseText<OpenAiStructuredResult>(text ?? '')
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) { if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
logger?.error(
{ event: 'topic_processor.parse_error', text },
'Topic processor failed to parse response'
)
return null return null
} }
@@ -409,6 +421,10 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
switch (route) { switch (route) {
case 'silent': case 'silent':
logger?.error(
{ event: 'topic_processor.silent', reason },
'Topic processor decided silent'
)
return { route, reason } return { route, reason }
case 'chat_reply': { case 'chat_reply': {
@@ -417,6 +433,10 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
? parsed.replyText.trim() ? parsed.replyText.trim()
: null : null
if (!replyText) { if (!replyText) {
logger?.error(
{ event: 'topic_processor.empty_chat_reply', reason },
'Topic processor returned empty chat reply'
)
return { route: 'silent', reason: 'empty_chat_reply' } return { route: 'silent', reason: 'empty_chat_reply' }
} }
return { route, replyText, reason } return { route, replyText, reason }
@@ -431,6 +451,15 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
: null : null
if (!amountMinor || !currency || !itemDescription) { if (!amountMinor || !currency || !itemDescription) {
logger?.error(
{
event: 'topic_processor.missing_purchase_fields',
amountMinor: parsed.amountMinor,
currency: parsed.currency,
itemDescription: parsed.itemDescription
},
'Topic processor missing purchase fields'
)
return { return {
route: 'purchase_clarification', route: 'purchase_clarification',
clarificationQuestion: 'Could you clarify the purchase details?', clarificationQuestion: 'Could you clarify the purchase details?',
@@ -476,6 +505,15 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
const kind = parsed.kind === 'rent' || parsed.kind === 'utilities' ? parsed.kind : null const kind = parsed.kind === 'rent' || parsed.kind === 'utilities' ? parsed.kind : null
if (!amountMinor || !currency || !kind) { if (!amountMinor || !currency || !kind) {
logger?.error(
{
event: 'topic_processor.missing_payment_fields',
amountMinor: parsed.amountMinor,
currency: parsed.currency,
kind: parsed.kind
},
'Topic processor missing payment fields'
)
return { return {
route: 'payment_clarification', route: 'payment_clarification',
clarificationQuestion: 'Could you clarify the payment details?', clarificationQuestion: 'Could you clarify the payment details?',
@@ -505,6 +543,10 @@ If user dismisses ("не, забей", "cancel"), use dismiss_workflow.`
} }
default: default:
logger?.error(
{ event: 'topic_processor.unknown_route', route: parsed.route },
'Topic processor returned unknown route'
)
return { route: 'silent', reason: 'unknown_route' } return { route: 'silent', reason: 'unknown_route' }
} }
} catch (error) { } catch (error) {