pkg/chat/service.go + messages.go implement the RFC §15.1–§15.8 chat service with the full IPC surface: - gui.chat.send — streams assistant reply, returns message id - gui.chat.history — []Message for a conversation - gui.chat.models — []Model (name, size, status) - gui.chat.selectModel — sets active model - gui.chat.conversations.list/load/delete - gui.chat.thinking.start/stop — explicit thinking-state tracking MCP tool registrations in pkg/mcp/tools_chat.go mirror the IPC surface (chat_send, chat_history, chat_models, etc). WS bridge in pkg/display/display.go wires chat:conversations:load and chat🤔stop, keeping legacy chat:conversations:get and chat🤔end paths pointed at the new handlers for compat. Good/Bad/Ugly tests per action in service_test.go + godoc example in service_example_test.go. go vet + go test ./pkg/chat/... + ./pkg/... all clean. Closes tasks.lthn.sh/view.php?id=14 Co-authored-by: Codex <noreply@openai.com> Co-Authored-By: Virgil <virgil@lethean.io>
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package chat
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
core "dappco.re/go/core"
|
|
)
|
|
|
|
func ExampleRegister() {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
writeSSE(w,
|
|
`{"id":"chatcmpl-1","choices":[{"delta":{"content":"Hello from chat"}}]}`,
|
|
`{"id":"chatcmpl-1","choices":[{"finish_reason":"stop"}]}`,
|
|
`[DONE]`,
|
|
)
|
|
}))
|
|
defer server.Close()
|
|
|
|
storeDir, err := os.MkdirTemp("", "chat-example-*")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(storeDir)
|
|
|
|
c := core.New(
|
|
core.WithService(Register(
|
|
func(o *Options) { o.APIURL = server.URL },
|
|
func(o *Options) { o.StorePath = filepath.Join(storeDir, "chat.db") },
|
|
func(o *Options) { o.ToolExecutor = &mockToolExecutor{} },
|
|
func(o *Options) { o.Now = func() time.Time { return time.Unix(1_700_000_000, 0).UTC() } },
|
|
)),
|
|
core.WithServiceLock(),
|
|
)
|
|
if !c.ServiceStartup(context.Background(), nil).OK {
|
|
panic("chat startup failed")
|
|
}
|
|
|
|
send := c.Action("gui.chat.send").Run(context.Background(), core.NewOptions(
|
|
core.Option{Key: "content", Value: "Hello"},
|
|
))
|
|
if !send.OK {
|
|
panic(send.Value)
|
|
}
|
|
|
|
conversations := c.Action("gui.chat.conversations.list").Run(context.Background(), core.NewOptions())
|
|
history := c.Action("gui.chat.history").Run(context.Background(), core.NewOptions(
|
|
core.Option{Key: "conversation_id", Value: conversations.Value.([]Conversation)[0].ID},
|
|
))
|
|
|
|
fmt.Println(len(history.Value.([]Message)))
|
|
fmt.Println(history.Value.([]Message)[1].Content)
|
|
// Output:
|
|
// 2
|
|
// Hello from chat
|
|
}
|