mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
[eric] apps: leading-_ -> p_ for import aliases (import x as _y) across apps modules (file-local bindings, p-private 0)
This commit is contained in:
@@ -76,13 +76,13 @@ async def send_message(session_id: str, body: dict):
|
||||
# Run MCP-suggestion classifier in parallel with the agent launch; fails open.
|
||||
try:
|
||||
from backend.apps.agents.core.mcp_preflight import run_preflight
|
||||
from backend.apps.agents.core.ws_manager import ws_manager as _ws
|
||||
from backend.apps.agents.core.ws_manager import ws_manager as p_ws
|
||||
|
||||
async def p_emit_preflight():
|
||||
try:
|
||||
result = await run_preflight(prompt, task_id=session_id)
|
||||
if result.get("suggestions") or result.get("is_vague"):
|
||||
await _ws.send_to_session(session_id, "agent:mcp_suggestions", {
|
||||
await p_ws.send_to_session(session_id, "agent:mcp_suggestions", {
|
||||
"session_id": session_id,
|
||||
"suggestions": result.get("suggestions", []),
|
||||
"is_vague": bool(result.get("is_vague")),
|
||||
@@ -90,8 +90,8 @@ async def send_message(session_id: str, body: dict):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
import asyncio as _asyncio
|
||||
_asyncio.create_task(p_emit_preflight())
|
||||
import asyncio as p_asyncio
|
||||
p_asyncio.create_task(p_emit_preflight())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -422,9 +422,9 @@ async def subscriptions_poll(body: dict):
|
||||
extra_data=body.get("extra_data"),
|
||||
)
|
||||
if result.get("success"):
|
||||
from backend.apps.service.client import sync as _sync
|
||||
from backend.apps.service.client import sync as p_sync
|
||||
from backend.apps.settings.settings import load_settings
|
||||
_sync(load_settings().model_dump())
|
||||
p_sync(load_settings().model_dump())
|
||||
return result
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
@@ -479,7 +479,7 @@ async def subscriptions_models():
|
||||
@agents.router.post("/probe-model")
|
||||
async def probe_model(body: dict):
|
||||
"""1-token health probe; returns latency or skipped when the route is ambiguous (silent beats wrong)."""
|
||||
import time as _time
|
||||
import time as p_time
|
||||
short_name = (body or {}).get("model") or ""
|
||||
if not short_name:
|
||||
return {"ok": False, "error": "model required"}
|
||||
@@ -491,7 +491,7 @@ async def probe_model(body: dict):
|
||||
_NINEROUTER_MODEL_PREFIXES,
|
||||
)
|
||||
from backend.apps.settings.settings import load_settings
|
||||
from backend.apps.nine_router import is_running as _9r_running
|
||||
from backend.apps.nine_router import is_running as p_9r_running
|
||||
settings = load_settings()
|
||||
api_type = get_api_type(short_name)
|
||||
resolved = resolve_model_id_for_sdk(short_name, settings)
|
||||
@@ -509,7 +509,7 @@ async def probe_model(body: dict):
|
||||
)
|
||||
|
||||
if resolved_is_9router:
|
||||
if not _9r_running():
|
||||
if not p_9r_running():
|
||||
return {"ok": True, "skipped": True}
|
||||
client = anthropic.AsyncAnthropic(api_key="9router", base_url="http://localhost:20128")
|
||||
elif route == "api" and api_type == "anthropic" and getattr(settings, "anthropic_api_key", None):
|
||||
@@ -523,18 +523,18 @@ async def probe_model(body: dict):
|
||||
elif api_type == "anthropic" and getattr(settings, "anthropic_api_key", None):
|
||||
client = anthropic.AsyncAnthropic(api_key=settings.anthropic_api_key)
|
||||
else:
|
||||
if not _9r_running():
|
||||
if not p_9r_running():
|
||||
return {"ok": True, "skipped": True}
|
||||
client = anthropic.AsyncAnthropic(api_key="9router", base_url="http://localhost:20128")
|
||||
|
||||
t0 = _time.monotonic()
|
||||
t0 = p_time.monotonic()
|
||||
await client.messages.create(
|
||||
model=resolved,
|
||||
max_tokens=1,
|
||||
messages=[{"role": "user", "content": "ping"}],
|
||||
timeout=10.0,
|
||||
)
|
||||
return {"ok": True, "latency_ms": int((_time.monotonic() - t0) * 1000)}
|
||||
return {"ok": True, "latency_ms": int((p_time.monotonic() - t0) * 1000)}
|
||||
except Exception as e:
|
||||
msg = str(e).splitlines()[0] if str(e) else type(e).__name__
|
||||
low = msg.lower()
|
||||
@@ -556,16 +556,16 @@ async def probe_model(body: dict):
|
||||
async def list_models():
|
||||
"""Picker model list, grouped by provider, intersected with available creds."""
|
||||
from backend.apps.agents.providers.registry import BUILTIN_MODELS
|
||||
from backend.apps.nine_router import is_running as _9r_running, get_providers as _9r_providers
|
||||
from backend.apps.nine_router import is_running as p_9r_running, get_providers as p_9r_providers
|
||||
from backend.apps.settings.settings import load_settings
|
||||
|
||||
settings = load_settings()
|
||||
nine_router_up = _9r_running()
|
||||
nine_router_up = p_9r_running()
|
||||
|
||||
connected: set[str] = set()
|
||||
if nine_router_up:
|
||||
try:
|
||||
conns = await _9r_providers()
|
||||
conns = await p_9r_providers()
|
||||
raw_providers = {c.get("provider", "") for c in conns if c.get("isActive") or c.get("testStatus") == "active"}
|
||||
# 9Router uses "claude"; our models use api="anthropic". Map across.
|
||||
p_9R_TO_API = {
|
||||
@@ -678,9 +678,9 @@ async def list_models():
|
||||
has_google_key = bool(getattr(settings, "google_api_key", None))
|
||||
has_openrouter_key = bool(getattr(settings, "openrouter_api_key", None))
|
||||
from backend.apps.agents.providers.registry import (
|
||||
COST_PER_1M_TOKENS as _CPM,
|
||||
compute_tiers as _ct_native,
|
||||
compute_billing_kind as _cbk_native,
|
||||
COST_PER_1M_TOKENS as P_CPM,
|
||||
compute_tiers as p_ct_native,
|
||||
compute_billing_kind as p_cbk_native,
|
||||
)
|
||||
for provider_name, models in BUILTIN_MODELS.items():
|
||||
if provider_name == "Anthropic":
|
||||
@@ -698,14 +698,14 @@ async def list_models():
|
||||
if not nine_router_up or api not in connected:
|
||||
continue
|
||||
in_cost = out_cost = 0.0
|
||||
for (p_p, p_v), rates in _CPM.items():
|
||||
for (p_p, p_v), rates in P_CPM.items():
|
||||
if p_v == m["value"]:
|
||||
in_cost, out_cost = rates
|
||||
break
|
||||
billing_kind = _cbk_native(
|
||||
billing_kind = p_cbk_native(
|
||||
api=api, route=route, is_or_free=False, settings=settings,
|
||||
)
|
||||
tiers = _ct_native(
|
||||
tiers = p_ct_native(
|
||||
m.get("model_id", m["value"]),
|
||||
m["label"],
|
||||
out_cost,
|
||||
@@ -736,19 +736,19 @@ async def list_models():
|
||||
if or_models:
|
||||
by_vendor: dict[str, list[dict]] = {}
|
||||
from backend.apps.agents.providers.registry import (
|
||||
compute_tiers as _ct,
|
||||
compute_billing_kind as _cbk,
|
||||
compute_tiers as p_ct,
|
||||
compute_billing_kind as p_cbk,
|
||||
)
|
||||
for m in or_models:
|
||||
v = m.get("vendor") or "Other"
|
||||
in_cost = float(m.get("input_cost_per_1m", 0.0))
|
||||
out_cost = float(m.get("output_cost_per_1m", 0.0))
|
||||
is_free = bool(m.get("is_free", False))
|
||||
billing_kind = _cbk(
|
||||
billing_kind = p_cbk(
|
||||
api="openrouter", route="openrouter", is_or_free=is_free,
|
||||
settings=settings,
|
||||
)
|
||||
tiers = _ct(
|
||||
tiers = p_ct(
|
||||
m.get("model_id", m["value"]),
|
||||
m["label"],
|
||||
out_cost,
|
||||
@@ -845,9 +845,9 @@ async def subscriptions_disconnect(body: dict):
|
||||
to_remove = [provider, *P_PROVIDER_CASCADE_REMOVES.get(provider, [])]
|
||||
removed = await p_delete_provider_connections(to_remove)
|
||||
if removed:
|
||||
from backend.apps.service.client import sync as _sync
|
||||
from backend.apps.service.client import sync as p_sync
|
||||
from backend.apps.settings.settings import load_settings
|
||||
_sync(load_settings().model_dump())
|
||||
p_sync(load_settings().model_dump())
|
||||
return {"ok": True}
|
||||
return {"ok": False, "error": "Connection not found"}
|
||||
except Exception as e:
|
||||
|
||||
@@ -97,7 +97,7 @@ def resolve_attachments(context_paths: Optional[List], api_type: str, model: str
|
||||
if not context_paths:
|
||||
return "", [], []
|
||||
from backend.apps.settings.settings import sniff_file_kind
|
||||
import base64 as _b64
|
||||
import base64 as p_b64
|
||||
sections: List[str] = []
|
||||
native: List[dict] = []
|
||||
refusals: List[str] = []
|
||||
@@ -236,7 +236,7 @@ def resolve_attachments(context_paths: Optional[List], api_type: str, model: str
|
||||
)
|
||||
continue
|
||||
with open(path, "rb") as fh:
|
||||
data_b64 = _b64.b64encode(fh.read()).decode("ascii")
|
||||
data_b64 = p_b64.b64encode(fh.read()).decode("ascii")
|
||||
block = {
|
||||
"type": "document",
|
||||
"source": {
|
||||
@@ -269,7 +269,7 @@ def resolve_attachments(context_paths: Optional[List], api_type: str, model: str
|
||||
)
|
||||
continue
|
||||
with open(path, "rb") as fh:
|
||||
data_b64 = _b64.b64encode(fh.read()).decode("ascii")
|
||||
data_b64 = p_b64.b64encode(fh.read()).decode("ascii")
|
||||
native.append({
|
||||
"type": "image",
|
||||
"source": {
|
||||
|
||||
@@ -78,12 +78,12 @@ def invalidate_openrouter_cache() -> None:
|
||||
|
||||
async def fetch_openrouter_models(api_key: str | None) -> list[dict]:
|
||||
"""Return OR's tool-capable chat catalog. Cached. Never raises."""
|
||||
import time as _time
|
||||
import time as p_time
|
||||
if not api_key:
|
||||
invalidate_openrouter_cache()
|
||||
return []
|
||||
|
||||
now = _time.monotonic()
|
||||
now = p_time.monotonic()
|
||||
fetched_at = p_or_models_cache["fetched_at"]
|
||||
if p_or_models_cache["models"] is not None:
|
||||
ttl = P_OR_MODELS_TTL_OK if p_or_models_cache["ok"] else P_OR_MODELS_TTL_FAIL
|
||||
|
||||
@@ -204,7 +204,7 @@ def heuristic_tiers(label: str, output_cost_per_1m: float, reasoning: bool) -> t
|
||||
- inverse of size, with name keywords as ±1 nudges.
|
||||
Cost: pure cost bucket.
|
||||
"""
|
||||
import re as _re
|
||||
import re as p_re
|
||||
out = output_cost_per_1m or 0.0
|
||||
|
||||
# Cost bucket; same 5-tier cost ladder as before.
|
||||
@@ -225,7 +225,7 @@ def heuristic_tiers(label: str, output_cost_per_1m: float, reasoning: bool) -> t
|
||||
# clearly above 1B (so we don't pick up version numbers).
|
||||
lower = (label or "").lower()
|
||||
param_b = 0.0
|
||||
for m in _re.finditer(r"\b(\d{1,4}(?:\.\d+)?)\s*b\b", lower):
|
||||
for m in p_re.finditer(r"\b(\d{1,4}(?:\.\d+)?)\s*b\b", lower):
|
||||
try:
|
||||
v = float(m.group(1))
|
||||
if v >= 1 and v > param_b:
|
||||
@@ -259,9 +259,9 @@ def heuristic_tiers(label: str, output_cost_per_1m: float, reasoning: bool) -> t
|
||||
|
||||
# Speed inverse of intel.
|
||||
speed = 6 - intel
|
||||
if _re.search(r"\b(mini|lite|flash|haiku|nano|small|fast|turbo|micro|tiny)\b", lower):
|
||||
if p_re.search(r"\b(mini|lite|flash|haiku|nano|small|fast|turbo|micro|tiny)\b", lower):
|
||||
speed += 1
|
||||
if _re.search(r"\b(opus|ultra|max|xlarge|titan|huge)\b", lower):
|
||||
if p_re.search(r"\b(opus|ultra|max|xlarge|titan|huge)\b", lower):
|
||||
speed -= 1
|
||||
if reasoning and intel >= 4:
|
||||
# Frontier reasoning models burn lots of tokens on hidden
|
||||
|
||||
@@ -232,9 +232,9 @@ def p_antigravity_connected() -> bool:
|
||||
probe (this resolver is sync) with a tight timeout; any hiccup reads as
|
||||
'no' so a slow/absent 9Router never blocks model resolution for long."""
|
||||
try:
|
||||
import httpx as _httpx
|
||||
import httpx as p_httpx
|
||||
from backend.apps.nine_router.process import cli_auth_headers
|
||||
r = _httpx.get("http://localhost:20128/api/providers", timeout=2.0, headers=cli_auth_headers())
|
||||
r = p_httpx.get("http://localhost:20128/api/providers", timeout=2.0, headers=cli_auth_headers())
|
||||
if r.status_code != 200:
|
||||
return False
|
||||
data = r.json()
|
||||
@@ -321,13 +321,13 @@ async def resolve_aux_model(
|
||||
bare = haiku_bare if preferred_tier == "haiku" else sonnet_bare
|
||||
or_aux = or_haiku if preferred_tier == "haiku" else or_sonnet
|
||||
|
||||
from backend.apps.nine_router import is_running as _9r_running, get_providers as _9r_providers
|
||||
from backend.apps.nine_router import is_running as p_9r_running, get_providers as p_9r_providers
|
||||
|
||||
base_url = "http://localhost:20128"
|
||||
connected: set[str] = set()
|
||||
if _9r_running():
|
||||
if p_9r_running():
|
||||
try:
|
||||
connections = await _9r_providers()
|
||||
connections = await p_9r_providers()
|
||||
connected = {c.get("provider") for c in connections if c.get("isActive")}
|
||||
except Exception:
|
||||
connected = set()
|
||||
@@ -355,7 +355,7 @@ async def resolve_aux_model(
|
||||
if getattr(settings, "anthropic_api_key", None):
|
||||
return (bare, None)
|
||||
|
||||
if not _9r_running():
|
||||
if not p_9r_running():
|
||||
raise ValueError(
|
||||
"No AI provider configured for auxiliary LLM call. "
|
||||
"Set an Anthropic API key or connect a subscription."
|
||||
|
||||
@@ -420,17 +420,17 @@ async def proxy(rest: str, request: Request):
|
||||
parsed_for_bypass = None
|
||||
if isinstance(parsed_for_bypass, dict):
|
||||
from backend.apps.agents.proxy.anthropic_to_openai import (
|
||||
should_bypass_9router as _should_bypass_oai,
|
||||
should_bypass_9router_for_openrouter as _should_bypass_or,
|
||||
forward_to_openai as _forward_oai,
|
||||
forward_to_openrouter as _forward_or,
|
||||
should_bypass_9router as p_should_bypass_oai,
|
||||
should_bypass_9router_for_openrouter as p_should_bypass_or,
|
||||
forward_to_openai as p_forward_oai,
|
||||
forward_to_openrouter as p_forward_or,
|
||||
)
|
||||
from backend.apps.settings.settings import load_settings as _load
|
||||
p_s = _load()
|
||||
from backend.apps.settings.settings import load_settings as p_load
|
||||
p_s = p_load()
|
||||
if p_is_openai_max_completion_tokens_model(model):
|
||||
p_oak = (getattr(p_s, "openai_api_key", "") or "").strip()
|
||||
if _should_bypass_oai(parsed_for_bypass, p_oak):
|
||||
status, body_stream, hdrs = await _forward_oai(
|
||||
if p_should_bypass_oai(parsed_for_bypass, p_oak):
|
||||
status, body_stream, hdrs = await p_forward_oai(
|
||||
parsed_for_bypass, p_oak,
|
||||
)
|
||||
return StreamingResponse(
|
||||
@@ -439,8 +439,8 @@ async def proxy(rest: str, request: Request):
|
||||
)
|
||||
if p_is_openrouter_model(model):
|
||||
p_ork = (getattr(p_s, "openrouter_api_key", "") or "").strip()
|
||||
if _should_bypass_or(parsed_for_bypass, p_ork):
|
||||
status, body_stream, hdrs = await _forward_or(
|
||||
if p_should_bypass_or(parsed_for_bypass, p_ork):
|
||||
status, body_stream, hdrs = await p_forward_or(
|
||||
parsed_for_bypass, p_ork,
|
||||
)
|
||||
return StreamingResponse(
|
||||
|
||||
@@ -62,7 +62,7 @@ def p_sync_identity_to_service(settings_obj) -> None:
|
||||
"""Push user_id + email + signin_method into the service-sync identify
|
||||
pipeline so every event from this user has the right Person properties."""
|
||||
try:
|
||||
from backend.apps.service.client import identify as _identify
|
||||
from backend.apps.service.client import identify as p_identify
|
||||
except Exception:
|
||||
return
|
||||
props = {
|
||||
@@ -73,7 +73,7 @@ def p_sync_identity_to_service(settings_obj) -> None:
|
||||
if email:
|
||||
props["email"] = email
|
||||
try:
|
||||
_identify(props)
|
||||
p_identify(props)
|
||||
except Exception as e:
|
||||
logger.debug("identify sync failed: %s", e)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ def p_patched_get_credentials():
|
||||
gauth.get_credentials = p_patched_get_credentials
|
||||
|
||||
|
||||
from google_workspace_mcp import __main__ as _gw_main # noqa: E402,F401
|
||||
from google_workspace_mcp import __main__ as p_gw_main # noqa: E402,F401
|
||||
from google_workspace_mcp.app import mcp # noqa: E402
|
||||
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ async def modes_lifespan():
|
||||
chat_path = os.path.join(DATA_DIR, "chat.json")
|
||||
if os.path.exists(chat_path):
|
||||
try:
|
||||
import json as _json
|
||||
import json as p_json
|
||||
with open(chat_path) as p_f:
|
||||
p_data = _json.load(p_f)
|
||||
p_data = p_json.load(p_f)
|
||||
if p_data.get("is_builtin") is True and p_data.get("id") == "chat":
|
||||
os.remove(chat_path)
|
||||
logger.info("Removed deprecated built-in chat.json (merged into ask)")
|
||||
|
||||
@@ -402,15 +402,15 @@ async def p_ensure_running_impl():
|
||||
# In dev mode, kill stale standalone servers (from previous builds)
|
||||
# so we can start `next dev` which always uses latest source code
|
||||
if not p_is_packaged:
|
||||
import subprocess as _sp
|
||||
import subprocess as p_sp
|
||||
try:
|
||||
result = _sp.run(
|
||||
result = p_sp.run(
|
||||
["pgrep", "-f", "next-server"],
|
||||
capture_output=True, text=True, timeout=3,
|
||||
)
|
||||
if result.stdout.strip():
|
||||
logger.info("Dev mode: killing stale standalone 9Router to use next dev instead")
|
||||
_sp.run(["pkill", "-f", "next-server"], timeout=5)
|
||||
p_sp.run(["pkill", "-f", "next-server"], timeout=5)
|
||||
await asyncio.sleep(2)
|
||||
else:
|
||||
logger.info("9Router already running on port %d", NINE_ROUTER_PORT)
|
||||
|
||||
@@ -30,8 +30,8 @@ async def sync_openai_compat_node(api_key: str | None) -> None:
|
||||
pair we use to ferry OpenAI requests through openai-passthrough."""
|
||||
if not nr().is_running():
|
||||
return
|
||||
import os as _os
|
||||
port = _os.environ.get("OPENSWARM_PORT", "8324")
|
||||
import os as p_os
|
||||
port = p_os.environ.get("OPENSWARM_PORT", "8324")
|
||||
base_url = f"http://127.0.0.1:{port}/api/openai-passthrough/v1"
|
||||
managed_name = f"OpenAI{NINE_ROUTER_CUSTOM_NAME_SUFFIX}"
|
||||
|
||||
|
||||
@@ -156,8 +156,8 @@ def p_envelope() -> dict:
|
||||
except Exception:
|
||||
pass
|
||||
if not ianatz:
|
||||
import datetime as _dt
|
||||
local_tz = _dt.datetime.now().astimezone().tzinfo
|
||||
import datetime as p_dt
|
||||
local_tz = p_dt.datetime.now().astimezone().tzinfo
|
||||
if local_tz:
|
||||
ianatz = str(local_tz)
|
||||
if ianatz:
|
||||
|
||||
@@ -69,15 +69,15 @@ async def p_pulse_loop():
|
||||
await asyncio.sleep(60)
|
||||
p_pulse_count += 1
|
||||
try:
|
||||
import datetime as _dt
|
||||
p_pulse_hours.add(_dt.datetime.now().hour)
|
||||
import datetime as p_dt
|
||||
p_pulse_hours.add(p_dt.datetime.now().hour)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
cost_delta = 0.0
|
||||
try:
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as _9r_running
|
||||
if _9r_running():
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as p_9r_running
|
||||
if p_9r_running():
|
||||
stats = await get_usage_stats()
|
||||
if stats:
|
||||
cur_cost = stats.get("totalCost", 0) or 0
|
||||
@@ -336,8 +336,8 @@ async def usage_summary():
|
||||
completed = status_counts.get("completed", 0)
|
||||
completion_rate = completed / total_sessions if total_sessions > 0 else 0
|
||||
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as _9r_running
|
||||
nine_router_stats = await get_usage_stats() if _9r_running() else None
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as p_9r_running
|
||||
nine_router_stats = await get_usage_stats() if p_9r_running() else None
|
||||
|
||||
if nine_router_stats and nine_router_stats.get("totalCost", 0) > 0:
|
||||
cost_source = "9router"
|
||||
@@ -397,8 +397,8 @@ async def usage_summary():
|
||||
|
||||
@service.router.get("/cost-breakdown")
|
||||
async def cost_breakdown(period: str = "7d"):
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as _9r_running
|
||||
if not _9r_running():
|
||||
from backend.apps.nine_router import get_usage_stats, is_running as p_9r_running
|
||||
if not p_9r_running():
|
||||
return {"available": False, "by_model": {}, "by_provider": {}}
|
||||
stats = await get_usage_stats(period)
|
||||
if not stats:
|
||||
|
||||
@@ -28,8 +28,8 @@ async def settings_lifespan():
|
||||
os.makedirs(DATA_DIR, exist_ok=True)
|
||||
try:
|
||||
from backend.apps.nine_router import (
|
||||
ensure_running as _9r_ensure,
|
||||
is_running as _9r_running,
|
||||
ensure_running as p_9r_ensure,
|
||||
is_running as p_9r_running,
|
||||
sync_gemini_api_key,
|
||||
sync_openai_api_key,
|
||||
sync_openrouter_api_key,
|
||||
@@ -37,7 +37,7 @@ async def settings_lifespan():
|
||||
sync_custom_providers,
|
||||
)
|
||||
s = load_settings()
|
||||
import asyncio as _asyncio
|
||||
import asyncio as p_asyncio
|
||||
|
||||
async def p_boot_router_then_sync():
|
||||
"""Boot 9Router then push key-based connections (sequential: sync helpers no-op pre-boot)."""
|
||||
@@ -50,7 +50,7 @@ async def settings_lifespan():
|
||||
])
|
||||
if needs_router:
|
||||
try:
|
||||
await _9r_ensure()
|
||||
await p_9r_ensure()
|
||||
except Exception as e:
|
||||
logger.warning(f"9Router lifespan boot failed: {e}")
|
||||
# Reconcile, don't just add: pass the key OR None so a cleared/never-set key
|
||||
@@ -58,7 +58,7 @@ async def settings_lifespan():
|
||||
# old add-only guards left a zombie managed key alive after disconnect, which
|
||||
# kept routing to it (the "still defaults to gemini") and blocked the free
|
||||
# trial from arming. Only acts when 9Router is already up (_sync no-ops if not).
|
||||
if _9r_running():
|
||||
if p_9r_running():
|
||||
await sync_gemini_api_key(getattr(s, "google_api_key", None) or None)
|
||||
await sync_openai_api_key(getattr(s, "openai_api_key", None) or None)
|
||||
await sync_openrouter_api_key(getattr(s, "openrouter_api_key", None) or None)
|
||||
@@ -75,8 +75,8 @@ async def settings_lifespan():
|
||||
await sync_openswarm_pro_as_claude(bearer, base)
|
||||
await sync_custom_providers(getattr(s, "custom_providers", None) or [])
|
||||
|
||||
_asyncio.create_task(p_boot_router_then_sync())
|
||||
_asyncio.create_task(p_upload_dir_gc_loop())
|
||||
p_asyncio.create_task(p_boot_router_then_sync())
|
||||
p_asyncio.create_task(p_upload_dir_gc_loop())
|
||||
except Exception as e:
|
||||
logger.warning(f"9Router sync startup failed: {e}")
|
||||
yield
|
||||
@@ -90,7 +90,7 @@ async def p_upload_dir_gc_loop():
|
||||
by the OS but not aggressively; Windows temp is not. Belt and braces.
|
||||
Errors are swallowed: a chmod hiccup or in-use lock should never
|
||||
crash the backend."""
|
||||
import asyncio as _a
|
||||
import asyncio as p_a
|
||||
while True:
|
||||
try:
|
||||
now = time.time()
|
||||
@@ -105,7 +105,7 @@ async def p_upload_dir_gc_loop():
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
await _a.sleep(24 * 3600)
|
||||
await p_a.sleep(24 * 3600)
|
||||
|
||||
|
||||
settings = SubApp("settings", settings_lifespan)
|
||||
@@ -145,7 +145,7 @@ SERVER_OWNED_FIELDS = (
|
||||
)
|
||||
|
||||
|
||||
import weakref as _weakref
|
||||
import weakref as p_weakref
|
||||
|
||||
# One serialization point for EVERY settings write (renderer PUT/PATCH + agent
|
||||
# tool), so two writes can't interleave and clobber each other mid read-modify-
|
||||
@@ -156,7 +156,7 @@ import weakref as _weakref
|
||||
# the first loop that uses it and then errors on reuse from another loop (every
|
||||
# async test spins a fresh one). WeakKeyDictionary auto-drops a loop's lock once
|
||||
# the loop is gone.
|
||||
p_settings_write_locks: "_weakref.WeakKeyDictionary" = _weakref.WeakKeyDictionary()
|
||||
p_settings_write_locks: "_weakref.WeakKeyDictionary" = p_weakref.WeakKeyDictionary()
|
||||
|
||||
|
||||
def settings_write_lock() -> asyncio.Lock:
|
||||
@@ -211,7 +211,7 @@ async def apply_settings_update(body: AppSettings, protect_fields: set[str] | No
|
||||
that must never be blanked by this write (the agent tool passes the field
|
||||
powering the live run): a SECOND, independent wall behind the endpoint's
|
||||
suicide-guard, so a guard bug still can't disconnect a run."""
|
||||
from backend.apps.service.client import sync as _sync
|
||||
from backend.apps.service.client import sync as p_sync
|
||||
|
||||
old = load_settings()
|
||||
for k in SERVER_OWNED_FIELDS:
|
||||
@@ -236,9 +236,9 @@ async def apply_settings_update(body: AppSettings, protect_fields: set[str] | No
|
||||
body.free_trial_token = None
|
||||
body.free_trial_remaining = None
|
||||
try:
|
||||
import asyncio as _aio
|
||||
from backend.apps.nine_router import sync_pro_routing as _spr
|
||||
_aio.create_task(_spr(body)) # drop the now-stale free-trial 9router node
|
||||
import asyncio as p_aio
|
||||
from backend.apps.nine_router import sync_pro_routing as p_spr
|
||||
p_aio.create_task(p_spr(body)) # drop the now-stale free-trial 9router node
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -246,11 +246,11 @@ async def apply_settings_update(body: AppSettings, protect_fields: set[str] | No
|
||||
"claude_subscription_token", "openai_subscription_token", "gemini_subscription_token",
|
||||
"openswarm_bearer_token", "free_trial_token", "installation_id"}
|
||||
safe = {k: v for k, v in body.model_dump().items() if k not in secret_keys}
|
||||
_sync(safe)
|
||||
p_sync(safe)
|
||||
|
||||
if (body.user_email and body.user_email != getattr(old, "user_email", None)) or \
|
||||
(body.user_name and body.user_name != getattr(old, "user_name", None)):
|
||||
from backend.apps.service.client import identify as _identify
|
||||
from backend.apps.service.client import identify as p_identify
|
||||
id_props = {}
|
||||
if body.user_email:
|
||||
id_props["email"] = body.user_email
|
||||
@@ -261,7 +261,7 @@ async def apply_settings_update(body: AppSettings, protect_fields: set[str] | No
|
||||
if body.user_referral_source:
|
||||
id_props["referral_source"] = body.user_referral_source
|
||||
if id_props:
|
||||
_identify(id_props)
|
||||
p_identify(id_props)
|
||||
|
||||
await save_settings_async(body)
|
||||
|
||||
@@ -310,15 +310,15 @@ async def apply_settings_update(body: AppSettings, protect_fields: set[str] | No
|
||||
):
|
||||
try:
|
||||
from backend.apps.nine_router import (
|
||||
ensure_running as _9r_ensure,
|
||||
is_running as _9r_running,
|
||||
ensure_running as p_9r_ensure,
|
||||
is_running as p_9r_running,
|
||||
sync_gemini_api_key,
|
||||
sync_openai_api_key,
|
||||
sync_openrouter_api_key,
|
||||
sync_custom_providers,
|
||||
)
|
||||
if need_boot and not _9r_running():
|
||||
await _9r_ensure()
|
||||
if need_boot and not p_9r_running():
|
||||
await p_9r_ensure()
|
||||
if do_google:
|
||||
await sync_gemini_api_key(google_key or None)
|
||||
if do_openai:
|
||||
@@ -473,15 +473,15 @@ def estimate_pdf_tokens(contents: bytes) -> int:
|
||||
Taking max() means a small page count on a huge PDF (image-heavy)
|
||||
still reads as expensive, and a huge page count on a small PDF still
|
||||
reads as expensive. The chip never lies that an attachment is cheap."""
|
||||
import re as _re
|
||||
import re as p_re
|
||||
by_pages = 0
|
||||
try:
|
||||
# Prefer the root catalog's /Pages entry. PDFs can have nested
|
||||
# /Count fields (outlines, sub-pages), so anchor on /Type /Pages.
|
||||
m = _re.search(rb"/Type\s*/Pages\b[^>]{0,200}?/Count\s+(\d+)", contents, _re.DOTALL)
|
||||
m = p_re.search(rb"/Type\s*/Pages\b[^>]{0,200}?/Count\s+(\d+)", contents, p_re.DOTALL)
|
||||
if not m:
|
||||
# Fallback: catalog declares /Pages then references /Count via /Kids.
|
||||
m = _re.search(rb"/Pages[^>]{0,200}?/Count\s+(\d+)", contents, _re.DOTALL)
|
||||
m = p_re.search(rb"/Pages[^>]{0,200}?/Count\s+(\d+)", contents, p_re.DOTALL)
|
||||
if m:
|
||||
pages = int(m.group(1))
|
||||
if 0 < pages < 10_000:
|
||||
|
||||
@@ -103,13 +103,13 @@ async def p_has_connected_subscription() -> bool:
|
||||
them; this catches a sub connected while the trial was armed."""
|
||||
try:
|
||||
from backend.apps.nine_router import (
|
||||
is_running as _9r_running,
|
||||
get_providers as _9r_providers,
|
||||
is_running as p_9r_running,
|
||||
get_providers as p_9r_providers,
|
||||
NINE_ROUTER_CLAUDE_PRO_NAME,
|
||||
)
|
||||
if not _9r_running():
|
||||
if not p_9r_running():
|
||||
return False
|
||||
conns = await _9r_providers()
|
||||
conns = await p_9r_providers()
|
||||
# Exclude our OWN managed node: the free trial registers itself as a `claude`
|
||||
# connection here, and counting it would make the trial think a real model is
|
||||
# connected and clear itself on the next boot (works once, dead on relaunch).
|
||||
@@ -172,8 +172,8 @@ async def arm_free_trial(settings_obj) -> dict:
|
||||
# lock with the boot auto-start), and skipped when a settings-level model
|
||||
# already proves there's nothing to shadow.
|
||||
try:
|
||||
from backend.apps.nine_router import ensure_running as _ensure_9r
|
||||
await _ensure_9r()
|
||||
from backend.apps.nine_router import ensure_running as p_ensure_9r
|
||||
await p_ensure_9r()
|
||||
except Exception:
|
||||
pass
|
||||
# 9Router's /api/providers can lag /v1/models (what is_running probes) by a
|
||||
|
||||
@@ -77,7 +77,7 @@ def p_sync_subscription_identity(settings_obj) -> None:
|
||||
paying-vs-free. Safe to call from hot paths; service-sync is fire-and-forget
|
||||
and swallows errors internally."""
|
||||
try:
|
||||
from backend.apps.service.client import identify as _identify
|
||||
from backend.apps.service.client import identify as p_identify
|
||||
except Exception:
|
||||
return
|
||||
mode = getattr(settings_obj, "connection_mode", "own_key")
|
||||
@@ -93,7 +93,7 @@ def p_sync_subscription_identity(settings_obj) -> None:
|
||||
if is_paying and expires:
|
||||
props["subscription_expires"] = expires
|
||||
try:
|
||||
_identify(props)
|
||||
p_identify(props)
|
||||
except Exception as e:
|
||||
logger.debug("identify sync failed: %s", e)
|
||||
|
||||
@@ -254,14 +254,14 @@ async def sync():
|
||||
already had."""
|
||||
# Lazy-import the service-sync helper so subscription/router doesn't pay the
|
||||
# cost when analytics are disabled.
|
||||
from backend.apps.service.client import sync as _sync
|
||||
from backend.apps.service.client import sync as p_sync
|
||||
|
||||
settings_obj = load_settings()
|
||||
bearer = getattr(settings_obj, "openswarm_bearer_token", None)
|
||||
mode = getattr(settings_obj, "connection_mode", "own_key")
|
||||
|
||||
if mode != "openswarm-pro" or not bearer:
|
||||
_sync(settings_obj.model_dump())
|
||||
p_sync(settings_obj.model_dump())
|
||||
return {"ok": True, "synced": False, "connection_mode": mode}
|
||||
|
||||
try:
|
||||
@@ -272,7 +272,7 @@ async def sync():
|
||||
)
|
||||
except httpx.HTTPError as e:
|
||||
logger.debug("subscription/sync live fetch failed: %s", e)
|
||||
_sync(settings_obj.model_dump())
|
||||
p_sync(settings_obj.model_dump())
|
||||
return {"ok": True, "synced": False, "reason": "network"}
|
||||
|
||||
# Same 401/402 handling as /status: if Stripe-side reconciliation proves
|
||||
@@ -281,7 +281,7 @@ async def sync():
|
||||
if r.status_code in (401, 402):
|
||||
await p_clear_subscription(settings_obj)
|
||||
reason = "revoked" if r.status_code == 401 else "expired"
|
||||
_sync(settings_obj.model_dump())
|
||||
p_sync(settings_obj.model_dump())
|
||||
return {
|
||||
"ok": True,
|
||||
"synced": False,
|
||||
@@ -291,7 +291,7 @@ async def sync():
|
||||
|
||||
if r.status_code != 200:
|
||||
logger.debug("subscription/sync got %s from cloud: %s", r.status_code, r.text[:200])
|
||||
_sync(settings_obj.model_dump())
|
||||
p_sync(settings_obj.model_dump())
|
||||
return {"ok": True, "synced": False, "reason": "upstream"}
|
||||
|
||||
data = r.json()
|
||||
@@ -309,7 +309,7 @@ async def sync():
|
||||
)
|
||||
await save_settings_async(settings_obj)
|
||||
p_sync_subscription_identity(settings_obj)
|
||||
_sync(settings_obj.model_dump())
|
||||
p_sync(settings_obj.model_dump())
|
||||
return {
|
||||
"ok": True,
|
||||
"synced": bool(data.get("synced")),
|
||||
|
||||
@@ -28,7 +28,7 @@ P_DENY_EXACT = {
|
||||
from backend.common.secret_scan import ( # noqa: E402
|
||||
REDACTED,
|
||||
find_secrets_in_files,
|
||||
looks_secret as _looks_secret,
|
||||
looks_secret as p_looks_secret,
|
||||
redact_secret_shapes as scrub_text,
|
||||
)
|
||||
|
||||
|
||||
@@ -245,9 +245,9 @@ def derive_mcp_config(tool: ToolDefinition) -> Optional[dict]:
|
||||
npm_dir = os.path.join(p_backend, "npm-servers", safe_dir)
|
||||
pkg_json_path = os.path.join(npm_dir, "node_modules", pkg_name, "package.json")
|
||||
if os.path.isfile(pkg_json_path):
|
||||
import json as _json
|
||||
import json as p_json
|
||||
with open(pkg_json_path) as f:
|
||||
pkg_meta = _json.load(f)
|
||||
pkg_meta = p_json.load(f)
|
||||
bin_field = pkg_meta.get("bin", {})
|
||||
entry = list(bin_field.values())[0] if isinstance(bin_field, dict) else bin_field
|
||||
# Same priority as 9Router / MCP-bundle paths: bundled node > system node > Electron-as-Node.
|
||||
|
||||
@@ -525,8 +525,8 @@ async def m365_device_login(tool_id: str):
|
||||
login_state["status"] = "connected"
|
||||
# Try to extract email from output
|
||||
try:
|
||||
import json as _j
|
||||
result = _j.loads(login_state["output"].strip().split("\n")[-1])
|
||||
import json as p_j
|
||||
result = p_j.loads(login_state["output"].strip().split("\n")[-1])
|
||||
if result.get("success"):
|
||||
ud = result.get("userData", {})
|
||||
login_state["email"] = ud.get("userPrincipalName") or ud.get("displayName")
|
||||
|
||||
Reference in New Issue
Block a user