feat: ByteClaw 0.2.0 – Provider-Wahl ab erster Nachricht, Markdown/Code-Blöcke mit Kopieren, Nachrichten-Aktionen, Spracheingabe, Session-Suche/Umbenennen, Verbindungsstatus, Benachrichtigungen

This commit is contained in:
OpenClaw Dev 2026-10-26 13:46:00 +01:00
parent 52b6b68117
commit ec797335a6
26 changed files with 560 additions and 30 deletions

View file

@ -178,3 +178,45 @@ func TestManualSummarize(t *testing.T) {
t.Fatal(r.StatusCode)
}
}
func TestWebSocketFirstMessageUsesSessionProvider(t *testing.T) {
ts, st := setupFull(t, echo{})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
c, _, err := websocket.Dial(ctx, "ws"+strings.TrimPrefix(ts.URL, "http")+"/api/ws", &websocket.DialOptions{HTTPHeader: map[string][]string{"Authorization": {"Bearer " + tok}}})
if err != nil {
t.Fatal(err)
}
defer c.CloseNow()
wsjson.Write(ctx, c, chatReq{Type: "message", Text: "hi", Provider: "dahl", Model: "zai-org/GLM-5.3-Flash"})
var sid string
for {
var e agent.Event
if err := wsjson.Read(ctx, c, &e); err != nil {
t.Fatal(err)
}
if e.Type == "session" {
sid = e.Session
got, _ := st.GetSession(ctx, sid)
if got.Provider != "dahl" || got.Model != "zai-org/GLM-5.3-Flash" {
t.Fatalf("provider not set before first run: %+v", got)
}
}
if e.Type == "done" {
break
}
if e.Type == "error" {
t.Fatalf("%+v", e)
}
}
// unconfigured provider is rejected without creating a session
wsjson.Write(ctx, c, chatReq{Type: "message", Text: "x", Provider: "openrouter"})
var e agent.Event
if err := wsjson.Read(ctx, c, &e); err != nil || e.Type != "error" || !strings.HasPrefix(e.Text, "provider:") {
t.Fatalf("%+v %v", e, err)
}
list, _ := st.ListSessions(ctx, 10)
if len(list) != 1 {
t.Fatalf("expected 1 session, got %d", len(list))
}
}