Spaces:
Build error
Build error
import { ClapCompletionMode, ClapProject, fetchClap, filterAssets, isValidNumber, serializeClap, removeGeneratedAssetUrls } from "@aitube/clap" | |
import queryString from "query-string" | |
import { aitubeApiUrl } from "@/constants/config" | |
import { applyClapCompletion } from "@/utils" | |
export async function editClapStory({ | |
clap, | |
prompt, | |
startTimeInMs, | |
endTimeInMs, | |
completionMode = ClapCompletionMode.MERGE, | |
turbo = false, | |
token, | |
}: { | |
// A ClapProject instance | |
clap: ClapProject | |
// a prompt to describe how to extend the story (optional) | |
prompt?: string | |
// indicates where the completion should start in the timeline | |
// | |
// this can be used tp jump to arbitrary timestamps | |
// in the story | |
// | |
// if you pick a start time AFTER the current project's end time, | |
// the project will be extended | |
// | |
// default value: the current project's end time | |
startTimeInMs?: number | |
// it is recommended to use a | |
// end time (eg. startTimeInMs + 12000) | |
// if left by default, th server will generate | |
// | |
// for performance and security reasons, | |
// the server may enforce a hardcoded limit to bypass what you | |
// set here, but that is not a big deal because you can pass | |
// you .clap file again if necessary | |
// | |
// default value: no limit (the server will set one) | |
endTimeInMs?: number | |
/** | |
* Completion mode (optional, defaults to "merge") | |
* | |
* Possible values are: | |
* - full: the API and the client will return a full clap file. This is a very convenient and simple mode, but it is also very ineficient, so it should not be used for intensive applications. | |
* - partial: the API and the client will return a partial clap file, containing only the new values and changes. This is useful for real-time applications and streaming. | |
* - merge: the API will return a partial clap file, and the client will return a merge of the original with the new values. This is safe to run, there are no side-effects. | |
* - replace: the API will return a partial clap file, and the client will replace the original. This is the most efficient mode, but it relies on side-effects and inline object updates. | |
*/ | |
completionMode?: ClapCompletionMode | |
turbo?: boolean | |
token?: string | |
}): Promise<ClapProject> { | |
if (!clap) { throw new Error(`please provide a clap to extend`) } | |
const hasToken = typeof token === "string" && token.length > 0 | |
const params: Record<string, any> = {} | |
if (typeof completionMode === "string") { | |
params.c = completionMode | |
} | |
if (typeof prompt === "string" && prompt.length > 0) { | |
params.p = prompt | |
} | |
if (isValidNumber(startTimeInMs)) { | |
params.s = startTimeInMs | |
} | |
if (isValidNumber(endTimeInMs)) { | |
params.e = endTimeInMs | |
} | |
if (turbo) { | |
params.t = "true" | |
} | |
// we remove heavy elements from the payload | |
const payload = await filterAssets({ | |
clap, | |
mode: "INCLUDE", | |
categories: {}, | |
immutable: true, // to create a standalone copy | |
// we only remove the data, but we still keep things marked as "generated" | |
updateStatus: false, | |
}) | |
const newClap = await fetchClap( | |
`${aitubeApiUrl}edit/story?${queryString.stringify(params)}`, { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/x-gzip", | |
...hasToken && { | |
"Authorization": `Bearer ${token}` | |
} | |
}, | |
body: await serializeClap(removeGeneratedAssetUrls(clap)), | |
cache: "no-store", | |
}) | |
const result = await applyClapCompletion(clap, newClap, completionMode) | |
return result | |
} |