Fix attachments never being sent with the message
Uploading an image showed the chip and then did nothing: the file was stored but never reached the model. Two causes, both in the composer template. The chips live in #attachments, and each carries the hidden file_ids input that binds it to the message. That container sat OUTSIDE the <form>, with an `hx-include="#attachments"` on a hidden <div> inside the form meant to pull it back in. That attribute only has an effect on the element issuing the request -- on a child of it, it does nothing. So the form serialised content and nothing else, and post_message saw no file_ids at all. Fixed by putting #attachments inside the form, where the inputs are submitted because they are in the form, rather than because of an attribute that has to be wired correctly. The file input stays outside, since inside it would submit an empty file part on every message. Second: /chat preselected models[0] rather than the model a new chat would actually use. With a vision model set as the default and a non-vision one first in the admin ordering, the composer showed the wrong model, sent the wrong model, and told the user images *would* be sent when they would not. It now resolves through default_model(), the same path /start uses. Every server-side test passed throughout, because the bug was entirely in the wiring between template and browser. Added tests that serialise the rendered form the way a browser does -- every named input inside <form> -- and assert file_ids is among them and the image reaches the model as a content part. Verified they fail with the old markup restored, then pass again. Confirmed end to end against gemma4-e4b-q8: given a drawing, it replied "Left: Green Circle / Right: Orange Triangle". 220 tests, ruff clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+14
-3
@@ -82,9 +82,20 @@ async def chat_index(request: Request, db: Db, user: RequiredUser, model: str =
|
||||
creating a row for a chat that may never be sent.
|
||||
"""
|
||||
context = _chat_context(db, user, None)
|
||||
preselected = next(
|
||||
(m for m in context["models"] if m.model_id == model), None
|
||||
) or (context["models"][0] if context["models"] else None)
|
||||
|
||||
# Fall back to the same choice a new chat would make -- the user's default,
|
||||
# then the instance default, then first in order. Using models[0] here
|
||||
# instead would show a model the chat is not going to use, which matters:
|
||||
# the composer decides from it whether to warn that images will be dropped.
|
||||
preselected = next((m for m in context["models"] if m.model_id == model), None)
|
||||
if preselected is None:
|
||||
chosen = chat_service.default_model(db, user)
|
||||
if chosen is not None:
|
||||
preselected = next(
|
||||
(m for m in context["models"] if m.model_id == chosen[0]), None
|
||||
)
|
||||
if preselected is None and context["models"]:
|
||||
preselected = context["models"][0]
|
||||
|
||||
return render(
|
||||
request,
|
||||
|
||||
Reference in New Issue
Block a user