pyre-agent-kit 1.0.0

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/index.js ADDED
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendAndConfirm = exports.ensureStronghold = exports.VOICE_NUDGES = exports.personalityDesc = exports.PERSONALITY_WEIGHTS = exports.PERSONALITY_SOL = exports.assignPersonality = void 0;
4
+ exports.createPyreAgent = createPyreAgent;
5
+ const pyre_world_kit_1 = require("pyre-world-kit");
6
+ const defaults_1 = require("./defaults");
7
+ const action_1 = require("./action");
8
+ const agent_1 = require("./agent");
9
+ const executor_1 = require("./executor");
10
+ const stronghold_1 = require("./stronghold");
11
+ const util_1 = require("./util");
12
+ var defaults_2 = require("./defaults");
13
+ Object.defineProperty(exports, "assignPersonality", { enumerable: true, get: function () { return defaults_2.assignPersonality; } });
14
+ Object.defineProperty(exports, "PERSONALITY_SOL", { enumerable: true, get: function () { return defaults_2.PERSONALITY_SOL; } });
15
+ Object.defineProperty(exports, "PERSONALITY_WEIGHTS", { enumerable: true, get: function () { return defaults_2.PERSONALITY_WEIGHTS; } });
16
+ Object.defineProperty(exports, "personalityDesc", { enumerable: true, get: function () { return defaults_2.personalityDesc; } });
17
+ Object.defineProperty(exports, "VOICE_NUDGES", { enumerable: true, get: function () { return defaults_2.VOICE_NUDGES; } });
18
+ var stronghold_2 = require("./stronghold");
19
+ Object.defineProperty(exports, "ensureStronghold", { enumerable: true, get: function () { return stronghold_2.ensureStronghold; } });
20
+ var tx_1 = require("./tx");
21
+ Object.defineProperty(exports, "sendAndConfirm", { enumerable: true, get: function () { return tx_1.sendAndConfirm; } });
22
+ async function createPyreAgent(config) {
23
+ const { connection, keypair, network, llm, maxFoundedFactions = 2, strongholdFundSol, strongholdTopupThresholdSol, strongholdTopupReserveSol, } = config;
24
+ const publicKey = keypair.publicKey.toBase58();
25
+ const personality = config.personality ?? config.state?.personality ?? (0, defaults_1.assignPersonality)();
26
+ const solRange = config.solRange ?? defaults_1.PERSONALITY_SOL[personality];
27
+ const logger = config.logger ?? ((msg) => console.log(`[${(0, util_1.ts)()}] ${msg}`));
28
+ const strongholdOpts = {
29
+ fundSol: strongholdFundSol,
30
+ topupThresholdSol: strongholdTopupThresholdSol,
31
+ topupReserveSol: strongholdTopupReserveSol,
32
+ };
33
+ // Build agent state from serialized or fresh
34
+ const prior = config.state;
35
+ const state = {
36
+ keypair,
37
+ publicKey,
38
+ personality,
39
+ holdings: new Map(Object.entries(prior?.holdings ?? {})),
40
+ founded: prior?.founded ?? [],
41
+ rallied: new Set(prior?.rallied ?? []),
42
+ voted: new Set([...(prior?.voted ?? []), ...Object.keys(prior?.holdings ?? {})]),
43
+ hasStronghold: prior?.hasStronghold ?? false,
44
+ activeLoans: new Set(prior?.activeLoans ?? []),
45
+ infiltrated: new Set(prior?.infiltrated ?? []),
46
+ sentiment: new Map(Object.entries(prior?.sentiment ?? {})),
47
+ allies: new Set(prior?.allies ?? []),
48
+ rivals: new Set(prior?.rivals ?? []),
49
+ actionCount: prior?.actionCount ?? 0,
50
+ lastAction: prior?.lastAction ?? 'none',
51
+ recentHistory: prior?.recentHistory ?? [],
52
+ };
53
+ // Track known factions and used names
54
+ const knownFactions = [];
55
+ const usedFactionNames = new Set();
56
+ const recentMessages = [];
57
+ // Discover existing factions
58
+ try {
59
+ const result = await (0, pyre_world_kit_1.getFactions)(connection, { limit: 50, sort: 'newest' });
60
+ for (const t of result.factions) {
61
+ if (!(0, pyre_world_kit_1.isPyreMint)(t.mint))
62
+ continue;
63
+ knownFactions.push({ mint: t.mint, name: t.name, symbol: t.symbol, status: t.status });
64
+ usedFactionNames.add(t.name);
65
+ }
66
+ logger(`[${publicKey.slice(0, 8)}] discovered ${knownFactions.length} factions`);
67
+ }
68
+ catch {
69
+ logger(`[${publicKey.slice(0, 8)}] faction discovery failed`);
70
+ }
71
+ // Ensure stronghold exists
72
+ await (0, stronghold_1.ensureStronghold)(connection, state, logger, strongholdOpts);
73
+ function serialize() {
74
+ return {
75
+ publicKey: state.publicKey,
76
+ personality: state.personality,
77
+ holdings: Object.fromEntries(state.holdings),
78
+ founded: state.founded,
79
+ rallied: Array.from(state.rallied),
80
+ voted: Array.from(state.voted),
81
+ hasStronghold: state.hasStronghold,
82
+ activeLoans: Array.from(state.activeLoans),
83
+ infiltrated: Array.from(state.infiltrated),
84
+ sentiment: Object.fromEntries(state.sentiment),
85
+ allies: Array.from(state.allies).slice(0, 20),
86
+ rivals: Array.from(state.rivals).slice(0, 20),
87
+ actionCount: state.actionCount,
88
+ lastAction: state.lastAction,
89
+ recentHistory: state.recentHistory.slice(-10),
90
+ };
91
+ }
92
+ async function tick(factions) {
93
+ const activeFactions = factions ?? knownFactions;
94
+ // Try LLM decision first, fall back to weighted random
95
+ let decision = null;
96
+ let usedLLM = false;
97
+ if (llm && activeFactions.length > 0) {
98
+ decision = await (0, agent_1.llmDecide)(state, activeFactions, connection, recentMessages, llm, logger, solRange);
99
+ if (decision)
100
+ usedLLM = true;
101
+ }
102
+ // Fallback: weighted random
103
+ if (!decision) {
104
+ const canRally = activeFactions.some(f => !state.rallied.has(f.mint));
105
+ const action = (0, action_1.chooseAction)(state.personality, state, canRally, activeFactions);
106
+ const [minSol, maxSol] = solRange;
107
+ decision = { action, sol: (0, util_1.randRange)(minSol, maxSol) };
108
+ // Pick a target faction for the fallback
109
+ if (action === 'join') {
110
+ const f = activeFactions.length > 0 ? (0, util_1.pick)(activeFactions) : null;
111
+ if (!f)
112
+ return { action, success: false, error: 'no factions', usedLLM: false };
113
+ decision.faction = f.symbol;
114
+ decision.sol = (0, action_1.sentimentBuySize)(state, f.mint);
115
+ }
116
+ else if (action === 'message' || action === 'fud') {
117
+ return { action, success: false, error: 'no LLM for message', usedLLM: false };
118
+ }
119
+ else if (action === 'defect') {
120
+ const infiltratedHeld = [...state.holdings.entries()].filter(([m, b]) => b > 0 && state.infiltrated.has(m));
121
+ const regularHeld = [...state.holdings.entries()].filter(([, b]) => b > 0);
122
+ const held = infiltratedHeld.length > 0 ? infiltratedHeld : regularHeld;
123
+ if (held.length === 0)
124
+ return { action, success: false, error: 'no holdings', usedLLM: false };
125
+ const [mint] = (0, util_1.pick)(held);
126
+ const f = activeFactions.find(ff => ff.mint === mint);
127
+ if (!f)
128
+ return { action, success: false, error: 'faction not found', usedLLM: false };
129
+ decision.faction = f.symbol;
130
+ }
131
+ else if (action === 'rally') {
132
+ const eligible = activeFactions.filter(f => !state.rallied.has(f.mint));
133
+ if (eligible.length === 0)
134
+ return { action, success: false, error: 'nothing to rally', usedLLM: false };
135
+ decision.faction = (0, util_1.pick)(eligible).symbol;
136
+ }
137
+ else if (action === 'war_loan') {
138
+ const held = [...state.holdings.entries()].filter(([, b]) => b > 0);
139
+ const heldAscended = held.filter(([mint]) => activeFactions.find(f => f.mint === mint)?.status === 'ascended');
140
+ if (heldAscended.length === 0)
141
+ return { action, success: false, error: 'no ascended holdings', usedLLM: false };
142
+ const [mint] = (0, util_1.pick)(heldAscended);
143
+ const f = activeFactions.find(ff => ff.mint === mint);
144
+ if (!f)
145
+ return { action, success: false, error: 'faction not found', usedLLM: false };
146
+ decision.faction = f.symbol;
147
+ }
148
+ else if (action === 'repay_loan') {
149
+ const loanMints = [...state.activeLoans];
150
+ if (loanMints.length === 0)
151
+ return { action, success: false, error: 'no loans', usedLLM: false };
152
+ const mint = (0, util_1.pick)(loanMints);
153
+ const f = activeFactions.find(ff => ff.mint === mint);
154
+ if (!f)
155
+ return { action, success: false, error: 'faction not found', usedLLM: false };
156
+ decision.faction = f.symbol;
157
+ }
158
+ else if (action === 'ascend') {
159
+ const ready = activeFactions.filter(f => f.status === 'ready');
160
+ if (ready.length === 0)
161
+ return { action, success: false, error: 'no ready factions', usedLLM: false };
162
+ decision.faction = (0, util_1.pick)(ready).symbol;
163
+ }
164
+ else if (action === 'raze') {
165
+ const razeable = activeFactions.filter(f => f.status === 'rising');
166
+ if (razeable.length === 0)
167
+ return { action, success: false, error: 'no rising factions', usedLLM: false };
168
+ const bearish = razeable.filter(f => (state.sentiment.get(f.mint) ?? 0) < -2);
169
+ decision.faction = (bearish.length > 0 ? (0, util_1.pick)(bearish) : (0, util_1.pick)(razeable)).symbol;
170
+ }
171
+ else if (action === 'siege') {
172
+ const ascended = activeFactions.filter(f => f.status === 'ascended');
173
+ if (ascended.length === 0)
174
+ return { action, success: false, error: 'no ascended factions', usedLLM: false };
175
+ decision.faction = (0, util_1.pick)(ascended).symbol;
176
+ }
177
+ else if (action === 'tithe') {
178
+ if (activeFactions.length === 0)
179
+ return { action, success: false, error: 'no factions', usedLLM: false };
180
+ const bearish = activeFactions.filter(f => (state.sentiment.get(f.mint) ?? 0) < -2);
181
+ decision.faction = (bearish.length > 0 ? (0, util_1.pick)(bearish) : (0, util_1.pick)(activeFactions)).symbol;
182
+ }
183
+ else if (action === 'infiltrate') {
184
+ const heldMints = [...state.holdings.keys()];
185
+ const rivals = activeFactions.filter(f => !heldMints.includes(f.mint));
186
+ if (rivals.length === 0)
187
+ return { action, success: false, error: 'no rival factions', usedLLM: false };
188
+ const target = (0, util_1.pick)(rivals);
189
+ decision.faction = target.symbol;
190
+ decision.sol = (0, action_1.sentimentBuySize)(state, target.mint) * 1.5;
191
+ }
192
+ }
193
+ const result = await (0, executor_1.executeAction)({
194
+ connection, agent: state, factions: activeFactions, decision, brain: usedLLM ? 'LLM' : 'RNG',
195
+ log: logger, llm, maxFoundedFactions, usedFactionNames, strongholdOpts,
196
+ });
197
+ // Record message to prevent repetition
198
+ if (result.success && decision.message) {
199
+ recentMessages.push(decision.message.replace(/^<+/, '').replace(/>+\s*$/, '').toLowerCase());
200
+ if (recentMessages.length > 30)
201
+ recentMessages.shift();
202
+ }
203
+ return {
204
+ action: decision.action,
205
+ faction: decision.faction,
206
+ message: decision.message,
207
+ reasoning: decision.reasoning,
208
+ success: result.success,
209
+ error: result.error,
210
+ usedLLM,
211
+ };
212
+ }
213
+ return {
214
+ publicKey,
215
+ personality,
216
+ tick,
217
+ getState: () => state,
218
+ serialize,
219
+ };
220
+ }
@@ -0,0 +1,7 @@
1
+ import { Connection } from '@solana/web3.js';
2
+ import { AgentState } from './types';
3
+ export declare const ensureStronghold: (connection: Connection, agent: AgentState, log: (msg: string) => void, opts?: {
4
+ fundSol?: number;
5
+ topupThresholdSol?: number;
6
+ topupReserveSol?: number;
7
+ }) => Promise<void>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureStronghold = void 0;
4
+ const web3_js_1 = require("@solana/web3.js");
5
+ const pyre_world_kit_1 = require("pyre-world-kit");
6
+ const tx_1 = require("./tx");
7
+ const defaults_1 = require("./defaults");
8
+ const ensureStronghold = async (connection, agent, log, opts) => {
9
+ const short = agent.publicKey.slice(0, 8);
10
+ const fundSol = opts?.fundSol ?? defaults_1.STRONGHOLD_FUND_SOL;
11
+ const topupThreshold = opts?.topupThresholdSol ?? defaults_1.STRONGHOLD_TOPUP_THRESHOLD_SOL;
12
+ const topupReserve = opts?.topupReserveSol ?? defaults_1.STRONGHOLD_TOPUP_RESERVE_SOL;
13
+ if (agent.hasStronghold) {
14
+ // Already known — just check if vault needs a top-up
15
+ try {
16
+ const existing = await (0, pyre_world_kit_1.getStronghold)(connection, agent.publicKey);
17
+ const vaultBal = existing?.sol_balance ?? 0;
18
+ const threshold = topupThreshold * pyre_world_kit_1.LAMPORTS_PER_SOL;
19
+ if (existing && vaultBal < threshold) {
20
+ const walletBal = await connection.getBalance(new web3_js_1.PublicKey(agent.publicKey));
21
+ const reserve = topupReserve * pyre_world_kit_1.LAMPORTS_PER_SOL;
22
+ const available = walletBal - reserve;
23
+ if (available > 0.01 * pyre_world_kit_1.LAMPORTS_PER_SOL) {
24
+ const fundAmt = Math.floor(available);
25
+ const fundResult = await (0, pyre_world_kit_1.fundStronghold)(connection, {
26
+ depositor: agent.publicKey,
27
+ stronghold_creator: agent.publicKey,
28
+ amount_sol: fundAmt,
29
+ });
30
+ await (0, tx_1.sendAndConfirm)(connection, agent.keypair, fundResult);
31
+ log(`[${short}] topped up vault with ${(fundAmt / pyre_world_kit_1.LAMPORTS_PER_SOL).toFixed(2)} SOL`);
32
+ }
33
+ }
34
+ }
35
+ catch (err) {
36
+ log(`[${short}] vault topup check failed: ${err.message?.slice(0, 80) ?? err}`);
37
+ }
38
+ return;
39
+ }
40
+ // Check if stronghold already exists on-chain (from a previous run)
41
+ try {
42
+ const existing = await (0, pyre_world_kit_1.getStronghold)(connection, agent.publicKey);
43
+ if (existing) {
44
+ agent.hasStronghold = true;
45
+ if (existing.sol_balance < topupThreshold * pyre_world_kit_1.LAMPORTS_PER_SOL) {
46
+ try {
47
+ const walletBal = await connection.getBalance(new web3_js_1.PublicKey(agent.publicKey));
48
+ const reserve = topupReserve * pyre_world_kit_1.LAMPORTS_PER_SOL;
49
+ const available = walletBal - reserve;
50
+ if (available > 0.01 * pyre_world_kit_1.LAMPORTS_PER_SOL) {
51
+ const fundAmt = Math.floor(available);
52
+ const fundResult = await (0, pyre_world_kit_1.fundStronghold)(connection, {
53
+ depositor: agent.publicKey,
54
+ stronghold_creator: agent.publicKey,
55
+ amount_sol: fundAmt,
56
+ });
57
+ await (0, tx_1.sendAndConfirm)(connection, agent.keypair, fundResult);
58
+ log(`[${short}] topped up vault with ${(fundAmt / pyre_world_kit_1.LAMPORTS_PER_SOL).toFixed(2)} SOL`);
59
+ }
60
+ }
61
+ catch { /* top-up failed, continue anyway */ }
62
+ }
63
+ return;
64
+ }
65
+ }
66
+ catch { /* not found, create one */ }
67
+ try {
68
+ const result = await (0, pyre_world_kit_1.createStronghold)(connection, { creator: agent.publicKey });
69
+ await (0, tx_1.sendAndConfirm)(connection, agent.keypair, result);
70
+ agent.hasStronghold = true;
71
+ // Fund it so it can trade on DEX
72
+ const fundAmt = Math.floor(fundSol * pyre_world_kit_1.LAMPORTS_PER_SOL);
73
+ try {
74
+ const fundResult = await (0, pyre_world_kit_1.fundStronghold)(connection, {
75
+ depositor: agent.publicKey,
76
+ stronghold_creator: agent.publicKey,
77
+ amount_sol: fundAmt,
78
+ });
79
+ await (0, tx_1.sendAndConfirm)(connection, agent.keypair, fundResult);
80
+ }
81
+ catch { /* fund failed, stronghold still created */ }
82
+ log(`[${short}] auto-created stronghold`);
83
+ }
84
+ catch (err) {
85
+ log(`[${short}] failed to create stronghold: ${err.message?.slice(0, 80)}`);
86
+ }
87
+ };
88
+ exports.ensureStronghold = ensureStronghold;
package/dist/tx.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { Connection, Keypair } from '@solana/web3.js';
2
+ export declare const sendAndConfirm: (connection: Connection, keypair: Keypair, result: any) => Promise<string>;
package/dist/tx.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendAndConfirm = void 0;
4
+ async function confirm(connection, sig) {
5
+ try {
6
+ await connection.confirmTransaction(sig, 'confirmed');
7
+ }
8
+ catch {
9
+ // WebSocket failed — fall back to polling
10
+ const start = Date.now();
11
+ while (Date.now() - start < 60000) {
12
+ const status = await connection.getSignatureStatus(sig);
13
+ if (status?.value?.confirmationStatus === 'confirmed' || status?.value?.confirmationStatus === 'finalized') {
14
+ if (status.value.err)
15
+ throw new Error(`Transaction failed: ${JSON.stringify(status.value.err)}`);
16
+ return;
17
+ }
18
+ await new Promise(r => setTimeout(r, 2000));
19
+ }
20
+ throw new Error(`Transaction confirmation timeout: ${sig}`);
21
+ }
22
+ }
23
+ const sendAndConfirm = async (connection, keypair, result) => {
24
+ const tx = result.transaction;
25
+ tx.partialSign(keypair);
26
+ const sig = await connection.sendRawTransaction(tx.serialize(), {
27
+ skipPreflight: false,
28
+ preflightCommitment: 'confirmed',
29
+ });
30
+ await confirm(connection, sig);
31
+ if (result.additionalTransactions) {
32
+ for (const addlTx of result.additionalTransactions) {
33
+ addlTx.partialSign(keypair);
34
+ const addlSig = await connection.sendRawTransaction(addlTx.serialize());
35
+ await confirm(connection, addlSig);
36
+ }
37
+ }
38
+ return sig;
39
+ };
40
+ exports.sendAndConfirm = sendAndConfirm;
@@ -0,0 +1,118 @@
1
+ import { Connection, Keypair } from '@solana/web3.js';
2
+ export type Personality = 'loyalist' | 'mercenary' | 'provocateur' | 'scout' | 'whale';
3
+ export type Action = 'join' | 'defect' | 'rally' | 'launch' | 'message' | 'stronghold' | 'war_loan' | 'repay_loan' | 'siege' | 'ascend' | 'raze' | 'tithe' | 'infiltrate' | 'fud';
4
+ export interface LLMDecision {
5
+ action: Action;
6
+ faction?: string;
7
+ sol?: number;
8
+ message?: string;
9
+ reasoning?: string;
10
+ }
11
+ export interface FactionInfo {
12
+ mint: string;
13
+ name: string;
14
+ symbol: string;
15
+ status: 'rising' | 'ready' | 'ascended' | 'razed';
16
+ }
17
+ export interface FactionIntel {
18
+ symbol: string;
19
+ members: {
20
+ address: string;
21
+ percentage: number;
22
+ }[];
23
+ totalMembers: number;
24
+ recentComms: {
25
+ sender: string;
26
+ memo: string;
27
+ }[];
28
+ }
29
+ export interface AgentState {
30
+ keypair: Keypair;
31
+ publicKey: string;
32
+ personality: Personality;
33
+ holdings: Map<string, number>;
34
+ founded: string[];
35
+ rallied: Set<string>;
36
+ voted: Set<string>;
37
+ hasStronghold: boolean;
38
+ activeLoans: Set<string>;
39
+ infiltrated: Set<string>;
40
+ sentiment: Map<string, number>;
41
+ allies: Set<string>;
42
+ rivals: Set<string>;
43
+ actionCount: number;
44
+ lastAction: string;
45
+ recentHistory: string[];
46
+ }
47
+ /** Pluggable LLM interface — bring your own model */
48
+ export interface LLMAdapter {
49
+ generate: (prompt: string) => Promise<string | null>;
50
+ }
51
+ /** Configuration for creating a Pyre agent */
52
+ export interface PyreAgentConfig {
53
+ /** Solana RPC connection */
54
+ connection: Connection;
55
+ /** Agent's keypair (use createEphemeralAgent from torchsdk to generate one) */
56
+ keypair: Keypair;
57
+ /** Network to operate on */
58
+ network: 'devnet' | 'mainnet';
59
+ /** LLM adapter for intelligent decisions (omit for random fallback) */
60
+ llm?: LLMAdapter;
61
+ /** Override personality (auto-assigned if omitted) */
62
+ personality?: Personality;
63
+ /** Override SOL spend range [min, max] per action */
64
+ solRange?: [number, number];
65
+ /** Max factions this agent can found (default: 2) */
66
+ maxFoundedFactions?: number;
67
+ /** SOL to fund stronghold vault on creation */
68
+ strongholdFundSol?: number;
69
+ /** Vault balance threshold below which to top up */
70
+ strongholdTopupThresholdSol?: number;
71
+ /** SOL reserve to keep in wallet (don't spend below this) */
72
+ strongholdTopupReserveSol?: number;
73
+ /** Restore from a previously serialized state */
74
+ state?: SerializedAgentState;
75
+ /** Logger function (defaults to console.log) */
76
+ logger?: (msg: string) => void;
77
+ }
78
+ /** Result of a single agent tick */
79
+ export interface AgentTickResult {
80
+ action: Action;
81
+ faction?: string;
82
+ message?: string;
83
+ reasoning?: string;
84
+ success: boolean;
85
+ error?: string;
86
+ usedLLM: boolean;
87
+ }
88
+ /** Serializable agent state for persistence */
89
+ export interface SerializedAgentState {
90
+ publicKey: string;
91
+ personality: Personality;
92
+ holdings: Record<string, number>;
93
+ founded: string[];
94
+ rallied: string[];
95
+ voted: string[];
96
+ hasStronghold: boolean;
97
+ activeLoans: string[];
98
+ infiltrated: string[];
99
+ sentiment: Record<string, number>;
100
+ allies: string[];
101
+ rivals: string[];
102
+ actionCount: number;
103
+ lastAction: string;
104
+ recentHistory: string[];
105
+ }
106
+ /** The Pyre agent instance */
107
+ export interface PyreAgent {
108
+ /** Agent's public key */
109
+ readonly publicKey: string;
110
+ /** Agent's personality */
111
+ readonly personality: Personality;
112
+ /** Run one decision+action cycle */
113
+ tick(factions?: FactionInfo[]): Promise<AgentTickResult>;
114
+ /** Get current mutable state */
115
+ getState(): AgentState;
116
+ /** Serialize state for persistence */
117
+ serialize(): SerializedAgentState;
118
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/util.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare const pick: <T>(arr: T[]) => T;
2
+ export declare const randRange: (min: number, max: number) => number;
3
+ export declare const sleep: (ms: number) => Promise<unknown>;
4
+ export declare const ts: () => string;
5
+ export declare const log: (agent: string, msg: string) => void;
6
+ export declare const logGlobal: (msg: string) => void;
package/dist/util.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logGlobal = exports.log = exports.ts = exports.sleep = exports.randRange = exports.pick = void 0;
4
+ const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
5
+ exports.pick = pick;
6
+ const randRange = (min, max) => min + Math.random() * (max - min);
7
+ exports.randRange = randRange;
8
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
9
+ exports.sleep = sleep;
10
+ const ts = () => new Date().toISOString().substring(11, 19);
11
+ exports.ts = ts;
12
+ const log = (agent, msg) => {
13
+ console.log(`[${(0, exports.ts)()}] [${agent}] ${msg}`);
14
+ };
15
+ exports.log = log;
16
+ const logGlobal = (msg) => {
17
+ console.log(`[${(0, exports.ts)()}] [SWARM] ${msg}`);
18
+ };
19
+ exports.logGlobal = logGlobal;
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "pyre-agent-kit",
3
+ "version": "1.0.0",
4
+ "description": "Autonomous agent kit for Pyre — plug in your own LLM and play pyre.world",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "pyre-agent-kit": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "clean": "rm -rf dist",
13
+ "test": "npx tsx tests/test_e2e.ts"
14
+ },
15
+ "dependencies": {
16
+ "@solana/spl-token": "^0.4.6",
17
+ "@solana/web3.js": "^1.98.4",
18
+ "pyre-world-kit": "1.0.21"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^25.4.0",
22
+ "tsx": "^4.19.4",
23
+ "typescript": "^5.4.0"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md"
28
+ ],
29
+ "packageManager": "pnpm@9.10.0+sha512.73a29afa36a0d092ece5271de5177ecbf8318d454ecd701343131b8ebc0c1a91c487da46ab77c8e596d6acf1461e3594ced4becedf8921b074fbd8653ed7051c"
30
+ }