@hypit/hypit 0.2.7 → 0.2.8

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.
@@ -68,7 +68,7 @@ differ from the image example, and each is the reason the video example exists.
68
68
  **The reference vocabulary is wider, and each role maps to its own field.** The Model declares
69
69
  `referenceImage`, `referenceVideo` and `referenceAudio` as separate ports precisely so each can map
70
70
  to one wire field — a service that mixes them into one array cannot tell the roles apart. An image
71
- reference also carries an optional `personReference` classification, which is why those ports use
71
+ reference also requires a boolean `personReference` classification, which is why those ports use
72
72
  `itemObject` rather than `urlArray`: the item field travels with the URL it belongs to.
73
73
 
74
74
  ```json
@@ -76,7 +76,7 @@ reference also carries an optional `personReference` classification, which is wh
76
76
  ```
77
77
 
78
78
  `firstFrame` and `lastFrame` accept at most one item each, so their body fields are URLs.
79
- This illustrative service accepts their optional person classification on `POST /uploads` through
79
+ This illustrative service accepts their required visual-reference person classification on `POST /uploads` through
80
80
  `x-person-reference: true` or `false`. Their mappings declare `resourceFields: ["personReference"]`,
81
81
  and the URL resolver sends that header when supplied. Replace this with the real service’s
82
82
  documented transport; a field that the service cannot carry must be refused, never discarded.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypit/hypit",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "homepage": "https://hypit.ai",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,7 +37,7 @@ Service limits this Provider reports as unsupported before submitting:
37
37
  `1:3`, `9:21`; 4K excludes `1:1`, `3:1`, `1:3`, `9:21`; image-to-image takes up to six references.
38
38
  - Grok Imagine renders 480p or 720p; `grok-imagine-1.5/image-to-video` animates exactly one image.
39
39
 
40
- Seedance visual references may carry `person-reference`; the Provider accepts the declaration and
40
+ Seedance visual references require `person-reference`; the Provider accepts the declaration and
41
41
  transmits nothing for it, since HiAPI has no field for it. Seedance rejects reference images and
42
42
  videos that contain a real human face; HiAPI offers no way to register authorized portrait material,
43
43
  so such a request fails with the service's moderation error.
@@ -123,12 +123,11 @@ size and part concurrency, retries a failed part with a fresh signed URL, comple
123
123
  one upload, and then passes the returned HTTPS URL to generation or transcription. Signing requests
124
124
  contain at most the service's 128-part limit; all batches belong to the same upload. One
125
125
  Resource identity with the same declared person-reference classification is uploaded once within one Runtime operation. Hypit keeps no upload catalog or
126
- cross-Build cache. Seedance visual references can carry `personReference` in their media fields;
126
+ cross-Build cache. Seedance visual references require boolean `personReference` in their media fields;
127
127
  the mapping declares it as a resource-transport field and the upload session receives
128
- `is_person_reference`, preserving true, false and omission. It stays out of the generation body.
128
+ `is_person_reference`, preserving true and false. It stays out of the generation body.
129
129
  This covers reference images, reference videos, and first/last frames for every declared Seedance
130
- variant. Omission remains absent on the wire; HypiHub's upload API currently defaults it to false,
131
- so omission does not enable detection or person-reference preparation.
130
+ variant. Seedance rejects omission before upload; no automatic face detection is requested.
132
131
  HypiHub stores the authored classification and prepares the applicable upstream person reference;
133
132
  this Provider does not detect faces or select an upstream private-avatar group.
134
133
 
