@kindgi/api 0.1.2 → 0.1.4-rc.0

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 (250) hide show
  1. package/dist/agent-binding.d.ts +18 -4
  2. package/dist/agent-binding.d.ts.map +1 -1
  3. package/dist/agent-pins.d.ts +48 -0
  4. package/dist/agent-pins.d.ts.map +1 -0
  5. package/dist/agent-pins.js +102 -0
  6. package/dist/agent-pins.js.map +1 -0
  7. package/dist/app.d.ts +22 -0
  8. package/dist/app.d.ts.map +1 -1
  9. package/dist/app.js +22 -3
  10. package/dist/app.js.map +1 -1
  11. package/dist/block-binding.d.ts +132 -0
  12. package/dist/block-binding.d.ts.map +1 -0
  13. package/dist/block-binding.js +4 -0
  14. package/dist/block-binding.js.map +1 -0
  15. package/dist/block-pins.d.ts +22 -0
  16. package/dist/block-pins.d.ts.map +1 -0
  17. package/dist/block-pins.js +112 -0
  18. package/dist/block-pins.js.map +1 -0
  19. package/dist/cost-binding.d.ts +100 -5
  20. package/dist/cost-binding.d.ts.map +1 -1
  21. package/dist/cost-binding.js +10 -0
  22. package/dist/cost-binding.js.map +1 -1
  23. package/dist/deploy-versions.d.ts +58 -0
  24. package/dist/deploy-versions.d.ts.map +1 -0
  25. package/dist/deploy-versions.js +91 -0
  26. package/dist/deploy-versions.js.map +1 -0
  27. package/dist/deployment-binding.d.ts +24 -3
  28. package/dist/deployment-binding.d.ts.map +1 -1
  29. package/dist/derive-agent-version.d.ts +69 -0
  30. package/dist/derive-agent-version.d.ts.map +1 -0
  31. package/dist/derive-agent-version.js +139 -0
  32. package/dist/derive-agent-version.js.map +1 -0
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +17 -0
  35. package/dist/errors.js.map +1 -1
  36. package/dist/eval-case-binding.d.ts +65 -0
  37. package/dist/eval-case-binding.d.ts.map +1 -0
  38. package/dist/eval-case-binding.js +4 -0
  39. package/dist/eval-case-binding.js.map +1 -0
  40. package/dist/eval-run-binding.d.ts +30 -0
  41. package/dist/eval-run-binding.d.ts.map +1 -1
  42. package/dist/eval-run-dispatcher.d.ts +38 -3
  43. package/dist/eval-run-dispatcher.d.ts.map +1 -1
  44. package/dist/eval-run-dispatcher.js +21 -15
  45. package/dist/eval-run-dispatcher.js.map +1 -1
  46. package/dist/eval-suite-binding.d.ts +1 -1
  47. package/dist/eval-suite-binding.d.ts.map +1 -1
  48. package/dist/eval-suite-binding.js +2 -0
  49. package/dist/eval-suite-binding.js.map +1 -1
  50. package/dist/flow-binding.d.ts +10 -4
  51. package/dist/flow-binding.d.ts.map +1 -1
  52. package/dist/flow-pins.d.ts +36 -0
  53. package/dist/flow-pins.d.ts.map +1 -0
  54. package/dist/flow-pins.js +81 -0
  55. package/dist/flow-pins.js.map +1 -0
  56. package/dist/hitl-binding.d.ts +20 -5
  57. package/dist/hitl-binding.d.ts.map +1 -1
  58. package/dist/index.d.ts +19 -8
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +8 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/judged-dispatcher.d.ts +134 -0
  63. package/dist/judged-dispatcher.d.ts.map +1 -0
  64. package/dist/judged-dispatcher.js +297 -0
  65. package/dist/judged-dispatcher.js.map +1 -0
  66. package/dist/judged-items.d.ts +86 -0
  67. package/dist/judged-items.d.ts.map +1 -0
  68. package/dist/judged-items.js +184 -0
  69. package/dist/judged-items.js.map +1 -0
  70. package/dist/judgment-binding.d.ts +316 -0
  71. package/dist/judgment-binding.d.ts.map +1 -0
  72. package/dist/judgment-binding.js +19 -0
  73. package/dist/judgment-binding.js.map +1 -0
  74. package/dist/middleware/auth.d.ts +3 -2
  75. package/dist/middleware/auth.d.ts.map +1 -1
  76. package/dist/middleware/auth.js.map +1 -1
  77. package/dist/middleware/idempotency.d.ts +5 -1
  78. package/dist/middleware/idempotency.d.ts.map +1 -1
  79. package/dist/middleware/idempotency.js +8 -1
  80. package/dist/middleware/idempotency.js.map +1 -1
  81. package/dist/openapi/generate.d.ts.map +1 -1
  82. package/dist/openapi/generate.js +4 -1
  83. package/dist/openapi/generate.js.map +1 -1
  84. package/dist/openapi/operations.d.ts.map +1 -1
  85. package/dist/openapi/operations.js +543 -24
  86. package/dist/openapi/operations.js.map +1 -1
  87. package/dist/openapi/schemas.d.ts +58 -0
  88. package/dist/openapi/schemas.d.ts.map +1 -1
  89. package/dist/openapi/schemas.js +1058 -27
  90. package/dist/openapi/schemas.js.map +1 -1
  91. package/dist/provenance-binding.d.ts +27 -1
  92. package/dist/provenance-binding.d.ts.map +1 -1
  93. package/dist/provenance-binding.js.map +1 -1
  94. package/dist/provider-binding.d.ts +12 -7
  95. package/dist/provider-binding.d.ts.map +1 -1
  96. package/dist/reviewer-binding.d.ts +10 -2
  97. package/dist/reviewer-binding.d.ts.map +1 -1
  98. package/dist/reviewer-role.d.ts +13 -0
  99. package/dist/reviewer-role.d.ts.map +1 -0
  100. package/dist/reviewer-role.js +27 -0
  101. package/dist/reviewer-role.js.map +1 -0
  102. package/dist/routes/agents.d.ts +9 -1
  103. package/dist/routes/agents.d.ts.map +1 -1
  104. package/dist/routes/agents.js +175 -11
  105. package/dist/routes/agents.js.map +1 -1
  106. package/dist/routes/approvals.d.ts +5 -4
  107. package/dist/routes/approvals.d.ts.map +1 -1
  108. package/dist/routes/approvals.js +52 -16
  109. package/dist/routes/approvals.js.map +1 -1
  110. package/dist/routes/blocks.d.ts +19 -0
  111. package/dist/routes/blocks.d.ts.map +1 -0
  112. package/dist/routes/blocks.js +281 -0
  113. package/dist/routes/blocks.js.map +1 -0
  114. package/dist/routes/conversations.d.ts +7 -1
  115. package/dist/routes/conversations.d.ts.map +1 -1
  116. package/dist/routes/conversations.js +41 -1
  117. package/dist/routes/conversations.js.map +1 -1
  118. package/dist/routes/cost.d.ts.map +1 -1
  119. package/dist/routes/cost.js +142 -11
  120. package/dist/routes/cost.js.map +1 -1
  121. package/dist/routes/deployments.d.ts +3 -0
  122. package/dist/routes/deployments.d.ts.map +1 -1
  123. package/dist/routes/deployments.js +208 -55
  124. package/dist/routes/deployments.js.map +1 -1
  125. package/dist/routes/eval-comparison.d.ts +14 -0
  126. package/dist/routes/eval-comparison.d.ts.map +1 -0
  127. package/dist/routes/eval-comparison.js +87 -0
  128. package/dist/routes/eval-comparison.js.map +1 -0
  129. package/dist/routes/eval-runs.d.ts.map +1 -1
  130. package/dist/routes/eval-runs.js +8 -0
  131. package/dist/routes/eval-runs.js.map +1 -1
  132. package/dist/routes/flows.d.ts +13 -1
  133. package/dist/routes/flows.d.ts.map +1 -1
  134. package/dist/routes/flows.js +44 -3
  135. package/dist/routes/flows.js.map +1 -1
  136. package/dist/routes/hierarchy-errors.d.ts +35 -0
  137. package/dist/routes/hierarchy-errors.d.ts.map +1 -0
  138. package/dist/routes/hierarchy-errors.js +39 -0
  139. package/dist/routes/hierarchy-errors.js.map +1 -0
  140. package/dist/routes/identity.d.ts +7 -0
  141. package/dist/routes/identity.d.ts.map +1 -1
  142. package/dist/routes/identity.js +3 -2
  143. package/dist/routes/identity.js.map +1 -1
  144. package/dist/routes/judged-suites.d.ts +20 -0
  145. package/dist/routes/judged-suites.d.ts.map +1 -0
  146. package/dist/routes/judged-suites.js +272 -0
  147. package/dist/routes/judged-suites.js.map +1 -0
  148. package/dist/routes/judgment-context.d.ts +22 -0
  149. package/dist/routes/judgment-context.d.ts.map +1 -0
  150. package/dist/routes/judgment-context.js +88 -0
  151. package/dist/routes/judgment-context.js.map +1 -0
  152. package/dist/routes/judgment-flow-context.d.ts +32 -0
  153. package/dist/routes/judgment-flow-context.d.ts.map +1 -0
  154. package/dist/routes/judgment-flow-context.js +195 -0
  155. package/dist/routes/judgment-flow-context.js.map +1 -0
  156. package/dist/routes/judgments.d.ts +41 -0
  157. package/dist/routes/judgments.d.ts.map +1 -0
  158. package/dist/routes/judgments.js +566 -0
  159. package/dist/routes/judgments.js.map +1 -0
  160. package/dist/routes/orgs.d.ts +5 -2
  161. package/dist/routes/orgs.d.ts.map +1 -1
  162. package/dist/routes/orgs.js +38 -22
  163. package/dist/routes/orgs.js.map +1 -1
  164. package/dist/routes/policies.d.ts.map +1 -1
  165. package/dist/routes/policies.js +12 -1
  166. package/dist/routes/policies.js.map +1 -1
  167. package/dist/routes/projects.d.ts +10 -2
  168. package/dist/routes/projects.d.ts.map +1 -1
  169. package/dist/routes/projects.js +87 -79
  170. package/dist/routes/projects.js.map +1 -1
  171. package/dist/routes/provenance.d.ts.map +1 -1
  172. package/dist/routes/provenance.js +32 -1
  173. package/dist/routes/provenance.js.map +1 -1
  174. package/dist/routes/providers.d.ts.map +1 -1
  175. package/dist/routes/providers.js +6 -1
  176. package/dist/routes/providers.js.map +1 -1
  177. package/dist/routes/runs.d.ts +0 -7
  178. package/dist/routes/runs.d.ts.map +1 -1
  179. package/dist/routes/runs.js +65 -20
  180. package/dist/routes/runs.js.map +1 -1
  181. package/dist/routes/scope-params.d.ts +16 -1
  182. package/dist/routes/scope-params.d.ts.map +1 -1
  183. package/dist/routes/scope-params.js +28 -0
  184. package/dist/routes/scope-params.js.map +1 -1
  185. package/dist/routes/teams.d.ts +6 -2
  186. package/dist/routes/teams.d.ts.map +1 -1
  187. package/dist/routes/teams.js +77 -73
  188. package/dist/routes/teams.js.map +1 -1
  189. package/dist/types.d.ts +4 -3
  190. package/dist/types.d.ts.map +1 -1
  191. package/dist/webhook-endpoint-binding.d.ts +11 -0
  192. package/dist/webhook-endpoint-binding.d.ts.map +1 -1
  193. package/dist/webhook-endpoint-binding.js.map +1 -1
  194. package/openapi.json +13316 -9299
  195. package/package.json +21 -21
  196. package/src/agent-binding.ts +19 -4
  197. package/src/agent-pins.ts +147 -0
  198. package/src/app.ts +76 -3
  199. package/src/block-binding.ts +137 -0
  200. package/src/block-pins.ts +148 -0
  201. package/src/cost-binding.ts +116 -5
  202. package/src/deploy-versions.ts +157 -0
  203. package/src/deployment-binding.ts +27 -3
  204. package/src/derive-agent-version.ts +206 -0
  205. package/src/errors.ts +17 -0
  206. package/src/eval-case-binding.ts +71 -0
  207. package/src/eval-run-binding.ts +33 -0
  208. package/src/eval-run-dispatcher.ts +57 -16
  209. package/src/eval-suite-binding.ts +2 -0
  210. package/src/flow-binding.ts +11 -4
  211. package/src/flow-pins.ts +113 -0
  212. package/src/hitl-binding.ts +20 -4
  213. package/src/index.ts +88 -2
  214. package/src/judged-dispatcher.ts +507 -0
  215. package/src/judged-items.ts +263 -0
  216. package/src/judgment-binding.ts +349 -0
  217. package/src/middleware/auth.ts +3 -2
  218. package/src/middleware/idempotency.ts +7 -1
  219. package/src/openapi/generate.ts +7 -1
  220. package/src/openapi/operations.ts +615 -24
  221. package/src/openapi/schemas.ts +1157 -22
  222. package/src/provenance-binding.ts +42 -1
  223. package/src/provider-binding.ts +12 -7
  224. package/src/reviewer-binding.ts +10 -2
  225. package/src/reviewer-role.ts +35 -0
  226. package/src/routes/agents.ts +243 -19
  227. package/src/routes/approvals.ts +70 -19
  228. package/src/routes/blocks.ts +362 -0
  229. package/src/routes/conversations.ts +57 -1
  230. package/src/routes/cost.ts +159 -21
  231. package/src/routes/deployments.ts +266 -56
  232. package/src/routes/eval-comparison.ts +101 -0
  233. package/src/routes/eval-runs.ts +11 -0
  234. package/src/routes/flows.ts +63 -5
  235. package/src/routes/hierarchy-errors.ts +51 -0
  236. package/src/routes/identity.ts +10 -2
  237. package/src/routes/judged-suites.ts +363 -0
  238. package/src/routes/judgment-context.ts +128 -0
  239. package/src/routes/judgment-flow-context.ts +245 -0
  240. package/src/routes/judgments.ts +743 -0
  241. package/src/routes/orgs.ts +44 -27
  242. package/src/routes/policies.ts +19 -0
  243. package/src/routes/projects.ts +106 -95
  244. package/src/routes/provenance.ts +48 -1
  245. package/src/routes/providers.ts +5 -0
  246. package/src/routes/runs.ts +79 -22
  247. package/src/routes/scope-params.ts +35 -1
  248. package/src/routes/teams.ts +96 -90
  249. package/src/types.ts +4 -3
  250. package/src/webhook-endpoint-binding.ts +11 -0
