Skip to content

💬 feat: Conversation Starters for Model Specs#13710

Merged
danny-avila merged 2 commits into
danny-avila:devfrom
mharveybu:feat/modelspec-conversation-starters
Jun 13, 2026
Merged

💬 feat: Conversation Starters for Model Specs#13710
danny-avila merged 2 commits into
danny-avila:devfrom
mharveybu:feat/modelspec-conversation-starters

Conversation

@mharveybu

@mharveybu mharveybu commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Model specs defined in librechat.yaml currently have no way to offer conversation starters — only database agents/assistants do. Deployments that present curated specs as "agents" (preset + instructions + MCP servers) can't surface suggested prompts on the landing page; the closest workaround is HTML links in the spec description (via #13662), which open in a new tab and clutter the model selector.

This PR adds an optional conversation_starters field to model specs. When the active conversation uses a spec that defines starters, the chat landing renders clickable starter cards between the landing content and the chat input, and clicking one submits it as the first message — mirroring agent/assistant starters.

modelSpecs:
  list:
    - name: 'library-search'
      label: 'Library Search'
      conversation_starters:
        - 'Find books about machine learning'
        - 'Help me track down a citation'
      preset:
        endpoint: 'anthropic'
        model: 'claude-haiku-4-5'

Changes:

  • packages/data-provider/src/models.ts: add conversation_starters?: string[] to TModelSpec and tModelSpecSchema (required so the field survives configSchema.strict() parsing in loadCustomConfig).
  • client/src/components/Chat/Input/ConversationStarters.tsx: resolve the active spec via getModelSpec (same pattern as Landing.tsx) and fall back to its starters. Entity (agent/assistant) starters keep precedence; the MAX_CONVO_STARTERS cap is unchanged. Starter cards are refined: centered text, content-based width, word-boundary wrapping (replaces break-all), staggered fade-in, and a focus-visible ring.
  • client/src/components/Chat/ChatView.tsx: render starters between the landing content and the chat input rather than below the input (footer slot).
  • packages/api/src/modelSpecs/modelSpecs.test.ts: unit test asserting sanitizeModelSpecs preserves the new field while still stripping private preset fields.
  • e2e/config/librechat.e2e.yaml + e2e/specs/mock/model-spec-starters.spec.ts: mock spec (5 starters) and Playwright coverage for rendering, absence on specs without starters, click-to-submit, and the 4-starter cap (mirrors model-spec-branding.spec.ts).

The yaml strings are intentionally uncapped in the zod schema: a .max() violation would fail the strict config parse and drop all model specs; the UI's 2-line clamp handles long text gracefully.

Related work: #11326 adds builder-UI conversation starters for database agents — complementary data source (DB agents vs. yaml specs); both touch the shared landing component, so whichever merges second needs a small rebase.

Change Type

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Testing

  • npx playwright test --config=e2e/playwright.config.mock.ts model-spec-starters — 3/3 passed (rendering, absence, click-to-submit + cap)
  • client: npm run test:ci — 204 suites / 2,526 tests passed; tsc --noEmit clean
  • packages/api: npx jest src/modelSpecs — 7/7 passed (incl. new sanitize test)
  • npm run build:data-provider succeeds; ESLint/Prettier clean on touched files
  • Manual: ran backend + built client locally with a librechat.yaml defining starters on two specs; verified cards render on the landing for the active spec, clicking submits the prompt, and specs without starters show the unchanged landing

Test Configuration:

  • Node v22, MongoDB 8 (Docker), librechat.yaml with modelSpecs.list[*].conversation_starters as in the example above

Checklist

Closes

🤖 Generated with Claude Code

Adds an optional conversation_starters field to model specs in
librechat.yaml. When the active conversation uses a spec that defines
starters (and no agent/assistant starters apply), the chat landing
renders clickable starter prompts between the landing content and the
chat input; clicking one submits it as the first message.

- data-provider: add conversation_starters to TModelSpec and
  tModelSpecSchema so the field survives strict config parsing
- client: ConversationStarters falls back to the active spec's
  starters via getModelSpec; entity (agent/assistant) starters
  take precedence; starter cards are centered, size to content,
  wrap at word boundaries, stagger their fade-in, and gain a
  focus-visible ring
- sanitizeModelSpecs passes the field through (denylist); covered
  by a new unit test
- e2e: mock spec + tests for rendering, absence, click-to-submit,
  and the MAX_CONVO_STARTERS cap

Closes danny-avila#3619

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mharveybu
mharveybu force-pushed the feat/modelspec-conversation-starters branch from 149c420 to 9e68d86 Compare June 12, 2026 14:59
@mharveybu
mharveybu marked this pull request as ready for review June 12, 2026 16:53
@danny-avila

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 9e68d8633b

ℹ️ 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".

@danny-avila
danny-avila changed the base branch from main to dev June 13, 2026 15:15
@danny-avila danny-avila changed the title ✨ feat: Conversation Starters for Model Specs 💬 feat: Conversation Starters for Model Specs Jun 13, 2026
@danny-avila
danny-avila merged commit 05eb986 into danny-avila:dev Jun 13, 2026
32 checks passed
danny-avila added a commit to LibreChat-AI/librechat.ai that referenced this pull request Jun 15, 2026
* 📋 docs: Add conversation_starters to Model Specs object structure

Documents the new modelSpec field from danny-avila/LibreChat#13710.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: Merge model spec starter guidance

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Danny Avila <danny@librechat.ai>
fuuuzzy pushed a commit to fuuuzzy/LibreChat that referenced this pull request Jun 18, 2026
* 💬 feat: Conversation Starters for Model Specs

Adds an optional conversation_starters field to model specs in
librechat.yaml. When the active conversation uses a spec that defines
starters (and no agent/assistant starters apply), the chat landing
renders clickable starter prompts between the landing content and the
chat input; clicking one submits it as the first message.

- data-provider: add conversation_starters to TModelSpec and
  tModelSpecSchema so the field survives strict config parsing
- client: ConversationStarters falls back to the active spec's
  starters via getModelSpec; entity (agent/assistant) starters
  take precedence; starter cards are centered, size to content,
  wrap at word boundaries, stagger their fade-in, and gain a
  focus-visible ring
- sanitizeModelSpecs passes the field through (denylist); covered
  by a new unit test
- e2e: mock spec + tests for rendering, absence, click-to-submit,
  and the MAX_CONVO_STARTERS cap

Closes danny-avila#3619

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: Sort ChatView imports

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Danny Avila <danny@librechat.ai>
ThomasVuNguyen pushed a commit to ThomasVuNguyen/LibreChat that referenced this pull request Jul 15, 2026
* 💬 feat: Conversation Starters for Model Specs

Adds an optional conversation_starters field to model specs in
librechat.yaml. When the active conversation uses a spec that defines
starters (and no agent/assistant starters apply), the chat landing
renders clickable starter prompts between the landing content and the
chat input; clicking one submits it as the first message.

- data-provider: add conversation_starters to TModelSpec and
  tModelSpecSchema so the field survives strict config parsing
- client: ConversationStarters falls back to the active spec's
  starters via getModelSpec; entity (agent/assistant) starters
  take precedence; starter cards are centered, size to content,
  wrap at word boundaries, stagger their fade-in, and gain a
  focus-visible ring
- sanitizeModelSpecs passes the field through (denylist); covered
  by a new unit test
- e2e: mock spec + tests for rendering, absence, click-to-submit,
  and the MAX_CONVO_STARTERS cap

Closes danny-avila#3619

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: Sort ChatView imports

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Danny Avila <danny@librechat.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhancement: ability to set conversation starters

2 participants