@sixb/core 0.1.15 → 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 (131) hide show
  1. package/dist/actions/index.js +15 -15
  2. package/dist/actions/worker.js +1 -1
  3. package/dist/agents/index.js +26 -26
  4. package/dist/auth/index.js +5 -5
  5. package/dist/authorization/index.js +2 -2
  6. package/dist/bootstrap/index.js +30 -30
  7. package/dist/{chunk-qne45xqq.js → chunk-2xvgy3x5.js} +2 -2
  8. package/dist/{chunk-2tz5vnvz.js → chunk-3q7z9hd4.js} +19 -19
  9. package/dist/{chunk-4jph1t3v.js → chunk-40qb8wpe.js} +9 -9
  10. package/dist/{chunk-4jph1t3v.js.map → chunk-40qb8wpe.js.map} +3 -3
  11. package/dist/{chunk-xr7y35yj.js → chunk-667x4drs.js} +2 -2
  12. package/dist/{chunk-8fjmqjyx.js → chunk-69kt9q43.js} +1 -1
  13. package/dist/{chunk-fjw417jf.js → chunk-6z1q7j19.js} +22 -9
  14. package/dist/{chunk-fjw417jf.js.map → chunk-6z1q7j19.js.map} +4 -4
  15. package/dist/{chunk-8w27xf9e.js → chunk-7g2gjvah.js} +1 -1
  16. package/dist/{chunk-wem5vqjw.js → chunk-8x74221e.js} +7 -7
  17. package/dist/{chunk-wd34wnsy.js → chunk-a7ne02hk.js} +6 -6
  18. package/dist/{chunk-bxx3ms5t.js → chunk-b9y8hcm2.js} +2 -2
  19. package/dist/{chunk-mmac1mp6.js → chunk-chdg6eqq.js} +2 -2
  20. package/dist/{chunk-6q7c68yx.js → chunk-cq44v1a6.js} +2 -2
  21. package/dist/{chunk-adbve9zt.js → chunk-cxj8y8t0.js} +2 -2
  22. package/dist/{chunk-p0nbkys4.js → chunk-dp7yk20b.js} +1 -1
  23. package/dist/{chunk-1jvq82rp.js → chunk-dsv8kdgk.js} +3 -3
  24. package/dist/{chunk-dsfw1bdr.js → chunk-f72rbvsb.js} +2 -2
  25. package/dist/{chunk-ex8s8wsk.js → chunk-gkxsenvp.js} +17 -9
  26. package/dist/{chunk-ex8s8wsk.js.map → chunk-gkxsenvp.js.map} +4 -4
  27. package/dist/{chunk-vef6qa14.js → chunk-gmdvns8f.js} +2 -2
  28. package/dist/{chunk-3c90jvfj.js → chunk-h044jb97.js} +1072 -1075
  29. package/dist/chunk-h044jb97.js.map +15 -0
  30. package/dist/{chunk-z708gemf.js → chunk-h4138ww2.js} +4 -4
  31. package/dist/{chunk-yfppyaty.js → chunk-h866d223.js} +1 -1
  32. package/dist/{chunk-7jc21943.js → chunk-kttr5ftm.js} +4 -4
  33. package/dist/{chunk-py2dw8cw.js → chunk-kvysp909.js} +1 -1
  34. package/dist/{chunk-p1683c0v.js → chunk-kyjcwqz6.js} +5 -2
  35. package/dist/{chunk-p1683c0v.js.map → chunk-kyjcwqz6.js.map} +3 -3
  36. package/dist/{chunk-ffwvdgk1.js → chunk-nj0020ay.js} +1 -1
  37. package/dist/{chunk-y0zmae99.js → chunk-nkbev3tr.js} +3 -3
  38. package/dist/{chunk-r5sc1d2b.js → chunk-nvymebc1.js} +1 -1
  39. package/dist/{chunk-2fv8sajb.js → chunk-qnd7ehe5.js} +2 -2
  40. package/dist/{chunk-n5t4mq6z.js → chunk-sbcm1b92.js} +3 -3
  41. package/dist/{chunk-d8yes9yx.js → chunk-swxzncrv.js} +1 -1
  42. package/dist/{chunk-drz59ve0.js → chunk-tkdbge6v.js} +1 -1
  43. package/dist/{chunk-ky7zpbtt.js → chunk-tnvafr7g.js} +1 -1
  44. package/dist/{chunk-dqkd3kdj.js → chunk-vjqt7q3a.js} +20 -20
  45. package/dist/{chunk-a4g5yjm0.js → chunk-vsvrv7n8.js} +1 -1
  46. package/dist/{chunk-q3grgzp1.js → chunk-zb47r1c8.js} +2 -2
  47. package/dist/{chunk-3nx8vj5a.js → chunk-zvmr2hqk.js} +3 -2
  48. package/dist/chunk-zvmr2hqk.js.map +12 -0
  49. package/dist/execution/agent.js +24 -24
  50. package/dist/execution/primitive.js +24 -24
  51. package/dist/execution/request.js +25 -25
  52. package/dist/index.js +34 -34
  53. package/dist/materializer/index.js +12 -12
  54. package/dist/models/embedding-model.d.ts +4 -0
  55. package/dist/models/embedding-model.d.ts.map +1 -1
  56. package/dist/models/execution/index.js +12 -12
  57. package/dist/models/index.js +2 -2
  58. package/dist/objects/index.js +15 -15
  59. package/dist/objects/query/index.js +13 -13
  60. package/dist/objects/query/index.js.map +1 -1
  61. package/dist/objects/vectors/indexing-generate.d.ts.map +1 -1
  62. package/dist/objects/vectors/profile.d.ts.map +1 -1
  63. package/dist/objects/vectors/query.d.ts +1 -1
  64. package/dist/objects/vectors/query.d.ts.map +1 -1
  65. package/dist/objects/vectors/resolve-query.d.ts.map +1 -1
  66. package/dist/objects/vectors/types.d.ts +1 -1
  67. package/dist/objects/vectors/types.d.ts.map +1 -1
  68. package/dist/ontology/builders.d.ts +13 -4
  69. package/dist/ontology/builders.d.ts.map +1 -1
  70. package/dist/ontology/index.js +3 -3
  71. package/dist/ontology/internal.js +2 -2
  72. package/dist/ontology/vector-profiles.d.ts.map +1 -1
  73. package/dist/pipelines/index.js +13 -13
  74. package/dist/projections/internal.js +12 -12
  75. package/dist/runtime/internal.js +14 -14
  76. package/dist/sandboxes/index.js +5 -5
  77. package/dist/shares/internal.js +11 -11
  78. package/dist/storage/agents/provider.js +1 -1
  79. package/dist/storage/file-upload-sessions/provider.js +6 -6
  80. package/dist/storage/index.js +10 -10
  81. package/dist/storage/workflow-runs/provider.js +6 -6
  82. package/dist/syncs/index.js +14 -14
  83. package/dist/testing/index.js +37 -37
  84. package/dist/testing/index.js.map +1 -1
  85. package/dist/webhooks/internal.js +12 -12
  86. package/dist/workflows/index.js +27 -27
  87. package/package.json +1 -1
  88. package/src/models/embedding-model.ts +12 -0
  89. package/src/models/execution/embedding.ts +5 -1
  90. package/src/objects/query/validate.ts +1 -10
  91. package/src/objects/vectors/README.md +8 -0
  92. package/src/objects/vectors/handle.ts +1 -1
  93. package/src/objects/vectors/indexing-generate.ts +5 -1
  94. package/src/objects/vectors/profile.ts +2 -0
  95. package/src/objects/vectors/query.ts +18 -4
  96. package/src/objects/vectors/resolve-query.ts +9 -5
  97. package/src/objects/vectors/types.ts +3 -1
  98. package/src/ontology/builders.ts +21 -7
  99. package/src/ontology/vector-profiles.ts +1 -0
  100. package/dist/chunk-3c90jvfj.js.map +0 -15
  101. package/dist/chunk-3nx8vj5a.js.map +0 -12
  102. /package/dist/{chunk-qne45xqq.js.map → chunk-2xvgy3x5.js.map} +0 -0
  103. /package/dist/{chunk-2tz5vnvz.js.map → chunk-3q7z9hd4.js.map} +0 -0
  104. /package/dist/{chunk-xr7y35yj.js.map → chunk-667x4drs.js.map} +0 -0
  105. /package/dist/{chunk-8fjmqjyx.js.map → chunk-69kt9q43.js.map} +0 -0
  106. /package/dist/{chunk-8w27xf9e.js.map → chunk-7g2gjvah.js.map} +0 -0
  107. /package/dist/{chunk-wem5vqjw.js.map → chunk-8x74221e.js.map} +0 -0
  108. /package/dist/{chunk-wd34wnsy.js.map → chunk-a7ne02hk.js.map} +0 -0
  109. /package/dist/{chunk-bxx3ms5t.js.map → chunk-b9y8hcm2.js.map} +0 -0
  110. /package/dist/{chunk-mmac1mp6.js.map → chunk-chdg6eqq.js.map} +0 -0
  111. /package/dist/{chunk-6q7c68yx.js.map → chunk-cq44v1a6.js.map} +0 -0
  112. /package/dist/{chunk-adbve9zt.js.map → chunk-cxj8y8t0.js.map} +0 -0
  113. /package/dist/{chunk-p0nbkys4.js.map → chunk-dp7yk20b.js.map} +0 -0
  114. /package/dist/{chunk-1jvq82rp.js.map → chunk-dsv8kdgk.js.map} +0 -0
  115. /package/dist/{chunk-dsfw1bdr.js.map → chunk-f72rbvsb.js.map} +0 -0
  116. /package/dist/{chunk-vef6qa14.js.map → chunk-gmdvns8f.js.map} +0 -0
  117. /package/dist/{chunk-z708gemf.js.map → chunk-h4138ww2.js.map} +0 -0
  118. /package/dist/{chunk-yfppyaty.js.map → chunk-h866d223.js.map} +0 -0
  119. /package/dist/{chunk-7jc21943.js.map → chunk-kttr5ftm.js.map} +0 -0
  120. /package/dist/{chunk-py2dw8cw.js.map → chunk-kvysp909.js.map} +0 -0
  121. /package/dist/{chunk-ffwvdgk1.js.map → chunk-nj0020ay.js.map} +0 -0
  122. /package/dist/{chunk-y0zmae99.js.map → chunk-nkbev3tr.js.map} +0 -0
  123. /package/dist/{chunk-r5sc1d2b.js.map → chunk-nvymebc1.js.map} +0 -0
  124. /package/dist/{chunk-2fv8sajb.js.map → chunk-qnd7ehe5.js.map} +0 -0
  125. /package/dist/{chunk-n5t4mq6z.js.map → chunk-sbcm1b92.js.map} +0 -0
  126. /package/dist/{chunk-d8yes9yx.js.map → chunk-swxzncrv.js.map} +0 -0
  127. /package/dist/{chunk-drz59ve0.js.map → chunk-tkdbge6v.js.map} +0 -0
  128. /package/dist/{chunk-ky7zpbtt.js.map → chunk-tnvafr7g.js.map} +0 -0
  129. /package/dist/{chunk-dqkd3kdj.js.map → chunk-vjqt7q3a.js.map} +0 -0
  130. /package/dist/{chunk-a4g5yjm0.js.map → chunk-vsvrv7n8.js.map} +0 -0
  131. /package/dist/{chunk-q3grgzp1.js.map → chunk-zb47r1c8.js.map} +0 -0
