Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,68 @@

A library for working with character cards.

## Installation

To install the library, use npm:

```sh
npm install @openrouter/character
```

## Usage

Here's a simple example of how to use the library:

```javascript
import { Character } from '@openrouter/character';

const file = new File(['{"name": "John Doe"}'], 'character.json', { type: 'application/json' });

Character.fromFile(file).then((character) => {
console.log(character.name); // Output: John Doe
});
```

## API Documentation

### `Character`

#### Properties

- `metadata`: The metadata of the character.
- `fallbackAvatar`: The fallback avatar of the character.

#### Methods

- `static fromFile(file: File): Promise<Character>`: Creates a `Character` instance from a file.
- `avatar`: Returns the avatar of the character.
- `description`: Returns the description of the character.
- `name`: Returns the name of the character.

## Comprehensive Example

Here's a comprehensive example demonstrating the `Character` class:

```javascript
import { Character } from '@openrouter/character';

const jsonFile = new File(['{"name": "John Doe", "description": "A brave warrior"}'], 'character.json', { type: 'application/json' });
const pngFile = new File([/* PNG file data */], 'character.png', { type: 'image/png' });
const webpFile = new File([/* WEBP file data */], 'character.webp', { type: 'image/webp' });

Promise.all([
Character.fromFile(jsonFile),
Character.fromFile(pngFile),
Character.fromFile(webpFile)
]).then(([jsonCharacter, pngCharacter, webpCharacter]) => {
console.log(jsonCharacter.name); // Output: John Doe
console.log(jsonCharacter.description); // Output: A brave warrior

console.log(pngCharacter.avatar); // Output: Base64 encoded PNG avatar
console.log(webpCharacter.avatar); // Output: Base64 encoded WEBP avatar
});
```

## Acknowledgements

- https://github.com/SillyTavern/SillyTavern
Expand Down
55 changes: 55 additions & 0 deletions tests/character.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Character } from '../src/index.js';
import { test, describe } from 'node:test';
import assert from 'node:assert';

describe('Character', () => {
test('Character.fromFile with JSON file', async () => {
const file = new File(['{"name": "John Doe"}'], 'character.json', { type: 'application/json' });
const character = await Character.fromFile(file);
assert.strictEqual(character.name, 'John Doe');
});

test('Character.fromFile with PNG file', async () => {
const pngData = new Uint8Array([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xDE, 0x00, 0x00, 0x00,
0x0A, 0x74, 0x45, 0x58, 0x74, 0x63, 0x68, 0x61, 0x72, 0x61, 0x00, 0x7B,
0x22, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x4A, 0x6F, 0x68, 0x6E,
0x20, 0x44, 0x6F, 0x65, 0x22, 0x7D, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
0x41, 0x54, 0x78, 0x9C, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
0xE2, 0x21, 0xBC, 0x33, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44,
0xAE, 0x42, 0x60, 0x82
]);
const file = new File([pngData], 'character.png', { type: 'image/png' });
const character = await Character.fromFile(file);
assert.strictEqual(character.name, 'John Doe');
});

test('Character.fromFile with WEBP file', async () => {
const webpData = new Uint8Array([
0x52, 0x49, 0x46, 0x46, 0x3A, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50,
0x56, 0x50, 0x38, 0x20, 0x0A, 0x00, 0x00, 0x00, 0x30, 0x2E, 0x30, 0x30,
0x2E, 0x30, 0x30, 0x2E, 0x30, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0x4C, 0x49, 0x53, 0x54, 0x3A, 0x00, 0x00, 0x00, 0x4A, 0x53, 0x4F, 0x4E,
0x3A, 0x7B, 0x22, 0x6E, 0x61, 0x6D, 0x65, 0x22, 0x3A, 0x22, 0x4A, 0x6F,
0x68, 0x6E, 0x20, 0x44, 0x6F, 0x65, 0x22, 0x7D, 0x00, 0x00, 0x00, 0x00
]);
const file = new File([webpData], 'character.webp', { type: 'image/webp' });
const character = await Character.fromFile(file);
assert.strictEqual(character.name, 'John Doe');
});

test('Character properties and methods', async () => {
const metadata = {
name: 'John Doe',
description: 'A brave warrior',
avatar: 'none',
system_prompt: 'A warrior in a fantasy world'
};
const character = new Character(metadata);
assert.strictEqual(character.name, 'John Doe');
assert.strictEqual(character.description, 'A warrior in a fantasy world');
assert.strictEqual(character.avatar, '');
});
});