Updated OTP Generate with new workflow

This commit is contained in:
2025-11-07 09:56:45 -05:00
parent 9dfdf8b9ee
commit 8a9b04cb7c
6 changed files with 524 additions and 50 deletions
+36 -24
View File
@@ -1,4 +1,6 @@
import difflib
import re
from typing import List
from textual.containers import Horizontal, Vertical
from textual.css.query import NoMatches
@@ -6,14 +8,16 @@ from textual.message import Message
from textual.widget import Widget
from textual.widgets import Button, SelectionList, Static, Switch, TextArea
from models.agent import Agent
class MultiAgentSelector(Widget):
class AgentsSelected(Message):
def __init__(self, selected_agents):
def __init__(self, selected_agents: List[Agent]):
super().__init__()
self.selected_agents = selected_agents
def __init__(self, all_agents: list[dict]):
def __init__(self, all_agents: List[Agent]):
super().__init__()
self.all_agents = all_agents
self._match_type = "exact"
@@ -48,7 +52,6 @@ class MultiAgentSelector(Widget):
yield text_area
with Horizontal(id="switch_search_container") as switch_search:
switch = Switch(value=False, id="match_switch")
switch.styles.width = "auto"
switch.styles.margin = (1, 0, 0, 0)
@@ -62,7 +65,6 @@ class MultiAgentSelector(Widget):
search = Button("🔍 Search", id="search_button")
search.styles.margin = (1, 0, 0, 0)
yield search
with Horizontal() as select_buttons:
@@ -76,17 +78,24 @@ class MultiAgentSelector(Widget):
select_none_button.styles.margin = (1, 0, 0, 1)
yield select_none_button
submit_button = Button(
"► Continue with Selected", id="submit_selection", variant="primary"
)
submit_button.styles.margin = (0, 5, 2, 1)
submit_button.styles.padding = (0, 6, 0, 0)
yield submit_button
with Horizontal() as button_row:
button_row.styles.height = "auto"
button_row.styles.margin = (1, 0, 0, 0)
back_button = Button("← Back", id="back_button")
back_button.styles.width = "1fr"
yield back_button
submit_button = Button(
"▶ Select & Continue", id="submit_selection", variant="primary"
)
submit_button.styles.margin = (0, 5, 2, 1)
submit_button.styles.padding = (0, 6, 0, 0)
yield submit_button
# Right side - Results
with Vertical() as right_pane:
right_pane.styles.width = "2fr"
yield SelectionList(id="match_results")
yield Static(id="unmatched_label")
@@ -97,24 +106,31 @@ class MultiAgentSelector(Widget):
)
def on_button_pressed(self, event: Button.Pressed):
btn_id = event.button.id # can be None for internal buttons
btn_id = event.button.id
# Only query when needed
try:
match_list = self.query_one("#match_results", SelectionList)
except NoMatches:
# UI not mounted yet or id changed—just ignore gracefully
return
if btn_id == "select_all":
if btn_id == "back_button":
self.app.pop_screen()
event.stop()
elif btn_id == "select_all":
match_list.select_all()
event.stop()
elif btn_id == "select_none":
match_list.deselect_all()
event.stop()
elif btn_id == "submit_selection":
selected = list(match_list.selected)
self.post_message(self.AgentsSelected(selected))
# Get selected hostnames
selected_hostnames = list(match_list.selected)
# Convert back to Agent objects
selected_agents = [
agent
for agent in self.all_agents
if agent.hostname in selected_hostnames
]
self.post_message(self.AgentsSelected(selected_agents))
event.stop()
elif btn_id == "search_button":
self.update_matches()
@@ -137,22 +153,18 @@ class MultiAgentSelector(Widget):
def match_devices(self, device_names: list[str]) -> tuple[list[str], list[str]]:
if not self.all_agents or not device_names:
return [], device_names
agent_names = [agent["hostname"] for agent in self.all_agents]
agent_names = [agent.hostname for agent in self.all_agents]
matched = set()
unmatched = []
for name in device_names:
# Check if the name contains wildcards
has_wildcards = "*" in name or "?" in name
if has_wildcards:
# Use regex for wildcard matching
import re
# Escape special regex characters except * and ?
pattern = re.escape(name)
# Convert wildcards to regex
pattern = pattern.replace(r"\*", ".*").replace(r"\?", ".")
# Make it case-insensitive and match full string
regex = re.compile(f"^{pattern}$", re.IGNORECASE)
wildcard_matches = [