Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- Fix `/resume` broken for OpenAI chats: handle nil reasoning text during replay, preserve prompt-id after chat replacement, and clear UI before replaying messages. #400

- Add `chat/update` notification for renaming chats. Chat titles are now persisted to the database and broadcast to all connected clients including remote web interface.

## 0.124.2

- Fix OpenAI Responses API tool calls not executing when streaming response returns empty output, and fix spurious retries caused by stale tool-call state with Copilot encrypted IDs. #398
Expand Down
30 changes: 30 additions & 0 deletions docs/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -1707,6 +1707,36 @@ _Response:_
interface ChatDeleteResponse {}
```

### Chat update (↩️)

A client request to update chat metadata like title.
Server will persist the change, broadcast to all connected clients via `chat/contentReceived` with metadata content, and return an empty response.

_Request:_

* method: `chat/update`
* params: `ChatUpdateParams` defined as follows:

```typescript
interface ChatUpdateParams {
/**
* The chat session identifier.
*/
chatId: string;

/**
* New title for the chat.
*/
title?: string;
}
```

_Response:_

```typescript
interface ChatUpdateResponse {}
```

### Chat selected agent changed (➡️)

A client notification for server telling the user selected a different agent in chat.
Expand Down
14 changes: 14 additions & 0 deletions src/eca/features/chat.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,20 @@
(messenger/chat-cleared messenger {:chat-id chat-id :messages messages})
(db/update-workspaces-cache! @db* metrics)))

(defn update-chat
"Update chat metadata like title.
Broadcasts the change to all connected clients."
[{:keys [chat-id title]} db* messenger metrics]
(when (and (get-in @db* [:chats chat-id])
title)
(swap! db* assoc-in [:chats chat-id :title] title)
(messenger/chat-content-received messenger
{:chat-id chat-id
:role "system"
:content {:type :metadata :title title}})
(db/update-workspaces-cache! @db* metrics))
{})

(defn rollback-chat
"Remove messages from chat in db until content-id matches.
Then notify to clear chat and then the kept messages."
Expand Down
4 changes: 4 additions & 0 deletions src/eca/handlers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@
(metrics/task metrics :eca/chat-fork
(f.chat/fork-chat params db* messenger metrics)))

(defn chat-update [{:keys [db* messenger metrics]} params]
(metrics/task metrics :eca/chat-update
(f.chat/update-chat params db* messenger metrics)))

(defn mcp-stop-server [{:keys [db* messenger metrics config]} params]
(metrics/task metrics :eca/mcp-stop-server
(f.tools/stop-server! (:name params) db* messenger config metrics)))
Expand Down
10 changes: 10 additions & 0 deletions src/eca/remote/handlers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@
:variant (:variant body)})
(no-content))))))

(defn handle-update-chat [{:keys [db*] :as components} request chat-id]
(if-not (chat-or-404 db* chat-id)
(error-response 404 "chat_not_found" (str "Chat " chat-id " does not exist"))
(let [body (parse-body request)
config (config/all @db*)]
(handlers/chat-update
(assoc components :config config)
{:chat-id chat-id :title (:title body)})
(no-content))))

(defn handle-set-trust [{:keys [db*]} request {:keys [sse-connections*]}]
(let [body (parse-body request)
trust (boolean (:trust body))]
Expand Down
1 change: 1 addition & 0 deletions src/eca/remote/routes.clj
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"model" [handlers/handle-change-model components request chat-id]
"agent" [handlers/handle-change-agent components request chat-id]
"variant" [handlers/handle-change-variant components request chat-id]
"update" [handlers/handle-update-chat components request chat-id]
nil)))
6 (let [action (nth segments 4)
tcid (nth segments 5)]
Expand Down
3 changes: 3 additions & 0 deletions src/eca/server.clj
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@
(defmethod jsonrpc.server/receive-request "chat/fork" [_ components params]
(eventually (handlers/chat-fork (with-config components) params)))

(defmethod jsonrpc.server/receive-request "chat/update" [_ components params]
(eventually (handlers/chat-update (with-config components) params)))

(defmethod jsonrpc.server/receive-notification "mcp/stopServer" [_ components params]
(async-notify (handlers/mcp-stop-server (with-config components) params)))

Expand Down
Loading