@lingjingai/scriptctl 0.12.0 → 0.12.2
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/domain/direct-core.d.ts +3 -1
- package/dist/domain/direct-core.js +32 -21
- package/dist/domain/direct-core.js.map +1 -1
- package/dist/help-text.js +35 -1
- package/dist/help-text.js.map +1 -1
- package/dist/infra/providers.js +2 -2
- package/dist/infra/providers.js.map +1 -1
- package/dist/usecases/direct.js +147 -62
- package/dist/usecases/direct.js.map +1 -1
- package/package.json +1 -1
|
@@ -49,7 +49,9 @@ export interface ProviderLike {
|
|
|
49
49
|
extractAssetCuration?(sourceText: string, script: Dict): Promise<Dict> | Dict;
|
|
50
50
|
extractEpisodeTitles?(sourceText: string, plan: Dict): Promise<Dict> | Dict;
|
|
51
51
|
}
|
|
52
|
-
export declare
|
|
52
|
+
export declare const DEFAULT_TITLE_CHUNK_SIZE = 10;
|
|
53
|
+
export declare function chunkEpisodesNeedingTitles(episodePlan: Dict, chunkSize: number): Dict[][];
|
|
54
|
+
export declare function applyEpisodeTitlesToPlan(sourceText: string, episodePlan: Dict, generated: Map<number, string>): number[];
|
|
53
55
|
export declare function formatBatchSource(sourceText: string, batchPlan: Dict): string;
|
|
54
56
|
export declare function lineNumberAt(sourceText: string, offset: number): number;
|
|
55
57
|
export declare function batchContextFor(sourceText: string, episode: Dict, start: number): Dict;
|
|
@@ -908,37 +908,48 @@ export function episodeTitleResponseMap(payload) {
|
|
|
908
908
|
}
|
|
909
909
|
return result;
|
|
910
910
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
911
|
+
// Default episodes per title-generation request. Title planning is the only
|
|
912
|
+
// init step that would otherwise bundle EVERY episode's excerpt into a single
|
|
913
|
+
// LLM request — which makes a content filter reject the whole show at once.
|
|
914
|
+
// Chunking bounds the blast radius of any one poisoned excerpt.
|
|
915
|
+
export const DEFAULT_TITLE_CHUNK_SIZE = 10;
|
|
916
|
+
// Split the episodes that still need a generated title into bounded chunks,
|
|
917
|
+
// each suitable for an independent title-generation request.
|
|
918
|
+
export function chunkEpisodesNeedingTitles(episodePlan, chunkSize) {
|
|
919
|
+
const episodes = episodesNeedingGeneratedTitles(episodePlan);
|
|
920
|
+
const size = Math.max(1, Math.floor(chunkSize) || 1);
|
|
921
|
+
const chunks = [];
|
|
922
|
+
for (let i = 0; i < episodes.length; i += size) {
|
|
923
|
+
chunks.push(episodes.slice(i, i + size));
|
|
924
|
+
}
|
|
925
|
+
return chunks;
|
|
926
|
+
}
|
|
927
|
+
// Write generated titles back onto the plan in place. Any episode missing from
|
|
928
|
+
// `generated` (model omitted it, or its request was filtered/failed) degrades
|
|
929
|
+
// to a deterministic title rather than blocking the run. Returns the episode
|
|
930
|
+
// numbers that fell back so callers can report the degradation.
|
|
931
|
+
export function applyEpisodeTitlesToPlan(sourceText, episodePlan, generated) {
|
|
932
|
+
const degraded = [];
|
|
933
|
+
for (const episode of episodesNeedingGeneratedTitles(episodePlan)) {
|
|
929
934
|
const episodeNum = Number(episode["episode"] ?? 0);
|
|
930
|
-
let rawTitle = generated.get(episodeNum)
|
|
935
|
+
let rawTitle = generated.get(episodeNum);
|
|
936
|
+
let fromModel = Boolean(rawTitle);
|
|
937
|
+
if (!rawTitle)
|
|
938
|
+
rawTitle = deterministicEpisodeShortTitle(sourceText, episode);
|
|
931
939
|
let title = formatEpisodeTitle(episodeNum, rawTitle);
|
|
932
940
|
if (!title) {
|
|
941
|
+
fromModel = false;
|
|
933
942
|
rawTitle = deterministicEpisodeShortTitle(sourceText, episode);
|
|
934
943
|
title = formatEpisodeTitle(episodeNum, rawTitle) || `第${episodeNum}集:剧情转折${episodeNum}`;
|
|
935
944
|
}
|
|
936
945
|
episode["generated_title"] = rawTitle;
|
|
937
946
|
episode["title"] = title;
|
|
938
947
|
episode["title_status"] = "generated";
|
|
939
|
-
episode["title_source"] = "generated";
|
|
948
|
+
episode["title_source"] = fromModel ? "generated" : "deterministic";
|
|
949
|
+
if (!fromModel)
|
|
950
|
+
degraded.push(episodeNum);
|
|
940
951
|
}
|
|
941
|
-
return
|
|
952
|
+
return degraded;
|
|
942
953
|
}
|
|
943
954
|
// ---------------------------------------------------------------------------
|
|
944
955
|
// Batch source formatting and planning
|