@slopmachine/core 0.1.26 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { AspectRatio as ImageAspectRatio, VideoAspectRatio } from \"@pixerate/schemas\";\nexport type { ImageAspectRatio };\n\nexport interface SlopImageOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n */\n bucketId: string;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated image\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n * Common values: \"1:1\", \"16:9\", \"9:16\", \"4:3\", \"3:4\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A photo of a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The target quality (\"fast\" or \"high\"). Only affects new generations and is ignored for caching.\n * Ignored if `model` is provided.\n * Defaults to \"fast\".\n */\n quality?: \"fast\" | \"high\";\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * If `true` (or `?raw=true`), bypasses the WebP optimized media and returns the original generated file (e.g., PNG/JPEG).\n * Defaults to false.\n */\n original?: boolean;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\nexport function interpolatePrompt(\n prompt?: string,\n variables?: Record<string, string | number | undefined | null>,\n): string {\n if (!prompt) return \"\";\n let text = prompt;\n if (!variables) return text;\n\n Object.keys(variables).forEach((key) => {\n const value = variables[key];\n if (value !== undefined && value !== null) {\n text = text.replace(new RegExp(`\\\\{${key}\\\\}`, \"g\"), String(value));\n }\n });\n return text;\n}\n\n/**\n * Builds a URL to render or retrieve an image from Slop Machine.\n *\n * @param options - Configuration options for the image generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildImageUrl(options: SlopImageOptions): string {\n const {\n bucketId,\n version,\n resultId,\n aspectRatio = \"1:1\",\n quality = \"fast\",\n variables = {},\n baseUrl = \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderImage\",\n original,\n attachments,\n } = options;\n\n const params = new URLSearchParams();\n params.set(\"bucketId\", bucketId);\n\n if (!resultId) {\n if (aspectRatio) {\n params.set(\"aspectRatio\", aspectRatio);\n }\n if (version) {\n params.set(\"version\", String(version));\n }\n if (quality && quality !== \"fast\") {\n params.set(\"quality\", quality);\n } else if (quality === \"fast\") {\n params.set(\"quality\", \"fast\");\n }\n\n if (original) {\n params.set(\"original\", \"true\");\n }\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${baseUrl}?${params.toString()}`;\n}\n\n/**\n * Preloads an image from Slop Machine into the browser's cache.\n * Useful for ensuring images are ready before displaying them.\n *\n * @param options - Configuration options for the image generation.\n * @returns A promise that resolves when the image has been loaded.\n */\nexport function preloadImage(options: SlopImageOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n const img = new Image();\n img.onload = () => resolve();\n img.onerror = (err) => reject(err);\n img.src = buildImageUrl(options);\n });\n}\n\nexport type { VideoAspectRatio };\n\nexport interface SlopVideoOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n */\n bucketId: string;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated video\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n * Common values: \"1:1\", \"16:9\", \"9:16\", \"4:3\", \"3:4\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A video of a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The duration of the generated video in seconds.\n * Must be between 4 and 8. Defaults to 4.\n */\n duration?: number;\n /**\n * The target quality (\"fast\" or \"high\"). Only affects new generations and is ignored for caching.\n * Ignored if `model` is provided.\n * Defaults to \"fast\".\n */\n quality?: \"fast\" | \"high\";\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * If `true` (or `?raw=true`), bypasses the WebP optimized media and returns the original generated file.\n * Defaults to false.\n */\n original?: boolean;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\n/**\n * Builds a URL to render or retrieve a video from Slop Machine.\n *\n * @param options - Configuration options for the video generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildVideoUrl(options: SlopVideoOptions): string {\n const {\n bucketId,\n version,\n resultId,\n aspectRatio = \"16:9\",\n quality = \"fast\",\n variables = {},\n duration = 4,\n baseUrl = \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderVideo\",\n original,\n attachments,\n } = options;\n\n const params = new URLSearchParams();\n params.set(\"bucketId\", bucketId);\n\n if (!resultId) {\n if (aspectRatio) {\n params.set(\"aspectRatio\", aspectRatio);\n }\n if (version) {\n params.set(\"version\", String(version));\n }\n if (duration) {\n params.set(\"duration\", String(duration));\n }\n if (quality) {\n params.set(\"quality\", quality);\n }\n\n if (original) {\n params.set(\"original\", \"true\");\n }\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${baseUrl}?${params.toString()}`;\n}\n\n/**\n * Preloads a video from Slop Machine into the browser's cache.\n * Useful for ensuring videos are ready before displaying them.\n *\n * @param options - Configuration options for the video generation.\n * @returns A promise that resolves when the video preload request has been initiated.\n */\nexport function preloadVideo(options: SlopVideoOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n // We can just fetch the URL to preload it into the browser's cache.\n // We use no-cors to avoid CORS errors for simple preloads\n fetch(buildVideoUrl(options), { mode: \"no-cors\" })\n .then(() => resolve())\n .catch((err) => reject(err));\n });\n}\n\nexport interface SlopTextOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n */\n bucketId: string;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated text\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A story about a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\n/**\n * Builds a URL to render or retrieve text from Slop Machine.\n *\n * @param options - Configuration options for the text generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildTextUrl(options: SlopTextOptions): string {\n const {\n bucketId,\n version,\n resultId,\n variables = {},\n baseUrl = \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderText\",\n attachments,\n } = options;\n\n const params = new URLSearchParams();\n params.set(\"bucketId\", bucketId);\n\n if (!resultId) {\n if (version) {\n params.set(\"version\", String(version));\n }\n if (resultId) {\n params.set(\"resultId\", resultId);\n }\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${baseUrl}?${params.toString()}`;\n}\n\n/**\n * Preloads text from Slop Machine into the browser's cache.\n * Useful for ensuring text is ready before displaying it.\n *\n * @param options - Configuration options for the text generation.\n * @returns A promise that resolves when the text preload request has been initiated.\n */\nexport function preloadText(options: SlopTextOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n // Fetch the URL to preload it into the browser's cache.\n // We use no-cors to avoid CORS errors for simple preloads\n fetch(buildTextUrl(options), { mode: \"no-cors\" })\n .then(() => resolve())\n .catch((err) => reject(err));\n });\n}\n\n/**\n * Uploads a base64 encoded file as a temporary attachment to be used in generation requests.\n *\n * @param base64 - The base64 encoded file data (without the data:mime/type;base64, prefix).\n * @param mimeType - The MIME type of the file.\n * @returns A promise that resolves to an object containing the URL of the uploaded attachment.\n */\nexport async function uploadTempAttachment(\n base64: string,\n mimeType: string,\n): Promise<{ url: string }> {\n const response = await fetch(\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/uploadTempAttachment\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ data: { base64, mimeType } }),\n },\n );\n if (!response.ok) {\n throw new Error(`Failed to upload attachment: ${response.statusText}`);\n }\n const json = await response.json();\n if (json.error) {\n throw new Error(\n `Failed to upload attachment: ${json.error.message || JSON.stringify(json.error)}`,\n );\n }\n return { url: json.result.url };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { AspectRatio as ImageAspectRatio, VideoAspectRatio } from \"@pixerate/schemas\";\nexport type { ImageAspectRatio, VideoAspectRatio };\n\nexport interface PipelineStepResult {\n stepId: string;\n stepName?: string;\n type: string;\n outputUrl?: string;\n outputText?: string;\n outputData?: any;\n computeTimeMs?: number;\n fuelCost?: number;\n error?: string;\n}\n\nexport interface PipelineResult {\n id: string;\n pipelineId: string;\n siloId: string;\n url?: string;\n text?: string;\n data?: any;\n resultType: string;\n status: \"completed\" | \"failed\" | \"pending\";\n stepResults: PipelineStepResult[];\n totalComputeTimeMs: number;\n totalFuelCost: number;\n metadata?: Record<string, any>;\n timestamp: any;\n error?: string;\n}\n\nexport interface SlopPipelineOptions {\n /**\n * The unique identifier of the pipeline to execute.\n */\n pipelineId: string;\n /**\n * Optional silo identifier for direct pipeline path resolution.\n */\n siloId?: string;\n /**\n * Dynamic runtime prompt to feed into the pipeline.\n */\n prompt?: string;\n /**\n * Variables to interpolate into prompt or step configs.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * Arbitrary user metadata to attach to the pipeline result document.\n */\n metadata?: Record<string, any>;\n /**\n * Whether to wait for full execution (default true) or return a job ID immediately.\n */\n sync?: boolean;\n /**\n * Whether to redirect to the primary media output URL upon completion.\n */\n redirect?: boolean;\n /**\n * Result ID to retrieve a specific previously generated result.\n */\n resultId?: string;\n /**\n * Base URL for the renderPipeline cloud function endpoint.\n */\n baseUrl?: string;\n}\n\nexport interface ExecutePipelineOptions {\n /**\n * The unique identifier of the pipeline to execute.\n */\n pipelineId: string;\n /**\n * Optional silo identifier for direct pipeline path resolution.\n */\n siloId?: string;\n /**\n * Dynamic runtime prompt to feed into the pipeline.\n */\n prompt?: string;\n /**\n * Variables to interpolate into prompt or step configs.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * Arbitrary user metadata to attach to the pipeline result document.\n */\n metadata?: Record<string, any>;\n /**\n * Base URL for the renderPipeline cloud function endpoint.\n */\n baseUrl?: string;\n}\n\nexport interface SlopImageOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n * Required when using a bucket unless pipelineId is provided.\n */\n bucketId?: string;\n /**\n * The unique identifier of your Slop Machine pipeline.\n * Required when targeting a pipeline instead of a bucket.\n */\n pipelineId?: string;\n /**\n * Optional silo identifier.\n */\n siloId?: string;\n /**\n * Dynamic runtime prompt (used when targeting a pipeline).\n */\n prompt?: string;\n /**\n * Arbitrary user metadata to attach to the generation request / result document.\n */\n metadata?: Record<string, any>;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated image\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * The aspect ratio of the generated image. Defaults to \"1:1\".\n * Common values: \"1:1\", \"16:9\", \"9:16\", \"4:3\", \"3:4\".\n */\n aspectRatio?: ImageAspectRatio;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A photo of a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The target quality (\"fast\" or \"high\"). Only affects new generations and is ignored for caching.\n * Ignored if `model` is provided.\n * Defaults to \"fast\".\n */\n quality?: \"fast\" | \"high\";\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * If `true` (or `?raw=true`), bypasses the WebP optimized media and returns the original generated file (e.g., PNG/JPEG).\n * Defaults to false.\n */\n original?: boolean;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\nexport function interpolatePrompt(\n prompt?: string,\n variables?: Record<string, string | number | undefined | null>,\n): string {\n if (!prompt) return \"\";\n let text = prompt;\n if (!variables) return text;\n\n Object.keys(variables).forEach((key) => {\n const value = variables[key];\n if (value !== undefined && value !== null) {\n text = text.replace(new RegExp(`\\\\{${key}\\\\}`, \"g\"), String(value));\n }\n });\n return text;\n}\n\n/**\n * Builds a URL to render or retrieve an image from Slop Machine.\n *\n * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).\n *\n * @param options - Configuration options for the image generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildImageUrl(options: SlopImageOptions): string {\n const {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n aspectRatio = \"1:1\",\n quality = \"fast\",\n variables = {},\n baseUrl,\n original,\n attachments,\n } = options;\n\n if (pipelineId) {\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline\";\n const params = new URLSearchParams();\n params.set(\"pipelineId\", pipelineId);\n params.set(\"redirect\", \"true\");\n\n if (siloId) params.set(\"siloId\", siloId);\n if (prompt) params.set(\"prompt\", prompt);\n if (resultId) params.set(\"resultId\", resultId);\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n return `${endpoint}?${params.toString()}`;\n }\n\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderImage\";\n const params = new URLSearchParams();\n if (bucketId) {\n params.set(\"bucketId\", bucketId);\n }\n\n if (!resultId) {\n if (aspectRatio) {\n params.set(\"aspectRatio\", aspectRatio);\n }\n if (version) {\n params.set(\"version\", String(version));\n }\n if (quality && quality !== \"fast\") {\n params.set(\"quality\", quality);\n } else if (quality === \"fast\") {\n params.set(\"quality\", \"fast\");\n }\n\n if (original) {\n params.set(\"original\", \"true\");\n }\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${endpoint}?${params.toString()}`;\n}\n\n/**\n * Preloads an image from Slop Machine into the browser's cache.\n * Useful for ensuring images are ready before displaying them.\n *\n * @param options - Configuration options for the image generation.\n * @returns A promise that resolves when the image has been loaded.\n */\nexport function preloadImage(options: SlopImageOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n const img = new Image();\n img.onload = () => resolve();\n img.onerror = (err) => reject(err);\n img.src = buildImageUrl(options);\n });\n}\n\nexport interface SlopVideoOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n * Required when using a bucket unless pipelineId is provided.\n */\n bucketId?: string;\n /**\n * The unique identifier of your Slop Machine pipeline.\n * Required when targeting a pipeline instead of a bucket.\n */\n pipelineId?: string;\n /**\n * Optional silo identifier.\n */\n siloId?: string;\n /**\n * Dynamic runtime prompt (used when targeting a pipeline).\n */\n prompt?: string;\n /**\n * Arbitrary user metadata to attach to the generation request / result document.\n */\n metadata?: Record<string, any>;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated video\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * The aspect ratio of the generated video. Defaults to \"16:9\".\n * Common values: \"1:1\", \"16:9\", \"9:16\", \"4:3\", \"3:4\".\n */\n aspectRatio?: VideoAspectRatio;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A video of a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The duration of the generated video in seconds.\n * Must be between 4 and 8. Defaults to 4.\n */\n duration?: number;\n /**\n * The target quality (\"fast\" or \"high\"). Only affects new generations and is ignored for caching.\n * Ignored if `model` is provided.\n * Defaults to \"fast\".\n */\n quality?: \"fast\" | \"high\";\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * If `true` (or `?raw=true`), bypasses the WebP optimized media and returns the original generated file.\n * Defaults to false.\n */\n original?: boolean;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\n/**\n * Builds a URL to render or retrieve a video from Slop Machine.\n *\n * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).\n *\n * @param options - Configuration options for the video generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildVideoUrl(options: SlopVideoOptions): string {\n const {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n aspectRatio = \"16:9\",\n quality = \"fast\",\n variables = {},\n duration = 4,\n baseUrl,\n original,\n attachments,\n } = options;\n\n if (pipelineId) {\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline\";\n const params = new URLSearchParams();\n params.set(\"pipelineId\", pipelineId);\n params.set(\"redirect\", \"true\");\n\n if (siloId) params.set(\"siloId\", siloId);\n if (prompt) params.set(\"prompt\", prompt);\n if (resultId) params.set(\"resultId\", resultId);\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n return `${endpoint}?${params.toString()}`;\n }\n\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderVideo\";\n const params = new URLSearchParams();\n if (bucketId) {\n params.set(\"bucketId\", bucketId);\n }\n\n if (!resultId) {\n if (aspectRatio) {\n params.set(\"aspectRatio\", aspectRatio);\n }\n if (version) {\n params.set(\"version\", String(version));\n }\n if (duration) {\n params.set(\"duration\", String(duration));\n }\n if (quality) {\n params.set(\"quality\", quality);\n }\n\n if (original) {\n params.set(\"original\", \"true\");\n }\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${endpoint}?${params.toString()}`;\n}\n\n/**\n * Preloads a video from Slop Machine into the browser's cache.\n * Useful for ensuring videos are ready before displaying them.\n *\n * @param options - Configuration options for the video generation.\n * @returns A promise that resolves when the video preload request has been initiated.\n */\nexport function preloadVideo(options: SlopVideoOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n fetch(buildVideoUrl(options), { mode: \"no-cors\" })\n .then(() => resolve())\n .catch((err) => reject(err));\n });\n}\n\nexport interface SlopTextOptions {\n /**\n * The unique identifier of your Slop Machine bucket.\n * Required when using a bucket unless pipelineId is provided.\n */\n bucketId?: string;\n /**\n * The unique identifier of your Slop Machine pipeline.\n * Required when targeting a pipeline instead of a bucket.\n */\n pipelineId?: string;\n /**\n * Optional silo identifier.\n */\n siloId?: string;\n /**\n * Dynamic runtime prompt (used when targeting a pipeline).\n */\n prompt?: string;\n /**\n * Arbitrary user metadata to attach to the generation request / result document.\n */\n metadata?: Record<string, any>;\n /**\n * The specific version of the prompt/settings to use.\n * If omitted, the latest version will be used.\n */\n version?: number;\n /**\n * Result ID to retrieve a specific previously generated text\n * instead of generating a new one.\n */\n resultId?: string;\n /**\n * Dynamic variables to interpolate into the prompt.\n * E.g., if prompt is \"A story about a {color} dog\", pass { color: \"brown\" }.\n */\n variables?: Record<string, string | number | undefined | null>;\n /**\n * The base URL for the Slop Machine API.\n * Defaults to the production URL. Useful for testing against local deployments.\n */\n baseUrl?: string;\n /**\n * Array of attachment URLs to include with the request.\n */\n attachments?: string[];\n}\n\n/**\n * Builds a URL to render or retrieve text from Slop Machine.\n *\n * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).\n *\n * @param options - Configuration options for the text generation.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildTextUrl(options: SlopTextOptions): string {\n const {\n bucketId,\n pipelineId,\n siloId,\n prompt,\n metadata,\n version,\n resultId,\n variables = {},\n baseUrl,\n attachments,\n } = options;\n\n if (pipelineId) {\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline\";\n const params = new URLSearchParams();\n params.set(\"pipelineId\", pipelineId);\n params.set(\"sync\", \"true\");\n\n if (siloId) params.set(\"siloId\", siloId);\n if (prompt) params.set(\"prompt\", prompt);\n if (resultId) params.set(\"resultId\", resultId);\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n return `${endpoint}?${params.toString()}`;\n }\n\n const endpoint =\n baseUrl ||\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderText\";\n const params = new URLSearchParams();\n if (bucketId) {\n params.set(\"bucketId\", bucketId);\n }\n\n if (!resultId) {\n if (version) {\n params.set(\"version\", String(version));\n }\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n if (metadata && Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n if (attachments && attachments.length > 0) {\n params.set(\"attachments\", JSON.stringify(attachments));\n }\n } else {\n params.set(\"resultId\", resultId);\n }\n\n return `${endpoint}?${params.toString()}`;\n}\n\n/**\n * Preloads text from Slop Machine into the browser's cache.\n * Useful for ensuring text is ready before displaying it.\n *\n * @param options - Configuration options for the text generation.\n * @returns A promise that resolves when the text preload request has been initiated.\n */\nexport function preloadText(options: SlopTextOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof window === \"undefined\") {\n resolve();\n return;\n }\n\n fetch(buildTextUrl(options), { mode: \"no-cors\" })\n .then(() => resolve())\n .catch((err) => reject(err));\n });\n}\n\n/**\n * Builds a URL to execute or inspect a multi-step Pipeline from Slop Machine.\n *\n * @param options - Configuration options for the pipeline execution.\n * @returns A string containing the fully constructed URL.\n */\nexport function buildPipelineUrl(options: SlopPipelineOptions): string {\n const {\n pipelineId,\n siloId,\n prompt,\n variables = {},\n metadata = {},\n sync = true,\n redirect = false,\n resultId,\n baseUrl = \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline\",\n } = options;\n\n const params = new URLSearchParams();\n params.set(\"pipelineId\", pipelineId);\n\n if (siloId) params.set(\"siloId\", siloId);\n if (prompt) params.set(\"prompt\", prompt);\n if (resultId) params.set(\"resultId\", resultId);\n if (sync !== undefined) params.set(\"sync\", String(sync));\n if (redirect) params.set(\"redirect\", \"true\");\n\n if (Object.keys(variables).length > 0) {\n params.set(\"variables\", JSON.stringify(variables));\n }\n if (Object.keys(metadata).length > 0) {\n params.set(\"metadata\", JSON.stringify(metadata));\n }\n\n return `${baseUrl}?${params.toString()}`;\n}\n\n/**\n * Executes a Slop Machine multi-step Pipeline programmatically and returns the full typed result payload.\n *\n * @param options - Execution parameters including the pipelineId and runtime prompt/variables/metadata.\n * @returns A promise resolving to the completed PipelineResult document.\n */\nexport async function executePipeline(\n options: ExecutePipelineOptions,\n): Promise<PipelineResult> {\n const {\n pipelineId,\n siloId,\n prompt,\n variables,\n metadata,\n baseUrl = \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline\",\n } = options;\n\n const response = await fetch(baseUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n pipelineId,\n ...(siloId ? { siloId } : {}),\n ...(prompt ? { prompt } : {}),\n variables,\n metadata,\n sync: true,\n }),\n });\n\n if (!response.ok) {\n let errorDetail = response.statusText;\n try {\n const errorJson = await response.json();\n if (errorJson.error) {\n errorDetail = errorJson.error;\n }\n } catch {\n // Use statusText\n }\n throw new Error(\n `Pipeline execution failed (${response.status}): ${errorDetail}`,\n );\n }\n\n return (await response.json()) as PipelineResult;\n}\n\n/**\n * Uploads a base64 encoded file as a temporary attachment to be used in generation requests.\n *\n * @param base64 - The base64 encoded file data (without the data:mime/type;base64, prefix).\n * @param mimeType - The MIME type of the file.\n * @returns A promise that resolves to an object containing the URL of the uploaded attachment.\n */\nexport async function uploadTempAttachment(\n base64: string,\n mimeType: string,\n): Promise<{ url: string }> {\n const response = await fetch(\n \"https://us-central1-slopmachine-12bfb.cloudfunctions.net/uploadTempAttachment\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ data: { base64, mimeType } }),\n },\n );\n if (!response.ok) {\n throw new Error(`Failed to upload attachment: ${response.statusText}`);\n }\n const json = await response.json();\n if (json.error) {\n throw new Error(\n `Failed to upload attachment: ${json.error.message || JSON.stringify(json.error)}`,\n );\n }\n return { url: json.result.url };\n}\n"],"mappings":"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","names":["endpoint","params"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slopmachine/core",
3
- "version": "0.1.26",
3
+ "version": "0.2.0",
4
4
  "description": "The official Core / VanillaJS SDK for Slop Machine",
5
5
  "llms": "https://docs.slopmachine.dev/llms.txt",
6
6
  "llmsFull": "https://docs.slopmachine.dev/llms-full.txt",
@@ -28,7 +28,7 @@
28
28
  "typescript": "^5.0.0"
29
29
  },
