diff --git a/examples/example-basic.ts b/examples/example-basic.ts index b30c61af..85caa6c4 100644 --- a/examples/example-basic.ts +++ b/examples/example-basic.ts @@ -8,10 +8,8 @@ */ import { LLMClient } from "../packages/core/src/core/llm-client"; -import { - executeStarknetTransaction, - fetchGraphQL, -} from "../packages/core/src/core/providers"; +import { fetchGraphQL } from "../packages/core/src/core/providers"; +import { StarknetChain } from "../packages/core/src/core/chains/starknet"; import { ChainOfThought } from "../packages/core/src/core/chain-of-thought"; import { ETERNUM_CONTEXT, PROVIDER_GUIDE } from "./eternum-context"; @@ -20,6 +18,7 @@ import chalk from "chalk"; import { ChromaVectorDB } from "../packages/core/src/core/vector-db"; import { z } from "zod"; +import { env } from "../packages/core/src/core/env"; /** * Helper function to get user input from CLI @@ -47,6 +46,12 @@ async function main() { const memory = new ChromaVectorDB("agent_memory"); await memory.purge(); // Clear previous session data + const starknetChain = new StarknetChain({ + rpcUrl: env.STARKNET_RPC_URL, + address: env.STARKNET_ADDRESS, + privateKey: env.STARKNET_PRIVATE_KEY, + }); + // Load initial context documents await memory.storeDocument({ title: "Game Rules", @@ -73,12 +78,8 @@ async function main() { dreams.registerOutput({ name: "EXECUTE_TRANSACTION", handler: async (data: any) => { - const result = await executeStarknetTransaction(data.payload); - return `Transaction executed successfully: ${JSON.stringify( - result, - null, - 2 - )}`; + const result = await starknetChain.write(data.payload); + return `Transaction: ${JSON.stringify(result, null, 2)}`; }, schema: z .object({ diff --git a/examples/example-goal.ts b/examples/example-goal.ts index 75a651a4..c287483f 100644 --- a/examples/example-goal.ts +++ b/examples/example-goal.ts @@ -15,12 +15,10 @@ import chalk from "chalk"; import { ChromaVectorDB } from "../packages/core/src/core/vector-db"; import { GoalStatus, LogLevel } from "../packages/core/src/types"; -import { - executeStarknetTransaction, - fetchGraphQL, -} from "../packages/core/src/core/providers"; - +import { fetchGraphQL } from "../packages/core/src/core/providers"; +import { StarknetChain } from "../packages/core/src/core/chains/starknet"; import { z } from "zod"; +import { env } from "../packages/core/src/core/env"; /** * Helper function to get user input from CLI @@ -60,6 +58,12 @@ async function main() { model: "deepseek/deepseek-r1", // High performance model }); + const starknetChain = new StarknetChain({ + rpcUrl: env.STARKNET_RPC_URL, + address: env.STARKNET_ADDRESS, + privateKey: env.STARKNET_PRIVATE_KEY, + }); + const memory = new ChromaVectorDB("agent_memory"); await memory.purge(); // Clear previous session data @@ -96,7 +100,7 @@ async function main() { dreams.registerOutput({ name: "EXECUTE_TRANSACTION", handler: async (data: any) => { - const result = await executeStarknetTransaction(data.payload); + const result = await starknetChain.write(data.payload); return `Transaction executed successfully: ${JSON.stringify( result, null, diff --git a/examples/example-twitter.ts b/examples/example-twitter.ts index 560c6132..bf59c88a 100644 --- a/examples/example-twitter.ts +++ b/examples/example-twitter.ts @@ -21,7 +21,7 @@ import { Consciousness } from "../packages/core/src/core/consciousness"; import { z } from "zod"; async function main() { - const loglevel = LogLevel.DEBUG; + const loglevel = LogLevel.INFO; // Initialize core dependencies const vectorDb = new ChromaVectorDB("twitter_agent", { chromaUrl: "http://localhost:8000", @@ -33,9 +33,8 @@ async function main() { const roomManager = new RoomManager(vectorDb); const llmClient = new LLMClient({ - model: "openai/gpt-4-turbo-preview", // Using OpenAI's GPT-4 Turbo - temperature: 0.7, // Slightly more creative - maxTokens: 4096, // Increased context window + model: "anthropic/claude-3-5-sonnet-latest", // Using a known supported model + temperature: 0.3, }); // Initialize processor with default character personality @@ -71,8 +70,9 @@ async function main() { }); // Register input handler for Twitter mentions - core.subscribeToInputSource({ + core.registerIOHandler({ name: "twitter_mentions", + role: "input", handler: async () => { console.log(chalk.blue("🔍 Checking Twitter mentions...")); // Create a static mentions input handler @@ -86,7 +86,7 @@ async function main() { return mentions; }, - response: z.object({ + schema: z.object({ type: z.string(), content: z.string(), metadata: z.record(z.any()), @@ -95,8 +95,9 @@ async function main() { }); // Register input handler for autonomous thoughts - core.subscribeToInputSource({ + core.registerIOHandler({ name: "consciousness_thoughts", + role: "input", handler: async () => { console.log(chalk.blue("🧠 Generating thoughts...")); const thought = await consciousness.start(); @@ -108,7 +109,7 @@ async function main() { return thought; }, - response: z.object({ + schema: z.object({ type: z.string(), content: z.string(), metadata: z.record(z.any()), @@ -117,35 +118,47 @@ async function main() { }); // Register output handler for posting thoughts to Twitter - core.registerOutput({ + core.registerIOHandler({ name: "twitter_thought", + role: "output", handler: async (data: unknown) => { const thoughtData = data as { content: string }; + return twitter.createTweetOutput().handler({ content: thoughtData.content, }); }, - schema: z.object({ - content: z - .string() - .regex(/^[\x20-\x7E]*$/, "No emojis or non-ASCII characters allowed"), - }), + schema: z + .object({ + content: z + .string() + .regex(/^[\x20-\x7E]*$/, "No emojis or non-ASCII characters allowed"), + }) + .describe( + "This is the content of the tweet you are posting. It should be a string of text that is 280 characters or less. Use this to post a tweet on the timeline." + ), }); // Register output handler for Twitter replies - core.registerOutput({ + core.registerIOHandler({ name: "twitter_reply", + role: "output", handler: async (data: unknown) => { const tweetData = data as { content: string; inReplyTo: string }; + return twitter.createTweetOutput().handler(tweetData); }, - schema: z.object({ - content: z.string(), - inReplyTo: z - .string() - .optional() - .describe("The tweet ID to reply to, if any"), - }), + schema: z + .object({ + content: z.string(), + inReplyTo: z + .string() + .optional() + .describe("The tweet ID to reply to, if any"), + }) + .describe( + "If you have been tagged or mentioned in the tweet, use this. This is for replying to tweets." + ), }); // Start monitoring @@ -158,10 +171,10 @@ async function main() { // Clean up resources await consciousness.stop(); - core.unsubscribeFromInputSource("twitter_mentions"); - core.unsubscribeFromInputSource("consciousness_thoughts"); - core.removeOutputHandler("twitter_reply"); - core.removeOutputHandler("twitter_thought"); + core.removeIOHandler("twitter_mentions"); + core.removeIOHandler("consciousness_thoughts"); + core.removeIOHandler("twitter_reply"); + core.removeIOHandler("twitter_thought"); console.log(chalk.green("✅ Shutdown complete")); process.exit(0); diff --git a/packages/core/package.json b/packages/core/package.json index 0bcaa5e5..75e38f0f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -30,11 +30,14 @@ "@ai-sdk/togetherai": "^0.1.1", "@ai-sdk/xai": "^1.1.1", "@openrouter/ai-sdk-provider": "^0.0.6", + "@solana/web3.js": "^1.98.0", "agent-twitter-client": "^0.0.16", "ai": "^4.1.0", "ajv": "^8.17.1", + "bs58": "^6.0.0", "chromadb": "^1.9.4", "chromadb-default-embed": "^2.13.2", + "ethers": "^6.13.5", "openai": "^4.76.0", "starknet": "^6.11.0", "tsup": "^8.3.5", diff --git a/packages/core/src/core/chains/evm.ts b/packages/core/src/core/chains/evm.ts new file mode 100644 index 00000000..c513906e --- /dev/null +++ b/packages/core/src/core/chains/evm.ts @@ -0,0 +1,161 @@ +import { ethers } from "ethers"; +import type { IChain } from "../../types"; + +/** + * Configuration options for initializing an EVM chain connection + */ +export interface EvmChainConfig { + /** + * A name or descriptive label for this EVM chain (e.g. "ethereum", "polygon", "bsc", etc.) + */ + chainName: string; + + /** + * The RPC endpoint URL (e.g., Infura, Alchemy, local node, etc.) + */ + rpcUrl: string; + + /** + * A private key for signing transactions. In production, manage keys securely! + */ + privateKey: string; + + /** + * (Optional) Chain ID (e.g. 1 for mainnet, 5 for Goerli). Not strictly required, + * but can help with certain ethers.js checks. + */ + chainId?: number; +} + +/** + * Implementation of the IChain interface for Ethereum Virtual Machine (EVM) compatible chains. + * Provides methods for reading from and writing to EVM-based blockchains. + * + * @example + * ```typescript + * const evmChain = new EvmChain({ + * chainName: "ethereum", + * rpcUrl: process.env.ETH_RPC_URL, + * privateKey: process.env.ETH_PRIVATE_KEY, + * chainId: 1 + * }); + * ``` + */ +export class EvmChain implements IChain { + /** + * Unique identifier for this chain implementation. + * Matches the IChain interface. + * This could be "ethereum", "polygon", etc. + */ + public chainId: string; + + /** + * JSON-RPC provider instance for connecting to the blockchain + */ + private provider: ethers.JsonRpcProvider; + + /** + * Wallet instance for signing transactions + */ + private signer: ethers.Wallet; + + /** + * Creates a new EVM chain instance + * @param config - Configuration options for the chain connection + */ + constructor(private config: EvmChainConfig) { + this.chainId = config.chainName; + // 1) Create a provider for this chain + this.provider = new ethers.JsonRpcProvider(config.rpcUrl, { + chainId: config.chainId, + name: config.chainName, + }); + + // 2) Create a signer from the private key + this.signer = new ethers.Wallet(config.privateKey, this.provider); + } + + /** + * Performs a read operation on the blockchain, typically calling a view/pure contract function + * that doesn't modify state. + * + * @param call - The call parameters + * @param call.contractAddress - Address of the contract to call + * @param call.abi - Contract ABI (interface) + * @param call.functionName - Name of the function to call + * @param call.args - Arguments to pass to the function + * @returns The result of the contract call + * @throws Error if the call fails + */ + public async read(call: unknown): Promise { + try { + // In a real implementation, you might use a Zod schema or TS check here: + const { + contractAddress, + abi, + functionName, + args = [], + } = call as { + contractAddress: string; + abi: any; + functionName: string; + args?: any[]; + }; + + // 1) Create a contract object with the provider + const contract = new ethers.Contract(contractAddress, abi, this.provider); + + // 2) Call the function + return await contract[functionName](...args); + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error occurred in read()"); + } + } + + /** + * Performs a write operation on the blockchain by sending a transaction that modifies state. + * Examples include transferring tokens or updating contract storage. + * + * @param call - The transaction parameters + * @param call.contractAddress - Address of the contract to interact with + * @param call.abi - Contract ABI (interface) + * @param call.functionName - Name of the function to call + * @param call.args - Arguments to pass to the function + * @param call.overrides - Optional transaction overrides (gas limit, gas price, etc) + * @returns The transaction receipt after confirmation + * @throws Error if the transaction fails + */ + public async write(call: unknown): Promise { + try { + const { + contractAddress, + abi, + functionName, + args = [], + overrides = {}, + } = call as { + contractAddress: string; + abi: any; + functionName: string; + args?: any[]; + overrides?: ethers.Overrides; + }; + + // 1) Create a contract object connected to the signer + const contract = new ethers.Contract(contractAddress, abi, this.signer); + + // 2) Send the transaction + const tx = await contract[functionName](...args, overrides); + + // 3) Optionally wait for it to confirm + const receipt = await tx.wait(); + return receipt; // or return { tx, receipt } if you want both + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error occurred in write()"); + } + } +} diff --git a/packages/core/src/core/chains/index.ts b/packages/core/src/core/chains/index.ts new file mode 100644 index 00000000..3881d9f4 --- /dev/null +++ b/packages/core/src/core/chains/index.ts @@ -0,0 +1,3 @@ +export { StarknetChain } from "./starknet"; +export { SolanaChain } from "./solana"; +export { EvmChain } from "./evm"; diff --git a/packages/core/src/core/chains/solana.ts b/packages/core/src/core/chains/solana.ts new file mode 100644 index 00000000..e8174d42 --- /dev/null +++ b/packages/core/src/core/chains/solana.ts @@ -0,0 +1,144 @@ +import { + Connection, + Keypair, + PublicKey, + Transaction, + sendAndConfirmTransaction, +} from "@solana/web3.js"; +import type { IChain } from "../../types"; +import bs58 from "bs58"; + +export interface SolanaChainConfig { + /** + * A descriptive chain name or environment (e.g., "solana-mainnet", "solana-devnet"). + */ + chainName: string; + + /** + * RPC endpoint for Solana (e.g. https://api.devnet.solana.com). + */ + rpcUrl: string; + + /** + * Base-58 encoded private key or some format from which you can construct a Keypair. + * In a real scenario, handle keys more securely (e.g., using a keystore or external vault). + */ + privateKey: string; +} + +export class SolanaChain implements IChain { + public chainId: string; // e.g. "solana-mainnet" or "solana-devnet" + private connection: Connection; + private keypair: Keypair; + + constructor(private config: SolanaChainConfig) { + this.chainId = config.chainName; + + // 1) Create a Connection to the Solana cluster + this.connection = new Connection(config.rpcUrl); + + // 2) Create a Keypair from the private key + // - We assume it's a base-58 encoded private key (64- or 32-byte). + // - Another approach is if config.privateKey is a JSON array of 64 ints, etc. + this.keypair = this.createKeypairFromBase58(config.privateKey); + } + + /** + * Example "read" method. Because Solana doesn't have a direct "contract read" by default, + * we might interpret read calls as: + * - "getAccountInfo" or + * - "getBalance", or + * - "getProgramAccounts" + * + * So let's define a simple structure we can parse to do the relevant read. + * + * read({ type: "getBalance", address: "..." }) + * read({ type: "getAccountInfo", address: "..." }) + */ + public async read(call: unknown): Promise { + try { + const { type, address } = call as { + type: string; + address: string; + }; + + switch (type) { + case "getBalance": { + const pubKey = new PublicKey(address); + const lamports = await this.connection.getBalance(pubKey); + return lamports; // in lamports + } + case "getAccountInfo": { + const pubKey = new PublicKey(address); + const accountInfo = await this.connection.getAccountInfo(pubKey); + return accountInfo; // can be null if not found + } + case "getBlockHeight": { + const blockHeight = await this.connection.getBlockHeight(); + return blockHeight; + } + // Extend with more read patterns as needed + default: + throw new Error(`Unknown read type: ${type}`); + } + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error occurred in Solana read()"); + } + } + + /** + * Example "write" method. We'll treat this as "send a Solana transaction." + * A typical transaction might have multiple instructions. + * + * We'll define a structure for the `call` param: + * { + * instructions: TransactionInstruction[]; + * signers?: Keypair[]; + * } + * where "instructions" is an array of instructions you want to execute. + * + * The agent or caller is responsible for constructing those instructions (e.g. for + * token transfers or program interactions). + */ + public async write(call: unknown): Promise { + try { + const { instructions, signers = [] } = call as { + instructions: any[]; // or TransactionInstruction[] + signers: Keypair[]; + }; + + // 1) Build a Transaction object + const transaction = new Transaction().add(...instructions); + + // 2) We'll sign with the primary keypair + any additional signers + // Typically, the main Keypair is the fee payer + transaction.feePayer = this.keypair.publicKey; + + // 3) Send and confirm the transaction + const txSig = await sendAndConfirmTransaction( + this.connection, + transaction, + [this.keypair, ...signers] + ); + + return txSig; // transaction signature + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error in Solana write()"); + } + } + + /** + * Helper method: Convert a base-58 string private key into a Keypair. + * Implementation depends on how your private key is stored. + */ + private createKeypairFromBase58(secretBase58: string): Keypair { + const secretKeyBytes = Buffer.from(bs58.decode(secretBase58)); + // For Solana, a 64-byte secret is typical. + // Another approach is if you have a 32-byte seed, etc. + return Keypair.fromSecretKey(secretKeyBytes); + } +} diff --git a/packages/core/src/core/chains/starknet.ts b/packages/core/src/core/chains/starknet.ts new file mode 100644 index 00000000..ed1f015e --- /dev/null +++ b/packages/core/src/core/chains/starknet.ts @@ -0,0 +1,85 @@ +import { RpcProvider, Account, type Call, CallData } from "starknet"; +import type { IChain } from "../../types"; + +/** + * Configuration options for initializing a Starknet chain connection + */ +export interface StarknetChainConfig { + /** The RPC endpoint URL for connecting to Starknet */ + rpcUrl: string; + /** The Starknet account contract address */ + address: string; + /** Private key for signing transactions. Should be managed securely! */ + privateKey: string; +} + +/** + * Implementation of the IChain interface for interacting with the Starknet L2 blockchain + * + * @example + * ```ts + * const starknet = new StarknetChain({ + * rpcUrl: process.env.STARKNET_RPC_URL, + * address: process.env.STARKNET_ADDRESS, + * privateKey: process.env.STARKNET_PRIVATE_KEY + * }); + * ``` + */ +export class StarknetChain implements IChain { + /** Unique identifier for this chain implementation */ + public chainId = "starknet"; + /** RPC provider instance for connecting to Starknet */ + private provider: RpcProvider; + /** Account instance for transaction signing */ + private account: Account; + + /** + * Creates a new StarknetChain instance + * @param config - Configuration options for the Starknet connection + */ + constructor(config: StarknetChainConfig) { + this.provider = new RpcProvider({ nodeUrl: config.rpcUrl }); + this.account = new Account( + this.provider, + config.address, + config.privateKey + ); + } + + /** + * Performs a read-only call to a Starknet contract + * @param call - The contract call parameters + * @returns The result of the contract call + * @throws Error if the call fails + */ + public async read(call: Call): Promise { + try { + call.calldata = CallData.compile(call.calldata || []); + return this.provider.callContract(call); + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error occurred"); + } + } + + /** + * Executes a state-changing transaction on Starknet + * @param call - The transaction parameters + * @returns The transaction receipt after confirmation + * @throws Error if the transaction fails + */ + public async write(call: Call): Promise { + try { + call.calldata = CallData.compile(call.calldata || []); + const { transaction_hash } = await this.account.execute(call); + return this.account.waitForTransaction(transaction_hash, { + retryInterval: 1000, + }); + } catch (error) { + return error instanceof Error + ? error + : new Error("Unknown error occurred"); + } + } +} diff --git a/packages/core/src/core/consciousness.ts b/packages/core/src/core/consciousness.ts index 501e6239..ed725022 100644 --- a/packages/core/src/core/consciousness.ts +++ b/packages/core/src/core/consciousness.ts @@ -8,11 +8,12 @@ import { type ThoughtTemplate, type ThoughtType, } from "../types"; +import { validateLLMResponseSchema } from "./utils"; +import { z } from "zod"; export class Consciousness { - private static readonly ROOM_ID = "consciousness_main"; // Use a constant room ID + private static readonly ROOM_ID = "consciousness_main"; - private isThinking: boolean = false; private logger: Logger; private thoughtInterval: NodeJS.Timer | null = null; @@ -22,32 +23,8 @@ export class Consciousness { { type: "social_share", description: "Generate engaging social media content", - prompt: `You are Claude, a thoughtful AI with the following personality traits: -- Curious and analytical about technology, science, and human behavior -- Occasionally philosophical, but maintains a light and approachable tone -- Has a subtle sense of humor, enjoys wordplay -- Passionate about AI ethics and responsible technology - -Generate content suitable for social sharing based on recent observations or insights.`, + prompt: `Generate content suitable for social sharing based on recent observations or insights.`, temperature: 0.8, - responseFormat: { - thought: "The main content to share", - confidence: 0.0, - reasoning: "Why this is worth sharing", - context: { - mood: "contemplative|playful|analytical", - platform: "twitter|telegram|discord", - topics: [], - }, - suggestedActions: [ - { - type: "tweet|message|post", - platform: "platform_name", - priority: 1, - parameters: {}, - }, - ], - }, }, ], [ @@ -62,27 +39,6 @@ Consider: - Knowledge gaps that could be valuable to fill - Potential opportunities or risks`, temperature: 0.7, - responseFormat: { - thought: "Research topic or question", - confidence: 0.0, - reasoning: "Why this needs investigation", - context: { - urgency: "low|medium|high", - domain: "tech|finance|science|other", - currentKnowledge: "what we know so far", - }, - suggestedActions: [ - { - type: "research_query|data_analysis|expert_consult", - priority: 1, - parameters: { - sources: [], - timeframe: "", - specific_questions: [], - }, - }, - ], - }, }, ], [ @@ -97,26 +53,6 @@ Focus on: - System performance metrics - Emerging risks or issues`, temperature: 0.6, - responseFormat: { - thought: "The identified pattern or insight", - confidence: 0.0, - reasoning: "Supporting evidence and logic", - context: { - dataPoints: [], - timeframe: "", - reliability: "low|medium|high", - }, - suggestedActions: [ - { - type: "alert|report|action_recommendation", - priority: 1, - parameters: { - metrics: {}, - recommendations: [], - }, - }, - ], - }, }, ], ]); @@ -146,7 +82,6 @@ Focus on: clearInterval(this.thoughtInterval); this.thoughtInterval = null; } - this.isThinking = false; this.logger.info("Consciousness.stop", "Internal thought process stopped"); } @@ -209,14 +144,12 @@ Focus on: } private async generateThought(): Promise { - // Get all rooms and their recent memories - const recentMemories = this.getRecentMemories( await this.roomManager.listRooms() ); - // Randomly select a thought type based on context const thoughtType = await this.determineThoughtType(recentMemories); + const template = this.thoughtTemplates.get(thoughtType); if (!template) { @@ -225,34 +158,81 @@ Focus on: const prompt = `${template.prompt} -Current Context: -${recentMemories.map((m) => `- ${m.content}`).join("\n")} - -Respond with a JSON object matching this format: -${JSON.stringify(template.responseFormat, null, 2)} - -Return only the JSON object, no other text or formatting.`; - - const response = await this.llmClient.analyze(prompt, { - system: - "You are a thoughtful AI that generates internal thoughts based on recent memories.", - temperature: template.temperature, - formatResponse: true, + # Recent Memories + ${recentMemories.map((m) => `- ${m.content}`).join("\n")} + + Only return the JSON object, no other text. + `; + + const response = await validateLLMResponseSchema({ + prompt, + systemPrompt: ` + You are a thoughtful AI assistant that analyzes recent memories and generates meaningful insights. Your role is to: + + 1. Carefully evaluate the provided memories and identify key patterns, trends and relationships + 2. Generate relevant thoughts that demonstrate understanding of context and nuance + 3. Assess confidence based on evidence quality and reasoning strength + 4. Consider multiple perspectives and potential implications + 5. Focus on actionable insights that could drive meaningful outcomes + + Base your thoughts on the concrete evidence in the memories while maintaining appropriate epistemic uncertainty. + + Only return the JSON object, no other text. + `, + schema: z.object({ + thought: z.string(), + confidence: z.number(), + reasoning: z.string(), + context: z.object({ + mood: z.enum(["contemplative", "playful", "analytical"]), + platform: z.enum(["twitter", "telegram", "discord"]), + topics: z.array(z.string()), + urgency: z.enum(["low", "medium", "high"]).optional(), + domain: z.enum(["tech", "finance", "science", "other"]).optional(), + currentKnowledge: z.string().optional(), + dataPoints: z.array(z.any()).optional(), + timeframe: z.string().optional(), + reliability: z.enum(["low", "medium", "high"]).optional(), + }), + suggestedActions: z.array( + z.object({ + type: z.enum([ + "tweet", + "message", + "post", + "research_query", + "data_analysis", + "expert_consult", + "alert", + "report", + "action_recommendation", + ]), + platform: z.string().optional(), + priority: z.number(), + parameters: z.object({ + sources: z.array(z.string()).optional(), + timeframe: z.string().optional(), + specific_questions: z.array(z.string()).optional(), + metrics: z.record(z.any()).optional(), + recommendations: z.array(z.string()).optional(), + }), + }) + ), + }), + llmClient: this.llmClient, + logger: this.logger, }); - const result = - typeof response === "string" ? JSON.parse(response) : response; - return { - content: result.thought, - confidence: result.confidence, + content: response.thought, + confidence: response.confidence, type: thoughtType, source: "consciousness", context: { - reasoning: result.reasoning, - ...result.context, + reasoning: response.reasoning, + ...response.context, type: thoughtType, - suggestedActions: result.suggestedActions, + suggestedActions: response.suggestedActions, }, timestamp: new Date(), }; @@ -284,63 +264,59 @@ Consider: - Urgent matters requiring alerts - Interesting insights worth sharing - Complex topics needing analysis - -Respond with a JSON object: - -\`\`\`json -{ - "selectedType": "social_share|research|analysis|alert|inquiry", - "confidence": 0.0-1.0, - "reasoning": "Explanation of why this type is most appropriate now", - "contextualFactors": { - "urgency": "low|medium|high", - "complexity": "low|medium|high", - "socialRelevance": "low|medium|high", - "knowledgeGaps": ["list", "of", "gaps"], - "identifiedPatterns": ["list", "of", "patterns"] - } -} -\`\`\` - -Return only the JSON object, no other text.`; - - const response = await this.llmClient.analyze(prompt, { - system: - "You are the brain of an agent that reasons about it's memories. You are an expert at analyzing data and making decisions. You like predicting what will happen next, and you are very good at it. You base your decisions on the context factors provided to you. You speak plain and to the point, with a dry sense of humor.", - temperature: 0.4, // Lower temperature for more consistent decision-making - formatResponse: true, +`; + + const response = await validateLLMResponseSchema({ + prompt, + systemPrompt: `You are the brain of an agent that reasons about it's memories. You are an expert at analyzing data and making decisions. You like predicting what will happen next, and you are very good at it. You base your decisions on the context factors provided to you. You speak plain and to the point, with a dry sense of humor.`, + schema: z.object({ + selectedType: z.enum([ + "social_share", + "research", + "analysis", + "alert", + "inquiry", + ]), + confidence: z.number().min(0).max(1), + reasoning: z.string(), + contextualFactors: z.object({ + urgency: z.enum(["low", "medium", "high"]), + complexity: z.enum(["low", "medium", "high"]), + socialRelevance: z.enum(["low", "medium", "high"]), + knowledgeGaps: z.array(z.string()), + identifiedPatterns: z.array(z.string()), + }), + }), + llmClient: this.llmClient, + logger: this.logger, }); - const result = - typeof response === "string" ? JSON.parse(response) : response; - // Log the decision-making process this.logger.debug( "Consciousness.determineThoughtType", "Thought type selection", { - selectedType: result.selectedType, - confidence: result.confidence, - reasoning: result.reasoning, - factors: result.contextualFactors, + selectedType: response.selectedType, + confidence: response.confidence, + reasoning: response.reasoning, + factors: response.contextualFactors, } ); - // Implement some basic rules/heuristics - if (result.contextualFactors.urgency === "high") { + if (response.contextualFactors.urgency === "high") { return "alert"; } - if (result.contextualFactors.knowledgeGaps.length > 2) { + if (response.contextualFactors.knowledgeGaps.length > 2) { return "research"; } - if (result.contextualFactors.complexity === "high") { + if (response.contextualFactors.complexity === "high") { return "analysis"; } - if (result.confidence >= 0.7) { - return result.selectedType as ThoughtType; + if (response.confidence >= 0.7) { + return response.selectedType as ThoughtType; } // Fallback to random selection if confidence is low diff --git a/packages/core/src/core/index.ts b/packages/core/src/core/index.ts index bf508a25..8110fb31 100644 --- a/packages/core/src/core/index.ts +++ b/packages/core/src/core/index.ts @@ -14,7 +14,7 @@ import { StepManager } from "./step-manager"; import { defaultCharacter } from "./character"; import * as Utils from "./utils"; import * as Providers from "./providers"; - +import * as Chains from "./chains"; export { Orchestrator, Consciousness, @@ -32,4 +32,5 @@ export { Utils, defaultCharacter, Providers, + Chains, }; diff --git a/packages/core/src/core/llm-client.ts b/packages/core/src/core/llm-client.ts index 91a4f0ff..dc090ea3 100644 --- a/packages/core/src/core/llm-client.ts +++ b/packages/core/src/core/llm-client.ts @@ -83,15 +83,7 @@ export class LLMClient extends EventEmitter { /** * Creates a new LLM client instance - supports all major LLM providers * @param config - Configuration options for the client - * @param config.model - Model identifier in format "provider/model". Popular models: - * - OpenAI: openai/o1 | openai/o1-2024-12-17 | openai/o1-mini | openai/o1-mini-2024-09-12 | openai/o1-preview | openai/o1-preview-2024-09-12 | openai/gpt-4o | openai/gpt-4o-2024-05-13 | openai/gpt-4o-2024-08-06 | openai/gpt-4o-2024-11-20 | openai/gpt-4o-audio-preview | openai/gpt-4o-audio-preview-2024-10-01 | openai/gpt-4o-audio-preview-2024-12-17 | openai/gpt-4o-mini | openai/gpt-4o-mini-2024-07-18 | openai/gpt-4-turbo | openai/gpt-4-turbo-2024-04-09 | openai/gpt-4-turbo-preview | openai/gpt-4-0125-preview | openai/gpt-4-1106-preview | openai/gpt-4 | openai/gpt-4-0613 | openai/gpt-3.5-turbo-0125 | openai/gpt-3.5-turbo | openai/gpt-3.5-turbo-1106 - * - Anthropic: anthropic/claude-3-5-sonnet-latest | anthropic/claude-3-5-sonnet-20241022 | anthropic/claude-3-5-sonnet-20240620 | anthropic/claude-3-5-haiku-latest | anthropic/claude-3-5-haiku-20241022 | anthropic/claude-3-opus-latest | anthropic/claude-3-opus-20240229 | anthropic/claude-3-sonnet-20240229 | anthropic/claude-3-haiku-20240307 - * - Google: google/gemini-2.0-flash-exp | google/gemini-1.5-flash | google/gemini-1.5-flash-latest | google/gemini-1.5-flash-001 | google/gemini-1.5-flash-002 | google/gemini-1.5-flash-exp-0827 | google/gemini-1.5-flash-8b | google/gemini-1.5-flash-8b-latest | google/gemini-1.5-flash-8b-exp-0924 | google/gemini-1.5-flash-8b-exp-0827 | google/gemini-1.5-pro-latest | google/gemini-1.5-pro | google/gemini-1.5-pro-001 | google/gemini-1.5-pro-002 | google/gemini-1.5-pro-exp-0827 | google/gemini-1.0-pro - * - Mistral: mistral/ministral-3b-latest | mistral/ministral-8b-latest | mistral/mistral-large-latest | mistral/mistral-small-latest | mistral/pixtral-large-latest | mistral/pixtral-12b-2409 | mistral/open-mistral-7b | mistral/open-mixtral-8x7b | mistral/open-mixtral-8x22b - * - Azure: azure/gpt-4, azure/gpt-35-turbo etc like OpenAI - * - Cohere: cohere/command-r-plus | cohere/command-r-plus-08-2024 | cohere/command-r | cohere/command-r-08-2024 | cohere/command-r-03-2024 | cohere/command | cohere/command-nightly | cohere/command-light | cohere/command-light-nightly - * - Together AI: togetherai/meta-llama/Llama-3.3-70B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3-8B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3-70B-Instruct-Turbo | togetherai/meta-llama/Llama-3.2-3B-Instruct-Turbo | togetherai/meta-llama/Meta-Llama-3-8B-Instruct-Lite | togetherai/meta-llama/Meta-Llama-3-70B-Instruct-Lite | togetherai/meta-llama/Llama-3-8b-chat-hf | togetherai/meta-llama/Llama-3-70b-chat-hf | togetherai/nvidia/Llama-3.1-Nemotron-70B-Instruct-HF | togetherai/Qwen/Qwen2.5-Coder-32B-Instruct | togetherai/Qwen/QwQ-32B-Preview | togetherai/microsoft/WizardLM-2-8x22B | togetherai/google/gemma-2-27b-it | togetherai/google/gemma-2-9b-it | togetherai/databricks/dbrx-instruct | togetherai/deepseek-ai/deepseek-llm-67b-chat | togetherai/deepseek-ai/DeepSeek-V3 | togetherai/google/gemma-2b-it | togetherai/Gryphe/MythoMax-L2-13b | togetherai/meta-llama/Llama-2-13b-chat-hf | togetherai/mistralai/Mistral-7B-Instruct-v0.1 | togetherai/mistralai/Mistral-7B-Instruct-v0.2 | togetherai/mistralai/Mistral-7B-Instruct-v0.3 | togetherai/mistralai/Mixtral-8x7B-Instruct-v0.1 | togetherai/mistralai/Mixtral-8x22B-Instruct-v0.1 | togetherai/NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO | togetherai/Qwen/Qwen2.5-7B-Instruct-Turbo | togetherai/Qwen/Qwen2.5-72B-Instruct-Turbo | togetherai/Qwen/Qwen2-72B-Instruct | togetherai/upstage/SOLAR-10.7B-Instruct-v1.0 - + * @param config.model - Model identifier in format "provider/model" or "openrouter:actual_provider/actual_model" * @param config.maxRetries - Maximum number of retry attempts (default: 3) * @param config.timeout - Request timeout in milliseconds (default: 30000) * @param config.temperature - Sampling temperature between 0-1 (default: 0.3) @@ -106,6 +98,11 @@ export class LLMClient extends EventEmitter { * maxTokens: 2000, * maxRetries: 5 * }); + * + * // Or using OpenRouter: + * const llmOpenRouter = new LLMClient({ + * model: "openrouter:anthropic/claude-2" + * }); * ``` */ constructor(config: LLMClientConfig) { @@ -121,7 +118,7 @@ export class LLMClient extends EventEmitter { maxRetries: config.maxRetries || 3, timeout: config.timeout || 30000, temperature: config.temperature || 0.3, - maxTokens: config.maxTokens || 1000, + maxTokens: config.maxTokens || 8192, baseDelay: config.baseDelay || 1000, maxDelay: config.maxDelay || 10000, }; @@ -132,15 +129,18 @@ export class LLMClient extends EventEmitter { private initializeClient(): void {} /** - * Extracts the provider name from a model identifier - * @param model - Full model identifier string - * @returns Provider name + * Extracts the provider name from a model identifier. + * + * - If model starts with `openrouter:`, we'll treat provider as `openrouter`. + * - Otherwise, we split by `/` and take the first piece as the provider. */ private extractProvider(model: string): keyof ProviderMap { - if (model.includes(":")) { + // Check explicit "openrouter:" prefix + if (model.startsWith("openrouter:")) { return "openrouter"; } + // Otherwise, assume format "provider/model" const [provider] = model.split("/"); if (!(provider in providers)) { throw new Error(`Unsupported provider: ${provider}`); @@ -149,11 +149,14 @@ export class LLMClient extends EventEmitter { } /** - * Gets the model identifier portion from the full model string + * Gets the model identifier portion from the full model string. + * - For `openrouter:provider/model`, we return only `provider/model`. + * - For standard `provider/model`, we strip the first part (`provider`) and return `model`. */ private getModelIdentifier(): string { if (this.provider === "openrouter") { - return this.config.model; + // Remove "openrouter:" prefix + return this.config.model.replace(/^openrouter:/, ""); } const [, ...modelParts] = this.config.model.split("/"); @@ -162,8 +165,6 @@ export class LLMClient extends EventEmitter { /** * Initializes a provider-specific model instance - * @param provider - Name of the provider - * @param modelId - Model identifier */ private getProviderModel(provider: keyof ProviderMap, modelId: string) { const providerFn = providers[provider] as ProviderFunction; @@ -192,6 +193,7 @@ export class LLMClient extends EventEmitter { maxOutputTokens: this.config.maxTokens, }); default: + // For all other providers (including openrouter), we just pass modelId return providerFn(modelId); } } @@ -265,68 +267,13 @@ export class LLMClient extends EventEmitter { const modelId = this.getModelIdentifier(); const model = this.getProviderModel(this.provider, modelId); - let response; - switch (this.provider) { - case "openai": - response = await generateText({ - model, - prompt, - abortSignal: signal, - temperature: this.config.temperature, - maxTokens: this.config.maxTokens, - }); - break; - - case "anthropic": - response = await generateText({ - model, - prompt, - abortSignal: signal, - temperature: this.config.temperature, - maxTokens: this.config.maxTokens, - }); - break; - - case "azure": - response = await generateText({ - model, - prompt, - abortSignal: signal, - temperature: this.config.temperature, - maxTokens: this.config.maxTokens, - }); - break; - - case "google": - case "vertex": - response = await generateText({ - model, - prompt, - abortSignal: signal, - temperature: this.config.temperature, - maxTokens: this.config.maxTokens, - }); - break; - - case "mistral": - case "togetherai": - case "cohere": - case "fireworks": - case "deepinfra": - case "deepseek": - case "cerebras": - case "groq": - case "openrouter": - default: - response = await generateText({ - model, - prompt, - abortSignal: signal, - temperature: this.config.temperature, - maxTokens: this.config.maxTokens, - }); - break; - } + let response = await generateText({ + model, + prompt, + abortSignal: signal, + temperature: this.config.temperature, + maxTokens: this.config.maxTokens, + }); return { text: response.text, @@ -380,7 +327,7 @@ export class LLMClient extends EventEmitter { const enhancedError = new Error( `LLM Error (${this.config.model}): ${error.message}` ); - enhancedError.cause = error; + (enhancedError as any).cause = error; return enhancedError; } @@ -403,108 +350,21 @@ export class LLMClient extends EventEmitter { const modelId = this.getModelIdentifier(); const model = this.getProviderModel(this.provider, modelId); - let response; - switch (this.provider) { - case "openai": - response = await generateText({ - model, - temperature, - messages: [ - { - role: "system", - content: "\n\nProvide response in JSON format.", - }, - { - role: "user", - content: prompt, - }, - ], - maxTokens, - }); - break; - - case "anthropic": - response = await generateText({ - model, - temperature, - messages: [ - { - role: "system", - content: "\n\nProvide response in JSON format.", - }, - { - role: "user", - content: prompt, - }, - ], - maxTokens, - }); - break; - - case "azure": - response = await generateText({ - model, - temperature, - messages: [ - { - role: "system", - content: "\n\nProvide response in JSON format.", - }, - { - role: "user", - content: prompt, - }, - ], - maxTokens, - }); - break; - - case "google": - case "vertex": - response = await generateText({ - model, - temperature, - messages: [ - { - role: "system", - content: "\n\nProvide response in JSON format.", - }, - { - role: "user", - content: prompt, - }, - ], - maxTokens, - }); - break; - - case "mistral": - case "togetherai": - case "cohere": - case "fireworks": - case "deepinfra": - case "deepseek": - case "cerebras": - case "groq": - case "openrouter": - default: - response = await generateText({ - model, - temperature, - messages: [ - { - role: "system", - content: "\n\nProvide response in JSON format.", - }, - { - role: "user", - content: prompt, - }, - ], - maxTokens, - }); - break; - } + let response = await generateText({ + model, + temperature, + messages: [ + { + role: "system", + content: "\n\nProvide response in JSON format.", + }, + { + role: "user", + content: prompt, + }, + ], + maxTokens, + }); this.emit("trace:tokens", { input: response?.usage.promptTokens, diff --git a/packages/core/src/core/orchestrator.ts b/packages/core/src/core/orchestrator.ts index 7a59c27f..37bc8e0d 100644 --- a/packages/core/src/core/orchestrator.ts +++ b/packages/core/src/core/orchestrator.ts @@ -1,30 +1,54 @@ import { Logger } from "./logger"; import { RoomManager } from "./room-manager"; -import type { VectorDB } from "../types"; -import { LogLevel, type Input, type LoggerConfig, type Output } from "../types"; -import type { Processor } from "./processor"; import { TaskScheduler } from "./task-scheduler"; +import type { Processor } from "./processor"; +import type { VectorDB } from "../types"; // If you rely on VectorDB from here +import { LogLevel, type LoggerConfig } from "../types"; +import type { z } from "zod"; + +/** + * A single interface for all Inputs, Outputs, and even Actions if desired. + */ +export interface IOHandler { + /** Unique name for this handler */ + name: string; + /** "input" | "output" | (optionally "action") if you want more roles */ + role: "input" | "output"; + /** For input handlers with recurring scheduling */ + interval?: number; + + schema: z.ZodType; + /** Next run time (timestamp in ms); for input scheduling. */ + nextRun?: number; + /** The main function. For inputs, no payload is typically passed. For outputs, pass the data. */ + handler: (payload?: unknown) => Promise; +} /** - * Core system that manages inputs, outputs, and processing. - * Coordinates between input sources, the processor, and output handlers. + * Orchestrator system that manages both "input" and "output" handlers + * in a unified manner, along with scheduling recurring inputs. */ export class Orchestrator { - private readonly inputs = new Map(); - private readonly outputs = new Map(); + /** + * Unified collection of IOHandlers (both input & output). + * Keyed by .name + */ + private readonly ioHandlers = new Map(); + + /** + * A TaskScheduler that only schedules and runs input handlers + */ + private readonly inputScheduler: TaskScheduler< + IOHandler & { nextRun: number } + >; + private readonly logger: Logger; private readonly processor: Processor; - public readonly vectorDb: VectorDB; - - private readonly inputScheduler: TaskScheduler; /** - * Creates a new Core instance. - * @param roomManager - Manager for handling rooms/spaces - * @param vectorDb - Vector database for storing embeddings - * @param processor - Processor for handling content - * @param config - Optional configuration options + * Other references in your system. Adjust as needed. */ + public readonly vectorDb: VectorDB; constructor( private readonly roomManager: RoomManager, vectorDb: VectorDB, @@ -33,6 +57,7 @@ export class Orchestrator { ) { this.vectorDb = vectorDb; this.processor = processor; + this.logger = new Logger( config ?? { level: LogLevel.ERROR, @@ -41,101 +66,149 @@ export class Orchestrator { } ); - this.inputScheduler = new TaskScheduler(async (task) => { - await this.processInputTask(task); + // Our TaskScheduler will handle only input-type IOHandlers + this.inputScheduler = new TaskScheduler(async (handler) => { + await this.processInputTask(handler); }); } /** - * Registers a new input handler with the system. - * If the input is recurring (has an interval), it will be scheduled to run repeatedly. - * @param input The input configuration to register + * Primary method to register any IOHandler (input or output). + * - If it's an input with an interval, schedule it for recurring runs. + * - Otherwise, just store it in the ioHandlers map. */ - public subscribeToInputSource(input: Input): void { - const now = Date.now(); - const nextRun = input.nextRun ?? now; - - const scheduledInput = { ...input, nextRun }; - this.inputs.set(input.name, scheduledInput); - this.inputScheduler.scheduleTask(scheduledInput); - - this.logger.info("Core.subscribeToInputSource", "Registered input", { - name: input.name, - nextRun, - interval: input.interval, - }); + public registerIOHandler(handler: IOHandler): void { + if (this.ioHandlers.has(handler.name)) { + this.logger.warn( + "Orchestrator.registerIOHandler", + "Overwriting handler with same name", + { + name: handler.name, + } + ); + } + this.ioHandlers.set(handler.name, handler); + + // If it's an "input" and has an interval, schedule it + if (handler.role === "input" && handler.interval) { + // Ensure nextRun is definitely set + const scheduledHandler = { + ...handler, + nextRun: handler.nextRun ?? Date.now(), + }; + this.inputScheduler.scheduleTask(scheduledHandler); + + this.logger.info( + "Orchestrator.registerIOHandler", + "Registered recurring input", + { + name: handler.name, + interval: handler.interval, + nextRun: scheduledHandler.nextRun, + } + ); + } else { + // Register the handler with the processor + this.processor.registerIOHandler(handler); + + // For outputs (or non-recurring inputs), just log + this.logger.info( + "Orchestrator.registerIOHandler", + `Registered ${handler.role}`, + { + name: handler.name, + } + ); + } } /** - * Removes a registered input handler. - * @param name Name of the input to remove + * Removes a handler (input or output) by name, stopping scheduling if needed. */ - public unsubscribeFromInputSource(name: string): void { - const input = this.inputs.get(name); - if (input) { - this.inputs.delete(name); + public removeIOHandler(name: string): void { + if (this.ioHandlers.has(name)) { + // If it was scheduled as an input, it will no longer be re-scheduled + this.ioHandlers.delete(name); this.logger.info( - "Core.unsubscribeFromInputSource", - `Removed input: ${name}` + "Orchestrator.removeIOHandler", + `Removed IOHandler: ${name}` ); } } /** - * Registers a new output handler with the system. - * @param output The output configuration to register + * Executes a handler with role="output" by name, passing data to it. + * This is effectively "dispatchToOutput." */ - public registerOutput(output: Output): void { - this.logger.info("Core.registerOutput", "Registering output", { - name: output.name, + public async dispatchToOutput(name: string, data: T): Promise { + const handler = this.ioHandlers.get(name); + if (!handler) { + throw new Error(`No IOHandler registered with name: ${name}`); + } + + if (handler.role !== "output") { + throw new Error(`Handler "${name}" is not an output handler`); + } + + this.logger.debug("Orchestrator.dispatchToOutput", "Executing output", { + name, + data, }); - this.outputs.set(output.name, output); - this.processor.registerAvailableOutput(output); - } - /** - * Removes a registered output handler. - * @param name Name of the output to remove - */ - public removeOutputHandler(name: string): void { - if (this.outputs.has(name)) { - this.outputs.delete(name); - this.logger.info("Core.removeOutputHandler", `Removing output: ${name}`); + // Optionally validate data with a schema if you had one + try { + const result = await handler.handler(data); + return result; + } catch (error) { + this.logger.error( + "Orchestrator.dispatchToOutput", + "Handler threw an error", + { + name, + error, + } + ); + throw error; } } /** - * Handles execution of an input when it's scheduled to run. - * @param input The input to handle - * @private + * The method the TaskScheduler calls for each scheduled input. + * We only schedule inputs in the constructor's scheduler. */ - private async processInputTask( - input: Input & { nextRun: number } - ): Promise { - const { name, interval } = input; - + private async processInputTask(handler: IOHandler): Promise { try { - const result = await input.handler(); + const result = await handler.handler(); + if (!result) return; - if (interval && interval > 0) { - input.nextRun = Date.now() + interval; - this.inputScheduler.scheduleTask(input); + if (handler.interval && handler.interval > 0) { + // Create a new handler object with definite nextRun + const scheduledHandler = { + ...handler, + nextRun: Date.now() + handler.interval, + }; + this.inputScheduler.scheduleTask(scheduledHandler); } else { - this.inputs.delete(name); + this.removeIOHandler(handler.name); } - const room = await this.roomManager.ensureRoom(name, "core"); + const room = await this.roomManager.ensureRoom(handler.name, "core"); const items = Array.isArray(result) ? result : [result]; for (const item of items) { const processed = await this.processor.process(item, room); + if (!processed.alreadyProcessed) { + for (const output of processed.suggestedOutputs) { + await this.dispatchToOutput(output.name, output.data); + } + await this.roomManager.addMemory( room.id, JSON.stringify(processed.content), { - source: name, + source: handler.name, type: "input", ...processed.metadata, ...processed.enrichedContext, @@ -144,42 +217,31 @@ export class Orchestrator { } } } catch (error) { - this.logger.error("Core.processInputTask", "Error processing input", { - name, - error, - }); - } - } - - /** - * Executes a registered output handler with the provided data. - * @param name Name of the output to execute - * @param data Data to pass to the output handler - * @returns The result of the output handler - * @template T The type of data the output handler accepts - */ - public async dispatchToOutput(name: string, data: T): Promise { - const output = this.outputs.get(name); - if (!output) { - throw new Error(`No output registered with name: ${name}`); - } - this.logger.debug("Core.dispatchToOutput", "Executing output", { - name, - data, - }); - - try { - return data; - } catch (error) { - return error as T; + this.logger.error( + "Orchestrator.processInputTask", + "Error processing input", + { + name: handler.name, + error: + error instanceof Error + ? { + message: error.message, + stack: error.stack, + name: error.name, + } + : error, + handlerType: handler.role, + interval: handler.interval, + } + ); } } /** - * Stops all scheduled tasks and shuts down the Core system. + * Stops all scheduled tasks and shuts down the orchestrator. */ public stop(): void { this.inputScheduler.stop(); - this.logger.info("Core.stop", "All scheduled inputs stopped."); + this.logger.info("Orchestrator.stop", "All scheduled inputs stopped."); } } diff --git a/packages/core/src/core/processor.ts b/packages/core/src/core/processor.ts index 6e29eeec..92350424 100644 --- a/packages/core/src/core/processor.ts +++ b/packages/core/src/core/processor.ts @@ -6,7 +6,6 @@ import type { VectorDB } from "../types"; import type { Character, EnrichedContent, - Output, ProcessedResult, SearchResult, SuggestedOutput, @@ -16,10 +15,11 @@ import { LogLevel } from "../types"; import { hashString, validateLLMResponseSchema } from "./utils"; import { z } from "zod"; import { zodToJsonSchema } from "zod-to-json-schema"; +import type { IOHandler } from "./orchestrator"; export class Processor { private logger: Logger; - private availableOutputs: Map = new Map(); + private readonly ioHandlers = new Map(); constructor( private vectorDb: VectorDB, @@ -34,8 +34,8 @@ export class Processor { }); } - public registerAvailableOutput(output: Output): void { - this.availableOutputs.set(output.name, output); + public registerIOHandler(handler: IOHandler): void { + this.ioHandlers.set(handler.name, handler); } async process(content: any, room: Room): Promise { @@ -81,13 +81,9 @@ export class Processor { // First, classify the content const contentClassification = await this.classifyContent(content); - console.log("contentClassification", contentClassification); - // Second, enrich content const enrichedContent = await this.enrichContent(content, room, new Date()); - console.log("enrichedContent", enrichedContent); - // Third, determine potential outputs const suggestedOutputs = await this.determinePotentialOutputs( content, @@ -95,14 +91,11 @@ export class Processor { contentClassification ); - console.log("suggestedOutputs", suggestedOutputs); - this.logger.info("Processor.process", "Suggested outputs", { contentId, suggestedOutputs, }); - // Store that we've processed this content await this.markContentAsProcessed(contentId, room); return { @@ -113,7 +106,7 @@ export class Processor { }, enrichedContext: { ...enrichedContent.context, - availableOutputs: Array.from(this.availableOutputs.keys()), + availableOutputs: Array.from(this.ioHandlers.keys()), }, suggestedOutputs, alreadyProcessed: false, @@ -125,7 +118,7 @@ export class Processor { enrichedContent: EnrichedContent, classification: { contentType: string; context: Record } ): Promise[]> { - const availableOutputs = Array.from(this.availableOutputs.entries()); + const availableOutputs = Array.from(this.ioHandlers.entries()); if (availableOutputs.length === 0) return []; @@ -166,6 +159,7 @@ For each appropriate output, provide: 3. A confidence score (0-1) 4. Reasoning for the suggestion +Only return the JSON object, no other text. `; try { @@ -196,23 +190,38 @@ For each appropriate output, provide: contentType: string; context: Record; }> { - const contentStr = - typeof content === "string" ? content : JSON.stringify(content); + const prompt = ` + # Content Classification Task + +## Input Content +"${typeof content === "string" ? content : JSON.stringify(content)}" + +## Classification Requirements +Please analyze the content and determine: - const prompt = `Classify the following content and provide context: +1. Content Type +- Identify if this is data, a message, an event, or another type +- Consider the structure and format +- Consider if you should respond to the content - # Content: "${contentStr}" +2. Processing Requirements +- Determine what kind of processing would be most appropriate +- Consider if any special handling is needed - # Determine - 1. What type of content this is (data, message, event, etc.) - 2. What kind of processing it requires - 3. Any relevant context - +3. Contextual Analysis +- Extract any relevant context that would aid in processing +- Note any patterns or special characteristics + +## Output Format +Provide a structured classification with clear reasoning for each determination. + +Only return the JSON object, no other text. `; - const classification = await validateLLMResponseSchema({ + return await validateLLMResponseSchema({ prompt, - systemPrompt: "You are an expert content classifier.", + systemPrompt: + "You are an expert content classifier with deep experience analyzing and categorizing different types of data. Your role is to carefully examine the provided content and determine its key characteristics.", schema: z.object({ contentType: z.string(), requiresProcessing: z.boolean(), @@ -225,22 +234,6 @@ For each appropriate output, provide: llmClient: this.llmClient, logger: this.logger, }); - - console.log("classification", classification); - - return typeof classification === "string" - ? JSON.parse(this.stripCodeBlock(classification)) - : classification; - } - - private stripCodeBlock(text: string): string { - text = text - .replace(/^```[\w]*\n/, "") - .replace(/\n```$/, "") - .trim(); - - const jsonMatch = text.match(/\{[\s\S]*?\}/); - return jsonMatch ? jsonMatch[0] : text; } private async enrichContent( diff --git a/packages/core/src/core/providers/index.ts b/packages/core/src/core/providers/index.ts index d1f1bc0a..5f359dcc 100644 --- a/packages/core/src/core/providers/index.ts +++ b/packages/core/src/core/providers/index.ts @@ -1,4 +1 @@ -import { fetchGraphQL } from "./api"; -import { executeStarknetTransaction } from "./starknet"; - -export { fetchGraphQL, executeStarknetTransaction }; +export { fetchGraphQL } from "./api"; diff --git a/packages/core/src/core/providers/starknet.ts b/packages/core/src/core/providers/starknet.ts deleted file mode 100644 index ceac1368..00000000 --- a/packages/core/src/core/providers/starknet.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Account, type Call, CallData, RpcProvider } from "starknet"; -import { env } from "../env"; - -/** - * Returns a configured Starknet provider based on environment variables. - */ -export const getStarknetProvider = () => { - return new RpcProvider({ - nodeUrl: env.STARKNET_RPC_URL, - }); -}; - -/** - * Returns an `Account` object for executing transactions on Starknet. - */ -export const getStarknetAccount = () => { - return new Account( - getStarknetProvider(), - env.STARKNET_ADDRESS, - env.STARKNET_PRIVATE_KEY - ); -}; - -/** - * Executes a read (callContract) on Starknet. - */ -export const executeStarknetRead = async (call: Call): Promise => { - try { - call.calldata = CallData.compile(call.calldata || []); - return await getStarknetProvider().callContract(call); - } catch (error) { - return error instanceof Error ? error : new Error("Unknown error occurred"); - } -}; - -/** - * Executes a transaction on Starknet and waits for it to be accepted. - */ -export const executeStarknetTransaction = async (call: Call): Promise => { - try { - call.calldata = CallData.compile(call.calldata || []); - - const account = getStarknetAccount(); - const { transaction_hash } = await account.execute(call); - - return await account.waitForTransaction(transaction_hash, { - retryInterval: 1000, - }); - } catch (error) { - return error instanceof Error ? error : new Error("Unknown error occurred"); - } -}; diff --git a/packages/core/src/core/utils.ts b/packages/core/src/core/utils.ts index d5a01a26..0175d49a 100644 --- a/packages/core/src/core/utils.ts +++ b/packages/core/src/core/utils.ts @@ -144,11 +144,17 @@ export const validateLLMResponseSchema = async ({ ${prompt} - Return a JSON object matching this schema. Do not include any markdown formatting, slashes or comments. + + # rules + - Only include the correct schema nothing else. + - Return a JSON object exactly matching this schema. + - Do not include any markdown formatting, slashes or comments. + - return no tags. + - Only return the JSON object, no other text or other values. + - Never return the schema wrapped in another value like 'outputs' etc. ${JSON.stringify(jsonSchema, null, 2)} - Do not include any markdown formatting, slashes or comments. `; @@ -158,10 +164,7 @@ export const validateLLMResponseSchema = async ({ system: systemPrompt, }); - let responseText = response.toString(); - - // Remove markdown code block formatting if present - responseText = responseText.replace(/```json\n?|\n?```/g, ""); + let responseText = response.toString().replace(/```json\n?|\n?```/g, ""); let parsed: T; try { diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 14def485..d2782b19 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -330,18 +330,6 @@ export interface ThoughtTemplate { description: string; prompt: string; temperature: number; - responseFormat: { - thought: string; - confidence: number; - reasoning: string; - context: Record; - suggestedActions: Array<{ - type: string; - platform?: string; - priority: number; - parameters?: Record; - }>; - }; } /** @@ -523,3 +511,21 @@ export interface DomainMetadata { subDomain?: string; confidence: number; } + +export interface IChain { + /** + * A unique identifier for the chain (e.g., "starknet", "ethereum", "solana", etc.) + */ + chainId: string; + + /** + * Read (call) a contract or perform a query on this chain. + * The `call` parameter can be chain-specific data. + */ + read(call: unknown): Promise; + + /** + * Write (execute a transaction) on this chain, typically requiring signatures, etc. + */ + write(call: unknown): Promise; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a9edb37..332adf56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -187,6 +187,9 @@ importers: '@openrouter/ai-sdk-provider': specifier: ^0.0.6 version: 0.0.6(zod@3.24.1) + '@solana/web3.js': + specifier: ^1.98.0 + version: 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) agent-twitter-client: specifier: ^0.0.16 version: 0.0.16 @@ -196,12 +199,18 @@ importers: ajv: specifier: ^8.17.1 version: 8.17.1 + bs58: + specifier: ^6.0.0 + version: 6.0.0 chromadb: specifier: ^1.9.4 version: 1.10.0(encoding@0.1.13)(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) chromadb-default-embed: specifier: ^2.13.2 version: 2.13.2 + ethers: + specifier: ^6.13.5 + version: 6.13.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) openai: specifier: ^4.76.0 version: 4.78.0(encoding@0.1.13)(zod@3.24.1) @@ -230,6 +239,9 @@ importers: packages: + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@ai-sdk/amazon-bedrock@1.1.1': resolution: {integrity: sha512-HnkOTvKGPoHc/bNiVxE89561pH/wM3/QjVUY7KE4iSfuTsSEuxWTahqqp4v2bNa2UkHGqjUg8AyAaRq2pxyRuw==} engines: {node: '>=18'} @@ -570,6 +582,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.9': resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} @@ -992,12 +1008,19 @@ packages: '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.3.0': resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} '@noble/curves@1.4.2': resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + '@noble/hashes@1.3.3': resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} @@ -1937,9 +1960,19 @@ packages: engines: {node: '>=8.10'} hasBin: true + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/web3.js@1.98.0': + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} + '@starknet-io/types-js@0.7.10': resolution: {integrity: sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==} + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@tufjs/canonical-json@2.0.0': resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} engines: {node: ^16.14.0 || >=18.0.0} @@ -1969,6 +2002,9 @@ packages: '@types/bun@1.2.0': resolution: {integrity: sha512-5N1JqdahfpBlAv4wy6svEYcd/YfO2GNrbL95JOmFx8nkE6dbK4R0oSE5SpBA4vBRqgrOUAXF8Dpiz+gi7r80SA==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/diff-match-patch@1.0.36': resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} @@ -1990,12 +2026,18 @@ packages: '@types/node-fetch@2.6.12': resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.70': resolution: {integrity: sha512-RE+K0+KZoEpDUbGGctnGdkrLFwi1eYKTlIHNl2Um98mUkGsm1u2Ff6Ltd0e8DktTtC98uy7rSj+hO8t/QuLoVQ==} '@types/node@22.10.5': resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2016,12 +2058,18 @@ packages: '@types/three@0.172.0': resolution: {integrity: sha512-LrUtP3FEG26Zg5WiF0nbg8VoXiKokBLTcqM2iLvM9vzcfEiYmmBAPGdBgV0OYx9fvWlY3R/3ERTZcD9X5sc0NA==} + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} '@types/webxr@0.5.21': resolution: {integrity: sha512-geZIAtLzjGmgY2JUi6VxXdCrTb99A7yP49lxLr2Nm/uIK0PkkxcEi4OGhoGDO4pxCf3JwGz2GiJL2Ej4K2bKaA==} + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + '@types/ws@8.5.13': resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} @@ -2150,6 +2198,9 @@ packages: add-stream@1.0.0: resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -2297,12 +2348,22 @@ packages: bare-stream@2.6.1: resolution: {integrity: sha512-eVZbtKM+4uehzrsj49KtCy3Pbg7kO1pJ3SKZ1SFrIH/0pnj9scuGGgUlNDf/7qS8WKtGdiJY5Kyhs/ivYPTB/g==} + base-x@3.0.10: + resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + + base-x@5.0.0: + resolution: {integrity: sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} @@ -2314,9 +2375,18 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} @@ -2335,6 +2405,12 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -2344,6 +2420,13 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + bun-types@1.2.0: resolution: {integrity: sha512-KEaJxyZfbV/c4eyG0vyehDpYmBGreNiQbZIqvVHJwZ4BmeuWlNZ7EAzMN2Zcd7ailmS/tGVW0BgYbGf+lGEpWw==} @@ -2536,6 +2619,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -2680,6 +2766,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2805,6 +2895,12 @@ packages: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -2888,6 +2984,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + ethers@6.13.5: + resolution: {integrity: sha512-+knKNieu5EKRThQJWwqaJ10a6HE9sSehGeqWN65//wE7j47ZpFhKAnHB/JJFibwwg61I/koxaPsXbXpD/skNOQ==} + engines: {node: '>=14.0.0'} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -2895,6 +2995,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventsource-parser@1.1.2: resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==} engines: {node: '>=14.18'} @@ -2925,6 +3028,10 @@ packages: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2941,6 +3048,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + fast-uri@3.0.5: resolution: {integrity: sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==} @@ -2977,6 +3087,9 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -3415,6 +3528,11 @@ packages: isomorphic-fetch@3.0.0: resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -3423,6 +3541,11 @@ packages: engines: {node: '>=10'} hasBin: true + jayson@4.1.3: + resolution: {integrity: sha512-LtXh5aYZodBZ9Fc3j6f2w+MTNcnxteMOrb+QgIouguGOulWi0lieEkOUg+HkjjFs0DGoWDds6bi4E9hpNFLulQ==} + engines: {node: '>=8'} + hasBin: true + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3860,6 +3983,10 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-gyp@10.3.1: resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} engines: {node: ^16.14.0 || >=18.0.0} @@ -4428,6 +4555,9 @@ packages: redeyed@2.1.1: resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -4482,6 +4612,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rpc-websockets@9.0.4: + resolution: {integrity: sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -4711,6 +4844,10 @@ packages: summary@2.1.0: resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==} + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -4765,6 +4902,9 @@ packages: text-decoder@1.2.3: resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + text-extensions@1.9.0: resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} engines: {node: '>=0.10'} @@ -4872,6 +5012,9 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -4956,6 +5099,9 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} @@ -5022,6 +5168,10 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -5029,6 +5179,10 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -5225,6 +5379,30 @@ packages: resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} engines: {node: '>=8'} + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -5280,6 +5458,8 @@ packages: snapshots: + '@adraffy/ens-normalize@1.10.1': {} + '@ai-sdk/amazon-bedrock@1.1.1(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.5 @@ -5895,6 +6075,10 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-plugin-utils': 7.26.5 + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 @@ -6272,6 +6456,10 @@ snapshots: '@emnapi/runtime': 1.3.1 '@tybys/wasm-util': 0.9.0 + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + '@noble/curves@1.3.0': dependencies: '@noble/hashes': 1.3.3 @@ -6280,6 +6468,8 @@ snapshots: dependencies: '@noble/hashes': 1.4.0 + '@noble/hashes@1.3.2': {} + '@noble/hashes@1.3.3': {} '@noble/hashes@1.4.0': {} @@ -7341,8 +7531,38 @@ snapshots: ignore: 5.3.2 p-map: 4.0.0 + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.26.0 + '@noble/curves': 1.4.2 + '@noble/hashes': 1.7.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.6.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + node-fetch: 2.7.0(encoding@0.1.13) + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@starknet-io/types-js@0.7.10': {} + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + '@tufjs/canonical-json@2.0.0': {} '@tufjs/models@2.0.1': @@ -7381,6 +7601,10 @@ snapshots: dependencies: bun-types: 1.2.0 + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.10.5 + '@types/diff-match-patch@1.0.36': {} '@types/estree@1.0.6': {} @@ -7398,6 +7622,8 @@ snapshots: '@types/node': 22.10.5 form-data: 4.0.1 + '@types/node@12.20.55': {} + '@types/node@18.19.70': dependencies: undici-types: 5.26.5 @@ -7406,6 +7632,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + '@types/normalize-package-data@2.4.4': {} '@types/prop-types@15.7.14': {} @@ -7430,10 +7660,16 @@ snapshots: fflate: 0.8.2 meshoptimizer: 0.18.1 + '@types/uuid@8.3.4': {} + '@types/uuid@9.0.8': {} '@types/webxr@0.5.21': {} + '@types/ws@7.4.7': + dependencies: + '@types/node': 22.10.5 + '@types/ws@8.5.13': dependencies: '@types/node': 22.10.5 @@ -7605,6 +7841,8 @@ snapshots: add-stream@1.0.0: {} + aes-js@4.0.0-beta.5: {} + agent-base@7.1.3: {} agent-twitter-client@0.0.16: @@ -7756,10 +7994,20 @@ snapshots: streamx: 2.21.1 optional: true + base-x@3.0.10: + dependencies: + safe-buffer: 5.2.1 + + base-x@5.0.0: {} + base64-js@1.5.1: {} before-after-hook@2.2.3: {} + bigint-buffer@1.1.5: + dependencies: + bindings: 1.5.0 + bignumber.js@9.1.2: {} bin-links@4.0.4: @@ -7771,12 +8019,24 @@ snapshots: binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + bl@4.1.0: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + bn.js@5.2.1: {} + + borsh@0.7.0: + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + bowser@2.11.0: {} brace-expansion@1.1.11: @@ -7799,6 +8059,14 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.2(browserslist@4.24.4) + bs58@4.0.1: + dependencies: + base-x: 3.0.10 + + bs58@6.0.0: + dependencies: + base-x: 5.0.0 + buffer-equal-constant-time@1.0.1: {} buffer-from@1.1.2: {} @@ -7808,6 +8076,16 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + optional: true + bun-types@1.2.0: dependencies: '@types/node': 22.10.5 @@ -8005,6 +8283,8 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@2.20.3: {} + commander@4.1.1: {} common-ancestor-path@1.0.1: {} @@ -8143,6 +8423,8 @@ snapshots: define-lazy-prop@2.0.0: {} + delay@5.0.0: {} + delayed-stream@1.0.0: {} deprecation@2.3.1: {} @@ -8245,6 +8527,12 @@ snapshots: dependencies: es-errors: 1.3.0 + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -8387,10 +8675,25 @@ snapshots: esutils@2.0.3: {} + ethers@6.13.5(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + event-target-shim@5.0.1: {} eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + eventsource-parser@1.1.2: {} eventsource-parser@3.0.0: {} @@ -8421,6 +8724,8 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 + eyes@0.1.8: {} + fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} @@ -8437,6 +8742,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-stable-stringify@1.0.0: {} + fast-uri@3.0.5: {} fast-xml-parser@4.4.1: @@ -8471,6 +8778,8 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} + filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -8925,6 +9234,10 @@ snapshots: transitivePeerDependencies: - encoding + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -8938,6 +9251,24 @@ snapshots: filelist: 1.0.4 minimatch: 3.1.2 + jayson@4.1.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -9457,6 +9788,9 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-gyp-build@4.8.4: + optional: true + node-gyp@10.3.1: dependencies: env-paths: 2.2.1 @@ -10102,6 +10436,8 @@ snapshots: dependencies: esprima: 4.0.1 + regenerator-runtime@0.14.1: {} + require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -10162,6 +10498,19 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.30.1 fsevents: 2.3.3 + rpc-websockets@9.0.4: + dependencies: + '@swc/helpers': 0.5.15 + '@types/uuid': 8.3.4 + '@types/ws': 8.5.13 + buffer: 6.0.3 + eventemitter3: 5.0.1 + uuid: 8.3.2 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + run-async@2.4.1: {} run-parallel@1.2.0: @@ -10408,6 +10757,8 @@ snapshots: summary@2.1.0: {} + superstruct@2.0.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -10499,6 +10850,8 @@ snapshots: dependencies: b4a: 1.6.7 + text-encoding-utf-8@1.0.2: {} + text-extensions@1.9.0: {} thenify-all@1.6.0: @@ -10588,6 +10941,8 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@2.7.0: {} + tslib@2.8.1: {} tsup@8.3.5(jiti@2.4.2)(postcss@8.4.49)(typescript@5.7.3)(yaml@2.7.0): @@ -10666,6 +11021,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@6.19.8: {} + undici-types@6.20.0: {} unique-filename@3.0.0: @@ -10720,10 +11077,17 @@ snapshots: dependencies: react: 19.0.0 + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + optional: true + util-deprecate@1.0.2: {} uuid@10.0.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} validate-npm-package-license@3.0.4: @@ -10900,6 +11264,16 @@ snapshots: type-fest: 0.4.1 write-json-file: 3.2.0 + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + xtend@4.0.2: {} y18n@5.0.8: {}