mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
fix(desktop): clarify inherited agent parallelism (#4010)
## Summary - show an unambiguous `App default (10)` inherited state for parallelism in create and edit forms - explain that blank inherits the app default and suppress create-form number steppers that could silently set `1` - align the E2E mint fallback with production while preserving explicit input → definition → app-default precedence ## Why The forms displayed `1` even though an untouched field is omitted and desktop minting materializes `10`. The create-form spinner could also turn blank/inherited into an explicit `1` with one click while leaving the field looking nearly unchanged. ## Testing - `pnpm test` (desktop: 3,886 passed) - `pnpm typecheck` (desktop) - `pnpm check` (desktop) - pre-push `desktop-check` and `desktop-test` --------- Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
This commit is contained in:
@@ -250,12 +250,16 @@ fn generated_passphrase_respects_word_count_and_separator() {
|
||||
|
||||
#[test]
|
||||
fn generated_passphrase_clamps_word_count() {
|
||||
// Use a separator that cannot appear in the EFF wordlist so a generated
|
||||
// word such as "yo-yo" cannot be mistaken for two words.
|
||||
const SEPARATOR: &str = "|";
|
||||
|
||||
// Below the floor: clamped up to MIN_PASSPHRASE_WORDS, never shorter.
|
||||
let phrase = generate_passphrase(1, "-").unwrap();
|
||||
assert_eq!(phrase.split('-').count(), MIN_PASSPHRASE_WORDS);
|
||||
let phrase = generate_passphrase(1, SEPARATOR).unwrap();
|
||||
assert_eq!(phrase.split(SEPARATOR).count(), MIN_PASSPHRASE_WORDS);
|
||||
// Above the ceiling: clamped down to MAX_PASSPHRASE_WORDS.
|
||||
let phrase = generate_passphrase(50, "-").unwrap();
|
||||
assert_eq!(phrase.split('-').count(), MAX_PASSPHRASE_WORDS);
|
||||
let phrase = generate_passphrase(50, SEPARATOR).unwrap();
|
||||
assert_eq!(phrase.split(SEPARATOR).count(), MAX_PASSPHRASE_WORDS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
20
desktop/src/features/agents/lib/agentParallelism.test.mjs
Normal file
20
desktop/src/features/agents/lib/agentParallelism.test.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
DEFAULT_AGENT_PARALLELISM,
|
||||
resolveAgentParallelism,
|
||||
} from "./agentParallelism.ts";
|
||||
|
||||
test("parallelism uses the app default only when input and definition omit it", () => {
|
||||
assert.equal(
|
||||
resolveAgentParallelism(undefined, undefined),
|
||||
DEFAULT_AGENT_PARALLELISM,
|
||||
);
|
||||
assert.equal(
|
||||
resolveAgentParallelism(undefined, null),
|
||||
DEFAULT_AGENT_PARALLELISM,
|
||||
);
|
||||
assert.equal(resolveAgentParallelism(undefined, 4), 4);
|
||||
assert.equal(resolveAgentParallelism(2, 4), 2);
|
||||
});
|
||||
18
desktop/src/features/agents/lib/agentParallelism.ts
Normal file
18
desktop/src/features/agents/lib/agentParallelism.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Desktop-managed agents materialize this value when neither the create input
|
||||
* nor the linked definition sets parallelism. Keep in sync with
|
||||
* `managed_agents::DEFAULT_AGENT_PARALLELISM` in the Tauri backend.
|
||||
*/
|
||||
export const DEFAULT_AGENT_PARALLELISM = 10;
|
||||
|
||||
export const AGENT_PARALLELISM_PLACEHOLDER = `App default (${DEFAULT_AGENT_PARALLELISM})`;
|
||||
export const AGENT_PARALLELISM_HELP = `Leave blank to use the app default (currently ${DEFAULT_AGENT_PARALLELISM}). Custom values may be 1–32.`;
|
||||
export const EDIT_AGENT_PARALLELISM_HELP =
|
||||
"Current value for this agent. Custom values may be 1–32.";
|
||||
|
||||
export function resolveAgentParallelism(
|
||||
input: number | undefined,
|
||||
definition: number | null | undefined,
|
||||
): number {
|
||||
return input ?? definition ?? DEFAULT_AGENT_PARALLELISM;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import type { AgentPersona } from "@/shared/api/types";
|
||||
import { BuzzAgentModelTuningFields } from "./buzzAgentModelTuningFields";
|
||||
import { isBuzzAgentRuntime } from "./buzzAgentConfig";
|
||||
import { EDIT_AGENT_PARALLELISM_HELP } from "../lib/agentParallelism";
|
||||
|
||||
export function EditAgentAdvancedFields({
|
||||
acpCommand,
|
||||
@@ -173,10 +174,14 @@ export function EditAgentAdvancedFields({
|
||||
id="edit-agent-parallelism"
|
||||
inputMode="numeric"
|
||||
onChange={(event) => onParallelismChange(event.target.value)}
|
||||
placeholder="1"
|
||||
placeholder="Current value"
|
||||
type="text"
|
||||
value={parallelism}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{EDIT_AGENT_PARALLELISM_HELP}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Relay URL: intentionally no editor. The legacy per-record relay pin
|
||||
|
||||
@@ -4,6 +4,10 @@ import { EnvVarsEditor, type EnvVarsValue } from "./EnvVarsEditor";
|
||||
import { CreateAgentRespondToField } from "./RespondToField";
|
||||
import type { PersonaBehaviorDraft } from "./personaBehaviorDraft";
|
||||
import { isBuzzAgentRuntime } from "./buzzAgentConfig";
|
||||
import {
|
||||
AGENT_PARALLELISM_HELP,
|
||||
AGENT_PARALLELISM_PLACEHOLDER,
|
||||
} from "../lib/agentParallelism";
|
||||
import { BuzzAgentModelTuningFields } from "./buzzAgentModelTuningFields";
|
||||
import {
|
||||
CARD_MINT_KEY_ANNOTATIONS,
|
||||
@@ -83,7 +87,7 @@ export function PersonaAdvancedFields({
|
||||
>
|
||||
<Input
|
||||
className={cn(
|
||||
"h-8 px-0 py-0 leading-6",
|
||||
"h-8 px-0 py-0 leading-6 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
|
||||
PERSONA_FIELD_CONTROL_CLASS,
|
||||
)}
|
||||
disabled={disabled}
|
||||
@@ -97,13 +101,13 @@ export function PersonaAdvancedFields({
|
||||
parallelism: event.target.value,
|
||||
})
|
||||
}
|
||||
placeholder="1"
|
||||
placeholder={AGENT_PARALLELISM_PLACEHOLDER}
|
||||
type="number"
|
||||
value={behaviorDraft.parallelism}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
How many conversations each running instance handles at once (1–32).
|
||||
{AGENT_PARALLELISM_HELP}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
|
||||
import { relayClient } from "@/shared/api/relayClient";
|
||||
import { activateRateLimit } from "@/shared/api/relayRateLimitGate";
|
||||
import { resolveAgentParallelism } from "@/features/agents/lib/agentParallelism";
|
||||
import type { ConnectionState } from "@/shared/api/relayClientShared";
|
||||
import type { ChannelTemplate, RelayEvent } from "@/shared/api/types";
|
||||
import { getMarkdownParseCount } from "@/shared/ui/markdown/nodeCache";
|
||||
@@ -8075,8 +8076,10 @@ async function handleCreateManagedAgent(
|
||||
args.input.respondTo !== undefined
|
||||
? (args.input.respondToAllowlist ?? [])
|
||||
: (linkedPersona?.respond_to_allowlist ?? []);
|
||||
const mintParallelism =
|
||||
args.input.parallelism ?? linkedPersona?.parallelism ?? 1;
|
||||
const mintParallelism = resolveAgentParallelism(
|
||||
args.input.parallelism,
|
||||
linkedPersona?.parallelism,
|
||||
);
|
||||
const personaAvatarUrl =
|
||||
args.input.personaId === undefined
|
||||
? null
|
||||
|
||||
Reference in New Issue
Block a user