openedx_ai_extensions package

Contents

openedx_ai_extensions package#

Subpackages#

Submodules#

openedx_ai_extensions.admin module#

Django admin configuration for AI Extensions models.

class openedx_ai_extensions.admin.AIWorkflowConfigAdmin(model, admin_site)#

Bases: ModelAdmin

Admin interface for managing AI Workflow Configurations.

fieldsets = (('Scope Matching', {'description': 'Define which course/location this scope applies to. <code>location_regex</code> is a Python regex matched against the unit/block location ID.', 'fields': ('course_id', 'location_regex', 'service_variant')}), ('UI Slot', {'description': 'Select which frontend widget renders this scope. Each widget sends its own <code>uiSlotSelectorId</code> to the backend; only the scope that matches exactly will be returned. This guarantees that exactly the configured slots render no more, no fewer.', 'fields': ('ui_slot_selector_id',)}), ('Profile & Status', {'fields': ('profile', 'enabled', 'specificity_index')}))#
form#

alias of AIWorkflowScopeAdminForm

list_display = ('course_id', 'location_regex', 'ui_slot_selector_id', 'specificity_index', 'service_variant', 'enabled', 'profile_link')#
list_filter = ('service_variant', 'enabled', 'ui_slot_selector_id')#
property media#

Render the profile as a clickable link to its admin change page.

readonly_fields = ('specificity_index',)#
search_fields = ('course_id', 'location_regex', 'ui_slot_selector_id', 'profile__slug', 'profile__content_patch')#
class openedx_ai_extensions.admin.AIWorkflowProfileAdmin(model, admin_site)#

Bases: ModelAdmin

Admin interface for AI Workflow Profiles with preview and validation.

class Media#

Bases: object

Admin media assets.

css = {'all': ('openedx_ai_extensions/admin.css',)}#
base_template_preview(obj)#

Show the base template file content as-is.

description_preview(obj)#

Show truncated description.

effective_config_preview(obj)#

Show the effective merged configuration as formatted JSON.

fieldsets = (('Basic Information', {'fields': ('slug', 'description')}), ('Profile Template Configuration', {'description': 'Select a base template and optionally override values with JSON patch.', 'fields': ('base_filepath', 'base_template_preview', 'content_patch')}), ('Preview & Validation', {'classes': ('collapse',), 'description': 'View the merged configuration and validation results.', 'fields': ('effective_config_preview', 'validation_status')}))#
form#

alias of AIWorkflowProfileAdminForm

is_valid(obj)#

Show validation status with icon.

list_display = ('slug', 'base_filepath', 'description_preview', 'is_valid')#
list_filter = ('base_filepath',)#
property media#
readonly_fields = ('base_template_preview', 'effective_config_preview', 'validation_status')#
search_fields = ('slug', 'description', 'base_filepath', 'content_patch')#
validation_status(obj)#

Show detailed validation results.

class openedx_ai_extensions.admin.AIWorkflowProfileAdminForm(*args, **kwargs)#

Bases: ModelForm

Custom form for AIWorkflowProfile with template selection.

class Meta#

Bases: object

Form metadata.

fields = '__all__'#
model#

alias of AIWorkflowProfile

widgets = {'content_patch': <django.forms.widgets.Textarea object>}#
base_fields = {'base_filepath': <django.forms.fields.CharField object>, 'content_patch': <django.forms.fields.CharField object>, 'description': <django.forms.fields.CharField object>, 'slug': <django.forms.fields.SlugField object>}#
clean()#

Validate the effective configuration after merging base template with patch.

clean_content_patch()#

Validate JSON5 syntax in content_patch.

declared_fields = {}#
property media#

Return all media required to render the widgets on this form.

class openedx_ai_extensions.admin.AIWorkflowScopeAdminForm(*args, **kwargs)#

Bases: ModelForm

Admin form for AIWorkflowScope.

ui_slot_selector_id is a free-text field with an HTML5 datalist that auto-suggests every value already present in the database. No Django settings are required — the suggestions grow automatically as operators configure more scopes.

class Meta#

Bases: object

Form metadata.

fields = '__all__'#
model#

alias of AIWorkflowScope

widgets = {'ui_slot_selector_id': <openedx_ai_extensions.admin.UiSlotDatalistWidget object>}#
base_fields = {'course_id': <django.forms.fields.CharField object>, 'enabled': <django.forms.fields.BooleanField object>, 'location_regex': <django.forms.fields.CharField object>, 'profile': <django.forms.models.ModelChoiceField object>, 'service_variant': <django.forms.fields.TypedChoiceField object>, 'ui_slot_selector_id': <django.forms.fields.CharField object>}#
declared_fields = {}#
property media#

Return all media required to render the widgets on this form.

class openedx_ai_extensions.admin.AIWorkflowSessionAdmin(model, admin_site)#

Bases: ModelAdmin

Admin interface for managing AI Workflow Sessions.

actions = ['debug_thread']#
date_hierarchy = 'created_at'#

Render a link to the debug thread view for this session.

debug_thread(request, queryset)#

Redirect selected sessions to the debug thread view.

debug_thread_view(request)#

Render the full local and remote threads for selected sessions.

exclude = ('user', 'scope', 'profile', 'local_submission_id', 'metadata')#
get_urls()#

Return custom admin URLs for debug views.

list_display = ('user', 'course_id', 'profile_slug', 'location_id', 'created_at', 'updated_at')#
list_filter = ('created_at',)#

Render local_submission_id as a link to submissions filtered by student_item_id.

property media#
metadata_pretty(obj)#

Render metadata as indented JSON.

Render profile as a link to its admin change page.

profile_slug(obj)#

Return the profile slug for list display.

readonly_fields = ('user_link', 'scope_link', 'profile_link', 'course_id', 'location_id', 'local_submission_id_link', 'remote_response_id', 'debug_link', 'metadata_pretty', 'created_at', 'updated_at')#

Render scope as a link to its admin change page.

search_fields = ('user__username', 'course_id', 'location_id', 'profile__slug')#

Render user as a link to their admin change page.

class openedx_ai_extensions.admin.PromptTemplateAdmin(model, admin_site)#

Bases: ModelAdmin

Admin interface for Prompt Templates - one big textbox for easy editing.

body_preview(obj)#

Show truncated body text.

get_fieldsets(request, obj=None)#

Return dynamic fieldsets with UUID example if editing existing object.

get_form(request, obj=None, change=False, **kwargs)#

Customize the form to use a large textarea for body.

list_display = ('slug', 'body_preview', 'updated_at')#
list_filter = ('created_at', 'updated_at')#
property media#
readonly_fields = ('id', 'created_at', 'updated_at')#
search_fields = ('slug', 'body')#
class openedx_ai_extensions.admin.UiSlotDatalistWidget(attrs=None)#

Bases: TextInput

Text input enhanced with an HTML5 <datalist> element.

Shows all ui_slot_selector_id values already stored in the database. The list is built at render time so it always reflects the current state of the DB — no settings, no code changes needed. The operator can still type any free-form value; the datalist only provides suggestions.

property media#
render(name, value, attrs=None, renderer=None)#

Render the text input with an attached <datalist> of existing slot selectors.

openedx_ai_extensions.apps module#

openedx_ai_extensions Django application initialization.

class openedx_ai_extensions.apps.OpenedxAIExtensionsConfig(app_name, app_module)#

Bases: AppConfig

Configuration for the openedx_ai_extensions Django application.

See openedx/edx-django-utils for more details and examples.

default_auto_field = 'django.db.models.BigAutoField'#
name = 'openedx_ai_extensions'#
plugin_app = {'settings_config': {'cms.djangoapp': {'common': {'relative_path': 'settings.common'}, 'production': {'relative_path': 'settings.production'}, 'test': {'relative_path': 'settings.test'}}, 'lms.djangoapp': {'common': {'relative_path': 'settings.common'}, 'production': {'relative_path': 'settings.production'}, 'test': {'relative_path': 'settings.test'}}}, 'signals_config': {'cms.djangoapp': {'receivers': [], 'relative_path': 'signals'}, 'lms.djangoapp': {'receivers': [], 'relative_path': 'signals'}}, 'url_config': {'cms.djangoapp': {'namespace': 'openedx_ai_extensions', 'regex': '^openedx-ai-extensions/', 'relative_path': 'urls'}, 'lms.djangoapp': {'namespace': 'openedx_ai_extensions', 'regex': '^openedx-ai-extensions/', 'relative_path': 'urls'}}}#
ready()#

Import xAPI transformers to register them with the XApiTransformersRegistry.

This ensures that our custom event transformers are available when the event-routing-backends processor looks them up.

verbose_name = 'Open edX AI Extensions (v2.5.1)'#

openedx_ai_extensions.decorators module#

Decorators for Open edX AI Extensions.

openedx_ai_extensions.decorators.handle_ai_errors(func)#

Decorate Django/DRF views to catch AI-related and general exceptions.

Returns a standardized JSON error contract.

openedx_ai_extensions.models module#

Database models for openedx_ai_extensions.

class openedx_ai_extensions.models.PromptTemplate(*args, **kwargs)#

Bases: Model

Reusable prompt templates for AI workflows.

This is the source for reusable prompt text. Profiles can reference templates by slug (human-readable) or UUID (stable).

Examples

  • slug: “eli5”, “summarize_unit”, “explain_concept”

  • body: “You are a helpful AI that explains things simply…”

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

body#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

created_at#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)#
get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)#
get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)#
get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)#
id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod load_prompt(template_identifier)#

Load prompt text by slug or UUID.

Uses regex to detect UUID format and query accordingly for efficiency.

Parameters:

template_identifier – Either a slug (str) or UUID string

Returns:

The prompt body, or None if not found

Return type:

str or None

objects = <django.db.models.manager.Manager object>#
slug#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

updated_at#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

openedx_ai_extensions.receivers module#

Django signal receivers for openedx-ai-extensions.

This is the entry point that bridges the event bus → orchestrator.

openedx_ai_extensions.receivers.handle_ai_orchestration_requested(_sender, ai_orchestration_request, **kwargs)#

Triggered when any app publishes AI_ORCHESTRATION_REQUESTED.

Either in-process (direct Django signal) or via the event bus consumer loop. Looks up the AIWorkflowProfile by slug and runs the orchestrator.

openedx_ai_extensions.signals module#

Signal handlers for the openedx_ai_extensions application.

openedx_ai_extensions.tasks module#

Celery tasks that will be registered.

openedx_ai_extensions.urls module#

URLs for openedx_ai_extensions.

openedx_ai_extensions.utils module#

Utility functions for Open edX AI Extensions.

openedx_ai_extensions.utils.is_generator(result)#

Check if the given object is a generator.

Parameters:

result (Any) – The object to check.

Returns:

True if the object is an instance of GeneratorType, False otherwise.

Return type:

bool

openedx_ai_extensions.utils.normalize_input_to_text(input_data) str#

Coerce input_data to a plain string suitable for use as message content.

Handles: str, dict with ‘text’ key, other dicts (JSON-serialised), None.

openedx_ai_extensions.views module#

Views for the openedx_ai_extensions app.

Module contents#

A experimental plugin for Open edX designed to explore AI extensibility.