@umituz/web-ai 1.0.3 → 1.0.4
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/dist/{AIErrors-B2ogd1PB.d.ts → AIErrors-CLjXRty-.d.ts} +99 -92
- package/dist/{AIErrors-C5EasV_c.d.cts → AIErrors-DjZXUiLT.d.cts} +99 -92
- package/dist/PromptBuilder-B5Lm1znm.d.ts +215 -0
- package/dist/PromptBuilder-DIUZlfV6.d.cts +215 -0
- package/dist/{cancellation-error-DwHrDKBz.d.cts → cancellation-error-Cj7fJyCg.d.cts} +3 -3
- package/dist/{cancellation-error-CKcZRhFg.d.ts → cancellation-error-CkMn5Kft.d.ts} +3 -3
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +3 -3
- package/dist/chat/index.d.ts +3 -3
- package/dist/chat/index.js.map +1 -1
- package/dist/{chat.service-CL1qtYxe.d.cts → chat.service-9M-KpLo-.d.cts} +1 -1
- package/dist/{chat.service-q05GnhEm.d.ts → chat.service-B4FLFxR1.d.ts} +1 -1
- package/dist/content/index.cjs +759 -400
- package/dist/content/index.cjs.map +1 -1
- package/dist/content/index.d.cts +165 -219
- package/dist/content/index.d.ts +165 -219
- package/dist/content/index.js +702 -401
- package/dist/content/index.js.map +1 -1
- package/dist/{create-ai-9PW752z8.d.ts → create-ai-0eZFFqTw.d.ts} +1 -1
- package/dist/{create-ai-CXYKPK6G.d.cts → create-ai-BrKR_5fQ.d.cts} +1 -1
- package/dist/hooks/index.cjs +2 -0
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +9 -9
- package/dist/hooks/index.d.ts +9 -9
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index-BUVULo3h.d.ts +177 -0
- package/dist/index-BulSkB2L.d.cts +177 -0
- package/dist/index.cjs +1727 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +1690 -15
- package/dist/index.js.map +1 -1
- package/dist/{provider.factory-DfDfk0dK.d.ts → provider.factory-BwPnqSEU.d.ts} +3 -1
- package/dist/{provider.factory-BxsfK4WW.d.cts → provider.factory-DyfJtR8M.d.cts} +3 -1
- package/dist/providers/index.cjs +9 -0
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +10 -8
- package/dist/providers/index.d.ts +10 -8
- package/dist/providers/index.js +7 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/wizard/index.d.cts +2 -86
- package/dist/wizard/index.d.ts +2 -86
- package/package.json +16 -1
- package/dist/ContentGeneration-B6iK2B33.d.cts +0 -93
- package/dist/ContentGeneration-B6iK2B33.d.ts +0 -93
package/dist/index.cjs
CHANGED
|
@@ -1084,6 +1084,26 @@ function isMediaProvider(provider) {
|
|
|
1084
1084
|
return provider.capabilities.includes("image") || provider.capabilities.includes("video");
|
|
1085
1085
|
}
|
|
1086
1086
|
|
|
1087
|
+
// src/content/domain/errors/AIErrors.ts
|
|
1088
|
+
var ValidationError = class extends AIError {
|
|
1089
|
+
constructor(message) {
|
|
1090
|
+
super(message, "VALIDATION_ERROR");
|
|
1091
|
+
this.name = "ValidationError";
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
var ProviderUnavailableError = class extends AIError {
|
|
1095
|
+
constructor(providerId) {
|
|
1096
|
+
super(`Provider ${providerId} is not available`, "PROVIDER_UNAVAILABLE");
|
|
1097
|
+
this.name = "ProviderUnavailableError";
|
|
1098
|
+
}
|
|
1099
|
+
};
|
|
1100
|
+
var ProviderQuotaExhaustedError = class extends AIError {
|
|
1101
|
+
constructor(providerId) {
|
|
1102
|
+
super(`Provider ${providerId} quota exhausted`, "PROVIDER_QUOTA_EXHAUSTED");
|
|
1103
|
+
this.name = "ProviderQuotaExhaustedError";
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1087
1107
|
// src/content/domain/limits/ProviderTimingConfig.ts
|
|
1088
1108
|
var ProviderTimingConfig = {
|
|
1089
1109
|
DEFAULT_TIMEOUT_MS: 3e4,
|
|
@@ -1426,6 +1446,9 @@ var ProviderFactory = class {
|
|
|
1426
1446
|
);
|
|
1427
1447
|
}
|
|
1428
1448
|
};
|
|
1449
|
+
function createProviderFactory(config) {
|
|
1450
|
+
return new ProviderFactory(config);
|
|
1451
|
+
}
|
|
1429
1452
|
|
|
1430
1453
|
// src/providers/anthropic/anthropic.constants.ts
|
|
1431
1454
|
var ANTHROPIC_MODELS = {
|
|
@@ -2455,6 +2478,9 @@ function toGroqMessages(messages, systemPrompt) {
|
|
|
2455
2478
|
}
|
|
2456
2479
|
return wire;
|
|
2457
2480
|
}
|
|
2481
|
+
function createGroqProvider(config) {
|
|
2482
|
+
return new GroqProvider(config);
|
|
2483
|
+
}
|
|
2458
2484
|
function findLastIndex2(items, predicate) {
|
|
2459
2485
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
2460
2486
|
if (predicate(items[i])) return i;
|
|
@@ -2721,6 +2747,128 @@ function createGeminiProvider(config) {
|
|
|
2721
2747
|
return new GeminiProvider(config);
|
|
2722
2748
|
}
|
|
2723
2749
|
|
|
2750
|
+
// src/content/domain/predicates/KeywordProminenceClassifier.ts
|
|
2751
|
+
var HIGH_DENSITY_THRESHOLD = 2;
|
|
2752
|
+
var MEDIUM_DENSITY_THRESHOLD = 1;
|
|
2753
|
+
function classifyKeywordProminence(densityPercent) {
|
|
2754
|
+
if (densityPercent > HIGH_DENSITY_THRESHOLD) return "high";
|
|
2755
|
+
if (densityPercent > MEDIUM_DENSITY_THRESHOLD) return "medium";
|
|
2756
|
+
return "low";
|
|
2757
|
+
}
|
|
2758
|
+
function isUnderutilizedKeyword(densityPercent) {
|
|
2759
|
+
return densityPercent < 1;
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
// src/content/domain/types/index.ts
|
|
2763
|
+
var PLATFORM_SPECS = {
|
|
2764
|
+
twitter: {
|
|
2765
|
+
maxLength: 280,
|
|
2766
|
+
style: "concise, engaging, thread-friendly",
|
|
2767
|
+
emojiSupport: true,
|
|
2768
|
+
hashtagSupport: true,
|
|
2769
|
+
imageSupport: true,
|
|
2770
|
+
videoSupport: true,
|
|
2771
|
+
maxHashtags: 5
|
|
2772
|
+
},
|
|
2773
|
+
linkedin: {
|
|
2774
|
+
maxLength: 3e3,
|
|
2775
|
+
style: "professional, insightful, industry-focused",
|
|
2776
|
+
emojiSupport: true,
|
|
2777
|
+
hashtagSupport: true,
|
|
2778
|
+
imageSupport: true,
|
|
2779
|
+
videoSupport: true,
|
|
2780
|
+
maxHashtags: 5
|
|
2781
|
+
},
|
|
2782
|
+
instagram: {
|
|
2783
|
+
maxLength: 2200,
|
|
2784
|
+
style: "visual, engaging, emoji-rich",
|
|
2785
|
+
emojiSupport: true,
|
|
2786
|
+
hashtagSupport: true,
|
|
2787
|
+
imageSupport: true,
|
|
2788
|
+
videoSupport: true,
|
|
2789
|
+
maxHashtags: 30
|
|
2790
|
+
},
|
|
2791
|
+
threads: {
|
|
2792
|
+
maxLength: 500,
|
|
2793
|
+
style: "conversational, community-driven",
|
|
2794
|
+
emojiSupport: true,
|
|
2795
|
+
hashtagSupport: true,
|
|
2796
|
+
imageSupport: true,
|
|
2797
|
+
videoSupport: true,
|
|
2798
|
+
maxHashtags: 5
|
|
2799
|
+
},
|
|
2800
|
+
tiktok: {
|
|
2801
|
+
maxLength: 150,
|
|
2802
|
+
style: "catchy, trending, short-form",
|
|
2803
|
+
emojiSupport: true,
|
|
2804
|
+
hashtagSupport: true,
|
|
2805
|
+
imageSupport: false,
|
|
2806
|
+
videoSupport: true,
|
|
2807
|
+
maxHashtags: 5
|
|
2808
|
+
},
|
|
2809
|
+
facebook: {
|
|
2810
|
+
maxLength: 63206,
|
|
2811
|
+
style: "conversational, engaging, shareable",
|
|
2812
|
+
emojiSupport: true,
|
|
2813
|
+
hashtagSupport: true,
|
|
2814
|
+
imageSupport: true,
|
|
2815
|
+
videoSupport: true,
|
|
2816
|
+
maxHashtags: 5
|
|
2817
|
+
}
|
|
2818
|
+
};
|
|
2819
|
+
|
|
2820
|
+
// src/content/domain/predicates/HashtagPriorityRanker.ts
|
|
2821
|
+
var DEFAULT_HASHTAG_BUDGET = Number.MAX_SAFE_INTEGER;
|
|
2822
|
+
function resolveHashtagBudget(platform) {
|
|
2823
|
+
return PLATFORM_SPECS[platform]?.maxHashtags ?? DEFAULT_HASHTAG_BUDGET;
|
|
2824
|
+
}
|
|
2825
|
+
function rankAndTrimHashtags(hashtags, budget) {
|
|
2826
|
+
if (hashtags.length <= budget) return [...hashtags];
|
|
2827
|
+
return [...hashtags].sort((a, b) => b.length - a.length).slice(0, budget);
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
// src/content/domain/predicates/QualityRecommenderByRatio.ts
|
|
2831
|
+
var WIDE_RATIOS = /* @__PURE__ */ new Set(["16:9", "4:3"]);
|
|
2832
|
+
function recommendQualityForAspectRatio(ratio) {
|
|
2833
|
+
return WIDE_RATIOS.has(ratio) ? "hd" : "standard";
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
// src/content/domain/predicates/PlatformSpecResolver.ts
|
|
2837
|
+
var FALLBACK_SPEC = {
|
|
2838
|
+
maxLength: 280,
|
|
2839
|
+
style: "concise, engaging, audience-friendly",
|
|
2840
|
+
emojiSupport: true,
|
|
2841
|
+
hashtagSupport: true,
|
|
2842
|
+
imageSupport: true,
|
|
2843
|
+
videoSupport: true,
|
|
2844
|
+
maxHashtags: 5
|
|
2845
|
+
};
|
|
2846
|
+
function resolvePlatformSpec(platform) {
|
|
2847
|
+
return PLATFORM_SPECS[platform] ?? FALLBACK_SPEC;
|
|
2848
|
+
}
|
|
2849
|
+
function resolveMaxContentLength(platform, override) {
|
|
2850
|
+
return override ?? resolvePlatformSpec(platform).maxLength;
|
|
2851
|
+
}
|
|
2852
|
+
|
|
2853
|
+
// src/content/domain/predicates/ScoreRangeGuard.ts
|
|
2854
|
+
var SCORE_MIN = 0;
|
|
2855
|
+
var SCORE_MAX = 100;
|
|
2856
|
+
var SCORE_FALLBACK = 50;
|
|
2857
|
+
var CONFIDENCE_MIN = 0;
|
|
2858
|
+
var CONFIDENCE_MAX = 1;
|
|
2859
|
+
var CONFIDENCE_FALLBACK = 0.5;
|
|
2860
|
+
function clampScoreToValidRange(score, fallback = SCORE_FALLBACK) {
|
|
2861
|
+
if (!Number.isFinite(score)) return fallback;
|
|
2862
|
+
return Math.max(SCORE_MIN, Math.min(SCORE_MAX, score));
|
|
2863
|
+
}
|
|
2864
|
+
function clampConfidenceToValidRange(confidence, fallback = CONFIDENCE_FALLBACK) {
|
|
2865
|
+
if (!Number.isFinite(confidence)) return fallback;
|
|
2866
|
+
return Math.max(CONFIDENCE_MIN, Math.min(CONFIDENCE_MAX, confidence));
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2869
|
+
// src/content/domain/predicates/AbTestConfidence.ts
|
|
2870
|
+
var AB_TEST_DEFAULT_CONFIDENCE = 0.7;
|
|
2871
|
+
|
|
2724
2872
|
// src/content/domain/predicates/FalImageRenderingOptions.ts
|
|
2725
2873
|
var FAL_FORMAT_TO_IMAGE_SIZE = {
|
|
2726
2874
|
square: "square_hd",
|
|
@@ -2991,7 +3139,7 @@ var TimeoutError = class extends Error {
|
|
|
2991
3139
|
};
|
|
2992
3140
|
|
|
2993
3141
|
// src/providers/pruna/client/core/errors/validation-error.ts
|
|
2994
|
-
var
|
|
3142
|
+
var ValidationError2 = class extends Error {
|
|
2995
3143
|
field;
|
|
2996
3144
|
reason;
|
|
2997
3145
|
receivedValue;
|
|
@@ -3276,21 +3424,21 @@ function deriveGenerationCacheKey(apiKey, input) {
|
|
|
3276
3424
|
// src/providers/pruna/client/core/validation/api-key-validator.ts
|
|
3277
3425
|
function assertValidApiKey(apiKey) {
|
|
3278
3426
|
if (typeof apiKey !== "string") {
|
|
3279
|
-
throw new
|
|
3427
|
+
throw new ValidationError2({
|
|
3280
3428
|
field: "apiKey",
|
|
3281
3429
|
reason: "must be a string",
|
|
3282
3430
|
receivedValue: typeof apiKey
|
|
3283
3431
|
});
|
|
3284
3432
|
}
|
|
3285
3433
|
if (apiKey.length < MIN_API_KEY_LENGTH) {
|
|
3286
|
-
throw new
|
|
3434
|
+
throw new ValidationError2({
|
|
3287
3435
|
field: "apiKey",
|
|
3288
3436
|
reason: "must not be empty",
|
|
3289
3437
|
receivedValue: apiKey
|
|
3290
3438
|
});
|
|
3291
3439
|
}
|
|
3292
3440
|
if (apiKey.length > MAX_API_KEY_LENGTH) {
|
|
3293
|
-
throw new
|
|
3441
|
+
throw new ValidationError2({
|
|
3294
3442
|
field: "apiKey",
|
|
3295
3443
|
reason: `exceeds maximum length of ${MAX_API_KEY_LENGTH}`,
|
|
3296
3444
|
receivedValue: apiKey.length
|
|
@@ -3307,7 +3455,7 @@ function classifyImageSource(source) {
|
|
|
3307
3455
|
}
|
|
3308
3456
|
function assertSecureImageSource(image, fieldName = "image") {
|
|
3309
3457
|
if (typeof image !== "string") {
|
|
3310
|
-
throw new
|
|
3458
|
+
throw new ValidationError2({
|
|
3311
3459
|
field: fieldName,
|
|
3312
3460
|
reason: "must be a string",
|
|
3313
3461
|
receivedValue: typeof image
|
|
@@ -3315,14 +3463,14 @@ function assertSecureImageSource(image, fieldName = "image") {
|
|
|
3315
3463
|
}
|
|
3316
3464
|
const kind = classifyImageSource(image);
|
|
3317
3465
|
if (kind === "http-url") {
|
|
3318
|
-
throw new
|
|
3466
|
+
throw new ValidationError2({
|
|
3319
3467
|
field: fieldName,
|
|
3320
3468
|
reason: "HTTP URLs are not supported; use HTTPS or a base64 data URI",
|
|
3321
3469
|
receivedValue: image
|
|
3322
3470
|
});
|
|
3323
3471
|
}
|
|
3324
3472
|
if (kind === "unknown") {
|
|
3325
|
-
throw new
|
|
3473
|
+
throw new ValidationError2({
|
|
3326
3474
|
field: fieldName,
|
|
3327
3475
|
reason: "must be an HTTPS URL or a base64 data URI",
|
|
3328
3476
|
receivedValue: typeof image
|
|
@@ -3346,7 +3494,7 @@ function isSupportedAspectRatio(value) {
|
|
|
3346
3494
|
function assertValidAspectRatio(value, fieldName = "aspect_ratio") {
|
|
3347
3495
|
if (value === void 0 || value === null) return;
|
|
3348
3496
|
if (!isSupportedAspectRatio(value)) {
|
|
3349
|
-
throw new
|
|
3497
|
+
throw new ValidationError2({
|
|
3350
3498
|
field: fieldName,
|
|
3351
3499
|
reason: `must be one of ${SUPPORTED_ASPECT_RATIOS.join(", ")}`,
|
|
3352
3500
|
receivedValue: value
|
|
@@ -3362,7 +3510,7 @@ function isSupportedResolution(value) {
|
|
|
3362
3510
|
function assertValidResolution(value, fieldName = "resolution") {
|
|
3363
3511
|
if (value === void 0 || value === null) return;
|
|
3364
3512
|
if (!isSupportedResolution(value)) {
|
|
3365
|
-
throw new
|
|
3513
|
+
throw new ValidationError2({
|
|
3366
3514
|
field: fieldName,
|
|
3367
3515
|
reason: `must be one of ${SUPPORTED_RESOLUTIONS.join(", ")}`,
|
|
3368
3516
|
receivedValue: value
|
|
@@ -3379,7 +3527,7 @@ function isValidDuration(value) {
|
|
|
3379
3527
|
function assertValidDuration(value, fieldName = "duration") {
|
|
3380
3528
|
if (value === void 0 || value === null) return;
|
|
3381
3529
|
if (!isValidDuration(value)) {
|
|
3382
|
-
throw new
|
|
3530
|
+
throw new ValidationError2({
|
|
3383
3531
|
field: fieldName,
|
|
3384
3532
|
reason: `must be an integer between ${MIN_VIDEO_DURATION_SECONDS} and ${MAX_VIDEO_DURATION_SECONDS} seconds`,
|
|
3385
3533
|
receivedValue: value
|
|
@@ -3392,21 +3540,21 @@ var MIN_PROMPT_LENGTH = 1;
|
|
|
3392
3540
|
var MAX_PROMPT_LENGTH = 4e3;
|
|
3393
3541
|
function assertValidPrompt(value, fieldName = "prompt") {
|
|
3394
3542
|
if (typeof value !== "string") {
|
|
3395
|
-
throw new
|
|
3543
|
+
throw new ValidationError2({
|
|
3396
3544
|
field: fieldName,
|
|
3397
3545
|
reason: "must be a string",
|
|
3398
3546
|
receivedValue: typeof value
|
|
3399
3547
|
});
|
|
3400
3548
|
}
|
|
3401
3549
|
if (value.trim().length < MIN_PROMPT_LENGTH) {
|
|
3402
|
-
throw new
|
|
3550
|
+
throw new ValidationError2({
|
|
3403
3551
|
field: fieldName,
|
|
3404
3552
|
reason: "must not be empty or whitespace-only",
|
|
3405
3553
|
receivedValue: value
|
|
3406
3554
|
});
|
|
3407
3555
|
}
|
|
3408
3556
|
if (value.length > MAX_PROMPT_LENGTH) {
|
|
3409
|
-
throw new
|
|
3557
|
+
throw new ValidationError2({
|
|
3410
3558
|
field: fieldName,
|
|
3411
3559
|
reason: `exceeds maximum length of ${MAX_PROMPT_LENGTH} characters`,
|
|
3412
3560
|
receivedValue: value.length
|
|
@@ -3423,7 +3571,7 @@ function isValidSeed(value) {
|
|
|
3423
3571
|
function assertValidSeed(value, fieldName = "seed") {
|
|
3424
3572
|
if (value === void 0 || value === null) return;
|
|
3425
3573
|
if (!isValidSeed(value)) {
|
|
3426
|
-
throw new
|
|
3574
|
+
throw new ValidationError2({
|
|
3427
3575
|
field: fieldName,
|
|
3428
3576
|
reason: `must be an integer in [${MIN_SEED}, ${MAX_SEED}]`,
|
|
3429
3577
|
receivedValue: value
|
|
@@ -4357,6 +4505,1535 @@ function resetProvider() {
|
|
|
4357
4505
|
container = null;
|
|
4358
4506
|
}
|
|
4359
4507
|
|
|
4508
|
+
// src/content/domain/calculations/ContentCreditCost.ts
|
|
4509
|
+
var CREDIT_COSTS = {
|
|
4510
|
+
"text-to-image": { standard: 1, hd: 2, "4k": 4 },
|
|
4511
|
+
"image-to-image": { standard: 1, hd: 2, "4k": 4 },
|
|
4512
|
+
"image-to-video": { standard: 3, hd: 5, "4k": 8 },
|
|
4513
|
+
"text-to-video": { standard: 5, hd: 8, "4k": 12 }
|
|
4514
|
+
};
|
|
4515
|
+
var DEFAULT_CREDIT_COST = 0;
|
|
4516
|
+
function toQualityTier(quality) {
|
|
4517
|
+
if (quality === "4k") return "4k";
|
|
4518
|
+
if (quality === "hd" || quality === "1080p") return "hd";
|
|
4519
|
+
return "standard";
|
|
4520
|
+
}
|
|
4521
|
+
function calculateContentCreditCost(type, quality = "standard") {
|
|
4522
|
+
const tierCosts = CREDIT_COSTS[type];
|
|
4523
|
+
if (!tierCosts) return DEFAULT_CREDIT_COST;
|
|
4524
|
+
return tierCosts[toQualityTier(quality)] ?? tierCosts.standard;
|
|
4525
|
+
}
|
|
4526
|
+
|
|
4527
|
+
// src/content/domain/limits/ImageFormatOptions.ts
|
|
4528
|
+
var ASPECT_RATIO_OPTIONS = [
|
|
4529
|
+
{ value: "1:1", label: "Square", width: 1024, height: 1024 },
|
|
4530
|
+
{ value: "16:9", label: "Landscape", width: 1920, height: 1080 },
|
|
4531
|
+
{ value: "9:16", label: "Portrait", width: 1080, height: 1920 },
|
|
4532
|
+
{ value: "4:3", label: "Standard", width: 1440, height: 1080 },
|
|
4533
|
+
{ value: "3:4", label: "Tall", width: 1080, height: 1440 }
|
|
4534
|
+
];
|
|
4535
|
+
var IMAGE_QUALITY_OPTIONS = [
|
|
4536
|
+
{ value: "standard", label: "Standard", description: "1024x1024, good quality", resolution: "1024x1024" },
|
|
4537
|
+
{ value: "hd", label: "HD", description: "1920x1080, high quality", resolution: "1920x1080" },
|
|
4538
|
+
{ value: "4k", label: "4K", description: "3840x2160, ultra quality", resolution: "3840x2160" }
|
|
4539
|
+
];
|
|
4540
|
+
var VIDEO_QUALITY_OPTIONS = [
|
|
4541
|
+
{ value: "720p", label: "720p HD", resolution: "1280x720" },
|
|
4542
|
+
{ value: "1080p", label: "1080p Full HD", resolution: "1920x1080" },
|
|
4543
|
+
{ value: "4k", label: "4K Ultra HD", resolution: "3840x2160" }
|
|
4544
|
+
];
|
|
4545
|
+
var VIDEO_DURATION_OPTIONS_SECONDS = [2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
4546
|
+
var MOTION_OPTIONS = [
|
|
4547
|
+
{ value: "slow", label: "Slow", description: "Gentle movement" },
|
|
4548
|
+
{ value: "medium", label: "Medium", description: "Balanced motion" },
|
|
4549
|
+
{ value: "fast", label: "Fast", description: "Dynamic movement" }
|
|
4550
|
+
];
|
|
4551
|
+
var STYLE_PRESETS = [
|
|
4552
|
+
{ value: "realistic", label: "Realistic", promptFragment: "realistic, photograph, detailed" },
|
|
4553
|
+
{ value: "artistic", label: "Artistic", promptFragment: "artistic, painting, creative" },
|
|
4554
|
+
{ value: "anime", label: "Anime", promptFragment: "anime style, manga, vibrant colors" },
|
|
4555
|
+
{ value: "cinematic", label: "Cinematic", promptFragment: "cinematic, movie scene, dramatic lighting" },
|
|
4556
|
+
{ value: "vintage", label: "Vintage", promptFragment: "vintage, retro, film grain" },
|
|
4557
|
+
{ value: "fantasy", label: "Fantasy", promptFragment: "fantasy, magical, ethereal" },
|
|
4558
|
+
{ value: "minimalist", label: "Minimalist", promptFragment: "minimalist, clean, simple" },
|
|
4559
|
+
{ value: "abstract", label: "Abstract", promptFragment: "abstract, geometric, artistic" }
|
|
4560
|
+
];
|
|
4561
|
+
|
|
4562
|
+
// src/content/domain/calculations/AspectRatioDimensions.ts
|
|
4563
|
+
var FALLBACK_DIMENSIONS = { width: 1024, height: 1024 };
|
|
4564
|
+
function resolveDimensionsForAspectRatio(ratio) {
|
|
4565
|
+
const match = ASPECT_RATIO_OPTIONS.find((option) => option.value === ratio);
|
|
4566
|
+
return match ? { width: match.width, height: match.height } : FALLBACK_DIMENSIONS;
|
|
4567
|
+
}
|
|
4568
|
+
|
|
4569
|
+
// src/content/domain/constants/GenerationConstants.ts
|
|
4570
|
+
var ASPECT_RATIO_VALUES = ASPECT_RATIO_OPTIONS.map((o) => o.value);
|
|
4571
|
+
var IMAGE_QUALITY_VALUES = IMAGE_QUALITY_OPTIONS.map((o) => o.value);
|
|
4572
|
+
var VIDEO_QUALITY_VALUES = VIDEO_QUALITY_OPTIONS.map((o) => o.value);
|
|
4573
|
+
var VIDEO_DURATION_OPTIONS = VIDEO_DURATION_OPTIONS_SECONDS;
|
|
4574
|
+
var getDimensionsForAspectRatio = resolveDimensionsForAspectRatio;
|
|
4575
|
+
var getRecommendedQuality = recommendQualityForAspectRatio;
|
|
4576
|
+
|
|
4577
|
+
// src/content/domain/limits/ValidationLimits.ts
|
|
4578
|
+
var ValidationLimits = {
|
|
4579
|
+
TOPIC: {
|
|
4580
|
+
MIN: 1,
|
|
4581
|
+
MAX: 500
|
|
4582
|
+
},
|
|
4583
|
+
CONTENT: {
|
|
4584
|
+
MIN: 1,
|
|
4585
|
+
MAX: 1e4
|
|
4586
|
+
},
|
|
4587
|
+
KEYWORD: {
|
|
4588
|
+
MAX_COUNT: 20,
|
|
4589
|
+
MAX_LENGTH: 50
|
|
4590
|
+
},
|
|
4591
|
+
DURATION_SECONDS: {
|
|
4592
|
+
MIN: 10,
|
|
4593
|
+
MAX: 600
|
|
4594
|
+
},
|
|
4595
|
+
CALENDAR_DAYS: {
|
|
4596
|
+
MIN: 1,
|
|
4597
|
+
MAX: 90
|
|
4598
|
+
},
|
|
4599
|
+
HASHTAG_COUNT: {
|
|
4600
|
+
MIN: 1,
|
|
4601
|
+
MAX: 50
|
|
4602
|
+
},
|
|
4603
|
+
SEO_CONTENT_PREVIEW: 500,
|
|
4604
|
+
BLOG_PROMPT_PREVIEW: 1e3,
|
|
4605
|
+
AB_VARIANT_CONTENT_PREVIEW: 200
|
|
4606
|
+
};
|
|
4607
|
+
|
|
4608
|
+
// src/content/domain/limits/SpeechPaceConfig.ts
|
|
4609
|
+
var SpeechPaceConfig = {
|
|
4610
|
+
WORDS_PER_SECOND: 2.5,
|
|
4611
|
+
TOKENS_PER_SECOND: 10,
|
|
4612
|
+
JSON_TOKEN_OVERHEAD: 500,
|
|
4613
|
+
TOKENS_PER_CALENDAR_DAY: 150
|
|
4614
|
+
};
|
|
4615
|
+
|
|
4616
|
+
// src/content/domain/calculations/SpeechPaceEstimate.ts
|
|
4617
|
+
function estimateWordCountForDuration(durationSeconds) {
|
|
4618
|
+
return Math.floor(durationSeconds * SpeechPaceConfig.WORDS_PER_SECOND);
|
|
4619
|
+
}
|
|
4620
|
+
function estimateTokenBudgetForDuration(durationSeconds) {
|
|
4621
|
+
return durationSeconds * SpeechPaceConfig.TOKENS_PER_SECOND + SpeechPaceConfig.JSON_TOKEN_OVERHEAD;
|
|
4622
|
+
}
|
|
4623
|
+
function estimateTokenBudgetForCalendarDays(days) {
|
|
4624
|
+
return days * SpeechPaceConfig.TOKENS_PER_CALENDAR_DAY + SpeechPaceConfig.JSON_TOKEN_OVERHEAD;
|
|
4625
|
+
}
|
|
4626
|
+
|
|
4627
|
+
// src/content/domain/calculations/SeoKeywordDensity.ts
|
|
4628
|
+
function countKeywordOccurrences(content, keyword) {
|
|
4629
|
+
if (!keyword) return 0;
|
|
4630
|
+
const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4631
|
+
const matches = content.match(new RegExp(escaped, "gi"));
|
|
4632
|
+
return matches ? matches.length : 0;
|
|
4633
|
+
}
|
|
4634
|
+
function countWordsInContent(content) {
|
|
4635
|
+
const tokens = content.split(/\s+/).filter(Boolean);
|
|
4636
|
+
return tokens.length || 1;
|
|
4637
|
+
}
|
|
4638
|
+
function calculateKeywordDensity(content, keyword) {
|
|
4639
|
+
const totalWords = countWordsInContent(content);
|
|
4640
|
+
const occurrences = countKeywordOccurrences(content, keyword);
|
|
4641
|
+
return occurrences / totalWords * 100;
|
|
4642
|
+
}
|
|
4643
|
+
|
|
4644
|
+
// src/content/domain/calculations/AbTestImprovementRatio.ts
|
|
4645
|
+
function calculateImprovementPercentage(scoreA, scoreB) {
|
|
4646
|
+
const higher = Math.max(scoreA, scoreB);
|
|
4647
|
+
const lower = Math.min(scoreA, scoreB);
|
|
4648
|
+
if (lower <= 0) {
|
|
4649
|
+
return "100";
|
|
4650
|
+
}
|
|
4651
|
+
const delta = (higher / lower - 1) * 100;
|
|
4652
|
+
return Math.abs(delta).toFixed(0);
|
|
4653
|
+
}
|
|
4654
|
+
function selectHigherScoreVariantId(scoreA, scoreB, idA = "A", idB = "B") {
|
|
4655
|
+
return scoreA > scoreB ? idA : idB;
|
|
4656
|
+
}
|
|
4657
|
+
|
|
4658
|
+
// src/content/domain/calculations/ContentCalendarDateOffset.ts
|
|
4659
|
+
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
4660
|
+
function resolveCalendarEntryDate(dayIndex, baseTimestamp = Date.now()) {
|
|
4661
|
+
return new Date(baseTimestamp + (dayIndex - 1) * ONE_DAY_MS);
|
|
4662
|
+
}
|
|
4663
|
+
|
|
4664
|
+
// src/content/domain/validation/TopicTextValidator.ts
|
|
4665
|
+
function validateTopicText(topic) {
|
|
4666
|
+
if (typeof topic !== "string" || topic.trim().length < ValidationLimits.TOPIC.MIN) {
|
|
4667
|
+
throw new ValidationError("Topic cannot be empty");
|
|
4668
|
+
}
|
|
4669
|
+
const trimmed = topic.trim();
|
|
4670
|
+
if (trimmed.length > ValidationLimits.TOPIC.MAX) {
|
|
4671
|
+
throw new ValidationError(`Topic exceeds maximum length of ${ValidationLimits.TOPIC.MAX} characters`);
|
|
4672
|
+
}
|
|
4673
|
+
return trimmed;
|
|
4674
|
+
}
|
|
4675
|
+
|
|
4676
|
+
// src/content/domain/validation/ContentBodyValidator.ts
|
|
4677
|
+
function validateContentBody(content) {
|
|
4678
|
+
if (typeof content !== "string" || content.trim().length < ValidationLimits.CONTENT.MIN) {
|
|
4679
|
+
throw new ValidationError("Content cannot be empty");
|
|
4680
|
+
}
|
|
4681
|
+
const trimmed = content.trim();
|
|
4682
|
+
if (trimmed.length > ValidationLimits.CONTENT.MAX) {
|
|
4683
|
+
throw new ValidationError(`Content exceeds maximum length of ${ValidationLimits.CONTENT.MAX} characters`);
|
|
4684
|
+
}
|
|
4685
|
+
return trimmed;
|
|
4686
|
+
}
|
|
4687
|
+
function truncateForSeoPreview(content) {
|
|
4688
|
+
return content.substring(0, ValidationLimits.SEO_CONTENT_PREVIEW);
|
|
4689
|
+
}
|
|
4690
|
+
function truncateForBlogPromptPreview(content) {
|
|
4691
|
+
return content.substring(0, ValidationLimits.BLOG_PROMPT_PREVIEW);
|
|
4692
|
+
}
|
|
4693
|
+
function truncateForAbVariantPreview(content) {
|
|
4694
|
+
return content.substring(0, ValidationLimits.AB_VARIANT_CONTENT_PREVIEW);
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
// src/content/domain/validation/KeywordListValidator.ts
|
|
4698
|
+
function validateKeywordList(keywords) {
|
|
4699
|
+
if (!Array.isArray(keywords)) {
|
|
4700
|
+
throw new ValidationError("Keywords must be an array");
|
|
4701
|
+
}
|
|
4702
|
+
if (keywords.length > ValidationLimits.KEYWORD.MAX_COUNT) {
|
|
4703
|
+
throw new ValidationError(`Cannot process more than ${ValidationLimits.KEYWORD.MAX_COUNT} keywords`);
|
|
4704
|
+
}
|
|
4705
|
+
return keywords.filter((k) => typeof k === "string" && k.trim().length > 0).map((keyword) => {
|
|
4706
|
+
const trimmed = keyword.trim();
|
|
4707
|
+
if (trimmed.length > ValidationLimits.KEYWORD.MAX_LENGTH) {
|
|
4708
|
+
const preview = trimmed.substring(0, 20);
|
|
4709
|
+
throw new ValidationError(
|
|
4710
|
+
`Keyword "${preview}..." exceeds maximum length of ${ValidationLimits.KEYWORD.MAX_LENGTH} characters`
|
|
4711
|
+
);
|
|
4712
|
+
}
|
|
4713
|
+
return trimmed;
|
|
4714
|
+
});
|
|
4715
|
+
}
|
|
4716
|
+
|
|
4717
|
+
// src/content/domain/validation/DurationSecondsValidator.ts
|
|
4718
|
+
function validateDurationSeconds(duration) {
|
|
4719
|
+
if (!Number.isFinite(duration)) {
|
|
4720
|
+
throw new ValidationError(
|
|
4721
|
+
`Duration must be between ${ValidationLimits.DURATION_SECONDS.MIN} and ${ValidationLimits.DURATION_SECONDS.MAX} seconds`
|
|
4722
|
+
);
|
|
4723
|
+
}
|
|
4724
|
+
if (duration < ValidationLimits.DURATION_SECONDS.MIN || duration > ValidationLimits.DURATION_SECONDS.MAX) {
|
|
4725
|
+
throw new ValidationError(
|
|
4726
|
+
`Duration must be between ${ValidationLimits.DURATION_SECONDS.MIN} and ${ValidationLimits.DURATION_SECONDS.MAX} seconds`
|
|
4727
|
+
);
|
|
4728
|
+
}
|
|
4729
|
+
return duration;
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
// src/content/domain/validation/CalendarDaysValidator.ts
|
|
4733
|
+
function validateCalendarDays(days) {
|
|
4734
|
+
if (!Number.isFinite(days)) {
|
|
4735
|
+
throw new ValidationError(
|
|
4736
|
+
`Days must be between ${ValidationLimits.CALENDAR_DAYS.MIN} and ${ValidationLimits.CALENDAR_DAYS.MAX}`
|
|
4737
|
+
);
|
|
4738
|
+
}
|
|
4739
|
+
if (days < ValidationLimits.CALENDAR_DAYS.MIN || days > ValidationLimits.CALENDAR_DAYS.MAX) {
|
|
4740
|
+
throw new ValidationError(
|
|
4741
|
+
`Days must be between ${ValidationLimits.CALENDAR_DAYS.MIN} and ${ValidationLimits.CALENDAR_DAYS.MAX}`
|
|
4742
|
+
);
|
|
4743
|
+
}
|
|
4744
|
+
return days;
|
|
4745
|
+
}
|
|
4746
|
+
|
|
4747
|
+
// src/content/domain/validation/HashtagCountValidator.ts
|
|
4748
|
+
function validateHashtagCount(count) {
|
|
4749
|
+
if (!Number.isFinite(count)) {
|
|
4750
|
+
throw new ValidationError(
|
|
4751
|
+
`Hashtag count must be between ${ValidationLimits.HASHTAG_COUNT.MIN} and ${ValidationLimits.HASHTAG_COUNT.MAX}`
|
|
4752
|
+
);
|
|
4753
|
+
}
|
|
4754
|
+
if (count < ValidationLimits.HASHTAG_COUNT.MIN || count > ValidationLimits.HASHTAG_COUNT.MAX) {
|
|
4755
|
+
throw new ValidationError(
|
|
4756
|
+
`Hashtag count must be between ${ValidationLimits.HASHTAG_COUNT.MIN} and ${ValidationLimits.HASHTAG_COUNT.MAX}`
|
|
4757
|
+
);
|
|
4758
|
+
}
|
|
4759
|
+
return Math.floor(count);
|
|
4760
|
+
}
|
|
4761
|
+
|
|
4762
|
+
// src/content/domain/utils/IdGenerator.ts
|
|
4763
|
+
function generateId(prefix) {
|
|
4764
|
+
const id = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`;
|
|
4765
|
+
return prefix ? `${prefix}-${id}` : id;
|
|
4766
|
+
}
|
|
4767
|
+
|
|
4768
|
+
// src/content/application/prompts/PromptBuilder.ts
|
|
4769
|
+
var PromptBuilder = class {
|
|
4770
|
+
static blogPost(input) {
|
|
4771
|
+
return `
|
|
4772
|
+
As an expert SEO Content Strategist and Copywriter, generate a high-quality, comprehensive blog post.
|
|
4773
|
+
|
|
4774
|
+
TOPIC: ${input.topic}
|
|
4775
|
+
TYPE: ${input.blogType}
|
|
4776
|
+
KEYWORDS: ${input.keywords.join(", ")}
|
|
4777
|
+
TONE: ${input.tone}
|
|
4778
|
+
TARGET AUDIENCE: ${input.targetAudience}
|
|
4779
|
+
WORD COUNT: ${input.wordCount}
|
|
4780
|
+
LANGUAGE: ${input.language || "English"}
|
|
4781
|
+
|
|
4782
|
+
OPTIMIZATION REQUIREMENTS:
|
|
4783
|
+
- SEO Optimization: ${input.seoOptimization ? "ON (Include semantic keywords, LSI, and proper H1-H3 structure)" : "OFF"}
|
|
4784
|
+
- Include Schema Markup: ${input.includeSchema ? "ON (Generate JSON-LD for this blog type)" : "OFF"}
|
|
4785
|
+
- Image Suggestions: ${input.includeImages ? "ON (Provide DALL-E/Midjourney style prompts for contextually relevant images)" : "OFF"}
|
|
4786
|
+
|
|
4787
|
+
RESPONSE FORMAT (STRICT JSON ONLY):
|
|
4788
|
+
{
|
|
4789
|
+
"title": "Compelling, Click-worthy Title",
|
|
4790
|
+
"content": "Full markdown-formatted blog content with headers",
|
|
4791
|
+
"metaDescription": "SEO-optimized description (150-160 chars)",
|
|
4792
|
+
"seoScore": 0-100,
|
|
4793
|
+
"readabilityScore": 0-100,
|
|
4794
|
+
"keywords": ["list", "of", "optimized", "keywords"],
|
|
4795
|
+
"performance": {
|
|
4796
|
+
"readingTime": minutes (number),
|
|
4797
|
+
"shareability": 0-10 (number),
|
|
4798
|
+
"seoRank": 0-10 (number)
|
|
4799
|
+
},
|
|
4800
|
+
"schemaMarkup": "JSON-LD string (if requested)",
|
|
4801
|
+
"imagePrompts": ["Prompt 1", "Prompt 2"] (if requested)
|
|
4802
|
+
}
|
|
4803
|
+
`;
|
|
4804
|
+
}
|
|
4805
|
+
static socialPost(input) {
|
|
4806
|
+
return `
|
|
4807
|
+
Write a ${input.tone} social media post about: ${input.topic}
|
|
4808
|
+
|
|
4809
|
+
Platform: ${input.platform}
|
|
4810
|
+
Style: ${input.style}
|
|
4811
|
+
Maximum length: ${input.maxLength} characters
|
|
4812
|
+
${input.includeHashtags ? "Include relevant hashtags" : "No hashtags"}
|
|
4813
|
+
${input.includeCallToAction ? "Include a call-to-action" : ""}
|
|
4814
|
+
|
|
4815
|
+
Requirements:
|
|
4816
|
+
- Platform-optimized formatting
|
|
4817
|
+
- Engaging hook in first sentence
|
|
4818
|
+
- Natural, conversational tone
|
|
4819
|
+
- Platform-appropriate emoji usage
|
|
4820
|
+
|
|
4821
|
+
Generate the post in JSON format:
|
|
4822
|
+
{
|
|
4823
|
+
"content": "The post content",
|
|
4824
|
+
"hashtags": ["hashtag1", "hashtag2"],
|
|
4825
|
+
"emojis": ["emoji1", "emoji2"],
|
|
4826
|
+
"estimatedEngagement": 0-100
|
|
4827
|
+
}
|
|
4828
|
+
`;
|
|
4829
|
+
}
|
|
4830
|
+
static videoScript(input) {
|
|
4831
|
+
return `
|
|
4832
|
+
Create a ${input.tone} video script about: ${input.topic}
|
|
4833
|
+
|
|
4834
|
+
Duration: ${input.duration} seconds
|
|
4835
|
+
Target Audience: ${input.targetAudience}
|
|
4836
|
+
Include Visual Cues: ${input.includeVisuals ? "Yes" : "No"}
|
|
4837
|
+
Include CTA: ${input.includeCallToAction ? "Yes" : "No"}
|
|
4838
|
+
|
|
4839
|
+
Approximate word count: ${estimateWordCountForDuration(input.duration)} words
|
|
4840
|
+
|
|
4841
|
+
Generate in JSON format:
|
|
4842
|
+
{
|
|
4843
|
+
"script": "Full script with dialogue and narration",
|
|
4844
|
+
"visualCues": ["Visual cue 1", "Visual cue 2"],
|
|
4845
|
+
"callToAction": "Call to action text (if requested)",
|
|
4846
|
+
"estimatedEngagement": 0-100
|
|
4847
|
+
}
|
|
4848
|
+
`;
|
|
4849
|
+
}
|
|
4850
|
+
static voiceScript(input) {
|
|
4851
|
+
return `
|
|
4852
|
+
Create a ${input.emotion} voice script about: ${input.topic}
|
|
4853
|
+
|
|
4854
|
+
Duration: ${input.duration} seconds
|
|
4855
|
+
Emotion: ${input.emotion}
|
|
4856
|
+
|
|
4857
|
+
The script should:
|
|
4858
|
+
- Evoke the specified emotion
|
|
4859
|
+
- Be suitable for voice recording with emotion control
|
|
4860
|
+
- Include natural speech patterns
|
|
4861
|
+
- Have appropriate pacing for the emotion
|
|
4862
|
+
- Include emotional cues in brackets where needed
|
|
4863
|
+
|
|
4864
|
+
Approximate word count: ${estimateWordCountForDuration(input.duration)} words
|
|
4865
|
+
|
|
4866
|
+
Generate in JSON format:
|
|
4867
|
+
{
|
|
4868
|
+
"script": "Full script with emotional cues",
|
|
4869
|
+
"visualCues": ["Visual cue 1", "Visual cue 2"],
|
|
4870
|
+
"estimatedEngagement": 0-100
|
|
4871
|
+
}
|
|
4872
|
+
`;
|
|
4873
|
+
}
|
|
4874
|
+
static contentCalendar(niche, days) {
|
|
4875
|
+
return `
|
|
4876
|
+
Generate a ${days}-day content calendar for: ${niche}
|
|
4877
|
+
|
|
4878
|
+
For each day, provide:
|
|
4879
|
+
- Topic
|
|
4880
|
+
- Content type (blog, video, social, email, caption, script)
|
|
4881
|
+
- Best platform for this content
|
|
4882
|
+
- Brief description
|
|
4883
|
+
- Estimated engagement (0-100)
|
|
4884
|
+
- Priority level (high, medium, low)
|
|
4885
|
+
|
|
4886
|
+
Format as JSON array:
|
|
4887
|
+
[
|
|
4888
|
+
{
|
|
4889
|
+
"day": 1,
|
|
4890
|
+
"topic": "...",
|
|
4891
|
+
"contentType": "blog|video|social|email|caption|script",
|
|
4892
|
+
"platform": "twitter|linkedin|instagram|threads|tiktok|facebook",
|
|
4893
|
+
"description": "...",
|
|
4894
|
+
"estimatedEngagement": 0-100,
|
|
4895
|
+
"priority": "high|medium|low"
|
|
4896
|
+
}
|
|
4897
|
+
]
|
|
4898
|
+
|
|
4899
|
+
Requirements:
|
|
4900
|
+
- Mix of content types across platforms
|
|
4901
|
+
- Platform-appropriate suggestions
|
|
4902
|
+
- Engaging, varied topics
|
|
4903
|
+
- Realistic posting schedule
|
|
4904
|
+
`;
|
|
4905
|
+
}
|
|
4906
|
+
static sentiment(content) {
|
|
4907
|
+
return `
|
|
4908
|
+
Analyze the sentiment of this social media post:
|
|
4909
|
+
|
|
4910
|
+
"${content}"
|
|
4911
|
+
|
|
4912
|
+
Provide analysis in JSON format:
|
|
4913
|
+
{
|
|
4914
|
+
"sentiment": "positive|neutral|negative",
|
|
4915
|
+
"confidence": 0-1,
|
|
4916
|
+
"emotions": [
|
|
4917
|
+
{"emotion": "happy|excited|calm|sad|angry|surprised|fearful|disgusted|neutral", "score": 0-1}
|
|
4918
|
+
]
|
|
4919
|
+
}
|
|
4920
|
+
|
|
4921
|
+
Return only the JSON:
|
|
4922
|
+
`;
|
|
4923
|
+
}
|
|
4924
|
+
static contentAnalysis(content) {
|
|
4925
|
+
return `
|
|
4926
|
+
Analyze this content:
|
|
4927
|
+
|
|
4928
|
+
"${content}"
|
|
4929
|
+
|
|
4930
|
+
Provide analysis in JSON format:
|
|
4931
|
+
{
|
|
4932
|
+
"keywords": ["keyword1", "keyword2", ...],
|
|
4933
|
+
"entities": ["entity1", "entity2", ...],
|
|
4934
|
+
"suggestedImprovements": ["suggestion1", ...],
|
|
4935
|
+
"readabilityScore": 0-100,
|
|
4936
|
+
"estimatedEngagement": 0-100
|
|
4937
|
+
}
|
|
4938
|
+
|
|
4939
|
+
Return only the JSON:
|
|
4940
|
+
`;
|
|
4941
|
+
}
|
|
4942
|
+
static seoOptimization(content, keywords) {
|
|
4943
|
+
return `
|
|
4944
|
+
Optimize this content for SEO:
|
|
4945
|
+
|
|
4946
|
+
Content: "${content}"
|
|
4947
|
+
Keywords: ${keywords.join(", ")}
|
|
4948
|
+
|
|
4949
|
+
Tasks:
|
|
4950
|
+
1. Incorporate keywords naturally
|
|
4951
|
+
2. Improve engagement potential
|
|
4952
|
+
3. Add relevant call-to-action if appropriate
|
|
4953
|
+
4. Optimize for readability
|
|
4954
|
+
5. Enhance heading structure
|
|
4955
|
+
|
|
4956
|
+
Return JSON:
|
|
4957
|
+
{
|
|
4958
|
+
"optimized": "...",
|
|
4959
|
+
"score": 0-100,
|
|
4960
|
+
"suggestions": ["suggestion1", ...],
|
|
4961
|
+
"addedKeywords": ["keyword1", ...],
|
|
4962
|
+
"removedFillerWords": number,
|
|
4963
|
+
"readabilityImprovements": ["improvement1", ...],
|
|
4964
|
+
"metaDescription": "SEO-optimized meta description",
|
|
4965
|
+
"titleSuggestions": ["title1", ...]
|
|
4966
|
+
}
|
|
4967
|
+
|
|
4968
|
+
Return only the JSON:
|
|
4969
|
+
`;
|
|
4970
|
+
}
|
|
4971
|
+
static seoScore(content, keywords) {
|
|
4972
|
+
return `
|
|
4973
|
+
Calculate SEO score for this content:
|
|
4974
|
+
|
|
4975
|
+
Content: "${content}"
|
|
4976
|
+
Keywords: ${keywords.join(", ")}
|
|
4977
|
+
|
|
4978
|
+
Provide breakdown in JSON:
|
|
4979
|
+
{
|
|
4980
|
+
"keywordDensity": 0-100,
|
|
4981
|
+
"readabilityScore": 0-100,
|
|
4982
|
+
"titleOptimization": 0-100,
|
|
4983
|
+
"metaDescription": 0-100,
|
|
4984
|
+
"headingStructure": 0-100,
|
|
4985
|
+
"internalLinking": 0-100,
|
|
4986
|
+
"overall": 0-100
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
Return only the JSON:
|
|
4990
|
+
`;
|
|
4991
|
+
}
|
|
4992
|
+
static abTestVariant(input) {
|
|
4993
|
+
return `
|
|
4994
|
+
Predict performance for this content variant:
|
|
4995
|
+
|
|
4996
|
+
Content: "${input.content}"
|
|
4997
|
+
Content Type: ${input.contentType}
|
|
4998
|
+
Tone: ${input.tone}
|
|
4999
|
+
Target Audience: ${input.targetAudience}
|
|
5000
|
+
Platform: ${input.platform}
|
|
5001
|
+
Goals: ${input.goals.join(", ")}
|
|
5002
|
+
|
|
5003
|
+
Provide prediction in JSON:
|
|
5004
|
+
{
|
|
5005
|
+
"predictedEngagement": 0-100,
|
|
5006
|
+
"predictedCTR": 0-100,
|
|
5007
|
+
"predictedConversions": 0-100,
|
|
5008
|
+
"confidence": 0-1,
|
|
5009
|
+
"reasoning": "...",
|
|
5010
|
+
"strengths": ["strength1", ...],
|
|
5011
|
+
"weaknesses": ["weakness1", ...],
|
|
5012
|
+
"suggestions": ["suggestion1", ...]
|
|
5013
|
+
}
|
|
5014
|
+
|
|
5015
|
+
Return only the JSON:
|
|
5016
|
+
`;
|
|
5017
|
+
}
|
|
5018
|
+
static hashtags(content, count) {
|
|
5019
|
+
return `
|
|
5020
|
+
Generate ${count} relevant hashtags for this content:
|
|
5021
|
+
|
|
5022
|
+
"${content}"
|
|
5023
|
+
|
|
5024
|
+
Requirements:
|
|
5025
|
+
- Mix of popular and niche hashtags
|
|
5026
|
+
- Industry-specific when possible
|
|
5027
|
+
- Trending if relevant
|
|
5028
|
+
- No duplicated words
|
|
5029
|
+
- Format: #hashtag (one per line)
|
|
5030
|
+
|
|
5031
|
+
Return only the hashtags:
|
|
5032
|
+
`;
|
|
5033
|
+
}
|
|
5034
|
+
static imagePrompt(description, style) {
|
|
5035
|
+
return `
|
|
5036
|
+
Generate a detailed AI image generation prompt for:
|
|
5037
|
+
|
|
5038
|
+
Description: ${description}
|
|
5039
|
+
Style: ${style || "realistic"}
|
|
5040
|
+
|
|
5041
|
+
Create a detailed, descriptive prompt that includes:
|
|
5042
|
+
- Subject details
|
|
5043
|
+
- Mood and atmosphere
|
|
5044
|
+
- Lighting
|
|
5045
|
+
- Composition
|
|
5046
|
+
- Art style reference
|
|
5047
|
+
- Technical specifications (aspect ratio, quality)
|
|
5048
|
+
|
|
5049
|
+
The prompt should be optimized for models like Midjourney, DALL-E, or Stable Diffusion.
|
|
5050
|
+
|
|
5051
|
+
Generate the prompt:
|
|
5052
|
+
`;
|
|
5053
|
+
}
|
|
5054
|
+
static blogImagePrompts(blogContent) {
|
|
5055
|
+
return `
|
|
5056
|
+
Analyze this blog content and generate 3-5 detailed image prompts for illustrative images:
|
|
5057
|
+
|
|
5058
|
+
Blog Content: "${blogContent}"
|
|
5059
|
+
|
|
5060
|
+
For each image prompt, provide:
|
|
5061
|
+
- Subject description
|
|
5062
|
+
- Mood and atmosphere
|
|
5063
|
+
- Style reference
|
|
5064
|
+
- Composition details
|
|
5065
|
+
- Technical specs
|
|
5066
|
+
|
|
5067
|
+
Return as JSON array:
|
|
5068
|
+
["prompt1", "prompt2", "prompt3", ...]
|
|
5069
|
+
|
|
5070
|
+
Return only the JSON:
|
|
5071
|
+
`;
|
|
5072
|
+
}
|
|
5073
|
+
static maxTokensForDuration(durationSeconds) {
|
|
5074
|
+
return estimateTokenBudgetForDuration(durationSeconds);
|
|
5075
|
+
}
|
|
5076
|
+
};
|
|
5077
|
+
|
|
5078
|
+
// src/content/application/services/BlogService.ts
|
|
5079
|
+
var BlogService = class {
|
|
5080
|
+
constructor(executor) {
|
|
5081
|
+
this.executor = executor;
|
|
5082
|
+
}
|
|
5083
|
+
executor;
|
|
5084
|
+
async generateBlogPost(request) {
|
|
5085
|
+
const topic = validateTopicText(request.topic);
|
|
5086
|
+
const keywords = validateKeywordList(request.targetKeywords);
|
|
5087
|
+
const prompt = PromptBuilder.blogPost({
|
|
5088
|
+
topic,
|
|
5089
|
+
blogType: request.blogType,
|
|
5090
|
+
keywords,
|
|
5091
|
+
tone: request.tone,
|
|
5092
|
+
targetAudience: request.targetAudience,
|
|
5093
|
+
wordCount: request.wordCount,
|
|
5094
|
+
language: request.language,
|
|
5095
|
+
seoOptimization: request.seoOptimization,
|
|
5096
|
+
includeSchema: request.includeSchema,
|
|
5097
|
+
includeImages: request.includeImages
|
|
5098
|
+
});
|
|
5099
|
+
const parsed = await this.executor.runJson(
|
|
5100
|
+
prompt,
|
|
5101
|
+
{},
|
|
5102
|
+
{ maxTokens: request.wordCount * 2, temperature: 0.7 }
|
|
5103
|
+
);
|
|
5104
|
+
return {
|
|
5105
|
+
id: generateId("blog"),
|
|
5106
|
+
...parsed,
|
|
5107
|
+
blogType: request.blogType,
|
|
5108
|
+
tone: request.tone,
|
|
5109
|
+
wordCount: request.wordCount,
|
|
5110
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5111
|
+
};
|
|
5112
|
+
}
|
|
5113
|
+
};
|
|
5114
|
+
async function batchRequest(requests, options = {}) {
|
|
5115
|
+
const {
|
|
5116
|
+
concurrency = 3,
|
|
5117
|
+
stopOnError = false
|
|
5118
|
+
} = options;
|
|
5119
|
+
const results = [];
|
|
5120
|
+
const errors = [];
|
|
5121
|
+
for (let i = 0; i < requests.length; i += concurrency) {
|
|
5122
|
+
const batch = requests.slice(i, i + concurrency);
|
|
5123
|
+
const batchResults = await Promise.allSettled(
|
|
5124
|
+
batch.map((fn) => fn())
|
|
5125
|
+
);
|
|
5126
|
+
for (const result of batchResults) {
|
|
5127
|
+
if (result.status === "fulfilled") {
|
|
5128
|
+
results.push(result.value);
|
|
5129
|
+
} else {
|
|
5130
|
+
errors.push(result.reason);
|
|
5131
|
+
if (stopOnError) {
|
|
5132
|
+
throw new Error(
|
|
5133
|
+
`Batch request failed: ${errors[0].message}`
|
|
5134
|
+
);
|
|
5135
|
+
}
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
}
|
|
5139
|
+
if (errors.length > 0 && !stopOnError) {
|
|
5140
|
+
console.warn(`${errors.length} requests failed in batch`);
|
|
5141
|
+
}
|
|
5142
|
+
return results;
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
// src/content/application/services/SocialService.ts
|
|
5146
|
+
var MULTI_PLATFORMS = [
|
|
5147
|
+
"twitter",
|
|
5148
|
+
"linkedin",
|
|
5149
|
+
"instagram",
|
|
5150
|
+
"threads",
|
|
5151
|
+
"tiktok"
|
|
5152
|
+
];
|
|
5153
|
+
var DEFAULT_SOCIAL_RESULT = {
|
|
5154
|
+
content: "",
|
|
5155
|
+
platform: "twitter",
|
|
5156
|
+
hashtags: [],
|
|
5157
|
+
emojis: [],
|
|
5158
|
+
characterCount: 0,
|
|
5159
|
+
estimatedEngagement: 0
|
|
5160
|
+
};
|
|
5161
|
+
var SocialService = class {
|
|
5162
|
+
constructor(executor) {
|
|
5163
|
+
this.executor = executor;
|
|
5164
|
+
}
|
|
5165
|
+
executor;
|
|
5166
|
+
async generateSocialContent(request) {
|
|
5167
|
+
const topic = validateTopicText(request.topic);
|
|
5168
|
+
const spec = resolvePlatformSpec(request.platform);
|
|
5169
|
+
const maxLength = resolveMaxContentLength(request.platform, request.maxLength);
|
|
5170
|
+
const prompt = PromptBuilder.socialPost({
|
|
5171
|
+
topic,
|
|
5172
|
+
platform: request.platform,
|
|
5173
|
+
tone: request.tone,
|
|
5174
|
+
style: spec.style,
|
|
5175
|
+
maxLength,
|
|
5176
|
+
includeHashtags: request.hashtags !== false,
|
|
5177
|
+
includeCallToAction: Boolean(request.includeCallToAction)
|
|
5178
|
+
});
|
|
5179
|
+
const parsed = await this.executor.runJson(
|
|
5180
|
+
prompt,
|
|
5181
|
+
{ ...DEFAULT_SOCIAL_RESULT, platform: request.platform },
|
|
5182
|
+
{ maxTokens: 500, temperature: 0.8 }
|
|
5183
|
+
);
|
|
5184
|
+
return {
|
|
5185
|
+
...parsed,
|
|
5186
|
+
platform: request.platform,
|
|
5187
|
+
characterCount: parsed.content?.length ?? 0
|
|
5188
|
+
};
|
|
5189
|
+
}
|
|
5190
|
+
async generateForAllPlatforms(topic, tone) {
|
|
5191
|
+
const requests = MULTI_PLATFORMS.map(
|
|
5192
|
+
(platform) => () => this.generateSocialContent({ topic, platform, tone })
|
|
5193
|
+
);
|
|
5194
|
+
try {
|
|
5195
|
+
return await batchRequest(requests, { concurrency: 2, stopOnError: false });
|
|
5196
|
+
} catch (error) {
|
|
5197
|
+
console.warn("Batch execution failed, falling back to sequential:", error);
|
|
5198
|
+
const results = [];
|
|
5199
|
+
for (const platform of MULTI_PLATFORMS) {
|
|
5200
|
+
try {
|
|
5201
|
+
results.push(await this.generateSocialContent({ topic, platform, tone }));
|
|
5202
|
+
} catch (err) {
|
|
5203
|
+
console.error(`Failed to generate for ${platform}:`, err);
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
return results;
|
|
5207
|
+
}
|
|
5208
|
+
}
|
|
5209
|
+
async generateHashtags(content, count) {
|
|
5210
|
+
const validated = validateHashtagCount(count);
|
|
5211
|
+
const prompt = PromptBuilder.hashtags(content, validated);
|
|
5212
|
+
const response = await this.executor.runText(prompt, { maxTokens: 200, temperature: 0.7 });
|
|
5213
|
+
const hashtags = response.match(/#[\w-]+/g) || [];
|
|
5214
|
+
return hashtags.slice(0, validated);
|
|
5215
|
+
}
|
|
5216
|
+
optimizeHashtags(hashtags, platform) {
|
|
5217
|
+
const budget = resolveHashtagBudget(platform);
|
|
5218
|
+
return rankAndTrimHashtags(hashtags, budget);
|
|
5219
|
+
}
|
|
5220
|
+
};
|
|
5221
|
+
|
|
5222
|
+
// src/content/application/services/VideoScriptService.ts
|
|
5223
|
+
var buildScriptResult = (parsed, duration) => {
|
|
5224
|
+
const script = parsed.script ?? "";
|
|
5225
|
+
if (!script) {
|
|
5226
|
+
throw new Error("AI response missing script field");
|
|
5227
|
+
}
|
|
5228
|
+
const wordCount = script.trim().length === 0 ? 0 : script.trim().split(/\s+/).length;
|
|
5229
|
+
return {
|
|
5230
|
+
...parsed,
|
|
5231
|
+
script,
|
|
5232
|
+
duration,
|
|
5233
|
+
wordCount
|
|
5234
|
+
};
|
|
5235
|
+
};
|
|
5236
|
+
var VideoScriptService = class {
|
|
5237
|
+
constructor(executor) {
|
|
5238
|
+
this.executor = executor;
|
|
5239
|
+
}
|
|
5240
|
+
executor;
|
|
5241
|
+
async generateVideoScript(request) {
|
|
5242
|
+
const topic = validateTopicText(request.topic);
|
|
5243
|
+
const duration = validateDurationSeconds(request.duration);
|
|
5244
|
+
const prompt = PromptBuilder.videoScript({
|
|
5245
|
+
topic,
|
|
5246
|
+
tone: request.tone,
|
|
5247
|
+
duration,
|
|
5248
|
+
targetAudience: request.targetAudience,
|
|
5249
|
+
includeVisuals: request.includeVisuals,
|
|
5250
|
+
includeCallToAction: request.includeCallToAction
|
|
5251
|
+
});
|
|
5252
|
+
const parsed = await this.executor.runJson(
|
|
5253
|
+
prompt,
|
|
5254
|
+
{ script: "", visualCues: [], duration, wordCount: 0, estimatedEngagement: 0 },
|
|
5255
|
+
{ maxTokens: estimateTokenBudgetForDuration(duration), temperature: 0.8 }
|
|
5256
|
+
);
|
|
5257
|
+
return buildScriptResult(parsed, duration);
|
|
5258
|
+
}
|
|
5259
|
+
async generateVoiceScript(topic, emotion, duration) {
|
|
5260
|
+
const validatedTopic = validateTopicText(topic);
|
|
5261
|
+
const validatedDuration = validateDurationSeconds(duration);
|
|
5262
|
+
const prompt = PromptBuilder.voiceScript({
|
|
5263
|
+
topic: validatedTopic,
|
|
5264
|
+
emotion,
|
|
5265
|
+
duration: validatedDuration
|
|
5266
|
+
});
|
|
5267
|
+
const parsed = await this.executor.runJson(
|
|
5268
|
+
prompt,
|
|
5269
|
+
{ script: "", visualCues: [], duration: validatedDuration, wordCount: 0, estimatedEngagement: 0 },
|
|
5270
|
+
{ maxTokens: estimateTokenBudgetForDuration(validatedDuration), temperature: 0.8 }
|
|
5271
|
+
);
|
|
5272
|
+
return buildScriptResult(parsed, validatedDuration);
|
|
5273
|
+
}
|
|
5274
|
+
};
|
|
5275
|
+
|
|
5276
|
+
// src/content/application/services/AnalysisService.ts
|
|
5277
|
+
var DEFAULT_SENTIMENT = {
|
|
5278
|
+
sentiment: "neutral",
|
|
5279
|
+
confidence: 0.5,
|
|
5280
|
+
emotions: []
|
|
5281
|
+
};
|
|
5282
|
+
var DEFAULT_ANALYSIS = {
|
|
5283
|
+
sentiment: DEFAULT_SENTIMENT,
|
|
5284
|
+
keywords: [],
|
|
5285
|
+
entities: [],
|
|
5286
|
+
suggestedImprovements: [],
|
|
5287
|
+
readabilityScore: 50,
|
|
5288
|
+
estimatedEngagement: 50
|
|
5289
|
+
};
|
|
5290
|
+
var AnalysisService = class {
|
|
5291
|
+
constructor(executor) {
|
|
5292
|
+
this.executor = executor;
|
|
5293
|
+
}
|
|
5294
|
+
executor;
|
|
5295
|
+
async analyzeSentiment(content) {
|
|
5296
|
+
const validated = validateContentBody(content);
|
|
5297
|
+
const prompt = PromptBuilder.sentiment(validated);
|
|
5298
|
+
const result = await this.executor.runJson(
|
|
5299
|
+
prompt,
|
|
5300
|
+
DEFAULT_SENTIMENT,
|
|
5301
|
+
{ maxTokens: 200, temperature: 0.3 }
|
|
5302
|
+
);
|
|
5303
|
+
return {
|
|
5304
|
+
...result,
|
|
5305
|
+
confidence: clampConfidenceToValidRange(result.confidence)
|
|
5306
|
+
};
|
|
5307
|
+
}
|
|
5308
|
+
async analyzeContent(request) {
|
|
5309
|
+
const validated = validateContentBody(request.content);
|
|
5310
|
+
const sentimentResult = await this.analyzeSentiment(validated);
|
|
5311
|
+
const prompt = PromptBuilder.contentAnalysis(validated);
|
|
5312
|
+
const parsed = await this.executor.runJson(
|
|
5313
|
+
prompt,
|
|
5314
|
+
{ ...DEFAULT_ANALYSIS, sentiment: sentimentResult },
|
|
5315
|
+
{ maxTokens: 300, temperature: 0.5 }
|
|
5316
|
+
);
|
|
5317
|
+
return {
|
|
5318
|
+
sentiment: sentimentResult,
|
|
5319
|
+
keywords: parsed.keywords ?? [],
|
|
5320
|
+
entities: parsed.entities ?? [],
|
|
5321
|
+
suggestedImprovements: parsed.suggestedImprovements ?? [],
|
|
5322
|
+
readabilityScore: clampScoreToValidRange(parsed.readabilityScore),
|
|
5323
|
+
estimatedEngagement: clampScoreToValidRange(parsed.estimatedEngagement)
|
|
5324
|
+
};
|
|
5325
|
+
}
|
|
5326
|
+
};
|
|
5327
|
+
|
|
5328
|
+
// src/content/application/services/SeoService.ts
|
|
5329
|
+
var DEFAULT_SEO_SCORE = {
|
|
5330
|
+
keywordDensity: 50,
|
|
5331
|
+
readabilityScore: 50,
|
|
5332
|
+
titleOptimization: 50,
|
|
5333
|
+
metaDescription: 50,
|
|
5334
|
+
headingStructure: 50,
|
|
5335
|
+
internalLinking: 50,
|
|
5336
|
+
overall: 50
|
|
5337
|
+
};
|
|
5338
|
+
var UNDERUTILIZED_SUGGESTION = "Consider using this keyword more frequently";
|
|
5339
|
+
var SeoService = class {
|
|
5340
|
+
constructor(executor) {
|
|
5341
|
+
this.executor = executor;
|
|
5342
|
+
}
|
|
5343
|
+
executor;
|
|
5344
|
+
async optimizeSEO(request) {
|
|
5345
|
+
const content = validateContentBody(request.content);
|
|
5346
|
+
const keywords = validateKeywordList(request.keywords);
|
|
5347
|
+
const prompt = PromptBuilder.seoOptimization(content, keywords);
|
|
5348
|
+
const result = await this.executor.runJson(
|
|
5349
|
+
prompt,
|
|
5350
|
+
{
|
|
5351
|
+
optimized: content,
|
|
5352
|
+
score: 50,
|
|
5353
|
+
suggestions: [],
|
|
5354
|
+
addedKeywords: [],
|
|
5355
|
+
removedFillerWords: 0,
|
|
5356
|
+
readabilityImprovements: []
|
|
5357
|
+
},
|
|
5358
|
+
{ maxTokens: 1e3, temperature: 0.7 }
|
|
5359
|
+
);
|
|
5360
|
+
return {
|
|
5361
|
+
...result,
|
|
5362
|
+
score: clampScoreToValidRange(result.score)
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
async calculateSEOScore(content, keywords) {
|
|
5366
|
+
const validatedContent = validateContentBody(content);
|
|
5367
|
+
const validatedKeywords = validateKeywordList(keywords);
|
|
5368
|
+
const prompt = PromptBuilder.seoOptimization(
|
|
5369
|
+
truncateForSeoPreview(validatedContent),
|
|
5370
|
+
validatedKeywords
|
|
5371
|
+
);
|
|
5372
|
+
const result = await this.executor.runJson(
|
|
5373
|
+
prompt,
|
|
5374
|
+
DEFAULT_SEO_SCORE,
|
|
5375
|
+
{ maxTokens: 200, temperature: 0.3 }
|
|
5376
|
+
);
|
|
5377
|
+
return {
|
|
5378
|
+
keywordDensity: clampScoreToValidRange(result.keywordDensity),
|
|
5379
|
+
readabilityScore: clampScoreToValidRange(result.readabilityScore),
|
|
5380
|
+
titleOptimization: clampScoreToValidRange(result.titleOptimization),
|
|
5381
|
+
metaDescription: clampScoreToValidRange(result.metaDescription),
|
|
5382
|
+
headingStructure: clampScoreToValidRange(result.headingStructure),
|
|
5383
|
+
internalLinking: clampScoreToValidRange(result.internalLinking),
|
|
5384
|
+
overall: clampScoreToValidRange(result.overall)
|
|
5385
|
+
};
|
|
5386
|
+
}
|
|
5387
|
+
analyzeKeywords(content, keywords) {
|
|
5388
|
+
const validatedContent = validateContentBody(content);
|
|
5389
|
+
const validatedKeywords = validateKeywordList(keywords);
|
|
5390
|
+
return validatedKeywords.map((keyword) => {
|
|
5391
|
+
const count = countKeywordOccurrences(validatedContent, keyword);
|
|
5392
|
+
const density = calculateKeywordDensity(validatedContent, keyword);
|
|
5393
|
+
return {
|
|
5394
|
+
keyword,
|
|
5395
|
+
count,
|
|
5396
|
+
density,
|
|
5397
|
+
prominence: classifyKeywordProminence(density),
|
|
5398
|
+
suggestions: isUnderutilizedKeyword(density) ? [UNDERUTILIZED_SUGGESTION] : []
|
|
5399
|
+
};
|
|
5400
|
+
});
|
|
5401
|
+
}
|
|
5402
|
+
};
|
|
5403
|
+
|
|
5404
|
+
// src/content/application/services/ABTestService.ts
|
|
5405
|
+
var DEFAULT_PREDICTION = {
|
|
5406
|
+
variantId: "",
|
|
5407
|
+
predictedEngagement: 0,
|
|
5408
|
+
predictedCTR: 0,
|
|
5409
|
+
predictedConversions: 0,
|
|
5410
|
+
confidence: 0,
|
|
5411
|
+
reasoning: "",
|
|
5412
|
+
strengths: [],
|
|
5413
|
+
weaknesses: [],
|
|
5414
|
+
suggestions: []
|
|
5415
|
+
};
|
|
5416
|
+
var VARIANT_A_ID = "A";
|
|
5417
|
+
var VARIANT_B_ID = "B";
|
|
5418
|
+
var FALLBACK_ENGAGEMENT = 50;
|
|
5419
|
+
var DEFAULT_RECOMMENDATIONS = [
|
|
5420
|
+
"Test with larger audience",
|
|
5421
|
+
"Monitor click-through rates"
|
|
5422
|
+
];
|
|
5423
|
+
var ABTestService = class {
|
|
5424
|
+
constructor(executor) {
|
|
5425
|
+
this.executor = executor;
|
|
5426
|
+
}
|
|
5427
|
+
executor;
|
|
5428
|
+
async predictABTest(request) {
|
|
5429
|
+
const predictions = [];
|
|
5430
|
+
for (const variant of request.variants) {
|
|
5431
|
+
const prompt = PromptBuilder.abTestVariant({
|
|
5432
|
+
content: truncateForAbVariantPreview(variant.content),
|
|
5433
|
+
contentType: variant.contentType,
|
|
5434
|
+
tone: variant.tone,
|
|
5435
|
+
targetAudience: request.targetAudience,
|
|
5436
|
+
platform: request.platform,
|
|
5437
|
+
goals: request.goals
|
|
5438
|
+
});
|
|
5439
|
+
const parsed = await this.executor.runJson(
|
|
5440
|
+
prompt,
|
|
5441
|
+
{ ...DEFAULT_PREDICTION, variantId: variant.id },
|
|
5442
|
+
{ maxTokens: 300, temperature: 0.5 }
|
|
5443
|
+
);
|
|
5444
|
+
predictions.push({
|
|
5445
|
+
variantId: variant.id,
|
|
5446
|
+
predictedEngagement: clampScoreToValidRange(parsed.predictedEngagement),
|
|
5447
|
+
predictedCTR: clampScoreToValidRange(parsed.predictedCTR),
|
|
5448
|
+
predictedConversions: clampScoreToValidRange(parsed.predictedConversions),
|
|
5449
|
+
confidence: clampConfidenceToValidRange(parsed.confidence),
|
|
5450
|
+
reasoning: parsed.reasoning ?? "",
|
|
5451
|
+
strengths: parsed.strengths ?? [],
|
|
5452
|
+
weaknesses: parsed.weaknesses ?? [],
|
|
5453
|
+
suggestions: parsed.suggestions ?? []
|
|
5454
|
+
});
|
|
5455
|
+
}
|
|
5456
|
+
return predictions;
|
|
5457
|
+
}
|
|
5458
|
+
async compareVariants(variantA, variantB) {
|
|
5459
|
+
const predictions = await this.predictABTest({
|
|
5460
|
+
variants: [
|
|
5461
|
+
{ id: VARIANT_A_ID, content: variantA, contentType: "social", tone: "casual" },
|
|
5462
|
+
{ id: VARIANT_B_ID, content: variantB, contentType: "social", tone: "casual" }
|
|
5463
|
+
],
|
|
5464
|
+
targetAudience: "general",
|
|
5465
|
+
platform: "twitter",
|
|
5466
|
+
goals: ["engagement", "clicks"]
|
|
5467
|
+
});
|
|
5468
|
+
const scoreA = predictions[0]?.predictedEngagement ?? FALLBACK_ENGAGEMENT;
|
|
5469
|
+
const scoreB = predictions[1]?.predictedEngagement ?? FALLBACK_ENGAGEMENT;
|
|
5470
|
+
const isTie = scoreA === scoreB;
|
|
5471
|
+
const winner = selectHigherScoreVariantId(scoreA, scoreB, VARIANT_A_ID, VARIANT_B_ID);
|
|
5472
|
+
const improvement = calculateImprovementPercentage(scoreA, scoreB);
|
|
5473
|
+
return {
|
|
5474
|
+
winner,
|
|
5475
|
+
confidence: AB_TEST_DEFAULT_CONFIDENCE,
|
|
5476
|
+
improvement: isTie ? "0%" : `+${improvement}% engagement`,
|
|
5477
|
+
reasoning: isTie ? "Both variants have equal predicted engagement" : winner === VARIANT_A_ID ? "Variant A has more engaging content" : "Variant B has more engaging content",
|
|
5478
|
+
recommendations: [...DEFAULT_RECOMMENDATIONS]
|
|
5479
|
+
};
|
|
5480
|
+
}
|
|
5481
|
+
};
|
|
5482
|
+
|
|
5483
|
+
// src/content/application/services/ImagePromptService.ts
|
|
5484
|
+
var ImagePromptService = class {
|
|
5485
|
+
constructor(executor) {
|
|
5486
|
+
this.executor = executor;
|
|
5487
|
+
}
|
|
5488
|
+
executor;
|
|
5489
|
+
async generateImagePrompt(description, style) {
|
|
5490
|
+
const validated = validateTopicText(description);
|
|
5491
|
+
const prompt = PromptBuilder.imagePrompt(validated, style);
|
|
5492
|
+
return this.executor.runText(prompt, { maxTokens: 300, temperature: 0.8 });
|
|
5493
|
+
}
|
|
5494
|
+
async generateImagePromptsForBlog(blogContent) {
|
|
5495
|
+
const truncated = truncateForBlogPromptPreview(validateContentBody(blogContent));
|
|
5496
|
+
const prompt = PromptBuilder.blogImagePrompts(truncated);
|
|
5497
|
+
const prompts = await this.executor.runJson(prompt, [], {
|
|
5498
|
+
maxTokens: 500,
|
|
5499
|
+
temperature: 0.8
|
|
5500
|
+
});
|
|
5501
|
+
return Array.isArray(prompts) ? prompts : [];
|
|
5502
|
+
}
|
|
5503
|
+
};
|
|
5504
|
+
|
|
5505
|
+
// src/content/application/services/ContentCalendarService.ts
|
|
5506
|
+
var toCalendarEntry = (item) => ({
|
|
5507
|
+
date: resolveCalendarEntryDate(item.day),
|
|
5508
|
+
topic: item.topic,
|
|
5509
|
+
contentType: item.contentType,
|
|
5510
|
+
platform: item.platform,
|
|
5511
|
+
description: item.description,
|
|
5512
|
+
estimatedEngagement: item.estimatedEngagement,
|
|
5513
|
+
priority: item.priority
|
|
5514
|
+
});
|
|
5515
|
+
var ContentCalendarService = class {
|
|
5516
|
+
constructor(executor) {
|
|
5517
|
+
this.executor = executor;
|
|
5518
|
+
}
|
|
5519
|
+
executor;
|
|
5520
|
+
async generateContentCalendar(niche, days) {
|
|
5521
|
+
const validatedNiche = validateTopicText(niche);
|
|
5522
|
+
const validatedDays = validateCalendarDays(days);
|
|
5523
|
+
const prompt = PromptBuilder.contentCalendar(validatedNiche, validatedDays);
|
|
5524
|
+
const data = await this.executor.runJson(
|
|
5525
|
+
prompt,
|
|
5526
|
+
[],
|
|
5527
|
+
{
|
|
5528
|
+
maxTokens: estimateTokenBudgetForCalendarDays(validatedDays),
|
|
5529
|
+
temperature: 0.8
|
|
5530
|
+
}
|
|
5531
|
+
);
|
|
5532
|
+
const items = Array.isArray(data) ? data : Array.isArray(data?.calendar) ? data.calendar : Array.isArray(data?.entries) ? data.entries : [];
|
|
5533
|
+
return items.map(toCalendarEntry);
|
|
5534
|
+
}
|
|
5535
|
+
};
|
|
5536
|
+
|
|
5537
|
+
// src/content/application/services/ProviderServices.ts
|
|
5538
|
+
var wrapProviderError = (operation, error) => {
|
|
5539
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5540
|
+
return new AIError(`${operation} failed: ${message}`, "PROVIDER_ERROR", error);
|
|
5541
|
+
};
|
|
5542
|
+
var ensureFactory = (factory, operation) => {
|
|
5543
|
+
if (factory.getAllProviders().length === 0) {
|
|
5544
|
+
throw new AIError(
|
|
5545
|
+
`${operation} failed: No providers are registered. Provide a ProviderConfig with at least one enabled provider when constructing AIContentService.`,
|
|
5546
|
+
"PROVIDER_UNAVAILABLE"
|
|
5547
|
+
);
|
|
5548
|
+
}
|
|
5549
|
+
};
|
|
5550
|
+
var MediaGenerationService = class {
|
|
5551
|
+
constructor(providerFactory) {
|
|
5552
|
+
this.providerFactory = providerFactory;
|
|
5553
|
+
}
|
|
5554
|
+
providerFactory;
|
|
5555
|
+
generateImage(request) {
|
|
5556
|
+
ensureFactory(this.providerFactory, "Image generation");
|
|
5557
|
+
return this.providerFactory.generateImage(request).catch((err) => {
|
|
5558
|
+
throw wrapProviderError("Image generation", err);
|
|
5559
|
+
});
|
|
5560
|
+
}
|
|
5561
|
+
generateVideo(request) {
|
|
5562
|
+
ensureFactory(this.providerFactory, "Video generation");
|
|
5563
|
+
return this.providerFactory.generateVideo(request).catch((err) => {
|
|
5564
|
+
throw wrapProviderError("Video generation", err);
|
|
5565
|
+
});
|
|
5566
|
+
}
|
|
5567
|
+
convertImageToVideo(request) {
|
|
5568
|
+
ensureFactory(this.providerFactory, "Image-to-video conversion");
|
|
5569
|
+
return this.providerFactory.imageToVideo(request).catch((err) => {
|
|
5570
|
+
throw wrapProviderError("Image-to-video conversion", err);
|
|
5571
|
+
});
|
|
5572
|
+
}
|
|
5573
|
+
transformVideo(request) {
|
|
5574
|
+
ensureFactory(this.providerFactory, "Video-to-video transformation");
|
|
5575
|
+
return this.providerFactory.videoToVideo(request).catch((err) => {
|
|
5576
|
+
throw wrapProviderError("Video-to-video transformation", err);
|
|
5577
|
+
});
|
|
5578
|
+
}
|
|
5579
|
+
};
|
|
5580
|
+
|
|
5581
|
+
// src/content/infrastructure/utils/jsonParser.ts
|
|
5582
|
+
function repairCommonJsonDefects2(text) {
|
|
5583
|
+
return text.replace(/(:\s*-?\d+(?:\.\d+)?)\s*"/g, "$1").replace(/(:\s*"[^"]*")"/g, "$1");
|
|
5584
|
+
}
|
|
5585
|
+
function safeJSONParse(text, fallback, onError) {
|
|
5586
|
+
try {
|
|
5587
|
+
return JSON.parse(text);
|
|
5588
|
+
} catch (error) {
|
|
5589
|
+
try {
|
|
5590
|
+
return JSON.parse(repairCommonJsonDefects2(text));
|
|
5591
|
+
} catch {
|
|
5592
|
+
}
|
|
5593
|
+
if (error instanceof SyntaxError) {
|
|
5594
|
+
const positionMatch = error.message.match(/position (\d+)/);
|
|
5595
|
+
const position = positionMatch ? parseInt(positionMatch[1], 10) : -1;
|
|
5596
|
+
if (position > 0) {
|
|
5597
|
+
text.substring(Math.max(0, position - 50), position + 50);
|
|
5598
|
+
}
|
|
5599
|
+
}
|
|
5600
|
+
return fallback;
|
|
5601
|
+
}
|
|
5602
|
+
}
|
|
5603
|
+
function extractJSON(text) {
|
|
5604
|
+
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
5605
|
+
if (codeBlockMatch && codeBlockMatch[1]) {
|
|
5606
|
+
const candidate = codeBlockMatch[1].trim();
|
|
5607
|
+
if (candidate.startsWith("{") || candidate.startsWith("[")) {
|
|
5608
|
+
return candidate;
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
const objectMatch = text.match(/\{[\s\S]*\}/);
|
|
5612
|
+
if (objectMatch) {
|
|
5613
|
+
return objectMatch[0];
|
|
5614
|
+
}
|
|
5615
|
+
const arrayMatch = text.match(/\[[\s\S]*\]/);
|
|
5616
|
+
if (arrayMatch) {
|
|
5617
|
+
return arrayMatch[0];
|
|
5618
|
+
}
|
|
5619
|
+
return null;
|
|
5620
|
+
}
|
|
5621
|
+
function parseAIResponse(response, fallback, onError) {
|
|
5622
|
+
const json = extractJSON(response);
|
|
5623
|
+
if (!json) {
|
|
5624
|
+
return fallback;
|
|
5625
|
+
}
|
|
5626
|
+
return safeJSONParse(json, fallback);
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5629
|
+
// src/content/application/services/GenerationExecutor.ts
|
|
5630
|
+
var GenerationExecutor = class {
|
|
5631
|
+
constructor(generator) {
|
|
5632
|
+
this.generator = generator;
|
|
5633
|
+
}
|
|
5634
|
+
generator;
|
|
5635
|
+
async runJson(prompt, fallback, generationOptions = {}) {
|
|
5636
|
+
const response = await this.generator.generateText(prompt, generationOptions);
|
|
5637
|
+
return parseAIResponse(response, fallback);
|
|
5638
|
+
}
|
|
5639
|
+
runText(prompt, options = {}) {
|
|
5640
|
+
return this.generator.generateText(prompt, options);
|
|
5641
|
+
}
|
|
5642
|
+
/** Usage-complete pass-through; requires a ProviderFactory engine. */
|
|
5643
|
+
runChat(request) {
|
|
5644
|
+
if (!(this.generator instanceof ProviderFactory)) {
|
|
5645
|
+
throw new AIError(
|
|
5646
|
+
"runChat requires a ProviderFactory engine \u2014 construct AIContentService with a provider config, not a custom ITextGenerator",
|
|
5647
|
+
"PROVIDER_UNAVAILABLE"
|
|
5648
|
+
);
|
|
5649
|
+
}
|
|
5650
|
+
return this.generator.chat(request);
|
|
5651
|
+
}
|
|
5652
|
+
};
|
|
5653
|
+
|
|
5654
|
+
// src/content/application/services/AIContentService.ts
|
|
5655
|
+
var isTextGenerator = (value) => typeof value === "object" && value !== null && typeof value.generateText === "function";
|
|
5656
|
+
function toAIProviderConfig(config) {
|
|
5657
|
+
const legacy = config;
|
|
5658
|
+
const modern = config;
|
|
5659
|
+
const anthropic = modern.anthropic ?? (legacy.anthropic?.enabled ? {
|
|
5660
|
+
apiKey: legacy.anthropic.apiKey,
|
|
5661
|
+
baseUrl: legacy.anthropic.baseUrl,
|
|
5662
|
+
timeoutMs: legacy.anthropic.timeout,
|
|
5663
|
+
models: legacy.anthropic.models,
|
|
5664
|
+
effort: legacy.anthropic.effort
|
|
5665
|
+
} : void 0);
|
|
5666
|
+
const groq = modern.groq ?? (legacy.groq?.enabled ? {
|
|
5667
|
+
apiKey: legacy.groq.apiKey,
|
|
5668
|
+
baseUrl: legacy.groq.baseUrl,
|
|
5669
|
+
timeoutMs: legacy.groq.timeout,
|
|
5670
|
+
// legacy {text, chat} model pins map onto the neutral tier slots
|
|
5671
|
+
...legacy.groq.models?.text ? { models: { balanced: legacy.groq.models.text } } : {}
|
|
5672
|
+
} : void 0);
|
|
5673
|
+
const gemini = modern.gemini ?? (legacy.gemini?.enabled ? { ...legacy.gemini } : void 0);
|
|
5674
|
+
const fal = modern.fal ?? (legacy.fal?.enabled ? { ...legacy.fal } : void 0);
|
|
5675
|
+
const pruna = modern.pruna ?? (legacy.pruna?.enabled ? { ...legacy.pruna } : void 0);
|
|
5676
|
+
return {
|
|
5677
|
+
priority: modern.priority,
|
|
5678
|
+
fallbackEnabled: modern.fallbackEnabled,
|
|
5679
|
+
defaultTier: modern.defaultTier,
|
|
5680
|
+
...anthropic ? { anthropic } : {},
|
|
5681
|
+
...groq ? { groq } : {},
|
|
5682
|
+
...gemini ? { gemini } : {},
|
|
5683
|
+
...fal ? { fal } : {},
|
|
5684
|
+
...pruna ? { pruna } : {}
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5687
|
+
var buildServices = (configOrGenerator) => {
|
|
5688
|
+
if (isTextGenerator(configOrGenerator)) {
|
|
5689
|
+
const executor2 = new GenerationExecutor(configOrGenerator);
|
|
5690
|
+
const emptyFactory = new ProviderFactory({
|
|
5691
|
+
priority: [],
|
|
5692
|
+
fallbackEnabled: false
|
|
5693
|
+
});
|
|
5694
|
+
return {
|
|
5695
|
+
providerFactory: emptyFactory,
|
|
5696
|
+
blogService: new BlogService(executor2),
|
|
5697
|
+
socialService: new SocialService(executor2),
|
|
5698
|
+
videoScriptService: new VideoScriptService(executor2),
|
|
5699
|
+
analysisService: new AnalysisService(executor2),
|
|
5700
|
+
seoService: new SeoService(executor2),
|
|
5701
|
+
abTestService: new ABTestService(executor2),
|
|
5702
|
+
imagePromptService: new ImagePromptService(executor2),
|
|
5703
|
+
contentCalendarService: new ContentCalendarService(executor2),
|
|
5704
|
+
mediaGenerationService: new MediaGenerationService(emptyFactory)
|
|
5705
|
+
};
|
|
5706
|
+
}
|
|
5707
|
+
const factory = createAI(toAIProviderConfig(configOrGenerator));
|
|
5708
|
+
const executor = new GenerationExecutor(factory);
|
|
5709
|
+
return {
|
|
5710
|
+
providerFactory: factory,
|
|
5711
|
+
blogService: new BlogService(executor),
|
|
5712
|
+
socialService: new SocialService(executor),
|
|
5713
|
+
videoScriptService: new VideoScriptService(executor),
|
|
5714
|
+
analysisService: new AnalysisService(executor),
|
|
5715
|
+
seoService: new SeoService(executor),
|
|
5716
|
+
abTestService: new ABTestService(executor),
|
|
5717
|
+
imagePromptService: new ImagePromptService(executor),
|
|
5718
|
+
contentCalendarService: new ContentCalendarService(executor),
|
|
5719
|
+
mediaGenerationService: new MediaGenerationService(factory)
|
|
5720
|
+
};
|
|
5721
|
+
};
|
|
5722
|
+
var AIContentService = class {
|
|
5723
|
+
providerFactory;
|
|
5724
|
+
blogService;
|
|
5725
|
+
socialService;
|
|
5726
|
+
videoScriptService;
|
|
5727
|
+
analysisService;
|
|
5728
|
+
seoService;
|
|
5729
|
+
abTestService;
|
|
5730
|
+
imagePromptService;
|
|
5731
|
+
contentCalendarService;
|
|
5732
|
+
mediaGenerationService;
|
|
5733
|
+
constructor(configOrGenerator) {
|
|
5734
|
+
const bundle = buildServices(configOrGenerator);
|
|
5735
|
+
this.providerFactory = bundle.providerFactory;
|
|
5736
|
+
this.blogService = bundle.blogService;
|
|
5737
|
+
this.socialService = bundle.socialService;
|
|
5738
|
+
this.videoScriptService = bundle.videoScriptService;
|
|
5739
|
+
this.analysisService = bundle.analysisService;
|
|
5740
|
+
this.seoService = bundle.seoService;
|
|
5741
|
+
this.abTestService = bundle.abTestService;
|
|
5742
|
+
this.imagePromptService = bundle.imagePromptService;
|
|
5743
|
+
this.contentCalendarService = bundle.contentCalendarService;
|
|
5744
|
+
this.mediaGenerationService = bundle.mediaGenerationService;
|
|
5745
|
+
}
|
|
5746
|
+
/** The composed factory — chat()/chatStream() with usage, health, fallback. */
|
|
5747
|
+
get providers() {
|
|
5748
|
+
return this.providerFactory;
|
|
5749
|
+
}
|
|
5750
|
+
generateBlogPost(request) {
|
|
5751
|
+
return this.blogService.generateBlogPost(request);
|
|
5752
|
+
}
|
|
5753
|
+
generateSocialContent(request) {
|
|
5754
|
+
return this.socialService.generateSocialContent(request);
|
|
5755
|
+
}
|
|
5756
|
+
generateForAllPlatforms(topic, tone) {
|
|
5757
|
+
return this.socialService.generateForAllPlatforms(topic, tone);
|
|
5758
|
+
}
|
|
5759
|
+
generateHashtags(content, count) {
|
|
5760
|
+
return this.socialService.generateHashtags(content, count);
|
|
5761
|
+
}
|
|
5762
|
+
optimizeHashtags(hashtags, platform) {
|
|
5763
|
+
return Promise.resolve(this.socialService.optimizeHashtags(hashtags, platform));
|
|
5764
|
+
}
|
|
5765
|
+
generateVideoScript(request) {
|
|
5766
|
+
return this.videoScriptService.generateVideoScript(request);
|
|
5767
|
+
}
|
|
5768
|
+
generateVoiceScript(topic, emotion, duration) {
|
|
5769
|
+
return this.videoScriptService.generateVoiceScript(topic, emotion, duration);
|
|
5770
|
+
}
|
|
5771
|
+
generateContentCalendar(niche, days) {
|
|
5772
|
+
return this.contentCalendarService.generateContentCalendar(niche, days);
|
|
5773
|
+
}
|
|
5774
|
+
analyzeSentiment(content) {
|
|
5775
|
+
return this.analysisService.analyzeSentiment(content);
|
|
5776
|
+
}
|
|
5777
|
+
analyzeContent(request) {
|
|
5778
|
+
return this.analysisService.analyzeContent(request);
|
|
5779
|
+
}
|
|
5780
|
+
optimizeSEO(request) {
|
|
5781
|
+
return this.seoService.optimizeSEO(request);
|
|
5782
|
+
}
|
|
5783
|
+
calculateSEOScore(content, keywords) {
|
|
5784
|
+
return this.seoService.calculateSEOScore(content, keywords);
|
|
5785
|
+
}
|
|
5786
|
+
analyzeKeywords(content, keywords) {
|
|
5787
|
+
return Promise.resolve(this.seoService.analyzeKeywords(content, keywords));
|
|
5788
|
+
}
|
|
5789
|
+
predictABTest(request) {
|
|
5790
|
+
return this.abTestService.predictABTest(request);
|
|
5791
|
+
}
|
|
5792
|
+
compareVariants(variantA, variantB) {
|
|
5793
|
+
return this.abTestService.compareVariants(variantA, variantB);
|
|
5794
|
+
}
|
|
5795
|
+
generateImagePrompt(description, style) {
|
|
5796
|
+
return this.imagePromptService.generateImagePrompt(description, style);
|
|
5797
|
+
}
|
|
5798
|
+
generateImagePromptsForBlog(blogContent) {
|
|
5799
|
+
return this.imagePromptService.generateImagePromptsForBlog(blogContent);
|
|
5800
|
+
}
|
|
5801
|
+
generateImage(request) {
|
|
5802
|
+
return this.mediaGenerationService.generateImage(request);
|
|
5803
|
+
}
|
|
5804
|
+
generateVideo(request) {
|
|
5805
|
+
return this.mediaGenerationService.generateVideo(request);
|
|
5806
|
+
}
|
|
5807
|
+
convertImageToVideo(request) {
|
|
5808
|
+
return this.mediaGenerationService.convertImageToVideo(request);
|
|
5809
|
+
}
|
|
5810
|
+
transformVideo(request) {
|
|
5811
|
+
return this.mediaGenerationService.transformVideo(request);
|
|
5812
|
+
}
|
|
5813
|
+
};
|
|
5814
|
+
|
|
5815
|
+
// src/wizard/content.wizard.ts
|
|
5816
|
+
var CONTENT_WIZARD_STEPS = [
|
|
5817
|
+
{
|
|
5818
|
+
id: "select-type",
|
|
5819
|
+
label: "Select Type",
|
|
5820
|
+
icon: "Layers",
|
|
5821
|
+
description: "Choose the type of content you want to generate",
|
|
5822
|
+
validate: (data) => Boolean(data.contentType)
|
|
5823
|
+
},
|
|
5824
|
+
{
|
|
5825
|
+
id: "input-topic",
|
|
5826
|
+
label: "Topic",
|
|
5827
|
+
icon: "Lightbulb",
|
|
5828
|
+
description: "Enter your topic or idea",
|
|
5829
|
+
validate: (data) => {
|
|
5830
|
+
const topic = data.topic;
|
|
5831
|
+
return typeof topic === "string" && topic.length > 0;
|
|
5832
|
+
}
|
|
5833
|
+
},
|
|
5834
|
+
{
|
|
5835
|
+
id: "configure",
|
|
5836
|
+
label: "Configure",
|
|
5837
|
+
icon: "Settings",
|
|
5838
|
+
description: "Set tone, audience, and platform",
|
|
5839
|
+
validate: (data) => {
|
|
5840
|
+
const d = data;
|
|
5841
|
+
return Boolean(d.tone && d.targetAudience);
|
|
5842
|
+
}
|
|
5843
|
+
},
|
|
5844
|
+
{
|
|
5845
|
+
id: "advanced",
|
|
5846
|
+
label: "Advanced",
|
|
5847
|
+
icon: "Sliders",
|
|
5848
|
+
description: "Additional options and optimizations",
|
|
5849
|
+
optional: true
|
|
5850
|
+
},
|
|
5851
|
+
{
|
|
5852
|
+
id: "preview",
|
|
5853
|
+
label: "Preview",
|
|
5854
|
+
icon: "Eye",
|
|
5855
|
+
description: "Review your settings before generation"
|
|
5856
|
+
},
|
|
5857
|
+
{
|
|
5858
|
+
id: "generating",
|
|
5859
|
+
label: "Generating",
|
|
5860
|
+
icon: "Sparkles",
|
|
5861
|
+
description: "AI is generating your content"
|
|
5862
|
+
},
|
|
5863
|
+
{
|
|
5864
|
+
id: "results",
|
|
5865
|
+
label: "Results",
|
|
5866
|
+
icon: "CheckCircle",
|
|
5867
|
+
description: "Your generated content is ready"
|
|
5868
|
+
}
|
|
5869
|
+
];
|
|
5870
|
+
function buildContentRequest(data) {
|
|
5871
|
+
switch (data.contentType) {
|
|
5872
|
+
case "blog":
|
|
5873
|
+
return {
|
|
5874
|
+
topic: data.topic ?? "",
|
|
5875
|
+
blogType: "tutorial",
|
|
5876
|
+
targetKeywords: data.keywords ?? [],
|
|
5877
|
+
tone: data.tone ?? "professional",
|
|
5878
|
+
wordCount: data.wordCount ?? 1e3,
|
|
5879
|
+
targetAudience: data.targetAudience ?? "",
|
|
5880
|
+
seoOptimization: data.seoOptimization ?? false,
|
|
5881
|
+
includeImages: data.includeImages ?? false,
|
|
5882
|
+
includeSchema: false
|
|
5883
|
+
};
|
|
5884
|
+
case "social":
|
|
5885
|
+
return {
|
|
5886
|
+
topic: data.topic ?? "",
|
|
5887
|
+
platform: data.platform ?? "twitter",
|
|
5888
|
+
tone: data.tone ?? "casual",
|
|
5889
|
+
hashtags: true,
|
|
5890
|
+
targetAudience: data.targetAudience,
|
|
5891
|
+
includeCallToAction: data.includeCallToAction
|
|
5892
|
+
};
|
|
5893
|
+
case "script":
|
|
5894
|
+
return {
|
|
5895
|
+
topic: data.topic ?? "",
|
|
5896
|
+
tone: data.tone ?? "professional",
|
|
5897
|
+
duration: data.duration ?? 60,
|
|
5898
|
+
targetAudience: data.targetAudience ?? "",
|
|
5899
|
+
includeVisuals: true,
|
|
5900
|
+
includeCallToAction: data.includeCallToAction ?? false
|
|
5901
|
+
};
|
|
5902
|
+
default:
|
|
5903
|
+
throw new Error(`Unsupported content type: ${data.contentType}`);
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
|
|
5907
|
+
// src/wizard/image.wizard.ts
|
|
5908
|
+
var IMAGE_WIZARD_STEPS = [
|
|
5909
|
+
{
|
|
5910
|
+
id: "input-prompt",
|
|
5911
|
+
label: "Describe Image",
|
|
5912
|
+
icon: "Image",
|
|
5913
|
+
description: "Describe the image you want to create",
|
|
5914
|
+
validate: (data) => {
|
|
5915
|
+
const prompt = data.prompt;
|
|
5916
|
+
return typeof prompt === "string" && prompt.length > 0;
|
|
5917
|
+
}
|
|
5918
|
+
},
|
|
5919
|
+
{
|
|
5920
|
+
id: "select-style",
|
|
5921
|
+
label: "Style",
|
|
5922
|
+
icon: "Palette",
|
|
5923
|
+
description: "Choose the artistic style",
|
|
5924
|
+
validate: (data) => Boolean(data.style)
|
|
5925
|
+
},
|
|
5926
|
+
{
|
|
5927
|
+
id: "configure",
|
|
5928
|
+
label: "Configure",
|
|
5929
|
+
icon: "Settings",
|
|
5930
|
+
description: "Set format, quality, and quantity",
|
|
5931
|
+
validate: (data) => {
|
|
5932
|
+
const d = data;
|
|
5933
|
+
return Boolean(d.format && d.quality);
|
|
5934
|
+
}
|
|
5935
|
+
},
|
|
5936
|
+
{
|
|
5937
|
+
id: "advanced",
|
|
5938
|
+
label: "Advanced",
|
|
5939
|
+
icon: "Sliders",
|
|
5940
|
+
description: "Color palette and platform optimization",
|
|
5941
|
+
optional: true
|
|
5942
|
+
},
|
|
5943
|
+
{ id: "preview", label: "Preview", icon: "Eye", description: "Review your settings" },
|
|
5944
|
+
{ id: "generating", label: "Generating", icon: "Sparkles", description: "AI is creating your image" },
|
|
5945
|
+
{ id: "results", label: "Results", icon: "Image", description: "Your generated image is ready" }
|
|
5946
|
+
];
|
|
5947
|
+
function buildImageRequest(data) {
|
|
5948
|
+
return {
|
|
5949
|
+
type: "image",
|
|
5950
|
+
prompt: data.prompt ?? "",
|
|
5951
|
+
style: data.style,
|
|
5952
|
+
format: data.format,
|
|
5953
|
+
quality: data.quality,
|
|
5954
|
+
quantity: data.quantity ?? 1
|
|
5955
|
+
};
|
|
5956
|
+
}
|
|
5957
|
+
|
|
5958
|
+
// src/wizard/video.wizard.ts
|
|
5959
|
+
var validateSource = (data) => {
|
|
5960
|
+
const d = data;
|
|
5961
|
+
if (d.generationType === "text-to-video") {
|
|
5962
|
+
return typeof d.prompt === "string" && d.prompt.length > 0;
|
|
5963
|
+
}
|
|
5964
|
+
if (d.generationType === "image-to-video") {
|
|
5965
|
+
return typeof d.imageUrl === "string" && d.imageUrl.length > 0;
|
|
5966
|
+
}
|
|
5967
|
+
if (d.generationType === "video-to-video") {
|
|
5968
|
+
return typeof d.sourceVideoUrl === "string" && d.sourceVideoUrl.length > 0 && typeof d.prompt === "string" && d.prompt.length > 0;
|
|
5969
|
+
}
|
|
5970
|
+
return false;
|
|
5971
|
+
};
|
|
5972
|
+
var VIDEO_WIZARD_STEPS = [
|
|
5973
|
+
{
|
|
5974
|
+
id: "select-type",
|
|
5975
|
+
label: "Select Type",
|
|
5976
|
+
icon: "Video",
|
|
5977
|
+
description: "Choose video generation type",
|
|
5978
|
+
validate: (data) => Boolean(data.generationType)
|
|
5979
|
+
},
|
|
5980
|
+
{
|
|
5981
|
+
id: "input-source",
|
|
5982
|
+
label: "Source",
|
|
5983
|
+
icon: "FileInput",
|
|
5984
|
+
description: "Provide your source (prompt, image, or video)",
|
|
5985
|
+
validate: validateSource
|
|
5986
|
+
},
|
|
5987
|
+
{
|
|
5988
|
+
id: "configure",
|
|
5989
|
+
label: "Configure",
|
|
5990
|
+
icon: "Settings",
|
|
5991
|
+
description: "Set duration, aspect ratio, and style",
|
|
5992
|
+
validate: (data) => {
|
|
5993
|
+
const d = data;
|
|
5994
|
+
return Boolean(d.duration && d.aspectRatio);
|
|
5995
|
+
}
|
|
5996
|
+
},
|
|
5997
|
+
{ id: "advanced", label: "Advanced", icon: "Sliders", description: "Additional video options", optional: true },
|
|
5998
|
+
{ id: "preview", label: "Preview", icon: "Eye", description: "Review your settings" },
|
|
5999
|
+
{ id: "generating", label: "Generating", icon: "Sparkles", description: "AI is creating your video" },
|
|
6000
|
+
{ id: "results", label: "Results", icon: "Video", description: "Your generated video is ready" }
|
|
6001
|
+
];
|
|
6002
|
+
function buildVideoRequest(data) {
|
|
6003
|
+
switch (data.generationType) {
|
|
6004
|
+
case "text-to-video":
|
|
6005
|
+
return {
|
|
6006
|
+
type: "video",
|
|
6007
|
+
prompt: data.prompt ?? "",
|
|
6008
|
+
duration: data.duration ?? 5,
|
|
6009
|
+
aspectRatio: data.aspectRatio ?? "16:9",
|
|
6010
|
+
style: data.style,
|
|
6011
|
+
quality: data.quality
|
|
6012
|
+
};
|
|
6013
|
+
case "image-to-video":
|
|
6014
|
+
return {
|
|
6015
|
+
type: "video",
|
|
6016
|
+
imageUrl: data.imageUrl ?? "",
|
|
6017
|
+
prompt: data.prompt,
|
|
6018
|
+
duration: data.duration ?? 5,
|
|
6019
|
+
motion: data.motion ?? "medium",
|
|
6020
|
+
camera: data.camera ?? "static"
|
|
6021
|
+
};
|
|
6022
|
+
case "video-to-video":
|
|
6023
|
+
return {
|
|
6024
|
+
type: "video",
|
|
6025
|
+
sourceVideoUrl: data.sourceVideoUrl ?? "",
|
|
6026
|
+
prompt: data.prompt ?? "",
|
|
6027
|
+
styleTransfer: data.styleTransfer,
|
|
6028
|
+
enhanceQuality: data.enhanceQuality
|
|
6029
|
+
};
|
|
6030
|
+
default:
|
|
6031
|
+
throw new Error(`Unsupported generation type: ${data.generationType}`);
|
|
6032
|
+
}
|
|
6033
|
+
}
|
|
6034
|
+
|
|
6035
|
+
exports.ABTestService = ABTestService;
|
|
6036
|
+
exports.AIContentService = AIContentService;
|
|
4360
6037
|
exports.AIError = AIError;
|
|
4361
6038
|
exports.AIErrorType = AIErrorType;
|
|
4362
6039
|
exports.ANTHROPIC_API_VERSION = ANTHROPIC_API_VERSION;
|
|
@@ -4364,16 +6041,23 @@ exports.ANTHROPIC_DEFAULT_MAX_TOKENS = ANTHROPIC_DEFAULT_MAX_TOKENS;
|
|
|
4364
6041
|
exports.ANTHROPIC_MODELS = ANTHROPIC_MODELS;
|
|
4365
6042
|
exports.ANTHROPIC_TIERS = ANTHROPIC_TIERS;
|
|
4366
6043
|
exports.API_ENDPOINTS = API_ENDPOINTS;
|
|
6044
|
+
exports.ASPECT_RATIO_OPTIONS = ASPECT_RATIO_OPTIONS;
|
|
6045
|
+
exports.ASPECT_RATIO_VALUES = ASPECT_RATIO_VALUES;
|
|
6046
|
+
exports.AnalysisService = AnalysisService;
|
|
4367
6047
|
exports.AnthropicHttpTransport = AnthropicHttpTransport;
|
|
4368
6048
|
exports.AnthropicProvider = AnthropicProvider;
|
|
4369
6049
|
exports.AnthropicRequestBuilder = AnthropicRequestBuilder;
|
|
4370
6050
|
exports.AuthenticationError = AuthenticationError;
|
|
6051
|
+
exports.BaseAIProvider = BaseProvider;
|
|
4371
6052
|
exports.BaseProvider = BaseProvider;
|
|
6053
|
+
exports.BlogService = BlogService;
|
|
6054
|
+
exports.CONTENT_WIZARD_STEPS = CONTENT_WIZARD_STEPS;
|
|
4372
6055
|
exports.CacheManager = CacheManager;
|
|
4373
6056
|
exports.CancellationError = CancellationError;
|
|
4374
6057
|
exports.ChatIdGenerator = ChatIdGenerator;
|
|
4375
6058
|
exports.ChatService = ChatService;
|
|
4376
6059
|
exports.CompositeExecutor = CompositeExecutor;
|
|
6060
|
+
exports.ContentCalendarService = ContentCalendarService;
|
|
4377
6061
|
exports.DEFAULT_API_KEY_RULE = DEFAULT_API_KEY_RULE;
|
|
4378
6062
|
exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
|
|
4379
6063
|
exports.DEFAULT_ERROR_CLASSIFICATION_RULE = DEFAULT_ERROR_CLASSIFICATION_RULE;
|
|
@@ -4390,9 +6074,11 @@ exports.DebounceManager = DebounceManager;
|
|
|
4390
6074
|
exports.DedupeExecutor = DedupeExecutor;
|
|
4391
6075
|
exports.FalProvider = FalProvider;
|
|
4392
6076
|
exports.GEMINI_TIERS = GEMINI_TIERS;
|
|
6077
|
+
exports.GENERATION_COSTS = CREDIT_COSTS;
|
|
4393
6078
|
exports.GROQ_MODELS = GROQ_MODELS;
|
|
4394
6079
|
exports.GROQ_TIERS = GROQ_TIERS;
|
|
4395
6080
|
exports.GeminiProvider = GeminiProvider;
|
|
6081
|
+
exports.GenerationExecutor = GenerationExecutor;
|
|
4396
6082
|
exports.GenerationFailedError = GenerationFailedError;
|
|
4397
6083
|
exports.GroqChatRequestBuilder = GroqChatRequestBuilder;
|
|
4398
6084
|
exports.GroqConfigStore = GroqConfigStore;
|
|
@@ -4401,11 +6087,20 @@ exports.GroqErrorType = AIErrorType;
|
|
|
4401
6087
|
exports.GroqHttpClient = GroqHttpClient;
|
|
4402
6088
|
exports.GroqHttpTransport = GroqHttpTransport;
|
|
4403
6089
|
exports.GroqProvider = GroqProvider;
|
|
6090
|
+
exports.IMAGE_QUALITY_OPTIONS = IMAGE_QUALITY_OPTIONS;
|
|
6091
|
+
exports.IMAGE_QUALITY_VALUES = IMAGE_QUALITY_VALUES;
|
|
6092
|
+
exports.IMAGE_WIZARD_STEPS = IMAGE_WIZARD_STEPS;
|
|
6093
|
+
exports.ImagePromptService = ImagePromptService;
|
|
4404
6094
|
exports.JSON_CODE_BLOCK_PATTERN = JSON_CODE_BLOCK_PATTERN;
|
|
4405
6095
|
exports.JSON_OBJECT_PATTERN = JSON_OBJECT_PATTERN;
|
|
4406
6096
|
exports.JsonResponseParser = JsonResponseParser;
|
|
6097
|
+
exports.MOTION_OPTIONS = MOTION_OPTIONS;
|
|
6098
|
+
exports.MediaGenerationService = MediaGenerationService;
|
|
6099
|
+
exports.PromptBuilder = PromptBuilder;
|
|
4407
6100
|
exports.ProviderError = ProviderError;
|
|
4408
6101
|
exports.ProviderFactory = ProviderFactory;
|
|
6102
|
+
exports.ProviderQuotaExhaustedError = ProviderQuotaExhaustedError;
|
|
6103
|
+
exports.ProviderUnavailableError = ProviderUnavailableError;
|
|
4409
6104
|
exports.PrunaProvider = PrunaProvider;
|
|
4410
6105
|
exports.QueueExecutor = QueueExecutor;
|
|
4411
6106
|
exports.RequestDeduplicator = RequestDeduplicator;
|
|
@@ -4415,6 +6110,9 @@ exports.RetryManager = RetryManager;
|
|
|
4415
6110
|
exports.SSE_BRIDGE_EVENTS = SSE_BRIDGE_EVENTS;
|
|
4416
6111
|
exports.SSE_DONE_MARKER = SSE_DONE_MARKER;
|
|
4417
6112
|
exports.SSE_PREFIX = SSE_PREFIX;
|
|
6113
|
+
exports.STYLE_PRESETS = STYLE_PRESETS;
|
|
6114
|
+
exports.SeoService = SeoService;
|
|
6115
|
+
exports.SocialService = SocialService;
|
|
4418
6116
|
exports.StreamingResponseParser = StreamingResponseParser;
|
|
4419
6117
|
exports.StructuredPromptBuilder = StructuredPromptBuilder;
|
|
4420
6118
|
exports.TEXT_TIERS = TEXT_TIERS;
|
|
@@ -4423,14 +6121,24 @@ exports.TextGenerationService = TextGenerationService;
|
|
|
4423
6121
|
exports.ThrottleManager = ThrottleManager;
|
|
4424
6122
|
exports.TimeoutError = TimeoutError;
|
|
4425
6123
|
exports.USER_FRIENDLY_ERROR_MESSAGES = USER_FRIENDLY_ERROR_MESSAGES;
|
|
4426
|
-
exports.
|
|
6124
|
+
exports.VIDEO_DURATION_OPTIONS = VIDEO_DURATION_OPTIONS;
|
|
6125
|
+
exports.VIDEO_DURATION_OPTIONS_SECONDS = VIDEO_DURATION_OPTIONS_SECONDS;
|
|
6126
|
+
exports.VIDEO_QUALITY_OPTIONS = VIDEO_QUALITY_OPTIONS;
|
|
6127
|
+
exports.VIDEO_QUALITY_VALUES = VIDEO_QUALITY_VALUES;
|
|
6128
|
+
exports.VIDEO_WIZARD_STEPS = VIDEO_WIZARD_STEPS;
|
|
6129
|
+
exports.ValidationError = ValidationError2;
|
|
6130
|
+
exports.VideoScriptService = VideoScriptService;
|
|
4427
6131
|
exports.asObjectArray = asObjectArray;
|
|
4428
6132
|
exports.asRecord = asRecord;
|
|
4429
6133
|
exports.asStringArray = asStringArray;
|
|
4430
6134
|
exports.asTrimmedOptionalString = asTrimmedOptionalString;
|
|
4431
6135
|
exports.buildCacheKey = buildCacheKey;
|
|
6136
|
+
exports.buildContentRequest = buildContentRequest;
|
|
4432
6137
|
exports.buildHttpStatusFallback = buildHttpStatusFallback;
|
|
6138
|
+
exports.buildImageRequest = buildImageRequest;
|
|
6139
|
+
exports.buildVideoRequest = buildVideoRequest;
|
|
4433
6140
|
exports.cacheManager = cacheManager;
|
|
6141
|
+
exports.calculateCreditCost = calculateContentCreditCost;
|
|
4434
6142
|
exports.chatIdGenerator = chatIdGenerator;
|
|
4435
6143
|
exports.clampScore = clampScore;
|
|
4436
6144
|
exports.classifyHttpStatus = classifyHttpStatus;
|
|
@@ -4441,7 +6149,9 @@ exports.createAI = createAI;
|
|
|
4441
6149
|
exports.createAssistantMessage = createAssistantMessage;
|
|
4442
6150
|
exports.createFalProvider = createFalProvider;
|
|
4443
6151
|
exports.createGeminiProvider = createGeminiProvider;
|
|
6152
|
+
exports.createGroqProvider = createGroqProvider;
|
|
4444
6153
|
exports.createMessage = createMessage;
|
|
6154
|
+
exports.createProviderFactory = createProviderFactory;
|
|
4445
6155
|
exports.createPrunaProvider = createPrunaProvider;
|
|
4446
6156
|
exports.createSseResponse = createSseResponse;
|
|
4447
6157
|
exports.createSystemMessage = createSystemMessage;
|
|
@@ -4465,7 +6175,9 @@ exports.formatMessagesForDisplay = formatMessagesForDisplay;
|
|
|
4465
6175
|
exports.generateImageThenVideo = generateImageThenVideo;
|
|
4466
6176
|
exports.generatePruna = generate;
|
|
4467
6177
|
exports.generateWithPruna = generateWithPruna;
|
|
6178
|
+
exports.getDimensionsForAspectRatio = getDimensionsForAspectRatio;
|
|
4468
6179
|
exports.getProvider = getProvider;
|
|
6180
|
+
exports.getRecommendedQuality = getRecommendedQuality;
|
|
4469
6181
|
exports.isAuthErrorType = isAuthErrorType;
|
|
4470
6182
|
exports.isMediaProvider = isMediaProvider;
|
|
4471
6183
|
exports.isRetryableErrorType = isRetryableErrorType;
|