项目文件夹

文件
wehub-resource-sync c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

274 行
9.0 KiB
Python

from __future__ import annotations
import hashlib
import re
from datetime import datetime, timezone
from threading import RLock
from typing import Iterable, Optional
from uuid import UUID
from cognee.modules.agents.models import (
AgentConnection,
AgentConnectionType,
AgentDatasetRef,
AgentMemoryMode,
AgentSource,
MemorySourceType,
)
from cognee.shared.logging_utils import get_logger
logger = get_logger("agents.registry")
AGENT_CONFIG_NAME = "agent_configuration"
_registered_agent_connections: dict[str, AgentConnection] = {}
_registry_lock = RLock()
def classify_memory_source_type(name: str | None) -> MemorySourceType:
normalized = (name or "").lower()
if "brain" in normalized:
return "company_brain"
if "wiki" in normalized:
return "knowledge_wiki"
if "project" in normalized:
return "project_dataset"
return "dataset"
def derive_memory_mode(
*,
with_memory: bool = False,
with_session_memory: bool = False,
save_session_traces: bool = False,
) -> AgentMemoryMode:
if with_memory and (with_session_memory or save_session_traces):
return "hybrid"
if with_memory:
return "cognee"
if with_session_memory or save_session_traces:
return "session"
return "none"
def derive_connection_type(
*,
origin_function: str | None = None,
session_id: str | None = None,
source: str | None = None,
) -> AgentConnectionType:
source_lower = (source or "").lower()
if source_lower in {"mcp", "api", "api_key", "serve", "workflow", "sdk"}:
if source_lower == "serve":
return "api"
if source_lower == "api_key":
return "api"
return source_lower # type: ignore[return-value]
text = f"{origin_function or ''} {session_id or ''}".lower()
if "claude" in text or "claude_code" in text or text.startswith("cc_"):
return "claude_code"
if "mcp" in text:
return "mcp"
return "sdk" if origin_function else "unknown"
def build_agent_connection_id(
*,
agent_session_name: str,
user_id: str | None = None,
) -> str:
identity = f"{agent_session_name}|{user_id or ''}"
digest = hashlib.sha1(identity.encode("utf-8")).hexdigest()[:16]
base = re.sub(r"[^a-zA-Z0-9_-]+", "-", agent_session_name).strip("-")
base = base[-48:] if len(base) > 48 else base
return f"{base or 'agent'}-{digest}"
def _normalize_datasets(datasets: Iterable[AgentDatasetRef | dict] | None) -> list[AgentDatasetRef]:
normalized = []
for dataset in datasets or []:
if isinstance(dataset, AgentDatasetRef):
ref = dataset
else:
ref = AgentDatasetRef(**dataset)
if ref.type == "dataset":
ref = ref.model_copy(update={"type": classify_memory_source_type(ref.name)})
normalized.append(ref)
return normalized
async def _persist_agent_connection(user_id: UUID, connection: AgentConnection) -> None:
from cognee.modules.users.methods.get_principal_configuration import (
get_principal_all_configuration,
)
from cognee.modules.users.methods.store_principal_configuration import (
store_principal_configuration,
)
all_configs = await get_principal_all_configuration(user_id)
existing_config = {}
for config in all_configs:
if config.get("name") == AGENT_CONFIG_NAME:
existing_config = config.get("configuration", {})
break
agents = existing_config.get("agents", {})
agents[connection.id] = connection.model_dump(mode="json")
await store_principal_configuration(
principal_id=user_id,
name=AGENT_CONFIG_NAME,
configuration={**existing_config, "agents": agents},
)
async def register_agent_connection(
*,
agent_session_name: str,
connection_type: AgentConnectionType = "unknown",
memory_mode: AgentMemoryMode = "unknown",
source: AgentSource = "api",
agent_id: Optional[str] = None,
origin_function: Optional[str] = None,
user_id: Optional[UUID] = None,
tenant_id: Optional[UUID] = None,
session_id: Optional[str] = None,
datasets: Iterable[AgentDatasetRef | dict] | None = None,
status: str = "active",
last_active_at: Optional[datetime] = None,
metadata: Optional[dict] = None,
) -> AgentConnection:
dataset_refs = _normalize_datasets(datasets)
resolved_agent_id = agent_id or build_agent_connection_id(
agent_session_name=agent_session_name,
user_id=str(user_id) if user_id is not None else None,
)
connection = AgentConnection(
id=resolved_agent_id,
agent_session_name=agent_session_name,
type=connection_type,
memory_mode=memory_mode,
session_id=session_id,
user_id=user_id,
tenant_id=tenant_id,
datasets=dataset_refs,
last_active_at=last_active_at or datetime.now(timezone.utc),
status=status if status in {"active", "inactive", "unknown"} else "unknown",
source=source,
origin_function=origin_function,
metadata=metadata or {},
)
with _registry_lock:
existing = _registered_agent_connections.get(connection.id)
if existing:
merged_metadata = {**existing.metadata, **connection.metadata}
connection = connection.model_copy(update={"metadata": merged_metadata})
_registered_agent_connections[connection.id] = connection
if user_id:
await _persist_agent_connection(user_id, connection)
return connection
def list_registered_agent_connections() -> list[AgentConnection]:
with _registry_lock:
return list(_registered_agent_connections.values())
async def list_persisted_agent_connections(
user_ids: list[UUID], active_only: bool = True
) -> list[AgentConnection]:
from cognee.modules.users.methods.get_principal_configuration import (
get_principal_all_configuration,
)
agents: list[AgentConnection] = []
for user_id in user_ids:
all_configs = await get_principal_all_configuration(user_id)
for config in all_configs:
if config.get("name") == AGENT_CONFIG_NAME:
agents_dict = config.get("configuration", {}).get("agents", {})
for data in agents_dict.values():
connection = AgentConnection(**data)
if not active_only or connection.status == "active":
agents.append(connection)
return agents
def _remove_from_registry(user_id: UUID) -> None:
with _registry_lock:
to_remove = [
key
for key, conn in _registered_agent_connections.items()
if conn.user_id is not None and conn.user_id == user_id
]
for key in to_remove:
del _registered_agent_connections[key]
def _remove_connection_from_registry(connection_id: str) -> None:
with _registry_lock:
_registered_agent_connections.pop(connection_id, None)
async def deactivate_agent_connection(user_id: UUID, connection_id: str) -> None:
_remove_connection_from_registry(connection_id)
await _deactivate_persisted_connection(user_id, connection_id)
async def delete_user_agent_connections(user_id: UUID) -> None:
_remove_from_registry(user_id)
await _delete_persisted_agent_connections(user_id)
async def _deactivate_persisted_connection(user_id: UUID, connection_id: str) -> None:
from cognee.modules.users.methods.get_principal_configuration import (
get_principal_all_configuration,
)
from cognee.modules.users.methods.store_principal_configuration import (
store_principal_configuration,
)
all_configs = await get_principal_all_configuration(user_id)
for config in all_configs:
if config.get("name") == AGENT_CONFIG_NAME:
existing_config = config.get("configuration", {})
agents = existing_config.get("agents", {})
if connection_id in agents:
agents[connection_id]["status"] = "inactive"
await store_principal_configuration(
principal_id=user_id,
name=AGENT_CONFIG_NAME,
configuration={**existing_config, "agents": agents},
)
return
async def _delete_persisted_agent_connections(user_id: UUID) -> None:
from cognee.modules.users.methods.get_principal_configuration import (
get_principal_all_configuration,
)
from cognee.modules.users.methods.store_principal_configuration import (
store_principal_configuration,
)
all_configs = await get_principal_all_configuration(user_id)
for config in all_configs:
if config.get("name") == AGENT_CONFIG_NAME:
existing_config = config.get("configuration", {})
existing_config.pop("agents", None)
await store_principal_configuration(
principal_id=user_id,
name=AGENT_CONFIG_NAME,
configuration=existing_config,
)
return
def clear_registered_agent_connections() -> None:
with _registry_lock:
_registered_agent_connections.clear()