zorya-classifier 0.2.0 → 0.2.2

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 (140) hide show
  1. package/README.md +24 -8
  2. package/dist/app/classifier-config.d.ts +30 -0
  3. package/dist/app/classifier-config.js +46 -0
  4. package/dist/app/classifier-contracts.d.ts +32 -0
  5. package/dist/app/classifier-contracts.js +1 -0
  6. package/dist/app/classifier-representation.d.ts +5 -0
  7. package/dist/app/classifier-representation.js +33 -0
  8. package/dist/app/classifier-runtime.d.ts +7 -0
  9. package/dist/app/classifier-runtime.js +71 -0
  10. package/dist/app/classifier-spatial.d.ts +31 -0
  11. package/dist/app/classifier-spatial.js +78 -0
  12. package/dist/app/cli-arguments.d.ts +2 -2
  13. package/dist/app/create-classifier.d.ts +4 -29
  14. package/dist/app/create-classifier.js +37 -237
  15. package/dist/cli.js +1 -1
  16. package/dist/entities/classification.d.ts +98 -0
  17. package/dist/entities/classification.js +28 -0
  18. package/dist/entities/contracts.d.ts +6 -471
  19. package/dist/entities/contracts.js +6 -97
  20. package/dist/entities/decision.d.ts +211 -0
  21. package/dist/entities/decision.js +33 -0
  22. package/dist/entities/geometry.d.ts +37 -0
  23. package/dist/entities/geometry.js +26 -0
  24. package/dist/entities/image.d.ts +39 -0
  25. package/dist/entities/image.js +15 -0
  26. package/dist/entities/localization.d.ts +125 -0
  27. package/dist/entities/localization.js +13 -0
  28. package/dist/entities/object-proposals.d.ts +4 -1
  29. package/dist/entities/segmentation-metadata.d.ts +70 -0
  30. package/dist/entities/segmentation-metadata.js +21 -1
  31. package/dist/entities/segmentation-verification.d.ts +1 -0
  32. package/dist/entities/segmentation.d.ts +6 -1
  33. package/dist/entities/validation.d.ts +2 -0
  34. package/dist/entities/validation.js +9 -0
  35. package/dist/entities/whole-object.d.ts +4 -0
  36. package/dist/features/choice-beam-layout.js +2 -7
  37. package/dist/features/proposals/presentation.d.ts +21 -0
  38. package/dist/features/proposals/presentation.js +122 -0
  39. package/dist/features/proposals/validation.d.ts +138 -0
  40. package/dist/features/proposals/validation.js +125 -0
  41. package/dist/features/segmentation/box-check.js +10 -23
  42. package/dist/features/segmentation/mask.js +2 -7
  43. package/dist/features/segmentation/region-result.d.ts +18 -0
  44. package/dist/features/segmentation/region-result.js +171 -0
  45. package/dist/features/segmentation/source-mask.d.ts +6 -0
  46. package/dist/features/segmentation/source-mask.js +32 -0
  47. package/dist/features/segmentation/validation.d.ts +9 -0
  48. package/dist/features/segmentation/validation.js +94 -0
  49. package/dist/infrastructure/decision-transport/errors.d.ts +8 -0
  50. package/dist/infrastructure/decision-transport/errors.js +34 -0
  51. package/dist/infrastructure/decision-transport/images.d.ts +1 -0
  52. package/dist/infrastructure/decision-transport/images.js +52 -0
  53. package/dist/infrastructure/{openrouter-common.d.ts → decision-transport/request.d.ts} +6 -15
  54. package/dist/infrastructure/decision-transport/request.js +162 -0
  55. package/dist/infrastructure/decision-transport/response.d.ts +1 -0
  56. package/dist/infrastructure/decision-transport/response.js +72 -0
  57. package/dist/infrastructure/decision-transport/route-identity.d.ts +11 -0
  58. package/dist/infrastructure/decision-transport/route-identity.js +23 -0
  59. package/dist/infrastructure/openrouter-vision.js +1 -1
  60. package/dist/infrastructure/openrouter.js +7 -19
  61. package/dist/infrastructure/raster.js +3 -8
  62. package/dist/infrastructure/segmentation/grabcut/index.d.ts +5 -1
  63. package/dist/infrastructure/segmentation/grabcut/index.js +6 -5
  64. package/dist/infrastructure/segmentation/grabcut/masks.d.ts +49 -0
  65. package/dist/infrastructure/segmentation/grabcut/masks.js +89 -0
  66. package/dist/infrastructure/segmentation/grabcut/model-asset.d.ts +4 -0
  67. package/dist/infrastructure/segmentation/grabcut/model-asset.js +4 -0
  68. package/dist/infrastructure/segmentation/grabcut/runtime.d.ts +70 -0
  69. package/dist/infrastructure/segmentation/grabcut/runtime.js +96 -0
  70. package/dist/infrastructure/segmentation/grabcut/worker-inference.d.ts +4 -43
  71. package/dist/infrastructure/segmentation/grabcut/worker-inference.js +4 -187
  72. package/dist/infrastructure/segmentation/mobile-sam/index.d.ts +3 -58
  73. package/dist/infrastructure/segmentation/mobile-sam/index.js +2 -472
  74. package/dist/infrastructure/segmentation/mobile-sam/input.d.ts +46 -0
  75. package/dist/infrastructure/segmentation/mobile-sam/input.js +83 -0
  76. package/dist/infrastructure/segmentation/mobile-sam/model-assets.d.ts +8 -0
  77. package/dist/infrastructure/segmentation/mobile-sam/model-assets.js +8 -0
  78. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.d.ts +7 -0
  79. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.js +124 -0
  80. package/dist/infrastructure/segmentation/mobile-sam/options.d.ts +43 -0
  81. package/dist/infrastructure/segmentation/mobile-sam/options.js +19 -0
  82. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.d.ts +26 -0
  83. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.js +71 -0
  84. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.d.ts +112 -0
  85. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.js +230 -0
  86. package/dist/infrastructure/segmentation/mobile-sam/segmenter.d.ts +22 -0
  87. package/dist/infrastructure/segmentation/mobile-sam/segmenter.js +268 -0
  88. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.d.ts +7 -0
  89. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.js +188 -0
  90. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.d.ts +6 -149
  91. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.js +6 -845
  92. package/dist/infrastructure/segmentation/mobile-sam/worker-models.d.ts +14 -0
  93. package/dist/infrastructure/segmentation/mobile-sam/worker-models.js +72 -0
  94. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.d.ts +7 -0
  95. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.js +159 -0
  96. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.d.ts +4 -0
  97. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.js +126 -0
  98. package/dist/infrastructure/segmentation/native-protocol.d.ts +59 -34
  99. package/dist/infrastructure/segmentation/native-protocol.js +26 -16
  100. package/dist/infrastructure/segmentation/proposal-presentation-input.d.ts +20 -0
  101. package/dist/infrastructure/segmentation/proposal-presentation-input.js +107 -0
  102. package/dist/infrastructure/segmentation/proposal-presentation-pixels.d.ts +8 -0
  103. package/dist/infrastructure/segmentation/proposal-presentation-pixels.js +93 -0
  104. package/dist/infrastructure/segmentation/proposal-presentation.js +10 -201
  105. package/dist/infrastructure/vision-chat/options.d.ts +62 -0
  106. package/dist/infrastructure/vision-chat/options.js +46 -0
  107. package/dist/infrastructure/vision-chat/request.d.ts +23 -0
  108. package/dist/infrastructure/vision-chat/request.js +109 -0
  109. package/dist/infrastructure/vision-chat/response.d.ts +3 -0
  110. package/dist/infrastructure/vision-chat/response.js +105 -0
  111. package/dist/infrastructure/vision-chat.d.ts +4 -61
  112. package/dist/infrastructure/vision-chat.js +8 -271
  113. package/dist/openai-compatible.js +1 -1
  114. package/dist/processes/extract-from-region.js +11 -216
  115. package/dist/processes/extract.d.ts +2 -8
  116. package/dist/processes/extract.js +12 -128
  117. package/dist/processes/proposal-location.js +5 -251
  118. package/docs/0.2.0-plan.md +3 -3
  119. package/docs/README.ru.md +42 -23
  120. package/docs/acceptance.md +5 -5
  121. package/docs/agents.ru.md +95 -0
  122. package/docs/api.md +4 -2
  123. package/docs/architecture.md +33 -5
  124. package/docs/architecture.ru.md +146 -0
  125. package/docs/benchmarks.md +4 -2
  126. package/docs/development.ru.md +141 -0
  127. package/docs/operations.md +4 -4
  128. package/docs/provenance.json +5 -1
  129. package/docs/publishing.md +8 -0
  130. package/docs/refactoring-plan.ru.md +183 -0
  131. package/docs/v02-usage.md +8 -6
  132. package/docs/vision-results.md +2 -0
  133. package/package.json +5 -3
  134. package/dist/infrastructure/boundary-view.d.ts +0 -2
  135. package/dist/infrastructure/boundary-view.js +0 -263
  136. package/dist/infrastructure/openrouter-common.js +0 -317
  137. package/dist/infrastructure/text-representation.d.ts +0 -23
  138. package/dist/infrastructure/text-representation.js +0 -226
  139. package/docs/evidence/v02/categorical-heldout-v4/README.md +0 -35
  140. package/docs/evidence/v02/proposal-resource-soak-261dc23.md +0 -15
