Release Notes — v0.2.19 (August 23, 2026)
1. New App: enezaagents — AI Agent Runtime
Status: Uncommitted
A brand-new Django app that lets users define, version, publish, and run AI agents from inside the Eneza admin, backed by pluggable LLM providers (OpenAI, Ollama) and tool-calling.
Models
| Model | Purpose |
|---|---|
Agent |
Top-level agent definition with code, description, and status (Draft/Published/Archived). publish() snapshots the working draft into a new AgentVersion. |
AgentVersion |
Versioned snapshot of an agent: instructions, model_config, output_schema, version_status, is_latest. |
AgentVersionTool |
Through model binding a Tool to an AgentVersion with per-version configuration and enabled. |
AgentVersionSubAgent |
Through model binding a child Agent as a delegatable sub-agent with a role and configuration. |
LLMProvider |
Provider registry entry (OpenAI/Ollama/…) with JSON configuration and enabled. |
ModelConfiguration |
Per-provider model settings: model_name, temperature, max_tokens, JSON configuration. |
Tool |
Executable tool with a type (Python / REST API / Database), JSON schema, and configuration. |
AgentRun |
Records one execution of a published AgentVersion, with input/output/status/task_id timestamps and optional parent_run for sub-agent nesting. |
AgentStep |
Ordered trace of each step in a run (LLM call, tool call, sub-agent, complete, failed). |
Artifact |
Named output artifacts produced by a run. |
Provider Adapters (enezaagents/providers/)
BaseLLMABC +LLMResponse/ToolCallnormalization layer.OpenAIProvider— chat completions, tool calling, structured output (json_schema), readsapi_key/base_urlfrom provider config orOPENAI_API_KEY/OPENAI_BASE_URLenv vars.OllamaProvider—ollamaPython package, tool calling + structured output (format).registry.get_llm()dispatches onLLMProvider.provider_type.
Runtime (enezaagents/runtime/)
agent_runner.run_agent_version()— iterative agent loop: builds tool/sub-agent schemas, calls the LLM, routes tool calls, recordsAgentRun/AgentStep, and terminates on final answer or max iterations.ToolRouter— executes tools by type:- Python: imports a dotted callable path.
- REST API: HTTP request via
requestswith params/data/json/headers config. - Database: safe queryset reads with field allowlists and an operator whitelist (
exact,iexact,icontains,in,gt,gte,lt,lte,isnull), capped atmax_rows. - Sub-agent delegation with cycle detection and max depth (
MAX_SUB_AGENT_DEPTH = 5).
Tasks (enezaagents/tasks/run.py)
execute_agent_runbackground task (django-tasks) andqueue_agent_runhelper that defers enqueue until after commit and captures the current thread-local user.
Admin & URLs
- Full CRUD setup views for all models via the framework setup/readonly base views, plus
AgentPublishView(POST /agent/publish/<pk>/) and read-only list/detail views forAgentRun,AgentStep, andArtifact. - App menu registered in
apps.py(Agents, LLM Providers, Model Configurations, Tools, Runs) withmenu_position = 99. - Initial migration
0001_initial. - New template:
enezaagents/templates/enezaagents/readonly_list.html.
Integration
enezaagentsadded toINSTALLED_APPSinframework/settings.py,eneza/templates/project/project_template/settings.py, andtestproject/testproject/settings.py.- URLs mounted in
framework/urls.py(/enezaagents/), project template (/agents/), andtestproject/testproject/urls.py(/agents/), all withnamespace='enezaagents'. - Packaging:
enezaagentsadded topackagesandpackage_datainsetup.py. - New runtime dependencies:
openai>=1.40.0andollama>=0.4.0insetup.pyinstall_requiresandrequirements.txt.
2. New BaseEnezaModelForm — Boolean Fields as Yes/No Select
Status: Uncommitted
Added BaseEnezaModelForm (enezaframework/forms/__init__.py) that automatically replaces every BooleanField widget with a new YesNoSelect widget (enezaframework/widgets.py) that renders a Yes/No dropdown instead of a checkbox.
All modelform_factory calls in UiMixin/UiMixinjournal (enezaframework/views/mixins.py) now pass form=BaseEnezaModelForm, so every generated model form inherits this behavior.
Display Consistency
get_smart_value (enezaframework/templatetags/custom_filters.py) now renders boolean values as Yes/No in read-only/detail views, matching the new form widget.
3. TomSelect Improvements
Status: Uncommitted
Auto-Initialization (enezaframework/static/assets/js/tomselect-init.js)
initTomSelects() is now invoked automatically:
- on DOMContentLoaded when scripts load late, and
- after every HTMX swap via the global htmx:afterSwap listener.
This guarantees the widget initializes regardless of load path and removes the need for per-partial inline init calls.
Detail Partials
Added if (typeof initTomSelects === 'function') { initTomSelects(); } to:
- core/partials/detail_partial.html
- core/partials/detail_source_document_partial.html
Styling (tomselect-custom.css)
.ms-wrappernow expands to fill available width (flex: 1 1 0%; min-width: 0; width: 100%).- Restyled control, search input, and dropdown colors to match the app theme (light
#e0e6edborders, dark#121e32/#17263csurfaces, primary accent#4361ee), larger padding, and heavier font weight. - Removed the dark placeholder override in favor of a single
placeholderrule. - Cache-busting query param bumped to
?v=3incomponents/layouts/default.html.
4. Sidebar Menu State Persistence
Status: Uncommitted
apps_sidebar.html now persists the active dropdown section per app:
- Alpine
$persiststores the openfasttabper app undereneza-sidebar-tab-<current_app>inlocalStorage. - On first visit (no saved choice), the sidebar auto-opens the section containing the active page.
- Added
data-tabattribute to menu buttons to support the auto-open logic.
5. Framework Test App (frameworkapp) Demo Changes
Status: Uncommitted
frameworktestgained aframeworktestsetupManyToManyField(withrelated_name="frameworktest_setups").Frameworktestsetupnow has a__str__returning its name.FrameworkTestDetailView:frameworktestsetupadded to the detailfieldtabs.FrameworkTestCreateView: new tab group with theframeworktestsetupM2M field.- New
FrameworktestsetupAutocompleteView(autocomplete for the M2M selector). - New migration
0011_frameworktest_frameworktestsetup.py.
6. Version Bump
setup.py: Version bumped from0.2.18→0.2.19.RELEASE_NOTE/CHANGELOG.md: Added 0.2.19 entry.
Summary
| Area | Description | Files |
|---|---|---|
| enezaagents | New AI Agent Runtime app (models, providers, runtime, tasks, views, URLs, menu, migration, templates) | ~25 |
| Framework Forms | BaseEnezaModelForm + YesNoSelect widget, applied to all model forms |
3 |
| Boolean Display | get_smart_value renders booleans as Yes/No |
1 |
| TomSelect | Auto-init on load/HTMX swap, theme restyle, cache-bust | 5 |
| Sidebar | Per-app dropdown state persistence via localStorage | 1 |
| Test App | M2M frameworktestsetup, autocomplete view, migration |
3 |
| Integration | INSTALLED_APPS/urls in 3 projects, packaging, deps | 6 |
| Versioning | Version bumped to 0.2.19, CHANGELOG updated | 2 |
Total: 20 modified files, 1 new migration, and the new enezaagents/ package (plus docs in .kilo/plans/ and feature_Planure/).
Note: All changes are uncommitted and untested. The user is solely responsible for testing and validating all outputs before committing or deploying.