@@ -28,7 +28,6 @@ type DispatchReplyWithBufferedBlockDispatcherArgs = Parameters<
2828> [ 0 ] ;
2929
3030const createTelegramDraftStream = vi . hoisted ( ( ) => vi . fn ( ) ) ;
31- const createNativeTelegramToolProgressDraft = vi . hoisted ( ( ) => vi . fn ( ) ) ;
3231const dispatchReplyWithBufferedBlockDispatcher = vi . hoisted ( ( ) =>
3332 vi . fn < ( params : DispatchReplyWithBufferedBlockDispatcherArgs ) => Promise < unknown > > ( ) ,
3433) ;
@@ -221,8 +220,6 @@ const telegramDepsForTest: TelegramBotDeps = {
221220 wasSentByBot : wasSentByBot as TelegramBotDeps [ "wasSentByBot" ] ,
222221 createTelegramDraftStream :
223222 createTelegramDraftStream as TelegramBotDeps [ "createTelegramDraftStream" ] ,
224- createNativeTelegramToolProgressDraft :
225- createNativeTelegramToolProgressDraft as TelegramBotDeps [ "createNativeTelegramToolProgressDraft" ] ,
226223 deliverReplies : deliverReplies as TelegramBotDeps [ "deliverReplies" ] ,
227224 deliverInboundReplyWithMessageSendContext :
228225 deliverInboundReplyWithMessageSendContext as TelegramBotDeps [ "deliverInboundReplyWithMessageSendContext" ] ,
@@ -247,7 +244,6 @@ describe("dispatchTelegramMessage draft streaming", () => {
247244 installTelegramStateRuntimeForTest ( ) ;
248245 resetTelegramReplyFenceForTests ( ) ;
249246 createTelegramDraftStream . mockReset ( ) ;
250- createNativeTelegramToolProgressDraft . mockReset ( ) ;
251247 dispatchReplyWithBufferedBlockDispatcher . mockReset ( ) ;
252248 deliverReplies . mockReset ( ) ;
253249 deliverInboundReplyWithMessageSendContext . mockReset ( ) ;
@@ -352,10 +348,6 @@ describe("dispatchTelegramMessage draft streaming", () => {
352348 const createDraftStream = ( messageId ?: number ) => createTestDraftStream ( { messageId } ) ;
353349 const createSequencedDraftStream = ( startMessageId = 1001 ) =>
354350 createSequencedTestDraftStream ( startMessageId ) ;
355- const createNativeToolProgressDraft = ( updateResult = true ) => ( {
356- update : vi . fn ( async ( ) => updateResult ) ,
357- stop : vi . fn ( ) ,
358- } ) ;
359351
360352 function setupDraftStreams ( params ?: { answerMessageId ?: number ; reasoningMessageId ?: number } ) {
361353 const answerDraftStream = createDraftStream ( params ?. answerMessageId ) ;
@@ -1827,234 +1819,7 @@ describe("dispatchTelegramMessage draft streaming", () => {
18271819 expect ( deliverReplies ) . not . toHaveBeenCalled ( ) ;
18281820 } ) ;
18291821
1830- it ( "uses native DM drafts for transient tool progress before answer text" , async ( ) => {
1831- const nativeDraft = createNativeToolProgressDraft ( ) ;
1832- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1833- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1834- dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
1835- async ( { dispatcherOptions, replyOptions } ) => {
1836- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
1837- await replyOptions ?. onPartialReply ?.( { text : "Done " , delta : "Done " } ) ;
1838- await dispatcherOptions . deliver ( { text : "Done answer." } , { kind : "final" } ) ;
1839- return { queuedFinal : true } ;
1840- } ,
1841- ) ;
1842-
1843- await dispatchWithContext ( {
1844- context : createContext ( ) ,
1845- streamMode : "partial" ,
1846- telegramCfg : {
1847- streaming : {
1848- mode : "partial" ,
1849- preview : { nativeToolProgress : true , nativeToolProgressAllowFrom : [ "123" ] } ,
1850- } ,
1851- } ,
1852- } ) ;
1853-
1854- expect ( createNativeTelegramToolProgressDraft ) . toHaveBeenCalledWith (
1855- expect . objectContaining ( {
1856- chatId : 123 ,
1857- thread : { id : 777 , scope : "dm" } ,
1858- } ) ,
1859- ) ;
1860- expect ( nativeDraft . update ) . toHaveBeenCalledWith ( expect . stringContaining ( "Exec" ) ) ;
1861- expect ( nativeDraft . update ) . toHaveBeenCalledWith ( expect . not . stringContaining ( "`" ) ) ;
1862- expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , "Done " ) ;
1863- expect ( answerDraftStream . update ) . toHaveBeenLastCalledWith ( "Done answer." ) ;
1864- expect ( answerDraftStream . update ) . not . toHaveBeenCalledWith ( expect . stringContaining ( "Exec" ) ) ;
1865- expect ( nativeDraft . stop ) . toHaveBeenCalled ( ) ;
1866- } ) ;
1867-
1868- it ( "keeps native DM drafts off by default" , async ( ) => {
1869- const nativeDraft = createNativeToolProgressDraft ( ) ;
1870- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1871- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1872- dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
1873- async ( { dispatcherOptions, replyOptions } ) => {
1874- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
1875- await dispatcherOptions . deliver ( { text : "Done answer." } , { kind : "final" } ) ;
1876- return { queuedFinal : true } ;
1877- } ,
1878- ) ;
1879-
1880- await dispatchWithContext ( {
1881- context : createContext ( ) ,
1882- streamMode : "partial" ,
1883- telegramCfg : { streaming : { mode : "partial" } } ,
1884- } ) ;
1885-
1886- expect ( createNativeTelegramToolProgressDraft ) . not . toHaveBeenCalled ( ) ;
1887- expect ( nativeDraft . update ) . not . toHaveBeenCalled ( ) ;
1888- expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , expect . stringContaining ( "Exec" ) ) ;
1889- expect ( answerDraftStream . update ) . toHaveBeenLastCalledWith ( "Done answer." ) ;
1890- } ) ;
1891-
1892- it ( "honors the native DM draft allowlist" , async ( ) => {
1893- const nativeDraft = createNativeToolProgressDraft ( ) ;
1894- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1895- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1896- dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
1897- async ( { dispatcherOptions, replyOptions } ) => {
1898- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
1899- await dispatcherOptions . deliver ( { text : "Done answer." } , { kind : "final" } ) ;
1900- return { queuedFinal : true } ;
1901- } ,
1902- ) ;
1903-
1904- await dispatchWithContext ( {
1905- context : createContext ( ) ,
1906- streamMode : "partial" ,
1907- telegramCfg : {
1908- streaming : {
1909- mode : "partial" ,
1910- preview : {
1911- nativeToolProgress : true ,
1912- nativeToolProgressAllowFrom : [ "999" ] ,
1913- } ,
1914- } ,
1915- } ,
1916- } ) ;
1917-
1918- expect ( createNativeTelegramToolProgressDraft ) . not . toHaveBeenCalled ( ) ;
1919- expect ( nativeDraft . update ) . not . toHaveBeenCalled ( ) ;
1920- expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , expect . stringContaining ( "Exec" ) ) ;
1921- expect ( answerDraftStream . update ) . toHaveBeenLastCalledWith ( "Done answer." ) ;
1922- } ) ;
1923-
1924- it ( "falls back to edited preview tool progress when native DM draft update fails" , async ( ) => {
1925- const nativeDraft = createNativeToolProgressDraft ( false ) ;
1926- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1927- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1928- dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
1929- async ( { dispatcherOptions, replyOptions } ) => {
1930- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
1931- await dispatcherOptions . deliver ( { text : "Done answer." } , { kind : "final" } ) ;
1932- return { queuedFinal : true } ;
1933- } ,
1934- ) ;
1935-
1936- await dispatchWithContext ( {
1937- context : createContext ( ) ,
1938- streamMode : "partial" ,
1939- telegramCfg : {
1940- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
1941- } ,
1942- } ) ;
1943-
1944- expect ( nativeDraft . update ) . toHaveBeenCalledWith ( expect . stringContaining ( "Exec" ) ) ;
1945- expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , expect . stringContaining ( "Exec" ) ) ;
1946- expect ( answerDraftStream . update ) . toHaveBeenLastCalledWith ( "Done answer." ) ;
1947- } ) ;
1948-
1949- it ( "does not hide durable tool media in native DM drafts" , async ( ) => {
1950- const nativeDraft = createNativeToolProgressDraft ( ) ;
1951- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1952- setupDraftStreams ( { answerMessageId : 2001 } ) ;
1953- dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { dispatcherOptions } ) => {
1954- await dispatcherOptions . deliver (
1955- { text : "Rendered chart" , mediaUrl : "/tmp/chart.png" } ,
1956- { kind : "tool" } ,
1957- ) ;
1958- return { queuedFinal : true } ;
1959- } ) ;
1960-
1961- await dispatchWithContext ( {
1962- context : createContext ( ) ,
1963- streamMode : "partial" ,
1964- telegramCfg : {
1965- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
1966- } ,
1967- } ) ;
1968-
1969- expect ( nativeDraft . update ) . not . toHaveBeenCalled ( ) ;
1970- expectDeliveredReply ( 0 , { text : "Rendered chart" , mediaUrl : "/tmp/chart.png" } ) ;
1971- } ) ;
1972-
1973- it ( "does not hide durable tool errors in native DM drafts" , async ( ) => {
1974- const nativeDraft = createNativeToolProgressDraft ( ) ;
1975- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1976- setupDraftStreams ( { answerMessageId : 2001 } ) ;
1977- dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { dispatcherOptions } ) => {
1978- await dispatcherOptions . deliver ( { text : "Tool failed" , isError : true } , { kind : "tool" } ) ;
1979- return { queuedFinal : true } ;
1980- } ) ;
1981-
1982- await dispatchWithContext ( {
1983- context : createContext ( ) ,
1984- streamMode : "partial" ,
1985- telegramCfg : {
1986- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
1987- } ,
1988- } ) ;
1989-
1990- expect ( nativeDraft . update ) . not . toHaveBeenCalled ( ) ;
1991- expectDeliveredReply ( 0 , { text : "Tool failed" , isError : true } ) ;
1992- } ) ;
1993-
1994- it ( "does not hide exec approval payloads in native DM drafts" , async ( ) => {
1995- const nativeDraft = createNativeToolProgressDraft ( ) ;
1996- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
1997- const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
1998- const execApproval = { id : "approval-1" , command : "pnpm test" } ;
1999- dispatchReplyWithBufferedBlockDispatcher . mockImplementation ( async ( { dispatcherOptions } ) => {
2000- await dispatcherOptions . deliver (
2001- {
2002- text : "Approve command?" ,
2003- channelData : { execApproval } ,
2004- } ,
2005- { kind : "tool" } ,
2006- ) ;
2007- return { queuedFinal : true } ;
2008- } ) ;
2009-
2010- await dispatchWithContext ( {
2011- context : createContext ( ) ,
2012- streamMode : "partial" ,
2013- telegramCfg : {
2014- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
2015- } ,
2016- } ) ;
2017-
2018- expect ( nativeDraft . update ) . not . toHaveBeenCalled ( ) ;
2019- expect ( answerDraftStream . update ) . toHaveBeenCalledWith ( "Approve command?" ) ;
2020- } ) ;
2021-
2022- it ( "does not use native tool progress drafts in groups" , async ( ) => {
2023- setupDraftStreams ( { answerMessageId : 2001 } ) ;
2024- dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
2025- async ( { dispatcherOptions, replyOptions } ) => {
2026- await replyOptions ?. onToolStart ?.( { name : "exec" , phase : "start" } ) ;
2027- await dispatcherOptions . deliver ( { text : "Done answer." } , { kind : "final" } ) ;
2028- return { queuedFinal : true } ;
2029- } ,
2030- ) ;
2031-
2032- await dispatchWithContext ( {
2033- context : createContext ( {
2034- ctxPayload : {
2035- SessionKey : "agent:main:telegram:group:-100123" ,
2036- ChatType : "group" ,
2037- } as unknown as TelegramMessageContext [ "ctxPayload" ] ,
2038- msg : {
2039- chat : { id : - 100123 , type : "supergroup" } ,
2040- message_id : 99 ,
2041- } as unknown as TelegramMessageContext [ "msg" ] ,
2042- chatId : - 100123 ,
2043- isGroup : true ,
2044- threadSpec : { id : undefined , scope : "none" } ,
2045- } ) ,
2046- streamMode : "partial" ,
2047- telegramCfg : {
2048- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
2049- } ,
2050- } ) ;
2051-
2052- expect ( createNativeTelegramToolProgressDraft ) . not . toHaveBeenCalled ( ) ;
2053- } ) ;
2054-
20551822 it ( "does not hide text-only tool output after answer streaming starts" , async ( ) => {
2056- const nativeDraft = createNativeToolProgressDraft ( ) ;
2057- createNativeTelegramToolProgressDraft . mockReturnValue ( nativeDraft ) ;
20581823 const { answerDraftStream } = setupDraftStreams ( { answerMessageId : 2001 } ) ;
20591824 dispatchReplyWithBufferedBlockDispatcher . mockImplementation (
20601825 async ( { dispatcherOptions, replyOptions } ) => {
@@ -2068,13 +1833,10 @@ describe("dispatchTelegramMessage draft streaming", () => {
20681833 context : createContext ( ) ,
20691834 streamMode : "partial" ,
20701835 telegramCfg : {
2071- streaming : { mode : "partial" , preview : { nativeToolProgress : true } } ,
1836+ streaming : { mode : "partial" } ,
20721837 } ,
20731838 } ) ;
20741839
2075- expect ( nativeDraft . update ) . not . toHaveBeenCalledWith (
2076- expect . stringContaining ( "Tool result after partial" ) ,
2077- ) ;
20781840 expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 1 , "Partial answer" ) ;
20791841 expect ( answerDraftStream . update ) . toHaveBeenNthCalledWith ( 2 , "Tool result after partial" ) ;
20801842 } ) ;
0 commit comments