11import {
2+ buildDefaultUserProfile ,
23 buildTelegramFollowUpIdempotencyKey ,
34 buildTelegramWebhookIdempotencyKey ,
4- type ConfirmedMutationRecoveryInput ,
5- type ConfirmedMutationRecoveryOutput ,
65 type ConversationEntity ,
76 type ConversationTurn ,
87 getAppBaseUrl ,
98 getConfig ,
109 getTelegramAllowedUserIds ,
11- isConfirmedMutationRecovered ,
1210 isTelegramUserAllowed ,
1311 normalizeTelegramUpdate ,
14- synthesizeMutationText ,
1512 type Task ,
1613 telegramUpdateSchema ,
1714} from "@atlas/core" ;
@@ -36,7 +33,6 @@ import {
3633 type ConversationMemorySummaryInput ,
3734 type ConversationMemorySummaryOutput ,
3835 editTelegramMessage ,
39- recoverConfirmedMutationWithResponses ,
4036 sendTelegramChatAction ,
4137 sendTelegramMessage ,
4238 summarizeConversationMemoryWithResponses ,
@@ -58,10 +54,8 @@ import {
5854 hasActiveGoogleCalendarConnection ,
5955} from "./google-calendar" ;
6056import { renderMutationReply } from "./mutation-reply" ;
61- import {
62- type ProcessInboxItemDependencies ,
63- processInboxItem ,
64- } from "./process-inbox-item" ;
57+ import { type ProcessInboxItemDependencies } from "./process-inbox-item" ;
58+ import { executePendingWrite } from "./execute-pending-write" ;
6559import { sendTelegramMessageWithPersistence } from "./telegram-webhook-transport" ;
6660import {
6761 doesPolicyAllowWrites ,
@@ -94,9 +88,6 @@ type TelegramWebhookDependencies = ProcessInboxItemDependencies & {
9488 conversationMemorySummarizer ?: (
9589 input : ConversationMemorySummaryInput ,
9690 ) => Promise < ConversationMemorySummaryOutput > ;
97- confirmedMutationRecoverer ?: (
98- input : ConfirmedMutationRecoveryInput ,
99- ) => Promise < ConfirmedMutationRecoveryOutput > ;
10091 googleCalendarConnectionChecker ?: ( userId : string ) => Promise < boolean > ;
10192 googleCalendarConnectLinkBuilder ?: ( input : {
10293 baseUrl : string ;
@@ -440,69 +431,24 @@ export async function handleTelegramWebhook(
440431 } ;
441432 }
442433
443- if ( routedWithContext . policy . action === "recover_and_execute" ) {
434+ if (
435+ routedWithContext . policy . action === "execute_mutation"
436+ ) {
444437 console . info ( "turn_execution_branch" , {
445438 userId : normalizedMessage . user . telegramUserId ,
446439 action : routedWithContext . policy . action ,
447440 } ) ;
448- const entityRegistry = conversationState ?. entityRegistry ?? [ ] ;
449- const proposalEntity = entityRegistry . find (
450- ( e ) : e is Extract < ConversationEntity , { kind : "proposal_option" } > =>
451- e . kind === "proposal_option" &&
452- e . id === routedWithContext . policy . targetProposalId ,
453- ) ;
454441
455- const synthesis = synthesizeMutationText ( {
456- resolvedFields :
457- routedWithContext . policy . resolvedOperation ?. resolvedFields ?? { } ,
458- targetEntityId : routedWithContext . policy . targetEntityId ,
459- proposalEntity,
460- entityRegistry,
461- } ) ;
462- console . info ( "turn_recovery_result" , {
463- userId : normalizedMessage . user . telegramUserId ,
464- action : routedWithContext . policy . action ,
465- outcome : synthesis . outcome ,
466- } ) ;
467-
468- if ( synthesis . outcome === "insufficient_data" ) {
469- const clarificationMessage =
470- "I need a bit more detail to proceed. What would you like me to schedule?" ;
471-
472- if ( conversationState ) {
473- await appendConversationTurn (
474- {
475- userId : normalizedMessage . user . telegramUserId ,
476- role : "assistant" ,
477- text : clarificationMessage ,
478- } ,
479- dependencies . conversationStateStore ,
480- ) ;
481- await saveConversationState (
482- {
483- userId : normalizedMessage . user . telegramUserId ,
484- ...deriveConversationReplyState ( {
485- snapshot : conversationState ,
486- policy : {
487- action : "ask_clarification" ,
488- resolvedOperation : routedWithContext . policy . resolvedOperation ,
489- } ,
490- interpretation : routedWithContext . interpretation ,
491- reply : clarificationMessage ,
492- userTurnText : normalizedMessage . rawText ,
493- summaryText : conversationState . conversation . summaryText ,
494- } ) ,
495- } ,
496- dependencies . conversationStateStore ,
497- ) ;
498- }
442+ await dependencies . primeProcessingStore ?.( ingress . inboxItem ) ;
499443
444+ const resolvedOperation = routedWithContext . policy . resolvedOperation ;
445+ if ( ! resolvedOperation ) {
500446 return replyWithText (
501447 {
502448 userId : normalizedMessage . user . telegramUserId ,
503449 chatId : normalizedMessage . chatId ,
504450 inboxItemId : ingress . inboxItem . id ,
505- text : clarificationMessage ,
451+ text : "I need a bit more detail to proceed." ,
506452 } ,
507453 {
508454 editor : dependencies . editor ?? editTelegramMessage ,
@@ -518,32 +464,29 @@ export async function handleTelegramWebhook(
518464 inboxItem : ingress . inboxItem ,
519465 turnRoute : compatibilityTurnRoute ,
520466 routing : routedWithContext ,
521- processing : {
522- outcome : "conversation_replied" ,
523- reply : clarificationMessage ,
524- } ,
467+ processing : { outcome : "needs_clarification" } ,
525468 } ,
526469 } ,
527470 ) ;
528471 }
529472
530- await dependencies . primeProcessingStore ?.( ingress . inboxItem ) ;
531-
532- const processing = await processInboxItem (
533- {
534- inboxItemId : ingress . inboxItem . id ,
535- planningInboxTextOverride : {
536- text : synthesis . text ,
537- } ,
538- } ,
539- {
540- ...( dependencies . store ? { store : dependencies . store } : { } ) ,
541- ...( dependencies . planner ? { planner : dependencies . planner } : { } ) ,
542- ...( dependencies . calendar !== undefined
543- ? { calendar : dependencies . calendar }
544- : { } ) ,
545- } ,
473+ const executionStore = dependencies . store ?? getDefaultInboxProcessingStore ( ) ;
474+ const executionContext = await executionStore . loadContext (
475+ ingress . inboxItem . id ,
546476 ) ;
477+
478+ const processing = await executePendingWrite ( {
479+ pendingWriteOperation : resolvedOperation ,
480+ userId : normalizedMessage . user . telegramUserId ,
481+ tasks : executionContext ?. tasks ?? [ ] ,
482+ scheduleBlocks : executionContext ?. scheduleBlocks ?? [ ] ,
483+ userProfile : executionContext ?. userProfile ?? buildDefaultUserProfile ( normalizedMessage . user . telegramUserId ) ,
484+ calendar : dependencies . calendar ?? null ,
485+ googleCalendarConnection :
486+ executionContext ?. googleCalendarConnection ?? null ,
487+ store : executionStore ,
488+ } ) ;
489+
547490 const outboundDelivery = await finalizeFollowUpMessage (
548491 {
549492 userId : normalizedMessage . user . telegramUserId ,
@@ -606,83 +549,9 @@ export async function handleTelegramWebhook(
606549 } ;
607550 }
608551
609- console . info ( "turn_execution_branch" , {
610- userId : normalizedMessage . user . telegramUserId ,
611- action : routedWithContext . policy . action ,
612- } ) ;
613- await dependencies . primeProcessingStore ?.( ingress . inboxItem ) ;
614-
615- const processing = await processInboxItem (
616- {
617- inboxItemId : ingress . inboxItem . id ,
618- } ,
619- {
620- ...( dependencies . store ? { store : dependencies . store } : { } ) ,
621- ...( dependencies . planner ? { planner : dependencies . planner } : { } ) ,
622- ...( dependencies . calendar !== undefined
623- ? { calendar : dependencies . calendar }
624- : { } ) ,
625- } ,
626- ) ;
627- const outboundDelivery = await finalizeFollowUpMessage (
628- {
629- userId : normalizedMessage . user . telegramUserId ,
630- chatId : normalizedMessage . chatId ,
631- inboxItemId : ingress . inboxItem . id ,
632- text : processing . followUpMessage ,
633- } ,
634- {
635- editor : dependencies . editor ?? editTelegramMessage ,
636- placeholderDelivery,
637- sender : dependencies . sender ?? sendTelegramMessage ,
638- ...( dependencies . deliveryStore
639- ? { deliveryStore : dependencies . deliveryStore }
640- : { } ) ,
641- } ,
642- ) ;
643- const followUpContinuation = await maybeSendOutstandingFollowUpContinuation (
644- {
645- userId : normalizedMessage . user . telegramUserId ,
646- chatId : normalizedMessage . chatId ,
647- inboxItemId : ingress . inboxItem . id ,
648- } ,
649- dependencies ,
650- ) ;
651-
652- if ( conversationState ) {
653- await appendConversationTurn (
654- {
655- userId : normalizedMessage . user . telegramUserId ,
656- role : "assistant" ,
657- text : processing . followUpMessage ,
658- } ,
659- dependencies . conversationStateStore ,
660- ) ;
661- await saveConversationState (
662- {
663- userId : normalizedMessage . user . telegramUserId ,
664- ...deriveMutationState ( {
665- snapshot : conversationState ,
666- processing,
667- } ) ,
668- } ,
669- dependencies . conversationStateStore ,
670- ) ;
671- }
672-
673552 return {
674- status : 200 ,
675- body : {
676- accepted : true ,
677- idempotencyKey,
678- ingestion : normalizedMessage ,
679- inboxItem : ingress . inboxItem ,
680- turnRoute : compatibilityTurnRoute ,
681- routing : routedWithContext ,
682- processing,
683- outboundDelivery,
684- followUpContinuation,
685- } ,
553+ status : 500 ,
554+ body : { accepted : false , error : "unhandled_policy_action" } ,
686555 } ;
687556}
688557
@@ -1043,23 +912,11 @@ async function tryHandleFollowUpReply(
1043912
1044913 const directStore = dependencies . store ?? getDefaultInboxProcessingStore ( ) ;
1045914 await dependencies . primeProcessingStore ?.( input . inboxItem ) ;
1046- const plannerRun = {
1047- userId : input . inboxItem . userId ,
1048- inboxItemId : input . inboxItem . id ,
1049- version : "followup-direct-v1" ,
1050- modelInput : {
1051- source : "followup_reply" ,
1052- text : input . normalizedMessage . normalizedText ,
1053- } ,
1054- modelOutput : parsed ,
1055- confidence : 1 ,
1056- } ;
1057915
1058916 if ( parsed . kind === "done" ) {
1059917 const processing = await directStore . saveTaskCompletionResult ( {
1060918 inboxItemId : input . inboxItem . id ,
1061919 confidence : 1 ,
1062- plannerRun,
1063920 taskIds : selectedTasks . map ( ( task ) => task . id ) ,
1064921 followUpMessage : "" ,
1065922 } ) ;
@@ -1089,7 +946,6 @@ async function tryHandleFollowUpReply(
1089946 const processing = await directStore . saveTaskArchiveResult ( {
1090947 inboxItemId : input . inboxItem . id ,
1091948 confidence : 1 ,
1092- plannerRun,
1093949 taskIds : selectedTasks . map ( ( task ) => task . id ) ,
1094950 followUpMessage : "" ,
1095951 } ) ;
@@ -1119,7 +975,6 @@ async function tryHandleFollowUpReply(
1119975 const processing = await directStore . saveNeedsClarificationResult ( {
1120976 inboxItemId : input . inboxItem . id ,
1121977 confidence : 1 ,
1122- plannerRun,
1123978 reason : "Follow-up reply needs explicit reschedule or archive decision." ,
1124979 followUpMessage :
1125980 "Noted. Tell me when you want to reschedule it, or say archive." ,
@@ -1364,8 +1219,6 @@ function getCompatibilityTurnRouteFromPolicy(
13641219 return "conversation_then_mutation" as const ;
13651220 case "execute_mutation" :
13661221 return "mutation" as const ;
1367- case "recover_and_execute" :
1368- return "confirmed_mutation" as const ;
13691222 }
13701223}
13711224
@@ -1378,11 +1231,6 @@ function buildImmediateRouteFeedback(
13781231 text : "Checking your schedule" ,
13791232 chatAction : "typing" ,
13801233 } ;
1381- case "recover_and_execute" :
1382- return {
1383- text : "Applying that" ,
1384- chatAction : "typing" ,
1385- } ;
13861234 case "reply_only" :
13871235 case "ask_clarification" :
13881236 case "present_proposal" :
0 commit comments