#!/usr/bin/env python3 # -*- coding: utf-8 -*- """专题十七 · 步骤 1:看清「插件自动升级策略」现状(只读,不改任何东西)。 一次性打印三块,用来判断「这次又要不要重打补丁」: 1) dify.tenant_plugin_auto_upgrade_strategies —— 6 个 category 各自的自动升级策略 (这是「关掉 OpenAI 插件自动更新」唯一真正的落点,控制台 UI 改的就是它) 2) dify_plugin.plugin_installations —— 当前装着哪些插件、什么版本 3) plugin_daemon 卷里 openai 各版本目录,及其 llm.py / chat.py 的补丁命中情况 用法(Windows 开发机,项目根): python scripts_cursor/Dify_专题十七_OpenAI插件升级后schema补丁丢失/专题十七_01_查看插件自动升级策略.py 也可在 207 上直接跑(脚本会自动切本地模式)。 """ from __future__ import annotations import sys import _bootstrap # noqa: F401 import _config as C from dify_api import Dify PG = C.PG_CONTAINER DAEMON = C.PLUGIN_CONTAINER SQL_STRATEGY = ( "select category, strategy_setting, upgrade_mode, " "exclude_plugins::text, include_plugins::text, " "to_char(updated_at, 'YYYY-MM-DD HH24:MI') as updated " "from tenant_plugin_auto_upgrade_strategies order by category;" ) SQL_INSTALLED = ( "select plugin_id, plugin_unique_identifier, source " "from plugin_installations order by plugin_id;" ) # 各补丁的「指纹」——正文里那句独特的标记,用来判断某个版本目录补没补 MARK_LLM = "Fallback for custom / non-OpenAI base models" MARK_CHAT_OLD = "_ensure_system_first" MARK_CHAT_NEW = "_single_leading_system" def psql(d, db: str, sql: str): """在本机与 207 两种模式下都能跑:SQL 全用双引号包,内部只用单引号。""" cmd = 'docker exec %s psql -U postgres -d %s -c "%s"' % (PG, db, sql) return d.sh(cmd) def main() -> int: d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD) print("=" * 78) print("1/3 自动升级策略 dify.tenant_plugin_auto_upgrade_strategies") print("=" * 78) out, err = psql(d, "dify", SQL_STRATEGY) print(out or err) print("说明:strategy_setting = disabled / fix_only / latest;") print(" upgrade_mode = all / partial / exclude;") print(" model 类若为 disabled 且 exclude 里含 langgenius/openai,") print(" 即「OpenAI 插件已被钉住,不会自动升级冲掉补丁」。") print("\n" + "=" * 78) print("2/3 已安装插件 dify_plugin.plugin_installations") print("=" * 78) out, err = psql(d, "dify_plugin", SQL_INSTALLED) print(out or err) print("\n" + "=" * 78) print("3/3 openai 插件卷:版本目录与补丁命中") print("=" * 78) out, err = d.sh( "docker exec %s sh -c " "'ls -d /app/storage/cwd/langgenius/openai-*@* 2>/dev/null | sort'" % DAEMON ) dirs = [x.strip() for x in (out or "").splitlines() if x.strip()] if not dirs: print("找不到 openai 插件目录:%s" % (err or out)) return 1 for t in dirs: ver = t.split("/langgenius/")[-1].split("/")[0] print("\n--- %s" % ver) for label, rel, mark in ( ("llm.py ", "models/llm/llm.py", MARK_LLM), ("chat.py", "models/llm/chat.py", MARK_CHAT_OLD), ("chat.py", "models/llm/chat.py", MARK_CHAT_NEW), ): o, _ = d.sh( "docker exec %s sh -c " "'grep -c \"%s\" %s/%s 2>/dev/null || echo 0'" % (DAEMON, mark, t, rel) ) n = (o or "0").strip().splitlines()[-1] if (o or "").strip() else "0" if label == "chat.py" and mark == MARK_CHAT_NEW: tag = "上游原生「单条 leading system」实现" elif label == "chat.py": tag = "专题四 合并 system 补丁(旧版函数名)" else: tag = "专题一 自定义基座 schema 补丁" print(" %s %-46s 命中 %s 处 ← %s" % (label, mark[:44], n, tag)) print("\n提示:当下真正影响「模型不可用」的是 llm.py 那份;" "chat.py 在 1.0.5 上游已内置,通常无需再 patch。") return 0 if __name__ == "__main__": sys.exit(main())