[MISC] Auto-create default LLM profile in Prompt Studio with clearer upload tooltip#2005
Conversation
…oad tooltip Drive default profile creation from the creator's default-set adapters (UserDefaultAdapter) instead of frictionless-only adapters, so OSS/on-prem projects also get a profile once each of the 4 adapter types is configured. Skips silently when a usable default is missing for any type. Frontend: wrap the disabled upload button in a span so the antd tooltip fires, and branch the message to prompt adding an LLM profile when none exists vs setting a default when profiles exist. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reuse DefaultValues.DEFAULT_PROFILE_NAME instead of "sample profile" so the auto-created profile matches the name the import flow already defaults to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Summary by CodeRabbit
WalkthroughRefactors default profile creation to use organization-scoped UserDefaultAdapter defaults and updates the manage-docs upload tooltip/wrapper to show contextual guidance when a default LLM profile is missing. ChangesDefault Profile Setup and Upload Modal UX
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Filename | Overview |
|---|---|
| backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py | Rewrites create_default_profile_manager to source adapters from UserDefaultAdapter; adds org-membership guard, all-adapters-usable check, and transaction.atomic() savepoint. Logic and field mappings are correct. |
| frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx | Wraps disabled upload Button in a span to enable tooltip hover events, and branches the tooltip message between 'Add' and 'Set default' based on whether any LLM profiles exist. |
| frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.css | Adds .manage-docs-upload-tooltip-wrap style (inline-block, full width) to support the new span wrapper. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[create_default_profile_manager called] --> B{OrganizationMember exists?}
B -- No --> C[Log & return]
B -- Yes --> D{UserDefaultAdapter row exists?}
D -- No --> E[Log & return]
D -- Yes --> F[Load all 4 adapter FKs]
F --> G{All 4 adapters present & is_usable?}
G -- No --> H[Log & return]
G -- Yes --> I[transaction.atomic savepoint]
I --> J[ProfileManager.objects.create with DEFAULT_PROFILE_NAME]
J -- Success --> K[Profile created, outer TX intact]
J -- Exception --> L[Savepoint rolled back, warning logged]
L --> M[Outer transaction unaffected]
Reviews (6): Last reviewed commit: "[MISC] Address review: guard missing org..." | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx (1)
756-789:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAlign
Upload.Draggerdisabled state with inner upload button state
Upload.Draggeris disabled only forisUploading || !defaultLlmProfile, but the inner Button also disables forisMultiPassExtractLoading,isSinglePassExtractLoading, andisPublicSource.beforeUpload/handleUploadChangedon’t guard these flags, so drag/click can still initiate uploads while the UI appears disabled.Proposed fix
<Upload.Dragger name="file" action={`/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/file/${details?.tool_id}`} headers={{ "X-CSRFToken": sessionDetails.csrfToken, }} onChange={handleUploadChange} - disabled={isUploading || !defaultLlmProfile} + disabled={ + isUploading || + !defaultLlmProfile || + isMultiPassExtractLoading || + isSinglePassExtractLoading || + isPublicSource + } showUploadList={false} beforeUpload={beforeUpload} >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx` around lines 756 - 789, The Upload.Dragger disabled condition must match the inner Button and prevent programmatic uploads: update the Upload.Dragger disabled prop to include isMultiPassExtractLoading, isSinglePassExtractLoading, and isPublicSource (so it uses isUploading || !defaultLlmProfile || isMultiPassExtractLoading || isSinglePassExtractLoading || isPublicSource) and add guards at the start of beforeUpload and handleUploadChange to return/abort if any of those flags are true; reference Upload.Dragger, Button, beforeUpload, and handleUploadChange to locate and change the conditions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py`:
- Around line 107-113: The code calls
OrganizationMemberService.get_user_by_id(...) and then immediately filters
UserDefaultAdapter.objects.filter(organization_member=organization_member), but
get_user_by_id can return None which causes a null-scoped filter to match
unrelated rows; update the logic in the function containing organization_member
(where OrganizationMemberService.get_user_by_id is called) to check if
organization_member is None and if so log a clear message (e.g., "Skipping
default profile creation: organization member not found for user X") and return
early before querying UserDefaultAdapter, ensuring
UserDefaultAdapter.objects.filter is only called with a valid OrganizationMember
instance.
---
Outside diff comments:
In `@frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx`:
- Around line 756-789: The Upload.Dragger disabled condition must match the
inner Button and prevent programmatic uploads: update the Upload.Dragger
disabled prop to include isMultiPassExtractLoading, isSinglePassExtractLoading,
and isPublicSource (so it uses isUploading || !defaultLlmProfile ||
isMultiPassExtractLoading || isSinglePassExtractLoading || isPublicSource) and
add guards at the start of beforeUpload and handleUploadChange to return/abort
if any of those flags are true; reference Upload.Dragger, Button, beforeUpload,
and handleUploadChange to locate and change the conditions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9c62b33f-ff2c-4309-bf91-9c33c25f9d7e
📒 Files selected for processing (3)
backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.pyfrontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.cssfrontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx
…roject creation create_default_profile_manager is called outside the create() try/except, so wrap the ProfileManager insert and swallow/log any error - matching the prior contract where a missing adapter was silently skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rofile create - Return early when the user has no OrganizationMember, so the nullable UserDefaultAdapter.organization_member can't match an unrelated null-scoped row. - Wrap ProfileManager.create in transaction.atomic() so a caught DB error doesn't poison the request's outer transaction under ATOMIC_REQUESTS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Frontend Lint Report (Biome)✅ All checks passed! No linting or formatting issues found. |
|
Unstract test resultsPer-group results
Critical paths
|



What
Why
How
prompt_studio_helper.py::create_default_profile_managernow builds the profile from the creator's default-set adapters (UserDefaultAdapter) instead ofis_friction_lessadapters. It creates the profile only when a usable default exists for every adapter type, and skips silently otherwise (so project creation never breaks before adapters are configured). One code path serves cloud (frictionless adapters are the triad defaults, seeded at onboarding) and OSS/on-prem (defaults auto-set as the user adds the first adapter of each type).DefaultValues.DEFAULT_PROFILE_NAMEconstant ("Default Profile"), matching what the tool-import flow already defaults to.AdapterKeys/BaseManagerimports.ManageDocsModal.jsx: wrapped the disabled upload button in a<span>so the tooltip fires, and branched the tooltip message. Added a.manage-docs-upload-tooltip-wrapCSS class (no inline CSS).Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
UserDefaultAdapterat onboarding/invite, so they remain the source for the auto-created profile. The profile-name uniqueness constraint is scoped per project(prompt_studio_tool, profile_name); the auto-created profile is the only profile in a fresh project, so no collision. The frontend change is additive (tooltip wrapper + message branch) and does not alter the disabled condition.Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
Dependencies Versions
Notes on Testing
Screenshots
Checklist
I have read and understood the Contribution Guidelines.
🤖 Generated with Claude Code