@fortemi/core 2026.9.4 → 2026.9.6
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.
- package/dist/index.d.ts +1617 -1486
- package/dist/index.js +2310 -438
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/schemas/dataset-execution-capabilities/validation/1.0.1/manifest.json +29 -0
- package/schemas/dataset-execution-capabilities/validation/1.0.1/negotiation-vectors.json +127 -0
- package/schemas/dataset-execution-capabilities/validation/1.0.1/schema.json +469 -0
- package/schemas/dataset-execution-capabilities/validation/1.0.1/wire-vectors.json +681 -0
- package/schemas/metadata-search/candidate/1.0.0/README.md +36 -0
- package/schemas/metadata-search/candidate/1.0.0/contract.receipt.json +38 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-locator.schema.json +50 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-resolution-vectors.json +355 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-resolution.schema.json +25 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-set-vectors.json +6095 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-set.schema.json +21 -0
- package/schemas/metadata-search/candidate/1.0.0/evidence-vectors.json +1603 -0
- package/schemas/metadata-search/candidate/1.0.0/predicate-vectors.json +919 -0
- package/schemas/metadata-search/candidate/1.0.0/predicates.schema.json +287 -0
- package/schemas/metadata-search/candidate/1.0.0/resolution.receipt.json +44 -0
- package/schemas/metadata-search/candidate/1.0.0/rest.receipt.json +51 -0
- package/schemas/metadata-search/candidate/1.0.0/search-rest-vectors.json +28 -0
- package/schemas/metadata-search/candidate/1.0.0/search-rest.schema.json +318 -0
- package/schemas/metadata-search/candidate/1.0.0/source.receipt.json +46 -0
- package/schemas/metadata-search/candidate/1.0.0/sql-scope-vectors.json +894 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { v7, v5 } from 'uuid';
|
|
2
2
|
import { sha256 } from '@noble/hashes/sha256';
|
|
3
3
|
import { blake3 } from '@noble/hashes/blake3';
|
|
4
|
-
import { bytesToHex } from '@noble/hashes/utils';
|
|
5
|
-
import
|
|
4
|
+
import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
|
|
5
|
+
import Ajv20206 from 'ajv/dist/2020.js';
|
|
6
6
|
import { gzipSync, gunzipSync } from 'fflate';
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
|
|
@@ -24,9 +24,9 @@ var __export = (target, all) => {
|
|
|
24
24
|
};
|
|
25
25
|
var __copyProps = (to, from, except, desc) => {
|
|
26
26
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
27
|
-
for (let
|
|
28
|
-
if (!__hasOwnProp.call(to,
|
|
29
|
-
__defProp(to,
|
|
27
|
+
for (let key3 of __getOwnPropNames(from))
|
|
28
|
+
if (!__hasOwnProp.call(to, key3) && key3 !== except)
|
|
29
|
+
__defProp(to, key3, { get: () => from[key3], enumerable: !(desc = __getOwnPropDesc(from, key3)) || desc.enumerable });
|
|
30
30
|
}
|
|
31
31
|
return to;
|
|
32
32
|
};
|
|
@@ -1991,19 +1991,19 @@ var require_point = __commonJS({
|
|
|
1991
1991
|
var Types = require_types();
|
|
1992
1992
|
var BinaryWriter = require_binarywriter();
|
|
1993
1993
|
var ZigZag = require_zigzag();
|
|
1994
|
-
function Point2(x, y,
|
|
1994
|
+
function Point2(x, y, z13, m, srid) {
|
|
1995
1995
|
Geometry2.call(this);
|
|
1996
1996
|
this.x = x;
|
|
1997
1997
|
this.y = y;
|
|
1998
|
-
this.z =
|
|
1998
|
+
this.z = z13;
|
|
1999
1999
|
this.m = m;
|
|
2000
2000
|
this.srid = srid;
|
|
2001
2001
|
this.hasZ = typeof this.z !== "undefined";
|
|
2002
2002
|
this.hasM = typeof this.m !== "undefined";
|
|
2003
2003
|
}
|
|
2004
2004
|
util.inherits(Point2, Geometry2);
|
|
2005
|
-
Point2.Z = function(x, y,
|
|
2006
|
-
var point = new Point2(x, y,
|
|
2005
|
+
Point2.Z = function(x, y, z13, srid) {
|
|
2006
|
+
var point = new Point2(x, y, z13, void 0, srid);
|
|
2007
2007
|
point.hasZ = true;
|
|
2008
2008
|
return point;
|
|
2009
2009
|
};
|
|
@@ -2012,8 +2012,8 @@ var require_point = __commonJS({
|
|
|
2012
2012
|
point.hasM = true;
|
|
2013
2013
|
return point;
|
|
2014
2014
|
};
|
|
2015
|
-
Point2.ZM = function(x, y,
|
|
2016
|
-
var point = new Point2(x, y,
|
|
2015
|
+
Point2.ZM = function(x, y, z13, m, srid) {
|
|
2016
|
+
var point = new Point2(x, y, z13, m, srid);
|
|
2017
2017
|
point.hasZ = true;
|
|
2018
2018
|
point.hasM = true;
|
|
2019
2019
|
return point;
|
|
@@ -2119,17 +2119,17 @@ var require_point = __commonJS({
|
|
|
2119
2119
|
Point2.prototype._writeTwkbPoint = function(twkb, precision, previousPoint) {
|
|
2120
2120
|
var x = this.x * precision.xyFactor;
|
|
2121
2121
|
var y = this.y * precision.xyFactor;
|
|
2122
|
-
var
|
|
2122
|
+
var z13 = this.z * precision.zFactor;
|
|
2123
2123
|
var m = this.m * precision.mFactor;
|
|
2124
2124
|
twkb.writeVarInt(ZigZag.encode(x - previousPoint.x));
|
|
2125
2125
|
twkb.writeVarInt(ZigZag.encode(y - previousPoint.y));
|
|
2126
2126
|
if (this.hasZ)
|
|
2127
|
-
twkb.writeVarInt(ZigZag.encode(
|
|
2127
|
+
twkb.writeVarInt(ZigZag.encode(z13 - previousPoint.z));
|
|
2128
2128
|
if (this.hasM)
|
|
2129
2129
|
twkb.writeVarInt(ZigZag.encode(m - previousPoint.m));
|
|
2130
2130
|
previousPoint.x = x;
|
|
2131
2131
|
previousPoint.y = y;
|
|
2132
|
-
previousPoint.z =
|
|
2132
|
+
previousPoint.z = z13;
|
|
2133
2133
|
previousPoint.m = m;
|
|
2134
2134
|
};
|
|
2135
2135
|
Point2.prototype._getWkbSize = function() {
|
|
@@ -3615,14 +3615,14 @@ var MemoryDatasetIngestStore = class {
|
|
|
3615
3615
|
receipts: /* @__PURE__ */ new Map()
|
|
3616
3616
|
};
|
|
3617
3617
|
const draft = {
|
|
3618
|
-
records: new Map([...existing.records].map(([
|
|
3619
|
-
receipts: new Map([...existing.receipts].map(([
|
|
3618
|
+
records: new Map([...existing.records].map(([key3, value]) => [key3, clone(value)])),
|
|
3619
|
+
receipts: new Map([...existing.receipts].map(([key3, value]) => [key3, clone(value)])),
|
|
3620
3620
|
...existing.checkpoint ? { checkpoint: clone(existing.checkpoint) } : {}
|
|
3621
3621
|
};
|
|
3622
3622
|
const transaction = {
|
|
3623
3623
|
getRecord: (id) => draft.records.get(id),
|
|
3624
3624
|
setRecord: (record) => draft.records.set(record.logicalId, clone(record)),
|
|
3625
|
-
getReceipt: (
|
|
3625
|
+
getReceipt: (key3) => draft.receipts.get(key3),
|
|
3626
3626
|
setReceipt: (receipt) => draft.receipts.set(receipt.idempotencyKey, clone(receipt)),
|
|
3627
3627
|
getCheckpoint: () => draft.checkpoint,
|
|
3628
3628
|
setCheckpoint: (checkpoint) => {
|
|
@@ -3650,7 +3650,7 @@ var MemoryDatasetIngestStore = class {
|
|
|
3650
3650
|
function canonicalJson(value) {
|
|
3651
3651
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
3652
3652
|
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
3653
|
-
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([
|
|
3653
|
+
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson(item)}`).join(",")}}`;
|
|
3654
3654
|
}
|
|
3655
3655
|
function digest(value) {
|
|
3656
3656
|
return computeHash(new TextEncoder().encode(canonicalJson(value)));
|
|
@@ -3819,11 +3819,11 @@ var DatasetIngestExecutor = class {
|
|
|
3819
3819
|
return this.store.getReceipt(datasetDestinationScopeKey(plan.destination), deriveDatasetIngestIdempotencyKey(plan, batch));
|
|
3820
3820
|
}
|
|
3821
3821
|
status(scope, expectedSourceRevision) {
|
|
3822
|
-
const
|
|
3823
|
-
const lastSuccessful = this.successes.get(
|
|
3822
|
+
const key3 = datasetDestinationScopeKey(scope);
|
|
3823
|
+
const lastSuccessful = this.successes.get(key3);
|
|
3824
3824
|
return {
|
|
3825
3825
|
scope: clone(scope),
|
|
3826
|
-
...this.attempts.get(
|
|
3826
|
+
...this.attempts.get(key3) ? { lastAttempt: clone(this.attempts.get(key3)) } : {},
|
|
3827
3827
|
...lastSuccessful ? { lastSuccessful: clone(lastSuccessful) } : {},
|
|
3828
3828
|
freshness: lastSuccessful ? expectedSourceRevision && expectedSourceRevision !== lastSuccessful.sourceRevision ? "stale" : "current" : "never"
|
|
3829
3829
|
};
|
|
@@ -3877,7 +3877,7 @@ function canonicalJson2(value) {
|
|
|
3877
3877
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
3878
3878
|
if (Array.isArray(value)) return `[${value.map(canonicalJson2).join(",")}]`;
|
|
3879
3879
|
const entries = Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
3880
|
-
return `{${entries.map(([
|
|
3880
|
+
return `{${entries.map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson2(item)}`).join(",")}}`;
|
|
3881
3881
|
}
|
|
3882
3882
|
function computeLineageDigest(value) {
|
|
3883
3883
|
return computeHash(new TextEncoder().encode(canonicalJson2(value)));
|
|
@@ -3957,9 +3957,9 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
3957
3957
|
if (item.payload !== void 0 && computeLineageDigest(item.payload) !== item.digest) {
|
|
3958
3958
|
throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence ${item.id} payload does not match ${item.digest}`);
|
|
3959
3959
|
}
|
|
3960
|
-
const
|
|
3961
|
-
this.ensureUnique(this.evidence,
|
|
3962
|
-
return this.append(this.evidence,
|
|
3960
|
+
const key3 = `${item.id}@${item.revision}`;
|
|
3961
|
+
this.ensureUnique(this.evidence, key3, "evidence revision");
|
|
3962
|
+
return this.append(this.evidence, key3, item);
|
|
3963
3963
|
}
|
|
3964
3964
|
appendAssertion(assertion) {
|
|
3965
3965
|
requireIdentity(assertion.id, "assertion.id");
|
|
@@ -3995,13 +3995,13 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
3995
3995
|
if (item.digest !== reference.digest) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence reference digest differs for ${reference.evidenceId}`);
|
|
3996
3996
|
if (reference.locator && reference.locator !== item.locator) throw new LineageValidationError("EVIDENCE_DIGEST_MISMATCH", `Evidence locator differs for ${reference.evidenceId}`);
|
|
3997
3997
|
}
|
|
3998
|
-
const
|
|
3999
|
-
if (this.assertions.has(
|
|
3998
|
+
const key3 = `${assertion.id}@${assertion.revision}`;
|
|
3999
|
+
if (this.assertions.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate assertion revision ${key3}`);
|
|
4000
4000
|
const prior = [...this.assertions.values()].some((entry) => entry.value.id === assertion.id);
|
|
4001
4001
|
if (prior && !this.hasReplacementPermission(assertion.id, assertion.revision)) {
|
|
4002
4002
|
throw new LineageValidationError("CORRECTION_INVALID", `Assertion ${assertion.id} can only receive revision ${assertion.revision} after an explicit correction`);
|
|
4003
4003
|
}
|
|
4004
|
-
return this.append(this.assertions,
|
|
4004
|
+
return this.append(this.assertions, key3, assertion);
|
|
4005
4005
|
}
|
|
4006
4006
|
appendCorrection(correction) {
|
|
4007
4007
|
requireIdentity(correction.id, "correction.id");
|
|
@@ -4116,10 +4116,10 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
4116
4116
|
const correction = pending.splice(index, 1)[0];
|
|
4117
4117
|
ledger.appendCorrection(correction);
|
|
4118
4118
|
if (correction.replacementAssertionId && correction.replacementRevision) {
|
|
4119
|
-
const
|
|
4120
|
-
if (!ledger.assertions.has(
|
|
4121
|
-
const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` ===
|
|
4122
|
-
if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${
|
|
4119
|
+
const key3 = `${correction.replacementAssertionId}@${correction.replacementRevision}`;
|
|
4120
|
+
if (!ledger.assertions.has(key3)) {
|
|
4121
|
+
const replacement = archive.assertions.find((item) => `${item.id}@${item.revision}` === key3);
|
|
4122
|
+
if (!replacement) throw new LineageValidationError("IDENTITY_DANGLING", `Missing replacement assertion ${key3}`);
|
|
4123
4123
|
ledger.appendAssertion(replacement);
|
|
4124
4124
|
}
|
|
4125
4125
|
}
|
|
@@ -4167,19 +4167,19 @@ var DatasetLineageLedger = class _DatasetLineageLedger {
|
|
|
4167
4167
|
}
|
|
4168
4168
|
});
|
|
4169
4169
|
}
|
|
4170
|
-
append(map,
|
|
4170
|
+
append(map, key3, value) {
|
|
4171
4171
|
this.sequence += 1;
|
|
4172
|
-
map.set(
|
|
4172
|
+
map.set(key3, { sequence: this.sequence, value: clone2(value) });
|
|
4173
4173
|
return this.sequence;
|
|
4174
4174
|
}
|
|
4175
|
-
ensureUnique(map,
|
|
4176
|
-
if (map.has(
|
|
4175
|
+
ensureUnique(map, key3, label) {
|
|
4176
|
+
if (map.has(key3)) throw new LineageValidationError("IDENTITY_DUPLICATE", `Duplicate ${label} identity ${key3}`);
|
|
4177
4177
|
}
|
|
4178
4178
|
visibleAt(map, snapshot) {
|
|
4179
|
-
return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([
|
|
4179
|
+
return new Map([...map].filter(([, entry]) => entry.sequence <= snapshot).map(([key3, entry]) => [key3, clone2(entry.value)]));
|
|
4180
4180
|
}
|
|
4181
|
-
sorted(map,
|
|
4182
|
-
return [...map.values()].sort((left, right) =>
|
|
4181
|
+
sorted(map, key3 = (item) => item.id) {
|
|
4182
|
+
return [...map.values()].sort((left, right) => key3(left).localeCompare(key3(right))).map(clone2);
|
|
4183
4183
|
}
|
|
4184
4184
|
hasReplacementPermission(assertionId, revision) {
|
|
4185
4185
|
return [...this.corrections.values()].some((entry) => entry.value.action === "correct" && entry.value.replacementAssertionId === assertionId && entry.value.replacementRevision === revision);
|
|
@@ -4215,6 +4215,479 @@ function compareAssertions(left, right) {
|
|
|
4215
4215
|
|
|
4216
4216
|
// src/dataset-execution-capabilities.ts
|
|
4217
4217
|
init_geometry_buffer();
|
|
4218
|
+
|
|
4219
|
+
// schemas/dataset-execution-capabilities/validation/1.0.1/schema.json
|
|
4220
|
+
var schema_default = {
|
|
4221
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4222
|
+
$id: "https://fortemi.dev/schemas/dataset-execution-capabilities/validation/1.0.1.schema.json",
|
|
4223
|
+
title: "Dataset Capability Validation Revision 1.0.1 (v1 wire)",
|
|
4224
|
+
oneOf: [
|
|
4225
|
+
{
|
|
4226
|
+
$ref: "#/$defs/descriptor"
|
|
4227
|
+
},
|
|
4228
|
+
{
|
|
4229
|
+
$ref: "#/$defs/request"
|
|
4230
|
+
},
|
|
4231
|
+
{
|
|
4232
|
+
$ref: "#/$defs/result"
|
|
4233
|
+
}
|
|
4234
|
+
],
|
|
4235
|
+
$defs: {
|
|
4236
|
+
capabilityId: {
|
|
4237
|
+
enum: [
|
|
4238
|
+
"ingest.full",
|
|
4239
|
+
"ingest.snapshot",
|
|
4240
|
+
"ingest.incremental",
|
|
4241
|
+
"ingest.stream",
|
|
4242
|
+
"schema.inspect",
|
|
4243
|
+
"identity.stable-revision",
|
|
4244
|
+
"identity.record",
|
|
4245
|
+
"mutation.upsert",
|
|
4246
|
+
"mutation.tombstone",
|
|
4247
|
+
"mutation.reconcile",
|
|
4248
|
+
"checkpoint.read",
|
|
4249
|
+
"checkpoint.write",
|
|
4250
|
+
"execution.cancel",
|
|
4251
|
+
"rejection.record",
|
|
4252
|
+
"index.lexical",
|
|
4253
|
+
"index.chunk",
|
|
4254
|
+
"index.vector",
|
|
4255
|
+
"index.hybrid",
|
|
4256
|
+
"index.rerank",
|
|
4257
|
+
"index.graph",
|
|
4258
|
+
"index.community",
|
|
4259
|
+
"lineage.dataset",
|
|
4260
|
+
"lineage.record",
|
|
4261
|
+
"lineage.field",
|
|
4262
|
+
"lineage.relationship-evidence",
|
|
4263
|
+
"transaction.atomic-batch",
|
|
4264
|
+
"privacy.pre-materialization-filter",
|
|
4265
|
+
"pagination.cursor",
|
|
4266
|
+
"ordering.deterministic"
|
|
4267
|
+
]
|
|
4268
|
+
},
|
|
4269
|
+
semver: {
|
|
4270
|
+
type: "string",
|
|
4271
|
+
maxLength: 256,
|
|
4272
|
+
pattern: "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$(?![\\s\\S])"
|
|
4273
|
+
},
|
|
4274
|
+
digest: {
|
|
4275
|
+
type: "string",
|
|
4276
|
+
pattern: "^[a-z0-9]+:[a-f0-9]+$"
|
|
4277
|
+
},
|
|
4278
|
+
limits: {
|
|
4279
|
+
type: "object",
|
|
4280
|
+
additionalProperties: false,
|
|
4281
|
+
properties: {
|
|
4282
|
+
maxInputBytes: {
|
|
4283
|
+
type: "integer",
|
|
4284
|
+
minimum: 0,
|
|
4285
|
+
maximum: 9007199254740991
|
|
4286
|
+
},
|
|
4287
|
+
maxRecordBytes: {
|
|
4288
|
+
type: "integer",
|
|
4289
|
+
minimum: 0,
|
|
4290
|
+
maximum: 9007199254740991
|
|
4291
|
+
},
|
|
4292
|
+
maxBatchRecords: {
|
|
4293
|
+
type: "integer",
|
|
4294
|
+
minimum: 0,
|
|
4295
|
+
maximum: 9007199254740991
|
|
4296
|
+
},
|
|
4297
|
+
maxConcurrency: {
|
|
4298
|
+
type: "integer",
|
|
4299
|
+
minimum: 0,
|
|
4300
|
+
maximum: 9007199254740991
|
|
4301
|
+
},
|
|
4302
|
+
maxPageSize: {
|
|
4303
|
+
type: "integer",
|
|
4304
|
+
minimum: 0,
|
|
4305
|
+
maximum: 9007199254740991
|
|
4306
|
+
},
|
|
4307
|
+
maxTraversalDepth: {
|
|
4308
|
+
type: "integer",
|
|
4309
|
+
minimum: 0,
|
|
4310
|
+
maximum: 9007199254740991
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
},
|
|
4314
|
+
evidence: {
|
|
4315
|
+
type: "object",
|
|
4316
|
+
additionalProperties: false,
|
|
4317
|
+
required: [
|
|
4318
|
+
"id",
|
|
4319
|
+
"kind",
|
|
4320
|
+
"uri"
|
|
4321
|
+
],
|
|
4322
|
+
properties: {
|
|
4323
|
+
id: {
|
|
4324
|
+
type: "string",
|
|
4325
|
+
minLength: 1
|
|
4326
|
+
},
|
|
4327
|
+
kind: {
|
|
4328
|
+
enum: [
|
|
4329
|
+
"fixture",
|
|
4330
|
+
"conformance-report",
|
|
4331
|
+
"live-qualification"
|
|
4332
|
+
]
|
|
4333
|
+
},
|
|
4334
|
+
uri: {
|
|
4335
|
+
type: "string",
|
|
4336
|
+
minLength: 1
|
|
4337
|
+
},
|
|
4338
|
+
digest: {
|
|
4339
|
+
$ref: "#/$defs/digest"
|
|
4340
|
+
}
|
|
4341
|
+
}
|
|
4342
|
+
},
|
|
4343
|
+
capability: {
|
|
4344
|
+
type: "object",
|
|
4345
|
+
additionalProperties: false,
|
|
4346
|
+
required: [
|
|
4347
|
+
"id",
|
|
4348
|
+
"version",
|
|
4349
|
+
"status",
|
|
4350
|
+
"evidence"
|
|
4351
|
+
],
|
|
4352
|
+
properties: {
|
|
4353
|
+
id: {
|
|
4354
|
+
$ref: "#/$defs/capabilityId"
|
|
4355
|
+
},
|
|
4356
|
+
version: {
|
|
4357
|
+
$ref: "#/$defs/semver"
|
|
4358
|
+
},
|
|
4359
|
+
status: {
|
|
4360
|
+
enum: [
|
|
4361
|
+
"supported",
|
|
4362
|
+
"experimental",
|
|
4363
|
+
"unsupported"
|
|
4364
|
+
]
|
|
4365
|
+
},
|
|
4366
|
+
limits: {
|
|
4367
|
+
$ref: "#/$defs/limits"
|
|
4368
|
+
},
|
|
4369
|
+
evidence: {
|
|
4370
|
+
type: "array",
|
|
4371
|
+
items: {
|
|
4372
|
+
type: "string",
|
|
4373
|
+
minLength: 1
|
|
4374
|
+
},
|
|
4375
|
+
uniqueItems: true
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
},
|
|
4379
|
+
runtime: {
|
|
4380
|
+
type: "object",
|
|
4381
|
+
additionalProperties: false,
|
|
4382
|
+
required: [
|
|
4383
|
+
"id",
|
|
4384
|
+
"version",
|
|
4385
|
+
"plane",
|
|
4386
|
+
"dataClass",
|
|
4387
|
+
"maturity"
|
|
4388
|
+
],
|
|
4389
|
+
properties: {
|
|
4390
|
+
id: {
|
|
4391
|
+
type: "string",
|
|
4392
|
+
minLength: 1
|
|
4393
|
+
},
|
|
4394
|
+
version: {
|
|
4395
|
+
$ref: "#/$defs/semver"
|
|
4396
|
+
},
|
|
4397
|
+
plane: {
|
|
4398
|
+
enum: [
|
|
4399
|
+
"browser-local-archive",
|
|
4400
|
+
"static-cache",
|
|
4401
|
+
"portable-shard",
|
|
4402
|
+
"server-process",
|
|
4403
|
+
"live-remote-persistence"
|
|
4404
|
+
]
|
|
4405
|
+
},
|
|
4406
|
+
dataClass: {
|
|
4407
|
+
enum: [
|
|
4408
|
+
"canonical",
|
|
4409
|
+
"regenerable-index",
|
|
4410
|
+
"static-cache",
|
|
4411
|
+
"portable-projection",
|
|
4412
|
+
"remote-persistence"
|
|
4413
|
+
]
|
|
4414
|
+
},
|
|
4415
|
+
maturity: {
|
|
4416
|
+
enum: [
|
|
4417
|
+
"experimental",
|
|
4418
|
+
"alpha",
|
|
4419
|
+
"beta",
|
|
4420
|
+
"stable"
|
|
4421
|
+
]
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
},
|
|
4425
|
+
guarantees: {
|
|
4426
|
+
type: "object",
|
|
4427
|
+
additionalProperties: false,
|
|
4428
|
+
required: [
|
|
4429
|
+
"transaction",
|
|
4430
|
+
"isolation",
|
|
4431
|
+
"durability",
|
|
4432
|
+
"availability",
|
|
4433
|
+
"ordering"
|
|
4434
|
+
],
|
|
4435
|
+
properties: {
|
|
4436
|
+
transaction: {
|
|
4437
|
+
enum: [
|
|
4438
|
+
"none",
|
|
4439
|
+
"single-record",
|
|
4440
|
+
"atomic-batch"
|
|
4441
|
+
]
|
|
4442
|
+
},
|
|
4443
|
+
isolation: {
|
|
4444
|
+
enum: [
|
|
4445
|
+
"none",
|
|
4446
|
+
"snapshot",
|
|
4447
|
+
"serializable"
|
|
4448
|
+
]
|
|
4449
|
+
},
|
|
4450
|
+
durability: {
|
|
4451
|
+
enum: [
|
|
4452
|
+
"process",
|
|
4453
|
+
"memory",
|
|
4454
|
+
"filesystem",
|
|
4455
|
+
"wal",
|
|
4456
|
+
"replicated"
|
|
4457
|
+
]
|
|
4458
|
+
},
|
|
4459
|
+
availability: {
|
|
4460
|
+
enum: [
|
|
4461
|
+
"local-process",
|
|
4462
|
+
"single-host",
|
|
4463
|
+
"remote-service"
|
|
4464
|
+
]
|
|
4465
|
+
},
|
|
4466
|
+
ordering: {
|
|
4467
|
+
enum: [
|
|
4468
|
+
"unspecified",
|
|
4469
|
+
"stable-identity",
|
|
4470
|
+
"backend-cursor"
|
|
4471
|
+
]
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
},
|
|
4475
|
+
descriptor: {
|
|
4476
|
+
type: "object",
|
|
4477
|
+
additionalProperties: false,
|
|
4478
|
+
required: [
|
|
4479
|
+
"contract",
|
|
4480
|
+
"schemaVersion",
|
|
4481
|
+
"runtime",
|
|
4482
|
+
"guarantees",
|
|
4483
|
+
"capabilities",
|
|
4484
|
+
"evidence"
|
|
4485
|
+
],
|
|
4486
|
+
properties: {
|
|
4487
|
+
contract: {
|
|
4488
|
+
const: "fortemi.dataset-execution-capabilities/v1"
|
|
4489
|
+
},
|
|
4490
|
+
schemaVersion: {
|
|
4491
|
+
$ref: "#/$defs/semver"
|
|
4492
|
+
},
|
|
4493
|
+
runtime: {
|
|
4494
|
+
$ref: "#/$defs/runtime"
|
|
4495
|
+
},
|
|
4496
|
+
guarantees: {
|
|
4497
|
+
$ref: "#/$defs/guarantees"
|
|
4498
|
+
},
|
|
4499
|
+
capabilities: {
|
|
4500
|
+
type: "array",
|
|
4501
|
+
items: {
|
|
4502
|
+
$ref: "#/$defs/capability"
|
|
4503
|
+
}
|
|
4504
|
+
},
|
|
4505
|
+
evidence: {
|
|
4506
|
+
type: "array",
|
|
4507
|
+
items: {
|
|
4508
|
+
$ref: "#/$defs/evidence"
|
|
4509
|
+
}
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
},
|
|
4513
|
+
requirement: {
|
|
4514
|
+
type: "object",
|
|
4515
|
+
additionalProperties: false,
|
|
4516
|
+
required: [
|
|
4517
|
+
"id"
|
|
4518
|
+
],
|
|
4519
|
+
properties: {
|
|
4520
|
+
id: {
|
|
4521
|
+
$ref: "#/$defs/capabilityId"
|
|
4522
|
+
},
|
|
4523
|
+
minimumVersion: {
|
|
4524
|
+
$ref: "#/$defs/semver"
|
|
4525
|
+
},
|
|
4526
|
+
minimumLimits: {
|
|
4527
|
+
$ref: "#/$defs/limits"
|
|
4528
|
+
}
|
|
4529
|
+
}
|
|
4530
|
+
},
|
|
4531
|
+
optionalRequirement: {
|
|
4532
|
+
type: "object",
|
|
4533
|
+
additionalProperties: false,
|
|
4534
|
+
required: [
|
|
4535
|
+
"id"
|
|
4536
|
+
],
|
|
4537
|
+
properties: {
|
|
4538
|
+
id: {
|
|
4539
|
+
$ref: "#/$defs/capabilityId"
|
|
4540
|
+
},
|
|
4541
|
+
minimumVersion: {
|
|
4542
|
+
$ref: "#/$defs/semver"
|
|
4543
|
+
},
|
|
4544
|
+
minimumLimits: {
|
|
4545
|
+
$ref: "#/$defs/limits"
|
|
4546
|
+
},
|
|
4547
|
+
fallback: {
|
|
4548
|
+
type: "array",
|
|
4549
|
+
items: {
|
|
4550
|
+
$ref: "#/$defs/capabilityId"
|
|
4551
|
+
},
|
|
4552
|
+
uniqueItems: true
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
},
|
|
4556
|
+
request: {
|
|
4557
|
+
type: "object",
|
|
4558
|
+
additionalProperties: false,
|
|
4559
|
+
required: [
|
|
4560
|
+
"contract",
|
|
4561
|
+
"required"
|
|
4562
|
+
],
|
|
4563
|
+
properties: {
|
|
4564
|
+
contract: {
|
|
4565
|
+
const: "fortemi.dataset-execution-capabilities/v1"
|
|
4566
|
+
},
|
|
4567
|
+
required: {
|
|
4568
|
+
type: "array",
|
|
4569
|
+
items: {
|
|
4570
|
+
$ref: "#/$defs/requirement"
|
|
4571
|
+
}
|
|
4572
|
+
},
|
|
4573
|
+
optional: {
|
|
4574
|
+
type: "array",
|
|
4575
|
+
items: {
|
|
4576
|
+
$ref: "#/$defs/optionalRequirement"
|
|
4577
|
+
}
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
},
|
|
4581
|
+
diagnostic: {
|
|
4582
|
+
type: "object",
|
|
4583
|
+
additionalProperties: false,
|
|
4584
|
+
required: [
|
|
4585
|
+
"code",
|
|
4586
|
+
"message"
|
|
4587
|
+
],
|
|
4588
|
+
properties: {
|
|
4589
|
+
code: {
|
|
4590
|
+
enum: [
|
|
4591
|
+
"CONTRACT_MAJOR_UNSUPPORTED",
|
|
4592
|
+
"SCHEMA_VERSION_UNSUPPORTED",
|
|
4593
|
+
"DESCRIPTOR_INVALID",
|
|
4594
|
+
"CAPABILITY_DUPLICATE",
|
|
4595
|
+
"CAPABILITY_INCONSISTENT",
|
|
4596
|
+
"REQUIRED_CAPABILITY_MISSING",
|
|
4597
|
+
"CAPABILITY_VERSION_INSUFFICIENT",
|
|
4598
|
+
"CAPABILITY_LIMIT_INSUFFICIENT"
|
|
4599
|
+
]
|
|
4600
|
+
},
|
|
4601
|
+
capability: {
|
|
4602
|
+
$ref: "#/$defs/capabilityId"
|
|
4603
|
+
},
|
|
4604
|
+
path: {
|
|
4605
|
+
type: "string"
|
|
4606
|
+
},
|
|
4607
|
+
message: {
|
|
4608
|
+
type: "string",
|
|
4609
|
+
minLength: 1
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
},
|
|
4613
|
+
degradation: {
|
|
4614
|
+
type: "object",
|
|
4615
|
+
additionalProperties: false,
|
|
4616
|
+
required: [
|
|
4617
|
+
"requested",
|
|
4618
|
+
"reason",
|
|
4619
|
+
"changedGuarantees"
|
|
4620
|
+
],
|
|
4621
|
+
properties: {
|
|
4622
|
+
requested: {
|
|
4623
|
+
$ref: "#/$defs/capabilityId"
|
|
4624
|
+
},
|
|
4625
|
+
selected: {
|
|
4626
|
+
$ref: "#/$defs/capabilityId"
|
|
4627
|
+
},
|
|
4628
|
+
reason: {
|
|
4629
|
+
enum: [
|
|
4630
|
+
"unsupported",
|
|
4631
|
+
"version-insufficient",
|
|
4632
|
+
"limit-insufficient"
|
|
4633
|
+
]
|
|
4634
|
+
},
|
|
4635
|
+
changedGuarantees: {
|
|
4636
|
+
type: "array",
|
|
4637
|
+
minItems: 1,
|
|
4638
|
+
items: {
|
|
4639
|
+
type: "string",
|
|
4640
|
+
minLength: 1
|
|
4641
|
+
}
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
},
|
|
4645
|
+
result: {
|
|
4646
|
+
type: "object",
|
|
4647
|
+
additionalProperties: false,
|
|
4648
|
+
required: [
|
|
4649
|
+
"contract",
|
|
4650
|
+
"accepted",
|
|
4651
|
+
"runtime",
|
|
4652
|
+
"selected",
|
|
4653
|
+
"degradations",
|
|
4654
|
+
"diagnostics"
|
|
4655
|
+
],
|
|
4656
|
+
properties: {
|
|
4657
|
+
contract: {
|
|
4658
|
+
const: "fortemi.dataset-execution-capabilities/v1"
|
|
4659
|
+
},
|
|
4660
|
+
accepted: {
|
|
4661
|
+
type: "boolean"
|
|
4662
|
+
},
|
|
4663
|
+
runtime: {
|
|
4664
|
+
$ref: "#/$defs/runtime"
|
|
4665
|
+
},
|
|
4666
|
+
selected: {
|
|
4667
|
+
type: "array",
|
|
4668
|
+
items: {
|
|
4669
|
+
$ref: "#/$defs/capabilityId"
|
|
4670
|
+
},
|
|
4671
|
+
uniqueItems: true
|
|
4672
|
+
},
|
|
4673
|
+
degradations: {
|
|
4674
|
+
type: "array",
|
|
4675
|
+
items: {
|
|
4676
|
+
$ref: "#/$defs/degradation"
|
|
4677
|
+
}
|
|
4678
|
+
},
|
|
4679
|
+
diagnostics: {
|
|
4680
|
+
type: "array",
|
|
4681
|
+
items: {
|
|
4682
|
+
$ref: "#/$defs/diagnostic"
|
|
4683
|
+
}
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
};
|
|
4689
|
+
|
|
4690
|
+
// src/dataset-execution-capabilities.ts
|
|
4218
4691
|
var DATASET_EXECUTION_CONTRACT = "fortemi.dataset-execution-capabilities/v1";
|
|
4219
4692
|
var DATASET_EXECUTION_SCHEMA_VERSION = "1.0.0";
|
|
4220
4693
|
var DATASET_EXECUTION_CAPABILITY_IDS = [
|
|
@@ -4250,27 +4723,64 @@ var DATASET_EXECUTION_CAPABILITY_IDS = [
|
|
|
4250
4723
|
];
|
|
4251
4724
|
var ID_SET = new Set(DATASET_EXECUTION_CAPABILITY_IDS);
|
|
4252
4725
|
var LIMIT_KEYS = ["maxInputBytes", "maxRecordBytes", "maxBatchRecords", "maxConcurrency", "maxPageSize", "maxTraversalDepth"];
|
|
4726
|
+
var versionPattern = new RegExp(schema_default.$defs.semver.pattern);
|
|
4727
|
+
var ajv = new Ajv20206({ strict: true, allErrors: false });
|
|
4728
|
+
ajv.addSchema(schema_default);
|
|
4729
|
+
var descriptorStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/descriptor" });
|
|
4730
|
+
var requestStructure = ajv.compile({ $ref: schema_default.$id + "#/$defs/request" });
|
|
4731
|
+
function parseVersion(value) {
|
|
4732
|
+
if (typeof value !== "string" || value.length > 256) return null;
|
|
4733
|
+
const match = versionPattern.exec(value);
|
|
4734
|
+
if (!match || match[0] !== value) return null;
|
|
4735
|
+
const core = match.slice(1, 4).map(Number);
|
|
4736
|
+
if (!core.every(Number.isSafeInteger)) return null;
|
|
4737
|
+
return { core, prerelease: match[4]?.split(".") ?? [] };
|
|
4738
|
+
}
|
|
4253
4739
|
function major(version) {
|
|
4254
|
-
const
|
|
4255
|
-
return
|
|
4740
|
+
const parsed = parseVersion(version);
|
|
4741
|
+
return parsed && parsed.prerelease.length === 0 ? parsed.core[0] : null;
|
|
4256
4742
|
}
|
|
4257
4743
|
function compareVersions(left, right) {
|
|
4258
|
-
const
|
|
4259
|
-
|
|
4260
|
-
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
4261
|
-
};
|
|
4262
|
-
const a = parse(left);
|
|
4263
|
-
const b = parse(right);
|
|
4744
|
+
const a = parseVersion(left);
|
|
4745
|
+
const b = parseVersion(right);
|
|
4264
4746
|
if (!a || !b) return null;
|
|
4265
4747
|
for (let index = 0; index < 3; index++) {
|
|
4266
|
-
if (a[index] !== b[index]) return a[index] > b[index] ? 1 : -1;
|
|
4748
|
+
if (a.core[index] !== b.core[index]) return a.core[index] > b.core[index] ? 1 : -1;
|
|
4749
|
+
}
|
|
4750
|
+
if (!a.prerelease.length || !b.prerelease.length) {
|
|
4751
|
+
return a.prerelease.length ? -1 : b.prerelease.length ? 1 : 0;
|
|
4752
|
+
}
|
|
4753
|
+
for (let index = 0; index < Math.max(a.prerelease.length, b.prerelease.length); index++) {
|
|
4754
|
+
const leftPart = a.prerelease[index];
|
|
4755
|
+
const rightPart = b.prerelease[index];
|
|
4756
|
+
if (leftPart === rightPart) continue;
|
|
4757
|
+
if (leftPart === void 0) return -1;
|
|
4758
|
+
if (rightPart === void 0) return 1;
|
|
4759
|
+
const leftNumeric = /^[0-9]+$/.test(leftPart);
|
|
4760
|
+
const rightNumeric = /^[0-9]+$/.test(rightPart);
|
|
4761
|
+
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
4762
|
+
if (leftNumeric && leftPart.length !== rightPart.length) return leftPart.length > rightPart.length ? 1 : -1;
|
|
4763
|
+
return leftPart > rightPart ? 1 : -1;
|
|
4267
4764
|
}
|
|
4268
4765
|
return 0;
|
|
4269
4766
|
}
|
|
4270
4767
|
function isSupported(capability) {
|
|
4271
|
-
return capability !== void 0 && capability.status
|
|
4768
|
+
return capability !== void 0 && (capability.status === "supported" || capability.status === "experimental");
|
|
4769
|
+
}
|
|
4770
|
+
function structuralDiagnostics(validate4, prefix = "") {
|
|
4771
|
+
return (validate4.errors ?? []).slice(0, 8).map((error) => ({
|
|
4772
|
+
code: "DESCRIPTOR_INVALID",
|
|
4773
|
+
path: (prefix + error.instancePath).slice(0, 256),
|
|
4774
|
+
message: "Invalid capability wire structure: " + error.keyword
|
|
4775
|
+
}));
|
|
4272
4776
|
}
|
|
4273
4777
|
function validateDatasetExecutionDescriptor(descriptor) {
|
|
4778
|
+
if (!descriptorStructure(descriptor)) {
|
|
4779
|
+
if (descriptor && typeof descriptor === "object" && "contract" in descriptor && descriptor.contract !== DATASET_EXECUTION_CONTRACT) {
|
|
4780
|
+
return [{ code: "CONTRACT_MAJOR_UNSUPPORTED", path: "/contract", message: "Unsupported descriptor contract" }];
|
|
4781
|
+
}
|
|
4782
|
+
return structuralDiagnostics(descriptorStructure);
|
|
4783
|
+
}
|
|
4274
4784
|
const diagnostics = [];
|
|
4275
4785
|
if (descriptor.contract !== DATASET_EXECUTION_CONTRACT) {
|
|
4276
4786
|
diagnostics.push({ code: "CONTRACT_MAJOR_UNSUPPORTED", path: "/contract", message: `Unsupported contract ${String(descriptor.contract)}` });
|
|
@@ -4278,6 +4788,9 @@ function validateDatasetExecutionDescriptor(descriptor) {
|
|
|
4278
4788
|
if (major(descriptor.schemaVersion) !== 1) {
|
|
4279
4789
|
diagnostics.push({ code: "SCHEMA_VERSION_UNSUPPORTED", path: "/schemaVersion", message: `Unsupported descriptor schema version ${descriptor.schemaVersion}` });
|
|
4280
4790
|
}
|
|
4791
|
+
if (!parseVersion(descriptor.runtime.version)) {
|
|
4792
|
+
diagnostics.push({ code: "DESCRIPTOR_INVALID", path: "/runtime/version", message: "Invalid runtime semantic version" });
|
|
4793
|
+
}
|
|
4281
4794
|
const capabilities = /* @__PURE__ */ new Map();
|
|
4282
4795
|
descriptor.capabilities.forEach((capability, index) => {
|
|
4283
4796
|
if (!ID_SET.has(capability.id) || compareVersions(capability.version, capability.version) === null) {
|
|
@@ -4288,10 +4801,10 @@ function validateDatasetExecutionDescriptor(descriptor) {
|
|
|
4288
4801
|
diagnostics.push({ code: "CAPABILITY_DUPLICATE", capability: capability.id, path: `/capabilities/${index}/id`, message: `Capability ${capability.id} is declared more than once` });
|
|
4289
4802
|
}
|
|
4290
4803
|
capabilities.set(capability.id, capability);
|
|
4291
|
-
for (const
|
|
4292
|
-
const value = capability.limits?.[
|
|
4804
|
+
for (const key3 of LIMIT_KEYS) {
|
|
4805
|
+
const value = capability.limits?.[key3];
|
|
4293
4806
|
if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0)) {
|
|
4294
|
-
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${
|
|
4807
|
+
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/limits/${key3}`, message: `${key3} must be a non-negative safe integer` });
|
|
4295
4808
|
}
|
|
4296
4809
|
}
|
|
4297
4810
|
if (capability.status !== "unsupported" && capability.evidence.length === 0) {
|
|
@@ -4299,7 +4812,7 @@ function validateDatasetExecutionDescriptor(descriptor) {
|
|
|
4299
4812
|
}
|
|
4300
4813
|
for (const evidenceId of capability.evidence) {
|
|
4301
4814
|
if (!descriptor.evidence.some((evidence) => evidence.id === evidenceId)) {
|
|
4302
|
-
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/evidence`, message:
|
|
4815
|
+
diagnostics.push({ code: "DESCRIPTOR_INVALID", capability: capability.id, path: `/capabilities/${index}/evidence`, message: "Capability references undeclared evidence" });
|
|
4303
4816
|
}
|
|
4304
4817
|
}
|
|
4305
4818
|
});
|
|
@@ -4326,31 +4839,53 @@ function validateDatasetExecutionDescriptor(descriptor) {
|
|
|
4326
4839
|
}
|
|
4327
4840
|
return diagnostics;
|
|
4328
4841
|
}
|
|
4842
|
+
function validateDatasetExecutionRequest(request) {
|
|
4843
|
+
if (!requestStructure(request)) {
|
|
4844
|
+
if (request && typeof request === "object" && "contract" in request && request.contract !== DATASET_EXECUTION_CONTRACT) {
|
|
4845
|
+
return [{ code: "CONTRACT_MAJOR_UNSUPPORTED", path: "/request/contract", message: "Unsupported request contract" }];
|
|
4846
|
+
}
|
|
4847
|
+
return structuralDiagnostics(requestStructure, "/request");
|
|
4848
|
+
}
|
|
4849
|
+
const diagnostics = [];
|
|
4850
|
+
for (const [group, requirements] of [["required", request.required], ["optional", request.optional ?? []]]) {
|
|
4851
|
+
requirements.forEach((requirement, index) => {
|
|
4852
|
+
if (requirement.minimumVersion !== void 0 && !parseVersion(requirement.minimumVersion)) {
|
|
4853
|
+
diagnostics.push({ code: "DESCRIPTOR_INVALID", path: "/request/" + group + "/" + index + "/minimumVersion", message: "Invalid required semantic version" });
|
|
4854
|
+
}
|
|
4855
|
+
});
|
|
4856
|
+
}
|
|
4857
|
+
return diagnostics;
|
|
4858
|
+
}
|
|
4859
|
+
function negotiateDatasetExecutionCapabilitiesFromWire(descriptor, request) {
|
|
4860
|
+
const diagnostics = [...validateDatasetExecutionDescriptor(descriptor), ...validateDatasetExecutionRequest(request)];
|
|
4861
|
+
if (diagnostics.length) return { valid: false, diagnostics };
|
|
4862
|
+
return {
|
|
4863
|
+
valid: true,
|
|
4864
|
+
result: negotiateDatasetExecutionCapabilities(descriptor, request)
|
|
4865
|
+
};
|
|
4866
|
+
}
|
|
4329
4867
|
function assessRequirement(requirement, capabilities) {
|
|
4330
4868
|
const capability = capabilities.get(requirement.id);
|
|
4331
4869
|
if (!isSupported(capability)) {
|
|
4332
4870
|
return { ok: false, reason: "unsupported", diagnostics: [{ code: "REQUIRED_CAPABILITY_MISSING", capability: requirement.id, message: `Capability ${requirement.id} is unsupported` }] };
|
|
4333
4871
|
}
|
|
4334
|
-
if (requirement.minimumVersion) {
|
|
4872
|
+
if (requirement.minimumVersion !== void 0) {
|
|
4335
4873
|
const comparison = compareVersions(capability.version, requirement.minimumVersion);
|
|
4336
4874
|
if (comparison === null || comparison < 0) {
|
|
4337
4875
|
return { ok: false, reason: "version-insufficient", diagnostics: [{ code: "CAPABILITY_VERSION_INSUFFICIENT", capability: requirement.id, message: `${capability.version} does not satisfy ${requirement.minimumVersion}` }] };
|
|
4338
4876
|
}
|
|
4339
4877
|
}
|
|
4340
|
-
for (const
|
|
4341
|
-
const required = requirement.minimumLimits?.[
|
|
4342
|
-
if (required !== void 0 && (capability.limits?.[
|
|
4343
|
-
return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${
|
|
4878
|
+
for (const key3 of LIMIT_KEYS) {
|
|
4879
|
+
const required = requirement.minimumLimits?.[key3];
|
|
4880
|
+
if (required !== void 0 && (capability.limits?.[key3] ?? -1) < required) {
|
|
4881
|
+
return { ok: false, reason: "limit-insufficient", diagnostics: [{ code: "CAPABILITY_LIMIT_INSUFFICIENT", capability: requirement.id, path: `/minimumLimits/${key3}`, message: `${key3} does not satisfy ${required}` }] };
|
|
4344
4882
|
}
|
|
4345
4883
|
}
|
|
4346
4884
|
return { ok: true, diagnostics: [] };
|
|
4347
4885
|
}
|
|
4348
4886
|
function negotiateDatasetExecutionCapabilities(descriptor, request) {
|
|
4349
|
-
const diagnostics = validateDatasetExecutionDescriptor(descriptor);
|
|
4350
|
-
|
|
4351
|
-
diagnostics.push({ code: "CONTRACT_MAJOR_UNSUPPORTED", path: "/contract", message: `Unsupported request contract ${String(request.contract)}` });
|
|
4352
|
-
}
|
|
4353
|
-
const capabilities = new Map(descriptor.capabilities.map((capability) => [capability.id, capability]));
|
|
4887
|
+
const diagnostics = [...validateDatasetExecutionDescriptor(descriptor), ...validateDatasetExecutionRequest(request)];
|
|
4888
|
+
const capabilities = new Map(diagnostics.length ? [] : descriptor.capabilities.map((capability) => [capability.id, capability]));
|
|
4354
4889
|
const selected = [];
|
|
4355
4890
|
const degradations = [];
|
|
4356
4891
|
if (diagnostics.length === 0) {
|
|
@@ -4378,7 +4913,7 @@ function negotiateDatasetExecutionCapabilities(descriptor, request) {
|
|
|
4378
4913
|
return {
|
|
4379
4914
|
contract: DATASET_EXECUTION_CONTRACT,
|
|
4380
4915
|
accepted: diagnostics.length === 0,
|
|
4381
|
-
runtime: { ...descriptor
|
|
4916
|
+
runtime: { ...descriptor?.runtime },
|
|
4382
4917
|
selected: [...new Set(selected)],
|
|
4383
4918
|
degradations,
|
|
4384
4919
|
diagnostics
|
|
@@ -4451,7 +4986,7 @@ var encoder = new TextEncoder();
|
|
|
4451
4986
|
function canonicalJson3(value) {
|
|
4452
4987
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
4453
4988
|
if (Array.isArray(value)) return `[${value.map(canonicalJson3).join(",")}]`;
|
|
4454
|
-
return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([
|
|
4989
|
+
return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson3(item)}`).join(",")}}`;
|
|
4455
4990
|
}
|
|
4456
4991
|
function digestDatasetMaterializationValue(value) {
|
|
4457
4992
|
return computeHash(encoder.encode(canonicalJson3(value)));
|
|
@@ -4542,7 +5077,7 @@ async function executeDatasetMaterialization(request, runtime, adapter, authoriz
|
|
|
4542
5077
|
}
|
|
4543
5078
|
const selected = [request.profile, ...options.fallbackProfiles ?? []].find((item) => item.id === negotiation.selectedProfile);
|
|
4544
5079
|
try {
|
|
4545
|
-
const validateConfiguration = new
|
|
5080
|
+
const validateConfiguration = new Ajv20206({ strict: true, allErrors: true }).compile(selected.configurationSchema);
|
|
4546
5081
|
if (!validateConfiguration(request.configuration)) {
|
|
4547
5082
|
throw new DatasetMaterializationError("CONFIGURATION_INVALID", `Configuration does not satisfy ${selected.id}: ${JSON.stringify(validateConfiguration.errors)}`);
|
|
4548
5083
|
}
|
|
@@ -6342,7 +6877,7 @@ function nativeIdentityKey(spec, row) {
|
|
|
6342
6877
|
// src/migrations/0031_native_shard_lineage.ts
|
|
6343
6878
|
var triggers = Object.entries(nativeIdentities).flatMap(([component, spec]) => (component === "links" ? ["link", "link_url_target"] : [spec.table]).map((table) => `
|
|
6344
6879
|
CREATE TRIGGER native_lineage_delete AFTER DELETE ON ${table} FOR EACH ROW
|
|
6345
|
-
EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((
|
|
6880
|
+
EXECUTE FUNCTION delete_native_record_lineage('${component}', ${spec.keys.map((key3) => `'${key3}'`).join(", ")});`)).join("\n");
|
|
6346
6881
|
var migration0031 = {
|
|
6347
6882
|
version: 31,
|
|
6348
6883
|
name: "0031_native_shard_lineage",
|
|
@@ -6388,6 +6923,58 @@ var migration0032 = {
|
|
|
6388
6923
|
`
|
|
6389
6924
|
};
|
|
6390
6925
|
|
|
6926
|
+
// src/migrations/0033_typed_metadata_search.ts
|
|
6927
|
+
init_geometry_buffer();
|
|
6928
|
+
var migration0033 = {
|
|
6929
|
+
version: 33,
|
|
6930
|
+
name: "0033_typed_metadata_search",
|
|
6931
|
+
sql: `
|
|
6932
|
+
CREATE FUNCTION public.metadata_search_order_key_v1(value jsonb)
|
|
6933
|
+
RETURNS numeric LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
|
|
6934
|
+
SET search_path = pg_catalog
|
|
6935
|
+
AS $function$
|
|
6936
|
+
SELECT CASE jsonb_typeof(value)
|
|
6937
|
+
WHEN 'number' THEN trunc(greatest(-1e16::numeric,
|
|
6938
|
+
least(1e16::numeric, (value #>> '{}')::numeric)), 18)
|
|
6939
|
+
WHEN 'boolean' THEN CASE WHEN value = 'true'::jsonb THEN 1::numeric ELSE 0::numeric END
|
|
6940
|
+
ELSE NULL::numeric
|
|
6941
|
+
END
|
|
6942
|
+
$function$;
|
|
6943
|
+
|
|
6944
|
+
CREATE FUNCTION public.metadata_search_text_key_v1(value jsonb)
|
|
6945
|
+
RETURNS text LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
|
|
6946
|
+
SET search_path = pg_catalog
|
|
6947
|
+
AS $function$
|
|
6948
|
+
SELECT CASE WHEN jsonb_typeof(value) = 'string'
|
|
6949
|
+
THEN left(value #>> '{}', 256) ELSE NULL::text END
|
|
6950
|
+
$function$;
|
|
6951
|
+
|
|
6952
|
+
DO $metadata_indexes$
|
|
6953
|
+
DECLARE metadata_path text;
|
|
6954
|
+
BEGIN
|
|
6955
|
+
FOREACH metadata_path IN ARRAY ARRAY['provider', 'model', 'role', 'event_kind', 'sensitivity']
|
|
6956
|
+
LOOP
|
|
6957
|
+
-- Superseded unbounded indexes can reject large values before query rechecks.
|
|
6958
|
+
EXECUTE format('DROP INDEX %I', 'idx_note_metadata_' || metadata_path);
|
|
6959
|
+
EXECUTE format('DROP INDEX %I', 'idx_note_native_metadata_' || metadata_path);
|
|
6960
|
+
EXECUTE format(
|
|
6961
|
+
'CREATE INDEX %I ON note (
|
|
6962
|
+
(jsonb_typeof(metadata -> %L)),
|
|
6963
|
+
(public.metadata_search_order_key_v1(metadata -> %L)),
|
|
6964
|
+
(public.metadata_search_text_key_v1(metadata -> %L) COLLATE "C"))',
|
|
6965
|
+
'idx_note_metadata_' || metadata_path || '_v1', metadata_path, metadata_path, metadata_path);
|
|
6966
|
+
END LOOP;
|
|
6967
|
+
END
|
|
6968
|
+
$metadata_indexes$;
|
|
6969
|
+
|
|
6970
|
+
CREATE INDEX idx_source_identity_metadata_run_v1 ON source_identity
|
|
6971
|
+
(tenant_id, import_run_id COLLATE "C", note_id);
|
|
6972
|
+
CREATE INDEX idx_source_identity_metadata_note_v1 ON source_identity (tenant_id, note_id);
|
|
6973
|
+
UPDATE metadata_index_path SET value_type = 'json-scalar-v1', indexed_at = now()
|
|
6974
|
+
WHERE path IN ('provider', 'model', 'role', 'event_kind', 'sensitivity');
|
|
6975
|
+
`
|
|
6976
|
+
};
|
|
6977
|
+
|
|
6391
6978
|
// src/migrations/index.ts
|
|
6392
6979
|
var allMigrations = [
|
|
6393
6980
|
migration0001,
|
|
@@ -6421,7 +7008,8 @@ var allMigrations = [
|
|
|
6421
7008
|
migration0029,
|
|
6422
7009
|
migration0030,
|
|
6423
7010
|
migration0031,
|
|
6424
|
-
migration0032
|
|
7011
|
+
migration0032,
|
|
7012
|
+
migration0033
|
|
6425
7013
|
];
|
|
6426
7014
|
|
|
6427
7015
|
// src/data-archive.ts
|
|
@@ -7023,6 +7611,137 @@ var NotesRepository = class {
|
|
|
7023
7611
|
// src/repositories/search-repository.ts
|
|
7024
7612
|
init_geometry_buffer();
|
|
7025
7613
|
|
|
7614
|
+
// src/repositories/search-evidence-repository.ts
|
|
7615
|
+
init_geometry_buffer();
|
|
7616
|
+
|
|
7617
|
+
// src/search-evidence.ts
|
|
7618
|
+
init_geometry_buffer();
|
|
7619
|
+
|
|
7620
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-locator.schema.json
|
|
7621
|
+
var evidence_locator_schema_default = {
|
|
7622
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7623
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-locator.schema.json",
|
|
7624
|
+
title: "Candidate search evidence locator",
|
|
7625
|
+
type: "object",
|
|
7626
|
+
additionalProperties: false,
|
|
7627
|
+
required: ["version", "note_id", "unit", "content_digest", "span"],
|
|
7628
|
+
properties: {
|
|
7629
|
+
version: { const: "1.0.0" },
|
|
7630
|
+
note_id: { $ref: "#/$defs/identifier" },
|
|
7631
|
+
unit: {
|
|
7632
|
+
type: "object",
|
|
7633
|
+
additionalProperties: false,
|
|
7634
|
+
required: ["kind", "id", "index"],
|
|
7635
|
+
properties: {
|
|
7636
|
+
kind: { enum: ["current", "title", "embedding", "attachment"] },
|
|
7637
|
+
id: { $ref: "#/$defs/identifier" },
|
|
7638
|
+
index: { type: "integer", minimum: 0, maximum: 2147483647 }
|
|
7639
|
+
},
|
|
7640
|
+
if: { properties: { kind: { enum: ["current", "title", "attachment"] } } },
|
|
7641
|
+
then: { properties: { index: { const: 0 } } }
|
|
7642
|
+
},
|
|
7643
|
+
content_digest: { $ref: "#/$defs/digest" },
|
|
7644
|
+
span: {
|
|
7645
|
+
type: "object",
|
|
7646
|
+
additionalProperties: false,
|
|
7647
|
+
required: ["unit", "start", "end"],
|
|
7648
|
+
properties: {
|
|
7649
|
+
unit: { const: "utf8-bytes" },
|
|
7650
|
+
start: { type: "integer", minimum: 0, maximum: 16777216 },
|
|
7651
|
+
end: { type: "integer", minimum: 0, maximum: 16777216 }
|
|
7652
|
+
}
|
|
7653
|
+
},
|
|
7654
|
+
source: {
|
|
7655
|
+
type: "object",
|
|
7656
|
+
additionalProperties: false,
|
|
7657
|
+
required: ["namespace", "external_id_hash", "import_run_id", "schema_version"],
|
|
7658
|
+
properties: {
|
|
7659
|
+
namespace: { $ref: "#/$defs/identifier" },
|
|
7660
|
+
external_id_hash: { $ref: "#/$defs/digest" },
|
|
7661
|
+
import_run_id: { $ref: "#/$defs/identifier" },
|
|
7662
|
+
schema_version: { $ref: "#/$defs/identifier" }
|
|
7663
|
+
}
|
|
7664
|
+
}
|
|
7665
|
+
},
|
|
7666
|
+
$defs: {
|
|
7667
|
+
identifier: { type: "string", minLength: 1, maxLength: 200, pattern: "^[^\\u0000]+$" },
|
|
7668
|
+
digest: { type: "string", pattern: "^sha256:[a-f0-9]{64}$" }
|
|
7669
|
+
}
|
|
7670
|
+
};
|
|
7671
|
+
|
|
7672
|
+
// src/search-evidence.ts
|
|
7673
|
+
var MAX_EVIDENCE_BYTES = 16 * 1024 * 1024;
|
|
7674
|
+
var validateSchema = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(evidence_locator_schema_default);
|
|
7675
|
+
var encoder2 = new TextEncoder();
|
|
7676
|
+
var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
7677
|
+
var invalid = () => new Error("SEARCH_EVIDENCE_INVALID");
|
|
7678
|
+
var unavailable = () => new Error("SEARCH_EVIDENCE_UNAVAILABLE");
|
|
7679
|
+
function wellFormed(value) {
|
|
7680
|
+
for (let i = 0; i < value.length; i++) {
|
|
7681
|
+
const code = value.charCodeAt(i);
|
|
7682
|
+
if (code >= 55296 && code <= 56319) {
|
|
7683
|
+
const next = value.charCodeAt(++i);
|
|
7684
|
+
if (!(next >= 56320 && next <= 57343)) return false;
|
|
7685
|
+
} else if (code >= 56320 && code <= 57343) return false;
|
|
7686
|
+
}
|
|
7687
|
+
return true;
|
|
7688
|
+
}
|
|
7689
|
+
function parseSearchEvidenceLocator(value) {
|
|
7690
|
+
if (!validateSchema(value)) throw invalid();
|
|
7691
|
+
const locator = value;
|
|
7692
|
+
const strings = [locator.note_id, locator.unit.id, ...Object.values(locator.source ?? {})];
|
|
7693
|
+
if (!strings.every(wellFormed) || locator.span.start > locator.span.end) throw invalid();
|
|
7694
|
+
if ((locator.unit.kind === "current" || locator.unit.kind === "title") && locator.unit.id !== locator.note_id) throw invalid();
|
|
7695
|
+
const copy = {
|
|
7696
|
+
version: locator.version,
|
|
7697
|
+
note_id: locator.note_id,
|
|
7698
|
+
unit: Object.freeze({ kind: locator.unit.kind, id: locator.unit.id, index: locator.unit.index }),
|
|
7699
|
+
content_digest: locator.content_digest,
|
|
7700
|
+
span: Object.freeze({ unit: locator.span.unit, start: locator.span.start, end: locator.span.end }),
|
|
7701
|
+
...locator.source === void 0 ? {} : { source: Object.freeze({ ...locator.source }) }
|
|
7702
|
+
};
|
|
7703
|
+
return Object.freeze(copy);
|
|
7704
|
+
}
|
|
7705
|
+
function textBytes(content) {
|
|
7706
|
+
if (typeof content !== "string" || content.length > MAX_EVIDENCE_BYTES || !wellFormed(content)) return null;
|
|
7707
|
+
const bytes = encoder2.encode(content);
|
|
7708
|
+
return bytes.length <= MAX_EVIDENCE_BYTES ? bytes : null;
|
|
7709
|
+
}
|
|
7710
|
+
function spanText(bytes, start, end) {
|
|
7711
|
+
if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || start > end || end > bytes.length) return null;
|
|
7712
|
+
if (start < bytes.length && (bytes[start] & 192) === 128 || end < bytes.length && (bytes[end] & 192) === 128) return null;
|
|
7713
|
+
try {
|
|
7714
|
+
return decoder.decode(bytes.subarray(start, end));
|
|
7715
|
+
} catch {
|
|
7716
|
+
return null;
|
|
7717
|
+
}
|
|
7718
|
+
}
|
|
7719
|
+
function bindSearchEvidence(text, start, end) {
|
|
7720
|
+
const bytes = textBytes(text.content);
|
|
7721
|
+
if (!bytes || spanText(bytes, start, end) === null) throw invalid();
|
|
7722
|
+
return parseSearchEvidenceLocator({
|
|
7723
|
+
version: "1.0.0",
|
|
7724
|
+
note_id: text.note_id,
|
|
7725
|
+
unit: text.unit,
|
|
7726
|
+
content_digest: computeHash(bytes),
|
|
7727
|
+
span: { unit: "utf8-bytes", start, end },
|
|
7728
|
+
...text.source === void 0 ? {} : { source: text.source }
|
|
7729
|
+
});
|
|
7730
|
+
}
|
|
7731
|
+
function sameSource(a, b) {
|
|
7732
|
+
if (!a || !b) return a === b;
|
|
7733
|
+
return a.namespace === b.namespace && a.external_id_hash === b.external_id_hash && a.import_run_id === b.import_run_id && a.schema_version === b.schema_version;
|
|
7734
|
+
}
|
|
7735
|
+
function resolveSearchEvidence(value, text) {
|
|
7736
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
7737
|
+
if (!text || locator.note_id !== text.note_id || locator.unit.kind !== text.unit.kind || locator.unit.id !== text.unit.id || locator.unit.index !== text.unit.index || !sameSource(locator.source, text.source)) throw unavailable();
|
|
7738
|
+
const bytes = textBytes(text.content);
|
|
7739
|
+
if (!bytes || computeHash(bytes) !== locator.content_digest) throw unavailable();
|
|
7740
|
+
const result = spanText(bytes, locator.span.start, locator.span.end);
|
|
7741
|
+
if (result === null) throw unavailable();
|
|
7742
|
+
return result;
|
|
7743
|
+
}
|
|
7744
|
+
|
|
7026
7745
|
// src/repositories/condition-builder.ts
|
|
7027
7746
|
init_geometry_buffer();
|
|
7028
7747
|
function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
@@ -7038,6 +7757,11 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7038
7757
|
);
|
|
7039
7758
|
params.push(options.tags);
|
|
7040
7759
|
}
|
|
7760
|
+
if (options.tagsAll?.length) {
|
|
7761
|
+
conditions.push(`NOT EXISTS (SELECT 1 FROM unnest($${idx++}::text[]) wanted(tag)
|
|
7762
|
+
WHERE NOT EXISTS (SELECT 1 FROM note_tag nt WHERE nt.note_id = n.id AND nt.tag = wanted.tag))`);
|
|
7763
|
+
params.push(options.tagsAll);
|
|
7764
|
+
}
|
|
7041
7765
|
if (options.collection_id) {
|
|
7042
7766
|
conditions.push(
|
|
7043
7767
|
`EXISTS (SELECT 1 FROM collection_note cn WHERE cn.note_id = n.id AND cn.collection_id = $${idx++})`
|
|
@@ -7068,6 +7792,10 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7068
7792
|
conditions.push(`n.source = $${idx++}`);
|
|
7069
7793
|
params.push(options.source);
|
|
7070
7794
|
}
|
|
7795
|
+
if (options.sources?.length) {
|
|
7796
|
+
conditions.push(`n.source = ANY($${idx++}::text[])`);
|
|
7797
|
+
params.push(options.sources);
|
|
7798
|
+
}
|
|
7071
7799
|
if (options.visibility) {
|
|
7072
7800
|
conditions.push(`n.visibility = $${idx++}`);
|
|
7073
7801
|
params.push(options.visibility);
|
|
@@ -7075,6 +7803,657 @@ function buildNoteConditions(options, startIdx, includeDeleted = false) {
|
|
|
7075
7803
|
return { conditions, params, nextIdx: idx };
|
|
7076
7804
|
}
|
|
7077
7805
|
|
|
7806
|
+
// src/repositories/metadata-predicates.ts
|
|
7807
|
+
init_geometry_buffer();
|
|
7808
|
+
|
|
7809
|
+
// schemas/metadata-search/candidate/1.0.0/predicates.schema.json
|
|
7810
|
+
var predicates_schema_default = {
|
|
7811
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7812
|
+
$id: "https://fortemi.dev/schemas/metadata-search/candidate/1.0.0/predicates.schema.json",
|
|
7813
|
+
title: "Candidate typed metadata predicates",
|
|
7814
|
+
type: "array",
|
|
7815
|
+
maxItems: 8,
|
|
7816
|
+
items: {
|
|
7817
|
+
$ref: "#/$defs/predicate"
|
|
7818
|
+
},
|
|
7819
|
+
$defs: {
|
|
7820
|
+
scalar: {
|
|
7821
|
+
oneOf: [
|
|
7822
|
+
{
|
|
7823
|
+
type: "string",
|
|
7824
|
+
maxLength: 256,
|
|
7825
|
+
pattern: "^[^\\u0000]*$"
|
|
7826
|
+
},
|
|
7827
|
+
{
|
|
7828
|
+
type: "number",
|
|
7829
|
+
minimum: -9007199254740991,
|
|
7830
|
+
maximum: 9007199254740991
|
|
7831
|
+
},
|
|
7832
|
+
{
|
|
7833
|
+
type: "boolean"
|
|
7834
|
+
},
|
|
7835
|
+
{
|
|
7836
|
+
type: "null"
|
|
7837
|
+
}
|
|
7838
|
+
]
|
|
7839
|
+
},
|
|
7840
|
+
bound: {
|
|
7841
|
+
oneOf: [
|
|
7842
|
+
{
|
|
7843
|
+
type: "string",
|
|
7844
|
+
maxLength: 256,
|
|
7845
|
+
pattern: "^[^\\u0000]*$"
|
|
7846
|
+
},
|
|
7847
|
+
{
|
|
7848
|
+
type: "number",
|
|
7849
|
+
minimum: -9007199254740991,
|
|
7850
|
+
maximum: 9007199254740991
|
|
7851
|
+
}
|
|
7852
|
+
]
|
|
7853
|
+
},
|
|
7854
|
+
predicate: {
|
|
7855
|
+
oneOf: [
|
|
7856
|
+
{
|
|
7857
|
+
type: "object",
|
|
7858
|
+
additionalProperties: false,
|
|
7859
|
+
required: [
|
|
7860
|
+
"path",
|
|
7861
|
+
"op",
|
|
7862
|
+
"value"
|
|
7863
|
+
],
|
|
7864
|
+
properties: {
|
|
7865
|
+
path: {
|
|
7866
|
+
enum: [
|
|
7867
|
+
"provider",
|
|
7868
|
+
"model",
|
|
7869
|
+
"role",
|
|
7870
|
+
"event_kind",
|
|
7871
|
+
"sensitivity",
|
|
7872
|
+
"import_run_id"
|
|
7873
|
+
]
|
|
7874
|
+
},
|
|
7875
|
+
op: {
|
|
7876
|
+
const: "eq"
|
|
7877
|
+
},
|
|
7878
|
+
value: {
|
|
7879
|
+
$ref: "#/$defs/scalar"
|
|
7880
|
+
}
|
|
7881
|
+
},
|
|
7882
|
+
allOf: [
|
|
7883
|
+
{
|
|
7884
|
+
if: {
|
|
7885
|
+
properties: {
|
|
7886
|
+
path: {
|
|
7887
|
+
const: "import_run_id"
|
|
7888
|
+
}
|
|
7889
|
+
}
|
|
7890
|
+
},
|
|
7891
|
+
then: {
|
|
7892
|
+
properties: {
|
|
7893
|
+
value: {
|
|
7894
|
+
type: "string",
|
|
7895
|
+
maxLength: 200,
|
|
7896
|
+
pattern: "^[^\\u0000]*$",
|
|
7897
|
+
minLength: 1
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
}
|
|
7902
|
+
]
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
type: "object",
|
|
7906
|
+
additionalProperties: false,
|
|
7907
|
+
required: [
|
|
7908
|
+
"path",
|
|
7909
|
+
"op",
|
|
7910
|
+
"value"
|
|
7911
|
+
],
|
|
7912
|
+
properties: {
|
|
7913
|
+
path: {
|
|
7914
|
+
enum: [
|
|
7915
|
+
"provider",
|
|
7916
|
+
"model",
|
|
7917
|
+
"role",
|
|
7918
|
+
"event_kind",
|
|
7919
|
+
"sensitivity",
|
|
7920
|
+
"import_run_id"
|
|
7921
|
+
]
|
|
7922
|
+
},
|
|
7923
|
+
op: {
|
|
7924
|
+
const: "in"
|
|
7925
|
+
},
|
|
7926
|
+
value: {
|
|
7927
|
+
type: "array",
|
|
7928
|
+
maxItems: 32,
|
|
7929
|
+
items: {
|
|
7930
|
+
$ref: "#/$defs/scalar"
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
},
|
|
7934
|
+
allOf: [
|
|
7935
|
+
{
|
|
7936
|
+
if: {
|
|
7937
|
+
properties: {
|
|
7938
|
+
path: {
|
|
7939
|
+
const: "import_run_id"
|
|
7940
|
+
}
|
|
7941
|
+
}
|
|
7942
|
+
},
|
|
7943
|
+
then: {
|
|
7944
|
+
properties: {
|
|
7945
|
+
value: {
|
|
7946
|
+
type: "array",
|
|
7947
|
+
items: {
|
|
7948
|
+
type: "string",
|
|
7949
|
+
maxLength: 200,
|
|
7950
|
+
pattern: "^[^\\u0000]*$",
|
|
7951
|
+
minLength: 1
|
|
7952
|
+
}
|
|
7953
|
+
}
|
|
7954
|
+
}
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7957
|
+
]
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
type: "object",
|
|
7961
|
+
additionalProperties: false,
|
|
7962
|
+
required: [
|
|
7963
|
+
"path",
|
|
7964
|
+
"op"
|
|
7965
|
+
],
|
|
7966
|
+
properties: {
|
|
7967
|
+
path: {
|
|
7968
|
+
enum: [
|
|
7969
|
+
"provider",
|
|
7970
|
+
"model",
|
|
7971
|
+
"role",
|
|
7972
|
+
"event_kind",
|
|
7973
|
+
"sensitivity",
|
|
7974
|
+
"import_run_id"
|
|
7975
|
+
]
|
|
7976
|
+
},
|
|
7977
|
+
op: {
|
|
7978
|
+
const: "range"
|
|
7979
|
+
},
|
|
7980
|
+
gte: {
|
|
7981
|
+
$ref: "#/$defs/bound"
|
|
7982
|
+
},
|
|
7983
|
+
lte: {
|
|
7984
|
+
$ref: "#/$defs/bound"
|
|
7985
|
+
}
|
|
7986
|
+
},
|
|
7987
|
+
anyOf: [
|
|
7988
|
+
{
|
|
7989
|
+
properties: {
|
|
7990
|
+
gte: {
|
|
7991
|
+
$ref: "#/$defs/bound"
|
|
7992
|
+
}
|
|
7993
|
+
},
|
|
7994
|
+
required: [
|
|
7995
|
+
"gte"
|
|
7996
|
+
]
|
|
7997
|
+
},
|
|
7998
|
+
{
|
|
7999
|
+
properties: {
|
|
8000
|
+
lte: {
|
|
8001
|
+
$ref: "#/$defs/bound"
|
|
8002
|
+
}
|
|
8003
|
+
},
|
|
8004
|
+
required: [
|
|
8005
|
+
"lte"
|
|
8006
|
+
]
|
|
8007
|
+
}
|
|
8008
|
+
],
|
|
8009
|
+
oneOf: [
|
|
8010
|
+
{
|
|
8011
|
+
properties: {
|
|
8012
|
+
gte: {
|
|
8013
|
+
type: "string",
|
|
8014
|
+
maxLength: 256,
|
|
8015
|
+
pattern: "^[^\\u0000]*$"
|
|
8016
|
+
},
|
|
8017
|
+
lte: {
|
|
8018
|
+
type: "string",
|
|
8019
|
+
maxLength: 256,
|
|
8020
|
+
pattern: "^[^\\u0000]*$"
|
|
8021
|
+
}
|
|
8022
|
+
}
|
|
8023
|
+
},
|
|
8024
|
+
{
|
|
8025
|
+
properties: {
|
|
8026
|
+
gte: {
|
|
8027
|
+
type: "number",
|
|
8028
|
+
minimum: -9007199254740991,
|
|
8029
|
+
maximum: 9007199254740991
|
|
8030
|
+
},
|
|
8031
|
+
lte: {
|
|
8032
|
+
type: "number",
|
|
8033
|
+
minimum: -9007199254740991,
|
|
8034
|
+
maximum: 9007199254740991
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
}
|
|
8038
|
+
],
|
|
8039
|
+
allOf: [
|
|
8040
|
+
{
|
|
8041
|
+
if: {
|
|
8042
|
+
properties: {
|
|
8043
|
+
path: {
|
|
8044
|
+
const: "import_run_id"
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
},
|
|
8048
|
+
then: {
|
|
8049
|
+
properties: {
|
|
8050
|
+
gte: {
|
|
8051
|
+
type: "string",
|
|
8052
|
+
maxLength: 200,
|
|
8053
|
+
pattern: "^[^\\u0000]*$",
|
|
8054
|
+
minLength: 1
|
|
8055
|
+
},
|
|
8056
|
+
lte: {
|
|
8057
|
+
type: "string",
|
|
8058
|
+
maxLength: 200,
|
|
8059
|
+
pattern: "^[^\\u0000]*$",
|
|
8060
|
+
minLength: 1
|
|
8061
|
+
}
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
}
|
|
8065
|
+
]
|
|
8066
|
+
},
|
|
8067
|
+
{
|
|
8068
|
+
type: "object",
|
|
8069
|
+
additionalProperties: false,
|
|
8070
|
+
required: [
|
|
8071
|
+
"path",
|
|
8072
|
+
"op"
|
|
8073
|
+
],
|
|
8074
|
+
properties: {
|
|
8075
|
+
path: {
|
|
8076
|
+
enum: [
|
|
8077
|
+
"provider",
|
|
8078
|
+
"model",
|
|
8079
|
+
"role",
|
|
8080
|
+
"event_kind",
|
|
8081
|
+
"sensitivity",
|
|
8082
|
+
"import_run_id"
|
|
8083
|
+
]
|
|
8084
|
+
},
|
|
8085
|
+
op: {
|
|
8086
|
+
const: "exists"
|
|
8087
|
+
},
|
|
8088
|
+
value: {
|
|
8089
|
+
type: "boolean"
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
]
|
|
8094
|
+
}
|
|
8095
|
+
}
|
|
8096
|
+
};
|
|
8097
|
+
|
|
8098
|
+
// src/repositories/metadata-predicates.ts
|
|
8099
|
+
var REGISTERED_METADATA_PATHS = [
|
|
8100
|
+
"provider",
|
|
8101
|
+
"model",
|
|
8102
|
+
"role",
|
|
8103
|
+
"event_kind",
|
|
8104
|
+
"sensitivity",
|
|
8105
|
+
"import_run_id"
|
|
8106
|
+
];
|
|
8107
|
+
var validateSchema2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).compile(predicates_schema_default);
|
|
8108
|
+
function compareStrings(left, right) {
|
|
8109
|
+
const a = Array.from(left, (char) => char.codePointAt(0));
|
|
8110
|
+
const b = Array.from(right, (char) => char.codePointAt(0));
|
|
8111
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
8112
|
+
if (a[i] !== b[i]) return a[i] - b[i];
|
|
8113
|
+
}
|
|
8114
|
+
return a.length - b.length;
|
|
8115
|
+
}
|
|
8116
|
+
function validateMetadataPredicates(value) {
|
|
8117
|
+
if (!validateSchema2(value)) throw new Error("METADATA_PREDICATES_INVALID");
|
|
8118
|
+
const predicates = value;
|
|
8119
|
+
for (const predicate of predicates) {
|
|
8120
|
+
const values = predicate.op === "range" ? [predicate.gte, predicate.lte] : predicate.op === "in" ? predicate.value : [predicate.value];
|
|
8121
|
+
for (const scalar of values) {
|
|
8122
|
+
if (typeof scalar === "string" && Array.from(scalar).some((char) => {
|
|
8123
|
+
const code = char.codePointAt(0);
|
|
8124
|
+
return code >= 55296 && code <= 57343;
|
|
8125
|
+
})) throw new Error("METADATA_PREDICATES_INVALID");
|
|
8126
|
+
}
|
|
8127
|
+
}
|
|
8128
|
+
for (const predicate of predicates) {
|
|
8129
|
+
if (predicate.op !== "range" || predicate.gte === void 0 || predicate.lte === void 0) continue;
|
|
8130
|
+
const reversed = typeof predicate.gte === "string" ? compareStrings(predicate.gte, predicate.lte) > 0 : predicate.gte > predicate.lte;
|
|
8131
|
+
if (reversed) throw new Error("METADATA_RANGE_INVALID");
|
|
8132
|
+
}
|
|
8133
|
+
}
|
|
8134
|
+
function predicateSql(predicate, compare, exists) {
|
|
8135
|
+
switch (predicate.op) {
|
|
8136
|
+
case "eq":
|
|
8137
|
+
return compare(predicate.value, "=");
|
|
8138
|
+
case "in":
|
|
8139
|
+
return predicate.value.length ? `(${predicate.value.map((value) => compare(value, "=")).join(" OR ")})` : "FALSE";
|
|
8140
|
+
case "range":
|
|
8141
|
+
return `(${[
|
|
8142
|
+
predicate.gte === void 0 ? null : compare(predicate.gte, ">="),
|
|
8143
|
+
predicate.lte === void 0 ? null : compare(predicate.lte, "<=")
|
|
8144
|
+
].filter(Boolean).join(" AND ")})`;
|
|
8145
|
+
case "exists":
|
|
8146
|
+
return predicate.value === false ? `NOT (${exists})` : exists;
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
8149
|
+
function buildMetadataSourceConditions(options, startIdx) {
|
|
8150
|
+
const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
|
|
8151
|
+
validateMetadataPredicates(predicates);
|
|
8152
|
+
const params = [options.tenant_id ?? "default"];
|
|
8153
|
+
let idx = startIdx + 1;
|
|
8154
|
+
const conditions = [
|
|
8155
|
+
`si.note_id = n.id`,
|
|
8156
|
+
`si.tenant_id = $${startIdx}`,
|
|
8157
|
+
"si.archive_id IS NOT DISTINCT FROM n.archive_id",
|
|
8158
|
+
"si.import_run_id IS NOT NULL"
|
|
8159
|
+
];
|
|
8160
|
+
for (const predicate of predicates.filter((p) => p.path === "import_run_id")) {
|
|
8161
|
+
conditions.push(predicateSql(predicate, (value, op) => {
|
|
8162
|
+
params.push(value);
|
|
8163
|
+
return `si.import_run_id COLLATE "C" ${op} $${idx++}::text COLLATE "C"`;
|
|
8164
|
+
}, "si.import_run_id IS NOT NULL"));
|
|
8165
|
+
}
|
|
8166
|
+
return { conditions, joins: [], params, nextIdx: idx };
|
|
8167
|
+
}
|
|
8168
|
+
function buildMetadataPredicateConditions(options, startIdx) {
|
|
8169
|
+
const predicates = options.metadataPredicates === void 0 ? [] : options.metadataPredicates;
|
|
8170
|
+
validateMetadataPredicates(predicates);
|
|
8171
|
+
const conditions = [];
|
|
8172
|
+
const params = [];
|
|
8173
|
+
const joins = [];
|
|
8174
|
+
let idx = startIdx;
|
|
8175
|
+
if (options.archive_id !== void 0) {
|
|
8176
|
+
conditions.push(`n.archive_id IS NOT DISTINCT FROM $${idx++}::text`);
|
|
8177
|
+
params.push(options.archive_id);
|
|
8178
|
+
}
|
|
8179
|
+
if (options.tenant_id !== void 0) {
|
|
8180
|
+
const source = buildMetadataSourceConditions({ ...options, metadataPredicates: [] }, idx);
|
|
8181
|
+
const native = options.tenant_id === "default" ? " OR NOT EXISTS (SELECT 1 FROM source_identity si WHERE si.note_id = n.id)" : "";
|
|
8182
|
+
conditions.push(`(EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})${native})`);
|
|
8183
|
+
params.push(...source.params);
|
|
8184
|
+
idx = source.nextIdx;
|
|
8185
|
+
}
|
|
8186
|
+
for (const predicate of predicates) {
|
|
8187
|
+
if (predicate.path === "import_run_id") continue;
|
|
8188
|
+
const lhs = `(n.metadata -> '${predicate.path}')`;
|
|
8189
|
+
conditions.push(predicateSql(predicate, (value, op) => {
|
|
8190
|
+
if (value === null) return `jsonb_typeof(${lhs}) = 'null'`;
|
|
8191
|
+
const rhs = `$${idx++}::jsonb`;
|
|
8192
|
+
params.push(JSON.stringify(value));
|
|
8193
|
+
const type = typeof value;
|
|
8194
|
+
if (type === "string") {
|
|
8195
|
+
return `(jsonb_typeof(${lhs}) = 'string'
|
|
8196
|
+
AND public.metadata_search_order_key_v1(${lhs}) IS NULL
|
|
8197
|
+
AND public.metadata_search_text_key_v1(${lhs}) COLLATE "C" ${op} public.metadata_search_text_key_v1(${rhs}) COLLATE "C"
|
|
8198
|
+
AND (${lhs} #>> '{}') COLLATE "C" ${op} (${rhs} #>> '{}') COLLATE "C")`;
|
|
8199
|
+
}
|
|
8200
|
+
return `(jsonb_typeof(${lhs}) = '${type}'
|
|
8201
|
+
AND public.metadata_search_order_key_v1(${lhs}) ${op} public.metadata_search_order_key_v1(${rhs})
|
|
8202
|
+
AND ${lhs} ${op} ${rhs})`;
|
|
8203
|
+
}, `jsonb_typeof(${lhs}) IS NOT NULL`));
|
|
8204
|
+
}
|
|
8205
|
+
const runs = predicates.filter((p) => p.path === "import_run_id");
|
|
8206
|
+
if (runs.length) {
|
|
8207
|
+
const positive = runs.filter((p) => !(p.op === "exists" && p.value === false));
|
|
8208
|
+
for (const [selected, negated] of [[positive, false], [[], true]]) {
|
|
8209
|
+
if (negated ? !runs.some((p) => p.op === "exists" && p.value === false) : !positive.length) continue;
|
|
8210
|
+
const source = buildMetadataSourceConditions({ ...options, metadataPredicates: selected }, idx);
|
|
8211
|
+
conditions.push(`${negated ? "NOT " : ""}EXISTS (SELECT 1 FROM source_identity si WHERE ${source.conditions.join(" AND ")})`);
|
|
8212
|
+
params.push(...source.params);
|
|
8213
|
+
idx = source.nextIdx;
|
|
8214
|
+
}
|
|
8215
|
+
}
|
|
8216
|
+
return { conditions, joins, params, nextIdx: idx };
|
|
8217
|
+
}
|
|
8218
|
+
|
|
8219
|
+
// src/repositories/search-evidence-repository.ts
|
|
8220
|
+
function validateScope(scope) {
|
|
8221
|
+
if (!scope || typeof scope !== "object" || Array.isArray(scope) || ![Object.prototype, null].includes(Object.getPrototypeOf(scope)) || Object.keys(scope).some((key3) => !["tenant_id", "archive_id", "visibility", "metadataPredicates"].includes(key3))) {
|
|
8222
|
+
throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8223
|
+
}
|
|
8224
|
+
for (const key3 of ["tenant_id", "archive_id", "visibility"]) {
|
|
8225
|
+
const value = scope[key3];
|
|
8226
|
+
if (value === void 0 || key3 === "archive_id" && value === null) continue;
|
|
8227
|
+
if (typeof value !== "string" || value.length === 0 || value.includes("\0") || Array.from(value).some((char) => {
|
|
8228
|
+
const code = char.codePointAt(0);
|
|
8229
|
+
return code >= 55296 && code <= 57343;
|
|
8230
|
+
})) throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8231
|
+
}
|
|
8232
|
+
}
|
|
8233
|
+
async function resolveStoredSearchEvidence(db, value, scope = {}) {
|
|
8234
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
8235
|
+
validateScope(scope);
|
|
8236
|
+
const options = { ...scope, tenant_id: scope.tenant_id ?? "default" };
|
|
8237
|
+
const notes = buildNoteConditions(options, 5);
|
|
8238
|
+
const metadata2 = buildMetadataPredicateConditions(options, notes.nextIdx);
|
|
8239
|
+
const params = [
|
|
8240
|
+
locator.note_id,
|
|
8241
|
+
locator.unit.id,
|
|
8242
|
+
locator.unit.index,
|
|
8243
|
+
MAX_EVIDENCE_BYTES,
|
|
8244
|
+
...notes.params,
|
|
8245
|
+
...metadata2.params
|
|
8246
|
+
];
|
|
8247
|
+
const conditions = ["n.id = $1", ...notes.conditions, ...metadata2.conditions];
|
|
8248
|
+
let joins;
|
|
8249
|
+
let content;
|
|
8250
|
+
switch (locator.unit.kind) {
|
|
8251
|
+
case "current":
|
|
8252
|
+
joins = "JOIN note_revised_current c ON c.note_id = n.id";
|
|
8253
|
+
content = "c.content";
|
|
8254
|
+
conditions.push("n.id = $2", "$3::integer = 0");
|
|
8255
|
+
break;
|
|
8256
|
+
case "title":
|
|
8257
|
+
joins = "";
|
|
8258
|
+
content = "n.title";
|
|
8259
|
+
conditions.push("n.id = $2", "$3::integer = 0");
|
|
8260
|
+
break;
|
|
8261
|
+
case "embedding":
|
|
8262
|
+
joins = "JOIN embedding e ON e.note_id = n.id";
|
|
8263
|
+
content = "e.text";
|
|
8264
|
+
conditions.push("e.id = $2", "e.chunk_index = $3");
|
|
8265
|
+
break;
|
|
8266
|
+
case "attachment":
|
|
8267
|
+
joins = "JOIN attachment a ON a.note_id = n.id";
|
|
8268
|
+
content = "a.extracted_text";
|
|
8269
|
+
conditions.push("a.id = $2", "$3::integer = 0", "a.status = 'completed'", "a.deleted_at IS NULL");
|
|
8270
|
+
break;
|
|
8271
|
+
}
|
|
8272
|
+
if (locator.source) {
|
|
8273
|
+
const source = buildMetadataSourceConditions(options, metadata2.nextIdx);
|
|
8274
|
+
let idx = source.nextIdx;
|
|
8275
|
+
conditions.push(`EXISTS (SELECT 1 FROM source_identity si
|
|
8276
|
+
WHERE ${source.conditions.join(" AND ")}
|
|
8277
|
+
AND si.namespace = $${idx++} AND si.external_id_hash = $${idx++}
|
|
8278
|
+
AND si.import_run_id = $${idx++} AND si.source_schema_version = $${idx++})`);
|
|
8279
|
+
params.push(
|
|
8280
|
+
...source.params,
|
|
8281
|
+
locator.source.namespace,
|
|
8282
|
+
locator.source.external_id_hash,
|
|
8283
|
+
locator.source.import_run_id,
|
|
8284
|
+
locator.source.schema_version
|
|
8285
|
+
);
|
|
8286
|
+
}
|
|
8287
|
+
const result = await db.query(
|
|
8288
|
+
`SELECT CASE WHEN octet_length(${content}) <= $4
|
|
8289
|
+
THEN encode(convert_to(${content}, 'UTF8'), 'hex') ELSE NULL END AS content_hex
|
|
8290
|
+
FROM note n ${joins} ${metadata2.joins.join(" ")}
|
|
8291
|
+
WHERE ${conditions.join(" AND ")} LIMIT 1`,
|
|
8292
|
+
params
|
|
8293
|
+
);
|
|
8294
|
+
const row = result.rows[0];
|
|
8295
|
+
return resolveSearchEvidence(locator, row?.content_hex == null ? null : {
|
|
8296
|
+
note_id: locator.note_id,
|
|
8297
|
+
unit: locator.unit,
|
|
8298
|
+
content: new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(hexToBytes(row.content_hex)),
|
|
8299
|
+
...locator.source === void 0 ? {} : { source: locator.source }
|
|
8300
|
+
});
|
|
8301
|
+
}
|
|
8302
|
+
|
|
8303
|
+
// src/repositories/search-evidence-projection.ts
|
|
8304
|
+
init_geometry_buffer();
|
|
8305
|
+
|
|
8306
|
+
// src/search-evidence-set.ts
|
|
8307
|
+
init_geometry_buffer();
|
|
8308
|
+
|
|
8309
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-set.schema.json
|
|
8310
|
+
var evidence_set_schema_default = {
|
|
8311
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
8312
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-set.schema.json",
|
|
8313
|
+
title: "Candidate per-hit search evidence envelope",
|
|
8314
|
+
type: "object",
|
|
8315
|
+
additionalProperties: false,
|
|
8316
|
+
required: ["version", "locators", "omissions"],
|
|
8317
|
+
properties: {
|
|
8318
|
+
version: { const: "1.0.0" },
|
|
8319
|
+
locators: {
|
|
8320
|
+
type: "array",
|
|
8321
|
+
maxItems: 64,
|
|
8322
|
+
uniqueItems: true,
|
|
8323
|
+
items: { $ref: "evidence-locator.schema.json" }
|
|
8324
|
+
},
|
|
8325
|
+
omissions: {
|
|
8326
|
+
type: "array",
|
|
8327
|
+
maxItems: 2,
|
|
8328
|
+
uniqueItems: true,
|
|
8329
|
+
items: { enum: ["unavailable-unit", "locator-limit"] }
|
|
8330
|
+
}
|
|
8331
|
+
},
|
|
8332
|
+
if: { properties: { locators: { type: "array", maxItems: 0 } } },
|
|
8333
|
+
then: { properties: { omissions: { type: "array", minItems: 1 } } }
|
|
8334
|
+
};
|
|
8335
|
+
|
|
8336
|
+
// src/search-evidence-set.ts
|
|
8337
|
+
var MAX_SEARCH_LOCATORS = 64;
|
|
8338
|
+
var EVIDENCE_OMISSIONS = ["unavailable-unit", "locator-limit"];
|
|
8339
|
+
var validate = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addSchema(evidence_locator_schema_default).compile(evidence_set_schema_default);
|
|
8340
|
+
var invalid2 = () => new Error("SEARCH_EVIDENCE_INVALID");
|
|
8341
|
+
var priorities = { embedding: 0, title: 1, current: 2, attachment: 3 };
|
|
8342
|
+
function scalarCompare(left, right) {
|
|
8343
|
+
const a = Array.from(left, (char) => char.codePointAt(0));
|
|
8344
|
+
const b = Array.from(right, (char) => char.codePointAt(0));
|
|
8345
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
8346
|
+
return a.length - b.length;
|
|
8347
|
+
}
|
|
8348
|
+
function key(locator) {
|
|
8349
|
+
return [
|
|
8350
|
+
priorities[locator.unit.kind],
|
|
8351
|
+
locator.unit.id,
|
|
8352
|
+
locator.unit.index,
|
|
8353
|
+
locator.content_digest,
|
|
8354
|
+
locator.span.start,
|
|
8355
|
+
locator.span.end,
|
|
8356
|
+
locator.source ? 1 : 0,
|
|
8357
|
+
locator.source?.namespace ?? "",
|
|
8358
|
+
locator.source?.external_id_hash ?? "",
|
|
8359
|
+
locator.source?.import_run_id ?? "",
|
|
8360
|
+
locator.source?.schema_version ?? ""
|
|
8361
|
+
];
|
|
8362
|
+
}
|
|
8363
|
+
function compareSearchEvidence(left, right) {
|
|
8364
|
+
const a = key(left), b = key(right);
|
|
8365
|
+
for (let i = 0; i < a.length; i++) {
|
|
8366
|
+
const cmp = typeof a[i] === "number" ? a[i] - b[i] : scalarCompare(a[i], b[i]);
|
|
8367
|
+
if (cmp !== 0) return cmp;
|
|
8368
|
+
}
|
|
8369
|
+
return 0;
|
|
8370
|
+
}
|
|
8371
|
+
function parseSearchEvidenceSet(value, noteId) {
|
|
8372
|
+
if (!validate(value)) throw invalid2();
|
|
8373
|
+
const locators = value.locators.map(parseSearchEvidenceLocator);
|
|
8374
|
+
if (locators.some((locator, i) => locator.note_id !== noteId || i > 0 && compareSearchEvidence(locators[i - 1], locator) >= 0)) throw invalid2();
|
|
8375
|
+
if (value.omissions.some((reason, i) => i > 0 && EVIDENCE_OMISSIONS.indexOf(value.omissions[i - 1]) >= EVIDENCE_OMISSIONS.indexOf(reason))) throw invalid2();
|
|
8376
|
+
return Object.freeze({ version: "1.0.0", locators: Object.freeze(locators), omissions: Object.freeze([...value.omissions]) });
|
|
8377
|
+
}
|
|
8378
|
+
function createSearchEvidenceSet(noteId, values, omissions = []) {
|
|
8379
|
+
const parsed = values.map(parseSearchEvidenceLocator);
|
|
8380
|
+
if (parsed.some((locator) => locator.note_id !== noteId) || omissions.some((reason) => !EVIDENCE_OMISSIONS.includes(reason))) throw invalid2();
|
|
8381
|
+
const locators = parsed.sort(compareSearchEvidence).filter((locator, i, all) => i === 0 || compareSearchEvidence(all[i - 1], locator) !== 0);
|
|
8382
|
+
const reasons = new Set(omissions);
|
|
8383
|
+
if (locators.length > MAX_SEARCH_LOCATORS) reasons.add("locator-limit");
|
|
8384
|
+
if (locators.length === 0) reasons.add("unavailable-unit");
|
|
8385
|
+
return parseSearchEvidenceSet({
|
|
8386
|
+
version: "1.0.0",
|
|
8387
|
+
locators: locators.slice(0, MAX_SEARCH_LOCATORS),
|
|
8388
|
+
omissions: EVIDENCE_OMISSIONS.filter((reason) => reasons.has(reason))
|
|
8389
|
+
}, noteId);
|
|
8390
|
+
}
|
|
8391
|
+
function mergeSearchEvidenceSets(noteId, sets) {
|
|
8392
|
+
const checked2 = sets.map((set) => parseSearchEvidenceSet(set, noteId));
|
|
8393
|
+
return createSearchEvidenceSet(noteId, checked2.flatMap((set) => [...set.locators]), checked2.flatMap((set) => [...set.omissions]));
|
|
8394
|
+
}
|
|
8395
|
+
|
|
8396
|
+
// src/repositories/search-evidence-projection.ts
|
|
8397
|
+
function buildSearchEvidenceProjection(options, startIdx, match) {
|
|
8398
|
+
const source = buildMetadataSourceConditions(options, startIdx);
|
|
8399
|
+
const scope = buildMetadataPredicateConditions({ tenant_id: options.tenant_id ?? "default", archive_id: options.archive_id }, source.nextIdx);
|
|
8400
|
+
const units = [];
|
|
8401
|
+
if (match.lexical) {
|
|
8402
|
+
const query = `${match.lexical.fn}('english', $${match.lexical.parameter})`;
|
|
8403
|
+
units.push(`SELECT 1 AS priority, 'title'::text AS kind, n.id AS id, 0 AS index, n.title AS content
|
|
8404
|
+
WHERE to_tsvector('english', n.title) @@ ${query}`);
|
|
8405
|
+
units.push(`SELECT 2, 'current', n.id, 0, c.content
|
|
8406
|
+
WHERE to_tsvector('english', c.content) @@ ${query}`);
|
|
8407
|
+
units.push(`SELECT 3, 'attachment', a.id, 0, a.extracted_text FROM attachment a
|
|
8408
|
+
WHERE a.note_id = n.id AND a.deleted_at IS NULL AND a.status = 'completed'
|
|
8409
|
+
AND to_tsvector('english', a.extracted_text) @@ ${query}`);
|
|
8410
|
+
}
|
|
8411
|
+
if (match.embedding) units.push("SELECT 0, 'embedding'::text, e.id, e.chunk_index, NULLIF(e.text, '')");
|
|
8412
|
+
if (units.length === 0) throw new Error("SEARCH_EVIDENCE_INVALID");
|
|
8413
|
+
return {
|
|
8414
|
+
params: [...source.params, ...scope.params],
|
|
8415
|
+
nextIdx: scope.nextIdx,
|
|
8416
|
+
sql: `(WITH units(priority, kind, id, index, content) AS (${units.join(" UNION ALL ")}),
|
|
8417
|
+
sources AS (
|
|
8418
|
+
SELECT DISTINCT si.namespace COLLATE "C" AS namespace, si.external_id_hash COLLATE "C" AS external_id_hash,
|
|
8419
|
+
si.import_run_id COLLATE "C" AS import_run_id, si.source_schema_version COLLATE "C" AS source_schema_version
|
|
8420
|
+
FROM source_identity si WHERE ${source.conditions.join(" AND ")}
|
|
8421
|
+
ORDER BY si.namespace COLLATE "C", si.external_id_hash COLLATE "C",
|
|
8422
|
+
si.import_run_id COLLATE "C", si.source_schema_version COLLATE "C"
|
|
8423
|
+
LIMIT ${MAX_SEARCH_LOCATORS + 1}
|
|
8424
|
+
), candidates AS MATERIALIZED (
|
|
8425
|
+
SELECT u.*, s.namespace, s.external_id_hash, s.import_run_id, s.source_schema_version
|
|
8426
|
+
FROM units u LEFT JOIN sources s ON true
|
|
8427
|
+
ORDER BY u.priority, u.id COLLATE "C", u.index, s.namespace COLLATE "C",
|
|
8428
|
+
s.external_id_hash COLLATE "C", s.import_run_id COLLATE "C", s.source_schema_version COLLATE "C"
|
|
8429
|
+
LIMIT ${MAX_SEARCH_LOCATORS + 1}
|
|
8430
|
+
), bound AS (
|
|
8431
|
+
SELECT CASE WHEN ${scope.conditions.join(" AND ")}
|
|
8432
|
+
AND char_length(n.id) BETWEEN 1 AND 200 AND char_length(id) BETWEEN 1 AND 200
|
|
8433
|
+
AND index BETWEEN 0 AND 2147483647 AND octet_length(content) <= ${MAX_EVIDENCE_BYTES}
|
|
8434
|
+
AND (namespace IS NULL OR (char_length(namespace) BETWEEN 1 AND 200
|
|
8435
|
+
AND external_id_hash ~ '^sha256:[a-f0-9]{64}$'
|
|
8436
|
+
AND char_length(import_run_id) BETWEEN 1 AND 200
|
|
8437
|
+
AND char_length(source_schema_version) BETWEEN 1 AND 200))
|
|
8438
|
+
THEN jsonb_build_object('version', '1.0.0', 'note_id', n.id,
|
|
8439
|
+
'unit', jsonb_build_object('kind', kind, 'id', id, 'index', index),
|
|
8440
|
+
'content_digest', 'sha256:' || encode(sha256(convert_to(content, 'UTF8')), 'hex'),
|
|
8441
|
+
'span', jsonb_build_object('unit', 'utf8-bytes', 'start', 0, 'end', octet_length(content)))
|
|
8442
|
+
|| CASE WHEN namespace IS NULL THEN '{}'::jsonb ELSE jsonb_build_object('source',
|
|
8443
|
+
jsonb_build_object('namespace', namespace, 'external_id_hash', external_id_hash,
|
|
8444
|
+
'import_run_id', import_run_id, 'schema_version', source_schema_version)) END
|
|
8445
|
+
ELSE NULL END AS locator FROM candidates
|
|
8446
|
+
) SELECT jsonb_build_object('locators', coalesce(jsonb_agg(locator), '[]'::jsonb),
|
|
8447
|
+
'limited', count(*) > ${MAX_SEARCH_LOCATORS}) FROM bound)`
|
|
8448
|
+
};
|
|
8449
|
+
}
|
|
8450
|
+
function projectedSearchEvidence(noteId, value) {
|
|
8451
|
+
return createSearchEvidenceSet(noteId, value.locators.filter((locator) => locator !== null), [
|
|
8452
|
+
...value.locators.some((locator) => locator === null) ? ["unavailable-unit"] : [],
|
|
8453
|
+
...value.limited ? ["locator-limit"] : []
|
|
8454
|
+
]);
|
|
8455
|
+
}
|
|
8456
|
+
|
|
7078
8457
|
// src/repositories/embedding-sets-repository.ts
|
|
7079
8458
|
init_geometry_buffer();
|
|
7080
8459
|
var ATTACHMENT_TEXT_JOIN = `
|
|
@@ -7654,91 +9033,6 @@ var EmbeddingSetsRepository = class {
|
|
|
7654
9033
|
}
|
|
7655
9034
|
};
|
|
7656
9035
|
|
|
7657
|
-
// src/repositories/metadata-predicates.ts
|
|
7658
|
-
init_geometry_buffer();
|
|
7659
|
-
var REGISTERED_METADATA_PATHS = [
|
|
7660
|
-
"provider",
|
|
7661
|
-
"model",
|
|
7662
|
-
"role",
|
|
7663
|
-
"event_kind",
|
|
7664
|
-
"sensitivity",
|
|
7665
|
-
"import_run_id"
|
|
7666
|
-
];
|
|
7667
|
-
var REGISTERED_SET = new Set(REGISTERED_METADATA_PATHS);
|
|
7668
|
-
var MAX_PREDICATES = 8;
|
|
7669
|
-
var MAX_IN_VALUES = 32;
|
|
7670
|
-
var MAX_VALUE_LENGTH = 256;
|
|
7671
|
-
function assertRegisteredPath(path) {
|
|
7672
|
-
if (!REGISTERED_SET.has(path) || path.includes(".") || path.includes("/")) {
|
|
7673
|
-
throw new Error(`Unsupported metadata predicate path: ${path}`);
|
|
7674
|
-
}
|
|
7675
|
-
}
|
|
7676
|
-
function assertBoundedValue(value) {
|
|
7677
|
-
if (typeof value === "string" && value.length > MAX_VALUE_LENGTH) {
|
|
7678
|
-
throw new Error("Metadata predicate value exceeds the 256 character bound");
|
|
7679
|
-
}
|
|
7680
|
-
}
|
|
7681
|
-
function jsonAccessor(path) {
|
|
7682
|
-
if (path === "import_run_id") return "si.import_run_id";
|
|
7683
|
-
return `n.metadata ->> '${path}'`;
|
|
7684
|
-
}
|
|
7685
|
-
function buildMetadataPredicateConditions(options, startIdx) {
|
|
7686
|
-
const predicates = options.metadataPredicates ?? [];
|
|
7687
|
-
if (predicates.length > MAX_PREDICATES) {
|
|
7688
|
-
throw new Error(`Metadata predicate count exceeds the ${MAX_PREDICATES} predicate bound`);
|
|
7689
|
-
}
|
|
7690
|
-
const conditions = [];
|
|
7691
|
-
const params = [];
|
|
7692
|
-
const joins = [];
|
|
7693
|
-
let idx = startIdx;
|
|
7694
|
-
let needsSourceJoin = options.tenant_id !== void 0 || options.archive_id !== void 0;
|
|
7695
|
-
if (options.tenant_id !== void 0) {
|
|
7696
|
-
conditions.push(`COALESCE(si.tenant_id, 'default') = $${idx++}`);
|
|
7697
|
-
params.push(options.tenant_id);
|
|
7698
|
-
}
|
|
7699
|
-
if (options.archive_id !== void 0) {
|
|
7700
|
-
conditions.push(`si.archive_id IS NOT DISTINCT FROM $${idx++}`);
|
|
7701
|
-
params.push(options.archive_id);
|
|
7702
|
-
}
|
|
7703
|
-
for (const predicate of predicates) {
|
|
7704
|
-
assertRegisteredPath(predicate.path);
|
|
7705
|
-
const lhs = jsonAccessor(predicate.path);
|
|
7706
|
-
if (predicate.path === "import_run_id") needsSourceJoin = true;
|
|
7707
|
-
if (predicate.op === "eq") {
|
|
7708
|
-
assertBoundedValue(predicate.value);
|
|
7709
|
-
conditions.push(`${lhs} IS NOT DISTINCT FROM $${idx++}`);
|
|
7710
|
-
params.push(predicate.value == null ? null : String(predicate.value));
|
|
7711
|
-
} else if (predicate.op === "in") {
|
|
7712
|
-
if (predicate.value.length > MAX_IN_VALUES) {
|
|
7713
|
-
throw new Error(`Metadata predicate membership exceeds the ${MAX_IN_VALUES} value bound`);
|
|
7714
|
-
}
|
|
7715
|
-
for (const value of predicate.value) assertBoundedValue(value);
|
|
7716
|
-
conditions.push(`${lhs} = ANY($${idx++})`);
|
|
7717
|
-
params.push(predicate.value.map((value) => value == null ? null : String(value)));
|
|
7718
|
-
} else if (predicate.op === "range") {
|
|
7719
|
-
if (predicate.gte === void 0 && predicate.lte === void 0) {
|
|
7720
|
-
throw new Error("Metadata range predicate requires gte or lte");
|
|
7721
|
-
}
|
|
7722
|
-
if (predicate.gte !== void 0) {
|
|
7723
|
-
assertBoundedValue(predicate.gte);
|
|
7724
|
-
conditions.push(`${lhs} >= $${idx++}`);
|
|
7725
|
-
params.push(String(predicate.gte));
|
|
7726
|
-
}
|
|
7727
|
-
if (predicate.lte !== void 0) {
|
|
7728
|
-
assertBoundedValue(predicate.lte);
|
|
7729
|
-
conditions.push(`${lhs} <= $${idx++}`);
|
|
7730
|
-
params.push(String(predicate.lte));
|
|
7731
|
-
}
|
|
7732
|
-
} else {
|
|
7733
|
-
conditions.push(predicate.value === false ? `${lhs} IS NULL` : `${lhs} IS NOT NULL`);
|
|
7734
|
-
}
|
|
7735
|
-
}
|
|
7736
|
-
if (needsSourceJoin) {
|
|
7737
|
-
joins.push("LEFT JOIN source_identity si ON si.note_id = n.id");
|
|
7738
|
-
}
|
|
7739
|
-
return { conditions, joins, params, nextIdx: idx };
|
|
7740
|
-
}
|
|
7741
|
-
|
|
7742
9036
|
// src/repositories/search-repository.ts
|
|
7743
9037
|
var ATTACHMENT_TEXT_JOIN2 = `
|
|
7744
9038
|
LEFT JOIN (
|
|
@@ -7760,6 +9054,10 @@ var SearchRepository = class {
|
|
|
7760
9054
|
this.db = db;
|
|
7761
9055
|
this.semanticAvailable = semanticAvailable;
|
|
7762
9056
|
}
|
|
9057
|
+
/** Candidate citation resolution with fresh local scope and content checks. */
|
|
9058
|
+
async resolveEvidence(locator, scope = {}) {
|
|
9059
|
+
return resolveStoredSearchEvidence(this.db, locator, scope);
|
|
9060
|
+
}
|
|
7763
9061
|
tsqueryFn(query) {
|
|
7764
9062
|
return query.includes('"') ? "phraseto_tsquery" : "plainto_tsquery";
|
|
7765
9063
|
}
|
|
@@ -7769,7 +9067,7 @@ var SearchRepository = class {
|
|
|
7769
9067
|
const setFilter = embeddingSetId ? " AND embedding_set_id = $2" : "";
|
|
7770
9068
|
if (embeddingSetId) params.push(embeddingSetId);
|
|
7771
9069
|
const result = await this.db.query(
|
|
7772
|
-
"SELECT note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
|
|
9070
|
+
"SELECT to_jsonb(note_id) AS note_id FROM embedding WHERE vector IS NOT NULL AND note_id = ANY($1)" + setFilter,
|
|
7773
9071
|
params
|
|
7774
9072
|
);
|
|
7775
9073
|
return new Set(result.rows.map((r) => r.note_id));
|
|
@@ -7813,15 +9111,17 @@ var SearchRepository = class {
|
|
|
7813
9111
|
attachEmbeddingStatus(results, embeddingSet) {
|
|
7814
9112
|
return results.map((r) => ({ ...r, has_embedding: embeddingSet.has(r.id) }));
|
|
7815
9113
|
}
|
|
7816
|
-
async fetchLocatorMap(noteIds,
|
|
9114
|
+
async fetchLocatorMap(noteIds, options) {
|
|
7817
9115
|
const locators = /* @__PURE__ */ new Map();
|
|
7818
9116
|
if (noteIds.length === 0) return locators;
|
|
9117
|
+
const metadataPaths = this.metadataPaths(options);
|
|
9118
|
+
const source = buildMetadataSourceConditions(options, 2);
|
|
7819
9119
|
const result = await this.db.query(
|
|
7820
|
-
`SELECT note_id, namespace, external_id_hash, import_run_id, source_schema_version
|
|
7821
|
-
FROM source_identity
|
|
7822
|
-
WHERE
|
|
7823
|
-
ORDER BY created_at ASC`,
|
|
7824
|
-
[noteIds]
|
|
9120
|
+
`SELECT to_jsonb(si.note_id) AS note_id, si.namespace, si.external_id_hash, si.import_run_id, si.source_schema_version
|
|
9121
|
+
FROM source_identity si JOIN note n ON n.id = si.note_id
|
|
9122
|
+
WHERE n.id = ANY($1) AND ${source.conditions.join(" AND ")}
|
|
9123
|
+
ORDER BY si.created_at ASC, si.id ASC`,
|
|
9124
|
+
[noteIds, ...source.params]
|
|
7825
9125
|
);
|
|
7826
9126
|
for (const row of result.rows) {
|
|
7827
9127
|
const existing = locators.get(row.note_id) ?? [];
|
|
@@ -7849,6 +9149,7 @@ var SearchRepository = class {
|
|
|
7849
9149
|
return [...new Set((options.metadataPredicates ?? []).map((predicate) => predicate.path))];
|
|
7850
9150
|
}
|
|
7851
9151
|
async search(query, options = {}, queryEmbedding) {
|
|
9152
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
7852
9153
|
const { limit = 20, offset = 0 } = options;
|
|
7853
9154
|
const mode = options.mode ?? "auto";
|
|
7854
9155
|
if (mode === "text") {
|
|
@@ -7894,9 +9195,11 @@ var SearchRepository = class {
|
|
|
7894
9195
|
allParams
|
|
7895
9196
|
);
|
|
7896
9197
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
7897
|
-
const
|
|
9198
|
+
const evidence = buildSearchEvidenceProjection(options, paramIdx, { lexical: { fn: tsqFn, parameter: 1 } });
|
|
9199
|
+
paramIdx = evidence.nextIdx;
|
|
9200
|
+
const searchParams = [...allParams, ...evidence.params, limit, offset];
|
|
7898
9201
|
const result = await this.db.query(
|
|
7899
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9202
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at, ${evidence.sql} AS evidence_projection,
|
|
7900
9203
|
ts_rank(
|
|
7901
9204
|
setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
|
|
7902
9205
|
${tsqFn}('english', $1)
|
|
@@ -7924,7 +9227,7 @@ var SearchRepository = class {
|
|
|
7924
9227
|
let facets;
|
|
7925
9228
|
if (options.include_facets) {
|
|
7926
9229
|
const idsResult = await this.db.query(
|
|
7927
|
-
`SELECT n.id FROM note n
|
|
9230
|
+
`SELECT to_jsonb(n.id) AS id FROM note n
|
|
7928
9231
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
7929
9232
|
${metadata2.joins.join("\n")}
|
|
7930
9233
|
${ATTACHMENT_TEXT_JOIN2}
|
|
@@ -7933,7 +9236,7 @@ var SearchRepository = class {
|
|
|
7933
9236
|
);
|
|
7934
9237
|
facets = await this.fetchFacets(idsResult.rows.map((r) => r.id));
|
|
7935
9238
|
}
|
|
7936
|
-
const locatorMap = await this.fetchLocatorMap(resultIds,
|
|
9239
|
+
const locatorMap = await this.fetchLocatorMap(resultIds, options);
|
|
7937
9240
|
const baseResults = result.rows.map((r) => ({
|
|
7938
9241
|
id: r.id,
|
|
7939
9242
|
title: r.title,
|
|
@@ -7942,7 +9245,8 @@ var SearchRepository = class {
|
|
|
7942
9245
|
created_at: r.created_at,
|
|
7943
9246
|
updated_at: r.updated_at,
|
|
7944
9247
|
tags: tagMap.get(r.id) ?? [],
|
|
7945
|
-
locators: locatorMap.get(r.id) ?? []
|
|
9248
|
+
locators: locatorMap.get(r.id) ?? [],
|
|
9249
|
+
evidence: projectedSearchEvidence(r.id, r.evidence_projection)
|
|
7946
9250
|
}));
|
|
7947
9251
|
return {
|
|
7948
9252
|
results: this.attachEmbeddingStatus(baseResults, embeddingSet),
|
|
@@ -7956,6 +9260,7 @@ var SearchRepository = class {
|
|
|
7956
9260
|
};
|
|
7957
9261
|
}
|
|
7958
9262
|
async semanticSearch(queryEmbedding, options = {}) {
|
|
9263
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
7959
9264
|
const { limit = 20, offset = 0 } = options;
|
|
7960
9265
|
const vector = vectorColumn(queryEmbedding);
|
|
7961
9266
|
const vectorStr = `[${queryEmbedding.join(",")}]`;
|
|
@@ -7977,11 +9282,14 @@ var SearchRepository = class {
|
|
|
7977
9282
|
params
|
|
7978
9283
|
);
|
|
7979
9284
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
9285
|
+
const evidence = buildSearchEvidenceProjection(options, paramIdx, { embedding: true });
|
|
9286
|
+
paramIdx = evidence.nextIdx;
|
|
7980
9287
|
const vecIdx = paramIdx++;
|
|
7981
9288
|
const limIdx = paramIdx++;
|
|
7982
9289
|
const offIdx = paramIdx++;
|
|
7983
9290
|
const result = await this.db.query(
|
|
7984
|
-
`SELECT * FROM (SELECT DISTINCT ON (n.id) n.id, n.title, n.created_at, n.updated_at,
|
|
9291
|
+
`SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
9292
|
+
${evidence.sql} AS evidence_projection,
|
|
7985
9293
|
(${vector} <=> $${vecIdx}::vector) as distance,
|
|
7986
9294
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
7987
9295
|
FROM embedding e
|
|
@@ -7993,11 +9301,11 @@ var SearchRepository = class {
|
|
|
7993
9301
|
ORDER BY n.id, ${vector} <=> $${vecIdx}::vector ASC, e.id) AS best_chunks
|
|
7994
9302
|
ORDER BY distance ASC, id
|
|
7995
9303
|
LIMIT $${limIdx} OFFSET $${offIdx}`,
|
|
7996
|
-
[...params, vectorStr, limit, offset]
|
|
9304
|
+
[...params, ...evidence.params, vectorStr, limit, offset]
|
|
7997
9305
|
);
|
|
7998
9306
|
const tagMap = await this.fetchTagMap(result.rows.map((r) => r.id));
|
|
7999
9307
|
const facets = options.include_facets ? await this.fetchFacets((await this.db.query(
|
|
8000
|
-
`SELECT n.id
|
|
9308
|
+
`SELECT to_jsonb(n.id) AS id
|
|
8001
9309
|
FROM embedding e
|
|
8002
9310
|
JOIN note n ON n.id = e.note_id
|
|
8003
9311
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8005,7 +9313,7 @@ var SearchRepository = class {
|
|
|
8005
9313
|
WHERE ${where}`,
|
|
8006
9314
|
params
|
|
8007
9315
|
)).rows.map((r) => r.id)) : void 0;
|
|
8008
|
-
const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id),
|
|
9316
|
+
const locatorMap = await this.fetchLocatorMap(result.rows.map((r) => r.id), options);
|
|
8009
9317
|
return {
|
|
8010
9318
|
results: result.rows.map((r) => ({
|
|
8011
9319
|
id: r.id,
|
|
@@ -8016,7 +9324,8 @@ var SearchRepository = class {
|
|
|
8016
9324
|
updated_at: r.updated_at,
|
|
8017
9325
|
tags: tagMap.get(r.id) ?? [],
|
|
8018
9326
|
has_embedding: true,
|
|
8019
|
-
locators: locatorMap.get(r.id) ?? []
|
|
9327
|
+
locators: locatorMap.get(r.id) ?? [],
|
|
9328
|
+
evidence: projectedSearchEvidence(r.id, r.evidence_projection)
|
|
8020
9329
|
})),
|
|
8021
9330
|
total,
|
|
8022
9331
|
query: "",
|
|
@@ -8028,6 +9337,7 @@ var SearchRepository = class {
|
|
|
8028
9337
|
};
|
|
8029
9338
|
}
|
|
8030
9339
|
async hybridSearch(query, queryEmbedding, options = {}) {
|
|
9340
|
+
validateMetadataPredicates(options.metadataPredicates === void 0 ? [] : options.metadataPredicates);
|
|
8031
9341
|
const { limit = 20, offset = 0 } = options;
|
|
8032
9342
|
const vectorStr = `[${queryEmbedding.join(",")}]`;
|
|
8033
9343
|
const k = 60;
|
|
@@ -8042,11 +9352,12 @@ var SearchRepository = class {
|
|
|
8042
9352
|
${COMBINED_TEXT_VECTOR_SQL2} @@ ${tsqFn}('english', $1))`
|
|
8043
9353
|
];
|
|
8044
9354
|
textCond.params.push(...textMeta.params);
|
|
8045
|
-
this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
|
|
9355
|
+
const textNextIdx = this.scopeToResolvedEmbeddingSet(textConditions, textCond.params, textMeta.nextIdx, resolvedEmbeddingSet);
|
|
8046
9356
|
const textWhere = textConditions.join(" AND ");
|
|
8047
|
-
const
|
|
9357
|
+
const textEvidence = buildSearchEvidenceProjection(options, textNextIdx, { lexical: { fn: tsqFn, parameter: 1 } });
|
|
9358
|
+
const textParams = [query, ...textCond.params, ...textEvidence.params];
|
|
8048
9359
|
const textResult = await this.db.query(
|
|
8049
|
-
`SELECT n.id,
|
|
9360
|
+
`SELECT to_jsonb(n.id) AS id, ${textEvidence.sql} AS evidence_projection,
|
|
8050
9361
|
ts_rank(
|
|
8051
9362
|
setweight(n.tsv, 'A') || setweight(${COMBINED_TEXT_VECTOR_SQL2}, 'B'),
|
|
8052
9363
|
${tsqFn}('english', $1)
|
|
@@ -8068,9 +9379,11 @@ var SearchRepository = class {
|
|
|
8068
9379
|
const vector = vectorColumn(queryEmbedding);
|
|
8069
9380
|
vecCond.conditions.push(`vector_dims(e.vector) = ${queryEmbedding.length}`);
|
|
8070
9381
|
const vecWhere = vecCond.conditions.join(" AND ");
|
|
8071
|
-
const
|
|
9382
|
+
const vectorEvidence = buildSearchEvidenceProjection(options, vecCond.nextIdx, { embedding: true });
|
|
9383
|
+
const vecVecIdx = vectorEvidence.nextIdx;
|
|
8072
9384
|
const vectorResult = await this.db.query(
|
|
8073
|
-
`SELECT * FROM (SELECT DISTINCT ON (n.id) n.id,
|
|
9385
|
+
`SELECT * FROM (SELECT DISTINCT ON (n.id) to_jsonb(n.id) AS id, ${vectorEvidence.sql} AS evidence_projection,
|
|
9386
|
+
(${vector} <=> $${vecVecIdx}::vector) as distance
|
|
8074
9387
|
FROM embedding e
|
|
8075
9388
|
JOIN note n ON n.id = e.note_id
|
|
8076
9389
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8079,9 +9392,15 @@ var SearchRepository = class {
|
|
|
8079
9392
|
ORDER BY n.id, ${vector} <=> $${vecVecIdx}::vector ASC, e.id) AS best_chunks
|
|
8080
9393
|
ORDER BY distance ASC, id
|
|
8081
9394
|
LIMIT 100`,
|
|
8082
|
-
[...vecCond.params, vectorStr]
|
|
9395
|
+
[...vecCond.params, ...vectorEvidence.params, vectorStr]
|
|
8083
9396
|
);
|
|
8084
9397
|
const rrfScores = /* @__PURE__ */ new Map();
|
|
9398
|
+
const evidenceMap = /* @__PURE__ */ new Map();
|
|
9399
|
+
for (const row of [...textResult.rows, ...vectorResult.rows]) {
|
|
9400
|
+
const existing = evidenceMap.get(row.id) ?? [];
|
|
9401
|
+
existing.push(projectedSearchEvidence(row.id, row.evidence_projection));
|
|
9402
|
+
evidenceMap.set(row.id, existing);
|
|
9403
|
+
}
|
|
8085
9404
|
textResult.rows.forEach((row, idx) => {
|
|
8086
9405
|
rrfScores.set(row.id, (rrfScores.get(row.id) ?? 0) + 1 / (k + idx + 1));
|
|
8087
9406
|
});
|
|
@@ -8094,21 +9413,24 @@ var SearchRepository = class {
|
|
|
8094
9413
|
if (pageIds.length === 0) {
|
|
8095
9414
|
return { results: [], total, query, mode: "hybrid", semantic_available: this.semanticAvailable, limit, offset };
|
|
8096
9415
|
}
|
|
9416
|
+
const displayConditions = buildNoteConditions(options, 2);
|
|
9417
|
+
const displayMetadata = buildMetadataPredicateConditions(options, displayConditions.nextIdx);
|
|
8097
9418
|
const noteResult = await this.db.query(
|
|
8098
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9419
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
8099
9420
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
8100
9421
|
FROM note n
|
|
8101
9422
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
8102
9423
|
${ATTACHMENT_TEXT_JOIN2}
|
|
8103
|
-
|
|
8104
|
-
|
|
9424
|
+
${displayMetadata.joins.join("\n")}
|
|
9425
|
+
WHERE n.id = ANY($1) AND ${[...displayConditions.conditions, ...displayMetadata.conditions].join(" AND ")}`,
|
|
9426
|
+
[pageIds, ...displayConditions.params, ...displayMetadata.params]
|
|
8105
9427
|
);
|
|
8106
9428
|
const noteMap = new Map(noteResult.rows.map((r) => [r.id, r]));
|
|
8107
9429
|
const [tagMap, embeddingSet] = await Promise.all([
|
|
8108
9430
|
this.fetchTagMap(pageIds),
|
|
8109
9431
|
this.fetchEmbeddingStatus(pageIds, resolvedEmbeddingSet, options.embeddingSetId)
|
|
8110
9432
|
]);
|
|
8111
|
-
const locatorMap = await this.fetchLocatorMap(pageIds,
|
|
9433
|
+
const locatorMap = await this.fetchLocatorMap(pageIds, options);
|
|
8112
9434
|
const facets = options.include_facets ? await this.fetchFacets(sortedIds) : void 0;
|
|
8113
9435
|
return {
|
|
8114
9436
|
results: pageIds.map((id) => {
|
|
@@ -8123,7 +9445,8 @@ var SearchRepository = class {
|
|
|
8123
9445
|
updated_at: r.updated_at,
|
|
8124
9446
|
tags: tagMap.get(id) ?? [],
|
|
8125
9447
|
has_embedding: embeddingSet.has(id),
|
|
8126
|
-
locators: locatorMap.get(id) ?? []
|
|
9448
|
+
locators: locatorMap.get(id) ?? [],
|
|
9449
|
+
evidence: mergeSearchEvidenceSets(id, evidenceMap.get(id) ?? [])
|
|
8127
9450
|
};
|
|
8128
9451
|
}).filter((r) => r !== null),
|
|
8129
9452
|
total,
|
|
@@ -8155,7 +9478,7 @@ var SearchRepository = class {
|
|
|
8155
9478
|
const total = parseInt(countResult.rows[0].count, 10);
|
|
8156
9479
|
const listParams = [...params, limit, offset];
|
|
8157
9480
|
const result = await this.db.query(
|
|
8158
|
-
`SELECT n.id, n.title, n.created_at, n.updated_at,
|
|
9481
|
+
`SELECT to_jsonb(n.id) AS id, n.title, n.created_at, n.updated_at,
|
|
8159
9482
|
LEFT(${COMBINED_TEXT_SQL}, 200) as snippet
|
|
8160
9483
|
FROM note n
|
|
8161
9484
|
LEFT JOIN note_revised_current c ON c.note_id = n.id
|
|
@@ -8168,7 +9491,7 @@ var SearchRepository = class {
|
|
|
8168
9491
|
);
|
|
8169
9492
|
const resultIds = result.rows.map((r) => r.id);
|
|
8170
9493
|
const embeddingSet = await this.fetchEmbeddingStatus(resultIds, resolvedEmbeddingSet, options.embeddingSetId);
|
|
8171
|
-
const locatorMap = await this.fetchLocatorMap(resultIds,
|
|
9494
|
+
const locatorMap = await this.fetchLocatorMap(resultIds, options);
|
|
8172
9495
|
return {
|
|
8173
9496
|
results: result.rows.map((r) => ({
|
|
8174
9497
|
id: r.id,
|
|
@@ -8213,7 +9536,7 @@ var SearchRepository = class {
|
|
|
8213
9536
|
const tagMap = /* @__PURE__ */ new Map();
|
|
8214
9537
|
if (noteIds.length === 0) return tagMap;
|
|
8215
9538
|
const tagsResult = await this.db.query(
|
|
8216
|
-
`SELECT note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
|
|
9539
|
+
`SELECT to_jsonb(note_id) AS note_id, tag FROM note_tag WHERE note_id = ANY($1) ORDER BY tag`,
|
|
8217
9540
|
[noteIds]
|
|
8218
9541
|
);
|
|
8219
9542
|
for (const row of tagsResult.rows) {
|
|
@@ -8457,7 +9780,7 @@ init_geometry_buffer();
|
|
|
8457
9780
|
// src/shard/full-v1-references.ts
|
|
8458
9781
|
init_geometry_buffer();
|
|
8459
9782
|
var uuid2 = (value) => typeof value === "string" ? value.toLowerCase() : value;
|
|
8460
|
-
var
|
|
9783
|
+
var key2 = (...values) => JSON.stringify(values);
|
|
8461
9784
|
var present = (value) => value !== null && value !== void 0;
|
|
8462
9785
|
function fullV1ReferenceErrors(records) {
|
|
8463
9786
|
const errors = [];
|
|
@@ -8515,7 +9838,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8515
9838
|
const id = uuid2(attachment.id);
|
|
8516
9839
|
check(!attachmentIds.has(id), "notes", index, "duplicate attachment identity");
|
|
8517
9840
|
attachmentIds.add(id);
|
|
8518
|
-
const declaration =
|
|
9841
|
+
const declaration = key2(attachment.bytes, attachment.mime);
|
|
8519
9842
|
check(
|
|
8520
9843
|
!digests.has(attachment.checksum) || digests.get(attachment.checksum) === declaration,
|
|
8521
9844
|
"notes",
|
|
@@ -8541,7 +9864,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8541
9864
|
}
|
|
8542
9865
|
});
|
|
8543
9866
|
ids2("note_original_history");
|
|
8544
|
-
unique2("note_original_history", (row) =>
|
|
9867
|
+
unique2("note_original_history", (row) => key2(uuid2(row.note_id), row.version_number));
|
|
8545
9868
|
rows("note_original_history").forEach((row, index) => {
|
|
8546
9869
|
ref(row, "note_id", notes, "note_original_history", index);
|
|
8547
9870
|
const current = originals.get(uuid2(row.note_id));
|
|
@@ -8553,7 +9876,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8553
9876
|
);
|
|
8554
9877
|
});
|
|
8555
9878
|
const revisionIds = ids2("note_revisions");
|
|
8556
|
-
unique2("note_revisions", (row) =>
|
|
9879
|
+
unique2("note_revisions", (row) => key2(uuid2(row.note_id), row.revision_number));
|
|
8557
9880
|
const revisions = new Map(rows("note_revisions").map((row) => [uuid2(row.id), row]));
|
|
8558
9881
|
rows("note_revisions").forEach((row, index) => {
|
|
8559
9882
|
ref(row, "note_id", notes, "note_revisions", index);
|
|
@@ -8608,7 +9931,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8608
9931
|
ref(row, "named_location_id", namedLocations, "provenance_locations", index, true);
|
|
8609
9932
|
});
|
|
8610
9933
|
const devices = ids2("provenance_devices");
|
|
8611
|
-
unique2("provenance_devices", (row) =>
|
|
9934
|
+
unique2("provenance_devices", (row) => key2(row.device_make, row.device_model, uuid2(row.owner_id)));
|
|
8612
9935
|
ids2("provenance_records");
|
|
8613
9936
|
unique2("provenance_records", (row) => uuid2(row.note_id));
|
|
8614
9937
|
rows("provenance_records").forEach((row, index) => {
|
|
@@ -8640,13 +9963,13 @@ function fullV1ReferenceErrors(records) {
|
|
|
8640
9963
|
const config = configRows.get(uuid2(row.embedding_config_id));
|
|
8641
9964
|
if (config) dimensions.set(uuid2(row.id), Number(row.truncate_dim ?? config.dimension));
|
|
8642
9965
|
});
|
|
8643
|
-
unique2("embedding_set_members", (row) =>
|
|
9966
|
+
unique2("embedding_set_members", (row) => key2(uuid2(row.embedding_set_id), uuid2(row.note_id)));
|
|
8644
9967
|
rows("embedding_set_members").forEach((row, index) => {
|
|
8645
9968
|
ref(row, "embedding_set_id", sets, "embedding_set_members", index);
|
|
8646
9969
|
ref(row, "note_id", notes, "embedding_set_members", index);
|
|
8647
9970
|
});
|
|
8648
9971
|
ids2("embeddings");
|
|
8649
|
-
unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ?
|
|
9972
|
+
unique2("embeddings", (row) => present(row.note_id) && present(row.embedding_set_id) ? key2(uuid2(row.note_id), uuid2(row.embedding_set_id), row.chunk_index) : null);
|
|
8650
9973
|
rows("embeddings").forEach((row, index) => {
|
|
8651
9974
|
ref(row, "note_id", notes, "embeddings", index, true);
|
|
8652
9975
|
ref(row, "embedding_set_id", sets, "embeddings", index, true);
|
|
@@ -8664,34 +9987,34 @@ function fullV1ReferenceErrors(records) {
|
|
|
8664
9987
|
unique2("skos_schemes", (row) => row.uri);
|
|
8665
9988
|
const concepts = ids2("skos_concepts");
|
|
8666
9989
|
unique2("skos_concepts", (row) => row.uri);
|
|
8667
|
-
unique2("skos_concepts", (row) => present(row.notation) ?
|
|
9990
|
+
unique2("skos_concepts", (row) => present(row.notation) ? key2(uuid2(row.primary_scheme_id), row.notation) : null);
|
|
8668
9991
|
rows("skos_concepts").forEach((row, index) => {
|
|
8669
9992
|
ref(row, "primary_scheme_id", schemes, "skos_concepts", index);
|
|
8670
9993
|
ref(row, "replaced_by_id", concepts, "skos_concepts", index, true);
|
|
8671
9994
|
check(uuid2(row.replaced_by_id) !== uuid2(row.id), "skos_concepts", index, "concept replaces itself");
|
|
8672
9995
|
});
|
|
8673
9996
|
ids2("skos_labels");
|
|
8674
|
-
unique2("skos_labels", (row) =>
|
|
8675
|
-
unique2("skos_labels", (row) => row.label_type === "pref_label" ?
|
|
9997
|
+
unique2("skos_labels", (row) => key2(uuid2(row.concept_id), row.label_type, row.language, row.value));
|
|
9998
|
+
unique2("skos_labels", (row) => row.label_type === "pref_label" ? key2(uuid2(row.concept_id), row.language) : null);
|
|
8676
9999
|
rows("skos_labels").forEach((row, index) => ref(row, "concept_id", concepts, "skos_labels", index));
|
|
8677
10000
|
ids2("skos_notes");
|
|
8678
10001
|
rows("skos_notes").forEach((row, index) => ref(row, "concept_id", concepts, "skos_notes", index));
|
|
8679
10002
|
ids2("skos_relations");
|
|
8680
|
-
unique2("skos_relations", (row) =>
|
|
10003
|
+
unique2("skos_relations", (row) => key2(uuid2(row.subject_id), uuid2(row.object_id), row.relation_type));
|
|
8681
10004
|
rows("skos_relations").forEach((row, index) => {
|
|
8682
10005
|
ref(row, "subject_id", concepts, "skos_relations", index);
|
|
8683
10006
|
ref(row, "object_id", concepts, "skos_relations", index);
|
|
8684
10007
|
check(uuid2(row.subject_id) !== uuid2(row.object_id), "skos_relations", index, "self relation is invalid");
|
|
8685
10008
|
});
|
|
8686
10009
|
ids2("skos_mapping_relations");
|
|
8687
|
-
unique2("skos_mapping_relations", (row) =>
|
|
10010
|
+
unique2("skos_mapping_relations", (row) => key2(uuid2(row.concept_id), row.target_uri, row.relation_type));
|
|
8688
10011
|
rows("skos_mapping_relations").forEach((row, index) => ref(row, "concept_id", concepts, "skos_mapping_relations", index));
|
|
8689
|
-
unique2("skos_scheme_memberships", (row) =>
|
|
10012
|
+
unique2("skos_scheme_memberships", (row) => key2(uuid2(row.concept_id), uuid2(row.scheme_id)));
|
|
8690
10013
|
rows("skos_scheme_memberships").forEach((row, index) => {
|
|
8691
10014
|
ref(row, "concept_id", concepts, "skos_scheme_memberships", index);
|
|
8692
10015
|
ref(row, "scheme_id", schemes, "skos_scheme_memberships", index);
|
|
8693
10016
|
});
|
|
8694
|
-
unique2("note_skos_tags", (row) =>
|
|
10017
|
+
unique2("note_skos_tags", (row) => key2(uuid2(row.note_id), uuid2(row.concept_id)));
|
|
8695
10018
|
rows("note_skos_tags").forEach((row, index) => {
|
|
8696
10019
|
ref(row, "note_id", notes, "note_skos_tags", index);
|
|
8697
10020
|
ref(row, "concept_id", concepts, "note_skos_tags", index);
|
|
@@ -8699,7 +10022,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8699
10022
|
const skosCollections = ids2("skos_collections");
|
|
8700
10023
|
unique2("skos_collections", (row) => row.uri);
|
|
8701
10024
|
rows("skos_collections").forEach((row, index) => ref(row, "scheme_id", schemes, "skos_collections", index, true));
|
|
8702
|
-
unique2("skos_collection_members", (row) =>
|
|
10025
|
+
unique2("skos_collection_members", (row) => key2(uuid2(row.collection_id), uuid2(row.concept_id)));
|
|
8703
10026
|
rows("skos_collection_members").forEach((row, index) => {
|
|
8704
10027
|
ref(row, "collection_id", skosCollections, "skos_collection_members", index);
|
|
8705
10028
|
ref(row, "concept_id", concepts, "skos_collection_members", index);
|
|
@@ -8715,7 +10038,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8715
10038
|
);
|
|
8716
10039
|
}
|
|
8717
10040
|
});
|
|
8718
|
-
unique2("graph_edges", (row) =>
|
|
10041
|
+
unique2("graph_edges", (row) => key2(row.graph_source_id, uuid2(row.from_note_id), uuid2(row.to_note_id), row.kind));
|
|
8719
10042
|
rows("graph_edges").forEach((row, index) => {
|
|
8720
10043
|
ref(row, "graph_source_id", sources, "graph_edges", index, false, false);
|
|
8721
10044
|
ref(row, "from_note_id", notes, "graph_edges", index);
|
|
@@ -8727,7 +10050,7 @@ function fullV1ReferenceErrors(records) {
|
|
|
8727
10050
|
rows("communities").forEach((row, index) => {
|
|
8728
10051
|
ref(row, "graph_source_id", sources, "communities", index, false, false);
|
|
8729
10052
|
for (const community of row.communities) {
|
|
8730
|
-
const id =
|
|
10053
|
+
const id = key2(row.id, community.id);
|
|
8731
10054
|
check(!communities.has(id), "communities", index, "duplicate community identity within set");
|
|
8732
10055
|
communities.add(id);
|
|
8733
10056
|
const representatives = /* @__PURE__ */ new Set();
|
|
@@ -8742,10 +10065,10 @@ function fullV1ReferenceErrors(records) {
|
|
|
8742
10065
|
}
|
|
8743
10066
|
}
|
|
8744
10067
|
});
|
|
8745
|
-
unique2("community_assignments", (row) =>
|
|
10068
|
+
unique2("community_assignments", (row) => key2(row.community_set_id, uuid2(row.note_id)));
|
|
8746
10069
|
rows("community_assignments").forEach((row, index) => {
|
|
8747
10070
|
check(
|
|
8748
|
-
communities.has(
|
|
10071
|
+
communities.has(key2(row.community_set_id, row.community_id)),
|
|
8749
10072
|
"community_assignments",
|
|
8750
10073
|
index,
|
|
8751
10074
|
"community does not belong to the declared set"
|
|
@@ -18704,15 +20027,15 @@ init_geometry_buffer();
|
|
|
18704
20027
|
var CURRENT_SHARD_VERSION = "1.2.0";
|
|
18705
20028
|
var MAX_SHARD_READER_VERSION = "2.0.0";
|
|
18706
20029
|
var SHARD_FORMAT = "matric-shard";
|
|
18707
|
-
function
|
|
20030
|
+
function parseVersion2(value) {
|
|
18708
20031
|
return value.split(".").map((segment) => {
|
|
18709
20032
|
const match = segment.match(/^\d+/);
|
|
18710
20033
|
return match ? Number.parseInt(match[0], 10) : 0;
|
|
18711
20034
|
});
|
|
18712
20035
|
}
|
|
18713
20036
|
function compareShardVersions(left, right) {
|
|
18714
|
-
const leftParts =
|
|
18715
|
-
const rightParts =
|
|
20037
|
+
const leftParts = parseVersion2(left);
|
|
20038
|
+
const rightParts = parseVersion2(right);
|
|
18716
20039
|
const length = Math.max(leftParts.length, rightParts.length);
|
|
18717
20040
|
for (let index = 0; index < length; index += 1) {
|
|
18718
20041
|
const leftValue = leftParts[index] ?? 0;
|
|
@@ -18748,7 +20071,7 @@ function collectSidecarBlobs(files) {
|
|
|
18748
20071
|
}
|
|
18749
20072
|
|
|
18750
20073
|
// src/shard/schema-validator.ts
|
|
18751
|
-
var
|
|
20074
|
+
var decoder2 = new TextDecoder();
|
|
18752
20075
|
var LEGACY_COMPONENT_SCHEMA_DEFS = {
|
|
18753
20076
|
notes: "note",
|
|
18754
20077
|
collections: "collection",
|
|
@@ -19004,13 +20327,13 @@ function getKnowledgeShardSchema() {
|
|
|
19004
20327
|
function getKnowledgeShardContractReceipt() {
|
|
19005
20328
|
return knowledge_shard_schema_receipt_default;
|
|
19006
20329
|
}
|
|
19007
|
-
function addCanonicalFormats(
|
|
19008
|
-
|
|
19009
|
-
|
|
20330
|
+
function addCanonicalFormats(ajv3) {
|
|
20331
|
+
ajv3.addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
20332
|
+
ajv3.addFormat("date-time", {
|
|
19010
20333
|
type: "string",
|
|
19011
20334
|
validate: (value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(value) && !Number.isNaN(Date.parse(value))
|
|
19012
20335
|
});
|
|
19013
|
-
|
|
20336
|
+
ajv3.addFormat("uri", {
|
|
19014
20337
|
type: "string",
|
|
19015
20338
|
validate: (value) => {
|
|
19016
20339
|
try {
|
|
@@ -19023,7 +20346,7 @@ function addCanonicalFormats(ajv) {
|
|
|
19023
20346
|
}
|
|
19024
20347
|
function getLegacyAjv() {
|
|
19025
20348
|
if (!legacyAjvInstance) {
|
|
19026
|
-
legacyAjvInstance = new
|
|
20349
|
+
legacyAjvInstance = new Ajv20206({
|
|
19027
20350
|
allErrors: true,
|
|
19028
20351
|
strict: true,
|
|
19029
20352
|
validateFormats: false
|
|
@@ -19034,7 +20357,7 @@ function getLegacyAjv() {
|
|
|
19034
20357
|
}
|
|
19035
20358
|
function getCoreAjv() {
|
|
19036
20359
|
if (!coreAjvInstance) {
|
|
19037
|
-
coreAjvInstance = new
|
|
20360
|
+
coreAjvInstance = new Ajv20206({
|
|
19038
20361
|
allErrors: true,
|
|
19039
20362
|
strict: true,
|
|
19040
20363
|
validateFormats: true
|
|
@@ -19054,7 +20377,7 @@ function getCoreAjv() {
|
|
|
19054
20377
|
}
|
|
19055
20378
|
function getRecordAjv() {
|
|
19056
20379
|
if (!recordAjvInstance) {
|
|
19057
|
-
recordAjvInstance = new
|
|
20380
|
+
recordAjvInstance = new Ajv20206({
|
|
19058
20381
|
allErrors: true,
|
|
19059
20382
|
strict: true,
|
|
19060
20383
|
validateFormats: true
|
|
@@ -19074,7 +20397,7 @@ function getRecordAjv() {
|
|
|
19074
20397
|
}
|
|
19075
20398
|
function getFullAjv() {
|
|
19076
20399
|
if (!fullAjvInstance) {
|
|
19077
|
-
fullAjvInstance = new
|
|
20400
|
+
fullAjvInstance = new Ajv20206({
|
|
19078
20401
|
allErrors: true,
|
|
19079
20402
|
strict: true,
|
|
19080
20403
|
validateFormats: true
|
|
@@ -19109,30 +20432,30 @@ function fullSchemaVersion(value) {
|
|
|
19109
20432
|
return value === "1.1.0" || value === "1.2.0" || value === "2.0.0" ? value : void 0;
|
|
19110
20433
|
}
|
|
19111
20434
|
function coreValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19112
|
-
const
|
|
19113
|
-
const cached = coreValidators.get(
|
|
20435
|
+
const key3 = `${version}:${name}`;
|
|
20436
|
+
const cached = coreValidators.get(key3);
|
|
19114
20437
|
if (cached) return cached;
|
|
19115
20438
|
const schema = CORE_V1_SCHEMAS[version][name];
|
|
19116
20439
|
const validator = getCoreAjv().getSchema(schema.$id) ?? getCoreAjv().compile(schema);
|
|
19117
|
-
coreValidators.set(
|
|
20440
|
+
coreValidators.set(key3, validator);
|
|
19118
20441
|
return validator;
|
|
19119
20442
|
}
|
|
19120
20443
|
function recordValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19121
|
-
const
|
|
19122
|
-
const cached = recordValidators.get(
|
|
20444
|
+
const key3 = `${version}:${name}`;
|
|
20445
|
+
const cached = recordValidators.get(key3);
|
|
19123
20446
|
if (cached) return cached;
|
|
19124
20447
|
const schema = RECORD_V1_SCHEMAS[version][name];
|
|
19125
20448
|
const validator = getRecordAjv().getSchema(schema.$id) ?? getRecordAjv().compile(schema);
|
|
19126
|
-
recordValidators.set(
|
|
20449
|
+
recordValidators.set(key3, validator);
|
|
19127
20450
|
return validator;
|
|
19128
20451
|
}
|
|
19129
20452
|
function fullValidatorFor(name, version = CURRENT_SHARD_VERSION) {
|
|
19130
|
-
const
|
|
19131
|
-
const cached = fullValidators.get(
|
|
20453
|
+
const key3 = `${version}:${name}`;
|
|
20454
|
+
const cached = fullValidators.get(key3);
|
|
19132
20455
|
if (cached) return cached;
|
|
19133
20456
|
const schema = FULL_V1_SCHEMAS[version][name];
|
|
19134
20457
|
const validator = getFullAjv().getSchema(schema.$id) ?? getFullAjv().compile(schema);
|
|
19135
|
-
fullValidators.set(
|
|
20458
|
+
fullValidators.set(key3, validator);
|
|
19136
20459
|
return validator;
|
|
19137
20460
|
}
|
|
19138
20461
|
function formatErrors(errors) {
|
|
@@ -19147,7 +20470,7 @@ function profileOf(value) {
|
|
|
19147
20470
|
return typeof profile === "string" ? profile : void 0;
|
|
19148
20471
|
}
|
|
19149
20472
|
function validateShardManifest(value) {
|
|
19150
|
-
let
|
|
20473
|
+
let validate4;
|
|
19151
20474
|
const profile = profileOf(value);
|
|
19152
20475
|
if (profile === "core-v1") {
|
|
19153
20476
|
const version = value && typeof value === "object" && !Array.isArray(value) ? coreSchemaVersion(String(value.version ?? "")) : void 0;
|
|
@@ -19157,7 +20480,7 @@ function validateShardManifest(value) {
|
|
|
19157
20480
|
errors: ["(root) uses an unsupported canonical core-v1 schema version"]
|
|
19158
20481
|
};
|
|
19159
20482
|
}
|
|
19160
|
-
|
|
20483
|
+
validate4 = coreValidatorFor("manifest", version);
|
|
19161
20484
|
} else if (profile === "record-v1") {
|
|
19162
20485
|
const version = value && typeof value === "object" && !Array.isArray(value) ? recordSchemaVersion(String(value.version ?? "")) : void 0;
|
|
19163
20486
|
if (!version) {
|
|
@@ -19166,7 +20489,7 @@ function validateShardManifest(value) {
|
|
|
19166
20489
|
errors: ["(root) uses an unsupported canonical record-v1 schema version"]
|
|
19167
20490
|
};
|
|
19168
20491
|
}
|
|
19169
|
-
|
|
20492
|
+
validate4 = recordValidatorFor("manifest", version);
|
|
19170
20493
|
} else if (profile === "full-v1") {
|
|
19171
20494
|
const version = value && typeof value === "object" && !Array.isArray(value) ? fullSchemaVersion(String(value.version ?? "")) : void 0;
|
|
19172
20495
|
if (!version) {
|
|
@@ -19175,17 +20498,17 @@ function validateShardManifest(value) {
|
|
|
19175
20498
|
errors: ["(root) uses an unsupported canonical full-v1 schema version"]
|
|
19176
20499
|
};
|
|
19177
20500
|
}
|
|
19178
|
-
|
|
20501
|
+
validate4 = fullValidatorFor("manifest", version);
|
|
19179
20502
|
} else {
|
|
19180
|
-
|
|
20503
|
+
validate4 = legacyValidatorFor("manifest");
|
|
19181
20504
|
}
|
|
19182
|
-
const valid =
|
|
19183
|
-
return { valid, errors: formatErrors(
|
|
20505
|
+
const valid = validate4(value);
|
|
20506
|
+
return { valid, errors: formatErrors(validate4.errors) };
|
|
19184
20507
|
}
|
|
19185
20508
|
function parseJsonArray(bytes, path) {
|
|
19186
20509
|
if (!bytes) return { records: [], errors: [] };
|
|
19187
20510
|
try {
|
|
19188
|
-
const value = JSON.parse(
|
|
20511
|
+
const value = JSON.parse(decoder2.decode(bytes));
|
|
19189
20512
|
if (!Array.isArray(value)) return { records: [], errors: [`${path} must be a JSON array`] };
|
|
19190
20513
|
return { records: value, errors: [] };
|
|
19191
20514
|
} catch {
|
|
@@ -19194,7 +20517,7 @@ function parseJsonArray(bytes, path) {
|
|
|
19194
20517
|
}
|
|
19195
20518
|
function parseJsonl(bytes, path) {
|
|
19196
20519
|
if (!bytes) return { records: [], errors: [] };
|
|
19197
|
-
const text =
|
|
20520
|
+
const text = decoder2.decode(bytes).trim();
|
|
19198
20521
|
if (!text) return { records: [], errors: [] };
|
|
19199
20522
|
const records = [];
|
|
19200
20523
|
const errors = [];
|
|
@@ -19438,7 +20761,7 @@ function validateFullV1Structure(files, manifest) {
|
|
|
19438
20761
|
const signatureBytes = files.get("signature.json");
|
|
19439
20762
|
if (signatureBytes) {
|
|
19440
20763
|
try {
|
|
19441
|
-
const signature = JSON.parse(
|
|
20764
|
+
const signature = JSON.parse(decoder2.decode(signatureBytes));
|
|
19442
20765
|
const signatureValidator = fullValidatorFor("signature", schemaVersion);
|
|
19443
20766
|
if (!signatureValidator(signature)) {
|
|
19444
20767
|
errors.push(
|
|
@@ -19534,7 +20857,7 @@ function validateShardArchive(input) {
|
|
|
19534
20857
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
19535
20858
|
let manifest;
|
|
19536
20859
|
try {
|
|
19537
|
-
manifest = JSON.parse(
|
|
20860
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
19538
20861
|
} catch {
|
|
19539
20862
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
19540
20863
|
}
|
|
@@ -19553,7 +20876,7 @@ async function validateCoreV1ShardArchive(input) {
|
|
|
19553
20876
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
19554
20877
|
let manifest;
|
|
19555
20878
|
try {
|
|
19556
|
-
manifest = JSON.parse(
|
|
20879
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
19557
20880
|
} catch {
|
|
19558
20881
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
19559
20882
|
}
|
|
@@ -19576,7 +20899,7 @@ async function validateRecordV1ShardArchive(input) {
|
|
|
19576
20899
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
19577
20900
|
let manifest;
|
|
19578
20901
|
try {
|
|
19579
|
-
manifest = JSON.parse(
|
|
20902
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
19580
20903
|
} catch {
|
|
19581
20904
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
19582
20905
|
}
|
|
@@ -19599,7 +20922,7 @@ async function validateFullV1ShardArchive(input) {
|
|
|
19599
20922
|
if (!manifestBytes) return { valid: false, errors: ["manifest.json is missing"] };
|
|
19600
20923
|
let manifest;
|
|
19601
20924
|
try {
|
|
19602
|
-
manifest = JSON.parse(
|
|
20925
|
+
manifest = JSON.parse(decoder2.decode(manifestBytes));
|
|
19603
20926
|
} catch {
|
|
19604
20927
|
return { valid: false, errors: ["manifest.json failed to parse as JSON"] };
|
|
19605
20928
|
}
|
|
@@ -19628,9 +20951,9 @@ async function validateFullV1ShardArchive(input) {
|
|
|
19628
20951
|
return { valid: errors.length === 0, errors };
|
|
19629
20952
|
}
|
|
19630
20953
|
function validateShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
19631
|
-
let
|
|
20954
|
+
let validate4;
|
|
19632
20955
|
if (profile === "core-v1" && component in CORE_V1_COMPONENT_FILES) {
|
|
19633
|
-
|
|
20956
|
+
validate4 = coreValidatorFor(component, version);
|
|
19634
20957
|
} else if (profile === "record-v1" && component in RECORD_V1_COMPONENT_FILES) {
|
|
19635
20958
|
const canonicalVersion = recordSchemaVersion(version);
|
|
19636
20959
|
if (!canonicalVersion) {
|
|
@@ -19639,7 +20962,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
19639
20962
|
errors: [`(root) uses an unsupported canonical record-v1 schema version ${version}`]
|
|
19640
20963
|
};
|
|
19641
20964
|
}
|
|
19642
|
-
|
|
20965
|
+
validate4 = recordValidatorFor(component, canonicalVersion);
|
|
19643
20966
|
} else if (profile === "full-v1" && component in FULL_V1_COMPONENT_FILES) {
|
|
19644
20967
|
const canonicalVersion = fullSchemaVersion(version);
|
|
19645
20968
|
if (!canonicalVersion) {
|
|
@@ -19648,7 +20971,7 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
19648
20971
|
errors: [`(root) uses an unsupported canonical full-v1 schema version ${version}`]
|
|
19649
20972
|
};
|
|
19650
20973
|
}
|
|
19651
|
-
|
|
20974
|
+
validate4 = fullValidatorFor(component, canonicalVersion);
|
|
19652
20975
|
} else {
|
|
19653
20976
|
const legacyDef = LEGACY_COMPONENT_SCHEMA_DEFS[component];
|
|
19654
20977
|
if (!legacyDef) {
|
|
@@ -19657,10 +20980,10 @@ function validateShardComponentRecord(component, value, profile, version = CURRE
|
|
|
19657
20980
|
errors: [`(root) component '${component}' requires an explicit full-v1 profile`]
|
|
19658
20981
|
};
|
|
19659
20982
|
}
|
|
19660
|
-
|
|
20983
|
+
validate4 = legacyValidatorFor(legacyDef);
|
|
19661
20984
|
}
|
|
19662
|
-
const valid =
|
|
19663
|
-
return { valid, errors: formatErrors(
|
|
20985
|
+
const valid = validate4(value);
|
|
20986
|
+
return { valid, errors: formatErrors(validate4.errors) };
|
|
19664
20987
|
}
|
|
19665
20988
|
function assertShardComponentRecord(component, value, profile, version = CURRENT_SHARD_VERSION) {
|
|
19666
20989
|
const result = validateShardComponentRecord(component, value, profile, version);
|
|
@@ -19977,6 +21300,12 @@ var ManageNoteInputSchema = z.object({
|
|
|
19977
21300
|
});
|
|
19978
21301
|
var SearchInputSchema = z.object({
|
|
19979
21302
|
query: z.string(),
|
|
21303
|
+
metadataPredicates: z.unknown().transform((value) => {
|
|
21304
|
+
validateMetadataPredicates(value);
|
|
21305
|
+
return value;
|
|
21306
|
+
}).optional(),
|
|
21307
|
+
tenant_id: z.string().min(1).optional(),
|
|
21308
|
+
archive_id: z.string().min(1).nullable().optional(),
|
|
19980
21309
|
mode: z.enum(["text", "semantic", "hybrid", "auto"]).default("text"),
|
|
19981
21310
|
query_embedding: z.array(z.number()).optional(),
|
|
19982
21311
|
embeddingSetId: z.string().optional(),
|
|
@@ -20041,6 +21370,366 @@ async function manageNote(db, rawInput, events) {
|
|
|
20041
21370
|
|
|
20042
21371
|
// src/remote-contract.ts
|
|
20043
21372
|
init_geometry_buffer();
|
|
21373
|
+
|
|
21374
|
+
// src/remote-search-schema.ts
|
|
21375
|
+
init_geometry_buffer();
|
|
21376
|
+
|
|
21377
|
+
// schemas/metadata-search/candidate/1.0.0/search-rest.schema.json
|
|
21378
|
+
var search_rest_schema_default = {
|
|
21379
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
21380
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/search-rest.schema.json",
|
|
21381
|
+
title: "Candidate canonical GET search request and response",
|
|
21382
|
+
description: "Producer authority candidate. Schema validation is supplemented by same-note/canonical evidence binding, exact returned totals, strict-filter aggregate count and metadata range semantics. No auth grant or complete capability promotion.",
|
|
21383
|
+
$defs: {
|
|
21384
|
+
StrictSearchFilterInput: {
|
|
21385
|
+
type: "object",
|
|
21386
|
+
description: "Decoded strict_filter JSON. Unknown keys retain legacy ignored behavior. Sum of the five list lengths must not exceed 1000; name resolution still requires current authorized storage.",
|
|
21387
|
+
additionalProperties: true,
|
|
21388
|
+
properties: {
|
|
21389
|
+
required_tags: {
|
|
21390
|
+
type: "array",
|
|
21391
|
+
maxItems: 1e3,
|
|
21392
|
+
items: {
|
|
21393
|
+
type: "string"
|
|
21394
|
+
},
|
|
21395
|
+
default: []
|
|
21396
|
+
},
|
|
21397
|
+
any_tags: {
|
|
21398
|
+
type: "array",
|
|
21399
|
+
maxItems: 1e3,
|
|
21400
|
+
items: {
|
|
21401
|
+
type: "string"
|
|
21402
|
+
},
|
|
21403
|
+
default: []
|
|
21404
|
+
},
|
|
21405
|
+
excluded_tags: {
|
|
21406
|
+
type: "array",
|
|
21407
|
+
maxItems: 1e3,
|
|
21408
|
+
items: {
|
|
21409
|
+
type: "string"
|
|
21410
|
+
},
|
|
21411
|
+
default: []
|
|
21412
|
+
},
|
|
21413
|
+
required_schemes: {
|
|
21414
|
+
type: "array",
|
|
21415
|
+
maxItems: 1e3,
|
|
21416
|
+
items: {
|
|
21417
|
+
type: "string"
|
|
21418
|
+
},
|
|
21419
|
+
default: []
|
|
21420
|
+
},
|
|
21421
|
+
excluded_schemes: {
|
|
21422
|
+
type: "array",
|
|
21423
|
+
maxItems: 1e3,
|
|
21424
|
+
items: {
|
|
21425
|
+
type: "string"
|
|
21426
|
+
},
|
|
21427
|
+
default: []
|
|
21428
|
+
},
|
|
21429
|
+
min_tag_count: {
|
|
21430
|
+
type: ["integer", "null"],
|
|
21431
|
+
minimum: -2147483648,
|
|
21432
|
+
maximum: 2147483647
|
|
21433
|
+
},
|
|
21434
|
+
include_untagged: {
|
|
21435
|
+
type: "boolean",
|
|
21436
|
+
default: true
|
|
21437
|
+
}
|
|
21438
|
+
}
|
|
21439
|
+
},
|
|
21440
|
+
SearchRestRequest: {
|
|
21441
|
+
type: "object",
|
|
21442
|
+
description: "Decoded GET query parameters. JSON-content parameters are decoded to JSON values before this schema is applied. This is not a POST request body. Unknown query keys retain legacy ignored behavior and cannot grant tenant/archive authorization.",
|
|
21443
|
+
required: [
|
|
21444
|
+
"q"
|
|
21445
|
+
],
|
|
21446
|
+
additionalProperties: true,
|
|
21447
|
+
properties: {
|
|
21448
|
+
q: {
|
|
21449
|
+
type: "string",
|
|
21450
|
+
description: "Search expression. Empty text remains accepted."
|
|
21451
|
+
},
|
|
21452
|
+
limit: {
|
|
21453
|
+
type: "integer",
|
|
21454
|
+
minimum: 0,
|
|
21455
|
+
maximum: 1e3,
|
|
21456
|
+
default: 20
|
|
21457
|
+
},
|
|
21458
|
+
filters: {
|
|
21459
|
+
type: "string",
|
|
21460
|
+
description: "Legacy filter expression; combined with comma-separated tags."
|
|
21461
|
+
},
|
|
21462
|
+
mode: {
|
|
21463
|
+
type: "string",
|
|
21464
|
+
default: "hybrid",
|
|
21465
|
+
description: "fts selects lexical search, semantic selects vector search. hybrid, absent and other legacy values select hybrid; failures have explicit FTS degradation."
|
|
21466
|
+
},
|
|
21467
|
+
set: {
|
|
21468
|
+
type: "string",
|
|
21469
|
+
description: "Embedding-set slug resolved within the authorized memory and tenant."
|
|
21470
|
+
},
|
|
21471
|
+
created_after: {
|
|
21472
|
+
type: "string",
|
|
21473
|
+
format: "date-time"
|
|
21474
|
+
},
|
|
21475
|
+
created_before: {
|
|
21476
|
+
type: "string",
|
|
21477
|
+
format: "date-time"
|
|
21478
|
+
},
|
|
21479
|
+
updated_after: {
|
|
21480
|
+
type: "string",
|
|
21481
|
+
format: "date-time"
|
|
21482
|
+
},
|
|
21483
|
+
updated_before: {
|
|
21484
|
+
type: "string",
|
|
21485
|
+
format: "date-time"
|
|
21486
|
+
},
|
|
21487
|
+
since: {
|
|
21488
|
+
type: "string",
|
|
21489
|
+
description: "Relative created-after time; explicit created_after wins. Unrecognized relative text retains legacy ignored behavior."
|
|
21490
|
+
},
|
|
21491
|
+
tags: {
|
|
21492
|
+
type: "string",
|
|
21493
|
+
description: "Comma-separated tags; trimmed nonempty entries are AND requirements."
|
|
21494
|
+
},
|
|
21495
|
+
strict_filter: {
|
|
21496
|
+
$ref: "#/$defs/StrictSearchFilterInput",
|
|
21497
|
+
"x-fortemi-query-content": "application/json"
|
|
21498
|
+
},
|
|
21499
|
+
metadata_predicates: {
|
|
21500
|
+
$ref: "predicates.schema.json",
|
|
21501
|
+
"x-fortemi-query-content": "application/json",
|
|
21502
|
+
"x-fortemi-max-encoded-utf8-bytes": 1048576
|
|
21503
|
+
},
|
|
21504
|
+
diversity: {
|
|
21505
|
+
type: "number",
|
|
21506
|
+
minimum: -34028234663852886e22,
|
|
21507
|
+
maximum: 34028234663852886e22,
|
|
21508
|
+
description: "Finite f32 input, clamped to [0,1] before MMR; zero is pure relevance."
|
|
21509
|
+
}
|
|
21510
|
+
}
|
|
21511
|
+
},
|
|
21512
|
+
SearchHitFields: {
|
|
21513
|
+
type: "object",
|
|
21514
|
+
required: [
|
|
21515
|
+
"note_id",
|
|
21516
|
+
"score",
|
|
21517
|
+
"snippet"
|
|
21518
|
+
],
|
|
21519
|
+
properties: {
|
|
21520
|
+
note_id: {
|
|
21521
|
+
type: "string",
|
|
21522
|
+
format: "uuid"
|
|
21523
|
+
},
|
|
21524
|
+
score: {
|
|
21525
|
+
type: "number",
|
|
21526
|
+
description: "Finite retrieval/fusion score, not a probability."
|
|
21527
|
+
},
|
|
21528
|
+
snippet: {
|
|
21529
|
+
type: [
|
|
21530
|
+
"string",
|
|
21531
|
+
"null"
|
|
21532
|
+
],
|
|
21533
|
+
description: "Display only; not citation text or coordinates."
|
|
21534
|
+
},
|
|
21535
|
+
title: {
|
|
21536
|
+
type: "string"
|
|
21537
|
+
},
|
|
21538
|
+
tags: {
|
|
21539
|
+
type: "array",
|
|
21540
|
+
items: {
|
|
21541
|
+
type: "string"
|
|
21542
|
+
}
|
|
21543
|
+
},
|
|
21544
|
+
embedding_status: {
|
|
21545
|
+
enum: [
|
|
21546
|
+
"ready",
|
|
21547
|
+
"pending",
|
|
21548
|
+
"failed",
|
|
21549
|
+
"none"
|
|
21550
|
+
]
|
|
21551
|
+
},
|
|
21552
|
+
evidence: {
|
|
21553
|
+
$ref: "evidence-set.schema.json"
|
|
21554
|
+
}
|
|
21555
|
+
}
|
|
21556
|
+
},
|
|
21557
|
+
SearchHit: {
|
|
21558
|
+
type: "object",
|
|
21559
|
+
allOf: [
|
|
21560
|
+
{
|
|
21561
|
+
$ref: "#/$defs/SearchHitFields"
|
|
21562
|
+
}
|
|
21563
|
+
],
|
|
21564
|
+
unevaluatedProperties: false
|
|
21565
|
+
},
|
|
21566
|
+
ChainSearchInfo: {
|
|
21567
|
+
type: "object",
|
|
21568
|
+
additionalProperties: false,
|
|
21569
|
+
required: [
|
|
21570
|
+
"chain_id",
|
|
21571
|
+
"original_title",
|
|
21572
|
+
"chunks_matched",
|
|
21573
|
+
"best_chunk_sequence",
|
|
21574
|
+
"total_chunks"
|
|
21575
|
+
],
|
|
21576
|
+
description: "Legacy display aggregation. Index/count fields are currently heuristic, not native citation coordinates; use evidence for exact unit identity.",
|
|
21577
|
+
properties: {
|
|
21578
|
+
chain_id: {
|
|
21579
|
+
type: "string",
|
|
21580
|
+
format: "uuid"
|
|
21581
|
+
},
|
|
21582
|
+
original_title: {
|
|
21583
|
+
type: "string"
|
|
21584
|
+
},
|
|
21585
|
+
chunks_matched: {
|
|
21586
|
+
type: "integer",
|
|
21587
|
+
minimum: 0
|
|
21588
|
+
},
|
|
21589
|
+
best_chunk_sequence: {
|
|
21590
|
+
type: "integer",
|
|
21591
|
+
minimum: 0,
|
|
21592
|
+
maximum: 4294967295
|
|
21593
|
+
},
|
|
21594
|
+
total_chunks: {
|
|
21595
|
+
type: "integer",
|
|
21596
|
+
minimum: 0,
|
|
21597
|
+
maximum: 4294967295
|
|
21598
|
+
}
|
|
21599
|
+
}
|
|
21600
|
+
},
|
|
21601
|
+
EnhancedSearchHit: {
|
|
21602
|
+
type: "object",
|
|
21603
|
+
allOf: [
|
|
21604
|
+
{
|
|
21605
|
+
$ref: "#/$defs/SearchHitFields"
|
|
21606
|
+
},
|
|
21607
|
+
{
|
|
21608
|
+
type: "object",
|
|
21609
|
+
properties: {
|
|
21610
|
+
chain_info: {
|
|
21611
|
+
$ref: "#/$defs/ChainSearchInfo"
|
|
21612
|
+
}
|
|
21613
|
+
}
|
|
21614
|
+
}
|
|
21615
|
+
],
|
|
21616
|
+
unevaluatedProperties: false
|
|
21617
|
+
},
|
|
21618
|
+
SearchDegradation: {
|
|
21619
|
+
type: "object",
|
|
21620
|
+
additionalProperties: false,
|
|
21621
|
+
required: [
|
|
21622
|
+
"code",
|
|
21623
|
+
"effective_mode"
|
|
21624
|
+
],
|
|
21625
|
+
properties: {
|
|
21626
|
+
code: {
|
|
21627
|
+
type: "string",
|
|
21628
|
+
pattern: "^[a-z][a-z0-9_]{0,63}$"
|
|
21629
|
+
},
|
|
21630
|
+
effective_mode: {
|
|
21631
|
+
const: "fts"
|
|
21632
|
+
}
|
|
21633
|
+
}
|
|
21634
|
+
},
|
|
21635
|
+
SearchRestResponse: {
|
|
21636
|
+
type: "object",
|
|
21637
|
+
additionalProperties: false,
|
|
21638
|
+
required: [
|
|
21639
|
+
"results",
|
|
21640
|
+
"query",
|
|
21641
|
+
"total",
|
|
21642
|
+
"degraded"
|
|
21643
|
+
],
|
|
21644
|
+
properties: {
|
|
21645
|
+
results: {
|
|
21646
|
+
type: "array",
|
|
21647
|
+
maxItems: 1e3,
|
|
21648
|
+
items: {
|
|
21649
|
+
$ref: "#/$defs/EnhancedSearchHit"
|
|
21650
|
+
}
|
|
21651
|
+
},
|
|
21652
|
+
query: {
|
|
21653
|
+
type: "string"
|
|
21654
|
+
},
|
|
21655
|
+
total: {
|
|
21656
|
+
type: "integer",
|
|
21657
|
+
minimum: 0,
|
|
21658
|
+
maximum: 1e3,
|
|
21659
|
+
description: "Returned hit count, exactly results.length; not total matches in storage."
|
|
21660
|
+
},
|
|
21661
|
+
degraded: {
|
|
21662
|
+
type: "boolean"
|
|
21663
|
+
},
|
|
21664
|
+
degradation: {
|
|
21665
|
+
$ref: "#/$defs/SearchDegradation"
|
|
21666
|
+
}
|
|
21667
|
+
},
|
|
21668
|
+
if: {
|
|
21669
|
+
properties: {
|
|
21670
|
+
degraded: {
|
|
21671
|
+
const: true
|
|
21672
|
+
}
|
|
21673
|
+
}
|
|
21674
|
+
},
|
|
21675
|
+
then: {
|
|
21676
|
+
properties: {
|
|
21677
|
+
degradation: {}
|
|
21678
|
+
},
|
|
21679
|
+
required: [
|
|
21680
|
+
"degradation"
|
|
21681
|
+
]
|
|
21682
|
+
},
|
|
21683
|
+
else: {
|
|
21684
|
+
not: {
|
|
21685
|
+
properties: {
|
|
21686
|
+
degradation: {}
|
|
21687
|
+
},
|
|
21688
|
+
required: [
|
|
21689
|
+
"degradation"
|
|
21690
|
+
]
|
|
21691
|
+
}
|
|
21692
|
+
}
|
|
21693
|
+
}
|
|
21694
|
+
}
|
|
21695
|
+
};
|
|
21696
|
+
|
|
21697
|
+
// schemas/metadata-search/candidate/1.0.0/evidence-resolution.schema.json
|
|
21698
|
+
var evidence_resolution_schema_default = {
|
|
21699
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
21700
|
+
$id: "https://fortemi.com/contracts/metadata-search/candidate/1.0.0/evidence-resolution.schema.json",
|
|
21701
|
+
title: "Candidate current-storage evidence resolution",
|
|
21702
|
+
$defs: {
|
|
21703
|
+
SearchEvidenceResolveRequest: {
|
|
21704
|
+
type: "object",
|
|
21705
|
+
additionalProperties: false,
|
|
21706
|
+
required: ["locator"],
|
|
21707
|
+
properties: {
|
|
21708
|
+
locator: { $ref: "evidence-locator.schema.json" },
|
|
21709
|
+
metadata_predicates: { $ref: "predicates.schema.json" },
|
|
21710
|
+
include_archived: { type: "boolean", default: false }
|
|
21711
|
+
}
|
|
21712
|
+
},
|
|
21713
|
+
SearchEvidenceResolveResponse: {
|
|
21714
|
+
type: "object",
|
|
21715
|
+
additionalProperties: false,
|
|
21716
|
+
required: ["text"],
|
|
21717
|
+
properties: {
|
|
21718
|
+
text: { type: "string", maxLength: 16777216 }
|
|
21719
|
+
}
|
|
21720
|
+
}
|
|
21721
|
+
}
|
|
21722
|
+
};
|
|
21723
|
+
|
|
21724
|
+
// src/remote-search-schema.ts
|
|
21725
|
+
var timestamp = z.string().datetime({ offset: true });
|
|
21726
|
+
var ajv2 = new Ajv20206({ strict: true, allErrors: false, ownProperties: true }).addFormat("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).addFormat("date-time", { type: "string", validate: (value) => timestamp.safeParse(value).success }).addKeyword({ keyword: "x-fortemi-query-content", schemaType: "string", valid: true }).addKeyword({ keyword: "x-fortemi-max-encoded-utf8-bytes", schemaType: "number", valid: true }).addSchema([search_rest_schema_default, evidence_locator_schema_default, evidence_set_schema_default, evidence_resolution_schema_default]).addSchema(predicates_schema_default, new URL("predicates.schema.json", search_rest_schema_default.$id).href);
|
|
21727
|
+
var isSearchRestRequest = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestRequest" });
|
|
21728
|
+
var isSearchRestResponse = ajv2.compile({ $ref: search_rest_schema_default.$id + "#/$defs/SearchRestResponse" });
|
|
21729
|
+
var isEvidenceResolveRequest = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveRequest" });
|
|
21730
|
+
var isEvidenceResolveResponse = ajv2.compile({ $ref: evidence_resolution_schema_default.$id + "#/$defs/SearchEvidenceResolveResponse" });
|
|
21731
|
+
|
|
21732
|
+
// src/remote-contract.ts
|
|
20044
21733
|
var uuid3 = z.string().uuid().transform((value) => value.toLowerCase());
|
|
20045
21734
|
var metadata = z.object({
|
|
20046
21735
|
id: uuid3,
|
|
@@ -20083,7 +21772,7 @@ function parseRemoteNoteDetail(value) {
|
|
|
20083
21772
|
return { ...projectNote({ ...result.note, tags: result.tags }), content: result.revised.content };
|
|
20084
21773
|
});
|
|
20085
21774
|
}
|
|
20086
|
-
var
|
|
21775
|
+
var timestamp2 = z.string().datetime({ offset: true });
|
|
20087
21776
|
function remoteNoteId(value) {
|
|
20088
21777
|
const parsed = uuid3.safeParse(value);
|
|
20089
21778
|
if (!parsed.success) throw new RemoteBackendError("invalid-request");
|
|
@@ -20096,7 +21785,7 @@ var link = z.object({
|
|
|
20096
21785
|
to_url: z.string().nullable(),
|
|
20097
21786
|
kind: z.string(),
|
|
20098
21787
|
score: z.number().finite(),
|
|
20099
|
-
created_at_utc:
|
|
21788
|
+
created_at_utc: timestamp2,
|
|
20100
21789
|
snippet: z.string().nullable(),
|
|
20101
21790
|
metadata: z.unknown().refine((value) => value !== void 0)
|
|
20102
21791
|
});
|
|
@@ -20135,7 +21824,7 @@ var conceptAssignment = z.tuple([
|
|
|
20135
21824
|
source: z.string(),
|
|
20136
21825
|
relevance_score: z.number().finite(),
|
|
20137
21826
|
is_primary: z.boolean(),
|
|
20138
|
-
created_at:
|
|
21827
|
+
created_at: timestamp2,
|
|
20139
21828
|
confidence: z.number().finite().optional(),
|
|
20140
21829
|
created_by: z.string().optional()
|
|
20141
21830
|
}),
|
|
@@ -20143,8 +21832,8 @@ var conceptAssignment = z.tuple([
|
|
|
20143
21832
|
id: uuid3,
|
|
20144
21833
|
primary_scheme_id: uuid3,
|
|
20145
21834
|
pref_label: z.string(),
|
|
20146
|
-
created_at:
|
|
20147
|
-
updated_at:
|
|
21835
|
+
created_at: timestamp2,
|
|
21836
|
+
updated_at: timestamp2
|
|
20148
21837
|
})
|
|
20149
21838
|
]);
|
|
20150
21839
|
function parseRemoteConcepts(value, noteId) {
|
|
@@ -20179,8 +21868,8 @@ var provenanceActivity = z.object({
|
|
|
20179
21868
|
revision_id: uuid3.nullable(),
|
|
20180
21869
|
activity_type: z.string(),
|
|
20181
21870
|
model_name: z.string().nullable(),
|
|
20182
|
-
started_at:
|
|
20183
|
-
ended_at:
|
|
21871
|
+
started_at: timestamp2,
|
|
21872
|
+
ended_at: timestamp2.nullable(),
|
|
20184
21873
|
metadata: z.unknown().refine((value) => value !== void 0)
|
|
20185
21874
|
});
|
|
20186
21875
|
var provenanceEdge = z.object({
|
|
@@ -20189,7 +21878,7 @@ var provenanceEdge = z.object({
|
|
|
20189
21878
|
source_note_id: uuid3.nullable(),
|
|
20190
21879
|
source_url: z.string().nullable(),
|
|
20191
21880
|
relation: z.string(),
|
|
20192
|
-
created_at_utc:
|
|
21881
|
+
created_at_utc: timestamp2
|
|
20193
21882
|
});
|
|
20194
21883
|
var provenanceChain = z.object({
|
|
20195
21884
|
note_id: uuid3,
|
|
@@ -20227,12 +21916,14 @@ function remoteSearchParameters(query, options) {
|
|
|
20227
21916
|
if (typeof query !== "string" || !parsed.success) throw new RemoteBackendError("invalid-request");
|
|
20228
21917
|
const value = parsed.data;
|
|
20229
21918
|
if ((value.offset ?? 0) !== 0 || (value.source?.length ?? 0) > 0) throw new RemoteBackendError("unsupported-operation");
|
|
20230
|
-
|
|
21919
|
+
const parameters = {
|
|
20231
21920
|
q: query,
|
|
20232
21921
|
mode: value.mode,
|
|
20233
21922
|
limit: value.limit,
|
|
20234
21923
|
...value.tags?.length ? { tags: value.tags.join(",") } : {}
|
|
20235
21924
|
};
|
|
21925
|
+
if (!isSearchRestRequest(parameters)) throw new RemoteBackendError("invalid-request");
|
|
21926
|
+
return parameters;
|
|
20236
21927
|
}
|
|
20237
21928
|
var searchHit = z.object({
|
|
20238
21929
|
note_id: uuid3,
|
|
@@ -20241,6 +21932,7 @@ var searchHit = z.object({
|
|
|
20241
21932
|
title: z.string().optional(),
|
|
20242
21933
|
tags: z.array(z.string()).optional(),
|
|
20243
21934
|
embedding_status: z.enum(["ready", "pending", "failed", "none"]).optional(),
|
|
21935
|
+
evidence: z.unknown().optional(),
|
|
20244
21936
|
chain_info: z.object({
|
|
20245
21937
|
chain_id: uuid3,
|
|
20246
21938
|
original_title: z.string(),
|
|
@@ -20248,10 +21940,13 @@ var searchHit = z.object({
|
|
|
20248
21940
|
best_chunk_sequence: z.number().int().nonnegative(),
|
|
20249
21941
|
total_chunks: z.number().int().nonnegative()
|
|
20250
21942
|
}).optional()
|
|
20251
|
-
})
|
|
21943
|
+
}).transform(({ evidence, ...hit }) => ({
|
|
21944
|
+
...hit,
|
|
21945
|
+
...evidence === void 0 ? {} : { evidence: parseSearchEvidenceSet(evidence, hit.note_id) }
|
|
21946
|
+
}));
|
|
20252
21947
|
var searchDegradation = z.object({
|
|
20253
21948
|
code: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
20254
|
-
effective_mode:
|
|
21949
|
+
effective_mode: z.literal("fts")
|
|
20255
21950
|
});
|
|
20256
21951
|
var searchResponse = z.object({
|
|
20257
21952
|
query: z.string(),
|
|
@@ -20262,8 +21957,10 @@ var searchResponse = z.object({
|
|
|
20262
21957
|
});
|
|
20263
21958
|
function parseRemoteSearch(value, query, limit) {
|
|
20264
21959
|
return remoteProjection(() => {
|
|
21960
|
+
if (!isSearchRestResponse(value)) throw new Error("Invalid search schema");
|
|
20265
21961
|
const result = searchResponse.parse(value);
|
|
20266
21962
|
if (result.query !== query || result.total !== result.results.length || result.results.length > limit || result.degraded !== (result.degradation !== void 0)) throw new Error("Invalid search envelope");
|
|
21963
|
+
if (result.results.some((hit) => hit.chain_info && hit.chain_info.chain_id !== hit.note_id)) throw new Error("Invalid chain identity");
|
|
20267
21964
|
return result;
|
|
20268
21965
|
});
|
|
20269
21966
|
}
|
|
@@ -20299,6 +21996,135 @@ function parseRemoteRestored(value, id) {
|
|
|
20299
21996
|
});
|
|
20300
21997
|
}
|
|
20301
21998
|
|
|
21999
|
+
// src/backend-search-options.ts
|
|
22000
|
+
init_geometry_buffer();
|
|
22001
|
+
function validateBackendSearchOptions(options, support) {
|
|
22002
|
+
if (options?.metadataPredicates !== void 0) {
|
|
22003
|
+
validateMetadataPredicates(options.metadataPredicates);
|
|
22004
|
+
if (!support.metadata) throw new Error("BACKEND_METADATA_PREDICATES_UNSUPPORTED");
|
|
22005
|
+
}
|
|
22006
|
+
if (options?.tenant_id !== void 0 || options?.archive_id !== void 0) {
|
|
22007
|
+
if (!support.scope) throw new Error("BACKEND_SEARCH_SCOPE_UNSUPPORTED");
|
|
22008
|
+
if (options.tenant_id !== void 0 && (typeof options.tenant_id !== "string" || !options.tenant_id.length) || options.archive_id !== void 0 && options.archive_id !== null && (typeof options.archive_id !== "string" || !options.archive_id.length)) {
|
|
22009
|
+
throw new Error("BACKEND_SEARCH_SCOPE_INVALID");
|
|
22010
|
+
}
|
|
22011
|
+
}
|
|
22012
|
+
if (options?.mode !== void 0 && support.modes && !support.modes.includes(options.mode)) {
|
|
22013
|
+
throw new Error("BACKEND_SEARCH_MODE_UNSUPPORTED");
|
|
22014
|
+
}
|
|
22015
|
+
}
|
|
22016
|
+
|
|
22017
|
+
// src/remote-evidence-resolution.ts
|
|
22018
|
+
init_geometry_buffer();
|
|
22019
|
+
var encoder3 = new TextEncoder();
|
|
22020
|
+
var decoder3 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
22021
|
+
var invalidRequest = () => new RemoteBackendError("invalid-request");
|
|
22022
|
+
var invalidResponse = () => new RemoteBackendError("invalid-response");
|
|
22023
|
+
function prepare(value, options = {}) {
|
|
22024
|
+
try {
|
|
22025
|
+
if (!options || typeof options !== "object" || Array.isArray(options) || ![Object.prototype, null].includes(Object.getPrototypeOf(options)) || Reflect.ownKeys(options).some((key3) => !["metadataPredicates", "includeArchived", "signal"].includes(String(key3)))) throw invalidRequest();
|
|
22026
|
+
const locator = parseSearchEvidenceLocator(value);
|
|
22027
|
+
if (locator.span.end > MAX_EVIDENCE_BYTES) throw invalidRequest();
|
|
22028
|
+
const metadata2 = Object.hasOwn(options, "metadataPredicates") ? options.metadataPredicates : void 0;
|
|
22029
|
+
const archived = Object.hasOwn(options, "includeArchived") ? options.includeArchived : void 0;
|
|
22030
|
+
const signal = Object.hasOwn(options, "signal") ? options.signal : void 0;
|
|
22031
|
+
if (signal !== void 0 && !(signal instanceof AbortSignal)) throw invalidRequest();
|
|
22032
|
+
if (metadata2 !== void 0) validateMetadataPredicates(metadata2);
|
|
22033
|
+
const request = {
|
|
22034
|
+
locator,
|
|
22035
|
+
...metadata2 === void 0 ? {} : { metadata_predicates: metadata2 },
|
|
22036
|
+
...archived === void 0 ? {} : { include_archived: archived }
|
|
22037
|
+
};
|
|
22038
|
+
if (!isEvidenceResolveRequest(request)) throw invalidRequest();
|
|
22039
|
+
const body = JSON.stringify(request);
|
|
22040
|
+
if (encoder3.encode(body).length > 65536) throw invalidRequest();
|
|
22041
|
+
const wire = JSON.parse(body);
|
|
22042
|
+
if (!isEvidenceResolveRequest(wire)) throw invalidRequest();
|
|
22043
|
+
const encoded = wire;
|
|
22044
|
+
parseSearchEvidenceLocator(encoded.locator);
|
|
22045
|
+
if (encoded.metadata_predicates !== void 0) validateMetadataPredicates(encoded.metadata_predicates);
|
|
22046
|
+
return { body, signal, length: locator.span.end - locator.span.start };
|
|
22047
|
+
} catch {
|
|
22048
|
+
throw invalidRequest();
|
|
22049
|
+
}
|
|
22050
|
+
}
|
|
22051
|
+
async function resolveRemoteEvidence(value, options, send) {
|
|
22052
|
+
const prepared = prepare(value, options);
|
|
22053
|
+
if (prepared.signal?.aborted) throw new RemoteBackendError("aborted");
|
|
22054
|
+
const controller = new AbortController();
|
|
22055
|
+
const abort = () => controller.abort();
|
|
22056
|
+
prepared.signal?.addEventListener("abort", abort, { once: true });
|
|
22057
|
+
const timer = setTimeout(abort, 3e4);
|
|
22058
|
+
let reader;
|
|
22059
|
+
let completed = false;
|
|
22060
|
+
let rejectAbort = () => {
|
|
22061
|
+
};
|
|
22062
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
22063
|
+
rejectAbort = () => reject(new RemoteBackendError("aborted"));
|
|
22064
|
+
});
|
|
22065
|
+
controller.signal.addEventListener("abort", rejectAbort, { once: true });
|
|
22066
|
+
async function perform() {
|
|
22067
|
+
const response = await send(prepared.body, controller.signal);
|
|
22068
|
+
if (controller.signal.aborted) {
|
|
22069
|
+
void response.body?.cancel().catch(() => {
|
|
22070
|
+
});
|
|
22071
|
+
throw new RemoteBackendError("aborted");
|
|
22072
|
+
}
|
|
22073
|
+
reader = response.body?.getReader();
|
|
22074
|
+
if (!response.ok) throw new RemoteBackendError("http", response.status);
|
|
22075
|
+
if (response.status !== 200 || !reader || response.headers.get("content-type")?.split(";")[0].trim().toLowerCase() !== "application/json" || !response.headers.get("cache-control")?.split(",").some((part) => part.trim().toLowerCase() === "no-store")) throw invalidResponse();
|
|
22076
|
+
const maximum = prepared.length * 6 + 64;
|
|
22077
|
+
const advertised = response.headers.get("content-length");
|
|
22078
|
+
if (advertised !== null && (!/^\d+$/.test(advertised) || Number(advertised) > maximum)) throw invalidResponse();
|
|
22079
|
+
let bytes = new Uint8Array(Math.min(maximum, 4096));
|
|
22080
|
+
let length = 0;
|
|
22081
|
+
while (true) {
|
|
22082
|
+
const { done, value: chunk } = await reader.read();
|
|
22083
|
+
if (done) {
|
|
22084
|
+
completed = true;
|
|
22085
|
+
break;
|
|
22086
|
+
}
|
|
22087
|
+
const nextLength = length + chunk.byteLength;
|
|
22088
|
+
if (nextLength > maximum) throw invalidResponse();
|
|
22089
|
+
if (nextLength > bytes.length) {
|
|
22090
|
+
const grown = new Uint8Array(Math.min(maximum, Math.max(nextLength, bytes.length * 2)));
|
|
22091
|
+
grown.set(bytes.subarray(0, length));
|
|
22092
|
+
bytes = grown;
|
|
22093
|
+
}
|
|
22094
|
+
bytes.set(chunk, length);
|
|
22095
|
+
length = nextLength;
|
|
22096
|
+
}
|
|
22097
|
+
let data;
|
|
22098
|
+
try {
|
|
22099
|
+
data = JSON.parse(decoder3.decode(bytes.subarray(0, length)));
|
|
22100
|
+
} catch {
|
|
22101
|
+
throw invalidResponse();
|
|
22102
|
+
}
|
|
22103
|
+
if (!isEvidenceResolveResponse(data)) throw invalidResponse();
|
|
22104
|
+
const text = data.text;
|
|
22105
|
+
if (text.length > prepared.length) throw invalidResponse();
|
|
22106
|
+
const textBytes2 = encoder3.encode(text);
|
|
22107
|
+
if (textBytes2.length !== prepared.length || decoder3.decode(textBytes2) !== text) throw invalidResponse();
|
|
22108
|
+
return text;
|
|
22109
|
+
}
|
|
22110
|
+
try {
|
|
22111
|
+
return await Promise.race([perform(), aborted]);
|
|
22112
|
+
} catch (error) {
|
|
22113
|
+
if (error instanceof RemoteBackendError) throw error;
|
|
22114
|
+
throw new RemoteBackendError(controller.signal.aborted || error instanceof Error && error.name === "AbortError" ? "aborted" : "transport");
|
|
22115
|
+
} finally {
|
|
22116
|
+
clearTimeout(timer);
|
|
22117
|
+
prepared.signal?.removeEventListener("abort", abort);
|
|
22118
|
+
controller.signal.removeEventListener("abort", rejectAbort);
|
|
22119
|
+
controller.abort();
|
|
22120
|
+
if (reader) {
|
|
22121
|
+
if (!completed) void reader.cancel().catch(() => {
|
|
22122
|
+
});
|
|
22123
|
+
reader.releaseLock();
|
|
22124
|
+
}
|
|
22125
|
+
}
|
|
22126
|
+
}
|
|
22127
|
+
|
|
20302
22128
|
// src/data-backend.ts
|
|
20303
22129
|
var SEMANTIC_RANK = {
|
|
20304
22130
|
none: 0,
|
|
@@ -20313,6 +22139,8 @@ var STARTUP_RANK = {
|
|
|
20313
22139
|
};
|
|
20314
22140
|
function missingFor(request, caps) {
|
|
20315
22141
|
const missing = [];
|
|
22142
|
+
if (request.typedMetadataPredicates && !caps.typedMetadataPredicates) missing.push("typedMetadataPredicates");
|
|
22143
|
+
if (request.evidenceLocators && !caps.evidenceLocators) missing.push("evidenceLocators");
|
|
20316
22144
|
if (request.read && !caps.read) missing.push("read");
|
|
20317
22145
|
if (request.write && !caps.write) missing.push("write");
|
|
20318
22146
|
if (request.merge && !caps.merge) missing.push("merge");
|
|
@@ -20436,9 +22264,45 @@ function shardProvenanceToBackend(edge) {
|
|
|
20436
22264
|
}
|
|
20437
22265
|
function createPGliteBackend(db, options = {}) {
|
|
20438
22266
|
const semanticAvailable = options.semanticAvailable ?? false;
|
|
22267
|
+
const embedQuery = options.embedQuery;
|
|
22268
|
+
const canEmbed = semanticAvailable && typeof embedQuery === "function";
|
|
20439
22269
|
const notes = new NotesRepository(db);
|
|
20440
22270
|
const search = new SearchRepository(db, semanticAvailable);
|
|
20441
22271
|
const links = new LinksRepository(db);
|
|
22272
|
+
async function searchNotes(query, o) {
|
|
22273
|
+
validateBackendSearchOptions(o, {
|
|
22274
|
+
metadata: true,
|
|
22275
|
+
scope: true,
|
|
22276
|
+
modes: canEmbed ? ["fts", "semantic", "hybrid"] : ["fts"]
|
|
22277
|
+
});
|
|
22278
|
+
const mode = o?.mode ?? "fts";
|
|
22279
|
+
const vector = mode === "fts" ? void 0 : await embedQuery(query);
|
|
22280
|
+
if (mode !== "fts" && (!Array.isArray(vector) || !vector.length || !Array.from(vector).every((value) => typeof value === "number" && Number.isFinite(value)))) {
|
|
22281
|
+
throw new Error("BACKEND_QUERY_EMBEDDING_INVALID");
|
|
22282
|
+
}
|
|
22283
|
+
const r = await search.search(query, {
|
|
22284
|
+
limit: o?.limit,
|
|
22285
|
+
offset: o?.offset,
|
|
22286
|
+
tagsAll: o?.tags,
|
|
22287
|
+
sources: o?.source,
|
|
22288
|
+
mode: mode === "fts" ? "text" : mode,
|
|
22289
|
+
metadataPredicates: o?.metadataPredicates,
|
|
22290
|
+
tenant_id: o?.tenant_id,
|
|
22291
|
+
archive_id: o?.archive_id,
|
|
22292
|
+
include_facets: true
|
|
22293
|
+
}, vector);
|
|
22294
|
+
return {
|
|
22295
|
+
hits: r.results.map((res) => ({
|
|
22296
|
+
note: searchResultToBackend(res),
|
|
22297
|
+
rank: res.rank,
|
|
22298
|
+
snippet: res.snippet,
|
|
22299
|
+
locators: res.locators,
|
|
22300
|
+
evidence: res.evidence
|
|
22301
|
+
})),
|
|
22302
|
+
total: r.total,
|
|
22303
|
+
facets: r.facets ? { tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count])) } : void 0
|
|
22304
|
+
};
|
|
22305
|
+
}
|
|
20442
22306
|
async function linksOf(id) {
|
|
20443
22307
|
const result = await links.listForNote(id);
|
|
20444
22308
|
const urlLinks = await db.query(
|
|
@@ -20479,7 +22343,9 @@ function createPGliteBackend(db, options = {}) {
|
|
|
20479
22343
|
write: true,
|
|
20480
22344
|
merge: true,
|
|
20481
22345
|
multiUser: false,
|
|
20482
|
-
|
|
22346
|
+
typedMetadataPredicates: true,
|
|
22347
|
+
evidenceLocators: false,
|
|
22348
|
+
semantic: canEmbed ? "ann-full" : "none",
|
|
20483
22349
|
startupCost: "index-build"
|
|
20484
22350
|
},
|
|
20485
22351
|
async listNotes(o) {
|
|
@@ -20494,24 +22360,8 @@ function createPGliteBackend(db, options = {}) {
|
|
|
20494
22360
|
return null;
|
|
20495
22361
|
}
|
|
20496
22362
|
},
|
|
20497
|
-
|
|
20498
|
-
|
|
20499
|
-
limit: o?.limit,
|
|
20500
|
-
offset: o?.offset,
|
|
20501
|
-
tags: o?.tags,
|
|
20502
|
-
source: o?.source?.[0],
|
|
20503
|
-
include_facets: true
|
|
20504
|
-
});
|
|
20505
|
-
const hits = r.results.map((res) => ({
|
|
20506
|
-
note: searchResultToBackend(res),
|
|
20507
|
-
rank: res.rank,
|
|
20508
|
-
snippet: res.snippet
|
|
20509
|
-
}));
|
|
20510
|
-
const facets = r.facets ? {
|
|
20511
|
-
tags: Object.fromEntries(r.facets.tags.map((t) => [t.tag, t.count]))
|
|
20512
|
-
} : void 0;
|
|
20513
|
-
return { hits, total: r.total, facets };
|
|
20514
|
-
},
|
|
22363
|
+
search: searchNotes,
|
|
22364
|
+
...canEmbed ? { semantic: async (query, k) => (await searchNotes(query, { mode: "semantic", limit: k })).hits } : {},
|
|
20515
22365
|
async getNoteFull(id) {
|
|
20516
22366
|
try {
|
|
20517
22367
|
const f = await notes.get(id);
|
|
@@ -20537,6 +22387,7 @@ var DEFAULT_REMOTE_PATHS = {
|
|
|
20537
22387
|
notes: "/api/v1/notes",
|
|
20538
22388
|
note: "/api/v1/notes/:id",
|
|
20539
22389
|
search: "/api/v1/search",
|
|
22390
|
+
resolveEvidence: "/api/v1/search/evidence/resolve",
|
|
20540
22391
|
links: "/api/v1/notes/:id/links",
|
|
20541
22392
|
concepts: "/api/v1/notes/:id/concepts",
|
|
20542
22393
|
provenance: "/api/v1/notes/:id/provenance",
|
|
@@ -20547,12 +22398,12 @@ function remotePath(template, id) {
|
|
|
20547
22398
|
}
|
|
20548
22399
|
function remoteUrl(baseUrl, path, params) {
|
|
20549
22400
|
const url = new URL(path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
20550
|
-
for (const [
|
|
22401
|
+
for (const [key3, value] of Object.entries(params ?? {})) {
|
|
20551
22402
|
if (value === void 0) continue;
|
|
20552
22403
|
if (Array.isArray(value)) {
|
|
20553
|
-
for (const item of value) url.searchParams.append(
|
|
22404
|
+
for (const item of value) url.searchParams.append(key3, String(item));
|
|
20554
22405
|
} else {
|
|
20555
|
-
url.searchParams.set(
|
|
22406
|
+
url.searchParams.set(key3, String(value));
|
|
20556
22407
|
}
|
|
20557
22408
|
}
|
|
20558
22409
|
return url.toString();
|
|
@@ -20608,6 +22459,7 @@ function createRemoteBackend(config) {
|
|
|
20608
22459
|
return note;
|
|
20609
22460
|
}
|
|
20610
22461
|
async function searchRemote(query, options, requireSemantic = false) {
|
|
22462
|
+
validateBackendSearchOptions(options, { metadata: false, scope: false });
|
|
20611
22463
|
const params = remoteSearchParameters(query, options);
|
|
20612
22464
|
const result = parseRemoteSearch(await getJson(paths.search, params), query, params.limit);
|
|
20613
22465
|
if (requireSemantic && result.degraded) throw new RemoteBackendError("degraded-search");
|
|
@@ -20632,6 +22484,7 @@ function createRemoteBackend(config) {
|
|
|
20632
22484
|
},
|
|
20633
22485
|
rank: hit.score,
|
|
20634
22486
|
...hit.snippet === null ? {} : { snippet: hit.snippet },
|
|
22487
|
+
...hit.evidence === void 0 ? {} : { evidence: hit.evidence },
|
|
20635
22488
|
remoteSearch: {
|
|
20636
22489
|
...hit.title === void 0 ? {} : { title: hit.title },
|
|
20637
22490
|
...hit.tags === void 0 ? {} : { tags: hit.tags },
|
|
@@ -20688,6 +22541,8 @@ function createRemoteBackend(config) {
|
|
|
20688
22541
|
merge: false,
|
|
20689
22542
|
multiUser: true,
|
|
20690
22543
|
semantic: "server",
|
|
22544
|
+
typedMetadataPredicates: false,
|
|
22545
|
+
evidenceLocators: false,
|
|
20691
22546
|
startupCost: "network"
|
|
20692
22547
|
},
|
|
20693
22548
|
async listNotes(o) {
|
|
@@ -20715,6 +22570,20 @@ function createRemoteBackend(config) {
|
|
|
20715
22570
|
}
|
|
20716
22571
|
},
|
|
20717
22572
|
search: searchRemote,
|
|
22573
|
+
async resolveEvidence(locator, options) {
|
|
22574
|
+
return resolveRemoteEvidence(locator, options, async (body, signal) => {
|
|
22575
|
+
const headers = await remoteHeaders(config, true);
|
|
22576
|
+
signal.throwIfAborted();
|
|
22577
|
+
return (config.fetchImpl ?? globalThis.fetch)(remoteUrl(config.baseUrl, paths.resolveEvidence ?? DEFAULT_REMOTE_PATHS.resolveEvidence), {
|
|
22578
|
+
method: "POST",
|
|
22579
|
+
headers,
|
|
22580
|
+
body,
|
|
22581
|
+
signal,
|
|
22582
|
+
cache: "no-store",
|
|
22583
|
+
redirect: "error"
|
|
22584
|
+
});
|
|
22585
|
+
});
|
|
22586
|
+
},
|
|
20718
22587
|
getNoteFull,
|
|
20719
22588
|
linksOf,
|
|
20720
22589
|
conceptsOf,
|
|
@@ -20784,6 +22653,8 @@ function createShardBackend(reader, options = {}) {
|
|
|
20784
22653
|
merge: false,
|
|
20785
22654
|
multiUser: false,
|
|
20786
22655
|
semantic,
|
|
22656
|
+
typedMetadataPredicates: false,
|
|
22657
|
+
evidenceLocators: false,
|
|
20787
22658
|
startupCost: "instant"
|
|
20788
22659
|
},
|
|
20789
22660
|
async listNotes(o) {
|
|
@@ -20795,6 +22666,7 @@ function createShardBackend(reader, options = {}) {
|
|
|
20795
22666
|
return n ? shardNoteToBackend(n) : null;
|
|
20796
22667
|
},
|
|
20797
22668
|
async search(query, o) {
|
|
22669
|
+
validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
|
|
20798
22670
|
const r = await reader.search(query, { ...o, rank: true, snippets: true });
|
|
20799
22671
|
const hits = r.rankedItems ? r.rankedItems.map((it) => ({
|
|
20800
22672
|
note: shardNoteToBackend(it.note),
|
|
@@ -21338,26 +23210,26 @@ function isRecord(value) {
|
|
|
21338
23210
|
function isSupportedState(value) {
|
|
21339
23211
|
return typeof value === "string" && FORTEMI_COMPATIBILITY_STATES.includes(value);
|
|
21340
23212
|
}
|
|
21341
|
-
function requireRecord(parent,
|
|
21342
|
-
const value = parent[
|
|
23213
|
+
function requireRecord(parent, key3, errors) {
|
|
23214
|
+
const value = parent[key3];
|
|
21343
23215
|
if (!isRecord(value)) {
|
|
21344
|
-
errors.push(`${
|
|
23216
|
+
errors.push(`${key3} must be an object`);
|
|
21345
23217
|
return null;
|
|
21346
23218
|
}
|
|
21347
23219
|
return value;
|
|
21348
23220
|
}
|
|
21349
|
-
function requireString(parent,
|
|
21350
|
-
const value = parent[
|
|
23221
|
+
function requireString(parent, key3, path, errors) {
|
|
23222
|
+
const value = parent[key3];
|
|
21351
23223
|
if (typeof value !== "string" || value.length === 0) {
|
|
21352
|
-
errors.push(`${path}.${
|
|
23224
|
+
errors.push(`${path}.${key3} must be a non-empty string`);
|
|
21353
23225
|
return null;
|
|
21354
23226
|
}
|
|
21355
23227
|
return value;
|
|
21356
23228
|
}
|
|
21357
|
-
function requireBoolean(parent,
|
|
21358
|
-
const value = parent[
|
|
23229
|
+
function requireBoolean(parent, key3, path, errors) {
|
|
23230
|
+
const value = parent[key3];
|
|
21359
23231
|
if (typeof value !== "boolean") {
|
|
21360
|
-
errors.push(`${path}.${
|
|
23232
|
+
errors.push(`${path}.${key3} must be a boolean`);
|
|
21361
23233
|
return null;
|
|
21362
23234
|
}
|
|
21363
23235
|
return value;
|
|
@@ -21407,24 +23279,24 @@ function validateFortemiCompatibilityResponse(raw) {
|
|
|
21407
23279
|
}
|
|
21408
23280
|
const capabilities = requireRecord(raw, "capabilities", errors);
|
|
21409
23281
|
if (capabilities) {
|
|
21410
|
-
for (const
|
|
21411
|
-
if (!isRecord(capabilities[
|
|
21412
|
-
errors.push(`capabilities.${
|
|
23282
|
+
for (const key3 of FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES) {
|
|
23283
|
+
if (!isRecord(capabilities[key3])) {
|
|
23284
|
+
errors.push(`capabilities.${key3} must be present as an object`);
|
|
21413
23285
|
}
|
|
21414
23286
|
}
|
|
21415
|
-
for (const [
|
|
23287
|
+
for (const [key3, value] of Object.entries(capabilities)) {
|
|
21416
23288
|
if (!isRecord(value)) {
|
|
21417
|
-
errors.push(`capabilities.${
|
|
23289
|
+
errors.push(`capabilities.${key3} must be an object`);
|
|
21418
23290
|
continue;
|
|
21419
23291
|
}
|
|
21420
23292
|
if (!isSupportedState(value.state)) {
|
|
21421
|
-
errors.push(`capabilities.${
|
|
23293
|
+
errors.push(`capabilities.${key3}.state must be one of ${FORTEMI_COMPATIBILITY_STATES.join(", ")}`);
|
|
21422
23294
|
}
|
|
21423
23295
|
if ("reason_code" in value && typeof value.reason_code !== "string") {
|
|
21424
|
-
errors.push(`capabilities.${
|
|
23296
|
+
errors.push(`capabilities.${key3}.reason_code must be a string when present`);
|
|
21425
23297
|
}
|
|
21426
23298
|
if (value.state !== "available" && !value.reason_code) {
|
|
21427
|
-
warnings.push(`capabilities.${
|
|
23299
|
+
warnings.push(`capabilities.${key3} is ${String(value.state)} without reason_code`);
|
|
21428
23300
|
}
|
|
21429
23301
|
}
|
|
21430
23302
|
}
|
|
@@ -21443,7 +23315,7 @@ function validateFortemiCompatibilityResponse(raw) {
|
|
|
21443
23315
|
};
|
|
21444
23316
|
}
|
|
21445
23317
|
function formatFortemiCompatibilitySummary(response) {
|
|
21446
|
-
const capabilitySummary = Object.entries(response.capabilities).map(([
|
|
23318
|
+
const capabilitySummary = Object.entries(response.capabilities).map(([key3, value]) => `${key3}=${value.state}`).sort().join(", ");
|
|
21447
23319
|
return [
|
|
21448
23320
|
`Fortemi compatibility ${response.contract_revision}`,
|
|
21449
23321
|
`api=${response.api.name}@${response.api.version}`,
|
|
@@ -23756,7 +25628,7 @@ var CollectionsRepository = class {
|
|
|
23756
25628
|
|
|
23757
25629
|
// src/repositories/templates-repository.ts
|
|
23758
25630
|
init_geometry_buffer();
|
|
23759
|
-
function
|
|
25631
|
+
function validate2(record) {
|
|
23760
25632
|
if (!validateShardComponentRecord("templates", record, "full-v1", "2.0.0").valid) throw new Error("Invalid native template");
|
|
23761
25633
|
}
|
|
23762
25634
|
var TemplatesRepository = class {
|
|
@@ -23774,7 +25646,7 @@ var TemplatesRepository = class {
|
|
|
23774
25646
|
async create(input) {
|
|
23775
25647
|
const id = generateId();
|
|
23776
25648
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
23777
|
-
|
|
25649
|
+
validate2({
|
|
23778
25650
|
id,
|
|
23779
25651
|
name: input.name,
|
|
23780
25652
|
content: input.content,
|
|
@@ -23794,13 +25666,13 @@ var TemplatesRepository = class {
|
|
|
23794
25666
|
}
|
|
23795
25667
|
async update(id, input) {
|
|
23796
25668
|
const current = await this.get(id);
|
|
23797
|
-
|
|
25669
|
+
validate2({ ...current, ...Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0)) });
|
|
23798
25670
|
const values = [];
|
|
23799
25671
|
const assignments = ["updated_at = now()"];
|
|
23800
|
-
for (const
|
|
23801
|
-
if (input[
|
|
23802
|
-
values.push(
|
|
23803
|
-
assignments.push(`${
|
|
25672
|
+
for (const key3 of ["name", "content", "description", "format", "default_tags", "collection_id"]) {
|
|
25673
|
+
if (input[key3] === void 0) continue;
|
|
25674
|
+
values.push(key3 === "default_tags" ? JSON.stringify(input[key3]) : input[key3]);
|
|
25675
|
+
assignments.push(`${key3} = $${values.length}${key3 === "default_tags" ? "::jsonb" : ""}`);
|
|
23804
25676
|
}
|
|
23805
25677
|
values.push(id);
|
|
23806
25678
|
await this.db.query(`UPDATE template SET ${assignments.join(", ")} WHERE id = $${values.length}`, values);
|
|
@@ -23961,8 +25833,8 @@ async function removeOmittedNativeSkos(tx, state, selectedNoteIds3) {
|
|
|
23961
25833
|
await tx.query(
|
|
23962
25834
|
`DELETE FROM ${table} existing WHERE existing.${owner} = ANY($1::text[])
|
|
23963
25835
|
AND NOT EXISTS (SELECT 1 FROM UNNEST(${keys.map((_, index) => `$${index + 2}::text[]`).join(", ")}) incoming(${keys.join(", ")})
|
|
23964
|
-
WHERE ${keys.map((
|
|
23965
|
-
[selected, ...keys.map((
|
|
25836
|
+
WHERE ${keys.map((key3) => `incoming.${key3} = existing.${key3}`).join(" AND ")})`,
|
|
25837
|
+
[selected, ...keys.map((key3) => incoming.map((row) => nativeUuid(row[key3])))]
|
|
23966
25838
|
);
|
|
23967
25839
|
}
|
|
23968
25840
|
}
|
|
@@ -24501,8 +26373,8 @@ async function captureKnowledge(db, rawInput, events) {
|
|
|
24501
26373
|
if (!input.template) throw new Error("template is required for from_template action");
|
|
24502
26374
|
let content = input.template;
|
|
24503
26375
|
if (input.variables) {
|
|
24504
|
-
for (const [
|
|
24505
|
-
content = content.replaceAll(`{{${
|
|
26376
|
+
for (const [key3, value] of Object.entries(input.variables)) {
|
|
26377
|
+
content = content.replaceAll(`{{${key3}}}`, value);
|
|
24506
26378
|
}
|
|
24507
26379
|
}
|
|
24508
26380
|
const note = await repo.create({
|
|
@@ -24528,6 +26400,9 @@ async function searchTool(db, rawInput) {
|
|
|
24528
26400
|
}
|
|
24529
26401
|
const repo = new SearchRepository(db, semanticAvailable);
|
|
24530
26402
|
return repo.search(input.query, {
|
|
26403
|
+
metadataPredicates: input.metadataPredicates,
|
|
26404
|
+
tenant_id: input.tenant_id,
|
|
26405
|
+
archive_id: input.archive_id,
|
|
24531
26406
|
limit: input.limit,
|
|
24532
26407
|
offset: input.offset,
|
|
24533
26408
|
mode: input.mode,
|
|
@@ -24552,10 +26427,10 @@ function zodToJsonSchema(schema) {
|
|
|
24552
26427
|
const shape = schema.shape;
|
|
24553
26428
|
const properties = {};
|
|
24554
26429
|
const required = [];
|
|
24555
|
-
for (const [
|
|
24556
|
-
properties[
|
|
26430
|
+
for (const [key3, value] of Object.entries(shape)) {
|
|
26431
|
+
properties[key3] = resolvePropertySchema(value);
|
|
24557
26432
|
if (!(value instanceof z.ZodOptional) && !(value instanceof z.ZodDefault)) {
|
|
24558
|
-
required.push(
|
|
26433
|
+
required.push(key3);
|
|
24559
26434
|
}
|
|
24560
26435
|
}
|
|
24561
26436
|
return {
|
|
@@ -26619,13 +28494,13 @@ var OpenAICompatibleProvider = class {
|
|
|
26619
28494
|
throw new Error("Streaming not supported: response body is null");
|
|
26620
28495
|
}
|
|
26621
28496
|
const reader = response.body.getReader();
|
|
26622
|
-
const
|
|
28497
|
+
const decoder10 = new TextDecoder();
|
|
26623
28498
|
let buffer = "";
|
|
26624
28499
|
try {
|
|
26625
28500
|
while (true) {
|
|
26626
28501
|
const { done, value } = await reader.read();
|
|
26627
28502
|
if (done) break;
|
|
26628
|
-
buffer +=
|
|
28503
|
+
buffer += decoder10.decode(value, { stream: true });
|
|
26629
28504
|
const lines = buffer.split("\n");
|
|
26630
28505
|
buffer = lines.pop() ?? "";
|
|
26631
28506
|
for (const line of lines) {
|
|
@@ -27686,8 +29561,8 @@ var AllowlistTrustStore = class {
|
|
|
27686
29561
|
}
|
|
27687
29562
|
/** Mark a key revoked without removing it (still resolvable, verdict `revoked`). */
|
|
27688
29563
|
revoke(keyId) {
|
|
27689
|
-
const
|
|
27690
|
-
if (
|
|
29564
|
+
const key3 = this.keys.get(keyId);
|
|
29565
|
+
if (key3) this.keys.set(keyId, { ...key3, revoked: true });
|
|
27691
29566
|
}
|
|
27692
29567
|
};
|
|
27693
29568
|
function base64urlToBytes(s) {
|
|
@@ -27775,7 +29650,7 @@ async function verifyShardSignature(input) {
|
|
|
27775
29650
|
};
|
|
27776
29651
|
let signatureValid = false;
|
|
27777
29652
|
try {
|
|
27778
|
-
const
|
|
29653
|
+
const key3 = await globalThis.crypto.subtle.importKey(
|
|
27779
29654
|
"raw",
|
|
27780
29655
|
toBufferSource(base64urlToBytes(trusted.public_key)),
|
|
27781
29656
|
{ name: "Ed25519" },
|
|
@@ -27785,7 +29660,7 @@ async function verifyShardSignature(input) {
|
|
|
27785
29660
|
const digest2 = await sha256Hex(canonicalPayloadBytes(payload));
|
|
27786
29661
|
signatureValid = await globalThis.crypto.subtle.verify(
|
|
27787
29662
|
"Ed25519",
|
|
27788
|
-
|
|
29663
|
+
key3,
|
|
27789
29664
|
toBufferSource(base64urlToBytes(envelope.signature)),
|
|
27790
29665
|
toBufferSource(new TextEncoder().encode(digest2))
|
|
27791
29666
|
);
|
|
@@ -36398,8 +38273,8 @@ function classifyPresenceValue(value) {
|
|
|
36398
38273
|
function classifyOwnProperty(document2, pointer) {
|
|
36399
38274
|
const resolved = parentAndKey(document2, pointer, false);
|
|
36400
38275
|
if (!resolved) return "absent";
|
|
36401
|
-
const { parent, key:
|
|
36402
|
-
return Object.hasOwn(parent,
|
|
38276
|
+
const { parent, key: key3 } = resolved;
|
|
38277
|
+
return Object.hasOwn(parent, key3) ? classifyPresenceValue(parent[key3]) : "absent";
|
|
36403
38278
|
}
|
|
36404
38279
|
function capturePresence(document2, pointers) {
|
|
36405
38280
|
return Object.fromEntries(pointers.flatMap(
|
|
@@ -36451,14 +38326,14 @@ function restoreStoredPresence(document2, presence) {
|
|
|
36451
38326
|
for (const [pointer, stored] of Object.entries(presence)) {
|
|
36452
38327
|
const resolved = parentAndKey(restored, pointer);
|
|
36453
38328
|
if (!resolved) throw new Error(`JSON Pointer '${pointer}' parent is not an object`);
|
|
36454
|
-
const { parent, key:
|
|
38329
|
+
const { parent, key: key3 } = resolved;
|
|
36455
38330
|
if (stored === "legacy-indeterminate") {
|
|
36456
38331
|
throw new Error(`Cannot emit schema 2.0 with legacy-indeterminate state at ${pointer}`);
|
|
36457
38332
|
}
|
|
36458
38333
|
if (stored === "absent") {
|
|
36459
|
-
delete parent[
|
|
38334
|
+
delete parent[key3];
|
|
36460
38335
|
} else if (stored === "null") {
|
|
36461
|
-
parent[
|
|
38336
|
+
parent[key3] = null;
|
|
36462
38337
|
} else if (classifyOwnProperty(restored, pointer) !== stored) {
|
|
36463
38338
|
throw new Error(`Stored ${stored} state at ${pointer} does not match the persisted value`);
|
|
36464
38339
|
}
|
|
@@ -36777,7 +38652,7 @@ var rowKey = (component, row) => nativeIdentityKey(nativeIdentities[component],
|
|
|
36777
38652
|
function canonical(value) {
|
|
36778
38653
|
if (Array.isArray(value)) return value.map(canonical);
|
|
36779
38654
|
if (value !== null && typeof value === "object") return Object.fromEntries(
|
|
36780
|
-
Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([
|
|
38655
|
+
Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key3, item]) => [key3, canonical(item)])
|
|
36781
38656
|
);
|
|
36782
38657
|
return value;
|
|
36783
38658
|
}
|
|
@@ -36839,7 +38714,7 @@ async function readNativeLineage(tx, state) {
|
|
|
36839
38714
|
|
|
36840
38715
|
// src/shard/live-full-v1.ts
|
|
36841
38716
|
var components2 = Object.keys(FULL_V1_COMPONENT_FILES);
|
|
36842
|
-
var
|
|
38717
|
+
var encoder4 = new TextEncoder();
|
|
36843
38718
|
var scoped = (values) => values ? [...values] : void 0;
|
|
36844
38719
|
var ids = (rows) => new Set(rows.map((row) => row.id));
|
|
36845
38720
|
var nullableIn = (set, value) => value === null || set.has(value);
|
|
@@ -37175,7 +39050,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37175
39050
|
for (const component of components2) {
|
|
37176
39051
|
const spec = FULL_V1_COMPONENT_FILES[component];
|
|
37177
39052
|
const rows = state[component];
|
|
37178
|
-
const bytes =
|
|
39053
|
+
const bytes = encoder4.encode(spec.encoding === "json-array" ? JSON.stringify(rows) : rows.map((row) => JSON.stringify(row)).join("\n"));
|
|
37179
39054
|
files.set(spec.file, bytes);
|
|
37180
39055
|
counts[component] = rows.length;
|
|
37181
39056
|
checksums[spec.file] = await sha256Hex(bytes);
|
|
@@ -37214,7 +39089,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37214
39089
|
capability = { ...capability, losses: manifestLosses };
|
|
37215
39090
|
return failure2("Generated live full-v1 manifest violates presence authority.");
|
|
37216
39091
|
}
|
|
37217
|
-
files.set("manifest.json",
|
|
39092
|
+
files.set("manifest.json", encoder4.encode(JSON.stringify(manifest, null, 2)));
|
|
37218
39093
|
for (const note of state.notes) for (const { attachment } of note.attachments) {
|
|
37219
39094
|
const path = sidecarEntryName(attachment.checksum);
|
|
37220
39095
|
if (files.has(path)) continue;
|
|
@@ -37237,7 +39112,7 @@ async function exportLiveFullV1(db, options) {
|
|
|
37237
39112
|
}
|
|
37238
39113
|
|
|
37239
39114
|
// src/shard/shard-export.ts
|
|
37240
|
-
var
|
|
39115
|
+
var encoder5 = new TextEncoder();
|
|
37241
39116
|
var CORE_V1_FILES = /* @__PURE__ */ new Set([
|
|
37242
39117
|
"notes.jsonl",
|
|
37243
39118
|
"collections.json",
|
|
@@ -37643,11 +39518,11 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37643
39518
|
const slice = shardNotes.slice(offset, offset + clusterSize);
|
|
37644
39519
|
const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
|
|
37645
39520
|
clusters.push({ href, offset });
|
|
37646
|
-
files.set(href,
|
|
39521
|
+
files.set(href, encoder5.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
|
|
37647
39522
|
}
|
|
37648
39523
|
layout = { clusters: { notes: clusters } };
|
|
37649
39524
|
} else {
|
|
37650
|
-
files.set("notes.jsonl",
|
|
39525
|
+
files.set("notes.jsonl", encoder5.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
|
|
37651
39526
|
}
|
|
37652
39527
|
components4.push("notes");
|
|
37653
39528
|
counts.notes = notes.length;
|
|
@@ -37675,7 +39550,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37675
39550
|
mode?.nativeSchema2Presence
|
|
37676
39551
|
);
|
|
37677
39552
|
}
|
|
37678
|
-
files.set("collections.json",
|
|
39553
|
+
files.set("collections.json", encoder5.encode(JSON.stringify(shardCollections)));
|
|
37679
39554
|
components4.push("collections");
|
|
37680
39555
|
counts.collections = shardCollections.length;
|
|
37681
39556
|
const allTagRows = await db.query(
|
|
@@ -37691,7 +39566,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37691
39566
|
const shardTags = tagsToShard(
|
|
37692
39567
|
relevantTags.map((r) => ({ name: r.tag, created_at: r.created_at }))
|
|
37693
39568
|
);
|
|
37694
|
-
files.set("tags.json",
|
|
39569
|
+
files.set("tags.json", encoder5.encode(JSON.stringify(shardTags)));
|
|
37695
39570
|
components4.push("tags");
|
|
37696
39571
|
counts.tags = shardTags.length;
|
|
37697
39572
|
const templateRows = await db.query(`SELECT * FROM template ORDER BY created_at, id`);
|
|
@@ -37707,7 +39582,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37707
39582
|
mode?.nativeSchema2Presence
|
|
37708
39583
|
);
|
|
37709
39584
|
}
|
|
37710
|
-
files.set("templates.json",
|
|
39585
|
+
files.set("templates.json", encoder5.encode(JSON.stringify(shardTemplates)));
|
|
37711
39586
|
components4.push("templates");
|
|
37712
39587
|
counts.templates = shardTemplates.length;
|
|
37713
39588
|
}
|
|
@@ -37732,7 +39607,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37732
39607
|
);
|
|
37733
39608
|
}
|
|
37734
39609
|
const linksJsonl = shardLinks.map((l) => JSON.stringify(l)).join("\n");
|
|
37735
|
-
files.set("links.jsonl",
|
|
39610
|
+
files.set("links.jsonl", encoder5.encode(linksJsonl));
|
|
37736
39611
|
components4.push("links");
|
|
37737
39612
|
counts.links = shardLinks.length;
|
|
37738
39613
|
const allNoteSkosRows = await db.query(`SELECT * FROM note_skos_tag ORDER BY created_at`);
|
|
@@ -37749,25 +39624,25 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37749
39624
|
(row) => exportedConceptIds.has(row.source_concept_id) && exportedConceptIds.has(row.target_concept_id)
|
|
37750
39625
|
) : allRelationRows.rows;
|
|
37751
39626
|
const shardSkosSchemes = filteredSchemeRows.map(skosSchemeToShard);
|
|
37752
|
-
files.set("skos_schemes.json",
|
|
39627
|
+
files.set("skos_schemes.json", encoder5.encode(JSON.stringify(shardSkosSchemes)));
|
|
37753
39628
|
components4.push("skos_schemes");
|
|
37754
39629
|
counts.skos_schemes = shardSkosSchemes.length;
|
|
37755
39630
|
const shardSkosConcepts = filteredConceptRows.map(skosConceptToShard);
|
|
37756
|
-
files.set("skos_concepts.json",
|
|
39631
|
+
files.set("skos_concepts.json", encoder5.encode(JSON.stringify(shardSkosConcepts)));
|
|
37757
39632
|
components4.push("skos_concepts");
|
|
37758
39633
|
counts.skos_concepts = shardSkosConcepts.length;
|
|
37759
39634
|
const skosRelationsJsonl = filteredRelationRows.map((row) => JSON.stringify(skosRelationToShard(row))).join("\n");
|
|
37760
|
-
files.set("skos_relations.jsonl",
|
|
39635
|
+
files.set("skos_relations.jsonl", encoder5.encode(skosRelationsJsonl));
|
|
37761
39636
|
components4.push("skos_relations");
|
|
37762
39637
|
counts.skos_relations = filteredRelationRows.length;
|
|
37763
39638
|
const noteSkosJsonl = filteredNoteSkosRows.map((row) => JSON.stringify(noteSkosTagToShard(row))).join("\n");
|
|
37764
|
-
files.set("note_skos_tags.jsonl",
|
|
39639
|
+
files.set("note_skos_tags.jsonl", encoder5.encode(noteSkosJsonl));
|
|
37765
39640
|
components4.push("note_skos_tags");
|
|
37766
39641
|
counts.note_skos_tags = filteredNoteSkosRows.length;
|
|
37767
39642
|
const provenanceRows = await db.query(`SELECT * FROM provenance_edge ORDER BY started_at`);
|
|
37768
39643
|
const filteredProvenanceRows = isFiltered ? provenanceRows.rows.filter((row) => row.entity_type !== "note" || exportedNoteIds.has(row.entity_id)) : provenanceRows.rows;
|
|
37769
39644
|
const provenanceJsonl = filteredProvenanceRows.map((row) => JSON.stringify(provenanceEdgeToShard(row))).join("\n");
|
|
37770
|
-
files.set("provenance_edges.jsonl",
|
|
39645
|
+
files.set("provenance_edges.jsonl", encoder5.encode(provenanceJsonl));
|
|
37771
39646
|
components4.push("provenance_edges");
|
|
37772
39647
|
counts.provenance_edges = filteredProvenanceRows.length;
|
|
37773
39648
|
if (options?.includeEmbeddings) {
|
|
@@ -37807,7 +39682,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37807
39682
|
freshness_json: { status: "unknown" }
|
|
37808
39683
|
} : row
|
|
37809
39684
|
));
|
|
37810
|
-
files.set("embedding_sets.json",
|
|
39685
|
+
files.set("embedding_sets.json", encoder5.encode(JSON.stringify(shardEmbSets)));
|
|
37811
39686
|
components4.push("embedding_sets");
|
|
37812
39687
|
counts.embedding_sets = shardEmbSets.length;
|
|
37813
39688
|
const embeddingConfigRows = await db.query(
|
|
@@ -37817,7 +39692,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37817
39692
|
);
|
|
37818
39693
|
if (embeddingConfigRows.rows.length > 0) {
|
|
37819
39694
|
const shardEmbeddingConfigs = embeddingConfigRows.rows.map((row) => embeddingConfigToShard(row));
|
|
37820
|
-
files.set("embedding_configs.json",
|
|
39695
|
+
files.set("embedding_configs.json", encoder5.encode(JSON.stringify(shardEmbeddingConfigs)));
|
|
37821
39696
|
components4.push("embedding_configs");
|
|
37822
39697
|
counts.embedding_configs = shardEmbeddingConfigs.length;
|
|
37823
39698
|
}
|
|
@@ -37830,7 +39705,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37830
39705
|
(member) => exportedSetIds.has(member.embedding_set_id) && exportedNoteIds.has(member.note_id) && (includeMaterializedSelectors || !virtualSetIds.has(member.embedding_set_id))
|
|
37831
39706
|
);
|
|
37832
39707
|
const membersJsonl = scopedEmbMemberRows.map((m) => JSON.stringify(embeddingSetMemberToShard(m))).join("\n");
|
|
37833
|
-
files.set("embedding_set_members.jsonl",
|
|
39708
|
+
files.set("embedding_set_members.jsonl", encoder5.encode(membersJsonl));
|
|
37834
39709
|
components4.push("embedding_set_members");
|
|
37835
39710
|
counts.embedding_set_members = scopedEmbMemberRows.length;
|
|
37836
39711
|
const embRows = await db.query(
|
|
@@ -37856,7 +39731,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37856
39731
|
(embedding) => exportedSetIds.has(embedding.embedding_set_id) && exportedNoteIds.has(embedding.note_id) && (memberEmbeddingIds.size === 0 || memberEmbeddingIds.has(embedding.id))
|
|
37857
39732
|
);
|
|
37858
39733
|
const embJsonl = scopedEmbRows.map((e) => JSON.stringify(embeddingToShard(e))).join("\n");
|
|
37859
|
-
files.set("embeddings.jsonl",
|
|
39734
|
+
files.set("embeddings.jsonl", encoder5.encode(embJsonl));
|
|
37860
39735
|
components4.push("embeddings");
|
|
37861
39736
|
counts.embeddings = scopedEmbRows.length;
|
|
37862
39737
|
}
|
|
@@ -37882,7 +39757,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37882
39757
|
freshness: jsonObject3(row.freshness_json) ?? { status: "unknown" },
|
|
37883
39758
|
created_at: iso2(row.created_at)
|
|
37884
39759
|
}));
|
|
37885
|
-
files.set("graph_sources.json",
|
|
39760
|
+
files.set("graph_sources.json", encoder5.encode(JSON.stringify(shardGraphSources)));
|
|
37886
39761
|
components4.push("graph_sources");
|
|
37887
39762
|
counts.graph_sources = shardGraphSources.length;
|
|
37888
39763
|
}
|
|
@@ -37898,7 +39773,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37898
39773
|
rank: row.rank,
|
|
37899
39774
|
metadata: jsonObject3(row.metadata_json)
|
|
37900
39775
|
})).join("\n");
|
|
37901
|
-
files.set("graph_edges.jsonl",
|
|
39776
|
+
files.set("graph_edges.jsonl", encoder5.encode(graphEdgesJsonl));
|
|
37902
39777
|
components4.push("graph_edges");
|
|
37903
39778
|
counts.graph_edges = scopedGraphEdgeRows.length;
|
|
37904
39779
|
}
|
|
@@ -37934,7 +39809,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37934
39809
|
})),
|
|
37935
39810
|
created_at: iso2(row.created_at)
|
|
37936
39811
|
}));
|
|
37937
|
-
files.set("communities.json",
|
|
39812
|
+
files.set("communities.json", encoder5.encode(JSON.stringify(shardCommunitySets)));
|
|
37938
39813
|
components4.push("communities");
|
|
37939
39814
|
counts.community_sets = shardCommunitySets.length;
|
|
37940
39815
|
counts.communities = scopedCommunityRows.length;
|
|
@@ -37950,7 +39825,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37950
39825
|
source_type: row.source_type,
|
|
37951
39826
|
metadata: jsonObject3(row.metadata_json)
|
|
37952
39827
|
})).join("\n");
|
|
37953
|
-
files.set("community_assignments.jsonl",
|
|
39828
|
+
files.set("community_assignments.jsonl", encoder5.encode(assignmentsJsonl));
|
|
37954
39829
|
components4.push("community_assignments");
|
|
37955
39830
|
counts.community_assignments = scopedAssignmentRows.length;
|
|
37956
39831
|
}
|
|
@@ -37973,10 +39848,10 @@ async function exportShardBytes(db, options, mode) {
|
|
|
37973
39848
|
const coreTags = [...tagsByName.values()].sort(
|
|
37974
39849
|
(left, right) => left.name.localeCompare(right.name)
|
|
37975
39850
|
);
|
|
37976
|
-
files.set("tags.json",
|
|
39851
|
+
files.set("tags.json", encoder5.encode(JSON.stringify(coreTags)));
|
|
37977
39852
|
components4.splice(0, components4.length, ...CORE_V1_COMPONENTS);
|
|
37978
|
-
for (const
|
|
37979
|
-
if (!CORE_V1_COMPONENTS.includes(
|
|
39853
|
+
for (const key3 of Object.keys(counts)) {
|
|
39854
|
+
if (!CORE_V1_COMPONENTS.includes(key3)) delete counts[key3];
|
|
37980
39855
|
}
|
|
37981
39856
|
Object.assign(counts, {
|
|
37982
39857
|
notes: shardNotes.length,
|
|
@@ -38013,7 +39888,7 @@ async function exportShardBytes(db, options, mode) {
|
|
|
38013
39888
|
...!coreV1 ? { migrated_from: null } : {},
|
|
38014
39889
|
...!coreV1 && layout ? { layout } : {}
|
|
38015
39890
|
};
|
|
38016
|
-
files.set("manifest.json",
|
|
39891
|
+
files.set("manifest.json", encoder5.encode(JSON.stringify(manifest, null, 2)));
|
|
38017
39892
|
if (options?.includeBlobs && options.blobStore) {
|
|
38018
39893
|
const packed = /* @__PURE__ */ new Set();
|
|
38019
39894
|
for (const row of attachmentRows.rows) {
|
|
@@ -38038,14 +39913,14 @@ init_geometry_buffer();
|
|
|
38038
39913
|
|
|
38039
39914
|
// src/shard/parse.ts
|
|
38040
39915
|
init_geometry_buffer();
|
|
38041
|
-
var
|
|
39916
|
+
var decoder4 = new TextDecoder();
|
|
38042
39917
|
function parseJsonlBytes(data) {
|
|
38043
39918
|
if (!data || data.byteLength === 0) return [];
|
|
38044
|
-
return
|
|
39919
|
+
return decoder4.decode(data).split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
38045
39920
|
}
|
|
38046
39921
|
function parseJsonArrayBytes(data) {
|
|
38047
39922
|
if (!data || data.byteLength === 0) return [];
|
|
38048
|
-
return JSON.parse(
|
|
39923
|
+
return JSON.parse(decoder4.decode(data));
|
|
38049
39924
|
}
|
|
38050
39925
|
|
|
38051
39926
|
// src/shard/blob-staging.ts
|
|
@@ -38109,8 +39984,8 @@ async function promoteBlobs(blobStore, blobs) {
|
|
|
38109
39984
|
init_geometry_buffer();
|
|
38110
39985
|
function instant(value) {
|
|
38111
39986
|
if (value === null || value === void 0) return Number.NEGATIVE_INFINITY;
|
|
38112
|
-
const
|
|
38113
|
-
return Number.isNaN(
|
|
39987
|
+
const timestamp4 = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
39988
|
+
return Number.isNaN(timestamp4) ? Number.NEGATIVE_INFINITY : timestamp4;
|
|
38114
39989
|
}
|
|
38115
39990
|
function shouldApplyReplacement(existing, incoming) {
|
|
38116
39991
|
const existingDeleted = instant(existing.deleted_at);
|
|
@@ -38470,7 +40345,7 @@ async function importNativeFullV1(db, data, options = {}) {
|
|
|
38470
40345
|
}
|
|
38471
40346
|
|
|
38472
40347
|
// src/shard/shard-import.ts
|
|
38473
|
-
var
|
|
40348
|
+
var decoder5 = new TextDecoder();
|
|
38474
40349
|
var DEFAULT_BATCH_SIZE = 250;
|
|
38475
40350
|
function emptyCounts2() {
|
|
38476
40351
|
return {
|
|
@@ -38607,7 +40482,7 @@ async function importShard(db, data, options) {
|
|
|
38607
40482
|
}
|
|
38608
40483
|
let manifest;
|
|
38609
40484
|
try {
|
|
38610
|
-
manifest = JSON.parse(
|
|
40485
|
+
manifest = JSON.parse(decoder5.decode(manifestData));
|
|
38611
40486
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
38612
40487
|
throw new Error("manifest must be a JSON object");
|
|
38613
40488
|
}
|
|
@@ -38911,11 +40786,11 @@ async function importShard(db, data, options) {
|
|
|
38911
40786
|
}
|
|
38912
40787
|
}
|
|
38913
40788
|
}
|
|
38914
|
-
const skipExisting = async (
|
|
40789
|
+
const skipExisting = async (key3, sql, params) => {
|
|
38915
40790
|
if (strategy !== "skip") return false;
|
|
38916
40791
|
const existing = await tx.query(sql, params);
|
|
38917
40792
|
if (existing.rows.length === 0) return false;
|
|
38918
|
-
skipped[
|
|
40793
|
+
skipped[key3] = (skipped[key3] ?? 0) + 1;
|
|
38919
40794
|
return true;
|
|
38920
40795
|
};
|
|
38921
40796
|
const storePresence = async (component, recordId, record) => {
|
|
@@ -39839,8 +41714,8 @@ function slugifyServerEmbeddingSet(value) {
|
|
|
39839
41714
|
|
|
39840
41715
|
// src/shard/full-v1-store.ts
|
|
39841
41716
|
init_geometry_buffer();
|
|
39842
|
-
var
|
|
39843
|
-
var
|
|
41717
|
+
var decoder6 = new TextDecoder();
|
|
41718
|
+
var encoder6 = new TextEncoder();
|
|
39844
41719
|
function emptyCounts3() {
|
|
39845
41720
|
return {
|
|
39846
41721
|
notes: 0,
|
|
@@ -39894,12 +41769,12 @@ function componentRecords(component, bytes) {
|
|
|
39894
41769
|
function canonicalJson4(value) {
|
|
39895
41770
|
if (Array.isArray(value)) return `[${value.map(canonicalJson4).join(",")}]`;
|
|
39896
41771
|
if (value && typeof value === "object") {
|
|
39897
|
-
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([
|
|
41772
|
+
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key3, item]) => `${JSON.stringify(key3)}:${canonicalJson4(item)}`).join(",")}}`;
|
|
39898
41773
|
}
|
|
39899
41774
|
return JSON.stringify(value);
|
|
39900
41775
|
}
|
|
39901
41776
|
function encodeComponentRecords(component, records) {
|
|
39902
|
-
return
|
|
41777
|
+
return encoder6.encode(FULL_V1_COMPONENT_FILES[component].encoding === "json-array" ? JSON.stringify(records) : records.map((record) => JSON.stringify(record)).join("\n"));
|
|
39903
41778
|
}
|
|
39904
41779
|
function attachmentBlobReferences(files) {
|
|
39905
41780
|
const refs = /* @__PURE__ */ new Map();
|
|
@@ -39936,7 +41811,7 @@ async function importFullV1Snapshot(db, data, options) {
|
|
|
39936
41811
|
files = unpackTarGz(bytes);
|
|
39937
41812
|
const manifestBytes = files.get("manifest.json");
|
|
39938
41813
|
if (!manifestBytes) throw new Error("Missing manifest");
|
|
39939
|
-
const parsed2 = JSON.parse(
|
|
41814
|
+
const parsed2 = JSON.parse(decoder6.decode(manifestBytes));
|
|
39940
41815
|
if (!parsed2 || typeof parsed2 !== "object" || Array.isArray(parsed2)) {
|
|
39941
41816
|
throw new Error("Manifest is not an object");
|
|
39942
41817
|
}
|
|
@@ -40190,7 +42065,7 @@ async function exportFullV1Snapshot(db, blobStore) {
|
|
|
40190
42065
|
name: "fortemi-react-full-v1-store",
|
|
40191
42066
|
version: manifest.producer?.version ?? "unknown"
|
|
40192
42067
|
};
|
|
40193
|
-
files.set("manifest.json",
|
|
42068
|
+
files.set("manifest.json", encoder6.encode(JSON.stringify(manifest, null, 2)));
|
|
40194
42069
|
files.delete("signature.json");
|
|
40195
42070
|
blobRefs = attachmentBlobReferences(files);
|
|
40196
42071
|
} else {
|
|
@@ -40217,7 +42092,7 @@ async function exportFullV1Snapshot(db, blobStore) {
|
|
|
40217
42092
|
|
|
40218
42093
|
// src/shard/shard-reader.ts
|
|
40219
42094
|
init_geometry_buffer();
|
|
40220
|
-
var
|
|
42095
|
+
var decoder7 = new TextDecoder();
|
|
40221
42096
|
function assertSafeComponentName(filename) {
|
|
40222
42097
|
if (filename.length === 0 || filename.startsWith("/") || filename.includes("\\") || filename.includes("\0") || filename.includes(":") || filename.split("/").some((segment) => segment === "..")) {
|
|
40223
42098
|
throw new Error(`Refusing to read unsafe shard component path: ${JSON.stringify(filename)}`);
|
|
@@ -40319,7 +42194,7 @@ async function resolveStore(source, maxComponentBytes) {
|
|
|
40319
42194
|
const files = unpackTarGz(bytes);
|
|
40320
42195
|
const manifestBytes = files.get("manifest.json");
|
|
40321
42196
|
if (!manifestBytes) throw new Error("Missing manifest.json in shard archive");
|
|
40322
|
-
const manifest = JSON.parse(
|
|
42197
|
+
const manifest = JSON.parse(decoder7.decode(manifestBytes));
|
|
40323
42198
|
return new PackedComponentStore(files, manifest);
|
|
40324
42199
|
}
|
|
40325
42200
|
function tokenize(query) {
|
|
@@ -40456,14 +42331,14 @@ var ShardReaderImpl = class {
|
|
|
40456
42331
|
weights: { ...DEFAULT_WEIGHTS, ...options.weights }
|
|
40457
42332
|
});
|
|
40458
42333
|
}
|
|
40459
|
-
cacheMatches(
|
|
40460
|
-
this.matchCache.delete(
|
|
40461
|
-
this.matchCache.set(
|
|
42334
|
+
cacheMatches(key3, notes) {
|
|
42335
|
+
this.matchCache.delete(key3);
|
|
42336
|
+
this.matchCache.set(key3, notes);
|
|
40462
42337
|
let total = 0;
|
|
40463
42338
|
for (const set of this.matchCache.values()) total += set.length;
|
|
40464
42339
|
while (total > this.maxCachedMatches && this.matchCache.size > 1) {
|
|
40465
42340
|
const oldest = this.matchCache.keys().next().value;
|
|
40466
|
-
if (oldest === void 0 || oldest ===
|
|
42341
|
+
if (oldest === void 0 || oldest === key3) break;
|
|
40467
42342
|
total -= this.matchCache.get(oldest)?.length ?? 0;
|
|
40468
42343
|
this.matchCache.delete(oldest);
|
|
40469
42344
|
}
|
|
@@ -40473,12 +42348,12 @@ var ShardReaderImpl = class {
|
|
|
40473
42348
|
const weights = { ...DEFAULT_WEIGHTS, ...options.weights };
|
|
40474
42349
|
const offset = options.offset ?? 0;
|
|
40475
42350
|
const limit = options.limit ?? Number.MAX_SAFE_INTEGER;
|
|
40476
|
-
const
|
|
40477
|
-
let matched = this.matchCache.get(
|
|
42351
|
+
const key3 = this.matchKey(query, options);
|
|
42352
|
+
let matched = this.matchCache.get(key3);
|
|
40478
42353
|
let fetchedClusters = 0;
|
|
40479
42354
|
if (matched) {
|
|
40480
|
-
this.matchCache.delete(
|
|
40481
|
-
this.matchCache.set(
|
|
42355
|
+
this.matchCache.delete(key3);
|
|
42356
|
+
this.matchCache.set(key3, matched);
|
|
40482
42357
|
} else {
|
|
40483
42358
|
const { notes, fetched } = await this.loadAllNotes();
|
|
40484
42359
|
fetchedClusters = fetched;
|
|
@@ -40486,7 +42361,7 @@ var ShardReaderImpl = class {
|
|
|
40486
42361
|
if (tokens.length > 0 && options.rank !== false) {
|
|
40487
42362
|
matched = [...matched].sort((a, b) => rankNote(b, tokens, weights) - rankNote(a, tokens, weights));
|
|
40488
42363
|
}
|
|
40489
|
-
this.cacheMatches(
|
|
42364
|
+
this.cacheMatches(key3, matched);
|
|
40490
42365
|
}
|
|
40491
42366
|
const page = matched.slice(offset, offset + limit);
|
|
40492
42367
|
const result = {
|
|
@@ -40605,7 +42480,7 @@ async function openShard(source, options = {}) {
|
|
|
40605
42480
|
|
|
40606
42481
|
// src/shard/semantic-providers.ts
|
|
40607
42482
|
init_geometry_buffer();
|
|
40608
|
-
var
|
|
42483
|
+
var decoder8 = new TextDecoder();
|
|
40609
42484
|
function cosine(a, b) {
|
|
40610
42485
|
let dot = 0;
|
|
40611
42486
|
let normA = 0;
|
|
@@ -40629,7 +42504,7 @@ function createCosineSemanticProvider(options) {
|
|
|
40629
42504
|
vectors = [];
|
|
40630
42505
|
return;
|
|
40631
42506
|
}
|
|
40632
|
-
vectors =
|
|
42507
|
+
vectors = decoder8.decode(bytes).split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
40633
42508
|
},
|
|
40634
42509
|
async search(query, k) {
|
|
40635
42510
|
const queryVector = await options.embedQuery(query);
|
|
@@ -42165,14 +44040,14 @@ function matchSetCacheKey(q, options) {
|
|
|
42165
44040
|
weights: { ...DEFAULT_QUERY_WEIGHTS, ...options.weights }
|
|
42166
44041
|
});
|
|
42167
44042
|
}
|
|
42168
|
-
function cacheMatchEntries(runtime,
|
|
42169
|
-
runtime.matchCache.delete(
|
|
42170
|
-
runtime.matchCache.set(
|
|
44043
|
+
function cacheMatchEntries(runtime, key3, entries) {
|
|
44044
|
+
runtime.matchCache.delete(key3);
|
|
44045
|
+
runtime.matchCache.set(key3, entries);
|
|
42171
44046
|
let total = 0;
|
|
42172
44047
|
for (const set of runtime.matchCache.values()) total += set.length;
|
|
42173
44048
|
while (total > runtime.maxCachedMatches && runtime.matchCache.size > 1) {
|
|
42174
44049
|
const oldest = runtime.matchCache.keys().next().value;
|
|
42175
|
-
if (oldest === void 0 || oldest ===
|
|
44050
|
+
if (oldest === void 0 || oldest === key3) break;
|
|
42176
44051
|
total -= runtime.matchCache.get(oldest)?.length ?? 0;
|
|
42177
44052
|
runtime.matchCache.delete(oldest);
|
|
42178
44053
|
}
|
|
@@ -42185,15 +44060,15 @@ function getPartsForRange(manifest, offset, limit) {
|
|
|
42185
44060
|
return manifest.parts.filter((part) => part.count > 0 && part.offset < end && part.offset + part.count > offset);
|
|
42186
44061
|
}
|
|
42187
44062
|
async function loadChunkPart(runtime, part) {
|
|
42188
|
-
const
|
|
42189
|
-
const cached = runtime.partCache.get(
|
|
44063
|
+
const key3 = chunkPartCacheKey(part);
|
|
44064
|
+
const cached = runtime.partCache.get(key3);
|
|
42190
44065
|
if (cached) {
|
|
42191
|
-
runtime.partCache.delete(
|
|
42192
|
-
runtime.partCache.set(
|
|
44066
|
+
runtime.partCache.delete(key3);
|
|
44067
|
+
runtime.partCache.set(key3, cached);
|
|
42193
44068
|
return { part: cached, fetched: false };
|
|
42194
44069
|
}
|
|
42195
44070
|
const parsed = assertAiwgFortemiChunkPart(await runtime.loader(part, runtime.manifest), part, runtime.manifest);
|
|
42196
|
-
runtime.partCache.set(
|
|
44071
|
+
runtime.partCache.set(key3, parsed);
|
|
42197
44072
|
while (runtime.partCache.size > runtime.maxCachedParts) {
|
|
42198
44073
|
const oldest = runtime.partCache.keys().next().value;
|
|
42199
44074
|
if (oldest === void 0) break;
|
|
@@ -42618,10 +44493,10 @@ function aiwgFortemiIndexToCommunityGraph(index, options = {}) {
|
|
|
42618
44493
|
const kind = relationship.type;
|
|
42619
44494
|
const configuredWeight = Object.prototype.hasOwnProperty.call(relationshipWeights, kind) ? relationshipWeights[kind] : void 0;
|
|
42620
44495
|
const baseWeight = typeof configuredWeight === "number" && Number.isFinite(configuredWeight) ? configuredWeight : 1;
|
|
42621
|
-
const
|
|
42622
|
-
const existing = edgeCounts.get(
|
|
44496
|
+
const key3 = `${item.id}\0${relationship.target_id}\0${kind}`;
|
|
44497
|
+
const existing = edgeCounts.get(key3);
|
|
42623
44498
|
if (existing) existing.weight += baseWeight;
|
|
42624
|
-
else edgeCounts.set(
|
|
44499
|
+
else edgeCounts.set(key3, { source: item.id, target: relationship.target_id, kind, weight: baseWeight });
|
|
42625
44500
|
}
|
|
42626
44501
|
}
|
|
42627
44502
|
const communities = /* @__PURE__ */ new Map();
|
|
@@ -43361,7 +45236,7 @@ function getAiwgFortemiIndexExportSchema() {
|
|
|
43361
45236
|
}
|
|
43362
45237
|
function getAjv() {
|
|
43363
45238
|
if (!ajvInstance) {
|
|
43364
|
-
ajvInstance = new
|
|
45239
|
+
ajvInstance = new Ajv20206({
|
|
43365
45240
|
allErrors: true,
|
|
43366
45241
|
strict: false,
|
|
43367
45242
|
validateFormats: false
|
|
@@ -43406,7 +45281,7 @@ function getProjectedRecordValidator() {
|
|
|
43406
45281
|
return projectedRecordValidator;
|
|
43407
45282
|
}
|
|
43408
45283
|
function validateAiwgFortemiIndexExportSchema(value) {
|
|
43409
|
-
const
|
|
45284
|
+
const validate4 = getExportValidator();
|
|
43410
45285
|
const schemaValue = value && typeof value === "object" && Array.isArray(value.items) ? {
|
|
43411
45286
|
...value,
|
|
43412
45287
|
items: value.items.map((item) => {
|
|
@@ -43416,18 +45291,18 @@ function validateAiwgFortemiIndexExportSchema(value) {
|
|
|
43416
45291
|
return schemaRecord;
|
|
43417
45292
|
})
|
|
43418
45293
|
} : value;
|
|
43419
|
-
const valid =
|
|
43420
|
-
return { valid, errors: formatErrors2(
|
|
45294
|
+
const valid = validate4(schemaValue);
|
|
45295
|
+
return { valid, errors: formatErrors2(validate4.errors) };
|
|
43421
45296
|
}
|
|
43422
45297
|
function validateAiwgFortemiProjectedRecordSchema(value) {
|
|
43423
|
-
const
|
|
43424
|
-
const valid =
|
|
43425
|
-
return { valid, errors: formatErrors2(
|
|
45298
|
+
const validate4 = getProjectedRecordValidator();
|
|
45299
|
+
const valid = validate4(value);
|
|
45300
|
+
return { valid, errors: formatErrors2(validate4.errors) };
|
|
43426
45301
|
}
|
|
43427
45302
|
|
|
43428
45303
|
// src/aiwg-index-full-shard.ts
|
|
43429
45304
|
init_geometry_buffer();
|
|
43430
|
-
var
|
|
45305
|
+
var encoder7 = new TextEncoder();
|
|
43431
45306
|
var UUID_NAMESPACE = "7ab5d1f8-29d2-5e35-9e2f-3a45de171a9e";
|
|
43432
45307
|
function uuid5(kind, id) {
|
|
43433
45308
|
return v5(`${kind}:${id}`, UUID_NAMESPACE);
|
|
@@ -43435,7 +45310,7 @@ function uuid5(kind, id) {
|
|
|
43435
45310
|
function own(value, field) {
|
|
43436
45311
|
return Object.prototype.hasOwnProperty.call(value, field);
|
|
43437
45312
|
}
|
|
43438
|
-
function
|
|
45313
|
+
function timestamp3(value) {
|
|
43439
45314
|
if (!value || Number.isNaN(Date.parse(value))) return void 0;
|
|
43440
45315
|
return new Date(value).toISOString();
|
|
43441
45316
|
}
|
|
@@ -43443,7 +45318,7 @@ function addLoss(losses, code, message, details = {}) {
|
|
|
43443
45318
|
losses.push({ code, message, ...details });
|
|
43444
45319
|
}
|
|
43445
45320
|
function encode(values, encoding) {
|
|
43446
|
-
return
|
|
45321
|
+
return encoder7.encode(encoding === "json-array" ? JSON.stringify(values) : values.map((value) => JSON.stringify(value)).join("\n"));
|
|
43447
45322
|
}
|
|
43448
45323
|
function noteTitle(record, losses) {
|
|
43449
45324
|
if (own(record, "title")) return record.title ?? null;
|
|
@@ -43508,7 +45383,7 @@ function noteContent(record, losses) {
|
|
|
43508
45383
|
return "";
|
|
43509
45384
|
}
|
|
43510
45385
|
function createdAt(record, losses) {
|
|
43511
|
-
const source =
|
|
45386
|
+
const source = timestamp3(record.source.updated_at);
|
|
43512
45387
|
if (source) return source;
|
|
43513
45388
|
addLoss(
|
|
43514
45389
|
losses,
|
|
@@ -43538,7 +45413,7 @@ function schemeName(concept) {
|
|
|
43538
45413
|
}
|
|
43539
45414
|
async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
43540
45415
|
const losses = [];
|
|
43541
|
-
const exportedAt =
|
|
45416
|
+
const exportedAt = timestamp3(options.createdAt) ?? new Date(index.generated_at).toISOString();
|
|
43542
45417
|
const records = [...index.items].sort((a, b) => a.id.localeCompare(b.id));
|
|
43543
45418
|
const noteIds = new Map(records.map((record) => [record.id, uuid5("record", record.id)]));
|
|
43544
45419
|
const rows = /* @__PURE__ */ new Map();
|
|
@@ -43611,7 +45486,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43611
45486
|
tags: recordTags,
|
|
43612
45487
|
attachments: []
|
|
43613
45488
|
});
|
|
43614
|
-
const hash = await sha256Hex(
|
|
45489
|
+
const hash = await sha256Hex(encoder7.encode(content));
|
|
43615
45490
|
rows.get("note_originals").push({
|
|
43616
45491
|
id: uuid5("note-original", record.id),
|
|
43617
45492
|
note_id: noteId,
|
|
@@ -43633,9 +45508,9 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43633
45508
|
for (const record of records) {
|
|
43634
45509
|
for (const [position, relationship] of record.relationships.entries()) {
|
|
43635
45510
|
const target = noteIds.get(relationship.target_id) ?? null;
|
|
43636
|
-
const
|
|
45511
|
+
const key3 = `${record.id}\0${position}\0${relationship.type}\0${relationship.target_id}`;
|
|
43637
45512
|
rows.get("links").push({
|
|
43638
|
-
id: uuid5("relationship",
|
|
45513
|
+
id: uuid5("relationship", key3),
|
|
43639
45514
|
from_note_id: noteIds.get(record.id),
|
|
43640
45515
|
to_note_id: target,
|
|
43641
45516
|
to_url: target ? null : `aiwg://record/${encodeURIComponent(relationship.target_id)}`,
|
|
@@ -43703,7 +45578,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43703
45578
|
metric: null,
|
|
43704
45579
|
algorithm: null,
|
|
43705
45580
|
parameters: null,
|
|
43706
|
-
input_hash: `sha256:${await sha256Hex(
|
|
45581
|
+
input_hash: `sha256:${await sha256Hex(encoder7.encode(JSON.stringify(relationshipInput)))}`,
|
|
43707
45582
|
freshness: { status: "fresh", checked_at: exportedAt },
|
|
43708
45583
|
created_at: exportedAt
|
|
43709
45584
|
});
|
|
@@ -43792,7 +45667,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43792
45667
|
action: "omit"
|
|
43793
45668
|
}
|
|
43794
45669
|
);
|
|
43795
|
-
const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((
|
|
45670
|
+
const unmappedConceptMetadata = Object.keys(concept.metadata ?? {}).filter((key3) => key3 !== "domain");
|
|
43796
45671
|
if (unmappedConceptMetadata.length > 0) addLoss(
|
|
43797
45672
|
losses,
|
|
43798
45673
|
"aiwg-skos-metadata-unmapped",
|
|
@@ -43935,7 +45810,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43935
45810
|
}
|
|
43936
45811
|
for (const record of records) {
|
|
43937
45812
|
for (const [position, event] of (record.provenance_events ?? []).entries()) {
|
|
43938
|
-
const start =
|
|
45813
|
+
const start = timestamp3(event.started_at);
|
|
43939
45814
|
if (!start) addLoss(
|
|
43940
45815
|
losses,
|
|
43941
45816
|
"aiwg-provenance-start-unavailable",
|
|
@@ -43955,7 +45830,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
43955
45830
|
activity_type: event.activity,
|
|
43956
45831
|
model_name: event.agent ?? null,
|
|
43957
45832
|
started_at: start ?? new Date(record.updated_at).toISOString(),
|
|
43958
|
-
ended_at:
|
|
45833
|
+
ended_at: timestamp3(event.ended_at) ?? null,
|
|
43959
45834
|
metadata: {
|
|
43960
45835
|
source: event.source ?? null,
|
|
43961
45836
|
path: event.path ?? null,
|
|
@@ -44161,7 +46036,7 @@ async function convertAiwgIndexToFullV1(index, options = {}) {
|
|
|
44161
46036
|
checksums,
|
|
44162
46037
|
min_reader_version: "2.0.0"
|
|
44163
46038
|
};
|
|
44164
|
-
const manifestBytes =
|
|
46039
|
+
const manifestBytes = encoder7.encode(JSON.stringify(manifest, null, 2));
|
|
44165
46040
|
files.set("manifest.json", manifestBytes);
|
|
44166
46041
|
const validation = await validateFullV1ShardArchive(files);
|
|
44167
46042
|
if (!validation.valid) {
|
|
@@ -44441,7 +46316,7 @@ var RECORD_STORE_CAPABILITIES = {
|
|
|
44441
46316
|
sourceAddressedUpsert: true,
|
|
44442
46317
|
deletionReceipts: true,
|
|
44443
46318
|
typedMetadataPredicates: false,
|
|
44444
|
-
evidenceLocators:
|
|
46319
|
+
evidenceLocators: false,
|
|
44445
46320
|
fullTextSearch: false,
|
|
44446
46321
|
vectorSearch: false,
|
|
44447
46322
|
sqlJoins: false
|
|
@@ -44828,7 +46703,7 @@ var CanonicalNotesRepository = class {
|
|
|
44828
46703
|
* Bounded substring scan over title + revised content (case-insensitive).
|
|
44829
46704
|
* This is deliberately not ranked FTS — see `store.capabilities`.
|
|
44830
46705
|
*/
|
|
44831
|
-
async searchText(query, limit = 20) {
|
|
46706
|
+
async searchText(query, limit = 20, accept) {
|
|
44832
46707
|
const needle = query.toLowerCase();
|
|
44833
46708
|
const revised = new Map(
|
|
44834
46709
|
(await this.store.list("note_revised_current")).map((r) => [r.id, r.content])
|
|
@@ -44836,6 +46711,7 @@ var CanonicalNotesRepository = class {
|
|
|
44836
46711
|
const hits = [];
|
|
44837
46712
|
for (const note of await this.store.list("note")) {
|
|
44838
46713
|
if (note.deleted_at !== null) continue;
|
|
46714
|
+
if (accept && !accept(note)) continue;
|
|
44839
46715
|
const haystack = `${note.title ?? ""}
|
|
44840
46716
|
${revised.get(note.id) ?? ""}`.toLowerCase();
|
|
44841
46717
|
if (haystack.includes(needle)) {
|
|
@@ -45351,6 +47227,8 @@ function createRecordBackend(store, options = {}) {
|
|
|
45351
47227
|
// via importShardToRecords (record-shard.ts)
|
|
45352
47228
|
multiUser: false,
|
|
45353
47229
|
semantic: "none",
|
|
47230
|
+
typedMetadataPredicates: false,
|
|
47231
|
+
evidenceLocators: false,
|
|
45354
47232
|
startupCost: "instant"
|
|
45355
47233
|
},
|
|
45356
47234
|
async listNotes(o) {
|
|
@@ -45370,17 +47248,11 @@ function createRecordBackend(store, options = {}) {
|
|
|
45370
47248
|
return noteToBackend(view.note, view.tags);
|
|
45371
47249
|
},
|
|
45372
47250
|
async search(query, o) {
|
|
47251
|
+
validateBackendSearchOptions(o, { metadata: false, scope: false, modes: ["fts"] });
|
|
45373
47252
|
const offset = o?.offset ?? 0;
|
|
45374
47253
|
const limit = o?.limit ?? 20;
|
|
45375
|
-
let matched = await notes.searchText(query, offset + limit);
|
|
45376
|
-
if (o?.tags?.length) {
|
|
45377
|
-
const tags2 = await tagsByNote();
|
|
45378
|
-
matched = matched.filter((n) => o.tags.every((t) => (tags2.get(n.id) ?? []).includes(t)));
|
|
45379
|
-
}
|
|
45380
|
-
if (o?.source?.length) {
|
|
45381
|
-
matched = matched.filter((n) => o.source.includes(n.source));
|
|
45382
|
-
}
|
|
45383
47254
|
const tags = await tagsByNote();
|
|
47255
|
+
const matched = await notes.searchText(query, offset + limit, (n) => (!o?.tags?.length || o.tags.every((t) => (tags.get(n.id) ?? []).includes(t))) && (!o?.source?.length || o.source.includes(n.source)));
|
|
45384
47256
|
const hits = matched.slice(offset, offset + limit).map((n) => ({ note: noteToBackend(n, tags.get(n.id) ?? []) }));
|
|
45385
47257
|
return { hits, total: matched.length };
|
|
45386
47258
|
},
|
|
@@ -45438,8 +47310,8 @@ function createRecordBackend(store, options = {}) {
|
|
|
45438
47310
|
|
|
45439
47311
|
// src/records/record-shard.ts
|
|
45440
47312
|
init_geometry_buffer();
|
|
45441
|
-
var
|
|
45442
|
-
var
|
|
47313
|
+
var encoder8 = new TextEncoder();
|
|
47314
|
+
var decoder9 = new TextDecoder();
|
|
45443
47315
|
function emptyCounts4() {
|
|
45444
47316
|
return {
|
|
45445
47317
|
notes: 0,
|
|
@@ -45696,11 +47568,11 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
45696
47568
|
const slice = shardNotes.slice(offset, offset + clusterSize);
|
|
45697
47569
|
const href = `notes/${String(offset).padStart(6, "0")}.jsonl`;
|
|
45698
47570
|
clusters.push({ href, offset });
|
|
45699
|
-
files.set(href,
|
|
47571
|
+
files.set(href, encoder8.encode(slice.map((n) => JSON.stringify(n)).join("\n")));
|
|
45700
47572
|
}
|
|
45701
47573
|
layout = { clusters: { notes: clusters } };
|
|
45702
47574
|
} else {
|
|
45703
|
-
files.set("notes.jsonl",
|
|
47575
|
+
files.set("notes.jsonl", encoder8.encode(shardNotes.map((n) => JSON.stringify(n)).join("\n")));
|
|
45704
47576
|
}
|
|
45705
47577
|
components4.push("notes");
|
|
45706
47578
|
counts.notes = shardNotes.length;
|
|
@@ -45728,7 +47600,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
45728
47600
|
note_count: mapped.note_count ?? 0
|
|
45729
47601
|
};
|
|
45730
47602
|
});
|
|
45731
|
-
files.set("collections.json",
|
|
47603
|
+
files.set("collections.json", encoder8.encode(JSON.stringify(shardCollections)));
|
|
45732
47604
|
components4.push("collections");
|
|
45733
47605
|
counts.collections = shardCollections.length;
|
|
45734
47606
|
const distinctTags = [...new Set(
|
|
@@ -45745,7 +47617,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
45745
47617
|
created_at: tagCreatedAt.get(name) ?? (/* @__PURE__ */ new Date(0)).toISOString()
|
|
45746
47618
|
}))
|
|
45747
47619
|
);
|
|
45748
|
-
files.set("tags.json",
|
|
47620
|
+
files.set("tags.json", encoder8.encode(JSON.stringify(shardTags)));
|
|
45749
47621
|
components4.push("tags");
|
|
45750
47622
|
counts.tags = shardTags.length;
|
|
45751
47623
|
const links = await store.list("link");
|
|
@@ -45767,7 +47639,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
45767
47639
|
}
|
|
45768
47640
|
return shard;
|
|
45769
47641
|
});
|
|
45770
|
-
files.set("links.jsonl",
|
|
47642
|
+
files.set("links.jsonl", encoder8.encode(shardLinks.map((l) => JSON.stringify(l)).join("\n")));
|
|
45771
47643
|
components4.push("links");
|
|
45772
47644
|
counts.links = shardLinks.length;
|
|
45773
47645
|
const checksums = {};
|
|
@@ -45897,7 +47769,7 @@ async function buildRecordShardArchive(store, options, profile) {
|
|
|
45897
47769
|
);
|
|
45898
47770
|
}
|
|
45899
47771
|
}
|
|
45900
|
-
files.set("manifest.json",
|
|
47772
|
+
files.set("manifest.json", encoder8.encode(JSON.stringify(manifest, null, 2)));
|
|
45901
47773
|
if (options?.includeBlobs && options.blobStore) {
|
|
45902
47774
|
const packed = /* @__PURE__ */ new Set();
|
|
45903
47775
|
for (const checksum of exportedBlobChecksums) {
|
|
@@ -45977,7 +47849,7 @@ async function importShardToRecords(store, data, options) {
|
|
|
45977
47849
|
}
|
|
45978
47850
|
let manifest;
|
|
45979
47851
|
try {
|
|
45980
|
-
manifest = JSON.parse(
|
|
47852
|
+
manifest = JSON.parse(decoder9.decode(manifestData));
|
|
45981
47853
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
45982
47854
|
throw new Error("manifest must be a JSON object");
|
|
45983
47855
|
}
|
|
@@ -46114,8 +47986,8 @@ async function importShardToRecords(store, data, options) {
|
|
|
46114
47986
|
for (const component of manifest.components ?? []) {
|
|
46115
47987
|
if (UNSUPPORTED_COMPONENTS.includes(component)) {
|
|
46116
47988
|
const count2 = manifest.counts?.[component];
|
|
46117
|
-
const
|
|
46118
|
-
skipped[
|
|
47989
|
+
const key3 = component === "communities" ? "communities" : component;
|
|
47990
|
+
skipped[key3] = (skipped[key3] ?? 0) + (typeof count2 === "number" ? count2 : 0);
|
|
46119
47991
|
warnings.push(
|
|
46120
47992
|
`Shard component '${component}' is not supported by the canonical record tier and was skipped. Import into a PGlite-backed store to preserve it.`
|
|
46121
47993
|
);
|
|
@@ -46283,7 +48155,7 @@ async function importShardToRecords(store, data, options) {
|
|
|
46283
48155
|
id: existingOriginal?.id ?? generateId(),
|
|
46284
48156
|
note_id: note.id,
|
|
46285
48157
|
content: note.original_content,
|
|
46286
|
-
content_hash: computeHash(
|
|
48158
|
+
content_hash: computeHash(encoder8.encode(note.original_content)),
|
|
46287
48159
|
created_at: createdAt2
|
|
46288
48160
|
};
|
|
46289
48161
|
mutations.push({ op: "put", collection: "note_original", record: originalRecord });
|
|
@@ -46590,7 +48462,7 @@ async function upsertRecordStoreSources(store, items, options = {}) {
|
|
|
46590
48462
|
const requestDigest = sourceRequestDigest(items, options);
|
|
46591
48463
|
const batchId = options.batchId ?? deriveSourceBatchId(requestDigest);
|
|
46592
48464
|
const batchReason = batchId.length === 0 || batchId.length > 200 ? "invalid_batch_metadata" : JSON.stringify(options.checkpoint ?? {}).length > 65536 ? "checkpoint_too_large" : void 0;
|
|
46593
|
-
const validation =
|
|
48465
|
+
const validation = validate3(items, options.maxItems ?? 500, batchReason);
|
|
46594
48466
|
if (validation) return finish2(importRunId, batchId, options.dryRun === true, "rejected", validation, options.checkpoint);
|
|
46595
48467
|
const batches = await store.list("source_import_batch");
|
|
46596
48468
|
const prior = batches.find((batch2) => batch2.tenant_id === (items[0].source.tenant_id ?? "default") && batch2.archive_id === (items[0].source.archive_id ?? null) && batch2.namespace === items[0].source.namespace && batch2.batch_id === batchId);
|
|
@@ -46774,7 +48646,7 @@ function addUpdateMutations(mutations, item, identity, note, current, original,
|
|
|
46774
48646
|
mutations.push({ op: "put", collection: "note_revision", record: revision });
|
|
46775
48647
|
}
|
|
46776
48648
|
}
|
|
46777
|
-
function
|
|
48649
|
+
function validate3(items, maxItems, initialReason) {
|
|
46778
48650
|
let reason = initialReason ?? (items.length === 0 || items.length > maxItems ? "batch_size_out_of_bounds" : null);
|
|
46779
48651
|
const seen = /* @__PURE__ */ new Set();
|
|
46780
48652
|
const stableIds = /* @__PURE__ */ new Set();
|
|
@@ -46783,9 +48655,9 @@ function validate2(items, maxItems, initialReason) {
|
|
|
46783
48655
|
if ((item.source.source_id?.length ?? 0) > 500 || item.source.source_id === "" || (item.source.workspace_id?.length ?? 0) > 500 || item.source.workspace_id === "") reason ??= "invalid_batch_metadata";
|
|
46784
48656
|
if ((item.format ?? "markdown").length > 100 || (item.title?.length ?? 0) > 2e3 || JSON.stringify(item.metadata ?? {}).length > 262144) reason ??= "invalid_item";
|
|
46785
48657
|
if (item.content_digest && item.content_digest !== sourceContentDigest(item.content)) reason ??= "content_digest_mismatch";
|
|
46786
|
-
const
|
|
46787
|
-
if (seen.has(
|
|
46788
|
-
seen.add(
|
|
48658
|
+
const key3 = `${item.source.tenant_id}\0${item.source.archive_id ?? ""}\0${item.source.namespace}\0${item.source.external_id}`;
|
|
48659
|
+
if (seen.has(key3)) reason ??= "duplicate_external_id_in_batch";
|
|
48660
|
+
seen.add(key3);
|
|
46789
48661
|
if (item.source.caller_stable_id && stableIds.has(item.source.caller_stable_id)) reason ??= "caller_stable_id_conflict";
|
|
46790
48662
|
if (item.source.caller_stable_id) stableIds.add(item.source.caller_stable_id);
|
|
46791
48663
|
}
|
|
@@ -46917,7 +48789,7 @@ async function purgeRecordStoreGraph(store, selector, operationKey) {
|
|
|
46917
48789
|
}
|
|
46918
48790
|
|
|
46919
48791
|
// src/index.ts
|
|
46920
|
-
var VERSION = "2026.9.
|
|
48792
|
+
var VERSION = "2026.9.6";
|
|
46921
48793
|
/*! Bundled license information:
|
|
46922
48794
|
|
|
46923
48795
|
ieee754/index.js:
|
|
@@ -46932,6 +48804,6 @@ buffer/index.js:
|
|
|
46932
48804
|
*)
|
|
46933
48805
|
*/
|
|
46934
48806
|
|
|
46935
|
-
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportFullV1Snapshot, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreRequest, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
48807
|
+
export { AIWG_SCAN_REQUIRED_FIELDS, AllowlistTrustStore, ArchiveManager, AttachmentsRepository, BridgeInferenceProvider, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, CURRENT_SHARD_VERSION, CanonicalAttachmentsRepository, CanonicalNotesRepository, CapabilityManager, CaptureKnowledgeInputSchema, CollectionsRepository, CommunitiesRepository, DATASET_EXECUTION_CAPABILITY_IDS, DATASET_EXECUTION_CONTRACT, DATASET_EXECUTION_SCHEMA_VERSION, DATASET_INGEST_CONTRACT, DATASET_INGEST_SCHEMA_VERSION, DATASET_LINEAGE_CONTRACT, DATASET_LINEAGE_SCHEMA_VERSION, DATASET_MATERIALIZATION_CONTRACT, DATASET_MATERIALIZATION_KINDS, DATASET_MATERIALIZATION_SCHEMA_VERSION, DB_SNAPSHOT_SCHEMA_VERSION, DEFAULT_LARGE_DOCUMENT_CHARS, DEFAULT_LARGE_DOCUMENT_CHUNKS, DatasetIngestError, DatasetIngestExecutor, DatasetLineageLedger, DatasetMaterializationError, DbSnapshotVersionError, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, EmbeddingSetsRepository, FORTEMI_BROWSER_LOCAL_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_PORTABLE_SHARD_DATASET_EXECUTION_DESCRIPTOR, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, FORTEMI_STATIC_CACHE_DATASET_EXECUTION_DESCRIPTOR, FallbackRouter, FortemiToolManifest, GetNoteInputSchema, GraphRepository, IdbRecordStore, JOB_CAPABILITIES, JOB_PRIORITIES, JobQueueWorker, LINEAGE_ENTITY_KINDS, LINEAGE_RELATIONSHIP_KINDS, LOCAL_ENDPOINTS, LifecyclePurgeRepository, LineageValidationError, LinksRepository, ListNotesInputSchema, ManageArchiveInputSchema, ManageAttachmentsInputSchema, ManageCapabilitiesInputSchema, ManageCollectionsInputSchema, ManageLinksInputSchema, ManageNoteInputSchema, ManageTagsInputSchema, MemoryBlobStore, MemoryDatasetIngestStore, MemoryRecordStore, MigrationRunner, NotesRepository, OpenAICompatibleProvider, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, ProvenanceRepository, ProviderRegistry, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, RemoteBackendError, SHARD_FORMAT, SIGNATURE_ENTRY, SIGNING_ENVELOPE_VERSION, SOURCE_UPSERT_CONTRACT_VERSION, SOURCE_UPSERT_MAX_ITEMS, SUPPORTED_PGLITE_VERSION, SearchInputSchema, SearchRepository, SkosRepository, SourceUpsertRepository, TagsRepository, TemplatesRepository, TransactionProxy, TypedEventBus, VERSION, aiRevisionHandler, aiwgFortemiIndexFromKnowledgeShard, aiwgFortemiIndexToCommunityGraph, aiwgFortemiIndexToKnowledgeShard, aiwgFortemiIndexToKnowledgeShardWithReport, allMigrations, appendPluginScript, assertAiwgFortemiChunkManifest, assertAiwgFortemiChunkPart, assertAiwgFortemiIndexExport, assertAiwgStaticEmbeddingSet, assertShardComponentRecord, bindSearchEvidence, buildAiwgChunkedIndex, buildAiwgStaticEmbeddingSet, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, compareDatasetIncrementalParity, computeBlobHash, computeHash, computeLineageDigest, computeSri, conceptTaggingHandler, configureInferenceRuntime, cosineSimilarity, createAiwgFetchChunkLoader, createAiwgFetchDetailLoader, createAiwgIndexController, createAiwgReviewDecisionExport, createBlobStore, createBridgeInferenceProviders, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLazyBlobStore, createLegacyProvider, createLocalProviderProfile, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createSearchEvidenceSet, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, datasetDestinationScopeKey, defaultStorageBackendFactory, defineInferenceProvider, defineInferenceRuntime, defineLegacyInferenceProvider, defineOpenAICompatibleProvider, deriveDatasetIngestIdempotencyKey, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, digestDatasetMaterializationValue, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, executeDatasetMaterialization, executeDatasetRetrieval, exportFullV1Snapshot, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, filterAiwgRecordsByPrivacy, findAiwgStaticDuplicatePairs, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getAiwgFortemiFacets, getAiwgFortemiIndexExportSchema, getConfiguredInferenceProviderId, getEmbedFunction, getEmbeddingTaskSelectionOptions, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, getProviderRouteRequirementIssue, handleEmbedRequests, hasFortemiSecureSecrets, importFullV1Snapshot, importShard, importShardToRecords, inferInferenceTaskCapability, inferLocalEmbeddingDimensions, isPluginScriptAllowed, isShardPrefetched, isShardSigningSupported, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, mergeInferenceRuntimeConfigs, mergeSearchEvidenceSets, migrateLegacyBlobStore, negotiateDatasetExecutionCapabilities, negotiateDatasetExecutionCapabilitiesFromWire, negotiateDatasetMaterializationProfile, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, parseSearchEvidenceLocator, parseSearchEvidenceSet, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, providerSatisfiesRouteRequirements, purgeRecordStoreGraph, queryAiwgFortemiIndex, queryAiwgHybridIndex, queryAiwgSemanticIndex, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, resolveSearchEvidence, restoreDbSnapshot, searchTool, selectBackend, selectEmbeddingTask, selectLlmModel, setEmbedFunction, setEmbeddingTaskSelectionOptions, setLlmFunction, sha256Hex, sidecarBlobDigests, signShard, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreRequest, upsertRecordStoreSources, urlLinkToShard, validateAiwgFortemiChunkManifest, validateAiwgFortemiChunkPart, validateAiwgFortemiIndexExport, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema, validateAiwgStaticEmbeddingSet, validateChecksums, validateCoreV1ShardArchive, validateDatasetBenchmarkEvidence, validateDatasetExecutionDescriptor, validateDatasetExecutionRequest, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateProviderRoute, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifyShardSignature, verifySri };
|
|
46936
48808
|
//# sourceMappingURL=index.js.map
|
|
46937
48809
|
//# sourceMappingURL=index.js.map
|