Skip to content

feat(webchat): add new chat session button#52042

Closed
bobashopcashier wants to merge 28 commits intoopenclaw:mainfrom
bobashopcashier:feat/webchat-new-chat-session
Closed

feat(webchat): add new chat session button#52042
bobashopcashier wants to merge 28 commits intoopenclaw:mainfrom
bobashopcashier:feat/webchat-new-chat-session

Conversation

@bobashopcashier
Copy link
Copy Markdown
Contributor

@bobashopcashier bobashopcashier commented Mar 22, 2026

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: webchat exposed session switching but not session creation from the selector, so users had to reuse one dashboard session or rely on /new, which only resets the current one.
  • Why it matters: separate webchat sessions let users keep unrelated drafts and histories split by topic or project instead of collapsing everything into one timeline.
  • What changed: added a + affordance beside the session selector that creates a new optional labeled dashboard session and auto-switches only when the originating session and composer state are still safe to move.
  • Hardening: guarded duplicate create attempts, stale history responses, delayed create responses, and contended session-list refreshes; when switching would be unsafe, the UI preserves existing drafts, queued prompts, and attachments instead of yanking the user into a different chat.
  • Scope boundary: this is the session-creation and state-safety slice of the broader multi-chat request in [Feature]: Multi-chat / tabbed sessions in webchat UI #51793, not full tabbed/sidebar multi-session management. Rename/delete flows, backend storage/tool APIs, and broader session-management semantics are still unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • Webchat now shows a + button beside the chat session selector.
  • Clicking + prompts for an optional label and creates a fresh dashboard session.
  • The UI switches into that new session only when the originating session is still active and the composer state is still safe to clear; otherwise it refreshes session options and keeps the user in place.
  • Existing drafts, queued prompts, or attachments are preserved when an auto-switch would be unsafe, and stale or malformed create responses no longer force an unexpected session jump.
  • This does not add tabbed/sidebar multi-session navigation yet; rename/delete flows for existing sessions are still follow-up work.

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: Darwin
  • Runtime/container: Node v25.8.1, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): webchat dashboard UI
  • Relevant config (redacted): default local dev and test config

Steps

  1. Run targeted webchat coverage: pnpm test -- ui/src/ui/controllers/chat.test.ts, pnpm test -- ui/src/ui/controllers/sessions.test.ts, and pnpm test -- ui/src/ui/views/chat.test.ts.
  2. Run supporting regression/build coverage for the maintenance alignments merged into this branch: pnpm build, plus the targeted Telegram/gateway/infra/helper expectation-alignment checks touched after merging main.
  3. Manually exercise the webchat create-session flow in the browser.

Expected

  • New session creation keeps the active-session spinner and session list state consistent under delayed, malformed, or contended responses.
  • Delayed create responses do not overwrite drafts, queued prompts, or attachments typed before or after the request started.
  • Existing drafts or attachments present before pressing + are preserved by staying in the current session when switching would be unsafe.
  • Supporting maintenance edits remain limited to keeping test/build expectations aligned after the main merge and do not expand the user-visible feature scope.

Actual

  • Targeted automated verification for the webchat flow and the supporting expectation-alignment regressions passed locally.
  • Manual browser verification of the webchat create-session flow also passed.
  • Rename/delete flows for existing sessions, tabbed/sidebar multi-chat navigation, and any broader backend session-management changes remain out of scope for this PR.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: manual browser verification of the webchat create-session flow, plus targeted automated verification for stale chat.history responses, successful session creation, missing-key create responses, thrown sessions.create errors, delayed create responses after a user session switch, delayed create responses after draft or attachment edits, delayed create responses with queued prompts already present, and refresh retries while sessions.list is already in flight.
  • Edge cases checked: loading indicator is not cleared by a stale history response; delayed create responses do not force navigation into a newer session; existing drafts, queued prompts, and attachments are preserved instead of triggering an unsafe auto-switch; attachments are cleared before a safe auto-switch into the new session.
  • What you did not verify: rename/delete flows for existing sessions, prompt UX in embedded or cross-origin environments, or any broader backend session-management behavior outside the existing UI affordance.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert the webchat session-creation UI changes and fall back to the previous session selector behavior.
  • Files/config to restore: ui/src/ui/app-render.helpers.ts, ui/src/ui/controllers/chat.ts, and the related webchat tests.
  • Known bad symptoms reviewers should watch for: session spinner disappearing too early, newly created sessions not appearing in the selector until a later refresh, unexpected session switches after a delayed create response, or preserved drafts/queue/attachments being cleared when they should stay put.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: delayed, malformed, or partially failed sessions.create responses could still leave the UI briefly out of sync with backend session state.
    • Mitigation: guarded success/error handling, defensive session-option refreshes, and targeted regression coverage for missing-key and thrown-error paths.
  • Risk: stale history or contended session-list refreshes can produce timing-sensitive UI state bugs.
    • Mitigation: sequence-based stale-response guards, queued refresh preservation, and explicit regression tests around those races.
  • Risk: this PR covers only session creation plus related UI-state hardening; rename/delete flows, tabbed/sidebar multi-chat UX, and broader backend session-management semantics remain separate follow-up work.
  • Risk: the small non-webchat file edits in this branch could be mistaken for expanded product scope.
    • Mitigation: they are limited to maintenance/test expectation alignment after the main merge and are not treated as separate user-facing behavior in this PR.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 22, 2026

Greptile Summary

This PR adds a + button beside the webchat session selector that lets users create new labeled dashboard sessions without disrupting existing conversations. The implementation is thorough: it guards against concurrent invocations, stale auto-switches after delayed RPC responses, and draft/attachment preservation. Two companion hardening changes are included — a sequence-number staleness guard for loadChatHistory and a single-slot queued-reload mechanism for loadSessions — both of which have dedicated regression tests. Previous review concerns (reactive disabled state, try/finally cleanup, success/error/throw path tests) are all addressed.

Key observations:

  • Missing refreshSessionOptions in catch block (app-render.helpers.ts): the missing-key error path correctly calls refreshSessionOptions, but the thrown-error path does not. A session silently committed by the server before a network error would be invisible until something else triggers a list refresh.
  • Out-of-scope config change (src/config/types.models.ts, src/config/zod-schema.core.ts): "openrouter" is added as a valid thinkingFormat value, which is unrelated to the webchat UI feature and not mentioned in the PR description. This should get explicit sign-off from config/model owners and ideally land in a separate PR.
  • Redundant tracking field (controllers/chat.ts): __chatHistoryRequestSeq and __chatHistoryActiveRequestSeq are always set to the same value — one can be removed without changing behavior.
  • Test coverage is comprehensive: 13+ new test cases covering the happy path, both error paths, all guarded auto-switch conditions, the stale-history race, and the in-flight session-list retry.

Confidence Score: 4/5

  • PR is on the happy path to merge; one minor gap in error-path refresh and an out-of-scope config change warrant targeted follow-up before landing.
  • All previously raised P1/P0 concerns have been addressed (reactive disabled state, try/finally guard, success/error/throw test paths). Remaining issues are P2: the catch block should call refreshSessionOptions for consistency, and the out-of-scope openrouter thinkingFormat addition needs config-owner sign-off. Test coverage is comprehensive. Score reflects strong convergence with two small targeted fixes remaining.
  • src/config/types.models.ts and src/config/zod-schema.core.ts (out-of-scope openrouter config change); ui/src/ui/app-render.helpers.ts catch block (missing refreshSessionOptions call).

Comments Outside Diff (3)

  1. ui/src/ui/app-render.helpers.ts, line 334-336 (link)

    refreshSessionOptions not called on thrown error

    When sessions.create rejects (network error, server error, etc.), the catch block only sets state.lastError and exits. If the server actually processed the request before the connection dropped (e.g., a TCP timeout after the server committed the session), the new session will exist on the backend but remain invisible in the dropdown until something else triggers a session list refresh.

    The missing-key path one level up explicitly calls void refreshSessionOptions(state) for exactly this consistency reason — the same defensive refresh would be valuable in the catch branch too:

  2. src/config/types.models.ts, line 90-91 (link)

    Out-of-scope config change — needs separate review

    Adding "openrouter" as a valid SupportedThinkingFormat value (and the matching z.literal("openrouter") in zod-schema.core.ts) is unrelated to the webchat session creation feature described in this PR. The PR description explicitly scopes changes to "UI / DX" and states that "no new model-inheritance policy for created sessions" was changed — but this touches the model config/Zod schema layer shared across the whole system.

    If "openrouter" is handled in the code that dispatches thinkingFormat (e.g., a switch statement somewhere), the missing handler would silently fall through. It would be cleaner to land this in a separate, targeted PR where the config and model-inference owners can review it directly, or at minimum call it out in the PR description so it gets sign-off from the right reviewers.

    This also appears in src/config/zod-schema.core.ts at the corresponding union definition.

  3. ui/src/ui/controllers/chat.ts, line 455-459 (link)

    Two tracking fields are always in sync — one is redundant

    __chatHistoryRequestSeq and __chatHistoryActiveRequestSeq are set to the same value at the start of every loadChatHistory call, and there is no code path that writes them independently. Every check of __chatHistoryActiveRequestSeq could equivalently read __chatHistoryRequestSeq, making one of the two fields dead weight.

    A cleaner approach is to keep only __chatHistoryRequestSeq as the monotonic counter and compare against it in the staleness check:

    // Before request:
    const requestSeq = (trackedState.__chatHistoryRequestSeq ?? 0) + 1;
    trackedState.__chatHistoryRequestSeq = requestSeq;
    
    // After await:
    if (trackedState.__chatHistoryRequestSeq !== requestSeq || ...) return;

    This is a style/clarity issue — the current code is not incorrect.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix All With AI
This is a comment left during a code review.
Path: ui/src/ui/app-render.helpers.ts
Line: 334-336

Comment:
**`refreshSessionOptions` not called on thrown error**

When `sessions.create` rejects (network error, server error, etc.), the `catch` block only sets `state.lastError` and exits. If the server actually processed the request before the connection dropped (e.g., a TCP timeout after the server committed the session), the new session will exist on the backend but remain invisible in the dropdown until something else triggers a session list refresh.

