Skip to content

v0.42.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 10:18
· 35 commits to main since this release
12b8911

Changed

  • The vendored web component is @artooi/ag-ui-web-component@0.37.0, which
    reports a send that would otherwise vanish. An element with no endpoint
    swallowed every message after the two visible halves of a working send had
    already happened — the bubble was in the transcript and the submit event had
    fired — so the composer cleared, the message appeared to go, and nothing was
    ever requested. It now names the missing attribute on the console and says so
    in the transcript.

    Not an inert re-vendor, and checked rather than assumed: the bundle grows 779
    bytes and first differs at char 246266, well before the embedded version
    string. Two smaller silent failures ride along — a checkpoint resumed with an
    empty composer, and a data-strings or data-skills value that will not
    parse.

    Nothing is owed on the host side, which is a result rather than a step
    skipped. The three changed rows in the component's own reference are
    modifications, not additions: no new attribute, property or method, and the
    only new public surface is a CSS part. The check that mattered was the last
    one — this package hands the component data-strings verbatim, so a key
    allowlist here would have silently dropped the two new string keys. There is
    none; _strings_json is a bare json.dumps.

  • The django-ag-ui floor is >=0.58. That release floors
    djangorestframework-pydantic-ai at 0.27, which stops a spec dispatch leaving
    a database connection open on asgiref's shared thread — a leak that survives
    an HTTP request, because request_finished closes the connection belonging to
    the request's thread and django.db.connections is thread-local.

    The [mcp] extra's djangorestframework-mcp-server>=0.37 deliberately does
    not move, though 0.41 is published: its work is the OAuth surface the
    in-process bridge never reaches, so raising the floor would narrow what a
    consumer may resolve in exchange for nothing. The lockfile was moved to
    0.41.0 all the same — a stale lock and a load-bearing floor are different
    claims, and the manual sibling audit is what catches the first, because
    Dependabot's uv group has never once proposed a first-party bump.

Fixed

  • SidebarAdminSite no longer hands a signed-out visitor the route manifest.
    each_context runs for the admin's login page like every other admin page, and
    it was building a full sidebar context there. That context carries
    build_route_map(), which takes no user and walks admin.site._registry
    unfiltered — so a template rendering it unconditionally published an
    inventory of every registered model, its label and its admin URL to anyone who
    could reach the login page.

    An anonymous request now gets an empty django_admin_agent. It is falsy, so
    {% if django_admin_agent %} is the natural guard and a host that already
    wrote one is unaffected; {{ django_admin_agent.endpoint }} resolves to the
    empty string either way, so a host rendering unconditionally is no worse off
    than before — its launcher was already inert for a visitor the endpoint
    refuses. It loses only the manifest it should not have had.

    This completes the previous release's fix, which covered the template tag and
    deliberately left this path alone on the grounds that the render decision is
    the host's. That remains true of the markup and is not true of the content.

    Two states here, not the tag's three: AdminSite.each_context reads
    request.user itself and raises first, so "no user to judge" cannot be
    reached — pinned by a test, so nobody adds a conjunct no test could hold.

  • The sidebar rendered on the admin login page, where nobody is signed in and
    the endpoint behind the launcher would refuse them. {% django_admin_agent_sidebar %}
    is installed in admin/base_site.html, and the login page renders that
    template's branding block like every other admin page — so the one page reached
    before signing in offered a chat that could only ever answer 401, and loaded the
    bootstrap module, the route manifest and the skill catalog to do it.

    The route manifest is the part worth upgrading for. build_route_map()
    takes no user and walks admin.site._registry unfiltered, so the login page
    served an unauthenticated visitor a JSON inventory of every registered
    model
    — app label, verbose name and admin URL apiece. Nothing there is a
    credential and admin URLs are guessable one at a time, but the complete list is
    not something a signed-out visitor should be handed, and it was being handed
    over by default. Reported as a cosmetic oddity; it is not one.

    The tag now renders nothing when the request carries an anonymous user. It is
    not a styling choice a host might want either way: the agent view requires an
    active staff user, so a launcher offered to a signed-out visitor is dead UI.

    Two states are deliberately unchanged. A signed-in principal renders exactly as
    before, and a context with no request — or a request that never met
    AuthenticationMiddleware — still renders, because "nobody to refuse" is not
    the same answer as "refused": a template rendered outside a request cycle has no
    visitor to gate on, which is the degradation the tag already documented.

    SidebarAdminSite.each_context is unchanged. That path hands the context to
    your own template, which is where the decision belongs there; each_context
    runs for the login page too, so guard your markup with
    {% if user.is_authenticated %}. Both docs pages now say so.