@lark-base-open/base-database-cli 1.3.9 → 1.4.3

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 (320) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +119 -15
  3. package/THIRD_PARTY_LICENSES.json +1662 -0
  4. package/config-schema.json +64 -3
  5. package/data/template-hmr-scripts.json +9 -0
  6. package/data/template-index-html/17e698eef687ece8f1628e3e2c4801da5e7233faa87076b3424acde8df57b825.html +24 -0
  7. package/dist/agent-tools-guide.d.ts +29 -0
  8. package/dist/agent-tools-guide.d.ts.map +1 -0
  9. package/dist/agent-tools-guide.js +169 -0
  10. package/dist/agent-tools-guide.js.map +1 -0
  11. package/dist/agent-tools-skill.d.ts +16 -0
  12. package/dist/agent-tools-skill.d.ts.map +1 -0
  13. package/dist/agent-tools-skill.js +183 -0
  14. package/dist/agent-tools-skill.js.map +1 -0
  15. package/dist/agent-tools.d.ts +20 -0
  16. package/dist/agent-tools.d.ts.map +1 -0
  17. package/dist/agent-tools.js +137 -0
  18. package/dist/agent-tools.js.map +1 -0
  19. package/dist/ai-functions.d.ts +10 -0
  20. package/dist/ai-functions.d.ts.map +1 -1
  21. package/dist/ai-functions.js +264 -212
  22. package/dist/ai-functions.js.map +1 -1
  23. package/dist/app-builder/core.d.mts +37 -0
  24. package/dist/app-builder/core.d.mts.map +1 -0
  25. package/dist/app-builder/core.mjs +673 -0
  26. package/dist/app-builder/core.mjs.map +1 -0
  27. package/dist/app-builder/package.json +1 -0
  28. package/dist/app-builder/schema.d.ts +4 -0
  29. package/dist/app-builder/schema.d.ts.map +1 -0
  30. package/dist/app-builder/schema.js +72 -0
  31. package/dist/app-builder/schema.js.map +1 -0
  32. package/dist/archive.d.ts +22 -2
  33. package/dist/archive.d.ts.map +1 -1
  34. package/dist/archive.js +311 -74
  35. package/dist/archive.js.map +1 -1
  36. package/dist/auth.d.ts +2 -2
  37. package/dist/auth.d.ts.map +1 -1
  38. package/dist/auth.js +13 -8
  39. package/dist/auth.js.map +1 -1
  40. package/dist/build-server.d.ts +25 -0
  41. package/dist/build-server.d.ts.map +1 -0
  42. package/dist/build-server.js +32 -0
  43. package/dist/build-server.js.map +1 -0
  44. package/dist/business-update-notice.d.ts +37 -0
  45. package/dist/business-update-notice.d.ts.map +1 -0
  46. package/dist/business-update-notice.js +24 -0
  47. package/dist/business-update-notice.js.map +1 -0
  48. package/dist/check.d.ts +11 -0
  49. package/dist/check.d.ts.map +1 -1
  50. package/dist/check.js +85 -15
  51. package/dist/check.js.map +1 -1
  52. package/dist/cloud-build-diagnostic.d.ts +9 -0
  53. package/dist/cloud-build-diagnostic.d.ts.map +1 -0
  54. package/dist/cloud-build-diagnostic.js +65 -0
  55. package/dist/cloud-build-diagnostic.js.map +1 -0
  56. package/dist/config.d.ts +6 -0
  57. package/dist/config.d.ts.map +1 -1
  58. package/dist/config.js +41 -11
  59. package/dist/config.js.map +1 -1
  60. package/dist/contract-extractor.d.ts +21 -0
  61. package/dist/contract-extractor.d.ts.map +1 -0
  62. package/dist/contract-extractor.js +260 -0
  63. package/dist/contract-extractor.js.map +1 -0
  64. package/dist/contract-worker.d.ts +12 -0
  65. package/dist/contract-worker.d.ts.map +1 -0
  66. package/dist/contract-worker.js +90 -0
  67. package/dist/contract-worker.js.map +1 -0
  68. package/dist/dependency-policy.d.ts.map +1 -1
  69. package/dist/dependency-policy.js +6 -1
  70. package/dist/dependency-policy.js.map +1 -1
  71. package/dist/deploy.d.ts +20 -1
  72. package/dist/deploy.d.ts.map +1 -1
  73. package/dist/deploy.js +181 -52
  74. package/dist/deploy.js.map +1 -1
  75. package/dist/dev-bootstrap.d.ts +5 -0
  76. package/dist/dev-bootstrap.d.ts.map +1 -0
  77. package/dist/dev-bootstrap.js +185 -0
  78. package/dist/dev-bootstrap.js.map +1 -0
  79. package/dist/dev-events.d.ts +24 -0
  80. package/dist/dev-events.d.ts.map +1 -0
  81. package/dist/dev-events.js +67 -0
  82. package/dist/dev-events.js.map +1 -0
  83. package/dist/dev-pairing.d.ts +4 -0
  84. package/dist/dev-pairing.d.ts.map +1 -0
  85. package/dist/dev-pairing.js +54 -0
  86. package/dist/dev-pairing.js.map +1 -0
  87. package/dist/dev-url.d.ts +4 -0
  88. package/dist/dev-url.d.ts.map +1 -0
  89. package/dist/dev-url.js +29 -0
  90. package/dist/dev-url.js.map +1 -0
  91. package/dist/dev-vite.d.ts +9 -0
  92. package/dist/dev-vite.d.ts.map +1 -0
  93. package/dist/dev-vite.js +237 -0
  94. package/dist/dev-vite.js.map +1 -0
  95. package/dist/dev-watch.d.ts +33 -0
  96. package/dist/dev-watch.d.ts.map +1 -0
  97. package/dist/dev-watch.js +246 -0
  98. package/dist/dev-watch.js.map +1 -0
  99. package/dist/dev.d.ts +24 -0
  100. package/dist/dev.d.ts.map +1 -0
  101. package/dist/dev.js +244 -0
  102. package/dist/dev.js.map +1 -0
  103. package/dist/development-pairing.generated.d.ts +12 -0
  104. package/dist/development-pairing.generated.d.ts.map +1 -0
  105. package/dist/development-pairing.generated.js +13 -0
  106. package/dist/development-pairing.generated.js.map +1 -0
  107. package/dist/diagnostic-platforms.d.ts +3 -0
  108. package/dist/diagnostic-platforms.d.ts.map +1 -0
  109. package/dist/diagnostic-platforms.js +3 -0
  110. package/dist/diagnostic-platforms.js.map +1 -0
  111. package/dist/diagnostic-schema.d.ts +151 -0
  112. package/dist/diagnostic-schema.d.ts.map +1 -0
  113. package/dist/diagnostic-schema.js +129 -0
  114. package/dist/diagnostic-schema.js.map +1 -0
  115. package/dist/diagnostics.d.ts +78 -0
  116. package/dist/diagnostics.d.ts.map +1 -0
  117. package/dist/diagnostics.js +333 -0
  118. package/dist/diagnostics.js.map +1 -0
  119. package/dist/distribution-commands.d.ts.map +1 -1
  120. package/dist/distribution-commands.js +6 -2
  121. package/dist/distribution-commands.js.map +1 -1
  122. package/dist/distribution-npm.d.ts +2 -2
  123. package/dist/distribution-npm.d.ts.map +1 -1
  124. package/dist/distribution-npm.js +14 -1
  125. package/dist/distribution-npm.js.map +1 -1
  126. package/dist/environment-variables.d.ts.map +1 -1
  127. package/dist/environment-variables.js +2 -1
  128. package/dist/environment-variables.js.map +1 -1
  129. package/dist/function-contracts.d.ts +40 -0
  130. package/dist/function-contracts.d.ts.map +1 -0
  131. package/dist/function-contracts.js +357 -0
  132. package/dist/function-contracts.js.map +1 -0
  133. package/dist/function-description.d.ts +11 -4
  134. package/dist/function-description.d.ts.map +1 -1
  135. package/dist/function-description.js +22 -12
  136. package/dist/function-description.js.map +1 -1
  137. package/dist/function-input-types.d.ts +6 -4
  138. package/dist/function-input-types.d.ts.map +1 -1
  139. package/dist/function-input-types.js +97 -135
  140. package/dist/function-input-types.js.map +1 -1
  141. package/dist/function-params.d.ts +53 -0
  142. package/dist/function-params.d.ts.map +1 -0
  143. package/dist/function-params.js +184 -0
  144. package/dist/function-params.js.map +1 -0
  145. package/dist/function-schema.d.ts +14 -0
  146. package/dist/function-schema.d.ts.map +1 -1
  147. package/dist/function-schema.js +99 -9
  148. package/dist/function-schema.js.map +1 -1
  149. package/dist/init-journal.d.ts +1 -0
  150. package/dist/init-journal.d.ts.map +1 -1
  151. package/dist/init-journal.js +21 -7
  152. package/dist/init-journal.js.map +1 -1
  153. package/dist/init.d.ts +1 -0
  154. package/dist/init.d.ts.map +1 -1
  155. package/dist/init.js +55 -5
  156. package/dist/init.js.map +1 -1
  157. package/dist/lark-cli-error.d.ts +13 -2
  158. package/dist/lark-cli-error.d.ts.map +1 -1
  159. package/dist/lark-cli-error.js +54 -13
  160. package/dist/lark-cli-error.js.map +1 -1
  161. package/dist/lark-cli-passthrough.d.ts +9 -0
  162. package/dist/lark-cli-passthrough.d.ts.map +1 -0
  163. package/dist/lark-cli-passthrough.js +101 -0
  164. package/dist/lark-cli-passthrough.js.map +1 -0
  165. package/dist/lark-cli.d.ts +5 -2
  166. package/dist/lark-cli.d.ts.map +1 -1
  167. package/dist/lark-cli.js +96 -29
  168. package/dist/lark-cli.js.map +1 -1
  169. package/dist/legacy-function-input-renderer.d.ts +6 -0
  170. package/dist/legacy-function-input-renderer.d.ts.map +1 -0
  171. package/dist/legacy-function-input-renderer.js +175 -0
  172. package/dist/legacy-function-input-renderer.js.map +1 -0
  173. package/dist/link-guard-check.d.ts +12 -0
  174. package/dist/link-guard-check.d.ts.map +1 -0
  175. package/dist/link-guard-check.js +138 -0
  176. package/dist/link-guard-check.js.map +1 -0
  177. package/dist/managed-agent-docs.d.ts +14 -0
  178. package/dist/managed-agent-docs.d.ts.map +1 -0
  179. package/dist/managed-agent-docs.js +172 -0
  180. package/dist/managed-agent-docs.js.map +1 -0
  181. package/dist/mutation-schema.d.ts +6 -0
  182. package/dist/mutation-schema.d.ts.map +1 -1
  183. package/dist/mutation-schema.js +6 -0
  184. package/dist/mutation-schema.js.map +1 -1
  185. package/dist/mutation.d.ts +4 -1
  186. package/dist/mutation.d.ts.map +1 -1
  187. package/dist/mutation.js +17 -2
  188. package/dist/mutation.js.map +1 -1
  189. package/dist/npm.d.ts +1 -0
  190. package/dist/npm.d.ts.map +1 -1
  191. package/dist/npm.js +28 -0
  192. package/dist/npm.js.map +1 -1
  193. package/dist/preview-receipt.d.ts +0 -2
  194. package/dist/preview-receipt.d.ts.map +1 -1
  195. package/dist/preview-receipt.js +0 -28
  196. package/dist/preview-receipt.js.map +1 -1
  197. package/dist/process.d.ts +1 -0
  198. package/dist/process.d.ts.map +1 -1
  199. package/dist/process.js +25 -0
  200. package/dist/process.js.map +1 -1
  201. package/dist/program.d.ts.map +1 -1
  202. package/dist/program.js +239 -26
  203. package/dist/program.js.map +1 -1
  204. package/dist/project-build.d.ts +2 -1
  205. package/dist/project-build.d.ts.map +1 -1
  206. package/dist/project-build.js +53 -16
  207. package/dist/project-build.js.map +1 -1
  208. package/dist/project-capabilities.d.ts +8 -0
  209. package/dist/project-capabilities.d.ts.map +1 -0
  210. package/dist/project-capabilities.js +47 -0
  211. package/dist/project-capabilities.js.map +1 -0
  212. package/dist/project-context.d.ts +66 -0
  213. package/dist/project-context.d.ts.map +1 -1
  214. package/dist/project-context.js +68 -6
  215. package/dist/project-context.js.map +1 -1
  216. package/dist/project-layout.d.ts +11 -0
  217. package/dist/project-layout.d.ts.map +1 -1
  218. package/dist/project-layout.js +63 -1
  219. package/dist/project-layout.js.map +1 -1
  220. package/dist/public-exports.d.ts +5 -0
  221. package/dist/public-exports.d.ts.map +1 -0
  222. package/dist/public-exports.js +76 -0
  223. package/dist/public-exports.js.map +1 -0
  224. package/dist/public-sql-error.d.ts +3 -1
  225. package/dist/public-sql-error.d.ts.map +1 -1
  226. package/dist/public-sql-error.js +5 -2
  227. package/dist/public-sql-error.js.map +1 -1
  228. package/dist/pull.d.ts +1 -0
  229. package/dist/pull.d.ts.map +1 -1
  230. package/dist/pull.js +103 -20
  231. package/dist/pull.js.map +1 -1
  232. package/dist/sdk-codegen.d.ts +16 -0
  233. package/dist/sdk-codegen.d.ts.map +1 -0
  234. package/dist/sdk-codegen.js +181 -0
  235. package/dist/sdk-codegen.js.map +1 -0
  236. package/dist/sdk-install.d.ts +4 -0
  237. package/dist/sdk-install.d.ts.map +1 -0
  238. package/dist/sdk-install.js +33 -0
  239. package/dist/sdk-install.js.map +1 -0
  240. package/dist/skill-frontmatter.d.ts +5 -0
  241. package/dist/skill-frontmatter.d.ts.map +1 -0
  242. package/dist/skill-frontmatter.js +28 -0
  243. package/dist/skill-frontmatter.js.map +1 -0
  244. package/dist/skill.d.ts +2 -1
  245. package/dist/skill.d.ts.map +1 -1
  246. package/dist/skill.js +18 -12
  247. package/dist/skill.js.map +1 -1
  248. package/dist/source-format.d.ts +10 -0
  249. package/dist/source-format.d.ts.map +1 -0
  250. package/dist/source-format.js +49 -0
  251. package/dist/source-format.js.map +1 -0
  252. package/dist/types.d.ts +6 -0
  253. package/dist/types.d.ts.map +1 -1
  254. package/dist/unified-functions.d.ts +22 -0
  255. package/dist/unified-functions.d.ts.map +1 -0
  256. package/dist/unified-functions.js +114 -0
  257. package/dist/unified-functions.js.map +1 -0
  258. package/dist/updates.d.ts +13 -1
  259. package/dist/updates.d.ts.map +1 -1
  260. package/dist/updates.js +65 -29
  261. package/dist/updates.js.map +1 -1
  262. package/dist/workspace-fingerprint.d.ts.map +1 -1
  263. package/dist/workspace-fingerprint.js +5 -0
  264. package/dist/workspace-fingerprint.js.map +1 -1
  265. package/package.json +17 -5
  266. package/skills/lark-base-database/SKILL.md +21 -55
  267. package/skills/lark-base-database/references/agent-tool-design.md +181 -0
  268. package/skills/lark-base-database/references/agent-tools.md +101 -0
  269. package/skills/lark-base-database/references/ai-function.md +80 -186
  270. package/skills/lark-base-database/references/database-function-limitations.md +12 -4
  271. package/skills/lark-base-database/references/database-function.md +49 -21
  272. package/skills/lark-base-database/references/development.md +81 -109
  273. package/skills/lark-base-database/references/environment-variables.md +2 -2
  274. package/skills/lark-base-database/references/faas.md +43 -16
  275. package/skills/lark-base-database/references/file-transfer.md +10 -33
  276. package/skills/lark-base-database/references/frontend-design-guide.md +1 -1
  277. package/skills/lark-base-database/references/legacy-ai-function.md +120 -0
  278. package/skills/lark-base-database/references/legacy-development.md +156 -0
  279. package/skills/lark-base-database/references/legacy-file-transfer.md +68 -0
  280. package/skills/lark-base-database/references/mutations.md +38 -29
  281. package/skills/lark-base-database/references/notifications.md +1 -1
  282. package/skills/lark-base-database/references/permission-design.md +11 -5
  283. package/skills/lark-base-database/references/release.md +22 -7
  284. package/skills/lark-base-database/references/verification.md +55 -16
  285. package/skills/lark-base-database/references/workspace-migration.md +86 -0
  286. package/skills/lark-base-database/references/workspace.md +55 -44
  287. package/templates/database-starter/README.md +2 -0
  288. package/templates/database-starter/database-functions/README.md +2 -2
  289. package/templates/database-starter/mutations/README.md +2 -2
  290. package/templates/database-starter/page/README.md +5 -4
  291. package/templates/database-starter/page/src/examples/ai-function/TextStreamOperation.tsx +6 -6
  292. package/templates/database-starter/page/src/lib/attachment-image.tsx +19 -5
  293. package/templates/database-starter/page/src/lib/database-runtime-attachment.test.ts +124 -5
  294. package/templates/database-starter/page/src/lib/database-runtime.test.ts +2 -2
  295. package/templates/database-starter/page/src/lib/database-runtime.ts +77 -13
  296. package/templates/database-starter/server-functions/scripts/run-tsc.mjs +3 -2
  297. package/templates/database-starter-v2/README.md +25 -0
  298. package/templates/database-starter-v2/base-app.config.ts +10 -0
  299. package/templates/database-starter-v2/database-functions/README.md +1 -0
  300. package/templates/database-starter-v2/gitignore +6 -0
  301. package/templates/database-starter-v2/mutations/README.md +1 -0
  302. package/templates/database-starter-v2/package-lock.json +2239 -0
  303. package/templates/database-starter-v2/package.json +18 -0
  304. package/templates/database-starter-v2/page/index.html +2 -0
  305. package/templates/database-starter-v2/page/package.json +25 -0
  306. package/templates/database-starter-v2/page/src/App.tsx +12 -0
  307. package/templates/database-starter-v2/page/src/generated/README.md +1 -0
  308. package/templates/database-starter-v2/page/src/index.css +1 -0
  309. package/templates/database-starter-v2/page/src/lib/date-time.ts +61 -0
  310. package/templates/database-starter-v2/page/src/main.tsx +6 -0
  311. package/templates/database-starter-v2/page/tsconfig.json +19 -0
  312. package/templates/database-starter-v2/page/vite.config.ts +3 -0
  313. package/templates/database-starter-v2/prettierignore +3 -0
  314. package/templates/database-starter-v2/server/functions/README.md +1 -0
  315. package/templates/database-starter-v2/server/functions/hello/contract.ts +5 -0
  316. package/templates/database-starter-v2/server/functions/hello/index.ts +7 -0
  317. package/templates/database-starter-v2/server/functions/hello/meta.json +1 -0
  318. package/templates/database-starter-v2/server/generated/runtime-profile.ts +5 -0
  319. package/templates/database-starter-v2/server/package.json +17 -0
  320. package/templates/database-starter-v2/server/tsconfig.json +14 -0