30
30
  "dependencies": {
31
- "@pixerate/schemas": "^1.0.0"
31
+ "@pixerate/schemas": "^1.1.0"
32
32
  },
33
33
  "license": "MIT"
34
34
  }
package/src/index.ts CHANGED
@@ -1,11 +1,124 @@
1
1
  import { AspectRatio as ImageAspectRatio, VideoAspectRatio } from "@pixerate/schemas";
2
- export type { ImageAspectRatio };
2
+ export type { ImageAspectRatio, VideoAspectRatio };
3
+
4
+ export interface PipelineStepResult {
5
+ stepId: string;
6
+ stepName?: string;
7
+ type: string;
8
+ outputUrl?: string;
9
+ outputText?: string;
10
+ outputData?: any;
11
+ computeTimeMs?: number;
12
+ fuelCost?: number;
13
+ error?: string;
14
+ }
15
+
16
+ export interface PipelineResult {
17
+ id: string;
18
+ pipelineId: string;
19
+ siloId: string;
20
+ url?: string;
21
+ text?: string;
22
+ data?: any;
23
+ resultType: string;
24
+ status: "completed" | "failed" | "pending";
25
+ stepResults: PipelineStepResult[];
26
+ totalComputeTimeMs: number;
27
+ totalFuelCost: number;
28
+ metadata?: Record<string, any>;
29
+ timestamp: any;
30
+ error?: string;
31
+ }
32
+
33
+ export interface SlopPipelineOptions {
34
+ /**
35
+ * The unique identifier of the pipeline to execute.
36
+ */
37
+ pipelineId: string;
38
+ /**
39
+ * Optional silo identifier for direct pipeline path resolution.
40
+ */
41
+ siloId?: string;
42
+ /**
43
+ * Dynamic runtime prompt to feed into the pipeline.
44
+ */
45
+ prompt?: string;
46
+ /**
47
+ * Variables to interpolate into prompt or step configs.
48
+ */
49
+ variables?: Record<string, string | number | undefined | null>;
50
+ /**
51
+ * Arbitrary user metadata to attach to the pipeline result document.
52
+ */
53
+ metadata?: Record<string, any>;
54
+ /**
55
+ * Whether to wait for full execution (default true) or return a job ID immediately.
56
+ */
57
+ sync?: boolean;
58
+ /**
59
+ * Whether to redirect to the primary media output URL upon completion.
60
+ */
61
+ redirect?: boolean;
62
+ /**
63
+ * Result ID to retrieve a specific previously generated result.
64
+ */
65
+ resultId?: string;
66
+ /**
67
+ * Base URL for the renderPipeline cloud function endpoint.
68
+ */
69
+ baseUrl?: string;
70
+ }
71
+
72
+ export interface ExecutePipelineOptions {
73
+ /**
74
+ * The unique identifier of the pipeline to execute.
75
+ */
76
+ pipelineId: string;
77
+ /**
78
+ * Optional silo identifier for direct pipeline path resolution.
79
+ */
80
+ siloId?: string;
81
+ /**
82
+ * Dynamic runtime prompt to feed into the pipeline.
83
+ */
84
+ prompt?: string;
85
+ /**
86
+ * Variables to interpolate into prompt or step configs.
87
+ */
88
+ variables?: Record<string, string | number | undefined | null>;
89
+ /**
90
+ * Arbitrary user metadata to attach to the pipeline result document.
91
+ */
92
+ metadata?: Record<string, any>;
93
+ /**
94
+ * Base URL for the renderPipeline cloud function endpoint.
95
+ */
96
+ baseUrl?: string;
97
+ }
3
98
 
