@sixb/core 0.1.3 → 0.1.5

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 (271) hide show
  1. package/dist/actions/index.d.ts +2 -2
  2. package/dist/actions/index.d.ts.map +1 -1
  3. package/dist/actions/index.js +17 -18
  4. package/dist/actions/index.js.map +1 -1
  5. package/dist/actions/read-facade.d.ts +10 -2
  6. package/dist/actions/read-facade.d.ts.map +1 -1
  7. package/dist/actions/types/context.d.ts +45 -2
  8. package/dist/actions/types/context.d.ts.map +1 -1
  9. package/dist/actions/worker.js +4 -4
  10. package/dist/actions/worker.js.map +1 -1
  11. package/dist/agents/context-compaction.d.ts +40 -0
  12. package/dist/agents/context-compaction.d.ts.map +1 -0
  13. package/dist/agents/ids.d.ts +2 -0
  14. package/dist/agents/ids.d.ts.map +1 -1
  15. package/dist/agents/index.d.ts +6 -5
  16. package/dist/agents/index.d.ts.map +1 -1
  17. package/dist/agents/index.js +42 -37
  18. package/dist/agents/index.js.map +1 -1
  19. package/dist/agents/streams.d.ts +17 -1
  20. package/dist/agents/streams.d.ts.map +1 -1
  21. package/dist/agents/streams.js +4 -2
  22. package/dist/agents/streams.js.map +1 -1
  23. package/dist/agents/types.d.ts +11 -0
  24. package/dist/agents/types.d.ts.map +1 -1
  25. package/dist/agents/validation.d.ts +1 -1
  26. package/dist/agents/validation.d.ts.map +1 -1
  27. package/dist/auth/index.js +7 -3
  28. package/dist/auth/index.js.map +1 -1
  29. package/dist/authorization/index.js +6 -2
  30. package/dist/authorization/index.js.map +1 -1
  31. package/dist/bootstrap/index.js +30 -31
  32. package/dist/bootstrap/index.js.map +1 -1
  33. package/dist/{chunk-d6y2wsfg.js → chunk-1q02e95s.js} +12 -7
  34. package/dist/{chunk-d6y2wsfg.js.map → chunk-1q02e95s.js.map} +4 -3
  35. package/dist/{chunk-c6cfqydk.js → chunk-4h947jd8.js} +1 -1
  36. package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
  37. package/dist/{chunk-f1cyvnrk.js → chunk-6d5xdj1q.js} +259 -9
  38. package/dist/chunk-6d5xdj1q.js.map +14 -0
  39. package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
  40. package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +3 -3
  41. package/dist/{chunk-ttba8x6z.js → chunk-78c6xvyr.js} +68 -3
  42. package/dist/chunk-78c6xvyr.js.map +15 -0
  43. package/dist/{chunk-wb4051cx.js → chunk-819wnjz8.js} +11 -5
  44. package/dist/chunk-819wnjz8.js.map +12 -0
  45. package/dist/{chunk-177ed2mp.js → chunk-84h6qhmp.js} +233 -97
  46. package/dist/{chunk-177ed2mp.js.map → chunk-84h6qhmp.js.map} +9 -9
  47. package/dist/{chunk-pxtrxm3p.js → chunk-a09jx26t.js} +1 -1
  48. package/dist/{chunk-bv41fmjn.js → chunk-am6eczah.js} +59 -22
  49. package/dist/{chunk-bv41fmjn.js.map → chunk-am6eczah.js.map} +8 -7
  50. package/dist/{chunk-zpw39qhj.js → chunk-dm72y8wt.js} +25 -2
  51. package/dist/chunk-dm72y8wt.js.map +10 -0
  52. package/dist/{chunk-kqxgf6kv.js → chunk-drjqm1aa.js} +16 -1
  53. package/dist/{chunk-kqxgf6kv.js.map → chunk-drjqm1aa.js.map} +3 -3
  54. package/dist/chunk-dysw7nsm.js.map +1 -1
  55. package/dist/{chunk-4p9rh7jj.js → chunk-ea73pzk7.js} +1 -1
  56. package/dist/{chunk-4aw0jwk0.js → chunk-f6erf2vv.js} +1 -1
  57. package/dist/{chunk-4z3n1dzt.js → chunk-f83ka50g.js} +131 -25
  58. package/dist/chunk-f83ka50g.js.map +23 -0
  59. package/dist/{chunk-c8bw2b6c.js → chunk-gadsm794.js} +2 -2
  60. package/dist/{chunk-1ywq4hzk.js → chunk-h6h91mfy.js} +8 -10
  61. package/dist/{chunk-1ywq4hzk.js.map → chunk-h6h91mfy.js.map} +2 -2
  62. package/dist/{chunk-n5x5y80a.js → chunk-nzw7sm3b.js} +2 -2
  63. package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
  64. package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
  65. package/dist/{chunk-261ag4t4.js → chunk-r0rry8dn.js} +3 -3
  66. package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
  67. package/dist/chunk-rte5sm3z.js.map +12 -0
  68. package/dist/chunk-t0jjkep3.js.map +1 -1
  69. package/dist/{chunk-ettb0cy4.js → chunk-tbv03sx2.js} +59 -29
  70. package/dist/{chunk-ettb0cy4.js.map → chunk-tbv03sx2.js.map} +5 -5
  71. package/dist/{chunk-d2adj15j.js → chunk-tkdscva6.js} +1 -1
  72. package/dist/{chunk-xmggaxg4.js → chunk-v0egge8b.js} +201 -38
  73. package/dist/{chunk-xmggaxg4.js.map → chunk-v0egge8b.js.map} +8 -6
  74. package/dist/{chunk-z8j83gzd.js → chunk-x2yw73hy.js} +1 -1
  75. package/dist/{chunk-qer6am8w.js → chunk-xdf9yswn.js} +1 -1
  76. package/dist/{chunk-3rsf30p4.js → chunk-z3ga9q5m.js} +18 -21
  77. package/dist/{chunk-3rsf30p4.js.map → chunk-z3ga9q5m.js.map} +4 -5
  78. package/dist/{chunk-km4rkj4t.js → chunk-zp2v2rv6.js} +3 -3
  79. package/dist/execution/agent.js +26 -27
  80. package/dist/execution/agent.js.map +1 -1
  81. package/dist/execution/primitive.js +26 -27
  82. package/dist/execution/primitive.js.map +2 -2
  83. package/dist/execution/request.js +27 -28
  84. package/dist/execution/request.js.map +2 -2
  85. package/dist/http/index.js +1 -1
  86. package/dist/index.d.ts +6 -5
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +54 -55
  89. package/dist/index.js.map +1 -1
  90. package/dist/lake-storage/types.d.ts +2 -1
  91. package/dist/lake-storage/types.d.ts.map +1 -1
  92. package/dist/materializer/index.js +15 -16
  93. package/dist/materializer/index.js.map +1 -1
  94. package/dist/models/index.d.ts +40 -0
  95. package/dist/models/index.d.ts.map +1 -0
  96. package/dist/objects/execution.d.ts +6 -1
  97. package/dist/objects/execution.d.ts.map +1 -1
  98. package/dist/objects/index.js +19 -20
  99. package/dist/objects/index.js.map +1 -1
  100. package/dist/objects/link/endpoints.d.ts.map +1 -1
  101. package/dist/objects/query/executor.d.ts +1 -0
  102. package/dist/objects/query/executor.d.ts.map +1 -1
  103. package/dist/objects/query/explain.d.ts +1 -0
  104. package/dist/objects/query/explain.d.ts.map +1 -1
  105. package/dist/objects/query/index.d.ts +3 -1
  106. package/dist/objects/query/index.d.ts.map +1 -1
  107. package/dist/objects/query/index.js +30 -5
  108. package/dist/objects/query/index.js.map +1 -1
  109. package/dist/objects/query/ir.d.ts +14 -1
  110. package/dist/objects/query/ir.d.ts.map +1 -1
  111. package/dist/objects/query/links.d.ts +25 -0
  112. package/dist/objects/query/links.d.ts.map +1 -0
  113. package/dist/objects/query/normalize.d.ts.map +1 -1
  114. package/dist/objects/query/planner.d.ts.map +1 -1
  115. package/dist/objects/query/validate.d.ts +1 -0
  116. package/dist/objects/query/validate.d.ts.map +1 -1
  117. package/dist/ontology/internal.d.ts +1 -1
  118. package/dist/ontology/internal.d.ts.map +1 -1
  119. package/dist/ontology/internal.js +14 -6
  120. package/dist/ontology/internal.js.map +3 -3
  121. package/dist/ontology/json-schema.d.ts +10 -0
  122. package/dist/ontology/json-schema.d.ts.map +1 -1
  123. package/dist/pipelines/index.js +15 -16
  124. package/dist/pipelines/index.js.map +1 -1
  125. package/dist/projections/builders.d.ts +33 -4
  126. package/dist/projections/builders.d.ts.map +1 -1
  127. package/dist/projections/index.d.ts +1 -1
  128. package/dist/projections/index.d.ts.map +1 -1
  129. package/dist/projections/internal.js +15 -16
  130. package/dist/projections/internal.js.map +1 -1
  131. package/dist/projections/run-dispatch.d.ts +1 -0
  132. package/dist/projections/run-dispatch.d.ts.map +1 -1
  133. package/dist/projections/types.d.ts +12 -9
  134. package/dist/projections/types.d.ts.map +1 -1
  135. package/dist/projections/validation.d.ts +6 -5
  136. package/dist/projections/validation.d.ts.map +1 -1
  137. package/dist/query.d.ts +2 -1
  138. package/dist/query.d.ts.map +1 -1
  139. package/dist/query.js +2 -2
  140. package/dist/runtime/create.d.ts +3 -0
  141. package/dist/runtime/create.d.ts.map +1 -1
  142. package/dist/runtime/definitions.d.ts +3 -0
  143. package/dist/runtime/definitions.d.ts.map +1 -1
  144. package/dist/runtime/host.d.ts +2 -0
  145. package/dist/runtime/host.d.ts.map +1 -1
  146. package/dist/runtime/resolve-definitions.d.ts +2 -0
  147. package/dist/runtime/resolve-definitions.d.ts.map +1 -1
  148. package/dist/storage/agents/in-memory.d.ts +4 -0
  149. package/dist/storage/agents/in-memory.d.ts.map +1 -1
  150. package/dist/storage/agents/provider.js +9 -5
  151. package/dist/storage/agents/provider.js.map +1 -1
  152. package/dist/storage/agents/types.d.ts +5 -0
  153. package/dist/storage/agents/types.d.ts.map +1 -1
  154. package/dist/storage/ai-cost/provider.js +1 -1
  155. package/dist/storage/ai-usage/in-memory.d.ts +2 -1
  156. package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
  157. package/dist/storage/ai-usage/index.d.ts +1 -1
  158. package/dist/storage/ai-usage/index.d.ts.map +1 -1
  159. package/dist/storage/ai-usage/types.d.ts +6 -0
  160. package/dist/storage/ai-usage/types.d.ts.map +1 -1
  161. package/dist/storage/index.d.ts +3 -2
  162. package/dist/storage/index.d.ts.map +1 -1
  163. package/dist/storage/index.js +19 -14
  164. package/dist/storage/index.js.map +1 -1
  165. package/dist/storage/objects/in-memory.d.ts +6 -3
  166. package/dist/storage/objects/in-memory.d.ts.map +1 -1
  167. package/dist/storage/objects/index.d.ts +3 -1
  168. package/dist/storage/objects/index.d.ts.map +1 -1
  169. package/dist/storage/objects/keys.d.ts +16 -0
  170. package/dist/storage/objects/keys.d.ts.map +1 -0
  171. package/dist/storage/objects/types.d.ts +33 -6
  172. package/dist/storage/objects/types.d.ts.map +1 -1
  173. package/dist/storage/ontology/provider.js +1 -1
  174. package/dist/storage/workflow-runs/provider.js +9 -5
  175. package/dist/storage/workflow-runs/provider.js.map +1 -1
  176. package/dist/syncs/index.js +15 -16
  177. package/dist/syncs/index.js.map +1 -1
  178. package/dist/testing/agent-storage-contract.d.ts.map +1 -1
  179. package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
  180. package/dist/testing/effective-storage-contract.d.ts +1 -1
  181. package/dist/testing/effective-storage-contract.d.ts.map +1 -1
  182. package/dist/testing/index.js +455 -40
  183. package/dist/testing/index.js.map +7 -7
  184. package/dist/testing/lake-storage-contract.d.ts.map +1 -1
  185. package/dist/testing/object-query-contract.d.ts +1 -1
  186. package/dist/testing/object-query-contract.d.ts.map +1 -1
  187. package/dist/webhooks/internal.js +13 -14
  188. package/dist/webhooks/internal.js.map +2 -2
  189. package/dist/workflows/index.js +27 -28
  190. package/dist/workflows/index.js.map +1 -1
  191. package/package.json +1 -1
  192. package/src/actions/index.ts +10 -1
  193. package/src/actions/read-facade.ts +125 -3
  194. package/src/actions/types/context.ts +69 -2
  195. package/src/agents/builders.ts +3 -3
  196. package/src/agents/context-compaction.ts +261 -0
  197. package/src/agents/ids.ts +5 -0
  198. package/src/agents/index.ts +18 -9
  199. package/src/agents/streams.ts +56 -0
  200. package/src/agents/types.ts +12 -0
  201. package/src/agents/validation.ts +39 -5
  202. package/src/http/api-routes.ts +7 -7
  203. package/src/index.ts +19 -0
  204. package/src/lake-storage/types.ts +2 -1
  205. package/src/materializer/telemetry/append.ts +33 -16
  206. package/src/models/index.ts +71 -0
  207. package/src/objects/execution.ts +20 -0
  208. package/src/objects/link/endpoints.ts +2 -1
  209. package/src/objects/query/executor.ts +42 -11
  210. package/src/objects/query/explain.ts +11 -0
  211. package/src/objects/query/index.ts +6 -0
  212. package/src/objects/query/ir.ts +16 -0
  213. package/src/objects/query/links.ts +308 -0
  214. package/src/objects/query/normalize.ts +40 -1
  215. package/src/objects/query/planner.ts +5 -0
  216. package/src/objects/query/validate.ts +58 -2
  217. package/src/ontology/internal.ts +1 -1
  218. package/src/ontology/json-schema.ts +27 -5
  219. package/src/projections/builders.ts +220 -15
  220. package/src/projections/index.ts +1 -0
  221. package/src/projections/ownership.ts +5 -5
  222. package/src/projections/registry.ts +9 -3
  223. package/src/projections/revision.ts +31 -5
  224. package/src/projections/run-dispatch.ts +10 -1
  225. package/src/projections/types.ts +13 -9
  226. package/src/projections/validation.ts +61 -19
  227. package/src/query.ts +2 -0
  228. package/src/runtime/create.ts +4 -0
  229. package/src/runtime/definitions.ts +3 -0
  230. package/src/runtime/host.ts +2 -0
  231. package/src/runtime/resolve-definitions.ts +28 -0
  232. package/src/storage/agents/in-memory.ts +15 -0
  233. package/src/storage/agents/types.ts +5 -0
  234. package/src/storage/ai-usage/in-memory.ts +23 -0
  235. package/src/storage/ai-usage/index.ts +1 -0
  236. package/src/storage/ai-usage/types.ts +10 -0
  237. package/src/storage/index.ts +11 -0
  238. package/src/storage/objects/in-memory.ts +103 -16
  239. package/src/storage/objects/index.ts +9 -0
  240. package/src/storage/objects/keys.ts +36 -0
  241. package/src/storage/objects/types.ts +34 -6
  242. package/src/storage/ontology/provider-header-validation.ts +2 -2
  243. package/src/storage/timeseries/store.ts +6 -6
  244. package/src/testing/agent-storage-contract.ts +12 -0
  245. package/src/testing/ai-usage-storage-contract.ts +35 -0
  246. package/src/testing/effective-storage-contract.ts +194 -4
  247. package/src/testing/lake-storage-contract.ts +56 -0
  248. package/src/testing/object-query-contract.ts +208 -1
  249. package/dist/agents/prompt.d.ts +0 -21
  250. package/dist/agents/prompt.d.ts.map +0 -1
  251. package/dist/chunk-4z3n1dzt.js.map +0 -23
  252. package/dist/chunk-6wetht33.js +0 -89
  253. package/dist/chunk-6wetht33.js.map +0 -10
  254. package/dist/chunk-88ppkr54.js.map +0 -12
  255. package/dist/chunk-f1cyvnrk.js.map +0 -13
  256. package/dist/chunk-ttba8x6z.js.map +0 -15
  257. package/dist/chunk-wb4051cx.js.map +0 -12
  258. package/dist/chunk-zpw39qhj.js.map +0 -10
  259. package/src/agents/prompt.ts +0 -85
  260. /package/dist/{chunk-c6cfqydk.js.map → chunk-4h947jd8.js.map} +0 -0
  261. /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
  262. /package/dist/{chunk-pxtrxm3p.js.map → chunk-a09jx26t.js.map} +0 -0
  263. /package/dist/{chunk-4p9rh7jj.js.map → chunk-ea73pzk7.js.map} +0 -0
  264. /package/dist/{chunk-4aw0jwk0.js.map → chunk-f6erf2vv.js.map} +0 -0
  265. /package/dist/{chunk-c8bw2b6c.js.map → chunk-gadsm794.js.map} +0 -0
  266. /package/dist/{chunk-n5x5y80a.js.map → chunk-nzw7sm3b.js.map} +0 -0
  267. /package/dist/{chunk-261ag4t4.js.map → chunk-r0rry8dn.js.map} +0 -0
  268. /package/dist/{chunk-d2adj15j.js.map → chunk-tkdscva6.js.map} +0 -0
  269. /package/dist/{chunk-z8j83gzd.js.map → chunk-x2yw73hy.js.map} +0 -0
  270. /package/dist/{chunk-qer6am8w.js.map → chunk-xdf9yswn.js.map} +0 -0
  271. /package/dist/{chunk-km4rkj4t.js.map → chunk-zp2v2rv6.js.map} +0 -0
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/http/api-routes.ts", "../src/http/route-pattern.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * The single source of truth for the Sixb HTTP API surface and its auth capabilities.\n *\n * Two views are derived from this one table:\n * - `AGENT_API_ROUTES` (@sixb/core agent gateway) = the `agentApi` rows, projected to {method, path}.\n * - `ACCESS_TOKEN_ROUTES` (@sixb/server bearer boundary) = the `accessToken` rows, with operationId.\n *\n * Because both views are projections of this table, the agent gateway allow-list is structurally a\n * subset of the bearer boundary — the invariant below enforces `agentApi ⇒ accessToken` at load\n * time. This table lives in @sixb/core (never @sixb/server) because @sixb/server depends on core,\n * not the reverse; the operationId strings are opaque here.\n */\nexport interface SixbApiRoute {\n /** OpenAPI operationId — the server keys its bearer security requirement off this. */\n readonly operationId: string\n readonly method: string\n readonly path: string\n /** The route accepts a bearer access token (enforced by the server access-token boundary). */\n readonly accessToken: boolean\n /** The route is proxied by the agent API gateway (a strict subset of the accessToken routes). */\n readonly agentApi: boolean\n}\n\nexport const SIXB_API_ROUTES: readonly SixbApiRoute[] = [\n {\n operationId: \"getProjectInfo\",\n method: \"GET\",\n path: \"/api/project\",\n accessToken: true,\n agentApi: true,\n },\n // Token and service-account management is bearer-capable so the CLI can authenticate with a\n // personal access token. It is NOT exposed to agents. The runtime still confines every operation\n // to the caller's own groups, and service-account tokens are rejected (only user principals may\n // manage credentials).\n {\n operationId: \"getAuthAccessManagementOptions\",\n method: \"GET\",\n path: \"/api/auth/access-management-options\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthAccessTokens\",\n method: \"GET\",\n path: \"/api/auth/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthPersonalAccessToken\",\n method: \"POST\",\n path: \"/api/auth/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"revokeAuthAccessToken\",\n method: \"POST\",\n path: \"/api/auth/access-tokens/:tokenId/revoke\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthServiceAccounts\",\n method: \"GET\",\n path: \"/api/auth/service-accounts\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthServiceAccount\",\n method: \"POST\",\n path: \"/api/auth/service-accounts\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"disableAuthServiceAccount\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/disable\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthServiceAccountAccessTokens\",\n method: \"GET\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthServiceAccountAccessToken\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"revokeAuthServiceAccountAccessToken\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens/:tokenId/revoke\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listObjectTypes\",\n method: \"GET\",\n path: \"/api/object-types\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObjectType\",\n method: \"GET\",\n path: \"/api/object-types/:objectTypeId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listObjects\",\n method: \"GET\",\n path: \"/api/objects\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"queryObjects\",\n method: \"POST\",\n path: \"/api/objects/query\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"countObjects\",\n method: \"POST\",\n path: \"/api/objects/query/count\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"existsObjects\",\n method: \"POST\",\n path: \"/api/objects/query/exists\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"facetObjects\",\n method: \"POST\",\n path: \"/api/objects/query/facets\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObject\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listObjectLinks\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/links\",\n accessToken: true,\n agentApi: true,\n },\n // The four write routes. Bearer-capable because their execution facade enforces authorization\n // (`edit:object` / `append:telemetry`), which is exactly the precondition this table requires.\n // NOT agent-proxied: letting an agent turn write objects on its own is a separate decision, and\n // the gateway already hands routes an execution SDK, so flipping `agentApi` later needs no\n // authorization work — only that decision.\n {\n operationId: \"upsertObject\",\n method: \"PUT\",\n path: \"/api/objects/:objectTypeId/:objectId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"upsertObjectLink\",\n method: \"PUT\",\n path: \"/api/objects/:objectTypeId/:objectId/links/:linkId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"removeObjectLink\",\n method: \"DELETE\",\n path: \"/api/objects/:objectTypeId/:objectId/links/:linkId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"appendTelemetry\",\n method: \"POST\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getBulkTelemetryHistory\",\n method: \"POST\",\n path: \"/api/telemetry/history\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getTelemetryHistory\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId/history\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getLatestTelemetry\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId/latest\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObjectFileContent\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n // Bearer-capable (CLI/programmatic existence + range probes) but NOT agent-proxied: the agent\n // API gateway only forwards GET/POST, and an agent gains nothing from HEAD over GET (a file's\n // size already travels in its FileRef). Keeping this agentApi:true would throw at gateway\n // registration (\"Unsupported agent API gateway method 'HEAD'\") and stop the server booting.\n operationId: \"headObjectFileContent\",\n method: \"HEAD\",\n path: \"/api/objects/:objectTypeId/:objectId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listActions\",\n method: \"GET\",\n path: \"/api/actions\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getAction\",\n method: \"GET\",\n path: \"/api/actions/:actionId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"requestAction\",\n method: \"POST\",\n path: \"/api/actions/:actionId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"uploadFileRaw\",\n method: \"POST\",\n path: \"/api/files\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listActionRuns\",\n method: \"GET\",\n path: \"/api/action-runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getActionRun\",\n method: \"GET\",\n path: \"/api/action-runs/:runId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getActionRunFileContent\",\n method: \"GET\",\n path: \"/api/action-runs/:runId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headActionRunFileContent\",\n method: \"HEAD\",\n path: \"/api/action-runs/:runId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listWorkflows\",\n method: \"GET\",\n path: \"/api/workflows\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getWorkflow\",\n method: \"GET\",\n path: \"/api/workflows/:workflowId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"requestWorkflowRun\",\n method: \"POST\",\n path: \"/api/workflows/:workflowId/runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listWorkflowRuns\",\n method: \"GET\",\n path: \"/api/workflow-runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getWorkflowRun\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"cancelWorkflowRun\",\n method: \"POST\",\n path: \"/api/workflow-runs/:runId/cancel\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowAgentNodeExecution\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/agent-execution\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowRunFileContent\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headWorkflowRunFileContent\",\n method: \"HEAD\",\n path: \"/api/workflow-runs/:runId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowNodeRunFileContent\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"headWorkflowNodeRunFileContent\",\n method: \"HEAD\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getAgentMessageFileContent\",\n method: \"GET\",\n path: \"/api/agent-threads/:threadId/messages/:messageId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headAgentMessageFileContent\",\n method: \"HEAD\",\n path: \"/api/agent-threads/:threadId/messages/:messageId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"searchObjects\",\n method: \"GET\",\n path: \"/api/objects/search\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listEvents\",\n method: \"GET\",\n path: \"/api/events\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listLogs\",\n method: \"GET\",\n path: \"/api/logs\",\n accessToken: true,\n agentApi: false,\n },\n]\n\n// Enforce the subset invariant at module load: a gateway-proxied route must also be a bearer route,\n// or the gateway would expose a surface the access-token boundary does not recognize.\nfor (const route of SIXB_API_ROUTES) {\n if (route.agentApi && !route.accessToken) {\n throw new Error(\n `[Sixb] agent API route '${route.method} ${route.path}' must also be an access-token route.`\n )\n }\n}\n",
5
+ "/**\n * The single source of truth for the Sixb HTTP API surface and its auth capabilities.\n *\n * Two views are derived from this one table:\n * - `AGENT_API_ROUTES` (@sixb/core agent gateway) = the `agentApi` rows, projected to {method, path}.\n * - `ACCESS_TOKEN_ROUTES` (@sixb/server bearer boundary) = the `accessToken` rows, with operationId.\n *\n * Because both views are projections of this table, the agent gateway allow-list is structurally a\n * subset of the bearer boundary — the invariant below enforces `agentApi ⇒ accessToken` at load\n * time. This table lives in @sixb/core (never @sixb/server) because @sixb/server depends on core,\n * not the reverse; the operationId strings are opaque here.\n */\nexport interface SixbApiRoute {\n /** OpenAPI operationId — the server keys its bearer security requirement off this. */\n readonly operationId: string\n readonly method: string\n readonly path: string\n /** The route accepts a bearer access token (enforced by the server access-token boundary). */\n readonly accessToken: boolean\n /** The route is proxied by the agent API gateway (a strict subset of the accessToken routes). */\n readonly agentApi: boolean\n}\n\nexport const SIXB_API_ROUTES: readonly SixbApiRoute[] = [\n {\n operationId: \"getProjectInfo\",\n method: \"GET\",\n path: \"/api/project\",\n accessToken: true,\n agentApi: true,\n },\n // Token and service-account management is bearer-capable so the CLI can authenticate with a\n // personal access token. It is NOT exposed to agents. The runtime still confines every operation\n // to the caller's own groups, and service-account tokens are rejected (only user principals may\n // manage credentials).\n {\n operationId: \"getAuthAccessManagementOptions\",\n method: \"GET\",\n path: \"/api/auth/access-management-options\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthAccessTokens\",\n method: \"GET\",\n path: \"/api/auth/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthPersonalAccessToken\",\n method: \"POST\",\n path: \"/api/auth/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"revokeAuthAccessToken\",\n method: \"POST\",\n path: \"/api/auth/access-tokens/:tokenId/revoke\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthServiceAccounts\",\n method: \"GET\",\n path: \"/api/auth/service-accounts\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthServiceAccount\",\n method: \"POST\",\n path: \"/api/auth/service-accounts\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"disableAuthServiceAccount\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/disable\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listAuthServiceAccountAccessTokens\",\n method: \"GET\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"createAuthServiceAccountAccessToken\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"revokeAuthServiceAccountAccessToken\",\n method: \"POST\",\n path: \"/api/auth/service-accounts/:serviceAccountId/access-tokens/:tokenId/revoke\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listObjectTypes\",\n method: \"GET\",\n path: \"/api/object-types\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObjectType\",\n method: \"GET\",\n path: \"/api/object-types/:objectTypeId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listObjects\",\n method: \"GET\",\n path: \"/api/objects\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"queryObjects\",\n method: \"POST\",\n path: \"/api/objects/query\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"queryObjectLinks\",\n method: \"POST\",\n path: \"/api/objects/query/links\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"countObjects\",\n method: \"POST\",\n path: \"/api/objects/query/count\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"existsObjects\",\n method: \"POST\",\n path: \"/api/objects/query/exists\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"facetObjects\",\n method: \"POST\",\n path: \"/api/objects/query/facets\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObject\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId\",\n accessToken: true,\n agentApi: true,\n },\n // The four write routes. Bearer-capable because their execution facade enforces authorization\n // (`edit:object` / `append:telemetry`), which is exactly the precondition this table requires.\n // NOT agent-proxied: letting an agent turn write objects on its own is a separate decision, and\n // the gateway already hands routes an execution SDK, so flipping `agentApi` later needs no\n // authorization work — only that decision.\n {\n operationId: \"upsertObject\",\n method: \"PUT\",\n path: \"/api/objects/:objectTypeId/:objectId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"upsertObjectLink\",\n method: \"PUT\",\n path: \"/api/objects/:objectTypeId/:objectId/links/:linkId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"removeObjectLink\",\n method: \"DELETE\",\n path: \"/api/objects/:objectTypeId/:objectId/links/:linkId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"appendTelemetry\",\n method: \"POST\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getBulkTelemetryHistory\",\n method: \"POST\",\n path: \"/api/telemetry/history\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getTelemetryHistory\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId/history\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getLatestTelemetry\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/telemetry/:propertyId/latest\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getObjectFileContent\",\n method: \"GET\",\n path: \"/api/objects/:objectTypeId/:objectId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n // Bearer-capable (CLI/programmatic existence + range probes) but NOT agent-proxied: the agent\n // API gateway only forwards GET/POST, and an agent gains nothing from HEAD over GET (a file's\n // size already travels in its FileRef). Keeping this agentApi:true would throw at gateway\n // registration (\"Unsupported agent API gateway method 'HEAD'\") and stop the server booting.\n operationId: \"headObjectFileContent\",\n method: \"HEAD\",\n path: \"/api/objects/:objectTypeId/:objectId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listActions\",\n method: \"GET\",\n path: \"/api/actions\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getAction\",\n method: \"GET\",\n path: \"/api/actions/:actionId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"requestAction\",\n method: \"POST\",\n path: \"/api/actions/:actionId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"uploadFileRaw\",\n method: \"POST\",\n path: \"/api/files\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listActionRuns\",\n method: \"GET\",\n path: \"/api/action-runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getActionRun\",\n method: \"GET\",\n path: \"/api/action-runs/:runId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getActionRunFileContent\",\n method: \"GET\",\n path: \"/api/action-runs/:runId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headActionRunFileContent\",\n method: \"HEAD\",\n path: \"/api/action-runs/:runId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listWorkflows\",\n method: \"GET\",\n path: \"/api/workflows\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getWorkflow\",\n method: \"GET\",\n path: \"/api/workflows/:workflowId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"requestWorkflowRun\",\n method: \"POST\",\n path: \"/api/workflows/:workflowId/runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listWorkflowRuns\",\n method: \"GET\",\n path: \"/api/workflow-runs\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"getWorkflowRun\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"cancelWorkflowRun\",\n method: \"POST\",\n path: \"/api/workflow-runs/:runId/cancel\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowAgentNodeExecution\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/agent-execution\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowRunFileContent\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headWorkflowRunFileContent\",\n method: \"HEAD\",\n path: \"/api/workflow-runs/:runId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getWorkflowNodeRunFileContent\",\n method: \"GET\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"headWorkflowNodeRunFileContent\",\n method: \"HEAD\",\n path: \"/api/workflow-runs/:runId/nodes/:nodeKey/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"getAgentMessageFileContent\",\n method: \"GET\",\n path: \"/api/agent-threads/:threadId/messages/:messageId/files/content\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"headAgentMessageFileContent\",\n method: \"HEAD\",\n path: \"/api/agent-threads/:threadId/messages/:messageId/files/content\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"searchObjects\",\n method: \"GET\",\n path: \"/api/objects/search\",\n accessToken: true,\n agentApi: true,\n },\n {\n operationId: \"listEvents\",\n method: \"GET\",\n path: \"/api/events\",\n accessToken: true,\n agentApi: false,\n },\n {\n operationId: \"listLogs\",\n method: \"GET\",\n path: \"/api/logs\",\n accessToken: true,\n agentApi: false,\n },\n]\n\n// Enforce the subset invariant at module load: a gateway-proxied route must also be a bearer route,\n// or the gateway would expose a surface the access-token boundary does not recognize.\nfor (const route of SIXB_API_ROUTES) {\n if (route.agentApi && !route.accessToken) {\n throw new Error(\n `[Sixb] agent API route '${route.method} ${route.path}' must also be an access-token route.`\n )\n }\n}\n",
6
6
  "/**\n * Shared HTTP route-pattern matching. Used by both the agent API gateway allow-list (@sixb/core)\n * and the server's access-token boundary (@sixb/server) so the two never drift.\n */\n\n/** Split a path into its non-empty segments (drops leading/trailing/empty parts). */\nexport function pathSegmentsFor(pathname: string): string[] {\n return pathname.split(\"/\").filter(Boolean)\n}\n\n/**\n * Match a concrete pathname against a route pattern. A `:param` pattern segment matches any single\n * non-empty segment; every other segment must match exactly. Segment counts must be equal.\n */\nexport function matchesPathPattern(pathname: string, pattern: string): boolean {\n const pathSegments = pathSegmentsFor(pathname)\n const patternSegments = pathSegmentsFor(pattern)\n\n if (pathSegments.length !== patternSegments.length) {\n return false\n }\n\n return patternSegments.every((patternSegment, index) => {\n if (patternSegment.startsWith(\":\")) {\n return pathSegments[index] !== \"\"\n }\n return patternSegment === pathSegments[index]\n })\n}\n\n/** Strip a single trailing slash so `/api/foo` and `/api/foo/` compare equal (leaves \"/\" alone). */\nexport function normalizeRoutePath(pathname: string): string {\n if (pathname.length > 1 && pathname.endsWith(\"/\")) {\n return pathname.slice(0, -1)\n }\n return pathname\n}\n"
7
7
  ],
8
8
  "mappings": "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",
9
- "debugId": "613AC9C17AABC3E364756E2164756E21",
9
+ "debugId": "F7C55438F878304564756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -3,10 +3,10 @@ import {
3
3
  createPrimitiveExecutionRecord,
4
4
  ensureExecutionRecord,
5
5
  executionRecordInputFromRuntime
6
- } from "./chunk-4aw0jwk0.js";
6
+ } from "./chunk-f6erf2vv.js";
7
7
  import {
8
8
  PIPELINE_RUN_FAILURE_CODES
9
- } from "./chunk-xmggaxg4.js";
9
+ } from "./chunk-v0egge8b.js";
10
10
  import {
11
11
  PipelineRunError
12
12
  } from "./chunk-cy0n5dms.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-dsrkgtnh.js";
