Skip to main content

mini_chat_sdk/
plugin_api.rs

1use async_trait::async_trait;
2use tokio_util::sync::CancellationToken;
3use uuid::Uuid;
4
5use crate::audit_models::{
6    TurnAuditEvent, TurnDeleteAuditEvent, TurnEditAuditEvent, TurnRetryAuditEvent,
7};
8use crate::error::{MiniChatAuditPluginError, MiniChatModelPolicyPluginError, PublishError};
9use crate::models::{PolicySnapshot, PolicyVersionInfo, UsageEvent, UserLicenseStatus, UserLimits};
10
11/// Plugin API trait for mini-chat model policy implementations.
12///
13/// Plugins implement this trait to provide model catalog and policy data.
14/// The mini-chat module discovers plugins via GTS types-registry and
15/// delegates policy queries to the selected plugin.
16///
17/// Every method accepts a [`CancellationToken`] so callers can abort
18/// in-flight HTTP requests on shutdown or request cancellation.
19#[async_trait]
20pub trait MiniChatModelPolicyPluginClientV1: Send + Sync {
21    /// Get the current policy version for a user.
22    async fn get_current_policy_version(
23        &self,
24        user_id: Uuid,
25        cancel: CancellationToken,
26    ) -> Result<PolicyVersionInfo, MiniChatModelPolicyPluginError>;
27
28    /// Get the full policy snapshot for a given version, including
29    /// model catalog and kill switches.
30    async fn get_policy_snapshot(
31        &self,
32        user_id: Uuid,
33        policy_version: u64,
34        cancel: CancellationToken,
35    ) -> Result<PolicySnapshot, MiniChatModelPolicyPluginError>;
36
37    /// Get per-user credit limits for a specific policy version.
38    async fn get_user_limits(
39        &self,
40        user_id: Uuid,
41        policy_version: u64,
42        cancel: CancellationToken,
43    ) -> Result<UserLimits, MiniChatModelPolicyPluginError>;
44
45    /// Check whether a user holds an active `CyberChat` license in the caller's tenant.
46    ///
47    /// Returns `active: true` when the user's status is `active`.
48    /// Returns `active: false` for any other status (`invited`, `deactivated`,
49    /// `deleted`) or when the user is not found — this is not an error condition.
50    ///
51    /// The default implementation returns `active: false` so that existing
52    /// out-of-tree V1 plugins remain compatible without code changes.
53    async fn check_user_license(
54        &self,
55        _user_id: Uuid,
56        _cancel: CancellationToken,
57    ) -> Result<UserLicenseStatus, MiniChatModelPolicyPluginError> {
58        Ok(UserLicenseStatus { active: false })
59    }
60
61    /// Publish a usage event after turn finalization.
62    ///
63    /// Called by the outbox processor after the finalization transaction
64    /// commits. Plugins can forward the event to external billing systems.
65    async fn publish_usage(
66        &self,
67        payload: UsageEvent,
68        cancel: CancellationToken,
69    ) -> Result<(), PublishError>;
70}
71
72/// Plugin API trait for mini-chat audit event publishing.
73///
74/// Plugins implement this trait to receive audit events from the mini-chat
75/// module. The mini-chat module discovers plugins via GTS types-registry and
76/// dispatches audit events to all registered implementations.
77///
78/// # Caller contract
79///
80/// The **caller** (mini-chat domain service) MUST redact secret patterns and
81/// truncate string content (max 8 KiB per field) *before* invoking any method
82/// on this trait. Plugins MUST assume all content fields are already sanitized.
83/// See DESIGN.md "Audit content handling (P1)" for the full redaction rule table.
84///
85/// # Delivery semantics
86///
87/// Audit emission is best-effort (fire-and-forget after DB commit). There is no
88/// transactional outbox for audit events. If the process crashes between DB
89/// commit and audit emission, the event is lost. Callers SHOULD track emission
90/// outcomes via `mini_chat_audit_emit_total{result}` metrics.
91///
92/// # Independence
93///
94/// When multiple audit plugin instances are registered, each MUST be
95/// independent. A failure in one plugin MUST NOT prevent delivery to others.
96#[async_trait]
97pub trait MiniChatAuditPluginClientV1: Send + Sync {
98    /// Emit a turn audit event (turn completed or failed).
99    async fn emit_turn_audit(&self, event: TurnAuditEvent) -> Result<(), MiniChatAuditPluginError>;
100
101    /// Emit a turn-retry audit event.
102    async fn emit_turn_retry_audit(
103        &self,
104        event: TurnRetryAuditEvent,
105    ) -> Result<(), MiniChatAuditPluginError>;
106
107    /// Emit a turn-edit audit event.
108    async fn emit_turn_edit_audit(
109        &self,
110        event: TurnEditAuditEvent,
111    ) -> Result<(), MiniChatAuditPluginError>;
112
113    /// Emit a turn-delete audit event.
114    async fn emit_turn_delete_audit(
115        &self,
116        event: TurnDeleteAuditEvent,
117    ) -> Result<(), MiniChatAuditPluginError>;
118}