AI · 12 — Speak (text → voice)

Text becomes speech through the ◈-wired local TTS (Kokoro on :8880), PLAYS right in the Console, and is saved to ./ai-demo-speech.mp3 for demo 13 to transcribe. Change the Inject text and Test again.

What’s inside

6 nodes — every type links to its full reference page.

StepNodeType
Script Inject input.inject
Speak AI Speak ai.speak
Kokoro TTS (local) AI Model ai.model
Play it Play Audio output.audio
Save mp3 Write File storage.write-file
Done Console utility.console

Import it

  1. Studio → Import — paste the JSON below (or the URL /docs/templates/ai-12-speak-text-voice.json).
  2. Or ask the AI Copilot with the JSON pasted after the phrase:
    import this workflow json into a new workflow named "AI · 12 — Speak (text → voice)"
  3. Any credentials the nodes need are ${credential.…} references — add them once in Admin → Credentials and the template picks them up. Nothing secret ships in a template.
The workflow document (flowdrome.workflow.v1, 6 node types)
{
  "schemaVersion": "flowdrome.workflow.v1",
  "id": "",
  "name": "AI · 12 — Speak (text → voice)",
  "version": "0",
  "status": "draft",
  "nodes": [
    {
      "id": "seed",
      "type": "input.inject",
      "label": "Script",
      "category": "trigger",
      "config": {
        "contentType": "application/json",
        "payload": {
          "text": "Hello! This voice was generated locally, on this machine, by the Flowdrome speak node."
        }
      },
      "position": {
        "x": 0,
        "y": 0
      }
    },
    {
      "id": "speak",
      "type": "ai.speak",
      "label": "Speak",
      "category": "ai",
      "config": {
        "baseUrl": "http://localhost:8880/v1",
        "apiKey": "",
        "model": "kokoro",
        "voice": "af_heart",
        "textField": "text",
        "format": "mp3",
        "timeoutMs": 120000
      },
      "position": {
        "x": 530,
        "y": 0
      },
      "attachments": {
        "model": "tts"
      }
    },
    {
      "id": "tts",
      "type": "ai.model",
      "label": "Kokoro TTS (local)",
      "category": "ai",
      "config": {
        "provider": "generic-url",
        "baseUrl": "http://localhost:8880/v1",
        "apiKey": "",
        "model": "kokoro",
        "models": [],
        "temperature": 0.2,
        "maxTokens": 512
      },
      "position": {
        "x": 530,
        "y": 222
      }
    },
    {
      "id": "play",
      "type": "output.audio",
      "label": "Play it",
      "category": "output",
      "config": {
        "audioField": "",
        "label": ""
      },
      "position": {
        "x": 1060,
        "y": 0
      }
    },
    {
      "id": "save",
      "type": "storage.write-file",
      "label": "Save mp3",
      "category": "io",
      "config": {
        "path": "./ai-demo-speech.mp3",
        "contentMode": "base64",
        "inputField": "audio",
        "append": false,
        "createDirs": true,
        "encoding": "utf8"
      },
      "position": {
        "x": 1590,
        "y": 0
      }
    },
    {
      "id": "out",
      "type": "utility.console",
      "label": "Done",
      "category": "utility",
      "config": {
        "message": "Saved ./ai-demo-speech.mp3 — Test demo 13 to hear it transcribed back."
      },
      "position": {
        "x": 2120,
        "y": 0
      }
    }
  ],
  "edges": [
    {
      "id": "e0",
      "sourceNodeId": "seed",
      "sourcePort": "output",
      "targetNodeId": "speak",
      "targetPort": "input"
    },
    {
      "id": "e1",
      "sourceNodeId": "speak",
      "sourcePort": "output",
      "targetNodeId": "play",
      "targetPort": "input"
    },
    {
      "id": "e2",
      "sourceNodeId": "play",
      "sourcePort": "output",
      "targetNodeId": "save",
      "targetPort": "input"
    },
    {
      "id": "e3",
      "sourceNodeId": "save",
      "sourcePort": "output",
      "targetNodeId": "out",
      "targetPort": "input"
    }
  ],
  "triggers": [
    {
      "id": "t0",
      "nodeId": "seed"
    }
  ],
  "meta": {
    "snippets": [],
    "source": "template-gallery",
    "description": "Text becomes speech through the ◈-wired local TTS (Kokoro on :8880), PLAYS right in the Console, and is saved to ./ai-demo-speech.mp3 for demo 13 to transcribe. Change the Inject text and Test again."
  }
}

Generated from the verified demo corpus — this exact document seeds and runs on a fresh Flowdrome. Raw JSON: ai-12-speak-text-voice.json.