API Reference
control_policy
add_api_key_header
AddApiKeyHeaderPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/add_api_key_header.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
Adds the configured OpenAI API key to the request Authorization header.
__init__(name=None)
Source code in luthien_control/control_policy/add_api_key_header.py
20 21 22 23 24 25 26 |
|
Initializes the policy.
apply(context, container, session)
async
Source code in luthien_control/control_policy/add_api_key_header.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
|
Adds the Authorization: Bearer
Reads OpenAI API key from settings via the container. Requires the DependencyContainer and AsyncSession in signature for interface compliance, but session is not directly used in this policy's logic.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container. |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession (unused). |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The potentially modified transaction context. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/add_api_key_header.py
74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
Constructs the policy from serialized configuration.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
Dictionary possibly containing 'name'. |
required |
Returns:
Type | Description |
---|---|
AddApiKeyHeaderPolicy
|
An instance of AddApiKeyHeaderPolicy. |
serialize()
Source code in luthien_control/control_policy/add_api_key_header.py
70 71 72 |
|
Serializes config. Returns base info as no instance-specific config needed.
add_api_key_header_from_env
Add an API key header, where the key is sourced from a configured environment variable.
This policy is used to add an API key to the request Authorization header. The API key is read from an environment variable whose name is configured when the policy is instantiated.
AddApiKeyHeaderFromEnvPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/add_api_key_header_from_env.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
|
Adds an API key to the request Authorization header. The API key is read from an environment variable whose name is configured when the policy is instantiated.
__init__(api_key_env_var_name, name=None)
Source code in luthien_control/control_policy/add_api_key_header_from_env.py
33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
Initializes the policy.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
api_key_env_var_name
|
str
|
The name of the environment variable that holds the API key. |
required |
name
|
Optional[str]
|
Optional name for this policy instance. |
None
|
apply(context, container, session)
async
Source code in luthien_control/control_policy/add_api_key_header_from_env.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
|
Adds the Authorization: Bearer
The API key is read from the environment variable specified by self.api_key_env_var_name. Requires DependencyContainer and AsyncSession for interface compliance, but they are not directly used in this policy's primary logic beyond what ControlPolicy might require.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container (unused). |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession (unused). |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The potentially modified transaction context. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/add_api_key_header_from_env.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
|
Constructs the policy from serialized configuration.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
Dictionary expecting 'api_key_env_var_name' and optionally 'name'. |
required |
Returns:
Type | Description |
---|---|
AddApiKeyHeaderFromEnvPolicy
|
An instance of AddApiKeyHeaderFromEnvPolicy. |
serialize()
Source code in luthien_control/control_policy/add_api_key_header_from_env.py
95 96 97 98 99 100 101 102 103 |
|
Serializes the policy's configuration.
branching_policy
BranchingPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/branching_policy.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
|
apply(context, container, session)
async
Source code in luthien_control/control_policy/branching_policy.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
Apply the first policy that matches the condition. If no condition matches, apply the default policy (if set).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The transaction context to apply the policy to. |
required |
container
|
DependencyContainer
|
The dependency container. |
required |
session
|
AsyncSession
|
The database session. |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The potentially modified transaction context. |
client_api_key_auth
ClientApiKeyAuthPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/client_api_key_auth.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
|
Verifies the client API key provided in the Authorization header.
Attributes:
Name | Type | Description |
---|---|---|
name |
str
|
The name of this policy instance. |
logger |
Logger
|
The logger instance for this policy. |
__init__(name=None)
Source code in luthien_control/control_policy/client_api_key_auth.py
35 36 37 38 |
|
Initializes the policy.
apply(context, container, session)
async
Source code in luthien_control/control_policy/client_api_key_auth.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
|
Verifies the API key from the Authorization header in the context's request. Requires the DependencyContainer and an active SQLAlchemy AsyncSession.
Raises:
Type | Description |
---|---|
NoRequestError
|
If context.fastapi_request is None. |
ClientAuthenticationError
|
If the key is missing, invalid, or inactive. |
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container. |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession. |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The unmodified transaction context if authentication is successful. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/client_api_key_auth.py
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
|
Constructs the policy from serialized data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
The serialized configuration dictionary. May optionally contain a 'name' key to set a custom name for the policy instance. |
required |
Returns:
Type | Description |
---|---|
ClientApiKeyAuthPolicy
|
An instance of ClientApiKeyAuthPolicy. |
serialize()
Source code in luthien_control/control_policy/client_api_key_auth.py
114 115 116 117 118 119 120 121 122 123 124 125 |
|
Serializes the policy's configuration.
This method converts the policy's configuration into a serializable dictionary. For this policy, only the 'name' attribute is included if it has been set to a non-default value.
Returns:
Name | Type | Description |
---|---|---|
SerializableDict |
SerializableDict
|
A dictionary representation of the policy's configuration. It may be empty or contain a 'name' key. |
conditions
Condition
Bases: ABC
Source code in luthien_control/control_policy/conditions/condition.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
|
Abstract base class for conditions in control policies.
Conditions are used to evaluate whether a policy should be applied based on the current transaction context.
from_serialized(serialized)
classmethod
Source code in luthien_control/control_policy/conditions/condition.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
Construct a condition from a serialized configuration.
This method acts as a dispatcher. It looks up the concrete condition class based on the 'type' field in the config and delegates to its from_serialized method.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
serialized
|
SerializableDict
|
The condition-specific configuration dictionary. It must contain a 'type' key that maps to a registered condition type. |
required |
Returns:
Type | Description |
---|---|
Condition
|
An instance of the concrete condition class. |
Raises:
Type | Description |
---|---|
ValueError
|
If the 'type' key is missing in config or the type is not registered. |
ContainsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
99 100 101 102 103 104 105 106 107 108 109 110 111 |
|
Condition to check if a value contains another value.
Example
key = "response.completion_tokens_details" value = "audio_tokens"
Matches when the completion_tokens_details
in the response contains "audio_tokens"
EqualsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
Condition to check if a value is equal to another value.
Example
key = "request.content.model" value = "gpt-4o"
Matches when the value of 'content'
in request.content
is "gpt-4o"
GreaterThanCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
144 145 146 147 148 149 150 151 152 153 154 155 156 |
|
Condition to check if a value is greater than another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is after 2025-01-01 00:00:00 UTC
GreaterThanOrEqualCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
159 160 161 162 163 164 165 166 167 168 169 170 171 |
|
Condition to check if a value is greater than or equal to another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is after or equal to 2025-01-01 00:00:00 UTC
LessThanCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
114 115 116 117 118 119 120 121 122 123 124 125 126 |
|
Condition to check if a value is less than another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is before 2025-01-01 00:00:00 UTC
LessThanOrEqualCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
129 130 131 132 133 134 135 136 137 138 139 140 141 |
|
Condition to check if a value is less than or equal to another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is before or equal to 2025-01-01 00:00:00 UTC
NotEqualsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
84 85 86 87 88 89 90 91 92 93 94 95 96 |
|
Condition to check if a value is NOT equal to another value.
Example
key = "request.content.model" value = "gpt-4o"
Matches when the value of 'content'
in request.content
is NOT "gpt-4o"
RegexMatchCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
174 175 176 177 178 179 180 181 182 183 184 185 186 |
|
Condition to check if a value matches a regular expression.
Example
key = "request.content.model" value = "gpt-4"
Matches when the model specified in the request contains "gpt-4"
comparisons
ComparisonCondition
Bases: Condition
, ABC
Source code in luthien_control/control_policy/conditions/comparisons.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
__init__(key, value)
Source code in luthien_control/control_policy/conditions/comparisons.py
28 29 30 31 32 33 34 35 36 37 38 39 |
|
Parameters:
Name | Type | Description | Default |
---|---|---|---|
key
|
str
|
The key to the value to compare against in the transaction context (see get_tx_value) |
required |
value
|
Any
|
The value to compare against the key. |
required |
Example
key = "request.data.user" value = "John"
ContainsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
99 100 101 102 103 104 105 106 107 108 109 110 111 |
|
Condition to check if a value contains another value.
Example
key = "response.completion_tokens_details" value = "audio_tokens"
Matches when the completion_tokens_details
in the response contains "audio_tokens"
EqualsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
Condition to check if a value is equal to another value.
Example
key = "request.content.model" value = "gpt-4o"
Matches when the value of 'content'
in request.content
is "gpt-4o"
GreaterThanCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
144 145 146 147 148 149 150 151 152 153 154 155 156 |
|
Condition to check if a value is greater than another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is after 2025-01-01 00:00:00 UTC
GreaterThanOrEqualCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
159 160 161 162 163 164 165 166 167 168 169 170 171 |
|
Condition to check if a value is greater than or equal to another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is after or equal to 2025-01-01 00:00:00 UTC
LessThanCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
114 115 116 117 118 119 120 121 122 123 124 125 126 |
|
Condition to check if a value is less than another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is before 2025-01-01 00:00:00 UTC
LessThanOrEqualCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
129 130 131 132 133 134 135 136 137 138 139 140 141 |
|
Condition to check if a value is less than or equal to another value.
Example
key = "response.content.created" value = 1741569952 # 2025-01-01 00:00:00 UTC
Matches when the timestamp of the response is before or equal to 2025-01-01 00:00:00 UTC
NotEqualsCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
84 85 86 87 88 89 90 91 92 93 94 95 96 |
|
Condition to check if a value is NOT equal to another value.
Example
key = "request.content.model" value = "gpt-4o"
Matches when the value of 'content'
in request.content
is NOT "gpt-4o"
RegexMatchCondition
Bases: ComparisonCondition
Source code in luthien_control/control_policy/conditions/comparisons.py
174 175 176 177 178 179 180 181 182 183 184 185 186 |
|
Condition to check if a value matches a regular expression.
Example
key = "request.content.model" value = "gpt-4"
Matches when the model specified in the request contains "gpt-4"
condition
Condition
Bases: ABC
Source code in luthien_control/control_policy/conditions/condition.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
|
Abstract base class for conditions in control policies.
Conditions are used to evaluate whether a policy should be applied based on the current transaction context.
from_serialized(serialized)
classmethod
Source code in luthien_control/control_policy/conditions/condition.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
Construct a condition from a serialized configuration.
This method acts as a dispatcher. It looks up the concrete condition class based on the 'type' field in the config and delegates to its from_serialized method.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
serialized
|
SerializableDict
|
The condition-specific configuration dictionary. It must contain a 'type' key that maps to a registered condition type. |
required |
Returns:
Type | Description |
---|---|
Condition
|
An instance of the concrete condition class. |
Raises:
Type | Description |
---|---|
ValueError
|
If the 'type' key is missing in config or the type is not registered. |
control_policy
ControlPolicy
Bases: ABC
Source code in luthien_control/control_policy/control_policy.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
|
Abstract Base Class defining the interface for a processing step.
Attributes:
Name | Type | Description |
---|---|---|
name |
Optional[str]
|
An optional name for the policy instance.
Subclasses are expected to set this, often in their |
__init__(**kwargs)
Source code in luthien_control/control_policy/control_policy.py
27 28 29 30 31 32 33 34 35 36 |
|
Initializes the ControlPolicy.
This is an abstract base class, and this constructor typically handles common initialization or can be overridden by subclasses.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
**kwargs
|
Any
|
Arbitrary keyword arguments that subclasses might use. |
{}
|
apply(context, container, session)
abstractmethod
async
Source code in luthien_control/control_policy/control_policy.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
Apply the policy to the transaction context using provided dependencies.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The dependency injection container. |
required |
session
|
AsyncSession
|
The database session for the current request. |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The potentially modified transaction context. |
Raises:
Type | Description |
---|---|
Exception
|
Processors may raise exceptions to halt the processing flow. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/control_policy.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
|
Construct a policy from a serialized configuration and optional dependencies.
This method acts as a dispatcher. It looks up the concrete policy class based on the 'type' field in the config and delegates to its from_serialized method.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
The policy-specific configuration dictionary. It must contain a 'type' key that maps to a registered policy type. |
required |
**kwargs
|
Additional dependencies needed for instantiation, passed to the concrete policy's from_serialized method. |
required |
Returns:
Type | Description |
---|---|
PolicyT
|
An instance of the concrete policy class. |
Raises:
Type | Description |
---|---|
ValueError
|
If the 'type' key is missing in config or the type is not registered. |
serialize()
abstractmethod
Source code in luthien_control/control_policy/control_policy.py
58 59 60 61 62 63 64 65 66 |
|
Serialize the policy's instance-specific configuration needed for reloading.
Returns:
Type | Description |
---|---|
SerializableDict
|
A serializable dictionary containing configuration parameters. |
exceptions
ApiKeyNotFoundError
Bases: ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
60 61 62 63 |
|
Exception raised when the API key is not found in the settings.
ClientAuthenticationError
Bases: ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
Exception raised when client API key authentication fails.
__init__(detail, status_code=401)
Source code in luthien_control/control_policy/exceptions.py
75 76 77 78 79 80 81 82 83 84 |
|
Initializes the ClientAuthenticationError.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
detail
|
str
|
A detailed error message explaining the authentication failure. |
required |
status_code
|
int
|
The HTTP status code to associate with this error. Defaults to 401 (Unauthorized). |
401
|
ClientAuthenticationNotFoundError
Bases: ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
87 88 89 90 91 92 93 94 95 96 97 98 99 |
|
Exception raised when the client API key is not found in the request.
__init__(detail, status_code=401)
Source code in luthien_control/control_policy/exceptions.py
90 91 92 93 94 95 96 97 98 99 |
|
Initializes the ClientAuthenticationNotFoundError.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
detail
|
str
|
A detailed error message explaining why the key was not found. |
required |
status_code
|
int
|
The HTTP status code to associate with this error. Defaults to 401 (Unauthorized). |
401
|
ControlPolicyError
Bases: Exception
Source code in luthien_control/control_policy/exceptions.py
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Base exception for all control policy errors.
Attributes:
Name | Type | Description |
---|---|---|
policy_name |
Optional[str]
|
The name of the policy where the error occurred, if specified. |
status_code |
Optional[int]
|
An HTTP status code associated with this error, if specified. |
detail |
Optional[str]
|
A detailed error message. If not provided directly during initialization but other arguments are, the first positional argument is used as the detail. |
__init__(*args, policy_name=None, status_code=None, detail=None)
Source code in luthien_control/control_policy/exceptions.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Initializes the ControlPolicyError.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args
|
Arguments passed to the base Exception class. |
()
|
|
policy_name
|
Optional[str]
|
The name of the policy where the error occurred. |
None
|
status_code
|
Optional[int]
|
An HTTP status code associated with this error. |
None
|
detail
|
Optional[str]
|
A detailed error message. If not provided and |
None
|
LeakedApiKeyError
Bases: ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
102 103 104 105 106 107 108 109 110 111 112 113 114 |
|
Exception raised when a leaked API key is detected.
__init__(detail, status_code=403)
Source code in luthien_control/control_policy/exceptions.py
105 106 107 108 109 110 111 112 113 114 |
|
Initializes the LeakedApiKeyError.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
detail
|
str
|
A detailed error message explaining the leaked key detection. |
required |
status_code
|
int
|
The HTTP status code to associate with this error. Defaults to 403 (Forbidden). |
403
|
NoRequestError
Bases: ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
66 67 68 69 |
|
Exception raised when the request object is not found in the context.
PolicyLoadError
Bases: ValueError
, ControlPolicyError
Source code in luthien_control/control_policy/exceptions.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
Custom exception for errors during policy loading/instantiation.
__init__(*args, policy_name=None, status_code=None, detail=None)
Source code in luthien_control/control_policy/exceptions.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
|
Initializes the PolicyLoadError.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args
|
Arguments passed to the base Exception class. |
()
|
|
policy_name
|
Optional[str]
|
The name of the policy that failed to load. |
None
|
status_code
|
Optional[int]
|
An HTTP status code associated with this error. |
None
|
detail
|
Optional[str]
|
A detailed error message. If not provided and |
None
|
leaked_api_key_detection
Control Policy for detecting leaked API keys in LLM message content.
This policy inspects the 'messages' field in request bodies to prevent sensitive API keys from being sent to language models.
LeakedApiKeyDetectionPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/leaked_api_key_detection.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
|
Detects API keys that might be leaked in message content sent to LLMs.
__init__(patterns=None, name=None)
Source code in luthien_control/control_policy/leaked_api_key_detection.py
34 35 36 37 38 39 40 41 42 43 44 45 |
|
Initializes the policy.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
patterns
|
Optional[List[str]]
|
Optional list of regex patterns to detect API keys. If not provided, uses DEFAULT_PATTERNS. |
None
|
name
|
Optional[str]
|
Optional name for this policy instance. |
None
|
apply(context, container, session)
async
Source code in luthien_control/control_policy/leaked_api_key_detection.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
|
Checks message content for potentially leaked API keys.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container. |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession. |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The transaction context, potentially with an error response set. |
Raises:
Type | Description |
---|---|
NoRequestError
|
If the request is not found in the context. |
LeakedApiKeyError
|
If a potential API key is detected in message content. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/leaked_api_key_detection.py
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
|
Constructs the policy from serialized configuration.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
Dictionary containing configuration options. |
required |
Returns:
Type | Description |
---|---|
LeakedApiKeyDetectionPolicy
|
An instance of LeakedApiKeyDetectionPolicy. |
Raises:
Type | Description |
---|---|
ValueError
|
If the 'name' or 'patterns' keys are missing or incorrectly typed in the config. |
serialize()
Source code in luthien_control/control_policy/leaked_api_key_detection.py
126 127 128 129 130 131 132 133 134 |
|
Serializes the policy's configuration.
loader
load_policy(serialized_policy)
Source code in luthien_control/control_policy/loader.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
Loads a ControlPolicy instance from a dictionary containing its name and config, injecting required dependencies.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
serialized_policy
|
SerializedPolicy
|
A SerializedPolicy object. |
required |
Returns:
Type | Description |
---|---|
ControlPolicy
|
An instantiated ControlPolicy object. |
Raises:
Type | Description |
---|---|
PolicyLoadError
|
If the policy name is unknown, data is missing/malformed, or a required dependency is not provided. |
Exception
|
Potentially from the policy's from_serialized method if config is invalid. |
load_policy_from_file(filepath)
Source code in luthien_control/control_policy/loader.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
|
Load a policy configuration from a file and instantiate it using the control_policy loader.
model_name_replacement
ModelNameReplacementPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/model_name_replacement.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
|
Replaces model names in requests based on a configured mapping.
This policy allows clients to use fake model names that will be replaced with real model names before the request is sent to the backend. This is useful for services like Cursor that assume model strings that match known models must route through specific endpoints.
__init__(model_mapping, name=None)
Source code in luthien_control/control_policy/model_name_replacement.py
25 26 27 28 29 30 31 32 33 34 |
|
Initializes the policy with a mapping of fake to real model names.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model_mapping
|
Dict[str, str]
|
Dictionary mapping fake model names to real model names. |
required |
name
|
Optional[str]
|
Optional name for this policy instance. |
None
|
apply(context, container, session)
async
Source code in luthien_control/control_policy/model_name_replacement.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
|
Replaces the model name in the request content based on the configured mapping.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container. |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession (unused). |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The potentially modified transaction context. |
Raises:
Type | Description |
---|---|
NoRequestError
|
If no request is found in the context. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/model_name_replacement.py
101 102 103 104 105 106 |
|
Constructs the policy from serialized configuration.
serialize()
Source code in luthien_control/control_policy/model_name_replacement.py
90 91 92 93 94 95 96 97 98 99 |
|
Serializes the policy configuration.
noop_policy
NoopPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/noop_policy.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
A policy that does nothing.
send_backend_request
SendBackendRequestPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/send_backend_request.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
|
Policy responsible for sending the request to the backend, storing the response, and reading the raw response body.
Attributes:
Name | Type | Description |
---|---|---|
name |
str
|
The name of this policy instance, used for logging and identification. It defaults to the class name if not provided during initialization. |
apply(context, container, session)
async
Source code in luthien_control/control_policy/send_backend_request.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
|
Sends the request from context to the backend and stores the response.
This policy constructs the target URL, prepares headers, and uses the
HTTP client from the DependencyContainer
to send the context.request
.
The backend's response (an httpx.Response
object) is stored in
context.response
. The response body is read immediately.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context, containing the |
required |
container
|
DependencyContainer
|
The application dependency container, providing |
required |
session
|
AsyncSession
|
An active SQLAlchemy |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The |
TransactionContext
|
containing the |
Raises:
Type | Description |
---|---|
ValueError
|
If |
TimeoutException
|
If the request to the backend times out. |
RequestError
|
For other network-related issues during the backend request. |
Exception
|
For any other unexpected errors during request preparation or execution. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/send_backend_request.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
|
Constructs the policy from serialized configuration.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
A dictionary that may optionally contain a 'name' key to set a custom name for the policy instance. |
required |
Returns:
Type | Description |
---|---|
SendBackendRequestPolicy
|
An instance of SendBackendRequestPolicy. |
serialize()
Source code in luthien_control/control_policy/send_backend_request.py
185 186 187 188 189 190 191 192 193 194 195 |
|
Serializes the policy's configuration.
For this policy, only the 'name' attribute is included, as all other dependencies (like HTTP client, settings) are resolved from the DependencyContainer at runtime.
Returns:
Name | Type | Description |
---|---|---|
SerializableDict |
SerializableDict
|
A dictionary containing the 'name' of the policy instance. |
serial_policy
SerialPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/serial_policy.py
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
|
A Control Policy that applies an ordered sequence of other policies.
Policies are applied sequentially. If any policy raises an exception, the execution stops, and the exception propagates.
Attributes:
Name | Type | Description |
---|---|---|
policies |
Sequence[ControlPolicy]
|
The ordered sequence of ControlPolicy instances that this policy will apply. |
logger |
Logger
|
The logger instance for this policy. |
name |
str
|
The name of this policy instance, used for logging and identification. |
__init__(policies, name=None)
Source code in luthien_control/control_policy/serial_policy.py
33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
Initializes the SerialPolicy.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
policies
|
Sequence[ControlPolicy]
|
An ordered sequence of ControlPolicy instances to apply. |
required |
name
|
Optional[str]
|
An optional name for logging/identification purposes. |
None
|
__repr__()
Source code in luthien_control/control_policy/serial_policy.py
88 89 90 91 92 93 |
|
Provides a developer-friendly representation.
apply(context, container, session)
async
Source code in luthien_control/control_policy/serial_policy.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
Applies the contained policies sequentially to the context. Requires the DependencyContainer and an active SQLAlchemy AsyncSession.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context
|
TransactionContext
|
The current transaction context. |
required |
container
|
DependencyContainer
|
The application dependency container. |
required |
session
|
AsyncSession
|
An active SQLAlchemy AsyncSession, passed to member policies. |
required |
Returns:
Type | Description |
---|---|
TransactionContext
|
The transaction context after all contained policies have been applied. |
Raises:
Type | Description |
---|---|
Exception
|
Propagates any exception raised by a contained policy. |
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/serial_policy.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
|
Constructs a SerialPolicy from serialized data, loading member policies.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config
|
SerializableDict
|
The serialized configuration dictionary. Expects a 'policies' key containing a list of dictionaries, each with 'type' and 'config'. |
required |
Returns:
Type | Description |
---|---|
SerialPolicy
|
An instance of SerialPolicy. |
Raises:
Type | Description |
---|---|
PolicyLoadError
|
If 'policies' key is missing, not a list, or if loading a member policy fails. |
serialize()
Source code in luthien_control/control_policy/serial_policy.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
|
Serializes the SerialPolicy into a dictionary.
This method converts the policy and its contained member policies into a serializable dictionary format. It uses the POLICY_CLASS_TO_NAME mapping to determine the 'type' string for each member policy.
Returns:
Name | Type | Description |
---|---|---|
SerializableDict |
SerializableDict
|
A dictionary representation of the policy, suitable for JSON serialization or persistence. The dictionary has a "policies" key, which is a list of serialized member policies. Each member policy dict contains "type" and "config" keys. |
Raises:
Type | Description |
---|---|
PolicyLoadError
|
If the type of a member policy cannot be determined from POLICY_CLASS_TO_NAME. |
serialization
SerializedPolicy
dataclass
Source code in luthien_control/control_policy/serialization.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
Represents the serialized form of a ControlPolicy.
This structure is used to store and transfer policy configurations. The 'type' field identifies the specific policy class, and the 'config' field contains the parameters needed to reconstruct that policy instance.
Attributes:
Name | Type | Description |
---|---|---|
type |
str
|
The registered name of the policy type (e.g., "AddApiKeyHeader"). |
config |
SerializableDict
|
A dictionary containing the configuration parameters for the policy instance. |
tx_logging
Transaction logging policy components, including serializers.
LuthienLogData
Bases: NamedTuple
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
18 19 20 21 22 23 |
|
Data structure for what a TxLoggingSpec should return.
TxLoggingSpec
Bases: ABC
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
Abstract Base Class for defining how to generate a log entry from a TransactionContext.
__init_subclass__(**kwargs)
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
32 33 34 35 36 37 38 39 40 41 42 43 |
|
Registers subclasses in the LOGGING_SPEC_REGISTRY.
full_transaction_context_spec
Defines the FullTransactionContextSpec for TxLoggingPolicy.
logging_utils
Utility functions and constants for logging serialization.
openai_request_spec
Defines the OpenAIRequestSpec for TxLoggingPolicy.
serialize_openai_chat_request(request)
Source code in luthien_control/control_policy/tx_logging/openai_request_spec.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
|
Serializes an httpx.Request known to be for OpenAI Chat Completions.
Extracts relevant fields from the JSON body and sanitizes headers.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request
|
Request
|
The httpx.Request object for OpenAI Chat Completions. |
required |
Returns:
Type | Description |
---|---|
Dict[str, Any]
|
A dictionary representing the serialized OpenAI chat request. |
openai_response_spec
Defines the OpenAIResponseSpec for TxLoggingPolicy.
serialize_openai_chat_response(response)
Source code in luthien_control/control_policy/tx_logging/openai_response_spec.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
Serializes an httpx.Response known to be from OpenAI Chat Completions.
Extracts relevant fields from the JSON body and includes sanitized headers and status code.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
response
|
Response
|
The httpx.Response object from OpenAI Chat Completions. |
required |
Returns:
Type | Description |
---|---|
Dict[str, Any]
|
A dictionary representing the serialized OpenAI chat response. |
request_headers_spec
Defines the RequestHeadersSpec for TxLoggingPolicy.
response_headers_spec
Defines the ResponseHeadersSpec for TxLoggingPolicy.
tx_logging_spec
Defines logging specifications for TxLoggingPolicy.
LuthienLogData
Bases: NamedTuple
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
18 19 20 21 22 23 |
|
Data structure for what a TxLoggingSpec should return.
TxLoggingSpec
Bases: ABC
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
Abstract Base Class for defining how to generate a log entry from a TransactionContext.
__init_subclass__(**kwargs)
Source code in luthien_control/control_policy/tx_logging/tx_logging_spec.py
32 33 34 35 36 37 38 39 40 41 42 43 |
|
Registers subclasses in the LOGGING_SPEC_REGISTRY.
tx_logging_policy
Control Policy for logging requests and responses based on TxLoggingSpec instances.
TxLoggingPolicy
Bases: ControlPolicy
Source code in luthien_control/control_policy/tx_logging_policy.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
|
A control policy that logs data based on a list of TxLoggingSpec instances.
__init__(spec, name='TxLoggingPolicy', **kwargs)
Source code in luthien_control/control_policy/tx_logging_policy.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Initializes the TxLoggingPolicy.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
spec
|
TxLoggingSpec
|
A TxLoggingSpec instance that defines what to log. |
required |
name
|
Optional[str]
|
An optional name for the policy instance. |
'TxLoggingPolicy'
|
**kwargs
|
Any
|
Additional keyword arguments passed to the superclass. |
{}
|
apply(context, container, session)
async
Source code in luthien_control/control_policy/tx_logging_policy.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
|
Applies all configured logging specifications to the transaction context.
from_serialized(config)
classmethod
Source code in luthien_control/control_policy/tx_logging_policy.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
|
Creates an instance of TxLoggingPolicy from serialized data.
This involves deserializing the configured logging spec.
serialize()
Source code in luthien_control/control_policy/tx_logging_policy.py
85 86 87 88 89 90 91 92 93 |
|
Serializes the policy's configuration, including its spec.
core
dependencies
get_db_session(dependencies=Depends(get_dependencies))
async
Source code in luthien_control/core/dependencies.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
|
FastAPI dependency to get an async database session using the container's factory.
get_dependencies(request)
Source code in luthien_control/core/dependencies.py
29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Dependency to retrieve the DependencyContainer from application state.
get_main_control_policy(dependencies=Depends(get_dependencies))
async
Source code in luthien_control/core/dependencies.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
|
Dependency to load and provide the main ControlPolicy instance.
Uses the DependencyContainer to access settings, http_client, and a database session.
initialize_app_dependencies(app_settings)
async
Source code in luthien_control/core/dependencies.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
|
Initialize and configure core application dependencies.
This function sets up essential services required by the application, including an HTTP client and a database connection pool. It encapsulates the creation and configuration of these dependencies into a DependencyContainer instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
app_settings
|
Settings
|
The application settings instance. |
required |
Returns:
Type | Description |
---|---|
DependencyContainer
|
A DependencyContainer instance populated with initialized dependencies. |
Raises:
Type | Description |
---|---|
RuntimeError
|
If initialization of the HTTP client or database engine fails. |
dependency_container
DependencyContainer
Source code in luthien_control/core/dependency_container.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Holds shared dependencies for the application.
__init__(settings, http_client, db_session_factory)
Source code in luthien_control/core/dependency_container.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Initializes the container.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
settings
|
Settings
|
Application settings. |
required |
http_client
|
AsyncClient
|
Shared asynchronous HTTP client. |
required |
db_session_factory
|
Callable[[], AsyncContextManager[AsyncSession]]
|
A factory function that returns an async context manager yielding an SQLAlchemy AsyncSession. |
required |
logging
setup_logging()
Source code in luthien_control/core/logging.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
|
Configures logging for the application.
Reads the desired log level from the LOG_LEVEL environment variable. Defaults to INFO if not set or invalid. Sets a standard format and directs logs to stderr. Sets louder libraries to WARNING level.
response_builder
ResponseBuilder
Source code in luthien_control/core/response_builder.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
|
Builds a FastAPI response from the TransactionContext based on successful policy execution.
Headers are filtered to remove hop-by-hop headers. Returns a 500 error response ONLY IF building the response itself fails unexpectedly, or if essential data (like status code) is missing after policies ran successfully. Policy execution errors (like auth failure) should be handled upstream by exception handlers.
transaction_context
TransactionContext
dataclass
Source code in luthien_control/core/transaction_context.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Holds the state for a single transaction through the proxy.
Attributes:
Name | Type | Description |
---|---|---|
transaction_id |
UUID
|
A unique identifier for the transaction. |
request |
Optional[Request]
|
The incoming HTTP request object. |
response |
Optional[Response]
|
The outgoing HTTP response object. |
data |
Dict[str, Any]
|
A general-purpose dictionary for policies to store and share information related to this transaction. |
get_tx_value(transaction_context, path)
Source code in luthien_control/core/transaction_context.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
|
Get a value from the transaction context using a path.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
transaction_context
|
TransactionContext
|
The transaction context. |
required |
path
|
str
|
The path to the value e.g. "request.headers.user-agent", "response.status_code", "data.user_id". |
required |
Returns:
Type | Description |
---|---|
Any
|
The value at the path. |
Raises:
Type | Description |
---|---|
ValueError
|
If the path is invalid or the value cannot be accessed. |
TypeError
|
If the transaction_id is not a UUID. |
custom_openapi_schema
create_custom_openapi(app)
Source code in luthien_control/custom_openapi_schema.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
Generate a custom OpenAPI schema for the FastAPI application.
This function retrieves the default schema and modifies it, specifically
to set allowReserved=True
for the full_path
path parameter used
in proxy routes. This is necessary for correctly handling URLs containing
reserved characters within that path segment.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
app
|
FastAPI
|
The FastAPI application instance. |
required |
Returns:
Type | Description |
---|---|
The modified OpenAPI schema dictionary. |
db
Database models and session management.
ControlPolicy
Bases: SQLModel
Source code in luthien_control/db/sqlmodel_models.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
class-attribute
instance-attribute
Database model for storing control policy configurations.
__tablename__ = 'policies'
class-attribute
instance-attribute
Database model for storing control policy configurations.
validate_timestamps(values)
classmethod
Source code in luthien_control/db/sqlmodel_models.py
75 76 77 78 79 80 81 |
|
Ensure updated_at is always set/updated.
LuthienLog
Bases: SQLModel
Source code in luthien_control/db/sqlmodel_models.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
|
Represents a log entry in the Luthien logging system using SQLModel.
Attributes:
Name | Type | Description |
---|---|---|
id |
Optional[int]
|
Unique identifier for the log entry (primary key). |
transaction_id |
str
|
Identifier to group related log entries. |
datetime |
datetime
|
Timestamp indicating when the log entry was generated (timezone-aware). |
data |
Optional[dict[str, Any]]
|
JSON blob containing the primary logged data. |
datatype |
str
|
String identifier for the nature and schema of 'data'. |
notes |
Optional[dict[str, Any]]
|
JSON blob for additional contextual information. |
client_api_key_crud
create_api_key(session, api_key)
async
Source code in luthien_control/db/client_api_key_crud.py
39 40 41 42 43 44 45 46 47 48 49 50 |
|
Create a new API key in the database.
get_api_key_by_value(session, key_value)
async
Source code in luthien_control/db/client_api_key_crud.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Get an active API key by its value.
list_api_keys(session, active_only=False)
async
Source code in luthien_control/db/client_api_key_crud.py
53 54 55 56 57 58 59 60 61 62 63 64 65 |
|
Get a list of all API keys.
update_api_key(session, key_id, api_key_update)
async
Source code in luthien_control/db/client_api_key_crud.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
|
Update an existing API key.
control_policy_crud
get_policy_by_name(session, name)
async
Source code in luthien_control/db/control_policy_crud.py
44 45 46 47 48 49 50 51 52 53 54 55 56 |
|
Get a policy by its name.
get_policy_config_by_name(session, name)
async
Source code in luthien_control/db/control_policy_crud.py
143 144 145 146 147 148 149 150 151 152 153 |
|
Get a policy configuration by its name, regardless of its active status.
list_policies(session, active_only=False)
async
Source code in luthien_control/db/control_policy_crud.py
59 60 61 62 63 64 65 66 67 68 69 70 71 |
|
Get a list of all policies.
load_policy_from_db(name, container)
async
Source code in luthien_control/db/control_policy_crud.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
|
Load a policy configuration from the database and instantiate it using the control_policy loader.
save_policy_to_db(session, policy)
async
Source code in luthien_control/db/control_policy_crud.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Create a new policy in the database.
update_policy(session, policy_id, policy_update)
async
Source code in luthien_control/db/control_policy_crud.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
|
Update an existing policy.
database_async
close_db_engine()
async
Source code in luthien_control/db/database_async.py
116 117 118 119 120 121 122 123 124 125 126 127 128 |
|
Closes the database engine.
create_db_engine()
async
Source code in luthien_control/db/database_async.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
|
Creates the asyncpg engine for the application DB. Returns: The asyncpg engine for the application DB.
Raises:
Type | Description |
---|---|
LuthienDBConfigurationError
|
If the database configuration is invalid. |
LuthienDBConnectionError
|
If the database connection fails. |
get_db_session()
async
Source code in luthien_control/db/database_async.py
131 132 133 134 135 136 137 138 139 140 141 142 |
|
Get a SQLAlchemy async session for the database as a context manager.
sqlmodel_models
ControlPolicy
Bases: SQLModel
Source code in luthien_control/db/sqlmodel_models.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
class-attribute
instance-attribute
Database model for storing control policy configurations.
__tablename__ = 'policies'
class-attribute
instance-attribute
Database model for storing control policy configurations.
validate_timestamps(values)
classmethod
Source code in luthien_control/db/sqlmodel_models.py
75 76 77 78 79 80 81 |
|
Ensure updated_at is always set/updated.
JsonBOrJson
Bases: TypeDecorator
Source code in luthien_control/db/sqlmodel_models.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Represents a JSON type that uses JSONB for PostgreSQL and JSON for other dialects (like SQLite).
This is mostly a hack for unit testing, as SQLite does not support JSONB.
LuthienLog
Bases: SQLModel
Source code in luthien_control/db/sqlmodel_models.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
|
Represents a log entry in the Luthien logging system using SQLModel.
Attributes:
Name | Type | Description |
---|---|---|
id |
Optional[int]
|
Unique identifier for the log entry (primary key). |
transaction_id |
str
|
Identifier to group related log entries. |
datetime |
datetime
|
Timestamp indicating when the log entry was generated (timezone-aware). |
data |
Optional[dict[str, Any]]
|
JSON blob containing the primary logged data. |
datatype |
str
|
String identifier for the nature and schema of 'data'. |
notes |
Optional[dict[str, Any]]
|
JSON blob for additional contextual information. |
exceptions
LuthienDBConfigurationError
Bases: LuthienDBException
Source code in luthien_control/exceptions.py
7 8 9 10 |
|
Exception raised when a database configuration is invalid or missing required variables.
LuthienDBConnectionError
Bases: LuthienDBException
Source code in luthien_control/exceptions.py
13 14 15 16 |
|
Exception raised when a connection to the database fails.
LuthienDBException
Bases: Exception
Source code in luthien_control/exceptions.py
1 2 3 4 |
|
Base exception for all Luthien DB related errors.
main
health_check()
async
Source code in luthien_control/main.py
91 92 93 94 95 96 97 98 99 100 101 |
|
Perform a basic health check.
This endpoint can be used to verify that the application is running and responsive.
Returns:
Type | Description |
---|---|
A dictionary indicating the application status. |
lifespan(app)
async
Source code in luthien_control/main.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
|
Manage the lifespan of the application resources.
This asynchronous context manager handles the startup and shutdown events of the FastAPI application. It initializes dependencies on startup and ensures they are properly cleaned up on shutdown.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
app
|
FastAPI
|
The FastAPI application instance. |
required |
Yields:
Name | Type | Description |
---|---|---|
None |
After startup procedures are complete, allowing the application to run. |
Raises:
Type | Description |
---|---|
RuntimeError
|
If critical application dependencies fail to initialize during startup. |
read_root()
async
Source code in luthien_control/main.py
110 111 112 113 114 115 116 117 |
|
Provide a simple root endpoint.
Returns:
Type | Description |
---|---|
A welcome message indicating the proxy is running. |
proxy
orchestration
run_policy_flow(request, main_policy, dependencies, session)
async
Source code in luthien_control/proxy/orchestration.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
|
Orchestrates the execution of the main ControlPolicy using injected dependencies. Exceptions raised by policies are expected to be caught by FastAPI exception handlers.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
request
|
Request
|
The incoming FastAPI request. |
required |
main_policy
|
ControlPolicy
|
The main policy instance to execute. |
required |
dependencies
|
DependencyContainer
|
The application's dependency container. |
required |
session
|
AsyncSession
|
The database session for this request. |
required |
Returns:
Type | Description |
---|---|
Response
|
The final FastAPI response. |
server
api_proxy_endpoint(request, full_path=default_path, dependencies=Depends(get_dependencies), main_policy=Depends(get_main_control_policy), session=Depends(get_db_session), payload=default_payload, token=Security(http_bearer_auth))
async
Source code in luthien_control/proxy/server.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
|
Main API proxy endpoint using the policy orchestration flow. Handles requests starting with /api/. Uses Dependency Injection Container and provides a DB session.
Authentication Note: This endpoint uses Bearer Token authentication
(Authorization: Bearer
api_proxy_get_endpoint(request, full_path=default_path, dependencies=Depends(get_dependencies), main_policy=Depends(get_main_control_policy), session=Depends(get_db_session), token=Security(http_bearer_auth))
async
Source code in luthien_control/proxy/server.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
|
Main API proxy endpoint for GET requests using the policy orchestration flow. Handles GET requests starting with /api/. Uses Dependency Injection Container and provides a DB session.
Authentication Note: This endpoint uses Bearer Token authentication
(Authorization: Bearer
api_proxy_options_handler(full_path=default_path)
async
Source code in luthien_control/proxy/server.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
|
Handles OPTIONS requests for the API proxy endpoint, indicating allowed methods.
settings
Settings
Source code in luthien_control/settings.py
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
|
Application configuration settings loaded from environment variables.
property
DSN for connecting to the default 'postgres' db for admin tasks. Raises ValueError if required DB settings are missing.
admin_dsn
property
DSN for connecting to the default 'postgres' db for admin tasks. Raises ValueError if required DB settings are missing.
property
Base DSN without a specific database name. Raises ValueError if required DB settings are missing.
base_dsn
property
Base DSN without a specific database name. Raises ValueError if required DB settings are missing.
dev_mode()
Source code in luthien_control/settings.py
177 178 179 |
|
Returns True if the run mode is 'dev', False otherwise.
get_app_host(default='0.0.0.0')
Source code in luthien_control/settings.py
100 101 102 |
|
Gets the configured app host, defaulting if not set.
get_app_port(default=8000)
Source code in luthien_control/settings.py
104 105 106 |
|
Gets the configured app port, defaulting if not set.
get_app_reload(default=False)
Source code in luthien_control/settings.py
108 109 110 111 112 113 114 115 116 117 118 |
|
Gets the configured app reload, defaulting if not set.
get_backend_url()
Source code in luthien_control/settings.py
30 31 32 33 34 35 36 37 38 |
|
Returns the backend URL as a string, if set.
get_database_url()
Source code in luthien_control/settings.py
40 41 42 |
|
Returns the primary DATABASE_URL, if set.
get_db_dsn(db_name=None)
Source code in luthien_control/settings.py
163 164 165 166 167 168 169 170 171 |
|
Returns the DSN for a specific database name, or the default DB_NAME. Raises ValueError if required DB settings or the target db_name are missing.
get_log_level(default='INFO')
Source code in luthien_control/settings.py
95 96 97 |
|
Gets the configured log level, defaulting if not set.
get_main_db_pool_max_size()
Source code in luthien_control/settings.py
87 88 89 90 91 92 |
|
Returns the maximum pool size for the main DB.
get_main_db_pool_min_size()
Source code in luthien_control/settings.py
80 81 82 83 84 85 |
|
Returns the minimum pool size for the main DB.
get_openai_api_key()
Source code in luthien_control/settings.py
44 45 46 |
|
Returns the OpenAI API key, if set.
get_policy_filepath()
Source code in luthien_control/settings.py
52 53 54 |
|
Returns the path to the policy file, if set.
get_postgres_port()
Source code in luthien_control/settings.py
69 70 71 72 73 74 75 76 77 |
|
Returns the PostgreSQL port as an integer, or None if not set.
get_run_mode()
Source code in luthien_control/settings.py
173 174 175 |
|
Returns the run mode, defaulting to 'prod' if not set.
get_top_level_policy_name()
Source code in luthien_control/settings.py
48 49 50 |
|
Returns the name of the top-level policy instance to load.