zorya-classifier 0.2.1 → 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 (126) hide show
  1. package/README.md +3 -3
  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 -34
  14. package/dist/app/create-classifier.js +37 -237
  15. package/dist/entities/classification.d.ts +98 -0
  16. package/dist/entities/classification.js +28 -0
  17. package/dist/entities/contracts.d.ts +6 -475
  18. package/dist/entities/contracts.js +6 -97
  19. package/dist/entities/decision.d.ts +211 -0
  20. package/dist/entities/decision.js +33 -0
  21. package/dist/entities/geometry.d.ts +37 -0
  22. package/dist/entities/geometry.js +26 -0
  23. package/dist/entities/image.d.ts +39 -0
  24. package/dist/entities/image.js +15 -0
  25. package/dist/entities/localization.d.ts +125 -0
  26. package/dist/entities/localization.js +13 -0
  27. package/dist/entities/segmentation-metadata.d.ts +70 -0
  28. package/dist/entities/segmentation-metadata.js +21 -1
  29. package/dist/entities/validation.d.ts +2 -0
  30. package/dist/entities/validation.js +9 -0
  31. package/dist/features/choice-beam-layout.js +2 -7
  32. package/dist/features/proposals/presentation.d.ts +21 -0
  33. package/dist/features/proposals/presentation.js +122 -0
  34. package/dist/features/proposals/validation.d.ts +138 -0
  35. package/dist/features/proposals/validation.js +125 -0
  36. package/dist/features/segmentation/box-check.js +10 -23
  37. package/dist/features/segmentation/mask.js +2 -7
  38. package/dist/features/segmentation/region-result.d.ts +18 -0
  39. package/dist/features/segmentation/region-result.js +171 -0
  40. package/dist/features/segmentation/source-mask.d.ts +6 -0
  41. package/dist/features/segmentation/source-mask.js +32 -0
  42. package/dist/features/segmentation/validation.d.ts +9 -0
  43. package/dist/features/segmentation/validation.js +94 -0
  44. package/dist/infrastructure/decision-transport/errors.d.ts +8 -0
  45. package/dist/infrastructure/decision-transport/errors.js +34 -0
  46. package/dist/infrastructure/decision-transport/images.d.ts +1 -0
  47. package/dist/infrastructure/decision-transport/images.js +52 -0
  48. package/dist/infrastructure/{openrouter-common.d.ts → decision-transport/request.d.ts} +6 -15
  49. package/dist/infrastructure/decision-transport/request.js +162 -0
  50. package/dist/infrastructure/decision-transport/response.d.ts +1 -0
  51. package/dist/infrastructure/decision-transport/response.js +72 -0
  52. package/dist/infrastructure/decision-transport/route-identity.d.ts +11 -0
  53. package/dist/infrastructure/decision-transport/route-identity.js +23 -0
  54. package/dist/infrastructure/openrouter-vision.js +1 -1
  55. package/dist/infrastructure/openrouter.js +7 -19
  56. package/dist/infrastructure/raster.js +3 -8
  57. package/dist/infrastructure/segmentation/grabcut/index.js +2 -4
  58. package/dist/infrastructure/segmentation/grabcut/masks.d.ts +49 -0
  59. package/dist/infrastructure/segmentation/grabcut/masks.js +89 -0
  60. package/dist/infrastructure/segmentation/grabcut/model-asset.d.ts +4 -0
  61. package/dist/infrastructure/segmentation/grabcut/model-asset.js +4 -0
  62. package/dist/infrastructure/segmentation/grabcut/runtime.d.ts +70 -0
  63. package/dist/infrastructure/segmentation/grabcut/runtime.js +96 -0
  64. package/dist/infrastructure/segmentation/grabcut/worker-inference.d.ts +4 -43
  65. package/dist/infrastructure/segmentation/grabcut/worker-inference.js +4 -187
  66. package/dist/infrastructure/segmentation/mobile-sam/index.d.ts +3 -66
  67. package/dist/infrastructure/segmentation/mobile-sam/index.js +2 -478
  68. package/dist/infrastructure/segmentation/mobile-sam/input.d.ts +46 -0
  69. package/dist/infrastructure/segmentation/mobile-sam/input.js +83 -0
  70. package/dist/infrastructure/segmentation/mobile-sam/model-assets.d.ts +8 -0
  71. package/dist/infrastructure/segmentation/mobile-sam/model-assets.js +8 -0
  72. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.d.ts +7 -0
  73. package/dist/infrastructure/segmentation/mobile-sam/object-proposals.js +124 -0
  74. package/dist/infrastructure/segmentation/mobile-sam/options.d.ts +43 -0
  75. package/dist/infrastructure/segmentation/mobile-sam/options.js +19 -0
  76. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.d.ts +26 -0
  77. package/dist/infrastructure/segmentation/mobile-sam/proposal-masks.js +71 -0
  78. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.d.ts +112 -0
  79. package/dist/infrastructure/segmentation/mobile-sam/segmentation-masks.js +230 -0
  80. package/dist/infrastructure/segmentation/mobile-sam/segmenter.d.ts +22 -0
  81. package/dist/infrastructure/segmentation/mobile-sam/segmenter.js +268 -0
  82. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.d.ts +7 -0
  83. package/dist/infrastructure/segmentation/mobile-sam/worker-expand.js +188 -0
  84. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.d.ts +6 -149
  85. package/dist/infrastructure/segmentation/mobile-sam/worker-inference.js +6 -845
  86. package/dist/infrastructure/segmentation/mobile-sam/worker-models.d.ts +14 -0
  87. package/dist/infrastructure/segmentation/mobile-sam/worker-models.js +72 -0
  88. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.d.ts +7 -0
  89. package/dist/infrastructure/segmentation/mobile-sam/worker-proposals.js +159 -0
  90. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.d.ts +4 -0
  91. package/dist/infrastructure/segmentation/mobile-sam/worker-segment.js +126 -0
  92. package/dist/infrastructure/segmentation/native-protocol.d.ts +59 -34
  93. package/dist/infrastructure/segmentation/native-protocol.js +26 -16
  94. package/dist/infrastructure/segmentation/proposal-presentation-input.d.ts +20 -0
  95. package/dist/infrastructure/segmentation/proposal-presentation-input.js +107 -0
  96. package/dist/infrastructure/segmentation/proposal-presentation-pixels.d.ts +8 -0
  97. package/dist/infrastructure/segmentation/proposal-presentation-pixels.js +93 -0
  98. package/dist/infrastructure/segmentation/proposal-presentation.js +10 -201
  99. package/dist/infrastructure/vision-chat/options.d.ts +62 -0
  100. package/dist/infrastructure/vision-chat/options.js +46 -0
  101. package/dist/infrastructure/vision-chat/request.d.ts +23 -0
  102. package/dist/infrastructure/vision-chat/request.js +109 -0
  103. package/dist/infrastructure/vision-chat/response.d.ts +3 -0
  104. package/dist/infrastructure/vision-chat/response.js +105 -0
  105. package/dist/infrastructure/vision-chat.d.ts +4 -61
  106. package/dist/infrastructure/vision-chat.js +8 -271
  107. package/dist/openai-compatible.js +1 -1
  108. package/dist/processes/extract-from-region.js +11 -216
  109. package/dist/processes/extract.d.ts +2 -8
  110. package/dist/processes/extract.js +12 -128
  111. package/dist/processes/proposal-location.js +5 -251
  112. package/docs/README.ru.md +15 -12
  113. package/docs/agents.ru.md +95 -0
  114. package/docs/architecture.md +31 -5
  115. package/docs/architecture.ru.md +146 -0
  116. package/docs/benchmarks.md +3 -1
  117. package/docs/development.ru.md +141 -0
  118. package/docs/provenance.json +5 -1
  119. package/docs/publishing.md +5 -3
  120. package/docs/refactoring-plan.ru.md +183 -0
  121. package/package.json +4 -2
  122. package/dist/infrastructure/boundary-view.d.ts +0 -2
  123. package/dist/infrastructure/boundary-view.js +0 -263
  124. package/dist/infrastructure/openrouter-common.js +0 -317
  125. package/dist/infrastructure/text-representation.d.ts +0 -23
  126. package/dist/infrastructure/text-representation.js +0 -226
