# How delete_session_chat and update_session_chat Implement Chat Manipulation in Coco App

> Learn how delete_session_chat and update_session_chat manipulate chat sessions in Coco App. Explore the TypeScript, Rust, and React architecture for server communication and data management.

- Repository: [INFINI Labs/coco-app](https://github.com/infinilabs/coco-app)
- Tags: internals
- Published: 2026-03-04

---

**The `delete_session_chat` and `update_session_chat` functions form a three-layered architecture—TypeScript wrappers, Rust Tauri commands, and React hooks—that perform HTTP DELETE and PUT operations against the Coco server REST API to remove or rename chat sessions.**

These commands are central to chat session management in the infinilabs/coco-app repository, a Tauri-based desktop application. They bridge the React frontend and the Coco AI server through a type-safe command pattern that handles authentication, error propagation, and state synchronization.

## Frontend TypeScript Wrappers ([`src/commands/servers.ts`](https://github.com/infinilabs/coco-app/blob/main/src/commands/servers.ts))

The UI interacts with the underlying Rust backend through thin TypeScript wrappers located in [`src/commands/servers.ts`](https://github.com/infinilabs/coco-app/blob/main/src/commands/servers.ts). These functions provide a typed, Promise-based API that delegates to `invokeWithErrorHandler`, which ensures the user is authenticated before calling the Tauri core invoke method.

**Deleting a session** requires the server ID and session ID:

```typescript
export const delete_session_chat = (serverId: string, sessionId: string) => {
  return invokeWithErrorHandler<boolean>(`delete_session_chat`, {
    serverId,
    sessionId,
  });
};

```

**Updating a session** accepts an optional title and context object:

```typescript
export const update_session_chat = (payload: {
  serverId: string;
  sessionId: string;
  title?: string;
  context?: Record<string, any>;
}): Promise<boolean> => {
  return invokeWithErrorHandler<boolean>("update_session_chat", payload);
};

```

Both functions return a boolean promise indicating success or failure, with errors logged and propagated through `invokeWithErrorHandler`.

## Rust Tauri Commands ([`src-tauri/src/assistant/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/assistant/mod.rs))

The actual network operations are implemented in Rust within [`src-tauri/src/assistant/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/assistant/mod.rs). These commands construct HTTP requests to the Coco server's REST API endpoints.

### Deleting Sessions with delete_session_chat

The `delete_session_chat` command issues an HTTP DELETE request to `/chat/{session_id}`:

```rust
#[tauri::command]
pub async fn delete_session_chat(
    server_id: String,
    session_id: String,
) -> Result<bool, HttpRequestError> {
    let response = HttpClient::delete(&server_id,
        &format!("/chat/{}", session_id), None, None).await?;

    let status = response.status();
    if status.is_success() {
        Ok(true)
    } else {
        Err(HttpRequestError::RequestFailed {
            status: status.as_u16(),
            error_response_body_str: None,
            coco_server_api_error_response_body: None,
        })
    }
}

```

This function uses the internal `HttpClient` to execute the deletion. It returns `true` only when the server responds with a 2xx status code; otherwise, it returns a structured `HttpRequestError`.

### Updating Sessions with update_session_chat

The `update_session_chat` command constructs a JSON body and sends an HTTP PUT request to the same endpoint:

```rust
#[tauri::command]
pub async fn update_session_chat(
    server_id: String,
    session_id: String,
    title: Option<String>,
    context: Option<HashMap<String, Value>>,
) -> Result<bool, HttpRequestError> {
    let mut body = HashMap::new();
    if let Some(title) = title {
        body.insert("title".to_string(), Value::String(title));
    }
    if let Some(context) = context {
        body.insert(
            "context".to_string(),
            Value::Object(context.into_iter().collect()),
        );
    }

    let response = HttpClient::put(
        &server_id,
        &format!("/chat/{}", session_id),
        None,
        None,
        Some(reqwest::Body::from(serde_json::to_string(&body).unwrap())),
    )
    .await?;

    Ok(response.status().is_success())
}

```

The command assembles the request body from optional title and context parameters before serializing them to JSON. The result indicates whether the server accepted the modification.

## React Hook Integration ([`src/hooks/useChatPanel.ts`](https://github.com/infinilabs/coco-app/blob/main/src/hooks/useChatPanel.ts))

The application consumes these commands through React hooks defined in [`src/hooks/useChatPanel.ts`](https://github.com/infinilabs/coco-app/blob/main/src/hooks/useChatPanel.ts), which synchronize local component state with the remote server.

**Deleting a chat** filters the local state after confirming server deletion:

```typescript
const deleteChat = useCallback(
  async (chatId: string) => {
    if (!currentService?.id) return;

    await platformAdapter.commands(
      "delete_session_chat",
      currentService.id,
      chatId
    );

    // Remove the chat from local state
    setChats(prev => prev.filter(chat => chat._id !== chatId));
    if (activeChat?._id === chatId) {
      const remaining = chats.filter(chat => chat._id !== chatId);
      setActiveChat(remaining[0]);
    }
  },
  [currentService?.id, activeChat?._id, chats]
);

```

**Renaming a chat** invokes the update command with minimal payload:

```typescript
platformAdapter.commands("update_session_chat", {
  serverId: currentService.id,
  sessionId: chatId,
  title,
});

```

The `platformAdapter.commands` method serves as the generic bridge that forwards these calls through the Tauri runtime to the Rust implementations.

## Summary

- **Frontend wrappers** in [`src/commands/servers.ts`](https://github.com/infinilabs/coco-app/blob/main/src/commands/servers.ts) provide type-safe TypeScript interfaces that validate parameters before invoking Tauri.
- **Rust commands** in [`src-tauri/src/assistant/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/assistant/mod.rs) execute HTTP DELETE and PUT requests against `/chat/{session_id}` using the internal `HttpClient`.
- **React hooks** in [`src/hooks/useChatPanel.ts`](https://github.com/infinilabs/coco-app/blob/main/src/hooks/useChatPanel.ts) orchestrate the commands and maintain UI state consistency, automatically selecting fallback sessions when the active chat is deleted.
- The architecture separates concerns across three layers—UI, bridge, and backend—enabling secure, authenticated chat manipulation backed by the Coco server REST API.

## Frequently Asked Questions

### What HTTP methods do delete_session_chat and update_session_chat use?

According to the source code in [`src-tauri/src/assistant/mod.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/assistant/mod.rs), `delete_session_chat` sends an HTTP DELETE request, while `update_session_chat` sends an HTTP PUT request. Both target the `/chat/{session_id}` endpoint on the Coco server.

### How does error handling work for these chat commands?

Both commands rely on `invokeWithErrorHandler` in the TypeScript layer to verify authentication before calling Tauri. The Rust layer returns `HttpRequestError` when the server responds with non-success status codes, which propagates back to the React hooks for UI display.

### Can update_session_chat modify both the title and context simultaneously?

Yes. The Rust implementation accepts both `title: Option<String>` and `context: Option<HashMap<String, Value>>` parameters, constructing a JSON body that includes whichever fields are provided. The HTTP PUT request transmits both values in a single operation.

### Where is the Coco server API endpoint defined?

The endpoint path `/chat/{}` is constructed inline within the Rust commands using `format!("/chat/{}", session_id)`. The `HttpClient` module handles the base URL resolution based on the provided `server_id` parameter.