feat: multimodal AI event creation with image support #1
9
src/lib/constants.ts
Normal file
9
src/lib/constants.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/** Shared constants for image handling across the app. */
|
||||||
|
|
||||||
|
export const IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".webp"];
|
||||||
|
|
||||||
|
export const IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp"];
|
||||||
|
|
||||||
|
export const IMAGE_ACCEPT = IMAGE_MIME_TYPES.join(",");
|
||||||
|
|
||||||
|
export const MAX_IMAGE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
|
||||||
19
src/lib/json-utils.ts
Normal file
19
src/lib/json-utils.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Extract JSON from text that may contain prose, markdown code blocks, or raw JSON.
|
||||||
|
* Pure function — same input = same output, no side effects.
|
||||||
|
*/
|
||||||
|
export const extractJsonFromText = (text: string): unknown => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch {
|
||||||
|
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
||||||
|
if (codeBlockMatch) {
|
||||||
|
return JSON.parse(codeBlockMatch[1].trim());
|
||||||
|
}
|
||||||
|
const arrayMatch = text.match(/\[[\s\S]*\]/);
|
||||||
|
if (arrayMatch) {
|
||||||
|
return JSON.parse(arrayMatch[0]);
|
||||||
|
}
|
||||||
|
throw new Error("No JSON found in response");
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user