diff --git a/CHANGELOG.md b/CHANGELOG.md index 7024df5..d9cf7f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ * SRP/DRY check: Pass - changelog content is centralized in one file with no duplication across docs. --> +## [Version 0.4.37] - 2025-11-06 04:11 UTC + +### Added +- Launched the ARC Agent Workspace with ARC-specific run intake, timeline, conversation, and artifact components powered by the new agent modules.@client/src/pages/arc-agent-workspace.tsx@client/src/components/agent/ArcAgentRunForm.tsx@client/src/components/agent/ArcStageTimeline.tsx@client/src/components/agent/ArcConversationLog.tsx@client/src/components/agent/ArcArtifactPanel.tsx@client/src/components/agent/ArcRunControls.tsx +- Documented the workspace transition plan for ongoing iterations.@docs/2025-11-06-plan-arc-agent-workspace.md + +### Changed +- Updated navigation, shared types, and agent infrastructure to adopt ARC-focused terminology, stages, and configuration defaults.@client/src/App.tsx@client/src/components/AppNavigation.tsx@client/src/stores/useLuigiWorkspaceStore.ts@shared/luigi-types.ts@server/routes/luigi.ts@server/luigi/executor.ts@server/luigi/openai-sdk-runner.ts@server/config.ts + ## [Version 0.4.36] - 2025-11-06 03:45 UTC ### Added diff --git a/client/src/App.tsx b/client/src/App.tsx index 8939905..72d82a4 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,3 +1,10 @@ +/* + * Author: gpt-5-codex + * Date: 2025-11-06T04:08:30Z + * PURPOSE: Application router with ARC agent workspace route updates. + * SRP/DRY check: Pass - maintains route mapping without duplicating page logic. + */ + import { Switch, Route } from "wouter"; import { queryClient } from "./lib/queryClient"; import { QueryClientProvider } from "@tanstack/react-query"; @@ -10,7 +17,7 @@ import Home from "@/pages/home"; import Battle from "@/pages/battle-chat"; import CreativeCombat from "./pages/creative-combat"; import Debate from "@/pages/debate"; -import ResearchSynthesis from "@/pages/research-synthesis"; +import ArcAgentWorkspace from "@/pages/arc-agent-workspace"; import PlanAssessmentPage from "@/pages/plan-assessment"; import NotFound from "@/pages/not-found"; import BillingPage from "@/pages/billing"; @@ -27,7 +34,7 @@ function Router() { - + @@ -36,7 +43,6 @@ function Router() { } function App() { - // Generate unique favicon for this tab/session useSimpleDynamicFavicon(); return ( diff --git a/client/src/components/AppNavigation.tsx b/client/src/components/AppNavigation.tsx index 4055b4b..b863a4a 100644 --- a/client/src/components/AppNavigation.tsx +++ b/client/src/components/AppNavigation.tsx @@ -1,12 +1,10 @@ -/** - * Author: Claude Code using Sonnet 4 - * Date: 2025-01-14 - * PURPOSE: Modernized AppNavigation component using advanced shadcn/ui components. - * Uses NavigationMenu, Breadcrumb, Switch, and other shadcn/ui primitives for professional UI. - * Maintains consistent navigation patterns while improving responsive design. - * SRP/DRY check: Pass - Single responsibility (navigation), reuses shadcn/ui components - * shadcn/ui: Pass - Uses NavigationMenu, Breadcrumb, Switch, and other shadcn/ui components - */ +/** + * Author: gpt-5-codex (building on Claude Code using Sonnet 4) + * Date: 2025-11-06T04:08:45Z + * PURPOSE: AppNavigation component with ARC agent workspace entry using shadcn/ui primitives. + * SRP/DRY check: Pass - Single navigation responsibility while extending existing mode registry. + * shadcn/ui: Pass - continues leveraging NavigationMenu, Breadcrumb, Switch, and related primitives. + */ import { Link, useLocation } from "wouter"; import { Button } from "@/components/ui/button"; @@ -86,14 +84,14 @@ const navigationModes: NavigationMode[] = [ description: "Critique a plan across models", category: 'advanced' }, - { - id: "research-synthesis", - name: "Research", - path: "/research-synthesis", - icon: Users, - description: "Collaborative research synthesis", - category: 'advanced' - }, + { + id: "arc-agent", + name: "ARC Workspace", + path: "/arc-agent", + icon: Users, + description: "ARC agent orchestration workspace", + category: 'advanced' + }, { id: "vixra", name: "Vixra", diff --git a/client/src/components/agent/ArcAgentRunForm.tsx b/client/src/components/agent/ArcAgentRunForm.tsx new file mode 100644 index 0000000..506f535 --- /dev/null +++ b/client/src/components/agent/ArcAgentRunForm.tsx @@ -0,0 +1,224 @@ +/* + * Author: gpt-5-codex + * Date: 2025-11-06T04:05:00Z + * PURPOSE: ARC agent workspace intake form capturing task context and validating ARC grid JSON before launching runs. + * SRP/DRY check: Pass - handles only form presentation and payload normalization, delegating persistence to store/hooks. + */ + +import { useState, useEffect } from 'react'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { useLuigiWorkspaceStore } from '@/stores/useLuigiWorkspaceStore'; +import type { ArcExample, CreateLuigiRunRequest } from '@shared/luigi-types'; + +const gridSchema = z + .array(z.array(z.number().int().min(0).max(9)).min(1)) + .min(1, 'ARC grids must contain at least one row.'); + +const exampleSchema: z.ZodType = z.object({ + input: gridSchema, + output: gridSchema.optional(), +}); + +const trainingExamplesSchema = z + .string() + .min(5, 'Provide at least one training pair.') + .transform((value, ctx) => { + try { + const parsed = JSON.parse(value) as unknown; + const examples = z.array(exampleSchema).min(1).parse(parsed); + return examples; + } catch (error) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: + 'Training pairs must be valid JSON: an array of { "input": number[][], "output": number[][] } records with digits 0-9.', + }); + return z.NEVER; + } + }); + +const evaluationExampleSchema = z + .string() + .optional() + .transform((value, ctx) => { + if (!value) return undefined; + try { + const parsed = JSON.parse(value) as unknown; + return exampleSchema.parse(parsed); + } catch (error) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: + 'Evaluation grid must be valid JSON describing a single { "input": number[][], "output"?: number[][] } object.', + }); + return z.NEVER; + } + }); + +const formSchema = z.object({ + taskId: z.string().min(3, 'Task ID must be at least 3 characters.'), + analysisBrief: z + .string() + .min(10, 'Describe the analysis goal so the ARC agent understands the mission.'), + trainingPairs: trainingExamplesSchema, + evaluationInput: evaluationExampleSchema, + workspaceNotes: z.string().optional(), +}); + +type FormValues = z.input; + +export interface ArcAgentRunFormProps { + className?: string; + isSubmitting?: boolean; + onSubmit: (payload: CreateLuigiRunRequest) => void; +} + +export function ArcAgentRunForm({ className, isSubmitting, onSubmit }: ArcAgentRunFormProps) { + const formStateSnapshot = useLuigiWorkspaceStore((state) => state.form); + const setFormField = useLuigiWorkspaceStore((state) => state.setFormField); + const resetForm = useLuigiWorkspaceStore((state) => state.resetForm); + + const [submitError, setSubmitError] = useState(); + + const { + register, + handleSubmit, + reset, + formState: { errors }, + } = useForm({ + resolver: zodResolver(formSchema), + defaultValues: formStateSnapshot, + }); + + useEffect(() => { + reset(formStateSnapshot); + }, [formStateSnapshot, reset]); + + const registerField = (field: K) => + register(field, { + onChange: (event) => { + const value = (event.target as HTMLInputElement | HTMLTextAreaElement).value; + setFormField(field, value); + }, + }); + + const submit = (values: FormValues) => { + setSubmitError(undefined); + const parsed = formSchema.safeParse(values); + if (!parsed.success) { + setSubmitError('Fix validation errors before launching the ARC agent.'); + return; + } + + onSubmit({ + taskId: parsed.data.taskId.trim(), + analysisBrief: parsed.data.analysisBrief.trim(), + trainingExamples: parsed.data.trainingPairs, + evaluationExample: parsed.data.evaluationInput, + workspaceNotes: parsed.data.workspaceNotes?.trim() || undefined, + }); + }; + + const handleClear = () => { + resetForm(); + reset({ + taskId: '', + analysisBrief: '', + trainingPairs: '', + evaluationInput: '', + workspaceNotes: '', + }); + setSubmitError(undefined); + }; + + return ( + + + Launch ARC Agent + + +
+
+ + + {errors.taskId &&

{errors.taskId.message}

} +
+ +
+ +