@@ -1,19 +1,19 @@
1
1
  # Base Database AI Function
2
2
 
3
+ 本参考中的 SDK 页面 API 仅适用于工程已安装 `@lark-base-open/base-database-app-sdk` 的情况;未安装时不得按 SDK 示例新增依赖或替换原实现,继续使用[冻结的classic AI Function 参考](legacy-ai-function.md)。
4
+
3
5
  本文说明如何在 Page 中配置和调用 AI Function。AI Function 是随应用版本发布的 AI 能力:文本可以按页面需要使用流式或一次性结果;图像和视频生成始终先创建任务、再轮询结果。页面只按 `functionKey` 调用平台 AI 能力;Base 数据读取仍使用 Database Function,写入按[Mutation 与 FaaS 分工](mutations.md#写入方式选择)选择。
4
6
 
5
7
  AI Function 是按需可选能力:需求不涉及模型或 AI 时不要创建 `ai/`,也不需要执行本文任何命令或开通 AI 能力;普通 `deploy` 在空 `ai/` 时自动跳过 AI Function 同步。只有需求包含 AI 对话、生成、分类、总结、文生图、文生视频或“查数据后让模型分析”时才读取本文。
6
8
 
7
- 每个 AI Function 的配置保存在 `ai/<functionKey>/meta.json`。配置决定模型、System Prompt、思考深度、尺寸、时长和变量;页面只传入 `functionKey`、本次的 `variables` 与 `messages` 或 `input`。
8
-
9
- 本文中的 `/sites/`、`siteToken` 和 `Site*` 是 SDK 与平台接口的既有名称;它们都指向当前 Base Database 应用,不需要额外创建或绑定其他产品对象。本地工程中的应用标识始终从 `base-database.jsonc` 的 `appToken` 读取。
9
+ 每个 AI Function 的配置保存在 `ai/<functionKey>/meta.json`。配置决定模型、System Prompt、思考深度、尺寸、时长和变量;页面只传入 `functionKey`、本次的 `params` 与 `messages` 或 `input`。
10
10
 
11
11
  ## 阅读路径
12
12
 
13
13
  1. 第一次实现时先执行[零背景最短闭环](#零背景最短闭环)。
14
14
  2. 再按需求读取[四类能力与配置契约](#四类能力与配置契约)和[Page 调用方式](#page-调用方式)。
15
15
  3. 修改已有应用时,工程若来自 `pull`,`ai/` 已与远端一致;工程不是 `pull` 得到而 `ai/` 又非空时,按[恢复已有 AI Function](#恢复已有-ai-function)核对。
16
- 4. 最后按[页面实现检查](#页面实现检查)和[区分三种调试成功](#区分三种调试成功)验收。
16
+ 4. 实现按[页面实现检查](#页面实现检查)核对;用户要求运行态验收时,按[AI 验收判定](verification.md#ai-验收判定)执行。
17
17
 
18
18
  ## 零背景最短闭环
19
19
 
@@ -22,7 +22,7 @@ AI Function 是按需可选能力:需求不涉及模型或 AI 时不要创建
22
22
  AI Function 不是 FaaS 代码,也不是页面直接请求模型。一个可运行的 AI 功能必须同时有两部分:
23
23
 
24
24
  ```text
25
- ai/<functionKey>/meta.json # 应用版本中的托管配置
25
+ ai/<functionKey>/meta.json # 应用版本中的配置
26
26
  page/... # 使用同一个 functionKey 的页面调用代码
27
27
  ```
28
28
 
@@ -31,11 +31,9 @@ page/... # 使用同一个 functionKey 的页面调用
31
31
  1. 修改已有应用且工程不是 `pull` 得到时,先按[恢复已有 AI Function](#恢复已有-ai-function)核对远端配置;新建应用或 `pull` 得到的工程继续下一步。
32
32
  2. 查询 `model_profiles`,按 `capability` 选择真实 `profile_id`;禁止猜测示例 ID。
33
33
  3. 为每个 AI 功能选择唯一、稳定的 `functionKey`,创建严格 JSON 文件 `ai/<functionKey>/meta.json`。`functionKey` 只能含字母、数字、下划线和连字符,长度 1~64;目录名就是调用 key。
34
- 4. 在 Page 中从 `./lib/database-runtime` 导入 helper,使用完全相同的 `functionKey`。调用 `callSiteAIFunction` 时显式传 `capability`;不要依赖 SDK 按 `messages` 或 `input` 猜调用链路。
35
- 5. 对每个本地 AI Function 执行 `ai-functions validate <functionKey>`,只有返回 `is_success: true` 才继续。
36
- 6. 执行一次普通 `deploy`。`deploy` 会构建页面、全量同步 `ai/` 到草稿版本并发布 Preview;正常发布流程不需要先手工执行 `ai-functions sync`。
37
- 7. 执行 `ai-functions list`,核对目标 `functionKey`、`capability_type`、`model_profile_id` 和 `disabled=false`;再在命令返回的 `baseAppUrl` 页面发起一次真实调用。
38
- 8. text/vision 使用显式流式入口时必须看到页面增量与 `onDone`,使用聚合入口时必须得到 `{type:'text'}`;image/video 必须轮询到 `succeeded` 并渲染生成资源。CLI `debug` 只用于辅助定位,不能代替页面链路验收。
34
+ 4. 在 workspace Page 中从 `@lark-base-open/base-database-app-sdk/page` 导入 SDK,使用完全相同的 `functionKey`。调用 `callSiteAIFunction` 时显式传 `capability`;不要依赖 SDK 按 `messages` 或 `input` 猜调用链路。
35
+ 5. 执行一次普通 `deploy`。发布顺序与 skip/Prod 行为按[发布参考](release.md#function-发布顺序与错误边界)执行。
36
+ 6. 运行态未检查时列为未验证;用户要求验收时按[AI 验收判定](verification.md#ai-验收判定)执行,Prod 是否验证按用户诉求决定。
39
37
 
40
38
  最小文本配置与页面调用如下。把 `replace-with-profile-id` 换成 `model_profiles` 返回的真实值。`showAnswer` 是你的页面状态更新函数,需要替换为实际 UI 代码:
41
39
 
@@ -45,10 +43,13 @@ page/... # 使用同一个 functionKey 的页面调用
45
43
  "description": "根据菜单和用餐条件生成推荐",
46
44
  "config": {
47
45
  "capability_type": "text",
48
- "output_mode": "stream",
49
46
  "model_profile_id": "replace-with-profile-id",
50
47
  "system_prompt": "只推荐 {{menu}} 中的菜品。",
51
- "variables": [{ "name": "menu", "type": "string", "required": true }],
48
+ "input_schema": {
49
+ "type": "object",
50
+ "properties": { "menu": { "type": "string" } },
51
+ "required": ["menu"]
52
+ },
52
53
  "text": {
53
54
  "reasoning_depth": "standard",
54
55
  "temperature": 0.7
@@ -58,12 +59,12 @@ page/... # 使用同一个 functionKey 的页面调用
58
59
  ```
59
60
 
60
61
  ```ts
61
- import { callSiteAIFunction } from './lib/database-runtime';
62
+ import { callSiteAIFunction } from '@lark-base-open/base-database-app-sdk/page';
62
63
 
63
64
  const result = await callSiteAIFunction({
64
65
  functionKey: 'recommend_dishes',
65
66
  capability: 'text',
66
- variables: { menu: '番茄炒蛋、宫保鸡丁、青椒肉丝' },
67
+ params: { menu: '番茄炒蛋、宫保鸡丁、青椒肉丝' },
67
68
  messages: [
68
69
  {
69
70
  role: 'user',
@@ -78,22 +79,26 @@ if (result.type === 'text') showAnswer(result.content);
78
79
 
79
80
  AI Function 和 Database Function 一样按应用版本保存:Preview 读取草稿版本,Prod 读取已发布版本。实现 AI 需求时,把每个 AI 功能建模为 `ai/<functionKey>/meta.json`,执行 `deploy` 后由 CLI 将 AI Function 全量同步到当前草稿版本。
80
81
 
81
- 部署前先执行 AI Function 静态校验:`functionKey`、`capability_type`、`output_mode`、`model_profile_id`、变量声明、System Prompt 占位符和能力专属参数都必须符合当前服务端契约。运行态调用进入鉴权、额度、并发和模型调用链路;目标 Function 必须存在,且配置没有设置 `disabled: true`。
82
+ 部署校验的适用条件、顺序和失败边界见[验证方法](verification.md#验证方法)。
83
+
84
+ 配置要求:`functionKey`、`capability_type`、`input_schema`、`model_profile_id`、变量声明、System Prompt 占位符和能力专属参数都必须符合当前服务端契约。运行态调用进入鉴权、额度、并发和模型调用链路;目标 Function 必须存在,且配置没有设置 `disabled: true`。
82
85
 
83
- Preview 发布成功后,必须在页面里触发一次真实 AI Function 调用(`callSiteAIFunction` 或 `invokeSiteAIFunctionStream`):收到结果、`onMessage` 增量或 `onDone` 才能说明 Preview 运行态链路可用。目标 Function 不存在时检查本地声明和 Functions 同步结果;返回 `ai function is disabled` 时检查该 Function 的 `disabled` 配置;模型不可用时重新查询 `model_profiles` 并校验配置;额度、并发或服务错误按实际错误码处理。无法通过应用配置解决时,保留 `requestId` 和脱敏错误摘要,向平台支持反馈。
86
+ 运行态未检查时列为未验证;用户要求验收时按[AI 验收判定](verification.md#ai-验收判定)执行,Prod 是否验证按用户诉求决定。
84
87
 
85
- Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes` 之后。Prod 发布成功后,在生产 `baseAppUrl` 页面再次触发真实 AI Function 调用;收到结果或 `onDone` 才能报告 Prod AI 链路已生效。发布 Prod 前,即使 Preview 已验证成功,也只能报告 Preview AI 可用。
88
+ ### 调用排障
89
+
90
+ 目标 Function 不存在时检查本地声明和 Functions 同步结果;返回 `ai function is disabled` 时检查该 Function 的 `disabled` 配置;模型不可用时重新查询 `model_profiles` 并校验配置;额度、并发或服务错误按实际错误码处理。无法通过应用配置解决时,保留 `requestId` 和脱敏错误摘要,向平台支持反馈。
86
91
 
87
92
  ### 恢复已有 AI Function
88
93
 
89
94
  `pull` 恢复源码制品的同时,会读取远端 AI Function 草稿并写回 `ai/<functionKey>/meta.json`,返回 `aiFunctions.status` 为 `restored` 或 `not_enabled`;当前账号未开通时不落 `ai/`,此后 deploy 不触碰远端 AI Function。`deploy` 在本地 `ai/` 非空时先核对远端已有 key 是否都在本地,缺失则拒绝并列出 key,不会静默删除;`ai-functions sync` 则把本地 `ai/` 当作全集立即全量覆盖(含空集合)。因此只有工程不是 `pull` 得到、且 `ai/` 非空时,才需要手工执行下列恢复:
90
95
 
91
96
  1. `ai-functions list` 取得草稿版本全部远端 key。
92
- 2. 对每个 key 执行 `ai-functions pull <functionKey>`。该命令只把详情打印为 JSON,**不会写文件**;读取返回的 snake_case 字段 `function.name`、`function.description`、`function.config_json`,把 `config_json` 字符串解析成 JSON 对象后还原为 `ai/<functionKey>/meta.json`。`disabled` 位于这个 `config` 对象内,不在 `meta.json` 顶层。
93
- 3. 比较远端 key 集合与本地 `ai/` 目录。需求外的远端 Function 必须保留所有配置值;JSON 缩进和字段顺序不影响语义。本地缺少任一远端 key,或 `config_json` 无法解析时,禁止 `ai-functions sync` 和显式删除操作,`deploy` 前也必须补齐。
97
+ 2. 对每个 key 执行 `ai-functions pull <functionKey>`。该命令读取 preview 详情中的 `spec`,解析配置并写入 `ai/<functionKey>/meta.json`;仅查看时使用 `ai-functions get <functionKey>`。`disabled` 位于这个 `config` 对象内,不在 `meta.json` 顶层。
98
+ 3. 比较远端 key 集合与本地 `ai/` 目录。需求外的远端 Function 必须保留所有配置值;JSON 缩进和字段顺序不影响语义。本地缺少任一远端 key,或 `spec` 缺失或无法解析时,禁止 `ai-functions sync` 和显式删除操作,`deploy` 前也必须补齐。
94
99
  4. 只有用户明确授权删除具体 Function 后,才能让该 key 从本地全集缺失并执行全量同步。
95
100
 
96
- 空 `ai/` 在 `deploy` 里是“本次不修改 AI Function”:CLI 会返回 `{ skipped: true, reason: 'no_local_ai_functions' }` 并跳过 AI Function 同步;仅 Page/Database Function/FaaS 会随本次 deploy 发布。本地已存在 `ai/` 声明但本次发布要完全不动 AI Function 时,使用显式参数 `deploy --skip-ai-functions`(生产发布追加在 `--production --yes` 之后),返回中带 `aiFunctionsSkipped: true`,交付报告必须说明 AI Function 未同步且未验证。`ai-functions sync` 与 deploy 不同,只要执行就是立即写远端草稿的全量覆盖操作,空集合会把远端 AI Function **全部删除**;因此仅在用户明确授权删除或有强规划时使用。常规发布不必单独执行 `ai-functions sync`。
101
+ deploy 的 AI 同步、skip 行为、Prod 提升与显式 sync 的区别统一见[发布顺序与错误边界](release.md#function-发布顺序与错误边界)。
97
102
 
98
103
  ## 选择 AI Function
99
104
 
@@ -102,10 +107,10 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
102
107
  | 业务动作 | 数据路径 | 页面职责 |
103
108
  | -------------- | -------------------------- | ------------------------------------------------------------------- |
104
109
  | 查询 | Page → Database Function | 固定 Function ID,校验查询结果 |
105
- | 写入 | Page → FaaS → Base Records | 固定 Function ID,由 FaaS 校验并写入 |
106
- | AI 对话 / 生成 | Page → AI Function | 传 functionKey + variables + messages/input,消费结果,维护会话状态 |
110
+ | 写入 | Page → Mutation 或 FaaS | 按[写入方式选择](mutations.md#写入方式选择):普通单表写入用 Mutation,需要业务校验或编排时用 FaaS |
111
+ | AI 对话 / 生成 | Page → AI Function | 传 functionKey + params + messages/input,消费结果,维护会话状态 |
107
112
 
108
- 需要先查 Base 再问模型时,先完成 Database Function 查询,在 Page 内把经过裁剪的结果放入 `messages` 或 `variables`,再按 `functionKey` 调用 AI Function。需要把 AI 结果写回 Base 时,再调用对应 FaaS。
113
+ 需要先查 Base 再问模型时,先完成 Database Function 查询,在 Page 内把经过裁剪的结果放入 `messages` 或 `params`,再按 `functionKey` 调用 AI Function。需要把 AI 结果写回 Base 时,按[写入方式选择](mutations.md#写入方式选择)选用 Mutation 或 FaaS。
109
114
 
110
115
  典型路由:
111
116
 
@@ -120,12 +125,12 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
120
125
 
121
126
  一个 AI Function 只承载一种能力,由 `capability_type` 决定用哪条运行链路与哪组配置字段:
122
127
 
123
- | capability_type | output_mode | 运行链路 | 专属配置字段 |
124
- | --------------- | ----------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
125
- | `text` | `stream` / `sync` | 通过 SDK 获取文本流或完整文本 | `text.reasoning_depth`(off/light/standard/deep) / `text.temperature` |
126
- | `vision` | `stream` / `sync` | 多模态理解;输入受下文 SDK 类型限制 | 同 text,且模型 Profile 必须声明本次使用的 image / video / audio / file 输入 |
127
- | `image` | `sync` | 创建图片任务并轮询结果 | `image.size` / `image.response_format`(url/b64_json) / `image.sequential_image_generation`(auto/disabled) / `image.max_images` / `image.watermark` |
128
- | `video` | `async` | 创建视频任务并轮询结果 | `video.resolution` / `video.ratio` / `video.duration` / `video.watermark` / `video.seed` |
128
+ | capability_type | mode | 运行链路 | 专属配置字段 |
129
+ | --------------- | -------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
130
+ | `text` | `stream` | 通过 SDK 获取文本流或完整文本 | `text.reasoning_depth`(off/light/standard/deep) / `text.temperature` |
131
+ | `vision` | `stream` | 多模态理解;输入受下文 SDK 类型限制 | 同 text,且模型 Profile 必须声明本次使用的 image / video / audio / file 输入 |
132
+ | `image` | `task` | 创建图片任务并轮询结果 | `image.size` / `image.response_format`(url/b64_json) / `image.sequential_image_generation`(auto/disabled) / `image.max_images` / `image.watermark` |
133
+ | `video` | `task` | 创建视频任务并轮询结果 | `video.resolution` / `video.ratio` / `video.duration` / `video.watermark` / `video.seed` |
129
134
 
130
135
  `AIFunctionConfig` 结构(落 `ai/<functionKey>/meta.json` 的 `config` 字段):
131
136
 
@@ -137,10 +142,13 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
137
142
  "description": "根据口味/预算/人数和菜单推荐菜品",
138
143
  "config": {
139
144
  "capability_type": "text",
140
- "output_mode": "stream",
141
145
  "model_profile_id": "replace-with-text-profile-id",
142
146
  "system_prompt": "你是点餐助手,只推荐 {{menu}} 中的菜品。",
143
- "variables": [{ "name": "menu", "type": "string", "required": true }],
147
+ "input_schema": {
148
+ "type": "object",
149
+ "properties": { "menu": { "type": "string" } },
150
+ "required": ["menu"]
151
+ },
144
152
  "text": {
145
153
  "reasoning_depth": "standard",
146
154
  "temperature": 0.7
@@ -149,13 +157,13 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
149
157
  }
150
158
  ```
151
159
 
152
- 静态校验(保存/发布前执行,按能力分支):`capability_type` 合法;`model_profile_id` 来自可用模型列表且能力匹配(文本模型不能配给文生图);`system_prompt` 里的 `{{var}}` 都在 `variables` 声明;`variables` 名称唯一、类型合法、required 项不带默认值;`output_mode` 与 `capability_type` 相容;文本 `temperature` 必须在 0~2 内;vision 要求 profile 至少声明 image / video / audio / file 中一种媒体输入,调用时每个 content part 还必须命中该 profile 的 `input_modalities`;image `max_images` 与 video `duration` 不超平台上限,video `seed` 必须为 -1 或更大。
160
+ 配置合法性要求(由 deploy 校验,按能力分支):`capability_type` 合法;`model_profile_id` 来自可用模型列表且能力匹配(文本模型不能配给文生图);`system_prompt` 里的 `{{var}}` 都在 `input_schema.properties` 声明;`input_schema` 属性类型合法,required 列表引用已声明属性;文本 `temperature` 必须在 0~2 内;vision 要求 profile 至少声明 image / video / audio / file 中一种媒体输入,调用时每个 content part 还必须命中该 profile 的 `input_modalities`;image `max_images` 与 video `duration` 不超平台上限,video `seed` 必须为 -1 或更大。
153
161
 
154
- 变量类型只能是 `string`、`number`、`boolean`、`object`。调用时 `variables` 的运行时类型必须匹配声明,required 变量不可缺失;`object` 同时接受对象和数组。`system_prompt` 适用于四类能力:text/vision 作为 system message,image/video 作为基础提示词;媒体调用的 `input.prompt` 会追加到这个基础提示词。
162
+ `input_schema` 是描述 `params` 的 object JSON Schema,支持 type、properties、required、additionalProperties、items、prefixItems、enum、数值/长度限制、oneOf、anyOf、pattern 和 default。pattern 使用 RE2;不支持 $ref 或外部加载。作者 Schema 最大 32 KiB、256 个节点、16 层。default 使用真实 JSON 值;有有效 default 的顶层属性无需 required。缺失属性由执行器补默认值,显式 null 只有 Schema 允许才合法,且不会触发默认值。`system_prompt` 适用于四类能力;媒体 `input.prompt` 追加到基础提示词。
155
163
 
156
164
  `disabled` 是 `config.disabled`,省略或 `false` 表示可调用,`true` 表示保留配置但停止调用。`video.seed=-1` 表示随机种子。
157
165
 
158
- 图片生成和文生视频的最小配置分别如下。这里的 `output_mode` 是服务端能力配置约束,不代表浏览器可以同步得到最终媒体;Page 对 image/video 都必须创建任务并轮询。
166
+ 图片生成和文生视频的最小配置分别如下。Page 对 image/video 创建任务并轮询,mode 由服务端按能力推导。
159
167
 
160
168
  ```json
161
169
  {
@@ -163,7 +171,7 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
163
171
  "description": "根据商品描述生成海报",
164
172
  "config": {
165
173
  "capability_type": "image",
166
- "output_mode": "sync",
174
+ "input_schema": { "type": "object", "properties": {} },
167
175
  "model_profile_id": "replace-with-image-profile-id",
168
176
  "system_prompt": "生成适合商品展示的图片。",
169
177
  "image": {
@@ -183,7 +191,7 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
183
191
  "description": "根据脚本生成短视频",
184
192
  "config": {
185
193
  "capability_type": "video",
186
- "output_mode": "async",
194
+ "input_schema": { "type": "object", "properties": {} },
187
195
  "model_profile_id": "replace-with-video-profile-id",
188
196
  "system_prompt": "生成简洁、自然的宣传短视频。",
189
197
  "video": {
@@ -197,24 +205,13 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
197
205
  }
198
206
  ```
199
207
 
200
- 示例里的尺寸、时长和其他参数只是结构演示,必须根据 `model_profiles` 返回的能力与业务要求调整,再用 `ai-functions validate` 让服务端做最终校验。
201
-
202
- 当前图片模型按 Seedream 5.0 lite 契约校验 `image.size`:可以使用分辨率档位 `2K`、`3K`、`4K`,也可以使用 `WIDTHxHEIGHT`。像素尺寸必须同时满足总像素数在 3,686,400~16,777,216 之间、宽高比在 1:16~16:1 之间;默认使用 `2048x2048`。服务端不会把非法尺寸自动放大或缩小,`ai-functions validate` 和运行时调用都会直接拒绝。
203
-
204
- `image.sequential_image_generation` 决定单图或组图:
208
+ 示例里的尺寸、时长和其他参数只是结构演示,必须根据 `model_profiles` 返回的能力与业务要求调整,由 `deploy` 完成服务端校验,编辑期可选 `ai-functions validate` 自检。
205
209
 
206
- | 模式 | `sequential_image_generation` | `input.image` | 输出上限 |
207
- | ---------- | ----------------------------- | --------------------- | ----------------------------------- |
208
- | 文生单图 | `disabled` | 省略 | 1 张 |
209
- | 单图生单图 | `disabled` | 单个字符串或 1 项数组 | 1 张 |
210
- | 多图生单图 | `disabled` | 2~14 项数组 | 1 张 |
211
- | 文生组图 | `auto` | 省略 | 最多 15 张 |
212
- | 单图生组图 | `auto` | 单个字符串或 1 项数组 | 最多 14 张 |
213
- | 多图生组图 | `auto` | 2~14 项数组 | 参考图数与最终生成图数之和不超过 15 |
210
+ 图片尺寸、像素与数量上限按实际选择的 model_profiles 和服务端校验反馈确定,不将某一模型版本的限制推广到其他模型。示例参数只演示结构;缺少范围说明时先用编辑期 `ai-functions validate` 获取明确校验反馈,修正参数后再发布,不靠反复模型调用试探限制。
214
211
 
215
- `image.max_images` 为 1~15,只在 `auto` 下生效;`0` 或省略表示使用平台默认值。服务端会按参考图数量和模型 Profile 上限进一步收紧。
212
+ `image.sequential_image_generation` 选择单图(disabled)或组图(auto);参考图使用 `input.image`,输入格式按下表。`image.max_images` 的可选范围、参考图数量与输出数量之间的约束以当前模型和服务端校验反馈为准,不从示例中的数量推断所有模型上限。
216
213
 
217
- 参考图不是 AI Function 的固定配置,属于每次调用输入。Channel SDK 导出的 `SiteAIImageGenerationInput` 定义了公开类型;使用 `input.image` 传一条可访问 URL / `data:image/...;base64,...` 字符串,或传包含 1~14 个此类字符串的数组。
214
+ 参考图属于每次调用输入,不是 AI Function 固定配置;使用可访问 URL / data:image/...;base64,... 字符串或非空字符串数组。接入类型以 SDK 的 SiteAIImageGenerationInput 为准。
218
215
 
219
216
  ### 参考图来源与传参
220
217
 
@@ -225,7 +222,7 @@ Prod 验证只能发生在用户明确确认并完成 `deploy --production --yes
225
222
  | 公网可访问图片 | HTTPS URL |
226
223
  | 浏览器本地 `File` | 用 `FileReader.readAsDataURL` 转成完整的 `data:image/...;base64,...`;只用于满足请求体限制的小图 |
227
224
  | Base 附件 | 用 `fetchAttachmentDownloadUrl(context, ref)` 换取短时效 URL |
228
- | 多张参考图 | 由上述字符串组成的 1~14 项数组 |
225
+ | 多张参考图 | 由上述字符串组成的非空数组,数量先按服务端契约校验 |
229
226
 
230
227
  `file_token` 只是附件资源标识,不能直接传给模型;浏览器 `blob:` URL 也不能使用,因为它只在当前页面上下文有效。不要手工拼 Box 下载地址。Base 附件场景同时读取[文件传输](file-transfer.md#展示与下载),使用真实的 `tableId`、`fieldId`、`recordId` 和 `fileToken` 证明附件位置:
231
228
 
@@ -234,7 +231,7 @@ import {
234
231
  createSiteAIFunctionTask,
235
232
  fetchAttachmentDownloadUrl,
236
233
  resolveDatabaseContext,
237
- } from './lib/database-runtime';
234
+ } from '@lark-base-open/base-database-app-sdk/page';
238
235
 
239
236
  const context = await resolveDatabaseContext();
240
237
  const sourceImageUrl = await fetchAttachmentDownloadUrl(context, {
@@ -282,33 +279,36 @@ base-database-cli lark-cli -- \
282
279
 
283
280
  ## CLI 建模与调试
284
281
 
285
- AI Function 在本地以声明式目录维护:每个 `ai/<functionKey>/meta.json` 声明一个 AI Function,`deploy` 时随发布走**全量覆盖**同步(新增、修改和删除均以本地全集为准)。
282
+ AI Function 在本地以声明式目录维护:每个 `ai/<functionKey>/meta.json` 声明一个 AI Function,`deploy` 时随发布走**全量覆盖**同步(适用条件与发布顺序见[发布参考](release.md#function-发布顺序与错误边界))。
286
283
 
287
284
  ```bash
288
285
  # 列出应用中的 AI Function
289
286
  base-database-cli ai-functions list
290
287
 
291
- # 读取单个配置用于本地编辑 / diff
288
+ # 查看草稿配置;--env prod 仅显示已发布公开契约
289
+ base-database-cli ai-functions get <functionKey>
290
+
291
+ # 恢复草稿配置到本地文件
292
292
  base-database-cli ai-functions pull <functionKey>
293
293
 
294
294
  # 全量覆盖同步本地 ai/ 声明
295
295
  base-database-cli ai-functions sync
296
296
 
297
- # 保存/发布前静态校验单个 AI Function
297
+ # 编辑期可选:静态校验单个 AI Function
298
298
  base-database-cli ai-functions validate <functionKey>
299
299
 
300
300
  # 调试 text/vision:聚合返回完整文本与 firstTokenMs
301
301
  base-database-cli ai-functions debug <functionKey> \
302
- --env preview --messages '[{"role":"user","content":[{"type":"text","text":"概括缺货风险"}]}]' --variables '{"menu":"..."}'
302
+ --env preview --messages '[{"role":"user","content":[{"type":"text","text":"概括缺货风险"}]}]' --params '{"menu":"..."}'
303
303
 
304
- # 调试 image/video:两者都提交媒体任务并返回 taskId;image 可带一张或多张参考图
304
+ # 调试 image/video:两者都提交媒体任务并返回 task_id;image 可带一张或多张参考图
305
305
  base-database-cli ai-functions debug <functionKey> \
306
306
  --env preview \
307
307
  --input '{"prompt":"保持角色一致,生成一组新品海报","image":["https://example.com/ref-1.png","https://example.com/ref-2.png"]}' \
308
- --variables '{}'
308
+ --params '{}'
309
309
 
310
310
  # 查询文生图 / 文生视频任务
311
- base-database-cli ai-functions task <functionKey> <taskId> --env preview
311
+ base-database-cli ai-functions task <functionKey> <task_id> --env preview
312
312
 
313
313
  # 查看用量汇总(总量 + 按日期分布 + 按 Function/能力/错误码分维度)
314
314
  base-database-cli ai-functions usage \
@@ -316,119 +316,25 @@ base-database-cli ai-functions usage \
316
316
  --model <profileId> --capability-type text
317
317
  ```
318
318
 
319
- CLI 调试对 text/vision 返回聚合文本,对 image/video 返回 taskId;随后使用 `ai-functions task` 查询任务。验证页面逐帧显示时,使用 `invokeSiteAIFunctionStream` 并观察回调。
319
+ CLI 调试对 text/vision 返回聚合文本,对 image/video 返回 task_id;随后使用 `ai-functions task` 查询任务。验证页面逐帧显示时,使用 `invokeSiteAIFunctionStream` 并观察回调。
320
320
 
321
321
  应用所有者可用 `ai-functions usage` 查询用量汇总。对应接口 `GET /open-apis/base/v3/sites/:token/ai_functions/usage/summary` 返回总量、`by_date`(Key 为 `YYYYMMDD`)、`by_function`、`by_capability`、`error_dist`。`from/to` 为 `YYYYMMDD` 区间(含),不传则聚合全部历史。`--model` 接受 `model_profiles` 返回的 `profiles[].profile_id`。
322
322
 
323
- image / video 创建任务后返回 `taskId` 和状态。使用同一应用、Function 与环境轮询,处理 `queued`、`running`、`succeeded`、`failed`、`cancelled`,仅在成功终态读取生成资源。平台会在应用绑定的 Base 中维护任务记录;页面通过任务接口读状态,不直接修改这些记录。
324
-
325
- `taskId` 是不透明的任务标识,原样传给查询接口;不要解析它或用 Base record ID 替代。创建失败时报告错误,不凭空构造 taskId。
326
-
327
- ## Page 调用方式
328
-
329
- 新建工程已包含本节所需的 Page runtime;实现 AI Function 时不需要安装、替换或选择 SDK。修改已有工程时,除非用户明确要求升级页面依赖,否则保留已有 `package.json` 与 lockfile,不因新增 AI Function 自行改依赖。
330
-
331
- starter 的 `page/src/lib/database-runtime.ts` 导出 key 化调用入口。调用 `callSiteAIFunction` 时显式提供与配置一致的 `capability`:text/vision 走流式聚合,image/video 走任务提交。页面统一使用这些 helper,由 SDK 处理流式和媒体任务通信。Page 不得自行调用全局 `fetch` 绕过 SDK,也不得在代理失败时降级直连。
332
-
333
- | 能力 | Page 本次输入 | 推荐入口 | 完成条件 |
334
- | ------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------- |
335
- | text | `messages` + 可选 `variables` | `invokeSiteAIFunctionStream` 需要逐帧 UI;`callSiteAIFunction` 需额外传 `capability:'text'` 取得聚合文本 | `onDone` 或 `{type:'text'}` |
336
- | vision | 多模态 `messages` + 可选 `variables` | 与 text 相同;统一入口传 `capability:'vision'`,输入类型必须属于模型 Profile 的 `input_modalities` | `onDone` 或 `{type:'text'}` |
337
- | image | `capability:'image'` + `input` + 可选 `variables` | `createSiteAIFunctionTask`,也可用统一入口创建任务 | `succeeded` 且读取 `imageAssets` |
338
- | video | `capability:'video'` + `input` + 可选 `variables` | `createSiteAIFunctionTask`,也可用统一入口创建任务 | `succeeded` 且读取 `videoAsset` |
339
-
340
- ```ts
341
- import {
342
- callSiteAIFunction,
343
- invokeSiteAIFunctionStream,
344
- createSiteAIFunctionTask,
345
- } from './lib/database-runtime';
346
-
347
- // 本例调用 text,因此只处理 text 结果。
348
- const result = await callSiteAIFunction({
349
- functionKey: 'recommend_dishes',
350
- capability: 'text',
351
- variables: { menu: '...' },
352
- messages: [
353
- {
354
- role: 'user',
355
- content: [{ type: 'text', text: '按预算 100 元推荐两道菜' }],
356
- },
357
- ],
358
- });
359
- if (result.type === 'text') {
360
- showAnswer(result.content); // 替换为实际的页面状态更新
361
- }
362
-
363
- // 显式流式(text/vision):逐帧增量
364
- const stream = invokeSiteAIFunctionStream({
365
- functionKey: 'recommend_dishes',
366
- messages: [
367
- { role: 'user', content: [{ type: 'text', text: '概括今天的缺货风险' }] },
368
- ],
369
- variables: { menu: '...' },
370
- });
371
- // reasoning 模型会先持续下发 delta.reasoningContent,再下发 delta.content。
372
- // 只消费 content 会让「思考过程」区域一直为空,看起来像没有流式输出,必须两者都消费。
373
- stream.onMessage((delta) => {
374
- if (delta.reasoningContent) appendReasoning(delta.reasoningContent);
375
- if (delta.content) appendAnswer(delta.content);
376
- });
377
- stream.onError((error) => showError(error.message));
378
- stream.onDone(() => markAnswerComplete());
379
- // 只在用户取消、组件卸载或新请求替代旧请求时调用;不要在注册回调后立即销毁。
380
- const cancel = () => stream.destroy();
381
- // appendReasoning、appendAnswer、showError、markAnswerComplete 都是页面自己的状态更新函数。
382
-
383
- // 多模态理解仍使用 capability:'vision'。content part 统一为 text、image、video、audio、file;
384
- // 实际可用组合以 model_profiles 返回的 input_modalities 为准。
385
- const multimodal = invokeSiteAIFunctionStream({
386
- functionKey: 'understand_assets',
387
- messages: [
388
- {
389
- role: 'user',
390
- content: [
391
- { type: 'text', text: '总结这些素材' },
392
- { type: 'image', url: imageUrl, detail: 'high' },
393
- { type: 'video', url: videoUrl, fps: 2 },
394
- { type: 'audio', url: audioUrl },
395
- { type: 'file', url: pdfUrl, filename: 'report.pdf' },
396
- ],
397
- },
398
- ],
399
- });
400
-
401
- // 图片生成 / 文生视频:提交后必须轮询。
402
- // image 完整可复用实现见 starter 的 `ImageTaskOperation.tsx`;video 参考 `ai-media-panel.tsx` 中的 `AIVideoPanel`。
403
- const task = await createSiteAIFunctionTask({
404
- functionKey: 'make_promo',
405
- capability: 'image',
406
- input: {
407
- prompt: '保持角色一致,生成一组新品海报',
408
- image: ['https://example.com/ref-1.png', 'https://example.com/ref-2.png'],
409
- },
410
- });
411
- ```
412
-
413
- 公开协议不暴露供应商字段,五类 part 固定为 `{type:'text', text}`、`{type:'image', url, detail?}`、`{type:'video', url, fps?}`、`{type:'audio', url}`、`{type:'file', url, filename?}`。四类非文本输入统一使用 `url`,不支持 `file_id`;本地文件先编码成 data URL。后端 Ark adapter 会把 image/video 转成 `image_url`/`video_url` 对象,把音频 URL 转成 `input_audio.url + format`(format 按链接后缀推断),把音频 data URL 拆成 `input_audio.data + format`,把文件映射为 `file.file_url` 或 `file.file_data`。
414
-
415
- 文件理解当前只支持 PDF,单文件不得超过 50 MB。公网 URL 必须是 HTTP(S),路径以 `.pdf` 结尾;若签名 URL 的路径没有后缀,必须补 `filename:'*.pdf'`。本地 PDF 使用 `data:application/pdf;base64,...`,并且必须带 `filename:'*.pdf'`。`filename` 只用于校验和 data URL 场景的 Ark 请求;URL 场景不会把它透传给供应商。Chat 文件理解返回仍是文本流,不新增文件输出类型。
323
+ ## 任务受理与完成
416
324
 
417
- `reasoningContent` 是模型思考过程增量,`content` 是最终回答增量:两者分区渲染,思考过程放较小的过程区域,最终回答进正式结果区。**要从结果里解析结构化列表时,基于最终 answer(`content` 累积值)解析,不要基于 reasoning 内容解析。** 业务页面只处理 SDK 返回的 `{ content?, reasoningContent?, raw }`,无需自行解析原始流式传输格式。
325
+ image / video 创建任务后返回 `task_id` 和状态。使用同一应用、Function 与环境轮询,处理 `queued`、`running`、`succeeded`、`failed`、`cancelled`,仅在成功终态读取生成资源。平台会在应用绑定的 Base 中维护任务记录;页面通过任务接口读状态,不直接修改这些记录。
418
326
 
419
- `SiteAIFunctionResult` 是可判别联合(用 `switch(result.type)` 判别,避免字符串解析媒体结果):`{ type:'text', content }` / `{ type:'image_task', taskId, status }` / `{ type:'video_task', taskId, status }`。Ark Chat 的 `choices.message.content` / `choices.delta.content` 是文本,因此 vision 表示多模态输入理解、文本输出;它不会在 Chat 响应中生成图片、视频或音频。需要媒体输出时必须显式调用 image/video AI Function 的任务接口,任务成功后分别从 `imageAssets` / `videoAsset` 读取结果。所有响应携带 `requestId`,用于监控与排查。
327
+ `task_id` 是不透明的任务标识,原样传给查询接口;不要解析它或用 Base record ID 替代。创建失败时报告错误,不凭空构造 task_id。
420
328
 
421
- 媒体任务只允许运行时覆盖有限字段:image 使用 `input.prompt` / `input.size` / `input.image`,video 使用 `input.prompt` / `input.image_url` / `input.duration`;model、张数、比例、水印等保持在 AI Function 配置中。`input.image` 接受单个字符串或 1~14 项字符串数组;`input.duration` 必须是正数,并会按模型 Profile 上限收紧。图片生成参考 starter 的 `page/src/examples/ai-function/ImageTaskOperation.tsx`(只渲染 `imageAssets`),文生视频参考同目录 `ai-media-panel.tsx` 中的 `AIVideoPanel`(渲染 `videoAsset`)。两个示例都轮询并处理 `queued`、`running`、`succeeded`、`failed`、`cancelled`,在新请求时通过 `requestSeq` 忽略旧任务结果,且带总轮询时限(`pollDeadlineMs`,默认 5 分钟)以避免死轮询;组件卸载时也停止 timer。不要用没有总时限或取消处理的 `while` 轮询。
422
-
423
- `messages[].content` 必须是非空 content part 数组,不接受字符串。业务调用只允许 `user` / `assistant`:`user` 可传 `text`、`image`、`video`、`audio`、`file`,`assistant` 只允许 `text`;System Prompt 只能由 AI Function 配置管理,调用方不得发送 `system`。每个 message 与 part 都采用严格字段白名单,多余字段会被拒绝。
329
+ ## Page 调用方式
424
330
 
425
- 图片 `detail` 仅允许 `low` / `high` / `xhigh`,视频 `fps` 仅允许 `[0.2, 5]`。媒体与文件 `url` 必须是非空 HTTP(S) URL 或合法 data URL;音频 data URL 的 MIME 必须对应 `mp3` / `wav` / `aac` / `m4a` / `pcm` / `ac3` / `alac`。音频 HTTP(S) URL 的路径后缀必须是这些格式之一(Ark 要求显式 format,服务端按后缀推断,签名参数不受影响),没有可识别后缀的链接请改传音频 data URL。文件只接受 PDF,并遵循上一段的 filename 和大小约束。每个 part 还必须命中所选 Profile 的 `input_modalities`。不要用 `any` 或自行 `fetch` 绕过公开类型与服务端校验。
331
+ 页面运行时 API 用法以工程已安装的 SDK 文档为准:读取 `node_modules/@lark-base-open/base-database-app-sdk/docs/README.md`,再按索引查看对应页面文档;旧模板可查[冻结的 AI 参考](legacy-ai-function.md#page-调用方式)。AI Function 的 Page 输入、能力与任务结果约束仍按本页前文执行。若工程使用 `defineFunction`,CLI 生成的 `meta.inputSchema` 是 Agent 开放能力的 schema;已有工程手写的 `meta.json` `inputSchema` 保持兼容,不要求迁移。
426
332
 
427
333
  ## System prompt 与数据边界
428
334
 
429
- System Prompt 在 **AI Function 配置**里维护,随版本快照进入线上;平台不代管、不隐藏,也**不承诺保护 System Prompt**,因此不得放入密钥、Token、内部凭据或不可向最终访问者暴露的内容。页面通过 `variables` 注入运行时值,占位符 `{{var}}` 由服务端渲染。
335
+ System Prompt 在 **AI Function 配置**里维护,随版本快照进入线上;平台不代管、不隐藏,也**不承诺保护 System Prompt**,因此不得放入密钥、Token、内部凭据或不可向最终访问者暴露的内容。页面通过 `params` 注入运行时值,占位符 `{{var}}` 由服务端渲染。
430
336
 
431
- 传给模型的数据遵循最小必要原则。Database Function 查询结果先在 Page 内筛选字段和记录,只发送完成当前任务所需的内容;不得把整个 Catalog、整表数据、登录凭证或原始下游响应无差别塞入 `messages` / `variables`。
337
+ 传给模型的数据遵循最小必要原则。Database Function 查询结果先在 Page 内筛选字段和记录,只发送完成当前任务所需的内容;不得把整个 Catalog、整表数据、登录凭证或原始下游响应无差别塞入 `messages` / `params`。
432
338
 
433
339
  ## 计费与失败处理
434
340
 
@@ -440,44 +346,32 @@ System Prompt 在 **AI Function 配置**里维护,随版本快照进入线上
440
346
 
441
347
  AI Function 的管理接口(`ai-functions list/pull/validate/sync/usage` 以及 `deploy` 内的同步)按当前用户做 feature gate。未开通的用户会收到业务码 `800004011`、消息 `ai function feature is not enabled`;CLI 会把它翻译为带降级路径的错误。它不是 scope 缺失,重新 `auth login` 不会改变结果,不要循环授权或重试。
442
348
 
443
- 处理方式:向用户说明当前账号未开通 AI Function;需求中的 AI 部分标记为阻塞,恢复条件是账号开通后重新 `deploy`。其余 Page、Database Function、FaaS 用 `deploy --skip-ai-functions` 正常发布,交付报告写明 AI Function 未同步、页面中的 AI 入口在开通前不可用。`deploy` 在写入任何远端 Function 之前先同步 AI Function,因此收到该错误时远端没有中间态,可直接加参数重跑。
349
+ 处理方式:向用户说明当前账号未开通 AI Function;需求中的 AI 部分标记为阻塞,恢复条件是账号开通后重新 `deploy`。其余 Page、Database Function、FaaS 用 `deploy --skip-ai-functions` 正常发布,交付报告写明 AI Function 未同步、页面中的 AI 入口在开通前不可用。降级前按[发布错误边界](release.md#function-发布顺序与错误边界)核对已执行步骤;未知写入先只读确认,不能盲目重跑。
444
350
 
445
351
  ### 页面如何处理运行态错误
446
352
 
447
- 页面只能可靠地按错误性质处理。收到 AI credit、并发限制或服务错误时,保留 `error.code`、`error.message` 和本次 `requestId`,结束 loading,并按错误是否可重试给出提示;不要在页面里自动重试,更不要绕过 AI Function 直连模型。
448
-
449
- AI credit 耗尽会作为不可重试的错误返回,消息为 `AI credit is exhausted`。应提示应用 owner 检查可用 credit 或联系平台支持,不能把它当作网络故障反复重试。
353
+ 参阅已安装 SDK 文档,入口见[Page 调用方式](#page-调用方式)。
450
354
 
451
355
  ## 页面实现检查
452
356
 
453
- 1. 页面按 `functionKey` 调用;`callSiteAIFunction` 显式传与配置相同的 `capability`。System Prompt / model / 参数由 AI Function 配置声明,`messages/input` 与 `variables` 是本次运行输入。
454
- 2. 指定模型或参数前先查 `/open-apis/base/v3/sites/:token/ai/model_profiles`;`:token` 取当前应用配置的 `appToken`,能力标记必须与 `capability_type` 匹配。
455
- 3. 用 `switch(result.type)` 判别渲染,不直接渲染 `delta.raw`;流式每个面板只有一个活动 handle,取消与卸载均调用 `destroy()`。
456
- 4. text/vision 流式同时消费 `delta.reasoningContent` 与 `delta.content`(或用 `readSiteAITextDelta` 取 `{ answer, reasoning }`),分区渲染;结构化解析只基于最终 answer。
457
- 5. `onError` 与 `onDone` 都结束 loading;image/video 用 `getSiteAIFunctionTask` 轮询到 `succeeded`/`failed`/`cancelled` 收尾。
458
- 6. vision 不绕过公开 `SiteAIMessage` 类型猜测媒体 content;只提交所选 Profile 的 `input_modalities` 已声明的 image / video / audio / file,未暴露对应输入契约时明确报告阻塞。
459
- 7. AI 调用走 AI Function,页面不保存模型凭证。
460
- 8. 与 Base 数据组合时,查询仍走 Database Function;写入按[Mutation 与 FaaS 分工](mutations.md#写入方式选择)选择。
461
-
462
- ## 区分三种「调试成功」
463
-
464
- AI Function 调试至少有三种互不等价的「成功」,不能互相替代地报告:
465
-
466
- - **配置校验成功**:`ai-functions validate` 返回 `is_success: true`,只证明 `meta.json` 合法,不代表能跑通。
467
- - **运行态调用成功**:接口能返回文本或 `taskId`,证明 Function 存在、未 `disabled`、鉴权与模型链路初步可用。CLI 对 text/vision 返回聚合文本。
468
- - **UI 流式成功**:页面 `onMessage` 多次收到增量并实时渲染,证明 SDK 回调与业务组件的增量显示已接通。
357
+ 按工程已安装的 SDK 文档验证调用、取消、错误与输出语义;老模板参考[冻结检查](legacy-ai-function.md#页面实现检查)。AI Function 页面只能通过宿主 broker 调用,不能直连模型域名或在代理失败时绕过宿主。
469
358
 
470
- 尤其对文本 AI Function:CLI 聚合返回成功或超时,都**不能**直接判断页面 SSE 是否正常。页面选择 `invokeSiteAIFunctionStream` 时,用真实页面验证多次 `onMessage` 和 `onDone`;选择 `callSiteAIFunction` 聚合时,验证得到 `{type:'text'}` 和完整 `content`。媒体能力用 task 接口验证终态。
359
+ 配置校验、运行态调用与 UI 流式成功的区别见[AI 验收判定](verification.md#ai-验收判定)。
471
360
 
472
361
  ## AI Function 交付 checklist
473
362
 
474
363
  ```text
475
364
  1. 查询 model_profiles,选择 capability 匹配的 profile_id。
476
- 2. 写 ai/<functionKey>/meta.json,先 validate(reasoning_depth 用 off/light/standard/deep;仅当 profile 的 thinking_levels 含 off 时关闭才生效)。
365
+ 2. 写 ai/<functionKey>/meta.json,由 deploy 校验(reasoning_depth 用 off/light/standard/deep;仅当 profile 的 thinking_levels 含 off 时关闭才生效)。
477
366
  3. 文本流式 UI 同时消费 delta.reasoningContent 与 delta.content。
478
367
  4. `callSiteAIFunction` 显式传 capability;文生图/文生视频使用 create task + poll task,不走文本 stream。
479
368
  5. 修改已有应用时,远端全部 key 已恢复到本地,未意外触发全量删除。
480
369
  6. record_id 不依赖短长度(^rec[A-Za-z0-9]{1,32}$)。
481
- 7. deploy 后 ai-functions list 确认 function 存在且 disabled=false。
482
- 8. 用真实页面按所选入口验证 text/vision(流式为多次 `onMessage` 增量和单次 `onDone`,错误时为 `onError` 且无 `onDone`;聚合为 text result);用 task 接口验证 image/video 终态。
370
+ 7. 运行态未检查即列未验证;用户要求验收时按下述 AI 验收判定执行,Prod 验证按用户诉求决定。
483
371
  ```
372
+
373
+ CLI 的 list/get/debug/task 默认 `--env preview`;prod 只读已发布版本,不作为草稿编辑依据。env 是函数版本,不是 CLI 运行环境。list 会读取全部分页后筛选 AI,pull 缺少 spec 或权限失败时停止。validate 仅验证指定本地项,不写入、不调用模型;sync 使用 kinds=[ai] 全覆盖,管理写入与校验不传 env。
374
+
375
+ 运行态验收方法见[AI 验收判定](verification.md#ai-验收判定)。
376
+
377
+ CLI debug 使用 `--params` 对象:text/vision 发送 `{params,messages}`,image/video 发送 `{params,input}`;不能混用 messages 和 input。新请求不传 mode/output_mode。媒体任务回执 `task_id` 仅表示受理,保存 key/env 后续查原任务;查询成功不表示生成成功,failed/cancelled 停止并报告错误,不重新提交。SDK 对页面保持 `taskId` 字段。超时/断网可能已执行和计费,结果未知时保留 requestId/LogID,不自动重试。
@@ -6,7 +6,7 @@
6
6
 
7
7
  原则:先确认业务要保留的结果语义,再选择查询形式。判定时按诊断的位置、语义码和 Catalog 类型定位问题;默认采用生成参考中与当前条件匹配、已有验证的形式,并逐项核对其前提。
8
8
 
9
- 例外:目录没有等价 SQL、前提不成立或改写会改变空值、行数及排序时,转到[SQL 外实现放在哪](../SKILL.md#sql-外实现放在哪)选择消费结果的实现位置。单个组合失败不代表组成它的所有能力都不可用;版本或运行环境不一致时,保留诊断和 LogID,先核对事实源。
9
+ 例外:目录没有等价 SQL、前提不成立或改写会改变空值、行数及排序时,转到[SQL 外实现放在哪](#sql-外实现放在哪)选择消费结果的实现位置。单个组合失败不代表组成它的所有能力都不可用;版本或运行环境不一致时,保留诊断和 LogID,先核对事实源。
10
10
 
11
11
  ## Stored Query 与分页
12
12
 
@@ -18,12 +18,20 @@
18
18
 
19
19
  默认逐列投影,保持输出 Schema 稳定;连接的每一侧使用明确的表或带别名的派生表,分阶段表达复杂查询。常规生成优先简单连接、顶层查询与带别名的派生表,而不是依靠深层组合表达全部业务逻辑。确需复杂组合时,依据生成参考和目标环境验证决定,而不将生成偏好当作平台能力结论。
20
20
 
21
- Database Function 需要 Catalog 中真实表依赖,以确定数据上下文;与 Base 数据无关的计算按[SQL 外实现放在哪](../SKILL.md#sql-外实现放在哪)处理。动态返回规模由调用方校验为非负整数并限制最大值;服务端资源预算以诊断中的实际限制为准。
21
+ Database Function 需要 Catalog 中真实表依赖,以确定数据上下文;与 Base 数据无关的计算按[SQL 外实现放在哪](#sql-外实现放在哪)处理。动态返回规模由调用方校验为非负整数并限制最大值;服务端资源预算以诊断中的实际限制为准。
22
22
 
23
23
  ## 按位置取值
24
24
 
25
- 先明确分区、排序、并列值与空分区的业务含义,再查[生成参考中的修复策略](base-sql-errors.generated.md)。默认只采用满足前提的已验证形式;没有等价形式时沿用[SQL 外实现选择原则](../SKILL.md#sql-外实现放在哪)。
25
+ 先明确分区、排序、并列值与空分区的业务含义,再查[生成参考中的修复策略](base-sql-errors.generated.md)。默认只采用满足前提的已验证形式;没有等价形式时沿用[SQL 外实现选择原则](#sql-外实现放在哪)。
26
26
 
27
27
  ## NULL 与数值边界
28
28
 
29
- 改写前明确空值、空集合、数值精度和错误行为是否属于结果契约。默认保留业务所需语义,并按[生成参考的前提与验证说明](base-sql-errors.generated.md)选择修法;防护写法会改变错误行为时,先确认业务接受该变化。需要 SQL 外处理的部分统一按[实现位置原则](../SKILL.md#sql-外实现放在哪)决定,不把截断结果或丢失空值的结果当作等价替代。
29
+ 改写前明确空值、空集合、数值精度和错误行为是否属于结果契约。默认保留业务所需语义,并按[生成参考的前提与验证说明](base-sql-errors.generated.md)选择修法;防护写法会改变错误行为时,先确认业务接受该变化。需要 SQL 外处理的部分统一按[实现位置原则](#sql-外实现放在哪)决定,不把截断结果或丢失空值的结果当作等价替代。
30
+
31
+ ## SQL 外实现放在哪
32
+
33
+ 原则:SQL 无法等价表达时,在消费查询结果的代码中完成计算;选择位置首先看数据可见性,再看规模与复用需求。
34
+
35
+ 判定:只有计算仅影响查看者本就有权看到的行的展示、结果集小且无需跨页面复用时,才适合放在 Page。若计算需要查看者不应看到的明细、数据量大、需要跨页面复用或写回,则放在 FaaS(SQL 报错中的 “Edge Function” 即指 FaaS),并沿用既有身份、权限和参数边界;FaaS 仍需在服务端校验调用者权限,只返回允许公开的结果。不能先把无权查看的明细发给浏览器,再靠 Page 过滤或隐藏。
36
+
37
+ 默认:拿不准时选 FaaS。把应在服务端处理的计算放到 Page,可能泄露数据;多一道服务端调用通常更容易纠正。SQL 报错中的“SQL 外实现”不等于一律新建 FaaS,也不构成绕过现有权限模型的授权。