@@ -1,77 +1,26 @@
1
- import { z } from 'zod';
2
1
  import { classifySchema, locateSchema, parse } from '../entities/contracts.js';
3
2
  import { ClassifierError } from '../entities/errors.js';
4
3
  import { createSharpRaster } from '../infrastructure/raster.js';
5
4
  import { classifyInput } from '../processes/classify.js';
6
5
  import { locateInput } from '../processes/locate.js';
7
- import { OperationGate } from '../shared/gate.js';
8
- import { OperationScope } from '../shared/scope.js';
9
- import { InputBudget } from '../shared/input-budget.js';
10
6
  import { wholeObjectSchema } from '../entities/whole-object.js';
11
- import { locateWholeObjectInput } from '../processes/whole-object.js';
12
- import { preparedTextSchema, representationLimits } from '../entities/representation.js';
13
7
  import { extractSchema } from '../entities/segmentation.js';
14
- import { extractObject } from '../processes/extract.js';
15
- import { extractFromRegion } from '../processes/extract-from-region.js';
16
8
  import { createSharpCutoutRaster } from '../infrastructure/segmentation/cutout-raster.js';
17
- import { locateFromProposals } from '../processes/proposal-location.js';
18
9
  import { createSharpObjectProposalPresentation } from '../infrastructure/segmentation/proposal-presentation.js';
