Skip to content

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

Open
bugkeep wants to merge 1 commit into
TencentCloud:mainfrom
bugkeep:feat/dify-memory-adapter
Open

feat(dify): add TencentDB Agent Memory adapter#394
bugkeep wants to merge 1 commit 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-specific TencentDB Agent Memory adapter so Dify workflows can call the existing Gateway/Core memory pipeline for recall, capture, search, and session flush without reimplementing memory logic inside Dify.

This PR is intentionally scoped as a platform-specific Dify integration. The review surface is limited to the Dify plugin itself: packaging, provider/tool definitions, the Python runtime transport shim, Dify workflow guidance, and Dify-side tests.

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 -> recall.
  • Added Dify packaging / installation / workflow documentation.
  • Added a Mermaid workflow diagram for the Dify integration flow.
  • 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.
  • Made tdai_recall consume both the legacy context field and the split recall fields from the Gateway/MCP compatibility path (prepend_context + append_system_context).

Scope Notes | 范围说明

This PR is kept Dify-specific on purpose.

  • Dify plugin code, package/config, docs, and Dify-side tests stay in this PR.
  • Shared Gateway /recall response compatibility work is not part of this PR scope and is left to the focused Gateway/MCP compatibility path in feat(adapter): add Codex MCP gateway bridge #372.
  • The shared Gateway client shape should come from the Gateway Client Adapter Kit in feat(adapters): add gateway client adapter kit #316.
  • The Python TdaiGatewayClient in this plugin is only a thin Dify-runtime transport shim. It mirrors the existing Gateway API contract for the Python plugin runtime and is not intended as a new shared cross-platform SDK layer.

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 tests

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

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 (Dify adapter smoke test)

[1/6] Starting or reusing TencentDB Agent Memory Gateway at http://127.0.0.1:8420
Gateway already healthy
[2/6] Starting mock Dify plugin server at http://127.0.0.1:18420
[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_...","total":2}
[5/6] Flushing the session through tdai_session_end
{"ok":true,"flushed":true}
[6/6] Validating the Gateway recall path through tdai_recall
{"context":"","memory_count":0,"ok":true}
Quickstart e2e succeeded: Gateway -> mock Dify server -> capture -> conversation_search (L0 read-back) -> session_end flush -> recall call

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_recall: ok=true

Read-back Positioning | 读回定位

For this Dify-specific PR:

  • tdai_conversation_search is the immediate L0 read path.
  • tdai_recall is the structured recall path exposed through the Dify adapter.
  • The quickstart proves that the Dify adapter can reach the recall path successfully.
  • The Dify adapter is compatible with both the legacy Gateway context response and the split Gateway/MCP recall fields (prepend_context and append_system_context).
  • Whether tdai_recall.context is non-empty depends on the deployed Gateway build plus the existing memory consolidation pipeline, so it is not used here as the sole pass condition of the Dify-only smoke test.

Additional Notes | 其他说明

  • The plugin uses Dify conversation_id as session_key.
  • Search output is truncated by default to keep tool responses prompt-safe.
  • Provider credential validation uses a read-only Gateway probe.
  • Local OCR check on the narrowed Dify-only changes:
ocr scan --path dify-plugin-tdai-memory/tools/tdai_recall.py,dify-plugin-tdai-memory/tests/test_mock_dify_server.py --audience agent --no-plan --no-summary --timeout 10
No comments generated. Looks good to me.

@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 2 times, most recently from a6ac065 to 17caf3e Compare July 5, 2026 05:55
@bugkeep

bugkeep commented Jul 5, 2026

Copy link
Copy Markdown
Author

Update on structured recall evidence (2026-07-05):

The latest quickstart evidence on this PR is no longer the old memory_count=0 result.

Current end-to-end quickstart snippet:

[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

So for the Dify adapter path we now have both:

  • immediate L0 read-back via tdai_conversation_search
  • non-empty structured recall via tdai_recall.context

This is the strongest answer to the “when does tdai_recall become non-empty for LLM injection?” question in this PR.

@YOMXXX

YOMXXX commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Triage note for #235 scope cleanup:

The Dify plugin work is platform-specific and should be reviewed separately from the generic adapter SDK cleanup. However, this PR currently also carries Gateway /recall transport response changes, which overlap with the focused and locally verified MCP/Gateway compatibility work in #372.

Recommended re-scope:

This keeps the Dify integration review focused while still preserving the platform-specific contribution.

@bugkeep

bugkeep commented Jul 10, 2026

Copy link
Copy Markdown
Author

Thanks, I agree with these three scope decisions.

  • I’ll keep this PR focused on the Dify plugin, Dify packaging/config, Dify docs, and Dify-side tests.
  • I agree the shared Gateway /recall compatibility change should be taken out of this Dify PR’s review surface.
  • I also agree #316 should be the reference for the shared Gateway client shape, and the Python client here should only be treated as a Dify-runtime transport shim.

I’ve already aligned my local branch in that direction.

@bugkeep bugkeep force-pushed the feat/dify-memory-adapter branch from 17caf3e to a59da6d Compare July 10, 2026 14:50
Add a Dify plugin adapter that connects Dify workflows to the TencentDB Agent Memory Gateway for recall, capture, health, search, and session flush operations.

Keep the PR scoped to Dify plugin code, packaging, documentation, and Dify-side tests. Shared Gateway recall response compatibility remains outside this Dify-specific review surface.

Closes TencentCloud#235

Signed-off-by: bugkeep <1921817430@qq.com>
@bugkeep bugkeep force-pushed the feat/dify-memory-adapter branch from a59da6d to 31fbf33 Compare July 10, 2026 15:13
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

2 participants