Spaces:
Sleeping
Sleeping
File size: 5,752 Bytes
90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 df2ef4f 90cbf22 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import { ObjectType, v } from "convex/values";
import { GameId, parseGameId, playerId } from "./ids";
import { Player } from "./player";
import { Game } from "./game";
import { HfInference } from "@huggingface/inference";
import { PlayerDescription } from "./playerDescription";
export const VotesSchema = {
voter: playerId,
playerIds: v.array(playerId),
}
export type SerializedVotes = ObjectType<typeof VotesSchema>;
export class Votes {
voter: GameId<'players'>;
playerIds: GameId<'players'>[];
constructor(serialized: SerializedVotes) {
const { voter, playerIds } = serialized;
this.voter = parseGameId('players', voter);
this.playerIds = playerIds.map((playerId) => parseGameId('players', playerId));
}
serialize(): SerializedVotes {
const { voter, playerIds } = this;
return {
voter,
playerIds,
};
}
}
export const llmVote = (game: Game, voter: GameId<'players'>, playerIds: GameId<'players'>[]) => {
// If the voter has already voted, remove their vote
let new_votes = game.world.llmVotes.filter((vote) => vote.voter !== voter);
new_votes.push(new Votes({
voter,
playerIds,
}));
game.world.llmVotes = new_votes
}
export const gameVote = (game: Game, voter: GameId<'players'>, playerIds: GameId<'players'>[]) => {
// If the voter has already voted, remove their vote
let new_votes = game.world.gameVotes.filter((vote) => vote.voter !== voter);
new_votes.push(new Votes({
voter,
playerIds,
}));
game.world.gameVotes = new_votes
}
export const processVotes = (votes: Votes[], players: Player[], k: number = 1) => {
// Select the players with the most votes
const voteCounts: Record<GameId<'players'>, number> = {};
players.forEach(player => {
voteCounts[player.id] = 0;
});
// Tally the votes
votes.forEach(vote => {
vote.playerIds.forEach(playerId => {
voteCounts[playerId] = (voteCounts[playerId] || 0) + 1;
});
});
// This can mean that warevolves can each other but whatever
const sortedVoteCounts = Object.entries(voteCounts).sort((a, b) => b[1] - a[1]);
const topKPlayers = sortedVoteCounts.slice(0, k).map((val) => {
return {
playerId: val[0] as GameId<'players'>,
voteCount: val[1],
};
});
return topKPlayers;
}
export function parseLLMVotingResult(voter: Player, log: any | null, game: Game) {
let votedPlayerId = ''
if (log?.arguments?.playerId) {
console.log('Successfully voted to eliminate villager: ', log.arguments.playerId);
votedPlayerId = log.arguments.playerId as string
} else {
const players = game.playerDescriptions.values();
const playerIds = [...players].map(player => player.playerId);
votedPlayerId = playerIds[Math.floor(Math.random() * playerIds.length)];
console.log('Voted to eliminate villager: ', votedPlayerId);
}
gameVote(game, voter.id, [votedPlayerId as GameId<'players'>]);
}
export async function LLmvotingCallWerewolf(werewolf: Player, villagers: PlayerDescription[]) {
// TODO: Use messages
// TODO: till fixed
return null
const inference = new HfInference();
const params = {
model: "tgi",
messages: [
{
role: "system",
content: "You are a werewolf and shall eliminate someone based on a conversation. You shall eliminate villagers. Don't make assumptions about what values to plug into functions. You MUST call a tool",
},
{ role: "user", content: `Who do you want to eliminate between the following player ? \n players : ${villagers} \n ` },
],
max_tokens: 500,
tool_choice: "auto",
tools: [
{
type: "function",
function: {
name: "vote_player",
description: "A function to chose on who to kick out",
parameters: {
type: "object",
properties: {
playerId: { type: "string", description: "The character playerId of the player to eliminate. ( eg : p:1, p:2, p:3 etc ...)" },
},
required: ["playerId"],
},
},
},
],
};
// Streaming chat completion API
const llama3 = inference.endpoint(
"https://lr2bjyq40uegzvb5.us-east-1.aws.endpoints.huggingface.cloud"
);
const response = await llama3.chatCompletion(params);
return response?.choices[0]?.message?.tool_calls?.[0]?.function || null;
}
export async function LLmvotingCallAll(villagers: PlayerDescription[]) {
// TODO: till fixed
return null
const inference = new HfInference();
const params = {
model: "tgi",
messages: [
{
role: "system",
content: "You are a villager and shall try to eliminate someone based on a conversation. You shall eliminate werewolves. Don't make assumptions about what values to plug into functions. You MUST call a tool",
},
{ role: "user", content: `Who do you want to eliminate between the following player ? \n players : ${villagers} \n ` },
],
max_tokens: 500,
tool_choice: "auto",
tools: [
{
type: "function",
function: {
name: "vote_player",
description: "A function to chose on who to kick out",
parameters: {
type: "object",
properties: {
playerId: { type: "string", description: "The character playerId of the player to eliminate. ( eg : p:1, p:2, p:3 etc ...)" },
},
required: ["playerId"],
},
},
},
],
};
// Streaming chat completion API
const llama3 = inference.endpoint(
"https://lr2bjyq40uegzvb5.us-east-1.aws.endpoints.huggingface.cloud"
);
const response = await llama3.chatCompletion(params);
return response?.choices[0]?.message?.tool_calls?.[0]?.function || null;
}
|