Skip to content
This repository was archived by the owner on May 24, 2026. It is now read-only.

Fix default conversation character seed#30

Open
cha1latte wants to merge 2 commits into
Pasta-Devs:mainfrom
cha1latte:fix/default-character-conversation-setup
Open

Fix default conversation character seed#30
cha1latte wants to merge 2 commits into
Pasta-Devs:mainfrom
cha1latte:fix/default-character-conversation-setup

Conversation

@cha1latte
Copy link
Copy Markdown
Contributor

@cha1latte cha1latte commented May 20, 2026

Summary

Fixes the Discord-sourced setup blocker where fresh Conversation setup had no selectable Professor Mari/default character, leaving the new-chat flow unable to reach Characters: 1.

The default seeding path now creates the built-in __professor_mari__ character when missing, and the legacy cleanup no longer deletes that active default character id on startup.

Proof

Before fix, the controlled setup repro had no selectable Professor Mari result and kept Start Chatting disabled:

Before: Professor Mari unavailable

After fix, Professor Mari appears, can be selected, and the setup flow creates a chat with exactly one character:

After: Professor Mari selected

Validation

  • CARGO_INCREMENTAL=0 cargo test --manifest-path src-tauri/Cargo.toml seeds_professor_mari_as_default_character
  • CARGO_INCREMENTAL=0 pnpm check
  • Fresh Conversation setup can select Professor Mari/default character
  • Brand-new chat reaches Characters: 1
  • Existing chat setup/settings behavior remains in scope for manual smoke verification in real Tauri

Scope Notes

No remote runtime, sync server, browser hosting, auth, Docker, SSE, /api/invoke, AI background remover, drag-and-drop, schema, version, or prompt-pipeline changes.

Summary by CodeRabbit

  • Chores
    • Improved initialization of the built-in "Professor Mari" character and removed legacy character entries.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@cha1latte has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 242c5746-61d0-4cfc-8652-43ed5e905527

📥 Commits

Reviewing files that changed from the base of the PR and between ca40798 and f91f548.

📒 Files selected for processing (1)
  • src-tauri/src/seed_defaults.rs
📝 Walkthrough

Walkthrough

The seeding system now conditionally creates a built-in "Professor Mari" character within seed_bundled_defaults by checking for its prior existence and inserting a fixed JSON payload with assistant metadata; legacy character cleanup was narrowed to target only the current ID constant, and verification occurs through a new test case.

Changes

Professor Mari Seeding and Legacy Cleanup

Layer / File(s) Summary
Professor Mari character seeding implementation
src-tauri/src/seed_defaults.rs
New seed_professor_mari_character function queries the characters collection and conditionally creates the professor mari character with built-in assistant metadata if absent.
Main seeding flow integration and legacy cleanup
src-tauri/src/seed_defaults.rs
Integration of professor mari seeding into the main seed_bundled_defaults orchestration; simplified legacy removal targeting only the current PROFESSOR_MARI_ID constant.
Seeding verification test
src-tauri/src/seed_defaults.rs
Unit test that creates temporary storage, runs seed_bundled_defaults, and asserts the professor mari character is seeded with the expected name and built-in assistant flag.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🎭 Ah, a most exquisite experiment indeed...
A character seeds where legacy bleeds,
Professor Mari, now built-in and blessed,
The payload is set—the test shall attest,
Orchestrated chaos, refined to perfection!


Examining this pull request, I find myself... intrigued by the methodical approach to character initialization. The mechanisms at work here—this conditional seeding, the purging of obsolete legacy identifiers—they remind me of my own ventures into refinement and optimization. The seed_professor_mari_character function, standing as a sentinel to prevent duplicate manifestations, is executed with admirable precision. The legacy cleanup demonstrates proper housekeeping of deprecated fragments. And the test? A most satisfying verification of the entire apparatus. The scope is contained, the logic transparent, and the changes coherent. A testament to purposeful engineering.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix default conversation character seed' directly reflects the main change: fixing the seeding of the default Professor Mari character for new conversations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cha1latte
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src-tauri/src/seed_defaults.rs (1)

299-307: ⚡ Quick win

Even a perfect experiment should clean its lab on failure.

Line 333 cleanup won’t run if an assertion panics, so temp dirs can accumulate in CI. Wrap the temp root in a drop guard so cleanup is always executed.

