@camstack/addon-post-analysis 1.2.347 → 1.2.348

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (15) hide show
  1. package/dist/{clip-model-registry--UsI8Ud4.js → clip-model-registry-AqAEU7Eo.js} +1759 -147
  2. package/dist/{clip-model-registry-BftmbgcV.mjs → clip-model-registry-CrUfogC-.mjs} +1759 -147
  3. package/dist/embedding-encoder/index.js +1 -1
  4. package/dist/embedding-encoder/index.mjs +1 -1
  5. package/dist/pipeline-analytics/_stub.js +2 -2
  6. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DuQPp3dT.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-zK8c1RbI.mjs} +3 -3
  7. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Du_tzgi2.mjs +26 -0
  8. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DLOjWwaN.mjs +26 -0
  9. package/dist/pipeline-analytics/{hostInit-BDQ6oQ7b.mjs → hostInit-DAeozYqI.mjs} +3 -3
  10. package/dist/pipeline-analytics/index.js +423 -242
  11. package/dist/pipeline-analytics/index.mjs +423 -242
  12. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  13. package/package.json +1 -1
  14. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-4Fu7jNn9.mjs +0 -26
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-D5IzYeGQ.mjs +0 -26
@@ -1,4 +1,4 @@
1
- import { $ as NC_ALARM_DEFAULT_PROFILE_ID, $r as subKindsOf, $t as RECORDING_EXPORT_MAX_READ_BYTES, A as DetectionSourceSchema, Ai as boolean, An as applyBlockingEdit, At as NcConditionsSchema, B as FailureCounters, Bi as templateLiteral, Bn as consumableLowPercentOf, Br as resolveModeNotifyPolicy, Bt as NcSharedSequenceSchema, C as CoverStateSchema, Ci as isDeviceScopedCap, Cn as TrackRelationSchema, Cr as isVectorIndexDimConflict, Ct as NC_TEMPLATE_VARS, D as DETECTION_MACRO_CLASSES, Di as ZodObject, Dn as addonWidgetsSourceCapability, Dr as memoizePinnedFfmpeg, Dt as NcAlarmSensorsSchema, E as DEFAULT_TIMELAPSE_PREVIEW_TEXT, Ei as sleep$1, En as activateAlarmProfile, Er as mayWriteToLocation, Et as NcAlarmSensorsInputSchema, F as EVENT_KIND_BY_CAP, Fi as object, Fn as audioMetricsCapability, Fr as readTimelapseGeneratedAt, Ft as NcRulePatchSchema, G as MAX_ARCHIVED_DEBUG_NOTES, Gn as deriveDetailCropRect, Gr as ruleDeviceCompatCapQueries, Gt as NcSystemEventKindSchema, H as ListTrackRelationsInputSchema, Hi as union, Hn as cosineSimilarity$1, Hr as rootSupplyServes, Ht as NcSnoozeSchema, I as EVENT_OWNER_TYPES, Ii as partialRecord, In as audioModeOf, Ir as renameAlarmProfile, It as NcRuleSchema, J as MAX_TRACK_PURITIES, Jn as describeSystemEventDeliveryProblem, Jr as sceneMonitorCapability, Jt as NcTemplatePreviewSchema, K as MAX_BIRTH_DECISION_RECORDS, Kn as derivePostTriggeredAction, Kr as ruleGroupingApplies, Kt as NcTaxonomySchema, L as EXPORT_DENSE_MAX_RANGES, Li as record, Ln as buildEventKindDescriptor, Lr as resolveClipSearchMinScore, Lt as NcRuleTargetSchema, M as EMBEDDING_REQUIREMENTS_FAILED, Mi as literal, Mn as applyNonBlockingEdit, Mr as plateGalleryCapability, Mt as NcRuleActionSchema, N as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ni as looseObject, Nn as applySecureOnArmEdit, Nr as readDeviceStateFrom, Nt as NcRuleActionsSchema, O as DETECTION_PIPELINE_CAP_NAME, Oi as _enum, On as alarmDeviceSecureOnArm, Or as notificationRulesCapability, Ot as NcAlarmSettingsPatchSchema, P as EVENT_DENSITY_BATCH_MAX, Pi as number, Pn as assertTimelapseCadences, Pr as readMotionTriggeredBy, Pt as NcRuleInputSchema, Q as MotionTriggeredBySchema, Qn as embeddingRefusalOf, Qr as storageOccupancyCapability, R as FIRST_LEVEL_MACRO_CLASSES, Ri as strictObject, Rn as buildViewerLink, Rr as resolveLocationMode, Rt as NcRuleUpdateInputSchema, S as ClearTrackRelationResultSchema, Si as hydrateSchema, Sn as TrackRelationKindSchema, Sr as isSystemEventSummaryRule, St as NC_TAXONOMY, T as DEFAULT_EVENT_COLOR, Tn as TrackSourceSchema, Tr as linkedStepOf, Tt as NcAlarmPostTriggeredActionSchema, U as ListTrackRelationsResultSchema, Ui as unknown, Un as createAlarmProfile, Ur as ruleAutoTriggersAlarm, Ut as NcSnoozeSuppressedSchema, V as LabelAttributionSchema, Vi as tuple, Vn as coreBlockIdFromAddonId, Vt as NcSnoozeInputSchema, W as LockStateSchema, Wi as EventCategory, Wn as deleteAlarmProfile, Wr as ruleBelongsToAlarm$1, Wt as NcStateSummarySectionIdSchema, X as MOTION_CLOSE_AFTER_MS, Xr as sensorRaisedOf, Xt as OPS_LOG_DEFAULT_LIMIT, Y as MAX_TRACK_RELATIONS, Yn as describeSystemEventFamilyProblem, Yr as secureActuationFor, Yt as NcTemplateVarDescriptorSchema, Z as MediaFileKindEnum, Zr as servedTemplateVars, Zt as OpsLogEntrySchema, _ as BIRTH_DECISION_DEFAULT_LIMIT, _i as BaseAddon, _n as TRACK_RELATIONS_DEFAULT_LIMIT, _r as isMediaOwnerType, _t as NC_GROUPING_MIN_SEC, a as CLIP_EMBEDDING_STEP_ID, ai as systemEventSummarySplitOf, an as SCENE_DEFAULT_ANCHOR_THRESHOLD, ar as faceGalleryCapability, at as NC_ALARM_TRIGGERED_MAX_SEC, b as COCO_TO_MACRO, bi as customAction, bn as TimelapseRuleSchema, br as isScheduleActive, bt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, c as resolveClusterModelPin, ci as vectorDimFromBase64, cn as SCENE_DEFAULT_QUIET_SECONDS, cr as gifFromMp4Args, ct as NC_CLIP_POST_ROLL_DEFAULT_SEC, d as APPEARANCE_BLOCKS, di as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, dn as SCENE_RESET_RECAPTURES, dr as isAudioClassName, dt as NC_CONDITION_CATALOG, ei as syncActiveAlarmProfileSettings, en as RECORDING_SOURCE_CAMSTACK_ADDON, et as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, f as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, fi as canonicalHash, fn as SceneMonitorSchema, fr as isDefaultAlarmProfileId, ft as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, g as ArchivedDebugNoteSchema, gi as errMsg, gn as TIMELAPSE_DENSE_FLOOR_SEC, gr as isKnownTemplateVar, gt as NC_GROUPING_MAX_SEC, h as AlarmArmModeSchema, hi as DeviceType, hn as SetTrackRelationInputSchema, hr as isEventOwnerType, ht as NC_GROUPING_DEFAULT_SEC, ii as systemEventSummaryScheduleOf, in as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, ir as evictionPolicyOfLocation, it as NC_ALARM_SYSTEM_EVENT_KINDS, j as EMBEDDING_MODEL_FAILED, ji as discriminatedUnion, jn as applyModeDelaysEdits, jr as pipelineAnalyticsCapability, jt as NcLegacyRuleActionSequenceSchema, k as DeclaredDevices, ki as array, kn as alarmPanelCapability, kr as occupancyScope, kt as NcConditionDescriptorSchema, l as ALL_CAPABILITY_DEFINITIONS, li as viewerLinkBaseOf, ln as SCENE_DEFAULT_UNCOVERED_POLICY, lr as isAlarmControllableCap, lt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, m as AUDIO_MACRO_LABELS, mi as isSourceCap, mn as SetTrackPurityResultSchema, mr as isEventKindLabelKey, mt as NC_DEFAULT_SNOOZE_MINUTES, ni as systemEventFamilyProblems, nn as RetrainStatusSchema, nr as ensureAlarmProfiles, nt as NC_ALARM_DELAY_MAX_SEC, o as FACE_EMBEDDING_STEP_ID, oi as templateCarriesSummary, on as SCENE_DEFAULT_CHECK_INTERVAL_SEC, or as failureContributionCapability, ot as NC_AUDIO_CONFIRM_HITS_DEFAULT, p as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, pi as evaluateSensorEdge, pn as SetTrackPurityInputSchema, pr as isDetectionMacroClass, pt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, q as MAX_BIRTH_LATENCY_PROXY_MS, qn as deriveRecordingMode, qr as ruleKindOf, qt as NcTemplatePreviewInputSchema, ri as systemEventFilterApplies, rn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, rr as eventKindLabel, rt as NC_ALARM_NOTIFY_FIELDS, s as readClusterModelPinStrict, si as templateVarsFor, sn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, sr as gifDeriveSpeed, st as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, t as BUILTIN_CLIP_MODELS, ti as systemEventDeliveryProblems, tn as RebuildObjectEmbeddingsRefusalSchema, tr as encodeVectorBase64, tt as NC_ALARM_DELAY_FIELDS, u as APPEARANCE_BIN_COUNT, ui as zoneAnalyticsCapability, un as SCENE_DIVERGED, ur as isAppLinkBase, ut as NC_CLIP_RETENTION_MAX_SEC, v as BaseDevice, vi as CamProfileSchema, vn as TimelapseRuleInputSchema, vr as isRetiredClearKey, vt as NC_SENSOR_TRANSITION_KINDS, w as DEFAULT_DETAIL_CROP_CONVENTION, wi as nodePin, wn as TrackSideSchema, wr as kebabToCamel, wt as NcAlarmConfigSchema, x as ClearTrackRelationInputSchema, xi as defineCustomActions, xn as TrackPuritySchema, xr as isSystemDelivery, xt as NC_TANK_SYSTEM_EVENT_KINDS, y as BirthDecisionRecordSchema, yi as createEvent, yn as TimelapseRulePatchSchema, yr as isRootSuppliableStepId, yt as NC_SNOOZE_MAX_MINUTES, z as FULL_IMAGE_BBOX, zi as string, zn as cloneAlarmSettings, zr as resolveModeDelays, zt as NcScheduleSchema } from "../clip-model-registry-BftmbgcV.mjs";
1
+ import { $ as NC_ALARM_DEFAULT_PROFILE_ID, $r as subKindsOf, $t as RECORDING_EXPORT_MAX_READ_BYTES, A as DetectionSourceSchema, Ai as boolean, An as applyBlockingEdit, At as NcConditionsSchema, B as FailureCounters, Bi as templateLiteral, Bn as consumableLowPercentOf, Br as resolveModeNotifyPolicy, Bt as NcSharedSequenceSchema, C as CoverStateSchema, Ci as isDeviceScopedCap, Cn as TrackRelationSchema, Cr as isVectorIndexDimConflict, Ct as NC_TEMPLATE_VARS, D as DETECTION_MACRO_CLASSES, Di as ZodObject, Dn as addonWidgetsSourceCapability, Dr as memoizePinnedFfmpeg, Dt as NcAlarmSensorsSchema, E as DEFAULT_TIMELAPSE_PREVIEW_TEXT, Ei as sleep$1, En as activateAlarmProfile, Er as mayWriteToLocation, Et as NcAlarmSensorsInputSchema, F as EVENT_KIND_BY_CAP, Fi as object, Fn as audioMetricsCapability, Fr as readTimelapseGeneratedAt, Ft as NcRulePatchSchema, G as MAX_ARCHIVED_DEBUG_NOTES, Gn as deriveDetailCropRect, Gr as ruleDeviceCompatCapQueries, Gt as NcSystemEventKindSchema, H as ListTrackRelationsInputSchema, Hi as union, Hn as cosineSimilarity$1, Hr as rootSupplyServes, Ht as NcSnoozeSchema, I as EVENT_OWNER_TYPES, Ii as partialRecord, In as audioModeOf, Ir as renameAlarmProfile, It as NcRuleSchema, J as MAX_TRACK_PURITIES, Jn as describeSystemEventDeliveryProblem, Jr as sceneMonitorCapability, Jt as NcTemplatePreviewSchema, K as MAX_BIRTH_DECISION_RECORDS, Kn as derivePostTriggeredAction, Kr as ruleGroupingApplies, Kt as NcTaxonomySchema, L as EXPORT_DENSE_MAX_RANGES, Li as record, Ln as buildEventKindDescriptor, Lr as resolveClipSearchMinScore, Lt as NcRuleTargetSchema, M as EMBEDDING_REQUIREMENTS_FAILED, Mi as literal, Mn as applyNonBlockingEdit, Mr as plateGalleryCapability, Mt as NcRuleActionSchema, N as EMBEDDING_REQUIREMENTS_UNAVAILABLE, Ni as looseObject, Nn as applySecureOnArmEdit, Nr as readDeviceStateFrom, Nt as NcRuleActionsSchema, O as DETECTION_PIPELINE_CAP_NAME, Oi as _enum, On as alarmDeviceSecureOnArm, Or as notificationRulesCapability, Ot as NcAlarmSettingsPatchSchema, P as EVENT_DENSITY_BATCH_MAX, Pi as number, Pn as assertTimelapseCadences, Pr as readMotionTriggeredBy, Pt as NcRuleInputSchema, Q as MotionTriggeredBySchema, Qn as embeddingRefusalOf, Qr as storageOccupancyCapability, R as FIRST_LEVEL_MACRO_CLASSES, Ri as strictObject, Rn as buildViewerLink, Rr as resolveLocationMode, Rt as NcRuleUpdateInputSchema, S as ClearTrackRelationResultSchema, Si as hydrateSchema, Sn as TrackRelationKindSchema, Sr as isSystemEventSummaryRule, St as NC_TAXONOMY, T as DEFAULT_EVENT_COLOR, Tn as TrackSourceSchema, Tr as linkedStepOf, Tt as NcAlarmPostTriggeredActionSchema, U as ListTrackRelationsResultSchema, Ui as unknown, Un as createAlarmProfile, Ur as ruleAutoTriggersAlarm, Ut as NcSnoozeSuppressedSchema, V as LabelAttributionSchema, Vi as tuple, Vn as coreBlockIdFromAddonId, Vt as NcSnoozeInputSchema, W as LockStateSchema, Wi as EventCategory, Wn as deleteAlarmProfile, Wr as ruleBelongsToAlarm$1, Wt as NcStateSummarySectionIdSchema, X as MOTION_CLOSE_AFTER_MS, Xr as sensorRaisedOf, Xt as OPS_LOG_DEFAULT_LIMIT, Y as MAX_TRACK_RELATIONS, Yn as describeSystemEventFamilyProblem, Yr as secureActuationFor, Yt as NcTemplateVarDescriptorSchema, Z as MediaFileKindEnum, Zr as servedTemplateVars, Zt as OpsLogEntrySchema, _ as BIRTH_DECISION_DEFAULT_LIMIT, _i as BaseAddon, _n as TRACK_RELATIONS_DEFAULT_LIMIT, _r as isMediaOwnerType, _t as NC_GROUPING_MIN_SEC, a as CLIP_EMBEDDING_STEP_ID, ai as systemEventSummarySplitOf, an as SCENE_DEFAULT_ANCHOR_THRESHOLD, ar as faceGalleryCapability, at as NC_ALARM_TRIGGERED_MAX_SEC, b as COCO_TO_MACRO, bi as customAction, bn as TimelapseRuleSchema, br as isScheduleActive, bt as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, c as resolveClusterModelPin, ci as vectorDimFromBase64, cn as SCENE_DEFAULT_QUIET_SECONDS, cr as gifFromMp4Args, ct as NC_CLIP_POST_ROLL_DEFAULT_SEC, d as APPEARANCE_BLOCKS, di as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, dn as SCENE_RESET_RECAPTURES, dr as isAudioClassName, dt as NC_CONDITION_CATALOG, ei as syncActiveAlarmProfileSettings, en as RECORDING_SOURCE_CAMSTACK_ADDON, et as NC_ALARM_DEFAULT_TRIGGERED_DURATION_SEC, f as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, fi as canonicalHash, fn as SceneMonitorSchema, fr as isDefaultAlarmProfileId, ft as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, g as ArchivedDebugNoteSchema, gi as errMsg, gn as TIMELAPSE_DENSE_FLOOR_SEC, gr as isKnownTemplateVar, gt as NC_GROUPING_MAX_SEC, h as AlarmArmModeSchema, hi as DeviceType, hn as SetTrackRelationInputSchema, hr as isEventOwnerType, ht as NC_GROUPING_DEFAULT_SEC, ii as systemEventSummaryScheduleOf, in as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, ir as evictionPolicyOfLocation, it as NC_ALARM_SYSTEM_EVENT_KINDS, j as EMBEDDING_MODEL_FAILED, ji as discriminatedUnion, jn as applyModeDelaysEdits, jr as pipelineAnalyticsCapability, jt as NcLegacyRuleActionSequenceSchema, k as DeclaredDevices, ki as array, kn as alarmPanelCapability, kr as occupancyScope, kt as NcConditionDescriptorSchema, l as ALL_CAPABILITY_DEFINITIONS, li as viewerLinkBaseOf, ln as SCENE_DEFAULT_UNCOVERED_POLICY, lr as isAlarmControllableCap, lt as NC_CLIP_PRE_ROLL_DEFAULT_SEC, m as AUDIO_MACRO_LABELS, mi as isSourceCap, mn as SetTrackPurityResultSchema, mr as isEventKindLabelKey, mt as NC_DEFAULT_SNOOZE_MINUTES, ni as systemEventFamilyProblems, nn as RetrainStatusSchema, nr as ensureAlarmProfiles, nt as NC_ALARM_DELAY_MAX_SEC, o as FACE_EMBEDDING_STEP_ID, oi as templateCarriesSummary, on as SCENE_DEFAULT_CHECK_INTERVAL_SEC, or as failureContributionCapability, ot as NC_AUDIO_CONFIRM_HITS_DEFAULT, p as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, pi as evaluateSensorEdge, pn as SetTrackPurityInputSchema, pr as isDetectionMacroClass, pt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, q as MAX_BIRTH_LATENCY_PROXY_MS, qn as deriveRecordingMode, qr as ruleKindOf, qt as NcTemplatePreviewInputSchema, ri as systemEventFilterApplies, rn as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, rr as eventKindLabel, rt as NC_ALARM_NOTIFY_FIELDS, s as readClusterModelPinStrict, si as templateVarsFor, sn as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, sr as gifDeriveSpeed, st as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, t as BUILTIN_CLIP_MODELS, ti as systemEventDeliveryProblems, tn as RebuildObjectEmbeddingsRefusalSchema, tr as encodeVectorBase64, tt as NC_ALARM_DELAY_FIELDS, u as APPEARANCE_BIN_COUNT, ui as zoneAnalyticsCapability, un as SCENE_DIVERGED, ur as isAppLinkBase, ut as NC_CLIP_RETENTION_MAX_SEC, v as BaseDevice, vi as CamProfileSchema, vn as TimelapseRuleInputSchema, vr as isRetiredClearKey, vt as NC_SENSOR_TRANSITION_KINDS, w as DEFAULT_DETAIL_CROP_CONVENTION, wi as nodePin, wn as TrackSideSchema, wr as kebabToCamel, wt as NcAlarmConfigSchema, x as ClearTrackRelationInputSchema, xi as defineCustomActions, xn as TrackPuritySchema, xr as isSystemDelivery, xt as NC_TANK_SYSTEM_EVENT_KINDS, y as BirthDecisionRecordSchema, yi as createEvent, yn as TimelapseRulePatchSchema, yr as isRootSuppliableStepId, yt as NC_SNOOZE_MAX_MINUTES, z as FULL_IMAGE_BBOX, zi as string, zn as cloneAlarmSettings, zr as resolveModeDelays, zt as NcScheduleSchema } from "../clip-model-registry-CrUfogC-.mjs";
2
2
  import { t as __exportAll } from "../embedding-encoder/index.mjs";
