# aardio 范例: 超级热键 - AI 自动续写补全

```aardio
//AI 自动续写补全
//调用 AI 大模型指南： https://www.aardio.com/zh-cn/doc/library-guide/std/web/rest/aiChat.html
//web.rest.aiChat 入门范例:https://www.aardio.com/zh-cn/doc/example/AI/aiChat.html
//关于超级热键: https://www.aardio.com/zh-cn/doc/library-guide/std/key/hotkey.html
import win.ui;
/*DSG{{*/
var winform = win.form(text="超级热键 - AI 自动续写补全";right=757;bottom=467)
winform.add(
edit={cls="richedit";left=32;top=35;right=725;bottom=414;autohscroll=false;edge=1;multiline=1;vscroll=1;z=1}
)
/*}}*/

winform.edit.text = /*
从前有一个小孩，
*/

import key.hotkey;
superHotkey = key.hotkey();
 
superHotkey.loadTable({
	
	// 按 Ctrl+Shift+F1 调用沉浸式 AI 助手，务必修改下面代码中的 API 接口配置与密钥。
	["Ctrl+Shift+F1"] = function(hFocus){   
		/*智能续写与补全{{*/

		//创建多线程以执行耗时操作，以避免阻塞键盘钩子消息导致热键失效。
		thread.invoke( 
			function(winform,hFocus){  
				import web.rest.aiChat; 
				var aiClient = web.rest.aiChat(
					//务必修改下面代码中的 API 接口配置与密钥
					key =   '\0\1\96';
					url = "https://ai.aardio.com/api/v1/";//接口地址
					model = "test-model-id";
					temperature = 0.5;//温度
					maxTokens = 1024,//最大回复长度
				)
				
				//import java.accessBridge;//支持 Java 程序窗口，例如 JetBrains 系列
				import winex.editor;
				import win.version;
				import key;
				
				//获取当前文本输入窗口光标插入点前后的文本。				
				var leftText,rightText = winex.editor.getText2(true); 
				if(!#leftText) return;
				
				//创建 AI 会话消息队列 
				var msg = web.rest.aiChat.message();  
				   
				//让 AI 更聪明的一个方法就是清楚表达背景、需求、上下文环境，消耗更多 token 得到更多回报。
				msg.system(`
## 背景

当前时间为：` + tostring(..time()) + `
当前操作系统为：` + ..win.version.format() + `;
当前进程启动文件为："` + (winex.editor.getPath() : "") + `"
当前窗口标题为："` + (winex.editor.getTitle() : "") + `"

用户当前输入光标插入点在"""前置文本"""与"""后置文本"""中间。
			
## 角色

你是智能续写与补全助手。

## 任务

分析上下文（"""前置文本"""与"""后置文本"""）插入新的内容。
	
## 要求

- 你需要根据当前操作系统、当前进程的启动文件名、窗口标题、上下文推测用户的输入环境与输入目的。
- 如果生成的是代码则直接回复代码， 不要放进 Markdown 代码块中 
- 请直接返回插入的内容，回复不要包含前置文本或后置文本`)
 		 
	    		msg.prompt(`
	    		
## 前置文本:  

console.log("Hello,

## 后置文本: 

;//在控制台输出一句话

## 任务

分析上下文（"""前置文本"""与"""后置文本"""）插入新的内容
 
`) 

				//利用小样本学习，以 AI 助手的角色教它一遍，胜过写千万句提示词
				msg.assistant(`world!")`);
	    		
	    		//下面是真正的问题。
	    		msg.prompt("
	    		
## 前置文本  

"+leftText+" 

## 后置文本  

"+(rightText:"")+" 

## 任务

请分析前置文本与后置文本，并在前置文本与后置文本之间插入新的内容。

## 要求

- 请直接返回插入的内容，回复不要包含前置文本或后置文本 
- 如果生成的是代码则直接回复代码， 不要放进 Markdown 代码块中 。
")

				if(string.find(leftText,"<//>|<# >|<!\N[ \t]*#>|<#:>\N*[ \t]*$")){
					winex.editor.sendString('\n')
				}
				
				import winex.loading;
				var loading = winex.loading("Thinking",hFocus) //进度动画
				 
				var ok,err = aiClient.messages(msg,function(delta,reasoning){
					
					//如果是推理模型，显示推理过程，推理过程放到 <think></think> 里是错误的做法不处理
					if(reasoning){ 
						return loading.thinking(reasoning);;
					}
					
					if(loading.isCanceled()){
						return false; //用户已取消（关闭进度动画窗口）
					}
					
					//以打字方式逐步输出 AI 回复的增量文本到目标输入框。
					//关于发送文本 https://www.aardio.com/zh-cn/doc/library-guide/std/key/sendString.html
					winex.editor.sendString(delta) 
				} ); 
				
				if(err){
					winex.editor.sendString(err) 
				}
			},winform,hFocus
		)
		/*}}*/
	};
	
	//按 Ctrl+$ 触发热键
	["Ctrl+$"] = function(hFocus){  
		import win.dlg.chineseNumber;
        win.dlg.chineseNumber().show();
    };
})

winform.show();
win.loopMessage();
```