mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-10-26 17:21:58 -06:00
Support selecting agent context for screenshots
This commit is contained in:
@@ -5852,14 +5852,22 @@ def get_agents():
|
||||
if info.get('is_script_agent'):
|
||||
continue
|
||||
d = dict(info)
|
||||
mode = _normalize_service_mode(d.get('service_mode'), aid)
|
||||
d['service_mode'] = mode
|
||||
ts = d.get('collector_active_ts') or 0
|
||||
d['collector_active'] = bool(ts and (now - float(ts) < 130))
|
||||
host = (d.get('hostname') or '').strip() or 'unknown'
|
||||
# Select best record per hostname: highest last_seen wins
|
||||
cur = seen_by_hostname.get(host)
|
||||
bucket = seen_by_hostname.setdefault(host, {})
|
||||
cur = bucket.get(mode)
|
||||
if not cur or int(d.get('last_seen') or 0) >= int(cur[1].get('last_seen') or 0):
|
||||
seen_by_hostname[host] = (aid, d)
|
||||
out = { aid: d for host, (aid, d) in seen_by_hostname.items() }
|
||||
bucket[mode] = (aid, d)
|
||||
out = {}
|
||||
for host, bucket in seen_by_hostname.items():
|
||||
for mode, (aid, d) in bucket.items():
|
||||
d = dict(d)
|
||||
d['hostname'] = (d.get('hostname') or '').strip() or host
|
||||
d['service_mode'] = mode
|
||||
out[aid] = d
|
||||
return jsonify(out)
|
||||
|
||||
|
||||
@@ -5869,6 +5877,28 @@ def get_agents():
|
||||
## dayjs_to_ts removed; scheduling parsing now lives in job_scheduler
|
||||
|
||||
|
||||
def _normalize_service_mode(value, agent_id=None):
|
||||
try:
|
||||
if isinstance(value, str):
|
||||
text = value.strip().lower()
|
||||
else:
|
||||
text = ''
|
||||
except Exception:
|
||||
text = ''
|
||||
if not text and agent_id:
|
||||
try:
|
||||
aid = agent_id.lower()
|
||||
if '-svc-' in aid or aid.endswith('-svc'):
|
||||
return 'system'
|
||||
except Exception:
|
||||
pass
|
||||
if text in {'system', 'svc', 'service', 'system_service'}:
|
||||
return 'system'
|
||||
if text in {'interactive', 'currentuser', 'user', 'current_user'}:
|
||||
return 'currentuser'
|
||||
return 'currentuser'
|
||||
|
||||
|
||||
def _is_empty(v):
|
||||
return v is None or v == '' or v == [] or v == {}
|
||||
|
||||
@@ -7252,12 +7282,15 @@ def handle_collector_status(data):
|
||||
if not agent_id:
|
||||
return
|
||||
|
||||
mode = _normalize_service_mode((data or {}).get('service_mode'), agent_id)
|
||||
rec = registered_agents.setdefault(agent_id, {})
|
||||
rec['agent_id'] = agent_id
|
||||
if hostname:
|
||||
rec['hostname'] = hostname
|
||||
if active:
|
||||
rec['collector_active_ts'] = time.time()
|
||||
if mode:
|
||||
rec['service_mode'] = mode
|
||||
|
||||
# Helper: decide if a reported user string is a real interactive user
|
||||
def _is_valid_interactive_user(s: str) -> bool:
|
||||
@@ -7491,12 +7524,14 @@ def connect_agent(data):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
service_mode = _normalize_service_mode((data or {}).get("service_mode"), agent_id)
|
||||
rec = registered_agents.setdefault(agent_id, {})
|
||||
rec["agent_id"] = agent_id
|
||||
rec["hostname"] = rec.get("hostname", "unknown")
|
||||
rec["agent_operating_system"] = rec.get("agent_operating_system", "-")
|
||||
rec["last_seen"] = int(time.time())
|
||||
rec["status"] = "provisioned" if agent_id in agent_configurations else "orphaned"
|
||||
rec["service_mode"] = service_mode
|
||||
# Flag script agents so they can be filtered out elsewhere if desired
|
||||
try:
|
||||
if isinstance(agent_id, str) and agent_id.lower().endswith('-script'):
|
||||
@@ -7524,6 +7559,8 @@ def on_agent_heartbeat(data):
|
||||
return
|
||||
hostname = data.get("hostname")
|
||||
|
||||
incoming_mode = _normalize_service_mode(data.get("service_mode"), agent_id)
|
||||
|
||||
if hostname:
|
||||
# Avoid duplicate entries per-hostname by collapsing to the newest agent_id.
|
||||
# Prefer non-script agents; we do not surface script agents in /api/agents.
|
||||
@@ -7537,6 +7574,9 @@ def on_agent_heartbeat(data):
|
||||
if aid == agent_id:
|
||||
continue
|
||||
if info.get("hostname") == hostname:
|
||||
existing_mode = _normalize_service_mode(info.get("service_mode"), aid)
|
||||
if existing_mode != incoming_mode:
|
||||
continue
|
||||
# If the incoming is a script helper and there is a non-script entry, keep non-script
|
||||
if is_current_script and not info.get('is_script_agent'):
|
||||
# Do not register duplicate script entry; just update last_seen persistence below
|
||||
@@ -7561,6 +7601,7 @@ def on_agent_heartbeat(data):
|
||||
rec["agent_operating_system"] = data.get("agent_operating_system")
|
||||
rec["last_seen"] = int(data.get("last_seen") or time.time())
|
||||
rec["status"] = "provisioned" if agent_id in agent_configurations else rec.get("status", "orphaned")
|
||||
rec["service_mode"] = incoming_mode
|
||||
# Persist last_seen (and agent_id) into DB keyed by hostname so it survives restarts.
|
||||
try:
|
||||
_persist_last_seen(rec.get("hostname") or hostname, rec["last_seen"], rec.get("agent_id"))
|
||||
|
||||
Reference in New Issue
Block a user