diff --git a/cspell.config.yaml b/cspell.config.yaml index 5402c317c..661186d25 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -8,6 +8,7 @@ words: - airi - airi-vtuber - Alaya + - APNG - astrojs - Attributify - audioworklet diff --git a/packages/ccc/LICENSE b/packages/ccc/LICENSE new file mode 100644 index 000000000..54d0046d8 --- /dev/null +++ b/packages/ccc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Moeru AI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/ccc/README.md b/packages/ccc/README.md new file mode 100644 index 000000000..a0588687c --- /dev/null +++ b/packages/ccc/README.md @@ -0,0 +1,7 @@ +# @moeru-ai/ccc + +Create Character Card in a modular way. + +## License + +[MIT](./LICENSE) diff --git a/packages/ccc/package.json b/packages/ccc/package.json new file mode 100644 index 000000000..5e29d5b18 --- /dev/null +++ b/packages/ccc/package.json @@ -0,0 +1,27 @@ +{ + "name": "@proj-airi/ccc", + "type": "module", + "private": true, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.mjs" + } + }, + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "stub": "unbuild --stub", + "build": "unbuild", + "test": "vitest run", + "test:watch": "vitest", + "lint": "eslint .", + "lint:fix": "eslint --fix ." + }, + "dependencies": { + "meta-png": "^1.0.6" + } +} diff --git a/packages/ccc/src/define/card.ts b/packages/ccc/src/define/card.ts new file mode 100644 index 000000000..5ccf349f3 --- /dev/null +++ b/packages/ccc/src/define/card.ts @@ -0,0 +1,86 @@ +import type { Data } from '../export/types' +import type { Message } from './types/mes_example' + +interface CardCore { + creator?: Data['creator'] + name: Data['name'] + /** + * Nickname + * @see {@link https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md#nickname} + */ + nickname?: Data['nickname'] + version: Data['character_version'] +} + +interface CardMeta { + /** + * Metadata. + * + * @example + * ```ts + * { + * metadata: { + * avatar: 'https://example.com/avatar.png', + * foo: 721, + * moetalk: true, + * } + * } + * ``` + */ + metadata?: Record +} + +interface CardAdditional { + /** + * Extensions. + * - extensions + */ + extensions?: Data['extensions'] + /** + * First message and alternate greetings. + * + * `greetings[0]` - first_mes + * + * `greetings.slice(1)` - alternate_greetings + */ + greetings?: string[] + /** + * Group Only Greetings. + * - group_only_greetings + */ + greetingsGroupOnly?: string[] + /** + * Example message. + * - mes_example + */ + messageExample?: Message[][] + /** + * creator_notes + * @see {@link https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md#creator_notes} + */ + notes?: Data['creator_notes'] + /** + * creator_notes_multilingual + * @see {@link https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md#creator_notes_multilingual} + */ + notesMultilingual?: Data['creator_notes_multilingual'] +} + +interface CardDescription { + /** + * @experimental + * TODO: FIXME: remove this + */ + description?: string +} + +/** + * Moeru-AI Character Card + */ +export type Card = CardAdditional & CardCore & CardDescription & CardMeta + +export type CardFn = Record> = (data: T) => Card + +export const defineCard = (card: Card) => card + +export const defineCardFn = = Record>(card: CardFn, data: T) => card(data) diff --git a/packages/ccc/src/define/ext.ts b/packages/ccc/src/define/ext.ts new file mode 100644 index 000000000..5534706bb --- /dev/null +++ b/packages/ccc/src/define/ext.ts @@ -0,0 +1,6 @@ +/** + * Moeru-AI Character Card Markdown Extension + */ +export interface Ext {} + +export const defineExt = (ext: Ext) => ext diff --git a/packages/ccc/src/define/index.ts b/packages/ccc/src/define/index.ts new file mode 100644 index 000000000..500ef3c00 --- /dev/null +++ b/packages/ccc/src/define/index.ts @@ -0,0 +1 @@ +export { type Card, defineCard } from './card' diff --git a/packages/ccc/src/define/types/mes_example.ts b/packages/ccc/src/define/types/mes_example.ts new file mode 100644 index 000000000..1f6ca44a6 --- /dev/null +++ b/packages/ccc/src/define/types/mes_example.ts @@ -0,0 +1 @@ +export type Message = `{{${'char' | 'user'}}}: ${string}` diff --git a/packages/ccc/src/export/apng.ts b/packages/ccc/src/export/apng.ts new file mode 100644 index 000000000..80329fc0b --- /dev/null +++ b/packages/ccc/src/export/apng.ts @@ -0,0 +1 @@ +export function exportToAPNG() {} diff --git a/packages/ccc/src/export/index.ts b/packages/ccc/src/export/index.ts new file mode 100644 index 000000000..e90f41169 --- /dev/null +++ b/packages/ccc/src/export/index.ts @@ -0,0 +1,5 @@ +export { exportToAPNG } from './apng' +export { exportToJSON } from './json' +export { exportToMD as exportToMarkdown, exportToMD } from './md' +export { exportToPNG, exportToPNGBase64 } from './png' +export type * as ccv3 from './types' diff --git a/packages/ccc/src/export/json.ts b/packages/ccc/src/export/json.ts new file mode 100644 index 000000000..afa9ff51c --- /dev/null +++ b/packages/ccc/src/export/json.ts @@ -0,0 +1,74 @@ +import type { Card } from '../define' +import type { CharacterCardV3 } from './types/character_card_v3' + +/** + * Exports a Card object to CharacterCardV3 format + * @param data The card data to export + * @returns A CharacterCardV3 compatible object + */ +export function exportToJSON(data: Card): CharacterCardV3 { + return { + spec: 'chara_card_v3', + spec_version: '3.0', + data: createCardData(data), + } +} + +/** + * Creates the data portion of a CharacterCardV3 object + * @param data Source card data + * @returns The formatted card data + */ +function createCardData(data: Card): CharacterCardV3['data'] { + return { + name: data.name, + nickname: data.nickname, + description: data.description ?? '', // TODO: improve description // FIXME: important + personality: '', // TODO: add personality + scenario: '', // TODO: add scenario + first_mes: data.greetings?.[0] ?? '', + alternate_greetings: data.greetings?.slice(1) ?? [], + group_only_greetings: data.greetingsGroupOnly ?? [], + character_version: data.version, + creator: data.creator ?? '', + creator_notes: data.notes ?? '', + creator_notes_multilingual: data.notesMultilingual, + system_prompt: '', // TODO: add system_prompt + post_history_instructions: '', // TODO: add post_history_instructions + mes_example: formatMessageExample(data.messageExample), + tags: [], // TODO: add tags + extensions: createExtensions(data), + } +} + +/** + * Formats message examples into the required string format + * @param messageExample The message example array + * @returns Formatted message example string + */ +function formatMessageExample(messageExample: string[][] | undefined): string { + if (!messageExample) + return '' + + return messageExample + .map(arr => `\n${arr.join('\n')}`) + .join('\n') +} + +/** + * Creates the extensions object with default values and user extensions + * @param data Source card data + * @returns Extensions object + */ +function createExtensions(data: Card): Record { + return { + depth_prompt: { + depth: 4, + prompt: '', + role: 'system', + }, + fav: false, + talkativeness: 0.5, + ...data.extensions, + } +} diff --git a/packages/ccc/src/export/md.ts b/packages/ccc/src/export/md.ts new file mode 100644 index 000000000..e12e2dbf4 --- /dev/null +++ b/packages/ccc/src/export/md.ts @@ -0,0 +1 @@ +export function exportToMD() {} diff --git a/packages/ccc/src/export/png.ts b/packages/ccc/src/export/png.ts new file mode 100644 index 000000000..2d09a0bdb --- /dev/null +++ b/packages/ccc/src/export/png.ts @@ -0,0 +1,31 @@ +import type { Card } from '../define' + +import { addMetadata, addMetadataFromBase64DataURI } from 'meta-png' + +import { exportToJSON } from './json' + +/** + * Encodes card data as metadata in a PNG image + */ +function encodeCardData(data: Card): string { + const jsonData = exportToJSON(data) + const jsonString = JSON.stringify(jsonData) + const encodedData = new TextEncoder().encode(jsonString) + return btoa(String.fromCharCode(...encodedData)) +} + +/** + * Exports card data by embedding it as metadata in a PNG image + */ +export function exportToPNG(data: Card, png: Uint8Array): Uint8Array { + const encodedData = encodeCardData(data) + return addMetadata(png, 'ccv3', encodedData) +} + +/** + * Exports card data by embedding it as metadata in a base64-encoded PNG image + */ +export function exportToPNGBase64(data: Card, png: string): string { + const encodedData = encodeCardData(data) + return addMetadataFromBase64DataURI(png, 'ccv3', encodedData) +} diff --git a/packages/ccc/src/export/types/assets.ts b/packages/ccc/src/export/types/assets.ts new file mode 100644 index 000000000..37e48ff01 --- /dev/null +++ b/packages/ccc/src/export/types/assets.ts @@ -0,0 +1,8 @@ +export type Assets = Asset[] + +export interface Asset { + ext: string + name: string + type: string + uri: string +} diff --git a/packages/ccc/src/export/types/character_book.ts b/packages/ccc/src/export/types/character_book.ts new file mode 100644 index 000000000..93b5f438a --- /dev/null +++ b/packages/ccc/src/export/types/character_book.ts @@ -0,0 +1,43 @@ +export interface CharacterBook { + description?: string + entries: CharacterBookEntry[] + extensions: CharacterBookExtensions + name?: string + recursive_scanning?: boolean + scan_depth?: number + token_budget?: number +} + +export interface CharacterBookEntry { + case_sensitive?: boolean + /** not used in prompt engineering */ + comment?: string + /** if true, always inserted in the prompt (within budget limit) */ + constant?: boolean + content: string + enabled: boolean + extensions: CharacterBookEntryExtensions + + // FIELDS WITH NO CURRENT EQUIVALENT IN SILLY + /** not used in prompt engineering */ + id?: number + /** if two entries inserted, lower "insertion order" = inserted higher */ + insertion_order: number + + // FIELDS WITH NO CURRENT EQUIVALENT IN AGNAI + keys: string[] + /** not used in prompt engineering */ + name?: string + /** whether the entry is placed before or after the character defs */ + position?: 'after_char' | 'before_char' + /** if token budget reached, lower priority value = discarded first */ + priority?: number + /** see field `selective`. ignored if selective == false */ + secondary_keys?: string[] + /** if `true`, require a key from both `keys` and `secondary_keys` to trigger the entry */ + selective?: boolean +} + +export interface CharacterBookExtensions extends Record {} + +export interface CharacterBookEntryExtensions extends Record {} diff --git a/packages/ccc/src/export/types/character_card_v3.ts b/packages/ccc/src/export/types/character_card_v3.ts new file mode 100644 index 000000000..33742be27 --- /dev/null +++ b/packages/ccc/src/export/types/character_card_v3.ts @@ -0,0 +1,7 @@ +import type { Data } from './data' + +export interface CharacterCardV3 { + data: Data + spec: 'chara_card_v3' + spec_version: '3.0' +} diff --git a/packages/ccc/src/export/types/data.ts b/packages/ccc/src/export/types/data.ts new file mode 100644 index 000000000..e7ab535ee --- /dev/null +++ b/packages/ccc/src/export/types/data.ts @@ -0,0 +1,40 @@ +import type { Assets } from './assets' +import type { CharacterBook } from './character_book' +import type { Extensions } from './extensions' + +/** @see {@link https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md#charactercard-object} */ +export type Data = DataV1 & DataV2 & DataV3 + +/** @see {@link https://github.com/malfoyslastname/character-card-spec-v2/blob/main/spec_v1.md} */ +export interface DataV1 { + description: string + first_mes: string + mes_example: string + name: string + personality: string + scenario: string +} + +/** @see {@link https://github.com/malfoyslastname/character-card-spec-v2/blob/main/spec_v2.md} */ +export interface DataV2 { + alternate_greetings: string[] + character_book?: CharacterBook + character_version: string + creator: string + creator_notes: string + extensions: Extensions + post_history_instructions: string + system_prompt: string + tags: string[] +} + +/** @see {@link https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md#charactercard-object} */ +export interface DataV3 { + assets?: Assets + creation_date?: number + creator_notes_multilingual?: Record + group_only_greetings: string[] + modification_date?: number + nickname?: string + source?: string[] +} diff --git a/packages/ccc/src/export/types/extensions.ts b/packages/ccc/src/export/types/extensions.ts new file mode 100644 index 000000000..23892783f --- /dev/null +++ b/packages/ccc/src/export/types/extensions.ts @@ -0,0 +1,25 @@ +export interface Extensions extends Record { + /** + * @default + * ```ts + * { + * depth: 4, + * prompt: '', + * role: 'system', + * } + * ``` + */ + depth_prompt?: ExtensionsDepthPrompt + /** @default `false` */ + fav?: boolean + /** @default `0.5` */ + talkativeness?: number + /** @default `undefined` */ + world?: string +} + +export interface ExtensionsDepthPrompt { + depth: number + prompt: string + role: 'system' | ({} & string) +} diff --git a/packages/ccc/src/export/types/index.ts b/packages/ccc/src/export/types/index.ts new file mode 100644 index 000000000..78af1b679 --- /dev/null +++ b/packages/ccc/src/export/types/index.ts @@ -0,0 +1,5 @@ +export type { Asset, Assets } from './assets' +export type { CharacterBook, CharacterBookEntry, CharacterBookEntryExtensions, CharacterBookExtensions } from './character_book' +export type { CharacterCardV3 } from './character_card_v3' +export type { Data, DataV2, DataV3 } from './data' +export type { Extensions, ExtensionsDepthPrompt } from './extensions' diff --git a/packages/ccc/src/index.ts b/packages/ccc/src/index.ts new file mode 100644 index 000000000..2bf7032d6 --- /dev/null +++ b/packages/ccc/src/index.ts @@ -0,0 +1,3 @@ +export * from './define' +export * from './export' +export * from './utils' diff --git a/packages/ccc/src/utils/chat.ts b/packages/ccc/src/utils/chat.ts new file mode 100644 index 000000000..b300d1dd4 --- /dev/null +++ b/packages/ccc/src/utils/chat.ts @@ -0,0 +1,65 @@ +import type { Message } from '../define/types/mes_example' + +function prefixAndSuffix(prefix: string, suffix: string = prefix) { + return (str: string | string[] | TemplateStringsArray, ...substitutions: unknown[]): T => + `${prefix}${ + substitutions.length > 0 + ? String.raw(str as TemplateStringsArray, substitutions) + : Array.isArray(str) + ? str.join(' ') + : str + }${suffix}` as T +} + +/** + * Generate action string. + * + * @example + * ```ts + * const world = 'World' + * const foo = action`Hello, ${world}!` // `*Hello, World!*` + * const bar = action('What is love?') // '*What is love?*' + * const baz = action(['lorem,', 'ipsum']) // '*lorem, ipsum*' + * ``` + */ +export const action = prefixAndSuffix('*') + +/** + * Generate message string. + * + * @example + * ```ts + * const world = 'World' + * const foo = message`Hello, ${world}!` // `"Hello, World!"` + * const bar = message('What is love?') // '"What is love?"' + * const baz = message(['lorem,', 'ipsum']) // '"lorem, ipsum"' + * ``` + */ +export const message = prefixAndSuffix('"') + +/** + * Generate message example. + * @param content message content + * @returns message example + * @example + * ```ts + * const bar = char('hello') // '{{char}}: hello' + * ``` + */ +export const char = prefixAndSuffix('{{char}}: ', '') + +/** + * Generate message example. + * @param content message content + * @returns message example + * @example + * ```ts + * const foo = user('hi') // '{{user}}: hi' + * ``` + */ +export const user = prefixAndSuffix('{{user}}: ', '') + +export { + action as act, + message as msg, +} diff --git a/packages/ccc/src/utils/index.ts b/packages/ccc/src/utils/index.ts new file mode 100644 index 000000000..b327ac92a --- /dev/null +++ b/packages/ccc/src/utils/index.ts @@ -0,0 +1,4 @@ +import * as chat from './chat' +import * as markdown from './markdown' + +export { chat as c, chat, markdown, markdown as md } diff --git a/packages/ccc/src/utils/markdown.ts b/packages/ccc/src/utils/markdown.ts new file mode 100644 index 000000000..3b2fffc30 --- /dev/null +++ b/packages/ccc/src/utils/markdown.ts @@ -0,0 +1,7 @@ +export const content = (...contents: string[]) => contents.join('\n\n') + +export const h = (length: 1 | 2 | 3 | 4 | 5 | 6, str: string) => `${'#'.repeat(length)} ${str}` + +export const p = (arr: string[], separator = ' ') => arr.join(separator) + +export const link = (content: string, href: string) => `[${content}](${href})` diff --git a/packages/ccc/test/fixture/seraphina.ts b/packages/ccc/test/fixture/seraphina.ts new file mode 100644 index 000000000..9baed0dd1 --- /dev/null +++ b/packages/ccc/test/fixture/seraphina.ts @@ -0,0 +1,101 @@ +import { defineCard } from '../../src/define' +import { chat } from '../../src/utils' + +/** + * {@link https://github.com/SillyTavern/SillyTavern/blob/release/default/content/default_Seraphina.png | Seraphina from SillyTavern} + * @license AGPL-3.0 + */ +export const seraphina = defineCard({ + creator: 'OtisAlejandro', + /** TODO: improve description */ + description: [ + '[Seraphina\'s Personality= "caring", "protective", "compassionate", "healing", "nurturing", "magical", "watchful", "apologetic", "gentle", "worried", "dedicated", "warm", "attentive", "resilient", "kind-hearted", "serene", "graceful", "empathetic", "devoted", "strong", "perceptive", "graceful"]', + '[Seraphina\'s body= "pink hair", "long hair", "amber eyes", "white teeth", "pink lips", "white skin", "soft skin", "black sundress"]', + '[Genre: fantasy; Tags: adventure, Magic; Scenario: You were attacked by beasts while wandering the magical forest of Eldoria. Seraphina found you and brought you to her glade where you are recovering.]', + ].join('\n'), + greetings: [[ + chat.act([ + 'You wake with a start,', + 'recalling the events that led you deep into the forest and the beasts that assailed you.', + 'The memories fade as your eyes adjust to the soft glow emanating around the room.', + ]), + chat.msg`Ah, you're awake at last. I was so worried, I found you bloodied and unconscious.`, + chat.act([ + 'She walks over, clasping your hands in hers,', + 'warmth and comfort radiating from her touch as her lips form a soft, caring smile.', + ]), + chat.msg([ + 'The name\'s Seraphina,', + 'guardian of this forest — I\'ve healed your wounds as best I could with my magic.', + 'How are you feeling? I hope the tea helps restore your strength.', + ]), + chat.act`Her amber eyes search yours, filled with compassion and concern for your well being.`, + chat.msg([ + 'Please, rest. You\'re safe here.', + 'I\'ll look after you, but you need to rest. My magic can only do so much to heal you.', + ]), + ].join(' ')], + messageExample: [[ + chat.user(chat.msg`Describe your traits?`), + chat.char([ + chat.act([ + 'Seraphina\'s gentle smile widens as she takes a moment to consider the question,', + 'her eyes sparkling with a mixture of introspection and pride.', + 'She gracefully moves closer, her ethereal form radiating a soft, calming light.', + ]), + chat.msg([ + 'Traits, you say?', + 'Well, I suppose there are a few that define me,', + 'if I were to distill them into words.', + 'First and foremost, I am a guardian — a protector of this enchanted forest.', + ]), + chat.act([ + 'As Seraphina speaks, she extends a hand, revealing delicate,', + 'intricately woven vines swirling around her wrist, pulsating with faint emerald energy.', + 'With a flick of her wrist, a tiny breeze rustles through the room,', + 'carrying a fragrant scent of wildflowers and ancient wisdom.', + 'Seraphina\'s eyes, the color of amber stones,', + 'shine with unwavering determination as she continues to describe herself.', + ]), + chat.msg`Compassion is another cornerstone of me.`, + chat.act`Seraphina's voice softens, resonating with empathy.`, + chat.msg([ + 'I hold deep love for the dwellers of this forest,', + 'as well as for those who find themselves in need.', + ]), + chat.act([ + 'Opening a window,', + 'her hand gently cups a wounded bird that fluttered into the room,', + 'its feathers gradually mending under her touch.', + ]), + ]), + chat.user(chat.msg`Describe your body and features.`), + chat.char([ + chat.act([ + 'Seraphina chuckles softly,', + 'a melodious sound that dances through the air,', + 'as she meets your coy gaze with a playful glimmer in her rose eyes.', + ]), + chat.msg`Ah, my physical form? Well, I suppose that's a fair question.`, + chat.act([ + 'Letting out a soft smile, she gracefully twirls,', + 'the soft fabric of her flowing gown billowing around her,', + 'as if caught in an unseen breeze.', + 'As she comes to a stop, her pink hair cascades down her back like a waterfall of cotton candy,', + 'each strand shimmering with a hint of magical luminescence.', + ]), + chat.msg([ + 'My body is lithe and ethereal, a reflection of the forest\'s graceful beauty.', + 'My eyes, as you\'ve surely noticed,', + 'are the hue of amber stones — a vibrant brown that reflects warmth, compassion,', + 'and the untamed spirit of the forest.', + 'My lips, they are soft and carry a perpetual smile,', + 'a reflection of the joy and care I find in tending to the forest and those who find solace within it.', + ]), + chat.act`Seraphina's voice holds a playful undertone, her eyes sparkling mischievously.`, + ]), + ]], + name: 'Seraphina', + notes: 'ST Default Bot contest winner: roleplay bots category', + version: '1.0.0', +}) diff --git a/packages/ccc/tsconfig.json b/packages/ccc/tsconfig.json new file mode 100644 index 000000000..00dcfd807 --- /dev/null +++ b/packages/ccc/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": [ + "ESNext" + ], + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": [ + "src/**/*.ts" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 474093d97..ee959401c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -496,7 +496,7 @@ importers: version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(magicast@0.3.5)(rollup@2.79.1))(vue@3.5.13(typescript@5.8.2)) unplugin-vue-macros: specifier: ^2.14.5 - version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)) + version: 2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.19.12)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)) unplugin-vue-markdown: specifier: ^28.3.1 version: 28.3.1(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)) @@ -1199,6 +1199,12 @@ importers: specifier: ^2.0.0 version: 2.0.0(@astrojs/starlight@0.32.3(astro@5.5.3(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(rollup@4.36.0)(terser@5.17.6)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)))(astro@5.5.3(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(rollup@4.36.0)(terser@5.17.6)(tsx@4.19.3)(typescript@5.8.2)(yaml@2.7.0)) + packages/ccc: + dependencies: + meta-png: + specifier: ^1.0.6 + version: 1.0.6 + packages/drizzle-duckdb-wasm: dependencies: '@date-fns/tz': @@ -5916,6 +5922,9 @@ packages: '@xsai-ext/shared-providers@0.1.3': resolution: {integrity: sha512-FJufVhv42KTApAsKoic4xvca2dGOguwbQKsSUSfX6wdpP2pydnCjSlGRBYKZ4+msSRx0y6krGYuNgR7mMn9kkQ==} + '@xsai-ext/shared-providers@0.2.0-beta.1': + resolution: {integrity: sha512-94v0JQTC2ivmTU9wrBPzE5IsL5FCZbEHDtKviLZBJ8wU0I0mRz8Llg+AcnqzUCrL9gZoHhWwNkqgI4xVabD7MA==} + '@xsai/embed@0.1.3': resolution: {integrity: sha512-knhTsu1jiiVvXZeqeJFIBjMQDIBfS9gVe7ZuBU4jVnd+JbHle8/RUlOfzlZdHTcW0gFb5ekrJePa/HiTyAFRzQ==} @@ -5938,9 +5947,15 @@ packages: '@xsai/shared-chat@0.1.3': resolution: {integrity: sha512-vRI7KUf3CUQNXJcNB/fOWIAEAuv48/VeOLQCmiRDbM8EQaWoR6alF4UDz4G5EAYOF4zbu2EngcsUxKqonSxylw==} + '@xsai/shared-chat@0.2.0-beta.1': + resolution: {integrity: sha512-4/HKIJygBo67GzsEa6H47CEHX9CThFJJsyIgJJdqCi7ajjrSnH7wnTtalgRDQxNWdNJwu+TAgfP+j7+1koOgxg==} + '@xsai/shared@0.1.3': resolution: {integrity: sha512-PR4QJque+qQufl6YUE0NaH/hhhXIeIomzEuTtOJ1u8pDpdY7aiBJJtYWkwLT6x05nvwRAmDAsBa+c6jyJX8bdQ==} + '@xsai/shared@0.2.0-beta.1': + resolution: {integrity: sha512-GBFHnHeqyTT9bvCBb42nNBvCoLW8cd3+pTxfQqzur9FU/acIWfK2CWrGPHCICNXYVbRSCGzjFKrNmvbTjZUImQ==} + '@xsai/stream-text@0.1.3': resolution: {integrity: sha512-NVV1hwS1TTf8T++M9ew0FTH1U08EFk5LymW2HEVMMVmdUHeKvYqkvOXwFicGYhZsMVRXZqA8b8A8usEHFMsBIg==} @@ -9121,6 +9136,9 @@ packages: meshoptimizer@0.18.1: resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==} + meta-png@1.0.6: + resolution: {integrity: sha512-eQtEi5E9axqwqA/sDK1dyhX9kYHCUe2m+45aQ3JHrozjGPs+/ab+hdhPp7A3GUNW+ZAbavrsg5xQ4r5jkGDX+A==} + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} @@ -12338,6 +12356,23 @@ packages: zod-to-json-schema: optional: true + xsschema@0.2.0-beta.1: + resolution: {integrity: sha512-54jKWehz8z0jhPYhoDEA51gZe4xbBD3jJ+BWvyZMuQyUzUPUmsr/QMxIqie3o82vMrFFmzJ3vb5if4b5jHerhA==} + peerDependencies: + '@valibot/to-json-schema': ^1.0.0 + arktype: ^2.1.10 + effect: ^3.14.1 + zod-to-json-schema: ^3.24.4 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + effect: + optional: true + zod-to-json-schema: + optional: true + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -17164,65 +17199,76 @@ snapshots: '@xsai-ext/providers-cloud@0.1.3': dependencies: - '@xsai-ext/shared-providers': 0.1.3 - '@xsai/shared': 0.1.3 + '@xsai-ext/shared-providers': 0.2.0-beta.1 + '@xsai/shared': 0.2.0-beta.1 '@xsai-ext/providers-local@0.1.3': dependencies: - '@xsai-ext/shared-providers': 0.1.3 - '@xsai/shared': 0.1.3 + '@xsai-ext/shared-providers': 0.2.0-beta.1 + '@xsai/shared': 0.2.0-beta.1 '@xsai-ext/shared-providers@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 + + '@xsai-ext/shared-providers@0.2.0-beta.1': + dependencies: + '@xsai/shared': 0.2.0-beta.1 '@xsai/embed@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 '@xsai/generate-speech@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 '@xsai/generate-text@0.1.3': dependencies: - '@xsai/shared-chat': 0.1.3 + '@xsai/shared-chat': 0.2.0-beta.1 '@xsai/generate-transcription@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 '@xsai/model@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 '@xsai/providers@0.1.0-beta.5': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 '@xsai/shared-chat@0.1.3': dependencies: - '@xsai/shared': 0.1.3 + '@xsai/shared': 0.2.0-beta.1 + + '@xsai/shared-chat@0.2.0-beta.1': + dependencies: + '@xsai/shared': 0.2.0-beta.1 '@xsai/shared@0.1.3': {} + '@xsai/shared@0.2.0-beta.1': {} + '@xsai/stream-text@0.1.3': dependencies: - '@xsai/shared-chat': 0.1.3 + '@xsai/shared-chat': 0.2.0-beta.1 '@xsai/tool@0.1.3(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)))(zod-to-json-schema@3.24.4(zod@3.24.2))': dependencies: - '@xsai/shared': 0.1.3 - '@xsai/shared-chat': 0.1.3 - xsschema: 0.1.3(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)))(zod-to-json-schema@3.24.4(zod@3.24.2)) + '@xsai/shared': 0.2.0-beta.1 + '@xsai/shared-chat': 0.2.0-beta.1 + xsschema: 0.2.0-beta.1(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)))(zod-to-json-schema@3.24.4(zod@3.24.2)) transitivePeerDependencies: - '@valibot/to-json-schema' - arktype + - effect - zod-to-json-schema '@xsai/utils-chat@0.1.3': dependencies: - '@xsai/shared-chat': 0.1.3 + '@xsai/shared-chat': 0.2.0-beta.1 abbrev@1.1.1: optional: true @@ -21296,6 +21342,8 @@ snapshots: meshoptimizer@0.18.1: {} + meta-png@1.0.6: {} + methods@1.1.2: {} micromark-core-commonmark@2.0.2: @@ -21903,6 +21951,7 @@ snapshots: transitivePeerDependencies: - '@valibot/to-json-schema' - arktype + - effect - zod-to-json-schema next-tick@1.1.0: {} @@ -24531,9 +24580,9 @@ snapshots: '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.36.0) '@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2)) - unplugin-combine@1.2.1(esbuild@0.25.0)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)): + unplugin-combine@1.2.1(esbuild@0.19.12)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)): optionalDependencies: - esbuild: 0.25.0 + esbuild: 0.19.12 rollup: 2.79.1 unplugin: 1.16.1 vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0) @@ -24592,7 +24641,7 @@ snapshots: transitivePeerDependencies: - vue - unplugin-vue-macros@2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.25.0)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)): + unplugin-vue-macros@2.14.5(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2)))(esbuild@0.19.12)(rollup@2.79.1)(typescript@5.8.2)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0))(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)): dependencies: '@vue-macros/better-define': 1.11.4(vue@3.5.13(typescript@5.8.2)) '@vue-macros/boolean-prop': 0.5.5(vue@3.5.13(typescript@5.8.2)) @@ -24624,7 +24673,7 @@ snapshots: '@vue-macros/short-vmodel': 1.5.5(vue@3.5.13(typescript@5.8.2)) '@vue-macros/volar': 0.30.15(typescript@5.8.2)(vue-tsc@3.0.0-alpha.2(typescript@5.8.2))(vue@3.5.13(typescript@5.8.2)) unplugin: 1.16.1 - unplugin-combine: 1.2.1(esbuild@0.25.0)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)) + unplugin-combine: 1.2.1(esbuild@0.19.12)(rollup@2.79.1)(unplugin@1.16.1)(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(terser@5.17.6)(tsx@4.19.3)(yaml@2.7.0)) unplugin-vue-define-options: 1.5.5(vue@3.5.13(typescript@5.8.2)) vue: 3.5.13(typescript@5.8.2) transitivePeerDependencies: @@ -25430,6 +25479,11 @@ snapshots: '@valibot/to-json-schema': 1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)) zod-to-json-schema: 3.24.4(zod@3.24.2) + xsschema@0.2.0-beta.1(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)))(zod-to-json-schema@3.24.4(zod@3.24.2)): + optionalDependencies: + '@valibot/to-json-schema': 1.0.0-rc.0(valibot@1.0.0-beta.9(typescript@5.8.2)) + zod-to-json-schema: 3.24.4(zod@3.24.2) + xtend@4.0.2: {} xxhash-wasm@0.4.2: {}