|
|
|
|
@@ -169,7 +169,7 @@ def _is_overdue(schedule_cron: str, last_run_at: datetime | None) -> bool:
|
|
|
|
|
next_run: datetime = cron.get_next(datetime)
|
|
|
|
|
return now >= next_run
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning("agent_runner: cannot parse cron %r: %s", schedule_cron, exc)
|
|
|
|
|
logger.warning("scout_runner: cannot parse cron %r: %s", schedule_cron, exc)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -290,7 +290,7 @@ async def _run_agent_with_tools(
|
|
|
|
|
call_name = str(call.get("name", ""))
|
|
|
|
|
call_args = call.get("args", {})
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: tool_call name=%s args=%s",
|
|
|
|
|
"scout_runner: tool_call name=%s args=%s",
|
|
|
|
|
call_name,
|
|
|
|
|
json.dumps(call_args, ensure_ascii=True)[:800],
|
|
|
|
|
)
|
|
|
|
|
@@ -305,7 +305,7 @@ async def _run_agent_with_tools(
|
|
|
|
|
tool_output = await tool_fn.ainvoke(call_args)
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: tool_result name=%s output=%s",
|
|
|
|
|
"scout_runner: tool_result name=%s output=%s",
|
|
|
|
|
call_name,
|
|
|
|
|
str(tool_output)[:200],
|
|
|
|
|
)
|
|
|
|
|
@@ -360,7 +360,7 @@ async def _scan_directories(
|
|
|
|
|
try:
|
|
|
|
|
result = await execute_on_client(action="list_directory", data={"path": path})
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning("agent_runner: list_directory failed %r: %s", path, exc)
|
|
|
|
|
logger.warning("scout_runner: list_directory failed %r: %s", path, exc)
|
|
|
|
|
return
|
|
|
|
|
for entry in result.get("entries", []):
|
|
|
|
|
entry_path = entry.get("path", "")
|
|
|
|
|
@@ -414,7 +414,7 @@ async def _fetch_projects() -> list[dict]:
|
|
|
|
|
result = await execute_on_client(action="select", table="projects")
|
|
|
|
|
return result.get("rows", [])
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning("agent_runner: failed to fetch projects: %s", exc)
|
|
|
|
|
logger.warning("scout_runner: failed to fetch projects: %s", exc)
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -442,7 +442,7 @@ async def _fetch_domain_entities(domain: str, project_id: str) -> list[dict]:
|
|
|
|
|
)
|
|
|
|
|
return result.get("rows", [])
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning("agent_runner: failed to fetch %s: %s", domain, exc)
|
|
|
|
|
logger.warning("scout_runner: failed to fetch %s: %s", domain, exc)
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -586,7 +586,7 @@ async def run_local_agent(
|
|
|
|
|
|
|
|
|
|
if not is_online:
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: skip run=%s — device %r offline for user=%s",
|
|
|
|
|
"scout_runner: skip run=%s — device %r offline for user=%s",
|
|
|
|
|
run_id,
|
|
|
|
|
target_device_id or "<any>",
|
|
|
|
|
user_id,
|
|
|
|
|
@@ -616,7 +616,7 @@ async def run_local_agent(
|
|
|
|
|
last_run_at=config.last_run_at,
|
|
|
|
|
)
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: run=%s found %d file(s) after filtering", run_id, len(file_paths)
|
|
|
|
|
"scout_runner: run=%s found %d file(s) after filtering", run_id, len(file_paths)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not file_paths:
|
|
|
|
|
@@ -641,7 +641,7 @@ async def run_local_agent(
|
|
|
|
|
raw_content: str = file_result.get("content", "")
|
|
|
|
|
if not raw_content.strip():
|
|
|
|
|
logger.debug(
|
|
|
|
|
"agent_runner: run=%s skipping empty file %r", run_id, file_path
|
|
|
|
|
"scout_runner: run=%s skipping empty file %r", run_id, file_path
|
|
|
|
|
)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
@@ -651,7 +651,7 @@ async def run_local_agent(
|
|
|
|
|
preprocessed = preprocess(content_type, raw_content)
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: run=%s file=%r content_type=%s clean_len=%d",
|
|
|
|
|
"scout_runner: run=%s file=%r content_type=%s clean_len=%d",
|
|
|
|
|
run_id, file_path, content_type, len(preprocessed.clean_text),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
@@ -711,19 +711,19 @@ async def run_local_agent(
|
|
|
|
|
projects_block = _format_projects(projects)
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: run=%s file=%r created=%d result=%s",
|
|
|
|
|
"scout_runner: run=%s file=%r created=%d result=%s",
|
|
|
|
|
run_id, file_path, file_created, result_text[:200],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
errors.append(f"Error processing '{file_path}': {exc}")
|
|
|
|
|
logger.error(
|
|
|
|
|
"agent_runner: run=%s file=%r failed: %s", run_id, file_path, exc
|
|
|
|
|
"scout_runner: run=%s file=%r failed: %s", run_id, file_path, exc
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
errors.append(f"Agent run failed: {exc}")
|
|
|
|
|
logger.error("agent_runner: run=%s failed: %s", run_id, exc)
|
|
|
|
|
logger.error("scout_runner: run=%s failed: %s", run_id, exc)
|
|
|
|
|
finally:
|
|
|
|
|
_running_agents.discard(agent_id)
|
|
|
|
|
clear_client_executor()
|
|
|
|
|
@@ -744,7 +744,7 @@ async def run_local_agent(
|
|
|
|
|
errors=errors,
|
|
|
|
|
)
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: run=%s done status=%s processed=%d created=%d errors=%d",
|
|
|
|
|
"scout_runner: run=%s done status=%s processed=%d created=%d errors=%d",
|
|
|
|
|
run_id,
|
|
|
|
|
final_status,
|
|
|
|
|
items_processed,
|
|
|
|
|
@@ -762,7 +762,7 @@ async def run_local_agent(
|
|
|
|
|
})
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning(
|
|
|
|
|
"agent_runner: run=%s failed to send run_complete: %s", run_id, exc
|
|
|
|
|
"scout_runner: run=%s failed to send run_complete: %s", run_id, exc
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -797,7 +797,7 @@ async def run_cloud_agent(
|
|
|
|
|
# ── 1. Device online check ─────────────────────────────────────────
|
|
|
|
|
if not device_mgr.is_online(user_id):
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: skip cloud run=%s — no device online for user=%s",
|
|
|
|
|
"scout_runner: skip cloud run=%s — no device online for user=%s",
|
|
|
|
|
run_id,
|
|
|
|
|
user_id,
|
|
|
|
|
)
|
|
|
|
|
@@ -822,7 +822,7 @@ async def run_cloud_agent(
|
|
|
|
|
try:
|
|
|
|
|
credentials_info = decrypt_token(config.oauth_token_encrypted)
|
|
|
|
|
except ValueError as exc:
|
|
|
|
|
logger.error("agent_runner: failed to decrypt OAuth token for agent %s: %s", config.id, exc)
|
|
|
|
|
logger.error("scout_runner: failed to decrypt OAuth token for agent %s: %s", config.id, exc)
|
|
|
|
|
await _finalize_run(
|
|
|
|
|
run_log,
|
|
|
|
|
status="error",
|
|
|
|
|
@@ -868,7 +868,7 @@ async def run_cloud_agent(
|
|
|
|
|
raw_messages = []
|
|
|
|
|
except RuntimeError as exc:
|
|
|
|
|
logger.error(
|
|
|
|
|
"agent_runner: provider fetch failed for cloud agent %s: %s", config.id, exc
|
|
|
|
|
"scout_runner: provider fetch failed for cloud agent %s: %s", config.id, exc
|
|
|
|
|
)
|
|
|
|
|
await _finalize_run(
|
|
|
|
|
run_log,
|
|
|
|
|
@@ -881,7 +881,7 @@ async def run_cloud_agent(
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: cloud agent %s fetched %d item(s) from %s for user=%s",
|
|
|
|
|
"scout_runner: cloud agent %s fetched %d item(s) from %s for user=%s",
|
|
|
|
|
config.id,
|
|
|
|
|
len(raw_messages),
|
|
|
|
|
config.provider,
|
|
|
|
|
@@ -947,10 +947,10 @@ async def run_cloud_agent(
|
|
|
|
|
if cfg_row:
|
|
|
|
|
cfg_row.oauth_token_encrypted = new_encrypted
|
|
|
|
|
await db.commit()
|
|
|
|
|
logger.debug("agent_runner: refreshed OAuth token persisted for agent %s", config.id)
|
|
|
|
|
logger.debug("scout_runner: refreshed OAuth token persisted for agent %s", config.id)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.warning(
|
|
|
|
|
"agent_runner: failed to persist refreshed token for agent %s: %s",
|
|
|
|
|
"scout_runner: failed to persist refreshed token for agent %s: %s",
|
|
|
|
|
config.id,
|
|
|
|
|
exc,
|
|
|
|
|
)
|
|
|
|
|
@@ -974,7 +974,7 @@ async def run_cloud_agent(
|
|
|
|
|
config_type="cloud",
|
|
|
|
|
)
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: cloud run=%s done status=%s processed=%d created=%d errors=%d",
|
|
|
|
|
"scout_runner: cloud run=%s done status=%s processed=%d created=%d errors=%d",
|
|
|
|
|
run_id,
|
|
|
|
|
final_status,
|
|
|
|
|
items_processed,
|
|
|
|
|
@@ -996,7 +996,7 @@ async def trigger_pending_runs(
|
|
|
|
|
Called as a background task from the device WS endpoint on ``device_hello``.
|
|
|
|
|
"""
|
|
|
|
|
logger.info(
|
|
|
|
|
"agent_runner: pending-run scan skipped for user=%s device=%s (client-owned agent config)",
|
|
|
|
|
"scout_runner: pending-run scan skipped for user=%s device=%s (client-owned agent config)",
|
|
|
|
|
user_id,
|
|
|
|
|
device_id,
|
|
|
|
|
)
|
|
|
|
|
@@ -1047,5 +1047,5 @@ async def _finalize_run(
|
|
|
|
|
await db.commit()
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
logger.error(
|
|
|
|
|
"agent_runner: failed to finalize run_log=%s: %s", run_log.id, exc
|
|
|
|
|
"scout_runner: failed to finalize run_log=%s: %s", run_log.id, exc
|
|
|
|
|
)
|