create-windy 0.6.12 → 0.6.14

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 (546) hide show
  1. package/dist/cli.js +572 -269
  2. package/package.json +1 -1
  3. package/template/.agents/skills/windy-business-module/SKILL.md +98 -70
  4. package/template/.windy-template.json +3 -3
  5. package/template/AGENTS.md +3 -6
  6. package/template/apps/agent-server/Dockerfile +2 -3
  7. package/template/apps/agent-server/README.md +38 -54
  8. package/template/apps/agent-server/pyproject.toml +0 -1
  9. package/template/apps/agent-server/src/southwind_agent_server/app.py +4 -2
  10. package/template/apps/agent-server/src/southwind_agent_server/attempt_context.py +191 -0
  11. package/template/apps/agent-server/src/southwind_agent_server/attempt_context_projection.py +203 -0
  12. package/template/apps/agent-server/src/southwind_agent_server/client_completion_contracts.py +61 -0
  13. package/template/apps/agent-server/src/southwind_agent_server/client_completion_governance.py +82 -0
  14. package/template/apps/agent-server/src/southwind_agent_server/client_completion_routes.py +121 -0
  15. package/template/apps/agent-server/src/southwind_agent_server/client_completion_runtime.py +158 -0
  16. package/template/apps/agent-server/src/southwind_agent_server/context_message_digest.py +24 -0
  17. package/template/apps/agent-server/src/southwind_agent_server/context_version_contracts.py +71 -0
  18. package/template/apps/agent-server/src/southwind_agent_server/context_version_port.py +307 -0
  19. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +39 -0
  20. package/template/apps/agent-server/src/southwind_agent_server/deterministic.py +2 -0
  21. package/template/apps/agent-server/src/southwind_agent_server/engine.py +9 -1
  22. package/template/apps/agent-server/src/southwind_agent_server/engine_identity.py +2 -0
  23. package/template/apps/agent-server/src/southwind_agent_server/fingerprint.py +15 -0
  24. package/template/apps/agent-server/src/southwind_agent_server/health_routes.py +37 -3
  25. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +46 -26
  26. package/template/apps/agent-server/src/southwind_agent_server/openai_engine_validation.py +32 -0
  27. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +7 -0
  28. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_insert.py +5 -2
  29. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_queries.py +1 -0
  30. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_store.py +6 -1
  31. package/template/apps/agent-server/src/southwind_agent_server/postgres_store.py +3 -2
  32. package/template/apps/agent-server/src/southwind_agent_server/postgres_store_backend.py +1 -0
  33. package/template/apps/agent-server/src/southwind_agent_server/provider_governance.py +21 -0
  34. package/template/apps/agent-server/src/southwind_agent_server/report_lifecycle.py +2 -1
  35. package/template/apps/agent-server/src/southwind_agent_server/report_presenter.py +1 -0
  36. package/template/apps/agent-server/src/southwind_agent_server/report_routes.py +7 -1
  37. package/template/apps/agent-server/src/southwind_agent_server/report_store.py +10 -56
  38. package/template/apps/agent-server/src/southwind_agent_server/report_store_protocol.py +75 -0
  39. package/template/apps/agent-server/src/southwind_agent_server/report_types.py +9 -2
  40. package/template/apps/agent-server/src/southwind_agent_server/runtime_budget.py +74 -0
  41. package/template/apps/agent-server/src/southwind_agent_server/runtime_factory.py +11 -3
  42. package/template/apps/agent-server/src/southwind_agent_server/service.py +41 -65
  43. package/template/apps/agent-server/src/southwind_agent_server/service_control.py +64 -0
  44. package/template/apps/agent-server/src/southwind_agent_server/service_execution.py +3 -0
  45. package/template/apps/agent-server/src/southwind_agent_server/sqlite_errors.py +2 -0
  46. package/template/apps/agent-server/src/southwind_agent_server/sqlite_schema.py +9 -1
  47. package/template/apps/agent-server/src/southwind_agent_server/sqlite_store.py +6 -5
  48. package/template/apps/agent-server/src/southwind_agent_server/store.py +2 -0
  49. package/template/apps/agent-server/src/southwind_agent_server/trajectory.py +137 -0
  50. package/template/apps/agent-server/src/southwind_agent_server/unavailable_engine.py +58 -0
  51. package/template/apps/agent-server/tests/test_api.py +30 -11
  52. package/template/apps/agent-server/tests/test_client_completion.py +230 -0
  53. package/template/apps/agent-server/tests/test_provider_attempt_reporting.py +12 -24
  54. package/template/apps/agent-server/tests/test_report_resilience.py +2 -0
  55. package/template/apps/agent-server/tests/test_report_routes.py +58 -1
  56. package/template/apps/agent-server/tests/test_report_summary_parity.py +1 -0
  57. package/template/apps/agent-server/tests/test_run_capacity.py +2 -0
  58. package/template/apps/agent-server/tests/test_runtime_factory_readiness.py +18 -3
  59. package/template/apps/agent-server/tests/test_trajectory.py +91 -0
  60. package/template/apps/agent-server/uv.lock +0 -259
  61. package/template/apps/server/Dockerfile +9 -4
  62. package/template/apps/server/src/agent/actor-projection-audit.ts +6 -0
  63. package/template/apps/server/src/agent/agent-run-delegation-policy.ts +115 -0
  64. package/template/apps/server/src/agent/agent-session-bootstrap.ts +23 -0
  65. package/template/apps/server/src/agent/{debug-session-facade-provider-failure.test.ts → agent-session-facade-provider-failure.test.ts} +24 -33
  66. package/template/apps/server/src/agent/{debug-session-facade.test.ts → agent-session-facade.test.ts} +34 -45
  67. package/template/apps/server/src/agent/{debug-session-facade.ts → agent-session-facade.ts} +50 -57
  68. package/template/apps/server/src/agent/{debug-session-id.test.ts → agent-session-id.test.ts} +5 -5
  69. package/template/apps/server/src/agent/{debug-session-id.ts → agent-session-id.ts} +7 -7
  70. package/template/apps/server/src/agent/{debug-session-provider-reader.ts → agent-session-provider-reader.ts} +18 -15
  71. package/template/apps/server/src/agent/{debug-session-routes.test.ts → agent-session-routes.test.ts} +16 -16
  72. package/template/apps/server/src/agent/{debug-session-routes.ts → agent-session-routes.ts} +12 -12
  73. package/template/apps/server/src/agent/{debug-session-validation.ts → agent-session-validation.ts} +13 -11
  74. package/template/apps/server/src/agent/client-session/authorization.ts +47 -0
  75. package/template/apps/server/src/agent/client-session/bootstrap.ts +96 -0
  76. package/template/apps/server/src/agent/client-session/capabilities.ts +19 -0
  77. package/template/apps/server/src/agent/client-session/completion.ts +299 -0
  78. package/template/apps/server/src/agent/client-session/contracts.ts +136 -0
  79. package/template/apps/server/src/agent/client-session/digest.ts +39 -0
  80. package/template/apps/server/src/agent/client-session/drizzle-repository.integration.test.ts +170 -0
  81. package/template/apps/server/src/agent/client-session/drizzle-repository.ts +345 -0
  82. package/template/apps/server/src/agent/client-session/errors.ts +28 -0
  83. package/template/apps/server/src/agent/client-session/fixtures/page-agent-1.12.2-request.json +52 -0
  84. package/template/apps/server/src/agent/client-session/host-auth.test.ts +144 -0
  85. package/template/apps/server/src/agent/client-session/host-auth.ts +110 -0
  86. package/template/apps/server/src/agent/client-session/manifest-admission.ts +240 -0
  87. package/template/apps/server/src/agent/client-session/openai-stream.ts +123 -0
  88. package/template/apps/server/src/agent/client-session/presentation.ts +46 -0
  89. package/template/apps/server/src/agent/client-session/remote-provider.test.ts +144 -0
  90. package/template/apps/server/src/agent/client-session/remote-provider.ts +216 -0
  91. package/template/apps/server/src/agent/client-session/repository.ts +225 -0
  92. package/template/apps/server/src/agent/client-session/request.test.ts +69 -0
  93. package/template/apps/server/src/agent/client-session/request.ts +289 -0
  94. package/template/apps/server/src/agent/client-session/revocation.ts +23 -0
  95. package/template/apps/server/src/agent/client-session/routes.ts +315 -0
  96. package/template/apps/server/src/agent/client-session/runtime-audit.ts +42 -0
  97. package/template/apps/server/src/agent/client-session/service.test-support.ts +226 -0
  98. package/template/apps/server/src/agent/client-session/service.test.ts +268 -0
  99. package/template/apps/server/src/agent/client-session/service.ts +346 -0
  100. package/template/apps/server/src/agent/context-memory/attempt-context-contracts.ts +60 -0
  101. package/template/apps/server/src/agent/context-memory/authoritative-source-registry.ts +127 -0
  102. package/template/apps/server/src/agent/context-memory/context-builder.test.ts +160 -0
  103. package/template/apps/server/src/agent/context-memory/context-builder.ts +184 -0
  104. package/template/apps/server/src/agent/context-memory/contracts.ts +284 -0
  105. package/template/apps/server/src/agent/context-memory/digest.ts +22 -0
  106. package/template/apps/server/src/agent/context-memory/memory-authorization.ts +82 -0
  107. package/template/apps/server/src/agent/context-memory/memory-content.ts +69 -0
  108. package/template/apps/server/src/agent/context-memory/memory-object-registry.ts +87 -0
  109. package/template/apps/server/src/agent/context-memory/memory-projector-contracts.ts +121 -0
  110. package/template/apps/server/src/agent/context-memory/memory-projector-validation.ts +155 -0
  111. package/template/apps/server/src/agent/context-memory/memory-projector.test.ts +19 -0
  112. package/template/apps/server/src/agent/context-memory/memory-projector.ts +259 -0
  113. package/template/apps/server/src/agent/context-memory/memory-retrieval-policy.ts +195 -0
  114. package/template/apps/server/src/agent/context-memory/memory-retriever.test.ts +339 -0
  115. package/template/apps/server/src/agent/context-memory/memory-retriever.ts +184 -0
  116. package/template/apps/server/src/agent/context-memory/search-provider-port.test.ts +62 -0
  117. package/template/apps/server/src/agent/context-memory/search-provider-port.ts +75 -0
  118. package/template/apps/server/src/agent/context-memory/working-context-expiry.ts +95 -0
  119. package/template/apps/server/src/agent/context-message-recovery.ts +23 -0
  120. package/template/apps/server/src/agent/context-version-routes.ts +241 -0
  121. package/template/apps/server/src/agent/context-version-runtime.ts +332 -0
  122. package/template/apps/server/src/agent/context-version-support.ts +93 -0
  123. package/template/apps/server/src/agent/context-version-validation.ts +118 -0
  124. package/template/apps/server/src/agent/drizzle-run-binding-repository.ts +11 -0
  125. package/template/apps/server/src/agent/idempotency-key.ts +9 -1
  126. package/template/apps/server/src/agent/memory-runtime-adapters.ts +266 -0
  127. package/template/apps/server/src/agent/memory-scope-binding.ts +14 -0
  128. package/template/apps/server/src/agent/module-ai-port-factory.ts +41 -0
  129. package/template/apps/server/src/agent/provider-input-governance.ts +19 -0
  130. package/template/apps/server/src/agent/remote-runtime-response.ts +162 -0
  131. package/template/apps/server/src/agent/remote-runtime.ts +53 -153
  132. package/template/apps/server/src/agent/run-audit.ts +2 -2
  133. package/template/apps/server/src/agent/run-authorization.test.ts +27 -0
  134. package/template/apps/server/src/agent/run-authorization.ts +60 -1
  135. package/template/apps/server/src/agent/run-binding-repository.ts +9 -0
  136. package/template/apps/server/src/agent/run-browser-authorization.ts +79 -0
  137. package/template/apps/server/src/agent/run-contracts.ts +23 -0
  138. package/template/apps/server/src/agent/run-facade.ts +139 -139
  139. package/template/apps/server/src/agent/run-failure-cleanup.ts +58 -0
  140. package/template/apps/server/src/agent/run-operation-policy.ts +20 -0
  141. package/template/apps/server/src/agent/run-route-input.ts +19 -1
  142. package/template/apps/server/src/agent/run-routes.ts +133 -5
  143. package/template/apps/server/src/agent/run-runtime-request.ts +89 -0
  144. package/template/apps/server/src/agent/run-session-authorization.ts +95 -0
  145. package/template/apps/server/src/agent/run-start-preparation.ts +71 -0
  146. package/template/apps/server/src/agent/runtime-bootstrap-input.ts +42 -0
  147. package/template/apps/server/src/agent/runtime-bootstrap-report.test.ts +53 -1
  148. package/template/apps/server/src/agent/runtime-bootstrap.ts +114 -111
  149. package/template/apps/server/src/agent/runtime-tool-composition.ts +38 -0
  150. package/template/apps/server/src/agent/session-context-source-support.ts +38 -0
  151. package/template/apps/server/src/agent/session-context-source.ts +346 -0
  152. package/template/apps/server/src/agent/session-invalidation/contracts.ts +217 -0
  153. package/template/apps/server/src/agent/session-invalidation/dispatcher.contract.test.ts +333 -0
  154. package/template/apps/server/src/agent/session-invalidation/dispatcher.ts +205 -0
  155. package/template/apps/server/src/agent/session-invalidation/module-authoritative-producer.test.ts +127 -0
  156. package/template/apps/server/src/agent/session-invalidation/module-authoritative-producer.ts +202 -0
  157. package/template/apps/server/src/agent/session-invalidation/read-guard.ts +39 -0
  158. package/template/apps/server/src/agent/session-invalidation/runtime.ts +69 -0
  159. package/template/apps/server/src/agent/session-invalidation/test-envelopes.ts +24 -0
  160. package/template/apps/server/src/agent/session-invalidation/worker.contract.test.ts +135 -0
  161. package/template/apps/server/src/agent/session-invalidation/worker.ts +76 -0
  162. package/template/apps/server/src/agent/session-log/checkpoint-digest.ts +36 -0
  163. package/template/apps/server/src/agent/session-log/domain.ts +123 -0
  164. package/template/apps/server/src/agent/session-log/events.ts +229 -0
  165. package/template/apps/server/src/agent/session-log/history.ts +143 -0
  166. package/template/apps/server/src/agent/session-log/in-memory-repository.ts +340 -0
  167. package/template/apps/server/src/agent/session-log/lifecycle.ts +67 -0
  168. package/template/apps/server/src/agent/session-log/replay-policy.ts +76 -0
  169. package/template/apps/server/src/agent/session-log/repository.ts +103 -0
  170. package/template/apps/server/src/agent/session-log/service.ts +349 -0
  171. package/template/apps/server/src/agent/session-log/session-log.test.ts +282 -0
  172. package/template/apps/server/src/agent/session-persistence/drizzle-context-memory.ts +348 -0
  173. package/template/apps/server/src/agent/session-persistence/drizzle-governed-context.ts +328 -0
  174. package/template/apps/server/src/agent/session-persistence/drizzle-invalidation-outbox.ts +260 -0
  175. package/template/apps/server/src/agent/session-persistence/drizzle-memory-projection-deletion.ts +56 -0
  176. package/template/apps/server/src/agent/session-persistence/drizzle-run-projection-receipt.ts +80 -0
  177. package/template/apps/server/src/agent/session-persistence/drizzle-session-fork.ts +147 -0
  178. package/template/apps/server/src/agent/session-persistence/drizzle-session-list.ts +24 -0
  179. package/template/apps/server/src/agent/session-persistence/drizzle-session-mapping.ts +154 -0
  180. package/template/apps/server/src/agent/session-persistence/drizzle-session-mutations.ts +64 -0
  181. package/template/apps/server/src/agent/session-persistence/drizzle-session-repository.ts +335 -0
  182. package/template/apps/server/src/agent/session-persistence/invalidation-projections.ts +229 -0
  183. package/template/apps/server/src/agent/session-persistence/payload-codec.ts +90 -0
  184. package/template/apps/server/src/agent/session-projection-access.ts +155 -0
  185. package/template/apps/server/src/agent/session-projection-bootstrap.ts +87 -0
  186. package/template/apps/server/src/agent/session-projection-errors.ts +22 -0
  187. package/template/apps/server/src/agent/session-projection-facade.ts +349 -0
  188. package/template/apps/server/src/agent/session-projection-routes.ts +215 -0
  189. package/template/apps/server/src/agent/session-projection-view.ts +137 -0
  190. package/template/apps/server/src/agent/session-result-memory.ts +228 -0
  191. package/template/apps/server/src/agent/session-run-lifecycle.ts +85 -0
  192. package/template/apps/server/src/agent/session-run-link-contracts.ts +56 -0
  193. package/template/apps/server/src/agent/session-run-link.ts +343 -0
  194. package/template/apps/server/src/agent/session-run-recovery.ts +16 -0
  195. package/template/apps/server/src/agent/session-runtime-composition.ts +265 -0
  196. package/template/apps/server/src/agent/session-source-chain-authorizer.ts +141 -0
  197. package/template/apps/server/src/agent/session-terminal-reconciler.ts +100 -0
  198. package/template/apps/server/src/agent/session-turn-state.ts +49 -0
  199. package/template/apps/server/src/agent/tool-audit.ts +3 -3
  200. package/template/apps/server/src/agent/tool-execution-receipt.ts +13 -0
  201. package/template/apps/server/src/agent/tool-host.ts +41 -4
  202. package/template/apps/server/src/agent/tool-registry-composition.ts +52 -0
  203. package/template/apps/server/src/agent/tool-registry.test.ts +5 -5
  204. package/template/apps/server/src/agent/tool-registry.ts +53 -59
  205. package/template/apps/server/src/agent/unavailable-routes.ts +49 -5
  206. package/template/apps/server/src/agent/workflow-durable-runtime-input.ts +32 -0
  207. package/template/apps/server/src/agent/workflow-runtime-bootstrap.ts +59 -0
  208. package/template/apps/server/src/agent-workflow/adapter-dispatch.ts +148 -0
  209. package/template/apps/server/src/agent-workflow/approval-node-adapter.ts +77 -0
  210. package/template/apps/server/src/agent-workflow/artifact-access-error.ts +9 -0
  211. package/template/apps/server/src/agent-workflow/artifact-node-adapter.ts +67 -0
  212. package/template/apps/server/src/agent-workflow/artifact-policy.ts +71 -0
  213. package/template/apps/server/src/agent-workflow/artifact-source-authorization.ts +85 -0
  214. package/template/apps/server/src/agent-workflow/authorization.ts +238 -0
  215. package/template/apps/server/src/agent-workflow/budget-ledger.ts +118 -0
  216. package/template/apps/server/src/agent-workflow/budget-validation.ts +305 -0
  217. package/template/apps/server/src/agent-workflow/canonical-agent-run-binding.ts +17 -0
  218. package/template/apps/server/src/agent-workflow/canonical-agent-run-evidence.ts +142 -0
  219. package/template/apps/server/src/agent-workflow/canonical-agent-run-port.ts +304 -0
  220. package/template/apps/server/src/agent-workflow/canonical-agent-run-remote.ts +64 -0
  221. package/template/apps/server/src/agent-workflow/canonical-json.ts +16 -0
  222. package/template/apps/server/src/agent-workflow/command-drive.ts +195 -0
  223. package/template/apps/server/src/agent-workflow/command-error.ts +9 -0
  224. package/template/apps/server/src/agent-workflow/command-facade.ts +290 -0
  225. package/template/apps/server/src/agent-workflow/command-input.ts +133 -0
  226. package/template/apps/server/src/agent-workflow/condition-node-adapter.ts +69 -0
  227. package/template/apps/server/src/agent-workflow/definition-budget-validation.ts +41 -0
  228. package/template/apps/server/src/agent-workflow/definition-node-validation.ts +197 -0
  229. package/template/apps/server/src/agent-workflow/definition-validation.ts +198 -0
  230. package/template/apps/server/src/agent-workflow/delegated-tool-authorization.ts +15 -0
  231. package/template/apps/server/src/agent-workflow/delegation-child-delivery.ts +129 -0
  232. package/template/apps/server/src/agent-workflow/delegation-execution-authorization.ts +218 -0
  233. package/template/apps/server/src/agent-workflow/delegation-policy-validation.ts +253 -0
  234. package/template/apps/server/src/agent-workflow/delegation-policy.ts +179 -0
  235. package/template/apps/server/src/agent-workflow/drizzle-artifact-port.ts +211 -0
  236. package/template/apps/server/src/agent-workflow/drizzle-artifact-support.ts +152 -0
  237. package/template/apps/server/src/agent-workflow/drizzle-budget-ledger-settlement.ts +271 -0
  238. package/template/apps/server/src/agent-workflow/drizzle-budget-ledger-support.ts +226 -0
  239. package/template/apps/server/src/agent-workflow/drizzle-budget-ledger.ts +189 -0
  240. package/template/apps/server/src/agent-workflow/drizzle-cancellation-reconcile.ts +177 -0
  241. package/template/apps/server/src/agent-workflow/drizzle-delegated-tool-authorization.ts +155 -0
  242. package/template/apps/server/src/agent-workflow/drizzle-delegation-completion.ts +84 -0
  243. package/template/apps/server/src/agent-workflow/drizzle-delegation-lifecycle.ts +139 -0
  244. package/template/apps/server/src/agent-workflow/drizzle-delegation-port.ts +288 -0
  245. package/template/apps/server/src/agent-workflow/drizzle-effect-command-fence.ts +333 -0
  246. package/template/apps/server/src/agent-workflow/drizzle-evaluation-repository.ts +214 -0
  247. package/template/apps/server/src/agent-workflow/drizzle-event-validation.ts +43 -0
  248. package/template/apps/server/src/agent-workflow/drizzle-recovery-admission.ts +115 -0
  249. package/template/apps/server/src/agent-workflow/drizzle-repository-lineage.ts +103 -0
  250. package/template/apps/server/src/agent-workflow/drizzle-repository-mappers.ts +317 -0
  251. package/template/apps/server/src/agent-workflow/drizzle-repository-write.ts +311 -0
  252. package/template/apps/server/src/agent-workflow/drizzle-repository.ts +285 -0
  253. package/template/apps/server/src/agent-workflow/drizzle-side-effect-repository.ts +83 -0
  254. package/template/apps/server/src/agent-workflow/drizzle-write-support.ts +101 -0
  255. package/template/apps/server/src/agent-workflow/durable-continuation-authorization.ts +109 -0
  256. package/template/apps/server/src/agent-workflow/durable-continuation-driver.ts +97 -0
  257. package/template/apps/server/src/agent-workflow/durable-continuation-runtime.ts +173 -0
  258. package/template/apps/server/src/agent-workflow/durable-job-node-adapter.ts +106 -0
  259. package/template/apps/server/src/agent-workflow/effect-command-fence.ts +250 -0
  260. package/template/apps/server/src/agent-workflow/evaluation-evidence-coordinates.ts +225 -0
  261. package/template/apps/server/src/agent-workflow/evaluation-evidence-metrics.ts +280 -0
  262. package/template/apps/server/src/agent-workflow/evaluation-evidence-reader.ts +326 -0
  263. package/template/apps/server/src/agent-workflow/evaluation-metrics-validation.ts +85 -0
  264. package/template/apps/server/src/agent-workflow/evaluation-projection.ts +70 -0
  265. package/template/apps/server/src/agent-workflow/evaluation-repository.ts +134 -0
  266. package/template/apps/server/src/agent-workflow/evaluation-service.ts +292 -0
  267. package/template/apps/server/src/agent-workflow/evaluation-tool-registration.ts +95 -0
  268. package/template/apps/server/src/agent-workflow/evaluation-validation.ts +331 -0
  269. package/template/apps/server/src/agent-workflow/event-validation.ts +277 -0
  270. package/template/apps/server/src/agent-workflow/governed-tool-schema.ts +55 -0
  271. package/template/apps/server/src/agent-workflow/in-memory-evaluation-repository.ts +123 -0
  272. package/template/apps/server/src/agent-workflow/in-memory-mutation-validation.ts +154 -0
  273. package/template/apps/server/src/agent-workflow/in-memory-repository-support.ts +277 -0
  274. package/template/apps/server/src/agent-workflow/in-memory-repository.ts +339 -0
  275. package/template/apps/server/src/agent-workflow/in-memory-side-effect-store.ts +78 -0
  276. package/template/apps/server/src/agent-workflow/input-receipt.ts +55 -0
  277. package/template/apps/server/src/agent-workflow/model-node-adapter.ts +86 -0
  278. package/template/apps/server/src/agent-workflow/model-pricing-catalog.ts +215 -0
  279. package/template/apps/server/src/agent-workflow/node-adapter-factory.ts +83 -0
  280. package/template/apps/server/src/agent-workflow/node-adapters.ts +50 -0
  281. package/template/apps/server/src/agent-workflow/node-execution-ports.ts +185 -0
  282. package/template/apps/server/src/agent-workflow/node-input-receipt-port.ts +42 -0
  283. package/template/apps/server/src/agent-workflow/node-result-receipt.ts +50 -0
  284. package/template/apps/server/src/agent-workflow/platform-node-adapter-support.ts +185 -0
  285. package/template/apps/server/src/agent-workflow/platform-node-adapters.ts +256 -0
  286. package/template/apps/server/src/agent-workflow/platform-node-approval.ts +146 -0
  287. package/template/apps/server/src/agent-workflow/platform-node-direct-adapters.ts +65 -0
  288. package/template/apps/server/src/agent-workflow/production-delegation-scope.ts +58 -0
  289. package/template/apps/server/src/agent-workflow/production-node-policies.ts +62 -0
  290. package/template/apps/server/src/agent-workflow/query-service.ts +198 -0
  291. package/template/apps/server/src/agent-workflow/release.ts +96 -0
  292. package/template/apps/server/src/agent-workflow/repository.ts +157 -0
  293. package/template/apps/server/src/agent-workflow/routes.ts +307 -0
  294. package/template/apps/server/src/agent-workflow/runtime-composition.ts +308 -0
  295. package/template/apps/server/src/agent-workflow/scheduler-cancellation-reconcile.ts +253 -0
  296. package/template/apps/server/src/agent-workflow/scheduler-cancellation-support.ts +145 -0
  297. package/template/apps/server/src/agent-workflow/scheduler-cancellation.ts +2 -0
  298. package/template/apps/server/src/agent-workflow/scheduler-context.ts +85 -0
  299. package/template/apps/server/src/agent-workflow/scheduler-deadline.ts +65 -0
  300. package/template/apps/server/src/agent-workflow/scheduler-effect-result.ts +205 -0
  301. package/template/apps/server/src/agent-workflow/scheduler-execution-convergence.ts +174 -0
  302. package/template/apps/server/src/agent-workflow/scheduler-execution.ts +211 -0
  303. package/template/apps/server/src/agent-workflow/scheduler-failure.ts +102 -0
  304. package/template/apps/server/src/agent-workflow/scheduler-join-cancellation.ts +282 -0
  305. package/template/apps/server/src/agent-workflow/scheduler-mutation-queue.ts +13 -0
  306. package/template/apps/server/src/agent-workflow/scheduler-node-timeout.ts +139 -0
  307. package/template/apps/server/src/agent-workflow/scheduler-parallel-dispatch.ts +99 -0
  308. package/template/apps/server/src/agent-workflow/scheduler-recovery-activation.ts +63 -0
  309. package/template/apps/server/src/agent-workflow/scheduler-recovery-budget.ts +41 -0
  310. package/template/apps/server/src/agent-workflow/scheduler-recovery-effect.ts +331 -0
  311. package/template/apps/server/src/agent-workflow/scheduler-recovery-event-time.ts +26 -0
  312. package/template/apps/server/src/agent-workflow/scheduler-recovery-failed-policy.ts +129 -0
  313. package/template/apps/server/src/agent-workflow/scheduler-recovery-node.ts +208 -0
  314. package/template/apps/server/src/agent-workflow/scheduler-recovery-policy-convergence.ts +140 -0
  315. package/template/apps/server/src/agent-workflow/scheduler-reservation-convergence.ts +40 -0
  316. package/template/apps/server/src/agent-workflow/scheduler-side-effect-execution.ts +249 -0
  317. package/template/apps/server/src/agent-workflow/scheduler-support.ts +235 -0
  318. package/template/apps/server/src/agent-workflow/scheduler-workflow-cancellation.ts +296 -0
  319. package/template/apps/server/src/agent-workflow/scheduler.ts +289 -0
  320. package/template/apps/server/src/agent-workflow/service-completion.ts +102 -0
  321. package/template/apps/server/src/agent-workflow/service-mutation-identity.ts +94 -0
  322. package/template/apps/server/src/agent-workflow/service-node-admission.ts +36 -0
  323. package/template/apps/server/src/agent-workflow/service-node-run-update.ts +55 -0
  324. package/template/apps/server/src/agent-workflow/service-recovery-events.ts +38 -0
  325. package/template/apps/server/src/agent-workflow/service-recovery.ts +264 -0
  326. package/template/apps/server/src/agent-workflow/service-retry.ts +86 -0
  327. package/template/apps/server/src/agent-workflow/service-run-command.ts +131 -0
  328. package/template/apps/server/src/agent-workflow/service-state-error.ts +21 -0
  329. package/template/apps/server/src/agent-workflow/service-state-invariants.ts +44 -0
  330. package/template/apps/server/src/agent-workflow/service-support.ts +152 -0
  331. package/template/apps/server/src/agent-workflow/service.ts +307 -0
  332. package/template/apps/server/src/agent-workflow/side-effect-state.ts +226 -0
  333. package/template/apps/server/src/agent-workflow/state-machine.ts +321 -0
  334. package/template/apps/server/src/agent-workflow/subagent-node-adapter.ts +229 -0
  335. package/template/apps/server/src/agent-workflow/tool-node-adapter.ts +259 -0
  336. package/template/apps/server/src/agent-workflow/usage.ts +149 -0
  337. package/template/apps/server/src/agent-workflow/wait-signal-service.ts +147 -0
  338. package/template/apps/server/src/agent-workflow/workflow-artifact-token.ts +109 -0
  339. package/template/apps/server/src/agent-workflow/workflow-value-validation.ts +101 -0
  340. package/template/apps/server/src/agent-workflow/workspace-policy.ts +109 -0
  341. package/template/apps/server/src/ai-runtime-report/remote-parser.ts +41 -0
  342. package/template/apps/server/src/ai-runtime-report/service.test.ts +2 -0
  343. package/template/apps/server/src/app/agent-runtime-composition.ts +38 -0
  344. package/template/apps/server/src/app/client-agent-host-auth-binding.ts +10 -0
  345. package/template/apps/server/src/auth/actor-resolver.test.ts +33 -0
  346. package/template/apps/server/src/auth/actor-resolver.ts +6 -1
  347. package/template/apps/server/src/auth/composition.ts +36 -0
  348. package/template/apps/server/src/auth/routes.test-support.ts +2 -0
  349. package/template/apps/server/src/auth/routes.test.ts +18 -0
  350. package/template/apps/server/src/auth/runtime.ts +2 -0
  351. package/template/apps/server/src/auth/service-options.ts +16 -0
  352. package/template/apps/server/src/auth/service.ts +7 -12
  353. package/template/apps/server/src/index.ts +35 -37
  354. package/template/apps/server/src/license/pairing-service.test.ts +1 -1
  355. package/template/apps/server/src/module-host/agent-session-memory-port.ts +91 -0
  356. package/template/apps/server/src/module-host/{debug-session-provider-registration.test.ts → agent-session-provider-registration.test.ts} +42 -17
  357. package/template/apps/server/src/module-host/{debug-session-provider-registration.ts → agent-session-provider-registration.ts} +18 -18
  358. package/template/apps/server/src/module-host/agent-source-invalidation-port.ts +53 -0
  359. package/template/apps/server/src/module-host/http-runtime.ts +14 -0
  360. package/template/apps/server/src/module-host/initialize-contracts.ts +4 -5
  361. package/template/apps/server/src/module-host/initialize.ts +4 -4
  362. package/template/apps/server/src/module-host/request-context.test.ts +5 -5
  363. package/template/apps/server/src/module-host/request-context.ts +8 -0
  364. package/template/apps/server/src/module-host/route-install-context.ts +65 -0
  365. package/template/apps/server/src/module-host/route-installer.ts +11 -56
  366. package/template/apps/server/src/module-host/scoped-host.ts +17 -12
  367. package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +3 -3
  368. package/template/apps/server/src/module-host.ts +3 -5
  369. package/template/apps/server/src/runtime.ts +3 -36
  370. package/template/apps/server/src/storage/routes-stream-cancellation.test.ts +19 -0
  371. package/template/apps/server/src/storage/routes.ts +3 -1
  372. package/template/apps/server/src/system/actor.ts +15 -2
  373. package/template/apps/server/src/system/authorization-invalidation-bridge.ts +30 -0
  374. package/template/apps/server/src/system/authorization-invalidation-composition.ts +36 -0
  375. package/template/apps/server/src/system/drizzle-system.ts +8 -1
  376. package/template/apps/server/src/system/identity-route-config.ts +9 -1
  377. package/template/apps/server/src/system/routes.ts +3 -0
  378. package/template/apps/server/src/system/seed.ts +3 -0
  379. package/template/apps/server/src/system/user-account-policy.ts +91 -0
  380. package/template/apps/web/package.json +1 -0
  381. package/template/apps/web/src/layout/AppSidebar.vue +2 -0
  382. package/template/apps/web/src/pages/system/AgentSessionPage.vue +73 -0
  383. package/template/apps/web/src/pages/system/AgentSessionPage.webtest.ts +66 -0
  384. package/template/apps/web/src/pages/system/AgentWorkflowPage.vue +69 -0
  385. package/template/apps/web/src/pages/system/components/agent-session/AgentSessionDetail.vue +114 -0
  386. package/template/apps/web/src/pages/system/components/agent-session/AgentSessionList.vue +84 -0
  387. package/template/apps/web/src/pages/system/components/agent-session/ContextVersionPanel.vue +119 -0
  388. package/template/apps/web/src/pages/system/components/agent-session/ContextVersionPanel.webtest.ts +46 -0
  389. package/template/apps/web/src/pages/system/components/agent-session/MemoryProjectionPanel.vue +163 -0
  390. package/template/apps/web/src/pages/system/components/agent-session/MemoryProjectionPanel.webtest.ts +62 -0
  391. package/template/apps/web/src/pages/system/components/agent-session/SessionTimeline.vue +71 -0
  392. package/template/apps/web/src/pages/system/components/agent-session/SessionTimeline.webtest.ts +34 -0
  393. package/template/apps/web/src/pages/system/components/agent-session/agent-session-presenter.ts +56 -0
  394. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowNodeCard.vue +39 -0
  395. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowNodeDetail.vue +172 -0
  396. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowRunDetail.vue +151 -0
  397. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowRunGraph.vue +96 -0
  398. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowRunList.vue +100 -0
  399. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowRunSummary.vue +148 -0
  400. package/template/apps/web/src/pages/system/components/agent-workflow/agent-workflow-presenter.ts +74 -0
  401. package/template/apps/web/src/pages/system/components/agent-workflow/workflow-graph-layout.ts +108 -0
  402. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunDetailDialog.vue +9 -0
  403. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunDetailDialog.webtest.ts +22 -0
  404. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeRunTable.webtest.ts +2 -0
  405. package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeTrajectory.vue +118 -0
  406. package/template/apps/web/src/pages/system/composables/useAgentSessions.ts +209 -0
  407. package/template/apps/web/src/pages/system/composables/useAgentSessions.webtest.ts +138 -0
  408. package/template/apps/web/src/pages/system/composables/useAgentWorkflowRuns.ts +173 -0
  409. package/template/apps/web/src/router/index.ts +4 -0
  410. package/template/apps/web/src/router/platform-admin-route-bindings.ts +6 -0
  411. package/template/apps/web/src/services/agent-session-api.ts +159 -0
  412. package/template/apps/web/src/services/agent-session-api.webtest.ts +65 -0
  413. package/template/apps/web/src/services/agent-workflow-api.ts +181 -0
  414. package/template/apps/web/src/services/ai-runtime-api.ts +4 -0
  415. package/template/docker-compose.yml +11 -8
  416. package/template/docs/adr/0003-agent-session-event-source.md +3 -0
  417. package/template/docs/architecture/agent-harness.md +464 -0
  418. package/template/docs/architecture/agent-workflow.md +99 -0
  419. package/template/docs/architecture/ai-runtime.md +55 -47
  420. package/template/docs/architecture/module-host.md +4 -3
  421. package/template/docs/operations/adk-retirement.md +98 -0
  422. package/template/docs/operations/agent-session-memory.md +162 -0
  423. package/template/docs/operations/agent-session-troubleshooting.md +196 -0
  424. package/template/docs/operations/agent-workflow-recovery.md +74 -0
  425. package/template/docs/operations/incremental-delivery.md +1 -1
  426. package/template/docs/platform/agent-production-store.md +82 -0
  427. package/template/docs/platform/agent-run-reattachment.md +52 -0
  428. package/template/docs/platform/agent-runtime-observability.md +4 -3
  429. package/template/docs/platform/agent-runtime.md +116 -281
  430. package/template/docs/platform/agent-tool-approval.md +61 -0
  431. package/template/docs/platform/background-ai-operations.md +50 -0
  432. package/template/docs/platform/client-agent-session.md +173 -0
  433. package/template/docs/platform/embedding-ai-runtime.md +94 -0
  434. package/template/docs/platform/platform-authentication.md +5 -8
  435. package/template/package.json +0 -1
  436. package/template/packages/ai-client/index.ts +1 -0
  437. package/template/packages/ai-client/package.json +2 -1
  438. package/template/packages/ai-client/src/agent/client/client.ts +15 -2
  439. package/template/packages/ai-client/src/agent/client/run-protocol.test.ts +39 -25
  440. package/template/packages/ai-client/src/agent/client/types.ts +4 -0
  441. package/template/packages/ai-client/src/agent/contracts/contracts.test.ts +49 -7
  442. package/template/packages/ai-client/src/agent/contracts/events.ts +61 -0
  443. package/template/packages/ai-client/src/agent/contracts/runs.ts +1 -0
  444. package/template/packages/ai-client/src/client-agent/contracts.ts +131 -0
  445. package/template/packages/ai-client/src/client-agent/http.test.ts +60 -0
  446. package/template/packages/ai-client/src/client-agent/http.ts +66 -0
  447. package/template/packages/ai-client/src/client-agent/index.ts +3 -0
  448. package/template/packages/ai-client/src/client-agent/validation.test.ts +57 -0
  449. package/template/packages/ai-client/src/client-agent/validation.ts +152 -0
  450. package/template/packages/config/index.test.ts +18 -0
  451. package/template/packages/config/package.json +1 -1
  452. package/template/packages/config/src/platform-validation.ts +8 -0
  453. package/template/packages/config/src/platform.ts +22 -9
  454. package/template/packages/database/drizzle/0055_square_yellowjacket.sql +47 -0
  455. package/template/packages/database/drizzle/0056_tricky_living_mummy.sql +2 -0
  456. package/template/packages/database/drizzle/0057_mature_doomsday.sql +4 -0
  457. package/template/packages/database/drizzle/0058_agent_session_memory.sql +159 -0
  458. package/template/packages/database/drizzle/0059_agent_source_module_key.sql +16 -0
  459. package/template/packages/database/drizzle/0060_slimy_rocket_raccoon.sql +43 -0
  460. package/template/packages/database/drizzle/0061_agent_workflow.sql +303 -0
  461. package/template/packages/database/drizzle/meta/0055_snapshot.json +11071 -0
  462. package/template/packages/database/drizzle/meta/0056_snapshot.json +11098 -0
  463. package/template/packages/database/drizzle/meta/0057_snapshot.json +10878 -0
  464. package/template/packages/database/drizzle/meta/0058_snapshot.json +12294 -0
  465. package/template/packages/database/drizzle/meta/0059_snapshot.json +12344 -0
  466. package/template/packages/database/drizzle/meta/0060_snapshot.json +12326 -0
  467. package/template/packages/database/drizzle/meta/0061_snapshot.json +14395 -0
  468. package/template/packages/database/drizzle/meta/_journal.json +49 -0
  469. package/template/packages/database/package.json +1 -1
  470. package/template/packages/database/src/agent-runtime-schema.test.ts +26 -0
  471. package/template/packages/database/src/schema/agent-context-message.ts +38 -0
  472. package/template/packages/database/src/schema/agent-runtime.ts +7 -0
  473. package/template/packages/database/src/schema/agent-session-receipt.ts +36 -0
  474. package/template/packages/database/src/schema/agent-session.ts +344 -0
  475. package/template/packages/database/src/schema/agent-workflow-delegation.ts +126 -0
  476. package/template/packages/database/src/schema/agent-workflow-effects.ts +213 -0
  477. package/template/packages/database/src/schema/agent-workflow-evaluation.ts +67 -0
  478. package/template/packages/database/src/schema/agent-workflow.ts +270 -0
  479. package/template/packages/database/src/schema/client-agent.ts +95 -0
  480. package/template/packages/database/src/schema/index.ts +8 -0
  481. package/template/packages/jobs/package.json +1 -1
  482. package/template/packages/modules/index.ts +2 -0
  483. package/template/packages/modules/package.json +1 -1
  484. package/template/packages/modules/src/ai-client-execution-composition.test.ts +98 -0
  485. package/template/packages/modules/src/ai-client-execution-policy.ts +54 -0
  486. package/template/packages/modules/src/ai-operation-composition.ts +2 -0
  487. package/template/packages/modules/src/manifest.ts +15 -0
  488. package/template/packages/modules/src/system-admin-routes.ts +16 -0
  489. package/template/packages/modules/src/system-admin-ui-catalog.ts +4 -1
  490. package/template/packages/modules/src/system-agent-audit-actions.ts +26 -0
  491. package/template/packages/modules/src/system-ai-api-bindings.ts +262 -0
  492. package/template/packages/modules/src/system-api-control-plane.ts +4 -78
  493. package/template/packages/modules/src/system-audit-actions.ts +113 -0
  494. package/template/packages/modules/src/system-features.ts +17 -0
  495. package/template/packages/modules/src/system-module-catalog.ts +21 -11
  496. package/template/packages/modules/src/system-modules.ts +22 -0
  497. package/template/packages/modules/src/system-permissions.ts +8 -0
  498. package/template/packages/server-sdk/index.ts +43 -0
  499. package/template/packages/server-sdk/package.json +5 -1
  500. package/template/packages/server-sdk/src/agent-session-memory-port.ts +64 -0
  501. package/template/packages/server-sdk/src/agent-session-provider.ts +63 -0
  502. package/template/packages/server-sdk/src/agent-source-invalidation-port.ts +54 -0
  503. package/template/packages/server-sdk/src/ai-operation-registration.ts +2 -0
  504. package/template/packages/server-sdk/src/client-agent-session.ts +95 -0
  505. package/template/packages/server-sdk/src/debug-session-provider.ts +14 -63
  506. package/template/packages/server-sdk/src/module-host.ts +7 -3
  507. package/template/packages/server-sdk/src/request-context.ts +6 -0
  508. package/template/packages/shared/index.ts +3 -0
  509. package/template/packages/shared/package.json +1 -1
  510. package/template/packages/shared/src/agent-workflow-definition.ts +113 -0
  511. package/template/packages/shared/src/agent-workflow-delegation.ts +123 -0
  512. package/template/packages/shared/src/agent-workflow-evaluation.ts +159 -0
  513. package/template/packages/shared/src/agent-workflow-events.ts +99 -0
  514. package/template/packages/shared/src/agent-workflow-run.ts +259 -0
  515. package/template/packages/shared/src/agent-workflow.ts +3 -0
  516. package/template/packages/shared/src/ai-runtime-report.ts +25 -0
  517. package/template/packages/shared/src/rbac.ts +24 -0
  518. package/template/packages/storage/package.json +1 -1
  519. package/template/packages/storage/src/upload-streams.test.ts +31 -0
  520. package/template/packages/storage/src/upload-streams.ts +20 -6
  521. package/template/apps/agent-server/adk_web_agents/__init__.py +0 -1
  522. package/template/apps/agent-server/adk_web_agents/canonical_debug/__init__.py +0 -1
  523. package/template/apps/agent-server/adk_web_agents/canonical_debug/agent.py +0 -145
  524. package/template/apps/agent-server/adk_web_agents/safe_debug/__init__.py +0 -3
  525. package/template/apps/agent-server/adk_web_agents/safe_debug/agent.py +0 -40
  526. package/template/apps/agent-server/adk_web_agents/services.py +0 -25
  527. package/template/apps/agent-server/project/adk-web-debug.json +0 -4
  528. package/template/apps/agent-server/src/southwind_agent_server/adk_adapter.py +0 -333
  529. package/template/apps/agent-server/src/southwind_agent_server/adk_debug.py +0 -348
  530. package/template/apps/agent-server/src/southwind_agent_server/adk_debug_sessions.py +0 -325
  531. package/template/apps/agent-server/src/southwind_agent_server/adk_failure.py +0 -13
  532. package/template/apps/agent-server/src/southwind_agent_server/adk_model.py +0 -304
  533. package/template/apps/agent-server/src/southwind_agent_server/adk_tools.py +0 -143
  534. package/template/apps/agent-server/tests/test_adk_adapter.py +0 -307
  535. package/template/apps/agent-server/tests/test_adk_debug_result_polling.py +0 -139
  536. package/template/apps/agent-server/tests/test_adk_debug_sessions.py +0 -215
  537. package/template/apps/agent-server/tests/test_adk_web_agent.py +0 -12
  538. package/template/apps/agent-server/tests/test_adk_web_canonical_debug.py +0 -282
  539. package/template/apps/server/src/agent/run-debug-authorization.ts +0 -27
  540. package/template/apps/server/src/agent/run-facade-adk-debug.test.ts +0 -95
  541. package/template/apps/server/src/runtime-adk-debug.test.ts +0 -270
  542. package/template/apps/server/src/runtime-adk-debug.ts +0 -164
  543. package/template/apps/server/src/runtime-request-actor.test.ts +0 -55
  544. package/template/apps/server/src/runtime-request-actor.ts +0 -22
  545. package/template/docker-compose.agent-debug.yml +0 -58
  546. package/template/scripts/dev-adk-web.ts +0 -107
