@sixb/core 0.1.14 → 0.1.16

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 (259) hide show
  1. package/dist/actions/index.js +26 -26
  2. package/dist/actions/worker.js +1 -1
  3. package/dist/agents/index.js +41 -41
  4. package/dist/agents/index.js.map +1 -1
  5. package/dist/agents/streams/index.js +2 -2
  6. package/dist/agents/streams/internal.js +2 -2
  7. package/dist/auth/index.js +6 -6
  8. package/dist/authorization/index.js +3 -3
  9. package/dist/bootstrap/index.js +44 -44
  10. package/dist/{chunk-6rzb1g6h.js → chunk-2xvgy3x5.js} +2 -2
  11. package/dist/{chunk-16jenmzw.js → chunk-3q7z9hd4.js} +33 -33
  12. package/dist/{chunk-16jenmzw.js.map → chunk-3q7z9hd4.js.map} +1 -1
  13. package/dist/{chunk-hxgj4kzd.js → chunk-40qb8wpe.js} +11 -11
  14. package/dist/{chunk-hxgj4kzd.js.map → chunk-40qb8wpe.js.map} +3 -3
  15. package/dist/{chunk-vn3yh259.js → chunk-4gmng3vf.js} +1 -1
  16. package/dist/{chunk-znw0zvy4.js → chunk-4wn7bxxa.js} +25 -7
  17. package/dist/chunk-4wn7bxxa.js.map +12 -0
  18. package/dist/{chunk-gct3m1da.js → chunk-667x4drs.js} +3 -3
  19. package/dist/{chunk-rzcjp5m2.js → chunk-69kt9q43.js} +2 -2
  20. package/dist/{chunk-3qpcrcj8.js → chunk-6aawea28.js} +2 -4
  21. package/dist/chunk-6aawea28.js.map +10 -0
  22. package/dist/{chunk-rzkr70gr.js → chunk-6fsr7y93.js} +5 -1
  23. package/dist/{chunk-rzkr70gr.js.map → chunk-6fsr7y93.js.map} +3 -3
  24. package/dist/{chunk-3fpgxpsq.js → chunk-6z1q7j19.js} +144 -73
  25. package/dist/{chunk-3fpgxpsq.js.map → chunk-6z1q7j19.js.map} +6 -6
  26. package/dist/{chunk-ypj2wqtj.js → chunk-70jmg2zx.js} +2 -2
  27. package/dist/{chunk-m8zkvep1.js → chunk-7g2gjvah.js} +1 -1
  28. package/dist/{chunk-pvgpckm1.js → chunk-8x74221e.js} +10 -10
  29. package/dist/{chunk-ma1mhh7w.js → chunk-a7ne02hk.js} +6 -6
  30. package/dist/{chunk-bxx3ms5t.js → chunk-b9y8hcm2.js} +2 -2
  31. package/dist/{chunk-ww185kt6.js → chunk-chdg6eqq.js} +2 -2
  32. package/dist/{chunk-y487ywrv.js → chunk-cq44v1a6.js} +4 -4
  33. package/dist/{chunk-4ypbe95r.js → chunk-cxj8y8t0.js} +2 -2
  34. package/dist/{chunk-3a338wrp.js → chunk-dp7yk20b.js} +1 -1
  35. package/dist/{chunk-dv4ct8mp.js → chunk-dsv8kdgk.js} +4 -4
  36. package/dist/{chunk-dsfw1bdr.js → chunk-f72rbvsb.js} +2 -2
  37. package/dist/{chunk-4tnrzqqh.js → chunk-fj1dvp37.js} +1 -1
  38. package/dist/{chunk-ht4a7mjg.js → chunk-g4rbm4a6.js} +42 -8
  39. package/dist/{chunk-ht4a7mjg.js.map → chunk-g4rbm4a6.js.map} +3 -3
  40. package/dist/{chunk-wnxabtn4.js → chunk-gkxsenvp.js} +19 -11
  41. package/dist/{chunk-wnxabtn4.js.map → chunk-gkxsenvp.js.map} +4 -4
  42. package/dist/{chunk-vef6qa14.js → chunk-gmdvns8f.js} +2 -2
  43. package/dist/{chunk-728fp090.js → chunk-h044jb97.js} +1072 -1075
  44. package/dist/chunk-h044jb97.js.map +15 -0
  45. package/dist/{chunk-00pfcqh4.js → chunk-h4138ww2.js} +130 -71
  46. package/dist/{chunk-00pfcqh4.js.map → chunk-h4138ww2.js.map} +5 -5
  47. package/dist/{chunk-yvf2jqj8.js → chunk-h866d223.js} +1 -1
  48. package/dist/{chunk-qma80ych.js → chunk-hn2r7z41.js} +3 -2
  49. package/dist/chunk-hn2r7z41.js.map +11 -0
  50. package/dist/{chunk-bdhfn0ww.js → chunk-kkqwzy6h.js} +1 -1
  51. package/dist/{chunk-wn7mznxc.js → chunk-kttr5ftm.js} +5 -5
  52. package/dist/{chunk-kxea54yg.js → chunk-kvysp909.js} +3 -3
  53. package/dist/{chunk-p1683c0v.js → chunk-kyjcwqz6.js} +5 -2
  54. package/dist/{chunk-p1683c0v.js.map → chunk-kyjcwqz6.js.map} +3 -3
  55. package/dist/{chunk-ffwvdgk1.js → chunk-nj0020ay.js} +1 -1
  56. package/dist/{chunk-q2xghyft.js → chunk-nkbev3tr.js} +5 -5
  57. package/dist/{chunk-cbn96bve.js → chunk-nvymebc1.js} +2 -2
  58. package/dist/{chunk-2fv8sajb.js → chunk-qnd7ehe5.js} +2 -2
  59. package/dist/{chunk-jfdggg1p.js → chunk-sbcm1b92.js} +5 -5
  60. package/dist/{chunk-d8yes9yx.js → chunk-swxzncrv.js} +1 -1
  61. package/dist/{chunk-drz59ve0.js → chunk-tkdbge6v.js} +1 -1
  62. package/dist/{chunk-ky7zpbtt.js → chunk-tnvafr7g.js} +1 -1
  63. package/dist/{chunk-y6vnvayj.js → chunk-vjcd8d27.js} +1 -1
  64. package/dist/{chunk-hj0n3c2p.js → chunk-vjqt7q3a.js} +45 -27
  65. package/dist/{chunk-hj0n3c2p.js.map → chunk-vjqt7q3a.js.map} +3 -3
  66. package/dist/{chunk-z9h698s8.js → chunk-vsvrv7n8.js} +1 -1
  67. package/dist/{chunk-xgptywp0.js → chunk-y2aq6ag9.js} +1 -1
  68. package/dist/{chunk-e2c5yxfe.js → chunk-zb47r1c8.js} +2 -2
  69. package/dist/{chunk-3nx8vj5a.js → chunk-zvmr2hqk.js} +3 -2
  70. package/dist/chunk-zvmr2hqk.js.map +12 -0
  71. package/dist/deploy/define.d.ts +4 -0
  72. package/dist/deploy/define.d.ts.map +1 -0
  73. package/dist/deploy/index.d.ts +3 -0
  74. package/dist/deploy/index.d.ts.map +1 -0
  75. package/dist/deploy/index.js +10 -0
  76. package/dist/deploy/index.js.map +10 -0
  77. package/dist/deploy/internal.d.ts +3 -0
  78. package/dist/deploy/internal.d.ts.map +1 -0
  79. package/dist/deploy/internal.js +244 -0
  80. package/dist/deploy/internal.js.map +11 -0
  81. package/dist/deploy/services.d.ts +8 -0
  82. package/dist/deploy/services.d.ts.map +1 -0
  83. package/dist/deploy/types.d.ts +309 -0
  84. package/dist/deploy/types.d.ts.map +1 -0
  85. package/dist/deploy/validation.d.ts +7 -0
  86. package/dist/deploy/validation.d.ts.map +1 -0
  87. package/dist/error-reporting/internal.js +3 -3
  88. package/dist/errors/catalog.d.ts +4 -0
  89. package/dist/errors/catalog.d.ts.map +1 -1
  90. package/dist/errors/internal.js +1 -1
  91. package/dist/events/index.js +3 -3
  92. package/dist/execution/agent.js +38 -38
  93. package/dist/execution/primitive.js +34 -34
  94. package/dist/execution/request.js +36 -36
  95. package/dist/execution/request.js.map +1 -1
  96. package/dist/index.js +56 -56
  97. package/dist/index.js.map +1 -1
  98. package/dist/maintenance/ontology-maintenance.d.ts +2 -0
  99. package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
  100. package/dist/maintenance/types.d.ts +8 -2
  101. package/dist/maintenance/types.d.ts.map +1 -1
  102. package/dist/materialization/dataset-watermark.d.ts +6 -1
  103. package/dist/materialization/dataset-watermark.d.ts.map +1 -1
  104. package/dist/materialization/index.js +1 -1
  105. package/dist/materialization/model.d.ts +6 -0
  106. package/dist/materialization/model.d.ts.map +1 -1
  107. package/dist/materializer/index.js +22 -22
  108. package/dist/materializer/index.js.map +1 -1
  109. package/dist/materializer/projections/finish-run.d.ts.map +1 -1
  110. package/dist/materializer/projections/replace.d.ts.map +1 -1
  111. package/dist/materializer/projections/source-materialization.d.ts +6 -2
  112. package/dist/materializer/projections/source-materialization.d.ts.map +1 -1
  113. package/dist/models/embedding-model.d.ts +4 -0
  114. package/dist/models/embedding-model.d.ts.map +1 -1
  115. package/dist/models/execution/index.js +19 -19
  116. package/dist/models/index.js +2 -2
  117. package/dist/objects/index.js +25 -25
  118. package/dist/objects/query/index.js +21 -21
  119. package/dist/objects/query/index.js.map +1 -1
  120. package/dist/objects/vectors/indexing-generate.d.ts.map +1 -1
  121. package/dist/objects/vectors/profile.d.ts.map +1 -1
  122. package/dist/objects/vectors/query.d.ts +1 -1
  123. package/dist/objects/vectors/query.d.ts.map +1 -1
  124. package/dist/objects/vectors/resolve-query.d.ts.map +1 -1
  125. package/dist/objects/vectors/types.d.ts +1 -1
  126. package/dist/objects/vectors/types.d.ts.map +1 -1
  127. package/dist/ontology/builders.d.ts +13 -4
  128. package/dist/ontology/builders.d.ts.map +1 -1
  129. package/dist/ontology/index.js +3 -3
  130. package/dist/ontology/internal.js +2 -2
  131. package/dist/ontology/vector-profiles.d.ts.map +1 -1
  132. package/dist/pipelines/index.js +23 -23
  133. package/dist/projections/internal.js +20 -20
  134. package/dist/projections/types.d.ts +1 -1
  135. package/dist/projections/types.d.ts.map +1 -1
  136. package/dist/queues/in-memory.d.ts +1 -1
  137. package/dist/queues/in-memory.d.ts.map +1 -1
  138. package/dist/runtime/internal.js +23 -23
  139. package/dist/sandboxes/index.js +5 -5
  140. package/dist/shares/internal.js +18 -18
  141. package/dist/shares/internal.js.map +1 -1
  142. package/dist/storage/action-runs/failure.js +2 -2
  143. package/dist/storage/agents/provider.js +1 -1
  144. package/dist/storage/ai-limits/enforcement.js +2 -2
  145. package/dist/storage/connector-connections/provider.js +1 -1
  146. package/dist/storage/file-upload-sessions/provider.js +7 -7
  147. package/dist/storage/index.d.ts +2 -2
  148. package/dist/storage/index.d.ts.map +1 -1
  149. package/dist/storage/index.js +33 -33
  150. package/dist/storage/index.js.map +1 -1
  151. package/dist/storage/internal.js +1 -1
  152. package/dist/storage/ontology/in-memory/sources.d.ts +6 -3
  153. package/dist/storage/ontology/in-memory/sources.d.ts.map +1 -1
  154. package/dist/storage/ontology/index.d.ts +1 -1
  155. package/dist/storage/ontology/index.d.ts.map +1 -1
  156. package/dist/storage/ontology/provider.d.ts +16 -3
  157. package/dist/storage/ontology/provider.d.ts.map +1 -1
  158. package/dist/storage/ontology/provider.js +8 -4
  159. package/dist/storage/ontology/provider.js.map +1 -1
  160. package/dist/storage/ontology/sources.d.ts +36 -8
  161. package/dist/storage/ontology/sources.d.ts.map +1 -1
  162. package/dist/storage/projection-runs/in-memory.d.ts +3 -1
  163. package/dist/storage/projection-runs/in-memory.d.ts.map +1 -1
  164. package/dist/storage/projection-runs/index.d.ts +1 -1
  165. package/dist/storage/projection-runs/index.d.ts.map +1 -1
  166. package/dist/storage/projection-runs/lifecycle.d.ts +12 -0
  167. package/dist/storage/projection-runs/lifecycle.d.ts.map +1 -1
  168. package/dist/storage/projection-runs/provider.js +10 -4
  169. package/dist/storage/projection-runs/provider.js.map +1 -1
  170. package/dist/storage/projection-runs/types.d.ts +32 -1
  171. package/dist/storage/projection-runs/types.d.ts.map +1 -1
  172. package/dist/storage/workflow-runs/provider.js +7 -7
  173. package/dist/syncs/index.js +24 -24
  174. package/dist/testing/index.js +306 -64
  175. package/dist/testing/index.js.map +4 -4
  176. package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
  177. package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
  178. package/dist/webhooks/internal.js +19 -19
  179. package/dist/webhooks/internal.js.map +1 -1
  180. package/dist/workers/index.js +1 -1
  181. package/dist/workflows/index.js +41 -41
  182. package/package.json +13 -1
  183. package/src/deploy/define.ts +6 -0
  184. package/src/deploy/index.ts +41 -0
  185. package/src/deploy/internal.ts +7 -0
  186. package/src/deploy/services.ts +51 -0
  187. package/src/deploy/types.ts +338 -0
  188. package/src/deploy/validation.ts +261 -0
  189. package/src/errors/catalog.ts +4 -0
  190. package/src/maintenance/ontology-maintenance.ts +32 -2
  191. package/src/maintenance/types.ts +8 -2
  192. package/src/materialization/dataset-watermark.ts +6 -4
  193. package/src/materialization/model.ts +7 -0
  194. package/src/materializer/README.md +26 -6
  195. package/src/materializer/projections/finish-run.ts +129 -26
  196. package/src/materializer/projections/replace.ts +67 -49
  197. package/src/materializer/projections/source-materialization.ts +11 -6
  198. package/src/models/embedding-model.ts +12 -0
  199. package/src/models/execution/embedding.ts +5 -1
  200. package/src/objects/query/validate.ts +1 -10
  201. package/src/objects/vectors/README.md +8 -0
  202. package/src/objects/vectors/handle.ts +1 -1
  203. package/src/objects/vectors/indexing-generate.ts +5 -1
  204. package/src/objects/vectors/profile.ts +2 -0
  205. package/src/objects/vectors/query.ts +18 -4
  206. package/src/objects/vectors/resolve-query.ts +9 -5
  207. package/src/objects/vectors/types.ts +3 -1
  208. package/src/ontology/builders.ts +21 -7
  209. package/src/ontology/vector-profiles.ts +1 -0
  210. package/src/projections/types.ts +1 -0
  211. package/src/storage/index.ts +6 -1
  212. package/src/storage/ontology/in-memory/sources.ts +119 -55
  213. package/src/storage/ontology/index.ts +4 -1
  214. package/src/storage/ontology/provider.ts +64 -7
  215. package/src/storage/ontology/sources.ts +42 -8
  216. package/src/storage/projection-runs/in-memory.ts +41 -2
  217. package/src/storage/projection-runs/index.ts +2 -0
  218. package/src/storage/projection-runs/lifecycle.ts +61 -4
  219. package/src/storage/projection-runs/types.ts +41 -1
  220. package/src/testing/ontology-storage-contract.ts +141 -15
  221. package/src/testing/projection-run-storage-contract.ts +174 -1
  222. package/dist/chunk-3nx8vj5a.js.map +0 -12
  223. package/dist/chunk-3qpcrcj8.js.map +0 -10
  224. package/dist/chunk-728fp090.js.map +0 -15
  225. package/dist/chunk-qma80ych.js.map +0 -11
  226. package/dist/chunk-znw0zvy4.js.map +0 -12
  227. /package/dist/{chunk-6rzb1g6h.js.map → chunk-2xvgy3x5.js.map} +0 -0
  228. /package/dist/{chunk-vn3yh259.js.map → chunk-4gmng3vf.js.map} +0 -0
  229. /package/dist/{chunk-gct3m1da.js.map → chunk-667x4drs.js.map} +0 -0
  230. /package/dist/{chunk-rzcjp5m2.js.map → chunk-69kt9q43.js.map} +0 -0
  231. /package/dist/{chunk-ypj2wqtj.js.map → chunk-70jmg2zx.js.map} +0 -0
  232. /package/dist/{chunk-m8zkvep1.js.map → chunk-7g2gjvah.js.map} +0 -0
  233. /package/dist/{chunk-pvgpckm1.js.map → chunk-8x74221e.js.map} +0 -0
  234. /package/dist/{chunk-ma1mhh7w.js.map → chunk-a7ne02hk.js.map} +0 -0
  235. /package/dist/{chunk-bxx3ms5t.js.map → chunk-b9y8hcm2.js.map} +0 -0
  236. /package/dist/{chunk-ww185kt6.js.map → chunk-chdg6eqq.js.map} +0 -0
  237. /package/dist/{chunk-y487ywrv.js.map → chunk-cq44v1a6.js.map} +0 -0
  238. /package/dist/{chunk-4ypbe95r.js.map → chunk-cxj8y8t0.js.map} +0 -0
  239. /package/dist/{chunk-3a338wrp.js.map → chunk-dp7yk20b.js.map} +0 -0
  240. /package/dist/{chunk-dv4ct8mp.js.map → chunk-dsv8kdgk.js.map} +0 -0
  241. /package/dist/{chunk-dsfw1bdr.js.map → chunk-f72rbvsb.js.map} +0 -0
  242. /package/dist/{chunk-4tnrzqqh.js.map → chunk-fj1dvp37.js.map} +0 -0
  243. /package/dist/{chunk-vef6qa14.js.map → chunk-gmdvns8f.js.map} +0 -0
  244. /package/dist/{chunk-yvf2jqj8.js.map → chunk-h866d223.js.map} +0 -0
  245. /package/dist/{chunk-bdhfn0ww.js.map → chunk-kkqwzy6h.js.map} +0 -0
  246. /package/dist/{chunk-wn7mznxc.js.map → chunk-kttr5ftm.js.map} +0 -0
  247. /package/dist/{chunk-kxea54yg.js.map → chunk-kvysp909.js.map} +0 -0
  248. /package/dist/{chunk-ffwvdgk1.js.map → chunk-nj0020ay.js.map} +0 -0
  249. /package/dist/{chunk-q2xghyft.js.map → chunk-nkbev3tr.js.map} +0 -0
  250. /package/dist/{chunk-cbn96bve.js.map → chunk-nvymebc1.js.map} +0 -0
  251. /package/dist/{chunk-2fv8sajb.js.map → chunk-qnd7ehe5.js.map} +0 -0
  252. /package/dist/{chunk-jfdggg1p.js.map → chunk-sbcm1b92.js.map} +0 -0
  253. /package/dist/{chunk-d8yes9yx.js.map → chunk-swxzncrv.js.map} +0 -0
  254. /package/dist/{chunk-drz59ve0.js.map → chunk-tkdbge6v.js.map} +0 -0
  255. /package/dist/{chunk-ky7zpbtt.js.map → chunk-tnvafr7g.js.map} +0 -0
  256. /package/dist/{chunk-y6vnvayj.js.map → chunk-vjcd8d27.js.map} +0 -0
  257. /package/dist/{chunk-z9h698s8.js.map → chunk-vsvrv7n8.js.map} +0 -0
  258. /package/dist/{chunk-xgptywp0.js.map → chunk-y2aq6ag9.js.map} +0 -0
  259. /package/dist/{chunk-e2c5yxfe.js.map → chunk-zb47r1c8.js.map} +0 -0
