create-windy 0.8.3 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/dist/cli.js +838 -560
  2. package/package.json +1 -1
  3. package/template/.windy-template.json +2 -2
  4. package/template/apps/agent-server/Dockerfile +92 -22
  5. package/template/apps/agent-server/README.md +47 -85
  6. package/template/apps/agent-server/documents/office.py +216 -0
  7. package/template/apps/agent-server/documents/query_report.py +136 -0
  8. package/template/apps/agent-server/documents/smoke.py +177 -0
  9. package/template/apps/agent-server/documents/test_boundaries.py +185 -0
  10. package/template/apps/agent-server/host-contracts.ts +56 -0
  11. package/template/apps/agent-server/install-native.ts +167 -0
  12. package/template/apps/agent-server/main.ts +179 -0
  13. package/template/apps/agent-server/native/EXTENSIONS.md +46 -0
  14. package/template/apps/agent-server/native/admission.ts +73 -0
  15. package/template/apps/agent-server/native/authorization.test.ts +176 -0
  16. package/template/apps/agent-server/native/authorization.ts +118 -0
  17. package/template/apps/agent-server/native/boundary-io.ts +93 -0
  18. package/template/apps/agent-server/native/boundary-product.ts +107 -0
  19. package/template/apps/agent-server/native/boundary-project.test.ts +247 -0
  20. package/template/apps/agent-server/native/boundary-project.ts +188 -0
  21. package/template/apps/agent-server/native/boundary.ts +188 -0
  22. package/template/apps/agent-server/native/compaction-policy.test.ts +175 -0
  23. package/template/apps/agent-server/native/config.ts +95 -0
  24. package/template/apps/agent-server/native/conversation-instructions.ts +9 -0
  25. package/template/apps/agent-server/native/extensions.test.ts +190 -0
  26. package/template/apps/agent-server/native/extensions.ts +31 -0
  27. package/template/apps/agent-server/native/host-profile.test.ts +91 -0
  28. package/template/apps/agent-server/native/host-profile.ts +33 -0
  29. package/template/apps/agent-server/native/host-test-fixture.ts +13 -0
  30. package/template/apps/agent-server/native/http.ts +129 -0
  31. package/template/apps/agent-server/native/lifecycle.test.ts +285 -0
  32. package/template/apps/agent-server/native/lifecycle.ts +136 -0
  33. package/template/apps/agent-server/native/manager.ts +292 -0
  34. package/template/apps/agent-server/native/native.test.ts +207 -0
  35. package/template/apps/agent-server/native/office-preview.test.ts +50 -0
  36. package/template/apps/agent-server/native/office-preview.ts +25 -0
  37. package/template/apps/agent-server/native/parallel-harness.ts +242 -0
  38. package/template/apps/agent-server/native/parallel-mcp-fixture.ts +97 -0
  39. package/template/apps/agent-server/native/parallel.test.ts +256 -0
  40. package/template/apps/agent-server/native/profile-composition.test.ts +147 -0
  41. package/template/apps/agent-server/native/profile.ts +307 -0
  42. package/template/apps/agent-server/native/request.ts +61 -0
  43. package/template/apps/agent-server/native/session-conflict.test.ts +235 -0
  44. package/template/apps/agent-server/native/session-conflict.ts +21 -0
  45. package/template/apps/agent-server/native/shared-skills.test.ts +128 -0
  46. package/template/apps/agent-server/native/shared-skills.ts +240 -0
  47. package/template/apps/agent-server/native/socket-lifecycle.test.ts +48 -0
  48. package/template/apps/agent-server/native/socket.ts +130 -0
  49. package/template/apps/agent-server/native/storage-lifecycle.test.ts +217 -0
  50. package/template/apps/agent-server/native/storage.ts +188 -0
  51. package/template/apps/agent-server/native/stream-authorization.test.ts +89 -0
  52. package/template/apps/agent-server/native/worker.ts +77 -0
  53. package/template/apps/agent-server/native-download.test.ts +119 -0
  54. package/template/apps/agent-server/native-download.ts +145 -0
  55. package/template/apps/agent-server/package.json +63 -0
  56. package/template/apps/agent-server/plugins/access.mjs +126 -0
  57. package/template/apps/agent-server/plugins/branding/README.md +9 -0
  58. package/template/apps/agent-server/plugins/branding/brand.css +85 -0
  59. package/template/apps/agent-server/plugins/branding/client.js +338 -0
  60. package/template/apps/agent-server/plugins/branding/index.mjs +35 -0
  61. package/template/apps/agent-server/plugins/branding/loading.d.mts +2 -0
  62. package/template/apps/agent-server/plugins/branding/loading.mjs +66 -0
  63. package/template/apps/agent-server/plugins/branding/loading.test.ts +89 -0
  64. package/template/apps/agent-server/plugins/branding/package.json +21 -0
  65. package/template/apps/agent-server/plugins/branding.test.ts +294 -0
  66. package/template/apps/agent-server/plugins/compaction.mjs +83 -0
  67. package/template/apps/agent-server/plugins/compaction.test.ts +91 -0
  68. package/template/apps/agent-server/plugins/confine-network.py +57 -0
  69. package/template/apps/agent-server/plugins/default-skills.test.ts +62 -0
  70. package/template/apps/agent-server/plugins/downloads/README.md +28 -0
  71. package/template/apps/agent-server/plugins/downloads/client.js +126 -0
  72. package/template/apps/agent-server/plugins/downloads/downloads.test.ts +222 -0
  73. package/template/apps/agent-server/plugins/downloads/index.d.mts +19 -0
  74. package/template/apps/agent-server/plugins/downloads/index.mjs +180 -0
  75. package/template/apps/agent-server/plugins/downloads/package.json +20 -0
  76. package/template/apps/agent-server/plugins/drop-overlay/README.md +24 -0
  77. package/template/apps/agent-server/plugins/drop-overlay/drop-overlay.test.ts +199 -0
  78. package/template/apps/agent-server/plugins/drop-overlay/index.d.mts +8 -0
  79. package/template/apps/agent-server/plugins/drop-overlay/index.mjs +12 -0
  80. package/template/apps/agent-server/plugins/drop-overlay/style.css +102 -0
  81. package/template/apps/agent-server/plugins/locale/client.js +61 -0
  82. package/template/apps/agent-server/plugins/locale/index.d.mts +9 -0
  83. package/template/apps/agent-server/plugins/locale/index.mjs +16 -0
  84. package/template/apps/agent-server/plugins/locale/locale.test.ts +217 -0
  85. package/template/apps/agent-server/plugins/locale/package.json +19 -0
  86. package/template/apps/agent-server/plugins/parallel.mjs +146 -0
  87. package/template/apps/agent-server/plugins/preset-registry.d.mts +2 -0
  88. package/template/apps/agent-server/plugins/preset-registry.mjs +41 -0
  89. package/template/apps/agent-server/plugins/preset-registry.test.ts +46 -0
  90. package/template/apps/agent-server/plugins/questions.d.mts +25 -0
  91. package/template/apps/agent-server/plugins/questions.mjs +142 -0
  92. package/template/apps/agent-server/plugins/questions.test.ts +105 -0
  93. package/template/apps/agent-server/plugins/settings/README.md +17 -0
  94. package/template/apps/agent-server/plugins/settings/client.js +102 -0
  95. package/template/apps/agent-server/plugins/settings/index.mjs +17 -0
  96. package/template/apps/agent-server/plugins/settings/package.json +19 -0
  97. package/template/apps/agent-server/plugins/settings/settings.test.ts +129 -0
  98. package/template/apps/agent-server/plugins/settings-controller.d.mts +4 -0
  99. package/template/apps/agent-server/plugins/settings-controller.mjs +31 -0
  100. package/template/apps/agent-server/plugins/settings-controller.test.ts +17 -0
  101. package/template/apps/agent-server/plugins/settings-dispatch.test.ts +34 -0
  102. package/template/apps/agent-server/plugins/shared-skills.d.mts +15 -0
  103. package/template/apps/agent-server/plugins/shared-skills.mjs +82 -0
  104. package/template/apps/agent-server/plugins/shared-skills.test.ts +51 -0
  105. package/template/apps/agent-server/plugins/skill-library/README.md +11 -0
  106. package/template/apps/agent-server/plugins/skill-library/archive.test.ts +43 -0
  107. package/template/apps/agent-server/plugins/skill-library/bundle.mjs +234 -0
  108. package/template/apps/agent-server/plugins/skill-library/client-chunks.test.ts +107 -0
  109. package/template/apps/agent-server/plugins/skill-library/client-form-mount.test.ts +139 -0
  110. package/template/apps/agent-server/plugins/skill-library/client-form.test.ts +261 -0
  111. package/template/apps/agent-server/plugins/skill-library/client-ui.test.ts +268 -0
  112. package/template/apps/agent-server/plugins/skill-library/client-use.test.ts +158 -0
  113. package/template/apps/agent-server/plugins/skill-library/client.editor.js +93 -0
  114. package/template/apps/agent-server/plugins/skill-library/client.form.js +316 -0
  115. package/template/apps/agent-server/plugins/skill-library/client.js +348 -0
  116. package/template/apps/agent-server/plugins/skill-library/client.request.js +52 -0
  117. package/template/apps/agent-server/plugins/skill-library/client.transfer.js +48 -0
  118. package/template/apps/agent-server/plugins/skill-library/client.use.js +46 -0
  119. package/template/apps/agent-server/plugins/skill-library/default-roots.test.ts +84 -0
  120. package/template/apps/agent-server/plugins/skill-library/draft.d.mts +17 -0
  121. package/template/apps/agent-server/plugins/skill-library/draft.mjs +152 -0
  122. package/template/apps/agent-server/plugins/skill-library/draft.test.ts +287 -0
  123. package/template/apps/agent-server/plugins/skill-library/index.d.mts +49 -0
  124. package/template/apps/agent-server/plugins/skill-library/index.mjs +226 -0
  125. package/template/apps/agent-server/plugins/skill-library/package.json +24 -0
  126. package/template/apps/agent-server/plugins/skill-library/presentation/README.md +27 -0
  127. package/template/apps/agent-server/plugins/skill-library/presentation/UPSTREAM.md +54 -0
  128. package/template/apps/agent-server/plugins/skill-library/presentation/boot.test.ts +150 -0
  129. package/template/apps/agent-server/plugins/skill-library/presentation/client.js +146 -0
  130. package/template/apps/agent-server/plugins/skill-library/presentation/client.test.ts +195 -0
  131. package/template/apps/agent-server/plugins/skill-library/presentation/index.d.mts +9 -0
  132. package/template/apps/agent-server/plugins/skill-library/presentation/index.mjs +30 -0
  133. package/template/apps/agent-server/plugins/skill-library/presentation/metadata.test.ts +82 -0
  134. package/template/apps/agent-server/plugins/skill-library/presentation/package.json +21 -0
  135. package/template/apps/agent-server/plugins/skill-library/presentation/react-boot.test.ts +162 -0
  136. package/template/apps/agent-server/plugins/skill-library/skills.test.ts +342 -0
  137. package/template/apps/agent-server/plugins/skill-library/storage.mjs +293 -0
  138. package/template/apps/agent-server/plugins/skill-library/style.css +229 -0
  139. package/template/apps/agent-server/plugins/skill-library/test-fixture.ts +77 -0
  140. package/template/apps/agent-server/plugins/skill-library/workflow.d.mts +18 -0
  141. package/template/apps/agent-server/plugins/skill-library/workflow.mjs +189 -0
  142. package/template/apps/agent-server/plugins/skill-library/workflow.test.ts +164 -0
  143. package/template/apps/agent-server/plugins/skills/README.md +5 -0
  144. package/template/apps/agent-server/plugins/skills/windy-data-summary/SKILL.md +14 -0
  145. package/template/apps/agent-server/plugins/skills/windy-extension-guide/SKILL.md +14 -0
  146. package/template/apps/agent-server/plugins/skills/windy-office/SKILL.md +14 -0
  147. package/template/apps/agent-server/plugins/skills/windy-skill-capture/SKILL.md +14 -0
  148. package/template/apps/agent-server/plugins/skills/windy-source-compare/SKILL.md +14 -0
  149. package/template/apps/agent-server/plugins/subprocess.mjs +40 -0
  150. package/template/apps/agent-server/plugins/theme/README.md +18 -0
  151. package/template/apps/agent-server/plugins/theme/client.js +18 -0
  152. package/template/apps/agent-server/plugins/theme/index.d.mts +9 -0
  153. package/template/apps/agent-server/plugins/theme/index.mjs +18 -0
  154. package/template/apps/agent-server/plugins/theme/package.json +19 -0
  155. package/template/apps/agent-server/plugins/theme/source-tokens.ts +82 -0
  156. package/template/apps/agent-server/plugins/theme/sync-tokens.ts +12 -0
  157. package/template/apps/agent-server/plugins/theme/theme.test.ts +193 -0
  158. package/template/apps/agent-server/plugins/theme/tokens.json +166 -0
  159. package/template/apps/agent-server/plugins/tool-catalog/README.md +79 -0
  160. package/template/apps/agent-server/plugins/tool-catalog/categories.mjs +111 -0
  161. package/template/apps/agent-server/plugins/tool-catalog/categories.test.ts +118 -0
  162. package/template/apps/agent-server/plugins/tool-catalog/client-cache.test.ts +264 -0
  163. package/template/apps/agent-server/plugins/tool-catalog/client.js +333 -0
  164. package/template/apps/agent-server/plugins/tool-catalog/client.test.ts +136 -0
  165. package/template/apps/agent-server/plugins/tool-catalog/discovery.d.mts +42 -0
  166. package/template/apps/agent-server/plugins/tool-catalog/discovery.mjs +242 -0
  167. package/template/apps/agent-server/plugins/tool-catalog/discovery.test.ts +229 -0
  168. package/template/apps/agent-server/plugins/tool-catalog/index.d.mts +5 -0
  169. package/template/apps/agent-server/plugins/tool-catalog/index.mjs +91 -0
  170. package/template/apps/agent-server/plugins/tool-catalog/package.json +23 -0
  171. package/template/apps/agent-server/plugins/tool-catalog/presentation.d.mts +21 -0
  172. package/template/apps/agent-server/plugins/tool-catalog/presentation.mjs +153 -0
  173. package/template/apps/agent-server/plugins/tool-catalog/presentation.test.ts +166 -0
  174. package/template/apps/agent-server/plugins/tool-catalog/routes.test.ts +209 -0
  175. package/template/apps/agent-server/plugins/tool-catalog/style.css +155 -0
  176. package/template/apps/agent-server/plugins/tool-catalog/use-tool.test.ts +160 -0
  177. package/template/apps/agent-server/plugins/tool-presentation/README.md +7 -0
  178. package/template/apps/agent-server/plugins/tool-presentation/build-client.ts +29 -0
  179. package/template/apps/agent-server/plugins/tool-presentation/client.js +312 -0
  180. package/template/apps/agent-server/plugins/tool-presentation/client.results.js +9 -0
  181. package/template/apps/agent-server/plugins/tool-presentation/client.test.ts +178 -0
  182. package/template/apps/agent-server/plugins/tool-presentation/index.mjs +10 -0
  183. package/template/apps/agent-server/plugins/tool-presentation/package.json +24 -0
  184. package/template/apps/agent-server/plugins/tool-presentation/result-discovery.mjs +43 -0
  185. package/template/apps/agent-server/plugins/tool-presentation/result-model.d.mts +51 -0
  186. package/template/apps/agent-server/plugins/tool-presentation/result-model.mjs +96 -0
  187. package/template/apps/agent-server/plugins/workspace/README.md +5 -0
  188. package/template/apps/agent-server/plugins/workspace/index.mjs +8 -0
  189. package/template/apps/agent-server/plugins/workspace/package.json +10 -0
  190. package/template/apps/agent-server/plugins/workspace/style.css +124 -0
  191. package/template/apps/agent-server/project/host.ts +13 -0
  192. package/template/apps/agent-server/runtime/artifacts.ts +115 -0
  193. package/template/apps/agent-server/runtime/audit.nodecheck.ts +60 -0
  194. package/template/apps/agent-server/runtime/capacity.ts +61 -0
  195. package/template/apps/agent-server/runtime/client-completion-budget.nodecheck.ts +92 -0
  196. package/template/apps/agent-server/runtime/compatibility.ts +33 -0
  197. package/template/apps/agent-server/runtime/completions.ts +320 -0
  198. package/template/apps/agent-server/runtime/config.ts +246 -0
  199. package/template/apps/agent-server/runtime/context-budget.ts +70 -0
  200. package/template/apps/agent-server/runtime/context-plugin.ts +306 -0
  201. package/template/apps/agent-server/runtime/context.nodecheck.ts +241 -0
  202. package/template/apps/agent-server/runtime/contracts.ts +201 -0
  203. package/template/apps/agent-server/runtime/dsh-engine.ts +196 -0
  204. package/template/apps/agent-server/runtime/evaluation-plugin.ts +115 -0
  205. package/template/apps/agent-server/runtime/evaluation.nodecheck.ts +194 -0
  206. package/template/apps/agent-server/runtime/events.ts +71 -0
  207. package/template/apps/agent-server/runtime/governance.ts +194 -0
  208. package/template/apps/agent-server/runtime/index.ts +339 -0
  209. package/template/apps/agent-server/runtime/internal-output.ts +37 -0
  210. package/template/apps/agent-server/runtime/isolation.nodecheck.ts +287 -0
  211. package/template/apps/agent-server/runtime/model-payload.ts +97 -0
  212. package/template/apps/agent-server/runtime/model-plugin.ts +308 -0
  213. package/template/apps/agent-server/runtime/model-route.ts +34 -0
  214. package/template/apps/agent-server/runtime/model-usage.ts +51 -0
  215. package/template/apps/agent-server/runtime/model-wire.ts +45 -0
  216. package/template/apps/agent-server/runtime/native-authorization.nodecheck.ts +126 -0
  217. package/template/apps/agent-server/runtime/native-completion.nodecheck.ts +81 -0
  218. package/template/apps/agent-server/runtime/output-validation.ts +66 -0
  219. package/template/apps/agent-server/runtime/production-capacity.nodecheck.ts +121 -0
  220. package/template/apps/agent-server/runtime/questions-workflow.nodecheck.ts +249 -0
  221. package/template/apps/agent-server/runtime/report-breakdown.ts +79 -0
  222. package/template/apps/agent-server/runtime/reporting.ts +219 -0
  223. package/template/apps/agent-server/runtime/run-completion.ts +39 -0
  224. package/template/apps/agent-server/runtime/run-request-digest.ts +18 -0
  225. package/template/apps/agent-server/runtime/runtime-test-fixtures.ts +264 -0
  226. package/template/apps/agent-server/runtime/runtime.nodecheck.ts +150 -0
  227. package/template/apps/agent-server/runtime/store-idempotency.nodecheck.ts +74 -0
  228. package/template/apps/agent-server/runtime/store.ts +324 -0
  229. package/template/apps/agent-server/runtime/structured-output-mode.nodecheck.ts +51 -0
  230. package/template/apps/agent-server/runtime/tool-name.ts +6 -0
  231. package/template/apps/agent-server/runtime/tool-plugin.ts +201 -0
  232. package/template/apps/agent-server/runtime/vision-readiness.ts +200 -0
  233. package/template/apps/agent-server/scripts/confinement-check.mjs +103 -0
  234. package/template/apps/agent-server/scripts/coordinator-check.mjs +344 -0
  235. package/template/apps/agent-server/scripts/documents-delivery-check.mjs +309 -0
  236. package/template/apps/agent-server/scripts/office-preview-check.mjs +92 -0
  237. package/template/apps/agent-server/scripts/test-confinement.ts +58 -0
  238. package/template/apps/agent-server/scripts/test-coordinator.ts +36 -0
  239. package/template/apps/agent-server/scripts/test-runtime.ts +46 -0
  240. package/template/apps/agent-server/tsconfig.json +21 -0
  241. package/template/apps/server/Dockerfile +3 -0
  242. package/template/apps/server/package.json +5 -1
  243. package/template/apps/server/scripts/check-dsh-platform-example.ts +251 -0
  244. package/template/apps/server/src/agent/dsh-runtime-wire.test.ts +33 -0
  245. package/template/apps/server/src/agent/governance-runtime.ts +41 -0
  246. package/template/apps/server/src/agent/remote-runtime-response.ts +1 -1
  247. package/template/apps/server/src/agent/run-contracts.ts +1 -0
  248. package/template/apps/server/src/agent/run-definition-support.ts +9 -0
  249. package/template/apps/server/src/agent/runtime-tool-composition.ts +2 -0
  250. package/template/apps/server/src/agent/workflow-runtime-bootstrap.ts +9 -0
  251. package/template/apps/server/src/agent-skills/access.ts +88 -0
  252. package/template/apps/server/src/agent-skills/bootstrap.ts +49 -0
  253. package/template/apps/server/src/agent-skills/builtin-registration.ts +83 -0
  254. package/template/apps/server/src/agent-skills/builtins.ts +19 -0
  255. package/template/apps/server/src/agent-skills/bundle-zip.ts +163 -0
  256. package/template/apps/server/src/agent-skills/bundle.test.ts +79 -0
  257. package/template/apps/server/src/agent-skills/bundle.ts +133 -0
  258. package/template/apps/server/src/agent-skills/contracts.ts +46 -0
  259. package/template/apps/server/src/agent-skills/drizzle-repository.ts +125 -0
  260. package/template/apps/server/src/agent-skills/input.ts +29 -0
  261. package/template/apps/server/src/agent-skills/postgres.integration.test.ts +348 -0
  262. package/template/apps/server/src/agent-skills/read-routes.test.ts +116 -0
  263. package/template/apps/server/src/agent-skills/reader.ts +108 -0
  264. package/template/apps/server/src/agent-skills/repository.ts +105 -0
  265. package/template/apps/server/src/agent-skills/routes.ts +176 -0
  266. package/template/apps/server/src/agent-skills/service.test.ts +295 -0
  267. package/template/apps/server/src/agent-skills/service.ts +301 -0
  268. package/template/apps/server/src/agent-workflow/preset-registry.test.ts +137 -0
  269. package/template/apps/server/src/agent-workflow/preset-registry.ts +191 -0
  270. package/template/apps/server/src/agent-workflow/preset-routes.test.ts +94 -0
  271. package/template/apps/server/src/agent-workflow/preset-routes.ts +45 -0
  272. package/template/apps/server/src/ai-runtime-report/service.test.ts +10 -7
  273. package/template/apps/server/src/ai-runtime-report/service.ts +1 -1
  274. package/template/apps/server/src/app/agent-workflow-presets.ts +4 -0
  275. package/template/apps/server/src/app/dsh-skill-draft-audit.test.ts +195 -0
  276. package/template/apps/server/src/app/dsh-skill-draft-audit.ts +115 -0
  277. package/template/apps/server/src/app/dsh-workbench-audit.test.ts +71 -0
  278. package/template/apps/server/src/app/dsh-workbench-audit.ts +34 -0
  279. package/template/apps/server/src/app/dsh-workbench-handshake.test.ts +63 -0
  280. package/template/apps/server/src/app/dsh-workbench-handshake.ts +48 -0
  281. package/template/apps/server/src/app/dsh-workbench-http.test.ts +96 -0
  282. package/template/apps/server/src/app/dsh-workbench-lan-origin.test.ts +114 -0
  283. package/template/apps/server/src/app/dsh-workbench-launch.test.ts +70 -0
  284. package/template/apps/server/src/app/dsh-workbench-origin.test.ts +54 -0
  285. package/template/apps/server/src/app/dsh-workbench-proxy.ts +205 -0
  286. package/template/apps/server/src/app/dsh-workbench-session-conflict.test.ts +61 -0
  287. package/template/apps/server/src/app/dsh-workbench-session.ts +59 -0
  288. package/template/apps/server/src/app/dsh-workbench-socket-audit.test.ts +115 -0
  289. package/template/apps/server/src/app/dsh-workbench-socket.test.ts +246 -0
  290. package/template/apps/server/src/app/dsh-workbench-socket.ts +272 -0
  291. package/template/apps/server/src/app/dsh-workbench-test-support.ts +158 -0
  292. package/template/apps/server/src/app/dsh-workbench.test.ts +213 -0
  293. package/template/apps/server/src/app/dsh-workbench.ts +279 -0
  294. package/template/apps/server/src/app/workbench-public-origin.ts +16 -0
  295. package/template/apps/server/src/data-governance/user-plaintext-routes.test.ts +3 -0
  296. package/template/apps/server/src/http-app.ts +31 -0
  297. package/template/apps/server/src/mcp/adapter.ts +1 -0
  298. package/template/apps/server/src/module-composition.test.ts +23 -0
  299. package/template/apps/server/src/module-composition.ts +9 -2
  300. package/template/apps/server/src/observability/bootstrap.ts +12 -0
  301. package/template/apps/server/src/observability/diagnostic-failure-recorder.ts +94 -0
  302. package/template/apps/server/src/observability/diagnostic-http-contract.test.ts +42 -0
  303. package/template/apps/server/src/observability/diagnostic-index.test.ts +89 -0
  304. package/template/apps/server/src/observability/diagnostic-index.ts +88 -0
  305. package/template/apps/server/src/observability/diagnostic-repository.ts +67 -0
  306. package/template/apps/server/src/platform-app-bootstrap.ts +42 -0
  307. package/template/apps/server/src/platform-http-runtime.ts +6 -0
  308. package/template/apps/server/src/runtime-development.test.ts +25 -0
  309. package/template/apps/server/src/runtime-development.ts +6 -44
  310. package/template/apps/server/src/system/diagnostic-routes.test.ts +78 -0
  311. package/template/apps/server/src/system/diagnostic-routes.ts +66 -0
  312. package/template/apps/web/Dockerfile +9 -1
  313. package/template/apps/web/dev/start.ts +21 -10
  314. package/template/apps/web/dsh-workbench-location.ts +21 -0
  315. package/template/apps/web/dsh-workbench-proxy.test.ts +121 -0
  316. package/template/apps/web/dsh-workbench-proxy.ts +194 -0
  317. package/template/apps/web/package.json +3 -1
  318. package/template/apps/web/server.ts +27 -6
  319. package/template/apps/web/src/composables/useLoginFlow.ts +13 -1
  320. package/template/apps/web/src/pages/errors/PlatformErrorPage.vue +6 -0
  321. package/template/apps/web/src/pages/errors/PlatformErrorPage.webtest.ts +14 -1
  322. package/template/apps/web/src/pages/errors/error-page-extension.ts +1 -0
  323. package/template/apps/web/src/pages/system/AgentNativePage.vue +44 -0
  324. package/template/apps/web/src/pages/system/AgentWorkflowPage.vue +20 -7
  325. package/template/apps/web/src/pages/system/DiagnosticLookupPage.vue +56 -0
  326. package/template/apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts +99 -0
  327. package/template/apps/web/src/pages/system/SystemAgentSkillsPage.vue +88 -0
  328. package/template/apps/web/src/pages/system/components/DiagnosticRecordDetails.vue +52 -0
  329. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillDetailDialog.vue +166 -0
  330. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillGovernanceActionDialog.vue +51 -0
  331. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue +320 -0
  332. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.webtest.ts +96 -0
  333. package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillsTable.vue +69 -0
  334. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowPresetCatalog.vue +82 -0
  335. package/template/apps/web/src/pages/system/components/agent-workflow/WorkflowPresetCatalog.webtest.ts +57 -0
  336. package/template/apps/web/src/pages/system/composables/useAgentSkillsGovernance.ts +105 -0
  337. package/template/apps/web/src/pages/system/composables/useAgentWorkflowPresets.ts +44 -0
  338. package/template/apps/web/src/pages/system/composables/useDiagnosticLookup.ts +64 -0
  339. package/template/apps/web/src/router/error-navigation.ts +3 -1
  340. package/template/apps/web/src/router/error-navigation.webtest.ts +14 -2
  341. package/template/apps/web/src/router/index.ts +8 -49
  342. package/template/apps/web/src/router/platform-admin-pages.ts +79 -0
  343. package/template/apps/web/src/router/platform-admin-route-bindings.ts +8 -0
  344. package/template/apps/web/src/services/agent-skills-api.ts +55 -0
  345. package/template/apps/web/src/services/agent-workflow-api.ts +12 -0
  346. package/template/apps/web/src/services/diagnostics-api.ts +12 -0
  347. package/template/apps/web/src/services/http.ts +18 -0
  348. package/template/apps/web/src/services/http.webtest.ts +51 -0
  349. package/template/apps/web/vite.config.ts +39 -0
  350. package/template/deploy/dsh/README.md +5 -0
  351. package/template/deploy/dsh/documents/README.md +9 -0
  352. package/template/deploy/dsh/documents/requirements.in +6 -0
  353. package/template/deploy/dsh/documents/requirements.lock +72 -0
  354. package/template/docker-compose.yml +24 -10
  355. package/template/docs/adr/0004-embedded-dsh-runtime.md +9 -0
  356. package/template/docs/architecture/agent-admin-workbench-implementation.md +73 -0
  357. package/template/docs/architecture/agent-admin-workbench-plan.md +41 -0
  358. package/template/docs/architecture/agent-harness.md +2 -0
  359. package/template/docs/architecture/agent-runtime-compatibility.md +2 -0
  360. package/template/docs/architecture/embedded-dsh-integration.md +44 -0
  361. package/template/docs/development/dsh-plugins.md +55 -0
  362. package/template/docs/operations/dsh-agent-migration.md +98 -0
  363. package/template/docs/platform/agent-production-store.md +5 -78
  364. package/template/docs/platform/agent-runtime-observability.md +2 -0
  365. package/template/docs/platform/agent-runtime.md +2 -0
  366. package/template/docs/platform/agent-skills.md +25 -0
  367. package/template/package.json +4 -3
  368. package/template/packages/database/drizzle/0064_dsh_skills_diagnostics.sql +42 -0
  369. package/template/packages/database/drizzle/meta/0064_snapshot.json +15349 -0
  370. package/template/packages/database/drizzle/meta/_journal.json +7 -0
  371. package/template/packages/database/package.json +2 -2
  372. package/template/packages/database/src/schema/agent-skills.ts +65 -0
  373. package/template/packages/database/src/schema/diagnostics.ts +27 -0
  374. package/template/packages/database/src/schema/index.ts +8 -0
  375. package/template/packages/modules/package.json +1 -1
  376. package/template/packages/modules/src/system-admin-routes.ts +24 -0
  377. package/template/packages/modules/src/system-admin-ui-catalog.ts +17 -10
  378. package/template/packages/modules/src/system-agent-admin-bindings.ts +2 -0
  379. package/template/packages/modules/src/system-agent-admin-menus.ts +20 -0
  380. package/template/packages/modules/src/system-agent-audit-actions.ts +3 -0
  381. package/template/packages/modules/src/system-agent-dsh.ts +119 -0
  382. package/template/packages/modules/src/system-api-permissions.ts +9 -0
  383. package/template/packages/modules/src/system-audit-actions.ts +11 -0
  384. package/template/packages/modules/src/system-features.ts +5 -0
  385. package/template/packages/modules/src/system-module-audit-selection.ts +25 -0
  386. package/template/packages/modules/src/system-module-catalog.ts +12 -32
  387. package/template/packages/modules/src/system-modules.ts +14 -3
  388. package/template/packages/modules/src/system-permissions.ts +10 -0
  389. package/template/packages/server-sdk/package.json +2 -2
  390. package/template/packages/shared/index.ts +12 -0
  391. package/template/packages/shared/package.json +1 -1
  392. package/template/packages/shared/src/agent-skills.ts +68 -0
  393. package/template/packages/shared/src/agent-workflow-presets.ts +26 -0
  394. package/template/packages/shared/src/diagnostics.ts +13 -0
  395. package/template/packages/shared/src/rbac.ts +1 -0
  396. package/template/apps/agent-server/install-python-dependencies.sh +0 -92
  397. package/template/apps/agent-server/pyproject.toml +0 -51
  398. package/template/apps/agent-server/src/southwind_agent_server/__init__.py +0 -5
  399. package/template/apps/agent-server/src/southwind_agent_server/app.py +0 -344
  400. package/template/apps/agent-server/src/southwind_agent_server/approval_resolution.py +0 -30
  401. package/template/apps/agent-server/src/southwind_agent_server/artifact_input.py +0 -153
  402. package/template/apps/agent-server/src/southwind_agent_server/asgi.py +0 -8
  403. package/template/apps/agent-server/src/southwind_agent_server/attempt_context.py +0 -199
  404. package/template/apps/agent-server/src/southwind_agent_server/attempt_context_projection.py +0 -203
  405. package/template/apps/agent-server/src/southwind_agent_server/client_completion_contracts.py +0 -61
  406. package/template/apps/agent-server/src/southwind_agent_server/client_completion_governance.py +0 -82
  407. package/template/apps/agent-server/src/southwind_agent_server/client_completion_routes.py +0 -121
  408. package/template/apps/agent-server/src/southwind_agent_server/client_completion_runtime.py +0 -158
  409. package/template/apps/agent-server/src/southwind_agent_server/config.py +0 -267
  410. package/template/apps/agent-server/src/southwind_agent_server/context_message_digest.py +0 -24
  411. package/template/apps/agent-server/src/southwind_agent_server/context_version_contracts.py +0 -71
  412. package/template/apps/agent-server/src/southwind_agent_server/context_version_port.py +0 -307
  413. package/template/apps/agent-server/src/southwind_agent_server/contracts.py +0 -297
  414. package/template/apps/agent-server/src/southwind_agent_server/deterministic.py +0 -63
  415. package/template/apps/agent-server/src/southwind_agent_server/engine.py +0 -134
  416. package/template/apps/agent-server/src/southwind_agent_server/engine_capacity.py +0 -31
  417. package/template/apps/agent-server/src/southwind_agent_server/engine_identity.py +0 -2
  418. package/template/apps/agent-server/src/southwind_agent_server/fingerprint.py +0 -61
  419. package/template/apps/agent-server/src/southwind_agent_server/health_routes.py +0 -93
  420. package/template/apps/agent-server/src/southwind_agent_server/http_helpers.py +0 -62
  421. package/template/apps/agent-server/src/southwind_agent_server/lease.py +0 -15
  422. package/template/apps/agent-server/src/southwind_agent_server/multimodal.py +0 -76
  423. package/template/apps/agent-server/src/southwind_agent_server/openai_engine.py +0 -329
  424. package/template/apps/agent-server/src/southwind_agent_server/openai_engine_validation.py +0 -165
  425. package/template/apps/agent-server/src/southwind_agent_server/openai_provider.py +0 -345
  426. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_insert.py +0 -37
  427. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_queries.py +0 -235
  428. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_replay.py +0 -44
  429. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_status.py +0 -83
  430. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_store.py +0 -336
  431. package/template/apps/agent-server/src/southwind_agent_server/postgres_report_summary.py +0 -304
  432. package/template/apps/agent-server/src/southwind_agent_server/postgres_store.py +0 -335
  433. package/template/apps/agent-server/src/southwind_agent_server/postgres_store_backend.py +0 -333
  434. package/template/apps/agent-server/src/southwind_agent_server/provider_audit.py +0 -144
  435. package/template/apps/agent-server/src/southwind_agent_server/provider_governance.py +0 -309
  436. package/template/apps/agent-server/src/southwind_agent_server/provider_output_guidance.py +0 -34
  437. package/template/apps/agent-server/src/southwind_agent_server/readiness_pin.py +0 -37
  438. package/template/apps/agent-server/src/southwind_agent_server/report_lifecycle.py +0 -218
  439. package/template/apps/agent-server/src/southwind_agent_server/report_metrics.py +0 -149
  440. package/template/apps/agent-server/src/southwind_agent_server/report_presenter.py +0 -300
  441. package/template/apps/agent-server/src/southwind_agent_server/report_routes.py +0 -132
  442. package/template/apps/agent-server/src/southwind_agent_server/report_store.py +0 -298
  443. package/template/apps/agent-server/src/southwind_agent_server/report_store_protocol.py +0 -75
  444. package/template/apps/agent-server/src/southwind_agent_server/report_types.py +0 -118
  445. package/template/apps/agent-server/src/southwind_agent_server/run_admission.py +0 -64
  446. package/template/apps/agent-server/src/southwind_agent_server/run_capacity.py +0 -59
  447. package/template/apps/agent-server/src/southwind_agent_server/runtime_budget.py +0 -74
  448. package/template/apps/agent-server/src/southwind_agent_server/runtime_compatibility.py +0 -89
  449. package/template/apps/agent-server/src/southwind_agent_server/runtime_factory.py +0 -105
  450. package/template/apps/agent-server/src/southwind_agent_server/runtime_logging.py +0 -57
  451. package/template/apps/agent-server/src/southwind_agent_server/service.py +0 -325
  452. package/template/apps/agent-server/src/southwind_agent_server/service_control.py +0 -64
  453. package/template/apps/agent-server/src/southwind_agent_server/service_errors.py +0 -4
  454. package/template/apps/agent-server/src/southwind_agent_server/service_execution.py +0 -34
  455. package/template/apps/agent-server/src/southwind_agent_server/service_tasks.py +0 -34
  456. package/template/apps/agent-server/src/southwind_agent_server/signal_events.py +0 -53
  457. package/template/apps/agent-server/src/southwind_agent_server/sqlite_catalog.py +0 -118
  458. package/template/apps/agent-server/src/southwind_agent_server/sqlite_errors.py +0 -2
  459. package/template/apps/agent-server/src/southwind_agent_server/sqlite_schema.py +0 -73
  460. package/template/apps/agent-server/src/southwind_agent_server/sqlite_serialization.py +0 -16
  461. package/template/apps/agent-server/src/southwind_agent_server/sqlite_store.py +0 -350
  462. package/template/apps/agent-server/src/southwind_agent_server/sse.py +0 -41
  463. package/template/apps/agent-server/src/southwind_agent_server/store.py +0 -255
  464. package/template/apps/agent-server/src/southwind_agent_server/store_cipher.py +0 -40
  465. package/template/apps/agent-server/src/southwind_agent_server/structured_logging.py +0 -145
  466. package/template/apps/agent-server/src/southwind_agent_server/telemetry.py +0 -93
  467. package/template/apps/agent-server/src/southwind_agent_server/tool_host.py +0 -152
  468. package/template/apps/agent-server/src/southwind_agent_server/trajectory.py +0 -137
  469. package/template/apps/agent-server/src/southwind_agent_server/unavailable_engine.py +0 -58
  470. package/template/apps/agent-server/src/southwind_agent_server/vision_probe.py +0 -87
  471. package/template/apps/agent-server/src/southwind_agent_server/vision_requirement.py +0 -28
  472. package/template/apps/agent-server/src/southwind_agent_server/vlm_readiness.py +0 -247
  473. package/template/apps/agent-server/tests/__init__.py +0 -1
  474. package/template/apps/agent-server/tests/openai_provider_test_support.py +0 -131
  475. package/template/apps/agent-server/tests/test_api.py +0 -305
  476. package/template/apps/agent-server/tests/test_artifact_input.py +0 -110
  477. package/template/apps/agent-server/tests/test_client_completion.py +0 -230
  478. package/template/apps/agent-server/tests/test_config.py +0 -106
  479. package/template/apps/agent-server/tests/test_fingerprint.py +0 -10
  480. package/template/apps/agent-server/tests/test_multimodal.py +0 -81
  481. package/template/apps/agent-server/tests/test_openai_provider.py +0 -320
  482. package/template/apps/agent-server/tests/test_postgres_report_status.py +0 -59
  483. package/template/apps/agent-server/tests/test_postgres_report_summary.py +0 -298
  484. package/template/apps/agent-server/tests/test_postgres_store.py +0 -135
  485. package/template/apps/agent-server/tests/test_provider_attempt_reporting.py +0 -140
  486. package/template/apps/agent-server/tests/test_provider_governance.py +0 -276
  487. package/template/apps/agent-server/tests/test_report_attempt_lifecycle.py +0 -126
  488. package/template/apps/agent-server/tests/test_report_resilience.py +0 -183
  489. package/template/apps/agent-server/tests/test_report_routes.py +0 -143
  490. package/template/apps/agent-server/tests/test_report_store.py +0 -347
  491. package/template/apps/agent-server/tests/test_report_summary_parity.py +0 -116
  492. package/template/apps/agent-server/tests/test_report_terminal_sync.py +0 -177
  493. package/template/apps/agent-server/tests/test_run_capacity.py +0 -112
  494. package/template/apps/agent-server/tests/test_run_operational_logging.py +0 -114
  495. package/template/apps/agent-server/tests/test_runtime_compatibility.py +0 -119
  496. package/template/apps/agent-server/tests/test_runtime_factory_readiness.py +0 -52
  497. package/template/apps/agent-server/tests/test_sqlite_store.py +0 -182
  498. package/template/apps/agent-server/tests/test_structured_logging.py +0 -142
  499. package/template/apps/agent-server/tests/test_telemetry.py +0 -25
  500. package/template/apps/agent-server/tests/test_tool_approval.py +0 -28
  501. package/template/apps/agent-server/tests/test_tool_structured_output.py +0 -347
  502. package/template/apps/agent-server/tests/test_trajectory.py +0 -91
  503. package/template/apps/agent-server/tests/test_vision_readiness_enforcement.py +0 -72
  504. package/template/apps/agent-server/tests/test_vlm_readiness.py +0 -106
  505. package/template/apps/agent-server/uv.lock +0 -831