@@ -25,7 +25,7 @@ each media input as a typed item with its `role` (`first_frame`, `last_frame`, `
25
25
 
26
26
  The Seedance endpoints add `generate_audio`. Monid documents no web search field for them, so
27
27
  `web-search="true"` is unsupported, and Seedance 2.5 frame mode (`first-frame` present) requires
28
- `aspect-ratio="adaptive"`. Seedance visual references may carry `person-reference`; the Provider
28
+ `aspect-ratio="adaptive"`. Seedance visual references require `person-reference`; the Provider
29
29
  accepts the declaration and transmits nothing for it, since the endpoint has no field for it.
30
30
  Seedance rejects reference images and videos that contain a real human face; Monid offers no way to
31
31
  register authorized portrait material, so such a request fails with the upstream moderation error.
@@ -19,7 +19,7 @@ the models the Distribution already describes.
19
19
  Video requests write the prompt and each media input as one item of the protocol's `content`
20
20
  array with its `role` (`first_frame`, `last_frame`, `reference_image`, `reference_video`,
21
21
  `reference_audio`), then `resolution`, `ratio`, `duration` and, for Seedance, `generate_audio`;
22
- `web-search="true"` adds `tools: [{ "type": "web_search" }]`. Seedance visual references may carry
22
+ `web-search="true"` adds `tools: [{ "type": "web_search" }]`. Seedance visual references require
23
23
  `person-reference`; the Provider accepts the declaration and transmits nothing for it, since the Ark
24
24
  protocol has no such field. Seedance 2.0 and 2.5 reject reference images and videos that contain a
25
25
  real human face; TokenDance offers no way to register authorized portrait material, so such a request
@@ -34,22 +34,20 @@ responsible for any additional service-specific input limits.
34
34
 
35
35
  ## Visual reference metadata
36
36
 
37
- Declare whether each image or video contains a person/avatar reference, including an AI-generated
38
- human likeness. This describes the supplied material, independently of the prompt's requested action:
37
+ Every supplied image or video must explicitly declare `person-reference`: `true` if it contains
38
+ a person, `false` otherwise. Classify the supplied material, not the requested result.
39
39
 
40
40
  ```xml
41
- <seedance:ReferenceVideo id="dance" model="mini" prompt={direction} duration="8">
41
+ <seedance:ReferenceVideo id="take" model="mini" prompt={direction} duration="8">
42
42
  <seedance:Reference image={presenter.image} person-reference="true"/>
43
- <seedance:Reference video={motion.video} person-reference="true"/>
43
+ <seedance:Reference video={presenter.video} person-reference="true"/>
44
44
  <seedance:Reference image={room.image} person-reference="false"/>
45
45
  </seedance:ReferenceVideo>
46
46
  ```
47
47
 
48
- `person-reference` is optional, accepts literal `true` or `false`, and applies to image/video, not
49
- voice audio. Omission carries no classification; it is distinct from explicitly declaring false.
50
- Inspect the actual reference when deciding the value. For `FrameVideo`, use
51
- `first-frame-person-reference` and `last-frame-person-reference` beside their respective frame
52
- inputs. A last-frame classification requires a last-frame input.
48
+ Missing or non-boolean declarations are rejected; there is no default or automatic face detection.
49
+ Audio must omit this field. `FrameVideo` requires `first-frame-person-reference` and, when a last
50
+ frame is supplied, `last-frame-person-reference`. A last-frame classification requires a last frame.
53
51
 
54
52
  | Supplied visual input | Authored attribute | Request port |
55
53
  | --- | --- | --- |
@@ -66,23 +64,18 @@ These forms apply to `standard`, `fast`, `mini` and `2.5`. For example:
66
64
  last-frame={empty-room.image} last-frame-person-reference="false"/>
67
65
  ```
68
66
 
69
- Classify the material supplied to this request, not the intended result. A dance video with a person
70
- still needs `true` when used only for motion, even if the prompt asks for a different performer.
71
- An empty room stays `false` when the prompt asks to add a person. Inspect video across the selected
72
- excerpt, not only its opening frame. This flag neither detects faces nor locks or names an identity.
73
- Identity and action direction remain in the prompt and references.
67
+ Inspect the selected video excerpt, not only its opening frame. An empty room stays `false` when
68
+ the prompt asks to add a person. The flag does not lock identity; direction and references own that.
74
69
 
75
70
  The SVML author declares this parameter on each reference input. Admitted files, generated
76
71
  images/videos and reused Results use the same attributes. For a future output, declare the intended
77
72
  reference classification explicitly; if its contents are uncertain, generate and inspect that
78
73
  material before using it downstream.
79
74
 
80
- The model's media ports carry this as `fields.personReference`. Providers interpret it through their
81
- service's media handling; it is not a prompt sentence or a Core-level identity. HypiHub sends it as
75
+ Direct requests require the same boolean in `fields.personReference`. Providers interpret it through
76
+ their service's media handling; it is not a prompt sentence or a Core-level identity. HypiHub sends it as
82
77
  `is_person_reference` when uploading the file, then uses the returned URL in the ordinary video
83
78
  request. A project Provider maps it according to its own API.
84
- Omission does not request automatic face detection. HypiHub currently treats omitted upload flags
85
- as unmarked (`false`); declare `true` explicitly for a person reference that needs its preparation.
86
79
 
87
80
  Video references can carry motion or camera behavior while image references carry the target
88
81
  appearance. Request duration and reference-clip duration are different limits. Check the selected
@@ -17,7 +17,7 @@ export type SeedanceModel = typeof seedanceModels[number];
17
17
 
18
18
  const ASPECT_RATIOS = ["1:1", "4:3", "3:4", "16:9", "9:16", "21:9", "adaptive"] as const;
19
19
 
20
- const PERSON_REFERENCE_FIELDS = [{ name: "personReference", value: { kind: "boolean" }, optional: true }] as const;
20
+ const PERSON_REFERENCE_FIELDS = [{ name: "personReference", value: { kind: "boolean" } }] as const;
21
21
 
22
22
  const SEEDANCE_25_DURATIONS = [-1, ...Array.from({ length: 27 }, (_item, index) => index + 4)] as const;
23
23
 
@@ -175,9 +175,9 @@ const seedanceCommonAttributes: readonly SurfaceAttributeVocabulary[] = [
175
175
  },
176
176
  ];
