@norskvideo/norsk-sdk 1.0.402-2026-01-14-bf6be668 → 1.0.402-2026-01-15-5687d367

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.
package/lib/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "license": "MIT",
3
3
  "name": "@norskvideo/norsk-sdk",
4
- "version": "1.0.402-2026-01-14-bf6be668+nightly",
4
+ "version": "1.0.402-2026-01-15-5687d367+nightly",
5
5
  "dependencies": {
6
6
  "@bufbuild/protobuf": "^0.3.0",
7
7
  "@grpc/grpc-js": "~1.12.0",
8
- "@norskvideo/norsk-api": "1.0.402-2026-01-14-bf6be668+nightly",
8
+ "@norskvideo/norsk-api": "1.0.402-2026-01-15-5687d367+nightly",
9
9
  "lodash": "^4.17.21",
10
10
  "typescript-nullable": "^0.6.0"
11
11
  },
@@ -1183,7 +1183,19 @@ export interface FileMp4OutputSettings extends SinkNodeSettings<FileMp4OutputNod
1183
1183
  * Settings for encrypting the video track.
1184
1184
  */
1185
1185
  videoEncryption?: EncryptionSettings;
1186
+ /**
1187
+ * Enable "incremental" write mode of non-fragmented mp4 output file. This periodically updates the file header (the moov) to
1188
+ * reflect the latest data that has been written, so that the file can be loaded/reloaded in some player while it is being written.
1189
+ * You must set {@link expectedMaxFileDurationS} to ensure an appropriate space can be reserved for the header or the file will no longer
1190
+ * update incrementally
1191
+ */
1186
1192
  enableIncrementalMp4Write?: boolean;
1193
+ /**
1194
+ * Maximum duration that the file is expected to last. This should be a conservative estimate according to the use case, so that you never
1195
+ * expect to hit the limit, but there is some file size cost to a larger value (so if the file is going to be 10 seconds, setting 2 hours would be a bad idea).
1196
+ */
1197
+ incrementalWriteIntervalMs?: number;
1198
+ expectedMaxFileDurationS?: number;
1187
1199
  }
1188
1200
  /**
1189
1201
  * @public
@@ -1502,7 +1502,9 @@ class FileMp4OutputNode extends common_2.AutoSinkMediaNode {
1502
1502
  statsSampling: settings.statsSampling
1503
1503
  ? (0, utils_1.provideFull)(media_pb_1.StreamStatisticsSampling, settings.statsSampling)
1504
1504
  : undefined,
1505
- enableIncrementalMp4Write: !!settings.enableIncrementalMp4Write
1505
+ enableIncrementalMp4Write: !!settings.enableIncrementalMp4Write,
1506
+ incrementalWriteIntervalMs: settings.incrementalWriteIntervalMs ?? 0,
1507
+ expectedMaxFileDurationS: settings.expectedMaxFileDurationS ?? 0,
1506
1508
  });
1507
1509
  this.grpcStream = this.client.media.createOutputFileMp4();
1508
1510
  this.grpcStream.write((0, utils_1.provideFull)(media_pb_1.FileMp4OutputMessage, (0, utils_1.mkMessageCase)({ configuration: config })));
@@ -159,6 +159,14 @@ export interface AudioMeasureLevelsSettings extends ProcessorNodeSettings<AudioM
159
159
  */
160
160
  export declare class AudioMeasureLevelsNode extends AutoProcessorMediaNode<"audio"> {
161
161
  }
162
+ /**
163
+ * @public
164
+ * Prompt to send periodically once setup is complete
165
+ */
166
+ export type GeminiPeriodicPrompt = {
167
+ text: string;
168
+ intervalSeconds: number;
169
+ };
162
170
  /**
163
171
  * @public
164
172
  * Recursive definition for defining types
@@ -166,6 +174,10 @@ export declare class AudioMeasureLevelsNode extends AutoProcessorMediaNode<"audi
166
174
  export type Schema = {
167
175
  type: "string";
168
176
  description: string;
177
+ } | {
178
+ type: "enum";
179
+ values: string[];
180
+ description: string;
169
181
  } | {
170
182
  type: "number";
171
183
  description: string;
@@ -189,6 +201,11 @@ export type Parameter = {
189
201
  name: string;
190
202
  description: string;
191
203
  type: "string";
204
+ } | {
205
+ name: string;
206
+ description: string;
207
+ type: "enum";
208
+ values: string[];
192
209
  } | {
193
210
  name: string;
194
211
  description: string;
@@ -210,7 +227,7 @@ export type Parameter = {
210
227
  };
211
228
  /**
212
229
  * @public
213
- * Definition for metadata passed as the first argument to a Gemini function call
230
+ * Definition for metadata passed as the first argument to an AI function call
214
231
  */
215
232
  export type FunctionCallMetadata = {
216
233
  frameUtc?: Date;
@@ -224,7 +241,7 @@ export type FunctionDeclaration = {
224
241
  description: string;
225
242
  parameters: Parameter[];
226
243
  response?: Schema;
227
- function: (metadata: FunctionCallMetadata, ...args: any[]) => any | Promise<any>;
244
+ function: (...args: any[]) => any | Promise<any>;
228
245
  };
229
246
  export type GeminiTextPart = {
230
247
  partType: "text";
@@ -244,15 +261,16 @@ export type GeminiServerContent = {
244
261
  interrupted: boolean;
245
262
  parts: GeminiPart[];
246
263
  };
247
- export type GeminiLiveApi = {
248
- apiType: "live";
264
+ export type GeminiApiAuth = {
265
+ authType: "geminiApi";
266
+ googleApiKey: string;
249
267
  };
250
- export type GeminiSingleShotApi = {
251
- apiType: "singleShot";
252
- historicalContextMs: number;
253
- prompt: string;
268
+ export type VertexAuth = {
269
+ authType: "vertex";
270
+ project: string;
271
+ location: string;
254
272
  };
255
- export type GeminiApiChoice = GeminiLiveApi | GeminiSingleShotApi;
273
+ export type GeminiAuth = GeminiApiAuth | VertexAuth;
256
274
  /**
257
275
  * @public
258
276
  * Settings for Gemini Video
@@ -261,21 +279,25 @@ export interface GeminiVideoSettings {
261
279
  resolution: Resolution;
262
280
  frameRate: FrameRate;
263
281
  }
282
+ /**
283
+ * @public
284
+ * Gemini status enumeration
285
+ */
286
+ export type GeminiStatus = "connected" | "setupCompleted" | "turnComplete";
264
287
  /**
265
288
  * @public
266
289
  * Settings for a GeminiProcessorNode
267
290
  * see: {@link NorskControl.geminiProcessor}
268
291
  */
269
292
  export interface GeminiSettings extends ProcessorNodeSettings<GeminiProcessorNode> {
270
- googleApiKey: string;
293
+ auth: GeminiAuth;
271
294
  model: string;
272
295
  systemInstruction: string;
296
+ periodicPrompt?: GeminiPeriodicPrompt;
273
297
  functions: FunctionDeclaration[];
274
- apiChoice: GeminiApiChoice;
275
298
  videoSettings?: GeminiVideoSettings;
276
- infoCb?: (status: "connected" | "setupStarted" | "setupCompleted") => void;
277
- contentCb?: (content: GeminiServerContent) => void;
278
- contextCb?: (context: string) => void;
299
+ statusCb?: (status: GeminiStatus) => void;
300
+ contentCb?: (content: string) => void;
279
301
  }
280
302
  /**
281
303
  * @public
@@ -414,6 +414,8 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
414
414
  switch (schemaType) {
415
415
  case "string":
416
416
  return (0, utils_1.mkCase)({ stringType: (0, utils_1.provideFull)(media_pb_1.StringType, {}) });
417
+ case "enum":
418
+ return (0, utils_1.mkCase)({ enumType: (0, utils_1.provideFull)(media_pb_1.EnumType, { values: schema.values }) });
417
419
  case "number":
418
420
  return (0, utils_1.mkCase)({ numberType: (0, utils_1.provideFull)(media_pb_1.NumberType, {}) });
419
421
  case "boolean":
@@ -443,6 +445,8 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
443
445
  switch (schemaType) {
444
446
  case "string":
445
447
  return { type: "string", description: parameter.description };
448
+ case "enum":
449
+ return { type: "enum", description: parameter.description, values: parameter.values };
446
450
  case "number":
447
451
  return { type: "number", description: parameter.description };
448
452
  case "boolean":
@@ -481,7 +485,16 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
481
485
  id: settings.id
482
486
  ? (0, utils_1.provideFull)(media_pb_1.MediaNodeId, { id: settings.id })
483
487
  : undefined,
484
- googleApiKey: settings.googleApiKey,
488
+ auth: (() => {
489
+ switch (settings.auth.authType) {
490
+ case "geminiApi":
491
+ return (0, utils_1.mkCase)({ geminiApi: (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_GeminiApiAuth, { googleApiKey: settings.auth.googleApiKey }) });
492
+ case "vertex":
493
+ return (0, utils_1.mkCase)({ vertex: (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_VertexAuth, { project: settings.auth.project, location: settings.auth.location }) });
494
+ default:
495
+ (0, utils_1.exhaustiveCheck)(settings.auth);
496
+ }
497
+ })(),
485
498
  model: settings.model,
486
499
  systemInstruction: settings.systemInstruction,
487
500
  functions: settings.functions.map((functionDeclaration) => (0, utils_1.provideFull)(media_pb_1.FunctionDeclaration, {
@@ -495,28 +508,6 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
495
508
  })),
496
509
  resolution: settings.videoSettings?.resolution ? (0, utils_1.provideFull)(media_pb_1.Resolution, settings.videoSettings.resolution) : undefined,
497
510
  frameRate: settings.videoSettings ? (0, utils_1.provideFull)(media_pb_1.FrameRate, settings.videoSettings.frameRate) : undefined,
498
- apiChoice: (() => {
499
- if (settings.videoSettings == undefined) {
500
- // No video, live is the only option for audio
501
- return (0, utils_1.mkCase)({ liveApi: (0, utils_1.provideFull)(protobuf_1.Empty, {}) });
502
- }
503
- else {
504
- const apiChoice = settings.apiChoice.apiType;
505
- switch (apiChoice) {
506
- case "live":
507
- return (0, utils_1.mkCase)({ liveApi: (0, utils_1.provideFull)(protobuf_1.Empty, {}) });
508
- case "singleShot":
509
- return (0, utils_1.mkCase)({
510
- "singleShotApi": (0, utils_1.provideFull)(media_pb_1.GeminiConfiguration_SingleShotApi, {
511
- historicalContextMs: settings.apiChoice.historicalContextMs,
512
- prompt: settings.apiChoice.prompt
513
- })
514
- });
515
- default:
516
- (0, utils_1.exhaustiveCheck)(apiChoice);
517
- }
518
- }
519
- })()
520
511
  });
521
512
  this.grpcStream = this.client.media.createGeminiProcessor();
522
513
  this.grpcStream.write((0, utils_1.provideFull)(media_pb_1.GeminiRequest, (0, utils_1.mkMessageCase)({ configuration: geminiConfig })));
@@ -541,17 +532,17 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
541
532
  break;
542
533
  }
543
534
  case "info": {
544
- if (settings.infoCb) {
535
+ if (settings.statusCb) {
545
536
  const v = data.message.value;
546
537
  switch (v) {
547
538
  case media_pb_1.GeminiInfo.CONNECTED:
548
- settings.infoCb("connected");
549
- break;
550
- case media_pb_1.GeminiInfo.SETUP_STARTED:
551
- settings.infoCb("setupStarted");
539
+ settings.statusCb("connected");
552
540
  break;
553
541
  case media_pb_1.GeminiInfo.SETUP_COMPLETED:
554
- settings.infoCb("setupCompleted");
542
+ settings.statusCb("setupCompleted");
543
+ break;
544
+ case media_pb_1.GeminiInfo.TURN_COMPLETE:
545
+ settings.statusCb("turnComplete");
555
546
  break;
556
547
  default:
557
548
  (0, utils_1.exhaustiveCheck)(v);
@@ -565,7 +556,7 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
565
556
  if (declaration) {
566
557
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
567
558
  const args = declaration.parameters.map(param => (0, common_1.valueToNative)(call.arguments[param.name]));
568
- const response = declaration.function({ frameUtc: call.frameUtc?.toDate() }, ...args);
559
+ const response = declaration.function(...args);
569
560
  if (response instanceof Promise) {
570
561
  response.then((result) => {
571
562
  const callResponse = (0, utils_1.provideFull)(media_pb_1.GeminiCallResponse, { name: call.name, id: call.id, response: { returnValue: (0, common_1.nativeToValue)(result) } });
@@ -587,20 +578,9 @@ class GeminiProcessorNode extends common_1.AutoProcessorMediaNode {
587
578
  }
588
579
  break;
589
580
  }
590
- case "serverContent": {
581
+ case "text": {
591
582
  if (settings.contentCb) {
592
- const content = data.message.value;
593
- settings.contentCb({
594
- turnComplete: content.turnComplete,
595
- interrupted: content.interrupted,
596
- parts: content.turn !== undefined ? content.turn.parts.map(GeminiProcessorNode.partFromPB) : []
597
- });
598
- }
599
- break;
600
- }
601
- case "singleShotContext": {
602
- if (settings.contextCb) {
603
- settings.contextCb(data.message.value);
583
+ settings.contentCb(data.message.value);
604
584
  }
605
585
  break;
606
586
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "license": "MIT",
3
3
  "name": "@norskvideo/norsk-sdk",
4
- "version": "1.0.402-2026-01-14-bf6be668+nightly",
4
+ "version": "1.0.402-2026-01-15-5687d367+nightly",
5
5
  "dependencies": {
6
6
  "@bufbuild/protobuf": "^0.3.0",
7
7
  "@grpc/grpc-js": "~1.12.0",
8
- "@norskvideo/norsk-api": "1.0.402-2026-01-14-bf6be668+nightly",
8
+ "@norskvideo/norsk-api": "1.0.402-2026-01-15-5687d367+nightly",
9
9
  "lodash": "^4.17.21",
10
10
  "typescript-nullable": "^0.6.0"
11
11
  },