@@ -128,6 +128,23 @@ export const RunStatusSchema: JsonSchema = {
128
128
  enum: ['pending', 'running', 'suspended', 'completed', 'failed', 'cancelled'],
129
129
  };
130
130
 
131
+ /**
132
+ * The agent a run is a turn of. A component of its own, so generated
133
+ * clients name it `RunAgent` (not after the `agent` property).
134
+ */
135
+ export const RunAgentSchema: JsonSchema = {
136
+ type: 'object',
137
+ additionalProperties: false,
138
+ required: ['id', 'version', 'conversationId'],
139
+ description:
140
+ "Set on an agent's turn (an agent run, or the turn a flow's agent step started): the agent, the version that ran and the conversation. Absent on other runs, and on turns that ran before Kindgi 0.1.3.",
141
+ properties: {
142
+ id: { type: 'string', description: 'The agent id.' },
143
+ version: { type: 'string', description: 'The agent version that ran (semver).' },
144
+ conversationId: { type: 'string', format: 'uuid' },
145
+ },
146
+ };
147
+
131
148
  export const RunSchema: JsonSchema = {
132
149
  type: 'object',
133
150
  additionalProperties: false,
@@ -167,6 +184,16 @@ export const RunSchema: JsonSchema = {
167
184
  type: 'string',
168
185
  description: 'Set on a child run: the node in the parent run that started it.',
169
186
  },
187
+ agent: { $ref: '#/components/schemas/RunAgent' },
188
+ replayOf: {
189
+ type: 'string',
190
+ format: 'uuid',
191
+ description: 'Set on a replay run (an eval run re-running a past run): the run it replays.',
192
+ },
193
+ evalRunId: {
194
+ type: 'string',
195
+ description: 'Set on a replay run: the eval run that started it.',
196
+ },
170
197
  publicAccessToken: {
171
198
  type: 'string',
172
199
  description:
@@ -557,6 +584,29 @@ export const ApprovalSchema: JsonSchema = {
557
584
  updatedAt: { type: 'string', format: 'date-time' },
558
585
  decidedAt: { type: 'string', format: 'date-time' },
559
586
  expiresAt: { type: 'string', format: 'date-time' },
587
+ decision: {
588
+ description:
589
+ "The reviewer's decision, once one is recorded. Absent while the approval is open, and when it ended without one (it expired, or a timeout escalated it).",
590
+ $ref: '#/components/schemas/ApprovalDecisionRecord',
591
+ },
592
+ },
593
+ };
594
+
595
+ export const ApprovalDecisionRecordSchema: JsonSchema = {
596
+ type: 'object',
597
+ additionalProperties: false,
598
+ required: ['decision', 'reviewerId', 'reviewerRoleAtDecision', 'decidedAt'],
599
+ properties: {
600
+ decision: ReviewDecisionKindSchema,
601
+ decidedBy: {
602
+ type: 'string',
603
+ description:
604
+ "Who decided, as an actor: `user:<userId>`, the reviewer's user. The run's journal and provenance name the decider the same way. The Kindgi runtime always records it; a deployment whose HITL binding doesn't leaves it out.",
605
+ },
606
+ reviewerId: { type: 'string', format: 'uuid' },
607
+ reviewerRoleAtDecision: ReviewerRoleSchema,
608
+ decidedAt: { type: 'string', format: 'date-time' },
609
+ rationale: { type: 'string' },
560
610
  },
561
611
  };
562
612
 
@@ -599,7 +649,7 @@ export const CompleteApprovalBodySchema: JsonSchema = {
599
649
  rationale: { type: 'string' },
600
650
  value: {
601
651
  description:
602
- 'Payload passed to the run waitpoint (`RunBinding.completeToken`) when the approval is linked to a suspended run and the decision is `approve` or `reject`.',
652
+ "Payload passed to the run waitpoint (`RunBinding.completeToken`) when the approval is linked to a suspended run and the decision is `approve` or `reject`. Refused (400 `bad-input`) for an agent's tool-call or session gate (`tool-call:pending`, `agent-turn:session-hitl-gate`): those resume on the decision alone.",
603
653
  },
604
654
  },
605
655
  };
@@ -887,8 +937,23 @@ export const AgentSchema: JsonSchema = {
887
937
  version: { type: 'string', description: 'Semver.' },
888
938
  name: { type: 'string' },
889
939
  description: { type: 'string' },
890
- instructions: { type: 'string' },
940
+ instructions: {
941
+ oneOf: [{ type: 'string', minLength: 1 }, { $ref: '#/components/schemas/PromptRef' }],
942
+ description:
943
+ 'The system prompt (a Liquid template), or a prompt block by range whose template and parameters are used instead (pinned at publish, `pins.prompts`).',
944
+ },
891
945
  parameters: { type: 'array', items: { $ref: '#/components/schemas/PromptParameter' } },
946
+ settings: {
947
+ type: 'array',
948
+ items: { $ref: '#/components/schemas/BlockRef' },
949
+ description:
950
+ 'Settings blocks the agent reads, by range: tools read them as `ToolContext.settings[\'<id>\']`, templates as `settings["<id>"]`. Pinned at publish (`pins.settings`).',
951
+ },
952
+ modelSettings: {
953
+ $ref: '#/components/schemas/BlockRef',
954
+ description:
955
+ "A model-settings block by range: its `temperature` and `maxOutputTokens` go into the turn's model calls. Pinned at publish.",
956
+ },
892
957
  capabilities: { type: 'array', items: { $ref: '#/components/schemas/Capability' } },
893
958
  tools: { type: 'array', items: { $ref: '#/components/schemas/ToolRef' } },
894
959
  retrieval: { type: 'array', items: { $ref: '#/components/schemas/RetrievalIntent' } },
@@ -910,6 +975,108 @@ export const AgentSchema: JsonSchema = {
910
975
  tags: { type: 'array', items: { type: 'string' } },
911
976
  output: { $ref: '#/components/schemas/AgentOutputSpec' },
912
977
  toolErrors: { $ref: '#/components/schemas/ToolErrorsSpec' },
978
+ pins: { $ref: '#/components/schemas/AgentPins' },
979
+ derivedFrom: { $ref: '#/components/schemas/VersionDerivation' },
980
+ unregisteredAt: {
981
+ type: 'string',
982
+ format: 'date-time',
983
+ description:
984
+ 'Present only on an unregistered version (`GET …/versions/{version}` reads those too). Unregister stops a version being chosen, not the pins that hold it: a new run naming it is refused, while a resumed run and a published version that pins it still run it.',
985
+ },
986
+ pinsDigest: {
987
+ type: 'string',
988
+ pattern: '^sha256:[0-9a-f]{64}$',
989
+ description:
990
+ "Set by the runtime with `pins`: `sha256:<hex>` of the pins' canonical JSON (sorted keys, no whitespace). Two agent versions with the same digest run the same blocks.",
991
+ },
992
+ },
993
+ };
994
+
995
+ export const VersionDerivationSchema: JsonSchema = {
996
+ description:
997
+ "Set by the runtime on an agent or flow version a deploy registered in place of the definition's version, which was registered already with other pins or content (versions never change). Never in the publish body.",
998
+ type: 'object',
999
+ additionalProperties: false,
1000
+ required: ['version', 'reason'],
1001
+ properties: {
1002
+ version: { type: 'string', description: 'The version the definition names.' },
1003
+ reason: {
1004
+ type: 'string',
1005
+ enum: ['pins-changed', 'unpinned', 'version-taken', 'edited'],
1006
+ description:
1007
+ "`pins-changed`: a block it uses has a new version; `unpinned`: the definition's version was published before pins existed; `version-taken`: the definition's version holds another definition; `edited`: derived from `version` with some data-block pins swapped (`POST /v1/agents/{agentId}/versions`).",
1008
+ },
1009
+ label: { type: 'string', description: 'For `edited`: a short label for the version.' },
1010
+ by: { type: 'string', description: 'For `edited`: who derived it (`user:<id>`).' },
1011
+ },
1012
+ };
1013
+
1014
+ export const DeriveAgentVersionBodySchema: JsonSchema = {
1015
+ description:
1016
+ "Derive a new agent version from a pinned one with some data-block pins swapped: an expert's edit reaching an agent with no code change.",
1017
+ type: 'object',
1018
+ additionalProperties: false,
1019
+ required: ['from', 'pins'],
1020
+ properties: {
1021
+ from: { type: 'string', description: 'The version to derive from (it must be pinned).' },
1022
+ pins: { $ref: '#/components/schemas/AgentPinSwaps' },
1023
+ label: { type: 'string', description: 'A short label for the new version.' },
1024
+ projectId: {
1025
+ type: 'string',
1026
+ format: 'uuid',
1027
+ description: "The agent's project, when the runtime doesn't record it on the version.",
1028
+ },
1029
+ },
1030
+ };
1031
+
1032
+ const PinMapSchema: JsonSchema = {
1033
+ type: 'object',
1034
+ additionalProperties: { type: 'string' },
1035
+ };
1036
+
1037
+ export const AgentPinSwapsSchema: JsonSchema = {
1038
+ description:
1039
+ 'The data-block pins to swap, by block id → exact version. Only blocks the version already references; tool pins come from code.',
1040
+ type: 'object',
1041
+ additionalProperties: false,
1042
+ properties: {
1043
+ prompts: { ...PinMapSchema, description: 'Prompt block id → exact version.' },
1044
+ settings: { ...PinMapSchema, description: 'Settings block id → exact version.' },
1045
+ },
1046
+ };
1047
+
1048
+ export const AgentPinsSchema: JsonSchema = {
1049
+ description:
1050
+ 'The exact block versions an agent version runs: its lockfile. Set by the runtime when the version is published, never in the publish body: each tool range resolves once to the version every run of that agent version uses, so a new tool version reaches the agent only through a new agent version. Absent on a version published before pins existed (its ranges resolve per run).',
1051
+ type: 'object',
1052
+ additionalProperties: false,
1053
+ required: ['tools', 'prompts', 'settings'],
1054
+ properties: {
1055
+ tools: { ...PinMapSchema, description: 'Tool id → exact version.' },
1056
+ prompts: { ...PinMapSchema, description: 'Prompt block id → exact version.' },
1057
+ settings: { ...PinMapSchema, description: 'Settings block id → exact version.' },
1058
+ },
1059
+ };
1060
+
1061
+ export const PromptRefSchema: JsonSchema = {
1062
+ description: "A prompt block an agent's instructions come from, by id and semver range.",
1063
+ type: 'object',
1064
+ additionalProperties: false,
1065
+ required: ['prompt', 'version'],
1066
+ properties: {
1067
+ prompt: { type: 'string', description: 'The prompt block id.' },
1068
+ version: { type: 'string', description: 'A semver range (`^1.0.0`, `1.2.0`).' },
1069
+ },
1070
+ };
1071
+
1072
+ export const BlockRefSchema: JsonSchema = {
1073
+ description: 'A settings block an agent reads, by id and semver range.',
1074
+ type: 'object',
1075
+ additionalProperties: false,
1076
+ required: ['id', 'version'],
1077
+ properties: {
1078
+ id: { type: 'string', description: 'The settings block id.' },
1079
+ version: { type: 'string', description: 'A semver range (`^1.0.0`, `1.2.0`).' },
913
1080
  },
914
1081
  };
