🧩 JavaScript API

已发布 2026-03-12

Since v0.75.0

📖 概述

Tavo JavaScript API 是面向玩家及创作者提供的一套 JavaScript 接口,以方便用户在开启 JavaScript 支持时可以获得强大的功能和高可玩性。

导入辅助角色卡

我们建议初学者使用以下角色卡,以便快速查看各 API 的使用例子。

可以直接在 “从 URL 导入角色” 处粘贴此URL:

https://type.tavo.cc/static/images/Tavo_JS_API_v0_7.png

或是下载以下角色卡图片,并通过文件导入:

Tavo JS API Guide
Tavo JS API Guide

⚙️ 变量

变量用于存储数据,JavaScript 本身的变量只能存活于页面中,一旦刷新就会丢失,因此我们提供一组变量 API 来协助用户长期存储数据。

获取变量

tavo.get(<name>[, <scope>])

例如:

let age = tavo.get('age')  // 获取聊天变量中的 age
let bestScore = tavo.get('bestScore', 'global')  // 获取全局最高分
let lover = tavo.get('lover', 'character')  // 获取当前角色的爱人

设置变量

tavo.set(<name>, <value>[, <scope>])

例如:

tavo.set('age', 16)  // 设置聊天变量 age = 16
tavo.set('Lily_lover', 'Colin', 'global')  // 设置全局变量,Lily 的爱人为 Colin
tavo.set('status', { hp: 100, mp: 32, location: 'Cave' })  // 设置当前聊天的状态为:生命值 100,魔法值 32,地点 洞穴

删除变量

tavo.unset(<name>[, <scope>])

例如:

tavo.set('age', 16)  // age = 16
tavo.unset('age')  // age = null

变量路径

当操作变量时,我们支持路径形式,例如:

tavo.set('status', { hp: 100, mp: 50 })
tavo.get('status.hp')  // 100
tavo.unset('status.hp')  // status = { mp: 50 }

在提示词中使用变量

可以通过提示词将变量发给模型,只需要在提示词中使用 宏 (macros) 即可:

{{getvar::<name>}} 获取变量(作用域为 chat,当前聊天) {{getglobalvar::<name>}} 获取变量(作用域为 chat,全局)

例如:

{{char}} 有了一个新名字 {{getvar::name}}
{{user}} 当前生命值 {{getvar::status.hp}}
全局历史最高分 {{getglobalvar::highestScore}}

更多的变量宏请参考

#变量
/welcome/supported-macros/#变量


💬 消息

Since v0.78.0

可以通过此接口读取或改变消息,所有消息接口均为 tavo.message.<method>(...)

查找消息

await tavo.message.find(<indexRange>[, <filter>])

按照楼层范围 indexRange 和过滤器 filter 查找消息,返回值为数组,其中:

indexRange 类型 number | array: 楼层范围

  • 当为 number 类型时:
    1. 获取指定楼层消息
    2. 楼层从 0 开始,第一条消息为 0,第二条消息为 1……以此类推
    3. 支持负数从尾部开始计算楼层, -1 为最后一条,-2 为倒数第二条……以此类推
  • 当为 array 类型时:
    1. [start, end] 例如 [2, 4],会取出第 2、3、4 条记录(双侧闭区间)
    2. [start] 代表从 start 开始到最后
    3. [0, end] 代表从第 0 条开始到 end
    4. [] | null | undefined 代表全部楼层
  • 无论何种参数,总是返回数组,若指定楼层不存在,返回空数组 []

filter 类型 object: 过滤条件

  • role 类型 string 按角色过滤,可选值(默认为所有):
    1. 'system' 系统消息
    2. 'assistant' 角色消息
    3. 'user' 用户消息
  • hidden 类型 boolean 是否包含隐藏消息,可选值(默认为所有):
    1. true 仅包含隐藏消息
    2. false 仅包含非隐藏消息
  • characters 类型 array 角色 ID 数组,仅过滤传入的角色发出的消息

消息格式为:

{
  id: 2338,  // 消息 ID
  characterId: 34,  // 角色 ID(仅 assistant 消息会有)
  content: 'Hello!',  // 消息内容
  hidden: false,  // 是否是隐藏消息
  role: 'assistant'  // 消息角色
}

例如:

await tavo.message.find(2)  // 获取第 3 层的消息
await tavo.message.find([3, 100])  // 获取第 3-100 条消息,若总共只有 50 层,则返回 3-50 层
await tavo.message.find(-1, { role: 'user' })  // 用户发的最后一层消息
await tavo.message.find([10], { hidden: false })  // 未隐藏的消息,楼层 >= 10 的所有消息