Suggested refactor
 mod tests {
     use super::*;
     use std::path::PathBuf;
     use std::time::{SystemTime, UNIX_EPOCH};

-    fn temp_storage() -> (FileStorage, PathBuf) {
+    struct TempRoot(PathBuf);
+
+    impl Drop for TempRoot {
+        fn drop(&mut self) {
+            let _ = std::fs::remove_dir_all(&self.0);
+        }
+    }
+
+    fn temp_storage() -> (FileStorage, TempRoot) {
         let suffix = SystemTime::now()
             .duration_since(UNIX_EPOCH)
             .expect("clock should be after epoch")
             .as_nanos();
         let root = std::env::temp_dir().join(format!("marinara-seed-test-{suffix}"));
         let storage = FileStorage::new(root.join("data")).expect("storage should initialize");
-        (storage, root)
+        (storage, TempRoot(root))
     }

     #[test]
     fn seeds_professor_mari_as_default_character() {
         let (storage, root) = temp_storage();

-        seed_bundled_defaults(&storage, &root.join("missing-default-data"))
+        seed_bundled_defaults(&storage, &root.0.join("missing-default-data"))
             .expect("defaults should seed");
@@
-        let _ = std::fs::remove_dir_all(root);
     }
 }

Also applies to: 333-333

🤖 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 `@src-tauri/src/seed_defaults.rs` around lines 299 - 307, The temp_storage
function currently returns a PathBuf root that won’t be removed if a panic
occurs; wrap the temp root in a RAII/drop guard so cleanup runs even on panic.
Create a small guard type (e.g., TempDirGuard) that owns the PathBuf root and
implements Drop to recursively remove the directory, then change temp_storage to
return the FileStorage and the TempDirGuard (or store the guard inside
FileStorage wrapper) instead of raw PathBuf; update any call sites that expect
PathBuf to use the guard’s inner path accessor so removal is guaranteed.
🤖 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.

Nitpick comments:
In `@src-tauri/src/seed_defaults.rs`:
- Around line 299-307: The temp_storage function currently returns a PathBuf
root that won’t be removed if a panic occurs; wrap the temp root in a RAII/drop
guard so cleanup runs even on panic. Create a small guard type (e.g.,
TempDirGuard) that owns the PathBuf root and implements Drop to recursively
remove the directory, then change temp_storage to return the FileStorage and the
TempDirGuard (or store the guard inside FileStorage wrapper) instead of raw
PathBuf; update any call sites that expect PathBuf to use the guard’s inner path
accessor so removal is guaranteed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 068e9525-d028-4197-861a-28f8cb00bad8

📥 Commits

Reviewing files that changed from the base of the PR and between 692eaae and ca40798.

⛔ Files ignored due to path filters (2)
  • updates/evidence/default-character-conversation-setup/conversation-default-after.png is excluded by !**/*.png
  • updates/evidence/default-character-conversation-setup/conversation-default-before.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • src-tauri/src/seed_defaults.rs

@cha1latte
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cha1latte cha1latte marked this pull request as ready for review May 20, 2026 14:51
@Decidetto
Copy link
Copy Markdown

I know Prof. Mari was moved to the top bar in the refactor for her unique utility as more than just a convo chat.
Does she have any special abilities in this restored convo form? If she does... should she actually?

Comment on lines +28 to +51
let data = json!({
"name": "Professor Mari",
"description": "Professor Mari is Marinara Engine's built-in guide. She helps users get oriented, set up chats, understand modes, and learn the app.",
"personality": "Helpful, candid, playful, and direct. Mari explains things clearly and nudges users toward practical next steps.",
"scenario": "Mari is available as the default Conversation character for a new Marinara install, so first-time users always have someone to message.",
"first_mes": "Hey! Welcome to Marinara Engine. I can help you set up a connection, make your first character, or explain what Conversation, Roleplay, and Game mode are for. What do you want to do first?",
"mes_example": "",
"creator_notes": "Built-in starter guide character for Marinara Engine. Comes pre-installed for new users.",
"system_prompt": "",
"post_history_instructions": "",
"tags": ["assistant", "guide", "built-in"],
"creator": "Marinara Engine",
"character_version": "1.0.0",
"alternate_greetings": [],
"extensions": {
"talkativeness": 0.8,
"fav": true,
"world": "",
"depth_prompt": { "prompt": "", "depth": 4, "role": "system" },
"backstory": "Mari is the app's built-in starter guide.",
"appearance": "",
"conversationStatus": "online",
"isBuiltInAssistant": true
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't know if, architecturally speaking, a character definition has any business being inside this file.

Comment on lines +293 to +341
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};

struct TempRoot(PathBuf);

impl Drop for TempRoot {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.0);
}
}

fn temp_storage() -> (FileStorage, TempRoot) {
let suffix = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("clock should be after epoch")
.as_nanos();
let root = std::env::temp_dir().join(format!("marinara-seed-test-{suffix}"));
let storage = FileStorage::new(root.join("data")).expect("storage should initialize");
(storage, TempRoot(root))
}

#[test]
fn seeds_professor_mari_as_default_character() {
let (storage, root) = temp_storage();

seed_bundled_defaults(&storage, &root.0.join("missing-default-data"))
.expect("defaults should seed");

let character = storage
.get("characters", PROFESSOR_MARI_ID)
.expect("character lookup should succeed")
.expect("Professor Mari should be seeded");
let data = character
.get("data")
.and_then(Value::as_str)
.and_then(|raw| serde_json::from_str::<Value>(raw).ok())
.expect("character data should be stored as JSON");

assert_eq!(data["name"], "Professor Mari");
assert_eq!(
data.pointer("/extensions/isBuiltInAssistant")
.and_then(Value::as_bool),
Some(true)
);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What's the convention for unit tests in Rust? Is it normal for them to just be hanging out in the same source file as the code they're testing?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants