@glodon-aiot/bot-client-sdk 3.26.0-alpha.4 → 3.26.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -76
- package/dist/es/Config.mjs +63 -85
- package/dist/es/builtinTools/browserRuntime/BrowserCommandRunner.mjs +201 -0
- package/dist/es/builtinTools/browserRuntime/PythonRunner.mjs +356 -0
- package/dist/es/builtinTools/browserRuntime/WorkspaceBashFs.mjs +350 -0
- package/dist/es/builtinTools/browserRuntime/assets.mjs +9 -0
- package/dist/es/builtinTools/browserRuntime/loadBash.mjs +17 -0
- package/dist/es/builtinTools/browserRuntime/pyodideRunner.py.mjs +96 -0
- package/dist/es/builtinTools/browserRuntime/pyodideWorker.mjs +242 -0
- package/dist/es/builtinTools/command.mjs +56 -0
- package/dist/es/builtinTools/constants.mjs +10 -0
- package/dist/es/builtinTools/createBuiltinToolsPlugin.mjs +236 -0
- package/dist/es/builtinTools/overview.mjs +77 -0
- package/dist/es/builtinTools/paths.mjs +63 -0
- package/dist/es/builtinTools/schemas.mjs +216 -0
- package/dist/es/builtinTools/tools.mjs +471 -0
- package/dist/es/index.mjs +49 -48
- package/dist/es/localFiles/adapters/FileSystemAccessAdapter.mjs +193 -103
- package/dist/es/localFiles/adapters/HostBridgeAdapter.mjs +138 -77
- package/dist/es/localFiles/adapters/MemoryWorkspaceAdapter.mjs +132 -97
- package/dist/es/localFiles/adapters/WorkspaceFileAdapter.mjs +32 -28
- package/dist/es/localFiles/constants.mjs +1 -1
- package/dist/es/localFiles/host/connectHostBridge.mjs +22 -18
- package/dist/es/localFiles/host/protocol.mjs +6 -5
- package/dist/es/localFiles/schemas.mjs +45 -60
- package/dist/es/localFiles/validate.mjs +37 -37
- package/dist/es/localFiles/workspace/LocalWorkspace.mjs +71 -52
- package/dist/es/package.json.mjs +33 -27
- package/dist/lib/index.js +372 -9
- package/dist/src/Config.d.ts +2 -2
- package/dist/src/builtinTools/browserRuntime/BrowserCommandRunner.d.ts +26 -0
- package/dist/src/builtinTools/browserRuntime/PythonRunner.d.ts +67 -0
- package/dist/src/builtinTools/browserRuntime/WorkspaceBashFs.d.ts +51 -0
- package/dist/src/builtinTools/browserRuntime/assets.d.ts +13 -0
- package/dist/src/builtinTools/browserRuntime/loadBash.d.ts +3 -0
- package/dist/src/builtinTools/browserRuntime/pyodideWorker.d.ts +44 -0
- package/dist/src/builtinTools/command.d.ts +26 -0
- package/dist/src/builtinTools/constants.d.ts +17 -0
- package/dist/src/builtinTools/createBuiltinToolsPlugin.d.ts +11 -0
- package/dist/src/builtinTools/overview.d.ts +5 -0
- package/dist/src/builtinTools/paths.d.ts +15 -0
- package/dist/src/builtinTools/schemas.d.ts +3 -0
- package/dist/src/builtinTools/tools.d.ts +60 -0
- package/dist/src/localFiles/adapters/FileSystemAccessAdapter.d.ts +4 -1
- package/dist/src/localFiles/adapters/HostBridgeAdapter.d.ts +20 -1
- package/dist/src/localFiles/adapters/MemoryWorkspaceAdapter.d.ts +4 -1
- package/dist/src/localFiles/adapters/WorkspaceFileAdapter.d.ts +14 -0
- package/dist/src/localFiles/adapters/fsaTypes.d.ts +2 -0
- package/dist/src/localFiles/constants.d.ts +2 -1
- package/dist/src/localFiles/host/protocol.d.ts +13 -0
- package/dist/src/localFiles/index.d.ts +3 -2
- package/dist/src/localFiles/schemas.d.ts +2 -3
- package/dist/src/localFiles/types.d.ts +14 -1
- package/dist/src/localFiles/workspace/LocalWorkspace.d.ts +12 -0
- package/package.json +8 -2
- package/dist/es/localFiles/createLocalPythonPlugin.mjs +0 -196
package/dist/lib/index.js
CHANGED
|
@@ -1,10 +1,373 @@
|
|
|
1
|
-
"use strict";var fi=Object.defineProperty,pi=Object.defineProperties;var gi=Object.getOwnPropertyDescriptors;var ye=Object.getOwnPropertySymbols;var nt=Object.prototype.hasOwnProperty,rt=Object.prototype.propertyIsEnumerable;var he=(i,e)=>{if(e=Symbol[i])return e;throw Error("Symbol."+i+" is not defined")};var ke=(i,e,t)=>e in i?fi(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t,v=(i,e)=>{for(var t in e||(e={}))nt.call(e,t)&&ke(i,t,e[t]);if(ye)for(var t of ye(e))rt.call(e,t)&&ke(i,t,e[t]);return i},I=(i,e)=>pi(i,gi(e));var at=(i,e)=>{var t={};for(var s in i)nt.call(i,s)&&e.indexOf(s)<0&&(t[s]=i[s]);if(i!=null&&ye)for(var s of ye(i))e.indexOf(s)<0&&rt.call(i,s)&&(t[s]=i[s]);return t};var y=(i,e,t)=>(ke(i,typeof e!="symbol"?e+"":e,t),t);var u=(i,e,t)=>new Promise((s,o)=>{var r=a=>{try{c(t.next(a))}catch(d){o(d)}},n=a=>{try{c(t.throw(a))}catch(d){o(d)}},c=a=>a.done?s(a.value):Promise.resolve(a.value).then(r,n);c((t=t.apply(i,e)).next())}),K=function(i,e){this[0]=i,this[1]=e},se=(i,e,t)=>{var s=(n,c,a,d)=>{try{var l=t[n](c),h=(c=l.value)instanceof K,f=l.done;Promise.resolve(h?c[0]:c).then(g=>h?s(n==="return"?n:"next",c[1]?{done:g.done,value:g.value}:g,a,d):a({value:g,done:f})).catch(g=>s("throw",g,a,d))}catch(g){d(g)}},o=n=>r[n]=c=>new Promise((a,d)=>s(n,c,a,d)),r={};return t=t.apply(i,e),r[Symbol.asyncIterator]=()=>r,o("next"),o("throw"),o("return"),r},ot=i=>{var e=i[he("asyncIterator")],t=!1,s,o={};return e==null?(e=i[he("iterator")](),s=r=>o[r]=n=>e[r](n)):(e=e.call(i),s=r=>o[r]=n=>{if(t){if(t=!1,r==="throw")throw n;return n}return t=!0,{done:!1,value:new K(new Promise(c=>{var a=e[r](n);if(!(a instanceof Object))throw TypeError("Object expected");c(a)}),1)}}),o[he("iterator")]=()=>o,s("next"),"throw"in e?s("throw"):o.throw=r=>{throw r},"return"in e&&s("return"),o},Y=(i,e,t)=>(e=i[he("asyncIterator")])?e.call(i):(i=i[he("iterator")](),e={},t=(s,o)=>(o=i[s])&&(e[s]=r=>new Promise((n,c,a)=>(r=o.call(i,r),a=r.done,Promise.resolve(r.value).then(d=>n({value:d,done:a}),c)))),t("next"),t("return"),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ae=require("uuid"),mi=require("js-base64"),yi=require("axios"),A=require("@glodon-aiot/apis"),wi=require("socket.io-client"),Ue=require("dayjs"),ee=class ee{constructor(e,t=!1){this.prefix=e,this.open=t}disable(){this.open=!1}enable(){this.open=!0}log(...e){!this.open&&!ee.debug||console.log(this.prefix,...e)}info(...e){!this.open&&!ee.debug||console.info(`%c ${this.prefix} %o`,"color:#0f0;",...e)}error(...e){!this.open&&!ee.debug||console.error(this.prefix,...e)}warn(...e){!this.open&&!ee.debug||console.warn(this.prefix,...e)}};y(ee,"debug",!1);let $=ee;const ze=["list_directory","read_file","stat_file","search_files","search_text","apply_patch","write_file","upload_file","download_file"],ue="buildin_tools",je={dev:ue,test:ue,prod:ue,local:ue},At=je,oe="run_python",St=je,Et=2e4,vi=12e4,Tt=16,Q="current-workspace",Lt=1024,pe=1024*1024,Ct=50,_e=Object.freeze({maxReadBytes:1*pe,maxWriteBytes:5*pe,maxSearchResults:200,maxConcurrentRequests:4,maxTransferBytes:Ct*pe,toolTimeoutMs:3e4,searchTimeoutMs:6e4,transferTimeoutMs:10*6e4,approvalTimeoutMs:5*6e4}),Rt=200,kt=1e3,Mt=8,We=16,xt=2e3,Ft=1*pe,be=500,Ot=3,Ve=8*Lt,Nt=Object.freeze(["glodon.com"]),Pt=Object.freeze([".git","node_modules",".svn",".idea",".vscode"]),Dt=Object.freeze(["~$*",".~lock*","*.tmp"]),_i=["apply_patch","write_file","upload_file","download_file"],Bt=["search_files","search_text"],qt=["upload_file","download_file"];var w=(i=>(i[i.Ok=0]="Ok",i[i.BadRequest=400]="BadRequest",i[i.Forbidden=403]="Forbidden",i[i.NotFound=404]="NotFound",i[i.Timeout=408]="Timeout",i[i.Conflict=409]="Conflict",i[i.TooLarge=413]="TooLarge",i[i.TooManyRequests=429]="TooManyRequests",i[i.Cancelled=499]="Cancelled",i[i.Internal=500]="Internal",i[i.NotImplemented=501]="NotImplemented",i))(w||{});class p extends Error{constructor(t,s,o){super(s);y(this,"code");y(this,"data");this.name="ToolError",this.code=t,this.data=o}}const bi="尚未授权工作文件夹,请先在助手中选择或恢复访问工作文件夹。";function Ye(){return new p(403,bi,{reason:"workspace_not_granted"})}function N(){return new p(499,"操作已取消。")}function M(i){if(i!=null&&i.aborted)throw N()}function Le(i){if(i instanceof p)return i;switch(i&&typeof i=="object"&&"name"in i?String(i.name):""){case"NotFoundError":return new p(404,"文件或目录不存在。");case"TypeMismatchError":return new p(400,"路径类型不匹配:目标是目录而不是文件,或路径中的某一段不是目录。");case"NotAllowedError":case"SecurityError":return Ye();case"AbortError":return N();case"NoModificationAllowedError":case"InvalidModificationError":case"InvalidStateError":return new p(403,"文件当前不可写,可能正被其他程序占用或为只读。");case"QuotaExceededError":return new p(413,"磁盘空间不足或超出写入配额。");default:return new p(500,"本地文件操作失败,请稍后重试。")}}const z="只操作用户在当前浏览器里选择的本地文件夹,路径相对该文件夹。云端工作区的文件不要用本工具。",B={type:"string",enum:[Q],description:`工作区 ID。省略时按 ${Q} 处理,传其他值会被拒绝。`},j=i=>({type:"string",description:`${i}使用相对工作区根目录的路径,以 / 分隔,不能包含 .. 或绝对路径。`}),Me={type:"string",description:"文件当前内容的 hash(sha256:<hex>),来自 read_file 或 stat_file 的返回值。"},Ge={list_directory:{functionCode:"list_directory",name:"列出本地目录",description:`${z}列出某个目录的直接子项(目录在前),支持分页。`,parameters:{type:"object",required:["grantId"],properties:{grantId:B,path:j('要列出的目录,省略或传 "." 表示工作区根目录。'),offset:{type:"integer",minimum:0,description:"分页起始位置,默认 0。"},limit:{type:"integer",minimum:1,maximum:1e3,description:"每页条数,默认 200。"}}}},read_file:{functionCode:"read_file",name:"读取本地文件",description:`${z}按行读取文本文件,单次最多返回 1 MiB,超出部分会被截断(truncated: true)。返回内容的 hash 可用于后续修改。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:B,path:j("要读取的文件。"),startLine:{type:"integer",minimum:1,description:"起始行(从 1 开始,含)。"},endLine:{type:"integer",minimum:1,description:"结束行(含)。"},maxBytes:{type:"integer",minimum:1,description:"返回内容的最大字节数,不超过 1 MiB。"},encoding:{type:"string",enum:["utf-8","gbk","gb18030"],description:"文本编码,默认 utf-8。"}}}},stat_file:{functionCode:"stat_file",name:"查看本地文件信息",description:`${z}返回文件或目录的类型、大小、修改时间,可选返回 hash。不返回文件内容。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:B,path:j("要查看的文件或目录。"),includeHash:{type:"boolean",description:"是否计算文件 hash。"}}}},search_files:{functionCode:"search_files",name:"查找本地文件",description:`${z}按文件名或 glob(支持 *、?、**)查找文件。不含 / 的模式匹配文件名,含 / 的模式匹配相对 path 的路径。`,parameters:{type:"object",required:["grantId","pattern"],properties:{grantId:B,pattern:{type:"string",minLength:1,description:"如 *.xlsx 或 reports/**/*.docx。"},path:j("搜索起点目录,默认工作区根目录。"),maxDepth:{type:"integer",minimum:1,maximum:16,description:"最大目录深度,默认 8。"},maxResults:{type:"integer",minimum:1,maximum:200,description:"最多返回条数,默认 200。"}}}},search_text:{functionCode:"search_text",name:"搜索本地文本",description:`${z}在指定文件或目录(递归)中搜索普通文本(不支持正则),返回所在文件、行号与该行内容。必须指定 path,不能搜索整个文件夹。`,parameters:{type:"object",required:["grantId","path","query"],properties:{grantId:B,path:j("搜索范围,可以是文件或目录。"),query:{type:"string",minLength:1,description:"要查找的文本。"},caseSensitive:{type:"boolean",description:"是否区分大小写,默认否。"},isRegex:{type:"boolean",description:"暂不支持正则,传 true 会返回 501。"},glob:{type:"string",description:"只搜索匹配该 glob 的文件,如 *.md。"},maxResults:{type:"integer",minimum:1,maximum:200,description:"最多返回条数,默认 200。"},contextLines:{type:"integer",minimum:0,maximum:3,description:"附带的上下文行数,默认 0。"}}}},apply_patch:{functionCode:"apply_patch",name:"修改本地文件",description:`${z}以查找替换的方式修改 UTF-8 文本文件。每条修改的 oldText 必须在文件中唯一出现(或设置 replaceAll)。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path","expectedHash","edits"],properties:{grantId:B,path:j("要修改的文件。"),expectedHash:Me,edits:{type:"array",minItems:1,description:"按顺序应用的修改。",items:{type:"object",required:["oldText","newText"],properties:{oldText:{type:"string",minLength:1,description:"要替换的原文,需包含足够上下文以保证唯一。"},newText:{type:"string",description:"替换后的文本。"},replaceAll:{type:"boolean",description:"是否替换所有出现位置,默认否。"}}}}}}},write_file:{functionCode:"write_file",name:"写入本地文件",description:`${z}新建文件,或整体覆盖已有文件(覆盖时必须提供 expectedHash)。修改已有文件优先使用 apply_patch。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path","content"],properties:{grantId:B,path:j("要写入的文件。"),content:{type:"string",description:"完整的文件内容(UTF-8)。"},expectedHash:Me,createDirectories:{type:"boolean",description:"父目录不存在时是否自动创建,默认否。"}}}},upload_file:{functionCode:"upload_file",name:"上传本地文件",description:`${z}把本地文件夹中的文件上传到平台文件服务,返回 fileId、name、size 和 url。url 是文件访问地址,可直接用于后续推理或对话。下载回本地文件夹时使用 download_file,source.type 为 platformFile。单文件不超过 50 MB。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:B,path:j("要上传的文件。"),target:{type:"string",description:"上传目标,目前只支持 session(默认),其他值返回 501。"},mimeHint:{type:"string",description:"可选的 MIME 类型。"}}}},download_file:{functionCode:"download_file",name:"下载到本地文件夹",description:`${z}把会话文件、平台文件或 https 地址保存到本地文件夹。source.type 为 url 时必须同时填写 source.url(完整地址),为 sessionFile 或 platformFile 时必须同时填写 source.fileId。不要只传 type。单文件不超过 50 MB。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","destPath","source"],properties:{grantId:B,destPath:j("保存位置(文件路径)。"),source:{type:"object",required:["type"],description:"下载来源。type 为 url 时必填 url;type 为 sessionFile 或 platformFile 时必填 fileId。",properties:{type:{type:"string",enum:["sessionFile","platformFile","url"],description:"sessionFile:当前会话文件;platformFile:平台文件(upload_file 返回的 fileId);url:https 地址。"},fileId:{type:"string",description:"type 为 sessionFile 或 platformFile 时必填,不能只传 type。"},url:{type:"string",description:"type 为 url 时必填,填写完整 https 地址。不能只传 type。默认只允许 glodon.com 及其子域。"}}},overwrite:{type:"boolean",description:"目标已存在时是否覆盖,默认否。"},expectedHash:Me}}}},Ii="在已绑定的本地工程目录中运行已有 .py,路径相对该目录。不要用于云端工作区,不要传 shell 或代码,只能传 path 和 args。",Ht={functionCode:oe,name:"运行本地 Python 脚本",description:`${Ii}每次运行需用户单独确认,文件读写授权不能代替。确认后脚本可直接读写该目录并使用标准库,改动立即落盘。不能联网,不能在运行中安装包,也不能访问该目录以外的文件。第三方包写在工程根目录 sandbox-requirements.txt。结果打印到标准输出。code 为 0 只表示已结束,成功看 data.exitCode,超时看 data.timedOut。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:B,path:{type:"string",description:"要运行的脚本。必须是已存在、以 .py 结尾的相对路径,以 / 分隔,不能包含 .. 、盘符或绝对路径。"},args:{type:"array",maxItems:16,description:"传给脚本的参数,最多 16 个。每个参数单独一项,不能含空格、引号或 shell 语法,只能包含字母、数字、下划线以及 . / : @ = + - , 。",items:{type:"string",description:"一个脚本参数。"}},timeoutMs:{type:"integer",minimum:1e3,maximum:12e4,description:"超时毫秒数。默认 20000,最大 120000。到时脚本会被终止。"}}}},Ai=I(v({},Ge),{run_python:Ht}),Si="路径必须是工作区内的相对路径,不能包含 ..、绝对路径或盘符。";function we(){return new p(w.Forbidden,Si,{reason:"path_outside_workspace"})}function $t(i){if(i!==Q)throw new p(w.Forbidden,`未知的工作区 grantId,当前仅支持 ${Q}。`,{reason:"path_outside_workspace"})}function U(i,{allowRoot:e=!1,field:t="path"}={}){if(i==null){if(e)return"";throw new p(w.BadRequest,`缺少参数 ${t}。`)}if(typeof i!="string")throw new p(w.BadRequest,`参数 ${t} 必须是字符串。`);if(i.includes("\0")||/%(2e|2f|5c|00)/i.test(i))throw we();const s=i.normalize("NFC").replace(/\\/g,"/").trim();if(s.startsWith("/")||/^[a-zA-Z]:/.test(s))throw we();const o=[];for(const n of s.split("/"))if(!(n===""||n===".")){if(n==="..")throw we();o.push(n)}const r=o.join("/");if(!r&&!e)throw new p(w.BadRequest,`参数 ${t} 不能指向工作区根目录。`);return r}function G(i){return i?i.split("/"):[]}function Ei(i){const e=i.lastIndexOf("/");return e<0?"":i.slice(0,e)}function Ut(i,e){return i?`${i}/${e}`:e}const ct=new Map;function Ti(i){return/[\\^$.|+()[\]{}]/.test(i)?`\\${i}`:i}function Li(i,e=!1){const t=`${e?"s":"i"}:${i}`,s=ct.get(t);if(s)return s;let o="";for(let n=0;n<i.length;n++){const c=i[n];c==="*"?i[n+1]==="*"?(n++,i[n+1]==="/"?(n++,o+="(?:.*/)?"):o+=".*"):o+="[^/]*":c==="?"?o+="[^/]":o+=Ti(c)}const r=new RegExp(`^${o}$`,e?"":"i");return ct.set(t,r),r}function Ae(i,e,t=!1){return Li(i,t).test(e)}function Qe(i){const e=i.lastIndexOf("/");return e<0?i:i.slice(e+1)}const zt=Object.freeze([{id:"env-files",pattern:".env*",reason:"环境变量文件可能包含密钥",source:"sdk-baseline"},{id:"pem",pattern:"*.pem",reason:"证书或密钥文件",source:"sdk-baseline"},{id:"key",pattern:"*.key",reason:"密钥文件",source:"sdk-baseline"},{id:"p12",pattern:"*.p12",reason:"证书文件",source:"sdk-baseline"},{id:"pfx",pattern:"*.pfx",reason:"证书文件",source:"sdk-baseline"},{id:"id-rsa",pattern:"id_rsa*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"id-ed25519",pattern:"id_ed25519*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"id-ecdsa",pattern:"id_ecdsa*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"credentials",pattern:".credentials",reason:"凭据文件",source:"sdk-baseline"},{id:"npmrc",pattern:".npmrc",reason:"可能包含 registry token",source:"sdk-baseline"},{id:"pypirc",pattern:".pypirc",reason:"可能包含仓库凭据",source:"sdk-baseline"},{id:"aws-credentials",pattern:"**/.aws/credentials",match:"path",reason:"云服务凭据",source:"sdk-baseline"},{id:"ssh-dir",pattern:"**/.ssh/**",match:"path",reason:"SSH 配置与密钥",source:"sdk-baseline"}]),Ci="该文件被列为敏感文件,不允许访问";class jt{constructor(e=[]){y(this,"rules");const t=e.filter(s=>s&&typeof s.pattern=="string"&&s.pattern).map(s=>I(v({},s),{id:String(s.id||s.pattern),source:s.source==="enterprise"?"enterprise":"product"}));this.rules=[...zt,...t]}match(e,t){if(!e)return null;const s=Qe(e);for(const o of this.rules){if(o.operations&&!o.operations.includes(t))continue;const r=o.match==="path"?e:s;if(Ae(o.pattern,r))return o}return null}isSensitive(e){return["read","write","search"].some(t=>this.match(e,t)!==null)}static reasonOf(e){return`${e.reason||Ci},已拒绝访问。`}}function de(i,e,t){const s=i.sensitive.match(e,t);if(s)throw new p(w.Forbidden,jt.reasonOf(s),{reason:"sensitive_file",ruleId:s.id})}function Ie(i,e){return u(this,null,function*(){try{return yield i.stat(e)}catch(t){if(Le(t).code===w.NotFound)return null;throw t}})}function Xe(i,e){return u(this,null,function*(){const t=yield i.stat(e);if(t.kind!=="file")throw new p(w.BadRequest,"目标是目录,不是文件。");return t})}function ce(i){return u(this,null,function*(){const e=yield crypto.subtle.digest("SHA-256",i);return`sha256:${Array.from(new Uint8Array(e)).map(s=>s.toString(16).padStart(2,"0")).join("")}`})}function te(i){return u(this,null,function*(){return new Uint8Array(yield i.arrayBuffer())})}function Wt(i){const e=Math.min(i.byteLength,Ve);for(let t=0;t<e;t++)if(i[t]===0)return!0;return!1}function Ri(i){return u(this,null,function*(){return Wt(yield te(i.slice(0,Ve)))})}function Vt(i){return i[0]===239&&i[1]===187&&i[2]===191}function ki(i){try{return new TextDecoder("utf-8",{fatal:!0}).decode(i)}catch(e){throw new p(w.BadRequest,"文件不是 UTF-8 编码,暂不支持修改。")}}function Mi(i){return new TextEncoder().encode(i).byteLength}function Yt(){return new Promise(i=>setTimeout(i,0))}function xi(i){return i>=1024*1024?`${(i/1024/1024).toFixed(1)} MB`:i>=1024?`${(i/1024).toFixed(1)} KB`:`${i} B`}function ie(i,e="文件"){return new p(w.TooLarge,`${e}超过大小上限 ${xi(i)}。`)}const Fi=new TextEncoder;function X(i,e,t,s){return i===void 0?e:Math.min(Math.max(Math.trunc(i),t),s)}const Oi=(i,e)=>u(exports,null,function*(){const t=U(i.path,{allowRoot:!0});if((yield e.adapter.stat(t)).kind!=="directory")throw new p(w.BadRequest,"目标是文件,不是目录。");const o=X(i.offset,0,0,Number.MAX_SAFE_INTEGER),r=X(i.limit,Rt,1,kt),n=yield e.adapter.listEntries(t,e.signal);n.sort((a,d)=>a.kind!==d.kind?a.kind==="directory"?-1:1:a.name<d.name?-1:a.name>d.name?1:0);const c=n.slice(o,o+r).map(a=>{const d=Ut(t,a.name),l={name:a.name,path:d,kind:a.kind};return a.kind==="file"&&(l.size=a.size,l.lastModified=a.lastModified,e.sensitive.isSensitive(d)&&(l.sensitive=!0)),l});return{data:{path:t,entries:c,total:n.length,hasMore:o+c.length<n.length}}});function Ni(i,e,t){return se(this,null,function*(){var c;const s=new TextDecoder(e),o=i.stream().getReader();let r="",n=!1;try{for(;;){M(t);const{done:a,value:d}=yield new K(o.read());r+=a?s.decode():s.decode(d,{stream:!0});const l=r.split(`
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";var En=Object.defineProperty,In=Object.defineProperties;var Sn=Object.getOwnPropertyDescriptors;var Me=Object.getOwnPropertySymbols;var qt=Object.prototype.hasOwnProperty,Wt=Object.prototype.propertyIsEnumerable;var Se=(i,e)=>{if(e=Symbol[i])return e;throw Error("Symbol."+i+" is not defined")};var Ye=(i,e,t)=>e in i?En(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t,w=(i,e)=>{for(var t in e||(e={}))qt.call(e,t)&&Ye(i,t,e[t]);if(Me)for(var t of Me(e))Wt.call(e,t)&&Ye(i,t,e[t]);return i},E=(i,e)=>In(i,Sn(e));var zt=(i,e)=>{var t={};for(var n in i)qt.call(i,n)&&e.indexOf(n)<0&&(t[n]=i[n]);if(i!=null&&Me)for(var n of Me(i))e.indexOf(n)<0&&Wt.call(i,n)&&(t[n]=i[n]);return t};var v=(i,e,t)=>(Ye(i,typeof e!="symbol"?e+"":e,t),t);var l=(i,e,t)=>new Promise((n,s)=>{var r=a=>{try{c(t.next(a))}catch(d){s(d)}},o=a=>{try{c(t.throw(a))}catch(d){s(d)}},c=a=>a.done?n(a.value):Promise.resolve(a.value).then(r,o);c((t=t.apply(i,e)).next())}),ee=function(i,e){this[0]=i,this[1]=e},de=(i,e,t)=>{var n=(o,c,a,d)=>{try{var h=t[o](c),u=(c=h.value)instanceof ee,f=h.done;Promise.resolve(u?c[0]:c).then(y=>u?n(o==="return"?o:"next",c[1]?{done:y.done,value:y.value}:y,a,d):a({value:y,done:f})).catch(y=>n("throw",y,a,d))}catch(y){d(y)}},s=o=>r[o]=c=>new Promise((a,d)=>n(o,c,a,d)),r={};return t=t.apply(i,e),r[Symbol.asyncIterator]=()=>r,s("next"),s("throw"),s("return"),r},Vt=i=>{var e=i[Se("asyncIterator")],t=!1,n,s={};return e==null?(e=i[Se("iterator")](),n=r=>s[r]=o=>e[r](o)):(e=e.call(i),n=r=>s[r]=o=>{if(t){if(t=!1,r==="throw")throw o;return o}return t=!0,{done:!1,value:new ee(new Promise(c=>{var a=e[r](o);if(!(a instanceof Object))throw TypeError("Object expected");c(a)}),1)}}),s[Se("iterator")]=()=>s,n("next"),"throw"in e?n("throw"):s.throw=r=>{throw r},"return"in e&&n("return"),s},V=(i,e,t)=>(e=i[Se("asyncIterator")])?e.call(i):(i=i[Se("iterator")](),e={},t=(n,s)=>(s=i[n])&&(e[n]=r=>new Promise((o,c,a)=>(r=s.call(i,r),a=r.done,Promise.resolve(r.value).then(d=>o({value:d,done:a}),c)))),t("next"),t("return"),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ye=require("uuid"),Tn=require("js-base64"),xn=require("axios"),T=require("@glodon-aiot/apis"),An=require("socket.io-client"),gt=require("dayjs"),se=class se{constructor(e,t=!1){this.prefix=e,this.open=t}disable(){this.open=!1}enable(){this.open=!0}log(...e){!this.open&&!se.debug||console.log(this.prefix,...e)}info(...e){!this.open&&!se.debug||console.info(`%c ${this.prefix} %o`,"color:#0f0;",...e)}error(...e){!this.open&&!se.debug||console.error(this.prefix,...e)}warn(...e){!this.open&&!se.debug||console.warn(this.prefix,...e)}};v(se,"debug",!1);let H=se;const yt=["list_directory","read_file","stat_file","search_files","search_text","apply_patch","write_file","upload_file","download_file"],Te="builtin_tools",wt={dev:Te,test:Te,prod:Te,local:Te},Ii=wt,Si="run_python",Ti=wt,Ln=2e4,kn=12e4,Rn=16,we="current-workspace",xi=1024,Le=1024*1024,Ai=50,De=Object.freeze({maxReadBytes:1*Le,maxWriteBytes:5*Le,maxSearchResults:200,maxConcurrentRequests:4,maxTransferBytes:Ai*Le,toolTimeoutMs:3e4,searchTimeoutMs:6e4,transferTimeoutMs:10*6e4,approvalTimeoutMs:5*6e4}),Li=200,ki=1e3,Ri=8,vt=16,Ci=2e3,Mi=1*Le,$e=500,Oi=3,_t=8*xi,Fi=Object.freeze(["glodon.com"]),Ni=Object.freeze([".git","node_modules",".svn",".idea",".vscode"]),Pi=Object.freeze(["~$*",".~lock*","*.tmp"]),Cn=["apply_patch","write_file","upload_file","download_file"],Di=["search_files","search_text"],$i=["upload_file","download_file"];function Bi(i,e){return e===i||e.startsWith(`${i}/`)}function x(i,e=i){return new DOMException(e,i)}function bt(i){return de(this,null,function*(){typeof i=="string"?yield new TextEncoder().encode(i):i instanceof Uint8Array?yield i:yield*Vt(i)})}var p=(i=>(i[i.Ok=0]="Ok",i[i.BadRequest=400]="BadRequest",i[i.Forbidden=403]="Forbidden",i[i.NotFound=404]="NotFound",i[i.Timeout=408]="Timeout",i[i.Conflict=409]="Conflict",i[i.TooLarge=413]="TooLarge",i[i.TooManyRequests=429]="TooManyRequests",i[i.Cancelled=499]="Cancelled",i[i.Internal=500]="Internal",i[i.NotImplemented=501]="NotImplemented",i))(p||{});class m extends Error{constructor(t,n,s){super(n);v(this,"code");v(this,"data");this.name="ToolError",this.code=t,this.data=s}}const Mn="尚未授权工作文件夹,请先在助手中选择或恢复访问工作文件夹。";function Et(){return new m(403,Mn,{reason:"workspace_not_granted"})}function U(){return new m(499,"操作已取消。")}function C(i){if(i!=null&&i.aborted)throw U()}function Ve(i){if(i instanceof m)return i;switch(i&&typeof i=="object"&&"name"in i?String(i.name):""){case"NotFoundError":return new m(404,"文件或目录不存在。");case"TypeMismatchError":return new m(400,"路径类型不匹配:目标是目录而不是文件,或路径中的某一段不是目录。");case"NotAllowedError":case"SecurityError":return Et();case"AbortError":return U();case"NoModificationAllowedError":case"InvalidModificationError":case"InvalidStateError":return new m(403,"文件当前不可写,可能正被其他程序占用或为只读。");case"QuotaExceededError":return new m(413,"磁盘空间不足或超出写入配额。");default:return new m(500,"本地文件操作失败,请稍后重试。")}}const Ue="glodon-workspace",st=1;function On(i){let e=i;if(typeof e=="string")try{e=JSON.parse(e)}catch(n){return}if(!e||typeof e!="object")return;const t=e;if(t.channel===Ue)return t}function Fn(){var e;const i=(e=globalThis.chrome)==null?void 0:e.webview;if(!(!i||typeof i.postMessage!="function"||typeof i.addEventListener!="function"))return i}const Yt=3e4;function Nn(i){let e="";for(let n=0;n<i.length;n+=32768)e+=String.fromCharCode(...i.subarray(n,n+32768));return btoa(e)}function Pn(i){const e=atob(i),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function Xt(i,e){const t=i&&typeof i=="object"?i:{},n=t.kind==="directory"?"directory":"file",s={name:typeof t.name=="string"&&t.name?t.name:e,kind:n};return n==="file"&&typeof t.size=="number"&&(s.size=t.size),typeof t.lastModified=="number"&&(s.lastModified=t.lastModified),s}class Ui{constructor(e,t=""){v(this,"displayName");v(this,"capabilities",new Set);v(this,"sandboxVersion");v(this,"sandboxProtocol");v(this,"seq",0);v(this,"pending",new Map);this.view=e,this.displayName=t}setCapabilities(e,t={}){const n=Array.isArray(e)?e.filter(s=>typeof s=="string"):[];this.capabilities=new Set(n),this.sandboxVersion=typeof t.version=="string"?t.version:void 0,this.sandboxProtocol=typeof t.protocol=="number"?t.protocol:void 0}get canExec(){return this.capabilities.has("sandbox-exec")&&this.sandboxProtocol===st}requireCapability(e){if(!this.capabilities.has(e))throw x("NotAllowedError",`宿主未声明 ${e}。`)}settle(e){const t=this.pending.get(e.id);if(t){if(clearTimeout(t.timer),this.pending.delete(e.id),e.ok===!1){t.reject(x(e.name||"NotAllowedError",e.message||e.name||"NotAllowedError"));return}t.resolve(e)}}call(e,t,n,s=Yt){C(n);const r=`host-${++this.seq}`;return new Promise((o,c)=>{const a=setTimeout(()=>{this.pending.delete(r),c(x("AbortError"))},s),d=()=>{clearTimeout(a),this.pending.delete(r),c(x("AbortError"))};n==null||n.addEventListener("abort",d,{once:!0}),this.pending.set(r,{resolve:h=>{n==null||n.removeEventListener("abort",d),o(h)},reject:c,timer:a}),this.view.postMessage(w({channel:Ue,id:r,op:e},t))})}stat(e){return l(this,null,function*(){const t=yield this.call("stat",{path:e});return Xt(t.entry,e.split("/").pop()||this.displayName)})}listEntries(e,t){return l(this,null,function*(){const n=yield this.call("list",{path:e},t);return(Array.isArray(n.entries)?n.entries:[]).map(r=>Xt(r,""))})}readFile(e){return l(this,null,function*(){var s;const t=yield this.call("read",{path:e}),n=Pn((s=t.contentBase64)!=null?s:"");return new Blob([n])})}createDirectory(e){return l(this,null,function*(){this.requireCapability("fs-mutate"),yield this.call("mkdir",{path:e})})}remove(n){return l(this,arguments,function*(e,t={}){this.requireCapability("fs-mutate"),yield this.call("remove",{path:e,recursive:t.recursive===!0})})}move(e,t){return l(this,null,function*(){this.requireCapability("fs-mutate"),yield this.call("move",{from:e,to:t})})}exec(e){return l(this,null,function*(){var s,r,o;this.requireCapability("sandbox-exec");const t=(s=e.timeoutMs)!=null?s:Yt,n=yield this.call("exec",{protocol:st,cwd:e.cwd,command:e.command,argv:e.argv,timeoutMs:t},e.signal,t+15e3);if(n.timedOut)throw x("AbortError","命令运行超时。");return{exitCode:typeof n.exitCode=="number"?n.exitCode:1,stdout:(r=n.stdout)!=null?r:"",stderr:(o=n.stderr)!=null?o:"",cwd:typeof n.cwd=="string"?n.cwd:void 0}})}runPython(e,t,n,s){return l(this,null,function*(){var o,c;const r=yield this.call("run_python",{path:e,args:t,timeoutMs:n},s,n+15e3);return{exitCode:typeof r.exitCode=="number"?r.exitCode:1,timedOut:r.timedOut===!0,stdout:(o=r.stdout)!=null?o:"",stderr:(c=r.stderr)!=null?c:""}})}writeFile(s,r){return l(this,arguments,function*(e,t,n={}){const o=[];try{for(var h=V(bt(t)),u,f,y;u=!(f=yield h.next()).done;u=!1){const _=f.value;C(n.signal),o.push(_)}}catch(f){y=[f]}finally{try{u&&(f=h.return)&&(yield f.call(h))}finally{if(y)throw y[0]}}const c=o.reduce((_,g)=>_+g.byteLength,0),a=new Uint8Array(c);let d=0;o.forEach(_=>{a.set(_,d),d+=_.byteLength}),yield this.call("write",{path:e,contentBase64:Nn(a),createDirectories:n.createDirectories===!0},n.signal)})}}function B(i,e){throw new m(p.BadRequest,i?`参数 ${i} ${e}`:`参数${e}`)}function Dn(i,e){return typeof i!="string"?i:(e.type==="integer"||e.type==="number")&&/^-?\d+(\.\d+)?$/.test(i.trim())?Number(i):e.type==="boolean"&&(i==="true"||i==="false")?i==="true":i}function rt(i,e,t){switch(i=Dn(i,e),e.type){case"string":typeof i!="string"&&B(t,"必须是字符串。"),e.minLength!==void 0&&i.length<e.minLength&&B(t,"不能为空。"),e.maxLength!==void 0&&i.length>e.maxLength&&B(t,`不能超过 ${e.maxLength} 字。`);break;case"integer":(typeof i!="number"||!Number.isInteger(i))&&B(t,"必须是整数。");break;case"number":(typeof i!="number"||!Number.isFinite(i))&&B(t,"必须是数字。");break;case"boolean":typeof i!="boolean"&&B(t,"必须是布尔值。");break;case"array":if(Array.isArray(i)||B(t,"必须是数组。"),e.minItems!==void 0&&i.length<e.minItems&&B(t,"不能为空。"),e.items){const n=e.items;return i.map((s,r)=>rt(s,n,`${t}[${r}]`))}break;case"object":return ji(i,e,t)}return e.enum&&!e.enum.includes(i)&&B(t,`必须是 ${e.enum.join("、")} 之一。`),typeof i=="number"&&(e.minimum!==void 0&&i<e.minimum&&B(t,`不能小于 ${e.minimum}。`),e.maximum!==void 0&&i>e.maximum&&B(t,`不能大于 ${e.maximum}。`)),i}function ji(i,e,t){var r,o;(!i||typeof i!="object"||Array.isArray(i))&&B(t,"必须是对象。");const n=i,s={};for(const c of(r=e.required)!=null?r:[])(n[c]===void 0||n[c]===null)&&B(t?`${t}.${c}`:c,"是必填项。");for(const[c,a]of Object.entries((o=e.properties)!=null?o:{})){if(n[c]===void 0||n[c]===null)continue;const d=t?`${t}.${c}`:c;s[c]=a.oneOf?(rt(n[c],E(w({},a),{oneOf:void 0}),d),n[c]):rt(n[c],a,d)}return s}function Hi(i,e){return ji(i,e,"")}const ot=["shell","read_file","write_file","append_file","run_file","edit_file","grep","find","load_skill","read_skill_resource","run_skill_script"],at=81920,je=81920,$n=2e4,qi=".",F="/workspace",Bn=[".py",".sh",".js"],Un=["input","output","uploads","tmp"],It="不要使用 input、output、uploads、tmp,也不要新建这些目录。请把文件直接放在工作区已有位置或根目录。",jn=/(?:^|[\s'"=;|&<>`:])\/?(?:input|output|uploads|tmp)(?=\/|[\s'"=;|&<>`:]|$)/;function He(i){return jn.test(i)}function St(i){const e=i.split("/")[0];return Un.includes(e)}function ct(i){throw new m(p.Forbidden,i,{reason:"path_outside_workspace"})}function Wi(i){if(typeof i!="string"||i.length===0)throw new m(p.BadRequest,"path 必须是工作区内绝对路径。");(i.includes("\0")||i.includes("\\"))&&ct("路径不能包含反斜杠。");const e=i.normalize("NFC").trim();if(!e.startsWith("/"))throw new m(p.BadRequest,"path 必须是工作区内绝对路径,例如 /说明.md。");const t=e.split("/").filter(n=>n.length>0);if(t.some(n=>n==="."||n==="..")&&ct("路径不能包含 . 或 .. 。"),t.length>0&&St(t[0]))throw new m(p.BadRequest,It);return t.join("/")}function _e(i){return Wi(i)}function Hn(i){return Wi(i)}function Tt(i){return i?`/${i}`:"/"}function qn(i){if(i===".")return!0;if(!i||i.startsWith("/")||i.includes("\\")||i.includes("\0"))return!1;const e=i.split("/").filter(t=>t.length>0);return e.length>0&&e.every(t=>t!=="."&&t!=="..")&&!St(e[0])}function xt(i,e){if(!i||/[\\/\0]/.test(i)||i==="."||i==="..")throw new m(p.BadRequest,"skill_name 必须是单个技能目录名。");if(!e||e.startsWith("/")||e.includes("\\")||e.includes("\0"))throw new m(p.BadRequest,"资源路径必须是技能目录内的相对路径。");const t=e.split("/").filter(n=>n.length>0);return(t.length===0||t.some(n=>n==="."||n===".."))&&ct("资源路径不能跳出技能目录。"),`skills/${i}/${t.join("/")}`}const zi="https://cv-cdn.obs.cn-north-4.myhuaweicloud.com/glodon/libs/",Wn="3.6.0",zn=`${zi}just-bash/${Wn}/just-bash.mjs`,Vn="314.0.7",Yn=`${zi}pyodide/${Vn}/`,Vi=["numpy","pandas","matplotlib","pillow","lxml"],Xe=new Map;function Xn(i){return import(i)}function Gn(i){let e=Xe.get(i);return e||(e=Xn(i).catch(t=>{throw Xe.delete(i),t}),Xe.set(i,e)),e}const Gt=new Map;function Kn(i){return/[\\^$.|+()[\]{}]/.test(i)?`\\${i}`:i}function Qn(i,e=!1){const t=`${e?"s":"i"}:${i}`,n=Gt.get(t);if(n)return n;let s="";for(let o=0;o<i.length;o++){const c=i[o];c==="*"?i[o+1]==="*"?(o++,i[o+1]==="/"?(o++,s+="(?:.*/)?"):s+=".*"):s+="[^/]*":c==="?"?s+="[^/]":s+=Kn(c)}const r=new RegExp(`^${s}$`,e?"":"i");return Gt.set(t,r),r}function qe(i,e,t=!1){return Qn(i,t).test(e)}function At(i){const e=i.lastIndexOf("/");return e<0?i:i.slice(e+1)}const Yi=Object.freeze([{id:"env-files",pattern:".env*",reason:"环境变量文件可能包含密钥",source:"sdk-baseline"},{id:"pem",pattern:"*.pem",reason:"证书或密钥文件",source:"sdk-baseline"},{id:"key",pattern:"*.key",reason:"密钥文件",source:"sdk-baseline"},{id:"p12",pattern:"*.p12",reason:"证书文件",source:"sdk-baseline"},{id:"pfx",pattern:"*.pfx",reason:"证书文件",source:"sdk-baseline"},{id:"id-rsa",pattern:"id_rsa*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"id-ed25519",pattern:"id_ed25519*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"id-ecdsa",pattern:"id_ecdsa*",reason:"SSH 私钥",source:"sdk-baseline"},{id:"credentials",pattern:".credentials",reason:"凭据文件",source:"sdk-baseline"},{id:"npmrc",pattern:".npmrc",reason:"可能包含 registry token",source:"sdk-baseline"},{id:"pypirc",pattern:".pypirc",reason:"可能包含仓库凭据",source:"sdk-baseline"},{id:"aws-credentials",pattern:"**/.aws/credentials",match:"path",reason:"云服务凭据",source:"sdk-baseline"},{id:"ssh-dir",pattern:"**/.ssh/**",match:"path",reason:"SSH 配置与密钥",source:"sdk-baseline"}]),Jn="该文件被列为敏感文件,不允许访问";class Xi{constructor(e=[]){v(this,"rules");const t=e.filter(n=>n&&typeof n.pattern=="string"&&n.pattern).map(n=>E(w({},n),{id:String(n.id||n.pattern),source:n.source==="enterprise"?"enterprise":"product"}));this.rules=[...Yi,...t]}match(e,t){if(!e)return null;const n=At(e);for(const s of this.rules){if(s.operations&&!s.operations.includes(t))continue;const r=s.match==="path"?e:n;if(qe(s.pattern,r))return s}return null}isSensitive(e){return["read","write","search"].some(t=>this.match(e,t)!==null)}static reasonOf(e){return`${e.reason||Jn},已拒绝访问。`}}function be(i,e,t){const n=i.sensitive.match(e,t);if(n)throw new m(p.Forbidden,Xi.reasonOf(n),{reason:"sensitive_file",ruleId:n.id})}function Be(i,e){return l(this,null,function*(){try{return yield i.stat(e)}catch(t){if(Ve(t).code===p.NotFound)return null;throw t}})}function Lt(i,e){return l(this,null,function*(){const t=yield i.stat(e);if(t.kind!=="file")throw new m(p.BadRequest,"目标是目录,不是文件。");return t})}function ve(i){return l(this,null,function*(){const e=yield crypto.subtle.digest("SHA-256",i);return`sha256:${Array.from(new Uint8Array(e)).map(n=>n.toString(16).padStart(2,"0")).join("")}`})}function z(i){return l(this,null,function*(){return new Uint8Array(yield i.arrayBuffer())})}function oe(i){const e=Math.min(i.byteLength,_t);for(let t=0;t<e;t++)if(i[t]===0)return!0;return!1}function Zn(i){return l(this,null,function*(){return oe(yield z(i.slice(0,_t)))})}function Gi(i){return i[0]===239&&i[1]===187&&i[2]===191}function es(i){try{return new TextDecoder("utf-8",{fatal:!0}).decode(i)}catch(e){throw new m(p.BadRequest,"文件不是 UTF-8 编码,暂不支持修改。")}}function kt(i){return new TextEncoder().encode(i).byteLength}function Ki(){return new Promise(i=>setTimeout(i,0))}function ts(i){return i>=1024*1024?`${(i/1024/1024).toFixed(1)} MB`:i>=1024?`${(i/1024).toFixed(1)} KB`:`${i} B`}function re(i,e="文件"){return new m(p.TooLarge,`${e}超过大小上限 ${ts(i)}。`)}const is=`# 在 Pyodide 里按 python3 命令行的语义运行代码。由 pyodideWorker.js 加载,最后一个表达式 run 交给 JS 调用。
|
|
2
|
+
# 解释器在多次命令之间复用,所以每次运行前恢复 sys.path、环境变量和工作目录,并丢掉工作区里的模块缓存。
|
|
3
|
+
import io
|
|
4
|
+
import os
|
|
5
|
+
import runpy
|
|
6
|
+
import sys
|
|
7
|
+
import traceback
|
|
8
|
+
|
|
9
|
+
ROOTS = ('/workspace',)
|
|
10
|
+
BASE_PATH = list(sys.path)
|
|
11
|
+
BASE_ENV = dict(os.environ)
|
|
12
|
+
HOME = os.environ.get('HOME', '/home/pyodide')
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _from_workspace(module):
|
|
16
|
+
path = getattr(module, '__file__', None) or ''
|
|
17
|
+
return any(path == root or path.startswith(root + '/') for root in ROOTS)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _reset():
|
|
21
|
+
for name, module in list(sys.modules.items()):
|
|
22
|
+
if _from_workspace(module):
|
|
23
|
+
del sys.modules[name]
|
|
24
|
+
sys.path[:] = BASE_PATH
|
|
25
|
+
os.environ.clear()
|
|
26
|
+
os.environ.update(BASE_ENV)
|
|
27
|
+
os.chdir(HOME)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _internal(frame):
|
|
31
|
+
name = frame.f_code.co_filename
|
|
32
|
+
return name == '<exec>' or name.endswith('/runpy.py')
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _print_error(error):
|
|
36
|
+
tb = error.__traceback__
|
|
37
|
+
while tb is not None and _internal(tb.tb_frame):
|
|
38
|
+
tb = tb.tb_next
|
|
39
|
+
traceback.print_exception(type(error), error, tb)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _exit_code(value):
|
|
43
|
+
if value is None:
|
|
44
|
+
return 0
|
|
45
|
+
if isinstance(value, int):
|
|
46
|
+
return value & 0xFF
|
|
47
|
+
print(value, file=sys.stderr)
|
|
48
|
+
return 1
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def run(mode, target, argv, cwd, stdin):
|
|
52
|
+
_reset()
|
|
53
|
+
sys.argv = list(argv)
|
|
54
|
+
sys.stdin = io.TextIOWrapper(io.BytesIO(stdin.to_bytes()), encoding='utf-8', errors='replace')
|
|
55
|
+
try:
|
|
56
|
+
os.chdir(cwd)
|
|
57
|
+
except OSError:
|
|
58
|
+
os.chdir('/')
|
|
59
|
+
try:
|
|
60
|
+
if mode == 'c':
|
|
61
|
+
sys.path.insert(0, '')
|
|
62
|
+
exec(compile(target, '<string>', 'exec'), {'__name__': '__main__'})
|
|
63
|
+
elif mode == 'm':
|
|
64
|
+
sys.path.insert(0, os.getcwd())
|
|
65
|
+
runpy.run_module(target, run_name='__main__', alter_sys=True)
|
|
66
|
+
elif not os.path.isfile(target):
|
|
67
|
+
print(f"python3: can't open file '{target}': [Errno 2] No such file or directory", file=sys.stderr)
|
|
68
|
+
return 2
|
|
69
|
+
else:
|
|
70
|
+
sys.path.insert(0, os.path.dirname(target))
|
|
71
|
+
runpy.run_path(target, run_name='__main__')
|
|
72
|
+
return 0
|
|
73
|
+
except SystemExit as error:
|
|
74
|
+
return _exit_code(error.code)
|
|
75
|
+
except ModuleNotFoundError as error:
|
|
76
|
+
_print_error(error)
|
|
77
|
+
name = (error.name or '').split('.')[0]
|
|
78
|
+
if name:
|
|
79
|
+
print(
|
|
80
|
+
f'浏览器环境没有 {name}。这里只能用标准库和 {"、".join(PACKAGES)},需要其他包请改用宿主环境。',
|
|
81
|
+
file=sys.stderr,
|
|
82
|
+
)
|
|
83
|
+
return 1
|
|
84
|
+
except BaseException as error:
|
|
85
|
+
_print_error(error)
|
|
86
|
+
return 1
|
|
87
|
+
finally:
|
|
88
|
+
sys.stdout.flush()
|
|
89
|
+
sys.stderr.flush()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
run
|
|
93
|
+
`,ns=`// Pyodide 专用 Worker。PythonRunner 用这份源码创建 Blob Module Worker,不经过集成方的打包器,
|
|
94
|
+
// 所以这里只能写浏览器直接能跑的 JS,不能有 import/export 语句和顶层 await。
|
|
95
|
+
//
|
|
96
|
+
// init { indexURL, packages, runner } → ready | failed { message }
|
|
97
|
+
// run { id, files, dirs, cwd, mode, target, argv, stdin } → result { id, exitCode, stdout, stderr, written, removed, createdDirs, removedDirs }
|
|
98
|
+
'use strict';
|
|
99
|
+
|
|
100
|
+
const ROOTS = ['/workspace'];
|
|
101
|
+
const OUTPUT_LIMIT = 16 * 1024 * 1024;
|
|
102
|
+
|
|
103
|
+
let pyodide = null;
|
|
104
|
+
let runPython = null;
|
|
105
|
+
let sink = null;
|
|
106
|
+
|
|
107
|
+
/** Emscripten 的 ErrnoError 不是 Error,只带 errno 和 code。 */
|
|
108
|
+
function describe(error) {
|
|
109
|
+
if (error && error.message) return error.message;
|
|
110
|
+
if (error && (error.code || error.errno !== undefined)) return \`文件系统错误 \${error.code || \`errno \${error.errno}\`}\`;
|
|
111
|
+
return String(error);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function networkDenied(url) {
|
|
115
|
+
return new TypeError(\`浏览器里的 Python 不能访问网络:\${url}\`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** 只放行 indexURL 下的资源(Pyodide 自身和白名单 wheel),其余请求一律拒绝。 */
|
|
119
|
+
function guardNetwork(indexURL) {
|
|
120
|
+
const realFetch = globalThis.fetch ? globalThis.fetch.bind(globalThis) : null;
|
|
121
|
+
const resolve = (input) => {
|
|
122
|
+
const raw = typeof input === 'string' || input instanceof URL ? String(input) : input && input.url;
|
|
123
|
+
try {
|
|
124
|
+
return new URL(raw, indexURL).href;
|
|
125
|
+
} catch {
|
|
126
|
+
return String(raw);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
globalThis.fetch = (input, init) => {
|
|
130
|
+
const url = resolve(input);
|
|
131
|
+
if (!realFetch || !url.startsWith(indexURL)) return Promise.reject(networkDenied(url));
|
|
132
|
+
return realFetch(input, init);
|
|
133
|
+
};
|
|
134
|
+
for (const name of ['XMLHttpRequest', 'WebSocket', 'EventSource']) {
|
|
135
|
+
globalThis[name] = class {
|
|
136
|
+
constructor(url) {
|
|
137
|
+
throw networkDenied(url === undefined ? name : resolve(url));
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function collector() {
|
|
144
|
+
const decoder = new TextDecoder();
|
|
145
|
+
let text = '';
|
|
146
|
+
let size = 0;
|
|
147
|
+
let dropped = false;
|
|
148
|
+
return {
|
|
149
|
+
write(bytes) {
|
|
150
|
+
if (dropped || size + bytes.length > OUTPUT_LIMIT) {
|
|
151
|
+
dropped = true;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
size += bytes.length;
|
|
155
|
+
text += decoder.decode(bytes, { stream: true });
|
|
156
|
+
},
|
|
157
|
+
finish() {
|
|
158
|
+
return text + decoder.decode() + (dropped ? '\\n…输出超过 16 MB,后面的内容已丢弃\\n' : '');
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function init({ indexURL, packages, runner }) {
|
|
164
|
+
guardNetwork(indexURL);
|
|
165
|
+
const { loadPyodide } = await import(indexURL + 'pyodide.mjs');
|
|
166
|
+
pyodide = await loadPyodide({ indexURL, env: { HOME: '/home/pyodide', MPLBACKEND: 'Agg' } });
|
|
167
|
+
const stream = (name) => ({
|
|
168
|
+
write(bytes) {
|
|
169
|
+
if (sink) sink[name].write(bytes);
|
|
170
|
+
return bytes.length;
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
pyodide.setStdout(stream('stdout'));
|
|
174
|
+
pyodide.setStderr(stream('stderr'));
|
|
175
|
+
runPython = pyodide.runPython(runner, { globals: pyodide.toPy({ PACKAGES: packages }) });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function dirname(path) {
|
|
179
|
+
const index = path.lastIndexOf('/');
|
|
180
|
+
return index <= 0 ? '/' : path.slice(0, index);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** 主脚本、\`-c\` 代码,以及主脚本目录和 cwd 下的 .py 文件里出现的 import。 */
|
|
184
|
+
function sourcesToScan({ files, cwd, mode, target }) {
|
|
185
|
+
const decoder = new TextDecoder();
|
|
186
|
+
const sources = mode === 'c' ? [target] : [];
|
|
187
|
+
const dirs = new Set([cwd]);
|
|
188
|
+
if (mode === 'file') dirs.add(dirname(target));
|
|
189
|
+
for (const file of files) {
|
|
190
|
+
if (file.path.endsWith('.py') && (file.path === target || dirs.has(dirname(file.path)))) {
|
|
191
|
+
sources.push(decoder.decode(file.data));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return sources;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async function loadPackages(sources, stderr) {
|
|
198
|
+
const encoder = new TextEncoder();
|
|
199
|
+
const report = (message) => stderr.write(encoder.encode(\`\${message}\\n\`));
|
|
200
|
+
for (const source of sources) {
|
|
201
|
+
try {
|
|
202
|
+
await pyodide.loadPackagesFromImports(source, { messageCallback() {}, errorCallback: report });
|
|
203
|
+
} catch (error) {
|
|
204
|
+
report(\`加载 Python 包失败:\${describe(error)}\`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function lstat(path) {
|
|
210
|
+
try {
|
|
211
|
+
return pyodide.FS.lstat(path);
|
|
212
|
+
} catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function removeTree(path) {
|
|
218
|
+
const { FS } = pyodide;
|
|
219
|
+
const stat = lstat(path);
|
|
220
|
+
if (!stat) return;
|
|
221
|
+
if (!FS.isDir(stat.mode)) {
|
|
222
|
+
FS.unlink(path);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
for (const name of FS.readdir(path)) {
|
|
226
|
+
if (name !== '.' && name !== '..') removeTree(\`\${path}/\${name}\`);
|
|
227
|
+
}
|
|
228
|
+
FS.rmdir(path);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function walk(path, files, dirs) {
|
|
232
|
+
const { FS } = pyodide;
|
|
233
|
+
for (const name of FS.readdir(path)) {
|
|
234
|
+
if (name === '.' || name === '..') continue;
|
|
235
|
+
const child = \`\${path}/\${name}\`;
|
|
236
|
+
const stat = lstat(child);
|
|
237
|
+
if (!stat) continue;
|
|
238
|
+
if (FS.isDir(stat.mode)) {
|
|
239
|
+
dirs.add(child);
|
|
240
|
+
walk(child, files, dirs);
|
|
241
|
+
} else if (FS.isFile(stat.mode)) {
|
|
242
|
+
files.set(child, FS.readFile(child));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function sameBytes(a, b) {
|
|
248
|
+
if (a.length !== b.length) return false;
|
|
249
|
+
for (let index = 0; index < a.length; index += 1) if (a[index] !== b[index]) return false;
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async function execute(message) {
|
|
254
|
+
const { FS } = pyodide;
|
|
255
|
+
const output = { stdout: collector(), stderr: collector() };
|
|
256
|
+
await loadPackages(sourcesToScan(message), output.stderr);
|
|
257
|
+
|
|
258
|
+
const before = new Map();
|
|
259
|
+
const beforeDirs = new Set(ROOTS);
|
|
260
|
+
// 上次运行停在某个根目录里时,Emscripten 不允许删除当前目录。
|
|
261
|
+
FS.chdir('/');
|
|
262
|
+
for (const root of ROOTS) {
|
|
263
|
+
removeTree(root);
|
|
264
|
+
FS.mkdirTree(root);
|
|
265
|
+
}
|
|
266
|
+
for (const dir of message.dirs) {
|
|
267
|
+
FS.mkdirTree(dir);
|
|
268
|
+
beforeDirs.add(dir);
|
|
269
|
+
}
|
|
270
|
+
for (const file of message.files) {
|
|
271
|
+
FS.mkdirTree(dirname(file.path));
|
|
272
|
+
FS.writeFile(file.path, file.data);
|
|
273
|
+
before.set(file.path, file.data);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
sink = output;
|
|
277
|
+
let exitCode;
|
|
278
|
+
const argv = pyodide.toPy(message.argv);
|
|
279
|
+
try {
|
|
280
|
+
exitCode = runPython(message.mode, message.target, argv, message.cwd, message.stdin);
|
|
281
|
+
} finally {
|
|
282
|
+
argv.destroy();
|
|
283
|
+
sink = null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const after = new Map();
|
|
287
|
+
const afterDirs = new Set();
|
|
288
|
+
for (const root of ROOTS) if (lstat(root)) walk(root, after, afterDirs);
|
|
289
|
+
|
|
290
|
+
const written = [];
|
|
291
|
+
for (const [path, data] of after) {
|
|
292
|
+
const old = before.get(path);
|
|
293
|
+
if (!old || !sameBytes(old, data)) written.push({ path, data });
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
exitCode,
|
|
297
|
+
stdout: output.stdout.finish(),
|
|
298
|
+
stderr: output.stderr.finish(),
|
|
299
|
+
written,
|
|
300
|
+
removed: [...before.keys()].filter((path) => !after.has(path)),
|
|
301
|
+
createdDirs: [...afterDirs].filter((dir) => !beforeDirs.has(dir)),
|
|
302
|
+
removedDirs: [...beforeDirs].filter((dir) => !ROOTS.includes(dir) && !afterDirs.has(dir)),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
self.onmessage = (event) => {
|
|
307
|
+
const message = event.data;
|
|
308
|
+
if (message.type === 'init') {
|
|
309
|
+
init(message).then(
|
|
310
|
+
() => self.postMessage({ type: 'ready' }),
|
|
311
|
+
(error) => self.postMessage({ type: 'failed', message: describe(error) })
|
|
312
|
+
);
|
|
313
|
+
} else if (message.type === 'run') {
|
|
314
|
+
execute(message).then(
|
|
315
|
+
(result) => self.postMessage({ type: 'result', id: message.id, ...result }),
|
|
316
|
+
(error) =>
|
|
317
|
+
self.postMessage({
|
|
318
|
+
type: 'result',
|
|
319
|
+
id: message.id,
|
|
320
|
+
exitCode: 1,
|
|
321
|
+
stdout: '',
|
|
322
|
+
stderr: \`Python 运行环境出错:\${describe(error)}\\n\`,
|
|
323
|
+
written: [],
|
|
324
|
+
removed: [],
|
|
325
|
+
createdDirs: [],
|
|
326
|
+
removedDirs: [],
|
|
327
|
+
})
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
`,dt=`浏览器环境不能安装依赖。可以直接 import ${Vi.join("、")},需要其他包请改用宿主环境。
|
|
332
|
+
`,ss=10*1024*1024,rs=64*1024*1024;function os(i){return!i||i==="."||i==="/"?F:i===F||i.startsWith(`${F}/`)?i:`${F}/${i.replace(/^\/+/,"")}`}function Oe(i){if(i===F)return"";if(i.startsWith(`${F}/`))return i.slice(F.length+1)}const as=new Set(["-u","-B","-E","-s","-S","-I","-O","-OO","-q","-b","-bb"]);function le(i,e,t=""){return{exitCode:i,stdout:t,stderr:e}}function cs(i,e){const t=[];for(const n of(e.startsWith("/")?e:`${i}/${e}`).split("/"))!n||n==="."||(n===".."?t.pop():t.push(n));return`/${t.join("/")}`}function ds(i,e,t){const n=new Uint8Array(0);for(let s=0;s<i.length;s+=1){const r=i[s],o=i.slice(s+1);if(r==="-c"||r.startsWith("-c")&&!r.startsWith("--")){const c=r==="-c"?o.shift():r.slice(2);return c===void 0?le(2,`python3: -c 后面缺少代码
|
|
333
|
+
`):{mode:"c",target:c,argv:["-c",...o],stdin:t}}if(r==="-m"){const c=o.shift();return c?c==="pip"||c==="ensurepip"?le(1,dt):{mode:"m",target:c,argv:[c,...o],stdin:t}:le(2,`python3: -m 后面缺少模块名
|
|
334
|
+
`)}if(r==="-V"||r==="--version")return{mode:"c",target:"import sys; print('Python ' + sys.version.split()[0])",argv:["-c"],stdin:t};if(r==="-h"||r==="--help")return le(0,"",`usage: python3 [option] ... [-c cmd | -m mod | file | -] [arg] ...
|
|
335
|
+
`);if(!(as.has(r)||/^-[WX]./.test(r))){if(r==="-W"||r==="-X"){s+=1;continue}return r==="-"?{mode:"c",target:new TextDecoder().decode(t),argv:["-",...o],stdin:n}:r.startsWith("-")?le(2,`python3: 浏览器环境不支持参数 ${r}
|
|
336
|
+
`):{mode:"file",target:cs(e,r),argv:[r,...o],stdin:t}}}return t.length>0?{mode:"c",target:new TextDecoder().decode(t),argv:[""],stdin:n}:le(2,`浏览器环境不支持交互式 Python,请用 python3 -c "…" 或脚本文件。
|
|
337
|
+
`)}function Ge(i){var e;return i&&typeof i=="object"?String((e=i.name)!=null?e:""):""}function Ke(i){return i instanceof Error?i.message:String(i)}function Kt(i,e){return new Promise((t,n)=>{if(!i)return;const s=()=>{e==null||e(),n(x("AbortError"))};i.aborted?s():i.addEventListener("abort",s,{once:!0})})}function ls(i){const e=URL.createObjectURL(new Blob([i],{type:"text/javascript"})),t=new Worker(e,{type:"module"}),n=()=>URL.revokeObjectURL(e);return t.addEventListener("message",n,{once:!0}),t.addEventListener("error",n,{once:!0}),t}class hs{constructor(e){v(this,"state");v(this,"queue",Promise.resolve());v(this,"nextId",0);this.options=e}get indexURL(){return this.options.indexURL||Yn}loadError(e){return new m(p.NotImplemented,`Python 运行环境加载失败,请确认页面能访问 ${this.indexURL}(CSP 需在 script-src、connect-src 放行该地址,worker-src 放行 blob:)。${e}`)}dispose(e,t){this.state===e&&(this.state=void 0),e.worker.terminate(),e.pending.forEach(({reject:n})=>n(t)),e.pending.clear()}spawn(){var r;let e;try{e=((r=this.options.createWorker)!=null?r:ls)(ns)}catch(o){throw this.loadError(`(${Ke(o)})`)}let t;const n=new Promise((o,c)=>t={resolve:o,reject:c}),s={worker:e,ready:n,pending:new Map};return n.catch(()=>{}),e.onmessage=({data:o})=>{var a;const c=o;if(c.type==="ready")t.resolve();else if(c.type==="failed"){const d=this.loadError(`(${c.message})`);t.reject(d),this.dispose(s,d)}else c.type==="result"&&((a=s.pending.get(c.id))==null||a.resolve(c),s.pending.delete(c.id))},e.onerror=o=>{var d;const c=Ke((d=o==null?void 0:o.message)!=null?d:o),a=this.loadError(`(${c})`);t.reject(a),this.dispose(s,new Error(`Python 运行环境意外退出:${c}`))},e.postMessage({type:"init",indexURL:this.indexURL,packages:Vi,runner:is}),s}run(e){const t=this.queue.then(()=>this.runNow(e));return this.queue=t.catch(()=>{}),t}runNow(e){return l(this,null,function*(){var u,f,y;const t=os(e.cwd),n=ds(e.args,t,(u=e.stdin)!=null?u:new Uint8Array(0));if(!("mode"in n))return n;if((f=e.signal)!=null&&f.aborted)throw x("AbortError");const s=(y=this.state)!=null?y:this.state=this.spawn();yield Promise.race([s.ready,Kt(e.signal)]);const r=yield this.collect(e.signal),o=this.nextId+=1,c=new Promise((_,g)=>s.pending.set(o,{resolve:_,reject:g}));s.worker.postMessage(w({type:"run",id:o,files:r.files,dirs:r.dirs,cwd:t},n),r.files.map(_=>_.data.buffer));const a=yield Promise.race([c,Kt(e.signal,()=>this.dispose(s,x("AbortError")))]),d=[];if(r.skipped.length>0){const _=r.skipped.slice(0,5).map(b=>`/${b}`),g=r.skipped.length>_.length?` 等 ${r.skipped.length} 个`:"";d.push(`提示:${_.join("、")}${g}文件超过同步上限(单个 10 MB、合计 64 MB),Python 里看不到。`)}return{exitCode:(yield this.writeBack(a,r,d))&&a.exitCode===0?1:a.exitCode,stdout:a.stdout,stderr:a.stderr+d.map(_=>`${_}
|
|
338
|
+
`).join("")}})}collect(e){return l(this,null,function*(){const{adapter:t,sensitive:n}=this.options,s={files:[],dirs:[],synced:new Set,skipped:[]};let r=0;const o=c=>l(this,null,function*(){var d,h;let a;try{a=yield t.listEntries(c,e)}catch(u){if(Ge(u)==="NotFoundError"||Ge(u)==="TypeMismatchError")return;throw u}s.dirs.push(c?`${F}/${c}`:F);for(const u of a.sort((f,y)=>f.name.localeCompare(y.name))){const f=c?`${c}/${u.name}`:u.name;if(u.kind==="directory"){yield o(f);continue}if(n.match(f,"read"))continue;const y=(h=(d=u.size)!=null?d:(yield t.stat(f)).size)!=null?h:0;if(y>ss||r+y>rs){s.skipped.push(f);continue}const _=yield z(yield t.readFile(f));r+=_.byteLength,s.files.push({path:`${F}/${f}`,data:_}),s.synced.add(f)}});return yield o(""),s})}exists(e){return l(this,null,function*(){try{return yield this.options.adapter.stat(e),!0}catch(t){return!1}})}writeBack(e,t,n){return l(this,null,function*(){const{adapter:s,sensitive:r}=this.options;let o=!1;const c=(d,h)=>{o=!0,n.push(`写回 ${d} 失败:${Ke(h)}`)};for(const d of e.createdDirs.sort()){const h=Oe(d);!h||!s.createDirectory||(yield s.createDirectory(h).catch(u=>c(d,u)))}for(const{path:d,data:h}of e.written){const u=Oe(d);u&&(r.match(u,"write")?n.push(`没有写回 ${d}:敏感文件不能由命令修改。`):!t.synced.has(u)&&(yield this.exists(u))?n.push(`没有写回 ${d}:工作区里已有这个文件,但它没有同步进 Python,为避免覆盖已跳过。`):yield s.writeFile(u,h,{createDirectories:!0}).catch(f=>c(d,f)))}if(e.removed.length>0&&!s.remove)return n.push(`当前工作区不支持删除,${e.removed.join("、")} 仍然保留。`),o;for(const d of e.removed){const h=Oe(d);h&&(yield s.remove(h).catch(u=>{Ge(u)!=="NotFoundError"&&c(d,u)}))}const a=e.removedDirs.sort((d,h)=>h.split("/").length-d.split("/").length);for(const d of a){const h=Oe(d);h&&(yield s.remove(h).catch(()=>{}))}return o})}}const us={ENOENT:"no such file or directory",EEXIST:"file already exists",EISDIR:"illegal operation on a directory",ENOTDIR:"not a directory",ENOTEMPTY:"directory not empty",EACCES:"permission denied",EPERM:"operation not permitted",EINVAL:"invalid argument",EIO:"i/o error"};function R(i,e,t){var s;const n=new Error(`${i}: ${(s=us[i])!=null?s:i}, ${e} '${t}'`);return n.code=i,n}function Fe(i){var e;return i&&typeof i=="object"?String((e=i.name)!=null?e:""):""}function Qe(i){const e=typeof i=="string"?i:i==null?void 0:i.encoding;return(e!=null?e:"utf8").toLowerCase()}function Qt(i){let e="";for(let t=0;t<i.length;t+=32768)e+=String.fromCharCode(...i.subarray(t,t+32768));return e}function fs(i,e){switch(e){case"binary":case"latin1":case"ascii":return Qt(i);case"base64":return btoa(Qt(i));case"hex":return Array.from(i,t=>t.toString(16).padStart(2,"0")).join("");default:return new TextDecoder().decode(i)}}function Jt(i,e){var t;if(typeof i!="string")return i;switch(e){case"binary":case"latin1":case"ascii":return Uint8Array.from(i,n=>n.charCodeAt(0)&255);case"base64":return Uint8Array.from(atob(i),n=>n.charCodeAt(0));case"hex":return Uint8Array.from((t=i.match(/../g))!=null?t:[],n=>parseInt(n,16));default:return new TextEncoder().encode(i)}}function J(i){const e=[];for(const t of i.split("/"))!t||t==="."||(t===".."?e.pop():e.push(t));return`/${e.join("/")}`}class ps{constructor(e,t,n){this.adapter=e,this.root=t,this.sensitive=n}relative(e){const t=J(e).slice(1);return this.root?t?`${this.root}/${t}`:this.root:t}shown(e){const t=this.relative(e);return t?`/${t}`:"/"}isRoot(e){return J(e)==="/"}guard(e,t,n){const s=this.relative(e);if(this.sensitive.match(s,t))throw R("EACCES",n,this.shown(e));return s}mapError(e,t,n){if(e&&typeof e=="object"&&typeof e.code=="string")return e;switch(Fe(e)){case"NotFoundError":return R("ENOENT",t,this.shown(n));case"TypeMismatchError":return R(t==="open"||t==="write"?"EISDIR":"ENOTDIR",t,this.shown(n));case"InvalidModificationError":return R(t==="rm"?"ENOTEMPTY":"EEXIST",t,this.shown(n));case"NotAllowedError":case"SecurityError":case"NoModificationAllowedError":return R("EACCES",t,this.shown(n));default:return R("EIO",t,this.shown(n))}}entry(e,t){return l(this,null,function*(){try{return yield this.adapter.stat(this.relative(e))}catch(n){if(this.isRoot(e)&&Fe(n)==="NotFoundError")return{name:this.root,kind:"directory"};throw this.mapError(n,t,e)}})}ensureRoot(){return l(this,null,function*(){if(this.root)try{yield this.adapter.stat(this.root)}catch(e){if(Fe(e)!=="NotFoundError")throw e;this.adapter.createDirectory&&(yield this.adapter.createDirectory(this.root))}})}readFileBuffer(e){return l(this,null,function*(){const t=this.guard(e,"read","open");if((yield this.entry(e,"open")).kind!=="file")throw R("EISDIR","read",this.shown(e));try{return yield z(yield this.adapter.readFile(t))}catch(s){throw this.mapError(s,"open",e)}})}readFile(e,t){return l(this,null,function*(){return fs(yield this.readFileBuffer(e),Qe(t))})}writeFile(e,t,n){return l(this,null,function*(){if(this.isRoot(e))throw R("EISDIR","open",this.shown(e));const s=this.guard(e,"write","open"),r=J(e).lastIndexOf("/")===0;try{r&&(yield this.ensureRoot()),yield this.adapter.writeFile(s,Jt(t,Qe(n)),{createDirectories:!0})}catch(o){throw this.mapError(o,"open",e)}})}appendFile(e,t,n){return l(this,null,function*(){let s=new Uint8Array;(yield this.exists(e))&&(s=yield this.readFileBuffer(e));const r=Jt(t,Qe(n)),o=new Uint8Array(s.byteLength+r.byteLength);o.set(s),o.set(r,s.byteLength),yield this.writeFile(e,o)})}exists(e){return l(this,null,function*(){try{return yield this.entry(e,"access"),!0}catch(t){return!1}})}stat(e){return l(this,null,function*(){var s,r;const t=yield this.entry(e,"stat"),n=t.kind==="directory";return{isFile:!n,isDirectory:n,isSymbolicLink:!1,mode:n?493:420,size:(s=t.size)!=null?s:0,mtime:new Date((r=t.lastModified)!=null?r:0)}})}lstat(e){return this.stat(e)}mkdir(e,t){return l(this,null,function*(){if(!this.adapter.createDirectory)throw R("EPERM","mkdir",this.shown(e));if(yield this.exists(e)){if(t!=null&&t.recursive)return;throw R("EEXIST","mkdir",this.shown(e))}if(!(t!=null&&t.recursive)){const n=J(e),s=n.slice(0,n.lastIndexOf("/"))||"/";if(!(yield this.exists(s)))throw R("ENOENT","mkdir",this.shown(e))}try{yield this.adapter.createDirectory(this.relative(e))}catch(n){throw this.mapError(n,"mkdir",e)}})}readdirWithFileTypes(e){return l(this,null,function*(){if((yield this.entry(e,"scandir")).kind!=="directory")throw R("ENOTDIR","scandir",this.shown(e));let n;try{n=yield this.adapter.listEntries(this.relative(e))}catch(s){if(this.isRoot(e)&&Fe(s)==="NotFoundError")return[];throw this.mapError(s,"scandir",e)}return n.map(s=>({name:s.name,isFile:s.kind==="file",isDirectory:s.kind==="directory",isSymbolicLink:!1})).sort((s,r)=>s.name<r.name?-1:s.name>r.name?1:0)})}readdir(e){return l(this,null,function*(){return(yield this.readdirWithFileTypes(e)).map(t=>t.name)})}rm(e,t){return l(this,null,function*(){if(this.isRoot(e))throw R("EPERM","rm",this.shown(e));const n=this.guard(e,"write","rm");if(!(yield this.exists(e))){if(t!=null&&t.force)return;throw R("ENOENT","rm",this.shown(e))}if(!this.adapter.remove)throw R("EPERM","rm",this.shown(e));try{yield this.adapter.remove(n,{recursive:(t==null?void 0:t.recursive)===!0})}catch(s){throw this.mapError(s,"rm",e)}})}cp(e,t,n){return l(this,null,function*(){if((yield this.entry(e,"cp")).kind==="file"){yield this.writeFile(t,yield this.readFileBuffer(e));return}if(!(n!=null&&n.recursive))throw R("EISDIR","cp",this.shown(e));yield this.mkdir(t,{recursive:!0});for(const r of yield this.readdir(e))yield this.cp(`${J(e)}/${r}`,`${J(t)}/${r}`,n)})}mv(e,t){return l(this,null,function*(){if(this.isRoot(e)||this.isRoot(t))throw R("EPERM","rename",this.shown(e));const n=this.guard(e,"write","rename"),s=this.guard(t,"write","rename");if(!this.adapter.move)throw R("EPERM","rename",this.shown(e));try{yield this.adapter.move(n,s)}catch(r){throw this.mapError(r,"rename",e)}})}resolvePath(e,t){return J(t.startsWith("/")?t:`${e}/${t}`)}getAllPaths(){return[]}chmod(e){return l(this,null,function*(){yield this.entry(e,"chmod")})}symlink(e,t){return l(this,null,function*(){throw R("EPERM","symlink",this.shown(t))})}link(e,t){return l(this,null,function*(){throw R("EPERM","link",this.shown(t))})}readlink(e){return l(this,null,function*(){throw yield this.entry(e,"readlink"),R("EINVAL","readlink",this.shown(e))})}realpath(e){return l(this,null,function*(){return yield this.entry(e,"realpath"),J(e)})}utimes(e){return l(this,null,function*(){yield this.entry(e,"utime")})}}const ms=`当前环境没有 Node,请改用 python3 或 shell 命令。
|
|
339
|
+
`,gs=new Set(["writeFile","appendFile","mkdir","rm","cp","mv","chmod","symlink","link","utimes","createExclusive"]),ys="dev|bin|usr|proc|etc|System|Library|private|var|opt|sbin|tmp|Applications|Volumes|cores|net|home",ws=new RegExp(`(^|[\\s'"=(;|&<>\`:])/(?!${ys}(?=$|[/\\s'"\`;|&)<>:]))(?!/)`,"g");function vs(i){let e=!1;return{fs:new Proxy(i,{get(n,s,r){const o=Reflect.get(n,s,r);return typeof o!="function"?o:(...c)=>{var d;const a=String((d=c[0])!=null?d:"");if(e&&gs.has(String(s))&&!a.startsWith("/dev/"))throw Object.assign(new Error(`EROFS: 只能写入工作区下的路径, open '${a}'`),{code:"EROFS"});return o.apply(n,c)}}}),lock:()=>e=!0}}function _s(i){return i instanceof Uint8Array?i:Uint8Array.from(String(i!=null?i:""),e=>e.charCodeAt(0)&255)}function bs(i){return i instanceof DOMException&&i.name==="AbortError"}function Es(i){if(!i)return;if(i===F)return".";if(!i.startsWith(`${F}/`))return;const e=i.slice(F.length+1).replace(/\/+$/,"");if(!e)return".";const t=e.split("/");if(!t.some(n=>!n||n==="."||n===".."))return t.join("/")}function Zt(i){return!i||i==="."?F:i===F||i.startsWith(`${F}/`)?i:`${F}/${i.replace(/^\/+/,"")}`}function Is(i){return i.replace(ws,(e,t)=>`${t}${F}/`)}function Je(i){return i.replace(/\/workspace(?![\p{L}\p{N}_.\-])/gu,(e,t,n)=>n[t+e.length]==="/"?"":"/")}class Ss{constructor(e){v(this,"python");this.options=e,this.python=new hs({adapter:e.adapter,sensitive:e.sensitive,indexURL:e.pyodideIndexURL,createWorker:e.createWorker})}load(){return l(this,null,function*(){const e=this.options.moduleURL||zn;try{return yield Gn(e)}catch(t){throw new m(p.NotImplemented,`命令运行时加载失败,请确认页面能访问 ${e}(CSP 需在 script-src 放行该地址)。`)}})}create(e,t,n,s){const{adapter:r,sensitive:o}=this.options,c=vs(new e.InMemoryFs),a=new e.MountableFs({base:c.fs});a.mount(F,new ps(r,"",o));const d=(f,y,_)=>e.defineCommand(f,()=>l(this,null,function*(){return{stdout:"",stderr:y,exitCode:_}})),h=f=>e.defineCommand(f,(y,_)=>l(this,null,function*(){var g;try{return yield this.python.run({args:y,cwd:_.cwd,stdin:_s(_.stdin),signal:n})}catch(b){return b instanceof m||bs(b)?((g=s.fatal)!=null||(s.fatal=b),{stdout:"",stderr:"",exitCode:1}):{stdout:"",stderr:`${f}: ${b instanceof Error?b.message:String(b)}
|
|
340
|
+
`,exitCode:1}}})),u=new e.Bash({fs:a,cwd:t,env:{HOME:"/tmp",LANG:"C.UTF-8"},customCommands:[d("node",ms,127),d("pip",dt,1),d("pip3",dt,1),h("python3"),h("python")],defenseInDepth:!1});return c.lock(),u}exec(e){return l(this,null,function*(){var h,u,f,y,_,g,b,A,I;if(St(e.cwd)||He((h=e.command)!=null?h:"")||He((f=(u=e.argv)==null?void 0:u[1])!=null?f:""))return{exitCode:1,stdout:"",stderr:`${It}
|
|
341
|
+
`};const t=yield this.load();if((y=e.signal)!=null&&y.aborted)throw x("AbortError");const n=Zt(e.cwd),s={},r=this.create(t,n,e.signal,s),[o,c,...a]=(_=e.argv)!=null?_:[];let d;try{d=e.argv?yield r.exec(o,{cwd:n,signal:e.signal,args:[Zt(c),...a]}):yield r.exec(Is((g=e.command)!=null?g:""),{cwd:n,signal:e.signal,rawScript:!0})}catch(L){if(s.fatal)throw s.fatal;if((b=e.signal)!=null&&b.aborted)throw x("AbortError");const k=L instanceof Error?L.message:String(L);return{exitCode:1,stdout:"",stderr:`bash: ${Je(k)}
|
|
342
|
+
`}}if(s.fatal)throw s.fatal;if((A=e.signal)!=null&&A.aborted)throw x("AbortError");return{exitCode:d.exitCode,stdout:Je(d.stdout),stderr:Je(d.stderr),cwd:Es((I=d.env)==null?void 0:I.PWD)}})}}const ei=16e3,Ts=`
|
|
343
|
+
…输出已截断`;function ti(i){if(i.length<=ei)return i;let e=ei;const t=i.charCodeAt(e-1);return t>=55296&&t<=56319&&(e-=1),i.slice(0,e)+Ts}function Ze(i){return{exec(t){return l(this,null,function*(){const n=yield i.exec(t);return E(w({},n),{stdout:ti(n.stdout),stderr:ti(n.stderr)})})}}}const te=i=>({type:"string",minLength:1,description:i}),he="必填。工作区内绝对路径,以 / 开头,例如 /说明.md。不要使用 /input、/output、/uploads、/tmp,也不要新建这些目录。",Rt={shell:{functionCode:"shell",name:"执行命令",description:"在当前会话工作区中执行一条 shell 命令并返回标准输出。每次调用都是新的 shell,只保留上次停留的目录;环境变量不会保留,需要时在同一条命令里设置。当前目录是工作区根目录。用相对路径,或以 / 开头表示工作区内已有的路径,例如 notes/a.md、/说明.md。不要使用或新建 input、output、uploads、tmp。/dev、/usr、/bin 仍是系统路径。写进脚本文件里的路径要用相对路径(见 run_file)。超过 20000 字的脚本请用 write_file 写到工作区文件后再调用 run_file;读取文件正文或结构摘要请用 read_file 的 start_line 和 end_line,不要用 cat、sed 或 head 把大文件正文打到标准输出。",parameters:{type:"object",required:["command"],properties:{command:{type:"string",minLength:1,maxLength:$n,description:"必填。一条不超过 20000 字的 shell 命令。当前目录已是工作区根目录。可以包含短的 python 或 heredoc。读取文件正文请改用 read_file。"}}}},read_file:{functionCode:"read_file",name:"读取文件",description:"按绝对路径读取工作区内的文本文件并返回内容;读不到时返回失败原因。未超过上限的文本按原文返回;超过单次读取上限的结构化文本(JSON/XML/SVG/CSV/TSV)会先附带通用结构概览和短预览,需要特定片段时再用 start_line 和 end_line。PDF 和图片只返回文件摘要,不返回正文。",parameters:{type:"object",required:["path"],properties:{path:te(he),start_line:{type:"integer",minimum:1,description:"可选。起始行号,从 1 开始,含本行。省略则从第 1 行读。"},end_line:{type:"integer",minimum:1,description:"可选。结束行号,从 1 开始,含本行。省略则读到文件末尾。"}}}},write_file:{functionCode:"write_file",name:"写入文件",description:`把文本写入工作区内文件,path 为工作区内绝对路径,文件已存在时覆盖。单次覆盖写入按 UTF-8 字节计,默认不超过 ${je} 字节。超限时先写一段,再用 edit_file 修改,或用 append_file 追加下一段。SVG 和整页 HTML 由工作区里的脚本生成,不要直接放进 content。`,parameters:{type:"object",required:["path","content"],properties:{path:te(he),content:{type:"string",description:`必填。覆盖写入的文本,UTF-8 不超过 ${je} 字节。不要放入 SVG 或整页 HTML。`}}}},append_file:{functionCode:"append_file",name:"追加文件",description:"把一段文本追加到工作区内文件末尾,path 为工作区内绝对路径,文件不存在时创建。覆盖写入超过字节上限时,用本工具把下一段接到同一文件。追加不设字节上限,但不要在一次调用里放入整份 HTML 或 SVG。",parameters:{type:"object",required:["path","content"],properties:{path:te(he),content:{type:"string",description:"必填。要追加到文件末尾的文本。不受覆盖写入的字节上限约束。"}}}},run_file:{functionCode:"run_file",name:"执行文件",description:"执行工作区里已经存在的 .py、.sh 或 .js 脚本文件。生成 SVG、HTML、JSON 等产物时优先使用:先用 write_file 写脚本,脚本自行读取工作区文件并写出产物,再调用本工具。脚本运行时当前目录是工作区根目录,脚本里访问工作区文件要写相对路径,例如 data.json、notes/a.py。不要使用或新建 input、output、uploads、tmp。需要查看文件正文时用 read_file,不要把整份文件打印到标准输出。",parameters:{type:"object",required:["path"],properties:{path:te("必填。要执行的 .py、.sh 或 .js 文件,工作区内绝对路径,例如 /scripts/gen.py。")}}},edit_file:{functionCode:"edit_file",name:"修改文件",description:"把工作区内文本文件中第一处与 old_text 完全相同的内容替换为 new_text。找不到 old_text 时返回最接近片段的行号,可直接复制原文重试,不必再读全文。old_text 与 new_text 不设长度上限。",parameters:{type:"object",required:["path","old_text","new_text"],properties:{path:te(he),old_text:{type:"string",minLength:1,description:"必填。文件中要被替换的原文,必须完全一致。"},new_text:{type:"string",description:"必填。替换后的文本。可以是一整段生成逻辑,不必拆成追加。"}}}},grep:{functionCode:"grep",name:"搜索文件",description:"在工作区目录中递归搜索文本,返回带行号的匹配行。path 为工作区内绝对路径,pattern 按 grep 基本正则匹配。用于定位内容,不要用来取回大文件全文。",parameters:{type:"object",required:["path","pattern"],properties:{path:te(he),pattern:{type:"string",minLength:1,description:"必填。grep 基本正则表达式。"}}}},find:{functionCode:"find",name:"查找文件",description:"按文件名通配在工作区目录中查找文件。path 为起始绝对路径,name 传给 find 的 -name,例如 *.html。",parameters:{type:"object",required:["path","name"],properties:{path:te(he),name:{type:"string",minLength:1,description:"必填。find -name 通配,例如 *.svg 或 *.html。"}}}},load_skill:{functionCode:"load_skill",name:"加载技能",description:"按技能名称加载指定技能的完整说明(SKILL.md)。",parameters:{type:"object",required:["skill_name"],properties:{skill_name:{type:"string",minLength:1,description:"必填。要加载的技能名称。"}}}},read_skill_resource:{functionCode:"read_skill_resource",name:"读取技能资源",description:"读取与指定技能关联的资源文件,例如参考资料、模板或附加说明。",parameters:{type:"object",required:["skill_name","resource_name"],properties:{skill_name:{type:"string",minLength:1,description:"必填。技能名称。"},resource_name:{type:"string",minLength:1,description:"必填。要读取的技能资源相对路径名称。"}}}},run_skill_script:{functionCode:"run_skill_script",name:"运行技能脚本",description:"在当前会话工作区中执行与指定技能关联的脚本并返回输出。脚本运行时当前目录是工作区根目录,参数里的文件路径按相对工作区根目录传,例如 docs/a.docx。",parameters:{type:"object",required:["skill_name","script_name"],properties:{skill_name:{type:"string",minLength:1,description:"必填。技能名称。"},script_name:{type:"string",minLength:1,description:"必填。要运行的技能脚本相对路径(保持技能说明中列出的目录前缀,如 scripts/run.py)。"},args:{type:"array",description:'传递给脚本的命令行位置参数数组,例如 ["input.docx", "--output", "result.idx"]。',items:{type:"string",description:"单个脚本参数。"}}}}}},ii=Object.keys(Rt);if(ii.length!==ot.length||ot.some(i=>!ii.includes(i)))throw new Error("BUILTIN_TOOL_SCHEMAS 与 BUILTIN_FUNCTION_CODES 不一致");const ni=500;function me(i){return`预览:
|
|
344
|
+
${i.length>ni?i.slice(0,ni):i}`}function xs(i){let e;try{e=JSON.parse(i)}catch(t){return`JSON 无法完整解析。
|
|
345
|
+
${me(i)}`}if(Array.isArray(e)){const t=e[0],n=t&&typeof t=="object"&&!Array.isArray(t)?`元素字段:${Object.keys(t).slice(0,20).join(", ")||"(无)"}。`:`元素类型:${t===null?"null":typeof t}。`;return`JSON 数组,长度 ${e.length}。${n}
|
|
346
|
+
${me(i)}`}if(e&&typeof e=="object"){const t=e,n=Object.keys(t),s=n.filter(o=>Array.isArray(t[o])).slice(0,10).map(o=>`${o} (${t[o].length})`),r=s.length?`数组字段:${s.join("、")}。`:"";return`JSON 对象。字段:${n.slice(0,40).join(", ")||"(无)"}。${r}
|
|
347
|
+
${me(i)}`}return`JSON ${e===null?"null":typeof e}。
|
|
348
|
+
${me(i)}`}function si(i,e){var d,h;const t=i.match(/<([A-Za-z_][\w:.-]*)\b/),n=(d=t==null?void 0:t[1])!=null?d:"未知",s=new Map,r=new RegExp("<([A-Za-z_][\\w:.-]*)\\b","g");let o,c=!1;for(;o=r.exec(i);){const u=o[1];if(!c&&u===n){c=!0;continue}if(s.set(u,((h=s.get(u))!=null?h:0)+1),s.size>30)break}const a=Array.from(s.entries()).slice(0,20).map(([u,f])=>`${u} (${f})`).join("、");return`${e} 根元素 ${n}。直接或嵌套子元素:${a||"(无)"}。
|
|
349
|
+
${me(i)}`}function ri(i,e,t){var a;const n=i.split(/\r?\n/).filter(d=>d.length>0),s=(a=n[0])!=null?a:"",r=s?s.split(e).length:0,o=Math.max(n.length-1,0),c=n.slice(0,4).join(`
|
|
350
|
+
`);return`${t},${r} 列,数据行 ${o}。表头:${s}
|
|
351
|
+
预览:
|
|
352
|
+
${c}`}function As(i){const e=ke(i);return e===".json"||e===".xml"||e===".svg"||e===".csv"||e===".tsv"}function Ls(i,e){const t=ke(i);return t===".json"?xs(e):t===".svg"?si(e,"SVG"):t===".xml"?si(e,"XML"):t===".tsv"?ri(e," ","TSV"):t===".csv"?ri(e,",","CSV"):me(e)}function ke(i){var n;const e=(n=i.split("/").pop())!=null?n:"",t=e.lastIndexOf(".");return t>=0?e.slice(t).toLowerCase():""}const ks=new Set([".png",".jpg",".jpeg",".gif",".webp",".bmp",".ico",".tif",".tiff"]);function Qi(i){return ks.has(ke(i))}function Ji(i,e){return ke(i)===".pdf"?!0:!e||e.byteLength<4?!1:e[0]===37&&e[1]===80&&e[2]===68&&e[3]===70}function Ct(i){return!!i&&typeof i=="object"&&i.name==="NotFoundError"}function Re(i){try{return new TextDecoder("utf-8",{fatal:!0}).decode(i)}catch(e){throw new m(p.BadRequest,"文件不是 UTF-8 文本。")}}function Mt(i){return i===""?[]:(i.endsWith(`
|
|
353
|
+
`)?i.slice(0,-1):i).split(`
|
|
354
|
+
`)}function Rs(i,e,t){if(e!==void 0&&t!==void 0&&t<e)throw new m(p.BadRequest,"end_line 不能小于 start_line。");const n=Mt(i),s=Math.max((e!=null?e:1)-1,0),r=t!=null?t:n.length;return n.slice(s,r).join(`
|
|
355
|
+
`)}function oi(i){if(kt(i)<=at)return{text:i,truncated:!1};const e=new TextEncoder().encode(i);let t=at;for(;t>0&&(e[t]&192)===128;)t-=1;const n=new TextDecoder().decode(e.slice(0,t)),s=n.lastIndexOf(`
|
|
356
|
+
`);return{text:s>0?n.slice(0,s):n,truncated:!0}}function Ee(i,e){return l(this,null,function*(){const t=yield i.stat(e);if(t.kind!=="file")throw new m(p.BadRequest,"目标是目录,不是文件。");const n=yield z(yield i.readFile(e));return{entry:t,bytes:n}})}function ai(i,e,t){const n=typeof t=="number"?`${t} 字节,`:"";return`${i},${n}路径 ${Tt(e)}。不返回正文。`}function Ot(i){const e=ke(i);if(!Bn.includes(e))throw new m(p.BadRequest,"只能执行 .py、.sh 或 .js 文件。");return e===".py"?"python3":e===".js"?"node":"sh"}function Zi(i){if(!i.runner)throw new m(p.NotImplemented,"当前环境不能执行命令或脚本,需要端侧宿主。");return i.runner}function Ft(i,e,t,n){return l(this,null,function*(){yield i.writeFile(e,t,{createDirectories:!0,signal:n})})}function Cs(i,e){return l(this,null,function*(){const t=_e(i.path);if(C(e.signal),Qi(t)){const a=yield e.adapter.stat(t);if(a.kind!=="file")throw new m(p.BadRequest,"目标是目录,不是文件。");return{data:{content:ai("图片",t,a.size),truncated:!1}}}const{entry:n,bytes:s}=yield Ee(e.adapter,t);if(Ji(t,s))return{data:{content:ai("PDF",t,n.size),truncated:!1}};if(oe(s))throw new m(p.BadRequest,"文件不是文本,无法读取正文。");const r=Re(s);if(i.start_line!==void 0||i.end_line!==void 0){const a=Rs(r,i.start_line,i.end_line),d=oi(a);return{data:{content:d.text,truncated:d.truncated}}}if(s.byteLength>at&&As(t))return{data:{content:Ls(t,r),truncated:!0}};const c=oi(r);return{data:{content:c.text,truncated:c.truncated}}})}function Ms(i,e){return l(this,null,function*(){const t=_e(i.path);if(kt(i.content)>je)throw new m(p.TooLarge,`content 按 UTF-8 计超过 ${je} 字节。请缩短后写入,或改用 append_file、edit_file。`);return C(e.signal),yield Ft(e.adapter,t,i.content,e.signal),{data:{}}})}function Os(i,e){return l(this,null,function*(){const t=_e(i.path);C(e.signal);let n="";try{const{bytes:s}=yield Ee(e.adapter,t);if(oe(s))throw new m(p.BadRequest,"文件不是文本,无法追加。");n=Re(s)}catch(s){if(!Ct(s))throw s}return yield Ft(e.adapter,t,n+i.content,e.signal),{data:{}}})}function Fs(i,e){return l(this,null,function*(){const t=_e(i.path);C(e.signal);const{bytes:n}=yield Ee(e.adapter,t);if(oe(n))throw new m(p.BadRequest,"文件不是文本,无法修改。");const s=Re(n),r=s.indexOf(i.old_text);if(r<0){const c=Ns(s,i.old_text);throw new m(p.BadRequest,`找不到与 old_text 完全相同的内容。最接近的原文从第 ${c.line} 行开始,可复制后重试:
|
|
357
|
+
${c.excerpt}`,{line:c.line,excerpt:c.excerpt})}const o=s.slice(0,r)+i.new_text+s.slice(r+i.old_text.length);return yield Ft(e.adapter,t,o,e.signal),{data:{}}})}function Ns(i,e){var a;const t=Mt(i);if(t.length===0)return{line:1,excerpt:""};const n=e.split(`
|
|
358
|
+
`),s=((a=n[0])!=null?a:"").slice(0,200);let r=0,o=-1;for(let d=0;d<t.length;d+=1){const h=Ps(t[d],s);h>o&&(o=h,r=d)}const c=Math.min(Math.max(n.length,1),8);return{line:r+1,excerpt:t.slice(r,r+c).join(`
|
|
359
|
+
`)}}function Ps(i,e){if(!e)return 0;const t=i.toLowerCase(),n=e.toLowerCase();let s=0,r=0;for(const o of t)r<n.length&&o===n[r]&&(s+=1,r+=1);return s}function Ds(i){let e="";for(let t=0;t<i.length;t+=1){const n=i[t];if(n==="\\"){const s=i[t+1];if(s===void 0){e+="\\\\";continue}t+=1,e+="+?|{}()".includes(s)?`\\${s}`:s==="n"?"\\n":s==="t"?"\\t":lt(s);continue}if("+?|{}()".includes(n)){e+=`\\${n}`;continue}if(n==="["){const s=i.indexOf("]",t+1);if(s<0){e+="\\[";continue}e+=i.slice(t,s+1),t=s;continue}e+=".^$*".includes(n)?n:lt(n)}return new RegExp(e)}function lt(i){return/[\\^$.*+?()[\]{}|]/.test(i)?`\\${i}`:i}function $s(i){try{return Ds(i)}catch(e){throw new m(p.BadRequest,"pattern 不是合法的 grep 基本正则。")}}function Nt(i,e,t,n,s){return l(this,null,function*(){if(n>16)return;C(t);const r=yield i.stat(e);if(yield s(e,r.kind),r.kind!=="directory")return;const o=yield i.listEntries(e,t);o.sort((c,a)=>c.name<a.name?-1:c.name>a.name?1:0);for(const c of o){const a=e?`${e}/${c.name}`:c.name;yield Nt(i,a,t,n+1,s)}})}function Bs(i,e){return l(this,null,function*(){const t=_e(i.path),n=$s(i.pattern),s=[];yield Nt(e.adapter,t,e.signal,0,(o,c)=>l(this,null,function*(){if(c!=="file"||s.length>=200)return;const{bytes:a}=yield Ee(e.adapter,o);if(oe(a)||Qi(o)||Ji(o,a))return;let d;try{d=Re(a)}catch(u){return}const h=Mt(d);for(let u=0;u<h.length&&s.length<200;u+=1){if(!n.test(h[u]))continue;const f=h[u].length>500?`${h[u].slice(0,500)}…`:h[u];s.push(`${Tt(o)}:${u+1}:${f}`)}}));const r=s.join(`
|
|
360
|
+
`);return{data:{matches:s.length>=200?`${r}
|
|
361
|
+
(匹配过多,已截断)`:r}}})}function Us(i,e){let t="^";for(let n=0;n<i.length;n+=1){const s=i[n];if(s==="*")t+=".*";else if(s==="?")t+=".";else if(s==="["){const r=i.indexOf("]",n+1);r<0?t+="\\[":(t+=i.slice(n,r+1),n=r)}else t+=lt(s)}return new RegExp(`${t}$`).test(e)}function js(i,e){return l(this,null,function*(){const t=_e(i.path),n=[];yield Nt(e.adapter,t,e.signal,0,r=>l(this,null,function*(){var c;if(n.length>=500)return;const o=(c=r.split("/").pop())!=null?c:r;Us(i.name,o)&&n.push(Tt(r))})),n.sort();const s=n.join(`
|
|
362
|
+
`);return{data:{files:n.length>=500?`${s}
|
|
363
|
+
(结果过多,已截断)`:s}}})}function en(i,e,t){return l(this,null,function*(){const n=Zi(t);yield Ee(t.adapter,i);const s=yield n.exec({argv:[Ot(i),i,...e],cwd:qi,timeoutMs:t.timeoutMs,signal:t.signal});return{data:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr}}})}function Hs(i,e){return l(this,null,function*(){const t=Hn(i.path);return Ot(t),en(t,[],e)})}function qs(i,e){return l(this,null,function*(){if(He(i.command)||He(e.shellCwd.cwd))return{data:{exitCode:1,stdout:"",stderr:`${It}
|
|
364
|
+
`}};const n=yield Zi(e).exec({command:i.command,cwd:e.shellCwd.cwd,timeoutMs:e.timeoutMs,signal:e.signal});return n.cwd&&qn(n.cwd)&&(e.shellCwd.cwd=n.cwd),{data:{exitCode:n.exitCode,stdout:n.stdout,stderr:n.stderr}}})}function tn(i,e){return l(this,null,function*(){try{const{bytes:t}=yield Ee(e.adapter,i);if(oe(t))throw new m(p.BadRequest,"技能资源不是文本。");return Re(t)}catch(t){throw Ct(t)?new m(p.NotFound,"技能或资源不存在。"):t}})}function Ws(i,e){return l(this,null,function*(){return{data:{content:yield tn(xt(i.skill_name,"SKILL.md"),e)}}})}function zs(i,e){return l(this,null,function*(){return{data:{content:yield tn(xt(i.skill_name,i.resource_name),e)}}})}function Vs(i,e){return l(this,null,function*(){var n;const t=xt(i.skill_name,i.script_name);Ot(t);try{return yield en(t,(n=i.args)!=null?n:[],e)}catch(s){throw Ct(s)?new m(p.NotFound,"技能脚本不存在。"):s}})}const Ys={shell:qs,read_file:Cs,write_file:Ms,append_file:Os,run_file:Hs,edit_file:Fs,grep:Bs,find:js,load_skill:Ws,read_skill_resource:zs,run_skill_script:Vs},xe=new H("[BuiltinTools] "),ci=new Set(["shell","run_file","run_skill_script"]);function Xs(i,e,t){var n,s;if(i.commandRunner)return Ze(i.commandRunner);if(e instanceof Ui&&e.capabilities.has("sandbox-exec")){if(e.canExec)return Ze({exec:o=>e.exec(o)});const r=`${(n=e.sandboxVersion)!=null?n:""}@${(s=e.sandboxProtocol)!=null?s:""}`;t.rejectedSandbox!==r&&(t.rejectedSandbox=r,xe.error("sandbox-protocol",{sandboxVersion:e.sandboxVersion,sandboxProtocol:e.sandboxProtocol,supported:st}))}if(i.browserRuntime.enabled)return(t.adapter!==e||!t.runner)&&(t.adapter=e,t.runner=Ze(new Ss({adapter:e,sensitive:i.sensitive,moduleURL:i.browserRuntime.bashModuleURL,pyodideIndexURL:i.browserRuntime.pyodideIndexURL}))),t.runner}function Gs(i){if(typeof i!="string")return i;try{return JSON.parse(i)}catch(e){throw new m(p.BadRequest,"参数不是合法的 JSON 对象。")}}function Ks(i){const e=i instanceof DOMException?i.name:"",t=i instanceof Error?i.message:"";if(e==="NotFoundError")return new m(p.NotFound,"脚本或目录不存在。");if(e==="SecurityError")return new m(p.Forbidden,"命令路径不在工作区内。");if(e==="AbortError")return t.includes("超时")?new m(p.Timeout,"命令运行超时,已中止。"):t.includes("已有")?new m(p.TooManyRequests,"已有一个命令在运行。"):U();if(e==="NotAllowedError")return new m(p.NotImplemented,"当前环境不能执行命令或脚本,需要端侧宿主。")}function Qs(i){return new Promise((e,t)=>{i.aborted&&t(U()),i.addEventListener("abort",()=>t(U()),{once:!0})})}function nn(i,e=160){return i.length>e?`${i.slice(0,e)}…`:i}function Js(i){const e={};for(const t of["path","skill_name","resource_name","script_name","pattern","name"])typeof i[t]=="string"&&(e[t]=i[t]);return typeof i.command=="string"&&(e.command=nn(i.command)),typeof i.start_line=="number"&&(e.start_line=i.start_line),typeof i.end_line=="number"&&(e.end_line=i.end_line),typeof i.content=="string"&&(e.contentLength=i.content.length),typeof i.old_text=="string"&&(e.oldTextLength=i.old_text.length),typeof i.new_text=="string"&&(e.newTextLength=i.new_text.length),Array.isArray(i.args)&&(e.argCount=i.args.length),e}function Zs(i){return w({code:i.code,message:i.message},i.data?{data:i.data}:{})}function er({pluginCode:i,workspace:e}){const t=new Map,n={},s={};return ot.forEach(r=>{s[r]=(o,c,a)=>{let d=!1;tr(e,t,n,r,o,u=>{if(!d){d=!0;try{c(u)}catch(f){console.error("[BuiltinTools] callback failed",f)}}},E(w({},a),{pluginCode:i}))}}),{[i]:s}}function tr(i,e,t,n,s,r,o){return l(this,null,function*(){var A,I,L,k,K;const c={requestId:o.requestId||ye.v4(),applicationId:o.applicationId||i.applicationId,sessionId:o.sessionId||"",pluginCode:o.pluginCode,functionCode:n,signal:o.signal},a={requestId:c.requestId,sessionId:c.sessionId,functionCode:n},d=new AbortController;let h=!1;const u=setTimeout(()=>{h=!0,d.abort()},i.limits.toolTimeoutMs),f=()=>d.abort();(A=c.signal)==null||A.addEventListener("abort",f,{once:!0}),(I=c.signal)!=null&&I.aborted&&d.abort();let y=null,_=null,g;const b=Date.now();try{const N=Gs(s),S=Hi(N,Rt[n].parameters);if(typeof S.path=="string"&&(a.path=S.path),xe.log("start",w(w({},a),Js(S))),yield i.ready,d.signal.aborted)throw U();const M=i.adapter;if(!M)throw Et();if(y=i.acquireSlot(),!y)throw new m(p.TooManyRequests,"同时进行的文件操作过多,请稍后重试。");if(ci.has(n)&&(_=i.acquireCommand(),!_))throw new m(p.TooManyRequests,"已有一个命令在运行,请等它结束后再试。");g=i.track(d),i.emit("tool:start",w({},a));const O=c.sessionId||"default";let P=e.get(O);P||(P={cwd:qi},e.set(O,P));const ae=Xs(i,M,t),ce=P.cwd,Ie={adapter:M,runner:ae,signal:d.signal,timeoutMs:i.limits.toolTimeoutMs,shellCwd:P},Q=yield Promise.race([Ys[n](S,Ie),Qs(d.signal)]),Ce={code:p.Ok,message:"ok",data:Q.data};Q.truncated&&(Ce.truncated=!0);const bn=Date.now()-b,Ht=Q.data.exitCode;xe.log("finish",w(w(w(E(w({},a),{elapsedMs:bn,code:p.Ok}),Q.truncated?{truncated:!0}:{}),typeof Ht=="number"?{exitCode:Ht}:{}),n==="shell"?{cwd:P.cwd,cwdChanged:P.cwd!==ce}:{})),i.emit("tool:finish",E(w({},a),{code:p.Ok})),ci.has(n)&&i.notifyFilesChanged(),r(Ce)}catch(N){let S=(L=Ks(N))!=null?L:Ve(N);h?S=new m(p.Timeout,"操作超时,已中止。"):d.signal.aborted&&S.code!==p.Cancelled&&(S=U());const M=Date.now()-b;S.code===p.Cancelled?(xe.log("cancelled",E(w({},a),{elapsedMs:M,timedOut:h})),i.emit("tool:cancelled",w({},a))):(xe.error("error",E(w({},a),{elapsedMs:M,code:S.code,message:nn(S.message,300)})),i.emit("tool:error",E(w({},a),{code:S.code,message:S.message,reason:(k=S.data)==null?void 0:k.reason}))),r(Zs(S))}finally{clearTimeout(u),(K=c.signal)==null||K.removeEventListener("abort",f),y==null||y(),_==null||_(),g==null||g()}})}const ir=new H("[Config] ");var sn=(i=>(i.dev="https://aiot-dev.glodon.com/api/cvforcepd",i.test="https://aiot-dev.glodon.com/api/cvforce",i.prod="https://copilot.glodon.com/api/cvforce",i.local="http://localhost:3000/api/cvforcepd",i))(sn||{});exports.configuration={debug:!1,env:"prod",apiRoot:"https://copilot.glodon.com/api/cvforce",applicationId:"",plugins:{},businessPlugins:{},builtinPlugins:void 0,mcp:void 0,loadRelatedQuesions:!0,stream:!1};let ge,j;const ht=new Set;function di(i){ge!==i&&(ge=i,j=void 0,ht.clear())}function nr(){if(!j)return;const{pluginCode:i,table:e}=j,t=exports.configuration.plugins[i],n=e[i];if(!(!t||t.shell!==n.shell))return i}function sr(){if(!j)return;const{pluginCode:i,table:e}=j,t=exports.configuration.plugins[i],n=e[i];if(!(!t||t.run_file!==n.run_file))return i}function rn(i,e){return(i==null?void 0:i.pluginCode)||Ii[e]}function rr(i,e,t){return(i==null?void 0:i.pluginCode)||t||Ti[e]}function or(){var a,d,h;const i=(a=exports.configuration.businessPlugins)!=null?a:{},e=(d=exports.configuration.builtinPlugins)==null?void 0:d.localFiles,t=(h=exports.configuration.builtinPlugins)==null?void 0:h.localPython,n=[],s=w({},i);if(!!!(e!=null&&e.enabled||t!=null&&t.enabled))return exports.configuration.plugins=s,n;if(!ge)return n.push("[BuiltinTools] 内置工具依赖已启用的本地工作区。工具未注册。"),exports.configuration.plugins=s,n;const o=e!=null&&e.enabled?rn(e,exports.configuration.env):void 0,c=o||(t!=null&&t.enabled?rr(t,exports.configuration.env,o):void 0);return c?i[c]?n.push(`[BuiltinTools] 业务插件中已存在 pluginCode「${c}」,已保留业务插件,内置工具未注册。`):(((j==null?void 0:j.workspace)!==ge||j.pluginCode!==c)&&(j={workspace:ge,pluginCode:c,table:er({pluginCode:c,workspace:ge})}),s[c]=j.table[c]):n.push(`[BuiltinTools] 当前环境(env: ${exports.configuration.env})没有默认的内置工具插件编码,请配置 builtinPlugins.localFiles.pluginCode。内置工具未注册。`),exports.configuration.plugins=s,n}function ut(){return or().filter(i=>!ht.has(i)).map(i=>(ht.add(i),console.error(i),new Error(i)))}function ft(i){var e,t,n;H.debug=(i==null?void 0:i.debug)||!1,exports.configuration=E(w(w({},exports.configuration),i),{apiRoot:(i==null?void 0:i.apiRoot)||exports.configuration.apiRoot||(i!=null&&i.env?sn[i.env||"prod"]:exports.configuration.apiRoot),businessPlugins:(t=(e=i==null?void 0:i.plugins)!=null?e:exports.configuration.businessPlugins)!=null?t:{},builtinPlugins:(n=i==null?void 0:i.builtinPlugins)!=null?n:exports.configuration.builtinPlugins}),ut(),H.debug&&ir.log("updated",exports.configuration)}const We=i=>JSON.parse(Tn.decode(i.split(".")[1])),ar=i=>{const e=We(i).exp;return new Date().valueOf()/1e3>=e},cr=i=>i==null?void 0:i.replace(/[\r\n]+/gm,""),dr=i=>i.replace(/\\|\\/g,""),lr=(i,e,t,n)=>{if(i!==!0)return null;const s=(e==null?void 0:e.includeUserQuestion)===!0,o=(e==null?void 0:e.includeAiAnswer)===!0||!s,c=[];return s&&c.push(`问题:${n}`),o&&c.push(`回答:${t}`),c.join(`
|
|
365
|
+
`)};function on(i,e,t){return new T.CVForceApi(an(i,"/data/v1",e,t),cn(t))}function hr(i,e,t){return new T.AIShopApi(an(i,"/aishop",e,t),cn(t))}function an(i,e,t,n){const s=o=>{var c;return t&&(ar(t)&&n(403,"aiotToken is timeout"),o.headers=(c=o.headers)!=null?c:{},o.headers=E(w({},o.headers),{Authorization:t?`Bearer ${t}`:""})),o};function r(o,c=!0){const a=`${i}${o}`,d=xn.create({baseURL:a});return c&&d.interceptors.request.use(s),d}return r(e)}function cn(i){return{onHttpStatusError:(n,s)=>{n===401&&i(n,"aiotToken is invalid")},onAppStatusError:(n,s)=>{n!==10001&&n!==10215&&i(n,s)}}}let ie;function ur(i){ie==null||ie(),ie=void 0;const e=Fn();if(!e)return()=>{};const t=new Ui(e),n=r=>{const o=On(r.data);if(o){if(o.type==="workspace"){const c=o.granted===!0,a=typeof o.displayName=="string"?o.displayName:"";t.setCapabilities(o.capabilities,{version:o.sandboxVersion,protocol:o.sandboxProtocol}),c?(t.displayName=a||"工程目录",(i.status!=="granted"||i.displayName!==t.displayName)&&i.attachAdapter(t,t.displayName)):i.status==="granted"&&i.clear();return}if(o.type==="fs-changed"){const c=Array.isArray(o.paths)?o.paths.filter(a=>typeof a=="string"):[];i.notifyFilesChanged(c);return}typeof o.id=="string"&&t.settle({channel:Ue,id:o.id,ok:o.ok!==!1,name:typeof o.name=="string"?o.name:void 0,entries:o.entries,entry:o.entry,contentBase64:typeof o.contentBase64=="string"?o.contentBase64:void 0,exitCode:typeof o.exitCode=="number"?o.exitCode:void 0,timedOut:o.timedOut===!0,stdout:typeof o.stdout=="string"?o.stdout:void 0,stderr:typeof o.stderr=="string"?o.stderr:void 0,cwd:typeof o.cwd=="string"?o.cwd:void 0,message:typeof o.message=="string"?o.message:void 0})}};e.addEventListener("message",n),e.postMessage({channel:Ue,type:"hello"});const s=()=>{e.removeEventListener("message",n),ie===s&&(ie=void 0)};return ie=s,s}const ne=new H("[EventBus] ");class Pt{constructor(e=!1){v(this,"eventListenerMap",{});e&&ne.disable()}getEventListenerMap(){return w({},this.eventListenerMap)}on(e,t,n=!1){this.eventListenerMap[e]||(this.eventListenerMap[e]=[]),n?this.eventListenerMap[e].push({fn:t,once:!0}):this.eventListenerMap[e].push(t),ne.log(`add event ${e} listener ${n?", call once":""}`)}once(e,t){this.on(e,t,!0)}off(e,t){if(this.eventListenerMap[e]){const n=this.eventListenerMap[e].findIndex(s=>{if(typeof s=="function"&&t===s)return!0;if(s=s,s.fn===t)return!0});n<0?ne.log(`event ${e} listener ${t.name} is not found`):(this.eventListenerMap[e].splice(n,1),ne.log(`remove event ${e} listener`))}else ne.log(`event ${e} listeners is empty`)}emit(e,t){if(!this.eventListenerMap[e]){ne.log(`event ${e} listeners is empty`);return}const n=[];for(let s=0;s<this.eventListenerMap[e].length;s++){const r=this.eventListenerMap[e][s];typeof r=="function"?r(t):n.push(r)}n.forEach(s=>{s&&(s.fn(t),this.off(e,s.fn))}),ne.log(`event ${e} is fired, has ${this.eventListenerMap[e].length} listeners`)}removeAllListeners(){this.eventListenerMap={}}}const fr="路径必须是工作区内的相对路径,不能包含 ..、绝对路径或盘符。";function Ne(){return new m(p.Forbidden,fr,{reason:"path_outside_workspace"})}function pr(i){if(i!==we)throw new m(p.Forbidden,`未知的工作区 grantId,当前仅支持 ${we}。`,{reason:"path_outside_workspace"})}function G(i,{allowRoot:e=!1,field:t="path"}={}){if(i==null){if(e)return"";throw new m(p.BadRequest,`缺少参数 ${t}。`)}if(typeof i!="string")throw new m(p.BadRequest,`参数 ${t} 必须是字符串。`);if(i.includes("\0")||/%(2e|2f|5c|00)/i.test(i))throw Ne();const n=i.normalize("NFC").replace(/\\/g,"/").trim();if(n.startsWith("/")||/^[a-zA-Z]:/.test(n))throw Ne();const s=[];for(const o of n.split("/"))if(!(o===""||o===".")){if(o==="..")throw Ne();s.push(o)}const r=s.join("/");if(!r&&!e)throw new m(p.BadRequest,`参数 ${t} 不能指向工作区根目录。`);return r}function $(i){return i?i.split("/"):[]}function mr(i){const e=i.lastIndexOf("/");return e<0?"":i.slice(0,e)}function dn(i,e){return i?`${i}/${e}`:e}function ue(i,e){return!!i&&typeof i=="object"&&i.name===e}class ln{constructor(e){this.root=e}get displayName(){return this.root.name}resolveDirectory(e,t=!1){return l(this,null,function*(){let n=this.root;for(const s of e)n=yield n.getDirectoryHandle(s,{create:t});return n})}resolveFile(e){return l(this,null,function*(){const t=$(e),n=t.pop();if(!n)throw x("TypeMismatchError");return(yield this.resolveDirectory(t)).getFileHandle(n)})}stat(e){return l(this,null,function*(){const t=$(e),n=t.pop();if(!n)return{name:this.root.name,kind:"directory"};const s=yield this.resolveDirectory(t);try{const r=yield(yield s.getFileHandle(n)).getFile();return{name:n,kind:"file",size:r.size,lastModified:r.lastModified}}catch(r){if(!ue(r,"TypeMismatchError"))throw r;return yield s.getDirectoryHandle(n),{name:n,kind:"directory"}}})}listEntries(e,t){return l(this,null,function*(){const n=yield this.resolveDirectory($(e)),s=[];try{for(var r=V(n.values()),o,c,a;o=!(c=yield r.next()).done;o=!1){const d=c.value;if(C(t),d.kind==="directory")s.push({name:d.name,kind:"directory"});else try{const h=yield d.getFile();s.push({name:d.name,kind:"file",size:h.size,lastModified:h.lastModified})}catch(h){if(ue(h,"NotAllowedError"))throw h;s.push({name:d.name,kind:"file"})}}}catch(c){a=[c]}finally{try{o&&(c=r.return)&&(yield c.call(r))}finally{if(a)throw a[0]}}return s})}readFile(e){return l(this,null,function*(){return(yield this.resolveFile(e)).getFile()})}writeFile(s,r){return l(this,arguments,function*(e,t,n={}){const o=$(e),c=o.pop();if(!c)throw x("TypeMismatchError");const a=yield this.resolveDirectory(o,n.createDirectories);let d=!0;try{yield a.getFileHandle(c)}catch(b){if(!ue(b,"NotFoundError"))throw b;d=!1}const h=yield a.getFileHandle(c,{create:!0});let u;try{u=yield h.createWritable();try{for(var f=V(bt(t)),y,_,g;y=!(_=yield f.next()).done;y=!1){const b=_.value;C(n.signal),yield u.write(b)}}catch(_){g=[_]}finally{try{y&&(_=f.return)&&(yield _.call(f))}finally{if(g)throw g[0]}}C(n.signal),yield u.close()}catch(b){throw yield u==null?void 0:u.abort().catch(()=>{}),d||(yield a.removeEntry(c).catch(()=>{})),b}})}createDirectory(e){return l(this,null,function*(){yield this.resolveDirectory($(e),!0)})}remove(n){return l(this,arguments,function*(e,t={}){const s=$(e),r=s.pop();if(!r)throw x("InvalidModificationError");yield(yield this.resolveDirectory(s)).removeEntry(r,{recursive:t.recursive===!0})})}move(e,t){return l(this,null,function*(){const n=$(e),s=$(t),r=n.pop(),o=s.pop();if(!r||!o)throw x("InvalidModificationError");const c=yield this.resolveDirectory(n),a=yield li(c,r),d=yield this.resolveDirectory(s);if(Bi(e,t))throw x("InvalidModificationError");let h;try{h=yield li(d,o)}catch(u){if(!ue(u,"NotFoundError"))throw u}if(h&&(h.kind==="directory"||a.kind==="directory"))throw x("InvalidModificationError");if(!h&&typeof a.move=="function")try{yield a.move(d,o);return}catch(u){if(!ue(u,"NotSupportedError")&&!(u instanceof TypeError))throw u}yield hn(a,d,o),yield c.removeEntry(r,{recursive:!0})})}}function li(i,e){return l(this,null,function*(){try{return yield i.getFileHandle(e)}catch(t){if(!ue(t,"TypeMismatchError"))throw t;return i.getDirectoryHandle(e)}})}function hn(i,e,t){return l(this,null,function*(){if(i.kind==="file"){const a=yield i.getFile(),d=yield(yield e.getFileHandle(t,{create:!0})).createWritable();try{yield d.write(a),yield d.close()}catch(h){throw yield d.abort().catch(()=>{}),h}return}const n=yield e.getDirectoryHandle(t,{create:!0});try{for(var s=V(i.values()),r,o,c;r=!(o=yield s.next()).done;r=!1){const a=o.value;yield hn(a,n,a.name)}}catch(o){c=[o]}finally{try{r&&(o=s.return)&&(yield o.call(s))}finally{if(c)throw c[0]}}})}function gr(){if(typeof window=="undefined")return;const i=window.showDirectoryPicker;return typeof i=="function"?i.bind(window):void 0}const yr=/^[a-z0-9-]+(\.[a-z0-9-]+)+$/;function wr(i){if(typeof i!="string")return null;const e=i.trim().toLowerCase().replace(/^\*?\./,"").replace(/\.$/,"");return!yr.test(e)||un(e)?null:e}function un(i){return i.startsWith("[")||i.includes(":")?!0:/^[0-9.]+$/.test(i)||/^0x[0-9a-f.]+$/i.test(i)}function Dt(i=[]){const e=new Set(Fi);for(const t of i){const n=wr(t);n&&e.add(n)}return Array.from(e)}function vr(i,e){return pt(i,Dt(e))}function pt(i,e){let t;try{t=new URL(i)}catch(s){return!1}if(t.protocol!=="https:"||t.username||t.password)return!1;const n=t.hostname.toLowerCase().replace(/\.$/,"");return!n||un(n)||n==="localhost"||n.endsWith(".localhost")?!1:e.some(s=>n===s||n.endsWith(`.${s}`))}function _r(i={}){const e=w({},De);return Object.keys(De).forEach(t=>{const n=i[t];typeof n=="number"&&Number.isFinite(n)&&n>0&&(e[t]=Math.min(n,De[t]))}),e}function fe(){return new m(p.Internal,"平台文件服务请求失败,请稍后重试。")}function $t(i,e=()=>{}){const t=()=>{const r=i();if(!r)throw fe();return r},n=()=>{const r=e();if(!r)throw fe();return r};return{upload(r,o,c){return l(this,null,function*(){if(!o.sessionId)throw new m(p.BadRequest,"当前没有可用的会话,无法上传文件。");try{c==null||c({loaded:0,total:r.size});const a=yield n().postFile(r,(d,h)=>c==null?void 0:c({loaded:d,total:h}));if(!(a!=null&&a.id)||!a.url)throw fe();return c==null||c({loaded:r.size,total:r.size}),{fileId:a.id,url:a.url}}catch(a){throw a instanceof m?a:fe()}})},resolveDownload(r,o){return l(this,null,function*(){if(r.type==="platformFile")return br(n(),r.fileId);if(!o.sessionId)throw new m(p.BadRequest,"当前没有可用的会话,无法下载会话文件。");let c;try{c=yield t().getApplicationIdSessionFile(o.applicationId,o.sessionId,r.fileId)}catch(a){throw fe()}if(!(c!=null&&c.url))throw new m(p.NotFound,"会话文件不存在或暂不可下载。");return{url:c.url,name:c.name,size:c.size}})}}}function br(i,e){return l(this,null,function*(){let t;try{t=yield i.getFile(e)}catch(s){throw fe()}if(!(t!=null&&t.url))throw new m(p.NotFound,"平台文件不存在或暂不可下载。");let n;try{n=new URL(t.url)}catch(s){throw new m(p.Internal,"平台返回的下载地址无效。")}if(n.protocol!=="https:")throw new m(p.Internal,"平台返回的下载地址无效。");return{url:t.url,size:t.bytes}})}const Er="glodon-aiot-local-workspace",et="kv";function Bt(){const i=new Map;return{get(t){return l(this,null,function*(){return i.get(t)})},set(t,n){return l(this,null,function*(){i.set(t,n)})},delete(t){return l(this,null,function*(){i.delete(t)})}}}function Ir(i){return new Promise((e,t)=>{i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)})}function fn(i=Er){if(typeof indexedDB=="undefined")return Bt();let e;const t=()=>(e||(e=new Promise((r,o)=>{const c=indexedDB.open(i,1);c.onupgradeneeded=()=>{c.result.createObjectStore(et)},c.onsuccess=()=>r(c.result),c.onerror=()=>{e=void 0,o(c.error)}})),e),n=(r,o)=>l(this,null,function*(){const c=yield t();return Ir(o(c.transaction(et,r).objectStore(et)))});return{get(r){return l(this,null,function*(){return yield n("readonly",o=>o.get(r))})},set(r,o){return l(this,null,function*(){yield n("readwrite",c=>c.put(o,r))})},delete(r){return l(this,null,function*(){yield n("readwrite",o=>o.delete(r))})}}}function hi(i){if(i!=null&&i.length&&!i.some(e=>!e||e==="."||e===".."||e.includes("/")||e.includes("\\")))return i.length===1?"":i.slice(0,-1).join("/")}function Sr(i,e){const t=globalThis.FileSystemObserver;if(typeof t!="function")return()=>{};let n;try{n=new t(s=>{const r=new Set;for(const o of s){if(o.type==="errored"){e();return}const c=hi(o.relativePathComponents),a=hi(o.relativePathMovedFrom);if(c===void 0&&a===void 0){e();return}c!==void 0&&r.add(c),a!==void 0&&r.add(a)}r.size&&e([...r])})}catch(s){return()=>{}}return n.observe(i,{recursive:!0}).catch(()=>n.disconnect()),()=>n.disconnect()}const Pe={mode:"readwrite"};function Tr(i){const e=i.replace(/\\/g,"/").trim().replace(/^\.\/+/,"").replace(/\/+$/,"");if(!e||e===".")return"";if(e.startsWith("/")||e.includes(":")||e.includes("\0"))return;const t=e.split("/");if(!t.some(n=>!n||n==="."||n===".."))return t.join("/")}function xr(i){return!!i&&typeof i=="object"&&i.name==="AbortError"}class pn{constructor(e){v(this,"applicationId");v(this,"limits");v(this,"sensitive");v(this,"downloadUrlAllowlist");v(this,"allowWorkspaceWideTextSearch");v(this,"transfer");v(this,"fetch");v(this,"commandRunner");v(this,"browserRuntime");v(this,"store");v(this,"picker");v(this,"event",new Pt(!0));v(this,"_status");v(this,"_displayName");v(this,"_adapter",null);v(this,"pendingHandle",null);v(this,"approvalHandler");v(this,"activeCalls",0);v(this,"commandRunning",!1);v(this,"inflight",new Set);v(this,"_ready",Promise.resolve());v(this,"stopWatching",()=>{});v(this,"pendingChangePaths",new Set);v(this,"changeTimer");v(this,"refreshAllVisible",!1);var o,c,a,d,h,u,f,y,_,g;const t=(o=e.config)!=null?o:{};this.applicationId=e.applicationId,this.store=(c=e.store)!=null?c:Bt(),this.picker=e.picker===null?void 0:(a=e.picker)!=null?a:gr(),this.limits=_r(t.limits),this.sensitive=new Xi(t.sensitiveRulesAppend),this.downloadUrlAllowlist=Dt(t.downloadUrlAllowlistAppend),this.allowWorkspaceWideTextSearch=!!t.allowWorkspaceWideTextSearch,this.approvalHandler=t.onApprovalRequired;const n=(d=e.transfer)!=null?d:$t(()=>{});this.transfer={upload:(u=(h=t.transfer)==null?void 0:h.upload)!=null?u:n.upload,resolveDownload:(y=(f=t.transfer)==null?void 0:f.resolveDownload)!=null?y:n.resolveDownload};const s=(_=e.fetch)!=null?_:typeof fetch=="function"?fetch:void 0;this.fetch=s?s.bind(globalThis):()=>Promise.reject(new Error("fetch is not available")),this.commandRunner=e.commandRunner;const r=(g=t.commandRuntime)==null?void 0:g.browser;this.browserRuntime={enabled:(r==null?void 0:r.enabled)!==!1,bashModuleURL:r==null?void 0:r.bashModuleURL,pyodideIndexURL:r==null?void 0:r.pyodideIndexURL},this._status=this.picker?"none":"unsupported"}get status(){return this._status}get displayName(){return this._displayName}get isSupported(){return!!this.picker}get ready(){return this._ready}get adapter(){return this._status==="granted"?this._adapter:null}get handleKey(){return`workspace:${this.applicationId}`}get disclosureKey(){return`disclosure:${this.applicationId}`}setStatus(e,t=this._displayName){e===this._status&&t===this._displayName||(this._status=e,this._displayName=t,this.emit("workspace:changed",{status:e,displayName:t}))}attachHandle(e){this.cancelFilesChanged(),this.pendingHandle=e,this._adapter=new ln(e),this.setStatus("granted",e.name),this.unwatchDirectory(),this.stopWatching=Sr(e,t=>this.notifyFilesChanged(t))}pick(){if(!this.picker)return Promise.resolve(!1);let e;try{e=this.picker({mode:"readwrite"})}catch(t){return Promise.reject(t)}return e.then(t=>l(this,null,function*(){var s,r;this.cancelAll();const n=(r=yield(s=t.queryPermission)==null?void 0:s.call(t,Pe))!=null?r:"granted";return yield this.store.set(this.handleKey,{handle:t,displayName:t.name,savedAt:Date.now()}).catch(()=>{}),n==="denied"?(this.pendingHandle=t,this._adapter=null,this.setStatus("denied",t.name),!1):(this.attachHandle(t),!0)}),t=>{if(xr(t))return!1;throw t})}restore(){return this._ready=this.doRestore(),this._ready}doRestore(){return l(this,null,function*(){var n,s,r;if(!this.picker){this._adapter||this.setStatus("unsupported");return}let e;try{e=yield this.store.get(this.handleKey)}catch(o){e=void 0}if(!(e!=null&&e.handle)){this.pendingHandle=null,this._adapter=null,this.setStatus("none",void 0);return}let t;try{t=(r=yield(s=(n=e.handle).queryPermission)==null?void 0:s.call(n,Pe))!=null?r:"prompt"}catch(o){t="prompt"}t==="granted"?this.attachHandle(e.handle):(this.pendingHandle=e.handle,this._adapter=null,this.setStatus(t==="denied"?"denied":"prompt",e.displayName))})}requestPermission(){const e=this.pendingHandle;if(!(e!=null&&e.requestPermission))return Promise.resolve(!1);let t;try{t=e.requestPermission(Pe)}catch(n){return Promise.reject(n)}return t.then(n=>n==="granted"?(this.attachHandle(e),!0):(this._adapter=null,this.setStatus(n==="denied"?"denied":"prompt",e.name),!1))}clear(){return l(this,null,function*(){this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this.pendingHandle=null,this._adapter=null,this.setStatus(this.picker?"none":"unsupported",void 0),yield this.store.delete(this.handleKey).catch(()=>{})})}attachAdapter(e,t=e.displayName){this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this.pendingHandle=null,this._adapter=e,this.setStatus("granted",t)}notifyFilesChanged(e){if(this._status==="granted"){if(!e||e.length===0)this.refreshAllVisible=!0;else for(const t of e){const n=Tr(t);n===void 0?this.refreshAllVisible=!0:this.pendingChangePaths.add(n)}clearTimeout(this.changeTimer),this.changeTimer=setTimeout(()=>this.flushFilesChanged(),150)}}handlePermissionLost(){return l(this,null,function*(){const e=this.pendingHandle;if(!(e!=null&&e.queryPermission))return;const t=yield e.queryPermission(Pe).catch(()=>"prompt");t!=="granted"&&(this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this._adapter=null,this.setStatus(t==="denied"?"denied":"prompt",e.name))})}isDisclosureAcknowledged(){return l(this,null,function*(){try{return!!(yield this.store.get(this.disclosureKey))}catch(e){return!1}})}acknowledgeDisclosure(){return l(this,null,function*(){yield this.store.set(this.disclosureKey,!0).catch(()=>{})})}setApprovalHandler(e){this.approvalHandler=e}get hasApprovalHandler(){return!!this.approvalHandler}getApprovalHandler(){return this.approvalHandler}acquireSlot(){if(this.activeCalls>=this.limits.maxConcurrentRequests)return null;this.activeCalls++;let e=!1;return()=>{e||(e=!0,this.activeCalls--)}}acquireCommand(){if(this.commandRunning)return null;this.commandRunning=!0;let e=!1;return()=>{e||(e=!0,this.commandRunning=!1)}}track(e){return this.inflight.add(e),()=>this.inflight.delete(e)}cancelAll(){const e=Array.from(this.inflight);this.inflight.clear(),e.forEach(t=>t.abort())}handshake(){const e=Object.fromEntries(yt.map(t=>[t,!0]));return{protocolVersion:"1.0",capabilities:E(w({},e),{cancellation:!0,atomicWrite:!0}),limits:w({},this.limits)}}on(e,t){return this.event.on(e,t),()=>this.off(e,t)}off(e,t){this.event.off(e,t)}unwatchDirectory(){const e=this.stopWatching;this.stopWatching=()=>{},e()}cancelFilesChanged(){clearTimeout(this.changeTimer),this.changeTimer=void 0,this.pendingChangePaths.clear(),this.refreshAllVisible=!1}flushFilesChanged(){this.changeTimer=void 0;const e=this.refreshAllVisible,t=[...this.pendingChangePaths].sort((n,s)=>n<s?-1:n>s?1:0);this.pendingChangePaths.clear(),this.refreshAllVisible=!1,this._status==="granted"&&this.emit("files:changed",{paths:e?[]:t})}emit(e,t){try{this.event.emit(e,t)}catch(n){console.error(`[LocalWorkspace] ${e} listener failed`,n)}}}var pe=(i=>(i[i.Normal=0]="Normal",i[i.Debug=1]="Debug",i))(pe||{});const ui=100,D=new H("[Session] ");var Ae=(i=>(i.DataRequestFailed="data request error",i.SocketConnectionFailed="socket error",i.IdUndefined="session id is not defined",i.SendingEmptyContent="failed at sending empty content",i.Frozen="session is frozen",i.UserModeError="failed at setting socket user mode",i.Inactive="session is inactive",i))(Ae||{});class Ut{constructor(e,t="",n,s,r,o){v(this,"_id");v(this,"_frozen",!1);v(this,"inactivating",!1);v(this,"_ready",!1);v(this,"event",new Pt);v(this,"_applicationId");v(this,"_application",null);v(this,"data",null);v(this,"client",null);v(this,"messages",[]);v(this,"_loadingMessages",!1);v(this,"_loadingMessagesSize",10);v(this,"cvforceApi");v(this,"socket",null);v(this,"_promptVariables",[]);v(this,"active",!1);v(this,"activing",!1);v(this,"_stopAnswer",!1);v(this,"_dataLoading",!1);v(this,"_dataLoaded",!1);v(this,"_mcpServers",null);this.token=e,this.lazyload=s,this.client=o||null,this._applicationId=We(e).rid||exports.configuration.applicationId,this.cvforceApi=this.getService(),r&&(this._application=r),this.event.emit("init",{applicationId:this._applicationId,sessionId:t}),this.loadApplicationInfo().then(()=>{var c;if(t)this._id=t,this.event.emit("data:loading"),n?(this.data=n,s||(this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,t).then(a=>l(this,null,function*(){this.data=a,this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,t)})).then(()=>l(this,null,function*(){this.messages=[],yield this.fetchMessages(),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data)})))):(this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,t).then(a=>l(this,null,function*(){this.data=a,this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,t)})).then(()=>l(this,null,function*(){this.messages=[],yield this.fetchMessages(),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),this._dataLoading=!1,this._dataLoaded=!0})));else{const a=(n==null?void 0:n.name)||"新建会话";this.event.emit("data:creating",{applicationId:this._applicationId,name:a}),this.event.emit("data:loading"),this.cvforceApi.postSession(this.applicationId,{name:a,netOpen:n==null?void 0:n.netOpen,knowledgeIdList:(c=n==null?void 0:n.knowledges)==null?void 0:c.map(d=>d.id),applicationId:this._applicationId}).then(d=>l(this,null,function*(){var h;this._id=d.id,this.data=E(w({},d),{knowledges:n==null?void 0:n.knowledges}),this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this._id);try{yield(()=>l(this,null,function*(){if(n!=null&&n.knowledges)return this.setKnowledges((n==null?void 0:n.knowledges)||void 0)}))()}catch(u){D.error(u)}yield(()=>{if(n!=null&&n.promptVariables){const u=this._promptVariables.map(f=>{var _,g;const y=((g=(_=n.promptVariables)==null?void 0:_.find(b=>b.key===f.key&&b.type===f.type))==null?void 0:g.value)||"";return E(w({},f),{value:y})}).sort((f,y)=>f.key.localeCompare(y.key));return this.setPromptVariables(u||[])}else return})(),this.event.emit("data:created",this.data),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),((h=this.application)==null?void 0:h.type)!==T.ApplicationTypes.Agent&&(this._ready=!0,this.event.emit("ready"))}))}})}fetchData(){return l(this,null,function*(){if(!this.data)throw Error("session data is not loaded");return yield this.cvforceApi.getSession(this.applicationId,this.data.id).then(e=>l(this,null,function*(){return this.data=e,this.event.emit("data:updated",this.data),e}))})}get id(){var e;return this._id||((e=this.data)==null?void 0:e.id)||""}get applicationId(){return this._applicationId}get application(){return this._application}set application(e){this._application=e}loadApplicationInfo(){if(this._application)return Promise.resolve(this._application);if(this._applicationId&&!this._application)return this.event.emit("application:data:loading"),this.cvforceApi.getApplicationId(this._applicationId).then(e=>(this._application=e,this.event.emit("application:data:loaded",e),e));throw Error("application id is not defined")}get ready(){return this._ready}get frozen(){return this._frozen}set frozen(e){e===!1&&this.inactivating&&this.socket&&(this.socket.disconnect(),this.socket=null,this.event.emit("inactivated")),this._frozen=e,this.event.emit("frozen",e)}get knowledges(){if(!this.data)throw Error("session data is not loaded");return this.data.knowledges||void 0}setKnowledges(e){return l(this,null,function*(){if(!this.data)throw Error("session data is not loaded");if((e||[]).some(s=>Array.isArray(s.fileIds)&&s.fileIds.length===0))throw Error("fileIds cannot be an empty array");if((e||[]).reduce((s,r)=>{var c,a;const o=(a=(c=r.fileIds)==null?void 0:c.length)!=null?a:0;return s+(o>0?o:1)},0)>ui)throw Error(`knowledges and fileIds total count cannot exceed ${ui}`);return yield this.cvforceApi.patchSessionsId(this._applicationId,this.data.id,{knowledges:e}),this.data.knowledges=e,this.event.emit("data:updated",this.data),this.event.emit("data:updated:knowledges",{knowledges:e}),e})}validateConfigs(){if(!this._id)throw Error("session id is not defined");if(!this.data)throw Error("session data is not loaded");const e=this.promptVariables.filter(t=>t.status===T.PromptStatus.Quoted).filter(t=>!t.value);if(e.length)throw Error(`在提示词中被引用的变量值不能为空, 请检查以下变量: ${e.map(t=>t.key).join(", ")}`)}get promptVariables(){return this._promptVariables.filter(e=>!(e.type===T.PromptVariableType.User&&e.key==="query")&&!(e.type===T.PromptVariableType.System&&e.key==="datetime"))}setPromptVariables(e){return l(this,null,function*(){const t=e==null?void 0:e.map(r=>r.type?r:E(w({},r),{type:"instruction"})),n=this._promptVariables.map(r=>{var c;const o=((c=t==null?void 0:t.find(a=>a.key===r.key&&a.type===r.type))==null?void 0:c.value)||r.value;return E(w({},r),{value:o})}).sort((r,o)=>r.key.localeCompare(o.key));if(!(yield Promise.all(n.filter(r=>!(r.type===T.PromptVariableType.User&&r.key==="query")&&!(r.type===T.PromptVariableType.System&&r.key==="datetime")).map(r=>{if(!this.data)throw Error("session data is not loaded");if(!(!r.id||!r.key))return this.cvforceApi.patchApplicationIdSessionpromptVariablesId(this._applicationId,this.data.id,r.id,{value:r.value})})).then(()=>!0).catch(r=>!1)))return!1;if(!this.data)throw Error("session data is not loaded");return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this.data.id),this.event.emit("data:updated",this.data),this.event.emit("data:updated:promptVariables",{promptVariables:this._promptVariables}),this._promptVariables})}get netOpen(){if(!this.data)throw Error("session data is not loaded");return this.data.netOpen||!1}setNetOpen(e){return l(this,null,function*(){var t,n,s;if(D.log("setNetOpen:",e),D.log("application arrange setting value: ",(t=this._application)==null?void 0:t.arrange[0].enableNetOpen),((n=this._application)==null?void 0:n.type)===T.ApplicationTypes.Agent){console.warn("Agent Application Sessions are disabled to setNetOpen.");return}if(((s=this._application)==null?void 0:s.arrange[0].enableNetOpen)===!1){console.warn("This Application is disabled to change netOpen.");return}if(!this.data)throw Error("session data is not loaded");return yield this.cvforceApi.patchSessionsId(this._applicationId,this.data.id,{netOpen:e?1:2}),this.data.netOpen=e,D.log("data:updated",this.data),this.event.emit("data:updated",this.data),this.event.emit("data:updated:netOpen",{netOpen:e}),e})}getService(){return on(exports.configuration.apiRoot,this.token,(e,t)=>{const n=new Error("data request error",{cause:{status:e,message:t}});D.error(n),this.event.emit("error",n)})}addEventListener(e,t,n=!1){if(typeof t!="function")throw Error("event listener is not a function");if(n){this.event.once(e,t);return}this.event.on(e,t)}removeEventListener(e,t){this.event.off(e,t)}fetchMessages(){return l(this,arguments,function*(e={}){var n,s;const t={pageSize:this._loadingMessagesSize};if(this._id){e=w(w({},t),e),this.event.emit("history:loading"),D.log("history:loading"),(e.endTime||e.startTime)&&(this.event.emit("history:moreloading",e),D.log("history:moreloading",e)),this._loadingMessages=!0;const r=yield this.cvforceApi.getChatHistorySessionId(this._applicationId,this._id,e),o=r.map((a,d)=>{var f,y;let h=[],u;return typeof((f=a.agentHistoryList)==null?void 0:f.agentList)=="string"&&(h=JSON.parse(a.agentHistoryList.agentList).reduce((g,b)=>(g[b.data.step-1]||(g[b.data.step-1]=[]),g[b.data.step-1].push(b),g),[])),d===r.length-1&&(u=(y=this.data)==null?void 0:y.lastRelatedQuestion),E(w({},a),{actions:h,relatedQuesion:u,fromHistory:!0})});if(!e.endTime&&!e.startTime){const a=this.messages[this.messages.length-1];a&&!a.relatedQuesion&&(a.relatedQuesion=(n=this.data)==null?void 0:n.lastRelatedQuestion),this.messages=[...o,...this.messages]}else if(e.endTime&&!e.startTime){const a=this.messages.findIndex(d=>d.ts===e.endTime);this.messages.splice(0,a+1),this.messages=[...o,...this.messages]}else if(!e.endTime&&e.startTime){const a=this.messages.findLastIndex(d=>d.ts===e.endTime);this.messages.splice(a,this.messages.length-a-1),this.messages=[...this.messages,...o]}else{const a=this.messages.findIndex(h=>h.ts===e.endTime),d=this.messages.findLastIndex(h=>h.ts===e.endTime);this.messages.splice(a,d-a+1,...o)}const c=this.messages[this.messages.length-1];return c&&!c.relatedQuesion&&(c.relatedQuesion=(s=this.data)==null?void 0:s.lastRelatedQuestion),this.event.emit("history:moreloaded",o),D.log("history:loaded",this.messages),this.event.emit("history:loaded",this.messages),this._loadingMessages=!1,o}else{const r=new Error("session id is not defined");return D.error(r),this.event.emit("error",r),!1}})}rename(e){return l(this,null,function*(){if(!this._id)throw Error("session is not created yet");if(e.trim()==="")throw Error("name is empty");return this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{name:e}),D.log("data:updated",this.messages),this.event.emit("data:updated",this.data),this.event.emit("data:updated:name",{name:e}),!0})}pushMessage(e){return l(this,null,function*(){this.messages.push(e),D.log("history:add",e),this.event.emit("history:add",e),this.event.emit("message:new",e),this.event.emit("message:updated",e)})}reloadSessionInfo(){if(!this._id)throw Error("session is not created yet");return this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,this._id).then(e=>l(this,null,function*(){if(this.data=e,!this._id)throw Error("session is not created yet");return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this._id),D.log("data:updated",this.data),this.event.emit("data:updated",this.data),this.data})).then(()=>l(this,null,function*(){return this.messages=[],yield this.fetchMessages(),this._dataLoading=!1,this._dataLoaded=!0,this.event.emit("data:loaded",this.data),this}))}reload(){return l(this,null,function*(){return yield this.reloadSessionInfo(),this.socket?(this.inactivate(!0),this.activate()):(this.inactivate(!0),this.activate())})}delete(){return l(this,null,function*(){if(!this.id){const e=new Error("session id is not defined");return D.error(e),this.event.emit("error",e),!1}return this.event.emit("data:deleting"),yield this.cvforceApi.delSessionsId(this.applicationId,this.id),this.event.emit("data:deleted"),this.destroy()})}activate(){return l(this,null,function*(){if(this.activing)return new Promise(t=>{this.addEventListener("activated",()=>{t(!0)},!0)});if(!this._id)throw Error("session is not avalible. id is undefined");this.activing=!0;const e=this._id;return this._dataLoading=!0,this._dataLoaded=!1,this.data=yield this.cvforceApi.getSession(this.applicationId,e).then(t=>l(this,null,function*(){return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,e),t})),this.messages.length||(this.messages=[],yield this.fetchMessages()),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),this._dataLoaded=!0,this._dataLoading=!1,this.inactivating=!1,this.frozen=!0,yield this.prepareConnection(),this.event.emit("activated",this.socket),this.active=!0,this.activing=!1,this})}inactivate(e=!1){return this.socket?this._frozen?(e||(this.inactivating=!0),this.activing=!1,!0):(this.socket.close(),this.socket=null,this.event.emit("inactivated"),this.active=!1,this.activing=!1,!0):(this.activing=!1,!0)}get dataLoaded(){return this._dataLoaded}get messagesLoading(){return this._loadingMessages}send(n){return l(this,arguments,function*(e,t={stream:exports.configuration.stream}){var _;try{this.validateConfigs()}catch(g){console.error(g)}const{stream:s=exports.configuration.stream,referenceFirst:r=!1}=t,o=e.uuid||ye.v4(),c=((_=e.text)==null?void 0:_.trim())||"",a=e.files||[],d=e.fileIds,h=e.imageContent;if(!c&&!a.length&&!(d!=null&&d.length)){const g=new Error("failed at sending empty content");return D.error(g),this.event.emit("error",g),!1}if(!this._id){const g=new Error("session id is not defined");return D.error(g),this.event.emit("error",g),!1}if(this.frozen){const g=new Error("session is frozen");return D.error(g),this.event.emit("error",g),!1}this.frozen=!0,this._stopAnswer=!1;const u={sessionId:this.id,role:2,content:c,messageId:o,reference:[],searchReference:[],messageTime:"",files:a,imageContent:h},f={content:c,stream:s,requestId:o,fileIds:d,referenceFirst:r,imageContent:h};this.pushMessage(u),this.event.emit("question:content",c);const y=g=>l(this,null,function*(){if(g.role!==T.ChatMessageRole.Robot)return;switch(this.removeEventListener("answer:finish",y),this._id&&g.content&&g.index&&g.index<0&&(this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{finialMessage:g.content}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:finialMessage",{finialMessage:g.content})),yield this.fillMessageReference(g),g.code){case 11915:g.content="请您换个问题问我吧~",g.index=-1,g.isSensitive=!0,g.isLoading=!1,g.sessionId=this._id||"",this.event.emit("message:error",g);break;case 11916:g.content="尊敬的用户您好,让我们换个话题再聊聊吧。",g.index=-1,g.isSensitive=!0,g.isLoading=!1,g.sessionId=this._id||"",this.event.emit("message:error",g);break;case 200:g.index=-1,g.isLoading=!1;break;default:g.content=g.message||"未知错误",g.isLoading=!1,g.index=-1,this.event.emit("message:error",g)}this.getRelatedQuesion(g),g.isLoading=!1;let b=this.messages[this.messages.length-1];if(b&&b.role===T.ChatMessageRole.Robot){const A=w(w({},b),g);this.messages[this.messages.length-1]=A,this.event.emit("message:updated",A)}else this.pushMessage(g);this.frozen=!1});return this.addEventListener("answer:finish",y),this.sendQuestion(f,E(w({},t),{stream:s,referenceFirst:r})),u})}currentUserQuestion(){for(let e=this.messages.length-1;e>=0;e-=1){const t=this.messages[e];if(t.role===T.ChatMessageRole.User)return t.content||""}return""}getRelatedQuesion(e){return l(this,null,function*(){var c,a;if(!e.content||e.isSensitive||e.code!==200)return e;const t=(c=this.application)==null?void 0:c.arrange[0],n=lr(t==null?void 0:t.recommendQuestionOpen,t==null?void 0:t.relatedQuestionApp,e.content,this.currentUserQuestion());if(n===null)return e;this.event.emit("message:relatedQuesion:loading",e);const s=yield this.cvforceApi.postGeneques({content:n}).catch(d=>null);if(!s){const d=[],h=E(w({},e),{relatedQuesion:d,index:-3,isLoading:!1});return this.event.emit("message:relatedQuesion:loaded",{relatedQuesion:d}),this.event.emit("message:updated",h),h}const r=(a=s.content)==null?void 0:a.split("*").map(cr).map(dr).filter(d=>!!d);e.relatedQuesion=r,e.index=-3,e.isLoading=!1;const o=E(w({},e),{relatedQuesion:r,index:-3,isLoading:!1});return this.event.emit("message:relatedQuesion:loaded",o),this.event.emit("message:updated",o),this._id&&this.cvforceApi.patchSessionsId(this._applicationId,this._id,{lastRelatedQuestion:r}),o})}fillMessageReference(e){return l(this,null,function*(){try{const t=yield Promise.all(e.reference.map(n=>this.cvforceApi.getKnowledgeIdFileId(n.knowledgeId,n.docId)));e.reference=e.reference.map((n,s)=>w(w({},n),t[s]))}catch(t){console.error("Failed to fill message reference:",t)}return this.event.emit("message:updated",e),e})}answerAgain(){return l(this,arguments,function*(e={stream:exports.configuration.stream}){const t=this.messages[this.messages.length-1];if(!t)throw Error("message list is empty");this.frozen=!0,this._stopAnswer=!1;const{stream:n=exports.configuration.stream}=e;let s;t.role!==T.ChatMessageRole.User&&(s=e.oldMessageId||t.messageId,this.messages.splice(this.messages.length-1,1),this.event.emit("message:remove",t),this.event.emit("history:remove",t));const r=this.messages[this.messages.length-1],o={content:r.content,fileIds:r.fileIds,requestId:r.messageId,stream:n,oldMessageId:s},c=a=>l(this,null,function*(){if(a.role===T.ChatMessageRole.Robot&&a.index===-1){switch(this._id&&a.content&&a.index&&a.index<0&&(this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{finialMessage:a.content}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:finialMessage",{finialMessage:a.content})),yield this.fillMessageReference(a),a.code){case 11915:a.content="请您换个问题问我吧~",a.index=-1,a.isSensitive=!0,a.isLoading=!1,a.sessionId=this._id||"",this.event.emit("message:error",a);break;case 11916:a.content="尊敬的用户您好,让我们换个话题再聊聊吧。",a.index=-1,a.isSensitive=!0,a.isLoading=!1,a.sessionId=this._id||"",this.event.emit("message:error",a);break;case 200:a.index=-1,a.isLoading=!1;break;default:a.content=a.message||"未知错误",a.isLoading=!1,a.index=-1,this.event.emit("message:error",a)}this.getRelatedQuesion(a),this.removeEventListener("message:content",c),this.frozen=!1}});this.addEventListener("message:content",c),this.sendQuestion(o,E(w({},e),{stream:n}))})}setTop(e){return l(this,null,function*(){if(!this._id)throw Error("session is not avalible. id is undefined");this.data=yield this.cvforceApi.patchSessionsId(this._applicationId,this._id,{top:e}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:top",{top:e})})}suspend(){var n;this.stopAnswer(),this.frozen=!1,this._stopAnswer=!0;let e=this.messages[this.messages.length-1];const t={messageId:ye.v4(),isLoading:!1,index:-2,messageTime:gt(new Date).format("YYYY-MM-DD HH:ss:mm"),content:"",role:T.ChatMessageRole.System,sessionId:this.id||"",reference:[],searchReference:[]};if(e&&!e.messageId){if(e.index===-2)return;if(e.actions){const s=e.actions[((n=e.actions)==null?void 0:n.length)-1];if(s){const r=s[s.length-1];if(r&&(r.type==="BEFORE_CALL"||r.type==="FUNCTION_CALL")){const{pluginName:o,pluginCode:c,funcCode:a,funcName:d}=r.data;s.push({data:{pluginName:o,pluginCode:c,funcCode:a,funcName:d,step:r.data.step+1},type:"ABORT"}),this.event.emit("message:action",{messageId:e.messageId,action:s})}}}e=w(w({},e),t),this.event.emit("message:content",e),this.event.emit("message:updated",e)}else this.pushMessage(t),this.event.emit("message:content",t);return this}handleStreamAnswer(e,t){var o;if(!e.data)return;const n=e.data.type,s=e.data.payload;t.isReplying=!0;const r=()=>{if(!t.searchingStatus){t.searchingStatus="start";return}if(t.searchingStatus==="start"){t.searchingStatus="end";return}};if(n==="error"&&(t.index=-1),n==="beforeSearch"&&r(),n==="searchOver"&&r(),n==="search"&&t.searchReference.push(s),n==="thinking"){t.thinkingStatus="start";const a=s.choices[0];t.reasoningContent=(t.reasoningContent||"")+((o=a.delta.reasoningContent)!=null?o:"")}if(n==="thinkingOver"){t.thinkingStatus="end";const c=s.thinkingSecs;t.thinkingSecs=c}if(n==="text"){const a=s.choices[0];t.content=(t.content||"")+a.delta.content}if(n==="reference"&&(t.reference=s),n==="updateSession"&&s&&this.data&&(this.data=w(w({},this.data),s),this.event.emit("data:updated",this.data)),n==="result"){const c=s.messageId,a=s.llmModel,d=s.messageTime;t.messageId=c,t.llmModel=a,t.messageTime=d}n==="over"?t.index=-1:(t.code=e.code,t.message=e.message)}getArtifacts(){return l(this,null,function*(){var t;if(!this._applicationId||!this._id)throw Error("session is not avalible. id is undefined");const e=yield this.cvforceApi.getSessionArtifacts(this._applicationId,this._id);return(t=e==null?void 0:e.artifacts)!=null?t:[]})}postMessageComment(e){return l(this,null,function*(){if(!this._applicationId||!this._id)throw Error("session is not avalible. id is undefined");return this.cvforceApi.postComments(this._applicationId,this._id,e).then(t=>{const n=this.messages.find(s=>s.messageId===e.messageId);return n&&(n.comment=e,this.event.emit("message:comment",n)),t})})}clear(){if(!this._id)throw Error("session is not avalible. id is undefined");return this.cvforceApi.patchApplicationIdSessionsIdContext(this._applicationId,this._id).then(()=>(this.event.emit("context:clear"),!0))}destroy(){var e;return this._ready=!1,this.event.removeAllListeners(),(e=this.socket)==null||e.disconnect(),this.socket=null,this.event.emit("destroy",{applicationId:this._applicationId,sessionId:this._id}),this._id||""}}const q=new H("[AgentSession] ");function fi(i){if(typeof i!="string")return i;const e=i.trim();if(e)try{return JSON.parse(e)}catch(t){return i}}function pi(i){return i==null||i===""||typeof i=="object"&&!Array.isArray(i)&&Object.keys(i).length===0}function Ar(i,e){const t=fi(i==null?void 0:i.query);if(!pi(t))return t;const n=fi(e);return pi(n)&&t!=null?t:n}class Lr extends Ut{constructor(t,n="",s,r,o,c){super(t,n,s,r,o,c);v(this,"inflightCalls",new Set)}prepareConnection(){return new Promise(t=>l(this,null,function*(){this.socket&&t(!0);const n={version:"1.0",stream:JSON.stringify(exports.configuration.stream),appId:this._applicationId,sessionId:this.id,Authorization:`${this.token}`,userMode:exports.configuration.debug?pe.Debug:pe.Normal},s=new URL(exports.configuration.apiRoot),r=yield An.io(s.origin,{path:s.pathname.replace("api","socketio")+"/copilot",query:n,transports:["websocket"]});r.on("connect",()=>{q.log("socket:connect"),this.event.emit("socket:connect"),r.emit("init")}),r.on("disconnect",()=>{q.log("socket:disconnect"),this.event.emit("socket:disconnect"),this._ready=!1}),r.on("ready",o=>{if(o.code===200){q.log("ready");const c=exports.configuration.debug?pe.Debug:pe.Normal;c===pe.Debug&&o.userMode,this._ready||(this._ready=!0,this.event.emit("ready")),this.frozen=!1,this.registerMcpFromClientConfig(),t(!0)}else{this._ready&&(this._ready=!1);const c=new Error(Ae.SocketConnectionFailed);q.error("error",c),this.event.emit("error",c),t(!1)}}),r.on("action",(o,c)=>l(this,null,function*(){var g;if(this._stopAnswer||!this.id)return;const{type:a,data:{runnerIsClient:d,pluginCode:h,funcCode:u,parameters:f,requestBody:y}}=o,_=this.messages[this.messages.length-1];if(!_.messageId)_.actions||(_.actions=[]),_.actions[o.data.step-1]||(_.actions[o.data.step-1]=[]),_.actions[o.data.step-1].push(o),this.event.emit("message:action",{messageId:_.messageId,action:o}),this.event.emit("message:updated",_);else{const b={messageId:"",content:"",role:T.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!0,messageTime:"",actions:[[o]],comment:{isAgree:0},isReplying:!0};this.pushMessage(b),this.event.emit("message:action",{messageId:b.messageId,action:o})}if(this.inactivating){const b=new Error(Ae.Inactive);q.warn("error",b),this.event.emit("error",b)}else if(a==="FUNCTION_CALL"&&d){q.log(`calling function ${u} of plugin ${h} with argument:
|
|
366
|
+
${JSON.stringify(f)}`);const b=(g=exports.configuration.plugins)==null?void 0:g[h];if(!b){c({code:404,message:"没有找到插件。"});return}const A=b[u];if(typeof A!="function"){c({code:404,message:"没有找到插件方法。"});return}const I=Ar(f,y);this.invokeClientPlugin(A,I,c,{requestId:o.requestId,pluginCode:h,functionCode:u})}})),r.on("answer",o=>{if(!this._stopAnswer)if(o.data.code!==200&&(o.data.index=-1),o.data.stream||o.data.stream===void 0){let c=this.messages[this.messages.length-1];if(c&&c.role===T.ChatMessageRole.Robot)this.handleStreamAnswer(o.data,c),this.messages[this.messages.length-1]=c,this.event.emit("message:content",c),this.event.emit("message:updated",c),c.index===-1&&(c.isReplying=!1,this.event.emit("answer:finish",c));else{const a={content:"",role:T.ChatMessageRole.Robot,reference:[],searchReference:[],messageId:"",sessionId:this.id,messageTime:gt(new Date).format("YYYY-MM-DD HH:mm:ss"),comment:{isAgree:0},isReplying:!0,reasoningContent:"",thinkingSecs:"",thinkingStatus:"",searchingStatus:""};this.handleStreamAnswer(o.data,a),this.pushMessage(a),this.event.emit("message:content",a),a.index===-1&&(a.isReplying=!1,this.event.emit("answer:finish",a))}}else if(o.data.updateSession&&this.data&&(this.data=w(w({},this.data),o.data.updateSession),this.event.emit("data:updated",this.data)),o.data.index===-1){let c=this.messages[this.messages.length-1];if(c&&!c.messageId)c=w(w({},c),o.data),this.event.emit("message:content",c),this.event.emit("message:updated",c),this.event.emit("answer:finish",c);else{const a=w({messageId:"",content:"",role:T.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!1,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0},o.data);this.event.emit("message:content",a),this.pushMessage(a),this.event.emit("answer:finish",a)}}else{let c=this.messages[this.messages.length-1];c&&!c.messageId?(c=w(w({},c),o.data),this.messages[this.messages.length-1]=c,this.event.emit("message:content",c),this.event.emit("message:updated",c)):(this.pushMessage(w({messageId:"",content:"",role:T.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!1,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0},o.data)),this.event.emit("message:content",o.data))}}),r.on("reference",o=>l(this,null,function*(){if(this._stopAnswer)return;if(!this.id){const f=new Error(Ae.IdUndefined);q.error(f),this.event.emit("error",f),this.frozen=!1;return}const{type:c,data:a,requestId:d}=o,h=this.messages.findIndex(f=>f.messageId===d&&f.role===T.ChatMessageRole.User);if(h<0)return;const u=h+1;if(u>=this.messages.length){const f={messageId:"",content:"",role:T.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!0,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0};this.pushMessage(f)}c==="KG"?(this.messages[u]=E(w({},this.messages[u]),{reference:a.knowledgeReference}),yield this.fillMessageReference(this.messages[u]),this.event.emit("message:reference",a.knowledgeReference),this.event.emit("message:updated",this.messages[u])):c==="WEB_SEARCH"&&(this.messages[u]=E(w({},this.messages[u]),{searchReference:a.knowledgeReference}),this.event.emit("message:searchreference",a.searchReference),this.event.emit("message:updated",this.messages[u]))})),this.socket=r,r.open()}))}registerMcpFromClientConfig(){return exports.configuration.mcp?new Promise((t,n)=>{if(!this.socket){n("socket is undefined");return}this.socket.emit("add_mcp_servers",exports.configuration.mcp,s=>{s.code===200?(Object.keys(s.data).forEach(r=>{s.data[r].code!==200&&console.error(r,"MCP Server 注册失败。",s.data[r])}),t(!0)):(console.error("MCP Server 注册失败。",s),n(s))})}):Promise.resolve(!0)}addMcpServers(t){return l(this,null,function*(){return this.ready?this.socket?new Promise((n,s)=>{this.socket&&this.socket.emit("add_mcp_servers",t,r=>{r.code===200?(Object.keys(r.data).forEach(o=>{r.data[o].code!==200&&console.error(o,"MCP Server 注册失败。",r.data[o])}),n(!0)):(console.error("MCP Server 注册失败。",r),s(r))})}):(console.error(" socket is undefined."),Promise.reject("socket is undefined")):(console.error("session is not avalible."),Promise.reject("session is not avalible"))})}listMcpServers(){return l(this,null,function*(){return this.ready?this.socket?new Promise((t,n)=>{this.socket&&this.socket.emit("list_mcp_servers",s=>{s.code===200?t(s.data):n(s)})}):(console.error(" socket is undefined."),Promise.reject("socket is undefined")):(console.error("session is not avalible."),Promise.reject("session is not avalible"))})}sendQuestion(t,n){return l(this,null,function*(){var r,o,c;this.convertKnowledgesToChatFormat(this.knowledges);let s=E(w({},t),{promptVariables:this.promptVariables.filter(a=>a.type===T.PromptVariableType.User).reduce((a,d)=>E(w({},a),{[d.key]:d.value}),{}),systemPromptVariables:this.promptVariables.filter(a=>a.type===T.PromptVariableType.System).reduce((a,d)=>E(w({},a),{[d.key]:d.value}),{}),knowledges:(r=this.knowledges)==null?void 0:r.map(a=>a.id),enableTitleSummary:!0});if(!this.active){if(yield this.activate(),!this.socket){const a=new Error(Ae.SocketConnectionFailed);return q.warn("error",a),this.event.emit("error",a),!1}(o=this.socket)==null||o.emit("question",s);return}(c=this.socket)==null||c.emit("question",s)})}invokeClientPlugin(t,n,s,r){const o=new AbortController;this.inflightCalls.add(o);let c=!1;const a=(...h)=>{c||(c=!0,this.inflightCalls.delete(o),!(this._stopAnswer||o.signal.aborted)&&s(...h))},d={requestId:r.requestId||ye.v4(),applicationId:this._applicationId,sessionId:this.id,pluginCode:r.pluginCode,functionCode:r.functionCode,signal:o.signal};try{const h=t(n,a,d);h&&typeof h.catch=="function"&&h.catch(u=>{q.error("client plugin failed",u),a({code:500,message:"客户端插件执行失败。"})})}catch(h){q.error("client plugin failed",h),a({code:500,message:"客户端插件执行失败。"})}}abortClientPluginCalls(){const t=Array.from(this.inflightCalls);this.inflightCalls.clear(),t.forEach(n=>n.abort())}stopAnswer(){var t;this.abortClientPluginCalls(),(t=this.socket)==null||t.emit("stop_answer")}inactivate(t=!1){return this.abortClientPluginCalls(),super.inactivate(t)}destroy(){return this.abortClientPluginCalls(),super.destroy()}convertKnowledgesToChatFormat(t){return t?t.map(n=>n!=null&&n.fileIds?{id:n.id,fileIds:n.fileIds}:n.id):[]}}function kr(i,e){return l(this,null,function*(){const t=i.getReader();let n;for(;!(n=yield t.read()).done;)e(n.value)})}function Rr(i){let e,t,n,s=!1,r;return function(c){e===void 0?(e=c,t=0,n=-1,r=!1):e=Mr(e,c);const a=e.length;let d=0;for(;t<a;){s&&(e[t]===10&&(d=++t),s=!1);let h=-1;for(;t<a&&h===-1;++t)switch(e[t]){case 58:n===-1&&(n=t-d);break;case 13:s=!1,t+4<a&&e[t+1]===10&&e[t+2]!==13&&e[t-1]!==10&&e[t-2]!==13&&(r=!0);case 10:h=t;break}if(h===-1)break;i(e.subarray(d,h),n,r),d=t,n=-1,r=!1}d===a?e=void 0:d!==0&&(e=e.subarray(d),t-=d)}}function Cr(i,e,t){let n=mi();const s=new TextDecoder;return function(o,c,a){if(o.length===0)t==null||t(n),n=mi();else if(c>0){const d=s.decode(o.subarray(0,c)),h=c+(o[c+1]===32?2:1);let u=s.decode(o.subarray(h));switch(a&&(u+=`
|
|
367
|
+
`),d){case"data":n.data=n.data?n.data+`
|
|
368
|
+
`+u:u;break;case"event":n.event=u;break;case"id":i(n.id=u);break;case"retry":const f=parseInt(u,10);isNaN(f)||e(n.retry=f);break}}}}function Mr(i,e){const t=new Uint8Array(i.length+e.length);return t.set(i),t.set(e,i.length),t}function mi(){return{data:"",event:"",id:"",retry:void 0}}const mt="text/event-stream",Or=1e3,gi="last-event-id";function yi(i,h){var u=h,{signal:e,headers:t,onopen:n,onmessage:s,onclose:r,onerror:o,openWhenHidden:c,fetch:a}=u,d=zt(u,["signal","headers","onopen","onmessage","onclose","onerror","openWhenHidden","fetch"]);return new Promise((f,y)=>{const _=w({},t);_.accept||(_.accept=mt);let g;function b(){g.abort(),document.hidden||N()}c||document.addEventListener("visibilitychange",b);let A=Or,I=0;function L(){document.removeEventListener("visibilitychange",b),window.clearTimeout(I),g.abort()}e==null||e.addEventListener("abort",()=>{L(),f()});const k=a!=null?a:window.fetch,K=n!=null?n:Fr;function N(){return l(this,null,function*(){var S;g=new AbortController;try{const M=yield k(i,E(w({},d),{headers:_,signal:g.signal}));yield K(M),yield kr(M.body,Rr(Cr(O=>{O?_[gi]=O:delete _[gi]},O=>{A=O},s))),r==null||r(),L(),f()}catch(M){if(!g.signal.aborted)try{const O=(S=o==null?void 0:o(M))!=null?S:A;window.clearTimeout(I),I=window.setTimeout(N,O)}catch(O){L(),y(O)}}})}N()})}function Fr(i){const e=i.headers.get("content-type");if(!(e!=null&&e.startsWith(mt)))throw new Error(`Expected content-type to be ${mt}, Actual: ${e}`)}const wi=new H("[DialogSession] ");class Nr extends Ut{constructor(t,n="",s,r,o,c){super(t,n,s,r,o,c);v(this,"ctrl",new AbortController)}prepareConnection(){return new Promise(t=>l(this,null,function*(){this._ready=!0,this.event.emit("ready"),this.frozen=!1,t(!0)}))}postChatV2EventSource(t,n,s,r,o,c){return l(this,null,function*(){const a={code:0,content:"",role:T.IHistoryRole.Robot,sessionId:n,reference:[],searchReference:[],messageTime:"",llmModel:"",comment:{isAgree:0},isReplying:!1},d=E(w({},s),{stream:exports.configuration.stream});yi(`${exports.configuration.apiRoot}/chat/v2/chat?applicationId=${t}&sessionId=${n}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(d),openWhenHidden:!0,signal:r,onopen(h){return h.ok&&o!=null&&o.onopen&&o.onopen(),Promise.resolve()},onmessage(h){if(!h.data.includes('{"code": ')){let f={};try{f=JSON.parse(h.data)}catch(_){}(f==null?void 0:f.mtype)==="search"?a.searchReference.push(f):a.content=a.content+h.data;const y={content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:n,messageTime:gt(new Date).format("YYYY-MM-DD HH:mm:ss"),comment:{isAgree:0},isReplying:!0};return(o==null?void 0:o.onmessage)&&o.onmessage(y)}const u=JSON.parse(h.data);if(a.reference=u.data.reference,a.searchReference=u.data.searchReference,a.messageTime=u.data.messageTime,a.messageId=u.data.messageId,a.llmModel=u.data.llmModel,a.content=u.data.content,a.code=u.code,u.code===200){const f={code:a.code,content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:n,messageTime:a.messageTime,isReplying:!0};o!=null&&o.onmessage&&o.onmessage(f)}else return o!=null&&o.onclose&&o.onclose(a),c&&c({code:a.code,message:a.message})},onerror(){o!=null&&o.onerror&&o.onerror()},onclose(){const h={code:a.code,content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:n,messageTime:a.messageTime,comment:{isAgree:0},isReplying:!1,index:-1};o!=null&&o.onclose&&o.onclose(h)}})})}postChatV3EventSource(t,n,s,r,o,c){return l(this,null,function*(){const a=this,d={code:0,content:"",role:T.IHistoryRole.Robot,sessionId:n,reference:[],searchReference:[],messageTime:"",llmModel:"",comment:{isAgree:0},isReplying:!1,reasoningContent:"",thinkingSecs:"",thinkingStatus:"",searchingStatus:""},h=E(w({},s),{stream:exports.configuration.stream});yi(`${exports.configuration.apiRoot}/chat/v3/chat?applicationId=${t}&sessionId=${n}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(h),openWhenHidden:!0,signal:r,onopen(u){return u.ok&&o!=null&&o.onopen&&o.onopen(),Promise.resolve()},onmessage(u){if(!u.data&&!u.event&&!u.id&&!u.retry)return;let f={};try{f=JSON.parse(u.data)}catch(y){console.error("parse eventData to JSON failed. ",u.data)}if(f.code!==200)return d.index=-1,d.code=f.code,d.message=f.message,o!=null&&o.onmessage&&o.onmessage(d),c&&c({code:f.code,message:f.message});a.handleStreamAnswer(f,d),o!=null&&o.onmessage&&o.onmessage(d)},onerror(){o!=null&&o.onerror&&o.onerror()},onclose(){const u=E(w({},d),{isReplying:!1});o!=null&&o.onclose&&o.onclose(u)}})})}sendQuestion(t,n){return l(this,null,function*(){const{content:s,fileIds:r,oldMessageId:o,imageContent:c}=t,{stream:a,referenceFirst:d}=n;if(this.active||(yield this.activate()),this._id){const h=this.convertKnowledgesToChatFormat(this.knowledges);let u={content:s,fileIds:r,referenceFirst:d,oldMessageId:o,promptVariables:this.promptVariables.filter(f=>f.type===T.PromptVariableType.User).reduce((f,y)=>E(w({},f),{[y.key]:y.value}),{}),systemPromptVariables:this.promptVariables.filter(f=>f.type===T.PromptVariableType.System).reduce((f,y)=>E(w({},f),{[y.key]:y.value}),{}),knowledges:h,enableTitleSummary:!0,imageContent:c};this.ctrl=new AbortController,this.postChatV3EventSource(this._applicationId,this._id,u,this.ctrl.signal,{onopen:()=>{wi.log("open",this.ctrl)},onmessage:f=>{if(this._stopAnswer)return;let y=this.messages[this.messages.length-1];y&&y.role===T.ChatMessageRole.Robot?(y=w(w({},y),f),this.messages[this.messages.length-1]=y,this.event.emit("message:content",y),this.event.emit("message:updated",y)):(this.pushMessage(f),this.event.emit("message:content",f))},onclose:f=>l(this,null,function*(){this._stopAnswer||(wi.log(f,"onclose"),this.event.emit("answer:finish",f))}),onerror:()=>{this._stopAnswer||(this.event.emit("message:error",""),this.frozen=!1)}})}})}stopAnswer(){this.ctrl.abort()}registerMcpFromClientConfig(){return l(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}addMcpServers(t){return l(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}listMcpServers(){return l(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}convertKnowledgesToChatFormat(t){return t?t.map(n=>n!=null&&n.fileIds?{id:n.id,fileIds:n.fileIds}:n.id):[]}}const Pr="@glodon-aiot/bot-client-sdk",Dr="3.26.0-alpha.5",$r="glodoncv",Br="aiot bot client js sdk",Ur="module",jr=!1,Hr=["aiot","bot","bot client","sdk"],qr=["dist"],Wr="./dist/es/index.mjs",zr="./dist/lib/index.js",Vr="./dist/src/index.d.ts",Yr={".":{import:"./dist/es/index.mjs",require:"./dist/lib/index.js",types:"./dist/src/index.d.ts"}},Xr="MIT",Gr={watch:"yarn build --watch",example:"node ./example/server.js",dev:"npm-run-all -p watch example",start:"vite",build:"tsc && vite build --mode prod && yarn build:cdn","build:npm":"tsc && vite build --mode prod","build:cdn":"tsc && vite build --mode prod --config ./vite.config.cdn.ts",preview:"vite preview",check:"yarn prettier --check .",write:"yarn prettier --write .",lint:"eslint --ext .tsx,.ts --fix ./example -c .eslintrc.js","build:just-bash":"node scripts/build-just-bash.mjs","upload:just-bash":"node scripts/build-just-bash.mjs && node scripts/upload-cdn-libs.cjs just-bash","build:pyodide":"node scripts/build-pyodide.mjs","upload:pyodide":"node scripts/build-pyodide.mjs && node scripts/upload-cdn-libs.cjs pyodide",test:"vitest run","test:watch":"vitest"},Kr={"@babel/core":"^7.20.12","@commitlint/cli":"^17.0.3","@commitlint/config-conventional":"^17.0.3","@rollup/plugin-babel":"^6.0.4","@rollup/plugin-typescript":"^11.1.6","@types/express":"^4","@types/identity-obj-proxy":"^3","@typescript-eslint/eslint-plugin":"^5.35.1","@typescript-eslint/parser":"^5.35.1","babel-loader":"^8.3.0",eslint:"^8.0.1","eslint-config-prettier":"^8.5.0","eslint-config-standard-with-typescript":"^22.0.0","eslint-plugin-import":"^2.25.2","eslint-plugin-n":"^15.0.0","eslint-plugin-promise":"^6.0.0","eslint-plugin-react":"^7.31.0","eslint-plugin-storybook":"^0.6.10",express:"4","http-proxy-middleware":"^3.0.0","identity-obj-proxy":"^3.0.0","just-bash":"3.6.0","npm-run-all":"^4.1.5",prettier:"2.7.1",pyodide:"314.0.7","rollup-plugin-visualizer":"^6.0.1","socket.io":"^4.7.5","ts-node":"^10.9.2",typescript:"*",vite:"^4.1.1","vite-plugin-dts":"^4.3.0","vite-plugin-externalize-deps":"^0.9.0","vite-tsconfig-paths":"^5.1.4",vitest:"^0.34.6"},Qr={access:"public",registry:"https://registry.npmjs.org/"},Jr={"@glodon-aiot/apis":"^3.26.0-alpha.5",axios:"0.24.0",buffer:"^6.0.3",dayjs:"^1.11.13","js-base64":"^3.7.7","socket.io-client":"^4.7.5",uuid:"^11.1.0"},Zr={name:Pr,version:Dr,author:$r,description:Br,type:Ur,sideEffects:jr,keywords:Hr,files:qr,module:Wr,main:zr,typings:Vr,exports:Yr,license:Xr,scripts:Gr,devDependencies:Kr,"lint-staged":{"*.{js,css,md,jsx,less,ts,tsx,json}":"prettier --write"},publishConfig:Qr,dependencies:Jr},vi=new H("[BotClient] ");class eo{constructor(e,t,n=!0,s={analytics:{enabled:!1}}){v(this,"event",new Pt);v(this,"cvforceApi");v(this,"_applicationId");v(this,"_application",null);v(this,"_sessions",[]);v(this,"_activeSession");v(this,"_ready",!1);v(this,"_questionContextMaxLength",4e3);v(this,"_promptVariables",[]);v(this,"_localWorkspace");v(this,"_disconnectHost");if(this._token=e,this.lazyload=n,this.sdkConfigs=s,ft(t),this._applicationId=We(e).rid||exports.configuration.applicationId,!this._applicationId)throw"token is not vaild";this.cvforceApi=this.getService(),this.setupLocalWorkspace(),this.loadApplication().then(r=>{ft(E(w({},t),{stream:t.stream===void 0?(r==null?void 0:r.type)===T.ApplicationTypes.Dialog||(r==null?void 0:r.type)===T.ApplicationTypes.Agent:t.stream})),this.event.emit("ready")})}setupLocalWorkspace(){var s,r;const e=(s=exports.configuration.builtinPlugins)==null?void 0:s.localFiles;if(!(e!=null&&e.enabled)){di(void 0),ut();return}const t=[],n=(r=e.backend)!=null?r:"file-system-access";if(n!=="file-system-access"&&n!=="host-bridge")t.push(new Error(`[LocalFiles] 不支持的 backend:${e.backend}`));else{const o=hr(exports.configuration.apiRoot,this.token,(c,a)=>vi.error(a));this._localWorkspace=new pn({applicationId:this._applicationId,config:e,store:fn(),picker:n==="host-bridge"?null:void 0,transfer:$t(()=>this.cvforceApi,()=>o)}),di(this._localWorkspace),n==="host-bridge"?this._disconnectHost=ur(this._localWorkspace):this._localWorkspace.restore()}t.push(...ut()),t.length&&Promise.resolve().then(()=>t.forEach(o=>this.event.emit("error",o)))}get localWorkspace(){return this._localWorkspace}checkReady(){if(!this.ready)throw Error("client is not ready.")}get ready(){return this._ready}set ready(e){this._ready=e}get questionContextMaxLength(){return this.checkReady(),this._questionContextMaxLength}get promptVariables(){return this.checkReady(),this._promptVariables}get knowledges(){var e;return this.checkReady(),(e=this._application)==null?void 0:e.arrange[0].knowledges}get sessions(){return this.checkReady(),this._sessions}set sessions(e){this.checkReady(),this._sessions=e,this.event.emit("sessions:updated",e)}loadApplication(){return l(this,null,function*(){var t,n,s,r,o;this._application=yield this.cvforceApi.getApplicationId(this._applicationId,{ui:(t=this.sdkConfigs.ui)==null?void 0:t.name,uiVersion:(n=this.sdkConfigs.ui)==null?void 0:n.version,sdkVersion:Zr.version}).then(c=>(typeof c.arrange[0].thinkingModeOpen!="boolean"&&(c.arrange[0].thinkingModeOpen=!0),typeof c.arrange[0].thinkingTextOpen!="boolean"&&(c.arrange[0].thinkingTextOpen=!0),E(w({},c),{arrange:[E(w({},c.arrange[0]),{recommendQuestionOpen:exports.configuration.loadRelatedQuesions&&c.arrange[0].recommendQuestionOpen})]})));const e=(o=(r=(s=this._application)==null?void 0:s.arrange)==null?void 0:r[0])==null?void 0:o.llmModel;return e&&(this._questionContextMaxLength=yield this.cvforceApi.getBaseModel(e).then(c=>c.maxModelLength)),this._promptVariables=yield Promise.all([this.cvforceApi.getPrompts(this._applicationId,{type:T.PromptVariableType.User}),this.cvforceApi.getPrompts(this._applicationId,{type:T.PromptVariableType.System})]).then(([c,a])=>[...c,...a]),this._ready=!0,this.event.emit("application:loaded"),this._application})}getService(){return this.cvforceApi?this.cvforceApi:on(exports.configuration.apiRoot,this.token,(e,t)=>vi.error(t))}get token(){return this._token}set token(e){this.checkReady(),this._token=e,this.ready=!1;const t=We(e).rid;this._applicationId!==t&&(this._applicationId=t,this._application=null,this.loadApplication().then(()=>{this.event.emit("ready")}),this.clean())}get applicationId(){return this._applicationId}get application(){return this.checkReady(),this._application}get activeSession(){var e;return this.checkReady(),((e=this._activeSession)==null?void 0:e.id)||""}set activeSession(e){this.checkReady(),this.loadSession(e).then(t=>{this._activeSession&&this._activeSession.id!==e&&this._activeSession.inactivate(),this._activeSession=t})}createSession(e,t,n,s,r){return l(this,null,function*(){const o=this;return new Promise((c,a)=>{const d=h=>l(this,null,function*(){if(h===T.ApplicationTypes.Agent)c(new Lr(e,t,n,s,r,o));else if(h===T.ApplicationTypes.Dialog)c(new Nr(e,t,n,s,r,o));else throw Error(`不支持的应用类型:${h}`)});if(this.ready){if(!this._application)throw Error("client is not ready");d(this._application.type)}else this.event.on("ready",()=>{if(!this._application)throw Error("_application is null");d(this._application.type)},!0)})})}getArtifacts(e){return l(this,null,function*(){var r,o;this.checkReady();const t=e||((r=this._activeSession)==null?void 0:r.id);if(!t)throw new Error("session id is not defined");const n=this._sessions.find(c=>c.id===t);if(n)return n.getArtifacts();const s=yield this.cvforceApi.getSessionArtifacts(this._applicationId,t);return(o=s==null?void 0:s.artifacts)!=null?o:[]})}getSessions(e){return l(this,null,function*(){return new Promise((t,n)=>{const s=()=>this.cvforceApi.listSessions(this._applicationId,e).then(r=>l(this,null,function*(){const o=[];for(const c of r){const a=this._sessions.find(d=>d.id===c.id);if(a)a.data=c,this._application?a.application=this._application:yield a.loadApplicationInfo(),o.push(a);else{const d=yield this.createSession(this.token,c.id,c,this.lazyload,this._application||void 0);o.push(d)}}if(e!=null&&e.pageSize){const c=[...this._sessions,...o],a=new Map;for(const d of c)a.set(d.id,d);return this.sessions=Array.from(a.values()),this.sessions}else return this.sessions=o,o}));if(this.ready){if(!this._application)throw Error("_application is null");t(s())}else this.event.on("ready",()=>{if(!this._application)throw Error("_application is null");t(s())},!0)})})}loadSession(e="",t){return l(this,null,function*(){this.checkReady();let n=this.sessions.find(s=>s.id===e);if(n||(n=yield this.createSession(this.token,e,t),this._sessions.push(n)),this._activeSession){if(this._activeSession===n)return n;this._activeSession.inactivate()}return n.id?(this._activeSession=n,yield n.activate()):n.addEventListener("data:loaded",()=>{this._activeSession!==n&&(n==null||n.activate(),this._activeSession=n)},!0),n})}reload(){return this.loadApplication().then(()=>l(this,null,function*(){return yield this.getSessions(),this.event.emit("ready"),this}))}reloadSession(e){return l(this,null,function*(){yield this.reload();let t=this._sessions.find(n=>n.id===e)||this._activeSession;if(!t){console.warn("reloadSession session failed.");return}return yield t.reload(),t})}setTop(e,t,n="top_time desc, sort_status desc, updated_at desc"){return l(this,null,function*(){let s=e?this._sessions.find(r=>r.id===e):this._activeSession;if(!s){console.warn("setTop session failed.");return}return yield s.setTop(t),this.getSessions({order:n})})}addEventListener(e,t,n=!1){if(typeof t!="function")throw Error("event listener is not a function");if(n){this.event.once(e,t);return}this.event.on(e,t)}removeEventListener(e,t){this.event.off(e,t)}removeSession(e,t){return l(this,null,function*(){this.checkReady();let n=-1;if(typeof e=="string"?n=this._sessions.findIndex(s=>s.id===e):n=this._sessions.findIndex(s=>s.id===e.id),n>-1){const s=this._sessions[n];t&&(yield s.delete()),this._sessions.splice(n,1)}else console.warn("session delete failed, session is not exist.")})}clean(){var e;(e=this._disconnectHost)==null||e.call(this),this._disconnectHost=void 0,this._sessions.forEach(t=>t.destroy()),this.sessions=[]}}class to{constructor(e,t={},n){v(this,"code");v(this,"description","");v(this,"loaded",!1);v(this,"functions",{});this.code=e,t&&(this.functions=t)}fetchData(){this.description="描述",this.loaded=!0}checkFunctions(){}}const Y="只操作用户在当前浏览器里选择的本地文件夹,路径相对该文件夹。云端工作区的文件不要用本工具。",W={type:"string",enum:[we],description:`工作区 ID。省略时按 ${we} 处理,传其他值会被拒绝。`},X=i=>({type:"string",description:`${i}使用相对工作区根目录的路径,以 / 分隔,不能包含 .. 或绝对路径。`}),tt={type:"string",description:"文件当前内容的 hash(sha256:<hex>),来自 read_file 或 stat_file 的返回值。"},mn={list_directory:{functionCode:"list_directory",name:"列出本地目录",description:`${Y}列出某个目录的直接子项(目录在前),支持分页。`,parameters:{type:"object",required:["grantId"],properties:{grantId:W,path:X('要列出的目录,省略或传 "." 表示工作区根目录。'),offset:{type:"integer",minimum:0,description:"分页起始位置,默认 0。"},limit:{type:"integer",minimum:1,maximum:1e3,description:"每页条数,默认 200。"}}}},read_file:{functionCode:"read_file",name:"读取本地文件",description:`${Y}按行读取文本文件,单次最多返回 1 MiB,超出部分会被截断(truncated: true)。返回内容的 hash 可用于后续修改。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:W,path:X("要读取的文件。"),startLine:{type:"integer",minimum:1,description:"起始行(从 1 开始,含)。"},endLine:{type:"integer",minimum:1,description:"结束行(含)。"},maxBytes:{type:"integer",minimum:1,description:"返回内容的最大字节数,不超过 1 MiB。"},encoding:{type:"string",enum:["utf-8","gbk","gb18030"],description:"文本编码,默认 utf-8。"}}}},stat_file:{functionCode:"stat_file",name:"查看本地文件信息",description:`${Y}返回文件或目录的类型、大小、修改时间,可选返回 hash。不返回文件内容。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:W,path:X("要查看的文件或目录。"),includeHash:{type:"boolean",description:"是否计算文件 hash。"}}}},search_files:{functionCode:"search_files",name:"查找本地文件",description:`${Y}按文件名或 glob(支持 *、?、**)查找文件。不含 / 的模式匹配文件名,含 / 的模式匹配相对 path 的路径。`,parameters:{type:"object",required:["grantId","pattern"],properties:{grantId:W,pattern:{type:"string",minLength:1,description:"如 *.xlsx 或 reports/**/*.docx。"},path:X("搜索起点目录,默认工作区根目录。"),maxDepth:{type:"integer",minimum:1,maximum:16,description:"最大目录深度,默认 8。"},maxResults:{type:"integer",minimum:1,maximum:200,description:"最多返回条数,默认 200。"}}}},search_text:{functionCode:"search_text",name:"搜索本地文本",description:`${Y}在指定文件或目录(递归)中搜索普通文本(不支持正则),返回所在文件、行号与该行内容。必须指定 path,不能搜索整个文件夹。`,parameters:{type:"object",required:["grantId","path","query"],properties:{grantId:W,path:X("搜索范围,可以是文件或目录。"),query:{type:"string",minLength:1,description:"要查找的文本。"},caseSensitive:{type:"boolean",description:"是否区分大小写,默认否。"},isRegex:{type:"boolean",description:"暂不支持正则,传 true 会返回 501。"},glob:{type:"string",description:"只搜索匹配该 glob 的文件,如 *.md。"},maxResults:{type:"integer",minimum:1,maximum:200,description:"最多返回条数,默认 200。"},contextLines:{type:"integer",minimum:0,maximum:3,description:"附带的上下文行数,默认 0。"}}}},apply_patch:{functionCode:"apply_patch",name:"修改本地文件",description:`${Y}以查找替换的方式修改 UTF-8 文本文件。每条修改的 oldText 必须在文件中唯一出现(或设置 replaceAll)。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path","expectedHash","edits"],properties:{grantId:W,path:X("要修改的文件。"),expectedHash:tt,edits:{type:"array",minItems:1,description:"按顺序应用的修改。",items:{type:"object",required:["oldText","newText"],properties:{oldText:{type:"string",minLength:1,description:"要替换的原文,需包含足够上下文以保证唯一。"},newText:{type:"string",description:"替换后的文本。"},replaceAll:{type:"boolean",description:"是否替换所有出现位置,默认否。"}}}}}}},write_file:{functionCode:"write_file",name:"写入本地文件",description:`${Y}新建文件,或整体覆盖已有文件(覆盖时必须提供 expectedHash)。修改已有文件优先使用 apply_patch。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path","content"],properties:{grantId:W,path:X("要写入的文件。"),content:{type:"string",description:"完整的文件内容(UTF-8)。"},expectedHash:tt,createDirectories:{type:"boolean",description:"父目录不存在时是否自动创建,默认否。"}}}},upload_file:{functionCode:"upload_file",name:"上传本地文件",description:`${Y}把本地文件夹中的文件上传到平台文件服务,返回 fileId、name、size 和 url。url 是文件访问地址,可直接用于后续推理或对话。下载回本地文件夹时使用 download_file,source.type 为 platformFile。单文件不超过 50 MB。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:W,path:X("要上传的文件。"),target:{type:"string",description:"上传目标,目前只支持 session(默认),其他值返回 501。"},mimeHint:{type:"string",description:"可选的 MIME 类型。"}}}},download_file:{functionCode:"download_file",name:"下载到本地文件夹",description:`${Y}把会话文件、平台文件或 https 地址保存到本地文件夹。source.type 为 url 时必须同时填写 source.url(完整地址),为 sessionFile 或 platformFile 时必须同时填写 source.fileId。不要只传 type。单文件不超过 50 MB。执行前需要用户确认。`,parameters:{type:"object",required:["grantId","destPath","source"],properties:{grantId:W,destPath:X("保存位置(文件路径)。"),source:{type:"object",required:["type"],description:"下载来源。type 为 url 时必填 url;type 为 sessionFile 或 platformFile 时必填 fileId。",properties:{type:{type:"string",enum:["sessionFile","platformFile","url"],description:"sessionFile:当前会话文件;platformFile:平台文件(upload_file 返回的 fileId);url:https 地址。"},fileId:{type:"string",description:"type 为 sessionFile 或 platformFile 时必填,不能只传 type。"},url:{type:"string",description:"type 为 url 时必填,填写完整 https 地址。不能只传 type。默认只允许 glodon.com 及其子域。"}}},overwrite:{type:"boolean",description:"目标已存在时是否覆盖,默认否。"},expectedHash:tt}}}},io="在已绑定的本地工程目录中运行已有 .py,路径相对该目录。不要用于云端工作区,不要传 shell 或代码,只能传 path 和 args。",no={functionCode:Si,name:"运行本地 Python 脚本",description:`${io}每次运行需用户单独确认,文件读写授权不能代替。确认后脚本可直接读写该目录并使用标准库,改动立即落盘。不能联网,不能在运行中安装包,也不能访问该目录以外的文件。第三方包写在工程根目录 sandbox-requirements.txt。结果打印到标准输出。code 为 0 只表示已结束,成功看 data.exitCode,超时看 data.timedOut。`,parameters:{type:"object",required:["grantId","path"],properties:{grantId:W,path:{type:"string",description:"要运行的脚本。必须是已存在、以 .py 结尾的相对路径,以 / 分隔,不能包含 .. 、盘符或绝对路径。"},args:{type:"array",maxItems:16,description:"传给脚本的参数,最多 16 个。每个参数单独一项,不能含空格、引号或 shell 语法,只能包含字母、数字、下划线以及 . / : @ = + - , 。",items:{type:"string",description:"一个脚本参数。"}},timeoutMs:{type:"integer",minimum:1e3,maximum:12e4,description:"超时毫秒数。默认 20000,最大 120000。到时脚本会被终止。"}}}},so=new TextEncoder;function Z(i,e,t,n){return i===void 0?e:Math.min(Math.max(Math.trunc(i),t),n)}const ro=(i,e)=>l(exports,null,function*(){const t=G(i.path,{allowRoot:!0});if((yield e.adapter.stat(t)).kind!=="directory")throw new m(p.BadRequest,"目标是文件,不是目录。");const s=Z(i.offset,0,0,Number.MAX_SAFE_INTEGER),r=Z(i.limit,Li,1,ki),o=yield e.adapter.listEntries(t,e.signal);o.sort((a,d)=>a.kind!==d.kind?a.kind==="directory"?-1:1:a.name<d.name?-1:a.name>d.name?1:0);const c=o.slice(s,s+r).map(a=>{const d=dn(t,a.name),h={name:a.name,path:d,kind:a.kind};return a.kind==="file"&&(h.size=a.size,h.lastModified=a.lastModified,e.sensitive.isSensitive(d)&&(h.sensitive=!0)),h});return{data:{path:t,entries:c,total:o.length,hasMore:s+c.length<o.length}}});function oo(i,e,t){return de(this,null,function*(){var c;const n=new TextDecoder(e),s=i.stream().getReader();let r="",o=!1;try{for(;;){C(t);const{done:a,value:d}=yield new ee(s.read());r+=a?n.decode():n.decode(d,{stream:!0});const h=r.split(`
|
|
369
|
+
`);r=(c=h.pop())!=null?c:"";for(const u of h)o=!0,yield u;if(a)break}}finally{s.releaseLock()}(r||!o)&&(yield r)})}const ao=(i,e)=>l(exports,null,function*(){var L,k;const t=G(i.path);be(e,t,"read");const n=yield Lt(e.adapter,t),s=yield e.adapter.readFile(t),r=(L=n.size)!=null?L:s.size;if(yield Zn(s))throw new m(p.BadRequest,"这是二进制文件,不能按文本读取。可以使用 stat_file 查看信息,或使用 upload_file 上传到会话。");const o=yield z(s.slice(0,3)),c=Gi(o)?"utf-8":(k=i.encoding)!=null?k:"utf-8",a=Z(i.startLine,1,1,Number.MAX_SAFE_INTEGER),d=i.endLine===void 0?Number.MAX_SAFE_INTEGER:Math.max(Math.trunc(i.endLine),a),h=Z(i.maxBytes,e.limits.maxReadBytes,1,e.limits.maxReadBytes),u=r<=e.limits.maxTransferBytes,f=[];let y=0,_=0,g=a-1,b=!1,A=!1;try{for(var K=V(oo(s,c,e.signal)),N,S,M;N=!(S=yield K.next()).done;N=!1){const O=S.value;_++;const P=O.endsWith("\r")?O.slice(0,-1):O;if(P!==O&&(A=!0),_<a||_>d||b){if(!u&&(b||_>d))break;continue}const ae=kt(P)+(f.length?1:0);if(y+ae>h){if(b=!0,f.length||(f.push(co(P,h)),g=_),!u)break;continue}f.push(P),y+=ae,g=_}}catch(S){M=[S]}finally{try{N&&(S=K.return)&&(yield S.call(K))}finally{if(M)throw M[0]}}const I={path:t,content:f.join(`
|
|
370
|
+
`),startLine:a,endLine:Math.max(g,a-1),size:r,encoding:c,lineEnding:A?"crlf":"lf"};return u&&(I.totalLines=_),r<=e.limits.maxWriteBytes&&(I.hash=yield ve(yield z(s))),{data:I,truncated:b||void 0}});function co(i,e){const t=so.encode(i);return t.byteLength<=e?i:new TextDecoder().decode(t.slice(0,e)).replace(/\uFFFD$/,"")}const lo=(i,e)=>l(exports,null,function*(){var r;const t=G(i.path),n=yield e.adapter.stat(t),s={path:t,kind:n.kind,sensitive:n.kind==="file"&&e.sensitive.isSensitive(t)};return n.kind==="file"&&(s.size=n.size,s.lastModified=n.lastModified,i.includeHash&&((r=n.size)!=null?r:0)<=e.limits.maxTransferBytes&&(s.hash=yield ve(yield z(yield e.adapter.readFile(t))))),{data:s}});function ho(i){return Pi.some(e=>qe(e,i))}function gn(i,e,t){return de(this,null,function*(){const n=[{path:e,depth:0}];let s=0;for(;n.length;){const r=n.shift();C(i.signal),++s%20===0&&(yield new ee(Ki()));const o=yield new ee(i.adapter.listEntries(r.path,i.signal));o.sort((c,a)=>c.name<a.name?-1:c.name>a.name?1:0);for(const c of o){const a=dn(r.path,c.name);if(c.kind==="directory"){r.depth+1<t&&!Ni.includes(c.name)&&n.push({path:a,depth:r.depth+1});continue}ho(c.name)||i.sensitive.match(a,"search")||(yield{path:a,relativePath:e?a.slice(e.length+1):a,name:c.name,size:c.size,lastModified:c.lastModified})}}})}function yn(i,e){return i.includes("/")?qe(i,e.relativePath):qe(i,e.name)}const uo=(i,e)=>l(exports,null,function*(){const t=G(i.path,{allowRoot:!0});if(!i.pattern.trim())throw new m(p.BadRequest,"参数 pattern 不能为空。");const n=i.pattern.replace(/\\/g,"/").replace(/^\.\//,"");if((yield e.adapter.stat(t)).kind!=="directory")throw new m(p.BadRequest,"参数 path 必须是目录。");const r=Z(i.maxDepth,Ri,1,vt),o=Z(i.maxResults,e.limits.maxSearchResults,1,e.limits.maxSearchResults),c=[];let a=!1;try{for(var d=V(gn(e,t,r)),h,u,f;h=!(u=yield d.next()).done;h=!1){const y=u.value;if(yn(n,y)){if(c.length>=o){a=!0;break}c.push({path:y.path,size:y.size,lastModified:y.lastModified})}}}catch(u){f=[u]}finally{try{h&&(u=d.return)&&(yield u.call(d))}finally{if(f)throw f[0]}}return{data:{matches:c},truncated:a||void 0}});function it(i,e){if(i.length<=$e)return i;const t=Math.max(0,Math.min(e-100,i.length-$e));return i.slice(t,t+$e)}const fo=(i,e)=>l(exports,null,function*(){var f;const t=G(i.path,{allowRoot:!0});if(!t&&!e.allowWorkspaceWideTextSearch)throw new m(p.BadRequest,"不支持在整个工作区内搜索文本,请把 path 缩小到具体的子目录或文件。");if(i.isRegex)throw new m(p.NotImplemented,"暂不支持正则搜索,请使用普通文本搜索。");if(!i.query)throw new m(p.BadRequest,"参数 query 不能为空。");const n=i.caseSensitive===!0,s=n?i.query:i.query.toLowerCase(),r=Z(i.contextLines,0,0,Oi),o=Z(i.maxResults,e.limits.maxSearchResults,1,e.limits.maxSearchResults),c=yield e.adapter.stat(t);let a;c.kind==="file"?(be(e,t,"search"),a=function(){return de(this,null,function*(){yield{path:t,relativePath:t,name:c.name,size:c.size}})}()):a=gn(e,t,vt);const d=[];let h=0,u=!1;e:try{for(var y=V(a),_,g,b;_=!(g=yield y.next()).done;_=!1){const A=g.value;if(i.glob&&!yn(i.glob,A)||((f=A.size)!=null?f:0)>Mi)continue;if(h>=Ci){u=!0;break}h++,h%20===0&&(yield Ki()),C(e.signal);const I=yield z(yield e.adapter.readFile(A.path));if(oe(I))continue;const L=new TextDecoder("utf-8").decode(I).split(/\r?\n/);for(let k=0;k<L.length;k++){const N=(n?L[k]:L[k].toLowerCase()).indexOf(s);if(N<0)continue;if(d.length>=o){u=!0;break e}const S={path:A.path,line:k+1,column:N+1,text:it(L[k],N)};r&&(S.before=L.slice(Math.max(0,k-r),k).map(M=>it(M,0)),S.after=L.slice(k+1,k+1+r).map(M=>it(M,0))),d.push(S)}}}catch(g){b=[g]}finally{try{_&&(g=y.return)&&(yield g.call(y))}finally{if(b)throw b[0]}}return{data:{matches:d,filesScanned:h},truncated:u||void 0}});function _i(){return new m(p.Forbidden,"下载地址不在允许范围内:只允许 https 协议且域名在白名单中的地址。",{reason:"url_not_allowed"})}const po=(i,e)=>l(exports,null,function*(){var u,f;const t=G(i.path);if(((u=i.target)!=null?u:"session")!=="session")throw new m(p.NotImplemented,"目前只支持上传到当前会话(target: session)。");be(e,t,"read");const s=yield Lt(e.adapter,t),r=(f=s.size)!=null?f:0;if(r>e.limits.maxTransferBytes)throw re(e.limits.maxTransferBytes);const o=At(t);yield e.requestApproval(t,{type:"upload",name:o,size:r,target:"session"}),e.progress({stage:"reading",loaded:0,total:r,path:t});const c=yield e.adapter.readFile(t);C(e.signal);const a=new File([c],o,{type:i.mimeHint||c.type||"application/octet-stream",lastModified:s.lastModified}),{fileId:d,url:h}=yield e.transfer.upload(a,e.context,({loaded:y,total:_})=>e.progress({stage:"uploading",loaded:y,total:_,path:t}));return C(e.signal),e.progress({stage:"done",loaded:r,total:r,path:t}),{data:{fileId:d,name:o,size:r,url:h}}});function mo(i){const e=i;if(!e||typeof e!="object")throw new m(p.BadRequest,"缺少参数 source。");if(e.type==="sessionFile"||e.type==="platformFile"){if(typeof e.fileId!="string"||!e.fileId)throw new m(p.BadRequest,"source.fileId 必须是非空字符串。");return{type:e.type,fileId:e.fileId}}if(e.type==="url"){if(typeof e.url!="string"||!e.url)throw new m(p.BadRequest,"source.url 必须是非空字符串。");return{type:"url",url:e.url}}throw new m(p.BadRequest,"source.type 必须是 sessionFile、platformFile 或 url 之一。")}function go(i){return i.type==="sessionFile"?"会话文件":i.type==="platformFile"?"平台文件":new URL(i.url).hostname}function yo(i,e,t,n,s){return de(this,null,function*(){const r=i.getReader();let o=0;try{for(;;){C(e.signal);const{done:c,value:a}=yield new ee(r.read());if(c)break;if(o+=a.byteLength,o>e.limits.maxTransferBytes)throw re(e.limits.maxTransferBytes,"下载内容");s.push(a),e.progress({stage:"downloading",loaded:o,total:n,path:t}),yield a}}finally{r.cancel().catch(()=>{})}})}const wo=(i,e)=>l(exports,null,function*(){var g,b,A;const t=G(i.destPath,{field:"destPath"}),n=mo(i.source);if(n.type==="url"&&!pt(n.url,e.downloadUrlAllowlist))throw _i();be(e,t,"write");const s=yield Be(e.adapter,t);if((s==null?void 0:s.kind)==="directory")throw new m(p.BadRequest,"目标是目录,不能写入文件。");if(s&&!i.overwrite)throw new m(p.Conflict,"目标文件已存在。如需覆盖,请设置 overwrite: true。");const r=()=>l(exports,null,function*(){if(!s||!i.expectedHash)return;const I=yield ve(yield z(yield e.adapter.readFile(t)));if(I!==i.expectedHash)throw new m(p.Conflict,"expectedHash 与目标文件当前内容不一致。",{currentHash:I})});yield r();const o=n.type==="url"?{url:n.url}:yield e.transfer.resolveDownload(n,e.context);if(o.size!==void 0&&o.size>e.limits.maxTransferBytes)throw re(e.limits.maxTransferBytes);const c={type:"download",source:{type:n.type,label:go(n)},name:(g=o.name)!=null?g:At(t),size:o.size,overwrite:!!s};yield e.requestApproval(t,c),yield r();let a;try{a=yield e.fetch(o.url,{headers:o.headers,credentials:"omit",redirect:"follow",signal:e.signal})}catch(I){throw C(e.signal),new m(p.Internal,"下载失败,无法连接到文件地址。")}if(n.type==="url"&&a.url&&!pt(a.url,e.downloadUrlAllowlist))throw(b=a.body)==null||b.cancel().catch(()=>{}),_i();if(!a.ok||!a.body)throw(A=a.body)==null||A.cancel().catch(()=>{}),new m(a.status===404?p.NotFound:p.Internal,`下载失败(HTTP ${a.status})。`);const d=Number(a.headers.get("content-length")),h=Number.isFinite(d)&&d>0?d:void 0;if(h!==void 0&&h>e.limits.maxTransferBytes)throw a.body.cancel().catch(()=>{}),re(e.limits.maxTransferBytes);const u=[];yield e.adapter.writeFile(t,yo(a.body,e,t,h,u),{signal:e.signal});const f=u.reduce((I,L)=>I+L.byteLength,0),y=new Uint8Array(f);let _=0;return u.forEach(I=>{y.set(I,_),_+=I.byteLength}),e.progress({stage:"done",loaded:f,total:f,path:t}),{data:{path:t,size:f,hash:yield ve(y)}}}),nt=new Uint8Array([239,187,191]);function ze(i,e){return new m(p.Conflict,e,{currentHash:i})}function jt(i,e){return l(this,null,function*(){var s;if(((s=(yield Lt(i.adapter,e)).size)!=null?s:0)>i.limits.maxWriteBytes)throw re(i.limits.maxWriteBytes,"目标文件");const n=yield z(yield i.adapter.readFile(e));return{bytes:n,hash:yield ve(n)}})}function wn(i,e,t){return l(this,null,function*(){const{hash:n}=yield jt(i,e);if(n!==t)throw ze(n,"文件在确认期间已被修改,本次写入已取消。请重新读取后再修改。")})}function vo(i,e){const t=new TextEncoder().encode(i);if(!e)return t;const n=new Uint8Array(nt.byteLength+t.byteLength);return n.set(nt,0),n.set(t,nt.byteLength),n}function _o(i,e){let t=0,n=i.indexOf(e);for(;n>=0;)t++,n=i.indexOf(e,n+e.length);return t}function bi(i,e){return!e||i.includes(`\r
|
|
4
371
|
`)?i:i.replace(/\n/g,`\r
|
|
5
|
-
`)}function
|
|
6
|
-
`);let a=n;i.edits.forEach((l,h)=>{if(typeof(l==null?void 0:l.oldText)!="string"||!l.oldText||typeof l.newText!="string")throw new p(w.BadRequest,`第 ${h+1} 条修改无效:oldText 必须是非空字符串,newText 必须是字符串。`);const f=lt(l.oldText,c),g=lt(l.newText,c),_=Ki(a,f);if(_===0)throw new p(w.Conflict,`第 ${h+1} 条修改的 oldText 在文件中不存在,请重新读取文件确认当前内容。`);if(_>1&&!l.replaceAll)throw new p(w.BadRequest,`第 ${h+1} 条修改的 oldText 在文件中出现了 ${_} 次,请补充上下文使其唯一,或设置 replaceAll。`);a=l.replaceAll?a.split(f).join(g):a.replace(f,()=>g)});const d=Xi(a,r);if(d.byteLength>e.limits.maxWriteBytes)throw ie(e.limits.maxWriteBytes,"修改后的内容");return yield e.requestApproval(t,{type:"text",before:n,after:a,created:!1}),yield Kt(e,t,o),{data:yield Jt(e,t,d)}}),Zi=(i,e)=>u(exports,null,function*(){const t=U(i.path);de(e,t,"write");const s=yield Ie(e.adapter,t);if((s==null?void 0:s.kind)==="directory")throw new p(w.BadRequest,"目标是目录,不能写入文件。");let o,r;if(s){const a=yield Je(e,t);if(r=a.hash,!i.expectedHash)throw Se(r,"目标文件已存在,覆盖前需要提供 expectedHash(可通过 read_file 或 stat_file 获取)。");if(i.expectedHash!==r)throw Se(r,"expectedHash 与文件当前内容不一致,请重新读取文件后再写入。");o=new TextDecoder("utf-8").decode(a.bytes)}else if(!i.createDirectories){const a=Ei(t),d=a?yield Ie(e.adapter,a):{kind:"directory"};if(!d)throw new p(w.NotFound,"父目录不存在,可设置 createDirectories 自动创建。");if(d.kind!=="directory")throw new p(w.BadRequest,"父路径不是目录。")}const n=new TextEncoder().encode(i.content);if(n.byteLength>e.limits.maxWriteBytes)throw ie(e.limits.maxWriteBytes,"写入内容");if(yield e.requestApproval(t,{type:"text",before:o,after:i.content,created:!s}),r)yield Kt(e,t,r);else if(yield Ie(e.adapter,t))throw new p(w.Conflict,"目标文件在确认期间被创建,本次写入已取消。请重新检查后再写入。");const c=yield Jt(e,t,n,i.createDirectories);return{data:I(v({},c),{created:!s})}});function O(i,e){throw new p(w.BadRequest,i?`参数 ${i} ${e}`:`参数${e}`)}function es(i,e){return typeof i!="string"?i:(e.type==="integer"||e.type==="number")&&/^-?\d+(\.\d+)?$/.test(i.trim())?Number(i):e.type==="boolean"&&(i==="true"||i==="false")?i==="true":i}function De(i,e,t){switch(i=es(i,e),e.type){case"string":typeof i!="string"&&O(t,"必须是字符串。"),e.minLength!==void 0&&i.length<e.minLength&&O(t,"不能为空。");break;case"integer":(typeof i!="number"||!Number.isInteger(i))&&O(t,"必须是整数。");break;case"number":(typeof i!="number"||!Number.isFinite(i))&&O(t,"必须是数字。");break;case"boolean":typeof i!="boolean"&&O(t,"必须是布尔值。");break;case"array":if(Array.isArray(i)||O(t,"必须是数组。"),e.minItems!==void 0&&i.length<e.minItems&&O(t,"不能为空。"),e.items){const s=e.items;return i.map((o,r)=>De(o,s,`${t}[${r}]`))}break;case"object":return Zt(i,e,t)}return e.enum&&!e.enum.includes(i)&&O(t,`必须是 ${e.enum.join("、")} 之一。`),typeof i=="number"&&(e.minimum!==void 0&&i<e.minimum&&O(t,`不能小于 ${e.minimum}。`),e.maximum!==void 0&&i>e.maximum&&O(t,`不能大于 ${e.maximum}。`)),i}function Zt(i,e,t){var r,n;(!i||typeof i!="object"||Array.isArray(i))&&O(t,"必须是对象。");const s=i,o={};for(const c of(r=e.required)!=null?r:[])(s[c]===void 0||s[c]===null)&&O(t?`${t}.${c}`:c,"是必填项。");for(const[c,a]of Object.entries((n=e.properties)!=null?n:{})){if(s[c]===void 0||s[c]===null)continue;const d=t?`${t}.${c}`:c;o[c]=a.oneOf?(De(s[c],I(v({},a),{oneOf:void 0}),d),s[c]):De(s[c],a,d)}return o}function ei(i,e){return Zt(i,e,"")}const ts={list_directory:Oi,read_file:Pi,stat_file:Bi,search_files:Hi,search_text:$i,apply_patch:Ji,write_file:Zi,upload_file:Wi,download_file:Qi};class is{constructor(e,t){y(this,"remaining");y(this,"startedAt",0);y(this,"handle");this.onTimeout=t,this.remaining=e}resume(){this.handle!==void 0||this.remaining<=0||(this.startedAt=Date.now(),this.handle=setTimeout(()=>{this.handle=void 0,this.remaining=0,this.onTimeout()},this.remaining))}pause(){this.handle!==void 0&&(clearTimeout(this.handle),this.handle=void 0,this.remaining-=Date.now()-this.startedAt)}clear(){this.pause(),this.remaining=0}}function ss(i,e){return qt.includes(e)?i.limits.transferTimeoutMs:Bt.includes(e)?i.limits.searchTimeoutMs:i.limits.toolTimeoutMs}function ns(i){if(typeof i!="string")return i;try{return JSON.parse(i)}catch(e){throw new p(w.BadRequest,"参数不是合法的 JSON 对象。")}}function rs(i){if(!i||typeof i!="object"||Array.isArray(i))return;const e=i;return(e.grantId===void 0||e.grantId===null||e.grantId==="")&&(e.grantId=Q),e.grantId}function ti(i){return new Promise((e,t)=>{i.aborted&&t(N()),i.addEventListener("abort",()=>t(N()),{once:!0})})}function as(i){return v({code:i.code,message:i.message},i.data?{data:i.data}:{})}function os(i,e,t,s,o){return u(this,null,function*(){var _,m,b,T,S,E,C,le;const r={requestId:o.requestId||ae.v4(),applicationId:o.applicationId||i.applicationId,sessionId:o.sessionId||"",pluginCode:o.pluginCode,functionCode:e,signal:o.signal},n={requestId:r.requestId,sessionId:r.sessionId,functionCode:e},c=new AbortController;let a=!1;const d=new is(ss(i,e),()=>{a=!0,c.abort()}),l=()=>c.abort();(_=r.signal)==null||_.addEventListener("abort",l,{once:!0}),(m=r.signal)!=null&&m.aborted&&c.abort();let h=null,f,g=!1;try{const x=ns(t),L=rs(x);L!=null&&$t(L);const F=ei(x,Ge[e].parameters),R=(b=F.path)!=null?b:F.destPath;if(typeof R=="string"&&(n.path=R),yield i.ready,c.signal.aborted)throw N();const V=i.adapter;if(!V)throw Ye();if(h=i.acquireSlot(),!h)throw new p(w.TooManyRequests,"同时进行的文件操作过多,请稍后重试。");f=i.track(c),g=!0,i.emit("tool:start",v({},n)),d.resume();const ge={adapter:V,workspaceName:(T=i.displayName)!=null?T:V.displayName,limits:i.limits,sensitive:i.sensitive,downloadUrlAllowlist:i.downloadUrlAllowlist,allowWorkspaceWideTextSearch:i.allowWorkspaceWideTextSearch,transfer:i.transfer,fetch:i.fetch,context:I(v({},r),{signal:c.signal}),signal:c.signal,requestApproval:(Re,ui)=>cs(i,{approvalPath:Re,preview:ui,context:r,functionCode:e,signal:c.signal,timer:d,base:n}),progress:Re=>i.emit("tool:progress",v(v({},n),Re))},me=yield Promise.race([ts[e](F,ge),ti(c.signal)]),Ce={code:w.Ok,message:"ok",data:me.data};me.truncated&&(Ce.truncated=!0),(S=me.warnings)!=null&&S.length&&(Ce.warnings=me.warnings),i.emit("tool:finish",I(v({},n),{code:w.Ok})),s(Ce)}catch(x){let L=Le(x);a?L=new p(w.Timeout,"操作超时,已中止。"):c.signal.aborted&&L.code!==w.Cancelled&&(L=N()),((E=L.data)==null?void 0:E.reason)==="workspace_not_granted"&&g&&i.handlePermissionLost(),L.code===w.Cancelled?i.emit("tool:cancelled",v({},n)):i.emit("tool:error",I(v({},n),{code:L.code,message:L.message,reason:(C=L.data)==null?void 0:C.reason})),s(as(L))}finally{d.clear(),(le=r.signal)==null||le.removeEventListener("abort",l),h==null||h(),f==null||f()}})}function cs(i,e){return u(this,null,function*(){var c;const t=i.getApprovalHandler();if(!t)throw new p(w.Forbidden,"当前环境未提供操作确认能力,无法执行写入或传输操作。",{reason:"approval_unavailable"});if(e.signal.aborted)throw N();const s=new AbortController,o=()=>s.abort();e.signal.addEventListener("abort",o,{once:!0});const r={id:ae.v4(),requestId:e.context.requestId,sessionId:e.context.sessionId,functionCode:e.functionCode,path:e.approvalPath,workspaceName:(c=i.displayName)!=null?c:"",preview:e.preview,signal:s.signal};e.timer.pause(),i.emit("tool:approval-required",I(v({},e.base),{path:e.approvalPath,approvalId:r.id}));let n;try{const a=yield Promise.race([Promise.resolve().then(()=>t(r)),ti(s.signal),new Promise(d=>{n=setTimeout(()=>d(!1),i.limits.approvalTimeoutMs)})]);if(e.signal.aborted)throw N();if(a!==!0)throw new p(w.Forbidden,"用户拒绝了本次操作。",{reason:"user_rejected"})}catch(a){throw a instanceof p?a:new p(w.Forbidden,"操作确认失败,已取消本次操作。",{reason:"user_rejected"})}finally{clearTimeout(n),e.signal.removeEventListener("abort",o),s.abort(),e.timer.resume()}})}function ii({pluginCode:i,workspace:e}){const t={};return ze.forEach(s=>{t[s]=(o,r,n)=>{let c=!1;os(e,s,o,d=>{if(!c){c=!0;try{r(d)}catch(l){console.error("[LocalFiles] callback failed",l)}}},I(v({},n),{pluginCode:i}))}}),{[i]:t}}function P(i,e=i){return new DOMException(e,i)}function Ze(i){return se(this,null,function*(){typeof i=="string"?yield new TextEncoder().encode(i):i instanceof Uint8Array?yield i:yield*ot(i)})}const Ee="glodon-workspace";function ds(i){let e=i;if(typeof e=="string")try{e=JSON.parse(e)}catch(s){return}if(!e||typeof e!="object")return;const t=e;if(t.channel===Ee)return t}function ls(){var e;const i=(e=globalThis.chrome)==null?void 0:e.webview;if(!(!i||typeof i.postMessage!="function"||typeof i.addEventListener!="function"))return i}const hs=3e4;function us(i){let e="";for(let s=0;s<i.length;s+=32768)e+=String.fromCharCode(...i.subarray(s,s+32768));return btoa(e)}function fs(i){const e=atob(i),t=new Uint8Array(e.length);for(let s=0;s<e.length;s++)t[s]=e.charCodeAt(s);return t}function ht(i,e){const t=i&&typeof i=="object"?i:{},s=t.kind==="directory"?"directory":"file",o={name:typeof t.name=="string"&&t.name?t.name:e,kind:s};return s==="file"&&typeof t.size=="number"&&(o.size=t.size),typeof t.lastModified=="number"&&(o.lastModified=t.lastModified),o}class si{constructor(e,t=""){y(this,"displayName");y(this,"seq",0);y(this,"pending",new Map);this.view=e,this.displayName=t}settle(e){const t=this.pending.get(e.id);if(t){if(clearTimeout(t.timer),this.pending.delete(e.id),e.ok===!1){t.reject(P(e.name||"NotAllowedError",e.message||e.name||"NotAllowedError"));return}t.resolve(e)}}call(e,t,s,o=hs){M(s);const r=`host-${++this.seq}`;return new Promise((n,c)=>{const a=setTimeout(()=>{this.pending.delete(r),c(P("AbortError"))},o),d=()=>{clearTimeout(a),this.pending.delete(r),c(P("AbortError"))};s==null||s.addEventListener("abort",d,{once:!0}),this.pending.set(r,{resolve:l=>{s==null||s.removeEventListener("abort",d),n(l)},reject:c,timer:a}),this.view.postMessage(v({channel:Ee,id:r,op:e},t))})}stat(e){return u(this,null,function*(){const t=yield this.call("stat",{path:e});return ht(t.entry,e.split("/").pop()||this.displayName)})}listEntries(e,t){return u(this,null,function*(){const s=yield this.call("list",{path:e},t);return(Array.isArray(s.entries)?s.entries:[]).map(r=>ht(r,""))})}readFile(e){return u(this,null,function*(){var o;const t=yield this.call("read",{path:e}),s=fs((o=t.contentBase64)!=null?o:"");return new Blob([s])})}runPython(e,t,s,o){return u(this,null,function*(){var n,c;const r=yield this.call("run_python",{path:e,args:t,timeoutMs:s},o,s+15e3);return{exitCode:typeof r.exitCode=="number"?r.exitCode:1,timedOut:r.timedOut===!0,stdout:(n=r.stdout)!=null?n:"",stderr:(c=r.stderr)!=null?c:""}})}writeFile(o,r){return u(this,arguments,function*(e,t,s={}){const n=[];try{for(var l=Y(Ze(t)),h,f,g;h=!(f=yield l.next()).done;h=!1){const _=f.value;M(s.signal),n.push(_)}}catch(f){g=[f]}finally{try{h&&(f=l.return)&&(yield f.call(l))}finally{if(g)throw g[0]}}const c=n.reduce((_,m)=>_+m.byteLength,0),a=new Uint8Array(c);let d=0;n.forEach(_=>{a.set(_,d),d+=_.byteLength}),yield this.call("write",{path:e,contentBase64:us(a),createDirectories:s.createDirectories===!0},s.signal)})}}const ps=/^[\p{L}\p{N}_./:@=+\-,]+$/u,gs={type:"object",required:["grantId","path"],properties:{grantId:{type:"string",enum:[Q]},path:{type:"string",minLength:1},args:{type:"array",items:{type:"string",minLength:1}},timeoutMs:{type:"integer",minimum:1e3,maximum:12e4}}};function ms(i){const e=i instanceof DOMException?i.name:"",t=i instanceof Error?i.message:"";switch(e){case"NotFoundError":return new p(w.NotFound,"脚本不存在。");case"TypeMismatchError":return new p(w.BadRequest,"只能运行 .py 文件。");case"SecurityError":return new p(w.BadRequest,"脚本路径不合法。");case"AbortError":return t.includes("已有")?new p(w.TooManyRequests,"已有一个脚本在沙箱里运行。"):new p(w.Timeout,"脚本运行超时,已中止。");default:return new p(w.NotImplemented,"当前环境不能运行本地脚本。")}}function ys(i,e,t,s,o){return u(this,null,function*(){if(!e)throw new p(w.Forbidden,"当前环境未提供脚本运行确认,无法执行。",{reason:"approval_unavailable"});if(o.aborted)throw N();const r=new AbortController,n=()=>r.abort();o.addEventListener("abort",n,{once:!0});let c;try{const a=yield Promise.race([Promise.resolve().then(()=>{var d;return e({requestId:s.requestId,sessionId:s.sessionId,path:t.path,args:t.args,workspaceName:(d=i.displayName)!=null?d:"",signal:r.signal})}),new Promise(d=>{c=setTimeout(()=>d(!1),i.limits.approvalTimeoutMs)})]);if(o.aborted)throw N();if(a!==!0)throw new p(w.Forbidden,"用户拒绝了本次脚本运行。",{reason:"user_rejected"})}catch(a){throw a instanceof p?a:new p(w.Forbidden,"脚本运行确认失败,已取消本次运行。",{reason:"user_rejected"})}finally{clearTimeout(c),o.removeEventListener("abort",n),r.abort()}})}function ws(i,e,t,s,o){return u(this,null,function*(){var c,a,d,l;const r=new AbortController,n=()=>r.abort();(c=s.signal)==null||c.addEventListener("abort",n);try{const h=typeof e=="string"?JSON.parse(e):e;if(h&&typeof h=="object"&&!Array.isArray(h)){const E=h;(E.grantId===void 0||E.grantId===null||E.grantId==="")&&(E.grantId=Q)}const f=ei(h,gs);$t(f.grantId);const g=U(f.path);if(!g.toLowerCase().endsWith(".py"))throw new p(w.BadRequest,"只能运行工程内已有的 .py 文件。");const _=(a=f.args)!=null?a:[];if(_.length>Tt||_.some(E=>!ps.test(E)))throw new p(w.BadRequest,"脚本参数不合法。每个参数单独填写,不能包含空格或 shell 语法。");const m=i.sensitive.match(g,"read");if(m)throw new p(w.Forbidden,"该脚本被列为敏感文件,不能运行。",{reason:"sensitive_file",ruleId:m.id});if(yield i.ready,r.signal.aborted)throw N();const b=i.adapter;if(!b)throw Ye();if(!(b instanceof si))throw new p(w.NotImplemented,"当前环境不能运行本地脚本。");yield ys(i,o,{path:g,args:_},s,r.signal);const T=yield b.runPython(g,_,(d=f.timeoutMs)!=null?d:Et,r.signal);i.notifyFilesChanged();const S={code:w.Ok,message:"ok",data:T};t(S)}catch(h){const f=r.signal.aborted?N():h instanceof SyntaxError?new p(w.BadRequest,"参数不是合法的 JSON 对象。"):h instanceof p?h:ms(h),g=Le(f);t({code:g.code,message:g.message,data:g.data})}finally{(l=s.signal)==null||l.removeEventListener("abort",n)}})}function vs({pluginCode:i,workspace:e,onApprovalRequired:t}){const s=(o,r,n)=>{var d,l,h;let c=!1;ws(e,o,f=>{if(!c){c=!0;try{r(f)}catch(g){console.error("[LocalPython] callback failed",g)}}},{requestId:(d=n==null?void 0:n.requestId)!=null?d:ae.v4(),applicationId:(l=n==null?void 0:n.applicationId)!=null?l:e.applicationId,sessionId:(h=n==null?void 0:n.sessionId)!=null?h:"",pluginCode:i,functionCode:oe,signal:n==null?void 0:n.signal},t)};return{[i]:{[oe]:s}}}const _s=new $("[Config] ");var ni=(i=>(i.dev="https://aiot-dev.glodon.com/api/cvforcepd",i.test="https://aiot-dev.glodon.com/api/cvforce",i.prod="https://copilot.glodon.com/api/cvforce",i.local="http://localhost:3000/api/cvforcepd",i))(ni||{});exports.configuration={debug:!1,env:"prod",apiRoot:"https://copilot.glodon.com/api/cvforce",applicationId:"",plugins:{},businessPlugins:{},builtinPlugins:void 0,mcp:void 0,loadRelatedQuesions:!0,stream:!1};let q,W,H;const Be=new Set;function ut(i){q!==i&&(q=i,W=void 0,H=void 0,Be.clear())}function bs(){if(!W)return;const{pluginCode:i,table:e}=W,t=exports.configuration.plugins[i],s=e[i];if(!(!t||t.list_directory!==s.list_directory))return i}function Is(){if(!H)return;const{pluginCode:i,table:e}=H,t=exports.configuration.plugins[i],s=e[i];if(!(!t||t[oe]!==s[oe]))return i}function ri(i,e){return(i==null?void 0:i.pluginCode)||At[e]}function As(i,e,t){return(i==null?void 0:i.pluginCode)||t||St[e]}function Ss(){var c,a,d;const i=(c=exports.configuration.businessPlugins)!=null?c:{},e=(a=exports.configuration.builtinPlugins)==null?void 0:a.localFiles,t=(d=exports.configuration.builtinPlugins)==null?void 0:d.localPython,s=[],o=v({},i);let r,n=!1;if(e!=null&&e.enabled&&q&&(r=ri(e,exports.configuration.env),r?i[r]?s.push(`[LocalFiles] 业务插件中已存在 pluginCode「${r}」,已保留业务插件,内置文件工具未注册。`):(((W==null?void 0:W.workspace)!==q||W.pluginCode!==r)&&(W={workspace:q,pluginCode:r,table:ii({pluginCode:r,workspace:q})}),o[r]=W.table[r],n=!0):s.push(`[LocalFiles] 当前环境(env: ${exports.configuration.env})没有默认的内置工具插件编码,请配置 builtinPlugins.localFiles.pluginCode。内置文件工具未注册。`)),t!=null&&t.enabled){const l=As(t,exports.configuration.env,r);if(!q)s.push("[LocalPython] 运行脚本依赖已启用的本地工作区。内置脚本工具未注册。");else if(!l)s.push(`[LocalPython] 当前环境(env: ${exports.configuration.env})没有默认的内置工具插件编码,请配置 builtinPlugins.localPython.pluginCode,或与文件工具使用同一个 pluginCode。内置脚本工具未注册。`);else if(i[l])s.push(`[LocalPython] pluginCode「${l}」已被业务插件占用,已保留业务插件,内置脚本工具未注册。`);else if(o[l]&&!(n&&l===r))s.push(`[LocalPython] pluginCode「${l}」已被占用,已保留原插件,内置脚本工具未注册。`);else{((H==null?void 0:H.workspace)!==q||H.pluginCode!==l||H.approve!==t.onApprovalRequired)&&(H={workspace:q,pluginCode:l,approve:t.onApprovalRequired,table:vs({pluginCode:l,workspace:q,onApprovalRequired:t.onApprovalRequired})});const h=H.table[l];o[l]=n&&l===r?v(v({},o[l]),h):h}}return exports.configuration.plugins=o,s}function qe(){return Ss().filter(i=>!Be.has(i)).map(i=>(Be.add(i),console.error(i),new Error(i)))}function He(i){var e,t,s;$.debug=(i==null?void 0:i.debug)||!1,exports.configuration=I(v(v({},exports.configuration),i),{apiRoot:(i==null?void 0:i.apiRoot)||exports.configuration.apiRoot||(i!=null&&i.env?ni[i.env||"prod"]:exports.configuration.apiRoot),businessPlugins:(t=(e=i==null?void 0:i.plugins)!=null?e:exports.configuration.businessPlugins)!=null?t:{},builtinPlugins:(s=i==null?void 0:i.builtinPlugins)!=null?s:exports.configuration.builtinPlugins}),qe(),$.debug&&_s.log("updated",exports.configuration)}const Te=i=>JSON.parse(mi.decode(i.split(".")[1])),Es=i=>{const e=Te(i).exp;return new Date().valueOf()/1e3>=e},Ts=i=>i==null?void 0:i.replace(/[\r\n]+/gm,""),Ls=i=>i.replace(/\\|\\/g,""),Cs=(i,e,t,s)=>{if(i!==!0)return null;const o=(e==null?void 0:e.includeUserQuestion)===!0,n=(e==null?void 0:e.includeAiAnswer)===!0||!o,c=[];return o&&c.push(`问题:${s}`),n&&c.push(`回答:${t}`),c.join(`
|
|
7
|
-
`)};function ai(i,e,t){return new A.CVForceApi(oi(i,"/data/v1",e,t),ci(t))}function Rs(i,e,t){return new A.AIShopApi(oi(i,"/aishop",e,t),ci(t))}function oi(i,e,t,s){const o=n=>{var c;return t&&(Es(t)&&s(403,"aiotToken is timeout"),n.headers=(c=n.headers)!=null?c:{},n.headers=I(v({},n.headers),{Authorization:t?`Bearer ${t}`:""})),n};function r(n,c=!0){const a=`${i}${n}`,d=yi.create({baseURL:a});return c&&d.interceptors.request.use(o),d}return r(e)}function ci(i){return{onHttpStatusError:(s,o)=>{s===401&&i(s,"aiotToken is invalid")},onAppStatusError:(s,o)=>{s!==10001&&s!==10215&&i(s,o)}}}let J;function ks(i){J==null||J(),J=void 0;const e=ls();if(!e)return()=>{};const t=new si(e),s=r=>{const n=ds(r.data);if(n){if(n.type==="workspace"){const c=n.granted===!0,a=typeof n.displayName=="string"?n.displayName:"";c?(t.displayName=a||"工程目录",(i.status!=="granted"||i.displayName!==t.displayName)&&i.attachAdapter(t,t.displayName)):i.status==="granted"&&i.clear();return}if(n.type==="fs-changed"){const c=Array.isArray(n.paths)?n.paths.filter(a=>typeof a=="string"):[];i.notifyFilesChanged(c);return}typeof n.id=="string"&&t.settle({channel:Ee,id:n.id,ok:n.ok!==!1,name:typeof n.name=="string"?n.name:void 0,entries:n.entries,entry:n.entry,contentBase64:typeof n.contentBase64=="string"?n.contentBase64:void 0,exitCode:typeof n.exitCode=="number"?n.exitCode:void 0,timedOut:n.timedOut===!0,stdout:typeof n.stdout=="string"?n.stdout:void 0,stderr:typeof n.stderr=="string"?n.stderr:void 0,message:typeof n.message=="string"?n.message:void 0})}};e.addEventListener("message",s),e.postMessage({channel:Ee,type:"hello"});const o=()=>{e.removeEventListener("message",s),J===o&&(J=void 0)};return J=o,o}const Z=new $("[EventBus] ");class et{constructor(e=!1){y(this,"eventListenerMap",{});e&&Z.disable()}getEventListenerMap(){return v({},this.eventListenerMap)}on(e,t,s=!1){this.eventListenerMap[e]||(this.eventListenerMap[e]=[]),s?this.eventListenerMap[e].push({fn:t,once:!0}):this.eventListenerMap[e].push(t),Z.log(`add event ${e} listener ${s?", call once":""}`)}once(e,t){this.on(e,t,!0)}off(e,t){if(this.eventListenerMap[e]){const s=this.eventListenerMap[e].findIndex(o=>{if(typeof o=="function"&&t===o)return!0;if(o=o,o.fn===t)return!0});s<0?Z.log(`event ${e} listener ${t.name} is not found`):(this.eventListenerMap[e].splice(s,1),Z.log(`remove event ${e} listener`))}else Z.log(`event ${e} listeners is empty`)}emit(e,t){if(!this.eventListenerMap[e]){Z.log(`event ${e} listeners is empty`);return}const s=[];for(let o=0;o<this.eventListenerMap[e].length;o++){const r=this.eventListenerMap[e][o];typeof r=="function"?r(t):s.push(r)}s.forEach(o=>{o&&(o.fn(t),this.off(e,o.fn))}),Z.log(`event ${e} is fired, has ${this.eventListenerMap[e].length} listeners`)}removeAllListeners(){this.eventListenerMap={}}}function Oe(i,e){return!!i&&typeof i=="object"&&i.name===e}class di{constructor(e){this.root=e}get displayName(){return this.root.name}resolveDirectory(e,t=!1){return u(this,null,function*(){let s=this.root;for(const o of e)s=yield s.getDirectoryHandle(o,{create:t});return s})}resolveFile(e){return u(this,null,function*(){const t=G(e),s=t.pop();if(!s)throw P("TypeMismatchError");return(yield this.resolveDirectory(t)).getFileHandle(s)})}stat(e){return u(this,null,function*(){const t=G(e),s=t.pop();if(!s)return{name:this.root.name,kind:"directory"};const o=yield this.resolveDirectory(t);try{const r=yield(yield o.getFileHandle(s)).getFile();return{name:s,kind:"file",size:r.size,lastModified:r.lastModified}}catch(r){if(!Oe(r,"TypeMismatchError"))throw r;return yield o.getDirectoryHandle(s),{name:s,kind:"directory"}}})}listEntries(e,t){return u(this,null,function*(){const s=yield this.resolveDirectory(G(e)),o=[];try{for(var r=Y(s.values()),n,c,a;n=!(c=yield r.next()).done;n=!1){const d=c.value;if(M(t),d.kind==="directory")o.push({name:d.name,kind:"directory"});else try{const l=yield d.getFile();o.push({name:d.name,kind:"file",size:l.size,lastModified:l.lastModified})}catch(l){if(Oe(l,"NotAllowedError"))throw l;o.push({name:d.name,kind:"file"})}}}catch(c){a=[c]}finally{try{n&&(c=r.return)&&(yield c.call(r))}finally{if(a)throw a[0]}}return o})}readFile(e){return u(this,null,function*(){return(yield this.resolveFile(e)).getFile()})}writeFile(o,r){return u(this,arguments,function*(e,t,s={}){const n=G(e),c=n.pop();if(!c)throw P("TypeMismatchError");const a=yield this.resolveDirectory(n,s.createDirectories);let d=!0;try{yield a.getFileHandle(c)}catch(b){if(!Oe(b,"NotFoundError"))throw b;d=!1}const l=yield a.getFileHandle(c,{create:!0});let h;try{h=yield l.createWritable();try{for(var f=Y(Ze(t)),g,_,m;g=!(_=yield f.next()).done;g=!1){const b=_.value;M(s.signal),yield h.write(b)}}catch(_){m=[_]}finally{try{g&&(_=f.return)&&(yield _.call(f))}finally{if(m)throw m[0]}}M(s.signal),yield h.close()}catch(b){throw yield h==null?void 0:h.abort().catch(()=>{}),d||(yield a.removeEntry(c).catch(()=>{})),b}})}}function Ms(){if(typeof window=="undefined")return;const i=window.showDirectoryPicker;return typeof i=="function"?i.bind(window):void 0}function xs(i={}){const e=v({},_e);return Object.keys(_e).forEach(t=>{const s=i[t];typeof s=="number"&&Number.isFinite(s)&&s>0&&(e[t]=Math.min(s,_e[t]))}),e}function ne(){return new p(w.Internal,"平台文件服务请求失败,请稍后重试。")}function tt(i,e=()=>{}){const t=()=>{const r=i();if(!r)throw ne();return r},s=()=>{const r=e();if(!r)throw ne();return r};return{upload(r,n,c){return u(this,null,function*(){if(!n.sessionId)throw new p(w.BadRequest,"当前没有可用的会话,无法上传文件。");try{c==null||c({loaded:0,total:r.size});const a=yield s().postFile(r,(d,l)=>c==null?void 0:c({loaded:d,total:l}));if(!(a!=null&&a.id)||!a.url)throw ne();return c==null||c({loaded:r.size,total:r.size}),{fileId:a.id,url:a.url}}catch(a){throw a instanceof p?a:ne()}})},resolveDownload(r,n){return u(this,null,function*(){if(r.type==="platformFile")return Fs(s(),r.fileId);if(!n.sessionId)throw new p(w.BadRequest,"当前没有可用的会话,无法下载会话文件。");let c;try{c=yield t().getApplicationIdSessionFile(n.applicationId,n.sessionId,r.fileId)}catch(a){throw ne()}if(!(c!=null&&c.url))throw new p(w.NotFound,"会话文件不存在或暂不可下载。");return{url:c.url,name:c.name,size:c.size}})}}}function Fs(i,e){return u(this,null,function*(){let t;try{t=yield i.getFile(e)}catch(o){throw ne()}if(!(t!=null&&t.url))throw new p(w.NotFound,"平台文件不存在或暂不可下载。");let s;try{s=new URL(t.url)}catch(o){throw new p(w.Internal,"平台返回的下载地址无效。")}if(s.protocol!=="https:")throw new p(w.Internal,"平台返回的下载地址无效。");return{url:t.url,size:t.bytes}})}const Os="glodon-aiot-local-workspace",Ne="kv";function it(){const i=new Map;return{get(t){return u(this,null,function*(){return i.get(t)})},set(t,s){return u(this,null,function*(){i.set(t,s)})},delete(t){return u(this,null,function*(){i.delete(t)})}}}function Ns(i){return new Promise((e,t)=>{i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)})}function li(i=Os){if(typeof indexedDB=="undefined")return it();let e;const t=()=>(e||(e=new Promise((r,n)=>{const c=indexedDB.open(i,1);c.onupgradeneeded=()=>{c.result.createObjectStore(Ne)},c.onsuccess=()=>r(c.result),c.onerror=()=>{e=void 0,n(c.error)}})),e),s=(r,n)=>u(this,null,function*(){const c=yield t();return Ns(n(c.transaction(Ne,r).objectStore(Ne)))});return{get(r){return u(this,null,function*(){return yield s("readonly",n=>n.get(r))})},set(r,n){return u(this,null,function*(){yield s("readwrite",c=>c.put(n,r))})},delete(r){return u(this,null,function*(){yield s("readwrite",n=>n.delete(r))})}}}function ft(i){if(i!=null&&i.length&&!i.some(e=>!e||e==="."||e===".."||e.includes("/")||e.includes("\\")))return i.length===1?"":i.slice(0,-1).join("/")}function Ps(i,e){const t=globalThis.FileSystemObserver;if(typeof t!="function")return()=>{};let s;try{s=new t(o=>{const r=new Set;for(const n of o){if(n.type==="errored"){e();return}const c=ft(n.relativePathComponents),a=ft(n.relativePathMovedFrom);if(c===void 0&&a===void 0){e();return}c!==void 0&&r.add(c),a!==void 0&&r.add(a)}r.size&&e([...r])})}catch(o){return()=>{}}return s.observe(i,{recursive:!0}).catch(()=>s.disconnect()),()=>s.disconnect()}const ve={mode:"readwrite"};function Ds(i){const e=i.replace(/\\/g,"/").trim().replace(/^\.\/+/,"").replace(/\/+$/,"");if(!e||e===".")return"";if(e.startsWith("/")||e.includes(":")||e.includes("\0"))return;const t=e.split("/");if(!t.some(s=>!s||s==="."||s===".."))return t.join("/")}function Bs(i){return!!i&&typeof i=="object"&&i.name==="AbortError"}class hi{constructor(e){y(this,"applicationId");y(this,"limits");y(this,"sensitive");y(this,"downloadUrlAllowlist");y(this,"allowWorkspaceWideTextSearch");y(this,"transfer");y(this,"fetch");y(this,"store");y(this,"picker");y(this,"event",new et(!0));y(this,"_status");y(this,"_displayName");y(this,"_adapter",null);y(this,"pendingHandle",null);y(this,"approvalHandler");y(this,"activeCalls",0);y(this,"inflight",new Set);y(this,"_ready",Promise.resolve());y(this,"stopWatching",()=>{});y(this,"pendingChangePaths",new Set);y(this,"changeTimer");y(this,"refreshAllVisible",!1);var r,n,c,a,d,l,h,f,g;const t=(r=e.config)!=null?r:{};this.applicationId=e.applicationId,this.store=(n=e.store)!=null?n:it(),this.picker=e.picker===null?void 0:(c=e.picker)!=null?c:Ms(),this.limits=xs(t.limits),this.sensitive=new jt(t.sensitiveRulesAppend),this.downloadUrlAllowlist=Ke(t.downloadUrlAllowlistAppend),this.allowWorkspaceWideTextSearch=!!t.allowWorkspaceWideTextSearch,this.approvalHandler=t.onApprovalRequired;const s=(a=e.transfer)!=null?a:tt(()=>{});this.transfer={upload:(l=(d=t.transfer)==null?void 0:d.upload)!=null?l:s.upload,resolveDownload:(f=(h=t.transfer)==null?void 0:h.resolveDownload)!=null?f:s.resolveDownload};const o=(g=e.fetch)!=null?g:typeof fetch=="function"?fetch:void 0;this.fetch=o?o.bind(globalThis):()=>Promise.reject(new Error("fetch is not available")),this._status=this.picker?"none":"unsupported"}get status(){return this._status}get displayName(){return this._displayName}get isSupported(){return!!this.picker}get ready(){return this._ready}get adapter(){return this._status==="granted"?this._adapter:null}get handleKey(){return`workspace:${this.applicationId}`}get disclosureKey(){return`disclosure:${this.applicationId}`}setStatus(e,t=this._displayName){e===this._status&&t===this._displayName||(this._status=e,this._displayName=t,this.emit("workspace:changed",{status:e,displayName:t}))}attachHandle(e){this.cancelFilesChanged(),this.pendingHandle=e,this._adapter=new di(e),this.setStatus("granted",e.name),this.unwatchDirectory(),this.stopWatching=Ps(e,t=>this.notifyFilesChanged(t))}pick(){if(!this.picker)return Promise.resolve(!1);let e;try{e=this.picker({mode:"readwrite"})}catch(t){return Promise.reject(t)}return e.then(t=>u(this,null,function*(){var o,r;this.cancelAll();const s=(r=yield(o=t.queryPermission)==null?void 0:o.call(t,ve))!=null?r:"granted";return yield this.store.set(this.handleKey,{handle:t,displayName:t.name,savedAt:Date.now()}).catch(()=>{}),s==="denied"?(this.pendingHandle=t,this._adapter=null,this.setStatus("denied",t.name),!1):(this.attachHandle(t),!0)}),t=>{if(Bs(t))return!1;throw t})}restore(){return this._ready=this.doRestore(),this._ready}doRestore(){return u(this,null,function*(){var s,o,r;if(!this.picker){this._adapter||this.setStatus("unsupported");return}let e;try{e=yield this.store.get(this.handleKey)}catch(n){e=void 0}if(!(e!=null&&e.handle)){this.pendingHandle=null,this._adapter=null,this.setStatus("none",void 0);return}let t;try{t=(r=yield(o=(s=e.handle).queryPermission)==null?void 0:o.call(s,ve))!=null?r:"prompt"}catch(n){t="prompt"}t==="granted"?this.attachHandle(e.handle):(this.pendingHandle=e.handle,this._adapter=null,this.setStatus(t==="denied"?"denied":"prompt",e.displayName))})}requestPermission(){const e=this.pendingHandle;if(!(e!=null&&e.requestPermission))return Promise.resolve(!1);let t;try{t=e.requestPermission(ve)}catch(s){return Promise.reject(s)}return t.then(s=>s==="granted"?(this.attachHandle(e),!0):(this._adapter=null,this.setStatus(s==="denied"?"denied":"prompt",e.name),!1))}clear(){return u(this,null,function*(){this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this.pendingHandle=null,this._adapter=null,this.setStatus(this.picker?"none":"unsupported",void 0),yield this.store.delete(this.handleKey).catch(()=>{})})}attachAdapter(e,t=e.displayName){this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this.pendingHandle=null,this._adapter=e,this.setStatus("granted",t)}notifyFilesChanged(e){if(this._status==="granted"){if(!e||e.length===0)this.refreshAllVisible=!0;else for(const t of e){const s=Ds(t);s===void 0?this.refreshAllVisible=!0:this.pendingChangePaths.add(s)}clearTimeout(this.changeTimer),this.changeTimer=setTimeout(()=>this.flushFilesChanged(),150)}}handlePermissionLost(){return u(this,null,function*(){const e=this.pendingHandle;if(!(e!=null&&e.queryPermission))return;const t=yield e.queryPermission(ve).catch(()=>"prompt");t!=="granted"&&(this.cancelAll(),this.cancelFilesChanged(),this.unwatchDirectory(),this._adapter=null,this.setStatus(t==="denied"?"denied":"prompt",e.name))})}isDisclosureAcknowledged(){return u(this,null,function*(){try{return!!(yield this.store.get(this.disclosureKey))}catch(e){return!1}})}acknowledgeDisclosure(){return u(this,null,function*(){yield this.store.set(this.disclosureKey,!0).catch(()=>{})})}setApprovalHandler(e){this.approvalHandler=e}get hasApprovalHandler(){return!!this.approvalHandler}getApprovalHandler(){return this.approvalHandler}acquireSlot(){if(this.activeCalls>=this.limits.maxConcurrentRequests)return null;this.activeCalls++;let e=!1;return()=>{e||(e=!0,this.activeCalls--)}}track(e){return this.inflight.add(e),()=>this.inflight.delete(e)}cancelAll(){const e=Array.from(this.inflight);this.inflight.clear(),e.forEach(t=>t.abort())}handshake(){const e=Object.fromEntries(ze.map(t=>[t,!0]));return{protocolVersion:"1.0",capabilities:I(v({},e),{cancellation:!0,atomicWrite:!0}),limits:v({},this.limits)}}on(e,t){return this.event.on(e,t),()=>this.off(e,t)}off(e,t){this.event.off(e,t)}unwatchDirectory(){const e=this.stopWatching;this.stopWatching=()=>{},e()}cancelFilesChanged(){clearTimeout(this.changeTimer),this.changeTimer=void 0,this.pendingChangePaths.clear(),this.refreshAllVisible=!1}flushFilesChanged(){this.changeTimer=void 0;const e=this.refreshAllVisible,t=[...this.pendingChangePaths].sort((s,o)=>s<o?-1:s>o?1:0);this.pendingChangePaths.clear(),this.refreshAllVisible=!1,this._status==="granted"&&this.emit("files:changed",{paths:e?[]:t})}emit(e,t){try{this.event.emit(e,t)}catch(s){console.error(`[LocalWorkspace] ${e} listener failed`,s)}}}var re=(i=>(i[i.Normal=0]="Normal",i[i.Debug=1]="Debug",i))(re||{});const pt=100,k=new $("[Session] ");var fe=(i=>(i.DataRequestFailed="data request error",i.SocketConnectionFailed="socket error",i.IdUndefined="session id is not defined",i.SendingEmptyContent="failed at sending empty content",i.Frozen="session is frozen",i.UserModeError="failed at setting socket user mode",i.Inactive="session is inactive",i))(fe||{});class st{constructor(e,t="",s,o,r,n){y(this,"_id");y(this,"_frozen",!1);y(this,"inactivating",!1);y(this,"_ready",!1);y(this,"event",new et);y(this,"_applicationId");y(this,"_application",null);y(this,"data",null);y(this,"client",null);y(this,"messages",[]);y(this,"_loadingMessages",!1);y(this,"_loadingMessagesSize",10);y(this,"cvforceApi");y(this,"socket",null);y(this,"_promptVariables",[]);y(this,"active",!1);y(this,"activing",!1);y(this,"_stopAnswer",!1);y(this,"_dataLoading",!1);y(this,"_dataLoaded",!1);y(this,"_mcpServers",null);this.token=e,this.lazyload=o,this.client=n||null,this._applicationId=Te(e).rid||exports.configuration.applicationId,this.cvforceApi=this.getService(),r&&(this._application=r),this.event.emit("init",{applicationId:this._applicationId,sessionId:t}),this.loadApplicationInfo().then(()=>{var c;if(t)this._id=t,this.event.emit("data:loading"),s?(this.data=s,o||(this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,t).then(a=>u(this,null,function*(){this.data=a,this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,t)})).then(()=>u(this,null,function*(){this.messages=[],yield this.fetchMessages(),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data)})))):(this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,t).then(a=>u(this,null,function*(){this.data=a,this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,t)})).then(()=>u(this,null,function*(){this.messages=[],yield this.fetchMessages(),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),this._dataLoading=!1,this._dataLoaded=!0})));else{const a=(s==null?void 0:s.name)||"新建会话";this.event.emit("data:creating",{applicationId:this._applicationId,name:a}),this.event.emit("data:loading"),this.cvforceApi.postSession(this.applicationId,{name:a,netOpen:s==null?void 0:s.netOpen,knowledgeIdList:(c=s==null?void 0:s.knowledges)==null?void 0:c.map(d=>d.id),applicationId:this._applicationId}).then(d=>u(this,null,function*(){var l;this._id=d.id,this.data=I(v({},d),{knowledges:s==null?void 0:s.knowledges}),this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this._id);try{yield(()=>u(this,null,function*(){if(s!=null&&s.knowledges)return this.setKnowledges((s==null?void 0:s.knowledges)||void 0)}))()}catch(h){k.error(h)}yield(()=>{if(s!=null&&s.promptVariables){const h=this._promptVariables.map(f=>{var _,m;const g=((m=(_=s.promptVariables)==null?void 0:_.find(b=>b.key===f.key&&b.type===f.type))==null?void 0:m.value)||"";return I(v({},f),{value:g})}).sort((f,g)=>f.key.localeCompare(g.key));return this.setPromptVariables(h||[])}else return})(),this.event.emit("data:created",this.data),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),((l=this.application)==null?void 0:l.type)!==A.ApplicationTypes.Agent&&(this._ready=!0,this.event.emit("ready"))}))}})}fetchData(){return u(this,null,function*(){if(!this.data)throw Error("session data is not loaded");return yield this.cvforceApi.getSession(this.applicationId,this.data.id).then(e=>u(this,null,function*(){return this.data=e,this.event.emit("data:updated",this.data),e}))})}get id(){var e;return this._id||((e=this.data)==null?void 0:e.id)||""}get applicationId(){return this._applicationId}get application(){return this._application}set application(e){this._application=e}loadApplicationInfo(){if(this._application)return Promise.resolve(this._application);if(this._applicationId&&!this._application)return this.event.emit("application:data:loading"),this.cvforceApi.getApplicationId(this._applicationId).then(e=>(this._application=e,this.event.emit("application:data:loaded",e),e));throw Error("application id is not defined")}get ready(){return this._ready}get frozen(){return this._frozen}set frozen(e){e===!1&&this.inactivating&&this.socket&&(this.socket.disconnect(),this.socket=null,this.event.emit("inactivated")),this._frozen=e,this.event.emit("frozen",e)}get knowledges(){if(!this.data)throw Error("session data is not loaded");return this.data.knowledges||void 0}setKnowledges(e){return u(this,null,function*(){if(!this.data)throw Error("session data is not loaded");if((e||[]).some(o=>Array.isArray(o.fileIds)&&o.fileIds.length===0))throw Error("fileIds cannot be an empty array");if((e||[]).reduce((o,r)=>{var c,a;const n=(a=(c=r.fileIds)==null?void 0:c.length)!=null?a:0;return o+(n>0?n:1)},0)>pt)throw Error(`knowledges and fileIds total count cannot exceed ${pt}`);return yield this.cvforceApi.patchSessionsId(this._applicationId,this.data.id,{knowledges:e}),this.data.knowledges=e,this.event.emit("data:updated",this.data),this.event.emit("data:updated:knowledges",{knowledges:e}),e})}validateConfigs(){if(!this._id)throw Error("session id is not defined");if(!this.data)throw Error("session data is not loaded");const e=this.promptVariables.filter(t=>t.status===A.PromptStatus.Quoted).filter(t=>!t.value);if(e.length)throw Error(`在提示词中被引用的变量值不能为空, 请检查以下变量: ${e.map(t=>t.key).join(", ")}`)}get promptVariables(){return this._promptVariables.filter(e=>!(e.type===A.PromptVariableType.User&&e.key==="query")&&!(e.type===A.PromptVariableType.System&&e.key==="datetime"))}setPromptVariables(e){return u(this,null,function*(){const t=e==null?void 0:e.map(r=>r.type?r:I(v({},r),{type:"instruction"})),s=this._promptVariables.map(r=>{var c;const n=((c=t==null?void 0:t.find(a=>a.key===r.key&&a.type===r.type))==null?void 0:c.value)||r.value;return I(v({},r),{value:n})}).sort((r,n)=>r.key.localeCompare(n.key));if(!(yield Promise.all(s.filter(r=>!(r.type===A.PromptVariableType.User&&r.key==="query")&&!(r.type===A.PromptVariableType.System&&r.key==="datetime")).map(r=>{if(!this.data)throw Error("session data is not loaded");if(!(!r.id||!r.key))return this.cvforceApi.patchApplicationIdSessionpromptVariablesId(this._applicationId,this.data.id,r.id,{value:r.value})})).then(()=>!0).catch(r=>!1)))return!1;if(!this.data)throw Error("session data is not loaded");return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this.data.id),this.event.emit("data:updated",this.data),this.event.emit("data:updated:promptVariables",{promptVariables:this._promptVariables}),this._promptVariables})}get netOpen(){if(!this.data)throw Error("session data is not loaded");return this.data.netOpen||!1}setNetOpen(e){return u(this,null,function*(){var t,s,o;if(k.log("setNetOpen:",e),k.log("application arrange setting value: ",(t=this._application)==null?void 0:t.arrange[0].enableNetOpen),((s=this._application)==null?void 0:s.type)===A.ApplicationTypes.Agent){console.warn("Agent Application Sessions are disabled to setNetOpen.");return}if(((o=this._application)==null?void 0:o.arrange[0].enableNetOpen)===!1){console.warn("This Application is disabled to change netOpen.");return}if(!this.data)throw Error("session data is not loaded");return yield this.cvforceApi.patchSessionsId(this._applicationId,this.data.id,{netOpen:e?1:2}),this.data.netOpen=e,k.log("data:updated",this.data),this.event.emit("data:updated",this.data),this.event.emit("data:updated:netOpen",{netOpen:e}),e})}getService(){return ai(exports.configuration.apiRoot,this.token,(e,t)=>{const s=new Error("data request error",{cause:{status:e,message:t}});k.error(s),this.event.emit("error",s)})}addEventListener(e,t,s=!1){if(typeof t!="function")throw Error("event listener is not a function");if(s){this.event.once(e,t);return}this.event.on(e,t)}removeEventListener(e,t){this.event.off(e,t)}fetchMessages(){return u(this,arguments,function*(e={}){var s,o;const t={pageSize:this._loadingMessagesSize};if(this._id){e=v(v({},t),e),this.event.emit("history:loading"),k.log("history:loading"),(e.endTime||e.startTime)&&(this.event.emit("history:moreloading",e),k.log("history:moreloading",e)),this._loadingMessages=!0;const r=yield this.cvforceApi.getChatHistorySessionId(this._applicationId,this._id,e),n=r.map((a,d)=>{var f,g;let l=[],h;return typeof((f=a.agentHistoryList)==null?void 0:f.agentList)=="string"&&(l=JSON.parse(a.agentHistoryList.agentList).reduce((m,b)=>(m[b.data.step-1]||(m[b.data.step-1]=[]),m[b.data.step-1].push(b),m),[])),d===r.length-1&&(h=(g=this.data)==null?void 0:g.lastRelatedQuestion),I(v({},a),{actions:l,relatedQuesion:h,fromHistory:!0})});if(!e.endTime&&!e.startTime){const a=this.messages[this.messages.length-1];a&&!a.relatedQuesion&&(a.relatedQuesion=(s=this.data)==null?void 0:s.lastRelatedQuestion),this.messages=[...n,...this.messages]}else if(e.endTime&&!e.startTime){const a=this.messages.findIndex(d=>d.ts===e.endTime);this.messages.splice(0,a+1),this.messages=[...n,...this.messages]}else if(!e.endTime&&e.startTime){const a=this.messages.findLastIndex(d=>d.ts===e.endTime);this.messages.splice(a,this.messages.length-a-1),this.messages=[...this.messages,...n]}else{const a=this.messages.findIndex(l=>l.ts===e.endTime),d=this.messages.findLastIndex(l=>l.ts===e.endTime);this.messages.splice(a,d-a+1,...n)}const c=this.messages[this.messages.length-1];return c&&!c.relatedQuesion&&(c.relatedQuesion=(o=this.data)==null?void 0:o.lastRelatedQuestion),this.event.emit("history:moreloaded",n),k.log("history:loaded",this.messages),this.event.emit("history:loaded",this.messages),this._loadingMessages=!1,n}else{const r=new Error("session id is not defined");return k.error(r),this.event.emit("error",r),!1}})}rename(e){return u(this,null,function*(){if(!this._id)throw Error("session is not created yet");if(e.trim()==="")throw Error("name is empty");return this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{name:e}),k.log("data:updated",this.messages),this.event.emit("data:updated",this.data),this.event.emit("data:updated:name",{name:e}),!0})}pushMessage(e){return u(this,null,function*(){this.messages.push(e),k.log("history:add",e),this.event.emit("history:add",e),this.event.emit("message:new",e),this.event.emit("message:updated",e)})}reloadSessionInfo(){if(!this._id)throw Error("session is not created yet");return this._dataLoading=!0,this.cvforceApi.getSession(this.applicationId,this._id).then(e=>u(this,null,function*(){if(this.data=e,!this._id)throw Error("session is not created yet");return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,this._id),k.log("data:updated",this.data),this.event.emit("data:updated",this.data),this.data})).then(()=>u(this,null,function*(){return this.messages=[],yield this.fetchMessages(),this._dataLoading=!1,this._dataLoaded=!0,this.event.emit("data:loaded",this.data),this}))}reload(){return u(this,null,function*(){return yield this.reloadSessionInfo(),this.socket?(this.inactivate(!0),this.activate()):(this.inactivate(!0),this.activate())})}delete(){return u(this,null,function*(){if(!this.id){const e=new Error("session id is not defined");return k.error(e),this.event.emit("error",e),!1}return this.event.emit("data:deleting"),yield this.cvforceApi.delSessionsId(this.applicationId,this.id),this.event.emit("data:deleted"),this.destroy()})}activate(){return u(this,null,function*(){if(this.activing)return new Promise(t=>{this.addEventListener("activated",()=>{t(!0)},!0)});if(!this._id)throw Error("session is not avalible. id is undefined");this.activing=!0;const e=this._id;return this._dataLoading=!0,this._dataLoaded=!1,this.data=yield this.cvforceApi.getSession(this.applicationId,e).then(t=>u(this,null,function*(){return this._promptVariables=yield this.cvforceApi.getApplicationIdSessionIdPromptVariables(this.applicationId,e),t})),this.messages.length||(this.messages=[],yield this.fetchMessages()),this.event.emit("data:loaded",this.data),this.event.emit("data:updated",this.data),this._dataLoaded=!0,this._dataLoading=!1,this.inactivating=!1,this.frozen=!0,yield this.prepareConnection(),this.event.emit("activated",this.socket),this.active=!0,this.activing=!1,this})}inactivate(e=!1){return this.socket?this._frozen?(e||(this.inactivating=!0),this.activing=!1,!0):(this.socket.close(),this.socket=null,this.event.emit("inactivated"),this.active=!1,this.activing=!1,!0):(this.activing=!1,!0)}get dataLoaded(){return this._dataLoaded}get messagesLoading(){return this._loadingMessages}send(s){return u(this,arguments,function*(e,t={stream:exports.configuration.stream}){var _;try{this.validateConfigs()}catch(m){console.error(m)}const{stream:o=exports.configuration.stream,referenceFirst:r=!1}=t,n=e.uuid||ae.v4(),c=((_=e.text)==null?void 0:_.trim())||"",a=e.files||[],d=e.fileIds,l=e.imageContent;if(!c&&!a.length&&!(d!=null&&d.length)){const m=new Error("failed at sending empty content");return k.error(m),this.event.emit("error",m),!1}if(!this._id){const m=new Error("session id is not defined");return k.error(m),this.event.emit("error",m),!1}if(this.frozen){const m=new Error("session is frozen");return k.error(m),this.event.emit("error",m),!1}this.frozen=!0,this._stopAnswer=!1;const h={sessionId:this.id,role:2,content:c,messageId:n,reference:[],searchReference:[],messageTime:"",files:a,imageContent:l},f={content:c,stream:o,requestId:n,fileIds:d,referenceFirst:r,imageContent:l};this.pushMessage(h),this.event.emit("question:content",c);const g=m=>u(this,null,function*(){if(m.role!==A.ChatMessageRole.Robot)return;switch(this.removeEventListener("answer:finish",g),this._id&&m.content&&m.index&&m.index<0&&(this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{finialMessage:m.content}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:finialMessage",{finialMessage:m.content})),yield this.fillMessageReference(m),m.code){case 11915:m.content="请您换个问题问我吧~",m.index=-1,m.isSensitive=!0,m.isLoading=!1,m.sessionId=this._id||"",this.event.emit("message:error",m);break;case 11916:m.content="尊敬的用户您好,让我们换个话题再聊聊吧。",m.index=-1,m.isSensitive=!0,m.isLoading=!1,m.sessionId=this._id||"",this.event.emit("message:error",m);break;case 200:m.index=-1,m.isLoading=!1;break;default:m.content=m.message||"未知错误",m.isLoading=!1,m.index=-1,this.event.emit("message:error",m)}this.getRelatedQuesion(m),m.isLoading=!1;let b=this.messages[this.messages.length-1];if(b&&b.role===A.ChatMessageRole.Robot){const T=v(v({},b),m);this.messages[this.messages.length-1]=T,this.event.emit("message:updated",T)}else this.pushMessage(m);this.frozen=!1});return this.addEventListener("answer:finish",g),this.sendQuestion(f,I(v({},t),{stream:o,referenceFirst:r})),h})}currentUserQuestion(){for(let e=this.messages.length-1;e>=0;e-=1){const t=this.messages[e];if(t.role===A.ChatMessageRole.User)return t.content||""}return""}getRelatedQuesion(e){return u(this,null,function*(){var c,a;if(!e.content||e.isSensitive||e.code!==200)return e;const t=(c=this.application)==null?void 0:c.arrange[0],s=Cs(t==null?void 0:t.recommendQuestionOpen,t==null?void 0:t.relatedQuestionApp,e.content,this.currentUserQuestion());if(s===null)return e;this.event.emit("message:relatedQuesion:loading",e);const o=yield this.cvforceApi.postGeneques({content:s}).catch(d=>null);if(!o){const d=[],l=I(v({},e),{relatedQuesion:d,index:-3,isLoading:!1});return this.event.emit("message:relatedQuesion:loaded",{relatedQuesion:d}),this.event.emit("message:updated",l),l}const r=(a=o.content)==null?void 0:a.split("*").map(Ts).map(Ls).filter(d=>!!d);e.relatedQuesion=r,e.index=-3,e.isLoading=!1;const n=I(v({},e),{relatedQuesion:r,index:-3,isLoading:!1});return this.event.emit("message:relatedQuesion:loaded",n),this.event.emit("message:updated",n),this._id&&this.cvforceApi.patchSessionsId(this._applicationId,this._id,{lastRelatedQuestion:r}),n})}fillMessageReference(e){return u(this,null,function*(){try{const t=yield Promise.all(e.reference.map(s=>this.cvforceApi.getKnowledgeIdFileId(s.knowledgeId,s.docId)));e.reference=e.reference.map((s,o)=>v(v({},s),t[o]))}catch(t){console.error("Failed to fill message reference:",t)}return this.event.emit("message:updated",e),e})}answerAgain(){return u(this,arguments,function*(e={stream:exports.configuration.stream}){const t=this.messages[this.messages.length-1];if(!t)throw Error("message list is empty");this.frozen=!0,this._stopAnswer=!1;const{stream:s=exports.configuration.stream}=e;let o;t.role!==A.ChatMessageRole.User&&(o=e.oldMessageId||t.messageId,this.messages.splice(this.messages.length-1,1),this.event.emit("message:remove",t),this.event.emit("history:remove",t));const r=this.messages[this.messages.length-1],n={content:r.content,fileIds:r.fileIds,requestId:r.messageId,stream:s,oldMessageId:o},c=a=>u(this,null,function*(){if(a.role===A.ChatMessageRole.Robot&&a.index===-1){switch(this._id&&a.content&&a.index&&a.index<0&&(this.data=yield this.cvforceApi.patchSessionsId(this.applicationId,this._id,{finialMessage:a.content}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:finialMessage",{finialMessage:a.content})),yield this.fillMessageReference(a),a.code){case 11915:a.content="请您换个问题问我吧~",a.index=-1,a.isSensitive=!0,a.isLoading=!1,a.sessionId=this._id||"",this.event.emit("message:error",a);break;case 11916:a.content="尊敬的用户您好,让我们换个话题再聊聊吧。",a.index=-1,a.isSensitive=!0,a.isLoading=!1,a.sessionId=this._id||"",this.event.emit("message:error",a);break;case 200:a.index=-1,a.isLoading=!1;break;default:a.content=a.message||"未知错误",a.isLoading=!1,a.index=-1,this.event.emit("message:error",a)}this.getRelatedQuesion(a),this.removeEventListener("message:content",c),this.frozen=!1}});this.addEventListener("message:content",c),this.sendQuestion(n,I(v({},e),{stream:s}))})}setTop(e){return u(this,null,function*(){if(!this._id)throw Error("session is not avalible. id is undefined");this.data=yield this.cvforceApi.patchSessionsId(this._applicationId,this._id,{top:e}),this.event.emit("data:updated",this.data),this.event.emit("data:updated:top",{top:e})})}suspend(){var s;this.stopAnswer(),this.frozen=!1,this._stopAnswer=!0;let e=this.messages[this.messages.length-1];const t={messageId:ae.v4(),isLoading:!1,index:-2,messageTime:Ue(new Date).format("YYYY-MM-DD HH:ss:mm"),content:"",role:A.ChatMessageRole.System,sessionId:this.id||"",reference:[],searchReference:[]};if(e&&!e.messageId){if(e.index===-2)return;if(e.actions){const o=e.actions[((s=e.actions)==null?void 0:s.length)-1];if(o){const r=o[o.length-1];if(r&&(r.type==="BEFORE_CALL"||r.type==="FUNCTION_CALL")){const{pluginName:n,pluginCode:c,funcCode:a,funcName:d}=r.data;o.push({data:{pluginName:n,pluginCode:c,funcCode:a,funcName:d,step:r.data.step+1},type:"ABORT"}),this.event.emit("message:action",{messageId:e.messageId,action:o})}}}e=v(v({},e),t),this.event.emit("message:content",e),this.event.emit("message:updated",e)}else this.pushMessage(t),this.event.emit("message:content",t);return this}handleStreamAnswer(e,t){var n;if(!e.data)return;const s=e.data.type,o=e.data.payload;t.isReplying=!0;const r=()=>{if(!t.searchingStatus){t.searchingStatus="start";return}if(t.searchingStatus==="start"){t.searchingStatus="end";return}};if(s==="error"&&(t.index=-1),s==="beforeSearch"&&r(),s==="searchOver"&&r(),s==="search"&&t.searchReference.push(o),s==="thinking"){t.thinkingStatus="start";const a=o.choices[0];t.reasoningContent=(t.reasoningContent||"")+((n=a.delta.reasoningContent)!=null?n:"")}if(s==="thinkingOver"){t.thinkingStatus="end";const c=o.thinkingSecs;t.thinkingSecs=c}if(s==="text"){const a=o.choices[0];t.content=(t.content||"")+a.delta.content}if(s==="reference"&&(t.reference=o),s==="updateSession"&&o&&this.data&&(this.data=v(v({},this.data),o),this.event.emit("data:updated",this.data)),s==="result"){const c=o.messageId,a=o.llmModel,d=o.messageTime;t.messageId=c,t.llmModel=a,t.messageTime=d}s==="over"?t.index=-1:(t.code=e.code,t.message=e.message)}getArtifacts(){return u(this,null,function*(){var t;if(!this._applicationId||!this._id)throw Error("session is not avalible. id is undefined");const e=yield this.cvforceApi.getSessionArtifacts(this._applicationId,this._id);return(t=e==null?void 0:e.artifacts)!=null?t:[]})}postMessageComment(e){return u(this,null,function*(){if(!this._applicationId||!this._id)throw Error("session is not avalible. id is undefined");return this.cvforceApi.postComments(this._applicationId,this._id,e).then(t=>{const s=this.messages.find(o=>o.messageId===e.messageId);return s&&(s.comment=e,this.event.emit("message:comment",s)),t})})}clear(){if(!this._id)throw Error("session is not avalible. id is undefined");return this.cvforceApi.patchApplicationIdSessionsIdContext(this._applicationId,this._id).then(()=>(this.event.emit("context:clear"),!0))}destroy(){var e;return this._ready=!1,this.event.removeAllListeners(),(e=this.socket)==null||e.disconnect(),this.socket=null,this.event.emit("destroy",{applicationId:this._applicationId,sessionId:this._id}),this._id||""}}const D=new $("[AgentSession] ");function gt(i){if(typeof i!="string")return i;const e=i.trim();if(e)try{return JSON.parse(e)}catch(t){return i}}function mt(i){return i==null||i===""||typeof i=="object"&&!Array.isArray(i)&&Object.keys(i).length===0}function qs(i,e){const t=gt(i==null?void 0:i.query);if(!mt(t))return t;const s=gt(e);return mt(s)&&t!=null?t:s}class Hs extends st{constructor(t,s="",o,r,n,c){super(t,s,o,r,n,c);y(this,"inflightCalls",new Set)}prepareConnection(){return new Promise(t=>u(this,null,function*(){this.socket&&t(!0);const s={version:"1.0",stream:JSON.stringify(exports.configuration.stream),appId:this._applicationId,sessionId:this.id,Authorization:`${this.token}`,userMode:exports.configuration.debug?re.Debug:re.Normal},o=new URL(exports.configuration.apiRoot),r=yield wi.io(o.origin,{path:o.pathname.replace("api","socketio")+"/copilot",query:s,transports:["websocket"]});r.on("connect",()=>{D.log("socket:connect"),this.event.emit("socket:connect"),r.emit("init")}),r.on("disconnect",()=>{D.log("socket:disconnect"),this.event.emit("socket:disconnect"),this._ready=!1}),r.on("ready",n=>{if(n.code===200){D.log("ready");const c=exports.configuration.debug?re.Debug:re.Normal;c===re.Debug&&n.userMode,this._ready||(this._ready=!0,this.event.emit("ready")),this.frozen=!1,this.registerMcpFromClientConfig(),t(!0)}else{this._ready&&(this._ready=!1);const c=new Error(fe.SocketConnectionFailed);D.error("error",c),this.event.emit("error",c),t(!1)}}),r.on("action",(n,c)=>u(this,null,function*(){var m;if(this._stopAnswer||!this.id)return;const{type:a,data:{runnerIsClient:d,pluginCode:l,funcCode:h,parameters:f,requestBody:g}}=n,_=this.messages[this.messages.length-1];if(!_.messageId)_.actions||(_.actions=[]),_.actions[n.data.step-1]||(_.actions[n.data.step-1]=[]),_.actions[n.data.step-1].push(n),this.event.emit("message:action",{messageId:_.messageId,action:n}),this.event.emit("message:updated",_);else{const b={messageId:"",content:"",role:A.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!0,messageTime:"",actions:[[n]],comment:{isAgree:0},isReplying:!0};this.pushMessage(b),this.event.emit("message:action",{messageId:b.messageId,action:n})}if(this.inactivating){const b=new Error(fe.Inactive);D.warn("error",b),this.event.emit("error",b)}else if(a==="FUNCTION_CALL"&&d){D.log(`calling function ${h} of plugin ${l} with argument:
|
|
8
|
-
${JSON.stringify(f)}`);const b=(m=exports.configuration.plugins)==null?void 0:m[l];if(!b){c({code:404,message:"没有找到插件。"});return}const T=b[h];if(typeof T!="function"){c({code:404,message:"没有找到插件方法。"});return}const S=qs(f,g);this.invokeClientPlugin(T,S,c,{requestId:n.requestId,pluginCode:l,functionCode:h})}})),r.on("answer",n=>{if(!this._stopAnswer)if(n.data.code!==200&&(n.data.index=-1),n.data.stream||n.data.stream===void 0){let c=this.messages[this.messages.length-1];if(c&&c.role===A.ChatMessageRole.Robot)this.handleStreamAnswer(n.data,c),this.messages[this.messages.length-1]=c,this.event.emit("message:content",c),this.event.emit("message:updated",c),c.index===-1&&(c.isReplying=!1,this.event.emit("answer:finish",c));else{const a={content:"",role:A.ChatMessageRole.Robot,reference:[],searchReference:[],messageId:"",sessionId:this.id,messageTime:Ue(new Date).format("YYYY-MM-DD HH:mm:ss"),comment:{isAgree:0},isReplying:!0,reasoningContent:"",thinkingSecs:"",thinkingStatus:"",searchingStatus:""};this.handleStreamAnswer(n.data,a),this.pushMessage(a),this.event.emit("message:content",a),a.index===-1&&(a.isReplying=!1,this.event.emit("answer:finish",a))}}else if(n.data.updateSession&&this.data&&(this.data=v(v({},this.data),n.data.updateSession),this.event.emit("data:updated",this.data)),n.data.index===-1){let c=this.messages[this.messages.length-1];if(c&&!c.messageId)c=v(v({},c),n.data),this.event.emit("message:content",c),this.event.emit("message:updated",c),this.event.emit("answer:finish",c);else{const a=v({messageId:"",content:"",role:A.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!1,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0},n.data);this.event.emit("message:content",a),this.pushMessage(a),this.event.emit("answer:finish",a)}}else{let c=this.messages[this.messages.length-1];c&&!c.messageId?(c=v(v({},c),n.data),this.messages[this.messages.length-1]=c,this.event.emit("message:content",c),this.event.emit("message:updated",c)):(this.pushMessage(v({messageId:"",content:"",role:A.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!1,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0},n.data)),this.event.emit("message:content",n.data))}}),r.on("reference",n=>u(this,null,function*(){if(this._stopAnswer)return;if(!this.id){const f=new Error(fe.IdUndefined);D.error(f),this.event.emit("error",f),this.frozen=!1;return}const{type:c,data:a,requestId:d}=n,l=this.messages.findIndex(f=>f.messageId===d&&f.role===A.ChatMessageRole.User);if(l<0)return;const h=l+1;if(h>=this.messages.length){const f={messageId:"",content:"",role:A.ChatMessageRole.Robot,sessionId:this.id,reference:[],searchReference:[],isLoading:!0,messageTime:"",actions:[],comment:{isAgree:0},isReplying:!0};this.pushMessage(f)}c==="KG"?(this.messages[h]=I(v({},this.messages[h]),{reference:a.knowledgeReference}),yield this.fillMessageReference(this.messages[h]),this.event.emit("message:reference",a.knowledgeReference),this.event.emit("message:updated",this.messages[h])):c==="WEB_SEARCH"&&(this.messages[h]=I(v({},this.messages[h]),{searchReference:a.knowledgeReference}),this.event.emit("message:searchreference",a.searchReference),this.event.emit("message:updated",this.messages[h]))})),this.socket=r,r.open()}))}registerMcpFromClientConfig(){return exports.configuration.mcp?new Promise((t,s)=>{if(!this.socket){s("socket is undefined");return}this.socket.emit("add_mcp_servers",exports.configuration.mcp,o=>{o.code===200?(Object.keys(o.data).forEach(r=>{o.data[r].code!==200&&console.error(r,"MCP Server 注册失败。",o.data[r])}),t(!0)):(console.error("MCP Server 注册失败。",o),s(o))})}):Promise.resolve(!0)}addMcpServers(t){return u(this,null,function*(){return this.ready?this.socket?new Promise((s,o)=>{this.socket&&this.socket.emit("add_mcp_servers",t,r=>{r.code===200?(Object.keys(r.data).forEach(n=>{r.data[n].code!==200&&console.error(n,"MCP Server 注册失败。",r.data[n])}),s(!0)):(console.error("MCP Server 注册失败。",r),o(r))})}):(console.error(" socket is undefined."),Promise.reject("socket is undefined")):(console.error("session is not avalible."),Promise.reject("session is not avalible"))})}listMcpServers(){return u(this,null,function*(){return this.ready?this.socket?new Promise((t,s)=>{this.socket&&this.socket.emit("list_mcp_servers",o=>{o.code===200?t(o.data):s(o)})}):(console.error(" socket is undefined."),Promise.reject("socket is undefined")):(console.error("session is not avalible."),Promise.reject("session is not avalible"))})}sendQuestion(t,s){return u(this,null,function*(){var r,n,c;this.convertKnowledgesToChatFormat(this.knowledges);let o=I(v({},t),{promptVariables:this.promptVariables.filter(a=>a.type===A.PromptVariableType.User).reduce((a,d)=>I(v({},a),{[d.key]:d.value}),{}),systemPromptVariables:this.promptVariables.filter(a=>a.type===A.PromptVariableType.System).reduce((a,d)=>I(v({},a),{[d.key]:d.value}),{}),knowledges:(r=this.knowledges)==null?void 0:r.map(a=>a.id),enableTitleSummary:!0});if(!this.active){if(yield this.activate(),!this.socket){const a=new Error(fe.SocketConnectionFailed);return D.warn("error",a),this.event.emit("error",a),!1}(n=this.socket)==null||n.emit("question",o);return}(c=this.socket)==null||c.emit("question",o)})}invokeClientPlugin(t,s,o,r){const n=new AbortController;this.inflightCalls.add(n);let c=!1;const a=(...l)=>{c||(c=!0,this.inflightCalls.delete(n),!(this._stopAnswer||n.signal.aborted)&&o(...l))},d={requestId:r.requestId||ae.v4(),applicationId:this._applicationId,sessionId:this.id,pluginCode:r.pluginCode,functionCode:r.functionCode,signal:n.signal};try{const l=t(s,a,d);l&&typeof l.catch=="function"&&l.catch(h=>{D.error("client plugin failed",h),a({code:500,message:"客户端插件执行失败。"})})}catch(l){D.error("client plugin failed",l),a({code:500,message:"客户端插件执行失败。"})}}abortClientPluginCalls(){const t=Array.from(this.inflightCalls);this.inflightCalls.clear(),t.forEach(s=>s.abort())}stopAnswer(){var t;this.abortClientPluginCalls(),(t=this.socket)==null||t.emit("stop_answer")}inactivate(t=!1){return this.abortClientPluginCalls(),super.inactivate(t)}destroy(){return this.abortClientPluginCalls(),super.destroy()}convertKnowledgesToChatFormat(t){return t?t.map(s=>s!=null&&s.fileIds?{id:s.id,fileIds:s.fileIds}:s.id):[]}}function $s(i,e){return u(this,null,function*(){const t=i.getReader();let s;for(;!(s=yield t.read()).done;)e(s.value)})}function Us(i){let e,t,s,o=!1,r;return function(c){e===void 0?(e=c,t=0,s=-1,r=!1):e=js(e,c);const a=e.length;let d=0;for(;t<a;){o&&(e[t]===10&&(d=++t),o=!1);let l=-1;for(;t<a&&l===-1;++t)switch(e[t]){case 58:s===-1&&(s=t-d);break;case 13:o=!1,t+4<a&&e[t+1]===10&&e[t+2]!==13&&e[t-1]!==10&&e[t-2]!==13&&(r=!0);case 10:l=t;break}if(l===-1)break;i(e.subarray(d,l),s,r),d=t,s=-1,r=!1}d===a?e=void 0:d!==0&&(e=e.subarray(d),t-=d)}}function zs(i,e,t){let s=yt();const o=new TextDecoder;return function(n,c,a){if(n.length===0)t==null||t(s),s=yt();else if(c>0){const d=o.decode(n.subarray(0,c)),l=c+(n[c+1]===32?2:1);let h=o.decode(n.subarray(l));switch(a&&(h+=`
|
|
9
|
-
`),d){case"data":s.data=s.data?s.data+`
|
|
10
|
-
`+h:h;break;case"event":s.event=h;break;case"id":i(s.id=h);break;case"retry":const f=parseInt(h,10);isNaN(f)||e(s.retry=f);break}}}}function js(i,e){const t=new Uint8Array(i.length+e.length);return t.set(i),t.set(e,i.length),t}function yt(){return{data:"",event:"",id:"",retry:void 0}}const $e="text/event-stream",Ws=1e3,wt="last-event-id";function vt(i,l){var h=l,{signal:e,headers:t,onopen:s,onmessage:o,onclose:r,onerror:n,openWhenHidden:c,fetch:a}=h,d=at(h,["signal","headers","onopen","onmessage","onclose","onerror","openWhenHidden","fetch"]);return new Promise((f,g)=>{const _=v({},t);_.accept||(_.accept=$e);let m;function b(){m.abort(),document.hidden||x()}c||document.addEventListener("visibilitychange",b);let T=Ws,S=0;function E(){document.removeEventListener("visibilitychange",b),window.clearTimeout(S),m.abort()}e==null||e.addEventListener("abort",()=>{E(),f()});const C=a!=null?a:window.fetch,le=s!=null?s:Vs;function x(){return u(this,null,function*(){var L;m=new AbortController;try{const F=yield C(i,I(v({},d),{headers:_,signal:m.signal}));yield le(F),yield $s(F.body,Us(zs(R=>{R?_[wt]=R:delete _[wt]},R=>{T=R},o))),r==null||r(),E(),f()}catch(F){if(!m.signal.aborted)try{const R=(L=n==null?void 0:n(F))!=null?L:T;window.clearTimeout(S),S=window.setTimeout(x,R)}catch(R){E(),g(R)}}})}x()})}function Vs(i){const e=i.headers.get("content-type");if(!(e!=null&&e.startsWith($e)))throw new Error(`Expected content-type to be ${$e}, Actual: ${e}`)}const _t=new $("[DialogSession] ");class Ys extends st{constructor(t,s="",o,r,n,c){super(t,s,o,r,n,c);y(this,"ctrl",new AbortController)}prepareConnection(){return new Promise(t=>u(this,null,function*(){this._ready=!0,this.event.emit("ready"),this.frozen=!1,t(!0)}))}postChatV2EventSource(t,s,o,r,n,c){return u(this,null,function*(){const a={code:0,content:"",role:A.IHistoryRole.Robot,sessionId:s,reference:[],searchReference:[],messageTime:"",llmModel:"",comment:{isAgree:0},isReplying:!1},d=I(v({},o),{stream:exports.configuration.stream});vt(`${exports.configuration.apiRoot}/chat/v2/chat?applicationId=${t}&sessionId=${s}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(d),openWhenHidden:!0,signal:r,onopen(l){return l.ok&&n!=null&&n.onopen&&n.onopen(),Promise.resolve()},onmessage(l){if(!l.data.includes('{"code": ')){let f={};try{f=JSON.parse(l.data)}catch(_){}(f==null?void 0:f.mtype)==="search"?a.searchReference.push(f):a.content=a.content+l.data;const g={content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:s,messageTime:Ue(new Date).format("YYYY-MM-DD HH:mm:ss"),comment:{isAgree:0},isReplying:!0};return(n==null?void 0:n.onmessage)&&n.onmessage(g)}const h=JSON.parse(l.data);if(a.reference=h.data.reference,a.searchReference=h.data.searchReference,a.messageTime=h.data.messageTime,a.messageId=h.data.messageId,a.llmModel=h.data.llmModel,a.content=h.data.content,a.code=h.code,h.code===200){const f={code:a.code,content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:s,messageTime:a.messageTime,isReplying:!0};n!=null&&n.onmessage&&n.onmessage(f)}else return n!=null&&n.onclose&&n.onclose(a),c&&c({code:a.code,message:a.message})},onerror(){n!=null&&n.onerror&&n.onerror()},onclose(){const l={code:a.code,content:a.content,role:1,reference:a.reference,searchReference:a.searchReference,messageId:a.messageId,sessionId:s,messageTime:a.messageTime,comment:{isAgree:0},isReplying:!1,index:-1};n!=null&&n.onclose&&n.onclose(l)}})})}postChatV3EventSource(t,s,o,r,n,c){return u(this,null,function*(){const a=this,d={code:0,content:"",role:A.IHistoryRole.Robot,sessionId:s,reference:[],searchReference:[],messageTime:"",llmModel:"",comment:{isAgree:0},isReplying:!1,reasoningContent:"",thinkingSecs:"",thinkingStatus:"",searchingStatus:""},l=I(v({},o),{stream:exports.configuration.stream});vt(`${exports.configuration.apiRoot}/chat/v3/chat?applicationId=${t}&sessionId=${s}`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`,"Content-Type":"application/json"},body:JSON.stringify(l),openWhenHidden:!0,signal:r,onopen(h){return h.ok&&n!=null&&n.onopen&&n.onopen(),Promise.resolve()},onmessage(h){if(!h.data&&!h.event&&!h.id&&!h.retry)return;let f={};try{f=JSON.parse(h.data)}catch(g){console.error("parse eventData to JSON failed. ",h.data)}if(f.code!==200)return d.index=-1,d.code=f.code,d.message=f.message,n!=null&&n.onmessage&&n.onmessage(d),c&&c({code:f.code,message:f.message});a.handleStreamAnswer(f,d),n!=null&&n.onmessage&&n.onmessage(d)},onerror(){n!=null&&n.onerror&&n.onerror()},onclose(){const h=I(v({},d),{isReplying:!1});n!=null&&n.onclose&&n.onclose(h)}})})}sendQuestion(t,s){return u(this,null,function*(){const{content:o,fileIds:r,oldMessageId:n,imageContent:c}=t,{stream:a,referenceFirst:d}=s;if(this.active||(yield this.activate()),this._id){const l=this.convertKnowledgesToChatFormat(this.knowledges);let h={content:o,fileIds:r,referenceFirst:d,oldMessageId:n,promptVariables:this.promptVariables.filter(f=>f.type===A.PromptVariableType.User).reduce((f,g)=>I(v({},f),{[g.key]:g.value}),{}),systemPromptVariables:this.promptVariables.filter(f=>f.type===A.PromptVariableType.System).reduce((f,g)=>I(v({},f),{[g.key]:g.value}),{}),knowledges:l,enableTitleSummary:!0,imageContent:c};this.ctrl=new AbortController,this.postChatV3EventSource(this._applicationId,this._id,h,this.ctrl.signal,{onopen:()=>{_t.log("open",this.ctrl)},onmessage:f=>{if(this._stopAnswer)return;let g=this.messages[this.messages.length-1];g&&g.role===A.ChatMessageRole.Robot?(g=v(v({},g),f),this.messages[this.messages.length-1]=g,this.event.emit("message:content",g),this.event.emit("message:updated",g)):(this.pushMessage(f),this.event.emit("message:content",f))},onclose:f=>u(this,null,function*(){this._stopAnswer||(_t.log(f,"onclose"),this.event.emit("answer:finish",f))}),onerror:()=>{this._stopAnswer||(this.event.emit("message:error",""),this.frozen=!1)}})}})}stopAnswer(){this.ctrl.abort()}registerMcpFromClientConfig(){return u(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}addMcpServers(t){return u(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}listMcpServers(){return u(this,null,function*(){throw new Error("MCP registration is not supported by DialogSession")})}convertKnowledgesToChatFormat(t){return t?t.map(s=>s!=null&&s.fileIds?{id:s.id,fileIds:s.fileIds}:s.id):[]}}const Gs="@glodon-aiot/bot-client-sdk",Qs="3.26.0-alpha.4",Xs="glodoncv",Ks="aiot bot client js sdk",Js="module",Zs=!1,en=["aiot","bot","bot client","sdk"],tn=["dist"],sn="./dist/es/index.mjs",nn="./dist/lib/index.js",rn="./dist/src/index.d.ts",an={".":{import:"./dist/es/index.mjs",require:"./dist/lib/index.js",types:"./dist/src/index.d.ts"}},on="MIT",cn={watch:"yarn build --watch",example:"node ./example/server.js",dev:"npm-run-all -p watch example",start:"vite",build:"tsc && vite build --mode prod && yarn build:cdn","build:npm":"tsc && vite build --mode prod","build:cdn":"tsc && vite build --mode prod --config ./vite.config.cdn.ts",preview:"vite preview",check:"yarn prettier --check .",write:"yarn prettier --write .",lint:"eslint --ext .tsx,.ts --fix ./example -c .eslintrc.js",test:"vitest run","test:watch":"vitest"},dn={"@babel/core":"^7.20.12","@commitlint/cli":"^17.0.3","@commitlint/config-conventional":"^17.0.3","@rollup/plugin-babel":"^6.0.4","@rollup/plugin-typescript":"^11.1.6","@types/express":"^4","@types/identity-obj-proxy":"^3","@typescript-eslint/eslint-plugin":"^5.35.1","@typescript-eslint/parser":"^5.35.1","babel-loader":"^8.3.0",eslint:"^8.0.1","eslint-config-prettier":"^8.5.0","eslint-config-standard-with-typescript":"^22.0.0","eslint-plugin-import":"^2.25.2","eslint-plugin-n":"^15.0.0","eslint-plugin-promise":"^6.0.0","eslint-plugin-react":"^7.31.0","eslint-plugin-storybook":"^0.6.10",express:"4","http-proxy-middleware":"^3.0.0","identity-obj-proxy":"^3.0.0","npm-run-all":"^4.1.5",prettier:"2.7.1","rollup-plugin-visualizer":"^6.0.1","socket.io":"^4.7.5","ts-node":"^10.9.2",typescript:"*",vite:"^4.1.1","vite-plugin-dts":"^4.3.0","vite-plugin-externalize-deps":"^0.9.0","vite-tsconfig-paths":"^5.1.4",vitest:"^0.34.6"},ln={access:"public",registry:"https://registry.npmjs.org/"},hn={"@glodon-aiot/apis":"^3.26.0-alpha.4",axios:"0.24.0",buffer:"^6.0.3",dayjs:"^1.11.13","js-base64":"^3.7.7","socket.io-client":"^4.7.5",uuid:"^11.1.0"},un={name:Gs,version:Qs,author:Xs,description:Ks,type:Js,sideEffects:Zs,keywords:en,files:tn,module:sn,main:nn,typings:rn,exports:an,license:on,scripts:cn,devDependencies:dn,"lint-staged":{"*.{js,css,md,jsx,less,ts,tsx,json}":"prettier --write"},publishConfig:ln,dependencies:hn},bt=new $("[BotClient] ");class fn{constructor(e,t,s=!0,o={analytics:{enabled:!1}}){y(this,"event",new et);y(this,"cvforceApi");y(this,"_applicationId");y(this,"_application",null);y(this,"_sessions",[]);y(this,"_activeSession");y(this,"_ready",!1);y(this,"_questionContextMaxLength",4e3);y(this,"_promptVariables",[]);y(this,"_localWorkspace");y(this,"_disconnectHost");if(this._token=e,this.lazyload=s,this.sdkConfigs=o,He(t),this._applicationId=Te(e).rid||exports.configuration.applicationId,!this._applicationId)throw"token is not vaild";this.cvforceApi=this.getService(),this.setupLocalWorkspace(),this.loadApplication().then(r=>{He(I(v({},t),{stream:t.stream===void 0?(r==null?void 0:r.type)===A.ApplicationTypes.Dialog||(r==null?void 0:r.type)===A.ApplicationTypes.Agent:t.stream})),this.event.emit("ready")})}setupLocalWorkspace(){var o,r;const e=(o=exports.configuration.builtinPlugins)==null?void 0:o.localFiles;if(!(e!=null&&e.enabled)){ut(void 0),qe();return}const t=[],s=(r=e.backend)!=null?r:"file-system-access";if(s!=="file-system-access"&&s!=="host-bridge")t.push(new Error(`[LocalFiles] 不支持的 backend:${e.backend}`));else{const n=Rs(exports.configuration.apiRoot,this.token,(c,a)=>bt.error(a));this._localWorkspace=new hi({applicationId:this._applicationId,config:e,store:li(),picker:s==="host-bridge"?null:void 0,transfer:tt(()=>this.cvforceApi,()=>n)}),ut(this._localWorkspace),s==="host-bridge"?this._disconnectHost=ks(this._localWorkspace):this._localWorkspace.restore()}t.push(...qe()),t.length&&Promise.resolve().then(()=>t.forEach(n=>this.event.emit("error",n)))}get localWorkspace(){return this._localWorkspace}checkReady(){if(!this.ready)throw Error("client is not ready.")}get ready(){return this._ready}set ready(e){this._ready=e}get questionContextMaxLength(){return this.checkReady(),this._questionContextMaxLength}get promptVariables(){return this.checkReady(),this._promptVariables}get knowledges(){var e;return this.checkReady(),(e=this._application)==null?void 0:e.arrange[0].knowledges}get sessions(){return this.checkReady(),this._sessions}set sessions(e){this.checkReady(),this._sessions=e,this.event.emit("sessions:updated",e)}loadApplication(){return u(this,null,function*(){var t,s,o,r,n;this._application=yield this.cvforceApi.getApplicationId(this._applicationId,{ui:(t=this.sdkConfigs.ui)==null?void 0:t.name,uiVersion:(s=this.sdkConfigs.ui)==null?void 0:s.version,sdkVersion:un.version}).then(c=>(typeof c.arrange[0].thinkingModeOpen!="boolean"&&(c.arrange[0].thinkingModeOpen=!0),typeof c.arrange[0].thinkingTextOpen!="boolean"&&(c.arrange[0].thinkingTextOpen=!0),I(v({},c),{arrange:[I(v({},c.arrange[0]),{recommendQuestionOpen:exports.configuration.loadRelatedQuesions&&c.arrange[0].recommendQuestionOpen})]})));const e=(n=(r=(o=this._application)==null?void 0:o.arrange)==null?void 0:r[0])==null?void 0:n.llmModel;return e&&(this._questionContextMaxLength=yield this.cvforceApi.getBaseModel(e).then(c=>c.maxModelLength)),this._promptVariables=yield Promise.all([this.cvforceApi.getPrompts(this._applicationId,{type:A.PromptVariableType.User}),this.cvforceApi.getPrompts(this._applicationId,{type:A.PromptVariableType.System})]).then(([c,a])=>[...c,...a]),this._ready=!0,this.event.emit("application:loaded"),this._application})}getService(){return this.cvforceApi?this.cvforceApi:ai(exports.configuration.apiRoot,this.token,(e,t)=>bt.error(t))}get token(){return this._token}set token(e){this.checkReady(),this._token=e,this.ready=!1;const t=Te(e).rid;this._applicationId!==t&&(this._applicationId=t,this._application=null,this.loadApplication().then(()=>{this.event.emit("ready")}),this.clean())}get applicationId(){return this._applicationId}get application(){return this.checkReady(),this._application}get activeSession(){var e;return this.checkReady(),((e=this._activeSession)==null?void 0:e.id)||""}set activeSession(e){this.checkReady(),this.loadSession(e).then(t=>{this._activeSession&&this._activeSession.id!==e&&this._activeSession.inactivate(),this._activeSession=t})}createSession(e,t,s,o,r){return u(this,null,function*(){const n=this;return new Promise((c,a)=>{const d=l=>u(this,null,function*(){if(l===A.ApplicationTypes.Agent)c(new Hs(e,t,s,o,r,n));else if(l===A.ApplicationTypes.Dialog)c(new Ys(e,t,s,o,r,n));else throw Error(`不支持的应用类型:${l}`)});if(this.ready){if(!this._application)throw Error("client is not ready");d(this._application.type)}else this.event.on("ready",()=>{if(!this._application)throw Error("_application is null");d(this._application.type)},!0)})})}getArtifacts(e){return u(this,null,function*(){var r,n;this.checkReady();const t=e||((r=this._activeSession)==null?void 0:r.id);if(!t)throw new Error("session id is not defined");const s=this._sessions.find(c=>c.id===t);if(s)return s.getArtifacts();const o=yield this.cvforceApi.getSessionArtifacts(this._applicationId,t);return(n=o==null?void 0:o.artifacts)!=null?n:[]})}getSessions(e){return u(this,null,function*(){return new Promise((t,s)=>{const o=()=>this.cvforceApi.listSessions(this._applicationId,e).then(r=>u(this,null,function*(){const n=[];for(const c of r){const a=this._sessions.find(d=>d.id===c.id);if(a)a.data=c,this._application?a.application=this._application:yield a.loadApplicationInfo(),n.push(a);else{const d=yield this.createSession(this.token,c.id,c,this.lazyload,this._application||void 0);n.push(d)}}if(e!=null&&e.pageSize){const c=[...this._sessions,...n],a=new Map;for(const d of c)a.set(d.id,d);return this.sessions=Array.from(a.values()),this.sessions}else return this.sessions=n,n}));if(this.ready){if(!this._application)throw Error("_application is null");t(o())}else this.event.on("ready",()=>{if(!this._application)throw Error("_application is null");t(o())},!0)})})}loadSession(e="",t){return u(this,null,function*(){this.checkReady();let s=this.sessions.find(o=>o.id===e);if(s||(s=yield this.createSession(this.token,e,t),this._sessions.push(s)),this._activeSession){if(this._activeSession===s)return s;this._activeSession.inactivate()}return s.id?(this._activeSession=s,yield s.activate()):s.addEventListener("data:loaded",()=>{this._activeSession!==s&&(s==null||s.activate(),this._activeSession=s)},!0),s})}reload(){return this.loadApplication().then(()=>u(this,null,function*(){return yield this.getSessions(),this.event.emit("ready"),this}))}reloadSession(e){return u(this,null,function*(){yield this.reload();let t=this._sessions.find(s=>s.id===e)||this._activeSession;if(!t){console.warn("reloadSession session failed.");return}return yield t.reload(),t})}setTop(e,t,s="top_time desc, sort_status desc, updated_at desc"){return u(this,null,function*(){let o=e?this._sessions.find(r=>r.id===e):this._activeSession;if(!o){console.warn("setTop session failed.");return}return yield o.setTop(t),this.getSessions({order:s})})}addEventListener(e,t,s=!1){if(typeof t!="function")throw Error("event listener is not a function");if(s){this.event.once(e,t);return}this.event.on(e,t)}removeEventListener(e,t){this.event.off(e,t)}removeSession(e,t){return u(this,null,function*(){this.checkReady();let s=-1;if(typeof e=="string"?s=this._sessions.findIndex(o=>o.id===e):s=this._sessions.findIndex(o=>o.id===e.id),s>-1){const o=this._sessions[s];t&&(yield o.delete()),this._sessions.splice(s,1)}else console.warn("session delete failed, session is not exist.")})}clean(){var e;(e=this._disconnectHost)==null||e.call(this),this._disconnectHost=void 0,this._sessions.forEach(t=>t.destroy()),this.sessions=[]}}class pn{constructor(e,t={},s){y(this,"code");y(this,"description","");y(this,"loaded",!1);y(this,"functions",{});this.code=e,t&&(this.functions=t)}fetchData(){this.description="描述",this.loaded=!0}checkFunctions(){}}function It(){return{kind:"directory",children:new Map}}class gn{constructor(e={},t="memory-workspace"){y(this,"root",It());this.displayName=t,Object.entries(e).forEach(([s,o])=>this.seed(s,o))}seed(e,t="",s=Date.now()){const o=e.split("/").filter(Boolean);if(e.endsWith("/")){this.resolveDirectory(o,!0);return}const r=o.pop();if(!r)return;const n=this.resolveDirectory(o,!0),c=typeof t=="string"?new TextEncoder().encode(t):t;n.children.set(r,{kind:"file",data:c,lastModified:s})}resolveDirectory(e,t=!1){let s=this.root;for(const o of e){let r=s.children.get(o);if(!r){if(!t)throw P("NotFoundError");r=It(),s.children.set(o,r)}if(r.kind!=="directory")throw P("TypeMismatchError");s=r}return s}resolveNode(e){const t=G(e),s=t.pop();if(s===void 0)return this.root;const o=this.resolveDirectory(t).children.get(s);if(!o)throw P("NotFoundError");return o}stat(e){return u(this,null,function*(){var o;const t=this.resolveNode(e),s=(o=G(e).pop())!=null?o:this.displayName;return t.kind==="directory"?{name:s,kind:"directory"}:{name:s,kind:"file",size:t.data.byteLength,lastModified:t.lastModified}})}listEntries(e,t){return u(this,null,function*(){M(t);const s=this.resolveDirectory(G(e));return Array.from(s.children.entries()).map(([o,r])=>r.kind==="directory"?{name:o,kind:"directory"}:{name:o,kind:"file",size:r.data.byteLength,lastModified:r.lastModified})})}readFile(e){return u(this,null,function*(){const t=this.resolveNode(e);if(t.kind!=="file")throw P("TypeMismatchError");return new Blob([t.data])})}writeFile(o,r){return u(this,arguments,function*(e,t,s={}){const n=G(e),c=n.pop();if(!c)throw P("TypeMismatchError");const a=this.resolveDirectory(n,s.createDirectories),d=a.children.get(c);if((d==null?void 0:d.kind)==="directory")throw P("TypeMismatchError");const l=[];let h=0;try{for(var _=Y(Ze(t)),m,b,T;m=!(b=yield _.next()).done;m=!1){const S=b.value;M(s.signal),l.push(S),h+=S.byteLength}}catch(b){T=[b]}finally{try{m&&(b=_.return)&&(yield b.call(_))}finally{if(T)throw T[0]}}M(s.signal);const f=new Uint8Array(h);let g=0;l.forEach(S=>{f.set(S,g),g+=S.byteLength}),a.children.set(c,{kind:"file",data:f,lastModified:Date.now()})})}}exports.AgentPlugin=pn;exports.BINARY_SNIFF_BYTES=Ve;exports.BUILTIN_TOOLS_PLUGIN_CODE=ue;exports.BUILTIN_TOOLS_PLUGIN_CODES=je;exports.BUILTIN_TOOL_SCHEMAS=Ai;exports.BotClient=fn;exports.DEFAULT_DOWNLOAD_URL_ALLOWLIST=Nt;exports.DEFAULT_IGNORED_DIRECTORIES=Pt;exports.DEFAULT_IGNORED_FILE_PATTERNS=Dt;exports.DEFAULT_LIMITS=_e;exports.FileSystemAccessAdapter=di;exports.KiB=Lt;exports.LIST_DIRECTORY_DEFAULT_LIMIT=Rt;exports.LIST_DIRECTORY_MAX_LIMIT=kt;exports.LOCAL_FILES_FUNCTION_CODES=ze;exports.LOCAL_FILES_PLUGIN_CODES=At;exports.LOCAL_FILE_TOOL_SCHEMAS=Ge;exports.LOCAL_PYTHON_FUNCTION_CODE=oe;exports.LOCAL_PYTHON_PLUGIN_CODES=St;exports.LOCAL_PYTHON_TOOL_SCHEMA=Ht;exports.LocalWorkspace=hi;exports.MemoryWorkspaceAdapter=gn;exports.MiB=pe;exports.PYTHON_DEFAULT_TIMEOUT_MS=Et;exports.PYTHON_MAX_ARGS=Tt;exports.PYTHON_MAX_TIMEOUT_MS=vi;exports.SDK_SENSITIVE_BASELINE=zt;exports.SEARCH_DEFAULT_DEPTH=Mt;exports.SEARCH_FUNCTION_CODES=Bt;exports.SEARCH_MAX_DEPTH=We;exports.Session=st;exports.TEXT_SEARCH_MAX_CONTEXT_LINES=Ot;exports.TEXT_SEARCH_MAX_FILES=xt;exports.TEXT_SEARCH_MAX_FILE_BYTES=Ft;exports.TEXT_SEARCH_MAX_LINE_CHARS=be;exports.TRANSFER_FILE_SIZE_LIMIT_MB=Ct;exports.TRANSFER_FUNCTION_CODES=qt;exports.ToolCode=w;exports.ToolError=p;exports.WORKSPACE_GRANT_ID=Q;exports.WRITE_FUNCTION_CODES=_i;exports.configure=He;exports.createDefaultSessionFileTransfer=tt;exports.createIndexedDbStore=li;exports.createLocalFilesPlugin=ii;exports.createMemoryStore=it;exports.getDownloadUrlAllowlist=Ke;exports.getRegisteredLocalFilesPluginCode=bs;exports.getRegisteredLocalPythonPluginCode=Is;exports.isDownloadUrlAllowed=ji;exports.resolveLocalFilesPluginCode=ri;exports.toToolError=Le;
|
|
372
|
+
`)}function vn(i,e,t,n=!1){return l(this,null,function*(){return i.progress({stage:"writing",loaded:0,total:t.byteLength,path:e}),yield i.adapter.writeFile(e,t,{createDirectories:n,signal:i.signal}),{path:e,hash:yield ve(t),size:t.byteLength}})}const bo=(i,e)=>l(exports,null,function*(){const t=G(i.path);if(be(e,t,"write"),!i.edits.length)throw new m(p.BadRequest,"参数 edits 不能为空。");const{bytes:n,hash:s}=yield jt(e,t);if(s!==i.expectedHash)throw ze(s,"expectedHash 与文件当前内容不一致,请重新读取文件后再修改。");const r=Gi(n),o=es(r?n.subarray(3):n),c=o.includes(`\r
|
|
373
|
+
`);let a=o;i.edits.forEach((h,u)=>{if(typeof(h==null?void 0:h.oldText)!="string"||!h.oldText||typeof h.newText!="string")throw new m(p.BadRequest,`第 ${u+1} 条修改无效:oldText 必须是非空字符串,newText 必须是字符串。`);const f=bi(h.oldText,c),y=bi(h.newText,c),_=_o(a,f);if(_===0)throw new m(p.Conflict,`第 ${u+1} 条修改的 oldText 在文件中不存在,请重新读取文件确认当前内容。`);if(_>1&&!h.replaceAll)throw new m(p.BadRequest,`第 ${u+1} 条修改的 oldText 在文件中出现了 ${_} 次,请补充上下文使其唯一,或设置 replaceAll。`);a=h.replaceAll?a.split(f).join(y):a.replace(f,()=>y)});const d=vo(a,r);if(d.byteLength>e.limits.maxWriteBytes)throw re(e.limits.maxWriteBytes,"修改后的内容");return yield e.requestApproval(t,{type:"text",before:o,after:a,created:!1}),yield wn(e,t,s),{data:yield vn(e,t,d)}}),Eo=(i,e)=>l(exports,null,function*(){const t=G(i.path);be(e,t,"write");const n=yield Be(e.adapter,t);if((n==null?void 0:n.kind)==="directory")throw new m(p.BadRequest,"目标是目录,不能写入文件。");let s,r;if(n){const a=yield jt(e,t);if(r=a.hash,!i.expectedHash)throw ze(r,"目标文件已存在,覆盖前需要提供 expectedHash(可通过 read_file 或 stat_file 获取)。");if(i.expectedHash!==r)throw ze(r,"expectedHash 与文件当前内容不一致,请重新读取文件后再写入。");s=new TextDecoder("utf-8").decode(a.bytes)}else if(!i.createDirectories){const a=mr(t),d=a?yield Be(e.adapter,a):{kind:"directory"};if(!d)throw new m(p.NotFound,"父目录不存在,可设置 createDirectories 自动创建。");if(d.kind!=="directory")throw new m(p.BadRequest,"父路径不是目录。")}const o=new TextEncoder().encode(i.content);if(o.byteLength>e.limits.maxWriteBytes)throw re(e.limits.maxWriteBytes,"写入内容");if(yield e.requestApproval(t,{type:"text",before:s,after:i.content,created:!n}),r)yield wn(e,t,r);else if(yield Be(e.adapter,t))throw new m(p.Conflict,"目标文件在确认期间被创建,本次写入已取消。请重新检查后再写入。");const c=yield vn(e,t,o,i.createDirectories);return{data:E(w({},c),{created:!n})}}),Io={list_directory:ro,read_file:ao,stat_file:lo,search_files:uo,search_text:fo,apply_patch:bo,write_file:Eo,upload_file:po,download_file:wo};class So{constructor(e,t){v(this,"remaining");v(this,"startedAt",0);v(this,"handle");this.onTimeout=t,this.remaining=e}resume(){this.handle!==void 0||this.remaining<=0||(this.startedAt=Date.now(),this.handle=setTimeout(()=>{this.handle=void 0,this.remaining=0,this.onTimeout()},this.remaining))}pause(){this.handle!==void 0&&(clearTimeout(this.handle),this.handle=void 0,this.remaining-=Date.now()-this.startedAt)}clear(){this.pause(),this.remaining=0}}function To(i,e){return $i.includes(e)?i.limits.transferTimeoutMs:Di.includes(e)?i.limits.searchTimeoutMs:i.limits.toolTimeoutMs}function xo(i){if(typeof i!="string")return i;try{return JSON.parse(i)}catch(e){throw new m(p.BadRequest,"参数不是合法的 JSON 对象。")}}function Ao(i){if(!i||typeof i!="object"||Array.isArray(i))return;const e=i;return(e.grantId===void 0||e.grantId===null||e.grantId==="")&&(e.grantId=we),e.grantId}function _n(i){return new Promise((e,t)=>{i.aborted&&t(U()),i.addEventListener("abort",()=>t(U()),{once:!0})})}function Lo(i){return w({code:i.code,message:i.message},i.data?{data:i.data}:{})}function ko(i,e,t,n,s){return l(this,null,function*(){var _,g,b,A,I,L,k,K;const r={requestId:s.requestId||ye.v4(),applicationId:s.applicationId||i.applicationId,sessionId:s.sessionId||"",pluginCode:s.pluginCode,functionCode:e,signal:s.signal},o={requestId:r.requestId,sessionId:r.sessionId,functionCode:e},c=new AbortController;let a=!1;const d=new So(To(i,e),()=>{a=!0,c.abort()}),h=()=>c.abort();(_=r.signal)==null||_.addEventListener("abort",h,{once:!0}),(g=r.signal)!=null&&g.aborted&&c.abort();let u=null,f,y=!1;try{const N=xo(t),S=Ao(N);S!=null&&pr(S);const M=Hi(N,mn[e].parameters),O=(b=M.path)!=null?b:M.destPath;if(typeof O=="string"&&(o.path=O),yield i.ready,c.signal.aborted)throw U();const P=i.adapter;if(!P)throw Et();if(u=i.acquireSlot(),!u)throw new m(p.TooManyRequests,"同时进行的文件操作过多,请稍后重试。");f=i.track(c),y=!0,i.emit("tool:start",w({},o)),d.resume();const ae={adapter:P,workspaceName:(A=i.displayName)!=null?A:P.displayName,limits:i.limits,sensitive:i.sensitive,downloadUrlAllowlist:i.downloadUrlAllowlist,allowWorkspaceWideTextSearch:i.allowWorkspaceWideTextSearch,transfer:i.transfer,fetch:i.fetch,context:E(w({},r),{signal:c.signal}),signal:c.signal,requestApproval:(Q,Ce)=>Ro(i,{approvalPath:Q,preview:Ce,context:r,functionCode:e,signal:c.signal,timer:d,base:o}),progress:Q=>i.emit("tool:progress",w(w({},o),Q))},ce=yield Promise.race([Io[e](M,ae),_n(c.signal)]),Ie={code:p.Ok,message:"ok",data:ce.data};ce.truncated&&(Ie.truncated=!0),(I=ce.warnings)!=null&&I.length&&(Ie.warnings=ce.warnings),i.emit("tool:finish",E(w({},o),{code:p.Ok})),n(Ie)}catch(N){let S=Ve(N);a?S=new m(p.Timeout,"操作超时,已中止。"):c.signal.aborted&&S.code!==p.Cancelled&&(S=U()),((L=S.data)==null?void 0:L.reason)==="workspace_not_granted"&&y&&i.handlePermissionLost(),S.code===p.Cancelled?i.emit("tool:cancelled",w({},o)):i.emit("tool:error",E(w({},o),{code:S.code,message:S.message,reason:(k=S.data)==null?void 0:k.reason})),n(Lo(S))}finally{d.clear(),(K=r.signal)==null||K.removeEventListener("abort",h),u==null||u(),f==null||f()}})}function Ro(i,e){return l(this,null,function*(){var c;const t=i.getApprovalHandler();if(!t)throw new m(p.Forbidden,"当前环境未提供操作确认能力,无法执行写入或传输操作。",{reason:"approval_unavailable"});if(e.signal.aborted)throw U();const n=new AbortController,s=()=>n.abort();e.signal.addEventListener("abort",s,{once:!0});const r={id:ye.v4(),requestId:e.context.requestId,sessionId:e.context.sessionId,functionCode:e.functionCode,path:e.approvalPath,workspaceName:(c=i.displayName)!=null?c:"",preview:e.preview,signal:n.signal};e.timer.pause(),i.emit("tool:approval-required",E(w({},e.base),{path:e.approvalPath,approvalId:r.id}));let o;try{const a=yield Promise.race([Promise.resolve().then(()=>t(r)),_n(n.signal),new Promise(d=>{o=setTimeout(()=>d(!1),i.limits.approvalTimeoutMs)})]);if(e.signal.aborted)throw U();if(a!==!0)throw new m(p.Forbidden,"用户拒绝了本次操作。",{reason:"user_rejected"})}catch(a){throw a instanceof m?a:new m(p.Forbidden,"操作确认失败,已取消本次操作。",{reason:"user_rejected"})}finally{clearTimeout(o),e.signal.removeEventListener("abort",s),n.abort(),e.timer.resume()}})}function Co({pluginCode:i,workspace:e}){const t={};return yt.forEach(n=>{t[n]=(s,r,o)=>{let c=!1;ko(e,n,s,d=>{if(!c){c=!0;try{r(d)}catch(h){console.error("[LocalFiles] callback failed",h)}}},E(w({},o),{pluginCode:i}))}}),{[i]:t}}function Ei(){return{kind:"directory",children:new Map}}class Mo{constructor(e={},t="memory-workspace"){v(this,"root",Ei());this.displayName=t,Object.entries(e).forEach(([n,s])=>this.seed(n,s))}seed(e,t="",n=Date.now()){const s=e.split("/").filter(Boolean);if(e.endsWith("/")){this.resolveDirectory(s,!0);return}const r=s.pop();if(!r)return;const o=this.resolveDirectory(s,!0),c=typeof t=="string"?new TextEncoder().encode(t):t;o.children.set(r,{kind:"file",data:c,lastModified:n})}resolveDirectory(e,t=!1){let n=this.root;for(const s of e){let r=n.children.get(s);if(!r){if(!t)throw x("NotFoundError");r=Ei(),n.children.set(s,r)}if(r.kind!=="directory")throw x("TypeMismatchError");n=r}return n}resolveNode(e){const t=$(e),n=t.pop();if(n===void 0)return this.root;const s=this.resolveDirectory(t).children.get(n);if(!s)throw x("NotFoundError");return s}stat(e){return l(this,null,function*(){var s;const t=this.resolveNode(e),n=(s=$(e).pop())!=null?s:this.displayName;return t.kind==="directory"?{name:n,kind:"directory"}:{name:n,kind:"file",size:t.data.byteLength,lastModified:t.lastModified}})}listEntries(e,t){return l(this,null,function*(){C(t);const n=this.resolveDirectory($(e));return Array.from(n.children.entries()).map(([s,r])=>r.kind==="directory"?{name:s,kind:"directory"}:{name:s,kind:"file",size:r.data.byteLength,lastModified:r.lastModified})})}readFile(e){return l(this,null,function*(){const t=this.resolveNode(e);if(t.kind!=="file")throw x("TypeMismatchError");return new Blob([t.data])})}writeFile(s,r){return l(this,arguments,function*(e,t,n={}){const o=$(e),c=o.pop();if(!c)throw x("TypeMismatchError");const a=this.resolveDirectory(o,n.createDirectories),d=a.children.get(c);if((d==null?void 0:d.kind)==="directory")throw x("TypeMismatchError");const h=[];let u=0;try{for(var _=V(bt(t)),g,b,A;g=!(b=yield _.next()).done;g=!1){const I=b.value;C(n.signal),h.push(I),u+=I.byteLength}}catch(b){A=[b]}finally{try{g&&(b=_.return)&&(yield b.call(_))}finally{if(A)throw A[0]}}C(n.signal);const f=new Uint8Array(u);let y=0;h.forEach(I=>{f.set(I,y),y+=I.byteLength}),a.children.set(c,{kind:"file",data:f,lastModified:Date.now()})})}createDirectory(e){return l(this,null,function*(){this.resolveDirectory($(e),!0)})}remove(n){return l(this,arguments,function*(e,t={}){const s=$(e),r=s.pop();if(r===void 0)throw x("InvalidModificationError");const o=this.resolveDirectory(s),c=o.children.get(r);if(!c)throw x("NotFoundError");if(c.kind==="directory"&&c.children.size>0&&!t.recursive)throw x("InvalidModificationError");o.children.delete(r)})}move(e,t){return l(this,null,function*(){const n=$(e),s=$(t),r=n.pop(),o=s.pop();if(r===void 0||o===void 0)throw x("InvalidModificationError");const c=this.resolveDirectory(n),a=c.children.get(r);if(!a)throw x("NotFoundError");const d=this.resolveDirectory(s);if(Bi(e,t))throw x("InvalidModificationError");const h=d.children.get(o);if(h&&(h.kind==="directory"||a.kind==="directory"))throw x("InvalidModificationError");c.children.delete(r),d.children.set(o,a)})}}exports.AgentPlugin=to;exports.BINARY_SNIFF_BYTES=_t;exports.BUILTIN_TOOLS_PLUGIN_CODE=Te;exports.BUILTIN_TOOLS_PLUGIN_CODES=wt;exports.BUILTIN_TOOL_SCHEMAS=Rt;exports.BotClient=eo;exports.DEFAULT_DOWNLOAD_URL_ALLOWLIST=Fi;exports.DEFAULT_IGNORED_DIRECTORIES=Ni;exports.DEFAULT_IGNORED_FILE_PATTERNS=Pi;exports.DEFAULT_LIMITS=De;exports.FileSystemAccessAdapter=ln;exports.KiB=xi;exports.LIST_DIRECTORY_DEFAULT_LIMIT=Li;exports.LIST_DIRECTORY_MAX_LIMIT=ki;exports.LOCAL_FILES_FUNCTION_CODES=yt;exports.LOCAL_FILES_PLUGIN_CODES=Ii;exports.LOCAL_FILE_TOOL_SCHEMAS=mn;exports.LOCAL_PYTHON_FUNCTION_CODE=Si;exports.LOCAL_PYTHON_PLUGIN_CODES=Ti;exports.LOCAL_PYTHON_TOOL_SCHEMA=no;exports.LocalWorkspace=pn;exports.MemoryWorkspaceAdapter=Mo;exports.MiB=Le;exports.PYTHON_DEFAULT_TIMEOUT_MS=Ln;exports.PYTHON_MAX_ARGS=Rn;exports.PYTHON_MAX_TIMEOUT_MS=kn;exports.SDK_SENSITIVE_BASELINE=Yi;exports.SEARCH_DEFAULT_DEPTH=Ri;exports.SEARCH_FUNCTION_CODES=Di;exports.SEARCH_MAX_DEPTH=vt;exports.Session=Ut;exports.TEXT_SEARCH_MAX_CONTEXT_LINES=Oi;exports.TEXT_SEARCH_MAX_FILES=Ci;exports.TEXT_SEARCH_MAX_FILE_BYTES=Mi;exports.TEXT_SEARCH_MAX_LINE_CHARS=$e;exports.TRANSFER_FILE_SIZE_LIMIT_MB=Ai;exports.TRANSFER_FUNCTION_CODES=$i;exports.ToolCode=p;exports.ToolError=m;exports.WORKSPACE_GRANT_ID=we;exports.WRITE_FUNCTION_CODES=Cn;exports.configure=ft;exports.createDefaultSessionFileTransfer=$t;exports.createIndexedDbStore=fn;exports.createLocalFilesPlugin=Co;exports.createMemoryStore=Bt;exports.getDownloadUrlAllowlist=Dt;exports.getRegisteredLocalFilesPluginCode=nr;exports.getRegisteredLocalPythonPluginCode=sr;exports.isDownloadUrlAllowed=vr;exports.resolveLocalFilesPluginCode=rn;exports.toToolError=Ve;
|