@rtc-agent/component 0.1.9-rc.1 → 0.1.9-rc.2
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/dist/assets/{shared-worker-DE3XeXaG.js → shared-worker-DgWfKSkP.js} +145 -145
- package/dist/{en-US-DZNGN4YL.js → en-US-zyAb-zK-.js} +1 -1
- package/dist/{index-BW-EmCDb.js → index-C6N7XSg9.js} +1 -1
- package/dist/{index-BnIf1Sm8.js → index-DHOyB0ST.js} +21 -22
- package/dist/index.js +1 -1
- package/dist/index.umd.js +1 -1
- package/package.json +5 -5
|
@@ -65622,7 +65622,7 @@ class P9 {
|
|
|
65622
65622
|
}
|
|
65623
65623
|
function LT(t) {
|
|
65624
65624
|
return new SharedWorker(
|
|
65625
|
-
"" + new URL("assets/shared-worker-
|
|
65625
|
+
"" + new URL("assets/shared-worker-DgWfKSkP.js", import.meta.url).href,
|
|
65626
65626
|
{
|
|
65627
65627
|
name: t == null ? void 0 : t.name
|
|
65628
65628
|
}
|
|
@@ -66170,14 +66170,13 @@ const Bo = class Bo {
|
|
|
66170
66170
|
* 清理失败的连接
|
|
66171
66171
|
*/
|
|
66172
66172
|
async _cleanupFailedConnection() {
|
|
66173
|
-
|
|
66174
|
-
if (e) {
|
|
66175
|
-
this._workerBridge === e && (this._workerBridge = void 0);
|
|
66173
|
+
if (this._workerBridge) {
|
|
66176
66174
|
try {
|
|
66177
|
-
await
|
|
66178
|
-
} catch (
|
|
66179
|
-
ga.debug("Cleanup after failed connection (non-critical):",
|
|
66175
|
+
await this._workerBridge.destroy();
|
|
66176
|
+
} catch (e) {
|
|
66177
|
+
ga.debug("Cleanup after failed connection (non-critical):", e);
|
|
66180
66178
|
}
|
|
66179
|
+
this._workerBridge = void 0;
|
|
66181
66180
|
}
|
|
66182
66181
|
this._layer = void 0;
|
|
66183
66182
|
}
|
|
@@ -66196,23 +66195,23 @@ const Bo = class Bo {
|
|
|
66196
66195
|
* Call this on logout or when auth is lost.
|
|
66197
66196
|
*/
|
|
66198
66197
|
async disconnect() {
|
|
66199
|
-
|
|
66200
|
-
if (
|
|
66201
|
-
this._layer = void 0;
|
|
66198
|
+
var e;
|
|
66199
|
+
if (this._layer) {
|
|
66202
66200
|
try {
|
|
66203
|
-
await
|
|
66204
|
-
} catch (
|
|
66205
|
-
ga.error("disconnect error:",
|
|
66201
|
+
await this._layer.getOffsetManager().reset(), await this._layer.close();
|
|
66202
|
+
} catch (r) {
|
|
66203
|
+
ga.error("disconnect error:", r);
|
|
66206
66204
|
}
|
|
66205
|
+
this._layer = void 0;
|
|
66207
66206
|
}
|
|
66208
|
-
if (
|
|
66209
|
-
|
|
66207
|
+
if (this._workerBridge) {
|
|
66208
|
+
(e = this._masterLock) == null || e.release(), this._masterLock = void 0;
|
|
66210
66209
|
try {
|
|
66211
|
-
await
|
|
66212
|
-
} catch (
|
|
66213
|
-
ga.error("WorkerBridge disconnect error:",
|
|
66210
|
+
await this._workerBridge.destroy();
|
|
66211
|
+
} catch (r) {
|
|
66212
|
+
ga.error("WorkerBridge disconnect error:", r);
|
|
66214
66213
|
}
|
|
66215
|
-
this._workerBridge
|
|
66214
|
+
this._workerBridge = void 0;
|
|
66216
66215
|
}
|
|
66217
66216
|
}
|
|
66218
66217
|
// ========== 连接状态统一接口 ==========
|
|
@@ -71633,7 +71632,7 @@ function Ij() {
|
|
|
71633
71632
|
QT || (QT = !0, yI());
|
|
71634
71633
|
}
|
|
71635
71634
|
const gI = ir("I18n"), Xt = "zh-CN", $r = ["en-US"], eE = {
|
|
71636
|
-
"en-US": async () => (await import("./en-US-
|
|
71635
|
+
"en-US": async () => (await import("./en-US-zyAb-zK-.js")).default
|
|
71637
71636
|
}, { getLocale: bI, setLocale: vI } = Y9({
|
|
71638
71637
|
sourceLocale: Xt,
|
|
71639
71638
|
targetLocales: $r,
|
|
@@ -76144,7 +76143,7 @@ let bs = class extends xr {
|
|
|
76144
76143
|
return this._modulesPromise || (this._modulesPromise = Promise.all([
|
|
76145
76144
|
import("./marked.esm-Dch69AxC.js"),
|
|
76146
76145
|
import("./purify.es-C-6FFqDW.js"),
|
|
76147
|
-
import("./index-
|
|
76146
|
+
import("./index-C6N7XSg9.js")
|
|
76148
76147
|
]).then(([t, e, r]) => ({
|
|
76149
76148
|
marked: t.marked,
|
|
76150
76149
|
DOMPurify: e.default,
|
|
@@ -79388,7 +79387,7 @@ let Xo = class extends xr {
|
|
|
79388
79387
|
this._lastParsedContent = r, this._modulesPromise || (this._modulesPromise = Promise.all([
|
|
79389
79388
|
import("./marked.esm-Dch69AxC.js"),
|
|
79390
79389
|
import("./purify.es-C-6FFqDW.js"),
|
|
79391
|
-
import("./index-
|
|
79390
|
+
import("./index-C6N7XSg9.js")
|
|
79392
79391
|
]).then(([c, p, f]) => ({
|
|
79393
79392
|
marked: c.marked,
|
|
79394
79393
|
DOMPurify: p.default,
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as s, D as t, E as n, F as o, a as r, R as i, S as d, b as l, c, d as u, e as F, f as g, h as m, i as p, j as E, l as R, o as S, p as A, v as T, w as f, k as h, m as v, z as w, n as C } from "./index-
|
|
1
|
+
import { C as s, D as t, E as n, F as o, a as r, R as i, S as d, b as l, c, d as u, e as F, f as g, h as m, i as p, j as E, l as R, o as S, p as A, v as T, w as f, k as h, m as v, z as w, n as C } from "./index-DHOyB0ST.js";
|
|
2
2
|
export {
|
|
3
3
|
s as CancelledError,
|
|
4
4
|
t as DEFAULT_SKILL_STATE,
|
package/dist/index.umd.js
CHANGED
|
@@ -3178,7 +3178,7 @@ Please consider using \`${n}\`${i}, or add @babel/plugin-transform-modules-commo
|
|
|
3178
3178
|
return (async () => {
|
|
3179
3179
|
${i}
|
|
3180
3180
|
})();
|
|
3181
|
-
`,c=new Function(...s,l);let d;const u=new Promise((h,m)=>{d=setTimeout(()=>{m(new RY(r))},r)});try{const h=c.call(void 0,...a);return await Promise.race([h,u])}finally{d!==void 0&&clearTimeout(d)}}async function qY(t,e,r){const n=FY(t,e,r),i=`/scripts/${t}.ts`;return await Kr.write(i,n,"overwrite"),i}async function hp(t){try{return{success:!0,data:await t()}}catch(e){return e instanceof Ed?{success:!1,error:e.message}:e instanceof SyntaxError?{success:!1,error:e.message}:{success:!1,error:e instanceof Error?e.message:String(e)}}}function hs(t,e){const r=t[e];if(r==null)return null;if(typeof r!="string")throw new TypeError(`Parameter '${e}' must be a string, got ${typeof r}`);return r}function mp(t,e){const r=t[e];if(r==null)return null;if(typeof r=="number"&&!isNaN(r))return r;if(typeof r=="string"){const n=Number(r);if(!isNaN(n))return n}throw new TypeError(`Parameter '${e}' must be a number, got ${typeof r}`)}const pD=["overwrite","append","create-new"];function $Y(t){return typeof t=="string"&&pD.includes(t)}class GY{constructor(){mr(this,"name","ls");mr(this,"description","List directory contents")}async execute(e){const r=hs(e,"path")||"/";return hp(()=>Kr.ls(r))}}class jY{constructor(){mr(this,"name","read");mr(this,"description","Read file contents")}async execute(e){const r=hs(e,"path");if(!r)return{success:!1,error:"path is required"};const n=mp(e,"offset")??void 0,i=mp(e,"limit")??void 0;return hp(()=>Kr.read(r,n,i))}}class VY{constructor(){mr(this,"name","write");mr(this,"description","Write to file")}async execute(e){const r=hs(e,"path");if(!r)return{success:!1,error:"path is required"};const n=e.content||"",i=e.mode??"overwrite";return $Y(i)?hp(async()=>({totalChars:await Kr.write(r,n,i),path:r})):{success:!1,error:`Invalid mode '${i}'. Must be one of: ${pD.join(", ")}`}}}class YY{constructor(){mr(this,"name","find");mr(this,"description","Find files by pattern")}async execute(e){const r=hs(e,"pattern");if(!r)return{success:!1,error:"pattern is required"};const n=hs(e,"path")||"/";return hp(()=>Kr.find(r,n))}}class zY{constructor(){mr(this,"name","grep");mr(this,"description","Search file contents")}async execute(e){const r=hs(e,"pattern");if(!r)return{success:!1,error:"pattern is required"};const n=hs(e,"path")||"/",i=e.case_sensitive||!1,s=mp(e,"max_results")??100;return hp(()=>Kr.grep(r,n,i,s))}}class fD{constructor(e){mr(this,"name","script");mr(this,"description","Save or execute scripts. Actions: save (save script to /scripts/), run (execute saved script), eval (execute inline code)");mr(this,"rtcAgent");this.rtcAgent=e??null}async execute(e){let r=hs(e,"action");return r||(r="eval"),r==="save"?this._saveScript(e):r==="run"?this._runScript(e):r==="eval"?this._evalScript(e):{success:!1,error:`Unknown action: ${r}. Use save, run, or eval.`}}async _saveScript(e){const r=hs(e,"name");if(!r)return{success:!1,error:"name is required for save action"};const n=hs(e,"code");if(!n)return{success:!1,error:"code is required for save action"};const i=hs(e,"description")||void 0;try{dD(n,r)}catch(s){return s instanceof Error&&"isScriptCompileError"in s?{success:!1,error:`Script syntax check failed: ${s.message}`}:{success:!1,error:`Script syntax check failed: ${s instanceof Error?s.message:String(s)}`}}try{return{success:!0,data:{path:await qY(r,n,i),name:r}}}catch(s){return{success:!1,error:`Failed to save script: ${s instanceof Error?s.message:String(s)}`}}}async _runScript(e){const r=hs(e,"name");if(!r)return{success:!1,error:"name is required for run action"};const n=e.params||{},i=mp(e,"timeout")??3e4,s=hs(e,"title")??void 0;return this._executeCode(r,n,i,void 0,s)}async _evalScript(e){const r=hs(e,"code");if(!r)return{success:!1,error:"code is required for eval action"};const n=e.params||{},i=mp(e,"timeout")??3e4,s=hs(e,"title")??void 0;return this._executeCode(void 0,n,i,r,s)}async _executeCode(e,r,n,i,s){if(!this.rtcAgent)return{success:!1,error:"rtcAgent not initialized. Pass rtcAgent to ScriptTool constructor."};try{let a;if(i!==void 0)a=i;else{const C=`/scripts/${e}.ts`,x=await Kr.read(C);a=BY(x).code}const l={logs:[],warns:[],errors:[]},c=PY(this.rtcAgent,r,l,s||void 0),d=performance.now(),u=await UY(a,c,n,e),h=Math.round(performance.now()-d),m={};e&&(m.name=e),u!==void 0&&(m.result=u);const _=100;return l.logs.length>0&&(m.logs=l.logs.slice(0,_)),l.warns.length>0&&(m.warnings=l.warns.slice(0,_)),l.errors.length>0&&(m.errors=l.errors.slice(0,_)),m.duration_ms=h,{success:!0,data:m}}catch(a){return a instanceof Error&&"isScriptTimeout"in a?{success:!1,error:a.message}:a instanceof Error&&"isScriptCompileError"in a?{success:!1,error:`Script compile error: ${a.message}`}:{success:!1,error:`Script execution failed: ${a instanceof Error?a.message:String(a)}`}}}}function HY(t){return[new GY,new jY,new VY,new YY,new zY,new fD(t)]}class WY{constructor(e){mr(this,"tools",new Map);const r=HY(e);for(const n of r)this.register(n)}setRtcAgent(e){this.register(new fD(e))}register(e){this.tools.set(e.name,e)}get(e){return this.tools.get(e)}has(e){return this.tools.has(e)}getToolNames(){return Array.from(this.tools.keys())}async execute(e,r){const n=this.tools.get(e);if(!n)throw new Error(`Tool not found: ${e}`);return n.execute(r)}}const hD=new WY,xi=pr("RtcProcessor"),KY=1e3,mD=10;class QY{constructor(e){mr(this,"persistence");mr(this,"processing",!1);mr(this,"pendingCheck",!1);mr(this,"retryCountMap",new Map);mr(this,"mode","edit");mr(this,"confirmDialog");mr(this,"askUserDialog");mr(this,"master");mr(this,"_lastSilentlySkippedRtcId");this.persistence=e}setMode(e){this.mode=e}getMode(){return this.mode}setConfirmDialog(e){this.confirmDialog=e}setAskUserDialog(e){this.askUserDialog=e}setMaster(e){this.master=e}_isMasterAllowed(){return this.master===void 0||this.master.isMaster}async onRtcUpdate(){if(xi.debug("onRtcUpdate called, processing:",this.processing),this.processing){this.pendingCheck=!0;return}await this.processLoop()}async processLoop(){if(!this._isMasterAllowed()){xi.debug("processLoop: not master, skipping");return}this.processing=!0,xi.debug("processLoop started"),this._lastSilentlySkippedRtcId=void 0;try{for(;;){this.pendingCheck=!1;const e=await this.persistence.getNextRtcToProcess(void 0);if(!e){if(xi.debug("processLoop: no more RTC to process, exiting"),this.pendingCheck)continue;break}if(e.client_id===this._lastSilentlySkippedRtcId){xi.warn(`processLoop: RTC ${e.client_id} returned again after silent skip, exiting loop to prevent infinite retry`);break}xi.debug("processing RTC:",e.client_id,"tool:",e.tool_name,"sync_status:",e.sync_status);try{await this.processOne(e),xi.debug("processOne completed successfully")}catch(r){xi.error("processOne failed:",r);const n=r instanceof Error?r.message:String(r);if(n.includes("connection")||n.includes("disconnected")){xi.warn("connection error detected, exiting processLoop");break}await this.sleep(KY)}}}finally{this.processing=!1,xi.debug("processLoop finished")}}async processOne(e){if(e.sync_status==="failed"){const r=this.retryCountMap.get(e.client_id)||0;if(r>=mD){xi.error(`RTC ${e.client_id} exceeded max submit retry count (${mD}), abandoning. The RTC remains in sync_status='failed' and will be retried on the next onRtcUpdate cycle.`),this.retryCountMap.delete(e.client_id),this._lastSilentlySkippedRtcId=e.client_id;return}const n=this.calculateBackoff(r);await this.sleep(n);try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:e.status==="completed",result:e.result,error:e.error_message}),this.retryCountMap.delete(e.client_id)}catch(i){throw this.retryCountMap.set(e.client_id,r+1),i}}else{const r=e.tool_name;if(r==="ask_user"){await this.processAskUser(e);return}const n=L5.needsConfirm(r,this.mode);let i=!0;if(n&&(i=await this.showConfirmDialog(e)),!i){try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User denied"})}catch(c){xi.error("submitRtcResult (denied) failed:",c)}return}let s,a=!0,l;try{const c=e.parameters||{},d=await hD.execute(r,c);s=d.data,d.success||(a=!1,l=d.error)}catch(c){a=!1,l=c instanceof Error?c.message:String(c)}try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:a,result:s,error:l})}catch(c){xi.error("submitRtcResult failed:",c)}}}async processAskUser(e){if(!this.askUserDialog){xi.warn("askUserDialog not set, defaulting to reject");try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User declined to answer questions"})}catch(n){xi.error("submitRtcResult (ask_user no dialog) failed:",n)}return}let r;try{r=await this.askUserDialog(e)}catch(n){xi.error("askUserDialog threw:",n);try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:n instanceof Error?n.message:String(n)})}catch(i){xi.error("submitRtcResult (ask_user error) failed:",i)}return}try{r===null?await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User declined to answer questions"}):await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!0,result:r})}catch(n){xi.error("submitRtcResult (ask_user) failed:",n)}}calculateBackoff(e){return Math.min(1e3*Math.pow(2,e),3e4)}sleep(e){return new Promise(r=>setTimeout(r,e))}async showConfirmDialog(e){return this.confirmDialog?this.confirmDialog(e):(xi.warn("confirmDialog not set, defaulting to reject"),!1)}}function gD(t){return new SharedWorker(""+(typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/assets/shared-worker-DE3XeXaG.js").href:new URL("assets/shared-worker-DE3XeXaG.js",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),{name:t==null?void 0:t.name})}const Qa=pr("WorkerBridge");function XY(t){const e=t.toString(),r=e.match(/new URL\(\s*(["'`])([^"'`]+)\1/);if(r)return r[2];const n=e.match(/new SharedWorker\(\s*(["'`])([^"'`]+)\1/);if(n)return n[2];throw new Error("[WorkerBridge] Cannot extract worker URL from factory. Source: "+e.slice(0,300))}const oo=class oo{constructor(e){this._auth=e,this._worker=null,this._core=null,this._initialized=!1,this._connectionListeners=new Set,this._callbacks={onUIUpdate:r=>{gf().publish(r)},requestToken:async()=>{const r=this._auth.getAccessToken();if(!r)throw new Error("[WorkerBridge] no access token available");return r},requestTokenRefresh:()=>this._auth.handleTokenExpired(),onConnectionStateChange:r=>{for(const n of this._connectionListeners)try{n(r)}catch(i){Qa.error("connection listener error:",i)}}},this._proxiedCallbacks=RA(this._callbacks)}async initWorker(){let e=null;for(let r=0;r<=oo.MAX_INIT_RETRIES;r++)try{r>0&&(Qa.warn(`Retrying worker initialization (attempt ${r+1}/${oo.MAX_INIT_RETRIES+1})...`),await this._delay(oo.INIT_RETRY_DELAY_MS*r)),await this._initWorkerOnce(),await this._verifyWorkerAlive();return}catch(n){e=n instanceof Error?n:new Error(String(n)),Qa.error(`Worker initialization attempt ${r+1} failed:`,e.message),this._cleanupFailedWorker()}throw new Error(`[WorkerBridge] Failed to initialize SharedWorker after ${oo.MAX_INIT_RETRIES+1} attempts: ${e==null?void 0:e.message}`)}async _initWorkerOnce(){const e=XY(gD),r=typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:as&&as.tagName.toUpperCase()==="SCRIPT"&&as.src||new URL("index.umd.js",document.baseURI).href,n=new URL(e,r).href,i=window.location.origin;let s;try{s=new URL(n).origin}catch(l){Qa.debug("Failed to parse worker URL origin, assuming same-origin:",l),s=i}const a=s!==i;if(Qa.info("worker init:",{workerUrl:n,pageOrigin:i,workerOrigin:s,isCrossOrigin:a}),!a)this._worker=gD();else{let l;try{const u=await fetch(n,{cache:"no-store"});if(!u.ok)throw new Error(`HTTP ${u.status} ${u.statusText}`);l=await u.text()}catch(u){throw new Error(`[WorkerBridge] failed to fetch worker script from ${n}: ${u instanceof Error?u.message:u}`)}const c=new Blob([l],{type:"application/javascript"}),d=URL.createObjectURL(c);try{this._worker=new SharedWorker(d,{name:"rtc-agent-worker",type:"module"})}finally{URL.revokeObjectURL(d)}}this._core=wA(this._worker.port),this._worker.onerror=l=>{Qa.error("SharedWorker error:",{message:l.message,filename:l.filename,lineno:l.lineno,colno:l.colno,error:l.error})},this._worker.port.onmessageerror=l=>{Qa.error("port message error:",l)}}async _verifyWorkerAlive(){if(!this._core)throw new Error("[WorkerBridge] No core available for verification");let e;const r=new Promise((n,i)=>{e=setTimeout(()=>i(new Error("Worker verification timed out")),oo.VERIFICATION_TIMEOUT_MS)});try{const n=await Promise.race([this._core.ping(),r]);if(n!=="pong")throw new Error(`Unexpected ping response: ${n}`);Qa.info("Worker verification successful")}catch(n){throw new Error(`[WorkerBridge] Worker verification failed: ${n instanceof Error?n.message:"unknown error"}`)}finally{e!==void 0&&clearTimeout(e)}}_cleanupFailedWorker(){if(this._worker){try{this._worker.port.close()}catch{}this._worker=null}this._core=null}_delay(e){return new Promise(r=>setTimeout(r,e))}get core(){return this._core}async init(e){if(this._initialized){Qa.warn("already initialized");return}if(!this._worker||!this._core)throw new Error("[WorkerBridge] init() called before initWorker()");this._worker.port.start(),await this._core.init(e),await this._core.registerCallback(this._proxiedCallbacks),this._initialized=!0}async destroy(){if(this._initialized&&!(!this._worker||!this._core)){try{await this._core.unregisterCallback(this._proxiedCallbacks)}catch(e){Qa.warn("unregisterCallback failed:",e)}this._connectionListeners.clear(),this._worker.port.close(),this._initialized=!1}}async getConnectionState(){return this._core.getConnectionState()}onConnectionStateChange(e){return this._connectionListeners.add(e),()=>{this._connectionListeners.delete(e)}}installVirtualFSProxy(){const e=this._core;Kr.read=(r,n,i)=>e.virtualFSRead(r,n,i),Kr.write=(r,n,i="overwrite",s)=>e.virtualFSWrite(r,n,i,s),Kr.ls=r=>e.virtualFSLs(r),Kr.find=(r,n)=>e.virtualFSFind(r,n),Kr.grep=(r,n,i,s)=>e.virtualFSGrep(r,n,i,s),Kr.queryByType=r=>e.virtualFSQueryByType(r),Kr.exists=r=>e.virtualFSExists(r),Kr.remove=r=>e.virtualFSRemove(r)}};oo.MAX_INIT_RETRIES=3,oo.INIT_RETRY_DELAY_MS=1e3,oo.VERIFICATION_TIMEOUT_MS=5e3;let WE=oo;const gp=pr("MasterLock");class JY{constructor(e){this._isMaster=!1,this._controlled=!1,this._lockName=`rtc-agent-master-${e}`}get isMaster(){return this._isMaster}get isControlled(){return this._controlled}async acquire(){var e;if(this._controlled){gp.warn("already acquiring/acquired, ignoring");return}if(!this._isWebLocksAvailable()){gp.warn("Web Locks API not available, acting as always-master"),this._isMaster=!0,this._controlled=!0,(e=this.onAcquire)==null||e.call(this);return}this._controlled=!0,this._abortController=new AbortController,navigator.locks.request(this._lockName,{signal:this._abortController.signal},async()=>{var r,n;this._isMaster=!0,gp.info("acquired lock → became Master"),(r=this.onAcquire)==null||r.call(this),await new Promise(i=>{this._releaseResolve=i}),this._isMaster=!1,gp.info("released lock → lost Master"),(n=this.onRelease)==null||n.call(this)}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||gp.error("lock request error:",r)})}release(){this._controlled&&(this._releaseResolve&&(this._releaseResolve(),this._releaseResolve=void 0),!this._isMaster&&this._abortController&&this._abortController.abort(),this._controlled=!1)}_isWebLocksAvailable(){return typeof navigator<"u"&&"locks"in navigator}}const Pa=pr("PersistenceController");function eae(t){return t}class ZY{constructor(e){this._core=e}async connect(){Pa.info("connect() called"),await this._core.connect(),Pa.info("connect() completed, worker state:",await this._core.getConnectionState())}disconnect(){this._core.disconnect()}async reconnect(){await this._core.reconnect()}async listSessions(e,r){return this._core.listSessions(e,r)}async getSession(e){return this._core.getSession(e)}async listMessages(e,r,n,i){return this._core.listMessages(e,r,n,i)}async getMessage(e){return this._core.getMessage(e)}async listRtc(e,r,n){return this._core.listRtc(e,r,n)}async getNextRtcToProcess(e){return this._core.getNextRtcToProcess(e)}async sendMessage(e){return this._core.sendMessage(e)}async insertLocalMessage(e){return this._core.insertLocalMessage(e)}async stopTurn(e){return this._core.stopTurn(e)}async closeSession(e){return this._core.closeSession(e)}async openSession(e){return this._core.openSession(e)}async compactSession(e,r){return this._core.compactSession(e,r)}async submitRtcResult(e){return this._core.submitRtcResult(e)}async forkSession(e){return this._core.forkSession(e)}async deleteSession(e){return this._core.deleteSession(e)}async updateSessionTitle(e,r){return this._core.updateSessionTitle(e,r)}async close(){await this._core.close()}async flushAll(){return this._core.flushAll()}async initializeVirtualFS(e){await this._core.initializeVirtualFS(e??{})}getClient(){throw new Error("[WorkerPersistenceAdapter] getClient() is not available. Use PersistenceController.onConnectionStateChange() instead.")}getOffsetManager(){return{reset:()=>this._core.resetOffset()}}getEntityRepository(){throw new Error("[WorkerPersistenceAdapter] getEntityRepository() is not available.")}}const Nl=class Nl{constructor(e,r){this._auth=r,e.addController(this)}get layer(){return this._layer}get isConnected(){return this._layer!==void 0}get workerBridge(){return this._workerBridge}get masterLock(){return this._masterLock}hostConnected(){}hostDisconnected(){this.disconnect()}async connect(){if(this._layer)return;if(this._connecting)return Pa.debug("connect() called while already connecting, awaiting existing attempt"),this._connecting;const e=vA(),r=this._auth.state.userId;if(!r)throw new Error("[PersistenceController] connect() called without userId; refusing to open a shared database");const n={databaseName:`rtc-agent-${r}`,deviceId:e,client:{endpoint:Qo.wsEndpoint,getToken:()=>{const i=this._auth.getAccessToken();if(!i)throw Pa.warn("getToken: no access token available"),new Error("No access token available");return i},onTokenExpired:()=>this._auth.handleTokenExpired(),deviceId:e,userId:r}};return this._connecting=this._connectWorker(n).finally(()=>{this._connecting=void 0}),this._connecting}async _connectWorker(e){let r=null;for(let n=0;n<=Nl.MAX_CONNECT_RETRIES;n++)try{n>0&&(Pa.warn(`Retrying connection (attempt ${n+1}/${Nl.MAX_CONNECT_RETRIES+1})...`),await this._delay(Nl.CONNECT_RETRY_DELAY_MS*n)),await this._connectWorkerOnce(e);return}catch(i){r=i instanceof Error?i:new Error(String(i)),Pa.error(`Connection attempt ${n+1} failed:`,r.message),await this._cleanupFailedConnection()}throw new Error(`[PersistenceController] Failed to connect after ${Nl.MAX_CONNECT_RETRIES+1} attempts: ${r==null?void 0:r.message}`)}async _connectWorkerOnce(e){this._workerBridge=new WE(this._auth),await this._workerBridge.initWorker();const{getToken:r,onTokenExpired:n,...i}=e.client,s={...e,client:i};await this._workerBridge.init(s),this._workerBridge.installVirtualFSProxy(),this._layer=new ZY(this._workerBridge.core),await this._workerBridge.core.connect();const a=this._auth.state.userId;a&&(this._masterLock=new JY(a),this._masterLock.onAcquire=()=>{Pa.info("this Tab became Master")},this._masterLock.onRelease=()=>{Pa.info("this Tab lost Master")},this._masterLock.acquire())}async _cleanupFailedConnection(){const e=this._workerBridge;if(e){this._workerBridge===e&&(this._workerBridge=void 0);try{await e.destroy()}catch(r){Pa.debug("Cleanup after failed connection (non-critical):",r)}}this._layer=void 0}_delay(e){return new Promise(r=>setTimeout(r,e))}async disconnect(){const e=this._layer,r=this._workerBridge,n=this._masterLock;if(e){this._layer=void 0;try{await e.getOffsetManager().reset(),await e.close()}catch(i){Pa.error("disconnect error:",i)}}if(r){n==null||n.release(),this._masterLock=void 0;try{await r.destroy()}catch(i){Pa.error("WorkerBridge disconnect error:",i)}this._workerBridge===r&&(this._workerBridge=void 0)}}async getConnectionState(){return this._workerBridge?this._workerBridge.getConnectionState():"disconnected"}onConnectionStateChange(e){return this._workerBridge?this._workerBridge.onConnectionStateChange(e):()=>{}}};Nl.MAX_CONNECT_RETRIES=2,Nl.CONNECT_RETRY_DELAY_MS=2e3;let KE=Nl;const _D=pr("EventBus");class yD{constructor(){this.handlers=new Map}on(e,r){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(r),()=>{var n;(n=this.handlers.get(e))==null||n.delete(r)}}once(e,r){const n=i=>(this.off(e,n),r(i));return this.on(e,n)}off(e,r){var n;(n=this.handlers.get(e))==null||n.delete(r)}emit(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n);for(const s of i)try{s(r)}catch(a){_D.error(`Handler error for event '${e}':`,a)}}async emitAsync(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n),s=[];for(const a of i)s.push(Promise.resolve(a(r)).catch(l=>{_D.error(`Async handler error for event '${e}':`,l)}));await Promise.all(s)}async emitAsyncStrict(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n),s=[];for(const a of i)s.push(Promise.resolve(a(r)));await Promise.all(s)}clearAll(){this.handlers.clear()}clearEvent(e){this.handlers.delete(e)}}function ez(){return new yD}const ol=ez(),tz=pr("SkillController");class bD{constructor(e,r){this._registry=null,this._config={},this._unsubscribes=[],this._host=e,this._config=r||{},e.addController(this)}get value(){return{registry:this._registry}}get actions(){return{getRegistry:()=>this._registry,setRegistry:e=>{this._registry=e,this._host.requestUpdate(),this._bridgeToolRegistry(e)}}}_bridgeToolRegistry(e){const r=new Proxy({callFunction:(n,i)=>e.execute(n,i),readFile:n=>Kr.read(n),writeFile:(n,i)=>Kr.write(n,i).then(()=>{}),listDir:n=>Kr.ls(n)},{get(n,i){return i in n?n[i]:e[i]}});hD.setRtcAgent(r),tz.info("rtcAgent API bridged to ToolRegistry")}setConfig(e){this._config=e}hostConnected(){this._subscribeEvents()}hostDisconnected(){for(const e of this._unsubscribes)e();this._unsubscribes=[]}_subscribeEvents(){for(const n of this._unsubscribes)n();this._unsubscribes=[];const e=ol.on("ui:toast",n=>{this._config.onToast&&this._config.onToast(n.message,n.type)});this._unsubscribes.push(e);const r=ol.on("ui:confirm-request",n=>{this._config.onConfirmRequest&&this._config.onConfirmRequest(n.requestId,n.path,n.message)});this._unsubscribes.push(r)}respondToConfirm(e,r){ol.emit("ui:confirm-response",{requestId:e,confirmed:r})}}class rz{constructor(e){this._toasts=[],this._timers=new Map,this._host=e,this._host.addController(this),this.actions={show:(r,n="info",i)=>this._show(r,n,i),remove:r=>this._remove(r)}}get toasts(){return this._toasts}hostConnected(){}hostDisconnected(){for(const e of this._timers.values())clearTimeout(e);this._timers.clear()}_show(e,r,n){const i=Date.now()+Math.random();this._toasts=[...this._toasts,{id:i,message:e,type:r,action:n}],this._host.requestUpdate();const s=r==="error"?0:r==="success"?2e3:2500;if(s>0){const a=setTimeout(()=>this._remove(i),s);this._timers.set(i,a)}}_remove(e){const r=this._timers.get(e);r!==void 0&&(clearTimeout(r),this._timers.delete(e)),this._toasts=this._toasts.filter(n=>n.id!==e),this._host.requestUpdate()}}/**
|
|
3181
|
+
`,c=new Function(...s,l);let d;const u=new Promise((h,m)=>{d=setTimeout(()=>{m(new RY(r))},r)});try{const h=c.call(void 0,...a);return await Promise.race([h,u])}finally{d!==void 0&&clearTimeout(d)}}async function qY(t,e,r){const n=FY(t,e,r),i=`/scripts/${t}.ts`;return await Kr.write(i,n,"overwrite"),i}async function hp(t){try{return{success:!0,data:await t()}}catch(e){return e instanceof Ed?{success:!1,error:e.message}:e instanceof SyntaxError?{success:!1,error:e.message}:{success:!1,error:e instanceof Error?e.message:String(e)}}}function hs(t,e){const r=t[e];if(r==null)return null;if(typeof r!="string")throw new TypeError(`Parameter '${e}' must be a string, got ${typeof r}`);return r}function mp(t,e){const r=t[e];if(r==null)return null;if(typeof r=="number"&&!isNaN(r))return r;if(typeof r=="string"){const n=Number(r);if(!isNaN(n))return n}throw new TypeError(`Parameter '${e}' must be a number, got ${typeof r}`)}const pD=["overwrite","append","create-new"];function $Y(t){return typeof t=="string"&&pD.includes(t)}class GY{constructor(){mr(this,"name","ls");mr(this,"description","List directory contents")}async execute(e){const r=hs(e,"path")||"/";return hp(()=>Kr.ls(r))}}class jY{constructor(){mr(this,"name","read");mr(this,"description","Read file contents")}async execute(e){const r=hs(e,"path");if(!r)return{success:!1,error:"path is required"};const n=mp(e,"offset")??void 0,i=mp(e,"limit")??void 0;return hp(()=>Kr.read(r,n,i))}}class VY{constructor(){mr(this,"name","write");mr(this,"description","Write to file")}async execute(e){const r=hs(e,"path");if(!r)return{success:!1,error:"path is required"};const n=e.content||"",i=e.mode??"overwrite";return $Y(i)?hp(async()=>({totalChars:await Kr.write(r,n,i),path:r})):{success:!1,error:`Invalid mode '${i}'. Must be one of: ${pD.join(", ")}`}}}class YY{constructor(){mr(this,"name","find");mr(this,"description","Find files by pattern")}async execute(e){const r=hs(e,"pattern");if(!r)return{success:!1,error:"pattern is required"};const n=hs(e,"path")||"/";return hp(()=>Kr.find(r,n))}}class zY{constructor(){mr(this,"name","grep");mr(this,"description","Search file contents")}async execute(e){const r=hs(e,"pattern");if(!r)return{success:!1,error:"pattern is required"};const n=hs(e,"path")||"/",i=e.case_sensitive||!1,s=mp(e,"max_results")??100;return hp(()=>Kr.grep(r,n,i,s))}}class fD{constructor(e){mr(this,"name","script");mr(this,"description","Save or execute scripts. Actions: save (save script to /scripts/), run (execute saved script), eval (execute inline code)");mr(this,"rtcAgent");this.rtcAgent=e??null}async execute(e){let r=hs(e,"action");return r||(r="eval"),r==="save"?this._saveScript(e):r==="run"?this._runScript(e):r==="eval"?this._evalScript(e):{success:!1,error:`Unknown action: ${r}. Use save, run, or eval.`}}async _saveScript(e){const r=hs(e,"name");if(!r)return{success:!1,error:"name is required for save action"};const n=hs(e,"code");if(!n)return{success:!1,error:"code is required for save action"};const i=hs(e,"description")||void 0;try{dD(n,r)}catch(s){return s instanceof Error&&"isScriptCompileError"in s?{success:!1,error:`Script syntax check failed: ${s.message}`}:{success:!1,error:`Script syntax check failed: ${s instanceof Error?s.message:String(s)}`}}try{return{success:!0,data:{path:await qY(r,n,i),name:r}}}catch(s){return{success:!1,error:`Failed to save script: ${s instanceof Error?s.message:String(s)}`}}}async _runScript(e){const r=hs(e,"name");if(!r)return{success:!1,error:"name is required for run action"};const n=e.params||{},i=mp(e,"timeout")??3e4,s=hs(e,"title")??void 0;return this._executeCode(r,n,i,void 0,s)}async _evalScript(e){const r=hs(e,"code");if(!r)return{success:!1,error:"code is required for eval action"};const n=e.params||{},i=mp(e,"timeout")??3e4,s=hs(e,"title")??void 0;return this._executeCode(void 0,n,i,r,s)}async _executeCode(e,r,n,i,s){if(!this.rtcAgent)return{success:!1,error:"rtcAgent not initialized. Pass rtcAgent to ScriptTool constructor."};try{let a;if(i!==void 0)a=i;else{const C=`/scripts/${e}.ts`,x=await Kr.read(C);a=BY(x).code}const l={logs:[],warns:[],errors:[]},c=PY(this.rtcAgent,r,l,s||void 0),d=performance.now(),u=await UY(a,c,n,e),h=Math.round(performance.now()-d),m={};e&&(m.name=e),u!==void 0&&(m.result=u);const _=100;return l.logs.length>0&&(m.logs=l.logs.slice(0,_)),l.warns.length>0&&(m.warnings=l.warns.slice(0,_)),l.errors.length>0&&(m.errors=l.errors.slice(0,_)),m.duration_ms=h,{success:!0,data:m}}catch(a){return a instanceof Error&&"isScriptTimeout"in a?{success:!1,error:a.message}:a instanceof Error&&"isScriptCompileError"in a?{success:!1,error:`Script compile error: ${a.message}`}:{success:!1,error:`Script execution failed: ${a instanceof Error?a.message:String(a)}`}}}}function HY(t){return[new GY,new jY,new VY,new YY,new zY,new fD(t)]}class WY{constructor(e){mr(this,"tools",new Map);const r=HY(e);for(const n of r)this.register(n)}setRtcAgent(e){this.register(new fD(e))}register(e){this.tools.set(e.name,e)}get(e){return this.tools.get(e)}has(e){return this.tools.has(e)}getToolNames(){return Array.from(this.tools.keys())}async execute(e,r){const n=this.tools.get(e);if(!n)throw new Error(`Tool not found: ${e}`);return n.execute(r)}}const hD=new WY,xi=pr("RtcProcessor"),KY=1e3,mD=10;class QY{constructor(e){mr(this,"persistence");mr(this,"processing",!1);mr(this,"pendingCheck",!1);mr(this,"retryCountMap",new Map);mr(this,"mode","edit");mr(this,"confirmDialog");mr(this,"askUserDialog");mr(this,"master");mr(this,"_lastSilentlySkippedRtcId");this.persistence=e}setMode(e){this.mode=e}getMode(){return this.mode}setConfirmDialog(e){this.confirmDialog=e}setAskUserDialog(e){this.askUserDialog=e}setMaster(e){this.master=e}_isMasterAllowed(){return this.master===void 0||this.master.isMaster}async onRtcUpdate(){if(xi.debug("onRtcUpdate called, processing:",this.processing),this.processing){this.pendingCheck=!0;return}await this.processLoop()}async processLoop(){if(!this._isMasterAllowed()){xi.debug("processLoop: not master, skipping");return}this.processing=!0,xi.debug("processLoop started"),this._lastSilentlySkippedRtcId=void 0;try{for(;;){this.pendingCheck=!1;const e=await this.persistence.getNextRtcToProcess(void 0);if(!e){if(xi.debug("processLoop: no more RTC to process, exiting"),this.pendingCheck)continue;break}if(e.client_id===this._lastSilentlySkippedRtcId){xi.warn(`processLoop: RTC ${e.client_id} returned again after silent skip, exiting loop to prevent infinite retry`);break}xi.debug("processing RTC:",e.client_id,"tool:",e.tool_name,"sync_status:",e.sync_status);try{await this.processOne(e),xi.debug("processOne completed successfully")}catch(r){xi.error("processOne failed:",r);const n=r instanceof Error?r.message:String(r);if(n.includes("connection")||n.includes("disconnected")){xi.warn("connection error detected, exiting processLoop");break}await this.sleep(KY)}}}finally{this.processing=!1,xi.debug("processLoop finished")}}async processOne(e){if(e.sync_status==="failed"){const r=this.retryCountMap.get(e.client_id)||0;if(r>=mD){xi.error(`RTC ${e.client_id} exceeded max submit retry count (${mD}), abandoning. The RTC remains in sync_status='failed' and will be retried on the next onRtcUpdate cycle.`),this.retryCountMap.delete(e.client_id),this._lastSilentlySkippedRtcId=e.client_id;return}const n=this.calculateBackoff(r);await this.sleep(n);try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:e.status==="completed",result:e.result,error:e.error_message}),this.retryCountMap.delete(e.client_id)}catch(i){throw this.retryCountMap.set(e.client_id,r+1),i}}else{const r=e.tool_name;if(r==="ask_user"){await this.processAskUser(e);return}const n=L5.needsConfirm(r,this.mode);let i=!0;if(n&&(i=await this.showConfirmDialog(e)),!i){try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User denied"})}catch(c){xi.error("submitRtcResult (denied) failed:",c)}return}let s,a=!0,l;try{const c=e.parameters||{},d=await hD.execute(r,c);s=d.data,d.success||(a=!1,l=d.error)}catch(c){a=!1,l=c instanceof Error?c.message:String(c)}try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:a,result:s,error:l})}catch(c){xi.error("submitRtcResult failed:",c)}}}async processAskUser(e){if(!this.askUserDialog){xi.warn("askUserDialog not set, defaulting to reject");try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User declined to answer questions"})}catch(n){xi.error("submitRtcResult (ask_user no dialog) failed:",n)}return}let r;try{r=await this.askUserDialog(e)}catch(n){xi.error("askUserDialog threw:",n);try{await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:n instanceof Error?n.message:String(n)})}catch(i){xi.error("submitRtcResult (ask_user error) failed:",i)}return}try{r===null?await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!1,error:"User declined to answer questions"}):await this.persistence.submitRtcResult({rtcClientId:e.client_id,success:!0,result:r})}catch(n){xi.error("submitRtcResult (ask_user) failed:",n)}}calculateBackoff(e){return Math.min(1e3*Math.pow(2,e),3e4)}sleep(e){return new Promise(r=>setTimeout(r,e))}async showConfirmDialog(e){return this.confirmDialog?this.confirmDialog(e):(xi.warn("confirmDialog not set, defaulting to reject"),!1)}}function gD(t){return new SharedWorker(""+(typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/assets/shared-worker-DgWfKSkP.js").href:new URL("assets/shared-worker-DgWfKSkP.js",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),{name:t==null?void 0:t.name})}const Qa=pr("WorkerBridge");function XY(t){const e=t.toString(),r=e.match(/new URL\(\s*(["'`])([^"'`]+)\1/);if(r)return r[2];const n=e.match(/new SharedWorker\(\s*(["'`])([^"'`]+)\1/);if(n)return n[2];throw new Error("[WorkerBridge] Cannot extract worker URL from factory. Source: "+e.slice(0,300))}const oo=class oo{constructor(e){this._auth=e,this._worker=null,this._core=null,this._initialized=!1,this._connectionListeners=new Set,this._callbacks={onUIUpdate:r=>{gf().publish(r)},requestToken:async()=>{const r=this._auth.getAccessToken();if(!r)throw new Error("[WorkerBridge] no access token available");return r},requestTokenRefresh:()=>this._auth.handleTokenExpired(),onConnectionStateChange:r=>{for(const n of this._connectionListeners)try{n(r)}catch(i){Qa.error("connection listener error:",i)}}},this._proxiedCallbacks=RA(this._callbacks)}async initWorker(){let e=null;for(let r=0;r<=oo.MAX_INIT_RETRIES;r++)try{r>0&&(Qa.warn(`Retrying worker initialization (attempt ${r+1}/${oo.MAX_INIT_RETRIES+1})...`),await this._delay(oo.INIT_RETRY_DELAY_MS*r)),await this._initWorkerOnce(),await this._verifyWorkerAlive();return}catch(n){e=n instanceof Error?n:new Error(String(n)),Qa.error(`Worker initialization attempt ${r+1} failed:`,e.message),this._cleanupFailedWorker()}throw new Error(`[WorkerBridge] Failed to initialize SharedWorker after ${oo.MAX_INIT_RETRIES+1} attempts: ${e==null?void 0:e.message}`)}async _initWorkerOnce(){const e=XY(gD),r=typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:as&&as.tagName.toUpperCase()==="SCRIPT"&&as.src||new URL("index.umd.js",document.baseURI).href,n=new URL(e,r).href,i=window.location.origin;let s;try{s=new URL(n).origin}catch(l){Qa.debug("Failed to parse worker URL origin, assuming same-origin:",l),s=i}const a=s!==i;if(Qa.info("worker init:",{workerUrl:n,pageOrigin:i,workerOrigin:s,isCrossOrigin:a}),!a)this._worker=gD();else{let l;try{const u=await fetch(n,{cache:"no-store"});if(!u.ok)throw new Error(`HTTP ${u.status} ${u.statusText}`);l=await u.text()}catch(u){throw new Error(`[WorkerBridge] failed to fetch worker script from ${n}: ${u instanceof Error?u.message:u}`)}const c=new Blob([l],{type:"application/javascript"}),d=URL.createObjectURL(c);try{this._worker=new SharedWorker(d,{name:"rtc-agent-worker",type:"module"})}finally{URL.revokeObjectURL(d)}}this._core=wA(this._worker.port),this._worker.onerror=l=>{Qa.error("SharedWorker error:",{message:l.message,filename:l.filename,lineno:l.lineno,colno:l.colno,error:l.error})},this._worker.port.onmessageerror=l=>{Qa.error("port message error:",l)}}async _verifyWorkerAlive(){if(!this._core)throw new Error("[WorkerBridge] No core available for verification");let e;const r=new Promise((n,i)=>{e=setTimeout(()=>i(new Error("Worker verification timed out")),oo.VERIFICATION_TIMEOUT_MS)});try{const n=await Promise.race([this._core.ping(),r]);if(n!=="pong")throw new Error(`Unexpected ping response: ${n}`);Qa.info("Worker verification successful")}catch(n){throw new Error(`[WorkerBridge] Worker verification failed: ${n instanceof Error?n.message:"unknown error"}`)}finally{e!==void 0&&clearTimeout(e)}}_cleanupFailedWorker(){if(this._worker){try{this._worker.port.close()}catch{}this._worker=null}this._core=null}_delay(e){return new Promise(r=>setTimeout(r,e))}get core(){return this._core}async init(e){if(this._initialized){Qa.warn("already initialized");return}if(!this._worker||!this._core)throw new Error("[WorkerBridge] init() called before initWorker()");this._worker.port.start(),await this._core.init(e),await this._core.registerCallback(this._proxiedCallbacks),this._initialized=!0}async destroy(){if(this._initialized&&!(!this._worker||!this._core)){try{await this._core.unregisterCallback(this._proxiedCallbacks)}catch(e){Qa.warn("unregisterCallback failed:",e)}this._connectionListeners.clear(),this._worker.port.close(),this._initialized=!1}}async getConnectionState(){return this._core.getConnectionState()}onConnectionStateChange(e){return this._connectionListeners.add(e),()=>{this._connectionListeners.delete(e)}}installVirtualFSProxy(){const e=this._core;Kr.read=(r,n,i)=>e.virtualFSRead(r,n,i),Kr.write=(r,n,i="overwrite",s)=>e.virtualFSWrite(r,n,i,s),Kr.ls=r=>e.virtualFSLs(r),Kr.find=(r,n)=>e.virtualFSFind(r,n),Kr.grep=(r,n,i,s)=>e.virtualFSGrep(r,n,i,s),Kr.queryByType=r=>e.virtualFSQueryByType(r),Kr.exists=r=>e.virtualFSExists(r),Kr.remove=r=>e.virtualFSRemove(r)}};oo.MAX_INIT_RETRIES=3,oo.INIT_RETRY_DELAY_MS=1e3,oo.VERIFICATION_TIMEOUT_MS=5e3;let WE=oo;const gp=pr("MasterLock");class JY{constructor(e){this._isMaster=!1,this._controlled=!1,this._lockName=`rtc-agent-master-${e}`}get isMaster(){return this._isMaster}get isControlled(){return this._controlled}async acquire(){var e;if(this._controlled){gp.warn("already acquiring/acquired, ignoring");return}if(!this._isWebLocksAvailable()){gp.warn("Web Locks API not available, acting as always-master"),this._isMaster=!0,this._controlled=!0,(e=this.onAcquire)==null||e.call(this);return}this._controlled=!0,this._abortController=new AbortController,navigator.locks.request(this._lockName,{signal:this._abortController.signal},async()=>{var r,n;this._isMaster=!0,gp.info("acquired lock → became Master"),(r=this.onAcquire)==null||r.call(this),await new Promise(i=>{this._releaseResolve=i}),this._isMaster=!1,gp.info("released lock → lost Master"),(n=this.onRelease)==null||n.call(this)}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||gp.error("lock request error:",r)})}release(){this._controlled&&(this._releaseResolve&&(this._releaseResolve(),this._releaseResolve=void 0),!this._isMaster&&this._abortController&&this._abortController.abort(),this._controlled=!1)}_isWebLocksAvailable(){return typeof navigator<"u"&&"locks"in navigator}}const Pa=pr("PersistenceController");function eae(t){return t}class ZY{constructor(e){this._core=e}async connect(){Pa.info("connect() called"),await this._core.connect(),Pa.info("connect() completed, worker state:",await this._core.getConnectionState())}disconnect(){this._core.disconnect()}async reconnect(){await this._core.reconnect()}async listSessions(e,r){return this._core.listSessions(e,r)}async getSession(e){return this._core.getSession(e)}async listMessages(e,r,n,i){return this._core.listMessages(e,r,n,i)}async getMessage(e){return this._core.getMessage(e)}async listRtc(e,r,n){return this._core.listRtc(e,r,n)}async getNextRtcToProcess(e){return this._core.getNextRtcToProcess(e)}async sendMessage(e){return this._core.sendMessage(e)}async insertLocalMessage(e){return this._core.insertLocalMessage(e)}async stopTurn(e){return this._core.stopTurn(e)}async closeSession(e){return this._core.closeSession(e)}async openSession(e){return this._core.openSession(e)}async compactSession(e,r){return this._core.compactSession(e,r)}async submitRtcResult(e){return this._core.submitRtcResult(e)}async forkSession(e){return this._core.forkSession(e)}async deleteSession(e){return this._core.deleteSession(e)}async updateSessionTitle(e,r){return this._core.updateSessionTitle(e,r)}async close(){await this._core.close()}async flushAll(){return this._core.flushAll()}async initializeVirtualFS(e){await this._core.initializeVirtualFS(e??{})}getClient(){throw new Error("[WorkerPersistenceAdapter] getClient() is not available. Use PersistenceController.onConnectionStateChange() instead.")}getOffsetManager(){return{reset:()=>this._core.resetOffset()}}getEntityRepository(){throw new Error("[WorkerPersistenceAdapter] getEntityRepository() is not available.")}}const Nl=class Nl{constructor(e,r){this._auth=r,e.addController(this)}get layer(){return this._layer}get isConnected(){return this._layer!==void 0}get workerBridge(){return this._workerBridge}get masterLock(){return this._masterLock}hostConnected(){}hostDisconnected(){this.disconnect()}async connect(){if(this._layer)return;if(this._connecting)return Pa.debug("connect() called while already connecting, awaiting existing attempt"),this._connecting;const e=vA(),r=this._auth.state.userId;if(!r)throw new Error("[PersistenceController] connect() called without userId; refusing to open a shared database");const n={databaseName:`rtc-agent-${r}`,deviceId:e,client:{endpoint:Qo.wsEndpoint,getToken:()=>{const i=this._auth.getAccessToken();if(!i)throw Pa.warn("getToken: no access token available"),new Error("No access token available");return i},onTokenExpired:()=>this._auth.handleTokenExpired(),deviceId:e,userId:r}};return this._connecting=this._connectWorker(n).finally(()=>{this._connecting=void 0}),this._connecting}async _connectWorker(e){let r=null;for(let n=0;n<=Nl.MAX_CONNECT_RETRIES;n++)try{n>0&&(Pa.warn(`Retrying connection (attempt ${n+1}/${Nl.MAX_CONNECT_RETRIES+1})...`),await this._delay(Nl.CONNECT_RETRY_DELAY_MS*n)),await this._connectWorkerOnce(e);return}catch(i){r=i instanceof Error?i:new Error(String(i)),Pa.error(`Connection attempt ${n+1} failed:`,r.message),await this._cleanupFailedConnection()}throw new Error(`[PersistenceController] Failed to connect after ${Nl.MAX_CONNECT_RETRIES+1} attempts: ${r==null?void 0:r.message}`)}async _connectWorkerOnce(e){this._workerBridge=new WE(this._auth),await this._workerBridge.initWorker();const{getToken:r,onTokenExpired:n,...i}=e.client,s={...e,client:i};await this._workerBridge.init(s),this._workerBridge.installVirtualFSProxy(),this._layer=new ZY(this._workerBridge.core),await this._workerBridge.core.connect();const a=this._auth.state.userId;a&&(this._masterLock=new JY(a),this._masterLock.onAcquire=()=>{Pa.info("this Tab became Master")},this._masterLock.onRelease=()=>{Pa.info("this Tab lost Master")},this._masterLock.acquire())}async _cleanupFailedConnection(){if(this._workerBridge){try{await this._workerBridge.destroy()}catch(e){Pa.debug("Cleanup after failed connection (non-critical):",e)}this._workerBridge=void 0}this._layer=void 0}_delay(e){return new Promise(r=>setTimeout(r,e))}async disconnect(){var e;if(this._layer){try{await this._layer.getOffsetManager().reset(),await this._layer.close()}catch(r){Pa.error("disconnect error:",r)}this._layer=void 0}if(this._workerBridge){(e=this._masterLock)==null||e.release(),this._masterLock=void 0;try{await this._workerBridge.destroy()}catch(r){Pa.error("WorkerBridge disconnect error:",r)}this._workerBridge=void 0}}async getConnectionState(){return this._workerBridge?this._workerBridge.getConnectionState():"disconnected"}onConnectionStateChange(e){return this._workerBridge?this._workerBridge.onConnectionStateChange(e):()=>{}}};Nl.MAX_CONNECT_RETRIES=2,Nl.CONNECT_RETRY_DELAY_MS=2e3;let KE=Nl;const _D=pr("EventBus");class yD{constructor(){this.handlers=new Map}on(e,r){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(r),()=>{var n;(n=this.handlers.get(e))==null||n.delete(r)}}once(e,r){const n=i=>(this.off(e,n),r(i));return this.on(e,n)}off(e,r){var n;(n=this.handlers.get(e))==null||n.delete(r)}emit(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n);for(const s of i)try{s(r)}catch(a){_D.error(`Handler error for event '${e}':`,a)}}async emitAsync(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n),s=[];for(const a of i)s.push(Promise.resolve(a(r)).catch(l=>{_D.error(`Async handler error for event '${e}':`,l)}));await Promise.all(s)}async emitAsyncStrict(e,r){const n=this.handlers.get(e);if(!n)return;const i=Array.from(n),s=[];for(const a of i)s.push(Promise.resolve(a(r)));await Promise.all(s)}clearAll(){this.handlers.clear()}clearEvent(e){this.handlers.delete(e)}}function ez(){return new yD}const ol=ez(),tz=pr("SkillController");class bD{constructor(e,r){this._registry=null,this._config={},this._unsubscribes=[],this._host=e,this._config=r||{},e.addController(this)}get value(){return{registry:this._registry}}get actions(){return{getRegistry:()=>this._registry,setRegistry:e=>{this._registry=e,this._host.requestUpdate(),this._bridgeToolRegistry(e)}}}_bridgeToolRegistry(e){const r=new Proxy({callFunction:(n,i)=>e.execute(n,i),readFile:n=>Kr.read(n),writeFile:(n,i)=>Kr.write(n,i).then(()=>{}),listDir:n=>Kr.ls(n)},{get(n,i){return i in n?n[i]:e[i]}});hD.setRtcAgent(r),tz.info("rtcAgent API bridged to ToolRegistry")}setConfig(e){this._config=e}hostConnected(){this._subscribeEvents()}hostDisconnected(){for(const e of this._unsubscribes)e();this._unsubscribes=[]}_subscribeEvents(){for(const n of this._unsubscribes)n();this._unsubscribes=[];const e=ol.on("ui:toast",n=>{this._config.onToast&&this._config.onToast(n.message,n.type)});this._unsubscribes.push(e);const r=ol.on("ui:confirm-request",n=>{this._config.onConfirmRequest&&this._config.onConfirmRequest(n.requestId,n.path,n.message)});this._unsubscribes.push(r)}respondToConfirm(e,r){ol.emit("ui:confirm-response",{requestId:e,confirmed:r})}}class rz{constructor(e){this._toasts=[],this._timers=new Map,this._host=e,this._host.addController(this),this.actions={show:(r,n="info",i)=>this._show(r,n,i),remove:r=>this._remove(r)}}get toasts(){return this._toasts}hostConnected(){}hostDisconnected(){for(const e of this._timers.values())clearTimeout(e);this._timers.clear()}_show(e,r,n){const i=Date.now()+Math.random();this._toasts=[...this._toasts,{id:i,message:e,type:r,action:n}],this._host.requestUpdate();const s=r==="error"?0:r==="success"?2e3:2500;if(s>0){const a=setTimeout(()=>this._remove(i),s);this._timers.set(i,a)}}_remove(e){const r=this._timers.get(e);r!==void 0&&(clearTimeout(r),this._timers.delete(e)),this._toasts=this._toasts.filter(n=>n.id!==e),this._host.requestUpdate()}}/**
|
|
3182
3182
|
* @license
|
|
3183
3183
|
* Copyright 2021 Google LLC
|
|
3184
3184
|
* SPDX-License-Identifier: BSD-3-Clause
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rtc-agent/component",
|
|
3
|
-
"version": "0.1.9-rc.
|
|
3
|
+
"version": "0.1.9-rc.2",
|
|
4
4
|
"description": "RTC Agent Web Components(基于 Lit)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"lit": "^3.1.0",
|
|
30
30
|
"marked": "^18.0.11",
|
|
31
31
|
"zod": "^3.23.8",
|
|
32
|
-
"@rtc-agent/client": "0.1.9-rc.
|
|
33
|
-
"@rtc-agent/persistence": "0.1.9-rc.
|
|
34
|
-
"@rtc-agent/
|
|
35
|
-
"@rtc-agent/
|
|
32
|
+
"@rtc-agent/client": "0.1.9-rc.2",
|
|
33
|
+
"@rtc-agent/persistence": "0.1.9-rc.2",
|
|
34
|
+
"@rtc-agent/protocol": "0.1.9-rc.2",
|
|
35
|
+
"@rtc-agent/worker": "0.1.9-rc.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@lit/localize-tools": "^0.8.2",
|