mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-24 08:54:05 +10:00
feat: add AI agent workspace (#3062)
* chore(ai): remove local AI store now that providers live server-side
The Zustand-based useAIStore has been replaced by the server-side
aiProviders oRPC router (encrypted credentials persisted in DB).
Delete the dead store + tests, drop the ./store export, and remove
zustand/immer deps which are no longer referenced anywhere in
packages/ai/src/.
* feat(agent): archive/delete actions and read-only state for agent threads
- Backend: mark archived threads as read-only in threads.get and reject
messages.send with CONFLICT when the thread is archived.
- Frontend: render archived threads in the sidebar with muted styling and
an Archived badge; add a per-thread dropdown menu in the chat header
with Archive (non-destructive) and Delete (with confirmation); show a
read-only banner above the message list that disambiguates archived
vs. missing-resource causes; suppress the Retry and Stop buttons in
read-only mode.
- Tests: new packages/api/src/services/agent.test.ts covering the
archived-thread isReadOnly flag and the archived-thread send refusal.
* fix(agent): abort run on archive and verify ownership before deleting thread
- threads.archive: before flipping status, abort any in-flight run controller
and clear the active-run state on the thread; cleanup failures are logged
but do not block the status update.
- threads.delete: assert thread ownership via getThread before destructive
work so an authenticated user cannot wipe another user's attachment rows
by passing a foreign threadId.
Adds focused tests for both behaviors.
* feat(agent): display patch diffs and surface revert conflicts
Render apply_resume_patch tool messages with a status-aware card (applied/
reverted/conflicted), expandable operation list, and a Revert button that
correctly handles RESUME_VERSION_CONFLICT responses. Adds unit tests for
the inverse-patch builder and the agentService.actions.revert flow.
* chore(agent): remove out-of-scope attachment tests accidentally added in Task 6
The Task 6 commit (73ef1acca) accidentally re-introduced three attachment-
related tests that belong to a separate task:
- `buildAttachmentModelParts > converts text, image, supported binary, and
unsupported attachments into model parts`
- `agentService.messages.send > persists the user message with file UI parts
and links selected attachments to it` (was failing — the `ToolLoopAgent`
mock is not callable as a constructor)
- `agentService.messages.send > rejects attachments that are missing, foreign,
or already linked before persisting a message`
These were likely re-added during a stash recovery and were not requested
for Task 6, whose scope was limited to the `agentService.actions.revert`
flow. Remove them along with the helpers/fixtures (`buildAttachment`,
`buildActiveThread`, `selectWhereResult`, `selectOrderByResult`) that they
were the only consumers of. `selectLimitResult` is preserved because it is
used by the revert tests.
* chore(agent): configure runtime dependencies
* feat(db): add agent workspace schema
* feat(api): add agent backend services
* feat(web): add agent workspace UI
* chore(agent): remove legacy builder assistant
* test(agent): make agent stream mocks constructible
* chore(web): remove unused resume replacement hook
* feat(api): add unsafe AI base URL flag
* chore(dev): expose local services in compose
* fix(web): normalize resume preview gaps
* feat(api): improve agent tool handling
* feat(web): polish agent workspace UI
* chore: update dependencies
* fix(api,web): address PR review feedback for agent workspace
Security/correctness:
- Restrict AI provider URLs to http/https even in unsafe mode
- Stop exposing Redis on host network by default
- Make .env.local optional and drop app profile in compose.dev.yml
- Store agent attachments with private ACL on S3
- Reset provider test status when provider/model/baseURL changes
- Decouple non-agent AI endpoints from REDIS_URL requirement
- Fix JSON Patch add inverse for existing object members
- Wrap resume patch + agent action insert in db transaction
- Validate partialMessage at runtime and rate-limit attachment uploads
- Add unique index on agent_messages (thread_id, sequence)
UX/bugs:
- Mark agent thread route as ssr: false and guard SSE chunk parsing
- Show config-specific banner only on known configuration error
- Gate AI provider checks behind loading state in resume import
- Fix relative-time formatter blank gap between 45-59 seconds
- Clarify thread delete confirmation message
Polish:
- Raise ENCRYPTION_SECRET minimum to 32 characters
- Bucket AI rate limits by resumeId/threadId/messageId
- Trim form values before submitting AI provider config
- Use single key identifier and nullish-coalesce baseURL display
* fix: address ai agent review feedback
* fix: preserve mobile agent chat state
* docs: add ai agent workspace guides
* feat: introduce design system for Reactive Resume
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: "AI Agent Tools"
|
||||
description: "Understand the tools available to the AI Agent workspace and how they affect resume drafts."
|
||||
---
|
||||
|
||||
The AI Agent workspace can use a curated set of tools while it chats with you. You do not call these tools directly; the agent chooses them when your request needs resume data, web context, attachments, questions, or a resume patch.
|
||||
|
||||
## Tool activity in chat
|
||||
|
||||
Tool activity appears inside the conversation. Some activity is collapsed by default so the chat stays readable.
|
||||
|
||||
Applied resume patches are shown as a small inline **Patch applied** item. Open it to inspect the raw JSON payload.
|
||||
|
||||
<Frame caption="Patch details and tool activity in the AI Agent chat">
|
||||
<img
|
||||
src="/images/guides/ai-agent-tools/screenshot-1.webp"
|
||||
alt="AI Agent chat showing an applied patch with raw JSON details"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
## Available tools
|
||||
|
||||
| Tool | What it does | Example request |
|
||||
| --- | --- | --- |
|
||||
| `read_resume` | Reads the current AI draft and gives the agent the resume data it can safely edit. | "What are the weakest parts of this resume?" |
|
||||
| `fetch_url` | Fetches public HTTPS pages, extracts readable content, and returns it as agent input. | "Tailor this resume to this job description: `https://example.com/job`" |
|
||||
| Provider-native search | Uses the selected provider's native web search when that provider/model supports it. | "Research this company and adjust the summary for its product area." |
|
||||
| `read_attachment` | Reads extracted text from attached plain text, Markdown, or JSON files. Other supported attachments, such as images or PDFs, are passed to the model when the selected provider can use them. | "Use the attached notes to update the keywords." |
|
||||
| `ask_user_question` | Shows a question card with answer choices when the agent needs your decision. | "Ask me before changing the career narrative." |
|
||||
| `apply_resume_patch` | Applies a JSON Patch to the AI draft and stores enough history to revert it later. | "Change the visible name to Amruth Pillai." |
|
||||
|
||||
## Resume patches
|
||||
|
||||
Resume patches are rooted at the resume data object. For example, the visible resume name is patched at `/basics/name`.
|
||||
|
||||
When a patch is applied:
|
||||
|
||||
- the AI draft updates immediately;
|
||||
- the raw JSON Patch is available from the **Patch applied** details;
|
||||
- an inverse patch is stored for revert;
|
||||
- the resume preview refreshes to show the updated draft.
|
||||
|
||||
If the resume changed after the patch was generated, revert or apply can fail with a version conflict. In that case, ask the agent to retry from the latest draft.
|
||||
|
||||
## Web access
|
||||
|
||||
The agent can fetch public HTTPS URLs so it can read job descriptions, company pages, or other public context you provide.
|
||||
|
||||
For self-hosted deployments:
|
||||
|
||||
- private, loopback, and non-HTTPS URLs are blocked by default;
|
||||
- Cloudflare URL extraction is optional and is used only as a fallback when local readability extraction fails;
|
||||
- unsafe/private AI provider base URLs require `FLAG_ALLOW_UNSAFE_AI_BASE_URL=true`, which should only be used on trusted self-hosted deployments.
|
||||
|
||||
## Attachments
|
||||
|
||||
Attach files from the chat composer when the agent needs extra context, such as:
|
||||
|
||||
- a job description PDF;
|
||||
- a portfolio brief;
|
||||
- a screenshot;
|
||||
- a plain text note with constraints.
|
||||
|
||||
Self-hosted deployments need S3-compatible storage for private agent attachments. Local filesystem storage rejects private objects.
|
||||
|
||||
## Good prompts for tool use
|
||||
|
||||
Use direct prompts that tell the agent what context to use and how cautious to be:
|
||||
|
||||
- "Fetch this role URL, identify the most important keywords, and apply a conservative patch."
|
||||
- "Read the attached job description and ask me before changing anything outside the summary."
|
||||
- "Compare my current projects against this company page and suggest only truthful wording."
|
||||
- "Apply a patch for the visible resume name, then show me what changed."
|
||||
|
||||
## When tools are unavailable
|
||||
|
||||
Tool use can be limited by the selected provider, deployment configuration, or thread state.
|
||||
|
||||
- A deleted provider makes the thread read-only; a disabled or untested provider blocks new agent runs until it is enabled and tested again.
|
||||
- A deleted working resume makes the thread read-only.
|
||||
- Archived threads cannot receive new messages.
|
||||
- URL fetching may fail for private URLs, blocked hosts, non-HTML pages, or pages that cannot be extracted.
|
||||
- Attachments may fail if private object storage is not configured.
|
||||
@@ -27,7 +27,7 @@ description: "Learn how to create your first resume in Reactive Resume, set a na
|
||||
|
||||
<Frame caption="Create a new resume dialog">
|
||||
<img
|
||||
src="/images/guides/creating-your-first-resume/screenshot-1.png"
|
||||
src="/images/guides/creating-your-first-resume/screenshot-1.webp"
|
||||
alt="Create a new resume dialog with name, slug, and tags fields"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -23,7 +23,7 @@ Reactive Resume can export your resume in three formats:
|
||||
|
||||
<Frame caption="Export section in the resume builder">
|
||||
<img
|
||||
src="/images/guides/exporting-your-resume/screenshot-1.png"
|
||||
src="/images/guides/exporting-your-resume/screenshot-1.webp"
|
||||
alt="Export section showing JSON, DOCX, and PDF download buttons"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -32,7 +32,7 @@ Reactive Resume can create a new resume from several existing file formats. Use
|
||||
|
||||
<Frame caption="Import an existing resume dialog">
|
||||
<img
|
||||
src="/images/guides/importing-resumes/screenshot-1.png"
|
||||
src="/images/guides/importing-resumes/screenshot-1.webp"
|
||||
alt="Import dialog showing supported resume import types"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -7,7 +7,7 @@ The **Resumes** dashboard is where you manage every resume in your account. Use
|
||||
|
||||
<Frame caption="Resumes dashboard in grid view">
|
||||
<img
|
||||
src="/images/guides/managing-resumes-from-the-dashboard/screenshot-1.png"
|
||||
src="/images/guides/managing-resumes-from-the-dashboard/screenshot-1.webp"
|
||||
alt="Resumes dashboard showing sort controls, grid view, create and import cards, and a sample resume"
|
||||
/>
|
||||
</Frame>
|
||||
@@ -23,7 +23,7 @@ Use the **Grid** and **List** tabs in the top-right of the dashboard to switch b
|
||||
|
||||
<Frame caption="Resumes dashboard in list view">
|
||||
<img
|
||||
src="/images/guides/managing-resumes-from-the-dashboard/screenshot-2.png"
|
||||
src="/images/guides/managing-resumes-from-the-dashboard/screenshot-2.webp"
|
||||
alt="Resumes dashboard showing the same resume in list view"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -36,7 +36,7 @@ Reactive Resume lets you share your resume via a **public URL** that anyone can
|
||||
|
||||
<Frame caption="Sharing section in the resume builder">
|
||||
<img
|
||||
src="/images/guides/sharing-your-resume-publicly/screenshot-1.png"
|
||||
src="/images/guides/sharing-your-resume-publicly/screenshot-1.webp"
|
||||
alt="Sharing section showing the public access control"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: "Using the AI Agent Workspace"
|
||||
description: "Learn how to start an isolated AI draft, chat with an agent, review resume patches, and continue existing agent threads."
|
||||
---
|
||||
|
||||
The AI Agent workspace is a dedicated place to work with an AI assistant on a resume draft. It keeps the conversation, tool activity, and read-only resume preview in one full-screen view.
|
||||
|
||||
<Info>
|
||||
Agent threads edit an AI draft copy of your resume. Your original resume is not changed when you start from an existing resume.
|
||||
</Info>
|
||||
|
||||
## Before you start
|
||||
|
||||
You need at least one AI provider that is tested and enabled in **Dashboard -> Settings -> Integrations**. For setup, see [Using Artificial Intelligence](/guides/using-ai).
|
||||
|
||||
If you self-host Reactive Resume, the agent workspace also requires the server-side agent configuration described in [Self-hosting with Docker](/self-hosting/docker).
|
||||
|
||||
## Open the agent workspace
|
||||
|
||||
From the dashboard sidebar, click **Agents**.
|
||||
|
||||
The agent page always shows your thread sidebar. Use it to continue an existing thread, or click **New thread** to start another one.
|
||||
|
||||
You can also open the agent from the builder dock. When you do this, the current resume is preselected in the new thread setup screen.
|
||||
|
||||
## Start a new thread
|
||||
|
||||
<Steps>
|
||||
<Step title="Choose an agent model">
|
||||
Pick the provider/model combo the agent should use. This choice is locked once the thread starts.
|
||||
</Step>
|
||||
|
||||
<Step title="Choose a resume draft">
|
||||
Select an existing resume to duplicate as an AI draft, or choose **Create from scratch** for a blank draft.
|
||||
</Step>
|
||||
|
||||
<Step title="Start the thread">
|
||||
Click **Start Thread** to create the draft and open the workspace.
|
||||
|
||||
<Frame caption="Starting an AI Agent thread">
|
||||
<img
|
||||
src="/images/guides/using-ai-agent/screenshot-1.webp"
|
||||
alt="AI Agent new thread setup with model and resume selectors"
|
||||
/>
|
||||
</Frame>
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Use the three-pane workspace
|
||||
|
||||
The desktop workspace is split into three panes:
|
||||
|
||||
- **Threads** on the left: continue, archive, delete, or start agent threads.
|
||||
- **Chat** in the center: send prompts, upload files, answer agent questions, and review tool activity.
|
||||
- **Resume** on the right: read the current AI draft, adjust zoom, open it in the builder, or download a PDF.
|
||||
|
||||
<Frame caption="AI Agent workspace with chat and resume preview">
|
||||
<img
|
||||
src="/images/guides/using-ai-agent/screenshot-2.webp"
|
||||
alt="AI Agent workspace showing thread sidebar, chat, and resume preview"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
On smaller screens, the workspace uses tabs/sheets so you can switch between threads, chat, and preview without losing the active conversation.
|
||||
|
||||
## Ask for resume changes
|
||||
|
||||
The agent works best with concrete instructions:
|
||||
|
||||
- "Tailor this resume to this job description: `https://example.com/job`"
|
||||
- "Find weak bullets and rewrite them with stronger outcomes."
|
||||
- "Compare this draft against a product manager role and update the keywords."
|
||||
- "Ask me before changing anything that looks uncertain."
|
||||
|
||||
You can attach files or images from the composer. The agent can read uploaded attachments when they are relevant to your request.
|
||||
|
||||
<Note>
|
||||
Text input is supported. Voice input is not supported in the agent workspace yet.
|
||||
</Note>
|
||||
|
||||
## Review patches
|
||||
|
||||
When the agent edits the resume, the patch is applied immediately to the AI draft. The chat shows a small **Patch applied** line.
|
||||
|
||||
Open the line to inspect the raw JSON Patch and use **Revert** if you want to undo that patch.
|
||||
|
||||
<Warning>
|
||||
AI-generated changes can still be inaccurate. Review the draft in the preview or builder before exporting or sharing it.
|
||||
</Warning>
|
||||
|
||||
## Answer agent questions
|
||||
|
||||
If the agent needs a decision, it may show a question card with recommended answers. Click the answer you want to send it back to the agent.
|
||||
|
||||
This is useful when the agent finds ambiguous instructions, missing job context, or a change that depends on your preference.
|
||||
|
||||
## Use the resume preview
|
||||
|
||||
The resume pane is read-only. Use the toolbar to:
|
||||
|
||||
- decrease or increase zoom;
|
||||
- set an exact zoom percentage;
|
||||
- open the AI draft in the builder;
|
||||
- download the draft as a PDF.
|
||||
|
||||
Zoom settings are remembered across refreshes.
|
||||
|
||||
## Manage threads
|
||||
|
||||
Threads are ordered by the newest message. Use the thread menu to archive or delete a thread.
|
||||
|
||||
- **Archive** keeps the conversation but makes the thread read-only.
|
||||
- **Delete** removes the thread conversation and its attachments. The generated resume draft remains in your dashboard.
|
||||
|
||||
Threads can also become read-only if the working resume is deleted, the selected provider is deleted, or the thread is archived. If a provider is disabled or no longer tested, re-enable and test it before sending new messages.
|
||||
@@ -27,7 +27,7 @@ Use resume analysis when you want a broad review before making changes.
|
||||
|
||||
<Frame caption="Resume Analysis section in the builder">
|
||||
<img
|
||||
src="/images/guides/using-ai-in-the-builder/screenshot-1.png"
|
||||
src="/images/guides/using-ai-in-the-builder/screenshot-1.webp"
|
||||
alt="Resume Analysis section showing the AI setup prompt in the builder sidebar"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
@@ -17,7 +17,7 @@ Reactive Resume uses AI providers for features such as resume analysis, AI-assis
|
||||
|
||||
<Frame caption="AI provider settings in Integrations">
|
||||
<img
|
||||
src="/images/guides/using-ai/screenshot-1.png"
|
||||
src="/images/guides/using-ai/screenshot-1.webp"
|
||||
alt="Integrations settings showing AI provider configuration"
|
||||
/>
|
||||
</Frame>
|
||||
@@ -38,6 +38,13 @@ In the **AI Providers** section, fill out the **Add Provider** form.
|
||||
|
||||
Click **Save Provider** when the form is complete.
|
||||
|
||||
<Frame caption="Saved AI provider in Integrations">
|
||||
<img
|
||||
src="/images/guides/using-ai/screenshot-2.webp"
|
||||
alt="Integrations settings showing a saved and tested AI provider"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
<Warning>
|
||||
Treat API keys like passwords. Anyone with a key can use the connected provider account and may incur costs.
|
||||
</Warning>
|
||||
@@ -71,8 +78,8 @@ AI provider credentials are encrypted on the server and are never shown again af
|
||||
If provider management is unavailable, your self-hosted deployment may be missing required server configuration.
|
||||
|
||||
<Warning>
|
||||
AI provider management requires the server-side services used to encrypt credentials and run AI work. If the page says
|
||||
provider management is unavailable, check your deployment configuration before using AI features.
|
||||
AI provider management requires the server-side services used to encrypt credentials. If the page says provider
|
||||
management is unavailable, check your deployment configuration before using AI features.
|
||||
</Warning>
|
||||
|
||||
## Where AI is used
|
||||
@@ -84,4 +91,4 @@ After a provider is tested and enabled, you can use AI in:
|
||||
- **Agent** workflows that create isolated AI drafts;
|
||||
- **PDF and Microsoft Word imports** from the dashboard import dialog.
|
||||
|
||||
For the builder workflow, see [Using AI in the builder](/guides/using-ai-in-the-builder). For AI-assisted imports, see [Importing resumes](/guides/importing-resumes).
|
||||
For the builder workflow, see [Using AI in the builder](/guides/using-ai-in-the-builder). For the dedicated agent workspace, see [Using the AI Agent Workspace](/guides/using-ai-agent) and [AI Agent Tools](/guides/ai-agent-tools). For AI-assisted imports, see [Importing resumes](/guides/importing-resumes).
|
||||
|
||||
@@ -7,7 +7,7 @@ The builder dock is the floating toolbar at the bottom of the resume builder. It
|
||||
|
||||
<Frame caption="Resume builder with the floating dock">
|
||||
<img
|
||||
src="/images/guides/using-the-builder-dock/screenshot-1.png"
|
||||
src="/images/guides/using-the-builder-dock/screenshot-1.webp"
|
||||
alt="Resume builder showing the floating dock with preview controls and download shortcuts"
|
||||
/>
|
||||
</Frame>
|
||||
|
||||
Reference in New Issue
Block a user