19
10
  import { createSegmentationBoxCheck } from '../features/segmentation/box-check.js';
20
11
  import { createSharpSegmentationBoxPresentation } from '../infrastructure/segmentation/box-presentation.js';
21
- const configSchema = z.object({
22
- timeoutMs: z.number().int().min(1).max(120000).default(45000),
23
- concurrency: z.number().int().min(1).max(4).default(2),
24
- maxQueue: z.number().int().min(0).max(32).default(16),
25
- maxInputBytes: z
26
- .number()
27
- .int()
28
- .min(1)
29
- .max(256 * 1024 * 1024)
30
- .default(64 * 1024 * 1024),
31
- });
32
- function signalOf(value) {
33
- if (value === undefined)
34
- return undefined;
35
- if (!(value instanceof AbortSignal))
36
- throw new ClassifierError('INVALID_INPUT', 'signal must be an AbortSignal');
37
- return value;
38
- }
12
+ import { validateClassifierOptions } from './classifier-config.js';
13
+ import { createClassifierRepresentation } from './classifier-representation.js';
14
+ import { createClassifierRuntime, parseOperationSignal } from './classifier-runtime.js';
15
+ import { createClassifierSpatial } from './classifier-spatial.js';
39
16
  export function createClassifier(options) {
40
17
  return composeClassifier(options);
41
18
  }
