@henjicc/ai-sdk 0.2.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/CHANGELOG.md +153 -143
  2. package/README.md +486 -461
  3. package/dist/capabilities/embedding/bailian.d.ts +23 -0
  4. package/dist/capabilities/embedding/bailian.js +10 -0
  5. package/dist/capabilities/embedding/bigmodel.d.ts +9 -0
  6. package/dist/capabilities/embedding/bigmodel.js +5 -0
  7. package/dist/capabilities/embedding/index.d.ts +1 -0
  8. package/dist/capabilities/embedding/index.js +1 -0
  9. package/dist/capabilities/embedding/ppio.d.ts +7 -0
  10. package/dist/capabilities/embedding/ppio.js +5 -0
  11. package/dist/capabilities/embedding/siliconflow.d.ts +21 -0
  12. package/dist/capabilities/embedding/siliconflow.js +10 -0
  13. package/dist/capabilities/embedding/volcengine.d.ts +10 -0
  14. package/dist/capabilities/embedding/volcengine.js +6 -0
  15. package/dist/capabilities/rerank/bailian.d.ts +21 -0
  16. package/dist/capabilities/rerank/bailian.js +14 -0
  17. package/dist/capabilities/rerank/bigmodel.d.ts +9 -0
  18. package/dist/capabilities/rerank/bigmodel.js +5 -0
  19. package/dist/capabilities/rerank/index.d.ts +1 -0
  20. package/dist/capabilities/rerank/index.js +1 -0
  21. package/dist/capabilities/rerank/ppio.d.ts +7 -0
  22. package/dist/capabilities/rerank/ppio.js +5 -0
  23. package/dist/capabilities/rerank/siliconflow.d.ts +21 -0
  24. package/dist/capabilities/rerank/siliconflow.js +10 -0
  25. package/dist/capabilities/retrieval/http.d.ts +3 -0
  26. package/dist/capabilities/retrieval/http.js +48 -0
  27. package/dist/capabilities/retrieval/module.d.ts +11 -0
  28. package/dist/capabilities/retrieval/module.js +110 -0
  29. package/dist/capabilities/retrieval/types.d.ts +54 -0
  30. package/dist/capabilities/retrieval/types.js +1 -0
  31. package/dist/capabilities/retrieval/validation.d.ts +10 -0
  32. package/dist/capabilities/retrieval/validation.js +65 -0
  33. package/dist/capabilities/types.d.ts +1 -1
  34. package/dist/catalog/apimart/gpt-image-2.5.model.d.ts +2 -0
  35. package/dist/catalog/apimart/gpt-image-2.5.model.js +51 -0
  36. package/dist/catalog/fal/gpt-image-2.5.model.d.ts +2 -0
  37. package/dist/catalog/fal/gpt-image-2.5.model.js +53 -0
  38. package/dist/catalog/fal/ic-light-v2.model.js +9 -13
  39. package/dist/catalog/grsai/gpt-image-2.5.model.d.ts +2 -0
  40. package/dist/catalog/grsai/gpt-image-2.5.model.js +54 -0
  41. package/dist/catalog/grsai/gptImage25Sizes.d.ts +1 -0
  42. package/dist/catalog/grsai/gptImage25Sizes.js +76 -0
  43. package/dist/catalog/index.js +112 -104
  44. package/dist/catalog/kie/gpt-image-2.5.model.d.ts +2 -0
  45. package/dist/catalog/kie/gpt-image-2.5.model.js +38 -0
  46. package/dist/catalog/shared/gptImage25.d.ts +16 -0
  47. package/dist/catalog/shared/gptImage25.js +48 -0
  48. package/dist/catalog/shared/gptImage25Pricing.d.ts +12 -0
  49. package/dist/catalog/shared/gptImage25Pricing.js +508 -0
  50. package/dist/llm/defaults.d.ts +1 -1
  51. package/dist/llm/defaults.js +1 -1
  52. package/dist/llm/modelCatalogEntries.js +16 -0
  53. package/dist/llm/providerPresets.js +2 -2
  54. package/dist/packs/models/apimart/gpt-image-2.5.d.ts +6 -0
  55. package/dist/packs/models/apimart/gpt-image-2.5.js +7 -0
  56. package/dist/packs/models/fal/gpt-image-2.5.d.ts +6 -0
  57. package/dist/packs/models/fal/gpt-image-2.5.js +7 -0
  58. package/dist/packs/models/grsai/gpt-image-2.5.d.ts +6 -0
  59. package/dist/packs/models/grsai/gpt-image-2.5.js +7 -0
  60. package/dist/packs/models/kie/gpt-image-2.5.d.ts +6 -0
  61. package/dist/packs/models/kie/gpt-image-2.5.js +7 -0
  62. package/dist/packs/provider-packs/apimart.d.ts +1 -1
  63. package/dist/packs/provider-packs/apimart.js +21 -20
  64. package/dist/packs/provider-packs/fal.d.ts +1 -1
  65. package/dist/packs/provider-packs/fal.js +37 -36
  66. package/dist/packs/provider-packs/grsai.d.ts +1 -1
  67. package/dist/packs/provider-packs/grsai.js +6 -5
  68. package/dist/packs/provider-packs/kie.d.ts +1 -1
  69. package/dist/packs/provider-packs/kie.js +28 -27
  70. package/dist/packs/tool-models/fal/{qwen-image-edit-2509-multiple-angles.d.ts → qwen-image-edit-2511-multiple-angles.d.ts} +1 -1
  71. package/dist/packs/tool-models/fal/{qwen-image-edit-2509-multiple-angles.js → qwen-image-edit-2511-multiple-angles.js} +1 -1
  72. package/dist/packs/tool-packs/fal-multi-angle-tools.js +1 -1
  73. package/dist/tool-packs/fal-multi-angle/models/qwen-image-edit-2511-multiple-angles.model.d.ts +2 -0
  74. package/dist/tool-packs/fal-multi-angle/models/{qwen-image-edit-2509-multiple-angles.model.js → qwen-image-edit-2511-multiple-angles.model.js} +20 -17
  75. package/docs/README.md +26 -26
  76. package/docs/consumers.md +54 -48
  77. package/docs/llm-adaptation/README.md +139 -139
  78. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/DeepSeek.md +103 -91
  79. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/Kimi.md +75 -75
  80. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/MiniMax.md +84 -84
  81. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//345/260/217/347/261/263MiMo.md +85 -85
  82. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//346/231/272/350/260/261GLM.md +232 -232
  83. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//347/201/253/345/261/261/345/274/225/346/223/216.md +87 -87
  84. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//347/231/276/347/202/274Qwen.md +84 -84
  85. package/docs/llm-adaptation//346/226/207/346/241/243/351/207/207/351/233/206/346/211/213/345/206/214.md +88 -88
  86. package/docs/model-adaptation/Bria-Eraser/Bria-Eraser_Fal.md +32 -32
  87. package/docs/model-adaptation/Bria-/345/210/233/346/204/217/346/224/276/345/244/247/Bria-/345/210/233/346/204/217/346/224/276/345/244/247_Fal.md +31 -31
  88. package/docs/model-adaptation/ControlLight/ControlLight_Fal.md +85 -85
  89. package/docs/model-adaptation/FLUX-2-/345/244/232/350/247/222/345/272/246/FLUX-2-/345/244/232/350/247/222/345/272/246_Fal.md +107 -107
  90. package/docs/model-adaptation/Finegrain-Eraser/Finegrain-Eraser_Fal.md +31 -31
  91. package/docs/model-adaptation/Flux-Pro-Erase/Flux-Pro-Erase_Fal.md +34 -34
  92. package/docs/model-adaptation/Fun-ASR/Fun-ASR_/347/231/276/347/202/274.md +43 -43
  93. package/docs/model-adaptation/Fun-ASR-Flash-2026-06-15/Fun-ASR-Flash-2026-06-15_/347/231/276/347/202/274.md +41 -41
  94. package/docs/model-adaptation/Fun-ASR-Realtime/Fun-ASR-Realtime_/347/231/276/347/202/274.md +37 -37
  95. package/docs/model-adaptation/Fun-ASR-Realtime-2026-02-28/Fun-ASR-Realtime-2026-02-28_/347/231/276/347/202/274.md +39 -39
  96. package/docs/model-adaptation/GLM-5.3-Flash/GLM-5.3-Flash_/346/231/272/350/260/261.md +207 -207
  97. package/docs/model-adaptation/GPT-Image-2/GPT-Image-2_APIMart.md +173 -173
  98. package/docs/model-adaptation/GPT-Image-2/GPT-Image-2_Fal.md +94 -94
  99. package/docs/model-adaptation/GPT-Image-2/GPT-Image-2_Grsai.md +137 -137
  100. package/docs/model-adaptation/GPT-Image-2/GPT-Image-2_KIE.md +93 -93
  101. package/docs/model-adaptation/GPT-Image-2.5/GPT-Image-2.5_APIMart.md +66 -0
  102. package/docs/model-adaptation/GPT-Image-2.5/GPT-Image-2.5_Fal.md +55 -0
  103. package/docs/model-adaptation/GPT-Image-2.5/GPT-Image-2.5_Grsai.md +53 -0
  104. package/docs/model-adaptation/GPT-Image-2.5/GPT-Image-2.5_KIE.md +55 -0
  105. package/docs/model-adaptation/GPT-OSS-20B/GPT-OSS-20B_Groq.md +62 -62
  106. package/docs/model-adaptation/Gemini-Omni-Flash/Gemini-Omni-Flash_APIMart.md +124 -124
  107. package/docs/model-adaptation/Gemini-Omni-Flash/Gemini-Omni-Flash_Fal.md +84 -84
  108. package/docs/model-adaptation/Gemini-Omni-Flash/Gemini-Omni-Flash_KIE.md +129 -129
  109. package/docs/model-adaptation/Grok-Imagine/Grok-Imagine_KIE.md +36 -36
  110. package/docs/model-adaptation/Grok-Imagine-2.0/Grok-Imagine-2.0_APIMart.md +250 -250
  111. package/docs/model-adaptation/Grok-Imagine-2.0/Grok-Imagine-2.0_Fal.md +84 -84
  112. package/docs/model-adaptation/Grok-Imagine-2.0/Grok-Imagine-2.0_KIE.md +105 -105
  113. package/docs/model-adaptation/Hailuo-02/Hailuo-02_Fal.md +93 -93
  114. package/docs/model-adaptation/Hailuo-02/Hailuo-02_KIE.md +56 -56
  115. package/docs/model-adaptation/Hailuo-2.3/Hailuo-2.3_Fal.md +88 -88
  116. package/docs/model-adaptation/Hailuo-2.3/Hailuo-2.3_KIE.md +51 -51
  117. package/docs/model-adaptation/Hailuo-2.3/Hailuo-2.3_/346/264/276/346/254/247/344/272/221.md +70 -70
  118. package/docs/model-adaptation/IC-Light-v2/IC-Light-v2_Fal.md +97 -94
  119. package/docs/model-adaptation/Ideogram-/345/233/276/347/211/207/346/224/276/345/244/247/Ideogram-/345/233/276/347/211/207/346/224/276/345/244/247_Fal.md +41 -41
  120. package/docs/model-adaptation/Image-Apps-v2-/345/225/206/345/223/201/346/221/204/345/275/261/Image-Apps-v2-/345/225/206/345/223/201/346/221/204/345/275/261_Fal.md +72 -72
  121. package/docs/model-adaptation/Image-Apps-v2-/346/211/251/345/233/276/Image-Apps-v2-/346/211/251/345/233/276_Fal.md +93 -93
  122. package/docs/model-adaptation/Image-Apps-v2-/347/205/247/347/211/207/344/277/256/345/244/215/Image-Apps-v2-/347/205/247/347/211/207/344/277/256/345/244/215_Fal.md +86 -86
  123. package/docs/model-adaptation/Image-Apps-v2-/351/207/215/346/211/223/345/205/211/Image-Apps-v2-/351/207/215/346/211/223/345/205/211_Fal.md +84 -84
  124. package/docs/model-adaptation/Kling-3.0/Kling-3.0_APIMart.md +112 -112
  125. package/docs/model-adaptation/Kling-3.0/Kling-3.0_Fal.md +89 -89
  126. package/docs/model-adaptation/Kling-3.0/Kling-3.0_KIE.md +106 -106
  127. package/docs/model-adaptation/Kling-3.0/Kling-3.0_/346/264/276/346/254/247/344/272/221.md +119 -119
  128. package/docs/model-adaptation/Kling-3.0-Omni/Kling-3.0-Omni_APIMart.md +125 -125
  129. package/docs/model-adaptation/Kling-3.0-Omni/Kling-3.0-Omni_Fal.md +107 -107
  130. package/docs/model-adaptation/Kling-3.0-Omni/Kling-3.0-Omni_KIE.md +143 -143
  131. package/docs/model-adaptation/Kling-3.0-Turbo/Kling-3.0-Turbo_APIMart.md +85 -85
  132. package/docs/model-adaptation/Kling-3.0-Turbo/Kling-3.0-Turbo_Fal.md +83 -83
  133. package/docs/model-adaptation/Kling-3.0-Turbo/Kling-3.0-Turbo_KIE.md +84 -84
  134. package/docs/model-adaptation/Midjourney/Midjourney_APIMart.md +396 -396
  135. package/docs/model-adaptation/MiniMax-H3/MiniMax-H3_APIMart.md +234 -234
  136. package/docs/model-adaptation/MiniMax-H3/MiniMax-H3_Fal.md +108 -108
  137. package/docs/model-adaptation/MiniMax-H3/MiniMax-H3_KIE.md +111 -111
  138. package/docs/model-adaptation/MiniMax-Speech/MiniMax-Speech_/346/264/276/346/254/247/344/272/221.md +170 -170
  139. package/docs/model-adaptation/Nano-Banana-2/Nano-Banana-2_APIMart.md +89 -89
  140. package/docs/model-adaptation/Nano-Banana-2/Nano-Banana-2_Fal.md +99 -99
  141. package/docs/model-adaptation/Nano-Banana-2/Nano-Banana-2_Grsai.md +82 -82
  142. package/docs/model-adaptation/Nano-Banana-2/Nano-Banana-2_KIE.md +70 -70
  143. package/docs/model-adaptation/Nano-Banana-2-Lite/Nano-Banana-2-Lite_APIMart.md +79 -79
  144. package/docs/model-adaptation/Nano-Banana-2-Lite/Nano-Banana-2-Lite_Grsai.md +65 -65
  145. package/docs/model-adaptation/Nano-Banana-2-Lite/Nano-Banana-2-Lite_KIE.md +64 -64
  146. package/docs/model-adaptation/Nano-Banana-Pro/Nano-Banana-Pro_APIMart.md +83 -83
  147. package/docs/model-adaptation/Nano-Banana-Pro/Nano-Banana-Pro_Fal.md +89 -89
  148. package/docs/model-adaptation/Nano-Banana-Pro/Nano-Banana-Pro_Grsai.md +82 -82
  149. package/docs/model-adaptation/Nano-Banana-Pro/Nano-Banana-Pro_KIE.md +64 -64
  150. package/docs/model-adaptation/Pixelcut-/350/203/214/346/231/257/347/247/273/351/231/244/Pixelcut-/350/203/214/346/231/257/347/247/273/351/231/244_Fal.md +79 -79
  151. package/docs/model-adaptation/Qwen-Image-3.0/Qwen-Image-3.0_APIMart.md +117 -117
  152. package/docs/model-adaptation/Qwen-Image-3.0/Qwen-Image-3.0_Fal.md +84 -84
  153. package/docs/model-adaptation/Qwen-Image-3.0/Qwen-Image-3.0_KIE.md +103 -103
  154. package/docs/model-adaptation/Qwen-Image-3.0/Qwen-Image-3.0_/347/231/276/347/202/274.md +138 -138
  155. package/docs/model-adaptation/Qwen-Image-Edit-2511-/345/244/232/350/247/222/345/272/246/Qwen-Image-Edit-2511-/345/244/232/350/247/222/345/272/246_Fal.md +57 -0
  156. package/docs/model-adaptation/Qwen-MT-Flash/Qwen-MT-Flash_/347/231/276/347/202/274.md +47 -47
  157. package/docs/model-adaptation/Qwen-MT-Lite/Qwen-MT-Lite_/347/231/276/347/202/274.md +39 -39
  158. package/docs/model-adaptation/Qwen-MT-Plus/Qwen-MT-Plus_/347/231/276/347/202/274.md +39 -39
  159. package/docs/model-adaptation/Qwen3-ASR-Flash/Qwen3-ASR-Flash_/347/231/276/347/202/274.md +40 -40
  160. package/docs/model-adaptation/Qwen3-ASR-Flash-2026-02-10/Qwen3-ASR-Flash-2026-02-10_/347/231/276/347/202/274.md +33 -33
  161. package/docs/model-adaptation/Qwen3-ASR-Flash-Filetrans/Qwen3-ASR-Flash-Filetrans_/347/231/276/347/202/274.md +41 -41
  162. package/docs/model-adaptation/Qwen3-ASR-Flash-Realtime/Qwen3-ASR-Flash-Realtime_/347/231/276/347/202/274.md +35 -35
  163. package/docs/model-adaptation/Qwen3-ASR-Flash-Realtime-2026-02-10/Qwen3-ASR-Flash-Realtime-2026-02-10_/347/231/276/347/202/274.md +37 -37
  164. package/docs/model-adaptation/README.md +313 -295
  165. package/docs/model-adaptation/SeedASR-2.0-File/SeedASR-2.0-File_/347/201/253/345/261/261/345/274/225/346/223/216.md +115 -115
  166. package/docs/model-adaptation/SeedASR-2.0-Realtime/SeedASR-2.0-Realtime_/347/201/253/345/261/261/345/274/225/346/223/216.md +143 -143
  167. package/docs/model-adaptation/SeedVR2-/345/233/276/347/211/207/346/224/276/345/244/247/SeedVR2-/345/233/276/347/211/207/346/224/276/345/244/247_Fal.md +45 -45
  168. package/docs/model-adaptation/Seedance-2.0/Seedance-2.0_APIMart.md +121 -121
  169. package/docs/model-adaptation/Seedance-2.0/Seedance-2.0_Fal.md +97 -97
  170. package/docs/model-adaptation/Seedance-2.0/Seedance-2.0_KIE.md +86 -86
  171. package/docs/model-adaptation/Seedance-2.0-Fast/Seedance-2.0-Fast_APIMart.md +89 -89
  172. package/docs/model-adaptation/Seedance-2.0-Fast/Seedance-2.0-Fast_Fal.md +95 -95
  173. package/docs/model-adaptation/Seedance-2.0-Fast/Seedance-2.0-Fast_KIE.md +78 -78
  174. package/docs/model-adaptation/Seedance-2.0-Mini/Seedance-2.0-Mini_APIMart.md +89 -89
  175. package/docs/model-adaptation/Seedance-2.0-Mini/Seedance-2.0-Mini_Fal.md +96 -96
  176. package/docs/model-adaptation/Seedance-2.0-Mini/Seedance-2.0-Mini_KIE.md +78 -78
  177. package/docs/model-adaptation/Seedance-2.5/Seedance-2.5_APIMart.md +212 -212
  178. package/docs/model-adaptation/Seedance-2.5/Seedance-2.5_Fal.md +94 -94
  179. package/docs/model-adaptation/Seedance-2.5/Seedance-2.5_KIE.md +89 -89
  180. package/docs/model-adaptation/Seedream-5.0-Lite/Seedream-5.0-Lite_APIMart.md +106 -106
  181. package/docs/model-adaptation/Seedream-5.0-Lite/Seedream-5.0-Lite_Fal.md +91 -91
  182. package/docs/model-adaptation/Seedream-5.0-Lite/Seedream-5.0-Lite_KIE.md +89 -89
  183. package/docs/model-adaptation/Seedream-5.0-Lite/Seedream-5.0-Lite_/347/201/253/345/261/261/345/274/225/346/223/216.md +108 -108
  184. package/docs/model-adaptation/Seedream-5.0-Pro/Seedream-5.0-Pro_APIMart.md +194 -194
  185. package/docs/model-adaptation/Seedream-5.0-Pro/Seedream-5.0-Pro_Fal.md +100 -100
  186. package/docs/model-adaptation/Seedream-5.0-Pro/Seedream-5.0-Pro_KIE.md +141 -141
  187. package/docs/model-adaptation/Seedream-5.0-Pro/Seedream-5.0-Pro_/347/201/253/345/261/261/345/274/225/346/223/216.md +137 -137
  188. package/docs/model-adaptation/SenseVoiceSmall/SenseVoiceSmall_/347/241/205/345/237/272/346/265/201/345/212/250.md +69 -69
  189. package/docs/model-adaptation/TeleSpeechASR/TeleSpeechASR_/347/241/205/345/237/272/346/265/201/345/212/250.md +72 -72
  190. package/docs/model-adaptation/Topaz-/345/233/276/347/211/207/346/224/276/345/244/247/Topaz-/345/233/276/347/211/207/346/224/276/345/244/247_Fal.md +87 -87
  191. package/docs/model-adaptation/Topaz-/351/200/217/346/230/216/345/233/276/346/224/276/345/244/247/Topaz-/351/200/217/346/230/216/345/233/276/346/224/276/345/244/247_Fal.md +34 -34
  192. package/docs/model-adaptation/Wan-2.5-Preview/Wan-2.5-Preview_/346/264/276/346/254/247/344/272/221.md +82 -82
  193. package/docs/model-adaptation/Wan-2.6/Wan-2.6_/346/264/276/346/254/247/344/272/221.md +84 -84
  194. package/docs/model-adaptation/Wan-2.7/Wan-2.7_/346/264/276/346/254/247/344/272/221.md +122 -122
  195. package/docs/model-adaptation/Whisper-Large-v3/Whisper-Large-v3_Groq.md +76 -76
  196. package/docs/model-adaptation/Whisper-Large-v3-Turbo/Whisper-Large-v3-Turbo_Groq.md +75 -75
  197. package/docs/model-adaptation/Z-Image-Turbo/Z-Image-Turbo_APIMart.md +88 -88
  198. package/docs/model-adaptation/Z-Image-Turbo/Z-Image-Turbo_Fal.md +95 -95
  199. package/docs/model-adaptation/Z-Image-Turbo/Z-Image-Turbo_KIE.md +71 -71
  200. package/docs/model-adaptation/Z-Image-Turbo/Z-Image-Turbo_/347/231/276/347/202/274.md +122 -122
  201. package/docs/model-adaptation/Z-Image-Turbo/Z-Image-Turbo_/351/255/224/346/220/255.md +97 -97
  202. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206/APIMart.md +238 -238
  203. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206/Fal.md +172 -172
  204. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206/Groq.md +121 -121
  205. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206/Grsai.md +217 -217
  206. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206/KIE.md +131 -131
  207. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//345/200/231/351/200/211/344/276/233/345/272/224/345/225/206/350/260/203/347/240/224-/345/233/276/347/211/207/345/267/245/345/205/267.md +151 -151
  208. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//345/277/253/351/200/237/351/200/202/351/205/215/344/276/233/345/272/224/345/225/206.md +65 -65
  209. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//346/264/276/346/254/247/344/272/221.md +147 -138
  210. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/201/253/345/261/261/345/274/225/346/223/216.md +181 -171
  211. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/231/276/347/202/274.md +237 -227
  212. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/241/205/345/237/272/346/265/201/345/212/250.md +110 -88
  213. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//351/255/224/346/220/255.md +207 -207
  214. package/docs/model-adaptation//346/226/207/346/241/243/351/207/207/351/233/206/346/211/213/345/206/214.md +338 -311
  215. package/docs/model-adaptation//351/200/217/350/247/206/345/217/230/346/215/242//351/200/217/350/247/206/345/217/230/346/215/242_Fal.md +59 -59
  216. package/docs//346/216/245/345/205/245/346/214/207/345/215/227/Electron.md +77 -77
  217. package/docs//346/216/245/345/205/245/346/214/207/345/215/227/Tauri.md +81 -81
  218. package/docs//346/216/245/345/205/245/346/214/207/345/215/227/UXP.md +169 -169
  219. package/docs//346/216/245/345/205/245/346/214/207/345/215/227//344/276/233/345/272/224/345/225/206/345/237/237/345/220/215.md +83 -83
  220. package/docs//346/216/245/345/205/245/346/214/207/345/215/227//351/224/231/350/257/257/345/244/204/347/220/206.md +72 -72
  221. package/examples/form-renderer/README.md +17 -17
  222. package/examples/form-renderer/cli.ts +32 -32
  223. package/examples/form-renderer/index.ts +144 -144
  224. package/examples/form-renderer/package.json +16 -16
  225. package/examples/form-renderer/tsconfig.json +14 -14
  226. package/examples/llm-chat/README.md +32 -32
  227. package/examples/llm-chat/index.ts +100 -100
  228. package/examples/llm-chat/package.json +19 -19
  229. package/examples/llm-chat/tsconfig.json +14 -14
  230. package/examples/minimal-node/README.md +31 -31
  231. package/examples/minimal-node/index.ts +138 -138
  232. package/examples/minimal-node/package.json +17 -17
  233. package/examples/minimal-node/tsconfig.json +14 -14
  234. package/package.json +252 -197
  235. package/dist/tool-packs/fal-multi-angle/models/qwen-image-edit-2509-multiple-angles.model.d.ts +0 -2
  236. package/docs/model-adaptation/Qwen-Image-Edit-2509-/345/244/232/350/247/222/345/272/246/Qwen-Image-Edit-2509-/345/244/232/350/247/222/345/272/246_Fal.md +0 -116
