@camstack/addon-post-analysis 1.2.45 → 1.2.46
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.
|
@@ -12169,8 +12169,15 @@ async function rebuildObjectEmbeddings(deps, options = {}) {
|
|
|
12169
12169
|
failed += 1;
|
|
12170
12170
|
continue;
|
|
12171
12171
|
}
|
|
12172
|
-
await deps.store(source, embedding);
|
|
12173
|
-
rebuilt += 1;
|
|
12172
|
+
const outcome = await deps.store(source, embedding);
|
|
12173
|
+
if (outcome === "persisted") rebuilt += 1;
|
|
12174
|
+
else {
|
|
12175
|
+
failed += 1;
|
|
12176
|
+
deps.logger.warn("embedding rebuild wrote nothing for a track", { meta: {
|
|
12177
|
+
trackId,
|
|
12178
|
+
outcome
|
|
12179
|
+
} });
|
|
12180
|
+
}
|
|
12174
12181
|
} catch (err) {
|
|
12175
12182
|
failed += 1;
|
|
12176
12183
|
deps.logger.warn("embedding rebuild failed for a track", { meta: {
|
|
@@ -20597,6 +20604,14 @@ var ObjectEmbeddingStore = class {
|
|
|
20597
20604
|
* write: the provider rejects an upsert into an index it has never seen. A
|
|
20598
20605
|
* dim change against a populated index is REFUSED rather than wiping it, so
|
|
20599
20606
|
* this failing is the signal that the encoder model changed.
|
|
20607
|
+
*
|
|
20608
|
+
* `declaredDim` caches the declaration, and that cache is per-PROCESS while
|
|
20609
|
+
* the index lives in whichever addon currently provides `vector-store`. When
|
|
20610
|
+
* the active provider changed under a running hub the cache stayed warm
|
|
20611
|
+
* against an index that no longer existed, and every write from then on threw
|
|
20612
|
+
* `index "object-clip" was never declared` — for hours, until the addon was
|
|
20613
|
+
* restarted by hand. So a failed write clears the cache (see
|
|
20614
|
+
* {@link upsertIfBetter}) and the next one re-declares.
|
|
20600
20615
|
*/
|
|
20601
20616
|
async ensureIndex(dim) {
|
|
20602
20617
|
if (this.declaredDim === dim) return true;
|
|
@@ -20628,33 +20643,49 @@ var ObjectEmbeddingStore = class {
|
|
|
20628
20643
|
* short-circuited, and every later pass silently wrote nothing while
|
|
20629
20644
|
* reporting hundreds rebuilt. Observed live — 214 "rebuilt" moved the index
|
|
20630
20645
|
* by 4 rows.
|
|
20646
|
+
*
|
|
20647
|
+
* ## Why this returns an outcome instead of `void`
|
|
20648
|
+
*
|
|
20649
|
+
* It used to return `void` and turn every failure into a warn. The rebuild
|
|
20650
|
+
* therefore counted a write the instant the call returned, and the second time
|
|
20651
|
+
* this class of bug appeared it produced `rebuilt: 704` against `indexed: 0` —
|
|
20652
|
+
* a progress number that was pure fiction while the real cause sat in a warn
|
|
20653
|
+
* nobody was reading. The caller now has to distinguish "written" from "logged
|
|
20654
|
+
* and dropped", because a counter that cannot reads as verification.
|
|
20631
20655
|
*/
|
|
20632
20656
|
async upsertIfBetter(input) {
|
|
20633
|
-
if (input.embedding.length === 0) return;
|
|
20634
|
-
if (!await this.ensureIndex(input.embedding.length)) return;
|
|
20657
|
+
if (input.embedding.length === 0) return "failed";
|
|
20658
|
+
if (!await this.ensureIndex(input.embedding.length)) return "failed";
|
|
20635
20659
|
try {
|
|
20636
20660
|
if (input.force !== true) {
|
|
20637
20661
|
const stored = (await this.vectorStore.getByIds.query({
|
|
20638
20662
|
index: OBJECT_CLIP_INDEX,
|
|
20639
20663
|
ids: [input.trackId]
|
|
20640
20664
|
})).items[0]?.metadata["confidence"];
|
|
20641
|
-
if (typeof stored === "number" && input.confidence <= stored) return;
|
|
20665
|
+
if (typeof stored === "number" && input.confidence <= stored) return "skipped";
|
|
20642
20666
|
}
|
|
20643
|
-
|
|
20644
|
-
index:
|
|
20667
|
+
const result = await this.vectorStore.upsert.mutate({
|
|
20668
|
+
index: OBJECT_CLIP_INDEX,
|
|
20645
20669
|
items: [{
|
|
20646
20670
|
id: input.trackId,
|
|
20647
20671
|
vector: require_dist.encodeVectorBase64(input.embedding),
|
|
20648
20672
|
metadata: metadataFor(input)
|
|
20649
20673
|
}]
|
|
20650
|
-
})).rejected > 0) this.logger.warn("object-embedding upsert rejected", {
|
|
20651
|
-
tags: { deviceId: input.deviceId },
|
|
20652
|
-
meta: {
|
|
20653
|
-
trackId: input.trackId,
|
|
20654
|
-
dim: input.embedding.length
|
|
20655
|
-
}
|
|
20656
20674
|
});
|
|
20675
|
+
if (result.upserted === 0) {
|
|
20676
|
+
this.logger.warn("object-embedding upsert rejected", {
|
|
20677
|
+
tags: { deviceId: input.deviceId },
|
|
20678
|
+
meta: {
|
|
20679
|
+
trackId: input.trackId,
|
|
20680
|
+
dim: input.embedding.length,
|
|
20681
|
+
rejected: result.rejected
|
|
20682
|
+
}
|
|
20683
|
+
});
|
|
20684
|
+
return "failed";
|
|
20685
|
+
}
|
|
20686
|
+
return "persisted";
|
|
20657
20687
|
} catch (err) {
|
|
20688
|
+
this.declaredDim = null;
|
|
20658
20689
|
this.logger.warn("ObjectEmbeddingStore.upsertIfBetter failed", {
|
|
20659
20690
|
tags: { deviceId: input.deviceId },
|
|
20660
20691
|
meta: {
|
|
@@ -20662,6 +20693,7 @@ var ObjectEmbeddingStore = class {
|
|
|
20662
20693
|
error: String(err)
|
|
20663
20694
|
}
|
|
20664
20695
|
});
|
|
20696
|
+
return "failed";
|
|
20665
20697
|
}
|
|
20666
20698
|
}
|
|
20667
20699
|
/**
|
|
@@ -27113,20 +27145,18 @@ var PipelineAnalyticsAddon = class extends require_dist.BaseAddon {
|
|
|
27113
27145
|
height
|
|
27114
27146
|
})).embedding;
|
|
27115
27147
|
},
|
|
27116
|
-
store: async (source, embedding) => {
|
|
27117
|
-
|
|
27118
|
-
|
|
27119
|
-
|
|
27120
|
-
|
|
27121
|
-
|
|
27122
|
-
|
|
27123
|
-
|
|
27124
|
-
|
|
27125
|
-
|
|
27126
|
-
|
|
27127
|
-
|
|
27128
|
-
});
|
|
27129
|
-
},
|
|
27148
|
+
store: async (source, embedding) => store.upsertIfBetter({
|
|
27149
|
+
trackId: source.trackId,
|
|
27150
|
+
deviceId: source.deviceId,
|
|
27151
|
+
timestamp: source.timestamp,
|
|
27152
|
+
className: source.className,
|
|
27153
|
+
embedding,
|
|
27154
|
+
modelId,
|
|
27155
|
+
confidence: source.confidence,
|
|
27156
|
+
force: true,
|
|
27157
|
+
...source.mediaKey !== void 0 ? { mediaKey: source.mediaKey } : {},
|
|
27158
|
+
...source.keyFrameMediaKey !== void 0 ? { keyFrameMediaKey: source.keyFrameMediaKey } : {}
|
|
27159
|
+
}),
|
|
27130
27160
|
logger: {
|
|
27131
27161
|
info: (message, extras) => this.ctx.logger.info(message, extras),
|
|
27132
27162
|
warn: (message, extras) => this.ctx.logger.warn(message, extras)
|
|
@@ -12163,8 +12163,15 @@ async function rebuildObjectEmbeddings(deps, options = {}) {
|
|
|
12163
12163
|
failed += 1;
|
|
12164
12164
|
continue;
|
|
12165
12165
|
}
|
|
12166
|
-
await deps.store(source, embedding);
|
|
12167
|
-
rebuilt += 1;
|
|
12166
|
+
const outcome = await deps.store(source, embedding);
|
|
12167
|
+
if (outcome === "persisted") rebuilt += 1;
|
|
12168
|
+
else {
|
|
12169
|
+
failed += 1;
|
|
12170
|
+
deps.logger.warn("embedding rebuild wrote nothing for a track", { meta: {
|
|
12171
|
+
trackId,
|
|
12172
|
+
outcome
|
|
12173
|
+
} });
|
|
12174
|
+
}
|
|
12168
12175
|
} catch (err) {
|
|
12169
12176
|
failed += 1;
|
|
12170
12177
|
deps.logger.warn("embedding rebuild failed for a track", { meta: {
|
|
@@ -20591,6 +20598,14 @@ var ObjectEmbeddingStore = class {
|
|
|
20591
20598
|
* write: the provider rejects an upsert into an index it has never seen. A
|
|
20592
20599
|
* dim change against a populated index is REFUSED rather than wiping it, so
|
|
20593
20600
|
* this failing is the signal that the encoder model changed.
|
|
20601
|
+
*
|
|
20602
|
+
* `declaredDim` caches the declaration, and that cache is per-PROCESS while
|
|
20603
|
+
* the index lives in whichever addon currently provides `vector-store`. When
|
|
20604
|
+
* the active provider changed under a running hub the cache stayed warm
|
|
20605
|
+
* against an index that no longer existed, and every write from then on threw
|
|
20606
|
+
* `index "object-clip" was never declared` — for hours, until the addon was
|
|
20607
|
+
* restarted by hand. So a failed write clears the cache (see
|
|
20608
|
+
* {@link upsertIfBetter}) and the next one re-declares.
|
|
20594
20609
|
*/
|
|
20595
20610
|
async ensureIndex(dim) {
|
|
20596
20611
|
if (this.declaredDim === dim) return true;
|
|
@@ -20622,33 +20637,49 @@ var ObjectEmbeddingStore = class {
|
|
|
20622
20637
|
* short-circuited, and every later pass silently wrote nothing while
|
|
20623
20638
|
* reporting hundreds rebuilt. Observed live — 214 "rebuilt" moved the index
|
|
20624
20639
|
* by 4 rows.
|
|
20640
|
+
*
|
|
20641
|
+
* ## Why this returns an outcome instead of `void`
|
|
20642
|
+
*
|
|
20643
|
+
* It used to return `void` and turn every failure into a warn. The rebuild
|
|
20644
|
+
* therefore counted a write the instant the call returned, and the second time
|
|
20645
|
+
* this class of bug appeared it produced `rebuilt: 704` against `indexed: 0` —
|
|
20646
|
+
* a progress number that was pure fiction while the real cause sat in a warn
|
|
20647
|
+
* nobody was reading. The caller now has to distinguish "written" from "logged
|
|
20648
|
+
* and dropped", because a counter that cannot reads as verification.
|
|
20625
20649
|
*/
|
|
20626
20650
|
async upsertIfBetter(input) {
|
|
20627
|
-
if (input.embedding.length === 0) return;
|
|
20628
|
-
if (!await this.ensureIndex(input.embedding.length)) return;
|
|
20651
|
+
if (input.embedding.length === 0) return "failed";
|
|
20652
|
+
if (!await this.ensureIndex(input.embedding.length)) return "failed";
|
|
20629
20653
|
try {
|
|
20630
20654
|
if (input.force !== true) {
|
|
20631
20655
|
const stored = (await this.vectorStore.getByIds.query({
|
|
20632
20656
|
index: OBJECT_CLIP_INDEX,
|
|
20633
20657
|
ids: [input.trackId]
|
|
20634
20658
|
})).items[0]?.metadata["confidence"];
|
|
20635
|
-
if (typeof stored === "number" && input.confidence <= stored) return;
|
|
20659
|
+
if (typeof stored === "number" && input.confidence <= stored) return "skipped";
|
|
20636
20660
|
}
|
|
20637
|
-
|
|
20638
|
-
index:
|
|
20661
|
+
const result = await this.vectorStore.upsert.mutate({
|
|
20662
|
+
index: OBJECT_CLIP_INDEX,
|
|
20639
20663
|
items: [{
|
|
20640
20664
|
id: input.trackId,
|
|
20641
20665
|
vector: encodeVectorBase64(input.embedding),
|
|
20642
20666
|
metadata: metadataFor(input)
|
|
20643
20667
|
}]
|
|
20644
|
-
})).rejected > 0) this.logger.warn("object-embedding upsert rejected", {
|
|
20645
|
-
tags: { deviceId: input.deviceId },
|
|
20646
|
-
meta: {
|
|
20647
|
-
trackId: input.trackId,
|
|
20648
|
-
dim: input.embedding.length
|
|
20649
|
-
}
|
|
20650
20668
|
});
|
|
20669
|
+
if (result.upserted === 0) {
|
|
20670
|
+
this.logger.warn("object-embedding upsert rejected", {
|
|
20671
|
+
tags: { deviceId: input.deviceId },
|
|
20672
|
+
meta: {
|
|
20673
|
+
trackId: input.trackId,
|
|
20674
|
+
dim: input.embedding.length,
|
|
20675
|
+
rejected: result.rejected
|
|
20676
|
+
}
|
|
20677
|
+
});
|
|
20678
|
+
return "failed";
|
|
20679
|
+
}
|
|
20680
|
+
return "persisted";
|
|
20651
20681
|
} catch (err) {
|
|
20682
|
+
this.declaredDim = null;
|
|
20652
20683
|
this.logger.warn("ObjectEmbeddingStore.upsertIfBetter failed", {
|
|
20653
20684
|
tags: { deviceId: input.deviceId },
|
|
20654
20685
|
meta: {
|
|
@@ -20656,6 +20687,7 @@ var ObjectEmbeddingStore = class {
|
|
|
20656
20687
|
error: String(err)
|
|
20657
20688
|
}
|
|
20658
20689
|
});
|
|
20690
|
+
return "failed";
|
|
20659
20691
|
}
|
|
20660
20692
|
}
|
|
20661
20693
|
/**
|
|
@@ -27107,20 +27139,18 @@ var PipelineAnalyticsAddon = class extends BaseAddon {
|
|
|
27107
27139
|
height
|
|
27108
27140
|
})).embedding;
|
|
27109
27141
|
},
|
|
27110
|
-
store: async (source, embedding) => {
|
|
27111
|
-
|
|
27112
|
-
|
|
27113
|
-
|
|
27114
|
-
|
|
27115
|
-
|
|
27116
|
-
|
|
27117
|
-
|
|
27118
|
-
|
|
27119
|
-
|
|
27120
|
-
|
|
27121
|
-
|
|
27122
|
-
});
|
|
27123
|
-
},
|
|
27142
|
+
store: async (source, embedding) => store.upsertIfBetter({
|
|
27143
|
+
trackId: source.trackId,
|
|
27144
|
+
deviceId: source.deviceId,
|
|
27145
|
+
timestamp: source.timestamp,
|
|
27146
|
+
className: source.className,
|
|
27147
|
+
embedding,
|
|
27148
|
+
modelId,
|
|
27149
|
+
confidence: source.confidence,
|
|
27150
|
+
force: true,
|
|
27151
|
+
...source.mediaKey !== void 0 ? { mediaKey: source.mediaKey } : {},
|
|
27152
|
+
...source.keyFrameMediaKey !== void 0 ? { keyFrameMediaKey: source.keyFrameMediaKey } : {}
|
|
27153
|
+
}),
|
|
27124
27154
|
logger: {
|
|
27125
27155
|
info: (message, extras) => this.ctx.logger.info(message, extras),
|
|
27126
27156
|
warn: (message, extras) => this.ctx.logger.warn(message, extras)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-post-analysis",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.46",
|
|
4
4
|
"description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -87,6 +87,12 @@
|
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
"name": "videoclips"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "face-gallery"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "plate-gallery"
|
|
90
96
|
}
|
|
91
97
|
],
|
|
92
98
|
"storageLocations": [
|