@piagent/platform 1.6.1 → 1.7.1

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 (645) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +8 -2
  3. package/README.vi.md +11 -2
  4. package/adapters/common/assurance-producers.json +109 -0
  5. package/adapters/common/structured-assurance-facts.mjs +153 -0
  6. package/adapters/node-typescript/contract-families.json +2811 -0
  7. package/adapters/node-typescript/contract-families.md +90 -0
  8. package/benchmarks/production-v1/grade.mjs +20 -0
  9. package/benchmarks/production-v1/spend-control.v1.json +3 -3
  10. package/benchmarks/production-v2/grade.mjs +892 -0
  11. package/benchmarks/production-v2/project/README.md +7 -0
  12. package/benchmarks/production-v2/project/config/service.json +4 -0
  13. package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
  14. package/benchmarks/production-v2/project/docs/ops.md +3 -0
  15. package/benchmarks/production-v2/project/logs/incident.log +2 -0
  16. package/benchmarks/production-v2/project/package.json +11 -0
  17. package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
  18. package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
  19. package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
  20. package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
  21. package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
  22. package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
  23. package/benchmarks/production-v2/project/src/data/csv.js +3 -0
  24. package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
  25. package/benchmarks/production-v2/project/src/data/migration.js +9 -0
  26. package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
  27. package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
  28. package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
  29. package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
  30. package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
  31. package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
  32. package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
  33. package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
  34. package/benchmarks/production-v2/project/src/platform/args.js +10 -0
  35. package/benchmarks/production-v2/project/src/platform/config.js +7 -0
  36. package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
  37. package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
  38. package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
  39. package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
  40. package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
  41. package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
  42. package/benchmarks/production-v2/project/vendor/README.md +1 -0
  43. package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
  44. package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
  45. package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
  46. package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
  47. package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
  48. package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
  49. package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
  50. package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
  51. package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
  52. package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
  53. package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
  54. package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
  55. package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
  56. package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
  57. package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
  58. package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
  59. package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  60. package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  61. package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
  62. package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
  63. package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  64. package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
  65. package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  66. package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
  67. package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
  68. package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
  69. package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
  70. package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
  71. package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
  72. package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
  73. package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
  74. package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
  75. package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
  76. package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
  77. package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
  78. package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
  79. package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
  80. package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
  81. package/benchmarks/production-v2/spend-control.v1.json +115 -0
  82. package/benchmarks/production-v2/suite.json +1009 -0
  83. package/benchmarks/production-v2/variant.mjs +169 -0
  84. package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
  85. package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
  86. package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
  87. package/benchmarks/production-v3/grade.mjs +1017 -0
  88. package/benchmarks/production-v3/project/README.md +7 -0
  89. package/benchmarks/production-v3/project/config/service.json +4 -0
  90. package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
  91. package/benchmarks/production-v3/project/docs/ops.md +3 -0
  92. package/benchmarks/production-v3/project/logs/incident.log +2 -0
  93. package/benchmarks/production-v3/project/package.json +11 -0
  94. package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
  95. package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
  96. package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
  97. package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
  98. package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
  99. package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
  100. package/benchmarks/production-v3/project/src/data/csv.js +3 -0
  101. package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
  102. package/benchmarks/production-v3/project/src/data/migration.js +9 -0
  103. package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
  104. package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
  105. package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
  106. package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
  107. package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
  108. package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
  109. package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
  110. package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
  111. package/benchmarks/production-v3/project/src/platform/args.js +10 -0
  112. package/benchmarks/production-v3/project/src/platform/config.js +7 -0
  113. package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
  114. package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
  115. package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
  116. package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
  117. package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
  118. package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
  119. package/benchmarks/production-v3/project/vendor/README.md +1 -0
  120. package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
  121. package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
  122. package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
  123. package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
  124. package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
  125. package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
  126. package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
  127. package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
  128. package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
  129. package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
  130. package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
  131. package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
  132. package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
  133. package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
  134. package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
  135. package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
  136. package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  137. package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  138. package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
  139. package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
  140. package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  141. package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
  142. package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  143. package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
  144. package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
  145. package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
  146. package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
  147. package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
  148. package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
  149. package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
  150. package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
  151. package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
  152. package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
  153. package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
  154. package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
  155. package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
  156. package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
  157. package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
  158. package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
  159. package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
  160. package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
  161. package/benchmarks/production-v3/spend-control.v1.json +121 -0
  162. package/benchmarks/production-v3/suite.json +1010 -0
  163. package/benchmarks/production-v3/variant.mjs +178 -0
  164. package/catalog/capabilities.json +2 -2
  165. package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
  166. package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
  167. package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
  168. package/docs/benchmark-public-contract-addendum-v2.md +85 -0
  169. package/docs/benchmark-public-contract-addendum-v3.md +116 -0
  170. package/docs/command-reference-vietnamese.md +10 -7
  171. package/docs/context-window-policy.md +3 -3
  172. package/docs/distribution-standard.md +9 -9
  173. package/docs/languages.json +2 -2
  174. package/docs/operator-manual-vietnamese.md +12 -12
  175. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  176. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  177. package/docs/piagent-core-improvement-plan.md +528 -0
  178. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  179. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  180. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  181. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  182. package/docs/piagent-open-session-wait.md +19 -0
  183. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  184. package/docs/publishing-for-teams.md +2 -0
  185. package/docs/quality-benchmark.md +128 -8
  186. package/docs/quickstart-vietnamese.md +2 -2
  187. package/docs/release-install-policy.md +32 -9
  188. package/docs/research/harness-next-evidence-review.md +113 -0
  189. package/docs/team-onboarding.md +7 -7
  190. package/docs/third-party-neutrality.md +7 -0
  191. package/docs/usage-observability.md +1 -1
  192. package/docs-site/architecture.html +1 -1
  193. package/docs-site/benchmark.html +1 -1
  194. package/docs-site/commands.html +1 -1
  195. package/docs-site/content/en/runtime.html +1 -1
  196. package/docs-site/content/en/whats-new.html +11 -0
  197. package/docs-site/content/runtime.html +2 -2
  198. package/docs-site/content/whats-new.html +11 -0
  199. package/docs-site/context-engine.html +1 -1
  200. package/docs-site/en/architecture.html +1 -1
  201. package/docs-site/en/benchmark.html +1 -1
  202. package/docs-site/en/commands.html +1 -1
  203. package/docs-site/en/context-engine.html +1 -1
  204. package/docs-site/en/index.html +1 -1
  205. package/docs-site/en/mcp-approval.html +1 -1
  206. package/docs-site/en/mcp-auth.html +1 -1
  207. package/docs-site/en/mcp-servers.html +1 -1
  208. package/docs-site/en/mcp.html +1 -1
  209. package/docs-site/en/permissions.html +1 -1
  210. package/docs-site/en/profiles.html +1 -1
  211. package/docs-site/en/quickstart.html +1 -1
  212. package/docs-site/en/runtime.html +2 -2
  213. package/docs-site/en/scope.html +1 -1
  214. package/docs-site/en/security.html +1 -1
  215. package/docs-site/en/team.html +1 -1
  216. package/docs-site/en/whats-new.html +12 -1
  217. package/docs-site/en/workflows.html +1 -1
  218. package/docs-site/index.html +1 -1
  219. package/docs-site/mcp-approval.html +1 -1
  220. package/docs-site/mcp-auth.html +1 -1
  221. package/docs-site/mcp-servers.html +1 -1
  222. package/docs-site/mcp.html +1 -1
  223. package/docs-site/permissions.html +1 -1
  224. package/docs-site/profiles.html +1 -1
  225. package/docs-site/quickstart.html +1 -1
  226. package/docs-site/runtime.html +3 -3
  227. package/docs-site/scope.html +1 -1
  228. package/docs-site/security.html +1 -1
  229. package/docs-site/team.html +1 -1
  230. package/docs-site/whats-new.html +12 -1
  231. package/docs-site/workflows.html +1 -1
  232. package/evals/architecture-conformance-v1/lane.json +18 -0
  233. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  234. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  235. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  236. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  237. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  238. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  239. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  240. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  241. package/evals/fixtures/composite-criterion.valid.json +33 -0
  242. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  243. package/evals/fixtures/contract-family-library.valid.json +41 -0
  244. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  245. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  246. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  247. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  248. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  249. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  250. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  251. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  252. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  253. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  254. package/evals/fs5-artifact-archive/README.md +32 -0
  255. package/evals/fs5-artifact-archive/manifest.json +148 -0
  256. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  257. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  258. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  259. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  260. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  261. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  262. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  263. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  264. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  265. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  266. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  267. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  268. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  269. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  270. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  271. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  272. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  273. package/evals/fs5-causal-arm.v1.json +9 -5
  274. package/evals/fs5-pilot-protocol.v1.json +1 -1
  275. package/evals/fs5-pilot-protocol.v4.json +4 -4
  276. package/evals/fs5-pilot-protocol.v5.json +6 -5
  277. package/evals/harness-next/development-corpus.mjs +106 -0
  278. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  279. package/evals/harness-next/run-calibration.mjs +83 -0
  280. package/evals/harness-next/run-resource-probe.mjs +55 -0
  281. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  282. package/evals/harness-next.v1.json +51 -0
  283. package/evals/long-horizon-v1/README.md +19 -0
  284. package/evals/long-horizon-v1/runner.mjs +116 -48
  285. package/evals/long-horizon-v1/worker.mjs +77 -30
  286. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  287. package/evals/private-holdout-v1/README.md +5 -2
  288. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  289. package/package.json +9 -4
  290. package/packages/piagent-core/README.md +2 -2
  291. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  292. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  293. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  294. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  295. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  296. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  297. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  298. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  299. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  300. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  301. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  302. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
  303. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  304. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  305. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  306. package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
  307. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  308. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  309. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  310. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  311. package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
  312. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  313. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  314. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  315. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  316. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  317. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  318. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  319. package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
  320. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  321. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  322. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  323. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
  324. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  325. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  326. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  327. package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
  328. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  329. package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
  330. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  331. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  332. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  333. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  334. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  335. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  336. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
  337. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  338. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  339. package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
  340. package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
  341. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  342. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  343. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  344. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  345. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  346. package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
  347. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  348. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  349. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  350. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  351. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  352. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  353. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  354. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
  355. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  356. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  357. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  358. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  359. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  360. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  361. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  362. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  363. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  364. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  365. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  366. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  367. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  368. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  369. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  370. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  371. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  372. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  373. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  374. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  375. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  376. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  377. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  378. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  379. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  380. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  381. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  382. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  383. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  384. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  385. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  386. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  387. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  388. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  389. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  390. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  391. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  392. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  393. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  394. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  395. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  396. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  397. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  398. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  399. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  400. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  401. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  402. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  403. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  404. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  405. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  406. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  407. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  408. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  409. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  410. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  411. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  412. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  413. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  414. package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
  415. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  416. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  417. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  418. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  419. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  420. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  421. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  422. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  423. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  424. package/packages/piagent-core/extensions/context-engine.js +11 -6
  425. package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
  426. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  427. package/packages/piagent-core/extensions/guard-types.ts +5 -1
  428. package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
  429. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  430. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  431. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  432. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  433. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  434. package/packages/piagent-core/extensions/task-journal.js +48 -3
  435. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  436. package/packages/piagent-core/extensions/task-state.js +74 -38
  437. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  438. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  439. package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
  440. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  441. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  442. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  443. package/packages/piagent-core/package.json +3 -3
  444. package/packages/piagent-core/policies/base-policy.json +1 -0
  445. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  446. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  447. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  448. package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
  449. package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
  450. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  451. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  452. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
  453. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
  454. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  455. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  456. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  457. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  458. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  459. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  460. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  461. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
  462. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
  463. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  464. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  465. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  466. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  467. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  468. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  469. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
  470. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  471. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  472. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  473. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  474. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  475. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
  476. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  477. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
  478. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  479. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  480. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
  481. package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
  482. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  483. package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
  484. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  485. package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
  486. package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
  487. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  488. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
  489. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  490. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
  491. package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
  492. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  493. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  494. package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
  495. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  496. package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
  497. package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
  498. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  499. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  500. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  501. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  502. package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
  503. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  504. package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
  505. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  506. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  507. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  508. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  509. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  510. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  511. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  512. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  513. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  514. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  515. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
  516. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  517. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  518. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  519. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  520. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  521. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  522. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  523. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
  524. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  525. package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
  526. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  527. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  528. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  529. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  530. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  531. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  532. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DGk34zJT.js} +1 -1
  533. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  534. package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
  535. package/packages/piagent-webui/dist/client/index.html +2 -2
  536. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  537. package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
  538. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  539. package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
  540. package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
  541. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  542. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  543. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  544. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  545. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  546. package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
  547. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  548. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  549. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  550. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  551. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  552. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  553. package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
  554. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  555. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  556. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  557. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  558. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  559. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  560. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
  561. package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
  562. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  563. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  564. package/packages/piagent-webui/server/transcript-projection.ts +65 -12
  565. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  566. package/schemas/approved-host-contracts.schema.json +973 -0
  567. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  568. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  569. package/schemas/composite-criterion.schema.json +788 -0
  570. package/schemas/contract-family-library.schema.json +28 -0
  571. package/schemas/contract-selection-recipe.schema.json +31 -0
  572. package/schemas/failure-evidence.schema.json +2 -2
  573. package/schemas/helper-request.schema.json +16 -4
  574. package/schemas/host-contract-plan.schema.json +25 -0
  575. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  576. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  577. package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
  578. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  579. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  580. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  581. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  582. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  583. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  584. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  585. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  586. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  587. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  588. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  589. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  590. package/schemas/task-contract.schema.json +30 -0
  591. package/scripts/approve-independent-verification.mjs +57 -0
  592. package/scripts/benchmark-arm-observer.mjs +320 -0
  593. package/scripts/benchmark-budget-ipc.mjs +34 -0
  594. package/scripts/benchmark-budget-launcher.mjs +91 -0
  595. package/scripts/benchmark-budget-processes.mjs +133 -0
  596. package/scripts/benchmark-budget-publication.mjs +228 -0
  597. package/scripts/benchmark-budget-runtime.mjs +136 -0
  598. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  599. package/scripts/benchmark-codex-journey.mjs +406 -0
  600. package/scripts/benchmark-independent-verification.mjs +628 -0
  601. package/scripts/benchmark-journey-outcome.mjs +92 -0
  602. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  603. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  604. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  605. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  606. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  607. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  608. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  609. package/scripts/benchmark-runner-completion.mjs +133 -0
  610. package/scripts/benchmark-runner-configuration.mjs +159 -0
  611. package/scripts/benchmark-runner-core.mjs +217 -388
  612. package/scripts/benchmark-runner-finalization.mjs +140 -27
  613. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  614. package/scripts/benchmark-runner-schedule.mjs +256 -0
  615. package/scripts/benchmark-runner-support.mjs +136 -4
  616. package/scripts/benchmark-runner.mjs +95 -18
  617. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  618. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  619. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  620. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  621. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  622. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  623. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  624. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  625. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  626. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  627. package/scripts/benchmark-session-evaluator.mjs +169 -0
  628. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  629. package/scripts/benchmark-session-usage.mjs +28 -0
  630. package/scripts/benchmark-session.mjs +343 -50
  631. package/scripts/benchmark-webui-journey.mjs +678 -0
  632. package/scripts/check-public-wording.mjs +46 -0
  633. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  634. package/scripts/phase-tools-evaluation.mjs +1 -0
  635. package/scripts/pi-auto.sh +7 -1
  636. package/scripts/pi-usage-history.mjs +201 -11
  637. package/scripts/piagent-cli.mjs +8 -0
  638. package/scripts/private-holdout-readiness.mjs +7 -1
  639. package/scripts/public-evaluation-exposure.mjs +140 -0
  640. package/scripts/select-independent-verification.mjs +62 -0
  641. package/scripts/typescript-loader.mjs +135 -1
  642. package/scripts/update-global.mjs +6 -7
  643. package/scripts/verify-local.sh +36 -55
  644. package/scripts/verify-release-identity.mjs +5 -3
  645. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