@@ -91,6 +91,7 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
91
91
  width: number;
92
92
  height: number;
93
93
  }>;
94
+ sampling: z.ZodDefault<z.ZodEnum<["seed-grid", "seed-center"]>>;
94
95
  options: z.ZodObject<{
95
96
  encoderPath: z.ZodString;
96
97
  decoderPath: z.ZodString;
@@ -112,8 +113,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
112
113
  threads?: number | undefined;
113
114
  }>;
114
115
  }, "strict", z.ZodTypeAny, {
115
- width: number;
116
- height: number;
117
116
  options: {
118
117
  encoderPath: string;
119
118
  decoderPath: string;
@@ -121,6 +120,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
121
120
  threads: number;
122
121
  deviceId?: number | undefined;
123
122
  };
123
+ width: number;
124
+ height: number;
124
125
  id: string;
125
126
  roi: {
126
127
  left: number;
@@ -135,10 +136,9 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
135
136
  width: number;
136
137
  height: number;
137
138
  };
139
+ sampling: "seed-grid" | "seed-center";
138
140
  rgba: string;
139
141
  }, {
140
- width: number;
141
- height: number;
142
142
  options: {
143
143
  encoderPath: string;
144
144
  decoderPath: string;
@@ -146,6 +146,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
146
146
  deviceId?: number | undefined;
147
147
  threads?: number | undefined;
148
148
  };
149
+ width: number;
150
+ height: number;
149
151
  id: string;
150
152
  roi: {
151
153
  left: number;
@@ -161,9 +163,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
161
163
  height: number;
162
164
  };
163
165
  rgba: string;
166
+ sampling?: "seed-grid" | "seed-center" | undefined;
164
167
  }>, {
165
- width: number;
166
- height: number;
167
168
  options: {
168
169
  encoderPath: string;
169
170
  decoderPath: string;
@@ -171,6 +172,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
171
172
  threads: number;
172
173
  deviceId?: number | undefined;
173
174
  };
175
+ width: number;
176
+ height: number;
174
177
  id: string;
175
178
  roi: {
176
179
  left: number;
@@ -185,10 +188,9 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
185
188
  width: number;
186
189
  height: number;
187
190
  };
191
+ sampling: "seed-grid" | "seed-center";
188
192
  rgba: string;
189
193
  }, {
190
- width: number;
191
- height: number;
192
194
  options: {
193
195
  encoderPath: string;
194
196
  decoderPath: string;
@@ -196,6 +198,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
196
198
  deviceId?: number | undefined;
197
199
  threads?: number | undefined;
198
200
  };
201
+ width: number;
202
+ height: number;
199
203
  id: string;
200
204
  roi: {
201
205
  left: number;
@@ -211,6 +215,7 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
211
215
  height: number;
212
216
  };
213
217
  rgba: string;
218
+ sampling?: "seed-grid" | "seed-center" | undefined;
214
219
  }>, z.ZodEffects<z.ZodObject<{
215
220
  id: z.ZodString;
216
221
  kind: z.ZodLiteral<"mobile-sam">;
@@ -286,8 +291,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
286
291
  threads?: number | undefined;
287
292
  }>;
