Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
•
5566043
1
Parent(s):
8951ca1
working on the assistant
Browse files- package-lock.json +0 -0
- package.json +4 -1
- src/app/api/assistant/askAnyAssistant.ts +178 -0
- src/app/api/assistant/providers/openai/askAssistant.ts +1 -6
- src/app/api/assistant/route.TODO +0 -0
- src/app/api/assistant/route.ts +17 -0
- src/app/api/resolve/route.ts +1 -1
- src/app/main.tsx +24 -15
- src/components/assistant/ChatView.tsx +2 -157
- src/components/settings/constants.ts +72 -9
- src/components/toolbars/top-menu/assistant/index.tsx +45 -0
- src/components/toolbars/top-menu/index.tsx +2 -0
- src/components/toolbars/top-menu/lists/AssistantModelList.tsx +55 -0
- src/components/toolbars/top-menu/music/index.tsx +5 -0
- src/components/toolbars/top-menu/sound/index.tsx +4 -0
- src/components/toolbars/top-menu/view/index.tsx +2 -0
- src/controllers/assistant/askAssistant.ts +14 -0
- src/controllers/assistant/types.ts +4 -1
- src/controllers/assistant/useAssistant.ts +157 -3
- src/controllers/metrics/constants.ts +18 -0
- src/controllers/metrics/getDefaultMetricsPerProvider.ts +18 -0
- src/controllers/metrics/useMetrics.ts +1 -1
- src/controllers/resolver/useResolver.ts +3 -3
- src/controllers/settings/getDefaultSettingsState.ts +15 -0
- src/controllers/settings/types.ts +33 -1
- src/controllers/settings/useSettings.ts +52 -0
- src/lib/utils/parseComputeProvider.ts +3 -0
- src/types.ts +6 -0
package-lock.json
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
package.json
CHANGED
@@ -12,13 +12,16 @@
|
|
12 |
"dependencies": {
|
13 |
"@aitube/clap": "0.0.26",
|
14 |
"@aitube/engine": "0.0.19",
|
15 |
-
"@aitube/timeline": "
|
16 |
"@fal-ai/serverless-client": "^0.10.3",
|
17 |
"@huggingface/hub": "^0.15.1",
|
18 |
"@huggingface/inference": "^2.7.0",
|
19 |
"@langchain/anthropic": "^0.2.0",
|
|
|
20 |
"@langchain/core": "^0.2.6",
|
|
|
21 |
"@langchain/groq": "^0.0.12",
|
|
|
22 |
"@langchain/openai": "^0.1.1",
|
23 |
"@monaco-editor/react": "^4.6.0",
|
24 |
"@radix-ui/react-accordion": "^1.1.2",
|
|
|
12 |
"dependencies": {
|
13 |
"@aitube/clap": "0.0.26",
|
14 |
"@aitube/engine": "0.0.19",
|
15 |
+
"@aitube/timeline": "file:/Users/jbilcke/Projects/Typescript_Libraries/aitube-timeline",
|
16 |
"@fal-ai/serverless-client": "^0.10.3",
|
17 |
"@huggingface/hub": "^0.15.1",
|
18 |
"@huggingface/inference": "^2.7.0",
|
19 |
"@langchain/anthropic": "^0.2.0",
|
20 |
+
"@langchain/cohere": "^0.0.11",
|
21 |
"@langchain/core": "^0.2.6",
|
22 |
+
"@langchain/google-vertexai": "^0.0.18",
|
23 |
"@langchain/groq": "^0.0.12",
|
24 |
+
"@langchain/mistralai": "^0.0.24",
|
25 |
"@langchain/openai": "^0.1.1",
|
26 |
"@monaco-editor/react": "^4.6.0",
|
27 |
"@radix-ui/react-accordion": "^1.1.2",
|
src/app/api/assistant/askAnyAssistant.ts
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use server"
|
2 |
+
|
3 |
+
import { ClapSegmentCategory } from "@aitube/clap"
|
4 |
+
import { RunnableLike } from "@langchain/core/runnables"
|
5 |
+
import { ChatPromptValueInterface } from "@langchain/core/dist/prompt_values"
|
6 |
+
import { AIMessageChunk } from "@langchain/core/messages"
|
7 |
+
import { ChatPromptTemplate } from "@langchain/core/prompts"
|
8 |
+
import { StructuredOutputParser } from "@langchain/core/output_parsers"
|
9 |
+
import { ChatOpenAI } from "@langchain/openai"
|
10 |
+
import { ChatGroq } from "@langchain/groq"
|
11 |
+
import { ChatAnthropic } from "@langchain/anthropic"
|
12 |
+
import { ChatCohere } from "@langchain/cohere"
|
13 |
+
import { ChatMistralAI } from "@langchain/mistralai"
|
14 |
+
import { ChatVertexAI } from "@langchain/google-vertexai"
|
15 |
+
// Hugging Face will be supported once the following package becomes available
|
16 |
+
// import { ChatHuggingFace } from "@langchain/huggingface"
|
17 |
+
|
18 |
+
import { AssistantRequest, AssistantResponse, ComputeProvider } from "@/types"
|
19 |
+
|
20 |
+
import { SimplifiedSegmentData, simplifiedSegmentDataZ } from "./types"
|
21 |
+
import { examples, humanTemplate, systemTemplate } from "./templates"
|
22 |
+
|
23 |
+
const parser = StructuredOutputParser.fromZodSchema(simplifiedSegmentDataZ)
|
24 |
+
|
25 |
+
const formatInstructions = parser.getFormatInstructions()
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Query the preferred language model on the user prompt + the segments of the current scene
|
29 |
+
*
|
30 |
+
* @param userPrompt
|
31 |
+
* @param segments
|
32 |
+
* @returns
|
33 |
+
*/
|
34 |
+
export async function askAnyAssistant({
|
35 |
+
settings,
|
36 |
+
|
37 |
+
prompt,
|
38 |
+
|
39 |
+
// the slice to edit
|
40 |
+
segments = [],
|
41 |
+
|
42 |
+
fullScene = "",
|
43 |
+
|
44 |
+
actionLine = "",
|
45 |
+
|
46 |
+
// used to provide more context
|
47 |
+
entities = {},
|
48 |
+
|
49 |
+
// used to provide more context
|
50 |
+
projectInfo = ""
|
51 |
+
}: AssistantRequest): Promise<AssistantResponse> {
|
52 |
+
|
53 |
+
const provider = settings.assistantProvider
|
54 |
+
|
55 |
+
if (!provider) { throw new Error(`Missing assistant provider`)}
|
56 |
+
|
57 |
+
let coerceable: undefined | RunnableLike<ChatPromptValueInterface, AIMessageChunk> =
|
58 |
+
provider === ComputeProvider.GROQ
|
59 |
+
? new ChatGroq({
|
60 |
+
apiKey: settings.groqApiKey,
|
61 |
+
modelName: settings.groqModelForAssistant,
|
62 |
+
// temperature: 0.7,
|
63 |
+
})
|
64 |
+
: provider === ComputeProvider.OPENAI
|
65 |
+
? new ChatOpenAI({
|
66 |
+
openAIApiKey: settings.openaiApiKey,
|
67 |
+
modelName: settings.openaiModelForAssistant,
|
68 |
+
// temperature: 0.7,
|
69 |
+
})
|
70 |
+
: provider === ComputeProvider.ANTHROPIC
|
71 |
+
? new ChatAnthropic({
|
72 |
+
anthropicApiKey: settings.anthropicApiKey,
|
73 |
+
modelName: settings.anthropicModelForAssistant,
|
74 |
+
// temperature: 0.7,
|
75 |
+
})
|
76 |
+
: provider === ComputeProvider.COHERE
|
77 |
+
? new ChatCohere({
|
78 |
+
apiKey: settings.cohereApiKey,
|
79 |
+
model: settings.cohereModelForAssistant,
|
80 |
+
// temperature: 0.7,
|
81 |
+
})
|
82 |
+
: provider === ComputeProvider.MISTRALAI
|
83 |
+
? new ChatMistralAI({
|
84 |
+
apiKey: settings.mistralAiApiKey,
|
85 |
+
modelName: settings.mistralAiModelForAssistant,
|
86 |
+
// temperature: 0.7,
|
87 |
+
})
|
88 |
+
: provider === ComputeProvider.GOOGLE
|
89 |
+
? new ChatVertexAI({
|
90 |
+
apiKey: settings.googleApiKey,
|
91 |
+
modelName: settings.googleModelForAssistant,
|
92 |
+
// temperature: 0.7,
|
93 |
+
})
|
94 |
+
: undefined
|
95 |
+
|
96 |
+
if (!coerceable) { throw new Error(`Provider ${provider} is not supported yet. If a LangChain bridge exists for this provider, then you can add it to Clapper.`)}
|
97 |
+
|
98 |
+
const chatPrompt = ChatPromptTemplate.fromMessages(
|
99 |
+
[
|
100 |
+
["system", systemTemplate],
|
101 |
+
["human", humanTemplate],
|
102 |
+
]
|
103 |
+
)
|
104 |
+
|
105 |
+
// we don't give the whole thing to the LLM as to not confuse it,
|
106 |
+
// and also to keep things tight and performant
|
107 |
+
const inputData: SimplifiedSegmentData[] = segments.map((segment) => ({
|
108 |
+
prompt: segment.prompt,
|
109 |
+
category: segment.category,
|
110 |
+
} as SimplifiedSegmentData))
|
111 |
+
|
112 |
+
// console.log("INPUT:", JSON.stringify(inputData, null, 2))
|
113 |
+
|
114 |
+
const chain = chatPrompt.pipe(coerceable).pipe(parser)
|
115 |
+
|
116 |
+
try {
|
117 |
+
const result = await chain.invoke({
|
118 |
+
formatInstructions,
|
119 |
+
examples,
|
120 |
+
projectInfo,
|
121 |
+
fullScene,
|
122 |
+
actionLine,
|
123 |
+
userPrompt: prompt,
|
124 |
+
inputData,
|
125 |
+
})
|
126 |
+
|
127 |
+
console.log("OUTPUT:", JSON.stringify(result, null, 2))
|
128 |
+
|
129 |
+
/*
|
130 |
+
this whole code doesn't work well actually..
|
131 |
+
|
132 |
+
let match: SegmentData | undefined = segments[result.index] || undefined
|
133 |
+
|
134 |
+
// LLM gave an object, but the index is wrong
|
135 |
+
if (!match) {
|
136 |
+
match = segments.find(s => s.category === result.category) || undefined
|
137 |
+
}
|
138 |
+
*/
|
139 |
+
|
140 |
+
// let's create a new segment then!
|
141 |
+
const categoryName: ClapSegmentCategory =
|
142 |
+
result?.category && Object.keys(ClapSegmentCategory).includes(result.category.toUpperCase())
|
143 |
+
? (result.category as ClapSegmentCategory)
|
144 |
+
: ClapSegmentCategory.GENERIC
|
145 |
+
|
146 |
+
return {
|
147 |
+
prompt: result?.prompt || "",
|
148 |
+
categoryName,
|
149 |
+
llmOutput: "",
|
150 |
+
}
|
151 |
+
} catch (err1) {
|
152 |
+
|
153 |
+
// a common scenario is when the output from the LLM is just not a JSON
|
154 |
+
// this can happen quite often, for instance if the user tried to bypass
|
155 |
+
// our prompt, or if they are just asking generic questions
|
156 |
+
const errObj = err1 as any
|
157 |
+
try {
|
158 |
+
const keys = Object.keys(errObj)
|
159 |
+
// console.log("keys:", keys)
|
160 |
+
if (errObj.llmOutput) {
|
161 |
+
return {
|
162 |
+
prompt: "",
|
163 |
+
categoryName: ClapSegmentCategory.GENERIC,
|
164 |
+
llmOutput: `${errObj.llmOutput || ""}`,
|
165 |
+
}
|
166 |
+
}
|
167 |
+
} catch (err2) {
|
168 |
+
// err2 is just the error for when the LLM failed to reply
|
169 |
+
console.error(`----<${err1}>----`)
|
170 |
+
}
|
171 |
+
|
172 |
+
return {
|
173 |
+
prompt: "",
|
174 |
+
categoryName: ClapSegmentCategory.GENERIC,
|
175 |
+
llmOutput: ""
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
src/app/api/assistant/providers/openai/askAssistant.ts
CHANGED
@@ -9,19 +9,17 @@ import { AssistantRequest, AssistantResponse } from "@/types"
|
|
9 |
import { SimplifiedSegmentData, simplifiedSegmentDataZ } from "../../types"
|
10 |
import { examples, humanTemplate, systemTemplate } from "../../templates"
|
11 |
|
12 |
-
|
13 |
const parser = StructuredOutputParser.fromZodSchema(simplifiedSegmentDataZ)
|
14 |
|
15 |
const formatInstructions = parser.getFormatInstructions()
|
16 |
|
17 |
-
|
18 |
/**
|
19 |
* Query the preferred language model on the user prompt + the segments of the current scene
|
20 |
* @param userPrompt
|
21 |
* @param segments
|
22 |
* @returns
|
23 |
*/
|
24 |
-
export async function
|
25 |
settings,
|
26 |
|
27 |
prompt,
|
@@ -54,9 +52,6 @@ export async function queryAssistant({
|
|
54 |
]
|
55 |
)
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
// we don't give the whole thing to the LLM as to not confuse it,
|
61 |
// and also to keep things tight and performant
|
62 |
const inputData: SimplifiedSegmentData[] = segments.map((segment) => ({
|
|
|
9 |
import { SimplifiedSegmentData, simplifiedSegmentDataZ } from "../../types"
|
10 |
import { examples, humanTemplate, systemTemplate } from "../../templates"
|
11 |
|
|
|
12 |
const parser = StructuredOutputParser.fromZodSchema(simplifiedSegmentDataZ)
|
13 |
|
14 |
const formatInstructions = parser.getFormatInstructions()
|
15 |
|
|
|
16 |
/**
|
17 |
* Query the preferred language model on the user prompt + the segments of the current scene
|
18 |
* @param userPrompt
|
19 |
* @param segments
|
20 |
* @returns
|
21 |
*/
|
22 |
+
export async function askAssistant({
|
23 |
settings,
|
24 |
|
25 |
prompt,
|
|
|
52 |
]
|
53 |
)
|
54 |
|
|
|
|
|
|
|
55 |
// we don't give the whole thing to the LLM as to not confuse it,
|
56 |
// and also to keep things tight and performant
|
57 |
const inputData: SimplifiedSegmentData[] = segments.map((segment) => ({
|
src/app/api/assistant/route.TODO
DELETED
File without changes
|
src/app/api/assistant/route.ts
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { NextResponse, NextRequest } from "next/server"
|
2 |
+
|
3 |
+
import { AssistantRequest, AssistantResponse } from "@/types"
|
4 |
+
import { askAnyAssistant } from "./askAnyAssistant"
|
5 |
+
|
6 |
+
export async function POST(req: NextRequest) {
|
7 |
+
// do we really need to secure it?
|
8 |
+
// I mean.. in the end, the user is using their own credentials,
|
9 |
+
// so they cannot siphon free OpenAI, HF, Replicate tokens
|
10 |
+
// console.log(`TODO Julian: secure the endpoint`)
|
11 |
+
// await throwIfInvalidToken(req.headers.get("Authorization"))
|
12 |
+
const request = (await req.json()) as AssistantRequest
|
13 |
+
|
14 |
+
const response: AssistantResponse = await askAnyAssistant(request)
|
15 |
+
|
16 |
+
return NextResponse.json(response)
|
17 |
+
}
|
src/app/api/resolve/route.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import { NextResponse, NextRequest } from "next/server"
|
|
|
2 |
|
3 |
import { resolveSegment as resolveSegmentUsingHuggingFace } from "./providers/huggingface"
|
4 |
import { resolveSegment as resolveSegmentUsingComfyReplicate } from "./providers/comfy-replicate"
|
@@ -8,7 +9,6 @@ import { resolveSegment as resolveSegmentUsingFalAi } from "./providers/falai"
|
|
8 |
import { resolveSegment as resolveSegmentUsingModelsLab } from "./providers/modelslab"
|
9 |
|
10 |
import { ComputeProvider, ResolveRequest } from "@/types"
|
11 |
-
import { ClapSegmentCategory } from "@aitube/clap"
|
12 |
|
13 |
export async function POST(req: NextRequest) {
|
14 |
// do we really need to secure it?
|
|
|
1 |
import { NextResponse, NextRequest } from "next/server"
|
2 |
+
import { ClapSegmentCategory } from "@aitube/clap"
|
3 |
|
4 |
import { resolveSegment as resolveSegmentUsingHuggingFace } from "./providers/huggingface"
|
5 |
import { resolveSegment as resolveSegmentUsingComfyReplicate } from "./providers/comfy-replicate"
|
|
|
9 |
import { resolveSegment as resolveSegmentUsingModelsLab } from "./providers/modelslab"
|
10 |
|
11 |
import { ComputeProvider, ResolveRequest } from "@/types"
|
|
|
12 |
|
13 |
export async function POST(req: NextRequest) {
|
14 |
// do we really need to secure it?
|
src/app/main.tsx
CHANGED
@@ -21,6 +21,7 @@ import { useUI } from "@/controllers/ui"
|
|
21 |
import { TopBar } from "@/components/toolbars/top-bar"
|
22 |
import { Timeline } from "@/components/core/timeline"
|
23 |
import { useIO } from "@/controllers/io/useIO"
|
|
|
24 |
|
25 |
type DroppableThing = { files: File[] }
|
26 |
|
@@ -71,23 +72,31 @@ function MainContent() {
|
|
71 |
`flex flex-row flex-grow w-full overflow-hidden`,
|
72 |
isEmpty ? "opacity-0" : "opacity-100"
|
73 |
)}>
|
74 |
-
<ReflexContainer orientation="
|
75 |
-
|
76 |
-
|
77 |
-
>
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
</ReflexElement>
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
maxSize={showTimeline ? 1600 : 1}
|
85 |
-
>
|
86 |
-
<Timeline />
|
87 |
-
</ReflexElement>
|
88 |
-
{/* showChat && <ReflexSplitter /> */}
|
89 |
-
{/* showChat && <ReflexElement size={300}><ChatView /></ReflexElement> */}
|
90 |
</ReflexContainer>
|
|
|
91 |
</div>
|
92 |
|
93 |
<SettingsDialog />
|
|
|
21 |
import { TopBar } from "@/components/toolbars/top-bar"
|
22 |
import { Timeline } from "@/components/core/timeline"
|
23 |
import { useIO } from "@/controllers/io/useIO"
|
24 |
+
import { ChatView } from "@/components/assistant/ChatView"
|
25 |
|
26 |
type DroppableThing = { files: File[] }
|
27 |
|
|
|
72 |
`flex flex-row flex-grow w-full overflow-hidden`,
|
73 |
isEmpty ? "opacity-0" : "opacity-100"
|
74 |
)}>
|
75 |
+
<ReflexContainer orientation="vertical">
|
76 |
+
|
77 |
+
<ReflexElement>
|
78 |
+
<ReflexContainer orientation="horizontal">
|
79 |
+
<ReflexElement
|
80 |
+
minSize={showTimeline ? 100 : 1}
|
81 |
+
>
|
82 |
+
<Monitor />
|
83 |
+
</ReflexElement>
|
84 |
+
<ReflexSplitter />
|
85 |
+
<ReflexElement
|
86 |
+
size={showTimeline ? 400 : 1}
|
87 |
+
minSize={showTimeline ? 100 : 1}
|
88 |
+
maxSize={showTimeline ? 1600 : 1}
|
89 |
+
>
|
90 |
+
<Timeline />
|
91 |
+
</ReflexElement>
|
92 |
+
</ReflexContainer>
|
93 |
</ReflexElement>
|
94 |
+
|
95 |
+
{showChat && <ReflexSplitter />}
|
96 |
+
{showChat && <ReflexElement size={300}><ChatView /></ReflexElement>}
|
97 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
</ReflexContainer>
|
99 |
+
|
100 |
</div>
|
101 |
|
102 |
<SettingsDialog />
|
src/components/assistant/ChatView.tsx
CHANGED
@@ -1,12 +1,8 @@
|
|
1 |
"use client"
|
2 |
|
3 |
import { useState, useTransition } from "react"
|
4 |
-
import { ClapOutputType, ClapProject, ClapSegment, ClapSegmentCategory, newSegment } from "@aitube/clap"
|
5 |
-
import { DEFAULT_DURATION_IN_MS_PER_STEP, findFreeTrack, useTimeline } from "@aitube/timeline"
|
6 |
|
7 |
import { useAssistant } from "@/controllers/assistant/useAssistant"
|
8 |
-
import { queryAssistant } from "@/app/api/assistant/providers/openai/askAssistant"
|
9 |
-
import { useSettings } from "@/controllers/settings"
|
10 |
|
11 |
import { ChatBubble } from "./ChatBubble"
|
12 |
import { Input } from "../ui/input"
|
@@ -14,22 +10,10 @@ import { Input } from "../ui/input"
|
|
14 |
export function ChatView() {
|
15 |
const [_isPending, startTransition] = useTransition()
|
16 |
|
17 |
-
/*
|
18 |
-
const others = useLiveProject((state) => state.liveblocks.others)
|
19 |
-
const userCount = others.length
|
20 |
-
console.log(`TODO: finish this There are ${userCount} other user(s) online`)
|
21 |
-
*/
|
22 |
|
23 |
const [draft, setDraft] = useState("")
|
24 |
-
const runCommand = useAssistant((s) => s.runCommand)
|
25 |
const history = useAssistant((s) => s.history)
|
26 |
-
const
|
27 |
-
|
28 |
-
/*
|
29 |
-
const updateSegment = useApp((state) => state.updateSegment)
|
30 |
-
const addSegment = useApp((state) => state.addSegment)
|
31 |
-
const projectInfo = useApp((state) => state.projectInfo)
|
32 |
-
*/
|
33 |
|
34 |
const handleSubmit = () => {
|
35 |
const message = draft.trim()
|
@@ -39,146 +23,7 @@ export function ChatView() {
|
|
39 |
}
|
40 |
|
41 |
setDraft("")
|
42 |
-
|
43 |
-
addEventToHistory({
|
44 |
-
senderId: "director",
|
45 |
-
senderName: "Director",
|
46 |
-
message,
|
47 |
-
})
|
48 |
-
|
49 |
-
// the LLM is behind a server action
|
50 |
-
startTransition(async () => {
|
51 |
-
|
52 |
-
|
53 |
-
const basicCommand = await runCommand(message)
|
54 |
-
// LLM analysis can be slow and expensive, so first we try to see if this was a trivial command
|
55 |
-
// like "start", "pause", "stop" etc
|
56 |
-
if (basicCommand) {
|
57 |
-
|
58 |
-
addEventToHistory({
|
59 |
-
senderId: "assistant",
|
60 |
-
senderName: "Assistant",
|
61 |
-
message: `${basicCommand}`,
|
62 |
-
})
|
63 |
-
return // no need to go further
|
64 |
-
}
|
65 |
-
|
66 |
-
|
67 |
-
const clap: ClapProject = useTimeline.getState().clap
|
68 |
-
|
69 |
-
console.log(`TODO @julian: restore the concept of "addSegment()", "updateSegment()", "active segment" and "cursor position" inside @aitube-timeline`)
|
70 |
-
// const { addSegment, activeSegments, cursorInSteps, } = useTimeline.getState()
|
71 |
-
|
72 |
-
const activeSegments: ClapSegment[] = []
|
73 |
-
const cursorInSteps = 0
|
74 |
-
|
75 |
-
const referenceSegment: ClapSegment | undefined = activeSegments.at(0)
|
76 |
-
|
77 |
-
if (!referenceSegment) {
|
78 |
-
throw new Error(`No segment under the current cursor`)
|
79 |
-
}
|
80 |
-
|
81 |
-
console.log(`TODO @julian: filter entities to only keep the ones in the current active segment? (although.. maybe a bad idea since the LLM need as much context as possible to "fill in the gap" eg. repair/invent missing elements of the story)`)
|
82 |
-
|
83 |
-
const entities = clap.entityIndex
|
84 |
-
|
85 |
-
const projectInfo = clap.meta.description
|
86 |
-
|
87 |
-
const sceneId = referenceSegment.sceneId
|
88 |
-
|
89 |
-
const scene = clap.scenes.find(s => s.id === sceneId)
|
90 |
-
|
91 |
-
const fullScene: string = scene?.sequenceFullText || ""
|
92 |
-
const actionLine: string = scene?.line || ""
|
93 |
-
|
94 |
-
const segments: ClapSegment[] = activeSegments
|
95 |
-
.filter(s =>
|
96 |
-
s.category === ClapSegmentCategory.LOCATION ||
|
97 |
-
s.category === ClapSegmentCategory.TIME ||
|
98 |
-
s.category === ClapSegmentCategory.LIGHTING ||
|
99 |
-
s.category === ClapSegmentCategory.ACTION ||
|
100 |
-
s.category === ClapSegmentCategory.DIALOGUE ||
|
101 |
-
s.category === ClapSegmentCategory.WEATHER
|
102 |
-
)
|
103 |
-
|
104 |
-
console.log(`TODO @julian: provide both contextual segments and editable ones to the LLM?`)
|
105 |
-
|
106 |
-
const { prompt, categoryName, llmOutput } = await queryAssistant({
|
107 |
-
settings: useSettings.getState().getSettings(),
|
108 |
-
prompt: message,
|
109 |
-
segments,
|
110 |
-
fullScene,
|
111 |
-
actionLine,
|
112 |
-
entities,
|
113 |
-
projectInfo,
|
114 |
-
})
|
115 |
-
if (!prompt.length) {
|
116 |
-
addEventToHistory({
|
117 |
-
senderId: "assistant",
|
118 |
-
senderName: "Assistant",
|
119 |
-
message: llmOutput || "🤔" // or "???" for a "boomer" theme
|
120 |
-
})
|
121 |
-
return
|
122 |
-
}
|
123 |
-
|
124 |
-
let match = segments.find(s => s.category === categoryName) || undefined
|
125 |
-
if (!match) {
|
126 |
-
|
127 |
-
const startTimeInMs = cursorInSteps * DEFAULT_DURATION_IN_MS_PER_STEP
|
128 |
-
const durationInSteps = 4
|
129 |
-
const durationInMs = durationInSteps * DEFAULT_DURATION_IN_MS_PER_STEP
|
130 |
-
const endTimeInMs = startTimeInMs + durationInMs
|
131 |
-
|
132 |
-
const newSeg = newSegment({
|
133 |
-
startTimeInSteps: cursorInSteps,
|
134 |
-
prompt: [prompt],
|
135 |
-
durationInSteps: 4,
|
136 |
-
trackId: findFreeTrack({
|
137 |
-
segments,
|
138 |
-
startTimeInMs,
|
139 |
-
endTimeInMs,
|
140 |
-
}),
|
141 |
-
outputType: ClapOutputType.TEXT,
|
142 |
-
categoryName,
|
143 |
-
})
|
144 |
-
console.log("Creating new existing segment:", newSeg)
|
145 |
-
|
146 |
-
console.log(`TODO Julian: add the segment!!`)
|
147 |
-
// addSegment(newSeg)
|
148 |
-
|
149 |
-
addEventToHistory({
|
150 |
-
senderId: "assistant",
|
151 |
-
senderName: "Assistant",
|
152 |
-
message: `Segment added: ${newSeg.prompt}`,
|
153 |
-
})
|
154 |
-
} else {
|
155 |
-
|
156 |
-
console.log("Updating an existing segment to:", {
|
157 |
-
...match,
|
158 |
-
prompt,
|
159 |
-
label: prompt,
|
160 |
-
})
|
161 |
-
|
162 |
-
console.log(`TODO Julian: update the segment!!`)
|
163 |
-
// addSegment(newSeg)
|
164 |
-
|
165 |
-
/*
|
166 |
-
updateSegment({
|
167 |
-
...match,
|
168 |
-
prompt,
|
169 |
-
label: prompt,
|
170 |
-
})
|
171 |
-
*/
|
172 |
-
|
173 |
-
addEventToHistory({
|
174 |
-
senderId: "assistant",
|
175 |
-
senderName: "Assistant",
|
176 |
-
message: `Segment updated: ${prompt}`,
|
177 |
-
})
|
178 |
-
}
|
179 |
-
|
180 |
-
})
|
181 |
-
|
182 |
}
|
183 |
|
184 |
return (
|
|
|
1 |
"use client"
|
2 |
|
3 |
import { useState, useTransition } from "react"
|
|
|
|
|
4 |
|
5 |
import { useAssistant } from "@/controllers/assistant/useAssistant"
|
|
|
|
|
6 |
|
7 |
import { ChatBubble } from "./ChatBubble"
|
8 |
import { Input } from "../ui/input"
|
|
|
10 |
export function ChatView() {
|
11 |
const [_isPending, startTransition] = useTransition()
|
12 |
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
const [draft, setDraft] = useState("")
|
|
|
15 |
const history = useAssistant((s) => s.history)
|
16 |
+
const processMessage = useAssistant((s) => s.processMessage)
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
const handleSubmit = () => {
|
19 |
const message = draft.trim()
|
|
|
23 |
}
|
24 |
|
25 |
setDraft("")
|
26 |
+
processMessage(draft.trim())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
return (
|
src/components/settings/constants.ts
CHANGED
@@ -1,25 +1,33 @@
|
|
1 |
import { ComfyIcuAccelerator, ComputeProvider } from "@/types"
|
2 |
|
3 |
export const computeProviderShortNames = {
|
4 |
-
[ComputeProvider.
|
5 |
-
[ComputeProvider.
|
6 |
-
[ComputeProvider.
|
7 |
[ComputeProvider.COMFY_HUGGINGFACE]: "Hugging Face Comfy",
|
8 |
-
[ComputeProvider.REPLICATE]: "Replicate",
|
9 |
[ComputeProvider.COMFY_REPLICATE]: "Replicate Comfy",
|
10 |
-
[ComputeProvider.
|
11 |
[ComputeProvider.ELEVENLABS]: "ElevenLabs",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
[ComputeProvider.OPENAI]: "OpenAI",
|
|
|
13 |
[ComputeProvider.STABILITYAI]: "StabilityAI",
|
14 |
-
[ComputeProvider.GROQ]: "Groq",
|
15 |
-
[ComputeProvider.FALAI]: "Fal.ai",
|
16 |
-
[ComputeProvider.MODELSLAB]: "ModelsLab"
|
17 |
}
|
18 |
|
19 |
export const availableComputeProvidersForAssistant = [
|
20 |
ComputeProvider.HUGGINGFACE,
|
21 |
ComputeProvider.GROQ,
|
22 |
ComputeProvider.OPENAI,
|
|
|
|
|
23 |
]
|
24 |
|
25 |
export const availableComputeProvidersForImages = [
|
@@ -27,6 +35,8 @@ export const availableComputeProvidersForImages = [
|
|
27 |
ComputeProvider.REPLICATE,
|
28 |
ComputeProvider.COMFY_REPLICATE,
|
29 |
ComputeProvider.COMFY_COMFYICU,
|
|
|
|
|
30 |
ComputeProvider.FALAI,
|
31 |
ComputeProvider.MODELSLAB,
|
32 |
]
|
@@ -36,6 +46,8 @@ export const availableComputeProvidersForVideos = [
|
|
36 |
ComputeProvider.REPLICATE,
|
37 |
ComputeProvider.COMFY_REPLICATE,
|
38 |
ComputeProvider.COMFY_COMFYICU,
|
|
|
|
|
39 |
ComputeProvider.FALAI,
|
40 |
ComputeProvider.MODELSLAB,
|
41 |
]
|
@@ -45,6 +57,7 @@ export const availableComputeProvidersForMusic = [
|
|
45 |
ComputeProvider.COMFY_REPLICATE,
|
46 |
ComputeProvider.COMFY_COMFYICU,
|
47 |
ComputeProvider.STABILITYAI,
|
|
|
48 |
ComputeProvider.FALAI,
|
49 |
ComputeProvider.MODELSLAB,
|
50 |
]
|
@@ -54,13 +67,16 @@ export const availableComputeProvidersForSound = [
|
|
54 |
ComputeProvider.COMFY_REPLICATE,
|
55 |
ComputeProvider.COMFY_COMFYICU,
|
56 |
ComputeProvider.STABILITYAI,
|
|
|
57 |
ComputeProvider.FALAI,
|
58 |
ComputeProvider.ELEVENLABS,
|
59 |
]
|
60 |
|
61 |
export const availableComputeProvidersForVoice = [
|
62 |
ComputeProvider.ELEVENLABS,
|
|
|
63 |
ComputeProvider.STABILITYAI,
|
|
|
64 |
ComputeProvider.HUGGINGFACE,
|
65 |
ComputeProvider.COMFY_REPLICATE,
|
66 |
ComputeProvider.COMFY_COMFYICU,
|
@@ -79,7 +95,36 @@ export const availableComfyIcuAccelerators = {
|
|
79 |
|
80 |
export const availableModelsForAssistant: Partial<Record<ComputeProvider, string[]>> = {
|
81 |
[ComputeProvider.OPENAI]: [
|
|
|
|
|
82 |
"gpt-4o",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
]
|
84 |
}
|
85 |
|
@@ -102,6 +147,17 @@ export const availableModelsForImageGeneration: Partial<Record<ComputeProvider,
|
|
102 |
// "fal-ai/pulid",
|
103 |
// "fal-ai/image-to-image",
|
104 |
// "fal-ai/omni-zero",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
]
|
106 |
}
|
107 |
|
@@ -109,12 +165,19 @@ export const availableModelsForImageGeneration: Partial<Record<ComputeProvider,
|
|
109 |
export const availableModelsForImageUpscaling: Partial<Record<ComputeProvider, string[]>> = {
|
110 |
[ComputeProvider.FALAI]: [
|
111 |
"fal-ai/ccsr",
|
112 |
-
]
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
|
115 |
export const availableModelsForVideoGeneration: Partial<Record<ComputeProvider, string[]>> = {
|
116 |
[ComputeProvider.FALAI]: [
|
117 |
"fal-ai/stable-video",
|
|
|
|
|
|
|
118 |
]
|
119 |
}
|
120 |
|
|
|
1 |
import { ComfyIcuAccelerator, ComputeProvider } from "@/types"
|
2 |
|
3 |
export const computeProviderShortNames = {
|
4 |
+
[ComputeProvider.ANTHROPIC]: "Anthropic",
|
5 |
+
[ComputeProvider.COHERE]: "Cohere",
|
6 |
+
[ComputeProvider.COMFY_COMFYICU]: "Comfy.icu",
|
7 |
[ComputeProvider.COMFY_HUGGINGFACE]: "Hugging Face Comfy",
|
|
|
8 |
[ComputeProvider.COMFY_REPLICATE]: "Replicate Comfy",
|
9 |
+
[ComputeProvider.CUSTOM]: "Custom API",
|
10 |
[ComputeProvider.ELEVENLABS]: "ElevenLabs",
|
11 |
+
[ComputeProvider.FALAI]: "Fal.ai",
|
12 |
+
[ComputeProvider.FIREWORKSAI]: "FireworksAI",
|
13 |
+
[ComputeProvider.GOOGLE]: "Google (VertexAI)",
|
14 |
+
[ComputeProvider.GROQ]: "Groq",
|
15 |
+
[ComputeProvider.HUGGINGFACE]: "Hugging Face",
|
16 |
+
[ComputeProvider.KITSAI]: "Kits.ai",
|
17 |
+
[ComputeProvider.MISTRALAI]: "MistralAI",
|
18 |
+
[ComputeProvider.MODELSLAB]: "ModelsLab",
|
19 |
+
[ComputeProvider.NONE]: "None", // <-- this is the default
|
20 |
[ComputeProvider.OPENAI]: "OpenAI",
|
21 |
+
[ComputeProvider.REPLICATE]: "Replicate",
|
22 |
[ComputeProvider.STABILITYAI]: "StabilityAI",
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
export const availableComputeProvidersForAssistant = [
|
26 |
ComputeProvider.HUGGINGFACE,
|
27 |
ComputeProvider.GROQ,
|
28 |
ComputeProvider.OPENAI,
|
29 |
+
ComputeProvider.ANTHROPIC,
|
30 |
+
ComputeProvider.FIREWORKSAI,
|
31 |
]
|
32 |
|
33 |
export const availableComputeProvidersForImages = [
|
|
|
35 |
ComputeProvider.REPLICATE,
|
36 |
ComputeProvider.COMFY_REPLICATE,
|
37 |
ComputeProvider.COMFY_COMFYICU,
|
38 |
+
ComputeProvider.STABILITYAI,
|
39 |
+
ComputeProvider.FIREWORKSAI,
|
40 |
ComputeProvider.FALAI,
|
41 |
ComputeProvider.MODELSLAB,
|
42 |
]
|
|
|
46 |
ComputeProvider.REPLICATE,
|
47 |
ComputeProvider.COMFY_REPLICATE,
|
48 |
ComputeProvider.COMFY_COMFYICU,
|
49 |
+
ComputeProvider.STABILITYAI,
|
50 |
+
// ComputeProvider.FIREWORKSAI,
|
51 |
ComputeProvider.FALAI,
|
52 |
ComputeProvider.MODELSLAB,
|
53 |
]
|
|
|
57 |
ComputeProvider.COMFY_REPLICATE,
|
58 |
ComputeProvider.COMFY_COMFYICU,
|
59 |
ComputeProvider.STABILITYAI,
|
60 |
+
// ComputeProvider.FIREWORKSAI,
|
61 |
ComputeProvider.FALAI,
|
62 |
ComputeProvider.MODELSLAB,
|
63 |
]
|
|
|
67 |
ComputeProvider.COMFY_REPLICATE,
|
68 |
ComputeProvider.COMFY_COMFYICU,
|
69 |
ComputeProvider.STABILITYAI,
|
70 |
+
// ComputeProvider.FIREWORKSAI,
|
71 |
ComputeProvider.FALAI,
|
72 |
ComputeProvider.ELEVENLABS,
|
73 |
]
|
74 |
|
75 |
export const availableComputeProvidersForVoice = [
|
76 |
ComputeProvider.ELEVENLABS,
|
77 |
+
ComputeProvider.KITSAI,
|
78 |
ComputeProvider.STABILITYAI,
|
79 |
+
// ComputeProvider.FIREWORKSAI,
|
80 |
ComputeProvider.HUGGINGFACE,
|
81 |
ComputeProvider.COMFY_REPLICATE,
|
82 |
ComputeProvider.COMFY_COMFYICU,
|
|
|
95 |
|
96 |
export const availableModelsForAssistant: Partial<Record<ComputeProvider, string[]>> = {
|
97 |
[ComputeProvider.OPENAI]: [
|
98 |
+
"gpt-4",
|
99 |
+
"gpt-4-turbo",
|
100 |
"gpt-4o",
|
101 |
+
],
|
102 |
+
[ComputeProvider.GROQ]: [
|
103 |
+
"Mixtral-8x7b-32768",
|
104 |
+
"Gemma-7b-lt",
|
105 |
+
"Llama3-70b-8192",
|
106 |
+
"Llama3-8b-8192",
|
107 |
+
],
|
108 |
+
[ComputeProvider.ANTHROPIC]: [
|
109 |
+
"claude-3-opus-20240229",
|
110 |
+
"claude-3-sonnet-20240229",
|
111 |
+
"claude-3-haiku-20240307"
|
112 |
+
],
|
113 |
+
[ComputeProvider.GOOGLE]: [
|
114 |
+
"claude-3-opus@20240229",
|
115 |
+
"claude-3-sonnet@20240229",
|
116 |
+
"claude-3-haiku@20240307"
|
117 |
+
],
|
118 |
+
[ComputeProvider.MISTRALAI]: [
|
119 |
+
"mistral-small-latest",
|
120 |
+
"open-mistral-7b"
|
121 |
+
],
|
122 |
+
[ComputeProvider.HUGGINGFACE]: [
|
123 |
+
"HuggingFaceH4/zephyr-7b-beta",
|
124 |
+
"mistralai/Mixtral-8x7B-Instruct-v0.1"
|
125 |
+
],
|
126 |
+
[ComputeProvider.FIREWORKSAI]: [
|
127 |
+
"fireworks/llama-v3-70b-instruct",
|
128 |
]
|
129 |
}
|
130 |
|
|
|
147 |
// "fal-ai/pulid",
|
148 |
// "fal-ai/image-to-image",
|
149 |
// "fal-ai/omni-zero",
|
150 |
+
],
|
151 |
+
[ComputeProvider.STABILITYAI]: [
|
152 |
+
"stable-image/generate/ultra",
|
153 |
+
"stable-image/generate/core",
|
154 |
+
"stable-image/generate/sd3"
|
155 |
+
],
|
156 |
+
[ComputeProvider.FIREWORKSAI]: [
|
157 |
+
"stability/sd3",
|
158 |
+
"accounts/stability/models/sd3-turbo",
|
159 |
+
"fireworks/stable-diffusion-xl-1024-v1-0",
|
160 |
+
"accounts/fireworks/models/playground-v2-5-1024px-aesthetic",
|
161 |
]
|
162 |
}
|
163 |
|
|
|
165 |
export const availableModelsForImageUpscaling: Partial<Record<ComputeProvider, string[]>> = {
|
166 |
[ComputeProvider.FALAI]: [
|
167 |
"fal-ai/ccsr",
|
168 |
+
],
|
169 |
+
[ComputeProvider.STABILITYAI]: [
|
170 |
+
"stable-image/upscale/conservative",
|
171 |
+
"stable-image/upscale/creative"
|
172 |
+
],
|
173 |
}
|
174 |
|
175 |
export const availableModelsForVideoGeneration: Partial<Record<ComputeProvider, string[]>> = {
|
176 |
[ComputeProvider.FALAI]: [
|
177 |
"fal-ai/stable-video",
|
178 |
+
],
|
179 |
+
[ComputeProvider.STABILITYAI]: [
|
180 |
+
"image-to-video",
|
181 |
]
|
182 |
}
|
183 |
|
src/components/toolbars/top-menu/assistant/index.tsx
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use client"
|
2 |
+
|
3 |
+
import {
|
4 |
+
MenubarCheckboxItem,
|
5 |
+
MenubarContent,
|
6 |
+
MenubarItem,
|
7 |
+
MenubarMenu,
|
8 |
+
MenubarSeparator,
|
9 |
+
MenubarSub,
|
10 |
+
MenubarSubContent,
|
11 |
+
MenubarSubTrigger,
|
12 |
+
MenubarTrigger
|
13 |
+
} from "@/components/ui/menubar"
|
14 |
+
import { useSettings } from "@/controllers/settings"
|
15 |
+
import { useUI } from "@/controllers/ui"
|
16 |
+
|
17 |
+
import { ProviderList } from "../lists/ProviderList"
|
18 |
+
import { availableComputeProvidersForAssistant } from "@/components/settings/constants"
|
19 |
+
import { SettingsCategory } from "@/types"
|
20 |
+
import { AssistantModelList } from "../lists/AssistantModelList"
|
21 |
+
|
22 |
+
export function TopMenuAssistant() {
|
23 |
+
const setShowSettings = useUI(s => s.setShowSettings)
|
24 |
+
const assistantProvider = useSettings(s => s.assistantProvider)
|
25 |
+
const setAssistantProvider = useSettings(s => s.setAssistantProvider)
|
26 |
+
const assistantModel = useSettings(s => s.assistantModel)
|
27 |
+
const setAssistantModel = useSettings(s => s.setAssistantModel)
|
28 |
+
return (
|
29 |
+
<MenubarMenu>
|
30 |
+
<MenubarTrigger>Assistant</MenubarTrigger>
|
31 |
+
<MenubarContent>
|
32 |
+
<MenubarSub>
|
33 |
+
<MenubarItem onClick={() => { setShowSettings(SettingsCategory.ASSISTANT) }}>Show advanced settings</MenubarItem>
|
34 |
+
<MenubarSeparator />
|
35 |
+
<AssistantModelList provider={assistantProvider} current={assistantModel} setter={setAssistantModel} />
|
36 |
+
<ProviderList providers={availableComputeProvidersForAssistant} current={assistantProvider} setter={setAssistantProvider} />
|
37 |
+
<MenubarSeparator />
|
38 |
+
<MenubarItem
|
39 |
+
disabled
|
40 |
+
>Usage and costs: not implemented</MenubarItem>
|
41 |
+
</MenubarSub>
|
42 |
+
</MenubarContent>
|
43 |
+
</MenubarMenu>
|
44 |
+
)
|
45 |
+
}
|
src/components/toolbars/top-menu/index.tsx
CHANGED
@@ -7,6 +7,7 @@ import { TopMenuVideo } from "./video"
|
|
7 |
import { TopMenuVoice } from "./voice"
|
8 |
import { TopMenuSound } from "./sound"
|
9 |
import { TopMenuMusic } from "./music"
|
|
|
10 |
|
11 |
import { TopMenuView } from "./view"
|
12 |
import { cn } from "@aitube/timeline"
|
@@ -30,6 +31,7 @@ export function TopMenu() {
|
|
30 |
<TopMenuVoice />
|
31 |
<TopMenuSound />
|
32 |
<TopMenuMusic />
|
|
|
33 |
<TopMenuView />
|
34 |
<div className={cn(`
|
35 |
flex flex-row flex-grow
|
|
|
7 |
import { TopMenuVoice } from "./voice"
|
8 |
import { TopMenuSound } from "./sound"
|
9 |
import { TopMenuMusic } from "./music"
|
10 |
+
import { TopMenuAssistant } from "./assistant"
|
11 |
|
12 |
import { TopMenuView } from "./view"
|
13 |
import { cn } from "@aitube/timeline"
|
|
|
31 |
<TopMenuVoice />
|
32 |
<TopMenuSound />
|
33 |
<TopMenuMusic />
|
34 |
+
<TopMenuAssistant />
|
35 |
<TopMenuView />
|
36 |
<div className={cn(`
|
37 |
flex flex-row flex-grow
|
src/components/toolbars/top-menu/lists/AssistantModelList.tsx
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use client"
|
2 |
+
|
3 |
+
import {
|
4 |
+
MenubarCheckboxItem,
|
5 |
+
MenubarContent,
|
6 |
+
MenubarItem,
|
7 |
+
MenubarMenu,
|
8 |
+
MenubarSeparator,
|
9 |
+
MenubarSub,
|
10 |
+
MenubarSubContent,
|
11 |
+
MenubarSubTrigger,
|
12 |
+
} from "@/components/ui/menubar"
|
13 |
+
|
14 |
+
import { TagColor } from "@/components/tags/types"
|
15 |
+
import { Tag } from "@/components/tags/Tag"
|
16 |
+
import { ComputeProvider } from "@/types"
|
17 |
+
import { availableModelsForAssistant } from "@/components/settings/constants"
|
18 |
+
|
19 |
+
export function AssistantModelList({
|
20 |
+
provider,
|
21 |
+
current,
|
22 |
+
setter,
|
23 |
+
}: {
|
24 |
+
provider?: ComputeProvider
|
25 |
+
current?: string
|
26 |
+
setter: (model: string) => void
|
27 |
+
}) {
|
28 |
+
const models: string[] = provider ? (availableModelsForAssistant[provider] || []) : []
|
29 |
+
|
30 |
+
if (models.length === 0) { return null }
|
31 |
+
|
32 |
+
return (
|
33 |
+
<MenubarSub>
|
34 |
+
<MenubarSubTrigger>
|
35 |
+
<Tag size="lg" color={TagColor.GREEN}>ai assistant</Tag>
|
36 |
+
{current || "None"}
|
37 |
+
</MenubarSubTrigger>
|
38 |
+
<MenubarSubContent>
|
39 |
+
{models.map(model => (
|
40 |
+
<MenubarCheckboxItem
|
41 |
+
key={model}
|
42 |
+
checked={current === model}
|
43 |
+
onClick={(e) => {
|
44 |
+
setter(model)
|
45 |
+
e.stopPropagation()
|
46 |
+
e.preventDefault()
|
47 |
+
return false
|
48 |
+
}}>
|
49 |
+
{model}
|
50 |
+
</MenubarCheckboxItem>
|
51 |
+
))}
|
52 |
+
</MenubarSubContent>
|
53 |
+
</MenubarSub>
|
54 |
+
)
|
55 |
+
}
|
src/components/toolbars/top-menu/music/index.tsx
CHANGED
@@ -18,13 +18,17 @@ import { ProviderList } from "../lists/ProviderList"
|
|
18 |
import { RenderingStrategyList } from "../lists/RenderingStrategyList"
|
19 |
import { availableComputeProvidersForMusic } from "@/components/settings/constants"
|
20 |
import { SettingsCategory } from "@/types"
|
|
|
21 |
|
22 |
export function TopMenuMusic() {
|
23 |
const setShowSettings = useUI(s => s.setShowSettings)
|
24 |
const musicProvider = useSettings(s => s.musicProvider)
|
25 |
const setMusicProvider = useSettings(s => s.setMusicProvider)
|
|
|
|
|
26 |
const musicRenderingStrategy = useSettings((s) => s.musicRenderingStrategy)
|
27 |
const setMusicRenderingStrategy = useSettings((s) => s.setMusicRenderingStrategy)
|
|
|
28 |
return (
|
29 |
<MenubarMenu>
|
30 |
<MenubarTrigger>Music</MenubarTrigger>
|
@@ -32,6 +36,7 @@ export function TopMenuMusic() {
|
|
32 |
<MenubarSub>
|
33 |
<MenubarItem onClick={() => { setShowSettings(SettingsCategory.MUSIC) }}>Show advanced settings</MenubarItem>
|
34 |
<MenubarSeparator />
|
|
|
35 |
<ProviderList providers={availableComputeProvidersForMusic} current={musicProvider} setter={setMusicProvider} />
|
36 |
<RenderingStrategyList current={musicRenderingStrategy} setter={setMusicRenderingStrategy} />
|
37 |
<MenubarSeparator />
|
|
|
18 |
import { RenderingStrategyList } from "../lists/RenderingStrategyList"
|
19 |
import { availableComputeProvidersForMusic } from "@/components/settings/constants"
|
20 |
import { SettingsCategory } from "@/types"
|
21 |
+
import { MusicGenerationModelList } from "../lists/MusicGenerationModelList"
|
22 |
|
23 |
export function TopMenuMusic() {
|
24 |
const setShowSettings = useUI(s => s.setShowSettings)
|
25 |
const musicProvider = useSettings(s => s.musicProvider)
|
26 |
const setMusicProvider = useSettings(s => s.setMusicProvider)
|
27 |
+
const musicGenerationModel = useSettings(s => s.musicGenerationModel)
|
28 |
+
const setMusicGenerationModel = useSettings(s => s.setMusicGenerationModel)
|
29 |
const musicRenderingStrategy = useSettings((s) => s.musicRenderingStrategy)
|
30 |
const setMusicRenderingStrategy = useSettings((s) => s.setMusicRenderingStrategy)
|
31 |
+
|
32 |
return (
|
33 |
<MenubarMenu>
|
34 |
<MenubarTrigger>Music</MenubarTrigger>
|
|
|
36 |
<MenubarSub>
|
37 |
<MenubarItem onClick={() => { setShowSettings(SettingsCategory.MUSIC) }}>Show advanced settings</MenubarItem>
|
38 |
<MenubarSeparator />
|
39 |
+
<MusicGenerationModelList provider={musicProvider} current={musicGenerationModel} setter={setMusicGenerationModel} />
|
40 |
<ProviderList providers={availableComputeProvidersForMusic} current={musicProvider} setter={setMusicProvider} />
|
41 |
<RenderingStrategyList current={musicRenderingStrategy} setter={setMusicRenderingStrategy} />
|
42 |
<MenubarSeparator />
|
src/components/toolbars/top-menu/sound/index.tsx
CHANGED
@@ -18,11 +18,14 @@ import { ProviderList } from "../lists/ProviderList"
|
|
18 |
import { RenderingStrategyList } from "../lists/RenderingStrategyList"
|
19 |
import { availableComputeProvidersForSound } from "@/components/settings/constants"
|
20 |
import { SettingsCategory } from "@/types"
|
|
|
21 |
|
22 |
export function TopMenuSound() {
|
23 |
const setShowSettings = useUI(s => s.setShowSettings)
|
24 |
const soundProvider = useSettings(s => s.soundProvider)
|
25 |
const setSoundProvider = useSettings(s => s.setSoundProvider)
|
|
|
|
|
26 |
const soundRenderingStrategy = useSettings((s) => s.soundRenderingStrategy)
|
27 |
const setSoundRenderingStrategy = useSettings((s) => s.setSoundRenderingStrategy)
|
28 |
return (
|
@@ -32,6 +35,7 @@ export function TopMenuSound() {
|
|
32 |
<MenubarSub>
|
33 |
<MenubarItem onClick={() => { setShowSettings(SettingsCategory.SOUND) }}>Show advanced settings</MenubarItem>
|
34 |
<MenubarSeparator />
|
|
|
35 |
<ProviderList providers={availableComputeProvidersForSound} current={soundProvider} setter={setSoundProvider} />
|
36 |
<RenderingStrategyList current={soundRenderingStrategy} setter={setSoundRenderingStrategy} />
|
37 |
<MenubarSeparator />
|
|
|
18 |
import { RenderingStrategyList } from "../lists/RenderingStrategyList"
|
19 |
import { availableComputeProvidersForSound } from "@/components/settings/constants"
|
20 |
import { SettingsCategory } from "@/types"
|
21 |
+
import { SoundGenerationModelList } from "../lists/SoundGenerationModelList"
|
22 |
|
23 |
export function TopMenuSound() {
|
24 |
const setShowSettings = useUI(s => s.setShowSettings)
|
25 |
const soundProvider = useSettings(s => s.soundProvider)
|
26 |
const setSoundProvider = useSettings(s => s.setSoundProvider)
|
27 |
+
const soundGenerationModel = useSettings(s => s.soundGenerationModel)
|
28 |
+
const setSoundGenerationModel = useSettings(s => s.setSoundGenerationModel)
|
29 |
const soundRenderingStrategy = useSettings((s) => s.soundRenderingStrategy)
|
30 |
const setSoundRenderingStrategy = useSettings((s) => s.setSoundRenderingStrategy)
|
31 |
return (
|
|
|
35 |
<MenubarSub>
|
36 |
<MenubarItem onClick={() => { setShowSettings(SettingsCategory.SOUND) }}>Show advanced settings</MenubarItem>
|
37 |
<MenubarSeparator />
|
38 |
+
<SoundGenerationModelList provider={soundProvider} current={soundGenerationModel} setter={setSoundGenerationModel} />
|
39 |
<ProviderList providers={availableComputeProvidersForSound} current={soundProvider} setter={setSoundProvider} />
|
40 |
<RenderingStrategyList current={soundRenderingStrategy} setter={setSoundRenderingStrategy} />
|
41 |
<MenubarSeparator />
|
src/components/toolbars/top-menu/view/index.tsx
CHANGED
@@ -77,6 +77,7 @@ export function TopMenuView() {
|
|
77 |
return false
|
78 |
}}
|
79 |
>Show asset explorer</MenubarCheckboxItem>
|
|
|
80 |
<MenubarCheckboxItem
|
81 |
checked={showChat}
|
82 |
onClick={(e) => {
|
@@ -86,6 +87,7 @@ export function TopMenuView() {
|
|
86 |
return false
|
87 |
}}
|
88 |
>Show chat assistant</MenubarCheckboxItem>
|
|
|
89 |
<MenubarCheckboxItem
|
90 |
checked={showVideoPlayer}
|
91 |
onClick={(e) => {
|
|
|
77 |
return false
|
78 |
}}
|
79 |
>Show asset explorer</MenubarCheckboxItem>
|
80 |
+
*/}
|
81 |
<MenubarCheckboxItem
|
82 |
checked={showChat}
|
83 |
onClick={(e) => {
|
|
|
87 |
return false
|
88 |
}}
|
89 |
>Show chat assistant</MenubarCheckboxItem>
|
90 |
+
{/*
|
91 |
<MenubarCheckboxItem
|
92 |
checked={showVideoPlayer}
|
93 |
onClick={(e) => {
|
src/controllers/assistant/askAssistant.ts
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { AssistantRequest, AssistantResponse } from "@/types"
|
2 |
+
|
3 |
+
export async function askAssistant(request: AssistantRequest) {
|
4 |
+
const res = await fetch("/api/assistant", {
|
5 |
+
method: "POST",
|
6 |
+
headers: {
|
7 |
+
"Content-Type": "application/json",
|
8 |
+
},
|
9 |
+
body: JSON.stringify(request)
|
10 |
+
})
|
11 |
+
|
12 |
+
const response = (await res.json()) as AssistantResponse
|
13 |
+
return response
|
14 |
+
}
|
src/controllers/assistant/types.ts
CHANGED
@@ -34,12 +34,13 @@ export type AssistantState = {
|
|
34 |
socket?: WebSocket
|
35 |
}
|
36 |
export type AssistantControls = {
|
|
|
37 |
/**
|
38 |
* Toggle the speech to text on or off
|
39 |
*
|
40 |
* @returns true if operation succeeded, false otherwise
|
41 |
*/
|
42 |
-
toggleVoice: () => Promise<boolean>
|
43 |
|
44 |
/**
|
45 |
* Run a prompt command (which can come from a transcript or somewhere else)
|
@@ -59,6 +60,8 @@ export type AssistantControls = {
|
|
59 |
addEventToHistory: (event: Partial<ChatEvent>) => ChatEvent
|
60 |
|
61 |
clearHistory: () => void
|
|
|
|
|
62 |
}
|
63 |
|
64 |
export type AssistantStore =
|
|
|
34 |
socket?: WebSocket
|
35 |
}
|
36 |
export type AssistantControls = {
|
37 |
+
|
38 |
/**
|
39 |
* Toggle the speech to text on or off
|
40 |
*
|
41 |
* @returns true if operation succeeded, false otherwise
|
42 |
*/
|
43 |
+
// toggleVoice: () => Promise<boolean>
|
44 |
|
45 |
/**
|
46 |
* Run a prompt command (which can come from a transcript or somewhere else)
|
|
|
60 |
addEventToHistory: (event: Partial<ChatEvent>) => ChatEvent
|
61 |
|
62 |
clearHistory: () => void
|
63 |
+
|
64 |
+
processMessage: (input: string) => void
|
65 |
}
|
66 |
|
67 |
export type AssistantStore =
|
src/controllers/assistant/useAssistant.ts
CHANGED
@@ -1,10 +1,14 @@
|
|
1 |
"use client"
|
2 |
|
3 |
import { create } from "zustand"
|
4 |
-
import { UUID } from "@aitube/clap"
|
5 |
|
6 |
import { AssistantStore, ChatEvent } from "./types"
|
7 |
import { getDefaultAssistantState } from "./getDefaultAssistantState"
|
|
|
|
|
|
|
|
|
8 |
|
9 |
// URL to the speech to text websocket server
|
10 |
export const STT_API_URL = process.env.NEXT_PUBLIC_SPEECH_TO_TEXT_API_URL || ""
|
@@ -13,6 +17,7 @@ const enableTextToSpeech = false
|
|
13 |
|
14 |
export const useAssistant = create<AssistantStore>((set, get) => ({
|
15 |
...getDefaultAssistantState(),
|
|
|
16 |
toggleVoice: async (): Promise<boolean> => {
|
17 |
|
18 |
if (!navigator?.mediaDevices?.getUserMedia || !MediaRecorder.isTypeSupported("audio/webm")) {
|
@@ -89,6 +94,7 @@ export const useAssistant = create<AssistantStore>((set, get) => ({
|
|
89 |
|
90 |
return true
|
91 |
},
|
|
|
92 |
|
93 |
runCommand: (prompt: string) => {
|
94 |
|
@@ -135,6 +141,154 @@ export const useAssistant = create<AssistantStore>((set, get) => ({
|
|
135 |
|
136 |
clearHistory: () => {
|
137 |
set({ history: [] })
|
138 |
-
}
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
"use client"
|
2 |
|
3 |
import { create } from "zustand"
|
4 |
+
import { ClapOutputType, ClapProject, ClapSegment, ClapSegmentCategory, newSegment, UUID } from "@aitube/clap"
|
5 |
|
6 |
import { AssistantStore, ChatEvent } from "./types"
|
7 |
import { getDefaultAssistantState } from "./getDefaultAssistantState"
|
8 |
+
import { DEFAULT_DURATION_IN_MS_PER_STEP, findFreeTrack, TimelineStore, useTimeline } from "@aitube/timeline"
|
9 |
+
import { useSettings } from "../settings"
|
10 |
+
import { AssistantRequest } from "@/types"
|
11 |
+
import { askAssistant } from "./askAssistant"
|
12 |
|
13 |
// URL to the speech to text websocket server
|
14 |
export const STT_API_URL = process.env.NEXT_PUBLIC_SPEECH_TO_TEXT_API_URL || ""
|
|
|
17 |
|
18 |
export const useAssistant = create<AssistantStore>((set, get) => ({
|
19 |
...getDefaultAssistantState(),
|
20 |
+
/*
|
21 |
toggleVoice: async (): Promise<boolean> => {
|
22 |
|
23 |
if (!navigator?.mediaDevices?.getUserMedia || !MediaRecorder.isTypeSupported("audio/webm")) {
|
|
|
94 |
|
95 |
return true
|
96 |
},
|
97 |
+
*/
|
98 |
|
99 |
runCommand: (prompt: string) => {
|
100 |
|
|
|
141 |
|
142 |
clearHistory: () => {
|
143 |
set({ history: [] })
|
144 |
+
},
|
145 |
+
|
146 |
+
processMessage: async (input: string) => {
|
147 |
+
const message = input.trim()
|
148 |
+
if (!message) {
|
149 |
+
return
|
150 |
+
}
|
151 |
+
const { addEventToHistory, runCommand } = get()
|
152 |
+
|
153 |
+
const timelineState: TimelineStore = useTimeline.getState()
|
154 |
+
const { clap } = timelineState
|
155 |
+
if (!clap) { return }
|
156 |
+
|
157 |
+
// note: settings is not the store (with methods etc)
|
158 |
+
// but a serializable snapshot of the values only
|
159 |
+
const settings = useSettings.getState().getSettings()
|
160 |
+
|
161 |
+
addEventToHistory({
|
162 |
+
senderId: "director",
|
163 |
+
senderName: "Director",
|
164 |
+
message,
|
165 |
+
})
|
166 |
+
|
167 |
+
|
168 |
+
const basicCommand = await runCommand(message)
|
169 |
+
// LLM analysis can be slow and expensive, so first we try to see if this was a trivial command
|
170 |
+
// like "start", "pause", "stop" etc
|
171 |
+
if (basicCommand) {
|
172 |
+
|
173 |
+
addEventToHistory({
|
174 |
+
senderId: "assistant",
|
175 |
+
senderName: "Assistant",
|
176 |
+
message: `${basicCommand}`,
|
177 |
+
})
|
178 |
+
return // no need to go further
|
179 |
+
}
|
180 |
+
|
181 |
+
console.log(`TODO @julian: restore the concept of "addSegment()", "updateSegment()", "active segment" and "cursor position" inside @aitube-timeline`)
|
182 |
+
// const { addSegment, activeSegments, cursorInSteps, } = useTimeline.getState()
|
183 |
+
|
184 |
+
const activeSegments: ClapSegment[] = []
|
185 |
+
const cursorInSteps = 0
|
186 |
+
|
187 |
+
const referenceSegment: ClapSegment | undefined = activeSegments.at(0)
|
188 |
+
|
189 |
+
if (!referenceSegment) {
|
190 |
+
throw new Error(`No segment under the current cursor`)
|
191 |
+
}
|
192 |
+
|
193 |
+
console.log(`TODO @julian: filter entities to only keep the ones in the current active segment? (although.. maybe a bad idea since the LLM need as much context as possible to "fill in the gap" eg. repair/invent missing elements of the story)`)
|
194 |
+
|
195 |
+
const entities = clap.entityIndex
|
196 |
|
197 |
+
const projectInfo = clap.meta.description
|
198 |
+
|
199 |
+
const sceneId = referenceSegment.sceneId
|
200 |
+
|
201 |
+
const scene = clap.scenes.find(s => s.id === sceneId)
|
202 |
+
|
203 |
+
const fullScene: string = scene?.sequenceFullText || ""
|
204 |
+
const actionLine: string = scene?.line || ""
|
205 |
+
|
206 |
+
const segments: ClapSegment[] = activeSegments
|
207 |
+
.filter(s =>
|
208 |
+
s.category === ClapSegmentCategory.LOCATION ||
|
209 |
+
s.category === ClapSegmentCategory.TIME ||
|
210 |
+
s.category === ClapSegmentCategory.LIGHTING ||
|
211 |
+
s.category === ClapSegmentCategory.ACTION ||
|
212 |
+
s.category === ClapSegmentCategory.DIALOGUE ||
|
213 |
+
s.category === ClapSegmentCategory.WEATHER
|
214 |
+
)
|
215 |
+
|
216 |
+
console.log(`TODO @julian: provide both contextual segments and editable ones to the LLM?`)
|
217 |
+
|
218 |
+
const request: AssistantRequest = {
|
219 |
+
settings,
|
220 |
+
prompt: message,
|
221 |
+
segments,
|
222 |
+
fullScene,
|
223 |
+
actionLine,
|
224 |
+
entities,
|
225 |
+
projectInfo,
|
226 |
+
}
|
227 |
+
|
228 |
+
const { prompt, categoryName, llmOutput } = await askAssistant(request)
|
229 |
+
if (!prompt.length) {
|
230 |
+
addEventToHistory({
|
231 |
+
senderId: "assistant",
|
232 |
+
senderName: "Assistant",
|
233 |
+
message: llmOutput || "🤔" // or "???" for a "boomer" theme
|
234 |
+
})
|
235 |
+
return
|
236 |
+
}
|
237 |
+
|
238 |
+
let match = segments.find(s => s.category === categoryName) || undefined
|
239 |
+
if (!match) {
|
240 |
+
|
241 |
+
const startTimeInMs = cursorInSteps * DEFAULT_DURATION_IN_MS_PER_STEP
|
242 |
+
const durationInSteps = 4
|
243 |
+
const durationInMs = durationInSteps * DEFAULT_DURATION_IN_MS_PER_STEP
|
244 |
+
const endTimeInMs = startTimeInMs + durationInMs
|
245 |
+
|
246 |
+
const newSeg = newSegment({
|
247 |
+
startTimeInSteps: cursorInSteps,
|
248 |
+
prompt: [prompt],
|
249 |
+
durationInSteps: 4,
|
250 |
+
trackId: findFreeTrack({
|
251 |
+
segments,
|
252 |
+
startTimeInMs,
|
253 |
+
endTimeInMs,
|
254 |
+
}),
|
255 |
+
outputType: ClapOutputType.TEXT,
|
256 |
+
categoryName,
|
257 |
+
})
|
258 |
+
console.log("Creating new existing segment:", newSeg)
|
259 |
+
|
260 |
+
console.log(`TODO Julian: add the segment!!`)
|
261 |
+
// addSegment(newSeg)
|
262 |
+
|
263 |
+
addEventToHistory({
|
264 |
+
senderId: "assistant",
|
265 |
+
senderName: "Assistant",
|
266 |
+
message: `Segment added: ${newSeg.prompt}`,
|
267 |
+
})
|
268 |
+
} else {
|
269 |
+
|
270 |
+
console.log("Updating an existing segment to:", {
|
271 |
+
...match,
|
272 |
+
prompt,
|
273 |
+
label: prompt,
|
274 |
+
})
|
275 |
+
|
276 |
+
console.log(`TODO Julian: update the segment!!`)
|
277 |
+
// addSegment(newSeg)
|
278 |
+
|
279 |
+
/*
|
280 |
+
updateSegment({
|
281 |
+
...match,
|
282 |
+
prompt,
|
283 |
+
label: prompt,
|
284 |
+
})
|
285 |
+
*/
|
286 |
+
|
287 |
+
addEventToHistory({
|
288 |
+
senderId: "assistant",
|
289 |
+
senderName: "Assistant",
|
290 |
+
message: `Segment updated: ${prompt}`,
|
291 |
+
})
|
292 |
+
}
|
293 |
+
}
|
294 |
+
}))
|
src/controllers/metrics/constants.ts
CHANGED
@@ -43,10 +43,28 @@ export const estimatedMetrics: Record<ComputeProvider, Record<string, ProviderMe
|
|
43 |
},
|
44 |
[ComputeProvider.STABILITYAI]: {
|
45 |
// TODO list the most popular models
|
|
|
|
|
|
|
46 |
},
|
47 |
[ComputeProvider.GROQ]: {
|
48 |
// TODO list the most popular models
|
49 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
[ComputeProvider.FALAI]: {
|
51 |
"fal-ai/fast-sdxl": {
|
52 |
estimationType: ProviderMetricsEstimationType.MANUAL_MEASUREMENTS,
|
|
|
43 |
},
|
44 |
[ComputeProvider.STABILITYAI]: {
|
45 |
// TODO list the most popular models
|
46 |
+
},
|
47 |
+
[ComputeProvider.FIREWORKSAI]: {
|
48 |
+
|
49 |
},
|
50 |
[ComputeProvider.GROQ]: {
|
51 |
// TODO list the most popular models
|
52 |
},
|
53 |
+
[ComputeProvider.KITSAI]: {
|
54 |
+
// TODO list the most popular models
|
55 |
+
},
|
56 |
+
[ComputeProvider.ANTHROPIC]: {
|
57 |
+
// TODO list the most popular models
|
58 |
+
},
|
59 |
+
[ComputeProvider.GOOGLE]: {
|
60 |
+
// TODO list the most popular models
|
61 |
+
},
|
62 |
+
[ComputeProvider.MISTRALAI]: {
|
63 |
+
// TODO list the most popular models
|
64 |
+
},
|
65 |
+
[ComputeProvider.COHERE]: {
|
66 |
+
// TODO list the most popular models
|
67 |
+
},
|
68 |
[ComputeProvider.FALAI]: {
|
69 |
"fal-ai/fast-sdxl": {
|
70 |
estimationType: ProviderMetricsEstimationType.MANUAL_MEASUREMENTS,
|
src/controllers/metrics/getDefaultMetricsPerProvider.ts
CHANGED
@@ -35,6 +35,9 @@ export function getDefaultMetricsPerProvider(): MetricsPerProvider {
|
|
35 |
[ComputeProvider.STABILITYAI]: {
|
36 |
...getDefaultComputeProviderMetrics(),
|
37 |
},
|
|
|
|
|
|
|
38 |
[ComputeProvider.GROQ]: {
|
39 |
...getDefaultComputeProviderMetrics(),
|
40 |
},
|
@@ -44,6 +47,21 @@ export function getDefaultMetricsPerProvider(): MetricsPerProvider {
|
|
44 |
[ComputeProvider.MODELSLAB]: {
|
45 |
...getDefaultComputeProviderMetrics(),
|
46 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
48 |
return metricsPerProvider
|
49 |
}
|
|
|
35 |
[ComputeProvider.STABILITYAI]: {
|
36 |
...getDefaultComputeProviderMetrics(),
|
37 |
},
|
38 |
+
[ComputeProvider.FIREWORKSAI]: {
|
39 |
+
...getDefaultComputeProviderMetrics(),
|
40 |
+
},
|
41 |
[ComputeProvider.GROQ]: {
|
42 |
...getDefaultComputeProviderMetrics(),
|
43 |
},
|
|
|
47 |
[ComputeProvider.MODELSLAB]: {
|
48 |
...getDefaultComputeProviderMetrics(),
|
49 |
},
|
50 |
+
[ComputeProvider.KITSAI]: {
|
51 |
+
...getDefaultComputeProviderMetrics(),
|
52 |
+
},
|
53 |
+
[ComputeProvider.ANTHROPIC]: {
|
54 |
+
...getDefaultComputeProviderMetrics(),
|
55 |
+
},
|
56 |
+
[ComputeProvider.GOOGLE]: {
|
57 |
+
...getDefaultComputeProviderMetrics(),
|
58 |
+
},
|
59 |
+
[ComputeProvider.MISTRALAI]: {
|
60 |
+
...getDefaultComputeProviderMetrics(),
|
61 |
+
},
|
62 |
+
[ComputeProvider.COHERE]: {
|
63 |
+
...getDefaultComputeProviderMetrics(),
|
64 |
+
},
|
65 |
}
|
66 |
return metricsPerProvider
|
67 |
}
|
src/controllers/metrics/useMetrics.ts
CHANGED
@@ -8,5 +8,5 @@ import { getDefaultMetricsState } from "./getDefaultMetricsState"
|
|
8 |
export const useMetrics = create<MetricsStore>((set, get) => ({
|
9 |
...getDefaultMetricsState(),
|
10 |
|
11 |
-
|
12 |
}))
|
|
|
8 |
export const useMetrics = create<MetricsStore>((set, get) => ({
|
9 |
...getDefaultMetricsState(),
|
10 |
|
11 |
+
// TODO: add a track metric callback
|
12 |
}))
|
src/controllers/resolver/useResolver.ts
CHANGED
@@ -91,8 +91,8 @@ export const useResolver = create<ResolverStore>((set, get) => ({
|
|
91 |
// segments visible on screen are show first,
|
92 |
// then those nearby, then the hidden ones
|
93 |
const segments: RuntimeSegment[] = ([...allSegments] as RuntimeSegment[]).sort((segment1, segment2) => {
|
94 |
-
const priority1 = SegmentVisibilityPriority[segment1.visibility || SegmentVisibility.HIDDEN] || 0
|
95 |
-
const priority2 = SegmentVisibilityPriority[segment2.visibility || SegmentVisibility.HIDDEN] || 0
|
96 |
|
97 |
return priority2 - priority1
|
98 |
})
|
@@ -278,7 +278,7 @@ export const useResolver = create<ResolverStore>((set, get) => ({
|
|
278 |
// throw new Error(`please call setSegmentRender(...) first`)
|
279 |
}
|
280 |
|
281 |
-
const shotSegments = filterSegments(
|
282 |
ClapSegmentFilteringMode.ANY,
|
283 |
segment,
|
284 |
allSegments
|
|
|
91 |
// segments visible on screen are show first,
|
92 |
// then those nearby, then the hidden ones
|
93 |
const segments: RuntimeSegment[] = ([...allSegments] as RuntimeSegment[]).sort((segment1, segment2) => {
|
94 |
+
const priority1 = (SegmentVisibilityPriority as any)[segment1.visibility || SegmentVisibility.HIDDEN] || 0
|
95 |
+
const priority2 = (SegmentVisibilityPriority as any)[segment2.visibility || SegmentVisibility.HIDDEN] || 0
|
96 |
|
97 |
return priority2 - priority1
|
98 |
})
|
|
|
278 |
// throw new Error(`please call setSegmentRender(...) first`)
|
279 |
}
|
280 |
|
281 |
+
const shotSegments: ClapSegment[] = filterSegments(
|
282 |
ClapSegmentFilteringMode.ANY,
|
283 |
segment,
|
284 |
allSegments
|
src/controllers/settings/getDefaultSettingsState.ts
CHANGED
@@ -20,6 +20,10 @@ export function getDefaultSettingsState(): SettingsState {
|
|
20 |
groqApiKey: "",
|
21 |
anthropicApiKey: "",
|
22 |
elevenLabsApiKey: "",
|
|
|
|
|
|
|
|
|
23 |
|
24 |
assistantProvider: ComputeProvider.NONE,
|
25 |
imageProvider: ComputeProvider.NONE,
|
@@ -93,6 +97,13 @@ export function getDefaultSettingsState(): SettingsState {
|
|
93 |
stabilityAiModelForSound: "",
|
94 |
stabilityAiModelForMusic: "",
|
95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
falAiModelForImage: "fal-ai/fast-sdxl", // "fal-ai/fast-lightning-sdxl",
|
97 |
falAiModelForVideo: "fal-ai/stable-video",
|
98 |
falAiModelForVoice: "fal-ai/metavoice-v1",
|
@@ -122,6 +133,10 @@ export function getDefaultSettingsState(): SettingsState {
|
|
122 |
|
123 |
elevenLabsModelForVoice: "v1",
|
124 |
elevenLabsModelForSound: "v1",
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
return state
|
127 |
}
|
|
|
20 |
groqApiKey: "",
|
21 |
anthropicApiKey: "",
|
22 |
elevenLabsApiKey: "",
|
23 |
+
kitsAiApiKey: "",
|
24 |
+
cohereApiKey: "",
|
25 |
+
mistralAiApiKey: "",
|
26 |
+
fireworksAiApiKey: "",
|
27 |
|
28 |
assistantProvider: ComputeProvider.NONE,
|
29 |
imageProvider: ComputeProvider.NONE,
|
|
|
97 |
stabilityAiModelForSound: "",
|
98 |
stabilityAiModelForMusic: "",
|
99 |
|
100 |
+
fireworksAiModelForAssistant: "",
|
101 |
+
fireworksAiModelForImage: "",
|
102 |
+
fireworksAiModelForVideo: "",
|
103 |
+
fireworksAiModelForVoice: "",
|
104 |
+
fireworksAiModelForSound: "",
|
105 |
+
fireworksAiModelForMusic: "",
|
106 |
+
|
107 |
falAiModelForImage: "fal-ai/fast-sdxl", // "fal-ai/fast-lightning-sdxl",
|
108 |
falAiModelForVideo: "fal-ai/stable-video",
|
109 |
falAiModelForVoice: "fal-ai/metavoice-v1",
|
|
|
133 |
|
134 |
elevenLabsModelForVoice: "v1",
|
135 |
elevenLabsModelForSound: "v1",
|
136 |
+
|
137 |
+
kitsAiModelForVoice: "",
|
138 |
+
cohereModelForAssistant: "",
|
139 |
+
mistralAiModelForAssistant: ""
|
140 |
}
|
141 |
return state
|
142 |
}
|
src/controllers/settings/types.ts
CHANGED
@@ -15,6 +15,10 @@ export type SettingsState = {
|
|
15 |
groqApiKey: string
|
16 |
anthropicApiKey: string
|
17 |
elevenLabsApiKey: string
|
|
|
|
|
|
|
|
|
18 |
|
19 |
// ------------- CATEGORY PROVIDERS ---------------
|
20 |
assistantProvider: ComputeProvider
|
@@ -92,6 +96,13 @@ export type SettingsState = {
|
|
92 |
stabilityAiModelForSound: string
|
93 |
stabilityAiModelForMusic: string
|
94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
falAiModelForImage: string
|
96 |
falAiModelForVideo: string
|
97 |
falAiModelForVoice: string
|
@@ -121,6 +132,12 @@ export type SettingsState = {
|
|
121 |
|
122 |
elevenLabsModelForVoice: string
|
123 |
elevenLabsModelForSound: string
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
export type SettingsControls = {
|
@@ -131,12 +148,15 @@ export type SettingsControls = {
|
|
131 |
setHuggingFaceApiKey: (huggingFaceApiKey?: string) => void
|
132 |
setModelsLabApiKey: (modelsLabApiKey?: string) => void
|
133 |
setFalAiApiKey: (falAiApiKey?: string) => void
|
134 |
-
|
135 |
setOpenaiApiKey: (openaiApiKey?: string) => void
|
136 |
setGoogleApiKey: (googleApiKey?: string) => void
|
137 |
setGroqApiKey: (groqApiKey?: string) => void
|
|
|
138 |
setAnthropicApiKey: (anthropicApiKey?: string) => void
|
139 |
setElevenLabsApiKey: (elevenLabsApiKey?: string) => void
|
|
|
|
|
|
|
140 |
|
141 |
setAssistantProvider: (assistantProvider?: ComputeProvider) => void
|
142 |
setVideoProvider: (videoProvider?: ComputeProvider) => void
|
@@ -204,6 +224,13 @@ export type SettingsControls = {
|
|
204 |
setStabilityAiModelForSound: (stabilityAiModelForSound?: string) => void
|
205 |
setStabilityAiModelForMusic: (stabilityAiModelForMusic?: string) => void
|
206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
setFalAiModelForImage: (falAiModelForImage?: string) => void
|
208 |
setFalAiModelForVideo: (falAiModelForVideo?: string) => void
|
209 |
setFalAiModelForVoice: (falAiModelForVoice?: string) => void
|
@@ -234,6 +261,11 @@ export type SettingsControls = {
|
|
234 |
setElevenLabsModelForVoice: (elevenLabsModelForVoice?: string) => void
|
235 |
setElevenLabsModelForSound: (elevenLabsModelForSound?: string) => void
|
236 |
|
|
|
|
|
|
|
|
|
|
|
237 |
getSettings: () => SettingsState
|
238 |
}
|
239 |
|
|
|
15 |
groqApiKey: string
|
16 |
anthropicApiKey: string
|
17 |
elevenLabsApiKey: string
|
18 |
+
kitsAiApiKey: string
|
19 |
+
cohereApiKey: string
|
20 |
+
mistralAiApiKey: string
|
21 |
+
fireworksAiApiKey: string
|
22 |
|
23 |
// ------------- CATEGORY PROVIDERS ---------------
|
24 |
assistantProvider: ComputeProvider
|
|
|
96 |
stabilityAiModelForSound: string
|
97 |
stabilityAiModelForMusic: string
|
98 |
|
99 |
+
fireworksAiModelForAssistant: string
|
100 |
+
fireworksAiModelForImage: string
|
101 |
+
fireworksAiModelForVideo: string
|
102 |
+
fireworksAiModelForVoice: string
|
103 |
+
fireworksAiModelForSound: string
|
104 |
+
fireworksAiModelForMusic: string
|
105 |
+
|
106 |
falAiModelForImage: string
|
107 |
falAiModelForVideo: string
|
108 |
falAiModelForVoice: string
|
|
|
132 |
|
133 |
elevenLabsModelForVoice: string
|
134 |
elevenLabsModelForSound: string
|
135 |
+
|
136 |
+
kitsAiModelForVoice: string
|
137 |
+
|
138 |
+
cohereModelForAssistant: string
|
139 |
+
|
140 |
+
mistralAiModelForAssistant: string
|
141 |
}
|
142 |
|
143 |
export type SettingsControls = {
|
|
|
148 |
setHuggingFaceApiKey: (huggingFaceApiKey?: string) => void
|
149 |
setModelsLabApiKey: (modelsLabApiKey?: string) => void
|
150 |
setFalAiApiKey: (falAiApiKey?: string) => void
|
|
|
151 |
setOpenaiApiKey: (openaiApiKey?: string) => void
|
152 |
setGoogleApiKey: (googleApiKey?: string) => void
|
153 |
setGroqApiKey: (groqApiKey?: string) => void
|
154 |
+
setFireworksAiApiKey: (fireworksAiApiKey?: string) => void
|
155 |
setAnthropicApiKey: (anthropicApiKey?: string) => void
|
156 |
setElevenLabsApiKey: (elevenLabsApiKey?: string) => void
|
157 |
+
setCohereApiKey: (cohereApiKey?: string) => void
|
158 |
+
setMistralAiApiKey: (mistralAiApiKey?: string) => void
|
159 |
+
setKitsAiApiKey: (kitsAiApiKey?: string) => void
|
160 |
|
161 |
setAssistantProvider: (assistantProvider?: ComputeProvider) => void
|
162 |
setVideoProvider: (videoProvider?: ComputeProvider) => void
|
|
|
224 |
setStabilityAiModelForSound: (stabilityAiModelForSound?: string) => void
|
225 |
setStabilityAiModelForMusic: (stabilityAiModelForMusic?: string) => void
|
226 |
|
227 |
+
setFireworksAiModelForAssistant: (fireworksAiModelForAssistant?: string) => void
|
228 |
+
setFireworksAiModelForImage: (fireworksAiModelForImage?: string) => void
|
229 |
+
setFireworksAiModelForVideo: (fireworksAiModelForVideo?: string) => void
|
230 |
+
setFireworksAiModelForVoice: (fireworksAiModelForVoice?: string) => void
|
231 |
+
setFireworksAiModelForSound: (fireworksAiModelForSound?: string) => void
|
232 |
+
setFireworksAiModelForMusic: (fireworksAiModelForMusic?: string) => void
|
233 |
+
|
234 |
setFalAiModelForImage: (falAiModelForImage?: string) => void
|
235 |
setFalAiModelForVideo: (falAiModelForVideo?: string) => void
|
236 |
setFalAiModelForVoice: (falAiModelForVoice?: string) => void
|
|
|
261 |
setElevenLabsModelForVoice: (elevenLabsModelForVoice?: string) => void
|
262 |
setElevenLabsModelForSound: (elevenLabsModelForSound?: string) => void
|
263 |
|
264 |
+
setCohereModelForAssistant: (cohereModelForAssistant?: string) => void
|
265 |
+
setMistralAiModelForAssistant: (mistralAiModelForAssistant?: string) => void
|
266 |
+
|
267 |
+
setKitsAiModelForVoice: (kitsAiModelForVoice?: string) => void
|
268 |
+
|
269 |
getSettings: () => SettingsState
|
270 |
}
|
271 |
|
src/controllers/settings/useSettings.ts
CHANGED
@@ -84,6 +84,18 @@ export const useSettings = create<SettingsStore>()(
|
|
84 |
setElevenLabsApiKey: (elevenLabsApiKey?: string) => {
|
85 |
set({ elevenLabsApiKey: getValidString(elevenLabsApiKey, getDefaultSettingsState().elevenLabsApiKey) })
|
86 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
setCensorNotForAllAudiencesContent: (censorNotForAllAudiencesContent?: boolean) => {
|
88 |
set({ censorNotForAllAudiencesContent: getValidBoolean(censorNotForAllAudiencesContent, getDefaultSettingsState().censorNotForAllAudiencesContent) })
|
89 |
},
|
@@ -269,6 +281,24 @@ export const useSettings = create<SettingsStore>()(
|
|
269 |
setStabilityAiModelForMusic: (stabilityAiModelForMusic?: string) => {
|
270 |
set({ stabilityAiModelForMusic: getValidString(stabilityAiModelForMusic, getDefaultSettingsState().stabilityAiModelForMusic) })
|
271 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
setFalAiModelForImage: (falAiModelForImage?: string) => {
|
273 |
set({ falAiModelForImage: getValidString(falAiModelForImage, getDefaultSettingsState().falAiModelForImage) })
|
274 |
},
|
@@ -338,6 +368,15 @@ export const useSettings = create<SettingsStore>()(
|
|
338 |
setElevenLabsModelForSound: (elevenLabsModelForSound?: string) => {
|
339 |
set({ elevenLabsModelForSound: getValidString(elevenLabsModelForSound, getDefaultSettingsState().elevenLabsModelForSound) })
|
340 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
getSettings: (): SettingsState => {
|
342 |
const state = get()
|
343 |
const defaultSettings = getDefaultSettingsState()
|
@@ -362,6 +401,10 @@ export const useSettings = create<SettingsStore>()(
|
|
362 |
googleApiKey: state.googleApiKey || defaultSettings.googleApiKey,
|
363 |
anthropicApiKey: state.anthropicApiKey || defaultSettings.anthropicApiKey,
|
364 |
elevenLabsApiKey: state.elevenLabsApiKey || defaultSettings.elevenLabsApiKey,
|
|
|
|
|
|
|
|
|
365 |
censorNotForAllAudiencesContent: state.censorNotForAllAudiencesContent || defaultSettings.censorNotForAllAudiencesContent,
|
366 |
imagePromptPrefix: state.imagePromptPrefix || defaultSettings.imagePromptPrefix,
|
367 |
imagePromptSuffix: state.imagePromptSuffix || defaultSettings.imagePromptSuffix,
|
@@ -415,6 +458,12 @@ export const useSettings = create<SettingsStore>()(
|
|
415 |
stabilityAiModelForVoice: state.stabilityAiModelForVoice || defaultSettings.stabilityAiModelForVoice,
|
416 |
stabilityAiModelForSound: state.stabilityAiModelForSound || defaultSettings.stabilityAiModelForSound,
|
417 |
stabilityAiModelForMusic: state.stabilityAiModelForMusic || defaultSettings.stabilityAiModelForMusic,
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
falAiModelForImage: state.falAiModelForImage || defaultSettings.falAiModelForImage,
|
419 |
falAiModelForVideo: state.falAiModelForVideo || defaultSettings.falAiModelForVideo,
|
420 |
falAiModelForVoice: state.falAiModelForVoice || defaultSettings.falAiModelForVoice,
|
@@ -438,6 +487,9 @@ export const useSettings = create<SettingsStore>()(
|
|
438 |
anthropicModelForAssistant: state.anthropicModelForAssistant || defaultSettings.anthropicModelForAssistant,
|
439 |
elevenLabsModelForVoice: state.elevenLabsModelForVoice || defaultSettings.elevenLabsModelForVoice,
|
440 |
elevenLabsModelForSound: state.elevenLabsModelForSound || defaultSettings.elevenLabsModelForSound,
|
|
|
|
|
|
|
441 |
}
|
442 |
},
|
443 |
}),
|
|
|
84 |
setElevenLabsApiKey: (elevenLabsApiKey?: string) => {
|
85 |
set({ elevenLabsApiKey: getValidString(elevenLabsApiKey, getDefaultSettingsState().elevenLabsApiKey) })
|
86 |
},
|
87 |
+
setKitsAiApiKey: (kitsAiApiKey?: string) => {
|
88 |
+
set({ kitsAiApiKey: getValidString(kitsAiApiKey, getDefaultSettingsState().kitsAiApiKey) })
|
89 |
+
},
|
90 |
+
setCohereApiKey: (cohereApiKey?: string) => {
|
91 |
+
set({ cohereApiKey: getValidString(cohereApiKey, getDefaultSettingsState().cohereApiKey) })
|
92 |
+
},
|
93 |
+
setMistralAiApiKey: (mistralAiApiKey?: string) => {
|
94 |
+
set({ mistralAiApiKey: getValidString(mistralAiApiKey, getDefaultSettingsState().mistralAiApiKey) })
|
95 |
+
},
|
96 |
+
setFireworksAiApiKey: (fireworksAiApiKey?: string) => {
|
97 |
+
set({ fireworksAiApiKey: getValidString(fireworksAiApiKey, getDefaultSettingsState().fireworksAiApiKey) })
|
98 |
+
},
|
99 |
setCensorNotForAllAudiencesContent: (censorNotForAllAudiencesContent?: boolean) => {
|
100 |
set({ censorNotForAllAudiencesContent: getValidBoolean(censorNotForAllAudiencesContent, getDefaultSettingsState().censorNotForAllAudiencesContent) })
|
101 |
},
|
|
|
281 |
setStabilityAiModelForMusic: (stabilityAiModelForMusic?: string) => {
|
282 |
set({ stabilityAiModelForMusic: getValidString(stabilityAiModelForMusic, getDefaultSettingsState().stabilityAiModelForMusic) })
|
283 |
},
|
284 |
+
setFireworksAiModelForAssistant: (fireworksAiModelForAssistant?: string) => {
|
285 |
+
set({ fireworksAiModelForAssistant: getValidString(fireworksAiModelForAssistant, getDefaultSettingsState().fireworksAiModelForAssistant) })
|
286 |
+
},
|
287 |
+
setFireworksAiModelForImage: (fireworksAiModelForImage?: string) => {
|
288 |
+
set({ fireworksAiModelForImage: getValidString(fireworksAiModelForImage, getDefaultSettingsState().fireworksAiModelForImage) })
|
289 |
+
},
|
290 |
+
setFireworksAiModelForVideo: (fireworksAiModelForVideo?: string) => {
|
291 |
+
set({ fireworksAiModelForVideo: getValidString(fireworksAiModelForVideo, getDefaultSettingsState().fireworksAiModelForVideo) })
|
292 |
+
},
|
293 |
+
setFireworksAiModelForVoice: (fireworksAiModelForVoice?: string) => {
|
294 |
+
set({ fireworksAiModelForVoice: getValidString(fireworksAiModelForVoice, getDefaultSettingsState().fireworksAiModelForVoice) })
|
295 |
+
},
|
296 |
+
setFireworksAiModelForSound: (fireworksAiModelForSound?: string) => {
|
297 |
+
set({ fireworksAiModelForSound: getValidString(fireworksAiModelForSound, getDefaultSettingsState().fireworksAiModelForSound) })
|
298 |
+
},
|
299 |
+
setFireworksAiModelForMusic: (fireworksAiModelForMusic?: string) => {
|
300 |
+
set({ fireworksAiModelForMusic: getValidString(fireworksAiModelForMusic, getDefaultSettingsState().fireworksAiModelForMusic) })
|
301 |
+
},
|
302 |
setFalAiModelForImage: (falAiModelForImage?: string) => {
|
303 |
set({ falAiModelForImage: getValidString(falAiModelForImage, getDefaultSettingsState().falAiModelForImage) })
|
304 |
},
|
|
|
368 |
setElevenLabsModelForSound: (elevenLabsModelForSound?: string) => {
|
369 |
set({ elevenLabsModelForSound: getValidString(elevenLabsModelForSound, getDefaultSettingsState().elevenLabsModelForSound) })
|
370 |
},
|
371 |
+
setCohereModelForAssistant: (cohereModelForAssistant?: string) => {
|
372 |
+
set({ cohereModelForAssistant: getValidString(cohereModelForAssistant, getDefaultSettingsState().cohereModelForAssistant) })
|
373 |
+
},
|
374 |
+
setMistralAiModelForAssistant: (mistralAiModelForAssistant?: string) => {
|
375 |
+
set({ mistralAiModelForAssistant: getValidString(mistralAiModelForAssistant, getDefaultSettingsState().mistralAiModelForAssistant) })
|
376 |
+
},
|
377 |
+
setKitsAiModelForVoice: (kitsAiModelForVoice?: string) => {
|
378 |
+
set({ kitsAiModelForVoice: getValidString(kitsAiModelForVoice, getDefaultSettingsState().kitsAiModelForVoice) })
|
379 |
+
},
|
380 |
getSettings: (): SettingsState => {
|
381 |
const state = get()
|
382 |
const defaultSettings = getDefaultSettingsState()
|
|
|
401 |
googleApiKey: state.googleApiKey || defaultSettings.googleApiKey,
|
402 |
anthropicApiKey: state.anthropicApiKey || defaultSettings.anthropicApiKey,
|
403 |
elevenLabsApiKey: state.elevenLabsApiKey || defaultSettings.elevenLabsApiKey,
|
404 |
+
cohereApiKey: state.cohereApiKey || defaultSettings.cohereApiKey,
|
405 |
+
mistralAiApiKey: state.mistralAiApiKey || defaultSettings.mistralAiApiKey,
|
406 |
+
kitsAiApiKey: state.kitsAiApiKey || defaultSettings.kitsAiApiKey,
|
407 |
+
fireworksAiApiKey: state.fireworksAiApiKey || defaultSettings.fireworksAiApiKey,
|
408 |
censorNotForAllAudiencesContent: state.censorNotForAllAudiencesContent || defaultSettings.censorNotForAllAudiencesContent,
|
409 |
imagePromptPrefix: state.imagePromptPrefix || defaultSettings.imagePromptPrefix,
|
410 |
imagePromptSuffix: state.imagePromptSuffix || defaultSettings.imagePromptSuffix,
|
|
|
458 |
stabilityAiModelForVoice: state.stabilityAiModelForVoice || defaultSettings.stabilityAiModelForVoice,
|
459 |
stabilityAiModelForSound: state.stabilityAiModelForSound || defaultSettings.stabilityAiModelForSound,
|
460 |
stabilityAiModelForMusic: state.stabilityAiModelForMusic || defaultSettings.stabilityAiModelForMusic,
|
461 |
+
fireworksAiModelForAssistant: state.fireworksAiModelForAssistant || defaultSettings.fireworksAiModelForAssistant,
|
462 |
+
fireworksAiModelForImage: state.fireworksAiModelForImage || defaultSettings.fireworksAiModelForImage,
|
463 |
+
fireworksAiModelForVideo: state.fireworksAiModelForVideo || defaultSettings.fireworksAiModelForVideo,
|
464 |
+
fireworksAiModelForVoice: state.fireworksAiModelForVoice || defaultSettings.fireworksAiModelForVoice,
|
465 |
+
fireworksAiModelForSound: state.fireworksAiModelForSound || defaultSettings.fireworksAiModelForSound,
|
466 |
+
fireworksAiModelForMusic: state.fireworksAiModelForMusic || defaultSettings.fireworksAiModelForMusic,
|
467 |
falAiModelForImage: state.falAiModelForImage || defaultSettings.falAiModelForImage,
|
468 |
falAiModelForVideo: state.falAiModelForVideo || defaultSettings.falAiModelForVideo,
|
469 |
falAiModelForVoice: state.falAiModelForVoice || defaultSettings.falAiModelForVoice,
|
|
|
487 |
anthropicModelForAssistant: state.anthropicModelForAssistant || defaultSettings.anthropicModelForAssistant,
|
488 |
elevenLabsModelForVoice: state.elevenLabsModelForVoice || defaultSettings.elevenLabsModelForVoice,
|
489 |
elevenLabsModelForSound: state.elevenLabsModelForSound || defaultSettings.elevenLabsModelForSound,
|
490 |
+
cohereModelForAssistant: state.cohereModelForAssistant || defaultSettings.cohereModelForAssistant,
|
491 |
+
mistralAiModelForAssistant: state.mistralAiModelForAssistant || defaultSettings.mistralAiModelForAssistant,
|
492 |
+
kitsAiModelForVoice: state.kitsAiModelForVoice || defaultSettings.kitsAiModelForVoice,
|
493 |
}
|
494 |
},
|
495 |
}),
|
src/lib/utils/parseComputeProvider.ts
CHANGED
@@ -34,6 +34,9 @@ export function parseComputeProvider(input: any, defaultVendor?: ComputeProvider
|
|
34 |
else if (unknownString === "stabilityai") {
|
35 |
vendor = ComputeProvider.STABILITYAI
|
36 |
}
|
|
|
|
|
|
|
37 |
else if (unknownString === "groq") {
|
38 |
vendor = ComputeProvider.GROQ
|
39 |
}
|
|
|
34 |
else if (unknownString === "stabilityai") {
|
35 |
vendor = ComputeProvider.STABILITYAI
|
36 |
}
|
37 |
+
else if (unknownString === "fireworksai") {
|
38 |
+
vendor = ComputeProvider.FIREWORKSAI
|
39 |
+
}
|
40 |
else if (unknownString === "groq") {
|
41 |
vendor = ComputeProvider.GROQ
|
42 |
}
|
src/types.ts
CHANGED
@@ -21,9 +21,15 @@ export enum ComputeProvider {
|
|
21 |
COMFY_REPLICATE = "COMFY_REPLICATE", // https://replicate.com
|
22 |
COMFY_COMFYICU = "COMFY_COMFYICU", // https://comfy.icu
|
23 |
ELEVENLABS = "ELEVENLABS", // https://elevenlabs.io
|
|
|
24 |
OPENAI = "OPENAI", // https://openai.com
|
25 |
STABILITYAI = "STABILITYAI", // https://stability.ai
|
|
|
26 |
GROQ = "GROQ", // https://groq.com
|
|
|
|
|
|
|
|
|
27 |
FALAI = "FALAI", // https://fal.ai
|
28 |
MODELSLAB = "MODELSLAB", // https://modelslab.com
|
29 |
}
|
|
|
21 |
COMFY_REPLICATE = "COMFY_REPLICATE", // https://replicate.com
|
22 |
COMFY_COMFYICU = "COMFY_COMFYICU", // https://comfy.icu
|
23 |
ELEVENLABS = "ELEVENLABS", // https://elevenlabs.io
|
24 |
+
KITSAI = "KITSAI", // https://kits.ai
|
25 |
OPENAI = "OPENAI", // https://openai.com
|
26 |
STABILITYAI = "STABILITYAI", // https://stability.ai
|
27 |
+
FIREWORKSAI = "FIREWORKSAI", // https://fireworks.ai
|
28 |
GROQ = "GROQ", // https://groq.com
|
29 |
+
ANTHROPIC = "ANTHROPIC", // https://anthropic.com
|
30 |
+
GOOGLE = "GOOGLE", // https://google.com (in case you didn't know)
|
31 |
+
MISTRALAI = "MISTRALAI", // https://mistral.ai
|
32 |
+
COHERE = "COHERE", // https://cohere.com
|
33 |
FALAI = "FALAI", // https://fal.ai
|
34 |
MODELSLAB = "MODELSLAB", // https://modelslab.com
|
35 |
}
|