915
1082
 
@@ -935,8 +1102,23 @@ export const PublishAgentBodySchema: JsonSchema = {
935
1102
  name: { type: 'string' },
936
1103
  description: { type: 'string' },
937
1104
  projectId: ContentProjectIdProperty,
938
- instructions: { type: 'string' },
1105
+ instructions: {
1106
+ oneOf: [{ type: 'string', minLength: 1 }, { $ref: '#/components/schemas/PromptRef' }],
1107
+ description:
1108
+ 'The system prompt (a Liquid template), or a prompt block by range whose template and parameters are used instead (pinned at publish, `pins.prompts`).',
1109
+ },
939
1110
  parameters: { type: 'array', items: { $ref: '#/components/schemas/PromptParameter' } },
1111
+ settings: {
1112
+ type: 'array',
1113
+ items: { $ref: '#/components/schemas/BlockRef' },
1114
+ description:
1115
+ 'Settings blocks the agent reads, by range: tools read them as `ToolContext.settings[\'<id>\']`, templates as `settings["<id>"]`. Pinned at publish (`pins.settings`).',
1116
+ },
1117
+ modelSettings: {
1118
+ $ref: '#/components/schemas/BlockRef',
1119
+ description:
1120
+ "A model-settings block by range: its `temperature` and `maxOutputTokens` go into the turn's model calls. Pinned at publish.",
1121
+ },
940
1122
  capabilities: { type: 'array', items: { $ref: '#/components/schemas/Capability' } },
941
1123
  tools: { type: 'array', items: { $ref: '#/components/schemas/ToolRef' } },
942
1124
  retrieval: { type: 'array', items: { $ref: '#/components/schemas/RetrievalIntent' } },
@@ -1073,6 +1255,35 @@ export const FlowSchema: JsonSchema = {
1073
1255
  edges: { type: 'array', items: { $ref: '#/components/schemas/FlowEdge' } },
1074
1256
  maxParallelism: { type: 'integer', minimum: 1 },
1075
1257
  metadata: { type: 'object', additionalProperties: true },
1258
+ pins: { $ref: '#/components/schemas/FlowPins' },
1259
+ pinsDigest: {
1260
+ type: 'string',
1261
+ pattern: '^sha256:[0-9a-f]{64}$',
1262
+ description:
1263
+ "Set by the runtime with `pins`: `sha256:<hex>` of the pins' canonical JSON (sorted keys, no whitespace).",
1264
+ },
1265
+ derivedFrom: { $ref: '#/components/schemas/VersionDerivation' },
1266
+ unregisteredAt: {
1267
+ type: 'string',
1268
+ format: 'date-time',
1269
+ description:
1270
+ 'Present only on an unregistered version (`GET …/versions/{version}` reads those too). Unregister stops a version being chosen, not the pins that hold it: a new run naming it is refused, while a resumed run and a published version that pins it still run it.',
1271
+ },
1272
+ },
1273
+ };
1274
+
1275
+ export const FlowPinsSchema: JsonSchema = {
1276
+ description:
1277
+ 'The exact tool and agent versions a flow version runs: its lockfile. Set by the runtime when the version is published, never in the publish body: each tool the flow runs, and each agent it runs at no named version, resolves once to its latest version then, which every run of that flow version uses. Absent on a version published before pins existed (it binds the latest versions per run).',
1278
+ type: 'object',
1279
+ additionalProperties: false,
1280
+ required: ['tools', 'agents'],
1281
+ properties: {
1282
+ tools: { ...PinMapSchema, description: 'Tool id → exact version.' },
1283
+ agents: {
1284
+ ...PinMapSchema,
1285
+ description: 'Agent id → exact version, for agent nodes that name no version.',
1286
+ },
1076
1287
  },
1077
1288
  };
1078
1289
 