288
293
  }, "strict", z.ZodTypeAny, {
289
- width: number;
290
- height: number;
291
294
  options: {
292
295
  encoderPath: string;
293
296
  decoderPath: string;
@@ -295,6 +298,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
295
298
  threads: number;
296
299
  deviceId?: number | undefined;
297
300
  };
301
+ width: number;
302
+ height: number;
298
303
  id: string;
299
304
  roi: {
300
305
  left: number;
@@ -318,8 +323,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
318
323
  height: number;
319
324
  };
320
325
  }, {
321
- width: number;
322
- height: number;
323
326
  options: {
324
327
  encoderPath: string;
325
328
  decoderPath: string;
@@ -327,6 +330,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
327
330
  deviceId?: number | undefined;
328
331
  threads?: number | undefined;
329
332
  };
333
+ width: number;
334
+ height: number;
330
335
  id: string;
331
336
  roi: {
332
337
  left: number;
@@ -350,8 +355,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
350
355
  };
351
356
  prompt?: "whole-region" | "seed-region" | undefined;
352
357
  }>, {
353
- width: number;
354
- height: number;
355
358
  options: {
356
359
  encoderPath: string;
357
360
  decoderPath: string;
@@ -359,6 +362,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
359
362
  threads: number;
360
363
  deviceId?: number | undefined;
361
364
  };
365
+ width: number;
366
+ height: number;
362
367
  id: string;
363
368
  roi: {
364
369
  left: number;
@@ -382,8 +387,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
382
387
  height: number;
383
388
  };
384
389
  }, {
385
- width: number;
386
- height: number;
387
390
  options: {
388
391
  encoderPath: string;
389
392
  decoderPath: string;
@@ -391,6 +394,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
391
394
  deviceId?: number | undefined;
392
395
  threads?: number | undefined;
393
396
  };
397
+ width: number;
398
+ height: number;
394
399
  id: string;
395
400
  roi: {
396
401
  left: number;
@@ -489,8 +494,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
489
494
  threads?: number | undefined;
490
495
  }>;
491
496
  }, "strict", z.ZodTypeAny, {
492
- width: number;
493
- height: number;
494
497
  options: {
495
498
  encoderPath: string;
496
499
  decoderPath: string;
@@ -498,6 +501,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
498
501
  threads: number;
499
502
  deviceId?: number | undefined;
500
503
  };
504
+ width: number;
505
+ height: number;
501
506
  id: string;
502
507
  roi: {
503
508
  left: number;
@@ -522,8 +527,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
522
527
  };
523
528
  previousMask: string;
524
529
  }, {
525
- width: number;
526
- height: number;
527
530
  options: {
528
531
  encoderPath: string;
529
532
  decoderPath: string;
@@ -531,6 +534,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
531
534
  deviceId?: number | undefined;
532
535
  threads?: number | undefined;
533
536
  };
537
+ width: number;
538
+ height: number;
534
539
  id: string;
535
540
  roi: {
536
541
  left: number;
@@ -555,8 +560,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
555
560
  previousMask: string;
556
561
  prompt?: "whole-region" | "seed-region" | undefined;
557
562
  }>, {
558
- width: number;
559
- height: number;
560
563
  options: {
561
564
  encoderPath: string;
562
565
  decoderPath: string;
@@ -564,6 +567,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
564
567
  threads: number;
565
568
  deviceId?: number | undefined;
566
569
  };
570
+ width: number;
571
+ height: number;
567
572
  id: string;
568
573
  roi: {
569
574
  left: number;
@@ -588,8 +593,6 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
588
593
  };
589
594
  previousMask: string;
590
595
  }, {
591
- width: number;
592
- height: number;
593
596
  options: {
594
597
  encoderPath: string;
595
598
  decoderPath: string;
@@ -597,6 +600,8 @@ export declare const nativeSegmentationRequestSchema: z.ZodUnion<[z.ZodObject<{
597
600
  deviceId?: number | undefined;
598
601
  threads?: number | undefined;
599
602
  };
603
+ width: number;
604
+ height: number;
600
605
  id: string;
601
606
  roi: {
602
607
  left: number;
@@ -789,16 +794,16 @@ export declare const nativeSegmentationReplySchema: z.ZodObject<{
789
794
  mask: z.ZodEffects<z.ZodString, string, string>;
790
795
  method: z.ZodString;
791
796
  }, "strict", z.ZodTypeAny, {
797
+ status: "segmented";
792
798
  width: number;
793
799
  height: number;
794
- status: "segmented";
795
800
  id: string;
796
801
  method: string;
797
802
  mask: string;
798
803
  }, {
804
+ status: "segmented";
799
805
  width: number;
800
806
  height: number;
801
- status: "segmented";
802
807
  id: string;
803
808
  method: string;
804
809
  mask: string;
@@ -814,17 +819,17 @@ export declare const nativeMobileSamExpansionReplySchema: z.ZodDiscriminatedUnio
814
819
  method: z.ZodLiteral<"mobile-sam-enclosing-mask-v1">;
815
820
  qualityScore: z.ZodNumber;
816
821
  }, "strict", z.ZodTypeAny, {
822
+ status: "expanded";
817
823
  width: number;
818
824
  height: number;
819
- status: "expanded";
820
825
  id: string;
821
826
  method: "mobile-sam-enclosing-mask-v1";
822
827
  qualityScore: number;
823
828
  mask: string;
824
829
  }, {
830
+ status: "expanded";
825
831
  width: number;
826
832
  height: number;
827
- status: "expanded";
828
833
  id: string;
829
834
  method: "mobile-sam-enclosing-mask-v1";
830
835
  qualityScore: number;
@@ -837,22 +842,22 @@ export declare const nativeMobileSamExpansionReplySchema: z.ZodDiscriminatedUnio
837
842
  height: z.ZodNumber;
838
843
  method: z.ZodLiteral<"mobile-sam-enclosing-mask-v1">;
839
844
  }, "strict", z.ZodTypeAny, {
845
+ status: "unknown";
840
846
  width: number;
841
847
  height: number;
842
- status: "unknown";
843
848
  id: string;
844
849
  reason: "no-enclosing-mask";
845
850
  method: "mobile-sam-enclosing-mask-v1";
846
851
  }, {
852
+ status: "unknown";
847
853
  width: number;
848
854
  height: number;
849
- status: "unknown";
850
855
  id: string;
851
856
  reason: "no-enclosing-mask";
852
857
  method: "mobile-sam-enclosing-mask-v1";
853
858
  }>]>;
854
859
  export type NativeMobileSamExpansionReply = z.infer<typeof nativeMobileSamExpansionReplySchema>;
855
- export declare const nativeObjectProposalReplySchema: z.ZodObject<{
860
+ export declare const nativeObjectProposalReplySchema: z.ZodEffects<z.ZodObject<{
856
861
  id: z.ZodString;
857
862
  status: z.ZodLiteral<"proposals">;
858
863
  width: z.ZodNumber;
@@ -871,9 +876,9 @@ export declare const nativeObjectProposalReplySchema: z.ZodObject<{
871
876
  mask: string;
872
877
  }>, "many">;
873
878
  }, "strict", z.ZodTypeAny, {
879
+ status: "proposals";
874
880
  width: number;
875
881
  height: number;
876
- status: "proposals";
877
882
  id: string;
878
883
  proposals: {
879
884
  id: string;
@@ -881,9 +886,29 @@ export declare const nativeObjectProposalReplySchema: z.ZodObject<{
881
886
  mask: string;
882
887
  }[];
883
888
  }, {
889
+ status: "proposals";
884
890
  width: number;
885
891
  height: number;
892
+ id: string;
893
+ proposals: {
894
+ id: string;
895
+ qualityScore: number;
896
+ mask: string;
897
+ }[];
898
+ }>, {
886
899
  status: "proposals";
900
+ width: number;
901
+ height: number;
902
+ id: string;
903
+ proposals: {
904
+ id: string;
905
+ qualityScore: number;
906
+ mask: string;
907
+ }[];
908
+ }, {
909
+ status: "proposals";
910
+ width: number;
911
+ height: number;
887
912
  id: string;
888
913
  proposals: {
889
914
  id: string;
@@ -911,13 +936,13 @@ export declare const nativeErrorReplySchema: z.ZodObject<{
911
936
  code: z.ZodEnum<["INVALID_INPUT", "INVALID_RESPONSE", "TIMEOUT", "ABORTED", "CAPACITY", "DISPOSED", "PROVIDER", "UNSUPPORTED", "RESOURCE_LIMIT"]>;
912
937
  message: z.ZodString;
913
938
  }, "strict", z.ZodTypeAny, {
939
+ status: "error";
914
940
  code: "INVALID_INPUT" | "INVALID_RESPONSE" | "TIMEOUT" | "ABORTED" | "CAPACITY" | "DISPOSED" | "PROVIDER" | "UNSUPPORTED" | "RESOURCE_LIMIT";
915
941
  message: string;
916
- status: "error";
917
942
  id: string;
918
943
  }, {
944
+ status: "error";
919
945
  code: "INVALID_INPUT" | "INVALID_RESPONSE" | "TIMEOUT" | "ABORTED" | "CAPACITY" | "DISPOSED" | "PROVIDER" | "UNSUPPORTED" | "RESOURCE_LIMIT";
920
946
  message: string;
921
- status: "error";
922
947
  id: string;
923
948
  }>;
@@ -41,6 +41,14 @@ function base64Schema(maxLength) {
41
41
  .max(maxLength)
42
42
  .refine((value) => value.length <= maxLength && isCanonicalBase64(value));
43
43
  }
44
+ const segmentationPixelLimit = 16_777_216;
45
+ function refineSegmentationImageAndRegions(value, context) {
46
+ if (value.width * value.height > segmentationPixelLimit)
47
+ context.addIssue({ code: 'custom', message: 'Image exceeds segmentation pixel limit' });
48
+ for (const region of [value.seedRegion, value.wholeRegion, value.roi])
49
+ if (region.left + region.width > value.width || region.top + region.height > value.height)
50
+ context.addIssue({ code: 'custom', message: 'Segmentation region is outside the source' });
51
+ }
44
52
  const modelOptionsSchema = z
45
53
  .object({
46
54
  encoderPath: z.string().min(1).max(4096),
@@ -78,13 +86,7 @@ const mobileSamRequestSchema = z
78
86
  options: modelOptionsSchema,
79
87
  })
80
88
  .strict()
81
- .superRefine((value, context) => {
82
- if (value.width * value.height > 16_777_216)
83
- context.addIssue({ code: 'custom', message: 'Image exceeds segmentation pixel limit' });
84
- for (const region of [value.seedRegion, value.wholeRegion, value.roi])
85
- if (region.left + region.width > value.width || region.top + region.height > value.height)
86
- context.addIssue({ code: 'custom', message: 'Segmentation region is outside the source' });
87
- });
89
+ .superRefine(refineSegmentationImageAndRegions);
88
90
  const mobileSamExpandRequestSchema = z
89
91
  .object({
90
92
  id: z.string().uuid(),
@@ -126,6 +128,7 @@ const mobileSamProposalsRequestSchema = z
126
128
  rgba: base64Schema(11_200_000),
127
129
  seedRegion: pixelRectSchema,
128
130
  roi: pixelRectSchema,
131
+ sampling: z.enum(['seed-grid', 'seed-center']).default('seed-grid'),
129
132
  options: modelOptionsSchema.extend({ executionProvider: z.literal('cpu') }),
130
133
  })
131
134
  .strict()
@@ -150,13 +153,7 @@ const grabCutRequestSchema = z
150
153
  assetPath: z.string().min(1).max(4096),
151
154
  })
152
155
  .strict()
153
- .superRefine((value, context) => {
154
- if (value.width * value.height > 16_777_216)
155
- context.addIssue({ code: 'custom', message: 'Image exceeds segmentation pixel limit' });
156
- for (const region of [value.seedRegion, value.wholeRegion, value.roi])
157
- if (region.left + region.width > value.width || region.top + region.height > value.height)
158
- context.addIssue({ code: 'custom', message: 'Segmentation region is outside the source' });
159
- });
156
+ .superRefine(refineSegmentationImageAndRegions);
160
157
  export const nativeSegmentationRequestSchema = z.union([
161
158
  mobileSamProbeSchema,
162
159
  grabCutProbeSchema,
@@ -212,9 +209,22 @@ export const nativeObjectProposalReplySchema = z
212
209
  qualityScore: z.number().finite(),
213
210
  })
214
211
  .strict())
215
- .length(36),
212
+ .min(4)
213
+ .max(36),
216
214
  })
217
- .strict();
215
+ .strict()
216
+ .superRefine((value, context) => {
217
+ if (value.proposals.length !== 4 && value.proposals.length !== 36)
218
+ context.addIssue({ code: 'custom', message: 'Proposal reply must contain four or 36 masks' });
219
+ for (const [index, proposal] of value.proposals.entries()) {
220
+ const expectedId = `C${String(index).padStart(2, '0')}`;
221
+ if (proposal.id !== expectedId)
222
+ context.addIssue({
223
+ code: 'custom',
224
+ message: 'Proposal aliases must be contiguous from C00',
225
+ });
226
+ }
227
+ });
218
228
  export const nativeProbeReplySchema = z
219
229
  .object({
220
230
  id: z.string().uuid(),
@@ -0,0 +1,20 @@
1
+ import { ClassifierError } from '../../entities/errors.js';
2
+ import type { PixelRect } from '../../entities/contracts.js';
3
+ import type { ObjectProposalPresentationPort } from '../../entities/object-proposals.js';
4
+ import type { RgbaRaster } from '../../entities/representation.js';
5
+ type ProposalSnapshot = {
6
+ id: string;
7
+ data: Uint8Array;
8
+ region: PixelRect | null;
9
+ bounds: PixelRect | null;
10
+ };
11
+ export declare function assertProposalSignal(signal: AbortSignal): void;
12
+ type PresentationRenderInput = Parameters<ObjectProposalPresentationPort['render']>[0];
13
+ export declare function snapshotOwnedPresentationInput(input: PresentationRenderInput): {
14
+ source: Uint8Array;
15
+ image: RgbaRaster;
16
+ seedRegion: PixelRect;
17
+ snapshots: ProposalSnapshot[];
18
+ };
19
+ export declare function proposalInvalid(message: string): ClassifierError;
20
+ export {};
@@ -0,0 +1,107 @@
1
+ import { ClassifierError, assertActive } from '../../entities/errors.js';
2
+ import { objectProposalLimits } from '../../entities/object-proposals.js';
3
+ import { unpackBinaryMask } from '../../features/segmentation/packed-mask.js';
4
+ import { maskBounds } from './proposal-presentation-pixels.js';
5
+ export function assertProposalSignal(signal) {
6
+ if (!(signal instanceof AbortSignal))
7
+ throw proposalInvalid('signal must be an AbortSignal');
8
+ assertActive(signal);
9
+ }
10
+ function assertProposalImage(image) {
11
+ if (image.format !== 'rgba8' ||
12
+ !Number.isSafeInteger(image.width) ||
13
+ !Number.isSafeInteger(image.height) ||
14
+ image.width < 1 ||
15
+ image.height < 1 ||
16
+ image.width * image.height > objectProposalLimits.imagePixels ||
17
+ image.data.length !== image.width * image.height * 4)
18
+ throw proposalInvalid('Expected canonical RGBA image within proposal limits');
19
+ }
20
+ function assertProposalRect(rect, width, height, name) {
21
+ if (!rect ||
22
+ !Number.isSafeInteger(rect.left) ||
23
+ !Number.isSafeInteger(rect.top) ||
24
+ !Number.isSafeInteger(rect.width) ||
25
+ !Number.isSafeInteger(rect.height) ||
26
+ rect.left < 0 ||
27
+ rect.top < 0 ||
28
+ rect.width < 1 ||
29
+ rect.height < 1 ||
30
+ rect.left + rect.width > width ||
31
+ rect.top + rect.height > height)
32
+ throw proposalInvalid(`${name} is outside the source image`);
33
+ }
34
+ export function snapshotOwnedPresentationInput(input) {
35
+ const callerImage = input.image;
36
+ assertProposalImage(callerImage);
37
+ const callerSeedRegion = input.seedRegion;
38
+ assertProposalRect(callerSeedRegion, callerImage.width, callerImage.height, 'seedRegion');
39
+ const image = {
40
+ data: new Uint8Array(callerImage.data),
41
+ width: callerImage.width,
42
+ height: callerImage.height,
43
+ format: callerImage.format,
44
+ };
45
+ const seedRegion = { ...callerSeedRegion };
46
+ const proposals = input.proposals;
47
+ if (!Array.isArray(proposals) ||
48
+ proposals.length < 1 ||
49
+ proposals.length > objectProposalLimits.candidates)
50
+ throw proposalInvalid('Expected 1..36 object proposals');
51
+ const source = image.data;
52
+ let previousAlias = -1;
53
+ for (const proposal of proposals) {
54
+ const match = typeof proposal.id === 'string' ? /^C(\d{2})$/.exec(proposal.id) : null;
55
+ const alias = match ? Number(match[1]) : -1;
56
+ if (alias < 0 || alias >= objectProposalLimits.candidates || alias <= previousAlias)
57
+ throw proposalInvalid('Proposal aliases must be unique and retain source order');
58
+ previousAlias = alias;
59
+ }
60
+ const snapshots = proposals.map((proposal) => snapshotProposal(proposal, image));
61
+ if (snapshots.reduce((sum, item) => sum + item.data.byteLength, 0) >
62
+ objectProposalLimits.packedBytes)
63
+ throw proposalInvalid('Packed proposal data exceeds the byte limit');
64
+ return { source, image, seedRegion, snapshots };
65
+ }
66
+ function snapshotProposal(proposal, image) {
67
+ const id = proposal.id;
68
+ const mask = proposal.mask;
69
+ const expectedBytes = Math.ceil((image.width * image.height) / 8);
70
+ if (!/^C(?:0[0-9]|[12][0-9]|3[0-5])$/.test(id) ||
71
+ !mask ||
72
+ mask.format !== 'binary-lsb0' ||
73
+ mask.width !== image.width ||
74
+ mask.height !== image.height ||
75
+ !(mask.data instanceof Uint8Array) ||
76
+ mask.data.byteLength !== expectedBytes)
77
+ throw proposalInvalid('Object proposal aliases or packed mask dimensions are invalid');
78
+ const data = new Uint8Array(mask.data);
79
+ const decoded = unpackBinaryMask({
80
+ data,
81
+ width: image.width,
82
+ height: image.height,
83
+ format: 'binary-lsb0',
84
+ });
85
+ const bounds = maskBounds(decoded, image.width, image.height);
86
+ if (bounds === null) {
87
+ if (proposal.region !== null)
88
+ throw proposalInvalid('Empty proposal must have a null pixel region');
89
+ }
90
+ else if (proposal.region !== null) {
91
+ assertProposalRect(proposal.region, image.width, image.height, 'proposal region');
92
+ if (proposal.region.left !== bounds.left ||
93
+ proposal.region.top !== bounds.top ||
94
+ proposal.region.width !== bounds.width ||
95
+ proposal.region.height !== bounds.height)
96
+ throw proposalInvalid('Proposal region does not match packed mask support');
97
+ }
98
+ return {
99
+ id,
100
+ data,
101
+ region: bounds ? { ...bounds } : null,
102
+ bounds: bounds ? { ...bounds } : null,
103
+ };
104
+ }
105
+ export function proposalInvalid(message) {
106
+ return new ClassifierError('INVALID_RESPONSE', message);
107
+ }
@@ -0,0 +1,8 @@
1
+ import type { PixelRect } from '../../entities/contracts.js';
2
+ export declare function maskBounds(mask: Uint8Array, width: number, height: number): PixelRect | null;
3
+ export declare function makeOverlay(source: Uint8Array, mask: Uint8Array, width: number, height: number, bounds: PixelRect | null): Uint8Array;
4
+ export declare function makeCutout(source: Uint8Array, mask: Uint8Array, width: number, height: number, bounds: PixelRect): {
5
+ data: Uint8Array;
6
+ width: number;
7
+ height: number;
8
+ };
@@ -0,0 +1,93 @@
1
+ export function maskBounds(mask, width, height) {
2
+ let left = width;
3
+ let top = height;
4
+ let right = -1;
5
+ let bottom = -1;
6
+ for (let y = 0; y < height; y++) {
7
+ for (let x = 0; x < width; x++) {
8
+ if (mask[y * width + x] === 0)
9
+ continue;
10
+ if (x < left)
11
+ left = x;
12
+ if (x > right)
13
+ right = x;
14
+ if (y < top)
15
+ top = y;
16
+ if (y > bottom)
17
+ bottom = y;
18
+ }
19
+ }
20
+ return right < left || bottom < top
21
+ ? null
22
+ : { left, top, width: right - left + 1, height: bottom - top + 1 };
23
+ }
24
+ export function makeOverlay(source, mask, width, height, bounds) {
25
+ const output = new Uint8Array(source.length);
26
+ for (let y = 0; y < height; y++) {
27
+ for (let x = 0; x < width; x++) {
28
+ const index = y * width + x;
29
+ const offset = index * 4;
30
+ output[offset] = source[offset];
31
+ output[offset + 1] = source[offset + 1];
32
+ output[offset + 2] = source[offset + 2];
33
+ output[offset + 3] = source[offset + 3];
34
+ if (mask[index] === 0)
35
+ continue;
36
+ const edge = x === 0 ||
37
+ y === 0 ||
38
+ x === width - 1 ||
39
+ y === height - 1 ||
40
+ mask[index - 1] === 0 ||
41
+ mask[index + 1] === 0 ||
42
+ mask[index - width] === 0 ||
43
+ mask[index + width] === 0;
44
+ if (edge) {
45
+ output[offset] = 0;
46
+ output[offset + 1] = 255;
47
+ output[offset + 2] = 255;
48
+ output[offset + 3] = 255;
49
+ }
50
+ else {
51
+ output[offset] = Math.round(source[offset] * 0.65 + 255 * 0.35);
52
+ output[offset + 1] = Math.round(source[offset + 1] * 0.65 + 32 * 0.35);
53
+ output[offset + 2] = Math.round(source[offset + 2] * 0.65 + 32 * 0.35);
54
+ }
55
+ }
56
+ }
57
+ if (bounds !== null) {
58
+ const right = bounds.left + bounds.width - 1;
59
+ const bottom = bounds.top + bounds.height - 1;
60
+ for (let x = bounds.left; x <= right; x++) {
61
+ paintRectanglePixel(output, width, x, bounds.top);
62
+ paintRectanglePixel(output, width, x, bottom);
63
+ }
64
+ for (let y = bounds.top; y <= bottom; y++) {
65
+ paintRectanglePixel(output, width, bounds.left, y);
66
+ paintRectanglePixel(output, width, right, y);
67
+ }
68
+ }
69
+ return output;
70
+ }
71
+ function paintRectanglePixel(output, width, x, y) {
72
+ const offset = (y * width + x) * 4;
73
+ output[offset] = 255;
74
+ output[offset + 1] = 220;
75
+ output[offset + 2] = 0;
76
+ output[offset + 3] = 255;
77
+ }
78
+ export function makeCutout(source, mask, width, height, bounds) {
79
+ const data = new Uint8Array(bounds.width * bounds.height * 4);
80
+ for (let y = 0; y < bounds.height; y++) {
81
+ for (let x = 0; x < bounds.width; x++) {
82
+ const sourceIndex = (bounds.top + y) * width + bounds.left + x;
83
+ const outputIndex = (y * bounds.width + x) * 4;
84
+ if (mask[sourceIndex] === 0)
85
+ continue;
86
+ data[outputIndex] = source[sourceIndex * 4];
87
+ data[outputIndex + 1] = source[sourceIndex * 4 + 1];
88
+ data[outputIndex + 2] = source[sourceIndex * 4 + 2];
89
+ data[outputIndex + 3] = source[sourceIndex * 4 + 3];
90
+ }
91
+ }
92
+ return { data, width: bounds.width, height: bounds.height };
93
+ }