{ "kind": "open-flow-workflow", "version": 1, "name": "Post AI News to X with Perplexity", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_9a811fa257ae0928": { "name": "Every 21 hours", "kind": "cron", "cronTimes": [ { "type": "every", "unit": "hour", "value": 21 } ] }, "n_9e0a413f1e8e9dc2": { "inputs": { "model": { "kind": "value", "value": "sonar" }, "messages": { "kind": "value", "value": [ { "role": "system", "content": "You are a social media assistant summarizing tech news for Twitter/X. Only return one article. Your output must follow this exact format: a short, engaging headline (max 140 characters), followed by a single space, then the direct article link. Do not use markdown, hashtags, emojis, or line breaks. Keep the total output under 200 characters. Be precise, objective, and newsworthy." }, { "role": "user", "content": "What's the latest news in artificial intelligence?" } ] }, "temperature": { "kind": "value", "value": 0.3 }, "top_p": { "kind": "value", "value": 0.9 }, "return_citations": { "kind": "value", "value": true }, "search_domain_filter": { "kind": "value", "value": [ "perplexity.ai" ] }, "search_recency_filter": { "kind": "value", "value": "day" }, "return_images": { "kind": "value", "value": true }, "max_tokens": { "kind": "value", "value": 80 }, "stream": { "kind": "value", "value": false }, "presence_penalty": { "kind": "value", "value": 0 }, "frequency_penalty": { "kind": "value", "value": 1 } }, "name": "Find recent AI news", "kind": "task", "task": { "inputs": [ { "description": "The Sonar model to use for the chat completion.", "jsonSchema": { "type": "string", "description": "The Sonar model to use for the chat completion." }, "nullable": false, "handle": "model" }, { "description": "The ordered conversation messages.", "jsonSchema": { "type": "array", "items": { "type": "object", "properties": { "role": { "type": "string", "enum": [ "system", "user", "assistant" ], "description": "The role of the message author." }, "content": { "type": "string", "description": "The plain-text message content." } }, "required": [ "role", "content" ], "additionalProperties": false, "description": "A chat message." }, "minItems": 1, "description": "The ordered conversation messages." }, "nullable": false, "handle": "messages" }, { "description": "The maximum number of tokens to generate.", "jsonSchema": { "type": "integer", "minimum": 1, "description": "The maximum number of tokens to generate." }, "nullable": true, "handle": "max_tokens", "value": null }, { "description": "The sampling temperature for generation.", "jsonSchema": { "type": "number", "minimum": 0, "maximum": 2, "description": "The sampling temperature for generation." }, "nullable": true, "handle": "temperature", "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": "The number of top tokens to consider per step.", "jsonSchema": { "type": "integer", "minimum": 0, "description": "The number of top tokens to consider per step." }, "nullable": true, "handle": "top_k", "value": null }, { "description": "Whether to stream the response. This connector only accepts false or an omitted value.", "jsonSchema": { "type": "boolean", "description": "Whether to stream the response. This connector only accepts false or an omitted value." }, "nullable": true, "handle": "stream", "value": null }, { "description": "Whether to include image references in the response.", "jsonSchema": { "type": "boolean", "description": "Whether to include image references in the response." }, "nullable": true, "handle": "return_images", "value": null }, { "description": "Whether to include citations in the response.", "jsonSchema": { "type": "boolean", "description": "Whether to include citations in the response." }, "nullable": true, "handle": "return_citations", "value": null }, { "description": "Whether to disable web search grounding for this request.", "jsonSchema": { "type": "boolean", "description": "Whether to disable web search grounding for this request." }, "nullable": true, "handle": "disable_search", "value": null }, { "description": "Only search within these domains or URL prefixes.", "jsonSchema": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "A domain or URL prefix used to limit web search." }, "description": "Only search within these domains or URL prefixes." }, "nullable": true, "handle": "search_domain_filter", "value": null }, { "description": "A recency filter such as day, week, month, or year.", "jsonSchema": { "type": "string", "description": "A recency filter such as day, week, month, or year." }, "nullable": true, "handle": "search_recency_filter", "value": null }, { "description": "The penalty applied to tokens that have already appeared.", "jsonSchema": { "type": "number", "minimum": -2, "maximum": 2, "description": "The penalty applied to tokens that have already appeared." }, "nullable": true, "handle": "presence_penalty", "value": null }, { "description": "The penalty applied based on token frequency.", "jsonSchema": { "type": "number", "minimum": 0, "maximum": 2, "description": "The penalty applied based on token frequency." }, "nullable": true, "handle": "frequency_penalty", "value": null } ], "outputs": [ { "description": "The response payload for the chat completion action.", "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The completion identifier." }, "model": { "type": "string", "description": "The model that generated the completion." }, "created": { "type": "integer", "description": "The Unix timestamp when the completion was created." }, "choices": { "type": "array", "items": { "type": "object", "properties": { "index": { "type": "integer", "description": "The choice index." }, "finish_reason": { "type": "string", "description": "The reason why generation stopped." }, "message": { "type": "object", "properties": { "role": { "type": "string", "description": "The role of the generated message." }, "content": { "type": "string", "description": "The generated message content." } }, "required": [ "role" ], "additionalProperties": true, "description": "The generated message." } }, "required": [ "index", "message" ], "additionalProperties": true, "description": "A single generated completion choice." }, "description": "The completion choices." }, "citations": { "type": "array", "items": { "type": "string", "description": "A citation URL returned with the response." }, "description": "The citation URLs referenced by the answer." }, "search_results": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string", "description": "The search result title." }, "url": { "type": "string", "description": "The canonical URL of the result." }, "snippet": { "type": "string", "description": "A short snippet extracted from the result page." }, "date": { "type": "string", "description": "The published date reported for the result." }, "last_updated": { "type": "string", "description": "The last updated date reported for the result." } }, "additionalProperties": true, "description": "A raw search result returned by Perplexity." }, "description": "The search results used to ground the response." }, "usage": { "type": "object", "properties": { "prompt_tokens": { "type": "integer", "description": "The number of prompt tokens consumed." }, "completion_tokens": { "type": "integer", "description": "The number of completion tokens generated." }, "total_tokens": { "type": "integer", "description": "The total number of tokens consumed." } }, "additionalProperties": true, "description": "Usage information for the completion." } }, "required": [ "choices" ], "additionalProperties": true, "description": "The response payload for the chat completion action." }, "nullable": false, "handle": "output" } ], "name": "Find recent AI news", "executor": { "kind": "connector", "action": "perplexity.create_chat_completion", "outputMode": "value" } } }, "n_ebfd10d1dba63498": { "inputs": { "response": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_9e0a413f1e8e9dc2", "output": "output" } ] } }, "name": "Check the headline and link", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "The completion identifier." }, "model": { "type": "string", "description": "The model that generated the completion." }, "created": { "type": "integer", "description": "The Unix timestamp when the completion was created." }, "choices": { "type": "array", "items": { "type": "object", "properties": { "index": { "type": "integer", "description": "The choice index." }, "finish_reason": { "type": "string", "description": "The reason why generation stopped." }, "message": { "type": "object", "properties": { "role": { "type": "string", "description": "The role of the generated message." }, "content": { "type": "string", "description": "The generated message content." } }, "required": [ "role" ], "additionalProperties": true, "description": "The generated message." } }, "required": [ "index", "message" ], "additionalProperties": true, "description": "A single generated completion choice." }, "description": "The completion choices." }, "citations": { "type": "array", "items": { "type": "string", "description": "A citation URL returned with the response." }, "description": "The citation URLs referenced by the answer." }, "search_results": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string", "description": "The search result title." }, "url": { "type": "string", "description": "The canonical URL of the result." }, "snippet": { "type": "string", "description": "A short snippet extracted from the result page." }, "date": { "type": "string", "description": "The published date reported for the result." }, "last_updated": { "type": "string", "description": "The last updated date reported for the result." } }, "additionalProperties": true, "description": "A raw search result returned by Perplexity." }, "description": "The search results used to ground the response." }, "usage": { "type": "object", "properties": { "prompt_tokens": { "type": "integer", "description": "The number of prompt tokens consumed." }, "completion_tokens": { "type": "integer", "description": "The number of completion tokens generated." }, "total_tokens": { "type": "integer", "description": "The total number of tokens consumed." } }, "additionalProperties": true, "description": "Usage information for the completion." } }, "required": [ "choices" ], "additionalProperties": true, "description": "The response payload for the chat completion action." }, "nullable": false, "handle": "response" } ], "outputs": [ { "jsonSchema": { "type": "string", "description": "The Tweet text content. Required unless another content source is provided." }, "nullable": true, "handle": "text" } ], "name": "Check the headline and link", "moduleId": "n_d4ca6b18539cd82f", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_6c6df9d1c930112c": { "inputs": { "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_ebfd10d1dba63498", "output": "text" } ] } }, "name": "Post the headline on X", "kind": "task", "task": { "inputs": [ { "description": "The Tweet text content. Required unless another content source is provided.", "jsonSchema": { "type": "string", "description": "The Tweet text content. Required unless another content source is provided." }, "nullable": true, "handle": "text", "value": null }, { "description": "The card URI to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The card URI to attach to the Tweet." }, "nullable": true, "handle": "cardUri", "value": null }, { "description": "Whether to mark the Tweet as promoted-only nullcast content.", "jsonSchema": { "type": "boolean", "description": "Whether to mark the Tweet as promoted-only nullcast content." }, "nullable": true, "handle": "nullcast", "value": null }, { "description": "The place ID to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The place ID to attach to the Tweet." }, "nullable": true, "handle": "geoPlaceId", "value": null }, { "description": "The poll options to create with the Tweet.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The poll options to create with the Tweet." }, "nullable": true, "handle": "pollOptions", "value": null }, { "description": "The Tweet ID to quote in the new Tweet.", "jsonSchema": { "type": "string", "description": "The Tweet ID to quote in the new Tweet." }, "nullable": true, "handle": "quoteTweetId", "value": null }, { "description": "Who can reply to the Tweet.", "jsonSchema": { "type": "string", "enum": [ "following", "mentionedUsers", "subscribers" ], "description": "Who can reply to the Tweet." }, "nullable": true, "handle": "replySettings", "value": null }, { "description": "The uploaded media IDs to attach to the Tweet.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The uploaded media IDs to attach to the Tweet." }, "nullable": true, "handle": "mediaMediaIds", "value": null }, { "description": "Who can reply to the poll Tweet.", "jsonSchema": { "type": "string", "description": "Who can reply to the poll Tweet." }, "nullable": true, "handle": "pollReplySettings", "value": null }, { "description": "The user IDs to tag in the attached media.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The user IDs to tag in the attached media." }, "nullable": true, "handle": "mediaTaggedUserIds", "value": null }, { "description": "The poll duration in minutes.", "jsonSchema": { "type": "integer", "description": "The poll duration in minutes." }, "nullable": true, "handle": "pollDurationMinutes", "value": null }, { "description": "The DM deep link to attach to the Tweet.", "jsonSchema": { "type": "string", "description": "The DM deep link to attach to the Tweet." }, "nullable": true, "handle": "directMessageDeepLink", "value": null }, { "description": "Whether to restrict the Tweet to super followers only.", "jsonSchema": { "type": "boolean", "description": "Whether to restrict the Tweet to super followers only." }, "nullable": true, "handle": "forSuperFollowersOnly", "value": null }, { "description": "The Tweet ID to reply to.", "jsonSchema": { "type": "string", "description": "The Tweet ID to reply to." }, "nullable": true, "handle": "replyInReplyToTweetId", "value": null }, { "description": "The user IDs to exclude from reply mentions.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The user IDs to exclude from reply mentions." }, "nullable": true, "handle": "replyExcludeReplyUserIds", "value": null } ], "outputs": [ { "description": "The ID of the created Tweet.", "jsonSchema": { "type": "string", "description": "The ID of the created Tweet." }, "nullable": false, "handle": "id" }, { "description": "The text content of the created Tweet.", "jsonSchema": { "type": "string", "description": "The text content of the created Tweet." }, "nullable": false, "handle": "text" }, { "description": "The edit history Tweet IDs returned by the X API.", "jsonSchema": { "type": "array", "items": { "type": "string", "description": "A string value." }, "description": "The edit history Tweet IDs returned by the X API." }, "nullable": true, "handle": "editHistoryTweetIds" }, { "description": "The raw create Tweet response returned by the X API.", "jsonSchema": { "type": "object", "properties": {}, "additionalProperties": true, "description": "The raw create Tweet response returned by the X API." }, "nullable": false, "handle": "raw" } ], "name": "Post the headline on X", "executor": { "kind": "connector", "action": "twitter.creation_of_a_post" } } }, "n_cca83feabc066e01": { "name": "Published post", "kind": "outputs", "outputDefs": [ { "jsonSchema": { "type": "string", "description": "The ID of the created Tweet." }, "nullable": false, "handle": "id" }, { "jsonSchema": { "type": "string", "description": "The text content of the created Tweet." }, "nullable": false, "handle": "text" } ], "outputMappings": { "id": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6c6df9d1c930112c", "output": "id" } ] }, "text": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_6c6df9d1c930112c", "output": "text" } ] } } } }, "edges": [ { "source": "n_9a811fa257ae0928", "target": "n_9e0a413f1e8e9dc2" }, { "source": "n_9e0a413f1e8e9dc2", "target": "n_ebfd10d1dba63498" }, { "source": "n_ebfd10d1dba63498", "target": "n_6c6df9d1c930112c" }, { "source": "n_6c6df9d1c930112c", "target": "n_cca83feabc066e01" } ] } }, "modules": { "n_d4ca6b18539cd82f": { "name": "Check the headline and link", "imports": [], "source": "export default function message({response}){const text=response?.choices?.[0]?.message?.content;if(typeof text!=='string'||!text.trim()||[...text].length>200||!/^\\S[\\s\\S]*https?:\\/\\/\\S+/i.test(text.trim()))throw Error('Expected a short headline and article link');return{text:text.trim()}}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }