podcast

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

When to Use

适用场景

  • User wants to create a podcast episode on any topic
  • User provides a URL or text and wants it turned into a podcast discussion
  • User asks for a "debate", "dialogue", or "discussion" format
  • User says "podcast", "播客", or "录一期节目"
  • 用户想要针对任意主题创建播客节目
  • 用户提供网址或文本,希望将其转化为播客讨论内容
  • 用户要求以“辩论”“对话”或“讨论”形式呈现内容
  • 用户提及"podcast"、"播客"或"录一期节目"

When NOT to Use

不适用场景

  • User wants text-to-speech reading (use
    /speech
    )
  • User wants an explainer video with visuals (use
    /explainer
    )
  • User wants to generate an image (use
    /image-gen
    )
  • User only wants to extract content from a URL without generating audio (use
    /content-parser
    )
  • 用户需要文本转语音朗读(请使用
    /speech
  • 用户需要带视觉效果的讲解视频(请使用
    /explainer
  • 用户需要生成图片(请使用
    /image-gen
  • 用户仅需从网址提取内容而不生成音频(请使用
    /content-parser

Purpose

功能目标

Generate podcast episodes with 1-2 AI speakers discussing a topic. Supports quick overviews, deep analysis, and debate formats. Input can be a topic description, URL(s), or text. Output is a full audio episode with transcript.
生成由1-2位AI主播讨论主题的播客节目。支持快速概述、深度分析和辩论等形式。输入可以是主题描述、网址或文本,输出为包含字幕的完整音频节目。

Hard Constraints

硬性约束

  • No shell scripts. Construct curl commands from the API reference files listed in Resources
  • Always read
    shared/authentication.md
    for API key and headers
  • Follow
    shared/common-patterns.md
    for polling, errors, and interaction patterns
  • Never hardcode speaker IDs — always fetch from the speakers API
  • Never fabricate API endpoints or parameters
  • Always read config following
    shared/config-pattern.md
    before any interaction
  • Always follow
    shared/speaker-selection.md
    for speaker selection (text table + free-text input)
  • Never save files to
    ~/Downloads/
    — use
    .listenhub/podcast/
    from config
<HARD-GATE> Use the AskUserQuestion tool for every multiple-choice step — do NOT print options as plain text. Ask one question at a time. Wait for the user's answer before proceeding to the next step. After all parameters are collected, summarize the choices and ask the user to confirm. Do NOT call any generation API until the user has explicitly confirmed. </HARD-GATE>
  • 禁止使用Shell脚本。需根据资源中列出的API参考文档构造curl命令
  • 务必阅读
    shared/authentication.md
    获取API密钥和请求头信息
  • 遵循
    shared/common-patterns.md
    中的轮询、错误处理和交互模式
  • 禁止硬编码主播ID — 必须通过主播API获取
  • 不得编造API端点或参数
  • 在进行任何交互前,务必遵循
    shared/config-pattern.md
    读取配置
  • 主播选择必须遵循
    shared/speaker-selection.md
    (文本表格+自由文本输入)
  • 禁止将文件保存至
    ~/Downloads/
    — 需使用配置中指定的
    .listenhub/podcast/
    目录
<HARD-GATE> 每个多选步骤都必须使用AskUserQuestion工具 — 不得将选项以纯文本形式打印。一次仅提出一个问题,等待用户回答后再进行下一步。收集所有参数后,汇总用户选择并请求确认。在用户明确确认前,不得调用任何生成API。 </HARD-GATE>

Step -1: API Key Check

步骤-1:API密钥检查

Follow
shared/config-pattern.md
§ API Key Check. If the key is missing, stop immediately.
遵循
shared/config-pattern.md
中的“API密钥检查”部分。如果密钥缺失,立即停止操作。

Step 0: Config Setup

步骤0:配置设置

Follow
shared/config-pattern.md
Step 0.
If file doesn't exist — ask location, then create immediately:
bash
mkdir -p ".listenhub/podcast"
echo '{"outputDir":".listenhub","outputMode":"inline","language":null,"defaultMode":null,"defaultMethod":null,"defaultSpeakers":{}}' > ".listenhub/podcast/config.json"
CONFIG_PATH=".listenhub/podcast/config.json"
遵循
shared/config-pattern.md
中的步骤0。
若配置文件不存在 — 询问存储位置,然后立即创建:
bash
mkdir -p ".listenhub/podcast"
echo '{"outputDir":".listenhub","outputMode":"inline","language":null,"defaultMode":null,"defaultMethod":null,"defaultSpeakers":{}}' > ".listenhub/podcast/config.json"
CONFIG_PATH=".listenhub/podcast/config.json"

(or $HOME/.listenhub/podcast/config.json for global)

(全局配置可使用 $HOME/.listenhub/podcast/config.json)

Then run **Setup Flow** below.

**If file exists** — read config, display summary, and confirm:
当前配置 (podcast): 输出方式:{inline / download / both} 语言偏好:{zh / en / 未设置} 默认模式:{quick / deep / debate / 未设置} 默认生成方式:{one-step / two-step / 未设置} 默认主播:{speakerName(s) / 未设置}
Ask: "使用已保存的配置?" → **确认,直接继续** / **重新配置**
然后执行下方的**设置流程**。

**若配置文件已存在** — 读取配置,显示摘要并请求确认:
当前配置 (podcast): 输出方式:{inline / download / both} 语言偏好:{zh / en / 未设置} 默认模式:{quick / deep / debate / 未设置} 默认生成方式:{one-step / two-step / 未设置} 默认主播:{主播名称 / 未设置}
询问:"使用已保存的配置?" → **确认,直接继续** / **重新配置**

Setup Flow (first run or reconfigure)

设置流程(首次运行或重新配置)

Ask these questions in order, then save all answers to config at once:
  1. outputMode: Follow
    shared/output-mode.md
    § Setup Flow Question.
  2. Language (optional): "默认语言?"
    • "中文 (zh)"
    • "English (en)"
    • "每次手动选择" → keep
      null
  3. Mode (optional): "默认播客模式?"
    • "Quick — 简短概述"
    • "Deep — 深度分析"
    • "Debate — 辩论对话"
    • "每次手动选择" → keep
      null
  4. Method (optional): "默认生成方式?"
    • "一步生成(推荐)" →
      defaultMethod: "one-step"
    • "两步生成(先预览文本)" →
      defaultMethod: "two-step"
    • "每次手动选择" → keep
      null
After collecting answers, save immediately:
bash
undefined
按顺序提出以下问题,然后一次性将所有答案保存至配置:
  1. outputMode:遵循
    shared/output-mode.md
    中的“设置流程问题”部分。
  2. 语言(可选):"默认语言?"
    • "中文 (zh)"
    • "English (en)"
    • "每次手动选择" → 保留
      null
  3. 模式(可选):"默认播客模式?"
    • "Quick — 简短概述"
    • "Deep — 深度分析"
    • "Debate — 辩论对话"
    • "每次手动选择" → 保留
      null
  4. 生成方式(可选):"默认生成方式?"
    • "一步生成(推荐)" →
      defaultMethod: "one-step"
    • "两步生成(先预览文本)" →
      defaultMethod: "two-step"
    • "每次手动选择" → 保留
      null
收集答案后立即保存:
bash
undefined

Follow shared/output-mode.md § Save to Config

遵循 shared/output-mode.md 中的“保存至配置”部分

NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}') echo "$NEW_CONFIG" > "$CONFIG_PATH" CONFIG=$(cat "$CONFIG_PATH")

Note: `defaultSpeakers` are saved after generation (see After Successful Generation section).
NEW_CONFIG=$(echo "$CONFIG" | jq --arg m "$OUTPUT_MODE" '. + {"outputMode": $m}') echo "$NEW_CONFIG" > "$CONFIG_PATH" CONFIG=$(cat "$CONFIG_PATH")

注意:`defaultSpeakers`会在生成完成后保存(请查看“生成成功后”部分)。

Interaction Flow

交互流程

Step 1: Topic / Content Source

步骤1:主题/内容来源

Free text input. Ask the user:
What topic or content would you like to turn into a podcast?
Accept: topic description, URL, or pasted text.
自由文本输入。询问用户:
您想要将什么主题或内容转化为播客?
接受:主题描述、网址或粘贴的文本。

Step 2: Mode

步骤2:模式

If
config.defaultMode
is set, pre-fill and show in summary — skip this question. Otherwise ask:
Question: "What podcast generation mode?"
Options:
  - "Quick" — Short, concise overview (~5 min)
  - "Deep" — Thorough analysis with more detail (~10-15 min)
  - "Debate" — Two speakers with opposing views (requires 2 speakers)
config.defaultMode
已设置,自动填充并显示在摘要中 — 跳过此问题。 否则询问:
问题:"选择播客生成模式?"
选项:
  - "Quick" — 简短概述(约5分钟)
  - "Deep" — 深度分析(内容更详细,约10-15分钟)
  - "Debate" — 两位主播持对立观点(需要2位主播)

Step 3: Language

步骤3:语言

If
config.language
is set, pre-fill and show in summary — skip this question. Otherwise ask:
Question: "What language?"
Options:
  - "Chinese (zh)" — Content in Mandarin Chinese
  - "English (en)" — Content in English
config.language
已设置,自动填充并显示在摘要中 — 跳过此问题。 否则询问:
问题:"选择语言?"
选项:
  - "Chinese (zh)" — 内容为中文普通话
  - "English (en)" — 内容为英文

Step 4: Speaker Count

步骤4:主播数量

Question: "How many speakers?"
Options:
  - "1 speaker (solo)" — Monologue style
  - "2 speakers (dialogue)" — Conversation style
Note: Debate mode automatically sets 2 speakers.
问题:"需要几位主播?"
选项:
  - "1位主播(单人独白)" — 独白风格
  - "2位主播(对话)" — 对话风格
注意:辩论模式会自动设置为2位主播。

Step 5: Speaker Selection

步骤5:主播选择

Follow
shared/speaker-selection.md
for the full selection flow, including:
  • Default from
    config.defaultSpeakers.{language}
    (skip step if set)
  • Text table + free-text input
  • Input matching and re-prompt on no match
For 2-speaker mode (dialogue/debate): run selection twice (or until both are chosen).
遵循
shared/speaker-selection.md
中的完整选择流程,包括:
  • config.defaultSpeakers.{language}
    读取默认设置(若已设置则跳过此步骤)
  • 文本表格+自由文本输入
  • 输入匹配,若无匹配则重新提示
对于双主播模式(对话/辩论):需执行两次选择流程(直到选好两位主播)。

Step 6: Reference Materials (optional)

步骤6:参考资料(可选)

Question: "Any reference materials to include?"
Options:
  - "Yes, URL(s)" — Provide URLs to analyze
  - "Yes, text" — Paste reference text
  - "No references" — Generate from topic alone
问题:"是否需要加入参考资料?"
选项:
  - "是,提供网址" — 提交用于分析的网址
  - "是,提供文本" — 粘贴参考文本
  - "无需参考资料" — 仅根据主题生成内容

Step 7: Generation Method

步骤7:生成方式

If
config.defaultMethod
is set, pre-fill and show in summary — skip this question. Otherwise ask:
Question: "How would you like to generate?"
Options:
  - "One step (recommended)" — Generate text + audio together, faster
  - "Two steps (review first)" — Generate text, review/edit, then generate audio
config.defaultMethod
已设置,自动填充并显示在摘要中 — 跳过此问题。 否则询问:
问题:"选择生成方式?"
选项:
  - "一步生成(推荐)" — 同时生成文本和音频,速度更快
  - "两步生成(先预览)" — 先生成文本,审核/编辑后再生成音频

Step 8: Confirm & Generate

步骤8:确认并生成

Summarize all choices:
Ready to generate podcast:

  Topic: {topic}
  Mode: {mode}
  Language: {language}
  Speakers: {speaker name(s)}
  References: {yes/no}
  Method: {one-step/two-step}

  Proceed?
Wait for explicit confirmation before calling any API.
汇总所有选择:
准备生成播客:

  主题:{topic}
  模式:{mode}
  语言:{language}
  主播:{主播姓名}
  参考资料:{是/否}
  生成方式:{一步生成/两步生成}

  是否继续?
等待用户明确确认后,再调用任何API。

Workflow

工作流

One-Step Generation

一步生成

  1. Submit (foreground):
    POST /podcast/episodes
    with collected parameters → extract
    episodeId
  2. Tell the user the task is submitted
  3. Poll (background): Run the following exact bash command with
    run_in_background: true
    and
    timeout: 600000
    . Do NOT use python3, awk, or any other JSON parser — use
    jq
    as shown:
    bash
    EPISODE_ID="<id-from-step-1>"
    for i in $(seq 1 30); do
      RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/podcast/episodes/$EPISODE_ID" \
        -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
      STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.processStatus // "pending"')
      case "$STATUS" in
        success|completed) echo "$RESULT"; exit 0 ;;
        failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
        *) sleep 10 ;;
      esac
    done
    echo "TIMEOUT" >&2; exit 2
  4. When notified of completion, Step 6: Present result
    Read
    OUTPUT_MODE
    from config. Follow
    shared/output-mode.md
    for behavior.
    inline
    or
    both
    : Display
    audioUrl
    as a clickable link.
    Present:
    播客已生成!
    
    在线收听:{audioUrl}
    字幕:{subtitlesUrl}(如有)
    时长:{audioDuration / 1000}s
    消耗积分:{credits}
    download
    or
    both
    : Also download the file.
    bash
    DATE=$(date +%Y-%m-%d)
    JOB_DIR=".listenhub/podcast/${DATE}-{episodeId}"
    mkdir -p "$JOB_DIR"
    curl -sS -o "${JOB_DIR}/{episodeId}.mp3" "{audioUrl}"
    Present the download path in addition to the above summary.
  5. Offer to show transcript or provide download URL on request
  1. 提交(前台):调用
    POST /podcast/episodes
    接口并传入收集到的参数 → 提取
    episodeId
  2. 告知用户任务已提交
  3. 轮询(后台):执行以下精确的bash命令,设置
    run_in_background: true
    timeout: 600000
    。禁止使用python3、awk或其他JSON解析器 — 必须使用如下所示的
    jq
    bash
    EPISODE_ID="<id-from-step-1>"
    for i in $(seq 1 30); do
      RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/podcast/episodes/$EPISODE_ID" \
        -H "Authorization: Bearer $LISTENHUB_API_KEY" 2>/dev/null)
      STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.processStatus // "pending"')
      case "$STATUS" in
        success|completed) echo "$RESULT"; exit 0 ;;
        failed|error) echo "FAILED: $RESULT" >&2; exit 1 ;;
        *) sleep 10 ;;
      esac
    done
    echo "TIMEOUT" >&2; exit 2
  4. 收到完成通知后,执行步骤6:展示结果
    从配置中读取
    OUTPUT_MODE
    ,遵循
    shared/output-mode.md
    中的行为规则。
    inline
    both
    模式
    :将
    audioUrl
    显示为可点击链接。
    展示内容:
    播客已生成!
    
    在线收听:{audioUrl}
    字幕:{subtitlesUrl}(如有)
    时长:{audioDuration / 1000}秒
    消耗积分:{credits}
    download
    both
    模式
    :同时下载文件。
    bash
    DATE=$(date +%Y-%m-%d)
    JOB_DIR=".listenhub/podcast/${DATE}-{episodeId}"
    mkdir -p "$JOB_DIR"
    curl -sS -o "${JOB_DIR}/{episodeId}.mp3" "{audioUrl}"
    除上述摘要外,还需展示文件下载路径。
  5. 主动询问用户是否需要查看字幕或提供下载链接

