@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,72 +1,72 @@
1
- # 错误处理
2
-
3
- SDK 有两层错误契约:生成/上传的 `AiRuntimeError.code`,以及 LLM 的
4
- `ProviderModelStepError.details` 分类。宿主显示用户可读提示,把原始细节放进经脱敏的调试日志;
5
- 不要把 API key、Authorization header 或完整供应商 body 原样显示。
6
-
7
- 在仓库根运行下列命令,会从 `packages/ai-sdk/src` 的真实 schema/callsites 穷举并检查本页:
8
-
9
- ```bash
10
- node packages/ai-sdk/scripts/audit-integration-docs.cjs --check
11
- ```
12
-
13
- ## AiRuntimeError
14
-
15
- | code | 宿主提示/处理 |
16
- |---|---|
17
- | `api_key_missing` | 该生成供应商未配置密钥;打开凭据设置。 |
18
- | `missing_api_key` | 媒体上传依赖的供应商密钥缺失;补配后重新提交。 |
19
- | `cancelled` | 任务已取消;不作失败 toast,停止轮询。 |
20
- | `client_disposed` | client 已释放;修正宿主生命周期,不要自动重试。 |
21
- | `empty_result` | 供应商已响应但没有可用结果 URL;保留 taskId 与脱敏响应供排查。 |
22
- | `invalid_audio` | 实时识别没有收到可提交的音频;检查录音与分块生命周期。 |
23
- | `invalid_audio_chunk` | 音频块为空或不满足 PCM 字节对齐;宿主修正分块后再发送。 |
24
- | `invalid_data_uri` | 媒体 data URI 格式无效;让用户重新选择/导出文件。 |
25
- | `invalid_base64` | 媒体 base64 数据无效;让宿主重新编码文件。 |
26
- | `invalid_json` | 供应商返回非 JSON;不重放付费创建请求,保留 taskId 查询。 |
27
- | `invalid_media` | 文件识别收到空媒体;让用户重新选择或重新读取文件。 |
28
- | `invalid_parameter` | ASR 通用或供应商参数类型/范围无效;修正调用参数,不自动重试。 |
29
- | `invalid_provider_id` | 自定义 provider ID 为空;在注册前校验。 |
30
- | `invalid_response` | 响应缺少必需字段;提示协议不兼容并记录脱敏响应。 |
31
- | `invalid_route` | catalog 给出空路由;属于开发/版本错误。 |
32
- | `invalid_selector_result` | endpoint selector 没有返回字符串;属于开发/版本错误。 |
33
- | `provider_already_registered` | provider ID 已被另一 client 占用;使用唯一 ID 或先 `dispose()`。 |
34
- | `provider_http_error` | 供应商 HTTP 失败;按 status 引导检查参数/鉴权/服务。 |
35
- | `provider_network_error` | DNS/连接等网络失败;允许用户主动重试,不自动重放可能计费的 POST。 |
36
- | `provider_not_found` | 模型无法映射 provider;检查模型 ID/版本。 |
37
- | `provider_task_failed` | 供应商明确宣告任务失败;显示经脱敏原因,不继续轮询。 |
38
- | `provider_task_unreachable` | 状态查询连续 20 次失败;保留 taskId,让用户稍后手动续查。 |
39
- | `public_media_url_required` | 目标字段必须是公网 URL,但当前供应商没有可用官方上传路径。 |
40
- | `unknown_provider` | 调用了未注册 provider;核对 ID 或注册流程。 |
41
- | `unsupported_media_source` | 后端不能解析 `blob:` 等媒体引用;宿主先导出成受管字节。 |
42
- | `unsupported_media_type` | 上传端点不支持当前 MIME;转成文档允许的格式。 |
43
- | `unsupported_audio_format` | ASR 音频编码不受当前协议支持;按模型要求转换格式。 |
44
- | `unsupported_parameter` | 当前 P0 协议未实现该可选参数;宿主移除参数或选择其他模型。 |
45
- | `unsupported_provider` | 对同步 provider 调用了续轮询等不支持的生命周期。 |
46
- | `upload_failed` | 供应商官方上传失败/未返回 URL;引导重新选择或检查密钥。 |
47
- | `upload_timeout` | Fal 两段上传超过 120 秒;确认网络后由用户重新提交。 |
48
- | `upload_too_large` | 文件超过上传上限;显示精确限制并让用户压缩/换文件。 |
49
-
50
- ## LLM 结构化错误
51
-
52
- `ProviderModelStepError.details` 固定字段为 `code/category/status/retryable/retryAfterMs/providerId/modelId/requestId/message`。
53
- 供应商的 code 可动态透传;SDK 自己产生的固定 code 是 `API_KEY_MISSING`、`MODEL_REQUEST_TIMEOUT`、
54
- `MODEL_STEP_CANCELLED`、`PROVIDER_ERROR`。字符串协议 marker 为 `api_key_missing`、`model_step_failed`、
55
- `provider_error`、`task_cancelled`。
56
-
57
- | category | 建议提示 | SDK 默认 retryable |
58
- |---|---|---|
59
- | `authentication` | 鉴权失败,重新配置密钥 | 否 |
60
- | `billing` | 计费状态异常,检查账单/充值 | 否 |
61
- | `quota` | 供应商额度不足 | 否 |
62
- | `rate_limit` | 请求频率受限,按 `retryAfterMs` 等待 | 是 |
63
- | `server` | 供应商服务暂时不可用 | 是 |
64
- | `network` | 网络请求失败 | 是 |
65
- | `invalid_request` | 供应商拒绝了参数,显示脱敏 detail | 否 |
66
- | `context_overflow` | 上下文超限,缩短历史/附件 | 否 |
67
- | `content_filter` | 内容策略拒绝,调整输入 | 否 |
68
- | `cancelled` | 用户取消,不当成系统失败 | 否 |
69
- | `unknown` | 供应商请求失败,保留 requestId 供排查 | 否 |
70
-
71
- `retryable: true` 不等于宿主可以无脑重放一次完整付费请求。生成创建 POST 只在能证明尚未建连时有
72
- “安全预连接”重试;轮询 GET 和 LLM 模型步又有各自独立生命周期。
1
+ # 错误处理
2
+
3
+ SDK 有两层错误契约:生成/上传的 `AiRuntimeError.code`,以及 LLM 的
4
+ `ProviderModelStepError.details` 分类。宿主显示用户可读提示,把原始细节放进经脱敏的调试日志;
5
+ 不要把 API key、Authorization header 或完整供应商 body 原样显示。
6
+
7
+ 在仓库根运行下列命令,会从 `packages/ai-sdk/src` 的真实 schema/callsites 穷举并检查本页:
8
+
9
+ ```bash
10
+ node packages/ai-sdk/scripts/audit-integration-docs.cjs --check
11
+ ```
12
+
13
+ ## AiRuntimeError
14
+
15
+ | code | 宿主提示/处理 |
16
+ |---|---|
17
+ | `api_key_missing` | 该生成供应商未配置密钥;打开凭据设置。 |
18
+ | `missing_api_key` | 媒体上传依赖的供应商密钥缺失;补配后重新提交。 |
19
+ | `cancelled` | 任务已取消;不作失败 toast,停止轮询。 |
20
+ | `client_disposed` | client 已释放;修正宿主生命周期,不要自动重试。 |
21
+ | `empty_result` | 供应商已响应但没有可用结果 URL;保留 taskId 与脱敏响应供排查。 |
22
+ | `invalid_audio` | 实时识别没有收到可提交的音频;检查录音与分块生命周期。 |
23
+ | `invalid_audio_chunk` | 音频块为空或不满足 PCM 字节对齐;宿主修正分块后再发送。 |
24
+ | `invalid_data_uri` | 媒体 data URI 格式无效;让用户重新选择/导出文件。 |
25
+ | `invalid_base64` | 媒体 base64 数据无效;让宿主重新编码文件。 |
26
+ | `invalid_json` | 供应商返回非 JSON;不重放付费创建请求,保留 taskId 查询。 |
27
+ | `invalid_media` | 文件识别收到空媒体;让用户重新选择或重新读取文件。 |
28
+ | `invalid_parameter` | ASR 通用或供应商参数类型/范围无效;修正调用参数,不自动重试。 |
29
+ | `invalid_provider_id` | 自定义 provider ID 为空;在注册前校验。 |
30
+ | `invalid_response` | 响应缺少必需字段;提示协议不兼容并记录脱敏响应。 |
31
+ | `invalid_route` | catalog 给出空路由;属于开发/版本错误。 |
32
+ | `invalid_selector_result` | endpoint selector 没有返回字符串;属于开发/版本错误。 |
33
+ | `provider_already_registered` | provider ID 已被另一 client 占用;使用唯一 ID 或先 `dispose()`。 |
34
+ | `provider_http_error` | 供应商 HTTP 失败;按 status 引导检查参数/鉴权/服务。 |
35
+ | `provider_network_error` | DNS/连接等网络失败;允许用户主动重试,不自动重放可能计费的 POST。 |
36
+ | `provider_not_found` | 模型无法映射 provider;检查模型 ID/版本。 |
37
+ | `provider_task_failed` | 供应商明确宣告任务失败;显示经脱敏原因,不继续轮询。 |
38
+ | `provider_task_unreachable` | 状态查询连续 20 次失败;保留 taskId,让用户稍后手动续查。 |
39
+ | `public_media_url_required` | 目标字段必须是公网 URL,但当前供应商没有可用官方上传路径。 |
40
+ | `unknown_provider` | 调用了未注册 provider;核对 ID 或注册流程。 |
41
+ | `unsupported_media_source` | 后端不能解析 `blob:` 等媒体引用;宿主先导出成受管字节。 |
42
+ | `unsupported_media_type` | 上传端点不支持当前 MIME;转成文档允许的格式。 |
43
+ | `unsupported_audio_format` | ASR 音频编码不受当前协议支持;按模型要求转换格式。 |
44
+ | `unsupported_parameter` | 当前 P0 协议未实现该可选参数;宿主移除参数或选择其他模型。 |
45
+ | `unsupported_provider` | 对同步 provider 调用了续轮询等不支持的生命周期。 |
46
+ | `upload_failed` | 供应商官方上传失败/未返回 URL;引导重新选择或检查密钥。 |
47
+ | `upload_timeout` | Fal 两段上传超过 120 秒;确认网络后由用户重新提交。 |
48
+ | `upload_too_large` | 文件超过上传上限;显示精确限制并让用户压缩/换文件。 |
49
+
50
+ ## LLM 结构化错误
51
+
52
+ `ProviderModelStepError.details` 固定字段为 `code/category/status/retryable/retryAfterMs/providerId/modelId/requestId/message`。
53
+ 供应商的 code 可动态透传;SDK 自己产生的固定 code 是 `API_KEY_MISSING`、`MODEL_REQUEST_TIMEOUT`、
54
+ `MODEL_STEP_CANCELLED`、`PROVIDER_ERROR`。字符串协议 marker 为 `api_key_missing`、`model_step_failed`、
55
+ `provider_error`、`task_cancelled`。
56
+
57
+ | category | 建议提示 | SDK 默认 retryable |
58
+ |---|---|---|
59
+ | `authentication` | 鉴权失败,重新配置密钥 | 否 |
60
+ | `billing` | 计费状态异常,检查账单/充值 | 否 |
61
+ | `quota` | 供应商额度不足 | 否 |
62
+ | `rate_limit` | 请求频率受限,按 `retryAfterMs` 等待 | 是 |
63
+ | `server` | 供应商服务暂时不可用 | 是 |
64
+ | `network` | 网络请求失败 | 是 |
65
+ | `invalid_request` | 供应商拒绝了参数,显示脱敏 detail | 否 |
66
+ | `context_overflow` | 上下文超限,缩短历史/附件 | 否 |
67
+ | `content_filter` | 内容策略拒绝,调整输入 | 否 |
68
+ | `cancelled` | 用户取消,不当成系统失败 | 否 |
69
+ | `unknown` | 供应商请求失败,保留 requestId 供排查 | 否 |
70
+
71
+ `retryable: true` 不等于宿主可以无脑重放一次完整付费请求。生成创建 POST 只在能证明尚未建连时有
72
+ “安全预连接”重试;轮询 GET 和 LLM 模型步又有各自独立生命周期。
@@ -1,17 +1,17 @@
1
- # form-renderer
2
-
3
- 无框架、无 DOM 依赖的 `@henjicc/ai-sdk@0.2.8` 参数表单契约示例。它从 `client.catalog` 读取真实模型,使用
4
- `evaluateRuntimeCondition()` 处理显隐/禁用,使用 `getRuntimeMediaInputContract()` 生成媒体上传入口。
5
- 示例只使用 `generation`、`catalog` 与 `runtime` 按需入口,保留完整 generation catalog,
6
- 但不会带入 LLM/BigModel。
7
-
8
- ```bash
9
- npm install
10
- npm start
11
- ```
12
-
13
- 入口会真实渲染 5 个差异模型,覆盖普通下拉与数值、条件显隐、动态 input limits、通用与特殊媒体、
14
- `composite` 宿主钩子。输出是最小 HTML 骨架,不包含痕迹AI 的名称、i18n、面板布局或专属组件。
15
-
16
- 媒体控件只负责让宿主选择本地/受管资源,不能降级为 URL 文本框;实际上传仍由 SDK 在请求边界调用
17
- 当前供应商的官方上传能力。`composite` 只输出 `data-control="custom"`,宿主按参数 ID 注入自己的组件。
1
+ # form-renderer
2
+
3
+ 无框架、无 DOM 依赖的 `@henjicc/ai-sdk@0.3.0` 参数表单契约示例。它从 `client.catalog` 读取真实模型,使用
4
+ `evaluateRuntimeCondition()` 处理显隐/禁用,使用 `getRuntimeMediaInputContract()` 生成媒体上传入口。
5
+ 示例只使用 `generation`、`catalog` 与 `runtime` 按需入口,保留完整 generation catalog,
6
+ 但不会带入 LLM/BigModel。
7
+
8
+ ```bash
9
+ npm install
10
+ npm start
11
+ ```
12
+
13
+ 入口会真实渲染 5 个差异模型,覆盖普通下拉与数值、条件显隐、动态 input limits、通用与特殊媒体、
14
+ `composite` 宿主钩子。输出是最小 HTML 骨架,不包含痕迹AI 的名称、i18n、面板布局或专属组件。
15
+
16
+ 媒体控件只负责让宿主选择本地/受管资源,不能降级为 URL 文本框;实际上传仍由 SDK 在请求边界调用
17
+ 当前供应商的官方上传能力。`composite` 只输出 `data-control="custom"`,宿主按参数 ID 注入自己的组件。
@@ -1,32 +1,32 @@
1
- import { createGenerationClient } from '@henjicc/ai-sdk/generation'
2
- import type { RuntimeContext } from '@henjicc/ai-sdk/runtime'
3
-
4
- import { renderMinimalModelForm } from './index.js'
5
-
6
- const runtime: RuntimeContext = {
7
- transport: { fetch: async () => { throw new Error('form-renderer does not access the network') } },
8
- credentials: { get: () => undefined },
9
- media: { read: async () => { throw new Error('form-renderer does not read media') } },
10
- }
11
-
12
- const modelIds = [
13
- 'volcengine-seedream-5.0-lite',
14
- 'apimart-gemini-omni-flash',
15
- 'ppio-wan-2.7',
16
- 'apimart-midjourney',
17
- 'ppio-minimax-speech',
18
- ] as const
19
-
20
- const client = createGenerationClient({ runtime })
21
- try {
22
- const forms = modelIds.map((modelId) => renderMinimalModelForm(client, modelId))
23
- console.log(JSON.stringify(forms.map((form) => ({
24
- modelId: form.modelId,
25
- controlCount: form.controls.length,
26
- mediaKinds: [...new Set(form.controls.map((control) => control.mediaKind).filter(Boolean))],
27
- customControlIds: form.customControlIds,
28
- html: form.html,
29
- })), null, 2))
30
- } finally {
31
- client.dispose()
32
- }
1
+ import { createGenerationClient } from '@henjicc/ai-sdk/generation'
2
+ import type { RuntimeContext } from '@henjicc/ai-sdk/runtime'
3
+
4
+ import { renderMinimalModelForm } from './index.js'
5
+
6
+ const runtime: RuntimeContext = {
7
+ transport: { fetch: async () => { throw new Error('form-renderer does not access the network') } },
8
+ credentials: { get: () => undefined },
9
+ media: { read: async () => { throw new Error('form-renderer does not read media') } },
10
+ }
11
+
12
+ const modelIds = [
13
+ 'volcengine-seedream-5.0-lite',
14
+ 'apimart-gemini-omni-flash',
15
+ 'ppio-wan-2.7',
16
+ 'apimart-midjourney',
17
+ 'ppio-minimax-speech',
18
+ ] as const
19
+
20
+ const client = createGenerationClient({ runtime })
21
+ try {
22
+ const forms = modelIds.map((modelId) => renderMinimalModelForm(client, modelId))
23
+ console.log(JSON.stringify(forms.map((form) => ({
24
+ modelId: form.modelId,
25
+ controlCount: form.controls.length,
26
+ mediaKinds: [...new Set(form.controls.map((control) => control.mediaKind).filter(Boolean))],
27
+ customControlIds: form.customControlIds,
28
+ html: form.html,
29
+ })), null, 2))
30
+ } finally {
31
+ client.dispose()
32
+ }
@@ -1,144 +1,144 @@
1
- import {
2
- evaluateRuntimeCondition,
3
- flattenRuntimeParams,
4
- getRuntimeMediaInputContract,
5
- } from '@henjicc/ai-sdk/catalog'
6
- import type { GenerationClient } from '@henjicc/ai-sdk/generation'
7
-
8
- type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject
9
- type JsonObject = { [key: string]: JsonValue }
10
- type RuntimeParamDef = ReturnType<GenerationClient['catalog']['getParams']>[number]
11
-
12
- export type MinimalControlKind =
13
- | 'text'
14
- | 'textarea'
15
- | 'number'
16
- | 'select'
17
- | 'switch'
18
- | 'upload'
19
- | 'custom'
20
-
21
- export interface MinimalRenderedControl {
22
- id: string
23
- kind: MinimalControlKind
24
- value: JsonValue | undefined
25
- disabled: boolean
26
- source: 'param' | 'input-limits'
27
- mediaKind?: 'image' | 'video' | 'audio' | 'file'
28
- }
29
-
30
- export interface MinimalRenderedForm {
31
- modelId: string
32
- controls: MinimalRenderedControl[]
33
- customControlIds: string[]
34
- html: string
35
- }
36
-
37
- /**
38
- * 无框架、无 DOM 依赖的最小 renderer,只用于证明 SDK 参数契约足以驱动消费方表单。
39
- * composite 只输出 data-control="custom" 钩子;痕迹AI 专属 panel/config 属于 presentation,
40
- * 宿主必须按 param id 注入自定义组件。
41
- */
42
- export function renderMinimalModelForm(
43
- client: GenerationClient,
44
- modelId: string,
45
- values: JsonObject = {}
46
- ): MinimalRenderedForm {
47
- const model = client.catalog.get(modelId)
48
- if (!model) throw new Error(`Unknown model: ${modelId}`)
49
- const runtimeValues: JsonObject = {
50
- ...client.catalog.getDefaultValues(modelId),
51
- uploadedFilePaths: [],
52
- uploadedVideoFilePaths: [],
53
- uploadedAudioFilePaths: [],
54
- images: [],
55
- videos: [],
56
- audios: [],
57
- uploadedImages: [],
58
- uploadedVideos: [],
59
- uploadedAudios: [],
60
- ...values,
61
- }
62
- const controls: MinimalRenderedControl[] = []
63
-
64
- for (const param of flattenRuntimeParams(client.catalog.getParams(modelId))) {
65
- if (!evaluateRuntimeCondition(param.visible?.condition, runtimeValues)) continue
66
- controls.push({
67
- id: param.id,
68
- kind: controlKindForParam(param),
69
- value: runtimeValues[param.id],
70
- disabled: param.disabled !== undefined &&
71
- evaluateRuntimeCondition(param.disabled.condition, runtimeValues),
72
- source: 'param',
73
- ...mediaKindForParam(param),
74
- })
75
- }
76
-
77
- const media = getRuntimeMediaInputContract(model, runtimeValues)
78
- for (const input of media.genericInputs) {
79
- controls.push({
80
- id: input.id,
81
- kind: 'upload',
82
- value: runtimeValues[input.id],
83
- disabled: false,
84
- source: 'input-limits',
85
- mediaKind: input.kind,
86
- })
87
- }
88
-
89
- controls.sort((left, right) => {
90
- const leftParam = model.params.find((param) => param.id === left.id)
91
- const rightParam = model.params.find((param) => param.id === right.id)
92
- return (leftParam?.order ?? Number.MAX_SAFE_INTEGER) -
93
- (rightParam?.order ?? Number.MAX_SAFE_INTEGER)
94
- })
95
-
96
- return {
97
- modelId: model.meta.id,
98
- controls,
99
- customControlIds: controls.filter((control) => control.kind === 'custom').map((control) => control.id),
100
- html: `<form data-model-id="${escapeHtml(model.meta.id)}">${controls.map(renderControlHtml).join('')}</form>`,
101
- }
102
- }
103
-
104
- function controlKindForParam(param: RuntimeParamDef): MinimalControlKind {
105
- switch (param.type) {
106
- case 'text': return 'text'
107
- case 'textarea': return 'textarea'
108
- case 'number': return 'number'
109
- case 'dropdown':
110
- case 'radio':
111
- case 'resolution':
112
- case 'aspect-ratio': return 'select'
113
- case 'switch': return 'switch'
114
- case 'image-upload':
115
- case 'video-upload':
116
- case 'file-upload': return 'upload'
117
- case 'composite': return 'custom'
118
- case 'panel': return 'custom'
119
- }
120
- }
121
-
122
- function mediaKindForParam(
123
- param: RuntimeParamDef
124
- ): Pick<MinimalRenderedControl, 'mediaKind'> | Record<string, never> {
125
- if (param.type === 'image-upload') return { mediaKind: 'image' }
126
- if (param.type === 'video-upload') return { mediaKind: 'video' }
127
- if (param.type === 'file-upload') return { mediaKind: 'file' }
128
- return {}
129
- }
130
-
131
- function renderControlHtml(control: MinimalRenderedControl): string {
132
- const id = escapeHtml(control.id)
133
- const media = control.mediaKind ? ` data-media-kind="${control.mediaKind}"` : ''
134
- const disabled = control.disabled ? ' aria-disabled="true"' : ''
135
- return `<div data-param-id="${id}" data-control="${control.kind}" data-source="${control.source}"${media}${disabled}></div>`
136
- }
137
-
138
- function escapeHtml(value: string): string {
139
- return value
140
- .replaceAll('&', '&amp;')
141
- .replaceAll('"', '&quot;')
142
- .replaceAll('<', '&lt;')
143
- .replaceAll('>', '&gt;')
144
- }
1
+ import {
2
+ evaluateRuntimeCondition,
3
+ flattenRuntimeParams,
4
+ getRuntimeMediaInputContract,
5
+ } from '@henjicc/ai-sdk/catalog'
6
+ import type { GenerationClient } from '@henjicc/ai-sdk/generation'
7
+
8
+ type JsonValue = null | boolean | number | string | JsonValue[] | JsonObject
9
+ type JsonObject = { [key: string]: JsonValue }
10
+ type RuntimeParamDef = ReturnType<GenerationClient['catalog']['getParams']>[number]
11
+
12
+ export type MinimalControlKind =
13
+ | 'text'
14
+ | 'textarea'
15
+ | 'number'
16
+ | 'select'
17
+ | 'switch'
18
+ | 'upload'
19
+ | 'custom'
20
+
21
+ export interface MinimalRenderedControl {
22
+ id: string
23
+ kind: MinimalControlKind
24
+ value: JsonValue | undefined
25
+ disabled: boolean
26
+ source: 'param' | 'input-limits'
27
+ mediaKind?: 'image' | 'video' | 'audio' | 'file'
28
+ }
29
+
30
+ export interface MinimalRenderedForm {
31
+ modelId: string
32
+ controls: MinimalRenderedControl[]
33
+ customControlIds: string[]
34
+ html: string
35
+ }
36
+
37
+ /**
38
+ * 无框架、无 DOM 依赖的最小 renderer,只用于证明 SDK 参数契约足以驱动消费方表单。
39
+ * composite 只输出 data-control="custom" 钩子;痕迹AI 专属 panel/config 属于 presentation,
40
+ * 宿主必须按 param id 注入自定义组件。
41
+ */
42
+ export function renderMinimalModelForm(
43
+ client: GenerationClient,
44
+ modelId: string,
45
+ values: JsonObject = {}
46
+ ): MinimalRenderedForm {
47
+ const model = client.catalog.get(modelId)
48
+ if (!model) throw new Error(`Unknown model: ${modelId}`)
49
+ const runtimeValues: JsonObject = {
50
+ ...client.catalog.getDefaultValues(modelId),
51
+ uploadedFilePaths: [],
52
+ uploadedVideoFilePaths: [],
53
+ uploadedAudioFilePaths: [],
54
+ images: [],
55
+ videos: [],
56
+ audios: [],
57
+ uploadedImages: [],
58
+ uploadedVideos: [],
59
+ uploadedAudios: [],
60
+ ...values,
61
+ }
62
+ const controls: MinimalRenderedControl[] = []
63
+
64
+ for (const param of flattenRuntimeParams(client.catalog.getParams(modelId))) {
65
+ if (!evaluateRuntimeCondition(param.visible?.condition, runtimeValues)) continue
66
+ controls.push({
67
+ id: param.id,
68
+ kind: controlKindForParam(param),
69
+ value: runtimeValues[param.id],
70
+ disabled: param.disabled !== undefined &&
71
+ evaluateRuntimeCondition(param.disabled.condition, runtimeValues),
72
+ source: 'param',
73
+ ...mediaKindForParam(param),
74
+ })
75
+ }
76
+
77
+ const media = getRuntimeMediaInputContract(model, runtimeValues)
78
+ for (const input of media.genericInputs) {
79
+ controls.push({
80
+ id: input.id,
81
+ kind: 'upload',
82
+ value: runtimeValues[input.id],
83
+ disabled: false,
84
+ source: 'input-limits',
85
+ mediaKind: input.kind,
86
+ })
87
+ }
88
+
89
+ controls.sort((left, right) => {
90
+ const leftParam = model.params.find((param) => param.id === left.id)
91
+ const rightParam = model.params.find((param) => param.id === right.id)
92
+ return (leftParam?.order ?? Number.MAX_SAFE_INTEGER) -
93
+ (rightParam?.order ?? Number.MAX_SAFE_INTEGER)
94
+ })
95
+
96
+ return {
97
+ modelId: model.meta.id,
98
+ controls,
99
+ customControlIds: controls.filter((control) => control.kind === 'custom').map((control) => control.id),
100
+ html: `<form data-model-id="${escapeHtml(model.meta.id)}">${controls.map(renderControlHtml).join('')}</form>`,
101
+ }
102
+ }
103
+
104
+ function controlKindForParam(param: RuntimeParamDef): MinimalControlKind {
105
+ switch (param.type) {
106
+ case 'text': return 'text'
107
+ case 'textarea': return 'textarea'
108
+ case 'number': return 'number'
109
+ case 'dropdown':
110
+ case 'radio':
111
+ case 'resolution':
112
+ case 'aspect-ratio': return 'select'
113
+ case 'switch': return 'switch'
114
+ case 'image-upload':
115
+ case 'video-upload':
116
+ case 'file-upload': return 'upload'
117
+ case 'composite': return 'custom'
118
+ case 'panel': return 'custom'
119
+ }
120
+ }
121
+
122
+ function mediaKindForParam(
123
+ param: RuntimeParamDef
124
+ ): Pick<MinimalRenderedControl, 'mediaKind'> | Record<string, never> {
125
+ if (param.type === 'image-upload') return { mediaKind: 'image' }
126
+ if (param.type === 'video-upload') return { mediaKind: 'video' }
127
+ if (param.type === 'file-upload') return { mediaKind: 'file' }
128
+ return {}
129
+ }
130
+
131
+ function renderControlHtml(control: MinimalRenderedControl): string {
132
+ const id = escapeHtml(control.id)
133
+ const media = control.mediaKind ? ` data-media-kind="${control.mediaKind}"` : ''
134
+ const disabled = control.disabled ? ' aria-disabled="true"' : ''
135
+ return `<div data-param-id="${id}" data-control="${control.kind}" data-source="${control.source}"${media}${disabled}></div>`
136
+ }
137
+
138
+ function escapeHtml(value: string): string {
139
+ return value
140
+ .replaceAll('&', '&amp;')
141
+ .replaceAll('"', '&quot;')
142
+ .replaceAll('<', '&lt;')
143
+ .replaceAll('>', '&gt;')
144
+ }
@@ -1,16 +1,16 @@
1
- {
2
- "name": "@henjicc/ai-sdk-example-form-renderer",
3
- "private": true,
4
- "type": "module",
5
- "scripts": {
6
- "build": "tsc -p tsconfig.json",
7
- "start": "npm run build && node dist/cli.js"
8
- },
9
- "dependencies": {
10
- "@henjicc/ai-sdk": "0.2.8"
11
- },
12
- "devDependencies": {
13
- "@types/node": "^24.0.0",
14
- "typescript": "^5.9.2"
15
- }
16
- }
1
+ {
2
+ "name": "@henjicc/ai-sdk-example-form-renderer",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "tsc -p tsconfig.json",
7
+ "start": "npm run build && node dist/cli.js"
8
+ },
9
+ "dependencies": {
10
+ "@henjicc/ai-sdk": "0.3.0"
11
+ },
12
+ "devDependencies": {
13
+ "@types/node": "^24.0.0",
14
+ "typescript": "^5.9.2"
15
+ }
16
+ }
@@ -1,14 +1,14 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "lib": ["ES2022", "DOM"],
5
- "module": "NodeNext",
6
- "moduleResolution": "NodeNext",
7
- "strict": true,
8
- "skipLibCheck": true,
9
- "outDir": "dist",
10
- "rootDir": ".",
11
- "types": ["node"]
12
- },
13
- "include": ["index.ts", "cli.ts"]
14
- }
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM"],
5
+ "module": "NodeNext",
6
+ "moduleResolution": "NodeNext",
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "outDir": "dist",
10
+ "rootDir": ".",
11
+ "types": ["node"]
12
+ },
13
+ "include": ["index.ts", "cli.ts"]
14
+ }