获取单条消息

await tavo.message.get(<messageId>)

按消息 ID 获取单条消息,若 ID 无效或消息不存在则返回 null

let msg = await tavo.message.get(2338)  // 获取 ID 为 2338 的消息

获取当前消息

await tavo.message.current()

获取执行此代码所在的那条消息对象,字段与上文「消息格式」及 tavo.message.get 一致。

典型用途:读取本条消息上的角色信息(tavo.character.get(currentMessage.characterId)),或是修改本条消息(调用 tavo.message.update 写回)。

const self = await tavo.message.current()
console.log(self)

获取消息总数

await tavo.message.count()

获取当前聊天中的消息总数(包含隐藏消息)。一般用来定位最后一条的楼层,第一条楼层为 0,最后一条楼层为 消息总数 - 1

let lastIndex = await tavo.message.count() - 1
console.log(lastIndex)

追加消息

await tavo.message.append(<message>)

在当前聊天末尾追加一条消息,成功返回新消息 ID,失败返回 null

message 类型 object,常见字段:

  • content 类型 string:消息内容(必填)
  • role 类型 string'assistant' | 'user'(默认按 'assistant' 处理),角色消息还是用户消息
  • characterId 类型 number:当 role = 'assistant' 时可指定发言角色 ID(单聊中可不传,群聊必传)
  • hidden 类型 boolean:是否为隐藏消息(默认 false

注意:

  1. role = 'assistant' 且未传 characterId 时,会按当前会话上下文自动推断角色
  2. 若无法推断角色,或角色不属于当前聊天,会创建失败并返回 null

例如:

let newId = await tavo.message.append({
  role: 'assistant',
  characterId: 34,
  content: '这是追加的一条消息',
  hidden: false,
})

单聊中创建非隐藏消息时,可简化为:

let newId = await tavo.message.append({
  content: '这是追加的一条消息。role 默认为 assistant ,即角色消息;单聊时自动推断角色;hidden 默认为 false',
})

更新消息

await tavo.message.update(<message>)

按消息 ID 更新一条已有消息,成功返回消息 ID,失败返回 null

message 类型 object,常见字段:

  • id 类型 number:要更新的消息 ID(必填)
  • content 类型 string:更新后的消息内容(必填)
  • reasoning 类型 string:推理内容(可选,传空字符串会清空)
  • hidden 类型 boolean:是否隐藏(可选,默认按 false 处理)
const lastMessage = (await tavo.message.find(-1))[0]  // 获得最后一层的消息 (参见 tavo.message.find 说明)
lastMessage.content = '更新后的内容'
lastMessage.reasoning = '可选推理内容'
lastMessage.hidden = true  // 改为隐藏消息
await tavo.message.update(lastMessage)  // 更新最后一条消息

删除消息

await tavo.message.delete(<messageId>)

按消息 ID 删除消息,成功返回被删除的消息 ID,失败返回 null

const count = await tavo.message.count();  // 获得总消息数
const midIndex = Math.floor(count / 2);
const midMessage = (await tavo.message.find(midIndex))[0]  // 获得中间一条消息
await tavo.message.delete(midMessage.id)  // 删除中间那条消息

🗨️ 聊天

可以通过此接口获取当前聊天信息,所有聊天接口均为 tavo.chat.<method>(...)

获取当前聊天

await tavo.chat.current()

获取当前正在进行的聊天信息,若当前没有聊天则返回 null

例如:

let chat = await tavo.chat.current()
console.log(chat.name)        // 打印当前聊天名称
console.log(chat.characters[0]?.name)  // 打印第一个角色名称
console.log(chat.persona?.name)        // 打印当前用户身份名称(若有)

更新当前聊天

await tavo.chat.update(<chat>)

更新当前聊天。

可更新字段:

  • name:聊天标题
  • characters:角色 ID 数组(会直接替换当前聊天角色列表)
  • persona:用户身份 ID
await tavo.chat.update({
  name: '新的聊天标题',
  characters: [12, 34],
  persona: 5,
})

注意:该接口仅更新“当前聊天”,不支持按聊天 ID 更新其他会话。

聊天对象字段

聊天对象(current 返回)包含以下常见字段:

{
  id: 1,                    // 聊天 ID
  name: '与爱丽丝的对话',    // 聊天名称
  characters: [             // 聊天中的角色概要列表
    {
      id: 12,
      name: 'Alice',
      avatar: 'alice.png'
    },
    {
      id: 7,
      name: 'Lee',
      avatar: 'lee.png'
    },
  ],
  persona: {                // 当前使用的用户身份概要(可能为 null)
    id: 5,
    name: '默认用户身份',
  },
  preset: {                 // 当前使用的预设概要
    id: 9,
    name: '默认预设',
  },
  lorebooks: [{
    id: 17,
    name: '不夜城',
  }],
  regexes: [{               // 当前启用的正则概要列表
    id: 3,
    name: '移除舞台提示',
  }],
}

🧙 角色

可以通过此接口管理角色,所有角色接口均为 tavo.character.<method>(...)

获取所有角色概要

await tavo.character.all()

返回角色概要对象数组(每项仅包含 idnameavatar 等概要信息):

let chars = await tavo.character.all()
console.log(chars[0].id)     // 例如 12
console.log(chars[0].avatar) // 例如 "chara/alice.png"
console.log(chars[0].name)   // 例如 "Alice"

获取单个角色

await tavo.character.get(<characterId>)

按角色 ID 获取角色对象,不存在时返回 null

let char = await tavo.character.get(12)
if (char) {
  console.log(char.name)
}

按名称查找角色

await tavo.character.find(<name>[, <options>])

按名称查找角色,返回角色对象数组。options.match 可选:'exact' | 'prefix' | 'suffix' | 'contains'(默认 'exact'

let chars = await tavo.character.find('Alice')
let chars2 = await tavo.character.find('Ali', { match: 'prefix' })
console.log(chars.length)

新建角色

await tavo.character.create(<character>)

创建角色并返回新角色 ID。character.namecharacter.first_mes 为必填项。

let id = await tavo.character.create({
  name: 'Alice',
  first_mes: '你好,我是 Alice。',
  description: '一位温柔的向导',
})

更新角色

await tavo.character.update(<character>)

更新角色并返回角色 ID。character.idcharacter.namecharacter.first_mes 为必填项。

await tavo.character.update({
  id: 12,
  name: 'Alice',
  first_mes: '你好,我是 Alice。',
  personality: '耐心、细致',
})

删除角色

await tavo.character.delete(<characterId>)

按角色 ID 删除角色:

await tavo.character.delete(12)
await tavo.character.delete(char)  // char 需要时带 id 的角色对象

角色对象字段

角色对象(get / find 返回)包含以下常见字段:

{
  id: 12,  // 角色的唯一ID
  avatar: 'xxx.png',  // 角色头像图片URL或路径
  name: 'Alice',  // 角色名称(必填)
  description: '...',  // 角色简介/描述
  first_mes: '...',  // 角色打招呼内容(必填)
  personality: '...',  // 角色性格描述
  scenario: '...',  // 适用场景或使用场景描述
  mes_example: '...',  // 消息示例,以 <START> 分割
  creator_notes: '...',  // 创建者注释或补充说明
  system_prompt: '...',  // 系统提示词
  post_history_instructions: '...',  // 信息上下文历史后的额外提示或说明
  alternate_greetings: ['...'],  // 角色可用的备用打招呼
  tags: ['guide'],  // 角色标签,用于分类或检索
  creator: 'Colin',  // 创建者用户名或昵称
  character_version: '1.0',  // 角色版本号
  nickname: 'Ali',  // 角色昵称或别名,如果填写了将替代 name 作为 {{char}} 的输出
  group_only_greetings: ['...'],  // 仅限群聊使用的特定打招呼语
  creation_date: new Date('2026-03-05T10:20:30.000Z'),  // 创建时间(Date对象)
  modification_date: new Date('2026-03-05T11:30:00.000Z'),  // 最后修改时间(Date对象)
}

说明:创建、更新、删除角色时会弹出确认框,用户取消后操作不会生效。


🎭 用户身份

可以通过此接口管理用户身份,所有用户身份接口均为 tavo.persona.<method>(...)

获取所有用户身份概要

await tavo.persona.all()

返回用户身份概要对象数组(每项包含 idname):

let personas = await tavo.persona.all()
console.log(personas[0].id)    // 例如 5
console.log(personas[0].name)  // 例如 "默认用户身份"

获取单个用户身份

await tavo.persona.get(<personaId>)

按用户身份 ID 获取用户身份对象,不存在时返回 null

let persona = await tavo.persona.get(5)
if (persona) {
  console.log(persona.name)
  console.log(persona.description)
}

按名称查找用户身份

await tavo.persona.find(<name>[, <options>])

按名称查找用户身份,返回用户身份对象数组。options.match 可选:'exact' | 'prefix' | 'suffix' | 'contains' (默认 'exact'

let personas = await tavo.persona.find('默认')
let personas2 = await tavo.persona.find('默', { match: 'prefix' })
console.log(personas.length)

新建用户身份

await tavo.persona.create(<persona>)

创建用户身份并返回新用户身份 ID。persona.namepersona.description 为必填项。

let id = await tavo.persona.create({
  name: '侦探用户身份',
  description: '注重细节,擅长结构化推理。',
  avatar: 'chara/persona-detective.png',
})

更新用户身份

await tavo.persona.update(<persona>)

更新用户身份。persona.idpersona.namepersona.description 为必填项。

await tavo.persona.update({
  id: 5,
  name: '默认用户身份',
  description: '语气更简洁,优先给出可执行结论。',
  avatar: 'chara/persona-default.png',
  active: true,
})

删除用户身份

await tavo.persona.delete(<personaId>)

按用户身份 ID 删除用户身份:

await tavo.persona.delete(5)
await tavo.persona.delete(persona)  // persona 需要是带 id 的用户身份对象

用户身份对象字段

用户身份对象(get 返回)包含以下常见字段:

{
  id: 5,  // 用户身份唯一 ID
  name: '默认用户身份',  // 用户身份名称(必填)
  description: '...',  // 用户身份描述(必填)
  avatar: 'xxx.png',  // 用户身份头像 URL 或路径(可选)
  active: true,  // 是否为默认用户身份
  sortIndex: 12,  // 排序索引
}

🎛️ 预设

可以通过此接口管理预设,所有预设接口均为 tavo.preset.<method>(...)

获取所有预设(摘要)

await tavo.preset.all()

返回预设摘要对象数组(每项包含 idname):

let presets = await tavo.preset.all()
console.log(presets[0].id)    // 例如 1
console.log(presets[0].name)  // 例如 "Default"

获取单个预设

await tavo.preset.get(<presetId>)

按预设 ID 获取完整预设对象,不存在时返回 null

let preset = await tavo.preset.get(1)
if (preset) {
  console.log(preset.name)
  console.log(preset.entries.length)
  console.log(preset.basicPrompts.chatStart)
}

按名称查找预设

await tavo.preset.find(<name>[, <options>])

按名称查找预设,返回完整预设对象数组。options.match 可选:'exact' | 'prefix' | 'suffix' | 'contains' (默认 'exact'

let presets = await tavo.preset.find('Default')
let presets2 = await tavo.preset.find('Def', { match: 'prefix' })
console.log(presets.length)

新建预设

await tavo.preset.create(<preset>)

创建预设并返回新预设 ID。preset.name 为必填项,其余字段可选;preset.basicPromptspreset.entries 中缺失的部分将自动填充默认值。

let id = await tavo.preset.create({
  name: '我的预设',
  basicPrompts: {
    continueNudge: '[继续你的上一条消息,不要重复原有内容。]',
  },
  entries: [
    {
      identifier: 'abc123',
      name: '🌸 文风控制',
      content: '采用精致优雅的叙事风格,类似晋江、长佩等平台受欢迎的高质量女性向作品。',
    },
  ],
})

更新预设

await tavo.preset.update(<preset>)

更新预设。preset.id 为必填项。传入的 entries 会直接覆盖原有的 entries,典型用法是先 get 取出,修改后再 update 写回。

const preset = await tavo.preset.get(33);
preset.entries.find(e => e.identifier == 'main').content = '请用中文回复 {{user}} 的所有问题。';
await tavo.preset.update(preset)

删除预设

await tavo.preset.delete(<presetId>)

按预设 ID 删除预设:

await tavo.preset.delete(1)
await tavo.preset.delete(preset)  // preset 需要是带 id 的预设对象

预设对象字段

完整预设对象(get / find 返回)包含以下字段:

{
  id: 1,          // 预设唯一 ID
  name: 'Default', // 预设名称(必填)
  basicPrompts: { /* BasicPrompts,见下 */ },
  entries: [],    // PresetEntry[] 提词条目列表(见下)
}

基础提词字段(BasicPrompts)

basicPrompts 包含各类系统提词模板,所有字段均可选,缺省时使用内置默认值:

{
  persona: '{{persona}}',        // 用户身份描述的格式模板
  description: '{{description}}', // 角色描述的格式模板
  personality: '{{personality}}', // 角色性格的格式模板(用 {{personality}} 标记插入位置)
  scenario: '{{scenario}}',      // 场景的格式模板(用 {{scenario}} 标记插入位置)
  exampleMessageStart: '[Example Chat]',  // 示例对话起始标记
  chatStart: '[Start a new Chat]',        // 聊天历史起始标记
  groupChatStart: '[Start a new group chat. Group members: {{group}}]',  // 群聊起始标记
  groupNudge: '[Write the next reply only as {{char}}.]',  // 群聊中催促指定角色回复的提词
  continueNudge: '[Continue your last message without repeating its original content.]',  // 续写按钮的提词
  impersonation: '[Write your next reply from the point of view of {{user}}...]',  // 扮演用户时的提词
  lorebook: '{0}',  // 世界书条目的包装模板(用 {0} 标记内容插入位置)
}

提词条目字段(PresetEntry)

entries 数组中每一项的结构:

{
  // ── 基本信息 ──────────────────────────────────
  identifier: 'main',   // 条目唯一标识(内置条目有固定 identifier,见下表)
  name: 'Main Prompt',  // 条目显示名称
  content: '...',       // 提词正文(marker 类型无此字段)
  enabled: true,        // 是否启用此条目(在激活列表中是否生效)
  active: true,         // 是否加入激活列表(false 时条目仅存档,不参与提示词构建)

  // ── 类型 ──────────────────────────────────────
  type: 'custom',       // 条目类型:
                        //   'builtin' - 内置提词(固定 identifier,如 main / jailbreak)
                        //   'marker'  - 位置标记(无内容,仅标记其他内容的插入位置)
                        //   'custom'  - 自定义提词

  // ── 角色与注入(custom 类型可配置)──────────────
  role: 'system',       // 消息角色:'system' | 'user' | 'assistant'
  injectionPosition: 'relative',  // 注入位置:
                                  //   'relative' - 相对位置(跟随预设列表顺序)
                                  //   'absolute' - 绝对位置(插入到聊天历史的特定深度)
  injectionDepth: 4,   // 注入深度,仅 injectionPosition 为 'absolute' 时生效
                        // 0 = 最后一条消息之后,1 = 最后一条消息之前,以此类推
}

内置条目 identifier 列表

以下 identifier 对应系统内置的固定提词或位置标记,创建 / 更新时可直接引用:

identifier 名称 类型 说明
main Main Prompt builtin 主提词,对话的核心指令
worldInfoBefore Lorebook Before marker 世界书(角色描述上方)插入点
personaDescription Persona Description marker 用户身份描述插入点
charDescription Char Description marker 角色描述插入点
charPersonality Char Personality marker 角色性格插入点
scenario Scenario marker 场景描述插入点
enhanceDefinitions Enhance Definitions builtin 增强角色定义的补充提词
nsfw Auxiliary Prompt builtin 辅助提词(默认为空)
worldInfoAfter Lorebook After marker 世界书(角色描述下方)插入点
dialogueExamples Chat Examples marker 示例对话插入点
chatHistory Chat History marker 聊天历史插入点
jailbreak Post-History Instructions builtin 历史记录后的补充指令

📚 世界书

可以通过此接口管理世界书,所有世界书接口均为 tavo.lorebook.<method>(...)

获取所有世界书概要

await tavo.lorebook.all()

返回世界书概要对象数组(每项包含 idnameentries):

let lorebooks = await tavo.lorebook.all()
console.log(lorebooks[0].id)       // 例如 3
console.log(lorebooks[0].name)     // 例如 "城市设定"
console.log(lorebooks[0].entries)  // 例如 12(条目数量)

获取单个世界书

await tavo.lorebook.get(<lorebookId>)

按世界书 ID 获取对象,不存在时返回 null

let lorebook = await tavo.lorebook.get(3)
if (lorebook) {
  console.log(lorebook.name)
  console.log(lorebook.entries.length)
}

按名称查找世界书

await tavo.lorebook.find(<name>[, <options>])

按名称查找世界书,返回世界书对象数组。options.match 可选:'exact' | 'prefix' | 'suffix' | 'contains' (默认 'exact'

let lorebooks = await tavo.lorebook.find('城市')
let lorebooks2 = await tavo.lorebook.find('城市', { match: 'suffix' })
console.log(lorebooks.length)

新建世界书

await tavo.lorebook.create(<lorebook>)

创建世界书并返回新世界书 ID。lorebook.name 为必填项。

let id = await tavo.lorebook.create({
  name: '城市设定',
  entries: [],
})

更新世界书

await tavo.lorebook.update(<lorebook>)

更新世界书。lorebook.idlorebook.name 为必填项。

await tavo.lorebook.update({
  id: 3,
  name: '城市设定(重制)',
  entries: [],
})

删除世界书

await tavo.lorebook.delete(<lorebookId>)

按世界书 ID 删除世界书:

await tavo.lorebook.delete(3)
await tavo.lorebook.delete(lorebook)  // lorebook 需要是带 id 的世界书对象

世界书对象字段

世界书对象(get / find 返回)包含以下字段:

{
  id: 3,           // 世界书唯一 ID
  name: '城市设定', // 世界书名称(必填)
  entries: [],     // LorebookEntry[] 条目列表(见下)
}

条目对象字段(LorebookEntry)

entries 数组中每一项的结构:

{
  // ── 基本信息 ──────────────────────────────────
  identifier: 'entry-uuid',  // 条目唯一标识(字符串)
  name: '城市总览',            // 条目名称(仅供显示和搜索)
  content: '这是一座临海城市,夜间常有浓雾。',  // 注入到提示词的正文内容
  enabled: true,             // 是否启用此条目
  strategy: 'constant',      // 触发策略:'constant'(常驻)| 'keyword'(关键词触发)

  // ── 关键词 ─────────────────────────────────────
  keywords: ['城市', '港口'],         // 主关键词列表(strategy 为 'keyword' 时生效)
  secondaryKeywords: ['夜晚', '雾'],  // 次级关键词列表
  secondaryKeywordStrategy: 'none',  // 次级关键词匹配策略:
                                     //   'none'   - 不启用次级关键词
                                     //   'andAny' - 主词命中且任意次级词命中(默认)
                                     //   'andAll' - 主词命中且全部次级词命中
                                     //   'notAny' - 主词命中且没有次级词命中
                                     //   'notAll' - 主词命中且不是全部次级词命中
  scanDepth: 2,              // 关键词扫描的消息深度(默认 2,最大 1000)
  caseSensitive: false,      // 关键词是否区分大小写
  matchWholeWord: true,      // 是否全词匹配

  // ── 注入位置 ───────────────────────────────────
  injectionPosition: 'lorebookBefore',  // 注入位置:
                                        //   'lorebookBefore'         - 角色描述上方(↑Char)
                                        //   'lorebookAfter'          - 角色描述下方(↓Char)
                                        //   'topOfExampleMessages'   - 示例对话之前
                                        //   'bottomOfExampleMessages'- 示例对话之后
                                        //   'atDepth'                - 聊天历史的绝对深度位置
  injectionDepth: 4,         // 注入深度,仅 injectionPosition 为 'atDepth' 时生效
  injectionRole: 'system',   // 注入角色:'system' | 'user' | 'assistant'

  // ── 概率与行为 ─────────────────────────────────
  probability: 100,  // 激活概率(0–100,默认 100)
  sticky: 0,         // 激活后持续保持的消息轮数(0 表示不持续)
  cooldown: 0,       // 激活一次后的冷却轮数(0 表示无冷却)
  delay: 0,          // 延迟激活的消息轮数(0 表示立即)
}

🎨 正则

可以通过此接口管理正则组(一组查找/替换规则),所有正则接口均为 tavo.regex.<method>(...)

获取所有正则(摘要)

await tavo.regex.all()

返回正则摘要对象数组(每项包含 idnameentries,其中 entries规则条数,不是条目数组):

let list = await tavo.regex.all()
console.log(list[0].id)       // 例如 2
console.log(list[0].name)     // 例如 "我的正则"
console.log(list[0].entries)  // 例如 5(条规则数量)

获取单个正则

await tavo.regex.get(<regexId>)

按 ID 获取完整正则对象,不存在时返回 null

let r = await tavo.regex.get(2)
if (r) {
  console.log(r.name)
  console.log(r.entries.length)
}

按名称查找正则

await tavo.regex.find(<name>[, <options>])

按名称查找正则,返回完整正则对象数组。options.match 可选:'exact' | 'prefix' | 'suffix' | 'contains' (默认 'exact'

let found = await tavo.regex.find('我的')
let found2 = await tavo.regex.find('我的', { match: 'contains' })
console.log(found.length)

新建正则

await tavo.regex.create(<regex>)

创建正则并返回新 ID。regex.name 为必填;regex.entries 为规则数组,可省略(视为空列表)。创建 / 更新前会弹出确认对话框。

let id = await tavo.regex.create({
  name: 'Demo 正则',
  entries: [
    {
      name: '状态栏',
      findRegex: '/<status>(.*?)<\/status>/gim',
      replaceString: '<pre>$1</pre>',
      placements: ['char'],
      timing: 'display',
    },
  ],
})

更新正则

await tavo.regex.update(<regex>)

更新正则。regex.idregex.name 均为必填(前端封装会校验)。典型用法:get → 修改 → update

const r = await tavo.regex.get(2)
r.entries[0].enabled = false
await tavo.regex.update(r)

删除正则

await tavo.regex.delete(<regexId>)

按 ID 删除;也可传入带 id 的正则对象:

await tavo.regex.delete(2)
await tavo.regex.delete({ id: 2 })

正则对象字段

完整对象(get / find 返回)结构:

{
  id: 2,
  name: '我的正则',
  entries: [ /* RegexEntry[],见下 */ ],
}

规则条目字段(RegexEntry)

entries 中每一项:

{
  name: '规则显示名',             // 必填(字符串),否则解析可能失败
  findRegex: 'pattern',          // 查找用正则(可支持 JavaScript 正则类似的 `/pattern/flags` 写法)
  replaceString: '',             // 替换为的字符串
  trimStrings: [],               // 额外要裁剪的字符串列表
  placements: ['char'],          // 作用位置,可多选:
                                 //   'user'      - 用户输入
                                 //   'char'      - AI 输出
                                 //   'reasoning' - 推理内容
                                 //   'lorebook'  - 世界书注入内容
  timing: 'display',           // 执行时机:
                                 //   'display'         - 仅显示时(不写入持久消息,类似 ST markdownOnly)
                                 //   'send'            - 仅发送进模型前
                                 //   'sendAndDisplay'  - 显示与发送都执行
                                 //   'receive'         - 收到回复后持久化(仅输入/输出相关)
                                 //   'editAndReceive'  - 收到与编辑消息时都会持久化改写
  substitution: 'none',        // 宏替换方式:'none' | 'raw' | 'escaped'
  minDepth: null,              // 可选,消息深度下限(整数)
  maxDepth: null,              // 可选,消息深度上限(整数)
  enabled: true,               // 是否启用该条规则
}

省略字段时,端侧会为 findRegexreplaceStringtrimStringsplacementstimingsubstitutionenabled 等填入合理默认值(例如 placements: ['char']timing: 'display')。


🧠 长记忆

可以通过此接口读取或修改当前聊天的长期记忆(Long-term Memory),所有接口均为 tavo.memory.<method>(...)

获取当前记忆

await tavo.memory.current()

获取当前聊天记忆对象:

const memory = await tavo.memory.current()
console.log(memory.enabled)         // true / false
console.log(memory.memories.length) // 记忆条数

更新记忆

await tavo.memory.update(<memory>)

更新当前聊天记忆并返回更新后的对象。可更新字段:

  • enabled:是否启用记忆
  • memories:记忆文本数组(string[]
const memory = await tavo.memory.current()

memory.enabled = true
memory.memories = [
  '用户喜欢简洁、结论先行的回答风格',
  '用户倾向于让角色保持冷静和专业',
]

const updated = await tavo.memory.update(memory)
console.log(updated)

记忆对象字段

current / update 返回对象结构:

{
  id: 12,  // 记忆记录 ID
  enabled: true,  // 是否启用长期记忆
  memories: [     // 记忆条目列表(字符串数组)
    '用户偏好简洁回复',
    '避免重复解释已确认信息'
  ],
}

生成请求

可以通过此接口直接触发一次文本生成,所有生成接口均为 tavo.generate(...)

发起生成

await tavo.generate(<prompt>, <options>)

  • prompt 类型 string:本次生成的用户输入内容
  • options 类型 object:生成选项(若无额外配置,传空对象 {}

返回值类型为 string,即模型生成的文本内容。

const result = await tavo.generate('请用一句话总结今天发生的事情', {})
console.log(result)

options 字段

options 支持以下字段:

  • context 类型 boolean(默认 false):
    1. true:带当前对话上下文生成(沿用当前聊天状态)
    2. false:与当前对话无关的AI生成请求(默认)
  • preset 类型 number | object(可选):
    1. 直接传预设 ID,例如 12
    2. 传对象时仅识别 id,例如 { id: 12 }
  • settings 类型 object(可选):覆盖本次请求的模型参数

示例:

const text = await tavo.generate(
  '根据最近对话,给我 3 条行动建议',
  {
    context: true,
    preset: { id: 8 },
    settings: {
      temperature: 0.7,
      topP: 0.9,
      maxCompletionTokens: 300,
    },
  },
)

console.log(text)

注意事项

  • 该接口为一次性请求,返回完整文本,不返回流式分片
  • 生成请求会使用当前聊天绑定的模型端点;若当前聊天无可用端点,则返回 null

使用示例

将以下内容复制到气泡中,以观察效果:

<h3>生成请求 API 演示</h3>
<pre id="log" style="background: #0006; font-size: 12px; padding: 1em 1.5em; min-height: 80px; max-height: 300px; overflow-y: auto;"></pre>
<button id="btn-generate" onclick="generate()">生成角色卡</button>
<p id="status"></p>
<div id="actions" style="display:none; gap:8px;">
  <button onclick="downloadJson()">下载 JSON 文件</button>
  <button onclick="createCharacter()">直接创建角色卡</button>
</div>
<script>
let generatedCard = null;
const log = (...args) => {
  const text = args.map(v => typeof v === 'string' ? v : JSON.stringify(v, null, 2)).join(' ');
  document.getElementById('log').textContent = text + '\n\n';
};
function setUi(loading, status, showActions = false) {
  document.getElementById('btn-generate').disabled = loading;
  document.getElementById('status').textContent = status;
  document.getElementById('actions').style.display = showActions ? 'flex' : 'none';
}
async function generate() {
  const p = prompt('请输入想要生成的角色特点');
  if (!p) return;
  setUi(true, '生成中...');
  try {
    let text = await tavo.generate(`根据以下信息生成一张角色卡,输出符合 Character Card Spec V3 规范的JSON格式\n${p}`);
    log(text)
    text = text.trim();
    if (text.startsWith('```') && text.endsWith('```')) {
      text = text.replace(/^```[a-zA-Z]*\n?/, '').replace(/```$/, '');
    }
    generatedCard = JSON.parse(text);
    if (generatedCard.mes_example instanceof Array) generatedCard.mes_example = generatedCard.mes_example.join('\n')
    setUi(false, `角色卡 《${generatedCard.name}》 已生成`, true);
  } catch (e) {
    log(e);
    console.log(e);
    setUi(false, `角色卡生成失败`, false)
  }
}
function downloadJson() {
  tavo.utils.export(`${generatedCard.name}.json`, JSON.stringify(generatedCard));
}
async function createCharacter() {
  await tavo.character.create(generatedCard);
}
</script>

⌨️ 输入框

可以通过此接口读取或操作聊天输入框,所有输入框接口均为 tavo.input.<method>(...)

读取输入框

await tavo.input.get()

获取当前输入框中的文本内容:

let text = await tavo.input.get()  // 获取当前输入框内容

写入输入框

tavo.input.set(<text>)

覆盖写入输入框内容(会清除原有内容):

tavo.input.set('你好!')  // 将输入框内容替换为"你好!"

追加到输入框

tavo.input.append(<text>)

在输入框现有内容末尾追加文本:

tavo.input.append(' 继续聊吧')  // 在原有内容后追加文字

清空输入框

tavo.input.clear()

清空输入框内容:

tavo.input.clear()

发送消息

tavo.input.send()

触发发送当前输入框中的消息:

tavo.input.set('今天天气不错')
tavo.input.send()  // 自动发送

🛠️ 工具

通用工具接口,所有工具接口均为 tavo.utils.<method>(...)

轻量提示

tavo.utils.toast(<text>)

显示一个轻量 toast 提示,数秒后自动消失

打开链接

tavo.utils.openUrl(<url>)

在外部浏览器中打开一个 URL:

tavo.utils.openUrl('https://example.com')

导出文件

tavo.utils.export(<name>, <data>)

将数据导出为文件并触发系统分享/保存。data 可以是 Base64 编码的内容(推荐)或普通文本字符串:

tavo.utils.export('叶离角色卡', btoa('这是一段文本或二进制,调用 btoa 转化为 base64'))  // 传 base64 数据(推荐)
tavo.utils.export('record.txt', '这是一段文本内容')  // 普通文本

📱 App

可以通过此接口读取或操作一些应用属性,所有接口均为 tavo.app.<method>(...)

获得当前 app 版本

await tavo.app.version();  // 字符串:0.77.0
await tavo.app.versionNumber();  // 数字: 770