3
3
  import * as fs$1 from "node:fs";
4
4
  import { createWriteStream, promises } from "node:fs";
@@ -83412,6 +83412,260 @@ function withDatasetVersion(manifest, version) {
83412
83412
  };
83413
83413
  }
83414
83414
  //#endregion
83415
+ //#region src/pipeline-analytics/retrain/retrain-dataset-version-store.ts
83416
+ /**
83417
+ * @durable class=ledger owner=pipeline-analytics
83418
+ * write="one row per dataset version the operator creates: a frozen frameIds list,
83419
+ * the sha256 of the annotations those frames carried, the export parameters and
83420
+ * the counts at creation. Never updated after the insert — a different selection
83421
+ * is a new version."
83422
+ * retention="none — rows leave only when the operator deletes the version. The
83423
+ * frames themselves are owned by the retrain corpus; deleting a version deletes no
83424
+ * frame, and deleting a frame does not edit a version (verify reports it missing)."
83425
+ */
83426
+ var RETRAIN_DATASET_VERSIONS_COLLECTION = "pipeline-analytics:retrain-dataset-versions";
83427
+ var COLUMNS = [
83428
+ {
83429
+ name: "id",
83430
+ type: "TEXT",
83431
+ primaryKey: true,
83432
+ notNull: true
83433
+ },
83434
+ {
83435
+ name: "name",
83436
+ type: "TEXT",
83437
+ notNull: true
83438
+ },
83439
+ {
83440
+ name: "nameKey",
83441
+ type: "TEXT",
83442
+ notNull: true
83443
+ },
83444
+ {
83445
+ name: "createdAt",
83446
+ type: "INTEGER",
83447
+ notNull: true
83448
+ },
83449
+ {
83450
+ name: "selection",
83451
+ type: "JSON",
83452
+ notNull: true
83453
+ },
83454
+ {
83455
+ name: "layout",
83456
+ type: "TEXT",
83457
+ notNull: true
83458
+ },
83459
+ {
83460
+ name: "completeOnly",
83461
+ type: "BOOLEAN",
83462
+ notNull: true
83463
+ },
83464
+ {
83465
+ name: "frameIds",
83466
+ type: "JSON",
83467
+ notNull: true
83468
+ },
83469
+ {
83470
+ name: "annotationHash",
83471
+ type: "TEXT",
83472
+ notNull: true
83473
+ },
83474
+ {
83475
+ name: "manifestSchema",
83476
+ type: "TEXT",
83477
+ notNull: true
83478
+ },
83479
+ {
83480
+ name: "stats",
83481
+ type: "JSON",
83482
+ notNull: true
83483
+ }
83484
+ ];
83485
+ var INDEXES = [{
83486
+ name: "idx_retrain_dataset_versions_name_key",
83487
+ columns: ["nameKey"],
83488
+ unique: true
83489
+ }, {
83490
+ name: "idx_retrain_dataset_versions_created",
83491
+ columns: ["createdAt"]
83492
+ }];
83493
+ function summaryOfVersion(version) {
83494
+ const { frameIds, ...rest } = version;
83495
+ return {
83496
+ ...rest,
83497
+ frameCount: frameIds.length
83498
+ };
83499
+ }
83500
+ var nameKeyOf = (name) => name.trim().toLowerCase();
83501
+ function numberList(value) {
83502
+ return Array.isArray(value) ? value.filter((v) => typeof v === "number") : void 0;
83503
+ }
83504
+ function stringList(value) {
83505
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : void 0;
83506
+ }
83507
+ function parseJson(value) {
83508
+ if (typeof value !== "string") return value;
83509
+ try {
83510
+ return JSON.parse(value);
83511
+ } catch {
83512
+ return;
83513
+ }
83514
+ }
83515
+ function asRecord(value) {
83516
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
83517
+ }
83518
+ var EMPTY_STATS = {
83519
+ frames: 0,
83520
+ completeFrames: 0,
83521
+ completeness: 0,
83522
+ subjects: 0,
83523
+ modelErrors: 0,
83524
+ hardNegatives: 0,
83525
+ cells: [],
83526
+ cameras: []
83527
+ };
83528
+ /** A stored stats object, trusted only as far as its shape. */
83529
+ function readStats(value) {
83530
+ const raw = asRecord(parseJson(value));
83531
+ const num = (k) => typeof raw[k] === "number" ? raw[k] : 0;
83532
+ const cells = Array.isArray(raw["cells"]) ? raw["cells"] : [];
83533
+ const cameras = Array.isArray(raw["cameras"]) ? raw["cameras"] : [];
83534
+ return {
83535
+ ...EMPTY_STATS,
83536
+ frames: num("frames"),
83537
+ completeFrames: num("completeFrames"),
83538
+ completeness: num("completeness"),
83539
+ subjects: num("subjects"),
83540
+ modelErrors: num("modelErrors"),
83541
+ hardNegatives: num("hardNegatives"),
83542
+ cells: cells.map((c) => {
83543
+ const r = asRecord(c);
83544
+ const lighting = r["lighting"] === "day" || r["lighting"] === "night" ? r["lighting"] : "unknown";
83545
+ return {
83546
+ macroClass: String(r["macroClass"] ?? ""),
83547
+ deviceId: Number(r["deviceId"] ?? 0),
83548
+ lighting,
83549
+ subjects: Number(r["subjects"] ?? 0),
83550
+ frames: Number(r["frames"] ?? 0)
83551
+ };
83552
+ }),
83553
+ cameras: cameras.map((c) => {
83554
+ const r = asRecord(c);
83555
+ return {
83556
+ deviceId: Number(r["deviceId"] ?? 0),
83557
+ frames: Number(r["frames"] ?? 0),
83558
+ completeFrames: Number(r["completeFrames"] ?? 0)
83559
+ };
83560
+ })
83561
+ };
83562
+ }
83563
+ var RetrainDatasetVersionStore = class {
83564
+ store;
83565
+ logger;
83566
+ constructor(deps) {
83567
+ this.store = deps.store;
83568
+ this.logger = deps.logger;
83569
+ }
83570
+ static async declare(store) {
83571
+ await store.declareCollection.mutate({
83572
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83573
+ columns: [...COLUMNS],
83574
+ indexes: [...INDEXES]
83575
+ });
83576
+ }
83577
+ insert = async (version) => {
83578
+ await this.store.set.mutate({
83579
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83580
+ key: version.id,
83581
+ value: {
83582
+ name: version.name,
83583
+ nameKey: nameKeyOf(version.name),
83584
+ createdAt: version.createdAt,
83585
+ selection: version.selection,
83586
+ layout: version.layout,
83587
+ completeOnly: version.completeOnly,
83588
+ frameIds: version.frameIds,
83589
+ annotationHash: version.annotationHash,
83590
+ manifestSchema: version.manifestSchema,
83591
+ stats: version.stats
83592
+ }
83593
+ });
83594
+ };
83595
+ get = async (id) => {
83596
+ try {
83597
+ const row = await this.store.get.query({
83598
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83599
+ key: id
83600
+ });
83601
+ return row === null || row === void 0 ? null : this.toVersion(id, asRecord(row));
83602
+ } catch (err) {
83603
+ this.logger.warn("retrain dataset version read failed", { meta: {
83604
+ versionId: id,
83605
+ error: String(err)
83606
+ } });
83607
+ return null;
83608
+ }
83609
+ };
83610
+ list = async () => {
83611
+ return (await this.listRows()).map(summaryOfVersion);
83612
+ };
83613
+ /** Every row WITH its frame list — the migration into `training` reads this. */
83614
+ listRows = async () => {
83615
+ try {
83616
+ return (await this.store.query.query({
83617
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83618
+ filter: { orderBy: {
83619
+ field: "createdAt",
83620
+ direction: "desc"
83621
+ } }
83622
+ })).map((r) => this.toVersion(r.id, asRecord(r.data)));
83623
+ } catch (err) {
83624
+ this.logger.warn("retrain dataset versions list failed", { meta: { error: String(err) } });
83625
+ return [];
83626
+ }
83627
+ };
83628
+ findIdByName = async (name) => {
83629
+ return (await this.store.query.query({
83630
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83631
+ filter: {
83632
+ where: { nameKey: nameKeyOf(name) },
83633
+ limit: 1
83634
+ }
83635
+ }))[0]?.id ?? null;
83636
+ };
83637
+ remove = async (id) => {
83638
+ if (await this.get(id) === null) return false;
83639
+ await this.store.delete.mutate({
83640
+ collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83641
+ key: id
83642
+ });
83643
+ return true;
83644
+ };
83645
+ toVersion(id, data) {
83646
+ const selection = asRecord(parseJson(data["selection"]));
83647
+ const deviceIds = numberList(selection["deviceIds"]);
83648
+ const collectionIds = stringList(selection["collectionIds"]);
83649
+ const frameIdsSel = stringList(selection["frameIds"]);
83650
+ return {
83651
+ id,
83652
+ name: String(data["name"] ?? ""),
83653
+ createdAt: Number(data["createdAt"] ?? 0),
83654
+ selection: {
83655
+ ...deviceIds !== void 0 ? { deviceIds } : {},
83656
+ ...collectionIds !== void 0 ? { collectionIds } : {},
83657
+ ...frameIdsSel !== void 0 ? { frameIds: frameIdsSel } : {}
83658
+ },
83659
+ layout: data["layout"] === "crops" ? "crops" : "frames",
83660
+ completeOnly: data["completeOnly"] === true || data["completeOnly"] === 1,
83661
+ frameIds: stringList(parseJson(data["frameIds"])) ?? [],
83662
+ annotationHash: String(data["annotationHash"] ?? ""),
83663
+ manifestSchema: String(data["manifestSchema"] ?? ""),
83664
+ stats: readStats(data["stats"])
83665
+ };
83666
+ }
83667
+ };
83668
+ //#endregion
83415
83669
  //#region src/pipeline-analytics/retrain/retrain-geometry.ts
