mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-05 20:13:23 -05:00
fix(studio): cut sub-agent titles on a rune boundary
The title of a sub-agent chat was cut at a byte count and could end in the middle of a UTF-8 character. Use the rune-safe CapText. Also use the slices package for the tool lookup and the waiter removal. Assisted-by: Claude Code:claude-sonnet-5-5 Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
This commit is contained in:
2 files changed
+14
-12
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/mudler/LocalAI/core/services/studio/agents"
|
||||
@@ -540,11 +541,9 @@ func (s *Service) forgetWaiter(k string, ch <-chan store.TurnStatus) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
ws := s.waiters[k]
|
||||
for i, w := range ws {
|
||||
if (<-chan store.TurnStatus)(w) == ch {
|
||||
s.waiters[k] = append(ws[:i:i], ws[i+1:]...)
|
||||
break
|
||||
}
|
||||
if i := slices.IndexFunc(ws, func(w chan store.TurnStatus) bool { return (<-chan store.TurnStatus)(w) == ch }); i >= 0 {
|
||||
// A copy: notifyWaiters may hold the old slice.
|
||||
s.waiters[k] = slices.Delete(slices.Clone(ws), i, i+1)
|
||||
}
|
||||
if len(s.waiters[k]) == 0 {
|
||||
delete(s.waiters, k)
|
||||
@@ -643,15 +642,10 @@ func truncate(s string, n int) string {
|
||||
if len(s) <= n {
|
||||
return s
|
||||
}
|
||||
return s[:n] + "…"
|
||||
return session.CapText(s, n) + "…"
|
||||
}
|
||||
|
||||
// hasTool says whether the list has a tool of that name.
|
||||
func hasTool(tools []session.Tool, name string) bool {
|
||||
for _, t := range tools {
|
||||
if t.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return slices.ContainsFunc(tools, func(t session.Tool) bool { return t.Name == name })
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
@@ -17,6 +18,13 @@ import (
|
||||
// A long sub-agent run has more entries than one page; its answer is the last
|
||||
// assistant message, not the first page's.
|
||||
var _ = Describe("subagent internal", func() {
|
||||
It("cuts a title on a rune boundary", func() {
|
||||
got := truncate("héllo wörld", 2)
|
||||
Expect(utf8.ValidString(got)).To(BeTrue(), "the title %q is cut inside a rune", got)
|
||||
Expect(got).To(Equal("h…"))
|
||||
Expect(truncate(" a b ", 10)).To(Equal("a b"))
|
||||
})
|
||||
|
||||
It("final text of a long child is its last answer", func() {
|
||||
st, err := store.NewJSON("")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Reference in new issue
Block a user