ugcinc 4.5.78 → 4.5.81

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.
@@ -22,7 +22,7 @@ export interface Account {
22
22
  age_range: string | null;
23
23
  sex: string | null;
24
24
  status: 'uninitialized' | 'pending' | 'initialized' | 'setup' | 'warming' | 'warmed' | 'needs_replacement' | 'replacing' | 'failed' | 'deleted' | 'reclaimed';
25
- phone_type: 'physical_iphone' | 'physical_android' | 'emulated_android' | 'social_api' | 'custom_provider' | 'tracking' | null;
25
+ phone_type: 'physical_iphone' | 'manual_iphone' | 'physical_android' | 'emulated_android' | 'social_api' | 'custom_provider' | 'tracking' | null;
26
26
  approved: boolean;
27
27
  replacement_count: number;
28
28
  oneup_social_network_id?: string | null;
@@ -106,7 +106,7 @@ export interface AccountInfoUpdate {
106
106
  description?: string;
107
107
  warmupVersion?: 'original' | 'v1_smart' | 'v2_smart';
108
108
  postVersion?: 'original' | 'v1_custom';
109
- phoneType?: 'physical_iphone' | 'physical_android' | 'emulated_android' | 'social_api' | 'custom_provider' | 'tracking';
109
+ phoneType?: 'physical_iphone' | 'manual_iphone' | 'physical_android' | 'emulated_android' | 'social_api' | 'custom_provider' | 'tracking';
110
110
  approved?: boolean;
111
111
  }
112
112
  export interface UpdateAccountInfoParams {
@@ -306,6 +306,17 @@ export declare const nodeDefinitions: {
306
306
  __TInputs: import("./save-to-media").SaveToMediaNodeInputs;
307
307
  __TOutputs: import("./save-to-media").SaveToMediaNodeOutputs;
308
308
  };
309
+ readonly 'scene-split': NodeDefinition<"scene-split", "generator", {
310
+ detector_type: import("../..").SceneSplitDetectorConfig["detector_type"];
311
+ threshold: number;
312
+ min_scene_length_sec: number;
313
+ fade_detection: boolean;
314
+ outputMode: import("./types").OutputMode;
315
+ selectionMode: import("./types").SelectionMode | null;
316
+ }, import("./scene-split").SceneSplitNodeInputs, import("./scene-split").SceneSplitNodeOutputs, false> & {
317
+ __TInputs: import("./scene-split").SceneSplitNodeInputs;
318
+ __TOutputs: import("./scene-split").SceneSplitNodeOutputs;
319
+ };
309
320
  readonly 'screenshot-animation': NodeDefinition<"screenshot-animation", "generator", {
310
321
  holdDurationMs: number;
311
322
  imageIsVariable: boolean;
@@ -35,6 +35,7 @@ const random_1 = __importDefault(require("./random"));
35
35
  const regex_1 = __importDefault(require("./regex"));
36
36
  const random_route_1 = __importDefault(require("./random-route"));
37
37
  const save_to_media_1 = __importDefault(require("./save-to-media"));
38
+ const scene_split_1 = __importDefault(require("./scene-split"));
38
39
  const screenshot_animation_1 = __importDefault(require("./screenshot-animation"));
39
40
  const social_audio_1 = __importDefault(require("./social-audio"));
40
41
  const text_1 = __importDefault(require("./text"));
@@ -74,6 +75,7 @@ exports.nodeDefinitions = {
74
75
  'regex': regex_1.default,
75
76
  'random-route': random_route_1.default,
76
77
  'save-to-media': save_to_media_1.default,
78
+ 'scene-split': scene_split_1.default,
77
79
  'screenshot-animation': screenshot_animation_1.default,
78
80
  'social-audio': social_audio_1.default,
79
81
  'text': text_1.default,
@@ -0,0 +1,23 @@
1
+ import type { VideoValue } from '../types';
2
+ import type { SceneSplitDetectorConfig } from '../../render';
3
+ import { type OutputMode, type SelectionMode } from './types';
4
+ export interface SceneSplitNodeInputs {
5
+ video: VideoValue;
6
+ }
7
+ export interface SceneSplitNodeOutputs {
8
+ clips: VideoValue[];
9
+ }
10
+ declare const definition: import("./types").NodeDefinition<"scene-split", "generator", {
11
+ detector_type: SceneSplitDetectorConfig["detector_type"];
12
+ threshold: number;
13
+ min_scene_length_sec: number;
14
+ fade_detection: boolean;
15
+ outputMode: OutputMode;
16
+ selectionMode: SelectionMode | null;
17
+ }, SceneSplitNodeInputs, SceneSplitNodeOutputs, false>;
18
+ declare const _default: typeof definition & {
19
+ __TInputs: SceneSplitNodeInputs;
20
+ __TOutputs: SceneSplitNodeOutputs;
21
+ };
22
+ export default _default;
23
+ export type SceneSplitNodeConfig = typeof definition.defaults;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const types_1 = require("./types");
4
+ // =============================================================================
5
+ // Node Definition
6
+ // =============================================================================
7
+ const definition = (0, types_1.defineNode)({
8
+ nodeId: 'scene-split',
9
+ label: 'Scene Split',
10
+ description: 'Split a video into clips at detected scene boundaries',
11
+ guide: 'Detects scene boundaries in a video using frame analysis and splits it into individual clips. Supports Content Detector (for hard cuts) and Adaptive Detector (adapts to varying content). Configure threshold sensitivity, minimum scene length, and optional fade detection. Output is an array of video clips — connect to a For Each node to process each clip individually. Use cases: splitting long-form content into short clips, isolating scenes for selective reposting, breaking down compilation videos.',
12
+ type: 'generator',
13
+ category: 'Generation',
14
+ outputModes: ['per-input', 'single'],
15
+ selectionModes: null,
16
+ defaults: {
17
+ detector_type: 'content',
18
+ threshold: 27.0,
19
+ min_scene_length_sec: 2.0,
20
+ fade_detection: false,
21
+ outputMode: 'per-input',
22
+ selectionMode: null,
23
+ },
24
+ computePorts: () => ({
25
+ inputs: [
26
+ {
27
+ id: 'video',
28
+ type: 'video',
29
+ isArray: false,
30
+ required: true,
31
+ },
32
+ ],
33
+ outputs: [
34
+ {
35
+ id: 'clips',
36
+ type: 'video',
37
+ isArray: true,
38
+ required: true,
39
+ },
40
+ ],
41
+ }),
42
+ generatePreview: (_config, _ctx, cachedOutputs) => {
43
+ return (0, types_1.preview)({
44
+ clips: cachedOutputs?.clips ?? null,
45
+ });
46
+ },
47
+ });
48
+ exports.default = definition;
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { AutomationsClient } from './automations';
13
13
  export { MediaClient } from './media';
14
14
  export { CommentsClient } from './comments';
15
15
  export { BillingClient } from './billing';
16
- export { submitImageRenderJob, submitVideoRenderJob, getRenderJobStatus, submitDeduplicationJob, submitScreenshotAnimationRenderJob, submitAutoCaptionRenderJob, submitInstagramDmRenderJob, submitIMessageDmRenderJob, } from './render';
16
+ export { submitImageRenderJob, submitVideoRenderJob, getRenderJobStatus, submitDeduplicationJob, submitSceneSplitJob, submitScreenshotAnimationRenderJob, submitAutoCaptionRenderJob, submitInstagramDmRenderJob, submitIMessageDmRenderJob, } from './render';
17
17
  export { areTypesCompatible, computePortsForNode, computePortsWithPreviews, computeAllNodePorts, computeAllNodePortsWithPreviews, getInputPreviewValue, getAllNodes, getNodeByType, getOutputSchema, createNode, deriveConnections, addConnection, removeConnection, removeNodeConnections, cleanupStaleConnections, getConnectedSource, getForEachContext, checkCrossContextViolation, getDownstreamNodes, getNodesDownstreamOfSet, getCapturedNodes, validateWorkflow, getErrorNodeIds, getPortErrorsForNode, hasMissingTriggerError, hasMissingTerminalError, getWorkflowOutputSchema, resolveNodePreview, computeAllNodePreviews, computePreviewMap, updatePreviewMapForConnection, removePreviewForConnection, getPreviewValue, shuffleNodePreview, type PreviewMap, type NodePreviewOutputs, type Connection, generateNodeName, extractWorkflowConfig, type WorkflowTemplateData, } from './automations/graph-controller';
18
18
  export { nodeDefinitions, internalNodeTypes, isAsyncExecutor, formatPortType, isPortType } from './automations/types';
19
19
  export { getNodeDefinition, getAllNodeDefinitions, getFlowControlNodeTypes, getCapturedSourceNodeTypes } from './automations/nodes';
@@ -33,7 +33,7 @@ export type { Org, ApiKey, DeleteApiKeyParams, EditApiKeyParams, IntegrationKey,
33
33
  export type { UserMedia, MediaUse, SocialAudio, Media, GetMediaParams, GetSocialAudioParams, UploadMediaParams, UploadMediaResponse, MediaTagUpdate, UpdateMediaTagsParams, MediaTagUpdateResult, UpdateMediaTagsResponse, UpdateMediaTagParams, UpdateMediaNameParams, DeleteMediaParams, DeleteMediaResponse, CreateSocialAudioParams, ImportTextParams, ImportTextResponse, CreateMediaFromUrlParams, GetMediaUseParams, GetMediaUseResponse, FilterMediaParams, FilterMediaResponse, GetUploadTokenParams, UploadTokenResponse, } from './media';
34
34
  export type { CommentStatus, Comment, CreateCommentParams, CreateCommentResponse, GetCommentsParams, } from './comments';
35
35
  export type { BillingInfo, CancelSubscriptionResponse, PortalUrlResponse, DeactivateAccountParams, DeactivateAccountResponse, RequestReplacementParams, RequestReplacementResponse, RequestRefundParams, RequestRefundResponse, BillingRequestInfo, PortalParams, } from './billing';
36
- export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitAutoCaptionRenderJobParams, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
36
+ export type { RenderJobResponse, RenderJobStatus, SubmitImageRenderJobParams, SubmitVideoRenderJobParams, SubmitScreenshotAnimationRenderJobParams, SubmitAutoCaptionRenderJobParams, SubmitSceneSplitJobParams, SceneSplitDetectorConfig, SubmitInstagramDmRenderJobParams, SubmitIMessageDmRenderJobParams, IgDmMessage, ImDmMessage, RenderVideoEditorConfig, } from './render';
37
37
  export type { VideoEditorNodeConfig, VideoEditorChannel, VideoEditorSegment, VideoEditorVideoSegment, VideoEditorAudioSegment, VideoEditorImageSegment, VideoEditorTextSegment, VideoEditorImageSequenceSegment, VideoEditorVideoSequenceSegment, TimeValue, TimeMode, SegmentTimelinePosition, DeduplicationLevel, DeduplicationInput, ImageEditorElement, DimensionPresetKey, } from './render/types';
38
38
  export type { ImageEditorNodeConfig, ImageComposerNodeConfig, ImageComposerRenderInput } from './automations/nodes/image-composer';
39
39
  export { prepareImageComposerInput } from './automations/nodes/image-composer';
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@
5
5
  * Official TypeScript/JavaScript client for the UGC Inc API
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.removePreviewForConnection = exports.updatePreviewMapForConnection = exports.computePreviewMap = exports.computeAllNodePreviews = exports.resolveNodePreview = exports.getWorkflowOutputSchema = exports.hasMissingTerminalError = exports.hasMissingTriggerError = exports.getPortErrorsForNode = exports.getErrorNodeIds = exports.validateWorkflow = exports.getCapturedNodes = exports.getNodesDownstreamOfSet = exports.getDownstreamNodes = exports.checkCrossContextViolation = exports.getForEachContext = exports.getConnectedSource = exports.cleanupStaleConnections = exports.removeNodeConnections = exports.removeConnection = exports.addConnection = exports.deriveConnections = exports.createNode = exports.getOutputSchema = exports.getNodeByType = exports.getAllNodes = exports.getInputPreviewValue = exports.computeAllNodePortsWithPreviews = exports.computeAllNodePorts = exports.computePortsWithPreviews = exports.computePortsForNode = exports.areTypesCompatible = exports.submitIMessageDmRenderJob = exports.submitInstagramDmRenderJob = exports.submitAutoCaptionRenderJob = exports.submitScreenshotAnimationRenderJob = exports.submitDeduplicationJob = exports.getRenderJobStatus = exports.submitVideoRenderJob = exports.submitImageRenderJob = exports.BillingClient = exports.CommentsClient = exports.MediaClient = exports.AutomationsClient = exports.OrganizationClient = exports.StatsClient = exports.PostsClient = exports.TasksClient = exports.AccountsClient = exports.UGCClient = void 0;
9
- exports.applyLogicOperator = exports.IfLogicOperators = exports.resolvePath = exports.indexExpressionToString = exports.indexExpressionToIndexes = exports.resolveUnknownPath = exports.getOutputTypeFromCategory = exports.parseOpenAPIOutputPath = exports.parseOpenAPIInputs = exports.mapOpenAPIType = exports.nodeConfigToCaptionStyle = exports.HttpMethods = exports.prepareImageComposerInput = exports.substituteVariables = exports.processTemplate = exports.extractTemplateVariables = exports.PortIdSchema = exports.normalizeToPortId = exports.portIdToTitle = exports.isValidPortId = exports.portId = exports.selectFromPool = exports.getModelDurations = exports.getModelAspectRatios = exports.ALL_VIDEO_MODELS = exports.getAvailableInputModes = exports.hasReferenceVariant = exports.getReferenceModelId = exports.hasFirstLastFrameVariant = exports.getFirstLastFrameModelId = exports.hasImageToVideoVariant = exports.getImageToVideoModelId = exports.isImageToVideoModel = exports.IMAGE_ASPECT_RATIOS = exports.ALL_IMAGE_MODELS = exports.getEditModelId = exports.isEditModel = exports.getCapturedSourceNodeTypes = exports.getFlowControlNodeTypes = exports.getAllNodeDefinitions = exports.getNodeDefinition = exports.isPortType = exports.formatPortType = exports.isAsyncExecutor = exports.internalNodeTypes = exports.nodeDefinitions = exports.extractWorkflowConfig = exports.generateNodeName = exports.shuffleNodePreview = exports.getPreviewValue = void 0;
10
- exports.prepareVideoComposerInput = exports.formatDateTag = exports.outputFieldsToZod = exports.outputFieldToZod = exports.LLMProviders = void 0;
8
+ exports.updatePreviewMapForConnection = exports.computePreviewMap = exports.computeAllNodePreviews = exports.resolveNodePreview = exports.getWorkflowOutputSchema = exports.hasMissingTerminalError = exports.hasMissingTriggerError = exports.getPortErrorsForNode = exports.getErrorNodeIds = exports.validateWorkflow = exports.getCapturedNodes = exports.getNodesDownstreamOfSet = exports.getDownstreamNodes = exports.checkCrossContextViolation = exports.getForEachContext = exports.getConnectedSource = exports.cleanupStaleConnections = exports.removeNodeConnections = exports.removeConnection = exports.addConnection = exports.deriveConnections = exports.createNode = exports.getOutputSchema = exports.getNodeByType = exports.getAllNodes = exports.getInputPreviewValue = exports.computeAllNodePortsWithPreviews = exports.computeAllNodePorts = exports.computePortsWithPreviews = exports.computePortsForNode = exports.areTypesCompatible = exports.submitIMessageDmRenderJob = exports.submitInstagramDmRenderJob = exports.submitAutoCaptionRenderJob = exports.submitScreenshotAnimationRenderJob = exports.submitSceneSplitJob = exports.submitDeduplicationJob = exports.getRenderJobStatus = exports.submitVideoRenderJob = exports.submitImageRenderJob = exports.BillingClient = exports.CommentsClient = exports.MediaClient = exports.AutomationsClient = exports.OrganizationClient = exports.StatsClient = exports.PostsClient = exports.TasksClient = exports.AccountsClient = exports.UGCClient = void 0;
9
+ exports.IfLogicOperators = exports.resolvePath = exports.indexExpressionToString = exports.indexExpressionToIndexes = exports.resolveUnknownPath = exports.getOutputTypeFromCategory = exports.parseOpenAPIOutputPath = exports.parseOpenAPIInputs = exports.mapOpenAPIType = exports.nodeConfigToCaptionStyle = exports.HttpMethods = exports.prepareImageComposerInput = exports.substituteVariables = exports.processTemplate = exports.extractTemplateVariables = exports.PortIdSchema = exports.normalizeToPortId = exports.portIdToTitle = exports.isValidPortId = exports.portId = exports.selectFromPool = exports.getModelDurations = exports.getModelAspectRatios = exports.ALL_VIDEO_MODELS = exports.getAvailableInputModes = exports.hasReferenceVariant = exports.getReferenceModelId = exports.hasFirstLastFrameVariant = exports.getFirstLastFrameModelId = exports.hasImageToVideoVariant = exports.getImageToVideoModelId = exports.isImageToVideoModel = exports.IMAGE_ASPECT_RATIOS = exports.ALL_IMAGE_MODELS = exports.getEditModelId = exports.isEditModel = exports.getCapturedSourceNodeTypes = exports.getFlowControlNodeTypes = exports.getAllNodeDefinitions = exports.getNodeDefinition = exports.isPortType = exports.formatPortType = exports.isAsyncExecutor = exports.internalNodeTypes = exports.nodeDefinitions = exports.extractWorkflowConfig = exports.generateNodeName = exports.shuffleNodePreview = exports.getPreviewValue = exports.removePreviewForConnection = void 0;
10
+ exports.prepareVideoComposerInput = exports.formatDateTag = exports.outputFieldsToZod = exports.outputFieldToZod = exports.LLMProviders = exports.applyLogicOperator = void 0;
11
11
  // =============================================================================
12
12
  // Client Exports
13
13
  // =============================================================================
@@ -37,6 +37,7 @@ Object.defineProperty(exports, "submitImageRenderJob", { enumerable: true, get:
37
37
  Object.defineProperty(exports, "submitVideoRenderJob", { enumerable: true, get: function () { return render_1.submitVideoRenderJob; } });
38
38
  Object.defineProperty(exports, "getRenderJobStatus", { enumerable: true, get: function () { return render_1.getRenderJobStatus; } });
39
39
  Object.defineProperty(exports, "submitDeduplicationJob", { enumerable: true, get: function () { return render_1.submitDeduplicationJob; } });
40
+ Object.defineProperty(exports, "submitSceneSplitJob", { enumerable: true, get: function () { return render_1.submitSceneSplitJob; } });
40
41
  Object.defineProperty(exports, "submitScreenshotAnimationRenderJob", { enumerable: true, get: function () { return render_1.submitScreenshotAnimationRenderJob; } });
41
42
  Object.defineProperty(exports, "submitAutoCaptionRenderJob", { enumerable: true, get: function () { return render_1.submitAutoCaptionRenderJob; } });
42
43
  Object.defineProperty(exports, "submitInstagramDmRenderJob", { enumerable: true, get: function () { return render_1.submitInstagramDmRenderJob; } });
package/dist/posts.d.ts CHANGED
@@ -40,6 +40,7 @@ export interface CreateSlideshowParams {
40
40
  postTime?: string;
41
41
  imageUrls: string[];
42
42
  strict?: boolean;
43
+ mustPostBy?: string;
43
44
  tag?: string;
44
45
  user_group?: string;
45
46
  org_group?: string;
@@ -59,6 +60,7 @@ export interface CreateVideoParams {
59
60
  postTime?: string;
60
61
  videoUrl: string;
61
62
  strict?: boolean;
63
+ mustPostBy?: string;
62
64
  tag?: string;
63
65
  user_group?: string;
64
66
  org_group?: string;
package/dist/render.d.ts CHANGED
@@ -19,6 +19,14 @@ export interface RenderJobStatus {
19
19
  progress?: number;
20
20
  message?: string;
21
21
  download_url?: string;
22
+ /** Multiple download URLs for multi-file jobs (e.g., scene-split) */
23
+ download_urls?: string[];
24
+ /** Scene metadata for scene-split jobs */
25
+ scene_metadata?: Array<{
26
+ start_sec: number;
27
+ end_sec: number;
28
+ duration_sec: number;
29
+ }>;
22
30
  error?: string;
23
31
  render_time_ms?: number;
24
32
  size_bytes?: number;
@@ -60,6 +68,22 @@ export interface SubmitDeduplicationJobParams {
60
68
  /** Deduplication config - preset level ('level1'-'level5') or custom config */
61
69
  deduplication: DeduplicationInput;
62
70
  }
71
+ export interface SceneSplitDetectorConfig {
72
+ /** Detector algorithm: 'content' for hard cuts, 'adaptive' for varying content */
73
+ detector_type: 'content' | 'adaptive';
74
+ /** Detection threshold (default: 27.0 for content, 3.0 for adaptive) */
75
+ threshold: number;
76
+ /** Minimum scene length in seconds (default: 2.0) */
77
+ min_scene_length_sec: number;
78
+ /** Enable fade-in/fade-out detection as secondary pass */
79
+ fade_detection: boolean;
80
+ }
81
+ export interface SubmitSceneSplitJobParams {
82
+ /** URL of the video to split into scenes */
83
+ video_url: string;
84
+ /** Scene detection configuration */
85
+ scene_split_config: SceneSplitDetectorConfig;
86
+ }
63
87
  export interface SubmitScreenshotAnimationRenderJobParams {
64
88
  /** URL of the image being "screenshotted" */
65
89
  imageUrl: string;
@@ -155,6 +179,11 @@ export declare function getRenderJobStatus(jobId: string): Promise<ApiResponse<R
155
179
  * Applies hash-breaking, metadata injection, and trace removal to a video.
156
180
  */
157
181
  export declare function submitDeduplicationJob(params: SubmitDeduplicationJobParams): Promise<ApiResponse<RenderJobResponse>>;
182
+ /**
183
+ * Submit a scene split job to the Modal renderer.
184
+ * Detects scene boundaries and splits a video into individual clips.
185
+ */
186
+ export declare function submitSceneSplitJob(params: SubmitSceneSplitJobParams): Promise<ApiResponse<RenderJobResponse>>;
158
187
  /**
159
188
  * Submit a screenshot animation render job to the Modal renderer.
160
189
  * Renders an iPhone screenshot animation video from a source image.
package/dist/render.js CHANGED
@@ -8,6 +8,7 @@ exports.submitImageRenderJob = submitImageRenderJob;
8
8
  exports.submitVideoRenderJob = submitVideoRenderJob;
9
9
  exports.getRenderJobStatus = getRenderJobStatus;
10
10
  exports.submitDeduplicationJob = submitDeduplicationJob;
11
+ exports.submitSceneSplitJob = submitSceneSplitJob;
11
12
  exports.submitScreenshotAnimationRenderJob = submitScreenshotAnimationRenderJob;
12
13
  exports.submitAutoCaptionRenderJob = submitAutoCaptionRenderJob;
13
14
  exports.submitInstagramDmRenderJob = submitInstagramDmRenderJob;
@@ -234,9 +235,9 @@ async function getRenderJobStatus(jobId) {
234
235
  if (data.status === 'error' || !response.ok) {
235
236
  return { ok: false, code: response.status, message: data.error ?? data.message ?? 'Failed to get job status' };
236
237
  }
237
- // If completed but no download_url, something went wrong — don't silently construct a broken fallback URL
238
- if (data.status === 'completed' && !data.download_url) {
239
- return { ok: false, code: 500, message: `CRITICAL: Render job ${jobId} completed but has no download_url. This means the Vercel Blob upload failed silently.` };
238
+ // If completed but no download_url(s), something went wrong — don't silently construct a broken fallback URL
239
+ if (data.status === 'completed' && !data.download_url && !data.download_urls?.length) {
240
+ return { ok: false, code: 500, message: `CRITICAL: Render job ${jobId} completed but has no download_url or download_urls. This means the Vercel Blob upload failed silently.` };
240
241
  }
241
242
  return { ok: true, code: 200, message: "Job status retrieved", data };
242
243
  }
@@ -278,6 +279,39 @@ async function submitDeduplicationJob(params) {
278
279
  return { ok: false, code: 500, message: `Failed to submit deduplication job: ${errorMessage}` };
279
280
  }
280
281
  }
282
+ /**
283
+ * Submit a scene split job to the Modal renderer.
284
+ * Detects scene boundaries and splits a video into individual clips.
285
+ */
286
+ async function submitSceneSplitJob(params) {
287
+ try {
288
+ const response = await modalFetch(RENDER_SUBMIT_URL, {
289
+ method: 'POST',
290
+ headers: { 'Content-Type': 'application/json' },
291
+ body: JSON.stringify({
292
+ video_url: params.video_url,
293
+ scene_split_config: params.scene_split_config,
294
+ output_type: 'video',
295
+ })
296
+ });
297
+ const text = await response.text();
298
+ let data;
299
+ try {
300
+ data = JSON.parse(text);
301
+ }
302
+ catch {
303
+ return { ok: false, code: response.status || 500, message: `Modal endpoint error: ${text.substring(0, 100)}` };
304
+ }
305
+ if (data.status === 'error' || !response.ok) {
306
+ return { ok: false, code: response.status, message: data.error ?? data.message ?? 'Failed to submit scene split job' };
307
+ }
308
+ return { ok: true, code: 200, message: "Scene split job submitted", data };
309
+ }
310
+ catch (error) {
311
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
312
+ return { ok: false, code: 500, message: `Failed to submit scene split job: ${errorMessage}` };
313
+ }
314
+ }
281
315
  /**
282
316
  * Submit a screenshot animation render job to the Modal renderer.
283
317
  * Renders an iPhone screenshot animation video from a source image.
@@ -41,7 +41,7 @@ exports.accountTools = [
41
41
  description: zod_1.z.string().optional().describe('Account description/niche'),
42
42
  warmupVersion: zod_1.z.enum(['original', 'v1_smart', 'v2_smart']).optional().describe('Warmup algorithm version'),
43
43
  postVersion: zod_1.z.enum(['original', 'v1_custom']).optional().describe('Post algorithm version'),
44
- phoneType: zod_1.z.enum(['physical_iphone', 'physical_android', 'emulated_android', 'social_api', 'tracking']).optional().describe('Phone type'),
44
+ phoneType: zod_1.z.enum(['physical_iphone', 'manual_iphone', 'physical_android', 'emulated_android', 'social_api', 'tracking']).optional().describe('Phone type'),
45
45
  approved: zod_1.z.boolean().optional().describe('Whether the account follows best practices'),
46
46
  })).describe('Array of account updates'),
47
47
  }),
@@ -26,6 +26,7 @@ exports.postTools = [
26
26
  socialAudioId: zod_1.z.string().optional().describe('Social audio ID to use'),
27
27
  postTime: zod_1.z.string().optional().describe('Scheduled time (ISO 8601). Omit for next available slot.'),
28
28
  strict: zod_1.z.boolean().optional().describe('If true with auto-selection, must post at exact time or error'),
29
+ mustPostBy: zod_1.z.string().optional().describe('Latest allowed scheduled time (ISO 8601). Errors if no slot is available before this deadline.'),
29
30
  tag: zod_1.z.string().optional().describe('Filter accounts by tag (for auto-selection)'),
30
31
  user_group: zod_1.z.string().optional().describe('Filter accounts by user group (for auto-selection)'),
31
32
  org_group: zod_1.z.string().optional().describe('Filter accounts by org group (for auto-selection)'),
@@ -45,6 +46,7 @@ exports.postTools = [
45
46
  socialAudioId: zod_1.z.string().optional().describe('Social audio ID to use'),
46
47
  postTime: zod_1.z.string().optional().describe('Scheduled time (ISO 8601)'),
47
48
  strict: zod_1.z.boolean().optional().describe('If true with auto-selection, must post at exact time or error'),
49
+ mustPostBy: zod_1.z.string().optional().describe('Latest allowed scheduled time (ISO 8601). Errors if no slot is available before this deadline.'),
48
50
  tag: zod_1.z.string().optional().describe('Filter accounts by tag (for auto-selection)'),
49
51
  user_group: zod_1.z.string().optional().describe('Filter accounts by user group (for auto-selection)'),
50
52
  org_group: zod_1.z.string().optional().describe('Filter accounts by org group (for auto-selection)'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugcinc",
3
- "version": "4.5.78",
3
+ "version": "4.5.81",
4
4
  "description": "TypeScript/JavaScript client for the UGC Inc API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",