@@ -1,35 +1,35 @@
1
1
  // @bun
2
2
  import"../chunk-6fsr7y93.js";
3
3
  import"../chunk-z3y5kg1x.js";
4
- import"../chunk-8fjmqjyx.js";
4
+ import"../chunk-69kt9q43.js";
5
5
  import"../chunk-v4jbb3rs.js";
6
- import"../chunk-d8yes9yx.js";
6
+ import"../chunk-swxzncrv.js";
7
7
  import {
8
8
  createConnectorCodedError,
9
9
  getConnectorExecutionSourceResolver
10
- } from "../chunk-r5sc1d2b.js";
10
+ } from "../chunk-nvymebc1.js";
11
11
  import"../chunk-y2aq6ag9.js";
12
12
  import"../chunk-fc5zfxy1.js";
13
- import"../chunk-qne45xqq.js";
14
- import"../chunk-drz59ve0.js";
13
+ import"../chunk-2xvgy3x5.js";
14
+ import"../chunk-tkdbge6v.js";
15
15
  import"../chunk-2jntasmh.js";
16
16
  import"../chunk-pqajwytd.js";
17
- import"../chunk-ky7zpbtt.js";
17
+ import"../chunk-tnvafr7g.js";
18
18
  import"../chunk-gfdh9kqa.js";
