@@ -595,15 +595,33 @@ describe("ThreadImpl", () => {
595595 }
596596 } ) ;
597597
598- it ( "should pass stream options from current message context" , async ( ) => {
598+ it . each ( [
599+ {
600+ expectedTeamId : "T123" ,
601+ label : "team_id" ,
602+ raw : { team_id : "T123" , type : "app_mention" } ,
603+ } ,
604+ {
605+ expectedTeamId : "T234" ,
606+ label : "team string" ,
607+ raw : { team : "T234" , type : "message" } ,
608+ } ,
609+ {
610+ expectedTeamId : "T345" ,
611+ label : "team.id" ,
612+ raw : { team : { id : "T345" } , type : "block_actions" } ,
613+ } ,
614+ ] ) ( "should pass stream options from Slack current message context via $label" , async ( {
615+ raw,
616+ expectedTeamId,
617+ } ) => {
599618 const mockStream = vi . fn ( ) . mockResolvedValue ( {
600619 id : "msg-stream" ,
601620 threadId : "t1" ,
602621 raw : "Hello" ,
603622 } ) ;
604623 mockAdapter . stream = mockStream ;
605624
606- // Create thread with current message context
607625 const threadWithContext = new ThreadImpl ( {
608626 id : "slack:C123:1234.5678" ,
609627 adapter : mockAdapter ,
@@ -614,7 +632,7 @@ describe("ThreadImpl", () => {
614632 threadId : "slack:C123:1234.5678" ,
615633 text : "test" ,
616634 formatted : { type : "root" , children : [ ] } ,
617- raw : { team_id : "T123" } ,
635+ raw,
618636 author : {
619637 userId : "U456" ,
620638 userName : "user" ,
@@ -630,6 +648,65 @@ describe("ThreadImpl", () => {
630648 const textStream = createTextStream ( [ "Hello" ] ) ;
631649 await threadWithContext . post ( textStream ) ;
632650
651+ expect ( mockStream ) . toHaveBeenCalledWith (
652+ "slack:C123:1234.5678" ,
653+ expect . any ( Object ) ,
654+ expect . objectContaining ( {
655+ recipientUserId : "U456" ,
656+ recipientTeamId : expectedTeamId ,
657+ } )
658+ ) ;
659+ } ) ;
660+
661+ it ( "should derive recipientTeamId from Slack block_actions payloads for structured streams" , async ( ) => {
662+ const mockStream = vi . fn ( ) . mockResolvedValue ( {
663+ id : "msg-stream" ,
664+ threadId : "t1" ,
665+ raw : "Hello" ,
666+ } ) ;
667+ mockAdapter . stream = mockStream ;
668+
669+ const threadWithActionContext = new ThreadImpl ( {
670+ id : "slack:C123:1234.5678" ,
671+ adapter : mockAdapter ,
672+ channelId : "C123" ,
673+ stateAdapter : mockState ,
674+ currentMessage : {
675+ id : "action-msg" ,
676+ threadId : "slack:C123:1234.5678" ,
677+ text : "" ,
678+ formatted : { type : "root" , children : [ ] } ,
679+ raw : {
680+ actions : [
681+ { action_id : "select-option" , selected_option : { value : "option-a" } } ,
682+ ] ,
683+ team : { domain : "workspace" , id : "T123" } ,
684+ type : "block_actions" ,
685+ } ,
686+ author : {
687+ userId : "U456" ,
688+ userName : "user" ,
689+ fullName : "Test User" ,
690+ isBot : false ,
691+ isMe : false ,
692+ } ,
693+ metadata : { dateSent : new Date ( ) , edited : false } ,
694+ attachments : [ ] ,
695+ } ,
696+ } ) ;
697+
698+ async function * structuredStream ( ) : AsyncIterable < string | StreamChunk > {
699+ yield "Picking option..." ;
700+ yield {
701+ id : "task-1" ,
702+ status : "pending" ,
703+ title : "Thinking" ,
704+ type : "task_update" ,
705+ } ;
706+ }
707+
708+ await threadWithActionContext . post ( structuredStream ( ) ) ;
709+
633710 expect ( mockStream ) . toHaveBeenCalledWith (
634711 "slack:C123:1234.5678" ,
635712 expect . any ( Object ) ,
0 commit comments