declare module '@peopl-health/nexus' { // Core Types export interface MessageData { id?: string; messageId?: string; message_id?: string; from: string; code?: string; body?: string; message?: string; timestamp?: string | Date; createdAt?: string | Date; fileUrl?: string; fileType?: 'text' | 'image' | 'document' | 'audio' | 'video'; contentSid?: string; variables?: Record; interactive?: InteractiveData; media?: MediaData; command?: CommandData; keyword?: string; flow?: InteractiveData; type?: 'message' | 'interactive' | 'media' | 'command' | 'keyword' | 'flow' | 'empty'; } export function registerInteractiveRoute( prefix: string, handler: (tap: { code: string; payload: string | null; title: string | null; messageData: unknown }) => unknown ): void; export function clearInteractiveRoutes(): void; export interface InteractiveData { type: 'button' | 'list' | 'flow' | 'quick_reply'; payload?: string; title?: string; description?: string; data?: any; } export interface MediaData { url?: string; contentType?: string; filename?: string; type?: string; data?: any; } export interface CommandData { prefix: string; command: string; args: string[]; } export interface ScheduledMessage extends MessageData { sendTime: string | Date; timeZone?: string; } export interface ThreadData { code: string; assistantId: string; threadId: string; patientId?: string; runId?: string; nombre?: string; stopped?: boolean; pausedAt?: Date | null; nextSid?: string[]; createdAt: Date; } // Provider Configurations export interface TwilioConfig { accountSid: string; authToken: string; whatsappNumber: string; } export interface BaileysConfig { authState?: string; mongoUri?: string; userDbMongo?: string; } export interface StorageConfig { mongoUri: string; dbName: string; collections?: { messages?: string; interactions?: string; threads?: string; }; } export interface AssistantConfig { llmClient?: any; assistants?: Record; handlers?: { onRequiresAction?: (result: any, threadData: ThreadData) => Promise; onCompleted?: (result: any) => Promise; onFailed?: (result: any) => Promise; }; } export interface ParserConfig { commandPrefixes?: string[]; keywords?: (string | { pattern: string; flags?: string })[]; } // Handler Types export type MessageHandler = (messageData: MessageData, nexus: Nexus) => Promise; export type InteractiveHandler = (messageData: MessageData, nexus: Nexus) => Promise; export type MediaHandler = (messageData: MessageData, nexus: Nexus) => Promise; export type CommandHandler = (messageData: MessageData, nexus: Nexus) => Promise; export type KeywordHandler = (messageData: MessageData, nexus: Nexus) => Promise; export type FlowHandler = (messageData: MessageData, nexus: Nexus) => Promise; export interface MessageHandlers { onMessage?: MessageHandler; onInteractive?: InteractiveHandler; onMedia?: MediaHandler; onCommand?: CommandHandler; onKeyword?: KeywordHandler; onFlow?: FlowHandler; } export interface AssistantToolDefinition { name: string; description?: string; parameters?: any; handler: (args: any) => string | Promise; } export interface AssistantConfigDefinition { extends?: typeof BaseAssistant; create?: (this: BaseAssistant, code: string, context?: any) => Promise; tools?: Array string | Promise }>; setup?: (this: BaseAssistant, context: { assistantId: string; thread?: any; options?: any }) => void; } export interface IncomingPreprocessingPayload { code: string; context?: string; message: MessageData; [key: string]: any; } export class BaseAssistant { constructor(options?: { assistantId?: string; thread?: any; client?: any; tools?: Array string | Promise }>; setup?: (context: { assistantId: string; thread?: any; options?: any }) => void; status?: string; } | any); assistantId: string | null; thread: any; status: string; createdAt: Date; registerTool(definition: AssistantToolDefinition | string, schema?: any, handler?: (args: any) => string | Promise): void; getToolSchemas(): any[]; executeTool(name: string, args: any): Promise; getPreviousMessages(thread?: any): Promise>; createThread(code: string, context?: any): Promise; sendMessage(userId: string, message: string, options?: any): Promise; waitForCompletion(threadId: string, runId: string, opts?: { interval?: number; maxAttempts?: number }): Promise; create(code: string, context?: any): Promise; close(): Promise; setThread(thread: any): void; setReplies(replies: any): void; } // Event Types export interface NexusEventEnvelope { event: string; timestamp: number; data: T; } export interface MessageNewEventData { messageId: string; from: string; body: string; media: any | null; type: 'message' | 'interactive' | 'media'; raw?: { role?: string; replyRequested?: boolean }; } export interface MessageStatusEventData { messageId: string; to: string; status: 'queued' | 'sending' | 'sent' | 'delivered' | 'undelivered' | 'failed' | 'read'; errorCode: string | null; errorMessage: string | null; } export interface NexusEventMap { 'message:new': NexusEventEnvelope; 'message:status': NexusEventEnvelope; } export type NexusEventName = keyof NexusEventMap; // Core Classes export abstract class MessageProvider { constructor(config: any); abstract initialize(): Promise; abstract sendMessage(messageData: MessageData): Promise; abstract getConnectionStatus(): boolean; abstract disconnect(): Promise; } export function registerAssistant( assistantId: string, definition: typeof BaseAssistant | ((thread?: any) => any) | AssistantConfigDefinition ): any; export function overrideGetAssistantById(resolver: (assistantId: string, thread?: any) => any): void; export function configureAssistants(config: any): void; export interface PreprocessingOpsAlert { label: string; summary: string; } export interface PreprocessingResult { handled?: boolean; alert?: true | PreprocessingOpsAlert; } export function setPreprocessingHandler( handler: (payload: IncomingPreprocessingPayload) => any | Promise ): void; export function hasPreprocessingHandler(): boolean; export function invokePreprocessingHandler( payload: IncomingPreprocessingPayload ): Promise; export class TwilioProvider extends MessageProvider { constructor(config: TwilioConfig); initialize(): Promise; sendMessage(messageData: MessageData): Promise; getConnectionStatus(): boolean; disconnect(): Promise; } export class BaileysProvider extends MessageProvider { constructor(config: BaileysConfig); initialize(): Promise; sendMessage(messageData: MessageData): Promise; getConnectionStatus(): boolean; disconnect(): Promise; } export class NexusMessaging { constructor(config?: NexusMessagingConfig); initializeProvider(providerType: 'twilio' | 'baileys', providerConfig: TwilioConfig | BaileysConfig): Promise; setMessageStorage(storage: any): void; setHandlers(handlers: MessageHandlers): void; sendMessage(messageData: MessageData): Promise; sendScheduledMessage(scheduledMessage: ScheduledMessage): Promise; processIncomingMessage(messageData: MessageData & { type: NonNullable }, options?: IncomingMessageOptions): Promise; getEventBus(): import('events').EventEmitter; getBatchingManager(): BatchingManager; getPipeline(): ProcessingPipeline; getAssistantProcessor(): AssistantProcessor; getLlmMonitor(): { start(options?: { scheduleDaily?: boolean }): Promise<{ enabled: boolean }> } | null; initializeLlmMonitor(): Promise<{ enabled: boolean; error?: string } | undefined>; processInstruction(code: string, instruction: string, role?: string, options?: { triggeredBy?: string }): Promise; processSystemMessage(code: string, messages: string | string[], role?: string, options?: { triggeredBy?: string; reply?: boolean }): Promise; processOutreach(code: string, options?: { brief?: OutreachBrief | null; triggeredBy?: string | null; reason?: string | null; firstName?: string | null; dryRun?: boolean }): Promise; processScheduledFollowUp(code: string, options: { reminderId: string; firstName: string; now?: Date }): Promise; isConnected(): boolean; shutdown(options?: ShutdownOptions): Promise; disconnect(options?: ShutdownOptions): Promise; } export class MongoStorage { constructor(config: StorageConfig); connect(): Promise; saveMessage(messageData: MessageData): Promise; saveInteractive(interactionData: any): Promise; getMessages(numero: string, limit?: number): Promise; getThread(code: string): Promise; createThread(threadData: ThreadData): Promise; updateThread(code: string, updateData: Partial): Promise; disconnect(): Promise; } export class MessageParser { constructor(config?: ParserConfig); parseMessage(rawMessage: any): MessageData; updateConfig(newConfig: ParserConfig): void; } // LLM Providers export class OpenAIResponsesProvider { constructor(options?: { apiKey?: string; organization?: string; client?: any; defaultModels?: Record; conversationManager?: any }); getVariant(): string; getClient(): any; executeRun(options: { thread: any; assistant: any; message?: string; tools?: any[]; config?: any }): Promise; runConversation(config?: any): Promise; transcribeAudio(options?: any): Promise; } export class GatewayProvider { constructor(options?: { conversationManager?: any; sessionManager?: any; [key: string]: any }); getVariant(): string; executeRun(options: { thread: any; assistant: any; message?: string; tools?: any[]; config?: any }): Promise; runConversation(config?: any): Promise; runStructured(params?: { promptId?: string; presetId?: string; variables?: any; input?: any[]; text?: any; metadata?: any }): Promise; } export interface LLMProvider { getVariant(): string; getClient?(): any; executeRun(options: { thread: any; assistant: any; message?: string; tools?: any[]; config?: any }): Promise; runConversation(config?: any): Promise; runStructured?(params?: { promptId?: string; presetId?: string; variables?: any; input?: any[]; text?: any; metadata?: any }): Promise; transcribeAudio?(options?: any): Promise; } export function createLLMProvider(config?: { variant?: string; [key: string]: any }): LLMProvider; // Main Nexus Class export interface NexusConfig { messaging?: NexusMessagingConfig; } export interface NerOptions { nerUrl?: string; nerApiKey?: string; nerTimeoutMs?: number; } export interface IncomingMessageOptions { /** Called with the saved message's id once it is persisted, before the turn runs. Not called when nothing was persisted. */ onSaved?: (messageId: string) => void | Promise; } export interface InitializeOptions { provider?: 'twilio' | 'baileys'; providerConfig?: TwilioConfig | BaileysConfig; storage?: 'mongo'; storageConfig?: StorageConfig; assistant?: AssistantConfig; parser?: boolean; parserConfig?: ParserConfig; ner?: NerOptions; recommendationRecovery?: RecommendationRecoveryOptions; inboundRecovery?: InboundRecoveryOptions; } export interface RecommendationRecoveryOptions { enabled: boolean; intervalMs?: number; } export interface InboundRecoveryOptions { enabled: boolean; intervalMs?: number; } export interface NerEntity { start: number; end: number; plaintext: string; label: string; score: number | null; } export class Nexus { constructor(config?: NexusConfig); initialize(options?: InitializeOptions): Promise; setHandlers(handlers: MessageHandlers): void; sendMessage(messageData: MessageData): Promise; sendScheduledMessage(scheduledMessage: ScheduledMessage): Promise; processScheduledFollowUp(code: string, options: { reminderId: string; firstName: string; now?: Date }): Promise; processMessage(rawMessage: any, options?: IncomingMessageOptions): Promise; isConnected(): boolean; beginDrain(): void; isDraining(): boolean; shutdown(options?: ShutdownOptions & { closeStorage?: boolean }): Promise; disconnect(options?: ShutdownOptions & { closeStorage?: boolean }): Promise; getMessaging(): NexusMessaging; getStorage(): MongoStorage | null; getMessageParser(): MessageParser | null; getLLMProvider(): LLMProvider | null; } // Utility Functions export function formatCode(codeBase: string): string; export function calculateDelay(sendTime: string | Date, timeZone?: string): number; export function ensureWhatsAppFormat(code: any): string | null; export function convertTwilioToInternalFormat(twilioMessage: any): any; export function getMediaTypeFromContentType(contentType: string): string; export function extractTitle(message: any, mediaType: string): string | null; export function useMongoDBAuthState(uri: string, dbName: string, sessionId: string): Promise; export const logger: any; export function requestIdMiddleware(req: any, res: any, next: () => void): void; export function getRequestId(): string | null; export function setModelDatabases(mapping: Record): void; export function setModelDatabase(modelName: string, dbName: string): void; export function getModelDatabase(modelName: string): string | null; export interface ContextSyncOptions { dryRun?: boolean; limit?: number; patientScope?: (patientId: string) => boolean; } export interface ContextSyncResult { ok: boolean; reason?: string; dryRun?: boolean; scanned?: number; planned?: number; written?: number; retracted?: number; failed?: number; advanced?: boolean; reconciling?: boolean; missingCreatedTime?: number; patients?: number; unreadable?: number; stats?: Record; watermark?: Date | null; } export interface ClinicalContextSyncResult { ok: boolean; facts: ContextSyncResult; legacy: ContextSyncResult | null; } export function syncContextFacts(options?: ContextSyncOptions): Promise; export function syncLegacyContext(options?: Omit): Promise; export function syncClinicalContext(options?: Omit): Promise; export interface OutreachBrief { reason?: string | null; lastTriageAt?: string | null; maxGrade?: number | null; positiveSymptoms?: string[]; lastInboundAt?: string | null; lastOutboundAt?: string | null; lastOutreach?: string | null; } export interface OutreachDecision { /** 'skipped' when the turn never ran — superseded, or dropped by a preProcess hook. */ decision: 'write' | 'hold' | 'skipped'; rationale: string; holdReason: string | null; nextCheckAt: string | null; /** Drafted patient-facing text. Present only on a dry run. */ draft?: string | null; /** Whether the provider accepted the fixed-template send. This is not proof of delivery. */ accepted?: boolean; /** Whether the provider status is already terminal delivered/read. */ delivered: boolean; deliveryStatus?: string | null; /** True only when downstream work remains queued. */ deferred?: boolean; turnId: string | null; traceId: string | null; } export interface ScheduledFollowUpResult { decision: 'write' | 'skipped'; holdReason: string | null; accepted: boolean; delivered: boolean; deliveryStatus?: string | null; deferred?: boolean; idempotent?: boolean; } export interface OutreachSweepResult { ran: boolean; weekday: number; mode?: 'continuity' | 'monday_triage_recovery'; targetDays?: string[]; dryRun?: boolean; counts: Record; rejectedBy?: Record; decisions?: Array>; } export function runProactiveOutreachSweep(options?: { now?: Date; dryRun?: boolean; limit?: number; concurrency?: number; patientScope?: string[] | null; /** Dry-run-only: replay rows already stamped by a prior sweep for clinician review. */ includePreviouslySwept?: boolean; /** continuity, or the Monday weekly-triage completion recovery lane. */ mode?: 'continuity' | 'monday_triage_recovery'; }): Promise; export const routes: any; export function setupDefaultRoutes(app: any): void; export function createRouter(routeDefinitions: Record, controllers: Record): any; // Queue Adapters export interface QueueJobOptions { jobId?: string; priority?: number; delay?: number; attempts?: number; backoff?: { type: 'fixed' | 'exponential'; delay: number }; repeat?: { cron: string; tz?: string }; } export interface QueueJobStatus { status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'not_found'; result?: any; error?: string; } export abstract class QueueAdapter { readonly supportsRepeat: boolean; constructor(config?: any); abstract enqueue(jobType: string, payload: any, options?: QueueJobOptions): Promise; abstract process(jobType: string, handler: (payload: any) => Promise): Promise; abstract getJobStatus(jobId: string): Promise; abstract cancelJob(jobId: string): Promise; abstract waitForResult(jobId: string, timeout?: number): Promise; abstract shutdown(): Promise; } export class LocalQueueAdapter extends QueueAdapter { constructor(config?: any); enqueue(jobType: string, payload: any, options?: QueueJobOptions): Promise; process(jobType: string, handler: (payload: any) => Promise): Promise; getJobStatus(jobId: string): Promise; cancelJob(jobId: string): Promise; waitForResult(jobId: string, timeout?: number): Promise; shutdown(): Promise; } export interface RedisQueueConfig { redis?: { host: string; port: number; password?: string }; defaultJobOptions?: QueueJobOptions; } export class RedisQueueAdapter extends QueueAdapter { constructor(config?: RedisQueueConfig); enqueue(jobType: string, payload: any, options?: QueueJobOptions): Promise; process(jobType: string, handler: (payload: any) => Promise): Promise; getJobStatus(jobId: string): Promise; cancelJob(jobId: string): Promise; waitForResult(jobId: string, timeout?: number): Promise; shutdown(): Promise; } export function createQueueAdapter(type: 'local' | 'redis' | string, config?: any): QueueAdapter; export function registerQueueAdapter(name: string, AdapterClass: typeof QueueAdapter): void; // Workflows export interface Workflow { kind: string; dedupeKey: (trigger: any) => string; prepare: (trigger: any) => Promise; } export interface WorkflowRunner { register(workflow: Workflow): Promise; enqueue(kind: string, trigger: any, options?: QueueJobOptions): Promise; } export function createWorkflowRunner(options: { queueAdapter: QueueAdapter }): WorkflowRunner; // Memory System export interface PatientMemoryDocument { _id: any; numero: string; category: 'preference' | 'emotional_pattern' | 'family_context' | 'life_event' | 'communication_style' | 'clinical_preference' | 'other'; content: string; confidence: number; source_session_id: string | null; active: boolean; last_reinforced_at: Date; reinforcement_count: number; createdAt: Date; updatedAt: Date; } export interface ConversationSummaryDocument { _id: any; numero: string; session_id: string; summary: string; topics: string[]; message_count: number; session_start: Date; session_end: Date; memories_extracted: number; createdAt: Date; updatedAt: Date; } export interface ClinicalDataResult { clinicalContext: string; lastSymptoms: string; patientMemories?: string; conversationSummaries?: string; } export class MemoryManager { constructor(options?: { memorySystem?: any }); buildContext(params: { thread: any; message?: any; config?: any }): Promise; processResponse(response: any, thread: any, config?: any): Promise; setMemorySystem(memorySystem: any): void; getMemorySystem(): any; optimizeContextWindow(messages: any[], maxTokens?: number): any[]; } export class DefaultMemoryManager extends MemoryManager { constructor(options?: { memorySystem?: any }); getClinicalData(whatsappId: string): Promise; handlePendingFunctionCalls(assistant: any, conversationMessages: any[], toolMetadata?: any): Promise<{ outputs: any[]; toolsExecuted: any[] }>; } export class EnhancedMemoryManager extends MemoryManager { constructor(options?: { memorySystem?: any }); getClinicalData(whatsappId: string): Promise; handlePendingFunctionCalls(assistant: any, conversationMessages: any[], toolMetadata?: any): Promise<{ outputs: any[]; toolsExecuted: any[] }>; } export interface MapCacheOptions { maxSize?: number; ttl?: number | null; } export class MapCache { constructor(options?: MapCacheOptions); get(key: any): V | undefined; getEntry(key: any): { value: V; timestamp: number } | null; set(key: any, value: V): void; has(key: any): boolean; delete(key: any): void; clear(): void; readonly size: number; entries(): Array<[string, V]>; } export interface SessionEndResult { summary: any | null; memoriesCreated: number; memoriesReinforced: number; } export interface BackfillResult { sessionsProcessed: number; totalMemories: number; totalSummaries: number; } export class MemoryExtractor { constructor(options?: { client?: any; model?: string; maxSummaryTokens?: number; maxMemoryTokens?: number }); generateSummary(messages: any[]): Promise<{ summary: string; topics: string[] } | null>; extractMemories(messages: any[], existingMemories?: any[]): Promise<{ new_memories: any[]; reinforced_memory_indices: number[] }>; processSessionEnd(numero: string, sessionMessages: any[], sessionId: string): Promise; backfillForPatient(numero: string): Promise; backfillAll(options?: { minMessages?: number; skipExisting?: boolean; onProgress?: (progress: { index: number; total: number; numero: string; skipped?: boolean; existing?: number; result?: BackfillResult; error?: string; }) => void; }): Promise<{ patientsProcessed: number; patientsSkipped: number; totalSessions: number; totalMemories: number; totalSummaries: number; errors: number; }>; } export class SessionManager { constructor(options?: { extractor?: MemoryExtractor; client?: any; model?: string }); recordActivity(numero: string): void; processSessionEndForNumero(numero: string): Promise; getActiveSession(numero: string): { lastActivity: number; sessionId: string; sessionStart: number } | null; getActiveSessionCount(): number; shutdown(): void; } export function getPatientMemory(): any; export function getConversationSummary(): any; export type SupportService = 'nutrition' | 'psychology'; export type SupportDisposition = 'group' | 'individual' | 'escalated' | 'reviewRequired' | 'none'; export type SupportPriority = 'routine' | 'soon' | 'urgent'; export type SupportInvitationClass = 'first' | 'followup'; export type SupportDeliveryStatus = 'sent' | 'delivered' | 'read' | 'failed' | 'unknown'; export type SupportEngagementState = 'notInvited' | 'invited' | 'registered' | 'attended' | 'declined'; export interface SupportEvidenceInput { source: 'triage' | 'chat' | 'fhir' | 'airtable'; sourceId: string; code: string; summary?: string | null; confidence?: number | null; } export interface SupportEvidence extends SupportEvidenceInput { key?: string; summary: string | null; confidence: number | null; } export interface SupportSafety { suicidalIdeation?: boolean; immediateRisk?: boolean; urgentMedicalRisk?: boolean; needsHumanConfirmation?: boolean; } export interface SupportRoutingDecisionBaseInput { disposition: SupportDisposition; groupEligible: boolean; priority?: SupportPriority; confidence: number; reasonCodes?: string[]; evidence: SupportEvidenceInput[]; safety: SupportSafety; } export type SupportRoutingDecisionInput = SupportRoutingDecisionBaseInput & ({ service: 'nutrition'; nutritionRisk: 'green' | 'yellow' | 'red' | 'unknown'; urgentIntakeEligible: boolean; } | { service: 'psychology'; psychologyRisk: 'green' | 'orange' | 'red' | 'unknown'; }); export interface SupportRoutingRecommendationInput { schemaVersion?: string; decisionVersion?: string; patientId: string; origin: 'triage' | 'chat' | 'fhir'; sourceId: string; createdAt: string; decisions: SupportRoutingDecisionInput[]; } export interface SupportCandidateRecord { candidateId: string; patientId: string; service: SupportService; disposition: SupportDisposition; groupEligible: boolean; urgentIntakeEligible: boolean; priority: SupportPriority; confidence?: number; nutritionRisk?: 'green' | 'yellow' | 'red' | 'unknown' | null; psychologyRisk?: 'green' | 'orange' | 'red' | 'unknown' | null; reasonCodes?: string[]; evidence?: SupportEvidence[]; sourceEventIds?: string[]; activeInvitationKey?: string | null; cooldownInvitationKey?: string | null; revision?: number; [key: string]: unknown; } export interface SupportActionRecord { candidateId: string; service: SupportService; type: 'group_registration' | 'urgent_nutrition_intake'; invitationClass: SupportInvitationClass | null; idempotencyKey?: string | null; targetKey: string; priority: SupportPriority; } export interface SupportActionResult { schemaVersion: '1'; patientId: string; sourceId: string; actions: SupportActionRecord[]; } export interface SupportDeliveryContext { invitationClassByService?: Partial>; targetKeyByService?: Partial>; attendanceEvidenceByService?: Partial>; } export interface SupportDashboardMetric { records: Array>; indicator: number; sample: number; total: number; struct: string[]; } export interface SupportDashboardSnapshot { generatedAt: string; metrics: { exceptions: SupportDashboardMetric }; } export type SupportDashboardCandidateRecord = Pick & Partial; export function registerDashboardProvider( source: 'auna.support.v1', provider: (context: { now: Date }) => SupportDashboardSnapshot | Promise ): void; export const supportCandidateService: { updateSupportOperationalReview(request: { patientId: string; service: SupportService; reasonCode: 'classification_failed' | 'attendance_unavailable' | 'safety_unconfirmed' | 'classification_safety_unconfirmed' | 'invitation_claim_failed'; sourceId: string; resolved?: boolean; noClinicalDecision?: boolean; now?: Date; }, options?: { Model?: unknown }): Promise; readSupportDashboardCandidates(): Promise; approveCandidate(candidateId: string, options: { reviewedRevision: number; reviewedRisk: 'green' | 'yellow'; Model?: unknown; }): Promise; candidatePatch(existing: SupportCandidateRecord | null | undefined, recommendation: SupportRoutingRecommendationInput, decision: SupportRoutingDecisionInput): Partial; claimInvitation(request: { candidateId: string; invitationClass: SupportInvitationClass; invitationCycle: string; templateVersion: string; now?: Date; }, options?: { Model?: unknown }): Promise; clearCandidateEscalation(candidateId: string, options: { reviewedRevision: number; approvedForGroup?: boolean; reviewedRisk?: 'green' | 'yellow'; Model?: unknown; }): Promise; evidenceKey(item: Pick): string; initialState(decision: SupportRoutingDecisionInput): SupportDisposition; markCandidateAccepted(request: { patientId: string; service: SupportService; sessionId?: string | null }, options?: { Model?: unknown }): Promise; markCandidateDeclined(request: { patientId: string; service: SupportService; preference?: 'another_date' | 'not_now' | 'never' }, options?: { Model?: unknown }): Promise; nextState(existing: SupportCandidateRecord | null | undefined, decision: SupportRoutingDecisionInput): SupportDisposition; normalizeEvidence(items?: SupportEvidenceInput[]): Array; recordEngagement(request: { patientId: string; service: SupportService; state: SupportEngagementState; evidenceId?: string | null; occurredAt?: string | Date | null; preference?: 'another_date' | 'not_now' | 'never' | null; }, options?: { Model?: unknown; historicalAttendance?: boolean }): Promise; recordLegacyInvitationResponse(request: { patientId: string; service: SupportService; outcome: 'accepted' | 'declined'; sessionId?: string | null; preference?: 'another_date' | 'not_now' | 'never'; }, options?: { Model?: unknown }): Promise; recordSentInvitationResponse(request: { patientId: string; service: SupportService; outcome: 'accepted' | 'declined'; sessionId?: string | null; preference?: 'another_date' | 'not_now' | 'never'; }, options?: { Model?: unknown }): Promise; recordSupportRoutingRecommendation(recommendation: SupportRoutingRecommendationInput, options?: { Model?: unknown }): Promise; rescheduleDeclinedCandidate(candidateId: string, options?: { Model?: unknown }): Promise; settleInvitation(request: { candidateId: string; idempotencyKey: string; status: SupportDeliveryStatus; providerMessageId?: string | null; error?: string | null; now?: Date; }, options?: { Model?: unknown }): Promise; }; export const supportActionService: { prepareSupportAction(request: { patientId: string; sourceId: string; candidates?: SupportCandidateRecord[]; resolveDeliveryContext?: (context: { patientId: string; candidates: SupportCandidateRecord[]; }) => SupportDeliveryContext | Promise; now?: Date; }, options?: { Model?: unknown }): Promise; }; // BatchingManager — per-chatId concurrency control export interface BatchingConfig { enabled?: boolean; abortOnNewMessage?: boolean; immediateRestart?: boolean; typingIndicator?: boolean; hooks?: Record; } export type NutritionSafetyFindingCode = | 'cannot_eat' | 'cannot_keep_fluids' | 'bleeding' | 'severe_abdominal_pain'; export type NutritionSafetyFindingValue = 'yes' | 'no' | 'unknown'; export type NutritionSafetyQuestionCode = | 'can_eat' | 'can_keep_fluids' | 'bleeding' | 'severe_abdominal_pain'; export type NutritionSafetyEvidenceSourceType = 'chat' | 'flow' | 'historical' | 'forecast'; export type NutritionSafetyDisposition = 'clear' | 'clarify' | 'escalate' | 'review_required'; export interface NutritionSafetyEvidenceRefInput { finding: NutritionSafetyFindingCode; source_type: NutritionSafetyEvidenceSourceType; source_id: string; observed_at: string; } export interface NutritionSafetyEvidenceRef { finding: NutritionSafetyFindingCode; sourceType: NutritionSafetyEvidenceSourceType; sourceId: string; observedAt: string; traceId?: string; } export interface NutritionSafetyDecisionInput { submission_revision: number; screen_revision: number; findings: Record; evidence_refs: NutritionSafetyEvidenceRefInput[]; questions_needed: NutritionSafetyQuestionCode[]; disposition: NutritionSafetyDisposition; } export class NutritionSafetyDecision { constructor(payload: NutritionSafetyDecisionInput); submissionRevision: number; screenRevision: number; findings: Record; evidenceRefs: NutritionSafetyEvidenceRef[]; questionsNeeded: NutritionSafetyQuestionCode[]; disposition: NutritionSafetyDisposition; } export interface NutritionSafetyDeliveryDirective { operationId: string; body: string; } export interface NutritionSafetyCommitRequest { decision: NutritionSafetyDecision; patientCode: string; turnId: string; traceId: string; sourceId: string; observedAt: string; } export interface NutritionSafetyCommitResult { outcome: string; status?: string; screen?: { status: string; [key: string]: any }; questionsNeeded?: NutritionSafetyQuestionCode[]; questions_needed?: NutritionSafetyQuestionCode[]; deliveryDirective?: NutritionSafetyDeliveryDirective; } export interface NutritionSafetyRepository { commitDecision(request: NutritionSafetyCommitRequest): Promise; claimDelivery?(request: { operationId: string; patientCode: string; turnId: string; traceId: string | null; sourceId: string | null; }): Promise<{ acquired: boolean }>; settleDelivery?(request: { operationId: string; outcome: 'sent' | 'known_not_sent' | 'unknown'; providerMessageId: string | null; patientCode: string; turnId: string | null; traceId: string | null; }): Promise; } export interface ToolRuntimeRepositories { nutritionSafety?: NutritionSafetyRepository; [key: string]: any; } export const FINDING_CODES: readonly NutritionSafetyFindingCode[]; export const FINDING_VALUES: readonly NutritionSafetyFindingValue[]; export const FINDING_TO_QUESTION: Readonly>; export const QUESTION_CODES: readonly NutritionSafetyQuestionCode[]; export const EVIDENCE_SOURCE_TYPES: readonly NutritionSafetyEvidenceSourceType[]; export const DISPOSITIONS: readonly NutritionSafetyDisposition[]; export interface NexusMessagingConfig { messageBatching?: BatchingConfig; assistant?: { mode?: 'local' | 'queue'; toolRuntimeRepos?: ToolRuntimeRepositories; [key: string]: any; }; [key: string]: any; } export interface DrainResult { drained: boolean; waitedMs: number; abandoned: Array<{ chatId: string | null; runId: string }>; } export interface TurnAdmission { accepted: boolean; reason?: string; } export interface ShutdownOptions { drainMs?: number; abortGraceMs?: number; teardownMs?: number; sweepStopMs?: number; closeStorage?: boolean; } export class DrainingError extends Error { constructor(chatId: string); code: 'draining'; } export class BatchingManager { constructor(options: { provider?: MessageProvider; config?: BatchingConfig; }); setProvider(provider: MessageProvider): void; isProcessing(chatId: string): boolean; isActiveRun(chatId: string, runId: string): boolean; isDraining(): boolean; getAbortSignal(runId: string): AbortSignal | undefined; drain(options?: { timeoutMs?: number; abortGraceMs?: number }): Promise; handleBatchedProcessing( chatId: string, processingFn: (runId: string) => Promise, sendResponseFn: (result: any) => Promise, discardResponseFn?: (result: any) => Promise ): Promise; enqueueProcessing( chatId: string, processingFn: (runId: string) => Promise, sendResponseFn: (result: any) => Promise, discardResponseFn?: (result: any) => Promise ): Promise; } // ProcessingPipeline — hook lifecycle for all LLM operations export interface PreProcessResult { skip?: boolean; additionalInstructions?: string; additionalMessages?: Array>; toolChoice?: string | Record | null; /** Registered tool ids to add for this turn only. Invalid ids are ignored and the list is capped at eight. */ additionalToolIds?: string[]; /** Recorded on the turn trace under `signals.consumer`; cannot collide with nexus-owned keys. */ signals?: Record; metadata?: Record; } export interface ProcessingContext { chatId: string; runId: string; type: string; metadata?: Record; } export class ProcessingPipeline { constructor(hooks?: Record); addHook(name: string, fn: Function): this; run( context: ProcessingContext, executeFn: (preProcessResult: PreProcessResult, shouldContinue: () => boolean) => Promise, shouldContinue?: () => boolean, discardResult?: (result: any) => Promise ): Promise; } // AssistantProcessor export type ClinicalTurnKind = 'patient' | 'operator_instruction' | 'system' | 'proactive_outreach' | 'unknown'; export interface AssistantRunOptions { [key: string]: any; turnKind?: ClinicalTurnKind; } export interface AssistantProcessorConfig { mode?: 'local' | 'queue'; queueAdapter?: QueueAdapter; sendMessage?: (messageData: MessageData) => Promise; storeRunMetrics?: (code: string, thread: any, result: any, timings?: Record) => Promise; llmMonitor?: { enqueueTurn(turnId: string): Promise } | null; toolRuntimeRepos?: ToolRuntimeRepositories; } export interface ProcessInput { code: string; runOptions?: AssistantRunOptions; message?: any | null; } export interface LLMResult { output: string; tools_executed?: any[]; prompt?: string | null; preset?: string | null; response_id?: string | null; turnId?: string | null; traceId?: string | null; run?: any; predictionTimeMs?: number; retries?: number; completed?: boolean; /** Internal delivery ownership receipt; never contains the directive body. */ deliveryDirective?: { operationId: string; claimed: boolean; settled: boolean }; } export class AssistantProcessor { constructor(config: AssistantProcessorConfig); setSendMessage(fn: AssistantProcessorConfig['sendMessage']): void; resolveThread(code: string): Promise<{ thread: any; assistant: any } | null>; executeLLM(thread: any, assistant: any, runOptions?: AssistantRunOptions, message?: any): Promise; process(input: ProcessInput): Promise; sendResponse(code: string, result: any): Promise; discardResponse(code: string, result: any): Promise; } }