mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): allow saving personas with an empty system prompt (#1276)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
This commit is contained in:
co-authored by
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d
Tyler Longwell
parent
5306735986
commit
996a3f89d5
@@ -167,13 +167,13 @@ pub fn create_persona(
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<PersonaRecord, String> {
|
||||
let display_name = trim_required(&input.display_name, "Display name")?;
|
||||
let system_prompt = trim_required(&input.system_prompt, "System prompt")?;
|
||||
// System prompt optional: core memory is auto-injected. Empty is valid.
|
||||
let system_prompt = input.system_prompt.trim().to_string();
|
||||
let avatar_url = trim_optional(input.avatar_url);
|
||||
let runtime = trim_optional(input.runtime);
|
||||
let model = trim_optional(input.model);
|
||||
let provider = trim_optional(input.provider);
|
||||
let now = now_iso();
|
||||
|
||||
let _store_guard = state
|
||||
.managed_agents_store_lock
|
||||
.lock()
|
||||
@@ -217,7 +217,7 @@ pub fn update_persona(
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<PersonaRecord, String> {
|
||||
let display_name = trim_required(&input.display_name, "Display name")?;
|
||||
let system_prompt = trim_required(&input.system_prompt, "System prompt")?;
|
||||
let system_prompt = input.system_prompt.trim().to_string();
|
||||
let avatar_url = trim_optional(input.avatar_url);
|
||||
let runtime = trim_optional(input.runtime);
|
||||
let model = trim_optional(input.model);
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
getImportErrorLabel,
|
||||
IMPORT_ERROR_VISIBILITY_MS,
|
||||
} from "./personaDialogImportState";
|
||||
import { canSubmitPersonaDialog } from "./personaDialogState";
|
||||
|
||||
type PersonaDialogProps = {
|
||||
open: boolean;
|
||||
@@ -519,11 +520,7 @@ export function PersonaDialog({
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
disabled={
|
||||
displayName.trim().length === 0 ||
|
||||
systemPrompt.trim().length === 0 ||
|
||||
isPending
|
||||
}
|
||||
disabled={!canSubmitPersonaDialog({ displayName, isPending })}
|
||||
onClick={() => void handleSubmit()}
|
||||
size="sm"
|
||||
type="button"
|
||||
|
||||
@@ -2,12 +2,44 @@ import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
canSubmitPersonaDialog,
|
||||
createPersonaDialogState,
|
||||
duplicatePersonaDialogState,
|
||||
editPersonaDialogState,
|
||||
importPersonaDialogState,
|
||||
} from "./personaDialogState.ts";
|
||||
|
||||
test("canSubmitPersonaDialog requires a display name but not a system prompt", () => {
|
||||
// Empty system prompt is allowed: core memory is auto-injected, so the
|
||||
// persona prompt is optional. Only the display name gates submission.
|
||||
assert.equal(
|
||||
canSubmitPersonaDialog({ displayName: "Coder", isPending: false }),
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
canSubmitPersonaDialog({ displayName: " Coder ", isPending: false }),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test("canSubmitPersonaDialog blocks an empty or whitespace display name", () => {
|
||||
assert.equal(
|
||||
canSubmitPersonaDialog({ displayName: "", isPending: false }),
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
canSubmitPersonaDialog({ displayName: " ", isPending: false }),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("canSubmitPersonaDialog blocks while a save is pending", () => {
|
||||
assert.equal(
|
||||
canSubmitPersonaDialog({ displayName: "Coder", isPending: true }),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("createPersonaDialogState returns a fresh empty draft", () => {
|
||||
const first = createPersonaDialogState();
|
||||
const second = createPersonaDialogState();
|
||||
|
||||
@@ -14,6 +14,20 @@ export type PersonaDialogState = {
|
||||
|
||||
type ParsedPersonaDraft = ParsePersonaFilesResult["personas"][number];
|
||||
|
||||
/**
|
||||
* Whether the persona dialog's save action should be enabled.
|
||||
*
|
||||
* A display name is the only required field. The system prompt is optional:
|
||||
* core memory is auto-injected at runtime, so a persona need not carry its
|
||||
* own prompt. `isPending` blocks double-submits while a save is in flight.
|
||||
*/
|
||||
export function canSubmitPersonaDialog(args: {
|
||||
displayName: string;
|
||||
isPending: boolean;
|
||||
}): boolean {
|
||||
return args.displayName.trim().length > 0 && !args.isPending;
|
||||
}
|
||||
|
||||
export function createPersonaDialogState(): PersonaDialogState {
|
||||
return {
|
||||
title: "Create persona",
|
||||
|
||||
Reference in New Issue
Block a user