# AI Chat Assistant

## Objective

Give users a conversation that answers questions and helps them finish work in the app.

A persistent chat surface with streamed responses, stored conversation history, and a defined set of actions it may take on the user's behalf.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Store conversations as records owned by a user and a workspace, and load every message through the same authorization path the rest of the app uses. Do not trust a conversation identifier supplied by the client as proof of access.
2. Stream tokens to the interface as they arrive, but persist a message only once the generation finishes cleanly. A stream that is cancelled, truncated, or errored must be marked incomplete rather than saved as an answer.
3. Set a token ceiling and a wall-clock timeout for every request, and trim old turns from the context with a summary of what was dropped rather than sending the entire history each time.
4. If the assistant can perform actions, let it only propose them and require the user to confirm before anything is written. Report success from the result of the action, never from what the model said it did.
5. Page-specific context — the record being viewed, the current route, the actions available on that screen — is owned by Contextual Page Copilot. This feature owns the conversation, its storage, and its streaming; do not build a second context assembler here.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- Every conversation and message must be scoped to one user and one workspace. A user who switches workspaces must not see the previous workspace's threads, and an identifier guessed or replayed from another account must resolve to nothing.
- A partial stream is not an answer. If the connection drops mid-generation or the user navigates away, the interface must show the turn as unfinished and offer to retry rather than leaving a half sentence in the transcript.
- Timeouts, provider errors, safety refusals, and user cancellation are four different outcomes and need four different messages. A refusal is not a bug and must not be retried automatically.
- Long conversations grow expensive and lose relevance. Cap the context window, and make the trimming visible enough that the user understands why the assistant no longer remembers something from an hour ago.
- The assistant must never claim an action succeeded unless the app confirmed it. If the confirmation call fails after the model announced the result, correct the transcript rather than leaving the false claim in place.
- The provider being unavailable must degrade the feature, not the page. The chat surface shows an unavailable state and the rest of the app keeps working.
- Enforce a per-user and per-workspace spend or request ceiling, and tell the user plainly when they have reached it instead of failing with a generic error.
- Pasted content the user does not realise is sensitive still leaves the app. State in the interface what is sent to the provider, and exclude fields the workspace has marked restricted.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] Conversations and messages are readable only by the owning user within the owning workspace.
- [ ] Cancelled, timed-out, and truncated generations are stored as incomplete and are never presented as finished answers.
- [ ] Every request carries a token ceiling and a timeout, and context is trimmed rather than allowed to grow without bound.
- [ ] Actions are proposed for approval, and reported outcomes come from the app rather than from the model's own claim.
- [ ] Refusals, provider outages, and rate limits each produce a distinct, non-technical message.
- [ ] The app remains fully usable when the model is unavailable.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
