kiki-agent-lite 0.3.1 → 0.3.2

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 (228) hide show
  1. package/README.md +13 -10
  2. package/dist/docs/en/configuration/config-files.md +63 -20
  3. package/dist/docs/en/configuration/data-locations.md +12 -4
  4. package/dist/docs/en/configuration/env-vars.md +4 -6
  5. package/dist/docs/en/configuration/overrides.md +13 -14
  6. package/dist/docs/en/configuration/providers.md +8 -6
  7. package/dist/docs/en/customization/agent-profiles.md +33 -38
  8. package/dist/docs/en/customization/agents.md +129 -107
  9. package/dist/docs/en/customization/hooks.md +41 -48
  10. package/dist/docs/en/customization/personas.md +19 -21
  11. package/dist/docs/en/customization/plugins.md +180 -156
  12. package/dist/docs/en/customization/prompt-fields.md +10 -6
  13. package/dist/docs/en/customization/skills.md +11 -13
  14. package/dist/docs/en/customization/skins.md +23 -27
  15. package/dist/docs/en/customization/themes.md +15 -15
  16. package/dist/docs/en/features/agents.md +85 -0
  17. package/dist/docs/en/features/daily.md +37 -7
  18. package/dist/docs/en/features/ecosystem.md +3 -1
  19. package/dist/docs/en/features/extend.md +7 -1
  20. package/dist/docs/en/features/freedom.md +4 -0
  21. package/dist/docs/en/features/index.md +6 -5
  22. package/dist/docs/en/features/long-work.md +23 -5
  23. package/dist/docs/en/features/look.md +1 -1
  24. package/dist/docs/en/features/people.md +10 -2
  25. package/dist/docs/en/features/spaces.md +16 -4
  26. package/dist/docs/en/features/workbench.md +11 -3
  27. package/dist/docs/en/getting-started/desktop-app.md +44 -29
  28. package/dist/docs/en/getting-started/first-launch.md +32 -21
  29. package/dist/docs/en/getting-started/installation.md +27 -12
  30. package/dist/docs/en/getting-started/use-cases.md +35 -35
  31. package/dist/docs/en/guides/goals.md +9 -7
  32. package/dist/docs/en/guides/interaction.md +26 -26
  33. package/dist/docs/en/guides/interface.md +18 -14
  34. package/dist/docs/en/guides/memory.md +43 -14
  35. package/dist/docs/en/guides/sessions.md +32 -26
  36. package/dist/docs/en/guides/settings.md +60 -29
  37. package/dist/docs/en/index.md +8 -2
  38. package/dist/docs/en/reference/command.md +8 -4
  39. package/dist/docs/en/reference/keyboard.md +18 -4
  40. package/dist/docs/en/reference/model-vocabulary.md +6 -8
  41. package/dist/docs/en/reference/slash-commands.md +4 -4
  42. package/dist/docs/en/reference/tools.md +92 -15
  43. package/dist/docs/en/release-notes/changelog.md +1 -9
  44. package/dist/docs/en/server/acp.md +1 -1
  45. package/dist/docs/en/server/ide.md +1 -1
  46. package/dist/docs/en/server/local-server.md +5 -5
  47. package/dist/docs/en/server/mcp.md +2 -2
  48. package/dist/docs/en/server/rest-api.md +79 -5
  49. package/dist/docs/en/server/sdk.md +2 -2
  50. package/dist/docs/zh/configuration/config-files.md +56 -15
  51. package/dist/docs/zh/configuration/data-locations.md +12 -4
  52. package/dist/docs/zh/configuration/env-vars.md +4 -6
  53. package/dist/docs/zh/configuration/overrides.md +13 -14
  54. package/dist/docs/zh/configuration/providers.md +7 -5
  55. package/dist/docs/zh/customization/agent-profiles.md +31 -36
  56. package/dist/docs/zh/customization/agents.md +120 -98
  57. package/dist/docs/zh/customization/hooks.md +35 -42
  58. package/dist/docs/zh/customization/personas.md +16 -18
  59. package/dist/docs/zh/customization/plugins.md +167 -142
  60. package/dist/docs/zh/customization/prompt-fields.md +9 -5
  61. package/dist/docs/zh/customization/skills.md +10 -12
  62. package/dist/docs/zh/customization/skins.md +19 -23
  63. package/dist/docs/zh/customization/themes.md +12 -12
  64. package/dist/docs/zh/features/agents.md +85 -0
  65. package/dist/docs/zh/features/daily.md +37 -7
  66. package/dist/docs/zh/features/ecosystem.md +3 -1
  67. package/dist/docs/zh/features/extend.md +7 -1
  68. package/dist/docs/zh/features/freedom.md +4 -0
  69. package/dist/docs/zh/features/index.md +6 -5
  70. package/dist/docs/zh/features/long-work.md +22 -4
  71. package/dist/docs/zh/features/look.md +1 -1
  72. package/dist/docs/zh/features/people.md +10 -2
  73. package/dist/docs/zh/features/spaces.md +15 -3
  74. package/dist/docs/zh/features/workbench.md +11 -3
  75. package/dist/docs/zh/getting-started/desktop-app.md +43 -28
  76. package/dist/docs/zh/getting-started/first-launch.md +32 -21
  77. package/dist/docs/zh/getting-started/installation.md +26 -11
  78. package/dist/docs/zh/getting-started/use-cases.md +35 -37
  79. package/dist/docs/zh/guides/goals.md +8 -8
  80. package/dist/docs/zh/guides/interaction.md +25 -25
  81. package/dist/docs/zh/guides/interface.md +18 -14
  82. package/dist/docs/zh/guides/memory.md +43 -14
  83. package/dist/docs/zh/guides/sessions.md +30 -24
  84. package/dist/docs/zh/guides/settings.md +54 -23
  85. package/dist/docs/zh/index.md +7 -1
  86. package/dist/docs/zh/reference/command.md +7 -3
  87. package/dist/docs/zh/reference/keyboard.md +18 -4
  88. package/dist/docs/zh/reference/model-vocabulary.md +6 -8
  89. package/dist/docs/zh/reference/slash-commands.md +3 -3
  90. package/dist/docs/zh/reference/tools.md +74 -9
  91. package/dist/docs/zh/release-notes/changelog.md +1 -9
  92. package/dist/docs/zh/server/acp.md +1 -1
  93. package/dist/docs/zh/server/ide.md +1 -1
  94. package/dist/docs/zh/server/local-server.md +5 -5
  95. package/dist/docs/zh/server/mcp.md +2 -2
  96. package/dist/docs/zh/server/rest-api.md +69 -1
  97. package/dist/docs/zh/server/sdk.md +2 -2
  98. package/dist/main.mjs +12545 -3456
  99. package/dist/web/assets/AppErrorBoundary-RFIAb-Uf.js +1 -0
  100. package/dist/web/assets/NavScopeBoundary-DY_ET7A-.js +1 -0
  101. package/dist/web/assets/{arc-y2SkSoyr.js → arc-CMgTB1m7.js} +1 -1
  102. package/dist/web/assets/{architectureDiagram-3BPJPVTR-uCwLz53m.js → architectureDiagram-3BPJPVTR-BU79ou2C.js} +1 -1
  103. package/dist/web/assets/{blockDiagram-GPEHLZMM-BZyWv36G.js → blockDiagram-GPEHLZMM-Bkuldod2.js} +1 -1
  104. package/dist/web/assets/{c4Diagram-AAUBKEIU-DKGx9i50.js → c4Diagram-AAUBKEIU-C3WMeqyu.js} +1 -1
  105. package/dist/web/assets/channel-DpDZUJRn.js +1 -0
  106. package/dist/web/assets/{chunk-2J33WTMH-CSkrhrsp.js → chunk-2J33WTMH-CesyWmwo.js} +1 -1
  107. package/dist/web/assets/{chunk-4BX2VUAB-CtxMoJ68.js → chunk-4BX2VUAB-C7rghYTf.js} +1 -1
  108. package/dist/web/assets/{chunk-55IACEB6-Dos3ftEy.js → chunk-55IACEB6-BqRHhwtz.js} +1 -1
  109. package/dist/web/assets/{chunk-727SXJPM-wbzEYK9z.js → chunk-727SXJPM-BhSqCRBc.js} +1 -1
  110. package/dist/web/assets/{chunk-AQP2D5EJ-B9GKvCD6.js → chunk-AQP2D5EJ-DdYE2ZVZ.js} +1 -1
  111. package/dist/web/assets/{chunk-FMBD7UC4-u5Y2P6IX.js → chunk-FMBD7UC4-BCRPUxDF.js} +1 -1
  112. package/dist/web/assets/{chunk-ND2GUHAM-B8rFKkTV.js → chunk-ND2GUHAM-CuvyDjTR.js} +1 -1
  113. package/dist/web/assets/{chunk-QZHKN3VN-EQsKtuD-.js → chunk-QZHKN3VN-BU5vAS78.js} +1 -1
  114. package/dist/web/assets/classDiagram-4FO5ZUOK-Bju1GfNu.js +1 -0
  115. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-Bju1GfNu.js +1 -0
  116. package/dist/web/assets/client-C0oH7-8r.js +2 -0
  117. package/dist/web/assets/connection-BhO2nh7P.js +1 -0
  118. package/dist/web/assets/{cose-bilkent-S5V4N54A-D6dr5mIW.js → cose-bilkent-S5V4N54A-CXrvsA1a.js} +1 -1
  119. package/dist/web/assets/{dagre-BM42HDAG-Dnyhc4Hn.js → dagre-BM42HDAG-TaAea3Rt.js} +1 -1
  120. package/dist/web/assets/{diagram-2AECGRRQ-CYXkWdne.js → diagram-2AECGRRQ-CdEH4jGt.js} +1 -1
  121. package/dist/web/assets/{diagram-5GNKFQAL-DPwBf5Ag.js → diagram-5GNKFQAL-A0jZ_p-T.js} +1 -1
  122. package/dist/web/assets/{diagram-KO2AKTUF-DNeLYZ8X.js → diagram-KO2AKTUF-miHWORz3.js} +1 -1
  123. package/dist/web/assets/{diagram-LMA3HP47-zU8RsQTX.js → diagram-LMA3HP47-BlUIwEIg.js} +1 -1
  124. package/dist/web/assets/{diagram-OG6HWLK6-Cf9Mm94H.js → diagram-OG6HWLK6-DwDzMhEg.js} +1 -1
  125. package/dist/web/assets/{erDiagram-TEJ5UH35-Ch4CeiUI.js → erDiagram-TEJ5UH35-BJr5w62i.js} +1 -1
  126. package/dist/web/assets/export-BlxaZKEe.js +2 -0
  127. package/dist/web/assets/{flowDiagram-I6XJVG4X-Csn6WqEH.js → flowDiagram-I6XJVG4X-BP7KSFjx.js} +1 -1
  128. package/dist/web/assets/{ganttDiagram-6RSMTGT7-DsuBgEyu.js → ganttDiagram-6RSMTGT7-BstLBBof.js} +1 -1
  129. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-CPA7jCxU.js → gitGraphDiagram-PVQCEYII-C57s7nZ-.js} +1 -1
  130. package/dist/web/assets/highlighted-body-OFNGDK62-BVb-7KsA.js +1 -0
  131. package/dist/web/assets/index-69qhvTvD.js +1 -0
  132. package/dist/web/assets/{index-BYUHmd8w.js → index-BDNM6yJI.js} +2 -2
  133. package/dist/web/assets/{index-BGgZxlEQ.js → index-BJF_gEDs.js} +2 -2
  134. package/dist/web/assets/index-BOwMP6BP.js +1 -0
  135. package/dist/web/assets/{index-C69a5Mcz.js → index-BZsyXCqm.js} +1 -1
  136. package/dist/web/assets/{index-C7EA7a_g.js → index-Bfl4JiNq.js} +2 -2
  137. package/dist/web/assets/index-BlD3AKX-.js +1 -0
  138. package/dist/web/assets/{index-CIymCfcP.js → index-BnvW0EvQ.js} +1 -1
  139. package/dist/web/assets/index-C4rmWyOm.js +1 -0
  140. package/dist/web/assets/index-CGLcb3HY.js +1 -0
  141. package/dist/web/assets/{index-kWBxPqIX.js → index-CPvOeQPX.js} +1 -1
  142. package/dist/web/assets/index-Cjbe0JKM.js +1 -0
  143. package/dist/web/assets/index-CmYoJWUm.js +1 -0
  144. package/dist/web/assets/index-CtUFrjKe.js +1 -0
  145. package/dist/web/assets/index-DDvDRMTK.js +1 -0
  146. package/dist/web/assets/index-DSpndwAR.css +1 -0
  147. package/dist/web/assets/index-D_JjTHxi.js +1 -0
  148. package/dist/web/assets/index-DbuwcnbT.js +1 -0
  149. package/dist/web/assets/index-DcXyS0nN.js +1 -0
  150. package/dist/web/assets/index-Dcl9ruKA.js +1 -0
  151. package/dist/web/assets/index-DgwALPNA.js +121 -0
  152. package/dist/web/assets/{index-DoN1FTEe.js → index-DkE8hRT1.js} +2 -2
  153. package/dist/web/assets/index-DsyRBZ4h.js +1 -0
  154. package/dist/web/assets/{index-29zav3JI.js → index-DuudNhLL.js} +4 -4
  155. package/dist/web/assets/index-Gc4F0b2f.js +1 -0
  156. package/dist/web/assets/index-HGqqwKoV.js +13 -0
  157. package/dist/web/assets/index-KchrJnno.js +3 -0
  158. package/dist/web/assets/{index-B0KNSyji.js → index-Tmi2BPYU.js} +1 -1
  159. package/dist/web/assets/index-Ya4GuDs0.js +1 -0
  160. package/dist/web/assets/index-_aDaKqLB.js +1 -0
  161. package/dist/web/assets/index-_qwOAotB.js +1 -0
  162. package/dist/web/assets/index-hnIkczza.js +7 -0
  163. package/dist/web/assets/{infoDiagram-5YYISTIA-D3Q__m62.js → infoDiagram-5YYISTIA-CifuVY6C.js} +1 -1
  164. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-CcvCBuZ5.js → ishikawaDiagram-YF4QCWOH-Cd60vQUi.js} +1 -1
  165. package/dist/web/assets/{journeyDiagram-JHISSGLW-COZU4LNt.js → journeyDiagram-JHISSGLW-Cb3Xl_wl.js} +1 -1
  166. package/dist/web/assets/{kanban-definition-UN3LZRKU-BrXjBoAU.js → kanban-definition-UN3LZRKU-Ei6ThuZt.js} +1 -1
  167. package/dist/web/assets/{linear-BgP1STFi.js → linear-CDZJx-o2.js} +1 -1
  168. package/dist/web/assets/mermaid-GHXKKRXX-DFxyxD7G.js +331 -0
  169. package/dist/web/assets/{mindmap-definition-RKZ34NQL-CgjSrE5r.js → mindmap-definition-RKZ34NQL-B0ygxzkx.js} +1 -1
  170. package/dist/web/assets/navViewState-Ck_HK-TK.js +1 -0
  171. package/dist/web/assets/{pieDiagram-4H26LBE5-DTfe1sKA.js → pieDiagram-4H26LBE5-B2FdrvDv.js} +1 -1
  172. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-D95hfh0q.js → quadrantDiagram-W4KKPZXB-CwpOTy3d.js} +1 -1
  173. package/dist/web/assets/{requirementDiagram-4Y6WPE33-DtSLi7Mh.js → requirementDiagram-4Y6WPE33-ExdZNzLQ.js} +1 -1
  174. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-gi_dJpcU.js → sankeyDiagram-5OEKKPKP-u0EZKD7D.js} +1 -1
  175. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-DKQ9a72t.js → sequenceDiagram-3UESZ5HK-BXHMy5DY.js} +1 -1
  176. package/dist/web/assets/{spaces-B2Ccyh_T.js → spaces-C8n7xQPx.js} +1 -1
  177. package/dist/web/assets/{stateDiagram-AJRCARHV-Bz7tmSqa.js → stateDiagram-AJRCARHV-DMXx7ell.js} +1 -1
  178. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-Bydq1_By.js +1 -0
  179. package/dist/web/assets/theme-BBnHttAf.js +1 -0
  180. package/dist/web/assets/{timeline-definition-PNZ67QCA-BfMXPwhV.js → timeline-definition-PNZ67QCA-DtqVG_4u.js} +1 -1
  181. package/dist/web/assets/{vennDiagram-CIIHVFJN-WLxW2KT5.js → vennDiagram-CIIHVFJN-Dom0ex8r.js} +1 -1
  182. package/dist/web/assets/{wardley-L42UT6IY-DiiqwIdq.js → wardley-L42UT6IY-C-RstmuQ.js} +1 -1
  183. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-DmCukWuw.js → wardleyDiagram-YWT4CUSO-C8CzNfdf.js} +1 -1
  184. package/dist/web/assets/{xychartDiagram-2RQKCTM6-Cfq1W2tT.js → xychartDiagram-2RQKCTM6-1AxVTyB6.js} +1 -1
  185. package/dist/web/index.html +2 -2
  186. package/native/auth-native/prebuilds/linux-arm64/auth-native.node +0 -0
  187. package/native/auth-native/prebuilds/linux-x64/auth-native.node +0 -0
  188. package/native/auth-native/prebuilds/win32-arm64/auth-native.node +0 -0
  189. package/native/auth-native/prebuilds/win32-x64/auth-native.node +0 -0
  190. package/package.json +1 -1
  191. package/dist/web/assets/AppErrorBoundary-DWpgwxFV.js +0 -1
  192. package/dist/web/assets/NavScopeBoundary-D8Lf1G0U.js +0 -1
  193. package/dist/web/assets/channel-BGdXootG.js +0 -1
  194. package/dist/web/assets/classDiagram-4FO5ZUOK-CPcnLy_H.js +0 -1
  195. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-CPcnLy_H.js +0 -1
  196. package/dist/web/assets/client-DSIbyfoz.js +0 -2
  197. package/dist/web/assets/connection-DYZn9oPZ.js +0 -1
  198. package/dist/web/assets/export-Bq8ZECqX.js +0 -2
  199. package/dist/web/assets/highlighted-body-OFNGDK62-CDPBxM_E.js +0 -1
  200. package/dist/web/assets/index-AksnytJj.js +0 -1
  201. package/dist/web/assets/index-B8xhhYDh.css +0 -1
  202. package/dist/web/assets/index-BUrlrKap.js +0 -1
  203. package/dist/web/assets/index-B_5-HLed.js +0 -62
  204. package/dist/web/assets/index-BfmoxdpP.js +0 -1
  205. package/dist/web/assets/index-Bo3e-ohM.js +0 -3
  206. package/dist/web/assets/index-BrYV9gV_.js +0 -1
  207. package/dist/web/assets/index-C8XUtAvK.js +0 -1
  208. package/dist/web/assets/index-C9uil5my.js +0 -13
  209. package/dist/web/assets/index-CKpWHSp9.js +0 -1
  210. package/dist/web/assets/index-CLKBgQxV.js +0 -1
  211. package/dist/web/assets/index-CTyyUNWj.js +0 -7
  212. package/dist/web/assets/index-D7cg9qYZ.js +0 -1
  213. package/dist/web/assets/index-D7dg8R_q.js +0 -1
  214. package/dist/web/assets/index-DCSpedV_.js +0 -1
  215. package/dist/web/assets/index-DLbD0Nx5.js +0 -1
  216. package/dist/web/assets/index-DaEzbvvu.js +0 -1
  217. package/dist/web/assets/index-DhbcjMZF.js +0 -1
  218. package/dist/web/assets/index-Dw2h88mF.js +0 -1
  219. package/dist/web/assets/index-FcMtfmKv.js +0 -1
  220. package/dist/web/assets/index-XFq9Kgg0.js +0 -1
  221. package/dist/web/assets/index-iI2mM43w.js +0 -1
  222. package/dist/web/assets/index-oXOF7lko.js +0 -1
  223. package/dist/web/assets/locale-CANfezJ4.js +0 -17
  224. package/dist/web/assets/mermaid-GHXKKRXX-_JLagMll.js +0 -321
  225. package/dist/web/assets/navViewState-DS5LnMYc.js +0 -1
  226. package/dist/web/assets/settings-CcwMWXbp.js +0 -42
  227. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-D6-wdUbw.js +0 -1
  228. package/dist/web/assets/theme-DlDhDxeD.js +0 -1
