jbilcke-hf HF staff commited on
Commit
8fb2ec4
·
1 Parent(s): 6896326

debugging..

Browse files
src/app/games/dungeon.ts CHANGED
@@ -51,7 +51,7 @@ export const game: Game = {
51
  initialActionnables,
52
  getScenePrompt: (situation?: string) => [
53
  `screenshot from an adventure videogame`,
54
- // `first-person footage`,
55
  situation || initialSituation,
56
  `medieval`,
57
  `unreal engine`,
 
51
  initialActionnables,
52
  getScenePrompt: (situation?: string) => [
53
  `screenshot from an adventure videogame`,
54
+ // `first-person footage`,
55
  situation || initialSituation,
56
  `medieval`,
57
  `unreal engine`,
src/app/main.tsx CHANGED
@@ -18,6 +18,7 @@ import { RenderedScene } from "./types"
18
  import { predict } from "./predict"
19
  import { GameType } from "./games/types"
20
  import { defaultGame, games, getGame } from "./games"
 
21
 
22
  export default function Main() {
23
  const [isPending, startTransition] = useTransition()
@@ -80,56 +81,42 @@ export default function Main() {
80
 
81
  const handleUserAction = async (actionnable: string) => {
82
  console.log("user actionnable:", actionnable)
83
-
 
 
84
  // TODO: ask Llama2 what to do about it
85
  // we need a frame and some actionnables,
86
  // perhaps even some music or sound effects
87
 
88
  await startTransition(async () => {
89
-
90
- setLoading(true)
91
 
92
  const game = getGame(ref.current)
93
- const initialPrompt = [...game.getScenePrompt()].join(", ")
94
 
95
- const currentPrompt = situation
96
- ? [...game.getScenePrompt(situation)].join(", ")
97
- : initialPrompt
98
 
99
  try {
100
- const basePrompt = [
101
- `QUESTION: You are the AI game master of a role video game.`,
102
- initialPrompt !== currentPrompt ? `The initial scene of the game was this: "${initialPrompt}".` : '',
103
- `The player is currently in this scene: "${currentPrompt}".`,
104
- `The player has just clicked on "${actionnable}".`
105
- ]
106
 
107
  console.log("ask the LLM to invent next steps..")
108
 
109
- const rawSituation = await predict([
110
- ...basePrompt,
111
- `Please describe the new scene to display in intricate details: the environment, lights, era, characters, objects, textures, light etc. You must include important objects, that the user can click on (eg. characters, doors, vehicles, useful objects).\nANSWER:`
112
- ].join(" "))
113
 
114
  console.log(`rawSituation: `, rawSituation)
115
 
116
  if (!rawSituation) {
117
  throw new Error("failed to generate the situation")
118
  }
119
- const newSituation = `${rawSituation.split("QUESTION:")[0] || ""}`
120
  if (!newSituation) {
121
  throw new Error("failed to parse the situation")
122
  }
123
 
124
  console.log(`newSituation: `, newSituation)
125
 
126
- const rawActionnables = await predict([
127
- ...basePrompt,
128
- `Here are the 4 most important objects visible in this scene, that the user can click on. The list is in JSON (list of strings). You must list basic name of things (eg. "parrot", "chest", "spaceship", "glass", "door", "person", "window", "light", "knob", "button" etc..) \nJSON = [`
129
- ].join(" "))
130
  console.log(`rawActionnables: `, rawActionnables)
131
 
132
-
133
  if (!rawActionnables) {
134
  throw new Error("failed to generate the actionnables")
135
  }
@@ -152,17 +139,13 @@ export default function Main() {
152
 
153
  console.log(`newActionnables: `, newActionnables)
154
 
155
-
156
- const rawDialogue = await predict([
157
- ...basePrompt,
158
- `As a game master, what should you say next? (Only reply with 2 sentences, please).\nANSWER:`
159
- ].join(" "))
160
  console.log(`rawDialogue: `, rawDialogue)
161
 
162
  if (!rawDialogue) {
163
  throw new Error("failed to generate the dialogue")
164
  }
165
- const newDialogue = `${rawDialogue.split("QUESTION:")[0] || ""}`
166
  if (!newDialogue) {
167
  throw new Error("failed to parse the dialogue")
168
  }
 
18
  import { predict } from "./predict"
19
  import { GameType } from "./games/types"
20
  import { defaultGame, games, getGame } from "./games"
21
+ import { getPrompts } from "./prompts"
22
 
23
  export default function Main() {
24
  const [isPending, startTransition] = useTransition()
 
81
 
82
  const handleUserAction = async (actionnable: string) => {
83
  console.log("user actionnable:", actionnable)
84
+
85
+ setLoading(true)
86
+
87
  // TODO: ask Llama2 what to do about it
88
  // we need a frame and some actionnables,
89
  // perhaps even some music or sound effects
90
 
91
  await startTransition(async () => {
 
 
92
 
93
  const game = getGame(ref.current)
 
94
 
95
+ const prompts = getPrompts(game, situation, actionnable)
96
+
97
+ console.log("prompts:", prompts)
98
 
99
  try {
 
 
 
 
 
 
100
 
101
  console.log("ask the LLM to invent next steps..")
102
 
103
+ const rawSituation = await predict(prompts.situationPrompt)
 
 
 
104
 
105
  console.log(`rawSituation: `, rawSituation)
106
 
107
  if (!rawSituation) {
108
  throw new Error("failed to generate the situation")
109
  }
110
+ const newSituation = `${rawSituation || ""}`
111
  if (!newSituation) {
112
  throw new Error("failed to parse the situation")
113
  }
114
 
115
  console.log(`newSituation: `, newSituation)
116
 
117
+ const rawActionnables = await predict(prompts.actionnablesPrompt)
 
 
 
118
  console.log(`rawActionnables: `, rawActionnables)
119
 
 
120
  if (!rawActionnables) {
121
  throw new Error("failed to generate the actionnables")
122
  }
 
139
 
140
  console.log(`newActionnables: `, newActionnables)
141
 
142
+ const rawDialogue = await predict(prompts.dialoguePrompt)
 
 
 
 
143
  console.log(`rawDialogue: `, rawDialogue)
144
 
145
  if (!rawDialogue) {
146
  throw new Error("failed to generate the dialogue")
147
  }
148
+ const newDialogue = `${rawDialogue || ""}`
149
  if (!newDialogue) {
150
  throw new Error("failed to parse the dialogue")
151
  }
src/app/predict.ts CHANGED
@@ -24,6 +24,7 @@ export async function predict(inputs: string) {
24
  if (
25
  instructions.includes("</s>") ||
26
  instructions.includes("<s>") ||
 
27
  instructions.includes("<|end|>") ||
28
  instructions.includes("<|assistant|>")
29
  ) {
@@ -40,6 +41,7 @@ export async function predict(inputs: string) {
40
  .replaceAll("<|end|>", "")
41
  .replaceAll("<s>", "")
42
  .replaceAll("</s>", "")
 
43
  .replaceAll("<|assistant|>", "")
44
  .replaceAll('""', '"')
45
  )
 
24
  if (
25
  instructions.includes("</s>") ||
26
  instructions.includes("<s>") ||
27
+ instructions.includes("</SYS>") ||
28
  instructions.includes("<|end|>") ||
29
  instructions.includes("<|assistant|>")
30
  ) {
 
41
  .replaceAll("<|end|>", "")
42
  .replaceAll("<s>", "")
43
  .replaceAll("</s>", "")
44
+ .replaceAll("</SYS>", "")
45
  .replaceAll("<|assistant|>", "")
46
  .replaceAll('""', '"')
47
  )
src/app/prompts.ts ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Game } from "./games/types"
2
+
3
+
4
+ export const getPrompts = (game: Game, situation: string = "", actionnable: string = "") => {
5
+
6
+ const initialPrompt = [...game.getScenePrompt()].join(", ")
7
+
8
+ const currentPrompt = situation
9
+ ? [...game.getScenePrompt(situation)].join(", ")
10
+ : initialPrompt
11
+
12
+ const userSituationPrompt = [
13
+ `[PROMPT] Player is currently in "${currentPrompt}". Player clicked on the "${actionnable}".`
14
+ ]
15
+
16
+ const baseSituationPromptIfWeHaveHistory = initialPrompt !== currentPrompt
17
+ ? ` You must imagine the most plausible next scene, based on where the player was located before and is now, and also what the player did before and are doing now.
18
+ Here is the original scene in which the user was located at first, which will inform you about the general settings to follow (you must respect this): "${initialPrompt}".`
19
+ : ""
20
+
21
+ const situationSystemPrompt = [
22
+ `[INST] <<SYS>>
23
+ You are the AI game master of a role video game.${baseSituationPromptIfWeHaveHistory}
24
+ You are going to receive new information about the current whereabouts of the player.
25
+ Please describe the next plausible scene to display in intricate details: the environment, lights, era, characters, objects, textures, light etc. You must include important objects, that the user can click on (eg. characters, doors, vehicles, useful objects).
26
+ <</SYS>>`,
27
+ ]
28
+
29
+ const situationPrompt = [
30
+ ...situationSystemPrompt,
31
+ ...userSituationPrompt,
32
+ ].join(" ")
33
+
34
+ const actionnablesSystemPrompt = [
35
+ `[INST] <<SYS>>
36
+ You are an API endpoint that can return a list of objects thare are in a scene.
37
+ You must list basic name of things (eg. "parrot", "chest", "spaceship", "glass", "door", "person", "window", "light", "knob", "button" <etc styleName=""></etc>
38
+ The answer must be a JSON array, ie. a list of quoted strings.
39
+ <</SYS>>`,
40
+ ]
41
+
42
+ const actionnablesPrompt = [
43
+ ...actionnablesSystemPrompt,
44
+ currentPrompt
45
+ ].join(" ")
46
+
47
+ const baseDialoguePromptIfWeHaveHistory = initialPrompt !== currentPrompt
48
+ ? `for your information, the initial game panel and scene was: "${initialPrompt}".`
49
+ : ""
50
+
51
+ const dialogueSystemPrompt = [
52
+ `[INST] <<SYS>>
53
+ You are the AI game master of a role video game.
54
+ You are going to receive new information about the current whereabouts and action of the player.
55
+ ${baseDialoguePromptIfWeHaveHistory}
56
+ You must imagine a funny response to speak in reaction to what the player did, like in some old point and click video games.
57
+ Please limit yourself to only a 1 or 2 sentences, please.
58
+ <</SYS>>`
59
+ ]
60
+
61
+ const dialoguePrompt = [
62
+ ...dialogueSystemPrompt,
63
+ ...userSituationPrompt,
64
+ ].join(" ")
65
+
66
+ const prompts = {
67
+ initialPrompt,
68
+ currentPrompt,
69
+ userSituationPrompt,
70
+ baseSituationPromptIfWeHaveHistory,
71
+ situationSystemPrompt,
72
+ situationPrompt,
73
+ actionnablesSystemPrompt,
74
+ actionnablesPrompt,
75
+ baseDialoguePromptIfWeHaveHistory,
76
+ dialogueSystemPrompt,
77
+ dialoguePrompt,
78
+ }
79
+
80
+ return prompts
81
+ }
82
+
83
+
src/components/business/image-renderer.tsx CHANGED
@@ -1,6 +1,7 @@
1
  import { useEffect, useRef, useState } from "react"
2
 
3
  import { ImageSegment, RenderedScene } from "@/app/types"
 
4
 
5
  export const ImageRenderer = ({
6
  rendered: {
@@ -21,6 +22,7 @@ export const ImageRenderer = ({
21
  const canvasRef = useRef<HTMLCanvasElement | null>(null)
22
  const contextRef = useRef<CanvasRenderingContext2D | null>(null)
23
  const [actionnable, setActionnable] = useState<string>("")
 
24
 
25
  useEffect(() => {
26
  if (maskBase64) {
@@ -86,7 +88,7 @@ export const ImageRenderer = ({
86
  if(distance < minDistance) {
87
  minDistance = distance;
88
  closestSegment = segment;
89
- console.log(`${distance} -> ${segment.label}: score = ${segment.score}`)
90
  }
91
  });
92
 
@@ -127,9 +129,36 @@ export const ImageRenderer = ({
127
  }
128
  };
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  if (!assetUrl) {
131
  return <div className="flex w-full h-screen items-center justify-center text-center">
132
- <div>Generating a new panel..</div>
 
 
 
133
  </div>
134
  }
135
 
 
1
  import { useEffect, useRef, useState } from "react"
2
 
3
  import { ImageSegment, RenderedScene } from "@/app/types"
4
+ import { ProgressBar } from "../misc/progress"
5
 
6
  export const ImageRenderer = ({
7
  rendered: {
 
22
  const canvasRef = useRef<HTMLCanvasElement | null>(null)
23
  const contextRef = useRef<CanvasRenderingContext2D | null>(null)
24
  const [actionnable, setActionnable] = useState<string>("")
25
+ const [progressPercent, setProcessPercent] = useState(0)
26
 
27
  useEffect(() => {
28
  if (maskBase64) {
 
88
  if(distance < minDistance) {
89
  minDistance = distance;
90
  closestSegment = segment;
91
+ // console.log(`${distance} -> ${segment.label}: score = ${segment.score}`)
92
  }
93
  });
94
 
 
129
  }
130
  };
131
 
132
+ useEffect(() => {
133
+ let progress = 0
134
+
135
+ // note: when everything is fine, it takes about 45 seconds to render a new scene
136
+
137
+ const computeProgress = async () => {
138
+ console.log("'computing progress")
139
+ if (!isLoading && assetUrl) {
140
+ console.log("Finished loading!")
141
+ setProcessPercent(100)
142
+ return
143
+ }
144
+
145
+ console.log("still loading..")
146
+
147
+ setTimeout(() => {
148
+ setProcessPercent(progress++)
149
+ }, 1000)
150
+
151
+ }
152
+
153
+ computeProgress()
154
+ }, [isLoading, assetUrl])
155
+
156
  if (!assetUrl) {
157
  return <div className="flex w-full h-screen items-center justify-center text-center">
158
+ <ProgressBar
159
+ text="⌛"
160
+ progressPercentage={progressPercent}
161
+ />
162
  </div>
163
  }
164
 
src/components/misc/progress.tsx ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ import { CircularProgressbar } from "react-circular-progressbar"
4
+ import "react-circular-progressbar/dist/styles.css"
5
+
6
+ export function ProgressBar ({
7
+ className,
8
+ progressPercentage,
9
+ text
10
+ }: {
11
+ className?: string
12
+ progressPercentage?: number
13
+ text?: string
14
+ }) {
15
+ return (
16
+ <div className={className}>
17
+ <CircularProgressbar
18
+ // doc: https://www.npmjs.com/package/react-circular-progressbar
19
+
20
+ value={progressPercentage || 0}
21
+
22
+ // Text to display inside progressbar. Default: ''.
23
+ text={text || ""}
24
+
25
+ // Width of circular line relative to total width of component, a value from 0-100. Default: 8.
26
+ strokeWidth={8}
27
+
28
+ /*
29
+ // As a convenience, you can use buildStyles to configure the most common style changes:
30
+
31
+ styles={buildStyles({
32
+ // Rotation of path and trail, in number of turns (0-1)
33
+ rotation: 0.25,
34
+
35
+ // Whether to use rounded or flat corners on the ends - can use 'butt' or 'round'
36
+ strokeLinecap: 'butt',
37
+
38
+ // Text size
39
+ textSize: '16px',
40
+
41
+ // How long animation takes to go from one percentage to another, in seconds
42
+ pathTransitionDuration: 0.5,
43
+
44
+ // Can specify path transition in more detail, or remove it entirely
45
+ // pathTransition: 'none',
46
+
47
+ // Colors
48
+ pathColor: `rgba(62, 152, 199, ${percentage / 100})`,
49
+ textColor: '#f88',
50
+ trailColor: '#d6d6d6',
51
+ backgroundColor: '#3e98c7',
52
+ })}
53
+ */
54
+ />
55
+ </div>
56
+ )
57
+ }