83416
83670
  function clamp01(v) {
83417
83671
  return v < 0 ? 0 : v > 1 ? 1 : v;
@@ -83700,13 +83954,6 @@ function filterOf(selection, completeOnly) {
83700
83954
  ...completeOnly ? { completeOnly: true } : {}
83701
83955
  };
83702
83956
  }
83703
- function summaryOf(version) {
83704
- const { frameIds, ...rest } = version;
83705
- return {
83706
- ...rest,
83707
- frameCount: frameIds.length
83708
- };
83709
- }
83710
83957
  var RetrainDatasetService = class {
83711
83958
  deps;
83712
83959
  constructor(deps) {
@@ -83759,11 +84006,11 @@ var RetrainDatasetService = class {
83759
84006
  } });
83760
84007
  return {
83761
84008
  kind: "created",
83762
- version: summaryOf(version)
84009
+ version: summaryOfVersion(version)
83763
84010
  };
83764
84011
  }
83765
84012
  async list() {
83766
- return (await this.deps.versions.list()).map(summaryOf);
84013
+ return this.deps.versions.list();
83767
84014
  }
83768
84015
  async delete(input) {
83769
84016
  const deleted = await this.deps.versions.remove(input.id);
@@ -83821,246 +84068,62 @@ var RetrainDatasetService = class {
83821
84068
  }
83822
84069
  };