@@ -1,311 +1,338 @@
1
- # 文档采集手册
2
-
3
- > 这份手册只记**做过一遍才知道**的东西。目标:下次做模型调研时,不再重新踩一遍坑。
4
- > 最后更新:2026-08-28(补充 SDK 官方资料先行、事件契约与首发验证规范)
5
-
6
- ---
7
-
8
- ## 一、怎么发现文档:先拿全量索引,别靠单页链接往下点
9
-
10
- **最大的坑:一个模型往往对应多份文档、多个端点,只看用户给的那一个链接必然漏。**
11
- 上一版适配 Midjourney 只做了 2 个端点,实际有 18 个;Grok Imagine 2.0 漏掉了整块图层选区编辑。
12
-
13
- ### 三个平台都有 `llms.txt` 全量索引,第一步就抓它
14
-
15
- ```bash
16
- curl -sL https://docs.apimart.ai/llms.txt -o apimart-index.txt # 171 行,含全部页面
17
- curl -sL https://docs.kie.ai/llms.txt -o kie-index.txt # 517 行
18
- curl -sL https://fal.ai/llms.txt -o fal-index.txt # 只是代表性列表,不全,见下
19
- ```
20
-
21
- 然后**按前缀过滤出目标模型的所有页面**,而不是凭印象猜:
22
-
23
- ```bash
24
- grep -oE "https://docs\.apimart\.ai/en/api-reference/(images|videos)[^)]*\.md" apimart-index.txt | sort -u
25
- grep -oE "https://docs\.kie\.ai/cn/market/[^)]*\.md" kie-index.txt | sort -u
26
- ```
27
-
28
- ### 发现「同一个模型有多份文档」的信号
29
-
30
- | 信号 | 例子 |
31
- |---|---|
32
- | 同目录下多个页面 | `images/midjourney/{generation,imagine,blend,describe,upscale,...}` 18 个 |
33
- | `official` / `ext` 后缀 | `gpt-image-2/{generation,official}`、`grok-imagine-2.0-ext/{generation,layer-region-edit,official}` |
34
- | `-lite` / `-fast` / `-mini` 变体 | `gemini-3.1-flash/{generation,generation-lite}` |
35
- | 平级的辅助能力 | `minimax-h3/{generation,context-ir,regeneration}`、`seedance-2-0/private-avatar` |
36
- | KIE 把能力拆成独立 model | `kling-3.0-omni/{text-to-video,image-to-video,reference-to-video,transformation}` |
37
-
38
- **判断标准**:只要索引里同一个模型名下有第二个页面,就必须打开看,哪怕名字看起来像「辅助说明」。
39
-
40
- ### Fal 的索引不全,要靠探测
41
-
42
- `fal.ai/llms.txt` 只列代表性端点。Fal 的端点是**可组合路径**(`<厂商>/<模型>/<档位>/<输入形态>`),用 HTTP 状态码探测存在性最快:
43
-
44
- ```bash
45
- for p in bytedance/seedance-2.0/text-to-video bytedance/seedance-2.0/image-to-video \
46
- bytedance/seedance-2.0/reference-to-video; do
47
- code=$(curl -sL -o /dev/null -w "%{http_code}" "https://fal.ai/models/$p/llms.txt")
48
- echo "$code $p"
49
- done
50
- ```
51
-
52
- 常见组合维度:`{text-to-video, image-to-video, reference-to-video}`、`{pro, standard}`、`{turbo}`、`{edit}`。
53
- 探测出来的 404 也是信息——比如 `google/gemini-omni-flash/text-to-video` 不存在,说明 Fal 上做不了纯文生视频。
54
-
55
- ---
56
-
57
- ## 二、怎么找文档:优先拿原始 Markdown,浏览器是最后手段
58
-
59
- ### 1. 文档站:URL 后面加 `.md` 就是原文
60
-
61
- `docs.apimart.ai` 和 `docs.kie.ai` 都支持,且 `/cn/` 前缀是中文版:
62
-
63
- ```bash
64
- curl -sL "https://docs.apimart.ai/cn/api-reference/images/midjourney/imagine.md"
65
- curl -sL "https://docs.kie.ai/cn/market/kling/kling-3-0.md"
66
- ```
67
-
68
- **比浏览器渲染好在**:拿到的是完整原文(含被折叠的参数、被 Tab 隐藏的示例),不会因为 UI 折叠而丢内容。
69
-
70
- ### 2. Fal:每个模型的 `llms.txt` 是权威实时 schema
71
-
72
- ```bash
73
- curl -sL "https://fal.ai/models/<endpoint-id>/llms.txt"
74
- ```
75
-
76
- 它由平台元数据实时生成,**不会与线上端点漂移**,且**同时包含 schema 和价格**。
77
-
78
- 枚举值被折叠成 `ImageSize | Enum` 时,去拿 OpenAPI 才能看到具体取值:
79
-
80
- ```bash
81
- curl -sL "https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=bytedance/seedream/v5/pro/text-to-image"
82
- # → image_size 的真实枚举:square_hd / square / portrait_4_3 / ... / auto_1K / auto_2K
83
- ```
84
-
85
- ### 3. 官方控制台是 SPA,curl 拿不到正文——去找它的内容接口
86
-
87
- 火山方舟的文档页 `curl` 只能拿到 18 个字符。用 ego-browser 打开后列出网络请求,就能找到真正的内容 API:
88
-
89
- ```js
90
- await js(`performance.getEntriesByType('resource').map(e => e.name)
91
- .filter(n => /api|doc|content/i.test(n))`)
92
- ```
93
-
94
- 火山方舟的结果(**可直接 curl,无需登录**):
95
-
96
- ```bash
97
- # 单篇文档全文(Result.MDContent 是完整 Markdown,Result.UpdatedTime 是官方更新时间)
98
- curl -sL "https://docs.volcengine.com/api/doc/getDocDetail?LibraryID=82379&DocumentID=1541523&type=online"
99
- # 全库目录(用来找价格页、模型列表页的 DocumentID)
100
- curl -sL "https://docs.volcengine.com/api/doc/getDocList?LibraryID=82379&DataSchema=all_second_nav&type=online"
101
- ```
102
-
103
- 常用 DocumentID:`1541523` 图片生成 API、`1544106` 模型价格、`1330310` 模型列表。
104
-
105
- **通用做法**:任何 SPA 文档站,都先用这招找内容 API,找到就退回 curl,别在浏览器里跟折叠 UI 搏斗。
106
-
107
- ### 4. 阿里云百炼是 SSR,直接 curl 就有全文
108
-
109
- ```bash
110
- curl -sL "https://help.aliyun.com/document_detail/3047054.html" # 会 302 到 slug 页
111
- curl -sL "https://help.aliyun.com/zh/model-studio/model-pricing" # 价格页,3.4 MB HTML
112
- ```
113
-
114
- 用户给的控制台链接里的 `url=3047054` 就是 `document_detail` 的 ID,可以直接换算。
115
-
116
- ### 5. 价格页只能用浏览器(ego-browser)
117
-
118
- APIMart 和 KIE 的定价都是前端渲染的:
119
-
120
- - **APIMart**:图像/视频/LLM/音频是**标签页**,切了才渲染。用 `js()` 找文本等于「视频」的可见元素点一下,等 4 秒再取 `document.body.innerText`
121
- - **KIE**:441 个模型的**搜索框** + 分页。`fillInput('input[type="text"]', 'seedance')` → 等 3.5 秒 → 取全文
122
- - ⚠️ 注意底部的 `1-25 of 28`:**默认每页 25 条,会漏**。换更精确的搜索词(如 `bytedance/seedance-2,` 带逗号)把结果压到 25 条以内
123
-
124
- 把 ego-browser 的输出落盘要这样写(`cliLog` 走的是进程输出):
125
-
126
- ```bash
127
- ego-browser nodejs > out.txt 2>&1 <<'EOF'
128
- const task = await useOrCreateTaskSpace(<空间id>)
129
- cliLog(await js(`document.body.innerText`))
130
- EOF
131
- ```
132
-
133
- ---
134
-
135
- ## 三、怎么处理文档:两个提取脚本 + 一轮交叉校验
136
-
137
- ### 1. KIE 文档是 OpenAPI YAML,用脚本提 schema
138
-
139
- KIE 每页正文是一个 ```` ```yaml ```` 代码块包着的完整 OpenAPI。手读会漏字段,**必须用脚本递归展开**(含 `enum` / `default` / `minItems` / `maxItems` / 嵌套对象):
140
-
141
- ```python
142
- # kie_extract.py —— 用法:python3 kie_extract.py <文件...>
143
- import sys, re, yaml, json
144
-
145
- def fmt(name, sch, indent=0, req=()):
146
- pad = ' ' * indent
147
- typ = sch.get('type', '')
148
- if 'enum' in sch: typ += ' enum=' + json.dumps(sch['enum'], ensure_ascii=False)
149
- if 'default' in sch: typ += f" default={json.dumps(sch['default'], ensure_ascii=False)}"
150
- for k in ('minimum','maximum','minLength','maxLength','minItems','maxItems'):
151
- if k in sch: typ += f" {k}={sch[k]}"
152
- desc = re.sub(r'\s*\n\s*', ' ', (sch.get('description') or '').strip())
153
- print(f"{pad}- {name} [{typ}] {'必填' if name in req else '可选'}: {desc[:1400]}")
154
- if sch.get('type') == 'object' and 'properties' in sch:
155
- r = tuple(sch.get('required', ()))
156
- for k, v in sch['properties'].items(): fmt(k, v, indent + 1, r)
157
- if sch.get('type') == 'array' and isinstance(sch.get('items'), dict):
158
- it = sch['items']
159
- if it.get('type') == 'object' and 'properties' in it:
160
- r = tuple(it.get('required', ()))
161
- for k, v in it['properties'].items(): fmt(k, v, indent + 1, r)
162
-
163
- for path in sys.argv[1:]:
164
- t = open(path, encoding='utf-8').read()
165
- m = re.search(r'```yaml\n(.*?)\n```', t, re.S)
166
- if not m: print(f'{path}: 无 OpenAPI 块'); continue
167
- d = yaml.safe_load(m.group(1))
168
- print('\n=====', path.split('/')[-1])
169
- for p, ops in d.get('paths', {}).items():
170
- for method, op in ops.items():
171
- print(f"### {method.upper()} {p} | {op.get('summary')} | {op.get('operationId')}")
172
- rb = op.get('requestBody', {}).get('content', {}).get('application/json', {}).get('schema')
173
- if rb:
174
- req = tuple(rb.get('required', ()))
175
- for k, v in (rb.get('properties') or {}).items(): fmt(k, v, 1, req)
176
- ```
177
-
178
- **`input` 是 `oneOf` 的要单独展开**(KIE 用它表达「二选一的输入形态」,如 Kling Omni 的「单张首帧」vs「仅视频输入」)——上面脚本会跳过,需要另外 dump `schema['properties']['input']`。
179
-
180
- 对比多个变体的字段差异,一行就够:
181
-
182
- ```bash
183
- for f in seedance-2 seedance-2-fast seedance-2-mini; do
184
- echo -n "$f: "; python3 kie_extract.py raw/$f.md | grep -oE "^ - [a-z_]+" | tr -d ' -' | tr '\n' ' '; echo
185
- done
186
- # 一眼看出 mini 少了 return_last_frame
187
- ```
188
-
189
- ### 2. APIMart 文档是 MDX,代码示例占 80%,先剥掉
190
-
191
- 每页会把同一个请求写成 15 种语言的示例,正文被淹没:
192
-
193
- ```python
194
- # apimart_strip.py —— 保留 bash/json,其余语言的代码块换成占位符
195
- import sys, re
196
- for path in sys.argv[1:]:
197
- t = open(path, encoding='utf-8').read()
198
- t = re.sub(r'```([^\n]*)\n(.*?)```',
199
- lambda m: m.group(0) if m.group(1).startswith(('bash','json'))
200
- else f'\n[[{m.group(1).strip()} 示例已省略]]\n', t, flags=re.S)
201
- print(re.sub(r'\n{3,}', '\n\n', t))
202
- ```
203
-
204
- 之后配合 `sed -n '/^## Body/,$p'` 直接跳到参数区。
205
-
206
- ### 3. 必做的三项交叉校验
207
-
208
- | 校验 | 为什么 | 这次的实例 |
209
- |---|---|---|
210
- | **API 文档正文价格 vs 定价页价格** | 文档正文更新慢,经常是过期价 | Seedream Pro 文档写 $0.045/$0.09,定价页是 $0.02928/$0.05856 |
211
- | **同一模型跨供应商的取值集合** | 名字一样但取值/默认值经常不同 | Lite 分辨率官方是 2K/3K/4K,旧文档抄成了 1K/2K;`adaptive`(APIMart/KIE) vs `auto`(Fal);`duration` 整数 vs 字符串 |
212
- | **schema 内部自相矛盾** | 供应商文档确实会写错 | KIE Qwen3-Pro 的 `enum` 与 `default` 不一致;KIE z-image 的 `aspect_ratio` 描述提到 `auto` 但枚举里没有 |
213
-
214
- **处理原则**:两处不一致时**两个都写进文档**并说明以哪个为准;文档自相矛盾时标注「接入前实测确认」,不要替供应商猜。
215
-
216
- ---
217
-
218
- ## 四、SDK 官方资料先行与首发验证(唯一详细规范)
219
-
220
- Henji-AI 是 `@henjicc/ai-sdk` 的主开发仓库与首发验证宿主。新模型、新供应商或新协议必须先在这里完成官方调研、SDK 实现和完整验证,再发布版本;消费项目只接入已经验证并发布的精确版本。禁止先在消费项目按猜测实现协议,再把结果回填 SDK。
221
-
222
- ### 1. 先文档,后代码
223
-
224
- 编码前必须把以下信息写入本目录对应的供应商/模型文档,并能逐项追溯到官方来源:
225
-
226
- - 模型展示名、API model ID 与适用区域/版本;
227
- - Base URL、端点、方法、鉴权、请求字段、枚举、限制和默认值;
228
- - 当前价格、计费维度、价格来源与冲突取舍;
229
- - 同步响应,或轮询、SSE、WebSocket 等异步/流式协议的完整事件契约;
230
- - 错误、终态、取消、断线、超时、资源释放与连接复用规则。
231
-
232
- 缺少官方来源,或模型、端点、价格、事件契约中任一项仍无法确定时,必须把未知项和已查入口写清并暂停编码;不得用相近模型、旧版本、SDK 现状或消费项目行为替官方契约作结论。官方资料本身矛盾时同时保留冲突来源,标为“实现前待官方确认/授权实测”,不能替供应商猜。
233
-
234
- ### 2. 流式与异步协议必须有事件契约矩阵
235
-
236
- 只要涉及 WebSocket、SSE、流式 HTTP、上传后轮询或回调,就必须在供应商/模型文档中按官方资料建立事件级矩阵。每一个官方事件/状态单独一行,不得只写一条 happy path 示例:
237
-
238
- | 事件/状态 | 前置状态 | 字段契约(required / optional / nullable) | 空值/缺字段语义 | 下一状态 | 对外输出 | 副作用 | 终态/错误 | 连接复用 |
239
- |---|---|---|---|---|---|---|---|---|
240
- | 官方事件名或状态值 | 允许从哪些状态进入 | 逐字段写清存在性、类型与可空性 | `null`、空串、空数组、字段缺失分别是否合法以及是否忽略 | 保持/迁移到哪个状态 | partial/final/usage/finish 或无输出 | ack、上传、轮询、计时器、资源释放等 | 是否终止;官方错误码/原因 | 继续收消息、等待关闭、主动关闭或可开启下一会话 |
241
-
242
- 矩阵还必须说明状态机不变量:首事件、合法重复/乱序、是否允许先终态后结果、什么才算“有效 final”、空终态如何处理、断线后能否恢复、取消与正常结束各释放哪些资源。若官方没有说明某项,明确写“官方未说明”,不要把实现假设写成官方事实。
243
-
244
- ### 3. 官方示例与 fixture 一一对应
245
-
246
- 官方资料中出现的每一个字面请求、响应或事件示例,都要逐项进入 `packages/ai-sdk/tests/fixtures/`,或由测试逐字内联引用同一份 fixture。fixture 必须记录:
247
-
248
- - 精确来源 URL 与抓取日期;
249
- - 内容是官方原样、仅做脱敏/不可联网替换,还是从字段表构造;
250
- - 任何替换的字段及替换原因;
251
- - 对应事件矩阵的行或场景。
252
-
253
- 原样示例只允许做安全脱敏、ID/URL 不可联网替换和必要的稳定化,不得为了让当前 parser 通过而补字段。官方只有字段表、没有字面示例时,可以据表构造 fixture,但必须标为“依据官方字段表构造”,不能标为官方原样。合成负例必须放在独立场景或独立文件并标为 `synthetic-negative`(或同等清晰标记),不得冒充官方样本。fixture 的通用格式与现有目录约定见 [../../tests/fixtures/README.md](../../tests/fixtures/README.md)。
254
-
255
- ### 4. fixture、parser 与测试必须闭环
256
-
257
- 协议实现的精确测试必须从事件矩阵和 fixture 推导,至少覆盖实际适用的下列场景:
258
-
259
- - 官方 happy path 的逐事件解析与完整状态迁移;
260
- - 合法空值(包括合法空始帧/心跳/无输出事件);
261
- - required 字段缺失或类型错误的明确拒绝;
262
- - 空终态、结束前无有效 final、重复事件、乱序事件;
263
- - 供应商错误事件、网络断开、取消、超时;
264
- - 正常结束、失败、取消、断线后的连接、计时器、迭代器和会话资源释放。
265
-
266
- “测试通过”还不够,门禁必须做一次**断牙验证**:临时破坏被测试的不变量(例如把合法空事件误判为错误、接受缺失必填字段、漏掉终态释放),确认对应测试确实失败,再恢复实现并确认重新通过。断牙改动不能提交;交接中记录破坏点和实际失败的测试。只匹配标题、关键词或 fixture 数量的检查不算协议门禁。
267
-
268
- ### 5. SDK 首发与消费顺序
269
-
270
- 发布和接入严格按以下顺序进行,任一步失败都在当前阶段修复,不跨阶段绕过:
271
-
272
- 1. 在 Henji-AI 跑变更协议/模型的精确契约测试与宿主集成测试;
273
- 2. 跑 SDK 全量测试、可移植性检查、类型/构建、打包与本地安装包验证;
274
- 3. 从将要发布的包或远端预发布/正式包回装,在受限运行环境验证公开入口、按需 bundle 与版本内容;
275
- 4. 发布 SDK;
276
- 5. 消费项目精确锁定已验证版本及 lockfile integrity,不使用 workspace 提升、浮动范围或源码旁路;
277
- 6. 消费项目再运行宿主 transport、凭据、媒体、取消、日志和资源释放的集成测试。
278
-
279
- 真实付费网络只在用户明确授权时执行;没有真网不妨碍协议契约测试,但必须在交接中准确写明边界,不能把 fixture/scripted 测试表述成真实供应商成功。
280
-
281
- ---
282
-
283
- ## 五、零散但会卡住你的坑
284
-
285
- | | 表现 | 解法 |
286
- |---|---|---|
287
- | **KIE 限流** | 连续请求后返回 HTTP **200**,但内容是 HTML 外壳 | `grep -l "DOCTYPE html"` 检出,加 2 秒延迟重试。批量下载后一定要跑一次这个检查 |
288
- | **zsh 不做单词分割** | `for p in $PATHS` 把整个多行变量当成一个词 | `while IFS= read -r p; do ... done < 路径文件` |
289
- | **Bash 工具禁用前台 `sleep`** | 加延迟的循环跑不了 | `perl -e 'select(undef,undef,undef,2.0)'` |
290
- | **ego-browser 里 `require` + 顶层 await 冲突** | `Cannot determine intended module format` | 别在 heredoc 里写文件,用 `> out.txt 2>&1` 重定向 |
291
- | **shell 工作目录会跨调用保留** | 上一条 `cd` 影响下一条 | 一律用绝对路径 |
292
- | **文件名带 `/`** | 批量落盘时路径炸掉 | `tr '/' '~'` 做扁平文件名 |
293
- | **Fal 价格标注 tentative** | 价格会变 | 文档里注明「接入前重新读一次 `llms.txt`」 |
294
-
295
- ---
296
-
297
- ## 六、推荐执行顺序
298
-
299
- 1. **抓三份 `llms.txt` 索引** → 按模型名前缀过滤,列出**完整**页面清单(这一步决定会不会漏能力)
300
- 2. **Fal 端点探测** 补上索引里没有的组合路径
301
- 3. **批量 curl 落盘**(`.md` / `llms.txt`),完成后检查有没有 HTML 外壳
302
- 4. **官方站**:SPA 找内容 API,SSR 直接 curl
303
- 5. **价格页**:ego-browser,注意标签页与分页
304
- 6. **用两个脚本提取** schema 与正文,逐字段成表
305
- 7. **三项交叉校验**,不一致的地方写清来源与取舍
306
- 8. 涉及异步/流式协议时,完成第四节的事件矩阵、官方 fixture 与测试场景清单
307
- 9. 每份文档结尾写「原始链接索引」,标注**是否需要登录**
308
-
309
- ---
310
-
311
- 相关:[README.md](README.md)(模型清单与结构约定)、[docs/rules/model-adaptation.md](../../../../docs/rules/model-adaptation.md)(代码侧适配规范)
1
+ # 文档采集手册
2
+
3
+ > 这份手册只记**做过一遍才知道**的东西。目标:下次做模型调研时,不再重新踩一遍坑。
4
+ > 最后更新:2026-08-31(明确 SDK 仓内开发、公共发布与外部消费边界)
5
+
6
+ ---
7
+
8
+ ## 一、怎么发现文档:先拿全量索引,别靠单页链接往下点
9
+
10
+ **最大的坑:一个模型往往对应多份文档、多个端点,只看用户给的那一个链接必然漏。**
11
+ 上一版适配 Midjourney 只做了 2 个端点,实际有 18 个;Grok Imagine 2.0 漏掉了整块图层选区编辑。
12
+
13
+ ### 三个平台都有 `llms.txt` 全量索引,第一步就抓它
14
+
15
+ ```bash
16
+ curl -sL https://docs.apimart.ai/llms.txt -o apimart-index.txt # 171 行,含全部页面
17
+ curl -sL https://docs.kie.ai/llms.txt -o kie-index.txt # 517 行
18
+ curl -sL https://fal.ai/llms.txt -o fal-index.txt # 只是代表性列表,不全,见下
19
+ ```
20
+
21
+ 然后**按前缀过滤出目标模型的所有页面**,而不是凭印象猜:
22
+
23
+ ```bash
24
+ grep -oE "https://docs\.apimart\.ai/en/api-reference/(images|videos)[^)]*\.md" apimart-index.txt | sort -u
25
+ grep -oE "https://docs\.kie\.ai/cn/market/[^)]*\.md" kie-index.txt | sort -u
26
+ ```
27
+
28
+ ### 发现「同一个模型有多份文档」的信号
29
+
30
+ | 信号 | 例子 |
31
+ |---|---|
32
+ | 同目录下多个页面 | `images/midjourney/{generation,imagine,blend,describe,upscale,...}` 18 个 |
33
+ | `official` / `ext` 后缀 | `gpt-image-2/{generation,official}`、`grok-imagine-2.0-ext/{generation,layer-region-edit,official}` |
34
+ | `-lite` / `-fast` / `-mini` 变体 | `gemini-3.1-flash/{generation,generation-lite}` |
35
+ | 平级的辅助能力 | `minimax-h3/{generation,context-ir,regeneration}`、`seedance-2-0/private-avatar` |
36
+ | KIE 把能力拆成独立 model | `kling-3.0-omni/{text-to-video,image-to-video,reference-to-video,transformation}` |
37
+
38
+ **判断标准**:只要索引里同一个模型名下有第二个页面,就必须打开看,哪怕名字看起来像「辅助说明」。
39
+
40
+ ### Fal 的索引不全,要靠探测
41
+
42
+ `fal.ai/llms.txt` 只列代表性端点。Fal 的端点是**可组合路径**(`<厂商>/<模型>/<档位>/<输入形态>`),用 HTTP 状态码探测存在性最快:
43
+
44
+ ```bash
45
+ for p in bytedance/seedance-2.0/text-to-video bytedance/seedance-2.0/image-to-video \
46
+ bytedance/seedance-2.0/reference-to-video; do
47
+ code=$(curl -sL -o /dev/null -w "%{http_code}" "https://fal.ai/models/$p/llms.txt")
48
+ echo "$code $p"
49
+ done
50
+ ```
51
+
52
+ 常见组合维度:`{text-to-video, image-to-video, reference-to-video}`、`{pro, standard}`、`{turbo}`、`{edit}`。
53
+ 探测出来的 404 也是信息——比如 `google/gemini-omni-flash/text-to-video` 不存在,说明 Fal 上做不了纯文生视频。
54
+
55
+ ---
56
+
57
+ ## 二、怎么找文档:优先拿原始 Markdown,浏览器是最后手段
58
+
59
+ ### 1. 文档站:URL 后面加 `.md` 就是原文
60
+
61
+ `docs.apimart.ai` 和 `docs.kie.ai` 都支持,且 `/cn/` 前缀是中文版:
62
+
63
+ ```bash
64
+ curl -sL "https://docs.apimart.ai/cn/api-reference/images/midjourney/imagine.md"
65
+ curl -sL "https://docs.kie.ai/cn/market/kling/kling-3-0.md"
66
+ ```
67
+
68
+ **比浏览器渲染好在**:拿到的是完整原文(含被折叠的参数、被 Tab 隐藏的示例),不会因为 UI 折叠而丢内容。
69
+
70
+ ### 2. Fal:每个模型的 `llms.txt` 是权威实时 schema
71
+
72
+ ```bash
73
+ curl -sL "https://fal.ai/models/<endpoint-id>/llms.txt"
74
+ ```
75
+
76
+ 它由平台元数据实时生成,**不会与线上端点漂移**,且**同时包含 schema 和价格**。
77
+
78
+ 枚举值被折叠成 `ImageSize | Enum` 时,去拿 OpenAPI 才能看到具体取值:
79
+
80
+ ```bash
81
+ curl -sL "https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=bytedance/seedream/v5/pro/text-to-image"
82
+ # → image_size 的真实枚举:square_hd / square / portrait_4_3 / ... / auto_1K / auto_2K
83
+ ```
84
+
85
+ ### 3. 官方控制台是 SPA,curl 拿不到正文——去找它的内容接口
86
+
87
+ 火山方舟的文档页 `curl` 只能拿到 18 个字符。用 ego-browser 打开后列出网络请求,就能找到真正的内容 API:
88
+
89
+ ```js
90
+ await js(`performance.getEntriesByType('resource').map(e => e.name)
91
+ .filter(n => /api|doc|content/i.test(n))`)
92
+ ```
93
+
94
+ 火山方舟的结果(**可直接 curl,无需登录**):
95
+
96
+ ```bash
97
+ # 单篇文档全文(Result.MDContent 是完整 Markdown,Result.UpdatedTime 是官方更新时间)
98
+ curl -sL "https://docs.volcengine.com/api/doc/getDocDetail?LibraryID=82379&DocumentID=1541523&type=online"
99
+ # 全库目录(用来找价格页、模型列表页的 DocumentID)
100
+ curl -sL "https://docs.volcengine.com/api/doc/getDocList?LibraryID=82379&DataSchema=all_second_nav&type=online"
101
+ ```
102
+
103
+ 常用 DocumentID:`1541523` 图片生成 API、`1544106` 模型价格、`1330310` 模型列表。
104
+
105
+ **通用做法**:任何 SPA 文档站,都先用这招找内容 API,找到就退回 curl,别在浏览器里跟折叠 UI 搏斗。
106
+
107
+ ### 4. 阿里云百炼是 SSR,直接 curl 就有全文
108
+
109
+ ```bash
110
+ curl -sL "https://help.aliyun.com/document_detail/3047054.html" # 会 302 到 slug 页
111
+ curl -sL "https://help.aliyun.com/zh/model-studio/model-pricing" # 价格页,3.4 MB HTML
112
+ ```
113
+
114
+ 用户给的控制台链接里的 `url=3047054` 就是 `document_detail` 的 ID,可以直接换算。
115
+
116
+ ### 5. 价格页只能用浏览器(ego-browser)
117
+
118
+ APIMart 和 KIE 的定价都是前端渲染的:
119
+
120
+ - **APIMart**:图像/视频/LLM/音频是**标签页**,切了才渲染。用 `js()` 找文本等于「视频」的可见元素点一下,等 4 秒再取 `document.body.innerText`
121
+ - **KIE**:441 个模型的**搜索框** + 分页。`fillInput('input[type="text"]', 'seedance')` → 等 3.5 秒 → 取全文
122
+ - ⚠️ 注意底部的 `1-25 of 28`:**默认每页 25 条,会漏**。换更精确的搜索词(如 `bytedance/seedance-2,` 带逗号)把结果压到 25 条以内
123
+
124
+ 把 ego-browser 的输出落盘要这样写(`cliLog` 走的是进程输出):
125
+
126
+ ```bash
127
+ ego-browser nodejs > out.txt 2>&1 <<'EOF'
128
+ const task = await useOrCreateTaskSpace(<空间id>)
129
+ cliLog(await js(`document.body.innerText`))
130
+ EOF
131
+ ```
132
+
133
+ ---
134
+
135
+ ## 三、怎么处理文档:两个提取脚本 + 一轮交叉校验
136
+
137
+ ### 1. KIE 文档是 OpenAPI YAML,用脚本提 schema
138
+
139
+ KIE 每页正文是一个 ```` ```yaml ```` 代码块包着的完整 OpenAPI。手读会漏字段,**必须用脚本递归展开**(含 `enum` / `default` / `minItems` / `maxItems` / 嵌套对象):
140
+
141
+ ```python
142
+ # kie_extract.py —— 用法:python3 kie_extract.py <文件...>
143
+ import sys, re, yaml, json
144
+
145
+ def fmt(name, sch, indent=0, req=()):
146
+ pad = ' ' * indent
147
+ typ = sch.get('type', '')
148
+ if 'enum' in sch: typ += ' enum=' + json.dumps(sch['enum'], ensure_ascii=False)
149
+ if 'default' in sch: typ += f" default={json.dumps(sch['default'], ensure_ascii=False)}"
150
+ for k in ('minimum','maximum','minLength','maxLength','minItems','maxItems'):
151
+ if k in sch: typ += f" {k}={sch[k]}"
152
+ desc = re.sub(r'\s*\n\s*', ' ', (sch.get('description') or '').strip())
153
+ print(f"{pad}- {name} [{typ}] {'必填' if name in req else '可选'}: {desc[:1400]}")
154
+ if sch.get('type') == 'object' and 'properties' in sch:
155
+ r = tuple(sch.get('required', ()))
156
+ for k, v in sch['properties'].items(): fmt(k, v, indent + 1, r)
157
+ if sch.get('type') == 'array' and isinstance(sch.get('items'), dict):
158
+ it = sch['items']
159
+ if it.get('type') == 'object' and 'properties' in it:
160
+ r = tuple(it.get('required', ()))
161
+ for k, v in it['properties'].items(): fmt(k, v, indent + 1, r)
162
+
163
+ for path in sys.argv[1:]:
164
+ t = open(path, encoding='utf-8').read()
165
+ m = re.search(r'```yaml\n(.*?)\n```', t, re.S)
166
+ if not m: print(f'{path}: 无 OpenAPI 块'); continue
167
+ d = yaml.safe_load(m.group(1))
168
+ print('\n=====', path.split('/')[-1])
169
+ for p, ops in d.get('paths', {}).items():
170
+ for method, op in ops.items():
171
+ print(f"### {method.upper()} {p} | {op.get('summary')} | {op.get('operationId')}")
172
+ rb = op.get('requestBody', {}).get('content', {}).get('application/json', {}).get('schema')
173
+ if rb:
174
+ req = tuple(rb.get('required', ()))
175
+ for k, v in (rb.get('properties') or {}).items(): fmt(k, v, 1, req)
176
+ ```
177
+
178
+ **`input` 是 `oneOf` 的要单独展开**(KIE 用它表达「二选一的输入形态」,如 Kling Omni 的「单张首帧」vs「仅视频输入」)——上面脚本会跳过,需要另外 dump `schema['properties']['input']`。
179
+
180
+ 对比多个变体的字段差异,一行就够:
181
+
182
+ ```bash
183
+ for f in seedance-2 seedance-2-fast seedance-2-mini; do
184
+ echo -n "$f: "; python3 kie_extract.py raw/$f.md | grep -oE "^ - [a-z_]+" | tr -d ' -' | tr '\n' ' '; echo
185
+ done
186
+ # 一眼看出 mini 少了 return_last_frame
187
+ ```
188
+
189
+ ### 2. APIMart 文档是 MDX,代码示例占 80%,先剥掉
190
+
191
+ 每页会把同一个请求写成 15 种语言的示例,正文被淹没:
192
+
193
+ ```python
194
+ # apimart_strip.py —— 保留 bash/json,其余语言的代码块换成占位符
195
+ import sys, re
196
+ for path in sys.argv[1:]:
197
+ t = open(path, encoding='utf-8').read()
198
+ t = re.sub(r'```([^\n]*)\n(.*?)```',
199
+ lambda m: m.group(0) if m.group(1).startswith(('bash','json'))
200
+ else f'\n[[{m.group(1).strip()} 示例已省略]]\n', t, flags=re.S)
201
+ print(re.sub(r'\n{3,}', '\n\n', t))
202
+ ```
203
+
204
+ 之后配合 `sed -n '/^## Body/,$p'` 直接跳到参数区。
205
+
206
+ ### 3. 必做的三项交叉校验
207
+
208
+ | 校验 | 为什么 | 这次的实例 |
209
+ |---|---|---|
210
+ | **API 文档正文价格 vs 定价页价格** | 文档正文更新慢,经常是过期价 | Seedream Pro 文档写 $0.045/$0.09,定价页是 $0.02928/$0.05856 |
211
+ | **同一模型跨供应商的取值集合** | 名字一样但取值/默认值经常不同 | Lite 分辨率官方是 2K/3K/4K,旧文档抄成了 1K/2K;`adaptive`(APIMart/KIE) vs `auto`(Fal);`duration` 整数 vs 字符串 |
212
+ | **schema 内部自相矛盾** | 供应商文档确实会写错 | KIE Qwen3-Pro 的 `enum` 与 `default` 不一致;KIE z-image 的 `aspect_ratio` 描述提到 `auto` 但枚举里没有 |
213
+
214
+ **处理原则**:两处不一致时**两个都写进文档**并说明以哪个为准;文档自相矛盾时标注「接入前实测确认」,不要替供应商猜。
215
+
216
+ ---
217
+
218
+ ## 四、SDK 官方资料先行与首发验证(唯一详细规范)
219
+
220
+ Henji-AI 是 `@henjicc/ai-sdk` 的主开发仓库与首发验证宿主。新模型、新供应商或新协议必须先在这里完成官方调研、SDK 实现和完整验证,再发布版本;消费项目只接入已经验证并发布的精确版本。禁止先在消费项目按猜测实现协议,再把结果回填 SDK。
221
+
222
+ ### 1. 先文档,后代码
223
+
224
+ 编码前必须把以下信息写入本目录对应的供应商/模型文档,并能逐项追溯到官方来源:
225
+
226
+ - 模型展示名、API model ID 与适用区域/版本;
227
+ - Base URL、端点、方法、鉴权、请求字段、枚举、限制和默认值;
228
+ - 当前价格、计费维度、价格来源与冲突取舍;
229
+ - 同步响应,或轮询、SSE、WebSocket 等异步/流式协议的完整事件契约;
230
+ - 错误、终态、取消、断线、超时、资源释放与连接复用规则。
231
+
232
+ 缺少官方来源,或模型、端点、价格、事件契约中任一项仍无法确定时,必须把未知项和已查入口写清并暂停编码;不得用相近模型、旧版本、SDK 现状或消费项目行为替官方契约作结论。官方资料本身矛盾时同时保留冲突来源,标为“实现前待官方确认/授权实测”,不能替供应商猜。
233
+
234
+ ### 2. 流式与异步协议必须有事件契约矩阵
235
+
236
+ 只要涉及 WebSocket、SSE、流式 HTTP、上传后轮询或回调,就必须在供应商/模型文档中按官方资料建立事件级矩阵。每一个官方事件/状态单独一行,不得只写一条 happy path 示例:
237
+
238
+ | 事件/状态 | 前置状态 | 字段契约(required / optional / nullable) | 空值/缺字段语义 | 下一状态 | 对外输出 | 副作用 | 终态/错误 | 连接复用 |
239
+ |---|---|---|---|---|---|---|---|---|
240
+ | 官方事件名或状态值 | 允许从哪些状态进入 | 逐字段写清存在性、类型与可空性 | `null`、空串、空数组、字段缺失分别是否合法以及是否忽略 | 保持/迁移到哪个状态 | partial/final/usage/finish 或无输出 | ack、上传、轮询、计时器、资源释放等 | 是否终止;官方错误码/原因 | 继续收消息、等待关闭、主动关闭或可开启下一会话 |
241
+
242
+ 矩阵还必须说明状态机不变量:首事件、合法重复/乱序、是否允许先终态后结果、什么才算“有效 final”、空终态如何处理、断线后能否恢复、取消与正常结束各释放哪些资源。若官方没有说明某项,明确写“官方未说明”,不要把实现假设写成官方事实。
243
+
244
+ ### 3. 官方示例与 fixture 一一对应
245
+
246
+ 官方资料中出现的每一个字面请求、响应或事件示例,都要逐项进入 `packages/ai-sdk/tests/fixtures/`,或由测试逐字内联引用同一份 fixture。fixture 必须记录:
247
+
248
+ - 精确来源 URL 与抓取日期;
249
+ - 内容是官方原样、仅做脱敏/不可联网替换,还是从字段表构造;
250
+ - 任何替换的字段及替换原因;
251
+ - 对应事件矩阵的行或场景。
252
+
253
+ 原样示例只允许做安全脱敏、ID/URL 不可联网替换和必要的稳定化,不得为了让当前 parser 通过而补字段。官方只有字段表、没有字面示例时,可以据表构造 fixture,但必须标为“依据官方字段表构造”,不能标为官方原样。合成负例必须放在独立场景或独立文件并标为 `synthetic-negative`(或同等清晰标记),不得冒充官方样本。fixture 的通用格式与现有目录约定见 [../../tests/fixtures/README.md](../../tests/fixtures/README.md)。
254
+
255
+ ### 4. fixture、parser 与测试必须闭环
256
+
257
+ 协议实现的精确测试必须从事件矩阵和 fixture 推导,至少覆盖实际适用的下列场景:
258
+
259
+ - 官方 happy path 的逐事件解析与完整状态迁移;
260
+ - 合法空值(包括合法空始帧/心跳/无输出事件);
261
+ - required 字段缺失或类型错误的明确拒绝;
262
+ - 空终态、结束前无有效 final、重复事件、乱序事件;
263
+ - 供应商错误事件、网络断开、取消、超时;
264
+ - 正常结束、失败、取消、断线后的连接、计时器、迭代器和会话资源释放。
265
+
266
+ “测试通过”还不够,门禁必须做一次**断牙验证**:临时破坏被测试的不变量(例如把合法空事件误判为错误、接受缺失必填字段、漏掉终态释放),确认对应测试确实失败,再恢复实现并确认重新通过。断牙改动不能提交;交接中记录破坏点和实际失败的测试。只匹配标题、关键词或 fixture 数量的检查不算协议门禁。
267
+
268
+ ### 5. SDK 首发与消费顺序
269
+
270
+ 发布和接入严格按以下顺序进行,任一步失败都在当前阶段修复,不跨阶段绕过:
271
+
272
+ 1. 在 Henji-AI 跑变更协议/模型的精确契约测试与宿主集成测试;
273
+ 2. 跑 SDK 全量测试、可移植性检查、类型/构建、打包与本地安装包验证;
274
+ 3. 从将要发布的包或远端预发布/正式包回装,在受限运行环境验证公开入口、按需 bundle 与版本内容;
275
+ 4. 发布 SDK;
276
+ 5. 消费项目精确锁定已验证版本及 lockfile integrity,不使用 workspace 提升、浮动范围或源码旁路;
277
+ 6. 消费项目再运行宿主 transport、凭据、媒体、取消、日志和资源释放的集成测试。
278
+
279
+ 真实付费网络只在用户明确授权时执行;没有真网不妨碍协议契约测试,但必须在交接中准确写明边界,不能把 fixture/scripted 测试表述成真实供应商成功。
280
+
281
+ ### 6. SDK 开发态、发布态与消费态
282
+
283
+ `@henjicc/ai-sdk` 只有一个源码主仓和一个正式分发渠道。不要把 Henji-AI 仓内为了开发而存在的 workspace 解析方式,误当成其他项目的安装方式。
284
+
285
+ | 状态 | 权威来源 | 允许的依赖/包形态 | 必须证明什么 |
286
+ |---|---|---|---|
287
+ | 开发态与首发验证 | Henji-AI `packages/ai-sdk` | 仓内 workspace 源码、构建产物、由当前源码生成的本地 tarball | 源码改动、公共导出、类型、可移植性、打包内容与宿主集成正确 |
288
+ | 待发布/正式发布 | 当前版本生成的 npm | `npm pack` 产物用于发布前回装;正式包只发布到公共 npm registry | tarball 内容等于待发布版本;完整改动已通过发布门禁及消费者影响核查,按持续授权自主发布;公共 registry 可匿名读取 |
289
+ | 外部消费 | 公共 npm 上已经发布的不可变版本 | `@henjicc/ai-sdk` 精确版本及对应 lockfile resolved/integrity | 在没有 Henji-AI workspace、源码旁路和用户 npm/GitHub 凭据时仍能安装、导入和运行所需入口 |
290
+
291
+ 硬性边界:
292
+
293
+ 1. Henji-AI 之外的仓库一律视为外部消费者,只能从 `https://registry.npmjs.org/` 安装已发布版本。禁止使用 `workspace:`、`file:`、Git URL、GitHub Packages、源码复制、软链接或手工 tarball 路径作为正式依赖。
294
+ 2. 外部消费者的 manifest 必须写精确版本,不使用 `^`、`~`、`latest` 等浮动范围;lockfile 必须解析到公共 npm tarball,并保存与正式包一致的 integrity。Henji-AI 根 manifest 虽然也声明精确版本,但仓内可能由 npm workspace 解析到本地源码,因此不能拿本仓的安装结果替代仓外验证。
295
+ 3. 消费项目需要尚未发布的能力时,先在 Henji-AI 完成官方资料、实现、契约测试、SDK 全量门禁、打包和回装;正式发布后,消费项目再升级。禁止先在消费方复制 provider/parser/transport 内核或长期 patch SDK。
296
+ 4. **用户已持续授权 Agent 自主发布 `@henjicc/ai-sdk`,无需逐次确认。** 一组完整 SDK 功能或修复完成后,应完成版本升级、变更说明和发布门禁,再自主发布到公共 npm;不能只提交源码或重建本地 dist 就声称外部消费者已获得更新。具体要求:
297
+ - **发布单位**:可独立验证的一组完整改动,不为每次小编辑发版本。影响 SDK 对外功能、请求契约、兼容性或可消费产物的改动进入发布流程;仅痕迹AI界面、规则、文档或测试调整不触发发布。用户明确要求暂缓某次发布时遵从该要求。
298
+ - **版本级别**:兼容性修复升级 patch,兼容性新增能力升级 minor;删除公共入口、改变参数含义或其他破坏性变更不得作为 patch 发布。稳定版破坏性变更升级 major,`0.x` 阶段升级 minor,并写明迁移方法。
299
+ - **发布前核查**:读取 [消费项目清单](../consumers.md),核对公共导出和请求/响应契约的实际使用;破坏性变更先确认可行的迁移路径,必要时提供过渡入口。关键兼容性影响尚不明确或发布门禁失败时,先解决并报告阻塞,不以已有授权绕过验证,也不把重新询问发布许可当成修复手段。
300
+ - **发布验证**:完成本手册要求的 SDK 全量门禁、候选 tarball 打包回装和 Henji-AI 首发验证;确认对应发布提交的必需 CI 门禁通过。版本号、包内容与已验证源码必须一致,发布内容不得夹带其他任务未验证的改动。
301
+ - **发布后同步**:按第 5、8 条完成公共 registry 匿名安装验证,并只升级实际需要新能力或修复的消费者;不要求所有项目机械追随每个新版本。报告已发布版本、验证结果、消费者升级情况及尚未验证的部分。
302
+ - **授权边界**:本授权针对 SDK 公共 npm 发布,不自动授权真实付费生成、改换分发渠道、绕过权限或改写远端历史。遇到必须由用户完成的 2FA 或凭据操作时,仅请求该必要协助,不重复询问是否允许发布。
303
+ 5. 发布前用当前源码产生唯一候选 tarball并完成本地回装;发布后必须在仓外临时目录移除项目级 workspace 影响和用户 npm/GitHub 凭据,从公共 npm 重新安装,核对包名、版本、公开入口和实际所需 bundle。只有这一步通过,才能称为“别人可以直接安装”。
304
+ 6. npm 返回 2FA、token 或权限错误时,只修复公共 npm 的鉴权;不得改用私有 registry、GitHub Packages 或源码安装绕过。若发布结果不确定,先查询公共 registry:版本已存在就按 npm 不可变原则发布新版本,版本不存在才重试原版本。
305
+ 7. GitHub Packages 只可作为历史记录,不再发布新版本,也不得在消费项目新增 `@henjicc` scope 的 GitHub registry 映射。历史包是否删除不影响公共 npm 消费链路。
306
+ 8. 正式发布并通过仓外验证后,读取 [消费项目清单](../consumers.md),只升级实际受影响的消费者,逐个记录精确版本、integrity、同步 commit、宿主边界与验证结果。
307
+
308
+ ---
309
+
310
+ ## 五、零散但会卡住你的坑
311
+
312
+ | 坑 | 表现 | 解法 |
313
+ |---|---|---|
314
+ | **KIE 限流** | 连续请求后返回 HTTP **200**,但内容是 HTML 外壳 | 用 `grep -l "DOCTYPE html"` 检出,加 2 秒延迟重试。批量下载后一定要跑一次这个检查 |
315
+ | **zsh 不做单词分割** | `for p in $PATHS` 把整个多行变量当成一个词 | 用 `while IFS= read -r p; do ... done < 路径文件` |
316
+ | **Bash 工具禁用前台 `sleep`** | 加延迟的循环跑不了 | `perl -e 'select(undef,undef,undef,2.0)'` |
317
+ | **ego-browser 里 `require` + 顶层 await 冲突** | `Cannot determine intended module format` | 别在 heredoc 里写文件,用 `> out.txt 2>&1` 重定向 |
318
+ | **shell 工作目录会跨调用保留** | 上一条 `cd` 影响下一条 | 一律用绝对路径 |
319
+ | **文件名带 `/`** | 批量落盘时路径炸掉 | `tr '/' '~'` 做扁平文件名 |
320
+ | **Fal 价格标注 tentative** | 价格会变 | 文档里注明「接入前重新读一次 `llms.txt`」 |
321
+
322
+ ---
323
+
324
+ ## 六、推荐执行顺序
325
+
326
+ 1. **抓三份 `llms.txt` 索引** → 按模型名前缀过滤,列出**完整**页面清单(这一步决定会不会漏能力)
327
+ 2. **Fal 端点探测** → 补上索引里没有的组合路径
328
+ 3. **批量 curl 落盘**(`.md` / `llms.txt`),完成后检查有没有 HTML 外壳
329
+ 4. **官方站**:SPA 找内容 API,SSR 直接 curl
330
+ 5. **价格页**:ego-browser,注意标签页与分页
331
+ 6. **用两个脚本提取** schema 与正文,逐字段成表
332
+ 7. **三项交叉校验**,不一致的地方写清来源与取舍
333
+ 8. 涉及异步/流式协议时,完成第四节的事件矩阵、官方 fixture 与测试场景清单
334
+ 9. 每份文档结尾写「原始链接索引」,标注**是否需要登录**
335
+
336
+ ---
337
+
338
+ 相关:[README.md](README.md)(模型清单与结构约定)、[docs/rules/model-adaptation.md](../../../../docs/rules/model-adaptation.md)(代码侧适配规范)