# HarmonyAgent **Repository Path**: geyiheng_sjtu/HarmonyAgent ## Basic Information - **Project Name**: HarmonyAgent - **Description**: 基于LLM的OH智能操作助手:鸿智助手 - **Primary Language**: TypeScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-10-04 - **Last Updated**: 2024-11-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README **OpenHarmony竞赛训练营** **鸿智助手** **基于OpenHarmony的手机操作助手** | 学校名称: | 上海交通大学 | | --- | --- | | 团队名称: | 鸿智宇飞团队 | | 队长: | 葛毅恒 | OpenHarmony竞赛训练营组委会 2024年9月 # 使用教程: - 应用主界面接入了百度文心一言可以进行聊天,支持流式返回结果和MarkDown渲染。 - 聊天文字输入可以通过语音识别输入 - 在聊天框发送“执行任务”或“execute task”并在后面加上要执行的任务内容,应用主页面将会退出以自动执行任务 - 若需要强制停止任务自动执行,需要三只手指同时轻触屏幕 - 在聊天框发送“学习任务”或“learn task”并在后面加上要执行的任务内容,应用主页面将会退出并将接受您手动演示任务供助手学习 - 若需要结束演示并保存演示结果,需要单指滑动屏幕,先从左到右滑动,不松开触摸,再向上滑动(rightThenUp) - 若需重新演示,需要先结束演示(rightThenUp),然后重新手动开启演示(leftThenUp) # 摘 要 背景:传统的手机语音聊天助手通过简单的自然语言处理和模式匹配,将人的指令转换为有限的、工程师预先内置的API调用,只能实现有限的功能。然而随着大语言模型的发展,直接让手机助手理解每个手机界面,注入点击事件来操作手机便成为了未来可能发展方向。 目的:本应用旨在构建一个基于LLM的智能手机操作助手,具备自主完成用户指定的任务的能力,作为一个能够从自己的历史操作和用户演示中学习如何操作手机的智能体 **关键词:大语言模型、Agent、手机智能助手、无障碍模式** 目 录 [摘 要 2](#_Toc147761347) [1 设计需求分析 4](#_Toc147761348) [1.1 主要解决问题 4](#_Toc147761349) [1.2 改进点 4](#_Toc147761350) [2 特色与创新 4](#_Toc147761351) [3 设计描述 4](#_Toc147761352) [3.1 总体设计 4](#_Toc147761353) [3.2 实现思路 4](#_Toc147761354) [3.3 系统结构 4](#_Toc147761355) [3.3.1 模块划分 4](#_Toc147761356) [3.3.2 系统架构说明 4](#_Toc147761357) [3.3.3 文件结构 4](#_Toc147761358) [3.4 模块功能描述 5](#_Toc147761359) [3.4.1 模块/子系统1功能描述 5](#_Toc147761360) [3.4.2 模块/子系统2功能描述 5](#_Toc147761361) [3.4.3 模块/子系统3功能描述 5](#_Toc147761362) [3.5 业务/实现流程说明 5](#_Toc147761363) [3.5.1 用例1处理流程 5](#_Toc147761364) [3.5.2 用例2处理流程 5](#_Toc147761365) [3.6 接口描述 5](#_Toc147761366) [3.6.1 调用接口 6](#_Toc147761367) [3.6.2 提供接口 6](#_Toc147761368) [3.7 UI设计 6](#_Toc147761369) [4 其他 6](#_Toc147761370) [4.1 成员分工 6](#_Toc147761371) [4.2 困难与思考 6](#_Toc147761372) [4.3 参考 6](#_Toc147761373) # 设计需求分析 ## 主要解决问题 本项目主要解决问题: **如何基于LLM,构建一个可以自主操作手机完成用户给出的任务,并具备一定学习能力的手机助手** 进一步来说,本项目解决了: ·如何基于OHSDK的API,集成一个能获取页面信息,操作页面,与LLM实时交互,同时又用户友好的应用 ·对于非视觉的手机Agent方案,如何使用较少的prompt,让LLM看到并理解一个手机页面的布局结构和文字 ·如何构建一个带有容错的任务完成框架,以此来嵌入LLM,并在任务完成高效的同时减少LLM调用次数 ## 改进点 本项目主要改进点: ·**DOM向虚拟DOM转化:** 原生的无障碍扩展功能可以获取页面的无障碍节点树**(并非完全是web开发中的DOM,但为便于理解,下文用DOM指代)**,然而其属性获取均为异步操作。为增加遍历效率,减少代码复杂程度,采用先提前将DOM转为TS对象的树**(借用vue的概念,下文用虚拟DOM指代)** ·**容错和安全机制:** 改进了在LLM难以理解页面内容时或LLM操作页面失效时的容错机制、在执行删除等危险操作时的安全机制 ·**学习机制:** 支持从助手自己的历史操作,以及用户的手动演示两个渠道学习,并将任务-操作列表存入向量数据库供以后检索查询 ·**页面信息简化**: 将页面冗长的DOM转为向LLM描述的简短页面信息,同时还能保留页面的结构,使得调用LLM时减少token资源消耗 ·**动态API调用控制**: 如何在若干步LLM的API调用中,实时修改prompt,控制操作流向并考虑容错,以完成任务 ·**无障碍模式下的用户交互:** 如何在无障碍模式下,用户的操作被屏蔽时,渗透用户点击事件至页面元素的点击 # 特色与创新 **2.1 与无LLM的语音助手相比** 传统手机语音助手只通过简单的自然语言处理或模式匹配,调用有限的、工程师手动设定的功能列表,这大大削弱了手机助手的能力范围。本应用直接读取每个页面的信息并注入触摸事件,无需提前写好有限个对特定应用的API接口。 **2.2与其他基于OpenHarmony和LLM的手机操作助手相比** **·虚拟DOM构建->获取页面信息效率提升:** 若有其他应用也基于开源鸿蒙,开发LLM引导的手机操作助手,则几乎必然也会用到SDK中AccessibilityExtAbility的API来获取页面的无障碍节点树,而此原生的API对页面的每个节点的每个属性的获取均为异步操作,这将影响后续页面信息检索和提炼的效率,增加代码复杂程度。 本应用直接先将这些节点树变成TS对象树,使异步操作变为同步,并且能通过递归和JSON.stringify快速提炼出有价值的精简信息,以JSON格式供LLM查看,提升访问效率。 **·无障碍模式下用户操作注入—用户体验和助手学习能力提升:** 在无障碍辅助功能开启的状态下,原生的API只支持识别各个方向的滑动等手势操作,而用户的触摸操作将会被屏蔽,这意味着在手机操作助手自动执行任务时,用户无法干预点击屏幕。这使得用户难以对助手执行错误操作时纠正,也无法演示操作给助手使其学习。这个问题也是利用SDK中API时类似鸿蒙应用很有遇到的。 本应用基于InputMonitor的系统API,得益于虚拟DOM的构建,能高效检索到点击坐标对应的UI节点实施操作,使得在无障碍辅助功能开启下,也能对用户的点击做出响应,完善了用户体验和助手的学习能力。 # 设计描述 ## 总体设计 本应用由两个Ability构成:MainAbility 和 AccessibilityExtAbility,前者实现了一个与大语言模型对话和用户交代需要自动执行的任务的UI界面,后者基于无障碍辅助功能来获取页面无障碍节点树并分析,结合任务及大模型的调用,执行对无障碍节点的操作,并将操作记录在向量数据库中,实现操作手机及自主学习。通过监听屏幕点击事件并对相应无障碍节点执行操作,实现用户演示学习。 ## 实现思路 **MainAbility:** **·**构建聊天对话的UI界面 ·调用讯飞语音识别和百度文心一言API ·加入Markdown渲染和流式返回结果增加用户体验 **AccessibilityExtAbility:** 基于OHSDK提供的Accessibility Kit API ·**让LLM看见页面:**通过OHSDK API中**AccessibilityContext.getWindowRootElement()** 获取页面无障碍节点树(以DOM指代),为提高效率转换成TS对象树(以虚拟DOM指代),并精简成页面信息的简短描述 ·**让LLM能操作手机:**从虚拟DOM寻找目标对象对应的目标元素,通过OHSDK API中**AccessibilityElement.performAction()** 对DOM执行操作 ·**让LLM学习:** **·通过LLM自己的历史操作学习:**创建关系数据库将任务和历史操作存入。需要查看记忆时通过embedding和余弦相似检索出数据库中适量记忆给LLM **·通过用户的手动演示学习:**通过OHSDK API中inputMonitor监视手机屏幕的点击事件,并匹配上点击的是TS对象树哪个元素,再存入数据库 ## 系统结构 ### 模块划分 ![READMEimgs/img0.png](READMEimgs/img_0.png) 对于一个手机操作助手,则需要一个Ability在自动操作手机各个应用时保持后台运行,而UI交互会较少。因此使用无障碍扩展能力;AccessibilityExtAbility,基于此来自动化执行任务。同时仿照一般手机语音聊天助手的思路, 还需要一个和助手聊天的UI界面,并且能指派需要操作的任务。因此使用一个MainAbility作为UIAbility。 ·MainAbility(聊天界面) 聊天界面除了需要其他模块的配合如API调用和写入对话到文件外,其对话的条目呈现方式需要LazyForEach的使用,而它需要IDataSource类型,故在DataSource.ets中实现并继承出MessageSource,而单条Message类在Message.ets中实现 ·AccessibilityExtAbility(任务执行功能) 任务执行功能是整个助手的核心,功能包括“看见”、“导航”、“行动”、“记忆” “看见”:AccessibilityUtils.ts构建无障碍节点树、TS对象树及提炼页面简略JSON信息 “导航”:AccessibilityExtAbility.ts中的Navigator()与taskManager.ts的配合使用,控制LLM的调用和行动的上层函数调用 “行动”:AccessibillityExtAbiliy.ts封装了翻页、返回上一页、点击、滑动、打字等上层函数供调用 “记忆”:AccessibilityExtAbility.ts中的addKnowledge嵌入在Navigator()调用的执行下一步操作stepOper()中,也嵌入函数permeate()中(处理inputMonitor监视到的用户点击事件作用于实际屏幕元素点击),两者分别对应记忆助手自己的历史操作,以及用户的手动演示。而commitKnowledge负责将记忆存入向量数据库供下次接受到类似任务时调出操作历史 ·ApiModel 本模块实现了大语言模型和语音识别的API调用。为了提升用户体验,在聊天界面中LLM采用流式返回stream.ts,而基础的LLM的API调用由request.ts实现。 ·VecDbModel 向量数据库模型由关系型数据库储存信息,词向量嵌入API调用,以及它们的上层:搜索模块构成。实现的功能为在写入数据时获取其词向量,构成“数据-向量”,存入关系型数据库,在检索数据时,将新数据的向量和已有的“数据-向量”列表计算余弦相似度,返回最相似的数据。 ·utils 工具模块用于实现各种工具函数,包括存放与LLM的历史对话的fileUtil.ts、用于在自动执行任务时显示文本提示框的 promptManager.ts、整个应用的全局信息交流的单例GlobalContext.ts、以及url编码和时间日期字符串返回的工具函数 ### 系统架构说明 ![READMEimgs/img.png](READMEimgs/img.png) 图表 1执行任务运行流程 用户首先进入聊天界面(MainAblity中的indexv),可以与LLM对话(LLMmanager类,其中需要用到stream.ts中的HttpStreamService来支持流式返回结果),支持语音转文字输入(VoiceRecogManager类)。当用户发送内容中有“执行任务”,则聊天界面会退出,AccessibilityExtAbility的自动执行任务功能将开启,AccessibilityManager类初始化。以下由AM简称AccessibilityManager 任务会被送入向量数据库模型(VecDbModel,其中rdbManager类提供关系数据库存储,embedding.ts调用词向量嵌入API,search.ts中的Search1n是搜索相似条目的接口),用来检索曾经完成的相似任务以及当时的成功操作,以此来为当前LLM执行任务提供信息。任务也会直接被送入生成prompt。与此同时,LLM还需要看到当前页面内容。通过AccessibilityUtils类的页面刷新得到无障碍节点树(getCurrentPageAllElement),转换为节点对象树(EAtoObject),再生成简短的Json字符串(JSONreculsiveTrim)用于描述页面的文字信息。发送给LLM的prompt由历史经验、当前任务、当前页面信息组成,通过LLMmanager类收发(其中用到request.ts中的HttpService)。导航器(AM.Navigator)根据LLM回复的当前任务状态决定下一步操作是返回上一页(AM.stepReturn),进行下一步操作(AM.stepOper,可以翻页、点击、滑动、通过inputManager类打字),还是执行下一个任务(AM.getNewTask)。在任务执行的同时,AM.addKnowledge会记录当前的操作,在任务结束后通过 AM.commitKnowledge存入向量数据库。 ![READMEimgs/img_1.png](READMEimgs/img_1.png) 图表 2完整功能用例图 在另一种情况下,当在聊天界面时,若用户发送内容中有学习任务,则聊天界面也会退出,AccessibilityExtAbility的学习任务功能将会开启。 此时系统API inputMonitor会监听用户的触摸事件的位置,并匹配上相应的节点对象树中的某个可点击的元素并执行点击(AM.permeate),而AM.addKnowledge一样会记录操作,在用户关闭学习模式后,也通过AM.commitKnowledge存入向量数据库。 ![READMEimgs/img_2.png](READMEimgs/img_2.png) 图表 3文件结构 文件结构基本和3.3.1的模块划分保持一致,不一致处有: 实际文件结构中, ·页面移到pages目录 ![img14.png](READMEimgs/img14.png) ·存在MainAbility.ts、AccessibilityExtAbility.ts、AbilityStage分别管控两个Ability和应用的生命周期 ## 模块功能描述 以两个Ability、两个Model、以及一个utils的模块划分方式,由上层至底层。 ### MainAbility功能描述 ![READMEimgs/img_3.png](READMEimgs/img_3.png) 图表 4MainAbility的类图 - **模块:MainAbility** - **类型:Ability** - **目的:** - 提供一个主界面,用于展示应用的核心功能和交互。 - 处理语音识别和消息展示。 - 管理应用的全局状态和配置。 - **功能列表:** - **语音识别管理**:启动和停止语音识别,处理识别结果。 - **消息展示**:展示对话消息,包括文本消息和系统提示。 - **全局状态管理**:存储和更新应用的全局状态,如语音文本、存储路径等。 - **配置管理**:启用和禁用应用配置。 - **文件管理**:读写对话记录和其他数据。 - **视图更新**:根据数据变化更新UI。 - **事件处理**:响应用户输入和系统事件。 - **处理:** - **语音识别管理**: - 使用VoiceRecogManager类进行语音识别操作。 - 通过Bridge机制实现语音识别的持续监听和处理。 - recordStart和recordStop方法控制语音输入。 - **消息展示**: - 使用MessageSource类管理消息数据源。 - pushData和popData方法用于更新消息列表。 - 使用lvMarkdownIn组件展示消息内容。 - **全局状态管理**: - 使用getP和setP函数从全局上下文中获取和设置参数。 - 存储语音文本、文件路径和LLM响应等状态。 - **配置管理**: - 使用configEnable和configDisable函数打开或关闭AccessibilityExtAbility。 - setConfig函数用于初始化无障碍模式快捷键配置。 - **文件管理**: - 使用fileManager类进行文件的读写操作。 - readlist、write和clear方法用于管理对话记录。 - **视图更新**: - Scroller组件用于消息区域的自动滚动处理。 - **事件处理**: - aboutToAppear和aboutToAppearFun函数用于开始接受语音识别流式回传的内容以及将历史对话内容加载到界面上。 - streamPushData函数处理流式数据更新和UI文本框更新。 - terminateSelfWithInfo函数在满足接收到用户输入“执行任务”或“学习任务”时终止自身并记录信息。 ### AccessibilityExtAbility功能描述 ![READMEimgs/img_4.png](READMEimgs/img_4.png) 图表 5AccessibilityExtAbility的类图 - **模块:AccessibilityExtAbility** - **类型:Ability** - **目的** - AccessibilityManager 类是为了管理设备上的辅助功能服务。它负责处理与用户界面交互相关的任务,如获取屏幕内容、执行点击操作、输入文本等。 - AccessibilityUtils 类提供了一系列静态方法,用于辅助 AccessibilityManager 类以及其他可能需要辅助功能服务的类。 - inputManager 类负责管理输入相关的操作,如模拟按键输入。 - taskManager 类负责管理和跟踪用户任务的执行状态。 - **功能列表** - **AccessibilityManager** - **获取当前屏幕内容**: 捕获当前屏幕上所有可访问元素的信息。 - **执行点击操作**: 对指定的UI元素执行点击操作。 - **输入文本**: 在指定的文本输入字段中输入文本。 - **监听触摸事件**: 监听屏幕上的触摸事件并作出响应。 - **数据库管理**: 管理本地数据库,存储和检索任务相关信息。 - **任务管理**: 管理和执行用户任务。 - **语音识别管理**: 管理语音识别功能,识别到 - **AccessibilityUtils** - **获取元素属性**: 获取屏幕上元素的各种属性,如文本内容、是否可点击等。 - **查找元素**: 根据给定的键值对查找屏幕上的元素。 - **构建元素数组**: 从系统提供的根元素开始,递归构建整个UI元素树。 - **处理元素信息**: 提取和处理元素信息,为其他操作提供数据支持。 - **inputManager** - **模拟按键事件**: 模拟硬件按键的按下和释放事件。 - **taskManager** - **获取任务信息**: 从文件或数据库中获取任务信息。 - **更新任务状态**: 根据任务执行情况更新任务状态。 - **生成任务提示**: 生成用于提示用户的任务描述。 - **处理** - **AccessibilityManager** - **使用 Accessibility API**: 利用操作系统提供的辅助功能API来获取屏幕内容和执行操作。 - **事件监听**: 注册事件监听器来响应系统事件,如触摸事件。 - **数据库操作**: 通过SQL语句操作SQLite数据库,实现数据的增删改查。 - **任务调度**: 根据用户的任务描述,调度相应的操作流程。 - **语音识别接口**: 调用语音识别服务API,将语音输入转换为文本。 - **AccessibilityUtils** - **使用 Accessibility API**: 调用辅助功能API来获取和操作屏幕上的元素。 - **递归遍历**: 递归地遍历UI元素树,构建元素数组。 - **属性提取**: 从元素对象中提取所需的属性信息。 - **inputManager** - **使用输入事件客户端**: 调用系统的输入事件客户端API,模拟按键操作。 - **taskManager** - **文件操作**: 读取和写入任务信息到文件系统。 - **数据库操作**: 从数据库中查询和更新任务状态。 - **模板生成**: 使用预设的模板生成任务提示信息。 ### ApiModel功能描述 ![READMEimgs/img_5.png](READMEimgs/img_5.png) ![READMEimgs/img_6.png](READMEimgs/img_6.png) - **实体:ApiModel** - **类型:Model** - **目的:** - ApiModel 类型包含多个类,它们分别负责处理与外部语言模型的交互、HTTP请求和响应的发送与接收、HTTP流式响应的处理以及文件的读写操作、语音识别的调用 - **功能列表:** - **LLMmanager**:初始化参数、发送HTTP请求并接收结果、将文本内容转换为JSON格式、处理HTTP响应流、与文件管理器交互进行读写操作。 - **HttpService**:创建HTTP请求对象、发送HTTP请求、订阅HTTP响应头事件、销毁HTTP连接。 - **HttpStreamService**:订阅HTTP响应头事件、订阅HTTP流式响应数据接收事件、处理流式响应数据、订阅HTTP流式响应数据接收进度事件、销毁HTTP连接。 - **VoiceRecogManager**:初始化语音识别配置、启动和停止语音识别、读取和发送音频数据、解析并处理识别结果、管理与语音识别服务的WebSocket连接。 - **处理:** - **LLMmanager**: - 初始化参数:通过 InitParam 方法配置HTTP请求的选项。 - 发送HTTP请求:通过 getHttpResult 方法发送请求并获取结果。 - 文本转JSON:通过 textToJson 方法将文本内容转换为适合发送给语言模型的JSON格式。 - 处理HTTP响应流:通过 getHttpStreamResult 方法处理HTTP响应流。 - 文件交互:通过 fileManager 实例进行文件的读写操作。 - **HttpService**: - 创建HTTP请求对象:通过 createHttpRequest 方法初始化 httpClient。 - 发送HTTP请求:通过 requestHttp 或 requestHttpWithOption 方法发送请求。 - 订阅HTTP响应头事件:通过 onHeaderReceive 方法订阅响应头事件。 - 销毁HTTP连接:通过 destroy 方法销毁HTTP连接。 - **HttpStreamService**: - 订阅HTTP响应头事件:通过 onHeadersReceive 方法订阅响应头事件。 - 订阅HTTP流式响应数据接收事件:通过 onDataReceive 方法订阅流数据事件。 - 处理流式响应数据:通过 parseStreamResult 方法处理流数据。 - 订阅HTTP流式响应数据接收进度事件:通过 onDataReceiveProgress 方法订阅数据接收进度事件。 - 销毁HTTP连接:通过 destroy 方法销毁HTTP连接。 - **VoiceRecogManager**: - 初始化语音识别管理器:通过 constructor 方法设置录音路径、自动重启等选项。 - 创建音频捕获器实例:配置音频捕获器选项。 - 启动语音识别:通过 recordStart 方法开启WebSocket连接、开始音频捕获,发送音频数据帧。 - 停止语音识别:通过 recordStop 方法停止音频捕获,关闭WebSocket连接。 - 读取音频数据:通过 readOneFrame 方法从音频捕获器获取音频数据。 - 发送音频数据帧:通过 sendStartFrame、sendMidFrame、sendEndFrame 方法向语音识别服务发送音频数据。 - 处理识别结果:通过 parseResult 方法处理识别结果,更新显示字符串。 - 监听WebSocket消息:通过 onMessage 事件监听函数接收并处理WebSocket消息。 - 建立WebSocket连接:通过 connectWS 方法设置事件监听器,管理WebSocket的生命周期。 - 管理WebSocket:通过 ws 对象处理连接开启、消息接收、错误处理和连接关闭。 ### VecDbModel功能描述 图表 7向量数据库类图 - **实体:VecDbModel** - **类型:模型** - **目的:** - VecDbModel 是一个综合性的实体,旨在通过各种方法和类来实现向量嵌入的生成、数据库管理、相似度搜索等功能。 - **功能列表:** - **生成向量嵌入**:通过 emb 函数调用API生成文本的向量表示。 - **管理关系数据库**:通过 rdbManager 类进行数据库的创建、数据表的生成、数据的插入、查询和删除。 - **执行相似度搜索**:通过 Search1n 函数在数据库中搜索与给定向量最相似的记录。 - **计算余弦相似度**:通过 cosineSimilarity、dotProduct 和 magnitude 函数计算两个向量之间的余弦相似度。 - **处理:** - **生成向量嵌入**: - 通过 emb 函数发送HTTP POST请求到指定的URL,并将文本转换为JSON格式的请求体。 - 解析响应数据,提取向量嵌入信息。 - **管理关系数据库**: - 通过 rdbManager 类的静态方法管理数据库的创建、表的生成、数据的插入、查询和删除。 - 使用 relationalStore API与关系数据库进行交互。 - **执行相似度搜索**: - 通过 Search1n 函数调用 emb 生成查询向量,然后查询数据库中相似的记录。 - 计算查询向量与数据库中记录的向量之间的余弦相似度。 - **计算余弦相似度**: - 通过 dotProduct 函数计算两个向量的点积。 - 通过 magnitude 函数计算向量的模。 - 通过 cosineSimilarity 函数计算两个向量的余弦相似度。 ### utils功能描述 ![READMEimgs/img_7.png](READMEimgs/img_7.png) ![READMEimgs/img_8.png](READMEimgs/img_8.png) - 实体:utils - 类型:utils - 目的: 提供一系列实用功能; - 功能列表: - **GlobalContext:**实现了整个应用的全局信息交流的单例,用于语音识别和LLMAPI返回结果的实时传回聊天主界面indexv.ets - **fileManager**: 管理文件操作,包括读取、写入、打印文件列表、清除文件内容和获取特定任务。 - **DateTimeUtil**: 提供日期和时间的格式化功能。 - **BoolObj**: 布尔对象,用于监控布尔值的状态。 - **promptManager**: 管理提示框和对话框的显示。 - **LoggerModel**: 提供日志记录功能。 - **ResourceUtils**: 提供资源管理功能,如获取字符串资源。 - **stringToUint8Array**: 将字符串转换为Uint8Array。 - **encode**: Base64编码函数。 - **btoa**: Base64编码的浏览器兼容版本。 - **toBase64**: 将ArrayBuffer转换为Base64字符串。 - **StrToBase64**: 将字符串转换为Base64字符串。 - 处理: - **GlobalContext**:创造一个单例,供全局访问同一个对象从而在应用全局交流信息 - getContext(): 静态方法,用于获取 GlobalContext 的唯一实例。 - getObject(value: string): 方法,根据提供的键值返回对应的对象,类型为 IndexParams。 - setObject(key: string, objectClass: IndexParams): 方法,将一个键值对存储到 \_objects Map 中。 - **fileManager**: - 构造函数: 初始化文件路径和文件名,如果目录为空则使用默认目录。 - readall: 读取整个文件内容。 - readlist: 读取文件并按特定分隔符分割成列表。 - write: 写入内容到文件,并添加分隔符。 - print: 打印文件列表。 - clear: 清除文件内容。 - gettask: 获取文件中的特定任务。 - **DateTimeUtil**: - getTime: 获取当前的小时和分钟。 - getDate: 获取当前的月和日。 - fill: 如果数字不足两位则前面补0。 - concatDate: 将月和日格式化为字符串。 - concatTime: 将小时和分钟格式化为字符串。 - nanotime: 获取纳秒级时间(静态方法)。 - **BoolObj**: 定义一个包含get、set和cond属性的对象,用于监控布尔值的状态。 - **promptManager**: - Toast: 显示提示信息。 - Dialog: 显示对话框。 - **LoggerModel**: - debug: 记录debug级别的日志。 - info: 记录info级别的日志。 - warn: 记录warn级别的日志。 - error: 记录error级别的日志。 - **ResourceUtils**: - getStringByName: 根据名称获取字符串资源。 - getStringByResource: 根据资源标识获取字符串资源。 - **stringToUint8Array**: 将JavaScript字符串转换为Uint8Array。 - **encode**: 将输入的字符串进行Base64编码。 - **btoa**: 浏览器兼容的Base64编码函数。 - **toBase64**: 将ArrayBuffer转换为Base64字符串。 - **StrToBase64**: 将字符串转换为Base64字符串。 ## 业务/实现流程说明 ![READMEimgs/img_9.png](READMEimgs/img_9.png) ![READMEimgs/img_10.png](READMEimgs/img_10.png) - **主界面**(indexv_UI)允许用户使用聊天界面,发送消息,接收消息。它使用了MessageSource来管理和显示消息。 - **语音识别管理器**(VoiceRecogManager)负责开始和停止语音识别过程。使用AudioCapturer来读入音频数据。 - **大语言模型管理器**(LLMmanager)处理与语言模型相关的HTTP请求,包括连接到Web服务、获取HTTP结果、流式传输HTTP结果,并解析识别结果。 - **Http服务**(HttpService)和**Http流服务**(HttpStreamService)用于处理HTTP请求和流式传输。 - **用例**包括: - **使用聊天界面**(Use Chat Interface):用户通过聊天界面与助手进行交流。 - **发送消息**(Send Message):用户可以发送文本消息。 - **接收消息**(Receive Message):用户可以接收来自助手的消息。 - **开始语音识别**(Start Voice Recognition):用户启动语音识别功能。 - **停止语音识别**(Stop Voice Recognition):用户停止语音识别功能。 - **连接到Web服务**(Connect to Web Service):系统建立网络连接。 - **获取和流式传输HTTP结果**(Fetch and Stream HTTP Result):系统获取和传输网络请求的结果。 - **解析识别结果**(Parse Recognition Result):系统解析语音识别的结果。 - **用户**执行使用聊天界面、开始和停止语音识别、发送消息、接收消息操作。 - **系统**执行连接到Web服务、获取和流式传输HTTP结果,解析识别结果。 ### 用例2任务执行功能 处理流程 ![READMEimgs/img_11.png](READMEimgs/img_11.png) - **主能力模块(MainAbility)**:用户通过主界面与系统进行交互。 - **无障碍管理器(AccessibilityManager)**:负责初始化和管理无障碍服务,包括启动输入管理器、获取页面描述、执行任务等。 - **无障碍工具(AccessibilityUtils)**:提供页面对象的刷新和获取页面简短描述的功能。 - **输入管理器(InputManager)**:模拟键盘事件,用于输入文本。 - **任务管理器(TaskManager)**:负责初始化和管理任务状态。 - **向量数据库搜索(Search)**用于搜索与当前任务相似的任务的历史操作记录。 - **用例包括**: - **使用聊天界面(Use Chat Interface)**:用户通过主能力模块与系统进行聊天。 - **执行任务(Execute Task)**:无障碍管理器执行用户指定的任务。 - **获取页面描述(Get Page Description)**:无障碍工具刷新页面对象并获取简短描述。 - **初始化大语言模型管理器(Initialize LLM Manager)**:无障碍管理器初始化大语言模型管理器。 - **初始化输入管理器(Initialize Input Manager)**:无障碍管理器初始化输入管理器。 - **自动执行任务(Auto-Execute Mission)**:无障碍管理器自动执行任务。 - **导航到另一页面(Navigate to Another Page)**:无障碍管理器决定导航到另一页面。 - **输入文本(Input Text)**:无障碍管理器决定输入文本。 - **返回上一页(Return to Last Page)**:无障碍管理器决定返回上一页。 - **接收新任务(Receive New Task)**:无障碍管理器接收新的任务。 - **用户执行的操作**: - 发送聊天信息。 - 发送执行任务命令。 - **系统执行的操作**: - 系统通过无障碍管理器执行任务。 - 系统通过无障碍工具获取页面描述。 - 系统通过大语言模型管理器处理请求并解析命令。 - 系统通过输入管理器模拟键盘事件输入文本。 - 系统通过任务管理器管理任务。 - 系统通过向量数据库搜索收集提示信息。 - **流程说明**: - 用户在主界面进行聊天,无障碍管理器执行任务并获取页面描述。 - 无障碍管理器根据大语言模型管理器的解析结果,决定下一步操作,可能是导航到另一页面、输入文本或返回上一页。 - 如果任务完成,无障碍管理器将请求新的任务并返回主界面。 - 如果大语言模型管理器无法确定下一步操作,无障碍管理器将返回上一页。 - 大语言模型通过向量数据库搜索收集历史记录以辅助决策。 ### 用例3任务学习功能 处理流程 ![READMEimgs/img_12.png](READMEimgs/img_12.png) - **主能力模块(MainAbility):**用户通过主界面与系统进行交互。 - **无障碍管理器(AccessibilityManager):**负责初始化和管理无障碍服务,包括启动输入管理器、获取页面描述、执行任务等。 - **无障碍工具(AccessibilityUtils):**提供页面对象的刷新和获取页面简短描述的功能。 - **嵌入模块(embedding):**负责获取当前任务的向量表示。 - **关系数据库管理器(rdbManager):**负责存储任务操作的历史记录。 - **用户执行的操作:** - 发送聊天信息。 - 发送学习任务命令。 - 点击屏幕演示任务 - 发送停止学习任务命令 - **系统执行的操作:** - 系统通过无障碍管理器执行任务。 - 系统通过无障碍工具获取页面描述。 - 系统通过嵌入模块获取当前任务的向量表示。 - 系统通过关系数据库管理器存储任务操作的历史记录。 - **用例包括:** - **使用聊天界面(Use Chat Interface):**用户通过主能力模块与系统进行聊天。 - **执行任务(Execute Task):**无障碍管理器执行用户指定的任务。 - **获取页面描述(Get Page Description):**无障碍工具刷新页面对象并获取简短描述。 - **获取当前任务向量(Get Task Vector):**嵌入模块获取当前任务的向量表示。 - **存储任务操作记录(Store Task Operation History):**关系数据库管理器存储操作历史。 - **流程说明:** - 用户在主界面通过聊天界面与系统进行聊天。 - 用户发送学习任务命令,无障碍管理器接收命令并开始学习任务。 - 无障碍管理器调用无障碍工具获取页面描述。 - 无障碍管理器初始化并监控用户的触摸事件。 - 用户在屏幕上触摸,无障碍管理器通过无障碍工具找到可操作的元素并执行点击。 - 无障碍管理器将操作记录存储到关系数据库管理器中。 - 用户完成演示后,无障碍管理器从嵌入模块获取当前任务的向量表示。 - 无障碍管理器将“任务-操作记录列表”存储到关系数据库管理器中。 ### 用例4向量数据库 处理流程 ![READMEimgs/img_13.png](READMEimgs/img_13.png) - **用户(User)**: - 请求文本的向量嵌入。 - 请求在存储的文本中搜索相似文本。 - **向量数据库模型(VecDbModel)**:负责处理向量嵌入请求和搜索请求,保存向量-文本对到关系型数据库。 - **词嵌入API调用函数(emb)**:负责调用百度embedding API将文本转换为向量。 - **关系型数据库(Relational DB)**:存储向量-文本对。 - **关系型数据库管理器(rdbManager)**:负责从关系型数据库中查询数据,执行数据库语句 - **相似度搜索(Search1n)**:负责在向量空间中搜索相似的文本。 - **余弦相似度(cosineSimilarity)**:用于计算向量之间的相似度。 - **用例包括**: - **请求文本的向量嵌入(Request Vector Embedding of Text)**:用户请求将特定文本转换为向量。 - **保存向量-文本对(Save "vector-text")**:向量数据库模型将向量-文本对保存到关系型数据库。 - **请求搜索相似文本(Request Search Similar Text Among Stored Texts)**:用户请求在存储的文本中搜索与给定文本相似的文本。 - **查询存储的向量-文本对(Query Stored "vector-text")**:关系型数据库管理器查询存储的向量-文本对。 - **搜索相似文本(Search1n)**:相似度搜索在向量空间中搜索相似的文本。 - **用户执行的操作**: - 用户请求文本的向量嵌入。 - 用户请求搜索相似文本。 - **系统执行的操作**: - 系统通过嵌入模型将文本转换为向量。 - 系统通过关系型数据库管理器查询存储的向量-文本对。 - 系统通过相似度搜索在向量空间中搜索相似的文本。 - 系统通过余弦相似度计算向量之间的相似度。 - **流程说明**: - 用户请求文本的向量嵌入,嵌入模型将文本转换为向量,向量数据库模型将向量-文本对保存到关系型数据库,并返回向量给用户。 - 用户请求搜索相似文本,向量数据库模型请求嵌入模型将目标文本转换为向量,然后查询关系型数据库管理器获取存储的向量-文本对。 - 向量数据库模型将目标向量与存储的向量进行相似度搜索,返回相似的文本记录给用户。 ## 接口描述 ### 调用接口 #### **_AccessibilityManager调用接口_** 1. **AccessibilityUtils**: - getCurrentPageAllElement(context): 获取当前页面所有元素。 - findScrollable(elements): 查找可滚动元素。 - getAllElementInfo(elements, detailed): 获取所有元素信息。 - findClickables(elements, detailed): 查找可点击元素。 - findClickablesObj(objs): 查找可点击对象。 - traceAncestorAttribute(element, attribute): 追踪祖先属性。 - performAction(element, action): 对元素执行动作。 - sleep(ms): 延迟指定毫秒数。 - ObjInfo(obj, detailed, includeChildren): 获取对象信息。 - ObjsInfo(objs, detailed, attr): 获取对象数组信息。 - isPointInRect(rect, x, y): 判断点是否在矩形内。 - clickAnsObj(objs, key, value): 根据键值点击对象。 - findReturnObj(objs): 查找返回对象。 - findElementByKey(elements, targetElement): 根据键值查找元素。 - findClickRect(elements, detailed): 查找点击矩形。 - attributeNames(element): 获取元素属性名称。 - findAbleLoc(screenX, screenY, Able, trialCnt): 查找可用位置。 - getJSONinfo(objs, humanReadable): 获取JSON信息。 2. **ResourceUtils**: - getStringByName(context, name): 根据名称获取字符串资源。 3. **LLMmanager**: - askLLMj(infostr, task): 向大语言模型请求并获取答案。 4. **inputManager**: - keyCode(code): 模拟按键操作。 5. **VoiceRecogManager**: - runBridgeForever(options): 运行语音识别桥接,持续获取语音输入。 6. **rdbManager**: - createStore(context): 创建数据库存储。 - createTable(tableName, schema): 创建数据表。 - insert(tableName, valuesBucket): 插入数据。 - query(tableName): 查询数据表。 - delete(tableName, conditions): 删除数据。 7. **Search1n**: - search(task, pageNodes, limit, detailed): 在页面节点中搜索任务。 8. **taskManager**: - settaskStatus(status): 设置任务状态。 - getPrompt(pageDesc): 获取任务提示。 - print(): 打印任务信息。 9. **promptManager**: - Toast(message, duration): 显示提示信息。 10. **fileManager**: - write(content, append): 写入文件内容。 11. **GesturePath & GesturePoint**: - injectGesture(path): 注入手势路径。 12. **inputEventClient & inputEvent**: - injectMouseEvent(eventData): 注入鼠标事件。 13. **DateTimeUtil**: - nanotime(): 获取纳秒时间戳。 14. **AccessibilityConfig**: - setConfig(): 设置无障碍功能配置。 - configEnable(): 启用配置。 - configDisable(): 禁用配置。 15. **inputMonitor & inputEventClient**: - on(event, callback): 监听输入事件。 16. **ValuesBucket**: - 用于表示数据库操作的数据结构。 17. **GlobalContext**: - getP(): 获取全局属性。 - setP(params): 设置全局属性。 18. **KeyCode**: - KEYCODE_\*: 定义按键代码常量。 #### **_indexv调用接口_** 1. **Message**: - new Message(content, role): 创建消息实例。 2. **MessageSource**: - new MessageSource(messages): 创建消息源实例。 - pushData(message): 推送消息数据。 - popData(): 移除最新消息数据。 - totalCount(): 获取消息总数。 3. **GlobalContext**: - getP(): 获取全局属性值。 - setP(params): 设置全局属性值。 4. **VoiceRecogManager**: - new VoiceRecogManager(recordPath, enable): 创建语音识别管理器实例。 - recordStart(): 开始录音。 - recordStop(): 停止录音。 - runBridgeForever(options): 运行语音识别桥接。 5. **fileManager**: - new fileManager(dir, convFile): 创建文件管理器实例。 - readlist(): 读取文件列表。 - clear(): 清空文件内容。 - write(content): 写入文件内容。 6. **LLMmanager**: - new LLMmanager(dir, convFile, mode): 创建大语言模型管理器实例。 - askLLMss(): 请求大语言模型服务。 7. **AccessibilityUtils**: - sleep(ms): 延迟指定毫秒数。 8. **promptAction**: - showDialog(options): 显示对话框。 - showToast(options): 显示提示信息。 9. **config**: - setConfig(): 设置AccessibilityExtAbility开启的快捷键。 - configEnable(): 启动AccessibilityExtAbility - configDisable(): 关闭AccessibilityExtAbility 10. **AccessibilityConfig**: - setConfig(): 设置无障碍功能配置。 - configEnable(): 启用配置。 - configDisable(): 禁用配置。 11. **lvMarkdownIn**: - lvMarkdownIn(options): 将Markdown文本渲染为组件。 12. **Image**: - Image(source): 创建图片组件。 13. **Button**: - Button(text): 创建按钮组件。 - onClick(callback): 设置按钮点击事件。 14. **TextArea**: - TextArea(options): 创建文本区域组件。 - onChange(callback): 设置文本变更事件。 15. **Scroller**: - scrollEdge(edge): 滚动到指定边缘。 - scrollBy(x, y): 滚动指定距离。 16. **DateTimeUtil**: - getDate(): 获取日期。 - getTime(): 获取时间。 ### 提供接口 #### **_LLMmanager提供接口_** #### **属性和基本操作** #### static p1: 存储promptManager的实例 #### static resultNumArray: 存储数字结果的数组 #### **构造函数** #### constructor(): 初始化静态属性p1 #### **属性获取与操作** #### static getAttributeValue(accessibilityElement, key): 异步获取元素的属性值 #### **元素信息提取** #### static async getElementWantedInfoPrint(element): 异步获取并打印元素的期望信息 #### static async getAllElementInfoPrint(currentPageElementArray, ElementLevelArray): 异步获取并打印所有页面元素的详细信息 #### static async getAllElementInfo(currentPageElementArray, getId = false): 异步获取所有页面元素的信息 #### static async getElementWantedInfo(element): 异步获取元素的期望信息 #### **元素查找** #### static async findElementByKey(elementArray, targetElement): 异步通过键值查找元素 #### static async findElementListByKey(elementArray, targetElement): 异步通过键值查找元素列表 #### static async findScrollable(currentPageElementArray): 异步查找可滚动的元素 #### static async findClickRect(currentPageElementArray, click = false, rect, waitTime = 300): 异步查找可点击的矩形区域 #### static async findClickables(currentPageElementArray, getEntrySum = true): 异步查找所有可点击的元素 #### static async findClickableAns(currentPageElementArray, targetid): 异步查找特定ID的可点击元素 #### **重叠检测** #### static examineOverlap(objs): 检查对象数组中是否有重叠的元素 #### static isOverlap(rectA, rectB): 检测两个矩形是否重叠 #### static isPointInRect(rect, pointX, pointY): 检测点是否在矩形内 #### static getOverlapText(elements): 获取元素的重叠文本 #### **异步等待** #### static async sleep(time): 异步等待指定的时间 #### **JSON处理** #### static getJSONinfo(elementsObj, plainStore = false): 提取对象的JSON信息 #### static JSONreculsiveTrim(elementObj, plain = false, lastSingle = false): 递归修剪JSON信息 #### **对象信息提取** #### static ObjInfo(Obj, plain = false, learnInfo = false): 获取对象的信息 #### **辅助功能** #### static scrollDirs(forward): 确定滚动方向 #### static findClickablesObj(Objs): 从对象数组中找到可点击的对象 #### static findReturnObj(Objs): 找到返回对象 #### **_LLMmanager提供接口_** - constructor(dir, filename, mode): 创建大语言模型管理器实例。 - textToJson(): 将历史对话从文件中读出,转换为JSON格式。 - InitParam(jsonobj): 初始化HTTP请求参数。 - getHttpResult(jsonobj): 发送HTTP请求并获取结果。 - parseResult(result): 解析HTTP响应结果。 - getHttpStreamResult(jsonobj, callback): 获取HTTP流式响应结果。 - askLLMss(): 向大语言模型发送请求并获取流式响应。 - askLLM(infoPrompt): 向大语言模型发送请求并获取结果。 - askLLMj(infoPrompt): 向大语言模型发送请求,获取并解析JSON格式的响应。 #### **_VoiceRecogManager提供接口_** - constructor(recordPath, autoRestart): 创建语音识别管理器实例。 - runBridgeForever(bridge): 持续运行语音识别内容返回桥接。 - recordStart(): 开始录音并发送音频数据。 - recordStop(): 停止录音。 ## UI设计 ![READMEimgs/img_14.png](READMEimgs/img_14.png) ### **布局** ### **Row**: 用于水平排列子控件 ### **Column**: 用于垂直排列子控件 ### **Stack**: 用于堆叠子控件,可以定义对齐和分布方式 ### **Scroll**: 可滚动视图,用于展示可滚动的内容 ### **控件** ### **Button**: 按钮控件,用于触发事件 ### **TextArea**: 文本区域控件,用于多行文本输入 ### **Text**: 文本控件,用于展示文本内容 ### **Image**: 图像控件,用于展示图像 ### **LoadingProgress**: 加载进度指示器,用于显示加载状态 ### **特殊功能** ### **lvMarkdownIn**: 用于解析并展示Markdown格式的LLM回复 ### **Scroller**: 提供滚动功能的控件,可以在LLM流式返回结果时自动滚动 ### **事件和行为** ### **clearConversations**: 清空对话历史 ### **terminateSelfWithInfo**: 根据关键词终止自身并记录信息 ### **streamPushData**: 流式推送数据 ### **aboutToAppearFun**: 页面即将出现时执行的函数 ### **组件状态管理** ### **Messages**: 对话消息数据 ### **main**: 控制语音识别开始、暂停、识别中的状态 ### **dispspeech**: 显示的文本框文本、 # 其他 ## 成员分工 ### 2024.1-2024.10 唯一成员 葛毅恒 完成所有开发任务 ## 参考 ### \[1\] #### \[2\] \[3\]