54 lines
5.2 KiB
Python
54 lines
5.2 KiB
Python
from pathlib import Path
|
|
import json,hashlib,tarfile,shutil
|
|
root=Path('C:/kefu'); release=root/'deploy/knowledge-v3-20260916';release.mkdir(exist_ok=True)
|
|
p=root/'wechat_rpa/KNOWLEDGE.md';s=p.read_text(encoding='utf-8').replace('模型整理使用管理端配置的主答模型,只发送规则预处理后的脱敏问答。', '模型整理可指定管理端已启用的文本模型,创建时固定所选出口;仅发送规则预处理后的脱敏问答。')
|
|
s+='''
|
|
|
|
## 第三版:模型任务恢复与驳回删除
|
|
|
|
- 创建模型任务时选择整理模型、单次等待时间(30–180 秒,默认 90 秒)及调用总上限;知识整理请求输出上限为 4096 token,独立于实时客服调用配置。Dify 应用自己的模型配置与限制仍由上游控制。
|
|
- 失败或暂停任务点击「配置 / 继续」,可换模型、增加等待时间或调用总上限,亦可改成规则整理。已完成草稿保留,新配置只作用于剩余问答。原模型停用时直接报错,不会偷偷切换到其他出口。
|
|
- 扫描游标和待处理问答先持久化,每生成一条草稿立即提交。失败重试不再重做该批已成功的问答;在途请求遇到暂停、取消或进程中断仍可能计费并需要重试。
|
|
- 错误区分超时、授权、限流、网络与输出格式问题,服务端不保存上游原始错误正文、密钥或地址。页面字符量统计成功处理的输入/输出,并非计费 token 数。
|
|
- 已驳回知识支持单条及批量确认删除,需知识编辑与来源正文查看权限。删除知识、来源快照、版本记录和关键词索引,保留原始聊天归档及删除审计;无法从管理界面恢复。租户内保留内容指纹,避免完全相同的已删除草稿被再次生成;不同模型改写仍需人工去重。
|
|
- 新增 `knowledge_discarded` 表,无需回填归档数据。任务待处理问答保存在私有 `state_json`,接口仅返回待处理数量。
|
|
|
|
回归检查:`python -m unittest test_knowledge test_knowledge_tasks test_model_gateway -q`;前端批量操作测试、类型检查及隔离浏览器中的失败换模型续跑与删除流程。
|
|
'''
|
|
p.write_text(s,encoding='utf-8',newline='\n')
|
|
files=[root/'wechat_rpa'/name for name in ['knowledge_api.py','knowledge_store.py','knowledge_worker.py','knowledge_models.py','test_knowledge.py','test_knowledge_tasks.py','KNOWLEDGE.md']]
|
|
files += [root/'admin-web/apps/web-antd/src/api/knowledge.ts']
|
|
files += list((root/'admin-web/apps/web-antd/src/views/knowledge').glob('*'))
|
|
files += [p for p in (root/'admin-web/apps/web-antd/dist').rglob('*') if p.is_file()]
|
|
manifest=[]
|
|
with tarfile.open(release/'payload.tar.gz','w:gz') as tf:
|
|
for p in files:
|
|
relative=p.relative_to(root).as_posix();data=p.read_bytes()
|
|
tf.add(p,arcname=relative)
|
|
manifest.append({'path':relative,'bytes':len(data),'sha256':hashlib.sha256(data).hexdigest()})
|
|
(release/'manifest.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8')
|
|
(release/'Dockerfile.overlay').write_text('''ARG BASE_IMAGE=zyt/wecom-admin:before-knowledge-v3-20260916
|
|
FROM ${BASE_IMAGE}
|
|
COPY --chown=app:app payload/wechat_rpa/*.py /app/wechat_rpa/
|
|
COPY --chown=app:app payload/admin-web/apps/web-antd/dist/ /app/admin-web/apps/web-antd/dist/
|
|
WORKDIR /app/wechat_rpa
|
|
''',encoding='utf-8')
|
|
previous=root/'deploy/knowledge-v2-20260916'
|
|
for filename in ['01-stage.sh','03-deploy.sh','04-verify.sh','rollback.sh']:
|
|
text=(previous/filename).read_text(encoding='utf-8').replace('knowledge-v2-20260916','knowledge-v3-20260916').replace('Second-version','Third-version').replace('second-version','third-version')
|
|
if filename=='01-stage.sh':
|
|
text=text.replace('sha256:061e8735ca4cc37fe09143f06095149ec7475a159fa0f1923d0410b50bfd9b22','sha256:c73e1952e9edcdb1ce5c516b0f54d728ce5b11f57de77e1bee31b1effc51d763').replace('/home/ps/knowledge-20260916-100045/manifest.json','/home/ps/knowledge-v2-20260916/manifest.json').replace('verified first release','verified second release')
|
|
if filename=='04-verify.sh':
|
|
text=text.replace("('/api/v2/knowledge/overview',401,'GET')", "('/api/v2/knowledge/overview',401,'GET'),('/api/v2/knowledge/models',401,'GET')")
|
|
if filename=='rollback.sh':
|
|
text=text.replace('docker compose up -d --no-build --wait --wait-timeout 180 api gateway knowledge-worker', '''# V2 cannot consume V3's pending candidate checkpoint. Keep worker stopped if one exists.
|
|
pending=$(docker run --rm --network=none --mount type=bind,source=/opt/im-admin/deploy/im-admin/data,target=/data,readonly zyt/wecom-admin:before-knowledge-v3-20260916 python -c "import sqlite3,json; db=sqlite3.connect('file:/data/backend.db?mode=ro',uri=True); print(sum(bool(json.loads(r[0]).get('_pending')) for r in db.execute(\\\"SELECT state_json FROM knowledge_job WHERE status NOT IN ('completed','cancelled')\\\")))")
|
|
if [ "$pending" = 0 ]; then
|
|
docker compose up -d --no-build --wait --wait-timeout 180 api gateway knowledge-worker
|
|
else
|
|
docker compose up -d --no-build --wait --wait-timeout 180 api gateway
|
|
echo 'Worker remains stopped to preserve pending V3 checkpoints. Redeploy V3 before processing jobs.'
|
|
fi''')
|
|
(release/filename).write_text(text,encoding='utf-8',newline='\n')
|
|
print(json.dumps({'files':len(manifest),'archive_bytes':(release/'payload.tar.gz').stat().st_size}))
|