gsd-pi 2.80.0-dev.2be7caf18 → 2.80.0-dev.3065f7bfa

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 (268) hide show
  1. package/README.md +1 -0
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/phases.js +178 -108
  4. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  5. package/dist/resources/extensions/gsd/auto/run-unit.js +20 -30
  6. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  7. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  9. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -4
  10. package/dist/resources/extensions/gsd/auto-prompts.js +90 -15
  11. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  12. package/dist/resources/extensions/gsd/auto-start.js +197 -6
  13. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  14. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  15. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  16. package/dist/resources/extensions/gsd/auto.js +79 -24
  17. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +42 -2
  18. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  19. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  20. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +9 -3
  21. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  22. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  23. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +238 -28
  25. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  26. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  27. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  28. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  29. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  30. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  31. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  32. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  33. package/dist/resources/extensions/gsd/git-service.js +36 -4
  34. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  35. package/dist/resources/extensions/gsd/guided-flow.js +66 -32
  36. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  37. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  38. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  39. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  40. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  41. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  42. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  43. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  44. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  45. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  46. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  47. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  48. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  49. package/dist/resources/extensions/gsd/unit-runtime.js +11 -0
  50. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  51. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  52. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  53. package/dist/web/standalone/.next/BUILD_ID +1 -1
  54. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  55. package/dist/web/standalone/.next/build-manifest.json +2 -2
  56. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.html +1 -1
  74. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  81. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  83. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  84. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  85. package/package.json +3 -3
  86. package/packages/mcp-server/src/workflow-tools.test.ts +9 -2
  87. package/packages/native/tsconfig.tsbuildinfo +1 -1
  88. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  89. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  90. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  91. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  92. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  93. package/packages/pi-agent-core/dist/agent.js +2 -0
  94. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  95. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  96. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  97. package/packages/pi-agent-core/dist/index.js +2 -0
  98. package/packages/pi-agent-core/dist/index.js.map +1 -1
  99. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  100. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  101. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  102. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  103. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  104. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  105. package/packages/pi-agent-core/dist/types.js.map +1 -1
  106. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  107. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  108. package/packages/pi-agent-core/src/agent.ts +8 -0
  109. package/packages/pi-agent-core/src/index.ts +2 -0
  110. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  111. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  112. package/packages/pi-agent-core/src/types.ts +14 -0
  113. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  114. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  115. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  116. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  117. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  118. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  119. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  120. package/packages/pi-coding-agent/dist/core/agent-session.js +41 -7
  121. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  122. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  124. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  126. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  127. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -6
  128. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  129. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +3 -3
  130. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +32 -1
  132. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  134. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  135. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  136. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  137. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  138. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  139. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  140. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  141. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  143. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  144. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  145. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  146. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  147. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  149. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  150. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  151. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  152. package/packages/pi-coding-agent/src/core/agent-session.ts +45 -7
  153. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  154. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +3 -3
  155. package/packages/pi-coding-agent/src/core/extensions/runner.ts +5 -5
  156. package/packages/pi-coding-agent/src/core/extensions/types.ts +35 -1
  157. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  158. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  159. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  160. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  161. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  162. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  163. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
  164. package/src/resources/extensions/gsd/auto/phases.ts +251 -172
  165. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  166. package/src/resources/extensions/gsd/auto/run-unit.ts +25 -30
  167. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  168. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  169. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  170. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  171. package/src/resources/extensions/gsd/auto-prompts.ts +95 -14
  172. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  173. package/src/resources/extensions/gsd/auto-start.ts +230 -9
  174. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  175. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  176. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  177. package/src/resources/extensions/gsd/auto.ts +87 -19
  178. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +49 -1
  179. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  180. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  181. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +10 -3
  182. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  183. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  184. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  185. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +283 -28
  186. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  187. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  188. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  189. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  190. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  191. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  192. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  193. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  194. package/src/resources/extensions/gsd/git-service.ts +46 -8
  195. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  196. package/src/resources/extensions/gsd/guided-flow.ts +84 -39
  197. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  198. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  199. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  200. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  201. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  202. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  203. package/src/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  204. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  205. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  206. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  207. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  208. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  209. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +417 -10
  210. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  211. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  212. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  213. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  214. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +3 -1
  215. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  216. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  217. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  218. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  219. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  220. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  221. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  222. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  223. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  224. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  225. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  226. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  227. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  228. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  229. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  230. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  231. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  232. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  233. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  234. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  235. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  236. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  237. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  238. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  239. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  240. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  241. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  242. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  243. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  244. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +106 -0
  245. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  246. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  247. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +38 -0
  248. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  249. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  250. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  251. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  252. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  253. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  254. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  255. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  256. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  257. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  258. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  259. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  260. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  261. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  262. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  263. package/src/resources/extensions/gsd/unit-runtime.ts +11 -0
  264. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  265. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  266. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  267. /package/dist/web/standalone/.next/static/{3EDDd9ULaybSupPoA_vf- → O2WvnXROue6l7nAp_4dhC}/_buildManifest.js +0 -0
  268. /package/dist/web/standalone/.next/static/{3EDDd9ULaybSupPoA_vf- → O2WvnXROue6l7nAp_4dhC}/_ssgManifest.js +0 -0
