clapper / packages /client /src /api /editClapStory.ts
jbilcke-hf's picture
jbilcke-hf HF Staff
fix issues
6b56adc
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
}