Skip to content

feat: add DeepSeek Search plugin (web search & fetch tools) - #3398

Open
Jay0130-a wants to merge 1 commit into
langgenius:mainfrom
Jay0130-a:add-deepseek-search-plugin
Open

Jay0130-a wants to merge 1 commit into
langgenius:mainfrom
Jay0130-a:add-deepseek-search-plugin

Conversation

@Jay0130-a

@Jay0130-a Jay0130-a commented Oct 18, 2026 •

Copy link
Copy Markdown

Plugin Submission

Plugin information

Submission type

  • New plugin
  • Version update

What changed

New tool plugin for the DeepSeek Tools API (https://api.deepseek.com/v1/tools/search and /v1/tools/fetch), which uses the same API key as the DeepSeek model platform. Two tools:

  1. deepseek_web_search — AI-native web search. Each result carries title, url, snippet, summary, site_name, date, rerank_score (0-3), and authority (0-4), so agents can filter on quality instead of trusting position order. Supports DeepSeek's search operators (site:, -site:, -"excluded phrase", "exact phrase", lang:, after:, before:), which are passed through as-is. Optional ori_question improves relevance; need_content optionally includes full extracted page content.
  2. deepseek_web_fetch — fetch a single page via DeepSeek's fetch infrastructure and return title + body as clean Markdown. The plugin forwards only the URL; retrieval/extraction happen on DeepSeek's side.

Design notes:

  • No dependencies beyond dify_plugin and httpx — a single shared httpx.Client (Bearer auth, 60 s timeout) against the two fixed endpoints.
  • URL validation rejects non-http(s) schemes, empty hosts, and embedded credentials (user:pass@), matching the API's documented URL constraints.
  • All errors are mapped to user-safe messages by HTTP status (401 / 403 / 422 / 429 / 5xx); the API key never appears in any error text or log.
  • PRIVACY.md states exactly what is sent to DeepSeek (query/URL parameters only) and that nothing is stored or logged locally.

Risk level

  • Low risk
  • Medium risk
  • High risk

Search queries and fetch URLs are user content sent to an external service (DeepSeek). All requests target the single fixed host api.deepseek.com; the plugin executes no code, commands, SQL, file operations, or browser automation, and does not proxy arbitrary URLs itself.

Required checks

  • I have read and followed the Marketplace submission requirements.
  • I have read and comply with the Plugin Developer Agreement.
  • I tested this plugin on Dify Community Edition and Dify Cloud, or documented any limitation below.
  • The package contains only files needed at runtime.
  • The package does not contain secrets, local credentials, .env files, .git directories, virtual environments, caches, logs, or IDE files.
  • The package does not contain executables or bundled binaries, or I explained why they are required below.
  • The plugin README includes setup steps, usage instructions, required APIs or credentials, connection requirements, and the source repository link.
  • The plugin includes PRIVACY.md or a hosted privacy policy, and manifest.yaml references it.
  • All user-facing text is primarily in English, with any localized README files following the i18n guidance.

Limitation note: none. Fully verified end-to-end on Dify Community Edition (install, credential validation, live tool calls for both tools) — see the verification report comment below.

Security and privacy notes

  • The plugin sends only tool parameters (search query / URL / count flags) to api.deepseek.com with the user's own Bearer key.
  • The API key is stored as a Dify secret credential; error messages are derived from HTTP status codes and server messages only — no key material can appear in tool output.
  • Request timeout is capped at 60 s per call; rate-limit (429) responses surface a clear message instead of retry amplification (Search and Fetch each allow 5 QPS per account).

Local validation

$ python -m pytest tests/test_plugin_helpers.py -q
16 passed in 0.66s
  • All four YAML files (manifest / provider / two tools) parse with yaml.safe_load; provider and both tool classes import cleanly under dify_plugin>=0.9.0.
  • Package verified: deepseek_search-0.0.1.difypkg contains exactly the 18 runtime files (source + docs + icon), no caches/tests/secrets.

Reviewer notes

  • The .difypkg in this PR was produced from the committed source tree at the same commit.
  • deepseek_web_fetch fetches pages through DeepSeek's own fetch service; the plugin itself only calls the fixed DeepSeek endpoints.

@github-actions github-actions Bot added the risk: medium Medium-risk Marketplace submission label Oct 18, 2026
The daemon requires the author part of a plugin_unique_identifier
to match [a-z0-9_-]{1,64}; the mixed-case GitHub username was
rejected at install time. Verified end-to-end on Dify Community
Edition: the package now uploads, installs, and its credential
validation runs against the live API.
@Jay0130-a
Jay0130-a force-pushed the add-deepseek-search-plugin branch from 721540f to 5eb95f7 Compare October 19, 2026 04:21
@Jay0130-a

Jay0130-a commented Oct 19, 2026 •

Copy link
Copy Markdown
Author

End-to-end verification on Dify Community Edition (done ✅)

Installed and exercised the plugin on a fresh Dify Community Edition deployment (Docker Compose, langgenius/dify@main with plugin daemon 0.6.11 runtime, Windows host / WSL2).

What was verified

Step Result
Package upload (/plugin/upload/pkg) ✅ manifest decoded: author jay0130-a, name deepseek_search, bilingual labels
Plugin install (daemon-side dependency install into plugin venv) ✅ status: success
Provider registration ✅ DeepSeek Search listed in workspace tool providers
Credential validation with an invalid key ✅ real call to api.deepseek.com returned 401 → plugin surfaces "DeepSeek rejected the API key (unauthorized). Re-enter a valid key in the plugin credentials." (the mapped message from tools/_errors.py)
deepseek_web_search live call ✅ succeeded in 0.51s — query What is Dify open-source LLM app platform? site:github.com with ori_question returned ranked results with rerank_score (e.g. 1.79), site_name, date populated; ~29k chars of formatted markdown output
deepseek_web_fetch live call ✅ succeeded in 9.3s — fetched https://dify.ai, returned page title + body as clean Markdown
Error-path behavior ✅ a URL the DeepSeek fetch service cannot retrieve (raw.githubusercontent.com → HTTP 404 from upstream) surfaces a user-safe message with the request id and the workflow node degrades gracefully instead of crashing

One real bug this E2E caught (fixed in 5eb95f7)

The first package failed to install with plugin_unique_identifier is not valid. Root cause: the daemon requires the author part of the identifier to match [a-z0-9_-]{1,64} (lowercase only), and the mixed-case GitHub username Jay0130-a was rejected. The manifest now uses jay0130-a, and the submission directory was renamed accordingly. This is exactly the class of issue a code-only review would not have caught — thanks for the E2E requirement.

Environment notes

  • FORCE_VERIFYING_SIGNATURE=false was set on the self-hosted instance to allow installing this unsigned package; the PR keeps the standard marketplace packaging.
  • The .difypkg in this PR is byte-identical to the package used for this verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium Medium-risk Marketplace submission

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant