Skip to content

feat(dify): add TencentDB Agent Memory adapter#394

Open
bugkeep wants to merge 2 commits into
TencentCloud:mainfrom
bugkeep:feat/dify-memory-adapter
Open

feat(dify): add TencentDB Agent Memory adapter#394
bugkeep wants to merge 2 commits into
TencentCloud:mainfrom
bugkeep:feat/dify-memory-adapter

Conversation

@bugkeep

@bugkeep bugkeep commented Jul 4, 2026

Copy link
Copy Markdown

Description | 描述

This PR adds a Dify platform adapter for TencentDB Agent Memory so Dify workflows can reuse the existing Gateway/Core memory pipeline for capture, recall, search, and session flush instead of reimplementing memory logic in Dify.

Besides the adapter itself, this PR also fixes the Gateway /recall transport response so HTTP clients such as Dify receive the merged recall context, including dynamic recalled memory snippets, rather than only the stable system-side context.

What changed

  • Added dify-plugin-tdai-memory, a Dify tool plugin that forwards:
    • tdai_health
    • tdai_recall
    • tdai_capture
    • tdai_memory_search
    • tdai_conversation_search
    • tdai_session_end
      to the TencentDB Agent Memory Gateway.
  • Added a real quickstart e2e script for:
    Gateway -> mock Dify server -> capture -> conversation_search -> session_end -> structured recall.
  • Added Dify packaging / installation / workflow documentation.
  • Added Mermaid workflow documentation and a cross-platform comparison for OpenClaw, Hermes, and Dify.
  • Added a minimal GitHub Actions workflow for Dify plugin tests and manifest/package validation.
  • Fixed Dify provider icon metadata so Dify CLI package validation passes.
  • Fixed Gateway /recall response composition so transport clients receive merged recall context (prependContext + appendSystemContext).
  • Added a focused regression test for the recall response composition.

Related Issue | 关联 Issue

Closes #235

Change Type | 修改类型

  • Bug fix | Bug 修复
  • New feature | 新功能
  • Documentation update | 文档更新
  • Code optimization | 代码优化

Self-test Checklist | 自测清单

  • Verified locally | 本地验证通过
  • No existing features affected | 无影响现有功能

Validation | 验证

Python / TypeScript tests

python -m unittest discover -s dify-plugin-tdai-memory\tests
Ran 54 tests
OK

npm test
Test Files 5 passed (5)
Tests 69 passed (69)

Minimal CI added in repo

.github/workflows/dify-plugin-ci.yml
- Dify Plugin Tests: python -m unittest discover -s dify-plugin-tdai-memory/tests
- Dify Plugin Manifest: python -m unittest discover -s dify-plugin-tdai-memory/tests -p test_plugin_manifest.py

Dify CLI packaging / install

plugin packaged successfully output_path=/tmp/tdai_memory_0.0.1.difypkg
package size: 19227 bytes
upload unique_identifier: tencentdb-agent-memory/tdai_memory:0.0.1@83c5476576a25586fc2223f0cd9cadf7331cfc3b52719b983039528a9ebab872
install task: status=success, message=installed

Real quickstart e2e (Gateway + mock Dify plugin server)

[1/6] Starting or reusing TencentDB Agent Memory Gateway at http://127.0.0.1:8432
Gateway already healthy
[2/6] Starting mock Dify plugin server at http://127.0.0.1:18421
[3/6] Capturing a completed Dify turn through tdai_capture
{"ok":true,"l0_recorded":2,"scheduler_notified":true}
[4/6] Validating immediate L0 read-back through tdai_conversation_search
{"ok":true,"results":"Found 2 matching message(s): ... TDAI_DIFY_E2E_TOKEN_20260705133838 ...","total":2}
[5/6] Flushing the session through tdai_session_end
{"ok":true,"flushed":true}
[6/6] Validating structured recall through tdai_recall
{"ok":true,"context":"<relevant-memories> ... 用户偏好使用Go语言开发后端服务,并通常部署在Kubernetes集群上。 ...","strategy":"hybrid","memory_count":2}
Structured recall ready after attempt 1/15
Quickstart e2e succeeded: Gateway -> mock Dify server -> capture -> conversation_search (L0 read-back) -> session_end flush -> structured recall

Real Dify runtime path verified

Dify API -> plugin_daemon -> tdai_memory Python plugin -> TencentDB Agent Memory Gateway

tdai_health: ok=true, status=ok, vectorStore=true
tdai_capture: ok=true, l0_recorded=2
tdai_conversation_search: ok=true, total=2
tdai_session_end: ok=true, flushed=true
tdai_memory_search: ok=true, total=1
tdai_recall: ok=true, memory_count=1

Actual L1 / L2 / L3 results | 实际 L1 / L2 / L3 结果

L0 immediate read-back

tdai_conversation_search is used as the adapter's immediate L0 read path.

Found 2 matching message(s):
- assistant: Stored. Preferred stack: Go with Kubernetes. Token confirmed: TDAI_DIFY_E2E_TOKEN_20260705133838.
- user: Please remember that the user prefers Go for backend services and deploys them on Kubernetes. Read-back token: TDAI_DIFY_E2E_TOKEN_20260705133838.

L1 actual recalled result

The structured recall path (tdai_recall) returned a non-empty L1 memory block over the real plugin path.

Actual tdai_recall.context excerpt:

<relevant-memories>
以下是当前对话召回的相关记忆,不代表当前任务进程,仅作为参考:

- [persona|The user (name unknown) is configuring AI to remember their tech stack preferences (Go + Kubernetes).] 用户偏好使用Go语言开发后端服务,并通常部署在Kubernetes集群上。 (活动时间: 2026-07-05T04:33:31+00:00)
- [episodic|The user (name unknown) is configuring AI to remember their tech stack preferences (Go + Kubernetes).] The user (name unknown) provided a read-back token TDAI_DIFY_E2E_TOKEN_20260705133838 for instruction verification on 2026-07-05T05:38:41Z. (活动时间: 2026-07-05T05:38:45+00:00)
</relevant-memories>

Strict read-back summary from the quickstart run:

{
  "ok": true,
  "strategy": "hybrid",
  "memory_count": 2
}

L2 actual aggregation result

In the same Dify-backed environment, L2 materialized a scene block and scene index entry from the same session.

Actual generated scene block excerpt:

summary: 用户偏好使用 Go 语言开发后端服务,并部署在 Kubernetes 集群上,是一名云原生后端开发者。

## 用户偏好
- 后端开发首选 Go 语言
- 服务部署偏好 Kubernetes 容器编排平台

Actual generated scene index entry:

Path: scene_blocks/Go后端开发-技术栈.md
Summary: 用户偏好使用 Go 语言开发后端服务,并部署在 Kubernetes 集群上,是一名云原生后端开发者。

Checkpoint/log evidence from the same environment:

scenes_processed = 1
last_extraction_time = 2026-07-05T04:33:48.389Z

L3 actual persona result

Actual tdai_recall.context / persona.md excerpt:

<user-persona>
# User Narrative Profile

> **Archetype**: A cloud-native backend engineer building scalable microservices with Go and Kubernetes.

> **Long-term Preferences**
- Prefers Go for backend service development due to its concurrency model and clean syntax
- Standardizes on Kubernetes for service deployment, scaling, and operations

Actual generated persona also includes scene navigation:

## Scene Navigation (Scene Index)
### Path: scene_blocks/Go后端开发-技术栈.md
Summary: 用户偏好使用 Go 语言开发后端服务,并部署在 Kubernetes 集群上,是一名云原生后端开发者。

Checkpoint evidence from the same environment:

last_persona_at = 2
last_persona_time = 2026-07-05T04:33:59.049Z
memories_since_last_persona = 0

So the real Dify plugin path now demonstrates:

  • L0 immediate read-back via tdai_conversation_search
  • L1 recalled and returned to Dify via <relevant-memories>
  • L2 aggregated into a concrete scene block / scene index
  • L3 generated and returned to Dify via <user-persona>

Open Code Review

ocr review --from origin/main --to HEAD
Timed out in local environment; CLI is installed and runnable, but this run did not produce review comments before timeout.

Additional Notes | 其他说明

  • tdai_conversation_search is documented as the adapter's immediate L0 read path for read-after-write validation.
  • tdai_recall is the structured recall path and is now verified with non-empty context over the real Dify plugin runtime path.
  • For local unsigned package installation in Dify, FORCE_VERIFYING_SIGNATURE=false was used in the local plugin daemon. Production deployments should keep signature verification enabled unless the package is signed and trusted.

@bugkeep

bugkeep commented Jul 4, 2026

Copy link
Copy Markdown
Author

Validation evidence for this Dify adapter PR:

Quickstart e2e

[1/4] Starting or reusing TencentDB Agent Memory Gateway at http://172.23.224.1:8420
Gateway already healthy
[2/4] Starting mock Dify plugin server at http://127.0.0.1:18420
[3/4] Capturing a completed Dify turn through tdai_capture
{"l0_recorded": 2, "ok": true, "scheduler_notified": true}
[4/4] Recalling memory through tdai_recall
{"context": "", "memory_count": 0, "ok": true}
Quickstart e2e succeeded: Gateway -> mock Dify server -> capture -> recall

Dify package/install

Dify: langgenius/dify-api:1.15.0
Dify plugin daemon: langgenius/dify-plugin-daemon:0.6.3-local
Gateway URL from plugin runtime: http://host.docker.internal:8420

