@contractspec/lib.video-gen 2.0.0 → 2.1.1

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.
@@ -557,12 +557,16 @@ class ScenePlanner {
557
557
  temperature;
558
558
  fps;
559
559
  i18n;
560
+ modelSelector;
561
+ selectionContext;
560
562
  constructor(options) {
561
563
  this.llm = options?.llm;
562
564
  this.model = options?.model;
563
565
  this.temperature = options?.temperature ?? 0.3;
564
566
  this.fps = options?.fps ?? DEFAULT_FPS;
565
567
  this.i18n = createVideoGenI18n(options?.locale);
568
+ this.modelSelector = options?.modelSelector;
569
+ this.selectionContext = options?.selectionContext;
566
570
  }
567
571
  async plan(brief) {
568
572
  if (this.llm) {
@@ -654,6 +658,18 @@ class ScenePlanner {
654
658
  narrationScript
655
659
  };
656
660
  }
661
+ async resolveModel() {
662
+ if (this.model)
663
+ return this.model;
664
+ if (this.modelSelector) {
665
+ const ctx = this.selectionContext ?? {
666
+ taskDimension: "reasoning"
667
+ };
668
+ const result = await this.modelSelector.select(ctx);
669
+ return result.modelId;
670
+ }
671
+ return;
672
+ }
657
673
  async planWithLlm(brief) {
658
674
  const { t } = this.i18n;
659
675
  const messages = [
@@ -683,8 +699,9 @@ class ScenePlanner {
683
699
  return this.planDeterministic(brief);
684
700
  }
685
701
  try {
702
+ const model = await this.resolveModel();
686
703
  const response = await this.llm.chat(messages, {
687
- model: this.model,
704
+ model,
688
705
  temperature: this.temperature,
689
706
  responseFormat: "json"
690
707
  });
@@ -723,7 +740,9 @@ class VideoGenerator {
723
740
  model: options?.model,
724
741
  temperature: options?.temperature,
725
742
  fps: this.fps,
726
- locale: options?.locale
743
+ locale: options?.locale,
744
+ modelSelector: options?.modelSelector,
745
+ selectionContext: options?.selectionContext
727
746
  });
728
747
  }
729
748
  async generate(brief) {
@@ -557,12 +557,16 @@ class ScenePlanner {
557
557
  temperature;
558
558
  fps;
559
559
  i18n;
560
+ modelSelector;
561
+ selectionContext;
560
562
  constructor(options) {
561
563
  this.llm = options?.llm;
562
564
  this.model = options?.model;
563
565
  this.temperature = options?.temperature ?? 0.3;
564
566
  this.fps = options?.fps ?? DEFAULT_FPS;
565
567
  this.i18n = createVideoGenI18n(options?.locale);
568
+ this.modelSelector = options?.modelSelector;
569
+ this.selectionContext = options?.selectionContext;
566
570
  }
567
571
  async plan(brief) {
568
572
  if (this.llm) {
@@ -654,6 +658,18 @@ class ScenePlanner {
654
658
  narrationScript
655
659
  };
656
660
  }
661
+ async resolveModel() {
662
+ if (this.model)
663
+ return this.model;
664
+ if (this.modelSelector) {
665
+ const ctx = this.selectionContext ?? {
666
+ taskDimension: "reasoning"
667
+ };
668
+ const result = await this.modelSelector.select(ctx);
669
+ return result.modelId;
670
+ }
671
+ return;
672
+ }
657
673
  async planWithLlm(brief) {
658
674
  const { t } = this.i18n;
659
675
  const messages = [
@@ -683,8 +699,9 @@ class ScenePlanner {
683
699
  return this.planDeterministic(brief);
684
700
  }
685
701
  try {
702
+ const model = await this.resolveModel();
686
703
  const response = await this.llm.chat(messages, {
687
- model: this.model,
704
+ model,
688
705
  temperature: this.temperature,
689
706
  responseFormat: "json"
690
707
  });
@@ -521,11 +521,15 @@ class ScriptGenerator {
521
521
  model;
522
522
  temperature;
523
523
  i18n;
524
+ modelSelector;
525
+ selectionContext;
524
526
  constructor(options) {
525
527
  this.llm = options?.llm;
526
528
  this.model = options?.model;
527
529
  this.temperature = options?.temperature ?? 0.5;
528
530
  this.i18n = createVideoGenI18n(options?.locale);
531
+ this.modelSelector = options?.modelSelector;
532
+ this.selectionContext = options?.selectionContext;
529
533
  }
530
534
  async generate(brief, config) {
531
535
  const style = config?.style ?? "professional";
@@ -590,6 +594,18 @@ class ScriptGenerator {
590
594
  style
591
595
  };
592
596
  }
597
+ async resolveModel() {
598
+ if (this.model)
599
+ return this.model;
600
+ if (this.modelSelector) {
601
+ const ctx = this.selectionContext ?? {
602
+ taskDimension: "reasoning"
603
+ };
604
+ const result = await this.modelSelector.select(ctx);
605
+ return result.modelId;
606
+ }
607
+ return;
608
+ }
593
609
  async generateWithLlm(brief, style) {
594
610
  const { t } = this.i18n;
595
611
  const styleGuide = {
@@ -619,8 +635,9 @@ class ScriptGenerator {
619
635
  return this.generateDeterministic(brief, style);
620
636
  }
621
637
  try {
638
+ const model = await this.resolveModel();
622
639
  const response = await this.llm.chat(messages, {
623
- model: this.model,
640
+ model,
624
641
  temperature: this.temperature,
625
642
  responseFormat: "json"
626
643
  });
@@ -557,12 +557,16 @@ class ScenePlanner {
557
557
  temperature;
558
558
  fps;
559
559
  i18n;
560
+ modelSelector;
561
+ selectionContext;
560
562
  constructor(options) {
561
563
  this.llm = options?.llm;
562
564
  this.model = options?.model;
563
565
  this.temperature = options?.temperature ?? 0.3;
564
566
  this.fps = options?.fps ?? DEFAULT_FPS;
565
567
  this.i18n = createVideoGenI18n(options?.locale);
568
+ this.modelSelector = options?.modelSelector;
569
+ this.selectionContext = options?.selectionContext;
566
570
  }
567
571
  async plan(brief) {
568
572
  if (this.llm) {
@@ -654,6 +658,18 @@ class ScenePlanner {
654
658
  narrationScript
655
659
  };
656
660
  }
661
+ async resolveModel() {
662
+ if (this.model)
663
+ return this.model;
664
+ if (this.modelSelector) {
665
+ const ctx = this.selectionContext ?? {
666
+ taskDimension: "reasoning"
667
+ };
668
+ const result = await this.modelSelector.select(ctx);
669
+ return result.modelId;
670
+ }
671
+ return;
672
+ }
657
673
  async planWithLlm(brief) {
658
674
  const { t } = this.i18n;
659
675
  const messages = [
@@ -683,8 +699,9 @@ class ScenePlanner {
683
699
  return this.planDeterministic(brief);
684
700
  }
685
701
  try {
702
+ const model = await this.resolveModel();
686
703
  const response = await this.llm.chat(messages, {
687
- model: this.model,
704
+ model,
688
705
  temperature: this.temperature,
689
706
  responseFormat: "json"
690
707
  });
@@ -723,7 +740,9 @@ class VideoGenerator {
723
740
  model: options?.model,
724
741
  temperature: options?.temperature,
725
742
  fps: this.fps,
726
- locale: options?.locale
743
+ locale: options?.locale,
744
+ modelSelector: options?.modelSelector,
745
+ selectionContext: options?.selectionContext
727
746
  });
728
747
  }
729
748
  async generate(brief) {
@@ -1636,12 +1636,16 @@ class ScenePlanner {
1636
1636
  temperature;
1637
1637
  fps;
1638
1638
  i18n;
1639
+ modelSelector;
1640
+ selectionContext;
1639
1641
  constructor(options) {
1640
1642
  this.llm = options?.llm;
1641
1643
  this.model = options?.model;
1642
1644
  this.temperature = options?.temperature ?? 0.3;
1643
1645
  this.fps = options?.fps ?? DEFAULT_FPS;
1644
1646
  this.i18n = createVideoGenI18n(options?.locale);
1647
+ this.modelSelector = options?.modelSelector;
1648
+ this.selectionContext = options?.selectionContext;
1645
1649
  }
1646
1650
  async plan(brief) {
1647
1651
  if (this.llm) {
@@ -1733,6 +1737,18 @@ class ScenePlanner {
1733
1737
  narrationScript
1734
1738
  };
1735
1739
  }
1740
+ async resolveModel() {
1741
+ if (this.model)
1742
+ return this.model;
1743
+ if (this.modelSelector) {
1744
+ const ctx = this.selectionContext ?? {
1745
+ taskDimension: "reasoning"
1746
+ };
1747
+ const result = await this.modelSelector.select(ctx);
1748
+ return result.modelId;
1749
+ }
1750
+ return;
1751
+ }
1736
1752
  async planWithLlm(brief) {
1737
1753
  const { t } = this.i18n;
1738
1754
  const messages = [
@@ -1762,8 +1778,9 @@ class ScenePlanner {
1762
1778
  return this.planDeterministic(brief);
1763
1779
  }
1764
1780
  try {
1781
+ const model = await this.resolveModel();
1765
1782
  const response = await this.llm.chat(messages, {
1766
- model: this.model,
1783
+ model,
1767
1784
  temperature: this.temperature,
1768
1785
  responseFormat: "json"
1769
1786
  });
@@ -1802,7 +1819,9 @@ class VideoGenerator {
1802
1819
  model: options?.model,
1803
1820
  temperature: options?.temperature,
1804
1821
  fps: this.fps,
1805
- locale: options?.locale
1822
+ locale: options?.locale,
1823
+ modelSelector: options?.modelSelector,
1824
+ selectionContext: options?.selectionContext
1806
1825
  });
1807
1826
  }
1808
1827
  async generate(brief) {
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -718,7 +735,9 @@ class VideoGenerator {
718
735
  model: options?.model,
719
736
  temperature: options?.temperature,
720
737
  fps: this.fps,
721
- locale: options?.locale
738
+ locale: options?.locale,
739
+ modelSelector: options?.modelSelector,
740
+ selectionContext: options?.selectionContext
722
741
  });
723
742
  }
724
743
  async generate(brief) {
@@ -1,4 +1,5 @@
1
1
  import type { LLMProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/llm';
2
+ import type { ModelSelector, ModelSelectionContext } from '@contractspec/lib.ai-providers/selector-types';
2
3
  import type { ScenePlan, VideoBrief } from '../types';
3
4
  export interface ScenePlannerOptions {
4
5
  llm?: LLMProvider;
@@ -6,6 +7,8 @@ export interface ScenePlannerOptions {
6
7
  temperature?: number;
7
8
  fps?: number;
8
9
  locale?: string;
10
+ modelSelector?: ModelSelector;
11
+ selectionContext?: ModelSelectionContext;
9
12
  }
10
13
  export declare class ScenePlanner {
11
14
  private readonly llm?;
@@ -13,6 +16,8 @@ export declare class ScenePlanner {
13
16
  private readonly temperature;
14
17
  private readonly fps;
15
18
  private readonly i18n;
19
+ private readonly modelSelector?;
20
+ private readonly selectionContext?;
16
21
  constructor(options?: ScenePlannerOptions);
17
22
  /**
18
23
  * Plan scenes for a video brief.
@@ -21,5 +26,6 @@ export declare class ScenePlanner {
21
26
  */
22
27
  plan(brief: VideoBrief): Promise<ScenePlan>;
23
28
  private planDeterministic;
29
+ private resolveModel;
24
30
  private planWithLlm;
25
31
  }
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -1,4 +1,5 @@
1
1
  import type { LLMProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/llm';
2
+ import type { ModelSelector, ModelSelectionContext } from '@contractspec/lib.ai-providers/selector-types';
2
3
  import type { ContentBrief } from '@contractspec/lib.content-gen/types';
3
4
  import type { NarrationConfig } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
4
5
  export interface NarrationScript {
@@ -24,18 +25,23 @@ export interface ScriptGeneratorOptions {
24
25
  model?: string;
25
26
  temperature?: number;
26
27
  locale?: string;
28
+ modelSelector?: ModelSelector;
29
+ selectionContext?: ModelSelectionContext;
27
30
  }
28
31
  export declare class ScriptGenerator {
29
32
  private readonly llm?;
30
33
  private readonly model?;
31
34
  private readonly temperature;
32
35
  private readonly i18n;
36
+ private readonly modelSelector?;
37
+ private readonly selectionContext?;
33
38
  constructor(options?: ScriptGeneratorOptions);
34
39
  /**
35
40
  * Generate a narration script from a content brief.
36
41
  */
37
42
  generate(brief: ContentBrief, config?: NarrationConfig): Promise<NarrationScript>;
38
43
  private generateDeterministic;
44
+ private resolveModel;
39
45
  private generateWithLlm;
40
46
  /**
41
47
  * Adjust text tone based on style.
@@ -516,11 +516,15 @@ class ScriptGenerator {
516
516
  model;
517
517
  temperature;
518
518
  i18n;
519
+ modelSelector;
520
+ selectionContext;
519
521
  constructor(options) {
520
522
  this.llm = options?.llm;
521
523
  this.model = options?.model;
522
524
  this.temperature = options?.temperature ?? 0.5;
523
525
  this.i18n = createVideoGenI18n(options?.locale);
526
+ this.modelSelector = options?.modelSelector;
527
+ this.selectionContext = options?.selectionContext;
524
528
  }
525
529
  async generate(brief, config) {
526
530
  const style = config?.style ?? "professional";
@@ -585,6 +589,18 @@ class ScriptGenerator {
585
589
  style
586
590
  };
587
591
  }
592
+ async resolveModel() {
593
+ if (this.model)
594
+ return this.model;
595
+ if (this.modelSelector) {
596
+ const ctx = this.selectionContext ?? {
597
+ taskDimension: "reasoning"
598
+ };
599
+ const result = await this.modelSelector.select(ctx);
600
+ return result.modelId;
601
+ }
602
+ return;
603
+ }
588
604
  async generateWithLlm(brief, style) {
589
605
  const { t } = this.i18n;
590
606
  const styleGuide = {
@@ -614,8 +630,9 @@ class ScriptGenerator {
614
630
  return this.generateDeterministic(brief, style);
615
631
  }
616
632
  try {
633
+ const model = await this.resolveModel();
617
634
  const response = await this.llm.chat(messages, {
618
- model: this.model,
635
+ model,
619
636
  temperature: this.temperature,
620
637
  responseFormat: "json"
621
638
  });
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -718,7 +735,9 @@ class VideoGenerator {
718
735
  model: options?.model,
719
736
  temperature: options?.temperature,
720
737
  fps: this.fps,
721
- locale: options?.locale
738
+ locale: options?.locale,
739
+ modelSelector: options?.modelSelector,
740
+ selectionContext: options?.selectionContext
722
741
  });
723
742
  }
724
743
  async generate(brief) {
package/dist/index.js CHANGED
@@ -1631,12 +1631,16 @@ class ScenePlanner {
1631
1631
  temperature;
1632
1632
  fps;
1633
1633
  i18n;
1634
+ modelSelector;
1635
+ selectionContext;
1634
1636
  constructor(options) {
1635
1637
  this.llm = options?.llm;
1636
1638
  this.model = options?.model;
1637
1639
  this.temperature = options?.temperature ?? 0.3;
1638
1640
  this.fps = options?.fps ?? DEFAULT_FPS;
1639
1641
  this.i18n = createVideoGenI18n(options?.locale);
1642
+ this.modelSelector = options?.modelSelector;
1643
+ this.selectionContext = options?.selectionContext;
1640
1644
  }
1641
1645
  async plan(brief) {
1642
1646
  if (this.llm) {
@@ -1728,6 +1732,18 @@ class ScenePlanner {
1728
1732
  narrationScript
1729
1733
  };
1730
1734
  }
1735
+ async resolveModel() {
1736
+ if (this.model)
1737
+ return this.model;
1738
+ if (this.modelSelector) {
1739
+ const ctx = this.selectionContext ?? {
1740
+ taskDimension: "reasoning"
1741
+ };
1742
+ const result = await this.modelSelector.select(ctx);
1743
+ return result.modelId;
1744
+ }
1745
+ return;
1746
+ }
1731
1747
  async planWithLlm(brief) {
1732
1748
  const { t } = this.i18n;
1733
1749
  const messages = [
@@ -1757,8 +1773,9 @@ class ScenePlanner {
1757
1773
  return this.planDeterministic(brief);
1758
1774
  }
1759
1775
  try {
1776
+ const model = await this.resolveModel();
1760
1777
  const response = await this.llm.chat(messages, {
1761
- model: this.model,
1778
+ model,
1762
1779
  temperature: this.temperature,
1763
1780
  responseFormat: "json"
1764
1781
  });
@@ -1797,7 +1814,9 @@ class VideoGenerator {
1797
1814
  model: options?.model,
1798
1815
  temperature: options?.temperature,
1799
1816
  fps: this.fps,
1800
- locale: options?.locale
1817
+ locale: options?.locale,
1818
+ modelSelector: options?.modelSelector,
1819
+ selectionContext: options?.selectionContext
1801
1820
  });
1802
1821
  }
1803
1822
  async generate(brief) {
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -718,7 +735,9 @@ class VideoGenerator {
718
735
  model: options?.model,
719
736
  temperature: options?.temperature,
720
737
  fps: this.fps,
721
- locale: options?.locale
738
+ locale: options?.locale,
739
+ modelSelector: options?.modelSelector,
740
+ selectionContext: options?.selectionContext
722
741
  });
723
742
  }
724
743
  async generate(brief) {
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -516,11 +516,15 @@ class ScriptGenerator {
516
516
  model;
517
517
  temperature;
518
518
  i18n;
519
+ modelSelector;
520
+ selectionContext;
519
521
  constructor(options) {
520
522
  this.llm = options?.llm;
521
523
  this.model = options?.model;
522
524
  this.temperature = options?.temperature ?? 0.5;
523
525
  this.i18n = createVideoGenI18n(options?.locale);
526
+ this.modelSelector = options?.modelSelector;
527
+ this.selectionContext = options?.selectionContext;
524
528
  }
525
529
  async generate(brief, config) {
526
530
  const style = config?.style ?? "professional";
@@ -585,6 +589,18 @@ class ScriptGenerator {
585
589
  style
586
590
  };
587
591
  }
592
+ async resolveModel() {
593
+ if (this.model)
594
+ return this.model;
595
+ if (this.modelSelector) {
596
+ const ctx = this.selectionContext ?? {
597
+ taskDimension: "reasoning"
598
+ };
599
+ const result = await this.modelSelector.select(ctx);
600
+ return result.modelId;
601
+ }
602
+ return;
603
+ }
588
604
  async generateWithLlm(brief, style) {
589
605
  const { t } = this.i18n;
590
606
  const styleGuide = {
@@ -614,8 +630,9 @@ class ScriptGenerator {
614
630
  return this.generateDeterministic(brief, style);
615
631
  }
616
632
  try {
633
+ const model = await this.resolveModel();
617
634
  const response = await this.llm.chat(messages, {
618
- model: this.model,
635
+ model,
619
636
  temperature: this.temperature,
620
637
  responseFormat: "json"
621
638
  });
@@ -552,12 +552,16 @@ class ScenePlanner {
552
552
  temperature;
553
553
  fps;
554
554
  i18n;
555
+ modelSelector;
556
+ selectionContext;
555
557
  constructor(options) {
556
558
  this.llm = options?.llm;
557
559
  this.model = options?.model;
558
560
  this.temperature = options?.temperature ?? 0.3;
559
561
  this.fps = options?.fps ?? DEFAULT_FPS;
560
562
  this.i18n = createVideoGenI18n(options?.locale);
563
+ this.modelSelector = options?.modelSelector;
564
+ this.selectionContext = options?.selectionContext;
561
565
  }
562
566
  async plan(brief) {
563
567
  if (this.llm) {
@@ -649,6 +653,18 @@ class ScenePlanner {
649
653
  narrationScript
650
654
  };
651
655
  }
656
+ async resolveModel() {
657
+ if (this.model)
658
+ return this.model;
659
+ if (this.modelSelector) {
660
+ const ctx = this.selectionContext ?? {
661
+ taskDimension: "reasoning"
662
+ };
663
+ const result = await this.modelSelector.select(ctx);
664
+ return result.modelId;
665
+ }
666
+ return;
667
+ }
652
668
  async planWithLlm(brief) {
653
669
  const { t } = this.i18n;
654
670
  const messages = [
@@ -678,8 +694,9 @@ class ScenePlanner {
678
694
  return this.planDeterministic(brief);
679
695
  }
680
696
  try {
697
+ const model = await this.resolveModel();
681
698
  const response = await this.llm.chat(messages, {
682
- model: this.model,
699
+ model,
683
700
  temperature: this.temperature,
684
701
  responseFormat: "json"
685
702
  });
@@ -718,7 +735,9 @@ class VideoGenerator {
718
735
  model: options?.model,
719
736
  temperature: options?.temperature,
720
737
  fps: this.fps,
721
- locale: options?.locale
738
+ locale: options?.locale,
739
+ modelSelector: options?.modelSelector,
740
+ selectionContext: options?.selectionContext
722
741
  });
723
742
  }
724
743
  async generate(brief) {
@@ -1631,12 +1631,16 @@ class ScenePlanner {
1631
1631
  temperature;
1632
1632
  fps;
1633
1633
  i18n;
1634
+ modelSelector;
1635
+ selectionContext;
1634
1636
  constructor(options) {
1635
1637
  this.llm = options?.llm;
1636
1638
  this.model = options?.model;
1637
1639
  this.temperature = options?.temperature ?? 0.3;
1638
1640
  this.fps = options?.fps ?? DEFAULT_FPS;
1639
1641
  this.i18n = createVideoGenI18n(options?.locale);
1642
+ this.modelSelector = options?.modelSelector;
1643
+ this.selectionContext = options?.selectionContext;
1640
1644
  }
1641
1645
  async plan(brief) {
1642
1646
  if (this.llm) {
@@ -1728,6 +1732,18 @@ class ScenePlanner {
1728
1732
  narrationScript
1729
1733
  };
1730
1734
  }
1735
+ async resolveModel() {
1736
+ if (this.model)
1737
+ return this.model;
1738
+ if (this.modelSelector) {
1739
+ const ctx = this.selectionContext ?? {
1740
+ taskDimension: "reasoning"
1741
+ };
1742
+ const result = await this.modelSelector.select(ctx);
1743
+ return result.modelId;
1744
+ }
1745
+ return;
1746
+ }
1731
1747
  async planWithLlm(brief) {
1732
1748
  const { t } = this.i18n;
1733
1749
  const messages = [
@@ -1757,8 +1773,9 @@ class ScenePlanner {
1757
1773
  return this.planDeterministic(brief);
1758
1774
  }
1759
1775
  try {
1776
+ const model = await this.resolveModel();
1760
1777
  const response = await this.llm.chat(messages, {
1761
- model: this.model,
1778
+ model,
1762
1779
  temperature: this.temperature,
1763
1780
  responseFormat: "json"
1764
1781
  });
@@ -1797,7 +1814,9 @@ class VideoGenerator {
1797
1814
  model: options?.model,
1798
1815
  temperature: options?.temperature,
1799
1816
  fps: this.fps,
1800
- locale: options?.locale
1817
+ locale: options?.locale,
1818
+ modelSelector: options?.modelSelector,
1819
+ selectionContext: options?.selectionContext
1801
1820
  });
1802
1821
  }
1803
1822
  async generate(brief) {
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { LLMProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/llm';
2
+ import type { ModelSelector, ModelSelectionContext } from '@contractspec/lib.ai-providers/selector-types';
2
3
  import type { VoiceSynthesizer } from '@contractspec/lib.voice/tts';
3
4
  import type { Transcriber } from '@contractspec/lib.voice/stt';
4
5
  import type { ContentBrief } from '@contractspec/lib.content-gen/types';
@@ -46,6 +47,16 @@ export interface VideoGeneratorOptions {
46
47
  fps?: number;
47
48
  /** Locale for generated content and LLM prompts (defaults to "en") */
48
49
  locale?: string;
50
+ /** Ranking-driven model selector for dynamic model routing */
51
+ modelSelector?: ModelSelector;
52
+ /** Per-call selection context override */
53
+ selectionContext?: ModelSelectionContext;
54
+ /** Transport mode for video/LLM providers. */
55
+ transport?: 'rest' | 'mcp' | 'sdk';
56
+ /** Auth method for video/LLM providers. */
57
+ authMethod?: 'api-key' | 'oauth2' | 'bearer';
58
+ /** Custom auth headers for video/LLM providers. */
59
+ authHeaders?: Record<string, string>;
49
60
  }
50
61
  export interface GeneratedVideo {
51
62
  project: VideoProject;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.video-gen",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -25,26 +25,27 @@
25
25
  "typecheck": "tsc --noEmit"
26
26
  },
27
27
  "dependencies": {
28
- "@contractspec/lib.contracts-spec": "3.0.0",
29
- "@contractspec/lib.contracts-integrations": "3.0.0",
30
- "@contractspec/lib.voice": "1.0.0",
31
- "@contractspec/lib.content-gen": "3.0.0",
32
- "@contractspec/lib.design-system": "3.0.0",
33
- "@contractspec/lib.image-gen": "1.0.0",
34
- "remotion": "^4.0.429"
28
+ "@contractspec/lib.contracts-spec": "3.1.1",
29
+ "@contractspec/lib.contracts-integrations": "3.1.1",
30
+ "@contractspec/lib.ai-providers": "3.1.1",
31
+ "@contractspec/lib.voice": "1.1.1",
32
+ "@contractspec/lib.content-gen": "3.1.1",
33
+ "@contractspec/lib.design-system": "3.1.1",
34
+ "@contractspec/lib.image-gen": "1.1.1",
35
+ "remotion": "^4.0.434"
35
36
  },
36
37
  "devDependencies": {
37
- "@contractspec/tool.typescript": "3.0.0",
38
- "@contractspec/tool.bun": "3.0.0",
38
+ "@contractspec/tool.typescript": "3.1.0",
39
+ "@contractspec/tool.bun": "3.1.0",
39
40
  "typescript": "^5.9.3",
40
- "@remotion/bundler": "^4.0.429",
41
- "@remotion/cli": "^4.0.429",
42
- "@remotion/player": "^4.0.429",
43
- "@remotion/renderer": "^4.0.429",
41
+ "@remotion/bundler": "^4.0.434",
42
+ "@remotion/cli": "^4.0.434",
43
+ "@remotion/player": "^4.0.434",
44
+ "@remotion/renderer": "^4.0.434",
44
45
  "@types/react": "^19.0.0",
45
46
  "react": "^19.0.0",
46
47
  "react-dom": "^19.0.0",
47
- "tsdown": "^0.20.3"
48
+ "tsdown": "^0.21.0"
48
49
  },
49
50
  "peerDependencies": {
50
51
  "react": "^19.0.0",