Production image releases 1.87.0 → 1.102.0 (14 releases, Jul 16–21, 2026).
| service | image / pin | version span |
|---|---|---|
| dm | iblai-dm-pro | 4.307.0-ai → 4.313.0-ai |
| os | iblai-os-spa | 0.95.8 → 0.98.6 |
| lms | iblai-lms-spa | 0.46.0 → 0.50.0 |
| edx | iblai-edx-pro | sumac.2.40.1 → sumac.2.41.0 |
| cli | ibl-cli | 5.50.0 → 5.51.0 |
iblai-dm-pro — 4.307.0-ai → 4.313.0-ai
Granular course-creation tools. The agent's Course Creation toolkit gained per-object tools so an agent can build and inspect an edX course piece by piece instead of only delegating to the background pipeline: push_course_outline, create_structural_block, create_html_component, create_multiple_choice_component, create_mentor_component (an optionally-graded agent wired into a unit), get_unit_components, get_component_content, get_course_details (by db id or xblock id), and delete_xblock. The delegating tools now state in their descriptions that they hand the task to a subagent.
Course naming is now the model's job. create_full_course_on_edx pushes section, subsection and unit names verbatim — no more injected Module N: prefixes or N.M subsection numbering. Only the unit type prefix, which the content-drafting pipeline consumes, is still applied.
Agent skills are referenceable by the deep graph agent. The RAG dynamic_prompt middleware ran inside deepagents' SkillsMiddleware and replaced the whole system message, discarding the skills listing that progressive disclosure depends on. The system prompt is now rendered eagerly and passed via create_deep_agent(system_prompt=...), so the skills listing appends to it; skill files are built with create_file_data and seeded under the absolute /skills/ path.
Longer agent runs. Graph-agent default recursion limit raised to 300, and to 750 with deep research, for long multi-step tasks such as course creation.
Web crawler tuning. Playwright navigation timeout is now a global config setting, WEBCRAWLER_PLAYWRIGHT_TIMEOUT_SECONDS, overridable per tenant and defaulting to 30s — a slow-site tenant can be given more headroom without slowing crawls for everyone else. The crawler now navigates with wait_until="domcontentloaded" rather than waiting on every sub-resource (images, trackers, chat widgets), which makes JavaScript- and marketing-heavy sites crawl reliably. Default concurrency drops from 15 to 5 and the page limit from 1000 to 200, since each concurrent unit is a full Chromium page; both remain per-tenant overridable on the DocumentEmbedding model.
Chat privacy. Sessions with chat history disabled now use a throwaway in-memory checkpointer, so graph state is never persisted for a session that opted out. IBLChatMessageHistory gained should_commit_history() / ashould_commit_history(), which return False when the resolved chat-privacy mode is DISABLED, letting callers with their own persistence layer skip it.
Cost attribution and tracing. Langfuse traces emitted from bare llm.invoke() / ainvoke() paths — title generation, topic generation, guided-prompt generation, agent summary, memory component, quiz customization, moderation and the edX course assistant — now carry platform_key, user and session, so usage is attributable per platform. Every trace additionally carries new mentor_provider and mentor_model metadata (the agent's configured LLM provider and model), so cost can be grouped or filtered by provider or model; this is surfaced through a Langfuse custom dashboard grouped by metadata.platform_key. Health-check agents (fake-llm-mentor, fake-embedding-llm-mentor) are excluded from tracing on both the chat and embedding paths, keyed on mentor.unique_id, across the LangChain, Google-ADK, A2A and OpenAI-assistant runners; set ENABLE_LANGFUSE_FOR_FAKE_MENTORS to opt back in for load testing.
Deployment. No migrations. WEBCRAWLER_PLAYWRIGHT_TIMEOUT_SECONDS defaults to 30s, so existing crawler behavior is preserved without action. To raise it for one tenant, add a Global Configuration row in the DM Django admin with that key, the value in seconds, and Platform set to the tenant key — leaving Platform empty changes the global default. The override takes effect on that tenant's next document retrain or crawl.
iblai-os-spa — 0.95.8 → 0.98.6
Internationalization. The app is now internationalized with next-intl, with dynamic rendering so cookie-based locale selection doesn't break the build.
Chrome side-panel extension. New extension hosting the element in the browser side panel.
Chat. Pasted text and files are converted into uploads via a new clipboard file-extraction helper; attachment chips show the full MIME type; chat history paginates with infinite scroll-up; a NEXT_PUBLIC_MAXIMUM_CHARACTER_SIZE_TO_COPY env var sets the paste-to-file threshold, with empty-string values treated as unset. Thought-process steps split on bold delimiters.
Access control. New dataset curator viewer role on the Access tab.
Tenancy. The tenant switcher now appears when a user belongs to tenants other than main.
Voice. The text-to-speech endpoint is streamable.
Model manager. Installation status repolls, and program installations have fallbacks.
Desktop. macOS DMG release added, and the app icon is rounded into a native macOS squircle.
SEO. New SEO foundation — robots, sitemap, manifest, metadata and JSON-LD. Public agent pages and the explore directory are indexable with rich metadata; shared chat pages emit rich OG cards but are noindexed; SEO fetches are never cached, and explore metadata lists only public agents. Copy says "Agents" rather than "Mentors", with a screenshot OG fallback.
Markdown rendering. LaTeX preprocessing was extracted into its own module, and $…$ styling wrappers emitted by the LLM are unwrapped so they render as prose.
Other. iblai-js bumped to 1.20.1; user phone support is behind an env flag; the embed snippet dropped a redundant auth redirect.
iblai-lms-spa — 0.46.0 → 0.50.0
Sidebar and navbar revamp. The sidebar and top navbar were restructured around the shared PlatformSidebar component, with amber accents replaced by blue and reduced font weights, followed by an optimization pass.
Tenancy. Tenant switcher shown when a learner is enrolled on tenants other than main.
Agent course mode. New media list dropdown.
Assessment mode. Fullscreen is no longer clipped, and an informative popover was added.
Navigation copy. Course display name is preferred over title in the navbar, and empty-state labels were corrected.
Desktop. macOS DMG release workflow with independent Tauri versioning and auto-bump (app v1.0.15); the SSO auth session callback handler was restored.
iblai-edx-pro — sumac.2.40.1 → sumac.2.41.0
Second OpenID SSO backend gets an independent settings namespace. As shipped in 2.40.0, IBLOpenIDTwoBackend was a thin subclass that inherited every value from the shared IBL_OPENID_SSO_* configuration, so editing provider one's endpoint, field keys, JWKS URI, JWT decode options or id-token-field behavior changed provider two too. The second backend now reads its own IBL_OPENID_SSO_TWO_* namespace and the two providers share no configuration value.
Implementation bumps ibl-edx-base-oauth-sso-backend-app 1.9.0 → 1.10.0. auth_openid_multi.py is a behavioral clone of auth_openid.py, byte-identical in its class body and differing only in config source and class name; config.py defines a one-for-one OPENIDTWO_* block reading IBL_OPENID_SSO_TWO_* with its own defaults. The working base backend is untouched — independence is achieved by cloning, not by modifying the shared base. MultiConfigOpenIDMixin is retired, its per-config OIDC discovery folded into the clone's oidc_config, which resolves OIDC_ENDPOINT via self.setting(...) so each provider's own OAuth2ProviderConfig.other_settings still overlays ahead of the namespace default. Client key and secret continue to come from each backend's own OAuth2ProviderConfig.
Deployment. Shared apps/ package change — picked up on image rebuild plus LMS restart (ibl edx config && ibl edx restart), not live.
ibl-cli — 5.50.0 → 5.51.0
Registers and configures the second OpenID SSO backend. Open edX keys each OAuth2ProviderConfig by (site_id, backend_name), so a second config under the same backend name supersedes the first instead of coexisting. IBLOpenIDTwoBackend therefore runs alongside the existing openid-oauth2 provider under its own name, openidtwo-oauth2. The ibl-edx-base-oauth-sso-backend Tutor plugin template renders the full IBL_OPENID_SSO_TWO_* namespace into openedx-common-settings — a one-for-one parallel of IBL_OPENID_SSO_* covering NAME, OIDC_ENDPOINT, USE_IDP_USERNAME, the username/fullname/email/first-name/last-name keys, ID_TOKEN_ISSUER, the access-token, authorization, revoke-token, userinfo and JWKS URLs, JWT_DECODE_OPTIONS and USE_IDTOKEN_FIELDS — and appends the backend's dotted path to THIRD_PARTY_AUTH_BACKENDS.
Operator steps. Set the IBL_OPENID_SSO_TWO_* keys in config.yml, create one OAuth2ProviderConfig per backend name, regenerate config, and restart edX. Per-deployment secrets (client key and secret, optionally OIDC_ENDPOINT / platform_key) still come from each backend's own provider config row, overlaid ahead of these defaults. Requires ibl-edx-pro ibl-base-oauth-sso-backend >= 1.10.0.