aardio 文档

aardio 范例: AI 智能助手 —— 自动编程自动操作电脑

import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(text="AI 智能助手 —— 自动编程自动操作电脑";right=900;bottom=600;bgcolor=0xFFFFFF)
winform.add(
btnSend={cls="plus";text="运行";left=790;top=550;right=885;bottom=590;bgcolor=0xFF0078D7;border={radius=4};db=1;dr=1;font=LOGFONT(h=-14);iconStyle={align="left";font=LOGFONT(h=-13;name='FontAwesome');padding={left=15}};iconText='\uF1D8';notify=1;textPadding={left=15};z=3};
btnSetting={cls="plus";left=11;top=551;right=46;bottom=581;align="left";color=0x3C3C3C;font=LOGFONT(h=-13);iconStyle={font=LOGFONT(h=-22;name='FontAwesome')};iconText='\uF013';textPadding={left=25};z=4};
customChat={cls="custom";text="聊天区域";left=0;top=0;right=900;bottom=540;db=1;dl=1;dr=1;dt=1;z=1};
editPrompt={cls="edit";left=50;top=550;right=780;bottom=590;db=1;dl=1;dr=1;edge=1;multiline=1;z=2}
)
/*}}*/

import fsys.table;
import web.rest.aiChat.settingForm;

// 创建配置文件
var path = io.appData("aardio/std/example/ai/agent.table");
var config = fsys.table(path);

winform.btnSetting.oncommand = function(id,event){

    table.mix(config,{
        title = "设置 AI 智能助手"; // 标题  
        hyperlink1Title = "领取百亿 tokens"; // key 输入框显示嵌入链接  

        //可选预定义默认设置(值必须是对象数组)
        itemData = [{
            url="https://openai.qiniu.com/v1";
            key= '\0\1\96';
            model="gemini-3.0-flash-preview";
            temperature=1;
            extraParameters={"reasoning_effort":"medium"}
        }] 
    });


    //打开 AI 设置窗口,参数 2 指定配置文件
    var frmSetting = web.rest.aiChat.settingForm(winform,config);
    frmSetting.onHyperlink = function(apiUrl,apiKey){
        import process;
        process.openUrl("https://imtip.aardio.com/api-keys/")
    }


    //用户点击了「保存」           
    if( frmSetting.doModal(this) ){ 
        //获取用户当前选择的配置
        var selectedConfig = config.itemData[config.selItem]; 
    }
}

//创建 AI 聊天界面
import web.form.chat;
var chatUi = web.form.chat(winform.customChat);

var tip = /***
### 警告: 
**将操作电脑的权力交给 AI 风险极大。**  
**AI 可能错误执行代码导致严重后果。**  
**使用此工具造成的一切后果自负,如不同意请不要使用**  

### 功能:
1. AI 自动编写程序。
2. AI 自动执行代码。
3. AI 自动排除代码错误并重写代码直到任务执行成功。

### 设置:
请 <a href="javascript:void(0)" onclick="javascript:external.updateApiKey()">» 点这里设置</a> 接口参数,指定支持交错思考 + 工具调用的大模型(例如 Gemini 3 Flash )。  
请不要使用 ai.aardio.com 接口。[领取 100 亿 tokens 支持 Gemini 3](https://imtip.aardio.com/api-keys/)

Gemini 3 Flash/Pro 的 temperature 必须指定为 1,
指定为其他值将无法正常运行。

使用 aardio 的 `web.rest.aiChat` [构造参数 reasoning.effort 设置](https://www.aardio.com/zh-cn/doc/library-guide/std/web/rest/aiChat.html#reasoning):
- Gemini 3 Flash 支持 "minimal"、"low"、"medium" 和 "high",建议设为 `medium`
- Gemini 3 Pro 仅支持 "low" 或 "high"
- 其他大模型大多支持 "low"、"medium" 和 "high" 

此工具已指定 reasoning.effort,temperature 忽略设置项。

***/
chatUi.write(tip)

chatUi.aardioSystem()
chatUi.system("你的能力是调用工具 loadcodex 执行 aardio 代码以自动化操作电脑")

