agent-hitch 0.2.16 → 0.2.17

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 (361) hide show
  1. package/README.md +7 -28
  2. package/README.zh-CN.md +6 -26
  3. package/dist/scripts/benchmark-dataset-verification.js +118 -0
  4. package/dist/scripts/benchmark-dataset-verification.js.map +1 -0
  5. package/dist/scripts/canary-external-endpoint.js +56 -0
  6. package/dist/scripts/canary-external-endpoint.js.map +1 -0
  7. package/dist/scripts/canary-native-training.js +8 -6
  8. package/dist/scripts/canary-native-training.js.map +1 -1
  9. package/dist/scripts/canary-remote-training.js +8 -6
  10. package/dist/scripts/canary-remote-training.js.map +1 -1
  11. package/dist/scripts/check-architecture.js +1 -1
  12. package/dist/scripts/check-architecture.js.map +1 -1
  13. package/dist/src/adapters/providers/codex.js +5 -2
  14. package/dist/src/adapters/providers/codex.js.map +1 -1
  15. package/dist/src/adapters/providers/model-call.js +1 -2
  16. package/dist/src/adapters/providers/model-call.js.map +1 -1
  17. package/dist/src/adapters/providers/training-tool.js +2 -0
  18. package/dist/src/adapters/providers/training-tool.js.map +1 -1
  19. package/dist/src/backends/harbor/artifact-pins.js +42 -0
  20. package/dist/src/backends/harbor/artifact-pins.js.map +1 -0
  21. package/dist/src/backends/harbor/backend.js +16 -8
  22. package/dist/src/backends/harbor/backend.js.map +1 -1
  23. package/dist/src/backends/harbor/bound-credential-helper.js +24 -0
  24. package/dist/src/backends/harbor/bound-credential-helper.js.map +1 -0
  25. package/dist/src/backends/harbor/credential-snapshot.js +71 -0
  26. package/dist/src/backends/harbor/credential-snapshot.js.map +1 -0
  27. package/dist/src/backends/harbor/environment-config.js +25 -2
  28. package/dist/src/backends/harbor/environment-config.js.map +1 -1
  29. package/dist/src/backends/harbor/environment-files.js +143 -0
  30. package/dist/src/backends/harbor/environment-files.js.map +1 -0
  31. package/dist/src/backends/harbor/evaluation-binding.js +160 -0
  32. package/dist/src/backends/harbor/evaluation-binding.js.map +1 -0
  33. package/dist/src/backends/harbor/host-credential-helper.js +5 -0
  34. package/dist/src/backends/harbor/host-credential-helper.js.map +1 -1
  35. package/dist/src/backends/harbor/index.js +2 -0
  36. package/dist/src/backends/harbor/index.js.map +1 -1
  37. package/dist/src/backends/harbor/model-proxy-config.js +3 -18
  38. package/dist/src/backends/harbor/model-proxy-config.js.map +1 -1
  39. package/dist/src/backends/harbor/portable-regrade.js +15 -3
  40. package/dist/src/backends/harbor/portable-regrade.js.map +1 -1
  41. package/dist/src/backends/harbor/python-runtime.js +71 -0
  42. package/dist/src/backends/harbor/python-runtime.js.map +1 -0
  43. package/dist/src/backends/harbor/tools.js +6 -4
  44. package/dist/src/backends/harbor/tools.js.map +1 -1
  45. package/dist/src/backends/index.js +3 -0
  46. package/dist/src/backends/index.js.map +1 -1
  47. package/dist/src/cli/arguments.js +30 -30
  48. package/dist/src/cli/arguments.js.map +1 -1
  49. package/dist/src/cli/commands/capabilities.js +7 -3
  50. package/dist/src/cli/commands/capabilities.js.map +1 -1
  51. package/dist/src/cli/commands/daemon.js +0 -17
  52. package/dist/src/cli/commands/daemon.js.map +1 -1
  53. package/dist/src/cli/commands/eval-binding.js +32 -0
  54. package/dist/src/cli/commands/eval-binding.js.map +1 -0
  55. package/dist/src/cli/commands/eval.js +21 -15
  56. package/dist/src/cli/commands/eval.js.map +1 -1
  57. package/dist/src/cli/commands/models.js +32 -45
  58. package/dist/src/cli/commands/models.js.map +1 -1
  59. package/dist/src/cli/commands/run.js +0 -35
  60. package/dist/src/cli/commands/run.js.map +1 -1
  61. package/dist/src/cli/main.js +0 -4
  62. package/dist/src/cli/main.js.map +1 -1
  63. package/dist/src/cli/output.js +5 -16
  64. package/dist/src/cli/output.js.map +1 -1
  65. package/dist/src/control-plane/eval-records.js +3 -1
  66. package/dist/src/control-plane/eval-records.js.map +1 -1
  67. package/dist/src/control-plane/eval-recovery.js +4 -1
  68. package/dist/src/control-plane/eval-recovery.js.map +1 -1
  69. package/dist/src/control-plane/eval-scheduler.js +16 -8
  70. package/dist/src/control-plane/eval-scheduler.js.map +1 -1
  71. package/dist/src/control-plane/index.js +0 -2
  72. package/dist/src/control-plane/index.js.map +1 -1
  73. package/dist/src/control-plane/model-capture-planning.js +3 -4
  74. package/dist/src/control-plane/model-capture-planning.js.map +1 -1
  75. package/dist/src/control-plane/remote-model-routes.js +4 -24
  76. package/dist/src/control-plane/remote-model-routes.js.map +1 -1
  77. package/dist/src/control-plane/remote-offer-contract.js +2 -2
  78. package/dist/src/control-plane/remote-offer-contract.js.map +1 -1
  79. package/dist/src/control-plane/remote-result-transport.js +7 -8
  80. package/dist/src/control-plane/remote-result-transport.js.map +1 -1
  81. package/dist/src/control-plane/remote-work-coordinator.js +2 -2
  82. package/dist/src/control-plane/remote-work-coordinator.js.map +1 -1
  83. package/dist/src/control-plane/remote-work-recovery.js +2 -2
  84. package/dist/src/control-plane/remote-work-recovery.js.map +1 -1
  85. package/dist/src/control-plane/remote-worker-protocol.js +1 -1
  86. package/dist/src/control-plane/remote-worker-protocol.js.map +1 -1
  87. package/dist/src/control-plane/remote-worker-runner.js +21 -6
  88. package/dist/src/control-plane/remote-worker-runner.js.map +1 -1
  89. package/dist/src/control-plane/remote-workers.js +2 -2
  90. package/dist/src/control-plane/remote-workers.js.map +1 -1
  91. package/dist/src/control-plane/rerun-recovery.js +1 -1
  92. package/dist/src/control-plane/rerun-recovery.js.map +1 -1
  93. package/dist/src/control-plane/rerun-scheduler.js +21 -14
  94. package/dist/src/control-plane/rerun-scheduler.js.map +1 -1
  95. package/dist/src/control-plane/rerun-source.js +5 -2
  96. package/dist/src/control-plane/rerun-source.js.map +1 -1
  97. package/dist/src/control-plane/rerun-submission.js +7 -5
  98. package/dist/src/control-plane/rerun-submission.js.map +1 -1
  99. package/dist/src/control-plane/synthetic-result.js +3 -2
  100. package/dist/src/control-plane/synthetic-result.js.map +1 -1
  101. package/dist/src/control-plane/worker-model-relay.js +1 -1
  102. package/dist/src/control-plane/worker-model-relay.js.map +1 -1
  103. package/dist/src/controller-runtime/hash.js +6 -0
  104. package/dist/src/controller-runtime/hash.js.map +1 -1
  105. package/dist/src/daemon/client.js +12 -35
  106. package/dist/src/daemon/client.js.map +1 -1
  107. package/dist/src/daemon/evaluation-binding.js +33 -0
  108. package/dist/src/daemon/evaluation-binding.js.map +1 -0
  109. package/dist/src/daemon/evaluation-submission.js +27 -0
  110. package/dist/src/daemon/evaluation-submission.js.map +1 -0
  111. package/dist/src/daemon/index.js +1 -0
  112. package/dist/src/daemon/index.js.map +1 -1
  113. package/dist/src/daemon/json-stream.js +98 -0
  114. package/dist/src/daemon/json-stream.js.map +1 -0
  115. package/dist/src/daemon/scheduler.js +1 -4
  116. package/dist/src/daemon/scheduler.js.map +1 -1
  117. package/dist/src/daemon/server.js +14 -54
  118. package/dist/src/daemon/server.js.map +1 -1
  119. package/dist/src/domain/endpoints.js +2 -0
  120. package/dist/src/domain/endpoints.js.map +1 -0
  121. package/dist/src/domain/evaluation-binding.js +5 -0
  122. package/dist/src/domain/evaluation-binding.js.map +1 -0
  123. package/dist/src/domain/index.js +2 -0
  124. package/dist/src/domain/index.js.map +1 -1
  125. package/dist/src/domain/runs.js.map +1 -1
  126. package/dist/src/evals/benchmark-adapter-manifest.js +95 -32
  127. package/dist/src/evals/benchmark-adapter-manifest.js.map +1 -1
  128. package/dist/src/evals/benchmark-verification.js +106 -0
  129. package/dist/src/evals/benchmark-verification.js.map +1 -0
  130. package/dist/src/evals/collect-only-rerun.js +3 -2
  131. package/dist/src/evals/collect-only-rerun.js.map +1 -1
  132. package/dist/src/evals/directory.js +9 -1
  133. package/dist/src/evals/directory.js.map +1 -1
  134. package/dist/src/evals/endpoint-attempts.js +112 -0
  135. package/dist/src/evals/endpoint-attempts.js.map +1 -0
  136. package/dist/src/evals/endpoint-usage.js +8 -0
  137. package/dist/src/evals/endpoint-usage.js.map +1 -0
  138. package/dist/src/evals/environment-binding.js +9 -0
  139. package/dist/src/evals/environment-binding.js.map +1 -0
  140. package/dist/src/evals/eval-artifact-planning.js +10 -1
  141. package/dist/src/evals/eval-artifact-planning.js.map +1 -1
  142. package/dist/src/evals/eval-finalization.js +2 -3
  143. package/dist/src/evals/eval-finalization.js.map +1 -1
  144. package/dist/src/evals/eval-logical-plan.js +2 -0
  145. package/dist/src/evals/eval-logical-plan.js.map +1 -1
  146. package/dist/src/evals/eval-result-builder.js +4 -0
  147. package/dist/src/evals/eval-result-builder.js.map +1 -1
  148. package/dist/src/evals/eval-state.js +22 -0
  149. package/dist/src/evals/eval-state.js.map +1 -0
  150. package/dist/src/evals/execution-plan.js +6 -2
  151. package/dist/src/evals/execution-plan.js.map +1 -1
  152. package/dist/src/evals/index.js +5 -1
  153. package/dist/src/evals/index.js.map +1 -1
  154. package/dist/src/evals/infrastructure-retry.js +2 -0
  155. package/dist/src/evals/infrastructure-retry.js.map +1 -1
  156. package/dist/src/evals/model-capture-runtime.js +9 -13
  157. package/dist/src/evals/model-capture-runtime.js.map +1 -1
  158. package/dist/src/evals/native-phase-evidence.js +8 -2
  159. package/dist/src/evals/native-phase-evidence.js.map +1 -1
  160. package/dist/src/evals/planned-execution.js +7 -2
  161. package/dist/src/evals/planned-execution.js.map +1 -1
  162. package/dist/src/evals/planned-progress-publisher.js +18 -5
  163. package/dist/src/evals/planned-progress-publisher.js.map +1 -1
  164. package/dist/src/evals/planned-retry-execution.js +1 -0
  165. package/dist/src/evals/planned-retry-execution.js.map +1 -1
  166. package/dist/src/evals/preparation-rerun.js +0 -1
  167. package/dist/src/evals/preparation-rerun.js.map +1 -1
  168. package/dist/src/evals/progress.js +92 -7
  169. package/dist/src/evals/progress.js.map +1 -1
  170. package/dist/src/evals/records.js +12 -2
  171. package/dist/src/evals/records.js.map +1 -1
  172. package/dist/src/evals/recovery.js +2 -0
  173. package/dist/src/evals/recovery.js.map +1 -1
  174. package/dist/src/evals/remote-rerun-execution.js +1 -3
  175. package/dist/src/evals/remote-rerun-execution.js.map +1 -1
  176. package/dist/src/evals/remote-verifier-rerun.js +1 -1
  177. package/dist/src/evals/remote-verifier-rerun.js.map +1 -1
  178. package/dist/src/evals/request.js +14 -45
  179. package/dist/src/evals/request.js.map +1 -1
  180. package/dist/src/evals/rerun-observation.js +31 -0
  181. package/dist/src/evals/rerun-observation.js.map +1 -0
  182. package/dist/src/evals/rerun.js +23 -28
  183. package/dist/src/evals/rerun.js.map +1 -1
  184. package/dist/src/evals/service.js +45 -42
  185. package/dist/src/evals/service.js.map +1 -1
  186. package/dist/src/evals/shared-runtime.js +125 -0
  187. package/dist/src/evals/shared-runtime.js.map +1 -0
  188. package/dist/src/evals/trial-import.js +10 -2
  189. package/dist/src/evals/trial-import.js.map +1 -1
  190. package/dist/src/evals/trial-publication-recovery.js +1 -1
  191. package/dist/src/evals/trial-publication-recovery.js.map +1 -1
  192. package/dist/src/evals/verifier-artifacts.js +1 -0
  193. package/dist/src/evals/verifier-artifacts.js.map +1 -1
  194. package/dist/src/evals/verifier-only-rerun.js +1 -1
  195. package/dist/src/evals/verifier-only-rerun.js.map +1 -1
  196. package/dist/src/evals/verifier-rerun-result.js +3 -2
  197. package/dist/src/evals/verifier-rerun-result.js.map +1 -1
  198. package/dist/src/evals/verifier-score-artifacts.js +9 -1
  199. package/dist/src/evals/verifier-score-artifacts.js.map +1 -1
  200. package/dist/src/foundation/config.js +0 -5
  201. package/dist/src/foundation/config.js.map +1 -1
  202. package/dist/src/inference/index.js +3 -22
  203. package/dist/src/inference/index.js.map +1 -1
  204. package/dist/src/inference/lock.js +44 -130
  205. package/dist/src/inference/lock.js.map +1 -1
  206. package/dist/src/model-access/endpoint-contract.js +127 -0
  207. package/dist/src/model-access/endpoint-contract.js.map +1 -0
  208. package/dist/src/model-access/endpoint-credentials.js +54 -0
  209. package/dist/src/model-access/endpoint-credentials.js.map +1 -0
  210. package/dist/src/model-access/endpoint-probe-stream.js +66 -0
  211. package/dist/src/model-access/endpoint-probe-stream.js.map +1 -0
  212. package/dist/src/model-access/endpoint-verification.js +76 -0
  213. package/dist/src/model-access/endpoint-verification.js.map +1 -0
  214. package/dist/src/model-access/endpoints.js +105 -0
  215. package/dist/src/model-access/endpoints.js.map +1 -0
  216. package/dist/src/model-access/index.js +5 -1
  217. package/dist/src/model-access/index.js.map +1 -1
  218. package/dist/src/model-access/proxy.js +57 -14
  219. package/dist/src/model-access/proxy.js.map +1 -1
  220. package/dist/src/model-access/remote-model.js +21 -29
  221. package/dist/src/model-access/remote-model.js.map +1 -1
  222. package/dist/src/model-access/usage.js +30 -0
  223. package/dist/src/model-access/usage.js.map +1 -0
  224. package/dist/src/runs/endpoint-runtime.js +40 -0
  225. package/dist/src/runs/endpoint-runtime.js.map +1 -0
  226. package/dist/src/runs/executor.js +28 -42
  227. package/dist/src/runs/executor.js.map +1 -1
  228. package/dist/src/runs/local-inference-environment.js +5 -53
  229. package/dist/src/runs/local-inference-environment.js.map +1 -1
  230. package/dist/src/runs/manifest.js +1 -0
  231. package/dist/src/runs/manifest.js.map +1 -1
  232. package/dist/src/runs/outcome.js +3 -10
  233. package/dist/src/runs/outcome.js.map +1 -1
  234. package/dist/src/runs/queued.js +3 -2
  235. package/dist/src/runs/queued.js.map +1 -1
  236. package/dist/src/runs/records.js +3 -0
  237. package/dist/src/runs/records.js.map +1 -1
  238. package/dist/src/runs/request.js +10 -38
  239. package/dist/src/runs/request.js.map +1 -1
  240. package/dist/src/workers/remote-harbor-work-spec.js +8 -10
  241. package/dist/src/workers/remote-harbor-work-spec.js.map +1 -1
  242. package/dist/src/workers/remote-harbor-worker.js +3 -0
  243. package/dist/src/workers/remote-harbor-worker.js.map +1 -1
  244. package/docs/evidence/eval-preparation-2026-10-09.json +393 -0
  245. package/docs/evidence/eval-preparation-2026-10-09.md +178 -0
  246. package/docs/local-model-inference-spec.zh-CN.md +4 -663
  247. package/docs/resource-storage.zh-CN.md +116 -0
  248. package/docs/schemas/endpoint-evaluation-attempt.schema.json +29 -0
  249. package/docs/schemas/eval-artifact-pin.schema.json +14 -0
  250. package/docs/schemas/eval-execution-plan.schema.json +486 -105
  251. package/docs/schemas/eval-progress.schema.json +1 -1
  252. package/docs/schemas/eval-request.schema.json +149 -18
  253. package/docs/schemas/eval-rerun-submission.schema.json +8 -1
  254. package/docs/schemas/eval-result.schema.json +310 -56
  255. package/docs/schemas/evaluation-binding.schema.json +15 -0
  256. package/docs/schemas/external-endpoint-binding.schema.json +153 -0
  257. package/docs/schemas/external-endpoint-config.schema.json +93 -0
  258. package/docs/schemas/inference-execution-evidence.schema.json +253 -3
  259. package/docs/schemas/inference-lock-v3.schema.json +6 -0
  260. package/docs/schemas/inference-lock.schema.json +842 -341
  261. package/docs/schemas/ordered-eval-control.schema.json +7 -1
  262. package/docs/schemas/ready-endpoint-binding.schema.json +201 -0
  263. package/docs/schemas/run-manifest.schema.json +6 -0
  264. package/docs/schemas/run-request.schema.json +122 -20
  265. package/examples/external-inference/.env.example +16 -0
  266. package/examples/external-inference/README.md +203 -0
  267. package/examples/external-inference/accept.mjs +297 -0
  268. package/examples/external-inference/compose.gateway.yaml +119 -0
  269. package/examples/external-inference/compose.single.yaml +64 -0
  270. package/examples/external-inference/compose.tp2.yaml +15 -0
  271. package/examples/external-inference/deployment.example.json +58 -0
  272. package/examples/external-inference/endpoint.chat-completions.example.json +13 -0
  273. package/examples/external-inference/endpoint.responses.example.json +13 -0
  274. package/integrations/harbor/hitch_build_inputs.py +213 -0
  275. package/integrations/harbor/hitch_build_process.py +126 -0
  276. package/integrations/harbor/hitch_compose_preparation.py +274 -0
  277. package/integrations/harbor/hitch_harbor_agent.py +25 -39
  278. package/integrations/harbor/hitch_harbor_environment.py +96 -3
  279. package/integrations/harbor/hitch_image_cache.py +357 -0
  280. package/integrations/harbor/hitch_python_runtime.py +303 -0
  281. package/integrations/harbor/hitch_shared_runtime.py +123 -0
  282. package/integrations/model-call/cli.js +11 -10
  283. package/integrations/training-tool/cli.js +5 -3
  284. package/node_modules/smol-toml/LICENSE +24 -0
  285. package/node_modules/smol-toml/README.md +418 -0
  286. package/node_modules/smol-toml/dist/date.d.ts +41 -0
  287. package/node_modules/smol-toml/dist/date.js +127 -0
  288. package/node_modules/smol-toml/dist/error.d.ts +38 -0
  289. package/node_modules/smol-toml/dist/error.js +63 -0
  290. package/node_modules/smol-toml/dist/extract.js +69 -0
  291. package/node_modules/smol-toml/dist/index.cjs +734 -0
  292. package/node_modules/smol-toml/dist/index.d.ts +43 -0
  293. package/node_modules/smol-toml/dist/index.js +33 -0
  294. package/node_modules/smol-toml/dist/parse.d.ts +36 -0
  295. package/node_modules/smol-toml/dist/parse.js +149 -0
  296. package/node_modules/smol-toml/dist/primitive.js +238 -0
  297. package/node_modules/smol-toml/dist/stringify.d.ts +31 -0
  298. package/node_modules/smol-toml/dist/stringify.js +181 -0
  299. package/node_modules/smol-toml/dist/struct.js +179 -0
  300. package/node_modules/smol-toml/dist/util.d.ts +38 -0
  301. package/node_modules/smol-toml/dist/util.js +89 -0
  302. package/node_modules/smol-toml/package.json +68 -0
  303. package/package.json +15 -4
  304. package/dist/src/cli/commands/local.js +0 -130
  305. package/dist/src/cli/commands/local.js.map +0 -1
  306. package/dist/src/cli/commands/model-node.js +0 -26
  307. package/dist/src/cli/commands/model-node.js.map +0 -1
  308. package/dist/src/control-plane/inference-manager.js +0 -357
  309. package/dist/src/control-plane/inference-manager.js.map +0 -1
  310. package/dist/src/control-plane/managed-gateway-receipt.js +0 -26
  311. package/dist/src/control-plane/managed-gateway-receipt.js.map +0 -1
  312. package/dist/src/control-plane/managed-service-recovery.js +0 -158
  313. package/dist/src/control-plane/managed-service-recovery.js.map +0 -1
  314. package/dist/src/daemon/inference-prepare.js +0 -47
  315. package/dist/src/daemon/inference-prepare.js.map +0 -1
  316. package/dist/src/inference/daemon-capacity.js +0 -41
  317. package/dist/src/inference/daemon-capacity.js.map +0 -1
  318. package/dist/src/inference/device-reservation.js +0 -58
  319. package/dist/src/inference/device-reservation.js.map +0 -1
  320. package/dist/src/inference/doctor.js +0 -95
  321. package/dist/src/inference/doctor.js.map +0 -1
  322. package/dist/src/inference/generation-recovery.js +0 -83
  323. package/dist/src/inference/generation-recovery.js.map +0 -1
  324. package/dist/src/inference/managed-launcher.js +0 -35
  325. package/dist/src/inference/managed-launcher.js.map +0 -1
  326. package/dist/src/inference/materialize.js +0 -66
  327. package/dist/src/inference/materialize.js.map +0 -1
  328. package/dist/src/inference/model-location.js +0 -34
  329. package/dist/src/inference/model-location.js.map +0 -1
  330. package/dist/src/inference/node-client.js +0 -167
  331. package/dist/src/inference/node-client.js.map +0 -1
  332. package/dist/src/inference/node-registry.js +0 -79
  333. package/dist/src/inference/node-registry.js.map +0 -1
  334. package/dist/src/inference/observation.js +0 -79
  335. package/dist/src/inference/observation.js.map +0 -1
  336. package/dist/src/inference/preflight.js +0 -132
  337. package/dist/src/inference/preflight.js.map +0 -1
  338. package/dist/src/inference/process-sglang.js +0 -169
  339. package/dist/src/inference/process-sglang.js.map +0 -1
  340. package/dist/src/inference/protocol-probe.js +0 -29
  341. package/dist/src/inference/protocol-probe.js.map +0 -1
  342. package/dist/src/inference/remote-model-store.js +0 -24
  343. package/dist/src/inference/remote-model-store.js.map +0 -1
  344. package/dist/src/inference/runtime-catalog.js +0 -41
  345. package/dist/src/inference/runtime-catalog.js.map +0 -1
  346. package/dist/src/inference/runtime-store.js +0 -93
  347. package/dist/src/inference/runtime-store.js.map +0 -1
  348. package/dist/src/inference/service-attachment.js +0 -46
  349. package/dist/src/inference/service-attachment.js.map +0 -1
  350. package/dist/src/inference/service-inspection.js +0 -38
  351. package/dist/src/inference/service-inspection.js.map +0 -1
  352. package/dist/src/inference/sglang.js +0 -279
  353. package/dist/src/inference/sglang.js.map +0 -1
  354. package/dist/src/inference/supervisor.js +0 -460
  355. package/dist/src/inference/supervisor.js.map +0 -1
  356. package/dist/src/model-access/local-gateway-request.js +0 -139
  357. package/dist/src/model-access/local-gateway-request.js.map +0 -1
  358. package/dist/src/model-access/local-gateway.js +0 -323
  359. package/dist/src/model-access/local-gateway.js.map +0 -1
  360. package/dist/src/runs/local-inference-run.js +0 -53
  361. package/dist/src/runs/local-inference-run.js.map +0 -1
