chainlesschain 0.166.86 → 0.166.88

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 (190) hide show
  1. package/README.md +26 -15
  2. package/package.json +1 -1
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-DZwiXAIh.js → AIOps-QzeGep9J.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-aNzXoIJP.js → ActionButton-Dfc5bx7S.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-ETQk4ZXt.js → Analytics-tn-_ZG2E.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-D5oEbeEC.js → AppLayout-Deg3WAK8.js} +3 -3
  9. package/src/assets/web-panel/assets/{Artifacts-ja48FAne.js → Artifacts-KU05t0a6.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-DlN0YnDt.js → Audit-CkSZf54T.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-CzvyNsRg.js → BackgroundAgents-i7ivfXF0.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-DXgEC2MQ.js → Backup-QcVUKtf0.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-D9XqejLx.js → BaseInput-B3h5ZJ0g.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-BTwuYUlN.js → Chat-D7AVz0xi.js} +5 -5
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-0anIC2Wn.js → ChatBubbleRenderer-B0-euPW7.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-CLuaQbDt.js → Checkbox-H0p0TMlD.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-KwQUZs8A.js → Codegen-B6HOmAY3.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-BCmROkzc.js → Col-n_64Fog2.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-CXlUEHR4.js → Community-CX0JGgj0.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-Dzx-lWI2.js → Compact-C4JWUZlx.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CfXW82FF.js → Compliance-DKyTZakB.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-DIISTRm2.js → Cowork-C0joBMci.js} +3 -3
  23. package/src/assets/web-panel/assets/{Cron-nyJ-KcFE.js → Cron-D6VkYpxK.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-Dtv1E4cV.js → Crosschain-7b6Uu8jc.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-BCTpektS.js → DID-C8YPKqzY.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-C1Q_m0So.js → Dashboard-DJsOiEry.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-BrQ5_PPL.js → Dropdown-CyStFY-4.js} +1 -1
  28. package/src/assets/web-panel/assets/EmailListRenderer-COrIx2Rg.js +1 -0
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DaGaE6bX.js → EvolutionSettings-DpxORusH.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-nJDWBECt.js → FamilyGuardDashboard-5BYZdMG0.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-DhMUY_wG.js → Federation-s1kS0ekU.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-CbONJPuc.js → FormItemContext-CmgoH9HV.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-CDdX4dX-.js → GenericCardRenderer-DSRWrvcL.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-DXbDVJdR.js → Git-Cz3EgnS1.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-DbAfAvs1.js → Governance-De4atTe7.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-Dy-fGea2.js → Inference-DoitBBxJ.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-DAxRpGUF.js → KnowledgeGraph-CIdmJ1pH.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-5L1UCR8X.js → Logs-Coa_qNhU.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-u0FPafvT.js → MarkdownRenderer-CeT_RocE.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-DUk_McDG.js → Marketplace-C6kbAQoM.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-B6PNsZ_p.js → McpTools-C2TZn8D-.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-BUUs8j5F.js → Memory-DYdEKDuB.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-pXRsgyuO.js → MobileBridge-pKLeVviZ.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-D4bWcHA_.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-Deaj4faB.js → Mtc-IEoVRV29.js} +4 -4
  46. package/src/assets/web-panel/assets/{MtcAudit-wUV0VUH1.js → MtcAudit-Cov-yYTY.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-C67IIkts.js → Multisig--Jr7OCmp.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-BCA_CWrW.js → NLProgramming-D2gXnYAA.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-D9eu14hQ.js → Notes-hk8pMyve.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-Cnd-J4LM.js → NotificationSettings-D26Nc7MU.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-C4pHUuyZ.js → OrderTableRenderer-DmzHMEOa.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-4YExAbnp.js → Organization-Cn-o6mHT.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-BF-wFuZz.js → Overflow-DP6xpDak.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-CdiajqCT.js → P2P-C9WAjG-I.js} +2 -2
  55. package/src/assets/web-panel/assets/PdhVaultBrowser-DxZb0Ux8.js +7 -0
  56. package/src/assets/web-panel/assets/{Permissions-DrZ4D78_.js → Permissions-BFBN4-IL.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-lDc6OXjz.js → PersonalDataHub-BEDvoAiz.js} +6 -6
  58. package/src/assets/web-panel/assets/{Pipeline-DqDS9ON1.js → Pipeline-Co2Ze_rR.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-BMekZRZu.js → Privacy-BOTn1EId.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-LYS7NFvJ.js → ProjectInit-CObyrZYm.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-CcJNHk9A.js → ProjectSettings-DVTN31rd.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-DrfAHgdF.js → Projects-DQSEaVjE.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-aqsly9SR.js → Providers-BRIKWIdQ.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-ZWvR3zqg.js → QrScannerModal-3nxaEXxN.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BT5CgsvW.js → QuickAsk-iwZJEE9z.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-Cz8Dz2RN.js → Recommend-D2_EEbvc.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BlxPVbtQ.js → RemoteSession-S4w2mUfq.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-B3VGBE-1.js → Reputation-CstUvfTC.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-Bwv7vSEA.js → Row-DEGHFpxz.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-DHI085r_.js → RssFeed-DGdZtJQl.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-DBler5T0.js → Search-DhfXi99U.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-BZdw43NW.js → Security-BbzISrgX.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Cslk5lUj.js → Services-CFjP2sQ3.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-Bur-C-25.js → Skeleton-CFn5wbvm.js} +1 -1
  75. package/src/assets/web-panel/assets/Skills-fVbT8RcW.js +1 -0
  76. package/src/assets/web-panel/assets/{Sla-B1OWgQ51.js → Sla-D6OtC0MT.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-CaBcEaV4.js → SpeechSettings-D0kteBjU.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-CBbG8L6J.js → SyncSettings-BGEWCtPh.js} +2 -2
  79. package/src/assets/web-panel/assets/Tasks-B1xZUG4D.js +1 -0
  80. package/src/assets/web-panel/assets/{Templates-VBBOZ1H5.js → Templates-COlorjqb.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CtQTj7IF.js → Tenant-yLkwfuo3.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DXVTQjnl.js → Terminal-CAmkq1wf.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BRIno0aN.js → TimelineRenderer-CcKYq1Ue.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-uiiAfkYN.js → Tokens-9hIqn_LE.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-CPApN8o6.js → Trigger-Dsdkb74C.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-T2jKVwCE.js → Trust-DC4GuE3C.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-C2U_gbzP.js → UkeySign-CSlh00wf.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-BCdlr3Kj.js → VideoEditing-QEWLo3QY.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-CWnjoSc1.js → Wallet-BkPNQgmg.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-CqSbYqHq.js → WebAuthn-7---jCBl.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-Dr_I3jcr.js → WorkflowEditor-Dq6Yiu8E.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-Cg21FKdE.js → chat-CTYIMpWD.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-CK85tY9e.js → colors-C8JtYlDN.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-m-XYPC7W.js → compact-item-spXpnsNC.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BmiEeNvs.js → createContext-D04ewPuL.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-3-s4adfp.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CCw4KAoc.js → hasIn-DZblOKXx.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Br9t_I1X.js → index-749P1pkM.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BvjC3t35.js → index-B-cKXztT.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BiVPFsat.js → index-B57W1RB6.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-8KzhlvJ9.js → index-B7RA974g.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-OIbfsi-o.js → index-BKfR2eSQ.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BGb1j2z9.js → index-BLv-KSGc.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-yYmjkf38.js → index-BOuUUW2U.js} +3 -3
  105. package/src/assets/web-panel/assets/{index-J81uvUMN.js → index-BSO33_O2.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DI9GJFcn.js → index-B_65aY6c.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BHsiSoGY.js → index-BjMY3Y_L.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-6jXf-Lln.js → index-Bm0z1M6s.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BGUYgc96.js → index-Bw-3CtK2.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-sWUmvT8H.js → index-CE3TYhl0.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CN2xbLGz.js → index-CHtwoTKX.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D7gS_TJl.js → index-CLkua5sJ.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BStyjmLG.js → index-COvZnoIg.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DmSgfXuz.js → index-CZmBlh5P.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-lhoexBDH.js → index-Cfk4o9eI.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DMbrl43d.js → index-Cgztj1JO.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DxRhnsEC.js → index-Cz0gkRz_.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DAlGVix-.js → index-DHOV24VR.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DIlGxS2W.js → index-DLUHbPl3.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CYEzWoyZ.js → index-DSoyEHi2.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CBcgIWOe.js → index-D_Md0Jhp.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-D1sU5-XA.js → index-Dcd-qZ68.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-B8IC9ZeZ.js → index-DcjouIsi.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-ByVvAXdl.js → index-DdC0OsNh.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BtvVupUL.js → index-DruABY-g.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-IskAKXhx.js → index-Dssnz_1x.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DpIy2HzE.js → index-DtSzmzFF.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BIOTRzaF.js → index-DwIEfKo7.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-B7xJkhtJ.js → index-EM4_wLPi.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Bv90WEWa.js → index-IFEbaISP.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cf5arJie.js → index-KIoJ2eCK.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BUYyhYP6.js → index-Mxj-qi1G.js} +1 -1
  133. package/src/assets/web-panel/assets/index-ZMf_BGlO.js +1 -0
  134. package/src/assets/web-panel/assets/index-jvp8bJBF.js +1 -0
  135. package/src/assets/web-panel/assets/{index-Br0ZNdu1.js → index-rU6_An6N.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-BcfVHmFK.js → index-rVEqWa0_.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-Cc1XOmNe.js → initDefaultProps-Dl0wiMxn.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BehsX88u.js → motion-BFmZYrGO.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BPx2YsqY.js → move-Cjs64yWq.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-BSFJgFQA.js → mtc-parser-NeQsnBuP.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DBN5KUeo.js → omit-4Rs-rfs9.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-BDK1yZ-9.js → pickAttrs-CUhx2rDY.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-C4rMmKNJ.js → placementArrow-DbIM_OB2.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-BoeoOnxX.js → responsiveObserve-B_TGx9AN.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-BKlr1bl9.js → slide-C46cEP5t.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-Ky1apWPI.js → statusUtils-DqeksICX.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-DxxR7uXk.js → styleChecker-2rrypo5u.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-DmsUqVe9.js → useFlexGapSupport-RRe1Edsg.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CwkG7sOg.js → useFs-CB0oxU1U.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-CddgeEfF.js → usePersonalDataHub-B98WdlUE.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-C_-H8i4Y.js → vnode-CY8AoD95.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-aAsHUMNE.js → zoom-BnT-0MbP.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/eval.js +116 -67
  156. package/src/commands/memory.js +34 -15
  157. package/src/commands/sandbox.js +9 -0
  158. package/src/data/changelog.json +26 -0
  159. package/src/lib/causal-observability.js +6 -45
  160. package/src/lib/context-memory-kernel/durable-memory-port.js +49 -10
  161. package/src/lib/context-memory-kernel/memory-query-index.js +278 -0
  162. package/src/lib/context-memory-kernel/memory-service.js +17 -2
  163. package/src/lib/context-memory-kernel/segmented-memory-port.js +277 -9
  164. package/src/lib/eval/outcomes.js +20 -10
  165. package/src/lib/eval/runner.js +49 -5
  166. package/src/lib/eval/stream-terminal.js +51 -0
  167. package/src/lib/eval/tasks.js +8 -3
  168. package/src/lib/eval/verify01-contracts.js +349 -0
  169. package/src/lib/eval/verify01-execution.js +611 -0
  170. package/src/lib/eval/verify01-host-evidence.js +604 -0
  171. package/src/lib/execution-support.js +58 -0
  172. package/src/lib/llm-pricing.js +98 -11
  173. package/src/lib/model-catalog-review.js +116 -0
  174. package/src/lib/model-context-catalog.js +23 -1
  175. package/src/lib/openai-responses.js +39 -0
  176. package/src/lib/process-execution-broker/index.js +8 -0
  177. package/src/lib/process-execution-broker/linux-subreaper-process.js +24 -2
  178. package/src/lib/process-execution-broker/process-ownership-journal.js +168 -7
  179. package/src/lib/process-execution-broker/process-ownership-quarantine.js +56 -1
  180. package/src/lib/process-execution-broker/process-recovery-cgroup.js +272 -0
  181. package/src/runtime/agent-core.js +9 -24
  182. package/src/runtime/permission-authority-host.js +14 -0
  183. package/src/assets/web-panel/assets/EmailListRenderer-DjoNlONP.js +0 -1
  184. package/src/assets/web-panel/assets/MobileProjects-D7v-2Hwm.js +0 -1
  185. package/src/assets/web-panel/assets/PdhVaultBrowser-BkjfS6Th.js +0 -7
  186. package/src/assets/web-panel/assets/Skills-v0zgLy0X.js +0 -1
  187. package/src/assets/web-panel/assets/Tasks-C7EjXrnN.js +0 -1
  188. package/src/assets/web-panel/assets/devWarning-CkMEODFC.js +0 -1
  189. package/src/assets/web-panel/assets/index-BjE5qaKn.js +0 -1
  190. package/src/assets/web-panel/assets/index-CsFH-2Zk.js +0 -1
@@ -4,11 +4,17 @@ import { randomUUID } from "node:crypto";
4
4
  import { withFileLock } from "../with-file-lock.js";
5
5
  import { writeSecurityStore } from "../durable-security-store.js";
6
6
  import { ensurePrivateDirectory } from "../secure-fs.js";
7
+ import { performance } from "node:perf_hooks";
8
+ import {
9
+ openRecoveryCgroup,
10
+ validateRecoveryCgroup,
11
+ } from "./process-recovery-cgroup.js";
7
12
 
8
13
  export const PROCESS_OWNERSHIP_PENDING = "BROKER_PROCESS_OWNERSHIP_PENDING";
9
14
  export const PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE =
10
15
  "BROKER_PROCESS_OWNERSHIP_JOURNAL_UNAVAILABLE";
11
16
  const SCHEMA = "chainlesschain.process-ownership-journal/v1";
17
+ const RECOVERY_SCHEMA = "chainlesschain.process-ownership-journal/v2";
12
18
  const MAX_BYTES = 1024 * 1024;
13
19
  const MAX_PENDING = 1024;
14
20
  const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
@@ -27,8 +33,12 @@ function unavailable(cause) {
27
33
  function validate(state) {
28
34
  if (
29
35
  !state ||
30
- Object.keys(state).sort().join() !== "pending,schema" ||
31
- state.schema !== SCHEMA ||
36
+ !(
37
+ (state.schema === SCHEMA &&
38
+ Object.keys(state).sort().join() === "pending,schema") ||
39
+ (state.schema === RECOVERY_SCHEMA &&
40
+ Object.keys(state).sort().join() === "pending,recoveries,schema")
41
+ ) ||
32
42
  !Array.isArray(state.pending) ||
33
43
  state.pending.length > MAX_PENDING
34
44
  )
@@ -37,7 +47,12 @@ function validate(state) {
37
47
  for (const entry of state.pending) {
38
48
  if (
39
49
  !entry ||
40
- Object.keys(entry).sort().join() !== "executionId,ownerPid,token" ||
50
+ ![
51
+ "executionId,ownerPid,token",
52
+ ...(state.schema === RECOVERY_SCHEMA
53
+ ? ["executionId,ownerPid,recovery,token"]
54
+ : []),
55
+ ].includes(Object.keys(entry).sort().join()) ||
41
56
  !UUID.test(entry.executionId) ||
42
57
  !UUID.test(entry.token) ||
43
58
  !Number.isSafeInteger(entry.ownerPid) ||
@@ -45,8 +60,31 @@ function validate(state) {
45
60
  ids.has(entry.executionId)
46
61
  )
47
62
  throw new Error("Invalid ownership journal entry");
63
+ if (Object.hasOwn(entry, "recovery"))
64
+ validateRecoveryCgroup(entry.recovery, entry.executionId);
48
65
  ids.add(entry.executionId);
49
66
  }
67
+ if (state.schema === RECOVERY_SCHEMA) {
68
+ if (
69
+ !Array.isArray(state.recoveries) ||
70
+ state.recoveries.length > MAX_PENDING
71
+ )
72
+ throw new Error("Invalid recovery audit inventory");
73
+ for (const receipt of state.recoveries) {
74
+ if (
75
+ !receipt ||
76
+ Object.keys(receipt).sort().join() !==
77
+ "completedAt,executionId,group,killIssued,populated,token" ||
78
+ !UUID.test(receipt.executionId) ||
79
+ !UUID.test(receipt.token) ||
80
+ receipt.killIssued !== true ||
81
+ receipt.populated !== false ||
82
+ !Number.isFinite(Date.parse(receipt.completedAt))
83
+ )
84
+ throw new Error("Invalid recovery audit receipt");
85
+ validateRecoveryCgroup(receipt.group, receipt.executionId);
86
+ }
87
+ }
50
88
  return state;
51
89
  }
52
90
 
@@ -211,6 +249,13 @@ export class ProcessOwnershipJournal {
211
249
  }
212
250
  }
213
251
 
252
+ #write(file, state, label = "Process ownership") {
253
+ validate(state);
254
+ if (Buffer.byteLength(`${JSON.stringify(state, null, 2)}\n`) > MAX_BYTES)
255
+ throw new Error("Ownership journal byte capacity is exhausted");
256
+ writeSecurityStore(file, label, state);
257
+ }
258
+
214
259
  assertAvailable() {
215
260
  if (this.#fault) throw this.#fault;
216
261
  this.#withDirectory(false, (file) => this.#assertState(this.#read(file)));
@@ -222,6 +267,9 @@ export class ProcessOwnershipJournal {
222
267
  const state = this.#read(file);
223
268
  return {
224
269
  pendingExecutionIds: state.pending.map((entry) => entry.executionId),
270
+ recoverableExecutionIds: state.pending
271
+ .filter((entry) => entry.recovery)
272
+ .map((entry) => entry.executionId),
225
273
  blocked: state.pending.some(
226
274
  (entry) => this.#local.get(entry.executionId)?.token !== entry.token,
227
275
  ),
@@ -229,24 +277,34 @@ export class ProcessOwnershipJournal {
229
277
  });
230
278
  }
231
279
 
232
- prepare(executionId) {
280
+ prepare(executionId, recovery = null) {
233
281
  if (!UUID.test(executionId))
234
282
  throw new TypeError("Invalid ownership execution id");
235
283
  if (this.#fault) throw this.#fault;
236
- const entry = { executionId, ownerPid: process.pid, token: randomUUID() };
284
+ if (recovery) validateRecoveryCgroup(recovery, executionId);
285
+ const entry = {
286
+ executionId,
287
+ ownerPid: process.pid,
288
+ token: randomUUID(),
289
+ ...(recovery ? { recovery: { ...recovery } } : {}),
290
+ };
237
291
  this.#withDirectory(true, (file) =>
238
292
  withFileLock(
239
293
  file,
240
294
  () => {
241
295
  const state = this.#read(file);
242
296
  this.#assertState(state);
297
+ if (recovery && state.schema === SCHEMA) {
298
+ state.schema = RECOVERY_SCHEMA;
299
+ state.recoveries = [];
300
+ }
243
301
  if (
244
302
  state.pending.length >= MAX_PENDING ||
245
303
  state.pending.some((item) => item.executionId === executionId)
246
304
  )
247
305
  throw new Error("Ownership journal admission limit");
248
306
  state.pending.push(entry);
249
- writeSecurityStore(file, "Process ownership", state);
307
+ this.#write(file, state);
250
308
  this.#initialized = true;
251
309
  this.#local.set(executionId, entry);
252
310
  },
@@ -284,7 +342,7 @@ export class ProcessOwnershipJournal {
284
342
  state.pending = state.pending.filter(
285
343
  (item) => item.executionId !== executionId,
286
344
  );
287
- writeSecurityStore(file, "Process ownership", state);
345
+ this.#write(file, state);
288
346
  this.#local.delete(executionId);
289
347
  settled = true;
290
348
  },
@@ -294,4 +352,107 @@ export class ProcessOwnershipJournal {
294
352
  },
295
353
  });
296
354
  }
355
+
356
+ /** Explicitly cancel an orphaned, identity-bound cgroup. Old PID-only records
357
+ * remain quarantined. Neither process death nor age is a cleanup authority.
358
+ */
359
+ async recover(executionId, { timeoutMs = 5000, pollMs = 10 } = {}) {
360
+ if (
361
+ !UUID.test(executionId) ||
362
+ !Number.isSafeInteger(timeoutMs) ||
363
+ timeoutMs < 1 ||
364
+ timeoutMs > 30000 ||
365
+ !Number.isSafeInteger(pollMs) ||
366
+ pollMs < 1 ||
367
+ pollMs > 1000
368
+ )
369
+ throw new TypeError("Invalid process recovery request");
370
+ if (this.#fault) throw this.#fault;
371
+ if (this.#local.has(executionId))
372
+ throw unavailable(
373
+ new Error(
374
+ "A locally owned live launch must use its normal cancellation fence",
375
+ ),
376
+ );
377
+ const entry = this.#withDirectory(false, (file) => {
378
+ const state = this.#read(file);
379
+ const found = state.pending.find(
380
+ (item) => item.executionId === executionId,
381
+ );
382
+ if (!found?.recovery) {
383
+ const error = new Error(
384
+ "This pending execution has no recoverable kernel group identity",
385
+ );
386
+ error.code = PROCESS_OWNERSHIP_PENDING;
387
+ error.recoveryRequired = true;
388
+ throw error;
389
+ }
390
+ if (state.recoveries.length >= MAX_PENDING)
391
+ throw new Error("Recovery audit capacity is exhausted");
392
+ return { ...found, recovery: { ...found.recovery } };
393
+ });
394
+ const group = openRecoveryCgroup(entry.recovery, executionId);
395
+ let settled = false;
396
+ try {
397
+ group.kill();
398
+ const deadline = performance.now() + timeoutMs;
399
+ while (group.populated()) {
400
+ if (performance.now() >= deadline) {
401
+ const error = new Error(
402
+ "Recovered process group has not reached its empty kernel fence",
403
+ );
404
+ error.code = PROCESS_OWNERSHIP_PENDING;
405
+ error.recoveryRequired = true;
406
+ throw error;
407
+ }
408
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
409
+ }
410
+ const receipt = {
411
+ executionId,
412
+ token: entry.token,
413
+ group: entry.recovery,
414
+ killIssued: true,
415
+ populated: false,
416
+ completedAt: new Date().toISOString(),
417
+ };
418
+ this.#withDirectory(false, (file) =>
419
+ withFileLock(
420
+ file,
421
+ () => {
422
+ const state = this.#read(file);
423
+ const current = state.pending.find(
424
+ (item) => item.executionId === executionId,
425
+ );
426
+ if (
427
+ !current ||
428
+ current.token !== entry.token ||
429
+ JSON.stringify(current.recovery) !==
430
+ JSON.stringify(entry.recovery)
431
+ )
432
+ throw new Error("Ownership recovery lost its original record");
433
+ if (state.recoveries.length >= MAX_PENDING)
434
+ throw new Error("Recovery audit capacity is exhausted");
435
+ // Check the kernel fence again while committing the durable receipt.
436
+ group.confirmEmpty();
437
+ state.pending = state.pending.filter(
438
+ (item) => item.executionId !== executionId,
439
+ );
440
+ state.recoveries.push(receipt);
441
+ this.#write(file, state, "Process ownership recovery");
442
+ settled = true;
443
+ },
444
+ { failIfUnavailable: true, timeoutMs: 2000 },
445
+ ),
446
+ );
447
+ return { ...receipt, cleanupConfirmed: true, executionResumed: false };
448
+ } finally {
449
+ // Publish settlement before removing the empty group. If journal IO
450
+ // fails, its kernel identity remains available for a safe retry.
451
+ try {
452
+ group.close({ remove: settled });
453
+ } catch {
454
+ group.close(); /* Empty directory leftovers never certify a run. */
455
+ }
456
+ }
457
+ }
297
458
  }
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { getMachineSecurityAnchorDir } from "../paths.js";
3
3
  import { ProcessOwnershipJournal } from "./process-ownership-journal.js";
4
+ import { prepareRecoveryCgroup } from "./process-recovery-cgroup.js";
4
5
 
5
6
  // Shared by every Broker in this JS runtime. A new Broker, different cwd or
6
7
  // cleared audit history cannot turn a lost process owner into cleanup evidence.
@@ -18,7 +19,60 @@ function durableJournal() {
18
19
  }
19
20
 
20
21
  export function prepareProcessOwnership(executionId) {
21
- return durableJournal()?.prepare(executionId) ?? null;
22
+ const authority = durableJournal();
23
+ if (!authority) return null;
24
+ const group = prepareRecoveryCgroup(
25
+ executionId,
26
+ process.env.CHAINLESSCHAIN_PROCESS_RECOVERY_CGROUP_ROOT,
27
+ );
28
+ if (!group) return authority.prepare(executionId);
29
+ let lease;
30
+ try {
31
+ lease = authority.prepare(executionId, group.identity);
32
+ } catch (error) {
33
+ group.close({ remove: true });
34
+ throw error;
35
+ }
36
+ let settled = false,
37
+ retained = false;
38
+ return Object.freeze({
39
+ beforeLaunch: (proc) => group.attachBeforeLaunch(proc),
40
+ settle() {
41
+ if (settled) return;
42
+ if (retained)
43
+ throw new Error("Retained recovery group requires explicit recovery");
44
+ try {
45
+ group.confirmEmpty();
46
+ lease.settle();
47
+ } catch (error) {
48
+ retained = true;
49
+ lease.retain();
50
+ group.close();
51
+ throw error;
52
+ }
53
+ settled = true;
54
+ try {
55
+ group.close({ remove: true });
56
+ } catch {
57
+ group.close();
58
+ }
59
+ },
60
+ retain() {
61
+ if (settled || retained) return;
62
+ retained = true;
63
+ lease.retain();
64
+ group.close();
65
+ },
66
+ });
67
+ }
68
+
69
+ export async function recoverProcessOwnership(executionId, options) {
70
+ const authority = durableJournal();
71
+ if (!authority)
72
+ throw new Error("Kernel process ownership recovery requires Linux");
73
+ const receipt = await authority.recover(executionId, options);
74
+ unresolvedOwners.delete(executionId);
75
+ return receipt;
22
76
  }
23
77
 
24
78
  export const PROCESS_OWNERSHIP_UNCONFIRMED =
@@ -73,6 +127,7 @@ export function getProcessOwnershipStatus() {
73
127
  !!durable &&
74
128
  [...unresolvedOwners.values()].every((owner) => owner.durable),
75
129
  restartSafe: false,
130
+ recoverableExecutionIds: durable?.recoverableExecutionIds || [],
76
131
  };
77
132
  }
78
133
 
@@ -0,0 +1,272 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ export const PROCESS_RECOVERY_CGROUP_SCHEMA =
5
+ "chainlesschain.process-recovery-cgroup/v1";
6
+ const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/u;
7
+ const CGROUP2_MAGIC = 0x63677270n;
8
+ const BOOT_ID = "/proc/sys/kernel/random/boot_id";
9
+
10
+ function denied(message, cause) {
11
+ return Object.assign(
12
+ new Error(
13
+ `Process recovery cgroup is unavailable: ${message}`,
14
+ cause ? { cause } : undefined,
15
+ ),
16
+ {
17
+ code: "BROKER_PROCESS_RECOVERY_UNAVAILABLE",
18
+ recoveryRequired: true,
19
+ },
20
+ );
21
+ }
22
+ function requireValue(value, reason) {
23
+ if (!value) throw denied(reason);
24
+ }
25
+ function identity(stat) {
26
+ return { dev: String(stat.dev), ino: String(stat.ino) };
27
+ }
28
+ function same(stat, expected, prefix = "") {
29
+ return (
30
+ String(stat.dev) === expected[`${prefix}dev`] &&
31
+ String(stat.ino) === expected[`${prefix}ino`]
32
+ );
33
+ }
34
+ function rootPath(root) {
35
+ requireValue(
36
+ typeof root === "string" &&
37
+ path.posix.isAbsolute(root) &&
38
+ root !== "/" &&
39
+ !root.includes("\0") &&
40
+ !root.split("/").includes(".."),
41
+ "invalid delegated root",
42
+ );
43
+ return path.posix.normalize(root).replace(/\/+$/u, "");
44
+ }
45
+
46
+ export function validateRecoveryCgroup(value, executionId) {
47
+ requireValue(
48
+ value &&
49
+ Object.keys(value).sort().join() ===
50
+ "bootId,dev,ino,name,root,rootdev,rootino,schema" &&
51
+ value.schema === PROCESS_RECOVERY_CGROUP_SCHEMA &&
52
+ UUID.test(value.bootId) &&
53
+ UUID.test(executionId) &&
54
+ value.name === `cc-owner-${executionId}` &&
55
+ rootPath(value.root) === value.root &&
56
+ [value.dev, value.ino, value.rootdev, value.rootino].every(
57
+ (part) => typeof part === "string" && /^\d{1,30}$/u.test(part),
58
+ ),
59
+ "invalid persisted group identity",
60
+ );
61
+ return value;
62
+ }
63
+
64
+ function openDirectory(io, directory) {
65
+ const before = io.lstatSync(directory, { bigint: true });
66
+ requireValue(
67
+ before.isDirectory() && !before.isSymbolicLink(),
68
+ "cgroup path is not a directory",
69
+ );
70
+ requireValue(
71
+ io.realpathSync(directory) === directory,
72
+ "cgroup path traverses a link",
73
+ );
74
+ const fd = io.openSync(
75
+ directory,
76
+ io.constants.O_RDONLY | io.constants.O_DIRECTORY | io.constants.O_NOFOLLOW,
77
+ );
78
+ try {
79
+ const opened = io.fstatSync(fd, { bigint: true });
80
+ requireValue(
81
+ same(opened, identity(before)),
82
+ "cgroup directory changed while opening",
83
+ );
84
+ requireValue(
85
+ BigInt(io.statfsSync(`/proc/self/fd/${fd}`, { bigint: true }).type) ===
86
+ CGROUP2_MAGIC,
87
+ "not a kernel cgroup v2 filesystem",
88
+ );
89
+ return { fd, stat: opened, pinned: `/proc/self/fd/${fd}` };
90
+ } catch (error) {
91
+ io.closeSync(fd);
92
+ throw error;
93
+ }
94
+ }
95
+
96
+ /** Kernel object identities, not PIDs, establish the recovery target. The root
97
+ * must be explicitly delegated by the host. This is cooperative lifecycle
98
+ * recovery, not confinement against same-UID code that can move cgroup members.
99
+ */
100
+ export function openRecoveryCgroup(value, executionId, runtime = {}) {
101
+ const io = runtime.fs || fs;
102
+ requireValue(
103
+ (runtime.platform || process.platform) === "linux",
104
+ "Linux cgroup v2 is required",
105
+ );
106
+ validateRecoveryCgroup(value, executionId);
107
+ requireValue(
108
+ String(io.readFileSync(BOOT_ID, "utf8")).trim() === value.bootId,
109
+ "boot identity changed",
110
+ );
111
+ const root = openDirectory(io, value.root);
112
+ let group;
113
+ try {
114
+ requireValue(
115
+ same(root.stat, value, "root"),
116
+ "delegated root identity changed",
117
+ );
118
+ group = openDirectory(io, path.posix.join(value.root, value.name));
119
+ requireValue(same(group.stat, value), "recovery group identity changed");
120
+ } catch (error) {
121
+ if (group) io.closeSync(group.fd);
122
+ io.closeSync(root.fd);
123
+ throw error;
124
+ }
125
+ let closed = false;
126
+ const assertIdentity = () => {
127
+ requireValue(!closed, "group lease was closed");
128
+ requireValue(
129
+ String(io.readFileSync(BOOT_ID, "utf8")).trim() === value.bootId,
130
+ "boot identity changed",
131
+ );
132
+ const currentRoot = io.lstatSync(value.root, { bigint: true });
133
+ const currentGroup = io.lstatSync(path.posix.join(value.root, value.name), {
134
+ bigint: true,
135
+ });
136
+ requireValue(
137
+ currentRoot.isDirectory() &&
138
+ !currentRoot.isSymbolicLink() &&
139
+ same(currentRoot, value, "root") &&
140
+ currentGroup.isDirectory() &&
141
+ !currentGroup.isSymbolicLink() &&
142
+ same(currentGroup, value),
143
+ "cgroup authority was replaced",
144
+ );
145
+ };
146
+ const populated = () => {
147
+ assertIdentity();
148
+ const bytes = io.readFileSync(`${group.pinned}/cgroup.events`, "utf8");
149
+ requireValue(
150
+ typeof bytes === "string" && bytes.length <= 4096,
151
+ "invalid cgroup event payload",
152
+ );
153
+ const lines = bytes
154
+ .trim()
155
+ .split(/\n/u)
156
+ .map((line) => line.trim().split(/\s+/u));
157
+ const entries = lines.filter(([key]) => key === "populated");
158
+ requireValue(
159
+ entries.length === 1 &&
160
+ entries[0].length === 2 &&
161
+ ["0", "1"].includes(entries[0][1]),
162
+ "missing or invalid populated fence",
163
+ );
164
+ return entries[0][1] === "1";
165
+ };
166
+ return Object.freeze({
167
+ identity: Object.freeze({ ...value }),
168
+ attachBeforeLaunch(proc) {
169
+ assertIdentity();
170
+ requireValue(
171
+ Number.isSafeInteger(proc?.pid) && proc.pid > 0,
172
+ "supervisor PID is unavailable",
173
+ );
174
+ requireValue(!populated(), "new recovery group was already populated");
175
+ // The native supervisor is still blocked on its private launch socket.
176
+ // No target can fork before this write and membership check complete.
177
+ io.writeFileSync(`${group.pinned}/cgroup.procs`, `${proc.pid}\n`, "utf8");
178
+ const members = String(
179
+ io.readFileSync(`${group.pinned}/cgroup.procs`, "utf8"),
180
+ )
181
+ .trim()
182
+ .split(/\s+/u);
183
+ requireValue(
184
+ members.includes(String(proc.pid)),
185
+ "supervisor membership was not observed",
186
+ );
187
+ },
188
+ kill() {
189
+ assertIdentity();
190
+ io.writeFileSync(`${group.pinned}/cgroup.kill`, "1\n", "utf8");
191
+ },
192
+ populated,
193
+ confirmEmpty() {
194
+ requireValue(!populated(), "recovery group remains populated");
195
+ return true;
196
+ },
197
+ close({ remove = false } = {}) {
198
+ if (closed) return;
199
+ try {
200
+ if (remove) {
201
+ requireValue(
202
+ !populated(),
203
+ "cannot remove a populated recovery group",
204
+ );
205
+ io.rmdirSync(`${root.pinned}/${value.name}`);
206
+ }
207
+ } finally {
208
+ closed = true;
209
+ io.closeSync(group.fd);
210
+ io.closeSync(root.fd);
211
+ }
212
+ },
213
+ });
214
+ }
215
+
216
+ export function prepareRecoveryCgroup(executionId, rootInput, runtime = {}) {
217
+ if (!rootInput) return null;
218
+ const io = runtime.fs || fs;
219
+ requireValue(
220
+ (runtime.platform || process.platform) === "linux",
221
+ "Linux cgroup v2 is required",
222
+ );
223
+ requireValue(UUID.test(executionId), "invalid execution identity");
224
+ const root = rootPath(rootInput);
225
+ const opened = openDirectory(io, root);
226
+ const name = `cc-owner-${executionId}`;
227
+ let created = false;
228
+ try {
229
+ const bootId = String(io.readFileSync(BOOT_ID, "utf8")).trim();
230
+ requireValue(UUID.test(bootId), "boot identity is unavailable");
231
+ // The unique group is created through the pinned delegated root.
232
+ io.mkdirSync(`${opened.pinned}/${name}`, { mode: 0o700 });
233
+ created = true;
234
+ const directory = path.posix.join(root, name);
235
+ const stat = io.lstatSync(directory, { bigint: true });
236
+ const value = {
237
+ schema: PROCESS_RECOVERY_CGROUP_SCHEMA,
238
+ root,
239
+ name,
240
+ bootId,
241
+ rootdev: String(opened.stat.dev),
242
+ rootino: String(opened.stat.ino),
243
+ ...identity(stat),
244
+ };
245
+ const group = openRecoveryCgroup(value, executionId, runtime);
246
+ try {
247
+ group.confirmEmpty();
248
+ // Require the real kernel primitive before a recoverable launch is armed.
249
+ const killFd = io.openSync(
250
+ `${directory}/cgroup.kill`,
251
+ io.constants.O_WRONLY | io.constants.O_NOFOLLOW,
252
+ );
253
+ io.closeSync(killFd);
254
+ return group;
255
+ } catch (error) {
256
+ group.close({ remove: true });
257
+ created = false;
258
+ throw error;
259
+ }
260
+ } catch (error) {
261
+ if (created) {
262
+ try {
263
+ io.rmdirSync(`${opened.pinned}/${name}`);
264
+ } catch {
265
+ /* No process was launched into this group. */
266
+ }
267
+ }
268
+ throw denied("preparation failed", error);
269
+ } finally {
270
+ io.closeSync(opened.fd);
271
+ }
272
+ }
@@ -88,6 +88,7 @@ import {
88
88
  } from "../lib/model-capabilities.js";
89
89
  import {
90
90
  createOpenAIResponsesBody,
91
+ createOpenAIResponsesReasoning,
91
92
  createOpenAIResponsesStreamState,
92
93
  finalizeOpenAIResponsesStream,
93
94
  normalizeOpenAIResponsesResponse,
@@ -12120,9 +12121,10 @@ export async function chatWithTools(rawMessages, options) {
12120
12121
  model: effectiveModel,
12121
12122
  messages,
12122
12123
  tools,
12123
- maxOutputTokens: options.maxOutputTokens,
12124
- reasoning: _openAIResponsesReasoningParams(options),
12124
+ maxOutputTokens: modelProfile.requestMaxOutputTokens,
12125
+ reasoning: _openAIResponsesReasoningParams(options, modelProfile),
12125
12126
  stream: typeof options.onToken === "function",
12127
+ modelProfile,
12126
12128
  });
12127
12129
  if (typeof options.onToken === "function") {
12128
12130
  return await _retryStreamingChat(
@@ -13039,28 +13041,11 @@ function _intensityToEffort(want) {
13039
13041
  }
13040
13042
 
13041
13043
  /** Build an opt-in Responses reasoning request without changing default cost. */
13042
- export function _openAIResponsesReasoningParams(options = {}) {
13043
- const want = options?.thinking;
13044
- if (!want || want === "off" || want === "none") return null;
13045
- const allowed = new Set([
13046
- "none",
13047
- "minimal",
13048
- "low",
13049
- "medium",
13050
- "high",
13051
- "xhigh",
13052
- ]);
13053
- const requested =
13054
- typeof options.thinkingEffort === "string"
13055
- ? options.thinkingEffort.toLowerCase()
13056
- : null;
13057
- return {
13058
- effort:
13059
- requested && allowed.has(requested)
13060
- ? requested
13061
- : _intensityToEffort(want),
13062
- summary: "auto",
13063
- };
13044
+ export function _openAIResponsesReasoningParams(
13045
+ options = {},
13046
+ modelProfile = null,
13047
+ ) {
13048
+ return createOpenAIResponsesReasoning(options, modelProfile);
13064
13049
  }
13065
13050
 
13066
13051
  /**
@@ -3,6 +3,8 @@ import path from "node:path";
3
3
  import persistentSettings from "../lib/settings-permission-authority.cjs";
4
4
  import settingsLoader from "../lib/settings-loader.cjs";
5
5
  import { ScopedPermissionStore } from "../lib/scoped-permission-store.js";
6
+ import { assessAgentSandboxCapabilities } from "../lib/agent-sandbox.js";
7
+ import { describeExecutionSupport } from "../lib/execution-support.js";
6
8
  import {
7
9
  createPermissionRulesProvider,
8
10
  permissionRulesProviderAuthority,
@@ -81,6 +83,18 @@ export function openPermissionAuthorityHost({
81
83
  };
82
84
  }
83
85
  return Object.freeze({
86
+ capabilities(sandbox, options = {}) {
87
+ assertOpen();
88
+ runtimeOptions({ sandbox });
89
+ const report = assessAgentSandboxCapabilities(sandbox, options);
90
+ return {
91
+ ...report,
92
+ support: describeExecutionSupport({
93
+ capabilityReport: report,
94
+ permissionRulesProvider: provider,
95
+ }),
96
+ };
97
+ },
84
98
  exportLaunch() {
85
99
  assertOpen();
86
100
  return persistentSettings.exportSettingsPermissionAuthority(binding);
@@ -1 +0,0 @@
1
- import{I as C,P as c,J as f,U as r,c as h,_ as k,R as n,V as l,K as d,Q as u,S as g,b as t}from"./vendor-Bn1JzzAn.js";import{_ as w}from"./index-yYmjkf38.js";import{aH as j}from"./icons-DG5UD-6K.js";const E={__name:"EmailListRenderer",props:{event:{type:Object,required:!0}},setup(_,{expose:m}){m();const a=_,e=t(()=>a.event.content||{}),i=t(()=>a.event.extra||{}),p=t(()=>e.value.from||e.value.sender||e.value.fromName||a.event.actor||"(未知发件人)"),s=t(()=>e.value.subject||e.value.title||"(无主题)"),y=t(()=>e.value.snippet||e.value.preview||e.value.body?.slice(0,100)||null),b=t(()=>Array.isArray(e.value.attachments)?e.value.attachments.length:typeof e.value.attachmentCount=="number"?e.value.attachmentCount:0),x=t(()=>i.value.category||e.value.category),S=t(()=>e.value.unread===!0),T=t(()=>{if(!a.event.occurredAt)return"";const o=new Date(a.event.occurredAt);return`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`}),v={props:a,c:e,e:i,fromText:p,subjectText:s,snippetText:y,attachmentCount:b,category:x,isUnread:S,formattedTime:T,computed:t,get MailOutlined(){return j}};return Object.defineProperty(v,"__isScriptSetup",{enumerable:!1,value:!0}),v}},M={class:"email-row"},N={class:"left"},O={class:"body"},V={class:"head"},A={class:"from"},B={class:"time"},R={class:"subject"},D={key:0,class:"snippet"},L={class:"meta"};function U(_,m,a,e,i,p){const s=C("a-tag");return c(),f("div",M,[r("div",N,[h(e.MailOutlined,{class:k(["icon",{unread:e.isUnread}])},null,8,["class"])]),r("div",O,[r("div",V,[r("span",A,n(e.fromText),1),r("span",B,n(e.formattedTime),1)]),r("div",R,n(e.subjectText),1),e.snippetText?(c(),f("div",D,n(e.snippetText),1)):l("v-if",!0),r("div",L,[h(s,{color:"blue",class:"src"},{default:d(()=>[u(n(a.event.source.adapter),1)]),_:1}),e.attachmentCount>0?(c(),g(s,{key:0,color:"orange"},{default:d(()=>[u(" 📎 "+n(e.attachmentCount),1)]),_:1})):l("v-if",!0),e.category?(c(),g(s,{key:1},{default:d(()=>[u(n(e.category),1)]),_:1})):l("v-if",!0)])])])}const Y=w(E,[["render",U],["__scopeId","data-v-e4ddf632"],["__file","/tmp/cc-web-panel-EYas9w/repo/packages/web-panel/src/components/pdh/renderers/EmailListRenderer.vue"]]);export{Y as default};