@@ -1652,6 +1863,12 @@ export const ConversationSchema: JsonSchema = {
1652
1863
  agentVersion: { type: 'string', description: 'Semver.' },
1653
1864
  title: { type: 'string' },
1654
1865
  participantId: { type: 'string' },
1866
+ projectId: {
1867
+ type: 'string',
1868
+ format: 'uuid',
1869
+ description:
1870
+ "The project the conversation is in: the project of the run that opened it, or `projectId` on open (the tenant's Default project when omitted). Absent on conversations from before Kindgi 0.1.3; those are listed only without a scope.",
1871
+ },
1655
1872
  scope: {
1656
1873
  type: 'object',
1657
1874
  additionalProperties: true,
@@ -1706,6 +1923,12 @@ export const OpenConversationBodySchema: JsonSchema = {
1706
1923
  type: 'string',
1707
1924
  description: 'Optional. Defaults to `"Untitled conversation"` when omitted.',
1708
1925
  },
1926
+ projectId: {
1927
+ type: 'string',
1928
+ format: 'uuid',
1929
+ description:
1930
+ "The project the conversation is in; `GET /v1/conversations?scopeKind=project&scopeId=…` lists it. A project of the caller's tenant, else `400 bad-input`. Omitted: the tenant's Default project, as for a run.",
1931
+ },
1709
1932
  scope: {
1710
1933
  type: 'object',
1711
1934
  additionalProperties: true,
@@ -1811,21 +2034,484 @@ export const ObservationSchema: JsonSchema = {
1811
2034
  provenanceId: { type: 'string', format: 'uuid' },
1812
2035
  },
1813
2036
  },
1814
- observedAt: { type: 'string', format: 'date-time' },
2037
+ observedAt: { type: 'string', format: 'date-time' },
2038
+ },
2039
+ };
2040
+
2041
+ export const ObservationCollectionPageSchema: JsonSchema = {
2042
+ type: 'object',
2043
+ additionalProperties: false,
2044
+ required: ['data', 'hasMore'],
2045
+ properties: {
2046
+ data: { type: 'array', items: { $ref: '#/components/schemas/Observation' } },
2047
+ nextCursor: {
2048
+ type: 'string',
2049
+ description: 'Opaque ISO-timestamp cursor. Treat as opaque on the client.',
2050
+ },
2051
+ hasMore: { type: 'boolean' },
2052
+ },
2053
+ };
2054
+
2055
+ // ---------------- judgments + judge classes ----------------
2056
+
2057
+ export const JudgeClassScopeSchema: JsonSchema = {
2058
+ description:
2059
+ 'Where a judge class applies: the whole tenant, one project, or one agent in a project.',
2060
+ oneOf: [
2061
+ {
2062
+ type: 'object',
2063
+ additionalProperties: false,
2064
+ required: ['kind'],
2065
+ properties: { kind: { type: 'string', const: 'tenant' } },
2066
+ },
2067
+ {
2068
+ type: 'object',
2069
+ additionalProperties: false,
2070
+ required: ['kind', 'projectId'],
2071
+ properties: {
2072
+ kind: { type: 'string', const: 'project' },
2073
+ projectId: { type: 'string', minLength: 1 },
2074
+ },
2075
+ },
2076
+ {
2077
+ type: 'object',
2078
+ additionalProperties: false,
2079
+ required: ['kind', 'projectId', 'agentId'],
2080
+ properties: {
2081
+ kind: { type: 'string', const: 'agent' },
2082
+ projectId: { type: 'string', minLength: 1 },
2083
+ agentId: { type: 'string', minLength: 1 },
2084
+ },
2085
+ },
2086
+ ],
2087
+ };
2088
+
2089
+ export const JudgeClassSchema: JsonSchema = {
2090
+ type: 'object',
2091
+ additionalProperties: false,
2092
+ required: ['id', 'tenantId', 'scope', 'name', 'weight', 'createdAt', 'updatedAt'],
2093
+ properties: {
2094
+ id: { type: 'string' },
2095
+ tenantId: { type: 'string' },
2096
+ scope: { $ref: '#/components/schemas/JudgeClassScope' },
2097
+ name: {
2098
+ type: 'string',
2099
+ description: 'The deployment\'s own word for the class: "expert", "user", "arbitrator".',
2100
+ },
2101
+ weight: {
2102
+ type: 'number',
2103
+ minimum: 0,
2104
+ description: 'How much a judgment of this class counts, relative to the others.',
2105
+ },
2106
+ description: { type: 'string' },
2107
+ createdAt: { type: 'string', format: 'date-time' },
2108
+ updatedAt: { type: 'string', format: 'date-time' },
2109
+ unregisteredAt: {
2110
+ type: 'string',
2111
+ format: 'date-time',
2112
+ description: 'Set when the class was retired.',
2113
+ },
2114
+ },
2115
+ };
2116
+
2117
+ export const JudgeClassCollectionPageSchema: JsonSchema = {
2118
+ type: 'object',
2119
+ additionalProperties: false,
2120
+ required: ['data', 'hasMore'],
2121
+ properties: {
2122
+ data: { type: 'array', items: { $ref: '#/components/schemas/JudgeClass' } },
2123
+ nextCursor: { type: 'string', description: 'Opaque cursor. Treat as opaque on the client.' },
2124
+ hasMore: { type: 'boolean' },
2125
+ },
2126
+ };
2127
+
2128
+ export const CreateJudgeClassBodySchema: JsonSchema = {
2129
+ type: 'object',
2130
+ additionalProperties: false,
2131
+ required: ['scope', 'name', 'weight'],
2132
+ properties: {
2133
+ scope: { $ref: '#/components/schemas/JudgeClassScope' },
2134
+ name: { type: 'string', minLength: 1, maxLength: 100 },
2135
+ weight: { type: 'number', minimum: 0 },
2136
+ description: { type: 'string' },
2137
+ },
2138
+ };
2139
+
2140
+ export const UpdateJudgeClassBodySchema: JsonSchema = {
2141
+ type: 'object',
2142
+ additionalProperties: false,
2143
+ minProperties: 1,
2144
+ properties: {
2145
+ weight: { type: 'number', minimum: 0 },
2146
+ description: { type: 'string' },
2147
+ },
2148
+ };
2149
+
2150
+ export const UnregisterJudgeClassResultSchema: JsonSchema = {
2151
+ type: 'object',
2152
+ additionalProperties: false,
2153
+ required: ['judgeClassId', 'unregistered'],
2154
+ properties: {
2155
+ judgeClassId: { type: 'string' },
2156
+ unregistered: { type: 'boolean', const: true },
2157
+ },
2158
+ };
2159
+
2160
+ export const JudgedSubjectSchema: JsonSchema = {
2161
+ type: 'object',
2162
+ additionalProperties: false,
2163
+ required: ['kind', 'id', 'version'],
2164
+ description: 'What a judged run ran: an agent at a version, or a flow at a version.',
2165
+ properties: {
2166
+ kind: { type: 'string', enum: ['agent', 'flow'] },
2167
+ id: { type: 'string' },
2168
+ version: { type: 'string' },
2169
+ },
2170
+ };
2171
+
2172
+ export const JudgedItemSchema: JsonSchema = {
2173
+ type: 'object',
2174
+ additionalProperties: false,
2175
+ required: ['key'],
2176
+ description: "The judged item of a run's output.",
2177
+ properties: {
2178
+ key: { type: 'string', minLength: 1, description: "The caller's stable id for the item." },
2179
+ pointer: {
2180
+ type: 'string',
2181
+ description:
2182
+ 'Where the item is in the run\'s output, as a JSON Pointer (RFC 6901), e.g. `/matches/2`. `""` is the whole output.',
2183
+ },
2184
+ rank: {
2185
+ type: 'integer',
2186
+ minimum: 0,
2187
+ description: "The item's position in a ranked list (0 = first).",
2188
+ },
2189
+ },
2190
+ };
2191
+
2192
+ export const JudgmentAssertedBySchema: JsonSchema = {
2193
+ type: 'object',
2194
+ additionalProperties: false,
2195
+ required: ['kind', 'id'],
2196
+ description: 'Who asserted a judgment: the authenticated caller, never a typed name.',
2197
+ properties: {
2198
+ kind: { type: 'string', enum: ['user', 'service'] },
2199
+ id: {
2200
+ type: 'string',
2201
+ description: 'A user id, or for a service token its token or session id.',
2202
+ },
2203
+ },
2204
+ };
2205
+
2206
+ export const JudgmentSchema: JsonSchema = {
2207
+ type: 'object',
2208
+ additionalProperties: false,
2209
+ required: [
2210
+ 'id',
2211
+ 'tenantId',
2212
+ 'projectId',
2213
+ 'runId',
2214
+ 'subject',
2215
+ 'item',
2216
+ 'verdict',
2217
+ 'assertedBy',
2218
+ 'createdAt',
2219
+ ],
2220
+ properties: {
2221
+ id: { type: 'string' },
2222
+ tenantId: { type: 'string' },
2223
+ projectId: { type: 'string' },
2224
+ runId: { type: 'string' },
2225
+ subject: { $ref: '#/components/schemas/JudgedSubject' },
2226
+ item: { $ref: '#/components/schemas/JudgedItem' },
2227
+ verdict: { type: 'string', enum: ['yes', 'no'] },
2228
+ reason: { type: 'string' },
2229
+ judgeClassId: {
2230
+ type: 'string',
2231
+ description:
2232
+ 'The judge class the judgment is recorded under. Absent when unclassified (counts with weight 1).',
2233
+ },
2234
+ assertedBy: { $ref: '#/components/schemas/JudgmentAssertedBy' },
2235
+ participantId: {
2236
+ type: 'string',
2237
+ description:
2238
+ "The app's opaque id for its end user who judged, when an app judged on their behalf.",
2239
+ },
2240
+ createdAt: { type: 'string', format: 'date-time' },
2241
+ unregisteredAt: {
2242
+ type: 'string',
2243
+ format: 'date-time',
2244
+ description: 'Set when the judgment was removed or superseded.',
2245
+ },
2246
+ supersededBy: { type: 'string', description: 'The judgment that replaced this one.' },
2247
+ },
2248
+ };
2249
+
2250
+ export const JudgedRunContextSchema: JsonSchema = {
2251
+ type: 'object',
2252
+ additionalProperties: false,
2253
+ description:
2254
+ 'What a judged run needs besides its input to be replayed, captured when it was first judged. For an agent turn: the conversation before it, what its retrievals returned, and the decision at its session approval gate. For a flow run: its tool calls with their results.',
2255
+ properties: {
2256
+ history: {
2257
+ type: 'array',
2258
+ items: {},
2259
+ description:
2260
+ "The conversation's messages before the turn, oldest first (at most the last 200).",
2261
+ },
2262
+ historyTruncated: {
2263
+ type: 'boolean',
2264
+ description: 'Whether older messages were left out of `history`.',
2265
+ },
2266
+ retrieved: { description: "What the turn's retrievals returned." },
2267
+ sessionApproval: {
2268
+ type: 'object',
2269
+ additionalProperties: false,
2270
+ required: ['approved'],
2271
+ description:
2272
+ "The reviewer's decision at the turn's session approval gate, when the turn waited on one. A replay of the turn follows it.",
2273
+ properties: {
2274
+ approved: { type: 'boolean' },
2275
+ rationale: { type: 'string', description: "The reviewer's reason for a rejection." },
2276
+ },
2277
+ },
2278
+ flow: {
2279
+ type: 'object',
2280
+ additionalProperties: false,
2281
+ required: ['calls', 'steps'],
2282
+ description:
2283
+ "For a flow run: what it did, kept at its first judgment so it can be replayed. Every tool call it made with its result (at its tool nodes, in its agent steps' turns and in its sub-flows), at most 500, and its agent steps.",
2284
+ properties: {
2285
+ calls: {
2286
+ type: 'array',
2287
+ items: {
2288
+ type: 'object',
2289
+ additionalProperties: false,
2290
+ required: ['runId', 'toolId'],
2291
+ properties: {
2292
+ runId: {
2293
+ type: 'string',
2294
+ description:
2295
+ "The run that made it: the flow run, a sub-flow's, or an agent step's turn.",
2296
+ },
2297
+ nodeId: {
2298
+ type: 'string',
2299
+ description: 'The tool node that made it, or the agent step whose turn did.',
2300
+ },
2301
+ scope: { type: 'string', description: 'The loop iteration, in a loop body.' },
2302
+ toolId: { type: 'string' },
2303
+ arguments: {},
2304
+ result: {},
2305
+ },
2306
+ },
2307
+ },
2308
+ steps: {
2309
+ type: 'array',
2310
+ items: {
2311
+ type: 'object',
2312
+ additionalProperties: false,
2313
+ required: ['runId', 'agentId', 'agentVersion'],
2314
+ properties: {
2315
+ runId: { type: 'string' },
2316
+ nodeId: { type: 'string' },
2317
+ scope: { type: 'string' },
2318
+ agentId: { type: 'string' },
2319
+ agentVersion: { type: 'string' },
2320
+ retrieved: { description: "What the step's turn retrieved." },
2321
+ },
2322
+ },
2323
+ },
2324
+ truncated: { type: 'boolean', description: 'More calls were made than were kept.' },
2325
+ },
2326
+ },
2327
+ },
2328
+ };
2329
+
2330
+ export const JudgedRunCopySchema: JsonSchema = {
2331
+ type: 'object',
2332
+ additionalProperties: false,
2333
+ required: ['runId', 'subject', 'input', 'output', 'capturedAt'],
2334
+ description:
2335
+ "The stored copy of a judged run's input and output, taken when it was first judged.",
2336
+ properties: {
2337
+ runId: { type: 'string' },
2338
+ subject: { $ref: '#/components/schemas/JudgedSubject' },
2339
+ input: {},
2340
+ context: {
2341
+ $ref: '#/components/schemas/JudgedRunContext',
2342
+ },
2343
+ output: {},
2344
+ capturedAt: { type: 'string', format: 'date-time' },
2345
+ },
2346
+ };
2347
+
2348
+ export const JudgmentWithCopiesSchema: JsonSchema = {
2349
+ description: 'A judgment with the stored copies of what was judged.',
2350
+ allOf: [
2351
+ { $ref: '#/components/schemas/Judgment' },
2352
+ {
2353
+ type: 'object',
2354
+ required: ['run'],
2355
+ properties: {
2356
+ run: { $ref: '#/components/schemas/JudgedRunCopy' },
2357
+ itemValue: {
2358
+ description: "The judged item's value, when the judgment pointed at it.",
2359
+ },
2360
+ },
2361
+ },
2362
+ ],
2363
+ };
2364
+
2365
+ export const JudgmentCollectionPageSchema: JsonSchema = {
2366
+ type: 'object',
2367
+ additionalProperties: false,
2368
+ required: ['data', 'hasMore'],
2369
+ properties: {
2370
+ data: { type: 'array', items: { $ref: '#/components/schemas/Judgment' } },
2371
+ nextCursor: { type: 'string', description: 'Opaque cursor. Treat as opaque on the client.' },
2372
+ hasMore: { type: 'boolean' },
2373
+ },
2374
+ };
2375
+
2376
+ export const CreateJudgmentBodySchema: JsonSchema = {
2377
+ type: 'object',
2378
+ additionalProperties: false,
2379
+ required: ['runId', 'item', 'verdict'],
2380
+ properties: {
2381
+ runId: { type: 'string', minLength: 1 },
2382
+ item: { $ref: '#/components/schemas/JudgedItem' },
2383
+ verdict: { type: 'string', enum: ['yes', 'no'] },
2384
+ reason: { type: 'string', maxLength: 4000 },
2385
+ judgeClassId: {
2386
+ type: 'string',
2387
+ minLength: 1,
2388
+ description: 'Optional. When given it must exist and apply to the run.',
2389
+ },
2390
+ participantId: {
2391
+ type: 'string',
2392
+ minLength: 1,
2393
+ description: "An app's opaque id for its end user, when judging on their behalf.",
2394
+ },
2395
+ },
2396
+ };
2397
+
2398
+ export const UnregisterJudgmentResultSchema: JsonSchema = {
2399
+ type: 'object',
2400
+ additionalProperties: false,
2401
+ required: ['judgmentId', 'unregistered'],
2402
+ properties: {
2403
+ judgmentId: { type: 'string' },
2404
+ unregistered: { type: 'boolean', const: true },
2405
+ },
2406
+ };
2407
+
2408
+ export const JudgedItemSummarySchema: JsonSchema = {
2409
+ type: 'object',
2410
+ additionalProperties: false,
2411
+ required: ['key', 'yes', 'no', 'yesWeight', 'totalWeight', 'reasons'],
2412
+ description: "The judgments of one item of a case's output, summed up.",
2413
+ properties: {
2414
+ key: { type: 'string' },
2415
+ pointer: { type: 'string' },
2416
+ rank: { type: 'integer', minimum: 0 },
2417
+ yes: { type: 'integer', minimum: 0, description: 'How many judgments said yes.' },
2418
+ no: { type: 'integer', minimum: 0, description: 'How many judgments said no.' },
2419
+ yesWeight: {
2420
+ type: 'number',
2421
+ description: 'The weight behind "yes" (an unclassified judgment counts 1).',
2422
+ },
2423
+ totalWeight: { type: 'number', description: 'The weight behind all judgments of the item.' },
2424
+ reasons: {
2425
+ type: 'array',
2426
+ description: 'The reasons given, newest first.',
2427
+ items: {
2428
+ type: 'object',
2429
+ additionalProperties: false,
2430
+ required: ['verdict', 'reason'],
2431
+ properties: {
2432
+ verdict: { type: 'string', enum: ['yes', 'no'] },
2433
+ reason: { type: 'string' },
2434
+ },
2435
+ },
2436
+ },
2437
+ },
2438
+ };
2439
+
2440
+ export const JudgedEvalCaseSchema: JsonSchema = {
2441
+ type: 'object',
2442
+ additionalProperties: false,
2443
+ required: ['caseId', 'subject', 'input', 'output', 'items'],
2444
+ description:
2445
+ "One case of a `judged` eval suite: a copy of a judged run with its items' judgments summed up.",
2446
+ properties: {
2447
+ caseId: { type: 'string', description: "The judged run's id." },
2448
+ subject: { $ref: '#/components/schemas/JudgedSubject' },
2449
+ input: {},
2450
+ context: { $ref: '#/components/schemas/JudgedRunContext' },
2451
+ output: {},
2452
+ items: { type: 'array', items: { $ref: '#/components/schemas/JudgedItemSummary' } },
2453
+ },
2454
+ };
2455
+
2456
+ export const JudgedEvalCaseCollectionPageSchema: JsonSchema = {
2457
+ type: 'object',
2458
+ additionalProperties: false,
2459
+ required: ['data', 'hasMore'],
2460
+ properties: {
2461
+ data: { type: 'array', items: { $ref: '#/components/schemas/JudgedEvalCase' } },
2462
+ nextCursor: { type: 'string', description: 'Opaque cursor. Treat as opaque on the client.' },
2463
+ hasMore: { type: 'boolean' },
2464
+ },
2465
+ };
2466
+
2467
+ export const BuildJudgedSuiteBodySchema: JsonSchema = {
2468
+ type: 'object',
2469
+ additionalProperties: false,
2470
+ required: ['version', 'projectId'],
2471
+ description: 'Name the agent (`agentId`) or the flow (`flowId`) whose judged runs to use.',
2472
+ properties: {
2473
+ version: { type: 'string', description: 'Semver version to publish, e.g. `1.0.0`.' },
2474
+ projectId: { type: 'string', minLength: 1 },
2475
+ agentId: { type: 'string', minLength: 1 },
2476
+ agentVersion: { type: 'string', minLength: 1, description: 'Needs `agentId`.' },
2477
+ flowId: { type: 'string', minLength: 1 },
2478
+ since: {
2479
+ type: 'string',
2480
+ format: 'date-time',
2481
+ description: 'Runs first judged at or after this time.',
2482
+ },
2483
+ until: {
2484
+ type: 'string',
2485
+ format: 'date-time',
2486
+ description: 'Runs first judged before this time.',
2487
+ },
2488
+ judgeClassIds: {
2489
+ type: 'array',
2490
+ items: { type: 'string', minLength: 1 },
2491
+ description: 'Count only judgments recorded under these judge classes.',
2492
+ },
2493
+ minJudgments: {
2494
+ type: 'integer',
2495
+ minimum: 1,
2496
+ description: 'Leave out runs with fewer counted judgments. Default 1.',
2497
+ },
2498
+ description: { type: 'string' },
1815
2499
  },
1816
2500
  };
