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,255 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import asyncio
4
- from dataclasses import dataclass, field
5
- from typing import Protocol
6
-
7
- from .contracts import JsonValue, RunStatus
8
- from .engine_identity import DIRECT_ENGINE_ID
9
-
10
- CanonicalEvent = dict[str, object]
11
- TERMINAL_STATUSES = frozenset({"completed", "failed", "cancelled"})
12
-
13
-
14
- @dataclass
15
- class RunRecord:
16
- run_id: str
17
- operation_key: str
18
- input: JsonValue
19
- idempotency_key: str
20
- fingerprint: str
21
- engine_id: str = DIRECT_ENGINE_ID
22
- release: JsonValue = None
23
- trace_id: str = ""
24
- status: RunStatus = "accepted"
25
- events: list[CanonicalEvent] = field(default_factory=list)
26
- output: JsonValue = None
27
-
28
- @property
29
- def terminal(self) -> bool:
30
- return self.status in TERMINAL_STATUSES
31
-
32
-
33
- class IdempotencyConflictError(Exception):
34
- pass
35
-
36
-
37
- class ReleaseNotFoundError(Exception):
38
- pass
39
-
40
-
41
- class RunStore(Protocol):
42
- async def create_or_get(
43
- self,
44
- record: RunRecord,
45
- invocation: JsonValue = None,
46
- ) -> tuple[RunRecord, bool]: ...
47
- async def get_by_idempotency(self, idempotency_key: str) -> RunRecord | None: ...
48
- async def get(self, run_id: str) -> RunRecord | None: ...
49
- async def append(
50
- self,
51
- run_id: str,
52
- event_type: str,
53
- fields: dict[str, object] | None = None,
54
- ) -> CanonicalEvent | None: ...
55
- async def complete(self, run_id: str, output: JsonValue) -> None: ...
56
- async def events_after(
57
- self,
58
- run_id: str,
59
- after: int,
60
- wait_seconds: float,
61
- ) -> tuple[list[CanonicalEvent], bool]: ...
62
- async def save_invocation(self, run_id: str, value: JsonValue) -> None: ...
63
- async def recoverable(self) -> list[tuple[RunRecord, JsonValue]]: ...
64
- async def clear_invocation(self, run_id: str) -> None: ...
65
- async def record_evaluation(
66
- self,
67
- release_id: str,
68
- evaluation_set_key: str,
69
- evaluation_set_version: str,
70
- metrics: dict[str, float],
71
- ) -> str: ...
72
- async def renew_lease(self, run_id: str) -> None: ...
73
- async def release_lease(self, run_id: str) -> None: ...
74
- async def probe(self) -> None: ...
75
- async def close(self) -> None: ...
76
-
77
-
78
- class InMemoryRunStore:
79
- """Non-production store for deterministic tests and local development only."""
80
-
81
- def __init__(self) -> None:
82
- self._runs: dict[str, RunRecord] = {}
83
- self._idempotency: dict[str, str] = {}
84
- self._condition = asyncio.Condition()
85
- self._invocations: dict[str, JsonValue] = {}
86
- self._evaluations: dict[tuple[str, str, str], tuple[str, dict[str, float]]] = {}
87
- self._releases: dict[str, tuple[str, JsonValue]] = {}
88
-
89
- async def create_or_get(
90
- self,
91
- record: RunRecord,
92
- invocation: JsonValue = None,
93
- ) -> tuple[RunRecord, bool]:
94
- async with self._condition:
95
- existing_id = self._idempotency.get(record.idempotency_key)
96
- if existing_id is not None:
97
- existing = self._runs[existing_id]
98
- if existing.fingerprint != record.fingerprint:
99
- raise IdempotencyConflictError
100
- return existing, False
101
- release_id = release_id_of(record)
102
- release = (record.operation_key, record.release)
103
- existing_release = self._releases.get(release_id)
104
- if existing_release is not None and existing_release != release:
105
- raise IdempotencyConflictError
106
- self._releases[release_id] = release
107
- self._runs[record.run_id] = record
108
- self._idempotency[record.idempotency_key] = record.run_id
109
- if invocation is not None:
110
- self._invocations[record.run_id] = invocation
111
- self._condition.notify_all()
112
- return record, True
113
-
114
- async def get(self, run_id: str) -> RunRecord | None:
115
- async with self._condition:
116
- return self._runs.get(run_id)
117
-
118
- async def get_by_idempotency(self, idempotency_key: str) -> RunRecord | None:
119
- async with self._condition:
120
- run_id = self._idempotency.get(idempotency_key)
121
- return self._runs.get(run_id) if run_id else None
122
-
123
- async def append(
124
- self,
125
- run_id: str,
126
- event_type: str,
127
- fields: dict[str, object] | None = None,
128
- ) -> CanonicalEvent | None:
129
- async with self._condition:
130
- record = self._runs[run_id]
131
- if record.terminal:
132
- return None
133
- event: CanonicalEvent = {
134
- "type": event_type,
135
- "runId": run_id,
136
- "sequence": len(record.events) + 1,
137
- **(fields or {}),
138
- }
139
- record.events.append(event)
140
- record.status = status_for(event_type, record.status)
141
- self._condition.notify_all()
142
- return event
143
-
144
- async def complete(self, run_id: str, output: JsonValue) -> None:
145
- async with self._condition:
146
- record = self._runs[run_id]
147
- if record.terminal:
148
- return
149
- record.output = output
150
- event: CanonicalEvent = {
151
- "type": "run.completed",
152
- "runId": run_id,
153
- "sequence": len(record.events) + 1,
154
- }
155
- record.events.append(event)
156
- record.status = "completed"
157
- self._condition.notify_all()
158
-
159
- async def events_after(
160
- self,
161
- run_id: str,
162
- after: int,
163
- wait_seconds: float,
164
- ) -> tuple[list[CanonicalEvent], bool]:
165
- async with self._condition:
166
- record = self._runs[run_id]
167
-
168
- def ready() -> bool:
169
- return len(record.events) > after or record.terminal
170
-
171
- if not ready():
172
- try:
173
- await asyncio.wait_for(
174
- self._condition.wait_for(ready),
175
- wait_seconds,
176
- )
177
- except TimeoutError:
178
- return [], False
179
- return list(record.events[after:]), record.terminal
180
-
181
- async def save_invocation(self, run_id: str, value: JsonValue) -> None:
182
- async with self._condition:
183
- if run_id not in self._runs:
184
- raise KeyError(run_id)
185
- self._invocations[run_id] = value
186
-
187
- async def recoverable(self) -> list[tuple[RunRecord, JsonValue]]:
188
- async with self._condition:
189
- return [
190
- (record, self._invocations[run_id])
191
- for run_id, record in self._runs.items()
192
- if not record.terminal and run_id in self._invocations
193
- ]
194
-
195
- async def clear_invocation(self, run_id: str) -> None:
196
- async with self._condition:
197
- self._invocations.pop(run_id, None)
198
-
199
- async def record_evaluation(
200
- self,
201
- release_id: str,
202
- evaluation_set_key: str,
203
- evaluation_set_version: str,
204
- metrics: dict[str, float],
205
- ) -> str:
206
- async with self._condition:
207
- if release_id not in self._releases:
208
- raise ReleaseNotFoundError
209
- key = (release_id, evaluation_set_key, evaluation_set_version)
210
- existing = self._evaluations.get(key)
211
- if existing:
212
- if existing[1] != metrics:
213
- raise IdempotencyConflictError
214
- return existing[0]
215
- evaluation_id = f"eval_{len(self._evaluations) + 1}"
216
- self._evaluations[key] = (evaluation_id, metrics)
217
- return evaluation_id
218
-
219
- async def renew_lease(self, run_id: str) -> None:
220
- record = self._runs.get(run_id)
221
- if record is None or record.terminal:
222
- raise KeyError(run_id)
223
-
224
- async def release_lease(self, run_id: str) -> None:
225
- if run_id not in self._runs:
226
- raise KeyError(run_id)
227
-
228
- async def probe(self) -> None:
229
- return None
230
-
231
- async def close(self) -> None:
232
- return None
233
-
234
-
235
- def status_for(event_type: str, current: RunStatus) -> RunStatus:
236
- if event_type == "run.started":
237
- return "running"
238
- if event_type == "approval.required":
239
- return "awaiting-approval"
240
- if event_type == "approval.resolved":
241
- return "running"
242
- if event_type == "run.failed":
243
- return "failed"
244
- if event_type == "run.cancelled":
245
- return "cancelled"
246
- return current
247
-
248
-
249
- def release_id_of(record: RunRecord) -> str:
250
- if not isinstance(record.release, dict):
251
- raise IdempotencyConflictError
252
- release_id = record.release.get("releaseId")
253
- if not isinstance(release_id, str):
254
- raise IdempotencyConflictError
255
- return release_id
@@ -1,40 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import base64
4
- import hashlib
5
- import json
6
- import os
7
- from typing import cast
8
-
9
- from cryptography.hazmat.primitives.ciphers.aead import AESGCM
10
-
11
- from .contracts import JsonValue
12
-
13
-
14
- class RunStoreCipher:
15
- def __init__(self, secret: str) -> None:
16
- if len(secret.encode()) < 32:
17
- raise ValueError("AGENT_RUN_ENCRYPTION_SECRET 至少需要 32 字节")
18
- self._key = hashlib.sha256(secret.encode()).digest()
19
-
20
- def seal(self, value: JsonValue) -> str:
21
- nonce = os.urandom(12)
22
- body = json.dumps(
23
- value,
24
- ensure_ascii=False,
25
- separators=(",", ":"),
26
- ).encode()
27
- encrypted = AESGCM(self._key).encrypt(nonce, body, b"agent-run-v1")
28
- return base64.urlsafe_b64encode(nonce + encrypted).decode()
29
-
30
- def open(self, value: str) -> JsonValue:
31
- try:
32
- raw = base64.urlsafe_b64decode(value.encode())
33
- body = AESGCM(self._key).decrypt(
34
- raw[:12],
35
- raw[12:],
36
- b"agent-run-v1",
37
- )
38
- return cast(JsonValue, json.loads(body))
39
- except Exception as error:
40
- raise ValueError("Agent Run 加密上下文无法解密") from error
@@ -1,145 +0,0 @@
1
- """Agent runtime adapter for the Windy operational log contract."""
2
-
3
- from __future__ import annotations
4
-
5
- import json
6
- import logging
7
- import math
8
- import re
9
- import sys
10
- from datetime import UTC, datetime
11
- from typing import TextIO
12
-
13
- MAX_LOG_BYTES = 2048
14
- _CORRELATION = re.compile(r"^[A-Za-z0-9._-]{1,128}$")
15
- _STABLE = re.compile(r"^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$")
16
- _EVENTS = {
17
- "Agent Run 恢复轮询失败,将继续重试": (
18
- "agent.run.recovery.failed",
19
- "AGENT_RUN_RECOVERY_FAILED",
20
- ),
21
- "Agent Runtime 报表写入失败": (
22
- "agent.report.write.failed",
23
- "AGENT_REPORT_WRITE_FAILED",
24
- ),
25
- }
26
- _ATTEMPT_EVENTS = frozenset(
27
- {
28
- "agent.run.attempt.started",
29
- "agent.run.attempt.completed",
30
- }
31
- )
32
- _ATTEMPT_ERRORS = {
33
- "failed": "AGENT_RUN_FAILED",
34
- "cancelled": "AGENT_RUN_CANCELLED",
35
- "interrupted": "AGENT_RUN_INTERRUPTED",
36
- }
37
-
38
-
39
- def agent_log_record(record: logging.LogRecord) -> dict[str, str | bool | float]:
40
- """Map known runtime failures without serializing messages, errors or extras."""
41
- event, error_code = _EVENTS.get(
42
- record.msg if isinstance(record.msg, str) else "",
43
- ("agent.runtime.failed", "AGENT_RUNTIME_FAILED"),
44
- )
45
- attempt_event = getattr(record, "operational_event", None)
46
- is_attempt = isinstance(attempt_event, str) and attempt_event in _ATTEMPT_EVENTS
47
- result: dict[str, str | bool | float] = {
48
- "timestamp": datetime.now(UTC)
49
- .isoformat(timespec="milliseconds")
50
- .replace("+00:00", "Z"),
51
- "level": "error"
52
- if record.levelno >= logging.ERROR
53
- else ("warn" if record.levelno >= logging.WARNING else "info"),
54
- "component": "agent-server",
55
- "event": attempt_event
56
- if isinstance(attempt_event, str) and is_attempt
57
- else event,
58
- "retentionClass": "operational",
59
- }
60
- if not is_attempt:
61
- result.update(outcome="failure", errorCode=error_code)
62
- elif attempt_event == "agent.run.attempt.completed":
63
- status = getattr(record, "operational_status", "interrupted")
64
- if status not in {"completed", "failed", "cancelled"}:
65
- status = "interrupted"
66
- result["stageKey"] = status
67
- result["outcome"] = "success" if status == "completed" else "failure"
68
- if status != "completed":
69
- result["errorCode"] = _ATTEMPT_ERRORS[status]
70
- duration = getattr(record, "operational_duration_ms", None)
71
- if (
72
- isinstance(duration, (int, float))
73
- and not isinstance(duration, bool)
74
- and math.isfinite(duration)
75
- and 0 <= duration <= 3_600_000
76
- ):
77
- result["durationMs"] = duration
78
- for source, target in (
79
- ("request_id", "requestId"),
80
- ("run_id", "runId"),
81
- ("job_id", "jobId"),
82
- ("trace_id", "traceId"),
83
- ):
84
- value = getattr(record, source, None)
85
- if isinstance(value, str) and _CORRELATION.fullmatch(value):
86
- result[target] = value
87
- stage = getattr(record, "report_stage", None)
88
- if isinstance(stage, str) and len(stage) <= 64 and _STABLE.fullmatch(stage):
89
- result["stageKey"] = stage
90
- for key in ("stageKey", "traceId", "jobId", "runId", "requestId"):
91
- if len(json.dumps(result, ensure_ascii=False).encode("utf-8")) <= MAX_LOG_BYTES:
92
- break
93
- result.pop(key, None)
94
- result["truncated"] = True
95
- return result
96
-
97
-
98
- class AgentStructuredLogHandler(logging.Handler):
99
- def __init__(self, stream: TextIO | None = None) -> None:
100
- super().__init__(level=logging.INFO)
101
- self.stream = stream or sys.stdout
102
-
103
- def emit(self, record: logging.LogRecord) -> None:
104
- try:
105
- if (
106
- record.levelno < logging.WARNING
107
- and getattr(record, "operational_event", None) not in _ATTEMPT_EVENTS
108
- ):
109
- return
110
- line = json.dumps(
111
- agent_log_record(record), ensure_ascii=False, separators=(",", ":")
112
- )
113
- self.stream.write(f"{line}\n")
114
- self.flush()
115
- except Exception:
116
- # 运行日志旁路失败时不能改变 Run 与报表写入的业务结果。
117
- return
118
-
119
- def flush(self) -> None:
120
- try:
121
- self.stream.flush()
122
- except Exception:
123
- return
124
-
125
-
126
- def configure_agent_logging() -> None:
127
- """Use one package sink without closing handlers shared with Uvicorn."""
128
- logger = logging.getLogger("southwind_agent_server")
129
- structured = next(
130
- (
131
- handler
132
- for handler in logger.handlers
133
- if isinstance(handler, AgentStructuredLogHandler)
134
- ),
135
- None,
136
- )
137
- if structured is None:
138
- structured = AgentStructuredLogHandler()
139
- for handler in logger.handlers[:]:
140
- if handler is not structured:
141
- logger.removeHandler(handler)
142
- if structured not in logger.handlers:
143
- logger.addHandler(structured)
144
- logger.setLevel(logging.INFO)
145
- logger.propagate = False
@@ -1,93 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import secrets
5
- from contextvars import Token
6
-
7
- from opentelemetry import context, trace
8
- from opentelemetry.context import Context
9
- from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
10
- from opentelemetry.sdk.resources import Resource
11
- from opentelemetry.sdk.trace import TracerProvider
12
- from opentelemetry.sdk.trace.export import BatchSpanProcessor
13
- from opentelemetry.trace import (
14
- NonRecordingSpan,
15
- Span,
16
- SpanContext,
17
- TraceFlags,
18
- )
19
-
20
- from .runtime_logging import AgentOperationalAttempt
21
- from .store import RunRecord
22
-
23
- _configured = False
24
-
25
-
26
- def configure_telemetry() -> None:
27
- global _configured
28
- endpoint = os.environ.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "").strip()
29
- if _configured or not endpoint:
30
- return
31
- provider = TracerProvider(
32
- resource=Resource.create({"service.name": "southwind-agent-server"})
33
- )
34
- provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint=endpoint)))
35
- trace.set_tracer_provider(provider)
36
- _configured = True
37
-
38
-
39
- class AgentRunTrace:
40
- """OTel span carrying metadata only; prompts, inputs and outputs stay excluded."""
41
-
42
- def __init__(self, record: RunRecord) -> None:
43
- parent = parent_context(record.trace_id)
44
- self._span: Span = trace.get_tracer(__name__).start_span(
45
- "agent.run",
46
- context=parent,
47
- attributes={
48
- "agent.run.id": record.run_id,
49
- "agent.operation.key": record.operation_key,
50
- "agent.release.id": release_id(record),
51
- },
52
- )
53
- self._token: Token[Context] | None = None
54
- self._operational = AgentOperationalAttempt(record)
55
-
56
- def start(self) -> None:
57
- self._token = context.attach(trace.set_span_in_context(self._span))
58
- self._operational.start()
59
-
60
- def finish(self, status: str) -> None:
61
- self._operational.finish(status)
62
- self._span.set_attribute("agent.run.status", status)
63
- if self._token is not None:
64
- context.detach(self._token)
65
- self._span.end()
66
-
67
-
68
- def parent_context(trace_id: str) -> context.Context | None:
69
- if len(trace_id) != 32:
70
- return None
71
- try:
72
- parsed = int(trace_id, 16)
73
- except ValueError:
74
- return None
75
- if parsed == 0:
76
- return None
77
- parent = NonRecordingSpan(
78
- SpanContext(
79
- trace_id=parsed,
80
- span_id=secrets.randbits(64) or 1,
81
- is_remote=True,
82
- trace_flags=TraceFlags(TraceFlags.SAMPLED),
83
- )
84
- )
85
- return trace.set_span_in_context(parent)
86
-
87
-
88
- def release_id(record: RunRecord) -> str:
89
- if isinstance(record.release, dict):
90
- value = record.release.get("releaseId")
91
- if isinstance(value, str):
92
- return value
93
- return "unknown"
@@ -1,152 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import hashlib
4
- import json
5
- from dataclasses import dataclass
6
-
7
- import httpx
8
-
9
- from .config import normalize_base_url
10
- from .contracts import JsonValue
11
- from .engine import SafeEngineError
12
-
13
-
14
- @dataclass(frozen=True)
15
- class ToolInvocation:
16
- run_id: str
17
- tool_call_id: str
18
- tool_key: str
19
- arguments: dict[str, JsonValue]
20
- execution_grant: str
21
-
22
-
23
- class ToolHostClient:
24
- def __init__(
25
- self,
26
- internal_token: str,
27
- *,
28
- transport: httpx.AsyncBaseTransport | None = None,
29
- timeout_seconds: float = 15.0,
30
- max_response_bytes: int = 1024 * 1024,
31
- ) -> None:
32
- self._internal_token = internal_token
33
- self._transport = transport
34
- self._timeout_seconds = timeout_seconds
35
- self._max_response_bytes = max_response_bytes
36
-
37
- async def execute(
38
- self,
39
- base_url: str,
40
- invocation: ToolInvocation,
41
- ) -> JsonValue:
42
- endpoint = normalize_base_url(base_url)
43
- headers = {
44
- "authorization": f"Bearer {self._internal_token}",
45
- "content-type": "application/json",
46
- }
47
- try:
48
- async with httpx.AsyncClient(
49
- base_url=f"{endpoint}/",
50
- headers=headers,
51
- timeout=self._timeout_seconds,
52
- transport=self._transport,
53
- ) as client:
54
- response = await client.post(
55
- "api/internal/agent/tools/execute",
56
- json={
57
- "executionGrant": invocation.execution_grant,
58
- "runId": invocation.run_id,
59
- "toolCallId": invocation.tool_call_id,
60
- "toolKey": invocation.tool_key,
61
- "arguments": invocation.arguments,
62
- },
63
- )
64
- body = await response.aread()
65
- except httpx.HTTPError:
66
- raise denied("Agent Tool Host 暂不可用", retryable=True) from None
67
- if len(body) > self._max_response_bytes:
68
- raise denied("Agent Tool 响应超过安全上限")
69
- if response.status_code == 202:
70
- raise approval_pending(body)
71
- if response.status_code == 409:
72
- raise approval_resolved(body)
73
- if not response.is_success:
74
- raise denied("Agent Tool 执行被拒绝")
75
- try:
76
- value = json.loads(body)
77
- except json.JSONDecodeError:
78
- raise denied("Agent Tool 响应无效") from None
79
- if not isinstance(value, dict) or "value" not in value:
80
- raise denied("Agent Tool 响应无效")
81
- return value["value"] # type: ignore[no-any-return]
82
-
83
-
84
- def denied(message: str, *, retryable: bool = False) -> SafeEngineError:
85
- return SafeEngineError("TOOL_DENIED", message, retryable=retryable)
86
-
87
-
88
- def canonical_tool_call_id(
89
- run_id: str,
90
- tool_key: str,
91
- arguments: dict[str, JsonValue],
92
- ) -> str:
93
- encoded = json.dumps(
94
- {
95
- "runId": run_id,
96
- "toolKey": tool_key,
97
- "arguments": arguments,
98
- },
99
- ensure_ascii=False,
100
- separators=(",", ":"),
101
- sort_keys=True,
102
- ).encode()
103
- return f"tool_{hashlib.sha256(encoded).hexdigest()[:40]}"
104
-
105
-
106
- class ToolApprovalPending(Exception):
107
- def __init__(self, work_item_id: str) -> None:
108
- super().__init__("Agent Tool 等待人工审批")
109
- self.work_item_id = work_item_id
110
-
111
-
112
- class ToolApprovalResolved(Exception):
113
- def __init__(self, work_item_id: str, outcome: str) -> None:
114
- super().__init__("Agent Tool 审批未通过")
115
- self.work_item_id = work_item_id
116
- self.outcome = outcome
117
-
118
-
119
- def approval_pending(body: bytes) -> ToolApprovalPending:
120
- value = safe_object(body)
121
- if value.get("code") != "APPROVAL_REQUIRED" or not isinstance(
122
- value.get("workItemId"), str
123
- ):
124
- raise denied("Agent Tool 审批响应无效")
125
- work_item_id = value["workItemId"]
126
- if not isinstance(work_item_id, str):
127
- raise denied("Agent Tool 审批响应无效")
128
- return ToolApprovalPending(work_item_id)
129
-
130
-
131
- def approval_resolved(body: bytes) -> ToolApprovalResolved:
132
- value = safe_object(body)
133
- code = value.get("code")
134
- work_item_id = value.get("workItemId")
135
- outcomes = {
136
- "APPROVAL_REJECTED": "rejected",
137
- "APPROVAL_CANCELLED": "cancelled",
138
- "APPROVAL_TIMED_OUT": "timed-out",
139
- }
140
- if code not in outcomes or not isinstance(work_item_id, str):
141
- raise denied("Agent Tool 审批响应无效")
142
- return ToolApprovalResolved(work_item_id, outcomes[code])
143
-
144
-
145
- def safe_object(body: bytes) -> dict[str, JsonValue]:
146
- try:
147
- value = json.loads(body)
148
- except json.JSONDecodeError:
149
- raise denied("Agent Tool 审批响应无效") from None
150
- if not isinstance(value, dict):
151
- raise denied("Agent Tool 审批响应无效")
152
- return value