42
- /** Internal benchmark composition. No research codec is exported by the npm entry points. */
43
- export function createResearchClassifier(options, experimental, boundaryView, intervalPolicy) {
44
- return composeClassifier(options, experimental, boundaryView, intervalPolicy);
45
- }
46
- function composeClassifier(options, experimental, boundaryView, intervalPolicy) {
47
- if (!options || typeof options.decision?.decide !== 'function')
48
- throw new ClassifierError('INVALID_INPUT', 'A DecisionPort is required');
49
- const segmenter = options.segmentation;
50
- const objectProposals = options.objectProposals;
51
- if (segmenter !== undefined &&
52
- (!segmenter ||
53
- typeof segmenter.segment !== 'function' ||
54
- (segmenter.expand !== undefined && typeof segmenter.expand !== 'function') ||
55
- typeof segmenter.settle !== 'function' ||
56
- typeof segmenter.dispose !== 'function'))
57
- throw new ClassifierError('INVALID_INPUT', 'segmentation must implement SegmentationPort');
58
- if (options.segmentationBoxCheck !== undefined &&
59
- (!options.segmentationBoxCheck || typeof options.segmentationBoxCheck.check !== 'function'))
60
- throw new ClassifierError('INVALID_INPUT', 'segmentationBoxCheck must implement its check port');
61
- if (objectProposals !== undefined &&
62
- (!objectProposals ||
63
- typeof objectProposals.propose !== 'function' ||
64
- typeof objectProposals.settle !== 'function' ||
65
- typeof objectProposals.dispose !== 'function'))
66
- throw new ClassifierError('INVALID_INPUT', 'objectProposals must implement ObjectProposalPort');
67
- const config = parse(configSchema, {
68
- timeoutMs: options.timeoutMs,
69
- concurrency: options.concurrency,
70
- maxQueue: options.maxQueue,
71
- maxInputBytes: options.maxInputBytes,
72
- });
73
- const gate = new OperationGate(config.concurrency, config.maxQueue);
74
- const inputBudget = new InputBudget(config.maxInputBytes);
19
+ /** Internal composition seam for benchmark helpers; not re-exported from public entry points. */
20
+ export function composeClassifier(options, experimental, boundaryView, intervalPolicy) {
21
+ const { config, ports } = validateClassifierOptions(options);
22
+ const { segmenter, objectProposals } = ports;
23
+ const runtime = createClassifierRuntime(config);
75
24
  const raster = createSharpRaster();
76
25
  const cutoutRaster = createSharpCutoutRaster();
77
26
  const boxCheck = segmenter
@@ -91,146 +40,47 @@ function composeClassifier(options, experimental, boundaryView, intervalPolicy)
91
40
  presentation: createSharpObjectProposalPresentation(),
92
41
  }
93
42
  : undefined;
94
- const owned = new Map();
95
- let disposed = false;
96
- const textRepresentation = experimental
97
- ? {
98
- async prepare(input) {
99
- const result = parse(preparedTextSchema, await experimental.prepare(input), 'INVALID_RESPONSE');
100
- const bytes = result.state.reduce((sum, part) => sum + Buffer.byteLength(part, 'utf8'), 0);
101
- if (bytes > representationLimits.totalBytes || bytes !== result.metadata.bytes)
102
- throw new ClassifierError('INVALID_RESPONSE', 'Representation byte accounting is inconsistent');
103
- return {
104
- state: result.state,
105
- metadata: {
106
- ...result.metadata,
107
- views: result.metadata.views.map(({ content, ...view }) => ({
108
- ...view,
109
- ...(content === undefined ? {} : { content }),
110
- })),
111
- },
112
- };
113
- },
114
- }
115
- : undefined;
116
- function representationFor(value) {
117
- if (value?.type !== 'experimental-text')
118
- return undefined;
119
- if (!textRepresentation)
120
- throw new ClassifierError('UNSUPPORTED', 'No text-image profile has passed release qualification yet');
121
- return textRepresentation;
122
- }
123
- async function locateWhole(input, signal, representation) {
124
- if (segmenter) {
125
- const result = await extractRegion(input, signal, representation);
126
- if (result.status === 'extracted')
127
- return result.location;
128
- if (result.status === 'unknown' && result.reason === 'segmentation-uncertain')
129
- return {
130
- status: 'unknown',
131
- reason: 'segmentation-uncertain',
132
- metadata: 'metadata' in result ? result.metadata : result.location.metadata,
133
- ...(result.verification ? { verification: result.verification } : {}),
134
- };
135
- return result;
136
- }
137
- if (proposalDependencies) {
138
- if (representation)
139
- throw new ClassifierError('UNSUPPORTED', 'Mask proposal selection requires vision input');
140
- return (await locateFromProposals(input, proposalDependencies, signal)).location;
141
- }
142
- return locateWholeObjectInput(input, options.decision, raster, signal, representation, boundaryView, intervalPolicy);
143
- }
144
- function extractRegion(input, signal, representation) {
145
- if (!segmenter || !boxCheck)
146
- throw new ClassifierError('UNSUPPORTED', 'Region extraction requires a SegmentationPort');
147
- if (representation)
148
- throw new ClassifierError('UNSUPPORTED', 'Checked segmentation requires vision input');
149
- return extractFromRegion({ ...input, signal }, {
150
- raster,
151
- image: cutoutRaster,
152
- segmenter,
153
- boxCheck,
154
- locateRegion: (source, { signal: operationSignal, ...request }) => locateInput({ ...request, image: source.bytes }, options.decision, raster, operationSignal, undefined, representation),
155
- });
156
- }
157
- async function run(signal, task) {
158
- if (disposed)
159
- throw new ClassifierError('DISPOSED', 'Classifier has been disposed');
160
- const scope = new OperationScope(config.timeoutMs, signal);
161
- const job = (async () => {
162
- let acquired = false;
163
- try {
164
- await gate.acquire(scope.signal);
165
- acquired = true;
166
- scope.guard();
167
- const result = await task(scope.signal);
168
- scope.guard();
169
- return result;
170
- }
171
- catch (error) {
172
- scope.guard();
173
- throw error;
174
- }
175
- finally {
176
- if (acquired)
177
- gate.release();
178
- scope.dispose();
179
- owned.delete(scope);
180
- }
181
- })();
182
- owned.set(scope, job);
183
- return job;
184
- }
43
+ const { representationFor } = createClassifierRepresentation(experimental);
44
+ const spatial = createClassifierSpatial({
45
+ getDecision: () => options.decision,
46
+ raster,
47
+ cutoutRaster,
48
+ segmenter,
49
+ boxCheck,
50
+ proposalDependencies,
51
+ boundaryView,
52
+ intervalPolicy,
53
+ });
185
54
  async function locate(input) {
186
- if (disposed)
187
- throw new ClassifierError('DISPOSED', 'Classifier has been disposed');
188
- gate.assertAvailable();
55
+ runtime.assertAcceptingOperations();
189
56
  if (!input || typeof input !== 'object')
190
57
  throw new ClassifierError('INVALID_INPUT', 'Expected locate input object');
191
58
  const { signal, ...rest } = input;
192
- const parent = signalOf(signal);
59
+ const parent = parseOperationSignal(signal);
193
60
  if (rest.mode === 'whole-object') {
194
61
  const parsed = parse(wholeObjectSchema, rest);
195
62
  const representation = representationFor(parsed.representation);
196
- const release = inputBudget.reserve(parsed.image.byteLength);
197
- try {
198
- const snapshot = { ...parsed, image: new Uint8Array(parsed.image) };
199
- return await run(parent, (s) => locateWhole(snapshot, s, representation));
200
- }
201
- finally {
202
- release();
203
- }
63
+ return runtime.withOwnedInput(parsed.image.byteLength, parent, () => ({ ...parsed, image: new Uint8Array(parsed.image) }), (snapshot, s) => spatial.locateWhole(snapshot, s, representation));
204
64
  }
205
65
  const parsed = parse(locateSchema, rest);
206
66
  const representation = representationFor(parsed.representation);
207
- const release = inputBudget.reserve(parsed.image.byteLength);
208
- try {
209
- const snapshot = { ...parsed, image: new Uint8Array(parsed.image) };
210
- return await run(parent, (s) => locateInput(snapshot, options.decision, raster, s, options.refinement, representation));
211
- }
212
- finally {
213
- release();
214
- }
67
+ return runtime.withOwnedInput(parsed.image.byteLength, parent, () => ({ ...parsed, image: new Uint8Array(parsed.image) }), (snapshot, s) => locateInput(snapshot, options.decision, raster, s, options.refinement, representation));
215
68
  }
216
69
  return {
217
70
  async classify(input) {
218
- if (disposed)
219
- throw new ClassifierError('DISPOSED', 'Classifier has been disposed');
220
- gate.assertAvailable();
71
+ runtime.assertAcceptingOperations();
221
72
  if (!input || typeof input !== 'object')
222
73
  throw new ClassifierError('INVALID_INPUT', 'Expected classify input object');
223
74
  const { signal, ...rest } = input;
224
- const parent = signalOf(signal);
75
+ const parent = parseOperationSignal(signal);
225
76
  const parsed = parse(classifySchema, rest);
226
77
  const hasImage = typeof parsed.input !== 'string' && parsed.input.image !== undefined;
227
78
  const representation = hasImage ? representationFor(parsed.representation) : undefined;
228
79
  const byteCount = typeof parsed.input === 'string'
229
80
  ? Buffer.byteLength(parsed.input)
230
81
  : (parsed.input.image?.byteLength ?? 0) + Buffer.byteLength(parsed.input.text ?? '');
231
- const release = inputBudget.reserve(byteCount);
232
- try {
233
- const media = typeof parsed.input === 'string'
82
+ return runtime.withOwnedInput(byteCount, parent, () => {
83
+ return typeof parsed.input === 'string'
234
84
  ? parsed.input
235
85
  : {
236
86
  ...parsed.input,
@@ -238,75 +88,25 @@ function composeClassifier(options, experimental, boundaryView, intervalPolicy)
238
88
  ? {}
239
89
  : { image: new Uint8Array(parsed.input.image) }),
240
90
  };
241
- return await run(parent, (s) => classifyInput({ ...parsed, input: media }, options.decision, raster, s, representation));
242
- }
243
- finally {
244
- release();
245
- }
91
+ }, (media, s) => classifyInput({ ...parsed, input: media }, options.decision, raster, s, representation));
246
92
  },
247
93
  locate,
248
94
  async extract(input) {
249
- if (disposed)
250
- throw new ClassifierError('DISPOSED', 'Classifier has been disposed');
251
- gate.assertAvailable();
95
+ runtime.assertAcceptingOperations();
252
96
  if (!input || typeof input !== 'object')
253
97
  throw new ClassifierError('INVALID_INPUT', 'Expected extract input object');
254
98
  const { signal, ...rest } = input;
255
- const parent = signalOf(signal);
99
+ const parent = parseOperationSignal(signal);
256
100
  const parsed = parse(extractSchema, rest);
257
101
  if (!segmenter && !proposalDependencies)
258
102
  throw new ClassifierError('UNSUPPORTED', 'extract requires an explicit SegmentationPort or ObjectProposalPort');
259
103
  const representation = representationFor(parsed.representation);
260
- const release = inputBudget.reserve(parsed.image.byteLength);
261
- try {
262
- const snapshot = { ...parsed, image: new Uint8Array(parsed.image) };
263
- return await run(parent, (s) => {
264
- if (segmenter)
265
- return extractRegion(snapshot, s, representation);
266
- let prepared;
267
- // Per-operation ownership: no global selected-mask cache or second native inference.
268
- const selectedMask = {
269
- async segment() {
270
- if (!prepared?.mask || !prepared.segmentation)
271
- throw new ClassifierError('INVALID_RESPONSE', 'Proposal selection omitted its mask');
272
- return {
273
- status: 'segmented',
274
- mask: prepared.mask,
275
- metadata: prepared.segmentation,
276
- };
277
- },
278
- async settle() { },
279
- async dispose() { },
280
- };
281
- return extractObject({ ...snapshot, mode: 'whole-object', signal: s }, {
282
- raster,
283
- image: cutoutRaster,
284
- segmenter: selectedMask,
285
- locateWhole: async (source, { signal: requestSignal, ...request }) => {
286
- const wholeInput = {
287
- ...request,
288
- mode: 'whole-object',
289
- image: source.bytes,
290
- };
291
- if (!proposalDependencies)
292
- throw new ClassifierError('UNSUPPORTED', 'ObjectProposalPort is required');
293
- if (representation)
294
- throw new ClassifierError('UNSUPPORTED', 'Mask proposal selection requires vision input');
295
- prepared = await locateFromProposals(wholeInput, proposalDependencies, requestSignal);
296
- return prepared.location;
297
- },
298
- });
299
- });
300
- }
301
- finally {
302
- release();
303
- }
304
- },
305
- async dispose() {
306
- disposed = true;
307
- for (const scope of owned.keys())
308
- scope.abort();
309
- await Promise.allSettled(owned.values());
104
+ return runtime.withOwnedInput(parsed.image.byteLength, parent, () => ({ ...parsed, image: new Uint8Array(parsed.image) }), (snapshot, s) => {
105
+ if (segmenter)
106
+ return spatial.extractRegion(snapshot, s, representation);
107
+ return spatial.extractWithProposals(snapshot, s, representation);
108
+ });
310
109
  },
110
+ dispose: () => runtime.dispose(),
311
111
  };