4
99
  export interface SlopImageOptions {
5
100
  /**
6
101
  * The unique identifier of your Slop Machine bucket.
102
+ * Required when using a bucket unless pipelineId is provided.
103
+ */
104
+ bucketId?: string;
105
+ /**
106
+ * The unique identifier of your Slop Machine pipeline.
107
+ * Required when targeting a pipeline instead of a bucket.
108
+ */
109
+ pipelineId?: string;
110
+ /**
111
+ * Optional silo identifier.
7
112
  */
8
- bucketId: string;
113
+ siloId?: string;
114
+ /**
115
+ * Dynamic runtime prompt (used when targeting a pipeline).
116
+ */
117
+ prompt?: string;
118
+ /**
119
+ * Arbitrary user metadata to attach to the generation request / result document.
120
+ */
121
+ metadata?: Record<string, any>;
9
122
  /**
10
123
  * The specific version of the prompt/settings to use.
11
124
  * If omitted, the latest version will be used.
@@ -68,24 +181,57 @@ export function interpolatePrompt(
68
181
  /**
69
182
  * Builds a URL to render or retrieve an image from Slop Machine.
70
183
  *
184
+ * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).
185
+ *
71
186
  * @param options - Configuration options for the image generation.
72
187
  * @returns A string containing the fully constructed URL.
73
188
  */
74
189
  export function buildImageUrl(options: SlopImageOptions): string {
75
190
  const {
76
191
  bucketId,
192
+ pipelineId,
193
+ siloId,
194
+ prompt,
195
+ metadata,
77
196
  version,
78
197
  resultId,
79
198
  aspectRatio = "1:1",
80
199
  quality = "fast",
81
200
  variables = {},
82
- baseUrl = "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderImage",
201
+ baseUrl,
83
202
  original,
84
203
  attachments,
85
204
  } = options;
86
205
 
206
+ if (pipelineId) {
207
+ const endpoint =
208
+ baseUrl ||
209
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline";
210
+ const params = new URLSearchParams();
211
+ params.set("pipelineId", pipelineId);
212
+ params.set("redirect", "true");
213
+
214
+ if (siloId) params.set("siloId", siloId);
215
+ if (prompt) params.set("prompt", prompt);
216
+ if (resultId) params.set("resultId", resultId);
217
+
218
+ if (Object.keys(variables).length > 0) {
219
+ params.set("variables", JSON.stringify(variables));
220
+ }
221
+ if (metadata && Object.keys(metadata).length > 0) {
222
+ params.set("metadata", JSON.stringify(metadata));
223
+ }
224
+
225
+ return `${endpoint}?${params.toString()}`;
226
+ }
227
+
228
+ const endpoint =
229
+ baseUrl ||
230
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderImage";
87
231
  const params = new URLSearchParams();
88
- params.set("bucketId", bucketId);
232
+ if (bucketId) {
233
+ params.set("bucketId", bucketId);
234
+ }
89
235
 
90
236
  if (!resultId) {
91
237
  if (aspectRatio) {
@@ -108,6 +254,10 @@ export function buildImageUrl(options: SlopImageOptions): string {
108
254
  params.set("variables", JSON.stringify(variables));
109
255
  }
110
256
 
257
+ if (metadata && Object.keys(metadata).length > 0) {
258
+ params.set("metadata", JSON.stringify(metadata));
259
+ }
260
+
111
261
  if (attachments && attachments.length > 0) {
112
262
  params.set("attachments", JSON.stringify(attachments));
113
263
  }
@@ -115,7 +265,7 @@ export function buildImageUrl(options: SlopImageOptions): string {
115
265
  params.set("resultId", resultId);
116
266
  }
117
267
 
118
- return `${baseUrl}?${params.toString()}`;
268
+ return `${endpoint}?${params.toString()}`;
119
269
  }
120
270
 
121
271
  /**
@@ -139,13 +289,29 @@ export function preloadImage(options: SlopImageOptions): Promise<void> {
139
289
  });
140
290
  }
141
291
 
142
- export type { VideoAspectRatio };
143
-
144
292
  export interface SlopVideoOptions {
145
293
  /**
146
294
  * The unique identifier of your Slop Machine bucket.
295
+ * Required when using a bucket unless pipelineId is provided.
296
+ */
297
+ bucketId?: string;
298
+ /**
299
+ * The unique identifier of your Slop Machine pipeline.
300
+ * Required when targeting a pipeline instead of a bucket.
301
+ */
302
+ pipelineId?: string;
303
+ /**
304
+ * Optional silo identifier.
305
+ */
306
+ siloId?: string;
307
+ /**
308
+ * Dynamic runtime prompt (used when targeting a pipeline).
309
+ */
310
+ prompt?: string;
311
+ /**
312
+ * Arbitrary user metadata to attach to the generation request / result document.
147
313
  */
148
- bucketId: string;
314
+ metadata?: Record<string, any>;
149
315
  /**
150
316
  * The specific version of the prompt/settings to use.
151
317
  * If omitted, the latest version will be used.
@@ -196,25 +362,58 @@ export interface SlopVideoOptions {
196
362
  /**
197
363
  * Builds a URL to render or retrieve a video from Slop Machine.
198
364
  *
365
+ * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).
366
+ *
199
367
  * @param options - Configuration options for the video generation.
200
368
  * @returns A string containing the fully constructed URL.
201
369
  */
202
370
  export function buildVideoUrl(options: SlopVideoOptions): string {
203
371
  const {
204
372
  bucketId,
373
+ pipelineId,
374
+ siloId,
375
+ prompt,
376
+ metadata,
205
377
  version,
206
378
  resultId,
207
379
  aspectRatio = "16:9",
208
380
  quality = "fast",
209
381
  variables = {},
210
382
  duration = 4,
211
- baseUrl = "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderVideo",
383
+ baseUrl,
212
384
  original,
213
385
  attachments,
214
386
  } = options;
215
387
 
388
+ if (pipelineId) {
389
+ const endpoint =
390
+ baseUrl ||
391
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline";
392
+ const params = new URLSearchParams();
393
+ params.set("pipelineId", pipelineId);
394
+ params.set("redirect", "true");
395
+
396
+ if (siloId) params.set("siloId", siloId);
397
+ if (prompt) params.set("prompt", prompt);
398
+ if (resultId) params.set("resultId", resultId);
399
+
400
+ if (Object.keys(variables).length > 0) {
401
+ params.set("variables", JSON.stringify(variables));
402
+ }
403
+ if (metadata && Object.keys(metadata).length > 0) {
404
+ params.set("metadata", JSON.stringify(metadata));
405
+ }
406
+
407
+ return `${endpoint}?${params.toString()}`;
408
+ }
409
+
410
+ const endpoint =
411
+ baseUrl ||
412
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderVideo";
216
413
  const params = new URLSearchParams();
217
- params.set("bucketId", bucketId);
414
+ if (bucketId) {
415
+ params.set("bucketId", bucketId);
416
+ }
218
417
 
219
418
  if (!resultId) {
220
419
  if (aspectRatio) {
@@ -238,6 +437,10 @@ export function buildVideoUrl(options: SlopVideoOptions): string {
238
437
  params.set("variables", JSON.stringify(variables));
239
438
  }
240
439
 
440
+ if (metadata && Object.keys(metadata).length > 0) {
441
+ params.set("metadata", JSON.stringify(metadata));
442
+ }
443
+
241
444
  if (attachments && attachments.length > 0) {
242
445
  params.set("attachments", JSON.stringify(attachments));
243
446
  }
@@ -245,7 +448,7 @@ export function buildVideoUrl(options: SlopVideoOptions): string {
245
448
  params.set("resultId", resultId);
246
449
  }
247
450
 
248
- return `${baseUrl}?${params.toString()}`;
451
+ return `${endpoint}?${params.toString()}`;
249
452
  }
250
453
 
251
454
  /**
@@ -262,8 +465,6 @@ export function preloadVideo(options: SlopVideoOptions): Promise<void> {
262
465
  return;
263
466
  }
264
467
 
265
- // We can just fetch the URL to preload it into the browser's cache.
266
- // We use no-cors to avoid CORS errors for simple preloads
267
468
  fetch(buildVideoUrl(options), { mode: "no-cors" })
268
469
  .then(() => resolve())
269
470
  .catch((err) => reject(err));
@@ -273,8 +474,26 @@ export function preloadVideo(options: SlopVideoOptions): Promise<void> {
273
474
  export interface SlopTextOptions {
274
475
  /**
275
476
  * The unique identifier of your Slop Machine bucket.
477
+ * Required when using a bucket unless pipelineId is provided.
276
478
  */
277
- bucketId: string;
479
+ bucketId?: string;
480
+ /**
481
+ * The unique identifier of your Slop Machine pipeline.
482
+ * Required when targeting a pipeline instead of a bucket.
483
+ */
484
+ pipelineId?: string;
485
+ /**
486
+ * Optional silo identifier.
487
+ */
488
+ siloId?: string;
489
+ /**
490
+ * Dynamic runtime prompt (used when targeting a pipeline).
491
+ */
492
+ prompt?: string;
493
+ /**
494
+ * Arbitrary user metadata to attach to the generation request / result document.
495
+ */
496
+ metadata?: Record<string, any>;
278
497
  /**
279
498
  * The specific version of the prompt/settings to use.
280
499
  * If omitted, the latest version will be used.
@@ -304,34 +523,65 @@ export interface SlopTextOptions {
304
523
  /**
305
524
  * Builds a URL to render or retrieve text from Slop Machine.
306
525
  *
526
+ * Supports both standard Buckets (via `bucketId`) and multi-step Pipelines (via `pipelineId`).
527
+ *
307
528
  * @param options - Configuration options for the text generation.
308
529
  * @returns A string containing the fully constructed URL.
309
530
  */
310
531
  export function buildTextUrl(options: SlopTextOptions): string {
311
532
  const {
312
533
  bucketId,
534
+ pipelineId,
535
+ siloId,
536
+ prompt,
537
+ metadata,
313
538
  version,
314
539
  resultId,
315
540
  variables = {},
316
- baseUrl = "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderText",
541
+ baseUrl,
317
542
  attachments,
318
543
  } = options;
319
544
 
545
+ if (pipelineId) {
546
+ const endpoint =
547
+ baseUrl ||
548
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline";
549
+ const params = new URLSearchParams();
550
+ params.set("pipelineId", pipelineId);
551
+ params.set("sync", "true");
552
+
553
+ if (siloId) params.set("siloId", siloId);
554
+ if (prompt) params.set("prompt", prompt);
555
+ if (resultId) params.set("resultId", resultId);
556
+
557
+ if (Object.keys(variables).length > 0) {
558
+ params.set("variables", JSON.stringify(variables));
559
+ }
560
+ if (metadata && Object.keys(metadata).length > 0) {
561
+ params.set("metadata", JSON.stringify(metadata));
562
+ }
563
+
564
+ return `${endpoint}?${params.toString()}`;
565
+ }
566
+
567
+ const endpoint =
568
+ baseUrl ||
569
+ "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderText";
320
570
  const params = new URLSearchParams();
321
- params.set("bucketId", bucketId);
571
+ if (bucketId) {
572
+ params.set("bucketId", bucketId);
573
+ }
322
574
 
323
575
  if (!resultId) {
324
576
  if (version) {
325
577
  params.set("version", String(version));
326
578
  }
327
- if (resultId) {
328
- params.set("resultId", resultId);
329
- }
330
-
331
579
  if (Object.keys(variables).length > 0) {
332
580
  params.set("variables", JSON.stringify(variables));
333
581
  }
334
-
582
+ if (metadata && Object.keys(metadata).length > 0) {
583
+ params.set("metadata", JSON.stringify(metadata));
584
+ }
335
585
  if (attachments && attachments.length > 0) {
336
586
  params.set("attachments", JSON.stringify(attachments));
337
587
  }
@@ -339,7 +589,7 @@ export function buildTextUrl(options: SlopTextOptions): string {
339
589
  params.set("resultId", resultId);
340
590
  }
341
591
 
342
- return `${baseUrl}?${params.toString()}`;
592
+ return `${endpoint}?${params.toString()}`;
343
593
  }
344
594
 
345
595
  /**
@@ -356,14 +606,101 @@ export function preloadText(options: SlopTextOptions): Promise<void> {
356
606
  return;
357
607
  }
358
608
 
359
- // Fetch the URL to preload it into the browser's cache.
360
- // We use no-cors to avoid CORS errors for simple preloads
361
609
  fetch(buildTextUrl(options), { mode: "no-cors" })
362
610
  .then(() => resolve())
363
611
  .catch((err) => reject(err));
364
612
  });
365
613
  }
366
614
 
615
+ /**
616
+ * Builds a URL to execute or inspect a multi-step Pipeline from Slop Machine.
617
+ *
618
+ * @param options - Configuration options for the pipeline execution.
619
+ * @returns A string containing the fully constructed URL.
620
+ */
621
+ export function buildPipelineUrl(options: SlopPipelineOptions): string {
622
+ const {
623
+ pipelineId,
624
+ siloId,
625
+ prompt,
626
+ variables = {},
627
+ metadata = {},
628
+ sync = true,
629
+ redirect = false,
630
+ resultId,
631
+ baseUrl = "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline",
632
+ } = options;
633
+
634
+ const params = new URLSearchParams();
635
+ params.set("pipelineId", pipelineId);
636
+
637
+ if (siloId) params.set("siloId", siloId);
638
+ if (prompt) params.set("prompt", prompt);
639
+ if (resultId) params.set("resultId", resultId);
640
+ if (sync !== undefined) params.set("sync", String(sync));
641
+ if (redirect) params.set("redirect", "true");
642
+
643
+ if (Object.keys(variables).length > 0) {
644
+ params.set("variables", JSON.stringify(variables));
645
+ }
646
+ if (Object.keys(metadata).length > 0) {
647
+ params.set("metadata", JSON.stringify(metadata));
648
+ }
649
+
650
+ return `${baseUrl}?${params.toString()}`;
651
+ }
652
+
653
+ /**
654
+ * Executes a Slop Machine multi-step Pipeline programmatically and returns the full typed result payload.
655
+ *
656
+ * @param options - Execution parameters including the pipelineId and runtime prompt/variables/metadata.
657
+ * @returns A promise resolving to the completed PipelineResult document.
658
+ */
659
+ export async function executePipeline(
660
+ options: ExecutePipelineOptions,
661
+ ): Promise<PipelineResult> {
662
+ const {
663
+ pipelineId,
664
+ siloId,
665
+ prompt,
666
+ variables,
667
+ metadata,
668
+ baseUrl = "https://us-central1-slopmachine-12bfb.cloudfunctions.net/renderPipeline",
669
+ } = options;
670
+
671
+ const response = await fetch(baseUrl, {
672
+ method: "POST",
673
+ headers: {
674
+ "Content-Type": "application/json",
675
+ },
676
+ body: JSON.stringify({
677
+ pipelineId,
678
+ ...(siloId ? { siloId } : {}),
679
+ ...(prompt ? { prompt } : {}),
680
+ variables,
681
+ metadata,
682
+ sync: true,
683
+ }),
684
+ });
685
+
686
+ if (!response.ok) {
687
+ let errorDetail = response.statusText;
688
+ try {
689
+ const errorJson = await response.json();
690
+ if (errorJson.error) {
691
+ errorDetail = errorJson.error;
692
+ }
693
+ } catch {
694
+ // Use statusText
695
+ }
696
+ throw new Error(
697
+ `Pipeline execution failed (${response.status}): ${errorDetail}`,
698
+ );
699
+ }
700
+
701
+ return (await response.json()) as PipelineResult;
702
+ }
703
+
367
704
  /**
368
705
  * Uploads a base64 encoded file as a temporary attachment to be used in generation requests.
369
706
  *