ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Operit Kotlin 与 TypeScript 桥接接口对齐:NativeInterface 清理、Tools.Net 浏览器截图与 Compose DSL 节点声明实战

Operit Kotlin 与 TypeScript 桥接接口对齐:NativeInterface 清理、Tools.Net 浏览器截图与 Compose DSL 节点声明实战 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 在 2026-08-09 完成的「Kotlin 与 TypeScript 桥接接口对齐」任务展开说明该 Android AI Agent 如何保证脚本运行时QuickJS/ToolPkg看到的 TypeScript 声明与 Kotlin 侧JavascriptInterface真实注入能力严格一致包括移除没有 Kotlin 实现的死声明、补齐Tools.Net.browserTakeScreenshot类型以及为 Compose DSL 增加AiChat与AdaptiveSidePanel两个渲染节点。读者读完可以掌握 Operit 脚本桥接的类型维护方法论、参数归一化约定与无编译静态双向核对的验证技巧并能在自己的 ToolPkg 脚本中正确使用这些公开接口。一、任务背景声明与运行时脱节带来的三个问题Operit 的脚本体系由多层组成Android 侧 Kotlin 代码通过JavascriptInterface向 QuickJS 脚本运行时暴露桥接方法脚本开发者则通过examples/types/下的.d.ts声明文件获得类型提示。这套体系中Kotlin 注入实现与 TypeScript 声明必须一一对应否则会出现类型提示缺失或提示了根本不存在的方法两类问题。本次对齐任务任务索引清点出三个具体问题examples/types/network.d.ts缺少 Kotlin 已注入的方法JsTools已向Tools.Net注入了browserTakeScreenshot但类型声明中没有对应成员脚本作者无法获得提示也无法获得参数校验的约束信息examples/types/core.d.ts保留了两个没有 Kotlin 实现的死声明NativeInterface命名空间中的setResult与setError在 Kotlin 侧并无对应JavascriptInterface实现属于历史遗留脚本开发者若调用将直接失败Compose DSL 声明缺少已确认需要公开的节点ToolPkg 脚本可以声明式渲染 Compose UI但AiChat嵌入宿主 AI 聊天界面与AdaptiveSidePanel自适应侧栏两个节点在 TypeScript 声明和 Kotlin 渲染器两侧都没有对齐。任务的目标很明确让运行时与类型声明在公开接口这个边界上完全一致并同步更新面向脚本开发者的文档。二、公开接口清点NativeInterface的边界在哪里桥接接口清点1_NativeBridgeInventory.md首先回答了哪些方法应该出现在公共类型里这个边界问题。JsEngine通过JavascriptInterface暴露的桥接方法并不全是公开脚本接口——其中一部分由 ToolPkg 运行时与运行时内部包装使用属于内部桥接不应进入公共NativeInterface类型。判断标准是公开NativeInterface类型只描述脚本开发者可以直接使用的桥接方法因此setResult、setError这种没有 Kotlin 实现的旧成员必须移除而内部桥接方法也绝不能因为存在注入就被复制进core.d.ts。对齐后core.d.ts 中NativeInterface命名空间的公共成员为成员说明callTool(toolType, toolName, paramsJson)同步调用工具legacy 方式返回 ToolResult 的 JSON 字符串callToolAsync(callbackId, toolType, toolName, paramsJson)异步调用工具回调携带 ToolResultcallToolAsyncStreaming(callbackId, intermediateCallbackId, toolType, toolName, paramsJson)流式异步调用logInfo(message)/logError(message)/logDebug(message, data)三类日志桥接registerToolPkgToolboxUiModule(specJson)注册 ToolPkg 工具箱 UI 模块registerToolPkgAppLifecycleHook(specJson)注册应用生命周期钩子registerToolPkgMessageProcessingPlugin(specJson)注册消息处理插件registerToolPkgXmlRenderPlugin(specJson)注册 XML 渲染插件getPluginConfigDir(pluginId)解析插件持久化配置目录/sdcard/Download/Operit/plugins/id下的绝对路径registerInputMenuTogglePlugin(specJson)注册输入菜单开关插件移除setResult与setError后其余公共声明均能映射到 Kotlin 的JavascriptInterface实现ToolPkg 与运行时内部桥接也未混入公共声明。三、Tools.Net.browserTakeScreenshot从类型声明到参数归一化3.1 TypeScript 声明对齐后network.d.ts 中browserTakeScreenshot的声明为function browserTakeScreenshot(options: { type?: string; // 图片格式省略时默认 png element?: string; // 快照元素描述 ref?: string; // 快照元素引用需与 element 成对提供 fullPage?: boolean; // 是否截取完整页面 }): Promisestring;返回值是Promisestring——即截图保存后的文件路径字符串。声明注释同时强调提供ref时必须附带与之匹配的快照element描述。3.2 Kotlin 注入侧的参数归一化类型声明只是契约的一半另一半在 Kotlin 注入实现中。JsTools.ktapp/src/main/java/com/ai/assistance/operit/core/tools/javascript/JsTools.kt向Tools.Net注入该方法的实现其参数归一化逻辑与声明严格对应入参校验options必须是一个普通对象否则抛出browserTakeScreenshot only accepts one options objecttype转字符串并trim()空值兜底为pngelement/ref分别转字符串ref额外trim()并且二者必须成对出现——ref存在而element缺失时报element is required when ref is provided反之报ref is required when element is providedfullPage归一化为布尔值!!params.fullPage最终调用toolCall(browser_take_screenshot, params)进入标准浏览器会话工具链。3.3 Kotlin 工具实现侧的约束browser_take_screenshot工具在浏览器会话工具中落地StandardBrowserSessionTools.ktKotlin 侧还补充了声明层看不到的运行约束type只接受png/jpeg/jpg否则报type must be png or jpegelement与ref成对校验element ! null ref null时报错fullPage与ref互斥fullPage为真且提供ref时报fullPage cannot be used with element screenshots——即截取完整页面与截取指定元素不可同时使用截图通过takeScreenshot落盘返回的ToolResult中result字段携带Saved screenshot to 路径同时附上当前打开的标签页列表与页面状态供 Agent 继续决策。面向脚本开发者的文档 docs/doc-src/package-dev/network.md 已同步更新其中明确说明ref与element必须成对提供fullPage控制是否截取完整页面。一个典型用法const path await Tools.Net.browserTakeScreenshot({ type: png, fullPage: true }); console.log(path); // 截图保存路径四、Compose DSL 新节点AiChat与AdaptiveSidePanel脚本开发者除了调用工具还可以通过 Compose DSL 以声明方式渲染 UI。本次对齐在 TypeScript 声明与 Kotlin 渲染器两侧同时补齐了两个节点2_TypeDeclarationsAndDocs.md。4.1 TypeScript 声明compose-dsl.d.ts 中新增/** Embeds the host AI chat surface without its workspace panel. */ export interface AiChatProps extends ComposeCommonProps {} /** Controls a responsive trailing panel around the supplied screen content. */ export interface AdaptiveSidePanelProps extends ComposeCommonProps { open: boolean; side: ComposeChildren; onOpenChanged: (open: boolean) void; defaultWidth?: number; minWidth?: number; minContentWidth?: number; // ... }并在节点工厂中注册compose-dsl.d.tsAiChat: ComposeNodeFactoryAiChatProps; AdaptiveSidePanel: ComposeNodeFactoryAdaptiveSidePanelProps;AiChat语义为嵌入宿主 AI 聊天界面不含工作区面板用于在 ToolPkg 自定义界面中直接嵌入聊天能力AdaptiveSidePanel语义为围绕给定屏幕内容控制响应式尾部面板open控制开关、side为侧栏内容、onOpenChanged为状态变更回调defaultWidth/minWidth/minContentWidth控制面板宽度行为。4.2 Kotlin 渲染器实现Kotlin 侧渲染分发位于 ToolPkgComposeDslScreen.kt节点类型归一化后aichat分发到renderAiChatNodeadaptivesidepanel分发到renderAdaptiveSidePanelNode。renderAiChatNodeL2477-L2484在应用通用修饰符后直接嵌入AIChatScreen(embedded true)——即嵌入模式的聊天界面renderAdaptiveSidePanelNodeL2487-L2619实现了双布局自适应宽屏布局内容区与侧栏区并排Rowweight(1f)侧栏展开时提供 3dp 宽、56dp 高的拖拽手柄通过detectDragGestures实时调整面板宽度并在minWidth/maxWidth范围内coerceIn收敛窄屏布局内容区全屏铺底侧栏从右侧滑出背景叠加Color.Black.copy(alpha 0.18f)半透明遮罩点击遮罩触发onOpenChanged(false)关闭——这正是任务文档记录的宽屏拖拽调宽、窄屏遮罩关闭能力来源。onOpenChanged为必填动作属性渲染器通过ToolPkgComposeDslParser.extractActionId提取动作 ID缺失或空白都会直接抛错。五、静态双向核对不跑编译的验证方法论本任务遵循执行约束——不运行编译、构建或测试命令index.md验证完全采用静态核对这也是它最有方法论价值的地方。核对范围3_StaticVerification.md包括四件事检查core.d.ts的NativeInterface不包含没有 Kotlin 实现的旧成员比较JsTools.kt注入的浏览器截图方法与network.d.ts的Net成员比较compose-dsl.d.ts的新增节点与 Kotlin Compose DSL 节点分发审查文档和类型文件的差异。完成标准与核对结果core.d.ts中每个NativeInterface成员均能在 KotlinJavascriptInterface中找到实现setResult与setError未出现在任何公开类型声明或开发者文档中browserTakeScreenshot的四个参数type/element/ref/fullPage与 Kotlin 归一化逻辑一致Compose DSL 类型工厂与 Kotlin 渲染节点各 88 个双向集合无差异——以集合比较的方式确认声明了的一定能渲染能渲染的一定已声明git diff --check未发现空白错误。这套方法可以直接迁移到其他声明文件 ↔ 运行时实现双端同步的维护场景先清点注入面再定义公开边界然后做双向集合比较最后用 diff 审查收尾。六、对齐后的收益脚本开发者的实际体验所有公开类型都通过 examples/types/index.d.ts 统一再导出export * from ./core、export * from ./network、export * from ./compose-dsl等脚本作者只需引用这一个入口即可获得完整类型提示写Tools.Net.browserTakeScreenshot时能获得参数结构、默认值与返回值提示不再盲写写 Compose DSL 时可以使用AiChat嵌入聊天、用AdaptiveSidePanel做响应式侧栏且有完整的 props 类型约束不会再看到NativeInterface.setResult/setError这类调用即失败的幽灵方法。从源码结构看这正是 Operit Kotlin 运行时注入 → TypeScript 声明 → 开发者文档三层一致性的一个典型维护闭环任何新增的JavascriptInterface注入或 Compose DSL 节点都应同步完成类型声明、文档更新与双向静态核对才能保证脚本生态的类型可靠与可检索性。相关文件索引任务索引与执行约束docs/TODO/kt_ts_bridge_alignment_20260809/index.md公开接口清点1_NativeBridgeInventory.md类型声明与文档更新2_TypeDeclarationsAndDocs.md静态双向核对3_StaticVerification.md桥接类型声明examples/types/core.d.ts、examples/types/network.d.ts、examples/types/compose-dsl.d.ts、统一入口 examples/types/index.d.tsKotlin 注入实现JsTools.kt、浏览器会话工具 StandardBrowserSessionTools.kt、Compose DSL 渲染器 ToolPkgComposeDslScreen.kt开发者文档docs/doc-src/package-dev/network.md赞分享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 Kotlin 与 TypeScript 桥接接口对齐NativeInterface 公开接口清点与类型声明修复实战Operit Kotlin 与 TypeScript 桥接接口对齐NativeInterface 公开接口清点与类型声明修复实战 导读 本文围绕 OperitAI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化IntelliJ Platform Kotlin UI DSL v2 实战指南用声明式 Kotlin 构建对话框、设置页与表单化工具窗口IntelliJ Platform Kotlin UI DSL v2 实战指南用声明式 Kotlin 构建对话框、设置页与表单化工具窗口 本指南以仓库内 .a开发工具IDE代码编辑器TypeScript 声明合并与类型扩展同名声明合并与接口继承的完整实战指南TypeScript 声明合并与类型扩展同名声明合并与接口继承的完整实战指南 导读 在 TypeScript 的类型系统中合并Merging与扩展文档教程上一篇NocoBase 数据源管理之 IField 接口详解字段抽象、FieldOptions 与类型注册机制下一篇Telegraf HashiCorp Vault Secret Store 插件从配置到源码的完整实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表