msflib.ai_api¶
Public modules of the msflib-ai-api package.
msflib.ai_api.adapter_registry
¶
msflib.ai_api.agent_builder
¶
msflib.ai_api.agent_runtime
¶
Shared LangGraph runtime-context schema for the ai_api agent.
Set once as the agent's context_schema and passed fresh on every
invoke/astream call (see router/agent.py), never checkpointed —
unlike graph state, context is documented by LangGraph as "static
context for the graph run" and is never persisted/rehydrated across turns,
which is exactly the property authorization-boundary data like scope
needs: it must come from the live request, never resurface from a stored
checkpoint.
Tool registries that need per-request identity (e.g. msflib.knowledge's
KnowledgeToolRegistry) read it via langgraph.runtime.get_runtime()
inside their own tool bodies — they don't import this module directly, they
just expect context.scope to exist by convention, the same way they
already avoid a hard dependency on ai_core's orchestration layer.
vector_store_resolver, when set, is a zero-arg callable ai_core's
rag_search tool calls per-invocation instead of the vector store it was
constructed with — how router/agent.py opts individual requests into
VectorStoreRegistryService-backed per-tenant routing without rebuilding
the (cached, router-lifetime) tool registries themselves.
web_search_backend, when set, is the tenant/workspace-tiered
WEB_SEARCH_BACKEND value ai_core's web_search tool reads
per-invocation instead of the backend it was constructed with — same
"override a cached, router-lifetime tool without rebuilding it" seam as
vector_store_resolver, but a plain resolved value rather than a
callable since router/agent.py already resolves it eagerly via a
FastAPI dependency (unlike the vector store, resolving it isn't deferred
to only when the tool actually runs). web_search_api_key is the
matching tiered WEB_SEARCH_API_KEY, needed so an override to a
key-requiring backend (e.g. "tavily") doesn't fall back to the
web_search tool's construction-time key, which may be absent when the
tool was built for the (keyless) default backend.
msflib.ai_api.contracts
¶
msflib.ai_api.deps
¶
Request-scoped FastAPI dependencies for ai_api's transport endpoints.
Follows the module deps convention (see ai_core.deps.get_provider_dependencies
and ai_core.router, which wires get_provider_dependencies and
msflib.scope.get_scope_dependencies as two separate factory calls): scope
building and settings/service resolution are two distinct factories here too.
Both now take get_session (scope building needs it to resolve the caller's
tenant id via get_current_tenant/resolve_default_tenant_id).
get_ai_api_scope_dependencies(*, get_current_account: Callable, get_current_workspace: Callable | None = None, get_current_tenant: Callable | None = None, get_session: Callable | None = None) -> DependencyNamespace
¶
Return reusable FastAPI dependencies yielding the caller's ai_api ScopeEnvelope.
get_current_account is always required (ai_api has no anonymous
surface); get_current_workspace is optional. get_current_tenant
is resolved once at the endpoint boundary, the same way
documents.router()/ingestion.router() resolve it (see
msflib.tenancy.deps.get_tenant_dependencies) -- yields a Tenant
row. When omitted, falls back to resolve_default_tenant_id (today's
single-tenant resolution) if get_session is wired, else the scope's
tenant dimension is set to _NO_TENANT_SENTINEL (0) -- mirrors
get_current_tenant itself being optional: a host app that supplies
neither gets a scope that still satisfies profiles requiring a non-null
tenant_id.
Returns:
| Type | Description |
|---|---|
DependencyNamespace exposing:
|
|
get_ai_api_settings_dependencies(settings: SettingsBase, *, get_session: Callable, get_current_account: Callable, get_current_workspace: Callable | None = None, get_policy_resolver: Callable | None = None) -> DependencyNamespace
¶
Return reusable FastAPI dependencies for ai_api's settings/service resolution.
Delegates tiered AICoreSettings/ProviderRegistryService resolution to
ai_core (see :func:msflib.ai_core.deps.get_provider_dependencies) rather
than re-implementing it; only adds the request-level k ->
RETRIEVER_K override on top.
Returns:
| Type | Description |
|---|---|
DependencyNamespace exposing:
|
|
msflib.ai_api.protocol_adapter
¶
msflib.ai_api.router
¶
TieredResolution(vector_store: bool = False, web_search_backend: bool = False)
dataclass
¶
Which settings a router should re-resolve per-request through policy tiers.
Shared by create_llm_router and create_agent_router (via the
top-level router()'s single tiered param) so both stay in sync
rather than each accumulating its own flat resolve_x_per_request
boolean. "Tiered" means resolved through
PolicyResolutionService's tenant -> workspace -> user chain (see
msflib.ai_core.deps._resolve_tiered_ai_settings) instead of the
module's static base AICoreSettings — each field defaults to
False (static settings, byte-for-byte unchanged from before this
class existed), since resolving through that chain means a live DB
lookup on every request, not something to switch on by default.
vector_store— re-resolve the vector store backend per request (VectorStoreRegistryService, ranked user < workspace < tenant < global). Read by both routers.web_search_backend— re-resolveWEB_SEARCH_BACKENDper request, tenant/workspace tiers only (the user tier is deliberately skipped — seecreate_agent_router). Read by the agent router only.
msflib.ai_api.schema
¶
msflib.ai_api.scope
¶
build_request_envelope(*, tenant_id: int | None, account: AccountBase, workspace_id: int | None, channel: str, conversation_id: str | None = None, sub_thread_id: str | None = None) -> ScopeEnvelope
¶
Build a per-request ScopeEnvelope from the authenticated account context.
tenant_id is caller-supplied (the endpoint boundary's already-resolved
real tenant id -- see ai_api.deps.get_ai_api_scope_dependencies) and
never derived from account: accounts can belong to multiple tenants.
account.id is the individual user identity and goes into PrincipalContext only.
msflib.ai_api.scope_profiles
¶
msflib.ai_api.services
¶
rag
¶
resolve_scoped_vector_store(*, settings: SettingsBase, session: Session, scope: ScopeEnvelope, ai_settings: AICoreSettings, collection_name: str | None = None) -> ScopedSearchable
¶
Resolve a vector store from the caller's scope via the DB-backed registry.
Unlike resolve_default_vector_store (static AICoreSettings.VECTOR_STORE_*,
cached for the router's lifetime), this re-resolves per call against
VectorStoreProfile rows ranked user < workspace < tenant < global for
scope, falling back to the static settings when none match or
DB_VECTOR_STORE_REGISTRY_ENABLED is off. ai_settings should already
be the per-request tiered settings from resolve_ai_settings so a
workspace-level VECTOR_STORE_BACKEND override is honored too.
answer_with_rag(*, question: str, hits: list[Document], llm: BaseLanguageModel | None) -> str
¶
Build a retrieval-grounded answer using the provided LLM client.