312
112
  }
@@ -0,0 +1,98 @@
1
+ import { z } from 'zod';
2
+ export declare const classSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ description: z.ZodString;
5
+ }, "strict", z.ZodTypeAny, {
6
+ id: string;
7
+ description: string;
8
+ }, {
9
+ id: string;
10
+ description: string;
11
+ }>;
12
+ export type ClassDefinition = z.infer<typeof classSchema>;
13
+ export declare const classifySchema: z.ZodObject<{
14
+ input: z.ZodUnion<[z.ZodString, z.ZodEffects<z.ZodObject<{
15
+ text: z.ZodOptional<z.ZodString>;
16
+ image: z.ZodOptional<z.ZodEffects<z.ZodType<Uint8Array<ArrayBufferLike>, z.ZodTypeDef, Uint8Array<ArrayBufferLike>>, Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>>>;
17
+ }, "strict", z.ZodTypeAny, {
18
+ text?: string | undefined;
19
+ image?: Uint8Array<ArrayBufferLike> | undefined;
20
+ }, {
21
+ text?: string | undefined;
22
+ image?: Uint8Array<ArrayBufferLike> | undefined;
23
+ }>, {
24
+ text?: string | undefined;
25
+ image?: Uint8Array<ArrayBufferLike> | undefined;
26
+ }, {
27
+ text?: string | undefined;
28
+ image?: Uint8Array<ArrayBufferLike> | undefined;
29
+ }>]>;
30
+ classes: z.ZodEffects<z.ZodArray<z.ZodObject<{
31
+ id: z.ZodString;
32
+ description: z.ZodString;
33
+ }, "strict", z.ZodTypeAny, {
34
+ id: string;
35
+ description: string;
36
+ }, {
37
+ id: string;
38
+ description: string;
39
+ }>, "many">, {
40
+ id: string;
41
+ description: string;
42
+ }[], {
43
+ id: string;
44
+ description: string;
45
+ }[]>;
46
+ instructions: z.ZodOptional<z.ZodString>;
47
+ representation: z.ZodOptional<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
48
+ type: z.ZodLiteral<"vision">;
49
+ }, "strict", z.ZodTypeAny, {
50
+ type: "vision";
51
+ }, {
52
+ type: "vision";
53
+ }>, z.ZodObject<{
54
+ type: z.ZodLiteral<"experimental-text">;
55
+ profile: z.ZodLiteral<"text-image-v1">;
56
+ }, "strict", z.ZodTypeAny, {
57
+ type: "experimental-text";
58
+ profile: "text-image-v1";
59
+ }, {
60
+ type: "experimental-text";
61
+ profile: "text-image-v1";
62
+ }>]>>;
63
+ }, "strict", z.ZodTypeAny, {
64
+ input: string | {
65
+ text?: string | undefined;
66
+ image?: Uint8Array<ArrayBufferLike> | undefined;
67
+ };
68
+ classes: {
69
+ id: string;
70
+ description: string;
71
+ }[];
72
+ instructions?: string | undefined;
73
+ representation?: {
74
+ type: "vision";
75
+ } | {
76
+ type: "experimental-text";
77
+ profile: "text-image-v1";
78
+ } | undefined;
79
+ }, {
80
+ input: string | {
81
+ text?: string | undefined;
82
+ image?: Uint8Array<ArrayBufferLike> | undefined;
83
+ };
84
+ classes: {
85
+ id: string;
86
+ description: string;
87
+ }[];
88
+ instructions?: string | undefined;
89
+ representation?: {
90
+ type: "vision";
91
+ } | {
92
+ type: "experimental-text";
93
+ profile: "text-image-v1";
94
+ } | undefined;
95
+ }>;
96
+ export type ClassifyInput = z.input<typeof classifySchema> & {
97
+ signal?: AbortSignal;
98
+ };
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { imageSchema, limits, representationSchema } from './image.js';
3
+ export const classSchema = z
4
+ .object({
5
+ id: z
6
+ .string()
7
+ .min(1)
8
+ .max(128)
9
+ .regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/),
10
+ description: z.string().trim().min(1).max(300),
11
+ })
12
+ .strict();
13
+ const mediaInputSchema = z
14
+ .object({ text: z.string().trim().min(1).max(32000).optional(), image: imageSchema.optional() })
15
+ .strict()
16
+ .refine((v) => v.text !== undefined || v.image !== undefined, 'Provide text or image');
17
+ export const classifySchema = z
18
+ .object({
19
+ input: z.union([z.string().trim().min(1).max(32000), mediaInputSchema]),
20
+ classes: z
21
+ .array(classSchema)
22
+ .min(2)
23
+ .max(limits.maxClasses)
24
+ .refine((v) => new Set(v.map((c) => c.id)).size === v.length, 'Class IDs must be unique'),
25
+ instructions: z.string().trim().min(1).max(4000).optional(),
26
+ representation: representationSchema.optional(),
27
+ })
28
+ .strict();