@@ -118,6 +118,13 @@ Desktop integrations can call the native `create_space_shortcut` command with `{
118
118
  | `POST /api/oauth/logout` | Log out the managed provider |
119
119
  | `GET /api/oauth/usage` | Plan usage and limits |
120
120
  | `GET /api/oauth/userinfo` | Account profile |
121
+ | `POST /api/usage-export/destinations/{id}/auth/begin` | Start a VibeCafe sign-in for a destination |
122
+ | `POST /api/usage-export/auth/{id}/poll` | Poll that sign-in |
123
+ | `POST /api/usage-export/auth/{id}/cancel` | Cancel that sign-in |
124
+
125
+ A `vibecafe.ai` destination signs in the way VibeCafe itself does, and the official service is the only one that offers it. `POST /api/usage-export/destinations/{id}/auth/begin` takes only the credential `storage` choice (`keyring` or `private-file`) — there is no address, client id, or key to paste, and the service is fixed to `https://vibecafe.ai`. The response carries `flow_id`, `state`, `user_code`, `verification_uri`, `expires_at`, and `poll_after_ms`; poll it with `POST /api/usage-export/auth/{id}/poll` at the interval it gives you, and cancel with `POST /api/usage-export/auth/{id}/cancel`. `state` moves from `pending` to `connected`, `cancelled`, `denied`, `expired`, or `error`, and `error_category` says why when it is not `connected`.
126
+
127
+ A finished sign-in stores the credential; it does not turn sending on. The destination stays `disabled` until you preview the payload and enable it, exactly like one you set up by hand. A destination pointed at a custom address, or one you authenticate with a key you supply yourself, uses the manual path instead; `vibe-auth-official-only` reports the sign-in as unavailable there.
121
128
 
122
129
  ### Config
123
130
 
@@ -182,6 +189,28 @@ Attachment does not copy the vendor transcript or send a prompt. The first promp
182
189
 
