cito-mcp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tools/match.js +9 -1
- package/dist/tools/meta.js +3 -2
- package/dist/tools/normalize.js +13 -7
- package/dist/tools/resolve.js +8 -1
- package/dist/tools/standings.js +1 -1
- package/package.json +1 -1
package/dist/tools/match.js
CHANGED
|
@@ -167,9 +167,17 @@ Example: { "game": "cs2", "matchId": "cs2-match-123", "view": "summary", "includ
|
|
|
167
167
|
const partial = [];
|
|
168
168
|
let upstreamCalls = 0;
|
|
169
169
|
let rateLimit = {};
|
|
170
|
-
|
|
170
|
+
let primary = await getSection(ctx, primaryPath(game, matchId));
|
|
171
171
|
upstreamCalls += 1;
|
|
172
172
|
rateLimit = primary.headers;
|
|
173
|
+
// Tennis live board hands out s365_* ids that live at /matches/live/{id}
|
|
174
|
+
// until the match finishes and lands in the archive. Without this fallback
|
|
175
|
+
// the board gives out ids that match_summary immediately 404s on.
|
|
176
|
+
if (!primary.ok && game === 'tennis' && primary.status === 404) {
|
|
177
|
+
primary = await getSection(ctx, `/tennis/matches/live/${encodeURIComponent(matchId)}`);
|
|
178
|
+
upstreamCalls += 1;
|
|
179
|
+
rateLimit = { ...rateLimit, ...primary.headers };
|
|
180
|
+
}
|
|
173
181
|
if (!primary.ok) {
|
|
174
182
|
return errorEnvelope({
|
|
175
183
|
code: mapHttpToCode(primary.status, { gameNotIncluded: gameNotIncludedHint(primary.data) }),
|
package/dist/tools/meta.js
CHANGED
|
@@ -430,6 +430,7 @@ Example: { "includeGameProbes": true }`,
|
|
|
430
430
|
{ game: 'dota2', path: '/dota2' },
|
|
431
431
|
{ game: 'cod', path: '/cod' },
|
|
432
432
|
{ game: 'ufc', path: '/ufc/live/health' },
|
|
433
|
+
{ game: 'tennis', path: '/tennis/rankings/top?tour=ATP&top_n=1' },
|
|
433
434
|
];
|
|
434
435
|
const results = await Promise.all(paths.map(async ({ game, path }) => {
|
|
435
436
|
const res = await fetchJson(ctx, path);
|
|
@@ -692,10 +693,10 @@ Example: { "game": "ufc", "q": "rankings" }`,
|
|
|
692
693
|
// documented paths and no curated tools, so it is exactly what call_api
|
|
693
694
|
// callers come looking for.
|
|
694
695
|
const gameRaw = typeof args.game === 'string' ? args.game.toLowerCase().trim() : '';
|
|
695
|
-
if (gameRaw && !gameRaw.match(/^(lol|cs2|dota2|cod|ufc|fortnite)$/)) {
|
|
696
|
+
if (gameRaw && !gameRaw.match(/^(lol|cs2|dota2|cod|ufc|fortnite|tennis)$/)) {
|
|
696
697
|
return errorEnvelope({
|
|
697
698
|
code: 'UNSUPPORTED_GAME',
|
|
698
|
-
message: `unsupported game "${gameRaw}"; use lol|cs2|dota2|cod|ufc|fortnite`,
|
|
699
|
+
message: `unsupported game "${gameRaw}"; use lol|cs2|dota2|cod|ufc|fortnite|tennis`,
|
|
699
700
|
game: null,
|
|
700
701
|
source: 'list_routes',
|
|
701
702
|
requestId,
|
package/dist/tools/normalize.js
CHANGED
|
@@ -171,14 +171,20 @@ export function normalizeMatch(game, row, forcedStatus) {
|
|
|
171
171
|
if (s != null)
|
|
172
172
|
team2 = { ...team2, score: s };
|
|
173
173
|
}
|
|
174
|
-
// Tennis: live
|
|
175
|
-
//
|
|
174
|
+
// Tennis: the live board nests player1/player2 objects ({id,name,sets_won});
|
|
175
|
+
// raw live rows carry player1_name/player2_name; archive rows only carry
|
|
176
|
+
// winner_id/loser_id (ids, no names). Map all three onto sides so labels are
|
|
177
|
+
// never "? vs ?" and live scores surface as sets won.
|
|
176
178
|
if (game === 'tennis' && !team1 && !team2) {
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
+
const p1obj = asRecord(r.player1);
|
|
180
|
+
const p2obj = asRecord(r.player2);
|
|
181
|
+
const p1 = pickString(p1obj?.name, r.player1_name);
|
|
182
|
+
const p2 = pickString(p2obj?.name, r.player2_name);
|
|
179
183
|
if (p1 || p2) {
|
|
180
|
-
|
|
181
|
-
|
|
184
|
+
const score1 = typeof p1obj?.sets_won === 'number' ? p1obj.sets_won : undefined;
|
|
185
|
+
const score2 = typeof p2obj?.sets_won === 'number' ? p2obj.sets_won : undefined;
|
|
186
|
+
team1 = sideFrom(p1, pickString(p1obj?.id, r.player1_id), undefined, score1);
|
|
187
|
+
team2 = sideFrom(p2, pickString(p2obj?.id, r.player2_id), undefined, score2);
|
|
182
188
|
}
|
|
183
189
|
else {
|
|
184
190
|
const w = pickString(r.winner_id);
|
|
@@ -286,7 +292,7 @@ export function normalizeMatch(game, row, forcedStatus) {
|
|
|
286
292
|
}
|
|
287
293
|
}
|
|
288
294
|
const ev = asRecord(r.event);
|
|
289
|
-
const eventName = pickString(ev?.name, ev?.title, r.eventName, typeof r.event === 'string' ? r.event : undefined, asRecord(r.tournament)?.name, asRecord(r.tournament)?.title, r.tournamentName);
|
|
295
|
+
const eventName = pickString(ev?.name, ev?.title, r.eventName, typeof r.event === 'string' ? r.event : undefined, asRecord(r.tournament)?.name, asRecord(r.tournament)?.title, r.tournamentName, r.tournament_name);
|
|
290
296
|
const eventId = pickString(ev?.id, r.eventId, asRecord(r.tournament)?.id, r.tournamentId);
|
|
291
297
|
const eventSlug = pickString(ev?.slug, r.eventSlug, asRecord(r.tournament)?.slug);
|
|
292
298
|
const leagueName = pickString(asRecord(r.league)?.name, r.leagueName, r.league, r.leagueSlug);
|
package/dist/tools/resolve.js
CHANGED
|
@@ -10,7 +10,14 @@ function pushCandidates(out, game, type, rows, q, limit) {
|
|
|
10
10
|
const ref = entityRef(row, type, game);
|
|
11
11
|
const r = asRecord(row) ?? {};
|
|
12
12
|
const nickname = pickString(r.nickname, asRecord(r.profile)?.nickname, ref.meta?.nickname);
|
|
13
|
-
|
|
13
|
+
let score = rankScore(q, ref.name, ref.id, ref.slug, nickname);
|
|
14
|
+
// Ranked-player tiebreaker: a surname query like "Alcaraz" fuzzy-ties the
|
|
15
|
+
// world #2 with a 1991 journeyman; the row's current_rank breaks the tie
|
|
16
|
+
// toward whoever is actually active/ranked (tennis search supplies it).
|
|
17
|
+
const currentRank = Number(r.current_rank);
|
|
18
|
+
if (score > 0 && Number.isFinite(currentRank) && currentRank > 0) {
|
|
19
|
+
score += currentRank <= 100 ? 8 : currentRank <= 1000 ? 4 : 2;
|
|
20
|
+
}
|
|
14
21
|
// Prefer positive fuzzy hits; keep weak API hits at floor 1 so real search results are not wiped.
|
|
15
22
|
if (q && score <= 0) {
|
|
16
23
|
// still allow through at floor so dedicated search endpoints aren't empty on odd nicknames
|
package/dist/tools/standings.js
CHANGED
|
@@ -62,7 +62,7 @@ export function normalizeStandingRow(row, index) {
|
|
|
62
62
|
: null),
|
|
63
63
|
championStatus: resolvedChampionStatus,
|
|
64
64
|
teamOrFighter: {
|
|
65
|
-
id: pickString(asRecord(entity)?.id, r.teamId, r.fighterId, r.orgId, r.id),
|
|
65
|
+
id: pickString(asRecord(entity)?.id, r.teamId, r.fighterId, r.orgId, r.id, r.player_id),
|
|
66
66
|
slug: pickString(asRecord(entity)?.slug, r.orgSlug, r.teamSlug, r.slug, r.fighterSlug),
|
|
67
67
|
name,
|
|
68
68
|
},
|
package/package.json
CHANGED