Compare commits
1 Commits
queue/378-
...
q/378-1776
| Author | SHA1 | Date | |
|---|---|---|---|
| 19369e273a |
44
cron/jobs.py
44
cron/jobs.py
@@ -363,6 +363,45 @@ def save_jobs(jobs: List[Dict[str, Any]]):
|
||||
raise
|
||||
|
||||
|
||||
# Patterns that reference local services unreachable on cloud endpoints
|
||||
_LOCAL_SERVICE_CHECK_PATTERNS = [
|
||||
re.compile(r"\b(?:check|verify)\s+(?:that\s+)?ollama\b", re.IGNORECASE),
|
||||
re.compile(r"\bcurl\s+(?:localhost|127\.0\.0\.1)", re.IGNORECASE),
|
||||
re.compile(r"\bpoll\s+localhost\b", re.IGNORECASE),
|
||||
re.compile(r"\bping\s+localhost\b", re.IGNORECASE),
|
||||
re.compile(r"localhost:\d+", re.IGNORECASE),
|
||||
re.compile(r"127\.0\.0\.1:\d+", re.IGNORECASE),
|
||||
]
|
||||
|
||||
|
||||
def _validate_job_prompt_local_refs(prompt: str, base_url: Optional[str] = None) -> List[str]:
|
||||
"""Check if a cron job prompt references local services.
|
||||
|
||||
Returns list of warning messages (empty = no issues).
|
||||
Warnings are advisory — jobs are NOT rejected.
|
||||
"""
|
||||
warnings = []
|
||||
if not prompt:
|
||||
return warnings
|
||||
|
||||
refs = []
|
||||
for pat in _LOCAL_SERVICE_CHECK_PATTERNS:
|
||||
found = pat.findall(prompt)
|
||||
if found:
|
||||
refs.extend(found[:2])
|
||||
|
||||
if refs:
|
||||
refs_str = ", ".join(f"'{r}'" for r in refs[:5])
|
||||
warnings.append(
|
||||
f"Prompt references local services ({refs_str}) which may be "
|
||||
f"unreachable if the job runs on a cloud provider. "
|
||||
f"Consider setting provider='ollama' or base_url='http://localhost:11434/v1'."
|
||||
)
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
|
||||
def create_job(
|
||||
prompt: str,
|
||||
schedule: str,
|
||||
@@ -457,6 +496,11 @@ def create_job(
|
||||
"origin": origin, # Tracks where job was created for "origin" delivery
|
||||
}
|
||||
|
||||
# Validate prompt for local service references (#378)
|
||||
_warnings = _validate_job_prompt_local_refs(prompt, normalized_base_url)
|
||||
for w in _warnings:
|
||||
logging.getLogger("cron.jobs").warning("Job '%s': %s", job_id, w)
|
||||
|
||||
jobs = load_jobs()
|
||||
jobs.append(job)
|
||||
save_jobs(jobs)
|
||||
|
||||
@@ -13,7 +13,6 @@ import concurrent.futures
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -644,56 +643,7 @@ def _build_job_prompt(job: dict) -> str:
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
# Regex patterns for local service references that fail on cloud endpoints
|
||||
_CLOUD_INCOMPATIBLE_PATTERNS = [
|
||||
(re.compile(r"\b[Cc]heck\s+(?:that\s+)?[Oo]llama\s+(?:is\s+)?(?:responding|running|up|available)", re.IGNORECASE),
|
||||
"Verify system services are healthy using available tools"),
|
||||
(re.compile(r"\b[Vv]erify\s+(?:that\s+)?[Oo]llama\s+(?:is\s+)?(?:responding|running|up)", re.IGNORECASE),
|
||||
"Verify system services are healthy using available tools"),
|
||||
(re.compile(r"\bcurl\s+localhost:\d+", re.IGNORECASE),
|
||||
"use available tools to check service health"),
|
||||
(re.compile(r"\bcurl\s+127\.0\.0\.1:\d+", re.IGNORECASE),
|
||||
"use available tools to check service health"),
|
||||
(re.compile(r"\bpoll\s+localhost", re.IGNORECASE),
|
||||
"check service health via available tools"),
|
||||
]
|
||||
|
||||
|
||||
def _rewrite_cloud_incompatible_prompt(prompt: str, base_url: str) -> str:
|
||||
"""Rewrite prompt instructions that assume local service access when running on cloud.
|
||||
|
||||
When a cron job runs on a cloud inference endpoint (Nous, OpenRouter, Anthropic),
|
||||
instructions to "Check Ollama" or "curl localhost:11434" are impossible.
|
||||
Instead of just warning, this rewrites the instruction to a cloud-compatible
|
||||
equivalent that the agent can actually execute.
|
||||
|
||||
Returns the (possibly rewritten) prompt.
|
||||
"""
|
||||
try:
|
||||
from agent.model_metadata import is_local_endpoint
|
||||
except ImportError:
|
||||
return prompt
|
||||
|
||||
if is_local_endpoint(base_url or ""):
|
||||
return prompt # Local — no rewrite needed
|
||||
|
||||
rewritten = prompt
|
||||
for pattern, replacement in _CLOUD_INCOMPATIBLE_PATTERNS:
|
||||
rewritten = pattern.sub(replacement, rewritten)
|
||||
|
||||
if rewritten != prompt:
|
||||
rewritten = (
|
||||
"[NOTE: Some instructions were adjusted for cloud execution. "
|
||||
"Local service checks were rewritten to use available tools.]
|
||||
|
||||
"
|
||||
+ rewritten
|
||||
)
|
||||
|
||||
return rewritten
|
||||
|
||||
|
||||
def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:(job: dict) -> tuple[bool, str, str, Optional[str]]:
|
||||
def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
|
||||
"""
|
||||
Execute a single cron job.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user