1817
2501
 
1818
- export const ObservationCollectionPageSchema: JsonSchema = {
2502
+ export const BuildJudgedSuiteResultSchema: JsonSchema = {
1819
2503
  type: 'object',
1820
2504
  additionalProperties: false,
1821
- required: ['data', 'hasMore'],
2505
+ required: ['suiteId', 'version', 'kind', 'caseCount', 'truncated'],
1822
2506
  properties: {
1823
- data: { type: 'array', items: { $ref: '#/components/schemas/Observation' } },
1824
- nextCursor: {
1825
- type: 'string',
1826
- description: 'Opaque ISO-timestamp cursor. Treat as opaque on the client.',
2507
+ suiteId: { type: 'string' },
2508
+ version: { type: 'string' },
2509
+ kind: { type: 'string', enum: ['judged'] },
2510
+ caseCount: { type: 'integer', minimum: 0 },
2511
+ truncated: {
2512
+ type: 'boolean',
2513
+ description: 'Whether more judged runs matched than the 1000 cases a set holds.',
1827
2514
  },
1828
- hasMore: { type: 'boolean' },
1829
2515
  },
1830
2516
  };
1831
2517
 
@@ -2483,6 +3169,12 @@ export const ProvenanceRecordMetadataSchema: JsonSchema = {
2483
3169
  'True when the emission-time signature is present. Independent of whether the export route can produce a signed bundle.',
2484
3170
  },
2485
3171
  createdAt: { type: 'string', format: 'date-time' },
3172
+ projectId: {
3173
+ type: 'string',
3174
+ format: 'uuid',
3175
+ description:
3176
+ "The project of the record's run. Absent on records from before Kindgi 0.1.3; those are listed only without a scope.",
3177
+ },
2486
3178
  },
2487
3179
  };
2488
3180
 
@@ -2508,6 +3200,22 @@ export const ProvenanceRecordSchema: JsonSchema = {
2508
3200
  },
2509
3201
  signature: ProvenanceSignatureSchema,
2510
3202
  createdAt: { type: 'string', format: 'date-time' },
3203
+ callUsage: {
3204
+ type: 'object',
3205
+ description:
3206
+ "Each model call's usage from the cost ledger, by the `callId` in its `model-call` node's attributes. Joined when read: not part of the signed DAG. A signed export includes it, as it stood when signed.",
3207
+ additionalProperties: {
3208
+ type: 'object',
3209
+ additionalProperties: false,
3210
+ required: ['usage'],
3211
+ properties: {
3212
+ usage: { $ref: '#/components/schemas/ModelCallTokens' },
3213
+ costUsd: { type: 'number', minimum: 0 },
3214
+ durationMs: { type: 'integer', minimum: 0 },
3215
+ servedModel: { type: 'string' },
3216
+ },
3217
+ },
3218
+ },
2511
3219
  },
2512
3220
  };
2513
3221
 