83823
84070
  //#endregion
83824
- //#region src/pipeline-analytics/retrain/retrain-dataset-version-store.ts
83825
- /**
83826
- * @durable class=ledger owner=pipeline-analytics
83827
- * write="one row per dataset version the operator creates: a frozen frameIds list,
83828
- * the sha256 of the annotations those frames carried, the export parameters and
83829
- * the counts at creation. Never updated after the insert — a different selection
83830
- * is a new version."
83831
- * retention="none — rows leave only when the operator deletes the version. The
83832
- * frames themselves are owned by the retrain corpus; deleting a version deletes no
83833
- * frame, and deleting a frame does not edit a version (verify reports it missing)."
83834
- */
83835
- var RETRAIN_DATASET_VERSIONS_COLLECTION = "pipeline-analytics:retrain-dataset-versions";
83836
- var COLUMNS = [
83837
- {
83838
- name: "id",
83839
- type: "TEXT",
83840
- primaryKey: true,
83841
- notNull: true
83842
- },
83843
- {
83844
- name: "name",
83845
- type: "TEXT",
83846
- notNull: true
83847
- },
83848
- {
83849
- name: "nameKey",
83850
- type: "TEXT",
83851
- notNull: true
83852
- },
83853
- {
83854
- name: "createdAt",
83855
- type: "INTEGER",
83856
- notNull: true
83857
- },
83858
- {
83859
- name: "selection",
83860
- type: "JSON",
83861
- notNull: true
83862
- },
83863
- {
83864
- name: "layout",
83865
- type: "TEXT",
83866
- notNull: true
83867
- },
83868
- {
83869
- name: "completeOnly",
83870
- type: "BOOLEAN",
83871
- notNull: true
83872
- },
83873
- {
83874
- name: "frameIds",
83875
- type: "JSON",
83876
- notNull: true
83877
- },
83878
- {
83879
- name: "annotationHash",
83880
- type: "TEXT",
83881
- notNull: true
83882
- },
83883
- {
83884
- name: "manifestSchema",
83885
- type: "TEXT",
83886
- notNull: true
83887
- },
83888
- {
83889
- name: "stats",
83890
- type: "JSON",
83891
- notNull: true
83892
- }
83893
- ];
83894
- var INDEXES = [{
83895
- name: "idx_retrain_dataset_versions_name_key",
83896
- columns: ["nameKey"],
83897
- unique: true
83898
- }, {
83899
- name: "idx_retrain_dataset_versions_created",
83900
- columns: ["createdAt"]
83901
- }];
83902
- var nameKeyOf = (name) => name.trim().toLowerCase();
83903
- function numberList(value) {
83904
- return Array.isArray(value) ? value.filter((v) => typeof v === "number") : void 0;
83905
- }
83906
- function stringList(value) {
83907
- return Array.isArray(value) ? value.filter((v) => typeof v === "string") : void 0;
83908
- }
83909
- function parseJson(value) {
83910
- if (typeof value !== "string") return value;
83911
- try {
83912
- return JSON.parse(value);
83913
- } catch {
83914
- return;
83915
- }
83916
- }
83917
- function asRecord(value) {
83918
- return value !== null && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
83919
- }
83920
- var EMPTY_STATS = {
83921
- frames: 0,
83922
- completeFrames: 0,
83923
- completeness: 0,
83924
- subjects: 0,
83925
- modelErrors: 0,
83926
- hardNegatives: 0,
83927
- cells: [],
83928
- cameras: []
83929
- };
83930
- /** A stored stats object, trusted only as far as its shape. */
83931
- function readStats(value) {
83932
- const raw = asRecord(parseJson(value));
83933
- const num = (k) => typeof raw[k] === "number" ? raw[k] : 0;
83934
- const cells = Array.isArray(raw["cells"]) ? raw["cells"] : [];
83935
- const cameras = Array.isArray(raw["cameras"]) ? raw["cameras"] : [];
83936
- return {
83937
- ...EMPTY_STATS,
83938
- frames: num("frames"),
83939
- completeFrames: num("completeFrames"),
83940
- completeness: num("completeness"),
83941
- subjects: num("subjects"),
83942
- modelErrors: num("modelErrors"),
83943
- hardNegatives: num("hardNegatives"),
83944
- cells: cells.map((c) => {
83945
- const r = asRecord(c);
83946
- const lighting = r["lighting"] === "day" || r["lighting"] === "night" ? r["lighting"] : "unknown";
83947
- return {
83948
- macroClass: String(r["macroClass"] ?? ""),
83949
- deviceId: Number(r["deviceId"] ?? 0),
83950
- lighting,
83951
- subjects: Number(r["subjects"] ?? 0),
83952
- frames: Number(r["frames"] ?? 0)
83953
- };
83954
- }),
83955
- cameras: cameras.map((c) => {
83956
- const r = asRecord(c);
83957
- return {
83958
- deviceId: Number(r["deviceId"] ?? 0),
83959
- frames: Number(r["frames"] ?? 0),
83960
- completeFrames: Number(r["completeFrames"] ?? 0)
83961
- };
83962
- })
83963
- };
83964
- }
83965
- var RetrainDatasetVersionStore = class {
83966
- store;
83967
- logger;
84071
+ //#region src/pipeline-analytics/retrain/retrain-dataset-version-routing.ts
84072
+ var RoutingDatasetVersionRepository = class {
84073
+ deps;
84074
+ lastPresence = false;
84075
+ migrated = false;
84076
+ migration = null;
83968
84077
  constructor(deps) {
83969
- this.store = deps.store;
83970
- this.logger = deps.logger;
83971
- }
83972
- static async declare(store) {
83973
- await store.declareCollection.mutate({
83974
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83975
- columns: [...COLUMNS],
83976
- indexes: [...INDEXES]
83977
- });
84078
+ this.deps = deps;
83978
84079
  }
83979
84080
  insert = async (version) => {
83980
- await this.store.set.mutate({
83981
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
83982
- key: version.id,
83983
- value: {
83984
- name: version.name,
83985
- nameKey: nameKeyOf(version.name),
83986
- createdAt: version.createdAt,
83987
- selection: version.selection,
83988
- layout: version.layout,
83989
- completeOnly: version.completeOnly,
83990
- frameIds: version.frameIds,
83991
- annotationHash: version.annotationHash,
83992
- manifestSchema: version.manifestSchema,
83993
- stats: version.stats
83994
- }
83995
- });
84081
+ if (await this.route() === "local") {
84082
+ await this.deps.local.insert(version);
84083
+ return;
84084
+ }
84085
+ await this.deps.training.put(version);
83996
84086
  };
83997
- get = async (id) => {
84087
+ get = async (id) => await this.route() === "local" ? this.deps.local.get(id) : this.deps.training.get(id);
84088
+ list = async () => await this.route() === "local" ? this.deps.local.list() : this.deps.training.list();
84089
+ findIdByName = async (name) => await this.route() === "local" ? this.deps.local.findIdByName(name) : this.deps.training.findIdByName(name);
84090
+ remove = async (id) => await this.route() === "local" ? this.deps.local.remove(id) : this.deps.training.remove(id);
84091
+ async route() {
84092
+ if (!await this.presence()) return "local";
84093
+ if (this.migrated) return "training";
84094
+ return await this.migrateOnce() ? "training" : "local";
84095
+ }
84096
+ async presence() {
84097
+ let answer;
83998
84098
  try {
83999
- const row = await this.store.get.query({
84000
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
84001
- key: id
84002
- });
84003
- return row === null || row === void 0 ? null : this.toVersion(id, asRecord(row));
84004
- } catch (err) {
84005
- this.logger.warn("retrain dataset version read failed", { meta: {
84006
- versionId: id,
84007
- error: String(err)
84008
- } });
84009
- return null;
84099
+ answer = await this.deps.trainingPresent();
84100
+ } catch {
84101
+ answer = null;
84010
84102
  }
84011
- };
84012
- list = async () => {
84103
+ if (answer !== null) this.lastPresence = answer;
84104
+ return this.lastPresence;
84105
+ }
84106
+ migrateOnce() {
84107
+ if (this.migration === null) this.migration = this.migrate().finally(() => {
84108
+ this.migration = null;
84109
+ });
84110
+ return this.migration;
84111
+ }
84112
+ async migrate() {
84113
+ const { local, training, logger } = this.deps;
84013
84114
  try {
84014
- return (await this.store.query.query({
84015
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
84016
- filter: { orderBy: {
84017
- field: "createdAt",
84018
- direction: "desc"
84019
- } }
84020
- })).map((r) => this.toVersion(r.id, asRecord(r.data)));
84115
+ const rows = await local.listRows();
84116
+ for (const row of rows) {
84117
+ await training.put(row);
84118
+ await local.remove(row.id);
84119
+ }
84120
+ this.migrated = true;
84121
+ if (rows.length > 0) logger.info("retrain dataset versions moved to the training capability", { meta: { versions: rows.length } });
84122
+ return true;
84021
84123
  } catch (err) {
84022
- this.logger.warn("retrain dataset versions list failed", { meta: { error: String(err) } });
84023
- return [];
84124
+ logger.warn("retrain dataset versions could not move to training yet — kept local", { meta: { error: err instanceof Error ? err.message : String(err) } });
84125
+ return false;
84024
84126
  }
84025
- };
84026
- findIdByName = async (name) => {
84027
- return (await this.store.query.query({
84028
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
84029
- filter: {
84030
- where: { nameKey: nameKeyOf(name) },
84031
- limit: 1
84032
- }
84033
- }))[0]?.id ?? null;
84034
- };
84035
- remove = async (id) => {
84036
- if (await this.get(id) === null) return false;
84037
- await this.store.delete.mutate({
84038
- collection: RETRAIN_DATASET_VERSIONS_COLLECTION,
84039
- key: id
84040
- });
84041
- return true;
84042
- };
84043
- toVersion(id, data) {
84044
- const selection = asRecord(parseJson(data["selection"]));
84045
- const deviceIds = numberList(selection["deviceIds"]);
84046
- const collectionIds = stringList(selection["collectionIds"]);
84047
- const frameIdsSel = stringList(selection["frameIds"]);
84048
- return {
84049
- id,
84050
- name: String(data["name"] ?? ""),
84051
- createdAt: Number(data["createdAt"] ?? 0),
84052
- selection: {
84053
- ...deviceIds !== void 0 ? { deviceIds } : {},
84054
- ...collectionIds !== void 0 ? { collectionIds } : {},
84055
- ...frameIdsSel !== void 0 ? { frameIds: frameIdsSel } : {}
84056
- },
84057
- layout: data["layout"] === "crops" ? "crops" : "frames",
84058
- completeOnly: data["completeOnly"] === true || data["completeOnly"] === 1,
84059
- frameIds: stringList(parseJson(data["frameIds"])) ?? [],
84060
- annotationHash: String(data["annotationHash"] ?? ""),
84061
- manifestSchema: String(data["manifestSchema"] ?? ""),
84062
- stats: readStats(data["stats"])
84063
- };
84064
84127
  }
84065
84128
  };
84066
84129
  //#endregion
@@ -84730,6 +84793,61 @@ async function writeRetrainArchiveTo(deps) {
84730
84793
  return stats;
84731
84794
  }
84732
84795
  //#endregion
84796
+ //#region src/pipeline-analytics/retrain/retrain-archive-offer.ts
84797
+ /** A reader silent this long is gone; the body is cut. */
84798
+ var RETRAIN_OFFER_STALL_MS = 6e4;
84799
+ function responseArchiveSink(res, stallMs = RETRAIN_OFFER_STALL_MS) {
84800
+ let closed = false;
84801
+ res.once("close", () => {
84802
+ closed = true;
84803
+ });
84804
+ return { write: (chunk) => new Promise((resolve, reject) => {
84805
+ if (closed || res.destroyed) {
84806
+ reject(/* @__PURE__ */ new Error("retrain archive reader went away"));
84807
+ return;
84808
+ }
84809
+ if (res.write(chunk)) {
84810
+ resolve();
84811
+ return;
84812
+ }
84813
+ const onDrain = () => {
84814
+ cleanup();
84815
+ resolve();
84816
+ };
84817
+ const onClose = () => {
84818
+ cleanup();
84819
+ reject(/* @__PURE__ */ new Error("retrain archive reader went away"));
84820
+ };
84821
+ const timer = setTimeout(() => {
84822
+ cleanup();
84823
+ res.destroy(/* @__PURE__ */ new Error("retrain archive reader stalled"));
84824
+ reject(/* @__PURE__ */ new Error(`retrain archive reader stalled for ${stallMs} ms`));
84825
+ }, stallMs);
84826
+ const cleanup = () => {
84827
+ clearTimeout(timer);
84828
+ res.off("drain", onDrain);
84829
+ res.off("close", onClose);
84830
+ };
84831
+ res.once("drain", onDrain);
84832
+ res.once("close", onClose);
84833
+ }) };
84834
+ }
84835
+ /**
84836
+ * Serve one archive: headers, the writer's chunks, the end. A writer that
84837
+ * throws destroys the response (the reader sees a truncated body, never a
84838
+ * clean end) and the error propagates to the caller's log.
84839
+ */
84840
+ async function serveRetrainArchive(_req, res, writeArchive) {
84841
+ res.writeHead(200, { "content-type": "application/x-tar" });
84842
+ try {
84843
+ await writeArchive(responseArchiveSink(res));
84844
+ await new Promise((resolve) => res.end(resolve));
84845
+ } catch (err) {
84846
+ res.destroy(err instanceof Error ? err : new Error(String(err)));
84847
+ throw err;
84848
+ }
84849
+ }
84850
+ //#endregion
84733
84851
  //#region src/pipeline-analytics/retrain/retrain-crop-cut.ts
84734
84852
  /**
84735
84853
  * The `crops` layout's cutter: one subject crop from a retrain frame copy.
@@ -111026,8 +111144,26 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
111026
111144
  logger: logger.child("RetrainDatasets")
111027
111145
  });
111028
111146
  this.retrainDatasetVersions = retrainDatasetVersions;
111147
+ const routedDatasetVersions = new RoutingDatasetVersionRepository({
111148
+ local: retrainDatasetVersions,
111149
+ training: {
111150
+ put: (row) => api.training.putDatasetVersion.mutate({ ...row }),
111151
+ get: (id) => api.training.getDatasetVersion.query({ id }),
111152
+ list: async () => api.training.listDatasetVersions.query({}),
111153
+ findIdByName: async (name) => (await api.training.findDatasetVersionIdByName.query({ name })).id,
111154
+ remove: async (id) => (await api.training.removeDatasetVersion.mutate({ id })).removed
111155
+ },
111156
+ trainingPresent: async () => {
111157
+ try {
111158
+ return (await api.addons.listCapabilityProviders.query({ capName: "training" })).length > 0;
111159
+ } catch {
111160
+ return null;
111161
+ }
111162
+ },
111163
+ logger: logger.child("RetrainDatasets")
111164
+ });
111029
111165
  this.retrainDatasets = new RetrainDatasetService({
111030
- versions: retrainDatasetVersions,
111166
+ versions: routedDatasetVersions,
111031
111167
  buildPlan: (request) => this.buildRetrainExportPlan(request),
111032
111168
  now: () => Date.now(),
111033
111169
  newId: () => randomUUID(),
@@ -112392,6 +112528,51 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
112392
112528
  }
112393
112529
  }
112394
112530
  /**
112531
+ * The same archive behind a one-shot `ctx.peerBytes` ticket (D805): the
112532
+ * caller (a training provider, same host) dials it at once and streams it
112533
+ * into its cloud. The plan is built now, so an empty or unknown selection
112534
+ * fails here rather than as an empty body; the bytes and their sha256 are
112535
+ * the reader's to measure.
112536
+ */
112537
+ async offerRetrainArchive(input) {
112538
+ const frameStore = this.retrainFrames;
112539
+ if (frameStore === null) throw new Error("retrain export: analytics stores unavailable");
112540
+ const peerBytes = this.ctx.peerBytes;
112541
+ if (peerBytes === void 0) throw new Error("retrain archive offer: no peer-bytes facility");
112542
+ const plan = await this.buildRetrainExportPlan({
112543
+ filter: input.filter,
112544
+ layout: input.layout
112545
+ });
112546
+ if (plan.frames.length === 0) throw new Error("retrain archive offer: the selection holds no frame");
112547
+ const logger = this.ctx.logger;
112548
+ const offered = await peerBytes.offer({
112549
+ label: "retrain-archive",
112550
+ handler: (req, res) => serveRetrainArchive(req, res, async (sink) => {
112551
+ await writeRetrainArchiveTo({
112552
+ plan,
112553
+ readFrame: (frame) => frameStore.readFrame(frame),
112554
+ cutCrop: this.retrainCropCutter(),
112555
+ sink,
112556
+ markExported: (frameIds, batchId) => this.markRetrainExported(frameIds, batchId),
112557
+ logger,
112558
+ now: () => Date.now()
112559
+ });
112560
+ }).catch((err) => {
112561
+ logger.warn("retrain archive offer failed mid-body", { meta: { error: errMsg(err) } });
112562
+ })
112563
+ });
112564
+ if (offered.kind === "refused") throw new Error(`retrain archive offer refused: ${offered.code} — ${offered.detail}`);
112565
+ logger.info("retrain archive offered", { meta: {
112566
+ frames: plan.frames.length,
112567
+ layout: input.layout
112568
+ } });
112569
+ return {
112570
+ ticket: offered.ticket,
112571
+ frames: plan.frames.length,
112572
+ annotations: plan.manifest.annotationCount
112573
+ };
112574
+ }
112575
+ /**
112395
112576
  * The store seam the `debug.*` actions and the debug bundle both read through.
112396
112577
  *
112397
112578
  * Index reads, plus ONE existence probe per media row — never a blob. The