ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Operit 角色卡脚本接口全解析:Tools.SoftwareSettings 九大管理工具与 Operit Editor 的同步实现

2026/9/28 21:03:34 拓冰建站 浏览量
Operit 角色卡脚本接口全解析:Tools.SoftwareSettings 九大管理工具与 Operit Editor 的同步实现 AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆【免费下载链接】OperitThe most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent项目地址https://gitcode.com/gh_mirrors/op/Operit点击查看免费下载本文基于 Operit 仓库中的《脚本接口与 Operit Editor》设计文档docs/TODO/character_card_software_settings_20260805/2_ScriptApiAndOperitEditor.md系统梳理 Operit 如何将原生角色卡管理能力通过 JavaScript 桥、严格 TypeScript 类型声明与内置operit_editor包三层暴露给脚本与 AI Agent。读完本文你将掌握Tools.SoftwareSettings上新增的 9 个角色卡接口的完整契约与参数语义、可编辑字段与受保护字段的边界划分、数组参数的两种合法表示形式以及examples/operit_editor.ts与两份 JavaScript 产物必须保持一致的同步机制可直接用于编写自己的角色卡管理与会话选卡脚本。背景脚本侧角色卡能力为何缺失在本次改造之前Operit 的角色卡能力存在明显的原生强、脚本弱断层原生层早已完备CharacterCardManager实现在 app/src/main/java/com/ai/assistance/operit/data/preferences/CharacterCardManager.kt已经支持角色卡的读取、创建、更新、删除、激活以及酒馆TavernJSON 的导入与导出脚本侧仅有一个只读入口Tools.Chat.listCharacterCards()返回的内容仅用于会话选卡缺少完整字段也不具备任何管理操作配置通道完全空白Tools.SoftwareSettings与operit_editor均不能管理角色卡examples/types/software_settings.d.ts中也没有角色卡相关类型。这意味着 AI Agent 和脚本包只能看角色卡列表却无法创建、编辑、删除、切换或导入导出角色卡。本次设计文档2_ScriptApiAndOperitEditor.md的核心目标正是把这套原生能力完整映射到脚本层并保证输入输出有严格的 TypeScript 类型约束。接口边界SoftwareSettings 管配置Chat 只管引用角色卡接口落位前设计文档docs/TODO/character_card_software_settings_20260805/index.md明确了两条边界原则职责划分SoftwareSettings负责角色卡配置本身Chat只在创建会话或发送消息时引用角色卡。因此新增的全部管理接口都挂在Tools.SoftwareSettings下而原有的Tools.Chat.listCharacterCards()继续保留会话工具保持原有调用方式不变在 ToolRegistration.kt 中仍以list_character_cards名称注册走chatManagerTool.listCharacterCards。写入接口只接受可编辑字段角色卡 ID、创建时间createdAt以及是否为默认角色卡isDefault等属性由角色卡管理器统一维护调用方不能通过更新接口改变它们。这一点在原生实现applyCharacterCardUpdates见下文中得到了严格贯彻。原生层 API 契约九个工具逐一对应配套文档 1_NativeCharacterCardTools.md 给出了原生工具的 API 契约StandardSoftwareSettingsModifyTools直接调用CharacterCardManager再由ToolRegistration注册为原生工具。九个接口的契约如下原生工具名功能关键参数返回要点list_character_cards_settings返回完整角色卡列表与当前活跃角色卡 ID无totalCount、activeCharacterCardId、cards[]get_character_card返回指定角色卡完整配置character_card_id必填单卡详情 activeCharacterCardIdcreate_character_card只接受可编辑字段创建新卡name必填等可编辑字段新卡详情 changedFieldsupdate_character_card按 ID 合并指定的可编辑字段character_card_id 可编辑字段更新后卡片 changedFieldsdelete_character_card删除非默认角色卡character_card_id必填被删除的 ID 当前活跃 IDset_active_character_card设置活跃角色卡character_card_id必填当前活跃角色卡 IDclear_active_character_card清除活跃角色卡状态无activeCharacterCardId nullimport_character_card_from_tavern_json从酒馆 JSON 导入单张角色卡tavern_json必填导入结果 新卡详情export_character_card_to_tavern_json将角色卡导出为酒馆 JSONcharacter_card_id必填characterCardIdtavernJson字符串原生层实现与调用链九个方法全部实现在 StandardSoftwareSettingsModifyTools.kt 中形成了一条清晰的调用链ToolRegistration.registerTool(name list_character_cards_settings, ...) └─ StandardSoftwareSettingsModifyTools.listCharacterCards(tool) // L1450 └─ CharacterCardManager.getAllCharacterCards() // CharacterCardManager.kt L690其它接口对应关系括号内为 Kotlin 源码行号为getCharacterCardL1479、createCharacterCardL1519、updateCharacterCardL1558、deleteCharacterCardL1611、setActiveCharacterCardL1662、clearActiveCharacterCardL1702、importCharacterCardFromTavernJsonL1721、exportCharacterCardToTavernJsonL1773。值得注意的防御性细节deleteCharacterCard会显式拦截默认角色卡返回The default character card cannot be deleted比较characterCardId CharacterCardManager.DEFAULT_CHARACTER_CARD_IDget/update/set_active/delete/export均通过requireCharacterCard校验卡片存在性不存在时抛出IllegalArgumentException并转为失败ToolResult导入导出复用CharacterCardManager.createCharacterCardFromTavernJsonL961与exportCharacterCardToTavernJsonL1066确保主题、Waifu 设置、自定义表情、聊天绑定与提示词标签等副作用仍由单一实现处理不会因脚本入口产生行为分叉。原生工具注册位于 ToolRegistration.ktlist_character_cards_settingsL703、get_character_cardL714、create_character_cardL726、update_character_cardL738、delete_character_cardL750、set_active_character_cardL762、clear_active_character_cardL774、import_character_card_from_tavern_jsonL783、export_character_card_to_tavern_jsonL794。所有 executor 均通过runBlocking(Dispatchers.IO)调用ToolGetter.getSoftwareSettingsModifyTools(context)上的对应方法。结构化结果类型原生层新增了一套完整的序列化结果类型定义在 ToolResultDataClasses.ktCharacterCardToolAccessConfigResultItemL2409工具访问白名单配置含enabled、allowedBuiltinTools、allowedPackages、allowedSkills、allowedMcpServersCharacterCardResultItemL2419单卡完整字段除上述配置外还包括id、name、description、characterSetting、openingStatement、otherContentChat、otherContentVoice、attachedTagIds、advancedCustomPrompt、marks、chatModelBindingMode、chatModelConfigId、chatModelIndex、memoryProfileBindingMode、memoryProfileId、isDefault、createdAt、updatedAtCharacterCardsResultDataL2443、CharacterCardResultDataL2455、CharacterCardCreateResultDataL2466含changedFields、CharacterCardUpdateResultDataL2479含changedFields、CharacterCardDeleteResultDataL2492、CharacterCardActivationResultDataL2504、CharacterCardImportResultDataL2514、CharacterCardExportResultDataL2526。其中changedFields字段是本次设计的亮点create_character_card与update_character_card会返回本次实际发生变更的字段名列表由applyCharacterCardUpdates中逐字段记录生成见 StandardSoftwareSettingsModifyTools.kt脚本可直接据此判断哪些参数真正生效。可编辑字段全集与数组参数约定写入接口create/update接受的全部可编辑字段如下严格对应 TypeScript 的CharacterCardWriteOptions定义于 examples/types/software_settings.d.ts字段类型说明namestring角色卡名称create 必填空白会报错descriptionstring简介character_settingstring角色设定提示词opening_statementstring开场白other_content_chatstring聊天附加内容other_content_voicestring语音附加内容attached_tag_idsstring | string[]标签 ID 数组支持 JSON 字符串数组表示advanced_custom_promptstring高级自定义提示词marksstring备注chat_model_binding_modeFOLLOW_GLOBAL \| FIXED_CONFIG对话模型绑定模式chat_model_config_idstring固定对话模型配置 ID空字符串清除绑定chat_model_indexnumber固定对话模型索引需 ≥ 0memory_profile_binding_modeFOLLOW_GLOBAL \| FIXED_PROFILE记忆配置绑定模式memory_profile_idstring固定记忆配置 ID空字符串清除绑定tool_access_enabledboolean启用角色卡工具白名单allowed_builtin_toolsstring | string[]内置工具名白名单allowed_packagesstring | string[]包名白名单allowed_skillsstring | string[]Skill 名称白名单allowed_mcp_serversstring | string[]MCP 服务名白名单数组参数字符串数组或其 JSON 字符串表示设计文档特别强调数组参数支持 string array 及其 JSON 字符串表示两种形式。原生解析函数parseStringArrayParameterStandardSoftwareSettingsModifyTools.kt通过JSONArray(raw)解析随后对每个元素做三项规范化要求元素必须是字符串、逐个trim()、过滤空串并去重。因此以下两种传法等价// 形式一JSON 字符串数组 await Tools.SoftwareSettings.updateCharacterCard(card-id-1, { allowed_skills: [web_search,code_runner] }); // 形式二原生字符串数组仅 JS 桥/editor 层支持由桥自动序列化 await Tools.SoftwareSettings.updateCharacterCard(card-id-1, { allowed_skills: [web_search, code_runner] });而在operit_editor中无论调用方传入哪种形式editor 元数据统一使用JSON 字符串数组上报给原生工具——这一归一化逻辑见 examples/operit_editor.ts 的类型定义与下文editor 调用实现中的JSON.stringify处理。JavaScript 桥Tools.SoftwareSettings 的封装原生工具注册完成后还需要在 JavaScript 桥中把它们封装为Tools.SoftwareSettings的方法。实现在 JsTools.kt封装逻辑如下listCharacterCards: () { return toolCall(list_character_cards_settings, {}); }, getCharacterCard: (characterCardId) { return toolCall(get_character_card, { character_card_id: characterCardId }); }, createCharacterCard: (options {}) { const params { ...options }; [ attached_tag_ids, allowed_builtin_tools, allowed_packages, allowed_skills, allowed_mcp_servers ].forEach((name) { if (Array.isArray(params[name])) { params[name] JSON.stringify(params[name]); } }); return toolCall(create_character_card, params); },要点桥内方法名采用驼峰式listCharacterCards、createCharacterCard等映射到原生下划线工具名list_character_cards_settings等二者一一对应桥层承担了数组参数自动归一化职责五个数组字段attached_tag_ids、allowed_builtin_tools、allowed_packages、allowed_skills、allowed_mcp_servers在调用前若为Array类型会自动JSON.stringify与原生parseStringArrayParameter的解析约定无缝衔接updateCharacterCard同样执行这一归一化后再透传character_card_id与 updates。Operit Editor九个角色卡管理工具的注册与实现operit_editor是 Operit 内置的脚本包为脚本开发者提供一组可直接调用的管理函数。本次在 examples/operit_editor.ts 中新增九个角色卡工具文档第 170-174 行对它们的中文说明如下list_character_cards查看完整角色卡列表和当前活跃角色卡get_character_card读取单张角色卡完整配置create_character_card、update_character_card、delete_character_card管理角色卡set_active_character_card、clear_active_character_card管理活跃角色卡import_character_card_from_tavern_json、export_character_card_to_tavern_json与 Tavern JSON 交换单张角色卡。工具注册定义含中英文描述与参数 schema九个工具在 editor 的 tools 定义数组中逐一声明以create_character_card为例examples/operit_editor.ts{ name: create_character_card, description: { zh: 创建角色卡。name 必填列表字段传 JSON 字符串数组。, en: Create a character card. name is required; list fields use JSON string arrays. }, parameters: [ { name: name, description: { zh: 角色卡名称, en: Character card name }, type: string, required: true }, { name: description, description: { zh: 可选简介, en: Optional description }, type: string, required: false }, { name: character_setting, description: { zh: 可选角色设定提示词, en: Optional character-setting prompt }, type: string, required: false }, { name: opening_statement, description: { zh: 可选开场白, en: Optional opening statement }, type: string, required: false }, // ... other_content_chat / other_content_voice / attached_tag_ids / advanced_custom_prompt / marks ... { name: chat_model_binding_mode, description: { zh: 可选FOLLOW_GLOBAL 或 FIXED_CONFIG, en: Optional FOLLOW_GLOBAL or FIXED_CONFIG }, type: string, required: false }, { name: chat_model_config_id, description: { zh: 可选固定对话模型配置 ID空字符串清除, en: Optional fixed chat-model config id; empty string clears }, type: string, required: false }, { name: chat_model_index, description: { zh: 可选固定对话模型索引, en: Optional fixed chat-model index }, type: integer, required: false }, { name: memory_profile_binding_mode, description: { zh: 可选FOLLOW_GLOBAL 或 FIXED_PROFILE, en: Optional FOLLOW_GLOBAL or FIXED_PROFILE }, type: string, required: false }, { name: memory_profile_id, description: { zh: 可选固定记忆配置 ID空字符串清除, en: Optional fixed memory-profile id; empty string clears }, type: string, required: false }, { name: tool_access_enabled, description: { zh: 可选启用角色卡工具白名单, en: Optional switch for the card tool allowlist }, type: boolean, required: false }, { name: allowed_builtin_tools, description: { zh: 可选内置工具名的 JSON 字符串数组, en: Optional JSON string array of built-in tool names }, type: string, required: false }, // ... allowed_packages / allowed_skills / allowed_mcp_servers ... ] }update_character_card的说明进一步明确了合并语义按角色卡 ID 更新提供的字段。除 ID 外的字段定义与 create_character_card 一致examples/operit_editor.ts即更新接口只处理调用方显式传入的字段未传入字段保持原值。参数校验与调用实现editor 层的函数实现位于 examples/operit_editor.ts。每个工具在调用前都会做参数校验典型的get/delete/set_active/export类工具要求character_card_id非空否则返回统一格式的失败对象async function get_character_card(params?: { character_card_id?: string }) { const characterCardId params?.character_card_id?.trim(); if (!characterCardId) { return complete_character_card_error(get_character_card, { message: Missing required parameter: character_card_id }); } const result await Tools.SoftwareSettings.getCharacterCard(characterCardId); // ...success 分支组装 }create_character_card与update_character_card内部同样执行五个数组字段的JSON.stringify归一化并且update会把character_card_id从参数中剥离避免其混入可编辑字段const { character_card_id: _ignoredCharacterCardId, ...updates } params;见 L4253。编辑器侧的类型辅助定义在 examples/operit_editor.tstype CharacterCardArrayInput string | string[]; type CharacterCardWriteParams { name?: string; description?: string; character_setting?: string; opening_statement?: string; other_content_chat?: string; other_content_voice?: string; attached_tag_ids?: CharacterCardArrayInput; advanced_custom_prompt?: string; marks?: string; chat_model_binding_mode?: string; chat_model_config_id?: string; chat_model_index?: number; memory_profile_binding_mode?: string; memory_profile_id?: string; tool_access_enabled?: boolean; allowed_builtin_tools?: CharacterCardArrayInput; allowed_packages?: CharacterCardArrayInput; allowed_skills?: CharacterCardArrayInput; allowed_mcp_servers?: CharacterCardArrayInput; };最终九个函数全部汇入 editor 的导出清单examples/operit_editor.ts作为包级 API 暴露exports.list_character_cards、exports.get_character_card、exports.create_character_card、exports.update_character_card、exports.delete_character_card、exports.set_active_character_card、exports.clear_active_character_card、exports.import_character_card_from_tavern_json、exports.export_character_card_to_tavern_json。三份文件的同步契约设计文档明确了角色卡工具契约必须一致的三个文件文件角色examples/operit_editor.ts编辑器源文件examples/operit_editor.jsTypeScript 编译产出的 JavaScriptapp/src/main/assets/packages/operit_editor.js应用内置包副本三者必须保持同一份角色卡工具契约工具名、参数 schema、校验逻辑与调用目标完全一致。这份内置副本会在应用启动时被包管理器加载为operit_editor包因此任何修改都必须同步回这三处否则会出现编辑器源码有、内置包没有或反之的漂移。验证方式可参考配套文档 3_VerificationAndDelivery.md 中记录的检查项原生工具注册名、软件设置执行器和 JavaScript 桥一一对应TypeScript 参数和结果类型与原生字段一致operit_editor.ts的工具定义、参数校验和调用覆盖全部角色卡接口JavaScript 产物与应用内置副本同步按交付记录examples/operit_editor.js与app/src/main/assets/packages/operit_editor.js哈希一致git diff --check未报告空白错误现有Tools.Chat.listCharacterCards()继续保留。端到端调用链与实战示例综合原生层、JS 桥与 editor 三层一次完整的角色卡管理调用链路如下operit_editor.list_character_cards() → Tools.SoftwareSettings.listCharacterCards() → JsTools.kt toolCall(list_character_cards_settings, {}) → ToolRegistration 注册的原生工具runBlocking(Dispatchers.IO) → StandardSoftwareSettingsModifyTools.listCharacterCards() → CharacterCardManager.getAllCharacterCards() → 序列化为 CharacterCardsResultData 返回一个完整的创建并激活角色卡脚本示例在 Operit 脚本环境中运行// 1. 创建角色卡editor 层 const created await operit_editor.create_character_card({ name: 图书管理员, character_setting: 你是一位严谨耐心的图书管理员…, opening_statement: 欢迎来到档案馆今天想查阅什么, attached_tag_ids: [tag-1, tag-2], // 数组形式editor 自动转 JSON 字符串数组 allowed_skills: [web_search] // 白名单数组 }); const cardId created.card.id; // 2. 激活该角色卡 await operit_editor.set_active_character_card({ character_card_id: cardId }); // 3. 校验活跃状态 const cards await operit_editor.list_character_cards(); console.log(active${cards.activeCharacterCardId}); // 4. 导出为酒馆 JSON供备份/迁移 const exported await operit_editor.export_character_card_to_tavern_json({ character_card_id: cardId });若需直接调用桥层而非 editor同样支持注意数组字段需自行传 JSON 字符串数组或数组字面量const imported await Tools.SoftwareSettings.importCharacterCardFromTavernJson( {spec:chara_card_v2,data:{name:AI助手,description:…}} );源码复核与交付要点回顾本次改造以源码复核而非构建测试作为验证手段3_VerificationAndDelivery.md 明确本任务不运行编译、构建或测试命令。对读者而言如需自行核查这套接口是否完整落地可按以下顺序核对原生注册ToolRegistration.kt 中九个下划线工具名是否齐备且 executor 均指向StandardSoftwareSettingsModifyToolsKotlin 实现StandardSoftwareSettingsModifyTools.kt 中九个suspend fun是否存在、参数解析与结果类型是否与契约一致结果类型ToolResultDataClasses.kt 中十个角色卡相关Serializable数据类JS 桥JsTools.kt 中SoftwareSettings的九个驼峰方法及数组归一化类型声明examples/types/software_settings.d.ts 的CharacterCardWriteOptions与 L329-L380 的九个函数签名editor 三件套examples/operit_editor.ts、examples/operit_editor.js、app/src/main/assets/packages/operit_editor.js 的工具定义、实现与导出是否同步。小结通过本次改造Operit 的角色卡管理能力完成了从仅原生 UI 与单一只读脚本接口到原生工具 JavaScript 桥 严格 TS 类型 editor 包全链路的闭环。设计上的关键决策值得脚本开发者注意SoftwareSettings与Chat的职责边界、写入接口仅接受可编辑字段、数组参数的双表示归一化以及三份 editor 文件的强制同步契约——这些约定共同保证了脚本侧接口与原生实现长期保持一致也让 AI Agent 得以通过一套稳定、类型安全的接口完成角色卡的完整生命周期管理。赞分享AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆【免费下载链接】OperitThe most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent项目地址https://gitcode.com/gh_mirrors/op/Operit点击查看免费下载相关推荐Operit 原生角色卡管理工具SoftwareSettings 角色卡完整管理接口的实现与脚本接入指南Operit 原生角色卡管理工具SoftwareSettings 角色卡完整管理接口的实现与脚本接入指南 本文以 Operit 仓库 docs/TODO/chAI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化Operit 角色卡全量管理接口落地实录SoftwareSettings 原生工具、JavaScript 桥与 Operit Editor 三端打通Operit 角色卡全量管理接口落地实录SoftwareSettings 原生工具、JavaScript 桥与 Operit Editor 三端打通 本指南围AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化Operit 桥接接口对齐core.d.ts 类型声明、Compose DSL 节点与开发文档同步实践Operit 桥接接口对齐core.d.ts 类型声明、Compose DSL 节点与开发文档同步实践 本篇技术指南聚焦 OperitAndroid AIAI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考