summaryrefslogtreecommitdiff
path: root/makima/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'makima/frontend/src')
-rw-r--r--makima/frontend/src/components/mesh/TaskOutput.tsx76
-rw-r--r--makima/frontend/src/lib/api.ts2
2 files changed, 67 insertions, 11 deletions
diff --git a/makima/frontend/src/components/mesh/TaskOutput.tsx b/makima/frontend/src/components/mesh/TaskOutput.tsx
index 7140c8a..c98b174 100644
--- a/makima/frontend/src/components/mesh/TaskOutput.tsx
+++ b/makima/frontend/src/components/mesh/TaskOutput.tsx
@@ -343,18 +343,48 @@ function SupervisorQuestionEntry({
const questionId = entry.toolInput?.question_id as string;
const choices = (entry.toolInput?.choices as string[]) || [];
const context = entry.toolInput?.context as string | null;
+ const multiSelect = (entry.toolInput?.multi_select as boolean) ?? false;
const [customInput, setCustomInput] = useState("");
const [showOther, setShowOther] = useState(false);
const [submitting, setSubmitting] = useState(false);
+ const [selectedChoices, setSelectedChoices] = useState<Set<string>>(new Set());
const isPending = pendingQuestionIds?.has(questionId) ?? false;
const handleChoiceSelect = async (choice: string) => {
if (!onAnswerQuestion || submitting) return;
+
+ if (multiSelect) {
+ // Toggle selection for multi-select mode
+ setSelectedChoices(prev => {
+ const newSet = new Set(prev);
+ if (newSet.has(choice)) {
+ newSet.delete(choice);
+ } else {
+ newSet.add(choice);
+ }
+ return newSet;
+ });
+ } else {
+ // Single select - submit immediately
+ setSubmitting(true);
+ try {
+ await onAnswerQuestion(questionId, choice);
+ } finally {
+ setSubmitting(false);
+ }
+ }
+ };
+
+ const handleMultiSelectSubmit = async () => {
+ if (!onAnswerQuestion || submitting || selectedChoices.size === 0) return;
setSubmitting(true);
try {
- await onAnswerQuestion(questionId, choice);
+ // Join selected choices with comma
+ const response = Array.from(selectedChoices).join(", ");
+ await onAnswerQuestion(questionId, response);
+ setSelectedChoices(new Set());
} finally {
setSubmitting(false);
}
@@ -376,6 +406,9 @@ function SupervisorQuestionEntry({
<div className="flex items-center gap-2 text-amber-400 font-semibold mb-2">
<span>?</span>
<span>Question</span>
+ {multiSelect && isPending && (
+ <span className="text-amber-300 text-xs font-normal">(select multiple)</span>
+ )}
{!isPending && (
<span className="text-green-400 text-xs font-normal">(Answered)</span>
)}
@@ -391,19 +424,40 @@ function SupervisorQuestionEntry({
<div className="space-y-2">
{choices.length > 0 && (
<div className="flex flex-wrap gap-2">
- {choices.map((choice, idx) => (
- <button
- key={idx}
- onClick={() => handleChoiceSelect(choice)}
- disabled={submitting}
- className="px-3 py-1.5 text-sm font-mono bg-amber-500/20 border border-amber-500/50 hover:bg-amber-500/30 disabled:opacity-50 text-amber-100 transition-colors"
- >
- {choice}
- </button>
- ))}
+ {choices.map((choice, idx) => {
+ const isSelected = selectedChoices.has(choice);
+ return (
+ <button
+ key={idx}
+ onClick={() => handleChoiceSelect(choice)}
+ disabled={submitting}
+ className={`px-3 py-1.5 text-sm font-mono border transition-colors disabled:opacity-50 ${
+ multiSelect && isSelected
+ ? "bg-amber-500/50 border-amber-400 text-amber-50"
+ : "bg-amber-500/20 border-amber-500/50 hover:bg-amber-500/30 text-amber-100"
+ }`}
+ >
+ {multiSelect && (
+ <span className="mr-1.5">{isSelected ? "✓" : "○"}</span>
+ )}
+ {choice}
+ </button>
+ );
+ })}
</div>
)}
+ {/* Submit button for multi-select mode */}
+ {multiSelect && selectedChoices.size > 0 && (
+ <button
+ onClick={handleMultiSelectSubmit}
+ disabled={submitting}
+ className="px-4 py-1.5 bg-amber-500 text-black text-sm font-medium rounded disabled:opacity-50 disabled:cursor-not-allowed transition-colors hover:bg-amber-400"
+ >
+ {submitting ? "Submitting..." : `Submit (${selectedChoices.size} selected)`}
+ </button>
+ )}
+
{/* Other option */}
{!showOther ? (
<button
diff --git a/makima/frontend/src/lib/api.ts b/makima/frontend/src/lib/api.ts
index 4652347..abf72b8 100644
--- a/makima/frontend/src/lib/api.ts
+++ b/makima/frontend/src/lib/api.ts
@@ -1948,6 +1948,8 @@ export interface PendingQuestion {
choices: string[];
context: string | null;
createdAt: string;
+ /** Whether multiple choices can be selected */
+ multiSelect?: boolean;
/** Question type - "general" for regular questions, "phase_confirmation" for phase transitions */
questionType?: "general" | "phase_confirmation";
/** Phase confirmation specific data (when questionType is "phase_confirmation") */