19
19
  import"../chunk-39tqv9hz.js";
20
20
  import"../chunk-69266efg.js";
21
21
  import"../chunk-xnx96gfy.js";
22
22
  import"../chunk-jgwb25gc.js";
23
23
  import"../chunk-h89wz928.js";
24
- import"../chunk-p0nbkys4.js";
24
+ import"../chunk-dp7yk20b.js";
25
25
  import {
26
26
  ExecutionStorageError2
27
27
  } from "../chunk-tw03bsmb.js";
28
- import"../chunk-3nx8vj5a.js";
28
+ import"../chunk-zvmr2hqk.js";
29
29
  import"../chunk-g4rbm4a6.js";
30
30
  import {
31
31
  canRetryWebhookRun2
32
- } from "../chunk-fjw417jf.js";
32
+ } from "../chunk-6z1q7j19.js";
33
33
  import"../chunk-7ytf06d3.js";
34
34
  import"../chunk-mr60an99.js";
35
35
  import"../chunk-mmagke4x.js";
@@ -39,20 +39,20 @@ import"../chunk-jmfet9r4.js";
39
39
  import {
40
40
  WebhookRunError2
41
41
  } from "../chunk-qf954wje.js";
42
- import"../chunk-xr7y35yj.js";
42
+ import"../chunk-667x4drs.js";
43
43
  import {
44
44
  isOAuthConnectorDefinition2,
45
45
  isStaticConnectorDefinition2
46
46
  } from "../chunk-9x8dybsb.js";
