feat(org): model grants, org memory, MCP gateway (v2 phases A1-3..5)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
c93b25741e
commit
dee2f72c46
@@ -1,44 +1,86 @@
|
||||
"""Wiring for the org-platform workstream (memory, model grants).
|
||||
|
||||
Foundation defaults: no memory, and every active model granted to every org (today's
|
||||
behaviour). The org-platform agent replaces the bodies with the real services; the
|
||||
function names and return types are FROZEN so other workstreams can call them now.
|
||||
``build_memory`` is the frozen ``MemoryPort`` builder the engine calls; it now
|
||||
returns the real ``MemoryService``. ``build_memory_service`` is the same object,
|
||||
typed for the router (list, teach, pin, confirm, delete). ``build_model_grants``
|
||||
returns the real ``ModelGrantService``; ``build_model_grant_service`` is its
|
||||
typed twin for the admin router.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.application.ports.memory import MemoryPort, NullMemory
|
||||
from app.application.ports.model_grants import (
|
||||
AllActiveModelsGrants,
|
||||
GrantedModel,
|
||||
ModelGrantPort,
|
||||
tier_for,
|
||||
from app.application.ports.memory import MemoryPort
|
||||
from app.application.ports.model_grants import ModelGrantPort
|
||||
from app.application.services.memory_service import MemoryService
|
||||
from app.application.services.model_grant_service import ModelGrantService
|
||||
from app.infrastructure.repositories.ai_control import (
|
||||
AiModelRepository,
|
||||
ModelCredentialRepository,
|
||||
RateCardRepository,
|
||||
)
|
||||
from app.infrastructure.repositories.audit import UsageLedgerRepository
|
||||
from app.infrastructure.repositories.memory import MemoryRepository
|
||||
from app.infrastructure.repositories.org_grants import (
|
||||
DefaultModelGrantRepository,
|
||||
OrgModelGrantRepository,
|
||||
OrgPolicyRepository,
|
||||
)
|
||||
from app.infrastructure.db.models import AiModelRow
|
||||
|
||||
_null_memory = NullMemory()
|
||||
|
||||
|
||||
def build_memory(session: AsyncSession) -> MemoryPort:
|
||||
return _null_memory
|
||||
"""The real memory service: recall, teach, and one reflection per task.
|
||||
|
||||
``get_model_provider`` is resolved from ``container``'s namespace rather
|
||||
than from the registry directly: that module is what the composition root
|
||||
re-exports, so a deployment (or the test suite) that swaps the adapter in
|
||||
one place swaps it here too.
|
||||
"""
|
||||
from app.application.container import get_model_provider
|
||||
|
||||
return build_memory_service(session, provider=get_model_provider())
|
||||
|
||||
|
||||
def build_memory_service(
|
||||
session: AsyncSession,
|
||||
*,
|
||||
provider=None,
|
||||
) -> MemoryService:
|
||||
"""The same object, typed for the router (list, teach, pin, confirm, delete)."""
|
||||
if provider is None:
|
||||
from app.application.container import get_model_provider
|
||||
|
||||
provider = get_model_provider()
|
||||
return MemoryService(
|
||||
session=session,
|
||||
memories=MemoryRepository(session),
|
||||
models=AiModelRepository(session),
|
||||
credentials=ModelCredentialRepository(session),
|
||||
rate_cards=RateCardRepository(session),
|
||||
ledger=UsageLedgerRepository(session),
|
||||
provider=provider,
|
||||
)
|
||||
|
||||
|
||||
def build_model_grants(session: AsyncSession) -> ModelGrantPort:
|
||||
async def _all_active() -> list[GrantedModel]:
|
||||
rows = (await session.scalars(select(AiModelRow).where(AiModelRow.is_active))).all()
|
||||
return [
|
||||
GrantedModel(
|
||||
ai_model_id=row.id,
|
||||
tier=tier_for(
|
||||
capabilities=list(row.capabilities or []),
|
||||
output_price_per_1m=row.output_price_per_1m,
|
||||
),
|
||||
capabilities=tuple(row.capabilities or []),
|
||||
)
|
||||
for row in rows
|
||||
]
|
||||
"""The real grant service: an organization sees only what the owner gave it."""
|
||||
return build_model_grant_service(session)
|
||||
|
||||
return AllActiveModelsGrants(_all_active)
|
||||
|
||||
def build_model_grant_service(session: AsyncSession) -> ModelGrantService:
|
||||
"""The same object, typed for the admin router (grants, defaults, policy)."""
|
||||
return ModelGrantService(
|
||||
session=session,
|
||||
grants=OrgModelGrantRepository(session),
|
||||
defaults=DefaultModelGrantRepository(session),
|
||||
policies=OrgPolicyRepository(session),
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"build_memory",
|
||||
"build_memory_service",
|
||||
"build_model_grant_service",
|
||||
"build_model_grants",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user