Commit
•
24b3b53
1
Parent(s):
3f94588
working to add the firehose
Browse files- .env +7 -0
- README.md +10 -1
- src/app/engine/community.ts +127 -0
- src/favicon.ico +0 -0
- src/icon.png +0 -0
- src/types.ts +24 -1
.env
CHANGED
@@ -28,3 +28,10 @@ HF_INFERENCE_API_MODEL="codellama/CodeLlama-7b-hf"
|
|
28 |
|
29 |
# Not supported yet
|
30 |
OPENAI_TOKEN=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
# Not supported yet
|
30 |
OPENAI_TOKEN=
|
31 |
+
|
32 |
+
# ----------- COMMUNITY SHARING (OPTIONAL) -----------
|
33 |
+
# You don't need those community sharing options to run the AI Comic Factory
|
34 |
+
# locally or on your own server (they are meant to be used by the Hugging Face team)
|
35 |
+
COMMUNITY_API_URL=
|
36 |
+
COMMUNITY_API_TOKEN=
|
37 |
+
COMMUNITY_API_ID=
|
README.md
CHANGED
@@ -25,7 +25,16 @@ If you try to duplicate the project, you will see it requires some variables:
|
|
25 |
- `RENDERING_ENGINE`: can only be "VIDEOCHAIN" for now, unless you code your custom solution
|
26 |
- `VIDEOCHAIN_API_URL`: url to the VideoChain API server
|
27 |
- `VIDEOCHAIN_API_TOKEN`: secret token to access the VideoChain API server
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
Please read the `.env` default config file for more informations.
|
30 |
To customise a variable locally, you should create a `.env.local`
|
31 |
(do not commit this file as it will contain your secrets).
|
|
|
25 |
- `RENDERING_ENGINE`: can only be "VIDEOCHAIN" for now, unless you code your custom solution
|
26 |
- `VIDEOCHAIN_API_URL`: url to the VideoChain API server
|
27 |
- `VIDEOCHAIN_API_TOKEN`: secret token to access the VideoChain API server
|
28 |
+
|
29 |
+
In addition, there are some community sharing variables that you can just ignore.
|
30 |
+
|
31 |
+
Those variables are not required to run the AI Comic Factory on your own website or computer
|
32 |
+
(they are meant to create a connection with the Hugging Face community,
|
33 |
+
and thus only make sense for official Hugging Face apps):
|
34 |
+
- `COMMUNITY_API_URL`: community sharing feature
|
35 |
+
- `COMMUNITY_API_TOKEN`: you don't need this
|
36 |
+
- `COMMUNITY_API_ID`: same
|
37 |
+
|
38 |
Please read the `.env` default config file for more informations.
|
39 |
To customise a variable locally, you should create a `.env.local`
|
40 |
(do not commit this file as it will contain your secrets).
|
src/app/engine/community.ts
ADDED
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use server"
|
2 |
+
|
3 |
+
import { v4 as uuidv4 } from "uuid"
|
4 |
+
|
5 |
+
import { CreatePostResponse, GetAppPostsResponse, Post } from "@/types"
|
6 |
+
|
7 |
+
const apiUrl = `${process.env.COMMUNITY_API_URL || ""}`
|
8 |
+
const apiToken = `${process.env.COMMUNITY_API_TOKEN || ""}`
|
9 |
+
const appId = `${process.env.APP_ID || ""}`
|
10 |
+
|
11 |
+
export async function postToCommunity({
|
12 |
+
prompt,
|
13 |
+
assetUrl,
|
14 |
+
}: {
|
15 |
+
prompt: string
|
16 |
+
assetUrl: string
|
17 |
+
}): Promise<Post> {
|
18 |
+
// if the community API is disabled,
|
19 |
+
// we don't fail, we just mock
|
20 |
+
if (!apiUrl) {
|
21 |
+
const mockPost: Post = {
|
22 |
+
postId: uuidv4(),
|
23 |
+
appId: "mock",
|
24 |
+
prompt,
|
25 |
+
previewUrl: assetUrl,
|
26 |
+
assetUrl,
|
27 |
+
createdAt: new Date().toISOString(),
|
28 |
+
upvotes: 0,
|
29 |
+
downvotes: 0
|
30 |
+
}
|
31 |
+
return mockPost
|
32 |
+
}
|
33 |
+
|
34 |
+
if (!prompt) {
|
35 |
+
console.error(`cannot call the community API without a prompt, aborting..`)
|
36 |
+
throw new Error(`cannot call the community API without a prompt, aborting..`)
|
37 |
+
}
|
38 |
+
if (!assetUrl) {
|
39 |
+
console.error(`cannot call the community API without an assetUrl, aborting..`)
|
40 |
+
throw new Error(`cannot call the community API without an assetUrl, aborting..`)
|
41 |
+
}
|
42 |
+
|
43 |
+
try {
|
44 |
+
console.log(`calling POST ${apiUrl}/post with prompt: ${prompt}`)
|
45 |
+
|
46 |
+
const postId = uuidv4()
|
47 |
+
|
48 |
+
const post: Partial<Post> = { postId, appId, prompt, assetUrl }
|
49 |
+
|
50 |
+
console.table(post)
|
51 |
+
|
52 |
+
const res = await fetch(`${apiUrl}/post`, {
|
53 |
+
method: "POST",
|
54 |
+
headers: {
|
55 |
+
Accept: "application/json",
|
56 |
+
"Content-Type": "application/json",
|
57 |
+
Authorization: `Bearer ${apiToken}`,
|
58 |
+
},
|
59 |
+
body: JSON.stringify(post),
|
60 |
+
cache: 'no-store',
|
61 |
+
// we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache)
|
62 |
+
// next: { revalidate: 1 }
|
63 |
+
})
|
64 |
+
|
65 |
+
// console.log("res:", res)
|
66 |
+
// The return value is *not* serialized
|
67 |
+
// You can return Date, Map, Set, etc.
|
68 |
+
|
69 |
+
// Recommendation: handle errors
|
70 |
+
if (res.status !== 200) {
|
71 |
+
// This will activate the closest `error.js` Error Boundary
|
72 |
+
throw new Error('Failed to fetch data')
|
73 |
+
}
|
74 |
+
|
75 |
+
const response = (await res.json()) as CreatePostResponse
|
76 |
+
// console.log("response:", response)
|
77 |
+
return response.post
|
78 |
+
} catch (err) {
|
79 |
+
const error = `failed to post to community: ${err}`
|
80 |
+
console.error(error)
|
81 |
+
throw new Error(error)
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
export async function getLatestPosts(): Promise<Post[]> {
|
86 |
+
|
87 |
+
let posts: Post[] = []
|
88 |
+
|
89 |
+
// if the community API is disabled we don't fail,
|
90 |
+
// we just mock
|
91 |
+
if (!apiUrl) {
|
92 |
+
return posts
|
93 |
+
}
|
94 |
+
|
95 |
+
try {
|
96 |
+
// console.log(`calling GET ${apiUrl}/posts with renderId: ${renderId}`)
|
97 |
+
const res = await fetch(`${apiUrl}/posts/${appId}`, {
|
98 |
+
method: "GET",
|
99 |
+
headers: {
|
100 |
+
Accept: "application/json",
|
101 |
+
"Content-Type": "application/json",
|
102 |
+
Authorization: `Bearer ${apiToken}`,
|
103 |
+
},
|
104 |
+
cache: 'no-store',
|
105 |
+
// we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache)
|
106 |
+
// next: { revalidate: 1 }
|
107 |
+
})
|
108 |
+
|
109 |
+
// console.log("res:", res)
|
110 |
+
// The return value is *not* serialized
|
111 |
+
// You can return Date, Map, Set, etc.
|
112 |
+
|
113 |
+
// Recommendation: handle errors
|
114 |
+
if (res.status !== 200) {
|
115 |
+
// This will activate the closest `error.js` Error Boundary
|
116 |
+
throw new Error('Failed to fetch data')
|
117 |
+
}
|
118 |
+
|
119 |
+
const response = (await res.json()) as GetAppPostsResponse
|
120 |
+
// console.log("response:", response)
|
121 |
+
return Array.isArray(response?.posts) ? response?.posts : []
|
122 |
+
} catch (err) {
|
123 |
+
const error = `failed to get posts: ${err}`
|
124 |
+
console.error(error)
|
125 |
+
throw new Error(error)
|
126 |
+
}
|
127 |
+
}
|
src/favicon.ico
ADDED
src/icon.png
ADDED
src/types.ts
CHANGED
@@ -90,4 +90,27 @@ export type LLMEngine =
|
|
90 |
export type RenderingEngine =
|
91 |
| "VIDEOCHAIN"
|
92 |
| "OPENAI"
|
93 |
-
| "REPLICATE"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
export type RenderingEngine =
|
91 |
| "VIDEOCHAIN"
|
92 |
| "OPENAI"
|
93 |
+
| "REPLICATE"
|
94 |
+
|
95 |
+
export type Post = {
|
96 |
+
postId: string
|
97 |
+
appId: string
|
98 |
+
prompt: string
|
99 |
+
previewUrl: string
|
100 |
+
assetUrl: string
|
101 |
+
createdAt: string
|
102 |
+
upvotes: number
|
103 |
+
downvotes: number
|
104 |
+
}
|
105 |
+
|
106 |
+
export type CreatePostResponse = {
|
107 |
+
success?: boolean
|
108 |
+
error?: string
|
109 |
+
post: Post
|
110 |
+
}
|
111 |
+
|
112 |
+
export type GetAppPostsResponse = {
|
113 |
+
success?: boolean
|
114 |
+
error?: string
|
115 |
+
posts: Post[]
|
116 |
+
}
|