gen-published-skills.py 4.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/env python3
  2. """生成服务层已发布技能(fmode-vision/listen/ffmpeg/qiwei/storage) + inventory.json"""
  3. import os, json
  4. BASE = '/opt/data/projects/fmode-skills/skills'
  5. skills = [
  6. {"dir":"fmode-vision","slug":"fmode-skill-fmode-vision","ver":"0.1.1","title":"视觉识别","summary":"图片/视频结构化视觉分析:宿主多模态优先,回落 Fmode API(豆包/Doubao)。","triggers":"看图、识图、截图分析、UI截图、视觉识别、图片文字、图像分析、doubao、vision","src":"npm fmode-vision","endpoint":"POST https://api.fmode.cn/v1/chat/completions"},
  7. {"dir":"fmode-listen","slug":"fmode-skill-fmode-listen","ver":"0.1.2","title":"录音转写","summary":"录音/视频音轨转文字(讯飞 LFASR × Fmode 网关),多语种/方言/说话人分离,服务端计费。","triggers":"转写、录音、语音转文字、ASR、讯飞、说话人分离、meeting转写","src":"npm fmode-listen","endpoint":"POST https://server.fmode.cn/api/listen/transcribe"},
  8. {"dir":"fmode-ffmpeg","slug":"fmode-skill-fmode-ffmpeg","ver":"0.1.1","title":"音视频处理","summary":"FFmpeg 音视频处理:抽音轨、转码、压缩、裁剪、截图。捆绑静态二进制零系统依赖。","triggers":"ffmpeg、抽音轨、转码、压缩、裁剪视频、截图、音视频处理、media","src":"npm fmode-ffmpeg","endpoint":"CLI 本地执行"},
  9. {"dir":"fmode-qiwei","slug":"fmode-skill-fmode-qiwei","ver":"0.5.2","title":"企微网关 SDK","summary":"企业微信网关:消息收发、通讯录、应用管理封装。","triggers":"企微、企业微信、WeCom、qiwei、公众号、消息推送、通讯录","src":"npm fmode-qiwei","endpoint":"gateway"},
  10. {"dir":"fmode-storage","slug":"fmode-skill-fmode-storage","ver":"1.1.0","title":"对象存储与公开分享","summary":"二进制大文件上云,本地零占用,一键生成公开分享链接(S3/OBS)。","triggers":"上传、存储、对象存储、S3、OBS、分享链接、公开URL、托管文件","src":"skill-storage 1.1.0","endpoint":"https://s3.fmode.cn/<key>"},
  11. ]
  12. inven = []
  13. for s in skills:
  14. d = os.path.join(BASE, s['dir'])
  15. os.makedirs(os.path.join(d,'scripts'),exist_ok=True)
  16. os.makedirs(os.path.join(d,'references'),exist_ok=True)
  17. skill_md = f"""---
  18. slug: {s['slug']}
  19. displayName: {s['dir']}
  20. version: {s['ver']}
  21. name: {s['dir']}
  22. description: {s['summary']} 触发词:{s['triggers']}
  23. tags: [FmodeAgent, FmodeCode, 服务级, {s['dir'].replace('fmode-','')}]
  24. platform: Both
  25. level: 服务级
  26. category: 平台基础设施
  27. icon: 🛠️
  28. license: MPL-2.0
  29. author: Fmode (未来飞马)
  30. ---
  31. # {s['title']}
  32. ## 触发词
  33. {s['triggers']}
  34. ## 快速开始
  35. ```bash
  36. node scripts/index.mjs <action>
  37. ```
  38. 或按 {s['src']} 的官方命令(`npx --yes {s['src'].split(' ')[-1]}@latest workspace`)。
  39. ## 端点
  40. - {s['endpoint']}
  41. ## 来源
  42. - {s['src']}
  43. ## License
  44. MPL-2.0 © 2026 Fmode (未来飞马)
  45. """
  46. open(os.path.join(d,'SKILL.md'),'w',encoding='utf-8').write(skill_md)
  47. open(os.path.join(d,'references','source.md'),'w',encoding='utf-8').write(f"# 来源\n{s['src']}\n端点: {s['endpoint']}\n")
  48. inven.append({"name":s['dir'],"slug":s['slug'],"version":s['ver'],"tier":"service","source":s['src']})
  49. print(f"✅ {s['dir']}")
  50. # 汇总全部技能到 inventory.json
  51. all_skills = sorted(os.listdir(BASE))
  52. inventory = {
  53. "name": "fmode-skills",
  54. "version": "0.1.0",
  55. "generatedAt": __import__('datetime').datetime.now().isoformat(),
  56. "format": "esm",
  57. "skills": [],
  58. }
  59. for name in all_skills:
  60. full = os.path.join(BASE, name)
  61. if not os.path.isdir(full): continue
  62. # 读 SKILL.md frontmatter 的 slug/version/level
  63. slug=version=level=""
  64. try:
  65. md = open(os.path.join(full,'SKILL.md'),encoding='utf-8').read()
  66. for line in md.split('\n')[:20]:
  67. if line.startswith('slug:'): slug = line.split(':',1)[1].strip()
  68. if line.startswith('version:'): version = line.split(':',1)[1].strip()
  69. if line.startswith('level:'): level = line.split(':',1)[1].strip()
  70. except: pass
  71. inventory["skills"].append({"name":name,"slug":slug or f"fmode-skill-{name}","version":version,"level":level})
  72. with open('/opt/data/projects/fmode-skills/skills/inventory.json','w',encoding='utf-8') as f:
  73. json.dump(inventory, f, ensure_ascii=False, indent=2)
  74. print(f"\n📊 inventory.json 生成: {len(inventory['skills'])} 个子技能")
  75. print("🎉 服务层已发布技能补齐")