Skip to content

Commit ea5496c

Browse files
feat: add client-side maia analysis in alternate /analyze page
1 parent 46cef3a commit ea5496c

File tree

18 files changed

+4454
-7486
lines changed

18 files changed

+4454
-7486
lines changed

package-lock.json

Lines changed: 3129 additions & 7443 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"lila-stockfish-web": "^0.0.7",
2626
"next": "^13.4.16",
2727
"next-transpile-modules": "^10.0.1",
28-
"onnxruntime-web": "^1.20.1",
28+
"onnxruntime-web": "^1.21.0-dev.20250114-228dd16893",
2929
"react": "^18.2.0",
3030
"react-chartjs-2": "^5.2.0",
3131
"react-dom": "^18.2.0",

public/maia2/maia_rapid.onnx

88.9 MB
Binary file not shown.

src/api/analysis/clientAnalysis.ts

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import {
3+
Player,
4+
MoveMap,
5+
MaiaEvaluation,
6+
ClientAnalyzedGame,
7+
PositionEvaluation,
8+
StockfishEvaluation,
9+
} from 'src/types'
10+
import { buildUrl } from '../utils'
11+
import { AvailableMoves } from 'src/types/training'
12+
13+
export const getClientAnalyzedTournamentGame = async (
14+
gameId = ['FkgYSri1'],
15+
) => {
16+
const res = await fetch(
17+
buildUrl(`analysis/analysis_list/${gameId.join('/')}`),
18+
)
19+
20+
if (res.status === 401) {
21+
throw new Error('Unauthorized')
22+
}
23+
24+
const data = await res.json()
25+
const id = data['id']
26+
const termination = {
27+
...data['termination'],
28+
condition: 'Normal',
29+
}
30+
31+
const gameType = 'blitz'
32+
const blackPlayer = data['black_player'] as Player
33+
const whitePlayer = data['white_player'] as Player
34+
35+
const maiaEvals: { [model: string]: MoveMap[] } = {}
36+
const stockfishEvaluations: MoveMap[] = data['stockfish_evals']
37+
38+
const availableMoves: AvailableMoves[] = []
39+
40+
for (const model of data['maia_versions']) {
41+
maiaEvals[model] = data['maia_evals'][model]
42+
}
43+
44+
for (const position of data['move_maps']) {
45+
const moves: AvailableMoves = {}
46+
for (const move of position) {
47+
const fromTo = move.move.join('')
48+
const san = move['move_san']
49+
const { check, fen } = move
50+
51+
moves[fromTo] = {
52+
board: fen,
53+
check,
54+
san,
55+
lastMove: move.move,
56+
}
57+
}
58+
availableMoves.push(moves)
59+
}
60+
61+
const gameStates = data['game_states']
62+
63+
const moves = gameStates.map((gameState: any) => {
64+
const {
65+
last_move: lastMove,
66+
fen,
67+
check,
68+
last_move_san: san,
69+
evaluations: maia_values,
70+
} = gameState
71+
72+
return {
73+
board: fen,
74+
lastMove,
75+
san,
76+
check,
77+
maia_values,
78+
}
79+
})
80+
81+
const maiaEvaluations = [] as { [rating: number]: MaiaEvaluation }[]
82+
83+
return {
84+
id,
85+
blackPlayer,
86+
whitePlayer,
87+
moves,
88+
maiaEvaluations,
89+
stockfishEvaluations,
90+
availableMoves,
91+
gameType,
92+
termination,
93+
} as any as ClientAnalyzedGame
94+
}
95+
96+
export const getClientAnalyzedLichessGame = async (
97+
id: string,
98+
pgn: string,
99+
maia_model = 'maia_kdd_1500',
100+
) => {
101+
const res = await fetch(
102+
buildUrl(
103+
'analysis/analyze_user_game?' +
104+
new URLSearchParams({
105+
maia_model,
106+
}),
107+
),
108+
{
109+
method: 'POST',
110+
body: pgn,
111+
headers: {
112+
'Content-Type': 'text/plain',
113+
},
114+
},
115+
)
116+
117+
if (res.status === 401) {
118+
throw new Error('Unauthorized')
119+
}
120+
121+
const data = await res.json()
122+
123+
const termination = {
124+
...data['termination'],
125+
condition: 'Normal',
126+
}
127+
128+
const gameType = 'blitz'
129+
const blackPlayer = data['black_player'] as Player
130+
const whitePlayer = data['white_player'] as Player
131+
132+
const maiaEvals: { [model: string]: MoveMap[] } = {}
133+
const positionEvaluations: { [model: string]: PositionEvaluation[] } = {}
134+
const availableMoves: AvailableMoves[] = []
135+
136+
for (const model of data['maia_versions']) {
137+
maiaEvals[model] = data['maia_evals'][model]
138+
positionEvaluations[model] = Object.keys(data['maia_evals'][model]).map(
139+
() => ({
140+
trickiness: 1,
141+
performance: 1,
142+
}),
143+
)
144+
}
145+
146+
for (const position of data['move_maps']) {
147+
const moves: AvailableMoves = {}
148+
for (const move of position) {
149+
const fromTo = move.move.join('')
150+
const san = move['move_san']
151+
const { check, fen } = move
152+
153+
moves[fromTo] = {
154+
board: fen,
155+
check,
156+
san,
157+
lastMove: move.move,
158+
}
159+
}
160+
availableMoves.push(moves)
161+
}
162+
163+
const gameStates = data['game_states']
164+
165+
const moves = gameStates.map((gameState: any) => {
166+
const {
167+
last_move: lastMove,
168+
fen,
169+
check,
170+
last_move_san: san,
171+
evaluations: maia_values,
172+
} = gameState
173+
174+
return {
175+
board: fen,
176+
lastMove,
177+
san,
178+
check,
179+
maia_values,
180+
}
181+
})
182+
183+
const maiaEvaluations = [] as { [rating: number]: MaiaEvaluation }[]
184+
const stockfishEvaluations: StockfishEvaluation[] = []
185+
186+
return {
187+
id,
188+
blackPlayer,
189+
whitePlayer,
190+
moves,
191+
availableMoves,
192+
gameType,
193+
termination,
194+
maiaEvaluations,
195+
stockfishEvaluations,
196+
type: 'brain',
197+
pgn,
198+
} as ClientAnalyzedGame
199+
}
200+
201+
export const getClientAnalyzedUserGame = async (
202+
id: string,
203+
game_type: 'play' | 'hand' | 'brain',
204+
maia_model = 'maia_kdd_1500',
205+
) => {
206+
const res = await fetch(
207+
buildUrl(
208+
`analysis/user/analyze_user_maia_game/${id}?` +
209+
new URLSearchParams({
210+
game_type,
211+
maia_model,
212+
}),
213+
),
214+
{
215+
method: 'GET',
216+
headers: {
217+
'Content-Type': 'text/plain',
218+
},
219+
},
220+
)
221+
222+
if (res.status === 401) {
223+
throw new Error('Unauthorized')
224+
}
225+
226+
const data = await res.json()
227+
228+
const termination = {
229+
...data['termination'],
230+
condition: 'Normal',
231+
}
232+
233+
const gameType = 'blitz'
234+
const blackPlayer = data['black_player'] as Player
235+
const whitePlayer = data['white_player'] as Player
236+
237+
const maiaPattern = /maia_kdd_1\d00/
238+
239+
if (maiaPattern.test(blackPlayer.name)) {
240+
blackPlayer.name = blackPlayer.name.replace('maia_kdd_', 'Maia ')
241+
}
242+
243+
if (maiaPattern.test(whitePlayer.name)) {
244+
whitePlayer.name = whitePlayer.name.replace('maia_kdd_', 'Maia ')
245+
}
246+
247+
const maiaEvals: { [model: string]: MoveMap[] } = {}
248+
249+
const availableMoves: AvailableMoves[] = []
250+
251+
for (const model of data['maia_versions']) {
252+
maiaEvals[model] = data['maia_evals'][model]
253+
}
254+
255+
for (const position of data['move_maps']) {
256+
const moves: AvailableMoves = {}
257+
for (const move of position) {
258+
const fromTo = move.move.join('')
259+
const san = move['move_san']
260+
const { check, fen } = move
261+
262+
moves[fromTo] = {
263+
board: fen,
264+
check,
265+
san,
266+
lastMove: move.move,
267+
}
268+
}
269+
availableMoves.push(moves)
270+
}
271+
272+
const gameStates = data['game_states']
273+
274+
const moves = gameStates.map((gameState: any) => {
275+
const {
276+
last_move: lastMove,
277+
fen,
278+
check,
279+
last_move_san: san,
280+
evaluations: maia_values,
281+
} = gameState
282+
283+
return {
284+
board: fen,
285+
lastMove,
286+
san,
287+
check,
288+
maia_values,
289+
}
290+
})
291+
292+
const maiaEvaluations = [] as { [rating: number]: MaiaEvaluation }[]
293+
const stockfishEvaluations: StockfishEvaluation[] = []
294+
295+
return {
296+
id,
297+
blackPlayer,
298+
whitePlayer,
299+
moves,
300+
availableMoves,
301+
gameType,
302+
termination,
303+
maiaEvaluations,
304+
stockfishEvaluations,
305+
type: 'brain',
306+
} as ClientAnalyzedGame
307+
}

src/api/analysis/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './analysis'
2+
export * from './clientAnalysis'

src/hooks/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ export * from './useAnalysisController'
77
export * from './useTuringController'
88
export * from './usePlayController'
99
export * from './useStockfishEngine'
10+
export * from './useMaiaEngine'
11+
export * from './useClientAnalysisController'

src/hooks/useAnalysisController/useAnalysisController.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ export const useAnalysisController = (
7575
})
7676
}
7777

78+
console.log(moveMap)
79+
7880
return moveMap
7981
}, [controller.currentIndex, game.maiaEvaluations, maiaModels])
8082

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './useClientAnalysisController'

0 commit comments

Comments
 (0)