dify plugin package ./dify-plugin-tdai-memory
-> plugin packaged successfully
-> package size: 19227 bytes

upload unique_identifier:
tencentdb-agent-memory/tdai_memory:0.0.1@83c5476576a25586fc2223f0cd9cadf7331cfc3b52719b983039528a9ebab872

install task:
status=success
message=installed
plugin_id=tencentdb-agent-memory/tdai_memory

Runtime invocation through Dify

Dify API -> plugin_daemon -> tdai_memory Python plugin -> TencentDB Agent Memory Gateway

tdai_health: ok=true, status=ok, vectorStore=true
tdai_capture: ok=true, l0_recorded=2
tdai_conversation_search: ok=true, total=2, read back TDAI_DIFY_E2E_TOKEN_20260704_SKYBLUE
tdai_recall: ok=true, memory_count=0

@bugkeep

bugkeep commented Jul 5, 2026

Copy link
Copy Markdown
Author

Added the requested minimal CI and reran the validation path.

Immediate read-back is now documented and asserted as:

  • tdai_conversation_search = immediate L0 read path
  • tdai_recall = structured recall path (may still be empty immediately after one capture)

Latest passing CI runs on the head branch in the fork:

Latest real quickstart e2e log:

[1/5] Starting or reusing TencentDB Agent Memory Gateway at http://172.23.224.1:8424
Gateway already healthy
[2/5] Starting mock Dify plugin server at http://127.0.0.1:18420
[3/5] Capturing a completed Dify turn through tdai_capture
{"l0_recorded": 2, "ok": true, "scheduler_notified": true}
[4/5] Validating immediate L0 read-back through tdai_conversation_search
{"ok": true, "results": "Found 2 matching message(s): ... TDAI_DIFY_E2E_TOKEN_20260705091935-960 ...", "total": 2}
[5/5] Recalling memory through tdai_recall
{"context": "", "memory_count": 0, "ok": true}
Quickstart e2e succeeded: Gateway -> mock Dify server -> capture -> conversation_search (L0 read-back) -> recall

@bugkeep

bugkeep commented Jul 5, 2026

Copy link
Copy Markdown
Author

Follow-up validation after the latest Gateway recall fix on the same PR branch.

Real Dify strict read-back

Environment:

  • Local Dify 1.15.0
  • Local plugin daemon 0.6.3-local
  • Dify plugin runtime -> TencentDB Agent Memory Gateway (http://host.docker.internal:8432)
  • Session: strict-recall-20260705-5

Runtime path:

tdai_capture             -> {"l0_recorded": 2, "ok": true, "scheduler_notified": true}
tdai_conversation_search -> found 2 matching captured messages
tdai_session_end         -> {"flushed": true, "ok": true}
tdai_memory_search       -> found 1 persona memory
tdai_recall              -> memory_count=1, context non-empty

tdai_recall summary:

{
  "ok": true,
  "memory_count": 1,
  "strategy": "hybrid",
  "context_length": 2013,
  "has_relevant_memories": true,
  "has_user_persona": true
}

L1 / L2 / L3 evidence from the same session

L1:

  • SQLite l1_records contains:
    用户偏好使用 Go 语言开发后端服务,并通常部署在 Kubernetes 集群上。

L2:

  • scene_blocks/Go后端开发-技术栈.md generated
  • .metadata/scene_index.json generated
  • checkpoint: scenes_processed = 1

L3:

  • persona.md generated
  • checkpoint: last_persona_at = 2
  • checkpoint: last_persona_time = 2026-07-05T04:33:59.049Z

So this is no longer only an L0 read-back proof. The real Dify plugin path now shows:

  • L1 stored and searchable
  • L2 scene materialized
  • L3 persona materialized
  • tdai_recall.context returns non-empty memory/persona context back to Dify / LLM

@bugkeep bugkeep force-pushed the feat/dify-memory-adapter branch from fae06e4 to a6ac065 Compare July 5, 2026 05:18
bugkeep added 2 commits July 5, 2026 13:54
Add a Dify plugin adapter that connects Dify workflows to the TencentDB Agent Memory Gateway for recall, capture, health, search, and session flush operations.

Include a mock Dify quickstart e2e script, adapter architecture notes, Mermaid workflow diagram, and cross-platform comparison documentation.

Closes TencentCloud#235

Signed-off-by: bugkeep <1921817430@qq.com>
Merge dynamic and stable recall context in the gateway HTTP response so transport clients like Dify receive actual L1 memory snippets during read-back validation.

Signed-off-by: bugkeep <1921817430@qq.com>
@bugkeep bugkeep force-pushed the feat/dify-memory-adapter branch from a6ac065 to 17caf3e Compare July 5, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cross-Platform Adapters for the Memory Plugin

1 participant