@@ -0,0 +1,287 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Provider-boundary token payload audit helpers.
3
+
4
+ import type { Context, ImageContent, Message, TextContent, Tool } from "@gsd/pi-ai";
5
+ import type { AgentMessage } from "./types.js";
6
+
7
+ const CHARS_PER_TOKEN = 4;
8
+ const LARGEST_MESSAGE_LIMIT = 5;
9
+ const LARGEST_TOOL_LIMIT = 10;
10
+ const LARGEST_CUSTOM_MESSAGE_LIMIT = 5;
11
+
12
+ export interface TokenAuditMessageSummary {
13
+ index: number;
14
+ role: string;
15
+ type: string;
16
+ chars: number;
17
+ }
18
+
19
+ export interface TokenAuditToolSummary {
20
+ name: string;
21
+ chars: number;
22
+ }
23
+
24
+ export interface TokenAuditCustomMessageSummary {
25
+ index: number;
26
+ role: string;
27
+ customType?: string;
28
+ chars: number;
29
+ }
30
+
31
+ export interface TokenAuditSummary {
32
+ systemChars: number;
33
+ toolSchemaChars: number;
34
+ messageCharsByRole: Record<string, number>;
35
+ toolResultChars: number;
36
+ customMessageChars: number;
37
+ imageCount: number;
38
+ estimatedInputTokens: number;
39
+ messageCount: number;
40
+ toolCount: number;
41
+ largestMessages: TokenAuditMessageSummary[];
42
+ largestTools: TokenAuditToolSummary[];
43
+ largestCustomMessages: TokenAuditCustomMessageSummary[];
44
+ }
45
+
46
+ export interface ProviderPayloadAuditSummary {
47
+ payloadChars: number;
48
+ messageCharsByRole: Record<string, number>;
49
+ toolSchemaChars: number;
50
+ imageCount: number;
51
+ messageCount: number;
52
+ toolCount: number;
53
+ largestMessages: TokenAuditMessageSummary[];
54
+ largestTools: TokenAuditToolSummary[];
55
+ }
56
+
57
+ export function buildTokenAuditSummary(context: Context, sourceMessages: AgentMessage[]): TokenAuditSummary {
58
+ const systemChars = context.systemPrompt?.length ?? 0;
59
+ const toolSummaries = summarizeTools(context.tools ?? []);
60
+ const toolSchemaChars = toolSummaries.reduce((sum, tool) => sum + tool.chars, 0);
61
+ const messageSummaries = context.messages.map((message, index) => summarizeMessage(message, index));
62
+ const messageCharsByRole: Record<string, number> = {};
63
+ let toolResultChars = 0;
64
+ let imageCount = 0;
65
+
66
+ for (const summary of messageSummaries) {
67
+ messageCharsByRole[summary.role] = (messageCharsByRole[summary.role] ?? 0) + summary.chars;
68
+ }
69
+
70
+ for (const message of context.messages) {
71
+ imageCount += countImagesInMessage(message);
72
+ if (message.role === "toolResult") {
73
+ toolResultChars += countContentChars(message.content);
74
+ }
75
+ }
76
+
77
+ const customMessageSummaries = summarizeCustomMessages(sourceMessages);
78
+ const customMessageChars = customMessageSummaries.reduce((sum, message) => sum + message.chars, 0);
79
+
80
+ const totalChars =
81
+ systemChars +
82
+ toolSchemaChars +
83
+ messageSummaries.reduce((sum, message) => sum + message.chars, 0);
84
+
85
+ return {
86
+ systemChars,
87
+ toolSchemaChars,
88
+ messageCharsByRole,
89
+ toolResultChars,
90
+ customMessageChars,
91
+ imageCount,
92
+ estimatedInputTokens: Math.ceil(totalChars / CHARS_PER_TOKEN),
93
+ messageCount: context.messages.length,
94
+ toolCount: context.tools?.length ?? 0,
95
+ largestMessages: [...messageSummaries].sort((a, b) => b.chars - a.chars).slice(0, LARGEST_MESSAGE_LIMIT),
96
+ largestTools: [...toolSummaries].sort((a, b) => b.chars - a.chars).slice(0, LARGEST_TOOL_LIMIT),
97
+ largestCustomMessages: [...customMessageSummaries]
98
+ .sort((a, b) => b.chars - a.chars)
99
+ .slice(0, LARGEST_CUSTOM_MESSAGE_LIMIT),
100
+ };
101
+ }
102
+
103
+ export function maybeLogTokenAudit(context: Context, sourceMessages: AgentMessage[]): void {
104
+ if (process.env.PI_TOKEN_AUDIT !== "1") return;
105
+ const summary = buildTokenAuditSummary(context, sourceMessages);
106
+ process.stderr.write(`${JSON.stringify({ type: "token_audit", summary })}\n`);
107
+ }
108
+
109
+ export function buildProviderPayloadAuditSummary(payload: unknown): ProviderPayloadAuditSummary {
110
+ const record = asRecord(payload);
111
+ const messages = extractProviderMessages(record);
112
+ const tools = extractProviderTools(record);
113
+ const messageSummaries = messages.map((message, index) => summarizeProviderMessage(message, index));
114
+ const toolSummaries = tools.map((tool) => summarizeProviderTool(tool));
115
+ const messageCharsByRole: Record<string, number> = {};
116
+ let imageCount = 0;
117
+
118
+ for (const summary of messageSummaries) {
119
+ messageCharsByRole[summary.role] = (messageCharsByRole[summary.role] ?? 0) + summary.chars;
120
+ }
121
+ for (const message of messages) {
122
+ imageCount += countImagesInValue(message);
123
+ }
124
+
125
+ return {
126
+ payloadChars: safeJsonLength(payload),
127
+ messageCharsByRole,
128
+ toolSchemaChars: toolSummaries.reduce((sum, tool) => sum + tool.chars, 0),
129
+ imageCount,
130
+ messageCount: messages.length,
131
+ toolCount: tools.length,
132
+ largestMessages: [...messageSummaries].sort((a, b) => b.chars - a.chars).slice(0, LARGEST_MESSAGE_LIMIT),
133
+ largestTools: [...toolSummaries].sort((a, b) => b.chars - a.chars).slice(0, LARGEST_TOOL_LIMIT),
134
+ };
135
+ }
136
+
137
+ export function maybeLogProviderPayloadAudit(payload: unknown, phase: string): void {
138
+ if (process.env.PI_TOKEN_AUDIT !== "1") return;
139
+ const summary = buildProviderPayloadAuditSummary(payload);
140
+ process.stderr.write(`${JSON.stringify({ type: "token_audit_provider_payload", phase, summary })}\n`);
141
+ }
142
+
143
+ function summarizeMessage(message: Message, index: number): TokenAuditMessageSummary {
144
+ return {
145
+ index,
146
+ role: message.role,
147
+ type: messageType(message),
148
+ chars: safeJsonLength(message),
149
+ };
150
+ }
151
+
152
+ function messageType(message: Message): string {
153
+ if (message.role === "assistant") {
154
+ const types = new Set(message.content.map((content) => content.type));
155
+ return types.size > 0 ? Array.from(types).join("+") : "assistant";
156
+ }
157
+ if (message.role === "toolResult") return message.toolName || "toolResult";
158
+ if (typeof message.content === "string") return "text";
159
+ const types = new Set(message.content.map((content) => content.type));
160
+ return types.size > 0 ? Array.from(types).join("+") : "user";
161
+ }
162
+
163
+ function summarizeTools(tools: Tool[]): TokenAuditToolSummary[] {
164
+ return tools.map((tool) => ({
165
+ name: tool.name,
166
+ chars: safeJsonLength(tool),
167
+ }));
168
+ }
169
+
170
+ function summarizeCustomMessages(messages: AgentMessage[]): TokenAuditCustomMessageSummary[] {
171
+ return messages.flatMap((message, index) => {
172
+ if (!isCustomOrInjectedMessage(message)) return [];
173
+ const customType = (message as { customType?: unknown }).customType;
174
+ return [{
175
+ index,
176
+ role: String((message as { role?: unknown }).role ?? "unknown"),
177
+ customType: typeof customType === "string" ? customType : undefined,
178
+ chars: safeJsonLength(message),
179
+ }];
180
+ });
181
+ }
182
+
183
+ function summarizeProviderMessage(message: unknown, index: number): TokenAuditMessageSummary {
184
+ const record = asRecord(message);
185
+ const role = typeof record?.role === "string" ? record.role : "unknown";
186
+ const type = typeof record?.type === "string" ? record.type : role;
187
+ return { index, role, type, chars: safeJsonLength(message) };
188
+ }
189
+
190
+ function summarizeProviderTool(tool: unknown): TokenAuditToolSummary {
191
+ const record = asRecord(tool);
192
+ const name =
193
+ typeof record?.name === "string"
194
+ ? record.name
195
+ : typeof asRecord(record?.function)?.name === "string"
196
+ ? String(asRecord(record?.function)?.name)
197
+ : typeof asRecord(record?.toolSpec)?.name === "string"
198
+ ? String(asRecord(record?.toolSpec)?.name)
199
+ : "unknown";
200
+ return { name, chars: safeJsonLength(tool) };
201
+ }
202
+
203
+ function extractProviderMessages(record: Record<string, unknown> | null): unknown[] {
204
+ const candidates = [
205
+ getArrayField(record, "messages"),
206
+ getArrayField(record, "input"),
207
+ getArrayField(record, "contents"),
208
+ ].filter((value): value is unknown[] => value !== null);
209
+ if (candidates.length > 0) return candidates[0];
210
+ const input = record?.input;
211
+ return typeof input === "string" ? [{ role: "input", content: input }] : [];
212
+ }
213
+
214
+ function extractProviderTools(record: Record<string, unknown> | null): unknown[] {
215
+ const direct = getArrayField(record, "tools")
216
+ ?? getNestedArrayField(record, ["config", "tools"])
217
+ ?? getNestedArrayField(record, ["toolConfig", "tools"])
218
+ ?? getNestedArrayField(record, ["tool_config", "tools"])
219
+ ?? [];
220
+ return direct.flatMap(expandProviderToolEntry);
221
+ }
222
+
223
+ function expandProviderToolEntry(tool: unknown): unknown[] {
224
+ const record = asRecord(tool);
225
+ const functionDeclarations =
226
+ getArrayField(record, "functionDeclarations")
227
+ ?? getArrayField(record, "function_declarations");
228
+ if (functionDeclarations) return functionDeclarations;
229
+ return [tool];
230
+ }
231
+
232
+ function countImagesInMessage(message: Message): number {
233
+ if (!("content" in message) || !Array.isArray(message.content)) return 0;
234
+ return message.content.filter((content): content is ImageContent => content.type === "image").length;
235
+ }
236
+
237
+ function countImagesInValue(value: unknown): number {
238
+ if (!value || typeof value !== "object") return 0;
239
+ if (Array.isArray(value)) {
240
+ return value.reduce((sum, item) => sum + countImagesInValue(item), 0);
241
+ }
242
+ const record = value as Record<string, unknown>;
243
+ let count = record.type === "image" || record.type === "input_image" ? 1 : 0;
244
+ for (const nested of Object.values(record)) {
245
+ count += countImagesInValue(nested);
246
+ }
247
+ return count;
248
+ }
249
+
250
+ function countContentChars(content: string | (TextContent | ImageContent)[]): number {
251
+ if (typeof content === "string") return content.length;
252
+ return content.reduce((sum, block) => {
253
+ if (block.type === "text") return sum + block.text.length;
254
+ if (block.type === "image") return sum + block.data.length;
255
+ return sum;
256
+ }, 0);
257
+ }
258
+
259
+ function isCustomOrInjectedMessage(message: AgentMessage): boolean {
260
+ const role = (message as { role?: unknown }).role;
261
+ return role === "custom" || role === "bashExecution" || role === "branchSummary" || role === "compactionSummary";
262
+ }
263
+
264
+ function asRecord(value: unknown): Record<string, unknown> | null {
265
+ return value && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : null;
266
+ }
267
+
268
+ function getArrayField(record: Record<string, unknown> | null, key: string): unknown[] | null {
269
+ const value = record?.[key];
270
+ return Array.isArray(value) ? value : null;
271
+ }
272
+
273
+ function getNestedArrayField(record: Record<string, unknown> | null, path: string[]): unknown[] | null {
274
+ let current: unknown = record;
275
+ for (const key of path) {
276
+ current = asRecord(current)?.[key];
277
+ }
278
+ return Array.isArray(current) ? current : null;
279
+ }
280
+
281
+ function safeJsonLength(value: unknown): number {
282
+ try {
283
+ return JSON.stringify(value)?.length ?? 0;
284
+ } catch {
285
+ return 0;
286
+ }
287
+ }
@@ -134,6 +134,20 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
134
134
  */
135
135
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
136
136
 
137
+ /**
138
+ * Optional final tool filter applied immediately before each provider call.
139
+ *
140
+ * Use this for runtime policy that depends on the fully active tool set.
141
+ * The returned list is what token audit and the provider request both see.
142
+ * Receives the post-transform AgentMessage context so policy can scope
143
+ * request-local custom messages without inspecting provider payload text.
144
+ */
145
+ filterTools?: (
146
+ tools: AgentTool<any>[],
147
+ signal?: AbortSignal,
148
+ messages?: AgentMessage[],
149
+ ) => AgentTool<any>[] | Promise<AgentTool<any>[]>;
150
+
137
151
  /**
138
152
  * Resolves an API key dynamically for each LLM call.
139
153
  *