Two-Step Generation

两步生成

  1. Step 1 — Submit text (foreground):
    POST /podcast/episodes/text-content
    → extract
    episodeId
  2. Poll text (background): Use the exact
    jq
    -based polling loop above (substitute endpoint
    podcast/episodes/text-content/{episodeId}
    if needed), with
    run_in_background: true
    and
    timeout: 600000
  3. When notified, save draft to config output dir:
    • Create
      .listenhub/podcast/YYYY-MM-DD-{episodeId}/
    • Write
      {episodeId}-draft.md
      (human-readable:
      **{speakerName}**: {content}
      per line)
    • Write
      {episodeId}-draft.json
      (raw
      scripts
      array)
    • Present the draft location and content preview
  4. STOP: Present the draft and wait for explicit user approval
  5. Step 2 — Submit audio (foreground, after approval):
    • No changes:
      POST /podcast/episodes/{episodeId}/audio
      with
      {}
    • With edits:
      POST /podcast/episodes/{episodeId}/audio
      with modified
      {scripts: [...]}
  6. Poll audio (background): Same exact
    jq
    -based loop,
    run_in_background: true
    ,
    timeout: 600000
  7. When notified, download audio to same folder:
    • curl -sS -o .listenhub/podcast/{dir}/{episodeId}.mp3 {audioUrl}
    • Present final result (same format as one-step, folder now has draft + final files)
  1. 步骤1 — 提交文本(前台):调用
    POST /podcast/episodes/text-content
    接口 → 提取
    episodeId
  2. 轮询文本生成状态(后台):使用上述精确的
    jq
    轮询循环(必要时替换为
    podcast/episodes/text-content/{episodeId}
    端点),设置
    run_in_background: true
    timeout: 600000
  3. 收到完成通知后,将草稿保存至配置输出目录
    • 创建目录
      .listenhub/podcast/YYYY-MM-DD-{episodeId}/
    • 写入文件
      {episodeId}-draft.md
      (人类可读格式:每行格式为
      **{主播姓名}**: {内容}
    • 写入文件
      {episodeId}-draft.json
      (原始
      scripts
      数组)
    • 展示草稿存储位置和内容预览
  4. 暂停操作:展示草稿并等待用户明确批准
  5. 步骤2 — 提交音频生成请求(前台,获得批准后)
    • 无需修改:调用
      POST /podcast/episodes/{episodeId}/audio
      接口,传入
      {}
    • 需要修改:调用
      POST /podcast/episodes/{episodeId}/audio
      接口,传入修改后的
      {scripts: [...]}
  6. 轮询音频生成状态(后台):使用相同的
    jq
    轮询循环,设置
    run_in_background: true
    timeout: 600000
  7. 收到完成通知后,将音频下载至同一目录
    • 执行命令
      curl -sS -o .listenhub/podcast/{dir}/{episodeId}.mp3 {audioUrl}
    • 展示最终结果(格式与一步生成相同,目录中包含草稿和最终文件)

After Successful Generation

生成成功后

Update config with the choices made this session:
bash
NEW_CONFIG=$(echo "$CONFIG" | jq \
  --arg lang "{language}" \
  --arg mode "{mode}" \
  --arg method "{one-step/two-step}" \
  --argjson speakers '{"{language}": ["{speakerId}"]}' \
  '. + {"language": $lang, "defaultMode": $mode, "defaultMethod": $method, "defaultSpeakers": (.defaultSpeakers + $speakers)}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
更新配置,保存本次会话的选择:
bash
NEW_CONFIG=$(echo "$CONFIG" | jq \
  --arg lang "{language}" \
  --arg mode "{mode}" \
  --arg method "{one-step/two-step}" \
  --argjson speakers '{"{language}": ["{speakerId}"]}' \
  '. + {"language": $lang, "defaultMode": $mode, "defaultMethod": $method, "defaultSpeakers": (.defaultSpeakers + $speakers)}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"

API Reference

API参考

  • Speaker list:
    shared/api-speakers.md
  • Speaker selection guide:
    shared/speaker-selection.md
  • Episode creation:
    shared/api-podcast.md
  • Polling:
    shared/common-patterns.md
    § Async Polling
  • Config pattern:
    shared/config-pattern.md
  • 主播列表:
    shared/api-speakers.md
  • 主播选择指南:
    shared/speaker-selection.md
  • 节目创建:
    shared/api-podcast.md
  • 轮询机制:
    shared/common-patterns.md
    § 异步轮询
  • 配置模式:
    shared/config-pattern.md

Composability

可组合性

  • Invokes: speakers API (for speaker selection)
  • Invoked by: content-planner (Phase 3)
  • 调用:主播API(用于主播选择)
  • 被调用:content-planner(第3阶段)

Example

示例

User: "Make a podcast about the latest AI developments"
Agent workflow:
  1. Detect: podcast request, topic = "latest AI developments"
  2. Ask mode → user picks "Deep"
  3. Ask language → "English"
  4. Ask speakers → 1 speaker
  5. Fetch speakers list, user picks "cozy-man-english"
  6. No references
  7. One-step generation
bash
curl -sS -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [{"type": "text", "content": "The latest AI developments"}],
    "speakers": [{"speakerId": "cozy-man-english"}],
    "language": "en",
    "mode": "deep"
  }'
Poll until complete, then present the result with title and listen link.
用户:"Make a podcast about the latest AI developments"
Agent工作流:
  1. 检测到播客请求,主题为"latest AI developments"
  2. 询问模式 → 用户选择"Deep"
  3. 询问语言 → "English"
  4. 询问主播数量 → 1位主播
  5. 获取主播列表,用户选择"cozy-man-english"
  6. 无需参考资料
  7. 选择一步生成
bash
curl -sS -X POST "https://api.marswave.ai/openapi/v1/podcast/episodes" \
  -H "Authorization: Bearer $LISTENHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [{"type": "text", "content": "The latest AI developments"}],
    "speakers": [{"speakerId": "cozy-man-english"}],
    "language": "en",
    "mode": "deep"
  }'
持续轮询直到完成,然后展示包含标题和收听链接的结果。