lexigram-ai-feedback
AI feedback collection for the Lexigram Framework — collection, processing, and storage
Overview
AI feedback collection and continuous-learning loop for the Lexigram Framework. Captures user ratings, corrections, text feedback, and ground-truth labels from LLM interactions and routes them through an extensible processor pipeline to configurable storage backends. Zero-config usage starts with sensible defaults.
Full documentation: docs.lexigram.dev
Install
uv add lexigram-ai-feedback
Quick Start
from lexigram import Application
from lexigram.di.module import Module, module
from lexigram.ai.feedback import FeedbackModule
from lexigram.ai.feedback.config import FeedbackConfig
@module(
imports=[
FeedbackModule.configure(
FeedbackConfig(
enabled=True,
async_processing=True,
store_raw_payloads=False,
)
)
]
)
class AppModule(Module):
pass
async with Application.boot(modules=[AppModule]) as app:
# use app.container to resolve services
...
Configuration
Zero-config usage: Call
FeedbackModule.configure()with no arguments to use defaults.
Option 1 — YAML file
# application.yaml
ai_feedback:
enabled: true
async_processing: true
store_raw_payloads: false
Option 2 — Profiles + Environment Variables (recommended)
export LEX_AI_FEEDBACK__ENABLED=true
# Environment variables for each field
Option 3 — Python
from lexigram.ai.feedback.config import FeedbackConfig
from lexigram.ai.feedback import FeedbackModule
config = FeedbackConfig(
enabled=True,
async_processing=True,
store_raw_payloads=False,
)
FeedbackModule.configure(config)
Config reference
| Field | Default | Env var | Description |
|---|---|---|---|
enabled |
True |
LEX_AI_FEEDBACK__ENABLED |
Master on/off switch for all feedback collection |
async_processing |
True |
LEX_AI_FEEDBACK__ASYNC_PROCESSING |
Process feedback handlers asynchronously in the background |
store_raw_payloads |
False |
LEX_AI_FEEDBACK__STORE_RAW_PAYLOADS |
Persist raw incoming feedback payloads for auditing |
Module Factory Methods
| Method | Description |
|---|---|
FeedbackModule.configure(config) |
Configure with explicit config |
FeedbackModule.stub() |
Minimal config for testing |
Key Features
- Four feedback types: Rating, free-text, correction (original → corrected), and ground-truth labels
- Extensible processor pipeline: Custom processors via
FeedbackProcessorRegistry - Storage backends: In-memory, database (
DatabaseFeedbackStore), and cache (CachedFeedbackStore) - Middleware integration:
FeedbackMiddlewareandFeedbackContextfor request/response capture - Lifecycle hooks:
FeedbackSubmittedHook,FeedbackProcessedHook,FeedbackStoredHook
Security
Enforced payload size limits
Submitted feedback is validated at the submission chokepoints
(FeedbackCollector._store() for the middleware/processor pipeline and
the collect_* API; FeedbackService.submit_feedback() for the
programmatic service). Oversized payloads are rejected with
FeedbackTooLargeError (never silently truncated); boundary values
(exactly at the limit) pass.
| Limit | Constant | Applied to |
|---|---|---|
| 10,000 characters | MAX_FEEDBACK_TEXT_LENGTH |
TEXT feedback values and submit_feedback(comment=...) |
| 50,000 characters (serialized JSON) | MAX_CONTEXT_SIZE |
context and metadata dicts |
Optional endpoint authorization
create_feedback_endpoint() performs no identity check by default —
an endpoint mounted without an authorize callback accepts feedback from
anyone who can reach it; that is an explicit, informed choice, not an
enforced control. Pass an authorization callback to gate submissions:
from lexigram.ai.feedback import FeedbackCollector, FeedbackMiddleware
def authorize(ctx) -> bool:
# ctx.context_id is the context being submitted against;
# ctx.metadata carries what the host framework supplied (e.g. user)
return ctx.metadata.get("user_id") is not None
middleware = FeedbackMiddleware(
collector=FeedbackCollector(),
authorize=authorize,
)
app.post("/feedback", middleware.create_feedback_endpoint())
Sync and async (bool | Awaitable[bool]) callables are supported. A
denied submission raises FeedbackAuthorizationError before any
processing.
Testing
async with Application.boot(modules=[FeedbackModule.stub()]) as app:
# your test code
...
Key Source Files
| File | What it contains |
|---|---|
src/lexigram/ai/feedback/module.py |
FeedbackModule.configure(), .stub() |
src/lexigram/ai/feedback/config.py |
FeedbackConfig |
src/lexigram/ai/feedback/services/collector.py |
FeedbackCollector core service |
src/lexigram/ai/feedback/storage/database.py |
DatabaseFeedbackStore |
src/lexigram/ai/feedback/storage/cache.py |
CachedFeedbackStore |
src/lexigram/ai/feedback/processors/processor_registry.py |
FeedbackProcessorRegistry |
src/lexigram/ai/feedback/di/provider.py |
FeedbackProvider boot and registration |
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lexigram_ai_feedback-0.1.5003-py3-none-any.whl.
File metadata
- Download URL: lexigram_ai_feedback-0.1.5003-py3-none-any.whl
- Upload date:
- Size: 28.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9dcf9bbdcc408bde7747b13e2f318edf58a372c7642f2011b26dc08aeb112b6d
|
|
| MD5 |
6f8d1e3721bc421c7b449c2a675b9028
|
|
| BLAKE2b-256 |
720385f4bbdef2af22d08ce28d647bc5c67fa1edc1a26858eb1bd2e058a12092
|