16
16
  import {
17
17
  assertAuthorized
18
- } from "./chunk-4z3n1dzt.js";
18
+ } from "./chunk-f83ka50g.js";
19
19
  import {
20
20
  createSixbError,
21
21
  toSixbFailure
@@ -51,6 +51,11 @@ function normalizeNode(query) {
51
51
  switch (query.kind) {
52
52
  case "start":
53
53
  return { ...query };
54
+ case "refs":
55
+ return {
56
+ kind: "refs",
57
+ refs: uniqueRefs(query.refs)
58
+ };
54
59
  case "filter":
55
60
  return normalizeFilter(query.input, query.predicate);
56
61
  case "text":
@@ -83,8 +88,9 @@ function normalizeNode(query) {
83
88
  }
84
89
  }
85
90
  function hoistExpand(query) {
86
- if (query.kind === "start" || query.kind === "set" || query.kind === "expand")
91
+ if (query.kind === "start" || query.kind === "refs" || query.kind === "set" || query.kind === "expand") {
87
92
  return query;
93
+ }
88
94
  if (query.input.kind !== "expand")
89
95
  return query;
90
96
  const inner = query.input;
@@ -225,6 +231,24 @@ function normalizeLimit(input, limit) {
225
231
  function uniqueStrings(values) {
226
232
  return [...new Set(values)];
227
233
  }
234
+ function uniqueRefs(refs) {
235
+ const seen = new Set;
236
+ const unique = refs.flatMap((ref) => {
237
+ const key = JSON.stringify([ref.objectTypeId, ref.primaryId]);
238
+ if (seen.has(key))
239
+ return [];
240
+ seen.add(key);
241
+ return [{ ...ref }];
242
+ });
243
+ return unique.sort((left, right) => compareStrings(left.objectTypeId, right.objectTypeId) || compareStrings(left.primaryId, right.primaryId));
244
+ }
245
+ function compareStrings(left, right) {
246
+ if (left < right)
247
+ return -1;
248
+ if (left > right)
249
+ return 1;
250
+ return 0;
251
+ }
228
252
  function uniqueStringRecord(record) {
229
253
  return Object.fromEntries(Object.entries(record).map(([objectTypeId, fields]) => [objectTypeId, uniqueStrings(fields)]));
230
254
  }
@@ -254,4 +278,4 @@ function appendNodeLines(node, lines, depth) {
254
278
 
255
279
  export { ObjectQueryValidationError, ObjectQueryPlanningError, ObjectQueryExecutionError, normalizeObjectQuery, normalizeObjectQueryPredicate, formatObjectQueryExplanation };
256
280
 
257
- //# debugId=623049810E5B19E064756E2164756E21
281
+ //# debugId=0FCE1B0193C4DA0664756E2164756E21
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/objects/query/errors.ts", "../src/objects/query/normalize.ts", "../src/objects/query/explain-format.ts"],
4
+ "sourcesContent": [
5
+ "import type { ObjectQueryValidationIssue } from \"./validate\"\n\nexport interface ObjectQueryPlanningIssue {\n path: string\n code: string\n message: string\n}\n\nexport class ObjectQueryValidationError extends Error {\n readonly name = \"ObjectQueryValidationError\"\n readonly issues: readonly ObjectQueryValidationIssue[]\n\n constructor(issues: readonly ObjectQueryValidationIssue[]) {\n super(formatQueryValidationMessage(issues))\n this.issues = issues\n }\n}\n\nexport class ObjectQueryPlanningError extends Error {\n readonly name = \"ObjectQueryPlanningError\"\n readonly issues: readonly ObjectQueryPlanningIssue[]\n\n constructor(issues: readonly ObjectQueryPlanningIssue[]) {\n super(formatQueryPlanningMessage(issues))\n this.issues = issues\n }\n}\n\nexport class ObjectQueryExecutionError extends Error {\n readonly name = \"ObjectQueryExecutionError\"\n readonly code: string\n readonly path?: string\n\n constructor(code: string, message: string, path?: string) {\n super(`[Sixb] Object query execution failed: ${message}`)\n this.code = code\n this.path = path\n }\n}\n\nfunction formatQueryValidationMessage(issues: readonly ObjectQueryValidationIssue[]): string {\n if (issues.length === 0) return \"[Sixb] Object query validation failed\"\n if (issues.length === 1) return `[Sixb] Object query validation failed: ${issues[0].message}`\n return `[Sixb] Object query validation failed with ${issues.length} issues: ${issues\n .map((issue) => issue.message)\n .join(\"; \")}`\n}\n\nfunction formatQueryPlanningMessage(issues: readonly ObjectQueryPlanningIssue[]): string {\n if (issues.length === 0) return \"[Sixb] Object query planning failed\"\n if (issues.length === 1) return `[Sixb] Object query planning failed: ${issues[0].message}`\n return `[Sixb] Object query planning failed with ${issues.length} issues: ${issues\n .map((issue) => issue.message)\n .join(\"; \")}`\n}\n",
6
+ "import type {\n ObjectExpansion,\n ObjectQuery,\n ObjectQueryPredicate,\n ObjectQuerySet,\n ObjectQuerySortField,\n} from \"./ir\"\n\n/**\n * Canonicalizes query trees before validation/planning so providers see a\n * stable shape regardless of how the typed builder assembled the query.\n *\n * `expand` is output-shaping, so it is hoisted to the outermost layer here: two\n * queries that differ only in where `.expand(...)` was chained normalize to the\n * same tree (and therefore the same cache key).\n */\nexport function normalizeObjectQuery(query: ObjectQuery): ObjectQuery {\n return hoistExpand(normalizeNode(query))\n}\n\nfunction normalizeNode(query: ObjectQuery): ObjectQuery {\n switch (query.kind) {\n case \"start\":\n return { ...query }\n case \"refs\":\n return {\n kind: \"refs\",\n refs: uniqueRefs(query.refs),\n }\n case \"filter\":\n return normalizeFilter(query.input, query.predicate)\n case \"text\":\n return {\n ...query,\n input: normalizeObjectQuery(query.input),\n fields: query.fields ? uniqueStrings(query.fields) : undefined,\n fieldsByObjectType: query.fieldsByObjectType\n ? uniqueStringRecord(query.fieldsByObjectType)\n : undefined,\n }\n case \"vector\":\n return { ...query, input: normalizeObjectQuery(query.input), vector: [...query.vector] }\n case \"traverse\":\n return { ...query, input: normalizeObjectQuery(query.input) }\n case \"set\":\n return normalizeSet(query)\n case \"sort\":\n return normalizeSort(query.input, query.fields)\n case \"limit\":\n return normalizeLimit(query.input, query.limit)\n case \"page\":\n return { ...query, input: normalizeObjectQuery(query.input) }\n case \"project\":\n return {\n ...query,\n input: normalizeObjectQuery(query.input),\n properties: query.properties ? uniqueStrings(query.properties) : undefined,\n }\n case \"expand\":\n return normalizeExpand(query.input, query.expansions)\n }\n}\n\n/**\n * Keeps `expand` at the outermost layer. A single-input wrapper sitting above an\n * `expand` is swapped so the `expand` wraps the (re-normalized) wrapper subtree;\n * re-normalizing collapses any nodes that became adjacent, and a wrapper that\n * lands above another `expand` is merged into one.\n */\nfunction hoistExpand(query: ObjectQuery): ObjectQuery {\n if (\n query.kind === \"start\" ||\n query.kind === \"refs\" ||\n query.kind === \"set\" ||\n query.kind === \"expand\"\n ) {\n return query\n }\n if (query.input.kind !== \"expand\") return query\n\n const inner = query.input\n const rebuilt = normalizeObjectQuery({ ...query, input: inner.input })\n if (rebuilt.kind === \"expand\") {\n return {\n kind: \"expand\",\n input: rebuilt.input,\n expansions: normalizeExpansions([...inner.expansions, ...rebuilt.expansions]),\n }\n }\n return { kind: \"expand\", input: rebuilt, expansions: inner.expansions }\n}\n\nfunction normalizeExpand(input: ObjectQuery, expansions: readonly ObjectExpansion[]): ObjectQuery {\n const normalizedInput = normalizeObjectQuery(input)\n const normalizedExpansions = normalizeExpansions(expansions)\n\n // A directly-nested expand (`a.expand(X).expand(Y)` builds\n // `expand(expand(start, [X]), [Y])`) collapses into one outermost expand.\n if (normalizedInput.kind === \"expand\") {\n return {\n kind: \"expand\",\n input: normalizedInput.input,\n expansions: normalizeExpansions([...normalizedInput.expansions, ...normalizedExpansions]),\n }\n }\n\n return { kind: \"expand\", input: normalizedInput, expansions: normalizedExpansions }\n}\n\nfunction normalizeExpansions(expansions: readonly ObjectExpansion[]): ObjectExpansion[] {\n const byKey = new Map<string, ObjectExpansion>()\n for (const expansion of expansions) {\n const normalized = normalizeExpansion(expansion)\n const key = expansionKey(normalized)\n const existing = byKey.get(key)\n byKey.set(key, existing ? mergeExpansion(existing, normalized) : normalized)\n }\n\n return [...byKey.values()].sort((a, b) => {\n const left = expansionKey(a)\n const right = expansionKey(b)\n return left < right ? -1 : left > right ? 1 : 0\n })\n}\n\nfunction normalizeExpansion(expansion: ObjectExpansion): ObjectExpansion {\n const nested = expansion.expand ? normalizeExpansions(expansion.expand) : []\n return {\n linkId: expansion.linkId,\n direction: expansion.direction,\n ...(expansion.sourceObjectTypeId !== undefined\n ? { sourceObjectTypeId: expansion.sourceObjectTypeId }\n : {}),\n ...(expansion.limit !== undefined ? { limit: expansion.limit } : {}),\n ...(expansion.orderBy ? { orderBy: expansion.orderBy.map((field) => ({ ...field })) } : {}),\n ...(nested.length > 0 ? { expand: nested } : {}),\n }\n}\n\n// Two expansions of the same link in the same direction are one hydration; their\n// nested expansions merge so the normalized tree never double-hydrates a link.\nfunction mergeExpansion(a: ObjectExpansion, b: ObjectExpansion): ObjectExpansion {\n const nested = normalizeExpansions([...(a.expand ?? []), ...(b.expand ?? [])])\n const { expand: _existing, ...base } = a\n return nested.length > 0 ? { ...base, expand: nested } : base\n}\n\nfunction expansionKey(expansion: ObjectExpansion): string {\n return `${expansion.direction}\\0${expansion.linkId}\\0${expansion.sourceObjectTypeId ?? \"\"}`\n}\n\nexport function normalizeObjectQueryPredicate(\n predicate: ObjectQueryPredicate\n): ObjectQueryPredicate {\n switch (predicate.op) {\n case \"and\":\n case \"or\": {\n const items = predicate.items.flatMap((item) => {\n const normalized = normalizeObjectQueryPredicate(item)\n if (normalized.op === predicate.op) return normalized.items\n return [normalized]\n })\n return items.length === 1 ? items[0] : { op: predicate.op, items }\n }\n case \"not\":\n return { op: \"not\", item: normalizeObjectQueryPredicate(predicate.item) }\n case \"in\":\n return { ...predicate, values: [...predicate.values] }\n default:\n return { ...predicate }\n }\n}\n\nfunction normalizeFilter(input: ObjectQuery, predicate: ObjectQueryPredicate): ObjectQuery {\n const normalizedInput = normalizeObjectQuery(input)\n const normalizedPredicate = normalizeObjectQueryPredicate(predicate)\n\n // Adjacent filters are equivalent to a single conjunction and are easier for\n // capability checks and providers to inspect.\n if (normalizedInput.kind === \"filter\") {\n return normalizeObjectQuery({\n kind: \"filter\",\n input: normalizedInput.input,\n predicate: {\n op: \"and\",\n items: [normalizedInput.predicate, normalizedPredicate],\n },\n })\n }\n\n return {\n kind: \"filter\",\n input: normalizedInput,\n predicate: normalizedPredicate,\n }\n}\n\nfunction normalizeSet(query: ObjectQuerySet): ObjectQuery {\n const inputs = query.inputs.flatMap((input) => {\n const normalized = normalizeObjectQuery(input)\n if (normalized.kind === \"set\" && normalized.op === query.op) return normalized.inputs\n return [normalized]\n })\n\n return { ...query, inputs }\n}\n\nfunction normalizeSort(input: ObjectQuery, fields: readonly ObjectQuerySortField[]): ObjectQuery {\n const normalizedInput = normalizeObjectQuery(input)\n const normalizedFields = fields.map((field) => ({ ...field }))\n\n // A later sort fully determines result order, so it replaces an adjacent sort.\n if (normalizedInput.kind === \"sort\") {\n return {\n kind: \"sort\",\n input: normalizedInput.input,\n fields: normalizedFields,\n }\n }\n\n return {\n kind: \"sort\",\n input: normalizedInput,\n fields: normalizedFields,\n }\n}\n\nfunction normalizeLimit(input: ObjectQuery, limit: number): ObjectQuery {\n const normalizedInput = normalizeObjectQuery(input)\n\n // Adjacent limits collapse to the stricter bound.\n if (normalizedInput.kind === \"limit\") {\n return {\n kind: \"limit\",\n input: normalizedInput.input,\n limit: Math.min(normalizedInput.limit, limit),\n }\n }\n\n return {\n kind: \"limit\",\n input: normalizedInput,\n limit,\n }\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n return [...new Set(values)]\n}\n\nfunction uniqueRefs(\n refs: readonly { objectTypeId: string; primaryId: string }[]\n): { objectTypeId: string; primaryId: string }[] {\n const seen = new Set<string>()\n const unique = refs.flatMap((ref) => {\n const key = JSON.stringify([ref.objectTypeId, ref.primaryId])\n if (seen.has(key)) return []\n seen.add(key)\n return [{ ...ref }]\n })\n\n // `refs` is an object-set source, not a positional batch response. Canonical\n // identity order makes equivalent sets normalize identically and matches the\n // default ordering used by provider query sources.\n return unique.sort(\n (left, right) =>\n compareStrings(left.objectTypeId, right.objectTypeId) ||\n compareStrings(left.primaryId, right.primaryId)\n )\n}\n\nfunction compareStrings(left: string, right: string): number {\n if (left < right) return -1\n if (left > right) return 1\n return 0\n}\n\nfunction uniqueStringRecord(\n record: Readonly<Record<string, readonly string[]>>\n): Record<string, string[]> {\n return Object.fromEntries(\n Object.entries(record).map(([objectTypeId, fields]) => [objectTypeId, uniqueStrings(fields)])\n )\n}\n",
7
+ "/**\n * Formatting for object query explanations.\n *\n * Lives apart from `explain.ts` so the fluent builder (and browser bundles\n * built on it) can import the formatter without pulling in the explanation\n * builder and its validation machinery.\n */\nimport type { ObjectQueryExplainNode, ObjectQueryExplanation } from \"./explain\"\n\nexport function formatObjectQueryExplanation(explanation: ObjectQueryExplanation): string {\n const lines: string[] = []\n const status =\n explanation.valid === undefined ? \"not validated\" : explanation.valid ? \"valid\" : \"invalid\"\n const result = explanation.result ? ` result=${explanation.result.objectTypeIds.join(\" | \")}` : \"\"\n\n lines.push(`ObjectQuery ${status}${result}`)\n appendNodeLines(explanation.tree, lines, 0)\n\n if (explanation.issues.length > 0) {\n lines.push(\"Issues:\")\n for (const issue of explanation.issues) {\n lines.push(`- ${issue.path} [${issue.code}] ${issue.message}`)\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction appendNodeLines(node: ObjectQueryExplainNode, lines: string[], depth: number): void {\n lines.push(`${\" \".repeat(depth)}- ${node.path} ${node.summary}`)\n for (const child of node.children) {\n appendNodeLines(child, lines, depth + 1)\n }\n}\n"
8
+ ],
9
+ "mappings": ";;AAQO,MAAM,mCAAmC,MAAM;AAAA,EAC3C,OAAO;AAAA,EACP;AAAA,EAET,WAAW,CAAC,QAA+C;AAAA,IACzD,MAAM,6BAA6B,MAAM,CAAC;AAAA,IAC1C,KAAK,SAAS;AAAA;AAElB;AAAA;AAEO,MAAM,iCAAiC,MAAM;AAAA,EACzC,OAAO;AAAA,EACP;AAAA,EAET,WAAW,CAAC,QAA6C;AAAA,IACvD,MAAM,2BAA2B,MAAM,CAAC;AAAA,IACxC,KAAK,SAAS;AAAA;AAElB;AAAA;AAEO,MAAM,kCAAkC,MAAM;AAAA,EAC1C,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EAET,WAAW,CAAC,MAAc,SAAiB,MAAe;AAAA,IACxD,MAAM,yCAAyC,SAAS;AAAA,IACxD,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO;AAAA;AAEhB;AAEA,SAAS,4BAA4B,CAAC,QAAuD;AAAA,EAC3F,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO;AAAA,EAChC,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,0CAA0C,OAAO,GAAG;AAAA,EACpF,OAAO,8CAA8C,OAAO,kBAAkB,OAC3E,IAAI,CAAC,UAAU,MAAM,OAAO,EAC5B,KAAK,IAAI;AAAA;AAGd,SAAS,0BAA0B,CAAC,QAAqD;AAAA,EACvF,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO;AAAA,EAChC,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,wCAAwC,OAAO,GAAG;AAAA,EAClF,OAAO,4CAA4C,OAAO,kBAAkB,OACzE,IAAI,CAAC,UAAU,MAAM,OAAO,EAC5B,KAAK,IAAI;AAAA;;;ACrCP,SAAS,oBAAoB,CAAC,OAAiC;AAAA,EACpE,OAAO,YAAY,cAAc,KAAK,CAAC;AAAA;AAGzC,SAAS,aAAa,CAAC,OAAiC;AAAA,EACtD,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,KAAK,MAAM;AAAA,SACf;AAAA,MACH,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,WAAW,MAAM,IAAI;AAAA,MAC7B;AAAA,SACG;AAAA,MACH,OAAO,gBAAgB,MAAM,OAAO,MAAM,SAAS;AAAA,SAChD;AAAA,MACH,OAAO;AAAA,WACF;AAAA,QACH,OAAO,qBAAqB,MAAM,KAAK;AAAA,QACvC,QAAQ,MAAM,SAAS,cAAc,MAAM,MAAM,IAAI;AAAA,QACrD,oBAAoB,MAAM,qBACtB,mBAAmB,MAAM,kBAAkB,IAC3C;AAAA,MACN;AAAA,SACG;AAAA,MACH,OAAO,KAAK,OAAO,OAAO,qBAAqB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,MAAM,MAAM,EAAE;AAAA,SACpF;AAAA,MACH,OAAO,KAAK,OAAO,OAAO,qBAAqB,MAAM,KAAK,EAAE;AAAA,SACzD;AAAA,MACH,OAAO,aAAa,KAAK;AAAA,SACtB;AAAA,MACH,OAAO,cAAc,MAAM,OAAO,MAAM,MAAM;AAAA,SAC3C;AAAA,MACH,OAAO,eAAe,MAAM,OAAO,MAAM,KAAK;AAAA,SAC3C;AAAA,MACH,OAAO,KAAK,OAAO,OAAO,qBAAqB,MAAM,KAAK,EAAE;AAAA,SACzD;AAAA,MACH,OAAO;AAAA,WACF;AAAA,QACH,OAAO,qBAAqB,MAAM,KAAK;AAAA,QACvC,YAAY,MAAM,aAAa,cAAc,MAAM,UAAU,IAAI;AAAA,MACnE;AAAA,SACG;AAAA,MACH,OAAO,gBAAgB,MAAM,OAAO,MAAM,UAAU;AAAA;AAAA;AAU1D,SAAS,WAAW,CAAC,OAAiC;AAAA,EACpD,IACE,MAAM,SAAS,WACf,MAAM,SAAS,UACf,MAAM,SAAS,SACf,MAAM,SAAS,UACf;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,IAAI,MAAM,MAAM,SAAS;AAAA,IAAU,OAAO;AAAA,EAE1C,MAAM,QAAQ,MAAM;AAAA,EACpB,MAAM,UAAU,qBAAqB,KAAK,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,EACrE,IAAI,QAAQ,SAAS,UAAU;AAAA,IAC7B,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,YAAY,oBAAoB,CAAC,GAAG,MAAM,YAAY,GAAG,QAAQ,UAAU,CAAC;AAAA,IAC9E;AAAA,EACF;AAAA,EACA,OAAO,EAAE,MAAM,UAAU,OAAO,SAAS,YAAY,MAAM,WAAW;AAAA;AAGxE,SAAS,eAAe,CAAC,OAAoB,YAAqD;AAAA,EAChG,MAAM,kBAAkB,qBAAqB,KAAK;AAAA,EAClD,MAAM,uBAAuB,oBAAoB,UAAU;AAAA,EAI3D,IAAI,gBAAgB,SAAS,UAAU;AAAA,IACrC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,gBAAgB;AAAA,MACvB,YAAY,oBAAoB,CAAC,GAAG,gBAAgB,YAAY,GAAG,oBAAoB,CAAC;AAAA,IAC1F;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,MAAM,UAAU,OAAO,iBAAiB,YAAY,qBAAqB;AAAA;AAGpF,SAAS,mBAAmB,CAAC,YAA2D;AAAA,EACtF,MAAM,QAAQ,IAAI;AAAA,EAClB,WAAW,aAAa,YAAY;AAAA,IAClC,MAAM,aAAa,mBAAmB,SAAS;AAAA,IAC/C,MAAM,MAAM,aAAa,UAAU;AAAA,IACnC,MAAM,WAAW,MAAM,IAAI,GAAG;AAAA,IAC9B,MAAM,IAAI,KAAK,WAAW,eAAe,UAAU,UAAU,IAAI,UAAU;AAAA,EAC7E;AAAA,EAEA,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AAAA,IACxC,MAAM,OAAO,aAAa,CAAC;AAAA,IAC3B,MAAM,QAAQ,aAAa,CAAC;AAAA,IAC5B,OAAO,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI;AAAA,GAC/C;AAAA;AAGH,SAAS,kBAAkB,CAAC,WAA6C;AAAA,EACvE,MAAM,SAAS,UAAU,SAAS,oBAAoB,UAAU,MAAM,IAAI,CAAC;AAAA,EAC3E,OAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB,WAAW,UAAU;AAAA,OACjB,UAAU,uBAAuB,YACjC,EAAE,oBAAoB,UAAU,mBAAmB,IACnD,CAAC;AAAA,OACD,UAAU,UAAU,YAAY,EAAE,OAAO,UAAU,MAAM,IAAI,CAAC;AAAA,OAC9D,UAAU,UAAU,EAAE,SAAS,UAAU,QAAQ,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE,EAAE,IAAI,CAAC;AAAA,OACrF,OAAO,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI,CAAC;AAAA,EAChD;AAAA;AAKF,SAAS,cAAc,CAAC,GAAoB,GAAqC;AAAA,EAC/E,MAAM,SAAS,oBAAoB,CAAC,GAAI,EAAE,UAAU,CAAC,GAAI,GAAI,EAAE,UAAU,CAAC,CAAE,CAAC;AAAA,EAC7E,QAAQ,QAAQ,cAAc,SAAS;AAAA,EACvC,OAAO,OAAO,SAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI;AAAA;AAG3D,SAAS,YAAY,CAAC,WAAoC;AAAA,EACxD,OAAO,GAAG,UAAU,gBAAc,UAAU,aAAW,UAAU,sBAAsB;AAAA;AAGlF,SAAS,6BAA6B,CAC3C,WACsB;AAAA,EACtB,QAAQ,UAAU;AAAA,SACX;AAAA,SACA,MAAM;AAAA,MACT,MAAM,QAAQ,UAAU,MAAM,QAAQ,CAAC,SAAS;AAAA,QAC9C,MAAM,aAAa,8BAA8B,IAAI;AAAA,QACrD,IAAI,WAAW,OAAO,UAAU;AAAA,UAAI,OAAO,WAAW;AAAA,QACtD,OAAO,CAAC,UAAU;AAAA,OACnB;AAAA,MACD,OAAO,MAAM,WAAW,IAAI,MAAM,KAAK,EAAE,IAAI,UAAU,IAAI,MAAM;AAAA,IACnE;AAAA,SACK;AAAA,MACH,OAAO,EAAE,IAAI,OAAO,MAAM,8BAA8B,UAAU,IAAI,EAAE;AAAA,SACrE;AAAA,MACH,OAAO,KAAK,WAAW,QAAQ,CAAC,GAAG,UAAU,MAAM,EAAE;AAAA;AAAA,MAErD,OAAO,KAAK,UAAU;AAAA;AAAA;AAI5B,SAAS,eAAe,CAAC,OAAoB,WAA8C;AAAA,EACzF,MAAM,kBAAkB,qBAAqB,KAAK;AAAA,EAClD,MAAM,sBAAsB,8BAA8B,SAAS;AAAA,EAInE,IAAI,gBAAgB,SAAS,UAAU;AAAA,IACrC,OAAO,qBAAqB;AAAA,MAC1B,MAAM;AAAA,MACN,OAAO,gBAAgB;AAAA,MACvB,WAAW;AAAA,QACT,IAAI;AAAA,QACJ,OAAO,CAAC,gBAAgB,WAAW,mBAAmB;AAAA,MACxD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAAA;AAGF,SAAS,YAAY,CAAC,OAAoC;AAAA,EACxD,MAAM,SAAS,MAAM,OAAO,QAAQ,CAAC,UAAU;AAAA,IAC7C,MAAM,aAAa,qBAAqB,KAAK;AAAA,IAC7C,IAAI,WAAW,SAAS,SAAS,WAAW,OAAO,MAAM;AAAA,MAAI,OAAO,WAAW;AAAA,IAC/E,OAAO,CAAC,UAAU;AAAA,GACnB;AAAA,EAED,OAAO,KAAK,OAAO,OAAO;AAAA;AAG5B,SAAS,aAAa,CAAC,OAAoB,QAAsD;AAAA,EAC/F,MAAM,kBAAkB,qBAAqB,KAAK;AAAA,EAClD,MAAM,mBAAmB,OAAO,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE;AAAA,EAG7D,IAAI,gBAAgB,SAAS,QAAQ;AAAA,IACnC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,gBAAgB;AAAA,MACvB,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA;AAGF,SAAS,cAAc,CAAC,OAAoB,OAA4B;AAAA,EACtE,MAAM,kBAAkB,qBAAqB,KAAK;AAAA,EAGlD,IAAI,gBAAgB,SAAS,SAAS;AAAA,IACpC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,gBAAgB;AAAA,MACvB,OAAO,KAAK,IAAI,gBAAgB,OAAO,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP;AAAA,EACF;AAAA;AAGF,SAAS,aAAa,CAAC,QAAqC;AAAA,EAC1D,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAAA;AAG5B,SAAS,UAAU,CACjB,MAC+C;AAAA,EAC/C,MAAM,OAAO,IAAI;AAAA,EACjB,MAAM,SAAS,KAAK,QAAQ,CAAC,QAAQ;AAAA,IACnC,MAAM,MAAM,KAAK,UAAU,CAAC,IAAI,cAAc,IAAI,SAAS,CAAC;AAAA,IAC5D,IAAI,KAAK,IAAI,GAAG;AAAA,MAAG,OAAO,CAAC;AAAA,IAC3B,KAAK,IAAI,GAAG;AAAA,IACZ,OAAO,CAAC,KAAK,IAAI,CAAC;AAAA,GACnB;AAAA,EAKD,OAAO,OAAO,KACZ,CAAC,MAAM,UACL,eAAe,KAAK,cAAc,MAAM,YAAY,KACpD,eAAe,KAAK,WAAW,MAAM,SAAS,CAClD;AAAA;AAGF,SAAS,cAAc,CAAC,MAAc,OAAuB;AAAA,EAC3D,IAAI,OAAO;AAAA,IAAO,OAAO;AAAA,EACzB,IAAI,OAAO;AAAA,IAAO,OAAO;AAAA,EACzB,OAAO;AAAA;AAGT,SAAS,kBAAkB,CACzB,QAC0B;AAAA,EAC1B,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,EAAE,IAAI,EAAE,cAAc,YAAY,CAAC,cAAc,cAAc,MAAM,CAAC,CAAC,CAC9F;AAAA;;;ACjRK,SAAS,4BAA4B,CAAC,aAA6C;AAAA,EACxF,MAAM,QAAkB,CAAC;AAAA,EACzB,MAAM,SACJ,YAAY,UAAU,YAAY,kBAAkB,YAAY,QAAQ,UAAU;AAAA,EACpF,MAAM,SAAS,YAAY,SAAS,WAAW,YAAY,OAAO,cAAc,KAAK,KAAK,MAAM;AAAA,EAEhG,MAAM,KAAK,eAAe,SAAS,QAAQ;AAAA,EAC3C,gBAAgB,YAAY,MAAM,OAAO,CAAC;AAAA,EAE1C,IAAI,YAAY,OAAO,SAAS,GAAG;AAAA,IACjC,MAAM,KAAK,SAAS;AAAA,IACpB,WAAW,SAAS,YAAY,QAAQ;AAAA,MACtC,MAAM,KAAK,KAAK,MAAM,SAAS,MAAM,SAAS,MAAM,SAAS;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,OAAO,MAAM,KAAK;AAAA,CAAI;AAAA;AAGxB,SAAS,eAAe,CAAC,MAA8B,OAAiB,OAAqB;AAAA,EAC3F,MAAM,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM,KAAK,QAAQ,KAAK,SAAS;AAAA,EAChE,WAAW,SAAS,KAAK,UAAU;AAAA,IACjC,gBAAgB,OAAO,OAAO,QAAQ,CAAC;AAAA,EACzC;AAAA;",
10
+ "debugId": "0FCE1B0193C4DA0664756E2164756E21",
11
+ "names": []
12
+ }
@@ -2,7 +2,7 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/storage/agents/types.ts"],
4
4
  "sourcesContent": [
5
- "import type { AgentMessage, AgentMessagePart, AgentMessageRole } from \"../../agents/message\"\nimport type { Principal } from \"../../auth\"\nimport type { SixbErrorCode, SixbFailure } from \"../../errors/types\"\nimport type { JsonValue } from \"../../json\"\n\n// ── agent_threads — one conversation with an agent ──────────────────────────────────────────────\n\nexport type AgentThreadStatus = \"active\" | \"archived\"\n\nexport interface AgentThreadRecord {\n readonly id: string\n readonly projectId: string\n readonly agentId: string\n /** Who owns/opened the thread. Reuses the canonical auth principal (gains `agent` later for free). */\n readonly ownerPrincipal: Principal\n readonly title?: string\n readonly status: AgentThreadStatus\n /** Single-flight anchor: the id of the one run currently allowed to write, or `null` when idle. */\n readonly activeRunId: string | null\n readonly lastMessageAt?: Date\n readonly messageCount: number\n readonly createdAt: Date\n readonly updatedAt: Date\n}\n\nexport interface CreateAgentThreadInput {\n readonly id: string\n readonly projectId: string\n readonly agentId: string\n readonly ownerPrincipal: Principal\n readonly title?: string\n readonly status?: AgentThreadStatus\n readonly createdAt?: Date\n readonly updatedAt?: Date\n}\n\nexport interface ListAgentThreadsInput {\n readonly projectId: string\n readonly agentId?: string\n /** Optional allowlist intersected with `agentId` when both are provided. Empty means no rows. */\n readonly agentIds?: readonly string[]\n readonly statuses?: readonly AgentThreadStatus[]\n readonly ownerPrincipal?: Principal\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentThreadsResult {\n readonly threads: readonly AgentThreadRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_runs — one loop execution (the worker job; attribution + fencing) ───────────────────\n\n/** Lifecycle shared by every durable agent execution, conversational or workflow-owned. */\nexport type AgentExecutionStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"cancelled\"\n\nexport type AgentRunStatus = AgentExecutionStatus\n\n/** Error codes an agent execution can persist and expose through its public contract. */\nexport const AGENT_RUN_FAILURE_CODES = [\n \"internal.unexpected\",\n \"runtime.cancelled\",\n \"agent.execution_failed\",\n] as const satisfies readonly [SixbErrorCode, ...SixbErrorCode[]]\n\nexport type AgentRunFailureCode = (typeof AGENT_RUN_FAILURE_CODES)[number]\n\n/**\n * Why a run ended — our own SDK-independent vocabulary. It includes the AI SDK's unified finish\n * reasons plus platform-level endings such as `timeout`, so reads are typed and exhaustive without\n * core depending on `ai`. `other`/`unknown` are catch-alls: an unrecognised provider value still\n * records *that* the run ended.\n */\nexport const AGENT_RUN_FINISH_REASONS = [\n \"stop\",\n \"length\",\n \"content-filter\",\n \"tool-calls\",\n \"timeout\",\n \"error\",\n \"other\",\n \"unknown\",\n] as const\n\nexport type AgentRunFinishReason = (typeof AGENT_RUN_FINISH_REASONS)[number]\n\n/**\n * Coerce an external finish-reason string — a DB column or an SDK value — to {@link\n * AgentRunFinishReason}. An unrecognised value becomes `\"unknown\"` rather than being dropped.\n */\nexport function coerceAgentRunFinishReason(\n value: string | null | undefined\n): AgentRunFinishReason | undefined {\n if (value === null || value === undefined) {\n return undefined\n }\n return (AGENT_RUN_FINISH_REASONS as readonly string[]).includes(value)\n ? (value as AgentRunFinishReason)\n : \"unknown\"\n}\n\n/** Stable, user-facing diagnostics emitted by the platform while executing a run. */\nexport const AGENT_RUN_DIAGNOSTIC_CODES = [\n \"output_file_limit_exceeded\",\n \"output_file_too_large\",\n \"output_budget_exhausted\",\n \"output_collection_failed\",\n \"output_file_changed\",\n \"output_storage_failed\",\n] as const\n\n/**\n * Closed on purpose, and the wire is closed with it.\n *\n * Sixb writes these codes and the generated client is what reads them, so an open union would only\n * be honest if the HTTP schema were open too — and that costs the OpenAPI enum, the client's\n * autocompletion, and Atlas's exhaustive `switch`. Sixb owns both ends, so a new code is a minor\n * version bump: cheap here, and a broken `switch` is better than a 500 from `z.enum`.\n */\nexport type AgentRunDiagnosticCode = (typeof AGENT_RUN_DIAGNOSTIC_CODES)[number]\nexport type AgentRunDiagnosticSeverity = \"warning\" | \"error\"\n\nexport interface AgentRunDiagnostic {\n readonly code: AgentRunDiagnosticCode\n readonly severity: AgentRunDiagnosticSeverity\n readonly scope: \"output\"\n /** Relative path inside the run's published output directory, when one file is involved. */\n readonly path?: string\n /** Sanitized, stable copy suitable for display to an end user. */\n readonly message: string\n}\n\n/**\n * Authorization state for the current queue delivery.\n *\n * `queueLeaseExpiresAt` is a persisted projection of `ClaimedQueueJob.leaseExpiresAt`, not an\n * independently managed run lease. It may only be extended from a successful queue lease renewal.\n */\nexport interface AgentRunExecution {\n readonly token: string\n readonly queueLeaseExpiresAt: Date\n}\n\nexport interface AgentRunRecord {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly threadId: string\n readonly agentId: string\n readonly triggerMessageId: string\n /** Durable group memberships snapshotted when the run was admitted. */\n readonly requesterGroupIds: readonly string[]\n readonly status: AgentRunStatus\n readonly modelId?: string\n /** Why the run ended (our own SDK-independent enum). */\n readonly finishReason?: AgentRunFinishReason\n /** Platform diagnostics are transcript annotations, never agent-authored message content. */\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n /** Portable failure snapshot when the run did not succeed. */\n readonly error?: SixbFailure<AgentRunFailureCode>\n /** Execution attempts: `0` while queued, `1` on first start, incremented on redelivery. */\n readonly attempt: number\n readonly execution?: AgentRunExecution\n readonly createdAt: Date\n readonly startedAt?: Date\n readonly completedAt?: Date\n}\n\nexport interface CreateAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly threadId: string\n readonly agentId: string\n readonly triggerMessageId: string\n readonly requesterGroupIds: readonly string[]\n readonly createdAt?: Date\n}\n\nexport interface StartAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly modelId?: string\n readonly execution: AgentRunExecution\n readonly startedAt?: Date\n}\n\nexport interface FinishQueuedAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly status: \"failed\" | \"cancelled\"\n readonly error?: SixbFailure<AgentRunFailureCode>\n readonly completedAt?: Date\n}\n\nexport interface ReclaimAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly execution: AgentRunExecution\n}\n\nexport interface ConfirmAgentRunExecutionOwnershipInput {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n /** Exact expiration returned by the queue claim or its latest successful renewal. */\n readonly queueLeaseExpiresAt: Date\n}\n\nexport type FinishAgentRunInput =\n | {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n readonly status: \"succeeded\"\n readonly modelId?: string\n readonly finishReason?: AgentRunFinishReason\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n readonly completedAt?: Date\n }\n | {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n readonly status: \"failed\" | \"cancelled\"\n readonly modelId?: string\n readonly finishReason?: AgentRunFinishReason\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n readonly error?: SixbFailure<AgentRunFailureCode>\n readonly completedAt?: Date\n }\n\nexport interface ListAgentRunsInput {\n readonly projectId: string\n readonly threadId?: string\n readonly agentId?: string\n readonly statuses?: readonly AgentRunStatus[]\n /** Effective start time; runs that never started use `createdAt`. */\n readonly startedAfter?: Date\n /** Effective start time; runs that never started use `createdAt`. */\n readonly startedBefore?: Date\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentRunsResult {\n readonly runs: readonly AgentRunRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_messages — one message (assistant messages inserted only once finalized) ─────────────\n\nexport type { AgentMessageRole }\n\nexport interface AgentMessageRecord {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n /** The run that produced this message; `null` for user-authored messages. */\n readonly runId: string | null\n readonly role: AgentMessageRole\n /** Principal that authored this persisted message: caller for user messages, agent identity later for assistant messages. */\n readonly authorPrincipal?: Principal\n /** Monotonic per thread, assigned by the store. */\n readonly seq: number\n /** Structured message content — text / reasoning / step boundaries / tool calls. */\n readonly parts: readonly AgentMessagePart[]\n /** Message-level metadata (mirrors `UIMessage.metadata`). */\n readonly metadata?: JsonValue\n /** Versions the `parts` shape so it can be migrated; stamped from `AGENT_MESSAGE_CONTENT_VERSION`. */\n readonly contentVersion: number\n readonly createdAt: Date\n readonly completedAt?: Date\n}\n\n/** Append a message: a {@link AgentMessage} (role + parts + metadata) plus its storage identity. */\nexport interface AppendAgentMessageInput extends AgentMessage {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly runId: string | null\n readonly authorPrincipal?: Principal\n readonly createdAt?: Date\n readonly completedAt?: Date\n}\n\nexport interface DeleteAgentMessagesByRunInput {\n readonly projectId: string\n readonly threadId: string\n readonly runId: string\n}\n\nexport interface ListAgentMessagesInput {\n readonly projectId: string\n readonly threadId: string\n /** Return only messages whose per-thread sequence is greater than this retained boundary. */\n readonly afterSeq?: number\n readonly roles?: readonly AgentMessageRole[]\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentMessagesResult {\n readonly messages: readonly AgentMessageRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_context_checkpoints — append-only model-context boundaries ──────────────────────────\n\nexport type AgentContextCheckpointReason = \"threshold\" | \"overflow\"\n\n/**\n * A durable summary boundary used only when projecting a thread into model context.\n *\n * Checkpoints never replace or mutate transcript messages. Normal thread reads remain authoritative\n * and complete; the worker reads the latest checkpoint and only the retained message tail.\n */\nexport interface AgentContextCheckpointRecord {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly createdByRunId: string\n readonly previousCheckpointId?: string\n readonly reason: AgentContextCheckpointReason\n readonly summary: string\n readonly summaryFormatVersion: 1\n readonly summarizedThroughSeq: number\n readonly observedHeadSeq: number\n readonly estimatedInputTokensBefore: number\n readonly estimatedInputTokensAfter: number\n readonly summaryModelId: string\n readonly createdAt: Date\n}\n\nexport interface CreateAgentContextCheckpointInput {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly createdByRunId: string\n /** Compare-and-swap anchor. `null` means the thread must not have a prior checkpoint. */\n readonly expectedPreviousCheckpointId: string | null\n /** Compare-and-swap anchor for the complete transcript observed by the summarizer. */\n readonly expectedHeadSeq: number\n /** Current delivery token for `createdByRunId`; stale redeliveries must not write. */\n readonly executionToken: string\n readonly reason: AgentContextCheckpointReason\n readonly summary: string\n readonly summaryFormatVersion: 1\n readonly summarizedThroughSeq: number\n readonly observedHeadSeq: number\n readonly estimatedInputTokensBefore: number\n readonly estimatedInputTokensAfter: number\n readonly summaryModelId: string\n readonly createdAt?: Date\n}\n\n// ── Store ───────────────────────────────────────────────────────────────────────────────────────\n\nexport interface AgentThreadStore {\n create(input: CreateAgentThreadInput): Promise<AgentThreadRecord>\n getById(params: { projectId: string; id: string }): Promise<AgentThreadRecord | null>\n list(input: ListAgentThreadsInput): Promise<ListAgentThreadsResult>\n}\n\nexport interface AgentRunStore {\n /** Persist a queued run and atomically claim the thread's single-flight slot. */\n create(input: CreateAgentRunInput): Promise<AgentRunRecord>\n /** Transition a queued run to running and install the first delivery's execution token. */\n start(input: StartAgentRunInput): Promise<AgentRunRecord>\n /** Finish a queued run before execution and release the thread's single-flight slot. */\n finishQueued(input: FinishQueuedAgentRunInput): Promise<AgentRunRecord>\n /** Rotate the execution token for a redelivered running job (`attempt++`). */\n reclaim(input: ReclaimAgentRunInput): Promise<AgentRunRecord>\n /**\n * Project the queue's latest confirmed ownership expiration onto the current execution.\n * Implementations must fence by token and must never move the expiration backwards.\n */\n confirmExecutionOwnership(input: ConfirmAgentRunExecutionOwnershipInput): Promise<AgentRunRecord>\n /** Finalize a run and release the thread's `activeRunId`. */\n finish(input: FinishAgentRunInput): Promise<AgentRunRecord>\n getById(params: { projectId: string; id: string }): Promise<AgentRunRecord | null>\n getByIds(params: {\n projectId: string\n ids: readonly string[]\n }): Promise<readonly AgentRunRecord[]>\n list(input: ListAgentRunsInput): Promise<ListAgentRunsResult>\n}\n\nexport interface AgentMessageStore {\n /** Insert a message (its `parts` are the canonical content) and bump thread stats. */\n append(input: AppendAgentMessageInput): Promise<AgentMessageRecord>\n /** Delete every message produced by one run and repair the thread's message stats. */\n deleteByRunId(input: DeleteAgentMessagesByRunInput): Promise<number>\n getById(params: { projectId: string; id: string }): Promise<AgentMessageRecord | null>\n list(input: ListAgentMessagesInput): Promise<ListAgentMessagesResult>\n}\n\nexport interface AgentContextCheckpointStore {\n /**\n * Append one checkpoint after atomically validating run ownership and both transcript anchors.\n * Repeating the same payload for the same creating run is idempotent.\n */\n create(input: CreateAgentContextCheckpointInput): Promise<AgentContextCheckpointRecord>\n getLatest(input: {\n readonly projectId: string\n readonly threadId: string\n }): Promise<AgentContextCheckpointRecord | null>\n}\n\nexport interface AgentStorage {\n readonly threads: AgentThreadStore\n readonly runs: AgentRunStore\n readonly messages: AgentMessageStore\n readonly checkpoints: AgentContextCheckpointStore\n}\n"
5
+ "import type { AgentMessage, AgentMessagePart, AgentMessageRole } from \"../../agents/message\"\nimport type { Principal } from \"../../auth\"\nimport type { SixbErrorCode, SixbFailure } from \"../../errors/types\"\nimport type { JsonValue } from \"../../json\"\n\n// ── agent_threads — one conversation with an agent ──────────────────────────────────────────────\n\nexport type AgentThreadStatus = \"active\" | \"archived\"\n\nexport interface AgentThreadRecord {\n readonly id: string\n readonly projectId: string\n readonly agentId: string\n /** Who owns/opened the thread. Reuses the canonical auth principal (gains `agent` later for free). */\n readonly ownerPrincipal: Principal\n readonly title?: string\n readonly status: AgentThreadStatus\n /** Single-flight anchor: the id of the one run currently allowed to write, or `null` when idle. */\n readonly activeRunId: string | null\n readonly lastMessageAt?: Date\n readonly messageCount: number\n readonly createdAt: Date\n readonly updatedAt: Date\n}\n\nexport interface CreateAgentThreadInput {\n readonly id: string\n readonly projectId: string\n readonly agentId: string\n readonly ownerPrincipal: Principal\n readonly title?: string\n readonly status?: AgentThreadStatus\n readonly createdAt?: Date\n readonly updatedAt?: Date\n}\n\nexport interface ListAgentThreadsInput {\n readonly projectId: string\n readonly agentId?: string\n /** Optional allowlist intersected with `agentId` when both are provided. Empty means no rows. */\n readonly agentIds?: readonly string[]\n readonly statuses?: readonly AgentThreadStatus[]\n readonly ownerPrincipal?: Principal\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentThreadsResult {\n readonly threads: readonly AgentThreadRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_runs — one loop execution (the worker job; attribution + fencing) ───────────────────\n\n/** Lifecycle shared by every durable agent execution, conversational or workflow-owned. */\nexport type AgentExecutionStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"cancelled\"\n\nexport type AgentRunStatus = AgentExecutionStatus\n\n/** Error codes an agent execution can persist and expose through its public contract. */\nexport const AGENT_RUN_FAILURE_CODES = [\n \"internal.unexpected\",\n \"runtime.cancelled\",\n \"agent.execution_failed\",\n] as const satisfies readonly [SixbErrorCode, ...SixbErrorCode[]]\n\nexport type AgentRunFailureCode = (typeof AGENT_RUN_FAILURE_CODES)[number]\n\n/**\n * Why a run ended — our own SDK-independent vocabulary. It includes the AI SDK's unified finish\n * reasons plus platform-level endings such as `timeout`, so reads are typed and exhaustive without\n * core depending on `ai`. `other`/`unknown` are catch-alls: an unrecognised provider value still\n * records *that* the run ended.\n */\nexport const AGENT_RUN_FINISH_REASONS = [\n \"stop\",\n \"length\",\n \"content-filter\",\n \"tool-calls\",\n \"timeout\",\n \"error\",\n \"other\",\n \"unknown\",\n] as const\n\nexport type AgentRunFinishReason = (typeof AGENT_RUN_FINISH_REASONS)[number]\n\n/**\n * Coerce an external finish-reason string — a DB column or an SDK value — to {@link\n * AgentRunFinishReason}. An unrecognised value becomes `\"unknown\"` rather than being dropped.\n */\nexport function coerceAgentRunFinishReason(\n value: string | null | undefined\n): AgentRunFinishReason | undefined {\n if (value === null || value === undefined) {\n return undefined\n }\n return (AGENT_RUN_FINISH_REASONS as readonly string[]).includes(value)\n ? (value as AgentRunFinishReason)\n : \"unknown\"\n}\n\n/** Stable, user-facing diagnostics emitted by the platform while executing a run. */\nexport const AGENT_RUN_DIAGNOSTIC_CODES = [\n \"output_file_limit_exceeded\",\n \"output_file_too_large\",\n \"output_budget_exhausted\",\n \"output_collection_failed\",\n \"output_file_changed\",\n \"output_storage_failed\",\n] as const\n\n/**\n * Closed on purpose, and the wire is closed with it.\n *\n * Sixb writes these codes and the generated client is what reads them, so an open union would only\n * be honest if the HTTP schema were open too — and that costs the OpenAPI enum, the client's\n * autocompletion, and Atlas's exhaustive `switch`. Sixb owns both ends, so a new code is a minor\n * version bump: cheap here, and a broken `switch` is better than a 500 from `z.enum`.\n */\nexport type AgentRunDiagnosticCode = (typeof AGENT_RUN_DIAGNOSTIC_CODES)[number]\nexport type AgentRunDiagnosticSeverity = \"warning\" | \"error\"\n\nexport interface AgentRunDiagnostic {\n readonly code: AgentRunDiagnosticCode\n readonly severity: AgentRunDiagnosticSeverity\n readonly scope: \"output\"\n /** Relative path inside the run's published output directory, when one file is involved. */\n readonly path?: string\n /** Sanitized, stable copy suitable for display to an end user. */\n readonly message: string\n}\n\n/**\n * Authorization state for the current queue delivery.\n *\n * `queueLeaseExpiresAt` is a persisted projection of `ClaimedQueueJob.leaseExpiresAt`, not an\n * independently managed run lease. It may only be extended from a successful queue lease renewal.\n */\nexport interface AgentRunExecution {\n readonly token: string\n readonly queueLeaseExpiresAt: Date\n}\n\nexport interface AgentRunRecord {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly threadId: string\n readonly agentId: string\n readonly triggerMessageId: string\n /** Durable group memberships snapshotted when the run was admitted. */\n readonly requesterGroupIds: readonly string[]\n readonly status: AgentRunStatus\n readonly modelId?: string\n /** Why the run ended (our own SDK-independent enum). */\n readonly finishReason?: AgentRunFinishReason\n /** Platform diagnostics are transcript annotations, never agent-authored message content. */\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n /** Portable failure snapshot when the run did not succeed. */\n readonly error?: SixbFailure<AgentRunFailureCode>\n /** Execution attempts: `0` while queued, `1` on first start, incremented on redelivery. */\n readonly attempt: number\n readonly execution?: AgentRunExecution\n readonly createdAt: Date\n readonly startedAt?: Date\n readonly completedAt?: Date\n}\n\nexport interface CreateAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly threadId: string\n readonly agentId: string\n readonly triggerMessageId: string\n readonly requesterGroupIds: readonly string[]\n readonly createdAt?: Date\n}\n\nexport interface StartAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly modelId?: string\n readonly execution: AgentRunExecution\n readonly startedAt?: Date\n}\n\nexport interface FinishQueuedAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly status: \"failed\" | \"cancelled\"\n readonly error?: SixbFailure<AgentRunFailureCode>\n readonly completedAt?: Date\n}\n\nexport interface ReclaimAgentRunInput {\n readonly id: string\n readonly projectId: string\n readonly execution: AgentRunExecution\n}\n\nexport interface ConfirmAgentRunExecutionOwnershipInput {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n /** Exact expiration returned by the queue claim or its latest successful renewal. */\n readonly queueLeaseExpiresAt: Date\n}\n\nexport type FinishAgentRunInput =\n | {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n readonly status: \"succeeded\"\n readonly modelId?: string\n readonly finishReason?: AgentRunFinishReason\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n readonly completedAt?: Date\n }\n | {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n readonly status: \"failed\" | \"cancelled\"\n readonly modelId?: string\n readonly finishReason?: AgentRunFinishReason\n readonly diagnostics?: readonly AgentRunDiagnostic[]\n readonly error?: SixbFailure<AgentRunFailureCode>\n readonly completedAt?: Date\n }\n\nexport interface ListAgentRunsInput {\n readonly projectId: string\n readonly threadId?: string\n readonly agentId?: string\n readonly statuses?: readonly AgentRunStatus[]\n /** Effective start time; runs that never started use `createdAt`. */\n readonly startedAfter?: Date\n /** Effective start time; runs that never started use `createdAt`. */\n readonly startedBefore?: Date\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentRunsResult {\n readonly runs: readonly AgentRunRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_messages — one message (assistant messages inserted only once finalized) ─────────────\n\nexport type { AgentMessageRole }\n\nexport interface AgentMessageRecord {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n /** The run that produced this message; `null` for user-authored messages. */\n readonly runId: string | null\n readonly role: AgentMessageRole\n /** Principal that authored this persisted message: caller for user messages, agent identity later for assistant messages. */\n readonly authorPrincipal?: Principal\n /** Monotonic per thread, assigned by the store. */\n readonly seq: number\n /** Structured message content — text / reasoning / step boundaries / tool calls. */\n readonly parts: readonly AgentMessagePart[]\n /** Message-level metadata (mirrors `UIMessage.metadata`). */\n readonly metadata?: JsonValue\n /** Versions the `parts` shape so it can be migrated; stamped from `AGENT_MESSAGE_CONTENT_VERSION`. */\n readonly contentVersion: number\n readonly createdAt: Date\n readonly completedAt?: Date\n}\n\n/** Append a message: a {@link AgentMessage} (role + parts + metadata) plus its storage identity. */\nexport interface AppendAgentMessageInput extends AgentMessage {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly runId: string | null\n readonly authorPrincipal?: Principal\n readonly createdAt?: Date\n readonly completedAt?: Date\n}\n\nexport interface DeleteAgentMessagesByRunInput {\n readonly projectId: string\n readonly threadId: string\n readonly runId: string\n}\n\nexport interface ListAgentMessagesInput {\n readonly projectId: string\n readonly threadId: string\n /** Return only messages whose per-thread sequence is greater than this retained boundary. */\n readonly afterSeq?: number\n readonly roles?: readonly AgentMessageRole[]\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListAgentMessagesResult {\n readonly messages: readonly AgentMessageRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\n// ── agent_context_checkpoints — append-only model-context boundaries ──────────────────────────\n\nexport type AgentContextCheckpointReason = \"threshold\" | \"overflow\"\n\n/**\n * A durable summary boundary used only when projecting a thread into model context.\n *\n * Checkpoints never replace or mutate transcript messages. Normal thread reads remain authoritative\n * and complete; the worker reads the latest checkpoint and only the retained message tail.\n */\nexport interface AgentContextCheckpointRecord {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly createdByRunId: string\n readonly previousCheckpointId?: string\n readonly reason: AgentContextCheckpointReason\n readonly summary: string\n readonly summaryFormatVersion: 1\n readonly summarizedThroughSeq: number\n readonly observedHeadSeq: number\n readonly estimatedInputTokensBefore: number\n readonly estimatedInputTokensAfter: number\n readonly summaryModelId: string\n readonly createdAt: Date\n}\n\nexport interface CreateAgentContextCheckpointInput {\n readonly id: string\n readonly projectId: string\n readonly threadId: string\n readonly createdByRunId: string\n /** Compare-and-swap anchor. `null` means the thread must not have a prior checkpoint. */\n readonly expectedPreviousCheckpointId: string | null\n /** Compare-and-swap anchor for the complete transcript observed by the summarizer. */\n readonly expectedHeadSeq: number\n /** Current delivery token for `createdByRunId`; stale redeliveries must not write. */\n readonly executionToken: string\n readonly reason: AgentContextCheckpointReason\n readonly summary: string\n readonly summaryFormatVersion: 1\n readonly summarizedThroughSeq: number\n readonly observedHeadSeq: number\n readonly estimatedInputTokensBefore: number\n readonly estimatedInputTokensAfter: number\n readonly summaryModelId: string\n readonly createdAt?: Date\n}\n\n// ── Store ───────────────────────────────────────────────────────────────────────────────────────\n\nexport interface AgentThreadStore {\n create(input: CreateAgentThreadInput): Promise<AgentThreadRecord>\n getById(params: { projectId: string; id: string }): Promise<AgentThreadRecord | null>\n list(input: ListAgentThreadsInput): Promise<ListAgentThreadsResult>\n}\n\nexport interface AgentRunStore {\n /** Persist a queued run and atomically claim the thread's single-flight slot. */\n create(input: CreateAgentRunInput): Promise<AgentRunRecord>\n /** Transition a queued run to running and install the first delivery's execution token. */\n start(input: StartAgentRunInput): Promise<AgentRunRecord>\n /** Finish a queued run before execution and release the thread's single-flight slot. */\n finishQueued(input: FinishQueuedAgentRunInput): Promise<AgentRunRecord>\n /** Rotate the execution token for a redelivered running job (`attempt++`). */\n reclaim(input: ReclaimAgentRunInput): Promise<AgentRunRecord>\n /**\n * Project the queue's latest confirmed ownership expiration onto the current execution.\n * Implementations must fence by token and must never move the expiration backwards.\n */\n confirmExecutionOwnership(input: ConfirmAgentRunExecutionOwnershipInput): Promise<AgentRunRecord>\n /** Finalize a run and release the thread's `activeRunId`. */\n finish(input: FinishAgentRunInput): Promise<AgentRunRecord>\n getById(params: { projectId: string; id: string }): Promise<AgentRunRecord | null>\n getByIds(params: {\n projectId: string\n ids: readonly string[]\n }): Promise<readonly AgentRunRecord[]>\n list(input: ListAgentRunsInput): Promise<ListAgentRunsResult>\n}\n\nexport interface AgentMessageStore {\n /** Insert a message (its `parts` are the canonical content) and bump thread stats. */\n append(input: AppendAgentMessageInput): Promise<AgentMessageRecord>\n /** Delete every message produced by one run and repair the thread's message stats. */\n deleteByRunId(input: DeleteAgentMessagesByRunInput): Promise<number>\n getById(params: { projectId: string; id: string }): Promise<AgentMessageRecord | null>\n list(input: ListAgentMessagesInput): Promise<ListAgentMessagesResult>\n}\n\nexport interface AgentContextCheckpointStore {\n /**\n * Append one checkpoint after atomically validating run ownership and both transcript anchors.\n * Repeating the same payload for the same creating run is idempotent.\n */\n create(input: CreateAgentContextCheckpointInput): Promise<AgentContextCheckpointRecord>\n /** Return checkpoints created by the requested runs, in first-occurrence input order. */\n getByRunIds(input: {\n readonly projectId: string\n readonly runIds: readonly string[]\n }): Promise<readonly AgentContextCheckpointRecord[]>\n getLatest(input: {\n readonly projectId: string\n readonly threadId: string\n }): Promise<AgentContextCheckpointRecord | null>\n}\n\nexport interface AgentStorage {\n readonly threads: AgentThreadStore\n readonly runs: AgentRunStore\n readonly messages: AgentMessageStore\n readonly checkpoints: AgentContextCheckpointStore\n}\n"
6
6
  ],
7
7
  "mappings": ";;AA8DO,IAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF;AAUO,IAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,SAAS,0BAA0B,CACxC,OACkC;AAAA,EAClC,IAAI,UAAU,QAAQ,UAAU,WAAW;AAAA,IACzC;AAAA,EACF;AAAA,EACA,OAAQ,yBAA+C,SAAS,KAAK,IAChE,QACD;AAAA;AAIC,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
8
8
  "debugId": "E6142794534A3A5D64756E2164756E21",
@@ -5,10 +5,10 @@ import {
5
5
  import {
6
6
  ensureExecutionRecord,
7
7
  executionRecordInputFromRuntime
8
- } from "./chunk-4aw0jwk0.js";
8
+ } from "./chunk-f6erf2vv.js";
9
9
  import {
10
10
  isStorageSerializationFailure
11
- } from "./chunk-xmggaxg4.js";
11
+ } from "./chunk-v0egge8b.js";
12
12
  import {
13
13
  createCommitId,
14
14
  createEventId,
@@ -16,7 +16,7 @@ import {
16
16
  materializationApplyPhase,
17
17
  materializationEventKindOrdinal,
18
18
  sha256Canonical
19
- } from "./chunk-fmx1sz2h.js";
19
+ } from "./chunk-72q2y8hn.js";
20
20
  import {
21
21
  assertPinnedDatasetWatermark
22
22
  } from "./chunk-9dzba0f2.js";
@@ -44,6 +44,12 @@ import {
44
44
  MaterializationObjectNotFoundError,
45
45
  MaterializationValidationError
46
46
  } from "./chunk-ry24jbr1.js";
47
+ import {
48
+ ProjectionValidationError,
49
+ isProjectionDefinition,
50
+ resolveExecutionScopeAuthorization,
51
+ validateProjectionsAtStartup
52
+ } from "./chunk-f83ka50g.js";
47
53
  import {
48
54
  assertKnownProperties,
49
55
  normalizeLinkProperties,
@@ -54,12 +60,6 @@ import {
54
60
  validatePropertyValue,
55
61
  validateTelemetryUnit
56
62
  } from "./chunk-rnshztfq.js";
57
- import {
58
- ProjectionValidationError,
59
- isProjectionDefinition,
60
- resolveExecutionScopeAuthorization,
61
- validateProjectionsAtStartup
62
- } from "./chunk-4z3n1dzt.js";
63
63
  import {
64
64
  assertJsonValue,
65
65
  cloneJsonValue,
@@ -186,14 +186,31 @@ function normalizeProjectionDefinition(projection) {
186
186
  targetField: projection.targetField
187
187
  };
188
188
  }
189
+ const properties = Object.entries(projection.properties).sort(([left], [right]) => compareStrings(left, right));
190
+ if (properties.length === 1) {
191
+ const [propertyId, mapping] = properties[0];
192
+ return {
193
+ kind: "telemetry",
194
+ objectTypeId: projection.objectTypeId,
195
+ propertyId,
196
+ objectIdField: projection.objectIdField,
197
+ atField: projection.atField,
198
+ valueField: mapping.valueField,
199
+ unitField: mapping.unitField ?? null
200
+ };
201
+ }
189
202
  return {
190
203
  kind: "telemetry",
191
204
  objectTypeId: projection.objectTypeId,
192
- propertyId: projection.propertyId,
193
205
  objectIdField: projection.objectIdField,
194
206
  atField: projection.atField,
195
- valueField: projection.valueField,
196
- unitField: projection.unitField ?? null
207
+ properties: Object.fromEntries(properties.map(([propertyId, mapping]) => [
208
+ propertyId,
209
+ {
210
+ valueField: mapping.valueField,
211
+ unitField: mapping.unitField ?? null
212
+ }
213
+ ]))
197
214
  };
198
215
  }
199
216
  function projectionColumns(projection) {
@@ -210,8 +227,10 @@ function projectionColumns(projection) {
210
227
  return new Set([
211
228
  projection.objectIdField,
212
229
  projection.atField,
213
- projection.valueField,
214
- ...projection.unitField === undefined ? [] : [projection.unitField]
230
+ ...Object.values(projection.properties).flatMap((mapping) => [
231
+ mapping.valueField,
232
+ ...mapping.unitField === undefined ? [] : [mapping.unitField]
233
+ ])
215
234
  ]);
216
235
  }
217
236
  function normalizeProperty(property) {
@@ -453,12 +472,16 @@ function cloneTelemetryProjectionDefinition(projection) {
453
472
  _tag: "TelemetryProjectionDefinition",
454
473
  id: projection.id,
455
474
  objectTypeId: projection.objectTypeId,
456
- propertyId: projection.propertyId,
457
475
  datasetId: projection.datasetId,
458
476
  objectIdField: projection.objectIdField,
459
477
  atField: projection.atField,
460
- valueField: projection.valueField,
461
- ...projection.unitField !== undefined ? { unitField: projection.unitField } : {}
478
+ properties: Object.fromEntries(Object.entries(projection.properties).map(([propertyId, mapping]) => [
479
+ propertyId,
480
+ {
481
+ valueField: mapping.valueField,
482
+ ...mapping.unitField !== undefined ? { unitField: mapping.unitField } : {}
483
+ }
484
+ ]))
462
485
  };
463
486
  }
464
487
  function deepFreeze(value) {
@@ -3972,7 +3995,6 @@ function prepareTelemetryAppend(context, raw) {
3972
3995
  points: raw.input.points.map((point) => validateTelemetryPoint(context.ontology, point))
3973
3996
  });
3974
3997
  const inputPointCount = telemetryInputPointCount(input, rawInputPointCount);
3975
- validateTelemetryBatch(input, inputPointCount);
3976
3998
  const ontologyRevision = context.projectionRegistry.ontologyRevision;
3977
3999
  const execution = prepareMaterializerExecution(context.projectId, raw.scope);
3978
4000
  if (input.source.kind === "runtime") {
@@ -3991,16 +4013,6 @@ function telemetryInputPointCount(input, rawInputPointCount) {
3991
4013
  return rawInputPointCount;
3992
4014
  return input.points.length;
3993
4015
  }
3994
- function validateTelemetryBatch(input, inputPointCount) {
3995
- if (input.source.kind === "projection") {
3996
- if (input.source.sourceRowCount === 0) {
3997
- throw new MaterializationValidationError("Projection telemetry batches must consume at least one source row; an empty dataset produces no batch commit.");
3998
- }
3999
- if (input.source.sourceRowCount !== inputPointCount + input.source.sourceRowsSkipped) {
4000
- throw new MaterializationValidationError("Projection telemetry sourceRowCount must equal input points plus skipped rows.");
4001
- }
4002
- }
4003
- }
4004
4016
  function prepareRuntimeTelemetry(context, input, source, inputPointCount, ontologyRevision) {
4005
4017
  const identity = createTimedCommitIdentity({
4006
4018
  projectId: context.projectId,
@@ -4014,6 +4026,7 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
4014
4026
  const resolvedProjection = context.projectionRegistry.resolveTelemetry(source.projection.projectionId);
4015
4027
  validateTelemetryProjectionDataset(resolvedProjection, source);
4016
4028
  validateTelemetryOwnership(resolvedProjection, input);
4029
+ validateTelemetryBatchCardinality(resolvedProjection, source, inputPointCount);
4017
4030
  const runIdentity = createProjectionRunMaterializationIdentity({
4018
4031
  resolved: resolvedProjection,
4019
4032
  datasetVersion: source.datasetVersion,
@@ -4036,6 +4049,23 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
4036
4049
  runIdentity
4037
4050
  };
4038
4051
  }
4052
+ function validateTelemetryBatchCardinality(resolved, source, inputPointCount) {
4053
+ if (source.sourceRowCount === 0) {
4054
+ throw new MaterializationValidationError("Projection telemetry batches must consume at least one source row; an empty dataset produces no batch commit.");
4055
+ }
4056
+ const mappedPropertyCount = resolved.ownership.telemetry.length;
4057
+ if (mappedPropertyCount === 0) {
4058
+ throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' must own at least one telemetry property.`);
4059
+ }
4060
+ const sourceRowsEmitted = source.sourceRowCount - source.sourceRowsSkipped;
4061
+ const maximumPointCount = sourceRowsEmitted * mappedPropertyCount;
4062
+ if (!Number.isSafeInteger(maximumPointCount)) {
4063
+ throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' batch point capacity exceeds the safe integer range.`);
4064
+ }
4065
+ if (inputPointCount < sourceRowsEmitted || inputPointCount > maximumPointCount) {
4066
+ throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' must emit between ${sourceRowsEmitted} and ${maximumPointCount} points for ${source.sourceRowCount} source rows with ${source.sourceRowsSkipped} skipped.`);
4067
+ }
4068
+ }
4039
4069
  function validateTelemetryProjectionDataset(resolved, source) {
4040
4070
  if (resolved.datasetId === source.datasetVersion.datasetId)
4041
4071
  return;
@@ -4298,4 +4328,4 @@ function createOntologyMaterializer(input) {
4298
4328
  }
4299
4329
  export { computeOntologyRevision, computeProjectionRevision, computeProjectionOwnershipHash, ProjectionRegistry, createActionIdempotencyKey, createRuntimeIdempotencyKey, createProjectionIdempotencyKey, createRuntimeTelemetryIdempotencyKey, createProjectionTelemetryIdempotencyKey, createCommitIdentity, timestampCommitIdentity, createTimedCommitIdentity, createProjectionMaterializationId, createLinkScopeFingerprint, normalizeJsonProperties, normalizeOntologyEditCommit, normalizeProjectionExecution, normalizeProjectionSourceEntry, normalizeTelemetryAppend, OntologyMaterializer, createOntologyMaterializer };
4300
4330
 
4301
- //# debugId=E68F145E5D3DE1BE64756E2164756E21
4331
+ //# debugId=D96E192C1BE0917864756E2164756E21