@@ -68,18 +68,28 @@ async def wait_for_terminal(
68
68
  return events(response)
69
69
 
70
70
 
71
- async def test_result_and_canonical_sequence(client: httpx.AsyncClient) -> None:
71
+ async def test_deterministic_result_and_canonical_sequence(
72
+ client: httpx.AsyncClient,
73
+ ) -> None:
72
74
  created = await start(client, "test.echo", {"text": "你好"}, "echo-1")
73
75
  run_id = str(created["runId"])
74
76
  emitted = await wait_for_terminal(client, run_id)
75
77
 
76
- assert [event["sequence"] for event in emitted] == [1, 2, 3, 4]
78
+ assert [event["sequence"] for event in emitted] == [1, 2, 3, 4, 5]
77
79
  assert [event["type"] for event in emitted] == [
78
80
  "run.started",
81
+ "input.prepared",
79
82
  "output.delta",
80
83
  "usage.reported",
81
84
  "run.completed",
82
85
  ]
86
+ assert emitted[1] == {
87
+ "type": "input.prepared",
88
+ "runId": run_id,
89
+ "sequence": 2,
90
+ "artifactCount": 0,
91
+ "inputModalities": ["text"],
92
+ }
83
93
  result = await client.get(f"/api/agent/runs/{run_id}/result")
84
94
  assert result.json() == {
85
95
  "runId": run_id,
@@ -98,8 +108,15 @@ async def test_replay_supports_header_and_after(client: httpx.AsyncClient) -> No
98
108
  headers={"Last-Event-ID": "2"},
99
109
  )
100
110
  from_query = await client.get(f"/api/agent/runs/{run_id}/events?after=3")
101
- assert [event["sequence"] for event in events(from_header)] == [3, 4]
102
- assert [event["sequence"] for event in events(from_query)] == [4]
111
+ assert [(event["sequence"], event["type"]) for event in events(from_header)] == [
112
+ (3, "output.delta"),
113
+ (4, "usage.reported"),
114
+ (5, "run.completed"),
115
+ ]
116
+ assert [(event["sequence"], event["type"]) for event in events(from_query)] == [
117
+ (4, "usage.reported"),
118
+ (5, "run.completed"),
119
+ ]
103
120
 
104
121
 
105
122
  async def test_status_exposes_only_canonical_terminal_event(
@@ -107,7 +124,13 @@ async def test_status_exposes_only_canonical_terminal_event(
107
124
  ) -> None:
108
125
  created = await start(client, "test.echo", {"text": "status"}, "status-1")
109
126
  run_id = str(created["runId"])
110
- await wait_for_terminal(client, run_id)
127
+ emitted = await wait_for_terminal(client, run_id)
128
+ terminal_event = emitted[-1]
129
+ assert terminal_event == {
130
+ "type": "run.completed",
131
+ "runId": run_id,
132
+ "sequence": 5,
133
+ }
111
134
 
112
135
  response = await client.get(f"/api/agent/runs/{run_id}")
113
136
 
@@ -115,12 +138,8 @@ async def test_status_exposes_only_canonical_terminal_event(
115
138
  assert response.json() == {
116
139
  "runId": run_id,
117
140
  "status": "completed",
118
- "lastSequence": 4,
119
- "terminalEvent": {
120
- "type": "run.completed",
121
- "runId": run_id,
122
- "sequence": 4,
123
- },
141
+ "lastSequence": 5,
142
+ "terminalEvent": terminal_event,
124
143
  }
125
144
 
126
145
 
@@ -0,0 +1,230 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import tempfile
5
+ from collections.abc import AsyncIterator
6
+
7
+ import httpx
8
+ from fastapi import FastAPI
9
+
10
+ from southwind_agent_server.app import create_app
11
+ from southwind_agent_server.client_completion_contracts import (
12
+ ClientCompletionRequest,
13
+ )
14
+ from southwind_agent_server.client_completion_runtime import ClientCompletionRuntime
15
+ from southwind_agent_server.openai_engine import OpenAiCompatibleEngineAdapter
16
+ from southwind_agent_server.provider_audit import ProviderAuditStore
17
+ from southwind_agent_server.provider_governance import ProviderRequestGovernance
18
+ from southwind_agent_server.tool_host import ToolHostClient
19
+ from tests.openai_provider_test_support import (
20
+ create_provider,
21
+ provider_data_policy,
22
+ sse_response,
23
+ )
24
+
25
+
26
+ def request_body(**patch: object) -> dict[str, object]:
27
+ value: dict[str, object] = {
28
+ "clientRunId": "carun_1",
29
+ "operationKey": "business.answer",
30
+ "deploymentKey": "ai.openai-compatible",
31
+ "modelAlias": "windy-client-agent-v1",
32
+ "attempt": 1,
33
+ "messages": [{"role": "user", "content": "查询记录"}],
34
+ "tools": [
35
+ {
36
+ "type": "function",
37
+ "function": {
38
+ "name": "read_page",
39
+ "description": "读取页面",
40
+ "parameters": {
41
+ "type": "object",
42
+ "properties": {"selector": {"type": "string"}},
43
+ "required": ["selector"],
44
+ },
45
+ },
46
+ },
47
+ {
48
+ "type": "function",
49
+ "function": {
50
+ "name": "AgentOutput",
51
+ "parameters": {
52
+ "type": "object",
53
+ "properties": {"answer": {"type": "string"}},
54
+ "required": ["answer"],
55
+ },
56
+ },
57
+ },
58
+ ],
59
+ "toolChoice": {
60
+ "type": "function",
61
+ "function": {"name": "AgentOutput"},
62
+ },
63
+ "parallelToolCalls": False,
64
+ "providerDataPolicy": provider_data_policy().model_dump(by_alias=True),
65
+ "maxResponseBytes": 65_536,
66
+ }
67
+ value.update(patch)
68
+ return value
69
+
70
+
71
+ async def test_internal_client_completion_fixes_provider_and_streams_tools() -> None:
72
+ observed: dict[str, object] = {}
73
+
74
+ async def provider_handler(request: httpx.Request) -> httpx.Response:
75
+ observed.update(json.loads(request.content))
76
+ assert request.headers["authorization"] == "Bearer server-secret"
77
+ return sse_response(
78
+ [
79
+ {
80
+ "id": "chunk_1",
81
+ "model": "physical-model-must-not-leak",
82
+ "choices": [
83
+ {
84
+ "delta": {
85
+ "tool_calls": [
86
+ {
87
+ "index": 0,
88
+ "id": "call_1",
89
+ "function": {
90
+ "name": "read_page",
91
+ "arguments": '{"selector":"main"}',
92
+ },
93
+ }
94
+ ]
95
+ }
96
+ }
97
+ ],
98
+ }
99
+ ]
100
+ )
101
+
102
+ app = configured_app(httpx.MockTransport(provider_handler))
103
+ async with httpx.AsyncClient(
104
+ transport=httpx.ASGITransport(app=app),
105
+ base_url="http://agent.test",
106
+ ) as client:
107
+ health = await client.get(
108
+ "/api/internal/client-agent/health",
109
+ headers={"authorization": "Bearer internal-token"},
110
+ )
111
+ forbidden = await client.post(
112
+ "/api/internal/client-agent/chat/completions",
113
+ json=request_body(),
114
+ )
115
+ response = await client.post(
116
+ "/api/internal/client-agent/chat/completions",
117
+ headers={"authorization": "Bearer internal-token"},
118
+ json=request_body(),
119
+ )
120
+
121
+ assert health.json() == {"status": "ready"}
122
+ assert forbidden.status_code == 403
123
+ assert response.status_code == 200
124
+ assert observed["model"] == "qwen-compatible"
125
+ assert observed["stream"] is True
126
+ assert observed["tools"] == request_body()["tools"]
127
+ assert observed["tool_choice"] == request_body()["toolChoice"]
128
+ assert observed["parallel_tool_calls"] is False
129
+ assert "windy.meta" in response.text
130
+ assert "windy-client-agent-v1" in response.text
131
+ assert "physical-model-must-not-leak" not in response.text
132
+ assert "server-secret" not in response.text
133
+ assert '"name": "read_page"' in response.text
134
+
135
+
136
+ async def test_internal_contract_rejects_model_url_and_redacts_dlp() -> None:
137
+ sent = ""
138
+
139
+ async def provider_handler(request: httpx.Request) -> httpx.Response:
140
+ nonlocal sent
141
+ sent = request.content.decode()
142
+ return sse_response([{"choices": [{"delta": {"content": "ok"}}]}])
143
+
144
+ app = configured_app(httpx.MockTransport(provider_handler))
145
+ headers = {"authorization": "Bearer internal-token"}
146
+ async with httpx.AsyncClient(
147
+ transport=httpx.ASGITransport(app=app),
148
+ base_url="http://agent.test",
149
+ ) as client:
150
+ override = await client.post(
151
+ "/api/internal/client-agent/chat/completions",
152
+ headers=headers,
153
+ json=request_body(model="attacker-model", providerUrl="https://evil.test"),
154
+ )
155
+ redacted = await client.post(
156
+ "/api/internal/client-agent/chat/completions",
157
+ headers=headers,
158
+ json=request_body(
159
+ messages=[{"role": "user", "content": "联系 a@example.com"}],
160
+ tools=[],
161
+ toolChoice="none",
162
+ ),
163
+ )
164
+
165
+ assert override.status_code == 400
166
+ assert redacted.status_code == 200
167
+ assert "a@example.com" not in sent
168
+ assert "[REDACTED]" in sent
169
+
170
+
171
+ async def test_closing_client_stream_aborts_provider_stream() -> None:
172
+ provider_closed = False
173
+
174
+ class SlowStream(httpx.AsyncByteStream):
175
+ async def __aiter__(self) -> AsyncIterator[bytes]:
176
+ yield b'data: {"choices":[{"delta":{"content":"first"}}]}\n\n'
177
+ yield b'data: {"choices":[{"delta":{"content":"late"}}]}\n\n'
178
+
179
+ async def aclose(self) -> None:
180
+ nonlocal provider_closed
181
+ provider_closed = True
182
+
183
+ async def handler(_request: httpx.Request) -> httpx.Response:
184
+ return httpx.Response(
185
+ 200,
186
+ headers={"content-type": "text/event-stream"},
187
+ stream=SlowStream(),
188
+ )
189
+
190
+ runtime = configured_runtime(httpx.MockTransport(handler))
191
+ prepared = runtime.prepare(
192
+ ClientCompletionRequest.model_validate(
193
+ request_body(tools=[], toolChoice="none")
194
+ )
195
+ )
196
+ stream = runtime.stream(prepared)
197
+ first = await anext(stream)
198
+ assert first["choices"]
199
+ await stream.aclose()
200
+ assert provider_closed is True
201
+
202
+
203
+ def configured_runtime(transport: httpx.AsyncBaseTransport) -> ClientCompletionRuntime:
204
+ audit = ProviderAuditStore(
205
+ tempfile.NamedTemporaryFile(suffix=".sqlite3", delete=False).name,
206
+ retention_days=90,
207
+ )
208
+ return ClientCompletionRuntime(
209
+ create_provider(transport),
210
+ ProviderRequestGovernance(audit),
211
+ )
212
+
213
+
214
+ def configured_app(transport: httpx.AsyncBaseTransport) -> FastAPI:
215
+ provider = create_provider(transport)
216
+ governance = ProviderRequestGovernance(
217
+ ProviderAuditStore(
218
+ tempfile.NamedTemporaryFile(suffix=".sqlite3", delete=False).name,
219
+ retention_days=90,
220
+ )
221
+ )
222
+ engine = OpenAiCompatibleEngineAdapter(
223
+ provider,
224
+ ToolHostClient(
225
+ "internal-token",
226
+ transport=httpx.MockTransport(lambda _request: httpx.Response(500)),
227
+ ),
228
+ governance,
229
+ )
230
+ return create_app(engine, internal_token="internal-token")
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import httpx
4
4
  import pytest
5
5
 
6
- from southwind_agent_server.adk_adapter import AdkEngineAdapter
7
6
  from southwind_agent_server.contracts import StartRunRequest
8
7
  from southwind_agent_server.engine import AgentEngineAdapter, SafeEngineError
9
8
  from southwind_agent_server.openai_engine import (
@@ -21,10 +20,7 @@ from tests.openai_provider_test_support import (
21
20
  )
22
21
 
23
22
 
24
- @pytest.mark.parametrize("adapter_kind", ["direct", "adk"])
25
- async def test_blocked_response_preserves_provider_usage(
26
- adapter_kind: str,
27
- ) -> None:
23
+ async def test_blocked_response_preserves_provider_usage() -> None:
28
24
  async def provider_handler(_request: httpx.Request) -> httpx.Response:
29
25
  return sse_response(
30
26
  [
@@ -64,21 +60,12 @@ async def test_blocked_response_preserves_provider_usage(
64
60
  )
65
61
  await report.start_run("run_1", 101.0)
66
62
  provider = create_provider(httpx.MockTransport(provider_handler))
67
- adapter: AgentEngineAdapter
68
- if adapter_kind == "direct":
69
- adapter = OpenAiCompatibleEngineAdapter(
70
- provider,
71
- ToolHostClient("internal-token"),
72
- governance(),
73
- report,
74
- )
75
- else:
76
- adapter = AdkEngineAdapter(
77
- provider,
78
- ToolHostClient("internal-token"),
79
- governance(),
80
- report,
81
- )
63
+ adapter: AgentEngineAdapter = OpenAiCompatibleEngineAdapter(
64
+ provider,
65
+ ToolHostClient("internal-token"),
66
+ governance(),
67
+ report,
68
+ )
82
69
 
83
70
  with pytest.raises(SafeEngineError) as captured:
84
71
  async for _ in adapter.execute(
@@ -102,8 +89,8 @@ async def test_blocked_response_preserves_provider_usage(
102
89
  assert attempt["model"] == "provider-model-v2"
103
90
 
104
91
 
105
- async def test_adk_cancel_after_response_preserves_provider_usage() -> None:
106
- adapter: AdkEngineAdapter
92
+ async def test_cancel_after_response_preserves_provider_usage() -> None:
93
+ adapter: AgentEngineAdapter
107
94
 
108
95
  async def provider_handler(_request: httpx.Request) -> httpx.Response:
109
96
  await adapter.cancel("run_1")
@@ -128,8 +115,9 @@ async def test_adk_cancel_after_response_preserves_provider_usage() -> None:
128
115
  100.0,
129
116
  )
130
117
  await report.start_run("run_1", 101.0)
131
- adapter = AdkEngineAdapter(
132
- create_provider(httpx.MockTransport(provider_handler)),
118
+ provider = create_provider(httpx.MockTransport(provider_handler))
119
+ adapter = OpenAiCompatibleEngineAdapter(
120
+ provider,
133
121
  ToolHostClient("internal-token"),
134
122
  governance(),
135
123
  report,
@@ -10,6 +10,7 @@ from southwind_agent_server.app import create_app
10
10
  from southwind_agent_server.contracts import StartRunRequest
11
11
  from southwind_agent_server.deterministic import DeterministicEngineAdapter
12
12
  from southwind_agent_server.engine import EngineCompleted
13
+ from southwind_agent_server.engine_identity import DIRECT_ENGINE_ID
13
14
  from southwind_agent_server.openai_engine import OpenAiCompatibleEngineAdapter
14
15
  from southwind_agent_server.report_store import InMemoryAgentRuntimeReportStore
15
16
  from southwind_agent_server.report_types import (
@@ -94,6 +95,7 @@ class UnavailableRunReportStore(InMemoryAgentRuntimeReportStore):
94
95
  run_id: str,
95
96
  request: StartRunRequest,
96
97
  created_at: float,
98
+ engine_id: str = DIRECT_ENGINE_ID,
97
99
  ) -> None:
98
100
  raise RuntimeError("report store unavailable")
99
101
 
@@ -8,6 +8,7 @@ from southwind_agent_server.contracts import RunReportingContext, StartRunReques
8
8
  from southwind_agent_server.report_routes import create_report_router
9
9
  from southwind_agent_server.report_store import InMemoryAgentRuntimeReportStore
10
10
  from southwind_agent_server.report_types import UsageFacts
11
+ from southwind_agent_server.store import InMemoryRunStore, RunRecord
11
12
 
12
13
 
13
14
  async def test_internal_run_routes_project_model_deployments_and_facts(
@@ -36,8 +37,36 @@ async def test_internal_run_routes_project_model_deployments_and_facts(
36
37
  102.0,
37
38
  "provider-model-v2",
38
39
  )
40
+ run_store = InMemoryRunStore()
41
+ await run_store.create_or_get(
42
+ RunRecord(
43
+ run_id="run_1",
44
+ operation_key="business.answer",
45
+ input={"prompt": "不应出现在轨迹中"},
46
+ idempotency_key="idem_1",
47
+ fingerprint="fingerprint_1",
48
+ engine_id="windy.direct.openai-compatible.v1",
49
+ release={"releaseId": "legacy"},
50
+ events=[
51
+ {"type": "run.started", "runId": "run_1", "sequence": 1},
52
+ {
53
+ "type": "output.delta",
54
+ "runId": "run_1",
55
+ "sequence": 2,
56
+ "text": "机密输出",
57
+ },
58
+ {
59
+ "type": "usage.reported",
60
+ "runId": "run_1",
61
+ "sequence": 3,
62
+ "attemptSequence": 1,
63
+ "usage": {"totalTokens": 12},
64
+ },
65
+ ],
66
+ )
67
+ )
39
68
  application = FastAPI()
40
- application.include_router(create_report_router(store, "internal-token"))
69
+ application.include_router(create_report_router(store, run_store, "internal-token"))
41
70
 
42
71
  async with httpx.AsyncClient(
43
72
  transport=httpx.ASGITransport(app=application), base_url="http://test"
@@ -84,3 +113,31 @@ async def test_internal_run_routes_project_model_deployments_and_facts(
84
113
  "finishedAt": "1970-01-01T00:01:42Z",
85
114
  }
86
115
  ]
116
+ assert detail.json()["trajectory"] == {
117
+ "available": True,
118
+ "events": [
119
+ {
120
+ "sequence": 1,
121
+ "sequenceEnd": 1,
122
+ "type": "run.started",
123
+ "title": "开始执行",
124
+ },
125
+ {
126
+ "sequence": 2,
127
+ "sequenceEnd": 2,
128
+ "type": "output.delta",
129
+ "title": "模型生成输出",
130
+ "deltaCount": 1,
131
+ "outputCharacters": 4,
132
+ },
133
+ {
134
+ "sequence": 3,
135
+ "sequenceEnd": 3,
136
+ "type": "usage.reported",
137
+ "title": "Provider 用量已上报",
138
+ "attemptSequence": 1,
139
+ "totalTokens": 12,
140
+ },
141
+ ],
142
+ }
143
+ assert "机密输出" not in detail.text
@@ -12,6 +12,7 @@ from southwind_agent_server.report_types import (
12
12
  def test_postgres_and_in_memory_summary_present_same_dual_timeline() -> None:
13
13
  run = RunReport(
14
14
  run_id="run_1",
15
+ engine_id="windy.direct.openai-compatible.v1",
15
16
  operation_key="business.answer",
16
17
  release_id="release_1",
17
18
  trace_id="trace_1",
@@ -11,11 +11,13 @@ from southwind_agent_server.engine import (
11
11
  EngineRunRequest,
12
12
  EngineSignal,
13
13
  )
14
+ from southwind_agent_server.engine_identity import DIRECT_ENGINE_ID
14
15
  from southwind_agent_server.report_store import InMemoryAgentRuntimeReportStore
15
16
  from southwind_agent_server.store import InMemoryRunStore
16
17
 
17
18
 
18
19
  class LimitedEngine:
20
+ engine_id = DIRECT_ENGINE_ID
19
21
  max_concurrent_runs = 1
20
22
  max_queue_depth = 1
21
23
 
@@ -4,11 +4,12 @@ from unittest.mock import AsyncMock, patch
4
4
 
5
5
  from pytest import MonkeyPatch
6
6
 
7
- from southwind_agent_server.adk_adapter import AdkEngineAdapter
7
+ from southwind_agent_server.openai_engine import OpenAiCompatibleEngineAdapter
8
8
  from southwind_agent_server.runtime_factory import default_engine
9
+ from southwind_agent_server.unavailable_engine import UnavailableEngineAdapter
9
10
 
10
11
 
11
- async def test_default_adk_engine_exposes_vlm_readiness(
12
+ async def test_default_direct_engine_exposes_vlm_readiness(
12
13
  monkeypatch: MonkeyPatch,
13
14
  ) -> None:
14
15
  values = {
@@ -26,7 +27,8 @@ async def test_default_adk_engine_exposes_vlm_readiness(
26
27
  for key, value in values.items():
27
28
  monkeypatch.setenv(key, value)
28
29
  engine = default_engine()
29
- assert isinstance(engine, AdkEngineAdapter)
30
+ assert isinstance(engine, OpenAiCompatibleEngineAdapter)
31
+ assert engine.engine_id == "windy.direct.openai-compatible.v1"
30
32
  provider = engine._provider
31
33
  assert provider is not None
32
34
  with patch.object(provider, "probe_vision", AsyncMock()) as probe:
@@ -35,3 +37,16 @@ async def test_default_adk_engine_exposes_vlm_readiness(
35
37
  probe.assert_awaited_once()
36
38
  assert snapshot["status"] == "ready"
37
39
  assert snapshot["runtimeKind"] == "agent"
40
+
41
+
42
+ async def test_missing_provider_uses_explicit_unavailable_engine(
43
+ monkeypatch: MonkeyPatch,
44
+ ) -> None:
45
+ for key in ("QWEN_API_URL", "QWEN_MODEL"):
46
+ monkeypatch.delenv(key, raising=False)
47
+
48
+ engine = default_engine()
49
+
50
+ assert isinstance(engine, UnavailableEngineAdapter)
51
+ assert engine.engine_id == "windy.unavailable.v1"
52
+ assert (await engine.readiness())["configured"] is False
@@ -0,0 +1,91 @@
1
+ from typing import cast
2
+
3
+ from southwind_agent_server.store import RunRecord
4
+ from southwind_agent_server.trajectory import project_run_trajectory
5
+
6
+
7
+ def test_trajectory_preserves_governed_signals_without_sensitive_payloads() -> None:
8
+ record = RunRecord(
9
+ run_id="run_1",
10
+ operation_key="business.answer",
11
+ input={"prompt": "输入正文"},
12
+ idempotency_key="idem_1",
13
+ fingerprint="fingerprint_1",
14
+ release={"releaseId": "legacy"},
15
+ events=[
16
+ {"type": "run.started", "sequence": 1},
17
+ {
18
+ "type": "input.prepared",
19
+ "sequence": 2,
20
+ "artifactCount": 1,
21
+ "inputModalities": ["text", "image"],
22
+ },
23
+ {
24
+ "type": "output.delta",
25
+ "sequence": 3,
26
+ "text": "第一段输出",
27
+ },
28
+ {
29
+ "type": "output.delta",
30
+ "sequence": 4,
31
+ "text": "第二段输出",
32
+ },
33
+ {
34
+ "type": "tool.requested",
35
+ "sequence": 5,
36
+ "toolCallId": "call_secret",
37
+ "toolKey": "business.search",
38
+ "arguments": {"secret": "不可暴露"},
39
+ },
40
+ {
41
+ "type": "approval.required",
42
+ "sequence": 6,
43
+ "toolCallId": "call_secret",
44
+ "workItemId": "approval_secret",
45
+ },
46
+ {
47
+ "type": "approval.resolved",
48
+ "sequence": 7,
49
+ "toolCallId": "call_secret",
50
+ "workItemId": "approval_secret",
51
+ "outcome": "approved",
52
+ },
53
+ {"type": "tool.completed", "sequence": 8, "toolCallId": "call_secret"},
54
+ {
55
+ "type": "usage.reported",
56
+ "sequence": 9,
57
+ "attemptSequence": 1,
58
+ "usage": {"totalTokens": 24, "providerBody": "不可暴露"},
59
+ },
60
+ {"type": "run.completed", "sequence": 10},
61
+ ],
62
+ )
63
+
64
+ trajectory = project_run_trajectory(record)
65
+ events = cast(list[dict[str, object]], trajectory["events"])
66
+
67
+ assert trajectory["available"] is True
68
+ assert events[2] == {
69
+ "sequence": 3,
70
+ "sequenceEnd": 4,
71
+ "type": "output.delta",
72
+ "title": "模型生成输出",
73
+ "deltaCount": 2,
74
+ "outputCharacters": 10,
75
+ }
76
+ assert events[3]["toolKey"] == "business.search"
77
+ assert events[5]["approvalOutcome"] == "approved"
78
+ serialized = repr(trajectory)
79
+ for sensitive in (
80
+ "输入正文",
81
+ "第一段输出",
82
+ "第二段输出",
83
+ "call_secret",
84
+ "approval_secret",
85
+ "不可暴露",
86
+ ):
87
+ assert sensitive not in serialized
88
+
89
+
90
+ def test_trajectory_marks_expired_canonical_run_as_unavailable() -> None:
91
+ assert project_run_trajectory(None) == {"available": False, "events": []}