feat(ui): allow to edit agent before importing#444
Merged
Conversation
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an “edit before import” flow for agents in the React UI and introduces guards/normalization to avoid sending assistant-final conversations that some backends (e.g., enable_thinking) reject.
Changes:
- Web UI: Parse imported agent JSON client-side, show an editable
AgentForm, then create the agent from edited data. - API: Reject “continue thread” requests (
previous_response_id) that contain no new user/tool message. - Core agent: Normalize conversations that end with an assistant message by appending a whitespace user message.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| webui/react-ui/src/pages/ImportAgent.jsx | Switches import workflow from uploading a file to parsing JSON, editing in AgentForm, and creating the agent. |
| webui/app.go | Adds validation to prevent continuing a conversation without new input. |
| core/agent/agent.go | Adds normalization to avoid requests ending with an assistant message for enable_thinking backends. |
Comments suppressed due to low confidence (6)
webui/react-ui/src/pages/ImportAgent.jsx:81
- Building the route with the raw agent name can break navigation when
formData.namecontains spaces or reserved URL characters (e.g.,/,?,#). UseencodeURIComponent(formData.name)when interpolating into the URL, or prefer navigating with an identifier returned bycreateAgentif available.
await agentApi.createAgent(formData);
showToast(`Agent "${formData.name}" imported successfully`, 'success');
navigate(`/settings/${formData.name}`);
webui/react-ui/src/pages/ImportAgent.jsx:67
- After going back to file selection, choosing the same file again may not fire
onChangebecause the hidden file input’s value hasn’t changed. Consider clearing the input value after processing a file and/or inhandleBack(typically via a ref), or force-remounting the input (e.g., with akey) so re-selecting the same file triggers parsing.
const handleBack = () => {
setShowForm(false);
setFormData({});
};
webui/react-ui/src/pages/ImportAgent.jsx:148
- After going back to file selection, choosing the same file again may not fire
onChangebecause the hidden file input’s value hasn’t changed. Consider clearing the input value after processing a file and/or inhandleBack(typically via a ref), or force-remounting the input (e.g., with akey) so re-selecting the same file triggers parsing.
<input
type="file"
id="fileInput"
accept=".json"
onChange={handleFileChange}
style={{ display: 'none' }}
/>
webui/react-ui/src/pages/ImportAgent.jsx:117
- The UI renders
AgentFormeven whenmetadatais stillnull(metadata is fetched asynchronously). IfAgentFormrelies on metadata being present, this can cause inconsistent rendering or runtime errors. Consider gating the form render until metadata is loaded (or providing a safe default shape + a loading state).
<AgentForm
formData={formData}
setFormData={setFormData}
onSubmit={handleSubmit}
loading={loading}
submitButtonText="Import Agent"
isEdit={false}
metadata={metadata}
/>
webui/app.go:602
- The validation is conditioned on
len(conv) > 0, soprevious_response_idwith no new messages will be allowed whenconvis empty (e.g., missing/invalid conversation lookup), potentially resulting in an empty message list being sent downstream. Consider rejecting any request withprevious_response_id != \"\"andlen(newMessages) == 0regardless ofconvlength (or explicitly validating thatmessagesis non-empty).
newMessages := request.ToChatCompletionMessages()
messages := append(conv, newMessages...)
// Continuing a thread (previous_response_id) without any new user/tool message causes
// the job to end with an assistant message, which backends with enable_thinking reject.
// Require at least one new message when continuing so we never send assistant-final conv.
if previousResponseID != "" && len(conv) > 0 && len(newMessages) == 0 {
return c.Status(http.StatusBadRequest).JSON(types.ResponseBody{
Error: "previous_response_id was set but no new input was sent; send at least one user or tool message when continuing a conversation",
})
}
core/agent/agent.go:931
- Appending a whitespace user message changes the conversation semantics (the model will respond to a blank user prompt) and can affect logs/analytics or downstream behavior. If the intent is strictly to avoid enable_thinking rejection, prefer a more explicit strategy (e.g., erroring when continuing without new input where possible, or using a clearly-defined sentinel message constant and documenting how it’s handled), rather than silently injecting a user message.
if len(conv) > 0 && conv[len(conv)-1].Role == AssistantRole {
conv = append(conv, openai.ChatCompletionMessage{
Role: UserRole,
Content: " ",
})
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.