Send revision notes with attached slides

This commit is contained in:
Codex 2026-06-09 11:54:35 -07:00
parent 6dc8e47eb6
commit e913fecd4c
2 changed files with 17 additions and 7 deletions

View file

@ -120,7 +120,10 @@ app.post("/api/decks/from-source", upload.single("source"), async (req, res, nex
const source = file ? await sourceFromUpload(file) : sourceFromText(pastedText); const source = file ? await sourceFromUpload(file) : sourceFromText(pastedText);
const result = await createDeckArtifacts({ const result = await createDeckArtifacts({
source, source,
instructions: stringField(req.body.instructions), instructions: combineInstructions(
stringField(req.body.instructions),
file && pastedText.trim() ? `Attached slide/deck update instructions:\n${pastedText.trim()}` : undefined
),
audience: stringField(req.body.audience) || "executives", audience: stringField(req.body.audience) || "executives",
styleId: stringField(req.body.style) || "incorta", styleId: stringField(req.body.style) || "incorta",
designTemplate: parseDesignTemplateField(req.body.designTemplate) designTemplate: parseDesignTemplateField(req.body.designTemplate)
@ -805,6 +808,11 @@ function stringField(value: unknown): string | undefined {
return typeof value === "string" && value.trim() ? value.trim() : undefined; return typeof value === "string" && value.trim() ? value.trim() : undefined;
} }
function combineInstructions(...values: Array<string | undefined>): string | undefined {
const parts = values.map((value) => value?.trim()).filter(Boolean);
return parts.length ? parts.join("\n\n") : undefined;
}
async function exists(targetPath: string): Promise<boolean> { async function exists(targetPath: string): Promise<boolean> {
try { try {
await access(targetPath); await access(targetPath);

View file

@ -196,6 +196,9 @@ function App() {
setFile(nextFile); setFile(nextFile);
setResult(null); setResult(null);
setError(null); setError(null);
if (nextFile && content.trim() === initialContent.trim()) {
setContent("");
}
if (nextFile?.type.startsWith("image/")) { if (nextFile?.type.startsWith("image/")) {
setPreviewUrl(URL.createObjectURL(nextFile)); setPreviewUrl(URL.createObjectURL(nextFile));
} else { } else {
@ -348,7 +351,8 @@ function App() {
selectedTemplate.layoutRules?.length ? `Layout rules:\n- ${selectedTemplate.layoutRules.join("\n- ")}` : "", selectedTemplate.layoutRules?.length ? `Layout rules:\n- ${selectedTemplate.layoutRules.join("\n- ")}` : "",
selectedTemplate.componentRules?.length ? `Component rules:\n- ${selectedTemplate.componentRules.join("\n- ")}` : "", selectedTemplate.componentRules?.length ? `Component rules:\n- ${selectedTemplate.componentRules.join("\n- ")}` : "",
selectedTemplate.slideFamilies?.length ? `Supported slide families: ${selectedTemplate.slideFamilies.join(", ")}.` : "", selectedTemplate.slideFamilies?.length ? `Supported slide families: ${selectedTemplate.slideFamilies.join(", ")}.` : "",
selectedTemplate.prompt ? `Reusable design prompt: ${selectedTemplate.prompt}` : "" selectedTemplate.prompt ? `Reusable design prompt: ${selectedTemplate.prompt}` : "",
file && content.trim() ? `Attached slide/deck update instructions:\n${content.trim()}` : ""
] ]
.filter(Boolean) .filter(Boolean)
.join("\n"); .join("\n");
@ -372,6 +376,7 @@ function App() {
formData.set("audience", "executives"); formData.set("audience", "executives");
formData.set("instructions", designAwareInstructions()); formData.set("instructions", designAwareInstructions());
formData.set("designTemplate", JSON.stringify(templateForRequest(selectedTemplate))); formData.set("designTemplate", JSON.stringify(templateForRequest(selectedTemplate)));
if (content.trim()) formData.set("content", content.trim());
return fetch("/api/decks/from-source", { return fetch("/api/decks/from-source", {
method: "POST", method: "POST",
body: formData body: formData
@ -724,14 +729,11 @@ function SourceInput(props: DeckPaneProps & { dropLabel: string; textLabel: stri
</label> </label>
<label className="field content"> <label className="field content">
<span>{props.textLabel}</span> <span>{props.file ? "Update instructions for attached slide / deck" : props.textLabel}</span>
<textarea <textarea
value={props.content} value={props.content}
onPaste={props.onPaste} onPaste={props.onPaste}
onChange={(event) => { onChange={(event) => props.onContent(event.target.value)}
props.onContent(event.target.value);
if (props.file) props.onFile(null);
}}
/> />
</label> </label>
</> </>