@@ -2544,7 +3252,7 @@ export const ExportProvenanceBodySchema: JsonSchema = {
2544
3252
 
2545
3253
  export const ExportProvenanceResultSchema: JsonSchema = {
2546
3254
  description:
2547
- 'Signed exportable bundle. `bundle` is base64 of the exact bytes that were signed (sorted-key canonical JSON, no whitespace); verifiers can pass those bytes directly to `verifyEd25519`. The bundle body itself includes `bundleSchemaVersion`, `runId`, `tenantId`, `dag: { nodes, edges }`, `messages?` (if requested), etc. See `canonicalization` for the deterministic serialization algorithm.',
3255
+ 'Signed exportable bundle. `bundle` is base64 of the exact bytes that were signed (sorted-key canonical JSON, no whitespace); verifiers can pass those bytes directly to `verifyEd25519`. The bundle body itself includes `bundleSchemaVersion`, `runId`, `tenantId`, `dag: { nodes, edges }`, `messages?` (if requested), `callUsage?` (the usage of the model calls, from the cost ledger), etc. See `canonicalization` for the deterministic serialization algorithm.',
2548
3256
  type: 'object',
2549
3257
  additionalProperties: false,
2550
3258
  required: [
@@ -2566,7 +3274,8 @@ export const ExportProvenanceResultSchema: JsonSchema = {
2566
3274
  },
2567
3275
  bundleSchemaVersion: {
2568
3276
  type: 'string',
2569
- description: 'Semver for the shape of the bundle body. Currently `1.0.0`.',
3277
+ description:
3278
+ "Semver for the shape of the bundle body. Currently `1.1.0`, which adds `callUsage`: each model call's usage from the cost ledger, by call id, as it stood when signed.",
2570
3279
  },
2571
3280
  algorithm: { type: 'string', const: 'ed25519' },
2572
3281
  signingKeyId: { type: 'string' },
@@ -2863,6 +3572,14 @@ export const ProviderMetadataSchema: JsonSchema = {
2863
3572
  description:
2864
3573
  "A fallback serves a capability only when no other provider satisfies it (e.g. `kindgi dev`'s scripted `dev-echo`); an agent turn routed to one carries a `fallback-provider` warning. Absent = `false`.",
2865
3574
  },
3575
+ labels: {
3576
+ type: 'object',
3577
+ maxProperties: 32,
3578
+ propertyNames: { pattern: '^[a-z0-9]([a-z0-9._/-]{0,61}[a-z0-9])?$' },
3579
+ additionalProperties: { type: 'string', maxLength: 256 },
3580
+ description:
3581
+ 'Bookkeeping, such as who manages the provider; the router ignores labels. At most 32 keys; a key is 1-63 lowercase letters and digits, with `.`, `-`, `_` or `/` inside; a value is at most 256 characters. The convention key `kindgi.com/managed-by` names the manager (`kindgi-dev`, `kindgi-deploy:<environment>`). Out of bounds: `400 invalid-provider`, reason `invalid-labels`.',
3582
+ },
2866
3583
  },
2867
3584
  };
2868
3585
 
@@ -3243,7 +3960,65 @@ export const GetMCPPromptResultSchema: JsonSchema = {
3243
3960
  */
3244
3961
  export const CostGroupDimensionSchema: JsonSchema = {
3245
3962
  type: 'string',
3246
- enum: ['agentId', 'runId', 'category', 'providerId', 'day', 'month', 'tenant', 'conversationId'],
3963
+ enum: [
3964
+ 'agentId',
3965
+ 'runId',
3966
+ 'category',
3967
+ 'providerId',
3968
+ 'day',
3969
+ 'month',
3970
+ 'tenant',
3971
+ 'conversationId',
3972
+ 'model',
3973
+ 'servedModel',
3974
+ 'projectId',
3975
+ 'orgId',
3976
+ 'rootRunId',
3977
+ 'flowId',
3978
+ ],
3979
+ };
3980
+
3981
+ /** Why a model call failed, as its cost record carries it. */
3982
+ export const ModelCallErrorSchema: JsonSchema = {
3983
+ type: 'object',
3984
+ additionalProperties: false,
3985
+ required: ['message'],
3986
+ description: 'Why a model call failed (`status: failed`).',
3987
+ properties: { message: { type: 'string' } },
3988
+ };
3989
+
3990
+ /** A model call's tokens, as a cost record and a provenance record carry them. */
3991
+ export const ModelCallTokensSchema: JsonSchema = {
3992
+ type: 'object',
3993
+ additionalProperties: false,
3994
+ required: ['promptTokens', 'completionTokens'],
3995
+ description:
3996
+ "The call's tokens. `promptTokens` / `completionTokens` are the totals; `cacheReadTokens` / `cacheWriteTokens` are parts of `promptTokens`, `reasoningTokens` of `completionTokens`, present when the provider reports them.",
3997
+ properties: {
3998
+ promptTokens: { type: 'integer', minimum: 0 },
3999
+ completionTokens: { type: 'integer', minimum: 0 },
4000
+ cacheReadTokens: { type: 'integer', minimum: 0 },
4001
+ cacheWriteTokens: { type: 'integer', minimum: 0 },
4002
+ reasoningTokens: { type: 'integer', minimum: 0 },
4003
+ },
4004
+ };
4005
+
4006
+ /**
4007
+ * Token sums of an aggregate. `prompt` / `completion` are the totals;
4008
+ * `cacheRead` / `cacheWrite` are parts of `prompt`, `reasoning` of
4009
+ * `completion` (`0` where providers didn't report them).
4010
+ */
4011
+ export const CostTokenTotalsSchema: JsonSchema = {
4012
+ type: 'object',
4013
+ additionalProperties: false,
4014
+ required: ['prompt', 'completion', 'cacheRead', 'cacheWrite', 'reasoning'],
4015
+ properties: {
4016
+ prompt: { type: 'integer', minimum: 0 },
4017
+ completion: { type: 'integer', minimum: 0 },
4018
+ cacheRead: { type: 'integer', minimum: 0 },
4019
+ cacheWrite: { type: 'integer', minimum: 0 },
4020
+ reasoning: { type: 'integer', minimum: 0 },
4021
+ },
3247
4022
  };
3248
4023
 
3249
4024
  /**
@@ -3283,6 +4058,63 @@ export const CostRecordSchema: JsonSchema = {
3283
4058
  additionalProperties: true,
3284
4059
  description: 'Free-form filter/display tags — never counters.',
3285
4060
  },
4061
+ callId: {
4062
+ type: 'string',
4063
+ description:
4064
+ "A model call's id (`category` `llm.inference`); its provenance `model-call` node carries it too.",
4065
+ },
4066
+ projectId: { type: 'string', format: 'uuid' },
4067
+ rootRunId: {
4068
+ type: 'string',
4069
+ format: 'uuid',
4070
+ description: "The root of the record's run tree (a flow run, for its agent turns).",
4071
+ },
4072
+ parentRunId: { type: 'string', format: 'uuid' },
4073
+ agentVersion: { type: 'string' },
4074
+ flowId: { type: 'string', description: "The flow of the run tree's root." },
4075
+ nodeId: { type: 'string', description: 'The step that made the call.' },
4076
+ step: { type: 'integer', minimum: 1, description: "The turn's step number." },
4077
+ purpose: {
4078
+ type: 'string',
4079
+ description:
4080
+ "What the call was for, beyond the turn's own model step: `guardrail-judge:<guardrail id>`.",
4081
+ },
4082
+ model: { type: 'string', description: 'The model actually called.' },
4083
+ servedModel: {
4084
+ type: 'string',
4085
+ description: 'The exact model version the vendor reported (vendors alias).',
4086
+ },
4087
+ fallback: {
4088
+ type: 'boolean',
4089
+ description: 'The router picked a fallback provider for the turn.',
4090
+ },
4091
+ status: {
4092
+ type: 'string',
4093
+ enum: ['ok', 'failed'],
4094
+ description: '`ok`: the provider answered. `failed`: the call threw.',
4095
+ },
4096
+ usage: { $ref: '#/components/schemas/ModelCallTokens' },
4097
+ durationMs: { type: 'integer', minimum: 0 },
4098
+ finishReason: { type: 'string' },
4099
+ providerRequestId: { type: 'string', description: "The vendor's id for the request." },
4100
+ attempts: {
4101
+ type: 'integer',
4102
+ minimum: 1,
4103
+ description: "HTTP attempts the call took, the client's retries included.",
4104
+ },
4105
+ error: { $ref: '#/components/schemas/ModelCallError' },
4106
+ rawUsage: {
4107
+ type: 'object',
4108
+ additionalProperties: false,
4109
+ required: ['provider', 'model', 'usage'],
4110
+ description:
4111
+ "The vendor's own usage object, exactly as it reported it. Only with `include=rawUsage`.",
4112
+ properties: {
4113
+ provider: { type: 'string' },
4114
+ model: { type: 'string' },
4115
+ usage: { type: 'object', additionalProperties: true },
4116
+ },
4117
+ },
3286
4118
  },
3287
4119
  };
3288
4120
 
@@ -3303,7 +4135,7 @@ export const CostRecordCollectionPageSchema: JsonSchema = {
3303
4135
  export const CostAggregateGroupSchema: JsonSchema = {
3304
4136
  type: 'object',
3305
4137
  additionalProperties: false,
3306
- required: ['key', 'count', 'totalUsd'],
4138
+ required: ['key', 'count', 'totalUsd', 'tokens'],
3307
4139
  properties: {
3308
4140
  key: {
3309
4141
  type: 'object',
@@ -3313,20 +4145,35 @@ export const CostAggregateGroupSchema: JsonSchema = {
3313
4145
  },
3314
4146
  count: { type: 'integer', minimum: 0 },
3315
4147
  totalUsd: { type: 'number', minimum: 0 },
4148
+ tokens: { $ref: '#/components/schemas/CostTokenTotals' },
3316
4149
  },
3317
4150
  };
3318
4151
 
3319
4152
  export const CostAggregateResultSchema: JsonSchema = {
3320
4153
  type: 'object',
3321
4154
  additionalProperties: false,
3322
- required: ['groups', 'totalUsd', 'totalRecords', 'timeRange', 'groupBy'],
4155
+ required: ['groups', 'totalUsd', 'totalRecords', 'tokens', 'timeRange', 'groupBy'],
3323
4156
  properties: {
3324
4157
  groups: {
3325
4158
  type: 'array',
3326
4159
  items: { $ref: '#/components/schemas/CostAggregateGroup' },
4160
+ description:
4161
+ 'The most expensive groups first (`totalUsd` descending, ties by key), at most `limit`.',
4162
+ },
4163
+ totalGroups: {
4164
+ type: 'integer',
4165
+ minimum: 0,
4166
+ description:
4167
+ 'How many groups there were before the `limit` cap. Absent from a runtime before 0.1.5.',
4168
+ },
4169
+ truncated: {
4170
+ type: 'boolean',
4171
+ description:
4172
+ '`true` when there were more groups than `limit`: `groups` holds the most expensive ones, and `totalUsd` / `totalRecords` / `tokens` still cover every record. Absent from a runtime before 0.1.5.',
3327
4173
  },
3328
4174
  totalUsd: { type: 'number', minimum: 0 },
3329
4175
  totalRecords: { type: 'integer', minimum: 0 },
4176
+ tokens: { $ref: '#/components/schemas/CostTokenTotals' },
3330
4177
  timeRange: {
3331
4178
  type: 'object',
3332
4179
  additionalProperties: false,
@@ -3610,7 +4457,7 @@ export const ReinstatePolicyVersionResultSchema: JsonSchema = {
3610
4457
  */
3611
4458
  export const EvalKindSchema: JsonSchema = {
3612
4459
  type: 'string',
3613
- enum: ['accuracy', 'pairwise', 'regression', 'human-review', 'benchmark', 'custom'],
4460
+ enum: ['accuracy', 'pairwise', 'regression', 'human-review', 'benchmark', 'custom', 'judged'],
3614
4461
  };
3615
4462
 
3616
4463
  /**
@@ -3711,6 +4558,138 @@ export const ReinstateEvalSuiteVersionResultSchema: JsonSchema = {
3711
4558
  },
3712
4559
  };
3713
4560
 
4561
+ // ---------------- data blocks ----------------
4562
+
4563
+ export const BlockKindSchema: JsonSchema = {
4564
+ type: 'string',
4565
+ enum: ['prompt', 'settings'],
4566
+ description:
4567
+ '`prompt`: a Liquid template an agent renders as its instructions. `settings`: a JSON object tools and templates read.',
4568
+ };
4569
+
4570
+ export const PromptBlockContentSchema: JsonSchema = {
4571
+ type: 'object',
4572
+ additionalProperties: false,
4573
+ required: ['template'],
4574
+ properties: {
4575
+ template: {
4576
+ type: 'string',
4577
+ minLength: 1,
4578
+ description:
4579
+ "Liquid, rendered as an agent's instructions are (same parameters and auto-injected variables).",
4580
+ },
4581
+ parameters: { type: 'array', items: { $ref: '#/components/schemas/PromptParameter' } },
4582
+ },
4583
+ };
4584
+
4585
+ export const SettingsBlockContentSchema: JsonSchema = {
4586
+ type: 'object',
4587
+ additionalProperties: false,
4588
+ required: ['values'],
4589
+ properties: {
4590
+ values: {
4591
+ type: 'object',
4592
+ additionalProperties: true,
4593
+ description:
4594
+ 'What tools read (`ToolContext.settings[<block id>]`) and templates read (`settings.<block id>.<key>`).',
4595
+ },
4596
+ schema: {
4597
+ type: 'object',
4598
+ additionalProperties: true,
4599
+ description:
4600
+ "JSON Schema (draft 2020-12) the values must satisfy. A later version's values must satisfy the latest version's schema too.",
4601
+ },
4602
+ },
4603
+ };
4604
+
4605
+ export const BlockSchema: JsonSchema = {
4606
+ description:
4607
+ 'A data block version: a prompt or settings, versioned like a tool (immutable versions, soft unregister). An agent version pins the block versions it uses when it is published. Belongs to one project and is authorized through it.',
4608
+ type: 'object',
4609
+ additionalProperties: false,
4610
+ required: ['id', 'version', 'kind', 'content', 'projectId', 'publishedAt'],
4611
+ properties: {
4612
+ id: { type: 'string', description: 'Dotted lowercase id (e.g. `acme.intake-prompt`).' },
4613
+ version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$' },
4614
+ kind: { $ref: '#/components/schemas/BlockKind' },
4615
+ description: { type: 'string' },
4616
+ content: {
4617
+ oneOf: [
4618
+ { $ref: '#/components/schemas/PromptBlockContent' },
4619
+ { $ref: '#/components/schemas/SettingsBlockContent' },
4620
+ ],
4621
+ description: '`PromptBlockContent` for a prompt, `SettingsBlockContent` for settings.',
4622
+ },
4623
+ projectId: { type: 'string', format: 'uuid' },
4624
+ publishedAt: { type: 'string', format: 'date-time' },
4625
+ unregisteredAt: {
4626
+ type: 'string',
4627
+ format: 'date-time',
4628
+ description:
4629
+ 'Present only on an unregistered version; agent versions that pin it still read it.',
4630
+ },
4631
+ },
4632
+ };
4633
+
4634
+ export const BlockCollectionPageSchema: JsonSchema = {
4635
+ type: 'object',
4636
+ additionalProperties: false,
4637
+ required: ['data', 'hasMore'],
4638
+ properties: {
4639
+ data: { type: 'array', items: { $ref: '#/components/schemas/Block' } },
4640
+ nextCursor: { type: 'string' },
4641
+ hasMore: { type: 'boolean' },
4642
+ },
4643
+ };
4644
+
4645
+ export const PublishBlockBodySchema: JsonSchema = {
4646
+ type: 'object',
4647
+ additionalProperties: false,
4648
+ required: ['projectId', 'id', 'version', 'kind', 'content'],
4649
+ properties: {
4650
+ projectId: ContentProjectIdProperty,
4651
+ id: { type: 'string', minLength: 1 },
4652
+ version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$' },
4653
+ kind: { $ref: '#/components/schemas/BlockKind' },
4654
+ description: { type: 'string' },
4655
+ content: {
4656
+ oneOf: [
4657
+ { $ref: '#/components/schemas/PromptBlockContent' },
4658
+ { $ref: '#/components/schemas/SettingsBlockContent' },
4659
+ ],
4660
+ },
4661
+ },
4662
+ };
4663
+
4664
+ export const PublishBlockResultSchema: JsonSchema = {
4665
+ type: 'object',
4666
+ additionalProperties: false,
4667
+ required: ['blockId', 'version'],
4668
+ properties: { blockId: { type: 'string' }, version: { type: 'string' } },
4669
+ };
4670
+
4671
+ export const UnregisterBlockResultSchema: JsonSchema = {
4672
+ type: 'object',
4673
+ additionalProperties: false,
4674
+ required: ['blockId', 'version', 'unregistered'],
4675
+ properties: {
4676
+ blockId: { type: 'string' },
4677
+ version: { type: 'string' },
4678
+ unregistered: { type: 'boolean', const: true },
4679
+ },
4680
+ };
4681
+
4682
+ export const ReinstateBlockResultSchema: JsonSchema = {
4683
+ type: 'object',
4684
+ additionalProperties: false,
4685
+ required: ['blockId', 'version', 'wasTombstoned'],
4686
+ properties: {
4687
+ blockId: { type: 'string' },
4688
+ version: { type: 'string' },
4689
+ wasTombstoned: { type: 'boolean' },
4690
+ },
4691
+ };
4692
+
3714
4693
  // ---------------- eval runs (admin plane) ----------------
3715
4694
 
3716
4695
  /**
@@ -3743,6 +4722,53 @@ export const EvalRunFlowRefSchema: JsonSchema = {
3743
4722
  },
3744
4723
  };
3745
4724
 
4725
+ export const EvalBaselineSchema: JsonSchema = {
4726
+ description:
4727
+ "What a comparison compares the candidate against: `'recorded'` (each case's recorded output, what was judged), a version (`{ agentId, version }`, replayed under the same rules), or the version live in a scope (`{ live: { projectId?, segments? } }`). Only `'recorded'` runs today; the others are refused when the run starts.",
4728
+ oneOf: [
4729
+ { type: 'string', enum: ['recorded'] },
4730
+ {
4731
+ type: 'object',
4732
+ additionalProperties: false,
4733
+ required: ['agentId', 'version'],
4734
+ properties: { agentId: { type: 'string' }, version: { type: 'string' } },
4735
+ },
4736
+ {
4737
+ type: 'object',
4738
+ additionalProperties: false,
4739
+ required: ['live'],
4740
+ properties: {
4741
+ live: {
4742
+ type: 'object',
4743
+ additionalProperties: false,
4744
+ properties: {
4745
+ projectId: { type: 'string' },
4746
+ segments: { type: 'object', additionalProperties: { type: 'string' } },
4747
+ },
4748
+ },
4749
+ },
4750
+ },
4751
+ ],
4752
+ };
4753
+
4754
+ export const EvalComparisonSchema: JsonSchema = {
4755
+ type: 'object',
4756
+ additionalProperties: false,
4757
+ required: ['baseline', 'reads', 'repetitions', 'k'],
4758
+ description: "A comparison eval run's settings (a `judged` suite).",
4759
+ properties: {
4760
+ baseline: { $ref: '#/components/schemas/EvalBaseline' },
4761
+ reads: {
4762
+ type: 'string',
4763
+ enum: ['recorded', 'live'],
4764
+ description:
4765
+ "Whether replayed reads use the past run's results when it has them (`recorded`), or run live.",
4766
+ },
4767
+ repetitions: { type: 'integer', minimum: 1, maximum: 10 },
4768
+ k: { type: 'integer', minimum: 1, maximum: 100 },
4769
+ },
4770
+ };
4771
+
3746
4772
  export const EvalRunSchema: JsonSchema = {
3747
4773
  type: 'object',
3748
4774
  additionalProperties: false,
@@ -3772,10 +4798,11 @@ export const EvalRunSchema: JsonSchema = {
3772
4798
  type: 'object',
3773
4799
  additionalProperties: true,
3774
4800
  description:
3775
- 'Kind-specific opaque JSON. For `accuracy`, contains `{ passCount, totalCount, meanScore, perCase[] }`. Other kinds define their own shapes as their dispatchers ship.',
4801
+ 'Kind-specific opaque JSON. For `accuracy`, contains `{ passCount, totalCount, meanScore, perCase[] }`. For `judged` (a comparison), `{ summary, perCase[] }`: the summary has the baseline (the versions behind the recorded runs) and the candidate (`{ kind: "agent", agentId, version }` or `{ kind: "flow", flowId, version }`), the case counts (`cases`, `diverged`, `refusedWrites`, `errors`, and `stopped`: flow cases that stopped at a write the replay refused, left out of the metrics), the models that answered, and `metrics` (`weightedYesShare`, `judgedCoverage`, `weightedPrecisionAtK`, each `{ baseline, candidate, delta, n, weight, baselineN, baselineWeight, direction, k?, spread? }`); each case has its replay runs, the scores, the items kept, dropped and new, the tool calls with what happened to each, and `stopped` (what it would have done) when it stopped. Other kinds define their own shapes as their dispatchers ship.',
3776
4802
  },
3777
4803
  error: { type: 'string' },
3778
4804
  correlationId: { type: 'string' },
4805
+ comparison: { $ref: '#/components/schemas/EvalComparison' },
3779
4806
  },
3780
4807
  };
3781
4808
 
@@ -3800,9 +4827,13 @@ export const StartEvalRunBodySchema: JsonSchema = {
3800
4827
  flowRef: { $ref: '#/components/schemas/EvalRunFlowRef' },
3801
4828
  dryRun: { type: 'boolean' },
3802
4829
  correlationId: { type: 'string' },
4830
+ baseline: { $ref: '#/components/schemas/EvalBaseline' },
4831
+ reads: { type: 'string', enum: ['recorded', 'live'] },
4832
+ repetitions: { type: 'integer', minimum: 1, maximum: 10 },
4833
+ k: { type: 'integer', minimum: 1, maximum: 100 },
3803
4834
  },
3804
4835
  description:
3805
- 'Exactly one of `agentRef` or `flowRef` MUST be supplied. `dryRun: true` returns a plan preview without invoking the subject.',
4836
+ "Exactly one of `agentRef` or `flowRef` MUST be supplied. `dryRun: true` returns a plan preview without invoking the subject. For a `judged` suite (a test set), the run is a comparison: `agentRef` or `flowRef` with its `version` is the candidate, replayed on each case without doing anything the past run didn't (a flow stops at a write the replay refuses); `baseline` (default `'recorded'`), `reads` (default `recorded`), `repetitions` (default 1) and `k` (default 10) set how.",
3806
4837
  };
3807
4838
 
3808
4839
  export const StartEvalRunResultSchema: JsonSchema = {
@@ -3980,7 +5011,7 @@ export const LogoutResultSchema: JsonSchema = {
3980
5011
 
3981
5012
  export const WhoamiResultSchema: JsonSchema = {
3982
5013
  description:
3983
- "Introspection of the caller's current authentication context. Always carries `tenantId` and `scopes` (empty for static bearer tokens), plus `userId` when the token carries one; session-token callers additionally see `sessionId`, `providerId`, and `expiresAt`. `user` is the caller's directory record, present when the deployment wires an identity directory and it knows the `userId`. `reviewerRole` is set when the token carries a reviewer role — clients can use it to gate reviewer-only UI (the approvals surface) without a second round trip.",
5014
+ "Introspection of the caller's current authentication context. Always carries `tenantId` and `scopes` (empty for static bearer tokens), plus `userId` when the token carries one; session-token callers additionally see `sessionId`, `providerId`, and `expiresAt`. `user` is the caller's directory record, present when the deployment wires an identity directory and it knows the `userId`. `reviewerRole` is set when the caller is a reviewer — its token carries a reviewer role, or its user is a registered reviewer — so clients can gate reviewer-only UI (the approvals surface) without a second round trip.",
3984
5015
  type: 'object',
3985
5016
  additionalProperties: false,
3986
5017
  required: ['tenantId', 'scopes'],
@@ -4090,6 +5121,49 @@ const DeployedPrimitiveSchema: JsonSchema = {
4090
5121
  },
4091
5122
  };
4092
5123
 
5124
+ const DeployedVersionSchema: JsonSchema = {
5125
+ type: 'object',
5126
+ additionalProperties: false,
5127
+ required: ['id', 'version'],
5128
+ properties: {
5129
+ id: { type: 'string' },
5130
+ version: { type: 'string', description: 'The version the agent is registered as.' },
5131
+ authoredVersion: {
5132
+ type: 'string',
5133
+ description:
5134
+ "The version the agent's or flow's definition names, present when it differs from `version`: that version was registered already with other pins or content, and versions never change, so the deploy registered the next free version in its line (or an earlier deploy did).",
5135
+ },
5136
+ reason: {
5137
+ type: 'string',
5138
+ enum: ['pins-changed', 'unpinned', 'version-taken'],
5139
+ description:
5140
+ 'Why `version` differs from `authoredVersion`: `pins-changed` (a tool or agent it uses has a new version), `unpinned` (`authoredVersion` was published before pins existed), `version-taken` (`authoredVersion` is registered with other content).',
5141
+ },
5142
+ newVersion: {
5143
+ type: 'boolean',
5144
+ description: '`true`: this deploy registered `version`; `false`: an earlier deploy did.',
5145
+ },
5146
+ pinChanges: {
5147
+ type: 'array',
5148
+ description: "For `pins-changed`: the pins that differ from `authoredVersion`'s.",
5149
+ items: { $ref: '#/components/schemas/PinChange' },
5150
+ },
5151
+ },
5152
+ };
5153
+
5154
+ export const PinChangeSchema: JsonSchema = {
5155
+ description: 'One pin that differs between two versions of an agent or a flow.',
5156
+ type: 'object',
5157
+ additionalProperties: false,
5158
+ required: ['kind', 'id'],
5159
+ properties: {
5160
+ kind: { type: 'string', enum: ['tool', 'prompt', 'setting', 'agent'] },
5161
+ id: { type: 'string' },
5162
+ from: { type: 'string', description: "The earlier version's pin; absent when it had none." },
5163
+ to: { type: 'string', description: "The later version's pin; absent when it has none." },
5164
+ },
5165
+ };
5166
+
4093
5167
  /**
4094
5168
  * Exactly what a deployment shipped. Versions are immutable, so this
4095
5169
  * says which code the deployment made live.
@@ -4101,8 +5175,8 @@ export const DeploymentContentsSchema: JsonSchema = {
4101
5175
  properties: {
4102
5176
  tools: { type: 'array', items: DeployedPrimitiveSchema },
4103
5177
  guardrails: { type: 'array', items: DeployedPrimitiveSchema },
4104
- agents: { type: 'array', items: DeployedPrimitiveSchema },
4105
- flows: { type: 'array', items: DeployedPrimitiveSchema },
5178
+ agents: { type: 'array', items: DeployedVersionSchema },
5179
+ flows: { type: 'array', items: DeployedVersionSchema },
4106
5180
  },
4107
5181
  };
4108
5182
 
@@ -5844,6 +6918,20 @@ export const WebhookEndpointUnregisterResultSchema: JsonSchema = {
5844
6918
  },
5845
6919
  };
5846
6920
 
6921
+ /** A run tree's model calls, as `run.finished` carries them. */
6922
+ export const RunTreeUsageSchema: JsonSchema = {
6923
+ type: 'object',
6924
+ additionalProperties: false,
6925
+ required: ['calls', 'costUsd', 'tokens'],
6926
+ description:
6927
+ "The model calls of the run tree (this run and every run it started) that the cost ledger had recorded when this run finished: a child run still running then isn't in it. `calls` counts failed calls too. Absent when the runtime records no usage.",
6928
+ properties: {
6929
+ calls: { type: 'integer', minimum: 0 },
6930
+ costUsd: { type: 'number', minimum: 0 },
6931
+ tokens: { $ref: '#/components/schemas/CostTokenTotals' },
6932
+ },
6933
+ };
6934
+
5847
6935
  export const FinishedRunSchema: JsonSchema = {
5848
6936
  type: 'object',
5849
6937
  additionalProperties: false,
@@ -5873,6 +6961,7 @@ export const FinishedRunSchema: JsonSchema = {
5873
6961
  },
5874
6962
  createdAt: { type: 'string', format: 'date-time' },
5875
6963
  completedAt: { type: 'string', format: 'date-time' },
6964
+ usage: { $ref: '#/components/schemas/RunTreeUsage' },
5876
6965
  },
5877
6966
  };
5878
6967
 
@@ -6020,6 +7109,7 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6020
7109
  ['WireError', WireErrorSchema],
6021
7110
  ['HealthResult', HealthResultSchema],
6022
7111
  ['RunStatus', RunStatusSchema],
7112
+ ['RunAgent', RunAgentSchema],
6023
7113
  ['Run', RunSchema],
6024
7114
  ['StartRunOptions', StartRunOptionsSchema],
6025
7115
  ['StartRunBody', StartRunBodySchema],
@@ -6047,6 +7137,7 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6047
7137
  ['ApprovalStatus', ApprovalStatusSchema],
6048
7138
  ['ReviewDecisionKind', ReviewDecisionKindSchema],
6049
7139
  ['Approval', ApprovalSchema],
7140
+ ['ApprovalDecisionRecord', ApprovalDecisionRecordSchema],
6050
7141
  ['ReviewDecision', ReviewDecisionSchema],
6051
7142
  ['ApprovalCollectionPage', ApprovalCollectionPageSchema],
6052
7143
  ['CompleteApprovalBody', CompleteApprovalBodySchema],
@@ -6060,6 +7151,27 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6060
7151
  ['ObservationStatus', ObservationStatusSchema],
6061
7152
  ['Observation', ObservationSchema],
6062
7153
  ['ObservationCollectionPage', ObservationCollectionPageSchema],
7154
+ ['JudgeClassScope', JudgeClassScopeSchema],
7155
+ ['JudgeClass', JudgeClassSchema],
7156
+ ['JudgeClassCollectionPage', JudgeClassCollectionPageSchema],
7157
+ ['CreateJudgeClassBody', CreateJudgeClassBodySchema],
7158
+ ['UpdateJudgeClassBody', UpdateJudgeClassBodySchema],
7159
+ ['UnregisterJudgeClassResult', UnregisterJudgeClassResultSchema],
7160
+ ['JudgedSubject', JudgedSubjectSchema],
7161
+ ['JudgedItem', JudgedItemSchema],
7162
+ ['JudgmentAssertedBy', JudgmentAssertedBySchema],
7163
+ ['Judgment', JudgmentSchema],
7164
+ ['JudgedRunContext', JudgedRunContextSchema],
7165
+ ['JudgedRunCopy', JudgedRunCopySchema],
7166
+ ['JudgmentWithCopies', JudgmentWithCopiesSchema],
7167
+ ['JudgmentCollectionPage', JudgmentCollectionPageSchema],
7168
+ ['CreateJudgmentBody', CreateJudgmentBodySchema],
7169
+ ['UnregisterJudgmentResult', UnregisterJudgmentResultSchema],
7170
+ ['JudgedItemSummary', JudgedItemSummarySchema],
7171
+ ['JudgedEvalCase', JudgedEvalCaseSchema],
7172
+ ['JudgedEvalCaseCollectionPage', JudgedEvalCaseCollectionPageSchema],
7173
+ ['BuildJudgedSuiteBody', BuildJudgedSuiteBodySchema],
7174
+ ['BuildJudgedSuiteResult', BuildJudgedSuiteResultSchema],
6063
7175
  ['PromptParameter', PromptParameterSchema],
6064
7176
  ['RetrievalIntent', RetrievalIntentSchema],
6065
7177
  ['ConversationPolicy', ConversationPolicySchema],
@@ -6069,6 +7181,14 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6069
7181
  ['AgentOutputSpec', AgentOutputSpecSchema],
6070
7182
  ['ToolErrorsSpec', ToolErrorsSpecSchema],
6071
7183
  ['Agent', AgentSchema],
7184
+ ['AgentPins', AgentPinsSchema],
7185
+ ['PromptRef', PromptRefSchema],
7186
+ ['BlockRef', BlockRefSchema],
7187
+ ['PinChange', PinChangeSchema],
7188
+ ['VersionDerivation', VersionDerivationSchema],
7189
+ ['DeriveAgentVersionBody', DeriveAgentVersionBodySchema],
7190
+ ['AgentPinSwaps', AgentPinSwapsSchema],
7191
+ ['FlowPins', FlowPinsSchema],
6072
7192
  ['PublishAgentBody', PublishAgentBodySchema],
6073
7193
  ['PublishAgentResult', PublishAgentResultSchema],
6074
7194
  ['UnregisterAgentResult', UnregisterAgentResultSchema],
@@ -6190,6 +7310,9 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6190
7310
  ['GetMCPPromptResult', GetMCPPromptResultSchema],
6191
7311
  ['CostGroupDimension', CostGroupDimensionSchema],
6192
7312
  ['CostRecord', CostRecordSchema],
7313
+ ['ModelCallTokens', ModelCallTokensSchema],
7314
+ ['ModelCallError', ModelCallErrorSchema],
7315
+ ['CostTokenTotals', CostTokenTotalsSchema],
6193
7316
  ['CostRecordCollectionPage', CostRecordCollectionPageSchema],
6194
7317
  ['CostAggregateGroup', CostAggregateGroupSchema],
6195
7318
  ['CostAggregateResult', CostAggregateResultSchema],
@@ -6215,9 +7338,20 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6215
7338
  ['PublishEvalSuiteResult', PublishEvalSuiteResultSchema],
6216
7339
  ['UnregisterEvalSuiteResult', UnregisterEvalSuiteResultSchema],
6217
7340
  ['ReinstateEvalSuiteVersionResult', ReinstateEvalSuiteVersionResultSchema],
7341
+ ['BlockKind', BlockKindSchema],
7342
+ ['PromptBlockContent', PromptBlockContentSchema],
7343
+ ['SettingsBlockContent', SettingsBlockContentSchema],
7344
+ ['Block', BlockSchema],
7345
+ ['BlockCollectionPage', BlockCollectionPageSchema],
7346
+ ['PublishBlockBody', PublishBlockBodySchema],
7347
+ ['PublishBlockResult', PublishBlockResultSchema],
7348
+ ['UnregisterBlockResult', UnregisterBlockResultSchema],
7349
+ ['ReinstateBlockResult', ReinstateBlockResultSchema],
6218
7350
  ['EvalRunStatus', EvalRunStatusSchema],
6219
7351
  ['EvalRunAgentRef', EvalRunAgentRefSchema],
6220
7352
  ['EvalRunFlowRef', EvalRunFlowRefSchema],
7353
+ ['EvalBaseline', EvalBaselineSchema],
7354
+ ['EvalComparison', EvalComparisonSchema],
6221
7355
  ['EvalRun', EvalRunSchema],
6222
7356
  ['EvalRunCollectionPage', EvalRunCollectionPageSchema],
6223
7357
  ['StartEvalRunBody', StartEvalRunBodySchema],
@@ -6348,6 +7482,7 @@ export const COMPONENT_SCHEMAS: ReadonlyArray<readonly [string, JsonSchema]> = [
6348
7482
  ['CreateWebhookEndpointBody', CreateWebhookEndpointBodySchema],
6349
7483
  ['PatchWebhookEndpointBody', PatchWebhookEndpointBodySchema],
6350
7484
  ['WebhookEndpointUnregisterResult', WebhookEndpointUnregisterResultSchema],
7485
+ ['RunTreeUsage', RunTreeUsageSchema],
6351
7486
  ['FinishedRun', FinishedRunSchema],
6352
7487
  ['RunFinishedEvent', RunFinishedEventSchema],
6353
7488
  ['WebhookTestEvent', WebhookTestEventSchema],