@@ -1,177 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
-
5
- from southwind_agent_server.contracts import (
6
- RunReportingContext,
7
- StartRunRequest,
8
- )
9
- from southwind_agent_server.deterministic import DeterministicEngineAdapter
10
- from southwind_agent_server.report_store import (
11
- InMemoryAgentRuntimeReportStore,
12
- )
13
- from southwind_agent_server.service import AgentRunService
14
- from southwind_agent_server.store import (
15
- CanonicalEvent,
16
- InMemoryRunStore,
17
- RunRecord,
18
- )
19
-
20
-
21
- def request(text: str = "done") -> StartRunRequest:
22
- return StartRunRequest(
23
- operation_key="test.echo",
24
- input={"text": text},
25
- trace_id="trace_1",
26
- reporting=RunReportingContext(
27
- actor_id="actor_1",
28
- actor_type="user",
29
- ),
30
- )
31
-
32
-
33
- async def test_rewritten_event_terminal_drives_report_status() -> None:
34
- canonical = EventLimitRunStore()
35
- report = InMemoryAgentRuntimeReportStore()
36
- service = AgentRunService(
37
- DeterministicEngineAdapter(),
38
- canonical,
39
- report,
40
- )
41
-
42
- record = await service.start(request(), "event-limit")
43
- final = await wait_for_terminal(service, record.run_id)
44
- detail = await report.get_run(record.run_id)
45
- await service.close()
46
-
47
- assert final.status == "failed"
48
- assert detail is not None
49
- assert detail["status"] == "failed"
50
- assert detail["safeErrorCode"] == "BUDGET_EXCEEDED"
51
-
52
-
53
- async def test_output_limit_terminal_drives_report_status() -> None:
54
- canonical = OutputLimitRunStore()
55
- report = InMemoryAgentRuntimeReportStore()
56
- service = AgentRunService(
57
- DeterministicEngineAdapter(),
58
- canonical,
59
- report,
60
- )
61
-
62
- record = await service.start(request("too large"), "output-limit")
63
- final = await wait_for_terminal(service, record.run_id)
64
- detail = await report.get_run(record.run_id)
65
- await service.close()
66
-
67
- assert final.status == "failed"
68
- assert detail is not None
69
- assert detail["status"] == "failed"
70
- assert detail["safeErrorCode"] == "BUDGET_EXCEEDED"
71
-
72
-
73
- async def test_completion_wins_cancel_race_in_report() -> None:
74
- canonical = CompleteWinsCancelRunStore()
75
- report = InMemoryAgentRuntimeReportStore()
76
- service = AgentRunService(
77
- DeterministicEngineAdapter(),
78
- canonical,
79
- report,
80
- )
81
- invocation = request()
82
- record = run_record(invocation, "race")
83
- await canonical.create_or_get(record, invocation.model_dump(by_alias=True))
84
- await report.ensure_run(record.run_id, invocation, 100.0)
85
- await report.start_run(record.run_id, 101.0)
86
-
87
- final = await service.cancel(record.run_id)
88
- detail = await report.get_run(record.run_id)
89
- await service.close()
90
-
91
- assert final.status == "completed"
92
- assert detail is not None
93
- assert detail["status"] == "completed"
94
-
95
-
96
- async def wait_for_terminal(
97
- service: AgentRunService,
98
- run_id: str,
99
- ) -> RunRecord:
100
- async def poll() -> RunRecord:
101
- while True:
102
- record = await service.get(run_id)
103
- if record.terminal:
104
- return record
105
- await asyncio.sleep(0)
106
-
107
- return await asyncio.wait_for(poll(), 1)
108
-
109
-
110
- def run_record(invocation: StartRunRequest, suffix: str) -> RunRecord:
111
- return RunRecord(
112
- run_id=f"run_{suffix}",
113
- operation_key=invocation.operation_key,
114
- input=invocation.input,
115
- idempotency_key=f"key_{suffix}",
116
- fingerprint=f"fingerprint_{suffix}",
117
- release=invocation.release.model_dump(by_alias=True),
118
- trace_id=invocation.trace_id,
119
- )
120
-
121
-
122
- def failure_event(run_id: str, sequence: int) -> CanonicalEvent:
123
- return {
124
- "type": "run.failed",
125
- "runId": run_id,
126
- "sequence": sequence,
127
- "error": {
128
- "code": "BUDGET_EXCEEDED",
129
- "message": "Agent 存储超过安全上限",
130
- "requestId": f"request_{sequence}",
131
- "retryable": False,
132
- },
133
- }
134
-
135
-
136
- class EventLimitRunStore(InMemoryRunStore):
137
- async def append(
138
- self,
139
- run_id: str,
140
- event_type: str,
141
- fields: dict[str, object] | None = None,
142
- ) -> CanonicalEvent | None:
143
- if event_type == "usage.reported":
144
- record = await self.get(run_id)
145
- assert record is not None
146
- event = failure_event(run_id, len(record.events) + 1)
147
- return await super().append(
148
- run_id,
149
- "run.failed",
150
- {"error": event["error"]},
151
- )
152
- return await super().append(run_id, event_type, fields)
153
-
154
-
155
- class OutputLimitRunStore(InMemoryRunStore):
156
- async def complete(self, run_id: str, output: object) -> None:
157
- del output
158
- record = await self.get(run_id)
159
- assert record is not None
160
- event = failure_event(run_id, len(record.events) + 1)
161
- await super().append(
162
- run_id,
163
- "run.failed",
164
- {"error": event["error"]},
165
- )
166
-
167
-
168
- class CompleteWinsCancelRunStore(InMemoryRunStore):
169
- async def append(
170
- self,
171
- run_id: str,
172
- event_type: str,
173
- fields: dict[str, object] | None = None,
174
- ) -> CanonicalEvent | None:
175
- if event_type == "run.cancelled":
176
- await super().complete(run_id, {"winner": "complete"})
177
- return await super().append(run_id, event_type, fields)
@@ -1,112 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- from collections.abc import AsyncIterator
5
-
6
- import httpx
7
-
8
- from southwind_agent_server.app import create_app
9
- from southwind_agent_server.engine import (
10
- EngineCompleted,
11
- EngineRunRequest,
12
- EngineSignal,
13
- )
14
- from southwind_agent_server.engine_identity import DIRECT_ENGINE_ID
15
- from southwind_agent_server.report_store import InMemoryAgentRuntimeReportStore
16
- from southwind_agent_server.store import InMemoryRunStore
17
-
18
-
19
- class LimitedEngine:
20
- engine_id = DIRECT_ENGINE_ID
21
- max_concurrent_runs = 1
22
- max_queue_depth = 1
23
-
24
- def __init__(self) -> None:
25
- self.started: asyncio.Queue[str] = asyncio.Queue()
26
- self.releases: dict[str, asyncio.Event] = {}
27
- self.active = 0
28
- self.max_active = 0
29
-
30
- @property
31
- def capabilities(self) -> tuple[str, ...]:
32
- return ("text-generation",)
33
-
34
- @property
35
- def input_modalities(self) -> tuple[str, ...]:
36
- return ("text",)
37
-
38
- def supports(self, operation_key: str) -> bool:
39
- return operation_key == "test.capacity"
40
-
41
- async def execute(self, request: EngineRunRequest) -> AsyncIterator[EngineSignal]:
42
- release = self.releases.setdefault(request.run_id, asyncio.Event())
43
- self.active += 1
44
- self.max_active = max(self.max_active, self.active)
45
- await self.started.put(request.run_id)
46
- try:
47
- await release.wait()
48
- yield EngineCompleted(request.input)
49
- finally:
50
- self.active -= 1
51
-
52
- async def cancel(self, run_id: str) -> None:
53
- self.releases.setdefault(run_id, asyncio.Event()).set()
54
-
55
-
56
- async def test_vlm_capacity_enforces_concurrency_queue_and_idempotency() -> None:
57
- engine = LimitedEngine()
58
- application = create_app(
59
- engine,
60
- store=InMemoryRunStore(),
61
- report_store=InMemoryAgentRuntimeReportStore(),
62
- )
63
- try:
64
- async with httpx.AsyncClient(
65
- transport=httpx.ASGITransport(app=application),
66
- base_url="http://agent.test",
67
- ) as client:
68
- first = await start(client, "capacity-1", "first")
69
- first_id = str(first.json()["runId"])
70
- assert await asyncio.wait_for(engine.started.get(), 1) == first_id
71
-
72
- second = await start(client, "capacity-2", "second")
73
- second_id = str(second.json()["runId"])
74
- same = await start(client, "capacity-2", "second")
75
- assert same.json()["runId"] == second_id
76
-
77
- conflict = await start(client, "capacity-2", "changed")
78
- assert conflict.status_code == 409
79
- assert conflict.json()["code"] == "RUN_CONFLICT"
80
-
81
- rejected = await start(client, "capacity-3", "third")
82
- assert rejected.status_code == 503
83
- assert rejected.json()["code"] == "RUNTIME_UNAVAILABLE"
84
- assert rejected.json()["message"] == "VLM Runtime 容量已满"
85
- assert rejected.json()["retryable"] is True
86
- assert str(rejected.json()["requestId"]).startswith("request_")
87
- assert engine.active == 1
88
-
89
- engine.releases[first_id].set()
90
- assert await asyncio.wait_for(engine.started.get(), 1) == second_id
91
- assert engine.max_active == 1
92
- engine.releases[second_id].set()
93
- await terminal(client, second_id)
94
- finally:
95
- await application.state.run_service.close()
96
-
97
-
98
- async def start(client: httpx.AsyncClient, key: str, value: str) -> httpx.Response:
99
- return await client.post(
100
- "/api/agent/runs",
101
- headers={"Idempotency-Key": key},
102
- json={"operationKey": "test.capacity", "input": {"text": value}},
103
- )
104
-
105
-
106
- async def terminal(client: httpx.AsyncClient, run_id: str) -> None:
107
- for _ in range(100):
108
- response = await client.get(f"/api/agent/runs/{run_id}")
109
- if response.json()["status"] == "completed":
110
- return
111
- await asyncio.sleep(0.01)
112
- raise AssertionError("Agent Run 未在容量释放后完成")
@@ -1,114 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- import io
5
- import json
6
- import logging
7
- from collections.abc import Iterator
8
- from typing import TextIO, cast
9
-
10
- import httpx
11
- import pytest
12
-
13
- from southwind_agent_server.app import create_app
14
- from southwind_agent_server.deterministic import DeterministicEngineAdapter
15
- from southwind_agent_server.runtime_logging import AgentOperationalAttempt, logger
16
- from southwind_agent_server.service import AgentRunService
17
- from southwind_agent_server.store import RunRecord
18
- from southwind_agent_server.structured_logging import AgentStructuredLogHandler
19
-
20
-
21
- @pytest.fixture(autouse=True)
22
- def operational_log_level() -> Iterator[None]:
23
- previous = logger.level
24
- logger.setLevel(logging.INFO)
25
- try:
26
- yield
27
- finally:
28
- logger.setLevel(previous)
29
-
30
-
31
- @pytest.mark.parametrize("broken_sink", [False, True])
32
- async def test_real_run_completion_and_replay_with_operational_logs(
33
- monkeypatch: pytest.MonkeyPatch,
34
- broken_sink: bool,
35
- ) -> None:
36
- class Stream(io.StringIO):
37
- def write(self, value: str) -> int:
38
- written = super().write(value)
39
- if broken_sink:
40
- raise OSError("sink-secret")
41
- return written
42
-
43
- stream = Stream()
44
- monkeypatch.setattr(logger, "handlers", [AgentStructuredLogHandler(stream)])
45
- monkeypatch.setattr(logger, "propagate", False)
46
- app = create_app(DeterministicEngineAdapter(), heartbeat_seconds=0.01)
47
- service = cast(AgentRunService, app.state.run_service)
48
- async with httpx.AsyncClient(
49
- transport=httpx.ASGITransport(app=app),
50
- base_url="http://agent.test",
51
- ) as client:
52
-
53
- async def start() -> httpx.Response:
54
- return await client.post(
55
- "/api/agent/runs",
56
- headers={"Idempotency-Key": "operational-replay"},
57
- json={
58
- "operationKey": "test.echo",
59
- "input": {"text": "input-secret"},
60
- "traceId": "1" * 32,
61
- },
62
- )
63
-
64
- response = await start()
65
- assert response.status_code == 200
66
- run_id = str(response.json()["runId"])
67
- await asyncio.gather(*service._tasks)
68
- replay = await start()
69
- assert replay.json()["runId"] == run_id
70
- events = await client.get(f"/api/agent/runs/{run_id}/events")
71
- result = await client.get(f"/api/agent/runs/{run_id}/result")
72
- assert result.json()["status"] == "completed"
73
- assert result.json()["output"] == {"text": "input-secret"}
74
- assert "run.failed" not in events.text
75
- records = [json.loads(line) for line in stream.getvalue().splitlines()]
76
- assert [record["event"] for record in records] == [
77
- "agent.run.attempt.started",
78
- "agent.run.attempt.completed",
79
- ]
80
- assert all(record["runId"] == run_id for record in records)
81
- assert all(record["traceId"] == "1" * 32 for record in records)
82
- assert records[-1]["outcome"] == "success"
83
- assert records[-1]["durationMs"] >= 0
84
- assert "input-secret" not in stream.getvalue()
85
- assert "sink-secret" not in stream.getvalue()
86
-
87
-
88
- @pytest.mark.parametrize("status", ["failed", "cancelled", "running"])
89
- def test_attempt_terminal_mapping_and_duplicate_finish_are_safe(
90
- monkeypatch: pytest.MonkeyPatch,
91
- status: str,
92
- ) -> None:
93
- stream = io.StringIO()
94
- monkeypatch.setattr(logger, "handlers", [AgentStructuredLogHandler(stream)])
95
- monkeypatch.setattr(logger, "propagate", False)
96
- record = RunRecord("run-1", "test.echo", {"secret": "input"}, "key", "digest")
97
- attempt = AgentOperationalAttempt(record)
98
- attempt.start()
99
- attempt.start()
100
- attempt.finish(status)
101
- attempt.finish(status)
102
- records = [json.loads(line) for line in stream.getvalue().splitlines()]
103
- assert len(records) == 2
104
- assert records[-1]["outcome"] == "failure"
105
- expected = status if status in {"failed", "cancelled"} else "interrupted"
106
- assert records[-1]["errorCode"] == f"AGENT_RUN_{expected.upper()}"
107
- assert "secret" not in stream.getvalue()
108
-
109
-
110
- def test_unknown_info_message_does_not_expand_log_content() -> None:
111
- stream = io.StringIO()
112
- handler = AgentStructuredLogHandler(cast(TextIO, stream))
113
- handler.emit(logging.makeLogRecord({"levelno": logging.INFO, "msg": "secret"}))
114
- assert stream.getvalue() == ""
@@ -1,119 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import json
4
- from collections.abc import AsyncIterator
5
- from pathlib import Path
6
- from typing import cast
7
-
8
- import httpx
9
- import pytest
10
-
11
- from southwind_agent_server.app import create_app
12
- from southwind_agent_server.deterministic import DeterministicEngineAdapter
13
- from southwind_agent_server.runtime_compatibility import (
14
- runtime_compatibility_offer,
15
- )
16
-
17
- TOKEN = "runtime-compatibility-test-token"
18
-
19
-
20
- @pytest.fixture
21
- async def client() -> AsyncIterator[httpx.AsyncClient]:
22
- app = create_app(DeterministicEngineAdapter(), internal_token=TOKEN)
23
- async with httpx.AsyncClient(
24
- transport=httpx.ASGITransport(app=app),
25
- base_url="http://agent.test",
26
- ) as value:
27
- yield value
28
-
29
-
30
- async def test_compatibility_offer_is_authenticated_and_matches_public_fixture(
31
- client: httpx.AsyncClient,
32
- ) -> None:
33
- denied = await client.get("/api/agent/runtime/compatibility")
34
- allowed = await client.get(
35
- "/api/agent/runtime/compatibility",
36
- headers={"Authorization": f"Bearer {TOKEN}"},
37
- )
38
-
39
- assert denied.status_code == 403
40
- assert allowed.status_code == 200
41
- assert allowed.json() == public_fixture()
42
-
43
-
44
- async def test_start_accepts_legacy_without_pin(
45
- client: httpx.AsyncClient,
46
- ) -> None:
47
- legacy = await start(client, "legacy-pin")
48
-
49
- assert legacy.status_code == 200
50
-
51
-
52
- async def test_start_accepts_complete_matching_pin(
53
- client: httpx.AsyncClient,
54
- ) -> None:
55
- offer = runtime_compatibility_offer("windy.direct.openai-compatible.v1")
56
- pinned = await start(
57
- client,
58
- "current-pin",
59
- {
60
- "X-Windy-Agent-Runtime-Protocol": "1",
61
- "X-Windy-Agent-Runtime-Offer-Digest": str(offer["offerDigest"]),
62
- },
63
- )
64
-
65
- assert pinned.status_code == 200
66
-
67
-
68
- @pytest.mark.parametrize(
69
- "headers",
70
- [
71
- {"X-Windy-Agent-Runtime-Protocol": "1"},
72
- {"X-Windy-Agent-Runtime-Offer-Digest": "sha256:" + "0" * 64},
73
- {
74
- "X-Windy-Agent-Runtime-Protocol": "2",
75
- "X-Windy-Agent-Runtime-Offer-Digest": "sha256:" + "0" * 64,
76
- },
77
- {
78
- "X-Windy-Agent-Runtime-Protocol": "1",
79
- "X-Windy-Agent-Runtime-Offer-Digest": "sha256:" + "0" * 64,
80
- },
81
- ],
82
- )
83
- async def test_start_rejects_partial_or_incompatible_pin_before_admission(
84
- client: httpx.AsyncClient,
85
- headers: dict[str, str],
86
- ) -> None:
87
- response = await start(client, "rejected-pin", headers)
88
-
89
- assert response.status_code == 409
90
- assert response.json() == {
91
- "code": "RUNTIME_UNAVAILABLE",
92
- "message": "Agent Runtime compatibility pin 不匹配",
93
- "requestId": response.json()["requestId"],
94
- "retryable": False,
95
- }
96
-
97
-
98
- async def start(
99
- client: httpx.AsyncClient,
100
- key: str,
101
- headers: dict[str, str] | None = None,
102
- ) -> httpx.Response:
103
- return await client.post(
104
- "/api/agent/runs",
105
- headers={
106
- "Authorization": f"Bearer {TOKEN}",
107
- "Idempotency-Key": key,
108
- **(headers or {}),
109
- },
110
- json={"operationKey": "test.echo", "input": {"text": key}},
111
- )
112
-
113
-
114
- def public_fixture() -> dict[str, object]:
115
- path = (
116
- Path(__file__).parents[3]
117
- / "packages/server-sdk/contracts/agent-runtime-compatibility/v1/offer.json"
118
- )
119
- return cast(dict[str, object], json.loads(path.read_text(encoding="utf8")))
@@ -1,52 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from unittest.mock import AsyncMock, patch
4
-
5
- from pytest import MonkeyPatch
6
-
7
- from southwind_agent_server.openai_engine import OpenAiCompatibleEngineAdapter
8
- from southwind_agent_server.runtime_factory import default_engine
9
- from southwind_agent_server.unavailable_engine import UnavailableEngineAdapter
10
-
11
-
12
- async def test_default_direct_engine_exposes_vlm_readiness(
13
- monkeypatch: MonkeyPatch,
14
- ) -> None:
15
- values = {
16
- "QWEN_API_URL": "http://vlm.internal/v1",
17
- "QWEN_MODEL": "vision-model",
18
- "AGENT_SERVER_INTERNAL_TOKEN": "internal-token",
19
- "AI_PROVIDER_AUDIT_STORE_PATH": ".data/provider-audit.sqlite3",
20
- "AI_PROVIDER_CAPABILITIES": "text-generation,vision",
21
- "AI_PROVIDER_INPUT_MODALITIES": "text,image",
22
- "AI_PROVIDER_DEPLOYMENT_IDENTITY": (
23
- "windy-deployment-v1_f31e8a65-92cb-4d03-8a77-3c1b5e9d4f04"
24
- ),
25
- "AI_PROVIDER_RELEASE_DIGEST": "sha256:" + "d" * 64,
26
- }
27
- for key, value in values.items():
28
- monkeypatch.setenv(key, value)
29
- engine = default_engine()
30
- assert isinstance(engine, OpenAiCompatibleEngineAdapter)
31
- assert engine.engine_id == "windy.direct.openai-compatible.v1"
32
- provider = engine._provider
33
- assert provider is not None
34
- with patch.object(provider, "probe_vision", AsyncMock()) as probe:
35
- snapshot = await engine.readiness()
36
-
37
- probe.assert_awaited_once()
38
- assert snapshot["status"] == "ready"
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