@@ -22,9 +22,15 @@
22
22
  "rerun_id": { "type": "string", "pattern": "^rerun_[a-f0-9]{32}$" },
23
23
  "rerun_type": { "$ref": "eval-rerun-submission.schema.json#/$defs/rerunType" },
24
24
  "selector": { "$ref": "eval-rerun-submission.schema.json#/$defs/selector" },
25
+ "endpoint_attempt": { "$ref": "endpoint-evaluation-attempt.schema.json" },
25
26
  "verifier_runtime_id": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }
26
27
  },
27
- "allOf": [{ "if": { "required": ["verifier_runtime_id"] }, "then": { "properties": { "rerun_type": { "const": "verifier-only" } } } }]
28
+ "allOf": [
29
+ { "if": { "required": ["verifier_runtime_id"] }, "then": { "properties": { "rerun_type": { "const": "verifier-only" } } } },
30
+ { "if": { "required": ["endpoint_attempt"] }, "then": { "properties": { "rerun_type": { "const": "candidate-restart" },
31
+ "selector": { "type": "object", "additionalProperties": false, "required": ["mode"], "properties": { "mode": { "const": "invalid" } } }
32
+ } } }
33
+ ]
28
34
  }
29
35
  }
30
36
  }
@@ -0,0 +1,201 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agent-hitch.local/schemas/ready-endpoint-binding.schema.json",
4
+ "title": "Private ready endpoint binding input",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schema_version",
9
+ "kind",
10
+ "endpoint_ref",
11
+ "endpoint_revision",
12
+ "api",
13
+ "wire_model",
14
+ "capabilities",
15
+ "generation",
16
+ "connection"
17
+ ],
18
+ "properties": {
19
+ "schema_version": {
20
+ "const": "1"
21
+ },
22
+ "kind": {
23
+ "const": "external-endpoint"
24
+ },
25
+ "endpoint_ref": {
26
+ "type": "string",
27
+ "pattern": "^endpoint/[a-z0-9][a-z0-9._-]{0,63}(@sha256:[a-f0-9]{64})?$"
28
+ },
29
+ "endpoint_revision": {
30
+ "type": "string",
31
+ "pattern": "^sha256:[a-f0-9]{64}$"
32
+ },
33
+ "api": {
34
+ "enum": [
35
+ "responses",
36
+ "chat-completions"
37
+ ]
38
+ },
39
+ "wire_model": {
40
+ "type": "string",
41
+ "minLength": 1
42
+ },
43
+ "capabilities": {
44
+ "type": "object",
45
+ "additionalProperties": false,
46
+ "required": [
47
+ "streaming",
48
+ "tool_calls",
49
+ "parallel_tool_calls",
50
+ "input_modalities"
51
+ ],
52
+ "properties": {
53
+ "streaming": {
54
+ "type": "boolean"
55
+ },
56
+ "tool_calls": {
57
+ "type": "boolean"
58
+ },
59
+ "parallel_tool_calls": {
60
+ "const": false
61
+ },
62
+ "input_modalities": {
63
+ "const": [
64
+ "text"
65
+ ]
66
+ }
67
+ }
68
+ },
69
+ "generation": {
70
+ "type": "object",
71
+ "additionalProperties": false,
72
+ "properties": {
73
+ "max_output_tokens": {
74
+ "type": "integer",
75
+ "minimum": 1
76
+ },
77
+ "temperature": {
78
+ "type": "number"
79
+ },
80
+ "top_p": {
81
+ "type": "number"
82
+ },
83
+ "top_k": {
84
+ "type": "number"
85
+ },
86
+ "min_p": {
87
+ "type": "number"
88
+ },
89
+ "repetition_penalty": {
90
+ "type": "number"
91
+ },
92
+ "seed": {
93
+ "type": "number"
94
+ }
95
+ }
96
+ },
97
+ "deployment_receipt": {
98
+ "type": "object",
99
+ "additionalProperties": false,
100
+ "required": [
101
+ "schema_version",
102
+ "model_digest",
103
+ "wire_model",
104
+ "deployment_ref",
105
+ "source",
106
+ "service_config"
107
+ ],
108
+ "properties": {
109
+ "schema_version": {
110
+ "const": "1"
111
+ },
112
+ "model_digest": {
113
+ "type": "string",
114
+ "pattern": "^sha256:[a-f0-9]{64}$"
115
+ },
116
+ "wire_model": {
117
+ "type": "string",
118
+ "minLength": 1
119
+ },
120
+ "deployment_ref": {
121
+ "type": "string",
122
+ "minLength": 1
123
+ },
124
+ "source": {
125
+ "type": "string",
126
+ "minLength": 1
127
+ },
128
+ "service_config": {
129
+ "type": "object",
130
+ "additionalProperties": false,
131
+ "required": [
132
+ "engine"
133
+ ],
134
+ "properties": {
135
+ "engine": {
136
+ "type": "string",
137
+ "minLength": 1
138
+ },
139
+ "engine_version": {},
140
+ "engine_digest": {},
141
+ "quantization": {},
142
+ "tool_parser": {},
143
+ "reasoning_parser": {},
144
+ "tokenizer_digest": {},
145
+ "chat_template_digest": {},
146
+ "cache_policy": {},
147
+ "isolation": {},
148
+ "parsing": {}
149
+ }
150
+ }
151
+ }
152
+ },
153
+ "connection": {
154
+ "type": "object",
155
+ "additionalProperties": false,
156
+ "required": [
157
+ "base_url",
158
+ "auth"
159
+ ],
160
+ "properties": {
161
+ "base_url": {
162
+ "type": "string",
163
+ "pattern": "^https?://"
164
+ },
165
+ "auth": {
166
+ "oneOf": [
167
+ {
168
+ "type": "object",
169
+ "additionalProperties": false,
170
+ "required": [
171
+ "kind"
172
+ ],
173
+ "properties": {
174
+ "kind": {
175
+ "const": "none"
176
+ }
177
+ }
178
+ },
179
+ {
180
+ "type": "object",
181
+ "additionalProperties": false,
182
+ "required": [
183
+ "kind",
184
+ "name"
185
+ ],
186
+ "properties": {
187
+ "kind": {
188
+ "const": "env"
189
+ },
190
+ "name": {
191
+ "type": "string",
192
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
193
+ }
194
+ }
195
+ }
196
+ ]
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
@@ -161,6 +161,9 @@
161
161
  "inference_id": {
162
162
  "type": "string",
163
163
  "pattern": "^sha256:[a-f0-9]{64}$"
164
+ },
165
+ "endpoint_binding": {
166
+ "$ref": "external-endpoint-binding.schema.json"
164
167
  }
165
168
  }
166
169
  },
@@ -238,6 +241,9 @@
238
241
  "completed_at": {
239
242
  "type": "string",
240
243
  "format": "date-time"
244
+ },
245
+ "endpoint_binding": {
246
+ "$ref": "external-endpoint-binding.schema.json"
241
247
  }
242
248
  },
243
249
  "$defs": {
@@ -4,19 +4,60 @@
4
4
  "title": "Hitch run request",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": ["prompt"],
8
- "allOf": [{
9
- "if": { "properties": { "context": { "properties": { "kind": { "const": "benchmark_phase" } }, "required": ["kind"] } }, "required": ["context"] },
10
- "then": { "required": ["parent"], "properties": { "defer_benchmark_observation": { "const": false } } }
11
- }],
7
+ "required": [
8
+ "prompt"
9
+ ],
10
+ "allOf": [
11
+ {
12
+ "if": {
13
+ "properties": {
14
+ "context": {
15
+ "properties": {
16
+ "kind": {
17
+ "const": "benchmark_phase"
18
+ }
19
+ },
20
+ "required": [
21
+ "kind"
22
+ ]
23
+ }
24
+ },
25
+ "required": [
26
+ "context"
27
+ ]
28
+ },
29
+ "then": {
30
+ "required": [
31
+ "parent"
32
+ ],
33
+ "properties": {
34
+ "defer_benchmark_observation": {
35
+ "const": false
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ],
12
41
  "oneOf": [
13
42
  {
14
- "required": ["harness_ref"],
15
- "not": { "required": ["agent"] }
43
+ "required": [
44
+ "harness_ref"
45
+ ],
46
+ "not": {
47
+ "required": [
48
+ "agent"
49
+ ]
50
+ }
16
51
  },
17
52
  {
18
- "required": ["agent"],
19
- "not": { "required": ["harness_ref"] }
53
+ "required": [
54
+ "agent"
55
+ ],
56
+ "not": {
57
+ "required": [
58
+ "harness_ref"
59
+ ]
60
+ }
20
61
  }
21
62
  ],
22
63
  "properties": {
@@ -39,7 +80,11 @@
39
80
  "minLength": 1
40
81
  },
41
82
  "workspace_mode": {
42
- "enum": ["shared", "worktree", "copy"],
83
+ "enum": [
84
+ "shared",
85
+ "worktree",
86
+ "copy"
87
+ ],
43
88
  "default": "shared"
44
89
  },
45
90
  "prompt": {
@@ -56,21 +101,78 @@
56
101
  "type": "string"
57
102
  }
58
103
  },
59
- "context": { "$ref": "run-context.schema.json" },
104
+ "context": {
105
+ "$ref": "run-context.schema.json"
106
+ },
60
107
  "parent": {
61
108
  "type": "object",
62
109
  "additionalProperties": false,
63
- "required": ["kind", "eval_id", "trial_id", "attempt"],
110
+ "required": [
111
+ "kind",
112
+ "eval_id",
113
+ "trial_id",
114
+ "attempt"
115
+ ],
64
116
  "properties": {
65
- "kind": { "const": "eval" },
66
- "eval_id": { "type": "string", "pattern": "^eval_[a-f0-9]{32}$" },
67
- "trial_id": { "type": "string", "minLength": 1 },
68
- "attempt": { "type": "integer", "minimum": 1 }
117
+ "kind": {
118
+ "const": "eval"
119
+ },
120
+ "eval_id": {
121
+ "type": "string",
122
+ "pattern": "^eval_[a-f0-9]{32}$"
123
+ },
124
+ "trial_id": {
125
+ "type": "string",
126
+ "minLength": 1
127
+ },
128
+ "attempt": {
129
+ "type": "integer",
130
+ "minimum": 1
131
+ }
69
132
  }
70
133
  },
71
- "model_identity": { "type": "object" },
72
- "protocol_identity": { "type": "object" },
73
- "defer_benchmark_observation": { "type": "boolean" },
74
- "local_inference": { "$ref": "local-inference-selection.schema.json" }
134
+ "model_identity": {
135
+ "type": "object"
136
+ },
137
+ "protocol_identity": {
138
+ "type": "object"
139
+ },
140
+ "defer_benchmark_observation": {
141
+ "type": "boolean"
142
+ },
143
+ "endpoint_binding": {
144
+ "$ref": "external-endpoint-binding.schema.json"
145
+ },
146
+ "model_binding": {
147
+ "$ref": "ready-endpoint-binding.schema.json"
148
+ },
149
+ "generation": {
150
+ "type": "object",
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "max_output_tokens": {
154
+ "type": "integer",
155
+ "minimum": 1
156
+ },
157
+ "temperature": {
158
+ "type": "number"
159
+ },
160
+ "top_p": {
161
+ "type": "number"
162
+ },
163
+ "top_k": {
164
+ "type": "number"
165
+ },
166
+ "min_p": {
167
+ "type": "number"
168
+ },
169
+ "repetition_penalty": {
170
+ "type": "number"
171
+ },
172
+ "seed": {
173
+ "type": "number"
174
+ }
175
+ }
176
+ }
75
177
  }
76
178
  }
@@ -0,0 +1,16 @@
1
+ # Copy to .env, then replace host paths and GPU UUIDs. Never put a key here.
2
+ SGLANG_IMAGE=lmsysorg/sglang:v0.5.21
3
+ # Official gateway-only release, independently pinned from the workers.
4
+ GATEWAY_IMAGE=lightseekorg/smg:1.12.0@sha256:d08b509491f222c2c9786323a3df90136127364c25b9b9b48e91b4b3e9e695d6
5
+ HF_SNAPSHOT_DIR=/srv/models/Qwen2.5-7B-Instruct/a09a35458c702b33eeacc393d103063234e8bc28
6
+ WIRE_MODEL=qwen25-7b-a09a35458c70
7
+ INFERENCE_API_KEY_FILE=/srv/secrets/hitch-inference-api-key
8
+ INFERENCE_GPU_0=GPU-REPLACE-WITH-FIRST-INFERENCE-UUID
9
+ INFERENCE_GPU_1=GPU-REPLACE-WITH-SECOND-INFERENCE-UUID
10
+ INFERENCE_PORT=30000
11
+ CONTEXT_LENGTH=16384
12
+ MEM_FRACTION_STATIC=0.82
13
+ ENGINE_MAX_RUNNING=4
14
+ ENGINE_MAX_QUEUED=8
15
+ GATEWAY_MAX_CONCURRENT=8
16
+ GATEWAY_QUEUE_SIZE=16
@@ -0,0 +1,203 @@
1
+ # External SGLang endpoints
2
+
3
+ These examples deploy an upstream model API independently of Hitch runs and Gear evaluations. Docker Compose owns service restart and device access; SGLang owns generation; upstream SMG owns replica routing. `accept.mjs` is a one-shot HTTP acceptance tool, not a service or model manager.
4
+
5
+ The configured workers use **SGLang v0.5.21**, release commit `e00930c5489053f26d86b179cee0d087f846acbb`, from `lmsysorg/sglang:v0.5.21`. The two-replica topology uses the separately released **Shepherd Model Gateway (SMG) 1.12.0**, source commit `dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef`, from the official gateway-only image `lightseekorg/smg:1.12.0`. `GATEWAY_IMAGE` pins its multi-architecture digest independently of `SGLANG_IMAGE`. SMG continues the Gateway codebase in its own repository; its upstream Python package rename from `sglang_router` to `smg` is recorded in [merged PR #69](https://github.com/smg-project/smg/pull/69).
6
+
7
+ The example model is **Qwen/Qwen2.5-7B-Instruct**, HF revision `a09a35458c702b33eeacc393d103063234e8bc28`, with the `qwen25` tool parser. Pin the pulled worker image digest in `.env` before recording a reproducible deployment.
8
+
9
+ A bounded GPU smoke on 2026-10-15 passed the checks below. It ran SMG from an official **1.12.0 wheel in a separate virtual environment**, connected to SGLang 0.5.21 workers. The SMG container image was **not started**; wheel results do not validate the Compose/container path. See the [hardware validation record](../../docs/validation/external-inference-gpu-2026-10-15.md) for exact observed configuration and evidence limits.
10
+
11
+ | Validation | Current status |
12
+ | --- | --- |
13
+ | Compose parsing: single TP=1, single TP=2, two TP=1 replicas | Checked locally; no containers started |
14
+ | Probe syntax and controlled standard HTTP protocol exercise | Checked locally; 15 usage fixture cases passed |
15
+ | Standalone TP=1 direct endpoint | A later Qwen3.5-2B / SGLang 0.5.15.post1 training diagnostic passed strict Hitch verification and real Harbor baseline/candidate evaluations, both valid with reward 0; this is a different model/runtime from the 7B Compose example |
16
+ | Real SGLang TP=2 | Responses and Chat Completions each passed all 9 HTTP checks |
17
+ | SMG 1.12.0 wheel + two TP=1 SGLang workers | Both APIs passed all 9 checks, including forced named JSON/SSE tools, worker distribution and cancellation isolation |
18
+ | Actual Codex 0.145 Harness | TP=2 SHA-256 task and SMG arithmetic task passed with actual terminal tool roundtrips |
19
+ | Legacy bundled `sglang-router` 0.3.2 + two TP=1 workers | Chat Completions passed; Responses rejected the flat named function `tool_choice` with HTTP 400 before reaching a worker |
20
+ | Official SMG 1.12.0 image and Compose container deployment | **NOT RUN; image metadata/source and Compose parsing checked only** |
21
+ | Harbor container execution path | One real local Harbor/Docker canary with remote GPU generation completed training feedback and baseline/candidate evaluation; a complete benchmark and remote Harbor workers remain **NOT RUN** |
22
+ | Static training/inference split, training rollout and HF export regression | A later 2×3090 diagnostic completed one real Slime update/native checkpoint/HF export on GPU 0 and ordinary endpoint evaluation on GPU 1; the shared service survived training cleanup and evidence pairing passed with meanDelta 0. Explicitly validated:false / pending-gpu, zero loss/gradient; complete local artifact closure (108 objects, 35,467,670,234 bytes), offline finite verification and exact-instance rental destruction passed |
23
+
24
+ The later [training and endpoint diagnostic](../../docs/validation/training-gpu-loop-2026-10-15.md) used the pinned Slime image and Qwen3.5-2B with SGLang 0.5.15.post1, not these Qwen2.5-7B / SGLang 0.5.21 Compose commands. Its one-task results establish a bounded pipeline exercise, not learning, formal runtime certification or container acceptance. Historical custom inference-pool records cannot substitute for these checks. A successful HTTP probe does not establish GPU topology, trusted weight identity, or actual Harness behavior.
25
+
26
+ ## Host and device requirements
27
+
28
+ Use a Linux NVIDIA GPU host with Docker Engine, NVIDIA Container Toolkit, a driver compatible with the SGLang CUDA 13 worker image, and Docker Compose **2.24.4 or later** (`!override` is used by the TP=2 override). The HTTP probe needs Node.js **22 or later**, with no npm packages or Python runtime on the Hitch client.
29
+
30
+ For this unquantized 7B BF16 example, plan for an Ampere-or-newer NVIDIA GPU with at least 24 GiB for each TP=1 replica. This is a conservative starting target, not measured capacity: model, kernels, context, batching and KV-cache allocation must fit the chosen hardware. TP=2 needs two suitable GPUs on one host with working NCCL communication. The recorded two-RTX-3090 smoke completed through NCCL after custom allreduce fell back because peer access was unavailable; it establishes successful execution, not a performance target. Validate the interconnect and actual rank execution; two device IDs in a file are not proof of TP execution. The default context is 16384 with memory fraction 0.82, per-worker running/queued request limits are 4/8, and the Gateway running/queued limits are 8/16 with a 30-second queue deadline. The worker commands include the upstream `--disable-cuda-graph` flag used in this smoke (deprecated but accepted by SGLang 0.5.21). These settings accommodate the recorded Codex input of about 10.6k tokens per request; they do not establish capacity for every model or workload. Adjust them to the measured deployment capacity and record the change.
31
+
32
+ Reserve distinct physical GPU UUIDs for inference and training in the resource owner's allocation system. For example, on a three-GPU host reserve GPU A/B for the two-replica endpoint and GPU C for training. Constrain the trainer to C and the Compose workers to A/B. One inference GPU plus one training GPU needs at least two GPUs; TP=2 or two replicas plus a one-GPU trainer needs at least three. These Compose device selections restrict visibility; they do not exclude other jobs or create a global allocation ledger. Dynamic sharing is outside this example.
33
+
34
+ ## Prepare the immutable snapshot and secret
35
+
36
+ Run these steps as the deployment owner in this directory, on the GPU host. Edit all paths and UUIDs for that host:
37
+
38
+ ```sh
39
+ cp .env.example .env
40
+ # Edit .env: absolute snapshot/secret paths, reserved GPU UUIDs, worker image digest.
41
+ set -a
42
+ . ./.env
43
+ set +a
44
+
45
+ install -d -m 700 ./secrets
46
+ (umask 077; openssl rand -hex 32 > ./secrets/api-key)
47
+ # Set INFERENCE_API_KEY_FILE in .env to this file's absolute path.
48
+ ```
49
+
50
+ The same secret protects Gateway and workers in the two-replica example. Compose mounts the file as `/run/secrets/api_key`; a small shell entrypoint reads it and execs the upstream launcher. The official SMG image defaults to UID 65532; this example explicitly runs the Gateway as `0:0` so it can read the existing host-owned `0600` secret without relaxing that file's permissions. Keep the host secret directory private. The released SMG image removes `curl`, so its readiness healthcheck uses the included Python standard library. The secret is absent from endpoint JSON and `.env`. Upstream `--api-key` arguments are visible to privileged process inspectors on the deployment host; use a trusted host and keep its diagnostics private. Never put a real key in a public task, receipt, or report.
51
+
52
+ Use the existing CAS/HF export flow for a candidate. It must produce a complete, immutable snapshot containing weights, config, tokenizer and template. For the public demonstration model, the fixed image can prepare a snapshot without GPU access:
53
+
54
+ ```sh
55
+ # Reload .env after editing its paths.
56
+ set -a
57
+ . ./.env
58
+ set +a
59
+ mkdir -p "$HF_SNAPSHOT_DIR"
60
+ docker pull "$SGLANG_IMAGE"
61
+ docker run --rm --entrypoint hf \
62
+ --mount "type=bind,src=$HF_SNAPSHOT_DIR,dst=/model" \
63
+ "$SGLANG_IMAGE" download Qwen/Qwen2.5-7B-Instruct \
64
+ --revision a09a35458c702b33eeacc393d103063234e8bc28 --local-dir /model
65
+
66
+ docker image inspect --format '{{index .RepoDigests 0}}' "$SGLANG_IMAGE"
67
+ # Replace SGLANG_IMAGE in .env with that returned lmsysorg/sglang@sha256:... value.
68
+ ```
69
+
70
+ Download only into a new snapshot directory. Do not point at a mutable `main` checkout or a cache snapshot whose symlinks target files outside the mount. The deployment owner must verify the complete files against the existing model manifest/CAS digest, prevent host-side mutation, and preserve the digest and receipt source. Every worker mounts exactly that directory read-only and runs with Hub/Transformers offline mode. The container mount alone does not prove host immutability or which weights were loaded.
71
+
72
+ Use a distinct `WIRE_MODEL` for each candidate version, and use the same value in endpoint JSON and the trusted deployment receipt. Do not replace the mounted weights behind an already-frozen model name. All replicas behind one Gateway in this example must serve the same snapshot and parser/template configuration.
73
+
74
+ ## Launch one topology
75
+
76
+ Reload `.env` after every edit, including the resolved image digest; exported shell values take precedence over `--env-file`:
77
+
78
+ ```sh
79
+ set -a
80
+ . ./.env
81
+ set +a
82
+ ```
83
+
84
+ For one TP=1 replica:
85
+
86
+ ```sh
87
+ docker compose --env-file .env -f compose.single.yaml config --quiet
88
+ docker compose --env-file .env -f compose.single.yaml up -d --wait --wait-timeout 1800
89
+ ```
90
+
91
+ For one TP=2 replica, select two distinct reserved UUIDs in `.env`:
92
+
93
+ ```sh
94
+ docker compose --env-file .env -f compose.single.yaml -f compose.tp2.yaml config --quiet
95
+ docker compose --env-file .env -f compose.single.yaml -f compose.tp2.yaml up -d --wait --wait-timeout 1800
96
+ ```
97
+
98
+ For two TP=1 replicas behind SMG 1.12.0:
99
+
100
+ ```sh
101
+ docker pull "$GATEWAY_IMAGE"
102
+ docker compose --env-file .env -f compose.gateway.yaml config --quiet
103
+ docker compose --env-file .env -f compose.gateway.yaml up -d --wait --wait-timeout 1800
104
+ ```
105
+
106
+ The Gateway image is pinned to `sha256:d08b509491f222c2c9786323a3df90136127364c25b9b9b48e91b4b3e9e695d6` (multi-architecture manifest; Linux amd64 child `sha256:a4041ccb14eed4316aabcba6d8b1ef511c6de49e56c27d90749552496f15f97f`). Its shell command runs `smg launch`; `SGLANG_IMAGE` is used only by the workers. No inference engine or GPU is needed in the Gateway container. `--disable-tokenizer-autoload` keeps this pure HTTP router from trying to load worker tokenizer paths; workers alone load the tokenizer from their immutable snapshot mount.
107
+
108
+ Choose one topology at a time. These files share a Compose project and public port; changing topology is a deployment-owner operation after existing consumers finish. Gateway explicitly uses `--disable-retries`; the probe uses builtin `fetch` without retries. Disable transparent retries/fallback in the selected Harness or SDK as well for strict evaluation. Docker restarting a service is a deployment policy, not request replay.
109
+
110
+ The Gateway explicitly has no visible NVIDIA/CUDA devices. Only loopback ports are published: API 30000, two-replica worker diagnostics 30001/30002, Gateway Prometheus 10001. Remote workers and Harbor containers need a genuinely reachable URL; container `127.0.0.1` is not the GPU host. Use the environment's existing private networking/TLS ingress or an operator-managed tunnel, then edit `base_url`. Do not publish these example HTTP ports to an untrusted network.
111
+
112
+ ## Connect Hitch and exercise the actual Harness
113
+
114
+ `endpoint.responses.example.json` and `endpoint.chat-completions.example.json` explicitly select one API. Their capability declarations are proposed settings until the selected protocol and Harness have passed real requests. This Hitch release accepts serial function tool calls only: both examples declare `parallel_tool_calls: false`, and a declaration of `true` is rejected. Choose the API required by that Harness; there is no protocol autodetection or conversion.
115
+
116
+ ```sh
117
+ cp endpoint.responses.example.json endpoint.json
118
+ # Update base_url and wire_model to the deployed values.
119
+ export INFERENCE_API_KEY="$(cat ./secrets/api-key)"
120
+ hitch models connect --name coder --file endpoint.json
121
+ hitch models inspect endpoint/coder --verify --json
122
+ hitch run --harness "$HARNESS" --model endpoint/coder \
123
+ --prompt "Use the available shell tool to compute the SHA-256 of README.md and report the result." \
124
+ --output json
125
+ ```
126
+
127
+ Set `HARNESS` to a concrete supported Harness ref with the required tool and workspace available. Save its version, provider/adapter configuration, full tool roundtrip, result and usage. Its actual upstream HTTP budget must be a normal business value (for example 1024 or 4096) and must pass unchanged. No `+2` compensation or tiny-budget test is part of these examples. Run the actual container/remote execution path if that is what the evaluation uses, with its credential available in the process that sends upstream requests.
128
+
129
+ Hitch freezes the registered endpoint revision for a task. Gear strict candidate evaluation additionally requires its trusted ready-binding/receipt contract and the matching existing model artifact digest. `deployment.example.json` is public operator metadata for this probe, **not** a signed or trusted receipt and **not** a Gear ready-binding file. Copy the actual deployment pipeline receipt into the Gear binding workflow; a model-name echo or a self-filled digest is insufficient.
130
+
131
+ ## Capture configuration and run the HTTP acceptance tool
132
+
133
+ Prepare a private evidence directory and copy the metadata template:
134
+
135
+ ```sh
136
+ mkdir -p artifacts
137
+ cp deployment.example.json deployment.json
138
+ docker compose --env-file .env -f compose.single.yaml config > artifacts/compose.resolved.yaml
139
+ docker compose --env-file .env -f compose.single.yaml exec -T engine \
140
+ python3 -c 'import importlib.metadata as m,json; print(json.dumps({k:m.version(k) for k in ("sglang",)},sort_keys=True))' \
141
+ > artifacts/package-versions.json
142
+ nvidia-smi --query-gpu=uuid,name,driver_version,memory.total --format=csv > artifacts/gpus.csv
143
+ ```
144
+
145
+ For TP=2 use both Compose files in the capture commands. For Gateway use `compose.gateway.yaml` and capture both worker packages and the separate SMG package:
146
+
147
+ ```sh
148
+ docker compose --env-file .env -f compose.gateway.yaml config > artifacts/compose.resolved.yaml
149
+ for worker in worker-1 worker-2; do
150
+ docker compose --env-file .env -f compose.gateway.yaml exec -T "$worker" \
151
+ python3 -c 'import importlib.metadata as m,json; print(json.dumps({"sglang":m.version("sglang")}))' \
152
+ > "artifacts/$worker-package-versions.json"
153
+ done
154
+ docker compose --env-file .env -f compose.gateway.yaml exec -T gateway \
155
+ python3 -c 'import importlib.metadata as m,json; print(json.dumps({"smg":m.version("smg")}))' \
156
+ > artifacts/gateway-package-versions.json
157
+ ```
158
+
159
+ The metadata template defaults to a single replica with `gateway.enabled: false`. For the two-replica topology set it to `true`, update the Compose files/replica count and `configuration.gateway` settings, and fill both engine and Gateway observed versions and resolved image digests. Record exact topology, UUIDs, allocation/receipt references, model/tokenizer/template digest, parser, quantization, cache/isolation policy and any changed capacity settings. Keep the configured and observed versions distinct. Preserve the original trusted receipt alongside the public metadata. Do not copy a process listing containing API-key arguments into public evidence.
160
+
161
+ Single-replica acceptance (run separately for TP=1 and TP=2):
162
+
163
+ ```sh
164
+ node accept.mjs --endpoint endpoint.json --deployment deployment.json \
165
+ --budget 1024 --concurrent 4 --worker-metrics http://127.0.0.1:30000/metrics \
166
+ --expect-workers 1 --out artifacts/single-responses.json
167
+ ```
168
+
169
+ Two-replica acceptance through the Gateway:
170
+
171
+ ```sh
172
+ node accept.mjs --endpoint endpoint.json --deployment deployment.json \
173
+ --budget 1024 --concurrent 4 \
174
+ --worker-metrics http://127.0.0.1:30001/metrics \
175
+ --worker-metrics http://127.0.0.1:30002/metrics \
176
+ --gateway-metrics http://127.0.0.1:10001/metrics --expect-workers 2 \
177
+ --out artifacts/gateway-responses.json
178
+ ```
179
+
180
+ Use `endpoint.chat-completions.example.json` and a different output filename when validating that API. A passing result for one API does not declare the other supported. The report records each exact request, HTTP status, generated text/SSE events, raw upstream usage and verified counts with their source field names, tool input/output, local probe version/hash and supplied deployment configuration. Known API keys are redacted; keep reports private because they contain prompts and model output. A failing probe exits nonzero and still saves the observations it obtained.
181
+
182
+ The checks cover:
183
+
184
+ - Authentication denial on the generation endpoint, ordinary generation, full-history multi-turn input and unchanged output budget.
185
+ - Text SSE deltas, terminal response/finish reason and real input/output usage; missing usage is an error, not a fabricated zero.
186
+ - Both JSON and streaming tool calls with an explicit named function `tool_choice`: the model emits the requested function call, the tool runs locally, its actual result returns with the call ID, and the model answers using that result.
187
+ - Simultaneous independent requests, followed by two active text streams. After both emit text, only one is aborted; the other must finish, and a subsequent request must succeed. This establishes observed client cancellation isolation, not physical GPU release.
188
+ - For the Gateway, positive before/after deltas of `sglang:num_requests_total` from **each worker**. Gateway aggregate counters alone do not prove replica distribution. The probe does not modify workers, caches, models or deployment state.
189
+
190
+ Finish hardware acceptance by saving server logs/metrics and GPU process/rank observations establishing actual TP=2 execution, plus the real Harness artifacts. In the static allocation setup, run the retained training rollout and HF export checks while independent evaluation uses its reserved devices; preserve training evidence and allocation records. Mark only those scenarios actually observed as passed. TP=2 with two replicas would require four inference GPUs and is not a first-version requirement.
191
+
192
+ A completed, cancelled or timed-out evaluation never runs `docker compose down`, stop, drain, cache flush or GPU release. The shared endpoint remains available to other consumers. The deployment owner may stop it after confirming all relevant consumers have ended.
193
+
194
+ ## Verified upstream references
195
+
196
+ - [SGLang v0.5.21 release and official NVIDIA image](https://github.com/sgl-project/sglang/releases/tag/v0.5.21).
197
+ - [SMG 1.12.0 release](https://github.com/smg-project/smg/releases/tag/v1.12.0), [official Docker image/tag metadata](https://hub.docker.com/v2/repositories/lightseekorg/smg/tags/1.12.0/), [release image build](https://github.com/smg-project/smg/blob/dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef/.github/workflows/release-docker.yml).
198
+ - [Pinned SMG Dockerfile: Python entrypoint, default non-root user and curl removal](https://github.com/smg-project/smg/blob/dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef/docker/Dockerfile), [package/CLI entrypoint](https://github.com/smg-project/smg/blob/dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef/bindings/python/pyproject.toml), [gateway-only startup guide](https://lightseek.org/smg/getting-started#option-b-launch-gateway-only-with-smg-launch).
199
+ - [Pinned SMG launch flags, retries, queue and Prometheus settings](https://github.com/smg-project/smg/blob/dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef/bindings/python/src/smg/router_args.py), [Responses named tool choice type](https://github.com/smg-project/smg/blob/dcc5cb0b8f2a64694938c10f02c6caaa0c40d5ef/crates/protocols/src/responses.rs).
200
+ - [Legacy bundled Router 0.3.2 and its pinned protocol dependency](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/sgl-model-gateway/Cargo.toml).
201
+ - [Pinned engine scheduling/capacity arguments](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/python/sglang/srt/arg_groups/fields/schedule.py), [serving/authentication arguments](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/python/sglang/srt/arg_groups/fields/serving.py), [TP arguments](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/python/sglang/srt/arg_groups/fields/parallel.py).
202
+ - [Pinned Responses implementation](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/python/sglang/srt/entrypoints/openai/serving_responses.py), [worker request metric](https://github.com/sgl-project/sglang/blob/e00930c5489053f26d86b179cee0d087f846acbb/python/sglang/srt/observability/metrics_collector.py).
203
+ - [Qwen example snapshot](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct/tree/a09a35458c702b33eeacc393d103063234e8bc28), [Docker Compose GPU device access](https://docs.docker.com/compose/how-tos/gpu-support/), [Compose merge/override behavior](https://docs.docker.com/reference/compose-file/merge/), [NVIDIA CUDA compatibility](https://docs.nvidia.com/deploy/cuda-compatibility/).