### Install @arisutalk/character-spec and Zod Source: https://github.com/arisutalk/character-spec/blob/main/README.md Installs the character-spec library and its peer dependency, Zod, using the pnpm package manager. Ensure Zod is installed as a peer dependency. ```bash pnpm add @arisutalk/character-spec zod ``` -------------------------------- ### Lorebook Entry Configuration (TypeScript) Source: https://context7.com/arisutalk/character-spec/llms.txt Illustrates the creation of lorebook entries with diverse activation conditions, including 'always', 'regex_match', and 'plain_text_match'. It also shows how to set priority levels and enable/disable entries. The examples utilize LorebookEntrySchema and LorebookDataSchema for validation. ```typescript import { LorebookDataSchema, LorebookEntrySchema } from "@arisutalk/character-spec"; import type { LorebookData, LorebookEntry } from "@arisutalk/character-spec"; // Create lorebook entries with different condition types const alwaysActiveLore: LorebookEntry = LorebookEntrySchema.parse({ id: "lore-001", name: "Core Setting", condition: [{ type: "always" }], content: "This is Kivotos, a city where students carry weapons.", priority: 100, enabled: true }); const regexActivatedLore: LorebookEntry = LorebookEntrySchema.parse({ id: "lore-002", name: "Blue Archive Context", condition: [ { type: "regex_match", regexPattern: "(blue archive|kivotos|schale)", regexFlags: "i" } ], content: "SCHALE is the organization that coordinates student councils.", priority: 50, enabled: true }); const plainTextLore: LorebookEntry = LorebookEntrySchema.parse({ id: "lore-003", name: "Character Relationships", condition: [ { type: "plain_text_match", text: "millennium" } ], multipleConditionResolveStrategy: "any", content: "Millennium Science School is known for advanced technology.", priority: 25, enabled: true }); // Complete lorebook with token limit const lorebook: LorebookData = LorebookDataSchema.parse({ config: { tokenLimit: 3000 }, data: [alwaysActiveLore, regexActivatedLore, plainTextLore] }); console.log(`Lorebook configured with ${lorebook.data.length} entries and ${lorebook.config.tokenLimit} token limit`); ``` -------------------------------- ### Development Commands for @arisutalk/character-spec Source: https://github.com/arisutalk/character-spec/blob/main/README.md Provides essential commands for developing the character-spec library. This includes installing dependencies, building the library (which compiles JS and generates types with JSDoc), generating types only, linting with Biome, and formatting code. ```bash # Install dependencies pnpm install # Build the library (compiles JS + generates types with JSDoc) pnpm build # Generate types only (with JSDoc from schema metadata) pnpm generate-types # Lint the code (Biome is fast! ⚡) pnpm lint # Format the code pnpm format ``` -------------------------------- ### File Message Attachments with Inlays (TypeScript) Source: https://context7.com/arisutalk/character-spec/llms.txt Demonstrates sending messages with file attachments, including local file paths and Base64 encoded data. It also shows how to include private inlay assets within messages, which are not intended for public export. The examples use the MessageSchema for validation. ```typescript import { MessageSchema } from "@arisutalk/character-spec"; import type { Message } from "@arisutalk/character-spec"; // User sends an image file (URL format) const imageMessage: Message = MessageSchema.parse({ id: "msg-003", chatId: "chat-uuid-5678", role: "user", content: { type: "file", data: "local://opfs/images/screenshot-2024.png", mimeType: "image/png" }, timestamp: Date.now(), inlays: [] }); // Base64 encoded image for export const base64ImageMessage: Message = MessageSchema.parse({ id: "msg-004", chatId: "chat-uuid-5678", role: "assistant", content: { type: "file", data: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...", mimeType: "image/jpeg" }, timestamp: Date.now(), inlays: [] }); // Message with private inlay assets (not intended for public export) const messageWithInlays: Message = MessageSchema.parse({ id: "msg-005", chatId: "chat-uuid-5678", role: "assistant", content: { type: "text", data: "Here's a private resource for you." }, timestamp: Date.now(), inlays: [ { data: "local://opfs/private/secret-asset.png", mimeType: "image/png", name: "secret-asset" } ] }); console.log(`Message ${imageMessage.id} contains a ${imageMessage.content.mimeType} file`); console.log(`Message ${messageWithInlays.id} has ${messageWithInlays.inlays.length} private inlay(s)`); ``` -------------------------------- ### Type-safe Character Creation with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt This snippet demonstrates how to create a new character object with complete type safety using the ArisuTalk CharacterSchema. It imports the schema and type definition, then populates a new character instance with all required properties, including prompt, executables, metadata, and assets. The example also shows how to log the created character's name and ID. ```typescript import { CharacterSchema } from "@arisutalk/character-spec/v0/Character/Character"; import type { Character } from "@arisutalk/character-spec/v0/Character/Character"; const newCharacter: Character = CharacterSchema.parse({ specVersion: 0, id: crypto.randomUUID(), name: "Yuuka", description: "Calculator-wielding student from Millennium Science School", avatarUrl: "https://cdn.arisutalk.com/characters/yuuka.webp", prompt: { description: "You are Yuuka, a diligent student with exceptional mathematical abilities. You speak precisely and enjoy solving problems.", authorsNote: "Yuuka occasionally references mathematical concepts in casual conversation.", lorebook: { config: { tokenLimit: 2500 }, data: [ { id: "yuuka-001", name: "Personality Core", condition: [{ type: "always" }], content: "Yuuka is serious, methodical, and has a strong sense of responsibility.", priority: 100, enabled: true }, { id: "yuuka-002", name: "Combat Style", condition: [ { type: "regex_match", regexPattern: "(fight|battle|combat)", regexFlags: "i" } ], content: "Yuuka uses a calculator as her weapon, dealing explosive damage.", priority: 50, enabled: true } ] } }, executables: { runtimeSetting: { mem: 768, timeout: 3 }, replaceHooks: { display: [], input: [], output: [ { input: "\b(\d+)\s*\+\s*(\d+)\b", meta: { type: "regex", flag: "g", isInputPatternScripted: false, isOutputScripted: true, priority: 5 }, output: "$1 + $2 = ${parseInt('$1') + parseInt('$2')}" } ], request: [] } }, metadata: { author: "arisutalk-official", license: "CC-BY-4.0", version: "1.0.0", distributedOn: "https://arisutalk.com/official/yuuka" }, assets: { assets: [ { data: "https://cdn.arisutalk.com/characters/yuuka/portrait.png", mimeType: "image/png", name: "portrait-default" } ] } }); console.log(`Created character: ${newCharacter.name} (${newCharacter.id})`); ``` -------------------------------- ### Replace Hooks for Text Processing (TypeScript) Source: https://context7.com/arisutalk/character-spec/llms.txt Shows how to implement text replacement hooks for different stages of text processing: display, input, output, and request. Each hook can be defined as a string match or a regular expression with specified flags, priority, and case sensitivity. The examples use ReplaceHookSchema and ReplaceHookEntitySchema for validation. ```typescript import { ReplaceHookSchema, ReplaceHookEntitySchema } from "@arisutalk/character-spec"; import type { ReplaceHookEntity } from "@arisutalk/character-spec"; // Define replace hooks for different stages const replaceHooks = ReplaceHookSchema.parse({ // Display hooks (visual only, doesn't edit data) display: [ { input: "\[REDACTED\]", meta: { type: "regex", flag: "gi", isInputPatternScripted: false, isOutputScripted: false, priority: 10 }, output: "[████████]" } ], // Input hooks (modifies user input before processing) input: [ { input: "sensei", meta: { type: "string", caseSensitive: false, isInputPatternScripted: false, isOutputScripted: false, priority: 5 }, output: "teacher" } ], // Output hooks (modifies AI response) output: [ { input: "\\b(haha|lol)\\b", meta: { type: "regex", flag: "gi", isInputPatternScripted: false, isOutputScripted: false, priority: 0 }, output: "*chuckles*" } ], // Request hooks (modifies AI request without editing stored data) request: [ { input: "{{user}}", meta: { type: "string", caseSensitive: true, isInputPatternScripted: false, isOutputScripted: true, priority: 20 }, output: "Sensei" } ] }); console.log(`Configured ${replaceHooks.input.length} input hooks and ${replaceHooks.output.length} output hooks`); ``` -------------------------------- ### Accessing Version-Specific Schemas with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt This example shows how to access character schemas based on their version number, which is crucial for managing migrations and ensuring compatibility. It imports a character map, accesses a specific version's schema, and defines a type alias for that version. A utility function `validateCharacter` is provided to parse and validate raw character data against the specified version's schema. ```typescript import characterMap from "@arisutalk/character-spec"; import type { CharacterMap } from "@arisutalk/character-spec"; // Access schema by version const v0Schema = characterMap[0]; // Type-safe character by version type V0Character = CharacterMap["0"]; // Validate with version-specific schema function validateCharacter(data: unknown, version: 0): V0Character { const schema = characterMap[version]; return schema.parse(data) as V0Character; } const rawCharacterData = { specVersion: 0, id: "test-char", name: "Test Character", description: "A test character for validation", prompt: { description: "Test prompt", authorsNote: "", lorebook: { config: { tokenLimit: 1000 }, data: [] } }, executables: { runtimeSetting: {}, replaceHooks: { display: [], input: [], output: [], request: [] } }, metadata: { author: "tester", license: "MIT" }, assets: { assets: [] } }; const validated = validateCharacter(rawCharacterData, 0); console.log(`Validated character ${validated.name} with spec version ${validated.specVersion}`); ``` -------------------------------- ### Configure Character Executable Settings with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Defines runtime settings and script execution parameters for character behavior. It includes memory limits, timeout settings, and replacement hooks for text. Dependencies include the ScriptSettingSchema from '@arisutalk/character-spec/v0/Executables/Executable'. ```typescript import { ScriptSettingSchema } from "@arisutalk/character-spec/v0/Executables/Executable"; const executables = ScriptSettingSchema.parse({ runtimeSetting: { mem: 1024, // Maximum memory in MB (may be capped by user settings) timeout: 5 // Maximum execution time in seconds (default: 3) }, replaceHooks: { display: [ { input: ":heart:", meta: { type: "string", caseSensitive: true, isInputPatternScripted: false, isOutputScripted: false, priority: 1 }, output: "❤️" } ], input: [], output: [], request: [] } }); console.log(`Runtime memory limit: ${executables.runtimeSetting.mem}MB`); console.log(`Script timeout: ${executables.runtimeSetting.timeout}s`); ``` -------------------------------- ### Importing Individual Schemas from @arisutalk/character-spec Source: https://github.com/arisutalk/character-spec/blob/main/README.md Illustrates how to import specific Zod schemas for individual components of the character specification, such as `CharacterSchema`, `ChatSchema`, `MessageSchema`, and `LorebookDataSchema`. This allows for more granular validation or usage of specific schema parts. ```typescript import { CharacterSchema } from "@arisutalk/character-spec/v0/Character/Character"; import { ChatSchema } from "@arisutalk/character-spec/v0/Character/Chat"; import { MessageSchema } from "@arisutalk/character-spec/v0/Character/Message"; import { LorebookDataSchema } from "@arisutalk/character-spec/v0/Character/Lorebook"; ``` -------------------------------- ### Create and Validate Chat Sessions with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Shows how to create and validate chat session objects using the ChatSchema from @arisutalk/character-spec. This ensures that chat session data, including metadata and lorebook entries, adheres to the expected structure. It requires importing the ChatSchema and Chat type. ```typescript import { ChatSchema } from "@arisutalk/character-spec"; import type { Chat } from "@arisutalk/character-spec"; // Create a chat session const chat: Chat = ChatSchema.parse({ id: "chat-uuid-5678", characterId: "char-uuid-1234", title: "First Conversation with Aris", createdAt: Date.now(), updatedAt: Date.now(), lorebook: [ { id: "lore-001", name: "Aris Background", condition: [{ type: "always" }], content: "Aris is a member of Millennium Science School.", priority: 10, enabled: true } ] }); console.log(`Chat ${chat.id} for character ${chat.characterId}`); console.log(`Created at: ${new Date(chat.createdAt).toISOString()}`); ``` -------------------------------- ### Manage Character Assets with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Manages character assets including images and media files, supporting both URL and binary data formats. It utilizes AssetsSettingSchema and AssetEntitySchema from '@arisutalk/character-spec/v0/Character/Assets'. Assets can be referenced by URL, use the 'local://' protocol for browser storage, or be provided as Uint8Array for binary data. ```typescript import { AssetsSettingSchema, AssetEntitySchema } from "@arisutalk/character-spec/v0/Character/Assets"; import type { AssetsSetting } from "@arisutalk/character-spec/v0/Character/Assets"; // Define character assets with URL references const characterAssets: AssetsSetting = AssetsSettingSchema.parse({ assets: [ { data: "https://cdn.arisutalk.com/characters/aris/expressions/happy.png", mimeType: "image/png", name: "expression-happy" }, { data: "https://cdn.arisutalk.com/characters/aris/expressions/surprised.png", mimeType: "image/png", name: "expression-surprised" }, { data: "https://cdn.arisutalk.com/characters/aris/background.webp", mimeType: "image/webp", name: "background-default" } ] }); // Assets can also use local:// protocol for browser storage const localAssets: AssetsSetting = AssetsSettingSchema.parse({ assets: [ { data: "local://opfs/characters/aris/portrait.png", mimeType: "image/png", name: "portrait-main" } ] }); // Assets can be Uint8Array for binary data const binaryAsset = AssetEntitySchema.parse({ data: new Uint8Array([0x89, 0x50, 0x4E, 0x47]), // PNG header mimeType: "image/png", name: "binary-image" }); // Assets can be referenced by name const happyExpression = characterAssets.assets.find(a => a.name === "expression-happy"); console.log(`Found asset: ${happyExpression?.name} (${happyExpression?.mimeType})`); console.log(`Total assets: ${characterAssets.assets.length}`); ``` -------------------------------- ### Manage Character Metadata with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Defines licensing, authorship, and distribution metadata for character sharing. It uses the MetaSchema from '@arisutalk/character-spec/v0/Character/Meta' to structure metadata like author, license, version, and distribution information. Minimal metadata can also be defined, with defaults applied for unspecified fields. ```typescript import { MetaSchema } from "@arisutalk/character-spec/v0/Character/Meta"; const metadata = MetaSchema.parse({ author: "concertypin", license: "CC-BY-NC-SA-4.0", // SPDX identifier version: "2.1.0", distributedOn: "https://arisutalk.com/characters/aris-v2", additionalInfo: "Updated with enhanced personality traits and expanded lorebook. Compatible with ArisuTalk v0.5+" }); // Minimal metadata with defaults const minimalMetadata = MetaSchema.parse({ author: "anonymous" // license defaults to "ARR" (All Rights Reserved) }); console.log(`Character by ${metadata.author}, licensed under ${metadata.license}`); console.log(`Anonymous character has default license: ${minimalMetadata.license}`); ``` -------------------------------- ### Validate AI Character Data with TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Demonstrates runtime validation of AI character data using the CharacterV0Schema from @arisutalk/character-spec. This process ensures that the character data conforms to the defined specification, providing type safety and catching potential errors at runtime. It requires importing the schema and the corresponding TypeScript type. ```typescript import { CharacterV0Schema } from "@arisutalk/character-spec"; import type { CharacterV0 } from "@arisutalk/character-spec"; try { const characterData = { specVersion: 0, id: "char-uuid-1234", name: "Aris", description: "Light Attribute AoE Dealer from Blue Archive", avatarUrl: "https://example.com/aris-avatar.png", prompt: { description: "You are Aris, a tactical support android from Blue Archive.", authorsNote: "Aris maintains a calm, analytical demeanor.", lorebook: { config: { tokenLimit: 2000 }, data: [] } }, executables: { runtimeSetting: { mem: 512, timeout: 3 }, replaceHooks: { display: [], input: [], output: [], request: [] } }, metadata: { author: "concertypin", license: "CC-BY-4.0", version: "1.0.0", distributedOn: "https://arisutalk.com/characters/aris" }, assets: { assets: [] } }; // Validate and parse with runtime type checking const validatedCharacter: CharacterV0 = CharacterV0Schema.parse(characterData); console.log(`Successfully validated character: ${validatedCharacter.name}`); } catch (error) { console.error("Validation failed:", error.errors); } ``` -------------------------------- ### Manage Messages with Chat Association in TypeScript Source: https://context7.com/arisutalk/character-spec/llms.txt Illustrates the creation and validation of message objects with proper chat association using the MessageSchema from @arisutalk/character-spec. This ensures that messages are correctly linked to their respective chats and have the correct content structure, including support for inlay elements. Requires importing MessageSchema and Message type. ```typescript import { MessageSchema } from "@arisutalk/character-spec"; import type { Message } from "@arisutalk/character-spec"; // Create individual messages with chat association const userMessage: Message = MessageSchema.parse({ id: "msg-001", chatId: "chat-uuid-5678", role: "user", content: { type: "text", data: "Hello Aris! How are you today?" }, timestamp: Date.now(), inlays: [] }); const assistantMessage: Message = MessageSchema.parse({ id: "msg-002", chatId: "chat-uuid-5678", role: "assistant", content: { type: "text", data: "I am functioning optimally. How may I assist you?" }, timestamp: Date.now(), inlays: [] }); console.log(`Message ${userMessage.id} in chat ${userMessage.chatId}`); console.log(`Role: ${userMessage.role}, Content: ${userMessage.content.data}`); ``` -------------------------------- ### Export Character to Compressed CBOR Source: https://github.com/arisutalk/character-spec/blob/main/TRANSPORT.md This function takes a Character object, converts it to CBOR format using `toCBOR`, compresses the CBOR data using `compressData`, and returns the compressed data as a string. Chat and message history are excluded to minimize data size. ```typescript declare function toCBOR(data: any): Uint8Array; declare async function compressData(input: Uint8Array): Promise async function exportCharacter(character: Character): string { const cbor = toCBOR(character); const compressed = await compressData(cbor); return compressed; } ``` -------------------------------- ### Runtime Validation of Character Data with TypeScript Source: https://github.com/arisutalk/character-spec/blob/main/README.md Demonstrates how to validate raw character data against the CharacterV0Schema provided by the library. It uses Zod's `parse` method for runtime validation and leverages TypeScript for type safety, allowing direct access to validated properties like `aris.name`. ```typescript import { CharacterV0Schema } from "@arisutalk/character-spec"; import type { CharacterV0 } from "@arisutalk/character-spec"; // Let's say you have some raw data... const rawData = { specVersion: 0, id: "uuid-1234", name: "Aris", description: "Light Attribute AoE Dealer from Blue Archive.", avatarUrl: "https://example.com/aris.png", prompt: { system: "You are Aris from Blue Archive.", jailbreak: "", }, lorebook: { config: { tokenLimit: 1000 }, data: [], }, executables: { runtimeSetting: {}, replaceHooks: { display: [], input: [], output: [], request: [], }, }, metadata: { author: "concertypin", license: "CC-BY-4.0", }, }; // Validate it against the schema! const aris = CharacterV0Schema.parse(rawData); console.log(`Hello, ${aris.name}!`); // TypeScript knows 'name' exists! ✨ ``` -------------------------------- ### Importing TypeScript Types with JSDoc from @arisutalk/character-spec Source: https://github.com/arisutalk/character-spec/blob/main/README.md Shows how to import TypeScript types for character-related data structures like `Character`, `Chat`, and `Message`. These types include JSDoc comments extracted from schema metadata, providing rich tooltips and documentation within IDEs. ```typescript import type { Character } from "@arisutalk/character-spec/v0/Character/Character"; import type { Chat } from "@arisutalk/character-spec/v0/Character/Chat"; import type { Message } from "@arisutalk/character-spec/v0/Character/Message"; // Hover over these in your IDE to see the JSDoc comments! const character: Character = { // ... your character data }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.