177
177
 
178
- const personReferenceAttribute = (name: string): SurfaceAttributeVocabulary => ({
179
- name, kind: "literal", required: false, values: ["true", "false"],
180
- summary: "Declares whether this visual input contains a person/avatar reference, including an AI-generated human likeness. Omission leaves it unclassified.",
178
+ const personReferenceAttribute = (name: string, required = false): SurfaceAttributeVocabulary => ({
179
+ name, kind: "literal", required, values: ["true", "false"],
180
+ summary: "Required for each supplied image/video, including first/last frames: true if it contains a person, false otherwise. Audio must omit it.",
181
181
  });
182
182
 
183
183
  const seedanceVideoPort: readonly SurfacePortVocabulary[] = [{
@@ -235,7 +235,7 @@ export const seedanceMarkupSurfaces = [
235
235
  summary: "Generates one video with an exact Seedance model from a Text prompt and the images the video opens and closes on.",
236
236
  attributes: [
237
237
  ...seedanceCommonAttributes,
238
- personReferenceAttribute("first-frame-person-reference"),
238
+ personReferenceAttribute("first-frame-person-reference", true),
239
239
  personReferenceAttribute("last-frame-person-reference"),
240
240
  {
241
241
  name: "first-frame",
@@ -253,7 +253,7 @@ export const seedanceMarkupSurfaces = [
253
253
  },
254
254
  ],
255
255
  ports: seedanceVideoPort,
256
- example: '<seedance:FrameVideo id="bridge" model="fast" prompt={direction} duration="5" first-frame={first.image} last-frame={last.image}/>',
256
+ example: '<seedance:FrameVideo id="bridge" model="fast" prompt={direction} duration="5" first-frame={first.image} first-frame-person-reference="true" last-frame={last.image} last-frame-person-reference="false"/>',
257
257
  notes: [
258
258
  ...seedanceSettingNotes,
259
259
  "Both frames are ordinary image Artifact edges; the Surface copies no runtime media into request metadata.",
@@ -316,7 +316,7 @@ export const seedanceMarkupSurfaces = [
316
316
  notes: [
317
317
  ...seedanceSettingNotes,
318
318
  "The element requires at least one `Reference` child, and the model's port limits cap how many of each role it accepts.",
319
- "`person-reference` applies to image/video references; voice audio carries no visual classification. The Provider transports the declared fact according to its API.",
319
+ "Every image/video Reference requires `person-reference=\"true|false\"`. Classify the supplied material; audio must omit the field. The Provider transports it according to its API.",
320
320
  "A `Reference` carries exactly one of `image`, `video` or `audio`, and is empty.",
321
321
  ],
322
322
  },
@@ -146,8 +146,10 @@ function booleanAttribute(element: StructuredElement, name: string, fallback: bo
146
146
  }
147
147
 
148
148
  function personReferenceFields(element: StructuredElement, name: string) {
149
- return element.attributes[name] === undefined ? undefined
150
- : { personReference: booleanAttribute(element, name, false) };
149
+ if (element.attributes[name] === undefined) {
150
+ throw new Error(`${element.name}.${name} is required for this visual reference; set true if it contains a person, false otherwise`);
151
+ }
152
+ return { personReference: booleanAttribute(element, name, false) };
151
153
  }
152
154
 
153
155
  function enumeratedPort(table: GenerationPortTable, name: string): readonly (string | number)[] {
@@ -217,8 +219,8 @@ function referenceInputs(
217
219
  const kinds = accepted.filter((kind) => child.attributes[kind] !== undefined);
218
220
  if (kinds.length !== 1) throw new Error(`${child.name} requires exactly one of ${accepted.join(", ")}`);
219
221
  const role = kinds[0]!;
220
- const fields = personReferenceFields(child, "person-reference");
221
- if (role === "audio" && fields !== undefined) throw new Error(`${child.name}.person-reference applies to image or video, not audio`);
222
+ if (role === "audio" && child.attributes["person-reference"] !== undefined) throw new Error(`${child.name}.person-reference applies to image or video, not audio`);
223
+ const fields = role === "audio" ? undefined : personReferenceFields(child, "person-reference");
222
224
  result.push({
223
225
  ...(fields === undefined ? {} : { fields }),
224
226
  role,
@@ -242,13 +244,12 @@ function frameInputs(
242
244
  ): MediaInput[] {
243
245
  const first = mediaReference(resolved(element, "first-frame", resolveReference), "image", `${element.name}.first-frame`);
244
246
  const firstFields = personReferenceFields(element, "first-frame-person-reference");
245
- const result: MediaInput[] = [{ port: "firstFrame", role: "image", source: first, ...(firstFields === undefined ? {} : { fields: firstFields }) }];
246
- const lastFields = personReferenceFields(element, "last-frame-person-reference");
247
- if (lastFields !== undefined && element.attributes["last-frame"] === undefined) throw new Error(`${element.name}.last-frame-person-reference requires last-frame`);
247
+ const result: MediaInput[] = [{ port: "firstFrame", role: "image", source: first, fields: firstFields }];
248
+ if (element.attributes["last-frame-person-reference"] !== undefined && element.attributes["last-frame"] === undefined) throw new Error(`${element.name}.last-frame-person-reference requires last-frame`);
248
249
  if (element.attributes["last-frame"] !== undefined) {
249
250
  result.push({
250
251
  port: "lastFrame",
251
- ...(lastFields === undefined ? {} : { fields: lastFields }),
252
+ fields: personReferenceFields(element, "last-frame-person-reference"),
252
253
  role: "image",
253
254
  source: mediaReference(resolved(element, "last-frame", resolveReference), "image", `${element.name}.last-frame`),
254
255
  });
@@ -23,8 +23,8 @@ ordinary explicit graph edges:
23
23
 
24
24
  <seedance:ReferenceVideo id="broll" model="mini" prompt={broll-prompt}
25
25
  duration="5" resolution="720p" aspect-ratio="9:16">
26
- <seedance:Reference image={scene}/>
27
- <seedance:Reference image={product}/>
26
+ <seedance:Reference image={scene} person-reference="false"/>
27
+ <seedance:Reference image={product} person-reference="false"/>
28
28
  </seedance:ReferenceVideo>
29
29
  ```
30
30
 
@@ -154,7 +154,8 @@ For a multi-scene B-roll montage, `story` can name the references in scene order
154
154
  action. Choose an edit language compatible with cuts. “Continuous within each scene” and “one
155
155
  continuous shot for the whole montage” ask for different results.
156
156
 
157
- Visual input classification belongs to the Seedance Reference, separately from Kit text. The
157
+ Every Seedance image/video Reference requires `person-reference="true|false"`: true if the supplied
158
+ material contains a person, false otherwise. Audio must omit it. The
158
159
  [Seedance author package](../seedance/README.md#visual-reference-metadata) explains `person-reference`
159
160
  and its frame variants. The Kit supplies direction; the actual reference edges supply media and
160
161
  metadata. For movement-led work, a reference video can carry the motion while the text explains what