Skip to content

bump keenable to 0.1.2 (search results had no text) - #2899

Open
ilya-bogin-keenable wants to merge 3 commits into
langgenius:mainfrom
ilya-bogin-keenable:fix/keenable-0.1.1
Open

bump keenable to 0.1.2 (search results had no text)#2899
ilya-bogin-keenable wants to merge 3 commits into
langgenius:mainfrom
ilya-bogin-keenable:fix/keenable-0.1.1

Conversation

@ilya-bogin-keenable

@ilya-bogin-keenable ilya-bogin-keenable commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Plugin Submission

Bug-fix bump of the Keenable plugin, 0.1.10.1.2. Follow-up to #2582 and #2586.

Plugin information

Submission type

  • New plugin
  • Version update

What changed

Search results reached the model with no text.

The Keenable API returns both description and snippet on every search result. description is frequently empty and snippet carries the page text, but the tool built its digest from description:

snippet = (result.get("description") or "").strip()

Verified against the live keyless endpoint: 10/10 results came back with len(description) == 0 and len(snippet) between 2000 and 2600. So the text message the model reads listed titles and URLs with nothing under them. This has been the case since 0.1.0 shipped on 2026-06-22.

The fix reads snippet first with a description fallback. The text is whitespace-collapsed — raw page text arrives with newlines, which broke the digest's one-line-per-field layout — and capped at 500 characters, since Keenable returns whole pages where other search engines return a short snippet. The untouched results still go out through create_json_message, so the workflow json output is unchanged.

manifest.yaml also gains the now-required repo and contact fields, which were not requirements when 0.1.1 was reviewed. The README gains a Connection requirements section and requirements.txt gains an upper bound on requests, both to clear pre-check warnings.

Everything from 0.1.1 (the SSRF-guard and API-key-redaction hardening from #2586) is carried forward unchanged — the package was rebuilt from the plugin's source repository at the 0.1.1 tree, not from an older copy.

Risk level

  • Low risk
  • Medium risk
  • High risk

Additive bug fix to an existing plugin. No new tools, no new credentials, no new network destinations, no change to the permission surface.

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.

Security and privacy notes

Arbitrary URL fetching — yes, and it is the point of one of the two tools. keenable_fetch takes a user- or agent-supplied URL and retrieves that page as markdown through Keenable's /v1/fetch endpoint. keenable_search sends a query string. Both are outbound HTTPS calls to api.keenable.ai and nowhere else; the base URL is not agent-settable.

The fetch path is SSRF-guarded before any request leaves the plugin: non-http(s) schemes and private or internal hosts (loopback, RFC1918, link-local including 169.254.169.254, reserved, multicast) are refused. There is a test for exactly that (test_fetch_rejects_unsafe_urls_without_calling_api), which asserts the API is never called for those inputs.

No command execution, no code execution, no SQL, no SSH/SFTP, no browser automation, no local file operations, no proxying. No health, financial, biometric, or children's data is handled — the plugin sends a query or a URL and returns public web content. Credentials: one optional API key, and the plugin works with no key at all (keyless free tier). Data handling is documented in PRIVACY.md.

Local validation

$ .venv/bin/python -m pytest tests/ -q
59 passed in 11.03s

Up from 57. Two cases were added for the snippet fallback and for the whitespace collapse + cap, and the pre-existing fixture was corrected: it populated description, a shape no real response has, which is precisely why this bug passed review the first time.

$ dify-plugin v0.6.10 plugin package .
INFO plugin packaged successfully

$ python3 validator/check-manifest-metadata.py -d unpacked
Manifest metadata check passed

Package verified by unzipping it and reading the contents rather than trusting the build: 15 files, version: 0.1.2, the shipped tools/keenable_search.py really does read snippet, and utils/keenable_client.py still carries the 0.1.1 _candidate_ips SSRF hardening.

Reviewer notes

No migration needed and no breaking changes: the tool signature, parameters, credentials and JSON output shape are all unchanged. Only the text of the human/LLM-readable message differs — it now has content in it.

The Keenable API returns both `description` and `snippet` on every result.
`description` is frequently empty and `snippet` carries the page text, so the
digest the model reads listed titles and URLs with no text. Verified against
the live keyless endpoint: 10/10 results had an empty `description` and a
`snippet` of 2000-2600 characters.

Reads `snippet` first with a `description` fallback, whitespace-collapsed
(raw page text arrives with newlines, which broke the digest layout) and
capped at 500 characters. The untouched results still go out through
`create_json_message`, so the workflow `json` output is unchanged.
@github-actions github-actions Bot added the risk: missing Missing or invalid Marketplace risk selection label Aug 16, 2026
The Marketplace pre-check tightened since 0.1.0 was reviewed. Repackaged with:

- manifest.yaml gains the now-required `repo` and `contact` fields.
- README gains a Connection requirements section (outbound HTTPS to
  api.keenable.ai only, port 443, no inbound, no local network; the fetch tool
  refuses private/internal addresses before issuing a request).
- requirements.txt pins an upper bound on requests.

All toolkit validators now pass locally against the unpacked package: manifest
metadata, PR body, sensitive capability disclosure, package contents, secrets,
binaries, README metadata, dependencies, access domains, prohibited financial
activity, python safety. 48 tests pass.
@github-actions github-actions Bot added risk: low Low-risk Marketplace submission and removed risk: missing Missing or invalid Marketplace risk selection labels Aug 17, 2026
The previous push targeted 0.1.1, which the Marketplace already carries: it
shipped 2026-06-23 via langgenius#2586 (SSRF-guard and API-key-redaction hardening), so
the version check blocked it correctly. Rebuilt as 0.1.2 from the plugin's own
source repository at the 0.1.1 tree, so that hardening is carried forward
rather than reverted — the earlier package had been built from a copy that
predated langgenius#2586.

Verified inside the archive: version 0.1.2, tools/keenable_search.py reads
snippet, utils/keenable_client.py still has the 0.1.1 _candidate_ips guard.
All toolkit validators pass locally; 59 tests.
@ilya-bogin-keenable ilya-bogin-keenable changed the title bump keenable to 0.1.1 (search results had no text) bump keenable to 0.1.2 (search results had no text) Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: low Low-risk Marketplace submission

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant