diff --git a/src/app/(dashboard)/dashboard/playground/components/StructuredOutputEditor.tsx b/src/app/(dashboard)/dashboard/playground/components/StructuredOutputEditor.tsx new file mode 100644 index 0000000000..f51ff4b16d --- /dev/null +++ b/src/app/(dashboard)/dashboard/playground/components/StructuredOutputEditor.tsx @@ -0,0 +1,143 @@ +"use client"; + +// src/app/(dashboard)/dashboard/playground/components/StructuredOutputEditor.tsx + +import { useState } from "react"; +import { useStructuredOutput } from "../hooks/useStructuredOutput"; +import type { StructuredOutputSchemaInput } from "../hooks/useStructuredOutput"; + +interface StructuredOutputEditorProps { + structuredOutput: ReturnType; +} + +const DEFAULT_SCHEMA: StructuredOutputSchemaInput = { + name: "my_schema", + schema: { + type: "object", + properties: { + result: { type: "string" }, + }, + required: ["result"], + }, + strict: true, +}; + +/** + * StructuredOutputEditor — toggle JSON mode on/off + edit JSON schema. + * + * When enabled, the Build tab sends response_format: { type: "json_schema", json_schema: {...} }. + * Schema validation is client-side via Zod StructuredOutputSchema (D9). + */ +export default function StructuredOutputEditor({ structuredOutput }: StructuredOutputEditorProps) { + const { enabled, schema, error, setEnabled, setSchema } = structuredOutput; + + const [schemaRaw, setSchemaRaw] = useState( + JSON.stringify(schema ?? DEFAULT_SCHEMA, null, 2), + ); + const [nameField, setNameField] = useState(schema?.name ?? "my_schema"); + const [parseError, setParseError] = useState(null); + + function handleValidate() { + let parsed: unknown; + try { + parsed = JSON.parse(schemaRaw); + } catch { + setParseError("Invalid JSON"); + return; + } + setParseError(null); + + // The parsed JSON should be the inner schema object (not the full response_format wrapper) + const input: StructuredOutputSchemaInput = { + name: nameField.trim() || "my_schema", + schema: parsed as Record, + strict: true, + }; + + setSchema(input); + } + + return ( +
+ {/* Toggle */} +
+
+ JSON mode + + Forces response_format: json_schema + +
+ +
+ + {/* Schema editor (shown only when enabled) */} + {enabled && ( +
+ {/* Schema name */} +
+ + setNameField(e.target.value)} + placeholder="my_schema" + className="text-xs bg-bg-alt border border-border rounded px-2 py-1.5 focus:outline-none focus:ring-1 focus:ring-primary text-text-main" + /> +
+ + {/* Schema JSON textarea */} +
+ +