183
190
  For automatic allocation, send `{}` to `POST /api/sessions`. The server creates a distinct directory under `$KIKI_HOME/workspaces/`, registers it, and returns its `workspace_id` and `metadata.cwd` in the session response. Supplying an existing `workspace_id` or `metadata.cwd` keeps the existing targeting behavior; an unknown `workspace_id` is still rejected.
184
191
 
192
+ Set `agent_config.execution` at creation to select a harness independently of a profile:
193
+
194
+ ```json
195
+ { "agent_config": { "execution": { "executor": "claude-acp" } } }
196
+ ```
197
+
198
+ The selection is `{ executor, profile?, overrides? }`. Omit `profile` for direct external execution; an explicitly selected profile must use the same executor. `overrides` accepts `model`, `thinking`, `permission_mode`, `kiki_context` and `allow_kiki_subagents`. With the same executor/profile, omitted overrides keep the session's saved overrides; `null` removes an override and restores the [lower-priority defaults](../configuration/config-files.md#external-harness-defaults), while `[]` and `false` explicitly disable their respective capabilities. Legacy top-level model/profile/thinking requests remain supported.
199
+
200
+ Session reads return the committed `agent_config.execution` binding as `{ version: 1, selection, effective, sources, generation }`. Sources are `session`, `profile`, `harness-settings` or `harness-default`; an absent effective model or effort means Kiki has not selected one, not that the harness has none. A reported vendor model is an observation, not a new override. Idle updates can also use `POST /api/sessions/{session_id}/profile` with `agent_config.execution`; while running, submit the selection with the next prompt instead.
201
+
202
+ #### `POST /api/sessions/{session_id}:compact`
203
+
204
+ The body is optional. It accepts `instruction` (what to preserve) and `strategy`, which is `summarize` or `relay` — the two renewal strategies the server implements. A session that was idle when the request arrives starts compressing immediately; one with a model call or tool result still landing in its history is queued, and Kiki processes it at the next step boundary once that work has finished, without waiting for the whole turn.
205
+
206
+ ```json
207
+ { "accepted": true, "status": "queued", "source": "manual" }
208
+ ```
209
+
210
+ `accepted: true` means the request was taken, **not** that the history was compressed. `status` is `queued` or `running` at that moment; the compression is done when a terminal [`compaction.*` event](#events) arrives, not when this response does. Asking again while a manual compaction is queued or running returns `accepted: false` and does not start a second one — send the request again only after a terminal event, and then only if the first attempt failed.
211
+
212
+ Accepting the request does not promise the compression succeeds. A run that reaches a point with no safe earlier history to compact against ends in `compaction.cancelled` with a `reason`, rather than quietly leaving the history alone, and a queued manual request is not cleared by a later automatic compaction finishing. An older server may return an empty `data`; treat every field in the example above as optional when it is absent.
213
+
185
214
  ### Messages and transcript
186
215
 
187
216
  | Method and path | Description |
@@ -205,7 +234,9 @@ Both transcript-page and catch-up requests must send `transcript_coverage_versio
205
234
  | `POST /api/sessions/{session_id}/prompts/{prompt_id}:abort` | Abort one queued, launching, running, or steered prompt |
206
235
  | `POST /api/sessions/{session_id}/prompts/{prompt_id}:steer` | Send one queued prompt now |
207
236
 
208
- Sending now adds the selected prompts to the active turn, or starts them as new turns in queue order when no turn is active. After a restart, it bypasses the recovery hold only for the selected prompts; other restored prompts still wait for confirmation. Aborting a steered prompt cancels the turn it joined, not a later turn. Aborting an unknown or already settled prompt returns `40402`.
237
+ A prompt can carry the same [execution selection](#sessions) in its top-level `execution` field. It is captured with that prompt and applied when the prompt launches, not when it enters the queue. The current turn keeps its committed binding. A changed execution generation starts a fresh remote session without resuming or forking the old one or sending a handoff of the old Kiki conversation; visible Kiki history is retained. Cold recovery reuses the committed generation and its own saved remote reference.
238
+
239
+ Sending now adds ordinary selected prompts to the active turn, or starts them as new turns in queue order when no turn is active. A prompt carrying an execution selection must launch as its own turn, rather than steer a new binding into the current turn. After a restart, it bypasses the recovery hold only for the selected prompts; other restored prompts still wait for confirmation. Aborting a steered prompt cancels the turn it joined, not a later turn. Aborting an unknown or already settled prompt returns `40402`.
209
240
 
210
241
  ### Approvals and questions
211
242
 
@@ -311,6 +342,41 @@ PTY terminal endpoints; mounted only on loopback binds.
311
342
  | `POST /api/workspaces/{workspace_id}/trust` | Grant trust |
312
343
  | `POST /api/workspaces/{workspace_id}/untrust` | Revoke trust |
313
344
 
345
+ ### Memory
346
+
347
+ `{scope}` is one of `global`, `workspace`, `persona` or `persona_workspace`. The three non-global scopes name their owner in the query string: `workspace_id` for a workspace, `persona_id` for a persona, and both for a persona's per-workspace notes. An unknown `workspace_id` is rejected.
348
+
349
+ | Method and path | Description |
350
+ | --- | --- |
351
+ | `GET /api/memory/settings` | Read the memory section, with `effective_enabled` |
352
+ | `PATCH /api/memory/settings` | Change `enabled`, `approval` or `budget` |
353
+ | `GET /api/memory/workspaces/{workspace_id}/settings` | Read one workspace's switch |
354
+ | `PATCH /api/memory/workspaces/{workspace_id}/settings` | Set it to `true` / `false`, or `null` to follow the global setting |
355
+ | `GET /api/memory/{scope}` | Search or list entries; see below for filters and pagination |
356
+ | `GET /api/memory/{scope}/{id}` | Read one entry with its `target`, `applicability` and `complete` |
357
+ | `PUT /api/memory/{scope}/{id}` | Write an entry; use `{id}` as `new` to create |
358
+ | `DELETE /api/memory/{scope}/{id}` | Delete an entry (`expected_revision` in the query string) |
359
+ | `GET /api/memory/{scope}/inbox` | List proposals awaiting review |
360
+ | `GET /api/memory/{scope}/journal` | Change history, optionally narrowed to one `id` |
361
+ | `POST /api/memory/{scope}/undo` | Undo one operation by `operation_id` |
362
+
363
+ `GET /api/memory/{scope}` returns bounded pages as `{ items, mode, next_cursor, coverage }`, including when no pagination parameters are supplied. `mode` defaults to `list` with no `query` and to `search` with one; `page_size` is 1–20. Without explicit `statuses`, list reads `active` and `pending`, search reads `active`, and `include_inactive=true` widens either to all four. `statuses` is a comma-separated list of `active`, `pending`, `superseded` and `archived`. Existing clients must consume `next_cursor` rather than treating the first page as the whole namespace.
364
+
365
+ Continue until `next_cursor` is null and `coverage.exhausted` is true. An empty preparation page with a cursor is not an empty namespace. `coverage.complete` and `warnings` report unreadable, invalid or oversized records; those records do not hide the other readable entries. Scan budgets are per call, not a permanent inventory limit; search ranking and list title ordering apply within each bounded source chunk.
366
+
367
+ Keep the same `{scope}` path and owning `workspace_id` / `persona_id`, and send `cursor` alone, without the original filters or page size. Mixing them returns `40944`. A cursor is invalidated by source changes or a store restart; restart and reconcile by scope plus ID. `GET /api/memory/{scope}/inbox` returns the same page shape for `pending` only and accepts `page_size` or a pending-list `cursor`; cursors for other statuses or search mode are rejected.
368
+
369
+ `PUT /api/memory/{scope}/{id}` takes the same action vocabulary as [`MemoryWrite`](../reference/tools.md#writing-an-entry): `action` (`create`, `update`, `supersede`, `archive`), `type`, `title`, `body`, `reason`, `expected_revision` and `pinned`. Writes through REST are recorded as coming from you, whatever `source` the agent would have used. The response is `{ entry, operationId, outcome, warnings? }`, where `outcome` is `applied`, `pending` or `unchanged`; `operationId` is `null` for `unchanged` and for a proposal identical to one already waiting, and those two cases have nothing to undo. For `update`, `supersede` and `archive`, `expected_revision` is required — a `PUT` built on a stale revision is refused instead of overwriting a newer one.
370
+
371
+ Two metadata fields are optional and behave differently on omission:
372
+
373
+ - **`basis`** — `{ kind, note, refs? }`, with `kind` one of `human`, `observed`, `derived`, `unknown`. It is an object or absent, never `null`. Omitting it on an `update` keeps the current basis only while `type`, `title` and `body` are unchanged; rewrite any of those without a new basis and the entry drops to `{ kind: 'unknown' }` with a `warnings` entry saying the attribution was not refreshed.
374
+ - **`validity`** — `{ check, until? }`, and `null` is meaningful: it clears a recorded check. Omitting the key preserves the current value on an `update` and leaves a new entry without one. An entry with no recorded validity is not a permanently valid one.
375
+
376
+ `covered_by` is accepted for `archive` only, as `{ id, expected_revision }` of the retained active entry in the same scope. The stored entry records the same dependency as `{ id, revision }` — the revision you sent — and it is re-checked when the retirement is applied, so an archive against a replacement that has since changed fails rather than dropping a rule that is still needed.
377
+
378
+ `GET /api/memory/{scope}/{id}` returns the full entry plus `scope`, a `target` of `{ scope, id, expected_revision }`, an `applicability` of `expired`, `recheck` or `unrecorded`, and `complete: true`. The `target` is an addressing object, not a request body: `scope` and `id` belong in the path, the owning workspace or persona in the query string, and `expected_revision` is the one field the `PUT` body takes from it — alongside the `action`, `type`, `title`, `body` and `reason` for the change you are making. Read an entry before writing to it. A `PUT` whose `expected_revision` no longer matches returns the `40944` code, and the response's `details` carries the domain's own `code` and `recovery` while the numeric envelope code stays the one existing clients already handle.
379
+
314
380
  ### Session leases and peer threads
315
381
 
316
382
  A session lease is a periodically renewed "online token" a client holds: `POST /api/leases` creates or renews one (default validity 60 seconds) and responds with `lease_id` and `expires_at`. A live lease can hold resources that need cleanup (such as PTY terminals and file watches) and keeps the shared daemon from exiting as idle — see `--idle-exit` under [`kiki serve`](../reference/command.md#kiki-serve).
@@ -343,11 +409,15 @@ The peer-thread endpoints support cross-session collaboration: a thread is addre
343
409
  | `limit` | Page size, default 50, range 1–100 |
344
410
  | `cursor` | Opaque continuation; repeat the same workspace/session/pair filters |
345
411
 
346
- The standard envelope's `data` is `{ items, next_cursor?, incomplete?, history? }`. Each item has `message_id`, `source: { kind: "thread", thread: { ref, title?, deleted, archived } }`, `target: { ref, title?, deleted, archived }`, `content`, `accepted_at` (Unix milliseconds), `target_seq`, `delivery`, and optional `reason`. References use the host/workspace/session triple. Room wake receipts use `source: { kind: "room", room_id }`. They carry a recipient's since catch-up, not individual room log messages, and match only that recipient's session/workspace. Pair filters exclude them. Follow the room reference to `GET /api/rooms/{id}/log` for the complete discussion; room logs have a separate forward `afterId` cursor and are not merged into this recipient-owned stream. Pages are newest-first, with stable message-ID ordering for equal timestamps. A scan-budget page can contain no items and still have `next_cursor`; continue until the cursor is absent. Changed filters return `40931` (`thread.cursor_invalid`), and a missing selected session returns `40421` (`thread.not_found`).
412
+ The standard envelope's `data` is `{ items, next_cursor?, incomplete?, history? }`. Each item has `message_id`, `source: { kind: "thread", thread: { ref, title?, deleted, archived } }`, `target: { ref, title?, deleted, archived }`, `content`, `accepted_at` (Unix milliseconds), `target_seq`, `delivery`, and optional `reason`. References use the host/workspace/session triple. Pages are newest-first, with stable message-ID ordering for equal timestamps, and a scan-budget page can be empty while still carrying `next_cursor` — continue until the cursor is absent.
413
+
414
+ Room wake receipts use `source: { kind: "room", room_id }` and are per recipient: they carry that recipient's since catch-up rather than individual room log messages, match only that recipient's session and workspace, and are excluded by pair filters. Follow the room reference to `GET /api/rooms/{id}/log` for the complete discussion; room logs have their own forward `afterId` cursor and are not merged into this stream. Changed filters return `40931` (`thread.cursor_invalid`), and a missing selected session returns `40421` (`thread.not_found`).
347
415
 
348
416
  `delivery` is `pending`, `delivered`, or `undeliverable`. Delivered means the input was handed to the target prompt, not that the target finished answering. A rejected send before mailbox acceptance, such as an unknown target, creates no communication record. The contract guarantees that `message_id` equals both the recipient main-agent prompt id and its user-message id, including steered delivery and idempotent retries. Navigate only `delivered` records in the target session with `?block=user-<message_id>`; `target_seq` is a mailbox sequence, not a transcript turn number. A deleted endpoint has `deleted: true`; the record stays visible from the surviving side and disappears from this view when neither side survives.
349
417
 
350
- History reads use existing indexed records without waiting for a full historical repair. While coverage is unproven, `incomplete: "history_preparing"` distinguishes preparation from an empty history. Optional `history` reports `generation`, `state` (`complete`, `preparing`, or `error`), `processedMessages`, `completedShards`, `totalShards`, the pending scope (`room` or `all`), and an optional failure detail. Retry from the first page while preparing; do not treat an absent cursor as proof of completeness. Cursors pin the coverage generation: repaired older records or completion invalidate an incomplete cursor with `40931`, so refresh from the first page. Pre-upgrade cursors also require a fresh first page. The GUI displays preparation or failure instead of "no records", refreshes the first page while preparing, and restarts pagination after cursor invalidation. Caller cancellation does not stop the shared repair; a failed repair leaves existing records readable and never reports complete coverage.
418
+ History reads serve existing indexed records without waiting for a full historical repair. While coverage is unproven, `incomplete: "history_preparing"` distinguishes preparation from an empty history; optional `history` reports `generation`, `state` (`complete`, `preparing`, or `error`), `processedMessages`, `completedShards`, `totalShards`, the pending scope (`room` or `all`), and an optional failure detail. Retry from the first page while preparing — an absent cursor is not proof of completeness.
419
+
420
+ Cursors pin the coverage generation, so repaired older records or a completed repair invalidate an incomplete cursor with `40931` and you must refresh from the first page; cursors from before an upgrade need a fresh first page too. Cancelling a read does not stop the shared repair, and a failed repair leaves existing records readable and never reports complete coverage.
351
421
 
352
422
  For `undeliverable` records, `reason_code` is a stable localization key and `reason_detail` is the original diagnostic text. The legacy `reason` remains an alias of `reason_detail`. Other delivery states omit these fields. Older stored failures without a code return `delivery_failed`; clients talking to older servers should use the same fallback instead of translating diagnostic text.
353
423
 
@@ -421,7 +491,7 @@ The session `fs:{action}` workspace API accepts workspace-relative paths only an
421
491
 
422
492
  On the usage page's History tab, **Rescan all usage** scans every indexed session, including archived sessions. It runs only when requested and can take a while. `POST /api/usage/rescan` starts the task without a body; another POST while it is running returns the same task's current progress. Poll `GET /api/usage/rescan` about once per second. Both use the normal success envelope with `data` containing `state` (`idle`, `running`, `completed`, or `failed`), `scanned_sessions`, `total_sessions`, `scanned_records`, `started_at`, `finished_at`, and `error`. Times are epoch milliseconds or `null`; `error` is `null` unless the task failed. `scanned_records` counts newly read wire records, including non-usage records; unchanged checkpoints need no wire reads.
423
493
 
424
- The task bypasses session, record, and time scan budgets and saves incremental checkpoints. Regular queries continue serving committed checkpoints while it runs. The regular deadline is 10 seconds, with a 500-session cold-scan limit and a 200,000-record budget. Successfully rescanned sessions no longer consume the cold-session limit: their keys are saved in `cache/usage-aggregation-v1/full-scan.json`, and their usage remains in the existing per-session checkpoints. Regular queries still check source fingerprints and obey their record and time budgets. Deleted-session and temporary-usage ledgers retain their regular query budgets. A completed rescan does not supply missing provider usage or model prices. Task progress is process-local and resets to `idle` on restart; checkpoints and the completed inventory survive. Cancellation is not supported.
494
+ The rescan bypasses session, record, and time scan budgets and saves incremental checkpoints; regular queries keep serving committed checkpoints while it runs. A regular query has a 10-second deadline, a 500-session cold-scan limit, and a 200,000-record budget. Sessions it rescans successfully stop consuming the cold-session limit: their keys are saved in `cache/usage-aggregation-v1/full-scan.json` and their usage stays in the existing per-session checkpoints. A completed rescan does not supply missing provider usage or model prices. Task progress is process-local and resets to `idle` on restart, while checkpoints and the completed inventory survive; cancellation is not supported.
425
495
 
426
496
  ### Usage pricing
427
497
 
@@ -530,6 +600,8 @@ Event frames look like `{ "type", "seq", "epoch"?, "volatile"?, "offset"?, "sess
530
600
  | Background | `task.started` / `terminated`, `shell.started` / `output` / `completed` |
531
601
  | Misc | `compaction.*`, `skill.activated`, `goal.updated`, `prompt.*`, `error`, `warning` |
532
602
 
603
+ The `compaction.*` family separates who asked from what happened. `compaction.started` carries `trigger` as `manual` or `auto` and an optional `phase` of `queued` or `running`; an event without `phase` means running. `compaction.completed` carries the optional `trigger` and a `result`; `compaction.cancelled` carries the optional `trigger` and a `reason` when it failed rather than being cancelled. Judge completion from these events, not from the HTTP response of a [compact request](#post-api-sessions-session-id-compact) — and treat a `trigger` that is absent as unknown rather than assuming a manual run finished. A queued manual compaction is not settled by an automatic one completing.
604
+
533
605
  Events also split into durable and volatile: durable events carry a strictly increasing `seq`, are journaled, and can be replayed; volatile events (the `*.delta` family, `tool.progress`, `shell.*`, and similar) are marked `volatile: true` and never replayed. When consuming a volatile text stream, compare `offset` (the cumulative character offset within the turn) against your locally accumulated text: below the local length means a duplicate frame; above means a gap that needs snapshot recovery.
534
606
 
535
607
  ### Reconnect and recovery
@@ -538,7 +610,9 @@ After reconnecting, pass each session's last applied `{seq, epoch}` in `subscrib
538
610
 
539
611
  ### Transcript protocol
540
612
 
541
- `subscribe_v2`'s `transcript` field sets a per-agent grade: `off` / `turn` / `block` / `delta` (the `"*"` key sets the default grade), with higher grades pushing finer detail. If any grade is not `off`, send the numeric `transcript_coverage_version: 2` in the payload; the successful acknowledgement echoes it. A missing or unsupported version is rejected before transcript frames are sent; an `off`-only subscription does not need the version. An agent with a non-`off` grade receives two frame types: `transcript.reset` (a baseline snapshot; history pages in over REST) and `transcript.ops` (incremental op batches with a per-agent strictly increasing `seq`). The agent's legacy events are suppressed on that connection and carried by transcript frames instead. After a disconnect, resume with `transcript_since`; when the server's op journal cannot cover the gap (REST catch-up returns `complete: false`), do a full refresh. The REST counterparts are `GET .../transcript` (turn-paged) and `GET .../transcript/ops?since_seq=` (op-batch catch-up).
613
+ `subscribe_v2`'s `transcript` field sets a per-agent grade: `off` / `turn` / `block` / `delta`, where the `"*"` key sets the default and a higher grade pushes finer detail. If any grade is not `off`, send the numeric `transcript_coverage_version: 2` in the payload; a missing or unsupported version is rejected before any transcript frame is sent, and an `off`-only subscription does not need it.
614
+
615
+ An agent with a non-`off` grade receives `transcript.reset` (a baseline snapshot; history pages in over REST) and `transcript.ops` (incremental op batches with a per-agent strictly increasing `seq`). That agent's legacy events are suppressed on the connection and carried by transcript frames instead. After a disconnect, resume with `transcript_since`; when the server's op journal cannot cover the gap — REST catch-up returns `complete: false` — do a full refresh. The REST counterparts are `GET .../transcript` (turn-paged) and `GET .../transcript/ops?since_seq=` (op-batch catch-up).
542
616
 
543
617
  ## Binary and streaming endpoints
544
618
 
@@ -1,6 +1,6 @@
1
1
  # Node.js SDK
2
2
 
3
- Kiki does not currently publish an SDK to a public npm registry. To integrate Kiki into your own application, use one of these supported protocol surfaces:
3
+ Kiki has no published SDK on npm. To integrate Kiki into your own application, use one of these protocol surfaces:
4
4
 
5
5
  | Surface | When to use | Reference |
6
6
  | --- | --- | --- |
@@ -8,4 +8,4 @@ Kiki does not currently publish an SDK to a public npm registry. To integrate Ki
8
8
  | MCP | Let external tools and agents call Kiki | [Model Context Protocol](./mcp.md) |
9
9
  | ACP | Editor and IDE clients | [ACP](./acp.md) |
10
10
 
11
- The Kiki repository also contains a TypeScript client (`@kiki/klient`, marked as a `private` package) for development and contributions inside the monorepo; this page will grow into full SDK documentation once it forms a public release contract.
11
+ The repository also contains a TypeScript client (`@kiki/klient`) used by Kiki's own tests and tooling. It is not published, so do not depend on it from your own code.
@@ -1,20 +1,24 @@
1
1
  # 配置文件
2
2
 
3
- Kiki 把所有长期偏好写进 `~/.kiki/` 下的 TOML(一种结构清晰的纯文本配置格式)文件——比如使用哪个模型、填哪个 API 密钥、Agent 每轮最多跑几步。保存后会保留到下次启动;`config.toml` 与供应商凭证也会在 Kiki 运行中自动重载。Agent 与运行时设置放在 `config.toml`,供应商凭证放在独立的 `credentials.toml`,终端界面与客户端偏好(主题、编辑器、通知、自动更新)放在配套的 `tui.toml`。
3
+ Kiki 的长期偏好保存在 TOML(结构清晰的纯文本格式)文件里,分布在三处,改之前值得先分清:
4
4
 
5
- 默认位置:`~/.kiki/config.toml`,首次运行时自动创建。供应商凭证放在 `~/.kiki/credentials/credentials.toml`,详见 [供应商凭证](#供应商凭证)。
5
+ | 文件 | 存放内容 |
6
+ | --- | --- |
7
+ | `~/.kiki/config.toml` | Agent 与运行时设置,以及模型和供应商定义 |
8
+ | `~/.kiki/credentials/credentials.toml` | API 密钥、OAuth 令牌与 MCP 凭据 |
9
+ | `~/.kiki/tui.toml` | 终端侧偏好:主题、编辑器、通知、自动更新 |
10
+
11
+ `config.toml` 在首次运行时创建。保存的偏好会保留到下次启动,运行中 Kiki 会同时监听 `config.toml` 和凭证文件。
6
12
 
7
13
  ## 配置文件位置
8
14
 
9
- CLI 从 `~/.kiki/config.toml` 读取配置。如需把数据目录迁移到别处,可用 `KIKI_HOME` 环境变量覆盖:
15
+ 要把整个数据目录换到别处,设置 `KIKI_HOME` 环境变量:
10
16
 
11
17
  ```sh
12
18
  export KIKI_HOME=/path/to/kiki-home
13
19
  ```
14
20
 
15
- 此时配置文件路径变为 `$KIKI_HOME/config.toml`。无论目录在哪里,文件名固定是 `config.toml`。
16
-
17
- 覆盖数据目录后,供应商凭证路径为 `$KIKI_HOME/credentials/credentials.toml`。`credentials/` 目录还存放 OAuth 与 MCP 凭据。
21
+ 配置文件随之变为 `$KIKI_HOME/config.toml`——无论目录在哪,文件名始终是 `config.toml`——凭证在 `$KIKI_HOME/credentials/credentials.toml`。
18
22
 
19
23
  ::: tip
20
24
  TOML 字段名一律用下划线(snake_case),如 `default_model`、`max_context_size`。字段名里若含 `.`,需用引号包住,例如 `[models."gpt-4.1"]`——否则 TOML 会把 `.` 解释为嵌套表分隔符。
@@ -22,7 +26,7 @@ TOML 字段名一律用下划线(snake_case),如 `default_model`、`max_co
22
26
 
23
27
  ## 配置修改如何生效
24
28
 
25
- Kiki 会在运行它的主机上监听 `config.toml` 和 `credentials/credentials.toml`。保存合法修改、文件内容稳定后会自动重载;修改请求并发规则不需要重启或执行 `/reload`。定期检查会补上遗漏的文件通知,尚未写完的内容会稍后重试;解析失败时保留上一份有效配置,并给出诊断。请修复诊断中指明的文件,不要从设置页覆盖它。
29
+ Kiki 在运行时监听 `config.toml` 和 `credentials/credentials.toml`。保存合法修改后内容稳定即自动重载,改请求并发规则不需要重启或执行 `/reload`;定期检查会补上遗漏的文件通知,尚未写完的保存会被重试。解析失败时保留上一份有效配置并给出诊断,请修复诊断指名的文件,不要从设置页覆盖它。
26
30
 
27
31
  文件重载与设置生效的时机不同:
28
32
 
@@ -105,6 +109,26 @@ command = "node ~/.kiki/hooks/check-bash.mjs"
105
109
  timeout = 5
106
110
  ```
107
111
 
112
+ ## 外部 harness 默认设置
113
+
114
+ 外部 harness(实际运行 Agent 的程序)可以不选 Kiki profile,使用自身配置。main agent 的 `execution` 选择通过 `[agent_executor_overrides.<id>.defaults]` 保存可复用的 Kiki 覆盖值;会话覆盖优先于 profile 显式声明,profile 显式声明优先于这些设置,仍未设置的值由 harness 自己决定。原生执行保持 Kiki 既有的模型与 profile 默认行为。
115
+
116
+ ```toml
117
+ [agent_executor_overrides."claude-acp".defaults]
118
+ # 可选:填写 harness 自己的模型 ID,而非 Kiki 原生模型 alias。
119
+ model_alias = "YOUR_HARNESS_MODEL"
120
+ thinking_effort = "high"
121
+ permission_mode = "auto"
122
+ kiki_context = []
123
+ allow_kiki_subagents = false
124
+ ```
125
+
126
+ 省略模型、思考强度与权限字段,就交给 harness 自己选择。`kiki_context` 接受 `memory`、`board`、`cron`、`threads`、`history`、`hooks`;`[]` 明确关闭全部组,`allow_kiki_subagents = false` 明确关闭委派。在这条 execution 路径中,profile 未声明的字段继承 harness 设置。修改设置不会改写已有绑定;重新选择 execution 或显式重建上下文才会采用新值。
127
+
128
+ `defaults.executor_prompt` 接受 `delivery`(`append`、`replace`、`preamble`)、`body`、`append`、`include` 和 `per_engine.<id>` 覆盖。这些字段与所选 profile 逐项合并,因此只设置 `delivery` 不会抹掉默认正文。省略 `include` 会继承,`include = []` 关闭附加段落。没有有效的 `executor_prompt.body` 时才使用 profile 正文。外部 execution 不会自动添加 Kiki cognition 或共享提示字段;需要哪些字段,在 `include` 中显式选择。
129
+
130
+ 通过 [REST API](../server/rest-api.md#会话) 修改时,向 `POST /api/config` 发送 `agent_executor_overrides` 对象。defaults 字段的 JSON `null` 删除该项保存值,`defaults: null` 删除整个默认设置块。TOML 不支持 `null`,直接编辑文件时删除对应键即可。`bin_path`、`home_dir`、`env`、`args` 等启动设置与 defaults 分开保存。
131
+
108
132
  ## 连续性提醒词表
109
133
 
110
134
  Kiki 会提醒 Agent 记录持续有效的指示、查找早先决定、更新未完成待办,并在上下文压缩前后保留工作笔记。提醒追加到对话历史,不会自动保存记忆或修改系统提示词。进度提醒需要 `TodoList`;`TodoList` 不可用但记忆访问已获批准时,记录指示和回看历史提醒仍可工作。
@@ -127,7 +151,7 @@ api_key = "YOUR_API_KEY"
127
151
 
128
152
  ### 迁移已有密钥
129
153
 
130
- 如果根目录还留有旧版 `credentials.toml`,启动时会把其内容原样迁入 `credentials/credentials.toml`;迁移成功前仍可从旧位置读取。如果新旧两处内容不同,Kiki 会停止而不擅自选择,请核对两份文件后重试。如果旧版 `config.toml` 里仍留有供应商凭证,启动时会把它们迁入 `credentials/credentials.toml`,并重写 `config.toml`(不再包含这些凭证)。原 `config.toml` 会以唯一的 `config.toml.bak-<YYYY-MM-DD>-<uuid>` 名称保留为备份,便于查看或恢复。备份仍含原来的明文密钥;确认迁移成功后,若不再需要备份,请将其删除。成功迁移后重复加载不会另建备份,也不会改动已迁出的凭证。如果两个文件的同一密钥路径有不同的值,迁移会停止并要求人工核对,不会擅自选择其一;失败或中断的迁移也可能留下需检查的备份。
154
+ 根目录还留有旧版 `credentials.toml` 时,启动会把内容原样迁入 `credentials/credentials.toml`,迁移成功前仍可从旧位置读取;两处内容不同则停止而不擅自选择,请核对后重试。旧版 `config.toml` 里仍留有凭证的,启动会把它们迁入 `credentials/credentials.toml` 并重写 `config.toml`,原文件以唯一的 `config.toml.bak-<YYYY-MM-DD>-<uuid>` 保留为备份。备份里仍是明文密钥,核对完不再需要就删掉它。迁移成功后重复加载不会再建备份,也不会改动已迁出的凭证;同一密钥路径在两个文件里值不同时迁移会停下等你人工处理,中断或失败可能留下需要检查的备份。
131
155
 
132
156
  ### 文件权限
133
157
 
@@ -159,6 +183,7 @@ api_key = "YOUR_API_KEY"
159
183
  | `retry` | `table` | — | 按错误定制的单步重试策略 → [`retry`](#retry) |
160
184
  | `request_governance` | `table` | 无规则 | 原生模型请求并发与等待预算 → [`request_governance`](#request-governance) |
161
185
  | `token_counting` | `table` | — | 对外上报哪种上下文 token 计数 → [`token_counting`](#token-counting) |
186
+ | `transcript_memory` | `table` | — | 服务端转录历史的内存预算 → [`transcript_memory`](#transcript-memory) |
162
187
  | `background` | `table` | — | 后台任务运行参数 → [`background`](#background) |
163
188
  | `subagent` | `table` | — | subagent 运行默认值与限额 → [`subagent`](#subagent) |
164
189
  | `agents` | `table` | — | 委派说明默认值 → [`agents`](#agents) |
@@ -176,7 +201,7 @@ api_key = "YOUR_API_KEY"
176
201
  | `identity` | `table` | — | 自定义 Agent 身份 → [`identity`](#identity) |
177
202
  | `prompt` | `table` | `{}` | 提示词字段覆写与自定义变量 → [`prompt`](#prompt) |
178
203
 
179
- 以下各节对 `providers`、`models`、`thinking`、`loop_control`、`retry`、`token_counting`、`background`、`subagent`、`agents`、`thread_communication`、`mcp`、`tools`、`image`、`session_title`、`experimental`、`nb_search`、`permission`、`interaction`、`prompt` 等嵌套表逐一展开。
204
+ 以下各节对 `providers`、`models`、`thinking`、`loop_control`、`retry`、`token_counting`、`transcript_memory`、`background`、`subagent`、`agents`、`thread_communication`、`mcp`、`tools`、`image`、`session_title`、`experimental`、`nb_search`、`permission`、`interaction`、`prompt` 等嵌套表逐一展开。
180
205
 
181
206
  ## `providers`
182
207
 
@@ -243,9 +268,13 @@ max_context_size = 1048576
243
268
 
244
269
  ### 显式迁移旧版模型参数
245
270
 
246
- 打开**设置 → 模型与提供商 → 可用模型 → 旧版模型参数迁移**,点击**预览迁移**可只读检查拟复制的字段,不会写文件。预览仅列模型别名、参数名、需人工核对的原因、修订标识及备份标识;不返回配置原文、凭据值或备份内容。模型参数不会在启动时自动迁移。在没有歧义的情况下,迁移会把旧版 `request_params.temperature`/`top_p` 和 `max_completion_tokens`/`service_tier` 复制进模型的 `parameters` 表。歧义值及冲突项留待人工处理;**旧字段不会被删除**,请先核对预览,不要假定旧字段的行为已经改变。
271
+ 旧版配置把 `temperature` / `top_p` 和 `max_completion_tokens` / `service_tier` 放在不同位置。**设置 → 模型与提供商 → 可用模型 → 旧版模型参数迁移** 可以把它们复制到某个模型的 `parameters` 表里。
272
+
273
+ 先点**预览迁移**:它只读列出模型别名、参数名、需要你人工判断的原因、一个修订标识和将使用的备份名称,不写任何文件。没有歧义的值会被复制;有歧义或冲突的值留给你决定。你原有的字段不会被删除,所以请读预览,而不是假设配置已经变了。
247
274
 
248
- 点击**应用预览的改动**并再次确认后,服务器先在 `config.toml` 旁以唯一的 `config.toml.generation-backup-<uuid>` 名称逐字备份原文件,再有条件地写入新配置。如果配置已变化或预览过期,则拒绝写入,不覆盖新修改。备份可能包含原始密钥,请像保护 `config.toml` 和 `credentials.toml` 一样保护它;服务器配置存储在支持的平台上要求仅文件所有者可读写,但不要假定各平台权限完全相同。面板列出备份标识;**恢复备份**还需单独确认,且只有当前配置仍逐字匹配该备份对应的迁移结果、预览修订仍有效时才会恢复。之后的修改只在配置字节不同的情况下阻止恢复;目前仅凭配置字节计算的修订标识无法发现配置最终回到完全相同字节的修改序列,此时旧备份仍可能撤销一次更新的同内容迁移。在发生后续修改后,不要使用旧备份恢复。备份和配置是两个文件,并非一次跨文件的崩溃原子事务。配置 CAS 明确拒绝过期修订时,只有新备份仍匹配原始字节才会删除;写入结果无法确认时,系统会保留备份和当前配置供核对,而不会冒险回滚另一写者的改动。在 Windows 上,底层原子写会先尝试通过重命名覆盖;若遭遇 `EPERM` 竞争,可能退回先删除目标文件再重命名,读者会短暂看不到配置,且在该空窗崩溃可能导致目标缺失。遇到不确定的失败,请先检查两个文件及备份再重试。
275
+ 再点**应用预览的改动**:它会先在 `config.toml` 旁以唯一的 `config.toml.generation-backup-<uuid>` 逐字备份原文件,然后才动配置;如果配置在预览之后被改过,它拒绝写入。该备份包含你的原始密钥,请像保护 `config.toml` 和 `credentials.toml` 一样保护它,不再需要时就删掉。
276
+
277
+ **恢复备份**需要单独一次确认,而且只有当前配置仍与该备份产生的版本逐字一致时才会恢复;期间任何其他编辑都会挡住它。迁移后尽早恢复:修订标识用的是逐字节比较,所以之后若某次编辑恰好让配置回到完全相同的字节,系统发现不了,旧备份就可能撤销更新的工作。
249
278
 
250
279
  ### 模型别名解析
251
280
 
@@ -341,13 +370,13 @@ steering = "cognition/flash-steering.md"
341
370
 
342
371
  `~/.kiki/cognition/flash-anchor.md`:
343
372
 
344
- ```
373
+ ```text
345
374
  You are a helpful software engineer assistant.
346
375
  ```
347
376
 
348
377
  `~/.kiki/cognition/flash-steering.md`:
349
378
 
350
- ```
379
+ ```text
351
380
  Router: classify this task (build or fix) now, then adopt the matching style — build: direct production; fix: inspect-first. Let's first understand the problem and devise a plan; then let's carry out the plan and act.
352
381
  ```
353
382
 
@@ -473,6 +502,18 @@ match = '^provider\.'
473
502
  retry = false
474
503
  ```
475
504
 
505
+ ## `transcript_memory`
506
+
507
+ `transcript_memory` 控制服务端把多少转录历史留在内存里。三个字段都是可选的:省略即使用默认值。
508
+
509
+ | 字段 | 类型 | 默认值 | 说明 |
510
+ | --- | --- | --- | --- |
511
+ | `tail_turns` | 正整数 | `20` | 每个 agent 常驻保留多少个已结束的 turn |
512
+ | `max_agent_bytes` | 正整数 | `16777216`(16 MiB) | 每个 agent 的常驻字节预算,即留在内存里的量。更早的 turn 会按需从磁盘读取 |
513
+ | `max_detail_cache_bytes` | 非负安全整数 | `268435456`(256 MiB) | 单次完整正文读取的最大缓存量。`0` 关掉这个额外缓存槽,内容照样读取,只是不留在该缓存里。改动后的值在下一次缓存准入或淘汰时生效;调低会淘汰放不下的内容,不会取消正在进行中的读取 |
514
+
515
+ 这些是服务端内存预算,不是读取上限。调低它们会减少内存占用,可能增加从磁盘重复读取的次数。
516
+
476
517
  ## `token_counting`
477
518
 
478
519
  `token_counting` 决定对外上报的上下文 token 计数——即上下文大小显示所基于的值。内部逻辑(自动压缩触发、预算、超限退避)始终同时使用供应商实测与估算,不受本配置影响。
@@ -668,14 +709,14 @@ disabled = ["EnterPlanMode", "ExitPlanMode", "mcp__github__*"]
668
709
 
669
710
  `nb_search` 配置 Kiki 内置的搜索与抓取模块,也就是 `WebSearch` 和 `FetchURL` 工具背后的能力。该模块是 Kiki 的一部分:随产品一起安装,不需要额外的安装步骤;其中的 provider 实例、凭证槽、lane 和默认 fetch chain 都已经内置。
670
711
 
671
- 默认的 `WebSearch` lane 是 `github.repositories`,不需要凭证或配置,但只检索 GitHub 仓库。查阅代码库文档时可显式选择 `context7.docs`;它返回 typed 文档上下文,不能与结果型 lane 组合。`duckduckgo.search` 是可选的免密钥通用网页 lane,但其公共 HTML 端点可能返回 CAPTCHA;如需更稳定的通用检索,请配置其他 provider 的凭证并覆盖 `defaults.search_lane`。字段名与合并行为遵循该模块的规范配置约定,与独立的 nb-search CLI 共用同一份 schema,因此已有的 nb-search 配置文件可以直接沿用。
712
+ 默认的 `WebSearch` lane 是 `duckduckgo.search`,无需注册、凭证或配置即可检索通用网页。公共 HTML 端点可能触发验证或限流;等待后再试,或显式选择其他已配置的来源。这些失败会报告错误,不会伪装为空结果,也不会静默切换到收费 provider。已配置的默认值和显式 lane 选择优先。仓库检索或代码库文档可显式选择 `github.repositories`、`context7.docs`;后者返回 typed 文档上下文,不能与结果型 lane 组合。字段名与合并行为遵循该模块的规范配置约定,与独立的 nb-search CLI 共用同一份 schema,因此已有的 nb-search 配置文件可以直接沿用。
672
713
 
673
714
  | 字段 | 类型 | 必填 | 说明 |
674
715
  | --- | --- | --- | --- |
675
716
  | `provider_instances` | `table` | 否 | 命名 provider 实例,包含 `provider_id`、`enabled`、可选的 `credential_slot_id` / `base_url`、`key_strategy`(`round-robin` 或 `priority`)、`balance_ttl_ms`(60,000–86,400,000 毫秒)及 provider 专属 `options` |
676
717
  | `credential_slots` | `table` | 否 | 命名凭据槽,只包含 `provider_id` 和 `env` 中的环境变量名 |
677
718
  | `lanes` | `table` | 否 | 命名 operation lane,包含 `provider_instance_id`、`operation_id`、`latency`、`cost` 和可选 `evidence_groups` |
678
- | `defaults.search_lane` | `string` | 否 | 内置默认值为 `github.repositories`(仅仓库);通用网页检索需要覆盖。显式删除默认值且不指定 lane 时,`WebSearch` 仍会拒绝运行 |
719
+ | `defaults.search_lane` | `string` | 否 | 内置默认值为免密钥的 `duckduckgo.search`(通用网页);已配置的默认值优先。显式删除默认值且不指定 lane 时,`WebSearch` 仍会拒绝运行 |
679
720
  | `defaults.fetch_chain` | `array<table>` | 否 | URL 默认先用 `direct.fetch`,失败时尝试免密钥的 `jina.reader`;直连成功但内容无用时,需显式配置 `execution.fetch.quality` 规则才能触发回退 |
680
721
  | `execution` | `table` | 否 | provider 调用数、并发、重试、超时、内联输出、响应大小、重定向、内容长度和质量预算 |
681
722
 
@@ -54,6 +54,8 @@ $KIKI_HOME (默认 ~/.kiki)
54
54
  │ └── <key>-<suffix>.json
55
55
  ├── sessions/ # 会话数据(详见下文)
56
56
  │ └── <workDirKey>/<sessionId>/
57
+ ├── server/
58
+ │ └── events/ # 有界的客户端事件重放日志
57
59
  ├── bin/
58
60
  │ ├── rg # Grep 使用的托管 ripgrep 二进制(Windows 为 rg.exe)
59
61
  │ └── fd # 文件引用使用的托管 fd 二进制(Windows 为 fd.exe)
@@ -68,7 +70,7 @@ $KIKI_HOME (默认 ~/.kiki)
68
70
  数据根下的文件各有用途,大部分由 CLI 自动管理:
69
71
 
70
72
  - **`config.toml`**:主运行时配置,存放供应商、模型、循环控制等用户级设置。供应商 API 密钥放在 `credentials/credentials.toml`。详见[配置文件](./config-files.md)。
71
- - **`credentials/credentials.toml`**:存放供应商凭证,例如各供应商的 `api_key`。同一条 TOML 路径上这里的值覆盖 `config.toml`;旧版 `config.toml` 里遗留的凭证会在首次加载时迁入该文件,原文件保留为 `config.toml.bak-<date>`。旧版根目录 `credentials.toml` 会原样迁入该目录;如果两处文件内容不同,迁移会停止,等待核对。在平台支持的前提下,Kiki 以仅属主可读写的权限(`0o600`)写入该文件。详见[供应商凭证](./config-files.md#供应商凭证)。
73
+ - **`credentials/credentials.toml`**:存放供应商凭证,例如各供应商的 `api_key`。同一条 TOML 路径上这里的值覆盖 `config.toml`;旧版 `config.toml` 里遗留的凭证会在首次加载时迁入该文件,原文件保留为 `config.toml.bak-<date>`——该备份仍是明文密钥,核对完迁移结果就删掉它。在平台支持的前提下,Kiki 以仅属主可读写的权限(`0o600`)写入该文件。详见[供应商凭证](./config-files.md#供应商凭证)。
72
74
  - **`tui.toml`**:终端界面客户端偏好,例如主题、编辑器、通知和状态栏。
73
75
  - **`AGENTS.md`**:用户级 Agent 指令。该文件会随 `KIKI_HOME` 移动,并与工作区根目录指令合并;工作区的 `.kiki/AGENTS.md` 可以覆盖它。
74
76
  - **`mcp.json`**:用户级 MCP server 声明,启动时与项目内的 `.kiki/mcp.json` 合并加载。详见 [MCP](../server/mcp.md)。
@@ -76,7 +78,7 @@ $KIKI_HOME (默认 ~/.kiki)
76
78
  - **`cognition/`**:`[models."<alias>".cognition]` 引用的提示词文件,路径相对于数据根目录。详见[模型认知](./config-files.md#模型认知)。
77
79
  - **`hooks/`**:`[[hooks]]` command 路径引用的脚本文件(如 `node ~/.kiki/hooks/check-bash.mjs`)。详见 [Hooks](../customization/hooks.md)。
78
80
  - **`plugins/installed.json`**:记录已安装的 plugin、每个 plugin 的启用状态,以及通过 `/plugins` 或 `/plugins mcp disable|enable` 修改的 MCP server 能力状态。本地路径和 zip URL 安装的文件会复制到 `plugins/managed/<id>/`。详见 [Plugins](../customization/plugins.md)。
79
- - **`credentials/`**:权限受限的凭据目录,请求权限为目录 `0o700`、文件 `0o600`。托管供应商的 OAuth 登录态存为 `credentials/<name>.json`,MCP server 凭据存在 `credentials/mcp/` 子目录下。OAuth 凭据写入使用原子流程(tmp → fsync → rename)防止写损。
81
+ - **`credentials/`**:权限受限的凭据目录,请求权限为目录 `0o700`、文件 `0o600`。托管供应商的 OAuth 登录态存为 `credentials/<name>.json`,MCP server 凭据存在 `credentials/mcp/` 子目录下。在 Windows 上,要靠这个目录挡住其他本机用户,请自行核查文件及其父目录的 ACL。
80
82
  - **`workspaces.json` 与 `workspaces/`**:分别记录已注册工作区,以及新会话未指定工作区时 Kiki 创建的项目目录。每个自动创建的会话使用独立目录;这里是工作文件,与 `sessions/` 下的会话历史不同。
81
83
 
82
84
  ## 会话数据
@@ -94,14 +96,20 @@ $KIKI_HOME (默认 ~/.kiki)
94
96
  - **`tasks/`**:后台任务持久化——`tasks/<task_id>.json` 保存状态/pid/退出码,`tasks/<task_id>/output.log` 保存输出。
95
97
  - **`cron/`**:定时任务持久化,用 `kiki --session` 恢复会话时重新加载到调度器。详见[定时任务](../reference/tools.md#定时任务)。
96
98
 
99
+ ## 服务端事件重放
100
+
101
+ `server/events/<sessionId>.jsonl` 保存客户端重连时使用的持久事件,不是完整会话历史。Kiki 自动保留会话的重放窗口(默认 1000 条)。活跃 writer 的日志超过两个窗口时会收缩为一个窗口,关闭时也收缩为一个窗口;这里限制的是事件条数,不是字节数,超大事件仍会完整保存。
102
+
103
+ 旧日志在新 writer 首次追加事件时收缩。浏览未激活的会话只读取水位,不会改写日志;因此,未再次写入的旧日志和已删除会话的遗留日志仍需显式清理。替换失败时会保留原持久日志并记录警告,后续写入或 writer 关闭时重试空间回收。
104
+
105
+ 这项保留策略不会删除 `sessions/`、Agent 的 `wire.jsonl` 或媒体原件。游标超出保留窗口的客户端会通过快照/reset 恢复,而不是补播旧事件序列,见 [断线恢复](../server/rest-api.md#断线恢复)。如需手动清理旧日志,先停止所有使用该数据根目录的 Kiki 服务,再仅清理 `server/events/` 并重启。不要在 writer 运行时删除或截断这些日志。
106
+
97
107
  ## 内置工具缓存
98
108
 
99
109
  `Grep` 工具第一次需要 ripgrep 时,CLI 可自动下载 `rg` 并缓存到 `bin/rg`(Windows 为 `bin/rg.exe`)。终端界面的文件引用补全使用 `fd`;需要时 CLI 会在后台自动下载并缓存到 `bin/fd`(Windows 为 `bin/fd.exe`)。之后的运行会直接复用缓存的二进制。`rg` 优先使用系统 `PATH`,再使用缓存;`fd` 优先检查托管缓存,再回退到系统 `fd` / `fdfind`。删除 `bin/` 目录会在下次需要时触发重新下载。
100
110
 
101
111
  ## 日志
102
112
 
103
- 日志文件名 `kimi-code.log` 沿用自 Kiki 上游项目的历史命名,保持不变。
104
-
105
113
  - **`logs/kimi-code.log`**(全局):记录启动、登录、导出等跨会话事件。
106
114
  - **`<sessionDir>/logs/kimi-code.log`**(会话级):记录单个会话内的诊断事件。
107
115
 
@@ -24,9 +24,9 @@ export KIKI_HOME="/path/to/custom/kiki"
24
24
 
25
25
  > 确保目录可写。多个 `kiki` 实例共用同一个 `KIKI_HOME` 会共享配置和凭证。
26
26
 
27
- 在 macOS 和 Linux 上,共享运行时会在这个目录里保留本地端点,得到的路径长度有随平台变化的上限。家目录仍然过长时会报配置问题,并给出实际长度、该平台的上限和修法——换用更短的 `KIKI_HOME`。这是诊断,不是静默搬迁:Kiki 不会替你搬移数据,也不会自行改用别的目录;短 symlink 也无法缩短上限实际度量的真实路径。
27
+ 在 macOS 和 Linux 上,共享运行时会在这个目录里保留本地端点,得到的路径长度有随平台变化的上限。路径仍然过长时,Kiki 会报出配置问题,并给出实际长度、该平台的上限和修法:换用更短的 `KIKI_HOME`。Kiki 不会替你搬移数据,短 symlink 也无法缩短上限实际度量的真实路径。
28
28
 
29
- 在 macOS 或 Linux 上升级后,请先退出所有仍在使用同一 `KIKI_HOME` 的进程,再用新版本启动。旧版本与新版本不会共用同一个运行中的运行时,Kiki 也不会替你迁移旧的那个。Windows 不受影响——那里的运行时使用命名管道,不需要这一步。
29
+ 在 macOS 或 Linux 上升级后,请先退出所有仍在使用同一 `KIKI_HOME` 的进程,再用新版本启动——新旧版本不会共用同一个运行中的运行时。Windows 不受影响:那里的运行时使用命名管道。
30
30
 
31
31
  数据目录的完整结构见[数据路径](./data-locations.md)。
32
32
 
@@ -36,9 +36,7 @@ export KIKI_HOME="/path/to/custom/kiki"
36
36
 
37
37
  ## 供应商凭证键
38
38
 
39
- 下面这些键名不是直接从 shell 读取的——它们是写在 `[providers.<name>.env]` 子表里、作为 `api_key` / `base_url` 备用来源的键名。CLI 只从配置文件读取,不从 `process.env` 读取。
40
-
41
- 这样设计是为了让你保留熟悉的键名写法,同时把密钥挡在 `config.toml` 之外:密钥键放进配套的 `credentials.toml`,非密钥的 `*_BASE_URL` 键留在 `config.toml`。
39
+ 下面这些键名不从 shell 读取。它们写在 `[providers.<name>.env]` 子表里,作为 `api_key` / `base_url` 的备用来源。密钥键放进配套的 `credentials.toml`,非密钥的 `*_BASE_URL` 键留在 `config.toml`。
42
40
 
43
41
  ```toml
44
42
  # ~/.kiki/credentials/credentials.toml
@@ -170,7 +168,7 @@ kiki
170
168
 
171
169
  subagent 并发没有环境变量覆盖。请在 [`[subagent]`](./config-files.md#subagent) 中配置 `max_direct_children` 和 `max_total_subagents`,默认值分别为 `16` 和 `0`(不限)。
172
170
 
173
- `[subagent].default_model` 仅在派发参数与生效 pin 都未指定模型时显式提供兜底;它不会继承调用方,也不能绕过硬模型规则。`[subagent].default_effort` 仍已移除:使用档位 pin 或所选模型的默认值(见 [`subagent`](./config-files.md#subagent))。宿主强制环境值同样不能绕过 profile 硬列表。
171
+ `[subagent].default_model` 只在派发参数与生效 pin 都未指定模型时提供兜底。它不会继承调用方的模型;它和宿主强制的环境值都不能绕过 profile 的硬模型规则。`[subagent].default_effort` 已移除、不再读取,启动时会给出警告——请改用 profile、route 或 caller lease 上的 effort pin,或者交给所选模型使用它自己的默认值。
174
172
 
175
173
  ## 诊断日志
176
174
 
@@ -77,28 +77,27 @@ CLI 从 `KIKI_HOME`(默认 `~/.kiki`)读取用户级配置,并从 `<项目
77
77
 
78
78
  ## 模型与 effort 解析
79
79
 
80
- 在原生 executor 上,先确定本次派发使用的模型,再解析其 thinking effort。Route 与 caller lease 的 pin 提供软默认值;偏离 pin、显式 `preferred_*` 或 `discouraged_models` 建议时,仅在绑定满足硬规则且可执行的前提下产生 advisory。`allowed_models`、`deny_models`、`allowed_efforts` 在每个 profile、lease、树策略与匹配 model-profile 作用域都为硬规则。机器级 deny 与 provider / executor 能力检查也仍是硬限制。
80
+ 先确定本次派发使用的模型,再解析该模型的 thinking effort。Route 与 caller lease 上的 pin 是可以被覆盖的默认值;`allowed_models`、`deny_models`、`allowed_efforts` 在每个 profile、lease、树策略与匹配 `model_profiles` 作用域都是硬限制——对 subagent 而言,越界会拒绝绑定、人工切换与恢复;在主会话中则以你的选择为准,越界只警示。模型本身不支持的值则无论哪种情况都会报错。
81
81
 
82
- Thinking effort 按以下顺序解析,解析后仍须满足全部硬档位列表:
82
+ profile 绑定时——新建主会话、新建 subagent、切换模型,或原生 `AgentRun` 派发——先从该角色自身的来源取出请求的 effort,再对照所绑定的模型解析:
83
83
 
84
- 1. 显式 `effort` 优先于默认值,但不能覆盖硬约束。Pin 或偏好偏离产生 advisory;列表外或不支持的档位被拒绝。
85
- 2. 未显式传入时,route 或 caller lease 默认值优先。
86
- 3. 匹配的 `model_profiles` 条目。
87
- 4. profile 顶层的 `thinking_effort`,但仅当所选模型匹配 profile 的默认 `model_alias`。
88
- 5. `[models."<alias>"].overrides.default_effort`。
89
- 6. 所选模型的 `default_effort`,包括 `[models."<alias>"].default_effort`。
90
- 7. 全局 `[thinking].effort`。
91
- 8. 两处均未设置默认 effort 时,回退到模型支持档位的中间值或能力默认值。
84
+ 1. 调用时显式传入的 `effort`。
85
+ 2. 主会话中取 persona 或 route 上锁定的 effort;subagent 中取 route 上锁定的 effort,route 未锁定时改用 caller lease 的。两者其后都是匹配的 `model_profiles` 条目,再后是 profile 顶层的 `thinking_effort`。
86
+ 3. 所绑定模型的首选 effort。
87
+ 4. `[models."<alias>"].overrides.default_effort`。
88
+ 5. 模型自身的 `default_effort`。
92
89
 
93
- `[thinking].enabled` 为 `false` 时,未固定的 effort 会解析为 Off,除非模型覆盖项另有设置。`always_thinking` 模型无法关闭;其兜底档位按模型默认值优先、全局默认值次之的顺序选择。
90
+ 如果以上都取不到值,或解析出的 effort 不被该模型支持,绑定会以配置错误失败,而不是悄悄替你挑一个。完全没有配置模型时,绑定会同时要求提供模型和 effort。只要 route、lease、profile pin 或模型默认里已经有可用值,就不必每次都传 effort;只有全都取不到时才需要,此时配置相应的 pin 或在本次调用里提供 `effort`。
94
91
 
95
- 没有 `model_alias` 的 profile 只跳过顶层 effort 这一层,不会 fail closed;解析会继续使用下一层默认值。普通 resume 省略模型参数时保持当前绑定;alias 解析到同一规范模型时为 no-op。只修改 `effort` 时保留已保存的模型;切换到不同规范模型且省略 `effort` 时,按新模型重新解析 effort。恢复时切换到不同规范模型仍需 `allow_model_change: true`。既有参数校验以及外部 executor 自行完成的校验继续生效。
92
+ 这些规则只作用于 profile 绑定。保留既有有效绑定的普通 resume 不会重新计算,因此早先保存的 effort 继续有效。只修改 `effort` 时保留已保存的模型;resume 时切换模型仍需 `allow_model_change: true`。
93
+
94
+ 不经过 profile 绑定的路径保持原样:全局 `[thinking]` 仍提供兜底,`[thinking].enabled = false` 在这些路径上仍会把未固定的 effort 解析为 Off。
96
95
 
97
96
  ## 提示词字段优先级
98
97
 
99
- 提示词文案字段使用独立的优先级链,不走普通的 CLI / 配置优先级。从低到高依次为全局 `[prompt.overrides]`、模型 `[models."<alias>".prompt_overrides]`、Agent 或 `SYSTEM.md` Frontmatter 的 `prompt_overrides`,以及匹配的 `model_profiles[].prompt_overrides`——共 4 个优先级层。Agent 文件与 `SYSTEM.md` 是共用链中同一位置的两个配置表面,因此合计 5 个受支持的表面。
98
+ 提示词文案字段使用独立的优先级链。从低到高:全局 `[prompt.overrides]`、模型 `[models."<alias>".prompt_overrides]`、Agent 或 `SYSTEM.md` Frontmatter 的 `prompt_overrides`,然后是匹配的 `model_profiles[].prompt_overrides`。Agent 文件与 `SYSTEM.md` 位于同一层,所以 4 层里一共 5 个配置表面。
100
99
 
101
- 每个表面都接受 `files` 与 `fields`。文件从 Kiki 主目录读取,按列表顺序应用,随后由同一表面的内联字段覆盖。高层未声明的字段继承低层值,字段值绝不会拼接。外部文件 schema、常用字段示例、turn 快照,以及从已移除 `prompt.shared` / `prompt.tools` 键迁移的方法见 [`prompt`](./config-files.md#prompt)。
100
+ 每个表面都接受 `files` 与 `fields`。文件从 Kiki 主目录读取,按列表顺序应用,随后由同一表面的内联字段覆盖。高层未声明的字段继承低层值,字段值绝不会拼接。外部文件 schema、常用字段示例,以及从已移除的 `prompt.shared` / `prompt.tools` 键迁出的方法见 [`prompt`](./config-files.md#prompt)。
102
101
 
103
102
  ## 典型场景
104
103
 
@@ -31,7 +31,7 @@ Kiki 可以同时连接多家模型提供商。API 密钥是适用范围最广
31
31
 
32
32
  添加时有两条路径:
33
33
 
34
- - **Known third-party provider**:从 [models.dev](https://models.dev/) 拉取模型目录,选供应商 → 输入 API 密钥 → 选默认模型。目录未声明协议类型的供应商(如 xai、openrouter 这类厂商专用 SDK)会按 OpenAI 兼容协议导入并显示 "guessed" 提示;目录没有可用端点时会先弹出 base URL 输入框;Amazon Bedrock / Cohere 等专有协议和无法识别的显式协议会被拒绝导入。已下线(deprecated)和 alpha 状态的模型不会出现在导入列表中。如果公共目录不可达,CLI 会回退到内置目录快照,离线或网络受限环境下也能完成导入
34
+ - **Known third-party provider**:从 [models.dev](https://models.dev/) 目录里选供应商 → 输入 API 密钥 → 选默认模型。目录没写明协议的供应商(xai、openrouter 这类厂商专用 SDK)会按 OpenAI 兼容协议导入,并标为 guessed;目录里没有可用端点时,会先让你填 base URL。Amazon Bedrock / Cohere 这类专有协议无法导入。已下线(deprecated)和 alpha 状态的模型不会出现在导入列表中。公共目录不可达时,Kiki 会回退到内置目录快照,离线也能完成导入。
35
35
  - **Custom registry (api.json)**:粘贴自定义 registry 地址和 Bearer token,本次显式导入会创建 `providers` / `models` 条目。后续启动不会同步上游新增、删除供应商或模型元数据变化。
36
36
 
37
37
  ### 获取模型建议
@@ -42,7 +42,7 @@ Kiki 可以同时连接多家模型提供商。API 密钥是适用范围最广
42
42
 
43
43
  在 GUI 的 **设置 → 模型与提供商 → 连接服务** 中,**用 API 密钥连接**提供五个协议入口:`openai`、`openai_responses`、`anthropic`、`google-genai`、`vertexai`;也可以按服务名称搜索。搜索 DeepSeek、GLM、Kimi、Ollama、LM Studio 或 OpenRouter,选中结果后会自动填入协议和 base URL。没有匹配结果时,选协议后手填 base URL;之后按需填写密钥并添加模型。
44
44
 
45
- Ollama 和 LM Studio 与其他 OpenAI 兼容服务共用 API 密钥路径,本地服务可能无需密钥。五个快捷入口是 OpenAI、Anthropic、Google Gemini、DeepSeek 和 Moonshot(Kimi)。Kimi 快捷入口沿用下文已有的 `kimi` 通信适配器,不额外增加第六张协议卡片。
45
+ Ollama 和 LM Studio 与其他 OpenAI 兼容服务共用 API 密钥路径,本地服务可能无需密钥。五个快捷入口是 OpenAI、Anthropic、Google Gemini、DeepSeek 和 Moonshot(Kimi)——Kimi 快捷入口配置的就是下文的 `kimi` 供应商。
46
46
 
47
47
  **可用模型**集中展示已配置的模型:按名称或 ID 搜索、查看上下文长度与能力,星标一个模型作为全局默认。提供商还保留自身的默认模型,模型也保留实际发送给上游的 ID。手动填写的 Kimi API 密钥和其他 API 密钥连接一样只获取建议;账号登录则配置其托管模型。
48
48
 
@@ -107,6 +107,8 @@ api_key = "sk-ant-xxxxx"
107
107
 
108
108
  第三方推理模型(DeepSeek、Qwen、One API 等)开箱即用:CLI 自动处理 `reasoning_content` 字段和 `reasoning_effort` 注入。如果你的网关用非标准字段名返回推理内容,在模型别名上设 `reasoning_key` 覆盖。
109
109
 
110
+ 对 `openai` 和 `openai_responses`,当你没有设过输出上限、模型能力也未知时,Kiki 不再自己发输出长度限制——请求里不会带 `max_tokens`、`max_completion_tokens` 或 `max_output_tokens`,由服务端自己的默认决定。你自己设的上限、已知的模型输出能力、session 或 profile 上更紧的限制,以及剩余窗口预算都照常生效;上下文窗口大小本身不被当作输出上限。这个最大值是天花板,不是对回答长度的保证——模型实际返回多少还取决于任务本身和它何时停止——费用按你实际得到的响应计算。
111
+
110
112
  - 默认 `base_url`:`https://api.openai.com/v1`
111
113
  - 凭证键名:`OPENAI_API_KEY`、`OPENAI_BASE_URL`
112
114
 
@@ -180,7 +182,7 @@ api_key = "xxxxx"
180
182
 
181
183
  - 凭证键名:`VERTEXAI_API_KEY` ——写在 `[providers.vertexai.env]` 子表里,并与其他供应商 API 密钥一样存放在 `credentials.toml`;是不走下文 ADC 流程时的 API 密钥来源
182
184
 
183
- 认证走 Google Cloud 标准 ADC 流程(`gcloud auth application-default login` 或 `GOOGLE_APPLICATION_CREDENTIALS` 服务账号 JSON),这部分与 Kimi Code 无关。**项目 ID 和区域必须写在 `[providers.vertexai.env]` 子表里**——直接在 shell 里 `export GOOGLE_CLOUD_PROJECT` 不会被 CLI 读取。
185
+ 认证走 Google Cloud 标准 ADC 流程(`gcloud auth application-default login`,或 `GOOGLE_APPLICATION_CREDENTIALS` 指向的服务账号 JSON 文件)。**项目 ID 和区域必须写在 `[providers.vertexai.env]` 子表里**——在 shell 里 `export GOOGLE_CLOUD_PROJECT` 不起作用。
184
186
 
185
187
  ```toml
186
188
  [providers.vertexai]
@@ -206,7 +208,7 @@ GUI 的 **连接服务 → 用账号登录** 提供 Kimi Code、GitHub Copilot
206
208
 
207
209
  上面的小节决定 Kiki 连到哪个端点、用哪把密钥;**请求身份**(request identity)决定每个请求以哪个客户端的身份发出——它写入发往 provider 端点的 `User-Agent` 和额外请求头,服务端据此把这段流量认成 Codex CLI、Claude Code、Grok Build、OpenCode 或 Kiki 自己的客户端。它与 [`[identity]`](./config-files.md#identity)(运行时显示名称和 slug)是两件不同的事。
208
210
 
209
- 身份只提供这批客户端标识字段:`base_url`、API 密钥和认证方式仍然由你在供应商配置和 `credentials.toml` 里决定,身份既不附带也不改写它们;`Authorization`、`x-api-key`、`Cookie`、`Content-Type` 这类鉴权与传输头也不接受身份声明。
211
+ 身份只提供这批客户端标识字段。`base_url`、API 密钥和认证方式仍然由你在供应商配置和 `credentials.toml` 里决定;`Authorization`、`x-api-key`、`Cookie`、`Content-Type` 这类鉴权与传输头不接受身份声明。
210
212
 
211
213
  ### 内置身份
212
214
 
@@ -242,7 +244,7 @@ GUI 的 **设置 → 请求身份** 是集中页面:左列列出内置(只
242
244
  | 供应商 | 设置 → 模型与提供商 → 供应商编辑器 → 「请求身份」 | `[providers.<name>.request_identity]` |
243
245
  | 模型 | 设置 → 模型与提供商 → 模型编辑器 → 「请求身份」 | `[models."<alias>".request_identity]` |
244
246
 
245
- 后面的层覆盖前面的层(全局 → 供应商 → 模型)。一层都不设置时,普通 API key 连接沿用内置的 Kimi Code 身份,走 Codex 或 Grok Build OAuth 登录的供应商则沿用该供应商的默认身份。你显式设置的层——全局、供应商或模型——仍然覆盖这个默认。选某个兼容 preset 会先重置更低层身份,再应用该层可选的 `overrides` 稀疏调整(如 `lineage.format`、`client.user_agent`、`request.logical_id`)。让一家供应商的流量以 OpenCode 身份发出只需:
247
+ 后面的层覆盖前面的层(全局 → 供应商 → 模型)。一层都不设置时,普通 API key 连接使用内置的 Kimi Code 身份,走 Codex 或 Grok Build OAuth 登录的供应商使用该供应商的默认身份。选某个兼容 preset 会先清空更低层的身份,再应用该层可选的 `overrides` 稀疏调整(如 `lineage.format`、`client.user_agent`、`request.logical_id`)。让一家供应商的流量以 OpenCode 身份发出只需:
246
248
 
247
249
  ```toml
248
250
  [providers.my-gateway.request_identity]