{ "kind": "open-flow-workflow", "version": 1, "name": "Describe a Website Screenshot", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_7f3d1a9064b4e179": { "name": "Run manually", "kind": "start", "inputDefs": [] }, "n_5cda27fce000176e": { "inputs": { "websiteName": { "kind": "value", "value": "Example" }, "url": { "kind": "value", "value": "https://example.com" } }, "name": "Choose a website", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "websiteName" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "websiteName" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "body" } ], "name": "Choose a website", "moduleId": "n_92fc22598087ab6e", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_2ef72897c99cde59": { "inputs": { "url": { "kind": "value", "value": "https://api.urlbox.com/v1/render/sync" }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5cda27fce000176e", "output": "body" } ] }, "auth.token": { "kind": "unset" } }, "name": "Capture full webpage", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" }, { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "auth.token" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" } ], "name": "Capture full webpage", "executor": { "method": "POST", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "authentication": { "type": "bearer" }, "responseFormat": "json", "statusPolicy": "success", "kind": "http-request" } } }, "n_73c97687d1bbd32f": { "inputs": { "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_2ef72897c99cde59", "output": "body" } ] } }, "name": "Prepare vision request", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "response" } ], "outputs": [ { "jsonSchema": { "anyOf": [ { "type": "string", "description": "A plain text prompt." }, { "type": "array", "items": { "type": "object", "properties": { "role": { "type": "string", "enum": [ "system", "user", "assistant", "developer" ], "description": "The role of the message author." }, "content": { "anyOf": [ { "type": "string", "description": "Plain text content for a simple message." }, { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "type": { "const": "input_text", "description": "The content type. Must be input_text." }, "text": { "type": "string", "description": "The text content sent to the model." } }, "required": [ "type", "text" ], "additionalProperties": false, "description": "A text content block for a response input message." }, { "type": "object", "properties": { "type": { "const": "input_image", "description": "The content type. Must be input_image." }, "image_url": { "type": "string", "description": "A remote image URL or a data URL containing the image bytes." }, "detail": { "type": "string", "enum": [ "auto", "low", "high", "original" ], "description": "The requested image detail level." } }, "required": [ "type", "image_url" ], "additionalProperties": false, "description": "An image content block for a response input message." }, { "type": "object", "properties": { "type": { "const": "input_file", "description": "The content type. Must be input_file." }, "file_id": { "type": "string", "description": "The uploaded file ID to reference." }, "file_data": { "type": "string", "description": "The inline file data encoded as base64 or supplied as a data URL." }, "filename": { "type": "string", "description": "The filename to report for inline file data." } }, "required": [ "type" ], "additionalProperties": false, "description": "A file content block for a response input message." } ], "description": "A structured content block." }, "minItems": 1, "description": "Structured multimodal content blocks." } ], "description": "The content for the message." } }, "required": [ "role", "content" ], "additionalProperties": false, "description": "A message in the Responses API input array." }, "minItems": 1, "description": "An ordered array of conversation messages." } ], "description": "The input prompt or message array sent to the model." }, "nullable": false, "handle": "input" } ], "name": "Prepare vision request", "moduleId": "n_09c3d1f5e7fa50e1", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_483a6f8f2bd1d525": { "inputs": { "model": { "kind": "value", "value": "gpt-4o-mini" }, "input": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_73c97687d1bbd32f", "output": "input" } ] } }, "name": "Describe the screenshot", "kind": "task", "task": { "inputs": [ { "description": "The model to use for the response.", "jsonSchema": { "type": "string", "description": "The model to use for the response." }, "nullable": false, "handle": "model" }, { "description": "The input prompt or message array sent to the model.", "jsonSchema": { "anyOf": [ { "type": "string", "description": "A plain text prompt." }, { "type": "array", "items": { "type": "object", "properties": { "role": { "type": "string", "enum": [ "system", "user", "assistant", "developer" ], "description": "The role of the message author." }, "content": { "anyOf": [ { "type": "string", "description": "Plain text content for a simple message." }, { "type": "array", "items": { "anyOf": [ { "type": "object", "properties": { "type": { "const": "input_text", "description": "The content type. Must be input_text." }, "text": { "type": "string", "description": "The text content sent to the model." } }, "required": [ "type", "text" ], "additionalProperties": false, "description": "A text content block for a response input message." }, { "type": "object", "properties": { "type": { "const": "input_image", "description": "The content type. Must be input_image." }, "image_url": { "type": "string", "description": "A remote image URL or a data URL containing the image bytes." }, "detail": { "type": "string", "enum": [ "auto", "low", "high", "original" ], "description": "The requested image detail level." } }, "required": [ "type", "image_url" ], "additionalProperties": false, "description": "An image content block for a response input message." }, { "type": "object", "properties": { "type": { "const": "input_file", "description": "The content type. Must be input_file." }, "file_id": { "type": "string", "description": "The uploaded file ID to reference." }, "file_data": { "type": "string", "description": "The inline file data encoded as base64 or supplied as a data URL." }, "filename": { "type": "string", "description": "The filename to report for inline file data." } }, "required": [ "type" ], "additionalProperties": false, "description": "A file content block for a response input message." } ], "description": "A structured content block." }, "minItems": 1, "description": "Structured multimodal content blocks." } ], "description": "The content for the message." } }, "required": [ "role", "content" ], "additionalProperties": false, "description": "A message in the Responses API input array." }, "minItems": 1, "description": "An ordered array of conversation messages." } ], "description": "The input prompt or message array sent to the model." }, "nullable": false, "handle": "input" }, { "description": "A top-level instruction string applied before the input.", "jsonSchema": { "type": "string", "description": "A top-level instruction string applied before the input." }, "nullable": true, "handle": "instructions", "value": null }, { "description": "The maximum number of output tokens to generate.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "The maximum number of output tokens to generate." }, "nullable": true, "handle": "max_output_tokens", "value": null }, { "description": "String metadata attached to the response.", "jsonSchema": { "type": "object", "additionalProperties": { "type": "string", "description": "Metadata field value." }, "description": "String metadata attached to the response." }, "nullable": true, "handle": "metadata", "value": null }, { "description": "The ID of a previous response to continue from.", "jsonSchema": { "type": "string", "description": "The ID of a previous response to continue from." }, "nullable": true, "handle": "previous_response_id", "value": null }, { "description": "Whether the response may be stored by the upstream platform.", "jsonSchema": { "type": "boolean", "description": "Whether the response may be stored by the upstream platform." }, "nullable": true, "handle": "store", "value": null }, { "description": "The sampling temperature.", "jsonSchema": { "type": "number", "minimum": 0, "maximum": 2, "description": "The sampling temperature." }, "nullable": true, "handle": "temperature", "value": null }, { "description": "Text output configuration for the response.", "jsonSchema": { "type": "object", "properties": { "format": { "anyOf": [ { "type": "object", "properties": { "type": { "const": "json_object", "description": "The format type. Must be json_object." } }, "required": [ "type" ], "additionalProperties": false, "description": "A flexible JSON object output format." }, { "type": "object", "properties": { "type": { "const": "json_schema", "description": "The format type. Must be json_schema." }, "name": { "type": "string", "description": "The schema name reported to the model." }, "schema": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "The JSON Schema definition used for output validation." }, "strict": { "type": "boolean", "description": "Whether the model must strictly follow the declared schema." } }, "required": [ "type", "name", "schema" ], "additionalProperties": false, "description": "A JSON Schema output format." } ], "description": "The output format configuration." } }, "additionalProperties": false, "description": "Text output configuration for the response." }, "nullable": true, "handle": "text", "value": null }, { "description": "The nucleus sampling threshold.", "jsonSchema": { "type": "number", "minimum": 0, "maximum": 1, "description": "The nucleus sampling threshold." }, "nullable": true, "handle": "top_p", "value": null }, { "description": "An end-user identifier passed through to the upstream API.", "jsonSchema": { "type": "string", "description": "An end-user identifier passed through to the upstream API." }, "nullable": true, "handle": "user", "value": null }, { "description": "Whether to request a streaming response. This connector only accepts false or an omitted value.", "jsonSchema": { "type": "boolean", "description": "Whether to request a streaming response. This connector only accepts false or an omitted value." }, "nullable": true, "handle": "stream", "value": null } ], "outputs": [ { "description": "The response payload returned by the OpenAI Responses API.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The response identifier." }, "object": { "type": "string", "description": "The top-level object type." }, "created_at": { "type": "integer", "description": "The Unix timestamp when the response was created." }, "status": { "type": "string", "description": "The response status." }, "model": { "type": "string", "description": "The model that generated the response." }, "output": { "type": "array", "items": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Any JSON object." }, "description": "The raw output items returned by the response." }, "output_text": { "type": "string", "description": "The aggregated plain text extracted from the output items." }, "usage": { "type": "object", "properties": { "input_tokens": { "type": "integer", "description": "The number of input tokens consumed." }, "output_tokens": { "type": "integer", "description": "The number of output tokens generated." }, "total_tokens": { "type": "integer", "description": "The total number of tokens used." }, "input_tokens_details": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Detailed usage information for input tokens." }, "output_tokens_details": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Detailed usage information for output tokens." } }, "additionalProperties": true, "description": "Usage statistics for the response." }, "error": { "type": [ "object", "null" ], "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "The upstream error payload, when the response is incomplete." }, "incomplete_details": { "type": [ "object", "null" ], "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "The upstream incomplete details payload, if provided." }, "previous_response_id": { "type": [ "string", "null" ], "description": "The previous response ID referenced by this response." }, "store": { "type": "boolean", "description": "Whether the response is stored by the upstream platform." }, "expire_at": { "type": "integer", "description": "The Unix timestamp when the stored response expires." } }, "required": [ "id", "output" ], "additionalProperties": true, "description": "The response payload returned by the OpenAI Responses API." }, "nullable": false, "handle": "output" } ], "name": "Describe the screenshot", "executor": { "kind": "connector", "action": "openai.create_response", "outputMode": "value" } } }, "n_f855790215c9b62a": { "inputs": { "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_483a6f8f2bd1d525", "output": "output" } ] }, "websiteName": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5cda27fce000176e", "output": "websiteName" } ] }, "url": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_5cda27fce000176e", "output": "url" } ] } }, "name": "Keep website and description together", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The response identifier." }, "object": { "type": "string", "description": "The top-level object type." }, "created_at": { "type": "integer", "description": "The Unix timestamp when the response was created." }, "status": { "type": "string", "description": "The response status." }, "model": { "type": "string", "description": "The model that generated the response." }, "output": { "type": "array", "items": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Any JSON object." }, "description": "The raw output items returned by the response." }, "output_text": { "type": "string", "description": "The aggregated plain text extracted from the output items." }, "usage": { "type": "object", "properties": { "input_tokens": { "type": "integer", "description": "The number of input tokens consumed." }, "output_tokens": { "type": "integer", "description": "The number of output tokens generated." }, "total_tokens": { "type": "integer", "description": "The total number of tokens used." }, "input_tokens_details": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Detailed usage information for input tokens." }, "output_tokens_details": { "type": "object", "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "Detailed usage information for output tokens." } }, "additionalProperties": true, "description": "Usage statistics for the response." }, "error": { "type": [ "object", "null" ], "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "The upstream error payload, when the response is incomplete." }, "incomplete_details": { "type": [ "object", "null" ], "additionalProperties": { "description": "Any JSON value accepted by the upstream API." }, "description": "The upstream incomplete details payload, if provided." }, "previous_response_id": { "type": [ "string", "null" ], "description": "The previous response ID referenced by this response." }, "store": { "type": "boolean", "description": "Whether the response is stored by the upstream platform." }, "expire_at": { "type": "integer", "description": "The Unix timestamp when the stored response expires." } }, "required": [ "id", "output" ], "additionalProperties": true, "description": "The response payload returned by the OpenAI Responses API." }, "nullable": false, "handle": "response" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "websiteName" }, { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "url" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "result" } ], "name": "Keep website and description together", "moduleId": "n_dfce561e31f55177", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_5f4790d58818548f": { "name": "Return description", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "result" } ], "outputMappings": { "result": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_f855790215c9b62a", "output": "result" } ] } } } }, "edges": [ { "source": "n_7f3d1a9064b4e179", "target": "n_5cda27fce000176e" }, { "source": "n_5cda27fce000176e", "target": "n_2ef72897c99cde59" }, { "source": "n_2ef72897c99cde59", "target": "n_73c97687d1bbd32f" }, { "source": "n_73c97687d1bbd32f", "target": "n_483a6f8f2bd1d525" }, { "source": "n_483a6f8f2bd1d525", "target": "n_f855790215c9b62a" }, { "source": "n_f855790215c9b62a", "target": "n_5f4790d58818548f" } ] } }, "modules": { "n_92fc22598087ab6e": { "name": "Choose a website", "imports": [], "source": "export default function prepare({websiteName,url}){if(typeof websiteName!=='string'||!websiteName.trim())throw Error('Enter a website name');let u;try{u=new URL(url)}catch{throw Error('Enter a valid HTTP or HTTPS URL')}if(!['http:','https:'].includes(u.protocol)||u.username||u.password)throw Error('Enter a public HTTP or HTTPS URL without credentials');return{body:{url:u.href,full_page:true},websiteName:websiteName.trim(),url:u.href}}\n" }, "n_09c3d1f5e7fa50e1": { "name": "Prepare vision request", "imports": [], "source": "export default function vision({response}){const u=response?.renderUrl;if(typeof u!=='string'||!/^https:\\/\\//i.test(u))throw Error('URLbox did not return a screenshot URL');return{input:[{role:'user',content:[{type:'input_text',text:'Your input is a screenshot of a website. Describe the content of the website in one sentence.'},{type:'input_image',image_url:u}]}]}}\n" }, "n_dfce561e31f55177": { "name": "Keep website and description together", "imports": [], "source": "export default function result({response,websiteName,url}){const text=typeof response?.output_text==='string'?response.output_text:(Array.isArray(response?.output)?response.output.flatMap(x=>Array.isArray(x.content)?x.content.filter(y=>y.type==='output_text'&&typeof y.text==='string').map(y=>y.text):[]).join('\\n'):'');if(response?.status!=='completed'||!text.trim())throw Error('Vision analysis did not return a completed description');return{result:{websiteName,url,description:text.trim()}}}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }