Skip to content

feat: add Dakera Memory tool plugin (v0.0.1)#2642

Merged
crazywoola merged 2 commits into
langgenius:mainfrom
ferhimedamine:feat/dakera-memory-plugin
Jul 8, 2026
Merged

feat: add Dakera Memory tool plugin (v0.0.1)#2642
crazywoola merged 2 commits into
langgenius:mainfrom
ferhimedamine:feat/dakera-memory-plugin

Conversation

@ferhimedamine

@ferhimedamine ferhimedamine commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Plugin Submission

Plugin information

Submission type

  • New plugin
  • Version update

What changed

New tool plugin that gives Dify agents persistent, decay-weighted memory backed by a
self-hosted Dakera server. Dakera importance-scores memories and lets them
decay over time, so stale context stops competing with fresh, relevant facts across sessions.

Six tools, namespaced by agent_id, covering the full memory lifecycle:

Tool Purpose Endpoint
Store Memory Persist a concise fact (optional importance 0–1, session_id, tags). POST /v1/memory/store
Recall Memory Top-k semantic retrieval for a natural-language query, ranked by score. POST /v1/memory/recall
Search Memory Filtered browse/list — optional text query + tag/importance/count filters. POST /v1/memory/search
Get Memory Fetch a single memory by ID. GET /v1/memory/get/{id}
Update Memory Change an existing memory's content (re-embedded), importance, or tags. PUT /v1/memory/update/{id}
Forget Memory Delete by IDs / session / tags / importance threshold (selector required). POST /v1/memory/forget

Recall and Search return each memory's ID, so results chain into Get / Update / Forget. Forget
requires a selector (IDs, session, tags, or importance threshold), so it can't wipe a namespace by
accident.

Credentials are user-supplied and point at the user's own self-hosted server: a base URL
(default port 3000) and an optional dk- API key. Saving credentials probes
GET /health/live. No third-party accounts; all memory data stays on the server the user runs.

The full plugin source is included under dakera/dakera/ (manifest, provider, tools, README,
PRIVACY.md) so the definition is reviewable in-diff, alongside the packaged
dakera-0.0.1.difypkg.

