Core
Core application: LLM models, prompt templates, and pipeline settings.
Models
Core models for LLM model management.
This module provides database models for tracking: - LLM models (HuggingFace model IDs) used for text generation - Prompt templates (Jinja2 templates for LLM prompts)
Note: Geographic models (Region, Country, Language) have been relocated to cw.audiences.
- class cw.core.models.LLMModel(*args, **kwargs)[source]
Bases:
ModelHuggingFace language model configuration.
Stores model identifiers and metadata for LLMs used in adaptation tasks. Each model can be marked as primary or alternative for specific languages.
Example
>>> model = LLMModel.objects.create( ... model_id="Qwen/Qwen2.5-7B-Instruct", ... name="Qwen 2.5 7B Instruct", ... notes="Good multilingual support" ... )
- model_id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- name
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- notes
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_active
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- load_in_4bit
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.
- updated_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- exception NotUpdated
Bases:
ObjectNotUpdated,DatabaseError
- ad_units
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_reverse_many_to_one_manager()defined below.
- alternative_for_languages
Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.
In the example:
class Pizza(Model): toppings = ManyToManyField(Topping, related_name='pizzas')
Pizza.toppingsandTopping.pizzasareManyToManyDescriptorinstances.Most of the implementation is delegated to a dynamically defined manager class built by
create_forward_many_to_many_manager()defined below.
- 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.
- languagealternativemodel_set
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_reverse_many_to_one_manager()defined below.
- objects = <django.db.models.manager.Manager object>
- primary_for_languages
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_reverse_many_to_one_manager()defined below.
- class cw.core.models.PromptTemplate(*args, **kwargs)[source]
Bases:
ModelDatabase-backed LLM prompt template with versioning and validation.
- CATEGORY_CHOICES = [('enhancement', 'Prompt Enhancement'), ('adaptation', 'Cultural Adaptation'), ('evaluation', 'Quality Evaluation'), ('concept', 'Concept Analysis')]
- slug
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- name
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- category
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- template
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- expected_variables
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- version
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_active
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- description
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.
- updated_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- created_by
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- usage_count
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- last_used_at
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- save(*args, **kwargs)[source]
Save the template, auto-incrementing version if template content changed.
If this is an update to an existing template and the template content has changed, we: 1. Deactivate the old version 2. Create a new version (incrementing version number) 3. Mark it as active
- render(**context)[source]
Render this template with the provided context.
- Parameters:
**context – Variables to pass to the Jinja2 template
- Returns:
Rendered template string
Updates usage analytics (usage_count, last_used_at).
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- exception NotUpdated
Bases:
ObjectNotUpdated,DatabaseError
- created_by_id
- get_category_display(*, field=<django.db.models.fields.CharField: category>)
- 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.
- objects = <django.db.models.manager.Manager object>
- class cw.core.models.PipelineSettings(*args, **kwargs)[source]
Bases:
ModelSingleton app-level defaults for per-node LLM model selection.
Each pipeline node (concept analyst, cultural researcher, evaluation gates) can have its own default LLM model. If not set, falls back to global_default_model. Writer node is excluded — it defaults to the Language’s primary LLM.
- global_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- concept_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- culture_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- format_gate_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- culture_gate_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- concept_gate_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- brand_gate_default_model
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- created_at
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.
- exception DoesNotExist
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned
Bases:
MultipleObjectsReturned
- exception NotUpdated
Bases:
ObjectNotUpdated,DatabaseError
- brand_gate_default_model_id
- concept_default_model_id
- concept_gate_default_model_id
- culture_default_model_id
- culture_gate_default_model_id
- format_gate_default_model_id
- 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)
- global_default_model_id
- id
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>
Admin
Django admin configuration for core models.
- class cw.core.admin.LLMModelAdmin(model, admin_site)[source]
Bases:
ModelAdmin- Parameters:
model (type[Model])
admin_site (AdminSite)
- list_display = ['name', 'model_id', 'show_4bit', 'show_active', 'show_language_count', 'updated_at']
- list_filter = ['is_active', 'load_in_4bit']
- search_fields = ['name', 'model_id', 'notes']
- readonly_fields = ['created_at', 'updated_at']
- fieldsets = (('Model', {'classes': ['tab'], 'fields': ('model_id', 'name', ('is_active', 'load_in_4bit'))}), ('Notes', {'classes': ['tab'], 'fields': ('notes',)}), ('Metadata', {'classes': ['tab'], 'fields': ('created_at', 'updated_at')}))
- property media
- class cw.core.admin.PromptTemplateAdmin(model, admin_site)[source]
Bases:
ModelAdminAdmin interface for PromptTemplate with Unfold styling and tabs.
- Parameters:
model (type[Model])
admin_site (AdminSite)
- list_display = ['name', 'slug', 'category', 'version', 'is_active', 'usage_count', 'last_used_at', 'updated_at']
- list_filter = ['category', 'is_active', 'created_at', 'updated_at']
- search_fields = ['name', 'slug', 'description', 'template']
- readonly_fields = ['version', 'created_at', 'updated_at', 'usage_count', 'last_used_at']
- fieldsets = (('Overview', {'classes': ('tab',), 'description': 'Basic template information and status', 'fields': ('slug', 'name', 'category', 'is_active')}), ('Documentation', {'classes': ('tab',), 'description': 'Purpose, usage notes, and examples for this template', 'fields': ('description',)}), ('Template Content', {'classes': ('tab',), 'description': 'Jinja2 template content - use {{ variable }} syntax for placeholders', 'fields': ('template',)}), ('Variables', {'classes': ('tab',), 'description': 'Expected template variables (JSON format): {name: {type, required, description}}', 'fields': ('expected_variables',)}), ('Version Information', {'classes': ('tab',), 'description': 'Version history and authorship information', 'fields': ('version', 'created_by', 'created_at', 'updated_at')}), ('Usage Analytics', {'classes': ('tab',), 'description': 'Template usage statistics and metrics', 'fields': ('usage_count', 'last_used_at')}))
- actions = ['duplicate_template', 'activate_version', 'test_render']
- activate_version(request, queryset)[source]
Set selected version as active (deactivates other versions of same slug).
- test_render(request, queryset)[source]
Test rendering templates with sample data (basic validation).
- property media
- class cw.core.admin.PipelineSettingsAdmin(model, admin_site)[source]
Bases:
ModelAdminSingleton admin for per-node LLM model defaults.
- Parameters:
model (type[Model])
admin_site (AdminSite)
- fieldsets = (('Global Default', {'classes': ['tab'], 'description': 'Fallback model used when no node-specific default is configured.', 'fields': ('global_default_model',)}), ('Research Nodes', {'classes': ['tab'], 'fields': ('concept_default_model', 'culture_default_model')}), ('Evaluation Gates', {'classes': ['tab'], 'fields': ('format_gate_default_model', 'culture_gate_default_model', 'concept_gate_default_model', 'brand_gate_default_model')}), ('Metadata', {'classes': ['tab'], 'fields': ('created_at', 'updated_at')}))
- readonly_fields = ['created_at', 'updated_at']
- has_add_permission(request)[source]
Return True if the given request has permission to add an object. Can be overridden by the user in subclasses.
- has_delete_permission(request, obj=None)[source]
Return True if the given request has permission to delete the given Django model instance, the default implementation doesn’t examine the obj parameter.
Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.
- property media
Prompt Rendering
Jinja2 template loader for LLM prompts.
Templates are loaded exclusively from the database (PromptTemplate model). This enables live editing via Django admin without code deployment. Results are cached in Redis/memory for 5 minutes to minimize DB hits.
Usage:
from cw.lib.prompts import render_prompt
prompt = render_prompt(
"adaptation",
target_market_name="US Hispanic",
target_market_rules="...",
original_json=original_data,
)
- cw.lib.prompts.render_prompt(slug, **context)[source]
Render a prompt template with the given context.
Loads the template from the database (PromptTemplate model) by slug, with Redis/memory caching (5-minute TTL) and usage analytics.
- Parameters:
- Return type:
- Returns:
Rendered prompt string
- Raises:
PromptTemplate.DoesNotExist – If no active template with the given slug exists
Example:
prompt = render_prompt( "adaptation", target_market_name="US Hispanic", original_json=data, )