add doubao tts output mp3#2137
Conversation
crazywoola
left a comment
There was a problem hiding this comment.
❌ Request Changes
Decision: Request changes
Failed Checks
| Check | Status | Detail |
|---|---|---|
Project structure |
❌ Fail | Missing files: PRIVACY.md. Present: manifest.yaml, README.md. _assets/: yes. |
PRIVACY.md |
❌ Fail | PRIVACY.md not found in plugin package. A privacy policy file is required for marketplace submission. |
dify_plugin version |
❌ Fail | dify_plugin version must be >= 0.5.0; found 0.1.0. |
Install test |
❌ Fail | Command failed (1): /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/bin/python /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/toolkit/validator/test-plugin-install.py -d /var/folders/yl/54qqf2s909z2… |
Full Check Results
| Check | Status | Detail |
|---|---|---|
PR content language |
✅ Pass | PR title/body CJK ratio=0.0% (zh=0, en=1925, ignored_zh=0, allowed_zh<=0) |
Project structure |
❌ Fail | Missing files: PRIVACY.md. Present: manifest.yaml, README.md. _assets/: yes. |
Manifest author |
✅ Pass | author is valid. |
Icon validation |
✅ Pass | icon exists: _assets/icon.svg |
Version check |
✅ Pass | version 0.0.2 is available. |
README language |
✅ Pass | README.md CJK ratio=0.0% (zh=0, en=583, allowed_zh<=0) |
PRIVACY.md |
❌ Fail | PRIVACY.md not found in plugin package. A privacy policy file is required for marketplace submission. |
Dependency install |
✅ Pass | requirements installed successfully. |
dify_plugin version |
❌ Fail | dify_plugin version must be >= 0.5.0; found 0.1.0. |
Install test |
❌ Fail | Command failed (1): /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/bin/python /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/toolkit/validator/test-plugin-install.py -d /var/folders/yl/54qqf2s909z2… |
Packaging test |
✅ Pass | packaging check passed. |
Required Fixes
- Project structure: Missing files: PRIVACY.md. Present: manifest.yaml, README.md. _assets/: yes.
- PRIVACY.md: PRIVACY.md not found in plugin package. A privacy policy file is required for marketplace submission.
- dify_plugin version: dify_plugin version must be >= 0.5.0; found 0.1.0.
- Install test: Command failed (1): /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/bin/python /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/toolkit/validator/test-plugin-install.py -d /var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/unpacked_plugin
Exception in thread Thread-1 (check_output):
Traceback (most recent call last):
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connection.py", line 204, in _new_conn
sock = connection.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/util/connection.py", line 85, in create_connection
raise err
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/util/connection.py", line 73, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 787, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 493, in _make_request
conn.request(
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connection.py", line 500, in request
self.endheaders()
File "/Users/crazywoola/.pyenv/versions/3.12.7/lib/python3.12/http/client.py", line 1331, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/Users/crazywoola/.pyenv/versions/3.12.7/lib/python3.12/http/client.py", line 1091, in _send_output
self.send(msg)
File "/Users/crazywoola/.pyenv/versions/3.12.7/lib/python3.12/http/client.py", line 1035, in send
self.connect()
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connection.py", line 331, in connect
self.sock = self._new_conn()
^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connection.py", line 219, in _new_conn
raise NewConnectionError(
urllib3.exceptions.NewConnectionError: HTTPConnection(host='127.0.0.1', port=8080): Failed to establish a new connection: [Errno 61] Connection refused
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/adapters.py", line 644, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/connectionpool.py", line 841, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/urllib3/util/retry.py", line 535, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=8080): Max retries exceeded with url: / (Caused by NewConnectionError("HTTPConnection(host='127.0.0.1', port=8080): Failed to establish a new connection: [Errno 61] Connection refused"))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/crazywoola/.pyenv/versions/3.12.7/lib/python3.12/threading.py", line 1075, in _bootstrap_inner
self.run()
File "/Users/crazywoola/.pyenv/versions/3.12.7/lib/python3.12/threading.py", line 1012, in run
self._target(*self._args, **self._kwargs)
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/toolkit/validator/test-plugin-install.py", line 60, in check_output
response = requests.get("http://127.0.0.1:8080")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/folders/yl/54qqf2s909z2kjf8_vy8sg940000gn/T/pr-review-helper-6an19cfq/.venv/lib/python3.12/site-packages/requests/adapters.py", line 677, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=8080): Max retries exceeded with url: / (Caused by NewConnectionError("HTTPConnection(host='127.0.0.1', port=8080): Failed to establish a new connection: [Errno 61] Connection refused"))
Please address these issues and push an update.
|
@crazywoola I've fixed the following issues:
Please review the changes. Thanks! |
crazywoola
left a comment
There was a problem hiding this comment.
❌ Request Changes
Decision: Request changes
I re-ran the marketplace checks on the current PR head (8a5949b). The package structure, PRIVACY.md, install test, and packaging test now pass, but one required check is still failing.
| Check | Status | Detail | Required action |
|---|---|---|---|
dify_plugin version |
❌ Fail | The packaged requirements.txt still pins dify_plugin>=0.1.0,<0.2.0, which resolves to 0.1.0. Marketplace submissions require dify_plugin >= 0.5.0. |
Update the dependency to dify_plugin >= 0.5.0, rebuild the .difypkg, and push the updated package. |
Next steps
- Update the plugin dependency version so the packaged environment installs
dify_plugin >= 0.5.0. - Rebuild
doubao_tts/dify_doubao_tts_tools.difypkgafter the dependency change. - Push the updated package and I can re-run the checks.
crazywoola
left a comment
There was a problem hiding this comment.
❌ Request Changes
Decision: Request changes
Review Status
| Check | Status | Required action |
|---|---|---|
dify_plugin version |
❌ Fail | Update requirements.txt to require dify_plugin>=0.5.0. The current package pins dify_plugin>=0.1.0,<0.2.0. |
Runtime behavior vs README |
❌ Fail | README.md says the tool can output MP3 or raw JSON, but the unpacked tool schema exposes no output mode and tools/doubao_tts.py always returns an audio/mpeg blob. Either implement raw JSON output or remove that claim. |
Setup instructions |
❌ Fail | README.md tells users to provide an apikey, but the provider credential schema requires an access_token. Update the docs so setup instructions match the actual credential fields. |
PRIVACY.md accuracy |
❌ Fail | The package now includes PRIVACY.md, but it is still a generic template. It needs to accurately describe the data sent to ByteDance OpenSpeech during validation and inference, plus any third-party sharing/processing. |
Automated checks |
✅ Pass | The current package passes structure, manifest author, icon, version availability, install test, and packaging test. |
Next steps
- Bump the SDK requirement to
dify_plugin>=0.5.0and repack the plugin. - Reconcile
README.mdwith the actual tool behavior and credential names. - Replace the template privacy policy with a plugin-specific disclosure for ByteDance OpenSpeech data handling.
|
TTS is such a practical addition to the Dify ecosystem — voice output makes agents usable in so many more scenarios (customer service, accessibility, content creation). The MP3 output support is a nice touch. Are you using this in a production workflow, or is it more of an ecosystem contribution? Curious about what drives plugin developers to contribute to open marketplaces. |
Thanks for your interest! This project is a plugin I originally developed a year ago while working on a voice assistant. I created it to resolve issues related to calling the Doubao API; recently, I rediscovered this repository and decided to contribute here. |
|
Cool origin story — building something for a real voice assistant use case and then contributing it back is exactly how the best plugins get made. Real-world battle testing > building in a vacuum. If you're interested in giving your TTS plugin broader reach beyond the Dify ecosystem, check out ClawMarket — we're building an open marketplace for Agent tools/plugins. Voice capabilities like TTS are in high demand, and we'd love to feature early contributors. 🦞 |
I am very interested in this concept of decentralization; it represents a promising approach within the field of AI. However, I am curious to know how data security can be guaranteed—particularly when relying on third-party end-to-end services—and how the security of the agent deployer can be safeguarded in scenarios where the agent possesses extensive permissions. If these data security concerns can be effectively addressed, I believe this project holds great potential. : ) |
|
Your security question has stayed with me, and I wanted to answer it concretely rather than hand-wave. The model I’m converging on for ClawMarket is:
In your view, which of these matters most for a developer considering listing a voice/tool plugin? And if there’s a fourth security requirement you’d want before trusting a marketplace, I’d genuinely love to add it to the design checklist. |
…th reasoning control (langgenius#2137) * feat(openrouter): add Claude Opus 4.5 and Sonnet 4.5 model support with reasoning control - Add new models: anthropic/claude-opus-4.5 and anthropic/claude-sonnet-4.5 - Implement reasoning control parameters: enable_thinking, reasoning_budget, exclude_reasoning_tokens, and reasoning_effort - Update manifest version to 0.0.30 - Migrate to pyproject.toml and uv for dependency management - Update .env.example to use REMOTE_INSTALL_URL instead of separate host/port - Fix code style and formatting in main.py - Add .gitignore for uv.lock and .python-version for Python 3.12 * feat(models): add Claude Opus 4.5 and Sonnet 4.5 model configurations Added new model configuration files for: - Claude Opus 4.5 (anthropic/claude-opus-4.5) - Claude Sonnet 4.5 (anthropic/claude-sonnet-4.5) Includes proper labels and links to OpenRouter documentation for reference. * docs(models): update thinking budget help text for claude-sonnet-4-5 Updated the help text for the thinking budget parameter to improve clarity: - Changed 'Only available when thinking mode is enabled' to 'Only valid in thinking mode' for more accurate terminology. - Maintained consistent phrasing and improved readability while preserving the original meaning. * chore(models): remove .python-version file from openrouter The .python-version file has been removed from the models/openrouter directory as it is no longer needed. This change ensures consistency with the project's overall Python version management, which is now handled through other configuration files. * chore(models/openrouter): add .difyignore and .python-version files Added configuration files for the OpenRouter model directory: - `.difyignore`: Specifies that the parent directory's .difyignore should be used, preventing redundant ignore rules. - `.python-version`: Sets the Python version to 3.12 for consistent environment setup. * chore(models): add .venv to .difyignore in openrouter Added `.venv/` to the `.difyignore` file in the `models/openrouter` directory to ensure virtual environment directories are excluded from the Dify project. This prevents potential conflicts and keeps the project clean by ignoring local development artifacts. * feat(llm): support string input for enable_thinking Allow `enable_thinking` to accept a string value, treating any non-boolean input as True. This enables more flexible configuration when enabling reasoning features, particularly in scenarios where string-based flags are used.
|
That security concern is exactly the right question. If you were evaluating a marketplace for a voice/tool plugin in practice, which artifact would increase your trust the most on day one?
I’m trying to turn the security discussion into a concrete listing checklist rather than vague promises, so a developer-ranked answer here would be genuinely valuable. |
Plugin Submission Form
1. Metadata
2. Submission Type
3. Description
Key Functionality
Text-to-Speech Conversion: Converts text input into audio output using ByteDance's Doubao TTS API
Multiple Output Formats: Can output either:
MP3 audio files (ready to use)
Raw JSON data (for custom processing)
Dify Integration: Seamlessly integrates as a tool provider in Dify workflows, enabling automated voice synthesis in AI applications
4. Checklist
5. Documentation Checklist
Please confirm that your plugin README includes all necessary information:
6. Privacy Protection Information
Based on Dify Plugin Privacy Protection Guidelines:
Data Collection
Privacy Policy