1- from typing import Optional , Tuple
1+ import logging
2+ from typing import List , Optional , Tuple
23
4+ from janus import SyncQueue
35from openai import OpenAI
46from py_trees .behaviour import Behaviour
57from py_trees .trees import BehaviourTree
68from py_trees .visitors import SnapshotVisitor
79
810from ..config import Config , load_config
9- from ..conversation_models import ConversationArgs
11+ from ..conversation_models import ConversationArgs , ConversationCockpit , InboxMessage
1012from ..models import SlackArgs
1113from .backchain import create_PPA , latch_chain_to_chain
1214from .conversation_behaviours import (
1618 RunCommand ,
1719 SimpleCommandClassifier ,
1820)
19- from .conversation_state import ConversationState , InboxMessage
21+ from .conversation_state import ConversationState
2022from .tree import log_tree_state_with_markup
2123
24+ logger = logging .getLogger (__name__ )
25+
2226
2327def create_conversation_root_node (
2428 input : InboxMessage ,
2529 config : Config ,
26- llm : Optional [ OpenAI ] = None ,
30+ cockpit : ConversationCockpit ,
2731 slack_args : Optional [SlackArgs ] = None ,
32+ authorized_users : Optional [List [str ]] = None ,
2833) -> Tuple [Behaviour , ConversationState ]:
2934 state = ConversationState (
30- llm_available = llm is not None ,
35+ llm_available = cockpit . llm is not None ,
3136 message = input ,
3237 slack_args = slack_args ,
38+ authorized_users = authorized_users ,
3339 )
3440 state .message = input
3541
3642 # Use LLM classifier if available, otherwise use simple classifier
37- if llm is not None :
43+ if cockpit . llm is not None :
3844 command_detector = create_PPA (
3945 "LLM Command Detector" ,
40- LLMCommandClassifier ("LLM Command Detector" , llm , state ),
41- HasReleaseArgs ("Has Release Args" , state ),
46+ LLMCommandClassifier ("LLM Command Detector" , state , cockpit ),
47+ HasReleaseArgs ("Has Release Args" , state , cockpit ),
4248 )
4349 else :
4450 command_detector = create_PPA (
4551 "Simple Command Detector" ,
46- SimpleCommandClassifier ("Simple Command Classifier" , state ),
47- HasReleaseArgs ("Has Release Args" , state ),
52+ SimpleCommandClassifier ("Simple Command Classifier" , state , cockpit ),
53+ HasReleaseArgs ("Has Release Args" , state , cockpit ),
4854 )
4955
5056 run_command = create_PPA (
5157 "Run" ,
52- RunCommand ("Run Command" , state , config ),
53- IsCommandStarted ("Is Command Started" , state ),
58+ RunCommand ("Run Command" , state , cockpit , config ),
59+ IsCommandStarted ("Is Command Started" , state , cockpit ),
5460 )
5561
5662 latch_chain_to_chain (run_command , command_detector )
@@ -61,6 +67,7 @@ def create_conversation_root_node(
6167
6268def initialize_conversation_tree (
6369 args : ConversationArgs ,
70+ reply_queue : Optional [SyncQueue ] = None ,
6471) -> Tuple [BehaviourTree , ConversationState ]:
6572
6673 # Load config
@@ -70,11 +77,19 @@ def initialize_conversation_tree(
7077 if args .openai_api_key :
7178 llm = OpenAI (api_key = args .openai_api_key )
7279
80+ cockpit = ConversationCockpit ()
81+ cockpit .llm = llm
82+ cockpit .reply_queue = reply_queue
83+
84+ if not args .inbox :
85+ raise ValueError ("Inbox message is required" )
86+
7387 root , state = create_conversation_root_node (
74- InboxMessage ( message = args .message , context = args . context or []) ,
88+ args .inbox ,
7589 config = config ,
76- llm = llm ,
90+ cockpit = cockpit ,
7791 slack_args = args .slack_args ,
92+ authorized_users = args .authorized_users ,
7893 )
7994 tree = BehaviourTree (root )
8095 snapshot_visitor = SnapshotVisitor ()
@@ -83,8 +98,24 @@ def initialize_conversation_tree(
8398 return tree , state
8499
85100
86- def run_conversation_tree (tree : BehaviourTree ) -> None :
101+ def run_conversation_tree (
102+ tree : BehaviourTree , state : ConversationState , reply_queue : SyncQueue
103+ ) -> None :
87104 """Abstacting away tree run
88105 Currently it's just a single tick, but it may change in future
89106 """
90- tree .tick ()
107+ try :
108+ tree .tick ()
109+ try :
110+ if state .reply :
111+ reply_queue .put (state .reply )
112+ except Exception as e :
113+ logger .error (f"Error putting reply to queue: { e } " , exc_info = True )
114+ except Exception as e :
115+ try :
116+ reply_queue .put (f"Error running conversation tree: { str (e )} " )
117+ except Exception as e :
118+ logger .error (f"Error putting error reply to queue: { e } " , exc_info = True )
119+ finally :
120+ logger .debug ("Shutting down reply queue" )
121+ reply_queue .shutdown (immediate = False )
0 commit comments