feat: agent concurrency, conversation summaries, AI tools config, UI polish
Some checks failed
Stable Release / stable (push) Failing after 33s
Some checks failed
Stable Release / stable (push) Failing after 33s
- Agent slot limiter for concurrent tool execution - Conversation summarization with soft-delete (MarkSummarized) - ANSI stripping in terminal tool output - Configurable crush-run timeout (default 600s, max 900s) - Starship theme refactor, AI tools config grid, system update UI - Streaming segments refactor, summarized messages block in feed - CSS: headings, scrollbars, tool cards, summary block styles - i18n additions (en+fr) for tools, updates, config 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
This commit is contained in:
@@ -2,12 +2,15 @@ package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/muyue/muyue/internal/agent"
|
||||
"github.com/muyue/muyue/internal/config"
|
||||
"github.com/muyue/muyue/internal/installer"
|
||||
"github.com/muyue/muyue/internal/scanner"
|
||||
"github.com/muyue/muyue/internal/workflow"
|
||||
)
|
||||
@@ -24,6 +27,8 @@ type Server struct {
|
||||
shellAgentRegistry *agent.Registry
|
||||
shellAgentToolsJSON json.RawMessage
|
||||
workflowEngine *workflow.Engine
|
||||
activeCrushAgents atomic.Int32
|
||||
activeClaudeAgents atomic.Int32
|
||||
}
|
||||
|
||||
func NewServer(cfg *config.MuyueConfig) *Server {
|
||||
@@ -43,7 +48,7 @@ func NewServer(cfg *config.MuyueConfig) *Server {
|
||||
}
|
||||
// Save initial config to establish the file for first-time usage
|
||||
if err := config.Save(defaultCfg); err != nil {
|
||||
log.Printf("config: initial save failed: %v", err)
|
||||
_ = err
|
||||
}
|
||||
cfg = defaultCfg
|
||||
}
|
||||
@@ -65,6 +70,7 @@ func NewServer(cfg *config.MuyueConfig) *Server {
|
||||
s.shellAgentToolsJSON = json.RawMessage(shellToolsJSON)
|
||||
|
||||
s.workflowEngine, _ = workflow.NewEngine(s.agentRegistry)
|
||||
s.initStarship()
|
||||
s.routes()
|
||||
return s
|
||||
}
|
||||
@@ -120,6 +126,7 @@ func (s *Server) routes() {
|
||||
s.mux.HandleFunc("/api/conversations/", s.handleDeleteConversation)
|
||||
s.mux.HandleFunc("/api/lsp/install", s.handleLSPInstall)
|
||||
s.mux.HandleFunc("/api/skills/deploy", s.handleSkillsDeploy)
|
||||
s.mux.HandleFunc("/api/skills/undeploy", s.handleSkillsUndeploy)
|
||||
s.mux.HandleFunc("/api/ssh/connections", s.handleSSHConnections)
|
||||
s.mux.HandleFunc("/api/ssh/test", s.handleSSHTest)
|
||||
|
||||
@@ -156,3 +163,37 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
s.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
const maxCrushAgents = 2
|
||||
const maxClaudeAgents = 2
|
||||
|
||||
func (s *Server) AcquireAgentSlot(toolName string) (release func(), err error) {
|
||||
var counter *atomic.Int32
|
||||
var max int32
|
||||
switch toolName {
|
||||
case "crush_run":
|
||||
counter = &s.activeCrushAgents
|
||||
max = maxCrushAgents
|
||||
case "claude_run":
|
||||
counter = &s.activeClaudeAgents
|
||||
max = maxClaudeAgents
|
||||
default:
|
||||
return func() {}, nil
|
||||
}
|
||||
current := counter.Add(1)
|
||||
if current > max {
|
||||
counter.Add(-1)
|
||||
return nil, fmt.Errorf("Limite de %d agents %s atteinte", max, toolName)
|
||||
}
|
||||
return func() { counter.Add(-1) }, nil
|
||||
}
|
||||
|
||||
func (s *Server) initStarship() {
|
||||
if _, err := exec.LookPath("starship"); err != nil {
|
||||
inst := installer.New(s.config)
|
||||
if result := inst.InstallTool("starship"); !result.Success {
|
||||
return
|
||||
}
|
||||
}
|
||||
ApplyStarshipTheme(s.config.Terminal.PromptTheme)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user