Files
Agentswarm/orchestrator/swarm_runtime.py
T
2026-06-08 17:32:34 +08:00

782 lines
31 KiB
Python

"""Agent Manager compatible swarm runtime bridge."""
import asyncio
from copy import deepcopy
import hashlib
import hmac
import json
import logging
import os
import time
import uuid
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional
import httpx
from pydantic import BaseModel, Field
from .redis_client import redis_client
logger = logging.getLogger(__name__)
class CallbackConfig(BaseModel):
"""Callback settings provided by Agent Manager."""
url: Optional[str] = None
signing_secret_ref: Optional[str] = None
subscribed_events: List[str] = Field(default_factory=list)
class SwarmRun(BaseModel):
"""Runtime-owned representation of a swarm run."""
deployment_id: str
swarm_id: str
mode: str = "swarm"
status: str
objective: str
manager_deployment_id: Optional[str] = None
correlation_id: Optional[str] = None
callback: CallbackConfig = Field(default_factory=CallbackConfig)
task_ids: List[str] = Field(default_factory=list)
approvals: Dict[str, Dict[str, Any]] = Field(default_factory=dict)
metadata: Dict[str, Any] = Field(default_factory=dict)
request_body: Dict[str, Any] = Field(default_factory=dict)
created_at: float = Field(default_factory=time.time)
updated_at: float = Field(default_factory=time.time)
class RuntimeValidationError(ValueError):
"""Validation error returned in the Agent Manager runtime envelope."""
def __init__(self, message: str, code: str = "VALIDATION_ERROR"):
super().__init__(message)
self.message = message
self.code = code
class SwarmRuntime:
"""Stores swarm runs and emits Agent Manager callback events."""
RUN_KEY_PREFIX = "swarm:"
TASK_RUN_KEY_PREFIX = "swarm_task:"
IDEMPOTENCY_KEY_PREFIX = "swarm_idempotency:"
EVENT_KEY_PREFIX = "swarm_events:"
def __init__(self):
self.callback_service_token = (
os.getenv("AGENT_CALLBACK_SERVICE_TOKEN")
or os.getenv("AGNET_CALLBACK_SERVICE_TOKEN")
)
self.callback_signing_secret = (
os.getenv("AGENT_CALLBACK_SIGNING_SECRET")
or os.getenv("AGNET_CALLBACK_SIGNING_SECRET")
)
self.runtime_source = os.getenv("SWARM_RUNTIME_SOURCE", "heicode-swarm-runtime")
def multi_agent_workflow_enabled(self, body: Optional[Dict[str, Any]] = None) -> bool:
"""Return whether the DAG-style runtime workflow is enabled."""
if os.getenv("ENABLE_SUBTASK_HANDOFF", "false").lower() not in {"1", "true", "yes"}:
return False
plan = (body or {}).get("orchestration_plan") or {}
agents = plan.get("agents") or (body or {}).get("agents") or []
return len(agents) > 0
async def health(self) -> Dict[str, Any]:
"""Return Agent Manager compatible runtime health."""
await redis_client.client.ping()
return {
"success": True,
"data": {
"status": "healthy",
"service": "heicode-swarm-runtime",
"version": "1.0.0",
"runtime": os.getenv("SWARM_RUNTIME_PLATFORM", "aks"),
"time": self._now_iso(),
"capabilities": [
"swarm.create",
"task.flow",
"handoff.events",
"artifact.events",
"approval.pause_resume",
"deployment.stop",
"runtime.tasks.query",
"runtime.logs.query",
"runtime.events.query",
"runtime.metrics.query",
"runtime.workflow.query",
"runtime.diagnostics.query",
],
},
}
def normalize_create_request(self, body: Dict[str, Any]) -> Dict[str, Any]:
"""Normalize the Manager swarm request into the runtime request shape."""
normalized = deepcopy(body or {})
metadata = dict(normalized.get("metadata") or {})
callback = dict(normalized.get("callback") or {})
requirement = dict(normalized.get("requirement") or {})
model_selection = dict(normalized.get("model_selection") or {})
existing_plan = dict(normalized.get("orchestration_plan") or {})
uses_new_shape = normalized.get("mode") == "swarm" or bool(requirement)
if uses_new_shape:
primary_model = (
model_selection.get("primary_model")
or existing_plan.get("model_id")
or normalized.get("model_id")
)
budget = deepcopy(
normalized.get("budget")
or existing_plan.get("budget")
or {}
)
if not existing_plan.get("objective") and requirement.get("objective"):
existing_plan["objective"] = requirement.get("objective")
existing_plan.setdefault("sub_mode", "swarm")
existing_plan.setdefault("risk_level", normalized.get("risk_level") or "medium")
existing_plan.setdefault("budget", budget)
existing_plan["model_id"] = primary_model
existing_plan["requirement"] = self._redact_sensitive(requirement)
existing_plan["attachments"] = self._redact_sensitive(
requirement.get("attachments") or []
)
existing_plan["constraints"] = self._redact_sensitive(
requirement.get("constraints") or []
)
existing_plan["acceptance_criteria"] = self._redact_sensitive(
requirement.get("acceptance_criteria") or []
)
if not existing_plan.get("agents"):
existing_plan["agents"] = normalized.get("agents") or []
normalized["mode"] = "swarm"
normalized["conversation_id"] = (
normalized.get("conversation_id")
or metadata.get("conversation_id")
)
normalized["requirement"] = requirement
normalized["model_selection"] = model_selection
normalized["model_id"] = primary_model
normalized["orchestration_plan"] = existing_plan
if normalized.get("conversation_id"):
metadata.setdefault("conversation_id", normalized.get("conversation_id"))
if requirement.get("objective"):
metadata.setdefault("objective", requirement.get("objective"))
if model_selection.get("type"):
metadata.setdefault("model_selection_type", model_selection.get("type"))
else:
normalized["orchestration_plan"] = existing_plan
normalized["metadata"] = metadata
normalized["callback"] = callback
return normalized
def validate_create_request(self, body: Dict[str, Any]):
"""Validate the Manager create request before a runtime run is persisted."""
normalized = self.normalize_create_request(body)
plan = normalized.get("orchestration_plan")
metadata = normalized.get("metadata")
callback = normalized.get("callback")
required_paths = {
"orchestration_plan.objective": plan.get("objective") if isinstance(plan, dict) else None,
"callback.url": callback.get("url") if isinstance(callback, dict) else None,
"metadata.manager_deployment_id": metadata.get("manager_deployment_id") if isinstance(metadata, dict) else None,
}
missing = [path for path, value in required_paths.items() if value in (None, "", [], {})]
if missing:
raise RuntimeValidationError(f"Missing required field(s): {', '.join(missing)}")
if normalized.get("mode") not in (None, "swarm"):
raise RuntimeValidationError("mode must be 'swarm'")
if normalized.get("model_selection"):
selection_type = (normalized.get("model_selection") or {}).get("type")
if selection_type not in (None, "primary"):
raise RuntimeValidationError("model_selection.type must be 'primary' for swarm")
billing_secret = (normalized.get("billing_context") or {}).get("secret_ref")
if billing_secret and not self._is_azkv_ref(billing_secret):
raise RuntimeValidationError("billing_context.secret_ref must use azkv://")
self._validate_resource_grants(normalized.get("resource_grants") or [], "resource_grants")
for index, agent in enumerate(plan.get("agents") or []):
self._validate_resource_grants(
agent.get("resource_grants") or [],
f"orchestration_plan.agents[{index}].resource_grants",
)
for index, agent in enumerate(normalized.get("agents") or []):
self._validate_resource_grants(
agent.get("resource_grants") or [],
f"agents[{index}].resource_grants",
)
for path in ("metadata", "resource_grants", "callback"):
value = normalized.get(path)
if value is not None:
self._reject_plaintext_secrets(value, path)
async def get_or_create_run(
self,
body: Dict[str, Any],
idempotency_key: Optional[str],
correlation_id: Optional[str],
) -> tuple[SwarmRun, bool]:
"""Create a swarm run or return the previous run for an idempotency key."""
body = self.normalize_create_request(body)
if idempotency_key:
existing_swarm_id = await redis_client.get(
f"{self.IDEMPOTENCY_KEY_PREFIX}{idempotency_key}"
)
if existing_swarm_id:
existing_run = await self.get_run(existing_swarm_id)
if existing_run:
return existing_run, False
metadata = body.get("metadata") or {}
plan = body.get("orchestration_plan") or {}
callback = CallbackConfig.model_validate(body.get("callback") or {})
swarm_id = f"swarm-{uuid.uuid4().hex[:12]}"
deployment_id = f"runtime-dep-{uuid.uuid4().hex[:12]}"
manager_deployment_id = (
metadata.get("manager_deployment_id")
or metadata.get("heicode_deployment_id")
)
objective = (
plan.get("objective")
or metadata.get("objective")
or "Swarm runtime task"
)
run = SwarmRun(
deployment_id=deployment_id,
swarm_id=swarm_id,
mode="swarm",
status="running",
objective=objective,
manager_deployment_id=manager_deployment_id,
correlation_id=correlation_id or metadata.get("correlation_id"),
callback=callback,
metadata=self._redact_sensitive(metadata),
request_body=self._redact_sensitive(body),
)
if self._requires_approval(body):
approval = self._build_approval(body, run)
run.status = "waiting_approval"
run.approvals[approval["approval_id"]] = approval
await self.save_run(run)
if idempotency_key:
await redis_client.set(
f"{self.IDEMPOTENCY_KEY_PREFIX}{idempotency_key}",
run.swarm_id,
ex=86400,
)
await self.emit_event(
run,
"deployment.status_changed",
payload=self.status_payload(run, phase="Plan"),
)
for approval in run.approvals.values():
await self.emit_event(run, "approval.requested", payload=approval)
return run, True
async def save_run(self, run: SwarmRun):
"""Persist a swarm run."""
run.updated_at = time.time()
await redis_client.set(
f"{self.RUN_KEY_PREFIX}{run.swarm_id}",
run.model_dump_json(),
)
async def get_run(self, swarm_id: str) -> Optional[SwarmRun]:
"""Get a swarm run by id."""
data = await redis_client.get(f"{self.RUN_KEY_PREFIX}{swarm_id}")
if not data:
return None
return SwarmRun.model_validate_json(data)
async def get_run_by_identifier(self, identifier: str) -> Optional[SwarmRun]:
"""Find a run by swarm id, runtime deployment id, or manager deployment id."""
direct = await self.get_run(identifier)
if direct:
return direct
for key in await redis_client.keys(f"{self.RUN_KEY_PREFIX}*"):
data = await redis_client.get(key)
if not data:
continue
run = SwarmRun.model_validate_json(data)
if identifier in {run.deployment_id, run.manager_deployment_id, run.swarm_id}:
return run
return None
async def get_run_for_task(self, task_id: str) -> Optional[SwarmRun]:
"""Find the swarm run that owns a task."""
swarm_id = await redis_client.get(f"{self.TASK_RUN_KEY_PREFIX}{task_id}")
if not swarm_id:
return None
return await self.get_run(swarm_id)
async def attach_task(self, run: SwarmRun, task_id: str):
"""Associate a queue task with a swarm run."""
if task_id not in run.task_ids:
run.task_ids.append(task_id)
await redis_client.set(f"{self.TASK_RUN_KEY_PREFIX}{task_id}", run.swarm_id)
await self.save_run(run)
async def stop_run(self, deployment_id: str, reason: str = "") -> Optional[SwarmRun]:
"""Stop a run by runtime deployment id or swarm id."""
run = await self.find_run_by_deployment_id(deployment_id)
if not run:
return None
run.status = "stopped"
await self.save_run(run)
await self.emit_event(
run,
"deployment.status_changed",
payload=self.status_payload(
run,
phase="Deliver",
reason=reason or "Heicode Manager requested stop",
),
)
return run
async def find_run_by_deployment_id(self, deployment_id: str) -> Optional[SwarmRun]:
"""Find a run by runtime deployment id or swarm id."""
return await self.get_run_by_identifier(deployment_id)
async def record_approval_decision(
self,
swarm_id: str,
approval_id: str,
decision: Dict[str, Any],
) -> Optional[SwarmRun]:
"""Persist an approval decision and update run state."""
run = await self.get_run_by_identifier(swarm_id)
if not run:
return None
approval = run.approvals.get(approval_id, {"approval_id": approval_id})
approval["decision"] = decision.get("decision")
credential_lease = decision.get("credential_lease") or {}
approval["credential_ref"] = (
decision.get("credential_ref") or credential_lease.get("credential_ref")
)
approval["lease_id"] = decision.get("lease_id") or credential_lease.get("lease_id")
approval["lease_expires_at"] = (
decision.get("lease_expires_at") or credential_lease.get("expires_at")
)
approval["decided_at"] = self._now_iso()
run.approvals[approval_id] = self._redact_sensitive(approval)
if decision.get("decision") == "approved":
run.status = "running"
elif decision.get("decision") == "rejected":
run.status = "blocked"
await self.save_run(run)
await self.emit_event(
run,
"deployment.status_changed",
payload=self.status_payload(
run,
phase="Review",
approval_id=approval_id,
decision=decision.get("decision"),
reason=decision.get("reason"),
),
)
if run.status == "blocked":
await self.emit_event(run, "task.blocked", payload={
"approval_id": approval_id,
"reason": decision.get("reason") or "Approval rejected",
"runtime_deployment_id": run.deployment_id,
})
await self.emit_event(run, "timeline.updated", payload={
"summary": "Swarm blocked by approval rejection",
"approval_id": approval_id,
})
return run
async def emit_event(
self,
run: SwarmRun,
event_type: str,
task_id: Optional[str] = None,
agent_instance_id: Optional[str] = None,
payload: Optional[Dict[str, Any]] = None,
artifact: Optional[Dict[str, Any]] = None,
):
"""Record and optionally emit a Manager callback event."""
callback = run.callback
redacted_payload = self._redact_sensitive(payload or {})
redacted_artifact = self._redact_sensitive(artifact) if artifact else None
if redacted_artifact and event_type == "artifact.created":
redacted_payload = {
**redacted_artifact,
**redacted_payload,
}
event_id = f"evt_{uuid.uuid4().hex}"
body: Dict[str, Any] = {
"event_id": event_id,
"idempotency_key": event_id,
"event_type": event_type,
"deployment_id": run.manager_deployment_id or run.deployment_id,
"runtime_deployment_id": run.deployment_id,
"swarm_id": run.swarm_id,
"agent_instance_id": agent_instance_id,
"task_id": task_id,
"occurred_at": self._now_iso(),
"correlation_id": run.correlation_id,
"source": self.runtime_source,
"payload": redacted_payload,
}
if redacted_artifact:
body["artifact"] = redacted_artifact
raw_body = json.dumps(body, ensure_ascii=False, separators=(",", ":"))
await self._store_event(run.swarm_id, raw_body)
if not callback.url:
return
if callback.subscribed_events and event_type not in callback.subscribed_events:
return
headers = {
"Content-Type": "application/json",
"X-Agent-Event-Id": event_id,
"X-Agnet-Event-Id": event_id,
}
if run.correlation_id:
headers["X-Correlation-ID"] = run.correlation_id
if self.callback_service_token:
headers["X-Agent-Service-Token"] = self.callback_service_token
headers["X-Agnet-Service-Token"] = self.callback_service_token
if self.callback_signing_secret:
timestamp = str(int(time.time() * 1000))
signature_payload = f"{timestamp}.{event_id}.{raw_body}"
signature = hmac.new(
self.callback_signing_secret.encode("utf-8"),
signature_payload.encode("utf-8"),
hashlib.sha256,
).hexdigest()
headers["X-Agent-Timestamp"] = timestamp
headers["X-Agent-Signature"] = f"sha256={signature}"
headers["X-Agnet-Timestamp"] = timestamp
headers["X-Agnet-Signature"] = f"sha256={signature}"
if callback.url and (not callback.subscribed_events or event_type in callback.subscribed_events):
await self._upsert_callback_attempt(
run.swarm_id,
event_id,
{
"event_id": event_id,
"event_type": event_type,
"url": callback.url,
"status": "pending",
"attempted_at": self._now_iso(),
},
)
asyncio.create_task(
self._post_callback(run.swarm_id, callback.url, raw_body, headers, event_type, event_id)
)
async def list_events(
self,
swarm_id: str,
limit: int = 100,
cursor: Optional[str] = None,
) -> Dict[str, Any]:
"""Return stored runtime events for a swarm."""
start = int(cursor or 0)
safe_limit = max(1, min(limit, 500))
items = await redis_client.lrange(
f"{self.EVENT_KEY_PREFIX}{swarm_id}",
start,
start + safe_limit - 1,
)
events = [json.loads(item) for item in items]
next_cursor = str(start + safe_limit) if len(events) == safe_limit else None
return {"events": events, "next_cursor": next_cursor}
async def _store_event(self, swarm_id: str, raw_body: str):
await redis_client.rpush(f"{self.EVENT_KEY_PREFIX}{swarm_id}", raw_body)
async def _post_callback(
self,
swarm_id: str,
url: str,
raw_body: str,
headers: Dict[str, str],
event_type: str,
event_id: str,
):
"""Send callback without blocking the agent WebSocket loop."""
if not url:
return
try:
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.post(url, content=raw_body, headers=headers)
await self._upsert_callback_attempt(
swarm_id,
event_id,
{
"event_id": event_id,
"event_type": event_type,
"url": url,
"status": "delivered" if response.status_code < 400 else "failed",
"response_status": response.status_code,
"attempted_at": self._now_iso(),
},
)
if response.status_code >= 400:
logger.warning(
"Manager callback %s failed with status %s: %s",
event_type,
response.status_code,
response.text[:500],
)
except Exception as exc:
await self._upsert_callback_attempt(
swarm_id,
event_id,
{
"event_id": event_id,
"event_type": event_type,
"url": url,
"status": "failed",
"error": str(exc),
"attempted_at": self._now_iso(),
},
)
logger.warning("Manager callback %s failed: %s", event_type, exc)
def build_task_descriptions(self, body: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Create a simple task graph from a Manager orchestration request."""
body = self.normalize_create_request(body)
plan = body.get("orchestration_plan") or {}
agents = plan.get("agents") or body.get("agents") or []
requirement = body.get("requirement") or {}
objective = (
requirement.get("objective")
or plan.get("objective")
or "Complete swarm objective"
)
multi_agent_enabled = self.multi_agent_workflow_enabled(body)
context = {
"orchestration_plan": self._redact_sensitive(plan),
"resource_grants": self._redact_sensitive(body.get("resource_grants") or []),
"sub_mode": body.get("sub_mode") or plan.get("sub_mode"),
"conversation_id": body.get("conversation_id"),
"mode": body.get("mode") or "swarm",
"requirement": self._redact_sensitive(requirement),
}
if not agents or not multi_agent_enabled:
return [{
"task_id": "task-1",
"title": "Swarm objective",
"description": objective,
"agent_role": "general",
"required_capabilities": ["general"],
"depends_on": [],
"parent_task_id": None,
"root_task_id": "task-1",
"source": "runtime_bridge",
"workflow_mode": "single_agent",
"allow_handoff": False,
"context": context,
}]
tasks = []
for index, agent in enumerate(agents, start=1):
role = agent.get("role") or f"agent-{index}"
title = agent.get("title") or f"{role} task"
description = agent.get("description") or f"[{role}] {objective}"
task_id = agent.get("task_id") or f"task-{index}"
required_capabilities = agent.get("required_capabilities") or [role]
tasks.append({
"task_id": task_id,
"title": title,
"description": description,
"agent_role": role,
"required_capabilities": required_capabilities,
"depends_on": agent.get("depends_on") or [],
"parent_task_id": None,
"root_task_id": task_id,
"source": "runtime_bridge",
"workflow_mode": "multi_agent",
"allow_handoff": True,
"context": {
**context,
"agent_role": role,
"workflow_mode": "multi_agent",
"resource_grants": self._redact_sensitive(
agent.get("resource_grants") or []
),
},
})
return tasks
def task_event_payload(self, task: Any, task_spec: Dict[str, Any]) -> Dict[str, Any]:
"""Return the minimum task graph payload required by Manager."""
return {
"task_id": task.task_id,
"title": task.title or task_spec.get("title", task.description[:80]),
"description": task.description,
"agent_role": task.agent_role or task_spec.get("agent_role", "general"),
"status": task.status.value if hasattr(task.status, "value") else task.status,
"depends_on": task.depends_on or task_spec.get("depends_on") or [],
"parent_task_id": task.parent_task_id or task_spec.get("parent_task_id"),
"root_task_id": task.root_task_id or task_spec.get("root_task_id"),
"required_capabilities": task.required_capabilities or task_spec.get("required_capabilities") or [],
"source": task.source or task_spec.get("source", "runtime_bridge"),
"attempt": getattr(task, "retry_count", 0),
}
def _requires_approval(self, body: Dict[str, Any]) -> bool:
plan = body.get("orchestration_plan") or {}
agile = plan.get("agile_context") or {}
risk = str(plan.get("risk_level") or body.get("risk_level") or "").lower()
return bool(agile.get("requires_user_approval")) or risk == "high"
def status_payload(
self,
run: SwarmRun,
phase: str,
reason: Optional[str] = None,
approval_id: Optional[str] = None,
decision: Optional[str] = None,
deliverable: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""Build the standard runtime status payload."""
payload: Dict[str, Any] = {
"status": run.status,
"runtime_execution_status": run.status,
"runtime_deployment_id": run.deployment_id,
"manager_deployment_id": run.manager_deployment_id,
"phase": phase,
}
if reason:
payload["reason"] = reason
if approval_id:
payload["approval_id"] = approval_id
if decision:
payload["decision"] = decision
if deliverable is not None:
payload["deliverable"] = deliverable
return payload
async def _upsert_callback_attempt(
self,
swarm_id: str,
event_id: str,
attempt: Dict[str, Any],
):
run = await self.get_run(swarm_id)
if not run:
return
callback_attempts = list(run.metadata.get("callback_attempts") or [])
filtered = [item for item in callback_attempts if item.get("event_id") != event_id]
filtered.append(self._redact_sensitive(attempt))
run.metadata["callback_attempts"] = filtered[-50:]
await self.save_run(run)
def _build_approval(self, body: Dict[str, Any], run: SwarmRun) -> Dict[str, Any]:
grants = body.get("resource_grants") or []
grant = grants[0] if grants else {}
return {
"approval_id": f"appr_{uuid.uuid4().hex[:12]}",
"operation": "git.write",
"resource_id": grant.get("resource_id", "repo-main"),
"resource_type": grant.get("resource_type", "git"),
"resource_scope": ",".join(grant.get("permission_scope") or []),
"target_role": grant.get("target_role", "general"),
"risk_level": "high",
"requires_credential": True,
"secret_ref": grant.get("secret_ref") or grant.get("ref"),
"ttl_seconds": 900,
"reason": "High-risk swarm run requires Manager approval",
"runtime_deployment_id": run.deployment_id,
}
def _validate_resource_grants(self, grants: List[Dict[str, Any]], path: str):
for index, grant in enumerate(grants):
for key in ("secret_ref", "ref"):
value = grant.get(key)
if value and not self._is_azkv_ref(value):
raise RuntimeValidationError(f"{path}[{index}].{key} must use azkv://")
def _reject_plaintext_secrets(self, value: Any, path: str):
if isinstance(value, dict):
for key, item in value.items():
child_path = f"{path}.{key}"
key_lower = key.lower()
is_ref_key = key_lower.endswith("_ref") or key_lower == "ref"
if self._looks_sensitive_key(key_lower) and not is_ref_key:
raise RuntimeValidationError(
f"Plaintext secret-like field is not allowed: {child_path}"
)
if is_ref_key and isinstance(item, str) and item and not self._is_azkv_ref(item):
raise RuntimeValidationError(f"{child_path} must use azkv://")
self._reject_plaintext_secrets(item, child_path)
elif isinstance(value, list):
for index, item in enumerate(value):
self._reject_plaintext_secrets(item, f"{path}[{index}]")
def _looks_sensitive_key(self, key: str) -> bool:
return (
any(part in key for part in ("token", "password", "passwd", "secret", "private_key", "api_key"))
or key.endswith("_key")
)
def _is_azkv_ref(self, value: Any) -> bool:
return isinstance(value, str) and value.startswith("azkv://")
def _redact_sensitive(self, value: Any) -> Any:
"""Remove obvious plaintext secrets from callback-safe payloads."""
sensitive_keys = {
"password",
"passwd",
"token",
"api_token",
"access_token",
"refresh_token",
"private_key",
"access_key",
"secret",
"client_secret",
"connection_string",
}
if isinstance(value, dict):
redacted = {}
for key, item in value.items():
key_lower = key.lower()
if key_lower in {"secret_ref", "credential_ref", "signing_secret_ref"}:
redacted[key] = item
elif key_lower in sensitive_keys or key_lower.endswith(("_token", "_secret", "_password", "_key")):
redacted[key] = "[redacted]"
else:
redacted[key] = self._redact_sensitive(item)
return redacted
if isinstance(value, list):
return [self._redact_sensitive(item) for item in value]
return value
def _now_iso(self) -> str:
return datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
swarm_runtime = SwarmRuntime()