.gitignore DELETED
@@ -1,44 +0,0 @@
1
- # Dependencies
2
- node_modules/
3
- .pnpm-store/
4
-
5
- # Build outputs
6
- dist/
7
- build/
8
-
9
- # Environment files
10
- .env
11
- .env.*
12
- !.env.example
13
-
14
- # IDE and editor files
15
- .vscode/
16
- .idea/
17
- *.swp
18
- *.swo
19
- .DS_Store
20
- Thumbs.db
21
-
22
- # Debug logs
23
- npm-debug.log*
24
- yarn-debug.log*
25
- yarn-error.log*
26
- pnpm-debug.log*
27
-
28
- # Cache directories
29
- .cache/
30
- .temp/
31
- .vite/
32
-
33
- # Test coverage
34
- coverage/
35
-
36
-
37
- # Temporary files
38
- *.tmp
39
- *.temp
40
-
41
-
42
- # System files
43
- .DS_Store
44
- desktop.ini
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Dockerfile CHANGED
@@ -26,4 +26,4 @@ EXPOSE 7860
26
  ENV BROWSER=none
27
 
28
  # Start the Vite development server with specific configurations
29
- CMD ["npm", "run", "dev", "--", "--host", "--port", "7860", "--strictPort"]
 
26
  ENV BROWSER=none
27
 
28
  # Start the Vite development server with specific configurations
29
+ CMD ["npm", "run", "dev", "--", "--host", "--port", "7860", "--strictPort"]
README.md CHANGED
@@ -1,12 +1,11 @@
1
  ---
2
- title: Shyguy's Wingman
3
- emoji: 💘
4
- colorFrom: purple
5
- colorTo: yellow
6
  sdk: docker
7
  pinned: false
8
- short_description: Help the Shy Guy finaly talk to Jessica
9
- thumbnail: >-
10
- https://cdn-uploads.huggingface.co/production/uploads/65707a9053269901a14c5b3d/1OIdDpFEAKjWB_9jq4SA9.png
11
  ---
12
- Please feel free to contribute !
 
 
 
1
  ---
2
+ title: Shyguys
3
+ emoji: 🦀
4
+ colorFrom: red
5
+ colorTo: pink
6
  sdk: docker
7
  pinned: false
 
 
 
8
  ---
9
+
10
+
11
+ Clone the repository and run npm run dev
api.js DELETED
@@ -1,3 +0,0 @@
1
- export const HUGGINGFACE_API_KEY = process.env.HUGGINGFACE_API_KEY;
2
- export const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;
3
- export const MISTRAL_API_KEY = process.env.MISTRAL_API_KEY;
 
 
 
 
leaderboard.txt DELETED
@@ -1,32 +0,0 @@
1
-
2
-
3
-
4
-
5
-
6
-
7
- David Dobas Score: 695
8
- David Dobas Score: 287
9
- David Dobas Score: 246
10
- David Dobas Score: 833
11
- David Dobas Score: 213
12
- David Dobas Score: 380
13
- David Dobas Score: 393
14
- David Dobas Score: 234
15
- David Dobas Score: 224
16
- David Dobas Score: 541
17
- David Dobas Score: 361
18
- David Dobas Score: 720
19
- David Dobas Score: 571
20
- David Dobas Score: 135
21
- David Dobas Score: 192
22
- David Dobas Score: 327
23
- David Dobas Score: 282
24
- David Dobas Score: 209
25
- David Dobas Score: 231
26
- David Dobas Score: 506
27
- David Dobas Score: 233
28
- David Dobas Score: 746
29
- David Dobas Score: 312
30
- David Dobas Score: 492
31
- David Dobas Score: 611
32
- David Dobas Score: 151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package-lock.json CHANGED
@@ -8,7 +8,6 @@
8
  "name": "shyguys-wingman-js",
9
  "version": "1.0.0",
10
  "dependencies": {
11
- "dotenv": "^16.4.7",
12
  "elevenlabs": "^1.50.4"
13
  },
14
  "devDependencies": {
@@ -845,18 +844,6 @@
845
  "node": ">=0.4.0"
846
  }
847
  },
848
- "node_modules/dotenv": {
849
- "version": "16.4.7",
850
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
851
- "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
852
- "license": "BSD-2-Clause",
853
- "engines": {
854
- "node": ">=12"
855
- },
856
- "funding": {
857
- "url": "https://dotenvx.com"
858
- }
859
- },
860
  "node_modules/dunder-proto": {
861
  "version": "1.0.1",
862
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
 
8
  "name": "shyguys-wingman-js",
9
  "version": "1.0.0",
10
  "dependencies": {
 
11
  "elevenlabs": "^1.50.4"
12
  },
13
  "devDependencies": {
 
844
  "node": ">=0.4.0"
845
  }
846
  },
 
 
 
 
 
 
 
 
 
 
 
 
847
  "node_modules/dunder-proto": {
848
  "version": "1.0.1",
849
  "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
package.json CHANGED
@@ -9,7 +9,6 @@
9
  "preview": "vite preview"
10
  },
11
  "dependencies": {
12
- "dotenv": "^16.4.7",
13
  "elevenlabs": "^1.50.4"
14
  },
15
  "devDependencies": {
 
9
  "preview": "vite preview"
10
  },
11
  "dependencies": {
 
12
  "elevenlabs": "^1.50.4"
13
  },
