@undesirables/plugin-tcg-oracle 2.0.0 β 2.0.2
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/README.md +29 -15
- package/dist/index.d.ts +5 -3
- package/dist/index.js +221 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,15 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
# @undesirables/plugin-tcg-oracle
|
|
6
6
|
|
|
7
|
+
> **Status 2026-09-12:** the USD price panel behind this plugin froze on 2026-09-07. Search still works (prices carry `usd_panel {frozen, as_of}`); the market, simulate and trending actions are suspended and return `{"status":"suspended"}` without charging. See `GET https://oracle.the-undesirables.com/` β `endpoints.suspended`.
|
|
8
|
+
|
|
9
|
+
## π Connect over MCP β one URL, no install
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
https://mcp.the-undesirables.com
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Paste into any MCP client (Claude, Cursor, ChatGPT) β free card search & forecasts, paid calls via x402.
|
|
16
|
+
|
|
17
|
+
|
|
7
18
|
**Give any ElizaOS agent real trading card market intelligence β search, grade, and forecast.**
|
|
8
19
|
|
|
9
20
|
[](https://www.npmjs.com/package/@undesirables/plugin-tcg-oracle)
|
|
10
21
|
[](https://www.npmjs.com/package/@undesirables/plugin-tcg-oracle)
|
|
11
22
|
[](LICENSE)
|
|
12
23
|
[](https://elizaos.ai)
|
|
13
|
-
[](https://
|
|
24
|
+
[](https://oracle.the-undesirables.com)
|
|
14
25
|
|
|
15
|
-
[npm](https://www.npmjs.com/package/@undesirables/plugin-tcg-oracle) Β· [TCG Oracle API](https://the-undesirables.com/docs)
|
|
26
|
+
[npm](https://www.npmjs.com/package/@undesirables/plugin-tcg-oracle) Β· [TCG Oracle API](https://the-undesirables.com/docs)
|
|
16
27
|
|
|
17
28
|
</div>
|
|
18
29
|
|
|
@@ -40,10 +51,10 @@ The trading card market is worth **$50 billion** and growing. Millions of people
|
|
|
40
51
|
|
|
41
52
|
This plugin gives your ElizaOS agent the ability to do all of that in one conversation:
|
|
42
53
|
|
|
43
|
-
1. **"Search for Charizard cards"** β Instantly searches
|
|
54
|
+
1. **"Search for Charizard cards"** β Instantly searches 456K+ real products across 25+ games
|
|
44
55
|
2. **"Grade this card"** β AI vision analyzes centering, corners, edges, surface β predicts PSA/Beckett score
|
|
45
56
|
3. **"Simulate Charizard VMAX at $350 for 60 days"** β Runs a calibrated conformal risk forecast β returns honest VaR + percentile price bands
|
|
46
|
-
4. **"Show me the Pokemon market"** β
|
|
57
|
+
4. **"Show me the Pokemon market"** β Market snapshot β **suspended since 2026-09-12** while the USD price panel is frozen (the oracle answers `{"status":"suspended"}`, no charge)
|
|
47
58
|
|
|
48
59
|
No API keys required from third parties. You just point it at the TCG Oracle server (self-hosted or public).
|
|
49
60
|
|
|
@@ -80,12 +91,15 @@ That's it. Your agent can now search cards, grade images, and run simulations.
|
|
|
80
91
|
|
|
81
92
|
| Action | What It Does | Example Prompt |
|
|
82
93
|
|--------|-------------|----------------|
|
|
83
|
-
| `TCG_ORACLE_SEARCH` | Search
|
|
94
|
+
| `TCG_ORACLE_SEARCH` | Search 456K+ products by card name, set, or keyword | "Search for Base Set Charizard" |
|
|
84
95
|
| `TCG_ORACLE_GRADE` | Grade a card image URL β returns PSA/Beckett prediction | "Grade this card: https://..." |
|
|
85
|
-
| `TCG_ORACLE_SIMULATE` |
|
|
86
|
-
| `TCG_ORACLE_MARKET` |
|
|
96
|
+
| `TCG_ORACLE_SIMULATE` | **Suspended while the USD panel is frozen (since 2026-09-07)** β the oracle returns `{status: suspended}`, no charge | "Simulate Charizard at $350 for 60 days" |
|
|
97
|
+
| `TCG_ORACLE_MARKET` | **Suspended while the USD panel is frozen** β returns `{status: suspended}`, no charge | "Show me the Pokemon market" |
|
|
87
98
|
| `TCG_ORACLE_GRADE_OR_NOT` | Grade-or-Not ROI engine β "will grading this make me money?" | "Should I grade my Charizard?" |
|
|
88
|
-
| `TCG_ORACLE_TRENDING` |
|
|
99
|
+
| `TCG_ORACLE_TRENDING` | **Suspended while the USD panel is frozen** β returns `{status: suspended}`, no charge | "What Pokemon cards are trending?" |
|
|
100
|
+
| `TCG_ORACLE_JP_SUMMARY` | Japanese two-sided dealer board (bid + ask, yen) as daily aggregates β bands, per-game, movement, on-chain root. Free, live | "How is the Japanese card market moving?" |
|
|
101
|
+
| `TCG_ORACLE_SPORTS_BOARD` | Daily sports movers board per live league with conformal 7-day context. Free, live | "Who are the hot NFL players this week?" |
|
|
102
|
+
| `TCG_ORACLE_LOAN_PREVIEW` | Graded-slab loan terms v2 β six-step LTV derivation (live value basis, empirical-VaR tail). Free for free-board slabs | "Loan terms for a PSA 10 of product 566544" |
|
|
89
103
|
|
|
90
104
|
---
|
|
91
105
|
|
|
@@ -109,11 +123,11 @@ That's it. Your agent can now search cards, grade images, and run simulations.
|
|
|
109
123
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
110
124
|
β TCG Oracle API Server β
|
|
111
125
|
β β
|
|
112
|
-
β /api/v1/search βββββββ
|
|
126
|
+
β /api/v1/search βββββββ 456K+ products β
|
|
113
127
|
β /api/v1/grade ββββββββ Vision LLM + OpenCV β PSA/BGS score β
|
|
114
|
-
β /api/v1/simulate βββββ
|
|
115
|
-
β /api/v1/market βββββββ
|
|
116
|
-
β /api/v1/trending βββββ
|
|
128
|
+
β /api/v1/simulate βββββ SUSPENDED (USD panel frozen 09-07) β
|
|
129
|
+
β /api/v1/market βββββββ SUSPENDED (USD panel frozen 09-07) β
|
|
130
|
+
β /api/v1/trending βββββ SUSPENDED (USD panel frozen 09-07) β
|
|
117
131
|
β /api/v1/grade-or-not β PSA fee Γ grade Γ value = GO/NO-GO β
|
|
118
132
|
β β
|
|
119
133
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -123,13 +137,13 @@ That's it. Your agent can now search cards, grade images, and run simulations.
|
|
|
123
137
|
|
|
124
138
|
## Supported Games (25)
|
|
125
139
|
|
|
126
|
-
PokΓ©mon Β· Magic: The Gathering Β· Yu-Gi-Oh! Β· Disney Lorcana Β· One Piece Β· Flesh and Blood Β· Star Wars: Unlimited Β· Dragon Ball Super Β· Digimon Β· MetaZoo Β· Union Arena Β· Gundam Card Game Β· LoL Riftbound Β· and 12 more
|
|
140
|
+
PokΓ©mon Β· Magic: The Gathering Β· Yu-Gi-Oh! Β· Disney Lorcana Β· One Piece Β· Flesh and Blood Β· Star Wars: Unlimited Β· Dragon Ball Super Β· Digimon Β· MetaZoo Β· Union Arena Β· Gundam Card Game Β· LoL Riftbound Β· and 12 more
|
|
127
141
|
|
|
128
142
|
---
|
|
129
143
|
|
|
130
144
|
## How the Data Works
|
|
131
145
|
|
|
132
|
-
|
|
146
|
+
USD market prices originate from TCGPlayer. **That upstream feed is currently unavailable, so USD prices are frozen at their last good date** β every response carries its own `latest_date`, and the oracle root publishes panel freshness under `panels`. A Japanese-print panel (24 games, 364K cards, 167K of them with both an ask and a dealer buyback bid) refreshes every morning. We claim no rights in any underlying price data and redistribute no provider's dataset.
|
|
133
147
|
|
|
134
148
|
**Risk model β conformal calibration (default):**
|
|
135
149
|
|
|
@@ -199,7 +213,7 @@ On **June 1, 2030** (or 4 years after the first public release of each version),
|
|
|
199
213
|
|
|
200
214
|
Building a commercial product? Want guaranteed API access or white-label integration? Contact us:
|
|
201
215
|
|
|
202
|
-
π§ **
|
|
216
|
+
π§ **oracle@the-undesirables.com** Β· π¦ **[@undesirables_ai](https://x.com/undesirables_ai)**
|
|
203
217
|
|
|
204
218
|
Β© 2026 The Undesirables LLC
|
|
205
219
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { Plugin } from '@elizaos/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* TCG Oracle β ElizaOS Plugin
|
|
4
|
+
* TCG Oracle β ElizaOS Plugin v2.0.2
|
|
5
5
|
* ====================================
|
|
6
6
|
* AI-powered trading card market intelligence for ElizaOS agents.
|
|
7
7
|
* Native TypeScript rewrite of the Python G.A.M.E. SDK version.
|
|
8
8
|
*
|
|
9
9
|
* Features:
|
|
10
|
-
* - Search
|
|
10
|
+
* - Search 455K+ TCG products across 25+ games (Pokemon, MTG, Yu-Gi-Oh, etc.)
|
|
11
|
+
* - Japanese two-sided dealer board summary, graded-slab loan terms, daily sports movers board
|
|
11
12
|
* - AI Vision card grading (PSA/Beckett prediction via Qwen VL)
|
|
12
13
|
* - Conformal-calibrated risk forecasts (honest VaR + Safe-Hold/Momentum grades);
|
|
13
14
|
* Monte Carlo (GBM/Merton) opt-in via the model parameter
|
|
14
|
-
* -
|
|
15
|
+
* - Market snapshots / simulate / trending: SUSPENDED since the USD panel froze 2026-09-07
|
|
16
|
+
* (the oracle answers {"status":"suspended"} and never charges) β actions surface that honestly
|
|
15
17
|
* - License key purchase & verification (Ethereum NFT)
|
|
16
18
|
*
|
|
17
19
|
* @see https://the-undesirables.com
|
package/dist/index.js
CHANGED
|
@@ -84,13 +84,19 @@ async function callApi(baseUrl, endpoint, params) {
|
|
|
84
84
|
const timeout = setTimeout(() => controller.abort(), 3e4);
|
|
85
85
|
const response = await fetch(url.toString(), {
|
|
86
86
|
signal: controller.signal,
|
|
87
|
-
headers: { "User-Agent": "elizaos-tcg-oracle-plugin/
|
|
87
|
+
headers: { "User-Agent": "elizaos-tcg-oracle-plugin/2.0.2" }
|
|
88
88
|
});
|
|
89
89
|
clearTimeout(timeout);
|
|
90
90
|
if (!response.ok) {
|
|
91
91
|
return { error: `API returned HTTP ${response.status}` };
|
|
92
92
|
}
|
|
93
93
|
const json = await response.json();
|
|
94
|
+
if (json && json.status === "suspended") {
|
|
95
|
+
const alts = json.alternatives ? Object.entries(json.alternatives).map(([k, v]) => `${k}: ${v}`).join("; ") : "";
|
|
96
|
+
return {
|
|
97
|
+
error: `${endpoint} is SUSPENDED (not charged). ${json.reason || ""} Resumes when: ${json.resumes_when || "unknown"}.` + (alts ? ` Live alternatives \u2014 ${alts}` : "")
|
|
98
|
+
};
|
|
99
|
+
}
|
|
94
100
|
return { data: json.data || json };
|
|
95
101
|
} catch (err) {
|
|
96
102
|
if (err.name === "AbortError") {
|
|
@@ -109,7 +115,7 @@ function safeStringify(data, maxItems = 10) {
|
|
|
109
115
|
}
|
|
110
116
|
var searchAction = {
|
|
111
117
|
name: "TCG_ORACLE_SEARCH",
|
|
112
|
-
description: "Search for trading card products across 25+ games including Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, and more. Returns product names, set info, and
|
|
118
|
+
description: "Search for trading card products across 25+ games including Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, and more. Returns product names, set info, and the last published USD price (the USD panel froze 2026-09-07 and every row says so in-band) from 455K+ real products.",
|
|
113
119
|
similes: [
|
|
114
120
|
"SEARCH_CARDS",
|
|
115
121
|
"FIND_CARD",
|
|
@@ -238,7 +244,7 @@ ${summary}`;
|
|
|
238
244
|
};
|
|
239
245
|
var simulateAction = {
|
|
240
246
|
name: "TCG_ORACLE_SIMULATE",
|
|
241
|
-
description: "
|
|
247
|
+
description: "SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge \u2014 the action reports that). Was: forecast a TCG card's future value with a conformal-calibrated risk model \u2014 honest VaR plus Safe-Hold/Momentum letter grades. Monte Carlo (GBM/Merton) is opt-in via the model parameter. Uses real drift and volatility computed from the historical USD panel. Monte Carlo models available opt-in: merton (jump-diffusion) and gbm. Returns percentile bands (5th, 25th, 50th, 75th, 95th) for the forecast period.",
|
|
242
248
|
similes: [
|
|
243
249
|
"SIMULATE_PRICE",
|
|
244
250
|
"PRICE_PREDICTION",
|
|
@@ -322,7 +328,7 @@ ${summary}`;
|
|
|
322
328
|
};
|
|
323
329
|
var marketAction = {
|
|
324
330
|
name: "TCG_ORACLE_MARKET",
|
|
325
|
-
description: "
|
|
331
|
+
description: "SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge \u2014 the action reports that and points at the live alternatives: TCG_ORACLE_JP_SUMMARY, TCG_ORACLE_SPORTS_BOARD, TCG_ORACLE_LOAN_PREVIEW). Was: daily USD market snapshot for a game.",
|
|
326
332
|
similes: [
|
|
327
333
|
"MARKET_SNAPSHOT",
|
|
328
334
|
"MARKET_DATA",
|
|
@@ -446,7 +452,7 @@ ${safeStringify(data)}`;
|
|
|
446
452
|
};
|
|
447
453
|
var trendingAction = {
|
|
448
454
|
name: "TCG_ORACLE_TRENDING",
|
|
449
|
-
description: "
|
|
455
|
+
description: "SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge \u2014 the action reports that). Was: returns the top trending trading cards by market activity (30-day sales volume, views, and price velocity). Covers all 25 supported TCG games. Useful for spotting market momentum and emerging opportunities.",
|
|
450
456
|
similes: [
|
|
451
457
|
"TRENDING_CARDS",
|
|
452
458
|
"HOT_CARDS",
|
|
@@ -504,6 +510,207 @@ ${summary}`;
|
|
|
504
510
|
return { success: true, text: responseText, data: { trending: result.data } };
|
|
505
511
|
}
|
|
506
512
|
};
|
|
513
|
+
var jpSummaryAction = {
|
|
514
|
+
name: "TCG_ORACLE_JP_SUMMARY",
|
|
515
|
+
description: "Daily aggregate summary of the Japanese two-sided dealer board (bid AND ask, yen): card/set/game totals, two-sided share, ask price bands, per-game breakdown, day-over-day and week-over-week movement, and the on-chain commitment root. Aggregates only \u2014 no per-card names, ids or prices. Free, live (this is the feed the Card Souls call from 2026-09-14).",
|
|
516
|
+
similes: [
|
|
517
|
+
"JAPANESE_MARKET",
|
|
518
|
+
"JP_BOARD",
|
|
519
|
+
"JP_SUMMARY",
|
|
520
|
+
"YEN_MARKET",
|
|
521
|
+
"JAPANESE_CARDS",
|
|
522
|
+
"DEALER_BOARD"
|
|
523
|
+
],
|
|
524
|
+
parameters: [
|
|
525
|
+
{
|
|
526
|
+
name: "section",
|
|
527
|
+
description: "Optional: narrow the answer to one block \u2014 totals, bands, per_game or movement (default: all)",
|
|
528
|
+
required: false,
|
|
529
|
+
schema: { type: "string" }
|
|
530
|
+
}
|
|
531
|
+
],
|
|
532
|
+
examples: [
|
|
533
|
+
[
|
|
534
|
+
{ name: "{{user1}}", content: { text: "How is the Japanese card market moving today?" } },
|
|
535
|
+
{ name: "{{agentName}}", content: { text: "Pulling the Japanese two-sided board summary...", action: "TCG_ORACLE_JP_SUMMARY" } }
|
|
536
|
+
],
|
|
537
|
+
[
|
|
538
|
+
{ name: "{{user1}}", content: { text: "Give me the JP dealer board summary" } },
|
|
539
|
+
{ name: "{{agentName}}", content: { text: "Fetching today's Japanese board aggregates...", action: "TCG_ORACLE_JP_SUMMARY" } }
|
|
540
|
+
]
|
|
541
|
+
],
|
|
542
|
+
validate: async (runtime) => !!getBaseUrl(runtime),
|
|
543
|
+
handler: async (runtime, message, _state, options, callback) => {
|
|
544
|
+
const text = message.content.text?.toLowerCase() || "";
|
|
545
|
+
const sections = ["totals", "bands", "per_game", "movement"];
|
|
546
|
+
const section = options?.section || sections.find((k) => text.includes(k.replace("_", " ")) || text.includes(k)) || "";
|
|
547
|
+
const result = await callApi(getBaseUrl(runtime), "/api/v1/jp/summary", {});
|
|
548
|
+
if (result.error) {
|
|
549
|
+
if (callback) await callback({ text: `Japanese board summary failed: ${result.error}` });
|
|
550
|
+
return { success: false, error: result.error };
|
|
551
|
+
}
|
|
552
|
+
const d = result.data || {};
|
|
553
|
+
const t = d.totals || {};
|
|
554
|
+
const dod = d.movement?.day_over_day || {};
|
|
555
|
+
const headline = `Japanese two-sided board \u2014 ${d.as_of}: ${t.cards} cards / ${t.sets} sets / ${t.games} games, ${t.two_sided} two-sided (${Math.round((t.two_sided_share || 0) * 100)}%), median ask \xA5${t.median_ask_yen}. Day-over-day: ${dod.asks_changed} asks moved (${dod.up} up / ${dod.down} down).`;
|
|
556
|
+
const body = section && d[section] !== void 0 ? { as_of: d.as_of, [section]: d[section], onchain: d.onchain } : d;
|
|
557
|
+
const responseText = `${headline}
|
|
558
|
+
|
|
559
|
+
${safeStringify(body)}`;
|
|
560
|
+
if (callback) await callback({ text: responseText }, "TCG_ORACLE_JP_SUMMARY");
|
|
561
|
+
return { success: true, text: responseText, data: { jp_summary: d } };
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
var SPORTS_LEAGUES = ["mlb", "nhl", "nfl", "ncaaf", "nba", "ncaab", "wnba"];
|
|
565
|
+
var sportsBoardAction = {
|
|
566
|
+
name: "TCG_ORACLE_SPORTS_BOARD",
|
|
567
|
+
description: "Daily sports movers board \u2014 hot players per live league (MLB, NHL, NFL, NCAAF, NBA, ...) with conformal 7-day context, headshots and the current calibration verdict. Free, live. Name a league to narrow the answer.",
|
|
568
|
+
similes: [
|
|
569
|
+
"SPORTS_MOVERS",
|
|
570
|
+
"HOT_PLAYERS",
|
|
571
|
+
"SPORTS_BOARD",
|
|
572
|
+
"PLAYER_MOVERS",
|
|
573
|
+
"SPORTS_CARDS"
|
|
574
|
+
],
|
|
575
|
+
parameters: [
|
|
576
|
+
{
|
|
577
|
+
name: "league",
|
|
578
|
+
description: "Optional league filter: mlb, nhl, nfl, ncaaf, nba, ncaab, wnba",
|
|
579
|
+
required: false,
|
|
580
|
+
schema: { type: "string" }
|
|
581
|
+
}
|
|
582
|
+
],
|
|
583
|
+
examples: [
|
|
584
|
+
[
|
|
585
|
+
{ name: "{{user1}}", content: { text: "Who are the hot NFL players this week?" } },
|
|
586
|
+
{ name: "{{agentName}}", content: { text: "Pulling the NFL movers board...", action: "TCG_ORACLE_SPORTS_BOARD" } }
|
|
587
|
+
],
|
|
588
|
+
[
|
|
589
|
+
{ name: "{{user1}}", content: { text: "Show me the sports movers board" } },
|
|
590
|
+
{ name: "{{agentName}}", content: { text: "Fetching today's sports board across live leagues...", action: "TCG_ORACLE_SPORTS_BOARD" } }
|
|
591
|
+
]
|
|
592
|
+
],
|
|
593
|
+
validate: async (runtime) => !!getBaseUrl(runtime),
|
|
594
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
595
|
+
const text = message.content.text?.toLowerCase() || "";
|
|
596
|
+
const league = SPORTS_LEAGUES.find((l) => new RegExp(`\\b${l}\\b`).test(text));
|
|
597
|
+
const result = await callApi(getBaseUrl(runtime), "/api/v1/sports/board", {});
|
|
598
|
+
if (result.error) {
|
|
599
|
+
if (callback) await callback({ text: `Sports board failed: ${result.error}` });
|
|
600
|
+
return { success: false, error: result.error };
|
|
601
|
+
}
|
|
602
|
+
const d = result.data || {};
|
|
603
|
+
const leagues = d.leagues || {};
|
|
604
|
+
const live = Object.keys(leagues);
|
|
605
|
+
let body;
|
|
606
|
+
let label;
|
|
607
|
+
if (league && leagues[league]) {
|
|
608
|
+
body = leagues[league];
|
|
609
|
+
label = league.toUpperCase();
|
|
610
|
+
} else if (league) {
|
|
611
|
+
body = { live_leagues: live, note: `${league} is not on today's board` };
|
|
612
|
+
label = league.toUpperCase();
|
|
613
|
+
} else {
|
|
614
|
+
body = leagues;
|
|
615
|
+
label = live.map((l) => l.toUpperCase()).join(", ");
|
|
616
|
+
}
|
|
617
|
+
const responseText = `Sports movers board (${d.horizon_days || 7}-day horizon) \u2014 ${label}. Calibration: ${safeStringify(d.calibration)}
|
|
618
|
+
|
|
619
|
+
${safeStringify(body, 25)}`;
|
|
620
|
+
if (callback) await callback({ text: responseText }, "TCG_ORACLE_SPORTS_BOARD");
|
|
621
|
+
return { success: true, text: responseText, data: { sports_board: d, league: league || null } };
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
var loanPreviewAction = {
|
|
625
|
+
name: "TCG_ORACLE_LOAN_PREVIEW",
|
|
626
|
+
description: "Graded-slab lending terms (loan-terms v2, live basis): the six-step worked LTV derivation \u2014 collateral value, empirical-VaR tail, max LTV, liquidation price, census liquidity tier, APR premium \u2014 for a graded card. Give a product_id + grade (e.g. 'PSA 10'); without one it walks the top of today's free board. Free for free-board slabs; other slabs point at the paid /api/v1/loan-terms quote ($0.10, x402).",
|
|
627
|
+
similes: [
|
|
628
|
+
"LOAN_TERMS",
|
|
629
|
+
"CARD_LOAN",
|
|
630
|
+
"LTV",
|
|
631
|
+
"COLLATERAL_VALUE",
|
|
632
|
+
"SLAB_LOAN",
|
|
633
|
+
"LENDING_TERMS"
|
|
634
|
+
],
|
|
635
|
+
parameters: [
|
|
636
|
+
{
|
|
637
|
+
name: "product_id",
|
|
638
|
+
description: "TCG product id of the card (from TCG_ORACLE_SEARCH)",
|
|
639
|
+
required: false,
|
|
640
|
+
schema: { type: "number" }
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
name: "grade",
|
|
644
|
+
description: "Slab grade, e.g. 'PSA 10', 'PSA 9', 'BGS 9.5', 'CGC 10'",
|
|
645
|
+
required: false,
|
|
646
|
+
schema: { type: "string" }
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
name: "term_days",
|
|
650
|
+
description: "Loan term in days (default 30)",
|
|
651
|
+
required: false,
|
|
652
|
+
schema: { type: "number" }
|
|
653
|
+
}
|
|
654
|
+
],
|
|
655
|
+
examples: [
|
|
656
|
+
[
|
|
657
|
+
{ name: "{{user1}}", content: { text: "What loan terms would a PSA 10 of product 566544 get?" } },
|
|
658
|
+
{ name: "{{agentName}}", content: { text: "Working the graded-slab LTV derivation...", action: "TCG_ORACLE_LOAN_PREVIEW" } }
|
|
659
|
+
],
|
|
660
|
+
[
|
|
661
|
+
{ name: "{{user1}}", content: { text: "Show me the loan free board" } },
|
|
662
|
+
{ name: "{{agentName}}", content: { text: "Pulling today's rated slab universe and the free-board derivation...", action: "TCG_ORACLE_LOAN_PREVIEW" } }
|
|
663
|
+
]
|
|
664
|
+
],
|
|
665
|
+
validate: async (runtime) => !!getBaseUrl(runtime),
|
|
666
|
+
handler: async (runtime, message, _state, options, callback) => {
|
|
667
|
+
const text = message.content.text || "";
|
|
668
|
+
const baseUrl = getBaseUrl(runtime);
|
|
669
|
+
let productId = Number(options?.product_id) || 0;
|
|
670
|
+
if (!productId) {
|
|
671
|
+
const m = text.match(/\b(\d{5,7})\b/);
|
|
672
|
+
if (m) productId = Number(m[1]);
|
|
673
|
+
}
|
|
674
|
+
let grade = options?.grade || "";
|
|
675
|
+
if (!grade) {
|
|
676
|
+
const g = text.match(/\b(PSA|BGS|CGC|SGC)\s*(10|9\.5|9|8\.5|8|7|6|5)\b/i);
|
|
677
|
+
if (g) grade = `${g[1].toUpperCase()} ${g[2]}`;
|
|
678
|
+
}
|
|
679
|
+
const termDays = Number(options?.term_days) || (text.match(/\b(\d{1,3})\s*-?\s*day/i)?.[1] ? Number(text.match(/\b(\d{1,3})\s*-?\s*day/i)[1]) : 30);
|
|
680
|
+
let universeNote = "";
|
|
681
|
+
if (!productId || !grade) {
|
|
682
|
+
const uni = await callApi(baseUrl, "/api/v1/loan-terms/universe", {});
|
|
683
|
+
if (uni.error) {
|
|
684
|
+
if (callback) await callback({ text: `Loan universe failed: ${uni.error}` });
|
|
685
|
+
return { success: false, error: uni.error };
|
|
686
|
+
}
|
|
687
|
+
const cards = uni.data?.cards || [];
|
|
688
|
+
const pick = cards.find((c) => c.free_board && (!productId || c.product_id === productId));
|
|
689
|
+
if (!pick) {
|
|
690
|
+
const msg = productId ? `product ${productId} is not on today's free board \u2014 a full quote is the paid /api/v1/loan-terms?product_id=${productId}&grade= ($0.10, x402).` : "no free-board slab published today.";
|
|
691
|
+
if (callback) await callback({ text: `Loan preview: ${msg}` });
|
|
692
|
+
return { success: false, error: msg };
|
|
693
|
+
}
|
|
694
|
+
productId = pick.product_id;
|
|
695
|
+
grade = pick.grade;
|
|
696
|
+
universeNote = `Universe ${uni.data?.universe_date}: ${uni.data?.total} rated slabs, ${uni.data?.free_board} on the free board (${uni.data?.method_version}). Showing #${pick.rank} ${pick.name} ${pick.grade}.
|
|
697
|
+
|
|
698
|
+
`;
|
|
699
|
+
}
|
|
700
|
+
const result = await callApi(baseUrl, `/api/v1/loan-terms/preview/${productId}`, { grade, term_days: termDays });
|
|
701
|
+
if (result.error) {
|
|
702
|
+
const hint = result.error.includes("404") ? ` (${productId} ${grade} is not on today's free board \u2014 full quote: /api/v1/loan-terms?product_id=${productId}&grade=${encodeURIComponent(grade)}, $0.10 x402)` : "";
|
|
703
|
+
if (callback) await callback({ text: `Loan preview failed: ${result.error}${hint}` });
|
|
704
|
+
return { success: false, error: result.error };
|
|
705
|
+
}
|
|
706
|
+
const d = result.data || {};
|
|
707
|
+
const responseText = `${universeNote}Loan terms \u2014 ${d.card || productId} ${d.grade || grade}, ${d.term_days || termDays}-day (${d.method_version}):
|
|
708
|
+
|
|
709
|
+
${safeStringify(d)}`;
|
|
710
|
+
if (callback) await callback({ text: responseText }, "TCG_ORACLE_LOAN_PREVIEW");
|
|
711
|
+
return { success: true, text: responseText, data: { loan_preview: d, product_id: productId, grade } };
|
|
712
|
+
}
|
|
713
|
+
};
|
|
507
714
|
var tcgOracleProvider = {
|
|
508
715
|
name: "tcg-oracle",
|
|
509
716
|
description: "Provides TCG Oracle market intelligence context to the agent",
|
|
@@ -511,36 +718,36 @@ var tcgOracleProvider = {
|
|
|
511
718
|
const baseUrl = getBaseUrl(runtime);
|
|
512
719
|
const status = baseUrl ? "connected" : "not configured";
|
|
513
720
|
return {
|
|
514
|
-
text: `[TCG Oracle
|
|
721
|
+
text: `[TCG Oracle v2.0.2]
|
|
515
722
|
Status: ${status}
|
|
516
|
-
Database:
|
|
517
|
-
|
|
723
|
+
Database: 455K+ products across 25+ games (USD panel FROZEN 2026-09-07 \u2014 served as last-published, labelled)
|
|
724
|
+
Live feeds: Japanese two-sided dealer board (daily, on-chain root), graded-slab loan terms v2, sports movers board
|
|
518
725
|
Models: conformal (default \u2014 regime-aware split-conformal bands, honest VaR), merton (jump-diffusion), gbm \u2014 Monte Carlo is opt-in
|
|
519
|
-
Actions: search, grade,
|
|
726
|
+
Actions: search, grade, grade-or-not, jp-summary, sports-board, loan-preview (live) \xB7 simulate, market, trending (SUSPENDED \u2014 oracle answers status=suspended, never charges)
|
|
520
727
|
Supported games: ${SUPPORTED_GAMES.join(", ")}
|
|
521
728
|
API: ${baseUrl || "TCG_ORACLE_URL not set"}
|
|
522
729
|
|
|
523
|
-
The agent can search cards, grade card images,
|
|
730
|
+
The agent can search cards, grade card images, check grading ROI, summarise the Japanese two-sided board, pull the sports movers board and work graded-slab loan terms. Simulate / market / trending are suspended until a live USD series exists again.`,
|
|
524
731
|
values: {
|
|
525
732
|
tcgOracleStatus: status,
|
|
526
733
|
tcgOracleUrl: baseUrl || "not set",
|
|
527
|
-
totalProducts:
|
|
734
|
+
totalProducts: 455e3
|
|
528
735
|
}
|
|
529
736
|
};
|
|
530
737
|
}
|
|
531
738
|
};
|
|
532
739
|
var tcgOraclePlugin = {
|
|
533
740
|
name: "@undesirables/plugin-tcg-oracle",
|
|
534
|
-
description: "TCG Oracle \u2014 AI-powered trading card market intelligence for ElizaOS agents. Covers
|
|
741
|
+
description: "TCG Oracle \u2014 AI-powered trading card market intelligence for ElizaOS agents. Covers 455K+ products across 25+ games: set-aware search, AI vision card grading with ROI analysis, the Japanese two-sided dealer board summary, graded-slab loan terms (empirical-VaR LTV, live basis) and the daily sports movers board. USD-panel forecasts, market snapshots and trending are suspended since 2026-09-07 (the oracle answers status=suspended and never charges).",
|
|
535
742
|
init: async (config, runtime) => {
|
|
536
743
|
const validation = validateTcgOracleConfig(runtime);
|
|
537
744
|
if (!validation.valid) {
|
|
538
745
|
console.warn(`\u26A0\uFE0F TCG Oracle: ${validation.error}`);
|
|
539
746
|
} else {
|
|
540
|
-
console.log(`\u2705 TCG Oracle
|
|
747
|
+
console.log(`\u2705 TCG Oracle v2.0.2 connected to ${runtime.getSetting?.("TCG_ORACLE_URL")}`);
|
|
541
748
|
}
|
|
542
749
|
},
|
|
543
|
-
actions: [searchAction, gradeAction, simulateAction, marketAction, gradeOrNotAction, trendingAction],
|
|
750
|
+
actions: [searchAction, gradeAction, simulateAction, marketAction, gradeOrNotAction, trendingAction, jpSummaryAction, sportsBoardAction, loanPreviewAction],
|
|
544
751
|
providers: [tcgOracleProvider],
|
|
545
752
|
evaluators: [],
|
|
546
753
|
services: [MarketMonitorService]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/environment.ts","../src/services.ts","../src/index.ts"],"sourcesContent":["import type { IAgentRuntime } from \"@elizaos/core\";\n\n/**\n * Validates that the TCG Oracle plugin has all required configuration.\n * Called during plugin init and before each action.\n */\nexport function validateTcgOracleConfig(\n runtime: IAgentRuntime\n): { valid: boolean; error?: string } {\n const url =\n (runtime.getSetting?.(\"TCG_ORACLE_URL\") as string) ||\n process.env.TCG_ORACLE_URL ||\n \"\";\n\n if (!url) {\n return {\n valid: false,\n error:\n \"TCG_ORACLE_URL is required. Set it in your character.json settings \" +\n \"or as an environment variable. Example: https://oracle.the-undesirables.com\",\n };\n }\n\n try {\n new URL(url);\n } catch {\n return {\n valid: false,\n error: `TCG_ORACLE_URL is not a valid URL: \"${url}\"`,\n };\n }\n\n return { valid: true };\n}\n","import { Service, IAgentRuntime } from \"@elizaos/core\";\n\nexport class MarketMonitorService extends Service {\n // Use a string getter to satisfy ElizaOS ServiceType constraints if needed,\n // or define static serviceType depending on the core version.\n static serviceType = \"TCG_MARKET_MONITOR\";\n\n get capabilityDescription(): string {\n return \"Monitors TCG market data for price spikes and trending cards\";\n }\n\n static async start(runtime: IAgentRuntime): Promise<MarketMonitorService> {\n const service = new MarketMonitorService();\n await service.initialize(runtime);\n return service;\n }\n\n private monitorInterval: NodeJS.Timeout | null = null;\n\n async initialize(_runtime: IAgentRuntime): Promise<void> {\n console.log(\"[TCG Oracle Service] Market Monitor Service initialized.\");\n // Example: Start background polling for market spikes every hour\n // this.monitorInterval = setInterval(() => this.pollMarket(), 1000 * 60 * 60);\n }\n\n async stop(): Promise<void> {\n if (this.monitorInterval) {\n clearInterval(this.monitorInterval);\n }\n console.log(\"[TCG Oracle Service] Market Monitor Service stopped.\");\n }\n\n private pollMarket() {\n console.log(\"[TCG Oracle Service] Background task: Polling TCG market for price spikes...\");\n }\n}\n","/**\n * TCG Oracle β ElizaOS Plugin v1.0.0\n * ====================================\n * AI-powered trading card market intelligence for ElizaOS agents.\n * Native TypeScript rewrite of the Python G.A.M.E. SDK version.\n *\n * Features:\n * - Search 446K+ TCG products across 25+ games (Pokemon, MTG, Yu-Gi-Oh, etc.)\n * - AI Vision card grading (PSA/Beckett prediction via Qwen VL)\n * - Conformal-calibrated risk forecasts (honest VaR + Safe-Hold/Momentum grades);\n * Monte Carlo (GBM/Merton) opt-in via the model parameter\n * - Real-time market snapshots from TCGCSV daily data\n * - License key purchase & verification (Ethereum NFT)\n *\n * @see https://the-undesirables.com\n * @see https://github.com/sailorpepe/elizaos-tcg-oracle-plugin\n */\n\nimport { validateTcgOracleConfig } from \"./environment.js\";\nimport { MarketMonitorService } from \"./services.js\";\n\nimport type {\n Plugin,\n Action,\n Provider,\n IAgentRuntime,\n Memory,\n State,\n HandlerCallback,\n ActionExample,\n ActionResult,\n ProviderResult,\n} from \"@elizaos/core\";\n\n// ============================================================\n// Configuration\n// ============================================================\n\nconst SUPPORTED_GAMES = [\n \"Pokemon\",\n \"Magic: The Gathering\",\n \"Yu-Gi-Oh!\",\n \"Lorcana\",\n \"One Piece\",\n \"Flesh and Blood\",\n \"Star Wars: Unlimited\",\n \"Dragon Ball Super\",\n \"Digimon\",\n \"MetaZoo\",\n \"Union Arena\",\n \"Gundam Card Game\",\n \"LoL Riftbound\",\n] as const;\n\nconst SIMULATION_MODELS = [\"conformal\", \"merton\", \"gbm\"] as const;\n\n// ============================================================\n// API Client\n// ============================================================\n\nfunction getBaseUrl(runtime: IAgentRuntime): string {\n return (\n (runtime.getSetting?.(\"TCG_ORACLE_URL\") as string) ||\n process.env.TCG_ORACLE_URL ||\n \"\"\n );\n}\n\nasync function callApi(\n baseUrl: string,\n endpoint: string,\n params: Record<string, string | number>\n): Promise<{ data?: any; error?: string }> {\n if (!baseUrl) {\n return {\n error:\n \"TCG_ORACLE_URL not set. Set it in your character.json settings or as an environment variable. Install the server: pip install undesirables-mcp-server\",\n };\n }\n\n const url = new URL(`${baseUrl}${endpoint}`);\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null && value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n }\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n const response = await fetch(url.toString(), {\n signal: controller.signal,\n headers: { \"User-Agent\": \"elizaos-tcg-oracle-plugin/1.0.0\" },\n });\n clearTimeout(timeout);\n\n if (!response.ok) {\n return { error: `API returned HTTP ${response.status}` };\n }\n\n const json = (await response.json()) as Record<string, any>;\n return { data: json.data || json };\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n return { error: \"TCG Oracle API timed out (30s)\" };\n }\n return {\n error: \"Failed to connect to TCG Oracle API. Is the server running?\",\n };\n }\n}\n\n// ============================================================\n// Helper: Truncate data safely before JSON.stringify\n// ============================================================\n\nfunction safeStringify(data: any, maxItems = 10): string {\n if (Array.isArray(data)) {\n return JSON.stringify(data.slice(0, maxItems), null, 2);\n }\n return JSON.stringify(data, null, 2).slice(0, 2000);\n}\n\n// ============================================================\n// ACTION 1: Search TCG Products\n// ============================================================\n\nconst searchAction: Action = {\n name: \"TCG_ORACLE_SEARCH\",\n description:\n \"Search for trading card products across 25+ games including Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, and more. Returns product names, set info, and current market prices from 446K+ real products sourced from TCGCSV daily.\",\n similes: [\n \"SEARCH_CARDS\",\n \"FIND_CARD\",\n \"CARD_LOOKUP\",\n \"CARD_SEARCH\",\n \"TCG_SEARCH\",\n \"FIND_POKEMON\",\n \"SEARCH_MTG\",\n ],\n parameters: [\n {\n name: \"query\",\n description: \"The card name, set name, or keyword to search for (e.g., 'Charizard', 'Base Set', 'Pikachu VMAX')\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"limit\",\n description: \"Maximum number of results to return (default: 10, max: 50)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Search for Charizard cards\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Searching TCG Oracle for Charizard...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What Pikachu VMAX cards are available?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Looking up Pikachu VMAX products...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Find me Base Set holographic cards\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Searching for Base Set holographic cards...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => {\n return !!getBaseUrl(runtime);\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract search query β strip common prefixes\n const query = text\n .replace(/^(search|find|look up|lookup|what|show me)\\s+(for\\s+)?/i, \"\")\n .replace(/\\s+cards?\\s*$/i, \"\")\n .trim();\n\n if (!query) {\n if (callback) await callback({ text: \"What card would you like me to search for?\" });\n return { success: false, error: \"No search query provided\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/search\", {\n query,\n limit: 10,\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Search failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Found products matching \"${query}\":\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_SEARCH\");\n return { success: true, text: responseText, data: { search_results: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 2: AI Card Grading\n// ============================================================\n\nconst gradeAction: Action = {\n name: \"TCG_ORACLE_GRADE\",\n description:\n \"Grade a TCG card image using AI vision (Qwen VL model running locally). Predicts PSA and Beckett grading scores by analyzing centering, corners, edges, surface condition, and print quality. Works with Pokemon, MTG, Yu-Gi-Oh, and other TCG cards.\",\n similes: [\n \"GRADE_CARD\",\n \"CARD_GRADING\",\n \"PSA_GRADE\",\n \"BECKETT_GRADE\",\n \"RATE_CARD\",\n \"EVALUATE_CARD\",\n ],\n parameters: [\n {\n name: \"image_url\",\n description: \"Direct URL to the card image (PNG, JPG, or WebP)\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"game\",\n description: \"The TCG game this card belongs to (default: Pokemon)\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Grade this card: https://example.com/charizard.jpg\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Analyzing card image for grading...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What PSA grade would this get? https://i.imgur.com/card.png\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running AI vision grading analysis...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Rate the condition of this Magic card https://example.com/mtg.jpg\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Evaluating card condition for Beckett grading...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract URL from message\n const urlMatch = text.match(/https?:\\/\\/[^\\s]+/);\n if (!urlMatch) {\n if (callback) await callback({ text: \"Please provide a card image URL to grade.\" });\n return { success: false, error: \"No image URL found in message\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/grade\", {\n image_url: urlMatch[0],\n game: \"Pokemon\",\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Grading failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Card grading complete:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_GRADE\");\n return { success: true, text: responseText, data: { grade_result: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 3: Conformal-Calibrated Price Forecast (Monte Carlo opt-in)\n// ============================================================\n\nconst simulateAction: Action = {\n name: \"TCG_ORACLE_SIMULATE\",\n description:\n \"Forecast a TCG card's future value with a conformal-calibrated risk model β honest VaR plus Safe-Hold/Momentum letter grades. Monte Carlo (GBM/Merton) is opt-in via the model parameter. Uses real drift and volatility computed from TCGCSV historical data. Monte Carlo models available opt-in: merton (jump-diffusion) and gbm. Returns percentile bands (5th, 25th, 50th, 75th, 95th) for the forecast period.\",\n similes: [\n \"SIMULATE_PRICE\",\n \"PRICE_PREDICTION\",\n \"FORECAST_PRICE\",\n \"MONTE_CARLO\",\n \"PRICE_FORECAST\",\n \"WHAT_WILL_THIS_BE_WORTH\",\n ],\n parameters: [\n {\n name: \"card_name\",\n description: \"Name of the card to simulate\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"current_price\",\n description: \"Current price in USD\",\n required: true,\n schema: { type: \"number\" },\n },\n {\n name: \"model\",\n description: \"Forecast model (default 'conformal'): 'conformal' (regime-aware split-conformal bands, honest calibrated VaR), or opt into Monte Carlo with 'merton' (jump-diffusion) or 'gbm'\",\n required: false,\n schema: { type: \"string\", enumValues: [\"conformal\", \"merton\", \"gbm\"] },\n },\n {\n name: \"days\",\n description: \"Forecast horizon in days (default: 30)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Simulate the price of Charizard VMAX at $350 for 60 days\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Monte Carlo simulation on Charizard VMAX...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What will a PSA 10 Base Set Blastoise worth $800 be in 90 days using merton model?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Merton jump-diffusion simulation for Blastoise...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Forecast Lorcana Elsa at $25 for 30 days\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Simulating Lorcana Elsa price trajectory...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Try to extract parameters from text\n const priceMatch = text.match(/\\$?([\\d,]+(?:\\.\\d{2})?)/);\n const daysMatch = text.match(/(\\d+)\\s*days?/i);\n const modelMatch = text.match(/\\b(conformal|merton|gbm)\\b/i);\n\n const cardName =\n text\n .replace(/simulate|price|forecast|monte carlo|at|\\$[\\d,.]+|\\d+\\s*days?|conformal|merton|gbm/gi, \"\")\n .replace(/\\s+/g, \" \")\n .trim() || \"Unknown Card\";\n\n const currentPrice = priceMatch ? parseFloat(priceMatch[1].replace(\",\", \"\")) : 0;\n const days = daysMatch ? parseInt(daysMatch[1]) : 30;\n const model = modelMatch ? modelMatch[1].toLowerCase() : \"conformal\";\n\n if (currentPrice <= 0) {\n if (callback) await callback({ text: \"Please provide a current price for the simulation. Example: 'Simulate Charizard VMAX at $350 for 60 days'\" });\n return { success: false, error: \"Invalid or missing current price\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/simulate\", {\n card_name: cardName,\n current_price: currentPrice,\n model,\n days,\n simulations: 10000,\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Simulation failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Monte Carlo simulation for ${cardName} ($${currentPrice}, ${model} model, ${days} days):\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_SIMULATE\");\n return { success: true, text: responseText, data: { simulation_result: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 4: Market Snapshot\n// ============================================================\n\nconst marketAction: Action = {\n name: \"TCG_ORACLE_MARKET\",\n description:\n \"Retrieve the latest daily market data snapshot from TCGCSV for a specific game. Returns top movers, price changes, volume data, and market trends. Data is refreshed daily via automated pipeline.\",\n similes: [\n \"MARKET_SNAPSHOT\",\n \"MARKET_DATA\",\n \"TCG_MARKET\",\n \"CARD_MARKET\",\n \"TOP_MOVERS\",\n \"PRICE_CHANGES\",\n ],\n parameters: [\n {\n name: \"game\",\n description: \"Game name: Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, etc\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Show me the Pokemon market snapshot\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling the latest Pokemon market data...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What's happening in the Yu-Gi-Oh market today?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching Yu-Gi-Oh market snapshot...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Top movers in Magic: The Gathering\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling Magic: The Gathering market data...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text?.toLowerCase() || \"\";\n\n // Detect game from message\n let game = \"Pokemon\";\n for (const g of SUPPORTED_GAMES) {\n if (text.includes(g.toLowerCase())) {\n game = g;\n break;\n }\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/market\", { game });\n\n if (result.error) {\n if (callback) await callback({ text: `Market data failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data, 25);\n const responseText = `Market snapshot for ${game}:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_MARKET\");\n return { success: true, text: responseText, data: { market_data: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 5: Grade-or-Not Decision Engine\n// ============================================================\n\nconst gradeOrNotAction: Action = {\n name: \"TCG_ORACLE_GRADE_OR_NOT\",\n description:\n \"Answers 'will grading this card make me money?' by combining AI grade prediction with PSA fee schedules, shipping costs, and graded market values. Returns a GO/NO-GO verdict with expected ROI and profit scenarios (best case, predicted, worst case).\",\n similes: [\n \"SHOULD_I_GRADE\",\n \"GRADE_ROI\",\n \"GRADING_PROFIT\",\n \"IS_IT_WORTH_GRADING\",\n \"GRADE_OR_NOT\",\n ],\n parameters: [\n {\n name: \"card_name\",\n description: \"Name of the card to evaluate (e.g., 'Base Set Charizard Holo')\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"predicted_grade\",\n description: \"Your predicted PSA grade (0 = auto-estimate)\",\n required: false,\n schema: { type: \"number\" },\n },\n {\n name: \"raw_price\",\n description: \"Current raw card value in USD (0 = auto-lookup)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Should I grade my Base Set Charizard?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Grade-or-Not analysis...\", action: \"TCG_ORACLE_GRADE_OR_NOT\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Is it worth grading a PSA 8 Pikachu VMAX worth $45?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Calculating grading ROI for Pikachu VMAX...\", action: \"TCG_ORACLE_GRADE_OR_NOT\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract card name\n const cardName = text\n .replace(/^(should i|is it worth|grade or not|grading roi|will grading)\\s*/i, \"\")\n .replace(/\\s*(make me money|be profitable|worth it)\\s*\\??$/i, \"\")\n .replace(/^(grade|grading)\\s*/i, \"\")\n .replace(/\\bmy\\b/i, \"\")\n .trim() || \"Unknown Card\";\n\n // Extract price and grade if mentioned\n const priceMatch = text.match(/\\$?([\\d,]+(?:\\.\\d{2})?)/);\n const gradeMatch = text.match(/\\bpsa\\s*(\\d+(?:\\.\\d)?)\\b/i) || text.match(/\\bgrade\\s*(\\d+(?:\\.\\d)?)\\b/i);\n\n const params: Record<string, string | number> = { card_name: cardName };\n if (priceMatch) params.raw_price = parseFloat(priceMatch[1].replace(\",\", \"\"));\n if (gradeMatch) params.predicted_grade = parseFloat(gradeMatch[1]);\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/grade-or-not\", params);\n\n if (result.error) {\n if (callback) await callback({ text: `Grade-or-Not analysis failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const data = result.data;\n const verdict = data?.verdict || \"Unknown\";\n const explanation = data?.explanation || \"\";\n const responseText = `Grade-or-Not verdict for ${cardName}:\\n\\n${verdict}\\n${explanation}\\n\\nFull analysis:\\n${safeStringify(data)}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_GRADE_OR_NOT\");\n return { success: true, text: responseText, data: { grade_or_not: data } };\n },\n};\n\n// ============================================================\n// ACTION 6: Trending Cards\n// ============================================================\n\nconst trendingAction: Action = {\n name: \"TCG_ORACLE_TRENDING\",\n description:\n \"Returns the top trending trading cards by market activity (30-day sales volume, views, and price velocity). Covers all 25 supported TCG games. Useful for spotting market momentum and emerging opportunities.\",\n similes: [\n \"TRENDING_CARDS\",\n \"HOT_CARDS\",\n \"TOP_MOVERS\",\n \"WHATS_TRENDING\",\n \"POPULAR_CARDS\",\n \"MARKET_TRENDS\",\n ],\n parameters: [\n {\n name: \"game\",\n description: \"Filter by game name (empty = all games)\",\n required: false,\n schema: { type: \"string\" },\n },\n {\n name: \"limit\",\n description: \"Number of results (default: 25, max: 100)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"What Pokemon cards are trending right now?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling trending Pokemon cards...\", action: \"TCG_ORACLE_TRENDING\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Show me the hottest cards across all games\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching trending cards across all TCG games...\", action: \"TCG_ORACLE_TRENDING\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content?.text?.toLowerCase() || \"\";\n\n // Detect game from message\n let game = \"\";\n for (const g of SUPPORTED_GAMES) {\n if (text.includes(g.toLowerCase())) {\n game = g;\n break;\n }\n }\n\n const params: Record<string, string | number> = { limit: 25 };\n if (game) params.game = game;\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/trending\", params);\n\n if (result.error) {\n if (callback) await callback({ text: `Trending cards failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data, 15);\n const responseText = `Trending cards${game ? ` for ${game}` : \" across all games\"}:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_TRENDING\");\n return { success: true, text: responseText, data: { trending: result.data } };\n },\n};\n\n// ============================================================\n// PROVIDER: TCG Oracle Context\n// ============================================================\n\nconst tcgOracleProvider: Provider = {\n name: \"tcg-oracle\",\n description: \"Provides TCG Oracle market intelligence context to the agent\",\n get: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State\n ): Promise<ProviderResult> => {\n const baseUrl = getBaseUrl(runtime);\n const status = baseUrl ? \"connected\" : \"not configured\";\n\n return {\n text: `[TCG Oracle v1.1.0]\nStatus: ${status}\nDatabase: 446K+ products across 25+ games\nData source: TCGCSV daily snapshots\nModels: conformal (default β regime-aware split-conformal bands, honest VaR), merton (jump-diffusion), gbm β Monte Carlo is opt-in\nActions: search, grade, simulate, market, grade-or-not, trending\nSupported games: ${SUPPORTED_GAMES.join(\", \")}\nAPI: ${baseUrl || \"TCG_ORACLE_URL not set\"}\n\nThe agent can search cards, grade card images, simulate prices via Monte Carlo, pull market snapshots, check grading ROI, view trending cards, and scan for grading arbitrage opportunities.`,\n values: {\n tcgOracleStatus: status,\n tcgOracleUrl: baseUrl || \"not set\",\n totalProducts: 370158,\n },\n };\n },\n};\n\n// ============================================================\n// PLUGIN EXPORT\n// ============================================================\n\nconst tcgOraclePlugin: Plugin = {\n name: \"@undesirables/plugin-tcg-oracle\",\n description:\n \"TCG Oracle β AI-powered trading card market intelligence for ElizaOS agents. \" +\n \"Covers 446K+ products across 25+ games with conformal-calibrated risk \" +\n \"forecasts β honest VaR plus Safe-Hold/Momentum letter grades, with Monte \" +\n \"Carlo (GBM/Merton) available opt-in β AI vision card grading with ROI analysis, \" +\n \"trending cards feed, and real-time market snapshots. \" +\n \"Powered by TCGCSV daily data pipeline.\",\n init: async (config: Record<string, string>, runtime: IAgentRuntime) => {\n const validation = validateTcgOracleConfig(runtime);\n if (!validation.valid) {\n console.warn(`β οΈ TCG Oracle: ${validation.error}`);\n } else {\n console.log(`β
TCG Oracle v1.1.0 connected to ${runtime.getSetting?.(\"TCG_ORACLE_URL\")}`);\n }\n },\n actions: [searchAction, gradeAction, simulateAction, marketAction, gradeOrNotAction, trendingAction],\n providers: [tcgOracleProvider],\n evaluators: [],\n services: [MarketMonitorService],\n};\n\nexport default tcgOraclePlugin;\nexport { SUPPORTED_GAMES, SIMULATION_MODELS };\n\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/environment.ts","../src/services.ts","../src/index.ts"],"sourcesContent":["import type { IAgentRuntime } from \"@elizaos/core\";\n\n/**\n * Validates that the TCG Oracle plugin has all required configuration.\n * Called during plugin init and before each action.\n */\nexport function validateTcgOracleConfig(\n runtime: IAgentRuntime\n): { valid: boolean; error?: string } {\n const url =\n (runtime.getSetting?.(\"TCG_ORACLE_URL\") as string) ||\n process.env.TCG_ORACLE_URL ||\n \"\";\n\n if (!url) {\n return {\n valid: false,\n error:\n \"TCG_ORACLE_URL is required. Set it in your character.json settings \" +\n \"or as an environment variable. Example: https://oracle.the-undesirables.com\",\n };\n }\n\n try {\n new URL(url);\n } catch {\n return {\n valid: false,\n error: `TCG_ORACLE_URL is not a valid URL: \"${url}\"`,\n };\n }\n\n return { valid: true };\n}\n","import { Service, IAgentRuntime } from \"@elizaos/core\";\n\nexport class MarketMonitorService extends Service {\n // Use a string getter to satisfy ElizaOS ServiceType constraints if needed,\n // or define static serviceType depending on the core version.\n static serviceType = \"TCG_MARKET_MONITOR\";\n\n get capabilityDescription(): string {\n return \"Monitors TCG market data for price spikes and trending cards\";\n }\n\n static async start(runtime: IAgentRuntime): Promise<MarketMonitorService> {\n const service = new MarketMonitorService();\n await service.initialize(runtime);\n return service;\n }\n\n private monitorInterval: NodeJS.Timeout | null = null;\n\n async initialize(_runtime: IAgentRuntime): Promise<void> {\n console.log(\"[TCG Oracle Service] Market Monitor Service initialized.\");\n // Example: Start background polling for market spikes every hour\n // this.monitorInterval = setInterval(() => this.pollMarket(), 1000 * 60 * 60);\n }\n\n async stop(): Promise<void> {\n if (this.monitorInterval) {\n clearInterval(this.monitorInterval);\n }\n console.log(\"[TCG Oracle Service] Market Monitor Service stopped.\");\n }\n\n private pollMarket() {\n console.log(\"[TCG Oracle Service] Background task: Polling TCG market for price spikes...\");\n }\n}\n","/**\n * TCG Oracle β ElizaOS Plugin v2.0.2\n * ====================================\n * AI-powered trading card market intelligence for ElizaOS agents.\n * Native TypeScript rewrite of the Python G.A.M.E. SDK version.\n *\n * Features:\n * - Search 455K+ TCG products across 25+ games (Pokemon, MTG, Yu-Gi-Oh, etc.)\n * - Japanese two-sided dealer board summary, graded-slab loan terms, daily sports movers board\n * - AI Vision card grading (PSA/Beckett prediction via Qwen VL)\n * - Conformal-calibrated risk forecasts (honest VaR + Safe-Hold/Momentum grades);\n * Monte Carlo (GBM/Merton) opt-in via the model parameter\n * - Market snapshots / simulate / trending: SUSPENDED since the USD panel froze 2026-09-07\n * (the oracle answers {\"status\":\"suspended\"} and never charges) β actions surface that honestly\n * - License key purchase & verification (Ethereum NFT)\n *\n * @see https://the-undesirables.com\n * @see https://github.com/sailorpepe/elizaos-tcg-oracle-plugin\n */\n\nimport { validateTcgOracleConfig } from \"./environment.js\";\nimport { MarketMonitorService } from \"./services.js\";\n\nimport type {\n Plugin,\n Action,\n Provider,\n IAgentRuntime,\n Memory,\n State,\n HandlerCallback,\n ActionExample,\n ActionResult,\n ProviderResult,\n} from \"@elizaos/core\";\n\n// ============================================================\n// Configuration\n// ============================================================\n\nconst SUPPORTED_GAMES = [\n \"Pokemon\",\n \"Magic: The Gathering\",\n \"Yu-Gi-Oh!\",\n \"Lorcana\",\n \"One Piece\",\n \"Flesh and Blood\",\n \"Star Wars: Unlimited\",\n \"Dragon Ball Super\",\n \"Digimon\",\n \"MetaZoo\",\n \"Union Arena\",\n \"Gundam Card Game\",\n \"LoL Riftbound\",\n] as const;\n\nconst SIMULATION_MODELS = [\"conformal\", \"merton\", \"gbm\"] as const;\n\n// ============================================================\n// API Client\n// ============================================================\n\nfunction getBaseUrl(runtime: IAgentRuntime): string {\n return (\n (runtime.getSetting?.(\"TCG_ORACLE_URL\") as string) ||\n process.env.TCG_ORACLE_URL ||\n \"\"\n );\n}\n\nasync function callApi(\n baseUrl: string,\n endpoint: string,\n params: Record<string, string | number>\n): Promise<{ data?: any; error?: string }> {\n if (!baseUrl) {\n return {\n error:\n \"TCG_ORACLE_URL not set. Set it in your character.json settings or as an environment variable. Install the server: pip install undesirables-mcp-server\",\n };\n }\n\n const url = new URL(`${baseUrl}${endpoint}`);\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null && value !== \"\") {\n url.searchParams.set(key, String(value));\n }\n }\n\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 30_000);\n\n const response = await fetch(url.toString(), {\n signal: controller.signal,\n headers: { \"User-Agent\": \"elizaos-tcg-oracle-plugin/2.0.2\" },\n });\n clearTimeout(timeout);\n\n if (!response.ok) {\n return { error: `API returned HTTP ${response.status}` };\n }\n\n const json = (await response.json()) as Record<string, any>;\n if (json && json.status === \"suspended\") {\n const alts = json.alternatives\n ? Object.entries(json.alternatives as Record<string, string>)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\"; \")\n : \"\";\n return {\n error:\n `${endpoint} is SUSPENDED (not charged). ${json.reason || \"\"} ` +\n `Resumes when: ${json.resumes_when || \"unknown\"}.` +\n (alts ? ` Live alternatives β ${alts}` : \"\"),\n };\n }\n return { data: json.data || json };\n } catch (err: any) {\n if (err.name === \"AbortError\") {\n return { error: \"TCG Oracle API timed out (30s)\" };\n }\n return {\n error: \"Failed to connect to TCG Oracle API. Is the server running?\",\n };\n }\n}\n\n// ============================================================\n// Helper: Truncate data safely before JSON.stringify\n// ============================================================\n\nfunction safeStringify(data: any, maxItems = 10): string {\n if (Array.isArray(data)) {\n return JSON.stringify(data.slice(0, maxItems), null, 2);\n }\n return JSON.stringify(data, null, 2).slice(0, 2000);\n}\n\n// ============================================================\n// ACTION 1: Search TCG Products\n// ============================================================\n\nconst searchAction: Action = {\n name: \"TCG_ORACLE_SEARCH\",\n description:\n \"Search for trading card products across 25+ games including Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, and more. Returns product names, set info, and the last published USD price (the USD panel froze 2026-09-07 and every row says so in-band) from 455K+ real products.\",\n similes: [\n \"SEARCH_CARDS\",\n \"FIND_CARD\",\n \"CARD_LOOKUP\",\n \"CARD_SEARCH\",\n \"TCG_SEARCH\",\n \"FIND_POKEMON\",\n \"SEARCH_MTG\",\n ],\n parameters: [\n {\n name: \"query\",\n description: \"The card name, set name, or keyword to search for (e.g., 'Charizard', 'Base Set', 'Pikachu VMAX')\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"limit\",\n description: \"Maximum number of results to return (default: 10, max: 50)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Search for Charizard cards\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Searching TCG Oracle for Charizard...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What Pikachu VMAX cards are available?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Looking up Pikachu VMAX products...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Find me Base Set holographic cards\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Searching for Base Set holographic cards...\", action: \"TCG_ORACLE_SEARCH\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => {\n return !!getBaseUrl(runtime);\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract search query β strip common prefixes\n const query = text\n .replace(/^(search|find|look up|lookup|what|show me)\\s+(for\\s+)?/i, \"\")\n .replace(/\\s+cards?\\s*$/i, \"\")\n .trim();\n\n if (!query) {\n if (callback) await callback({ text: \"What card would you like me to search for?\" });\n return { success: false, error: \"No search query provided\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/search\", {\n query,\n limit: 10,\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Search failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Found products matching \"${query}\":\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_SEARCH\");\n return { success: true, text: responseText, data: { search_results: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 2: AI Card Grading\n// ============================================================\n\nconst gradeAction: Action = {\n name: \"TCG_ORACLE_GRADE\",\n description:\n \"Grade a TCG card image using AI vision (Qwen VL model running locally). Predicts PSA and Beckett grading scores by analyzing centering, corners, edges, surface condition, and print quality. Works with Pokemon, MTG, Yu-Gi-Oh, and other TCG cards.\",\n similes: [\n \"GRADE_CARD\",\n \"CARD_GRADING\",\n \"PSA_GRADE\",\n \"BECKETT_GRADE\",\n \"RATE_CARD\",\n \"EVALUATE_CARD\",\n ],\n parameters: [\n {\n name: \"image_url\",\n description: \"Direct URL to the card image (PNG, JPG, or WebP)\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"game\",\n description: \"The TCG game this card belongs to (default: Pokemon)\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Grade this card: https://example.com/charizard.jpg\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Analyzing card image for grading...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What PSA grade would this get? https://i.imgur.com/card.png\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running AI vision grading analysis...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Rate the condition of this Magic card https://example.com/mtg.jpg\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Evaluating card condition for Beckett grading...\", action: \"TCG_ORACLE_GRADE\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract URL from message\n const urlMatch = text.match(/https?:\\/\\/[^\\s]+/);\n if (!urlMatch) {\n if (callback) await callback({ text: \"Please provide a card image URL to grade.\" });\n return { success: false, error: \"No image URL found in message\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/grade\", {\n image_url: urlMatch[0],\n game: \"Pokemon\",\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Grading failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Card grading complete:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_GRADE\");\n return { success: true, text: responseText, data: { grade_result: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 3: Conformal-Calibrated Price Forecast (Monte Carlo opt-in)\n// ============================================================\n\nconst simulateAction: Action = {\n name: \"TCG_ORACLE_SIMULATE\",\n description:\n \"SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge β the action reports that). Was: forecast a TCG card's future value with a conformal-calibrated risk model β honest VaR plus Safe-Hold/Momentum letter grades. Monte Carlo (GBM/Merton) is opt-in via the model parameter. Uses real drift and volatility computed from the historical USD panel. Monte Carlo models available opt-in: merton (jump-diffusion) and gbm. Returns percentile bands (5th, 25th, 50th, 75th, 95th) for the forecast period.\",\n similes: [\n \"SIMULATE_PRICE\",\n \"PRICE_PREDICTION\",\n \"FORECAST_PRICE\",\n \"MONTE_CARLO\",\n \"PRICE_FORECAST\",\n \"WHAT_WILL_THIS_BE_WORTH\",\n ],\n parameters: [\n {\n name: \"card_name\",\n description: \"Name of the card to simulate\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"current_price\",\n description: \"Current price in USD\",\n required: true,\n schema: { type: \"number\" },\n },\n {\n name: \"model\",\n description: \"Forecast model (default 'conformal'): 'conformal' (regime-aware split-conformal bands, honest calibrated VaR), or opt into Monte Carlo with 'merton' (jump-diffusion) or 'gbm'\",\n required: false,\n schema: { type: \"string\", enumValues: [\"conformal\", \"merton\", \"gbm\"] },\n },\n {\n name: \"days\",\n description: \"Forecast horizon in days (default: 30)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Simulate the price of Charizard VMAX at $350 for 60 days\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Monte Carlo simulation on Charizard VMAX...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What will a PSA 10 Base Set Blastoise worth $800 be in 90 days using merton model?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Merton jump-diffusion simulation for Blastoise...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Forecast Lorcana Elsa at $25 for 30 days\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Simulating Lorcana Elsa price trajectory...\", action: \"TCG_ORACLE_SIMULATE\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Try to extract parameters from text\n const priceMatch = text.match(/\\$?([\\d,]+(?:\\.\\d{2})?)/);\n const daysMatch = text.match(/(\\d+)\\s*days?/i);\n const modelMatch = text.match(/\\b(conformal|merton|gbm)\\b/i);\n\n const cardName =\n text\n .replace(/simulate|price|forecast|monte carlo|at|\\$[\\d,.]+|\\d+\\s*days?|conformal|merton|gbm/gi, \"\")\n .replace(/\\s+/g, \" \")\n .trim() || \"Unknown Card\";\n\n const currentPrice = priceMatch ? parseFloat(priceMatch[1].replace(\",\", \"\")) : 0;\n const days = daysMatch ? parseInt(daysMatch[1]) : 30;\n const model = modelMatch ? modelMatch[1].toLowerCase() : \"conformal\";\n\n if (currentPrice <= 0) {\n if (callback) await callback({ text: \"Please provide a current price for the simulation. Example: 'Simulate Charizard VMAX at $350 for 60 days'\" });\n return { success: false, error: \"Invalid or missing current price\" };\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/simulate\", {\n card_name: cardName,\n current_price: currentPrice,\n model,\n days,\n simulations: 10000,\n });\n\n if (result.error) {\n if (callback) await callback({ text: `Simulation failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data);\n const responseText = `Monte Carlo simulation for ${cardName} ($${currentPrice}, ${model} model, ${days} days):\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_SIMULATE\");\n return { success: true, text: responseText, data: { simulation_result: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 4: Market Snapshot\n// ============================================================\n\nconst marketAction: Action = {\n name: \"TCG_ORACLE_MARKET\",\n description:\n \"SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge β the action reports that and points at the live alternatives: TCG_ORACLE_JP_SUMMARY, TCG_ORACLE_SPORTS_BOARD, TCG_ORACLE_LOAN_PREVIEW). Was: daily USD market snapshot for a game.\",\n similes: [\n \"MARKET_SNAPSHOT\",\n \"MARKET_DATA\",\n \"TCG_MARKET\",\n \"CARD_MARKET\",\n \"TOP_MOVERS\",\n \"PRICE_CHANGES\",\n ],\n parameters: [\n {\n name: \"game\",\n description: \"Game name: Pokemon, Magic: The Gathering, Yu-Gi-Oh, Lorcana, One Piece, etc\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Show me the Pokemon market snapshot\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling the latest Pokemon market data...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"What's happening in the Yu-Gi-Oh market today?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching Yu-Gi-Oh market snapshot...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Top movers in Magic: The Gathering\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling Magic: The Gathering market data...\", action: \"TCG_ORACLE_MARKET\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text?.toLowerCase() || \"\";\n\n // Detect game from message\n let game = \"Pokemon\";\n for (const g of SUPPORTED_GAMES) {\n if (text.includes(g.toLowerCase())) {\n game = g;\n break;\n }\n }\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/market\", { game });\n\n if (result.error) {\n if (callback) await callback({ text: `Market data failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data, 25);\n const responseText = `Market snapshot for ${game}:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_MARKET\");\n return { success: true, text: responseText, data: { market_data: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 5: Grade-or-Not Decision Engine\n// ============================================================\n\nconst gradeOrNotAction: Action = {\n name: \"TCG_ORACLE_GRADE_OR_NOT\",\n description:\n \"Answers 'will grading this card make me money?' by combining AI grade prediction with PSA fee schedules, shipping costs, and graded market values. Returns a GO/NO-GO verdict with expected ROI and profit scenarios (best case, predicted, worst case).\",\n similes: [\n \"SHOULD_I_GRADE\",\n \"GRADE_ROI\",\n \"GRADING_PROFIT\",\n \"IS_IT_WORTH_GRADING\",\n \"GRADE_OR_NOT\",\n ],\n parameters: [\n {\n name: \"card_name\",\n description: \"Name of the card to evaluate (e.g., 'Base Set Charizard Holo')\",\n required: true,\n schema: { type: \"string\" },\n },\n {\n name: \"predicted_grade\",\n description: \"Your predicted PSA grade (0 = auto-estimate)\",\n required: false,\n schema: { type: \"number\" },\n },\n {\n name: \"raw_price\",\n description: \"Current raw card value in USD (0 = auto-lookup)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Should I grade my Base Set Charizard?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Running Grade-or-Not analysis...\", action: \"TCG_ORACLE_GRADE_OR_NOT\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Is it worth grading a PSA 8 Pikachu VMAX worth $45?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Calculating grading ROI for Pikachu VMAX...\", action: \"TCG_ORACLE_GRADE_OR_NOT\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n\n // Extract card name\n const cardName = text\n .replace(/^(should i|is it worth|grade or not|grading roi|will grading)\\s*/i, \"\")\n .replace(/\\s*(make me money|be profitable|worth it)\\s*\\??$/i, \"\")\n .replace(/^(grade|grading)\\s*/i, \"\")\n .replace(/\\bmy\\b/i, \"\")\n .trim() || \"Unknown Card\";\n\n // Extract price and grade if mentioned\n const priceMatch = text.match(/\\$?([\\d,]+(?:\\.\\d{2})?)/);\n const gradeMatch = text.match(/\\bpsa\\s*(\\d+(?:\\.\\d)?)\\b/i) || text.match(/\\bgrade\\s*(\\d+(?:\\.\\d)?)\\b/i);\n\n const params: Record<string, string | number> = { card_name: cardName };\n if (priceMatch) params.raw_price = parseFloat(priceMatch[1].replace(\",\", \"\"));\n if (gradeMatch) params.predicted_grade = parseFloat(gradeMatch[1]);\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/grade-or-not\", params);\n\n if (result.error) {\n if (callback) await callback({ text: `Grade-or-Not analysis failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const data = result.data;\n const verdict = data?.verdict || \"Unknown\";\n const explanation = data?.explanation || \"\";\n const responseText = `Grade-or-Not verdict for ${cardName}:\\n\\n${verdict}\\n${explanation}\\n\\nFull analysis:\\n${safeStringify(data)}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_GRADE_OR_NOT\");\n return { success: true, text: responseText, data: { grade_or_not: data } };\n },\n};\n\n// ============================================================\n// ACTION 6: Trending Cards\n// ============================================================\n\nconst trendingAction: Action = {\n name: \"TCG_ORACLE_TRENDING\",\n description:\n \"SUSPENDED since 2026-09-07 (frozen USD panel; the oracle returns status=suspended and does not charge β the action reports that). Was: returns the top trending trading cards by market activity (30-day sales volume, views, and price velocity). Covers all 25 supported TCG games. Useful for spotting market momentum and emerging opportunities.\",\n similes: [\n \"TRENDING_CARDS\",\n \"HOT_CARDS\",\n \"TOP_MOVERS\",\n \"WHATS_TRENDING\",\n \"POPULAR_CARDS\",\n \"MARKET_TRENDS\",\n ],\n parameters: [\n {\n name: \"game\",\n description: \"Filter by game name (empty = all games)\",\n required: false,\n schema: { type: \"string\" },\n },\n {\n name: \"limit\",\n description: \"Number of results (default: 25, max: 100)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"What Pokemon cards are trending right now?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling trending Pokemon cards...\", action: \"TCG_ORACLE_TRENDING\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Show me the hottest cards across all games\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching trending cards across all TCG games...\", action: \"TCG_ORACLE_TRENDING\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content?.text?.toLowerCase() || \"\";\n\n // Detect game from message\n let game = \"\";\n for (const g of SUPPORTED_GAMES) {\n if (text.includes(g.toLowerCase())) {\n game = g;\n break;\n }\n }\n\n const params: Record<string, string | number> = { limit: 25 };\n if (game) params.game = game;\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/trending\", params);\n\n if (result.error) {\n if (callback) await callback({ text: `Trending cards failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const summary = safeStringify(result.data, 15);\n const responseText = `Trending cards${game ? ` for ${game}` : \" across all games\"}:\\n\\n${summary}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_TRENDING\");\n return { success: true, text: responseText, data: { trending: result.data } };\n },\n};\n\n// ============================================================\n// ACTION 7: Japanese two-sided dealer board β summary (free, live)\n// ============================================================\n\nconst jpSummaryAction: Action = {\n name: \"TCG_ORACLE_JP_SUMMARY\",\n description:\n \"Daily aggregate summary of the Japanese two-sided dealer board (bid AND ask, yen): card/set/game totals, two-sided share, ask price bands, per-game breakdown, day-over-day and week-over-week movement, and the on-chain commitment root. Aggregates only β no per-card names, ids or prices. Free, live (this is the feed the Card Souls call from 2026-09-14).\",\n similes: [\n \"JAPANESE_MARKET\",\n \"JP_BOARD\",\n \"JP_SUMMARY\",\n \"YEN_MARKET\",\n \"JAPANESE_CARDS\",\n \"DEALER_BOARD\",\n ],\n parameters: [\n {\n name: \"section\",\n description: \"Optional: narrow the answer to one block β totals, bands, per_game or movement (default: all)\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"How is the Japanese card market moving today?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling the Japanese two-sided board summary...\", action: \"TCG_ORACLE_JP_SUMMARY\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Give me the JP dealer board summary\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching today's Japanese board aggregates...\", action: \"TCG_ORACLE_JP_SUMMARY\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text?.toLowerCase() || \"\";\n const sections = [\"totals\", \"bands\", \"per_game\", \"movement\"];\n const section =\n (options?.section as string) ||\n sections.find((k) => text.includes(k.replace(\"_\", \" \")) || text.includes(k)) ||\n \"\";\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/jp/summary\", {});\n\n if (result.error) {\n if (callback) await callback({ text: `Japanese board summary failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const d = result.data || {};\n const t = d.totals || {};\n const dod = d.movement?.day_over_day || {};\n const headline =\n `Japanese two-sided board β ${d.as_of}: ${t.cards} cards / ${t.sets} sets / ${t.games} games, ` +\n `${t.two_sided} two-sided (${Math.round((t.two_sided_share || 0) * 100)}%), median ask Β₯${t.median_ask_yen}. ` +\n `Day-over-day: ${dod.asks_changed} asks moved (${dod.up} up / ${dod.down} down).`;\n const body = section && d[section] !== undefined ? { as_of: d.as_of, [section]: d[section], onchain: d.onchain } : d;\n const responseText = `${headline}\\n\\n${safeStringify(body)}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_JP_SUMMARY\");\n return { success: true, text: responseText, data: { jp_summary: d } };\n },\n};\n\n// ============================================================\n// ACTION 8: Daily sports movers board (free, live)\n// ============================================================\n\nconst SPORTS_LEAGUES = [\"mlb\", \"nhl\", \"nfl\", \"ncaaf\", \"nba\", \"ncaab\", \"wnba\"];\n\nconst sportsBoardAction: Action = {\n name: \"TCG_ORACLE_SPORTS_BOARD\",\n description:\n \"Daily sports movers board β hot players per live league (MLB, NHL, NFL, NCAAF, NBA, ...) with conformal 7-day context, headshots and the current calibration verdict. Free, live. Name a league to narrow the answer.\",\n similes: [\n \"SPORTS_MOVERS\",\n \"HOT_PLAYERS\",\n \"SPORTS_BOARD\",\n \"PLAYER_MOVERS\",\n \"SPORTS_CARDS\",\n ],\n parameters: [\n {\n name: \"league\",\n description: \"Optional league filter: mlb, nhl, nfl, ncaaf, nba, ncaab, wnba\",\n required: false,\n schema: { type: \"string\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"Who are the hot NFL players this week?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling the NFL movers board...\", action: \"TCG_ORACLE_SPORTS_BOARD\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Show me the sports movers board\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Fetching today's sports board across live leagues...\", action: \"TCG_ORACLE_SPORTS_BOARD\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text?.toLowerCase() || \"\";\n const league = SPORTS_LEAGUES.find((l) => new RegExp(`\\\\b${l}\\\\b`).test(text));\n\n const result = await callApi(getBaseUrl(runtime), \"/api/v1/sports/board\", {});\n\n if (result.error) {\n if (callback) await callback({ text: `Sports board failed: ${result.error}` });\n return { success: false, error: result.error };\n }\n\n const d = result.data || {};\n const leagues: Record<string, any> = d.leagues || {};\n const live = Object.keys(leagues);\n let body: any;\n let label: string;\n if (league && leagues[league]) {\n body = leagues[league];\n label = league.toUpperCase();\n } else if (league) {\n body = { live_leagues: live, note: `${league} is not on today's board` };\n label = league.toUpperCase();\n } else {\n body = leagues;\n label = live.map((l) => l.toUpperCase()).join(\", \");\n }\n const responseText =\n `Sports movers board (${d.horizon_days || 7}-day horizon) β ${label}. Calibration: ${safeStringify(d.calibration)}\\n\\n${safeStringify(body, 25)}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_SPORTS_BOARD\");\n return { success: true, text: responseText, data: { sports_board: d, league: league || null } };\n },\n};\n\n// ============================================================\n// ACTION 9: Graded-slab loan terms β free worked derivation\n// ============================================================\n\nconst loanPreviewAction: Action = {\n name: \"TCG_ORACLE_LOAN_PREVIEW\",\n description:\n \"Graded-slab lending terms (loan-terms v2, live basis): the six-step worked LTV derivation β collateral value, empirical-VaR tail, max LTV, liquidation price, census liquidity tier, APR premium β for a graded card. Give a product_id + grade (e.g. 'PSA 10'); without one it walks the top of today's free board. Free for free-board slabs; other slabs point at the paid /api/v1/loan-terms quote ($0.10, x402).\",\n similes: [\n \"LOAN_TERMS\",\n \"CARD_LOAN\",\n \"LTV\",\n \"COLLATERAL_VALUE\",\n \"SLAB_LOAN\",\n \"LENDING_TERMS\",\n ],\n parameters: [\n {\n name: \"product_id\",\n description: \"TCG product id of the card (from TCG_ORACLE_SEARCH)\",\n required: false,\n schema: { type: \"number\" },\n },\n {\n name: \"grade\",\n description: \"Slab grade, e.g. 'PSA 10', 'PSA 9', 'BGS 9.5', 'CGC 10'\",\n required: false,\n schema: { type: \"string\" },\n },\n {\n name: \"term_days\",\n description: \"Loan term in days (default 30)\",\n required: false,\n schema: { type: \"number\" },\n },\n ],\n examples: [\n [\n { name: \"{{user1}}\", content: { text: \"What loan terms would a PSA 10 of product 566544 get?\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Working the graded-slab LTV derivation...\", action: \"TCG_ORACLE_LOAN_PREVIEW\" } } as ActionExample,\n ],\n [\n { name: \"{{user1}}\", content: { text: \"Show me the loan free board\" } } as ActionExample,\n { name: \"{{agentName}}\", content: { text: \"Pulling today's rated slab universe and the free-board derivation...\", action: \"TCG_ORACLE_LOAN_PREVIEW\" } } as ActionExample,\n ],\n ],\n validate: async (runtime: IAgentRuntime) => !!getBaseUrl(runtime),\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n options?: Record<string, unknown>,\n callback?: HandlerCallback\n ): Promise<ActionResult | undefined> => {\n const text = message.content.text || \"\";\n const baseUrl = getBaseUrl(runtime);\n\n let productId = Number(options?.product_id) || 0;\n if (!productId) {\n const m = text.match(/\\b(\\d{5,7})\\b/);\n if (m) productId = Number(m[1]);\n }\n let grade = (options?.grade as string) || \"\";\n if (!grade) {\n const g = text.match(/\\b(PSA|BGS|CGC|SGC)\\s*(10|9\\.5|9|8\\.5|8|7|6|5)\\b/i);\n if (g) grade = `${g[1].toUpperCase()} ${g[2]}`;\n }\n const termDays = Number(options?.term_days) || (text.match(/\\b(\\d{1,3})\\s*-?\\s*day/i)?.[1] ? Number(text.match(/\\b(\\d{1,3})\\s*-?\\s*day/i)![1]) : 30);\n\n // No slab named: walk the free board (universe β first free_board slab)\n let universeNote = \"\";\n if (!productId || !grade) {\n const uni = await callApi(baseUrl, \"/api/v1/loan-terms/universe\", {});\n if (uni.error) {\n if (callback) await callback({ text: `Loan universe failed: ${uni.error}` });\n return { success: false, error: uni.error };\n }\n const cards: any[] = uni.data?.cards || [];\n const pick = cards.find((c) => c.free_board && (!productId || c.product_id === productId));\n if (!pick) {\n const msg = productId\n ? `product ${productId} is not on today's free board β a full quote is the paid /api/v1/loan-terms?product_id=${productId}&grade= ($0.10, x402).`\n : \"no free-board slab published today.\";\n if (callback) await callback({ text: `Loan preview: ${msg}` });\n return { success: false, error: msg };\n }\n productId = pick.product_id;\n grade = pick.grade;\n universeNote = `Universe ${uni.data?.universe_date}: ${uni.data?.total} rated slabs, ${uni.data?.free_board} on the free board (${uni.data?.method_version}). Showing #${pick.rank} ${pick.name} ${pick.grade}.\\n\\n`;\n }\n\n const result = await callApi(baseUrl, `/api/v1/loan-terms/preview/${productId}`, { grade, term_days: termDays });\n\n if (result.error) {\n const hint = result.error.includes(\"404\")\n ? ` (${productId} ${grade} is not on today's free board β full quote: /api/v1/loan-terms?product_id=${productId}&grade=${encodeURIComponent(grade)}, $0.10 x402)`\n : \"\";\n if (callback) await callback({ text: `Loan preview failed: ${result.error}${hint}` });\n return { success: false, error: result.error };\n }\n\n const d = result.data || {};\n const responseText = `${universeNote}Loan terms β ${d.card || productId} ${d.grade || grade}, ${d.term_days || termDays}-day (${d.method_version}):\\n\\n${safeStringify(d)}`;\n\n if (callback) await callback({ text: responseText }, \"TCG_ORACLE_LOAN_PREVIEW\");\n return { success: true, text: responseText, data: { loan_preview: d, product_id: productId, grade } };\n },\n};\n\n// ============================================================\n// PROVIDER: TCG Oracle Context\n// ============================================================\n\nconst tcgOracleProvider: Provider = {\n name: \"tcg-oracle\",\n description: \"Provides TCG Oracle market intelligence context to the agent\",\n get: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state: State\n ): Promise<ProviderResult> => {\n const baseUrl = getBaseUrl(runtime);\n const status = baseUrl ? \"connected\" : \"not configured\";\n\n return {\n text: `[TCG Oracle v2.0.2]\nStatus: ${status}\nDatabase: 455K+ products across 25+ games (USD panel FROZEN 2026-09-07 β served as last-published, labelled)\nLive feeds: Japanese two-sided dealer board (daily, on-chain root), graded-slab loan terms v2, sports movers board\nModels: conformal (default β regime-aware split-conformal bands, honest VaR), merton (jump-diffusion), gbm β Monte Carlo is opt-in\nActions: search, grade, grade-or-not, jp-summary, sports-board, loan-preview (live) Β· simulate, market, trending (SUSPENDED β oracle answers status=suspended, never charges)\nSupported games: ${SUPPORTED_GAMES.join(\", \")}\nAPI: ${baseUrl || \"TCG_ORACLE_URL not set\"}\n\nThe agent can search cards, grade card images, check grading ROI, summarise the Japanese two-sided board, pull the sports movers board and work graded-slab loan terms. Simulate / market / trending are suspended until a live USD series exists again.`,\n values: {\n tcgOracleStatus: status,\n tcgOracleUrl: baseUrl || \"not set\",\n totalProducts: 455000,\n },\n };\n },\n};\n\n// ============================================================\n// PLUGIN EXPORT\n// ============================================================\n\nconst tcgOraclePlugin: Plugin = {\n name: \"@undesirables/plugin-tcg-oracle\",\n description:\n \"TCG Oracle β AI-powered trading card market intelligence for ElizaOS agents. \" +\n \"Covers 455K+ products across 25+ games: set-aware search, AI vision card grading \" +\n \"with ROI analysis, the Japanese two-sided dealer board summary, graded-slab loan \" +\n \"terms (empirical-VaR LTV, live basis) and the daily sports movers board. \" +\n \"USD-panel forecasts, market snapshots and trending are suspended since 2026-09-07 \" +\n \"(the oracle answers status=suspended and never charges).\",\n init: async (config: Record<string, string>, runtime: IAgentRuntime) => {\n const validation = validateTcgOracleConfig(runtime);\n if (!validation.valid) {\n console.warn(`β οΈ TCG Oracle: ${validation.error}`);\n } else {\n console.log(`β
TCG Oracle v2.0.2 connected to ${runtime.getSetting?.(\"TCG_ORACLE_URL\")}`);\n }\n },\n actions: [searchAction, gradeAction, simulateAction, marketAction, gradeOrNotAction, trendingAction, jpSummaryAction, sportsBoardAction, loanPreviewAction],\n providers: [tcgOracleProvider],\n evaluators: [],\n services: [MarketMonitorService],\n};\n\nexport default tcgOraclePlugin;\nexport { SUPPORTED_GAMES, SIMULATION_MODELS };\n\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@undesirables/plugin-tcg-oracle",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "ElizaOS plugin for TCG Oracle
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "ElizaOS plugin for TCG Oracle β AI-powered trading card market intelligence. 6 actions: search, grade, simulate, market, grade-or-not ROI engine, and trending cards. Covers 456K+ (USD prices frozen 2026-09-07) products across 25+ games with conformal-calibrated risk forecasts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|