Skip to content

Commit

Permalink
custom personality improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
phughesmcr committed Sep 4, 2024
1 parent 8a55281 commit 37e43e8
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 88 deletions.
67 changes: 67 additions & 0 deletions components/CustomPersonalityInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { MAX_PERSONALITY_LENGTH } from "lib/debate/inputValidation.ts";
import { personalities } from "lib/debate/personalities.ts";
import { useEffect, useState } from "preact/hooks";

interface CustomPersonalityInputProps {
value: string;
onChange: (value: string) => void;
}

export default function CustomPersonalityInput({ value, onChange }: CustomPersonalityInputProps) {
const [selectedOption, setSelectedOption] = useState<string>("custom");
const [customInput, setCustomInput] = useState<string>(value);

useEffect(() => {
const matchingPersonality = personalities.find(p => p.personality === value);
if (matchingPersonality) {
setSelectedOption(matchingPersonality.name);
} else {
setSelectedOption("custom");
setCustomInput(value);
}
}, [value]);

const handleSelectChange = (e: Event) => {
const selected = (e.target as HTMLSelectElement).value;
setSelectedOption(selected);
if (selected === "custom") {
onChange(customInput);
} else {
const personality = personalities.find(p => p.name === selected);
if (personality) {
onChange(personality.personality);
}
}
};

const handleCustomInputChange = (e: Event) => {
const newValue = (e.target as HTMLTextAreaElement).value;
setCustomInput(newValue);
onChange(newValue);
};

return (
<div class="space-y-2">
<select
value={selectedOption}
onChange={handleSelectChange}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value="custom">Custom</option>
{personalities.map((p) => (
<option key={p.name} value={p.name}>{p.name}</option>
))}
</select>
{selectedOption === "custom" && (
<textarea
value={customInput}
onInput={handleCustomInputChange}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
maxLength={MAX_PERSONALITY_LENGTH}
rows={3}
placeholder="Enter custom personality..."
/>
)}
</div>
);
}
125 changes: 37 additions & 88 deletions islands/AgentSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useState } from "preact/hooks";
import { personalities, Personality } from "lib/debate/personalities.ts";
import CustomPersonalityInput from "components/CustomPersonalityInput.tsx";
import { MAX_NAME_LENGTH } from "lib/debate/inputValidation.ts";
import type { Personality } from "lib/debate/personalities.ts";
import { sanitizeInput } from "lib/utils.ts";
import { MAX_NAME_LENGTH, MAX_PERSONALITY_LENGTH } from "lib/debate/inputValidation.ts";
import { DEFAULT_VOICE } from "routes/api/voicesynth.tsx";

interface AgentSelectorProps {
agentDetails: Required<Personality>[];
Expand All @@ -12,14 +11,11 @@ interface AgentSelectorProps {
export default function AgentSelector(
{ agentDetails, setAgentDetails }: AgentSelectorProps,
) {
const [showCustomAgents, setShowCustomAgents] = useState(false);

const handlePersonalitySelect = (personality: Personality, index: number) => {
const handlePersonalityChange = (personality: string, index: number) => {
const newAgents = [...agentDetails];
newAgents[index] = {
...personality,
stance: newAgents[index].stance,
voice: personality.voice || newAgents[index].voice || DEFAULT_VOICE,
...newAgents[index],
personality,
};
setAgentDetails(newAgents);
};
Expand All @@ -34,10 +30,6 @@ export default function AgentSelector(
setAgentDetails(newAgents);
};

const toggleCustomAgents = () => {
setShowCustomAgents(!showCustomAgents);
};

return (
<div class="space-y-6">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6">
Expand All @@ -46,73 +38,37 @@ export default function AgentSelector(
agentDetails.map((agent, index) => (
<div key={index} class="bg-white shadow-md rounded-lg p-6">
<h4 class="text-lg font-semibold mb-3">Participant {index + 1}</h4>
{showCustomAgents
? (
<>
<div class="mb-3">
<label htmlFor={`agent-name-${index}`} class="block text-sm font-medium text-gray-700 mb-2">
Name:
</label>
<input
id={`agent-name-${index}`}
type="text"
value={agent.name}
onInput={(e) =>
handleAgentDetailChange(
index,
"name",
sanitizeInput((e.target as HTMLInputElement).value),
)}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
maxLength={MAX_NAME_LENGTH}
required
/>
</div>
<div class="mb-3">
<label
htmlFor={`agent-personality-${index}`}
class="block text-sm font-medium text-gray-700 mb-2"
>
Personality:
</label>
<textarea
id={`agent-personality-${index}`}
value={agent.personality}
onInput={(e) =>
handleAgentDetailChange(
index,
"personality",
(e.target as HTMLTextAreaElement).value,
)}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
maxLength={MAX_PERSONALITY_LENGTH}
required
/>
</div>
</>
)
: (
<div class="mb-3">
<label
htmlFor={`agent-personality-${index}`}
class="block text-sm font-medium text-gray-700 mb-2"
>
Personality:
</label>
<select
id={`agent-personality-${index}`}
value={agent.name}
onChange={(e) => {
const selected = personalities.find((p) => p.name === (e.target as HTMLSelectElement).value);
if (selected) handlePersonalitySelect(selected, index);
}}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
required
>
{personalities.map((p) => <option key={p.name} value={p.name}>{p.name}</option>)}
</select>
</div>
)}
<div class="mb-3">
<label htmlFor={`agent-name-${index}`} class="block text-sm font-medium text-gray-700 mb-2">
Name:
</label>
<input
id={`agent-name-${index}`}
type="text"
value={agent.name.split(" ")[1]}
onInput={(e) =>
handleAgentDetailChange(
index,
"name",
sanitizeInput((e.target as HTMLInputElement).value),
)}
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
maxLength={MAX_NAME_LENGTH}
required
/>
</div>
<div class="mb-3">
<label
htmlFor={`agent-personality-${index}`}
class="block text-sm font-medium text-gray-700 mb-2"
>
Personality:
</label>
<CustomPersonalityInput
value={agent.personality}
onChange={(value) => handlePersonalityChange(value, index)}
/>
</div>
<div class="mb-3">
<label htmlFor={`agent-stance-${index}`} class="block text-sm font-medium text-gray-700 mb-2">
Stance:
Expand Down Expand Up @@ -163,13 +119,6 @@ export default function AgentSelector(
)
: <p class="text-gray-600">No agents available. Please add agents to continue.</p>}
</div>
<button
type="button"
onClick={toggleCustomAgents}
class="px-4 py-2 bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-opacity-50 transition duration-150 ease-in-out"
>
{showCustomAgents ? "Use Predefined Personalities" : "Customize Agents"}
</button>
</div>
);
}

0 comments on commit 37e43e8

Please sign in to comment.