The missing-key path one level up explicitly calls `void refreshSessionOptions(state)` for exactly this consistency reason — the same defensive refresh would be valuable in the `catch` branch too:

```suggestion
  } catch (err) {
    state.lastError = String(err);
    void refreshSessionOptions(state);
  } finally {
    state.newChatSessionPending = false;
  }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/config/types.models.ts
Line: 90-91

Comment:
**Out-of-scope config change — needs separate review**

Adding `"openrouter"` as a valid `SupportedThinkingFormat` value (and the matching `z.literal("openrouter")` in `zod-schema.core.ts`) is unrelated to the webchat session creation feature described in this PR. The PR description explicitly scopes changes to "UI / DX" and states that "no new model-inheritance policy for created sessions" was changed — but this touches the model config/Zod schema layer shared across the whole system.

If `"openrouter"` is handled in the code that dispatches `thinkingFormat` (e.g., a `switch` statement somewhere), the missing handler would silently fall through. It would be cleaner to land this in a separate, targeted PR where the config and model-inference owners can review it directly, or at minimum call it out in the PR description so it gets sign-off from the right reviewers.

This also appears in `src/config/zod-schema.core.ts` at the corresponding union definition.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ui/src/ui/controllers/chat.ts
Line: 455-459

Comment:
**Two tracking fields are always in sync — one is redundant**

`__chatHistoryRequestSeq` and `__chatHistoryActiveRequestSeq` are set to the same value at the start of every `loadChatHistory` call, and there is no code path that writes them independently. Every check of `__chatHistoryActiveRequestSeq` could equivalently read `__chatHistoryRequestSeq`, making one of the two fields dead weight.

A cleaner approach is to keep only `__chatHistoryRequestSeq` as the monotonic counter and compare against it in the staleness check:

```ts
// Before request:
const requestSeq = (trackedState.__chatHistoryRequestSeq ?? 0) + 1;
trackedState.__chatHistoryRequestSeq = requestSeq;

// After await:
if (trackedState.__chatHistoryRequestSeq !== requestSeq || ...) return;
```

This is a style/clarity issue — the current code is not incorrect.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (9): Last reviewed commit: "Merge branch 'main' into feat/webchat-ne..." | Re-trigger Greptile

Comment thread ui/src/ui/app-render.helpers.ts Outdated
Comment thread ui/src/ui/app-render.helpers.ts Outdated
Comment thread ui/src/ui/app-render.helpers.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7c255e997

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a96c8938d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts Outdated
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Comment thread ui/src/ui/app-render.helpers.ts
Comment thread ui/src/ui/app-render.helpers.ts Outdated
@bobashopcashier bobashopcashier force-pushed the feat/webchat-new-chat-session branch from 6b6337d to fee4c6f Compare March 22, 2026 03:53
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread ui/src/ui/app-render.helpers.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e022dac2c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts Outdated
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b09094f4db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts Outdated
Comment thread ui/src/ui/app-render.helpers.ts
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread ui/src/ui/views/chat.test.ts
Comment thread ui/src/ui/views/chat.test.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f6cdb38b9f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts Outdated
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d9034f233

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts Outdated
Comment thread ui/src/ui/app-render.helpers.ts Outdated
Comment thread ui/src/ui/views/chat.test.ts
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread ui/src/ui/views/chat.test.ts
Comment thread .github/workflows/ci.yml
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

@greptile review

@bobashopcashier bobashopcashier force-pushed the feat/webchat-new-chat-session branch from 9d65eca to 73a067f Compare March 22, 2026 23:59
@openclaw-barnacle openclaw-barnacle Bot removed the channel: discord Channel integration: discord label Mar 23, 2026
@bobashopcashier
Copy link
Copy Markdown
Contributor Author

bobashopcashier commented Mar 23, 2026

@BunsDev Hey tysm for looking at this PR! Can you look over it again. I have fixed the things addressed.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 73a067fb6b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.helpers.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62a04f3861

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/src/ui/app-render.ts
Comment on lines +1440 to +1442
canCreateSession:
state.connected && !state.chatRunId && !state.newChatSessionPending,
onCreateSession: () => void createNewChatSession(state),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Hide new-session action during onboarding

When state.onboarding is true, ui/src/ui/app-render.ts:306 forces chat focus mode and the normal header controls are hidden, so these props are what make the floating + action appear on the onboarding chat. Other chat controls are explicitly locked down in onboarding (ui/src/ui/app-render.helpers.ts:231-360), but this still allows createNewChatSession(), which can switch the user into a blank dashboard session mid-onboarding and pull them away from the guided conversation they were supposed to continue.

Useful? React with 👍 / 👎.

@bobashopcashier
Copy link
Copy Markdown
Contributor Author

image Here is what it looks like. It still needs renaming/deleting capabilities in future PRs.

@vincentkoc
Copy link
Copy Markdown
Member

Closing due to high volume of changes and breaking changes upstream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui channel: telegram Channel integration: telegram cli CLI command changes docs Improvements or additions to documentation scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple Labeled Sessions in Webchat

3 participants