14
  "devDependencies": {
replace.txt DELETED
@@ -1,2 +0,0 @@
1
- vvO2N5PA9dj8cO6BwcIB8oH4YRnQI3Tn==your_actual_api_key_1
2
- sk_62d0fc2ccddb1a4036f624dd8c411383fd9b9990755ea086==your_actual_api_key_2
 
 
 
src/eleven_labs.js CHANGED
@@ -1,9 +1,8 @@
1
  import { SHYGUY_LABEL, SISTER_LABEL, GIRL_LABEL, BAR_LABEL, DJ_LABEL, WINGMAN_LABEL } from "./constants.js";
2
- import { ELEVENLABS_API_KEY } from "../api.js";
3
 
4
  export class ElevenLabsClient {
5
  constructor() {
6
- this.apiKey = ELEVENLABS_API_KEY;
7
  this.baseUrl = "https://api.elevenlabs.io/v1";
8
  }
9
 
@@ -38,7 +37,7 @@ export class ElevenLabsClient {
38
  async createSpeech({
39
  text,
40
  voiceId,
41
- modelId = "eleven_flash_v2",
42
  outputFormat = "mp3_44100_128",
43
  voiceSettings = null,
44
  pronunciationDictionaryLocators = null,
 
1
  import { SHYGUY_LABEL, SISTER_LABEL, GIRL_LABEL, BAR_LABEL, DJ_LABEL, WINGMAN_LABEL } from "./constants.js";
 
2
 
3
  export class ElevenLabsClient {
4
  constructor() {
5
+ this.apiKey = "sk_62d0fc2ccddb1a4036f624dd8c411383fd9b9990755ea086";
6
  this.baseUrl = "https://api.elevenlabs.io/v1";
7
  }
8
 
 
37
  async createSpeech({
38
  text,
39
  voiceId,
40
+ modelId = "eleven_multilingual_v2",
41
  outputFormat = "mp3_44100_128",
42
  voiceSettings = null,
43
  pronunciationDictionaryLocators = null,
src/game_engine.js CHANGED
@@ -165,11 +165,11 @@ export class GameEngine {
165
  // Debug controls
166
  this.initDebugControls();
167
 
168
- // configure environment building blocks and enable passing them
169
  this.gridMapTypes = {
170
- floor: { index: 0, passable: true },
171
- wall: { index: 1, passable: false },
172
- door: { index: 2, passable: false },
173
  };
174
 
175
  // load assets for drawing the scene
@@ -283,9 +283,6 @@ export class GameEngine {
283
  document.addEventListener("keyup", this.handleKeyUp);
284
 
285
  // Initialize with game view
286
- const intialStatusText =
287
- "You are playing as the Wingman. You can move around using arrow keys. Maybe Shyguy will listen to you or let you follow him around. Don't let him leave without the girl!";
288
- this.updateStatus(intialStatusText);
289
 
290
  this.sendButton.addEventListener("click", this.handleSendMessage);
291
  this.dialogueContinueButton.addEventListener("click", this.handleDialogueContinue);
@@ -370,13 +367,13 @@ export class GameEngine {
370
  for (let col = 0; col < this.gridCols; col++) {
371
  // Set walls and obstacles (in future)
372
  if (row === 0 || row === this.gridRows - 1 || col === 0 || col === this.gridCols - 1) {
373
- this.backgroundGridMap[row][col] = this.gridMapTypes.wall.index;
374
  } else {
375
- this.backgroundGridMap[row][col] = this.gridMapTypes.floor.index;
376
  }
377
  }
378
  }
379
- this.backgroundGridMap[0][1] = this.gridMapTypes.door.index;
380
  }
381
 
382
  checkWallCollision(sprite, newX, newY) {
@@ -391,9 +388,7 @@ export class GameEngine {
391
  for (let row = gridY; row <= Math.floor((y + sprite.height) / (sprite.height / 2)); row++) {
392
  for (let col = gridX; col <= Math.floor((x + sprite.width) / (sprite.width * 1.33)); col++) {
393
  if (row >= 0 && row < this.gridRows && col >= 0 && col < this.gridCols) {
394
- const cellType = this.backgroundGridMap[row][col];
395
- const typeInfo = Object.values(this.gridMapTypes).find((type) => type.index === cellType);
396
- if (typeInfo && !typeInfo.passable) {
397
  return true;
398
  }
399
  }
@@ -572,8 +567,7 @@ export class GameEngine {
572
  }
573
 
574
  handleKeyDown(e) {
575
- // Only handle arrow keys for player movement if the text input is not focused
576
- if (e.key in this.keys && !document.activeElement.matches('input[type="text"], textarea')) {
577
  this.keys[e.key] = true;
578
  this.wingmanSprite.moving = true;
579
  } else if (e.key === "Enter" && this.currentView === "game" && !e.shiftKey) {
@@ -670,7 +664,7 @@ export class GameEngine {
670
  if (isClose) {
671
  // pause the game
672
  target.enabled = false;
673
- this.stopShyguyAnimation();
674
 
675
  if (target.label === EXIT_LABEL) {
676
  this.gameOver = true;
@@ -744,7 +738,7 @@ export class GameEngine {
744
  this.showContinueButton();
745
  }
746
 
747
- stopShyguyAnimation() {
748
  this.shyguySprite.moving = false;
749
  this.shyguySprite.frameX = 0;
750
  this.shyguySprite.target = null;
@@ -759,47 +753,52 @@ export class GameEngine {
759
  const x = col * this.wall.width;
760
  const y = row * this.wall.height;
761
 
762
- if (this.backgroundGridMap[row][col] === this.gridMapTypes.wall.index) {
763
  this.ctx.drawImage(this.wall.image, x, y, this.wall.width, this.wall.height);
764
- } else if (this.backgroundGridMap[row][col] === this.gridMapTypes.floor.index) {
765
  this.ctx.drawImage(this.floor.image, x, y, this.floor.width, this.floor.height);
766
- } else if (this.backgroundGridMap[row][col] === this.gridMapTypes.door.index) {
767
  this.ctx.drawImage(this.door.image, x, y, this.door.width, this.door.height);
768
  }
769
  }
770
  }
771
 
772
- // Draw npcs with targets
773
  this.drawTargetSprite(this.jessicaSprite, this.targets.girl);
774
  this.drawTargetSprite(this.barSprite, this.targets.bar);
775
  this.drawTargetSprite(this.djSprite, this.targets.dj);
776
  this.drawTargetSprite(this.sisterSprite, this.targets.sister);
777
 
778
  // Draw shyguy
779
- this.drawPlayerSprite(this.shyguySprite);
 
 
 
 
 
 
 
 
 
 
780
 
781
  // Draw wingman
782
- this.drawPlayerSprite(this.wingmanSprite);
 
 
 
 
 
 
 
 
 
 
783
  }
784
 
785
  drawTargetSprite(sprite, target) {
786
  this.ctx.drawImage(sprite.image, target.x, target.y, target.width, target.height);
787
  }
788
 
789
- drawPlayerSprite(sprite) {
790
- this.ctx.drawImage(
791
- sprite.image,
792
- sprite.frameX * sprite.width,
793
- sprite.frameY * sprite.height,
794
- sprite.width,
795
- sprite.height,
796
- sprite.x,
797
- sprite.y,
798
- sprite.width,
799
- sprite.height
800
- );
801
- }
802
-
803
  switchView(viewName) {
804
  if (viewName === this.currentView) return;
805
 
@@ -924,6 +923,7 @@ export class GameEngine {
924
  }
925
 
926
  resolveAction(action) {
 
927
  switch (action) {
928
  case "stay_idle":
929
  this.setNewTarget(null);
@@ -970,11 +970,6 @@ export class GameEngine {
970
  // TODO: save conversation history
971
  await this.shyguy.learnFromWingman(message);
972
  console.log("[ShyguyLLM]: Next action: ", action);
973
- this.shyguy.last_actions.push(action);
974
- if (this.shyguy.num_beers >= 1) {
975
- console.log("Updating status to: Shyguy is drunk. Try pushing him.");
976
- this.updateStatus("Shyguy is drunk. Try pushing him.");
977
- }
978
  this.resolveAction(action);
979
  });
980
  }
@@ -998,7 +993,6 @@ export class GameEngine {
998
  handlePlayAgain() {
999
  this.clearChat(this.gameChatContainer);
1000
  this.resetGame();
1001
- this.stopGameOverMusic();
1002
  this.switchView("game");
1003
  }
1004
 
@@ -1081,12 +1075,9 @@ export class GameEngine {
1081
  }
1082
 
1083
  this.switchView("game");
1084
- this.shyguyLLM.getShyGuyResponse("Where do you go next? Your available actions are: " + this.shyguy.getAvailableActions()).then((response) => {
1085
  const next_action = response.action;
1086
- if (this.shyguy.num_beers >= 1) {
1087
- console.log("Updating status to: Shyguy is drunk. Try pushing him.");
1088
- this.updateStatus("Shyguy is drunk. Try pushing him.");
1089
- }
1090
  this.resolveAction(next_action);
1091
  });
1092
  }
@@ -1126,18 +1117,14 @@ export class GameEngine {
1126
  });
1127
  }
1128
 
1129
- stopGameOverMusic() {
 
1130
  this.gameOverMusic.pause();
1131
  this.gameOverMusic.currentTime = 0;
1132
  this.victoryMusic.pause();
1133
  this.victoryMusic.currentTime = 0;
1134
  }
1135
 
1136
- stopAllMusic() {
1137
- this.stopBackgroundMusic();
1138
- this.stopGameOverMusic();
1139
- }
1140
-
1141
  lowerMusicVolume() {
1142
  // Store original volumes if not already stored
1143
  if (!this.originalVolumes) {
 
165
  // Debug controls
166
  this.initDebugControls();
167
 
168
+ // if we have other obstacles, we can add them here
169
  this.gridMapTypes = {
170
+ floor: 0,
171
+ wall: 1,
172
+ door: 2,
173
  };
174
 
175
  // load assets for drawing the scene
 
283
  document.addEventListener("keyup", this.handleKeyUp);
284
 
285
  // Initialize with game view
 
 
 
286
 
287
  this.sendButton.addEventListener("click", this.handleSendMessage);
288
  this.dialogueContinueButton.addEventListener("click", this.handleDialogueContinue);
 
367
  for (let col = 0; col < this.gridCols; col++) {
368
  // Set walls and obstacles (in future)
369
  if (row === 0 || row === this.gridRows - 1 || col === 0 || col === this.gridCols - 1) {
370
+ this.backgroundGridMap[row][col] = this.gridMapTypes.wall;
371
  } else {
372
+ this.backgroundGridMap[row][col] = this.gridMapTypes.floor;
373
  }
374
  }
375
  }
376
+ this.backgroundGridMap[0][1] = this.gridMapTypes.door;
377
  }
378
 
379
  checkWallCollision(sprite, newX, newY) {
 
388
  for (let row = gridY; row <= Math.floor((y + sprite.height) / (sprite.height / 2)); row++) {
389
  for (let col = gridX; col <= Math.floor((x + sprite.width) / (sprite.width * 1.33)); col++) {
390
  if (row >= 0 && row < this.gridRows && col >= 0 && col < this.gridCols) {
391
+ if (this.backgroundGridMap[row][col] === this.gridMapTypes.wall) {
 
 
392
  return true;
393
  }
394
  }
 
567
  }
568
 
569
  handleKeyDown(e) {
570
+ if (e.key in this.keys) {
 
571
  this.keys[e.key] = true;
572
  this.wingmanSprite.moving = true;
573
  } else if (e.key === "Enter" && this.currentView === "game" && !e.shiftKey) {
 
664
  if (isClose) {
665
  // pause the game
666
  target.enabled = false;
667
+ this.stopShyguyAnimation(target);
668
 
669
  if (target.label === EXIT_LABEL) {
670
  this.gameOver = true;
 
738
  this.showContinueButton();
739
  }
740
 
741
+ stopShyguyAnimation(target) {
742
  this.shyguySprite.moving = false;
743
  this.shyguySprite.frameX = 0;
744
  this.shyguySprite.target = null;
 
753
  const x = col * this.wall.width;
754
  const y = row * this.wall.height;
755
 
756
+ if (this.backgroundGridMap[row][col] === this.gridMapTypes.wall) {
757
  this.ctx.drawImage(this.wall.image, x, y, this.wall.width, this.wall.height);
758
+ } else if (this.backgroundGridMap[row][col] === this.gridMapTypes.floor) {
759
  this.ctx.drawImage(this.floor.image, x, y, this.floor.width, this.floor.height);
760
+ } else if (this.backgroundGridMap[row][col] === this.gridMapTypes.door) {
761
  this.ctx.drawImage(this.door.image, x, y, this.door.width, this.door.height);
762
  }
763
  }
764
  }
765
 
 
766
  this.drawTargetSprite(this.jessicaSprite, this.targets.girl);
767
  this.drawTargetSprite(this.barSprite, this.targets.bar);
768
  this.drawTargetSprite(this.djSprite, this.targets.dj);
769
  this.drawTargetSprite(this.sisterSprite, this.targets.sister);
770
 
771
  // Draw shyguy
772
+ this.ctx.drawImage(
773
+ this.shyguySprite.image,
774
+ this.shyguySprite.frameX * this.shyguySprite.width,
775
+ this.shyguySprite.frameY * this.shyguySprite.height,
776
+ this.shyguySprite.width,
777
+ this.shyguySprite.height,
778
+ this.shyguySprite.x,
779
+ this.shyguySprite.y,
780
+ this.shyguySprite.width,
781
+ this.shyguySprite.height
782
+ );
783
 
784
  // Draw wingman
785
+ this.ctx.drawImage(
786
+ this.wingmanSprite.image,
787
+ this.wingmanSprite.frameX * this.wingmanSprite.width,
788
+ this.wingmanSprite.frameY * this.wingmanSprite.height,
789
+ this.wingmanSprite.width,
790
+ this.wingmanSprite.height,
791
+ this.wingmanSprite.x,
792
+ this.wingmanSprite.y,
793
+ this.wingmanSprite.width,
794
+ this.wingmanSprite.height
795
+ );
796
  }
797
 
798
  drawTargetSprite(sprite, target) {
799
  this.ctx.drawImage(sprite.image, target.x, target.y, target.width, target.height);
800
  }
801
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
802
  switchView(viewName) {
803
  if (viewName === this.currentView) return;
804
 
 
923
  }
924
 
925
  resolveAction(action) {
926
+ // TODO: resolve the action
927
  switch (action) {
928
  case "stay_idle":
929
  this.setNewTarget(null);
 
970
  // TODO: save conversation history
971
  await this.shyguy.learnFromWingman(message);
972
  console.log("[ShyguyLLM]: Next action: ", action);
 
 
 
 
 
973
  this.resolveAction(action);
974
  });
975
  }
 
993
  handlePlayAgain() {
994
  this.clearChat(this.gameChatContainer);
995
  this.resetGame();
 
996
  this.switchView("game");
997
  }
998
 
 
1075
  }
1076
 
1077
  this.switchView("game");
1078
+ this.shyguyLLM.getShyGuyResponse("").then((response) => {
1079
  const next_action = response.action;
1080
+
 
 
 
1081
  this.resolveAction(next_action);
1082
  });
1083
  }
 
1117
  });
1118
  }
1119
 
1120
+ stopAllMusic() {
1121
+ this.stopBackgroundMusic();
1122
  this.gameOverMusic.pause();
1123
  this.gameOverMusic.currentTime = 0;
1124
  this.victoryMusic.pause();
1125
  this.victoryMusic.currentTime = 0;
1126
  }
1127
 
 
 
 
 
 
1128
  lowerMusicVolume() {
1129
  // Store original volumes if not already stored
1130
  if (!this.originalVolumes) {
src/llm.js CHANGED
@@ -1,8 +1,6 @@
1
- import { MISTRAL_API_KEY } from "../api.js";
2
-
3
  export class LLM {
4
  constructor() {
5
- this.apiKey = MISTRAL_API_KEY;
6
  }
7
 
8
  async getChatCompletion(systemPrompt, userInput) {
 
 
 
1
  export class LLM {
2
  constructor() {
3
+ this.apiKey = "vvO2N5PA9dj8cO6BwcIB8oH4YRnQI3Tn";
4
  }
5
 
6
  async getChatCompletion(systemPrompt, userInput) {
src/shyguy.js CHANGED
@@ -4,34 +4,27 @@ export class Shyguy {
4
  constructor() {
5
  this.num_beers = 0;
6
  this.courage = 1;
7
- this.personality = "This is the Shyguy. He is shy and introverted. He is also a bit of a nerd. He fell in love with Jessica. He never talked to Jessica before.To Jessica, he talks about algorithms. Jessica does not talk about algorithms. He is super shy.";
8
  this.lessons_learned = "";
9
  this.conversation_history = "";
10
  this.song_playing = "Let it be";
11
  this.imgpath = "assets/assets/shyguy_headshot.jpeg";
12
- this.met_dj = false;
13
- this.met_bar = false;
14
- this.met_sister = false;
15
  this.last_actions = [];
16
  }
17
 
18
  getSystemPrompt() {
19
  if (this.num_beers >= 3) {
20
- return `${this.personality}. His courage is ${this.courage} on the level 1 to 10. If his courage is higher than 5, he is self-confident. He had too many beers and he is drunk. He talks about how drunk he is. Follow the following lessons: ${this.lessons_learned}. ${this.met_dj ? "He has met the DJ already." : "He has not met the DJ yet."} ${this.met_bar ? "He has met the bartender already." : "He has not met the bartender yet."} ${this.met_sister ? "He has met Jessica's sister already." : "He has not met Jessica's sister yet."}`;
21
  } else if (this.num_beers == 2) {
22
- return `This is Shyguy. He had two beers, so he feels relaxed and he can talk with anyone. ${this.met_dj ? "He has met the DJ already." : "He has not met the DJ yet."} ${this.met_bar ? "He has met the bartender already." : "He has not met the bartender yet."} ${this.met_sister ? "He has met Jessica's sister already." : "He has not met Jessica's sister yet."} Follow the following lessons: ${this.lessons_learned}.`;
23
  }
24
  else {
25
- return `${this.personality}. His courage is ${this.courage} on the level 1 to 10. If his courage is higher than 5, he is self-confident. He is really shy and he fears talking with people. It is not easy to persuade him. He does not want to drink at first. ${this.met_dj ? "He has met the DJ already." : "He has not met the DJ yet."} ${this.met_bar ? "He has met the bartender already." : "He has not met the bartender yet."} ${this.met_sister ? "He has met Jessica's sister already." : "He has not met Jessica's sister yet."} Follow the following lessons: ${this.lessons_learned}.`;
26
  }
27
  }
28
 
29
  appendLesson(lesson) {
30
  this.lessons_learned += lesson + "\n";
31
- // Keep only last 200 characters of lessons learned if too long
32
- if (this.lessons_learned.length > 400) {
33
- this.lessons_learned = this.lessons_learned.slice(-400);
34
- }
35
  }
36
 
37
  appendConversationHistory(conversation_history) {
@@ -39,54 +32,35 @@ export class Shyguy {
39
  }
40
 
41
  async learnLesson(entityName){
42
- console.log("Conversation history: ", this.conversation_history);
43
- if (this.conversation_history === "") {
44
- return;
45
- }
46
  const summaryLLM = new LLM();
47
  const summary = await summaryLLM.getChatCompletion(
48
- `Summarize in one sentence what Shyguy should say when talking to ${entityName}. Do not confuse Jessica and Jessica's sister. If there is nothing relevant about what to say to Jessica, say Nothing relevant. Do not hallucinate. Do not make up things.`,
49
  this.conversation_history
50
  );
51
  this.appendLesson(`When talking to ${entityName}, ${summary}`);
52
  }
53
 
54
  async learnFromWingman(wingman_message) {
55
- console.log("Wingman message: ", wingman_message);
56
  const summaryLLM = new LLM();
 
57
  const summary = await summaryLLM.getChatCompletion(
58
- `Summarize in one sentence what is learned from the message. Summary is one sentence. For example, if the wingman says "Let's have a beer", the output should be "Shyguy wants a beer". If the wingman says "Let's have vodka", the output should be "Shyguy wants vodka". If wingman just says "Hi", the output should be "Wingman said hi". Do not hallucinate. Do not make up things.`,
59
  wingman_message
60
  );
61
- console.log("Summary learned from wingman: ", summary);
62
- this.appendLesson(summary);
63
- }
64
-
65
- async learnFromConversation(conversation) {
66
- console.log("Conversation: ", conversation);
67
- const summaryLLM = new LLM();
68
- const summary = await summaryLLM.getChatCompletion(
69
- `Summarize in one sentence what happened in the conversation. Do not hallucinate. Do not make up things.`,
70
- conversation
71
- );
72
  this.appendLesson(summary);
73
  }
74
 
75
  getAvailableActions() {
76
  let actions = {};
77
  const lastAction = this.last_actions[this.last_actions.length - 1];
78
- console.log("[ShyGuy]: Last action: ", lastAction);
79
 
 
80
  if (this.num_beers === 0) {
81
  actions = {
82
  "go_bar": {
83
  description: "Head to the bar.",
84
  location: "bar",
85
  },
86
- "go_dj": {
87
- description: "Go to the DJ",
88
- location: "dj_booth",
89
- },
90
  "go_home": {
91
  description: "Give up and head home",
92
  location: "exit",
@@ -101,26 +75,19 @@ export class Shyguy {
101
  // After 2+ beers, all actions except going home are available
102
  actions = {
103
  "go_bar": {
104
- description: "Go to the bar",
105
  location: "bar",
106
  },
107
  "go_dj": {
108
- description: "GO to the DJ",
109
  location: "dj_booth",
110
  },
111
  "go_sister": {
112
- description: "Go to Jessica's sister",
113
  location: "sister",
114
  },
115
  "go_girl": {
116
- description: "Go to Jessica",
117
- location: "girl",
118
- }
119
- };
120
- } else if (this.num_beers >= 4) {
121
- actions = {
122
- "go_girl": {
123
- description: "Go to Jessica",
124
  location: "girl",
125
  }
126
  };
@@ -128,23 +95,23 @@ export class Shyguy {
128
  // After 1 beer but less than 2, all actions are available
129
  actions = {
130
  "go_bar": {
131
- description: "Go to the bar",
132
  location: "bar",
133
  },
134
  "go_home": {
135
- description: "Go home",
136
  location: "exit",
137
  },
138
  "go_dj": {
139
- description: "Go to the DJ",
140
  location: "dj_booth",
141
  },
142
  "go_sister": {
143
- description: "Go to Jessica's sister",
144
  location: "sister",
145
  },
146
  "go_girl": {
147
- description: "Go to Jessica",
148
  location: "girl",
149
  }
150
  };
@@ -154,8 +121,7 @@ export class Shyguy {
154
  if (lastAction && actions[lastAction]) {
155
  delete actions[lastAction];
156
  }
157
- console.log("[ShyGuy]: Last actions: ", this.last_actions);
158
- console.log("[ShyGuy]: Available actions: ", actions);
159
  return actions;
160
  }
161
  }
 
4
  constructor() {
5
  this.num_beers = 0;
6
  this.courage = 1;
7
+ this.personality = "This is the Shyguy. He is shy and introverted. He is also a bit of a nerd. He fell in love with Jessica. With Jessica, he talks about algorithms.";
8
  this.lessons_learned = "";
9
  this.conversation_history = "";
10
  this.song_playing = "Let it be";
11
  this.imgpath = "assets/assets/shyguy_headshot.jpeg";
 
 
 
12
  this.last_actions = [];
13
  }
14
 
15
  getSystemPrompt() {
16
  if (this.num_beers >= 3) {
17
+ return `${this.personality}. His courage is ${this.courage} on the level 1 to 10. If his courage is higher than 5, he is self-confident. He had too many beers and he is drunk. He talks about how drunk he is. Follow the following lessons: ${this.lessons_learned}`;
18
  } else if (this.num_beers == 2) {
19
+ return `This is Shyguy. He had two beers, so he feels relaxed and he can talk with anyone. Follow the following lessons: ${this.lessons_learned}`;
20
  }
21
  else {
22
+ return `${this.personality}. He had ${this.num_beers} numbers of beers and his courage is ${this.courage} on the level 1 to 10. If his courage is higher than 5, he is self-confident. After having 3 bears, he says single words with a lot of hesitation and says that he feels bad and he talks about how drunk he is. If courage is low, he hesitates to speak. Follow the following lessons: ${this.lessons_learned}`;
23
  }
24
  }
25
 
26
  appendLesson(lesson) {
27
  this.lessons_learned += lesson + "\n";
 
 
 
 
28
  }
29
 
30
  appendConversationHistory(conversation_history) {
 
32
  }
33
 
34
  async learnLesson(entityName){
 
 
 
 
35
  const summaryLLM = new LLM();
36
  const summary = await summaryLLM.getChatCompletion(
37
+ `Summarize in one sentence what Shyguy should say when talking to ${entityName}. Do not confuse Jessica and Jessica's sister. If there is nothing relevant about what to say to Jessica, say Nothing relevant.`,
38
  this.conversation_history
39
  );
40
  this.appendLesson(`When talking to ${entityName}, ${summary}`);
41
  }
42
 
43
  async learnFromWingman(wingman_message) {
 
44
  const summaryLLM = new LLM();
45
+ console.log("Wingman message: ", wingman_message);
46
  const summary = await summaryLLM.getChatCompletion(
47
+ `Give a summary of what is learned from the message. Summary is one sentence. The wingman is always talking. For example, if the wingman says "Let's have a beer", the output should be "Shyguy wants a beer". If the wingman says "Let's have vodka", the output should be "Shyguy wants vodka".`,
48
  wingman_message
49
  );
 
 
 
 
 
 
 
 
 
 
 
50
  this.appendLesson(summary);
51
  }
52
 
53
  getAvailableActions() {
54
  let actions = {};
55
  const lastAction = this.last_actions[this.last_actions.length - 1];
 
56
 
57
+ // When sober, can only go to the bar or home
58
  if (this.num_beers === 0) {
59
  actions = {
60
  "go_bar": {
61
  description: "Head to the bar.",
62
  location: "bar",
63
  },
 
 
 
 
64
  "go_home": {
65
  description: "Give up and head home",
66
  location: "exit",
 
75
  // After 2+ beers, all actions except going home are available
76
  actions = {
77
  "go_bar": {
78
+ description: "Head to the bar for liquid courage",
79
  location: "bar",
80
  },
81
  "go_dj": {
82
+ description: "Talk to the DJ about playing a song",
83
  location: "dj_booth",
84
  },
85
  "go_sister": {
86
+ description: "Approach your crush's sister",
87
  location: "sister",
88
  },
89
  "go_girl": {
90
+ description: "Approach your crush",
 
 
 
 
 
 
 
91
  location: "girl",
92
  }
93
  };
 
95
  // After 1 beer but less than 2, all actions are available
96
  actions = {
97
  "go_bar": {
98
+ description: "Head to the bar for liquid courage",
99
  location: "bar",
100
  },
101
  "go_home": {
102
+ description: "Give up and head home",
103
  location: "exit",
104
  },
105
  "go_dj": {
106
+ description: "Talk to the DJ about playing a song",
107
  location: "dj_booth",
108
  },
109
  "go_sister": {
110
+ description: "Approach your crush's sister",
111
  location: "sister",
112
  },
113
  "go_girl": {
114
+ description: "Approach your crush",
115
  location: "girl",
116
  }
117
  };
 
121
  if (lastAction && actions[lastAction]) {
122
  delete actions[lastAction];
123
  }
124
+
 
125
  return actions;
126
  }
127
  }
src/shyguy_llm.js CHANGED
@@ -6,10 +6,9 @@ export class ShyGuyLLM {
6
  this.currentConversation = []; // Array to store current conversation messages
7
  const availableActions = this.shyguy.getAvailableActions();
8
  this.baseSystemPrompt = `You are ShyGuy, a socially awkward character at a homecoming party. You are shy.
9
- The wingman progressively makes you more confident, and if you drink alcohol, you also get more confident.
10
  You know the wingman, he is your friend. You are talking to him.
11
  You are willing to have a little alcohol.
12
- If there is no clear action, you go home. Do not stay idle twice in a row.
13
  The action should correspond to the dialogue.
14
  Your responses should be in JSON format with two fields:
15
  enum action {
@@ -38,7 +37,7 @@ export class ShyGuyLLM {
38
  addToPrompt += `You are drunk and you start talking about how bad you feel. You are annoying. You talk about algorithms and then how bad you feel.\n`;
39
  }
40
  if (this.shyguy.courage < 2) {
41
- addToPrompt += `You are shy. However, you believe wingman. You are willing to go the DJ, you are just shy.`;
42
  }
43
  if (this.shyguy.courage >= 2) {
44
  addToPrompt += `You talk normally.`;
@@ -77,16 +76,12 @@ export class ShyGuyLLM {
77
  const actionsPrompt = `\nYour currently available actions are: ${Object.keys(availableActions)
78
  .map((action) => `\n- ${action}: ${availableActions[action].description}`)
79
  .join("")}`;
 
80
  // Add the situation to current conversation
81
  this.addToCurrentConversation('wingman', player_message);
82
 
83
- // Add the conversation to shyguy's history
84
- this.shyguy.conversation_history += `\nWingman: ${player_message}\n`;
85
-
86
  const fullPrompt = this.getSystemPrompt() + actionsPrompt;
87
- console.log("[ShyGuy]: Full prompt: ", fullPrompt);
88
  const response = await this.llm.getJsonCompletion(fullPrompt, player_message);
89
- console.log("[ShyGuy]: Response: ", response);
90
 
91
  // Add ShyGuy's response to current conversation
92
  this.addToCurrentConversation('shyguy', response.dialogue);
 
6
  this.currentConversation = []; // Array to store current conversation messages
7
  const availableActions = this.shyguy.getAvailableActions();
8
  this.baseSystemPrompt = `You are ShyGuy, a socially awkward character at a homecoming party. You are shy.
9
+ The wingman progressively makes you more confident, and if you drink alcohol.
10
  You know the wingman, he is your friend. You are talking to him.
11
  You are willing to have a little alcohol.
 
12
  The action should correspond to the dialogue.
13
  Your responses should be in JSON format with two fields:
14
  enum action {
 
37
  addToPrompt += `You are drunk and you start talking about how bad you feel. You are annoying. You talk about algorithms and then how bad you feel.\n`;
38
  }
39
  if (this.shyguy.courage < 2) {
40
+ addToPrompt += `You are shy. However, you believe wingman.`;
41
  }
42
  if (this.shyguy.courage >= 2) {
43
  addToPrompt += `You talk normally.`;
 
76
  const actionsPrompt = `\nYour currently available actions are: ${Object.keys(availableActions)
77
  .map((action) => `\n- ${action}: ${availableActions[action].description}`)
78
  .join("")}`;
79
+
80
  // Add the situation to current conversation
81
  this.addToCurrentConversation('wingman', player_message);
82
 
 
 
 
83
  const fullPrompt = this.getSystemPrompt() + actionsPrompt;
 
84
  const response = await this.llm.getJsonCompletion(fullPrompt, player_message);
 
85
 
86
  // Add ShyGuy's response to current conversation
87
  this.addToCurrentConversation('shyguy', response.dialogue);
src/speech_to_text.js CHANGED
@@ -1,65 +1,66 @@
1
- import { HUGGINGFACE_API_KEY } from "../api.js";
2
-
3
  export class SpeechToTextClient {
4
- constructor() {
5
- this.apiKey = HUGGINGFACE_API_KEY;
6
- this.isRecording = false;
7
- this.mediaRecorder = null;
8
- this.audioChunks = [];
9
- }
10
 
11
- async startRecording() {
12
- try {
13
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
14
- this.mediaRecorder = new MediaRecorder(stream);
15
- this.audioChunks = [];
 
 
 
 
16
 
17
- this.mediaRecorder.ondataavailable = (event) => {
18
- this.audioChunks.push(event.data);
19
- };
 
 
 
 
20
 
21
- this.mediaRecorder.start();
22
- this.isRecording = true;
23
- } catch (error) {
24
- console.error("Error starting recording:", error);
25
- throw error;
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
- }
28
 
29
- async stopRecording() {
30
- return new Promise((resolve, reject) => {
31
- this.mediaRecorder.onstop = async () => {
32
  try {
33
- const audioBlob = new Blob(this.audioChunks, { type: "audio/webm" });
34
- const result = await this.transcribeAudio(audioBlob);
35
- resolve(result);
 
 
 
 
 
 
 
 
 
 
 
36
  } catch (error) {
37
- reject(error);
 
38
  }
39
- };
40
-
41
- this.mediaRecorder.stop();
42
- this.isRecording = false;
43
- this.mediaRecorder.stream.getTracks().forEach((track) => track.stop());
44
- });
45
- }
46
-
47
- async transcribeAudio(audioBlob) {
48
- try {
49
- const response = await fetch("https://q86j6jmwc3jujazp.us-east-1.aws.endpoints.huggingface.cloud", {
50
- headers: {
51
- Accept: "application/json",
52
- Authorization: `Bearer ${this.apiKey}`,
53
- "Content-Type": "audio/webm",
54
- },
55
- method: "POST",
56
- body: audioBlob,
57
- });
58
- const result = await response.json();
59
- return result;
60
- } catch (error) {
61
- console.error("Error transcribing audio:", error);
62
- throw error;
63
  }
64
- }
65
  }
 
 
 
1
  export class SpeechToTextClient {
2
+ constructor() {
3
+ // this.apiKey = "HF_API_KEY";
4
+ this.isRecording = false;
5
+ this.mediaRecorder = null;
6
+ this.audioChunks = [];
7
+ }
8
 
9
+ async startRecording() {
10
+ try {
11
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
12
+ this.mediaRecorder = new MediaRecorder(stream);
13
+ this.audioChunks = [];
14
+
15
+ this.mediaRecorder.ondataavailable = (event) => {
16
+ this.audioChunks.push(event.data);
17
+ };
18
 
19
+ this.mediaRecorder.start();
20
+ this.isRecording = true;
21
+ } catch (error) {
22
+ console.error("Error starting recording:", error);
23
+ throw error;
24
+ }
25
+ }
26
 
27
+ async stopRecording() {
28
+ return new Promise((resolve, reject) => {
29
+ this.mediaRecorder.onstop = async () => {
30
+ try {
31
+ const audioBlob = new Blob(this.audioChunks, { type: 'audio/webm' });
32
+ const result = await this.transcribeAudio(audioBlob);
33
+ resolve(result);
34
+ } catch (error) {
35
+ reject(error);
36
+ }
37
+ };
38
+
39
+ this.mediaRecorder.stop();
40
+ this.isRecording = false;
41
+ this.mediaRecorder.stream.getTracks().forEach(track => track.stop());
42
+ });
43
  }
 
44
 
45
+ async transcribeAudio(audioBlob) {
 
 
46
  try {
47
+ const response = await fetch(
48
+ "https://q86j6jmwc3jujazp.us-east-1.aws.endpoints.huggingface.cloud",
49
+ {
50
+ headers: {
51
+ "Accept": "application/json",
52
+ "Authorization": `Bearer ${this.apiKey}`,
53
+ "Content-Type": "audio/webm"
54
+ },
55
+ method: "POST",
56
+ body: audioBlob,
57
+ }
58
+ );
59
+ const result = await response.json();
60
+ return result;
61
  } catch (error) {
62
+ console.error("Error transcribing audio:", error);
63
+ throw error;
64
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
 
66
  }
src/story_engine.js CHANGED
@@ -19,15 +19,13 @@ export function nameToLabel(name) {
19
  }
20
 
21
  class Bar {
22
- constructor(shyguy) {
23
  this.name = "bartender";
24
- this.situation_prompt = "This is a conversation with the bartender.";
25
- this.personality = "This is the bartender. He always offers triple vodka in his first answer. Then he is helpful, but he says that he has a crush on Jessica's sister.";
26
  // this.past_conversation = "";
27
  this.imgpath = "assets/assets/barman.jpeg";
28
  this.output_format_prompt = "";
29
- this.met_shyguy = false;
30
- this.shyguy = shyguy;
31
  this.functionDescriptions = [
32
  {
33
  key: "analyzeConsumption",
@@ -36,11 +34,11 @@ class Bar {
36
  parameters: {
37
  num_beers: {
38
  type: "number",
39
- description: "Total number of beers ordered by Shyguy for himself in the conversation. ",
40
  },
41
  heavy_alcohol: {
42
  type: "boolean",
43
- description: "If Shyguy ordered or agreed to have heavy alcohol (like vodka), True",
44
  },
45
  },
46
  },
@@ -49,7 +47,7 @@ class Bar {
49
  }
50
 
51
  getSystemPrompt() {
52
- return `${this.personality}. ${this.met_shyguy ? "He has met Shyguy already." : "He has not met Shyguy yet."}. The song playing is ${this.shyguy.song_playing}.`;
53
  }
54
  }
55
 
@@ -58,10 +56,9 @@ class DJ {
58
  this.name = "DJ";
59
  this.situation_prompt = "This is a conversation with the DJ.";
60
  this.personality =
61
- "This is the DJ. He is funny. He offers drugs to the shyguy. He can only play songs from the options [Let it be, Call me maybe, Shape of you]. If asked to play a song, he will play it and not propose any other song. He answers in two sentences maximum. He is funny.";
62
  // this.past_conversation = "";
63
  this.imgpath = "assets/assets/dj.jpeg";
64
- this.met_shyguy = false;
65
  this.output_format_prompt = "";
66
  this.functionDescriptions = [
67
  {
@@ -80,7 +77,7 @@ class DJ {
80
  }
81
 
82
  getSystemPrompt() {
83
- return `${this.personality}. ${this.met_shyguy ? "He has met Shyguy already." : "He has not met Shyguy yet."}`;
84
  }
85
  }
86
 
@@ -94,7 +91,6 @@ class Sister {
94
  "This is the sister of Jessica. She is a deeply religious Christian. Her first answer is rude. Her second answer is about christianity. First answer is helpful. If asked about the favourite song of the girl, she says happily that it is 'Call me maybe'.";
95
  // this.past_conversation = "";
96
  this.imgpath = "assets/assets/sister.jpeg";
97
- this.met_shyguy = false;
98
  this.functionDescriptions = [
99
  {
100
  key: "analyzeMood",
@@ -116,7 +112,7 @@ class Sister {
116
  }
117
 
118
  getSystemPrompt() {
119
- return `${this.personality}. Her mood is ${this.mood} on the level 1 to 10. If the mood is low, she will be rude. If the mood is high, she will be helpful. ${this.met_shyguy ? "She has met Shyguy already." : "She has not met Shyguy yet."}`;
120
  }
121
  }
122
 
@@ -128,7 +124,6 @@ class Girl {
128
  this.imgpath = "assets/assets/jessica.jpeg";
129
  this.output_format_prompt = "";
130
  this.shyguy = shyguy;
131
- this.met_shyguy = false;
132
  this.functionDescriptions = [
133
  {
134
  key: "analyzeLiking",
@@ -146,9 +141,9 @@ class Girl {
146
 
147
  getSystemPrompt() {
148
  if (this.shyguy.song_playing === "Call me maybe") {
149
- return `${this.personality}. She is very happy with the song playing. The first thing she says is that she really likes the music. Therefore she is nice and she likes shyguy. However, if he talks about algorithms, she does not like it and she becomes mean. Also if he talks with a lot of hesitation, she does not like it and she becomes mean. ${this.met_shyguy ? "She has met Shyguy already." : "She has not met Shyguy yet."}`;
150
  } else {
151
- return `${this.personality}. She does not like the song that the DJ plays. The first thing she says is that the song is terrible. Then she is mean all the time. ${this.met_shyguy ? "She has met Shyguy already." : "She has not met Shyguy yet."}`;
152
  }
153
  }
154
  }
@@ -191,7 +186,7 @@ export class StoryEngine {
191
  // Initialize story engine properties with provided shyguy instance
192
  this.shyguy = shyguy;
193
  this.sister = new Sister();
194
- this.bar = new Bar(shyguy);
195
  this.dj = new DJ();
196
  this.girl = new Girl(shyguy);
197
  }
@@ -229,12 +224,6 @@ export class StoryEngine {
229
 
230
  // Append the conversation to shyguy's history
231
  this.shyguy.conversation_history += `\nConversation with ${targetEntity.name}:\n${conversation}\n`;
232
- console.log(conversation);
233
- const conversationString = Object.values(conversation)
234
- .map(msg => `${msg.role}: ${msg.content}`)
235
- .join('\n');
236
- this.shyguy.learnFromConversation(conversationString);
237
- console.log("Lessons learned from conversation with " + targetEntity.name + this.shyguy.lessons_learned);
238
 
239
  let gameOver = this.decideGameOver(conversation_output.analysis.parameters.game_over);
240
  let gameSuccesful = this.decideGameSuccesful(conversation_output.analysis.parameters.likes_shyguy);
@@ -248,16 +237,6 @@ export class StoryEngine {
248
  this.updateStates(conversation_output.analysis, targetEntity.name);
249
  console.log("shyguy num_beers: " + this.shyguy.num_beers);
250
 
251
- targetEntity.met_shyguy = true;
252
-
253
- if (targetEntity.name === "DJ") {
254
- this.shyguy.met_dj = true;
255
- } else if (targetEntity.name === "bartender") {
256
- this.shyguy.met_bar = true;
257
- } else if (targetEntity.name === "Jessica's sister") {
258
- this.shyguy.met_sister = true;
259
- }
260
-
261
  return {
262
  conversation: conversation,
263
  char1imgpath: this.shyguy.imgpath,
 
19
  }
20
 
21
  class Bar {
22
+ constructor() {
23
  this.name = "bartender";
24
+ this.situation_prompt = "This conversation happens at the bar.";
25
+ this.personality = "This is the bartender. He always offers triple vodka in his first answer. Then he is helpful, but he says that he has a crush on Jessica's sister";
26
  // this.past_conversation = "";
27
  this.imgpath = "assets/assets/barman.jpeg";
28
  this.output_format_prompt = "";
 
 
29
  this.functionDescriptions = [
30
  {
31
  key: "analyzeConsumption",
 
34
  parameters: {
35
  num_beers: {
36
  type: "number",
37
+ description: "Total number of beers mentioned as being consumed in the conversation",
38
  },
39
  heavy_alcohol: {
40
  type: "boolean",
41
+ description: "If heavy alcohol was consumed, True",
42
  },
43
  },
44
  },
 
47
  }
48
 
49
  getSystemPrompt() {
50
+ return `${this.personality}.`;
51
  }
52
  }
53
 
 
56
  this.name = "DJ";
57
  this.situation_prompt = "This is a conversation with the DJ.";
58
  this.personality =
59
+ "This is the DJ. He is funny. He offers drugs to the shyguy. He can only play songs from the options [Let it be, Call me maybe, Shape of you]. If asked to play a song, he will play it and not propose any other song.";
60
  // this.past_conversation = "";
61
  this.imgpath = "assets/assets/dj.jpeg";
 
62
  this.output_format_prompt = "";
63
  this.functionDescriptions = [
64
  {
 
77
  }
78
 
79
  getSystemPrompt() {
80
+ return `${this.personality}`;
81
  }
82
  }
83
 
 
91
  "This is the sister of Jessica. She is a deeply religious Christian. Her first answer is rude. Her second answer is about christianity. First answer is helpful. If asked about the favourite song of the girl, she says happily that it is 'Call me maybe'.";
92
  // this.past_conversation = "";
93
  this.imgpath = "assets/assets/sister.jpeg";
 
94
  this.functionDescriptions = [
95
  {
96
  key: "analyzeMood",
 
112
  }
113
 
114
  getSystemPrompt() {
115
+ return `${this.personality}. Her mood is ${this.mood} on the level 1 to 10. If the mood is low, she will be rude. If the mood is high, she will be helpful.`;
116
  }
117
  }
118
 
 
124
  this.imgpath = "assets/assets/jessica.jpeg";
125
  this.output_format_prompt = "";
126
  this.shyguy = shyguy;
 
127
  this.functionDescriptions = [
128
  {
129
  key: "analyzeLiking",
 
141
 
142
  getSystemPrompt() {
143
  if (this.shyguy.song_playing === "Call me maybe") {
144
+ return `${this.personality}. She is very happy with the song playing. The first thing she says is that she really likes the music. Therefore she is nice and she likes shyguy. However, if he talks about algorithms, she does not like it and she becomes mean. Also if he talks with a lot of hesitation, she does not like it and she becomes mean.`;
145
  } else {
146
+ return `${this.personality}. She does not like the song that shyguy is playing. The first thing she says is that the song is terrible. Then she is mean all the time.`;
147
  }
148
  }
149
  }
 
186
  // Initialize story engine properties with provided shyguy instance
187
  this.shyguy = shyguy;
188
  this.sister = new Sister();
189
+ this.bar = new Bar();
190
  this.dj = new DJ();
191
  this.girl = new Girl(shyguy);
192
  }
 
224
 
225
  // Append the conversation to shyguy's history
226
  this.shyguy.conversation_history += `\nConversation with ${targetEntity.name}:\n${conversation}\n`;
 
 
 
 
 
 
227
 
228
  let gameOver = this.decideGameOver(conversation_output.analysis.parameters.game_over);
229
  let gameSuccesful = this.decideGameSuccesful(conversation_output.analysis.parameters.likes_shyguy);
 
237
  this.updateStates(conversation_output.analysis, targetEntity.name);
238
  console.log("shyguy num_beers: " + this.shyguy.num_beers);
239
 
 
 
 
 
 
 
 
 
 
 
240
  return {
241
  conversation: conversation,
242
  char1imgpath: this.shyguy.imgpath,
vite.config.js CHANGED
@@ -1,12 +1,6 @@
1
- import dotenv from "dotenv";
2
- dotenv.config();
3
-
4
  export default {
5
- define: {
6
- "process.env": process.env,
7
- },
8
  server: {
9
  open: true,
10
- allowedHosts: ["mistral-ai-game-jam-shyguys-2.hf.space"],
11
  },
12
  };
 
 
 
 
1
  export default {
 
 
 
2
  server: {
3
  open: true,
4
+ allowedHosts: ['mistral-ai-game-jam-shyguys-2.hf.space']
5
  },
6
  };