diff --git a/typescript/agentkit/src/action-providers/index.ts b/typescript/agentkit/src/action-providers/index.ts index 9f7164086..4f8850abc 100644 --- a/typescript/agentkit/src/action-providers/index.ts +++ b/typescript/agentkit/src/action-providers/index.ts @@ -19,6 +19,7 @@ export * from "./erc8004"; export * from "./farcaster"; export * from "./jupiter"; export * from "./messari"; +export * from "./mnemopay"; export * from "./pyth"; export * from "./moonwell"; export * from "./morpho"; diff --git a/typescript/agentkit/src/action-providers/mnemopay/README.md b/typescript/agentkit/src/action-providers/mnemopay/README.md new file mode 100644 index 000000000..452350d5e --- /dev/null +++ b/typescript/agentkit/src/action-providers/mnemopay/README.md @@ -0,0 +1,68 @@ +# MnemoPay Action Provider + +This directory contains the **MnemoPayActionProvider** implementation, which gives AI agents **economic memory** through the [MnemoPay SDK](https://www.npmjs.com/package/@mnemopay/sdk). Agents can remember payment outcomes, learn from settlements and refunds, and build reputation over time. + +## Directory Structure + +``` +mnemopay/ +├── mnemopayActionProvider.ts # Main provider with MnemoPay functionality +├── mnemopayActionProvider.test.ts # Test file for MnemoPay provider +├── schemas.ts # MnemoPay action schemas +├── index.ts # Main exports +└── README.md # This file +``` + +## Actions + +- `remember_outcome` - Store a memory about a payment outcome, provider interaction, or economic event +- `recall_memories` - Recall memories by semantic query, ranked by similarity and importance +- `charge_payment` - Charge a payment and create an escrow +- `settle_payment` - Settle a payment (positive reinforcement: +0.05 reputation) +- `refund_payment` - Refund a payment (negative reinforcement: -0.05 reputation) +- `check_balance` - Check the agent's wallet balance and reputation score +- `agent_profile` - Get the agent's full profile including memory statistics + +## Usage + +```typescript +import { AgentKit } from "@coinbase/agentkit"; +import { mnemoPayActionProvider } from "@coinbase/agentkit"; + +const agentkit = new AgentKit({ + // ... your config + actionProviders: [ + mnemoPayActionProvider({ + agentId: "my-trading-agent", + decayRate: 0.05, + }), + ], +}); +``` + +## Configuration + +| Option | Environment Variable | Default | Description | +|--------|---------------------|---------|-------------| +| `agentId` | `MNEMOPAY_AGENT_ID` | `"default-agent"` | Unique identifier for the agent | +| `decayRate` | `MNEMOPAY_DECAY_RATE` | `0.05` | Memory decay rate (0.0-1.0) | + +## How Economic Memory Works + +1. **Remember**: Agent stores memories about interactions (provider quality, payment outcomes, patterns) +2. **Recall**: Agent queries memories semantically to inform decisions +3. **Charge**: Agent initiates a payment, creating an escrow +4. **Settle**: If the outcome was good, settling reinforces the memories that led to the decision (+0.05 reputation) +5. **Refund**: If the outcome was bad, refunding weakens those memories (-0.05 reputation) + +Over time, the agent builds a reputation score and learns which economic decisions lead to good outcomes. + +## Network Support + +The MnemoPay provider is network-agnostic. It operates at the application layer and works with any blockchain network. + +## Dependencies + +- `@mnemopay/sdk` - The MnemoPay TypeScript SDK + +For more information, visit the [MnemoPay documentation](https://github.com/t49qnsx7qt-kpanks/mnemopay-sdk). diff --git a/typescript/agentkit/src/action-providers/mnemopay/index.ts b/typescript/agentkit/src/action-providers/mnemopay/index.ts new file mode 100644 index 000000000..2351e2d61 --- /dev/null +++ b/typescript/agentkit/src/action-providers/mnemopay/index.ts @@ -0,0 +1,2 @@ +export * from "./mnemopayActionProvider"; +export * from "./schemas"; diff --git a/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.test.ts b/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.test.ts new file mode 100644 index 000000000..50dfc6b88 --- /dev/null +++ b/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.test.ts @@ -0,0 +1,270 @@ +import { MnemoPayActionProvider } from "./mnemopayActionProvider"; + +// Mock the @mnemopay/sdk module +const mockRemember = jest.fn(); +const mockRecall = jest.fn(); +const mockCharge = jest.fn(); +const mockSettle = jest.fn(); +const mockRefund = jest.fn(); +const mockBalance = jest.fn(); +const mockProfile = jest.fn(); + +jest.mock("@mnemopay/sdk", () => ({ + MnemoPayLite: jest.fn().mockImplementation(() => ({ + remember: mockRemember, + recall: mockRecall, + charge: mockCharge, + settle: mockSettle, + refund: mockRefund, + balance: mockBalance, + profile: mockProfile, + })), +})); + +const MOCK_CONFIG = { + agentId: "test-agent", + decayRate: 0.05, +}; + +describe("MnemoPayActionProvider", () => { + let provider: MnemoPayActionProvider; + + beforeEach(() => { + jest.clearAllMocks(); + provider = new MnemoPayActionProvider(MOCK_CONFIG); + }); + + describe("Constructor", () => { + it("should initialize with config values", () => { + expect(() => new MnemoPayActionProvider(MOCK_CONFIG)).not.toThrow(); + }); + + it("should initialize with default values", () => { + expect(() => new MnemoPayActionProvider()).not.toThrow(); + }); + + it("should use environment variables as fallback", () => { + process.env.MNEMOPAY_AGENT_ID = "env-agent"; + process.env.MNEMOPAY_DECAY_RATE = "0.1"; + expect(() => new MnemoPayActionProvider()).not.toThrow(); + delete process.env.MNEMOPAY_AGENT_ID; + delete process.env.MNEMOPAY_DECAY_RATE; + }); + }); + + describe("rememberOutcome", () => { + it("should store a memory successfully", async () => { + mockRemember.mockResolvedValue(undefined); + + const result = await provider.rememberOutcome({ + content: "Provider X delivered quality work", + importance: 0.8, + tags: ["provider", "quality"], + }); + + expect(result).toContain("Successfully stored memory"); + expect(result).toContain("Provider X delivered quality work"); + expect(result).toContain("0.8"); + expect(mockRemember).toHaveBeenCalledWith("Provider X delivered quality work", { + importance: 0.8, + tags: ["provider", "quality"], + }); + }); + + it("should use default importance when not provided", async () => { + mockRemember.mockResolvedValue(undefined); + + const result = await provider.rememberOutcome({ + content: "Some memory", + }); + + expect(result).toContain("0.5"); + expect(mockRemember).toHaveBeenCalledWith("Some memory", { + importance: 0.5, + tags: [], + }); + }); + + it("should handle errors", async () => { + mockRemember.mockRejectedValue(new Error("Storage failed")); + + const result = await provider.rememberOutcome({ + content: "Some memory", + }); + + expect(result).toContain("Error storing memory"); + }); + }); + + describe("recallMemories", () => { + it("should recall memories successfully", async () => { + mockRecall.mockResolvedValue([ + { content: "Provider X is reliable", score: 0.95, tags: ["provider"] }, + { content: "Provider Y is slow", score: 0.72, tags: ["provider", "slow"] }, + ]); + + const result = await provider.recallMemories({ + query: "reliable providers", + limit: 5, + }); + + expect(result).toContain("Recalled 2 memories"); + expect(result).toContain("Provider X is reliable"); + expect(result).toContain("0.950"); + expect(mockRecall).toHaveBeenCalledWith("reliable providers", 5); + }); + + it("should return message when no memories found", async () => { + mockRecall.mockResolvedValue([]); + + const result = await provider.recallMemories({ + query: "nonexistent topic", + }); + + expect(result).toContain("No memories found"); + }); + + it("should handle errors", async () => { + mockRecall.mockRejectedValue(new Error("Recall failed")); + + const result = await provider.recallMemories({ + query: "test", + }); + + expect(result).toContain("Error recalling memories"); + }); + }); + + describe("chargePayment", () => { + it("should charge payment successfully", async () => { + mockCharge.mockResolvedValue("tx-123-abc"); + + const result = await provider.chargePayment({ + amount: 50, + description: "Payment for design work", + }); + + expect(result).toContain("Payment charged successfully"); + expect(result).toContain("tx-123-abc"); + expect(result).toContain("50"); + expect(mockCharge).toHaveBeenCalledWith(50, "Payment for design work"); + }); + + it("should handle errors", async () => { + mockCharge.mockRejectedValue(new Error("Insufficient funds")); + + const result = await provider.chargePayment({ + amount: 50, + description: "Payment", + }); + + expect(result).toContain("Error charging payment"); + }); + }); + + describe("settlePayment", () => { + it("should settle payment successfully", async () => { + mockSettle.mockResolvedValue(undefined); + + const result = await provider.settlePayment({ + transactionId: "tx-123-abc", + }); + + expect(result).toContain("Payment settled successfully"); + expect(result).toContain("tx-123-abc"); + expect(result).toContain("+0.05"); + expect(mockSettle).toHaveBeenCalledWith("tx-123-abc"); + }); + + it("should handle errors", async () => { + mockSettle.mockRejectedValue(new Error("Transaction not found")); + + const result = await provider.settlePayment({ + transactionId: "invalid-tx", + }); + + expect(result).toContain("Error settling payment"); + }); + }); + + describe("refundPayment", () => { + it("should refund payment successfully", async () => { + mockRefund.mockResolvedValue(undefined); + + const result = await provider.refundPayment({ + transactionId: "tx-123-abc", + }); + + expect(result).toContain("Payment refunded successfully"); + expect(result).toContain("tx-123-abc"); + expect(result).toContain("-0.05"); + expect(mockRefund).toHaveBeenCalledWith("tx-123-abc"); + }); + + it("should handle errors", async () => { + mockRefund.mockRejectedValue(new Error("Transaction not found")); + + const result = await provider.refundPayment({ + transactionId: "invalid-tx", + }); + + expect(result).toContain("Error refunding payment"); + }); + }); + + describe("checkBalance", () => { + it("should return balance successfully", async () => { + mockBalance.mockReturnValue({ wallet: 150, reputation: 1.15 }); + + const result = await provider.checkBalance({}); + + expect(result).toContain("Agent Balance"); + expect(result).toContain("150"); + expect(result).toContain("1.15"); + }); + + it("should handle errors", async () => { + mockBalance.mockImplementation(() => { + throw new Error("Balance error"); + }); + + const result = await provider.checkBalance({}); + + expect(result).toContain("Error checking balance"); + }); + }); + + describe("agentProfile", () => { + it("should return profile successfully", async () => { + mockProfile.mockReturnValue({ + agentId: "test-agent", + wallet: 150, + reputation: 1.15, + memoryCount: 42, + }); + + const result = await provider.agentProfile({}); + + expect(result).toContain("Agent Profile"); + expect(result).toContain("test-agent"); + }); + + it("should handle errors", async () => { + mockProfile.mockImplementation(() => { + throw new Error("Profile error"); + }); + + const result = await provider.agentProfile({}); + + expect(result).toContain("Error retrieving agent profile"); + }); + }); + + describe("supportsNetwork", () => { + it("should return true for any network", () => { + const network = { protocolFamily: "evm", networkId: "base-mainnet" }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(provider.supportsNetwork(network as any)).toBe(true); + }); + }); +}); diff --git a/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.ts b/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.ts new file mode 100644 index 000000000..7824fa5e6 --- /dev/null +++ b/typescript/agentkit/src/action-providers/mnemopay/mnemopayActionProvider.ts @@ -0,0 +1,371 @@ +import { z } from "zod"; +import { ActionProvider } from "../actionProvider"; +import { CreateAction } from "../actionDecorator"; +import { Network } from "../../network"; +import { + RememberOutcomeSchema, + RecallMemoriesSchema, + ChargePaymentSchema, + SettlePaymentSchema, + RefundPaymentSchema, + CheckBalanceSchema, + AgentProfileSchema, +} from "./schemas"; + +// eslint-disable-next-line @typescript-eslint/no-require-imports +type MnemoPayLiteType = import("@mnemopay/sdk").MnemoPayLite; + +/** + * Configuration options for the MnemoPayActionProvider. + */ +export interface MnemoPayActionProviderConfig { + /** + * Unique identifier for the agent. + */ + agentId?: string; + + /** + * Memory decay rate (0.0 to 1.0). Controls how fast old memories fade. + * Lower values = slower decay. Default: 0.05 + */ + decayRate?: number; +} + +/** + * MnemoPayActionProvider gives AI agents economic memory through the MnemoPay SDK. + * + * Agents can remember payment outcomes, learn from settlements and refunds, + * and build reputation over time. This enables agents to make better economic + * decisions based on past interactions. + * + * @augments ActionProvider + */ +export class MnemoPayActionProvider extends ActionProvider { + private agent: MnemoPayLiteType | null = null; + private config: MnemoPayActionProviderConfig; + + /** + * Constructor for the MnemoPayActionProvider class. + * + * @param config - The configuration options for the MnemoPayActionProvider + */ + constructor(config: MnemoPayActionProviderConfig = {}) { + super("mnemopay", []); + + this.config = { ...config }; + this.config.agentId ||= process.env.MNEMOPAY_AGENT_ID || "default-agent"; + this.config.decayRate ??= Number(process.env.MNEMOPAY_DECAY_RATE) || 0.05; + } + + /** + * Store a memory about a payment outcome, provider interaction, or any economic event. + * Memories are scored by importance and can be tagged for categorization. + * Over time, memories decay unless reinforced by settlements. + * + * @param args - The memory content, importance, and optional tags + * @returns A confirmation message with the stored memory details + */ + @CreateAction({ + name: "remember_outcome", + description: ` +This tool stores a memory about a payment outcome, provider interaction, or any economic event. +Memories are scored by importance (0.0-1.0) and can be tagged for categorization. +Over time, memories naturally decay unless reinforced by successful payment settlements. + +Use this to record: +- Quality of work from a provider ("Provider X delivered excellent design work") +- Payment outcomes ("Payment to Y was disputed due to late delivery") +- Economic patterns ("Service prices tend to be lower on weekends") + +It takes the following inputs: +- content: The memory content to store (required) +- importance: Importance score from 0.0 to 1.0 (optional, default 0.5) +- tags: Array of categorization tags (optional)`, + schema: RememberOutcomeSchema, + }) + async rememberOutcome(args: z.infer): Promise { + try { + const client = await this.getClient(); + await client.remember(args.content, { + importance: args.importance ?? 0.5, + tags: args.tags ?? [], + }); + return [ + "Successfully stored memory:", + `- Content: ${args.content}`, + `- Importance: ${args.importance ?? 0.5}`, + `- Tags: ${(args.tags ?? []).join(", ") || "none"}`, + ].join("\n"); + } catch (error) { + return `Error storing memory: ${error}`; + } + } + + /** + * Recall memories by semantic query. Returns the most relevant memories + * ranked by a combination of semantic similarity and importance score. + * + * @param args - The semantic query and optional result limit + * @returns A formatted list of recalled memories with scores + */ + @CreateAction({ + name: "recall_memories", + description: ` +This tool recalls memories by semantic query, returning the most relevant memories +ranked by a combination of semantic similarity and importance score. + +Use this to: +- Find reliable providers ("good providers for design work") +- Check payment history ("past payments over $100") +- Review interaction patterns ("providers who delivered late") + +It takes the following inputs: +- query: Semantic search query (required) +- limit: Maximum number of results to return (optional, default 5, max 50)`, + schema: RecallMemoriesSchema, + }) + async recallMemories(args: z.infer): Promise { + try { + const client = await this.getClient(); + const memories = await client.recall(args.query, args.limit ?? 5); + + if (!memories || memories.length === 0) { + return "No memories found matching the query."; + } + + const formatted = memories.map( + (m: { content: string; score: number; tags?: string[] }, i: number) => + [ + `${i + 1}. [Score: ${m.score.toFixed(3)}] ${m.content}`, + m.tags && m.tags.length > 0 ? ` Tags: ${m.tags.join(", ")}` : null, + ] + .filter(Boolean) + .join("\n"), + ); + + return [`Recalled ${memories.length} memories for "${args.query}":`, ...formatted].join("\n"); + } catch (error) { + return `Error recalling memories: ${error}`; + } + } + + /** + * Charge a payment, creating an escrow. The payment is held until settled or refunded. + * This is the starting point for any economic transaction. + * + * @param args - The amount and description for the payment + * @returns The transaction ID and payment details + */ + @CreateAction({ + name: "charge_payment", + description: ` +This tool charges a payment and creates an escrow. The payment is held until explicitly +settled (releasing funds and reinforcing positive memories) or refunded (returning funds +and docking reputation). + +Use this when the agent needs to: +- Pay for a service or task +- Create an escrow for a new transaction +- Initiate a payment that will later be settled or refunded + +It takes the following inputs: +- amount: The payment amount in agent currency units (required, must be positive) +- description: What the payment is for (required) + +Returns a transaction ID that must be used with settle_payment or refund_payment.`, + schema: ChargePaymentSchema, + }) + async chargePayment(args: z.infer): Promise { + try { + const client = await this.getClient(); + const transactionId = await client.charge(args.amount, args.description); + return [ + "Payment charged successfully:", + `- Transaction ID: ${transactionId}`, + `- Amount: ${args.amount}`, + `- Description: ${args.description}`, + "", + "Use settle_payment or refund_payment with this transaction ID to complete the flow.", + ].join("\n"); + } catch (error) { + return `Error charging payment: ${error}`; + } + } + + /** + * Settle a payment, releasing the escrow. This positively reinforces the memories + * that led to the payment decision, increasing the agent's confidence in similar + * future decisions. + * + * @param args - The transaction ID to settle + * @returns Confirmation of settlement + */ + @CreateAction({ + name: "settle_payment", + description: ` +This tool settles a previously charged payment, releasing the escrow funds. +Settlement positively reinforces (+0.05) the memories that led to this payment decision, +helping the agent learn which providers and decisions lead to good outcomes. + +Use this when: +- Work was delivered satisfactorily +- A service was completed as expected +- The agent wants to reinforce positive economic patterns + +It takes the following inputs: +- transactionId: The transaction ID from charge_payment (required)`, + schema: SettlePaymentSchema, + }) + async settlePayment(args: z.infer): Promise { + try { + const client = await this.getClient(); + await client.settle(args.transactionId); + return [ + "Payment settled successfully:", + `- Transaction ID: ${args.transactionId}`, + "- Reputation: +0.05 (positive reinforcement applied)", + "- Related memories have been strengthened.", + ].join("\n"); + } catch (error) { + return `Error settling payment: ${error}`; + } + } + + /** + * Refund a payment, returning the escrowed funds. This negatively reinforces the + * memories that led to the payment decision, helping the agent avoid similar + * mistakes in the future. + * + * @param args - The transaction ID to refund + * @returns Confirmation of refund + */ + @CreateAction({ + name: "refund_payment", + description: ` +This tool refunds a previously charged payment, returning the escrowed funds. +Refunding negatively reinforces (-0.05) the memories that led to this payment decision, +helping the agent learn which providers and decisions lead to poor outcomes. + +Use this when: +- Work was not delivered or was unsatisfactory +- A service failed to meet expectations +- The agent wants to penalize negative economic patterns + +It takes the following inputs: +- transactionId: The transaction ID from charge_payment (required)`, + schema: RefundPaymentSchema, + }) + async refundPayment(args: z.infer): Promise { + try { + const client = await this.getClient(); + await client.refund(args.transactionId); + return [ + "Payment refunded successfully:", + `- Transaction ID: ${args.transactionId}`, + "- Reputation: -0.05 (negative reinforcement applied)", + "- Related memories have been weakened.", + ].join("\n"); + } catch (error) { + return `Error refunding payment: ${error}`; + } + } + + /** + * Check the agent's current wallet balance and reputation score. + * + * @param _ - Empty parameter object (not used) + * @returns The agent's balance and reputation details + */ + @CreateAction({ + name: "check_balance", + description: ` +This tool returns the agent's current wallet balance and reputation score. + +The reputation score reflects the agent's economic track record: +- Starts at 1.0 +- Increases with successful settlements (+0.05 each) +- Decreases with refunds (-0.05 each) +- Higher reputation = more trustworthy economic decisions`, + schema: CheckBalanceSchema, + }) + async checkBalance(_: z.infer): Promise { + try { + const client = await this.getClient(); + const balance = client.balance(); + return [ + "Agent Balance:", + `- Wallet: ${balance.wallet}`, + `- Reputation: ${balance.reputation}`, + ].join("\n"); + } catch (error) { + return `Error checking balance: ${error}`; + } + } + + /** + * Get the agent's full profile including memory statistics, balance, and reputation. + * + * @param _ - Empty parameter object (not used) + * @returns The agent's complete profile + */ + @CreateAction({ + name: "agent_profile", + description: ` +This tool returns the agent's full profile, including: +- Agent ID and configuration +- Wallet balance and reputation score +- Memory statistics (total memories, decay rate) +- Economic activity summary + +Use this for a comprehensive overview of the agent's economic state.`, + schema: AgentProfileSchema, + }) + async agentProfile(_: z.infer): Promise { + try { + const client = await this.getClient(); + const profile = client.profile(); + return [ + "Agent Profile:", + `${JSON.stringify(profile, null, 2)}`, + ].join("\n"); + } catch (error) { + return `Error retrieving agent profile: ${error}`; + } + } + + /** + * Checks if the MnemoPay action provider supports the given network. + * MnemoPay operates at the application layer and is network-agnostic. + * + * @param _ - The network to check (not used) + * @returns Always returns true as MnemoPay is network-independent + */ + supportsNetwork(_: Network): boolean { + return true; + } + + /** + * Get the MnemoPay client, initializing it if needed. + * + * @returns The MnemoPayLite instance + */ + private async getClient(): Promise { + if (!this.agent) { + const { MnemoPayLite } = await import("@mnemopay/sdk"); + this.agent = new MnemoPayLite( + this.config.agentId!, + this.config.decayRate!, + ); + } + return this.agent; + } +} + +/** + * Factory function to create a new MnemoPayActionProvider instance. + * + * @param config - The configuration options for the MnemoPayActionProvider + * @returns A new instance of MnemoPayActionProvider + */ +export const mnemoPayActionProvider = (config: MnemoPayActionProviderConfig = {}) => + new MnemoPayActionProvider(config); diff --git a/typescript/agentkit/src/action-providers/mnemopay/schemas.ts b/typescript/agentkit/src/action-providers/mnemopay/schemas.ts new file mode 100644 index 000000000..1e8e99b7f --- /dev/null +++ b/typescript/agentkit/src/action-providers/mnemopay/schemas.ts @@ -0,0 +1,96 @@ +import { z } from "zod"; + +/** + * Input schema for storing a memory about a payment outcome or interaction. + */ +export const RememberOutcomeSchema = z + .object({ + content: z + .string() + .min(1, "Memory content is required.") + .describe("The memory content to store (e.g. 'Provider X delivered high-quality work on time')"), + importance: z + .number() + .min(0) + .max(1) + .optional() + .describe("Importance score from 0.0 to 1.0 (default: 0.5)"), + tags: z + .array(z.string()) + .optional() + .describe("Optional tags to categorize the memory (e.g. ['provider', 'quality', 'fast'])"), + }) + .describe("Input schema for storing a memory about a payment outcome or interaction"); + +/** + * Input schema for recalling memories by semantic query. + */ +export const RecallMemoriesSchema = z + .object({ + query: z + .string() + .min(1, "Query is required.") + .describe("Semantic query to search memories (e.g. 'reliable providers for design work')"), + limit: z + .number() + .int() + .min(1) + .max(50) + .optional() + .describe("Maximum number of memories to return (default: 5)"), + }) + .describe("Input schema for recalling memories by semantic query"); + +/** + * Input schema for charging a payment (creating an escrow). + */ +export const ChargePaymentSchema = z + .object({ + amount: z + .number() + .positive("Amount must be positive.") + .describe("The amount to charge in the agent's currency units"), + description: z + .string() + .min(1, "Payment description is required.") + .describe("Description of what the payment is for (e.g. 'Payment for logo design task')"), + }) + .describe("Input schema for charging a payment and creating an escrow"); + +/** + * Input schema for settling a payment (releasing escrow, positive reinforcement). + */ +export const SettlePaymentSchema = z + .object({ + transactionId: z + .string() + .min(1, "Transaction ID is required.") + .describe("The transaction ID returned from charge_payment to settle"), + }) + .describe("Input schema for settling a payment and reinforcing positive memories"); + +/** + * Input schema for refunding a payment (negative reinforcement). + */ +export const RefundPaymentSchema = z + .object({ + transactionId: z + .string() + .min(1, "Transaction ID is required.") + .describe("The transaction ID returned from charge_payment to refund"), + }) + .describe("Input schema for refunding a payment and docking reputation"); + +/** + * Input schema for checking the agent's balance and reputation. + */ +export const CheckBalanceSchema = z + .object({}) + .describe("Input schema for checking the agent's wallet balance and reputation score"); + +/** + * Input schema for retrieving the agent's full profile. + */ +export const AgentProfileSchema = z + .object({}) + .describe("Input schema for retrieving the agent's full profile including memory stats");