@@ -63,7 +63,11 @@ export async function generateVectors(
63
63
  )
64
64
  }
65
65
 
66
- const result = await model.embed({ texts: entries.map((entry) => entry.input.text), signal })
66
+ const result = await model.embed({
67
+ texts: entries.map((entry) => entry.input.text),
68
+ purpose: "document",
69
+ signal,
70
+ })
67
71
  const values = normalizeEmbeddingResult(
68
72
  result,
69
73
  entries.length,
@@ -13,6 +13,8 @@ export function vectorConfiguration(profile: ObjectVectorSearchProfile): string
13
13
  model: profile.model.modelId,
14
14
  representation: profile.model.definition.representation ?? { name: profile.model.modelId },
15
15
  dimensions: profile.model.definition.dimensions,
16
+ // Include retrieval preparation without changing existing symmetric identities.
17
+ ...(profile.model.definition.inputMode === "asymmetric" ? { inputMode: "asymmetric" } : {}),
16
18
  metric: "cosine",
17
19
  precision: "float32",
18
20
  normalization: "l2-v1",
@@ -6,11 +6,25 @@ export function hasVectorProfile(query: ObjectQuery): boolean {
6
6
  return "input" in query && hasVectorProfile(query.input)
7
7
  }
8
8
 
9
- /** V1 supports one exact top-k, with filters applied before ranking. */
9
+ /** Rank one eligible object set; validation resolves its type and admits every traversed edge. */
10
10
  export function isVectorProfileQuery(query: ObjectQuery): boolean {
11
11
  if (query.kind === "limit" || query.kind === "project") return isVectorProfileQuery(query.input)
12
12
  if (query.kind !== "vector" || !query.profile) return false
13
- let input = query.input
14
- while (input.kind === "filter") input = input.input
15
- return input.kind === "start" && !input.includeSubtypes
13
+ return isVectorCandidateQuery(query.input)
14
+ }
15
+
16
+ function isVectorCandidateQuery(query: ObjectQuery): boolean {
17
+ switch (query.kind) {
18
+ case "start":
19
+ return !query.includeSubtypes
20
+ case "refs":
21
+ return true
22
+ case "filter":
23
+ case "traverse":
24
+ return isVectorCandidateQuery(query.input)
25
+ case "set":
26
+ return query.inputs.every(isVectorCandidateQuery)
27
+ default:
28
+ return false
29
+ }
16
30
  }
@@ -3,6 +3,7 @@ import { type EmbeddingModel, sameEmbeddingModel } from "../../models/embedding-
3
3
  import type { OntologyRegistry } from "../../ontology"
4
4
  import { ObjectQueryExecutionError } from "../query/errors"
5
5
  import type { ObjectQuery, ObjectQueryVector } from "../query/ir"
6
+ import { resolveObjectQueryResultShape } from "../query/validate"
6
7
  import { normalizeVector } from "./profile"
7
8
 
8
9
  const QUERY_EMBEDDING_TIMEOUT_MS = 30_000
@@ -30,16 +31,19 @@ function resolveProfileEmbeddingModel(
30
31
  ontology: OntologyRegistry,
31
32
  models: EmbeddingModelCatalog | undefined
32
33
  ): EmbeddingModel {
33
- let input = query.input
34
- while (input.kind === "filter") input = input.input
35
- if (input.kind !== "start" || !query.profile) {
34
+ const { objectTypeIds } = resolveObjectQueryResultShape(query.input, {
35
+ ontology,
36
+ normalize: false,
37
+ })
38
+ const objectTypeId = objectTypeIds.length === 1 ? objectTypeIds[0] : undefined
39
+ if (!objectTypeId || !query.profile) {
36
40
  throw new ObjectQueryExecutionError(
37
41
  "embedding_model_unavailable",
38
42
  "Vector search requires the embedding model registered for its profile."
39
43
  )
40
44
  }
41
45
 
42
- const profile = ontology.resolveObjectType(input.objectTypeId).search?.vectors?.[query.profile]
46
+ const profile = ontology.resolveObjectType(objectTypeId).search?.vectors?.[query.profile]
43
47
  if (!profile) {
44
48
  throw new ObjectQueryExecutionError(
45
49
  "embedding_model_unavailable",
@@ -69,7 +73,7 @@ async function embedSearchText(
69
73
  const timeout = AbortSignal.timeout(QUERY_EMBEDDING_TIMEOUT_MS)
70
74
  const requestSignal = signal ? AbortSignal.any([signal, timeout]) : timeout
71
75
  requestSignal.throwIfAborted()
72
- const result = await model.embed({ texts: [text], signal: requestSignal })
76
+ const result = await model.embed({ texts: [text], purpose: "query", signal: requestSignal })
73
77
  requestSignal.throwIfAborted()
74
78
 
75
79
  if (!Array.isArray(result?.vectors) || result.vectors.length !== 1) {
@@ -2,7 +2,9 @@ import type { ObjectType } from "../../ontology"
2
2
 
3
3
  export type VectorProfileName<T extends ObjectType> = T extends { search: { vectors: infer P } }
4
4
  ? Extract<keyof P, string>
5
- : never
5
+ : string extends T["id"]
6
+ ? string
7
+ : never
6
8
 
7
9
  export interface ObjectVectorHandle {
8
10
  /** Generate and atomically store this profile using its configured model. Conflicts are not retried. */
@@ -35,6 +35,7 @@ import type {
35
35
  ObjectLink,
36
36
  ObjectLinkTargetMetadata,
37
37
  ObjectType,
38
+ ObjectVectorSearchProfile,
38
39
  Ontology,
39
40
  Property,
40
41
  PropertyMode,
@@ -446,19 +447,32 @@ export type DirectLinkResult<
446
447
  > = LinkResult<TId, TTargetObjectTypeId, TOptions> & ObjectLinkTargetMetadata<TTarget>
447
448
 
448
449
  type ObjectTypeIdArray<TTargets extends readonly ObjectType[]> = Array<TTargets[number]["id"]>
450
+ /** Keep profile names without carrying provider types through every linked declaration. */
449
451
  export type DirectLinkTarget<
450
452
  TId extends string,
451
453
  TName extends string,
452
454
  TProperties extends Property[],
453
- > = ObjectTypeWithPropertyTokens<{
454
- id: TId
455
- name: TName
456
- properties: TProperties
457
- links: ObjectLink[]
458
- }>
455
+ TVectorProfiles extends string = never,
456
+ > = ObjectTypeWithPropertyTokens<
457
+ {
458
+ id: TId
459
+ name: TName
460
+ properties: TProperties
461
+ links: ObjectLink[]
462
+ } & ([TVectorProfiles] extends [never]
463
+ ? unknown
464
+ : { search: { vectors: Record<TVectorProfiles, ObjectVectorSearchProfile> } })
465
+ >
459
466
 
460
467
  type DirectLinkTargetFor<TTarget extends ObjectType> = TTarget extends ObjectTypeWithPropertyTokens
461
- ? DirectLinkTarget<TTarget["id"], TTarget["name"], TTarget["properties"]>
468
+ ? DirectLinkTarget<
469
+ TTarget["id"],
470
+ TTarget["name"],
471
+ TTarget["properties"],
472
+ TTarget extends { search: { vectors: infer TProfiles } }
473
+ ? Extract<keyof TProfiles, string>
474
+ : never
475
+ >
462
476
  : TTarget
463
477
 
464
478
  /**
@@ -17,6 +17,7 @@ export function snapshotVectorProfiles(
17
17
  providerId,
18
18
  modelId,
19
19
  dimensions: definition.dimensions,
20
+ ...(definition.inputMode ? { inputMode: definition.inputMode } : {}),
20
21
  ...(definition.representation
21
22
  ? {
22
23
  representation: Object.freeze({
@@ -6,6 +6,7 @@ export const PROJECTION_RUN_FAILURE_CODES = [
6
6
  "runtime.cancelled",
7
7
  "queue.enqueue_failed",
8
8
  "projection.execution_failed",
9
+ "storage.unavailable",
9
10
  ] as const satisfies readonly [SixbErrorCode, ...SixbErrorCode[]]
10
11
 
11
12
  export type ProjectionRunFailureCode = (typeof PROJECTION_RUN_FAILURE_CODES)[number]
@@ -449,8 +449,11 @@ export {
449
449
  snapshotObjectReadExecutionLimits,
450
450
  } from "./objects"
451
451
  export type {
452
+ AbandonRunSourceMaterializationInput,
452
453
  AbandonSourceMaterializationCandidateInput,
453
454
  AbandonSourceMaterializationInput,
455
+ AdoptedSourceMaterialization,
456
+ AdoptSourceMaterializationInput,
454
457
  ApplyMaterializationChunkInput,
455
458
  ApplyMaterializationResult,
456
459
  AssertSourceMaterializationExecution,
@@ -530,9 +533,9 @@ export type {
530
533
  OntologyStorage,
531
534
  OntologyVectorStorage,
532
535
  ProjectionOntologyCommitIntent,
536
+ PurgeAbandonedSourceMaterializationsInput,
533
537
  PurgePublishedOntologyOutboxInput,
534
538
  ReadMaterializationObjectExistenceInput,
535
- ReclaimSourceMaterializationInput,
536
539
  RescheduleOntologyOutboxLeaseInput,
537
540
  SourceActivationWrite,
538
541
  SourceReplacementLinkState,
@@ -595,6 +598,7 @@ export {
595
598
  export type {
596
599
  AdvanceProjectionTelemetryCheckpointInput,
597
600
  FailProjectionRunEnqueueInput,
601
+ FindSupersedingProjectionRunInput,
598
602
  FinishProjectionRunInput,
599
603
  LinkProjectionRunRecord,
600
604
  LinkProjectionTarget,
@@ -616,6 +620,7 @@ export type {
616
620
  ProjectionTarget,
617
621
  ProjectionTelemetryCheckpoint,
618
622
  QueueProjectionRunInput,
623
+ RecordProjectionAttemptFailureInput,
619
624
  RecordProjectionMissingTargetInput,
620
625
  StartOrReclaimProjectionRunInput,
621
626
  TelemetryProjectionRunRecord,
@@ -16,8 +16,11 @@ import {
16
16
  sourceStageRoots,
17
17
  } from "../provider"
18
18
  import type {
19
+ AbandonRunSourceMaterializationInput,
19
20
  AbandonSourceMaterializationCandidateInput,
20
21
  AbandonSourceMaterializationInput,
22
+ AdoptedSourceMaterialization,
23
+ AdoptSourceMaterializationInput,
21
24
  AssertSourceMaterializationExecution,
22
25
  BeginSourceMaterializationInput,
23
26
  CleanupTerminalSourceMaterializationsInput,
@@ -26,7 +29,7 @@ import type {
26
29
  MarkSourceMaterializationReadyInput,
27
30
  OntologySourceRecord,
28
31
  OntologySourceStorage,
29
- ReclaimSourceMaterializationInput,
32
+ PurgeAbandonedSourceMaterializationsInput,
30
33
  StageSourceAssertion,
31
34
  StageSourceRowsInput,
32
35
  StageSourceRowsResult,
@@ -38,6 +41,7 @@ import {
38
41
  assertNonblank,
39
42
  type InMemoryOntologyState,
40
43
  type InMemorySourceMaterialization,
44
+ type InMemorySourceRoot,
41
45
  insertBounded,
42
46
  sourceMaterializationKey,
43
47
  sourceMaterializationRecord,
@@ -78,7 +82,7 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
78
82
  )
79
83
  if (nonterminal.length > 0) {
80
84
  throw sourceConflict(
81
- `Projection run '${input.execution.projectionRunId}' already has a nonterminal source materialization; reclaim it before beginning another.`
85
+ `Projection run '${input.execution.projectionRunId}' already has a nonterminal source materialization; adopt it before beginning another.`
82
86
  )
83
87
  }
84
88
 
@@ -191,8 +195,42 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
191
195
  })
192
196
  }
193
197
 
198
+ async adopt(
199
+ input: AdoptSourceMaterializationInput
200
+ ): Promise<AdoptedSourceMaterialization | null> {
201
+ return this.runRootOperation(async () => {
202
+ assertProjectAndSource(input)
203
+ assertSourceExecutionIdentity(input.execution.projectionRunId, input.execution.executionToken)
204
+ assertCanonicalTimestamp(input.adoptedAt, "Source adoptedAt")
205
+ await this.assertCurrentExecution(input)
206
+ const [candidate, ...others] = this.findRunCandidates(
207
+ input.projectId,
208
+ input.source.projectionId,
209
+ input.execution.projectionRunId
210
+ )
211
+ if (!candidate) return null
212
+ if (others.length > 0) throw multipleRunCandidates(input.execution.projectionRunId)
213
+ const [key, materialization] = candidate
214
+ const adopted: InMemorySourceMaterialization = {
215
+ ...materialization,
216
+ executionToken: input.execution.executionToken,
217
+ // Workers' clocks differ; adoption never moves the record back in time.
218
+ updatedAt:
219
+ input.adoptedAt > materialization.updatedAt ? input.adoptedAt : materialization.updatedAt,
220
+ }
221
+ this.state.sourceMaterializations.set(key, adopted)
222
+ return {
223
+ record: sourceMaterializationRecord(adopted),
224
+ resumeStagingOrdinal:
225
+ adopted.status === "ready"
226
+ ? (adopted.rootCount ?? 0)
227
+ : Math.max(0, ...adopted.ordinalRoots.keys()),
228
+ }
229
+ })
230
+ }
231
+
194
232
  async abandon(input: AbandonSourceMaterializationCandidateInput): Promise<OntologySourceRecord>
195
- async abandon(input: ReclaimSourceMaterializationInput): Promise<OntologySourceRecord | null>
233
+ async abandon(input: AbandonRunSourceMaterializationInput): Promise<OntologySourceRecord | null>
196
234
  async abandon(input: AbandonSourceMaterializationInput): Promise<OntologySourceRecord | null> {
197
235
  return this.runRootOperation(async () => {
198
236
  assertProjectAndSource(input)
@@ -201,7 +239,7 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
201
239
  await this.assertCurrentExecution(input)
202
240
  return input.kind === "candidate"
203
241
  ? this.abandonCandidate(input)
204
- : this.abandonForReclaim(input)
242
+ : this.abandonRunCandidate(input)
205
243
  })
206
244
  }
207
245
 
@@ -211,18 +249,14 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
211
249
  return this.runRootOperation(() => {
212
250
  assertNonblank(input.projectId, "Terminal source cleanup project id")
213
251
  assertCanonicalTimestamp(input.terminalBefore, "Terminal source cleanup cutoff")
214
- if (!Number.isSafeInteger(input.limit) || input.limit <= 0) {
215
- throw new MaterializationValidationError(
216
- "Terminal source cleanup limit must be a positive safe integer."
217
- )
218
- }
252
+ assertCleanupLimit(input.limit)
219
253
 
220
254
  const candidates: [string, InMemorySourceMaterialization][] = []
221
255
  for (const entry of this.state.sourceMaterializations.entries()) {
222
256
  const materialization = entry[1]
223
257
  if (
224
258
  materialization.projectId !== input.projectId ||
225
- (materialization.status !== "superseded" && materialization.status !== "abandoned") ||
259
+ materialization.status !== "superseded" ||
226
260
  materialization.terminalAt === null ||
227
261
  materialization.terminalAt >= input.terminalBefore
228
262
  ) {
@@ -239,42 +273,69 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
239
273
  insertBounded(candidates, entry, input.limit, compareTerminalMaterializations)
240
274
  }
241
275
 
242
- let remaining = input.limit
243
- let rowsDeleted = 0
244
- let materializationsDeleted = 0
245
- for (const [key, candidate] of candidates) {
276
+ return this.deleteRetiredRoots(
277
+ candidates,
278
+ input.limit,
279
+ (root) => !root.active && root.retiredAt !== null && root.retiredAt < input.terminalBefore
280
+ )
281
+ })
282
+ }
283
+
284
+ async purgeAbandoned(
285
+ input: PurgeAbandonedSourceMaterializationsInput
286
+ ): Promise<CleanupTerminalSourceMaterializationsResult> {
287
+ return this.runRootOperation(() => {
288
+ assertNonblank(input.projectId, "Abandoned source purge project id")
289
+ assertCleanupLimit(input.limit)
290
+ const abandoned = [...this.state.sourceMaterializations.entries()]
291
+ .filter(
292
+ ([, materialization]) =>
293
+ materialization.projectId === input.projectId && materialization.status === "abandoned"
294
+ )
295
+ .sort(compareTerminalMaterializations)
296
+ return this.deleteRetiredRoots(abandoned, input.limit, () => true)
297
+ })
298
+ }
299
+
300
+ private deleteRetiredRoots(
301
+ candidates: readonly [string, InMemorySourceMaterialization][],
302
+ limit: number,
303
+ retired: (root: InMemorySourceRoot) => boolean
304
+ ): CleanupTerminalSourceMaterializationsResult {
305
+ let remaining = limit
306
+ let rowsDeleted = 0
307
+ let materializationsDeleted = 0
308
+ for (const [key, candidate] of candidates) {
309
+ if (remaining === 0) break
310
+ const current = this.state.sourceMaterializations.get(key)
311
+ if (current !== candidate) continue
312
+ current.rootOrdinals.clear()
313
+ current.ordinalRoots.clear()
314
+ for (const [rootKey, root] of current.roots) {
246
315
  if (remaining === 0) break
247
- const current = this.state.sourceMaterializations.get(key)
248
- if (current !== candidate) continue
249
- current.rootOrdinals.clear()
250
- current.ordinalRoots.clear()
251
- for (const [rootKey, root] of current.roots) {
316
+ if (!retired(root)) continue
317
+ for (const entityKey of root.entityKeys) {
252
318
  if (remaining === 0) break
253
- if (root.active || root.retiredAt === null || root.retiredAt >= input.terminalBefore)
254
- continue
255
- for (const entityKey of root.entityKeys) {
256
- if (remaining === 0) break
257
- current.rowsByEntity.delete(entityKey)
258
- root.entityKeys.delete(entityKey)
259
- rowsDeleted += 1
260
- remaining -= 1
261
- }
262
- if (root.entityKeys.size === 0 && remaining > 0) {
263
- current.roots.delete(rootKey)
264
- current.rootOrdinals.delete(rootKey)
265
- current.ordinalRoots.delete(root.stagingOrdinal)
266
- rowsDeleted += 1
267
- remaining -= 1
268
- }
319
+ current.rowsByEntity.delete(entityKey)
320
+ root.entityKeys.delete(entityKey)
321
+ rowsDeleted += 1
322
+ remaining -= 1
269
323
  }
270
- if (current.roots.size === 0 && current.rowsByEntity.size === 0 && remaining > 0) {
271
- this.state.sourceMaterializations.delete(key)
272
- materializationsDeleted += 1
324
+ if (root.entityKeys.size === 0 && remaining > 0) {
325
+ current.roots.delete(rootKey)
326
+ current.rootOrdinals.delete(rootKey)
327
+ current.ordinalRoots.delete(root.stagingOrdinal)
328
+ rowsDeleted += 1
273
329
  remaining -= 1
274
330
  }
275
331
  }
276
- return { rowsDeleted, materializationsDeleted }
277
- })
332
+ if (current.roots.size === 0 && current.rowsByEntity.size === 0 && remaining > 0) {
333
+ this.state.sourceMaterializations.delete(key)
334
+ materializationsDeleted += 1
335
+ remaining -= 1
336
+ }
337
+ }
338
+ return { rowsDeleted, materializationsDeleted }
278
339
  }
279
340
 
280
341
  async summarizeTerminal(
@@ -356,26 +417,15 @@ export class InMemoryOntologySourceStorage implements OntologySourceStorage {
356
417
  return this.transitionToAbandoned(materialization, input.abandonedAt)
357
418
  }
358
419
 
359
- private abandonForReclaim(input: ReclaimSourceMaterializationInput): OntologySourceRecord | null {
420
+ private abandonRunCandidate(
421
+ input: AbandonRunSourceMaterializationInput
422
+ ): OntologySourceRecord | null {
360
423
  const candidates = this.findRunCandidates(
361
424
  input.projectId,
362
425
  input.source.projectionId,
363
426
  input.execution.projectionRunId
364
427
  )
365
- if (
366
- candidates.some(
367
- ([, materialization]) => materialization.executionToken === input.execution.executionToken
368
- )
369
- ) {
370
- throw sourceConflict(
371
- `Projection run '${input.execution.projectionRunId}' already has a source materialization owned by the current execution.`
372
- )
373
- }
374
- if (candidates.length > 1) {
375
- throw sourceConflict(
376
- `Projection run '${input.execution.projectionRunId}' has multiple nonterminal source materializations.`
377
- )
378
- }
428
+ if (candidates.length > 1) throw multipleRunCandidates(input.execution.projectionRunId)
379
429
  const candidate = candidates[0]?.[1]
380
430
  return candidate ? this.transitionToAbandoned(candidate, input.abandonedAt) : null
381
431
  }
@@ -609,6 +659,20 @@ function assertNotBefore(
609
659
  }
610
660
  }
611
661
 
662
+ function assertCleanupLimit(limit: number): void {
663
+ if (!Number.isSafeInteger(limit) || limit <= 0) {
664
+ throw new MaterializationValidationError(
665
+ "Terminal source cleanup limit must be a positive safe integer."
666
+ )
667
+ }
668
+ }
669
+
670
+ function multipleRunCandidates(projectionRunId: string) {
671
+ return sourceConflict(
672
+ `Projection run '${projectionRunId}' has multiple nonterminal source materializations.`
673
+ )
674
+ }
675
+
612
676
  function compareTerminalMaterializations(
613
677
  [, left]: readonly [string, InMemorySourceMaterialization],
614
678
  [, right]: readonly [string, InMemorySourceMaterialization]
@@ -97,8 +97,11 @@ export type {
97
97
  } from "./outbox"
98
98
  export { ONTOLOGY_OUTBOX_FAILURE_CODES } from "./outbox"
99
99
  export type {
100
+ AbandonRunSourceMaterializationInput,
100
101
  AbandonSourceMaterializationCandidateInput,
101
102
  AbandonSourceMaterializationInput,
103
+ AdoptedSourceMaterialization,
104
+ AdoptSourceMaterializationInput,
102
105
  AssertSourceMaterializationExecution,
103
106
  AssertSourceMaterializationExecutionInput,
104
107
  BeginSourceMaterializationInput,
@@ -109,7 +112,7 @@ export type {
109
112
  OntologySourceMaterializationStatus,
110
113
  OntologySourceRecord,
111
114
  OntologySourceStorage,
112
- ReclaimSourceMaterializationInput,
115
+ PurgeAbandonedSourceMaterializationsInput,
113
116
  StageSourceAssertion,
114
117
  StageSourceRoot,
115
118
  StageSourceRowsInput,
@@ -11,6 +11,8 @@ import type {
11
11
  ExpectedObjectRevision,
12
12
  OntologyLinkRef,
13
13
  OntologyObjectRef,
14
+ ProjectionEntityRef,
15
+ ProjectionSourceAssertion,
14
16
  } from "../../materialization/model"
15
17
  import { linkRefKey, objectRefKey, projectionEntityKey } from "../../materialization/refs"
16
18
  import type { OntologyCommitOriginSelector, OntologyCommitWrite } from "./commits"
@@ -716,7 +718,6 @@ export function sourceStageRow(row: StageSourceAssertion): SourceStageRow {
716
718
  export interface SourceStageRoot {
717
719
  readonly root: StageSourceAssertion["root"]
718
720
  readonly rootKey: string
719
- readonly sortKey: string
720
721
  readonly stagingOrdinal: number
721
722
  readonly deleted: boolean
722
723
  }
@@ -763,7 +764,6 @@ export function sourceStageRoots(
763
764
  roots.set(key, {
764
765
  root: row.root,
765
766
  rootKey: key,
766
- sortKey: utf8SortKey(key),
767
767
  stagingOrdinal: row.stagingOrdinal,
768
768
  deleted,
769
769
  })
@@ -965,12 +965,69 @@ export function sourceEntityColumns(entity: StageSourceAssertion["root"]): {
965
965
  }
966
966
  }
967
967
 
968
- export function utf8SortKey(canonicalKey: string): string {
969
- let key = ""
970
- for (const byte of new TextEncoder().encode(canonicalKey)) {
971
- key += byte.toString(16).padStart(2, "0")
968
+ /** The inverse of `projectionEntityKey`, for providers that store only the canonical key. */
969
+ export function sourceEntityFromKey(key: string): ProjectionEntityRef {
970
+ const parts: unknown = JSON.parse(key)
971
+ if (Array.isArray(parts) && parts.every((part) => typeof part === "string")) {
972
+ if (parts[0] === "object" && parts.length === 3) {
973
+ return { kind: "object", ref: { objectTypeId: parts[1]!, primaryId: parts[2]! } }
974
+ }
975
+ if (parts[0] === "link" && parts.length === 6) {
976
+ return {
977
+ kind: "link",
978
+ ref: {
979
+ source: { objectTypeId: parts[1]!, primaryId: parts[2]! },
980
+ linkId: parts[3]!,
981
+ target: { objectTypeId: parts[4]!, primaryId: parts[5]! },
982
+ },
983
+ }
984
+ }
972
985
  }
973
- return key
986
+ throw new MaterializationConflictError(
987
+ "source-materialization",
988
+ `Stored source key ${key} is not a canonical entity key.`
989
+ )
990
+ }
991
+
992
+ /** What an assertion carries beyond its identity, or null when that is nothing. */
993
+ export function sourceAssertionPayload(
994
+ assertion: ProjectionSourceAssertion
995
+ ): Readonly<Record<string, unknown>> | null {
996
+ const { kind: _kind, ref: _ref, ...payload } = assertion
997
+ return Object.keys(payload).length === 0 ? null : payload
998
+ }
999
+
1000
+ /** Rebuilds an assertion from its typed identity columns and its payload. */
1001
+ export function sourceAssertionFromColumns(
1002
+ columns: {
1003
+ readonly entity_kind: "object" | "link"
1004
+ readonly object_type_id: string | null
1005
+ readonly primary_id: string | null
1006
+ readonly source_type_id: string | null
1007
+ readonly source_primary_id: string | null
1008
+ readonly link_id: string | null
1009
+ readonly target_type_id: string | null
1010
+ readonly target_primary_id: string | null
1011
+ },
1012
+ payload: unknown
1013
+ ): ProjectionSourceAssertion {
1014
+ const rest = (payload ?? {}) as Record<string, unknown>
1015
+ if (columns.entity_kind === "object") {
1016
+ return {
1017
+ kind: "object",
1018
+ ref: { objectTypeId: columns.object_type_id!, primaryId: columns.primary_id! },
1019
+ ...rest,
1020
+ } as ProjectionSourceAssertion
1021
+ }
1022
+ return {
1023
+ kind: "link",
1024
+ ref: {
1025
+ source: { objectTypeId: columns.source_type_id!, primaryId: columns.source_primary_id! },
1026
+ linkId: columns.link_id!,
1027
+ target: { objectTypeId: columns.target_type_id!, primaryId: columns.target_primary_id! },
1028
+ },
1029
+ ...rest,
1030
+ } as ProjectionSourceAssertion
974
1031
  }
975
1032
 
976
1033
  export function isExactStagingManifest(