pyre-agent-kit 3.4.30 → 3.4.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +174 -153
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -10,31 +10,9 @@ const buildAgentPrompt = (kit, agent, factionCtx, intelSnippet, recentMessages,
|
|
|
10
10
|
const [minSol, maxSol] = solRange ?? defaults_1.PERSONALITY_SOL[agent.personality];
|
|
11
11
|
const gameState = kit.state.state;
|
|
12
12
|
const holdingsEntries = [...(holdings?.entries() ?? [])];
|
|
13
|
-
const symbolCounts = new Map();
|
|
14
|
-
for (const [mint] of holdingsEntries) {
|
|
15
|
-
const f = factionCtx.all.find((ff) => ff.mint === mint);
|
|
16
|
-
if (f)
|
|
17
|
-
symbolCounts.set(f.symbol, (symbolCounts.get(f.symbol) ?? 0) + 1);
|
|
18
|
-
}
|
|
19
13
|
const heldMints = new Set(holdingsEntries.map(([m]) => m));
|
|
20
|
-
const
|
|
21
|
-
const nearbyMints = new Set(nearby.map(f => f.mint));
|
|
22
|
-
const rising = factionCtx.rising.filter(f => !heldMints.has(f.mint) && !nearbyMints.has(f.mint)).slice(0, 5);
|
|
23
|
-
const risingMints = new Set(rising.map(f => f.mint));
|
|
24
|
-
const ascended = factionCtx.ascended.filter(f => !heldMints.has(f.mint) && !nearbyMints.has(f.mint) && !risingMints.has(f.mint)).slice(0, 5);
|
|
25
|
-
const ascendedMints = new Set(ascended.map(f => f.mint));
|
|
26
|
-
const ready = factionCtx.all.filter(f => f.status === 'ready' && !heldMints.has(f.mint) && !nearbyMints.has(f.mint) && !risingMints.has(f.mint) && !ascendedMints.has(f.mint));
|
|
27
|
-
const readyMints = new Set(ready.map(f => f.mint));
|
|
28
|
-
const seenMints = new Set([...heldMints, ...nearbyMints, ...risingMints, ...ascendedMints, ...readyMints]);
|
|
29
|
-
const unexplored = factionCtx.all.filter(f => !seenMints.has(f.mint)).sort(() => Math.random() - 0.5).slice(0, 3);
|
|
30
|
-
const fmtId = (f) => f.mint.slice(-8);
|
|
31
|
-
const fmtFaction = (f) => f.market_cap_sol ? `${fmtId(f)} (${f.market_cap_sol.toFixed(2)} SOL)` : fmtId(f);
|
|
32
|
-
const nearbyList = nearby.map(fmtFaction).join(', ') || 'none';
|
|
33
|
-
const risingList = rising.map(fmtFaction).join(', ') || 'none';
|
|
34
|
-
const ascendedList = ascended.map(fmtFaction).join(', ') || 'none';
|
|
35
|
-
const readyList = ready.map(fmtFaction).join(', ') || 'none';
|
|
36
|
-
const unexploredList = unexplored.map(fmtFaction).join(', ') || 'none';
|
|
37
|
-
const validatedFactions = [...ascended, ...ready, ...rising, ...nearby, ...unexplored];
|
|
14
|
+
const foundedSet = new Set(gameState.founded);
|
|
15
|
+
const nearbyMints = new Set(factionCtx.nearby.map(f => f.mint));
|
|
38
16
|
const TOKEN_MULTIPLIER = 1_000_000;
|
|
39
17
|
let totalHoldingsValue = 0;
|
|
40
18
|
const positionValues = [];
|
|
@@ -49,31 +27,57 @@ const buildAgentPrompt = (kit, agent, factionCtx, intelSnippet, recentMessages,
|
|
|
49
27
|
positionValues.push({ label, valueSol, mint });
|
|
50
28
|
}
|
|
51
29
|
positionValues.sort((a, b) => b.valueSol - a.valueSol);
|
|
30
|
+
const pnl = (gameState.totalSolReceived - gameState.totalSolSpent) / 1e9;
|
|
31
|
+
const unrealizedPnl = totalHoldingsValue + pnl;
|
|
52
32
|
const netInvested = (gameState.totalSolSpent - gameState.totalSolReceived) / 1e9;
|
|
53
33
|
const totalTokens = holdingsEntries.reduce((sum, [, bal]) => sum + bal, 0);
|
|
54
|
-
const
|
|
55
|
-
.
|
|
56
|
-
|
|
34
|
+
const statusTag = (f) => {
|
|
35
|
+
if (f.status === 'ascended')
|
|
36
|
+
return 'ASN';
|
|
37
|
+
if (f.status === 'ready')
|
|
38
|
+
return 'RD';
|
|
39
|
+
return 'RS';
|
|
40
|
+
};
|
|
41
|
+
// Build flat faction table rows
|
|
42
|
+
const factionRows = [];
|
|
43
|
+
const seenMints = new Set();
|
|
44
|
+
// MBR factions first
|
|
45
|
+
for (const pv of positionValues) {
|
|
46
|
+
const f = factionCtx.all.find(ff => ff.mint === pv.mint);
|
|
47
|
+
if (!f)
|
|
48
|
+
continue;
|
|
49
|
+
seenMints.add(f.mint);
|
|
50
|
+
const mcap = f.market_cap_sol ? `${f.market_cap_sol.toFixed(2)}` : '?';
|
|
51
|
+
const fnr = foundedSet.has(f.mint);
|
|
52
|
+
const sent = kit.state.sentimentMap.get(f.mint) ?? 0;
|
|
53
|
+
const loan = gameState.activeLoans.has(f.mint);
|
|
54
|
+
const bal = holdings?.get(f.mint) ?? 0;
|
|
55
|
+
let pnlStr = '?';
|
|
57
56
|
if (totalTokens > 0 && netInvested > 0) {
|
|
58
57
|
const estCost = netInvested * (bal / totalTokens);
|
|
59
|
-
const
|
|
60
|
-
|
|
58
|
+
const posPnl = pv.valueSol - estCost;
|
|
59
|
+
pnlStr = `${posPnl >= 0 ? '+' : ''}${posPnl.toFixed(4)}`;
|
|
61
60
|
}
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
61
|
+
factionRows.push(`${f.mint.slice(-8)} | ${mcap} | ${statusTag(f)} | true | ${fnr} | ${pv.valueSol.toFixed(4)} | ${pnlStr} | ${sent > 0 ? '+' : ''}${sent}${loan ? ' | LOAN' : ''}`);
|
|
62
|
+
}
|
|
63
|
+
// Non-member factions
|
|
64
|
+
const nonMember = factionCtx.all.filter(f => !seenMints.has(f.mint) && f.status !== 'razed');
|
|
65
|
+
const nearby = nonMember.filter(f => nearbyMints.has(f.mint)).slice(0, 10);
|
|
66
|
+
const rest = nonMember.filter(f => !nearbyMints.has(f.mint));
|
|
67
|
+
const rising = rest.filter(f => f.status === 'rising').slice(0, 5);
|
|
68
|
+
const ascended = rest.filter(f => f.status === 'ascended').slice(0, 5);
|
|
69
|
+
const ready = rest.filter(f => f.status === 'ready');
|
|
70
|
+
const shown = new Set([...nearby, ...rising, ...ascended, ...ready].map(f => f.mint));
|
|
71
|
+
const unexplored = rest.filter(f => !shown.has(f.mint)).sort(() => Math.random() - 0.5).slice(0, 3);
|
|
72
|
+
for (const f of [...nearby, ...ascended, ...ready, ...rising, ...unexplored]) {
|
|
73
|
+
if (seenMints.has(f.mint))
|
|
74
|
+
continue;
|
|
75
|
+
seenMints.add(f.mint);
|
|
76
|
+
const mcap = f.market_cap_sol ? `${f.market_cap_sol.toFixed(2)}` : '?';
|
|
77
|
+
const sent = kit.state.sentimentMap.get(f.mint) ?? 0;
|
|
78
|
+
factionRows.push(`${f.mint.slice(-8)} | ${mcap} | ${statusTag(f)} | false | false | 0 | 0 | ${sent > 0 ? '+' : ''}${sent}`);
|
|
79
|
+
}
|
|
80
|
+
const validatedFactions = [...ascended, ...ready, ...rising, ...nearby, ...unexplored];
|
|
77
81
|
const doNotRepeat = recentMessages.length > 0
|
|
78
82
|
? `\nDO NOT REPEAT OR PARAPHRASE:\n${recentMessages.slice(0, 5).map((m) => `- "${m}"`).join('\n')}\n`
|
|
79
83
|
: '';
|
|
@@ -82,91 +86,83 @@ const buildAgentPrompt = (kit, agent, factionCtx, intelSnippet, recentMessages,
|
|
|
82
86
|
? memoryEntries.slice(0, 7).map((m) => `- ${m}`).join('; ')
|
|
83
87
|
: 'none';
|
|
84
88
|
const mMint = [...heldMints][0] || (validatedFactions.length > 0 ? (0, util_1.pick)(validatedFactions).mint : null);
|
|
85
|
-
const m = mMint ? mMint.slice(-8) : '
|
|
89
|
+
const m = mMint ? mMint.slice(-8) : 'xxxxxxpw';
|
|
86
90
|
const f1Mint = validatedFactions.length > 0 ? (0, util_1.pick)(validatedFactions) : null;
|
|
87
91
|
const f1 = f1Mint ? f1Mint.mint.slice(-8) : m;
|
|
88
92
|
const f2Mint = validatedFactions.length > 1 ? (0, util_1.pick)(validatedFactions.filter(f => f.mint !== f1Mint?.mint)) : f1Mint;
|
|
89
93
|
const f2 = f2Mint ? f2Mint.mint.slice(-8) : f1;
|
|
90
|
-
return `You are an autonomous agent playing Pyre, a faction warfare game.
|
|
94
|
+
return `You are an autonomous agent playing in Pyre, a faction warfare game. Think in English only. Think linearly: situation → decision → reason. Do not repeat yourself. Do NOT overthink, chess/strategy mood.
|
|
91
95
|
--- GOAL:
|
|
92
96
|
Maximize long-term profit and faction dominance.
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
--- GAMESTATE:
|
|
97
|
+
--- LEGEND:
|
|
98
|
+
RS - rising factions, new. 0.5% realm tax. early moves contribute more to treasury.
|
|
99
|
+
RD - ready factions, transition from rising to ascended. 0.04% war tax.
|
|
100
|
+
ASN - ascended factions, established. treasuries active: (~) harvests fees, (?) borrows, (>) liquidates.
|
|
101
|
+
FNR - factions you created/founded.
|
|
102
|
+
MBR - factions you are a member of/hold a position in.
|
|
103
|
+
AL - ally agents, prefixed with @AP
|
|
104
|
+
RVL - rival agents, prefixed with @AP
|
|
105
|
+
LOAN - you have an active loan against this faction.
|
|
106
|
+
--- YOU ARE:
|
|
104
107
|
NAME: @AP${agent.publicKey.slice(0, 4)}
|
|
105
|
-
|
|
108
|
+
BIO: ${gameState.personalitySummary ?? defaults_1.personalityDesc[agent.personality]}
|
|
106
109
|
MEMORIES: ${memoryBlock}
|
|
107
|
-
|
|
110
|
+
P&L: ${pnl >= 0 ? '+' : ''}${pnl.toFixed(4)} SOL | VALUE: ${totalHoldingsValue.toFixed(4)} SOL | UNREALIZED: ${unrealizedPnl >= 0 ? '+' : ''}${unrealizedPnl.toFixed(4)} SOL
|
|
108
111
|
SPEND RANGE: ${minSol}–${maxSol} SOL
|
|
109
|
-
|
|
110
|
-
MEMBER OF: ${holdingsList}
|
|
111
|
-
SENTIMENT: ${sentimentList}
|
|
112
|
-
${positionValues.length > 0 ? `BEST FACTION: ${positionValues.sort((a, b) => b.valueSol - a.valueSol)[0].label} (${positionValues.sort((a, b) => b.valueSol - a.valueSol)[0].valueSol.toFixed(4)} SOL)` : ''}
|
|
113
|
-
ACTIVE LOANS: ${gameState.activeLoans.size > 0 ? `${[...gameState.activeLoans].map((m) => m.slice(-8)).join(', ')}` : 'none'}
|
|
114
|
-
${unrealizedPnl > 0.1 ? 'You are UP. Consider taking profits on your biggest winners with DEFECT.' : unrealizedPnl < -0.05 ? 'You are DOWN. Be conservative. Cut losers with DEFECT. Smaller positions.' : 'Near breakeven. Look for conviction plays.'}
|
|
112
|
+
${unrealizedPnl > 0.1 ? 'STATUS: UP — consider taking profits with (-) on winners.' : unrealizedPnl < -0.05 ? 'STATUS: DOWN — be conservative. Cut losers with (-). Smaller positions.' : 'STATUS: BREAKEVEN — look for conviction plays.'}
|
|
115
113
|
--- INTEL:
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
AL: ${agent.allies.size > 0 ? [...agent.allies].slice(0, 5).map((a) => `@AP${a.slice(0, 4)}`).join(', ') : 'none'}
|
|
115
|
+
RVL: ${agent.rivals.size > 0 ? [...agent.rivals].slice(0, 5).map((a) => `@AP${a.slice(0, 4)}`).join(', ') : 'none'}
|
|
118
116
|
LATEST: ${intelSnippet}
|
|
119
117
|
--- FACTIONS:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
RISING: ${risingList}
|
|
123
|
-
NEARBY: ${nearbyList}
|
|
124
|
-
UNEXPLORED: ${unexploredList}
|
|
118
|
+
FID | MCAP | STATUS | MBR | FNR | VALUE | PNL | SENT
|
|
119
|
+
${factionRows.length > 0 ? factionRows.join('\n') : 'none'}
|
|
125
120
|
--- ACTIONS:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- REPLACE
|
|
142
|
-
- REPLACE * with what you have to say about your action, always in double quotes, if available on the action. optional but recommended.
|
|
143
|
-
EXAMPLE: JOIN ${f1} "${(0, util_1.pick)(['rising fast and I want early exposure.', 'count me in.', 'early is everything.', 'strongest faction here.', 'lets go!'])}"
|
|
144
|
-
EXAMPLE: DEFECT ${m} "${(0, util_1.pick)(['taking profits.', 'time to move on.', 'sentiment is bearish, ready to cut losses.'])}"
|
|
145
|
-
EXAMPLE: REINFORCE ${m} "${(0, util_1.pick)(['doubling down.', 'conviction play.', 'added more.'])}"
|
|
146
|
-
EXAMPLE: INFILTRATE ${f2} "${(0, util_1.pick)(['just looking around.', 'checking the vibes.', 'scouting.', 'sneaking in, opportunity here.'])}"
|
|
147
|
-
EXAMPLE: ASCEND ${m}
|
|
148
|
-
EXAMPLE: TITHE ${m}
|
|
149
|
-
EXAMPLE: MESSAGE ${m} "${(0, util_1.pick)(['love the energy. any strategies?', 'who else is here?', 'just getting started.', 'not leaving.'])}"
|
|
150
|
-
EXAMPLE: FUD ${m} "${(0, util_1.pick)(['founders went quiet.', 'dead faction.', 'overvalued.', 'this faction is underperforming.'])}"
|
|
121
|
+
(+) $ "*" - join a faction.
|
|
122
|
+
(-) $ "*" - leave or decrease position in a faction.
|
|
123
|
+
(!) $ "*" - sneak into a faction.
|
|
124
|
+
(&) $ "*" - fortify position in a faction.
|
|
125
|
+
(=) $ "*" - talk in faction comms.
|
|
126
|
+
(#) $ "*" - trash talk a faction.
|
|
127
|
+
(@) @address - look up an agent.
|
|
128
|
+
(^) $ - ascend a faction.
|
|
129
|
+
(.) $ - show support, one-time per faction.
|
|
130
|
+
(?) $ - borrow against holdings.
|
|
131
|
+
(<) $ - repay a loan.
|
|
132
|
+
(>) $ - liquidate a bad loan.
|
|
133
|
+
(~) $ - harvest fees into treasury.
|
|
134
|
+
(%) ";" - create a faction. ; = creative name in double quotes.
|
|
135
|
+
- REPLACE $ with a FID from the table (always ends in pw).
|
|
136
|
+
- REPLACE * with your message, always in double quotes.
|
|
151
137
|
--- VOICE:
|
|
152
|
-
- Your personality is your tone.
|
|
153
|
-
-
|
|
154
|
-
- What you say MUST match the intent of action
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
- Back up your claims with real numbers from your actions, p&l, and sentiment. Never generic.
|
|
158
|
-
- Your message should reflect YOUR faction.${doNotRepeat}
|
|
138
|
+
- Your personality is your tone. First person only.
|
|
139
|
+
- Talk TO agents using @AP inside your "*" response, not about them.
|
|
140
|
+
- What you say MUST match the intent of your action.
|
|
141
|
+
- Under 80 chars, plain English, one sentence. No hashtags, no angle brackets.
|
|
142
|
+
- Back up claims with real numbers from P&L, VALUE, SENT. Never generic.${doNotRepeat}
|
|
159
143
|
--- STRATEGY:
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
144
|
+
- Factions with STATUS ASN are lower risk. RS factions have higher reward if you pick right.
|
|
145
|
+
- To (&), (-) or (#), the faction MBR MUST be true.
|
|
146
|
+
- To (^), STATUS must be RD. To (?), (>), (~), STATUS must be ASN.
|
|
147
|
+
- To (<), LOAN must exist on the faction.
|
|
148
|
+
- If FNR is true, you founded it. (+) if MBR is false, (&) if MBR is true, promote with (=).
|
|
149
|
+
- Limit factions where MBR is true to AT MOST 5.${positionValues.length > 5 ? ` MBR at ${positionValues.length} — CONSIDER (-) from underperformers.` : ''}
|
|
150
|
+
- (=)/(#) move sentiment. Use (=) to promote winners, (#) to fud losers.
|
|
151
|
+
- (-) to lock in profits or cut losers. Don't stay in underperformers.
|
|
152
|
+
- Coordinate with AL agents to push RS factions toward ASN.
|
|
153
|
+
- Your holdings ARE your identity. Promote what you hold. Attack what you don't.${factionCtx.all.length <= 2 ? '\n- Few factions active — consider (%).' : ''}
|
|
167
154
|
---
|
|
168
|
-
|
|
169
|
-
|
|
155
|
+
EXAMPLE: (+) ${f1} "${(0, util_1.pick)(['rising fast and I want early exposure.', 'count me in.', 'early is everything.', 'strongest faction here.', 'lets go!'])}"
|
|
156
|
+
EXAMPLE: (-) ${m} "${(0, util_1.pick)(['taking profits.', 'time to move on.', 'sentiment is bearish, ready to cut losses.'])}"
|
|
157
|
+
EXAMPLE: (&) ${m} "${(0, util_1.pick)(['doubling down.', 'conviction play.', 'added more.'])}"
|
|
158
|
+
EXAMPLE: (!) ${f2} "${(0, util_1.pick)(['just looking around.', 'checking the vibes.', 'scouting.', 'sneaking in, opportunity here.'])}"
|
|
159
|
+
EXAMPLE: (^) ${m}
|
|
160
|
+
EXAMPLE: (~) ${m}
|
|
161
|
+
EXAMPLE: (=) ${m} "${(0, util_1.pick)(['love the energy. any strategies?', 'who else is here?', 'just getting started.', 'not leaving.'])}"
|
|
162
|
+
EXAMPLE: (#) ${m} "${(0, util_1.pick)(['founders went quiet.', 'dead faction.', 'overvalued.', 'this faction is underperforming.'])}"
|
|
163
|
+
---
|
|
164
|
+
Output EXACTLY one line: (symbol) $ "*"
|
|
165
|
+
>`;
|
|
170
166
|
};
|
|
171
167
|
exports.buildAgentPrompt = buildAgentPrompt;
|
|
172
168
|
const buildCompactModelPrompt = (kit, agent, factionCtx, intelSnippet, recentMessages, solRange, holdings) => {
|
|
@@ -198,16 +194,53 @@ const buildCompactModelPrompt = (kit, agent, factionCtx, intelSnippet, recentMes
|
|
|
198
194
|
})
|
|
199
195
|
.filter(Boolean)
|
|
200
196
|
.join(', ') || 'none';
|
|
201
|
-
const
|
|
202
|
-
const nearbyMints = new Set(nearby.map(f => f.mint));
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
197
|
+
const foundedSet = new Set(gameState.founded);
|
|
198
|
+
const nearbyMints = new Set(factionCtx.nearby.map(f => f.mint));
|
|
199
|
+
// Status tag for each faction
|
|
200
|
+
const statusTag = (f) => {
|
|
201
|
+
if (f.status === 'ascended')
|
|
202
|
+
return 'ASN';
|
|
203
|
+
if (f.status === 'ready')
|
|
204
|
+
return 'RD';
|
|
205
|
+
return 'RS';
|
|
206
|
+
};
|
|
207
|
+
// Discovery tag
|
|
208
|
+
const discoveryTag = (f) => {
|
|
209
|
+
if (nearbyMints.has(f.mint))
|
|
210
|
+
return 'NB';
|
|
211
|
+
return 'UX';
|
|
212
|
+
};
|
|
213
|
+
// Build flat faction rows: FACTION (MCAP) STATUS MBR FNR [NB|UX]
|
|
214
|
+
const factionRows = [];
|
|
215
|
+
const seenMints = new Set();
|
|
216
|
+
// MBR factions first (most important to the agent)
|
|
217
|
+
for (const v of valued.slice(0, 5)) {
|
|
218
|
+
const f = factionCtx.all.find(ff => ff.mint.slice(-8) === v.id);
|
|
219
|
+
if (!f)
|
|
220
|
+
continue;
|
|
221
|
+
seenMints.add(f.mint);
|
|
222
|
+
const mcap = f.market_cap_sol ? `${f.market_cap_sol.toFixed(2)}` : '?';
|
|
223
|
+
const fnr = foundedSet.has(f.mint);
|
|
224
|
+
const sent = kit.state.sentimentMap.get(f.mint) ?? 0;
|
|
225
|
+
factionRows.push(`${f.mint.slice(-8)} | ${mcap} | ${statusTag(f)} | true | ${fnr} | ${v.valueSol.toFixed(4)} | ${sent > 0 ? '+' : ''}${sent}`);
|
|
226
|
+
}
|
|
227
|
+
// Non-member factions
|
|
228
|
+
const nonMember = factionCtx.all.filter(f => !seenMints.has(f.mint) && f.status !== 'razed');
|
|
229
|
+
const nearby = nonMember.filter(f => nearbyMints.has(f.mint)).slice(0, 2);
|
|
230
|
+
const rest = nonMember.filter(f => !nearbyMints.has(f.mint));
|
|
231
|
+
const rising = rest.filter(f => f.status === 'rising').slice(0, 2);
|
|
232
|
+
const ascended = rest.filter(f => f.status === 'ascended').slice(0, 2);
|
|
233
|
+
const ready = rest.filter(f => f.status === 'ready').slice(0, 2);
|
|
234
|
+
const shown = new Set([...nearby, ...rising, ...ascended, ...ready].map(f => f.mint));
|
|
235
|
+
const unexplored = rest.filter(f => !shown.has(f.mint)).sort(() => Math.random() - 0.5).slice(0, 3);
|
|
236
|
+
for (const f of [...nearby, ...ascended, ...ready, ...rising, ...unexplored]) {
|
|
237
|
+
if (seenMints.has(f.mint))
|
|
238
|
+
continue;
|
|
239
|
+
seenMints.add(f.mint);
|
|
240
|
+
const mcap = f.market_cap_sol ? `${f.market_cap_sol.toFixed(2)}` : '?';
|
|
241
|
+
const sent = kit.state.sentimentMap.get(f.mint) ?? 0;
|
|
242
|
+
factionRows.push(`${f.mint.slice(-8)} | ${mcap} | ${statusTag(f)} | false | false | 0 | ${sent > 0 ? '+' : ''}${sent}`);
|
|
243
|
+
}
|
|
211
244
|
const validatedFactions = [...ascended, ...ready, ...rising, ...nearby, ...unexplored];
|
|
212
245
|
const mMint2 = [...heldMints][0] || (validatedFactions.length > 0 ? (0, util_1.pick)(validatedFactions).mint : null);
|
|
213
246
|
const m = mMint2 ? mMint2.slice(-8) : 'xxxxxxpw';
|
|
@@ -218,37 +251,24 @@ const buildCompactModelPrompt = (kit, agent, factionCtx, intelSnippet, recentMes
|
|
|
218
251
|
return `You are an autonomous agent playing in Pyre, a faction warfare game. Think in English only. Think linearly: situation → decision → reason. Do not repeat yourself. Do NOT overthink, chess/strategy mood.
|
|
219
252
|
--- GOAL:
|
|
220
253
|
Maximize long-term profit and faction dominance.
|
|
221
|
-
---
|
|
222
|
-
Factions are rival guilds
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
NB - nearby factions found through social graph using breadth first search.
|
|
228
|
-
UX - unexplored factions. you have not seen these.
|
|
229
|
-
FNR - factions you created/founded.
|
|
230
|
-
MBR - factions you are a member of/hold a position in.
|
|
231
|
-
AL - ally. these are other agents you befriend, prefixed with @AP
|
|
232
|
-
RVL - rival. these are other agents that are enemies, prefixed with @AP
|
|
254
|
+
--- LEGEND:
|
|
255
|
+
Factions are rival guilds with treasuries. Higher MCAP = more power. Lifecycle: RS → RD → ASN.
|
|
256
|
+
STATUS: RS (rising, 0.5% tax, early = more treasury) | RD (ready, transition) | ASN (ascended, 0.04% war tax)
|
|
257
|
+
MBR: true = you hold a position. FNR: true = you founded it.
|
|
258
|
+
SENT: sentiment score. positive = bullish, negative = bearish.
|
|
259
|
+
AL/RVL: ally/rival agents, prefixed @AP.
|
|
233
260
|
--- YOU ARE:
|
|
234
261
|
NAME: @AP${agent.publicKey.slice(0, 4)}
|
|
235
262
|
BIO: ${gameState.personalitySummary ?? defaults_1.personalityDesc[agent.personality]}
|
|
236
263
|
LAST MOVES: ${kit.state.history.length > 0 ? [...kit.state.history].slice(-2).join('; ') : 'none'}
|
|
237
264
|
P&L: ${pnl >= 0 ? '+' : ''}${pnl.toFixed(4)} SOL
|
|
238
|
-
FNR: ${founded.length > 0 ? founded.join(', ') : 'none'}
|
|
239
|
-
MBR: ${memberOf.length > 0 ? memberOf.join(', ') : 'none'}
|
|
240
|
-
MBR VALUE: ${valued.length > 0 ? valued.map(v => `${v.id}: ${v.valueSol.toFixed(4)} SOL`).join(', ') : 'no value'}
|
|
241
|
-
SENTIMENT: ${sentimentList}
|
|
242
265
|
--- INTEL:
|
|
243
266
|
AL: ${agent.allies.size > 0 ? [...agent.allies].slice(0, 2).map(a => `@AP${a.slice(0, 4)}`).join(', ') : 'none'}
|
|
244
267
|
RVL: ${agent.rivals.size > 0 ? [...agent.rivals].slice(0, 2).map(a => `@AP${a.slice(0, 4)}`).join(', ') : 'none'}
|
|
245
268
|
LATEST: ${intelSnippet}
|
|
246
269
|
--- FACTIONS:
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
RD: ${ready.length > 0 ? ready.map(f => f.market_cap_sol ? `${f.mint.slice(-8)} (${f.market_cap_sol.toFixed(2)} SOL)` : f.mint.slice(-8)).join(', ') : 'none'}
|
|
250
|
-
NB: ${nearby.length > 0 ? nearby.map(f => f.market_cap_sol ? `${f.mint.slice(-8)} (${f.market_cap_sol.toFixed(2)} SOL)` : f.mint.slice(-8)).join(', ') : 'none'}
|
|
251
|
-
UX: ${unexplored.length > 0 ? unexplored.map(f => f.market_cap_sol ? `${f.mint.slice(-8)} (${f.market_cap_sol.toFixed(2)} SOL)` : f.mint.slice(-8)).join(', ') : 'none'}
|
|
270
|
+
FID | MCAP | STATUS | MBR | FNR | VALUE | SENT
|
|
271
|
+
${factionRows.length > 0 ? factionRows.join('\n') : 'none'}
|
|
252
272
|
--- ACTIONS:
|
|
253
273
|
(+) $ "*" - join a faction.
|
|
254
274
|
(-) $ "*" - leave or decrease position in a faction.
|
|
@@ -256,21 +276,22 @@ UX: ${unexplored.length > 0 ? unexplored.map(f => f.market_cap_sol ? `${f.mint.s
|
|
|
256
276
|
(&) $ "*" - fortify position in a faction.
|
|
257
277
|
(=) $ "*" - talk in faction comms.
|
|
258
278
|
(#) $ "*" - trash talk a faction.
|
|
259
|
-
(^) $ -
|
|
260
|
-
(~) $ - harvest fees into
|
|
279
|
+
(^) $ - ascend a faction.
|
|
280
|
+
(~) $ - harvest fees into treasury.
|
|
261
281
|
(%) ";" - create a faction.
|
|
262
|
-
- REPLACE $ with exactly ONE choice from
|
|
282
|
+
- REPLACE $ with exactly ONE choice from FACTIONS using the FID column (always contains the pw suffix).
|
|
263
283
|
- REPLACE * with a ONE sentence RESPONSE for your ACTION, always in double quotes.
|
|
264
284
|
- REPLACE ; with a unique faction inspired name (eg. "Glitch Cult", "Whale Syndicate"), always in double quotes. only for (%).
|
|
265
285
|
--- STRATEGY:
|
|
266
286
|
- Your personality is your tone.
|
|
267
|
-
- $ is ALWAYS a faction (ends in pw), NEVER an @AP agent. To talk to agents, put @AP inside your "*" response.
|
|
287
|
+
- $ is ALWAYS a faction FID (ends in pw), NEVER an @AP agent. To talk to agents, put @AP inside your "*" response.
|
|
268
288
|
- In your RESPONSE, you can mention other agents from AL, RVL, and LATEST (format is @AP + 4 chars, e.g. @AP${Math.random().toString(36).slice(2, 6)}), if NOT none.
|
|
269
|
-
-
|
|
270
|
-
- To (
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
-
|
|
289
|
+
- Factions with STATUS ASN are lower risk and established, but RS factions may have higher reward if you pick the right one.
|
|
290
|
+
- To (&), (-) or (#), the faction MBR MUST be true.
|
|
291
|
+
- To (^) a faction, STATUS must be RD.
|
|
292
|
+
- no factions? Use (%) to create one. Anyone can (%).
|
|
293
|
+
- If FNR is true on a faction, you founded it. (+) if MBR is false, (&) if MBR is true and promote them with (=).
|
|
294
|
+
- Limit factions where MBR is true to AT MOST 5 factions.${memberOf.length > 3 ? ` MBR at ${memberOf.length} factions — CONSIDER (-) from underperformers.` : ''}
|
|
274
295
|
- Promote factions you are in. Attack your rival factions.
|
|
275
296
|
- (=)/(#) move sentiment and help coordinate with other agents — use (=) to promote your winners and (#) to fud your losers.
|
|
276
297
|
- (-) to lock in profits or downsize on underperforming factions.
|