mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-06 04:23:15 -05:00
The draft tools and add-on lists, and the tools list of a stored chat, read the execution status without an execution scope. The host logged an error and reported the status as not selected. They now run in a scope; a draft has no conversation, so its status says "draft". In the Home composer, switching a built-in tool group on or off reset the commands state to the loading value and never read it again. The composer then showed the unknown warning for good. The Hide button also did nothing for that state, because it needed a binding identity that the loading value does not have. A draft now keeps the state the list gave it, and Hide works for any notice that is shown. Assisted-by: Claude:claude-sonnet-5-5 go ginkgo node
69 lines
2.4 KiB
Go
69 lines
2.4 KiB
Go
package studio
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/mudler/LocalAI/core/services/studio/session"
|
|
)
|
|
|
|
// The composer of a new chat shows the Tools and Skills menus before the chat
|
|
// exists. It lists what a chat on the chosen model (and saved agent) could
|
|
// switch, keeps the person's choices as a draft and sends them with the
|
|
// create request (CreateInput.Switches), so the chat is stored with them.
|
|
|
|
// DraftTools lists what a new chat on model, with the saved agent agentID when
|
|
// it is set, could use, every switch in its default state. The agent's model,
|
|
// when it has one, replaces model, as Create does.
|
|
func (s *Service) DraftTools(ctx context.Context, user, model, agentID string) (ToolsPanel, error) {
|
|
rec, err := s.draftRecord(ctx, user, model, agentID)
|
|
if err != nil {
|
|
return ToolsPanel{}, err
|
|
}
|
|
// The add-on gate reads the execution status. A draft has no chat, so the
|
|
// scope has no conversation and the status says "draft".
|
|
ctx, closeScope := s.executionScope(ctx, principal(user), rec.ID)
|
|
defer closeScope()
|
|
return s.toolsFor(ctx, user, rec)
|
|
}
|
|
|
|
// DraftAddons lists the add-ons of a new chat as DraftTools does, and whether
|
|
// it could run commands at its first turn.
|
|
func (s *Service) DraftAddons(ctx context.Context, user, model, agentID string) ([]AddonInfo, Commands, error) {
|
|
rec, err := s.draftRecord(ctx, user, model, agentID)
|
|
if err != nil {
|
|
return nil, Commands{}, err
|
|
}
|
|
ctx, closeScope := s.executionScope(ctx, principal(user), rec.ID)
|
|
defer closeScope()
|
|
list, err := s.addonsFor(ctx, user, rec)
|
|
if err != nil {
|
|
return nil, Commands{}, err
|
|
}
|
|
commands, err := s.commandsFor(ctx, principal(user), rec)
|
|
if err != nil {
|
|
return nil, Commands{}, err
|
|
}
|
|
return list, commands, nil
|
|
}
|
|
|
|
// draftRecord is the record a new chat would have, with no ID and no switch.
|
|
func (s *Service) draftRecord(ctx context.Context, user, model, agentID string) (session.ChatRecord, error) {
|
|
rec := session.ChatRecord{Principal: principal(user), Kind: session.KindChat, Model: model, AgentID: agentID}
|
|
if agentID == "" {
|
|
return rec, nil
|
|
}
|
|
if s.d.Agents == nil {
|
|
return rec, ErrAgentsOff
|
|
}
|
|
ag, err := s.d.Agents.Get(ctx, principal(user), agentID)
|
|
if err != nil {
|
|
return rec, err
|
|
}
|
|
if ag.Model != "" {
|
|
rec.Model = ag.Model
|
|
}
|
|
// The opt-in groups the agent starts with are on in the draft.
|
|
rec.BuiltinsOn = mergeGroups(rec.BuiltinsOn, ag.BuiltinsOn)
|
|
return rec, nil
|
|
}
|