This resubmits, as a proper Marketplace plugin, an integration that was previously opened against
the langgenius/dify monorepo (langgenius/dify#38267) and closed with guidance to ship it as a
plugin here.

Risk level

  • Low risk
  • Medium risk
  • High risk

Selected Medium because the plugin sends user-provided memory content to an external service at a
user-configured base URL. It does not execute code/SQL/commands, does no browser automation,
and does not fetch arbitrary per-invocation URLs — the destination is fixed per credential set.
The Forget tool refuses an unscoped mass-delete (it requires at least one selector).

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

The plugin sends the memory content / query the user (or agent) supplies to the self-hosted Dakera
server URL configured in credentials, over HTTP(S). The dk- API key is stored as a Dify secret,
sent only as a Bearer token, and never echoed in tool output. Requests use bounded timeouts
(5s health check, 15s tool calls). The Forget tool requires an explicit selector before it will
delete. No command/code/SQL execution, no filesystem or browser access, no arbitrary URL fetching,
and no handling of health/financial/biometric data.

Local validation

# Packaged with the official CLI (dify-plugin 0.6.3):
$ dify plugin package ./dakera -o dakera.difypkg
INFO plugin packaged successfully output_path=dakera.difypkg

# Package contents verified — source only, no caches/secrets/binaries/pyc:
.difyignore  PRIVACY.md  README.md  _assets/icon.png  main.py  manifest.yaml
provider/dakera.{py,yaml}  requirements.txt  tools/base.py
tools/{store,recall,search,get,update,forget}.{py,yaml}

# Test suite shipped in tests/ (excluded from the package) — pytest, 11/11 PASS:
$ pytest -q
11 passed
#
# Behaviour covered against an in-process mock Dakera server:
PASS provider.validate_credentials succeeds against healthy server
PASS store  POST /v1/memory/store    (content, agent_id, importance clamp, csv tags, bearer auth, id reported)
PASS recall POST /v1/memory/recall   (query, top_k clamped to 20, ranked summary)
PASS search POST /v1/memory/search   (top_k clamped to 50, tag + min_importance filters, total reported)
PASS get    GET  /v1/memory/get/{id} (agent_id query param, content returned)
PASS update PUT  /v1/memory/update/{id} (importance+tags body, agent_id query, no-op guard)
PASS forget POST /v1/memory/forget   (selector required, deleted count; unscoped mass-delete refused)
PASS empty store/recall inputs make no HTTP call
RESULT: ALL PASS

Reviewer notes

Tested locally: packaging with the official dify CLI and a full request/response smoke test of
all six tools + credential validation against a mock server. I have not yet exercised it on a live
Dify Cloud tenant; behavior is standard dify_plugin Tool/ToolProvider usage mirroring the
existing bailian_memory tool plugin, and the runtime contract is covered by the smoke test.
Dakera is self-hosted, so trying the plugin requires running a Dakera server
(https://github.com/dakera-ai/dakera-deploy).

Persistent, decay-weighted memory for Dify agents backed by a self-hosted
Dakera server. Six tools (store, recall, search, get, update, forget) over the
Dakera REST API, packaged as dakera-0.0.1.difypkg. Recall/Search surface memory
IDs so results chain into Get/Update/Forget; Forget requires a selector. Full
plugin source + pytest suite included for review (tests excluded from package).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@ferhimedamine ferhimedamine force-pushed the feat/dakera-memory-plugin branch from 3ef4e65 to f4c2d1d Compare July 3, 2026 06:21
@ferhimedamine

Copy link
Copy Markdown
Contributor Author

Continued hardening of the plugin:

  • Recall & Search now surface each memory's ID in their output, so an agent can chain a hit straight into Get / Update / Forget (previously the IDs weren't shown, so the CRUD tools couldn't be targeted).
  • Added a pytest suite (tests/, 11 tests) covering all six tools + credential validation against an in-process mock Dakera server — including the top_k clamps, the Update no-op guard, and the Forget mass-delete guard. Tests are excluded from the packaged .difypkg via .difyignore.
  • README: added a tool-chaining section (Recall/Search → Get/Update/Forget) and a Development/test note.

Package rebuilt cleanly (byte-identical to source, no tests//cache in the .difypkg). Still open + mergeable.

@crazywoola crazywoola left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the submission. A few required checks need fixes before this can be approved.

Check Status Required action
Single .difypkg ❌ Fail Only one .difypkg file change is allowed. This PR also changes unpacked plugin source files; please submit only the packaged .difypkg.
PR language ✅ Pass None.
Project structure ✅ Pass None.
Manifest author ✅ Pass None.
Icon ✅ Pass None.
Version availability ✅ Pass None.
README language ✅ Pass None.
PRIVACY.md ✅ Pass None.
Dependencies / install / packaging ✅ Pass CI pre-check passed.
dify_plugin version ✅ Pass None.
CI pre-check ❌ Fail No pre-check-plugin result was reported. Once only the package is changed, the pre-check should run.

Next steps

  1. Only one .difypkg file change is allowed. This PR also changes unpacked plugin source files; please submit only the packaged .difypkg.
  2. No pre-check-plugin result was reported. Once only the package is changed, the pre-check should run.

Per marketplace review (crazywoola): a plugin PR may change only the
single packaged .difypkg. Remove the unpacked plugin source from the PR;
the package already bundles it (tests excluded via .difyignore).
@github-actions github-actions Bot added the risk: medium Medium-risk Marketplace submission label Jul 7, 2026
@ferhimedamine

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @crazywoola — addressed both required checks.

The PR now changes a single file, dakera/dakera/dakera-0.0.1.difypkg. I removed the unpacked plugin source (main.py, manifest.yaml, provider/, tools/, tests/, README.md, PRIVACY.md, requirements.txt, _assets/) from the PR — that source is already bundled inside the package, and the test suite is excluded from the build via .difyignore, so the .difypkg is byte-for-byte the built plugin.

With only the package changed, pre-check-plugin should now run. Let me know if anything else is needed.

@crazywoola crazywoola left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

Decision: Approve

Check Results

Check Status Detail
Single .difypkg ✅ Pass Exactly one package file changed.
Project structure ✅ Pass manifest.yaml, README.md, PRIVACY.md, and _assets/ are present.
README language ✅ Pass No Chinese characters found in README.md.
dify_plugin version ✅ Pass Package declares dify_plugin>=0.9.0.
Install / packaging ✅ Pass Local dependency install, startup, and packaging checks passed; GitHub did not show a fresh pre-check result, so I verified the package locally.

LGTM.

@crazywoola crazywoola merged commit efe595d into langgenius:main Jul 8, 2026
1 check passed
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.

2 participants