openedx_ai_extensions package#
Subpackages#
- openedx_ai_extensions.api package
- openedx_ai_extensions.edxapp_wrapper package
- openedx_ai_extensions.events package
- openedx_ai_extensions.functions package
- openedx_ai_extensions.processors package
- Subpackages
- Module contents
ContentLibraryProcessorEducatorAssistantProcessorLLMProcessorOpenEdXProcessorSubmissionProcessorSubmissionProcessor.get_chat_history()SubmissionProcessor.get_full_message_history()SubmissionProcessor.get_full_thread()SubmissionProcessor.get_previous_messages()SubmissionProcessor.get_submission()SubmissionProcessor.process()SubmissionProcessor.update_chat_submission()SubmissionProcessor.update_submission()
- openedx_ai_extensions.settings package
- openedx_ai_extensions.workflows package
- Subpackages
- openedx_ai_extensions.workflows.orchestrators package
- Submodules
- openedx_ai_extensions.workflows.orchestrators.base_orchestrator module
- openedx_ai_extensions.workflows.orchestrators.direct_orchestrator module
- openedx_ai_extensions.workflows.orchestrators.flashcards_orchestrator module
- openedx_ai_extensions.workflows.orchestrators.mock_orchestrator module
- openedx_ai_extensions.workflows.orchestrators.session_based_orchestrator module
- openedx_ai_extensions.workflows.orchestrators.threaded_orchestrator module
- Module contents
- openedx_ai_extensions.workflows.orchestrators package
- Submodules
- openedx_ai_extensions.workflows.models module
AIWorkflowProfileAIWorkflowProfile.DoesNotExistAIWorkflowProfile.MultipleObjectsReturnedAIWorkflowProfile.aiworkflowscope_setAIWorkflowProfile.aiworkflowsession_setAIWorkflowProfile.base_filepathAIWorkflowProfile.clean()AIWorkflowProfile.configAIWorkflowProfile.content_patchAIWorkflowProfile.content_patch_dictAIWorkflowProfile.descriptionAIWorkflowProfile.get_config()AIWorkflowProfile.get_ui_components()AIWorkflowProfile.idAIWorkflowProfile.objectsAIWorkflowProfile.orchestrator_classAIWorkflowProfile.processor_configAIWorkflowProfile.save()AIWorkflowProfile.slugAIWorkflowProfile.validate()
AIWorkflowScopeAIWorkflowScope.DoesNotExistAIWorkflowScope.MultipleObjectsReturnedAIWorkflowScope.SERVICE_VARIANTSAIWorkflowScope.actionAIWorkflowScope.aiworkflowsession_setAIWorkflowScope.clean()AIWorkflowScope.course_idAIWorkflowScope.enabledAIWorkflowScope.execute()AIWorkflowScope.get_profile()AIWorkflowScope.get_service_variant_display()AIWorkflowScope.idAIWorkflowScope.list_profiles_for_context()AIWorkflowScope.location_idAIWorkflowScope.location_regexAIWorkflowScope.objectsAIWorkflowScope.profileAIWorkflowScope.profile_idAIWorkflowScope.save()AIWorkflowScope.service_variantAIWorkflowScope.specificity_indexAIWorkflowScope.ui_slot_selector_id
AIWorkflowSessionAIWorkflowSession.DoesNotExistAIWorkflowSession.MultipleObjectsReturnedAIWorkflowSession.course_idAIWorkflowSession.created_atAIWorkflowSession.get_combined_thread()AIWorkflowSession.get_local_thread()AIWorkflowSession.get_remote_thread()AIWorkflowSession.idAIWorkflowSession.local_submission_idAIWorkflowSession.location_idAIWorkflowSession.metadataAIWorkflowSession.objectsAIWorkflowSession.profileAIWorkflowSession.profile_idAIWorkflowSession.remote_response_idAIWorkflowSession.scopeAIWorkflowSession.scope_idAIWorkflowSession.updated_atAIWorkflowSession.userAIWorkflowSession.user_id
- openedx_ai_extensions.workflows.template_utils module
- Module contents
- Subpackages
- openedx_ai_extensions.xapi package
Submodules#
openedx_ai_extensions.admin module#
Django admin configuration for AI Extensions models.
- class openedx_ai_extensions.admin.AIWorkflowConfigAdmin(model, admin_site)#
Bases:
ModelAdminAdmin 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#
- profile_link(obj)#
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:
ModelAdminAdmin interface for AI Workflow Profiles with preview and validation.
- 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:
ModelFormCustom form for AIWorkflowProfile with template selection.
- class Meta#
Bases:
objectForm 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:
ModelFormAdmin form for AIWorkflowScope.
ui_slot_selector_idis 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:
objectForm 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:
ModelAdminAdmin interface for managing AI Workflow Sessions.
- actions = ['debug_thread']#
- date_hierarchy = 'created_at'#
- debug_link(obj)#
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',)#
- local_submission_id_link(obj)#
Render local_submission_id as a link to submissions filtered by student_item_id.
- property media#
- metadata_pretty(obj)#
Render metadata as indented JSON.
- profile_link(obj)#
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')#
- scope_link(obj)#
Render scope as a link to its admin change page.
- search_fields = ('user__username', 'course_id', 'location_id', 'profile__slug')#
- user_link(obj)#
Render user as a link to their admin change page.
- class openedx_ai_extensions.admin.PromptTemplateAdmin(model, admin_site)#
Bases:
ModelAdminAdmin 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:
TextInputText input enhanced with an HTML5
<datalist>element.Shows all
ui_slot_selector_idvalues 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:
AppConfigConfiguration 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:
ModelReusable 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:
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.