47
47
  import {
48
48
  createPrimitiveExecutionRecord
49
- } from "../chunk-8w27xf9e.js";
49
+ } from "../chunk-7g2gjvah.js";
50
50
  import"../chunk-br3k6qbf.js";
51
51
  import {
52
52
  isStorageSerializationFailure2
53
53
  } from "../chunk-zdkcdshk.js";
54
54
  import"../chunk-s3csryxe.js";
55
- import"../chunk-2fv8sajb.js";
55
+ import"../chunk-qnd7ehe5.js";
56
56
  // src/webhooks/connections.ts
57
57
  function createWebhookConnections(runtime, definition) {
58
58
  return {
@@ -8,13 +8,13 @@ import {
8
8
  defineWorkflow2,
9
9
  createWorkflowNodeFailure2,
10
10
  unwrapWorkflowNodeFailure2
11
- } from "../chunk-7jc21943.js";
11
+ } from "../chunk-kttr5ftm.js";
12
12
  import"../chunk-e1c18xjx.js";
13
13
  import"../chunk-fb3feg1e.js";
14
14
  import"../chunk-dfm066qg.js";
15
15
  import"../chunk-r2y23egw.js";
16
- import"../chunk-dsfw1bdr.js";
17
- import"../chunk-ffwvdgk1.js";
16
+ import"../chunk-f72rbvsb.js";
17
+ import"../chunk-nj0020ay.js";
18
18
  import"../chunk-9vx5e9g1.js";
19
19
  import {
20
20
  WorkflowDefinitionError2,
@@ -45,34 +45,34 @@ import {
45
45
  snapshotWorkflowActionInput2,
46
46
  WorkflowRunDispatcher2,
47
47
  requestWorkflowRun2
48
- } from "../chunk-2tz5vnvz.js";
49
- import"../chunk-y0zmae99.js";
50
- import"../chunk-r5sc1d2b.js";
51
- import"../chunk-adbve9zt.js";
52
- import"../chunk-mmac1mp6.js";
53
- import"../chunk-bxx3ms5t.js";
54
- import"../chunk-py2dw8cw.js";
48
+ } from "../chunk-3q7z9hd4.js";
49
+ import"../chunk-nkbev3tr.js";
50
+ import"../chunk-nvymebc1.js";
51
+ import"../chunk-cxj8y8t0.js";
52
+ import"../chunk-chdg6eqq.js";
53
+ import"../chunk-b9y8hcm2.js";
54
+ import"../chunk-kvysp909.js";
55
55
  import"../chunk-f85hpqnm.js";
56
56
  import"../chunk-fj1dvp37.js";
57
- import"../chunk-4jph1t3v.js";
57
+ import"../chunk-40qb8wpe.js";
58
58
  import"../chunk-85cd7e8c.js";
59
- import"../chunk-n5t4mq6z.js";
59
+ import"../chunk-sbcm1b92.js";
60
60
  import"../chunk-5a4a52tq.js";
61
61
  import"../chunk-91kcnbf0.js";
62
62
  import"../chunk-rb143ggb.js";
63
63
  import"../chunk-cd234ba4.js";
64
- import"../chunk-1jvq82rp.js";
65
- import"../chunk-wem5vqjw.js";
66
- import"../chunk-z708gemf.js";
67
- import"../chunk-3c90jvfj.js";
68
- import"../chunk-8w27xf9e.js";
69
- import"../chunk-fjw417jf.js";
64
+ import"../chunk-dsv8kdgk.js";
65
+ import"../chunk-8x74221e.js";
66
+ import"../chunk-h4138ww2.js";
67
+ import"../chunk-h044jb97.js";
68
+ import"../chunk-7g2gjvah.js";
69
+ import"../chunk-6z1q7j19.js";
70
70
  import"../chunk-br3k6qbf.js";
71
71
  import"../chunk-jmfet9r4.js";
72
72
  import"../chunk-qf954wje.js";
73
- import"../chunk-xr7y35yj.js";
73
+ import"../chunk-667x4drs.js";
74
74
  import"../chunk-tw03bsmb.js";
75
- import"../chunk-p0nbkys4.js";
75
+ import"../chunk-dp7yk20b.js";
76
76
  import"../chunk-zdkcdshk.js";
77
77
  import"../chunk-h89wz928.js";
78
78
  import"../chunk-g4rbm4a6.js";
@@ -86,9 +86,9 @@ import"../chunk-69266efg.js";
86
86
  import"../chunk-xnx96gfy.js";
87
87
  import"../chunk-s3csryxe.js";
88
88
  import"../chunk-jgwb25gc.js";
89
- import"../chunk-ky7zpbtt.js";
89
+ import"../chunk-tnvafr7g.js";
90
90
  import"../chunk-pqajwytd.js";
91
- import"../chunk-3nx8vj5a.js";
91
+ import"../chunk-zvmr2hqk.js";
92
92
  import"../chunk-7ytf06d3.js";
93
93
  import"../chunk-wr8qp979.js";
94
94
  import"../chunk-vjcd8d27.js";
@@ -97,12 +97,12 @@ import"../chunk-39tqv9hz.js";
97
97
  import"../chunk-gfdh9kqa.js";
98
98
  import"../chunk-dmn70ztd.js";
99
99
  import"../chunk-4gmng3vf.js";
100
- import"../chunk-qne45xqq.js";
101
- import"../chunk-2fv8sajb.js";
102
- import"../chunk-drz59ve0.js";
103
- import"../chunk-8fjmqjyx.js";
100
+ import"../chunk-2xvgy3x5.js";
101
+ import"../chunk-qnd7ehe5.js";
102
+ import"../chunk-tkdbge6v.js";
103
+ import"../chunk-69kt9q43.js";
104
104
  import"../chunk-v4jbb3rs.js";
105
- import"../chunk-d8yes9yx.js";
105
+ import"../chunk-swxzncrv.js";
106
106
  import"../chunk-6fsr7y93.js";
107
107
  import"../chunk-z3y5kg1x.js";
108
108
  import"../chunk-2jntasmh.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sixb/core",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "The ontology-first runtime for Sixb — objects, links, telemetry, actions, and provider contracts",
5
5
  "keywords": [
6
6
  "sixb",
@@ -7,12 +7,16 @@ import type { ModelCostEstimator, ModelReportedCost } from "./pricing"
7
7
  export interface EmbeddingModelDefinition extends ModelDefinition {
8
8
  readonly kind: "embedding"
9
9
  readonly dimensions: number
10
+ /** Asymmetric models use distinct document/query modes. Omission means symmetric. */
11
+ readonly inputMode?: "symmetric" | "asymmetric"
10
12
  /** Actual representation behind a routing alias. Omit only when modelId identifies it directly. */
11
13
  readonly representation?: { readonly name: string; readonly version?: string }
12
14
  }
13
15
 
14
16
  export interface EmbeddingModelRequest {
15
17
  readonly texts: readonly string[]
18
+ /** Retrieval role. Sixb sets this for indexing and search; symmetric models may ignore it. */
19
+ readonly purpose?: "document" | "query"
16
20
  /** Providers must honor cancellation and propagate this signal to their transport. */
17
21
  readonly signal?: AbortSignal
18
22
  }
@@ -73,6 +77,13 @@ export function assertEmbeddingModel(model: EmbeddingModel): void {
73
77
  export function assertEmbeddingModelRef(model: EmbeddingModelRef): void {
74
78
  const definition = model?.definition
75
79
  const representation = definition?.representation
80
+ if (
81
+ definition?.inputMode !== undefined &&
82
+ definition.inputMode !== "symmetric" &&
83
+ definition.inputMode !== "asymmetric"
84
+ ) {
85
+ throw new TypeError("[Sixb] Invalid embedding input mode.")
86
+ }
76
87
  if (
77
88
  representation !== undefined &&
78
89
  (!representation ||
@@ -106,6 +117,7 @@ export function sameEmbeddingModel(left: EmbeddingModelRef, right: EmbeddingMode
106
117
  left.providerId === right.providerId &&
107
118
  left.modelId === right.modelId &&
108
119
  left.definition.dimensions === right.definition.dimensions &&
120
+ (left.definition.inputMode ?? "symmetric") === (right.definition.inputMode ?? "symmetric") &&
109
121
  (left.definition.representation?.name ?? left.modelId) ===
110
122
  (right.definition.representation?.name ?? right.modelId) &&
111
123
  left.definition.representation?.version === right.definition.representation?.version
@@ -54,6 +54,10 @@ async function executeEmbedding(
54
54
  throw new TypeError("[SixbModels] Embedding inputs must be nonempty strings.")
55
55
  }
56
56
  const texts = [...input.texts]
57
+ const purpose = input.purpose
58
+ if (purpose !== undefined && purpose !== "document" && purpose !== "query") {
59
+ throw new TypeError("[SixbModels] Embedding purpose must be 'document' or 'query'.")
60
+ }
57
61
  const signal = session.signal(input.signal)
58
62
  const requestSignal = AbortSignal.any([signal, AbortSignal.timeout(30_000)])
59
63
  requestSignal.throwIfAborted()
@@ -89,7 +93,7 @@ async function executeEmbedding(
89
93
  let result: EmbeddingModelResult
90
94
  try {
91
95
  requestSignal.throwIfAborted()
92
- result = await model.embed({ texts, signal: requestSignal })
96
+ result = await model.embed({ texts, purpose, signal: requestSignal })
93
97
  } catch (error) {
94
98
  if (error instanceof EmbeddingModelResponseError) {
95
99
  await recordEmbedding(accounting, model, callId, error.metadata)
@@ -223,7 +223,7 @@ function validateVectorComposition(query: ObjectQuery, ctx: QueryValidationConte
223
223
  path: "$",
224
224
  code: "vector.composition",
225
225
  message:
226
- "Vector profiles support one top-k over one concrete type, with filters before ranking and optional limit/project after it.",
226
+ "Vector profiles support one top-k over one concrete type, with filters, traversals or sets before ranking and optional limit/project after it.",
227
227
  })
228
228
  }
229
229
 
@@ -923,15 +923,6 @@ function validateVectorProfileQuery(
923
923
  )
924
924
  return query
925
925
  }
926
- let input = query.input
927
- while (input.kind === "filter") input = input.input
928
- if (input.kind !== "start" || input.includeSubtypes)
929
- addIssue(
930
- ctx,
931
- path,
932
- "unsupported_vector_composition",
933
- "Vector profile input must be a type with optional filters."
934
- )
935
926
  const objectType = types[0]!
936
927
  const profile =
937
928
  query.profile === undefined ? undefined : objectType.search?.vectors?.[query.profile]
@@ -2,6 +2,14 @@
2
2
 
3
3
  A named profile identifies a derived representation, separate from object properties.
4
4
 
5
+ Indexing sends embedding purpose `document`; search sends `query`. The execution wrapper preserves
6
+ that role through model resolution, admission and accounting. Symmetric providers may ignore it.
7
+
8
+ Vector candidates may come from filters, traversals, explicit refs or set operations. Canonical
9
+ validation requires one concrete result type and admits every intermediate type, edge and source
10
+ property. Model lookup uses that resolved result type, not the query's initial type. SQL ranks the
11
+ eligible set after link and property authorization; it never filters a global top-k afterward.
12
+
5
13
  ```text
6
14
  Effective object change → invalidate stale vector + persist latest intent (one transaction)
7
15
  ProjectionWorker → durable queue → project AI admission → provider → save result → fenced commit
@@ -65,7 +65,7 @@ export function createObjectVectorHandle(
65
65
  }
66
66
 
67
67
  // Network work never holds a storage transaction or retries an obsolete computation.
68
- const result = await model.embed({ texts: [input.text] })
68
+ const result = await model.embed({ texts: [input.text], purpose: "document" })
69
69
  if (!Array.isArray(result?.vectors) || result.vectors.length !== 1) {
70
70
  throw new MaterializationValidationError(
71
71
  "Embedding model must return exactly one vector for one input text."
@@ -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({