lumiverse-spindle-types 0.5.28 → 0.5.30

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lumiverse-spindle-types",
3
3
 
4
- "version": "0.5.28",
4
+ "version": "0.5.30",
5
5
  "types": "./src/index.ts",
6
6
  "keywords": [
7
7
  "lumiverse",
package/src/api.ts CHANGED
@@ -615,6 +615,7 @@ export interface ImageGenResultDTO {
615
615
  // ─── Image DTOs ─────────────────────────────────────────────────────────
616
616
 
617
617
  export type ImageSpecificityDTO = "full" | "sm" | "lg";
618
+ export type ImageVideoCodecDTO = "h264" | "hevc";
618
619
 
619
620
  export interface ImageListOptionsDTO {
620
621
  limit?: number;
@@ -644,7 +645,7 @@ export interface ImageGetOptionsDTO {
644
645
  userId?: string;
645
646
  }
646
647
 
647
- /** Safe representation of an image exposed to extensions. */
648
+ /** Safe representation of an image/video asset exposed to extensions. */
648
649
  export interface ImageDTO {
649
650
  id: string;
650
651
  original_filename: string;
@@ -663,7 +664,7 @@ export interface ImageDTO {
663
664
 
664
665
  /** Upload payload for `spindle.images.upload()` */
665
666
  export interface ImageUploadDTO {
666
- /** Raw image bytes. */
667
+ /** Raw image or video bytes. */
667
668
  data: Uint8Array;
668
669
  /** Optional filename used to preserve the extension/MIME when storing the image. */
669
670
  filename?: string;
@@ -673,6 +674,12 @@ export interface ImageUploadDTO {
673
674
  owner_character_id?: string;
674
675
  /** Optional chat ownership tag for the persisted image. */
675
676
  owner_chat_id?: string;
677
+ /** For video uploads, strip any audio tracks from the stored output when possible. */
678
+ strip_audio?: boolean;
679
+ /** For video uploads, transcode the primary stored asset to this codec. */
680
+ transcode_video_codec?: ImageVideoCodecDTO;
681
+ /** Optional extra video variants to generate alongside the primary stored asset. */
682
+ sidecar_video_codecs?: ImageVideoCodecDTO[];
676
683
  }
677
684
 
678
685
  export interface ImageUploadFromDataUrlOptionsDTO {
@@ -685,6 +692,159 @@ export interface ImageUploadFromDataUrlOptionsDTO {
685
692
  userId?: string;
686
693
  }
687
694
 
695
+ // ─── Media DTOs ─────────────────────────────────────────────────────────
696
+
697
+ export type MediaSourceDTO =
698
+ | {
699
+ kind: "inline";
700
+ data: Uint8Array;
701
+ filename?: string;
702
+ mime_type?: string;
703
+ }
704
+ | {
705
+ kind: "upload";
706
+ upload_id: string;
707
+ filename?: string;
708
+ mime_type?: string;
709
+ }
710
+ | {
711
+ /**
712
+ * Image or video asset already stored in Lumiverse's images table.
713
+ * This can point at either a still image or a video upload.
714
+ */
715
+ kind: "image";
716
+ image_id: string;
717
+ }
718
+ | {
719
+ /** Audio asset already stored in Lumiverse's audio_files table. */
720
+ kind: "audio";
721
+ audio_id: string;
722
+ };
723
+
724
+ export type MediaAudioFormatDTO =
725
+ | "mp3"
726
+ | "wav"
727
+ | "ogg"
728
+ | "aac"
729
+ | "flac"
730
+ | "m4a"
731
+ | "webm";
732
+
733
+ export type MediaVideoFormatDTO =
734
+ | "mp4"
735
+ | "webm"
736
+ | "mov"
737
+ | "mkv";
738
+
739
+ export type MediaVideoCodecDTO =
740
+ | "h264"
741
+ | "hevc"
742
+ | "vp9"
743
+ | "av1"
744
+ | "copy";
745
+
746
+ export type MediaAudioCodecDTO =
747
+ | "aac"
748
+ | "mp3"
749
+ | "opus"
750
+ | "vorbis"
751
+ | "flac"
752
+ | "pcm_s16le"
753
+ | "copy";
754
+
755
+ export type MediaFitModeDTO = "contain" | "cover" | "stretch";
756
+
757
+ export interface MediaTransformResultDTO {
758
+ data: Uint8Array;
759
+ filename: string;
760
+ mime_type: string;
761
+ byte_size: number;
762
+ duration_ms?: number | null;
763
+ width?: number | null;
764
+ height?: number | null;
765
+ }
766
+
767
+ export interface MediaConvertAudioRequestDTO {
768
+ source: MediaSourceDTO;
769
+ output_format: MediaAudioFormatDTO;
770
+ audio_codec?: MediaAudioCodecDTO;
771
+ bitrate_kbps?: number;
772
+ sample_rate?: number;
773
+ channels?: number;
774
+ filename?: string;
775
+ /** For operator-scoped extensions. */
776
+ userId?: string;
777
+ }
778
+
779
+ export interface MediaConvertVideoRequestDTO {
780
+ source: MediaSourceDTO;
781
+ output_format: MediaVideoFormatDTO;
782
+ filename?: string;
783
+ /** For operator-scoped extensions. */
784
+ userId?: string;
785
+ }
786
+
787
+ export interface MediaTranscodeVideoRequestDTO {
788
+ source: MediaSourceDTO;
789
+ output_format?: MediaVideoFormatDTO;
790
+ video_codec?: MediaVideoCodecDTO;
791
+ audio_codec?: MediaAudioCodecDTO | "none";
792
+ video_bitrate_kbps?: number;
793
+ audio_bitrate_kbps?: number;
794
+ crf?: number;
795
+ preset?: string;
796
+ width?: number;
797
+ height?: number;
798
+ fps?: number;
799
+ pixel_format?: string;
800
+ faststart?: boolean;
801
+ filename?: string;
802
+ /** For operator-scoped extensions. */
803
+ userId?: string;
804
+ }
805
+
806
+ export interface MediaRemoveAudioFromVideoRequestDTO {
807
+ source: MediaSourceDTO;
808
+ output_format?: MediaVideoFormatDTO;
809
+ video_codec?: MediaVideoCodecDTO;
810
+ filename?: string;
811
+ /** For operator-scoped extensions. */
812
+ userId?: string;
813
+ }
814
+
815
+ export interface MediaAddAudioToVideoRequestDTO {
816
+ video: MediaSourceDTO;
817
+ audio: MediaSourceDTO;
818
+ output_format?: MediaVideoFormatDTO;
819
+ video_codec?: MediaVideoCodecDTO;
820
+ audio_codec?: MediaAudioCodecDTO;
821
+ /** Defaults to true: replace any existing audio track on the source video. */
822
+ replace_existing_audio?: boolean;
823
+ /** When true, clamp the output duration to the shorter input stream. */
824
+ shortest?: boolean;
825
+ /** Optional positive offset, in milliseconds, before the new audio starts. */
826
+ audio_start_ms?: number;
827
+ filename?: string;
828
+ /** For operator-scoped extensions. */
829
+ userId?: string;
830
+ }
831
+
832
+ export interface MediaCreateVideoFromImageAndAudioRequestDTO {
833
+ image: MediaSourceDTO;
834
+ audio: MediaSourceDTO;
835
+ output_format?: MediaVideoFormatDTO;
836
+ video_codec?: Exclude<MediaVideoCodecDTO, "copy">;
837
+ audio_codec?: MediaAudioCodecDTO;
838
+ width?: number;
839
+ height?: number;
840
+ fps?: number;
841
+ fit_mode?: MediaFitModeDTO;
842
+ background_color?: string;
843
+ filename?: string;
844
+ /** For operator-scoped extensions. */
845
+ userId?: string;
846
+ }
847
+
688
848
  // ─── Character DTOs ─────────────────────────────────────────────────────
689
849
 
690
850
  /**
@@ -2347,6 +2507,13 @@ export interface TokenCountResultDTO {
2347
2507
  approximate: boolean;
2348
2508
  }
2349
2509
 
2510
+ /** A completed resumable upload read back by `spindle.uploads.get`. */
2511
+ export interface SpindleUploadDTO {
2512
+ fileName: string;
2513
+ size: number;
2514
+ data: Uint8Array;
2515
+ }
2516
+
2350
2517
  /** Context delivered to an on-request shared RPC endpoint handler. */
2351
2518
  export interface SharedRpcRequestContextDTO {
2352
2519
  /** Fully-qualified endpoint name (for example `weather_ext.status.current`). */
@@ -2845,6 +3012,17 @@ export type WorkerToHost =
2845
3012
  userId?: string;
2846
3013
  }
2847
3014
  | { type: "images_delete"; requestId: string; imageId: string; userId?: string }
3015
+ // ─── Media (gated: "media") ─────────────────────────────────────────
3016
+ | { type: "media_audio_convert"; requestId: string; input: MediaConvertAudioRequestDTO }
3017
+ | { type: "media_video_convert"; requestId: string; input: MediaConvertVideoRequestDTO }
3018
+ | { type: "media_video_transcode"; requestId: string; input: MediaTranscodeVideoRequestDTO }
3019
+ | { type: "media_video_remove_audio"; requestId: string; input: MediaRemoveAudioFromVideoRequestDTO }
3020
+ | { type: "media_video_add_audio"; requestId: string; input: MediaAddAudioToVideoRequestDTO }
3021
+ | {
3022
+ type: "media_video_from_image_audio";
3023
+ requestId: string;
3024
+ input: MediaCreateVideoFromImageAndAudioRequestDTO;
3025
+ }
2848
3026
  // ─── Theme (gated: "app_manipulation") ──────────────────────────────────
2849
3027
  | { type: "theme_apply"; requestId: string; overrides: ThemeOverrideDTO; userId?: string }
2850
3028
  | { type: "theme_apply_palette"; requestId: string; palette: ThemePaletteConfigDTO | null; userId?: string }
package/src/index.ts CHANGED
@@ -119,8 +119,22 @@ export type {
119
119
  ImageDTO,
120
120
  ImageListOptionsDTO,
121
121
  ImageSpecificityDTO,
122
+ ImageVideoCodecDTO,
122
123
  ImageUploadDTO,
123
124
  ImageUploadFromDataUrlOptionsDTO,
125
+ MediaSourceDTO,
126
+ MediaAudioFormatDTO,
127
+ MediaVideoFormatDTO,
128
+ MediaVideoCodecDTO,
129
+ MediaAudioCodecDTO,
130
+ MediaFitModeDTO,
131
+ MediaTransformResultDTO,
132
+ MediaConvertAudioRequestDTO,
133
+ MediaConvertVideoRequestDTO,
134
+ MediaTranscodeVideoRequestDTO,
135
+ MediaRemoveAudioFromVideoRequestDTO,
136
+ MediaAddAudioToVideoRequestDTO,
137
+ MediaCreateVideoFromImageAndAudioRequestDTO,
124
138
  ThemeOverrideDTO,
125
139
  ThemeInfoDTO,
126
140
  ThemePaletteConfigDTO,
@@ -160,6 +174,7 @@ export type {
160
174
  TokenModelSourceDTO,
161
175
  TokenCountOptionsDTO,
162
176
  TokenCountResultDTO,
177
+ SpindleUploadDTO,
163
178
  SharedRpcRequestContextDTO,
164
179
  SharedRpcEndpointPolicyDTO,
165
180
  MacroInterceptorPhase,
@@ -18,6 +18,8 @@
18
18
  * - "memories" — CRUD on the Memory Cortex (entities, relations, vaults, chat
19
19
  * links, consolidations) and long-term chat memory (vectorized
20
20
  * chat-chunk retrieval, warmup, cache).
21
+ * - "media" — invoke the backend media pipeline for audio/video conversion,
22
+ * transcoding, muxing, and simple image+audio composition.
21
23
  * - "macro_interceptor" — transform raw templates before macro parsing/dispatch
22
24
  * - "web_search" — execute searches via the user's configured web search
23
25
  * provider (e.g. SearXNG) and read the safe view of their
@@ -44,6 +46,7 @@ export type SpindlePermission =
44
46
  | "regex_scripts"
45
47
  | "databanks"
46
48
  | "memories"
49
+ | "media"
47
50
  | "personas"
48
51
  | "push_notification"
49
52
  | "image_gen"
@@ -72,6 +75,7 @@ export const ALL_PERMISSIONS: readonly SpindlePermission[] = [
72
75
  "regex_scripts",
73
76
  "databanks",
74
77
  "memories",
78
+ "media",
75
79
  "personas",
76
80
  "push_notification",
77
81
  "image_gen",
@@ -65,6 +65,13 @@ import type {
65
65
  ImageListOptionsDTO,
66
66
  ImageUploadDTO,
67
67
  ImageUploadFromDataUrlOptionsDTO,
68
+ MediaConvertAudioRequestDTO,
69
+ MediaConvertVideoRequestDTO,
70
+ MediaTranscodeVideoRequestDTO,
71
+ MediaRemoveAudioFromVideoRequestDTO,
72
+ MediaAddAudioToVideoRequestDTO,
73
+ MediaCreateVideoFromImageAndAudioRequestDTO,
74
+ MediaTransformResultDTO,
68
75
  ThemeOverrideDTO,
69
76
  ThemeInfoDTO,
70
77
  ThemePaletteConfigDTO,
@@ -100,6 +107,7 @@ import type {
100
107
  StreamChunkDTO,
101
108
  TokenCountOptionsDTO,
102
109
  TokenCountResultDTO,
110
+ SpindleUploadDTO,
103
111
  MacroInterceptorCtxDTO,
104
112
  MacroInterceptorResultDTO,
105
113
  WorldInfoInterceptorCtxDTO,
@@ -719,6 +727,17 @@ export interface SpindleAPI {
719
727
  countChat(chatId: string, options?: TokenCountOptionsDTO): Promise<TokenCountResultDTO>;
720
728
  };
721
729
 
730
+ /**
731
+ * Resumable uploads (free tier). Consume a file the user streamed to the host
732
+ * tus endpoint (`/api/v1/spindle-uploads`), scoped to this extension + user.
733
+ */
734
+ uploads: {
735
+ /** Read a completed upload's bytes. Null if missing, expired, or not owned by this extension + user. */
736
+ get(uploadId: string, userId?: string): Promise<SpindleUploadDTO | null>;
737
+ /** Delete a staged upload once consumed. Returns false if it was already gone. */
738
+ delete(uploadId: string, userId?: string): Promise<boolean>;
739
+ };
740
+
722
741
  /**
723
742
  * Image generation (permission: "image_gen").
724
743
  * Generate images via the user's configured image gen connection profiles.
@@ -754,8 +773,8 @@ export interface SpindleAPI {
754
773
  };
755
774
 
756
775
  /**
757
- * Image CRUD (permission: "images").
758
- * Manage images stored in Lumiverse's image system on behalf of the user.
776
+ * Image/video asset CRUD (permission: "images").
777
+ * Manage assets stored in Lumiverse's image system on behalf of the user.
759
778
  * For user-scoped extensions, userId is inferred from the extension owner.
760
779
  * For operator-scoped extensions, pass userId to scope to a specific user.
761
780
  */
@@ -773,6 +792,20 @@ export interface SpindleAPI {
773
792
  delete(imageId: string, userId?: string): Promise<boolean>;
774
793
  };
775
794
 
795
+ /**
796
+ * Backend media conversion and composition (permission: "media").
797
+ * Uses Lumiverse's host-side media pipeline for audio/video transforms.
798
+ * Sources may be inline bytes, staged uploads, or existing Lumiverse assets.
799
+ */
800
+ media: {
801
+ convertAudio(input: MediaConvertAudioRequestDTO): Promise<MediaTransformResultDTO>;
802
+ convertVideo(input: MediaConvertVideoRequestDTO): Promise<MediaTransformResultDTO>;
803
+ transcodeVideo(input: MediaTranscodeVideoRequestDTO): Promise<MediaTransformResultDTO>;
804
+ removeAudioFromVideo(input: MediaRemoveAudioFromVideoRequestDTO): Promise<MediaTransformResultDTO>;
805
+ addAudioToVideo(input: MediaAddAudioToVideoRequestDTO): Promise<MediaTransformResultDTO>;
806
+ createVideoFromImageAndAudio(input: MediaCreateVideoFromImageAndAudioRequestDTO): Promise<MediaTransformResultDTO>;
807
+ };
808
+
776
809
  /**
777
810
  * Local (transient), global (user-scoped), and chat (persisted) variable access
778
811
  * (free tier — no permission needed).