@@ -32,6 +32,7 @@ import { ProjectRegistry } from "./project-registry.ts";
32
32
  import { pickNativeProjectFolders } from "./native-project-picker.ts";
33
33
  import { ProviderAuthBroker } from "./provider-auth-broker.ts";
34
34
  import { McpAuthBroker } from "./mcp-auth-broker.ts";
35
+ import type { ScopedBrokerRouter } from "./session-runtime-factory.ts";
35
36
 
36
37
  function unavailable(reasonCode: string) {
37
38
  return { status: "unavailable" as const, version: null, reasonCode };
@@ -80,6 +81,8 @@ export async function startPiagentGateway(options: {
80
81
  packageRoot: string;
81
82
  expectedPiVersion: string;
82
83
  agentDir?: string;
84
+ staticRoot?: string;
85
+ scopedBrokerRouter?: ScopedBrokerRouter;
83
86
  }): Promise<{ descriptor: GatewayDescriptor; wait(): Promise<void>; close(): Promise<void> }> {
84
87
  const state = gatewayProfileState(options.agentDir);
85
88
  process.env.PI_CODING_AGENT_DIR = state.agentDir;
@@ -87,7 +90,7 @@ export async function startPiagentGateway(options: {
87
90
  const metadata = new SessionMetadataStore(state.root, key);
88
91
  const projects = new ProjectRegistry(state.root, key);
89
92
  const gatewayInstanceRef = `gateway_${process.pid}_${randomBytes(24).toString("base64url")}`;
90
- const staticRoot = path.join(options.packageRoot, "packages", "piagent-webui", "dist", "client");
93
+ const staticRoot = options.staticRoot ?? path.join(options.packageRoot, "packages", "piagent-webui", "dist", "client");
91
94
  if (!fs.existsSync(path.join(staticRoot, "index.html"))) throw new Error("gateway-webui-build-missing");
92
95
 
93
96
  let descriptor: GatewayDescriptor | null = null;
@@ -145,6 +148,7 @@ export async function startPiagentGateway(options: {
145
148
  runtimes = new SessionRuntimeSupervisor({
146
149
  gatewayInstanceRef, key, leases, listSessions: () => host.SessionManager.listAll(),
147
150
  host, agentDir: state.agentDir, packageRoot: options.packageRoot, modelRuntime: inspectionModels, events,
151
+ scopedBrokerRouter: options.scopedBrokerRouter,
148
152
  resolveProject: (projectRef) => projects.resolve(projectRef)
149
153
  });
150
154
  const readCatalog = () => buildSessionCatalog({
@@ -182,7 +186,8 @@ export async function startPiagentGateway(options: {
182
186
  events, command: commands });
183
187
  const inspections = new SessionInspectionRegistry({ gatewayInstanceRef, host, key, packageRoot: options.packageRoot, agentDir: state.agentDir,
184
188
  models: inspectionModels, projects, mcpAuth, listSessions: () => runtimes!.listSessions(),
185
- openLiveSession: (sessionRef) => runtimes!.liveSessionManager(sessionRef) });
189
+ openLiveSession: (sessionRef) => runtimes!.liveSessionManager(sessionRef),
190
+ operationLiveness: (sessionRef) => runtimes!.currentOperation(sessionRef) ? "running" : "idle" });
186
191
  // Staged bytes live beside the inspection projection they were checked
187
192
  // against, so both read the same session through the same registry.
188
193
  attachments = new SessionAttachmentRegistry({
@@ -2,7 +2,8 @@ import { randomBytes } from "node:crypto";
2
2
 
3
3
  import { redactSensitiveText } from "../../piagent-core/security/sensitive-data.js";
4
4
  import { hasVisibleText } from "../shared/text-visibility.ts";
5
- import { GatewayEventStore } from "./gateway-events.ts";
5
+ import type { TerminalDeliveryReceipt } from "../server/terminal-delivery-receipt.ts";
6
+ import { GatewayEventStore, type GatewayTaskStatus } from "./gateway-events.ts";
6
7
  import { SessionOperationLifecycle, type SessionOperationObservation,
7
8
  type SessionOperationPhase, type SessionOperationRetryPolicyOptions } from "./session-operation-lifecycle.ts";
8
9
 
@@ -17,6 +18,14 @@ const COMPLETION_GATE = /^\[Piagent completion gate: (CONTINUING|NOT APPROVED)\]
17
18
  export type GatewayOperationSettlement = "completed" | "blocked" | "aborted" | "error" | "unknown";
18
19
  type Settlement = { outcome: GatewayOperationSettlement; reasonCode: string | null };
19
20
 
21
+ function projectedTaskStatus(taskOutcome: string | null, override: GatewayTaskStatus | null): GatewayTaskStatus {
22
+ if (override) return override;
23
+ if (taskOutcome === "pending") return "pending";
24
+ if (taskOutcome === "completed") return "completed";
25
+ if (["blocked", "partial", "failed"].includes(String(taskOutcome))) return "failed";
26
+ return "unknown";
27
+ }
28
+
20
29
  function clean(value: unknown): string {
21
30
  return String(value ?? "").replace(/\u001b(?:\[[0-?]*[ -/]*[@-~]|[@-_])/g, "")
22
31
  .replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, " ");
@@ -26,6 +35,66 @@ function safeTool(value: unknown): string {
26
35
  if (safe.redacted) return "redacted-tool";
27
36
  return safe.text.replace(/[^A-Za-z0-9._:-]/g, "-").replace(/^[^A-Za-z0-9]+/, "").slice(0, 160) || "tool";
28
37
  }
38
+
39
+ const DIRECT_FILE_KEYS = ["file", "filePath", "file_path", "filename", "targetFile", "target_file"] as const;
40
+ const PATH_KEYS = ["path", "targetPath", "target_path"] as const;
41
+ const FILE_MUTATION_OR_READ_TOOL = /(?:^|[._:-])(read|write|edit|patch|apply)(?:[._:-]|$)/i;
42
+ const FILE_SEARCH_TOOL = /(?:^|[._:-])(grep|search|find|glob|list|ls)(?:[._:-]|$)/i;
43
+ const FILE_LIKE_BASENAME = /(?:^\.[^./\\]+$)|(?:\.[A-Za-z0-9][A-Za-z0-9+_-]{0,15}$)|^(?:Dockerfile|Containerfile|Makefile|README|LICENSE|CHANGELOG)$/i;
44
+ const PATCH_FILE_HEADER = /^\*\*\* (?:Update|Add|Delete) File:\s*(.+)$/m;
45
+
46
+ function record(value: unknown): Record<string, unknown> | null {
47
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : null;
48
+ }
49
+
50
+ function firstString(records: readonly Record<string, unknown>[], keys: readonly string[]): string | null {
51
+ for (const source of records) for (const key of keys) {
52
+ const value = source[key];
53
+ if (typeof value === "string" && value.trim()) return value;
54
+ if (Array.isArray(value)) {
55
+ const first = value.find((item) => typeof item === "string" && item.trim());
56
+ if (typeof first === "string") return first;
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function safeBasename(value: unknown): string | null {
63
+ if (typeof value !== "string") return null;
64
+ const source = clean(value).trim();
65
+ if (!source || source.includes("\n") || source.includes("\r") || /(?:^|\s)(?:https?|data):\/\//i.test(source)) return null;
66
+ const parts = source.replace(/\\/g, "/").replace(/\/+$/, "").split("/");
67
+ const basename = (parts.at(-1) ?? "").trim().replace(/^["']|["']$/g, "");
68
+ if (!basename || basename === "." || basename === "..") return null;
69
+ const projected = redactSensitiveText(basename);
70
+ if (projected.redacted || projected.text !== basename || /[\u0000-\u001f\u007f/\\]/.test(basename)) return null;
71
+ return basename.slice(0, 160);
72
+ }
73
+
74
+ /**
75
+ * Returns only a redaction-checked basename suitable for the compact chat
76
+ * progress row. Raw arguments and full paths remain confined to the runtime;
77
+ * the Activity inspector keeps its independent, richer projection.
78
+ */
79
+ export function safeToolFileLabel(toolName: unknown, args: unknown): string | null {
80
+ const tool = safeTool(toolName), direct = record(args); if (!direct) return null;
81
+ const nested = record(direct.args), input = record(direct.input);
82
+ const records = [direct, ...(nested ? [nested] : []), ...(input ? [input] : [])];
83
+ const explicitFile = firstString(records, DIRECT_FILE_KEYS);
84
+ if (explicitFile) return safeBasename(explicitFile);
85
+ const path = firstString(records, PATH_KEYS);
86
+ if (path) {
87
+ const basename = safeBasename(path);
88
+ if (basename && (FILE_MUTATION_OR_READ_TOOL.test(tool)
89
+ || FILE_SEARCH_TOOL.test(tool) && FILE_LIKE_BASENAME.test(basename))) return basename;
90
+ }
91
+ if (FILE_MUTATION_OR_READ_TOOL.test(tool)) {
92
+ const patch = firstString(records, ["patch"]);
93
+ const headerPath = typeof patch === "string" ? PATCH_FILE_HEADER.exec(patch)?.[1] : null;
94
+ if (headerPath) return safeBasename(headerPath);
95
+ }
96
+ return null;
97
+ }
29
98
  function ref(prefix: string): string { return `${prefix}_${randomBytes(18).toString("base64url")}`; }
30
99
  function messageText(message: any): string {
31
100
  if (typeof message?.content === "string") return message.content;
@@ -69,6 +138,7 @@ export function runtimeRestartReasonCode(event: unknown): "runtime-restart-requi
69
138
  export class GatewaySessionStream {
70
139
  readonly sessionRef: string;
71
140
  readonly operationRef: string;
141
+ readonly messageRequestId: string | null;
72
142
  readonly #events: GatewayEventStore;
73
143
  #messageRef: string | null = null;
74
144
  #messageSequence = 0;
@@ -83,7 +153,12 @@ export class GatewaySessionStream {
83
153
  #lifecycleTerminationReasonCode: string | null = null;
84
154
  #settleListeners: Array<() => void> = [];
85
155
  readonly #toolRefs = new Map<string, string>();
156
+ readonly #toolLabels = new Map<string, string>();
157
+ readonly #toolFileLabels = new Map<string, string | null>();
86
158
  readonly #lifecycle: SessionOperationLifecycle;
159
+ readonly #commitTerminalDeliveryReceipt: ((message: unknown) => TerminalDeliveryReceipt | undefined) | undefined;
160
+ #terminalDeliveryMessage: unknown;
161
+ #receiptOnly = true;
87
162
 
88
163
  get runtimeRestartRequired(): boolean { return this.#runtimeRestartRequired; }
89
164
  get lifecycleTerminationReasonCode(): string | null { return this.#lifecycleTerminationReasonCode; }
@@ -91,6 +166,9 @@ export class GatewaySessionStream {
91
166
  get retryAbortRequired(): boolean { return this.#lifecycle.retryAbortRequired; }
92
167
 
93
168
  markAborted(reasonCode = "operation-aborted"): void { this.#forcedSettlement = { outcome: "aborted", reasonCode }; }
169
+ markBlocked(reasonCode = "operation-blocked"): void {
170
+ if (!this.#forcedSettlement) this.#forcedSettlement = { outcome: "blocked", reasonCode };
171
+ }
94
172
  markError(reasonCode = "operation-failed"): void {
95
173
  if (!this.#forcedSettlement) this.#forcedSettlement = { outcome: "error", reasonCode };
96
174
  }
@@ -102,10 +180,17 @@ export class GatewaySessionStream {
102
180
  if (!wasSettled) for (const resolve of this.#settleListeners.splice(0)) resolve();
103
181
  }
104
182
 
105
- constructor(options: { sessionRef: string; operationRef: string; events: GatewayEventStore;
106
- retryPolicy?: SessionOperationRetryPolicyOptions }) {
107
- this.sessionRef = options.sessionRef; this.operationRef = options.operationRef; this.#events = options.events;
183
+ constructor(options: { sessionRef: string; operationRef: string; messageRequestId?: string | null; events: GatewayEventStore;
184
+ retryPolicy?: SessionOperationRetryPolicyOptions;
185
+ commitTerminalDeliveryReceipt?: (message: unknown) => TerminalDeliveryReceipt | undefined }) {
186
+ this.sessionRef = options.sessionRef; this.operationRef = options.operationRef;
187
+ this.messageRequestId = options.messageRequestId ?? null; this.#events = options.events;
108
188
  this.#lifecycle = new SessionOperationLifecycle({ operationRef: options.operationRef, retryPolicy: options.retryPolicy });
189
+ this.#commitTerminalDeliveryReceipt = options.commitTerminalDeliveryReceipt;
190
+ }
191
+
192
+ #correlation(): { messageRequestId?: string } {
193
+ return this.messageRequestId ? { messageRequestId: this.messageRequestId } : {};
109
194
  }
110
195
 
111
196
  started(): Promise<void> {
@@ -122,6 +207,9 @@ export class GatewaySessionStream {
122
207
  const wasStarted = this.#lifecycle.started, wasSettled = this.#lifecycle.hostSettled;
123
208
  const observation = this.#lifecycle.observe(event);
124
209
  if (!observation.accepted) return observation;
210
+ if (event?.type === "agent_start" || event?.message?.role === "assistant" || event?.assistantMessageEvent
211
+ || String(event?.type ?? "").startsWith("tool_execution_")) this.#receiptOnly = false;
212
+ if (event?.type === "message_end" && event.message?.role === "custom") this.#terminalDeliveryMessage = event.message;
125
213
  if (!wasStarted && this.#lifecycle.started) for (const resolve of this.#startListeners.splice(0)) resolve();
126
214
  if (!wasSettled && this.#lifecycle.hostSettled) for (const resolve of this.#settleListeners.splice(0)) resolve();
127
215
  if (observation.retry === "abort") this.markError(observation.reasonCode ?? "automatic-retry-blocked");
@@ -129,6 +217,7 @@ export class GatewaySessionStream {
129
217
  return observation;
130
218
  }
131
219
  if (event?.type === "agent_settled") {
220
+ this.#settleActiveTools("operation-settled-before-tool-result");
132
221
  return observation;
133
222
  }
134
223
  if (event?.type === "message_start" && event.message?.role === "assistant") {
@@ -146,22 +235,35 @@ export class GatewaySessionStream {
146
235
  this.#flush(true); this.#lastMessageRef = this.#messageRef; this.#settlement = assistantSettlement(event.message); return observation;
147
236
  }
148
237
  if (event?.type === "tool_execution_start" && typeof event.toolCallId === "string") {
149
- const toolCallRef = ref("tool"); this.#toolRefs.set(event.toolCallId, toolCallRef);
150
- this.#events.publish("tool.started", { sessionRef: this.sessionRef, operationRef: this.operationRef, toolCallRef,
151
- toolLabel: safeTool(event.toolName), isError: null, reasonCode: null });
238
+ const toolCallRef = ref("tool"), toolLabel = safeTool(event.toolName), fileLabel = safeToolFileLabel(event.toolName, event.args);
239
+ this.#toolRefs.set(event.toolCallId, toolCallRef); this.#toolLabels.set(event.toolCallId, toolLabel);
240
+ this.#toolFileLabels.set(event.toolCallId, fileLabel);
241
+ this.#events.publish("tool.started", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(), toolCallRef,
242
+ toolLabel, fileLabel, isError: null, reasonCode: null });
152
243
  return observation;
153
244
  }
154
245
  if (event?.type === "tool_execution_end" && typeof event.toolCallId === "string") {
155
246
  const toolCallRef = this.#toolRefs.get(event.toolCallId); if (!toolCallRef) return observation;
156
247
  const reasonCode = runtimeRestartReasonCode(event);
157
248
  if (reasonCode) this.#runtimeRestartRequired = true;
158
- this.#events.publish("tool.completed", { sessionRef: this.sessionRef, operationRef: this.operationRef, toolCallRef,
159
- toolLabel: safeTool(event.toolName), isError: event.isError === true, reasonCode });
160
- this.#toolRefs.delete(event.toolCallId);
249
+ this.#events.publish("tool.completed", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(), toolCallRef,
250
+ toolLabel: safeTool(event.toolName), fileLabel: this.#toolFileLabels.get(event.toolCallId) ?? null,
251
+ isError: event.isError === true, reasonCode });
252
+ this.#toolRefs.delete(event.toolCallId); this.#toolLabels.delete(event.toolCallId); this.#toolFileLabels.delete(event.toolCallId);
161
253
  }
254
+ if (event?.type === "turn_end") this.#settleActiveTools("turn-ended-before-tool-result");
162
255
  return observation;
163
256
  }
164
257
 
258
+ #settleActiveTools(reasonCode: string): void {
259
+ for (const [toolCallId, toolCallRef] of this.#toolRefs) {
260
+ this.#events.publish("tool.completed", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(), toolCallRef,
261
+ toolLabel: this.#toolLabels.get(toolCallId) ?? "tool", fileLabel: this.#toolFileLabels.get(toolCallId) ?? null,
262
+ isError: true, reasonCode });
263
+ }
264
+ this.#toolRefs.clear(); this.#toolLabels.clear(); this.#toolFileLabels.clear();
265
+ }
266
+
165
267
  #flush(final: boolean): void {
166
268
  if (!this.#messageRef || !this.#buffer || this.#eventCount >= MAX_EVENTS) {
167
269
  if (this.#eventCount >= MAX_EVENTS) this.#truncated = true;
@@ -186,37 +288,57 @@ export class GatewaySessionStream {
186
288
  #emit(value: string): void {
187
289
  for (let offset = 0; offset < value.length; offset += MAX_DELTA) {
188
290
  if (this.#eventCount >= MAX_EVENTS) { this.#truncated = true; break; }
189
- this.#events.publish("message.delta", { sessionRef: this.sessionRef, operationRef: this.operationRef,
291
+ this.#events.publish("message.delta", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(),
190
292
  messageRef: this.#messageRef!, messageSequence: this.#messageSequence++, delta: value.slice(offset, offset + MAX_DELTA) });
191
293
  this.#eventCount += 1;
192
294
  }
193
295
  }
194
296
 
195
- complete(sessionRevision: string | null, taskOutcome: string | null = null): void {
297
+ complete(sessionRevision: string | null, taskOutcome: string | null = null,
298
+ taskStatusOverride: GatewayTaskStatus | null = null): void {
196
299
  if (!this.#lifecycle.markTerminal()) return;
300
+ const receipt = this.#receiptOnly && !this.#forcedSettlement && !this.#runtimeRestartRequired
301
+ && sessionRevision !== null && taskOutcome !== null && taskOutcome !== "pending"
302
+ ? this.#commitTerminalDeliveryReceipt?.(this.#terminalDeliveryMessage) : undefined;
303
+ if (receipt) {
304
+ // The canonical transcript renders a custom receipt. Never stream it as
305
+ // assistant text or open a model turn just to supply a final message.
306
+ this.#lastMessageRef = ref("receipt");
307
+ const diagnostic = receipt.details.diagnosticDelivery as { mode?: string; qualityClaim?: string } | undefined;
308
+ const diagnosticDelivered = taskOutcome === "completed" && receipt.details.completionApproved === false
309
+ && diagnostic?.mode === "diagnostic" && diagnostic.qualityClaim === "withheld";
310
+ const completedTask = receipt.details.outcome === "completed" && (receipt.details.completionApproved || diagnosticDelivered)
311
+ && receipt.details.gateDecision === "pass";
312
+ // Delivery of an already refused task is a completed operation, never
313
+ // approval to perform the refused action. Both the committed receipt
314
+ // and the supervisor's current native task projection must agree.
315
+ const refusedTask = taskOutcome === "blocked" && taskStatusOverride === "refused"
316
+ && receipt.details.outcome === "blocked" && receipt.details.completionApproved === false
317
+ && receipt.details.gateDecision === "fail";
318
+ this.#settlement = completedTask || refusedTask ? { outcome: "completed", reasonCode: null }
319
+ : { outcome: "blocked", reasonCode: "terminal-receipt-not-approved" };
320
+ }
197
321
  this.#flush(true);
322
+ this.#settleActiveTools("operation-settled-before-tool-result");
198
323
  let settlement = this.#forcedSettlement ?? (this.#runtimeRestartRequired
199
324
  ? { outcome: "unknown" as const, reasonCode: "runtime-restart-required" }
200
325
  : this.#settlement);
201
326
  const messageRef = this.#lastMessageRef ?? this.#messageRef;
327
+ const taskStatus = projectedTaskStatus(taskOutcome, taskStatusOverride);
202
328
  if (settlement.outcome === "completed" && !messageRef) {
203
329
  settlement = { outcome: "unknown", reasonCode: "assistant-message-unavailable" };
204
- } else if (settlement.outcome === "completed" && taskOutcome === "pending") {
205
- // Provider completion is not governed-task completion. The durable task
206
- // contract is authoritative, so withhold both success settlement and the
207
- // durable assistant-success event until that contract becomes terminal.
208
- settlement = { outcome: "unknown", reasonCode: "task-completion-pending" };
209
330
  } else if (settlement.outcome === "completed" && sessionRevision === null) {
210
331
  // Streaming text is not durable success until the canonical session
211
332
  // projection confirms it. Still terminate the UI, but do not show draft.
212
333
  settlement = { outcome: "unknown", reasonCode: "session-projection-unavailable" };
213
334
  }
214
335
  if (settlement.outcome === "completed" && messageRef && sessionRevision) {
215
- this.#events.publish("message.completed", { sessionRef: this.sessionRef, operationRef: this.operationRef,
336
+ this.#events.publish("message.completed", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(),
216
337
  messageRef, sessionRevision, truncated: this.#truncated });
217
338
  }
218
- this.#events.publish("operation.settled", { sessionRef: this.sessionRef, operationRef: this.operationRef,
339
+ this.#events.publish("operation.settled", { sessionRef: this.sessionRef, operationRef: this.operationRef, ...this.#correlation(),
219
340
  messageRef, sessionRevision, settlement: settlement.outcome,
341
+ taskStatus,
220
342
  reasonCode: settlement.outcome === "completed" ? null : settlement.reasonCode ?? "operation-settlement-unknown" });
221
343
  }
222
344
  }
@@ -16,13 +16,38 @@ export function rpcUiContext(): object {
16
16
  getThinkingBorderColor: () => plain,
17
17
  getBashModeBorderColor: () => plain
18
18
  });
19
- return new Proxy({}, {
20
- get(_target, property) {
21
- if (property === GATEWAY_RUNTIME_UI_MARKER) return true;
22
- if (property === "theme") return theme;
23
- if (property === "confirm") return () => new Promise<boolean>(() => undefined);
24
- if (property === "select" || property === "input") return async () => undefined;
25
- return () => undefined;
26
- }
27
- });
19
+ const noop = () => undefined;
20
+ // Pi copies this context when wrapping prompts. Keep methods and the ownership
21
+ // marker enumerable so notification delivery and gateway detection survive.
22
+ return {
23
+ [GATEWAY_RUNTIME_UI_MARKER]: true,
24
+ theme,
25
+ confirm: () => new Promise<boolean>(() => undefined),
26
+ select: async () => undefined,
27
+ input: async () => undefined,
28
+ editor: async () => undefined,
29
+ custom: async () => undefined,
30
+ notify: noop,
31
+ onTerminalInput: () => noop,
32
+ setStatus: noop,
33
+ setWorkingMessage: noop,
34
+ setWorkingVisible: noop,
35
+ setWorkingIndicator: noop,
36
+ setHiddenThinkingLabel: noop,
37
+ setWidget: noop,
38
+ setFooter: noop,
39
+ setHeader: noop,
40
+ setTitle: noop,
41
+ pasteToEditor: noop,
42
+ setEditorText: noop,
43
+ getEditorText: () => "",
44
+ addAutocompleteProvider: noop,
45
+ setEditorComponent: noop,
46
+ getEditorComponent: noop,
47
+ getAllThemes: () => [],
48
+ getTheme: noop,
49
+ setTheme: () => ({ success: false, error: "UI not available" }),
50
+ getToolsExpanded: () => false,
51
+ setToolsExpanded: noop
52
+ };
28
53
  }
@@ -5,8 +5,12 @@ import {
5
5
  buildWebUiRuntimeCommand,
6
6
  isWebUiRuntimeActionId
7
7
  } from "../../piagent-core/runtime/workflows/webui-runtime-command.ts";
8
+ import {
9
+ PIAGENT_SERVICE_TIER_RECEIPT_ENTRY_TYPE,
10
+ parseServiceTierReceipt
11
+ } from "../../piagent-core/runtime/model/service-tier-runtime.ts";
8
12
  import type { Catalog } from "../contracts/generated/session-catalog-v1.ts";
9
- import type { Action, Command, Receipt } from "../contracts/generated/runtime-command-v1.ts";
13
+ import type { Action, Command, Output, Receipt } from "../contracts/generated/runtime-command-v1.ts";
10
14
  import { GatewayEventStore } from "./gateway-events.ts";
11
15
  import { SessionRuntimeSupervisor } from "./session-runtime-supervisor.ts";
12
16
 
@@ -15,6 +19,9 @@ const REVISION = /^[A-Za-z0-9][A-Za-z0-9._:~-]{0,159}$/;
15
19
  const MAX_REPLAYS = 200;
16
20
 
17
21
  type Replay = { digest: string; receipt: Receipt };
22
+ type FastControlAssessment = Pick<Receipt, "state" | "resultCode" | "reasonCode">;
23
+
24
+ const FAST_ACTIONS = new Set<Action>(["runtime.fast-status", "runtime.fast-on", "runtime.fast-off"]);
18
25
 
19
26
  function record(value: unknown): value is Record<string, unknown> {
20
27
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -41,6 +48,33 @@ function commandDigest(command: Command): string {
41
48
  argument: command.argument, confirmed: command.confirmed })).digest("hex");
42
49
  }
43
50
 
51
+ function normalizedOutputs(value: unknown): Receipt["outputs"] {
52
+ if (!Array.isArray(value)) return [];
53
+ return value.slice(0, 8).map((item) => {
54
+ if (!record(item)) return item;
55
+ const { details: _details, ...base } = item;
56
+ if (item.customType !== PIAGENT_SERVICE_TIER_RECEIPT_ENTRY_TYPE) return base;
57
+ const details = parseServiceTierReceipt(item.details);
58
+ return details ? { ...base, details } : base;
59
+ }) as Receipt["outputs"];
60
+ }
61
+
62
+ function assessFastControl(action: Action, outputs: readonly Output[]): FastControlAssessment | null {
63
+ if (!FAST_ACTIONS.has(action)) return null;
64
+ const candidates = outputs.filter((output) => output.customType === PIAGENT_SERVICE_TIER_RECEIPT_ENTRY_TYPE);
65
+ if (candidates.length === 0) return { state: "uncertain", resultCode: "effect-unknown", reasonCode: "fast-service-tier-receipt-missing" };
66
+ if (candidates.length !== 1) return { state: "uncertain", resultCode: "effect-unknown", reasonCode: "fast-service-tier-receipt-ambiguous" };
67
+ const details = parseServiceTierReceipt(candidates[0]?.details);
68
+ if (!details) return { state: "uncertain", resultCode: "effect-unknown", reasonCode: "fast-service-tier-receipt-invalid" };
69
+ if (action === "runtime.fast-on" && !details.enabled || action === "runtime.fast-off" && details.enabled) {
70
+ return { state: "uncertain", resultCode: "effect-unknown", reasonCode: "fast-service-tier-receipt-state-mismatch" };
71
+ }
72
+ if (details.reasonCode === "provider-not-supported") {
73
+ return { state: "rejected", resultCode: "unavailable", reasonCode: "provider-not-supported" };
74
+ }
75
+ return { state: "settled", resultCode: "completed", reasonCode: null };
76
+ }
77
+
44
78
  export class RuntimeCommandController {
45
79
  readonly #catalog: () => Promise<Catalog>;
46
80
  readonly #runtimes: SessionRuntimeSupervisor;
@@ -89,11 +123,17 @@ export class RuntimeCommandController {
89
123
  const result = await this.#runtimes.runRuntimeCommand(command.sessionRef, built.command);
90
124
  const after = await this.#readyCatalog();
91
125
  const afterRow = after.sessions.find((session) => session.sessionRef === command.sessionRef);
92
- const zeroTurnViolation = built.spec.effect === "read-only" && result.modelCallObserved;
93
- const receipt = this.#receipt(command, zeroTurnViolation ? "uncertain" : "settled",
94
- zeroTurnViolation ? "effect-unknown" : "completed",
95
- zeroTurnViolation ? "read-only-command-started-model-call" : null,
96
- afterRow?.sessionRevision ?? null, result.modelCallObserved, result.outputs as Receipt["outputs"]);
126
+ const outputs = normalizedOutputs(result.outputs);
127
+ const fastControl = assessFastControl(command.action, outputs);
128
+ const zeroTurnExpected = built.spec.effect === "read-only" || built.spec.effect === "session-setting";
129
+ const zeroTurnViolation = zeroTurnExpected && result.modelCallObserved;
130
+ const zeroTurnReason = built.spec.effect === "session-setting"
131
+ ? "session-setting-command-started-model-call"
132
+ : "read-only-command-started-model-call";
133
+ const receipt = this.#receipt(command, zeroTurnViolation ? "uncertain" : fastControl?.state ?? "settled",
134
+ zeroTurnViolation ? "effect-unknown" : fastControl?.resultCode ?? "completed",
135
+ zeroTurnViolation ? zeroTurnReason : fastControl?.reasonCode ?? null,
136
+ afterRow?.sessionRevision ?? null, result.modelCallObserved, outputs);
97
137
  this.#events.publish("session.changed", { catalogRevision: after.catalogRevision, session: afterRow ?? row });
98
138
  return this.#settle(command, digest, receipt);
99
139
  } catch (error) {
@@ -1,4 +1,17 @@
1
1
  import { redactSensitiveText } from "../../piagent-core/security/sensitive-data.js";
2
+ import {
3
+ PIAGENT_SERVICE_TIER_RECEIPT_ENTRY_TYPE,
4
+ parseServiceTierReceipt,
5
+ type ServiceTierReceipt
6
+ } from "../../piagent-core/runtime/model/service-tier-runtime.ts";
7
+
8
+ type RuntimeCommandOutput = {
9
+ customType: string;
10
+ content: string;
11
+ truncated: boolean;
12
+ redacted: boolean;
13
+ details?: ServiceTierReceipt;
14
+ };
2
15
 
3
16
  export async function executePermissionCommand(session: any,
4
17
  permissionMode: "read-only" | "workspace-write" | "trusted-full-access"): Promise<void> {
@@ -12,7 +25,7 @@ export async function executePermissionCommand(session: any,
12
25
  }
13
26
 
14
27
  export async function executeRuntimeCommand(session: any, command: string): Promise<{
15
- outputs: Array<{ customType: string; content: string; truncated: boolean; redacted: boolean }>;
28
+ outputs: RuntimeCommandOutput[];
16
29
  modelCallObserved: boolean;
17
30
  }> {
18
31
  const before = Array.isArray(session.messages) ? session.messages.length : 0;
@@ -22,8 +35,10 @@ export async function executeRuntimeCommand(session: any, command: string): Prom
22
35
  const source = typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? "");
23
36
  const bounded = source.slice(0, 12_000), redacted = redactSensitiveText(bounded);
24
37
  const rawType = String(message.customType ?? "runtime-output");
38
+ const details = rawType === PIAGENT_SERVICE_TIER_RECEIPT_ENTRY_TYPE
39
+ ? parseServiceTierReceipt(message.details) : null;
25
40
  return { customType: /^[A-Za-z0-9._-]{1,120}$/.test(rawType) ? rawType : "runtime-output", content: redacted.text,
26
- truncated: source.length > bounded.length, redacted: redacted.redacted };
41
+ truncated: source.length > bounded.length, redacted: redacted.redacted, ...(details ? { details } : {}) };
27
42
  });
28
43
  return { outputs, modelCallObserved: added.some((message: any) => message?.role === "assistant") };
29
44
  }
@@ -2,6 +2,7 @@ import { createHmac } from "node:crypto";
2
2
  import path from "node:path";
3
3
 
4
4
  import { redactSensitiveText } from "../../piagent-core/security/sensitive-data.js";
5
+ import { workflowCommandPattern } from "../../piagent-core/runtime/workflows/webui-workflow.ts";
5
6
  import type { Catalog, SessionRow } from "../contracts/generated/session-catalog-v1.ts";
6
7
  import type { MetadataSnapshot, SessionMetadata } from "./session-metadata-store.ts";
7
8
  import { projectRefForCwd, sessionRefForPath } from "../ownership/session-refs.ts";
@@ -54,7 +55,12 @@ function display(value: unknown, maximum: number, fallback: string): string {
54
55
  return (clean || fallback).slice(0, maximum);
55
56
  }
56
57
 
57
- const INTERNAL_FRESH_TRANSITION = /(?:^|\b)(?:\/fresh\s+(?:task|scout|be-to-fe)|(?:task|scout|be-to-fe):)\b[\s\S]{0,180}\bRead task intake from \.pi\/task-inbox\//i;
58
+ const WORKFLOW_PATTERN = workflowCommandPattern({ aliases: false });
59
+ const INTERNAL_FRESH_TRANSITION = new RegExp(
60
+ `(?:^|\\b)(?:\\/fresh\\s+(?:${WORKFLOW_PATTERN})|(?:${WORKFLOW_PATTERN}):)\\b[\\s\\S]{0,180}\\bRead task intake from \\.pi\\/task-inbox\\/`, "i"
61
+ );
62
+ const LEADING_WORKFLOW = new RegExp(`^\\/(?:fresh\\s+)?(?:${WORKFLOW_PATTERN})\\s+`, "i");
63
+ const LEADING_WORKFLOW_LABEL = new RegExp(`^(?:${WORKFLOW_PATTERN}):\\s*`, "i");
58
64
 
59
65
  function atWordBoundary(value: string, maximum: number): string {
60
66
  if (value.length <= maximum) return value;
@@ -78,8 +84,8 @@ export function projectedSessionTitle(info: Pick<PiSessionInfo, "name" | "firstM
78
84
  const internal = INTERNAL_FRESH_TRANSITION.test(source) || INTERNAL_FRESH_TRANSITION.test(first)
79
85
  || /\.pi\/task-inbox\//i.test(source);
80
86
  const cleaned = display(source, 500, "")
81
- .replace(/^\/(?:fresh\s+)?(?:task|scout|be-to-fe)\s+/i, "")
82
- .replace(/^(?:task|scout|be-to-fe):\s*/i, "")
87
+ .replace(LEADING_WORKFLOW, "")
88
+ .replace(LEADING_WORKFLOW_LABEL, "")
83
89
  .replace(/^[-#*>\s]+/, "")
84
90
  // Keep underscores: the shared redactor deliberately emits
85
91
  // [REDACTED_SECRET], and title cleanup must not mutate that proof marker.
@@ -6,6 +6,7 @@ import { buildWebUiWorkflowCommand, isWebUiWorkflowId, type WebUiWorkflowId } fr
6
6
  import { GatewayEventStore } from "./gateway-events.ts";
7
7
  import { SessionCommandStore, type SessionAction, type SessionCommandIdentity } from "./session-command-store.ts";
8
8
  import { SessionRuntimeSupervisor } from "./session-runtime-supervisor.ts";
9
+ import type { SessionSendResult } from "./session-prompt-dispatch.ts";
9
10
  import { SessionMetadataStore } from "./session-metadata-store.ts";
10
11
 
11
12
  const REF = /^[A-Za-z0-9][A-Za-z0-9._~-]{0,159}$/;
@@ -125,9 +126,9 @@ export class SessionCommandController {
125
126
  }
126
127
 
127
128
  async #execute(command: SessionCommand): Promise<Receipt> {
128
- const current = await this.#readyCatalog(), row = command.sessionRef ? current.sessions.find((item) => item.sessionRef === command.sessionRef) : null;
129
129
  const replay = this.#store.lookup(command);
130
130
  if (replay.state === "settled") return { ...replay.receipt!, deduplicated: true };
131
+ const current = await this.#readyCatalog(), row = command.sessionRef ? current.sessions.find((item) => item.sessionRef === command.sessionRef) : null;
131
132
  if (replay.state === "conflict") return this.#rejected(command, current, row, "invalid-command", "idempotency-payload-mismatch");
132
133
  if (replay.state === "unavailable") return this.#rejected(command, current, row, "unavailable", "session-command-journal-unavailable");
133
134
  if (replay.state === "pending") {
@@ -148,7 +149,9 @@ export class SessionCommandController {
148
149
  catch { return this.#rejected(command, current, row, "unavailable", "session-command-admission-failed"); }
149
150
  let targetSessionRef = command.sessionRef;
150
151
  let attachmentReservation: { commit(): void; release(): void } | null = null;
151
- let sendAttempted = false;
152
+ let sendAttempted = false, dispatchCommitted = false;
153
+ let deferredDispatch: Pick<SessionSendResult, "dispatch" | "cancel"> | null = null;
154
+ let observedCatalog = current, observedRow = row;
152
155
  try {
153
156
  let resultCode: "created" | "acquired" | "released" | "started" | "queued" | "steered" | "aborted" | "model-changed" | "thinking-changed" | "permission-changed"
154
157
  | "renamed" | "pinned" | "unpinned" | "archived" | "unarchived" | "forked" | "no-change",
@@ -172,12 +175,15 @@ export class SessionCommandController {
172
175
  }
173
176
  const created = await this.#readyCatalog(), createdRow = created.sessions.find((item) => item.sessionRef === targetSessionRef);
174
177
  if (!createdRow) throw new Error("session-catalog-refresh-failed");
178
+ observedCatalog = created; observedRow = createdRow;
175
179
  if (command.payload.deferInitialMessage === true) resultCode = "created";
176
180
  else {
177
181
  const message = buildWebUiWorkflowCommand((command.payload.workflow as WebUiWorkflowId | undefined) ?? null,
178
182
  String(command.payload.message));
179
183
  const sent = await this.#runtimes.send(targetSessionRef, { delivery: "new-operation", message,
180
- expectedOperationRef: null }, createdRow.sessionRevision);
184
+ messageRequestId: String(command.payload.messageRequestId), expectedOperationRef: null },
185
+ createdRow.sessionRevision, { deferDispatch: true });
186
+ deferredDispatch = sent;
181
187
  resultCode = sent.resultCode === "started" ? "started" : sent.resultCode; operationRef = sent.operationRef;
182
188
  }
183
189
  } else if (command.action === "session.acquire") { await this.#runtimes.acquire(command.sessionRef!); resultCode = "acquired"; }
@@ -186,6 +192,7 @@ export class SessionCommandController {
186
192
  await this.#runtimes.acquire(command.sessionRef!);
187
193
  const acquired = await this.#readyCatalog(), acquiredRow = acquired.sessions.find((item) => item.sessionRef === command.sessionRef);
188
194
  if (!acquiredRow) throw new Error("session-catalog-refresh-failed");
195
+ observedCatalog = acquired; observedRow = acquiredRow;
189
196
  const payload = command.payload as { delivery: "new-operation" | "follow-up" | "steer"; message: string;
190
197
  expectedOperationRef: string | null; messageRequestId: string; attachmentRefs: string[]; workflow?: WebUiWorkflowId };
191
198
  // Staged refs are claimed once, here, before the runtime is asked to
@@ -198,9 +205,10 @@ export class SessionCommandController {
198
205
  if (!this.#prepareAttachments && payload.attachmentRefs.length > 0) throw new Error("session-attachment-unavailable");
199
206
  sendAttempted = true;
200
207
  const message = buildWebUiWorkflowCommand(payload.workflow ?? null, prepared.text);
201
- const sent = await this.#runtimes.send(command.sessionRef!, { ...payload, message, images: prepared.images },
202
- acquiredRow.sessionRevision);
203
- prepared.commit();
208
+ const sent = await this.#runtimes.send(command.sessionRef!, { ...payload, message,
209
+ messageRequestId: payload.messageRequestId, images: prepared.images },
210
+ acquiredRow.sessionRevision, { deferDispatch: true });
211
+ deferredDispatch = sent;
204
212
  resultCode = sent.resultCode; operationRef = sent.operationRef;
205
213
  } else if (command.action === "session.abort") {
206
214
  operationRef = String(command.payload.operationRef);
@@ -239,15 +247,27 @@ export class SessionCommandController {
239
247
  }
240
248
  const after = await this.#readyCatalog(), afterRow = after.sessions.find((item) => item.sessionRef === targetSessionRef);
241
249
  if (!afterRow) throw new Error("session-catalog-refresh-failed");
250
+ observedCatalog = after; observedRow = afterRow;
242
251
  const receipt = this.#settled(command, after, afterRow, resultCode, operationRef);
243
252
  try { this.#store.settle(command, receipt, this.#now()); }
244
- catch { return this.#uncertain(command, after, afterRow, "session-command-settlement-not-durable"); }
253
+ catch {
254
+ deferredDispatch?.cancel?.(); try { attachmentReservation?.release(); } catch { /* staged refs remain unavailable to this command */ }
255
+ return this.#uncertain(command, after, afterRow, "session-command-settlement-not-durable");
256
+ }
257
+ if (attachmentReservation) {
258
+ try { attachmentReservation.commit(); } catch { /* prepared bytes remain dispatchable; the one-shot registry fails closed */ }
259
+ attachmentReservation = null;
260
+ }
245
261
  this.#events.publish("session.changed", { catalogRevision: after.catalogRevision, session: afterRow });
262
+ dispatchCommitted = true; deferredDispatch?.dispatch?.();
246
263
  return receipt;
247
264
  } catch (cause) {
248
- const after = await this.#readyCatalog(), afterRow = after.sessions.find((item) => item.sessionRef === targetSessionRef) ?? row;
265
+ if (!dispatchCommitted) deferredDispatch?.cancel?.();
266
+ let after = observedCatalog;
267
+ try { after = await this.#readyCatalog(); } catch { /* the last proven catalog remains authoritative */ }
268
+ const afterRow = after.sessions.find((item) => item.sessionRef === targetSessionRef) ?? observedRow;
249
269
  const message = cause instanceof Error ? cause.message : "session-command-failed";
250
- const noDispatchEffect = command.action === "session.send" && (!sendAttempted
270
+ const noDispatchEffect = command.action === "session.send" && (!sendAttempted || Boolean(deferredDispatch && !dispatchCommitted)
251
271
  || /^(session-runtime-unavailable|session-operation-conflict|session-owner-conflict|session-runtime-busy)$/.test(message));
252
272
  if (attachmentReservation) {
253
273
  try { if (noDispatchEffect) attachmentReservation.release(); else attachmentReservation.commit(); }
@@ -25,15 +25,8 @@ export function effectiveThinkingLevel(session: any): string | null {
25
25
  return THINKING_LEVELS.has(level) ? level : null;
26
26
  }
27
27
 
28
- export async function configureSessionOptions(session: any, modelRef: string | null,
29
- thinkingLevel: string): Promise<EffectiveSessionOptions> {
30
- if (modelRef) {
31
- const models = session.modelRuntime?.getAvailableSnapshot?.() ?? [];
32
- const model = models.find((value: any) => webUiModelRef(String(value.provider ?? ""),
33
- String(value.id ?? value.modelId ?? "")) === modelRef);
34
- try { if (model) await session.setModel(model); } catch { /* Canonical read-back below decides the effect. */ }
35
- }
36
- try { await session.setThinkingLevel(thinkingLevel); } catch { /* Canonical read-back below decides the effect. */ }
28
+ export function inspectEffectiveSessionOptions(session: any, modelRef: string | null,
29
+ thinkingLevel: string): EffectiveSessionOptions {
37
30
  const effectiveModel = effectiveModelRef(session), effectiveThinking = effectiveThinkingLevel(session);
38
31
  if (!effectiveModel) return { state: "unknown", modelRef: null,
39
32
  thinkingLevel: effectiveThinking, reasonCode: "session-model-effect-unknown" };