@@ -1539,10 +1539,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
15391539
15401540 await dispatchWithContext ( { context : createContext ( ) } ) ;
15411541
1542- expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith (
1543- 1 ,
1544- expect . stringMatching ( / ` 🛠 ️ E x e c ` $ / ) ,
1545- ) ;
1542+ expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , "Cracking\n\n`🛠️ Exec`" ) ;
15461543 expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 2 , "Branch is up to date" ) ;
15471544 expect ( answerDraftStream . forceNewMessage ) . toHaveBeenCalledTimes ( 1 ) ;
15481545 expect ( answerDraftStream . clear ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -1574,8 +1571,8 @@ describe("dispatchTelegramMessage draft streaming", () => {
15741571 expect ( rotationOrder ) . toBeLessThan ( finalUpdateOrder ) ;
15751572 } ) ;
15761573
1577- it ( "keeps progress updates in a draft and sends the final answer normally" , async ( ) => {
1578- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1574+ it ( "sends progress updates as durable messages and sends the final answer normally" , async ( ) => {
1575+ setupDraftStreams ( { answerMessageId : 2001 } ) ;
15791576 dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
15801577 async ( { dispatcherOptions, replyOptions } ) => {
15811578 await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
@@ -1595,18 +1592,15 @@ describe("dispatchTelegramMessage draft streaming", () => {
15951592 telegramCfg : { streaming : { mode : "progress" } } ,
15961593 } ) ;
15971594
1598- expect ( answerDraftStream . update ) . toHaveBeenCalledWith (
1599- "Cracking\n\n`🛠️ Exec`\n`🛠️ git rev-parse --abbrev-ref HEAD`" ,
1600- ) ;
1601- expect ( answerDraftStream . update ) . not . toHaveBeenCalledWith ( "Branch is up to date" ) ;
1602- expect ( answerDraftStream . forceNewMessage ) . toHaveBeenCalledTimes ( 1 ) ;
1603- expect ( answerDraftStream . clear ) . toHaveBeenCalledTimes ( 1 ) ;
1604- expectDeliveredReply ( 0 , { text : "Branch is up to date" } ) ;
1595+ expect ( createTelegramDraftStream ) . not . toHaveBeenCalled ( ) ;
1596+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "Exec" ) } , 0 ) ;
1597+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "git rev-parse" ) } , 1 ) ;
1598+ expectDeliveredReply ( 0 , { text : "Branch is up to date" } , 2 ) ;
16051599 expect ( editMessageTelegram ) . not . toHaveBeenCalled ( ) ;
16061600 } ) ;
16071601
1608- it ( "does not restart progress drafts after final answer delivery" , async ( ) => {
1609- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1602+ it ( "does not send more standalone progress after final answer delivery" , async ( ) => {
1603+ setupDraftStreams ( { answerMessageId : 2001 } ) ;
16101604 dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
16111605 async ( { dispatcherOptions, replyOptions } ) => {
16121606 await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
@@ -1622,9 +1616,10 @@ describe("dispatchTelegramMessage draft streaming", () => {
16221616 telegramCfg : { streaming : { mode : "progress" , progress : { label : "Shelling" } } } ,
16231617 } ) ;
16241618
1625- expect ( answerDraftStream . update ) . toHaveBeenCalledTimes ( 1 ) ;
1626- expect ( answerDraftStream . update ) . toHaveBeenCalledWith ( "Shelling\n\n`🛠️ Exec`" ) ;
1627- expectDeliveredReply ( 0 , { text : "Branch is up to date" } ) ;
1619+ expect ( createTelegramDraftStream ) . not . toHaveBeenCalled ( ) ;
1620+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "Exec" ) } , 0 ) ;
1621+ expectDeliveredReply ( 0 , { text : "Branch is up to date" } , 1 ) ;
1622+ expect ( deliverReplies ) . toHaveBeenCalledTimes ( 2 ) ;
16281623 } ) ;
16291624
16301625 it ( "uses the transcript final when progress-mode final text is truncated" , async ( ) => {
@@ -1656,7 +1651,8 @@ describe("dispatchTelegramMessage draft streaming", () => {
16561651 telegramCfg : { streaming : { mode : "progress" } } ,
16571652 } ) ;
16581653
1659- expectDeliveredReply ( 0 , { text : fullAnswer } ) ;
1654+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "Exec" ) } , 0 ) ;
1655+ expectDeliveredReply ( 0 , { text : fullAnswer } , 1 ) ;
16601656 } ) ;
16611657
16621658 it ( "streams the first long final chunk and sends follow-up chunks" , async ( ) => {
@@ -1729,9 +1725,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
17291725 expectDeliveredReply ( 0 , { text : undefined , mediaUrl : "https://example.com/a.png" } ) ;
17301726 } ) ;
17311727
1732- it ( "shows Telegram progress drafts immediately for explicit tool starts" , async ( ) => {
1733- const draftStream = createSequencedDraftStream ( 2001 ) ;
1734- createTelegramDraftStream . mockReturnValue ( draftStream ) ;
1728+ it ( "sends Telegram progress immediately for explicit tool starts" , async ( ) => {
17351729 dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { replyOptions } ) => {
17361730 await replyOptions ?. onReplyStart ?.( ) ;
17371731 await replyOptions ?. onAssistantMessageStart ?.( ) ;
@@ -1745,13 +1739,11 @@ describe("dispatchTelegramMessage draft streaming", () => {
17451739 telegramCfg : { streaming : { mode : "progress" , progress : { label : "Shelling" } } } ,
17461740 } ) ;
17471741
1748- expect ( draftStream . update ) . toHaveBeenCalledWith ( "Shelling\n\n`🛠️ Exec`" ) ;
1749- expect ( draftStream . flush ) . toHaveBeenCalled ( ) ;
1742+ expect ( createTelegramDraftStream ) . not . toHaveBeenCalled ( ) ;
1743+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "Exec" ) } ) ;
17501744 } ) ;
17511745
1752- it ( "keeps the progress draft label when tool progress lines are hidden" , async ( ) => {
1753- const draftStream = createSequencedDraftStream ( 2001 ) ;
1754- createTelegramDraftStream . mockReturnValue ( draftStream ) ;
1746+ it ( "does not send standalone tool progress when progress lines are hidden" , async ( ) => {
17551747 dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { replyOptions } ) => {
17561748 await replyOptions ?. onReplyStart ?.( ) ;
17571749 await replyOptions ?. onAssistantMessageStart ?.( ) ;
@@ -1770,46 +1762,11 @@ describe("dispatchTelegramMessage draft streaming", () => {
17701762 } ,
17711763 } ) ;
17721764
1773- expect ( draftStream . update ) . toHaveBeenCalledWith ( "Shelling" ) ;
1774- expect ( draftStream . flush ) . toHaveBeenCalled ( ) ;
1775- } ) ;
1776-
1777- it ( "keeps progress draft labels static while the draft is active" , async ( ) => {
1778- const draftStream = createSequencedDraftStream ( 2001 ) ;
1779- createTelegramDraftStream . mockReturnValue ( draftStream ) ;
1780- let finishRun : ( ( ) => void ) | undefined ;
1781- dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { replyOptions } ) => {
1782- await replyOptions ?. onReplyStart ?.( ) ;
1783- await replyOptions ?. onAssistantMessageStart ?.( ) ;
1784- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
1785- await new Promise < void > ( ( resolve ) => {
1786- finishRun = resolve ;
1787- } ) ;
1788- return { queuedFinal : false } ;
1789- } ) ;
1790-
1791- const run = dispatchWithContext ( {
1792- context : createContext ( ) ,
1793- streamMode : "progress" ,
1794- telegramCfg : {
1795- streaming : {
1796- mode : "progress" ,
1797- progress : { label : "Working" , toolProgress : false } ,
1798- } ,
1799- } ,
1800- } ) ;
1801-
1802- await vi . waitFor ( ( ) => expect ( draftStream . update ) . toHaveBeenCalledWith ( "Working" ) ) ;
1803- expect ( draftStream . update ) . not . toHaveBeenCalledWith ( "Working." ) ;
1804- expect ( draftStream . update ) . not . toHaveBeenCalledWith ( "Working.." ) ;
1805- expect ( draftStream . update ) . not . toHaveBeenCalledWith ( "Working..." ) ;
1806- finishRun ?.( ) ;
1807- await run ;
1765+ expect ( createTelegramDraftStream ) . not . toHaveBeenCalled ( ) ;
1766+ expect ( deliverReplies ) . not . toHaveBeenCalled ( ) ;
18081767 } ) ;
18091768
1810- it ( "renders Telegram progress drafts before slow status reactions resolve" , async ( ) => {
1811- const draftStream = createSequencedDraftStream ( 2001 ) ;
1812- createTelegramDraftStream . mockReturnValue ( draftStream ) ;
1769+ it ( "sends Telegram progress before slow status reactions resolve" , async ( ) => {
18131770 let releaseSetTool : ( ( ) => void ) | undefined ;
18141771 const statusReactionController = createStatusReactionController ( ) ;
18151772 statusReactionController . setTool . mockImplementation (
@@ -1822,10 +1779,14 @@ describe("dispatchTelegramMessage draft streaming", () => {
18221779 const pendingToolStart = replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
18231780 await Promise . resolve ( ) ;
18241781 await Promise . resolve ( ) ;
1825- const updateBeforeStatusReaction = draftStream . update . mock . calls . at ( - 1 ) ?. [ 0 ] ;
1782+ const progressBeforeStatusReaction = deliverReplies . mock . calls . at ( - 1 ) ?. [ 0 ] ;
18261783 releaseSetTool ?.( ) ;
18271784 await pendingToolStart ;
1828- expect ( updateBeforeStatusReaction ) . toMatch ( / ^ S h e l l i n g \n ` 🛠 ️ E x e c ` $ / ) ;
1785+ expect ( progressBeforeStatusReaction ) . toEqual (
1786+ expect . objectContaining ( {
1787+ replies : [ expect . objectContaining ( { text : expect . stringContaining ( "Exec" ) } ) ] ,
1788+ } ) ,
1789+ ) ;
18291790 return { queuedFinal : false } ;
18301791 } ) ;
18311792
@@ -1840,9 +1801,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
18401801 expect ( statusReactionController . setTool ) . toHaveBeenCalledWith ( "exec" ) ;
18411802 } ) ;
18421803
1843- it ( "keeps non-command Telegram progress draft lines across post-tool assistant boundaries" , async ( ) => {
1844- const draftStream = createSequencedDraftStream ( 2001 ) ;
1845- createTelegramDraftStream . mockReturnValue ( draftStream ) ;
1804+ it ( "keeps non-command Telegram progress as durable messages across assistant boundaries" , async ( ) => {
18461805 dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
18471806 async ( { dispatcherOptions, replyOptions } ) => {
18481807 await replyOptions ?. onReplyStart ?.( ) ;
@@ -1861,13 +1820,10 @@ describe("dispatchTelegramMessage draft streaming", () => {
18611820 telegramCfg : { streaming : { mode : "progress" , progress : { label : "Shelling" } } } ,
18621821 } ) ;
18631822
1864- expect ( draftStream . update ) . toHaveBeenCalledWith (
1865- "Shelling\n\n`🔎 Web Search: docs lookup`\n• `tests passed`" ,
1866- ) ;
1867- expect ( draftStream . forceNewMessage ) . toHaveBeenCalledTimes ( 1 ) ;
1868- expect ( draftStream . materialize ) . not . toHaveBeenCalled ( ) ;
1869- expect ( draftStream . clear ) . toHaveBeenCalledTimes ( 1 ) ;
1870- expectDeliveredReply ( 0 , { text : "Final after tool" } ) ;
1823+ expect ( createTelegramDraftStream ) . not . toHaveBeenCalled ( ) ;
1824+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "docs lookup" ) } , 0 ) ;
1825+ expectDeliveredReply ( 0 , { text : expect . stringContaining ( "tests passed" ) } , 1 ) ;
1826+ expectDeliveredReply ( 0 , { text : "Final after tool" } , 2 ) ;
18711827 expect ( editMessageTelegram ) . not . toHaveBeenCalled ( ) ;
18721828 } ) ;
18731829
0 commit comments