UNPKG

wowok_agent

Version:

Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.

447 lines (446 loc) 28.8 kB
import { z } from "zod"; import { NameOrAddressSchema, EntrypointSchema, AccountOrMark_AddressAISchema, ManyAccountOrMark_AddressAISchema } from "../common/index.js"; export const MessageStatusSchema = z.enum(["pending", "confirmed", "read", "failed", "rejected", "decrypted", "decrypt_failed"]); export const MessageDirectionSchema = z.enum(["sent", "received"]); export const MessageTypeSchema = z.union([z.literal(1), z.literal(3)]); export const MessageContentTypeSchema = z.enum(["text", "zip", "wts", "wip"]); export const MessageTimeFieldSchema = z.enum(["createdAt", "receivedAt", "serverTimestamp"]); export const RangeTypeSchema = z.enum(["time", "messageId", "seqIndex"]); export const ZipMetadataSchema = z.object({ fileName: z.string().describe("ZIP filename"), fileSize: z.number().describe("File size in bytes"), fileHash: z.string().describe("File SHA256 hash"), contentType: MessageContentTypeSchema.describe("Content type"), localCachePath: z.string().optional().describe("Local cache path"), downloadedAt: z.number().optional().describe("Download timestamp"), }).describe("ZIP file metadata"); export const MessageSchema = z.object({ messageId: z.string().describe("Message ID"), fromAddress: z.string().describe("Sender address"), toAddress: z.string().describe("Recipient address"), plaintextHash: z.string().describe("Plaintext hash"), plaintext: z.string().optional().describe("Decrypted plaintext (optional)"), guardAddress: z.string().optional().describe("Guard address"), passportAddress: z.string().optional().describe("Passport address"), lastReceivedLeafIndex: z.number().optional().describe("Last received leaf index"), direction: MessageDirectionSchema.describe("Message direction"), status: MessageStatusSchema.describe("Message status"), msgType: MessageTypeSchema.describe("Message type"), leafIndex: z.number().optional().describe("Leaf index"), prevRoot: z.string().optional().describe("Previous Merkle Root"), newRoot: z.string().optional().describe("Current Merkle Root"), serverSignature: z.string().optional().describe("Server signature"), serverTimestamp: z.number().optional().describe("Server confirmation timestamp"), serverPublicKey: z.string().optional().describe("Server public key"), arkConfirmed: z.object({ recipient: z.string().describe("Recipient address"), recipientPublicKey: z.string().describe("Recipient public key"), signature: z.string().describe("Recipient signature"), timestamp: z.number().describe("ARK confirmation time"), }).optional().describe("ARK confirmation"), createdAt: z.number().describe("Message creation time (client)"), receivedAt: z.number().optional().describe("Local reception time"), zipMetadata: ZipMetadataSchema.optional().describe("ZIP file metadata"), proof: z.string().optional().describe("On-chain proof object address"), decryptError: z.string().optional().describe("Decryption failure reason"), decryptAttempts: z.number().optional().describe("Number of decryption attempts"), lastDecryptAttemptAt: z.number().optional().describe("Last decryption attempt timestamp"), viewedAt: z.number().optional().describe("Timestamp when the current user viewed this message (local storage). If present, indicates the message has been viewed by the user. Only applicable to received messages (direction === 'received')"), }).describe("Message object"); export const ConversationInfoSchema = z.object({ peerAddress: z.string().describe("Peer address"), lastMessageAt: z.number().describe("Last message time"), messageCount: z.number().describe("Total message count"), unreadCount: z.number().describe("Unread message count - count of received messages that have not been viewed (viewedAt is undefined)"), lastMessagePreview: z.string().optional().describe("Last message preview text"), previewMessages: z.array(MessageSchema).optional().describe("Preview messages for this conversation (default 2 messages, sorted by time descending)"), }).describe("Conversation info with unread count and preview messages"); export const ConversationsFilterSchema = z.object({ account: z.string().optional().describe("Account name or address to query conversations for. If not specified, uses default account"), unreadOnly: z.boolean().optional().describe("If true, only return conversations with unread messages (unreadCount > 0). Useful for quickly finding conversations needing attention"), startTime: z.number().optional().describe("Start timestamp (ms) for filtering conversations by lastMessageAt. Only returns conversations where lastMessageAt >= this value"), endTime: z.number().optional().describe("End timestamp (ms) for filtering conversations by lastMessageAt. Only returns conversations where lastMessageAt <= this value"), previewMessageCount: z.number().optional().describe("Number of preview messages to include for each conversation (default: 2). Set to 0 to disable preview messages. If > 0, preview messages are automatically included"), sortBy: z.enum(["lastMessageAt", "unreadCount", "messageCount"]).optional().describe("Sort conversations by: 'lastMessageAt' = most recent activity first, 'unreadCount' = most unread messages first, 'messageCount' = most total messages first"), sortOrder: z.enum(["asc", "desc"]).optional().describe("Sort order: 'asc' = ascending (oldest/smallest first), 'desc' = descending (newest/largest first). Default is 'desc' for time-based sorting"), skipAutoMarkViewed: z.boolean().optional().describe("If true, preview messages will NOT be automatically marked as viewed when retrieved. Default is false, meaning preview messages are auto-marked as viewed"), }).describe("Conversations filter options - use unreadOnly to quickly find active conversations, and previewMessageCount to control how many recent messages are included"); export const MessageFilterSchema = z.object({ account: z.string().optional().describe("Account to filter messages for"), direction: MessageDirectionSchema.optional().describe("Filter by message direction"), status: MessageStatusSchema.optional().describe("Filter by message status"), peerAddress: AccountOrMark_AddressAISchema.optional().describe("Filter by peer address - can be a string (name/address) or full object"), msgType: MessageTypeSchema.optional().describe("Filter by message type"), contentType: MessageContentTypeSchema.optional().describe("Filter by content type"), decryptedOnly: z.boolean().optional().describe("Only return decrypted messages"), confirmedOnly: z.boolean().optional().describe("Only return confirmed messages"), keyword: z.string().optional().describe("Search keyword in plaintext"), sortOrder: z.enum(["asc", "desc"]).optional().describe("Sort order: asc or desc"), limit: z.number().optional().describe("Return limit"), offset: z.number().optional().describe("Pagination offset"), timeField: MessageTimeFieldSchema.optional().describe("Time field for time filtering"), startTime: z.number().optional().describe("Start timestamp (ms)"), endTime: z.number().optional().describe("End timestamp (ms)"), createdAtStart: z.number().optional().describe("Created at start time"), createdAtEnd: z.number().optional().describe("Created at end time"), receivedAtStart: z.number().optional().describe("Received at start time"), receivedAtEnd: z.number().optional().describe("Received at end time"), serverTimestampStart: z.number().optional().describe("Server timestamp start time"), serverTimestampEnd: z.number().optional().describe("Server timestamp end time"), arkConfirmedOnly: z.boolean().optional().describe("Only return ARK confirmed messages"), arkTimestampStart: z.number().optional().describe("ARK timestamp start"), arkTimestampEnd: z.number().optional().describe("ARK timestamp end"), proofedOnly: z.boolean().optional().describe("Only return messages with proof"), hasLastReceivedIndexOnly: z.boolean().optional().describe("Only return messages with lastReceivedLeafIndex"), lastReceivedIndexMin: z.number().optional().describe("Min lastReceivedLeafIndex"), lastReceivedIndexMax: z.number().optional().describe("Max lastReceivedLeafIndex"), listFilterMode: z.enum(["friends", "guard", "stranger", "any"]).optional().describe("List filter mode: 'friends' = only messages from friends list, 'guard' = only messages from Guard list, 'stranger' = only messages from strangers (not in friends/guard lists), 'any' = no filtering (default)"), customListFilter: z.object({ includeAddresses: z.array(z.string()).optional().describe("Include addresses - only return messages from these addresses (highest priority)"), excludeAddresses: z.array(z.string()).optional().describe("Exclude addresses - exclude messages from these addresses"), relation: z.enum(["union", "intersection"]).optional().describe("Address list relation: 'union' = combine lists as union, 'intersection' = combine lists as intersection"), }).optional().describe("Custom list filter for advanced address-based filtering, works in combination with listFilterMode"), viewed: z.boolean().optional().describe("Filter by viewed status: true = only viewed messages, false = only unviewed messages. A message is considered 'viewed' if viewedAt field exists. Only applicable to received messages"), viewedAtStart: z.number().optional().describe("Filter by viewed timestamp start (inclusive). Only returns messages where viewedAt >= this value. Useful for finding recently viewed messages"), viewedAtEnd: z.number().optional().describe("Filter by viewed timestamp end (inclusive). Only returns messages where viewedAt <= this value. Useful for finding messages viewed before a certain time"), skipAutoMarkViewed: z.boolean().optional().describe("If true, messages returned by this query will NOT be automatically marked as viewed. Default is false, meaning messages are auto-marked as viewed when retrieved through watch_messages"), }).describe("Message filter options - all conditions are optional and combined with AND logic. Use viewed field to filter by read/unread status, and viewedAtStart/viewedAtEnd to filter by when messages were viewed"); export const SendMessageOptionsSchema = z.object({ guardAddress: NameOrAddressSchema.optional().describe("Guard address"), passportAddress: NameOrAddressSchema.optional().describe("Passport address"), force: z.boolean().optional().describe("Force send even if there are pending Guard messages"), new_messenger_name: z.string().optional().describe("New messenger name for recipient"), }).describe("Send message options"); export const SendFileOptionsSchema = z.object({ fileName: z.string().optional().describe("Custom file name"), contentType: z.enum(["wts", "wip", "zip"]).optional().describe("Content type hint"), guardAddress: NameOrAddressSchema.optional().describe("Guard address"), passportAddress: NameOrAddressSchema.optional().describe("Passport address"), force: z.boolean().optional().describe("Force send even if there are pending Guard messages"), new_messenger_name: z.string().optional().describe("New messenger name for recipient"), }).describe("Send file options"); export const SendMessageResultSchema = z.object({ messageId: z.string().describe("Message ID"), status: MessageStatusSchema.describe("Message status"), merkleData: z.object({ leafIndex: z.number().describe("Leaf index"), prevRoot: z.string().describe("Previous Merkle Root"), newRoot: z.string().describe("Current Merkle Root"), serverSignature: z.string().describe("Server signature"), serverTimestamp: z.number().describe("Server confirmation timestamp"), serverPublicKey: z.string().describe("Server public key"), }).optional().describe("Merkle Tree proof data"), guardList: z.array(z.string()).optional().describe("Guard list (only returned on error)"), lastReceivedLeafIndex: z.number().optional().describe("Last received leaf index (for message confirmation)"), }).describe("Send message result"); const BaseRangeSchema = z.object({ type: RangeTypeSchema.describe("Range type"), start: z.union([z.number(), z.string()]).describe("Start value"), end: z.union([z.number(), z.string()]).describe("End value"), }); export const TimeRangeSchema = BaseRangeSchema.extend({ type: z.literal("time"), start: z.number(), end: z.number(), }); export const MessageIdRangeSchema = BaseRangeSchema.extend({ type: z.literal("messageId"), start: z.string(), end: z.string(), }); export const SeqIndexRangeSchema = BaseRangeSchema.extend({ type: z.literal("seqIndex"), start: z.number(), end: z.number(), }); export const WtsRangeSchema = z.discriminatedUnion("type", [ TimeRangeSchema, MessageIdRangeSchema, SeqIndexRangeSchema, ]).describe("WTS range filter parameters"); export const WtsGenerationParamsSchema = z.object({ myAccount: NameOrAddressSchema.describe("My account name or address (string)"), peerAccount: AccountOrMark_AddressAISchema.describe("Peer account name or address - can be a string (name/address) or full object"), range: WtsRangeSchema.optional().describe("Range filter parameters"), excludePlaintext: z.boolean().optional().describe("Whether to exclude plaintext"), outputDir: z.string().describe("Output directory path"), }).describe("WTS generation parameters"); export const WtsFileResultSchema = z.object({ files: z.array(z.string()).describe("Generated WTS file paths"), totalMessageCount: z.number().describe("Total message count"), timeRange: z.object({ start: z.number().describe("Start time"), end: z.number().describe("End time"), }).describe("Time range"), }).describe("WTS file result"); export const WtsSignatureVerificationSchema = z.object({ publicKey: z.string().describe("Signer public key"), address: z.string().optional().describe("Signer address"), valid: z.boolean().describe("Whether signature is valid"), }).describe("WTS signature verification details"); export const WtsVerificationResultSchema = z.object({ valid: z.boolean().describe("Whether verification succeeded"), error: z.string().optional().describe("Error message if verification failed"), hashValid: z.boolean().optional().describe("Whether hash validation passed"), hasSignature: z.boolean().optional().describe("Whether WTS has signatures"), signatureValid: z.boolean().optional().describe("Whether signature validation passed"), signatures: z.array(WtsSignatureVerificationSchema).optional().describe("Signature verification details"), }).describe("WTS verification result"); export const WtsToHtmlOptionsSchema = z.object({ title: z.string().optional().describe("HTML document title"), theme: z.enum(["light", "dark"]).optional().describe("HTML theme"), outputPath: z.string().optional().describe("Output file path"), }).describe("WTS to HTML conversion options"); export const AddressExistenceSchema = z.object({ address: z.string().describe("Address"), exists: z.boolean().describe("Whether address exists in list"), }).describe("Address existence check result"); export const GuardListItemSchema = z.object({ guardAddress: z.string().describe("Guard address"), passportValiditySeconds: z.number().describe("Passport validity in seconds"), }).describe("Guard list item"); export const ListOperationResponseSchema = z.object({ success: z.boolean().describe("Whether operation succeeded"), operation: z.string().describe("Operation performed"), modifiedCount: z.number().describe("Number of items modified"), currentCount: z.number().describe("Current list size"), maxCount: z.number().describe("Maximum list size"), invalidAddresses: z.array(z.string()).optional().nullable().describe("Invalid addresses"), existResults: z.array(AddressExistenceSchema).optional().nullable().describe("Existence check results"), message: z.string().optional().nullable().describe("Operation message"), currentList: z.array(z.string()).optional().nullable().describe("Current list content"), currentGuardList: z.array(GuardListItemSchema).optional().nullable().describe("Current guard list content"), }).describe("List operation response"); export const BlacklistOperationSchema = z.discriminatedUnion("op", [ z.object({ op: z.literal("add"), users: ManyAccountOrMark_AddressAISchema.describe("Users to add to blacklist - can be array of strings (names/addresses) or full object"), }), z.object({ op: z.literal("remove"), users: ManyAccountOrMark_AddressAISchema.describe("Users to remove from blacklist - can be array of strings (names/addresses) or full object"), }), z.object({ op: z.literal("clear"), }), z.object({ op: z.literal("get"), }), z.object({ op: z.literal("exist"), users: ManyAccountOrMark_AddressAISchema.describe("Users to check existence - can be array of strings (names/addresses) or full object"), }), ]).describe("Blacklist management operation"); export const FriendslistOperationSchema = z.discriminatedUnion("op", [ z.object({ op: z.literal("add"), users: ManyAccountOrMark_AddressAISchema.describe("Users to add to friends list - can be array of strings (names/addresses) or full object"), }), z.object({ op: z.literal("remove"), users: ManyAccountOrMark_AddressAISchema.describe("Users to remove from friends list - can be array of strings (names/addresses) or full object"), }), z.object({ op: z.literal("clear"), }), z.object({ op: z.literal("get"), }), z.object({ op: z.literal("exist"), users: ManyAccountOrMark_AddressAISchema.describe("Users to check existence - can be array of strings (names/addresses) or full object"), }), ]).describe("Friends list management operation"); export const GuardParamSchema = z.object({ guard: NameOrAddressSchema.describe("Guard address or name"), passportValiditySeconds: z.number().min(10).max(315360000).describe("Passport validity in seconds (10s to 10 years)"), }).describe("Guard parameter"); export const GuardlistOperationSchema = z.discriminatedUnion("op", [ z.object({ op: z.literal("add"), guards: z.array(GuardParamSchema).min(1).max(10).describe("Guards to add to guard list"), }), z.object({ op: z.literal("remove"), guards: z.array(NameOrAddressSchema).min(1).max(10).describe("Guard addresses to remove from guard list"), }), z.object({ op: z.literal("get"), }), ]).describe("Guard list management operation"); export const SettingsOperationSchema = z.discriminatedUnion("op", [ z.object({ op: z.literal("get"), }), z.object({ op: z.literal("set"), allowStrangerMessages: z.boolean().optional().describe("Allow messages from strangers"), maxInboxSize: z.number().min(1).optional().describe("Maximum inbox size"), }), ]).describe("Settings management operation"); export const GetSettingsResponseSchema = z.object({ allowStrangerMessages: z.boolean().optional().describe("Whether messages from strangers are allowed"), maxInboxSize: z.number().optional().describe("Current maximum inbox size"), minUserInboxSize: z.number().describe("Server minimum allowed inbox size limit"), maxUserInboxSize: z.number().describe("Server maximum allowed inbox size limit"), defaultAllowStrangerMessages: z.boolean().describe("Server default setting for allowing stranger messages"), }).describe("Get settings response"); export const MessengerOperationInputSchema = z.discriminatedUnion("operation", [ z.object({ operation: z.literal("watch_conversations"), filter: ConversationsFilterSchema.optional().describe("Conversations filter options - use unreadOnly to find conversations with unread messages, previewMessageCount to control message previews (default 2), and sortBy/sortOrder to customize sorting"), }), z.object({ operation: z.literal("send_message"), from: NameOrAddressSchema.optional().describe("Sender account name or address. If not specified, uses default account"), to: AccountOrMark_AddressAISchema.describe("Recipient address or account name - can be a string (name/address) or full object"), content: z.string().max(10000).describe("Message content text"), options: SendMessageOptionsSchema.optional().describe("Optional message settings"), }), z.object({ operation: z.literal("send_file"), from: NameOrAddressSchema.optional().describe("Sender account name or address. If not specified, uses default account"), to: AccountOrMark_AddressAISchema.describe("Recipient address or account name - can be a string (name/address) or full object"), filePath: z.string().describe("Local file path to send. File will be compressed as ZIP before sending"), options: SendFileOptionsSchema.optional().describe("Optional file sending settings"), }), z.object({ operation: z.literal("watch_messages"), filter: MessageFilterSchema.optional().describe("Message filter options"), }), z.object({ operation: z.literal("extract_zip_messages"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), messages: z.array(z.union([z.string(), MessageSchema])).describe("Array of message objects or message IDs to extract"), outputDir: z.string().describe("Output directory path for extracted files"), }), z.object({ operation: z.literal("generate_wts"), params: WtsGenerationParamsSchema.describe("WTS generation parameters"), }), z.object({ operation: z.literal("verify_wts"), wtsFilePath: z.string().describe("WTS file path to verify"), }), z.object({ operation: z.literal("sign_wts"), wtsFilePath: z.string().describe("WTS file path to sign"), account: NameOrAddressSchema.optional().describe("Account name or address to sign with. If not specified, uses default account"), outputPath: z.string().optional().describe("Output file path. If not specified, saves to signed_*.wts"), }), z.object({ operation: z.literal("wts2html"), wtsPath: z.string().describe("WTS file path or directory to convert"), options: WtsToHtmlOptionsSchema.optional().describe("Conversion options"), }), z.object({ operation: z.literal("proof_message"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), messageId: z.string().describe("Message ID to proof on-chain"), network: EntrypointSchema.optional().describe("Network to use for on-chain proof"), }), z.object({ operation: z.literal("blacklist"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), blacklist: BlacklistOperationSchema.describe("Blacklist management operation"), }), z.object({ operation: z.literal("friendslist"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), friendslist: FriendslistOperationSchema.describe("Friends list management operation"), }), z.object({ operation: z.literal("guardlist"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), guardlist: GuardlistOperationSchema.describe("Guard list management operation"), }), z.object({ operation: z.literal("settings"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), settings: SettingsOperationSchema.describe("Settings management operation"), }), z.object({ operation: z.literal("mark_messages_as_viewed"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), messageIds: z.array(z.string()).min(1).max(1000).describe("Array of message IDs to mark as viewed (1-1000 messages). Only messages belonging to this account will be marked"), }), z.object({ operation: z.literal("mark_conversation_as_viewed"), account: NameOrAddressSchema.optional().describe("Account name or address. If not specified, uses default account"), peerAddress: AccountOrMark_AddressAISchema.describe("Peer address or account name - can be a string (name/address) or full object. All unviewed received messages from this peer will be marked as viewed"), }), ]).describe("Messenger operation input schema"); export const MessengerOperationOutputSchema = z.object({ result: z.discriminatedUnion("operation", [ z.object({ operation: z.literal("watch_conversations"), result: z.array(ConversationInfoSchema).describe("List of conversations"), }), z.object({ operation: z.literal("send_message"), result: SendMessageResultSchema.describe("Send message result"), }), z.object({ operation: z.literal("send_file"), result: SendMessageResultSchema.describe("Send file result"), }), z.object({ operation: z.literal("watch_messages"), result: z.array(MessageSchema).describe("List of messages"), }), z.object({ operation: z.literal("extract_zip_messages"), result: z.array(z.string()).describe("Extracted file paths"), }), z.object({ operation: z.literal("generate_wts"), result: WtsFileResultSchema.describe("Generate WTS result"), }), z.object({ operation: z.literal("verify_wts"), result: WtsVerificationResultSchema.describe("WTS verification result"), }), z.object({ operation: z.literal("sign_wts"), result: z.string().describe("Signed WTS file path"), }), z.object({ operation: z.literal("wts2html"), result: z.union([z.string(), z.array(z.string())]).describe("HTML string or file path(s)"), }), z.object({ operation: z.literal("proof_message"), result: z.object({ proofAddress: z.string().describe("Proof object address on blockchain"), }).describe("Proof message result"), }), z.object({ operation: z.literal("blacklist"), op: z.enum(["add", "remove", "clear", "get", "exist"]).describe("Operation type"), result: z.union([ListOperationResponseSchema, z.array(z.string())]).describe("Blacklist operation result"), }), z.object({ operation: z.literal("friendslist"), op: z.enum(["add", "remove", "clear", "get", "exist"]).describe("Operation type"), result: z.union([ListOperationResponseSchema, z.array(z.string())]).describe("Friends list operation result"), }), z.object({ operation: z.literal("guardlist"), op: z.enum(["add", "remove", "get"]).describe("Operation type"), result: ListOperationResponseSchema.describe("Guard list operation result"), }), z.object({ operation: z.literal("settings"), op: z.enum(["get", "set"]).describe("Operation type"), result: z.union([GetSettingsResponseSchema, z.boolean()]).describe("Settings operation result - GetSettingsResponse for 'get' operation, boolean for 'set' operation"), }), z.object({ operation: z.literal("mark_messages_as_viewed"), result: z.number().describe("Number of messages successfully marked as viewed. Only messages that were previously unviewed are counted"), }), z.object({ operation: z.literal("mark_conversation_as_viewed"), result: z.number().describe("Number of messages successfully marked as viewed in the conversation. Only received messages that were previously unviewed are counted"), }), ]).describe("Messenger operation result discriminated union"), }).describe("Messenger operation output schema");