var sendApiMessage = function(){

    var aiConfig = config.itemData[[config.selItem]];

    if(!aiConfig[["url"]] || string.find(aiConfig[["url"]],"aardio.com") ){
        winform.msgboxErr('请在设置中指定支持交错思考+工具调用的大模型。\n建议使用 Gemini Flash 3。\n\n请不要使用 ai.aardio.com 接口。');
        winform.btnSetting.oncommand();
        return;
    }

    var prompt = winform.editPrompt.text;

    // 检查输入是否为空(移除首尾空白)
    if(!#string.trim(prompt)){
        winform.editPrompt.setFocus();
        winform.editPrompt.showWarningTip("请输入提示词");
        return;
    }

    // UI 状态变更
    winform.editPrompt.text = ""; // 清空输入
    winform.btnSend.disabled = true; // 禁用按钮防止重复点击

    chatUi.showLoading(" 正在思考...");
    chatUi.prompt(prompt);

    // 创建 AI 对话线程
    thread.invoke( 
        function(chatUi,winform,aiConfig){
            import web.rest.aiChat;


            aiConfig.reasoning = {
                effort = "medium";
            } 
            aiConfig.temperature = 1;

            aiConfig.tools = { 
                {
                    "type": "function",
                    "function": {
                        "name": "loadcodex",
                        "description": "在当前电脑执行 aardio 代码。代码将作为匿名函数执行,你要通过 return 语句返回你需要的值。你要避免使用 try 语句。",
                        "parameters": {
                            "type": "object",
                            "properties": {
                                "code": {
                                    "type": "string",
                                    "description": "要执行的 aardio 源代码。"
                                },
                            },
                            "required": {
                                "code"
                            }
                        }
                    }
                },
                {
                    "type": "function",
                    "function": {
                        "name": "searchDocument",
                        "description": "联网搜索 aardio 官网上的文档与范例。",
                        "parameters": {
                            "type": "object", 
                            "properties": {
                                "query": {
                                    "type": "string",
                                    "description": "用于搜索 aardio 文档与范例的查询字符串"
                                }, 
                            },
                            "required": {
                                "query"
                            }
                        }
                    }
                }
            }

            // 创建 AI API 客户端
            var aiClient = web.rest.aiChat(aiConfig)

            aiClient.external = {
                loadcodex = function(args){ 

                    chatUi.showThinking('\n\n```aardio\n'+args.code+'\n```\n\n');

                    var func,err = loadcode(args.code)
                    if(!func){
                        return  {
                            error = err;
                            comment = "加载当前代码时遇到了错误,error 字段为错误信息。"
                        }   
                    }

                    var ok,result =  call(func); 
                    if(!ok){
                        return  {
                            error = result;
                            comment = "运行当前代码时遇到了错误,error 字段为错误信息。"
                        }
                    }

                    return  {
                        result = result; 
                        comment = "代码已成功执行,未发生错误。result 字段为执行代码的返回值。"
                    }
                },
                searchDocument = function(args){

                    chatUi.showThinking('\n搜索:'+args.query+'\n\n\n');

                    import string.escape2;
                    import web.rest.jsonClient;
                    var http = web.rest.jsonClient();

                    //请将 Key 换成自己的(注册 tavily 就可以领,每月免费 1000 次)。 
                    http.setAuthToken(string.escape2('\0\112\4\6\28\9\93\20\21\6\93\54\62\66\72\57\31\5\3\27\64\9\8\73\49\50\52\57\61\49\56\61\69\51\68\9\56\38\61\39\37\31\26'));
                    var tavily = http.api("https://api.tavily.com");

                    //搜索,不建议指定 include_raw_content 参数( 返回的 raw_content 可能有乱码 ).
                    var resp = tavily.search(
                        query = args.query,
                        max_results = 3, //限制返回结果数,默认值为 5。 
                        include_domains = ["www.aardio.com"], //可选用这个字段限定搜索的域名
                    )

                    //利用消息对象自动合成提示词
                    import web.rest.aiChat; 
                    var msg = web.rest.aiChat.message(); 
                    msg.url(resp[["results"]]) //将搜索结果添加到系统提示词

                    if(#msg){
                        return msg[#msg].content;//返回合成的提示词
                    }

                } 
            }

            // 调用接口
            var ok,err,errCode = aiClient.messages(chatUi.chatMessage,
                function(deltaText,reasoning){
                    if(reasoning) chatUi.showThinking(reasoning);
                    chatUi.assistant(deltaText);
                }
            );

            if(err){ 
                if(errCode==12029){
                    chatUi.errorMessage(`旧版操作系统不支持此服务商接口!<a href="javascript:void(0)" onclick="javascript:external.updateApiKey()">点这里更换其他接口</a>`)
                }
                elseif(aiClient.lastStatusCode==401){
                    chatUi.errorMessage(`API 密钥错误!<a href="https://imtip.aardio.com/api-keys/">点这里领取 tokens</a>,&nbsp;<a href="javascript:void(0)" onclick="javascript:external.updateApiKey()">点这里设置新密钥</a>`)
                }
                else{
                     chatUi.errorMessage(err)
                } 
            }

            // 恢复按钮状态
            winform.btnSend.disabled = false;

        },chatUi,winform,aiConfig
    )

    // 发送后焦点切回输入框
    winform.editPrompt.setFocus();
}

winform.editPrompt.text = "获取我的公网 IP,然后打开 Google 搜索此 IP"

chatUi.external = {
    updateApiKey = function(){
        winform.btnSetting.oncommand();
    } 
} 

winform.btnSend.oncommand = function(id,event){
    sendApiMessage();
}

//回车发送(Ctrl+Enter 换行)
winform.editPrompt.onOk = function(ctrl,alt,shift){
    if(ctrl){
        winform.btnSend.oncommand();
        return true;
    }
}

winform.btnSend.skin({
    background={
        default=0xFF0078D7;
        hover=0xFF0088EE;
        active=0xFF005BB5;
        disabled=0xFFCCCCCC;
    };
    color={
        default=0xFFFFFFFF;
        disabled=0xFF888888;
    }
})

winform.btnSetting.skin({
    color={
        active=0xFF00FF00;
        default=0xFF3C3C3C;
        disabled=0xFF6D6D6D;
        hover=0xFFFF0000        
    }
})

winform.show();
win.loopMessage();
Markdown 格式